diff --git a/Android.bp b/Android.bp
index eb6d503..720d605 100644
--- a/Android.bp
+++ b/Android.bp
@@ -17,7 +17,9 @@
 // The source files that contribute to Android's core library APIs.
 filegroup {
     name: "okhttp_api_files",
-    srcs: ["android/src/main/java/com/android/okhttp/internalandroidapi/**/*.java"],
+    // Use the repackaged version of android as that is what is used by Android core library
+    // APIs.
+    srcs: ["repackaged/android/src/main/java/com/android/okhttp/internalandroidapi/**/*.java"],
 }
 
 // non-jarjar'd version of okhttp to compile the tests against
@@ -44,8 +46,16 @@
 
 java_library {
     name: "okhttp",
-    static_libs: ["okhttp-nojarjar"],
-    jarjar_rules: "jarjar-rules.txt",
+    srcs: [
+        // Although some of the classes in the android/ directory are already in the correct
+        // package and do not need to be moved to another package they are transformed as they
+        // reference other classes that do require repackaging.
+        "repackaged/android/src/main/java/**/*.java",
+        "repackaged/okhttp/src/main/java/**/*.java",
+        "repackaged/okhttp-urlconnection/src/main/java/**/*.java",
+        "repackaged/okhttp-android-support/src/main/java/**/*.java",
+        "repackaged/okio/okio/src/main/java/**/*.java",
+    ],
 
     hostdex: true,
     installable: true,
diff --git a/jarjar-rules.txt b/jarjar-rules.txt
deleted file mode 100644
index c84813d..0000000
--- a/jarjar-rules.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-rule com.squareup.** com.android.@1
-rule okio.** com.android.okhttp.okio.@1
diff --git a/repackaged/android/src/main/java/com/android/okhttp/ConfigAwareConnectionPool.java b/repackaged/android/src/main/java/com/android/okhttp/ConfigAwareConnectionPool.java
new file mode 100644
index 0000000..1414133
--- /dev/null
+++ b/repackaged/android/src/main/java/com/android/okhttp/ConfigAwareConnectionPool.java
@@ -0,0 +1,102 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  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.android.okhttp;
+
+import libcore.net.event.NetworkEventDispatcher;
+import libcore.net.event.NetworkEventListener;
+
+/**
+ * A provider of the shared Android {@link ConnectionPool}. This class is aware of network
+ * configuration change events: When the network configuration changes the pool object is discarded
+ * and a later calls to {@link #get()} will return a new pool.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ConfigAwareConnectionPool {
+
+  private static final long CONNECTION_POOL_DEFAULT_KEEP_ALIVE_DURATION_MS = 5 * 60 * 1000; // 5 min
+
+  private static final int CONNECTION_POOL_MAX_IDLE_CONNECTIONS;
+  private static final long CONNECTION_POOL_KEEP_ALIVE_DURATION_MS;
+  static {
+    String keepAliveProperty = System.getProperty("http.keepAlive");
+    String keepAliveDurationProperty = System.getProperty("http.keepAliveDuration");
+    String maxIdleConnectionsProperty = System.getProperty("http.maxConnections");
+    CONNECTION_POOL_KEEP_ALIVE_DURATION_MS = (keepAliveDurationProperty != null
+        ? Long.parseLong(keepAliveDurationProperty)
+        : CONNECTION_POOL_DEFAULT_KEEP_ALIVE_DURATION_MS);
+    if (keepAliveProperty != null && !Boolean.parseBoolean(keepAliveProperty)) {
+      CONNECTION_POOL_MAX_IDLE_CONNECTIONS = 0;
+    } else if (maxIdleConnectionsProperty != null) {
+      CONNECTION_POOL_MAX_IDLE_CONNECTIONS = Integer.parseInt(maxIdleConnectionsProperty);
+    } else {
+      CONNECTION_POOL_MAX_IDLE_CONNECTIONS = 5;
+    }
+  }
+
+  private static final ConfigAwareConnectionPool instance = new ConfigAwareConnectionPool();
+
+  private final NetworkEventDispatcher networkEventDispatcher;
+
+  /**
+   * {@code true} if the ConnectionPool reset has been registered with the
+   * {@link NetworkEventDispatcher}.
+   */
+  private boolean networkEventListenerRegistered;
+
+  private ConnectionPool connectionPool;
+
+  /** Visible for testing. Use {@link #getInstance()} */
+  protected ConfigAwareConnectionPool(NetworkEventDispatcher networkEventDispatcher) {
+    this.networkEventDispatcher = networkEventDispatcher;
+  }
+
+  private ConfigAwareConnectionPool() {
+    networkEventDispatcher = NetworkEventDispatcher.getInstance();
+  }
+
+  public static ConfigAwareConnectionPool getInstance() {
+    return instance;
+  }
+
+  /**
+   * Returns the current {@link ConnectionPool} to use.
+   */
+  public synchronized ConnectionPool get() {
+    if (connectionPool == null) {
+      // Only register the listener once the first time a ConnectionPool is created.
+      if (!networkEventListenerRegistered) {
+        networkEventDispatcher.addListener(new NetworkEventListener() {
+          @Override
+          public void onNetworkConfigurationChanged() {
+            synchronized (ConfigAwareConnectionPool.this) {
+              // If the network config has changed then existing pooled connections should not be
+              // re-used. By setting connectionPool to null it ensures that the next time
+              // getConnectionPool() is called a new pool will be created.
+              connectionPool = null;
+            }
+          }
+        });
+        networkEventListenerRegistered = true;
+      }
+      connectionPool = new ConnectionPool(
+          CONNECTION_POOL_MAX_IDLE_CONNECTIONS, CONNECTION_POOL_KEEP_ALIVE_DURATION_MS);
+    }
+    return connectionPool;
+  }
+}
diff --git a/repackaged/android/src/main/java/com/android/okhttp/ConnectionSpecs.java b/repackaged/android/src/main/java/com/android/okhttp/ConnectionSpecs.java
new file mode 100644
index 0000000..2684dd6
--- /dev/null
+++ b/repackaged/android/src/main/java/com/android/okhttp/ConnectionSpecs.java
@@ -0,0 +1,35 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.okhttp;
+
+/**
+ * Exposes nonpublic {@link ConnectionSpec} API for internal use by libcore.
+ *
+ * @hide
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ConnectionSpecs {
+    /** uninstantiable */
+    private ConnectionSpecs() {
+    }
+
+    public static ConnectionSpec.Builder builder(boolean tls) {
+        return new ConnectionSpec.Builder(tls);
+    }
+
+}
diff --git a/repackaged/android/src/main/java/com/android/okhttp/HttpHandler.java b/repackaged/android/src/main/java/com/android/okhttp/HttpHandler.java
new file mode 100644
index 0000000..920824b
--- /dev/null
+++ b/repackaged/android/src/main/java/com/android/okhttp/HttpHandler.java
@@ -0,0 +1,123 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  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.android.okhttp;
+
+import com.android.okhttp.internal.URLFilter;
+import libcore.net.NetworkSecurityPolicy;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.Proxy;
+import java.net.ResponseCache;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public class HttpHandler extends URLStreamHandler {
+
+    private final static List<ConnectionSpec> CLEARTEXT_ONLY =
+        Collections.singletonList(ConnectionSpec.CLEARTEXT);
+
+    private static final CleartextURLFilter CLEARTEXT_FILTER = new CleartextURLFilter();
+
+    private final ConfigAwareConnectionPool configAwareConnectionPool =
+            ConfigAwareConnectionPool.getInstance();
+
+    @Override protected URLConnection openConnection(URL url) throws IOException {
+        return newOkUrlFactory(null /* proxy */).open(url);
+    }
+
+    @Override protected URLConnection openConnection(URL url, Proxy proxy) throws IOException {
+        if (url == null || proxy == null) {
+            throw new IllegalArgumentException("url == null || proxy == null");
+        }
+        return newOkUrlFactory(proxy).open(url);
+    }
+
+    @Override protected int getDefaultPort() {
+        return 80;
+    }
+
+    protected OkUrlFactory newOkUrlFactory(Proxy proxy) {
+        OkUrlFactory okUrlFactory = createHttpOkUrlFactory(proxy);
+        // For HttpURLConnections created through java.net.URL Android uses a connection pool that
+        // is aware when the default network changes so that pooled connections are not re-used when
+        // the default network changes.
+        okUrlFactory.client().setConnectionPool(configAwareConnectionPool.get());
+        return okUrlFactory;
+    }
+
+    /**
+     * Creates an OkHttpClient suitable for creating {@link java.net.HttpURLConnection} instances on
+     * Android.
+     */
+    // Visible for android.net.Network.
+    public static OkUrlFactory createHttpOkUrlFactory(Proxy proxy) {
+        OkHttpClient client = new OkHttpClient();
+
+        // Explicitly set the timeouts to infinity.
+        client.setConnectTimeout(0, TimeUnit.MILLISECONDS);
+        client.setReadTimeout(0, TimeUnit.MILLISECONDS);
+        client.setWriteTimeout(0, TimeUnit.MILLISECONDS);
+
+        // Set the default (same protocol) redirect behavior. The default can be overridden for
+        // each instance using HttpURLConnection.setInstanceFollowRedirects().
+        client.setFollowRedirects(HttpURLConnection.getFollowRedirects());
+
+        // Do not permit http -> https and https -> http redirects.
+        client.setFollowSslRedirects(false);
+
+        // Permit cleartext traffic only (this is a handler for HTTP, not for HTTPS).
+        client.setConnectionSpecs(CLEARTEXT_ONLY);
+
+        // When we do not set the Proxy explicitly OkHttp picks up a ProxySelector using
+        // ProxySelector.getDefault().
+        if (proxy != null) {
+            client.setProxy(proxy);
+        }
+
+        // OkHttp requires that we explicitly set the response cache.
+        OkUrlFactory okUrlFactory = new OkUrlFactory(client);
+
+        // Use the installed NetworkSecurityPolicy to determine which requests are permitted over
+        // http.
+        OkUrlFactories.setUrlFilter(okUrlFactory, CLEARTEXT_FILTER);
+
+        ResponseCache responseCache = ResponseCache.getDefault();
+        if (responseCache != null) {
+            AndroidInternal.setResponseCache(okUrlFactory, responseCache);
+        }
+        return okUrlFactory;
+    }
+
+    private static final class CleartextURLFilter implements URLFilter {
+        @Override
+        public void checkURLPermitted(URL url) throws IOException {
+            String host = url.getHost();
+            if (!NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted(host)) {
+                throw new IOException("Cleartext HTTP traffic to " + host + " not permitted");
+            }
+        }
+    }
+}
diff --git a/repackaged/android/src/main/java/com/android/okhttp/HttpsHandler.java b/repackaged/android/src/main/java/com/android/okhttp/HttpsHandler.java
new file mode 100644
index 0000000..299274d
--- /dev/null
+++ b/repackaged/android/src/main/java/com/android/okhttp/HttpsHandler.java
@@ -0,0 +1,100 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  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.android.okhttp;
+
+import java.net.Proxy;
+import java.util.Collections;
+import java.util.List;
+
+import javax.net.ssl.HttpsURLConnection;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class HttpsHandler extends HttpHandler {
+
+    /**
+     * The connection spec to use when connecting to an https:// server. Note that Android does
+     * not set the cipher suites or TLS versions to use so the socket's defaults will be used
+     * instead. When the SSLSocketFactory is provided by the app or GMS core we will not
+     * override the enabled ciphers or TLS versions set on the sockets it produces with a
+     * list hardcoded at release time. This is deliberate.
+     */
+    private static final ConnectionSpec TLS_CONNECTION_SPEC = ConnectionSpecs.builder(true)
+            .allEnabledCipherSuites()
+            .allEnabledTlsVersions()
+            .supportsTlsExtensions(true)
+            .build();
+
+    private static final List<Protocol> HTTP_1_1_ONLY =
+            Collections.singletonList(Protocol.HTTP_1_1);
+
+    private final ConfigAwareConnectionPool configAwareConnectionPool =
+            ConfigAwareConnectionPool.getInstance();
+
+    @Override protected int getDefaultPort() {
+        return 443;
+    }
+
+    @Override
+    protected OkUrlFactory newOkUrlFactory(Proxy proxy) {
+        OkUrlFactory okUrlFactory = createHttpsOkUrlFactory(proxy);
+        // For HttpsURLConnections created through java.net.URL Android uses a connection pool that
+        // is aware when the default network changes so that pooled connections are not re-used when
+        // the default network changes.
+        okUrlFactory.client().setConnectionPool(configAwareConnectionPool.get());
+        return okUrlFactory;
+    }
+
+    /**
+     * Creates an OkHttpClient suitable for creating {@link HttpsURLConnection} instances on
+     * Android.
+     */
+    // Visible for android.net.Network.
+    public static OkUrlFactory createHttpsOkUrlFactory(Proxy proxy) {
+        // The HTTPS OkHttpClient is an HTTP OkHttpClient with extra configuration.
+        OkUrlFactory okUrlFactory = HttpHandler.createHttpOkUrlFactory(proxy);
+
+        // All HTTPS requests are allowed.
+        OkUrlFactories.setUrlFilter(okUrlFactory, null);
+
+        OkHttpClient okHttpClient = okUrlFactory.client();
+
+        // Only enable HTTP/1.1 (implies HTTP/1.0). Disable SPDY / HTTP/2.0.
+        okHttpClient.setProtocols(HTTP_1_1_ONLY);
+
+        okHttpClient.setConnectionSpecs(Collections.singletonList(TLS_CONNECTION_SPEC));
+
+        // Android support certificate pinning via NetworkSecurityConfig so there is no need to
+        // also expose OkHttp's mechanism. The OkHttpClient underlying https HttpsURLConnections
+        // in Android should therefore always use the default certificate pinner, whose set of
+        // {@code hostNamesToPin} is empty.
+        okHttpClient.setCertificatePinner(CertificatePinner.DEFAULT);
+
+        // OkHttp does not automatically honor the system-wide HostnameVerifier set with
+        // HttpsURLConnection.setDefaultHostnameVerifier().
+        okUrlFactory.client().setHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier());
+        // OkHttp does not automatically honor the system-wide SSLSocketFactory set with
+        // HttpsURLConnection.setDefaultSSLSocketFactory().
+        // See https://github.com/square/okhttp/issues/184 for details.
+        okHttpClient.setSslSocketFactory(HttpsURLConnection.getDefaultSSLSocketFactory());
+
+        return okUrlFactory;
+    }
+}
diff --git a/repackaged/android/src/main/java/com/android/okhttp/OkUrlFactories.java b/repackaged/android/src/main/java/com/android/okhttp/OkUrlFactories.java
new file mode 100644
index 0000000..1b01f44
--- /dev/null
+++ b/repackaged/android/src/main/java/com/android/okhttp/OkUrlFactories.java
@@ -0,0 +1,46 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.okhttp;
+
+import com.android.okhttp.internal.URLFilter;
+
+import java.net.HttpURLConnection;
+import java.net.Proxy;
+import java.net.URL;
+
+/**
+ * Exposes nonpublic {@link OkUrlFactory} API for internal use by libcore.
+ *
+ * @hide
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OkUrlFactories {
+
+    /** uninstantiable */
+    private OkUrlFactories() {
+    }
+
+    public static HttpURLConnection open(OkUrlFactory okUrlFactory, URL url, Proxy proxy) {
+        return okUrlFactory.open(url, proxy);
+    }
+
+    public static void setUrlFilter(OkUrlFactory okUrlFactory, URLFilter urlFilter) {
+        okUrlFactory.setUrlFilter(urlFilter);
+    }
+
+}
diff --git a/repackaged/android/src/main/java/com/android/okhttp/internal/Platform.java b/repackaged/android/src/main/java/com/android/okhttp/internal/Platform.java
new file mode 100644
index 0000000..ad2559a
--- /dev/null
+++ b/repackaged/android/src/main/java/com/android/okhttp/internal/Platform.java
@@ -0,0 +1,219 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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.
+ */
+package com.android.okhttp.internal;
+
+import com.android.okhttp.Protocol;
+import com.android.okhttp.internal.tls.RealTrustRootIndex;
+import com.android.okhttp.internal.tls.TrustRootIndex;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketException;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.X509TrustManager;
+
+import dalvik.system.SocketTagger;
+import com.android.okhttp.okio.Buffer;
+
+/**
+ * Access to proprietary Android APIs. Avoids use of reflection where possible.
+ * @hide This class is not part of the Android public SDK API
+ */
+// only tests should extend this class
+public class Platform {
+    private static final AtomicReference<Platform> INSTANCE_HOLDER
+            = new AtomicReference<>(new Platform());
+
+    // only for private use and in tests
+    protected Platform() {
+    }
+
+    public static Platform get() {
+        return INSTANCE_HOLDER.get();
+    }
+
+    /**
+     * Atomically replaces the Platform instance returned by future
+     * invocations of {@link #get()}, for use in tests.
+     * Invocations of this method should typically be followed by
+     * a try/finally block to reset the previous value:
+     *
+     * <pre>
+     * Platform p = getAndSetForTest(...);
+     * try {
+     *   ...
+     * } finally {
+     *   getAndSetForTest(p);
+     * }
+     * </pre>
+     *
+     * @return the previous value of {@link #get()}.
+     */
+    public static Platform getAndSetForTest(Platform platform) {
+        if (platform == null) {
+            throw new NullPointerException();
+        }
+        return INSTANCE_HOLDER.getAndSet(platform);
+    }
+
+    /** setUseSessionTickets(boolean) */
+    private static final OptionalMethod<Socket> SET_USE_SESSION_TICKETS =
+            new OptionalMethod<Socket>(null, "setUseSessionTickets", Boolean.TYPE);
+    /** setHostname(String) */
+    private static final OptionalMethod<Socket> SET_HOSTNAME =
+            new OptionalMethod<Socket>(null, "setHostname", String.class);
+    /** byte[] getAlpnSelectedProtocol() */
+    private static final OptionalMethod<Socket> GET_ALPN_SELECTED_PROTOCOL =
+            new OptionalMethod<Socket>(byte[].class, "getAlpnSelectedProtocol");
+    /** setAlpnSelectedProtocol(byte[]) */
+    private static final OptionalMethod<Socket> SET_ALPN_PROTOCOLS =
+            new OptionalMethod<Socket>(null, "setAlpnProtocols", byte[].class );
+
+    public void logW(String warning) {
+        System.logW(warning);
+    }
+
+    public void tagSocket(Socket socket) throws SocketException {
+        SocketTagger.get().tag(socket);
+    }
+
+    public void untagSocket(Socket socket) throws SocketException {
+        SocketTagger.get().untag(socket);
+    }
+
+    public void configureTlsExtensions(
+            SSLSocket sslSocket, String hostname, List<Protocol> protocols) {
+        // Enable SNI and session tickets.
+        if (hostname != null) {
+            SET_USE_SESSION_TICKETS.invokeOptionalWithoutCheckedException(sslSocket, true);
+            SET_HOSTNAME.invokeOptionalWithoutCheckedException(sslSocket, hostname);
+        }
+
+        // Enable ALPN.
+        boolean alpnSupported = SET_ALPN_PROTOCOLS.isSupported(sslSocket);
+        if (!alpnSupported) {
+            return;
+        }
+
+        Object[] parameters = { concatLengthPrefixed(protocols) };
+        if (alpnSupported) {
+            SET_ALPN_PROTOCOLS.invokeWithoutCheckedException(sslSocket, parameters);
+        }
+    }
+
+    /**
+     * Called after the TLS handshake to release resources allocated by {@link
+     * #configureTlsExtensions}.
+     */
+    public void afterHandshake(SSLSocket sslSocket) {
+    }
+
+    public String getSelectedProtocol(SSLSocket socket) {
+        boolean alpnSupported = GET_ALPN_SELECTED_PROTOCOL.isSupported(socket);
+        if (!alpnSupported) {
+            return null;
+        }
+
+        byte[] alpnResult =
+                (byte[]) GET_ALPN_SELECTED_PROTOCOL.invokeWithoutCheckedException(socket);
+        if (alpnResult != null) {
+            return new String(alpnResult, Util.UTF_8);
+        }
+        return null;
+    }
+
+    public void connectSocket(Socket socket, InetSocketAddress address,
+              int connectTimeout) throws IOException {
+        socket.connect(address, connectTimeout);
+    }
+
+    /** Prefix used on custom headers. */
+    public String getPrefix() {
+        return "X-Android";
+    }
+
+    /**
+     * Stripped down/adapted from OkHttp's {@code Platform.Android.trustManager()}.
+     * OkHttp 2.7.5 uses this only for certificate pinning logic that we don't use
+     * on Android, so this method should never be called outside of OkHttp's tests.
+     * This method has been stripped down to the minimum for OkHttp's tests to pass.
+     */
+    public X509TrustManager trustManager(SSLSocketFactory sslSocketFactory) {
+        Class sslParametersClass;
+        try {
+            sslParametersClass = Class.forName("com.android.org.conscrypt.SSLParametersImpl");
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+        Object context = readFieldOrNull(sslSocketFactory, sslParametersClass, "sslParameters");
+        return readFieldOrNull(context, X509TrustManager.class, "x509TrustManager");
+    }
+
+    /**
+     * Stripped down from OkHttp's implementation to the minimum to get OkHttp's tests
+     * to pass. OkHttp 2.7.5 uses this for certificate pinning logic which is unused
+     * in Android. This method should never be called outside of OkHttp's tests.
+     */
+    public TrustRootIndex trustRootIndex(X509TrustManager trustManager) {
+        return new RealTrustRootIndex(trustManager.getAcceptedIssuers());
+    }
+
+    // Helper method from OkHttp's Platform.java
+    private static <T> T readFieldOrNull(Object instance, Class<T> fieldType, String fieldName) {
+        for (Class<?> c = instance.getClass(); c != Object.class; c = c.getSuperclass()) {
+            try {
+                Field field = c.getDeclaredField(fieldName);
+                field.setAccessible(true);
+                Object value = field.get(instance);
+                if (value == null || !fieldType.isInstance(value)) return null;
+                return fieldType.cast(value);
+            } catch (NoSuchFieldException ignored) {
+            } catch (IllegalAccessException e) {
+                throw new AssertionError();
+            }
+        }
+
+        // Didn't find the field we wanted. As a last gasp attempt, try to find the value on a delegate.
+        if (!fieldName.equals("delegate")) {
+            Object delegate = readFieldOrNull(instance, Object.class, "delegate");
+            if (delegate != null) return readFieldOrNull(delegate, fieldType, fieldName);
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the concatenation of 8-bit, length prefixed protocol names.
+     * http://tools.ietf.org/html/draft-agl-tls-nextprotoneg-04#page-4
+     */
+    static byte[] concatLengthPrefixed(List<Protocol> protocols) {
+        Buffer result = new Buffer();
+        for (int i = 0, size = protocols.size(); i < size; i++) {
+            Protocol protocol = protocols.get(i);
+            if (protocol == Protocol.HTTP_1_0) continue; // No HTTP/1.0 for ALPN.
+            result.writeByte(protocol.toString().length());
+            result.writeUtf8(protocol.toString());
+        }
+        return result.readByteArray();
+    }
+}
diff --git a/repackaged/android/src/main/java/com/android/okhttp/internal/Version.java b/repackaged/android/src/main/java/com/android/okhttp/internal/Version.java
new file mode 100644
index 0000000..f186a62
--- /dev/null
+++ b/repackaged/android/src/main/java/com/android/okhttp/internal/Version.java
@@ -0,0 +1,30 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.internal;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Version {
+  public static String userAgent() {
+    String agent = System.getProperty("http.agent");
+    return agent != null ? agent : ("Java" + System.getProperty("java.version"));
+  }
+
+  private Version() {
+  }
+}
diff --git a/repackaged/android/src/main/java/com/android/okhttp/internalandroidapi/AndroidResponseCacheAdapter.java b/repackaged/android/src/main/java/com/android/okhttp/internalandroidapi/AndroidResponseCacheAdapter.java
new file mode 100644
index 0000000..b7f5002
--- /dev/null
+++ b/repackaged/android/src/main/java/com/android/okhttp/internalandroidapi/AndroidResponseCacheAdapter.java
@@ -0,0 +1,172 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.okhttp.internalandroidapi;
+
+import com.android.okhttp.internalandroidapi.HasCacheHolder.CacheHolder;
+import com.android.okhttp.Cache;
+import com.android.okhttp.Request;
+import com.android.okhttp.Response;
+import com.android.okhttp.internal.huc.JavaApiConverter;
+
+import java.io.IOException;
+import java.net.CacheRequest;
+import java.net.CacheResponse;
+import java.net.URI;
+import java.net.URLConnection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A modified copy of {@link com.android.okhttp.AndroidShimResponseCache} that exposes a
+ * {@link CacheHolder} instead of a {@link Cache}. We want to keep the framework code that interacts
+ * with OkHttp at arms length. By delegating to this class the Android HttpResponseCache class has
+ * no knowledge of OkHttp internal classes at class resolution time and there are no internal
+ * classes appearing on method signatures.
+ * @hide
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.CorePlatformApi
+public final class AndroidResponseCacheAdapter {
+
+    private final CacheHolder cacheHolder;
+    private final Cache okHttpCache;
+
+    @libcore.api.CorePlatformApi
+    public AndroidResponseCacheAdapter(CacheHolder cacheHolder) {
+        this.cacheHolder = cacheHolder;
+        // Avoid one level of dereferencing by storing the reference to the OkHttp cache for later.
+        this.okHttpCache = cacheHolder.getCache();
+    }
+
+    /**
+     * Returns the {@link CacheHolder} associated with this instance and can be used by OkHttp
+     * internal code to obtain the underlying OkHttp Cache object.
+     */
+    @libcore.api.CorePlatformApi
+    public CacheHolder getCacheHolder() {
+        return cacheHolder;
+    }
+
+    /**
+     * Used to implement {@link java.net.ResponseCache#get(URI, String, Map)}. See that method for
+     * details.
+     */
+    @libcore.api.CorePlatformApi
+    public CacheResponse get(URI uri, String requestMethod,
+            Map<String, List<String>> requestHeaders) throws IOException {
+        Request okRequest = JavaApiConverter.createOkRequest(uri, requestMethod, requestHeaders);
+        Response okResponse = okHttpCache.internalCache.get(okRequest);
+        if (okResponse == null) {
+            return null;
+        }
+        return JavaApiConverter.createJavaCacheResponse(okResponse);
+    }
+
+    /**
+     * Used to implement {@link java.net.ResponseCache#put(URI, URLConnection)}. See that method for
+     * details.
+     */
+    @libcore.api.CorePlatformApi
+    public CacheRequest put(URI uri, URLConnection urlConnection) throws IOException {
+        Response okResponse = JavaApiConverter.createOkResponseForCachePut(uri, urlConnection);
+        if (okResponse == null) {
+            // The URLConnection is not cacheable or could not be converted. Stop.
+            return null;
+        }
+        com.android.okhttp.internal.http.CacheRequest okCacheRequest =
+                okHttpCache.internalCache.put(okResponse);
+        if (okCacheRequest == null) {
+            return null;
+        }
+        return JavaApiConverter.createJavaCacheRequest(okCacheRequest);
+    }
+
+    /**
+     * Returns the number of bytes currently being used to store the values in
+     * this cache. This may be greater than the {@link #getMaxSize()} if a background
+     * deletion is pending. IOException is thrown if the size cannot be determined.
+     */
+    @libcore.api.CorePlatformApi
+    public long getSize() throws IOException {
+        return okHttpCache.getSize();
+    }
+
+    /**
+     * Returns the maximum number of bytes that this cache should use to store
+     * its data.
+     */
+    @libcore.api.CorePlatformApi
+    public long getMaxSize() {
+        return okHttpCache.getMaxSize();
+    }
+
+    /**
+     * Force buffered operations to the filesystem. This ensures that responses
+     * written to the cache will be available the next time the cache is opened,
+     * even if this process is killed. IOException is thrown if the flush fails.
+     */
+    @libcore.api.CorePlatformApi
+    public void flush() throws IOException {
+        okHttpCache.flush();
+    }
+
+    /**
+     * Returns the number of HTTP requests that required the network to either
+     * supply a response or validate a locally cached response.
+     */
+    @libcore.api.CorePlatformApi
+    public int getNetworkCount() {
+        return okHttpCache.getNetworkCount();
+    }
+
+    /**
+     * Returns the number of HTTP requests whose response was provided by the
+     * cache. This may include conditional {@code GET} requests that were
+     * validated over the network.
+     */
+    @libcore.api.CorePlatformApi
+    public int getHitCount() {
+        return okHttpCache.getHitCount();
+    }
+
+    /**
+     * Returns the total number of HTTP requests that were made. This includes
+     * both client requests and requests that were made on the client's behalf
+     * to handle a redirects and retries.
+     */
+    @libcore.api.CorePlatformApi
+    public int getRequestCount() {
+        return okHttpCache.getRequestCount();
+    }
+
+    /** Closes this cache. Stored values will remain on the filesystem. */
+    @libcore.api.CorePlatformApi
+    public void close() throws IOException {
+        okHttpCache.close();
+    }
+
+    /**
+     * 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.
+     */
+    @libcore.api.CorePlatformApi
+    public void delete() throws IOException {
+        okHttpCache.delete();
+    }
+}
diff --git a/repackaged/android/src/main/java/com/android/okhttp/internalandroidapi/Dns.java b/repackaged/android/src/main/java/com/android/okhttp/internalandroidapi/Dns.java
new file mode 100644
index 0000000..859ea80
--- /dev/null
+++ b/repackaged/android/src/main/java/com/android/okhttp/internalandroidapi/Dns.java
@@ -0,0 +1,37 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.okhttp.internalandroidapi;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.List;
+
+/**
+ * A domain name service that resolves IP addresses for host names.
+ * @hide
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.CorePlatformApi
+public interface Dns {
+    /**
+     * Returns the IP addresses of {@code hostname}, in the order they should
+     * be attempted.
+     */
+    @libcore.api.CorePlatformApi
+    List<InetAddress> lookup(String hostname) throws UnknownHostException;
+}
diff --git a/repackaged/android/src/main/java/com/android/okhttp/internalandroidapi/HasCacheHolder.java b/repackaged/android/src/main/java/com/android/okhttp/internalandroidapi/HasCacheHolder.java
new file mode 100644
index 0000000..aa90bf3
--- /dev/null
+++ b/repackaged/android/src/main/java/com/android/okhttp/internalandroidapi/HasCacheHolder.java
@@ -0,0 +1,91 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2018 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 com.android.okhttp.internalandroidapi;
+
+import com.android.okhttp.Cache;
+
+import java.io.File;
+
+/**
+ * An interface used to indicate a class can return a {@link CacheHolder} object.
+ * @hide
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.CorePlatformApi
+public interface HasCacheHolder {
+
+    /**
+     * Returns the {@link CacheHolder} object.
+     */
+    @libcore.api.CorePlatformApi
+    CacheHolder getCacheHolder();
+
+    /**
+     * A holder for an OkHttp internal Cache object. This class exists as an opaque layer over
+     * OkHttp internal classes.
+     * @hide
+     */
+    @libcore.api.CorePlatformApi
+    final class CacheHolder {
+
+        private final Cache okHttpCache;
+
+        private CacheHolder(Cache okHttpCache) {
+            this.okHttpCache = okHttpCache;
+        }
+
+        // This constructor is required for @libcore.api.CorePlatformApi stubs generation. Without
+        // it the constructor above is included in the stubs code which adds a dependency on
+        // okhttp.Cache that we don't want.
+        @SuppressWarnings("unused")
+        private CacheHolder() {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * Returns the underlying {@link Cache} object.
+         * @hide
+         */
+        public Cache getCache() {
+            return okHttpCache;
+        }
+
+        /**
+         * Returns a new {@link CacheHolder} containing an OKHttp Cache with the specified settings.
+         *
+         * @param directory a writable directory
+         * @param maxSizeBytes the maximum number of bytes this cache should use to store
+         */
+        @libcore.api.CorePlatformApi
+        public static CacheHolder create(File directory, long maxSizeBytes) {
+            Cache cache = new Cache(directory, maxSizeBytes);
+            return new CacheHolder(cache);
+        }
+
+        /**
+         * Returns true if the arguments supplied would result in an equivalent cache to this one
+         * being created if they were passed to {@link #create(File, long)}.
+         */
+        @libcore.api.CorePlatformApi
+        public boolean isEquivalent(File directory, long maxSizeBytes) {
+            return (okHttpCache.getDirectory().equals(directory)
+                    && okHttpCache.getMaxSize() == maxSizeBytes
+                    && !okHttpCache.isClosed());
+        }
+    }
+}
diff --git a/repackaged/android/src/main/java/com/android/okhttp/internalandroidapi/HttpURLConnectionFactory.java b/repackaged/android/src/main/java/com/android/okhttp/internalandroidapi/HttpURLConnectionFactory.java
new file mode 100644
index 0000000..38722fe
--- /dev/null
+++ b/repackaged/android/src/main/java/com/android/okhttp/internalandroidapi/HttpURLConnectionFactory.java
@@ -0,0 +1,181 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2017 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 com.android.okhttp.internalandroidapi;
+
+import com.android.okhttp.ConnectionPool;
+import com.android.okhttp.HttpHandler;
+import com.android.okhttp.HttpsHandler;
+import com.android.okhttp.OkHttpClient;
+import com.android.okhttp.OkUrlFactories;
+import com.android.okhttp.OkUrlFactory;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.Proxy;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.UnknownHostException;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+import javax.net.SocketFactory;
+
+/**
+ * A way to construct {@link java.net.HttpURLConnection}s that supports some
+ * configuration on a per-factory or per-connection basis rather than only via
+ * global static state such as {@link java.net.CookieHandler#setDefault(java.net.CookieHandler)}.
+ * The per-factory configuration is <b>optional</b>; if not set, global
+ * configuration or default behavior is used.
+ *
+ * This facade prevents tight coupling with the underlying implementation (on
+ * top of a particular version of OkHttp). Android code outside of libcore
+ * should never depend directly on OkHttp.
+ *
+ * This abstraction is not suitable for general use. Talk to the maintainers of
+ * this class before modifying it or adding additional dependencies.
+ *
+ * @hide
+ * @hide This class is not part of the Android public SDK API
+ */
+@libcore.api.CorePlatformApi
+public final class HttpURLConnectionFactory {
+
+    private ConnectionPool connectionPool;
+    private com.android.okhttp.Dns dns;
+
+    /**
+     * Sets a new ConnectionPool, specific to this URLFactory and not shared with
+     * any other connections, with the given configuration.
+     */
+    @libcore.api.CorePlatformApi
+    public void setNewConnectionPool(int maxIdleConnections, long keepAliveDuration,
+            TimeUnit timeUnit) {
+        this.connectionPool = new ConnectionPool(maxIdleConnections, keepAliveDuration, timeUnit);
+    }
+
+    @libcore.api.CorePlatformApi
+    public void setDns(Dns dns) {
+        Objects.requireNonNull(dns);
+        this.dns = new DnsAdapter(dns);
+    }
+
+    /**
+     * Opens a connection that uses the system default proxy settings and SocketFactory.
+     */
+    public URLConnection openConnection(URL url) throws IOException {
+        return internalOpenConnection(url, null /* socketFactory */, null /* proxy */);
+    }
+
+    /**
+     * Opens a connection that uses the system default SocketFactory and the specified
+     * proxy settings.
+     */
+    public URLConnection openConnection(URL url, Proxy proxy) throws IOException {
+        Objects.requireNonNull(proxy);
+        return internalOpenConnection(url, null /* socketFactory */, proxy);
+    }
+
+    /**
+     * Opens a connection that uses the specified SocketFactory and the system default
+     * proxy settings.
+     */
+    public URLConnection openConnection(URL url, SocketFactory socketFactory) throws IOException {
+        Objects.requireNonNull(socketFactory);
+        return internalOpenConnection(url, socketFactory, null /* proxy */);
+    }
+
+    /**
+     * Opens a connection using the specified SocketFactory and the specified proxy
+     * settings, overriding any system wide configuration.
+     */
+    @libcore.api.CorePlatformApi
+    public URLConnection openConnection(URL url, SocketFactory socketFactory, Proxy proxy)
+            throws IOException {
+        Objects.requireNonNull(socketFactory);
+        Objects.requireNonNull(proxy);
+        return internalOpenConnection(url, socketFactory, proxy);
+    }
+
+    private URLConnection internalOpenConnection(URL url, SocketFactory socketFactoryOrNull,
+            Proxy proxyOrNull) throws IOException {
+        String protocol = url.getProtocol();
+        OkUrlFactory okUrlFactory;
+        // TODO: HttpHandler creates OkUrlFactory instances that share the default ResponseCache.
+        // Could this cause unexpected behavior?
+        if (protocol.equals("http")) {
+            okUrlFactory = HttpHandler.createHttpOkUrlFactory(proxyOrNull);
+        } else if (protocol.equals("https")) {
+            okUrlFactory = HttpsHandler.createHttpsOkUrlFactory(proxyOrNull);
+        } else {
+            // OkHttp only supports HTTP and HTTPS.
+            throw new MalformedURLException("Invalid URL or unrecognized protocol " + protocol);
+        }
+
+        OkHttpClient client = okUrlFactory.client();
+        if (connectionPool != null) {
+            client.setConnectionPool(connectionPool);
+        }
+        if (dns != null) {
+            client.setDns(dns);
+        }
+        if (socketFactoryOrNull != null) {
+            client.setSocketFactory(socketFactoryOrNull);
+        }
+        if (proxyOrNull == null) {
+            return okUrlFactory.open(url);
+        } else {
+            return OkUrlFactories.open(okUrlFactory, url, proxyOrNull);
+        }
+    }
+
+    /**
+     * Adapts a {@link Dns} as a {@link com.android.okhttp.Dns}.
+     */
+    static final class DnsAdapter implements com.android.okhttp.Dns {
+        private final Dns adaptee;
+
+        DnsAdapter(Dns adaptee) {
+            this.adaptee = Objects.requireNonNull(adaptee);
+        }
+
+        @Override
+        public List<InetAddress> lookup(String hostname) throws UnknownHostException {
+            return adaptee.lookup(hostname);
+        }
+
+        @Override
+        public int hashCode() {
+            return 31 * DnsAdapter.class.hashCode() + adaptee.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (!(obj instanceof DnsAdapter)) {
+                return false;
+            }
+            return adaptee.equals(((DnsAdapter) obj).adaptee);
+        }
+
+        @Override
+        public String toString() {
+            return adaptee.toString();
+        }
+    }
+
+}
diff --git a/repackaged/okhttp-android-support/src/main/java/com/android/okhttp/AndroidInternal.java b/repackaged/okhttp-android-support/src/main/java/com/android/okhttp/AndroidInternal.java
new file mode 100644
index 0000000..746f63c
--- /dev/null
+++ b/repackaged/okhttp-android-support/src/main/java/com/android/okhttp/AndroidInternal.java
@@ -0,0 +1,58 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.okhttp;
+
+import com.android.okhttp.internalandroidapi.HasCacheHolder;
+import com.android.okhttp.internalandroidapi.HasCacheHolder.CacheHolder;
+import com.android.okhttp.internal.huc.CacheAdapter;
+
+import java.net.ResponseCache;
+
+/**
+ * Back doors to enable the use of OkHttp within the Android platform libraries. OkHttp is used to
+ * provide the default {@link java.net.HttpURLConnection} / {@link javax.net.ssl.HttpsURLConnection}
+ * implementation including support for a custom {@link ResponseCache}.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AndroidInternal {
+
+  private AndroidInternal() {
+  }
+
+  /** Sets the response cache to be used to read and write cached responses. */
+  public static void setResponseCache(OkUrlFactory okUrlFactory, ResponseCache responseCache) {
+    OkHttpClient client = okUrlFactory.client();
+    if (responseCache instanceof OkCacheContainer) {
+      // Avoid adding layers of wrappers. Rather than wrap the ResponseCache in yet another layer to
+      // make the ResponseCache look like an InternalCache, we can unwrap the Cache instead.
+      // This means that Cache stats will be correctly updated.
+      OkCacheContainer okCacheContainer = (OkCacheContainer) responseCache;
+      client.setCache(okCacheContainer.getCache());
+    // BEGIN Android-added: Recognize internalapi.HasCacheHolder.
+    } else if (responseCache instanceof HasCacheHolder) {
+      // Avoid adding layers of wrappers. Rather than wrap the ResponseCache in yet another layer to
+      // make the ResponseCache look like an InternalCache using CacheAdapter, we can unwrap the
+      // held Cache instead. This means that Cache stats will be correctly updated by OkHttp.
+      HasCacheHolder hasCacheHolder = (HasCacheHolder) responseCache;
+      CacheHolder cacheHolder = hasCacheHolder.getCacheHolder();
+      client.setCache(cacheHolder.getCache());
+    // END Android-added: Recognize internalapi.HasCacheHolder.
+    } else {
+      client.setInternalCache(responseCache != null ? new CacheAdapter(responseCache) : null);
+    }
+  }
+}
diff --git a/repackaged/okhttp-android-support/src/main/java/com/android/okhttp/AndroidShimResponseCache.java b/repackaged/okhttp-android-support/src/main/java/com/android/okhttp/AndroidShimResponseCache.java
new file mode 100644
index 0000000..b0f504a
--- /dev/null
+++ b/repackaged/okhttp-android-support/src/main/java/com/android/okhttp/AndroidShimResponseCache.java
@@ -0,0 +1,151 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.okhttp;
+
+import com.android.okhttp.internal.huc.JavaApiConverter;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.CacheRequest;
+import java.net.CacheResponse;
+import java.net.ResponseCache;
+import java.net.URI;
+import java.net.URLConnection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A class provided for use by Android so that it can continue supporting a {@link ResponseCache}
+ * with stats.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AndroidShimResponseCache extends ResponseCache {
+
+  private final Cache delegate;
+
+  private AndroidShimResponseCache(Cache delegate) {
+    this.delegate = delegate;
+  }
+
+  public static AndroidShimResponseCache create(File directory, long maxSize) throws IOException {
+    Cache cache = new Cache(directory, maxSize);
+    return new AndroidShimResponseCache(cache);
+  }
+
+  public boolean isEquivalent(File directory, long maxSize) {
+    Cache installedCache = getCache();
+    return (installedCache.getDirectory().equals(directory)
+        && installedCache.getMaxSize() == maxSize
+        && !installedCache.isClosed());
+  }
+
+  public Cache getCache() {
+    return delegate;
+  }
+
+  @Override public CacheResponse get(URI uri, String requestMethod,
+      Map<String, List<String>> requestHeaders) throws IOException {
+    Request okRequest = JavaApiConverter.createOkRequest(uri, requestMethod, requestHeaders);
+    Response okResponse = delegate.internalCache.get(okRequest);
+    if (okResponse == null) {
+      return null;
+    }
+    return JavaApiConverter.createJavaCacheResponse(okResponse);
+  }
+
+  @Override public CacheRequest put(URI uri, URLConnection urlConnection) throws IOException {
+    Response okResponse = JavaApiConverter.createOkResponseForCachePut(uri, urlConnection);
+    if (okResponse == null) {
+      // The URLConnection is not cacheable or could not be converted. Stop.
+      return null;
+    }
+    com.android.okhttp.internal.http.CacheRequest okCacheRequest =
+        delegate.internalCache.put(okResponse);
+    if (okCacheRequest == null) {
+      return null;
+    }
+    return JavaApiConverter.createJavaCacheRequest(okCacheRequest);
+  }
+
+  /**
+   * Returns the number of bytes currently being used to store the values in
+   * this cache. This may be greater than the {@link #maxSize} if a background
+   * deletion is pending.
+   */
+  public long size() throws IOException {
+    return delegate.getSize();
+  }
+
+  /**
+   * Returns the maximum number of bytes that this cache should use to store
+   * its data.
+   */
+  public long maxSize() {
+    return delegate.getMaxSize();
+  }
+
+  /**
+   * Force buffered operations to the filesystem. This ensures that responses
+   * written to the cache will be available the next time the cache is opened,
+   * even if this process is killed.
+   */
+  public void flush() throws IOException {
+    delegate.flush();
+  }
+
+  /**
+   * Returns the number of HTTP requests that required the network to either
+   * supply a response or validate a locally cached response.
+   */
+  public int getNetworkCount() {
+    return delegate.getNetworkCount();
+  }
+
+  /**
+   * Returns the number of HTTP requests whose response was provided by the
+   * cache. This may include conditional {@code GET} requests that were
+   * validated over the network.
+   */
+  public int getHitCount() {
+    return delegate.getHitCount();
+  }
+
+  /**
+   * Returns the total number of HTTP requests that were made. This includes
+   * both client requests and requests that were made on the client's behalf
+   * to handle a redirects and retries.
+   */
+  public int getRequestCount() {
+    return delegate.getRequestCount();
+  }
+
+  /**
+   * Uninstalls the cache and releases any active resources. Stored contents
+   * will remain on the filesystem.
+   */
+  public void close() throws IOException {
+    delegate.close();
+  }
+
+  /**
+   * Uninstalls the cache and deletes all of its stored contents.
+   */
+  public void delete() throws IOException {
+    delegate.delete();
+  }
+
+}
diff --git a/repackaged/okhttp-android-support/src/main/java/com/android/okhttp/OkCacheContainer.java b/repackaged/okhttp-android-support/src/main/java/com/android/okhttp/OkCacheContainer.java
new file mode 100644
index 0000000..72e71b1
--- /dev/null
+++ b/repackaged/okhttp-android-support/src/main/java/com/android/okhttp/OkCacheContainer.java
@@ -0,0 +1,26 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp;
+
+/**
+ * An interface that allows OkHttp to detect that a {@link java.net.ResponseCache} contains a
+ * {@link Cache}.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface OkCacheContainer {
+  Cache getCache();
+}
diff --git a/repackaged/okhttp-android-support/src/main/java/com/android/okhttp/internal/huc/CacheAdapter.java b/repackaged/okhttp-android-support/src/main/java/com/android/okhttp/internal/huc/CacheAdapter.java
new file mode 100644
index 0000000..97751d2
--- /dev/null
+++ b/repackaged/okhttp-android-support/src/main/java/com/android/okhttp/internal/huc/CacheAdapter.java
@@ -0,0 +1,107 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.internal.huc;
+
+import com.android.okhttp.Request;
+import com.android.okhttp.Response;
+import com.android.okhttp.internal.InternalCache;
+import com.android.okhttp.internal.http.CacheRequest;
+import com.android.okhttp.internal.http.CacheStrategy;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.CacheResponse;
+import java.net.HttpURLConnection;
+import java.net.ResponseCache;
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+import com.android.okhttp.okio.Okio;
+import com.android.okhttp.okio.Sink;
+
+/** Adapts {@link ResponseCache} to {@link InternalCache}. 
+ * @hide This class is not part of the Android public SDK API*/
+public final class CacheAdapter implements InternalCache {
+  private final ResponseCache delegate;
+
+  public CacheAdapter(ResponseCache delegate) {
+    this.delegate = delegate;
+  }
+
+  public ResponseCache getDelegate() {
+    return delegate;
+  }
+
+  @Override public Response get(Request request) throws IOException {
+    CacheResponse javaResponse = getJavaCachedResponse(request);
+    if (javaResponse == null) {
+      return null;
+    }
+    return JavaApiConverter.createOkResponseForCacheGet(request, javaResponse);
+  }
+
+  @Override public CacheRequest put(Response response) throws IOException {
+    URI uri = response.request().uri();
+    HttpURLConnection connection = JavaApiConverter.createJavaUrlConnectionForCachePut(response);
+    final java.net.CacheRequest request = delegate.put(uri, connection);
+    if (request == null) {
+      return null;
+    }
+    return new CacheRequest() {
+      @Override public Sink body() throws IOException {
+        OutputStream body = request.getBody();
+        return body != null ? Okio.sink(body) : null;
+      }
+
+      @Override public void abort() {
+        request.abort();
+      }
+    };
+  }
+
+  @Override public void remove(Request request) throws IOException {
+    // This method is treated as optional and there is no obvious way of implementing it with
+    // ResponseCache. Removing items from the cache due to modifications made from this client is
+    // not essential given that modifications could be made from any other client. We have to assume
+    // that it's ok to keep using the cached data. Otherwise the server shouldn't declare it as
+    // cacheable or the client should be careful about caching it.
+  }
+
+  @Override public void update(Response cached, Response network) throws IOException {
+    // This method is treated as optional and there is no obvious way of implementing it with
+    // ResponseCache. Updating headers is useful if the server changes the metadata for a resource
+    // (e.g. max age) to extend or truncate the life of that resource in the cache. If the metadata
+    // is not updated the caching behavior may not be optimal, but will obey the metadata sent
+    // with the original cached response.
+  }
+
+  @Override public void trackConditionalCacheHit() {
+    // This method is optional.
+  }
+
+  @Override public void trackResponse(CacheStrategy cacheStrategy) {
+    // This method is optional.
+  }
+
+  /**
+   * Returns the {@link CacheResponse} from the delegate by converting the
+   * OkHttp {@link Request} into the arguments required by the {@link ResponseCache}.
+   */
+  private CacheResponse getJavaCachedResponse(Request request) throws IOException {
+    Map<String, List<String>> headers = JavaApiConverter.extractJavaHeaders(request);
+    return delegate.get(request.uri(), request.method(), headers);
+  }
+}
diff --git a/repackaged/okhttp-android-support/src/main/java/com/android/okhttp/internal/huc/JavaApiConverter.java b/repackaged/okhttp-android-support/src/main/java/com/android/okhttp/internal/huc/JavaApiConverter.java
new file mode 100644
index 0000000..cbd3b83
--- /dev/null
+++ b/repackaged/okhttp-android-support/src/main/java/com/android/okhttp/internal/huc/JavaApiConverter.java
@@ -0,0 +1,867 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.internal.huc;
+
+import com.android.okhttp.Handshake;
+import com.android.okhttp.Headers;
+import com.android.okhttp.MediaType;
+import com.android.okhttp.Request;
+import com.android.okhttp.RequestBody;
+import com.android.okhttp.Response;
+import com.android.okhttp.ResponseBody;
+import com.android.okhttp.internal.Internal;
+import com.android.okhttp.internal.Util;
+import com.android.okhttp.internal.http.CacheRequest;
+import com.android.okhttp.internal.http.HttpMethod;
+import com.android.okhttp.internal.http.OkHeaders;
+import com.android.okhttp.internal.http.StatusLine;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.CacheResponse;
+import java.net.HttpURLConnection;
+import java.net.ProtocolException;
+import java.net.SecureCacheResponse;
+import java.net.URI;
+import java.net.URLConnection;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSocketFactory;
+import com.android.okhttp.okio.BufferedSource;
+import com.android.okhttp.okio.Okio;
+import com.android.okhttp.okio.Sink;
+
+/**
+ * Helper methods that convert between Java and OkHttp representations.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class JavaApiConverter {
+  private static final RequestBody EMPTY_REQUEST_BODY = RequestBody.create(null, new byte[0]);
+
+  private JavaApiConverter() {
+  }
+
+  /**
+   * Creates an OkHttp {@link Response} using the supplied {@link URI} and {@link URLConnection}
+   * to supply the data. The URLConnection is assumed to already be connected. If this method
+   * returns {@code null} the response is uncacheable.
+   */
+  public static Response createOkResponseForCachePut(URI uri, URLConnection urlConnection)
+      throws IOException {
+
+    HttpURLConnection httpUrlConnection = (HttpURLConnection) urlConnection;
+
+    Response.Builder okResponseBuilder = new Response.Builder();
+
+    // Request: Create one from the URL connection.
+    Headers responseHeaders = createHeaders(urlConnection.getHeaderFields());
+    // Some request headers are needed for Vary caching.
+    Headers varyHeaders = varyHeaders(urlConnection, responseHeaders);
+    if (varyHeaders == null) {
+      return null;
+    }
+
+    // OkHttp's Call API requires a placeholder body; the real body will be streamed separately.
+    String requestMethod = httpUrlConnection.getRequestMethod();
+    RequestBody placeholderBody = HttpMethod.requiresRequestBody(requestMethod)
+        ? EMPTY_REQUEST_BODY
+        : null;
+
+    Request okRequest = new Request.Builder()
+        .url(uri.toString())
+        .method(requestMethod, placeholderBody)
+        .headers(varyHeaders)
+        .build();
+    okResponseBuilder.request(okRequest);
+
+    // Status line
+    StatusLine statusLine = StatusLine.parse(extractStatusLine(httpUrlConnection));
+    okResponseBuilder.protocol(statusLine.protocol);
+    okResponseBuilder.code(statusLine.code);
+    okResponseBuilder.message(statusLine.message);
+
+    // A network response is required for the Cache to find any Vary headers it needs.
+    Response networkResponse = okResponseBuilder.build();
+    okResponseBuilder.networkResponse(networkResponse);
+
+    // Response headers
+    Headers okHeaders = extractOkResponseHeaders(httpUrlConnection);
+    okResponseBuilder.headers(okHeaders);
+
+    // Response body
+    ResponseBody okBody = createOkBody(urlConnection);
+    okResponseBuilder.body(okBody);
+
+    // Handle SSL handshake information as needed.
+    if (httpUrlConnection instanceof HttpsURLConnection) {
+      HttpsURLConnection httpsUrlConnection = (HttpsURLConnection) httpUrlConnection;
+
+      Certificate[] peerCertificates;
+      try {
+        peerCertificates = httpsUrlConnection.getServerCertificates();
+      } catch (SSLPeerUnverifiedException e) {
+        peerCertificates = null;
+      }
+
+      Certificate[] localCertificates = httpsUrlConnection.getLocalCertificates();
+
+      Handshake handshake = Handshake.get(
+          httpsUrlConnection.getCipherSuite(), nullSafeImmutableList(peerCertificates),
+          nullSafeImmutableList(localCertificates));
+      okResponseBuilder.handshake(handshake);
+    }
+
+    return okResponseBuilder.build();
+  }
+
+  /**
+   * Returns headers for the header names and values in the {@link Map}.
+   */
+  private static Headers createHeaders(Map<String, List<String>> headers) {
+    Headers.Builder builder = new Headers.Builder();
+    for (Map.Entry<String, List<String>> header : headers.entrySet()) {
+      if (header.getKey() == null || header.getValue() == null) {
+        continue;
+      }
+      String name = header.getKey().trim();
+      for (String value : header.getValue()) {
+        String trimmedValue = value.trim();
+        Internal.instance.addLenient(builder, name, trimmedValue);
+      }
+    }
+    return builder.build();
+  }
+
+  private static Headers varyHeaders(URLConnection urlConnection, Headers responseHeaders) {
+    if (OkHeaders.hasVaryAll(responseHeaders)) {
+      // "*" means that this will be treated as uncacheable anyway.
+      return null;
+    }
+    Set<String> varyFields = OkHeaders.varyFields(responseHeaders);
+    if (varyFields.isEmpty()) {
+      return new Headers.Builder().build();
+    }
+
+    // This probably indicates another HTTP stack is trying to use the shared ResponseCache.
+    // We cannot guarantee this case will work properly because we cannot reliably extract *all*
+    // the request header values, and we can't get multiple Vary request header values.
+    // We also can't be sure about the Accept-Encoding behavior of other stacks.
+    if (!(urlConnection instanceof CacheHttpURLConnection
+        || urlConnection instanceof CacheHttpsURLConnection)) {
+      return null;
+    }
+
+    // This is the case we expect: The URLConnection is from a call to
+    // JavaApiConverter.createJavaUrlConnection() and we have access to the user's request headers.
+    Map<String, List<String>> requestProperties = urlConnection.getRequestProperties();
+    Headers.Builder result = new Headers.Builder();
+    for (String fieldName : varyFields) {
+      List<String> fieldValues = requestProperties.get(fieldName);
+      if (fieldValues == null) {
+        if (fieldName.equals("Accept-Encoding")) {
+          // Accept-Encoding is special. If OkHttp sees Accept-Encoding is unset it will add
+          // "gzip". We don't have access to the request that was actually made so we must do the
+          // same.
+          result.add("Accept-Encoding", "gzip");
+        }
+      } else {
+        for (String fieldValue : fieldValues) {
+          Internal.instance.addLenient(result, fieldName, fieldValue);
+        }
+      }
+    }
+    return result.build();
+  }
+
+  /**
+   * Creates an OkHttp {@link Response} using the supplied {@link Request} and {@link CacheResponse}
+   * to supply the data.
+   */
+  static Response createOkResponseForCacheGet(Request request, CacheResponse javaResponse)
+      throws IOException {
+
+    // Build a cache request for the response to use.
+    Headers responseHeaders = createHeaders(javaResponse.getHeaders());
+    Headers varyHeaders;
+    if (OkHeaders.hasVaryAll(responseHeaders)) {
+      // "*" means that this will be treated as uncacheable anyway.
+      varyHeaders = new Headers.Builder().build();
+    } else {
+      varyHeaders = OkHeaders.varyHeaders(request.headers(), responseHeaders);
+    }
+
+    Request cacheRequest = new Request.Builder()
+        .url(request.httpUrl())
+        .method(request.method(), null)
+        .headers(varyHeaders)
+        .build();
+
+    Response.Builder okResponseBuilder = new Response.Builder();
+
+    // Request: Use the cacheRequest we built.
+    okResponseBuilder.request(cacheRequest);
+
+    // Status line: Java has this as one of the headers.
+    StatusLine statusLine = StatusLine.parse(extractStatusLine(javaResponse));
+    okResponseBuilder.protocol(statusLine.protocol);
+    okResponseBuilder.code(statusLine.code);
+    okResponseBuilder.message(statusLine.message);
+
+    // Response headers
+    Headers okHeaders = extractOkHeaders(javaResponse);
+    okResponseBuilder.headers(okHeaders);
+
+    // Response body
+    ResponseBody okBody = createOkBody(okHeaders, javaResponse);
+    okResponseBuilder.body(okBody);
+
+    // Handle SSL handshake information as needed.
+    if (javaResponse instanceof SecureCacheResponse) {
+      SecureCacheResponse javaSecureCacheResponse = (SecureCacheResponse) javaResponse;
+
+      // Handshake doesn't support null lists.
+      List<Certificate> peerCertificates;
+      try {
+        peerCertificates = javaSecureCacheResponse.getServerCertificateChain();
+      } catch (SSLPeerUnverifiedException e) {
+        peerCertificates = Collections.emptyList();
+      }
+      List<Certificate> localCertificates = javaSecureCacheResponse.getLocalCertificateChain();
+      if (localCertificates == null) {
+        localCertificates = Collections.emptyList();
+      }
+      Handshake handshake = Handshake.get(
+          javaSecureCacheResponse.getCipherSuite(), peerCertificates, localCertificates);
+      okResponseBuilder.handshake(handshake);
+    }
+
+    return okResponseBuilder.build();
+  }
+
+  /**
+   * Creates an OkHttp {@link Request} from the supplied information.
+   *
+   * <p>This method allows a {@code null} value for {@code requestHeaders} for situations
+   * where a connection is already connected and access to the headers has been lost.
+   * See {@link java.net.HttpURLConnection#getRequestProperties()} for details.
+   */
+  public static Request createOkRequest(
+      URI uri, String requestMethod, Map<String, List<String>> requestHeaders) {
+    // OkHttp's Call API requires a placeholder body; the real body will be streamed separately.
+    RequestBody placeholderBody = HttpMethod.requiresRequestBody(requestMethod)
+        ? EMPTY_REQUEST_BODY
+        : null;
+
+    Request.Builder builder = new Request.Builder()
+        .url(uri.toString())
+        .method(requestMethod, placeholderBody);
+
+    if (requestHeaders != null) {
+      Headers headers = extractOkHeaders(requestHeaders);
+      builder.headers(headers);
+    }
+    return builder.build();
+  }
+
+  /**
+   * Creates a {@link java.net.CacheResponse} of the correct (sub)type using information
+   * gathered from the supplied {@link Response}.
+   */
+  public static CacheResponse createJavaCacheResponse(final Response response) {
+    final Headers headers = response.headers();
+    final ResponseBody body = response.body();
+    if (response.request().isHttps()) {
+      final Handshake handshake = response.handshake();
+      return new SecureCacheResponse() {
+        @Override
+        public String getCipherSuite() {
+          return handshake != null ? handshake.cipherSuite() : null;
+        }
+
+        @Override
+        public List<Certificate> getLocalCertificateChain() {
+          if (handshake == null) return null;
+          // Java requires null, not an empty list here.
+          List<Certificate> certificates = handshake.localCertificates();
+          return certificates.size() > 0 ? certificates : null;
+        }
+
+        @Override
+        public List<Certificate> getServerCertificateChain() throws SSLPeerUnverifiedException {
+          if (handshake == null) return null;
+          // Java requires null, not an empty list here.
+          List<Certificate> certificates = handshake.peerCertificates();
+          return certificates.size() > 0 ? certificates : null;
+        }
+
+        @Override
+        public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
+          if (handshake == null) return null;
+          return handshake.peerPrincipal();
+        }
+
+        @Override
+        public Principal getLocalPrincipal() {
+          if (handshake == null) return null;
+          return handshake.localPrincipal();
+        }
+
+        @Override
+        public Map<String, List<String>> getHeaders() throws IOException {
+          // Java requires that the entry with a null key be the status line.
+          return OkHeaders.toMultimap(headers, StatusLine.get(response).toString());
+        }
+
+        @Override
+        public InputStream getBody() throws IOException {
+          if (body == null) return null;
+          return body.byteStream();
+        }
+      };
+    } else {
+      return new CacheResponse() {
+        @Override
+        public Map<String, List<String>> getHeaders() throws IOException {
+          // Java requires that the entry with a null key be the status line.
+          return OkHeaders.toMultimap(headers, StatusLine.get(response).toString());
+        }
+
+        @Override
+        public InputStream getBody() throws IOException {
+          if (body == null) return null;
+          return body.byteStream();
+        }
+      };
+    }
+  }
+
+  public static java.net.CacheRequest createJavaCacheRequest(final CacheRequest okCacheRequest) {
+    return new java.net.CacheRequest() {
+      @Override
+      public void abort() {
+        okCacheRequest.abort();
+      }
+      @Override
+      public OutputStream getBody() throws IOException {
+        Sink body = okCacheRequest.body();
+        if (body == null) {
+          return null;
+        }
+        return Okio.buffer(body).outputStream();
+      }
+    };
+  }
+
+  /**
+   * Creates an {@link java.net.HttpURLConnection} of the correct subclass from the supplied OkHttp
+   * {@link Response}.
+   */
+  static HttpURLConnection createJavaUrlConnectionForCachePut(Response okResponse) {
+    Request request = okResponse.request();
+    // Create an object of the correct class in case the ResponseCache uses instanceof.
+    if (request.isHttps()) {
+      return new CacheHttpsURLConnection(new CacheHttpURLConnection(okResponse));
+    } else {
+      return new CacheHttpURLConnection(okResponse);
+    }
+  }
+
+  /**
+   * Extracts an immutable request header map from the supplied {@link com.android.okhttp.Headers}.
+   */
+  static Map<String, List<String>> extractJavaHeaders(Request request) {
+    return OkHeaders.toMultimap(request.headers(), null);
+  }
+
+  /**
+   * Extracts OkHttp headers from the supplied {@link java.net.CacheResponse}. Only real headers are
+   * extracted. See {@link #extractStatusLine(java.net.CacheResponse)}.
+   */
+  private static Headers extractOkHeaders(CacheResponse javaResponse) throws IOException {
+    Map<String, List<String>> javaResponseHeaders = javaResponse.getHeaders();
+    return extractOkHeaders(javaResponseHeaders);
+  }
+
+  /**
+   * Extracts OkHttp headers from the supplied {@link java.net.HttpURLConnection}. Only real headers
+   * are extracted. See {@link #extractStatusLine(java.net.HttpURLConnection)}.
+   */
+  private static Headers extractOkResponseHeaders(HttpURLConnection httpUrlConnection) {
+    Map<String, List<String>> javaResponseHeaders = httpUrlConnection.getHeaderFields();
+    return extractOkHeaders(javaResponseHeaders);
+  }
+
+  /**
+   * Extracts OkHttp headers from the supplied {@link Map}. Only real headers are
+   * extracted. Any entry (one with a {@code null} key) is discarded.
+   */
+  // @VisibleForTesting
+  static Headers extractOkHeaders(Map<String, List<String>> javaHeaders) {
+    Headers.Builder okHeadersBuilder = new Headers.Builder();
+    for (Map.Entry<String, List<String>> javaHeader : javaHeaders.entrySet()) {
+      String name = javaHeader.getKey();
+      if (name == null) {
+        // The Java API uses the null key to store the status line in responses.
+        // Earlier versions of OkHttp would use the null key to store the "request line" in
+        // requests. e.g. "GET / HTTP 1.1". Although this is no longer the case it must be
+        // explicitly ignored because Headers.Builder does not support null keys.
+        continue;
+      }
+      for (String value : javaHeader.getValue()) {
+        Internal.instance.addLenient(okHeadersBuilder, name, value);
+      }
+    }
+    return okHeadersBuilder.build();
+  }
+
+  /**
+   * Extracts the status line from the supplied Java API {@link java.net.HttpURLConnection}.
+   * As per the spec, the status line is held as the header with the null key. Returns {@code null}
+   * if there is no status line.
+   */
+  private static String extractStatusLine(HttpURLConnection httpUrlConnection) {
+    // Java specifies that this will be be response header with a null key.
+    return httpUrlConnection.getHeaderField(null);
+  }
+
+  /**
+   * Extracts the status line from the supplied Java API {@link java.net.CacheResponse}.
+   * As per the spec, the status line is held as the header with the null key. Throws a
+   * {@link ProtocolException} if there is no status line.
+   */
+  private static String extractStatusLine(CacheResponse javaResponse) throws IOException {
+    Map<String, List<String>> javaResponseHeaders = javaResponse.getHeaders();
+    return extractStatusLine(javaResponseHeaders);
+  }
+
+  // VisibleForTesting
+  static String extractStatusLine(Map<String, List<String>> javaResponseHeaders)
+      throws ProtocolException {
+    List<String> values = javaResponseHeaders.get(null);
+    if (values == null || values.size() == 0) {
+      // The status line is missing. This suggests a badly behaving cache.
+      throw new ProtocolException(
+          "CacheResponse is missing a \'null\' header containing the status line. Headers="
+          + javaResponseHeaders);
+    }
+    return values.get(0);
+  }
+
+  /**
+   * Creates an OkHttp Response.Body containing the supplied information.
+   */
+  private static ResponseBody createOkBody(final Headers okHeaders,
+      final CacheResponse cacheResponse) {
+    return new ResponseBody() {
+      private BufferedSource body;
+
+      @Override
+      public MediaType contentType() {
+        String contentTypeHeader = okHeaders.get("Content-Type");
+        return contentTypeHeader == null ? null : MediaType.parse(contentTypeHeader);
+      }
+
+      @Override
+      public long contentLength() {
+        return OkHeaders.contentLength(okHeaders);
+      }
+      @Override public BufferedSource source() throws IOException {
+        if (body == null) {
+          InputStream is = cacheResponse.getBody();
+          body = Okio.buffer(Okio.source(is));
+        }
+        return body;
+      }
+    };
+  }
+
+  /**
+   * Creates an OkHttp Response.Body containing the supplied information.
+   */
+  private static ResponseBody createOkBody(final URLConnection urlConnection) {
+    if (!urlConnection.getDoInput()) {
+      return null;
+    }
+    return new ResponseBody() {
+      private BufferedSource body;
+
+      @Override public MediaType contentType() {
+        String contentTypeHeader = urlConnection.getContentType();
+        return contentTypeHeader == null ? null : MediaType.parse(contentTypeHeader);
+      }
+      @Override public long contentLength() {
+        String s = urlConnection.getHeaderField("Content-Length");
+        return stringToLong(s);
+      }
+      @Override public BufferedSource source() throws IOException {
+        if (body == null) {
+          InputStream is = urlConnection.getInputStream();
+          body = Okio.buffer(Okio.source(is));
+        }
+        return body;
+      }
+    };
+  }
+
+  /**
+   * An {@link java.net.HttpURLConnection} that represents an HTTP request at the point where
+   * the request has been made, and the response headers have been received, but the body content,
+   * if present, has not been read yet. This intended to provide enough information for
+   * {@link java.net.ResponseCache} subclasses and no more.
+   *
+   * <p>Much of the method implementations are overrides to delegate to the OkHttp request and
+   * response, or to deny access to information as a real HttpURLConnection would after connection.
+   */
+  private static final class CacheHttpURLConnection extends HttpURLConnection {
+
+    private final Request request;
+    private final Response response;
+
+    public CacheHttpURLConnection(Response response) {
+      super(response.request().url());
+      this.request = response.request();
+      this.response = response;
+
+      // Configure URLConnection inherited fields.
+      this.connected = true;
+      this.doOutput = request.body() != null;
+      this.doInput = true;
+      this.useCaches = true;
+
+      // Configure HttpUrlConnection inherited fields.
+      this.method = request.method();
+    }
+
+    // HTTP connection lifecycle methods
+
+    @Override
+    public void connect() throws IOException {
+      throw throwRequestModificationException();
+    }
+
+    @Override
+    public void disconnect() {
+      throw throwRequestModificationException();
+    }
+
+    // HTTP Request methods
+
+    @Override
+    public void setRequestProperty(String key, String value) {
+      throw throwRequestModificationException();
+    }
+
+    @Override
+    public void addRequestProperty(String key, String value) {
+      throw throwRequestModificationException();
+    }
+
+    @Override
+    public String getRequestProperty(String key) {
+      return request.header(key);
+    }
+
+    @Override
+    public Map<String, List<String>> getRequestProperties() {
+      // The RI and OkHttp's HttpURLConnectionImpl fail this call after connect() as required by the
+      // spec. There seems no good reason why this should fail while getRequestProperty() is ok.
+      // We don't fail here, because we need all request header values for caching Vary responses
+      // correctly.
+      return OkHeaders.toMultimap(request.headers(), null);
+    }
+
+    @Override
+    public void setFixedLengthStreamingMode(int contentLength) {
+      throw throwRequestModificationException();
+    }
+
+    @Override
+    public void setFixedLengthStreamingMode(long contentLength) {
+      throw throwRequestModificationException();
+    }
+
+    @Override
+    public void setChunkedStreamingMode(int chunklen) {
+      throw throwRequestModificationException();
+    }
+
+    @Override
+    public void setInstanceFollowRedirects(boolean followRedirects) {
+      throw throwRequestModificationException();
+    }
+
+    @Override
+    public boolean getInstanceFollowRedirects() {
+      // Return the platform default.
+      return super.getInstanceFollowRedirects();
+    }
+
+    @Override
+    public void setRequestMethod(String method) throws ProtocolException {
+      throw throwRequestModificationException();
+    }
+
+    @Override
+    public String getRequestMethod() {
+      return request.method();
+    }
+
+    // HTTP Response methods
+
+    @Override
+    public String getHeaderFieldKey(int position) {
+      // Deal with index 0 meaning "status line"
+      if (position < 0) {
+        throw new IllegalArgumentException("Invalid header index: " + position);
+      }
+      if (position == 0) {
+        return null;
+      }
+      return response.headers().name(position - 1);
+    }
+
+    @Override
+    public String getHeaderField(int position) {
+      // Deal with index 0 meaning "status line"
+      if (position < 0) {
+        throw new IllegalArgumentException("Invalid header index: " + position);
+      }
+      if (position == 0) {
+        return StatusLine.get(response).toString();
+      }
+      return response.headers().value(position - 1);
+    }
+
+    @Override
+    public String getHeaderField(String fieldName) {
+      return fieldName == null
+          ? StatusLine.get(response).toString()
+          : response.headers().get(fieldName);
+    }
+
+    @Override
+    public Map<String, List<String>> getHeaderFields() {
+      return OkHeaders.toMultimap(response.headers(), StatusLine.get(response).toString());
+    }
+
+    @Override
+    public int getResponseCode() throws IOException {
+      return response.code();
+    }
+
+    @Override
+    public String getResponseMessage() throws IOException {
+      return response.message();
+    }
+
+    @Override
+    public InputStream getErrorStream() {
+      return null;
+    }
+
+    // HTTP miscellaneous methods
+
+    @Override
+    public boolean usingProxy() {
+      // It's safe to return false here, even if a proxy is in use. The problem is we don't
+      // necessarily know if we're going to use a proxy by the time we ask the cache for a response.
+      return false;
+    }
+
+    // URLConnection methods
+
+    @Override
+    public void setConnectTimeout(int timeout) {
+      throw throwRequestModificationException();
+    }
+
+    @Override
+    public int getConnectTimeout() {
+      // Impossible to say.
+      return 0;
+    }
+
+    @Override
+    public void setReadTimeout(int timeout) {
+      throw throwRequestModificationException();
+    }
+
+    @Override
+    public int getReadTimeout() {
+      // Impossible to say.
+      return 0;
+    }
+
+    @Override
+    public Object getContent() throws IOException {
+      throw throwResponseBodyAccessException();
+    }
+
+    @Override
+    public Object getContent(Class[] classes) throws IOException {
+      throw throwResponseBodyAccessException();
+    }
+
+    @Override
+    public InputStream getInputStream() throws IOException {
+      throw throwResponseBodyAccessException();
+    }
+
+    @Override
+    public OutputStream getOutputStream() throws IOException {
+      throw throwRequestModificationException();
+    }
+
+    @Override
+    public void setDoInput(boolean doInput) {
+      throw throwRequestModificationException();
+    }
+
+    @Override
+    public boolean getDoInput() {
+      return doInput;
+    }
+
+    @Override
+    public void setDoOutput(boolean doOutput) {
+      throw throwRequestModificationException();
+    }
+
+    @Override
+    public boolean getDoOutput() {
+      return doOutput;
+    }
+
+    @Override
+    public void setAllowUserInteraction(boolean allowUserInteraction) {
+      throw throwRequestModificationException();
+    }
+
+    @Override
+    public boolean getAllowUserInteraction() {
+      return false;
+    }
+
+    @Override
+    public void setUseCaches(boolean useCaches) {
+      throw throwRequestModificationException();
+    }
+
+    @Override
+    public boolean getUseCaches() {
+      return super.getUseCaches();
+    }
+
+    @Override
+    public void setIfModifiedSince(long ifModifiedSince) {
+      throw throwRequestModificationException();
+    }
+
+    @Override
+    public long getIfModifiedSince() {
+      return stringToLong(request.headers().get("If-Modified-Since"));
+    }
+
+    @Override
+    public boolean getDefaultUseCaches() {
+      return super.getDefaultUseCaches();
+    }
+
+    @Override
+    public void setDefaultUseCaches(boolean defaultUseCaches) {
+      super.setDefaultUseCaches(defaultUseCaches);
+    }
+  }
+
+  /** An HttpsURLConnection to offer to the cache. */
+  private static final class CacheHttpsURLConnection extends DelegatingHttpsURLConnection {
+    private final CacheHttpURLConnection delegate;
+
+    public CacheHttpsURLConnection(CacheHttpURLConnection delegate) {
+      super(delegate);
+      this.delegate = delegate;
+    }
+
+    @Override protected Handshake handshake() {
+      return delegate.response.handshake();
+    }
+
+    @Override public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
+      throw throwRequestModificationException();
+    }
+
+    @Override public HostnameVerifier getHostnameVerifier() {
+      throw throwRequestSslAccessException();
+    }
+
+    @Override public void setSSLSocketFactory(SSLSocketFactory socketFactory) {
+      throw throwRequestModificationException();
+    }
+
+    @Override public SSLSocketFactory getSSLSocketFactory() {
+      throw throwRequestSslAccessException();
+    }
+
+    @Override public long getContentLengthLong() {
+      return delegate.getContentLengthLong();
+    }
+
+    @Override public void setFixedLengthStreamingMode(long contentLength) {
+      delegate.setFixedLengthStreamingMode(contentLength);
+    }
+
+    @Override public long getHeaderFieldLong(String field, long defaultValue) {
+      return delegate.getHeaderFieldLong(field, defaultValue);
+    }
+  }
+
+  private static RuntimeException throwRequestModificationException() {
+    throw new UnsupportedOperationException("ResponseCache cannot modify the request.");
+  }
+
+  private static RuntimeException throwRequestHeaderAccessException() {
+    throw new UnsupportedOperationException("ResponseCache cannot access request headers");
+  }
+
+  private static RuntimeException throwRequestSslAccessException() {
+    throw new UnsupportedOperationException("ResponseCache cannot access SSL internals");
+  }
+
+  private static RuntimeException throwResponseBodyAccessException() {
+    throw new UnsupportedOperationException("ResponseCache cannot access the response body.");
+  }
+
+  private static <T> List<T> nullSafeImmutableList(T[] elements) {
+    return elements == null ? Collections.<T>emptyList() : Util.immutableList(elements);
+  }
+
+  private static long stringToLong(String s) {
+    if (s == null) return -1;
+    try {
+      return Long.parseLong(s);
+    } catch (NumberFormatException e) {
+      return -1;
+    }
+  }
+}
diff --git a/repackaged/okhttp-urlconnection/src/main/java/com/android/okhttp/OkUrlFactory.java b/repackaged/okhttp-urlconnection/src/main/java/com/android/okhttp/OkUrlFactory.java
new file mode 100644
index 0000000..43e8259
--- /dev/null
+++ b/repackaged/okhttp-urlconnection/src/main/java/com/android/okhttp/OkUrlFactory.java
@@ -0,0 +1,100 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp;
+
+import com.android.okhttp.internal.URLFilter;
+import com.android.okhttp.internal.huc.HttpURLConnectionImpl;
+import com.android.okhttp.internal.huc.HttpsURLConnectionImpl;
+
+import java.net.HttpURLConnection;
+import java.net.Proxy;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class OkUrlFactory implements URLStreamHandlerFactory, Cloneable {
+  private final OkHttpClient client;
+  private URLFilter urlFilter;
+
+  public OkUrlFactory(OkHttpClient client) {
+    this.client = client;
+  }
+
+  public OkHttpClient client() {
+    return client;
+  }
+
+  void setUrlFilter(URLFilter filter) {
+    urlFilter = filter;
+  }
+
+  /**
+   * Returns a copy of this stream handler factory that includes a shallow copy
+   * of the internal {@linkplain OkHttpClient HTTP client}.
+   */
+  @Override public OkUrlFactory clone() {
+    return new OkUrlFactory(client.clone());
+  }
+
+  public HttpURLConnection open(URL url) {
+    return open(url, client.getProxy());
+  }
+
+  HttpURLConnection open(URL url, Proxy proxy) {
+    String protocol = url.getProtocol();
+    OkHttpClient copy = client.copyWithDefaults();
+    copy.setProxy(proxy);
+
+    if (protocol.equals("http")) return new HttpURLConnectionImpl(url, copy, urlFilter);
+    if (protocol.equals("https")) return new HttpsURLConnectionImpl(url, copy, urlFilter);
+    throw new IllegalArgumentException("Unexpected protocol: " + protocol);
+  }
+
+  /**
+   * Creates a URLStreamHandler as a {@link java.net.URL#setURLStreamHandlerFactory}.
+   *
+   * <p>This code configures OkHttp to handle all HTTP and HTTPS connections
+   * created with {@link java.net.URL#openConnection()}: <pre>   {@code
+   *
+   *   OkHttpClient okHttpClient = new OkHttpClient();
+   *   URL.setURLStreamHandlerFactory(new OkUrlFactory(okHttpClient));
+   * }</pre>
+   */
+  @Override public URLStreamHandler createURLStreamHandler(final String protocol) {
+    if (!protocol.equals("http") && !protocol.equals("https")) return null;
+
+    return new URLStreamHandler() {
+      @Override protected URLConnection openConnection(URL url) {
+        return open(url);
+      }
+
+      @Override protected URLConnection openConnection(URL url, Proxy proxy) {
+        return open(url, proxy);
+      }
+
+      @Override protected int getDefaultPort() {
+        if (protocol.equals("http")) return 80;
+        if (protocol.equals("https")) return 443;
+        throw new AssertionError();
+      }
+    };
+  }
+}
diff --git a/repackaged/okhttp-urlconnection/src/main/java/com/android/okhttp/internal/URLFilter.java b/repackaged/okhttp-urlconnection/src/main/java/com/android/okhttp/internal/URLFilter.java
new file mode 100644
index 0000000..9f69a0f
--- /dev/null
+++ b/repackaged/okhttp-urlconnection/src/main/java/com/android/okhttp/internal/URLFilter.java
@@ -0,0 +1,34 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2016 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 com.android.okhttp.internal;
+import java.io.IOException;
+import java.net.URL;
+
+/**
+ * Request filter based on the request's URL.
+ *
+ * @deprecated use {@link okhttp3.Interceptor} for non-HttpURLConnection filtering.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface URLFilter {
+  /**
+   * Check whether request to the provided URL is permitted to be issued.
+   *
+   * @throws IOException if the request to the provided URL is not permitted.
+   */
+  void checkURLPermitted(URL url) throws IOException;
+}
diff --git a/repackaged/okhttp-urlconnection/src/main/java/com/android/okhttp/internal/huc/DelegatingHttpsURLConnection.java b/repackaged/okhttp-urlconnection/src/main/java/com/android/okhttp/internal/huc/DelegatingHttpsURLConnection.java
new file mode 100644
index 0000000..25cf6fb
--- /dev/null
+++ b/repackaged/okhttp-urlconnection/src/main/java/com/android/okhttp/internal/huc/DelegatingHttpsURLConnection.java
@@ -0,0 +1,293 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  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.android.okhttp.internal.huc;
+
+import com.android.okhttp.Handshake;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.ProtocolException;
+import java.net.URL;
+import java.security.Permission;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.util.List;
+import java.util.Map;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSocketFactory;
+
+/**
+ * Implement an HTTPS connection by delegating to an HTTP connection for
+ * everything but the HTTPS-specific stuff.
+ */
+abstract class DelegatingHttpsURLConnection extends HttpsURLConnection {
+  private final HttpURLConnection delegate;
+
+  public DelegatingHttpsURLConnection(HttpURLConnection delegate) {
+    super(delegate.getURL());
+    this.delegate = delegate;
+  }
+
+  protected abstract Handshake handshake();
+
+  @Override public abstract void setHostnameVerifier(HostnameVerifier hostnameVerifier);
+
+  @Override public abstract HostnameVerifier getHostnameVerifier();
+
+  @Override public abstract void setSSLSocketFactory(SSLSocketFactory sslSocketFactory);
+
+  @Override public abstract SSLSocketFactory getSSLSocketFactory();
+
+  @Override public String getCipherSuite() {
+    Handshake handshake = handshake();
+    return handshake != null ? handshake.cipherSuite() : null;
+  }
+
+  @Override public Certificate[] getLocalCertificates() {
+    Handshake handshake = handshake();
+    if (handshake == null) return null;
+    List<Certificate> result = handshake.localCertificates();
+    return !result.isEmpty() ? result.toArray(new Certificate[result.size()]) : null;
+  }
+
+  @Override public Certificate[] getServerCertificates() throws SSLPeerUnverifiedException {
+    Handshake handshake = handshake();
+    if (handshake == null) return null;
+    List<Certificate> result = handshake.peerCertificates();
+    return !result.isEmpty() ? result.toArray(new Certificate[result.size()]) : null;
+  }
+
+  @Override public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
+    Handshake handshake = handshake();
+    return handshake != null ? handshake.peerPrincipal() : null;
+  }
+
+  @Override public Principal getLocalPrincipal() {
+    Handshake handshake = handshake();
+    return handshake != null ? handshake.localPrincipal() : null;
+  }
+
+  @Override public void connect() throws IOException {
+    connected = true;
+    delegate.connect();
+  }
+
+  @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 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 position) {
+    return delegate.getHeaderFieldKey(position);
+  }
+
+  @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);
+  }
+}
diff --git a/repackaged/okhttp-urlconnection/src/main/java/com/android/okhttp/internal/huc/HttpURLConnectionImpl.java b/repackaged/okhttp-urlconnection/src/main/java/com/android/okhttp/internal/huc/HttpURLConnectionImpl.java
new file mode 100644
index 0000000..962bc99
--- /dev/null
+++ b/repackaged/okhttp-urlconnection/src/main/java/com/android/okhttp/internal/huc/HttpURLConnectionImpl.java
@@ -0,0 +1,641 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  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.android.okhttp.internal.huc;
+
+import com.android.okhttp.Connection;
+import com.android.okhttp.Handshake;
+import com.android.okhttp.Headers;
+import com.android.okhttp.HttpUrl;
+import com.android.okhttp.OkHttpClient;
+import com.android.okhttp.Protocol;
+import com.android.okhttp.Request;
+import com.android.okhttp.RequestBody;
+import com.android.okhttp.Response;
+import com.android.okhttp.Route;
+import com.android.okhttp.internal.Internal;
+import com.android.okhttp.internal.Platform;
+import com.android.okhttp.internal.URLFilter;
+import com.android.okhttp.internal.Util;
+import com.android.okhttp.internal.Version;
+import com.android.okhttp.internal.http.HttpDate;
+import com.android.okhttp.internal.http.HttpEngine;
+import com.android.okhttp.internal.http.HttpMethod;
+import com.android.okhttp.internal.http.OkHeaders;
+import com.android.okhttp.internal.http.RequestException;
+import com.android.okhttp.internal.http.RetryableSink;
+import com.android.okhttp.internal.http.RouteException;
+import com.android.okhttp.internal.http.StatusLine;
+import com.android.okhttp.internal.http.StreamAllocation;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpRetryException;
+import java.net.HttpURLConnection;
+import java.net.InetSocketAddress;
+import java.net.MalformedURLException;
+import java.net.ProtocolException;
+import java.net.Proxy;
+import java.net.SocketPermission;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.security.Permission;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import com.android.okhttp.okio.BufferedSink;
+import com.android.okhttp.okio.Sink;
+
+/**
+ * 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 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.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class HttpURLConnectionImpl extends HttpURLConnection {
+  private static final Set<String> METHODS = new LinkedHashSet<>(
+      Arrays.asList("OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "PATCH"));
+  private static final RequestBody EMPTY_REQUEST_BODY = RequestBody.create(null, new byte[0]);
+
+  final OkHttpClient client;
+
+  private Headers.Builder requestHeaders = new Headers.Builder();
+
+  /** Like the superclass field of the same name, but a long and available on all platforms. */
+  private long fixedContentLength = -1;
+  private int followUpCount;
+  protected IOException httpEngineFailure;
+  protected HttpEngine httpEngine;
+  /** Lazily created (with synthetic headers) on first call to getHeaders(). */
+  private Headers responseHeaders;
+
+  /**
+   * The most recently attempted route. This will be null if we haven't sent a
+   * request yet, or if the response comes from a cache.
+   */
+  private Route route;
+
+  /**
+   * The most recently received TLS handshake. This will be null if we haven't
+   * connected yet, or if the most recent connection was HTTP (and not HTTPS).
+   */
+  Handshake handshake;
+
+  private URLFilter urlFilter;
+
+  public HttpURLConnectionImpl(URL url, OkHttpClient client) {
+    super(url);
+    this.client = client;
+  }
+
+  public HttpURLConnectionImpl(URL url, OkHttpClient client, URLFilter urlFilter) {
+    this(url, client);
+    this.urlFilter = urlFilter;
+  }
+
+  @Override public final void connect() throws IOException {
+    initHttpEngine();
+    boolean success;
+    do {
+      success = execute(false);
+    } while (!success);
+  }
+
+  @Override public final void disconnect() {
+    // Calling disconnect() before a connection exists should have no effect.
+    if (httpEngine == null) return;
+
+    httpEngine.cancel();
+
+    // This doesn't close the stream because doing so would require all stream
+    // access to be synchronized. It's expected that the thread using the
+    // connection will close its streams directly. If it doesn't, the worst
+    // case is that the GzipSource's Inflater won't be released until it's
+    // finalized. (This logs a warning on Android.)
+  }
+
+  /**
+   * 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 (HttpEngine.hasBody(response.getResponse())
+          && response.getResponse().code() >= HTTP_BAD_REQUEST) {
+        return response.getResponse().body().byteStream();
+      }
+      return null;
+    } catch (IOException e) {
+      return null;
+    }
+  }
+
+  private Headers getHeaders() throws IOException {
+    if (responseHeaders == null) {
+      Response response = getResponse().getResponse();
+      Headers headers = response.headers();
+      responseHeaders = headers.newBuilder()
+          .add(OkHeaders.SELECTED_PROTOCOL, response.protocol().toString())
+          .add(OkHeaders.RESPONSE_SOURCE, responseSourceHeader(response))
+          .build();
+    }
+    return responseHeaders;
+  }
+
+  private static String responseSourceHeader(Response response) {
+    if (response.networkResponse() == null) {
+      if (response.cacheResponse() == null) {
+        return "NONE";
+      }
+      return "CACHE " + response.code();
+    }
+    if (response.cacheResponse() == null) {
+      return "NETWORK " + response.code();
+    }
+    return "CONDITIONAL_CACHE " + response.networkResponse().code();
+  }
+
+  /**
+   * 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 getHeaders().value(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 {
+      return fieldName == null
+          ? StatusLine.get(getResponse().getResponse()).toString()
+          : getHeaders().get(fieldName);
+    } catch (IOException e) {
+      return null;
+    }
+  }
+
+  @Override public final String getHeaderFieldKey(int position) {
+    try {
+      return getHeaders().name(position);
+    } catch (IOException e) {
+      return null;
+    }
+  }
+
+  @Override public final Map<String, List<String>> getHeaderFields() {
+    try {
+      return OkHeaders.toMultimap(getHeaders(),
+          StatusLine.get(getResponse().getResponse()).toString());
+    } catch (IOException e) {
+      return Collections.emptyMap();
+    }
+  }
+
+  @Override public final Map<String, List<String>> getRequestProperties() {
+    if (connected) {
+      throw new IllegalStateException(
+          "Cannot access request header fields after connection is set");
+    }
+
+    return OkHeaders.toMultimap(requestHeaders.build(), null);
+  }
+
+  @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());
+    }
+
+    return response.getResponse().body().byteStream();
+  }
+
+  @Override public final OutputStream getOutputStream() throws IOException {
+    connect();
+
+    BufferedSink sink = httpEngine.getBufferedRequestBody();
+    if (sink == 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 sink.outputStream();
+  }
+
+  @Override public final Permission getPermission() throws IOException {
+    URL url = getURL();
+    String hostName = url.getHost();
+    int hostPort = url.getPort() != -1
+        ? url.getPort()
+        : HttpUrl.defaultPort(url.getProtocol());
+    if (usingProxy()) {
+      InetSocketAddress proxyAddress = (InetSocketAddress) client.getProxy().address();
+      hostName = proxyAddress.getHostName();
+      hostPort = proxyAddress.getPort();
+    }
+    return new SocketPermission(hostName + ":" + hostPort, "connect, resolve");
+  }
+
+  @Override public final String getRequestProperty(String field) {
+    if (field == null) return null;
+    return requestHeaders.get(field);
+  }
+
+  @Override public void setConnectTimeout(int timeoutMillis) {
+    client.setConnectTimeout(timeoutMillis, TimeUnit.MILLISECONDS);
+  }
+
+  @Override
+  public void setInstanceFollowRedirects(boolean followRedirects) {
+    client.setFollowRedirects(followRedirects);
+  }
+
+  @Override public boolean getInstanceFollowRedirects() {
+    return client.getFollowRedirects();
+  }
+
+  @Override public int getConnectTimeout() {
+    return client.getConnectTimeout();
+  }
+
+  @Override public void setReadTimeout(int timeoutMillis) {
+    client.setReadTimeout(timeoutMillis, TimeUnit.MILLISECONDS);
+  }
+
+  @Override public int getReadTimeout() {
+    return client.getReadTimeout();
+  }
+
+  private void initHttpEngine() throws IOException {
+    if (httpEngineFailure != null) {
+      throw httpEngineFailure;
+    } else if (httpEngine != null) {
+      return;
+    }
+
+    connected = true;
+    try {
+      if (doOutput) {
+        if (method.equals("GET")) {
+          // they are requesting a stream to write to. This implies a POST method
+          method = "POST";
+        } else if (!HttpMethod.permitsRequestBody(method)) {
+          throw new ProtocolException(method + " does not support writing");
+        }
+      }
+      // If the user set content length to zero, we know there will not be a request body.
+      httpEngine = newHttpEngine(method, null, null, null);
+    } catch (IOException e) {
+      httpEngineFailure = e;
+      throw e;
+    }
+  }
+
+  private HttpEngine newHttpEngine(String method, StreamAllocation streamAllocation,
+      RetryableSink requestBody, Response priorResponse)
+      throws MalformedURLException, UnknownHostException {
+    // OkHttp's Call API requires a placeholder body; the real body will be streamed separately.
+    RequestBody placeholderBody = HttpMethod.requiresRequestBody(method)
+        ? EMPTY_REQUEST_BODY
+        : null;
+    URL url = getURL();
+    HttpUrl httpUrl = Internal.instance.getHttpUrlChecked(url.toString());
+    Request.Builder builder = new Request.Builder()
+        .url(httpUrl)
+        .method(method, placeholderBody);
+    Headers headers = requestHeaders.build();
+    for (int i = 0, size = headers.size(); i < size; i++) {
+      builder.addHeader(headers.name(i), headers.value(i));
+    }
+
+    boolean bufferRequestBody = false;
+    if (HttpMethod.permitsRequestBody(method)) {
+      // Specify how the request body is terminated.
+      if (fixedContentLength != -1) {
+        builder.header("Content-Length", Long.toString(fixedContentLength));
+      } else if (chunkLength > 0) {
+        builder.header("Transfer-Encoding", "chunked");
+      } else {
+        bufferRequestBody = true;
+      }
+
+      // Add a content type for the request body, if one isn't already present.
+      if (headers.get("Content-Type") == null) {
+        builder.header("Content-Type", "application/x-www-form-urlencoded");
+      }
+    }
+
+    if (headers.get("User-Agent") == null) {
+      builder.header("User-Agent", defaultUserAgent());
+    }
+
+    Request request = builder.build();
+
+    // If we're currently not using caches, make sure the engine's client doesn't have one.
+    OkHttpClient engineClient = client;
+    if (Internal.instance.internalCache(engineClient) != null && !getUseCaches()) {
+      engineClient = client.clone().setCache(null);
+    }
+
+    return new HttpEngine(engineClient, request, bufferRequestBody, true, false, streamAllocation,
+        requestBody, priorResponse);
+  }
+
+  private String defaultUserAgent() {
+    String agent = System.getProperty("http.agent");
+    return agent != null ? Util.toHumanReadableAscii(agent) : Version.userAgent();
+  }
+
+  /**
+   * 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) {
+      if (!execute(true)) {
+        continue;
+      }
+
+      Response response = httpEngine.getResponse();
+      Request followUp = httpEngine.followUpRequest();
+
+      if (followUp == null) {
+        httpEngine.releaseStreamAllocation();
+        return httpEngine;
+      }
+
+      if (++followUpCount > HttpEngine.MAX_FOLLOW_UPS) {
+        throw new ProtocolException("Too many follow-up requests: " + followUpCount);
+      }
+
+      // The first request was insufficient. Prepare for another...
+      url = followUp.url();
+      requestHeaders = followUp.headers().newBuilder();
+
+      // 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.
+      Sink requestBody = httpEngine.getRequestBody();
+      if (!followUp.method().equals(method)) {
+        requestBody = null;
+      }
+
+      if (requestBody != null && !(requestBody instanceof RetryableSink)) {
+        throw new HttpRetryException("Cannot retry streamed HTTP body", responseCode);
+      }
+
+      StreamAllocation streamAllocation = httpEngine.close();
+      if (!httpEngine.sameConnection(followUp.httpUrl())) {
+        streamAllocation.release();
+        streamAllocation = null;
+      }
+
+      httpEngine = newHttpEngine(followUp.method(), streamAllocation, (RetryableSink) requestBody,
+          response);
+    }
+  }
+
+  /**
+   * Sends a request and optionally reads a response. Returns true if the
+   * request was successfully executed, and false if the request can be
+   * retried. Throws an exception if the request failed permanently.
+   */
+  private boolean execute(boolean readResponse) throws IOException {
+    boolean releaseConnection = true;
+    if (urlFilter != null) {
+      urlFilter.checkURLPermitted(httpEngine.getRequest().url());
+    }
+    try {
+      httpEngine.sendRequest();
+      Connection connection = httpEngine.getConnection();
+      if (connection != null) {
+        route = connection.getRoute();
+        handshake = connection.getHandshake();
+      } else {
+        route = null;
+        handshake = null;
+      }
+      if (readResponse) {
+        httpEngine.readResponse();
+      }
+      releaseConnection = false;
+
+      return true;
+    } catch (RequestException e) {
+      // An attempt to interpret a request failed.
+      IOException toThrow = e.getCause();
+      httpEngineFailure = toThrow;
+      throw toThrow;
+    } catch (RouteException e) {
+      // The attempt to connect via a route failed. The request will not have been sent.
+      HttpEngine retryEngine = httpEngine.recover(e);
+      if (retryEngine != null) {
+        releaseConnection = false;
+        httpEngine = retryEngine;
+        return false;
+      }
+
+      // Give up; recovery is not possible.
+      IOException toThrow = e.getLastConnectException();
+      httpEngineFailure = toThrow;
+      throw toThrow;
+    } catch (IOException e) {
+      // An attempt to communicate with a server failed. The request may have been sent.
+      HttpEngine retryEngine = httpEngine.recover(e);
+      if (retryEngine != null) {
+        releaseConnection = false;
+        httpEngine = retryEngine;
+        return false;
+      }
+
+      // Give up; recovery is not possible.
+      httpEngineFailure = e;
+      throw e;
+    } finally {
+      // We're throwing an unchecked exception. Release any resources.
+      if (releaseConnection) {
+        StreamAllocation streamAllocation = httpEngine.close();
+        streamAllocation.release();
+      }
+    }
+  }
+
+  /**
+   * Returns true if either:
+   * <ul>
+   *   <li>A specific proxy was explicitly configured for this connection.
+   *   <li>The response has already been retrieved, and a proxy was {@link
+   *       java.net.ProxySelector selected} in order to get it.
+   * </ul>
+   *
+   * <p><strong>Warning:</strong> This method may return false before attempting
+   * to connect and true afterwards.
+   */
+  @Override public final boolean usingProxy() {
+    Proxy proxy = route != null
+        ? route.getProxy()
+        : client.getProxy();
+    return proxy != null && proxy.type() != Proxy.Type.DIRECT;
+  }
+
+  @Override public String getResponseMessage() throws IOException {
+    return getResponse().getResponse().message();
+  }
+
+  @Override public final int getResponseCode() throws IOException {
+    return getResponse().getResponse().code();
+  }
+
+  @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");
+    }
+    if (newValue == null) {
+      // Silently ignore null header values for backwards compatibility with older
+      // android versions as well as with other URLConnection implementations.
+      //
+      // Some implementations send a malformed HTTP header when faced with
+      // such requests, we respect the spec and ignore the header.
+      Platform.get().logW("Ignoring header " + field + " because its value was null.");
+      return;
+    }
+
+    // TODO: Deprecate use of X-Android-Transports header?
+    if ("X-Android-Transports".equals(field) || "X-Android-Protocols".equals(field)) {
+      setProtocols(newValue, false /* append */);
+    } else {
+      requestHeaders.set(field, newValue);
+    }
+  }
+
+  @Override public void setIfModifiedSince(long newValue) {
+    super.setIfModifiedSince(newValue);
+    if (ifModifiedSince != 0) {
+      requestHeaders.set("If-Modified-Since", HttpDate.format(new Date(ifModifiedSince)));
+    } else {
+      requestHeaders.removeAll("If-Modified-Since");
+    }
+  }
+
+  @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");
+    }
+    if (value == null) {
+      // Silently ignore null header values for backwards compatibility with older
+      // android versions as well as with other URLConnection implementations.
+      //
+      // Some implementations send a malformed HTTP header when faced with
+      // such requests, we respect the spec and ignore the header.
+      Platform.get().logW("Ignoring header " + field + " because its value was null.");
+      return;
+    }
+
+    // TODO: Deprecate use of X-Android-Transports header?
+    if ("X-Android-Transports".equals(field) || "X-Android-Protocols".equals(field)) {
+      setProtocols(value, true /* append */);
+    } else {
+      requestHeaders.add(field, value);
+    }
+  }
+
+  /*
+   * Splits and validates a comma-separated string of protocols.
+   * When append == false, we require that the transport list contains "http/1.1".
+   * Throws {@link IllegalStateException} when one of the protocols isn't
+   * defined in {@link Protocol OkHttp's protocol enumeration}.
+   */
+  private void setProtocols(String protocolsString, boolean append) {
+    List<Protocol> protocolsList = new ArrayList<>();
+    if (append) {
+      protocolsList.addAll(client.getProtocols());
+    }
+    for (String protocol : protocolsString.split(",", -1)) {
+      try {
+        protocolsList.add(Protocol.get(protocol));
+      } catch (IOException e) {
+        throw new IllegalStateException(e);
+      }
+    }
+    client.setProtocols(protocolsList);
+  }
+
+  @Override public void setRequestMethod(String method) throws ProtocolException {
+    if (!METHODS.contains(method)) {
+      throw new ProtocolException("Expected one of " + METHODS + " but was " + method);
+    }
+    this.method = method;
+  }
+
+  @Override public void setFixedLengthStreamingMode(int contentLength) {
+    setFixedLengthStreamingMode((long) contentLength);
+  }
+
+  @Override public void setFixedLengthStreamingMode(long 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;
+    super.fixedContentLength = (int) Math.min(contentLength, Integer.MAX_VALUE);
+  }
+}
diff --git a/repackaged/okhttp-urlconnection/src/main/java/com/android/okhttp/internal/huc/HttpsURLConnectionImpl.java b/repackaged/okhttp-urlconnection/src/main/java/com/android/okhttp/internal/huc/HttpsURLConnectionImpl.java
new file mode 100644
index 0000000..5d7e738
--- /dev/null
+++ b/repackaged/okhttp-urlconnection/src/main/java/com/android/okhttp/internal/huc/HttpsURLConnectionImpl.java
@@ -0,0 +1,95 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  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.android.okhttp.internal.huc;
+
+import com.android.okhttp.Handshake;
+import com.android.okhttp.OkHttpClient;
+import com.android.okhttp.internal.URLFilter;
+import java.net.URL;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSocketFactory;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class HttpsURLConnectionImpl extends DelegatingHttpsURLConnection {
+  private final HttpURLConnectionImpl delegate;
+
+  public HttpsURLConnectionImpl(URL url, OkHttpClient client) {
+    this(new HttpURLConnectionImpl(url, client));
+  }
+
+  public HttpsURLConnectionImpl(URL url, OkHttpClient client, URLFilter filter) {
+    this(new HttpURLConnectionImpl(url, client, filter));
+  }
+
+  public HttpsURLConnectionImpl(HttpURLConnectionImpl delegate) {
+    super(delegate);
+    this.delegate = delegate;
+  }
+
+  @Override protected Handshake handshake() {
+    if (delegate.httpEngine == null) {
+      throw new IllegalStateException("Connection has not yet been established");
+    }
+
+    // If there's a response, get the handshake from there so that caching
+    // works. Otherwise get the handshake from the connection because we might
+    // have not connected yet.
+    return delegate.httpEngine.hasResponse()
+        ? delegate.httpEngine.getResponse().handshake()
+        : delegate.handshake;
+  }
+
+  @Override public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
+    delegate.client.setHostnameVerifier(hostnameVerifier);
+  }
+
+  @Override public HostnameVerifier getHostnameVerifier() {
+    return delegate.client.getHostnameVerifier();
+  }
+
+  @Override public void setSSLSocketFactory(SSLSocketFactory sslSocketFactory) {
+    // BEGIN Android-added: Integrate upstream change: Let setSSLSocketFactory(null) throw.
+    // https://github.com/square/okhttp/commit/f704f9d30e941ebdbdc95843c931cfc9d34bcba6
+    // This method is documented to throw if sslSocketFactory == null. Setting the client's
+    // sslSocketFactory to null instead would cause it to fall back to the default factory.
+    // http://b/73702052
+    if (sslSocketFactory == null) {
+      throw new IllegalArgumentException("sslSocketFactory == null");
+    }
+    // END Android-added: Integrate upstream change: Let setSSLSocketFactory(null) throw.
+    delegate.client.setSslSocketFactory(sslSocketFactory);
+  }
+
+  @Override public SSLSocketFactory getSSLSocketFactory() {
+    return delegate.client.getSslSocketFactory();
+  }
+
+  @Override public long getContentLengthLong() {
+    return delegate.getContentLengthLong();
+  }
+
+  @Override public void setFixedLengthStreamingMode(long contentLength) {
+    delegate.setFixedLengthStreamingMode(contentLength);
+  }
+
+  @Override public long getHeaderFieldLong(String field, long defaultValue) {
+    return delegate.getHeaderFieldLong(field, defaultValue);
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/Address.java b/repackaged/okhttp/src/main/java/com/android/okhttp/Address.java
new file mode 100644
index 0000000..5331969
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/Address.java
@@ -0,0 +1,205 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.okhttp;
+
+import com.android.okhttp.internal.Util;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.util.List;
+import javax.net.SocketFactory;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSocketFactory;
+
+import static com.android.okhttp.internal.Util.equal;
+
+/**
+ * A specification for a connection to an origin server. For simple connections,
+ * this is the server's hostname and port. If an explicit proxy is requested (or
+ * {@linkplain Proxy#NO_PROXY no proxy} is explicitly requested), this also includes
+ * that proxy information. For secure connections the address also includes the
+ * SSL socket factory, hostname verifier, and certificate pinner.
+ *
+ * <p>HTTP requests that share the same {@code Address} may also share the same
+ * {@link Connection}.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Address {
+  final HttpUrl url;
+  final Dns dns;
+  final SocketFactory socketFactory;
+  final Authenticator authenticator;
+  final List<Protocol> protocols;
+  final List<ConnectionSpec> connectionSpecs;
+  final ProxySelector proxySelector;
+  final Proxy proxy;
+  final SSLSocketFactory sslSocketFactory;
+  final HostnameVerifier hostnameVerifier;
+  final CertificatePinner certificatePinner;
+
+  public Address(String uriHost, int uriPort, Dns dns, SocketFactory socketFactory,
+      SSLSocketFactory sslSocketFactory, HostnameVerifier hostnameVerifier,
+      CertificatePinner certificatePinner, Authenticator authenticator, Proxy proxy,
+      List<Protocol> protocols, List<ConnectionSpec> connectionSpecs, ProxySelector proxySelector) {
+    this.url = new HttpUrl.Builder()
+        .scheme(sslSocketFactory != null ? "https" : "http")
+        .host(uriHost)
+        .port(uriPort)
+        .build();
+
+    if (dns == null) throw new IllegalArgumentException("dns == null");
+    this.dns = dns;
+
+    if (socketFactory == null) throw new IllegalArgumentException("socketFactory == null");
+    this.socketFactory = socketFactory;
+
+    if (authenticator == null) throw new IllegalArgumentException("authenticator == null");
+    this.authenticator = authenticator;
+
+    if (protocols == null) throw new IllegalArgumentException("protocols == null");
+    this.protocols = Util.immutableList(protocols);
+
+    if (connectionSpecs == null) throw new IllegalArgumentException("connectionSpecs == null");
+    this.connectionSpecs = Util.immutableList(connectionSpecs);
+
+    if (proxySelector == null) throw new IllegalArgumentException("proxySelector == null");
+    this.proxySelector = proxySelector;
+
+    this.proxy = proxy;
+    this.sslSocketFactory = sslSocketFactory;
+    this.hostnameVerifier = hostnameVerifier;
+    this.certificatePinner = certificatePinner;
+  }
+
+  /**
+   * Returns a URL with the hostname and port of the origin server. The path, query, and fragment of
+   * this URL are always empty, since they are not significant for planning a route.
+   */
+  public HttpUrl url() {
+    return url;
+  }
+
+  /**
+   * Returns the hostname of the origin server.
+   *
+   * @deprecated prefer {@code address.url().host()}.
+   */
+  @Deprecated
+  public String getUriHost() {
+    return url.host();
+  }
+
+  /**
+   * Returns the port of the origin server; typically 80 or 443. Unlike
+   * may {@code getPort()} accessors, this method never returns -1.
+   *
+   * @deprecated prefer {@code address.url().port()}.
+   */
+  @Deprecated
+  public int getUriPort() {
+    return url.port();
+  }
+
+  /** Returns the service that will be used to resolve IP addresses for hostnames. */
+  public Dns getDns() {
+    return dns;
+  }
+
+  /** Returns the socket factory for new connections. */
+  public SocketFactory getSocketFactory() {
+    return socketFactory;
+  }
+
+  /** Returns the client's authenticator. */
+  public Authenticator getAuthenticator() {
+    return authenticator;
+  }
+
+  /**
+   * Returns the protocols the client supports. This method always returns a
+   * non-null list that contains minimally {@link Protocol#HTTP_1_1}.
+   */
+  public List<Protocol> getProtocols() {
+    return protocols;
+  }
+
+  public List<ConnectionSpec> getConnectionSpecs() {
+    return connectionSpecs;
+  }
+
+  /**
+   * Returns this address's proxy selector. Only used if the proxy is null. If none of this
+   * selector's proxies are reachable, a direct connection will be attempted.
+   */
+  public ProxySelector getProxySelector() {
+    return proxySelector;
+  }
+
+  /**
+   * Returns this address's explicitly-specified HTTP proxy, or null to
+   * delegate to the {@linkplain #getProxySelector proxy selector}.
+   */
+  public Proxy getProxy() {
+    return proxy;
+  }
+
+  /** Returns the SSL socket factory, or null if this is not an HTTPS address. */
+  public SSLSocketFactory getSslSocketFactory() {
+    return sslSocketFactory;
+  }
+
+  /** Returns the hostname verifier, or null if this is not an HTTPS address. */
+  public HostnameVerifier getHostnameVerifier() {
+    return hostnameVerifier;
+  }
+
+  /** Returns this address's certificate pinner, or null if this is not an HTTPS address. */
+  public CertificatePinner getCertificatePinner() {
+    return certificatePinner;
+  }
+
+  @Override public boolean equals(Object other) {
+    if (other instanceof Address) {
+      Address that = (Address) other;
+      return this.url.equals(that.url)
+          && this.dns.equals(that.dns)
+          && this.authenticator.equals(that.authenticator)
+          && this.protocols.equals(that.protocols)
+          && this.connectionSpecs.equals(that.connectionSpecs)
+          && this.proxySelector.equals(that.proxySelector)
+          && equal(this.proxy, that.proxy)
+          && equal(this.sslSocketFactory, that.sslSocketFactory)
+          && equal(this.hostnameVerifier, that.hostnameVerifier)
+          && equal(this.certificatePinner, that.certificatePinner);
+    }
+    return false;
+  }
+
+  @Override public int hashCode() {
+    int result = 17;
+    result = 31 * result + url.hashCode();
+    result = 31 * result + dns.hashCode();
+    result = 31 * result + authenticator.hashCode();
+    result = 31 * result + protocols.hashCode();
+    result = 31 * result + connectionSpecs.hashCode();
+    result = 31 * result + proxySelector.hashCode();
+    result = 31 * result + (proxy != null ? proxy.hashCode() : 0);
+    result = 31 * result + (sslSocketFactory != null ? sslSocketFactory.hashCode() : 0);
+    result = 31 * result + (hostnameVerifier != null ? hostnameVerifier.hashCode() : 0);
+    result = 31 * result + (certificatePinner != null ? certificatePinner.hashCode() : 0);
+    return result;
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/Authenticator.java b/repackaged/okhttp/src/main/java/com/android/okhttp/Authenticator.java
new file mode 100644
index 0000000..ae23d30
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/Authenticator.java
@@ -0,0 +1,62 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.okhttp;
+
+import java.io.IOException;
+import java.net.Proxy;
+
+/**
+ * Responds to authentication challenges from the remote web or proxy server.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface Authenticator {
+  /**
+   * Returns a request that includes a credential to satisfy an authentication
+   * challenge in {@code response}. Returns null if the challenge cannot be
+   * satisfied. This method is called in response to an HTTP 401 unauthorized
+   * status code sent by the origin server.
+   *
+   * <p>Typical implementations will look up a credential and create a request
+   * derived from the initial request by setting the "Authorization" header.
+   * <pre>   {@code
+   *
+   *    String credential = Credentials.basic(...)
+   *    return response.request().newBuilder()
+   *        .header("Authorization", credential)
+   *        .build();
+   * }</pre>
+   */
+  Request authenticate(Proxy proxy, Response response) throws IOException;
+
+  /**
+   * Returns a request that includes a credential to satisfy an authentication
+   * challenge made by {@code response}. Returns null if the challenge cannot be
+   * satisfied. This method is called in response to an HTTP 407 unauthorized
+   * status code sent by the proxy server.
+   *
+   * <p>Typical implementations will look up a credential and create a request
+   * derived from the initial request by setting the "Proxy-Authorization"
+   * header. <pre>   {@code
+   *
+   *    String credential = Credentials.basic(...)
+   *    return response.request().newBuilder()
+   *        .header("Proxy-Authorization", credential)
+   *        .build();
+   * }</pre>
+   */
+  Request authenticateProxy(Proxy proxy, Response response) throws IOException;
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/Cache.java b/repackaged/okhttp/src/main/java/com/android/okhttp/Cache.java
new file mode 100644
index 0000000..1e8f583
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/Cache.java
@@ -0,0 +1,732 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.okhttp;
+
+import com.android.okhttp.internal.DiskLruCache;
+import com.android.okhttp.internal.InternalCache;
+import com.android.okhttp.internal.Util;
+import com.android.okhttp.internal.http.CacheRequest;
+import com.android.okhttp.internal.http.CacheStrategy;
+import com.android.okhttp.internal.http.HttpMethod;
+import com.android.okhttp.internal.http.OkHeaders;
+import com.android.okhttp.internal.http.StatusLine;
+import com.android.okhttp.internal.io.FileSystem;
+import java.io.File;
+import java.io.IOException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import com.android.okhttp.okio.Buffer;
+import com.android.okhttp.okio.BufferedSink;
+import com.android.okhttp.okio.BufferedSource;
+import com.android.okhttp.okio.ByteString;
+import com.android.okhttp.okio.ForwardingSink;
+import com.android.okhttp.okio.ForwardingSource;
+import com.android.okhttp.okio.Okio;
+import com.android.okhttp.okio.Sink;
+import com.android.okhttp.okio.Source;
+
+/**
+ * Caches HTTP and HTTPS responses to the filesystem so they may be reused, saving time and
+ * bandwidth.
+ *
+ * <h3>Cache Optimization</h3>
+ * To measure cache effectiveness, this class tracks three statistics:
+ * <ul>
+ *   <li><strong>{@linkplain #getRequestCount() Request Count:}</strong> the number of HTTP
+ *     requests issued since this cache was created.
+ *   <li><strong>{@linkplain #getNetworkCount() Network Count:}</strong> the number of those
+ *     requests that required network use.
+ *   <li><strong>{@linkplain #getHitCount() Hit Count:}</strong> the number of those requests whose
+ *     responses were served by the cache.
+ * </ul>
+ *
+ * Sometimes a request will result in a conditional cache hit. If the cache contains a stale copy of
+ * the response, the client will issue a conditional {@code GET}. The server will then send either
+ * the updated response if it has changed, or a short 'not modified' response if the client's copy
+ * is still valid. Such responses increment both the network count and hit count.
+ *
+ * <p>The best way to improve the cache hit rate is by configuring the web server to return
+ * cacheable responses. Although this client honors all <a
+ * href="http://tools.ietf.org/html/rfc7234">HTTP/1.1 (RFC 7234)</a> cache headers, it doesn't cache
+ * partial responses.
+ *
+ * <h3>Force a Network Response</h3>
+ * In some situations, such as after a user clicks a 'refresh' button, it may be necessary to skip
+ * the cache, and fetch data directly from the server. To force a full refresh, add the {@code
+ * no-cache} directive: <pre>   {@code
+ *
+ *   Request request = new Request.Builder()
+ *       .cacheControl(new CacheControl.Builder().noCache().build())
+ *       .url("http://publicobject.com/helloworld.txt")
+ *       .build();
+ * }</pre>
+ *
+ * If it is only necessary to force a cached response to be validated by the server, use the more
+ * efficient {@code max-age=0} directive instead: <pre>   {@code
+ *
+ *   Request request = new Request.Builder()
+ *       .cacheControl(new CacheControl.Builder()
+ *           .maxAge(0, TimeUnit.SECONDS)
+ *           .build())
+ *       .url("http://publicobject.com/helloworld.txt")
+ *       .build();
+ * }</pre>
+ *
+ * <h3>Force a Cache Response</h3>
+ * Sometimes you'll want to show resources if they are available immediately, but not otherwise.
+ * This can be used so your application can show <i>something</i> while waiting for the latest data
+ * to be downloaded. To restrict a request to locally-cached resources, add the {@code
+ * only-if-cached} directive: <pre>   {@code
+ *
+ *     Request request = new Request.Builder()
+ *         .cacheControl(new CacheControl.Builder()
+ *             .onlyIfCached()
+ *             .build())
+ *         .url("http://publicobject.com/helloworld.txt")
+ *         .build();
+ *     Response forceCacheResponse = client.newCall(request).execute();
+ *     if (forceCacheResponse.code() != 504) {
+ *       // The resource was cached! Show it.
+ *     } else {
+ *       // The resource was not cached.
+ *     }
+ * }</pre>
+ * This technique works even better in situations where a stale response is better than no response.
+ * To permit stale cached responses, use the {@code max-stale} directive with the maximum staleness
+ * in seconds: <pre>   {@code
+ *
+ *   Request request = new Request.Builder()
+ *       .cacheControl(new CacheControl.Builder()
+ *           .maxStale(365, TimeUnit.DAYS)
+ *           .build())
+ *       .url("http://publicobject.com/helloworld.txt")
+ *       .build();
+ * }</pre>
+ *
+ * <p>The {@link CacheControl} class can configure request caching directives and parse response
+ * caching directives. It even offers convenient constants {@link CacheControl#FORCE_NETWORK} and
+ * {@link CacheControl#FORCE_CACHE} that address the use cases above.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class 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;
+
+  // Android-changed: internalCache made public so it can be used from Android internalapi package.
+  public final InternalCache internalCache = new InternalCache() {
+    @Override public Response get(Request request) throws IOException {
+      return Cache.this.get(request);
+    }
+    @Override public CacheRequest put(Response response) throws IOException {
+      return Cache.this.put(response);
+    }
+    @Override public void remove(Request request) throws IOException {
+      Cache.this.remove(request);
+    }
+    @Override public void update(Response cached, Response network) throws IOException {
+      Cache.this.update(cached, network);
+    }
+    @Override public void trackConditionalCacheHit() {
+      Cache.this.trackConditionalCacheHit();
+    }
+    @Override public void trackResponse(CacheStrategy cacheStrategy) {
+      Cache.this.trackResponse(cacheStrategy);
+    }
+  };
+
+  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 Cache(File directory, long maxSize) {
+    this(directory, maxSize, FileSystem.SYSTEM);
+  }
+
+  Cache(File directory, long maxSize, FileSystem fileSystem) {
+    this.cache = DiskLruCache.create(fileSystem, directory, VERSION, ENTRY_COUNT, maxSize);
+  }
+
+  private static String urlToKey(Request request) {
+    return Util.md5Hex(request.urlString());
+  }
+
+  Response get(Request request) {
+    String key = urlToKey(request);
+    DiskLruCache.Snapshot snapshot;
+    Entry entry;
+    try {
+      snapshot = cache.get(key);
+      if (snapshot == null) {
+        return null;
+      }
+    } catch (IOException e) {
+      // Give up because the cache cannot be read.
+      return null;
+    }
+
+    try {
+      entry = new Entry(snapshot.getSource(ENTRY_METADATA));
+    } catch (IOException e) {
+      Util.closeQuietly(snapshot);
+      return null;
+    }
+
+    Response response = entry.response(request, snapshot);
+
+    if (!entry.matches(request, response)) {
+      Util.closeQuietly(response.body());
+      return null;
+    }
+
+    return response;
+  }
+
+  private CacheRequest put(Response response) throws IOException {
+    String requestMethod = response.request().method();
+
+    if (HttpMethod.invalidatesCache(response.request().method())) {
+      try {
+        remove(response.request());
+      } catch (IOException ignored) {
+        // The cache cannot be written.
+      }
+      return null;
+    }
+    if (!requestMethod.equals("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;
+    }
+
+    if (OkHeaders.hasVaryAll(response)) {
+      return null;
+    }
+
+    Entry entry = new Entry(response);
+    DiskLruCache.Editor editor = null;
+    try {
+      editor = cache.edit(urlToKey(response.request()));
+      if (editor == null) {
+        return null;
+      }
+      entry.writeTo(editor);
+      return new CacheRequestImpl(editor);
+    } catch (IOException e) {
+      abortQuietly(editor);
+      return null;
+    }
+  }
+
+  private void remove(Request request) throws IOException {
+    cache.remove(urlToKey(request));
+  }
+
+  private void update(Response cached, Response network) {
+    Entry entry = new Entry(network);
+    DiskLruCache.Snapshot snapshot = ((CacheResponseBody) cached.body()).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) {
+    }
+  }
+
+  /**
+   * Initialize the cache. This will include reading the journal files from
+   * the storage and building up the necessary in-memory cache information.
+   * <p>
+   * The initialization time may vary depending on the journal file size and
+   * the current actual cache size. The application needs to be aware of calling
+   * this function during the initialization phase and preferably in a background
+   * worker thread.
+   * <p>
+   * Note that if the application chooses to not call this method to initialize
+   * the cache. By default, the okhttp will perform lazy initialization upon the
+   * first usage of the cache.
+   */
+  public void initialize() throws IOException {
+    cache.initialize();
+  }
+
+  /**
+   * 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 {
+    cache.delete();
+  }
+
+  /**
+   * Deletes all values stored in the cache. In-flight writes to the cache will
+   * complete normally, but the corresponding responses will not be stored.
+   */
+  public void evictAll() throws IOException {
+    cache.evictAll();
+  }
+
+  /**
+   * Returns an iterator over the URLs in this cache. This iterator doesn't throw {@code
+   * ConcurrentModificationException}, but if new responses are added while iterating, their URLs
+   * will not be returned. If existing responses are evicted during iteration, they will be absent
+   * (unless they were already returned).
+   *
+   * <p>The iterator supports {@linkplain Iterator#remove}. Removing a URL from the iterator evicts
+   * the corresponding response from the cache. Use this to evict selected responses.
+   */
+  public Iterator<String> urls() throws IOException {
+    return new Iterator<String>() {
+      final Iterator<DiskLruCache.Snapshot> delegate = cache.snapshots();
+
+      String nextUrl;
+      boolean canRemove;
+
+      @Override public boolean hasNext() {
+        if (nextUrl != null) return true;
+
+        canRemove = false; // Prevent delegate.remove() on the wrong item!
+        while (delegate.hasNext()) {
+          DiskLruCache.Snapshot snapshot = delegate.next();
+          try {
+            BufferedSource metadata = Okio.buffer(snapshot.getSource(ENTRY_METADATA));
+            nextUrl = metadata.readUtf8LineStrict();
+            return true;
+          } catch (IOException ignored) {
+            // We couldn't read the metadata for this snapshot; possibly because the host filesystem
+            // has disappeared! Skip it.
+          } finally {
+            snapshot.close();
+          }
+        }
+
+        return false;
+      }
+
+      @Override public String next() {
+        if (!hasNext()) throw new NoSuchElementException();
+        String result = nextUrl;
+        nextUrl = null;
+        canRemove = true;
+        return result;
+      }
+
+      @Override public void remove() {
+        if (!canRemove) throw new IllegalStateException("remove() before next()");
+        delegate.remove();
+      }
+    };
+  }
+
+  public synchronized int getWriteAbortCount() {
+    return writeAbortCount;
+  }
+
+  public synchronized int getWriteSuccessCount() {
+    return writeSuccessCount;
+  }
+
+  public long getSize() throws IOException {
+    return cache.size();
+  }
+
+  public long getMaxSize() {
+    return cache.getMaxSize();
+  }
+
+  public void flush() throws IOException {
+    cache.flush();
+  }
+
+  public void close() throws IOException {
+    cache.close();
+  }
+
+  public File getDirectory() {
+    return cache.getDirectory();
+  }
+
+  public boolean isClosed() {
+    return cache.isClosed();
+  }
+
+  private synchronized void trackResponse(CacheStrategy cacheStrategy) {
+    requestCount++;
+
+    if (cacheStrategy.networkRequest != null) {
+      // If this is a conditional request, we'll increment hitCount if/when it hits.
+      networkCount++;
+
+    } else if (cacheStrategy.cacheResponse != null) {
+      // This response uses the cache and not the network. That's a cache hit.
+      hitCount++;
+    }
+  }
+
+  private 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 implements CacheRequest {
+    private final DiskLruCache.Editor editor;
+    private Sink cacheOut;
+    private boolean done;
+    private Sink body;
+
+    public CacheRequestImpl(final DiskLruCache.Editor editor) throws IOException {
+      this.editor = editor;
+      this.cacheOut = editor.newSink(ENTRY_BODY);
+      this.body = new ForwardingSink(cacheOut) {
+        @Override public void close() throws IOException {
+          synchronized (Cache.this) {
+            if (done) {
+              return;
+            }
+            done = true;
+            writeSuccessCount++;
+          }
+          super.close();
+          editor.commit();
+        }
+      };
+    }
+
+    @Override public void abort() {
+      synchronized (Cache.this) {
+        if (done) {
+          return;
+        }
+        done = true;
+        writeAbortCount++;
+      }
+      Util.closeQuietly(cacheOut);
+      try {
+        editor.abort();
+      } catch (IOException ignored) {
+      }
+    }
+
+    @Override public Sink body() {
+      return body;
+    }
+  }
+
+  private static final class Entry {
+    private final String url;
+    private final Headers varyHeaders;
+    private final String requestMethod;
+    private final Protocol protocol;
+    private final int code;
+    private final String message;
+    private final Headers responseHeaders;
+    private final Handshake handshake;
+
+    /**
+     * Reads an entry from an input stream. A typical entry looks like this:
+     * <pre>{@code
+     *   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
+     * }</pre>
+     *
+     * <p>A typical HTTPS file looks like this:
+     * <pre>{@code
+     *   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
+     * }</pre>
+     * 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.
+     *
+     * <p>Next is the response status line, followed by the number of HTTP
+     * response header lines, followed by those lines.
+     *
+     * <p>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(Source in) throws IOException {
+      try {
+        BufferedSource source = Okio.buffer(in);
+        url = source.readUtf8LineStrict();
+        requestMethod = source.readUtf8LineStrict();
+        Headers.Builder varyHeadersBuilder = new Headers.Builder();
+        int varyRequestHeaderLineCount = readInt(source);
+        for (int i = 0; i < varyRequestHeaderLineCount; i++) {
+          varyHeadersBuilder.addLenient(source.readUtf8LineStrict());
+        }
+        varyHeaders = varyHeadersBuilder.build();
+
+        StatusLine statusLine = StatusLine.parse(source.readUtf8LineStrict());
+        protocol = statusLine.protocol;
+        code = statusLine.code;
+        message = statusLine.message;
+        Headers.Builder responseHeadersBuilder = new Headers.Builder();
+        int responseHeaderLineCount = readInt(source);
+        for (int i = 0; i < responseHeaderLineCount; i++) {
+          responseHeadersBuilder.addLenient(source.readUtf8LineStrict());
+        }
+        responseHeaders = responseHeadersBuilder.build();
+
+        if (isHttps()) {
+          String blank = source.readUtf8LineStrict();
+          if (blank.length() > 0) {
+            throw new IOException("expected \"\" but was \"" + blank + "\"");
+          }
+          String cipherSuite = source.readUtf8LineStrict();
+          List<Certificate> peerCertificates = readCertificateList(source);
+          List<Certificate> localCertificates = readCertificateList(source);
+          handshake = Handshake.get(cipherSuite, peerCertificates, localCertificates);
+        } else {
+          handshake = null;
+        }
+      } finally {
+        in.close();
+      }
+    }
+
+    public Entry(Response response) {
+      this.url = response.request().urlString();
+      this.varyHeaders = OkHeaders.varyHeaders(response);
+      this.requestMethod = response.request().method();
+      this.protocol = response.protocol();
+      this.code = response.code();
+      this.message = response.message();
+      this.responseHeaders = response.headers();
+      this.handshake = response.handshake();
+    }
+
+    public void writeTo(DiskLruCache.Editor editor) throws IOException {
+      BufferedSink sink = Okio.buffer(editor.newSink(ENTRY_METADATA));
+
+      sink.writeUtf8(url);
+      sink.writeByte('\n');
+      sink.writeUtf8(requestMethod);
+      sink.writeByte('\n');
+      sink.writeDecimalLong(varyHeaders.size());
+      sink.writeByte('\n');
+      for (int i = 0, size = varyHeaders.size(); i < size; i++) {
+        sink.writeUtf8(varyHeaders.name(i));
+        sink.writeUtf8(": ");
+        sink.writeUtf8(varyHeaders.value(i));
+        sink.writeByte('\n');
+      }
+
+      sink.writeUtf8(new StatusLine(protocol, code, message).toString());
+      sink.writeByte('\n');
+      sink.writeDecimalLong(responseHeaders.size());
+      sink.writeByte('\n');
+      for (int i = 0, size = responseHeaders.size(); i < size; i++) {
+        sink.writeUtf8(responseHeaders.name(i));
+        sink.writeUtf8(": ");
+        sink.writeUtf8(responseHeaders.value(i));
+        sink.writeByte('\n');
+      }
+
+      if (isHttps()) {
+        sink.writeByte('\n');
+        sink.writeUtf8(handshake.cipherSuite());
+        sink.writeByte('\n');
+        writeCertList(sink, handshake.peerCertificates());
+        writeCertList(sink, handshake.localCertificates());
+      }
+      sink.close();
+    }
+
+    private boolean isHttps() {
+      return url.startsWith("https://");
+    }
+
+    private List<Certificate> readCertificateList(BufferedSource source) throws IOException {
+      int length = readInt(source);
+      if (length == -1) return Collections.emptyList(); // OkHttp v1.2 used -1 to indicate null.
+
+      try {
+        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
+        List<Certificate> result = new ArrayList<>(length);
+        for (int i = 0; i < length; i++) {
+          String line = source.readUtf8LineStrict();
+          Buffer bytes = new Buffer();
+          bytes.write(ByteString.decodeBase64(line));
+          result.add(certificateFactory.generateCertificate(bytes.inputStream()));
+        }
+        return result;
+      } catch (CertificateException e) {
+        throw new IOException(e.getMessage());
+      }
+    }
+
+    private void writeCertList(BufferedSink sink, List<Certificate> certificates)
+        throws IOException {
+      try {
+        sink.writeDecimalLong(certificates.size());
+        sink.writeByte('\n');
+        for (int i = 0, size = certificates.size(); i < size; i++) {
+          byte[] bytes = certificates.get(i).getEncoded();
+          String line = ByteString.of(bytes).base64();
+          sink.writeUtf8(line);
+          sink.writeByte('\n');
+        }
+      } catch (CertificateEncodingException e) {
+        throw new IOException(e.getMessage());
+      }
+    }
+
+    public boolean matches(Request request, Response response) {
+      return url.equals(request.urlString())
+          && requestMethod.equals(request.method())
+          && OkHeaders.varyMatches(response, varyHeaders, request);
+    }
+
+    public Response response(Request request, DiskLruCache.Snapshot snapshot) {
+      String contentType = responseHeaders.get("Content-Type");
+      String contentLength = responseHeaders.get("Content-Length");
+      Request cacheRequest = new Request.Builder()
+          .url(url)
+          .method(requestMethod, null)
+          .headers(varyHeaders)
+          .build();
+      return new Response.Builder()
+          .request(cacheRequest)
+          .protocol(protocol)
+          .code(code)
+          .message(message)
+          .headers(responseHeaders)
+          .body(new CacheResponseBody(snapshot, contentType, contentLength))
+          .handshake(handshake)
+          .build();
+    }
+  }
+
+  private static int readInt(BufferedSource source) throws IOException {
+    try {
+      long result = source.readDecimalLong();
+      String line = source.readUtf8LineStrict();
+      if (result < 0 || result > Integer.MAX_VALUE || !line.isEmpty()) {
+        throw new IOException("expected an int but was \"" + result + line + "\"");
+      }
+      return (int) result;
+    } catch (NumberFormatException e) {
+      throw new IOException(e.getMessage());
+    }
+  }
+
+  private static class CacheResponseBody extends ResponseBody {
+    private final DiskLruCache.Snapshot snapshot;
+    private final BufferedSource bodySource;
+    private final String contentType;
+    private final String contentLength;
+
+    public CacheResponseBody(final DiskLruCache.Snapshot snapshot,
+        String contentType, String contentLength) {
+      this.snapshot = snapshot;
+      this.contentType = contentType;
+      this.contentLength = contentLength;
+
+      Source source = snapshot.getSource(ENTRY_BODY);
+      bodySource = Okio.buffer(new ForwardingSource(source) {
+        @Override public void close() throws IOException {
+          snapshot.close();
+          super.close();
+        }
+      });
+    }
+
+    @Override public MediaType contentType() {
+      return contentType != null ? MediaType.parse(contentType) : null;
+    }
+
+    @Override public long contentLength() {
+      try {
+        return contentLength != null ? Long.parseLong(contentLength) : -1;
+      } catch (NumberFormatException e) {
+        return -1;
+      }
+    }
+
+    @Override public BufferedSource source() {
+      return bodySource;
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/CacheControl.java b/repackaged/okhttp/src/main/java/com/android/okhttp/CacheControl.java
new file mode 100644
index 0000000..27e2e4a
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/CacheControl.java
@@ -0,0 +1,369 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.okhttp;
+
+import com.android.okhttp.internal.http.HeaderParser;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A Cache-Control header with cache directives from a server or client. These
+ * directives set policy on what responses can be stored, and which requests can
+ * be satisfied by those stored responses.
+ *
+ * <p>See <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9">RFC
+ * 2616, 14.9</a>.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class CacheControl {
+  /**
+   * Cache control request directives that require network validation of
+   * responses. Note that such requests may be assisted by the cache via
+   * conditional GET requests.
+   */
+  public static final CacheControl FORCE_NETWORK = new Builder().noCache().build();
+
+  /**
+   * Cache control request directives that uses the cache only, even if the
+   * cached response is stale. If the response isn't available in the cache or
+   * requires server validation, the call will fail with a {@code 504
+   * Unsatisfiable Request}.
+   */
+  public static final CacheControl FORCE_CACHE = new Builder()
+      .onlyIfCached()
+      .maxStale(Integer.MAX_VALUE, TimeUnit.SECONDS)
+      .build();
+
+  private final boolean noCache;
+  private final boolean noStore;
+  private final int maxAgeSeconds;
+  private final int sMaxAgeSeconds;
+  private final boolean isPrivate;
+  private final boolean isPublic;
+  private final boolean mustRevalidate;
+  private final int maxStaleSeconds;
+  private final int minFreshSeconds;
+  private final boolean onlyIfCached;
+  private final boolean noTransform;
+
+  String headerValue; // Lazily computed, if absent.
+
+  private CacheControl(boolean noCache, boolean noStore, int maxAgeSeconds, int sMaxAgeSeconds,
+      boolean isPrivate, boolean isPublic, boolean mustRevalidate, int maxStaleSeconds,
+      int minFreshSeconds, boolean onlyIfCached, boolean noTransform, String headerValue) {
+    this.noCache = noCache;
+    this.noStore = noStore;
+    this.maxAgeSeconds = maxAgeSeconds;
+    this.sMaxAgeSeconds = sMaxAgeSeconds;
+    this.isPrivate = isPrivate;
+    this.isPublic = isPublic;
+    this.mustRevalidate = mustRevalidate;
+    this.maxStaleSeconds = maxStaleSeconds;
+    this.minFreshSeconds = minFreshSeconds;
+    this.onlyIfCached = onlyIfCached;
+    this.noTransform = noTransform;
+    this.headerValue = headerValue;
+  }
+
+  private CacheControl(Builder builder) {
+    this.noCache = builder.noCache;
+    this.noStore = builder.noStore;
+    this.maxAgeSeconds = builder.maxAgeSeconds;
+    this.sMaxAgeSeconds = -1;
+    this.isPrivate = false;
+    this.isPublic = false;
+    this.mustRevalidate = false;
+    this.maxStaleSeconds = builder.maxStaleSeconds;
+    this.minFreshSeconds = builder.minFreshSeconds;
+    this.onlyIfCached = builder.onlyIfCached;
+    this.noTransform = builder.noTransform;
+  }
+
+  /**
+   * In a 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.
+   *
+   * <p>In a request, it means do not use a cache to satisfy the request.
+   */
+  public boolean noCache() {
+    return noCache;
+  }
+
+  /** If true, this response should not be cached. */
+  public boolean noStore() {
+    return noStore;
+  }
+
+  /**
+   * The duration past the response's served date that it can be served without
+   * validation.
+   */
+  public int maxAgeSeconds() {
+    return maxAgeSeconds;
+  }
+
+  /**
+   * 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.
+   */
+  public int sMaxAgeSeconds() {
+    return sMaxAgeSeconds;
+  }
+
+  public boolean isPrivate() {
+    return isPrivate;
+  }
+
+  public boolean isPublic() {
+    return isPublic;
+  }
+
+  public boolean mustRevalidate() {
+    return mustRevalidate;
+  }
+
+  public int maxStaleSeconds() {
+    return maxStaleSeconds;
+  }
+
+  public int minFreshSeconds() {
+    return minFreshSeconds;
+  }
+
+  /**
+   * 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.
+   */
+  public boolean onlyIfCached() {
+    return onlyIfCached;
+  }
+
+  public boolean noTransform() {
+    return noTransform;
+  }
+
+  /**
+   * Returns the cache directives of {@code headers}. This honors both
+   * Cache-Control and Pragma headers if they are present.
+   */
+  public static CacheControl parse(Headers headers) {
+    boolean noCache = false;
+    boolean noStore = false;
+    int maxAgeSeconds = -1;
+    int sMaxAgeSeconds = -1;
+    boolean isPrivate = false;
+    boolean isPublic = false;
+    boolean mustRevalidate = false;
+    int maxStaleSeconds = -1;
+    int minFreshSeconds = -1;
+    boolean onlyIfCached = false;
+    boolean noTransform = false;
+
+    boolean canUseHeaderValue = true;
+    String headerValue = null;
+
+    for (int i = 0, size = headers.size(); i < size; i++) {
+      String name = headers.name(i);
+      String value = headers.value(i);
+
+      if (name.equalsIgnoreCase("Cache-Control")) {
+        if (headerValue != null) {
+          // Multiple cache-control headers means we can't use the raw value.
+          canUseHeaderValue = false;
+        } else {
+          headerValue = value;
+        }
+      } else if (name.equalsIgnoreCase("Pragma")) {
+        // Might specify additional cache-control params. We invalidate just in case.
+        canUseHeaderValue = false;
+      } else {
+        continue;
+      }
+
+      int pos = 0;
+      while (pos < value.length()) {
+        int tokenStart = pos;
+        pos = HeaderParser.skipUntil(value, pos, "=,;");
+        String directive = value.substring(tokenStart, pos).trim();
+        String parameter;
+
+        if (pos == value.length() || value.charAt(pos) == ',' || value.charAt(pos) == ';') {
+          pos++; // consume ',' or ';' (if necessary)
+          parameter = null;
+        } else {
+          pos++; // consume '='
+          pos = HeaderParser.skipWhitespace(value, pos);
+
+          // quoted string
+          if (pos < value.length() && value.charAt(pos) == '\"') {
+            pos++; // consume '"' open quote
+            int parameterStart = pos;
+            pos = HeaderParser.skipUntil(value, pos, "\"");
+            parameter = value.substring(parameterStart, pos);
+            pos++; // consume '"' close quote (if necessary)
+
+            // unquoted string
+          } else {
+            int parameterStart = pos;
+            pos = HeaderParser.skipUntil(value, pos, ",;");
+            parameter = value.substring(parameterStart, pos).trim();
+          }
+        }
+
+        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, -1);
+        } else if ("s-maxage".equalsIgnoreCase(directive)) {
+          sMaxAgeSeconds = HeaderParser.parseSeconds(parameter, -1);
+        } else if ("private".equalsIgnoreCase(directive)) {
+          isPrivate = true;
+        } else if ("public".equalsIgnoreCase(directive)) {
+          isPublic = true;
+        } else if ("must-revalidate".equalsIgnoreCase(directive)) {
+          mustRevalidate = true;
+        } else if ("max-stale".equalsIgnoreCase(directive)) {
+          maxStaleSeconds = HeaderParser.parseSeconds(parameter, Integer.MAX_VALUE);
+        } else if ("min-fresh".equalsIgnoreCase(directive)) {
+          minFreshSeconds = HeaderParser.parseSeconds(parameter, -1);
+        } else if ("only-if-cached".equalsIgnoreCase(directive)) {
+          onlyIfCached = true;
+        } else if ("no-transform".equalsIgnoreCase(directive)) {
+          noTransform = true;
+        }
+      }
+    }
+
+    if (!canUseHeaderValue) {
+      headerValue = null;
+    }
+    return new CacheControl(noCache, noStore, maxAgeSeconds, sMaxAgeSeconds, isPrivate, isPublic,
+        mustRevalidate, maxStaleSeconds, minFreshSeconds, onlyIfCached, noTransform, headerValue);
+  }
+
+  @Override public String toString() {
+    String result = headerValue;
+    return result != null ? result : (headerValue = headerValue());
+  }
+
+  private String headerValue() {
+    StringBuilder result = new StringBuilder();
+    if (noCache) result.append("no-cache, ");
+    if (noStore) result.append("no-store, ");
+    if (maxAgeSeconds != -1) result.append("max-age=").append(maxAgeSeconds).append(", ");
+    if (sMaxAgeSeconds != -1) result.append("s-maxage=").append(sMaxAgeSeconds).append(", ");
+    if (isPrivate) result.append("private, ");
+    if (isPublic) result.append("public, ");
+    if (mustRevalidate) result.append("must-revalidate, ");
+    if (maxStaleSeconds != -1) result.append("max-stale=").append(maxStaleSeconds).append(", ");
+    if (minFreshSeconds != -1) result.append("min-fresh=").append(minFreshSeconds).append(", ");
+    if (onlyIfCached) result.append("only-if-cached, ");
+    if (noTransform) result.append("no-transform, ");
+    if (result.length() == 0) return "";
+    result.delete(result.length() - 2, result.length());
+    return result.toString();
+  }
+
+  /** Builds a {@code Cache-Control} request header. 
+   * @hide This class is not part of the Android public SDK API*/
+  public static final class Builder {
+    boolean noCache;
+    boolean noStore;
+    int maxAgeSeconds = -1;
+    int maxStaleSeconds = -1;
+    int minFreshSeconds = -1;
+    boolean onlyIfCached;
+    boolean noTransform;
+
+    /** Don't accept an unvalidated cached response. */
+    public Builder noCache() {
+      this.noCache = true;
+      return this;
+    }
+
+    /** Don't store the server's response in any cache. */
+    public Builder noStore() {
+      this.noStore = true;
+      return this;
+    }
+
+    /**
+     * Sets the maximum age of a cached response. If the cache response's age
+     * exceeds {@code maxAge}, it will not be used and a network request will
+     * be made.
+     *
+     * @param maxAge a non-negative integer. This is stored and transmitted with
+     *     {@link TimeUnit#SECONDS} precision; finer precision will be lost.
+     */
+    public Builder maxAge(int maxAge, TimeUnit timeUnit) {
+      if (maxAge < 0) throw new IllegalArgumentException("maxAge < 0: " + maxAge);
+      long maxAgeSecondsLong = timeUnit.toSeconds(maxAge);
+      this.maxAgeSeconds = maxAgeSecondsLong > Integer.MAX_VALUE
+          ? Integer.MAX_VALUE
+          : (int) maxAgeSecondsLong;
+      return this;
+    }
+
+    /**
+     * Accept cached responses that have exceeded their freshness lifetime by
+     * up to {@code maxStale}. If unspecified, stale cache responses will not be
+     * used.
+     *
+     * @param maxStale a non-negative integer. This is stored and transmitted
+     *     with {@link TimeUnit#SECONDS} precision; finer precision will be
+     *     lost.
+     */
+    public Builder maxStale(int maxStale, TimeUnit timeUnit) {
+      if (maxStale < 0) throw new IllegalArgumentException("maxStale < 0: " + maxStale);
+      long maxStaleSecondsLong = timeUnit.toSeconds(maxStale);
+      this.maxStaleSeconds = maxStaleSecondsLong > Integer.MAX_VALUE
+          ? Integer.MAX_VALUE
+          : (int) maxStaleSecondsLong;
+      return this;
+    }
+
+    /**
+     * Sets the minimum number of seconds that a response will continue to be
+     * fresh for. If the response will be stale when {@code minFresh} have
+     * elapsed, the cached response will not be used and a network request will
+     * be made.
+     *
+     * @param minFresh a non-negative integer. This is stored and transmitted
+     *     with {@link TimeUnit#SECONDS} precision; finer precision will be
+     *     lost.
+     */
+    public Builder minFresh(int minFresh, TimeUnit timeUnit) {
+      if (minFresh < 0) throw new IllegalArgumentException("minFresh < 0: " + minFresh);
+      long minFreshSecondsLong = timeUnit.toSeconds(minFresh);
+      this.minFreshSeconds = minFreshSecondsLong > Integer.MAX_VALUE
+          ? Integer.MAX_VALUE
+          : (int) minFreshSecondsLong;
+      return this;
+    }
+
+    /**
+     * Only accept the response if it is in the cache. If the response isn't
+     * cached, a {@code 504 Unsatisfiable Request} response will be returned.
+     */
+    public Builder onlyIfCached() {
+      this.onlyIfCached = true;
+      return this;
+    }
+
+    /** Don't accept a transformed response. */
+    public Builder noTransform() {
+      this.noTransform = true;
+      return this;
+    }
+
+    public CacheControl build() {
+      return new CacheControl(this);
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/Call.java b/repackaged/okhttp/src/main/java/com/android/okhttp/Call.java
new file mode 100644
index 0000000..25cddd0
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/Call.java
@@ -0,0 +1,350 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp;
+
+import com.android.okhttp.internal.NamedRunnable;
+import com.android.okhttp.internal.http.HttpEngine;
+import com.android.okhttp.internal.http.RequestException;
+import com.android.okhttp.internal.http.RouteException;
+import com.android.okhttp.internal.http.StreamAllocation;
+import java.io.IOException;
+import java.net.ProtocolException;
+import java.util.logging.Level;
+
+import static com.android.okhttp.internal.Internal.logger;
+import static com.android.okhttp.internal.http.HttpEngine.MAX_FOLLOW_UPS;
+
+/**
+ * A call is a request that has been prepared for execution. A call can be
+ * canceled. As this object represents a single request/response pair (stream),
+ * it cannot be executed twice.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Call {
+  private final OkHttpClient client;
+
+  // Guarded by this.
+  private boolean executed;
+  volatile boolean canceled;
+
+  /** The application's original request unadulterated by redirects or auth headers. */
+  Request originalRequest;
+  HttpEngine engine;
+
+  protected Call(OkHttpClient client, Request originalRequest) {
+    // Copy the client. Otherwise changes (socket factory, redirect policy,
+    // etc.) may incorrectly be reflected in the request when it is executed.
+    this.client = client.copyWithDefaults();
+    this.originalRequest = originalRequest;
+  }
+
+  /**
+   * Invokes the request immediately, and blocks until the response can be
+   * processed or is in error.
+   *
+   * <p>The caller may read the response body with the response's
+   * {@link Response#body} method.  To facilitate connection recycling, callers
+   * should always {@link ResponseBody#close() close the response body}.
+   *
+   * <p>Note that transport-layer success (receiving a HTTP response code,
+   * headers and body) does not necessarily indicate application-layer success:
+   * {@code response} may still indicate an unhappy HTTP response code like 404
+   * or 500.
+   *
+   * @throws IOException if the request could not be executed due to
+   *     cancellation, a connectivity problem or timeout. Because networks can
+   *     fail during an exchange, it is possible that the remote server
+   *     accepted the request before the failure.
+   *
+   * @throws IllegalStateException when the call has already been executed.
+   */
+  public Response execute() throws IOException {
+    synchronized (this) {
+      if (executed) throw new IllegalStateException("Already Executed");
+      executed = true;
+    }
+    try {
+      client.getDispatcher().executed(this);
+      Response result = getResponseWithInterceptorChain(false);
+      if (result == null) throw new IOException("Canceled");
+      return result;
+    } finally {
+      client.getDispatcher().finished(this);
+    }
+  }
+
+  Object tag() {
+    return originalRequest.tag();
+  }
+
+  /**
+   * Schedules the request to be executed at some point in the future.
+   *
+   * <p>The {@link OkHttpClient#getDispatcher dispatcher} defines when the
+   * request will run: usually immediately unless there are several other
+   * requests currently being executed.
+   *
+   * <p>This client will later call back {@code responseCallback} with either
+   * an HTTP response or a failure exception. If you {@link #cancel} a request
+   * before it completes the callback will not be invoked.
+   *
+   * @throws IllegalStateException when the call has already been executed.
+   */
+  public void enqueue(Callback responseCallback) {
+    enqueue(responseCallback, false);
+  }
+
+  void enqueue(Callback responseCallback, boolean forWebSocket) {
+    synchronized (this) {
+      if (executed) throw new IllegalStateException("Already Executed");
+      executed = true;
+    }
+    client.getDispatcher().enqueue(new AsyncCall(responseCallback, forWebSocket));
+  }
+
+  /**
+   * Cancels the request, if possible. Requests that are already complete
+   * cannot be canceled.
+   */
+  public void cancel() {
+    canceled = true;
+    if (engine != null) engine.cancel();
+  }
+
+  /**
+   * Returns true if this call has been either {@linkplain #execute() executed} or {@linkplain
+   * #enqueue(Callback) enqueued}. It is an error to execute a call more than once.
+   */
+  public synchronized boolean isExecuted() {
+    return executed;
+  }
+
+  public boolean isCanceled() {
+    return canceled;
+  }
+
+  final class AsyncCall extends NamedRunnable {
+    private final Callback responseCallback;
+    private final boolean forWebSocket;
+
+    private AsyncCall(Callback responseCallback, boolean forWebSocket) {
+      super("OkHttp %s", originalRequest.urlString());
+      this.responseCallback = responseCallback;
+      this.forWebSocket = forWebSocket;
+    }
+
+    String host() {
+      return originalRequest.httpUrl().host();
+    }
+
+    Request request() {
+      return originalRequest;
+    }
+
+    Object tag() {
+      return originalRequest.tag();
+    }
+
+    void cancel() {
+      Call.this.cancel();
+    }
+
+    Call get() {
+      return Call.this;
+    }
+
+    @Override protected void execute() {
+      boolean signalledCallback = false;
+      try {
+        Response response = getResponseWithInterceptorChain(forWebSocket);
+        if (canceled) {
+          signalledCallback = true;
+          responseCallback.onFailure(originalRequest, new IOException("Canceled"));
+        } else {
+          signalledCallback = true;
+          responseCallback.onResponse(response);
+        }
+      } catch (IOException e) {
+        if (signalledCallback) {
+          // Do not signal the callback twice!
+          logger.log(Level.INFO, "Callback failure for " + toLoggableString(), e);
+        } else {
+          Request request = engine == null ? originalRequest : engine.getRequest();
+          responseCallback.onFailure(request, e);
+        }
+      } finally {
+        client.getDispatcher().finished(this);
+      }
+    }
+  }
+
+  /**
+   * Returns a string that describes this call. Doesn't include a full URL as that might contain
+   * sensitive information.
+   */
+  private String toLoggableString() {
+    String string = canceled ? "canceled call" : "call";
+    HttpUrl redactedUrl = originalRequest.httpUrl().resolve("/...");
+    return string + " to " + redactedUrl;
+  }
+
+  private Response getResponseWithInterceptorChain(boolean forWebSocket) throws IOException {
+    Interceptor.Chain chain = new ApplicationInterceptorChain(0, originalRequest, forWebSocket);
+    return chain.proceed(originalRequest);
+  }
+
+  class ApplicationInterceptorChain implements Interceptor.Chain {
+    private final int index;
+    private final Request request;
+    private final boolean forWebSocket;
+
+    ApplicationInterceptorChain(int index, Request request, boolean forWebSocket) {
+      this.index = index;
+      this.request = request;
+      this.forWebSocket = forWebSocket;
+    }
+
+    @Override public Connection connection() {
+      return null;
+    }
+
+    @Override public Request request() {
+      return request;
+    }
+
+    @Override public Response proceed(Request request) throws IOException {
+      // If there's another interceptor in the chain, call that.
+      if (index < client.interceptors().size()) {
+        Interceptor.Chain chain = new ApplicationInterceptorChain(index + 1, request, forWebSocket);
+        Interceptor interceptor = client.interceptors().get(index);
+        Response interceptedResponse = interceptor.intercept(chain);
+
+        if (interceptedResponse == null) {
+          throw new NullPointerException("application interceptor " + interceptor
+              + " returned null");
+        }
+
+        return interceptedResponse;
+      }
+
+      // No more interceptors. Do HTTP.
+      return getResponse(request, forWebSocket);
+    }
+  }
+
+  /**
+   * Performs the request and returns the response. May return null if this
+   * call was canceled.
+   */
+  Response getResponse(Request request, boolean forWebSocket) throws IOException {
+    // Copy body metadata to the appropriate request headers.
+    RequestBody body = request.body();
+    if (body != null) {
+      Request.Builder requestBuilder = request.newBuilder();
+
+      MediaType contentType = body.contentType();
+      if (contentType != null) {
+        requestBuilder.header("Content-Type", contentType.toString());
+      }
+
+      long contentLength = body.contentLength();
+      if (contentLength != -1) {
+        requestBuilder.header("Content-Length", Long.toString(contentLength));
+        requestBuilder.removeHeader("Transfer-Encoding");
+      } else {
+        requestBuilder.header("Transfer-Encoding", "chunked");
+        requestBuilder.removeHeader("Content-Length");
+      }
+
+      request = requestBuilder.build();
+    }
+
+    // Create the initial HTTP engine. Retries and redirects need new engine for each attempt.
+    engine = new HttpEngine(client, request, false, false, forWebSocket, null, null, null);
+
+    int followUpCount = 0;
+    while (true) {
+      if (canceled) {
+        engine.releaseStreamAllocation();
+        throw new IOException("Canceled");
+      }
+
+      boolean releaseConnection = true;
+      try {
+        engine.sendRequest();
+        engine.readResponse();
+        releaseConnection = false;
+      } catch (RequestException e) {
+        // The attempt to interpret the request failed. Give up.
+        throw e.getCause();
+      } catch (RouteException e) {
+        // The attempt to connect via a route failed. The request will not have been sent.
+        HttpEngine retryEngine = engine.recover(e);
+        if (retryEngine != null) {
+          releaseConnection = false;
+          engine = retryEngine;
+          continue;
+        }
+        // Give up; recovery is not possible.
+        throw e.getLastConnectException();
+      } catch (IOException e) {
+        // An attempt to communicate with a server failed. The request may have been sent.
+        HttpEngine retryEngine = engine.recover(e, null);
+        if (retryEngine != null) {
+          releaseConnection = false;
+          engine = retryEngine;
+          continue;
+        }
+
+        // Give up; recovery is not possible.
+        throw e;
+      } finally {
+        // We're throwing an unchecked exception. Release any resources.
+        if (releaseConnection) {
+          StreamAllocation streamAllocation = engine.close();
+          streamAllocation.release();
+        }
+      }
+
+      Response response = engine.getResponse();
+      Request followUp = engine.followUpRequest();
+
+      if (followUp == null) {
+        if (!forWebSocket) {
+          engine.releaseStreamAllocation();
+        }
+        return response;
+      }
+
+      StreamAllocation streamAllocation = engine.close();
+
+      if (++followUpCount > MAX_FOLLOW_UPS) {
+        streamAllocation.release();
+        throw new ProtocolException("Too many follow-up requests: " + followUpCount);
+      }
+
+      if (!engine.sameConnection(followUp.httpUrl())) {
+        streamAllocation.release();
+        streamAllocation = null;
+      }
+
+      request = followUp;
+      engine = new HttpEngine(client, request, false, false, forWebSocket, streamAllocation, null,
+          response);
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/Callback.java b/repackaged/okhttp/src/main/java/com/android/okhttp/Callback.java
new file mode 100644
index 0000000..10d78c6
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/Callback.java
@@ -0,0 +1,46 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp;
+
+import java.io.IOException;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface Callback {
+  /**
+   * Called when the request could not be executed due to cancellation, a
+   * connectivity problem or timeout. Because networks can fail during an
+   * exchange, it is possible that the remote server accepted the request
+   * before the failure.
+   */
+  void onFailure(Request request, IOException e);
+
+  /**
+   * Called when the HTTP response was successfully returned by the remote
+   * server. The callback may proceed to read the response body with {@link
+   * Response#body}. The response is still live until its response body is
+   * closed with {@code response.body().close()}. The recipient of the callback
+   * may even consume the response body on another thread.
+   *
+   * <p>Note that transport-layer success (receiving a HTTP response code,
+   * headers and body) does not necessarily indicate application-layer
+   * success: {@code response} may still indicate an unhappy HTTP response
+   * code like 404 or 500.
+   */
+  void onResponse(Response response) throws IOException;
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/CertificatePinner.java b/repackaged/okhttp/src/main/java/com/android/okhttp/CertificatePinner.java
new file mode 100644
index 0000000..638dea0
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/CertificatePinner.java
@@ -0,0 +1,275 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp;
+
+import com.android.okhttp.internal.Util;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import com.android.okhttp.okio.ByteString;
+
+import static java.util.Collections.unmodifiableSet;
+
+/**
+ * Constrains which certificates are trusted. Pinning certificates defends
+ * against attacks on certificate authorities. It also prevents connections
+ * through man-in-the-middle certificate authorities either known or unknown to
+ * the application's user.
+ *
+ * <p>This class currently pins a certificate's Subject Public Key Info as
+ * described on <a href="http://goo.gl/AIx3e5">Adam Langley's Weblog</a>. Pins
+ * are base-64 SHA-1 hashes, consistent with the format Chromium uses for <a
+ * href="http://goo.gl/XDh6je">static certificates</a>. See Chromium's <a
+ * href="http://goo.gl/4CCnGs">pinsets</a> for hostnames that are pinned in that
+ * browser.
+ *
+ * <h3>Setting up Certificate Pinning</h3>
+ * The easiest way to pin a host is turn on pinning with a broken configuration
+ * and read the expected configuration when the connection fails. Be sure to
+ * do this on a trusted network, and without man-in-the-middle tools like <a
+ * href="http://charlesproxy.com">Charles</a> or <a
+ * href="http://fiddlertool.com">Fiddler</a>.
+ *
+ * <p>For example, to pin {@code https://publicobject.com}, start with a broken
+ * configuration: <pre>   {@code
+ *
+ *     String hostname = "publicobject.com";
+ *     CertificatePinner certificatePinner = new CertificatePinner.Builder()
+ *         .add(hostname, "sha1/AAAAAAAAAAAAAAAAAAAAAAAAAAA=")
+ *         .build();
+ *     OkHttpClient client = new OkHttpClient();
+ *     client.setCertificatePinner(certificatePinner);
+ *
+ *     Request request = new Request.Builder()
+ *         .url("https://" + hostname)
+ *         .build();
+ *     client.newCall(request).execute();
+ * }</pre>
+ *
+ * As expected, this fails with a certificate pinning exception: <pre>   {@code
+ *
+ * javax.net.ssl.SSLPeerUnverifiedException: Certificate pinning failure!
+ *   Peer certificate chain:
+ *     sha1/DmxUShsZuNiqPQsX2Oi9uv2sCnw=: CN=publicobject.com, OU=PositiveSSL
+ *     sha1/SXxoaOSEzPC6BgGmxAt/EAcsajw=: CN=COMODO RSA Domain Validation Secure Server CA
+ *     sha1/blhOM3W9V/bVQhsWAcLYwPU6n24=: CN=COMODO RSA Certification Authority
+ *     sha1/T5x9IXmcrQ7YuQxXnxoCmeeQ84c=: CN=AddTrust External CA Root
+ *   Pinned certificates for publicobject.com:
+ *     sha1/AAAAAAAAAAAAAAAAAAAAAAAAAAA=
+ *   at com.squareup.okhttp.CertificatePinner.check(CertificatePinner.java)
+ *   at com.squareup.okhttp.Connection.upgradeToTls(Connection.java)
+ *   at com.squareup.okhttp.Connection.connect(Connection.java)
+ *   at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java)
+ * }</pre>
+ *
+ * Follow up by pasting the public key hashes from the exception into the
+ * certificate pinner's configuration: <pre>   {@code
+ *
+ *     CertificatePinner certificatePinner = new CertificatePinner.Builder()
+ *       .add("publicobject.com", "sha1/DmxUShsZuNiqPQsX2Oi9uv2sCnw=")
+ *       .add("publicobject.com", "sha1/SXxoaOSEzPC6BgGmxAt/EAcsajw=")
+ *       .add("publicobject.com", "sha1/blhOM3W9V/bVQhsWAcLYwPU6n24=")
+ *       .add("publicobject.com", "sha1/T5x9IXmcrQ7YuQxXnxoCmeeQ84c=")
+ *       .build();
+ * }</pre>
+ *
+ * Pinning is per-hostname and/or per-wildcard pattern. To pin both
+ * {@code publicobject.com} and {@code www.publicobject.com}, you must
+ * configure both hostnames.
+ *
+ * <p>Wildcard pattern rules:
+ * <ol>
+ *   <li>Asterisk {@code *} is only permitted in the left-most
+ *       domain name label and must be the only character in that label
+ *       (i.e., must match the whole left-most label). For example,
+ *       {@code *.example.com} is permitted, while {@code *a.example.com},
+ *       {@code a*.example.com}, {@code a*b.example.com}, {@code a.*.example.com}
+ *       are not permitted.
+ *   <li>Asterisk {@code *} cannot match across domain name labels.
+ *       For example, {@code *.example.com} matches {@code test.example.com}
+ *       but does not match {@code sub.test.example.com}.
+ *   <li>Wildcard patterns for single-label domain names are not permitted.
+ * </ol>
+ *
+ * If hostname pinned directly and via wildcard pattern, both
+ * direct and wildcard pins will be used. For example: {@code *.example.com} pinned
+ * with {@code pin1} and {@code a.example.com} pinned with {@code pin2},
+ * to check {@code a.example.com} both {@code pin1} and {@code pin2} will be used.
+ *
+ * <h3>Warning: Certificate Pinning is Dangerous!</h3>
+ * Pinning certificates limits your server team's abilities to update their TLS
+ * certificates. By pinning certificates, you take on additional operational
+ * complexity and limit your ability to migrate between certificate authorities.
+ * Do not use certificate pinning without the blessing of your server's TLS
+ * administrator!
+ *
+ * <h4>Note about self-signed certificates</h4>
+ * {@link CertificatePinner} can not be used to pin self-signed certificate
+ * if such certificate is not accepted by {@link javax.net.ssl.TrustManager}.
+ *
+ * @see <a href="https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning">
+ *     OWASP: Certificate and Public Key Pinning</a>
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class CertificatePinner {
+  public static final CertificatePinner DEFAULT = new Builder().build();
+
+  private final Map<String, Set<ByteString>> hostnameToPins;
+
+  private CertificatePinner(Builder builder) {
+    this.hostnameToPins = Util.immutableMap(builder.hostnameToPins);
+  }
+
+  /**
+   * Confirms that at least one of the certificates pinned for {@code hostname}
+   * is in {@code peerCertificates}. Does nothing if there are no certificates
+   * pinned for {@code hostname}. OkHttp calls this after a successful TLS
+   * handshake, but before the connection is used.
+   *
+   * @throws SSLPeerUnverifiedException if {@code peerCertificates} don't match
+   *     the certificates pinned for {@code hostname}.
+   */
+  public void check(String hostname, List<Certificate> peerCertificates)
+      throws SSLPeerUnverifiedException {
+
+    Set<ByteString> pins = findMatchingPins(hostname);
+
+    if (pins == null) return;
+
+    for (int i = 0, size = peerCertificates.size(); i < size; i++) {
+      X509Certificate x509Certificate = (X509Certificate) peerCertificates.get(i);
+      if (pins.contains(sha1(x509Certificate))) return; // Success!
+    }
+
+    // If we couldn't find a matching pin, format a nice exception.
+    StringBuilder message = new StringBuilder()
+        .append("Certificate pinning failure!")
+        .append("\n  Peer certificate chain:");
+    for (int i = 0, size = peerCertificates.size(); i < size; i++) {
+      X509Certificate x509Certificate = (X509Certificate) peerCertificates.get(i);
+      message.append("\n    ").append(pin(x509Certificate))
+          .append(": ").append(x509Certificate.getSubjectDN().getName());
+    }
+    message.append("\n  Pinned certificates for ").append(hostname).append(":");
+    for (ByteString pin : pins) {
+      message.append("\n    sha1/").append(pin.base64());
+    }
+    throw new SSLPeerUnverifiedException(message.toString());
+  }
+
+  /** @deprecated replaced with {@link #check(String, List)}. */
+  public void check(String hostname, Certificate... peerCertificates)
+      throws SSLPeerUnverifiedException {
+    check(hostname, Arrays.asList(peerCertificates));
+  }
+
+  /**
+   * Returns list of matching certificates' pins for the hostname
+   * or {@code null} if hostname does not have pinned certificates.
+   */
+  Set<ByteString> findMatchingPins(String hostname) {
+    Set<ByteString> directPins   = hostnameToPins.get(hostname);
+    Set<ByteString> wildcardPins = null;
+
+    int indexOfFirstDot = hostname.indexOf('.');
+    int indexOfLastDot  = hostname.lastIndexOf('.');
+
+    // Skip hostnames with one dot symbol for wildcard pattern search
+    //   example.com   will  be skipped
+    //   a.example.com won't be skipped
+    if (indexOfFirstDot != indexOfLastDot) {
+      // a.example.com -> search for wildcard pattern *.example.com
+      wildcardPins = hostnameToPins.get("*." + hostname.substring(indexOfFirstDot + 1));
+    }
+
+    if (directPins == null && wildcardPins == null) return null;
+
+    if (directPins != null && wildcardPins != null) {
+      Set<ByteString> pins = new LinkedHashSet<>();
+      pins.addAll(directPins);
+      pins.addAll(wildcardPins);
+      return pins;
+    }
+
+    if (directPins != null) return directPins;
+
+    return wildcardPins;
+  }
+
+  /**
+   * Returns the SHA-1 of {@code certificate}'s public key. This uses the
+   * mechanism Moxie Marlinspike describes in <a
+   * href="https://github.com/moxie0/AndroidPinning">Android Pinning</a>.
+   */
+  public static String pin(Certificate certificate) {
+    if (!(certificate instanceof X509Certificate)) {
+      throw new IllegalArgumentException("Certificate pinning requires X509 certificates");
+    }
+    return "sha1/" + sha1((X509Certificate) certificate).base64();
+  }
+
+  private static ByteString sha1(X509Certificate x509Certificate) {
+    return Util.sha1(ByteString.of(x509Certificate.getPublicKey().getEncoded()));
+  }
+
+  /** Builds a configured certificate pinner. 
+   * @hide This class is not part of the Android public SDK API*/
+  public static final class Builder {
+    private final Map<String, Set<ByteString>> hostnameToPins = new LinkedHashMap<>();
+
+    /**
+     * Pins certificates for {@code hostname}.
+     *
+     * @param hostname lower-case host name or wildcard pattern such as {@code *.example.com}.
+     * @param pins SHA-1 hashes. Each pin is a SHA-1 hash of a
+     *     certificate's Subject Public Key Info, base64-encoded and prefixed with
+     *     {@code sha1/}.
+     */
+    public Builder add(String hostname, String... pins) {
+      if (hostname == null) throw new IllegalArgumentException("hostname == null");
+
+      Set<ByteString> hostPins = new LinkedHashSet<>();
+      Set<ByteString> previousPins = hostnameToPins.put(hostname, unmodifiableSet(hostPins));
+      if (previousPins != null) {
+        hostPins.addAll(previousPins);
+      }
+
+      for (String pin : pins) {
+        if (!pin.startsWith("sha1/")) {
+          throw new IllegalArgumentException("pins must start with 'sha1/': " + pin);
+        }
+        ByteString decodedPin = ByteString.decodeBase64(pin.substring("sha1/".length()));
+        if (decodedPin == null) {
+          throw new IllegalArgumentException("pins must be base64: " + pin);
+        }
+        hostPins.add(decodedPin);
+      }
+
+      return this;
+    }
+
+    public CertificatePinner build() {
+      return new CertificatePinner(this);
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/Challenge.java b/repackaged/okhttp/src/main/java/com/android/okhttp/Challenge.java
new file mode 100644
index 0000000..20f11d2
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/Challenge.java
@@ -0,0 +1,58 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp;
+
+import static com.android.okhttp.internal.Util.equal;
+
+/** An RFC 2617 challenge. 
+ * @hide This class is not part of the Android public SDK API*/
+public final class Challenge {
+  private final String scheme;
+  private final String realm;
+
+  public Challenge(String scheme, String realm) {
+    this.scheme = scheme;
+    this.realm = realm;
+  }
+
+  /** Returns the authentication scheme, like {@code Basic}. */
+  public String getScheme() {
+    return scheme;
+  }
+
+  /** Returns the protection space. */
+  public String getRealm() {
+    return realm;
+  }
+
+  @Override public boolean equals(Object o) {
+    return o instanceof Challenge
+        && equal(scheme, ((Challenge) o).scheme)
+        && equal(realm, ((Challenge) o).realm);
+  }
+
+  @Override public int hashCode() {
+    int result = 29;
+    result = 31 * result + (realm != null ? realm.hashCode() : 0);
+    result = 31 * result + (scheme != null ? scheme.hashCode() : 0);
+    return result;
+  }
+
+  @Override public String toString() {
+    return scheme + " realm=\"" + realm + "\"";
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/CipherSuite.java b/repackaged/okhttp/src/main/java/com/android/okhttp/CipherSuite.java
new file mode 100644
index 0000000..bc15fb7
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/CipherSuite.java
@@ -0,0 +1,377 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp;
+
+import static java.lang.Integer.MAX_VALUE;
+
+/**
+ * <a href="https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml">TLS cipher
+ * suites</a>.
+ *
+ * <p><strong>Not all cipher suites are supported on all platforms.</strong> As newer cipher suites
+ * are created (for stronger privacy, better performance, etc.) they will be adopted by the platform
+ * and then exposed here. Cipher suites that are not available on either Android (through API level
+ * 20) or Java (through JDK 8) are omitted for brevity.
+ *
+ * <p>See also <a href="https://android.googlesource.com/platform/external/conscrypt/+/master/src/main/java/org/conscrypt/NativeCrypto.java">NativeCrypto.java</a>
+ * from conscrypt, which lists the cipher suites supported by Android.
+ * @hide This class is not part of the Android public SDK API
+ */
+public enum CipherSuite {
+  // Last updated 2014-11-11 using cipher suites from Android 21 and Java 8.
+
+  // TLS_NULL_WITH_NULL_NULL("TLS_NULL_WITH_NULL_NULL", 0x0000, 5246, MAX_VALUE, MAX_VALUE),
+  TLS_RSA_WITH_NULL_MD5("SSL_RSA_WITH_NULL_MD5", 0x0001, 5246, 6, 10),
+  TLS_RSA_WITH_NULL_SHA("SSL_RSA_WITH_NULL_SHA", 0x0002, 5246, 6, 10),
+  TLS_RSA_EXPORT_WITH_RC4_40_MD5("SSL_RSA_EXPORT_WITH_RC4_40_MD5", 0x0003, 4346, 6, 10),
+  TLS_RSA_WITH_RC4_128_MD5("SSL_RSA_WITH_RC4_128_MD5", 0x0004, 5246, 6, 10),
+  TLS_RSA_WITH_RC4_128_SHA("SSL_RSA_WITH_RC4_128_SHA", 0x0005, 5246, 6, 10),
+  // TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5("SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5", 0x0006, 4346, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_WITH_IDEA_CBC_SHA("TLS_RSA_WITH_IDEA_CBC_SHA", 0x0007, 5469, MAX_VALUE, MAX_VALUE),
+  TLS_RSA_EXPORT_WITH_DES40_CBC_SHA("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", 0x0008, 4346, 6, 10),
+  TLS_RSA_WITH_DES_CBC_SHA("SSL_RSA_WITH_DES_CBC_SHA", 0x0009, 5469, 6, 10),
+  TLS_RSA_WITH_3DES_EDE_CBC_SHA("SSL_RSA_WITH_3DES_EDE_CBC_SHA", 0x000a, 5246, 6, 10),
+  // TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA("SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", 0x000b, 4346, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_DSS_WITH_DES_CBC_SHA("TLS_DH_DSS_WITH_DES_CBC_SHA", 0x000c, 5469, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA("TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA", 0x000d, 5246, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA("SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", 0x000e, 4346, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_RSA_WITH_DES_CBC_SHA("TLS_DH_RSA_WITH_DES_CBC_SHA", 0x000f, 5469, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA("TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA", 0x0010, 5246, MAX_VALUE, MAX_VALUE),
+  TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", 0x0011, 4346, 6, 10),
+  TLS_DHE_DSS_WITH_DES_CBC_SHA("SSL_DHE_DSS_WITH_DES_CBC_SHA", 0x0012, 5469, 6, 10),
+  TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA("SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", 0x0013, 5246, 6, 10),
+  TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", 0x0014, 4346, 6, 10),
+  TLS_DHE_RSA_WITH_DES_CBC_SHA("SSL_DHE_RSA_WITH_DES_CBC_SHA", 0x0015, 5469, 6, 10),
+  TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA("SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", 0x0016, 5246, 6, 10),
+  TLS_DH_anon_EXPORT_WITH_RC4_40_MD5("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", 0x0017, 4346, 6, 10),
+  TLS_DH_anon_WITH_RC4_128_MD5("SSL_DH_anon_WITH_RC4_128_MD5", 0x0018, 5246, 6, 10),
+  TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", 0x0019, 4346, 6, 10),
+  TLS_DH_anon_WITH_DES_CBC_SHA("SSL_DH_anon_WITH_DES_CBC_SHA", 0x001a, 5469, 6, 10),
+  TLS_DH_anon_WITH_3DES_EDE_CBC_SHA("SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", 0x001b, 5246, 6, 10),
+  TLS_KRB5_WITH_DES_CBC_SHA("TLS_KRB5_WITH_DES_CBC_SHA", 0x001e, 2712, 6, MAX_VALUE),
+  TLS_KRB5_WITH_3DES_EDE_CBC_SHA("TLS_KRB5_WITH_3DES_EDE_CBC_SHA", 0x001f, 2712, 6, MAX_VALUE),
+  TLS_KRB5_WITH_RC4_128_SHA("TLS_KRB5_WITH_RC4_128_SHA", 0x0020, 2712, 6, MAX_VALUE),
+  // TLS_KRB5_WITH_IDEA_CBC_SHA("TLS_KRB5_WITH_IDEA_CBC_SHA", 0x0021, 2712, MAX_VALUE, MAX_VALUE),
+  TLS_KRB5_WITH_DES_CBC_MD5("TLS_KRB5_WITH_DES_CBC_MD5", 0x0022, 2712, 6, MAX_VALUE),
+  TLS_KRB5_WITH_3DES_EDE_CBC_MD5("TLS_KRB5_WITH_3DES_EDE_CBC_MD5", 0x0023, 2712, 6, MAX_VALUE),
+  TLS_KRB5_WITH_RC4_128_MD5("TLS_KRB5_WITH_RC4_128_MD5", 0x0024, 2712, 6, MAX_VALUE),
+  // TLS_KRB5_WITH_IDEA_CBC_MD5("TLS_KRB5_WITH_IDEA_CBC_MD5", 0x0025, 2712, MAX_VALUE, MAX_VALUE),
+  TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA("TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", 0x0026, 2712, 6, MAX_VALUE),
+  // TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA", 0x0027, 2712, MAX_VALUE, MAX_VALUE),
+  TLS_KRB5_EXPORT_WITH_RC4_40_SHA("TLS_KRB5_EXPORT_WITH_RC4_40_SHA", 0x0028, 2712, 6, MAX_VALUE),
+  TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", 0x0029, 2712, 6, MAX_VALUE),
+  // TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5", 0x002a, 2712, MAX_VALUE, MAX_VALUE),
+  TLS_KRB5_EXPORT_WITH_RC4_40_MD5("TLS_KRB5_EXPORT_WITH_RC4_40_MD5", 0x002b, 2712, 6, MAX_VALUE),
+  // TLS_PSK_WITH_NULL_SHA("TLS_PSK_WITH_NULL_SHA", 0x002c, 4785, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_NULL_SHA("TLS_DHE_PSK_WITH_NULL_SHA", 0x002d, 4785, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_PSK_WITH_NULL_SHA("TLS_RSA_PSK_WITH_NULL_SHA", 0x002e, 4785, MAX_VALUE, MAX_VALUE),
+  TLS_RSA_WITH_AES_128_CBC_SHA("TLS_RSA_WITH_AES_128_CBC_SHA", 0x002f, 5246, 6, 10),
+  // TLS_DH_DSS_WITH_AES_128_CBC_SHA("TLS_DH_DSS_WITH_AES_128_CBC_SHA", 0x0030, 5246, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_RSA_WITH_AES_128_CBC_SHA("TLS_DH_RSA_WITH_AES_128_CBC_SHA", 0x0031, 5246, MAX_VALUE, MAX_VALUE),
+  TLS_DHE_DSS_WITH_AES_128_CBC_SHA("TLS_DHE_DSS_WITH_AES_128_CBC_SHA", 0x0032, 5246, 6, 10),
+  TLS_DHE_RSA_WITH_AES_128_CBC_SHA("TLS_DHE_RSA_WITH_AES_128_CBC_SHA", 0x0033, 5246, 6, 10),
+  TLS_DH_anon_WITH_AES_128_CBC_SHA("TLS_DH_anon_WITH_AES_128_CBC_SHA", 0x0034, 5246, 6, 10),
+  TLS_RSA_WITH_AES_256_CBC_SHA("TLS_RSA_WITH_AES_256_CBC_SHA", 0x0035, 5246, 6, 10),
+  // TLS_DH_DSS_WITH_AES_256_CBC_SHA("TLS_DH_DSS_WITH_AES_256_CBC_SHA", 0x0036, 5246, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_RSA_WITH_AES_256_CBC_SHA("TLS_DH_RSA_WITH_AES_256_CBC_SHA", 0x0037, 5246, MAX_VALUE, MAX_VALUE),
+  TLS_DHE_DSS_WITH_AES_256_CBC_SHA("TLS_DHE_DSS_WITH_AES_256_CBC_SHA", 0x0038, 5246, 6, 10),
+  TLS_DHE_RSA_WITH_AES_256_CBC_SHA("TLS_DHE_RSA_WITH_AES_256_CBC_SHA", 0x0039, 5246, 6, 10),
+  TLS_DH_anon_WITH_AES_256_CBC_SHA("TLS_DH_anon_WITH_AES_256_CBC_SHA", 0x003a, 5246, 6, 10),
+  TLS_RSA_WITH_NULL_SHA256("TLS_RSA_WITH_NULL_SHA256", 0x003b, 5246, 7, 21),
+  TLS_RSA_WITH_AES_128_CBC_SHA256("TLS_RSA_WITH_AES_128_CBC_SHA256", 0x003c, 5246, 7, 21),
+  TLS_RSA_WITH_AES_256_CBC_SHA256("TLS_RSA_WITH_AES_256_CBC_SHA256", 0x003d, 5246, 7, 21),
+  // TLS_DH_DSS_WITH_AES_128_CBC_SHA256("TLS_DH_DSS_WITH_AES_128_CBC_SHA256", 0x003e, 5246, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_RSA_WITH_AES_128_CBC_SHA256("TLS_DH_RSA_WITH_AES_128_CBC_SHA256", 0x003f, 5246, MAX_VALUE, MAX_VALUE),
+  TLS_DHE_DSS_WITH_AES_128_CBC_SHA256("TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", 0x0040, 5246, 7, 21),
+  // TLS_RSA_WITH_CAMELLIA_128_CBC_SHA("TLS_RSA_WITH_CAMELLIA_128_CBC_SHA", 0x0041, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA("TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA", 0x0042, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA("TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA", 0x0043, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA("TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA", 0x0044, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA("TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", 0x0045, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA("TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA", 0x0046, 5932, MAX_VALUE, MAX_VALUE),
+  TLS_DHE_RSA_WITH_AES_128_CBC_SHA256("TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", 0x0067, 5246, 7, 21),
+  // TLS_DH_DSS_WITH_AES_256_CBC_SHA256("TLS_DH_DSS_WITH_AES_256_CBC_SHA256", 0x0068, 5246, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_RSA_WITH_AES_256_CBC_SHA256("TLS_DH_RSA_WITH_AES_256_CBC_SHA256", 0x0069, 5246, MAX_VALUE, MAX_VALUE),
+  TLS_DHE_DSS_WITH_AES_256_CBC_SHA256("TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", 0x006a, 5246, 7, 21),
+  TLS_DHE_RSA_WITH_AES_256_CBC_SHA256("TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", 0x006b, 5246, 7, 21),
+  TLS_DH_anon_WITH_AES_128_CBC_SHA256("TLS_DH_anon_WITH_AES_128_CBC_SHA256", 0x006c, 5246, 7, 21),
+  TLS_DH_anon_WITH_AES_256_CBC_SHA256("TLS_DH_anon_WITH_AES_256_CBC_SHA256", 0x006d, 5246, 7, 21),
+  // TLS_RSA_WITH_CAMELLIA_256_CBC_SHA("TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", 0x0084, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA("TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA", 0x0085, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA("TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA", 0x0086, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA("TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA", 0x0087, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA("TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", 0x0088, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA("TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA", 0x0089, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_RC4_128_SHA("TLS_PSK_WITH_RC4_128_SHA", 0x008a, 4279, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_3DES_EDE_CBC_SHA("TLS_PSK_WITH_3DES_EDE_CBC_SHA", 0x008b, 4279, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_AES_128_CBC_SHA("TLS_PSK_WITH_AES_128_CBC_SHA", 0x008c, 4279, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_AES_256_CBC_SHA("TLS_PSK_WITH_AES_256_CBC_SHA", 0x008d, 4279, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_RC4_128_SHA("TLS_DHE_PSK_WITH_RC4_128_SHA", 0x008e, 4279, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA("TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA", 0x008f, 4279, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_AES_128_CBC_SHA("TLS_DHE_PSK_WITH_AES_128_CBC_SHA", 0x0090, 4279, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_AES_256_CBC_SHA("TLS_DHE_PSK_WITH_AES_256_CBC_SHA", 0x0091, 4279, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_PSK_WITH_RC4_128_SHA("TLS_RSA_PSK_WITH_RC4_128_SHA", 0x0092, 4279, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA("TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA", 0x0093, 4279, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_PSK_WITH_AES_128_CBC_SHA("TLS_RSA_PSK_WITH_AES_128_CBC_SHA", 0x0094, 4279, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_PSK_WITH_AES_256_CBC_SHA("TLS_RSA_PSK_WITH_AES_256_CBC_SHA", 0x0095, 4279, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_WITH_SEED_CBC_SHA("TLS_RSA_WITH_SEED_CBC_SHA", 0x0096, 4162, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_DSS_WITH_SEED_CBC_SHA("TLS_DH_DSS_WITH_SEED_CBC_SHA", 0x0097, 4162, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_RSA_WITH_SEED_CBC_SHA("TLS_DH_RSA_WITH_SEED_CBC_SHA", 0x0098, 4162, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_DSS_WITH_SEED_CBC_SHA("TLS_DHE_DSS_WITH_SEED_CBC_SHA", 0x0099, 4162, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_RSA_WITH_SEED_CBC_SHA("TLS_DHE_RSA_WITH_SEED_CBC_SHA", 0x009a, 4162, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_anon_WITH_SEED_CBC_SHA("TLS_DH_anon_WITH_SEED_CBC_SHA", 0x009b, 4162, MAX_VALUE, MAX_VALUE),
+  TLS_RSA_WITH_AES_128_GCM_SHA256("TLS_RSA_WITH_AES_128_GCM_SHA256", 0x009c, 5288, 8, 21),
+  TLS_RSA_WITH_AES_256_GCM_SHA384("TLS_RSA_WITH_AES_256_GCM_SHA384", 0x009d, 5288, 8, 21),
+  TLS_DHE_RSA_WITH_AES_128_GCM_SHA256("TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", 0x009e, 5288, 8, 21),
+  TLS_DHE_RSA_WITH_AES_256_GCM_SHA384("TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", 0x009f, 5288, 8, 21),
+  // TLS_DH_RSA_WITH_AES_128_GCM_SHA256("TLS_DH_RSA_WITH_AES_128_GCM_SHA256", 0x00a0, 5288, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_RSA_WITH_AES_256_GCM_SHA384("TLS_DH_RSA_WITH_AES_256_GCM_SHA384", 0x00a1, 5288, MAX_VALUE, MAX_VALUE),
+  TLS_DHE_DSS_WITH_AES_128_GCM_SHA256("TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", 0x00a2, 5288, 8, 21),
+  TLS_DHE_DSS_WITH_AES_256_GCM_SHA384("TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", 0x00a3, 5288, 8, 21),
+  // TLS_DH_DSS_WITH_AES_128_GCM_SHA256("TLS_DH_DSS_WITH_AES_128_GCM_SHA256", 0x00a4, 5288, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_DSS_WITH_AES_256_GCM_SHA384("TLS_DH_DSS_WITH_AES_256_GCM_SHA384", 0x00a5, 5288, MAX_VALUE, MAX_VALUE),
+  TLS_DH_anon_WITH_AES_128_GCM_SHA256("TLS_DH_anon_WITH_AES_128_GCM_SHA256", 0x00a6, 5288, 8, 21),
+  TLS_DH_anon_WITH_AES_256_GCM_SHA384("TLS_DH_anon_WITH_AES_256_GCM_SHA384", 0x00a7, 5288, 8, 21),
+  // TLS_PSK_WITH_AES_128_GCM_SHA256("TLS_PSK_WITH_AES_128_GCM_SHA256", 0x00a8, 5487, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_AES_256_GCM_SHA384("TLS_PSK_WITH_AES_256_GCM_SHA384", 0x00a9, 5487, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_AES_128_GCM_SHA256("TLS_DHE_PSK_WITH_AES_128_GCM_SHA256", 0x00aa, 5487, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_AES_256_GCM_SHA384("TLS_DHE_PSK_WITH_AES_256_GCM_SHA384", 0x00ab, 5487, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_PSK_WITH_AES_128_GCM_SHA256("TLS_RSA_PSK_WITH_AES_128_GCM_SHA256", 0x00ac, 5487, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_PSK_WITH_AES_256_GCM_SHA384("TLS_RSA_PSK_WITH_AES_256_GCM_SHA384", 0x00ad, 5487, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_AES_128_CBC_SHA256("TLS_PSK_WITH_AES_128_CBC_SHA256", 0x00ae, 5487, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_AES_256_CBC_SHA384("TLS_PSK_WITH_AES_256_CBC_SHA384", 0x00af, 5487, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_NULL_SHA256("TLS_PSK_WITH_NULL_SHA256", 0x00b0, 5487, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_NULL_SHA384("TLS_PSK_WITH_NULL_SHA384", 0x00b1, 5487, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_AES_128_CBC_SHA256("TLS_DHE_PSK_WITH_AES_128_CBC_SHA256", 0x00b2, 5487, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_AES_256_CBC_SHA384("TLS_DHE_PSK_WITH_AES_256_CBC_SHA384", 0x00b3, 5487, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_NULL_SHA256("TLS_DHE_PSK_WITH_NULL_SHA256", 0x00b4, 5487, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_NULL_SHA384("TLS_DHE_PSK_WITH_NULL_SHA384", 0x00b5, 5487, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_PSK_WITH_AES_128_CBC_SHA256("TLS_RSA_PSK_WITH_AES_128_CBC_SHA256", 0x00b6, 5487, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_PSK_WITH_AES_256_CBC_SHA384("TLS_RSA_PSK_WITH_AES_256_CBC_SHA384", 0x00b7, 5487, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_PSK_WITH_NULL_SHA256("TLS_RSA_PSK_WITH_NULL_SHA256", 0x00b8, 5487, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_PSK_WITH_NULL_SHA384("TLS_RSA_PSK_WITH_NULL_SHA384", 0x00b9, 5487, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256("TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0x00ba, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256("TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256", 0x00bb, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256("TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0x00bc, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256("TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256", 0x00bd, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256("TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0x00be, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256("TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256", 0x00bf, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256("TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0x00c0, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256("TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256", 0x00c1, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256("TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0x00c2, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256("TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256", 0x00c3, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256("TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0x00c4, 5932, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256("TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256", 0x00c5, 5932, MAX_VALUE, MAX_VALUE),
+  TLS_EMPTY_RENEGOTIATION_INFO_SCSV("TLS_EMPTY_RENEGOTIATION_INFO_SCSV", 0x00ff, 5746, 6, 14),
+  TLS_ECDH_ECDSA_WITH_NULL_SHA("TLS_ECDH_ECDSA_WITH_NULL_SHA", 0xc001, 4492, 7, 14),
+  TLS_ECDH_ECDSA_WITH_RC4_128_SHA("TLS_ECDH_ECDSA_WITH_RC4_128_SHA", 0xc002, 4492, 7, 14),
+  TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA("TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", 0xc003, 4492, 7, 14),
+  TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", 0xc004, 4492, 7, 14),
+  TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", 0xc005, 4492, 7, 14),
+  TLS_ECDHE_ECDSA_WITH_NULL_SHA("TLS_ECDHE_ECDSA_WITH_NULL_SHA", 0xc006, 4492, 7, 14),
+  TLS_ECDHE_ECDSA_WITH_RC4_128_SHA("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", 0xc007, 4492, 7, 14),
+  TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA("TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", 0xc008, 4492, 7, 14),
+  TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", 0xc009, 4492, 7, 14),
+  TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", 0xc00a, 4492, 7, 14),
+  TLS_ECDH_RSA_WITH_NULL_SHA("TLS_ECDH_RSA_WITH_NULL_SHA", 0xc00b, 4492, 7, 14),
+  TLS_ECDH_RSA_WITH_RC4_128_SHA("TLS_ECDH_RSA_WITH_RC4_128_SHA", 0xc00c, 4492, 7, 14),
+  TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA("TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", 0xc00d, 4492, 7, 14),
+  TLS_ECDH_RSA_WITH_AES_128_CBC_SHA("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", 0xc00e, 4492, 7, 14),
+  TLS_ECDH_RSA_WITH_AES_256_CBC_SHA("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", 0xc00f, 4492, 7, 14),
+  TLS_ECDHE_RSA_WITH_NULL_SHA("TLS_ECDHE_RSA_WITH_NULL_SHA", 0xc010, 4492, 7, 14),
+  TLS_ECDHE_RSA_WITH_RC4_128_SHA("TLS_ECDHE_RSA_WITH_RC4_128_SHA", 0xc011, 4492, 7, 14),
+  TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", 0xc012, 4492, 7, 14),
+  TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", 0xc013, 4492, 7, 14),
+  TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", 0xc014, 4492, 7, 14),
+  TLS_ECDH_anon_WITH_NULL_SHA("TLS_ECDH_anon_WITH_NULL_SHA", 0xc015, 4492, 7, 14),
+  TLS_ECDH_anon_WITH_RC4_128_SHA("TLS_ECDH_anon_WITH_RC4_128_SHA", 0xc016, 4492, 7, 14),
+  TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", 0xc017, 4492, 7, 14),
+  TLS_ECDH_anon_WITH_AES_128_CBC_SHA("TLS_ECDH_anon_WITH_AES_128_CBC_SHA", 0xc018, 4492, 7, 14),
+  TLS_ECDH_anon_WITH_AES_256_CBC_SHA("TLS_ECDH_anon_WITH_AES_256_CBC_SHA", 0xc019, 4492, 7, 14),
+  // TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA("TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA", 0xc01a, 5054, MAX_VALUE, MAX_VALUE),
+  // TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA("TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", 0xc01b, 5054, MAX_VALUE, MAX_VALUE),
+  // TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA("TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA", 0xc01c, 5054, MAX_VALUE, MAX_VALUE),
+  // TLS_SRP_SHA_WITH_AES_128_CBC_SHA("TLS_SRP_SHA_WITH_AES_128_CBC_SHA", 0xc01d, 5054, MAX_VALUE, MAX_VALUE),
+  // TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA("TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA", 0xc01e, 5054, MAX_VALUE, MAX_VALUE),
+  // TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA("TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA", 0xc01f, 5054, MAX_VALUE, MAX_VALUE),
+  // TLS_SRP_SHA_WITH_AES_256_CBC_SHA("TLS_SRP_SHA_WITH_AES_256_CBC_SHA", 0xc020, 5054, MAX_VALUE, MAX_VALUE),
+  // TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA("TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA", 0xc021, 5054, MAX_VALUE, MAX_VALUE),
+  // TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA("TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA", 0xc022, 5054, MAX_VALUE, MAX_VALUE),
+  TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", 0xc023, 5289, 7, 21),
+  TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", 0xc024, 5289, 7, 21),
+  TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", 0xc025, 5289, 7, 21),
+  TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", 0xc026, 5289, 7, 21),
+  TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", 0xc027, 5289, 7, 21),
+  TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", 0xc028, 5289, 7, 21),
+  TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", 0xc029, 5289, 7, 21),
+  TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", 0xc02a, 5289, 7, 21),
+  TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", 0xc02b, 5289, 8, 21),
+  TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", 0xc02c, 5289, 8, 21),
+  TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256("TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", 0xc02d, 5289, 8, 21),
+  TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384("TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", 0xc02e, 5289, 8, 21),
+  TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 0xc02f, 5289, 8, 21),
+  TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", 0xc030, 5289, 8, 21),
+  TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256("TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", 0xc031, 5289, 8, 21),
+  TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384("TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", 0xc032, 5289, 8, 21),
+  // TLS_ECDHE_PSK_WITH_RC4_128_SHA("TLS_ECDHE_PSK_WITH_RC4_128_SHA", 0xc033, 5489, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA("TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA", 0xc034, 5489, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", 0xc035, 5489, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", 0xc036, 5489, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", 0xc037, 5489, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", 0xc038, 5489, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_PSK_WITH_NULL_SHA("TLS_ECDHE_PSK_WITH_NULL_SHA", 0xc039, 5489, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_PSK_WITH_NULL_SHA256("TLS_ECDHE_PSK_WITH_NULL_SHA256", 0xc03a, 5489, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_PSK_WITH_NULL_SHA384("TLS_ECDHE_PSK_WITH_NULL_SHA384", 0xc03b, 5489, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_WITH_ARIA_128_CBC_SHA256("TLS_RSA_WITH_ARIA_128_CBC_SHA256", 0xc03c, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_WITH_ARIA_256_CBC_SHA384("TLS_RSA_WITH_ARIA_256_CBC_SHA384", 0xc03d, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256("TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256", 0xc03e, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384("TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384", 0xc03f, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256("TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256", 0xc040, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384("TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384", 0xc041, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256("TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256", 0xc042, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384("TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384", 0xc043, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256("TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256", 0xc044, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384("TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384", 0xc045, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_anon_WITH_ARIA_128_CBC_SHA256("TLS_DH_anon_WITH_ARIA_128_CBC_SHA256", 0xc046, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_anon_WITH_ARIA_256_CBC_SHA384("TLS_DH_anon_WITH_ARIA_256_CBC_SHA384", 0xc047, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256("TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256", 0xc048, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384("TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384", 0xc049, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256("TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256", 0xc04a, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384("TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384", 0xc04b, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256("TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256", 0xc04c, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384("TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384", 0xc04d, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256("TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256", 0xc04e, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384("TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384", 0xc04f, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_WITH_ARIA_128_GCM_SHA256("TLS_RSA_WITH_ARIA_128_GCM_SHA256", 0xc050, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_WITH_ARIA_256_GCM_SHA384("TLS_RSA_WITH_ARIA_256_GCM_SHA384", 0xc051, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256("TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256", 0xc052, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384("TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384", 0xc053, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256("TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256", 0xc054, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384("TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384", 0xc055, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256("TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256", 0xc056, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384("TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384", 0xc057, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256("TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256", 0xc058, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384("TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384", 0xc059, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_anon_WITH_ARIA_128_GCM_SHA256("TLS_DH_anon_WITH_ARIA_128_GCM_SHA256", 0xc05a, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_anon_WITH_ARIA_256_GCM_SHA384("TLS_DH_anon_WITH_ARIA_256_GCM_SHA384", 0xc05b, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256("TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256", 0xc05c, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384("TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384", 0xc05d, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256("TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256", 0xc05e, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384("TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384", 0xc05f, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256("TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256", 0xc060, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384("TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384", 0xc061, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256("TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256", 0xc062, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384("TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384", 0xc063, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_ARIA_128_CBC_SHA256("TLS_PSK_WITH_ARIA_128_CBC_SHA256", 0xc064, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_ARIA_256_CBC_SHA384("TLS_PSK_WITH_ARIA_256_CBC_SHA384", 0xc065, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256("TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256", 0xc066, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384("TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384", 0xc067, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256("TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256", 0xc068, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384("TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384", 0xc069, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_ARIA_128_GCM_SHA256("TLS_PSK_WITH_ARIA_128_GCM_SHA256", 0xc06a, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_ARIA_256_GCM_SHA384("TLS_PSK_WITH_ARIA_256_GCM_SHA384", 0xc06b, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256("TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256", 0xc06c, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384("TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384", 0xc06d, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256("TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256", 0xc06e, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384("TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384", 0xc06f, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256("TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256", 0xc070, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384("TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384", 0xc071, 6209, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256("TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", 0xc072, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384("TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", 0xc073, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256("TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", 0xc074, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384("TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", 0xc075, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256("TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0xc076, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384("TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384", 0xc077, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256("TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0xc078, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384("TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384", 0xc079, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256("TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc07a, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384("TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc07b, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256("TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc07c, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384("TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc07d, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256("TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc07e, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384("TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc07f, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256("TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256", 0xc080, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384("TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384", 0xc081, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256("TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256", 0xc082, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384("TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384", 0xc083, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256("TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256", 0xc084, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384("TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384", 0xc085, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256("TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc086, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384("TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc087, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256("TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc088, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384("TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc089, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256("TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc08a, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384("TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc08b, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256("TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256", 0xc08c, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384("TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384", 0xc08d, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256("TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256", 0xc08e, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384("TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384", 0xc08f, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256("TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256", 0xc090, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384("TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384", 0xc091, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256("TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256", 0xc092, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384("TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384", 0xc093, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256("TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256", 0xc094, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384("TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384", 0xc095, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256("TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", 0xc096, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384("TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", 0xc097, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256("TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256", 0xc098, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384("TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384", 0xc099, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256("TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", 0xc09a, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384("TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", 0xc09b, 6367, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_WITH_AES_128_CCM("TLS_RSA_WITH_AES_128_CCM", 0xc09c, 6655, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_WITH_AES_256_CCM("TLS_RSA_WITH_AES_256_CCM", 0xc09d, 6655, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_RSA_WITH_AES_128_CCM("TLS_DHE_RSA_WITH_AES_128_CCM", 0xc09e, 6655, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_RSA_WITH_AES_256_CCM("TLS_DHE_RSA_WITH_AES_256_CCM", 0xc09f, 6655, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_WITH_AES_128_CCM_8("TLS_RSA_WITH_AES_128_CCM_8", 0xc0a0, 6655, MAX_VALUE, MAX_VALUE),
+  // TLS_RSA_WITH_AES_256_CCM_8("TLS_RSA_WITH_AES_256_CCM_8", 0xc0a1, 6655, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_RSA_WITH_AES_128_CCM_8("TLS_DHE_RSA_WITH_AES_128_CCM_8", 0xc0a2, 6655, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_RSA_WITH_AES_256_CCM_8("TLS_DHE_RSA_WITH_AES_256_CCM_8", 0xc0a3, 6655, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_AES_128_CCM("TLS_PSK_WITH_AES_128_CCM", 0xc0a4, 6655, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_AES_256_CCM("TLS_PSK_WITH_AES_256_CCM", 0xc0a5, 6655, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_AES_128_CCM("TLS_DHE_PSK_WITH_AES_128_CCM", 0xc0a6, 6655, MAX_VALUE, MAX_VALUE),
+  // TLS_DHE_PSK_WITH_AES_256_CCM("TLS_DHE_PSK_WITH_AES_256_CCM", 0xc0a7, 6655, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_AES_128_CCM_8("TLS_PSK_WITH_AES_128_CCM_8", 0xc0a8, 6655, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_WITH_AES_256_CCM_8("TLS_PSK_WITH_AES_256_CCM_8", 0xc0a9, 6655, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_DHE_WITH_AES_128_CCM_8("TLS_PSK_DHE_WITH_AES_128_CCM_8", 0xc0aa, 6655, MAX_VALUE, MAX_VALUE),
+  // TLS_PSK_DHE_WITH_AES_256_CCM_8("TLS_PSK_DHE_WITH_AES_256_CCM_8", 0xc0ab, 6655, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_ECDSA_WITH_AES_128_CCM("TLS_ECDHE_ECDSA_WITH_AES_128_CCM", 0xc0ac, 7251, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_ECDSA_WITH_AES_256_CCM("TLS_ECDHE_ECDSA_WITH_AES_256_CCM", 0xc0ad, 7251, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8("TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8", 0xc0ae, 7251, MAX_VALUE, MAX_VALUE),
+  // TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8("TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8", 0xc0af, 7251, MAX_VALUE, MAX_VALUE),
+  ;
+
+  final String javaName;
+
+  /**
+   * @param javaName the name used by Java APIs for this cipher suite. Different than the IANA name
+   *     for older cipher suites because the prefix is {@code SSL_} instead of {@code TLS_}.
+   * @param value the integer identifier for this cipher suite. (Documentation only.)
+   * @param rfc the RFC describing this cipher suite. (Documentation only.)
+   * @param sinceJavaVersion the first major Java release supporting this cipher suite.
+   * @param sinceAndroidVersion the first Android SDK version supporting this cipher suite.
+   */
+  private CipherSuite(
+      String javaName, int value, int rfc, int sinceJavaVersion, int sinceAndroidVersion) {
+    this.javaName = javaName;
+  }
+
+  public static CipherSuite forJavaName(String javaName) {
+    return javaName.startsWith("SSL_")
+        ? valueOf("TLS_" + javaName.substring(4))
+        : valueOf(javaName);
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/Connection.java b/repackaged/okhttp/src/main/java/com/android/okhttp/Connection.java
new file mode 100644
index 0000000..89f2546
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/Connection.java
@@ -0,0 +1,86 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  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.android.okhttp;
+
+import java.net.Socket;
+
+/**
+ * The sockets and streams of an HTTP, HTTPS, or HTTPS+SPDY connection. May be used for multiple
+ * HTTP request/response exchanges. Connections may be direct to the origin server or via a proxy.
+ *
+ * <p>Typically instances of this class are created, connected and exercised automatically by the
+ * HTTP client. Applications may use this class to monitor HTTP connections as members of a
+ * {@linkplain ConnectionPool connection pool}.
+ *
+ * <p>Do not confuse this class with the misnamed {@code HttpURLConnection}, which isn't so much a
+ * connection as a single request/response exchange.
+ *
+ * <h3>Modern TLS</h3>
+ * There are tradeoffs when selecting which options to include when negotiating a secure connection
+ * to a remote host. Newer TLS options are quite useful:
+ * <ul>
+ *   <li>Server Name Indication (SNI) enables one IP address to negotiate secure connections for
+ *       multiple domain names.
+ *   <li>Application Layer Protocol Negotiation (ALPN) enables the HTTPS port (443) to be used for
+ *       different HTTP and SPDY protocols.
+ * </ul>
+ * Unfortunately, older HTTPS servers refuse to connect when such options are presented. Rather than
+ * avoiding these options entirely, this class allows a connection to be attempted with modern
+ * options and then retried without them should the attempt fail.
+ *
+ * <h3>Connection Reuse</h3>
+ * <p>Each connection can carry a varying number streams, depending on the underlying protocol being
+ * used. HTTP/1.x connections can carry either zero or one streams. HTTP/2 connections can carry any
+ * number of streams, dynamically configured with {@code SETTINGS_MAX_CONCURRENT_STREAMS}. A
+ * connection currently carrying zero streams is an idle stream. We keep it alive because reusing an
+ * existing connection is typically faster than establishing a new one.
+ *
+ * <p>When a single logical call requires multiple streams due to redirects or authorization
+ * challenges, we prefer to use the same physical connection for all streams in the sequence. There
+ * are potential performance and behavior consequences to this preference. To support this feature,
+ * this class separates <i>allocations</i> from <i>streams</i>. An allocation is created by a call,
+ * used for one or more streams, and then released. An allocated connection won't be stolen by
+ * other calls while a redirect or authorization challenge is being handled.
+ *
+ * <p>When the maximum concurrent streams limit is reduced, some allocations will be rescinded.
+ * Attempting to create new streams on these allocations will fail.
+ *
+ * <p>Note that an allocation may be released before its stream is completed. This is intended to
+ * make bookkeeping easier for the caller: releasing the allocation as soon as the terminal stream
+ * has been found. But only complete the stream once its data stream has been exhausted.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface Connection {
+  /** Returns the route used by this connection. */
+  Route getRoute();
+
+  /**
+   * Returns the socket that this connection uses, or null if the connection
+   * is not currently connected.
+   */
+  Socket getSocket();
+
+  Handshake getHandshake();
+
+  /**
+   * Returns the protocol negotiated by this connection, or {@link Protocol#HTTP_1_1} if no protocol
+   * has been negotiated. This method returns {@link Protocol#HTTP_1_1} even if the remote peer is
+   * using {@link Protocol#HTTP_1_0}.
+   */
+  Protocol getProtocol();
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/ConnectionPool.java b/repackaged/okhttp/src/main/java/com/android/okhttp/ConnectionPool.java
new file mode 100644
index 0000000..657751b
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/ConnectionPool.java
@@ -0,0 +1,329 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  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.android.okhttp;
+
+import com.android.okhttp.internal.Internal;
+import com.android.okhttp.internal.RouteDatabase;
+import com.android.okhttp.internal.Util;
+import com.android.okhttp.internal.http.StreamAllocation;
+import com.android.okhttp.internal.io.RealConnection;
+import java.lang.ref.Reference;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Manages reuse of HTTP and SPDY connections for reduced network latency. HTTP
+ * requests that share the same {@link com.android.okhttp.Address} may share a
+ * {@link Connection}. This class implements the policy of which connections to
+ * keep open for future use.
+ *
+ * <p>The {@link #getDefault() system-wide default} uses system properties for
+ * tuning parameters:
+ * <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 idle connections to
+ *         each to keep in the pool. Default is 5.
+ *     <li>{@code http.keepAliveDuration} Time in milliseconds to keep the
+ *         connection alive in the pool before closing it. Default is 5 minutes.
+ *         This property isn't used by {@code HttpURLConnection}.
+ * </ul>
+ *
+ * <p>The default instance <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.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class ConnectionPool {
+  private static final long DEFAULT_KEEP_ALIVE_DURATION_MS = 5 * 60 * 1000; // 5 min
+
+  private static final ConnectionPool systemDefault;
+
+  static {
+    String keepAlive = System.getProperty("http.keepAlive");
+    String keepAliveDuration = System.getProperty("http.keepAliveDuration");
+    String maxIdleConnections = System.getProperty("http.maxConnections");
+    long keepAliveDurationMs = keepAliveDuration != null
+        ? Long.parseLong(keepAliveDuration)
+        : DEFAULT_KEEP_ALIVE_DURATION_MS;
+    if (keepAlive != null && !Boolean.parseBoolean(keepAlive)) {
+      systemDefault = new ConnectionPool(0, keepAliveDurationMs);
+    } else if (maxIdleConnections != null) {
+      systemDefault = new ConnectionPool(Integer.parseInt(maxIdleConnections), keepAliveDurationMs);
+    } else {
+      systemDefault = new ConnectionPool(5, keepAliveDurationMs);
+    }
+  }
+
+  /**
+   * A background thread is used to cleanup expired connections. There will be, at most, a single
+   * thread running per connection pool. We use a thread pool executor because it can shrink to
+   * zero threads, permitting this pool to be garbage collected.
+   */
+  private final Executor executor = new ThreadPoolExecutor(
+      0 /* corePoolSize */, 1 /* maximumPoolSize */, 60L /* keepAliveTime */, TimeUnit.SECONDS,
+      new LinkedBlockingQueue<Runnable>(), Util.threadFactory("OkHttp ConnectionPool", true));
+
+  /** The maximum number of idle connections for each address. */
+  private final int maxIdleConnections;
+  private final long keepAliveDurationNs;
+  private Runnable cleanupRunnable = new Runnable() {
+    @Override public void run() {
+      while (true) {
+        long waitNanos = cleanup(System.nanoTime());
+        if (waitNanos == -1) return;
+        if (waitNanos > 0) {
+          long waitMillis = waitNanos / 1000000L;
+          waitNanos -= (waitMillis * 1000000L);
+          synchronized (ConnectionPool.this) {
+            try {
+              ConnectionPool.this.wait(waitMillis, (int) waitNanos);
+            } catch (InterruptedException ignored) {
+            }
+          }
+        }
+      }
+    }
+  };
+
+  private final Deque<RealConnection> connections = new ArrayDeque<>();
+  final RouteDatabase routeDatabase = new RouteDatabase();
+
+  public ConnectionPool(int maxIdleConnections, long keepAliveDurationMs) {
+    this(maxIdleConnections, keepAliveDurationMs, TimeUnit.MILLISECONDS);
+  }
+
+  public ConnectionPool(int maxIdleConnections, long keepAliveDuration, TimeUnit timeUnit) {
+    this.maxIdleConnections = maxIdleConnections;
+    this.keepAliveDurationNs = timeUnit.toNanos(keepAliveDuration);
+
+    // Put a floor on the keep alive duration, otherwise cleanup will spin loop.
+    if (keepAliveDuration <= 0) {
+      throw new IllegalArgumentException("keepAliveDuration <= 0: " + keepAliveDuration);
+    }
+  }
+
+  public static ConnectionPool getDefault() {
+    return systemDefault;
+  }
+
+  /** Returns the number of idle connections in the pool. */
+  public synchronized int getIdleConnectionCount() {
+    int total = 0;
+    for (RealConnection connection : connections) {
+      if (connection.allocations.isEmpty()) total++;
+    }
+    return total;
+  }
+
+  /**
+   * Returns total number of connections in the pool. Note that prior to OkHttp 2.7 this included
+   * only idle connections and SPDY connections. In OkHttp 2.7 this includes all connections, both
+   * active and inactive. Use {@link #getIdleConnectionCount()} to count connections not currently
+   * in use.
+   */
+  public synchronized int getConnectionCount() {
+    return connections.size();
+  }
+
+  /** @deprecated Use {@link #getMultiplexedConnectionCount()}. */
+  @Deprecated
+  public synchronized int getSpdyConnectionCount() {
+    return getMultiplexedConnectionCount();
+  }
+
+  /** Returns total number of multiplexed connections in the pool. */
+  public synchronized int getMultiplexedConnectionCount() {
+    int total = 0;
+    for (RealConnection connection : connections) {
+      if (connection.isMultiplexed()) total++;
+    }
+    return total;
+  }
+
+  /** Returns total number of http connections in the pool. */
+  public synchronized int getHttpConnectionCount() {
+    return connections.size() - getMultiplexedConnectionCount();
+  }
+
+  /** Returns a recycled connection to {@code address}, or null if no such connection exists. */
+  RealConnection get(Address address, StreamAllocation streamAllocation) {
+    assert (Thread.holdsLock(this));
+    for (RealConnection connection : connections) {
+      // TODO(jwilson): this is awkward. We're already holding a lock on 'this', and
+      //     connection.allocationLimit() may also lock the FramedConnection.
+      if (connection.allocations.size() < connection.allocationLimit()
+          && address.equals(connection.getRoute().address)
+          && !connection.noNewStreams) {
+        streamAllocation.acquire(connection);
+        return connection;
+      }
+    }
+    return null;
+  }
+
+  void put(RealConnection connection) {
+    assert (Thread.holdsLock(this));
+    if (connections.isEmpty()) {
+      executor.execute(cleanupRunnable);
+    }
+    connections.add(connection);
+  }
+
+  /**
+   * Notify this pool that {@code connection} has become idle. Returns true if the connection
+   * has been removed from the pool and should be closed.
+   */
+  boolean connectionBecameIdle(RealConnection connection) {
+    assert (Thread.holdsLock(this));
+    if (connection.noNewStreams || maxIdleConnections == 0) {
+      connections.remove(connection);
+      return true;
+    } else {
+      notifyAll(); // Awake the cleanup thread: we may have exceeded the idle connection limit.
+      return false;
+    }
+  }
+
+  /** Close and remove all idle connections in the pool. */
+  public void evictAll() {
+    List<RealConnection> evictedConnections = new ArrayList<>();
+    synchronized (this) {
+      for (Iterator<RealConnection> i = connections.iterator(); i.hasNext(); ) {
+        RealConnection connection = i.next();
+        if (connection.allocations.isEmpty()) {
+          connection.noNewStreams = true;
+          evictedConnections.add(connection);
+          i.remove();
+        }
+      }
+    }
+
+    for (RealConnection connection : evictedConnections) {
+      Util.closeQuietly(connection.getSocket());
+    }
+  }
+
+  /**
+   * Performs maintenance on this pool, evicting the connection that has been idle the longest if
+   * either it has exceeded the keep alive limit or the idle connections limit.
+   *
+   * <p>Returns the duration in nanos to sleep until the next scheduled call to this method.
+   * Returns -1 if no further cleanups are required.
+   */
+  long cleanup(long now) {
+    int inUseConnectionCount = 0;
+    int idleConnectionCount = 0;
+    RealConnection longestIdleConnection = null;
+    long longestIdleDurationNs = Long.MIN_VALUE;
+
+    // Find either a connection to evict, or the time that the next eviction is due.
+    synchronized (this) {
+      for (Iterator<RealConnection> i = connections.iterator(); i.hasNext(); ) {
+        RealConnection connection = i.next();
+
+        // If the connection is in use, keep searching.
+        if (pruneAndGetAllocationCount(connection, now) > 0) {
+          inUseConnectionCount++;
+          continue;
+        }
+
+        idleConnectionCount++;
+
+        // If the connection is ready to be evicted, we're done.
+        long idleDurationNs = now - connection.idleAtNanos;
+        if (idleDurationNs > longestIdleDurationNs) {
+          longestIdleDurationNs = idleDurationNs;
+          longestIdleConnection = connection;
+        }
+      }
+
+      if (longestIdleDurationNs >= this.keepAliveDurationNs
+          || idleConnectionCount > this.maxIdleConnections) {
+        // We've found a connection to evict. Remove it from the list, then close it below (outside
+        // of the synchronized block).
+        connections.remove(longestIdleConnection);
+
+      } else if (idleConnectionCount > 0) {
+        // A connection will be ready to evict soon.
+        return keepAliveDurationNs - longestIdleDurationNs;
+
+      } else if (inUseConnectionCount > 0) {
+        // All connections are in use. It'll be at least the keep alive duration 'til we run again.
+        return keepAliveDurationNs;
+
+      } else {
+        // No connections, idle or in use.
+        return -1;
+      }
+    }
+
+    Util.closeQuietly(longestIdleConnection.getSocket());
+
+    // Cleanup again immediately.
+    return 0;
+  }
+
+  /**
+   * Prunes any leaked allocations and then returns the number of remaining live allocations on
+   * {@code connection}. Allocations are leaked if the connection is tracking them but the
+   * application code has abandoned them. Leak detection is imprecise and relies on garbage
+   * collection.
+   */
+  private int pruneAndGetAllocationCount(RealConnection connection, long now) {
+    List<Reference<StreamAllocation>> references = connection.allocations;
+    for (int i = 0; i < references.size(); ) {
+      Reference<StreamAllocation> reference = references.get(i);
+
+      if (reference.get() != null) {
+        i++;
+        continue;
+      }
+
+      // Android-removed: Drop warning about a leak that may not be the app's fault.
+      // We can't tell here whether the app accessed the response body (InputStream) or
+      // only the header fields; at least in the latter case, the app has done nothing
+      // wrong so we shouldn't warn. http://b/64789755
+      // // We've discovered a leaked allocation. This is an application bug.
+      // Internal.logger.warning("A connection to " + connection.getRoute().getAddress().url()
+      //      + " was leaked. Did you forget to close a response body?");
+      references.remove(i);
+      connection.noNewStreams = true;
+
+      // If this was the last allocation, the connection is eligible for immediate eviction.
+      if (references.isEmpty()) {
+        connection.idleAtNanos = now - keepAliveDurationNs;
+        return 0;
+      }
+    }
+
+    return references.size();
+  }
+
+  void setCleanupRunnableForTest(Runnable cleanupRunnable) {
+    this.cleanupRunnable = cleanupRunnable;
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/ConnectionSpec.java b/repackaged/okhttp/src/main/java/com/android/okhttp/ConnectionSpec.java
new file mode 100644
index 0000000..516d596
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/ConnectionSpec.java
@@ -0,0 +1,336 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp;
+
+import com.android.okhttp.internal.Util;
+import java.util.Arrays;
+import java.util.List;
+import javax.net.ssl.SSLSocket;
+
+import static com.android.okhttp.internal.Util.concat;
+import static com.android.okhttp.internal.Util.contains;
+
+/**
+ * Specifies configuration for the socket connection that HTTP traffic travels through. For {@code
+ * https:} URLs, this includes the TLS version and cipher suites to use when negotiating a secure
+ * connection.
+ *
+ * <p>The TLS versions configured in a connection spec are only be used if they are also enabled in
+ * the SSL socket. For example, if an SSL socket does not have TLS 1.2 enabled, it will not be used
+ * even if it is present on the connection spec. The same policy also applies to cipher suites.
+ *
+ * <p>Use {@link Builder#allEnabledTlsVersions()} and {@link Builder#allEnabledCipherSuites} to
+ * defer all feature selection to the underlying SSL socket.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class ConnectionSpec {
+
+  // This is a subset of the cipher suites supported in Chrome 46, current as of 2015-11-05.
+  // All of these suites are available on Android 5.0; earlier releases support a subset of
+  // these suites. https://github.com/square/okhttp/issues/330
+  private static final CipherSuite[] APPROVED_CIPHER_SUITES = new CipherSuite[] {
+      CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+      CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+      CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+
+      // Note that the following cipher suites are all on HTTP/2's bad cipher suites list. We'll
+      // continue to include them until better suites are commonly available. For example, none
+      // of the better cipher suites listed above shipped with Android 4.4 or Java 7.
+      CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+      CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+      CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+      CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+      CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+      CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
+      CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,
+      CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
+      CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA,
+      CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+  };
+
+  /** A modern TLS connection with extensions like SNI and ALPN available. */
+  public static final ConnectionSpec MODERN_TLS = new Builder(true)
+      .cipherSuites(APPROVED_CIPHER_SUITES)
+      .tlsVersions(TlsVersion.TLS_1_2, TlsVersion.TLS_1_1, TlsVersion.TLS_1_0)
+      .supportsTlsExtensions(true)
+      .build();
+
+  /** A backwards-compatible fallback connection for interop with obsolete servers. */
+  public static final ConnectionSpec COMPATIBLE_TLS = new Builder(MODERN_TLS)
+      .tlsVersions(TlsVersion.TLS_1_0)
+      .supportsTlsExtensions(true)
+      .build();
+
+  /** Unencrypted, unauthenticated connections for {@code http:} URLs. */
+  public static final ConnectionSpec CLEARTEXT = new Builder(false).build();
+
+  private final boolean tls;
+  private final boolean supportsTlsExtensions;
+  private final String[] cipherSuites;
+  private final String[] tlsVersions;
+
+  private ConnectionSpec(Builder builder) {
+    this.tls = builder.tls;
+    this.cipherSuites = builder.cipherSuites;
+    this.tlsVersions = builder.tlsVersions;
+    this.supportsTlsExtensions = builder.supportsTlsExtensions;
+  }
+
+  public boolean isTls() {
+    return tls;
+  }
+
+  /**
+   * Returns the cipher suites to use for a connection. Returns {@code null} if all of the SSL
+   * socket's enabled cipher suites should be used.
+   */
+  public List<CipherSuite> cipherSuites() {
+    if (cipherSuites == null) return null;
+
+    CipherSuite[] result = new CipherSuite[cipherSuites.length];
+    for (int i = 0; i < cipherSuites.length; i++) {
+      result[i] = CipherSuite.forJavaName(cipherSuites[i]);
+    }
+    return Util.immutableList(result);
+  }
+
+  /**
+   * Returns the TLS versions to use when negotiating a connection. Returns {@code null} if all of
+   * the SSL socket's enabled TLS versions should be used.
+   */
+  public List<TlsVersion> tlsVersions() {
+    if (tlsVersions == null) return null;
+
+    TlsVersion[] result = new TlsVersion[tlsVersions.length];
+    for (int i = 0; i < tlsVersions.length; i++) {
+      result[i] = TlsVersion.forJavaName(tlsVersions[i]);
+    }
+    return Util.immutableList(result);
+  }
+
+  public boolean supportsTlsExtensions() {
+    return supportsTlsExtensions;
+  }
+
+  /** Applies this spec to {@code sslSocket}. */
+  void apply(SSLSocket sslSocket, boolean isFallback) {
+    ConnectionSpec specToApply = supportedSpec(sslSocket, isFallback);
+
+    if (specToApply.tlsVersions != null) {
+      sslSocket.setEnabledProtocols(specToApply.tlsVersions);
+    }
+    if (specToApply.cipherSuites != null) {
+      sslSocket.setEnabledCipherSuites(specToApply.cipherSuites);
+    }
+  }
+
+  /**
+   * Returns a copy of this that omits cipher suites and TLS versions not enabled by {@code
+   * sslSocket}.
+   */
+  private ConnectionSpec supportedSpec(SSLSocket sslSocket, boolean isFallback) {
+    String[] cipherSuitesIntersection = cipherSuites != null
+        ? Util.intersect(String.class, cipherSuites, sslSocket.getEnabledCipherSuites())
+        : sslSocket.getEnabledCipherSuites();
+    String[] tlsVersionsIntersection = tlsVersions != null
+        ? Util.intersect(String.class, tlsVersions, sslSocket.getEnabledProtocols())
+        : sslSocket.getEnabledProtocols();
+
+    // In accordance with https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00
+    // the SCSV cipher is added to signal that a protocol fallback has taken place.
+    if (isFallback && contains(sslSocket.getSupportedCipherSuites(), "TLS_FALLBACK_SCSV")) {
+      cipherSuitesIntersection = concat(cipherSuitesIntersection, "TLS_FALLBACK_SCSV");
+    }
+
+    return new Builder(this)
+        .cipherSuites(cipherSuitesIntersection)
+        .tlsVersions(tlsVersionsIntersection)
+        .build();
+  }
+
+  /**
+   * Returns {@code true} if the socket, as currently configured, supports this connection spec.
+   * In order for a socket to be compatible the enabled cipher suites and protocols must intersect.
+   *
+   * <p>For cipher suites, at least one of the {@link #cipherSuites() required cipher suites} must
+   * match the socket's enabled cipher suites. If there are no required cipher suites the socket
+   * must have at least one cipher suite enabled.
+   *
+   * <p>For protocols, at least one of the {@link #tlsVersions() required protocols} must match the
+   * socket's enabled protocols.
+   */
+  public boolean isCompatible(SSLSocket socket) {
+    if (!tls) {
+      return false;
+    }
+
+    if (tlsVersions != null
+        && !nonEmptyIntersection(tlsVersions, socket.getEnabledProtocols())) {
+      return false;
+    }
+
+    if (cipherSuites != null
+        && !nonEmptyIntersection(cipherSuites, socket.getEnabledCipherSuites())) {
+      return false;
+    }
+
+    return true;
+  }
+
+  /**
+   * An N*M intersection that terminates if any intersection is found. The sizes of both
+   * arguments are assumed to be so small, and the likelihood of an intersection so great, that it
+   * is not worth the CPU cost of sorting or the memory cost of hashing.
+   */
+  private static boolean nonEmptyIntersection(String[] a, String[] b) {
+    if (a == null || b == null || a.length == 0 || b.length == 0) {
+      return false;
+    }
+    for (String toFind : a) {
+      if (contains(b, toFind)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @Override public boolean equals(Object other) {
+    if (!(other instanceof ConnectionSpec)) return false;
+    if (other == this) return true;
+
+    ConnectionSpec that = (ConnectionSpec) other;
+    if (this.tls != that.tls) return false;
+
+    if (tls) {
+      if (!Arrays.equals(this.cipherSuites, that.cipherSuites)) return false;
+      if (!Arrays.equals(this.tlsVersions, that.tlsVersions)) return false;
+      if (this.supportsTlsExtensions != that.supportsTlsExtensions) return false;
+    }
+
+    return true;
+  }
+
+  @Override public int hashCode() {
+    int result = 17;
+    if (tls) {
+      result = 31 * result + Arrays.hashCode(cipherSuites);
+      result = 31 * result + Arrays.hashCode(tlsVersions);
+      result = 31 * result + (supportsTlsExtensions ? 0 : 1);
+    }
+    return result;
+  }
+
+  @Override public String toString() {
+    if (!tls) {
+      return "ConnectionSpec()";
+    }
+
+    String cipherSuitesString = cipherSuites != null ? cipherSuites().toString() : "[all enabled]";
+    String tlsVersionsString = tlsVersions != null ? tlsVersions().toString() : "[all enabled]";
+    return "ConnectionSpec("
+        + "cipherSuites=" + cipherSuitesString
+        + ", tlsVersions=" + tlsVersionsString
+        + ", supportsTlsExtensions=" + supportsTlsExtensions
+        + ")";
+  }
+
+  /**
+   * @hide This class is not part of the Android public SDK API
+   */
+  public static final class Builder {
+    private boolean tls;
+    private String[] cipherSuites;
+    private String[] tlsVersions;
+    private boolean supportsTlsExtensions;
+
+    Builder(boolean tls) {
+      this.tls = tls;
+    }
+
+    public Builder(ConnectionSpec connectionSpec) {
+      this.tls = connectionSpec.tls;
+      this.cipherSuites = connectionSpec.cipherSuites;
+      this.tlsVersions = connectionSpec.tlsVersions;
+      this.supportsTlsExtensions = connectionSpec.supportsTlsExtensions;
+    }
+
+    public Builder allEnabledCipherSuites() {
+      if (!tls) throw new IllegalStateException("no cipher suites for cleartext connections");
+      this.cipherSuites = null;
+      return this;
+    }
+
+    public Builder cipherSuites(CipherSuite... cipherSuites) {
+      if (!tls) throw new IllegalStateException("no cipher suites for cleartext connections");
+
+      String[] strings = new String[cipherSuites.length];
+      for (int i = 0; i < cipherSuites.length; i++) {
+        strings[i] = cipherSuites[i].javaName;
+      }
+      return cipherSuites(strings);
+    }
+
+    public Builder cipherSuites(String... cipherSuites) {
+      if (!tls) throw new IllegalStateException("no cipher suites for cleartext connections");
+
+      if (cipherSuites.length == 0) {
+        throw new IllegalArgumentException("At least one cipher suite is required");
+      }
+
+      this.cipherSuites = cipherSuites.clone(); // Defensive copy.
+      return this;
+    }
+
+    public Builder allEnabledTlsVersions() {
+      if (!tls) throw new IllegalStateException("no TLS versions for cleartext connections");
+      this.tlsVersions = null;
+      return this;
+    }
+
+    public Builder tlsVersions(TlsVersion... tlsVersions) {
+      if (!tls) throw new IllegalStateException("no TLS versions for cleartext connections");
+
+      String[] strings = new String[tlsVersions.length];
+      for (int i = 0; i < tlsVersions.length; i++) {
+        strings[i] = tlsVersions[i].javaName;
+      }
+
+      return tlsVersions(strings);
+    }
+
+    public Builder tlsVersions(String... tlsVersions) {
+      if (!tls) throw new IllegalStateException("no TLS versions for cleartext connections");
+
+      if (tlsVersions.length == 0) {
+        throw new IllegalArgumentException("At least one TLS version is required");
+      }
+
+      this.tlsVersions = tlsVersions.clone(); // Defensive copy.
+      return this;
+    }
+
+    public Builder supportsTlsExtensions(boolean supportsTlsExtensions) {
+      if (!tls) throw new IllegalStateException("no TLS extensions for cleartext connections");
+      this.supportsTlsExtensions = supportsTlsExtensions;
+      return this;
+    }
+
+    public ConnectionSpec build() {
+      return new ConnectionSpec(this);
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/Credentials.java b/repackaged/okhttp/src/main/java/com/android/okhttp/Credentials.java
new file mode 100644
index 0000000..dd758be
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/Credentials.java
@@ -0,0 +1,39 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp;
+
+import java.io.UnsupportedEncodingException;
+import com.android.okhttp.okio.ByteString;
+
+/** Factory for HTTP authorization credentials. 
+ * @hide This class is not part of the Android public SDK API*/
+public final class Credentials {
+  private Credentials() {
+  }
+
+  /** Returns an auth credential for the Basic scheme. */
+  public static String basic(String userName, String password) {
+    try {
+      String usernameAndPassword = userName + ":" + password;
+      byte[] bytes = usernameAndPassword.getBytes("ISO-8859-1");
+      String encoded = ByteString.of(bytes).base64();
+      return "Basic " + encoded;
+    } catch (UnsupportedEncodingException e) {
+      throw new AssertionError();
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/Dispatcher.java b/repackaged/okhttp/src/main/java/com/android/okhttp/Dispatcher.java
new file mode 100644
index 0000000..ef518c2
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/Dispatcher.java
@@ -0,0 +1,190 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.okhttp;
+
+import com.android.okhttp.Call.AsyncCall;
+import com.android.okhttp.internal.Util;
+import com.android.okhttp.internal.http.HttpEngine;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Policy on when async requests are executed.
+ *
+ * <p>Each dispatcher uses an {@link ExecutorService} to run calls internally. If you
+ * supply your own executor, it should be able to run {@linkplain #getMaxRequests the
+ * configured maximum} number of calls concurrently.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Dispatcher {
+  private int maxRequests = 64;
+  private int maxRequestsPerHost = 5;
+
+  /** Executes calls. Created lazily. */
+  private ExecutorService executorService;
+
+  /** Ready calls in the order they'll be run. */
+  private final Deque<AsyncCall> readyCalls = new ArrayDeque<>();
+
+  /** Running calls. Includes canceled calls that haven't finished yet. */
+  private final Deque<AsyncCall> runningCalls = new ArrayDeque<>();
+
+  /** In-flight synchronous calls. Includes canceled calls that haven't finished yet. */
+  private final Deque<Call> executedCalls = new ArrayDeque<>();
+
+  public Dispatcher(ExecutorService executorService) {
+    this.executorService = executorService;
+  }
+
+  public Dispatcher() {
+  }
+
+  public synchronized ExecutorService getExecutorService() {
+    if (executorService == null) {
+      executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
+          new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
+    }
+    return executorService;
+  }
+
+  /**
+   * Set the maximum number of requests to execute concurrently. Above this
+   * requests queue in memory, waiting for the running calls to complete.
+   *
+   * <p>If more than {@code maxRequests} requests are in flight when this is
+   * invoked, those requests will remain in flight.
+   */
+  public synchronized void setMaxRequests(int maxRequests) {
+    if (maxRequests < 1) {
+      throw new IllegalArgumentException("max < 1: " + maxRequests);
+    }
+    this.maxRequests = maxRequests;
+    promoteCalls();
+  }
+
+  public synchronized int getMaxRequests() {
+    return maxRequests;
+  }
+
+  /**
+   * Set the maximum number of requests for each host to execute concurrently.
+   * This limits requests by the URL's host name. Note that concurrent requests
+   * to a single IP address may still exceed this limit: multiple hostnames may
+   * share an IP address or be routed through the same HTTP proxy.
+   *
+   * <p>If more than {@code maxRequestsPerHost} requests are in flight when this
+   * is invoked, those requests will remain in flight.
+   */
+  public synchronized void setMaxRequestsPerHost(int maxRequestsPerHost) {
+    if (maxRequestsPerHost < 1) {
+      throw new IllegalArgumentException("max < 1: " + maxRequestsPerHost);
+    }
+    this.maxRequestsPerHost = maxRequestsPerHost;
+    promoteCalls();
+  }
+
+  public synchronized int getMaxRequestsPerHost() {
+    return maxRequestsPerHost;
+  }
+
+  synchronized void enqueue(AsyncCall call) {
+    if (runningCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
+      runningCalls.add(call);
+      getExecutorService().execute(call);
+    } else {
+      readyCalls.add(call);
+    }
+  }
+
+  /** Cancel all calls with the tag {@code tag}. */
+  public synchronized void cancel(Object tag) {
+    for (AsyncCall call : readyCalls) {
+      if (Util.equal(tag, call.tag())) {
+        call.cancel();
+      }
+    }
+
+    for (AsyncCall call : runningCalls) {
+      if (Util.equal(tag, call.tag())) {
+        call.get().canceled = true;
+        HttpEngine engine = call.get().engine;
+        if (engine != null) engine.cancel();
+      }
+    }
+
+    for (Call call : executedCalls) {
+      if (Util.equal(tag, call.tag())) {
+        call.cancel();
+      }
+    }
+  }
+
+  /** Used by {@code AsyncCall#run} to signal completion. */
+  synchronized void finished(AsyncCall call) {
+    if (!runningCalls.remove(call)) throw new AssertionError("AsyncCall wasn't running!");
+    promoteCalls();
+  }
+
+  private void promoteCalls() {
+    if (runningCalls.size() >= maxRequests) return; // Already running max capacity.
+    if (readyCalls.isEmpty()) return; // No ready calls to promote.
+
+    for (Iterator<AsyncCall> i = readyCalls.iterator(); i.hasNext(); ) {
+      AsyncCall call = i.next();
+
+      if (runningCallsForHost(call) < maxRequestsPerHost) {
+        i.remove();
+        runningCalls.add(call);
+        getExecutorService().execute(call);
+      }
+
+      if (runningCalls.size() >= maxRequests) return; // Reached max capacity.
+    }
+  }
+
+  /** Returns the number of running calls that share a host with {@code call}. */
+  private int runningCallsForHost(AsyncCall call) {
+    int result = 0;
+    for (AsyncCall c : runningCalls) {
+      if (c.host().equals(call.host())) result++;
+    }
+    return result;
+  }
+
+  /** Used by {@code Call#execute} to signal it is in-flight. */
+  synchronized void executed(Call call) {
+    executedCalls.add(call);
+  }
+
+  /** Used by {@code Call#execute} to signal completion. */
+  synchronized void finished(Call call) {
+    if (!executedCalls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
+  }
+
+  public synchronized int getRunningCallCount() {
+    return runningCalls.size();
+  }
+
+  public synchronized int getQueuedCallCount() {
+    return readyCalls.size();
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/Dns.java b/repackaged/okhttp/src/main/java/com/android/okhttp/Dns.java
new file mode 100644
index 0000000..20610bc
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/Dns.java
@@ -0,0 +1,52 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.okhttp;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A domain name service that resolves IP addresses for host names. Most applications will use the
+ * {@linkplain #SYSTEM system DNS service}, which is the default. Some applications may provide
+ * their own implementation to use a different DNS server, to prefer IPv6 addresses, to prefer IPv4
+ * addresses, or to force a specific known IP address.
+ *
+ * <p>Implementations of this interface must be safe for concurrent use.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface Dns {
+  /**
+   * A DNS that uses {@link InetAddress#getAllByName} to ask the underlying operating system to
+   * lookup IP addresses. Most custom {@link Dns} implementations should delegate to this instance.
+   */
+  Dns SYSTEM = new Dns() {
+    @Override public List<InetAddress> lookup(String hostname) throws UnknownHostException {
+      if (hostname == null) throw new UnknownHostException("hostname == null");
+      return Arrays.asList(InetAddress.getAllByName(hostname));
+    }
+  };
+
+  /**
+   * Returns the IP addresses of {@code hostname}, in the order they will be attempted by OkHttp.
+   * If a connection to an address fails, OkHttp will retry the connection with the next address
+   * until either a connection is made, the set of IP addresses is exhausted, or a limit is
+   * exceeded.
+   */
+  List<InetAddress> lookup(String hostname) throws UnknownHostException;
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/FormEncodingBuilder.java b/repackaged/okhttp/src/main/java/com/android/okhttp/FormEncodingBuilder.java
new file mode 100644
index 0000000..b95deed
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/FormEncodingBuilder.java
@@ -0,0 +1,61 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp;
+
+import com.android.okhttp.okio.Buffer;
+
+/**
+ * Fluent API to build <a href="http://www.w3.org/MarkUp/html-spec/html-spec_8.html#SEC8.2.1">HTML
+ * 2.0</a>-compliant form data.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class FormEncodingBuilder {
+  private static final MediaType CONTENT_TYPE =
+      MediaType.parse("application/x-www-form-urlencoded");
+
+  private final Buffer content = new Buffer();
+
+  /** Add new key-value pair. */
+  public FormEncodingBuilder add(String name, String value) {
+    if (content.size() > 0) {
+      content.writeByte('&');
+    }
+    HttpUrl.canonicalize(content, name, 0, name.length(),
+        HttpUrl.FORM_ENCODE_SET, false, false, true, true);
+    content.writeByte('=');
+    HttpUrl.canonicalize(content, value, 0, value.length(),
+        HttpUrl.FORM_ENCODE_SET, false, false, true, true);
+    return this;
+  }
+
+  /** Add new key-value pair. */
+  public FormEncodingBuilder addEncoded(String name, String value) {
+    if (content.size() > 0) {
+      content.writeByte('&');
+    }
+    HttpUrl.canonicalize(content, name, 0, name.length(),
+        HttpUrl.FORM_ENCODE_SET, true, false, true, true);
+    content.writeByte('=');
+    HttpUrl.canonicalize(content, value, 0, value.length(),
+        HttpUrl.FORM_ENCODE_SET, true, false, true, true);
+    return this;
+  }
+
+  public RequestBody build() {
+    return RequestBody.create(CONTENT_TYPE, content.snapshot());
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/Handshake.java b/repackaged/okhttp/src/main/java/com/android/okhttp/Handshake.java
new file mode 100644
index 0000000..4f39576
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/Handshake.java
@@ -0,0 +1,122 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.okhttp;
+
+import com.android.okhttp.internal.Util;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.List;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
+
+/**
+ * A record of a TLS handshake. For HTTPS clients, the client is <i>local</i>
+ * and the remote server is its <i>peer</i>.
+ *
+ * <p>This value object describes a completed handshake. Use {@link
+ * javax.net.ssl.SSLSocketFactory} to set policy for new handshakes.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Handshake {
+  private final String cipherSuite;
+  private final List<Certificate> peerCertificates;
+  private final List<Certificate> localCertificates;
+
+  private Handshake(
+      String cipherSuite, List<Certificate> peerCertificates, List<Certificate> localCertificates) {
+    this.cipherSuite = cipherSuite;
+    this.peerCertificates = peerCertificates;
+    this.localCertificates = localCertificates;
+  }
+
+  public static Handshake get(SSLSession session) {
+    String cipherSuite = session.getCipherSuite();
+    if (cipherSuite == null) throw new IllegalStateException("cipherSuite == null");
+
+    Certificate[] peerCertificates;
+    try {
+      peerCertificates = session.getPeerCertificates();
+    } catch (SSLPeerUnverifiedException ignored) {
+      peerCertificates = null;
+    }
+    List<Certificate> peerCertificatesList = peerCertificates != null
+        ? Util.immutableList(peerCertificates)
+        : Collections.<Certificate>emptyList();
+
+    Certificate[] localCertificates = session.getLocalCertificates();
+    List<Certificate> localCertificatesList = localCertificates != null
+        ? Util.immutableList(localCertificates)
+        : Collections.<Certificate>emptyList();
+
+    return new Handshake(cipherSuite, peerCertificatesList, localCertificatesList);
+  }
+
+  public static Handshake get(
+      String cipherSuite, List<Certificate> peerCertificates, List<Certificate> localCertificates) {
+    if (cipherSuite == null) throw new IllegalArgumentException("cipherSuite == null");
+    return new Handshake(cipherSuite, Util.immutableList(peerCertificates),
+        Util.immutableList(localCertificates));
+  }
+
+  /** Returns a cipher suite name like "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA". */
+  public String cipherSuite() {
+    return cipherSuite;
+  }
+
+  /** Returns a possibly-empty list of certificates that identify the remote peer. */
+  public List<Certificate> peerCertificates() {
+    return peerCertificates;
+  }
+
+  /** Returns the remote peer's principle, or null if that peer is anonymous. */
+  public Principal peerPrincipal() {
+    return !peerCertificates.isEmpty()
+        ? ((X509Certificate) peerCertificates.get(0)).getSubjectX500Principal()
+        : null;
+  }
+
+  /** Returns a possibly-empty list of certificates that identify this peer. */
+  public List<Certificate> localCertificates() {
+    return localCertificates;
+  }
+
+  /** Returns the local principle, or null if this peer is anonymous. */
+  public Principal localPrincipal() {
+    return !localCertificates.isEmpty()
+        ? ((X509Certificate) localCertificates.get(0)).getSubjectX500Principal()
+        : null;
+  }
+
+  @Override public boolean equals(Object other) {
+    if (!(other instanceof Handshake)) return false;
+    Handshake that = (Handshake) other;
+    return cipherSuite.equals(that.cipherSuite)
+        && peerCertificates.equals(that.peerCertificates)
+        && localCertificates.equals(that.localCertificates);
+  }
+
+  @Override public int hashCode() {
+    int result = 17;
+    result = 31 * result + cipherSuite.hashCode();
+    result = 31 * result + peerCertificates.hashCode();
+    result = 31 * result + localCertificates.hashCode();
+    return result;
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/Headers.java b/repackaged/okhttp/src/main/java/com/android/okhttp/Headers.java
new file mode 100644
index 0000000..ec740a1
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/Headers.java
@@ -0,0 +1,339 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  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.android.okhttp;
+
+import com.android.okhttp.internal.http.HttpDate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * The header fields of a single HTTP message. Values are uninterpreted strings;
+ * use {@code Request} and {@code Response} for interpreted headers. This class
+ * maintains the order of the header fields within the HTTP message.
+ *
+ * <p>This class tracks header values 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.
+ *
+ * <p>Instances of this class are immutable. Use {@link Builder} to create
+ * instances.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Headers {
+  private final String[] namesAndValues;
+
+  private Headers(Builder builder) {
+    this.namesAndValues = builder.namesAndValues.toArray(new String[builder.namesAndValues.size()]);
+  }
+
+  private Headers(String[] namesAndValues) {
+    this.namesAndValues = namesAndValues;
+  }
+
+  /** Returns the last value corresponding to the specified field, or null. */
+  public String get(String name) {
+    return get(namesAndValues, name);
+  }
+
+  /**
+   * Returns the last value corresponding to the specified field parsed as an
+   * HTTP date, or null if either the field is absent or cannot be parsed as a
+   * date.
+   */
+  public Date getDate(String name) {
+    String value = get(name);
+    return value != null ? HttpDate.parse(value) : null;
+  }
+
+  /** Returns the number of field values. */
+  public int size() {
+    return namesAndValues.length / 2;
+  }
+
+  /** Returns the field at {@code position} or null if that is out of range. */
+  public String name(int index) {
+    int nameIndex = index * 2;
+    if (nameIndex < 0 || nameIndex >= namesAndValues.length) {
+      return null;
+    }
+    return namesAndValues[nameIndex];
+  }
+
+  /** Returns the value at {@code index} or null if that is out of range. */
+  public String value(int index) {
+    int valueIndex = index * 2 + 1;
+    if (valueIndex < 0 || valueIndex >= namesAndValues.length) {
+      return null;
+    }
+    return namesAndValues[valueIndex];
+  }
+
+  /** Returns an immutable case-insensitive set of header names. */
+  public Set<String> names() {
+    TreeSet<String> result = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+    for (int i = 0, size = size(); i < size; i++) {
+      result.add(name(i));
+    }
+    return Collections.unmodifiableSet(result);
+  }
+
+  /** Returns an immutable list of the header values for {@code name}. */
+  public List<String> values(String name) {
+    List<String> result = null;
+    for (int i = 0, size = size(); i < size; i++) {
+      if (name.equalsIgnoreCase(name(i))) {
+        if (result == null) result = new ArrayList<>(2);
+        result.add(value(i));
+      }
+    }
+    return result != null
+        ? Collections.unmodifiableList(result)
+        : Collections.<String>emptyList();
+  }
+
+  public Builder newBuilder() {
+    Builder result = new Builder();
+    Collections.addAll(result.namesAndValues, namesAndValues);
+    return result;
+  }
+
+  @Override public String toString() {
+    StringBuilder result = new StringBuilder();
+    for (int i = 0, size = size(); i < size; i++) {
+      result.append(name(i)).append(": ").append(value(i)).append("\n");
+    }
+    return result.toString();
+  }
+
+  public Map<String, List<String>> toMultimap() {
+    Map<String, List<String>> result = new LinkedHashMap<String, List<String>>();
+    for (int i = 0, size = size(); i < size; i++) {
+      String name = name(i);
+      List<String> values = result.get(name);
+      if (values == null) {
+        values = new ArrayList<>(2);
+        result.put(name, values);
+      }
+      values.add(value(i));
+    }
+    return result;
+  }
+
+  private static String get(String[] namesAndValues, String name) {
+    for (int i = namesAndValues.length - 2; i >= 0; i -= 2) {
+      if (name.equalsIgnoreCase(namesAndValues[i])) {
+        return namesAndValues[i + 1];
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Returns headers for the alternating header names and values. There must be
+   * an even number of arguments, and they must alternate between header names
+   * and values.
+   */
+  public static Headers of(String... namesAndValues) {
+    if (namesAndValues == null || namesAndValues.length % 2 != 0) {
+      throw new IllegalArgumentException("Expected alternating header names and values");
+    }
+
+    // Make a defensive copy and clean it up.
+    namesAndValues = namesAndValues.clone();
+    for (int i = 0; i < namesAndValues.length; i++) {
+      if (namesAndValues[i] == null) throw new IllegalArgumentException("Headers cannot be null");
+      namesAndValues[i] = namesAndValues[i].trim();
+    }
+
+    // Check for malformed headers.
+    for (int i = 0; i < namesAndValues.length; i += 2) {
+      String name = namesAndValues[i];
+      String value = namesAndValues[i + 1];
+      if (name.length() == 0 || name.indexOf('\0') != -1 || value.indexOf('\0') != -1) {
+        throw new IllegalArgumentException("Unexpected header: " + name + ": " + value);
+      }
+    }
+
+    return new Headers(namesAndValues);
+  }
+
+  /**
+   * Returns headers for the header names and values in the {@link Map}.
+   */
+  public static Headers of(Map<String, String> headers) {
+    if (headers == null) {
+      throw new IllegalArgumentException("Expected map with header names and values");
+    }
+
+    // Make a defensive copy and clean it up.
+    String[] namesAndValues = new String[headers.size() * 2];
+    int i = 0;
+    for (Map.Entry<String, String> header : headers.entrySet()) {
+      if (header.getKey() == null || header.getValue() == null) {
+        throw new IllegalArgumentException("Headers cannot be null");
+      }
+      String name = header.getKey().trim();
+      String value = header.getValue().trim();
+      if (name.length() == 0 || name.indexOf('\0') != -1 || value.indexOf('\0') != -1) {
+        throw new IllegalArgumentException("Unexpected header: " + name + ": " + value);
+      }
+      namesAndValues[i] = name;
+      namesAndValues[i + 1] = value;
+      i += 2;
+    }
+
+    return new Headers(namesAndValues);
+  }
+
+  /**
+   * @hide This class is not part of the Android public SDK API
+   */
+  public static final class Builder {
+    private final List<String> namesAndValues = new ArrayList<>(20);
+
+    /**
+     * Add a header line without any validation. Only appropriate for headers from the remote peer
+     * or cache.
+     */
+    Builder addLenient(String line) {
+      int index = line.indexOf(":", 1);
+      if (index != -1) {
+        return addLenient(line.substring(0, index), line.substring(index + 1));
+      } else if (line.startsWith(":")) {
+        // Work around empty header names and header names that start with a
+        // colon (created by old broken SPDY versions of the response cache).
+        return addLenient("", line.substring(1)); // Empty header name.
+      } else {
+        return addLenient("", line); // No header name.
+      }
+    }
+
+    /** Add an header line containing a field name, a literal colon, and a value. */
+    public Builder add(String line) {
+      int index = line.indexOf(":");
+      if (index == -1) {
+        throw new IllegalArgumentException("Unexpected header: " + line);
+      }
+      return add(line.substring(0, index).trim(), line.substring(index + 1));
+    }
+
+    /** Add a field with the specified value. */
+    public Builder add(String name, String value) {
+      checkNameAndValue(name, value);
+      return addLenient(name, value);
+    }
+
+    /**
+     * Add a field with the specified value without any validation. Only
+     * appropriate for headers from the remote peer or cache.
+     */
+    Builder addLenient(String name, String value) {
+      namesAndValues.add(name);
+      namesAndValues.add(value.trim());
+      return this;
+    }
+
+    public Builder removeAll(String name) {
+      for (int i = 0; i < namesAndValues.size(); i += 2) {
+        if (name.equalsIgnoreCase(namesAndValues.get(i))) {
+          namesAndValues.remove(i); // name
+          namesAndValues.remove(i); // value
+          i -= 2;
+        }
+      }
+      return this;
+    }
+
+    /**
+     * 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 Builder set(String name, String value) {
+      checkNameAndValue(name, value);
+      removeAll(name);
+      addLenient(name, value);
+      return this;
+    }
+
+    private void checkNameAndValue(String name, String value) {
+      if (name == null) throw new IllegalArgumentException("name == null");
+      if (name.isEmpty()) throw new IllegalArgumentException("name is empty");
+      for (int i = 0, length = name.length(); i < length; i++) {
+        char c = name.charAt(i);
+        if (c <= '\u001f' || c >= '\u007f') {
+          throw new IllegalArgumentException(String.format(
+              "Unexpected char %#04x at %d in header name: %s", (int) c, i, name));
+        }
+      }
+      if (value == null) throw new IllegalArgumentException("value == null");
+
+      // Workaround for applications that set trailing "\r", "\n" or "\r\n" on header values.
+      // http://b/26422335, http://b/26889631 Android used to allow anything except '\0'.
+      int valueLen = value.length();
+      if (valueLen >= 2 && value.charAt(valueLen - 2) == '\r'
+          && value.charAt(valueLen - 1) == '\n') {
+        value = value.substring(0, value.length() - 2);
+      } else if (valueLen > 0
+              && (value.charAt(valueLen - 1) == '\n'
+                      || value.charAt(valueLen - 1) == '\r')) {
+        value = value.substring(0, valueLen - 1);
+      }
+      // End of workaround.
+
+      for (int i = 0, length = value.length(); i < length; i++) {
+        char c = value.charAt(i);
+        // ANDROID-BEGIN
+        // http://b/28867041 - keep things working for apps that rely on Android's (out of spec)
+        // UTF-8 header encoding behavior.
+        // if ((c <= '\u001f' && c != '\u0009' /* htab */) || c >= '\u007f') {
+        if ((c <= '\u001f' && c != '\u0009' /* htab */) || c == '\u007f') {
+        // ANDROID-END
+          throw new IllegalArgumentException(String.format(
+              "Unexpected char %#04x at %d in header value: %s", (int) c, i, value));
+        }
+      }
+    }
+
+    /** Equivalent to {@code build().get(name)}, but potentially faster. */
+    public String get(String name) {
+      for (int i = namesAndValues.size() - 2; i >= 0; i -= 2) {
+        if (name.equalsIgnoreCase(namesAndValues.get(i))) {
+          return namesAndValues.get(i + 1);
+        }
+      }
+      return null;
+    }
+
+    public Headers build() {
+      return new Headers(this);
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/HttpUrl.java b/repackaged/okhttp/src/main/java/com/android/okhttp/HttpUrl.java
new file mode 100644
index 0000000..24cb0d4
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/HttpUrl.java
@@ -0,0 +1,1646 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.okhttp;
+
+import java.net.IDN;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import com.android.okhttp.okio.Buffer;
+
+/**
+ * A uniform resource locator (URL) with a scheme of either {@code http} or {@code https}. Use this
+ * class to compose and decompose Internet addresses. For example, this code will compose and print
+ * a URL for Google search: <pre>   {@code
+ *
+ *   HttpUrl url = new HttpUrl.Builder()
+ *       .scheme("https")
+ *       .host("www.google.com")
+ *       .addPathSegment("search")
+ *       .addQueryParameter("q", "polar bears")
+ *       .build();
+ *   System.out.println(url);
+ * }</pre>
+ *
+ * which prints: <pre>   {@code
+ *
+ *     https://www.google.com/search?q=polar%20bears
+ * }</pre>
+ *
+ * As another example, this code prints the human-readable query parameters of a Twitter search:
+ * <pre>   {@code
+ *
+ *   HttpUrl url = HttpUrl.parse("https://twitter.com/search?q=cute%20%23puppies&f=images");
+ *   for (int i = 0, size = url.querySize(); i < size; i++) {
+ *     System.out.println(url.queryParameterName(i) + ": " + url.queryParameterValue(i));
+ *   }
+ * }</pre>
+ *
+ * which prints: <pre>   {@code
+ *
+ *   q: cute #puppies
+ *   f: images
+ * }</pre>
+ *
+ * In addition to composing URLs from their component parts and decomposing URLs into their
+ * component parts, this class implements relative URL resolution: what address you'd reach by
+ * clicking a relative link on a specified page. For example: <pre>   {@code
+ *
+ *   HttpUrl base = HttpUrl.parse("https://www.youtube.com/user/WatchTheDaily/videos");
+ *   HttpUrl link = base.resolve("../../watch?v=cbP2N1BQdYc");
+ *   System.out.println(link);
+ * }</pre>
+ *
+ * which prints: <pre>   {@code
+ *
+ *   https://www.youtube.com/watch?v=cbP2N1BQdYc
+ * }</pre>
+ *
+ * <h3>What's in a URL?</h3>
+ *
+ * A URL has several components.
+ *
+ * <h4>Scheme</h4>
+ * Sometimes referred to as <i>protocol</i>, A URL's scheme describes what mechanism should be used
+ * to retrieve the resource. Although URLs have many schemes ({@code mailto}, {@code file}, {@code
+ * ftp}), this class only supports {@code http} and {@code https}. Use {@link URI java.net.URI} for
+ * URLs with arbitrary schemes.
+ *
+ * <h4>Username and Password</h4>
+ * Username and password are either present, or the empty string {@code ""} if absent. This class
+ * offers no mechanism to differentiate empty from absent. Neither of these components are popular
+ * in practice. Typically HTTP applications use other mechanisms for user identification and
+ * authentication.
+ *
+ * <h4>Host</h4>
+ * The host identifies the webserver that serves the URL's resource. It is either a hostname like
+ * {@code square.com} or {@code localhost}, an IPv4 address like {@code 192.168.0.1}, or an IPv6
+ * address like {@code ::1}.
+ *
+ * <p>Usually a webserver is reachable with multiple identifiers: its IP addresses, registered
+ * domain names, and even {@code localhost} when connecting from the server itself. Each of a
+ * webserver's names is a distinct URL and they are not interchangeable. For example, even if
+ * {@code http://square.github.io/dagger} and {@code http://google.github.io/dagger} are served by
+ * the same IP address, the two URLs identify different resources.
+ *
+ * <h4>Port</h4>
+ * The port used to connect to the webserver. By default this is 80 for HTTP and 443 for HTTPS. This
+ * class never returns -1 for the port: if no port is explicitly specified in the URL then the
+ * scheme's default is used.
+ *
+ * <h4>Path</h4>
+ * The path identifies a specific resource on the host. Paths have a hierarchical structure like
+ * "/square/okhttp/issues/1486". Each path segment is prefixed with "/". This class offers methods
+ * to compose and decompose paths by segment. If a path's last segment is the empty string, then the
+ * path ends with "/". This class always builds non-empty paths: if the path is omitted it defaults
+ * to "/", which is a path whose only segment is the empty string.
+ *
+ * <h4>Query</h4>
+ * The query is optional: it can be null, empty, or non-empty. For many HTTP URLs the query string
+ * is subdivided into a collection of name-value parameters. This class offers methods to set the
+ * query as the single string, or as individual name-value parameters. With name-value parameters
+ * the values are optional and names may be repeated.
+ *
+ * <h4>Fragment</h4>
+ * The fragment is optional: it can be null, empty, or non-empty. Unlike host, port, path, and query
+ * the fragment is not sent to the webserver: it's private to the client.
+ *
+ * <h3>Encoding</h3>
+ * Each component must be encoded before it is embedded in the complete URL. As we saw above, the
+ * string {@code cute #puppies} is encoded as {@code cute%20%23puppies} when used as a query
+ * parameter value.
+ *
+ * <h4>Percent encoding</h4>
+ * Percent encoding replaces a character (like {@code \ud83c\udf69}) with its UTF-8 hex bytes (like
+ * {@code %F0%9F%8D%A9}). This approach works for whitespace characters, control characters,
+ * non-ASCII characters, and characters that already have another meaning in a particular context.
+ *
+ * <p>Percent encoding is used in every URL component except for the hostname. But the set of
+ * characters that need to be encoded is different for each component. For example, the path
+ * component must escape all of its {@code ?} characters, otherwise it could be interpreted as the
+ * start of the URL's query. But within the query and fragment components, the {@code ?} character
+ * doesn't delimit anything and doesn't need to be escaped. <pre>   {@code
+ *
+ *   HttpUrl url = HttpUrl.parse("http://who-let-the-dogs.out").newBuilder()
+ *       .addPathSegment("_Who?_")
+ *       .query("_Who?_")
+ *       .fragment("_Who?_")
+ *       .build();
+ *   System.out.println(url);
+ * }</pre>
+ *
+ * This prints: <pre>   {@code
+ *
+ *   http://who-let-the-dogs.out/_Who%3F_?_Who?_#_Who?_
+ * }</pre>
+ *
+ * When parsing URLs that lack percent encoding where it is required, this class will percent encode
+ * the offending characters.
+ *
+ * <h4>IDNA Mapping and Punycode encoding</h4>
+ * Hostnames have different requirements and use a different encoding scheme. It consists of IDNA
+ * mapping and Punycode encoding.
+ *
+ * <p>In order to avoid confusion and discourage phishing attacks,
+ * <a href="http://www.unicode.org/reports/tr46/#ToASCII">IDNA Mapping</a> transforms names to avoid
+ * confusing characters. This includes basic case folding: transforming shouting {@code SQUARE.COM}
+ * into cool and casual {@code square.com}. It also handles more exotic characters. For example, the
+ * Unicode trademark sign (™) could be confused for the letters "TM" in {@code http://ho™mail.com}.
+ * To mitigate this, the single character (™) maps to the string (tm). There is similar policy for
+ * all of the 1.1 million Unicode code points. Note that some code points such as "\ud83c\udf69" are
+ * not mapped and cannot be used in a hostname.
+ *
+ * <p><a href="http://ietf.org/rfc/rfc3492.txt">Punycode</a> converts a Unicode string to an ASCII
+ * string to make international domain names work everywhere. For example, "σ" encodes as
+ * "xn--4xa". The encoded string is not human readable, but can be used with classes like {@link
+ * InetAddress} to establish connections.
+ *
+ * <h3>Why another URL model?</h3>
+ * Java includes both {@link URL java.net.URL} and {@link URI java.net.URI}. We offer a new URL
+ * model to address problems that the others don't.
+ *
+ * <h4>Different URLs should be different</h4>
+ * Although they have different content, {@code java.net.URL} considers the following two URLs
+ * equal, and the {@link Object#equals equals()} method between them returns true:
+ * <ul>
+ *   <li>http://square.github.io/
+ *   <li>http://google.github.io/
+ * </ul>
+ * This is because those two hosts share the same IP address. This is an old, bad design decision
+ * that makes {@code java.net.URL} unusable for many things. It shouldn't be used as a {@link
+ * java.util.Map Map} key or in a {@link Set}. Doing so is both inefficient because equality may
+ * require a DNS lookup, and incorrect because unequal URLs may be equal because of how they are
+ * hosted.
+ *
+ * <h4>Equal URLs should be equal</h4>
+ * These two URLs are semantically identical, but {@code java.net.URI} disagrees:
+ * <ul>
+ *   <li>http://host:80/
+ *   <li>http://host
+ * </ul>
+ * Both the unnecessary port specification ({@code :80}) and the absent trailing slash ({@code /})
+ * cause URI to bucket the two URLs separately. This harms URI's usefulness in collections. Any
+ * application that stores information-per-URL will need to either canonicalize manually, or suffer
+ * unnecessary redundancy for such URLs.
+ *
+ * <p>Because they don't attempt canonical form, these classes are surprisingly difficult to use
+ * securely. Suppose you're building a webservice that checks that incoming paths are prefixed
+ * "/static/images/" before serving the corresponding assets from the filesystem. <pre>   {@code
+ *
+ *   String attack = "http://example.com/static/images/../../../../../etc/passwd";
+ *   System.out.println(new URL(attack).getPath());
+ *   System.out.println(new URI(attack).getPath());
+ *   System.out.println(HttpUrl.parse(attack).path());
+ * }</pre>
+ *
+ * By canonicalizing the input paths, they are complicit in directory traversal attacks. Code that
+ * checks only the path prefix may suffer!
+ * <pre>   {@code
+ *
+ *    /static/images/../../../../../etc/passwd
+ *    /static/images/../../../../../etc/passwd
+ *    /etc/passwd
+ * }</pre>
+ *
+ * <h4>If it works on the web, it should work in your application</h4>
+ * The {@code java.net.URI} class is strict around what URLs it accepts. It rejects URLs like
+ * "http://example.com/abc|def" because the '|' character is unsupported. This class is more
+ * forgiving: it will automatically percent-encode the '|', yielding "http://example.com/abc%7Cdef".
+ * This kind behavior is consistent with web browsers. {@code HttpUrl} prefers consistency with
+ * major web browsers over consistency with obsolete specifications.
+ *
+ * <h4>Paths and Queries should decompose</h4>
+ * Neither of the built-in URL models offer direct access to path segments or query parameters.
+ * Manually using {@code StringBuilder} to assemble these components is cumbersome: do '+'
+ * characters get silently replaced with spaces? If a query parameter contains a '&amp;', does that
+ * get escaped? By offering methods to read and write individual query parameters directly,
+ * application developers are saved from the hassles of encoding and decoding.
+ *
+ * <h4>Plus a modern API</h4>
+ * The URL (JDK1.0) and URI (Java 1.4) classes predate builders and instead use telescoping
+ * constructors. For example, there's no API to compose a URI with a custom port without also
+ * providing a query and fragment.
+ *
+ * <p>Instances of {@link HttpUrl} are well-formed and always have a scheme, host, and path. With
+ * {@code java.net.URL} it's possible to create an awkward URL like {@code http:/} with scheme and
+ * path but no hostname. Building APIs that consume such malformed values is difficult!
+ *
+ * <p>This class has a modern API. It avoids punitive checked exceptions: {@link #parse parse()}
+ * returns null if the input is an invalid URL. You can even be explicit about whether each
+ * component has been encoded already.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class HttpUrl {
+  private static final char[] HEX_DIGITS =
+      { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+  static final String USERNAME_ENCODE_SET = " \"':;<=>@[]^`{}|/\\?#";
+  static final String PASSWORD_ENCODE_SET = " \"':;<=>@[]^`{}|/\\?#";
+  static final String PATH_SEGMENT_ENCODE_SET = " \"<>^`{}|/\\?#";
+  static final String PATH_SEGMENT_ENCODE_SET_URI = "[]";
+  // ANDROID-CHANGED: http://b/30405333 - we do not encode single quote as %27 in query strings.
+  // static final String QUERY_ENCODE_SET = " \"'<>#";
+  // static final String QUERY_COMPONENT_ENCODE_SET = " \"'<>#&=";
+  static final String QUERY_ENCODE_SET = " \"<>#";
+  static final String QUERY_COMPONENT_ENCODE_SET = " \"<>#&=";
+  // ANDROID-CHANGED end.
+  static final String QUERY_COMPONENT_ENCODE_SET_URI = "\\^`{|}";
+  static final String FORM_ENCODE_SET = " \"':;<=>@[]^`{}|/\\?#&!$(),~";
+  static final String FRAGMENT_ENCODE_SET = "";
+  static final String FRAGMENT_ENCODE_SET_URI = " \"#<>\\^`{|}";
+
+  /** Either "http" or "https". */
+  private final String scheme;
+
+  /** Decoded username. */
+  private final String username;
+
+  /** Decoded password. */
+  private final String password;
+
+  /** Canonical hostname. */
+  private final String host;
+
+  /** Either 80, 443 or a user-specified port. In range [1..65535]. */
+  private final int port;
+
+  /**
+   * A list of canonical path segments. This list always contains at least one element, which may
+   * be the empty string. Each segment is formatted with a leading '/', so if path segments were
+   * ["a", "b", ""], then the encoded path would be "/a/b/".
+   */
+  private final List<String> pathSegments;
+
+  /**
+   * Alternating, decoded query names and values, or null for no query. Names may be empty or
+   * non-empty, but never null. Values are null if the name has no corresponding '=' separator, or
+   * empty, or non-empty.
+   */
+  private final List<String> queryNamesAndValues;
+
+  /** Decoded fragment. */
+  private final String fragment;
+
+  /** Canonical URL. */
+  private final String url;
+
+  private HttpUrl(Builder builder) {
+    this.scheme = builder.scheme;
+    this.username = percentDecode(builder.encodedUsername, false);
+    this.password = percentDecode(builder.encodedPassword, false);
+    this.host = builder.host;
+    this.port = builder.effectivePort();
+    this.pathSegments = percentDecode(builder.encodedPathSegments, false);
+    this.queryNamesAndValues = builder.encodedQueryNamesAndValues != null
+        ? percentDecode(builder.encodedQueryNamesAndValues, true)
+        : null;
+    this.fragment = builder.encodedFragment != null
+        ? percentDecode(builder.encodedFragment, false)
+        : null;
+    this.url = builder.toString();
+  }
+
+  /** Returns this URL as a {@link URL java.net.URL}. */
+  public URL url() {
+    try {
+      return new URL(url);
+    } catch (MalformedURLException e) {
+      throw new RuntimeException(e); // Unexpected!
+    }
+  }
+
+  /**
+   * Returns this URL as a {@link URI java.net.URI}. Because {@code URI} is more strict than this
+   * class, the returned URI may be semantically different from this URL:
+   * <ul>
+   *   <li>Characters forbidden by URI like {@code [} and {@code |} will be escaped.
+   *   <li>Invalid percent-encoded sequences like {@code %xx} will be encoded like {@code %25xx}.
+   *   <li>Whitespace and control characters in the fragment will be stripped.
+   * </ul>
+   *
+   * <p>These differences may have a significant consequence when the URI is interpretted by a
+   * webserver. For this reason the {@linkplain URI URI class} and this method should be avoided.
+   */
+  public URI uri() {
+    String uri = newBuilder().reencodeForUri().toString();
+    try {
+      return new URI(uri);
+    } catch (URISyntaxException e) {
+      // Unlikely edge case: the URI has a forbidden character in the fragment. Strip it & retry.
+      try {
+        String stripped = uri.replaceAll("[\\u0000-\\u001F\\u007F-\\u009F\\p{javaWhitespace}]", "");
+        return URI.create(stripped);
+      } catch (Exception e1) {
+        throw new RuntimeException(e); // Unexpected!
+      }
+    }
+  }
+
+  /** Returns either "http" or "https". */
+  public String scheme() {
+    return scheme;
+  }
+
+  public boolean isHttps() {
+    return scheme.equals("https");
+  }
+
+  /** Returns the username, or an empty string if none is set. */
+  public String encodedUsername() {
+    if (username.isEmpty()) return "";
+    int usernameStart = scheme.length() + 3; // "://".length() == 3.
+    int usernameEnd = delimiterOffset(url, usernameStart, url.length(), ":@");
+    return url.substring(usernameStart, usernameEnd);
+  }
+
+  public String username() {
+    return username;
+  }
+
+  /** Returns the password, or an empty string if none is set. */
+  public String encodedPassword() {
+    if (password.isEmpty()) return "";
+    int passwordStart = url.indexOf(':', scheme.length() + 3) + 1;
+    int passwordEnd = url.indexOf('@');
+    return url.substring(passwordStart, passwordEnd);
+  }
+
+  /** Returns the decoded password, or an empty string if none is present. */
+  public String password() {
+    return password;
+  }
+
+  /**
+   * Returns the host address suitable for use with {@link InetAddress#getAllByName(String)}. May
+   * be:
+   * <ul>
+   *   <li>A regular host name, like {@code android.com}.
+   *   <li>An IPv4 address, like {@code 127.0.0.1}.
+   *   <li>An IPv6 address, like {@code ::1}. Note that there are no square braces.
+   *   <li>An encoded IDN, like {@code xn--n3h.net}.
+   * </ul>
+   */
+  public String host() {
+    return host;
+  }
+
+  /**
+   * Returns the explicitly-specified port if one was provided, or the default port for this URL's
+   * scheme. For example, this returns 8443 for {@code https://square.com:8443/} and 443 for {@code
+   * https://square.com/}. The result is in {@code [1..65535]}.
+   */
+  public int port() {
+    return port;
+  }
+
+  /**
+   * Returns 80 if {@code scheme.equals("http")}, 443 if {@code scheme.equals("https")} and -1
+   * otherwise.
+   */
+  public static int defaultPort(String scheme) {
+    if (scheme.equals("http")) {
+      return 80;
+    } else if (scheme.equals("https")) {
+      return 443;
+    } else {
+      return -1;
+    }
+  }
+
+  public int pathSize() {
+    return pathSegments.size();
+  }
+
+  /**
+   * Returns the entire path of this URL, encoded for use in HTTP resource resolution. The
+   * returned path is always nonempty and is prefixed with {@code /}.
+   */
+  public String encodedPath() {
+    int pathStart = url.indexOf('/', scheme.length() + 3); // "://".length() == 3.
+    int pathEnd = delimiterOffset(url, pathStart, url.length(), "?#");
+    return url.substring(pathStart, pathEnd);
+  }
+
+  static void pathSegmentsToString(StringBuilder out, List<String> pathSegments) {
+    for (int i = 0, size = pathSegments.size(); i < size; i++) {
+      out.append('/');
+      out.append(pathSegments.get(i));
+    }
+  }
+
+  public List<String> encodedPathSegments() {
+    int pathStart = url.indexOf('/', scheme.length() + 3);
+    int pathEnd = delimiterOffset(url, pathStart, url.length(), "?#");
+    List<String> result = new ArrayList<>();
+    for (int i = pathStart; i < pathEnd; ) {
+      i++; // Skip the '/'.
+      int segmentEnd = delimiterOffset(url, i, pathEnd, "/");
+      result.add(url.substring(i, segmentEnd));
+      i = segmentEnd;
+    }
+    return result;
+  }
+
+  public List<String> pathSegments() {
+    return pathSegments;
+  }
+
+  /**
+   * Returns the query of this URL, encoded for use in HTTP resource resolution. The returned string
+   * may be null (for URLs with no query), empty (for URLs with an empty query) or non-empty (all
+   * other URLs).
+   */
+  public String encodedQuery() {
+    if (queryNamesAndValues == null) return null; // No query.
+    int queryStart = url.indexOf('?') + 1;
+    int queryEnd = delimiterOffset(url, queryStart + 1, url.length(), "#");
+    return url.substring(queryStart, queryEnd);
+  }
+
+  static void namesAndValuesToQueryString(StringBuilder out, List<String> namesAndValues) {
+    for (int i = 0, size = namesAndValues.size(); i < size; i += 2) {
+      String name = namesAndValues.get(i);
+      String value = namesAndValues.get(i + 1);
+      if (i > 0) out.append('&');
+      out.append(name);
+      if (value != null) {
+        out.append('=');
+        out.append(value);
+      }
+    }
+  }
+
+  /**
+   * Cuts {@code encodedQuery} up into alternating parameter names and values. This divides a
+   * query string like {@code subject=math&easy&problem=5-2=3} into the list {@code ["subject",
+   * "math", "easy", null, "problem", "5-2=3"]}. Note that values may be null and may contain
+   * '=' characters.
+   */
+  static List<String> queryStringToNamesAndValues(String encodedQuery) {
+    List<String> result = new ArrayList<>();
+    for (int pos = 0; pos <= encodedQuery.length(); ) {
+      int ampersandOffset = encodedQuery.indexOf('&', pos);
+      if (ampersandOffset == -1) ampersandOffset = encodedQuery.length();
+
+      int equalsOffset = encodedQuery.indexOf('=', pos);
+      if (equalsOffset == -1 || equalsOffset > ampersandOffset) {
+        result.add(encodedQuery.substring(pos, ampersandOffset));
+        result.add(null); // No value for this name.
+      } else {
+        result.add(encodedQuery.substring(pos, equalsOffset));
+        result.add(encodedQuery.substring(equalsOffset + 1, ampersandOffset));
+      }
+      pos = ampersandOffset + 1;
+    }
+    return result;
+  }
+
+  public String query() {
+    if (queryNamesAndValues == null) return null; // No query.
+    StringBuilder result = new StringBuilder();
+    namesAndValuesToQueryString(result, queryNamesAndValues);
+    return result.toString();
+  }
+
+  public int querySize() {
+    return queryNamesAndValues != null ? queryNamesAndValues.size() / 2 : 0;
+  }
+
+  /**
+   * Returns the first query parameter named {@code name} decoded using UTF-8, or null if there is
+   * no such query parameter.
+   */
+  public String queryParameter(String name) {
+    if (queryNamesAndValues == null) return null;
+    for (int i = 0, size = queryNamesAndValues.size(); i < size; i += 2) {
+      if (name.equals(queryNamesAndValues.get(i))) {
+        return queryNamesAndValues.get(i + 1);
+      }
+    }
+    return null;
+  }
+
+  public Set<String> queryParameterNames() {
+    if (queryNamesAndValues == null) return Collections.emptySet();
+    Set<String> result = new LinkedHashSet<>();
+    for (int i = 0, size = queryNamesAndValues.size(); i < size; i += 2) {
+      result.add(queryNamesAndValues.get(i));
+    }
+    return Collections.unmodifiableSet(result);
+  }
+
+  public List<String> queryParameterValues(String name) {
+    if (queryNamesAndValues == null) return Collections.emptyList();
+    List<String> result = new ArrayList<>();
+    for (int i = 0, size = queryNamesAndValues.size(); i < size; i += 2) {
+      if (name.equals(queryNamesAndValues.get(i))) {
+        result.add(queryNamesAndValues.get(i + 1));
+      }
+    }
+    return Collections.unmodifiableList(result);
+  }
+
+  public String queryParameterName(int index) {
+    return queryNamesAndValues.get(index * 2);
+  }
+
+  public String queryParameterValue(int index) {
+    return queryNamesAndValues.get(index * 2 + 1);
+  }
+
+  public String encodedFragment() {
+    if (fragment == null) return null;
+    int fragmentStart = url.indexOf('#') + 1;
+    return url.substring(fragmentStart);
+  }
+
+  public String fragment() {
+    return fragment;
+  }
+
+  /** Returns the URL that would be retrieved by following {@code link} from this URL. */
+  public HttpUrl resolve(String link) {
+    Builder builder = new Builder();
+    Builder.ParseResult result = builder.parse(this, link);
+    return result == Builder.ParseResult.SUCCESS ? builder.build() : null;
+  }
+
+  public Builder newBuilder() {
+    Builder result = new Builder();
+    result.scheme = scheme;
+    result.encodedUsername = encodedUsername();
+    result.encodedPassword = encodedPassword();
+    result.host = host;
+    // If we're set to a default port, unset it in case of a scheme change.
+    result.port = port != defaultPort(scheme) ? port : -1;
+    result.encodedPathSegments.clear();
+    result.encodedPathSegments.addAll(encodedPathSegments());
+    result.encodedQuery(encodedQuery());
+    result.encodedFragment = encodedFragment();
+    return result;
+  }
+
+  /**
+   * Returns a new {@code HttpUrl} representing {@code url} if it is a well-formed HTTP or HTTPS
+   * URL, or null if it isn't.
+   */
+  public static HttpUrl parse(String url) {
+    Builder builder = new Builder();
+    Builder.ParseResult result = builder.parse(null, url);
+    return result == Builder.ParseResult.SUCCESS ? builder.build() : null;
+  }
+
+  /**
+   * Returns an {@link HttpUrl} for {@code url} if its protocol is {@code http} or {@code https}, or
+   * null if it has any other protocol.
+   */
+  public static HttpUrl get(URL url) {
+    return parse(url.toString());
+  }
+
+  /**
+   * Returns a new {@code HttpUrl} representing {@code url} if it is a well-formed HTTP or HTTPS
+   * URL, or throws an exception if it isn't.
+   *
+   * @throws MalformedURLException if there was a non-host related URL issue
+   * @throws UnknownHostException if the host was invalid
+   */
+  static HttpUrl getChecked(String url) throws MalformedURLException, UnknownHostException {
+    Builder builder = new Builder();
+    Builder.ParseResult result = builder.parse(null, url);
+    switch (result) {
+      case SUCCESS:
+        return builder.build();
+      case INVALID_HOST:
+        throw new UnknownHostException("Invalid host: " + url);
+      case UNSUPPORTED_SCHEME:
+      case MISSING_SCHEME:
+      case INVALID_PORT:
+      default:
+        throw new MalformedURLException("Invalid URL: " + result + " for " + url);
+    }
+  }
+
+  public static HttpUrl get(URI uri) {
+    return parse(uri.toString());
+  }
+
+  @Override public boolean equals(Object o) {
+    return o instanceof HttpUrl && ((HttpUrl) o).url.equals(url);
+  }
+
+  @Override public int hashCode() {
+    return url.hashCode();
+  }
+
+  @Override public String toString() {
+    return url;
+  }
+
+  /**
+   * @hide This class is not part of the Android public SDK API
+   */
+  public static final class Builder {
+    String scheme;
+    String encodedUsername = "";
+    String encodedPassword = "";
+    String host;
+    int port = -1;
+    final List<String> encodedPathSegments = new ArrayList<>();
+    List<String> encodedQueryNamesAndValues;
+    String encodedFragment;
+
+    public Builder() {
+      encodedPathSegments.add(""); // The default path is '/' which needs a trailing space.
+    }
+
+    public Builder scheme(String scheme) {
+      if (scheme == null) {
+        throw new IllegalArgumentException("scheme == null");
+      } else if (scheme.equalsIgnoreCase("http")) {
+        this.scheme = "http";
+      } else if (scheme.equalsIgnoreCase("https")) {
+        this.scheme = "https";
+      } else {
+        throw new IllegalArgumentException("unexpected scheme: " + scheme);
+      }
+      return this;
+    }
+
+    public Builder username(String username) {
+      if (username == null) throw new IllegalArgumentException("username == null");
+      this.encodedUsername = canonicalize(username, USERNAME_ENCODE_SET, false, false, false, true);
+      return this;
+    }
+
+    public Builder encodedUsername(String encodedUsername) {
+      if (encodedUsername == null) throw new IllegalArgumentException("encodedUsername == null");
+      this.encodedUsername = canonicalize(
+          encodedUsername, USERNAME_ENCODE_SET, true, false, false, true);
+      return this;
+    }
+
+    public Builder password(String password) {
+      if (password == null) throw new IllegalArgumentException("password == null");
+      this.encodedPassword = canonicalize(password, PASSWORD_ENCODE_SET, false, false, false, true);
+      return this;
+    }
+
+    public Builder encodedPassword(String encodedPassword) {
+      if (encodedPassword == null) throw new IllegalArgumentException("encodedPassword == null");
+      this.encodedPassword = canonicalize(
+          encodedPassword, PASSWORD_ENCODE_SET, true, false, false, true);
+      return this;
+    }
+
+    /**
+     * @param host either a regular hostname, International Domain Name, IPv4 address, or IPv6
+     *     address.
+     */
+    public Builder host(String host) {
+      if (host == null) throw new IllegalArgumentException("host == null");
+      String encoded = canonicalizeHost(host, 0, host.length());
+      if (encoded == null) throw new IllegalArgumentException("unexpected host: " + host);
+      this.host = encoded;
+      return this;
+    }
+
+    public Builder port(int port) {
+      if (port <= 0 || port > 65535) throw new IllegalArgumentException("unexpected port: " + port);
+      this.port = port;
+      return this;
+    }
+
+    int effectivePort() {
+      return port != -1 ? port : defaultPort(scheme);
+    }
+
+    public Builder addPathSegment(String pathSegment) {
+      if (pathSegment == null) throw new IllegalArgumentException("pathSegment == null");
+      push(pathSegment, 0, pathSegment.length(), false, false);
+      return this;
+    }
+
+    public Builder addEncodedPathSegment(String encodedPathSegment) {
+      if (encodedPathSegment == null) {
+        throw new IllegalArgumentException("encodedPathSegment == null");
+      }
+      push(encodedPathSegment, 0, encodedPathSegment.length(), false, true);
+      return this;
+    }
+
+    public Builder setPathSegment(int index, String pathSegment) {
+      if (pathSegment == null) throw new IllegalArgumentException("pathSegment == null");
+      String canonicalPathSegment = canonicalize(
+          pathSegment, 0, pathSegment.length(), PATH_SEGMENT_ENCODE_SET, false, false, false, true);
+      if (isDot(canonicalPathSegment) || isDotDot(canonicalPathSegment)) {
+        throw new IllegalArgumentException("unexpected path segment: " + pathSegment);
+      }
+      encodedPathSegments.set(index, canonicalPathSegment);
+      return this;
+    }
+
+    public Builder setEncodedPathSegment(int index, String encodedPathSegment) {
+      if (encodedPathSegment == null) {
+        throw new IllegalArgumentException("encodedPathSegment == null");
+      }
+      String canonicalPathSegment = canonicalize(encodedPathSegment,
+          0, encodedPathSegment.length(), PATH_SEGMENT_ENCODE_SET, true, false, false, true);
+      encodedPathSegments.set(index, canonicalPathSegment);
+      if (isDot(canonicalPathSegment) || isDotDot(canonicalPathSegment)) {
+        throw new IllegalArgumentException("unexpected path segment: " + encodedPathSegment);
+      }
+      return this;
+    }
+
+    public Builder removePathSegment(int index) {
+      encodedPathSegments.remove(index);
+      if (encodedPathSegments.isEmpty()) {
+        encodedPathSegments.add(""); // Always leave at least one '/'.
+      }
+      return this;
+    }
+
+    public Builder encodedPath(String encodedPath) {
+      if (encodedPath == null) throw new IllegalArgumentException("encodedPath == null");
+      if (!encodedPath.startsWith("/")) {
+        throw new IllegalArgumentException("unexpected encodedPath: " + encodedPath);
+      }
+      resolvePath(encodedPath, 0, encodedPath.length());
+      return this;
+    }
+
+    public Builder query(String query) {
+      this.encodedQueryNamesAndValues = query != null
+          ? queryStringToNamesAndValues(canonicalize(
+              query, QUERY_ENCODE_SET, false, false, true, true))
+          : null;
+      return this;
+    }
+
+    public Builder encodedQuery(String encodedQuery) {
+      this.encodedQueryNamesAndValues = encodedQuery != null
+          ? queryStringToNamesAndValues(
+              canonicalize(encodedQuery, QUERY_ENCODE_SET, true, false, true, true))
+          : null;
+      return this;
+    }
+
+    /** Encodes the query parameter using UTF-8 and adds it to this URL's query string. */
+    public Builder addQueryParameter(String name, String value) {
+      if (name == null) throw new IllegalArgumentException("name == null");
+      if (encodedQueryNamesAndValues == null) encodedQueryNamesAndValues = new ArrayList<>();
+      encodedQueryNamesAndValues.add(
+          canonicalize(name, QUERY_COMPONENT_ENCODE_SET, false, false, true, true));
+      encodedQueryNamesAndValues.add(value != null
+          ? canonicalize(value, QUERY_COMPONENT_ENCODE_SET, false, false, true, true)
+          : null);
+      return this;
+    }
+
+    /** Adds the pre-encoded query parameter to this URL's query string. */
+    public Builder addEncodedQueryParameter(String encodedName, String encodedValue) {
+      if (encodedName == null) throw new IllegalArgumentException("encodedName == null");
+      if (encodedQueryNamesAndValues == null) encodedQueryNamesAndValues = new ArrayList<>();
+      encodedQueryNamesAndValues.add(
+          canonicalize(encodedName, QUERY_COMPONENT_ENCODE_SET, true, false, true, true));
+      encodedQueryNamesAndValues.add(encodedValue != null
+          ? canonicalize(encodedValue, QUERY_COMPONENT_ENCODE_SET, true, false, true, true)
+          : null);
+      return this;
+    }
+
+    public Builder setQueryParameter(String name, String value) {
+      removeAllQueryParameters(name);
+      addQueryParameter(name, value);
+      return this;
+    }
+
+    public Builder setEncodedQueryParameter(String encodedName, String encodedValue) {
+      removeAllEncodedQueryParameters(encodedName);
+      addEncodedQueryParameter(encodedName, encodedValue);
+      return this;
+    }
+
+    public Builder removeAllQueryParameters(String name) {
+      if (name == null) throw new IllegalArgumentException("name == null");
+      if (encodedQueryNamesAndValues == null) return this;
+      String nameToRemove = canonicalize(
+          name, QUERY_COMPONENT_ENCODE_SET, false, false, true, true);
+      removeAllCanonicalQueryParameters(nameToRemove);
+      return this;
+    }
+
+    public Builder removeAllEncodedQueryParameters(String encodedName) {
+      if (encodedName == null) throw new IllegalArgumentException("encodedName == null");
+      if (encodedQueryNamesAndValues == null) return this;
+      removeAllCanonicalQueryParameters(
+          canonicalize(encodedName, QUERY_COMPONENT_ENCODE_SET, true, false, true, true));
+      return this;
+    }
+
+    private void removeAllCanonicalQueryParameters(String canonicalName) {
+      for (int i = encodedQueryNamesAndValues.size() - 2; i >= 0; i -= 2) {
+        if (canonicalName.equals(encodedQueryNamesAndValues.get(i))) {
+          encodedQueryNamesAndValues.remove(i + 1);
+          encodedQueryNamesAndValues.remove(i);
+          if (encodedQueryNamesAndValues.isEmpty()) {
+            encodedQueryNamesAndValues = null;
+            return;
+          }
+        }
+      }
+    }
+
+    public Builder fragment(String fragment) {
+      this.encodedFragment = fragment != null
+          ? canonicalize(fragment, FRAGMENT_ENCODE_SET, false, false, false, false)
+          : null;
+      return this;
+    }
+
+    public Builder encodedFragment(String encodedFragment) {
+      this.encodedFragment = encodedFragment != null
+          ? canonicalize(encodedFragment, FRAGMENT_ENCODE_SET, true, false, false, false)
+          : null;
+      return this;
+    }
+
+    /**
+     * Re-encodes the components of this URL so that it satisfies (obsolete) RFC 2396, which is
+     * particularly strict for certain components.
+     */
+    Builder reencodeForUri() {
+      for (int i = 0, size = encodedPathSegments.size(); i < size; i++) {
+        String pathSegment = encodedPathSegments.get(i);
+        encodedPathSegments.set(i,
+            canonicalize(pathSegment, PATH_SEGMENT_ENCODE_SET_URI, true, true, false, true));
+      }
+      if (encodedQueryNamesAndValues != null) {
+        for (int i = 0, size = encodedQueryNamesAndValues.size(); i < size; i++) {
+          String component = encodedQueryNamesAndValues.get(i);
+          if (component != null) {
+            encodedQueryNamesAndValues.set(i,
+                canonicalize(component, QUERY_COMPONENT_ENCODE_SET_URI, true, true, true, true));
+          }
+        }
+      }
+      if (encodedFragment != null) {
+        encodedFragment = canonicalize(
+            encodedFragment, FRAGMENT_ENCODE_SET_URI, true, true, false, false);
+      }
+      return this;
+    }
+
+    public HttpUrl build() {
+      if (scheme == null) throw new IllegalStateException("scheme == null");
+      if (host == null) throw new IllegalStateException("host == null");
+      return new HttpUrl(this);
+    }
+
+    @Override public String toString() {
+      StringBuilder result = new StringBuilder();
+      result.append(scheme);
+      result.append("://");
+
+      if (!encodedUsername.isEmpty() || !encodedPassword.isEmpty()) {
+        result.append(encodedUsername);
+        if (!encodedPassword.isEmpty()) {
+          result.append(':');
+          result.append(encodedPassword);
+        }
+        result.append('@');
+      }
+
+      if (host.indexOf(':') != -1) {
+        // Host is an IPv6 address.
+        result.append('[');
+        result.append(host);
+        result.append(']');
+      } else {
+        result.append(host);
+      }
+
+      int effectivePort = effectivePort();
+      if (effectivePort != defaultPort(scheme)) {
+        result.append(':');
+        result.append(effectivePort);
+      }
+
+      pathSegmentsToString(result, encodedPathSegments);
+
+      if (encodedQueryNamesAndValues != null) {
+        result.append('?');
+        namesAndValuesToQueryString(result, encodedQueryNamesAndValues);
+      }
+
+      if (encodedFragment != null) {
+        result.append('#');
+        result.append(encodedFragment);
+      }
+
+      return result.toString();
+    }
+
+    enum ParseResult {
+      SUCCESS,
+      MISSING_SCHEME,
+      UNSUPPORTED_SCHEME,
+      INVALID_PORT,
+      INVALID_HOST,
+    }
+
+    ParseResult parse(HttpUrl base, String input) {
+      int pos = skipLeadingAsciiWhitespace(input, 0, input.length());
+      int limit = skipTrailingAsciiWhitespace(input, pos, input.length());
+
+      // Scheme.
+      int schemeDelimiterOffset = schemeDelimiterOffset(input, pos, limit);
+      if (schemeDelimiterOffset != -1) {
+        if (input.regionMatches(true, pos, "https:", 0, 6)) {
+          this.scheme = "https";
+          pos += "https:".length();
+        } else if (input.regionMatches(true, pos, "http:", 0, 5)) {
+          this.scheme = "http";
+          pos += "http:".length();
+        } else {
+          return ParseResult.UNSUPPORTED_SCHEME; // Not an HTTP scheme.
+        }
+      } else if (base != null) {
+        this.scheme = base.scheme;
+      } else {
+        return ParseResult.MISSING_SCHEME; // No scheme.
+      }
+
+      // Authority.
+      boolean hasUsername = false;
+      boolean hasPassword = false;
+      int slashCount = slashCount(input, pos, limit);
+      if (slashCount >= 2 || base == null || !base.scheme.equals(this.scheme)) {
+        // Read an authority if either:
+        //  * The input starts with 2 or more slashes. These follow the scheme if it exists.
+        //  * The input scheme exists and is different from the base URL's scheme.
+        //
+        // The structure of an authority is:
+        //   username:password@host:port
+        //
+        // Username, password and port are optional.
+        //   [username[:password]@]host[:port]
+        pos += slashCount;
+        authority:
+        while (true) {
+          int componentDelimiterOffset = delimiterOffset(input, pos, limit, "@/\\?#");
+          int c = componentDelimiterOffset != limit
+              ? input.charAt(componentDelimiterOffset)
+              : -1;
+          switch (c) {
+            case '@':
+              // User info precedes.
+              if (!hasPassword) {
+                int passwordColonOffset = delimiterOffset(
+                    input, pos, componentDelimiterOffset, ":");
+                String canonicalUsername = canonicalize(
+                    input, pos, passwordColonOffset, USERNAME_ENCODE_SET, true, false, false, true);
+                this.encodedUsername = hasUsername
+                    ? this.encodedUsername + "%40" + canonicalUsername
+                    : canonicalUsername;
+                if (passwordColonOffset != componentDelimiterOffset) {
+                  hasPassword = true;
+                  this.encodedPassword = canonicalize(input, passwordColonOffset + 1,
+                      componentDelimiterOffset, PASSWORD_ENCODE_SET, true, false, false, true);
+                }
+                hasUsername = true;
+              } else {
+                this.encodedPassword = this.encodedPassword + "%40" + canonicalize(input, pos,
+                    componentDelimiterOffset, PASSWORD_ENCODE_SET, true, false, false, true);
+              }
+              pos = componentDelimiterOffset + 1;
+              break;
+
+            case -1:
+            case '/':
+            case '\\':
+            case '?':
+            case '#':
+              // Host info precedes.
+              int portColonOffset = portColonOffset(input, pos, componentDelimiterOffset);
+              if (portColonOffset + 1 < componentDelimiterOffset) {
+                this.host = canonicalizeHost(input, pos, portColonOffset);
+                this.port = parsePort(input, portColonOffset + 1, componentDelimiterOffset);
+                if (this.port == -1) return ParseResult.INVALID_PORT; // Invalid port.
+              } else {
+                this.host = canonicalizeHost(input, pos, portColonOffset);
+                this.port = defaultPort(this.scheme);
+              }
+              if (this.host == null) return ParseResult.INVALID_HOST; // Invalid host.
+              pos = componentDelimiterOffset;
+              break authority;
+          }
+        }
+      } else {
+        // This is a relative link. Copy over all authority components. Also maybe the path & query.
+        this.encodedUsername = base.encodedUsername();
+        this.encodedPassword = base.encodedPassword();
+        this.host = base.host;
+        this.port = base.port;
+        this.encodedPathSegments.clear();
+        this.encodedPathSegments.addAll(base.encodedPathSegments());
+        if (pos == limit || input.charAt(pos) == '#') {
+          encodedQuery(base.encodedQuery());
+        }
+      }
+
+      // Resolve the relative path.
+      int pathDelimiterOffset = delimiterOffset(input, pos, limit, "?#");
+      resolvePath(input, pos, pathDelimiterOffset);
+      pos = pathDelimiterOffset;
+
+      // Query.
+      if (pos < limit && input.charAt(pos) == '?') {
+        int queryDelimiterOffset = delimiterOffset(input, pos, limit, "#");
+        this.encodedQueryNamesAndValues = queryStringToNamesAndValues(canonicalize(
+            input, pos + 1, queryDelimiterOffset, QUERY_ENCODE_SET, true, false, true, true));
+        pos = queryDelimiterOffset;
+      }
+
+      // Fragment.
+      if (pos < limit && input.charAt(pos) == '#') {
+        this.encodedFragment = canonicalize(
+            input, pos + 1, limit, FRAGMENT_ENCODE_SET, true, false, false, false);
+      }
+
+      return ParseResult.SUCCESS;
+    }
+
+    private void resolvePath(String input, int pos, int limit) {
+      // Read a delimiter.
+      if (pos == limit) {
+        // Empty path: keep the base path as-is.
+        return;
+      }
+      char c = input.charAt(pos);
+      if (c == '/' || c == '\\') {
+        // Absolute path: reset to the default "/".
+        encodedPathSegments.clear();
+        encodedPathSegments.add("");
+        pos++;
+      } else {
+        // Relative path: clear everything after the last '/'.
+        encodedPathSegments.set(encodedPathSegments.size() - 1, "");
+      }
+
+      // Read path segments.
+      for (int i = pos; i < limit; ) {
+        int pathSegmentDelimiterOffset = delimiterOffset(input, i, limit, "/\\");
+        boolean segmentHasTrailingSlash = pathSegmentDelimiterOffset < limit;
+        push(input, i, pathSegmentDelimiterOffset, segmentHasTrailingSlash, true);
+        i = pathSegmentDelimiterOffset;
+        if (segmentHasTrailingSlash) i++;
+      }
+    }
+
+    /** Adds a path segment. If the input is ".." or equivalent, this pops a path segment. */
+    private void push(String input, int pos, int limit, boolean addTrailingSlash,
+        boolean alreadyEncoded) {
+      String segment = canonicalize(
+          input, pos, limit, PATH_SEGMENT_ENCODE_SET, alreadyEncoded, false, false, true);
+      if (isDot(segment)) {
+        return; // Skip '.' path segments.
+      }
+      if (isDotDot(segment)) {
+        pop();
+        return;
+      }
+      if (encodedPathSegments.get(encodedPathSegments.size() - 1).isEmpty()) {
+        encodedPathSegments.set(encodedPathSegments.size() - 1, segment);
+      } else {
+        encodedPathSegments.add(segment);
+      }
+      if (addTrailingSlash) {
+        encodedPathSegments.add("");
+      }
+    }
+
+    private boolean isDot(String input) {
+      return input.equals(".") || input.equalsIgnoreCase("%2e");
+    }
+
+    private boolean isDotDot(String input) {
+      return input.equals("..")
+          || input.equalsIgnoreCase("%2e.")
+          || input.equalsIgnoreCase(".%2e")
+          || input.equalsIgnoreCase("%2e%2e");
+    }
+
+    /**
+     * Removes a path segment. When this method returns the last segment is always "", which means
+     * the encoded path will have a trailing '/'.
+     *
+     * <p>Popping "/a/b/c/" yields "/a/b/". In this case the list of path segments goes from
+     * ["a", "b", "c", ""] to ["a", "b", ""].
+     *
+     * <p>Popping "/a/b/c" also yields "/a/b/". The list of path segments goes from ["a", "b", "c"]
+     * to ["a", "b", ""].
+     */
+    private void pop() {
+      String removed = encodedPathSegments.remove(encodedPathSegments.size() - 1);
+
+      // Make sure the path ends with a '/' by either adding an empty string or clearing a segment.
+      if (removed.isEmpty() && !encodedPathSegments.isEmpty()) {
+        encodedPathSegments.set(encodedPathSegments.size() - 1, "");
+      } else {
+        encodedPathSegments.add("");
+      }
+    }
+
+    /**
+     * Increments {@code pos} until {@code input[pos]} is not ASCII whitespace. Stops at {@code
+     * limit}.
+     */
+    private int skipLeadingAsciiWhitespace(String input, int pos, int limit) {
+      for (int i = pos; i < limit; i++) {
+        switch (input.charAt(i)) {
+          case '\t':
+          case '\n':
+          case '\f':
+          case '\r':
+          case ' ':
+            continue;
+          default:
+            return i;
+        }
+      }
+      return limit;
+    }
+
+    /**
+     * Decrements {@code limit} until {@code input[limit - 1]} is not ASCII whitespace. Stops at
+     * {@code pos}.
+     */
+    private int skipTrailingAsciiWhitespace(String input, int pos, int limit) {
+      for (int i = limit - 1; i >= pos; i--) {
+        switch (input.charAt(i)) {
+          case '\t':
+          case '\n':
+          case '\f':
+          case '\r':
+          case ' ':
+            continue;
+          default:
+            return i + 1;
+        }
+      }
+      return pos;
+    }
+
+    /**
+     * Returns the index of the ':' in {@code input} that is after scheme characters. Returns -1 if
+     * {@code input} does not have a scheme that starts at {@code pos}.
+     */
+    private static int schemeDelimiterOffset(String input, int pos, int limit) {
+      if (limit - pos < 2) return -1;
+
+      char c0 = input.charAt(pos);
+      if ((c0 < 'a' || c0 > 'z') && (c0 < 'A' || c0 > 'Z')) return -1; // Not a scheme start char.
+
+      for (int i = pos + 1; i < limit; i++) {
+        char c = input.charAt(i);
+
+        if ((c >= 'a' && c <= 'z')
+            || (c >= 'A' && c <= 'Z')
+            || (c >= '0' && c <= '9')
+            || c == '+'
+            || c == '-'
+            || c == '.') {
+          continue; // Scheme character. Keep going.
+        } else if (c == ':') {
+          return i; // Scheme prefix!
+        } else {
+          return -1; // Non-scheme character before the first ':'.
+        }
+      }
+
+      return -1; // No ':'; doesn't start with a scheme.
+    }
+
+    /** Returns the number of '/' and '\' slashes in {@code input}, starting at {@code pos}. */
+    private static int slashCount(String input, int pos, int limit) {
+      int slashCount = 0;
+      while (pos < limit) {
+        char c = input.charAt(pos);
+        if (c == '\\' || c == '/') {
+          slashCount++;
+          pos++;
+        } else {
+          break;
+        }
+      }
+      return slashCount;
+    }
+
+    /** Finds the first ':' in {@code input}, skipping characters between square braces "[...]". */
+    private static int portColonOffset(String input, int pos, int limit) {
+      for (int i = pos; i < limit; i++) {
+        switch (input.charAt(i)) {
+          case '[':
+            while (++i < limit) {
+              if (input.charAt(i) == ']') break;
+            }
+            break;
+          case ':':
+            return i;
+        }
+      }
+      return limit; // No colon.
+    }
+
+    private static String canonicalizeHost(String input, int pos, int limit) {
+      // Start by percent decoding the host. The WHATWG spec suggests doing this only after we've
+      // checked for IPv6 square braces. But Chrome does it first, and that's more lenient.
+      String percentDecoded = percentDecode(input, pos, limit, false);
+
+      // If the input contains a :, it’s an IPv6 address.
+      if (percentDecoded.contains(":")) {
+        // If the input is encased in square braces "[...]", drop 'em.
+        InetAddress inetAddress = percentDecoded.startsWith("[") && percentDecoded.endsWith("]")
+            ? decodeIpv6(percentDecoded, 1, percentDecoded.length() - 1)
+            : decodeIpv6(percentDecoded, 0, percentDecoded.length());
+        if (inetAddress == null) return null;
+        byte[] address = inetAddress.getAddress();
+        if (address.length == 16) return inet6AddressToAscii(address);
+        throw new AssertionError();
+      }
+
+      return domainToAscii(percentDecoded);
+    }
+
+    /** Decodes an IPv6 address like 1111:2222:3333:4444:5555:6666:7777:8888 or ::1. */
+    private static InetAddress decodeIpv6(String input, int pos, int limit) {
+      byte[] address = new byte[16];
+      int b = 0;
+      int compress = -1;
+      int groupOffset = -1;
+
+      for (int i = pos; i < limit; ) {
+        if (b == address.length) return null; // Too many groups.
+
+        // Read a delimiter.
+        if (i + 2 <= limit && input.regionMatches(i, "::", 0, 2)) {
+          // Compression "::" delimiter, which is anywhere in the input, including its prefix.
+          if (compress != -1) return null; // Multiple "::" delimiters.
+          i += 2;
+          b += 2;
+          compress = b;
+          if (i == limit) break;
+        } else if (b != 0) {
+          // Group separator ":" delimiter.
+          if (input.regionMatches(i, ":", 0, 1)) {
+            i++;
+          } else if (input.regionMatches(i, ".", 0, 1)) {
+            // If we see a '.', rewind to the beginning of the previous group and parse as IPv4.
+            if (!decodeIpv4Suffix(input, groupOffset, limit, address, b - 2)) return null;
+            b += 2; // We rewound two bytes and then added four.
+            break;
+          } else {
+            return null; // Wrong delimiter.
+          }
+        }
+
+        // Read a group, one to four hex digits.
+        int value = 0;
+        groupOffset = i;
+        for (; i < limit; i++) {
+          char c = input.charAt(i);
+          int hexDigit = decodeHexDigit(c);
+          if (hexDigit == -1) break;
+          value = (value << 4) + hexDigit;
+        }
+        int groupLength = i - groupOffset;
+        if (groupLength == 0 || groupLength > 4) return null; // Group is the wrong size.
+
+        // We've successfully read a group. Assign its value to our byte array.
+        address[b++] = (byte) ((value >>> 8) & 0xff);
+        address[b++] = (byte) (value & 0xff);
+      }
+
+      // All done. If compression happened, we need to move bytes to the right place in the
+      // address. Here's a sample:
+      //
+      //      input: "1111:2222:3333::7777:8888"
+      //     before: { 11, 11, 22, 22, 33, 33, 00, 00, 77, 77, 88, 88, 00, 00, 00, 00  }
+      //   compress: 6
+      //          b: 10
+      //      after: { 11, 11, 22, 22, 33, 33, 00, 00, 00, 00, 00, 00, 77, 77, 88, 88 }
+      //
+      if (b != address.length) {
+        if (compress == -1) return null; // Address didn't have compression or enough groups.
+        System.arraycopy(address, compress, address, address.length - (b - compress), b - compress);
+        Arrays.fill(address, compress, compress + (address.length - b), (byte) 0);
+      }
+
+      try {
+        return InetAddress.getByAddress(address);
+      } catch (UnknownHostException e) {
+        throw new AssertionError();
+      }
+    }
+
+    /** Decodes an IPv4 address suffix of an IPv6 address, like 1111::5555:6666:192.168.0.1. */
+    private static boolean decodeIpv4Suffix(
+        String input, int pos, int limit, byte[] address, int addressOffset) {
+      int b = addressOffset;
+
+      for (int i = pos; i < limit; ) {
+        if (b == address.length) return false; // Too many groups.
+
+        // Read a delimiter.
+        if (b != addressOffset) {
+          if (input.charAt(i) != '.') return false; // Wrong delimiter.
+          i++;
+        }
+
+        // Read 1 or more decimal digits for a value in 0..255.
+        int value = 0;
+        int groupOffset = i;
+        for (; i < limit; i++) {
+          char c = input.charAt(i);
+          if (c < '0' || c > '9') break;
+          if (value == 0 && groupOffset != i) return false; // Reject unnecessary leading '0's.
+          value = (value * 10) + c - '0';
+          if (value > 255) return false; // Value out of range.
+        }
+        int groupLength = i - groupOffset;
+        if (groupLength == 0) return false; // No digits.
+
+        // We've successfully read a byte.
+        address[b++] = (byte) value;
+      }
+
+      if (b != addressOffset + 4) return false; // Too few groups. We wanted exactly four.
+      return true; // Success.
+    }
+
+    /**
+     * Performs IDN ToASCII encoding and canonicalize the result to lowercase. e.g. This converts
+     * {@code ☃.net} to {@code xn--n3h.net}, and {@code WwW.GoOgLe.cOm} to {@code www.google.com}.
+     * {@code null} will be returned if the input cannot be ToASCII encoded or if the result
+     * contains unsupported ASCII characters.
+     */
+    private static String domainToAscii(String input) {
+      try {
+        String result = IDN.toASCII(input).toLowerCase(Locale.US);
+        if (result.isEmpty()) return null;
+
+        // Confirm that the IDN ToASCII result doesn't contain any illegal characters.
+        if (containsInvalidHostnameAsciiCodes(result)) {
+          return null;
+        }
+        // TODO: implement all label limits.
+        return result;
+      } catch (IllegalArgumentException e) {
+        return null;
+      }
+    }
+
+    private static boolean containsInvalidHostnameAsciiCodes(String hostnameAscii) {
+      for (int i = 0; i < hostnameAscii.length(); i++) {
+        char c = hostnameAscii.charAt(i);
+        // The WHATWG Host parsing rules accepts some character codes which are invalid by
+        // definition for OkHttp's host header checks (and the WHATWG Host syntax definition). Here
+        // we rule out characters that would cause problems in host headers.
+        if (c <= '\u001f' || c >= '\u007f') {
+          return true;
+        }
+        // Check for the characters mentioned in the WHATWG Host parsing spec:
+        // U+0000, U+0009, U+000A, U+000D, U+0020, "#", "%", "/", ":", "?", "@", "[", "\", and "]"
+        // (excluding the characters covered above).
+        if (" #%/:?@[\\]".indexOf(c) != -1) {
+          return true;
+        }
+      }
+      return false;
+    }
+
+    private static String inet6AddressToAscii(byte[] address) {
+      // Go through the address looking for the longest run of 0s. Each group is 2-bytes.
+      int longestRunOffset = -1;
+      int longestRunLength = 0;
+      for (int i = 0; i < address.length; i += 2) {
+        int currentRunOffset = i;
+        while (i < 16 && address[i] == 0 && address[i + 1] == 0) {
+          i += 2;
+        }
+        int currentRunLength = i - currentRunOffset;
+        if (currentRunLength > longestRunLength) {
+          longestRunOffset = currentRunOffset;
+          longestRunLength = currentRunLength;
+        }
+      }
+
+      // Emit each 2-byte group in hex, separated by ':'. The longest run of zeroes is "::".
+      Buffer result = new Buffer();
+      for (int i = 0; i < address.length; ) {
+        if (i == longestRunOffset) {
+          result.writeByte(':');
+          i += longestRunLength;
+          if (i == 16) result.writeByte(':');
+        } else {
+          if (i > 0) result.writeByte(':');
+          int group = (address[i] & 0xff) << 8 | address[i + 1] & 0xff;
+          result.writeHexadecimalUnsignedLong(group);
+          i += 2;
+        }
+      }
+      return result.readUtf8();
+    }
+
+    private static int parsePort(String input, int pos, int limit) {
+      try {
+        // Canonicalize the port string to skip '\n' etc.
+        String portString = canonicalize(input, pos, limit, "", false, false, false, true);
+        int i = Integer.parseInt(portString);
+        if (i > 0 && i <= 65535) return i;
+        return -1;
+      } catch (NumberFormatException e) {
+        return -1; // Invalid port.
+      }
+    }
+  }
+
+  /**
+   * Returns the index of the first character in {@code input} that contains a character in {@code
+   * delimiters}. Returns limit if there is no such character.
+   */
+  private static int delimiterOffset(String input, int pos, int limit, String delimiters) {
+    for (int i = pos; i < limit; i++) {
+      if (delimiters.indexOf(input.charAt(i)) != -1) return i;
+    }
+    return limit;
+  }
+
+  static String percentDecode(String encoded, boolean plusIsSpace) {
+    return percentDecode(encoded, 0, encoded.length(), plusIsSpace);
+  }
+
+  private List<String> percentDecode(List<String> list, boolean plusIsSpace) {
+    List<String> result = new ArrayList<>(list.size());
+    for (String s : list) {
+      result.add(s != null ? percentDecode(s, plusIsSpace) : null);
+    }
+    return Collections.unmodifiableList(result);
+  }
+
+  static String percentDecode(String encoded, int pos, int limit, boolean plusIsSpace) {
+    for (int i = pos; i < limit; i++) {
+      char c = encoded.charAt(i);
+      if (c == '%' || (c == '+' && plusIsSpace)) {
+        // Slow path: the character at i requires decoding!
+        Buffer out = new Buffer();
+        out.writeUtf8(encoded, pos, i);
+        percentDecode(out, encoded, i, limit, plusIsSpace);
+        return out.readUtf8();
+      }
+    }
+
+    // Fast path: no characters in [pos..limit) required decoding.
+    return encoded.substring(pos, limit);
+  }
+
+  static void percentDecode(Buffer out, String encoded, int pos, int limit, boolean plusIsSpace) {
+    int codePoint;
+    for (int i = pos; i < limit; i += Character.charCount(codePoint)) {
+      codePoint = encoded.codePointAt(i);
+      if (codePoint == '%' && i + 2 < limit) {
+        int d1 = decodeHexDigit(encoded.charAt(i + 1));
+        int d2 = decodeHexDigit(encoded.charAt(i + 2));
+        if (d1 != -1 && d2 != -1) {
+          out.writeByte((d1 << 4) + d2);
+          i += 2;
+          continue;
+        }
+      } else if (codePoint == '+' && plusIsSpace) {
+        out.writeByte(' ');
+        continue;
+      }
+      out.writeUtf8CodePoint(codePoint);
+    }
+  }
+
+  static boolean percentEncoded(String encoded, int pos, int limit) {
+    return pos + 2 < limit
+        && encoded.charAt(pos) == '%'
+        && decodeHexDigit(encoded.charAt(pos + 1)) != -1
+        && decodeHexDigit(encoded.charAt(pos + 2)) != -1;
+  }
+
+  static int decodeHexDigit(char c) {
+    if (c >= '0' && c <= '9') return c - '0';
+    if (c >= 'a' && c <= 'f') return c - 'a' + 10;
+    if (c >= 'A' && c <= 'F') return c - 'A' + 10;
+    return -1;
+  }
+
+  /**
+   * Returns a substring of {@code input} on the range {@code [pos..limit)} with the following
+   * transformations:
+   * <ul>
+   *   <li>Tabs, newlines, form feeds and carriage returns are skipped.
+   *   <li>In queries, ' ' is encoded to '+' and '+' is encoded to "%2B".
+   *   <li>Characters in {@code encodeSet} are percent-encoded.
+   *   <li>Control characters and non-ASCII characters are percent-encoded.
+   *   <li>All other characters are copied without transformation.
+   * </ul>
+   *
+   * @param alreadyEncoded true to leave '%' as-is; false to convert it to '%25'.
+   * @param strict true to encode '%' if it is not the prefix of a valid percent encoding.
+   * @param plusIsSpace true to encode '+' as "%2B" if it is not already encoded.
+   * @param asciiOnly true to encode all non-ASCII codepoints.
+   */
+  static String canonicalize(String input, int pos, int limit, String encodeSet,
+      boolean alreadyEncoded, boolean strict, boolean plusIsSpace, boolean asciiOnly) {
+    int codePoint;
+    for (int i = pos; i < limit; i += Character.charCount(codePoint)) {
+      codePoint = input.codePointAt(i);
+      if (codePoint < 0x20
+          || codePoint == 0x7f
+          || codePoint >= 0x80 && asciiOnly
+          || encodeSet.indexOf(codePoint) != -1
+          || codePoint == '%' && (!alreadyEncoded || strict && !percentEncoded(input, i, limit))
+          || codePoint == '+' && plusIsSpace) {
+        // Slow path: the character at i requires encoding!
+        Buffer out = new Buffer();
+        out.writeUtf8(input, pos, i);
+        canonicalize(out, input, i, limit, encodeSet, alreadyEncoded, strict, plusIsSpace,
+            asciiOnly);
+        return out.readUtf8();
+      }
+    }
+
+    // Fast path: no characters in [pos..limit) required encoding.
+    return input.substring(pos, limit);
+  }
+
+  static void canonicalize(Buffer out, String input, int pos, int limit, String encodeSet,
+      boolean alreadyEncoded, boolean strict, boolean plusIsSpace, boolean asciiOnly) {
+    Buffer utf8Buffer = null; // Lazily allocated.
+    int codePoint;
+    for (int i = pos; i < limit; i += Character.charCount(codePoint)) {
+      codePoint = input.codePointAt(i);
+      if (alreadyEncoded
+          && (codePoint == '\t' || codePoint == '\n' || codePoint == '\f' || codePoint == '\r')) {
+        // Skip this character.
+      } else if (codePoint == '+' && plusIsSpace) {
+        // Encode '+' as '%2B' since we permit ' ' to be encoded as either '+' or '%20'.
+        out.writeUtf8(alreadyEncoded ? "+" : "%2B");
+      } else if (codePoint < 0x20
+          || codePoint == 0x7f
+          || codePoint >= 0x80 && asciiOnly
+          || encodeSet.indexOf(codePoint) != -1
+          || codePoint == '%' && (!alreadyEncoded || strict && !percentEncoded(input, i, limit))) {
+        // Percent encode this character.
+        if (utf8Buffer == null) {
+          utf8Buffer = new Buffer();
+        }
+        utf8Buffer.writeUtf8CodePoint(codePoint);
+        while (!utf8Buffer.exhausted()) {
+          int b = utf8Buffer.readByte() & 0xff;
+          out.writeByte('%');
+          out.writeByte(HEX_DIGITS[(b >> 4) & 0xf]);
+          out.writeByte(HEX_DIGITS[b & 0xf]);
+        }
+      } else {
+        // This character doesn't need encoding. Just copy it over.
+        out.writeUtf8CodePoint(codePoint);
+      }
+    }
+  }
+
+  static String canonicalize(String input, String encodeSet, boolean alreadyEncoded,
+      boolean strict, boolean plusIsSpace, boolean asciiOnly) {
+    return canonicalize(input, 0, input.length(),
+            encodeSet, alreadyEncoded, strict, plusIsSpace, asciiOnly);
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/Interceptor.java b/repackaged/okhttp/src/main/java/com/android/okhttp/Interceptor.java
new file mode 100644
index 0000000..5dee765
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/Interceptor.java
@@ -0,0 +1,35 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp;
+
+import java.io.IOException;
+
+/**
+ * Observes, modifies, and potentially short-circuits requests going out and the corresponding
+ * requests coming back in. Typically interceptors will be used to add, remove, or transform headers
+ * on the request or response.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface Interceptor {
+  Response intercept(Chain chain) throws IOException;
+
+  interface Chain {
+    Request request();
+    Response proceed(Request request) throws IOException;
+    Connection connection();
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/MediaType.java b/repackaged/okhttp/src/main/java/com/android/okhttp/MediaType.java
new file mode 100644
index 0000000..15048e4
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/MediaType.java
@@ -0,0 +1,125 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.okhttp;
+
+import java.nio.charset.Charset;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * An <a href="http://tools.ietf.org/html/rfc2045">RFC 2045</a> Media Type,
+ * appropriate to describe the content type of an HTTP request or response body.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class MediaType {
+  private static final String TOKEN = "([a-zA-Z0-9-!#$%&'*+.^_`{|}~]+)";
+  private static final String QUOTED = "\"([^\"]*)\"";
+  private static final Pattern TYPE_SUBTYPE = Pattern.compile(TOKEN + "/" + TOKEN);
+  private static final Pattern PARAMETER = Pattern.compile(
+      ";\\s*(?:" + TOKEN + "=(?:" + TOKEN + "|" + QUOTED + "))?");
+
+  private final String mediaType;
+  private final String type;
+  private final String subtype;
+  private final String charset;
+
+  private MediaType(String mediaType, String type, String subtype, String charset) {
+    this.mediaType = mediaType;
+    this.type = type;
+    this.subtype = subtype;
+    this.charset = charset;
+  }
+
+  /**
+   * Returns a media type for {@code string}, or null if {@code string} is not a
+   * well-formed media type.
+   */
+  public static MediaType parse(String string) {
+    Matcher typeSubtype = TYPE_SUBTYPE.matcher(string);
+    if (!typeSubtype.lookingAt()) return null;
+    String type = typeSubtype.group(1).toLowerCase(Locale.US);
+    String subtype = typeSubtype.group(2).toLowerCase(Locale.US);
+
+    String charset = null;
+    Matcher parameter = PARAMETER.matcher(string);
+    for (int s = typeSubtype.end(); s < string.length(); s = parameter.end()) {
+      parameter.region(s, string.length());
+      if (!parameter.lookingAt()) return null; // This is not a well-formed media type.
+
+      String name = parameter.group(1);
+      if (name == null || !name.equalsIgnoreCase("charset")) continue;
+      String charsetParameter = parameter.group(2) != null
+          ? parameter.group(2)  // Value is a token.
+          : parameter.group(3); // Value is a quoted string.
+      if (charset != null && !charsetParameter.equalsIgnoreCase(charset)) {
+        throw new IllegalArgumentException("Multiple different charsets: " + string);
+      }
+      charset = charsetParameter;
+    }
+
+    return new MediaType(string, type, subtype, charset);
+  }
+
+  /**
+   * Returns the high-level media type, such as "text", "image", "audio",
+   * "video", or "application".
+   */
+  public String type() {
+    return type;
+  }
+
+  /**
+   * Returns a specific media subtype, such as "plain" or "png", "mpeg",
+   * "mp4" or "xml".
+   */
+  public String subtype() {
+    return subtype;
+  }
+
+  /**
+   * Returns the charset of this media type, or null if this media type doesn't
+   * specify a charset.
+   */
+  public Charset charset() {
+    return charset != null ? Charset.forName(charset) : null;
+  }
+
+  /**
+   * Returns the charset of this media type, or {@code defaultValue} if this
+   * media type doesn't specify a charset.
+   */
+  public Charset charset(Charset defaultValue) {
+    return charset != null ? Charset.forName(charset) : defaultValue;
+  }
+
+  /**
+   * Returns the encoded media type, like "text/plain; charset=utf-8",
+   * appropriate for use in a Content-Type header.
+   */
+  @Override public String toString() {
+    return mediaType;
+  }
+
+  @Override public boolean equals(Object o) {
+    return o instanceof MediaType && ((MediaType) o).mediaType.equals(mediaType);
+  }
+
+  @Override public int hashCode() {
+    return mediaType.hashCode();
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/MultipartBuilder.java b/repackaged/okhttp/src/main/java/com/android/okhttp/MultipartBuilder.java
new file mode 100644
index 0000000..2bce7c5
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/MultipartBuilder.java
@@ -0,0 +1,302 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp;
+
+import com.android.okhttp.internal.Util;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import com.android.okhttp.okio.Buffer;
+import com.android.okhttp.okio.BufferedSink;
+import com.android.okhttp.okio.ByteString;
+
+/**
+ * Fluent API to build <a href="http://www.ietf.org/rfc/rfc2387.txt">RFC
+ * 2387</a>-compliant request bodies.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class MultipartBuilder {
+  /**
+   * The "mixed" subtype of "multipart" is intended for use when the body
+   * parts are independent and need to be bundled in a particular order. Any
+   * "multipart" subtypes that an implementation does not recognize must be
+   * treated as being of subtype "mixed".
+   */
+  public static final MediaType MIXED = MediaType.parse("multipart/mixed");
+
+  /**
+   * The "multipart/alternative" type is syntactically identical to
+   * "multipart/mixed", but the semantics are different. In particular, each
+   * of the body parts is an "alternative" version of the same information.
+   */
+  public static final MediaType ALTERNATIVE = MediaType.parse("multipart/alternative");
+
+  /**
+   * This type is syntactically identical to "multipart/mixed", but the
+   * semantics are different. In particular, in a digest, the default {@code
+   * Content-Type} value for a body part is changed from "text/plain" to
+   * "message/rfc822".
+   */
+  public static final MediaType DIGEST = MediaType.parse("multipart/digest");
+
+  /**
+   * This type is syntactically identical to "multipart/mixed", but the
+   * semantics are different. In particular, in a parallel entity, the order
+   * of body parts is not significant.
+   */
+  public static final MediaType PARALLEL = MediaType.parse("multipart/parallel");
+
+  /**
+   * The media-type multipart/form-data follows the rules of all multipart
+   * MIME data streams as outlined in RFC 2046. In forms, there are a series
+   * of fields to be supplied by the user who fills out the form. Each field
+   * has a name. Within a given form, the names are unique.
+   */
+  public static final MediaType FORM = MediaType.parse("multipart/form-data");
+
+  private static final byte[] COLONSPACE = { ':', ' ' };
+  private static final byte[] CRLF = { '\r', '\n' };
+  private static final byte[] DASHDASH = { '-', '-' };
+
+  private final ByteString boundary;
+  private MediaType type = MIXED;
+
+  // Parallel lists of nullable headers and non-null bodies.
+  private final List<Headers> partHeaders = new ArrayList<>();
+  private final List<RequestBody> partBodies = new ArrayList<>();
+
+  /** Creates a new multipart builder that uses a random boundary token. */
+  public MultipartBuilder() {
+    this(UUID.randomUUID().toString());
+  }
+
+  /**
+   * Creates a new multipart builder that uses {@code boundary} to separate
+   * parts. Prefer the no-argument constructor to defend against injection
+   * attacks.
+   */
+  public MultipartBuilder(String boundary) {
+    this.boundary = ByteString.encodeUtf8(boundary);
+  }
+
+  /**
+   * Set the MIME type. Expected values for {@code type} are {@link #MIXED} (the
+   * default), {@link #ALTERNATIVE}, {@link #DIGEST}, {@link #PARALLEL} and
+   * {@link #FORM}.
+   */
+  public MultipartBuilder type(MediaType type) {
+    if (type == null) {
+      throw new NullPointerException("type == null");
+    }
+    if (!type.type().equals("multipart")) {
+      throw new IllegalArgumentException("multipart != " + type);
+    }
+    this.type = type;
+    return this;
+  }
+
+  /** Add a part to the body. */
+  public MultipartBuilder addPart(RequestBody body) {
+    return addPart(null, body);
+  }
+
+  /** Add a part to the body. */
+  public MultipartBuilder addPart(Headers headers, RequestBody body) {
+    if (body == null) {
+      throw new NullPointerException("body == null");
+    }
+    if (headers != null && headers.get("Content-Type") != null) {
+      throw new IllegalArgumentException("Unexpected header: Content-Type");
+    }
+    if (headers != null && headers.get("Content-Length") != null) {
+      throw new IllegalArgumentException("Unexpected header: Content-Length");
+    }
+
+    partHeaders.add(headers);
+    partBodies.add(body);
+    return this;
+  }
+
+  /**
+   * Appends a quoted-string to a StringBuilder.
+   *
+   * <p>RFC 2388 is rather vague about how one should escape special characters
+   * in form-data parameters, and as it turns out Firefox and Chrome actually
+   * do rather different things, and both say in their comments that they're
+   * not really sure what the right approach is. We go with Chrome's behavior
+   * (which also experimentally seems to match what IE does), but if you
+   * actually want to have a good chance of things working, please avoid
+   * double-quotes, newlines, percent signs, and the like in your field names.
+   */
+  private static StringBuilder appendQuotedString(StringBuilder target, String key) {
+    target.append('"');
+    for (int i = 0, len = key.length(); i < len; i++) {
+      char ch = key.charAt(i);
+      switch (ch) {
+        case '\n':
+          target.append("%0A");
+          break;
+        case '\r':
+          target.append("%0D");
+          break;
+        case '"':
+          target.append("%22");
+          break;
+        default:
+          target.append(ch);
+          break;
+      }
+    }
+    target.append('"');
+    return target;
+  }
+
+  /** Add a form data part to the body. */
+  public MultipartBuilder addFormDataPart(String name, String value) {
+    return addFormDataPart(name, null, RequestBody.create(null, value));
+  }
+
+  /** Add a form data part to the body. */
+  public MultipartBuilder addFormDataPart(String name, String filename, RequestBody value) {
+    if (name == null) {
+      throw new NullPointerException("name == null");
+    }
+    StringBuilder disposition = new StringBuilder("form-data; name=");
+    appendQuotedString(disposition, name);
+
+    if (filename != null) {
+      disposition.append("; filename=");
+      appendQuotedString(disposition, filename);
+    }
+
+    return addPart(Headers.of("Content-Disposition", disposition.toString()), value);
+  }
+
+  /** Assemble the specified parts into a request body. */
+  public RequestBody build() {
+    if (partHeaders.isEmpty()) {
+      throw new IllegalStateException("Multipart body must have at least one part.");
+    }
+    return new MultipartRequestBody(type, boundary, partHeaders, partBodies);
+  }
+
+  private static final class MultipartRequestBody extends RequestBody {
+    private final ByteString boundary;
+    private final MediaType contentType;
+    private final List<Headers> partHeaders;
+    private final List<RequestBody> partBodies;
+    private long contentLength = -1L;
+
+    public MultipartRequestBody(MediaType type, ByteString boundary, List<Headers> partHeaders,
+        List<RequestBody> partBodies) {
+      if (type == null) throw new NullPointerException("type == null");
+
+      this.boundary = boundary;
+      this.contentType = MediaType.parse(type + "; boundary=" + boundary.utf8());
+      this.partHeaders = Util.immutableList(partHeaders);
+      this.partBodies = Util.immutableList(partBodies);
+    }
+
+    @Override public MediaType contentType() {
+      return contentType;
+    }
+
+    @Override public long contentLength() throws IOException {
+      long result = contentLength;
+      if (result != -1L) return result;
+      return contentLength = writeOrCountBytes(null, true);
+    }
+
+    /**
+     * Either writes this request to {@code sink} or measures its content length. We have one method
+     * do double-duty to make sure the counting and content are consistent, particularly when it
+     * comes to awkward operations like measuring the encoded length of header strings, or the
+     * length-in-digits of an encoded integer.
+     */
+    private long writeOrCountBytes(BufferedSink sink, boolean countBytes) throws IOException {
+      long byteCount = 0L;
+
+      Buffer byteCountBuffer = null;
+      if (countBytes) {
+        sink = byteCountBuffer = new Buffer();
+      }
+
+      for (int p = 0, partCount = partHeaders.size(); p < partCount; p++) {
+        Headers headers = partHeaders.get(p);
+        RequestBody body = partBodies.get(p);
+
+        sink.write(DASHDASH);
+        sink.write(boundary);
+        sink.write(CRLF);
+
+        if (headers != null) {
+          for (int h = 0, headerCount = headers.size(); h < headerCount; h++) {
+            sink.writeUtf8(headers.name(h))
+                .write(COLONSPACE)
+                .writeUtf8(headers.value(h))
+                .write(CRLF);
+          }
+        }
+
+        MediaType contentType = body.contentType();
+        if (contentType != null) {
+          sink.writeUtf8("Content-Type: ")
+              .writeUtf8(contentType.toString())
+              .write(CRLF);
+        }
+
+        long contentLength = body.contentLength();
+        if (contentLength != -1) {
+          sink.writeUtf8("Content-Length: ")
+              .writeDecimalLong(contentLength)
+              .write(CRLF);
+        } else if (countBytes) {
+          // We can't measure the body's size without the sizes of its components.
+          byteCountBuffer.clear();
+          return -1L;
+        }
+
+        sink.write(CRLF);
+
+        if (countBytes) {
+          byteCount += contentLength;
+        } else {
+          partBodies.get(p).writeTo(sink);
+        }
+
+        sink.write(CRLF);
+      }
+
+      sink.write(DASHDASH);
+      sink.write(boundary);
+      sink.write(DASHDASH);
+      sink.write(CRLF);
+
+      if (countBytes) {
+        byteCount += byteCountBuffer.size();
+        byteCountBuffer.clear();
+      }
+
+      return byteCount;
+    }
+
+    @Override public void writeTo(BufferedSink sink) throws IOException {
+      writeOrCountBytes(sink, false);
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/OkHttpClient.java b/repackaged/okhttp/src/main/java/com/android/okhttp/OkHttpClient.java
new file mode 100644
index 0000000..b6698d3
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/OkHttpClient.java
@@ -0,0 +1,647 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.okhttp;
+
+import com.android.okhttp.internal.Internal;
+import com.android.okhttp.internal.InternalCache;
+import com.android.okhttp.internal.RouteDatabase;
+import com.android.okhttp.internal.Util;
+import com.android.okhttp.internal.http.AuthenticatorAdapter;
+import com.android.okhttp.internal.http.StreamAllocation;
+import com.android.okhttp.internal.io.RealConnection;
+import com.android.okhttp.internal.tls.OkHostnameVerifier;
+import java.net.CookieHandler;
+import java.net.MalformedURLException;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.URLConnection;
+import java.net.UnknownHostException;
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import javax.net.SocketFactory;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
+/**
+ * Configures and creates HTTP connections. Most applications can use a single
+ * OkHttpClient for all of their HTTP requests - benefiting from a shared
+ * response cache, thread pool, connection re-use, etc.
+ *
+ * <p>Instances of OkHttpClient are intended to be fully configured before they're
+ * shared - once shared they should be treated as immutable and can safely be used
+ * to concurrently open new connections. If required, threads can call
+ * {@link #clone()} to make a shallow copy of the OkHttpClient that can be
+ * safely modified with further configuration changes.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class OkHttpClient implements Cloneable {
+  private static final List<Protocol> DEFAULT_PROTOCOLS = Util.immutableList(
+      Protocol.HTTP_2, Protocol.SPDY_3, Protocol.HTTP_1_1);
+
+  private static final List<ConnectionSpec> DEFAULT_CONNECTION_SPECS = Util.immutableList(
+      ConnectionSpec.MODERN_TLS, ConnectionSpec.COMPATIBLE_TLS, ConnectionSpec.CLEARTEXT);
+
+  static {
+    Internal.instance = new Internal() {
+      @Override public void addLenient(Headers.Builder builder, String line) {
+        builder.addLenient(line);
+      }
+
+      @Override public void addLenient(Headers.Builder builder, String name, String value) {
+        builder.addLenient(name, value);
+      }
+
+      @Override public void setCache(OkHttpClient client, InternalCache internalCache) {
+        client.setInternalCache(internalCache);
+      }
+
+      @Override public InternalCache internalCache(OkHttpClient client) {
+        return client.internalCache();
+      }
+
+      @Override public boolean connectionBecameIdle(
+          ConnectionPool pool, RealConnection connection) {
+        return pool.connectionBecameIdle(connection);
+      }
+
+      @Override public RealConnection get(
+          ConnectionPool pool, Address address, StreamAllocation streamAllocation) {
+        return pool.get(address, streamAllocation);
+      }
+
+      @Override public void put(ConnectionPool pool, RealConnection connection) {
+        pool.put(connection);
+      }
+
+      @Override public RouteDatabase routeDatabase(ConnectionPool connectionPool) {
+        return connectionPool.routeDatabase;
+      }
+
+      @Override
+      public void callEnqueue(Call call, Callback responseCallback, boolean forWebSocket) {
+        call.enqueue(responseCallback, forWebSocket);
+      }
+
+      @Override public StreamAllocation callEngineGetStreamAllocation(Call call) {
+        return call.engine.streamAllocation;
+      }
+
+      @Override
+      public void apply(ConnectionSpec tlsConfiguration, SSLSocket sslSocket, boolean isFallback) {
+        tlsConfiguration.apply(sslSocket, isFallback);
+      }
+
+      @Override public HttpUrl getHttpUrlChecked(String url)
+          throws MalformedURLException, UnknownHostException {
+        return HttpUrl.getChecked(url);
+      }
+    };
+  }
+
+  /** Lazily-initialized. */
+  private static SSLSocketFactory defaultSslSocketFactory;
+
+  private final RouteDatabase routeDatabase;
+  private Dispatcher dispatcher;
+  private Proxy proxy;
+  private List<Protocol> protocols;
+  private List<ConnectionSpec> connectionSpecs;
+  private final List<Interceptor> interceptors = new ArrayList<>();
+  private final List<Interceptor> networkInterceptors = new ArrayList<>();
+  private ProxySelector proxySelector;
+  private CookieHandler cookieHandler;
+
+  /** Non-null if this client is caching; possibly by {@code cache}. */
+  private InternalCache internalCache;
+  private Cache cache;
+
+  private SocketFactory socketFactory;
+  private SSLSocketFactory sslSocketFactory;
+  private HostnameVerifier hostnameVerifier;
+  private CertificatePinner certificatePinner;
+  private Authenticator authenticator;
+  private ConnectionPool connectionPool;
+  private Dns dns;
+  private boolean followSslRedirects = true;
+  private boolean followRedirects = true;
+  private boolean retryOnConnectionFailure = true;
+  private int connectTimeout = 10_000;
+  private int readTimeout = 10_000;
+  private int writeTimeout = 10_000;
+
+  public OkHttpClient() {
+    routeDatabase = new RouteDatabase();
+    dispatcher = new Dispatcher();
+  }
+
+  private OkHttpClient(OkHttpClient okHttpClient) {
+    this.routeDatabase = okHttpClient.routeDatabase;
+    this.dispatcher = okHttpClient.dispatcher;
+    this.proxy = okHttpClient.proxy;
+    this.protocols = okHttpClient.protocols;
+    this.connectionSpecs = okHttpClient.connectionSpecs;
+    this.interceptors.addAll(okHttpClient.interceptors);
+    this.networkInterceptors.addAll(okHttpClient.networkInterceptors);
+    this.proxySelector = okHttpClient.proxySelector;
+    this.cookieHandler = okHttpClient.cookieHandler;
+    this.cache = okHttpClient.cache;
+    this.internalCache = cache != null ? cache.internalCache : okHttpClient.internalCache;
+    this.socketFactory = okHttpClient.socketFactory;
+    this.sslSocketFactory = okHttpClient.sslSocketFactory;
+    this.hostnameVerifier = okHttpClient.hostnameVerifier;
+    this.certificatePinner = okHttpClient.certificatePinner;
+    this.authenticator = okHttpClient.authenticator;
+    this.connectionPool = okHttpClient.connectionPool;
+    this.dns = okHttpClient.dns;
+    this.followSslRedirects = okHttpClient.followSslRedirects;
+    this.followRedirects = okHttpClient.followRedirects;
+    this.retryOnConnectionFailure = okHttpClient.retryOnConnectionFailure;
+    this.connectTimeout = okHttpClient.connectTimeout;
+    this.readTimeout = okHttpClient.readTimeout;
+    this.writeTimeout = okHttpClient.writeTimeout;
+  }
+
+  /**
+   * Sets the default connect timeout for new connections. A value of 0 means no timeout, otherwise
+   * values must be between 1 and {@link Integer#MAX_VALUE} when converted to milliseconds.
+   *
+   * @see URLConnection#setConnectTimeout(int)
+   */
+  public void setConnectTimeout(long timeout, TimeUnit unit) {
+    if (timeout < 0) throw new IllegalArgumentException("timeout < 0");
+    if (unit == null) throw new IllegalArgumentException("unit == null");
+    long millis = unit.toMillis(timeout);
+    if (millis > Integer.MAX_VALUE) throw new IllegalArgumentException("Timeout too large.");
+    if (millis == 0 && timeout > 0) throw new IllegalArgumentException("Timeout too small.");
+    connectTimeout = (int) millis;
+  }
+
+  /** Default connect timeout (in milliseconds). */
+  public int getConnectTimeout() {
+    return connectTimeout;
+  }
+
+  /**
+   * Sets the default read timeout for new connections. A value of 0 means no timeout, otherwise
+   * values must be between 1 and {@link Integer#MAX_VALUE} when converted to milliseconds.
+   *
+   * @see URLConnection#setReadTimeout(int)
+   */
+  public void setReadTimeout(long timeout, TimeUnit unit) {
+    if (timeout < 0) throw new IllegalArgumentException("timeout < 0");
+    if (unit == null) throw new IllegalArgumentException("unit == null");
+    long millis = unit.toMillis(timeout);
+    if (millis > Integer.MAX_VALUE) throw new IllegalArgumentException("Timeout too large.");
+    if (millis == 0 && timeout > 0) throw new IllegalArgumentException("Timeout too small.");
+    readTimeout = (int) millis;
+  }
+
+  /** Default read timeout (in milliseconds). */
+  public int getReadTimeout() {
+    return readTimeout;
+  }
+
+  /**
+   * Sets the default write timeout for new connections. A value of 0 means no timeout, otherwise
+   * values must be between 1 and {@link Integer#MAX_VALUE} when converted to milliseconds.
+   */
+  public void setWriteTimeout(long timeout, TimeUnit unit) {
+    if (timeout < 0) throw new IllegalArgumentException("timeout < 0");
+    if (unit == null) throw new IllegalArgumentException("unit == null");
+    long millis = unit.toMillis(timeout);
+    if (millis > Integer.MAX_VALUE) throw new IllegalArgumentException("Timeout too large.");
+    if (millis == 0 && timeout > 0) throw new IllegalArgumentException("Timeout too small.");
+    writeTimeout = (int) millis;
+  }
+
+  /** Default write timeout (in milliseconds). */
+  public int getWriteTimeout() {
+    return writeTimeout;
+  }
+
+  /**
+   * Sets the HTTP proxy that will be used by connections created by this
+   * client. This takes precedence over {@link #setProxySelector}, which is
+   * only honored when this proxy is null (which it is by default). To disable
+   * proxy use completely, call {@code setProxy(Proxy.NO_PROXY)}.
+   */
+  public OkHttpClient setProxy(Proxy proxy) {
+    this.proxy = proxy;
+    return this;
+  }
+
+  public Proxy getProxy() {
+    return proxy;
+  }
+
+  /**
+   * Sets the proxy selection policy to be used if no {@link #setProxy proxy}
+   * is specified explicitly. The proxy selector may return multiple proxies;
+   * in that case they will be tried in sequence until a successful connection
+   * is established.
+   *
+   * <p>If unset, the {@link ProxySelector#getDefault() system-wide default}
+   * proxy selector will be used.
+   */
+  public OkHttpClient setProxySelector(ProxySelector proxySelector) {
+    this.proxySelector = proxySelector;
+    return this;
+  }
+
+  public ProxySelector getProxySelector() {
+    return proxySelector;
+  }
+
+  /**
+   * Sets the cookie handler to be used to read outgoing cookies and write
+   * incoming cookies.
+   *
+   * <p>If unset, the {@link CookieHandler#getDefault() system-wide default}
+   * cookie handler will be used.
+   */
+  public OkHttpClient setCookieHandler(CookieHandler cookieHandler) {
+    this.cookieHandler = cookieHandler;
+    return this;
+  }
+
+  public CookieHandler getCookieHandler() {
+    return cookieHandler;
+  }
+
+  /** Sets the response cache to be used to read and write cached responses. */
+  void setInternalCache(InternalCache internalCache) {
+    this.internalCache = internalCache;
+    this.cache = null;
+  }
+
+  InternalCache internalCache() {
+    return internalCache;
+  }
+
+  public OkHttpClient setCache(Cache cache) {
+    this.cache = cache;
+    this.internalCache = null;
+    return this;
+  }
+
+  public Cache getCache() {
+    return cache;
+  }
+
+  /**
+   * Sets the DNS service used to lookup IP addresses for hostnames.
+   *
+   * <p>If unset, the {@link Dns#SYSTEM system-wide default} DNS will be used.
+   */
+  public OkHttpClient setDns(Dns dns) {
+    this.dns = dns;
+    return this;
+  }
+
+  public Dns getDns() {
+    return dns;
+  }
+
+  /**
+   * Sets the socket factory used to create connections. OkHttp only uses
+   * the parameterless {@link SocketFactory#createSocket() createSocket()}
+   * method to create unconnected sockets. Overriding this method,
+   * e. g., allows the socket to be bound to a specific local address.
+   *
+   * <p>If unset, the {@link SocketFactory#getDefault() system-wide default}
+   * socket factory will be used.
+   */
+  public OkHttpClient setSocketFactory(SocketFactory socketFactory) {
+    this.socketFactory = socketFactory;
+    return this;
+  }
+
+  public SocketFactory getSocketFactory() {
+    return socketFactory;
+  }
+
+  /**
+   * Sets the socket factory used to secure HTTPS connections.
+   *
+   * <p>If unset, a lazily created SSL socket factory will be used.
+   */
+  public OkHttpClient setSslSocketFactory(SSLSocketFactory sslSocketFactory) {
+    this.sslSocketFactory = sslSocketFactory;
+    return this;
+  }
+
+  public SSLSocketFactory getSslSocketFactory() {
+    return sslSocketFactory;
+  }
+
+  /**
+   * Sets the verifier used to confirm that response certificates apply to
+   * requested hostnames for HTTPS connections.
+   *
+   * <p>If unset, a default hostname verifier will be used.
+   */
+  public OkHttpClient setHostnameVerifier(HostnameVerifier hostnameVerifier) {
+    this.hostnameVerifier = hostnameVerifier;
+    return this;
+  }
+
+  public HostnameVerifier getHostnameVerifier() {
+    return hostnameVerifier;
+  }
+
+  /**
+   * Sets the certificate pinner that constrains which certificates are trusted.
+   * By default HTTPS connections rely on only the {@link #setSslSocketFactory
+   * SSL socket factory} to establish trust. Pinning certificates avoids the
+   * need to trust certificate authorities.
+   */
+  public OkHttpClient setCertificatePinner(CertificatePinner certificatePinner) {
+    this.certificatePinner = certificatePinner;
+    return this;
+  }
+
+  public CertificatePinner getCertificatePinner() {
+    return certificatePinner;
+  }
+
+  /**
+   * Sets the authenticator used to respond to challenges from the remote web
+   * server or proxy server.
+   *
+   * <p>If unset, the {@link java.net.Authenticator#setDefault system-wide default}
+   * authenticator will be used.
+   */
+  public OkHttpClient setAuthenticator(Authenticator authenticator) {
+    this.authenticator = authenticator;
+    return this;
+  }
+
+  public Authenticator getAuthenticator() {
+    return authenticator;
+  }
+
+  /**
+   * Sets the connection pool used to recycle HTTP and HTTPS connections.
+   *
+   * <p>If unset, the {@link ConnectionPool#getDefault() system-wide
+   * default} connection pool will be used.
+   */
+  public OkHttpClient setConnectionPool(ConnectionPool connectionPool) {
+    this.connectionPool = connectionPool;
+    return this;
+  }
+
+  public ConnectionPool getConnectionPool() {
+    return connectionPool;
+  }
+
+  /**
+   * Configure this client to follow redirects from HTTPS to HTTP and from HTTP
+   * to HTTPS.
+   *
+   * <p>If unset, protocol redirects will be followed. This is different than
+   * the built-in {@code HttpURLConnection}'s default.
+   */
+  public OkHttpClient setFollowSslRedirects(boolean followProtocolRedirects) {
+    this.followSslRedirects = followProtocolRedirects;
+    return this;
+  }
+
+  public boolean getFollowSslRedirects() {
+    return followSslRedirects;
+  }
+
+  /** Configure this client to follow redirects. If unset, redirects be followed. */
+  public void setFollowRedirects(boolean followRedirects) {
+    this.followRedirects = followRedirects;
+  }
+
+  public boolean getFollowRedirects() {
+    return followRedirects;
+  }
+
+  /**
+   * Configure this client to retry or not when a connectivity problem is encountered. By default,
+   * this client silently recovers from the following problems:
+   *
+   * <ul>
+   *   <li><strong>Unreachable IP addresses.</strong> If the URL's host has multiple IP addresses,
+   *       failure to reach any individual IP address doesn't fail the overall request. This can
+   *       increase availability of multi-homed services.
+   *   <li><strong>Stale pooled connections.</strong> The {@link ConnectionPool} reuses sockets
+   *       to decrease request latency, but these connections will occasionally time out.
+   *   <li><strong>Unreachable proxy servers.</strong> A {@link ProxySelector} can be used to
+   *       attempt multiple proxy servers in sequence, eventually falling back to a direct
+   *       connection.
+   * </ul>
+   *
+   * Set this to false to avoid retrying requests when doing so is destructive. In this case the
+   * calling application should do its own recovery of connectivity failures.
+   */
+  public void setRetryOnConnectionFailure(boolean retryOnConnectionFailure) {
+    this.retryOnConnectionFailure = retryOnConnectionFailure;
+  }
+
+  public boolean getRetryOnConnectionFailure() {
+    return retryOnConnectionFailure;
+  }
+
+  RouteDatabase routeDatabase() {
+    return routeDatabase;
+  }
+
+  /**
+   * Sets the dispatcher used to set policy and execute asynchronous requests.
+   * Must not be null.
+   */
+  public OkHttpClient setDispatcher(Dispatcher dispatcher) {
+    if (dispatcher == null) throw new IllegalArgumentException("dispatcher == null");
+    this.dispatcher = dispatcher;
+    return this;
+  }
+
+  public Dispatcher getDispatcher() {
+    return dispatcher;
+  }
+
+  /**
+   * Configure the protocols used by this client to communicate with remote
+   * servers. By default this client will prefer the most efficient transport
+   * available, falling back to more ubiquitous protocols. Applications should
+   * only call this method to avoid specific compatibility problems, such as web
+   * servers that behave incorrectly when SPDY is enabled.
+   *
+   * <p>The following protocols are currently supported:
+   * <ul>
+   *   <li><a href="http://www.w3.org/Protocols/rfc2616/rfc2616.html">http/1.1</a>
+   *   <li><a href="http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1">spdy/3.1</a>
+   *   <li><a href="http://tools.ietf.org/html/draft-ietf-httpbis-http2-17">h2</a>
+   * </ul>
+   *
+   * <p><strong>This is an evolving set.</strong> Future releases include
+   * support for transitional protocols. The http/1.1 transport will never be
+   * dropped.
+   *
+   * <p>If multiple protocols are specified, <a
+   * href="http://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg">ALPN</a>
+   * will be used to negotiate a transport.
+   *
+   * <p>{@link Protocol#HTTP_1_0} is not supported in this set. Requests are
+   * initiated with {@code HTTP/1.1} only. If the server responds with {@code
+   * HTTP/1.0}, that will be exposed by {@link Response#protocol()}.
+   *
+   * @param protocols the protocols to use, in order of preference. The list
+   *     must contain {@link Protocol#HTTP_1_1}. It must not contain null or
+   *     {@link Protocol#HTTP_1_0}.
+   */
+  public OkHttpClient setProtocols(List<Protocol> protocols) {
+    protocols = Util.immutableList(protocols);
+    if (!protocols.contains(Protocol.HTTP_1_1)) {
+      throw new IllegalArgumentException("protocols doesn't contain http/1.1: " + protocols);
+    }
+    if (protocols.contains(Protocol.HTTP_1_0)) {
+      throw new IllegalArgumentException("protocols must not contain http/1.0: " + protocols);
+    }
+    if (protocols.contains(null)) {
+      throw new IllegalArgumentException("protocols must not contain null");
+    }
+    this.protocols = Util.immutableList(protocols);
+    return this;
+  }
+
+  public List<Protocol> getProtocols() {
+    return protocols;
+  }
+
+  public OkHttpClient setConnectionSpecs(List<ConnectionSpec> connectionSpecs) {
+    this.connectionSpecs = Util.immutableList(connectionSpecs);
+    return this;
+  }
+
+  public List<ConnectionSpec> getConnectionSpecs() {
+    return connectionSpecs;
+  }
+
+  /**
+   * Returns a modifiable list of interceptors that observe the full span of each call: from before
+   * the connection is established (if any) until after the response source is selected (either the
+   * origin server, cache, or both).
+   */
+  public List<Interceptor> interceptors() {
+    return interceptors;
+  }
+
+  /**
+   * Returns a modifiable list of interceptors that observe a single network request and response.
+   * These interceptors must call {@link Interceptor.Chain#proceed} exactly once: it is an error for
+   * a network interceptor to short-circuit or repeat a network request.
+   */
+  public List<Interceptor> networkInterceptors() {
+    return networkInterceptors;
+  }
+
+  /**
+   * Prepares the {@code request} to be executed at some point in the future.
+   */
+  public Call newCall(Request request) {
+    return new Call(this, request);
+  }
+
+  /**
+   * Cancels all scheduled or in-flight calls tagged with {@code tag}. Requests
+   * that are already complete cannot be canceled.
+   */
+  public OkHttpClient cancel(Object tag) {
+    getDispatcher().cancel(tag);
+    return this;
+  }
+
+  /**
+   * Returns a shallow copy of this OkHttpClient that uses the system-wide
+   * default for each field that hasn't been explicitly configured.
+   */
+  OkHttpClient copyWithDefaults() {
+    OkHttpClient result = new OkHttpClient(this);
+    if (result.proxySelector == null) {
+      result.proxySelector = ProxySelector.getDefault();
+    }
+    if (result.cookieHandler == null) {
+      result.cookieHandler = CookieHandler.getDefault();
+    }
+    if (result.socketFactory == null) {
+      result.socketFactory = SocketFactory.getDefault();
+    }
+    if (result.sslSocketFactory == null) {
+      result.sslSocketFactory = getDefaultSSLSocketFactory();
+    }
+    if (result.hostnameVerifier == null) {
+      result.hostnameVerifier = OkHostnameVerifier.INSTANCE;
+    }
+    if (result.certificatePinner == null) {
+      result.certificatePinner = CertificatePinner.DEFAULT;
+    }
+    if (result.authenticator == null) {
+      result.authenticator = AuthenticatorAdapter.INSTANCE;
+    }
+    if (result.connectionPool == null) {
+      result.connectionPool = ConnectionPool.getDefault();
+    }
+    if (result.protocols == null) {
+      result.protocols = DEFAULT_PROTOCOLS;
+    }
+    if (result.connectionSpecs == null) {
+      result.connectionSpecs = DEFAULT_CONNECTION_SPECS;
+    }
+    if (result.dns == null) {
+      result.dns = Dns.SYSTEM;
+    }
+    return result;
+  }
+
+  /**
+   * Java and Android programs default to using a single global SSL context,
+   * accessible to HTTP clients as {@link SSLSocketFactory#getDefault()}. If we
+   * used the shared SSL context, when OkHttp enables ALPN for its SPDY-related
+   * stuff, it would also enable ALPN for other usages, which might crash them
+   * because ALPN is enabled when it isn't expected to be.
+   *
+   * <p>This code avoids that by defaulting to an OkHttp-created SSL context.
+   * The drawback of this approach is that apps that customize the global SSL
+   * context will lose these customizations.
+   */
+  private synchronized SSLSocketFactory getDefaultSSLSocketFactory() {
+    if (defaultSslSocketFactory == null) {
+      try {
+        SSLContext sslContext = SSLContext.getInstance("TLS");
+        sslContext.init(null, null, null);
+        defaultSslSocketFactory = sslContext.getSocketFactory();
+      } catch (GeneralSecurityException e) {
+        throw new AssertionError(); // The system has no TLS. Just give up.
+      }
+    }
+    return defaultSslSocketFactory;
+  }
+
+  /** Returns a shallow copy of this OkHttpClient. */
+  @Override public OkHttpClient clone() {
+    return new OkHttpClient(this);
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/Protocol.java b/repackaged/okhttp/src/main/java/com/android/okhttp/Protocol.java
new file mode 100644
index 0000000..3ddb8bf
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/Protocol.java
@@ -0,0 +1,99 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp;
+
+import java.io.IOException;
+
+/**
+ * Protocols that OkHttp implements for <a
+ * href="http://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg">ALPN</a>
+ * selection.
+ *
+ * <h3>Protocol vs Scheme</h3>
+ * Despite its name, {@link java.net.URL#getProtocol()} returns the
+ * {@linkplain java.net.URI#getScheme() scheme} (http, https, etc.) of the URL, not
+ * the protocol (http/1.1, spdy/3.1, etc.). OkHttp uses the word <i>protocol</i>
+ * to identify how HTTP messages are framed.
+ * @hide This class is not part of the Android public SDK API
+ */
+public enum Protocol {
+  /**
+   * An obsolete plaintext framing that does not use persistent sockets by
+   * default.
+   */
+  HTTP_1_0("http/1.0"),
+
+  /**
+   * A plaintext framing that includes persistent connections.
+   *
+   * <p>This version of OkHttp implements <a
+   * href="http://www.ietf.org/rfc/rfc2616.txt">RFC 2616</a>, and tracks
+   * revisions to that spec.
+   */
+  HTTP_1_1("http/1.1"),
+
+  /**
+   * Chromium's binary-framed protocol that includes header compression,
+   * multiplexing multiple requests on the same socket, and server-push.
+   * HTTP/1.1 semantics are layered on SPDY/3.
+   *
+   * <p>This version of OkHttp implements SPDY 3 <a
+   * href="http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1">draft
+   * 3.1</a>. Future releases of OkHttp may use this identifier for a newer draft
+   * of the SPDY spec.
+   */
+  SPDY_3("spdy/3.1"),
+
+  /**
+   * The IETF's binary-framed protocol that includes header compression,
+   * multiplexing multiple requests on the same socket, and server-push.
+   * HTTP/1.1 semantics are layered on HTTP/2.
+   *
+   * <p>HTTP/2 requires deployments of HTTP/2 that use TLS 1.2 support
+   * {@linkplain com.android.okhttp.CipherSuite#TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}
+   * , present in Java 8+ and Android 5+. Servers that enforce this may send an
+   * exception message including the string {@code INADEQUATE_SECURITY}.
+   */
+  HTTP_2("h2");
+
+  private final String protocol;
+
+  Protocol(String protocol) {
+    this.protocol = protocol;
+  }
+
+  /**
+   * Returns the protocol identified by {@code protocol}.
+   * @throws IOException if {@code protocol} is unknown.
+   */
+  public static Protocol get(String protocol) throws IOException {
+    // Unroll the loop over values() to save an allocation.
+    if (protocol.equals(HTTP_1_0.protocol)) return HTTP_1_0;
+    if (protocol.equals(HTTP_1_1.protocol)) return HTTP_1_1;
+    if (protocol.equals(HTTP_2.protocol)) return HTTP_2;
+    if (protocol.equals(SPDY_3.protocol)) return SPDY_3;
+    throw new IOException("Unexpected protocol: " + protocol);
+  }
+
+  /**
+   * Returns the string used to identify this protocol for ALPN, like
+   * "http/1.1", "spdy/3.1" or "h2".
+   */
+  @Override public String toString() {
+    return protocol;
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/Request.java b/repackaged/okhttp/src/main/java/com/android/okhttp/Request.java
new file mode 100644
index 0000000..e16496e
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/Request.java
@@ -0,0 +1,286 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.okhttp;
+
+import com.android.okhttp.internal.http.HttpMethod;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URL;
+import java.util.List;
+
+/**
+ * An HTTP request. Instances of this class are immutable if their {@link #body}
+ * is null or itself immutable.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Request {
+  private final HttpUrl url;
+  private final String method;
+  private final Headers headers;
+  private final RequestBody body;
+  private final Object tag;
+
+  private volatile URL javaNetUrl; // Lazily initialized.
+  private volatile URI javaNetUri; // Lazily initialized.
+  private volatile CacheControl cacheControl; // Lazily initialized.
+
+  private Request(Builder builder) {
+    this.url = builder.url;
+    this.method = builder.method;
+    this.headers = builder.headers.build();
+    this.body = builder.body;
+    this.tag = builder.tag != null ? builder.tag : this;
+  }
+
+  public HttpUrl httpUrl() {
+    return url;
+  }
+
+  public URL url() {
+    URL result = javaNetUrl;
+    return result != null ? result : (javaNetUrl = url.url());
+  }
+
+  public URI uri() throws IOException {
+    try {
+      URI result = javaNetUri;
+      return result != null ? result : (javaNetUri = url.uri());
+    } catch (IllegalStateException e) {
+      throw new IOException(e.getMessage());
+    }
+  }
+
+  public String urlString() {
+    return url.toString();
+  }
+
+  public String method() {
+    return method;
+  }
+
+  public Headers headers() {
+    return headers;
+  }
+
+  public String header(String name) {
+    return headers.get(name);
+  }
+
+  public List<String> headers(String name) {
+    return headers.values(name);
+  }
+
+  public RequestBody body() {
+    return body;
+  }
+
+  public Object tag() {
+    return tag;
+  }
+
+  public Builder newBuilder() {
+    return new Builder(this);
+  }
+
+  /**
+   * Returns the cache control directives for this response. This is never null,
+   * even if this response contains no {@code Cache-Control} header.
+   */
+  public CacheControl cacheControl() {
+    CacheControl result = cacheControl;
+    return result != null ? result : (cacheControl = CacheControl.parse(headers));
+  }
+
+  public boolean isHttps() {
+    return url.isHttps();
+  }
+
+  @Override public String toString() {
+    return "Request{method="
+        + method
+        + ", url="
+        + url
+        + ", tag="
+        + (tag != this ? tag : null)
+        + '}';
+  }
+
+  /**
+   * @hide This class is not part of the Android public SDK API
+   */
+  public static class Builder {
+    private HttpUrl url;
+    private String method;
+    private Headers.Builder headers;
+    private RequestBody body;
+    private Object tag;
+
+    public Builder() {
+      this.method = "GET";
+      this.headers = new Headers.Builder();
+    }
+
+    private Builder(Request request) {
+      this.url = request.url;
+      this.method = request.method;
+      this.body = request.body;
+      this.tag = request.tag;
+      this.headers = request.headers.newBuilder();
+    }
+
+    public Builder url(HttpUrl url) {
+      if (url == null) throw new IllegalArgumentException("url == null");
+      this.url = url;
+      return this;
+    }
+
+    /**
+     * Sets the URL target of this request.
+     *
+     * @throws IllegalArgumentException if {@code url} is not a valid HTTP or HTTPS URL. Avoid this
+     *     exception by calling {@link HttpUrl#parse}; it returns null for invalid URLs.
+     */
+    public Builder url(String url) {
+      if (url == null) throw new IllegalArgumentException("url == null");
+
+      // Silently replace websocket URLs with HTTP URLs.
+      if (url.regionMatches(true, 0, "ws:", 0, 3)) {
+        url = "http:" + url.substring(3);
+      } else if (url.regionMatches(true, 0, "wss:", 0, 4)) {
+        url = "https:" + url.substring(4);
+      }
+
+      HttpUrl parsed = HttpUrl.parse(url);
+      if (parsed == null) throw new IllegalArgumentException("unexpected url: " + url);
+      return url(parsed);
+    }
+
+    /**
+     * Sets the URL target of this request.
+     *
+     * @throws IllegalArgumentException if the scheme of {@code url} is not {@code http} or {@code
+     *     https}.
+     */
+    public Builder url(URL url) {
+      if (url == null) throw new IllegalArgumentException("url == null");
+      HttpUrl parsed = HttpUrl.get(url);
+      if (parsed == null) throw new IllegalArgumentException("unexpected url: " + url);
+      return url(parsed);
+    }
+
+    /**
+     * Sets the header named {@code name} to {@code value}. If this request
+     * already has any headers with that name, they are all replaced.
+     */
+    public Builder header(String name, String value) {
+      headers.set(name, value);
+      return this;
+    }
+
+    /**
+     * Adds a header with {@code name} and {@code value}. Prefer this method for
+     * multiply-valued headers like "Cookie".
+     *
+     * <p>Note that for some headers including {@code Content-Length} and {@code Content-Encoding},
+     * OkHttp may replace {@code value} with a header derived from the request body.
+     */
+    public Builder addHeader(String name, String value) {
+      headers.add(name, value);
+      return this;
+    }
+
+    public Builder removeHeader(String name) {
+      headers.removeAll(name);
+      return this;
+    }
+
+    /** Removes all headers on this builder and adds {@code headers}. */
+    public Builder headers(Headers headers) {
+      this.headers = headers.newBuilder();
+      return this;
+    }
+
+    /**
+     * Sets this request's {@code Cache-Control} header, replacing any cache
+     * control headers already present. If {@code cacheControl} doesn't define
+     * any directives, this clears this request's cache-control headers.
+     */
+    public Builder cacheControl(CacheControl cacheControl) {
+      String value = cacheControl.toString();
+      if (value.isEmpty()) return removeHeader("Cache-Control");
+      return header("Cache-Control", value);
+    }
+
+    public Builder get() {
+      return method("GET", null);
+    }
+
+    public Builder head() {
+      return method("HEAD", null);
+    }
+
+    public Builder post(RequestBody body) {
+      return method("POST", body);
+    }
+
+    public Builder delete(RequestBody body) {
+      return method("DELETE", body);
+    }
+
+    public Builder delete() {
+      return delete(RequestBody.create(null, new byte[0]));
+    }
+
+    public Builder put(RequestBody body) {
+      return method("PUT", body);
+    }
+
+    public Builder patch(RequestBody body) {
+      return method("PATCH", body);
+    }
+
+    public Builder method(String method, RequestBody body) {
+      if (method == null || method.length() == 0) {
+        throw new IllegalArgumentException("method == null || method.length() == 0");
+      }
+      if (body != null && !HttpMethod.permitsRequestBody(method)) {
+        throw new IllegalArgumentException("method " + method + " must not have a request body.");
+      }
+      if (body == null && HttpMethod.requiresRequestBody(method)) {
+        throw new IllegalArgumentException("method " + method + " must have a request body.");
+      }
+      this.method = method;
+      this.body = body;
+      return this;
+    }
+
+    /**
+     * Attaches {@code tag} to the request. It can be used later to cancel the
+     * request. If the tag is unspecified or null, the request is canceled by
+     * using the request itself as the tag.
+     */
+    public Builder tag(Object tag) {
+      this.tag = tag;
+      return this;
+    }
+
+    public Request build() {
+      if (url == null) throw new IllegalStateException("url == null");
+      return new Request(this);
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/RequestBody.java b/repackaged/okhttp/src/main/java/com/android/okhttp/RequestBody.java
new file mode 100644
index 0000000..a762d8a
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/RequestBody.java
@@ -0,0 +1,129 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp;
+
+import com.android.okhttp.internal.Util;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import com.android.okhttp.okio.BufferedSink;
+import com.android.okhttp.okio.ByteString;
+import com.android.okhttp.okio.Okio;
+import com.android.okhttp.okio.Source;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class RequestBody {
+  /** Returns the Content-Type header for this body. */
+  public abstract MediaType contentType();
+
+  /**
+   * Returns the number of bytes that will be written to {@code out} in a call
+   * to {@link #writeTo}, or -1 if that count is unknown.
+   */
+  public long contentLength() throws IOException {
+    return -1;
+  }
+
+  /** Writes the content of this request to {@code out}. */
+  public abstract void writeTo(BufferedSink sink) throws IOException;
+
+  /**
+   * Returns a new request body that transmits {@code content}. If {@code
+   * contentType} is non-null and lacks a charset, this will use UTF-8.
+   */
+  public static RequestBody create(MediaType contentType, String content) {
+    Charset charset = Util.UTF_8;
+    if (contentType != null) {
+      charset = contentType.charset();
+      if (charset == null) {
+        charset = Util.UTF_8;
+        contentType = MediaType.parse(contentType + "; charset=utf-8");
+      }
+    }
+    byte[] bytes = content.getBytes(charset);
+    return create(contentType, bytes);
+  }
+
+  /** Returns a new request body that transmits {@code content}. */
+  public static RequestBody create(final MediaType contentType, final ByteString content) {
+    return new RequestBody() {
+      @Override public MediaType contentType() {
+        return contentType;
+      }
+
+      @Override public long contentLength() throws IOException {
+        return content.size();
+      }
+
+      @Override public void writeTo(BufferedSink sink) throws IOException {
+        sink.write(content);
+      }
+    };
+  }
+
+  /** Returns a new request body that transmits {@code content}. */
+  public static RequestBody create(final MediaType contentType, final byte[] content) {
+    return create(contentType, content, 0, content.length);
+  }
+
+  /** Returns a new request body that transmits {@code content}. */
+  public static RequestBody create(final MediaType contentType, final byte[] content,
+      final int offset, final int byteCount) {
+    if (content == null) throw new NullPointerException("content == null");
+    Util.checkOffsetAndCount(content.length, offset, byteCount);
+    return new RequestBody() {
+      @Override public MediaType contentType() {
+        return contentType;
+      }
+
+      @Override public long contentLength() {
+        return byteCount;
+      }
+
+      @Override public void writeTo(BufferedSink sink) throws IOException {
+        sink.write(content, offset, byteCount);
+      }
+    };
+  }
+
+  /** Returns a new request body that transmits the content of {@code file}. */
+  public static RequestBody create(final MediaType contentType, final File file) {
+    if (file == null) throw new NullPointerException("content == null");
+
+    return new RequestBody() {
+      @Override public MediaType contentType() {
+        return contentType;
+      }
+
+      @Override public long contentLength() {
+        return file.length();
+      }
+
+      @Override public void writeTo(BufferedSink sink) throws IOException {
+        Source source = null;
+        try {
+          source = Okio.source(file);
+          sink.writeAll(source);
+        } finally {
+          Util.closeQuietly(source);
+        }
+      }
+    };
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/Response.java b/repackaged/okhttp/src/main/java/com/android/okhttp/Response.java
new file mode 100644
index 0000000..f4bba1b
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/Response.java
@@ -0,0 +1,357 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.okhttp;
+
+import com.android.okhttp.internal.http.OkHeaders;
+import java.util.Collections;
+import java.util.List;
+
+import static com.android.okhttp.internal.http.StatusLine.HTTP_PERM_REDIRECT;
+import static com.android.okhttp.internal.http.StatusLine.HTTP_TEMP_REDIRECT;
+import static java.net.HttpURLConnection.HTTP_MOVED_PERM;
+import static java.net.HttpURLConnection.HTTP_MOVED_TEMP;
+import static java.net.HttpURLConnection.HTTP_MULT_CHOICE;
+import static java.net.HttpURLConnection.HTTP_PROXY_AUTH;
+import static java.net.HttpURLConnection.HTTP_SEE_OTHER;
+import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
+
+/**
+ * An HTTP response. Instances of this class are not immutable: the response
+ * body is a one-shot value that may be consumed only once. All other properties
+ * are immutable.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Response {
+  private final Request request;
+  private final Protocol protocol;
+  private final int code;
+  private final String message;
+  private final Handshake handshake;
+  private final Headers headers;
+  private final ResponseBody body;
+  private Response networkResponse;
+  private Response cacheResponse;
+  private final Response priorResponse;
+
+  private volatile CacheControl cacheControl; // Lazily initialized.
+
+  private Response(Builder builder) {
+    this.request = builder.request;
+    this.protocol = builder.protocol;
+    this.code = builder.code;
+    this.message = builder.message;
+    this.handshake = builder.handshake;
+    this.headers = builder.headers.build();
+    this.body = builder.body;
+    this.networkResponse = builder.networkResponse;
+    this.cacheResponse = builder.cacheResponse;
+    this.priorResponse = builder.priorResponse;
+  }
+
+  /**
+   * The wire-level request that initiated this HTTP response. This is not
+   * necessarily the same request issued by the application:
+   * <ul>
+   *     <li>It may be transformed by the HTTP client. For example, the client
+   *         may copy headers like {@code Content-Length} from the request body.
+   *     <li>It may be the request generated in response to an HTTP redirect or
+   *         authentication challenge. In this case the request URL may be
+   *         different than the initial request URL.
+   * </ul>
+   */
+  public Request request() {
+    return request;
+  }
+
+  /**
+   * Returns the HTTP protocol, such as {@link Protocol#HTTP_1_1} or {@link
+   * Protocol#HTTP_1_0}.
+   */
+  public Protocol protocol() {
+    return protocol;
+  }
+
+  /** Returns the HTTP status code. */
+  public int code() {
+    return code;
+  }
+
+  /**
+   * Returns true if the code is in [200..300), which means the request was
+   * successfully received, understood, and accepted.
+   */
+  public boolean isSuccessful() {
+    return code >= 200 && code < 300;
+  }
+
+  /** Returns the HTTP status message or null if it is unknown. */
+  public String message() {
+    return message;
+  }
+
+  /**
+   * Returns the TLS handshake of the connection that carried this response, or
+   * null if the response was received without TLS.
+   */
+  public Handshake handshake() {
+    return handshake;
+  }
+
+  public List<String> headers(String name) {
+    return headers.values(name);
+  }
+
+  public String header(String name) {
+    return header(name, null);
+  }
+
+  public String header(String name, String defaultValue) {
+    String result = headers.get(name);
+    return result != null ? result : defaultValue;
+  }
+
+  public Headers headers() {
+    return headers;
+  }
+
+  public ResponseBody body() {
+    return body;
+  }
+
+  public Builder newBuilder() {
+    return new Builder(this);
+  }
+
+  /** Returns true if this response redirects to another resource. */
+  public boolean isRedirect() {
+    switch (code) {
+      case HTTP_PERM_REDIRECT:
+      case HTTP_TEMP_REDIRECT:
+      case HTTP_MULT_CHOICE:
+      case HTTP_MOVED_PERM:
+      case HTTP_MOVED_TEMP:
+      case HTTP_SEE_OTHER:
+        return true;
+      default:
+        return false;
+    }
+  }
+
+  /**
+   * Returns the raw response received from the network. Will be null if this
+   * response didn't use the network, such as when the response is fully cached.
+   * The body of the returned response should not be read.
+   */
+  public Response networkResponse() {
+    return networkResponse;
+  }
+
+  /**
+   * Returns the raw response received from the cache. Will be null if this
+   * response didn't use the cache. For conditional get requests the cache
+   * response and network response may both be non-null. The body of the
+   * returned response should not be read.
+   */
+  public Response cacheResponse() {
+    return cacheResponse;
+  }
+
+  /**
+   * Returns the response for the HTTP redirect or authorization challenge that
+   * triggered this response, or null if this response wasn't triggered by an
+   * automatic retry. The body of the returned response should not be read
+   * because it has already been consumed by the redirecting client.
+   */
+  public Response priorResponse() {
+    return priorResponse;
+  }
+
+  /**
+   * Returns the authorization challenges appropriate for this response's code.
+   * If the response code is 401 unauthorized, this returns the
+   * "WWW-Authenticate" challenges. If the response code is 407 proxy
+   * unauthorized, this returns the "Proxy-Authenticate" challenges. Otherwise
+   * this returns an empty list of challenges.
+   */
+  public List<Challenge> challenges() {
+    String responseField;
+    if (code == HTTP_UNAUTHORIZED) {
+      responseField = "WWW-Authenticate";
+    } else if (code == HTTP_PROXY_AUTH) {
+      responseField = "Proxy-Authenticate";
+    } else {
+      return Collections.emptyList();
+    }
+    return OkHeaders.parseChallenges(headers(), responseField);
+  }
+
+  /**
+   * Returns the cache control directives for this response. This is never null,
+   * even if this response contains no {@code Cache-Control} header.
+   */
+  public CacheControl cacheControl() {
+    CacheControl result = cacheControl;
+    return result != null ? result : (cacheControl = CacheControl.parse(headers));
+  }
+
+  @Override public String toString() {
+    return "Response{protocol="
+        + protocol
+        + ", code="
+        + code
+        + ", message="
+        + message
+        + ", url="
+        + request.urlString()
+        + '}';
+  }
+
+  /**
+   * @hide This class is not part of the Android public SDK API
+   */
+  public static class Builder {
+    private Request request;
+    private Protocol protocol;
+    private int code = -1;
+    private String message;
+    private Handshake handshake;
+    private Headers.Builder headers;
+    private ResponseBody body;
+    private Response networkResponse;
+    private Response cacheResponse;
+    private Response priorResponse;
+
+    public Builder() {
+      headers = new Headers.Builder();
+    }
+
+    private Builder(Response response) {
+      this.request = response.request;
+      this.protocol = response.protocol;
+      this.code = response.code;
+      this.message = response.message;
+      this.handshake = response.handshake;
+      this.headers = response.headers.newBuilder();
+      this.body = response.body;
+      this.networkResponse = response.networkResponse;
+      this.cacheResponse = response.cacheResponse;
+      this.priorResponse = response.priorResponse;
+    }
+
+    public Builder request(Request request) {
+      this.request = request;
+      return this;
+    }
+
+    public Builder protocol(Protocol protocol) {
+      this.protocol = protocol;
+      return this;
+    }
+
+    public Builder code(int code) {
+      this.code = code;
+      return this;
+    }
+
+    public Builder message(String message) {
+      this.message = message;
+      return this;
+    }
+
+    public Builder handshake(Handshake handshake) {
+      this.handshake = handshake;
+      return this;
+    }
+
+    /**
+     * Sets the header named {@code name} to {@code value}. If this request
+     * already has any headers with that name, they are all replaced.
+     */
+    public Builder header(String name, String value) {
+      headers.set(name, value);
+      return this;
+    }
+
+    /**
+     * Adds a header with {@code name} and {@code value}. Prefer this method for
+     * multiply-valued headers like "Set-Cookie".
+     */
+    public Builder addHeader(String name, String value) {
+      headers.add(name, value);
+      return this;
+    }
+
+    public Builder removeHeader(String name) {
+      headers.removeAll(name);
+      return this;
+    }
+
+    /** Removes all headers on this builder and adds {@code headers}. */
+    public Builder headers(Headers headers) {
+      this.headers = headers.newBuilder();
+      return this;
+    }
+
+    public Builder body(ResponseBody body) {
+      this.body = body;
+      return this;
+    }
+
+    public Builder networkResponse(Response networkResponse) {
+      if (networkResponse != null) checkSupportResponse("networkResponse", networkResponse);
+      this.networkResponse = networkResponse;
+      return this;
+    }
+
+    public Builder cacheResponse(Response cacheResponse) {
+      if (cacheResponse != null) checkSupportResponse("cacheResponse", cacheResponse);
+      this.cacheResponse = cacheResponse;
+      return this;
+    }
+
+    private void checkSupportResponse(String name, Response response) {
+      if (response.body != null) {
+        throw new IllegalArgumentException(name + ".body != null");
+      } else if (response.networkResponse != null) {
+        throw new IllegalArgumentException(name + ".networkResponse != null");
+      } else if (response.cacheResponse != null) {
+        throw new IllegalArgumentException(name + ".cacheResponse != null");
+      } else if (response.priorResponse != null) {
+        throw new IllegalArgumentException(name + ".priorResponse != null");
+      }
+    }
+
+    public Builder priorResponse(Response priorResponse) {
+      if (priorResponse != null) checkPriorResponse(priorResponse);
+      this.priorResponse = priorResponse;
+      return this;
+    }
+
+    private void checkPriorResponse(Response response) {
+      if (response.body != null) {
+        throw new IllegalArgumentException("priorResponse.body != null");
+      }
+    }
+
+    public Response build() {
+      if (request == null) throw new IllegalStateException("request == null");
+      if (protocol == null) throw new IllegalStateException("protocol == null");
+      if (code < 0) throw new IllegalStateException("code < 0: " + code);
+      return new Response(this);
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/ResponseBody.java b/repackaged/okhttp/src/main/java/com/android/okhttp/ResponseBody.java
new file mode 100644
index 0000000..2596a3a
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/ResponseBody.java
@@ -0,0 +1,140 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp;
+
+import com.android.okhttp.internal.Util;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.Charset;
+import com.android.okhttp.okio.Buffer;
+import com.android.okhttp.okio.BufferedSource;
+
+import static com.android.okhttp.internal.Util.UTF_8;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class ResponseBody implements Closeable {
+  /** Multiple calls to {@link #charStream()} must return the same instance. */
+  private Reader reader;
+
+  public abstract MediaType contentType();
+
+  /**
+   * Returns the number of bytes in that will returned by {@link #bytes}, or
+   * {@link #byteStream}, or -1 if unknown.
+   */
+  public abstract long contentLength() throws IOException;
+
+  public final InputStream byteStream() throws IOException {
+    return source().inputStream();
+  }
+
+  public abstract BufferedSource source() throws IOException;
+
+  public final byte[] bytes() throws IOException {
+    long contentLength = contentLength();
+    if (contentLength > Integer.MAX_VALUE) {
+      throw new IOException("Cannot buffer entire body for content length: " + contentLength);
+    }
+
+    BufferedSource source = source();
+    byte[] bytes;
+    try {
+      bytes = source.readByteArray();
+    } finally {
+      Util.closeQuietly(source);
+    }
+    if (contentLength != -1 && contentLength != bytes.length) {
+      throw new IOException("Content-Length and stream length disagree");
+    }
+    return bytes;
+  }
+
+  /**
+   * Returns the response as a character stream decoded with the charset
+   * of the Content-Type header. If that header is either absent or lacks a
+   * charset, this will attempt to decode the response body as UTF-8.
+   */
+  public final Reader charStream() throws IOException {
+    Reader r = reader;
+    return r != null ? r : (reader = new InputStreamReader(byteStream(), charset()));
+  }
+
+  /**
+   * Returns the response as a string decoded with the charset of the
+   * Content-Type header. If that header is either absent or lacks a charset,
+   * this will attempt to decode the response body as UTF-8.
+   */
+  public final String string() throws IOException {
+    return new String(bytes(), charset().name());
+  }
+
+  private Charset charset() {
+    MediaType contentType = contentType();
+    return contentType != null ? contentType.charset(UTF_8) : UTF_8;
+  }
+
+  @Override public void close() throws IOException {
+    source().close();
+  }
+
+  /**
+   * Returns a new response body that transmits {@code content}. If {@code
+   * contentType} is non-null and lacks a charset, this will use UTF-8.
+   */
+  public static ResponseBody create(MediaType contentType, String content) {
+    Charset charset = Util.UTF_8;
+    if (contentType != null) {
+      charset = contentType.charset();
+      if (charset == null) {
+        charset = Util.UTF_8;
+        contentType = MediaType.parse(contentType + "; charset=utf-8");
+      }
+    }
+    Buffer buffer = new Buffer().writeString(content, charset);
+    return create(contentType, buffer.size(), buffer);
+  }
+
+  /** Returns a new response body that transmits {@code content}. */
+  public static ResponseBody create(final MediaType contentType, byte[] content) {
+    Buffer buffer = new Buffer().write(content);
+    return create(contentType, content.length, buffer);
+  }
+
+  /** Returns a new response body that transmits {@code content}. */
+  public static ResponseBody create(
+      final MediaType contentType, final long contentLength, final BufferedSource content) {
+    if (content == null) throw new NullPointerException("source == null");
+    return new ResponseBody() {
+      @Override public MediaType contentType() {
+        return contentType;
+      }
+
+      @Override public long contentLength() {
+        return contentLength;
+      }
+
+      @Override public BufferedSource source() {
+        return content;
+      }
+    };
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/Route.java b/repackaged/okhttp/src/main/java/com/android/okhttp/Route.java
new file mode 100644
index 0000000..ba33f86
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/Route.java
@@ -0,0 +1,100 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.okhttp;
+
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+
+/**
+ * The concrete route used by a connection to reach an abstract origin server.
+ * When creating a connection the client has many options:
+ * <ul>
+ *   <li><strong>HTTP proxy:</strong> a proxy server may be explicitly
+ *       configured for the client. Otherwise the {@linkplain java.net.ProxySelector
+ *       proxy selector} is used. It may return multiple proxies to attempt.
+ *   <li><strong>IP address:</strong> whether connecting directly to an origin
+ *       server or a proxy, opening a socket requires an IP address. The DNS
+ *       server may return multiple IP addresses to attempt.
+ * </ul>
+ * Each route is a specific selection of these options.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Route {
+  final Address address;
+  final Proxy proxy;
+  final InetSocketAddress inetSocketAddress;
+
+  public Route(Address address, Proxy proxy, InetSocketAddress inetSocketAddress) {
+    if (address == null) {
+      throw new NullPointerException("address == null");
+    }
+    if (proxy == null) {
+      throw new NullPointerException("proxy == null");
+    }
+    if (inetSocketAddress == null) {
+      throw new NullPointerException("inetSocketAddress == null");
+    }
+    this.address = address;
+    this.proxy = proxy;
+    this.inetSocketAddress = inetSocketAddress;
+  }
+
+  public Address getAddress() {
+    return address;
+  }
+
+  /**
+   * Returns the {@link Proxy} of this route.
+   *
+   * <strong>Warning:</strong> This may disagree with {@link Address#getProxy}
+   * when it is null. When the address's proxy is null, the proxy selector is
+   * used.
+   */
+  public Proxy getProxy() {
+    return proxy;
+  }
+
+  public InetSocketAddress getSocketAddress() {
+    return inetSocketAddress;
+  }
+
+  /**
+   * Returns true if this route tunnels HTTPS through an HTTP proxy. See <a
+   * href="http://www.ietf.org/rfc/rfc2817.txt">RFC 2817, Section 5.2</a>.
+   */
+  public boolean requiresTunnel() {
+    return address.sslSocketFactory != null && proxy.type() == Proxy.Type.HTTP;
+  }
+
+  @Override public boolean equals(Object obj) {
+    if (obj instanceof Route) {
+      Route other = (Route) obj;
+      return address.equals(other.address)
+          && proxy.equals(other.proxy)
+          && inetSocketAddress.equals(other.inetSocketAddress);
+    }
+    return false;
+  }
+
+  @Override public int hashCode() {
+    int result = 17;
+    result = 31 * result + address.hashCode();
+    result = 31 * result + proxy.hashCode();
+    result = 31 * result + inetSocketAddress.hashCode();
+    return result;
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/TlsVersion.java b/repackaged/okhttp/src/main/java/com/android/okhttp/TlsVersion.java
new file mode 100644
index 0000000..c8cd1e3
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/TlsVersion.java
@@ -0,0 +1,52 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp;
+
+import javax.net.ssl.SSLSocket;
+
+/**
+ * Versions of TLS that can be offered when negotiating a secure socket. See
+ * {@link SSLSocket#setEnabledProtocols}.
+ * @hide This class is not part of the Android public SDK API
+ */
+public enum TlsVersion {
+  TLS_1_2("TLSv1.2"), // 2008.
+  TLS_1_1("TLSv1.1"), // 2006.
+  TLS_1_0("TLSv1"),   // 1999.
+  SSL_3_0("SSLv3"),   // 1996.
+  ;
+
+  final String javaName;
+
+  TlsVersion(String javaName) {
+    this.javaName = javaName;
+  }
+
+  public static TlsVersion forJavaName(String javaName) {
+    switch (javaName) {
+      case "TLSv1.2": return TLS_1_2;
+      case "TLSv1.1": return TLS_1_1;
+      case "TLSv1": return TLS_1_0;
+      case "SSLv3": return SSL_3_0;
+    }
+    throw new IllegalArgumentException("Unexpected TLS version: " + javaName);
+  }
+
+  public String javaName() {
+    return javaName;
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/ConnectionSpecSelector.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/ConnectionSpecSelector.java
new file mode 100644
index 0000000..c91a00a
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/ConnectionSpecSelector.java
@@ -0,0 +1,145 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.okhttp.internal;
+
+import com.android.okhttp.ConnectionSpec;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.ProtocolException;
+import java.net.UnknownServiceException;
+import java.security.cert.CertificateException;
+import java.util.Arrays;
+import java.util.List;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLProtocolException;
+import javax.net.ssl.SSLSocket;
+
+/**
+ * Handles the connection spec fallback strategy: When a secure socket connection fails
+ * due to a handshake / protocol problem the connection may be retried with different protocols.
+ * Instances are stateful and should be created and used for a single connection attempt.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class ConnectionSpecSelector {
+
+  private final List<ConnectionSpec> connectionSpecs;
+  private int nextModeIndex;
+  private boolean isFallbackPossible;
+  private boolean isFallback;
+
+  public ConnectionSpecSelector(List<ConnectionSpec> connectionSpecs) {
+    this.nextModeIndex = 0;
+    this.connectionSpecs = connectionSpecs;
+  }
+
+  /**
+   * Configures the supplied {@link SSLSocket} to connect to the specified host using an appropriate
+   * {@link ConnectionSpec}. Returns the chosen {@link ConnectionSpec}, never {@code null}.
+   *
+   * @throws IOException if the socket does not support any of the TLS modes available
+   */
+  public ConnectionSpec configureSecureSocket(SSLSocket sslSocket) throws IOException {
+    ConnectionSpec tlsConfiguration = null;
+    for (int i = nextModeIndex, size = connectionSpecs.size(); i < size; i++) {
+      ConnectionSpec connectionSpec = connectionSpecs.get(i);
+      if (connectionSpec.isCompatible(sslSocket)) {
+        tlsConfiguration = connectionSpec;
+        nextModeIndex = i + 1;
+        break;
+      }
+    }
+
+    if (tlsConfiguration == null) {
+      // This may be the first time a connection has been attempted and the socket does not support
+      // any the required protocols, or it may be a retry (but this socket supports fewer
+      // protocols than was suggested by a prior socket).
+      throw new UnknownServiceException(
+          "Unable to find acceptable protocols. isFallback=" + isFallback
+              + ", modes=" + connectionSpecs
+              + ", supported protocols=" + Arrays.toString(sslSocket.getEnabledProtocols()));
+    }
+
+    isFallbackPossible = isFallbackPossible(sslSocket);
+
+    Internal.instance.apply(tlsConfiguration, sslSocket, isFallback);
+
+    return tlsConfiguration;
+  }
+
+  /**
+   * Reports a failure to complete a connection. Determines the next {@link ConnectionSpec} to
+   * try, if any.
+   *
+   * @return {@code true} if the connection should be retried using
+   *     {@link #configureSecureSocket(SSLSocket)} or {@code false} if not
+   */
+  public boolean connectionFailed(IOException e) {
+    // Any future attempt to connect using this strategy will be a fallback attempt.
+    isFallback = true;
+
+    if (!isFallbackPossible) {
+      return false;
+    }
+
+    // If there was a protocol problem, don't recover.
+    if (e instanceof ProtocolException) {
+      return false;
+    }
+
+    // If there was an interruption or timeout (SocketTimeoutException), don't recover.
+    // For the socket connect timeout case we do not try the same host with a different
+    // ConnectionSpec: we assume it is unreachable.
+    if (e instanceof InterruptedIOException) {
+      return false;
+    }
+
+    // Look for known client-side or negotiation errors that are unlikely to be fixed by trying
+    // again with a different connection spec.
+    if (e instanceof SSLHandshakeException) {
+      // If the problem was a CertificateException from the X509TrustManager,
+      // do not retry.
+      if (e.getCause() instanceof CertificateException) {
+        return false;
+      }
+    }
+    if (e instanceof SSLPeerUnverifiedException) {
+      // e.g. a certificate pinning error.
+      return false;
+    }
+
+
+    // On Android, SSLProtocolExceptions can be caused by TLS_FALLBACK_SCSV failures, which means we
+    // retry those when we probably should not.
+    return (e instanceof SSLHandshakeException || e instanceof SSLProtocolException);
+  }
+
+  /**
+   * Returns {@code true} if any later {@link ConnectionSpec} in the fallback strategy looks
+   * possible based on the supplied {@link SSLSocket}. It assumes that a future socket will have the
+   * same capabilities as the supplied socket.
+   */
+  private boolean isFallbackPossible(SSLSocket socket) {
+    for (int i = nextModeIndex; i < connectionSpecs.size(); i++) {
+      if (connectionSpecs.get(i).isCompatible(socket)) {
+        return true;
+      }
+    }
+    return false;
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/DiskLruCache.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/DiskLruCache.java
new file mode 100644
index 0000000..2169de9
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/DiskLruCache.java
@@ -0,0 +1,1048 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.okhttp.internal;
+
+import com.android.okhttp.internal.io.FileSystem;
+import java.io.Closeable;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.NoSuchElementException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import com.android.okhttp.okio.Buffer;
+import com.android.okhttp.okio.BufferedSink;
+import com.android.okhttp.okio.BufferedSource;
+import com.android.okhttp.okio.Okio;
+import com.android.okhttp.okio.Sink;
+import com.android.okhttp.okio.Source;
+import com.android.okhttp.okio.Timeout;
+
+/**
+ * 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. Each key must match
+ * the regex <strong>[a-z0-9_-]{1,64}</strong>. 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.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class DiskLruCache implements Closeable {
+  static final String JOURNAL_FILE = "journal";
+  static final String JOURNAL_FILE_TEMP = "journal.tmp";
+  static final String JOURNAL_FILE_BACKUP = "journal.bkp";
+  static final String MAGIC = "libcore.io.DiskLruCache";
+  static final String VERSION_1 = "1";
+  static final long ANY_SEQUENCE_NUMBER = -1;
+  static final Pattern LEGAL_KEY_PATTERN = Pattern.compile("[a-z0-9_-]{1,120}");
+  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 FileSystem fileSystem;
+  private final File directory;
+  private final File journalFile;
+  private final File journalFileTmp;
+  private final File journalFileBackup;
+  private final int appVersion;
+  private long maxSize;
+  private final int valueCount;
+  private long size = 0;
+  private BufferedSink journalWriter;
+  private final LinkedHashMap<String, Entry> lruEntries = new LinkedHashMap<>(0, 0.75f, true);
+  private int redundantOpCount;
+  private boolean hasJournalErrors;
+
+  // Must be read and written when synchronized on 'this'.
+  private boolean initialized;
+  private boolean closed;
+
+  /**
+   * 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;
+
+  /** Used to run 'cleanupRunnable' for journal rebuilds. */
+  private final Executor executor;
+  private final Runnable cleanupRunnable = new Runnable() {
+    public void run() {
+      synchronized (DiskLruCache.this) {
+        if (!initialized | closed) {
+          return; // Nothing to do
+        }
+        try {
+          trimToSize();
+          if (journalRebuildRequired()) {
+            rebuildJournal();
+            redundantOpCount = 0;
+          }
+        } catch (IOException e) {
+          throw new RuntimeException(e);
+        }
+      }
+    }
+  };
+
+  DiskLruCache(FileSystem fileSystem, File directory, int appVersion, int valueCount, long maxSize,
+      Executor executor) {
+    this.fileSystem = fileSystem;
+    this.directory = directory;
+    this.appVersion = appVersion;
+    this.journalFile = new File(directory, JOURNAL_FILE);
+    this.journalFileTmp = new File(directory, JOURNAL_FILE_TEMP);
+    this.journalFileBackup = new File(directory, JOURNAL_FILE_BACKUP);
+    this.valueCount = valueCount;
+    this.maxSize = maxSize;
+    this.executor = executor;
+  }
+
+  public synchronized void initialize() throws IOException {
+    assert Thread.holdsLock(this);
+
+    if (initialized) {
+      return; // Already initialized.
+    }
+
+    // If a bkp file exists, use it instead.
+    if (fileSystem.exists(journalFileBackup)) {
+      // If journal file also exists just delete backup file.
+      if (fileSystem.exists(journalFile)) {
+        fileSystem.delete(journalFileBackup);
+      } else {
+        fileSystem.rename(journalFileBackup, journalFile);
+      }
+    }
+
+    // Prefer to pick up where we left off.
+    if (fileSystem.exists(journalFile)) {
+      try {
+        readJournal();
+        processJournal();
+        initialized = true;
+        return;
+      } catch (IOException journalIsCorrupt) {
+        Platform.get().logW("DiskLruCache " + directory + " is corrupt: "
+            + journalIsCorrupt.getMessage() + ", removing");
+        delete();
+        closed = false;
+      }
+    }
+
+    rebuildJournal();
+
+    initialized = true;
+  }
+
+  /**
+   * Create a cache which will reside in {@code directory}. This cache is lazily initialized on
+   * first access and will be created if it does not exist.
+   *
+   * @param directory a writable directory
+   * @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
+   */
+  public static DiskLruCache create(FileSystem fileSystem, File directory, int appVersion,
+      int valueCount, long maxSize) {
+    if (maxSize <= 0) {
+      throw new IllegalArgumentException("maxSize <= 0");
+    }
+    if (valueCount <= 0) {
+      throw new IllegalArgumentException("valueCount <= 0");
+    }
+
+    // Use a single background thread to evict entries.
+    Executor executor = new ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS,
+        new LinkedBlockingQueue<Runnable>(), Util.threadFactory("OkHttp DiskLruCache", true));
+
+    return new DiskLruCache(fileSystem, directory, appVersion, valueCount, maxSize, executor);
+  }
+
+  private void readJournal() throws IOException {
+    BufferedSource source = Okio.buffer(fileSystem.source(journalFile));
+    try {
+      String magic = source.readUtf8LineStrict();
+      String version = source.readUtf8LineStrict();
+      String appVersionString = source.readUtf8LineStrict();
+      String valueCountString = source.readUtf8LineStrict();
+      String blank = source.readUtf8LineStrict();
+      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 + "]");
+      }
+
+      int lineCount = 0;
+      while (true) {
+        try {
+          readJournalLine(source.readUtf8LineStrict());
+          lineCount++;
+        } catch (EOFException endOfJournal) {
+          break;
+        }
+      }
+      redundantOpCount = lineCount - lruEntries.size();
+
+      // If we ended on a truncated line, rebuild the journal before appending to it.
+      if (!source.exhausted()) {
+        rebuildJournal();
+      } else {
+        journalWriter = newJournalWriter();
+      }
+    } finally {
+      Util.closeQuietly(source);
+    }
+  }
+
+  private BufferedSink newJournalWriter() throws FileNotFoundException {
+    Sink fileSink = fileSystem.appendingSink(journalFile);
+    Sink faultHidingSink = new FaultHidingSink(fileSink) {
+      @Override protected void onException(IOException e) {
+        assert (Thread.holdsLock(DiskLruCache.this));
+        hasJournalErrors = true;
+      }
+    };
+    return Okio.buffer(faultHidingSink);
+  }
+
+  private void readJournalLine(String line) throws IOException {
+    int firstSpace = line.indexOf(' ');
+    if (firstSpace == -1) {
+      throw new IOException("unexpected journal line: " + line);
+    }
+
+    int keyBegin = firstSpace + 1;
+    int secondSpace = line.indexOf(' ', keyBegin);
+    final String key;
+    if (secondSpace == -1) {
+      key = line.substring(keyBegin);
+      if (firstSpace == REMOVE.length() && line.startsWith(REMOVE)) {
+        lruEntries.remove(key);
+        return;
+      }
+    } else {
+      key = line.substring(keyBegin, secondSpace);
+    }
+
+    Entry entry = lruEntries.get(key);
+    if (entry == null) {
+      entry = new Entry(key);
+      lruEntries.put(key, entry);
+    }
+
+    if (secondSpace != -1 && firstSpace == CLEAN.length() && line.startsWith(CLEAN)) {
+      String[] parts = line.substring(secondSpace + 1).split(" ");
+      entry.readable = true;
+      entry.currentEditor = null;
+      entry.setLengths(parts);
+    } else if (secondSpace == -1 && firstSpace == DIRTY.length() && line.startsWith(DIRTY)) {
+      entry.currentEditor = new Editor(entry);
+    } else if (secondSpace == -1 && firstSpace == READ.length() && line.startsWith(READ)) {
+      // 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 {
+    fileSystem.delete(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++) {
+          fileSystem.delete(entry.cleanFiles[t]);
+          fileSystem.delete(entry.dirtyFiles[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();
+    }
+
+    BufferedSink writer = Okio.buffer(fileSystem.sink(journalFileTmp));
+    try {
+      writer.writeUtf8(MAGIC).writeByte('\n');
+      writer.writeUtf8(VERSION_1).writeByte('\n');
+      writer.writeDecimalLong(appVersion).writeByte('\n');
+      writer.writeDecimalLong(valueCount).writeByte('\n');
+      writer.writeByte('\n');
+
+      for (Entry entry : lruEntries.values()) {
+        if (entry.currentEditor != null) {
+          writer.writeUtf8(DIRTY).writeByte(' ');
+          writer.writeUtf8(entry.key);
+          writer.writeByte('\n');
+        } else {
+          writer.writeUtf8(CLEAN).writeByte(' ');
+          writer.writeUtf8(entry.key);
+          entry.writeLengths(writer);
+          writer.writeByte('\n');
+        }
+      }
+    } finally {
+      writer.close();
+    }
+
+    if (fileSystem.exists(journalFile)) {
+      fileSystem.rename(journalFile, journalFileBackup);
+    }
+    fileSystem.rename(journalFileTmp, journalFile);
+    fileSystem.delete(journalFileBackup);
+
+    journalWriter = newJournalWriter();
+    hasJournalErrors = false;
+  }
+
+  /**
+   * 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 {
+    initialize();
+
+    checkNotClosed();
+    validateKey(key);
+    Entry entry = lruEntries.get(key);
+    if (entry == null || !entry.readable) return null;
+
+    Snapshot snapshot = entry.snapshot();
+    if (snapshot == null) return null;
+
+    redundantOpCount++;
+    journalWriter.writeUtf8(READ).writeByte(' ').writeUtf8(key).writeByte('\n');
+    if (journalRebuildRequired()) {
+      executor.execute(cleanupRunnable);
+    }
+
+    return snapshot;
+  }
+
+  /**
+   * 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 {
+    initialize();
+
+    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.currentEditor != null) {
+      return null; // Another edit is in progress.
+    }
+
+    // Flush the journal before creating files to prevent file leaks.
+    journalWriter.writeUtf8(DIRTY).writeByte(' ').writeUtf8(key).writeByte('\n');
+    journalWriter.flush();
+
+    if (hasJournalErrors) {
+      return null; // Don't edit; the journal can't be written.
+    }
+
+    if (entry == null) {
+      entry = new Entry(key);
+      lruEntries.put(key, entry);
+    }
+    Editor editor = new Editor(entry);
+    entry.currentEditor = editor;
+    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 synchronized long getMaxSize() {
+    return maxSize;
+  }
+
+  /**
+   * Changes the maximum number of bytes the cache can store and queues a job
+   * to trim the existing store, if necessary.
+   */
+  public synchronized void setMaxSize(long maxSize) {
+    this.maxSize = maxSize;
+    if (initialized) {
+      executor.execute(cleanupRunnable);
+    }
+  }
+
+  /**
+   * 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() throws IOException {
+    initialize();
+    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 (!editor.written[i]) {
+          editor.abort();
+          throw new IllegalStateException("Newly created entry didn't create value for index " + i);
+        }
+        if (!fileSystem.exists(entry.dirtyFiles[i])) {
+          editor.abort();
+          return;
+        }
+      }
+    }
+
+    for (int i = 0; i < valueCount; i++) {
+      File dirty = entry.dirtyFiles[i];
+      if (success) {
+        if (fileSystem.exists(dirty)) {
+          File clean = entry.cleanFiles[i];
+          fileSystem.rename(dirty, clean);
+          long oldLength = entry.lengths[i];
+          long newLength = fileSystem.size(clean);
+          entry.lengths[i] = newLength;
+          size = size - oldLength + newLength;
+        }
+      } else {
+        fileSystem.delete(dirty);
+      }
+    }
+
+    redundantOpCount++;
+    entry.currentEditor = null;
+    if (entry.readable | success) {
+      entry.readable = true;
+      journalWriter.writeUtf8(CLEAN).writeByte(' ');
+      journalWriter.writeUtf8(entry.key);
+      entry.writeLengths(journalWriter);
+      journalWriter.writeByte('\n');
+      if (success) {
+        entry.sequenceNumber = nextSequenceNumber++;
+      }
+    } else {
+      lruEntries.remove(entry.key);
+      journalWriter.writeUtf8(REMOVE).writeByte(' ');
+      journalWriter.writeUtf8(entry.key);
+      journalWriter.writeByte('\n');
+    }
+    journalWriter.flush();
+
+    if (size > maxSize || journalRebuildRequired()) {
+      executor.execute(cleanupRunnable);
+    }
+  }
+
+  /**
+   * 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. If the
+   * entry for {@code key} is currently being edited, that edit will complete
+   * normally but its value will not be stored.
+   *
+   * @return true if an entry was removed.
+   */
+  public synchronized boolean remove(String key) throws IOException {
+    initialize();
+
+    checkNotClosed();
+    validateKey(key);
+    Entry entry = lruEntries.get(key);
+    if (entry == null) return false;
+    return removeEntry(entry);
+  }
+
+  private boolean removeEntry(Entry entry) throws IOException {
+    if (entry.currentEditor != null) {
+      entry.currentEditor.detach(); // Prevent the edit from completing normally.
+    }
+
+    for (int i = 0; i < valueCount; i++) {
+      fileSystem.delete(entry.cleanFiles[i]);
+      size -= entry.lengths[i];
+      entry.lengths[i] = 0;
+    }
+
+    redundantOpCount++;
+    journalWriter.writeUtf8(REMOVE).writeByte(' ').writeUtf8(entry.key).writeByte('\n');
+    lruEntries.remove(entry.key);
+
+    if (journalRebuildRequired()) {
+      executor.execute(cleanupRunnable);
+    }
+
+    return true;
+  }
+
+  /** Returns true if this cache has been closed. */
+  public synchronized boolean isClosed() {
+    return closed;
+  }
+
+  private synchronized void checkNotClosed() {
+    if (isClosed()) {
+      throw new IllegalStateException("cache is closed");
+    }
+  }
+
+  /** Force buffered operations to the filesystem. */
+  public synchronized void flush() throws IOException {
+    if (!initialized) return;
+
+    checkNotClosed();
+    trimToSize();
+    journalWriter.flush();
+  }
+
+  /** Closes this cache. Stored values will remain on the filesystem. */
+  public synchronized void close() throws IOException {
+    if (!initialized || closed) {
+      closed = true;
+      return;
+    }
+    // Copying for safe iteration.
+    for (Entry entry : lruEntries.values().toArray(new Entry[lruEntries.size()])) {
+      if (entry.currentEditor != null) {
+        entry.currentEditor.abort();
+      }
+    }
+    trimToSize();
+    journalWriter.close();
+    journalWriter = null;
+    closed = true;
+  }
+
+  private void trimToSize() throws IOException {
+    while (size > maxSize) {
+      Entry toEvict = lruEntries.values().iterator().next();
+      removeEntry(toEvict);
+    }
+  }
+
+  /**
+   * 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();
+    fileSystem.deleteContents(directory);
+  }
+
+  /**
+   * Deletes all stored values from the cache. In-flight edits will complete
+   * normally but their values will not be stored.
+   */
+  public synchronized void evictAll() throws IOException {
+    initialize();
+    // Copying for safe iteration.
+    for (Entry entry : lruEntries.values().toArray(new Entry[lruEntries.size()])) {
+      removeEntry(entry);
+    }
+  }
+
+  private void validateKey(String key) {
+    Matcher matcher = LEGAL_KEY_PATTERN.matcher(key);
+    if (!matcher.matches()) {
+      throw new IllegalArgumentException(
+          "keys must match regex [a-z0-9_-]{1,120}: \"" + key + "\"");
+    }
+  }
+
+  /**
+   * Returns an iterator over the cache's current entries. This iterator doesn't throw {@code
+   * ConcurrentModificationException}, but if new entries are added while iterating, those new
+   * entries will not be returned by the iterator. If existing entries are removed during iteration,
+   * they will be absent (unless they were already returned).
+   *
+   * <p>If there are I/O problems during iteration, this iterator fails silently. For example, if
+   * the hosting filesystem becomes unreachable, the iterator will omit elements rather than
+   * throwing exceptions.
+   *
+   * <p><strong>The caller must {@link Snapshot#close close}</strong> each snapshot returned by
+   * {@link Iterator#next}. Failing to do so leaks open files!
+   *
+   * <p>The returned iterator supports {@link Iterator#remove}.
+   */
+  public synchronized Iterator<Snapshot> snapshots() throws IOException {
+    initialize();
+    return new Iterator<Snapshot>() {
+      /** Iterate a copy of the entries to defend against concurrent modification errors. */
+      final Iterator<Entry> delegate = new ArrayList<>(lruEntries.values()).iterator();
+
+      /** The snapshot to return from {@link #next}. Null if we haven't computed that yet. */
+      Snapshot nextSnapshot;
+
+      /** The snapshot to remove with {@link #remove}. Null if removal is illegal. */
+      Snapshot removeSnapshot;
+
+      @Override public boolean hasNext() {
+        if (nextSnapshot != null) return true;
+
+        synchronized (DiskLruCache.this) {
+          // If the cache is closed, truncate the iterator.
+          if (closed) return false;
+
+          while (delegate.hasNext()) {
+            Entry entry = delegate.next();
+            Snapshot snapshot = entry.snapshot();
+            if (snapshot == null) continue; // Evicted since we copied the entries.
+            nextSnapshot = snapshot;
+            return true;
+          }
+        }
+
+        return false;
+      }
+
+      @Override public Snapshot next() {
+        if (!hasNext()) throw new NoSuchElementException();
+        removeSnapshot = nextSnapshot;
+        nextSnapshot = null;
+        return removeSnapshot;
+      }
+
+      @Override public void remove() {
+        if (removeSnapshot == null) throw new IllegalStateException("remove() before next()");
+        try {
+          DiskLruCache.this.remove(removeSnapshot.key);
+        } catch (IOException ignored) {
+          // Nothing useful to do here. We failed to remove from the cache. Most likely that's
+          // because we couldn't update the journal, but the cached entry will still be gone.
+        } finally {
+          removeSnapshot = null;
+        }
+      }
+    };
+  }
+
+  /** A snapshot of the values for an entry. 
+   * @hide This class is not part of the Android public SDK API*/
+  public final class Snapshot implements Closeable {
+    private final String key;
+    private final long sequenceNumber;
+    private final Source[] sources;
+    private final long[] lengths;
+
+    private Snapshot(String key, long sequenceNumber, Source[] sources, long[] lengths) {
+      this.key = key;
+      this.sequenceNumber = sequenceNumber;
+      this.sources = sources;
+      this.lengths = lengths;
+    }
+
+    public String key() {
+      return key;
+    }
+
+    /**
+     * 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 Source getSource(int index) {
+      return sources[index];
+    }
+
+    /** Returns the byte length of the value for {@code index}. */
+    public long getLength(int index) {
+      return lengths[index];
+    }
+
+    public void close() {
+      for (Source in : sources) {
+        Util.closeQuietly(in);
+      }
+    }
+  }
+
+  private static final Sink NULL_SINK = new Sink() {
+    @Override public void write(Buffer source, long byteCount) throws IOException {
+      source.skip(byteCount);
+    }
+
+    @Override public void flush() throws IOException {
+    }
+
+    @Override public Timeout timeout() {
+      return Timeout.NONE;
+    }
+
+    @Override public void close() throws IOException {
+    }
+  };
+
+  /** Edits the values for an entry. 
+   * @hide This class is not part of the Android public SDK API*/
+  public final class Editor {
+    private final Entry entry;
+    private final boolean[] written;
+    private boolean done;
+
+    private Editor(Entry entry) {
+      this.entry = entry;
+      this.written = (entry.readable) ? null : new boolean[valueCount];
+    }
+
+    /**
+     * Prevents this editor from completing normally. This is necessary either when the edit causes
+     * an I/O error, or if the target entry is evicted while this editor is active. In either case
+     * we delete the editor's created files and prevent new files from being created. Note that once
+     * an editor has been detached it is possible for another editor to edit the entry.
+     */
+    void detach() {
+      if (entry.currentEditor == this) {
+        for (int i = 0; i < valueCount; i++) {
+          try {
+            fileSystem.delete(entry.dirtyFiles[i]);
+          } catch (IOException e) {
+            // This file is potentially leaked. Not much we can do about that.
+          }
+        }
+        entry.currentEditor = null;
+      }
+    }
+
+    /**
+     * Returns an unbuffered input stream to read the last committed value,
+     * or null if no value has been committed.
+     */
+    public Source newSource(int index) throws IOException {
+      synchronized (DiskLruCache.this) {
+        if (done) {
+          throw new IllegalStateException();
+        }
+        if (!entry.readable || entry.currentEditor != this) {
+          return null;
+        }
+        try {
+          return fileSystem.source(entry.cleanFiles[index]);
+        } catch (FileNotFoundException e) {
+          return 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 Sink newSink(int index) throws IOException {
+      synchronized (DiskLruCache.this) {
+        if (done) {
+          throw new IllegalStateException();
+        }
+        if (entry.currentEditor != this) {
+          return NULL_SINK;
+        }
+        if (!entry.readable) {
+          written[index] = true;
+        }
+        File dirtyFile = entry.dirtyFiles[index];
+        Sink sink;
+        try {
+          sink = fileSystem.sink(dirtyFile);
+        } catch (FileNotFoundException e) {
+          return NULL_SINK;
+        }
+        return new FaultHidingSink(sink) {
+          @Override protected void onException(IOException e) {
+            synchronized (DiskLruCache.this) {
+              detach();
+            }
+          }
+        };
+      }
+    }
+
+    /**
+     * 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 {
+      synchronized (DiskLruCache.this) {
+        if (done) {
+          throw new IllegalStateException();
+        }
+        if (entry.currentEditor == this) {
+          completeEdit(this, true);
+        }
+        done = true;
+      }
+    }
+
+    /**
+     * Aborts this edit. This releases the edit lock so another edit may be
+     * started on the same key.
+     */
+    public void abort() throws IOException {
+      synchronized (DiskLruCache.this) {
+        if (done) {
+          throw new IllegalStateException();
+        }
+        if (entry.currentEditor == this) {
+          completeEdit(this, false);
+        }
+        done = true;
+      }
+    }
+
+    public void abortUnlessCommitted() {
+      synchronized (DiskLruCache.this) {
+        if (!done && entry.currentEditor == this) {
+          try {
+            completeEdit(this, false);
+          } catch (IOException ignored) {
+          }
+        }
+      }
+    }
+  }
+
+  private final class Entry {
+    private final String key;
+
+    /** Lengths of this entry's files. */
+    private final long[] lengths;
+    private final File[] cleanFiles;
+    private final File[] dirtyFiles;
+
+    /** 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;
+
+      lengths = new long[valueCount];
+      cleanFiles = new File[valueCount];
+      dirtyFiles = new File[valueCount];
+
+      // The names are repetitive so re-use the same builder to avoid allocations.
+      StringBuilder fileBuilder = new StringBuilder(key).append('.');
+      int truncateTo = fileBuilder.length();
+      for (int i = 0; i < valueCount; i++) {
+        fileBuilder.append(i);
+        cleanFiles[i] = new File(directory, fileBuilder.toString());
+        fileBuilder.append(".tmp");
+        dirtyFiles[i] = new File(directory, fileBuilder.toString());
+        fileBuilder.setLength(truncateTo);
+      }
+    }
+
+    /** 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);
+      }
+    }
+
+    /** Append space-prefixed lengths to {@code writer}. */
+    void writeLengths(BufferedSink writer) throws IOException {
+      for (long length : lengths) {
+        writer.writeByte(' ').writeDecimalLong(length);
+      }
+    }
+
+    private IOException invalidLengths(String[] strings) throws IOException {
+      throw new IOException("unexpected journal line: " + Arrays.toString(strings));
+    }
+
+    /**
+     * Returns a snapshot of this entry. This opens 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.
+     */
+    Snapshot snapshot() {
+      if (!Thread.holdsLock(DiskLruCache.this)) throw new AssertionError();
+
+      Source[] sources = new Source[valueCount];
+      long[] lengths = this.lengths.clone(); // Defensive copy since these can be zeroed out.
+      try {
+        for (int i = 0; i < valueCount; i++) {
+          sources[i] = fileSystem.source(cleanFiles[i]);
+        }
+        return new Snapshot(key, sequenceNumber, sources, lengths);
+      } catch (FileNotFoundException e) {
+        // A file must have been deleted manually!
+        for (int i = 0; i < valueCount; i++) {
+          if (sources[i] != null) {
+            Util.closeQuietly(sources[i]);
+          } else {
+            break;
+          }
+        }
+        return null;
+      }
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/FaultHidingSink.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/FaultHidingSink.java
new file mode 100644
index 0000000..d76152d
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/FaultHidingSink.java
@@ -0,0 +1,52 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.okhttp.internal;
+
+import java.io.IOException;
+import com.android.okhttp.okio.Buffer;
+import com.android.okhttp.okio.ForwardingSink;
+import com.android.okhttp.okio.Sink;
+
+/** A sink that never throws IOExceptions, even if the underlying sink does. */
+class FaultHidingSink extends ForwardingSink {
+  private boolean hasErrors;
+
+  public FaultHidingSink(Sink delegate) {
+    super(delegate);
+  }
+
+  @Override public void write(Buffer source, long byteCount) throws IOException {
+    if (hasErrors) {
+      source.skip(byteCount);
+      return;
+    }
+    try {
+      super.write(source, byteCount);
+    } catch (IOException e) {
+      hasErrors = true;
+      onException(e);
+    }
+  }
+
+  @Override public void flush() throws IOException {
+    if (hasErrors) return;
+    try {
+      super.flush();
+    } catch (IOException e) {
+      hasErrors = true;
+      onException(e);
+    }
+  }
+
+  @Override public void close() throws IOException {
+    if (hasErrors) return;
+    try {
+      super.close();
+    } catch (IOException e) {
+      hasErrors = true;
+      onException(e);
+    }
+  }
+
+  protected void onException(IOException e) {
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/Internal.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/Internal.java
new file mode 100644
index 0000000..20f937d
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/Internal.java
@@ -0,0 +1,76 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.internal;
+
+import com.android.okhttp.Address;
+import com.android.okhttp.Call;
+import com.android.okhttp.Callback;
+import com.android.okhttp.ConnectionPool;
+import com.android.okhttp.ConnectionSpec;
+import com.android.okhttp.Headers;
+import com.android.okhttp.HttpUrl;
+import com.android.okhttp.OkHttpClient;
+import com.android.okhttp.internal.http.StreamAllocation;
+import com.android.okhttp.internal.io.RealConnection;
+import java.net.MalformedURLException;
+import java.net.UnknownHostException;
+import java.util.logging.Logger;
+import javax.net.ssl.SSLSocket;
+
+/**
+ * Escalate internal APIs in {@code com.squareup.okhttp} so they can be used
+ * from OkHttp's implementation packages. The only implementation of this
+ * interface is in {@link com.android.okhttp.OkHttpClient}.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class Internal {
+  public static final Logger logger = Logger.getLogger(OkHttpClient.class.getName());
+
+  public static void initializeInstanceForTests() {
+    // Needed in tests to ensure that the instance is actually pointing to something.
+    new OkHttpClient();
+  }
+
+  public static Internal instance;
+
+  public abstract void addLenient(Headers.Builder builder, String line);
+
+  public abstract void addLenient(Headers.Builder builder, String name, String value);
+
+  public abstract void setCache(OkHttpClient client, InternalCache internalCache);
+
+  public abstract InternalCache internalCache(OkHttpClient client);
+
+  public abstract RealConnection get(
+      ConnectionPool pool, Address address, StreamAllocation streamAllocation);
+
+  public abstract void put(ConnectionPool pool, RealConnection connection);
+
+  public abstract boolean connectionBecameIdle(ConnectionPool pool, RealConnection connection);
+
+  public abstract RouteDatabase routeDatabase(ConnectionPool connectionPool);
+
+  public abstract void apply(ConnectionSpec tlsConfiguration, SSLSocket sslSocket,
+      boolean isFallback);
+
+  public abstract HttpUrl getHttpUrlChecked(String url)
+      throws MalformedURLException, UnknownHostException;
+
+  // TODO delete the following when web sockets move into the main package.
+  public abstract void callEnqueue(Call call, Callback responseCallback, boolean forWebSocket);
+  public abstract StreamAllocation callEngineGetStreamAllocation(Call call);
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/InternalCache.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/InternalCache.java
new file mode 100644
index 0000000..772e13e
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/InternalCache.java
@@ -0,0 +1,54 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.okhttp.internal;
+
+import com.android.okhttp.Request;
+import com.android.okhttp.Response;
+import com.android.okhttp.internal.http.CacheRequest;
+import com.android.okhttp.internal.http.CacheStrategy;
+import java.io.IOException;
+
+/**
+ * OkHttp's internal cache interface. Applications shouldn't implement this:
+ * instead use {@link com.android.okhttp.Cache}.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface InternalCache {
+  Response get(Request request) throws IOException;
+
+  CacheRequest put(Response response) throws IOException;
+
+  /**
+   * Remove any cache entries for the supplied {@code request}. This is invoked
+   * when the client invalidates the cache, such as when making POST requests.
+   */
+  void remove(Request request) throws IOException;
+
+  /**
+   * Handles a conditional request hit by updating the stored cache response
+   * with the headers from {@code network}. The cached response body is not
+   * updated. If the stored response has changed since {@code cached} was
+   * returned, this does nothing.
+   */
+  void update(Response cached, Response network) throws IOException;
+
+  /** Track an conditional GET that was satisfied by this cache. */
+  void trackConditionalCacheHit();
+
+  /** Track an HTTP response being satisfied with {@code cacheStrategy}. */
+  void trackResponse(CacheStrategy cacheStrategy);
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/NamedRunnable.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/NamedRunnable.java
new file mode 100644
index 0000000..dcaeb91
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/NamedRunnable.java
@@ -0,0 +1,42 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.okhttp.internal;
+
+/**
+ * Runnable implementation which always sets its thread name.
+ * @hide This class is not part of the Android public SDK API
+ */
+public abstract class NamedRunnable implements Runnable {
+  protected final String name;
+
+  public NamedRunnable(String format, Object... args) {
+    this.name = String.format(format, args);
+  }
+
+  @Override public final void run() {
+    String oldName = Thread.currentThread().getName();
+    Thread.currentThread().setName(name);
+    try {
+      execute();
+    } finally {
+      Thread.currentThread().setName(oldName);
+    }
+  }
+
+  protected abstract void execute();
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/OptionalMethod.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/OptionalMethod.java
new file mode 100644
index 0000000..ee2425f
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/OptionalMethod.java
@@ -0,0 +1,177 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  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.android.okhttp.internal;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/**
+ * Duck-typing for methods: Represents a method that may or may not be present on an object.
+ *
+ * @param <T> the type of the object the method might be on, typically an interface or base class
+ */
+class OptionalMethod<T> {
+
+  /** The return type of the method. null means "don't care". */
+  private final Class<?> returnType;
+
+  private final String methodName;
+
+  private final Class[] methodParams;
+
+  /**
+   * Creates an optional method.
+   *
+   * @param returnType the return type to required, null if it does not matter
+   * @param methodName the name of the method
+   * @param methodParams the method parameter types
+   */
+  public OptionalMethod(Class<?> returnType, String methodName, Class... methodParams) {
+    this.returnType = returnType;
+    this.methodName = methodName;
+    this.methodParams = methodParams;
+  }
+
+  /**
+   * Returns true if the method exists on the supplied {@code target}.
+   */
+  public boolean isSupported(T target) {
+    return getMethod(target.getClass()) != null;
+  }
+
+  /**
+   * Invokes the method on {@code target} with {@code args}. If the method does not exist or is not
+   * public then {@code null} is returned. See also
+   * {@link #invokeOptionalWithoutCheckedException(Object, Object...)}.
+   *
+   * @throws IllegalArgumentException if the arguments are invalid
+   * @throws InvocationTargetException if the invocation throws an exception
+   */
+  public Object invokeOptional(T target, Object... args) throws InvocationTargetException {
+    Method m = getMethod(target.getClass());
+    if (m == null) {
+      return null;
+    }
+    try {
+      return m.invoke(target, args);
+    } catch (IllegalAccessException e) {
+      return null;
+    }
+  }
+
+  /**
+   * Invokes the method on {@code target}.  If the method does not exist or is not
+   * public then {@code null} is returned. Any RuntimeException thrown by the method is thrown,
+   * checked exceptions are wrapped in an {@link AssertionError}.
+   *
+   * @throws IllegalArgumentException if the arguments are invalid
+   */
+  public Object invokeOptionalWithoutCheckedException(T target, Object... args) {
+    try {
+      return invokeOptional(target, args);
+    } catch (InvocationTargetException e) {
+      Throwable targetException = e.getTargetException();
+      if (targetException instanceof RuntimeException) {
+        throw (RuntimeException) targetException;
+      }
+      AssertionError error = new AssertionError("Unexpected exception");
+      error.initCause(targetException);
+      throw error;
+    }
+  }
+
+  /**
+   * Invokes the method on {@code target} with {@code args}. Throws an error if the method is not
+   * supported. See also {@link #invokeWithoutCheckedException(Object, Object...)}.
+   *
+   * @throws IllegalArgumentException if the arguments are invalid
+   * @throws InvocationTargetException if the invocation throws an exception
+   */
+  public Object invoke(T target, Object... args) throws InvocationTargetException {
+    Method m = getMethod(target.getClass());
+    if (m == null) {
+      throw new AssertionError("Method " + methodName + " not supported for object " + target);
+    }
+    try {
+      return m.invoke(target, args);
+    } catch (IllegalAccessException e) {
+      // Method should be public: we checked.
+      AssertionError error = new AssertionError("Unexpectedly could not call: " + m);
+      error.initCause(e);
+      throw error;
+    }
+  }
+
+  /**
+   * Invokes the method on {@code target}. Throws an error if the method is not supported. Any
+   * RuntimeException thrown by the method is thrown, checked exceptions are wrapped in
+   * an {@link AssertionError}.
+   *
+   * @throws IllegalArgumentException if the arguments are invalid
+   */
+  public Object invokeWithoutCheckedException(T target, Object... args) {
+    try {
+      return invoke(target, args);
+    } catch (InvocationTargetException e) {
+      Throwable targetException = e.getTargetException();
+      if (targetException instanceof RuntimeException) {
+        throw (RuntimeException) targetException;
+      }
+      AssertionError error = new AssertionError("Unexpected exception");
+      error.initCause(targetException);
+      throw error;
+    }
+  }
+
+  /**
+   * Perform a lookup for the method. No caching.
+   * In order to return a method the method name and arguments must match those specified when
+   * the {@link OptionalMethod} was created. If the return type is specified (i.e. non-null) it
+   * must also be compatible. The method must also be public.
+   */
+  private Method getMethod(Class<?> clazz) {
+    Method method = null;
+    if (methodName != null) {
+      method = getPublicMethod(clazz, methodName, methodParams);
+      if (method != null
+          && returnType != null
+          && !returnType.isAssignableFrom(method.getReturnType())) {
+
+        // If the return type is non-null it must be compatible.
+        method = null;
+      }
+    }
+    return method;
+  }
+
+  private static Method getPublicMethod(Class<?> clazz, String methodName, Class[] parameterTypes) {
+    Method method = null;
+    try {
+      method = clazz.getMethod(methodName, parameterTypes);
+      if ((method.getModifiers() & Modifier.PUBLIC) == 0) {
+        method = null;
+      }
+    } catch (NoSuchMethodException e) {
+      // None.
+    }
+    return method;
+  }
+}
+
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/RouteDatabase.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/RouteDatabase.java
new file mode 100644
index 0000000..afe2317
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/RouteDatabase.java
@@ -0,0 +1,51 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.okhttp.internal;
+
+import com.android.okhttp.Route;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * A blacklist of failed routes to avoid when creating a new connection to a
+ * target address. This is used so that OkHttp can learn from its mistakes: if
+ * there was a failure attempting to connect to a specific IP address or proxy
+ * server, that failure is remembered and alternate routes are preferred.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class RouteDatabase {
+  private final Set<Route> failedRoutes = new LinkedHashSet<>();
+
+  /** Records a failure connecting to {@code failedRoute}. */
+  public synchronized void failed(Route failedRoute) {
+    failedRoutes.add(failedRoute);
+  }
+
+  /** Records success connecting to {@code failedRoute}. */
+  public synchronized void connected(Route route) {
+    failedRoutes.remove(route);
+  }
+
+  /** Returns true if {@code route} has failed recently and should be avoided. */
+  public synchronized boolean shouldPostpone(Route route) {
+    return failedRoutes.contains(route);
+  }
+
+  public synchronized int failedRoutesCount() {
+    return failedRoutes.size();
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/Util.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/Util.java
new file mode 100644
index 0000000..b611109
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/Util.java
@@ -0,0 +1,306 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.okhttp.internal;
+
+import com.android.okhttp.HttpUrl;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Array;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.nio.charset.Charset;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import com.android.okhttp.okio.Buffer;
+import com.android.okhttp.okio.ByteString;
+import com.android.okhttp.okio.Source;
+
+/** Junk drawer of utility methods. 
+ * @hide This class is not part of the Android public SDK API*/
+public final class Util {
+  public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+  public static final String[] EMPTY_STRING_ARRAY = new String[0];
+
+  /** A cheap and type-safe constant for the UTF-8 Charset. */
+  public static final Charset UTF_8 = Charset.forName("UTF-8");
+
+  private Util() {
+  }
+
+  public static void checkOffsetAndCount(long arrayLength, long offset, long count) {
+    if ((offset | count) < 0 || offset > arrayLength || arrayLength - offset < count) {
+      throw new ArrayIndexOutOfBoundsException();
+    }
+  }
+
+  /** 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));
+  }
+
+  /**
+   * Closes {@code closeable}, ignoring any checked exceptions. Does nothing
+   * if {@code closeable} is null.
+   */
+  public static void closeQuietly(Closeable closeable) {
+    if (closeable != null) {
+      try {
+        closeable.close();
+      } catch (RuntimeException rethrown) {
+        throw rethrown;
+      } catch (Exception ignored) {
+      }
+    }
+  }
+
+  /**
+   * Closes {@code socket}, ignoring any checked exceptions. Does nothing if
+   * {@code socket} is null.
+   */
+  public static void closeQuietly(Socket socket) {
+    if (socket != null) {
+      try {
+        socket.close();
+      } catch (AssertionError e) {
+        if (!isAndroidGetsocknameError(e)) throw e;
+      } catch (RuntimeException rethrown) {
+        throw rethrown;
+      } catch (Exception ignored) {
+      }
+    }
+  }
+
+  /**
+   * Closes {@code serverSocket}, ignoring any checked exceptions. Does nothing if
+   * {@code serverSocket} is null.
+   */
+  public static void closeQuietly(ServerSocket serverSocket) {
+    if (serverSocket != null) {
+      try {
+        serverSocket.close();
+      } catch (RuntimeException rethrown) {
+        throw rethrown;
+      } catch (Exception ignored) {
+      }
+    }
+  }
+
+  /**
+   * Closes {@code a} and {@code b}. If either close fails, this completes
+   * the other close and rethrows the first encountered exception.
+   */
+  public static void closeAll(Closeable a, Closeable b) throws IOException {
+    Throwable thrown = null;
+    try {
+      a.close();
+    } catch (Throwable e) {
+      thrown = e;
+    }
+    try {
+      b.close();
+    } catch (Throwable e) {
+      if (thrown == null) thrown = e;
+    }
+    if (thrown == null) return;
+    if (thrown instanceof IOException) throw (IOException) thrown;
+    if (thrown instanceof RuntimeException) throw (RuntimeException) thrown;
+    if (thrown instanceof Error) throw (Error) thrown;
+    throw new AssertionError(thrown);
+  }
+
+  /**
+   * Attempts to exhaust {@code source}, returning true if successful. This is useful when reading
+   * a complete source is helpful, such as when doing so completes a cache body or frees a socket
+   * connection for reuse.
+   */
+  public static boolean discard(Source source, int timeout, TimeUnit timeUnit) {
+    try {
+      return skipAll(source, timeout, timeUnit);
+    } catch (IOException e) {
+      return false;
+    }
+  }
+
+  /**
+   * Reads until {@code in} is exhausted or the deadline has been reached. This is careful to not
+   * extend the deadline if one exists already.
+   */
+  public static boolean skipAll(Source source, int duration, TimeUnit timeUnit) throws IOException {
+    long now = System.nanoTime();
+    long originalDuration = source.timeout().hasDeadline()
+        ? source.timeout().deadlineNanoTime() - now
+        : Long.MAX_VALUE;
+    source.timeout().deadlineNanoTime(now + Math.min(originalDuration, timeUnit.toNanos(duration)));
+    try {
+      Buffer skipBuffer = new Buffer();
+      while (source.read(skipBuffer, 2048) != -1) {
+        skipBuffer.clear();
+      }
+      return true; // Success! The source has been exhausted.
+    } catch (InterruptedIOException e) {
+      return false; // We ran out of time before exhausting the source.
+    } finally {
+      if (originalDuration == Long.MAX_VALUE) {
+        source.timeout().clearDeadline();
+      } else {
+        source.timeout().deadlineNanoTime(now + originalDuration);
+      }
+    }
+  }
+
+  /** Returns a 32 character string containing an MD5 hash of {@code s}. */
+  public static String md5Hex(String s) {
+    try {
+      MessageDigest messageDigest = MessageDigest.getInstance("MD5");
+      byte[] md5bytes = messageDigest.digest(s.getBytes("UTF-8"));
+      return ByteString.of(md5bytes).hex();
+    } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
+      throw new AssertionError(e);
+    }
+  }
+
+  /** Returns a Base 64-encoded string containing a SHA-1 hash of {@code s}. */
+  public static String shaBase64(String s) {
+    try {
+      MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
+      byte[] sha1Bytes = messageDigest.digest(s.getBytes("UTF-8"));
+      return ByteString.of(sha1Bytes).base64();
+    } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
+      throw new AssertionError(e);
+    }
+  }
+
+  /** Returns a SHA-1 hash of {@code s}. */
+  public static ByteString sha1(ByteString s) {
+    try {
+      MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
+      byte[] sha1Bytes = messageDigest.digest(s.toByteArray());
+      return ByteString.of(sha1Bytes);
+    } catch (NoSuchAlgorithmException e) {
+      throw new AssertionError(e);
+    }
+  }
+
+  /** Returns an immutable copy of {@code list}. */
+  public static <T> List<T> immutableList(List<T> list) {
+    return Collections.unmodifiableList(new ArrayList<>(list));
+  }
+
+  /** Returns an immutable list containing {@code elements}. */
+  public static <T> List<T> immutableList(T... elements) {
+    return Collections.unmodifiableList(Arrays.asList(elements.clone()));
+  }
+
+  /** Returns an immutable copy of {@code map}. */
+  public static <K, V> Map<K, V> immutableMap(Map<K, V> map) {
+    return Collections.unmodifiableMap(new LinkedHashMap<>(map));
+  }
+
+  public static ThreadFactory threadFactory(final String name, final boolean daemon) {
+    return new ThreadFactory() {
+      @Override public Thread newThread(Runnable runnable) {
+        Thread result = new Thread(runnable, name);
+        result.setDaemon(daemon);
+        return result;
+      }
+    };
+  }
+
+  /**
+   * Returns an array containing containing only elements found in {@code first}  and also in
+   * {@code second}. The returned elements are in the same order as in {@code first}.
+   */
+  @SuppressWarnings("unchecked")
+  public static <T> T[] intersect(Class<T> arrayType, T[] first, T[] second) {
+    List<T> result = intersect(first, second);
+    return result.toArray((T[]) Array.newInstance(arrayType, result.size()));
+  }
+
+  /**
+   * Returns a list containing containing only elements found in {@code first}  and also in
+   * {@code second}. The returned elements are in the same order as in {@code first}.
+   */
+  private static <T> List<T> intersect(T[] first, T[] second) {
+    List<T> result = new ArrayList<>();
+    for (T a : first) {
+      for (T b : second) {
+        if (a.equals(b)) {
+          result.add(b);
+          break;
+        }
+      }
+    }
+    return result;
+  }
+
+  public static String hostHeader(HttpUrl url, boolean includeDefaultPort) {
+    String host = url.host().contains(":")
+        ? "[" + url.host() + "]"
+        : url.host();
+    return includeDefaultPort || url.port() != HttpUrl.defaultPort(url.scheme())
+        ? host + ":" + url.port()
+        : host;
+  }
+
+  /** Returns {@code s} with control characters and non-ASCII characters replaced with '?'. */
+  public static String toHumanReadableAscii(String s) {
+    for (int i = 0, length = s.length(), c; i < length; i += Character.charCount(c)) {
+      c = s.codePointAt(i);
+      if (c > '\u001f' && c < '\u007f') continue;
+
+      Buffer buffer = new Buffer();
+      buffer.writeUtf8(s, 0, i);
+      for (int j = i; j < length; j += Character.charCount(c)) {
+        c = s.codePointAt(j);
+        buffer.writeUtf8CodePoint(c > '\u001f' && c < '\u007f' ? c : '?');
+      }
+      return buffer.readUtf8();
+    }
+    return s;
+  }
+
+  /**
+   * Returns true if {@code e} is due to a firmware bug fixed after Android 4.2.2.
+   * https://code.google.com/p/android/issues/detail?id=54072
+   */
+  public static boolean isAndroidGetsocknameError(AssertionError e) {
+    return e.getCause() != null && e.getMessage() != null
+        && e.getMessage().contains("getsockname failed");
+  }
+
+  public static boolean contains(String[] array, String value) {
+    return Arrays.asList(array).contains(value);
+  }
+
+  public static String[] concat(String[] array, String value) {
+    String[] result = new String[array.length + 1];
+    System.arraycopy(array, 0, result, 0, array.length);
+    result[result.length - 1] = value;
+    return result;
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/ErrorCode.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/ErrorCode.java
new file mode 100644
index 0000000..d5d71ff
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/ErrorCode.java
@@ -0,0 +1,95 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.okhttp.internal.framed;
+
+// http://tools.ietf.org/html/draft-ietf-httpbis-http2-17#section-7
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public enum ErrorCode {
+  /** Not an error! For SPDY stream resets, prefer null over NO_ERROR. */
+  NO_ERROR(0, -1, 0),
+
+  PROTOCOL_ERROR(1, 1, 1),
+
+  /** A subtype of PROTOCOL_ERROR used by SPDY. */
+  INVALID_STREAM(1, 2, -1),
+
+  /** A subtype of PROTOCOL_ERROR used by SPDY. */
+  UNSUPPORTED_VERSION(1, 4, -1),
+
+  /** A subtype of PROTOCOL_ERROR used by SPDY. */
+  STREAM_IN_USE(1, 8, -1),
+
+  /** A subtype of PROTOCOL_ERROR used by SPDY. */
+  STREAM_ALREADY_CLOSED(1, 9, -1),
+
+  INTERNAL_ERROR(2, 6, 2),
+
+  FLOW_CONTROL_ERROR(3, 7, -1),
+
+  STREAM_CLOSED(5, -1, -1),
+
+  FRAME_TOO_LARGE(6, 11, -1),
+
+  REFUSED_STREAM(7, 3, -1),
+
+  CANCEL(8, 5, -1),
+
+  COMPRESSION_ERROR(9, -1, -1),
+
+  CONNECT_ERROR(10, -1, -1),
+
+  ENHANCE_YOUR_CALM(11, -1, -1),
+
+  INADEQUATE_SECURITY(12, -1, -1),
+
+  HTTP_1_1_REQUIRED(13, -1, -1),
+
+  INVALID_CREDENTIALS(-1, 10, -1);
+
+  public final int httpCode;
+  public final int spdyRstCode;
+  public final int spdyGoAwayCode;
+
+  private ErrorCode(int httpCode, int spdyRstCode, int spdyGoAwayCode) {
+    this.httpCode = httpCode;
+    this.spdyRstCode = spdyRstCode;
+    this.spdyGoAwayCode = spdyGoAwayCode;
+  }
+
+  public static ErrorCode fromSpdy3Rst(int code) {
+    for (ErrorCode errorCode : ErrorCode.values()) {
+      if (errorCode.spdyRstCode == code) return errorCode;
+    }
+    return null;
+  }
+
+  public static ErrorCode fromHttp2(int code) {
+    for (ErrorCode errorCode : ErrorCode.values()) {
+      if (errorCode.httpCode == code) return errorCode;
+    }
+    return null;
+  }
+
+  public static ErrorCode fromSpdyGoAway(int code) {
+    for (ErrorCode errorCode : ErrorCode.values()) {
+      if (errorCode.spdyGoAwayCode == code) return errorCode;
+    }
+    return null;
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/FrameReader.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/FrameReader.java
new file mode 100644
index 0000000..f17ed42
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/FrameReader.java
@@ -0,0 +1,139 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.okhttp.internal.framed;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.List;
+import com.android.okhttp.okio.BufferedSource;
+import com.android.okhttp.okio.ByteString;
+
+/** Reads transport frames for SPDY/3 or HTTP/2. 
+ * @hide This class is not part of the Android public SDK API*/
+public interface FrameReader extends Closeable {
+  void readConnectionPreface() throws IOException;
+  boolean nextFrame(Handler handler) throws IOException;
+
+  interface Handler {
+    void data(boolean inFinished, int streamId, BufferedSource source, int length)
+        throws IOException;
+
+    /**
+     * Create or update incoming headers, creating the corresponding streams
+     * if necessary. Frames that trigger this are SPDY SYN_STREAM, HEADERS, and
+     * SYN_REPLY, and HTTP/2 HEADERS and PUSH_PROMISE.
+     *
+     * @param outFinished true if the receiver should not send further frames.
+     * @param inFinished true if the sender will not send further frames.
+     * @param streamId the stream owning these headers.
+     * @param associatedStreamId the stream that triggered the sender to create
+     *     this stream.
+     */
+    void headers(boolean outFinished, boolean inFinished, int streamId, int associatedStreamId,
+        List<Header> headerBlock, HeadersMode headersMode);
+    void rstStream(int streamId, ErrorCode errorCode);
+    void settings(boolean clearPrevious, Settings settings);
+
+    /** HTTP/2 only. */
+    void ackSettings();
+
+    /**
+     *  Read a connection-level ping from the peer.  {@code ack} indicates this
+     *  is a reply.  Payload parameters are different between SPDY/3 and HTTP/2.
+     *  <p>
+     *  In SPDY/3, only the first {@code payload1} parameter is set.  If the
+     *  reader is a client, it is an unsigned even number.  Likewise, a server
+     *  will receive an odd number.
+     *  <p>
+     *  In HTTP/2, both {@code payload1} and {@code payload2} parameters are
+     *  set. The data is opaque binary, and there are no rules on the content.
+     */
+    void ping(boolean ack, int payload1, int payload2);
+
+    /**
+     * The peer tells us to stop creating streams.  It is safe to replay
+     * streams with {@code ID > lastGoodStreamId} on a new connection.  In-
+     * flight streams with {@code ID <= lastGoodStreamId} can only be replayed
+     * on a new connection if they are idempotent.
+     *
+     * @param lastGoodStreamId the last stream ID the peer processed before
+     *     sending this message. If {@code lastGoodStreamId} is zero, the peer
+     *     processed no frames.
+     * @param errorCode reason for closing the connection.
+     * @param debugData only valid for HTTP/2; opaque debug data to send.
+     */
+    void goAway(int lastGoodStreamId, ErrorCode errorCode, ByteString debugData);
+
+    /**
+     * Notifies that an additional {@code windowSizeIncrement} bytes can be
+     * sent on {@code streamId}, or the connection if {@code streamId} is zero.
+     */
+    void windowUpdate(int streamId, long windowSizeIncrement);
+
+    /**
+     * Called when reading a headers or priority frame. This may be used to
+     * change the stream's weight from the default (16) to a new value.
+     *
+     * @param streamId stream which has a priority change.
+     * @param streamDependency the stream ID this stream is dependent on.
+     * @param weight relative proportion of priority in [1..256].
+     * @param exclusive inserts this stream ID as the sole child of
+     *     {@code streamDependency}.
+     */
+    void priority(int streamId, int streamDependency, int weight, boolean exclusive);
+
+    /**
+     * HTTP/2 only. Receive a push promise header block.
+     * <p>
+     * A push promise contains all the headers that pertain to a server-initiated
+     * request, and a {@code promisedStreamId} to which response frames will be
+     * delivered. Push promise frames are sent as a part of the response to
+     * {@code streamId}.
+     *
+     * @param streamId client-initiated stream ID.  Must be an odd number.
+     * @param promisedStreamId server-initiated stream ID.  Must be an even
+     * number.
+     * @param requestHeaders minimally includes {@code :method}, {@code :scheme},
+     * {@code :authority}, and (@code :path}.
+     */
+    void pushPromise(int streamId, int promisedStreamId, List<Header> requestHeaders)
+        throws IOException;
+
+    /**
+     * HTTP/2 only. Expresses that resources for the connection or a client-
+     * initiated stream are available from a different network location or
+     * protocol configuration.
+     *
+     * <p>See <a href="http://tools.ietf.org/html/draft-ietf-httpbis-alt-svc-01">alt-svc</a>
+     *
+     * @param streamId when a client-initiated stream ID (odd number), the
+     *     origin of this alternate service is the origin of the stream. When
+     *     zero, the origin is specified in the {@code origin} parameter.
+     * @param origin when present, the
+     *     <a href="http://tools.ietf.org/html/rfc6454">origin</a> is typically
+     *     represented as a combination of scheme, host and port. When empty,
+     *     the origin is that of the {@code streamId}.
+     * @param protocol an ALPN protocol, such as {@code h2}.
+     * @param host an IP address or hostname.
+     * @param port the IP port associated with the service.
+     * @param maxAge time in seconds that this alternative is considered fresh.
+     */
+    void alternateService(int streamId, String origin, ByteString protocol, String host, int port,
+        long maxAge);
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/FrameWriter.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/FrameWriter.java
new file mode 100644
index 0000000..75b049d
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/FrameWriter.java
@@ -0,0 +1,105 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.okhttp.internal.framed;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.List;
+import com.android.okhttp.okio.Buffer;
+
+/** Writes transport frames for SPDY/3 or HTTP/2. 
+ * @hide This class is not part of the Android public SDK API*/
+public interface FrameWriter extends Closeable {
+  /** HTTP/2 only. */
+  void connectionPreface() throws IOException;
+  /** Informs the peer that we've applied its latest settings. */
+  void ackSettings(Settings peerSettings) throws IOException;
+
+  /**
+   * HTTP/2 only. Send a push promise header block.
+   * <p>
+   * A push promise contains all the headers that pertain to a server-initiated
+   * request, and a {@code promisedStreamId} to which response frames will be
+   * delivered. Push promise frames are sent as a part of the response to
+   * {@code streamId}.  The {@code promisedStreamId} has a priority of one
+   * greater than {@code streamId}.
+   *
+   * @param streamId client-initiated stream ID.  Must be an odd number.
+   * @param promisedStreamId server-initiated stream ID.  Must be an even
+   * number.
+   * @param requestHeaders minimally includes {@code :method}, {@code :scheme},
+   * {@code :authority}, and (@code :path}.
+   */
+  void pushPromise(int streamId, int promisedStreamId, List<Header> requestHeaders)
+      throws IOException;
+
+  /** SPDY/3 only. */
+  void flush() throws IOException;
+  void synStream(boolean outFinished, boolean inFinished, int streamId, int associatedStreamId,
+      List<Header> headerBlock) throws IOException;
+  void synReply(boolean outFinished, int streamId, List<Header> headerBlock)
+      throws IOException;
+  void headers(int streamId, List<Header> headerBlock) throws IOException;
+  void rstStream(int streamId, ErrorCode errorCode) throws IOException;
+
+  /** The maximum size of bytes that may be sent in a single call to {@link #data}. */
+  int maxDataLength();
+
+  /**
+   * {@code source.length} may be longer than the max length of the variant's data frame.
+   * Implementations must send multiple frames as necessary.
+   *
+   * @param source the buffer to draw bytes from. May be null if byteCount is 0.
+   * @param byteCount must be between 0 and the minimum of {code source.length}
+   * and {@link #maxDataLength}.
+   */
+  void data(boolean outFinished, int streamId, Buffer source, int byteCount) throws IOException;
+
+  /** Write okhttp's settings to the peer. */
+  void settings(Settings okHttpSettings) throws IOException;
+
+  /**
+   *  Send a connection-level ping to the peer.  {@code ack} indicates this is
+   *  a reply.  Payload parameters are different between SPDY/3 and HTTP/2.
+   *  <p>
+   *  In SPDY/3, only the first {@code payload1} parameter is sent.  If the
+   *  sender is a client, it is an unsigned odd number.  Likewise, a server
+   *  will send an even number.
+   *  <p>
+   *  In HTTP/2, both {@code payload1} and {@code payload2} parameters are
+   *  sent.  The data is opaque binary, and there are no rules on the content.
+   */
+  void ping(boolean ack, int payload1, int payload2) throws IOException;
+
+  /**
+   * Tell the peer to stop creating streams and that we last processed
+   * {@code lastGoodStreamId}, or zero if no streams were processed.
+   *
+   * @param lastGoodStreamId the last stream ID processed, or zero if no
+   * streams were processed.
+   * @param errorCode reason for closing the connection.
+   * @param debugData only valid for HTTP/2; opaque debug data to send.
+   */
+  void goAway(int lastGoodStreamId, ErrorCode errorCode, byte[] debugData) throws IOException;
+
+  /**
+   * Inform peer that an additional {@code windowSizeIncrement} bytes can be
+   * sent on {@code streamId}, or the connection if {@code streamId} is zero.
+   */
+  void windowUpdate(int streamId, long windowSizeIncrement) throws IOException;
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/FramedConnection.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/FramedConnection.java
new file mode 100644
index 0000000..2945e65
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/FramedConnection.java
@@ -0,0 +1,949 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.okhttp.internal.framed;
+
+import com.android.okhttp.Protocol;
+import com.android.okhttp.internal.NamedRunnable;
+import com.android.okhttp.internal.Util;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import com.android.okhttp.okio.Buffer;
+import com.android.okhttp.okio.BufferedSink;
+import com.android.okhttp.okio.BufferedSource;
+import com.android.okhttp.okio.ByteString;
+import com.android.okhttp.okio.Okio;
+
+import static com.android.okhttp.internal.Internal.logger;
+import static com.android.okhttp.internal.framed.Settings.DEFAULT_INITIAL_WINDOW_SIZE;
+
+/**
+ * A socket connection to a remote peer. A connection hosts streams which can
+ * send and receive data.
+ *
+ * <p>Many methods in this API are <strong>synchronous:</strong> the call is
+ * completed before the method returns. This is typical for Java but atypical
+ * for SPDY. This is motivated by exception transparency: an IOException that
+ * was triggered by a certain caller can be caught and handled by that caller.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class FramedConnection implements Closeable {
+
+  // Internal state of this connection is guarded by 'this'. No blocking
+  // operations may be performed while holding this lock!
+  //
+  // Socket writes are guarded by frameWriter.
+  //
+  // Socket reads are unguarded but are only made by the reader thread.
+  //
+  // Certain operations (like SYN_STREAM) need to synchronize on both the
+  // frameWriter (to do blocking I/O) and this (to create streams). Such
+  // operations must synchronize on 'this' last. This ensures that we never
+  // wait for a blocking operation while holding 'this'.
+
+  private static final ExecutorService executor = new ThreadPoolExecutor(0,
+      Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(),
+      Util.threadFactory("OkHttp FramedConnection", true));
+
+  /** The protocol variant, like {@link com.android.okhttp.internal.framed.Spdy3}. */
+  final Protocol protocol;
+
+  /** True if this peer initiated the connection. */
+  final boolean client;
+
+  /**
+   * User code to run in response to incoming streams or settings. Calls to this are always invoked
+   * on {@link #executor}.
+   */
+  private final Listener listener;
+  private final Map<Integer, FramedStream> streams = new HashMap<>();
+  private final String hostName;
+  private int lastGoodStreamId;
+  private int nextStreamId;
+  private boolean shutdown;
+  private long idleStartTimeNs = System.nanoTime();
+
+  /** Ensures push promise callbacks events are sent in order per stream. */
+  private final ExecutorService pushExecutor;
+
+  /** Lazily-created map of in-flight pings awaiting a response. Guarded by this. */
+  private Map<Integer, Ping> pings;
+  /** User code to run in response to push promise events. */
+  private final PushObserver pushObserver;
+  private int nextPingId;
+
+  /**
+   * The total number of bytes consumed by the application, but not yet
+   * acknowledged by sending a {@code WINDOW_UPDATE} frame on this connection.
+   */
+  // Visible for testing
+  long unacknowledgedBytesRead = 0;
+
+  /**
+   * Count of bytes that can be written on the connection before receiving a
+   * window update.
+   */
+  // Visible for testing
+  long bytesLeftInWriteWindow;
+
+  /** Settings we communicate to the peer. */
+  Settings okHttpSettings = new Settings();
+
+  private static final int OKHTTP_CLIENT_WINDOW_SIZE = 16 * 1024 * 1024;
+
+  /** Settings we receive from the peer. */
+  // TODO: MWS will need to guard on this setting before attempting to push.
+  final Settings peerSettings = new Settings();
+
+  private boolean receivedInitialPeerSettings = false;
+  final Variant variant;
+  final Socket socket;
+  final FrameWriter frameWriter;
+
+  // Visible for testing
+  final Reader readerRunnable;
+
+  private FramedConnection(Builder builder) throws IOException {
+    protocol = builder.protocol;
+    pushObserver = builder.pushObserver;
+    client = builder.client;
+    listener = builder.listener;
+    // http://tools.ietf.org/html/draft-ietf-httpbis-http2-17#section-5.1.1
+    nextStreamId = builder.client ? 1 : 2;
+    if (builder.client && protocol == Protocol.HTTP_2) {
+      nextStreamId += 2; // In HTTP/2, 1 on client is reserved for Upgrade.
+    }
+
+    nextPingId = builder.client ? 1 : 2;
+
+    // Flow control was designed more for servers, or proxies than edge clients.
+    // If we are a client, set the flow control window to 16MiB.  This avoids
+    // thrashing window updates every 64KiB, yet small enough to avoid blowing
+    // up the heap.
+    if (builder.client) {
+      okHttpSettings.set(Settings.INITIAL_WINDOW_SIZE, 0, OKHTTP_CLIENT_WINDOW_SIZE);
+    }
+
+    hostName = builder.hostName;
+
+    if (protocol == Protocol.HTTP_2) {
+      variant = new Http2();
+      // Like newSingleThreadExecutor, except lazy creates the thread.
+      pushExecutor = new ThreadPoolExecutor(0, 1, 60, TimeUnit.SECONDS,
+          new LinkedBlockingQueue<Runnable>(),
+          Util.threadFactory(String.format("OkHttp %s Push Observer", hostName), true));
+      // 1 less than SPDY http://tools.ietf.org/html/draft-ietf-httpbis-http2-17#section-6.9.2
+      peerSettings.set(Settings.INITIAL_WINDOW_SIZE, 0, 65535);
+      peerSettings.set(Settings.MAX_FRAME_SIZE, 0, Http2.INITIAL_MAX_FRAME_SIZE);
+    } else if (protocol == Protocol.SPDY_3) {
+      variant = new Spdy3();
+      pushExecutor = null;
+    } else {
+      throw new AssertionError(protocol);
+    }
+    bytesLeftInWriteWindow = peerSettings.getInitialWindowSize(DEFAULT_INITIAL_WINDOW_SIZE);
+    socket = builder.socket;
+    frameWriter = variant.newWriter(builder.sink, client);
+
+    readerRunnable = new Reader(variant.newReader(builder.source, client));
+    new Thread(readerRunnable).start(); // Not a daemon thread.
+  }
+
+  /** The protocol as selected using ALPN. */
+  public Protocol getProtocol() {
+    return protocol;
+  }
+
+  /**
+   * Returns the number of {@link FramedStream#isOpen() open streams} on this
+   * connection.
+   */
+  public synchronized int openStreamCount() {
+    return streams.size();
+  }
+
+  synchronized FramedStream getStream(int id) {
+    return streams.get(id);
+  }
+
+  synchronized FramedStream removeStream(int streamId) {
+    FramedStream stream = streams.remove(streamId);
+    if (stream != null && streams.isEmpty()) {
+      setIdle(true);
+    }
+    notifyAll(); // The removed stream may be blocked on a connection-wide window update.
+    return stream;
+  }
+
+  private synchronized void setIdle(boolean value) {
+    idleStartTimeNs = value ? System.nanoTime() : Long.MAX_VALUE;
+  }
+
+  /** Returns true if this connection is idle. */
+  public synchronized boolean isIdle() {
+    return idleStartTimeNs != Long.MAX_VALUE;
+  }
+
+  public synchronized int maxConcurrentStreams() {
+    return peerSettings.getMaxConcurrentStreams(Integer.MAX_VALUE);
+  }
+
+  /**
+   * Returns the time in ns when this connection became idle or Long.MAX_VALUE
+   * if connection is not idle.
+   */
+  public synchronized long getIdleStartTimeNs() {
+    return idleStartTimeNs;
+  }
+
+  /**
+   * Returns a new server-initiated stream.
+   *
+   * @param associatedStreamId the stream that triggered the sender to create
+   *     this 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}.
+   */
+  public FramedStream pushStream(int associatedStreamId, List<Header> requestHeaders, boolean out)
+      throws IOException {
+    if (client) throw new IllegalStateException("Client cannot push requests.");
+    if (protocol != Protocol.HTTP_2) throw new IllegalStateException("protocol != HTTP_2");
+    return newStream(associatedStreamId, requestHeaders, out, false);
+  }
+
+  /**
+   * 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 FramedStream newStream(List<Header> requestHeaders, boolean out, boolean in)
+      throws IOException {
+    return newStream(0, requestHeaders, out, in);
+  }
+
+  private FramedStream newStream(int associatedStreamId, List<Header> requestHeaders, boolean out,
+      boolean in) throws IOException {
+    boolean outFinished = !out;
+    boolean inFinished = !in;
+    FramedStream stream;
+    int streamId;
+
+    synchronized (frameWriter) {
+      synchronized (this) {
+        if (shutdown) {
+          throw new IOException("shutdown");
+        }
+        streamId = nextStreamId;
+        nextStreamId += 2;
+        stream = new FramedStream(streamId, this, outFinished, inFinished, requestHeaders);
+        if (stream.isOpen()) {
+          streams.put(streamId, stream);
+          setIdle(false);
+        }
+      }
+      if (associatedStreamId == 0) {
+        frameWriter.synStream(outFinished, inFinished, streamId, associatedStreamId,
+            requestHeaders);
+      } else if (client) {
+        throw new IllegalArgumentException("client streams shouldn't have associated stream IDs");
+      } else { // HTTP/2 has a PUSH_PROMISE frame.
+        frameWriter.pushPromise(associatedStreamId, streamId, requestHeaders);
+      }
+    }
+
+    if (!out) {
+      frameWriter.flush();
+    }
+
+    return stream;
+  }
+
+  void writeSynReply(int streamId, boolean outFinished, List<Header> alternating)
+      throws IOException {
+    frameWriter.synReply(outFinished, streamId, alternating);
+  }
+
+  /**
+   * Callers of this method are not thread safe, and sometimes on application threads. Most often,
+   * this method will be called to send a buffer worth of data to the peer.
+   *
+   * <p>Writes are subject to the write window of the stream and the connection. Until there is a
+   * window sufficient to send {@code byteCount}, the caller will block. For example, a user of
+   * {@code HttpURLConnection} who flushes more bytes to the output stream than the connection's
+   * write window will block.
+   *
+   * <p>Zero {@code byteCount} writes are not subject to flow control and will not block. The only
+   * use case for zero {@code byteCount} is closing a flushed output stream.
+   */
+  public void writeData(int streamId, boolean outFinished, Buffer buffer, long byteCount)
+      throws IOException {
+    if (byteCount == 0) { // Empty data frames are not flow-controlled.
+      frameWriter.data(outFinished, streamId, buffer, 0);
+      return;
+    }
+
+    while (byteCount > 0) {
+      int toWrite;
+      synchronized (FramedConnection.this) {
+        try {
+          while (bytesLeftInWriteWindow <= 0) {
+            // Before blocking, confirm that the stream we're writing is still open. It's possible
+            // that the stream has since been closed (such as if this write timed out.)
+            if (!streams.containsKey(streamId)) {
+              throw new IOException("stream closed");
+            }
+            FramedConnection.this.wait(); // Wait until we receive a WINDOW_UPDATE.
+          }
+        } catch (InterruptedException e) {
+          throw new InterruptedIOException();
+        }
+
+        toWrite = (int) Math.min(byteCount, bytesLeftInWriteWindow);
+        toWrite = Math.min(toWrite, frameWriter.maxDataLength());
+        bytesLeftInWriteWindow -= toWrite;
+      }
+
+      byteCount -= toWrite;
+      frameWriter.data(outFinished && byteCount == 0, streamId, buffer, toWrite);
+    }
+  }
+
+  /**
+   * {@code delta} will be negative if a settings frame initial window is
+   * smaller than the last.
+   */
+  void addBytesToWriteWindow(long delta) {
+    bytesLeftInWriteWindow += delta;
+    if (delta > 0) FramedConnection.this.notifyAll();
+  }
+
+  void writeSynResetLater(final int streamId, final ErrorCode errorCode) {
+    executor.submit(new NamedRunnable("OkHttp %s stream %d", hostName, streamId) {
+      @Override public void execute() {
+        try {
+          writeSynReset(streamId, errorCode);
+        } catch (IOException ignored) {
+        }
+      }
+    });
+  }
+
+  void writeSynReset(int streamId, ErrorCode statusCode) throws IOException {
+    frameWriter.rstStream(streamId, statusCode);
+  }
+
+  void writeWindowUpdateLater(final int streamId, final long unacknowledgedBytesRead) {
+    executor.execute(new NamedRunnable("OkHttp Window Update %s stream %d", hostName, streamId) {
+      @Override public void execute() {
+        try {
+          frameWriter.windowUpdate(streamId, unacknowledgedBytesRead);
+        } catch (IOException ignored) {
+        }
+      }
+    });
+  }
+
+  /**
+   * Sends a ping frame to the peer. Use the returned object to await the
+   * ping's response and observe its round trip time.
+   */
+  public Ping ping() throws IOException {
+    Ping ping = new Ping();
+    int pingId;
+    synchronized (this) {
+      if (shutdown) {
+        throw new IOException("shutdown");
+      }
+      pingId = nextPingId;
+      nextPingId += 2;
+      if (pings == null) pings = new HashMap<>();
+      pings.put(pingId, ping);
+    }
+    writePing(false, pingId, 0x4f4b6f6b /* ASCII "OKok" */, ping);
+    return ping;
+  }
+
+  private void writePingLater(
+      final boolean reply, final int payload1, final int payload2, final Ping ping) {
+    executor.execute(new NamedRunnable("OkHttp %s ping %08x%08x",
+        hostName, payload1, payload2) {
+      @Override public void execute() {
+        try {
+          writePing(reply, payload1, payload2, ping);
+        } catch (IOException ignored) {
+        }
+      }
+    });
+  }
+
+  private void writePing(boolean reply, int payload1, int payload2, Ping ping) throws IOException {
+    synchronized (frameWriter) {
+      // Observe the sent time immediately before performing I/O.
+      if (ping != null) ping.send();
+      frameWriter.ping(reply, payload1, payload2);
+    }
+  }
+
+  private synchronized Ping removePing(int id) {
+    return pings != null ? pings.remove(id) : null;
+  }
+
+  public void flush() throws IOException {
+    frameWriter.flush();
+  }
+
+  /**
+   * Degrades this connection such that new streams can neither be created
+   * locally, nor accepted from the remote peer. Existing streams are not
+   * impacted. This is intended to permit an endpoint to gracefully stop
+   * accepting new requests without harming previously established streams.
+   */
+  public void shutdown(ErrorCode statusCode) throws IOException {
+    synchronized (frameWriter) {
+      int lastGoodStreamId;
+      synchronized (this) {
+        if (shutdown) {
+          return;
+        }
+        shutdown = true;
+        lastGoodStreamId = this.lastGoodStreamId;
+      }
+      // TODO: propagate exception message into debugData
+      frameWriter.goAway(lastGoodStreamId, statusCode, Util.EMPTY_BYTE_ARRAY);
+    }
+  }
+
+  /**
+   * Closes this connection. This cancels all open streams and unanswered
+   * pings. It closes the underlying input and output streams and shuts down
+   * internal executor services.
+   */
+  @Override public void close() throws IOException {
+    close(ErrorCode.NO_ERROR, ErrorCode.CANCEL);
+  }
+
+  private void close(ErrorCode connectionCode, ErrorCode streamCode) throws IOException {
+    assert (!Thread.holdsLock(this));
+    IOException thrown = null;
+    try {
+      shutdown(connectionCode);
+    } catch (IOException e) {
+      thrown = e;
+    }
+
+    FramedStream[] streamsToClose = null;
+    Ping[] pingsToCancel = null;
+    synchronized (this) {
+      if (!streams.isEmpty()) {
+        streamsToClose = streams.values().toArray(new FramedStream[streams.size()]);
+        streams.clear();
+        setIdle(false);
+      }
+      if (pings != null) {
+        pingsToCancel = pings.values().toArray(new Ping[pings.size()]);
+        pings = null;
+      }
+    }
+
+    if (streamsToClose != null) {
+      for (FramedStream stream : streamsToClose) {
+        try {
+          stream.close(streamCode);
+        } catch (IOException e) {
+          if (thrown != null) thrown = e;
+        }
+      }
+    }
+
+    if (pingsToCancel != null) {
+      for (Ping ping : pingsToCancel) {
+        ping.cancel();
+      }
+    }
+
+    // Close the writer to release its resources (such as deflaters).
+    try {
+      frameWriter.close();
+    } catch (IOException e) {
+      if (thrown == null) thrown = e;
+    }
+
+    // Close the socket to break out the reader thread, which will clean up after itself.
+    try {
+      socket.close();
+    } catch (IOException e) {
+      thrown = e;
+    }
+
+    if (thrown != null) throw thrown;
+  }
+
+  /**
+   * Sends a connection header if the current variant requires it. This should
+   * be called after {@link Builder#build} for all new connections.
+   */
+  public void sendConnectionPreface() throws IOException {
+    frameWriter.connectionPreface();
+    frameWriter.settings(okHttpSettings);
+    int windowSize = okHttpSettings.getInitialWindowSize(Settings.DEFAULT_INITIAL_WINDOW_SIZE);
+    if (windowSize != Settings.DEFAULT_INITIAL_WINDOW_SIZE) {
+      frameWriter.windowUpdate(0, windowSize - Settings.DEFAULT_INITIAL_WINDOW_SIZE);
+    }
+  }
+
+  /** Merges {@code settings} into this peer's settings and sends them to the remote peer. */
+  public void setSettings(Settings settings) throws IOException {
+    synchronized (frameWriter) {
+      synchronized (this) {
+        if (shutdown) {
+          throw new IOException("shutdown");
+        }
+        okHttpSettings.merge(settings);
+        frameWriter.settings(settings);
+      }
+    }
+  }
+
+  /**
+   * @hide This class is not part of the Android public SDK API
+   */
+  public static class Builder {
+    private Socket socket;
+    private String hostName;
+    private BufferedSource source;
+    private BufferedSink sink;
+    private Listener listener = Listener.REFUSE_INCOMING_STREAMS;
+    private Protocol protocol = Protocol.SPDY_3;
+    private PushObserver pushObserver = PushObserver.CANCEL;
+    private boolean client;
+
+    /**
+     * @param client true if this peer initiated the connection; false if this
+     *     peer accepted the connection.
+     */
+    public Builder(boolean client) throws IOException {
+      this.client = client;
+    }
+
+    public Builder socket(Socket socket) throws IOException {
+      return socket(socket, ((InetSocketAddress) socket.getRemoteSocketAddress()).getHostName(),
+          Okio.buffer(Okio.source(socket)), Okio.buffer(Okio.sink(socket)));
+    }
+
+    public Builder socket(
+        Socket socket, String hostName, BufferedSource source, BufferedSink sink) {
+      this.socket = socket;
+      this.hostName = hostName;
+      this.source = source;
+      this.sink = sink;
+      return this;
+    }
+
+    public Builder listener(Listener listener) {
+      this.listener = listener;
+      return this;
+    }
+
+    public Builder protocol(Protocol protocol) {
+      this.protocol = protocol;
+      return this;
+    }
+
+    public Builder pushObserver(PushObserver pushObserver) {
+      this.pushObserver = pushObserver;
+      return this;
+    }
+
+    public FramedConnection build() throws IOException {
+      return new FramedConnection(this);
+    }
+  }
+
+  /**
+   * Methods in this class must not lock FrameWriter.  If a method needs to
+   * write a frame, create an async task to do so.
+   */
+  class Reader extends NamedRunnable implements FrameReader.Handler {
+    final FrameReader frameReader;
+
+    private Reader(FrameReader frameReader) {
+      super("OkHttp %s", hostName);
+      this.frameReader = frameReader;
+    }
+
+    @Override protected void execute() {
+      ErrorCode connectionErrorCode = ErrorCode.INTERNAL_ERROR;
+      ErrorCode streamErrorCode = ErrorCode.INTERNAL_ERROR;
+      try {
+        if (!client) {
+          frameReader.readConnectionPreface();
+        }
+        while (frameReader.nextFrame(this)) {
+        }
+        connectionErrorCode = ErrorCode.NO_ERROR;
+        streamErrorCode = ErrorCode.CANCEL;
+      } catch (IOException e) {
+        connectionErrorCode = ErrorCode.PROTOCOL_ERROR;
+        streamErrorCode = ErrorCode.PROTOCOL_ERROR;
+      } finally {
+        try {
+          close(connectionErrorCode, streamErrorCode);
+        } catch (IOException ignored) {
+        }
+        Util.closeQuietly(frameReader);
+      }
+    }
+
+    @Override public void data(boolean inFinished, int streamId, BufferedSource source, int length)
+        throws IOException {
+      if (pushedStream(streamId)) {
+        pushDataLater(streamId, source, length, inFinished);
+        return;
+      }
+      FramedStream dataStream = getStream(streamId);
+      if (dataStream == null) {
+        writeSynResetLater(streamId, ErrorCode.INVALID_STREAM);
+        source.skip(length);
+        return;
+      }
+      dataStream.receiveData(source, length);
+      if (inFinished) {
+        dataStream.receiveFin();
+      }
+    }
+
+    @Override public void headers(boolean outFinished, boolean inFinished, int streamId,
+        int associatedStreamId, List<Header> headerBlock, HeadersMode headersMode) {
+      if (pushedStream(streamId)) {
+        pushHeadersLater(streamId, headerBlock, inFinished);
+        return;
+      }
+      FramedStream stream;
+      synchronized (FramedConnection.this) {
+        // If we're shutdown, don't bother with this stream.
+        if (shutdown) return;
+
+        stream = getStream(streamId);
+
+        if (stream == null) {
+          // The headers claim to be for an existing stream, but we don't have one.
+          if (headersMode.failIfStreamAbsent()) {
+            writeSynResetLater(streamId, ErrorCode.INVALID_STREAM);
+            return;
+          }
+
+          // If the stream ID is less than the last created ID, assume it's already closed.
+          if (streamId <= lastGoodStreamId) return;
+
+          // If the stream ID is in the client's namespace, assume it's already closed.
+          if (streamId % 2 == nextStreamId % 2) return;
+
+          // Create a stream.
+          final FramedStream
+              newStream = new FramedStream(streamId, FramedConnection.this, outFinished,
+              inFinished, headerBlock);
+          lastGoodStreamId = streamId;
+          streams.put(streamId, newStream);
+          executor.execute(new NamedRunnable("OkHttp %s stream %d", hostName, streamId) {
+            @Override public void execute() {
+              try {
+                listener.onStream(newStream);
+              } catch (IOException e) {
+                logger.log(Level.INFO, "FramedConnection.Listener failure for " + hostName, e);
+                try {
+                  newStream.close(ErrorCode.PROTOCOL_ERROR);
+                } catch (IOException ignored) {
+                }
+              }
+            }
+          });
+          return;
+        }
+      }
+
+      // The headers claim to be for a new stream, but we already have one.
+      if (headersMode.failIfStreamPresent()) {
+        stream.closeLater(ErrorCode.PROTOCOL_ERROR);
+        removeStream(streamId);
+        return;
+      }
+
+      // Update an existing stream.
+      stream.receiveHeaders(headerBlock, headersMode);
+      if (inFinished) stream.receiveFin();
+    }
+
+    @Override public void rstStream(int streamId, ErrorCode errorCode) {
+      if (pushedStream(streamId)) {
+        pushResetLater(streamId, errorCode);
+        return;
+      }
+      FramedStream rstStream = removeStream(streamId);
+      if (rstStream != null) {
+        rstStream.receiveRstStream(errorCode);
+      }
+    }
+
+    @Override public void settings(boolean clearPrevious, Settings newSettings) {
+      long delta = 0;
+      FramedStream[] streamsToNotify = null;
+      synchronized (FramedConnection.this) {
+        int priorWriteWindowSize = peerSettings.getInitialWindowSize(DEFAULT_INITIAL_WINDOW_SIZE);
+        if (clearPrevious) peerSettings.clear();
+        peerSettings.merge(newSettings);
+        if (getProtocol() == Protocol.HTTP_2) {
+          ackSettingsLater(newSettings);
+        }
+        int peerInitialWindowSize = peerSettings.getInitialWindowSize(DEFAULT_INITIAL_WINDOW_SIZE);
+        if (peerInitialWindowSize != -1 && peerInitialWindowSize != priorWriteWindowSize) {
+          delta = peerInitialWindowSize - priorWriteWindowSize;
+          if (!receivedInitialPeerSettings) {
+            addBytesToWriteWindow(delta);
+            receivedInitialPeerSettings = true;
+          }
+          if (!streams.isEmpty()) {
+            streamsToNotify = streams.values().toArray(new FramedStream[streams.size()]);
+          }
+        }
+        executor.execute(new NamedRunnable("OkHttp %s settings", hostName) {
+          @Override public void execute() {
+            listener.onSettings(FramedConnection.this);
+          }
+        });
+      }
+      if (streamsToNotify != null && delta != 0) {
+        for (FramedStream stream : streamsToNotify) {
+          synchronized (stream) {
+            stream.addBytesToWriteWindow(delta);
+          }
+        }
+      }
+    }
+
+    private void ackSettingsLater(final Settings peerSettings) {
+      executor.execute(new NamedRunnable("OkHttp %s ACK Settings", hostName) {
+        @Override public void execute() {
+          try {
+            frameWriter.ackSettings(peerSettings);
+          } catch (IOException ignored) {
+          }
+        }
+      });
+    }
+
+    @Override public void ackSettings() {
+      // TODO: If we don't get this callback after sending settings to the peer, SETTINGS_TIMEOUT.
+    }
+
+    @Override public void ping(boolean reply, int payload1, int payload2) {
+      if (reply) {
+        Ping ping = removePing(payload1);
+        if (ping != null) {
+          ping.receive();
+        }
+      } else {
+        // Send a reply to a client ping if this is a server and vice versa.
+        writePingLater(true, payload1, payload2, null);
+      }
+    }
+
+    @Override public void goAway(int lastGoodStreamId, ErrorCode errorCode, ByteString debugData) {
+      if (debugData.size() > 0) { // TODO: log the debugData
+      }
+
+      // Copy the streams first. We don't want to hold a lock when we call receiveRstStream().
+      FramedStream[] streamsCopy;
+      synchronized (FramedConnection.this) {
+        streamsCopy = streams.values().toArray(new FramedStream[streams.size()]);
+        shutdown = true;
+      }
+
+      // Fail all streams created after the last good stream ID.
+      for (FramedStream framedStream : streamsCopy) {
+        if (framedStream.getId() > lastGoodStreamId && framedStream.isLocallyInitiated()) {
+          framedStream.receiveRstStream(ErrorCode.REFUSED_STREAM);
+          removeStream(framedStream.getId());
+        }
+      }
+    }
+
+    @Override public void windowUpdate(int streamId, long windowSizeIncrement) {
+      if (streamId == 0) {
+        synchronized (FramedConnection.this) {
+          bytesLeftInWriteWindow += windowSizeIncrement;
+          FramedConnection.this.notifyAll();
+        }
+      } else {
+        FramedStream stream = getStream(streamId);
+        if (stream != null) {
+          synchronized (stream) {
+            stream.addBytesToWriteWindow(windowSizeIncrement);
+          }
+        }
+      }
+    }
+
+    @Override public void priority(int streamId, int streamDependency, int weight,
+        boolean exclusive) {
+      // TODO: honor priority.
+    }
+
+    @Override
+    public void pushPromise(int streamId, int promisedStreamId, List<Header> requestHeaders) {
+      pushRequestLater(promisedStreamId, requestHeaders);
+    }
+
+    @Override public void alternateService(int streamId, String origin, ByteString protocol,
+        String host, int port, long maxAge) {
+      // TODO: register alternate service.
+    }
+  }
+
+  /** Even, positive numbered streams are pushed streams in HTTP/2. */
+  private boolean pushedStream(int streamId) {
+    return protocol == Protocol.HTTP_2 && streamId != 0 && (streamId & 1) == 0;
+  }
+
+  // Guarded by this.
+  private final Set<Integer> currentPushRequests = new LinkedHashSet<>();
+
+  private void pushRequestLater(final int streamId, final List<Header> requestHeaders) {
+    synchronized (this) {
+      if (currentPushRequests.contains(streamId)) {
+        writeSynResetLater(streamId, ErrorCode.PROTOCOL_ERROR);
+        return;
+      }
+      currentPushRequests.add(streamId);
+    }
+    pushExecutor.execute(new NamedRunnable("OkHttp %s Push Request[%s]", hostName, streamId) {
+      @Override public void execute() {
+        boolean cancel = pushObserver.onRequest(streamId, requestHeaders);
+        try {
+          if (cancel) {
+            frameWriter.rstStream(streamId, ErrorCode.CANCEL);
+            synchronized (FramedConnection.this) {
+              currentPushRequests.remove(streamId);
+            }
+          }
+        } catch (IOException ignored) {
+        }
+      }
+    });
+  }
+
+  private void pushHeadersLater(final int streamId, final List<Header> requestHeaders,
+      final boolean inFinished) {
+    pushExecutor.execute(new NamedRunnable("OkHttp %s Push Headers[%s]", hostName, streamId) {
+      @Override public void execute() {
+        boolean cancel = pushObserver.onHeaders(streamId, requestHeaders, inFinished);
+        try {
+          if (cancel) frameWriter.rstStream(streamId, ErrorCode.CANCEL);
+          if (cancel || inFinished) {
+            synchronized (FramedConnection.this) {
+              currentPushRequests.remove(streamId);
+            }
+          }
+        } catch (IOException ignored) {
+        }
+      }
+    });
+  }
+
+  /**
+   * Eagerly reads {@code byteCount} bytes from the source before launching a background task to
+   * process the data.  This avoids corrupting the stream.
+   */
+  private void pushDataLater(final int streamId, final BufferedSource source, final int byteCount,
+      final boolean inFinished) throws IOException {
+    final Buffer buffer = new Buffer();
+    source.require(byteCount); // Eagerly read the frame before firing client thread.
+    source.read(buffer, byteCount);
+    if (buffer.size() != byteCount) throw new IOException(buffer.size() + " != " + byteCount);
+    pushExecutor.execute(new NamedRunnable("OkHttp %s Push Data[%s]", hostName, streamId) {
+      @Override public void execute() {
+        try {
+          boolean cancel = pushObserver.onData(streamId, buffer, byteCount, inFinished);
+          if (cancel) frameWriter.rstStream(streamId, ErrorCode.CANCEL);
+          if (cancel || inFinished) {
+            synchronized (FramedConnection.this) {
+              currentPushRequests.remove(streamId);
+            }
+          }
+        } catch (IOException ignored) {
+        }
+      }
+    });
+  }
+
+  private void pushResetLater(final int streamId, final ErrorCode errorCode) {
+    pushExecutor.execute(new NamedRunnable("OkHttp %s Push Reset[%s]", hostName, streamId) {
+      @Override public void execute() {
+        pushObserver.onReset(streamId, errorCode);
+        synchronized (FramedConnection.this) {
+          currentPushRequests.remove(streamId);
+        }
+      }
+    });
+  }
+
+  /** Listener of streams and settings initiated by the peer. 
+   * @hide This class is not part of the Android public SDK API*/
+  public abstract static class Listener {
+    public static final Listener REFUSE_INCOMING_STREAMS = new Listener() {
+      @Override public void onStream(FramedStream stream) throws IOException {
+        stream.close(ErrorCode.REFUSED_STREAM);
+      }
+    };
+
+    /**
+     * Handle a new stream from this connection's peer. Implementations should
+     * respond by either {@linkplain FramedStream#reply replying to the stream}
+     * or {@linkplain FramedStream#close closing it}. This response does not
+     * need to be synchronous.
+     */
+    public abstract void onStream(FramedStream stream) throws IOException;
+
+    /**
+     * Notification that the connection's peer's settings may have changed.
+     * Implementations should take appropriate action to handle the updated
+     * settings.
+     *
+     * <p>It is the implementation's responsibility to handle concurrent calls
+     * to this method. A remote peer that sends multiple settings frames will
+     * trigger multiple calls to this method, and those calls are not
+     * necessarily serialized.
+     */
+    public void onSettings(FramedConnection connection) {
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/FramedStream.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/FramedStream.java
new file mode 100644
index 0000000..9339acf
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/FramedStream.java
@@ -0,0 +1,618 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.okhttp.internal.framed;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.SocketTimeoutException;
+import java.util.ArrayList;
+import java.util.List;
+import com.android.okhttp.okio.AsyncTimeout;
+import com.android.okhttp.okio.Buffer;
+import com.android.okhttp.okio.BufferedSource;
+import com.android.okhttp.okio.Sink;
+import com.android.okhttp.okio.Source;
+import com.android.okhttp.okio.Timeout;
+
+import static com.android.okhttp.internal.framed.Settings.DEFAULT_INITIAL_WINDOW_SIZE;
+
+/** A logical bidirectional stream. 
+ * @hide This class is not part of the Android public SDK API*/
+public final class FramedStream {
+  // Internal state is guarded by this. No long-running or potentially
+  // blocking operations are performed while the lock is held.
+
+  /**
+   * The total number of bytes consumed by the application (with {@link
+   * FramedDataSource#read}), but not yet acknowledged by sending a {@code
+   * WINDOW_UPDATE} frame on this stream.
+   */
+  // Visible for testing
+  long unacknowledgedBytesRead = 0;
+
+  /**
+   * Count of bytes that can be written on the stream before receiving a
+   * window update. Even if this is positive, writes will block until there
+   * available bytes in {@code connection.bytesLeftInWriteWindow}.
+   */
+  // guarded by this
+  long bytesLeftInWriteWindow;
+
+  private final int id;
+  private final FramedConnection connection;
+
+  /** Headers sent by the stream initiator. Immutable and non null. */
+  private final List<Header> requestHeaders;
+
+  /** Headers sent in the stream reply. Null if reply is either not sent or not sent yet. */
+  private List<Header> responseHeaders;
+
+  private final FramedDataSource source;
+  final FramedDataSink sink;
+  private final StreamTimeout readTimeout = new StreamTimeout();
+  private final StreamTimeout writeTimeout = new StreamTimeout();
+
+  /**
+   * 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 ErrorCode errorCode = null;
+
+  FramedStream(int id, FramedConnection connection, boolean outFinished, boolean inFinished,
+      List<Header> requestHeaders) {
+    if (connection == null) throw new NullPointerException("connection == null");
+    if (requestHeaders == null) throw new NullPointerException("requestHeaders == null");
+    this.id = id;
+    this.connection = connection;
+    this.bytesLeftInWriteWindow =
+        connection.peerSettings.getInitialWindowSize(DEFAULT_INITIAL_WINDOW_SIZE);
+    this.source = new FramedDataSource(
+        connection.okHttpSettings.getInitialWindowSize(DEFAULT_INITIAL_WINDOW_SIZE));
+    this.sink = new FramedDataSink();
+    this.source.finished = inFinished;
+    this.sink.finished = outFinished;
+    this.requestHeaders = requestHeaders;
+  }
+
+  public int getId() {
+    return id;
+  }
+
+  /**
+   * Returns true if this stream is open. A stream is open until either:
+   * <ul>
+   * <li>A {@code SYN_RESET} frame abnormally terminates the stream.
+   * <li>Both input and output streams have transmitted all data and
+   * headers.
+   * </ul>
+   * Note that the input stream may continue to yield data even after a stream
+   * reports itself as not open. This is because input data is buffered.
+   */
+  public synchronized boolean isOpen() {
+    if (errorCode != null) {
+      return false;
+    }
+    if ((source.finished || source.closed)
+        && (sink.finished || sink.closed)
+        && responseHeaders != null) {
+      return false;
+    }
+    return true;
+  }
+
+  /** Returns true if this stream was created by this peer. */
+  public boolean isLocallyInitiated() {
+    boolean streamIsClient = ((id & 1) == 1);
+    return connection.client == streamIsClient;
+  }
+
+  public FramedConnection getConnection() {
+    return connection;
+  }
+
+  public List<Header> getRequestHeaders() {
+    return requestHeaders;
+  }
+
+  /**
+   * Returns the stream's response headers, blocking if necessary if they
+   * have not been received yet.
+   */
+  public synchronized List<Header> getResponseHeaders() throws IOException {
+    readTimeout.enter();
+    try {
+      while (responseHeaders == null && errorCode == null) {
+        waitForIo();
+      }
+    } finally {
+      readTimeout.exitAndThrowIfTimedOut();
+    }
+    if (responseHeaders != null) return responseHeaders;
+    throw new IOException("stream was reset: " + errorCode);
+  }
+
+  /**
+   * Returns the reason why this stream was closed, or null if it closed
+   * normally or has not yet been closed.
+   */
+  public synchronized ErrorCode getErrorCode() {
+    return errorCode;
+  }
+
+  /**
+   * Sends a reply to an incoming 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}.
+   */
+  public void reply(List<Header> responseHeaders, boolean out) throws IOException {
+    assert (!Thread.holdsLock(FramedStream.this));
+    boolean outFinished = false;
+    synchronized (this) {
+      if (responseHeaders == null) {
+        throw new NullPointerException("responseHeaders == null");
+      }
+      if (this.responseHeaders != null) {
+        throw new IllegalStateException("reply already sent");
+      }
+      this.responseHeaders = responseHeaders;
+      if (!out) {
+        this.sink.finished = true;
+        outFinished = true;
+      }
+    }
+    connection.writeSynReply(id, outFinished, responseHeaders);
+
+    if (outFinished) {
+      connection.flush();
+    }
+  }
+
+  public Timeout readTimeout() {
+    return readTimeout;
+  }
+
+  public Timeout writeTimeout() {
+    return writeTimeout;
+  }
+
+  /** Returns a source that reads data from the peer. */
+  public Source getSource() {
+    return source;
+  }
+
+  /**
+   * Returns a sink that can be used to write data to the peer.
+   *
+   * @throws IllegalStateException if this stream was initiated by the peer
+   *     and a {@link #reply} has not yet been sent.
+   */
+  public Sink getSink() {
+    synchronized (this) {
+      if (responseHeaders == null && !isLocallyInitiated()) {
+        throw new IllegalStateException("reply before requesting the sink");
+      }
+    }
+    return sink;
+  }
+
+  /**
+   * Abnormally terminate this stream. This blocks until the {@code RST_STREAM}
+   * frame has been transmitted.
+   */
+  public void close(ErrorCode rstStatusCode) throws IOException {
+    if (!closeInternal(rstStatusCode)) {
+      return; // Already closed.
+    }
+    connection.writeSynReset(id, rstStatusCode);
+  }
+
+  /**
+   * Abnormally terminate this stream. This enqueues a {@code RST_STREAM}
+   * frame and returns immediately.
+   */
+  public void closeLater(ErrorCode errorCode) {
+    if (!closeInternal(errorCode)) {
+      return; // Already closed.
+    }
+    connection.writeSynResetLater(id, errorCode);
+  }
+
+  /** Returns true if this stream was closed. */
+  private boolean closeInternal(ErrorCode errorCode) {
+    assert (!Thread.holdsLock(this));
+    synchronized (this) {
+      if (this.errorCode != null) {
+        return false;
+      }
+      if (source.finished && sink.finished) {
+        return false;
+      }
+      this.errorCode = errorCode;
+      notifyAll();
+    }
+    connection.removeStream(id);
+    return true;
+  }
+
+  void receiveHeaders(List<Header> headers, HeadersMode headersMode) {
+    assert (!Thread.holdsLock(FramedStream.this));
+    ErrorCode errorCode = null;
+    boolean open = true;
+    synchronized (this) {
+      if (responseHeaders == null) {
+        if (headersMode.failIfHeadersAbsent()) {
+          errorCode = ErrorCode.PROTOCOL_ERROR;
+        } else {
+          responseHeaders = headers;
+          open = isOpen();
+          notifyAll();
+        }
+      } else {
+        if (headersMode.failIfHeadersPresent()) {
+          errorCode = ErrorCode.STREAM_IN_USE;
+        } else {
+          List<Header> newHeaders = new ArrayList<>();
+          newHeaders.addAll(responseHeaders);
+          newHeaders.addAll(headers);
+          this.responseHeaders = newHeaders;
+        }
+      }
+    }
+    if (errorCode != null) {
+      closeLater(errorCode);
+    } else if (!open) {
+      connection.removeStream(id);
+    }
+  }
+
+  void receiveData(BufferedSource in, int length) throws IOException {
+    assert (!Thread.holdsLock(FramedStream.this));
+    this.source.receive(in, length);
+  }
+
+  void receiveFin() {
+    assert (!Thread.holdsLock(FramedStream.this));
+    boolean open;
+    synchronized (this) {
+      this.source.finished = true;
+      open = isOpen();
+      notifyAll();
+    }
+    if (!open) {
+      connection.removeStream(id);
+    }
+  }
+
+  synchronized void receiveRstStream(ErrorCode errorCode) {
+    if (this.errorCode == null) {
+      this.errorCode = errorCode;
+      notifyAll();
+    }
+  }
+
+  /**
+   * A source 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 FramedDataSource implements Source {
+    /** Buffer to receive data from the network into. Only accessed by the reader thread. */
+    private final Buffer receiveBuffer = new Buffer();
+
+    /** Buffer with readable data. Guarded by FramedStream.this. */
+    private final Buffer readBuffer = new Buffer();
+
+    /** Maximum number of bytes to buffer before reporting a flow control error. */
+    private final long maxByteCount;
+
+    /** True if the caller has closed this stream. */
+    private boolean closed;
+
+    /**
+     * True if either side has cleanly shut down this stream. We will
+     * receive no more bytes beyond those already in the buffer.
+     */
+    private boolean finished;
+
+    private FramedDataSource(long maxByteCount) {
+      this.maxByteCount = maxByteCount;
+    }
+
+    @Override public long read(Buffer sink, long byteCount)
+        throws IOException {
+      if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
+
+      long read;
+      synchronized (FramedStream.this) {
+        waitUntilReadable();
+        checkNotClosed();
+        if (readBuffer.size() == 0) return -1; // This source is exhausted.
+
+        // Move bytes from the read buffer into the caller's buffer.
+        read = readBuffer.read(sink, Math.min(byteCount, readBuffer.size()));
+
+        // Flow control: notify the peer that we're ready for more data!
+        unacknowledgedBytesRead += read;
+        if (unacknowledgedBytesRead
+            >= connection.okHttpSettings.getInitialWindowSize(DEFAULT_INITIAL_WINDOW_SIZE) / 2) {
+          connection.writeWindowUpdateLater(id, unacknowledgedBytesRead);
+          unacknowledgedBytesRead = 0;
+        }
+      }
+
+      // Update connection.unacknowledgedBytesRead outside the stream lock.
+      synchronized (connection) { // Multiple application threads may hit this section.
+        connection.unacknowledgedBytesRead += read;
+        if (connection.unacknowledgedBytesRead
+            >= connection.okHttpSettings.getInitialWindowSize(DEFAULT_INITIAL_WINDOW_SIZE) / 2) {
+          connection.writeWindowUpdateLater(0, connection.unacknowledgedBytesRead);
+          connection.unacknowledgedBytesRead = 0;
+        }
+      }
+
+      return read;
+    }
+
+    /** Returns once the source is either readable or finished. */
+    private void waitUntilReadable() throws IOException {
+      readTimeout.enter();
+      try {
+        while (readBuffer.size() == 0 && !finished && !closed && errorCode == null) {
+          waitForIo();
+        }
+      } finally {
+        readTimeout.exitAndThrowIfTimedOut();
+      }
+    }
+
+    void receive(BufferedSource in, long byteCount) throws IOException {
+      assert (!Thread.holdsLock(FramedStream.this));
+
+      while (byteCount > 0) {
+        boolean finished;
+        boolean flowControlError;
+        synchronized (FramedStream.this) {
+          finished = this.finished;
+          flowControlError = byteCount + readBuffer.size() > maxByteCount;
+        }
+
+        // If the peer sends more data than we can handle, discard it and close the connection.
+        if (flowControlError) {
+          in.skip(byteCount);
+          closeLater(ErrorCode.FLOW_CONTROL_ERROR);
+          return;
+        }
+
+        // Discard data received after the stream is finished. It's probably a benign race.
+        if (finished) {
+          in.skip(byteCount);
+          return;
+        }
+
+        // Fill the receive buffer without holding any locks.
+        long read = in.read(receiveBuffer, byteCount);
+        if (read == -1) throw new EOFException();
+        byteCount -= read;
+
+        // Move the received data to the read buffer to the reader can read it.
+        synchronized (FramedStream.this) {
+          boolean wasEmpty = readBuffer.size() == 0;
+          readBuffer.writeAll(receiveBuffer);
+          if (wasEmpty) {
+            FramedStream.this.notifyAll();
+          }
+        }
+      }
+    }
+
+    @Override public Timeout timeout() {
+      return readTimeout;
+    }
+
+    @Override public void close() throws IOException {
+      synchronized (FramedStream.this) {
+        closed = true;
+        readBuffer.clear();
+        FramedStream.this.notifyAll();
+      }
+      cancelStreamIfNecessary();
+    }
+
+    private void checkNotClosed() throws IOException {
+      if (closed) {
+        throw new IOException("stream closed");
+      }
+      if (errorCode != null) {
+        throw new IOException("stream was reset: " + errorCode);
+      }
+    }
+  }
+
+  private void cancelStreamIfNecessary() throws IOException {
+    assert (!Thread.holdsLock(FramedStream.this));
+    boolean open;
+    boolean cancel;
+    synchronized (this) {
+      cancel = !source.finished && source.closed && (sink.finished || sink.closed);
+      open = isOpen();
+    }
+    if (cancel) {
+      // RST this stream to prevent additional data from being sent. This
+      // is safe because the input stream is closed (we won't use any
+      // further bytes) and the output stream is either finished or closed
+      // (so RSTing both streams doesn't cause harm).
+      FramedStream.this.close(ErrorCode.CANCEL);
+    } else if (!open) {
+      connection.removeStream(id);
+    }
+  }
+
+  /**
+   * A sink that writes outgoing data frames of a stream. This class is not
+   * thread safe.
+   */
+  final class FramedDataSink implements Sink {
+    private static final long EMIT_BUFFER_SIZE = 16384;
+
+    /**
+     * Buffer of outgoing data. This batches writes of small writes into this sink as larges
+     * frames written to the outgoing connection. Batching saves the (small) framing overhead.
+     */
+    private final Buffer sendBuffer = new Buffer();
+
+    private boolean closed;
+
+    /**
+     * True if either side has cleanly shut down this stream. We shall send
+     * no more bytes.
+     */
+    private boolean finished;
+
+    @Override public void write(Buffer source, long byteCount) throws IOException {
+      assert (!Thread.holdsLock(FramedStream.this));
+      sendBuffer.write(source, byteCount);
+      while (sendBuffer.size() >= EMIT_BUFFER_SIZE) {
+        emitDataFrame(false);
+      }
+    }
+
+    /**
+     * Emit a single data frame to the connection. The frame's size be limited by this stream's
+     * write window. This method will block until the write window is nonempty.
+     */
+    private void emitDataFrame(boolean outFinished) throws IOException {
+      long toWrite;
+      synchronized (FramedStream.this) {
+        writeTimeout.enter();
+        try {
+          while (bytesLeftInWriteWindow <= 0 && !finished && !closed && errorCode == null) {
+            waitForIo(); // Wait until we receive a WINDOW_UPDATE for this stream.
+          }
+        } finally {
+          writeTimeout.exitAndThrowIfTimedOut();
+        }
+
+        checkOutNotClosed(); // Kick out if the stream was reset or closed while waiting.
+        toWrite = Math.min(bytesLeftInWriteWindow, sendBuffer.size());
+        bytesLeftInWriteWindow -= toWrite;
+      }
+
+      writeTimeout.enter();
+      try {
+        connection.writeData(id, outFinished && toWrite == sendBuffer.size(), sendBuffer, toWrite);
+      } finally {
+        writeTimeout.exitAndThrowIfTimedOut();
+      }
+    }
+
+    @Override public void flush() throws IOException {
+      assert (!Thread.holdsLock(FramedStream.this));
+      synchronized (FramedStream.this) {
+        checkOutNotClosed();
+      }
+      while (sendBuffer.size() > 0) {
+        emitDataFrame(false);
+        connection.flush();
+      }
+    }
+
+    @Override public Timeout timeout() {
+      return writeTimeout;
+    }
+
+    @Override public void close() throws IOException {
+      assert (!Thread.holdsLock(FramedStream.this));
+      synchronized (FramedStream.this) {
+        if (closed) return;
+      }
+      if (!sink.finished) {
+        // Emit the remaining data, setting the END_STREAM flag on the last frame.
+        if (sendBuffer.size() > 0) {
+          while (sendBuffer.size() > 0) {
+            emitDataFrame(true);
+          }
+        } else {
+          // Send an empty frame just so we can set the END_STREAM flag.
+          connection.writeData(id, true, null, 0);
+        }
+      }
+      synchronized (FramedStream.this) {
+        closed = true;
+      }
+      connection.flush();
+      cancelStreamIfNecessary();
+    }
+  }
+
+  /**
+   * {@code delta} will be negative if a settings frame initial window is
+   * smaller than the last.
+   */
+  void addBytesToWriteWindow(long delta) {
+    bytesLeftInWriteWindow += delta;
+    if (delta > 0) FramedStream.this.notifyAll();
+  }
+
+  private void checkOutNotClosed() throws IOException {
+    if (sink.closed) {
+      throw new IOException("stream closed");
+    } else if (sink.finished) {
+      throw new IOException("stream finished");
+    } else if (errorCode != null) {
+      throw new IOException("stream was reset: " + errorCode);
+    }
+  }
+
+  /**
+   * Like {@link #wait}, but throws an {@code InterruptedIOException} when
+   * interrupted instead of the more awkward {@link InterruptedException}.
+   */
+  private void waitForIo() throws InterruptedIOException {
+    try {
+      wait();
+    } catch (InterruptedException e) {
+      throw new InterruptedIOException();
+    }
+  }
+
+  /**
+   * The Okio timeout watchdog will call {@link #timedOut} if the timeout is
+   * reached. In that case we close the stream (asynchronously) which will
+   * notify the waiting thread.
+   */
+  class StreamTimeout extends AsyncTimeout {
+    @Override protected void timedOut() {
+      closeLater(ErrorCode.CANCEL);
+    }
+
+    @Override protected IOException newTimeoutException(IOException cause) {
+      SocketTimeoutException socketTimeoutException = new SocketTimeoutException("timeout");
+      if (cause != null) {
+        socketTimeoutException.initCause(cause);
+      }
+      return socketTimeoutException;
+    }
+
+    public void exitAndThrowIfTimedOut() throws IOException {
+      if (exit()) throw newTimeoutException(null /* cause */);
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Header.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Header.java
new file mode 100644
index 0000000..4e2c67f
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Header.java
@@ -0,0 +1,58 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.okhttp.internal.framed;
+
+import com.android.okhttp.okio.ByteString;
+
+/** HTTP header: the name is an ASCII string, but the value can be UTF-8. 
+ * @hide This class is not part of the Android public SDK API*/
+public final class Header {
+  // Special header names defined in the SPDY and HTTP/2 specs.
+  public static final ByteString RESPONSE_STATUS = ByteString.encodeUtf8(":status");
+  public static final ByteString TARGET_METHOD = ByteString.encodeUtf8(":method");
+  public static final ByteString TARGET_PATH = ByteString.encodeUtf8(":path");
+  public static final ByteString TARGET_SCHEME = ByteString.encodeUtf8(":scheme");
+  public static final ByteString TARGET_AUTHORITY = ByteString.encodeUtf8(":authority"); // HTTP/2
+  public static final ByteString TARGET_HOST = ByteString.encodeUtf8(":host"); // spdy/3
+  public static final ByteString VERSION = ByteString.encodeUtf8(":version"); // spdy/3
+
+  /** Name in case-insensitive ASCII encoding. */
+  public final ByteString name;
+  /** Value in UTF-8 encoding. */
+  public final ByteString value;
+  final int hpackSize;
+
+  // TODO: search for toLowerCase and consider moving logic here.
+  public Header(String name, String value) {
+    this(ByteString.encodeUtf8(name), ByteString.encodeUtf8(value));
+  }
+
+  public Header(ByteString name, String value) {
+    this(name, ByteString.encodeUtf8(value));
+  }
+
+  public Header(ByteString name, ByteString value) {
+    this.name = name;
+    this.value = value;
+    this.hpackSize = 32 + name.size() + value.size();
+  }
+
+  @Override public boolean equals(Object other) {
+    if (other instanceof Header) {
+      Header that = (Header) other;
+      return this.name.equals(that.name)
+          && this.value.equals(that.value);
+    }
+    return false;
+  }
+
+  @Override public int hashCode() {
+    int result = 17;
+    result = 31 * result + name.hashCode();
+    result = 31 * result + value.hashCode();
+    return result;
+  }
+
+  @Override public String toString() {
+    return String.format("%s: %s", name.utf8(), value.utf8());
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/HeadersMode.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/HeadersMode.java
new file mode 100644
index 0000000..bcbb492
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/HeadersMode.java
@@ -0,0 +1,53 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.okhttp.internal.framed;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public enum HeadersMode {
+  SPDY_SYN_STREAM,
+  SPDY_REPLY,
+  SPDY_HEADERS,
+  HTTP_20_HEADERS;
+
+  /** Returns true if it is an error these headers to create a new stream. */
+  public boolean failIfStreamAbsent() {
+    return this == SPDY_REPLY || this == SPDY_HEADERS;
+  }
+
+  /** Returns true if it is an error these headers to update an existing stream. */
+  public boolean failIfStreamPresent() {
+    return this == SPDY_SYN_STREAM;
+  }
+
+  /**
+   * Returns true if it is an error these headers to be the initial headers of a
+   * response.
+   */
+  public boolean failIfHeadersAbsent() {
+    return this == SPDY_HEADERS;
+  }
+
+  /**
+   * Returns true if it is an error these headers to be update existing headers
+   * of a response.
+   */
+  public boolean failIfHeadersPresent() {
+    return this == SPDY_REPLY;
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Hpack.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Hpack.java
new file mode 100644
index 0000000..538e498
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Hpack.java
@@ -0,0 +1,436 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.okhttp.internal.framed;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import com.android.okhttp.okio.Buffer;
+import com.android.okhttp.okio.BufferedSource;
+import com.android.okhttp.okio.ByteString;
+import com.android.okhttp.okio.Okio;
+import com.android.okhttp.okio.Source;
+
+/**
+ * Read and write HPACK v10.
+ *
+ * http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-12
+ *
+ * This implementation uses an array for the dynamic table and a list for
+ * indexed entries.  Dynamic entries are added to the array, starting in the
+ * last position moving forward.  When the array fills, it is doubled.
+ */
+final class Hpack {
+  private static final int PREFIX_4_BITS = 0x0f;
+  private static final int PREFIX_5_BITS = 0x1f;
+  private static final int PREFIX_6_BITS = 0x3f;
+  private static final int PREFIX_7_BITS = 0x7f;
+
+  private static final Header[] STATIC_HEADER_TABLE = new Header[] {
+      new Header(Header.TARGET_AUTHORITY, ""),
+      new Header(Header.TARGET_METHOD, "GET"),
+      new Header(Header.TARGET_METHOD, "POST"),
+      new Header(Header.TARGET_PATH, "/"),
+      new Header(Header.TARGET_PATH, "/index.html"),
+      new Header(Header.TARGET_SCHEME, "http"),
+      new Header(Header.TARGET_SCHEME, "https"),
+      new Header(Header.RESPONSE_STATUS, "200"),
+      new Header(Header.RESPONSE_STATUS, "204"),
+      new Header(Header.RESPONSE_STATUS, "206"),
+      new Header(Header.RESPONSE_STATUS, "304"),
+      new Header(Header.RESPONSE_STATUS, "400"),
+      new Header(Header.RESPONSE_STATUS, "404"),
+      new Header(Header.RESPONSE_STATUS, "500"),
+      new Header("accept-charset", ""),
+      new Header("accept-encoding", "gzip, deflate"),
+      new Header("accept-language", ""),
+      new Header("accept-ranges", ""),
+      new Header("accept", ""),
+      new Header("access-control-allow-origin", ""),
+      new Header("age", ""),
+      new Header("allow", ""),
+      new Header("authorization", ""),
+      new Header("cache-control", ""),
+      new Header("content-disposition", ""),
+      new Header("content-encoding", ""),
+      new Header("content-language", ""),
+      new Header("content-length", ""),
+      new Header("content-location", ""),
+      new Header("content-range", ""),
+      new Header("content-type", ""),
+      new Header("cookie", ""),
+      new Header("date", ""),
+      new Header("etag", ""),
+      new Header("expect", ""),
+      new Header("expires", ""),
+      new Header("from", ""),
+      new Header("host", ""),
+      new Header("if-match", ""),
+      new Header("if-modified-since", ""),
+      new Header("if-none-match", ""),
+      new Header("if-range", ""),
+      new Header("if-unmodified-since", ""),
+      new Header("last-modified", ""),
+      new Header("link", ""),
+      new Header("location", ""),
+      new Header("max-forwards", ""),
+      new Header("proxy-authenticate", ""),
+      new Header("proxy-authorization", ""),
+      new Header("range", ""),
+      new Header("referer", ""),
+      new Header("refresh", ""),
+      new Header("retry-after", ""),
+      new Header("server", ""),
+      new Header("set-cookie", ""),
+      new Header("strict-transport-security", ""),
+      new Header("transfer-encoding", ""),
+      new Header("user-agent", ""),
+      new Header("vary", ""),
+      new Header("via", ""),
+      new Header("www-authenticate", "")
+  };
+
+  private Hpack() {
+  }
+
+  // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-12#section-3.1
+  static final class Reader {
+
+    private final List<Header> headerList = new ArrayList<>();
+    private final BufferedSource source;
+
+    private int headerTableSizeSetting;
+    private int maxDynamicTableByteCount;
+    // Visible for testing.
+    Header[] dynamicTable = new Header[8];
+    // Array is populated back to front, so new entries always have lowest index.
+    int nextHeaderIndex = dynamicTable.length - 1;
+    int headerCount = 0;
+    int dynamicTableByteCount = 0;
+
+    Reader(int headerTableSizeSetting, Source source) {
+      this.headerTableSizeSetting = headerTableSizeSetting;
+      this.maxDynamicTableByteCount = headerTableSizeSetting;
+      this.source = Okio.buffer(source);
+    }
+
+    int maxDynamicTableByteCount() {
+      return maxDynamicTableByteCount;
+    }
+
+    /**
+     * Called by the reader when the peer sent {@link Settings#HEADER_TABLE_SIZE}.
+     * While this establishes the maximum dynamic table size, the
+     * {@link #maxDynamicTableByteCount} set during processing may limit the
+     * table size to a smaller amount.
+     * <p> Evicts entries or clears the table as needed.
+     */
+    void headerTableSizeSetting(int headerTableSizeSetting) {
+      this.headerTableSizeSetting = headerTableSizeSetting;
+      this.maxDynamicTableByteCount = headerTableSizeSetting;
+      adjustDynamicTableByteCount();
+    }
+
+    private void adjustDynamicTableByteCount() {
+      if (maxDynamicTableByteCount < dynamicTableByteCount) {
+        if (maxDynamicTableByteCount == 0) {
+          clearDynamicTable();
+        } else {
+          evictToRecoverBytes(dynamicTableByteCount - maxDynamicTableByteCount);
+        }
+      }
+    }
+
+    private void clearDynamicTable() {
+      headerList.clear();
+      Arrays.fill(dynamicTable, null);
+      nextHeaderIndex = dynamicTable.length - 1;
+      headerCount = 0;
+      dynamicTableByteCount = 0;
+    }
+
+    /** Returns the count of entries evicted. */
+    private int evictToRecoverBytes(int bytesToRecover) {
+      int entriesToEvict = 0;
+      if (bytesToRecover > 0) {
+        // determine how many headers need to be evicted.
+        for (int j = dynamicTable.length - 1; j >= nextHeaderIndex && bytesToRecover > 0; j--) {
+          bytesToRecover -= dynamicTable[j].hpackSize;
+          dynamicTableByteCount -= dynamicTable[j].hpackSize;
+          headerCount--;
+          entriesToEvict++;
+        }
+        System.arraycopy(dynamicTable, nextHeaderIndex + 1, dynamicTable,
+            nextHeaderIndex + 1 + entriesToEvict, headerCount);
+        nextHeaderIndex += entriesToEvict;
+      }
+      return entriesToEvict;
+    }
+
+    /**
+     * Read {@code byteCount} bytes of headers from the source stream. This
+     * implementation does not propagate the never indexed flag of a header.
+     */
+    void readHeaders() throws IOException {
+      while (!source.exhausted()) {
+        int b = source.readByte() & 0xff;
+        if (b == 0x80) { // 10000000
+          throw new IOException("index == 0");
+        } else if ((b & 0x80) == 0x80) { // 1NNNNNNN
+          int index = readInt(b, PREFIX_7_BITS);
+          readIndexedHeader(index - 1);
+        } else if (b == 0x40) { // 01000000
+          readLiteralHeaderWithIncrementalIndexingNewName();
+        } else if ((b & 0x40) == 0x40) {  // 01NNNNNN
+          int index = readInt(b, PREFIX_6_BITS);
+          readLiteralHeaderWithIncrementalIndexingIndexedName(index - 1);
+        } else if ((b & 0x20) == 0x20) {  // 001NNNNN
+          maxDynamicTableByteCount = readInt(b, PREFIX_5_BITS);
+          if (maxDynamicTableByteCount < 0
+              || maxDynamicTableByteCount > headerTableSizeSetting) {
+            throw new IOException("Invalid dynamic table size update " + maxDynamicTableByteCount);
+          }
+          adjustDynamicTableByteCount();
+        } else if (b == 0x10 || b == 0) { // 000?0000 - Ignore never indexed bit.
+          readLiteralHeaderWithoutIndexingNewName();
+        } else { // 000?NNNN - Ignore never indexed bit.
+          int index = readInt(b, PREFIX_4_BITS);
+          readLiteralHeaderWithoutIndexingIndexedName(index - 1);
+        }
+      }
+    }
+
+    public List<Header> getAndResetHeaderList() {
+      List<Header> result = new ArrayList<>(headerList);
+      headerList.clear();
+      return result;
+    }
+
+    private void readIndexedHeader(int index) throws IOException {
+      if (isStaticHeader(index)) {
+        Header staticEntry = STATIC_HEADER_TABLE[index];
+        headerList.add(staticEntry);
+      } else {
+        int dynamicTableIndex = dynamicTableIndex(index - STATIC_HEADER_TABLE.length);
+        if (dynamicTableIndex < 0 || dynamicTableIndex > dynamicTable.length - 1) {
+          throw new IOException("Header index too large " + (index + 1));
+        }
+        headerList.add(dynamicTable[dynamicTableIndex]);
+      }
+    }
+
+    // referencedHeaders is relative to nextHeaderIndex + 1.
+    private int dynamicTableIndex(int index) {
+      return nextHeaderIndex + 1 + index;
+    }
+
+    private void readLiteralHeaderWithoutIndexingIndexedName(int index) throws IOException {
+      ByteString name = getName(index);
+      ByteString value = readByteString();
+      headerList.add(new Header(name, value));
+    }
+
+    private void readLiteralHeaderWithoutIndexingNewName() throws IOException {
+      ByteString name = checkLowercase(readByteString());
+      ByteString value = readByteString();
+      headerList.add(new Header(name, value));
+    }
+
+    private void readLiteralHeaderWithIncrementalIndexingIndexedName(int nameIndex)
+        throws IOException {
+      ByteString name = getName(nameIndex);
+      ByteString value = readByteString();
+      insertIntoDynamicTable(-1, new Header(name, value));
+    }
+
+    private void readLiteralHeaderWithIncrementalIndexingNewName() throws IOException {
+      ByteString name = checkLowercase(readByteString());
+      ByteString value = readByteString();
+      insertIntoDynamicTable(-1, new Header(name, value));
+    }
+
+    private ByteString getName(int index) {
+      if (isStaticHeader(index)) {
+        return STATIC_HEADER_TABLE[index].name;
+      } else {
+        return dynamicTable[dynamicTableIndex(index - STATIC_HEADER_TABLE.length)].name;
+      }
+    }
+
+    private boolean isStaticHeader(int index) {
+      return index >= 0 && index <= STATIC_HEADER_TABLE.length - 1;
+    }
+
+    /** index == -1 when new. */
+    private void insertIntoDynamicTable(int index, Header entry) {
+      headerList.add(entry);
+
+      int delta = entry.hpackSize;
+      if (index != -1) { // Index -1 == new header.
+        delta -= dynamicTable[dynamicTableIndex(index)].hpackSize;
+      }
+
+      // if the new or replacement header is too big, drop all entries.
+      if (delta > maxDynamicTableByteCount) {
+        clearDynamicTable();
+        return;
+      }
+
+      // Evict headers to the required length.
+      int bytesToRecover = (dynamicTableByteCount + delta) - maxDynamicTableByteCount;
+      int entriesEvicted = evictToRecoverBytes(bytesToRecover);
+
+      if (index == -1) { // Adding a value to the dynamic table.
+        if (headerCount + 1 > dynamicTable.length) { // Need to grow the dynamic table.
+          Header[] doubled = new Header[dynamicTable.length * 2];
+          System.arraycopy(dynamicTable, 0, doubled, dynamicTable.length, dynamicTable.length);
+          nextHeaderIndex = dynamicTable.length - 1;
+          dynamicTable = doubled;
+        }
+        index = nextHeaderIndex--;
+        dynamicTable[index] = entry;
+        headerCount++;
+      } else { // Replace value at same position.
+        index += dynamicTableIndex(index) + entriesEvicted;
+        dynamicTable[index] = entry;
+      }
+      dynamicTableByteCount += delta;
+    }
+
+    private int readByte() throws IOException {
+      return source.readByte() & 0xff;
+    }
+
+    int readInt(int firstByte, int prefixMask) throws IOException {
+      int prefix = firstByte & prefixMask;
+      if (prefix < prefixMask) {
+        return prefix; // This was a single byte value.
+      }
+
+      // This is a multibyte value. Read 7 bits at a time.
+      int result = prefixMask;
+      int shift = 0;
+      while (true) {
+        int b = readByte();
+        if ((b & 0x80) != 0) { // Equivalent to (b >= 128) since b is in [0..255].
+          result += (b & 0x7f) << shift;
+          shift += 7;
+        } else {
+          result += b << shift; // Last byte.
+          break;
+        }
+      }
+      return result;
+    }
+
+    /** Reads a potentially Huffman encoded byte string. */
+    ByteString readByteString() throws IOException {
+      int firstByte = readByte();
+      boolean huffmanDecode = (firstByte & 0x80) == 0x80; // 1NNNNNNN
+      int length = readInt(firstByte, PREFIX_7_BITS);
+
+      if (huffmanDecode) {
+        return ByteString.of(Huffman.get().decode(source.readByteArray(length)));
+      } else {
+        return source.readByteString(length);
+      }
+    }
+  }
+
+  private static final Map<ByteString, Integer> NAME_TO_FIRST_INDEX = nameToFirstIndex();
+
+  private static Map<ByteString, Integer> nameToFirstIndex() {
+    Map<ByteString, Integer> result = new LinkedHashMap<>(STATIC_HEADER_TABLE.length);
+    for (int i = 0; i < STATIC_HEADER_TABLE.length; i++) {
+      if (!result.containsKey(STATIC_HEADER_TABLE[i].name)) {
+        result.put(STATIC_HEADER_TABLE[i].name, i);
+      }
+    }
+    return Collections.unmodifiableMap(result);
+  }
+
+  static final class Writer {
+    private final Buffer out;
+
+    Writer(Buffer out) {
+      this.out = out;
+    }
+
+    /** This does not use "never indexed" semantics for sensitive headers. */
+    // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-12#section-6.2.3
+    void writeHeaders(List<Header> headerBlock) throws IOException {
+      // TODO: implement index tracking
+      for (int i = 0, size = headerBlock.size(); i < size; i++) {
+        ByteString name = headerBlock.get(i).name.toAsciiLowercase();
+        Integer staticIndex = NAME_TO_FIRST_INDEX.get(name);
+        if (staticIndex != null) {
+          // Literal Header Field without Indexing - Indexed Name.
+          writeInt(staticIndex + 1, PREFIX_4_BITS, 0);
+          writeByteString(headerBlock.get(i).value);
+        } else {
+          out.writeByte(0x00); // Literal Header without Indexing - New Name.
+          writeByteString(name);
+          writeByteString(headerBlock.get(i).value);
+        }
+      }
+    }
+
+    // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-12#section-4.1.1
+    void writeInt(int value, int prefixMask, int bits) throws IOException {
+      // Write the raw value for a single byte value.
+      if (value < prefixMask) {
+        out.writeByte(bits | value);
+        return;
+      }
+
+      // Write the mask to start a multibyte value.
+      out.writeByte(bits | prefixMask);
+      value -= prefixMask;
+
+      // Write 7 bits at a time 'til we're done.
+      while (value >= 0x80) {
+        int b = value & 0x7f;
+        out.writeByte(b | 0x80);
+        value >>>= 7;
+      }
+      out.writeByte(value);
+    }
+
+    void writeByteString(ByteString data) throws IOException {
+      writeInt(data.size(), PREFIX_7_BITS, 0);
+      out.write(data);
+    }
+  }
+
+  /**
+   * An HTTP/2 response cannot contain uppercase header characters and must
+   * be treated as malformed.
+   */
+  private static ByteString checkLowercase(ByteString name) throws IOException {
+    for (int i = 0, length = name.size(); i < length; i++) {
+      byte c = name.getByte(i);
+      if (c >= 'A' && c <= 'Z') {
+        throw new IOException("PROTOCOL_ERROR response malformed: mixed case name: " + name.utf8());
+      }
+    }
+    return name;
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Http2.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Http2.java
new file mode 100644
index 0000000..882d7e8
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Http2.java
@@ -0,0 +1,773 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.okhttp.internal.framed;
+
+import com.android.okhttp.Protocol;
+import java.io.IOException;
+import java.util.List;
+import java.util.logging.Logger;
+import com.android.okhttp.okio.Buffer;
+import com.android.okhttp.okio.BufferedSink;
+import com.android.okhttp.okio.BufferedSource;
+import com.android.okhttp.okio.ByteString;
+import com.android.okhttp.okio.Source;
+import com.android.okhttp.okio.Timeout;
+
+import static com.android.okhttp.internal.framed.Http2.FrameLogger.formatHeader;
+import static java.lang.String.format;
+import static java.util.logging.Level.FINE;
+import static com.android.okhttp.okio.ByteString.EMPTY;
+
+/**
+ * Read and write HTTP/2 frames.
+ * <p>
+ * This implementation assumes we do not send an increased
+ * {@link Settings#getMaxFrameSize frame size setting} to the peer. Hence, we
+ * expect all frames to have a max length of {@link #INITIAL_MAX_FRAME_SIZE}.
+ * <p>http://tools.ietf.org/html/draft-ietf-httpbis-http2-17
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Http2 implements Variant {
+  private static final Logger logger = Logger.getLogger(FrameLogger.class.getName());
+
+  @Override public Protocol getProtocol() {
+    return Protocol.HTTP_2;
+  }
+
+  private static final ByteString CONNECTION_PREFACE
+      = ByteString.encodeUtf8("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n");
+
+  /** The initial max frame size, applied independently writing to, or reading from the peer. */
+  static final int INITIAL_MAX_FRAME_SIZE = 0x4000; // 16384
+
+  static final byte TYPE_DATA = 0x0;
+  static final byte TYPE_HEADERS = 0x1;
+  static final byte TYPE_PRIORITY = 0x2;
+  static final byte TYPE_RST_STREAM = 0x3;
+  static final byte TYPE_SETTINGS = 0x4;
+  static final byte TYPE_PUSH_PROMISE = 0x5;
+  static final byte TYPE_PING = 0x6;
+  static final byte TYPE_GOAWAY = 0x7;
+  static final byte TYPE_WINDOW_UPDATE = 0x8;
+  static final byte TYPE_CONTINUATION = 0x9;
+
+  static final byte FLAG_NONE = 0x0;
+  static final byte FLAG_ACK = 0x1; // Used for settings and ping.
+  static final byte FLAG_END_STREAM = 0x1; // Used for headers and data.
+  static final byte FLAG_END_HEADERS = 0x4; // Used for headers and continuation.
+  static final byte FLAG_END_PUSH_PROMISE = 0x4;
+  static final byte FLAG_PADDED = 0x8; // Used for headers and data.
+  static final byte FLAG_PRIORITY = 0x20; // Used for headers.
+  static final byte FLAG_COMPRESSED = 0x20; // Used for data.
+
+  /**
+   * Creates a frame reader with max header table size of 4096 and data frame
+   * compression disabled.
+   */
+  @Override public FrameReader newReader(BufferedSource source, boolean client) {
+    return new Reader(source, 4096, client);
+  }
+
+  @Override public FrameWriter newWriter(BufferedSink sink, boolean client) {
+    return new Writer(sink, client);
+  }
+
+  static final class Reader implements FrameReader {
+    private final BufferedSource source;
+    private final ContinuationSource continuation;
+    private final boolean client;
+
+    // Visible for testing.
+    final Hpack.Reader hpackReader;
+
+    Reader(BufferedSource source, int headerTableSize, boolean client) {
+      this.source = source;
+      this.client = client;
+      this.continuation = new ContinuationSource(this.source);
+      this.hpackReader = new Hpack.Reader(headerTableSize, continuation);
+    }
+
+    @Override public void readConnectionPreface() throws IOException {
+      if (client) return; // Nothing to read; servers doesn't send a connection preface!
+      ByteString connectionPreface = source.readByteString(CONNECTION_PREFACE.size());
+      if (logger.isLoggable(FINE)) logger.fine(format("<< CONNECTION %s", connectionPreface.hex()));
+      if (!CONNECTION_PREFACE.equals(connectionPreface)) {
+        throw ioException("Expected a connection header but was %s", connectionPreface.utf8());
+      }
+    }
+
+    @Override public boolean nextFrame(Handler handler) throws IOException {
+      try {
+        source.require(9); // Frame header size
+      } catch (IOException e) {
+        return false; // This might be a normal socket close.
+      }
+
+      /*  0                   1                   2                   3
+       *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       * |                 Length (24)                   |
+       * +---------------+---------------+---------------+
+       * |   Type (8)    |   Flags (8)   |
+       * +-+-+-----------+---------------+-------------------------------+
+       * |R|                 Stream Identifier (31)                      |
+       * +=+=============================================================+
+       * |                   Frame Payload (0...)                      ...
+       * +---------------------------------------------------------------+
+       */
+      int length = readMedium(source);
+      if (length < 0 || length > INITIAL_MAX_FRAME_SIZE) {
+        throw ioException("FRAME_SIZE_ERROR: %s", length);
+      }
+      byte type = (byte) (source.readByte() & 0xff);
+      byte flags = (byte) (source.readByte() & 0xff);
+      int streamId = (source.readInt() & 0x7fffffff); // Ignore reserved bit.
+      if (logger.isLoggable(FINE)) logger.fine(formatHeader(true, streamId, length, type, flags));
+
+      switch (type) {
+        case TYPE_DATA:
+          readData(handler, length, flags, streamId);
+          break;
+
+        case TYPE_HEADERS:
+          readHeaders(handler, length, flags, streamId);
+          break;
+
+        case TYPE_PRIORITY:
+          readPriority(handler, length, flags, streamId);
+          break;
+
+        case TYPE_RST_STREAM:
+          readRstStream(handler, length, flags, streamId);
+          break;
+
+        case TYPE_SETTINGS:
+          readSettings(handler, length, flags, streamId);
+          break;
+
+        case TYPE_PUSH_PROMISE:
+          readPushPromise(handler, length, flags, streamId);
+          break;
+
+        case TYPE_PING:
+          readPing(handler, length, flags, streamId);
+          break;
+
+        case TYPE_GOAWAY:
+          readGoAway(handler, length, flags, streamId);
+          break;
+
+        case TYPE_WINDOW_UPDATE:
+          readWindowUpdate(handler, length, flags, streamId);
+          break;
+
+        default:
+          // Implementations MUST discard frames that have unknown or unsupported types.
+          source.skip(length);
+      }
+      return true;
+    }
+
+    private void readHeaders(Handler handler, int length, byte flags, int streamId)
+        throws IOException {
+      if (streamId == 0) throw ioException("PROTOCOL_ERROR: TYPE_HEADERS streamId == 0");
+
+      boolean endStream = (flags & FLAG_END_STREAM) != 0;
+
+      short padding = (flags & FLAG_PADDED) != 0 ? (short) (source.readByte() & 0xff) : 0;
+
+      if ((flags & FLAG_PRIORITY) != 0) {
+        readPriority(handler, streamId);
+        length -= 5; // account for above read.
+      }
+
+      length = lengthWithoutPadding(length, flags, padding);
+
+      List<Header> headerBlock = readHeaderBlock(length, padding, flags, streamId);
+
+      handler.headers(false, endStream, streamId, -1, headerBlock, HeadersMode.HTTP_20_HEADERS);
+    }
+
+    private List<Header> readHeaderBlock(int length, short padding, byte flags, int streamId)
+        throws IOException {
+      continuation.length = continuation.left = length;
+      continuation.padding = padding;
+      continuation.flags = flags;
+      continuation.streamId = streamId;
+
+      // TODO: Concat multi-value headers with 0x0, except COOKIE, which uses 0x3B, 0x20.
+      // http://tools.ietf.org/html/draft-ietf-httpbis-http2-17#section-8.1.2.5
+      hpackReader.readHeaders();
+      return hpackReader.getAndResetHeaderList();
+    }
+
+    private void readData(Handler handler, int length, byte flags, int streamId)
+        throws IOException {
+      // TODO: checkState open or half-closed (local) or raise STREAM_CLOSED
+      boolean inFinished = (flags & FLAG_END_STREAM) != 0;
+      boolean gzipped = (flags & FLAG_COMPRESSED) != 0;
+      if (gzipped) {
+        throw ioException("PROTOCOL_ERROR: FLAG_COMPRESSED without SETTINGS_COMPRESS_DATA");
+      }
+
+      short padding = (flags & FLAG_PADDED) != 0 ? (short) (source.readByte() & 0xff) : 0;
+      length = lengthWithoutPadding(length, flags, padding);
+
+      handler.data(inFinished, streamId, source, length);
+      source.skip(padding);
+    }
+
+    private void readPriority(Handler handler, int length, byte flags, int streamId)
+        throws IOException {
+      if (length != 5) throw ioException("TYPE_PRIORITY length: %d != 5", length);
+      if (streamId == 0) throw ioException("TYPE_PRIORITY streamId == 0");
+      readPriority(handler, streamId);
+    }
+
+    private void readPriority(Handler handler, int streamId) throws IOException {
+      int w1 = source.readInt();
+      boolean exclusive = (w1 & 0x80000000) != 0;
+      int streamDependency = (w1 & 0x7fffffff);
+      int weight = (source.readByte() & 0xff) + 1;
+      handler.priority(streamId, streamDependency, weight, exclusive);
+    }
+
+    private void readRstStream(Handler handler, int length, byte flags, int streamId)
+        throws IOException {
+      if (length != 4) throw ioException("TYPE_RST_STREAM length: %d != 4", length);
+      if (streamId == 0) throw ioException("TYPE_RST_STREAM streamId == 0");
+      int errorCodeInt = source.readInt();
+      ErrorCode errorCode = ErrorCode.fromHttp2(errorCodeInt);
+      if (errorCode == null) {
+        throw ioException("TYPE_RST_STREAM unexpected error code: %d", errorCodeInt);
+      }
+      handler.rstStream(streamId, errorCode);
+    }
+
+    private void readSettings(Handler handler, int length, byte flags, int streamId)
+        throws IOException {
+      if (streamId != 0) throw ioException("TYPE_SETTINGS streamId != 0");
+      if ((flags & FLAG_ACK) != 0) {
+        if (length != 0) throw ioException("FRAME_SIZE_ERROR ack frame should be empty!");
+        handler.ackSettings();
+        return;
+      }
+
+      if (length % 6 != 0) throw ioException("TYPE_SETTINGS length %% 6 != 0: %s", length);
+      Settings settings = new Settings();
+      for (int i = 0; i < length; i += 6) {
+        short id = source.readShort();
+        int value = source.readInt();
+
+        switch (id) {
+          case 1: // SETTINGS_HEADER_TABLE_SIZE
+            break;
+          case 2: // SETTINGS_ENABLE_PUSH
+            if (value != 0 && value != 1) {
+              throw ioException("PROTOCOL_ERROR SETTINGS_ENABLE_PUSH != 0 or 1");
+            }
+            break;
+          case 3: // SETTINGS_MAX_CONCURRENT_STREAMS
+            id = 4; // Renumbered in draft 10.
+            break;
+          case 4: // SETTINGS_INITIAL_WINDOW_SIZE
+            id = 7; // Renumbered in draft 10.
+            if (value < 0) {
+              throw ioException("PROTOCOL_ERROR SETTINGS_INITIAL_WINDOW_SIZE > 2^31 - 1");
+            }
+            break;
+          case 5: // SETTINGS_MAX_FRAME_SIZE
+            if (value < INITIAL_MAX_FRAME_SIZE || value > 16777215) {
+              throw ioException("PROTOCOL_ERROR SETTINGS_MAX_FRAME_SIZE: %s", value);
+            }
+            break;
+          case 6: // SETTINGS_MAX_HEADER_LIST_SIZE
+            break; // Advisory only, so ignored.
+          default:
+            throw ioException("PROTOCOL_ERROR invalid settings id: %s", id);
+        }
+        settings.set(id, 0, value);
+      }
+      handler.settings(false, settings);
+      if (settings.getHeaderTableSize() >= 0) {
+        hpackReader.headerTableSizeSetting(settings.getHeaderTableSize());
+      }
+    }
+
+    private void readPushPromise(Handler handler, int length, byte flags, int streamId)
+        throws IOException {
+      if (streamId == 0) {
+        throw ioException("PROTOCOL_ERROR: TYPE_PUSH_PROMISE streamId == 0");
+      }
+      short padding = (flags & FLAG_PADDED) != 0 ? (short) (source.readByte() & 0xff) : 0;
+      int promisedStreamId = source.readInt() & 0x7fffffff;
+      length -= 4; // account for above read.
+      length = lengthWithoutPadding(length, flags, padding);
+      List<Header> headerBlock = readHeaderBlock(length, padding, flags, streamId);
+      handler.pushPromise(streamId, promisedStreamId, headerBlock);
+    }
+
+    private void readPing(Handler handler, int length, byte flags, int streamId)
+        throws IOException {
+      if (length != 8) throw ioException("TYPE_PING length != 8: %s", length);
+      if (streamId != 0) throw ioException("TYPE_PING streamId != 0");
+      int payload1 = source.readInt();
+      int payload2 = source.readInt();
+      boolean ack = (flags & FLAG_ACK) != 0;
+      handler.ping(ack, payload1, payload2);
+    }
+
+    private void readGoAway(Handler handler, int length, byte flags, int streamId)
+        throws IOException {
+      if (length < 8) throw ioException("TYPE_GOAWAY length < 8: %s", length);
+      if (streamId != 0) throw ioException("TYPE_GOAWAY streamId != 0");
+      int lastStreamId = source.readInt();
+      int errorCodeInt = source.readInt();
+      int opaqueDataLength = length - 8;
+      ErrorCode errorCode = ErrorCode.fromHttp2(errorCodeInt);
+      if (errorCode == null) {
+        throw ioException("TYPE_GOAWAY unexpected error code: %d", errorCodeInt);
+      }
+      ByteString debugData = EMPTY;
+      if (opaqueDataLength > 0) { // Must read debug data in order to not corrupt the connection.
+        debugData = source.readByteString(opaqueDataLength);
+      }
+      handler.goAway(lastStreamId, errorCode, debugData);
+    }
+
+    private void readWindowUpdate(Handler handler, int length, byte flags, int streamId)
+        throws IOException {
+      if (length != 4) throw ioException("TYPE_WINDOW_UPDATE length !=4: %s", length);
+      long increment = (source.readInt() & 0x7fffffffL);
+      if (increment == 0) throw ioException("windowSizeIncrement was 0", increment);
+      handler.windowUpdate(streamId, increment);
+    }
+
+    @Override public void close() throws IOException {
+      source.close();
+    }
+  }
+
+  static final class Writer implements FrameWriter {
+    private final BufferedSink sink;
+    private final boolean client;
+    private final Buffer hpackBuffer;
+    private final Hpack.Writer hpackWriter;
+    private int maxFrameSize;
+    private boolean closed;
+
+    Writer(BufferedSink sink, boolean client) {
+      this.sink = sink;
+      this.client = client;
+      this.hpackBuffer = new Buffer();
+      this.hpackWriter = new Hpack.Writer(hpackBuffer);
+      this.maxFrameSize = INITIAL_MAX_FRAME_SIZE;
+    }
+
+    @Override public synchronized void flush() throws IOException {
+      if (closed) throw new IOException("closed");
+      sink.flush();
+    }
+
+    @Override public synchronized void ackSettings(Settings peerSettings) throws IOException {
+      if (closed) throw new IOException("closed");
+      this.maxFrameSize = peerSettings.getMaxFrameSize(maxFrameSize);
+      int length = 0;
+      byte type = TYPE_SETTINGS;
+      byte flags = FLAG_ACK;
+      int streamId = 0;
+      frameHeader(streamId, length, type, flags);
+      sink.flush();
+    }
+
+    @Override public synchronized void connectionPreface() throws IOException {
+      if (closed) throw new IOException("closed");
+      if (!client) return; // Nothing to write; servers don't send connection headers!
+      if (logger.isLoggable(FINE)) {
+        logger.fine(format(">> CONNECTION %s", CONNECTION_PREFACE.hex()));
+      }
+      sink.write(CONNECTION_PREFACE.toByteArray());
+      sink.flush();
+    }
+
+    @Override public synchronized void synStream(boolean outFinished, boolean inFinished,
+        int streamId, int associatedStreamId, List<Header> headerBlock)
+        throws IOException {
+      if (inFinished) throw new UnsupportedOperationException();
+      if (closed) throw new IOException("closed");
+      headers(outFinished, streamId, headerBlock);
+    }
+
+    @Override public synchronized void synReply(boolean outFinished, int streamId,
+        List<Header> headerBlock) throws IOException {
+      if (closed) throw new IOException("closed");
+      headers(outFinished, streamId, headerBlock);
+    }
+
+    @Override public synchronized void headers(int streamId, List<Header> headerBlock)
+        throws IOException {
+      if (closed) throw new IOException("closed");
+      headers(false, streamId, headerBlock);
+    }
+
+    @Override public synchronized void pushPromise(int streamId, int promisedStreamId,
+        List<Header> requestHeaders) throws IOException {
+      if (closed) throw new IOException("closed");
+      hpackWriter.writeHeaders(requestHeaders);
+
+      long byteCount = hpackBuffer.size();
+      int length = (int) Math.min(maxFrameSize - 4, byteCount);
+      byte type = TYPE_PUSH_PROMISE;
+      byte flags = byteCount == length ? FLAG_END_HEADERS : 0;
+      frameHeader(streamId, length + 4, type, flags);
+      sink.writeInt(promisedStreamId & 0x7fffffff);
+      sink.write(hpackBuffer, length);
+
+      if (byteCount > length) writeContinuationFrames(streamId, byteCount - length);
+    }
+
+    void headers(boolean outFinished, int streamId, List<Header> headerBlock) throws IOException {
+      if (closed) throw new IOException("closed");
+      hpackWriter.writeHeaders(headerBlock);
+
+      long byteCount = hpackBuffer.size();
+      int length = (int) Math.min(maxFrameSize, byteCount);
+      byte type = TYPE_HEADERS;
+      byte flags = byteCount == length ? FLAG_END_HEADERS : 0;
+      if (outFinished) flags |= FLAG_END_STREAM;
+      frameHeader(streamId, length, type, flags);
+      sink.write(hpackBuffer, length);
+
+      if (byteCount > length) writeContinuationFrames(streamId, byteCount - length);
+    }
+
+    private void writeContinuationFrames(int streamId, long byteCount) throws IOException {
+      while (byteCount > 0) {
+        int length = (int) Math.min(maxFrameSize, byteCount);
+        byteCount -= length;
+        frameHeader(streamId, length, TYPE_CONTINUATION, byteCount == 0 ? FLAG_END_HEADERS : 0);
+        sink.write(hpackBuffer, length);
+      }
+    }
+
+    @Override public synchronized void rstStream(int streamId, ErrorCode errorCode)
+        throws IOException {
+      if (closed) throw new IOException("closed");
+      if (errorCode.httpCode == -1) throw new IllegalArgumentException();
+
+      int length = 4;
+      byte type = TYPE_RST_STREAM;
+      byte flags = FLAG_NONE;
+      frameHeader(streamId, length, type, flags);
+      sink.writeInt(errorCode.httpCode);
+      sink.flush();
+    }
+
+    @Override public int maxDataLength() {
+      return maxFrameSize;
+    }
+
+    @Override public synchronized void data(boolean outFinished, int streamId, Buffer source,
+        int byteCount) throws IOException {
+      if (closed) throw new IOException("closed");
+      byte flags = FLAG_NONE;
+      if (outFinished) flags |= FLAG_END_STREAM;
+      dataFrame(streamId, flags, source, byteCount);
+    }
+
+    void dataFrame(int streamId, byte flags, Buffer buffer, int byteCount) throws IOException {
+      byte type = TYPE_DATA;
+      frameHeader(streamId, byteCount, type, flags);
+      if (byteCount > 0) {
+        sink.write(buffer, byteCount);
+      }
+    }
+
+    @Override public synchronized void settings(Settings settings) throws IOException {
+      if (closed) throw new IOException("closed");
+      int length = settings.size() * 6;
+      byte type = TYPE_SETTINGS;
+      byte flags = FLAG_NONE;
+      int streamId = 0;
+      frameHeader(streamId, length, type, flags);
+      for (int i = 0; i < Settings.COUNT; i++) {
+        if (!settings.isSet(i)) continue;
+        int id = i;
+        if (id == 4) id = 3; // SETTINGS_MAX_CONCURRENT_STREAMS renumbered.
+        else if (id == 7) id = 4; // SETTINGS_INITIAL_WINDOW_SIZE renumbered.
+        sink.writeShort(id);
+        sink.writeInt(settings.get(i));
+      }
+      sink.flush();
+    }
+
+    @Override public synchronized void ping(boolean ack, int payload1, int payload2)
+        throws IOException {
+      if (closed) throw new IOException("closed");
+      int length = 8;
+      byte type = TYPE_PING;
+      byte flags = ack ? FLAG_ACK : FLAG_NONE;
+      int streamId = 0;
+      frameHeader(streamId, length, type, flags);
+      sink.writeInt(payload1);
+      sink.writeInt(payload2);
+      sink.flush();
+    }
+
+    @Override public synchronized void goAway(int lastGoodStreamId, ErrorCode errorCode,
+        byte[] debugData) throws IOException {
+      if (closed) throw new IOException("closed");
+      if (errorCode.httpCode == -1) throw illegalArgument("errorCode.httpCode == -1");
+      int length = 8 + debugData.length;
+      byte type = TYPE_GOAWAY;
+      byte flags = FLAG_NONE;
+      int streamId = 0;
+      frameHeader(streamId, length, type, flags);
+      sink.writeInt(lastGoodStreamId);
+      sink.writeInt(errorCode.httpCode);
+      if (debugData.length > 0) {
+        sink.write(debugData);
+      }
+      sink.flush();
+    }
+
+    @Override public synchronized void windowUpdate(int streamId, long windowSizeIncrement)
+        throws IOException {
+      if (closed) throw new IOException("closed");
+      if (windowSizeIncrement == 0 || windowSizeIncrement > 0x7fffffffL) {
+        throw illegalArgument("windowSizeIncrement == 0 || windowSizeIncrement > 0x7fffffffL: %s",
+            windowSizeIncrement);
+      }
+      int length = 4;
+      byte type = TYPE_WINDOW_UPDATE;
+      byte flags = FLAG_NONE;
+      frameHeader(streamId, length, type, flags);
+      sink.writeInt((int) windowSizeIncrement);
+      sink.flush();
+    }
+
+    @Override public synchronized void close() throws IOException {
+      closed = true;
+      sink.close();
+    }
+
+    void frameHeader(int streamId, int length, byte type, byte flags) throws IOException {
+      if (logger.isLoggable(FINE)) logger.fine(formatHeader(false, streamId, length, type, flags));
+      if (length > maxFrameSize) {
+        throw illegalArgument("FRAME_SIZE_ERROR length > %d: %d", maxFrameSize, length);
+      }
+      if ((streamId & 0x80000000) != 0) throw illegalArgument("reserved bit set: %s", streamId);
+      writeMedium(sink, length);
+      sink.writeByte(type & 0xff);
+      sink.writeByte(flags & 0xff);
+      sink.writeInt(streamId & 0x7fffffff);
+    }
+  }
+
+  private static IllegalArgumentException illegalArgument(String message, Object... args) {
+    throw new IllegalArgumentException(format(message, args));
+  }
+
+  private static IOException ioException(String message, Object... args) throws IOException {
+    throw new IOException(format(message, args));
+  }
+
+  /**
+   * Decompression of the header block occurs above the framing layer. This
+   * class lazily reads continuation frames as they are needed by {@link
+   * Hpack.Reader#readHeaders()}.
+   */
+  static final class ContinuationSource implements Source {
+    private final BufferedSource source;
+
+    int length;
+    byte flags;
+    int streamId;
+
+    int left;
+    short padding;
+
+    public ContinuationSource(BufferedSource source) {
+      this.source = source;
+    }
+
+    @Override public long read(Buffer sink, long byteCount) throws IOException {
+      while (left == 0) {
+        source.skip(padding);
+        padding = 0;
+        if ((flags & FLAG_END_HEADERS) != 0) return -1;
+        readContinuationHeader();
+        // TODO: test case for empty continuation header?
+      }
+
+      long read = source.read(sink, Math.min(byteCount, left));
+      if (read == -1) return -1;
+      left -= read;
+      return read;
+    }
+
+    @Override public Timeout timeout() {
+      return source.timeout();
+    }
+
+    @Override public void close() throws IOException {
+    }
+
+    private void readContinuationHeader() throws IOException {
+      int previousStreamId = streamId;
+
+      length = left = readMedium(source);
+      byte type = (byte) (source.readByte() & 0xff);
+      flags = (byte) (source.readByte() & 0xff);
+      if (logger.isLoggable(FINE)) logger.fine(formatHeader(true, streamId, length, type, flags));
+      streamId = (source.readInt() & 0x7fffffff);
+      if (type != TYPE_CONTINUATION) throw ioException("%s != TYPE_CONTINUATION", type);
+      if (streamId != previousStreamId) throw ioException("TYPE_CONTINUATION streamId changed");
+    }
+  }
+
+  private static int lengthWithoutPadding(int length, byte flags, short padding)
+      throws IOException {
+    if ((flags & FLAG_PADDED) != 0) length--; // Account for reading the padding length.
+    if (padding > length) {
+      throw ioException("PROTOCOL_ERROR padding %s > remaining length %s", padding, length);
+    }
+    return (short) (length - padding);
+  }
+
+  /**
+   * Logs a human-readable representation of HTTP/2 frame headers.
+   *
+   * <p>The format is:
+   *
+   * <pre>
+   *   direction streamID length type flags
+   * </pre>
+   * Where direction is {@code <<} for inbound and {@code >>} for outbound.
+   *
+   * <p> For example, the following would indicate a HEAD request sent from
+   * the client.
+   * <pre>
+   * {@code
+   *   << 0x0000000f    12 HEADERS       END_HEADERS|END_STREAM
+   * }
+   * </pre>
+   */
+  static final class FrameLogger {
+
+    static String formatHeader(boolean inbound, int streamId, int length, byte type, byte flags) {
+      String formattedType = type < TYPES.length ? TYPES[type] : format("0x%02x", type);
+      String formattedFlags = formatFlags(type, flags);
+      return format("%s 0x%08x %5d %-13s %s", inbound ? "<<" : ">>", streamId, length,
+          formattedType, formattedFlags);
+    }
+
+    /**
+     * Looks up valid string representing flags from the table. Invalid
+     * combinations are represented in binary.
+     */
+    // Visible for testing.
+    static String formatFlags(byte type, byte flags) {
+      if (flags == 0) return "";
+      switch (type) { // Special case types that have 0 or 1 flag.
+        case TYPE_SETTINGS:
+        case TYPE_PING:
+          return flags == FLAG_ACK ? "ACK" : BINARY[flags];
+        case TYPE_PRIORITY:
+        case TYPE_RST_STREAM:
+        case TYPE_GOAWAY:
+        case TYPE_WINDOW_UPDATE:
+          return BINARY[flags];
+      }
+      String result = flags < FLAGS.length ? FLAGS[flags] : BINARY[flags];
+      // Special case types that have overlap flag values.
+      if (type == TYPE_PUSH_PROMISE && (flags & FLAG_END_PUSH_PROMISE) != 0) {
+        return result.replace("HEADERS", "PUSH_PROMISE"); // TODO: Avoid allocation.
+      } else if (type == TYPE_DATA && (flags & FLAG_COMPRESSED) != 0) {
+        return result.replace("PRIORITY", "COMPRESSED"); // TODO: Avoid allocation.
+      }
+      return result;
+    }
+
+    /** Lookup table for valid frame types. */
+    private static final String[] TYPES = new String[] {
+        "DATA",
+        "HEADERS",
+        "PRIORITY",
+        "RST_STREAM",
+        "SETTINGS",
+        "PUSH_PROMISE",
+        "PING",
+        "GOAWAY",
+        "WINDOW_UPDATE",
+        "CONTINUATION"
+    };
+
+    /**
+     * Lookup table for valid flags for DATA, HEADERS, CONTINUATION. Invalid
+     * combinations are represented in binary.
+     */
+    private static final String[] FLAGS = new String[0x40]; // Highest bit flag is 0x20.
+    private static final String[] BINARY = new String[256];
+
+    static {
+      for (int i = 0; i < BINARY.length; i++) {
+        BINARY[i] = format("%8s", Integer.toBinaryString(i)).replace(' ', '0');
+      }
+
+      FLAGS[FLAG_NONE] = "";
+      FLAGS[FLAG_END_STREAM] = "END_STREAM";
+
+      int[] prefixFlags = new int[] {FLAG_END_STREAM};
+
+      FLAGS[FLAG_PADDED] = "PADDED";
+      for (int prefixFlag : prefixFlags) {
+         FLAGS[prefixFlag | FLAG_PADDED] = FLAGS[prefixFlag] + "|PADDED";
+      }
+
+      FLAGS[FLAG_END_HEADERS] = "END_HEADERS"; // Same as END_PUSH_PROMISE.
+      FLAGS[FLAG_PRIORITY] = "PRIORITY"; // Same as FLAG_COMPRESSED.
+      FLAGS[FLAG_END_HEADERS | FLAG_PRIORITY] = "END_HEADERS|PRIORITY"; // Only valid on HEADERS.
+      int[] frameFlags =
+          new int[] {FLAG_END_HEADERS, FLAG_PRIORITY, FLAG_END_HEADERS | FLAG_PRIORITY};
+
+      for (int frameFlag : frameFlags) {
+        for (int prefixFlag : prefixFlags) {
+          FLAGS[prefixFlag | frameFlag] = FLAGS[prefixFlag] + '|' + FLAGS[frameFlag];
+          FLAGS[prefixFlag | frameFlag | FLAG_PADDED] =
+              FLAGS[prefixFlag] + '|' + FLAGS[frameFlag] + "|PADDED";
+        }
+      }
+
+      for (int i = 0; i < FLAGS.length; i++) { // Fill in holes with binary representation.
+        if (FLAGS[i] == null) FLAGS[i] = BINARY[i];
+      }
+    }
+  }
+
+  private static int readMedium(BufferedSource source) throws IOException {
+    return (source.readByte() & 0xff) << 16
+        |  (source.readByte() & 0xff) <<  8
+        |  (source.readByte() & 0xff);
+  }
+
+  private static void writeMedium(BufferedSink sink, int i) throws IOException {
+    sink.writeByte((i >>> 16) & 0xff);
+    sink.writeByte((i >>>  8) & 0xff);
+    sink.writeByte(i          & 0xff);
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Huffman.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Huffman.java
new file mode 100644
index 0000000..311e5fc
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Huffman.java
@@ -0,0 +1,226 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2013 Twitter, 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 com.android.okhttp.internal.framed;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * This class was originally composed from the following classes in
+ * <a href="https://github.com/twitter/hpack">Twitter Hpack</a>.
+ * <ul>
+ * <li>{@code com.twitter.hpack.HuffmanEncoder}</li>
+ * <li>{@code com.twitter.hpack.HuffmanDecoder}</li>
+ * <li>{@code com.twitter.hpack.HpackUtil}</li>
+ * </ul>
+ */
+class Huffman {
+
+  // Appendix C: Huffman Codes
+  // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-12#appendix-B
+  private static final int[] CODES = {
+      0x1ff8, 0x7fffd8, 0xfffffe2, 0xfffffe3, 0xfffffe4, 0xfffffe5, 0xfffffe6, 0xfffffe7, 0xfffffe8,
+      0xffffea, 0x3ffffffc, 0xfffffe9, 0xfffffea, 0x3ffffffd, 0xfffffeb, 0xfffffec, 0xfffffed,
+      0xfffffee, 0xfffffef, 0xffffff0, 0xffffff1, 0xffffff2, 0x3ffffffe, 0xffffff3, 0xffffff4,
+      0xffffff5, 0xffffff6, 0xffffff7, 0xffffff8, 0xffffff9, 0xffffffa, 0xffffffb, 0x14, 0x3f8,
+      0x3f9, 0xffa, 0x1ff9, 0x15, 0xf8, 0x7fa, 0x3fa, 0x3fb, 0xf9, 0x7fb, 0xfa, 0x16, 0x17, 0x18,
+      0x0, 0x1, 0x2, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x5c, 0xfb, 0x7ffc, 0x20, 0xffb,
+      0x3fc, 0x1ffa, 0x21, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+      0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0xfc, 0x73, 0xfd, 0x1ffb, 0x7fff0,
+      0x1ffc, 0x3ffc, 0x22, 0x7ffd, 0x3, 0x23, 0x4, 0x24, 0x5, 0x25, 0x26, 0x27, 0x6, 0x74, 0x75,
+      0x28, 0x29, 0x2a, 0x7, 0x2b, 0x76, 0x2c, 0x8, 0x9, 0x2d, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7ffe,
+      0x7fc, 0x3ffd, 0x1ffd, 0xffffffc, 0xfffe6, 0x3fffd2, 0xfffe7, 0xfffe8, 0x3fffd3, 0x3fffd4,
+      0x3fffd5, 0x7fffd9, 0x3fffd6, 0x7fffda, 0x7fffdb, 0x7fffdc, 0x7fffdd, 0x7fffde, 0xffffeb,
+      0x7fffdf, 0xffffec, 0xffffed, 0x3fffd7, 0x7fffe0, 0xffffee, 0x7fffe1, 0x7fffe2, 0x7fffe3,
+      0x7fffe4, 0x1fffdc, 0x3fffd8, 0x7fffe5, 0x3fffd9, 0x7fffe6, 0x7fffe7, 0xffffef, 0x3fffda,
+      0x1fffdd, 0xfffe9, 0x3fffdb, 0x3fffdc, 0x7fffe8, 0x7fffe9, 0x1fffde, 0x7fffea, 0x3fffdd,
+      0x3fffde, 0xfffff0, 0x1fffdf, 0x3fffdf, 0x7fffeb, 0x7fffec, 0x1fffe0, 0x1fffe1, 0x3fffe0,
+      0x1fffe2, 0x7fffed, 0x3fffe1, 0x7fffee, 0x7fffef, 0xfffea, 0x3fffe2, 0x3fffe3, 0x3fffe4,
+      0x7ffff0, 0x3fffe5, 0x3fffe6, 0x7ffff1, 0x3ffffe0, 0x3ffffe1, 0xfffeb, 0x7fff1, 0x3fffe7,
+      0x7ffff2, 0x3fffe8, 0x1ffffec, 0x3ffffe2, 0x3ffffe3, 0x3ffffe4, 0x7ffffde, 0x7ffffdf,
+      0x3ffffe5, 0xfffff1, 0x1ffffed, 0x7fff2, 0x1fffe3, 0x3ffffe6, 0x7ffffe0, 0x7ffffe1, 0x3ffffe7,
+      0x7ffffe2, 0xfffff2, 0x1fffe4, 0x1fffe5, 0x3ffffe8, 0x3ffffe9, 0xffffffd, 0x7ffffe3,
+      0x7ffffe4, 0x7ffffe5, 0xfffec, 0xfffff3, 0xfffed, 0x1fffe6, 0x3fffe9, 0x1fffe7, 0x1fffe8,
+      0x7ffff3, 0x3fffea, 0x3fffeb, 0x1ffffee, 0x1ffffef, 0xfffff4, 0xfffff5, 0x3ffffea, 0x7ffff4,
+      0x3ffffeb, 0x7ffffe6, 0x3ffffec, 0x3ffffed, 0x7ffffe7, 0x7ffffe8, 0x7ffffe9, 0x7ffffea,
+      0x7ffffeb, 0xffffffe, 0x7ffffec, 0x7ffffed, 0x7ffffee, 0x7ffffef, 0x7fffff0, 0x3ffffee
+  };
+
+  private static final byte[] CODE_LENGTHS = {
+      13, 23, 28, 28, 28, 28, 28, 28, 28, 24, 30, 28, 28, 30, 28, 28, 28, 28, 28, 28, 28, 28, 30,
+      28, 28, 28, 28, 28, 28, 28, 28, 28, 6, 10, 10, 12, 13, 6, 8, 11, 10, 10, 8, 11, 8, 6, 6, 6, 5,
+      5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 8, 15, 6, 12, 10, 13, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+      7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 13, 19, 13, 14, 6, 15, 5, 6, 5, 6, 5, 6, 6, 6, 5, 7, 7, 6,
+      6, 6, 5, 6, 7, 6, 5, 5, 6, 7, 7, 7, 7, 7, 15, 11, 14, 13, 28, 20, 22, 20, 20, 22, 22, 22, 23,
+      22, 23, 23, 23, 23, 23, 24, 23, 24, 24, 22, 23, 24, 23, 23, 23, 23, 21, 22, 23, 22, 23, 23,
+      24, 22, 21, 20, 22, 22, 23, 23, 21, 23, 22, 22, 24, 21, 22, 23, 23, 21, 21, 22, 21, 23, 22,
+      23, 23, 20, 22, 22, 22, 23, 22, 22, 23, 26, 26, 20, 19, 22, 23, 22, 25, 26, 26, 26, 27, 27,
+      26, 24, 25, 19, 21, 26, 27, 27, 26, 27, 24, 21, 21, 26, 26, 28, 27, 27, 27, 20, 24, 20, 21,
+      22, 21, 21, 23, 22, 22, 25, 25, 24, 24, 26, 23, 26, 27, 26, 26, 27, 27, 27, 27, 27, 28, 27,
+      27, 27, 27, 27, 26
+  };
+
+  private static final Huffman INSTANCE = new Huffman();
+
+  public static Huffman get() {
+    return INSTANCE;
+  }
+
+  private final Node root = new Node();
+
+  private Huffman() {
+    buildTree();
+  }
+
+  void encode(byte[] data, OutputStream out) throws IOException {
+    long current = 0;
+    int n = 0;
+
+    for (int i = 0; i < data.length; i++) {
+      int b = data[i] & 0xFF;
+      int code = CODES[b];
+      int nbits = CODE_LENGTHS[b];
+
+      current <<= nbits;
+      current |= code;
+      n += nbits;
+
+      while (n >= 8) {
+        n -= 8;
+        out.write(((int) (current >> n)));
+      }
+    }
+
+    if (n > 0) {
+      current <<= (8 - n);
+      current |= (0xFF >>> n);
+      out.write((int) current);
+    }
+  }
+
+  int encodedLength(byte[] bytes) {
+    long len = 0;
+
+    for (int i = 0; i < bytes.length; i++) {
+      int b = bytes[i] & 0xFF;
+      len += CODE_LENGTHS[b];
+    }
+
+    return (int) ((len + 7) >> 3);
+  }
+
+  byte[] decode(byte[] buf) throws IOException {
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    Node node = root;
+    int current = 0;
+    int nbits = 0;
+    for (int i = 0; i < buf.length; i++) {
+      int b = buf[i] & 0xFF;
+      current = (current << 8) | b;
+      nbits += 8;
+      while (nbits >= 8) {
+        int c = (current >>> (nbits - 8)) & 0xFF;
+        node = node.children[c];
+        if (node.children == null) {
+          // terminal node
+          baos.write(node.symbol);
+          nbits -= node.terminalBits;
+          node = root;
+        } else {
+          // non-terminal node
+          nbits -= 8;
+        }
+      }
+    }
+
+    while (nbits > 0) {
+      int c = (current << (8 - nbits)) & 0xFF;
+      node = node.children[c];
+      if (node.children != null || node.terminalBits > nbits) {
+        break;
+      }
+      baos.write(node.symbol);
+      nbits -= node.terminalBits;
+      node = root;
+    }
+
+    return baos.toByteArray();
+  }
+
+  private void buildTree() {
+    for (int i = 0; i < CODE_LENGTHS.length; i++) {
+      addCode(i, CODES[i], CODE_LENGTHS[i]);
+    }
+  }
+
+  private void addCode(int sym, int code, byte len) {
+    Node terminal = new Node(sym, len);
+
+    Node current = root;
+    while (len > 8) {
+      len -= 8;
+      int i = ((code >>> len) & 0xFF);
+      if (current.children == null) {
+        throw new IllegalStateException("invalid dictionary: prefix not unique");
+      }
+      if (current.children[i] == null) {
+        current.children[i] = new Node();
+      }
+      current = current.children[i];
+    }
+
+    int shift = 8 - len;
+    int start = (code << shift) & 0xFF;
+    int end = 1 << shift;
+    for (int i = start; i < start + end; i++) {
+      current.children[i] = terminal;
+    }
+  }
+
+  private static final class Node {
+
+    // Null if terminal.
+    private final Node[] children;
+
+    // Terminal nodes have a symbol.
+    private final int symbol;
+
+    // Number of bits represented in the terminal node.
+    private final int terminalBits;
+
+    /** Construct an internal node. */
+    Node() {
+      this.children = new Node[256];
+      this.symbol = 0; // Not read.
+      this.terminalBits = 0; // Not read.
+    }
+
+    /**
+     * Construct a terminal node.
+     *
+     * @param symbol symbol the node represents
+     * @param bits length of Huffman code in bits
+     */
+    Node(int symbol, int bits) {
+      this.children = null;
+      this.symbol = symbol;
+      int b = bits & 0x07;
+      this.terminalBits = b == 0 ? 8 : b;
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/NameValueBlockReader.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/NameValueBlockReader.java
new file mode 100644
index 0000000..8c84927
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/NameValueBlockReader.java
@@ -0,0 +1,119 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.okhttp.internal.framed;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.zip.DataFormatException;
+import java.util.zip.Inflater;
+import com.android.okhttp.okio.Buffer;
+import com.android.okhttp.okio.BufferedSource;
+import com.android.okhttp.okio.ByteString;
+import com.android.okhttp.okio.ForwardingSource;
+import com.android.okhttp.okio.InflaterSource;
+import com.android.okhttp.okio.Okio;
+import com.android.okhttp.okio.Source;
+
+/**
+ * Reads a SPDY/3 Name/Value header block. This class is made complicated by the
+ * requirement that we're strict with which bytes we put in the compressed bytes
+ * buffer. We need to put all compressed bytes into that buffer -- but no other
+ * bytes.
+ */
+class NameValueBlockReader {
+  /** This source transforms compressed bytes into uncompressed bytes. */
+  private final InflaterSource inflaterSource;
+
+  /**
+   * How many compressed bytes must be read into inflaterSource before
+   * {@link #readNameValueBlock} returns.
+   */
+  private int compressedLimit;
+
+  /** This source holds inflated bytes. */
+  private final BufferedSource source;
+
+  public NameValueBlockReader(BufferedSource source) {
+    // Limit the inflater input stream to only those bytes in the Name/Value
+    // block. We cut the inflater off at its source because we can't predict the
+    // ratio of compressed bytes to uncompressed bytes.
+    Source throttleSource = new ForwardingSource(source) {
+      @Override public long read(Buffer sink, long byteCount) throws IOException {
+        if (compressedLimit == 0) return -1; // Out of data for the current block.
+        long read = super.read(sink, Math.min(byteCount, compressedLimit));
+        if (read == -1) return -1;
+        compressedLimit -= read;
+        return read;
+      }
+    };
+
+    // 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(Spdy3.DICTIONARY);
+          result = super.inflate(buffer, offset, count);
+        }
+        return result;
+      }
+    };
+
+    this.inflaterSource = new InflaterSource(throttleSource, inflater);
+    this.source = Okio.buffer(inflaterSource);
+  }
+
+  public List<Header> readNameValueBlock(int length) throws IOException {
+    this.compressedLimit += length;
+
+    int numberOfPairs = source.readInt();
+    if (numberOfPairs < 0) throw new IOException("numberOfPairs < 0: " + numberOfPairs);
+    if (numberOfPairs > 1024) throw new IOException("numberOfPairs > 1024: " + numberOfPairs);
+
+    List<Header> entries = new ArrayList<>(numberOfPairs);
+    for (int i = 0; i < numberOfPairs; i++) {
+      ByteString name = readByteString().toAsciiLowercase();
+      ByteString values = readByteString();
+      if (name.size() == 0) throw new IOException("name.size == 0");
+      entries.add(new Header(name, values));
+    }
+
+    doneReading();
+    return entries;
+  }
+
+  private ByteString readByteString() throws IOException {
+    int length = source.readInt();
+    return source.readByteString(length);
+  }
+
+  private void doneReading() throws IOException {
+    // Move any outstanding unread bytes into the inflater. One side-effect of
+    // deflate compression is that sometimes there are bytes remaining in the
+    // stream after we've consumed all of the content.
+    if (compressedLimit > 0) {
+      inflaterSource.refill();
+      if (compressedLimit != 0) throw new IOException("compressedLimit > 0: " + compressedLimit);
+    }
+  }
+
+  public void close() throws IOException {
+    source.close();
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Ping.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Ping.java
new file mode 100644
index 0000000..42eb248
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Ping.java
@@ -0,0 +1,73 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.okhttp.internal.framed;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A locally-originated ping.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Ping {
+  private final CountDownLatch latch = new CountDownLatch(1);
+  private long sent = -1;
+  private long received = -1;
+
+  Ping() {
+  }
+
+  void send() {
+    if (sent != -1) throw new IllegalStateException();
+    sent = System.nanoTime();
+  }
+
+  void receive() {
+    if (received != -1 || sent == -1) throw new IllegalStateException();
+    received = System.nanoTime();
+    latch.countDown();
+  }
+
+  void cancel() {
+    if (received != -1 || sent == -1) throw new IllegalStateException();
+    received = sent - 1;
+    latch.countDown();
+  }
+
+  /**
+   * Returns the round trip time for this ping in nanoseconds, waiting for the
+   * response to arrive if necessary. Returns -1 if the response was
+   * canceled.
+   */
+  public long roundTripTime() throws InterruptedException {
+    latch.await();
+    return received - sent;
+  }
+
+  /**
+   * Returns the round trip time for this ping in nanoseconds, or -1 if the
+   * response was canceled, or -2 if the timeout elapsed before the round
+   * trip completed.
+   */
+  public long roundTripTime(long timeout, TimeUnit unit) throws InterruptedException {
+    if (latch.await(timeout, unit)) {
+      return received - sent;
+    } else {
+      return -2;
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/PushObserver.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/PushObserver.java
new file mode 100644
index 0000000..8c71514
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/PushObserver.java
@@ -0,0 +1,97 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.internal.framed;
+
+import java.io.IOException;
+import java.util.List;
+import com.android.okhttp.okio.BufferedSource;
+
+/**
+ * {@link com.android.okhttp.Protocol#HTTP_2 HTTP/2} only.
+ * Processes server-initiated HTTP requests on the client. Implementations must
+ * quickly dispatch callbacks to avoid creating a bottleneck.
+ *
+ * <p>While {@link #onReset} may occur at any time, the following callbacks are
+ * expected in order, correlated by stream ID.
+ * <ul>
+ *   <li>{@link #onRequest}</li>
+ *   <li>{@link #onHeaders} (unless canceled)</li>
+ *   <li>{@link #onData} (optional sequence of data frames)</li>
+ * </ul>
+ *
+ * <p>As a stream ID is scoped to a single HTTP/2 connection, implementations
+ * which target multiple connections should expect repetition of stream IDs.
+ *
+ * <p>Return true to request cancellation of a pushed stream.  Note that this
+ * does not guarantee future frames won't arrive on the stream ID.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface PushObserver {
+  /**
+   * Describes the request that the server intends to push a response for.
+   *
+   * @param streamId server-initiated stream ID: an even number.
+   * @param requestHeaders minimally includes {@code :method}, {@code :scheme},
+   * {@code :authority}, and (@code :path}.
+   */
+  boolean onRequest(int streamId, List<Header> requestHeaders);
+
+  /**
+   * The response headers corresponding to a pushed request.  When {@code last}
+   * is true, there are no data frames to follow.
+   *
+   * @param streamId server-initiated stream ID: an even number.
+   * @param responseHeaders minimally includes {@code :status}.
+   * @param last when true, there is no response data.
+   */
+  boolean onHeaders(int streamId, List<Header> responseHeaders, boolean last);
+
+  /**
+   * A chunk of response data corresponding to a pushed request.  This data
+   * must either be read or skipped.
+   *
+   * @param streamId server-initiated stream ID: an even number.
+   * @param source location of data corresponding with this stream ID.
+   * @param byteCount number of bytes to read or skip from the source.
+   * @param last when true, there are no data frames to follow.
+   */
+  boolean onData(int streamId, BufferedSource source, int byteCount, boolean last)
+      throws IOException;
+
+  /** Indicates the reason why this stream was canceled. */
+  void onReset(int streamId, ErrorCode errorCode);
+
+  PushObserver CANCEL = new PushObserver() {
+
+    @Override public boolean onRequest(int streamId, List<Header> requestHeaders) {
+      return true;
+    }
+
+    @Override public boolean onHeaders(int streamId, List<Header> responseHeaders, boolean last) {
+      return true;
+    }
+
+    @Override public boolean onData(int streamId, BufferedSource source, int byteCount,
+        boolean last) throws IOException {
+      source.skip(byteCount);
+      return true;
+    }
+
+    @Override public void onReset(int streamId, ErrorCode errorCode) {
+    }
+  };
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Settings.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Settings.java
new file mode 100644
index 0000000..223de47
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Settings.java
@@ -0,0 +1,241 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.okhttp.internal.framed;
+
+import java.util.Arrays;
+
+/**
+ * Settings describe characteristics of the sending peer, which are used by the receiving peer.
+ * Settings are {@link FramedConnection connection} scoped.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Settings {
+  /**
+   * From the SPDY/3 and HTTP/2 specs, the default initial window size for all
+   * streams is 64 KiB. (Chrome 25 uses 10 MiB).
+   */
+  static final int DEFAULT_INITIAL_WINDOW_SIZE = 64 * 1024;
+
+  /** Peer request to clear durable settings. */
+  static final int FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS = 0x1;
+
+  /** Sent by servers only. The peer requests this setting persisted for future connections. */
+  static final int PERSIST_VALUE = 0x1;
+  /** Sent by clients only. The client is reminding the server of a persisted value. */
+  static final int PERSISTED = 0x2;
+
+  /** spdy/3: Sender's estimate of max incoming kbps. */
+  static final int UPLOAD_BANDWIDTH = 1;
+  /** HTTP/2: Size in bytes of the table used to decode the sender's header blocks. */
+  static final int HEADER_TABLE_SIZE = 1;
+  /** spdy/3: Sender's estimate of max outgoing kbps. */
+  static final int DOWNLOAD_BANDWIDTH = 2;
+  /** HTTP/2: The peer must not send a PUSH_PROMISE frame when this is 0. */
+  static final int ENABLE_PUSH = 2;
+  /** spdy/3: Sender's estimate of millis between sending a request and receiving a response. */
+  static final int ROUND_TRIP_TIME = 3;
+  /** Sender's maximum number of concurrent streams. */
+  static final int MAX_CONCURRENT_STREAMS = 4;
+  /** spdy/3: Current CWND in Packets. */
+  static final int CURRENT_CWND = 5;
+  /** HTTP/2: Size in bytes of the largest frame payload the sender will accept. */
+  static final int MAX_FRAME_SIZE = 5;
+  /** spdy/3: Retransmission rate. Percentage */
+  static final int DOWNLOAD_RETRANS_RATE = 6;
+  /** HTTP/2: Advisory only. Size in bytes of the largest header list the sender will accept. */
+  static final int MAX_HEADER_LIST_SIZE = 6;
+  /** Window size in bytes. */
+  static final int INITIAL_WINDOW_SIZE = 7;
+  /** spdy/3: Size of the client certificate vector. Unsupported. */
+  static final int CLIENT_CERTIFICATE_VECTOR_SIZE = 8;
+  /** Flow control options. */
+  static final int FLOW_CONTROL_OPTIONS = 10;
+
+  /** Total number of settings. */
+  static final int COUNT = 10;
+
+  /** If set, flow control is disabled for streams directed to the sender of these settings. */
+  static final int FLOW_CONTROL_OPTIONS_DISABLED = 0x1;
+
+  /** Bitfield of which flags that values. */
+  private int set;
+
+  /** Bitfield of flags that have {@link #PERSIST_VALUE}. */
+  private int persistValue;
+
+  /** Bitfield of flags that have {@link #PERSISTED}. */
+  private int persisted;
+
+  /** Flag values. */
+  private final int[] values = new int[COUNT];
+
+  void clear() {
+    set = persistValue = persisted = 0;
+    Arrays.fill(values, 0);
+  }
+
+  Settings set(int id, int idFlags, int value) {
+    if (id >= values.length) {
+      return this; // Discard unknown settings.
+    }
+
+    int bit = 1 << id;
+    set |= bit;
+    if ((idFlags & PERSIST_VALUE) != 0) {
+      persistValue |= bit;
+    } else {
+      persistValue &= ~bit;
+    }
+    if ((idFlags & PERSISTED) != 0) {
+      persisted |= bit;
+    } else {
+      persisted &= ~bit;
+    }
+
+    values[id] = value;
+    return this;
+  }
+
+  /** Returns true if a value has been assigned for the setting {@code id}. */
+  boolean isSet(int id) {
+    int bit = 1 << id;
+    return (set & bit) != 0;
+  }
+
+  /** Returns the value for the setting {@code id}, or 0 if unset. */
+  int get(int id) {
+    return values[id];
+  }
+
+  /** Returns the flags for the setting {@code id}, or 0 if unset. */
+  int flags(int id) {
+    int result = 0;
+    if (isPersisted(id)) result |= Settings.PERSISTED;
+    if (persistValue(id)) result |= Settings.PERSIST_VALUE;
+    return result;
+  }
+
+  /** Returns the number of settings that have values assigned. */
+  int size() {
+    return Integer.bitCount(set);
+  }
+
+  /** spdy/3 only. */
+  int getUploadBandwidth(int defaultValue) {
+    int bit = 1 << UPLOAD_BANDWIDTH;
+    return (bit & set) != 0 ? values[UPLOAD_BANDWIDTH] : defaultValue;
+  }
+
+  /** HTTP/2 only. Returns -1 if unset. */
+  int getHeaderTableSize() {
+    int bit = 1 << HEADER_TABLE_SIZE;
+    return (bit & set) != 0 ? values[HEADER_TABLE_SIZE] : -1;
+  }
+
+  /** spdy/3 only. */
+  int getDownloadBandwidth(int defaultValue) {
+    int bit = 1 << DOWNLOAD_BANDWIDTH;
+    return (bit & set) != 0 ? values[DOWNLOAD_BANDWIDTH] : defaultValue;
+  }
+
+  /** HTTP/2 only. */
+  // TODO: honor this setting in HTTP/2.
+  boolean getEnablePush(boolean defaultValue) {
+    int bit = 1 << ENABLE_PUSH;
+    return ((bit & set) != 0 ? values[ENABLE_PUSH] : defaultValue ? 1 : 0) == 1;
+  }
+
+  /** spdy/3 only. */
+  int getRoundTripTime(int defaultValue) {
+    int bit = 1 << ROUND_TRIP_TIME;
+    return (bit & set) != 0 ? values[ROUND_TRIP_TIME] : defaultValue;
+  }
+
+  // TODO: honor this setting in spdy/3 and HTTP/2.
+  int getMaxConcurrentStreams(int defaultValue) {
+    int bit = 1 << MAX_CONCURRENT_STREAMS;
+    return (bit & set) != 0 ? values[MAX_CONCURRENT_STREAMS] : defaultValue;
+  }
+
+  /** spdy/3 only. */
+  int getCurrentCwnd(int defaultValue) {
+    int bit = 1 << CURRENT_CWND;
+    return (bit & set) != 0 ? values[CURRENT_CWND] : defaultValue;
+  }
+
+  /** HTTP/2 only. */
+  int getMaxFrameSize(int defaultValue) {
+    int bit = 1 << MAX_FRAME_SIZE;
+    return (bit & set) != 0 ? values[MAX_FRAME_SIZE] : defaultValue;
+  }
+
+  /** spdy/3 only. */
+  int getDownloadRetransRate(int defaultValue) {
+    int bit = 1 << DOWNLOAD_RETRANS_RATE;
+    return (bit & set) != 0 ? values[DOWNLOAD_RETRANS_RATE] : defaultValue;
+  }
+
+  /** HTTP/2 only. */
+  int getMaxHeaderListSize(int defaultValue) {
+    int bit = 1 << MAX_HEADER_LIST_SIZE;
+    return (bit & set) != 0 ? values[MAX_HEADER_LIST_SIZE] : defaultValue;
+  }
+
+  int getInitialWindowSize(int defaultValue) {
+    int bit = 1 << INITIAL_WINDOW_SIZE;
+    return (bit & set) != 0 ? values[INITIAL_WINDOW_SIZE] : defaultValue;
+  }
+
+  /** spdy/3 only. */
+  int getClientCertificateVectorSize(int defaultValue) {
+    int bit = 1 << CLIENT_CERTIFICATE_VECTOR_SIZE;
+    return (bit & set) != 0 ? values[CLIENT_CERTIFICATE_VECTOR_SIZE] : defaultValue;
+  }
+
+  // TODO: honor this setting in spdy/3 and HTTP/2.
+  boolean isFlowControlDisabled() {
+    int bit = 1 << FLOW_CONTROL_OPTIONS;
+    int value = (bit & set) != 0 ? values[FLOW_CONTROL_OPTIONS] : 0;
+    return (value & FLOW_CONTROL_OPTIONS_DISABLED) != 0;
+  }
+
+  /**
+   * Returns true if this user agent should use this setting in future spdy/3
+   * connections to the same host.
+   */
+  boolean persistValue(int id) {
+    int bit = 1 << id;
+    return (persistValue & bit) != 0;
+  }
+
+  /** Returns true if this setting was persisted. */
+  boolean isPersisted(int id) {
+    int bit = 1 << id;
+    return (persisted & bit) != 0;
+  }
+
+  /**
+   * Writes {@code other} into this. If any setting is populated by this and
+   * {@code other}, the value and flags from {@code other} will be kept.
+   */
+  void merge(Settings other) {
+    for (int i = 0; i < COUNT; i++) {
+      if (!other.isSet(i)) continue;
+      set(i, other.flags(i), other.get(i));
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Spdy3.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Spdy3.java
new file mode 100644
index 0000000..d792cd8
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Spdy3.java
@@ -0,0 +1,493 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.okhttp.internal.framed;
+
+import com.android.okhttp.Protocol;
+import com.android.okhttp.internal.Util;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.ProtocolException;
+import java.util.List;
+import java.util.zip.Deflater;
+import com.android.okhttp.okio.Buffer;
+import com.android.okhttp.okio.BufferedSink;
+import com.android.okhttp.okio.BufferedSource;
+import com.android.okhttp.okio.ByteString;
+import com.android.okhttp.okio.DeflaterSink;
+import com.android.okhttp.okio.Okio;
+
+/**
+ * Read and write spdy/3.1 frames.
+ * http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Spdy3 implements Variant {
+
+  @Override public Protocol getProtocol() {
+    return Protocol.SPDY_3;
+  }
+
+  static final int TYPE_DATA = 0x0;
+  static final int TYPE_SYN_STREAM = 0x1;
+  static final int TYPE_SYN_REPLY = 0x2;
+  static final int TYPE_RST_STREAM = 0x3;
+  static final int TYPE_SETTINGS = 0x4;
+  static final int TYPE_PING = 0x6;
+  static final int TYPE_GOAWAY = 0x7;
+  static final int TYPE_HEADERS = 0x8;
+  static final int TYPE_WINDOW_UPDATE = 0x9;
+
+  static final int FLAG_FIN = 0x1;
+  static final int FLAG_UNIDIRECTIONAL = 0x2;
+
+  static final int VERSION = 3;
+
+  static final byte[] DICTIONARY;
+  static {
+    try {
+      DICTIONARY = ("\u0000\u0000\u0000\u0007options\u0000\u0000\u0000\u0004hea"
+          + "d\u0000\u0000\u0000\u0004post\u0000\u0000\u0000\u0003put\u0000\u0000\u0000\u0006dele"
+          + "te\u0000\u0000\u0000\u0005trace\u0000\u0000\u0000\u0006accept\u0000\u0000\u0000"
+          + "\u000Eaccept-charset\u0000\u0000\u0000\u000Faccept-encoding\u0000\u0000\u0000\u000Fa"
+          + "ccept-language\u0000\u0000\u0000\raccept-ranges\u0000\u0000\u0000\u0003age\u0000"
+          + "\u0000\u0000\u0005allow\u0000\u0000\u0000\rauthorization\u0000\u0000\u0000\rcache-co"
+          + "ntrol\u0000\u0000\u0000\nconnection\u0000\u0000\u0000\fcontent-base\u0000\u0000"
+          + "\u0000\u0010content-encoding\u0000\u0000\u0000\u0010content-language\u0000\u0000"
+          + "\u0000\u000Econtent-length\u0000\u0000\u0000\u0010content-location\u0000\u0000\u0000"
+          + "\u000Bcontent-md5\u0000\u0000\u0000\rcontent-range\u0000\u0000\u0000\fcontent-type"
+          + "\u0000\u0000\u0000\u0004date\u0000\u0000\u0000\u0004etag\u0000\u0000\u0000\u0006expe"
+          + "ct\u0000\u0000\u0000\u0007expires\u0000\u0000\u0000\u0004from\u0000\u0000\u0000"
+          + "\u0004host\u0000\u0000\u0000\bif-match\u0000\u0000\u0000\u0011if-modified-since"
+          + "\u0000\u0000\u0000\rif-none-match\u0000\u0000\u0000\bif-range\u0000\u0000\u0000"
+          + "\u0013if-unmodified-since\u0000\u0000\u0000\rlast-modified\u0000\u0000\u0000\blocati"
+          + "on\u0000\u0000\u0000\fmax-forwards\u0000\u0000\u0000\u0006pragma\u0000\u0000\u0000"
+          + "\u0012proxy-authenticate\u0000\u0000\u0000\u0013proxy-authorization\u0000\u0000"
+          + "\u0000\u0005range\u0000\u0000\u0000\u0007referer\u0000\u0000\u0000\u000Bretry-after"
+          + "\u0000\u0000\u0000\u0006server\u0000\u0000\u0000\u0002te\u0000\u0000\u0000\u0007trai"
+          + "ler\u0000\u0000\u0000\u0011transfer-encoding\u0000\u0000\u0000\u0007upgrade\u0000"
+          + "\u0000\u0000\nuser-agent\u0000\u0000\u0000\u0004vary\u0000\u0000\u0000\u0003via"
+          + "\u0000\u0000\u0000\u0007warning\u0000\u0000\u0000\u0010www-authenticate\u0000\u0000"
+          + "\u0000\u0006method\u0000\u0000\u0000\u0003get\u0000\u0000\u0000\u0006status\u0000"
+          + "\u0000\u0000\u0006200 OK\u0000\u0000\u0000\u0007version\u0000\u0000\u0000\bHTTP/1.1"
+          + "\u0000\u0000\u0000\u0003url\u0000\u0000\u0000\u0006public\u0000\u0000\u0000\nset-coo"
+          + "kie\u0000\u0000\u0000\nkeep-alive\u0000\u0000\u0000\u0006origin100101201202205206300"
+          + "302303304305306307402405406407408409410411412413414415416417502504505203 Non-Authori"
+          + "tative Information204 No Content301 Moved Permanently400 Bad Request401 Unauthorized"
+          + "403 Forbidden404 Not Found500 Internal Server Error501 Not Implemented503 Service Un"
+          + "availableJan Feb Mar Apr May Jun Jul Aug Sept Oct Nov Dec 00:00:00 Mon, Tue, Wed, Th"
+          + "u, Fri, Sat, Sun, GMTchunked,text/html,image/png,image/jpg,image/gif,application/xml"
+          + ",application/xhtml+xml,text/plain,text/javascript,publicprivatemax-age=gzip,deflate,"
+          + "sdchcharset=utf-8charset=iso-8859-1,utf-,*,enq=0.").getBytes(Util.UTF_8.name());
+    } catch (UnsupportedEncodingException e) {
+      throw new AssertionError();
+    }
+  }
+
+  @Override public FrameReader newReader(BufferedSource source, boolean client) {
+    return new Reader(source, client);
+  }
+
+  @Override public FrameWriter newWriter(BufferedSink sink, boolean client) {
+    return new Writer(sink, client);
+  }
+
+  /** Read spdy/3 frames. */
+  static final class Reader implements FrameReader {
+    private final BufferedSource source;
+    private final boolean client;
+    private final NameValueBlockReader headerBlockReader;
+
+    Reader(BufferedSource source, boolean client) {
+      this.source = source;
+      this.headerBlockReader = new NameValueBlockReader(this.source);
+      this.client = client;
+    }
+
+    @Override public void readConnectionPreface() {
+    }
+
+    /**
+     * Send the next frame to {@code handler}. Returns true unless there are no
+     * more frames on the stream.
+     */
+    @Override public boolean nextFrame(Handler handler) throws IOException {
+      int w1;
+      int w2;
+      try {
+        w1 = source.readInt();
+        w2 = source.readInt();
+      } catch (IOException e) {
+        return false; // This might be a normal socket close.
+      }
+
+      boolean control = (w1 & 0x80000000) != 0;
+      int flags = (w2 & 0xff000000) >>> 24;
+      int length = (w2 & 0xffffff);
+
+      if (control) {
+        int version = (w1 & 0x7fff0000) >>> 16;
+        int type = (w1 & 0xffff);
+
+        if (version != 3) {
+          throw new ProtocolException("version != 3: " + version);
+        }
+
+        switch (type) {
+          case TYPE_SYN_STREAM:
+            readSynStream(handler, flags, length);
+            return true;
+
+          case TYPE_SYN_REPLY:
+            readSynReply(handler, flags, length);
+            return true;
+
+          case TYPE_RST_STREAM:
+            readRstStream(handler, flags, length);
+            return true;
+
+          case TYPE_SETTINGS:
+            readSettings(handler, flags, length);
+            return true;
+
+          case TYPE_PING:
+            readPing(handler, flags, length);
+            return true;
+
+          case TYPE_GOAWAY:
+            readGoAway(handler, flags, length);
+            return true;
+
+          case TYPE_HEADERS:
+            readHeaders(handler, flags, length);
+            return true;
+
+          case TYPE_WINDOW_UPDATE:
+            readWindowUpdate(handler, flags, length);
+            return true;
+
+          default:
+            source.skip(length);
+            return true;
+        }
+      } else {
+        int streamId = w1 & 0x7fffffff;
+        boolean inFinished = (flags & FLAG_FIN) != 0;
+        handler.data(inFinished, streamId, source, length);
+        return true;
+      }
+    }
+
+    private void readSynStream(Handler handler, int flags, int length) throws IOException {
+      int w1 = source.readInt();
+      int w2 = source.readInt();
+      int streamId = w1 & 0x7fffffff;
+      int associatedStreamId = w2 & 0x7fffffff;
+      source.readShort(); // int priority = (s3 & 0xe000) >>> 13; int slot = s3 & 0xff;
+      List<Header> headerBlock = headerBlockReader.readNameValueBlock(length - 10);
+
+      boolean inFinished = (flags & FLAG_FIN) != 0;
+      boolean outFinished = (flags & FLAG_UNIDIRECTIONAL) != 0;
+      handler.headers(outFinished, inFinished, streamId, associatedStreamId, headerBlock,
+          HeadersMode.SPDY_SYN_STREAM);
+    }
+
+    private void readSynReply(Handler handler, int flags, int length) throws IOException {
+      int w1 = source.readInt();
+      int streamId = w1 & 0x7fffffff;
+      List<Header> headerBlock = headerBlockReader.readNameValueBlock(length - 4);
+      boolean inFinished = (flags & FLAG_FIN) != 0;
+      handler.headers(false, inFinished, streamId, -1, headerBlock, HeadersMode.SPDY_REPLY);
+    }
+
+    private void readRstStream(Handler handler, int flags, int length) throws IOException {
+      if (length != 8) throw ioException("TYPE_RST_STREAM length: %d != 8", length);
+      int streamId = source.readInt() & 0x7fffffff;
+      int errorCodeInt = source.readInt();
+      ErrorCode errorCode = ErrorCode.fromSpdy3Rst(errorCodeInt);
+      if (errorCode == null) {
+        throw ioException("TYPE_RST_STREAM unexpected error code: %d", errorCodeInt);
+      }
+      handler.rstStream(streamId, errorCode);
+    }
+
+    private void readHeaders(Handler handler, int flags, int length) throws IOException {
+      int w1 = source.readInt();
+      int streamId = w1 & 0x7fffffff;
+      List<Header> headerBlock = headerBlockReader.readNameValueBlock(length - 4);
+      handler.headers(false, false, streamId, -1, headerBlock, HeadersMode.SPDY_HEADERS);
+    }
+
+    private void readWindowUpdate(Handler handler, int flags, int length) throws IOException {
+      if (length != 8) throw ioException("TYPE_WINDOW_UPDATE length: %d != 8", length);
+      int w1 = source.readInt();
+      int w2 = source.readInt();
+      int streamId = w1 & 0x7fffffff;
+      long increment = w2 & 0x7fffffff;
+      if (increment == 0) throw ioException("windowSizeIncrement was 0", increment);
+      handler.windowUpdate(streamId, increment);
+    }
+
+    private void readPing(Handler handler, int flags, int length) throws IOException {
+      if (length != 4) throw ioException("TYPE_PING length: %d != 4", length);
+      int id = source.readInt();
+      boolean ack = client == ((id & 1) == 1);
+      handler.ping(ack, id, 0);
+    }
+
+    private void readGoAway(Handler handler, int flags, int length) throws IOException {
+      if (length != 8) throw ioException("TYPE_GOAWAY length: %d != 8", length);
+      int lastGoodStreamId = source.readInt() & 0x7fffffff;
+      int errorCodeInt = source.readInt();
+      ErrorCode errorCode = ErrorCode.fromSpdyGoAway(errorCodeInt);
+      if (errorCode == null) {
+        throw ioException("TYPE_GOAWAY unexpected error code: %d", errorCodeInt);
+      }
+      handler.goAway(lastGoodStreamId, errorCode, ByteString.EMPTY);
+    }
+
+    private void readSettings(Handler handler, int flags, int length) throws IOException {
+      int numberOfEntries = source.readInt();
+      if (length != 4 + 8 * numberOfEntries) {
+        throw ioException("TYPE_SETTINGS length: %d != 4 + 8 * %d", length, numberOfEntries);
+      }
+      Settings settings = new Settings();
+      for (int i = 0; i < numberOfEntries; i++) {
+        int w1 = source.readInt();
+        int value = source.readInt();
+        int idFlags = (w1 & 0xff000000) >>> 24;
+        int id = w1 & 0xffffff;
+        settings.set(id, idFlags, value);
+      }
+      boolean clearPrevious = (flags & Settings.FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) != 0;
+      handler.settings(clearPrevious, settings);
+    }
+
+    private static IOException ioException(String message, Object... args) throws IOException {
+      throw new IOException(String.format(message, args));
+    }
+
+    @Override public void close() throws IOException {
+      headerBlockReader.close();
+    }
+  }
+
+  /** Write spdy/3 frames. */
+  static final class Writer implements FrameWriter {
+    private final BufferedSink sink;
+    private final Buffer headerBlockBuffer;
+    private final BufferedSink headerBlockOut;
+    private final boolean client;
+    private boolean closed;
+
+    Writer(BufferedSink sink, boolean client) {
+      this.sink = sink;
+      this.client = client;
+
+      Deflater deflater = new Deflater();
+      deflater.setDictionary(DICTIONARY);
+      headerBlockBuffer = new Buffer();
+      headerBlockOut = Okio.buffer(new DeflaterSink(headerBlockBuffer, deflater));
+    }
+
+    @Override public void ackSettings(Settings peerSettings) {
+      // Do nothing: no ACK for SPDY/3 settings.
+    }
+
+    @Override
+    public void pushPromise(int streamId, int promisedStreamId, List<Header> requestHeaders)
+        throws IOException {
+      // Do nothing: no push promise for SPDY/3.
+    }
+
+    @Override public synchronized void connectionPreface() {
+      // Do nothing: no connection preface for SPDY/3.
+    }
+
+    @Override public synchronized void flush() throws IOException {
+      if (closed) throw new IOException("closed");
+      sink.flush();
+    }
+
+    @Override public synchronized void synStream(boolean outFinished, boolean inFinished,
+        int streamId, int associatedStreamId, List<Header> headerBlock)
+        throws IOException {
+      if (closed) throw new IOException("closed");
+      writeNameValueBlockToBuffer(headerBlock);
+      int length = (int) (10 + headerBlockBuffer.size());
+      int type = TYPE_SYN_STREAM;
+      int flags = (outFinished ? FLAG_FIN : 0) | (inFinished ? FLAG_UNIDIRECTIONAL : 0);
+
+      int unused = 0;
+      sink.writeInt(0x80000000 | (VERSION & 0x7fff) << 16 | type & 0xffff);
+      sink.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+      sink.writeInt(streamId & 0x7fffffff);
+      sink.writeInt(associatedStreamId & 0x7fffffff);
+      sink.writeShort((unused & 0x7) << 13 | (unused & 0x1f) << 8 | (unused & 0xff));
+      sink.writeAll(headerBlockBuffer);
+      sink.flush();
+    }
+
+    @Override public synchronized void synReply(boolean outFinished, int streamId,
+        List<Header> headerBlock) throws IOException {
+      if (closed) throw new IOException("closed");
+      writeNameValueBlockToBuffer(headerBlock);
+      int type = TYPE_SYN_REPLY;
+      int flags = (outFinished ? FLAG_FIN : 0);
+      int length = (int) (headerBlockBuffer.size() + 4);
+
+      sink.writeInt(0x80000000 | (VERSION & 0x7fff) << 16 | type & 0xffff);
+      sink.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+      sink.writeInt(streamId & 0x7fffffff);
+      sink.writeAll(headerBlockBuffer);
+      sink.flush();
+    }
+
+    @Override public synchronized void headers(int streamId, List<Header> headerBlock)
+        throws IOException {
+      if (closed) throw new IOException("closed");
+      writeNameValueBlockToBuffer(headerBlock);
+      int flags = 0;
+      int type = TYPE_HEADERS;
+      int length = (int) (headerBlockBuffer.size() + 4);
+
+      sink.writeInt(0x80000000 | (VERSION & 0x7fff) << 16 | type & 0xffff);
+      sink.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+      sink.writeInt(streamId & 0x7fffffff);
+      sink.writeAll(headerBlockBuffer);
+    }
+
+    @Override public synchronized void rstStream(int streamId, ErrorCode errorCode)
+        throws IOException {
+      if (closed) throw new IOException("closed");
+      if (errorCode.spdyRstCode == -1) throw new IllegalArgumentException();
+      int flags = 0;
+      int type = TYPE_RST_STREAM;
+      int length = 8;
+      sink.writeInt(0x80000000 | (VERSION & 0x7fff) << 16 | type & 0xffff);
+      sink.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+      sink.writeInt(streamId & 0x7fffffff);
+      sink.writeInt(errorCode.spdyRstCode);
+      sink.flush();
+    }
+
+    @Override public int maxDataLength() {
+      return 16383;
+    }
+
+    @Override public synchronized void data(boolean outFinished, int streamId, Buffer source,
+        int byteCount) throws IOException {
+      int flags = (outFinished ? FLAG_FIN : 0);
+      sendDataFrame(streamId, flags, source, byteCount);
+    }
+
+    void sendDataFrame(int streamId, int flags, Buffer buffer, int byteCount)
+        throws IOException {
+      if (closed) throw new IOException("closed");
+      if (byteCount > 0xffffffL) {
+        throw new IllegalArgumentException("FRAME_TOO_LARGE max size is 16Mib: " + byteCount);
+      }
+      sink.writeInt(streamId & 0x7fffffff);
+      sink.writeInt((flags & 0xff) << 24 | byteCount & 0xffffff);
+      if (byteCount > 0) {
+        sink.write(buffer, byteCount);
+      }
+    }
+
+    private void writeNameValueBlockToBuffer(List<Header> headerBlock) throws IOException {
+      headerBlockOut.writeInt(headerBlock.size());
+      for (int i = 0, size = headerBlock.size(); i < size; i++) {
+        ByteString name = headerBlock.get(i).name;
+        headerBlockOut.writeInt(name.size());
+        headerBlockOut.write(name);
+        ByteString value = headerBlock.get(i).value;
+        headerBlockOut.writeInt(value.size());
+        headerBlockOut.write(value);
+      }
+      headerBlockOut.flush();
+    }
+
+    @Override public synchronized void settings(Settings settings) throws IOException {
+      if (closed) throw new IOException("closed");
+      int type = TYPE_SETTINGS;
+      int flags = 0;
+      int size = settings.size();
+      int length = 4 + size * 8;
+      sink.writeInt(0x80000000 | (VERSION & 0x7fff) << 16 | type & 0xffff);
+      sink.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+      sink.writeInt(size);
+      for (int i = 0; i <= Settings.COUNT; i++) {
+        if (!settings.isSet(i)) continue;
+        int settingsFlags = settings.flags(i);
+        sink.writeInt((settingsFlags & 0xff) << 24 | (i & 0xffffff));
+        sink.writeInt(settings.get(i));
+      }
+      sink.flush();
+    }
+
+    @Override public synchronized void ping(boolean reply, int payload1, int payload2)
+        throws IOException {
+      if (closed) throw new IOException("closed");
+      boolean payloadIsReply = client != ((payload1 & 1) == 1);
+      if (reply != payloadIsReply) throw new IllegalArgumentException("payload != reply");
+      int type = TYPE_PING;
+      int flags = 0;
+      int length = 4;
+      sink.writeInt(0x80000000 | (VERSION & 0x7fff) << 16 | type & 0xffff);
+      sink.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+      sink.writeInt(payload1);
+      sink.flush();
+    }
+
+    @Override public synchronized void goAway(int lastGoodStreamId, ErrorCode errorCode,
+        byte[] ignored) throws IOException {
+      if (closed) throw new IOException("closed");
+      if (errorCode.spdyGoAwayCode == -1) {
+        throw new IllegalArgumentException("errorCode.spdyGoAwayCode == -1");
+      }
+      int type = TYPE_GOAWAY;
+      int flags = 0;
+      int length = 8;
+      sink.writeInt(0x80000000 | (VERSION & 0x7fff) << 16 | type & 0xffff);
+      sink.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+      sink.writeInt(lastGoodStreamId);
+      sink.writeInt(errorCode.spdyGoAwayCode);
+      sink.flush();
+    }
+
+    @Override public synchronized void windowUpdate(int streamId, long increment)
+        throws IOException {
+      if (closed) throw new IOException("closed");
+      if (increment == 0 || increment > 0x7fffffffL) {
+        throw new IllegalArgumentException(
+            "windowSizeIncrement must be between 1 and 0x7fffffff: " + increment);
+      }
+      int type = TYPE_WINDOW_UPDATE;
+      int flags = 0;
+      int length = 8;
+      sink.writeInt(0x80000000 | (VERSION & 0x7fff) << 16 | type & 0xffff);
+      sink.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+      sink.writeInt(streamId);
+      sink.writeInt((int) increment);
+      sink.flush();
+    }
+
+    @Override public synchronized void close() throws IOException {
+      closed = true;
+      Util.closeAll(sink, headerBlockOut);
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Variant.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Variant.java
new file mode 100644
index 0000000..92f319c
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/framed/Variant.java
@@ -0,0 +1,39 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.okhttp.internal.framed;
+
+import com.android.okhttp.Protocol;
+import com.android.okhttp.okio.BufferedSink;
+import com.android.okhttp.okio.BufferedSource;
+
+/** A version and dialect of the framed socket protocol. 
+ * @hide This class is not part of the Android public SDK API*/
+public interface Variant {
+
+  /** The protocol as selected using ALPN. */
+  Protocol getProtocol();
+
+  /**
+   * @param client true if this is the HTTP client's reader, reading frames from a server.
+   */
+  FrameReader newReader(BufferedSource source, boolean client);
+
+  /**
+   * @param client true if this is the HTTP client's writer, writing frames to a server.
+   */
+  FrameWriter newWriter(BufferedSink sink, boolean client);
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/AuthenticatorAdapter.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/AuthenticatorAdapter.java
new file mode 100644
index 0000000..48257f3
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/AuthenticatorAdapter.java
@@ -0,0 +1,89 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2013 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 com.android.okhttp.internal.http;
+
+import com.android.okhttp.Authenticator;
+import com.android.okhttp.Challenge;
+import com.android.okhttp.Credentials;
+import com.android.okhttp.HttpUrl;
+import com.android.okhttp.Request;
+import com.android.okhttp.Response;
+import java.io.IOException;
+import java.net.Authenticator.RequestorType;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.PasswordAuthentication;
+import java.net.Proxy;
+import java.util.List;
+
+/** Adapts {@link java.net.Authenticator} to {@link com.android.okhttp.Authenticator}. 
+ * @hide This class is not part of the Android public SDK API*/
+public final class AuthenticatorAdapter implements Authenticator {
+  /** Uses the global authenticator to get the password. */
+  public static final Authenticator INSTANCE = new AuthenticatorAdapter();
+
+  @Override public Request authenticate(Proxy proxy, Response response) throws IOException {
+    List<Challenge> challenges = response.challenges();
+    Request request = response.request();
+    HttpUrl url = request.httpUrl();
+    for (int i = 0, size = challenges.size(); i < size; i++) {
+      Challenge challenge = challenges.get(i);
+      if (!"Basic".equalsIgnoreCase(challenge.getScheme())) continue;
+
+      PasswordAuthentication auth = java.net.Authenticator.requestPasswordAuthentication(
+          url.host(), getConnectToInetAddress(proxy, url), url.port(), url.scheme(),
+          challenge.getRealm(), challenge.getScheme(), url.url(), RequestorType.SERVER);
+      if (auth == null) continue;
+
+      String credential = Credentials.basic(auth.getUserName(), new String(auth.getPassword()));
+      return request.newBuilder()
+          .header("Authorization", credential)
+          .build();
+    }
+    return null;
+
+  }
+
+  @Override public Request authenticateProxy(Proxy proxy, Response response) throws IOException {
+    List<Challenge> challenges = response.challenges();
+    Request request = response.request();
+    HttpUrl url = request.httpUrl();
+    for (int i = 0, size = challenges.size(); i < size; i++) {
+      Challenge challenge = challenges.get(i);
+      if (!"Basic".equalsIgnoreCase(challenge.getScheme())) continue;
+
+      InetSocketAddress proxyAddress = (InetSocketAddress) proxy.address();
+      PasswordAuthentication auth = java.net.Authenticator.requestPasswordAuthentication(
+          proxyAddress.getHostName(), getConnectToInetAddress(proxy, url), proxyAddress.getPort(),
+          url.scheme(), challenge.getRealm(), challenge.getScheme(), url.url(),
+          RequestorType.PROXY);
+      if (auth == null) continue;
+
+      String credential = Credentials.basic(auth.getUserName(), new String(auth.getPassword()));
+      return request.newBuilder()
+          .header("Proxy-Authorization", credential)
+          .build();
+    }
+    return null;
+  }
+
+  private InetAddress getConnectToInetAddress(Proxy proxy, HttpUrl url) throws IOException {
+    return (proxy != null && proxy.type() != Proxy.Type.DIRECT)
+        ? ((InetSocketAddress) proxy.address()).getAddress()
+        : InetAddress.getByName(url.host());
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/CacheRequest.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/CacheRequest.java
new file mode 100644
index 0000000..f419884
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/CacheRequest.java
@@ -0,0 +1,28 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.internal.http;
+
+import java.io.IOException;
+import com.android.okhttp.okio.Sink;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface CacheRequest {
+  Sink body() throws IOException;
+  void abort();
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/CacheStrategy.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/CacheStrategy.java
new file mode 100644
index 0000000..de544db
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/CacheStrategy.java
@@ -0,0 +1,309 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.okhttp.internal.http;
+
+import com.android.okhttp.CacheControl;
+import com.android.okhttp.Headers;
+import com.android.okhttp.Request;
+import com.android.okhttp.Response;
+import java.util.Date;
+
+import static com.android.okhttp.internal.http.StatusLine.HTTP_PERM_REDIRECT;
+import static com.android.okhttp.internal.http.StatusLine.HTTP_TEMP_REDIRECT;
+import static java.net.HttpURLConnection.HTTP_BAD_METHOD;
+import static java.net.HttpURLConnection.HTTP_GONE;
+import static java.net.HttpURLConnection.HTTP_MOVED_PERM;
+import static java.net.HttpURLConnection.HTTP_MOVED_TEMP;
+import static java.net.HttpURLConnection.HTTP_MULT_CHOICE;
+import static java.net.HttpURLConnection.HTTP_NOT_AUTHORITATIVE;
+import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
+import static java.net.HttpURLConnection.HTTP_NOT_IMPLEMENTED;
+import static java.net.HttpURLConnection.HTTP_NO_CONTENT;
+import static java.net.HttpURLConnection.HTTP_OK;
+import static java.net.HttpURLConnection.HTTP_REQ_TOO_LONG;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+/**
+ * Given a request and cached response, this figures out whether to use the
+ * network, the cache, or both.
+ *
+ * <p>Selecting a cache strategy may add conditions to the request (like the
+ * "If-Modified-Since" header for conditional GETs) or warnings to the cached
+ * response (if the cached data is potentially stale).
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class CacheStrategy {
+  /** The request to send on the network, or null if this call doesn't use the network. */
+  public final Request networkRequest;
+
+  /** The cached response to return or validate; or null if this call doesn't use a cache. */
+  public final Response cacheResponse;
+
+  private CacheStrategy(Request networkRequest, Response cacheResponse) {
+    this.networkRequest = networkRequest;
+    this.cacheResponse = cacheResponse;
+  }
+
+  /**
+   * Returns true if {@code response} can be stored to later serve another
+   * request.
+   */
+  public static boolean isCacheable(Response response, Request request) {
+    // Always go to network for uncacheable response codes (RFC 7231 section 6.1),
+    // This implementation doesn't support caching partial content.
+    switch (response.code()) {
+      case HTTP_OK:
+      case HTTP_NOT_AUTHORITATIVE:
+      case HTTP_NO_CONTENT:
+      case HTTP_MULT_CHOICE:
+      case HTTP_MOVED_PERM:
+      case HTTP_NOT_FOUND:
+      case HTTP_BAD_METHOD:
+      case HTTP_GONE:
+      case HTTP_REQ_TOO_LONG:
+      case HTTP_NOT_IMPLEMENTED:
+      case HTTP_PERM_REDIRECT:
+      // These codes can be cached unless headers forbid it.
+      break;
+
+      case HTTP_MOVED_TEMP:
+      case HTTP_TEMP_REDIRECT:
+        // These codes can only be cached with the right response headers.
+        // http://tools.ietf.org/html/rfc7234#section-3
+        // s-maxage is not checked because OkHttp is a private cache that should ignore s-maxage.
+        if (response.header("Expires") != null
+            || response.cacheControl().maxAgeSeconds() != -1
+            || response.cacheControl().isPublic()
+            || response.cacheControl().isPrivate()) {
+          break;
+        }
+        // Fall-through.
+
+      default:
+        // All other codes cannot be cached.
+        return false;
+    }
+
+    // A 'no-store' directive on request or response prevents the response from being cached.
+    return !response.cacheControl().noStore() && !request.cacheControl().noStore();
+  }
+
+  /**
+   * @hide This class is not part of the Android public SDK API
+   */
+  public static class Factory {
+    final long nowMillis;
+    final Request request;
+    final Response cacheResponse;
+
+    /** The server's time when the cached response was served, if known. */
+    private Date servedDate;
+    private String servedDateString;
+
+    /** The last modified date of the cached response, if known. */
+    private Date lastModified;
+    private String lastModifiedString;
+
+    /**
+     * The expiration date of the cached 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 OkHttp specifying the timestamp when the cached
+     * HTTP request was first initiated.
+     */
+    private long sentRequestMillis;
+
+    /**
+     * Extension header set by OkHttp specifying the timestamp when the cached
+     * HTTP response was first received.
+     */
+    private long receivedResponseMillis;
+
+    /** Etag of the cached response. */
+    private String etag;
+
+    /** Age of the cached response. */
+    private int ageSeconds = -1;
+
+    public Factory(long nowMillis, Request request, Response cacheResponse) {
+      this.nowMillis = nowMillis;
+      this.request = request;
+      this.cacheResponse = cacheResponse;
+
+      if (cacheResponse != null) {
+        Headers headers = cacheResponse.headers();
+        for (int i = 0, size = headers.size(); i < size; i++) {
+          String fieldName = headers.name(i);
+          String value = headers.value(i);
+          if ("Date".equalsIgnoreCase(fieldName)) {
+            servedDate = HttpDate.parse(value);
+            servedDateString = value;
+          } else if ("Expires".equalsIgnoreCase(fieldName)) {
+            expires = HttpDate.parse(value);
+          } else if ("Last-Modified".equalsIgnoreCase(fieldName)) {
+            lastModified = HttpDate.parse(value);
+            lastModifiedString = value;
+          } else if ("ETag".equalsIgnoreCase(fieldName)) {
+            etag = value;
+          } else if ("Age".equalsIgnoreCase(fieldName)) {
+            ageSeconds = HeaderParser.parseSeconds(value, -1);
+          } else if (OkHeaders.SENT_MILLIS.equalsIgnoreCase(fieldName)) {
+            sentRequestMillis = Long.parseLong(value);
+          } else if (OkHeaders.RECEIVED_MILLIS.equalsIgnoreCase(fieldName)) {
+            receivedResponseMillis = Long.parseLong(value);
+          }
+        }
+      }
+    }
+
+    /**
+     * Returns a strategy to satisfy {@code request} using the a cached response
+     * {@code response}.
+     */
+    public CacheStrategy get() {
+      CacheStrategy candidate = getCandidate();
+
+      if (candidate.networkRequest != null && request.cacheControl().onlyIfCached()) {
+        // We're forbidden from using the network and the cache is insufficient.
+        return new CacheStrategy(null, null);
+      }
+
+      return candidate;
+    }
+
+    /** Returns a strategy to use assuming the request can use the network. */
+    private CacheStrategy getCandidate() {
+      // No cached response.
+      if (cacheResponse == null) {
+        return new CacheStrategy(request, null);
+      }
+
+      // Drop the cached response if it's missing a required handshake.
+      if (request.isHttps() && cacheResponse.handshake() == null) {
+        return new CacheStrategy(request, null);
+      }
+
+      // 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(cacheResponse, request)) {
+        return new CacheStrategy(request, null);
+      }
+
+      CacheControl requestCaching = request.cacheControl();
+      if (requestCaching.noCache() || hasConditions(request)) {
+        return new CacheStrategy(request, null);
+      }
+
+      long ageMillis = cacheResponseAge();
+      long freshMillis = computeFreshnessLifetime();
+
+      if (requestCaching.maxAgeSeconds() != -1) {
+        freshMillis = Math.min(freshMillis, SECONDS.toMillis(requestCaching.maxAgeSeconds()));
+      }
+
+      long minFreshMillis = 0;
+      if (requestCaching.minFreshSeconds() != -1) {
+        minFreshMillis = SECONDS.toMillis(requestCaching.minFreshSeconds());
+      }
+
+      long maxStaleMillis = 0;
+      CacheControl responseCaching = cacheResponse.cacheControl();
+      if (!responseCaching.mustRevalidate() && requestCaching.maxStaleSeconds() != -1) {
+        maxStaleMillis = SECONDS.toMillis(requestCaching.maxStaleSeconds());
+      }
+
+      if (!responseCaching.noCache() && ageMillis + minFreshMillis < freshMillis + maxStaleMillis) {
+        Response.Builder builder = cacheResponse.newBuilder();
+        if (ageMillis + minFreshMillis >= freshMillis) {
+          builder.addHeader("Warning", "110 HttpURLConnection \"Response is stale\"");
+        }
+        long oneDayMillis = 24 * 60 * 60 * 1000L;
+        if (ageMillis > oneDayMillis && isFreshnessLifetimeHeuristic()) {
+          builder.addHeader("Warning", "113 HttpURLConnection \"Heuristic expiration\"");
+        }
+        return new CacheStrategy(null, builder.build());
+      }
+
+      Request.Builder conditionalRequestBuilder = request.newBuilder();
+
+      if (etag != null) {
+        conditionalRequestBuilder.header("If-None-Match", etag);
+      } else if (lastModified != null) {
+        conditionalRequestBuilder.header("If-Modified-Since", lastModifiedString);
+      } else if (servedDate != null) {
+        conditionalRequestBuilder.header("If-Modified-Since", servedDateString);
+      }
+
+      Request conditionalRequest = conditionalRequestBuilder.build();
+      return hasConditions(conditionalRequest)
+          ? new CacheStrategy(conditionalRequest, cacheResponse)
+          : new CacheStrategy(conditionalRequest, null);
+    }
+
+    /**
+     * Returns the number of milliseconds that the response was fresh for,
+     * starting from the served date.
+     */
+    private long computeFreshnessLifetime() {
+      CacheControl responseCaching = cacheResponse.cacheControl();
+      if (responseCaching.maxAgeSeconds() != -1) {
+        return SECONDS.toMillis(responseCaching.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
+          && cacheResponse.request().httpUrl().query() == 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 the current age of the response, in milliseconds. The calculation
+     * is specified by RFC 2616, 13.2.3 Age Calculations.
+     */
+    private long cacheResponseAge() {
+      long apparentReceivedAge = servedDate != null
+          ? Math.max(0, receivedResponseMillis - servedDate.getTime())
+          : 0;
+      long receivedAge = ageSeconds != -1
+          ? Math.max(apparentReceivedAge, SECONDS.toMillis(ageSeconds))
+          : apparentReceivedAge;
+      long responseDuration = receivedResponseMillis - sentRequestMillis;
+      long residentDuration = nowMillis - receivedResponseMillis;
+      return receivedAge + responseDuration + residentDuration;
+    }
+
+    /**
+     * 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 cacheResponse.cacheControl().maxAgeSeconds() == -1 && expires == null;
+    }
+
+    /**
+     * Returns true if the request contains conditions that save the server from
+     * sending a response that the client has locally. When a request is enqueued
+     * with its own conditions, the built-in response cache won't be used.
+     */
+    private static boolean hasConditions(Request request) {
+      return request.header("If-Modified-Since") != null || request.header("If-None-Match") != null;
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/HeaderParser.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/HeaderParser.java
new file mode 100644
index 0000000..7d398ea
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/HeaderParser.java
@@ -0,0 +1,73 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.okhttp.internal.http;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class HeaderParser {
+  /**
+   * 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.
+   */
+  public 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.
+   */
+  public 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
+   * {@code defaultValue} if it cannot be parsed.
+   */
+  public static int parseSeconds(String value, int defaultValue) {
+    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 defaultValue;
+    }
+  }
+
+  private HeaderParser() {
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/Http1xStream.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/Http1xStream.java
new file mode 100644
index 0000000..a925746
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/Http1xStream.java
@@ -0,0 +1,508 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.okhttp.internal.http;
+
+import com.android.okhttp.Headers;
+import com.android.okhttp.Request;
+import com.android.okhttp.Response;
+import com.android.okhttp.ResponseBody;
+import com.android.okhttp.internal.Internal;
+import com.android.okhttp.internal.Util;
+import com.android.okhttp.internal.io.RealConnection;
+import java.io.EOFException;
+import java.io.IOException;
+import java.net.ProtocolException;
+import com.android.okhttp.okio.Buffer;
+import com.android.okhttp.okio.BufferedSink;
+import com.android.okhttp.okio.BufferedSource;
+import com.android.okhttp.okio.ForwardingTimeout;
+import com.android.okhttp.okio.Okio;
+import com.android.okhttp.okio.Sink;
+import com.android.okhttp.okio.Source;
+import com.android.okhttp.okio.Timeout;
+
+import static com.android.okhttp.internal.Util.checkOffsetAndCount;
+import static com.android.okhttp.internal.http.StatusLine.HTTP_CONTINUE;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+/**
+ * A socket connection that can be used to send HTTP/1.1 messages. This class
+ * strictly enforces the following lifecycle:
+ * <ol>
+ *   <li>{@link #writeRequest Send request headers}.
+ *   <li>Open a sink to write the request body. Either {@link
+ *       #newFixedLengthSink fixed-length} or {@link #newChunkedSink chunked}.
+ *   <li>Write to and then close that sink.
+ *   <li>{@link #readResponse Read response headers}.
+ *   <li>Open a source to read the response body. Either {@link
+ *       #newFixedLengthSource fixed-length}, {@link #newChunkedSource chunked}
+ *       or {@link #newUnknownLengthSource unknown length}.
+ *   <li>Read from and close that source.
+ * </ol>
+ * <p>Exchanges that do not have a request body may skip creating and closing
+ * the request body. Exchanges that do not have a response body can call {@link
+ * #newFixedLengthSource(long) newFixedLengthSource(0)} and may skip reading and
+ * closing that source.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Http1xStream implements HttpStream {
+  private static final int STATE_IDLE = 0; // Idle connections are ready to write request headers.
+  private static final int STATE_OPEN_REQUEST_BODY = 1;
+  private static final int STATE_WRITING_REQUEST_BODY = 2;
+  private static final int STATE_READ_RESPONSE_HEADERS = 3;
+  private static final int STATE_OPEN_RESPONSE_BODY = 4;
+  private static final int STATE_READING_RESPONSE_BODY = 5;
+  private static final int STATE_CLOSED = 6;
+
+  /** The stream allocation that owns this stream. May be null for HTTPS proxy tunnels. */
+  private final StreamAllocation streamAllocation;
+  private final BufferedSource source;
+  private final BufferedSink sink;
+  private HttpEngine httpEngine;
+  private int state = STATE_IDLE;
+
+  public Http1xStream(StreamAllocation streamAllocation, BufferedSource source, BufferedSink sink) {
+    this.streamAllocation = streamAllocation;
+    this.source = source;
+    this.sink = sink;
+  }
+
+  @Override public void setHttpEngine(HttpEngine httpEngine) {
+    this.httpEngine = httpEngine;
+  }
+
+  @Override public Sink createRequestBody(Request request, long contentLength) throws IOException {
+    if ("chunked".equalsIgnoreCase(request.header("Transfer-Encoding"))) {
+      // Stream a request body of unknown length.
+      return newChunkedSink();
+    }
+
+    if (contentLength != -1) {
+      // Stream a request body of a known length.
+      return newFixedLengthSink(contentLength);
+    }
+
+    throw new IllegalStateException(
+        "Cannot stream a request body without chunked encoding or a known content length!");
+  }
+
+  @Override public void cancel() {
+    RealConnection connection = streamAllocation.connection();
+    if (connection != null) connection.cancel();
+  }
+
+  /**
+   * 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.
+   */
+  @Override public void writeRequestHeaders(Request request) throws IOException {
+    httpEngine.writingRequestHeaders();
+    String requestLine = RequestLine.get(
+        request, httpEngine.getConnection().getRoute().getProxy().type());
+    writeRequest(request.headers(), requestLine);
+  }
+
+  @Override public Response.Builder readResponseHeaders() throws IOException {
+    return readResponse();
+  }
+
+  @Override public ResponseBody openResponseBody(Response response) throws IOException {
+    Source source = getTransferStream(response);
+    return new RealResponseBody(response.headers(), Okio.buffer(source));
+  }
+
+  private Source getTransferStream(Response response) throws IOException {
+    if (!HttpEngine.hasBody(response)) {
+      return newFixedLengthSource(0);
+    }
+
+    if ("chunked".equalsIgnoreCase(response.header("Transfer-Encoding"))) {
+      return newChunkedSource(httpEngine);
+    }
+
+    long contentLength = OkHeaders.contentLength(response);
+    if (contentLength != -1) {
+      return newFixedLengthSource(contentLength);
+    }
+
+    // Wrap the input stream from the connection (rather than just returning
+    // "socketIn" directly here), so that we can control its use after the
+    // reference escapes.
+    return newUnknownLengthSource();
+  }
+
+  /** Returns true if this connection is closed. */
+  public boolean isClosed() {
+    return state == STATE_CLOSED;
+  }
+
+  @Override public void finishRequest() throws IOException {
+    sink.flush();
+  }
+
+  /** Returns bytes of a request header for sending on an HTTP transport. */
+  public void writeRequest(Headers headers, String requestLine) throws IOException {
+    if (state != STATE_IDLE) throw new IllegalStateException("state: " + state);
+    sink.writeUtf8(requestLine).writeUtf8("\r\n");
+    for (int i = 0, size = headers.size(); i < size; i ++) {
+      sink.writeUtf8(headers.name(i))
+          .writeUtf8(": ")
+          .writeUtf8(headers.value(i))
+          .writeUtf8("\r\n");
+    }
+    sink.writeUtf8("\r\n");
+    state = STATE_OPEN_REQUEST_BODY;
+  }
+
+  /** Parses bytes of a response header from an HTTP transport. */
+  public Response.Builder readResponse() throws IOException {
+    if (state != STATE_OPEN_REQUEST_BODY && state != STATE_READ_RESPONSE_HEADERS) {
+      throw new IllegalStateException("state: " + state);
+    }
+
+    try {
+      while (true) {
+        StatusLine statusLine = StatusLine.parse(source.readUtf8LineStrict());
+
+        Response.Builder responseBuilder = new Response.Builder()
+            .protocol(statusLine.protocol)
+            .code(statusLine.code)
+            .message(statusLine.message)
+            .headers(readHeaders());
+
+        if (statusLine.code != HTTP_CONTINUE) {
+          state = STATE_OPEN_RESPONSE_BODY;
+          return responseBuilder;
+        }
+      }
+    } catch (EOFException e) {
+      // Provide more context if the server ends the stream before sending a response.
+      IOException exception = new IOException("unexpected end of stream on " + streamAllocation);
+      exception.initCause(e);
+      throw exception;
+    }
+  }
+
+  /** Reads headers or trailers. */
+  public Headers readHeaders() throws IOException {
+    Headers.Builder headers = new Headers.Builder();
+    // parse the result headers until the first blank line
+    for (String line; (line = source.readUtf8LineStrict()).length() != 0; ) {
+      Internal.instance.addLenient(headers, line);
+    }
+    return headers.build();
+  }
+
+  public Sink newChunkedSink() {
+    if (state != STATE_OPEN_REQUEST_BODY) throw new IllegalStateException("state: " + state);
+    state = STATE_WRITING_REQUEST_BODY;
+    return new ChunkedSink();
+  }
+
+  public Sink newFixedLengthSink(long contentLength) {
+    if (state != STATE_OPEN_REQUEST_BODY) throw new IllegalStateException("state: " + state);
+    state = STATE_WRITING_REQUEST_BODY;
+    return new FixedLengthSink(contentLength);
+  }
+
+  @Override public void writeRequestBody(RetryableSink requestBody) throws IOException {
+    if (state != STATE_OPEN_REQUEST_BODY) throw new IllegalStateException("state: " + state);
+    state = STATE_READ_RESPONSE_HEADERS;
+    requestBody.writeToSocket(sink);
+  }
+
+  public Source newFixedLengthSource(long length) throws IOException {
+    if (state != STATE_OPEN_RESPONSE_BODY) throw new IllegalStateException("state: " + state);
+    state = STATE_READING_RESPONSE_BODY;
+    return new FixedLengthSource(length);
+  }
+
+  public Source newChunkedSource(HttpEngine httpEngine) throws IOException {
+    if (state != STATE_OPEN_RESPONSE_BODY) throw new IllegalStateException("state: " + state);
+    state = STATE_READING_RESPONSE_BODY;
+    return new ChunkedSource(httpEngine);
+  }
+
+  public Source newUnknownLengthSource() throws IOException {
+    if (state != STATE_OPEN_RESPONSE_BODY) throw new IllegalStateException("state: " + state);
+    if (streamAllocation == null) throw new IllegalStateException("streamAllocation == null");
+    state = STATE_READING_RESPONSE_BODY;
+    streamAllocation.noNewStreams();
+    return new UnknownLengthSource();
+  }
+
+  /**
+   * Sets the delegate of {@code timeout} to {@link Timeout#NONE} and resets its underlying timeout
+   * to the default configuration. Use this to avoid unexpected sharing of timeouts between pooled
+   * connections.
+   */
+  private void detachTimeout(ForwardingTimeout timeout) {
+    Timeout oldDelegate = timeout.delegate();
+    timeout.setDelegate(Timeout.NONE);
+    oldDelegate.clearDeadline();
+    oldDelegate.clearTimeout();
+  }
+
+  /** An HTTP body with a fixed length known in advance. */
+  private final class FixedLengthSink implements Sink {
+    private final ForwardingTimeout timeout = new ForwardingTimeout(sink.timeout());
+    private boolean closed;
+    private long bytesRemaining;
+
+    private FixedLengthSink(long bytesRemaining) {
+      this.bytesRemaining = bytesRemaining;
+    }
+
+    @Override public Timeout timeout() {
+      return timeout;
+    }
+
+    @Override public void write(Buffer source, long byteCount) throws IOException {
+      if (closed) throw new IllegalStateException("closed");
+      checkOffsetAndCount(source.size(), 0, byteCount);
+      if (byteCount > bytesRemaining) {
+        throw new ProtocolException("expected " + bytesRemaining
+            + " bytes but received " + byteCount);
+      }
+      sink.write(source, byteCount);
+      bytesRemaining -= byteCount;
+    }
+
+    @Override public void flush() throws IOException {
+      if (closed) return; // Don't throw; this stream might have been closed on the caller's behalf.
+      sink.flush();
+    }
+
+    @Override public void close() throws IOException {
+      if (closed) return;
+      closed = true;
+      if (bytesRemaining > 0) throw new ProtocolException("unexpected end of stream");
+      detachTimeout(timeout);
+      state = STATE_READ_RESPONSE_HEADERS;
+    }
+  }
+
+  /**
+   * An HTTP body with alternating chunk sizes and chunk bodies. It is the
+   * caller's responsibility to buffer chunks; typically by using a buffered
+   * sink with this sink.
+   */
+  private final class ChunkedSink implements Sink {
+    private final ForwardingTimeout timeout = new ForwardingTimeout(sink.timeout());
+    private boolean closed;
+
+    @Override public Timeout timeout() {
+      return timeout;
+    }
+
+    @Override public void write(Buffer source, long byteCount) throws IOException {
+      if (closed) throw new IllegalStateException("closed");
+      if (byteCount == 0) return;
+
+      sink.writeHexadecimalUnsignedLong(byteCount);
+      sink.writeUtf8("\r\n");
+      sink.write(source, byteCount);
+      sink.writeUtf8("\r\n");
+    }
+
+    @Override public synchronized void flush() throws IOException {
+      if (closed) return; // Don't throw; this stream might have been closed on the caller's behalf.
+      sink.flush();
+    }
+
+    @Override public synchronized void close() throws IOException {
+      if (closed) return;
+      closed = true;
+      sink.writeUtf8("0\r\n\r\n");
+      detachTimeout(timeout);
+      state = STATE_READ_RESPONSE_HEADERS;
+    }
+  }
+
+  private abstract class AbstractSource implements Source {
+    protected final ForwardingTimeout timeout = new ForwardingTimeout(source.timeout());
+    protected boolean closed;
+
+    @Override public Timeout timeout() {
+      return timeout;
+    }
+
+    /**
+     * 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() throws IOException {
+      if (state != STATE_READING_RESPONSE_BODY) throw new IllegalStateException("state: " + state);
+
+      detachTimeout(timeout);
+
+      state = STATE_CLOSED;
+      if (streamAllocation != null) {
+        streamAllocation.streamFinished(Http1xStream.this);
+      }
+    }
+
+    protected final void unexpectedEndOfInput() {
+      if (state == STATE_CLOSED) return;
+
+      state = STATE_CLOSED;
+      if (streamAllocation != null) {
+        streamAllocation.noNewStreams();
+        streamAllocation.streamFinished(Http1xStream.this);
+      }
+    }
+  }
+
+  /** An HTTP body with a fixed length specified in advance. */
+  private class FixedLengthSource extends AbstractSource {
+    private long bytesRemaining;
+
+    public FixedLengthSource(long length) throws IOException {
+      bytesRemaining = length;
+      if (bytesRemaining == 0) {
+        endOfInput();
+      }
+    }
+
+    @Override public long read(Buffer sink, long byteCount) throws IOException {
+      if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
+      if (closed) throw new IllegalStateException("closed");
+      if (bytesRemaining == 0) return -1;
+
+      long read = source.read(sink, Math.min(bytesRemaining, byteCount));
+      if (read == -1) {
+        unexpectedEndOfInput(); // The server didn't supply the promised content length.
+        throw new ProtocolException("unexpected end of stream");
+      }
+
+      bytesRemaining -= read;
+      if (bytesRemaining == 0) {
+        endOfInput();
+      }
+      return read;
+    }
+
+    @Override public void close() throws IOException {
+      if (closed) return;
+
+      if (bytesRemaining != 0
+          && !Util.discard(this, DISCARD_STREAM_TIMEOUT_MILLIS, MILLISECONDS)) {
+        unexpectedEndOfInput();
+      }
+
+      closed = true;
+    }
+  }
+
+  /** An HTTP body with alternating chunk sizes and chunk bodies. */
+  private class ChunkedSource extends AbstractSource {
+    private static final long NO_CHUNK_YET = -1L;
+    private long bytesRemainingInChunk = NO_CHUNK_YET;
+    private boolean hasMoreChunks = true;
+    private final HttpEngine httpEngine;
+
+    ChunkedSource(HttpEngine httpEngine) throws IOException {
+      this.httpEngine = httpEngine;
+    }
+
+    @Override public long read(Buffer sink, long byteCount) throws IOException {
+      if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
+      if (closed) throw new IllegalStateException("closed");
+      if (!hasMoreChunks) return -1;
+
+      if (bytesRemainingInChunk == 0 || bytesRemainingInChunk == NO_CHUNK_YET) {
+        readChunkSize();
+        if (!hasMoreChunks) return -1;
+      }
+
+      long read = source.read(sink, Math.min(byteCount, bytesRemainingInChunk));
+      if (read == -1) {
+        unexpectedEndOfInput(); // The server didn't supply the promised chunk length.
+        throw new ProtocolException("unexpected end of stream");
+      }
+      bytesRemainingInChunk -= read;
+      return read;
+    }
+
+    private void readChunkSize() throws IOException {
+      // Read the suffix of the previous chunk.
+      if (bytesRemainingInChunk != NO_CHUNK_YET) {
+        source.readUtf8LineStrict();
+      }
+      try {
+        bytesRemainingInChunk = source.readHexadecimalUnsignedLong();
+        String extensions = source.readUtf8LineStrict().trim();
+        if (bytesRemainingInChunk < 0 || (!extensions.isEmpty() && !extensions.startsWith(";"))) {
+          throw new ProtocolException("expected chunk size and optional extensions but was \""
+              + bytesRemainingInChunk + extensions + "\"");
+        }
+      } catch (NumberFormatException e) {
+        throw new ProtocolException(e.getMessage());
+      }
+      if (bytesRemainingInChunk == 0L) {
+        hasMoreChunks = false;
+        httpEngine.receiveHeaders(readHeaders());
+        endOfInput();
+      }
+    }
+
+    @Override public void close() throws IOException {
+      if (closed) return;
+      if (hasMoreChunks && !Util.discard(this, DISCARD_STREAM_TIMEOUT_MILLIS, MILLISECONDS)) {
+        unexpectedEndOfInput();
+      }
+      closed = true;
+    }
+  }
+
+  /** An HTTP message body terminated by the end of the underlying stream. */
+  private class UnknownLengthSource extends AbstractSource {
+    private boolean inputExhausted;
+
+    @Override public long read(Buffer sink, long byteCount)
+        throws IOException {
+      if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
+      if (closed) throw new IllegalStateException("closed");
+      if (inputExhausted) return -1;
+
+      long read = source.read(sink, byteCount);
+      if (read == -1) {
+        inputExhausted = true;
+        endOfInput();
+        return -1;
+      }
+      return read;
+    }
+
+    @Override public void close() throws IOException {
+      if (closed) return;
+      if (!inputExhausted) {
+        unexpectedEndOfInput();
+      }
+      closed = true;
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/Http2xStream.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/Http2xStream.java
new file mode 100644
index 0000000..64908e0
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/Http2xStream.java
@@ -0,0 +1,298 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.okhttp.internal.http;
+
+import com.android.okhttp.Headers;
+import com.android.okhttp.Protocol;
+import com.android.okhttp.Request;
+import com.android.okhttp.Response;
+import com.android.okhttp.ResponseBody;
+import com.android.okhttp.internal.Util;
+import com.android.okhttp.internal.framed.ErrorCode;
+import com.android.okhttp.internal.framed.FramedConnection;
+import com.android.okhttp.internal.framed.FramedStream;
+import com.android.okhttp.internal.framed.Header;
+import java.io.IOException;
+import java.net.ProtocolException;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import com.android.okhttp.okio.ByteString;
+import com.android.okhttp.okio.ForwardingSource;
+import com.android.okhttp.okio.Okio;
+import com.android.okhttp.okio.Sink;
+import com.android.okhttp.okio.Source;
+
+import static com.android.okhttp.internal.framed.Header.RESPONSE_STATUS;
+import static com.android.okhttp.internal.framed.Header.TARGET_AUTHORITY;
+import static com.android.okhttp.internal.framed.Header.TARGET_HOST;
+import static com.android.okhttp.internal.framed.Header.TARGET_METHOD;
+import static com.android.okhttp.internal.framed.Header.TARGET_PATH;
+import static com.android.okhttp.internal.framed.Header.TARGET_SCHEME;
+import static com.android.okhttp.internal.framed.Header.VERSION;
+
+/** An HTTP stream for HTTP/2 and SPDY. 
+ * @hide This class is not part of the Android public SDK API*/
+public final class Http2xStream implements HttpStream {
+  private static final ByteString CONNECTION = ByteString.encodeUtf8("connection");
+  private static final ByteString HOST = ByteString.encodeUtf8("host");
+  private static final ByteString KEEP_ALIVE = ByteString.encodeUtf8("keep-alive");
+  private static final ByteString PROXY_CONNECTION = ByteString.encodeUtf8("proxy-connection");
+  private static final ByteString TRANSFER_ENCODING = ByteString.encodeUtf8("transfer-encoding");
+  private static final ByteString TE = ByteString.encodeUtf8("te");
+  private static final ByteString ENCODING = ByteString.encodeUtf8("encoding");
+  private static final ByteString UPGRADE = ByteString.encodeUtf8("upgrade");
+
+  /** See http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1#TOC-3.2.1-Request. */
+  private static final List<ByteString> SPDY_3_SKIPPED_REQUEST_HEADERS = Util.immutableList(
+      CONNECTION,
+      HOST,
+      KEEP_ALIVE,
+      PROXY_CONNECTION,
+      TRANSFER_ENCODING,
+      TARGET_METHOD,
+      TARGET_PATH,
+      TARGET_SCHEME,
+      TARGET_AUTHORITY,
+      TARGET_HOST,
+      VERSION);
+  private static final List<ByteString> SPDY_3_SKIPPED_RESPONSE_HEADERS = Util.immutableList(
+      CONNECTION,
+      HOST,
+      KEEP_ALIVE,
+      PROXY_CONNECTION,
+      TRANSFER_ENCODING);
+
+  /** See http://tools.ietf.org/html/draft-ietf-httpbis-http2-09#section-8.1.3. */
+  private static final List<ByteString> HTTP_2_SKIPPED_REQUEST_HEADERS = Util.immutableList(
+      CONNECTION,
+      HOST,
+      KEEP_ALIVE,
+      PROXY_CONNECTION,
+      TE,
+      TRANSFER_ENCODING,
+      ENCODING,
+      UPGRADE,
+      TARGET_METHOD,
+      TARGET_PATH,
+      TARGET_SCHEME,
+      TARGET_AUTHORITY,
+      TARGET_HOST,
+      VERSION);
+  private static final List<ByteString> HTTP_2_SKIPPED_RESPONSE_HEADERS = Util.immutableList(
+      CONNECTION,
+      HOST,
+      KEEP_ALIVE,
+      PROXY_CONNECTION,
+      TE,
+      TRANSFER_ENCODING,
+      ENCODING,
+      UPGRADE);
+
+  private final StreamAllocation streamAllocation;
+  private final FramedConnection framedConnection;
+  private HttpEngine httpEngine;
+  private FramedStream stream;
+
+  public Http2xStream(StreamAllocation streamAllocation, FramedConnection framedConnection) {
+    this.streamAllocation = streamAllocation;
+    this.framedConnection = framedConnection;
+  }
+
+  @Override public void setHttpEngine(HttpEngine httpEngine) {
+    this.httpEngine = httpEngine;
+  }
+
+  @Override public Sink createRequestBody(Request request, long contentLength) throws IOException {
+    return stream.getSink();
+  }
+
+  @Override public void writeRequestHeaders(Request request) throws IOException {
+    if (stream != null) return;
+
+    httpEngine.writingRequestHeaders();
+    boolean permitsRequestBody = httpEngine.permitsRequestBody(request);
+    List<Header> requestHeaders = framedConnection.getProtocol() == Protocol.HTTP_2
+        ? http2HeadersList(request)
+        : spdy3HeadersList(request);
+    boolean hasResponseBody = true;
+    stream = framedConnection.newStream(requestHeaders, permitsRequestBody, hasResponseBody);
+    stream.readTimeout().timeout(httpEngine.client.getReadTimeout(), TimeUnit.MILLISECONDS);
+    stream.writeTimeout().timeout(httpEngine.client.getWriteTimeout(), TimeUnit.MILLISECONDS);
+  }
+
+  @Override public void writeRequestBody(RetryableSink requestBody) throws IOException {
+    requestBody.writeToSocket(stream.getSink());
+  }
+
+  @Override public void finishRequest() throws IOException {
+    stream.getSink().close();
+  }
+
+  @Override public Response.Builder readResponseHeaders() throws IOException {
+    return framedConnection.getProtocol() == Protocol.HTTP_2
+        ? readHttp2HeadersList(stream.getResponseHeaders())
+        : readSpdy3HeadersList(stream.getResponseHeaders());
+  }
+
+  /**
+   * Returns a list of alternating names and values containing a SPDY request.
+   * Names are all lowercase. No names are repeated. If any name has multiple
+   * values, they are concatenated using "\0" as a delimiter.
+   */
+  public static List<Header> spdy3HeadersList(Request request) {
+    Headers headers = request.headers();
+    List<Header> result = new ArrayList<>(headers.size() + 5);
+    result.add(new Header(TARGET_METHOD, request.method()));
+    result.add(new Header(TARGET_PATH, RequestLine.requestPath(request.httpUrl())));
+    result.add(new Header(VERSION, "HTTP/1.1"));
+    result.add(new Header(TARGET_HOST, Util.hostHeader(request.httpUrl(), false)));
+    result.add(new Header(TARGET_SCHEME, request.httpUrl().scheme()));
+
+    Set<ByteString> names = new LinkedHashSet<>();
+    for (int i = 0, size = headers.size(); i < size; i++) {
+      // header names must be lowercase.
+      ByteString name = ByteString.encodeUtf8(headers.name(i).toLowerCase(Locale.US));
+
+      // Drop headers that are forbidden when layering HTTP over SPDY.
+      if (SPDY_3_SKIPPED_REQUEST_HEADERS.contains(name)) continue;
+
+      // If we haven't seen this name before, add the pair to the end of the list...
+      String value = headers.value(i);
+      if (names.add(name)) {
+        result.add(new Header(name, value));
+        continue;
+      }
+
+      // ...otherwise concatenate the existing values and this value.
+      for (int j = 0; j < result.size(); j++) {
+        if (result.get(j).name.equals(name)) {
+          String concatenated = joinOnNull(result.get(j).value.utf8(), value);
+          result.set(j, new Header(name, concatenated));
+          break;
+        }
+      }
+    }
+    return result;
+  }
+
+  private static String joinOnNull(String first, String second) {
+    return new StringBuilder(first).append('\0').append(second).toString();
+  }
+
+  public static List<Header> http2HeadersList(Request request) {
+    Headers headers = request.headers();
+    List<Header> result = new ArrayList<>(headers.size() + 4);
+    result.add(new Header(TARGET_METHOD, request.method()));
+    result.add(new Header(TARGET_PATH, RequestLine.requestPath(request.httpUrl())));
+    result.add(new Header(TARGET_AUTHORITY, Util.hostHeader(request.httpUrl(), false))); // Optional
+    result.add(new Header(TARGET_SCHEME, request.httpUrl().scheme()));
+
+    for (int i = 0, size = headers.size(); i < size; i++) {
+      // header names must be lowercase.
+      ByteString name = ByteString.encodeUtf8(headers.name(i).toLowerCase(Locale.US));
+      if (!HTTP_2_SKIPPED_REQUEST_HEADERS.contains(name)) {
+        result.add(new Header(name, headers.value(i)));
+      }
+    }
+    return result;
+  }
+
+  /** Returns headers for a name value block containing a SPDY response. */
+  public static Response.Builder readSpdy3HeadersList(List<Header> headerBlock) throws IOException {
+    String status = null;
+    String version = "HTTP/1.1";
+    Headers.Builder headersBuilder = new Headers.Builder();
+    for (int i = 0, size = headerBlock.size(); i < size; i++) {
+      ByteString name = headerBlock.get(i).name;
+
+      String values = headerBlock.get(i).value.utf8();
+      for (int start = 0; start < values.length(); ) {
+        int end = values.indexOf('\0', start);
+        if (end == -1) {
+          end = values.length();
+        }
+        String value = values.substring(start, end);
+        if (name.equals(RESPONSE_STATUS)) {
+          status = value;
+        } else if (name.equals(VERSION)) {
+          version = value;
+        } else if (!SPDY_3_SKIPPED_RESPONSE_HEADERS.contains(name)) {
+          headersBuilder.add(name.utf8(), value);
+        }
+        start = end + 1;
+      }
+    }
+    if (status == null) throw new ProtocolException("Expected ':status' header not present");
+
+    StatusLine statusLine = StatusLine.parse(version + " " + status);
+    return new Response.Builder()
+        .protocol(Protocol.SPDY_3)
+        .code(statusLine.code)
+        .message(statusLine.message)
+        .headers(headersBuilder.build());
+  }
+
+  /** Returns headers for a name value block containing an HTTP/2 response. */
+  public static Response.Builder readHttp2HeadersList(List<Header> headerBlock) throws IOException {
+    String status = null;
+
+    Headers.Builder headersBuilder = new Headers.Builder();
+    for (int i = 0, size = headerBlock.size(); i < size; i++) {
+      ByteString name = headerBlock.get(i).name;
+
+      String value = headerBlock.get(i).value.utf8();
+      if (name.equals(RESPONSE_STATUS)) {
+        status = value;
+      } else if (!HTTP_2_SKIPPED_RESPONSE_HEADERS.contains(name)) {
+        headersBuilder.add(name.utf8(), value);
+      }
+    }
+    if (status == null) throw new ProtocolException("Expected ':status' header not present");
+
+    StatusLine statusLine = StatusLine.parse("HTTP/1.1 " + status);
+    return new Response.Builder()
+        .protocol(Protocol.HTTP_2)
+        .code(statusLine.code)
+        .message(statusLine.message)
+        .headers(headersBuilder.build());
+  }
+
+  @Override public ResponseBody openResponseBody(Response response) throws IOException {
+    Source source = new StreamFinishingSource(stream.getSource());
+    return new RealResponseBody(response.headers(), Okio.buffer(source));
+  }
+
+  @Override public void cancel() {
+    if (stream != null) stream.closeLater(ErrorCode.CANCEL);
+  }
+
+  class StreamFinishingSource extends ForwardingSource {
+    public StreamFinishingSource(Source delegate) {
+      super(delegate);
+    }
+
+    @Override public void close() throws IOException {
+      streamAllocation.streamFinished(Http2xStream.this);
+      super.close();
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/HttpDate.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/HttpDate.java
new file mode 100644
index 0000000..52265c2
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/HttpDate.java
@@ -0,0 +1,121 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.okhttp.internal.http;
+
+import java.text.DateFormat;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+/**
+ * Best-effort parser for HTTP dates.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class HttpDate {
+
+  private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
+
+  /**
+   * 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() {
+          // RFC 2616 specified: RFC 822, updated by RFC 1123 format with fixed GMT.
+          DateFormat rfc1123 = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
+          rfc1123.setLenient(false);
+          rfc1123.setTimeZone(GMT);
+          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_FORMAT_STRINGS = new String[] {
+      // HTTP formats required by RFC2616 but with any timezone.
+      "EEE, dd MMM yyyy HH:mm:ss zzz", // RFC 822, updated by RFC 1123 with any TZ
+      "EEEE, dd-MMM-yy HH:mm:ss zzz", // RFC 850, obsoleted by RFC 1036 with any TZ.
+      "EEE MMM d HH:mm:ss yyyy", // ANSI C's asctime() format
+       // Alternative formats.
+      "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",
+  };
+
+  private static final DateFormat[] BROWSER_COMPATIBLE_DATE_FORMATS =
+      new DateFormat[BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS.length];
+
+  /** Returns the date for {@code value}. Returns null if the value couldn't be parsed. */
+  public static Date parse(String value) {
+    if (value.length() == 0) {
+      return null;
+    }
+
+    ParsePosition position = new ParsePosition(0);
+    Date result = STANDARD_DATE_FORMAT.get().parse(value, position);
+    if (position.getIndex() == value.length()) {
+      // STANDARD_DATE_FORMAT must match exactly; all text must be consumed, e.g. no ignored
+      // non-standard trailing "+01:00". Those cases are covered below.
+      return result;
+    }
+    synchronized (BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS) {
+      for (int i = 0, count = BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS.length; i < count; i++) {
+        DateFormat format = BROWSER_COMPATIBLE_DATE_FORMATS[i];
+        if (format == null) {
+          format = new SimpleDateFormat(BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS[i], Locale.US);
+          // Set the timezone to use when interpreting formats that don't have a timezone. GMT is
+          // specified by RFC 2616.
+          format.setTimeZone(GMT);
+          BROWSER_COMPATIBLE_DATE_FORMATS[i] = format;
+        }
+        position.setIndex(0);
+        result = format.parse(value, position);
+        if (position.getIndex() != 0) {
+          // Something was parsed. It's possible the entire string was not consumed but we ignore
+          // that. If any of the BROWSER_COMPATIBLE_DATE_FORMAT_STRINGS ended in "'GMT'" we'd have
+          // to also check that position.getIndex() == value.length() otherwise parsing might have
+          // terminated early, ignoring things like "+01:00". Leaving this as != 0 means that any
+          // trailing junk is ignored.
+          return result;
+        }
+      }
+    }
+    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/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/HttpEngine.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/HttpEngine.java
new file mode 100644
index 0000000..0ef78ed
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/HttpEngine.java
@@ -0,0 +1,989 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  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.android.okhttp.internal.http;
+
+import com.android.okhttp.Address;
+import com.android.okhttp.CertificatePinner;
+import com.android.okhttp.Connection;
+import com.android.okhttp.Headers;
+import com.android.okhttp.HttpUrl;
+import com.android.okhttp.Interceptor;
+import com.android.okhttp.MediaType;
+import com.android.okhttp.OkHttpClient;
+import com.android.okhttp.Protocol;
+import com.android.okhttp.Request;
+import com.android.okhttp.Response;
+import com.android.okhttp.ResponseBody;
+import com.android.okhttp.Route;
+import com.android.okhttp.internal.Internal;
+import com.android.okhttp.internal.InternalCache;
+import com.android.okhttp.internal.Util;
+import com.android.okhttp.internal.Version;
+import java.io.IOException;
+import java.net.CookieHandler;
+import java.net.ProtocolException;
+import java.net.Proxy;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSocketFactory;
+import com.android.okhttp.okio.Buffer;
+import com.android.okhttp.okio.BufferedSink;
+import com.android.okhttp.okio.BufferedSource;
+import com.android.okhttp.okio.GzipSource;
+import com.android.okhttp.okio.Okio;
+import com.android.okhttp.okio.Sink;
+import com.android.okhttp.okio.Source;
+import com.android.okhttp.okio.Timeout;
+
+import static com.android.okhttp.internal.Util.closeQuietly;
+import static com.android.okhttp.internal.http.StatusLine.HTTP_CONTINUE;
+import static com.android.okhttp.internal.http.StatusLine.HTTP_PERM_REDIRECT;
+import static com.android.okhttp.internal.http.StatusLine.HTTP_TEMP_REDIRECT;
+import static java.net.HttpURLConnection.HTTP_MOVED_PERM;
+import static java.net.HttpURLConnection.HTTP_MOVED_TEMP;
+import static java.net.HttpURLConnection.HTTP_MULT_CHOICE;
+import static java.net.HttpURLConnection.HTTP_NOT_MODIFIED;
+import static java.net.HttpURLConnection.HTTP_NO_CONTENT;
+import static java.net.HttpURLConnection.HTTP_PROXY_AUTH;
+import static java.net.HttpURLConnection.HTTP_SEE_OTHER;
+import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+/**
+ * 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.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class HttpEngine {
+  /**
+   * How many redirects and auth challenges should we attempt? Chrome follows 21 redirects; Firefox,
+   * curl, and wget follow 20; Safari follows 16; and HTTP/1.0 recommends 5.
+   */
+  public static final int MAX_FOLLOW_UPS = 20;
+
+  private static final ResponseBody EMPTY_BODY = new ResponseBody() {
+    @Override public MediaType contentType() {
+      return null;
+    }
+    @Override public long contentLength() {
+      return 0;
+    }
+    @Override public BufferedSource source() {
+      return new Buffer();
+    }
+  };
+
+  final OkHttpClient client;
+
+  public final StreamAllocation streamAllocation;
+  private final Response priorResponse;
+  private HttpStream httpStream;
+
+  /** 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;
+
+  /**
+   * True if the request body must be completely buffered before transmission;
+   * false if it can be streamed. Buffering has two advantages: we don't need
+   * the content-length in advance and we can retransmit if necessary. The
+   * upside of streaming is that we can save memory.
+   */
+  public final boolean bufferRequestBody;
+
+  /**
+   * The original application-provided request. Never modified by OkHttp. When
+   * follow-up requests are necessary, they are derived from this request.
+   */
+  private final Request userRequest;
+
+  /**
+   * The request to send on the network, or null for no network request. This is
+   * derived from the user request, and customized to support OkHttp features
+   * like compression and caching.
+   */
+  private Request networkRequest;
+
+  /**
+   * The cached response, or null if the cache doesn't exist or cannot be used
+   * for this request. Conditional caching means this may be non-null even when
+   * the network request is non-null. Never modified by OkHttp.
+   */
+  private Response cacheResponse;
+
+  /**
+   * The user-visible response. This is derived from either the network
+   * response, cache response, or both. It is customized to support OkHttp
+   * features like compression and caching.
+   */
+  private Response userResponse;
+
+  private Sink requestBodyOut;
+  private BufferedSink bufferedRequestBody;
+  private final boolean callerWritesRequestBody;
+  private final boolean forWebSocket;
+
+  /** The cache request currently being populated from a network response. */
+  private CacheRequest storeRequest;
+  private CacheStrategy cacheStrategy;
+
+  /**
+   * @param request the HTTP request without a body. The body must be written via the engine's
+   *     request body stream.
+   * @param callerWritesRequestBody true for the {@code HttpURLConnection}-style interaction
+   *     model where control flow is returned to the calling application to write the request body
+   *     before the response body is readable.
+   */
+  public HttpEngine(OkHttpClient client, Request request, boolean bufferRequestBody,
+      boolean callerWritesRequestBody, boolean forWebSocket, StreamAllocation streamAllocation,
+      RetryableSink requestBodyOut, Response priorResponse) {
+    this.client = client;
+    this.userRequest = request;
+    this.bufferRequestBody = bufferRequestBody;
+    this.callerWritesRequestBody = callerWritesRequestBody;
+    this.forWebSocket = forWebSocket;
+    this.streamAllocation = streamAllocation != null
+        ? streamAllocation
+        : new StreamAllocation(client.getConnectionPool(), createAddress(client, request));
+    this.requestBodyOut = requestBodyOut;
+    this.priorResponse = priorResponse;
+  }
+
+  /**
+   * 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.
+   *
+   * @throws RequestException if there was a problem with request setup. Unrecoverable.
+   * @throws RouteException if the was a problem during connection via a specific route. Sometimes
+   *     recoverable. See {@link #recover(RouteException)}.
+   * @throws IOException if there was a problem while making a request. Sometimes recoverable. See
+   *     {@link #recover(IOException)}.
+   *
+   */
+  public void sendRequest() throws RequestException, RouteException, IOException {
+    if (cacheStrategy != null) return; // Already sent.
+    if (httpStream != null) throw new IllegalStateException();
+
+    Request request = networkRequest(userRequest);
+
+    InternalCache responseCache = Internal.instance.internalCache(client);
+    Response cacheCandidate = responseCache != null
+        ? responseCache.get(request)
+        : null;
+
+    long now = System.currentTimeMillis();
+    cacheStrategy = new CacheStrategy.Factory(now, request, cacheCandidate).get();
+    networkRequest = cacheStrategy.networkRequest;
+    cacheResponse = cacheStrategy.cacheResponse;
+
+    if (responseCache != null) {
+      responseCache.trackResponse(cacheStrategy);
+    }
+
+    if (cacheCandidate != null && cacheResponse == null) {
+      closeQuietly(cacheCandidate.body()); // The cache candidate wasn't applicable. Close it.
+    }
+
+    if (networkRequest != null) {
+      httpStream = connect();
+      httpStream.setHttpEngine(this);
+
+      // If the caller's control flow writes the request body, we need to create that stream
+      // immediately. And that means we need to immediately write the request headers, so we can
+      // start streaming the request body. (We may already have a request body if we're retrying a
+      // failed POST.)
+      if (callerWritesRequestBody && permitsRequestBody(networkRequest) && requestBodyOut == null) {
+        long contentLength = OkHeaders.contentLength(request);
+        if (bufferRequestBody) {
+          if (contentLength > Integer.MAX_VALUE) {
+            throw new IllegalStateException("Use setFixedLengthStreamingMode() or "
+                + "setChunkedStreamingMode() for requests larger than 2 GiB.");
+          }
+
+          if (contentLength != -1) {
+            // Buffer a request body of a known length.
+            httpStream.writeRequestHeaders(networkRequest);
+            requestBodyOut = new RetryableSink((int) contentLength);
+          } else {
+            // 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.
+            requestBodyOut = new RetryableSink();
+          }
+        } else {
+          httpStream.writeRequestHeaders(networkRequest);
+          requestBodyOut = httpStream.createRequestBody(networkRequest, contentLength);
+        }
+      }
+
+    } else {
+      if (cacheResponse != null) {
+        // We have a valid cached response. Promote it to the user response immediately.
+        this.userResponse = cacheResponse.newBuilder()
+            .request(userRequest)
+            .priorResponse(stripBody(priorResponse))
+            .cacheResponse(stripBody(cacheResponse))
+            .build();
+      } else {
+        // We're forbidden from using the network, and the cache is insufficient.
+        this.userResponse = new Response.Builder()
+            .request(userRequest)
+            .priorResponse(stripBody(priorResponse))
+            .protocol(Protocol.HTTP_1_1)
+            .code(504)
+            .message("Unsatisfiable Request (only-if-cached)")
+            .body(EMPTY_BODY)
+            .build();
+      }
+
+      userResponse = unzip(userResponse);
+    }
+  }
+
+  private HttpStream connect() throws RouteException, RequestException, IOException {
+    boolean doExtensiveHealthChecks = !networkRequest.method().equals("GET");
+    return streamAllocation.newStream(client.getConnectTimeout(),
+        client.getReadTimeout(), client.getWriteTimeout(),
+        client.getRetryOnConnectionFailure(), doExtensiveHealthChecks);
+  }
+
+  private static Response stripBody(Response response) {
+    return response != null && response.body() != null
+        ? response.newBuilder().body(null).build()
+        : response;
+  }
+
+
+  /**
+   * Called immediately before the transport transmits HTTP request headers.
+   * This is used to observe the sent time should the request be cached.
+   */
+  public void writingRequestHeaders() {
+    if (sentRequestMillis != -1) throw new IllegalStateException();
+    sentRequestMillis = System.currentTimeMillis();
+  }
+
+  boolean permitsRequestBody(Request request) {
+    return HttpMethod.permitsRequestBody(request.method());
+  }
+
+  /** Returns the request body or null if this request doesn't have a body. */
+  public Sink getRequestBody() {
+    if (cacheStrategy == null) throw new IllegalStateException();
+    return requestBodyOut;
+  }
+
+  public BufferedSink getBufferedRequestBody() {
+    BufferedSink result = bufferedRequestBody;
+    if (result != null) return result;
+    Sink requestBody = getRequestBody();
+    return requestBody != null
+        ? (bufferedRequestBody = Okio.buffer(requestBody))
+        : null;
+  }
+
+  public boolean hasResponse() {
+    return userResponse != null;
+  }
+
+  public Request getRequest() {
+    return userRequest;
+  }
+
+  /** Returns the engine's response. */
+  // TODO: the returned body will always be null.
+  public Response getResponse() {
+    if (userResponse == null) throw new IllegalStateException();
+    return userResponse;
+  }
+
+  public Connection getConnection() {
+    return streamAllocation.connection();
+  }
+
+  /**
+   * Attempt to recover from failure to connect via a route. Returns a new HTTP engine
+   * that should be used for the retry if there are other routes to try, or null if
+   * there are no more routes to try.
+   */
+  public HttpEngine recover(RouteException e) {
+    if (!streamAllocation.recover(e)) {
+      return null;
+    }
+
+    if (!client.getRetryOnConnectionFailure()) {
+      return null;
+    }
+
+    StreamAllocation streamAllocation = close();
+
+    // For failure recovery, use the same route selector with a new connection.
+    return new HttpEngine(client, userRequest, bufferRequestBody, callerWritesRequestBody,
+        forWebSocket, streamAllocation, (RetryableSink) requestBodyOut, priorResponse);
+  }
+
+  /**
+   * Report and attempt to recover from a failure to communicate with a server. Returns a new
+   * HTTP engine that should be used for the retry if {@code e} is recoverable, or null if
+   * the failure is permanent. Requests with a body can only be recovered if the
+   * body is buffered.
+   */
+  public HttpEngine recover(IOException e, Sink requestBodyOut) {
+    if (!streamAllocation.recover(e, requestBodyOut)) {
+      return null;
+    }
+
+    if (!client.getRetryOnConnectionFailure()) {
+      return null;
+    }
+
+    StreamAllocation streamAllocation = close();
+
+    // For failure recovery, use the same route selector with a new connection.
+    return new HttpEngine(client, userRequest, bufferRequestBody, callerWritesRequestBody,
+        forWebSocket, streamAllocation, (RetryableSink) requestBodyOut, priorResponse);
+  }
+
+  public HttpEngine recover(IOException e) {
+    return recover(e, requestBodyOut);
+  }
+
+  private void maybeCache() throws IOException {
+    InternalCache responseCache = Internal.instance.internalCache(client);
+    if (responseCache == null) return;
+
+    // Should we cache this response for this request?
+    if (!CacheStrategy.isCacheable(userResponse, networkRequest)) {
+      if (HttpMethod.invalidatesCache(networkRequest.method())) {
+        try {
+          responseCache.remove(networkRequest);
+        } catch (IOException ignored) {
+          // The cache cannot be written.
+        }
+      }
+      return;
+    }
+
+    // Offer this request to the cache.
+    storeRequest = responseCache.put(stripBody(userResponse));
+  }
+
+  /**
+   * Configure the socket connection to be either pooled or closed when it is
+   * either exhausted or closed. If it is unneeded when this is called, it will
+   * be released immediately.
+   */
+  public void releaseStreamAllocation() throws IOException {
+    streamAllocation.release();
+  }
+
+  /**
+   * Immediately closes the socket connection if it's currently held by this engine. Use this to
+   * interrupt an in-flight request from any thread. It's the caller's responsibility to close the
+   * request body and response body streams; otherwise resources may be leaked.
+   *
+   * <p>This method is safe to be called concurrently, but provides limited guarantees. If a
+   * transport layer connection has been established (such as a HTTP/2 stream) that is terminated.
+   * Otherwise if a socket connection is being established, that is terminated.
+   */
+  public void cancel() {
+    streamAllocation.cancel();
+  }
+
+  /**
+   * Release any resources held by this engine. Returns the stream allocation held by this engine,
+   * which itself must be used or released.
+   */
+  public StreamAllocation close() {
+    if (bufferedRequestBody != null) {
+      // This also closes the wrapped requestBodyOut.
+      closeQuietly(bufferedRequestBody);
+    } else if (requestBodyOut != null) {
+      closeQuietly(requestBodyOut);
+    }
+
+    if (userResponse != null) {
+      closeQuietly(userResponse.body());
+    } else {
+      // If this engine never achieved a response body, its stream allocation is dead.
+      streamAllocation.connectionFailed();
+    }
+
+    return streamAllocation;
+  }
+
+  /**
+   * Returns a new response that does gzip decompression on {@code response}, if transparent gzip
+   * was both offered by OkHttp and used by the origin server.
+   *
+   * <p>In addition to decompression, this will also strip the corresponding headers. We strip the
+   * Content-Encoding header to prevent the application from attempting to double decompress. We
+   * strip the Content-Length header because it is the length of the compressed content, but the
+   * application is only interested in the length of the uncompressed content.
+   *
+   * <p>This method should only be used for non-empty response bodies. Response codes like "304 Not
+   * Modified" can include "Content-Encoding: gzip" without a response body and we will crash if we
+   * attempt to decompress the zero-byte source.
+   */
+  private Response unzip(final Response response) throws IOException {
+    if (!transparentGzip || !"gzip".equalsIgnoreCase(userResponse.header("Content-Encoding"))) {
+      return response;
+    }
+
+    if (response.body() == null) {
+      return response;
+    }
+
+    GzipSource responseBody = new GzipSource(response.body().source());
+    Headers strippedHeaders = response.headers().newBuilder()
+        .removeAll("Content-Encoding")
+        .removeAll("Content-Length")
+        .build();
+    return response.newBuilder()
+        .headers(strippedHeaders)
+        .body(new RealResponseBody(strippedHeaders, Okio.buffer(responseBody)))
+        .build();
+  }
+
+  /**
+   * Returns true if the response must have a (possibly 0-length) body.
+   * See RFC 2616 section 4.3.
+   */
+  public static boolean hasBody(Response response) {
+    // HEAD requests never yield a body regardless of the response headers.
+    if (response.request().method().equals("HEAD")) {
+      return false;
+    }
+
+    int responseCode = response.code();
+    if ((responseCode < HTTP_CONTINUE || responseCode >= 200)
+        && responseCode != HTTP_NO_CONTENT
+        && responseCode != 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 (OkHeaders.contentLength(response) != -1
+        || "chunked".equalsIgnoreCase(response.header("Transfer-Encoding"))) {
+      return true;
+    }
+
+    return false;
+  }
+
+  /**
+   * Populates request 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 Request networkRequest(Request request) throws IOException {
+    Request.Builder result = request.newBuilder();
+
+    if (request.header("Host") == null) {
+      result.header("Host", Util.hostHeader(request.httpUrl(), false));
+    }
+
+    if (request.header("Connection") == null) {
+      result.header("Connection", "Keep-Alive");
+    }
+
+    if (request.header("Accept-Encoding") == null) {
+      transparentGzip = true;
+      result.header("Accept-Encoding", "gzip");
+    }
+
+    CookieHandler cookieHandler = client.getCookieHandler();
+    if (cookieHandler != null) {
+      // Capture the request headers added so far so that they can be offered to the CookieHandler.
+      // This is mostly to stay close to the RI; it is unlikely any of the headers above would
+      // affect cookie choice besides "Host".
+      Map<String, List<String>> headers = OkHeaders.toMultimap(result.build().headers(), null);
+
+      Map<String, List<String>> cookies = cookieHandler.get(request.uri(), headers);
+
+      // Add any new cookies to the request.
+      OkHeaders.addCookies(result, cookies);
+    }
+
+    if (request.header("User-Agent") == null) {
+      result.header("User-Agent", Version.userAgent());
+    }
+
+    return result.build();
+  }
+
+  /**
+   * Flushes the remaining request header and body, parses the HTTP response
+   * headers and starts reading the HTTP response body if it exists.
+   */
+  public void readResponse() throws IOException {
+    if (userResponse != null) {
+      return; // Already ready.
+    }
+    if (networkRequest == null && cacheResponse == null) {
+      throw new IllegalStateException("call sendRequest() first!");
+    }
+    if (networkRequest == null) {
+      return; // No network response to read.
+    }
+
+    Response networkResponse;
+
+    if (forWebSocket) {
+      httpStream.writeRequestHeaders(networkRequest);
+      networkResponse = readNetworkResponse();
+
+    } else if (!callerWritesRequestBody) {
+      networkResponse = new NetworkInterceptorChain(0, networkRequest).proceed(networkRequest);
+
+    } else {
+      // Emit the request body's buffer so that everything is in requestBodyOut.
+      if (bufferedRequestBody != null && bufferedRequestBody.buffer().size() > 0) {
+        bufferedRequestBody.emit();
+      }
+
+      // Emit the request headers if we haven't yet. We might have just learned the Content-Length.
+      if (sentRequestMillis == -1) {
+        if (OkHeaders.contentLength(networkRequest) == -1
+            && requestBodyOut instanceof RetryableSink) {
+          long contentLength = ((RetryableSink) requestBodyOut).contentLength();
+          networkRequest = networkRequest.newBuilder()
+              .header("Content-Length", Long.toString(contentLength))
+              .build();
+        }
+        httpStream.writeRequestHeaders(networkRequest);
+      }
+
+      // Write the request body to the socket.
+      if (requestBodyOut != null) {
+        if (bufferedRequestBody != null) {
+          // This also closes the wrapped requestBodyOut.
+          bufferedRequestBody.close();
+        } else {
+          requestBodyOut.close();
+        }
+        if (requestBodyOut instanceof RetryableSink) {
+          httpStream.writeRequestBody((RetryableSink) requestBodyOut);
+        }
+      }
+
+      networkResponse = readNetworkResponse();
+    }
+
+    receiveHeaders(networkResponse.headers());
+
+    // If we have a cache response too, then we're doing a conditional get.
+    if (cacheResponse != null) {
+      if (validate(cacheResponse, networkResponse)) {
+        userResponse = cacheResponse.newBuilder()
+            .request(userRequest)
+            .priorResponse(stripBody(priorResponse))
+            .headers(combine(cacheResponse.headers(), networkResponse.headers()))
+            .cacheResponse(stripBody(cacheResponse))
+            .networkResponse(stripBody(networkResponse))
+            .build();
+        networkResponse.body().close();
+        releaseStreamAllocation();
+
+        // Update the cache after combining headers but before stripping the
+        // Content-Encoding header (as performed by initContentStream()).
+        InternalCache responseCache = Internal.instance.internalCache(client);
+        responseCache.trackConditionalCacheHit();
+        responseCache.update(cacheResponse, stripBody(userResponse));
+        userResponse = unzip(userResponse);
+        return;
+      } else {
+        closeQuietly(cacheResponse.body());
+      }
+    }
+
+    userResponse = networkResponse.newBuilder()
+        .request(userRequest)
+        .priorResponse(stripBody(priorResponse))
+        .cacheResponse(stripBody(cacheResponse))
+        .networkResponse(stripBody(networkResponse))
+        .build();
+
+    if (hasBody(userResponse)) {
+      maybeCache();
+      userResponse = unzip(cacheWritingResponse(storeRequest, userResponse));
+    }
+  }
+
+  class NetworkInterceptorChain implements Interceptor.Chain {
+    private final int index;
+    private final Request request;
+    private int calls;
+
+    NetworkInterceptorChain(int index, Request request) {
+      this.index = index;
+      this.request = request;
+    }
+
+    @Override public Connection connection() {
+      return streamAllocation.connection();
+    }
+
+    @Override public Request request() {
+      return request;
+    }
+
+    @Override public Response proceed(Request request) throws IOException {
+      calls++;
+
+      if (index > 0) {
+        Interceptor caller = client.networkInterceptors().get(index - 1);
+        Address address = connection().getRoute().getAddress();
+
+        // Confirm that the interceptor uses the connection we've already prepared.
+        if (!request.httpUrl().host().equals(address.getUriHost())
+            || request.httpUrl().port() != address.getUriPort()) {
+          throw new IllegalStateException("network interceptor " + caller
+              + " must retain the same host and port");
+        }
+
+        // Confirm that this is the interceptor's first call to chain.proceed().
+        if (calls > 1) {
+          throw new IllegalStateException("network interceptor " + caller
+              + " must call proceed() exactly once");
+        }
+      }
+
+      if (index < client.networkInterceptors().size()) {
+        // There's another interceptor in the chain. Call that.
+        NetworkInterceptorChain chain = new NetworkInterceptorChain(index + 1, request);
+        Interceptor interceptor = client.networkInterceptors().get(index);
+        Response interceptedResponse = interceptor.intercept(chain);
+
+        // Confirm that the interceptor made the required call to chain.proceed().
+        if (chain.calls != 1) {
+          throw new IllegalStateException("network interceptor " + interceptor
+              + " must call proceed() exactly once");
+        }
+        if (interceptedResponse == null) {
+          throw new NullPointerException("network interceptor " + interceptor
+              + " returned null");
+        }
+
+        return interceptedResponse;
+      }
+
+      httpStream.writeRequestHeaders(request);
+
+      //Update the networkRequest with the possibly updated interceptor request.
+      networkRequest = request;
+
+      if (permitsRequestBody(request) && request.body() != null) {
+        Sink requestBodyOut = httpStream.createRequestBody(request, request.body().contentLength());
+        BufferedSink bufferedRequestBody = Okio.buffer(requestBodyOut);
+        request.body().writeTo(bufferedRequestBody);
+        bufferedRequestBody.close();
+      }
+
+      Response response = readNetworkResponse();
+
+      int code = response.code();
+      if ((code == 204 || code == 205) && response.body().contentLength() > 0) {
+        throw new ProtocolException(
+            "HTTP " + code + " had non-zero Content-Length: " + response.body().contentLength());
+      }
+
+      return response;
+    }
+  }
+
+  private Response readNetworkResponse() throws IOException {
+    httpStream.finishRequest();
+
+    Response networkResponse = httpStream.readResponseHeaders()
+        .request(networkRequest)
+        .handshake(streamAllocation.connection().getHandshake())
+        .header(OkHeaders.SENT_MILLIS, Long.toString(sentRequestMillis))
+        .header(OkHeaders.RECEIVED_MILLIS, Long.toString(System.currentTimeMillis()))
+        .build();
+
+    if (!forWebSocket) {
+      networkResponse = networkResponse.newBuilder()
+          .body(httpStream.openResponseBody(networkResponse))
+          .build();
+    }
+
+    if ("close".equalsIgnoreCase(networkResponse.request().header("Connection"))
+        || "close".equalsIgnoreCase(networkResponse.header("Connection"))) {
+      streamAllocation.noNewStreams();
+    }
+
+    return networkResponse;
+  }
+
+  /**
+   * Returns a new source that writes bytes to {@code cacheRequest} as they are read by the source
+   * consumer. This is careful to discard bytes left over when the stream is closed; otherwise we
+   * may never exhaust the source stream and therefore not complete the cached response.
+   */
+  private Response cacheWritingResponse(final CacheRequest cacheRequest, Response response)
+      throws IOException {
+    // Some apps return a null body; for compatibility we treat that like a null cache request.
+    if (cacheRequest == null) return response;
+    Sink cacheBodyUnbuffered = cacheRequest.body();
+    if (cacheBodyUnbuffered == null) return response;
+
+    final BufferedSource source = response.body().source();
+    final BufferedSink cacheBody = Okio.buffer(cacheBodyUnbuffered);
+
+    Source cacheWritingSource = new Source() {
+      boolean cacheRequestClosed;
+
+      @Override public long read(Buffer sink, long byteCount) throws IOException {
+        long bytesRead;
+        try {
+          bytesRead = source.read(sink, byteCount);
+        } catch (IOException e) {
+          if (!cacheRequestClosed) {
+            cacheRequestClosed = true;
+            cacheRequest.abort(); // Failed to write a complete cache response.
+          }
+          throw e;
+        }
+
+        if (bytesRead == -1) {
+          if (!cacheRequestClosed) {
+            cacheRequestClosed = true;
+            cacheBody.close(); // The cache response is complete!
+          }
+          return -1;
+        }
+
+        sink.copyTo(cacheBody.buffer(), sink.size() - bytesRead, bytesRead);
+        cacheBody.emitCompleteSegments();
+        return bytesRead;
+      }
+
+      @Override public Timeout timeout() {
+        return source.timeout();
+      }
+
+      @Override public void close() throws IOException {
+        if (!cacheRequestClosed
+            && !Util.discard(this, HttpStream.DISCARD_STREAM_TIMEOUT_MILLIS, MILLISECONDS)) {
+          cacheRequestClosed = true;
+          cacheRequest.abort();
+        }
+        source.close();
+      }
+    };
+
+    return response.newBuilder()
+        .body(new RealResponseBody(response.headers(), Okio.buffer(cacheWritingSource)))
+        .build();
+  }
+
+  /**
+   * Returns true if {@code cached} should be used; false if {@code network}
+   * response should be used.
+   */
+  private static boolean validate(Response cached, Response network) {
+    if (network.code() == 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.
+    Date lastModified = cached.headers().getDate("Last-Modified");
+    if (lastModified != null) {
+      Date networkLastModified = network.headers().getDate("Last-Modified");
+      if (networkLastModified != null
+          && networkLastModified.getTime() < lastModified.getTime()) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Combines cached headers with a network headers as defined by RFC 2616,
+   * 13.5.3.
+   */
+  private static Headers combine(Headers cachedHeaders, Headers networkHeaders) throws IOException {
+    Headers.Builder result = new Headers.Builder();
+
+    for (int i = 0, size = cachedHeaders.size(); i < size; i++) {
+      String fieldName = cachedHeaders.name(i);
+      String value = cachedHeaders.value(i);
+      if ("Warning".equalsIgnoreCase(fieldName) && value.startsWith("1")) {
+        continue; // Drop 100-level freshness warnings.
+      }
+      if (!OkHeaders.isEndToEnd(fieldName) || networkHeaders.get(fieldName) == null) {
+        result.add(fieldName, value);
+      }
+    }
+
+    for (int i = 0, size = networkHeaders.size(); i < size; i++) {
+      String fieldName = networkHeaders.name(i);
+      if ("Content-Length".equalsIgnoreCase(fieldName)) {
+        continue; // Ignore content-length headers of validating responses.
+      }
+      if (OkHeaders.isEndToEnd(fieldName)) {
+        result.add(fieldName, networkHeaders.value(i));
+      }
+    }
+
+    return result.build();
+  }
+
+  public void receiveHeaders(Headers headers) throws IOException {
+    CookieHandler cookieHandler = client.getCookieHandler();
+    if (cookieHandler != null) {
+      cookieHandler.put(userRequest.uri(), OkHeaders.toMultimap(headers, null));
+    }
+  }
+
+  /**
+   * Figures out the HTTP request to make in response to receiving this engine's
+   * response. This will either add authentication headers or follow redirects.
+   * If a follow-up is either unnecessary or not applicable, this returns null.
+   */
+  public Request followUpRequest() throws IOException {
+    if (userResponse == null) throw new IllegalStateException();
+    Connection connection = streamAllocation.connection();
+    Route route = connection != null
+        ? connection.getRoute()
+        : null;
+    Proxy selectedProxy = route != null
+        ? route.getProxy()
+        : client.getProxy();
+    int responseCode = userResponse.code();
+
+    final String method = userRequest.method();
+    switch (responseCode) {
+      case HTTP_PROXY_AUTH:
+        if (selectedProxy.type() != Proxy.Type.HTTP) {
+          throw new ProtocolException("Received HTTP_PROXY_AUTH (407) code while not using proxy");
+        }
+        // fall-through
+      case HTTP_UNAUTHORIZED:
+        return OkHeaders.processAuthHeader(client.getAuthenticator(), userResponse, selectedProxy);
+
+      case HTTP_PERM_REDIRECT:
+      case HTTP_TEMP_REDIRECT:
+        // "If the 307 or 308 status code is received in response to a request other than GET
+        // or HEAD, the user agent MUST NOT automatically redirect the request"
+        if (!method.equals("GET") && !method.equals("HEAD")) {
+            return null;
+        }
+        // fall-through
+      case HTTP_MULT_CHOICE:
+      case HTTP_MOVED_PERM:
+      case HTTP_MOVED_TEMP:
+      case HTTP_SEE_OTHER:
+        // Does the client allow redirects?
+        if (!client.getFollowRedirects()) return null;
+
+        String location = userResponse.header("Location");
+        if (location == null) return null;
+        HttpUrl url = userRequest.httpUrl().resolve(location);
+
+        // Don't follow redirects to unsupported protocols.
+        if (url == null) return null;
+
+        // If configured, don't follow redirects between SSL and non-SSL.
+        boolean sameScheme = url.scheme().equals(userRequest.httpUrl().scheme());
+        if (!sameScheme && !client.getFollowSslRedirects()) return null;
+
+        // Redirects don't include a request body.
+        Request.Builder requestBuilder = userRequest.newBuilder();
+        if (HttpMethod.permitsRequestBody(method)) {
+          if (HttpMethod.redirectsToGet(method)) {
+            requestBuilder.method("GET", null);
+          } else {
+            requestBuilder.method(method, null);
+          }
+          requestBuilder.removeHeader("Transfer-Encoding");
+          requestBuilder.removeHeader("Content-Length");
+          requestBuilder.removeHeader("Content-Type");
+        }
+
+        // When redirecting across hosts, drop all authentication headers. This
+        // is potentially annoying to the application layer since they have no
+        // way to retain them.
+        if (!sameConnection(url)) {
+          requestBuilder.removeHeader("Authorization");
+        }
+
+        return requestBuilder.url(url).build();
+
+      default:
+        return null;
+    }
+  }
+
+  /**
+   * Returns true if an HTTP request for {@code followUp} can reuse the
+   * connection used by this engine.
+   */
+  public boolean sameConnection(HttpUrl followUp) {
+    HttpUrl url = userRequest.httpUrl();
+    return url.host().equals(followUp.host())
+        && url.port() == followUp.port()
+        && url.scheme().equals(followUp.scheme());
+  }
+
+  private static Address createAddress(OkHttpClient client, Request request) {
+    SSLSocketFactory sslSocketFactory = null;
+    HostnameVerifier hostnameVerifier = null;
+    CertificatePinner certificatePinner = null;
+    if (request.isHttps()) {
+      sslSocketFactory = client.getSslSocketFactory();
+      hostnameVerifier = client.getHostnameVerifier();
+      certificatePinner = client.getCertificatePinner();
+    }
+
+    return new Address(request.httpUrl().host(), request.httpUrl().port(), client.getDns(),
+        client.getSocketFactory(), sslSocketFactory, hostnameVerifier, certificatePinner,
+        client.getAuthenticator(), client.getProxy(), client.getProtocols(),
+        client.getConnectionSpecs(), client.getProxySelector());
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/HttpMethod.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/HttpMethod.java
new file mode 100644
index 0000000..5bd7b48
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/HttpMethod.java
@@ -0,0 +1,55 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.internal.http;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class HttpMethod {
+  public static boolean invalidatesCache(String method) {
+    return method.equals("POST")
+        || method.equals("PATCH")
+        || method.equals("PUT")
+        || method.equals("DELETE")
+        || method.equals("MOVE");     // WebDAV
+  }
+
+  public static boolean requiresRequestBody(String method) {
+    return method.equals("POST")
+        || method.equals("PUT")
+        || method.equals("PATCH")
+        || method.equals("PROPPATCH") // WebDAV
+        || method.equals("REPORT");   // CalDAV/CardDAV (defined in WebDAV Versioning)
+  }
+
+  public static boolean permitsRequestBody(String method) {
+    return requiresRequestBody(method)
+        || method.equals("OPTIONS")
+        || method.equals("DELETE")    // Permitted as spec is ambiguous.
+        || method.equals("PROPFIND")  // (WebDAV) without body: request <allprop/>
+        || method.equals("MKCOL")     // (WebDAV) may contain a body, but behaviour is unspecified
+        || method.equals("LOCK");     // (WebDAV) body: create lock, without body: refresh lock
+  }
+
+  public static boolean redirectsToGet(String method) {
+    // All requests but PROPFIND should redirect to a GET request.
+    return !method.equals("PROPFIND");
+  }
+
+  private HttpMethod() {
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/HttpStream.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/HttpStream.java
new file mode 100644
index 0000000..ccc026d
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/HttpStream.java
@@ -0,0 +1,65 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.okhttp.internal.http;
+
+import com.android.okhttp.Request;
+import com.android.okhttp.Response;
+import com.android.okhttp.ResponseBody;
+import java.io.IOException;
+import com.android.okhttp.okio.Sink;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface HttpStream {
+  /**
+   * The timeout to use while discarding a stream of input data. Since this is
+   * used for connection reuse, this timeout should be significantly less than
+   * the time it takes to establish a new connection.
+   */
+  int DISCARD_STREAM_TIMEOUT_MILLIS = 100;
+
+  /** Returns an output stream where the request body can be streamed. */
+  Sink createRequestBody(Request request, long contentLength) throws IOException;
+
+  /** This should update the HTTP engine's sentRequestMillis field. */
+  void writeRequestHeaders(Request request) throws IOException;
+
+  /**
+   * Sends the request body returned by {@link #createRequestBody} to the
+   * remote peer.
+   */
+  void writeRequestBody(RetryableSink requestBody) throws IOException;
+
+  /** Flush the request to the underlying socket. */
+  void finishRequest() throws IOException;
+
+  /** Read and return response headers. */
+  Response.Builder readResponseHeaders() throws IOException;
+
+  /** Returns a stream that reads the response body. */
+  ResponseBody openResponseBody(Response response) throws IOException;
+
+  void setHttpEngine(HttpEngine httpEngine);
+
+  /**
+   * Cancel this stream. Resources held by this stream will be cleaned up, though not synchronously.
+   * That may happen later by the connection pool thread.
+   */
+  void cancel();
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/OkHeaders.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/OkHeaders.java
new file mode 100644
index 0000000..f192dcb
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/OkHeaders.java
@@ -0,0 +1,292 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.okhttp.internal.http;
+
+import com.android.okhttp.Authenticator;
+import com.android.okhttp.Challenge;
+import com.android.okhttp.Headers;
+import com.android.okhttp.Request;
+import com.android.okhttp.Response;
+import com.android.okhttp.internal.Platform;
+import java.io.IOException;
+import java.net.Proxy;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import static com.android.okhttp.internal.Util.equal;
+import static java.net.HttpURLConnection.HTTP_PROXY_AUTH;
+
+/** Headers and utilities for internal use by OkHttp. 
+ * @hide This class is not part of the Android public SDK API*/
+public final class OkHeaders {
+  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);
+      }
+    }
+  };
+
+  static final String PREFIX = Platform.get().getPrefix();
+
+  /**
+   * Synthetic response header: the local time when the request was sent.
+   */
+  public static final String SENT_MILLIS = PREFIX + "-Sent-Millis";
+
+  /**
+   * Synthetic response header: the local time when the response was received.
+   */
+  public static final String RECEIVED_MILLIS = PREFIX + "-Received-Millis";
+
+  /**
+   * Synthetic response header: the selected
+   * {@link com.android.okhttp.Protocol protocol} ("spdy/3.1", "http/1.1", etc).
+   */
+  public static final String SELECTED_PROTOCOL = PREFIX + "-Selected-Protocol";
+
+  /** Synthetic response header: the location from which the response was loaded. */
+  public static final String RESPONSE_SOURCE = PREFIX + "-Response-Source";
+
+  private OkHeaders() {
+  }
+
+  public static long contentLength(Request request) {
+    return contentLength(request.headers());
+  }
+
+  public static long contentLength(Response response) {
+    return contentLength(response.headers());
+  }
+
+  public static long contentLength(Headers headers) {
+    return stringToLong(headers.get("Content-Length"));
+  }
+
+  private static long stringToLong(String s) {
+    if (s == null) return -1;
+    try {
+      return Long.parseLong(s);
+    } catch (NumberFormatException e) {
+      return -1;
+    }
+  }
+
+  /**
+   * Returns an immutable map containing each field to its list of values.
+   *
+   * @param valueForNullKey the request line for requests, or the status line
+   *     for responses. If non-null, this value is mapped to the null key.
+   */
+  public static Map<String, List<String>> toMultimap(Headers headers, String valueForNullKey) {
+    Map<String, List<String>> result = new TreeMap<>(FIELD_NAME_COMPARATOR);
+    for (int i = 0, size = headers.size(); i < size; i++) {
+      String fieldName = headers.name(i);
+      String value = headers.value(i);
+
+      List<String> allValues = new ArrayList<>();
+      List<String> otherValues = result.get(fieldName);
+      if (otherValues != null) {
+        allValues.addAll(otherValues);
+      }
+      allValues.add(value);
+      result.put(fieldName, Collections.unmodifiableList(allValues));
+    }
+    if (valueForNullKey != null) {
+      result.put(null, Collections.unmodifiableList(Collections.singletonList(valueForNullKey)));
+    }
+    return Collections.unmodifiableMap(result);
+  }
+
+  public static void addCookies(Request.Builder builder, Map<String, List<String>> cookieHeaders) {
+    for (Map.Entry<String, List<String>> entry : cookieHeaders.entrySet()) {
+      String key = entry.getKey();
+      if (("Cookie".equalsIgnoreCase(key) || "Cookie2".equalsIgnoreCase(key))
+          && !entry.getValue().isEmpty()) {
+        builder.addHeader(key, buildCookieHeader(entry.getValue()));
+      }
+    }
+  }
+
+  /**
+   * Send all cookies in one big header, as recommended by
+   * <a href="http://tools.ietf.org/html/rfc6265#section-4.2.1">RFC 6265</a>.
+   */
+  private static String buildCookieHeader(List<String> cookies) {
+    if (cookies.size() == 1) return cookies.get(0);
+    StringBuilder sb = new StringBuilder();
+    for (int i = 0, size = cookies.size(); i < size; i++) {
+      if (i > 0) sb.append("; ");
+      sb.append(cookies.get(i));
+    }
+    return sb.toString();
+  }
+
+  /**
+   * Returns true if none of the Vary headers have changed between {@code
+   * cachedRequest} and {@code newRequest}.
+   */
+  public static boolean varyMatches(
+      Response cachedResponse, Headers cachedRequest, Request newRequest) {
+    for (String field : varyFields(cachedResponse)) {
+      if (!equal(cachedRequest.values(field), newRequest.headers(field))) return false;
+    }
+    return true;
+  }
+
+  /**
+   * Returns true if a Vary header contains an asterisk. Such responses cannot
+   * be cached.
+   */
+  public static boolean hasVaryAll(Response response) {
+    return hasVaryAll(response.headers());
+  }
+
+  /**
+   * Returns true if a Vary header contains an asterisk. Such responses cannot
+   * be cached.
+   */
+  public static boolean hasVaryAll(Headers responseHeaders) {
+    return varyFields(responseHeaders).contains("*");
+  }
+
+  private static Set<String> varyFields(Response response) {
+    return varyFields(response.headers());
+  }
+
+  /**
+   * Returns the names of the request headers that need to be checked for
+   * equality when caching.
+   */
+  public static Set<String> varyFields(Headers responseHeaders) {
+    Set<String> result = Collections.emptySet();
+    for (int i = 0, size = responseHeaders.size(); i < size; i++) {
+      if (!"Vary".equalsIgnoreCase(responseHeaders.name(i))) continue;
+
+      String value = responseHeaders.value(i);
+      if (result.isEmpty()) {
+        result = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+      }
+      for (String varyField : value.split(",")) {
+        result.add(varyField.trim());
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Returns the subset of the headers in {@code response}'s request that
+   * impact the content of response's body.
+   */
+  public static Headers varyHeaders(Response response) {
+    // Use the request headers sent over the network, since that's what the
+    // response varies on. Otherwise OkHttp-supplied headers like
+    // "Accept-Encoding: gzip" may be lost.
+    Headers requestHeaders = response.networkResponse().request().headers();
+    Headers responseHeaders = response.headers();
+    return varyHeaders(requestHeaders, responseHeaders);
+  }
+
+  /**
+   * Returns the subset of the headers in {@code requestHeaders} that
+   * impact the content of response's body.
+   */
+  public static Headers varyHeaders(Headers requestHeaders, Headers responseHeaders) {
+    Set<String> varyFields = varyFields(responseHeaders);
+    if (varyFields.isEmpty()) return new Headers.Builder().build();
+
+    Headers.Builder result = new Headers.Builder();
+    for (int i = 0, size = requestHeaders.size(); i < size; i++) {
+      String fieldName = requestHeaders.name(i);
+      if (varyFields.contains(fieldName)) {
+        result.add(fieldName, requestHeaders.value(i));
+      }
+    }
+    return result.build();
+  }
+
+  /**
+   * Returns true if {@code fieldName} is an end-to-end HTTP header, as
+   * defined by RFC 2616, 13.5.1.
+   */
+  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);
+  }
+
+  /**
+   * Parse RFC 2617 challenges. This API is only interested in the scheme
+   * name and realm.
+   */
+  public static List<Challenge> parseChallenges(Headers 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<>();
+    for (int i = 0, size = responseHeaders.size(); i < size; i++) {
+      if (!challengeHeader.equalsIgnoreCase(responseHeaders.name(i))) {
+        continue;
+      }
+      String value = responseHeaders.value(i);
+      int pos = 0;
+      while (pos < value.length()) {
+        int tokenStart = pos;
+        pos = HeaderParser.skipUntil(value, pos, " ");
+
+        String scheme = value.substring(tokenStart, pos).trim();
+        pos = HeaderParser.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(true, pos, "realm=\"", 0, "realm=\"".length())) {
+          break; // Unexpected challenge parameter; give up!
+        }
+
+        pos += "realm=\"".length();
+        int realmStart = pos;
+        pos = HeaderParser.skipUntil(value, pos, "\"");
+        String realm = value.substring(realmStart, pos);
+        pos++; // Consume '"' close quote.
+        pos = HeaderParser.skipUntil(value, pos, ",");
+        pos++; // Consume ',' comma.
+        pos = HeaderParser.skipWhitespace(value, pos);
+        result.add(new Challenge(scheme, realm));
+      }
+    }
+    return result;
+  }
+
+  /**
+   * React to a failed authorization response by looking up new credentials.
+   * Returns a request for a subsequent attempt, or null if no further attempts
+   * should be made.
+   */
+  public static Request processAuthHeader(Authenticator authenticator, Response response,
+      Proxy proxy) throws IOException {
+    return response.code() == HTTP_PROXY_AUTH
+        ? authenticator.authenticateProxy(proxy, response)
+        : authenticator.authenticate(proxy, response);
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/RealResponseBody.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/RealResponseBody.java
new file mode 100644
index 0000000..5bd4840
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/RealResponseBody.java
@@ -0,0 +1,48 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.internal.http;
+
+import com.android.okhttp.Headers;
+import com.android.okhttp.MediaType;
+import com.android.okhttp.ResponseBody;
+import com.android.okhttp.okio.BufferedSource;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class RealResponseBody extends ResponseBody {
+  private final Headers headers;
+  private final BufferedSource source;
+
+  public RealResponseBody(Headers headers, BufferedSource source) {
+    this.headers = headers;
+    this.source = source;
+  }
+
+  @Override public MediaType contentType() {
+    String contentType = headers.get("Content-Type");
+    return contentType != null ? MediaType.parse(contentType) : null;
+  }
+
+  @Override public long contentLength() {
+    return OkHeaders.contentLength(headers);
+  }
+
+  @Override public BufferedSource source() {
+    return source;
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/RequestException.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/RequestException.java
new file mode 100644
index 0000000..729b8d5
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/RequestException.java
@@ -0,0 +1,36 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.okhttp.internal.http;
+
+import java.io.IOException;
+
+/**
+ * Indicates a problem with interpreting a request. It may indicate there was a problem with the
+ * request itself, or the environment being used to interpret the request (network failure, etc.).
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class RequestException extends Exception {
+
+  public RequestException(IOException cause) {
+    super(cause);
+  }
+
+  @Override
+  public IOException getCause() {
+    return (IOException) super.getCause();
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/RequestLine.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/RequestLine.java
new file mode 100644
index 0000000..fcfda0b
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/RequestLine.java
@@ -0,0 +1,54 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.okhttp.internal.http;
+
+import com.android.okhttp.HttpUrl;
+import com.android.okhttp.Request;
+import java.net.HttpURLConnection;
+import java.net.Proxy;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class RequestLine {
+  private RequestLine() {
+  }
+
+  /**
+   * Returns the request status line, like "GET / HTTP/1.1". This is exposed
+   * to the application by {@link HttpURLConnection#getHeaderFields}, so it
+   * needs to be set even if the transport is SPDY.
+   */
+  static String get(Request request, Proxy.Type proxyType) {
+    StringBuilder result = new StringBuilder();
+    result.append(request.method());
+    result.append(' ');
+
+    if (includeAuthorityInRequestLine(request, proxyType)) {
+      result.append(request.httpUrl());
+    } else {
+      result.append(requestPath(request.httpUrl()));
+    }
+
+    result.append(" HTTP/1.1");
+    return result.toString();
+  }
+
+  /**
+   * 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").
+   */
+  private static boolean includeAuthorityInRequestLine(Request request, Proxy.Type proxyType) {
+    return !request.isHttps() && proxyType == Proxy.Type.HTTP;
+  }
+
+  /**
+   * Returns the path to request, like the '/' in 'GET / HTTP/1.1'. Never empty,
+   * even if the request URL is. Includes the query component if it exists.
+   */
+  public static String requestPath(HttpUrl url) {
+    String path = url.encodedPath();
+    String query = url.encodedQuery();
+    return query != null ? (path + '?' + query) : path;
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/RetryableSink.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/RetryableSink.java
new file mode 100644
index 0000000..2891079
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/RetryableSink.java
@@ -0,0 +1,82 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.okhttp.internal.http;
+
+import java.io.IOException;
+import java.net.ProtocolException;
+import com.android.okhttp.okio.Buffer;
+import com.android.okhttp.okio.Sink;
+import com.android.okhttp.okio.Timeout;
+
+import static com.android.okhttp.internal.Util.checkOffsetAndCount;
+
+/**
+ * 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.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class RetryableSink implements Sink {
+  private boolean closed;
+  private final int limit;
+  private final Buffer content = new Buffer();
+
+  public RetryableSink(int limit) {
+    this.limit = limit;
+  }
+
+  public RetryableSink() {
+    this(-1);
+  }
+
+  @Override public void close() throws IOException {
+    if (closed) return;
+    closed = true;
+    if (content.size() < limit) {
+      throw new ProtocolException(
+          "content-length promised " + limit + " bytes, but received " + content.size());
+    }
+  }
+
+  @Override public void write(Buffer source, long byteCount) throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    checkOffsetAndCount(source.size(), 0, byteCount);
+    if (limit != -1 && content.size() > limit - byteCount) {
+      throw new ProtocolException("exceeded content-length limit of " + limit + " bytes");
+    }
+    content.write(source, byteCount);
+  }
+
+  @Override public void flush() throws IOException {
+  }
+
+  @Override public Timeout timeout() {
+    return Timeout.NONE;
+  }
+
+  public long contentLength() throws IOException {
+    return content.size();
+  }
+
+  public void writeToSocket(Sink socketOut) throws IOException {
+    // Copy the content; otherwise we won't have data to retry.
+    Buffer buffer = new Buffer();
+    content.copyTo(buffer, 0, content.size());
+    socketOut.write(buffer, buffer.size());
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/RouteException.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/RouteException.java
new file mode 100644
index 0000000..72ed5de
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/RouteException.java
@@ -0,0 +1,63 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.okhttp.internal.http;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * An exception thrown to indicate a problem connecting via a single Route. Multiple attempts may
+ * have been made with alternative protocols, none of which were successful.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class RouteException extends Exception {
+  private static final Method addSuppressedExceptionMethod;
+  static {
+    Method m;
+    try {
+      m = Throwable.class.getDeclaredMethod("addSuppressed", Throwable.class);
+    } catch (Exception e) {
+      m = null;
+    }
+    addSuppressedExceptionMethod = m;
+  }
+  private IOException lastException;
+
+  public RouteException(IOException cause) {
+    super(cause);
+    lastException = cause;
+  }
+
+  public IOException getLastConnectException() {
+    return lastException;
+  }
+
+  public void addConnectException(IOException e) {
+    addSuppressedIfPossible(e, lastException);
+    lastException = e;
+  }
+
+  private void addSuppressedIfPossible(IOException e, IOException suppressed) {
+    if (addSuppressedExceptionMethod != null) {
+      try {
+        addSuppressedExceptionMethod.invoke(e, suppressed);
+      } catch (InvocationTargetException | IllegalAccessException ignored) {
+      }
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/RouteSelector.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/RouteSelector.java
new file mode 100644
index 0000000..75ecf64
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/RouteSelector.java
@@ -0,0 +1,228 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * 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 com.android.okhttp.internal.http;
+
+import com.android.okhttp.Address;
+import com.android.okhttp.HttpUrl;
+import com.android.okhttp.Route;
+import com.android.okhttp.internal.RouteDatabase;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+/**
+ * Selects routes to connect to an origin server. Each connection requires a
+ * choice of proxy server, IP address, and TLS mode. Connections may also be
+ * recycled.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class RouteSelector {
+  private final Address address;
+  private final RouteDatabase routeDatabase;
+
+  /* The most recently attempted route. */
+  private Proxy lastProxy;
+  private InetSocketAddress lastInetSocketAddress;
+
+  /* State for negotiating the next proxy to use. */
+  private List<Proxy> proxies = Collections.emptyList();
+  private int nextProxyIndex;
+
+  /* State for negotiating the next socket address to use. */
+  private List<InetSocketAddress> inetSocketAddresses = Collections.emptyList();
+  private int nextInetSocketAddressIndex;
+
+  /* State for negotiating failed routes */
+  private final List<Route> postponedRoutes = new ArrayList<>();
+
+  public RouteSelector(Address address, RouteDatabase routeDatabase) {
+    this.address = address;
+    this.routeDatabase = routeDatabase;
+
+    resetNextProxy(address.url(), address.getProxy());
+  }
+
+  /**
+   * Returns true if there's another route to attempt. Every address has at
+   * least one route.
+   */
+  public boolean hasNext() {
+    return hasNextInetSocketAddress()
+        || hasNextProxy()
+        || hasNextPostponed();
+  }
+
+  public Route next() throws IOException {
+    // Compute the next route to attempt.
+    if (!hasNextInetSocketAddress()) {
+      if (!hasNextProxy()) {
+        if (!hasNextPostponed()) {
+          throw new NoSuchElementException();
+        }
+        return nextPostponed();
+      }
+      lastProxy = nextProxy();
+    }
+    lastInetSocketAddress = nextInetSocketAddress();
+
+    Route route = new Route(address, lastProxy, lastInetSocketAddress);
+    if (routeDatabase.shouldPostpone(route)) {
+      postponedRoutes.add(route);
+      // We will only recurse in order to skip previously failed routes. They will be tried last.
+      return next();
+    }
+
+    return route;
+  }
+
+  /**
+   * Clients should invoke this method when they encounter a connectivity
+   * failure on a connection returned by this route selector.
+   */
+  public void connectFailed(Route failedRoute, IOException failure) {
+    if (failedRoute.getProxy().type() != Proxy.Type.DIRECT && address.getProxySelector() != null) {
+      // Tell the proxy selector when we fail to connect on a fresh connection.
+      address.getProxySelector().connectFailed(
+          address.url().uri(), failedRoute.getProxy().address(), failure);
+    }
+
+    routeDatabase.failed(failedRoute);
+  }
+
+  /** Prepares the proxy servers to try. */
+  private void resetNextProxy(HttpUrl url, Proxy proxy) {
+    if (proxy != null) {
+      // If the user specifies a proxy, try that and only that.
+      proxies = Collections.singletonList(proxy);
+    } else {
+      // Try each of the ProxySelector choices until one connection succeeds. If none succeed
+      // then we'll try a direct connection below.
+      proxies = new ArrayList<>();
+      List<Proxy> selectedProxies = address.getProxySelector().select(url.uri());
+      if (selectedProxies != null) proxies.addAll(selectedProxies);
+      // Finally try a direct connection. We only try it once!
+      proxies.removeAll(Collections.singleton(Proxy.NO_PROXY));
+      proxies.add(Proxy.NO_PROXY);
+    }
+    nextProxyIndex = 0;
+  }
+
+  /** Returns true if there's another proxy to try. */
+  private boolean hasNextProxy() {
+    return nextProxyIndex < proxies.size();
+  }
+
+  /** Returns the next proxy to try. May be PROXY.NO_PROXY but never null. */
+  private Proxy nextProxy() throws IOException {
+    if (!hasNextProxy()) {
+      throw new SocketException("No route to " + address.getUriHost()
+          + "; exhausted proxy configurations: " + proxies);
+    }
+    Proxy result = proxies.get(nextProxyIndex++);
+    resetNextInetSocketAddress(result);
+    return result;
+  }
+
+  /** Prepares the socket addresses to attempt for the current proxy or host. */
+  private void resetNextInetSocketAddress(Proxy proxy) throws IOException {
+    // Clear the addresses. Necessary if getAllByName() below throws!
+    inetSocketAddresses = new ArrayList<>();
+
+    String socketHost;
+    int socketPort;
+    if (proxy.type() == Proxy.Type.DIRECT || proxy.type() == Proxy.Type.SOCKS) {
+      socketHost = address.getUriHost();
+      socketPort = address.getUriPort();
+    } else {
+      SocketAddress proxyAddress = proxy.address();
+      if (!(proxyAddress instanceof InetSocketAddress)) {
+        throw new IllegalArgumentException(
+            "Proxy.address() is not an " + "InetSocketAddress: " + proxyAddress.getClass());
+      }
+      InetSocketAddress proxySocketAddress = (InetSocketAddress) proxyAddress;
+      socketHost = getHostString(proxySocketAddress);
+      socketPort = proxySocketAddress.getPort();
+    }
+
+    if (socketPort < 1 || socketPort > 65535) {
+      throw new SocketException("No route to " + socketHost + ":" + socketPort
+          + "; port is out of range");
+    }
+
+    if (proxy.type() == Proxy.Type.SOCKS) {
+      inetSocketAddresses.add(InetSocketAddress.createUnresolved(socketHost, socketPort));
+    } else {
+      // Try each address for best behavior in mixed IPv4/IPv6 environments.
+      List<InetAddress> addresses = address.getDns().lookup(socketHost);
+      for (int i = 0, size = addresses.size(); i < size; i++) {
+        InetAddress inetAddress = addresses.get(i);
+        inetSocketAddresses.add(new InetSocketAddress(inetAddress, socketPort));
+      }
+    }
+
+    nextInetSocketAddressIndex = 0;
+  }
+
+  /**
+   * Obtain a "host" from an {@link InetSocketAddress}. This returns a string containing either an
+   * actual host name or a numeric IP address.
+   */
+  // Visible for testing
+  static String getHostString(InetSocketAddress socketAddress) {
+    InetAddress address = socketAddress.getAddress();
+    if (address == null) {
+      // The InetSocketAddress was specified with a string (either a numeric IP or a host name). If
+      // it is a name, all IPs for that name should be tried. If it is an IP address, only that IP
+      // address should be tried.
+      return socketAddress.getHostName();
+    }
+    // The InetSocketAddress has a specific address: we should only try that address. Therefore we
+    // return the address and ignore any host name that may be available.
+    return address.getHostAddress();
+  }
+
+  /** Returns true if there's another socket address to try. */
+  private boolean hasNextInetSocketAddress() {
+    return nextInetSocketAddressIndex < inetSocketAddresses.size();
+  }
+
+  /** Returns the next socket address to try. */
+  private InetSocketAddress nextInetSocketAddress() throws IOException {
+    if (!hasNextInetSocketAddress()) {
+      throw new SocketException("No route to " + address.getUriHost()
+          + "; exhausted inet socket addresses: " + inetSocketAddresses);
+    }
+    return inetSocketAddresses.get(nextInetSocketAddressIndex++);
+  }
+
+  /** Returns true if there is another postponed route to try. */
+  private boolean hasNextPostponed() {
+    return !postponedRoutes.isEmpty();
+  }
+
+  /** Returns the next postponed route to try. */
+  private Route nextPostponed() {
+    return postponedRoutes.remove(0);
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/StatusLine.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/StatusLine.java
new file mode 100644
index 0000000..45b52c3
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/StatusLine.java
@@ -0,0 +1,92 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.okhttp.internal.http;
+
+import com.android.okhttp.Protocol;
+import com.android.okhttp.Response;
+import java.io.IOException;
+import java.net.ProtocolException;
+
+/** An HTTP response status line like "HTTP/1.1 200 OK". 
+ * @hide This class is not part of the Android public SDK API*/
+public final class StatusLine {
+  /** Numeric status code, 307: Temporary Redirect. */
+  public static final int HTTP_TEMP_REDIRECT = 307;
+  public static final int HTTP_PERM_REDIRECT = 308;
+  public static final int HTTP_CONTINUE = 100;
+
+  public final Protocol protocol;
+  public final int code;
+  public final String message;
+
+  public StatusLine(Protocol protocol, int code, String message) {
+    this.protocol = protocol;
+    this.code = code;
+    this.message = message;
+  }
+
+  public static StatusLine get(Response response) {
+    return new StatusLine(response.protocol(), response.code(), response.message());
+  }
+
+  public static StatusLine parse(String statusLine) throws IOException {
+    // H T T P / 1 . 1   2 0 0   T e m p o r a r y   R e d i r e c t
+    // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
+
+    // Parse protocol like "HTTP/1.1" followed by a space.
+    int codeStart;
+    Protocol protocol;
+    if (statusLine.startsWith("HTTP/1.")) {
+      if (statusLine.length() < 9 || statusLine.charAt(8) != ' ') {
+        throw new ProtocolException("Unexpected status line: " + statusLine);
+      }
+      int httpMinorVersion = statusLine.charAt(7) - '0';
+      codeStart = 9;
+      if (httpMinorVersion == 0) {
+        protocol = Protocol.HTTP_1_0;
+      } else if (httpMinorVersion == 1) {
+        protocol = Protocol.HTTP_1_1;
+      } else {
+        throw new ProtocolException("Unexpected status line: " + statusLine);
+      }
+    } else if (statusLine.startsWith("ICY ")) {
+      // Shoutcast uses ICY instead of "HTTP/1.0".
+      protocol = Protocol.HTTP_1_0;
+      codeStart = 4;
+    } else {
+      throw new ProtocolException("Unexpected status line: " + statusLine);
+    }
+
+    // Parse response code like "200". Always 3 digits.
+    if (statusLine.length() < codeStart + 3) {
+      throw new ProtocolException("Unexpected status line: " + statusLine);
+    }
+    int code;
+    try {
+      code = Integer.parseInt(statusLine.substring(codeStart, codeStart + 3));
+    } catch (NumberFormatException e) {
+      throw new ProtocolException("Unexpected status line: " + statusLine);
+    }
+
+    // Parse an optional response message like "OK" or "Not Modified". If it
+    // exists, it is separated from the response code by a space.
+    String message = "";
+    if (statusLine.length() > codeStart + 3) {
+      if (statusLine.charAt(codeStart + 3) != ' ') {
+        throw new ProtocolException("Unexpected status line: " + statusLine);
+      }
+      message = statusLine.substring(codeStart + 4);
+    }
+
+    return new StatusLine(protocol, code, message);
+  }
+
+  @Override public String toString() {
+    StringBuilder result = new StringBuilder();
+    result.append(protocol == Protocol.HTTP_1_0 ? "HTTP/1.0" : "HTTP/1.1");
+    result.append(' ').append(code);
+    if (message != null) {
+      result.append(' ').append(message);
+    }
+    return result.toString();
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/StreamAllocation.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/StreamAllocation.java
new file mode 100644
index 0000000..4199e90
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/http/StreamAllocation.java
@@ -0,0 +1,412 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.okhttp.internal.http;
+
+import com.android.okhttp.Address;
+import com.android.okhttp.ConnectionPool;
+import com.android.okhttp.Route;
+import com.android.okhttp.internal.Internal;
+import com.android.okhttp.internal.RouteDatabase;
+import com.android.okhttp.internal.Util;
+import com.android.okhttp.internal.io.RealConnection;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.net.ProtocolException;
+import java.net.SocketTimeoutException;
+import java.security.cert.CertificateException;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import com.android.okhttp.okio.Sink;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+/**
+ * This class coordinates the relationship between three entities:
+ *
+ * <ul>
+ *   <li><strong>Connections:</strong> physical socket connections to remote servers. These are
+ *       potentially slow to establish so it is necessary to be able to cancel a connection
+ *       currently being connected.
+ *   <li><strong>Streams:</strong> logical HTTP request/response pairs that are layered on
+ *       connections. Each connection has its own allocation limit, which defines how many
+ *       concurrent streams that connection can carry. HTTP/1.x connections can carry 1 stream
+ *       at a time, SPDY and HTTP/2 typically carry multiple.
+ *   <li><strong>Calls:</strong> a logical sequence of streams, typically an initial request and
+ *       its follow up requests. We prefer to keep all streams of a single call on the same
+ *       connection for better behavior and locality.
+ * </ul>
+ *
+ * <p>Instances of this class act on behalf of the call, using one or more streams over one or
+ * more connections. This class has APIs to release each of the above resources:
+ *
+ * <ul>
+ *   <li>{@link #noNewStreams()} prevents the connection from being used for new streams in the
+ *       future. Use this after a {@code Connection: close} header, or when the connection may be
+ *       inconsistent.
+ *   <li>{@link #streamFinished streamFinished()} releases the active stream from this allocation.
+ *       Note that only one stream may be active at a given time, so it is necessary to call {@link
+ *       #streamFinished streamFinished()} before creating a subsequent stream with {@link
+ *       #newStream newStream()}.
+ *   <li>{@link #release()} removes the call's hold on the connection. Note that this won't
+ *       immediately free the connection if there is a stream still lingering. That happens when a
+ *       call is complete but its response body has yet to be fully consumed.
+ * </ul>
+ *
+ * <p>This class supports {@linkplain #cancel asynchronous canceling}. This is intended to have
+ * the smallest blast radius possible. If an HTTP/2 stream is active, canceling will cancel that
+ * stream but not the other streams sharing its connection. But if the TLS handshake is still in
+ * progress then canceling may break the entire connection.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class StreamAllocation {
+  public final Address address;
+  private final ConnectionPool connectionPool;
+
+  // State guarded by connectionPool.
+  private RouteSelector routeSelector;
+  private RealConnection connection;
+  private boolean released;
+  private boolean canceled;
+  private HttpStream stream;
+
+  public StreamAllocation(ConnectionPool connectionPool, Address address) {
+    this.connectionPool = connectionPool;
+    this.address = address;
+  }
+
+  public HttpStream newStream(int connectTimeout, int readTimeout, int writeTimeout,
+      boolean connectionRetryEnabled, boolean doExtensiveHealthChecks)
+      throws RouteException, IOException {
+    try {
+      RealConnection resultConnection = findHealthyConnection(connectTimeout, readTimeout,
+          writeTimeout, connectionRetryEnabled, doExtensiveHealthChecks);
+
+      HttpStream resultStream;
+      if (resultConnection.framedConnection != null) {
+        resultStream = new Http2xStream(this, resultConnection.framedConnection);
+      } else {
+        resultConnection.getSocket().setSoTimeout(readTimeout);
+        resultConnection.source.timeout().timeout(readTimeout, MILLISECONDS);
+        resultConnection.sink.timeout().timeout(writeTimeout, MILLISECONDS);
+        resultStream = new Http1xStream(this, resultConnection.source, resultConnection.sink);
+      }
+
+      synchronized (connectionPool) {
+        resultConnection.streamCount++;
+        stream = resultStream;
+        return resultStream;
+      }
+    } catch (IOException e) {
+      throw new RouteException(e);
+    }
+  }
+
+  /**
+   * Finds a connection and returns it if it is healthy. If it is unhealthy the process is repeated
+   * until a healthy connection is found.
+   */
+  private RealConnection findHealthyConnection(int connectTimeout, int readTimeout,
+      int writeTimeout, boolean connectionRetryEnabled, boolean doExtensiveHealthChecks)
+      throws IOException, RouteException {
+    while (true) {
+      RealConnection candidate = findConnection(connectTimeout, readTimeout, writeTimeout,
+          connectionRetryEnabled);
+
+      // If this is a brand new connection, we can skip the extensive health checks.
+      synchronized (connectionPool) {
+        if (candidate.streamCount == 0) {
+          return candidate;
+        }
+      }
+
+      // Otherwise do a potentially-slow check to confirm that the pooled connection is still good.
+      if (candidate.isHealthy(doExtensiveHealthChecks)) {
+        return candidate;
+      }
+
+      connectionFailed();
+    }
+  }
+
+  /**
+   * Returns a connection to host a new stream. This prefers the existing connection if it exists,
+   * then the pool, finally building a new connection.
+   */
+  private RealConnection findConnection(int connectTimeout, int readTimeout, int writeTimeout,
+      boolean connectionRetryEnabled) throws IOException, RouteException {
+    synchronized (connectionPool) {
+      if (released) throw new IllegalStateException("released");
+      if (stream != null) throw new IllegalStateException("stream != null");
+      if (canceled) throw new IOException("Canceled");
+
+      RealConnection allocatedConnection = this.connection;
+      if (allocatedConnection != null && !allocatedConnection.noNewStreams) {
+        return allocatedConnection;
+      }
+
+      // Attempt to get a connection from the pool.
+      RealConnection pooledConnection = Internal.instance.get(connectionPool, address, this);
+      if (pooledConnection != null) {
+        this.connection = pooledConnection;
+        return pooledConnection;
+      }
+
+      // Attempt to create a connection.
+      if (routeSelector == null) {
+        routeSelector = new RouteSelector(address, routeDatabase());
+      }
+    }
+
+    Route route = routeSelector.next();
+    RealConnection newConnection = new RealConnection(route);
+    acquire(newConnection);
+
+    synchronized (connectionPool) {
+      Internal.instance.put(connectionPool, newConnection);
+      this.connection = newConnection;
+      if (canceled) throw new IOException("Canceled");
+    }
+
+    newConnection.connect(connectTimeout, readTimeout, writeTimeout, address.getConnectionSpecs(),
+        connectionRetryEnabled);
+    routeDatabase().connected(newConnection.getRoute());
+
+    return newConnection;
+  }
+
+  public void streamFinished(HttpStream stream) {
+    synchronized (connectionPool) {
+      if (stream == null || stream != this.stream) {
+        throw new IllegalStateException("expected " + this.stream + " but was " + stream);
+      }
+    }
+    deallocate(false, false, true);
+  }
+
+  public HttpStream stream() {
+    synchronized (connectionPool) {
+      return stream;
+    }
+  }
+
+  private RouteDatabase routeDatabase() {
+    return Internal.instance.routeDatabase(connectionPool);
+  }
+
+  public synchronized RealConnection connection() {
+    return connection;
+  }
+
+  public void release() {
+    deallocate(false, true, false);
+  }
+
+  /** Forbid new streams from being created on the connection that hosts this allocation. */
+  public void noNewStreams() {
+    deallocate(true, false, false);
+  }
+
+  /**
+   * Releases resources held by this allocation. If sufficient resources are allocated, the
+   * connection will be detached or closed.
+   */
+  private void deallocate(boolean noNewStreams, boolean released, boolean streamFinished) {
+    RealConnection connectionToClose = null;
+    synchronized (connectionPool) {
+      if (streamFinished) {
+        this.stream = null;
+      }
+      if (released) {
+        this.released = true;
+      }
+      if (connection != null) {
+        if (noNewStreams) {
+          connection.noNewStreams = true;
+        }
+        if (this.stream == null && (this.released || connection.noNewStreams)) {
+          release(connection);
+          if (connection.streamCount > 0) {
+            routeSelector = null;
+          }
+          if (connection.allocations.isEmpty()) {
+            connection.idleAtNanos = System.nanoTime();
+            if (Internal.instance.connectionBecameIdle(connectionPool, connection)) {
+              connectionToClose = connection;
+            }
+          }
+          connection = null;
+        }
+      }
+    }
+    if (connectionToClose != null) {
+      Util.closeQuietly(connectionToClose.getSocket());
+    }
+  }
+
+  public void cancel() {
+    HttpStream streamToCancel;
+    RealConnection connectionToCancel;
+    synchronized (connectionPool) {
+      canceled = true;
+      streamToCancel = stream;
+      connectionToCancel = connection;
+    }
+    if (streamToCancel != null) {
+      streamToCancel.cancel();
+    } else if (connectionToCancel != null) {
+      connectionToCancel.cancel();
+    }
+  }
+
+  private void connectionFailed(IOException e) {
+    synchronized (connectionPool) {
+      if (routeSelector != null) {
+        if (connection.streamCount == 0) {
+          // Record the failure on a fresh route.
+          Route failedRoute = connection.getRoute();
+          routeSelector.connectFailed(failedRoute, e);
+        } else {
+          // We saw a failure on a recycled connection, reset this allocation with a fresh route.
+          routeSelector = null;
+        }
+      }
+    }
+    connectionFailed();
+  }
+
+  /** Finish the current stream and prevent new streams from being created. */
+  public void connectionFailed() {
+    deallocate(true, false, true);
+  }
+
+  /**
+   * Use this allocation to hold {@code connection}. Each call to this must be paired with a call to
+   * {@link #release} on the same connection.
+   */
+  public void acquire(RealConnection connection) {
+    connection.allocations.add(new WeakReference<>(this));
+  }
+
+  /** Remove this allocation from the connection's list of allocations. */
+  private void release(RealConnection connection) {
+    for (int i = 0, size = connection.allocations.size(); i < size; i++) {
+      Reference<StreamAllocation> reference = connection.allocations.get(i);
+      if (reference.get() == this) {
+        connection.allocations.remove(i);
+        return;
+      }
+    }
+    throw new IllegalStateException();
+  }
+
+  public boolean recover(RouteException e) {
+    // Android-changed: Canceled StreamAllocations can never recover http://b/33763156
+    if (canceled) {
+      return false;
+    }
+    if (connection != null) {
+      connectionFailed(e.getLastConnectException());
+    }
+
+    if ((routeSelector != null && !routeSelector.hasNext()) // No more routes to attempt.
+        || !isRecoverable(e)) {
+      return false;
+    }
+
+    return true;
+  }
+
+  public boolean recover(IOException e, Sink requestBodyOut) {
+    if (connection != null) {
+      int streamCount = connection.streamCount;
+      connectionFailed(e);
+
+      if (streamCount == 1) {
+        // This isn't a recycled connection.
+        // TODO(jwilson): find a better way for this.
+        return false;
+      }
+    }
+
+    boolean canRetryRequestBody = requestBodyOut == null || requestBodyOut instanceof RetryableSink;
+    if ((routeSelector != null && !routeSelector.hasNext()) // No more routes to attempt.
+        || !isRecoverable(e)
+        || !canRetryRequestBody) {
+      return false;
+    }
+
+    return true;
+  }
+
+  private boolean isRecoverable(IOException e) {
+    // If there was a protocol problem, don't recover.
+    if (e instanceof ProtocolException) {
+      return false;
+    }
+
+    // If there was an interruption or timeout, don't recover.
+    if (e instanceof InterruptedIOException) {
+      return false;
+    }
+
+    return true;
+  }
+
+  private boolean isRecoverable(RouteException e) {
+    // Problems with a route may mean the connection can be retried with a new route, or may
+    // indicate a client-side or server-side issue that should not be retried. To tell, we must look
+    // at the cause.
+
+    IOException ioe = e.getLastConnectException();
+
+    // If there was a protocol problem, don't recover.
+    if (ioe instanceof ProtocolException) {
+      return false;
+    }
+
+    // If there was an interruption don't recover, but if there was a timeout
+    // we should try the next route (if there is one).
+    if (ioe instanceof InterruptedIOException) {
+      return ioe instanceof SocketTimeoutException;
+    }
+
+    // Look for known client-side or negotiation errors that are unlikely to be fixed by trying
+    // again with a different route.
+    if (ioe instanceof SSLHandshakeException) {
+      // If the problem was a CertificateException from the X509TrustManager,
+      // do not retry.
+      if (ioe.getCause() instanceof CertificateException) {
+        return false;
+      }
+    }
+    if (ioe instanceof SSLPeerUnverifiedException) {
+      // e.g. a certificate pinning error.
+      return false;
+    }
+
+    // An example of one we might want to retry with a different route is a problem connecting to a
+    // proxy and would manifest as a standard IOException. Unless it is one we know we should not
+    // retry, we return true and try a new route.
+    return true;
+  }
+
+  @Override public String toString() {
+    return address.toString();
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/io/FileSystem.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/io/FileSystem.java
new file mode 100644
index 0000000..3bdcbc9
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/io/FileSystem.java
@@ -0,0 +1,139 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.okhttp.internal.io;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import com.android.okhttp.okio.Okio;
+import com.android.okhttp.okio.Sink;
+import com.android.okhttp.okio.Source;
+
+/**
+ * Access to read and write files on a hierarchical data store. Most callers should use the {@link
+ * #SYSTEM} implementation, which uses the host machine's local file system. Alternate
+ * implementations may be used to inject faults (for testing) or to transform stored data (to add
+ * encryption, for example).
+ *
+ * <p>All operations on a file system are racy. For example, guarding a call to {@link #source}
+ * with {@link #exists} does not guarantee that {@link FileNotFoundException} will not be thrown.
+ * The file may be moved between the two calls!
+ *
+ * <p>This interface is less ambitious than {@link java.nio.file.FileSystem} introduced in Java 7.
+ * It lacks important features like file watching, metadata, permissions, and disk space
+ * information. In exchange for these limitations, this interface is easier to implement and works
+ * on all versions of Java and Android.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface FileSystem {
+  /** The host machine's local file system. */
+  FileSystem SYSTEM = new FileSystem() {
+    @Override public Source source(File file) throws FileNotFoundException {
+      return Okio.source(file);
+    }
+
+    @Override public Sink sink(File file) throws FileNotFoundException {
+      try {
+        return Okio.sink(file);
+      } catch (FileNotFoundException e) {
+        // Maybe the parent directory doesn't exist? Try creating it first.
+        file.getParentFile().mkdirs();
+        return Okio.sink(file);
+      }
+    }
+
+    @Override public Sink appendingSink(File file) throws FileNotFoundException {
+      try {
+        return Okio.appendingSink(file);
+      } catch (FileNotFoundException e) {
+        // Maybe the parent directory doesn't exist? Try creating it first.
+        file.getParentFile().mkdirs();
+        return Okio.appendingSink(file);
+      }
+    }
+
+    @Override public void delete(File file) throws IOException {
+      // If delete() fails, make sure it's because the file didn't exist!
+      if (!file.delete() && file.exists()) {
+        throw new IOException("failed to delete " + file);
+      }
+    }
+
+    @Override public boolean exists(File file) throws IOException {
+      return file.exists();
+    }
+
+    @Override public long size(File file) {
+      return file.length();
+    }
+
+    @Override public void rename(File from, File to) throws IOException {
+      delete(to);
+      if (!from.renameTo(to)) {
+        throw new IOException("failed to rename " + from + " to " + to);
+      }
+    }
+
+    @Override public void deleteContents(File directory) throws IOException {
+      File[] files = directory.listFiles();
+      if (files == null) {
+        throw new IOException("not a readable directory: " + directory);
+      }
+      for (File file : files) {
+        if (file.isDirectory()) {
+          deleteContents(file);
+        }
+        if (!file.delete()) {
+          throw new IOException("failed to delete " + file);
+        }
+      }
+    }
+  };
+
+  /** Reads from {@code file}. */
+  Source source(File file) throws FileNotFoundException;
+
+  /**
+   * Writes to {@code file}, discarding any data already present. Creates parent directories if
+   * necessary.
+   */
+  Sink sink(File file) throws FileNotFoundException;
+
+  /**
+   * Writes to {@code file}, appending if data is already present. Creates parent directories if
+   * necessary.
+   */
+  Sink appendingSink(File file) throws FileNotFoundException;
+
+  /** Deletes {@code file} if it exists. Throws if the file exists and cannot be deleted. */
+  void delete(File file) throws IOException;
+
+  /** Returns true if {@code file} exists on the file system. */
+  boolean exists(File file) throws IOException;
+
+  /** Returns the number of bytes stored in {@code file}, or 0 if it does not exist. */
+  long size(File file);
+
+  /** Renames {@code from} to {@code to}. Throws if the file cannot be renamed. */
+  void rename(File from, File to) throws IOException;
+
+  /**
+   * Recursively delete the contents of {@code directory}. Throws an IOException if any file could
+   * not be deleted, or if {@code dir} is not a readable directory.
+   */
+  void deleteContents(File directory) throws IOException;
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/io/RealConnection.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/io/RealConnection.java
new file mode 100644
index 0000000..719890e
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/io/RealConnection.java
@@ -0,0 +1,411 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  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.android.okhttp.internal.io;
+
+import com.android.okhttp.Address;
+import com.android.okhttp.CertificatePinner;
+import com.android.okhttp.Connection;
+import com.android.okhttp.ConnectionSpec;
+import com.android.okhttp.Handshake;
+import com.android.okhttp.HttpUrl;
+import com.android.okhttp.Protocol;
+import com.android.okhttp.Request;
+import com.android.okhttp.Response;
+import com.android.okhttp.Route;
+import com.android.okhttp.internal.ConnectionSpecSelector;
+import com.android.okhttp.internal.Platform;
+import com.android.okhttp.internal.Util;
+import com.android.okhttp.internal.Version;
+import com.android.okhttp.internal.framed.FramedConnection;
+import com.android.okhttp.internal.http.Http1xStream;
+import com.android.okhttp.internal.http.OkHeaders;
+import com.android.okhttp.internal.http.RouteException;
+import com.android.okhttp.internal.http.StreamAllocation;
+import com.android.okhttp.internal.tls.CertificateChainCleaner;
+import com.android.okhttp.internal.tls.OkHostnameVerifier;
+import com.android.okhttp.internal.tls.TrustRootIndex;
+import java.io.IOException;
+import java.lang.ref.Reference;
+import java.net.ConnectException;
+import java.net.Proxy;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.net.UnknownServiceException;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.X509TrustManager;
+import com.android.okhttp.okio.BufferedSink;
+import com.android.okhttp.okio.BufferedSource;
+import com.android.okhttp.okio.Okio;
+import com.android.okhttp.okio.Source;
+
+import static com.android.okhttp.internal.Util.closeQuietly;
+import static java.net.HttpURLConnection.HTTP_OK;
+import static java.net.HttpURLConnection.HTTP_PROXY_AUTH;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class RealConnection implements Connection {
+  private final Route route;
+
+  /** The low-level TCP socket. */
+  private Socket rawSocket;
+
+  /**
+   * The application layer socket. Either an {@link SSLSocket} layered over {@link #rawSocket}, or
+   * {@link #rawSocket} itself if this connection does not use SSL.
+   */
+  public Socket socket;
+  private Handshake handshake;
+  private Protocol protocol;
+  public volatile FramedConnection framedConnection;
+  public int streamCount;
+  public BufferedSource source;
+  public BufferedSink sink;
+  public final List<Reference<StreamAllocation>> allocations = new ArrayList<>();
+  public boolean noNewStreams;
+  public long idleAtNanos = Long.MAX_VALUE;
+
+  public RealConnection(Route route) {
+    this.route = route;
+  }
+
+  public void connect(int connectTimeout, int readTimeout, int writeTimeout,
+      List<ConnectionSpec> connectionSpecs, boolean connectionRetryEnabled) throws RouteException {
+    if (protocol != null) throw new IllegalStateException("already connected");
+
+    RouteException routeException = null;
+    ConnectionSpecSelector connectionSpecSelector = new ConnectionSpecSelector(connectionSpecs);
+    Proxy proxy = route.getProxy();
+    Address address = route.getAddress();
+
+    if (route.getAddress().getSslSocketFactory() == null
+        && !connectionSpecs.contains(ConnectionSpec.CLEARTEXT)) {
+      throw new RouteException(new UnknownServiceException(
+          "CLEARTEXT communication not supported: " + connectionSpecs));
+    }
+
+    while (protocol == null) {
+      try {
+        rawSocket = proxy.type() == Proxy.Type.DIRECT || proxy.type() == Proxy.Type.HTTP
+            ? address.getSocketFactory().createSocket()
+            : new Socket(proxy);
+        connectSocket(connectTimeout, readTimeout, writeTimeout, connectionSpecSelector);
+      } catch (IOException e) {
+        Util.closeQuietly(socket);
+        Util.closeQuietly(rawSocket);
+        socket = null;
+        rawSocket = null;
+        source = null;
+        sink = null;
+        handshake = null;
+        protocol = null;
+
+        if (routeException == null) {
+          routeException = new RouteException(e);
+        } else {
+          routeException.addConnectException(e);
+        }
+
+        if (!connectionRetryEnabled || !connectionSpecSelector.connectionFailed(e)) {
+          throw routeException;
+        }
+      }
+    }
+  }
+
+  /** Does all the work necessary to build a full HTTP or HTTPS connection on a raw socket. */
+  private void connectSocket(int connectTimeout, int readTimeout, int writeTimeout,
+      ConnectionSpecSelector connectionSpecSelector) throws IOException {
+    rawSocket.setSoTimeout(readTimeout);
+    try {
+      Platform.get().connectSocket(rawSocket, route.getSocketAddress(), connectTimeout);
+    } catch (ConnectException e) {
+      throw new ConnectException("Failed to connect to " + route.getSocketAddress());
+    }
+    source = Okio.buffer(Okio.source(rawSocket));
+    sink = Okio.buffer(Okio.sink(rawSocket));
+
+    if (route.getAddress().getSslSocketFactory() != null) {
+      connectTls(readTimeout, writeTimeout, connectionSpecSelector);
+    } else {
+      protocol = Protocol.HTTP_1_1;
+      socket = rawSocket;
+    }
+
+    if (protocol == Protocol.SPDY_3 || protocol == Protocol.HTTP_2) {
+      socket.setSoTimeout(0); // Framed connection timeouts are set per-stream.
+
+      FramedConnection framedConnection = new FramedConnection.Builder(true)
+          .socket(socket, route.getAddress().url().host(), source, sink)
+          .protocol(protocol)
+          .build();
+      framedConnection.sendConnectionPreface();
+
+      // Only assign the framed connection once the preface has been sent successfully.
+      this.framedConnection = framedConnection;
+    }
+  }
+
+  private void connectTls(int readTimeout, int writeTimeout,
+      ConnectionSpecSelector connectionSpecSelector) throws IOException {
+    if (route.requiresTunnel()) {
+      createTunnel(readTimeout, writeTimeout);
+    }
+
+    Address address = route.getAddress();
+    SSLSocketFactory sslSocketFactory = address.getSslSocketFactory();
+    boolean success = false;
+    SSLSocket sslSocket = null;
+    try {
+      // Create the wrapper over the connected socket.
+      sslSocket = (SSLSocket) sslSocketFactory.createSocket(
+          rawSocket, address.getUriHost(), address.getUriPort(), true /* autoClose */);
+
+      // Configure the socket's ciphers, TLS versions, and extensions.
+      ConnectionSpec connectionSpec = connectionSpecSelector.configureSecureSocket(sslSocket);
+      if (connectionSpec.supportsTlsExtensions()) {
+        Platform.get().configureTlsExtensions(
+            sslSocket, address.getUriHost(), address.getProtocols());
+      }
+
+      // Force handshake. This can throw!
+      sslSocket.startHandshake();
+      Handshake unverifiedHandshake = Handshake.get(sslSocket.getSession());
+
+      // Verify that the socket's certificates are acceptable for the target host.
+      if (!address.getHostnameVerifier().verify(address.getUriHost(), sslSocket.getSession())) {
+        X509Certificate cert = (X509Certificate) unverifiedHandshake.peerCertificates().get(0);
+        throw new SSLPeerUnverifiedException("Hostname " + address.getUriHost() + " not verified:"
+            + "\n    certificate: " + CertificatePinner.pin(cert)
+            + "\n    DN: " + cert.getSubjectDN().getName()
+            + "\n    subjectAltNames: " + OkHostnameVerifier.allSubjectAltNames(cert));
+      }
+
+      // Check that the certificate pinner is satisfied by the certificates presented.
+      if (address.getCertificatePinner() != CertificatePinner.DEFAULT) {
+        TrustRootIndex trustRootIndex = trustRootIndex(address.getSslSocketFactory());
+        List<Certificate> certificates = new CertificateChainCleaner(trustRootIndex)
+            .clean(unverifiedHandshake.peerCertificates());
+        address.getCertificatePinner().check(address.getUriHost(), certificates);
+      }
+
+      // Success! Save the handshake and the ALPN protocol.
+      String maybeProtocol = connectionSpec.supportsTlsExtensions()
+          ? Platform.get().getSelectedProtocol(sslSocket)
+          : null;
+      socket = sslSocket;
+      source = Okio.buffer(Okio.source(socket));
+      sink = Okio.buffer(Okio.sink(socket));
+      handshake = unverifiedHandshake;
+      protocol = maybeProtocol != null
+          ? Protocol.get(maybeProtocol)
+          : Protocol.HTTP_1_1;
+      success = true;
+    } catch (AssertionError e) {
+      if (Util.isAndroidGetsocknameError(e)) throw new IOException(e);
+      throw e;
+    } finally {
+      if (sslSocket != null) {
+        Platform.get().afterHandshake(sslSocket);
+      }
+      if (!success) {
+        closeQuietly(sslSocket);
+      }
+    }
+  }
+
+  private static SSLSocketFactory lastSslSocketFactory;
+  private static TrustRootIndex lastTrustRootIndex;
+
+  /**
+   * Returns a trust root index for {@code sslSocketFactory}. This uses a static, single-element
+   * cache to avoid redoing reflection and SSL indexing in the common case where most SSL
+   * connections use the same SSL socket factory.
+   */
+  private static synchronized TrustRootIndex trustRootIndex(SSLSocketFactory sslSocketFactory) {
+    if (sslSocketFactory != lastSslSocketFactory) {
+      X509TrustManager trustManager = Platform.get().trustManager(sslSocketFactory);
+      lastTrustRootIndex = Platform.get().trustRootIndex(trustManager);
+      lastSslSocketFactory = sslSocketFactory;
+    }
+    return lastTrustRootIndex;
+  }
+
+  /**
+   * 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 createTunnel(int readTimeout, int writeTimeout) throws IOException {
+    // Make an SSL Tunnel on the first message pair of each SSL + proxy connection.
+    Request tunnelRequest = createTunnelRequest();
+    HttpUrl url = tunnelRequest.httpUrl();
+    String requestLine = "CONNECT " + Util.hostHeader(url, true) + " HTTP/1.1";
+    while (true) {
+      Http1xStream tunnelConnection = new Http1xStream(null, source, sink);
+      source.timeout().timeout(readTimeout, MILLISECONDS);
+      sink.timeout().timeout(writeTimeout, MILLISECONDS);
+      tunnelConnection.writeRequest(tunnelRequest.headers(), requestLine);
+      tunnelConnection.finishRequest();
+      Response response = tunnelConnection.readResponse().request(tunnelRequest).build();
+      // The response body from a CONNECT should be empty, but if it is not then we should consume
+      // it before proceeding.
+      long contentLength = OkHeaders.contentLength(response);
+      if (contentLength == -1L) {
+        contentLength = 0L;
+      }
+      Source body = tunnelConnection.newFixedLengthSource(contentLength);
+      Util.skipAll(body, Integer.MAX_VALUE, TimeUnit.MILLISECONDS);
+      body.close();
+
+      switch (response.code()) {
+        case HTTP_OK:
+          // Assume the server won't send a TLS ServerHello until we send a TLS ClientHello. If
+          // that happens, then we will have buffered bytes that are needed by the SSLSocket!
+          // This check is imperfect: it doesn't tell us whether a handshake will succeed, just
+          // that it will almost certainly fail because the proxy has sent unexpected data.
+          if (!source.buffer().exhausted() || !sink.buffer().exhausted()) {
+            throw new IOException("TLS tunnel buffered too many bytes!");
+          }
+          return;
+
+        case HTTP_PROXY_AUTH:
+          tunnelRequest = OkHeaders.processAuthHeader(
+              route.getAddress().getAuthenticator(), response, route.getProxy());
+          if (tunnelRequest != null) continue;
+          throw new IOException("Failed to authenticate with proxy");
+
+        default:
+          throw new IOException(
+              "Unexpected response code for CONNECT: " + response.code());
+      }
+    }
+  }
+
+  /**
+   * Returns a request that creates a TLS tunnel via an HTTP proxy, or null if
+   * no tunnel is necessary. Everything in the tunnel request is sent
+   * unencrypted to the proxy server, so tunnels include only the minimum set of
+   * headers. This avoids sending potentially sensitive data like HTTP cookies
+   * to the proxy unencrypted.
+   */
+  private Request createTunnelRequest() throws IOException {
+    return new Request.Builder()
+        .url(route.getAddress().url())
+        .header("Host", Util.hostHeader(route.getAddress().url(), true))
+        .header("Proxy-Connection", "Keep-Alive")
+        .header("User-Agent", Version.userAgent()) // For HTTP/1.0 proxies like Squid.
+        .build();
+  }
+
+  /** Returns true if {@link #connect} has been attempted on this connection. */
+  boolean isConnected() {
+    return protocol != null;
+  }
+
+  @Override public Route getRoute() {
+    return route;
+  }
+
+  public void cancel() {
+    // Close the raw socket so we don't end up doing synchronous I/O.
+    Util.closeQuietly(rawSocket);
+  }
+
+  @Override public Socket getSocket() {
+    return socket;
+  }
+
+  public int allocationLimit() {
+    FramedConnection framedConnection = this.framedConnection;
+    return framedConnection != null
+        ? framedConnection.maxConcurrentStreams()
+        : 1;
+  }
+
+  /** Returns true if this connection is ready to host new streams. */
+  public boolean isHealthy(boolean doExtensiveChecks) {
+    if (socket.isClosed() || socket.isInputShutdown() || socket.isOutputShutdown()) {
+      return false;
+    }
+
+    if (framedConnection != null) {
+      return true; // TODO: check framedConnection.shutdown.
+    }
+
+    if (doExtensiveChecks) {
+      try {
+        int readTimeout = socket.getSoTimeout();
+        try {
+          socket.setSoTimeout(1);
+          if (source.exhausted()) {
+            return false; // Stream is exhausted; socket is closed.
+          }
+          return true;
+        } finally {
+          socket.setSoTimeout(readTimeout);
+        }
+      } catch (SocketTimeoutException ignored) {
+        // Read timed out; socket is good.
+      } catch (IOException e) {
+        return false; // Couldn't read; socket is closed.
+      }
+    }
+
+    return true;
+  }
+
+  @Override public Handshake getHandshake() {
+    return handshake;
+  }
+
+  /**
+   * Returns true if this is a SPDY connection. Such connections can be used
+   * in multiple HTTP requests simultaneously.
+   */
+  public boolean isMultiplexed() {
+    return framedConnection != null;
+  }
+
+  @Override public Protocol getProtocol() {
+    return protocol != null ? protocol : Protocol.HTTP_1_1;
+  }
+
+  @Override public String toString() {
+    return "Connection{"
+        + route.getAddress().url().host() + ":" + route.getAddress().url().port()
+        + ", proxy="
+        + route.getProxy()
+        + " hostAddress="
+        + route.getSocketAddress()
+        + " cipherSuite="
+        + (handshake != null ? handshake.cipherSuite() : "none")
+        + " protocol="
+        + protocol
+        + '}';
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/tls/AndroidTrustRootIndex.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/tls/AndroidTrustRootIndex.java
new file mode 100644
index 0000000..207985e
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/tls/AndroidTrustRootIndex.java
@@ -0,0 +1,67 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2016 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 com.android.okhttp.internal.tls;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.cert.TrustAnchor;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * A index of trusted root certificates that exploits knowledge of Android implementation details.
+ * This class is potentially much faster to initialize than {@link RealTrustRootIndex} because
+ * it doesn't need to load and index trusted CA certificates.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class AndroidTrustRootIndex implements TrustRootIndex {
+  private final X509TrustManager trustManager;
+  private final Method findByIssuerAndSignatureMethod;
+
+  public AndroidTrustRootIndex(
+      X509TrustManager trustManager, Method findByIssuerAndSignatureMethod) {
+    this.findByIssuerAndSignatureMethod = findByIssuerAndSignatureMethod;
+    this.trustManager = trustManager;
+  }
+
+  @Override public X509Certificate findByIssuerAndSignature(X509Certificate cert) {
+    try {
+      TrustAnchor trustAnchor = (TrustAnchor) findByIssuerAndSignatureMethod.invoke(
+          trustManager, cert);
+      return trustAnchor != null
+          ? trustAnchor.getTrustedCert()
+          : null;
+    } catch (IllegalAccessException e) {
+      throw new AssertionError();
+    } catch (InvocationTargetException e) {
+      return null;
+    }
+  }
+
+  public static TrustRootIndex get(X509TrustManager trustManager) {
+    // From org.conscrypt.TrustManagerImpl, we want the method with this signature:
+    // private TrustAnchor findTrustAnchorByIssuerAndSignature(X509Certificate lastCert);
+    try {
+      Method method = trustManager.getClass().getDeclaredMethod(
+          "findTrustAnchorByIssuerAndSignature", X509Certificate.class);
+      method.setAccessible(true);
+      return new AndroidTrustRootIndex(trustManager, method);
+    } catch (NoSuchMethodException e) {
+      return null;
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/tls/CertificateChainCleaner.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/tls/CertificateChainCleaner.java
new file mode 100644
index 0000000..6bcdc25
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/tls/CertificateChainCleaner.java
@@ -0,0 +1,119 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  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.android.okhttp.internal.tls;
+
+import java.security.GeneralSecurityException;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.List;
+import javax.net.ssl.SSLPeerUnverifiedException;
+
+/**
+ * Computes the effective certificate chain from the raw array returned by Java's built in TLS APIs.
+ * Cleaning a chain returns a list of certificates where the first element is {@code chain[0]}, each
+ * certificate is signed by the certificate that follows, and the last certificate is a trusted CA
+ * certificate.
+ *
+ * <p>Use of the chain cleaner is necessary to omit unexpected certificates that aren't relevant to
+ * the TLS handshake and to extract the trusted CA certificate for the benefit of certificate
+ * pinning.
+ *
+ * <p>This class includes code from <a href="https://conscrypt.org/">Conscrypt's</a> {@code
+ * TrustManagerImpl} and {@code TrustedCertificateIndex}.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class CertificateChainCleaner {
+  /** The maximum number of signers in a chain. We use 9 for consistency with OpenSSL. */
+  private static final int MAX_SIGNERS = 9;
+
+  private final TrustRootIndex trustRootIndex;
+
+  public CertificateChainCleaner(TrustRootIndex trustRootIndex) {
+    this.trustRootIndex = trustRootIndex;
+  }
+
+  /**
+   * Returns a cleaned chain for {@code chain}.
+   *
+   * <p>This method throws if the complete chain to a trusted CA certificate cannot be constructed.
+   * This is unexpected unless the trust root index in this class has a different trust manager than
+   * what was used to establish {@code chain}.
+   */
+  public List<Certificate> clean(List<Certificate> chain) throws SSLPeerUnverifiedException {
+    Deque<Certificate> queue = new ArrayDeque<>(chain);
+    List<Certificate> result = new ArrayList<>();
+    result.add(queue.removeFirst());
+    boolean foundTrustedCertificate = false;
+
+    followIssuerChain:
+    for (int c = 0; c < MAX_SIGNERS; c++) {
+      X509Certificate toVerify = (X509Certificate) result.get(result.size() - 1);
+
+      // If this cert has been signed by a trusted cert, use that. Add the trusted certificate to
+      // the end of the chain unless it's already present. (That would happen if the first
+      // certificate in the chain is itself a self-signed and trusted CA certificate.)
+      X509Certificate trustedCert = trustRootIndex.findByIssuerAndSignature(toVerify);
+      if (trustedCert != null) {
+        if (result.size() > 1 || !toVerify.equals(trustedCert)) {
+          result.add(trustedCert);
+        }
+        if (verifySignature(trustedCert, trustedCert)) {
+          return result; // The self-signed cert is a root CA. We're done.
+        }
+        foundTrustedCertificate = true;
+        continue;
+      }
+
+      // Search for the certificate in the chain that signed this certificate. This is typically the
+      // next element in the chain, but it could be any element.
+      for (Iterator<Certificate> i = queue.iterator(); i.hasNext(); ) {
+        X509Certificate signingCert = (X509Certificate) i.next();
+        if (verifySignature(toVerify, signingCert)) {
+          i.remove();
+          result.add(signingCert);
+          continue followIssuerChain;
+        }
+      }
+
+      // We've reached the end of the chain. If any cert in the chain is trusted, we're done.
+      if (foundTrustedCertificate) {
+        return result;
+      }
+
+      // The last link isn't trusted. Fail.
+      throw new SSLPeerUnverifiedException("Failed to find a trusted cert that signed " + toVerify);
+    }
+
+    throw new SSLPeerUnverifiedException("Certificate chain too long: " + result);
+  }
+
+  /** Returns true if {@code toVerify} was signed by {@code signingCert}'s public key. */
+  private boolean verifySignature(X509Certificate toVerify, X509Certificate signingCert) {
+    if (!toVerify.getIssuerDN().equals(signingCert.getSubjectDN())) return false;
+    try {
+      toVerify.verify(signingCert.getPublicKey());
+      return true;
+    } catch (GeneralSecurityException verifyFailed) {
+      return false;
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/tls/DistinguishedNameParser.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/tls/DistinguishedNameParser.java
new file mode 100644
index 0000000..15f0a6a
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/tls/DistinguishedNameParser.java
@@ -0,0 +1,408 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  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.android.okhttp.internal.tls;
+
+import javax.security.auth.x500.X500Principal;
+
+/**
+ * A distinguished name (DN) parser. This parser only supports extracting a
+ * string value from a DN. It doesn't support values in the hex-string style.
+ */
+final class DistinguishedNameParser {
+  private final String dn;
+  private final int length;
+  private int pos;
+  private int beg;
+  private int end;
+
+  /** Temporary variable to store positions of the currently parsed item. */
+  private int cur;
+
+  /** Distinguished name characters. */
+  private char[] chars;
+
+  public DistinguishedNameParser(X500Principal principal) {
+    // RFC2253 is used to ensure we get attributes in the reverse
+    // order of the underlying ASN.1 encoding, so that the most
+    // significant values of repeated attributes occur first.
+    this.dn = principal.getName(X500Principal.RFC2253);
+    this.length = this.dn.length();
+  }
+
+  // gets next attribute type: (ALPHA 1*keychar) / oid
+  private String nextAT() {
+    // skip preceding space chars, they can present after
+    // comma or semicolon (compatibility with RFC 1779)
+    for (; pos < length && chars[pos] == ' '; pos++) {
+    }
+    if (pos == length) {
+      return null; // reached the end of DN
+    }
+
+    // mark the beginning of attribute type
+    beg = pos;
+
+    // attribute type chars
+    pos++;
+    for (; pos < length && chars[pos] != '=' && chars[pos] != ' '; pos++) {
+      // we don't follow exact BNF syntax here:
+      // accept any char except space and '='
+    }
+    if (pos >= length) {
+      throw new IllegalStateException("Unexpected end of DN: " + dn);
+    }
+
+    // mark the end of attribute type
+    end = pos;
+
+    // skip trailing space chars between attribute type and '='
+    // (compatibility with RFC 1779)
+    if (chars[pos] == ' ') {
+      for (; pos < length && chars[pos] != '=' && chars[pos] == ' '; pos++) {
+      }
+
+      if (chars[pos] != '=' || pos == length) {
+        throw new IllegalStateException("Unexpected end of DN: " + dn);
+      }
+    }
+
+    pos++; //skip '=' char
+
+    // skip space chars between '=' and attribute value
+    // (compatibility with RFC 1779)
+    for (; pos < length && chars[pos] == ' '; pos++) {
+    }
+
+    // in case of oid attribute type skip its prefix: "oid." or "OID."
+    // (compatibility with RFC 1779)
+    if ((end - beg > 4) && (chars[beg + 3] == '.')
+        && (chars[beg] == 'O' || chars[beg] == 'o')
+        && (chars[beg + 1] == 'I' || chars[beg + 1] == 'i')
+        && (chars[beg + 2] == 'D' || chars[beg + 2] == 'd')) {
+      beg += 4;
+    }
+
+    return new String(chars, beg, end - beg);
+  }
+
+  // gets quoted attribute value: QUOTATION *( quotechar / pair ) QUOTATION
+  private String quotedAV() {
+    pos++;
+    beg = pos;
+    end = beg;
+    while (true) {
+
+      if (pos == length) {
+        throw new IllegalStateException("Unexpected end of DN: " + dn);
+      }
+
+      if (chars[pos] == '"') {
+        // enclosing quotation was found
+        pos++;
+        break;
+      } else if (chars[pos] == '\\') {
+        chars[end] = getEscaped();
+      } else {
+        // shift char: required for string with escaped chars
+        chars[end] = chars[pos];
+      }
+      pos++;
+      end++;
+    }
+
+    // skip trailing space chars before comma or semicolon.
+    // (compatibility with RFC 1779)
+    for (; pos < length && chars[pos] == ' '; pos++) {
+    }
+
+    return new String(chars, beg, end - beg);
+  }
+
+  // gets hex string attribute value: "#" hexstring
+  private String hexAV() {
+    if (pos + 4 >= length) {
+      // encoded byte array  must be not less then 4 c
+      throw new IllegalStateException("Unexpected end of DN: " + dn);
+    }
+
+    beg = pos; // store '#' position
+    pos++;
+    while (true) {
+
+      // check for end of attribute value
+      // looks for space and component separators
+      if (pos == length || chars[pos] == '+' || chars[pos] == ','
+          || chars[pos] == ';') {
+        end = pos;
+        break;
+      }
+
+      if (chars[pos] == ' ') {
+        end = pos;
+        pos++;
+        // skip trailing space chars before comma or semicolon.
+        // (compatibility with RFC 1779)
+        for (; pos < length && chars[pos] == ' '; pos++) {
+        }
+        break;
+      } else if (chars[pos] >= 'A' && chars[pos] <= 'F') {
+        chars[pos] += 32; //to low case
+      }
+
+      pos++;
+    }
+
+    // verify length of hex string
+    // encoded byte array  must be not less then 4 and must be even number
+    int hexLen = end - beg; // skip first '#' char
+    if (hexLen < 5 || (hexLen & 1) == 0) {
+      throw new IllegalStateException("Unexpected end of DN: " + dn);
+    }
+
+    // get byte encoding from string representation
+    byte[] encoded = new byte[hexLen / 2];
+    for (int i = 0, p = beg + 1; i < encoded.length; p += 2, i++) {
+      encoded[i] = (byte) getByte(p);
+    }
+
+    return new String(chars, beg, hexLen);
+  }
+
+  // gets string attribute value: *( stringchar / pair )
+  private String escapedAV() {
+    beg = pos;
+    end = pos;
+    while (true) {
+      if (pos >= length) {
+        // the end of DN has been found
+        return new String(chars, beg, end - beg);
+      }
+
+      switch (chars[pos]) {
+        case '+':
+        case ',':
+        case ';':
+          // separator char has been found
+          return new String(chars, beg, end - beg);
+        case '\\':
+          // escaped char
+          chars[end++] = getEscaped();
+          pos++;
+          break;
+        case ' ':
+          // need to figure out whether space defines
+          // the end of attribute value or not
+          cur = end;
+
+          pos++;
+          chars[end++] = ' ';
+
+          for (; pos < length && chars[pos] == ' '; pos++) {
+            chars[end++] = ' ';
+          }
+          if (pos == length || chars[pos] == ',' || chars[pos] == '+'
+              || chars[pos] == ';') {
+            // separator char or the end of DN has been found
+            return new String(chars, beg, cur - beg);
+          }
+          break;
+        default:
+          chars[end++] = chars[pos];
+          pos++;
+      }
+    }
+  }
+
+  // returns escaped char
+  private char getEscaped() {
+    pos++;
+    if (pos == length) {
+      throw new IllegalStateException("Unexpected end of DN: " + dn);
+    }
+
+    switch (chars[pos]) {
+      case '"':
+      case '\\':
+      case ',':
+      case '=':
+      case '+':
+      case '<':
+      case '>':
+      case '#':
+      case ';':
+      case ' ':
+      case '*':
+      case '%':
+      case '_':
+        //FIXME: escaping is allowed only for leading or trailing space char
+        return chars[pos];
+      default:
+        // RFC doesn't explicitly say that escaped hex pair is
+        // interpreted as UTF-8 char. It only contains an example of such DN.
+        return getUTF8();
+    }
+  }
+
+  // decodes UTF-8 char
+  // see http://www.unicode.org for UTF-8 bit distribution table
+  private char getUTF8() {
+    int res = getByte(pos);
+    pos++; //FIXME tmp
+
+    if (res < 128) { // one byte: 0-7F
+      return (char) res;
+    } else if (res >= 192 && res <= 247) {
+
+      int count;
+      if (res <= 223) { // two bytes: C0-DF
+        count = 1;
+        res = res & 0x1F;
+      } else if (res <= 239) { // three bytes: E0-EF
+        count = 2;
+        res = res & 0x0F;
+      } else { // four bytes: F0-F7
+        count = 3;
+        res = res & 0x07;
+      }
+
+      int b;
+      for (int i = 0; i < count; i++) {
+        pos++;
+        if (pos == length || chars[pos] != '\\') {
+          return 0x3F; //FIXME failed to decode UTF-8 char - return '?'
+        }
+        pos++;
+
+        b = getByte(pos);
+        pos++; //FIXME tmp
+        if ((b & 0xC0) != 0x80) {
+          return 0x3F; //FIXME failed to decode UTF-8 char - return '?'
+        }
+
+        res = (res << 6) + (b & 0x3F);
+      }
+      return (char) res;
+    } else {
+      return 0x3F; //FIXME failed to decode UTF-8 char - return '?'
+    }
+  }
+
+  // Returns byte representation of a char pair
+  // The char pair is composed of DN char in
+  // specified 'position' and the next char
+  // According to BNF syntax:
+  // hexchar    = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
+  //                    / "a" / "b" / "c" / "d" / "e" / "f"
+  private int getByte(int position) {
+    if (position + 1 >= length) {
+      throw new IllegalStateException("Malformed DN: " + dn);
+    }
+
+    int b1, b2;
+
+    b1 = chars[position];
+    if (b1 >= '0' && b1 <= '9') {
+      b1 = b1 - '0';
+    } else if (b1 >= 'a' && b1 <= 'f') {
+      b1 = b1 - 87; // 87 = 'a' - 10
+    } else if (b1 >= 'A' && b1 <= 'F') {
+      b1 = b1 - 55; // 55 = 'A' - 10
+    } else {
+      throw new IllegalStateException("Malformed DN: " + dn);
+    }
+
+    b2 = chars[position + 1];
+    if (b2 >= '0' && b2 <= '9') {
+      b2 = b2 - '0';
+    } else if (b2 >= 'a' && b2 <= 'f') {
+      b2 = b2 - 87; // 87 = 'a' - 10
+    } else if (b2 >= 'A' && b2 <= 'F') {
+      b2 = b2 - 55; // 55 = 'A' - 10
+    } else {
+      throw new IllegalStateException("Malformed DN: " + dn);
+    }
+
+    return (b1 << 4) + b2;
+  }
+
+  /**
+   * Parses the DN and returns the most significant attribute value
+   * for an attribute type, or null if none found.
+   *
+   * @param attributeType attribute type to look for (e.g. "ca")
+   */
+  public String findMostSpecific(String attributeType) {
+    // Initialize internal state.
+    pos = 0;
+    beg = 0;
+    end = 0;
+    cur = 0;
+    chars = dn.toCharArray();
+
+    String attType = nextAT();
+    if (attType == null) {
+      return null;
+    }
+    while (true) {
+      String attValue = "";
+
+      if (pos == length) {
+        return null;
+      }
+
+      switch (chars[pos]) {
+        case '"':
+          attValue = quotedAV();
+          break;
+        case '#':
+          attValue = hexAV();
+          break;
+        case '+':
+        case ',':
+        case ';': // compatibility with RFC 1779: semicolon can separate RDNs
+          //empty attribute value
+          break;
+        default:
+          attValue = escapedAV();
+      }
+
+      // Values are ordered from most specific to least specific
+      // due to the RFC2253 formatting. So take the first match
+      // we see.
+      if (attributeType.equalsIgnoreCase(attType)) {
+        return attValue;
+      }
+
+      if (pos >= length) {
+        return null;
+      }
+
+      if (chars[pos] == ',' || chars[pos] == ';') {
+      } else if (chars[pos] != '+') {
+        throw new IllegalStateException("Malformed DN: " + dn);
+      }
+
+      pos++;
+      attType = nextAT();
+      if (attType == null) {
+        throw new IllegalStateException("Malformed DN: " + dn);
+      }
+    }
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/tls/OkHostnameVerifier.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/tls/OkHostnameVerifier.java
new file mode 100644
index 0000000..3cdd1bf
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/tls/OkHostnameVerifier.java
@@ -0,0 +1,257 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  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.android.okhttp.internal.tls;
+
+import java.security.cert.Certificate;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Pattern;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+
+/**
+ * A HostnameVerifier consistent with <a
+ * href="http://www.ietf.org/rfc/rfc2818.txt">RFC 2818</a>.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class OkHostnameVerifier implements HostnameVerifier {
+  public static final OkHostnameVerifier INSTANCE = new OkHostnameVerifier();
+
+  /**
+   * Quick and dirty pattern to differentiate IP addresses from hostnames. This
+   * is an approximation of Android's private InetAddress#isNumeric API.
+   *
+   * <p>This matches IPv6 addresses as a hex string containing at least one
+   * colon, and possibly including dots after the first colon. It matches IPv4
+   * addresses as strings containing only decimal digits and dots. This pattern
+   * matches strings like "a:.23" and "54" that are neither IP addresses nor
+   * hostnames; they will be verified as IP addresses (which is a more strict
+   * verification).
+   */
+  private static final Pattern VERIFY_AS_IP_ADDRESS = Pattern.compile(
+      "([0-9a-fA-F]*:[0-9a-fA-F:.]*)|([\\d.]+)");
+
+  private static final int ALT_DNS_NAME = 2;
+  private static final int ALT_IPA_NAME = 7;
+
+  private OkHostnameVerifier() {
+  }
+
+  @Override
+  public boolean verify(String host, SSLSession session) {
+    try {
+      Certificate[] certificates = session.getPeerCertificates();
+      return verify(host, (X509Certificate) certificates[0]);
+    } catch (SSLException e) {
+      return false;
+    }
+  }
+
+  public boolean verify(String host, X509Certificate certificate) {
+    return verifyAsIpAddress(host)
+        ? verifyIpAddress(host, certificate)
+        : verifyHostName(host, certificate);
+  }
+
+  static boolean verifyAsIpAddress(String host) {
+    return VERIFY_AS_IP_ADDRESS.matcher(host).matches();
+  }
+
+  /**
+   * Returns true if {@code certificate} matches {@code ipAddress}.
+   */
+  private boolean verifyIpAddress(String ipAddress, X509Certificate certificate) {
+    List<String> altNames = getSubjectAltNames(certificate, ALT_IPA_NAME);
+    for (int i = 0, size = altNames.size(); i < size; i++) {
+      if (ipAddress.equalsIgnoreCase(altNames.get(i))) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Returns true if {@code certificate} matches {@code hostName}.
+   */
+  private boolean verifyHostName(String hostName, X509Certificate certificate) {
+    hostName = hostName.toLowerCase(Locale.US);
+    boolean hasDns = false;
+    List<String> altNames = getSubjectAltNames(certificate, ALT_DNS_NAME);
+    for (int i = 0, size = altNames.size(); i < size; i++) {
+      hasDns = true;
+      if (verifyHostName(hostName, altNames.get(i))) {
+        return true;
+      }
+    }
+
+    // BEGIN Android-removed: Ignore common name in hostname verification. http://b/70278814
+    /*
+    if (!hasDns) {
+      X500Principal principal = certificate.getSubjectX500Principal();
+      // RFC 2818 advises using the most specific name for matching.
+      String cn = new DistinguishedNameParser(principal).findMostSpecific("cn");
+      if (cn != null) {
+        return verifyHostName(hostName, cn);
+      }
+    }
+    */
+    // END Android-removed: Ignore common name in hostname verification. http://b/70278814
+
+    return false;
+  }
+
+  public static List<String> allSubjectAltNames(X509Certificate certificate) {
+    List<String> altIpaNames = getSubjectAltNames(certificate, ALT_IPA_NAME);
+    List<String> altDnsNames = getSubjectAltNames(certificate, ALT_DNS_NAME);
+    List<String> result = new ArrayList<>(altIpaNames.size() + altDnsNames.size());
+    result.addAll(altIpaNames);
+    result.addAll(altDnsNames);
+    return result;
+  }
+
+  private static List<String> getSubjectAltNames(X509Certificate certificate, int type) {
+    List<String> result = new ArrayList<>();
+    try {
+      Collection<?> subjectAltNames = certificate.getSubjectAlternativeNames();
+      if (subjectAltNames == null) {
+        return Collections.emptyList();
+      }
+      for (Object subjectAltName : subjectAltNames) {
+        List<?> entry = (List<?>) subjectAltName;
+        if (entry == null || entry.size() < 2) {
+          continue;
+        }
+        Integer altNameType = (Integer) entry.get(0);
+        if (altNameType == null) {
+          continue;
+        }
+        if (altNameType == type) {
+          String altName = (String) entry.get(1);
+          if (altName != null) {
+            result.add(altName);
+          }
+        }
+      }
+      return result;
+    } catch (CertificateParsingException e) {
+      return Collections.emptyList();
+    }
+  }
+
+  /**
+   * Returns {@code true} iff {@code hostName} matches the domain name {@code pattern}.
+   *
+   * @param hostName lower-case host name.
+   * @param pattern domain name pattern from certificate. May be a wildcard pattern such as
+   *        {@code *.android.com}.
+   */
+  private boolean verifyHostName(String hostName, String pattern) {
+    // Basic sanity checks
+    // Check length == 0 instead of .isEmpty() to support Java 5.
+    if ((hostName == null) || (hostName.length() == 0) || (hostName.startsWith("."))
+        || (hostName.endsWith(".."))) {
+      // Invalid domain name
+      return false;
+    }
+    if ((pattern == null) || (pattern.length() == 0) || (pattern.startsWith("."))
+        || (pattern.endsWith(".."))) {
+      // Invalid pattern/domain name
+      return false;
+    }
+
+    // Normalize hostName and pattern by turning them into absolute domain names if they are not
+    // yet absolute. This is needed because server certificates do not normally contain absolute
+    // names or patterns, but they should be treated as absolute. At the same time, any hostName
+    // presented to this method should also be treated as absolute for the purposes of matching
+    // to the server certificate.
+    //   www.android.com  matches www.android.com
+    //   www.android.com  matches www.android.com.
+    //   www.android.com. matches www.android.com.
+    //   www.android.com. matches www.android.com
+    if (!hostName.endsWith(".")) {
+      hostName += '.';
+    }
+    if (!pattern.endsWith(".")) {
+      pattern += '.';
+    }
+    // hostName and pattern are now absolute domain names.
+
+    pattern = pattern.toLowerCase(Locale.US);
+    // hostName and pattern are now in lower case -- domain names are case-insensitive.
+
+    if (!pattern.contains("*")) {
+      // Not a wildcard pattern -- hostName and pattern must match exactly.
+      return hostName.equals(pattern);
+    }
+    // Wildcard pattern
+
+    // WILDCARD PATTERN RULES:
+    // 1. Asterisk (*) is only permitted in the left-most domain name label and must be the
+    //    only character in that label (i.e., must match the whole left-most label).
+    //    For example, *.example.com is permitted, while *a.example.com, a*.example.com,
+    //    a*b.example.com, a.*.example.com are not permitted.
+    // 2. Asterisk (*) cannot match across domain name labels.
+    //    For example, *.example.com matches test.example.com but does not match
+    //    sub.test.example.com.
+    // 3. Wildcard patterns for single-label domain names are not permitted.
+
+    if ((!pattern.startsWith("*.")) || (pattern.indexOf('*', 1) != -1)) {
+      // Asterisk (*) is only permitted in the left-most domain name label and must be the only
+      // character in that label
+      return false;
+    }
+
+    // Optimization: check whether hostName is too short to match the pattern. hostName must be at
+    // least as long as the pattern because asterisk must match the whole left-most label and
+    // hostName starts with a non-empty label. Thus, asterisk has to match one or more characters.
+    if (hostName.length() < pattern.length()) {
+      // hostName too short to match the pattern.
+      return false;
+    }
+
+    if ("*.".equals(pattern)) {
+      // Wildcard pattern for single-label domain name -- not permitted.
+      return false;
+    }
+
+    // hostName must end with the region of pattern following the asterisk.
+    String suffix = pattern.substring(1);
+    if (!hostName.endsWith(suffix)) {
+      // hostName does not end with the suffix
+      return false;
+    }
+
+    // Check that asterisk did not match across domain name labels.
+    int suffixStartIndexInHostName = hostName.length() - suffix.length();
+    if ((suffixStartIndexInHostName > 0)
+        && (hostName.lastIndexOf('.', suffixStartIndexInHostName - 1) != -1)) {
+      // Asterisk is matching across domain name labels -- not permitted.
+      return false;
+    }
+
+    // hostName matches pattern
+    return true;
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/tls/RealTrustRootIndex.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/tls/RealTrustRootIndex.java
new file mode 100644
index 0000000..f4696a5
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/tls/RealTrustRootIndex.java
@@ -0,0 +1,62 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2016 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 com.android.okhttp.internal.tls;
+
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import javax.security.auth.x500.X500Principal;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class RealTrustRootIndex implements TrustRootIndex {
+  private final Map<X500Principal, List<X509Certificate>> subjectToCaCerts;
+
+  public RealTrustRootIndex(X509Certificate... caCerts) {
+    subjectToCaCerts = new LinkedHashMap<>();
+    for (X509Certificate caCert : caCerts) {
+      X500Principal subject = caCert.getSubjectX500Principal();
+      List<X509Certificate> subjectCaCerts = subjectToCaCerts.get(subject);
+      if (subjectCaCerts == null) {
+        subjectCaCerts = new ArrayList<>(1);
+        subjectToCaCerts.put(subject, subjectCaCerts);
+      }
+      subjectCaCerts.add(caCert);
+    }
+  }
+
+  @Override public X509Certificate findByIssuerAndSignature(X509Certificate cert) {
+    X500Principal issuer = cert.getIssuerX500Principal();
+    List<X509Certificate> subjectCaCerts = subjectToCaCerts.get(issuer);
+    if (subjectCaCerts == null) return null;
+
+    for (X509Certificate caCert : subjectCaCerts) {
+      PublicKey publicKey = caCert.getPublicKey();
+      try {
+        cert.verify(publicKey);
+        return caCert;
+      } catch (Exception ignored) {
+      }
+    }
+
+    return null;
+  }
+}
diff --git a/repackaged/okhttp/src/main/java/com/android/okhttp/internal/tls/TrustRootIndex.java b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/tls/TrustRootIndex.java
new file mode 100644
index 0000000..86111a8
--- /dev/null
+++ b/repackaged/okhttp/src/main/java/com/android/okhttp/internal/tls/TrustRootIndex.java
@@ -0,0 +1,27 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2016 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 com.android.okhttp.internal.tls;
+
+import java.security.cert.X509Certificate;
+
+/**
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface TrustRootIndex {
+  /** Returns the trusted CA certificate that signed {@code cert}. */
+  X509Certificate findByIssuerAndSignature(X509Certificate cert);
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/AsyncTimeout.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/AsyncTimeout.java
new file mode 100644
index 0000000..e801ae7
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/AsyncTimeout.java
@@ -0,0 +1,334 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.okio;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+
+/**
+ * This timeout uses a background thread to take action exactly when the timeout
+ * occurs. Use this to implement timeouts where they aren't supported natively,
+ * such as to sockets that are blocked on writing.
+ *
+ * <p>Subclasses should override {@link #timedOut} to take action when a timeout
+ * occurs. This method will be invoked by the shared watchdog thread so it
+ * should not do any long-running operations. Otherwise we risk starving other
+ * timeouts from being triggered.
+ *
+ * <p>Use {@link #sink} and {@link #source} to apply this timeout to a stream.
+ * The returned value will apply the timeout to each operation on the wrapped
+ * stream.
+ *
+ * <p>Callers should call {@link #enter} before doing work that is subject to
+ * timeouts, and {@link #exit} afterwards. The return value of {@link #exit}
+ * indicates whether a timeout was triggered. Note that the call to {@link
+ * #timedOut} is asynchronous, and may be called after {@link #exit}.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class AsyncTimeout extends Timeout {
+  /**
+   * The watchdog thread processes a linked list of pending timeouts, sorted in
+   * the order to be triggered. This class synchronizes on AsyncTimeout.class.
+   * This lock guards the queue.
+   *
+   * <p>Head's 'next' points to the first element of the linked list. The first
+   * element is the next node to time out, or null if the queue is empty. The
+   * head is null until the watchdog thread is started.
+   */
+  private static AsyncTimeout head;
+
+  /** True if this node is currently in the queue. */
+  private boolean inQueue;
+
+  /** The next node in the linked list. */
+  private AsyncTimeout next;
+
+  /** If scheduled, this is the time that the watchdog should time this out. */
+  private long timeoutAt;
+
+  public final void enter() {
+    if (inQueue) throw new IllegalStateException("Unbalanced enter/exit");
+    long timeoutNanos = timeoutNanos();
+    boolean hasDeadline = hasDeadline();
+    if (timeoutNanos == 0 && !hasDeadline) {
+      return; // No timeout and no deadline? Don't bother with the queue.
+    }
+    inQueue = true;
+    scheduleTimeout(this, timeoutNanos, hasDeadline);
+  }
+
+  private static synchronized void scheduleTimeout(
+      AsyncTimeout node, long timeoutNanos, boolean hasDeadline) {
+    // Start the watchdog thread and create the head node when the first timeout is scheduled.
+    if (head == null) {
+      head = new AsyncTimeout();
+      new Watchdog().start();
+    }
+
+    long now = System.nanoTime();
+    if (timeoutNanos != 0 && hasDeadline) {
+      // Compute the earliest event; either timeout or deadline. Because nanoTime can wrap around,
+      // Math.min() is undefined for absolute values, but meaningful for relative ones.
+      node.timeoutAt = now + Math.min(timeoutNanos, node.deadlineNanoTime() - now);
+    } else if (timeoutNanos != 0) {
+      node.timeoutAt = now + timeoutNanos;
+    } else if (hasDeadline) {
+      node.timeoutAt = node.deadlineNanoTime();
+    } else {
+      throw new AssertionError();
+    }
+
+    // Insert the node in sorted order.
+    long remainingNanos = node.remainingNanos(now);
+    for (AsyncTimeout prev = head; true; prev = prev.next) {
+      if (prev.next == null || remainingNanos < prev.next.remainingNanos(now)) {
+        node.next = prev.next;
+        prev.next = node;
+        if (prev == head) {
+          AsyncTimeout.class.notify(); // Wake up the watchdog when inserting at the front.
+        }
+        break;
+      }
+    }
+  }
+
+  /** Returns true if the timeout occurred. */
+  public final boolean exit() {
+    if (!inQueue) return false;
+    inQueue = false;
+    return cancelScheduledTimeout(this);
+  }
+
+  /** Returns true if the timeout occurred. */
+  private static synchronized boolean cancelScheduledTimeout(AsyncTimeout node) {
+    // Remove the node from the linked list.
+    for (AsyncTimeout prev = head; prev != null; prev = prev.next) {
+      if (prev.next == node) {
+        prev.next = node.next;
+        node.next = null;
+        return false;
+      }
+    }
+
+    // The node wasn't found in the linked list: it must have timed out!
+    return true;
+  }
+
+  /**
+   * Returns the amount of time left until the time out. This will be negative
+   * if the timeout has elapsed and the timeout should occur immediately.
+   */
+  private long remainingNanos(long now) {
+    return timeoutAt - now;
+  }
+
+  /**
+   * Invoked by the watchdog thread when the time between calls to {@link
+   * #enter()} and {@link #exit()} has exceeded the timeout.
+   */
+  protected void timedOut() {
+  }
+
+  /**
+   * Returns a new sink that delegates to {@code sink}, using this to implement
+   * timeouts. This works best if {@link #timedOut} is overridden to interrupt
+   * {@code sink}'s current operation.
+   */
+  public final Sink sink(final Sink sink) {
+    return new Sink() {
+      @Override public void write(Buffer source, long byteCount) throws IOException {
+        boolean throwOnTimeout = false;
+        enter();
+        try {
+          sink.write(source, byteCount);
+          throwOnTimeout = true;
+        } catch (IOException e) {
+          throw exit(e);
+        } finally {
+          exit(throwOnTimeout);
+        }
+      }
+
+      @Override public void flush() throws IOException {
+        boolean throwOnTimeout = false;
+        enter();
+        try {
+          sink.flush();
+          throwOnTimeout = true;
+        } catch (IOException e) {
+          throw exit(e);
+        } finally {
+          exit(throwOnTimeout);
+        }
+      }
+
+      @Override public void close() throws IOException {
+        boolean throwOnTimeout = false;
+        enter();
+        try {
+          sink.close();
+          throwOnTimeout = true;
+        } catch (IOException e) {
+          throw exit(e);
+        } finally {
+          exit(throwOnTimeout);
+        }
+      }
+
+      @Override public Timeout timeout() {
+        return AsyncTimeout.this;
+      }
+
+      @Override public String toString() {
+        return "AsyncTimeout.sink(" + sink + ")";
+      }
+    };
+  }
+
+  /**
+   * Returns a new source that delegates to {@code source}, using this to
+   * implement timeouts. This works best if {@link #timedOut} is overridden to
+   * interrupt {@code sink}'s current operation.
+   */
+  public final Source source(final Source source) {
+    return new Source() {
+      @Override public long read(Buffer sink, long byteCount) throws IOException {
+        boolean throwOnTimeout = false;
+        enter();
+        try {
+          long result = source.read(sink, byteCount);
+          throwOnTimeout = true;
+          return result;
+        } catch (IOException e) {
+          throw exit(e);
+        } finally {
+          exit(throwOnTimeout);
+        }
+      }
+
+      @Override public void close() throws IOException {
+        boolean throwOnTimeout = false;
+        try {
+          source.close();
+          throwOnTimeout = true;
+        } catch (IOException e) {
+          throw exit(e);
+        } finally {
+          exit(throwOnTimeout);
+        }
+      }
+
+      @Override public Timeout timeout() {
+        return AsyncTimeout.this;
+      }
+
+      @Override public String toString() {
+        return "AsyncTimeout.source(" + source + ")";
+      }
+    };
+  }
+
+  /**
+   * Throws an IOException if {@code throwOnTimeout} is {@code true} and a
+   * timeout occurred. See {@link #newTimeoutException(java.io.IOException)}
+   * for the type of exception thrown.
+   */
+  final void exit(boolean throwOnTimeout) throws IOException {
+    boolean timedOut = exit();
+    if (timedOut && throwOnTimeout) throw newTimeoutException(null);
+  }
+
+  /**
+   * Returns either {@code cause} or an IOException that's caused by
+   * {@code cause} if a timeout occurred. See
+   * {@link #newTimeoutException(java.io.IOException)} for the type of
+   * exception returned.
+   */
+  final IOException exit(IOException cause) throws IOException {
+    if (!exit()) return cause;
+    return newTimeoutException(cause);
+  }
+
+  /**
+   * Returns an {@link IOException} to represent a timeout. By default this method returns
+   * {@link java.io.InterruptedIOException}. If {@code cause} is non-null it is set as the cause of
+   * the returned exception.
+   */
+  protected IOException newTimeoutException(IOException cause) {
+    InterruptedIOException e = new InterruptedIOException("timeout");
+    if (cause != null) {
+      e.initCause(cause);
+    }
+    return e;
+  }
+
+  private static final class Watchdog extends Thread {
+    public Watchdog() {
+      super("Okio Watchdog");
+      setDaemon(true);
+    }
+
+    public void run() {
+      while (true) {
+        try {
+          AsyncTimeout timedOut = awaitTimeout();
+
+          // Didn't find a node to interrupt. Try again.
+          if (timedOut == null) continue;
+
+          // Close the timed out node.
+          timedOut.timedOut();
+        } catch (InterruptedException ignored) {
+        }
+      }
+    }
+  }
+
+  /**
+   * Removes and returns the node at the head of the list, waiting for it to
+   * time out if necessary. Returns null if the situation changes while waiting:
+   * either a newer node is inserted at the head, or the node being waited on
+   * has been removed.
+   */
+  private static synchronized AsyncTimeout awaitTimeout() throws InterruptedException {
+    // Get the next eligible node.
+    AsyncTimeout node = head.next;
+
+    // The queue is empty. Wait for something to be enqueued.
+    if (node == null) {
+      AsyncTimeout.class.wait();
+      return null;
+    }
+
+    long waitNanos = node.remainingNanos(System.nanoTime());
+
+    // The head of the queue hasn't timed out yet. Await that.
+    if (waitNanos > 0) {
+      // Waiting is made complicated by the fact that we work in nanoseconds,
+      // but the API wants (millis, nanos) in two arguments.
+      long waitMillis = waitNanos / 1000000L;
+      waitNanos -= (waitMillis * 1000000L);
+      AsyncTimeout.class.wait(waitMillis, (int) waitNanos);
+      return null;
+    }
+
+    // The head of the queue has timed out. Remove it.
+    head.next = node.next;
+    node.next = null;
+    return node;
+  }
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Base64.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Base64.java
new file mode 100644
index 0000000..3260c96
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Base64.java
@@ -0,0 +1,163 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ *  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 com.android.okhttp.okio;
+
+import java.io.UnsupportedEncodingException;
+
+final class Base64 {
+  private Base64() {
+  }
+
+  public static byte[] decode(String in) {
+    // Ignore trailing '=' padding and whitespace from the input.
+    int limit = in.length();
+    for (; limit > 0; limit--) {
+      char c = in.charAt(limit - 1);
+      if (c != '=' && c != '\n' && c != '\r' && c != ' ' && c != '\t') {
+        break;
+      }
+    }
+
+    // If the input includes whitespace, this output array will be longer than necessary.
+    byte[] out = new byte[(int) (limit * 6L / 8L)];
+    int outCount = 0;
+    int inCount = 0;
+
+    int word = 0;
+    for (int pos = 0; pos < limit; pos++) {
+      char c = in.charAt(pos);
+
+      int bits;
+      if (c >= 'A' && c <= 'Z') {
+        // char ASCII value
+        //  A    65    0
+        //  Z    90    25 (ASCII - 65)
+        bits = c - 65;
+      } else if (c >= 'a' && c <= 'z') {
+        // char ASCII value
+        //  a    97    26
+        //  z    122   51 (ASCII - 71)
+        bits = c - 71;
+      } else if (c >= '0' && c <= '9') {
+        // char ASCII value
+        //  0    48    52
+        //  9    57    61 (ASCII + 4)
+        bits = c + 4;
+      } else if (c == '+' || c == '-') {
+        bits = 62;
+      } else if (c == '/' || c == '_') {
+        bits = 63;
+      } else if (c == '\n' || c == '\r' || c == ' ' || c == '\t') {
+        continue;
+      } else {
+        return null;
+      }
+
+      // Append this char's 6 bits to the word.
+      word = (word << 6) | (byte) bits;
+
+      // For every 4 chars of input, we accumulate 24 bits of output. Emit 3 bytes.
+      inCount++;
+      if (inCount % 4 == 0) {
+        out[outCount++] = (byte) (word >> 16);
+        out[outCount++] = (byte) (word >> 8);
+        out[outCount++] = (byte) word;
+      }
+    }
+
+    int lastWordChars = inCount % 4;
+    if (lastWordChars == 1) {
+      // We read 1 char followed by "===". But 6 bits is a truncated byte! Fail.
+      return null;
+    } else if (lastWordChars == 2) {
+      // We read 2 chars followed by "==". Emit 1 byte with 8 of those 12 bits.
+      word = word << 12;
+      out[outCount++] = (byte) (word >> 16);
+    } else if (lastWordChars == 3) {
+      // We read 3 chars, followed by "=". Emit 2 bytes for 16 of those 18 bits.
+      word = word << 6;
+      out[outCount++] = (byte) (word >> 16);
+      out[outCount++] = (byte) (word >> 8);
+    }
+
+    // If we sized our out array perfectly, we're done.
+    if (outCount == out.length) return out;
+
+    // Copy the decoded bytes to a new, right-sized array.
+    byte[] prefix = new byte[outCount];
+    System.arraycopy(out, 0, prefix, 0, outCount);
+    return prefix;
+  }
+
+  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', '+', '/'
+  };
+
+  private static final byte[] URL_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) {
+    return encode(in, MAP);
+  }
+
+  public static String encodeUrl(byte[] in) {
+    return encode(in, URL_MAP);
+  }
+
+  private static String encode(byte[] in, byte[] map) {
+    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/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Buffer.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Buffer.java
new file mode 100644
index 0000000..04752d8
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Buffer.java
@@ -0,0 +1,1439 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.okio;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static com.android.okhttp.okio.Util.checkOffsetAndCount;
+import static com.android.okhttp.okio.Util.reverseBytesLong;
+
+/**
+ * A collection of bytes in memory.
+ *
+ * <p><strong>Moving data from one buffer to another is fast.</strong> Instead
+ * of copying bytes from one place in memory to another, this class just changes
+ * ownership of the underlying byte arrays.
+ *
+ * <p><strong>This buffer grows with your data.</strong> Just like ArrayList,
+ * each buffer starts small. It consumes only the memory it needs to.
+ *
+ * <p><strong>This buffer pools its byte arrays.</strong> When you allocate a
+ * byte array in Java, the runtime must zero-fill the requested array before
+ * returning it to you. Even if you're going to write over that space anyway.
+ * This class avoids zero-fill and GC churn by pooling byte arrays.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class Buffer implements BufferedSource, BufferedSink, Cloneable {
+  private static final byte[] DIGITS =
+      { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+  static final int REPLACEMENT_CHARACTER = '\ufffd';
+
+  Segment head;
+  long size;
+
+  public Buffer() {
+  }
+
+  /** Returns the number of bytes currently in this buffer. */
+  public long size() {
+    return size;
+  }
+
+  @Override public Buffer buffer() {
+    return this;
+  }
+
+  @Override public OutputStream outputStream() {
+    return new OutputStream() {
+      @Override public void write(int b) {
+        writeByte((byte) b);
+      }
+
+      @Override public void write(byte[] data, int offset, int byteCount) {
+        Buffer.this.write(data, offset, byteCount);
+      }
+
+      @Override public void flush() {
+      }
+
+      @Override public void close() {
+      }
+
+      @Override public String toString() {
+        return this + ".outputStream()";
+      }
+    };
+  }
+
+  @Override public Buffer emitCompleteSegments() {
+    return this; // Nowhere to emit to!
+  }
+
+  @Override public BufferedSink emit() {
+    return this; // Nowhere to emit to!
+  }
+
+  @Override public boolean exhausted() {
+    return size == 0;
+  }
+
+  @Override public void require(long byteCount) throws EOFException {
+    if (size < byteCount) throw new EOFException();
+  }
+
+  @Override public boolean request(long byteCount) {
+    return size >= byteCount;
+  }
+
+  @Override public InputStream inputStream() {
+    return new InputStream() {
+      @Override public int read() {
+        if (size > 0) return readByte() & 0xff;
+        return -1;
+      }
+
+      @Override public int read(byte[] sink, int offset, int byteCount) {
+        return Buffer.this.read(sink, offset, byteCount);
+      }
+
+      @Override public int available() {
+        return (int) Math.min(size, Integer.MAX_VALUE);
+      }
+
+      @Override public void close() {
+      }
+
+      @Override public String toString() {
+        return Buffer.this + ".inputStream()";
+      }
+    };
+  }
+
+  /** Copy the contents of this to {@code out}. */
+  public Buffer copyTo(OutputStream out) throws IOException {
+    return copyTo(out, 0, size);
+  }
+
+  /**
+   * Copy {@code byteCount} bytes from this, starting at {@code offset}, to
+   * {@code out}.
+   */
+  public Buffer copyTo(OutputStream out, long offset, long byteCount) throws IOException {
+    if (out == null) throw new IllegalArgumentException("out == null");
+    checkOffsetAndCount(size, offset, byteCount);
+    if (byteCount == 0) return this;
+
+    // Skip segments that we aren't copying from.
+    Segment s = head;
+    for (; offset >= (s.limit - s.pos); s = s.next) {
+      offset -= (s.limit - s.pos);
+    }
+
+    // Copy from one segment at a time.
+    for (; byteCount > 0; s = s.next) {
+      int pos = (int) (s.pos + offset);
+      int toCopy = (int) Math.min(s.limit - pos, byteCount);
+      out.write(s.data, pos, toCopy);
+      byteCount -= toCopy;
+      offset = 0;
+    }
+
+    return this;
+  }
+
+  /** Copy {@code byteCount} bytes from this, starting at {@code offset}, to {@code out}. */
+  public Buffer copyTo(Buffer out, long offset, long byteCount) {
+    if (out == null) throw new IllegalArgumentException("out == null");
+    checkOffsetAndCount(size, offset, byteCount);
+    if (byteCount == 0) return this;
+
+    out.size += byteCount;
+
+    // Skip segments that we aren't copying from.
+    Segment s = head;
+    for (; offset >= (s.limit - s.pos); s = s.next) {
+      offset -= (s.limit - s.pos);
+    }
+
+    // Copy one segment at a time.
+    for (; byteCount > 0; s = s.next) {
+      Segment copy = new Segment(s);
+      copy.pos += offset;
+      copy.limit = Math.min(copy.pos + (int) byteCount, copy.limit);
+      if (out.head == null) {
+        out.head = copy.next = copy.prev = copy;
+      } else {
+        out.head.prev.push(copy);
+      }
+      byteCount -= copy.limit - copy.pos;
+      offset = 0;
+    }
+
+    return this;
+  }
+
+  /** Write the contents of this to {@code out}. */
+  public Buffer writeTo(OutputStream out) throws IOException {
+    return writeTo(out, size);
+  }
+
+  /** Write {@code byteCount} bytes from this to {@code out}. */
+  public Buffer writeTo(OutputStream out, long byteCount) throws IOException {
+    if (out == null) throw new IllegalArgumentException("out == null");
+    checkOffsetAndCount(size, 0, byteCount);
+
+    Segment s = head;
+    while (byteCount > 0) {
+      int toCopy = (int) Math.min(byteCount, s.limit - s.pos);
+      out.write(s.data, s.pos, toCopy);
+
+      s.pos += toCopy;
+      size -= toCopy;
+      byteCount -= toCopy;
+
+      if (s.pos == s.limit) {
+        Segment toRecycle = s;
+        head = s = toRecycle.pop();
+        SegmentPool.recycle(toRecycle);
+      }
+    }
+
+    return this;
+  }
+
+  /** Read and exhaust bytes from {@code in} to this. */
+  public Buffer readFrom(InputStream in) throws IOException {
+    readFrom(in, Long.MAX_VALUE, true);
+    return this;
+  }
+
+  /** Read {@code byteCount} bytes from {@code in} to this. */
+  public Buffer readFrom(InputStream in, long byteCount) throws IOException {
+    if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
+    readFrom(in, byteCount, false);
+    return this;
+  }
+
+  private void readFrom(InputStream in, long byteCount, boolean forever) throws IOException {
+    if (in == null) throw new IllegalArgumentException("in == null");
+    while (byteCount > 0 || forever) {
+      Segment tail = writableSegment(1);
+      int maxToCopy = (int) Math.min(byteCount, Segment.SIZE - tail.limit);
+      int bytesRead = in.read(tail.data, tail.limit, maxToCopy);
+      if (bytesRead == -1) {
+        if (forever) return;
+        throw new EOFException();
+      }
+      tail.limit += bytesRead;
+      size += bytesRead;
+      byteCount -= bytesRead;
+    }
+  }
+
+  /**
+   * Returns the number of bytes in segments that are not writable. This is the
+   * number of bytes that can be flushed immediately to an underlying sink
+   * without harming throughput.
+   */
+  public long completeSegmentByteCount() {
+    long result = size;
+    if (result == 0) return 0;
+
+    // Omit the tail if it's still writable.
+    Segment tail = head.prev;
+    if (tail.limit < Segment.SIZE && tail.owner) {
+      result -= tail.limit - tail.pos;
+    }
+
+    return result;
+  }
+
+  @Override public byte readByte() {
+    if (size == 0) throw new IllegalStateException("size == 0");
+
+    Segment segment = head;
+    int pos = segment.pos;
+    int limit = segment.limit;
+
+    byte[] data = segment.data;
+    byte b = data[pos++];
+    size -= 1;
+
+    if (pos == limit) {
+      head = segment.pop();
+      SegmentPool.recycle(segment);
+    } else {
+      segment.pos = pos;
+    }
+
+    return b;
+  }
+
+  /** Returns the byte at {@code pos}. */
+  public byte getByte(long pos) {
+    checkOffsetAndCount(size, pos, 1);
+    for (Segment s = head; true; s = s.next) {
+      int segmentByteCount = s.limit - s.pos;
+      if (pos < segmentByteCount) return s.data[s.pos + (int) pos];
+      pos -= segmentByteCount;
+    }
+  }
+
+  @Override public short readShort() {
+    if (size < 2) throw new IllegalStateException("size < 2: " + size);
+
+    Segment segment = head;
+    int pos = segment.pos;
+    int limit = segment.limit;
+
+    // If the short is split across multiple segments, delegate to readByte().
+    if (limit - pos < 2) {
+      int s = (readByte() & 0xff) << 8
+          |   (readByte() & 0xff);
+      return (short) s;
+    }
+
+    byte[] data = segment.data;
+    int s = (data[pos++] & 0xff) << 8
+        |   (data[pos++] & 0xff);
+    size -= 2;
+
+    if (pos == limit) {
+      head = segment.pop();
+      SegmentPool.recycle(segment);
+    } else {
+      segment.pos = pos;
+    }
+
+    return (short) s;
+  }
+
+  @Override public int readInt() {
+    if (size < 4) throw new IllegalStateException("size < 4: " + size);
+
+    Segment segment = head;
+    int pos = segment.pos;
+    int limit = segment.limit;
+
+    // If the int is split across multiple segments, delegate to readByte().
+    if (limit - pos < 4) {
+      return (readByte() & 0xff) << 24
+          |  (readByte() & 0xff) << 16
+          |  (readByte() & 0xff) <<  8
+          |  (readByte() & 0xff);
+    }
+
+    byte[] data = segment.data;
+    int i = (data[pos++] & 0xff) << 24
+        |   (data[pos++] & 0xff) << 16
+        |   (data[pos++] & 0xff) <<  8
+        |   (data[pos++] & 0xff);
+    size -= 4;
+
+    if (pos == limit) {
+      head = segment.pop();
+      SegmentPool.recycle(segment);
+    } else {
+      segment.pos = pos;
+    }
+
+    return i;
+  }
+
+  @Override public long readLong() {
+    if (size < 8) throw new IllegalStateException("size < 8: " + size);
+
+    Segment segment = head;
+    int pos = segment.pos;
+    int limit = segment.limit;
+
+    // If the long is split across multiple segments, delegate to readInt().
+    if (limit - pos < 8) {
+      return (readInt() & 0xffffffffL) << 32
+          |  (readInt() & 0xffffffffL);
+    }
+
+    byte[] data = segment.data;
+    long v = (data[pos++] & 0xffL) << 56
+        |    (data[pos++] & 0xffL) << 48
+        |    (data[pos++] & 0xffL) << 40
+        |    (data[pos++] & 0xffL) << 32
+        |    (data[pos++] & 0xffL) << 24
+        |    (data[pos++] & 0xffL) << 16
+        |    (data[pos++] & 0xffL) <<  8
+        |    (data[pos++] & 0xffL);
+    size -= 8;
+
+    if (pos == limit) {
+      head = segment.pop();
+      SegmentPool.recycle(segment);
+    } else {
+      segment.pos = pos;
+    }
+
+    return v;
+  }
+
+  @Override public short readShortLe() {
+    return Util.reverseBytesShort(readShort());
+  }
+
+  @Override public int readIntLe() {
+    return Util.reverseBytesInt(readInt());
+  }
+
+  @Override public long readLongLe() {
+    return Util.reverseBytesLong(readLong());
+  }
+
+  @Override public long readDecimalLong() {
+    if (size == 0) throw new IllegalStateException("size == 0");
+
+    // This value is always built negatively in order to accommodate Long.MIN_VALUE.
+    long value = 0;
+    int seen = 0;
+    boolean negative = false;
+    boolean done = false;
+
+    long overflowZone = Long.MIN_VALUE / 10;
+    long overflowDigit = (Long.MIN_VALUE % 10) + 1;
+
+    do {
+      Segment segment = head;
+
+      byte[] data = segment.data;
+      int pos = segment.pos;
+      int limit = segment.limit;
+
+      for (; pos < limit; pos++, seen++) {
+        byte b = data[pos];
+        if (b >= '0' && b <= '9') {
+          int digit = '0' - b;
+
+          // Detect when the digit would cause an overflow.
+          if (value < overflowZone || value == overflowZone && digit < overflowDigit) {
+            Buffer buffer = new Buffer().writeDecimalLong(value).writeByte(b);
+            if (!negative) buffer.readByte(); // Skip negative sign.
+            throw new NumberFormatException("Number too large: " + buffer.readUtf8());
+          }
+          value *= 10;
+          value += digit;
+        } else if (b == '-' && seen == 0) {
+          negative = true;
+          overflowDigit -= 1;
+        } else {
+          if (seen == 0) {
+            throw new NumberFormatException(
+                "Expected leading [0-9] or '-' character but was 0x" + Integer.toHexString(b));
+          }
+          // Set a flag to stop iteration. We still need to run through segment updating below.
+          done = true;
+          break;
+        }
+      }
+
+      if (pos == limit) {
+        head = segment.pop();
+        SegmentPool.recycle(segment);
+      } else {
+        segment.pos = pos;
+      }
+    } while (!done && head != null);
+
+    size -= seen;
+    return negative ? value : -value;
+  }
+
+  @Override public long readHexadecimalUnsignedLong() {
+    if (size == 0) throw new IllegalStateException("size == 0");
+
+    long value = 0;
+    int seen = 0;
+    boolean done = false;
+
+    do {
+      Segment segment = head;
+
+      byte[] data = segment.data;
+      int pos = segment.pos;
+      int limit = segment.limit;
+
+      for (; pos < limit; pos++, seen++) {
+        int digit;
+
+        byte b = data[pos];
+        if (b >= '0' && b <= '9') {
+          digit = b - '0';
+        } else if (b >= 'a' && b <= 'f') {
+          digit = b - 'a' + 10;
+        } else if (b >= 'A' && b <= 'F') {
+          digit = b - 'A' + 10; // We never write uppercase, but we support reading it.
+        } else {
+          if (seen == 0) {
+            throw new NumberFormatException(
+                "Expected leading [0-9a-fA-F] character but was 0x" + Integer.toHexString(b));
+          }
+          // Set a flag to stop iteration. We still need to run through segment updating below.
+          done = true;
+          break;
+        }
+
+        // Detect when the shift will overflow.
+        if ((value & 0xf000000000000000L) != 0) {
+          Buffer buffer = new Buffer().writeHexadecimalUnsignedLong(value).writeByte(b);
+          throw new NumberFormatException("Number too large: " + buffer.readUtf8());
+        }
+
+        value <<= 4;
+        value |= digit;
+      }
+
+      if (pos == limit) {
+        head = segment.pop();
+        SegmentPool.recycle(segment);
+      } else {
+        segment.pos = pos;
+      }
+    } while (!done && head != null);
+
+    size -= seen;
+    return value;
+  }
+
+  @Override public ByteString readByteString() {
+    return new ByteString(readByteArray());
+  }
+
+  @Override public ByteString readByteString(long byteCount) throws EOFException {
+    return new ByteString(readByteArray(byteCount));
+  }
+
+  @Override public void readFully(Buffer sink, long byteCount) throws EOFException {
+    if (size < byteCount) {
+      sink.write(this, size); // Exhaust ourselves.
+      throw new EOFException();
+    }
+    sink.write(this, byteCount);
+  }
+
+  @Override public long readAll(Sink sink) throws IOException {
+    long byteCount = size;
+    if (byteCount > 0) {
+      sink.write(this, byteCount);
+    }
+    return byteCount;
+  }
+
+  @Override public String readUtf8() {
+    try {
+      return readString(size, Util.UTF_8);
+    } catch (EOFException e) {
+      throw new AssertionError(e);
+    }
+  }
+
+  @Override public String readUtf8(long byteCount) throws EOFException {
+    return readString(byteCount, Util.UTF_8);
+  }
+
+  @Override public String readString(Charset charset) {
+    try {
+      return readString(size, charset);
+    } catch (EOFException e) {
+      throw new AssertionError(e);
+    }
+  }
+
+  @Override public String readString(long byteCount, Charset charset) throws EOFException {
+    checkOffsetAndCount(size, 0, byteCount);
+    if (charset == null) throw new IllegalArgumentException("charset == null");
+    if (byteCount > Integer.MAX_VALUE) {
+      throw new IllegalArgumentException("byteCount > Integer.MAX_VALUE: " + byteCount);
+    }
+    if (byteCount == 0) return "";
+
+    Segment s = head;
+    if (s.pos + byteCount > s.limit) {
+      // If the string spans multiple segments, delegate to readBytes().
+      return new String(readByteArray(byteCount), charset);
+    }
+
+    String result = new String(s.data, s.pos, (int) byteCount, charset);
+    s.pos += byteCount;
+    size -= byteCount;
+
+    if (s.pos == s.limit) {
+      head = s.pop();
+      SegmentPool.recycle(s);
+    }
+
+    return result;
+  }
+
+  @Override public String readUtf8Line() throws EOFException {
+    long newline = indexOf((byte) '\n');
+
+    if (newline == -1) {
+      return size != 0 ? readUtf8(size) : null;
+    }
+
+    return readUtf8Line(newline);
+  }
+
+  @Override public String readUtf8LineStrict() throws EOFException {
+    long newline = indexOf((byte) '\n');
+    if (newline == -1) {
+      Buffer data = new Buffer();
+      copyTo(data, 0, Math.min(32, size));
+      throw new EOFException("\\n not found: size=" + size()
+          + " content=" + data.readByteString().hex() + "...");
+    }
+    return readUtf8Line(newline);
+  }
+
+  String readUtf8Line(long newline) throws EOFException {
+    if (newline > 0 && getByte(newline - 1) == '\r') {
+      // Read everything until '\r\n', then skip the '\r\n'.
+      String result = readUtf8((newline - 1));
+      skip(2);
+      return result;
+
+    } else {
+      // Read everything until '\n', then skip the '\n'.
+      String result = readUtf8(newline);
+      skip(1);
+      return result;
+    }
+  }
+
+  @Override public int readUtf8CodePoint() throws EOFException {
+    if (size == 0) throw new EOFException();
+
+    byte b0 = getByte(0);
+    int codePoint;
+    int byteCount;
+    int min;
+
+    if ((b0 & 0x80) == 0) {
+      // 0xxxxxxx.
+      codePoint = b0 & 0x7f;
+      byteCount = 1; // 7 bits (ASCII).
+      min = 0x0;
+
+    } else if ((b0 & 0xe0) == 0xc0) {
+      // 0x110xxxxx
+      codePoint = b0 & 0x1f;
+      byteCount = 2; // 11 bits (5 + 6).
+      min = 0x80;
+
+    } else if ((b0 & 0xf0) == 0xe0) {
+      // 0x1110xxxx
+      codePoint = b0 & 0x0f;
+      byteCount = 3; // 16 bits (4 + 6 + 6).
+      min = 0x800;
+
+    } else if ((b0 & 0xf8) == 0xf0) {
+      // 0x11110xxx
+      codePoint = b0 & 0x07;
+      byteCount = 4; // 21 bits (3 + 6 + 6 + 6).
+      min = 0x10000;
+
+    } else {
+      // We expected the first byte of a code point but got something else.
+      skip(1);
+      return REPLACEMENT_CHARACTER;
+    }
+
+    if (size < byteCount) {
+      throw new EOFException("size < " + byteCount + ": " + size
+          + " (to read code point prefixed 0x" + Integer.toHexString(b0) + ")");
+    }
+
+    // Read the continuation bytes. If we encounter a non-continuation byte, the sequence consumed
+    // thus far is truncated and is decoded as the replacement character. That non-continuation byte
+    // is left in the stream for processing by the next call to readUtf8CodePoint().
+    for (int i = 1; i < byteCount; i++) {
+      byte b = getByte(i);
+      if ((b & 0xc0) == 0x80) {
+        // 0x10xxxxxx
+        codePoint <<= 6;
+        codePoint |= b & 0x3f;
+      } else {
+        skip(i);
+        return REPLACEMENT_CHARACTER;
+      }
+    }
+
+    skip(byteCount);
+
+    if (codePoint > 0x10ffff) {
+      return REPLACEMENT_CHARACTER; // Reject code points larger than the Unicode maximum.
+    }
+
+    if (codePoint >= 0xd800 && codePoint <= 0xdfff) {
+      return REPLACEMENT_CHARACTER; // Reject partial surrogates.
+    }
+
+    if (codePoint < min) {
+      return REPLACEMENT_CHARACTER; // Reject overlong code points.
+    }
+
+    return codePoint;
+  }
+
+  @Override public byte[] readByteArray() {
+    try {
+      return readByteArray(size);
+    } catch (EOFException e) {
+      throw new AssertionError(e);
+    }
+  }
+
+  @Override public byte[] readByteArray(long byteCount) throws EOFException {
+    checkOffsetAndCount(size, 0, byteCount);
+    if (byteCount > Integer.MAX_VALUE) {
+      throw new IllegalArgumentException("byteCount > Integer.MAX_VALUE: " + byteCount);
+    }
+
+    byte[] result = new byte[(int) byteCount];
+    readFully(result);
+    return result;
+  }
+
+  @Override public int read(byte[] sink) {
+    return read(sink, 0, sink.length);
+  }
+
+  @Override public void readFully(byte[] sink) throws EOFException {
+    int offset = 0;
+    while (offset < sink.length) {
+      int read = read(sink, offset, sink.length - offset);
+      if (read == -1) throw new EOFException();
+      offset += read;
+    }
+  }
+
+  @Override public int read(byte[] sink, int offset, int byteCount) {
+    checkOffsetAndCount(sink.length, offset, byteCount);
+
+    Segment s = head;
+    if (s == null) return -1;
+    int toCopy = Math.min(byteCount, s.limit - s.pos);
+    System.arraycopy(s.data, s.pos, sink, offset, toCopy);
+
+    s.pos += toCopy;
+    size -= toCopy;
+
+    if (s.pos == s.limit) {
+      head = s.pop();
+      SegmentPool.recycle(s);
+    }
+
+    return toCopy;
+  }
+
+  /**
+   * Discards all bytes in this buffer. Calling this method when you're done
+   * with a buffer will return its segments to the pool.
+   */
+  public void clear() {
+    try {
+      skip(size);
+    } catch (EOFException e) {
+      throw new AssertionError(e);
+    }
+  }
+
+  /** Discards {@code byteCount} bytes from the head of this buffer. */
+  @Override public void skip(long byteCount) throws EOFException {
+    while (byteCount > 0) {
+      if (head == null) throw new EOFException();
+
+      int toSkip = (int) Math.min(byteCount, head.limit - head.pos);
+      size -= toSkip;
+      byteCount -= toSkip;
+      head.pos += toSkip;
+
+      if (head.pos == head.limit) {
+        Segment toRecycle = head;
+        head = toRecycle.pop();
+        SegmentPool.recycle(toRecycle);
+      }
+    }
+  }
+
+  @Override public Buffer write(ByteString byteString) {
+    if (byteString == null) throw new IllegalArgumentException("byteString == null");
+    byteString.write(this);
+    return this;
+  }
+
+  @Override public Buffer writeUtf8(String string) {
+    return writeUtf8(string, 0, string.length());
+  }
+
+  @Override public Buffer writeUtf8(String string, int beginIndex, int endIndex) {
+    if (string == null) throw new IllegalArgumentException("string == null");
+    if (beginIndex < 0) throw new IllegalAccessError("beginIndex < 0: " + beginIndex);
+    if (endIndex < beginIndex) {
+      throw new IllegalArgumentException("endIndex < beginIndex: " + endIndex + " < " + beginIndex);
+    }
+    if (endIndex > string.length()) {
+      throw new IllegalArgumentException(
+          "endIndex > string.length: " + endIndex + " > " + string.length());
+    }
+
+    // Transcode a UTF-16 Java String to UTF-8 bytes.
+    for (int i = beginIndex; i < endIndex;) {
+      int c = string.charAt(i);
+
+      if (c < 0x80) {
+        Segment tail = writableSegment(1);
+        byte[] data = tail.data;
+        int segmentOffset = tail.limit - i;
+        int runLimit = Math.min(endIndex, Segment.SIZE - segmentOffset);
+
+        // Emit a 7-bit character with 1 byte.
+        data[segmentOffset + i++] = (byte) c; // 0xxxxxxx
+
+        // Fast-path contiguous runs of ASCII characters. This is ugly, but yields a ~4x performance
+        // improvement over independent calls to writeByte().
+        while (i < runLimit) {
+          c = string.charAt(i);
+          if (c >= 0x80) break;
+          data[segmentOffset + i++] = (byte) c; // 0xxxxxxx
+        }
+
+        int runSize = i + segmentOffset - tail.limit; // Equivalent to i - (previous i).
+        tail.limit += runSize;
+        size += runSize;
+
+      } else if (c < 0x800) {
+        // Emit a 11-bit character with 2 bytes.
+        writeByte(c >>  6        | 0xc0); // 110xxxxx
+        writeByte(c       & 0x3f | 0x80); // 10xxxxxx
+        i++;
+
+      } else if (c < 0xd800 || c > 0xdfff) {
+        // Emit a 16-bit character with 3 bytes.
+        writeByte(c >> 12        | 0xe0); // 1110xxxx
+        writeByte(c >>  6 & 0x3f | 0x80); // 10xxxxxx
+        writeByte(c       & 0x3f | 0x80); // 10xxxxxx
+        i++;
+
+      } else {
+        // c is a surrogate. Make sure it is a high surrogate & that its successor is a low
+        // surrogate. If not, the UTF-16 is invalid, in which case we emit a replacement character.
+        int low = i + 1 < endIndex ? string.charAt(i + 1) : 0;
+        if (c > 0xdbff || low < 0xdc00 || low > 0xdfff) {
+          writeByte('?');
+          i++;
+          continue;
+        }
+
+        // UTF-16 high surrogate: 110110xxxxxxxxxx (10 bits)
+        // UTF-16 low surrogate:  110111yyyyyyyyyy (10 bits)
+        // Unicode code point:    00010000000000000000 + xxxxxxxxxxyyyyyyyyyy (21 bits)
+        int codePoint = 0x010000 + ((c & ~0xd800) << 10 | low & ~0xdc00);
+
+        // Emit a 21-bit character with 4 bytes.
+        writeByte(codePoint >> 18        | 0xf0); // 11110xxx
+        writeByte(codePoint >> 12 & 0x3f | 0x80); // 10xxxxxx
+        writeByte(codePoint >>  6 & 0x3f | 0x80); // 10xxyyyy
+        writeByte(codePoint       & 0x3f | 0x80); // 10yyyyyy
+        i += 2;
+      }
+    }
+
+    return this;
+  }
+
+  @Override public Buffer writeUtf8CodePoint(int codePoint) {
+    if (codePoint < 0x80) {
+      // Emit a 7-bit code point with 1 byte.
+      writeByte(codePoint);
+
+    } else if (codePoint < 0x800) {
+      // Emit a 11-bit code point with 2 bytes.
+      writeByte(codePoint >>  6        | 0xc0); // 110xxxxx
+      writeByte(codePoint       & 0x3f | 0x80); // 10xxxxxx
+
+    } else if (codePoint < 0x10000) {
+      if (codePoint >= 0xd800 && codePoint <= 0xdfff) {
+        throw new IllegalArgumentException(
+            "Unexpected code point: " + Integer.toHexString(codePoint));
+      }
+
+      // Emit a 16-bit code point with 3 bytes.
+      writeByte(codePoint >> 12        | 0xe0); // 1110xxxx
+      writeByte(codePoint >>  6 & 0x3f | 0x80); // 10xxxxxx
+      writeByte(codePoint       & 0x3f | 0x80); // 10xxxxxx
+
+    } else if (codePoint <= 0x10ffff) {
+      // Emit a 21-bit code point with 4 bytes.
+      writeByte(codePoint >> 18        | 0xf0); // 11110xxx
+      writeByte(codePoint >> 12 & 0x3f | 0x80); // 10xxxxxx
+      writeByte(codePoint >>  6 & 0x3f | 0x80); // 10xxxxxx
+      writeByte(codePoint       & 0x3f | 0x80); // 10xxxxxx
+
+    } else {
+      throw new IllegalArgumentException(
+          "Unexpected code point: " + Integer.toHexString(codePoint));
+    }
+
+    return this;
+  }
+
+  @Override public Buffer writeString(String string, Charset charset) {
+    return writeString(string, 0, string.length(), charset);
+  }
+
+  @Override
+  public Buffer writeString(String string, int beginIndex, int endIndex, Charset charset) {
+    if (string == null) throw new IllegalArgumentException("string == null");
+    if (beginIndex < 0) throw new IllegalAccessError("beginIndex < 0: " + beginIndex);
+    if (endIndex < beginIndex) {
+      throw new IllegalArgumentException("endIndex < beginIndex: " + endIndex + " < " + beginIndex);
+    }
+    if (endIndex > string.length()) {
+      throw new IllegalArgumentException(
+          "endIndex > string.length: " + endIndex + " > " + string.length());
+    }
+    if (charset == null) throw new IllegalArgumentException("charset == null");
+    if (charset.equals(Util.UTF_8)) return writeUtf8(string);
+    byte[] data = string.substring(beginIndex, endIndex).getBytes(charset);
+    return write(data, 0, data.length);
+  }
+
+  @Override public Buffer write(byte[] source) {
+    if (source == null) throw new IllegalArgumentException("source == null");
+    return write(source, 0, source.length);
+  }
+
+  @Override public Buffer write(byte[] source, int offset, int byteCount) {
+    if (source == null) throw new IllegalArgumentException("source == null");
+    checkOffsetAndCount(source.length, offset, byteCount);
+
+    int limit = offset + byteCount;
+    while (offset < limit) {
+      Segment tail = writableSegment(1);
+
+      int toCopy = Math.min(limit - offset, Segment.SIZE - tail.limit);
+      System.arraycopy(source, offset, tail.data, tail.limit, toCopy);
+
+      offset += toCopy;
+      tail.limit += toCopy;
+    }
+
+    size += byteCount;
+    return this;
+  }
+
+  @Override public long writeAll(Source source) throws IOException {
+    if (source == null) throw new IllegalArgumentException("source == null");
+    long totalBytesRead = 0;
+    for (long readCount; (readCount = source.read(this, Segment.SIZE)) != -1; ) {
+      totalBytesRead += readCount;
+    }
+    return totalBytesRead;
+  }
+
+  @Override public BufferedSink write(Source source, long byteCount) throws IOException {
+    while (byteCount > 0) {
+      long read = source.read(this, byteCount);
+      if (read == -1) throw new EOFException();
+      byteCount -= read;
+    }
+    return this;
+  }
+
+  @Override public Buffer writeByte(int b) {
+    Segment tail = writableSegment(1);
+    tail.data[tail.limit++] = (byte) b;
+    size += 1;
+    return this;
+  }
+
+  @Override public Buffer writeShort(int s) {
+    Segment tail = writableSegment(2);
+    byte[] data = tail.data;
+    int limit = tail.limit;
+    data[limit++] = (byte) ((s >>> 8) & 0xff);
+    data[limit++] = (byte)  (s        & 0xff);
+    tail.limit = limit;
+    size += 2;
+    return this;
+  }
+
+  @Override public Buffer writeShortLe(int s) {
+    return writeShort(Util.reverseBytesShort((short) s));
+  }
+
+  @Override public Buffer writeInt(int i) {
+    Segment tail = writableSegment(4);
+    byte[] data = tail.data;
+    int limit = tail.limit;
+    data[limit++] = (byte) ((i >>> 24) & 0xff);
+    data[limit++] = (byte) ((i >>> 16) & 0xff);
+    data[limit++] = (byte) ((i >>>  8) & 0xff);
+    data[limit++] = (byte)  (i         & 0xff);
+    tail.limit = limit;
+    size += 4;
+    return this;
+  }
+
+  @Override public Buffer writeIntLe(int i) {
+    return writeInt(Util.reverseBytesInt(i));
+  }
+
+  @Override public Buffer writeLong(long v) {
+    Segment tail = writableSegment(8);
+    byte[] data = tail.data;
+    int limit = tail.limit;
+    data[limit++] = (byte) ((v >>> 56L) & 0xff);
+    data[limit++] = (byte) ((v >>> 48L) & 0xff);
+    data[limit++] = (byte) ((v >>> 40L) & 0xff);
+    data[limit++] = (byte) ((v >>> 32L) & 0xff);
+    data[limit++] = (byte) ((v >>> 24L) & 0xff);
+    data[limit++] = (byte) ((v >>> 16L) & 0xff);
+    data[limit++] = (byte) ((v >>>  8L) & 0xff);
+    data[limit++] = (byte)  (v          & 0xff);
+    tail.limit = limit;
+    size += 8;
+    return this;
+  }
+
+  @Override public Buffer writeLongLe(long v) {
+    return writeLong(reverseBytesLong(v));
+  }
+
+  @Override public Buffer writeDecimalLong(long v) {
+    if (v == 0) {
+      // Both a shortcut and required since the following code can't handle zero.
+      return writeByte('0');
+    }
+
+    boolean negative = false;
+    if (v < 0) {
+      v = -v;
+      if (v < 0) { // Only true for Long.MIN_VALUE.
+        return writeUtf8("-9223372036854775808");
+      }
+      negative = true;
+    }
+
+    // Binary search for character width which favors matching lower numbers.
+    int width = //
+          v < 100000000L
+        ? v < 10000L
+        ? v < 100L
+        ? v < 10L ? 1 : 2
+        : v < 1000L ? 3 : 4
+        : v < 1000000L
+        ? v < 100000L ? 5 : 6
+        : v < 10000000L ? 7 : 8
+        : v < 1000000000000L
+        ? v < 10000000000L
+        ? v < 1000000000L ? 9 : 10
+        : v < 100000000000L ? 11 : 12
+        : v < 1000000000000000L
+        ? v < 10000000000000L ? 13
+        : v < 100000000000000L ? 14 : 15
+        : v < 100000000000000000L
+        ? v < 10000000000000000L ? 16 : 17
+        : v < 1000000000000000000L ? 18 : 19;
+    if (negative) {
+      ++width;
+    }
+
+    Segment tail = writableSegment(width);
+    byte[] data = tail.data;
+    int pos = tail.limit + width; // We write backwards from right to left.
+    while (v != 0) {
+      int digit = (int) (v % 10);
+      data[--pos] = DIGITS[digit];
+      v /= 10;
+    }
+    if (negative) {
+      data[--pos] = '-';
+    }
+
+    tail.limit += width;
+    this.size += width;
+    return this;
+  }
+
+  @Override public Buffer writeHexadecimalUnsignedLong(long v) {
+    if (v == 0) {
+      // Both a shortcut and required since the following code can't handle zero.
+      return writeByte('0');
+    }
+
+    int width = Long.numberOfTrailingZeros(Long.highestOneBit(v)) / 4 + 1;
+
+    Segment tail = writableSegment(width);
+    byte[] data = tail.data;
+    for (int pos = tail.limit + width - 1, start = tail.limit; pos >= start; pos--) {
+      data[pos] = DIGITS[(int) (v & 0xF)];
+      v >>>= 4;
+    }
+    tail.limit += width;
+    size += width;
+    return this;
+  }
+
+  /**
+   * Returns a tail segment that we can write at least {@code minimumCapacity}
+   * bytes to, creating it if necessary.
+   */
+  Segment writableSegment(int minimumCapacity) {
+    if (minimumCapacity < 1 || minimumCapacity > Segment.SIZE) throw new IllegalArgumentException();
+
+    if (head == null) {
+      head = SegmentPool.take(); // Acquire a first segment.
+      return head.next = head.prev = head;
+    }
+
+    Segment tail = head.prev;
+    if (tail.limit + minimumCapacity > Segment.SIZE || !tail.owner) {
+      tail = tail.push(SegmentPool.take()); // Append a new empty segment to fill up.
+    }
+    return tail;
+  }
+
+  @Override public void write(Buffer source, long byteCount) {
+    // Move bytes from the head of the source buffer to the tail of this buffer
+    // while balancing two conflicting goals: don't waste CPU and don't waste
+    // memory.
+    //
+    //
+    // Don't waste CPU (ie. don't copy data around).
+    //
+    // Copying large amounts of data is expensive. Instead, we prefer to
+    // reassign entire segments from one buffer to the other.
+    //
+    //
+    // Don't waste memory.
+    //
+    // As an invariant, adjacent pairs of segments in a buffer should be at
+    // least 50% full, except for the head segment and the tail segment.
+    //
+    // The head segment cannot maintain the invariant because the application is
+    // consuming bytes from this segment, decreasing its level.
+    //
+    // The tail segment cannot maintain the invariant because the application is
+    // producing bytes, which may require new nearly-empty tail segments to be
+    // appended.
+    //
+    //
+    // Moving segments between buffers
+    //
+    // When writing one buffer to another, we prefer to reassign entire segments
+    // over copying bytes into their most compact form. Suppose we have a buffer
+    // with these segment levels [91%, 61%]. If we append a buffer with a
+    // single [72%] segment, that yields [91%, 61%, 72%]. No bytes are copied.
+    //
+    // Or suppose we have a buffer with these segment levels: [100%, 2%], and we
+    // want to append it to a buffer with these segment levels [99%, 3%]. This
+    // operation will yield the following segments: [100%, 2%, 99%, 3%]. That
+    // is, we do not spend time copying bytes around to achieve more efficient
+    // memory use like [100%, 100%, 4%].
+    //
+    // When combining buffers, we will compact adjacent buffers when their
+    // combined level doesn't exceed 100%. For example, when we start with
+    // [100%, 40%] and append [30%, 80%], the result is [100%, 70%, 80%].
+    //
+    //
+    // Splitting segments
+    //
+    // Occasionally we write only part of a source buffer to a sink buffer. For
+    // example, given a sink [51%, 91%], we may want to write the first 30% of
+    // a source [92%, 82%] to it. To simplify, we first transform the source to
+    // an equivalent buffer [30%, 62%, 82%] and then move the head segment,
+    // yielding sink [51%, 91%, 30%] and source [62%, 82%].
+
+    if (source == null) throw new IllegalArgumentException("source == null");
+    if (source == this) throw new IllegalArgumentException("source == this");
+    checkOffsetAndCount(source.size, 0, byteCount);
+
+    while (byteCount > 0) {
+      // Is a prefix of the source's head segment all that we need to move?
+      if (byteCount < (source.head.limit - source.head.pos)) {
+        Segment tail = head != null ? head.prev : null;
+        if (tail != null && tail.owner
+            && (byteCount + tail.limit - (tail.shared ? 0 : tail.pos) <= Segment.SIZE)) {
+          // Our existing segments are sufficient. Move bytes from source's head to our tail.
+          source.head.writeTo(tail, (int) byteCount);
+          source.size -= byteCount;
+          size += byteCount;
+          return;
+        } else {
+          // We're going to need another segment. Split the source's head
+          // segment in two, then move the first of those two to this buffer.
+          source.head = source.head.split((int) byteCount);
+        }
+      }
+
+      // Remove the source's head segment and append it to our tail.
+      Segment segmentToMove = source.head;
+      long movedByteCount = segmentToMove.limit - segmentToMove.pos;
+      source.head = segmentToMove.pop();
+      if (head == null) {
+        head = segmentToMove;
+        head.next = head.prev = head;
+      } else {
+        Segment tail = head.prev;
+        tail = tail.push(segmentToMove);
+        tail.compact();
+      }
+      source.size -= movedByteCount;
+      size += movedByteCount;
+      byteCount -= movedByteCount;
+    }
+  }
+
+  @Override public long read(Buffer sink, long byteCount) {
+    if (sink == null) throw new IllegalArgumentException("sink == null");
+    if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
+    if (size == 0) return -1L;
+    if (byteCount > size) byteCount = size;
+    sink.write(this, byteCount);
+    return byteCount;
+  }
+
+  @Override public long indexOf(byte b) {
+    return indexOf(b, 0);
+  }
+
+  /**
+   * Returns the index of {@code b} in this at or beyond {@code fromIndex}, or
+   * -1 if this buffer does not contain {@code b} in that range.
+   */
+  @Override public long indexOf(byte b, long fromIndex) {
+    if (fromIndex < 0) throw new IllegalArgumentException("fromIndex < 0");
+
+    Segment s = head;
+    if (s == null) return -1L;
+    long offset = 0L;
+    do {
+      int segmentByteCount = s.limit - s.pos;
+      if (fromIndex >= segmentByteCount) {
+        fromIndex -= segmentByteCount;
+      } else {
+        byte[] data = s.data;
+        for (int pos = (int) (s.pos + fromIndex), limit = s.limit; pos < limit; pos++) {
+          if (data[pos] == b) return offset + pos - s.pos;
+        }
+        fromIndex = 0;
+      }
+      offset += segmentByteCount;
+      s = s.next;
+    } while (s != head);
+    return -1L;
+  }
+
+  @Override public long indexOf(ByteString bytes) throws IOException {
+    return indexOf(bytes, 0);
+  }
+
+  @Override public long indexOf(ByteString bytes, long fromIndex) throws IOException {
+    if (bytes.size() == 0) throw new IllegalArgumentException("bytes is empty");
+    while (true) {
+      fromIndex = indexOf(bytes.getByte(0), fromIndex);
+      if (fromIndex == -1) {
+        return -1;
+      }
+      if (rangeEquals(fromIndex, bytes)) {
+        return fromIndex;
+      }
+      fromIndex++;
+    }
+  }
+
+  @Override public long indexOfElement(ByteString targetBytes) {
+    return indexOfElement(targetBytes, 0);
+  }
+
+  @Override public long indexOfElement(ByteString targetBytes, long fromIndex) {
+    if (fromIndex < 0) throw new IllegalArgumentException("fromIndex < 0");
+
+    Segment s = head;
+    if (s == null) return -1L;
+    long offset = 0L;
+    byte[] toFind = targetBytes.toByteArray();
+    do {
+      int segmentByteCount = s.limit - s.pos;
+      if (fromIndex >= segmentByteCount) {
+        fromIndex -= segmentByteCount;
+      } else {
+        byte[] data = s.data;
+        for (long pos = s.pos + fromIndex, limit = s.limit; pos < limit; pos++) {
+          byte b = data[(int) pos];
+          for (byte targetByte : toFind) {
+            if (b == targetByte) return offset + pos - s.pos;
+          }
+        }
+        fromIndex = 0;
+      }
+      offset += segmentByteCount;
+      s = s.next;
+    } while (s != head);
+    return -1L;
+  }
+
+  boolean rangeEquals(long offset, ByteString bytes) {
+    int byteCount = bytes.size();
+    if (size - offset < byteCount) {
+      return false;
+    }
+    for (int i = 0; i < byteCount; i++) {
+      if (getByte(offset + i) != bytes.getByte(i)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  @Override public void flush() {
+  }
+
+  @Override public void close() {
+  }
+
+  @Override public Timeout timeout() {
+    return Timeout.NONE;
+  }
+
+  /** For testing. This returns the sizes of the segments in this buffer. */
+  List<Integer> segmentSizes() {
+    if (head == null) return Collections.emptyList();
+    List<Integer> result = new ArrayList<>();
+    result.add(head.limit - head.pos);
+    for (Segment s = head.next; s != head; s = s.next) {
+      result.add(s.limit - s.pos);
+    }
+    return result;
+  }
+
+  @Override public boolean equals(Object o) {
+    if (this == o) return true;
+    if (!(o instanceof Buffer)) return false;
+    Buffer that = (Buffer) o;
+    if (size != that.size) return false;
+    if (size == 0) return true; // Both buffers are empty.
+
+    Segment sa = this.head;
+    Segment sb = that.head;
+    int posA = sa.pos;
+    int posB = sb.pos;
+
+    for (long pos = 0, count; pos < size; pos += count) {
+      count = Math.min(sa.limit - posA, sb.limit - posB);
+
+      for (int i = 0; i < count; i++) {
+        if (sa.data[posA++] != sb.data[posB++]) return false;
+      }
+
+      if (posA == sa.limit) {
+        sa = sa.next;
+        posA = sa.pos;
+      }
+
+      if (posB == sb.limit) {
+        sb = sb.next;
+        posB = sb.pos;
+      }
+    }
+
+    return true;
+  }
+
+  @Override public int hashCode() {
+    Segment s = head;
+    if (s == null) return 0;
+    int result = 1;
+    do {
+      for (int pos = s.pos, limit = s.limit; pos < limit; pos++) {
+        result = 31 * result + s.data[pos];
+      }
+      s = s.next;
+    } while (s != head);
+    return result;
+  }
+
+  @Override public String toString() {
+    if (size == 0) {
+      return "Buffer[size=0]";
+    }
+
+    if (size <= 16) {
+      ByteString data = clone().readByteString();
+      return String.format("Buffer[size=%s data=%s]", size, data.hex());
+    }
+
+    try {
+      MessageDigest md5 = MessageDigest.getInstance("MD5");
+      md5.update(head.data, head.pos, head.limit - head.pos);
+      for (Segment s = head.next; s != head; s = s.next) {
+        md5.update(s.data, s.pos, s.limit - s.pos);
+      }
+      return String.format("Buffer[size=%s md5=%s]",
+          size, ByteString.of(md5.digest()).hex());
+    } catch (NoSuchAlgorithmException e) {
+      throw new AssertionError();
+    }
+  }
+
+  /** Returns a deep copy of this buffer. */
+  @Override public Buffer clone() {
+    Buffer result = new Buffer();
+    if (size == 0) return result;
+
+    result.head = new Segment(head);
+    result.head.next = result.head.prev = result.head;
+    for (Segment s = head.next; s != head; s = s.next) {
+      result.head.prev.push(new Segment(s));
+    }
+    result.size = size;
+    return result;
+  }
+
+  /** Returns an immutable copy of this buffer as a byte string. */
+  public ByteString snapshot() {
+    if (size > Integer.MAX_VALUE) {
+      throw new IllegalArgumentException("size > Integer.MAX_VALUE: " + size);
+    }
+    return snapshot((int) size);
+  }
+
+  /**
+   * Returns an immutable copy of the first {@code byteCount} bytes of this buffer as a byte string.
+   */
+  public ByteString snapshot(int byteCount) {
+    if (byteCount == 0) return ByteString.EMPTY;
+    return new SegmentedByteString(this, byteCount);
+  }
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/BufferedSink.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/BufferedSink.java
new file mode 100644
index 0000000..7dd3f13
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/BufferedSink.java
@@ -0,0 +1,119 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.okio;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+
+/**
+ * A sink that keeps a buffer internally so that callers can do small writes
+ * without a performance penalty.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface BufferedSink extends Sink {
+  /** Returns this sink's internal buffer. */
+  Buffer buffer();
+
+  BufferedSink write(ByteString byteString) throws IOException;
+
+  /**
+   * Like {@link OutputStream#write(byte[])}, this writes a complete byte array to
+   * this sink.
+   */
+  BufferedSink write(byte[] source) throws IOException;
+
+  /**
+   * Like {@link OutputStream#write(byte[], int, int)}, this writes {@code byteCount}
+   * bytes of {@code source}, starting at {@code offset}.
+   */
+  BufferedSink write(byte[] source, int offset, int byteCount) throws IOException;
+
+  /**
+   * Removes all bytes from {@code source} and appends them to this sink. Returns the
+   * number of bytes read which will be 0 if {@code source} is exhausted.
+   */
+  long writeAll(Source source) throws IOException;
+
+  /** Removes {@code byteCount} bytes from {@code source} and appends them to this sink. */
+  BufferedSink write(Source source, long byteCount) throws IOException;
+
+  /** Encodes {@code string} in UTF-8 and writes it to this sink. */
+  BufferedSink writeUtf8(String string) throws IOException;
+
+  /**
+   * Encodes the characters at {@code beginIndex} up to {@code endIndex} from {@code string} in
+   * UTF-8 and writes it to this sink.
+   */
+  BufferedSink writeUtf8(String string, int beginIndex, int endIndex) throws IOException;
+
+  /** Encodes {@code codePoint} in UTF-8 and writes it to this sink. */
+  BufferedSink writeUtf8CodePoint(int codePoint) throws IOException;
+
+  /** Encodes {@code string} in {@code charset} and writes it to this sink. */
+  BufferedSink writeString(String string, Charset charset) throws IOException;
+
+  /**
+   * Encodes the characters at {@code beginIndex} up to {@code endIndex} from {@code string} in
+   * {@code charset} and writes it to this sink.
+   */
+  BufferedSink writeString(String string, int beginIndex, int endIndex, Charset charset)
+      throws IOException;
+
+  /** Writes a byte to this sink. */
+  BufferedSink writeByte(int b) throws IOException;
+
+  /** Writes a big-endian short to this sink using two bytes. */
+  BufferedSink writeShort(int s) throws IOException;
+
+  /** Writes a little-endian short to this sink using two bytes. */
+  BufferedSink writeShortLe(int s) throws IOException;
+
+  /** Writes a big-endian int to this sink using four bytes. */
+  BufferedSink writeInt(int i) throws IOException;
+
+  /** Writes a little-endian int to this sink using four bytes. */
+  BufferedSink writeIntLe(int i) throws IOException;
+
+  /** Writes a big-endian long to this sink using eight bytes. */
+  BufferedSink writeLong(long v) throws IOException;
+
+  /** Writes a little-endian long to this sink using eight bytes. */
+  BufferedSink writeLongLe(long v) throws IOException;
+
+  /** Writes a long to this sink in signed decimal form (i.e., as a string in base 10). */
+  BufferedSink writeDecimalLong(long v) throws IOException;
+
+  /** Writes a long to this sink in hexadecimal form (i.e., as a string in base 16). */
+  BufferedSink writeHexadecimalUnsignedLong(long v) throws IOException;
+
+  /**
+   * Writes complete segments to the underlying sink, if one exists. Like {@link #flush}, but
+   * weaker. Use this to limit the memory held in the buffer to a single segment.
+   */
+  BufferedSink emitCompleteSegments() throws IOException;
+
+  /**
+   * Writes all buffered data to the underlying sink, if one exists. Like {@link #flush}, but
+   * weaker. Call this before this buffered sink goes out of scope so that its data can reach its
+   * destination.
+   */
+  BufferedSink emit() throws IOException;
+
+  /** Returns an output stream that writes to this sink. */
+  OutputStream outputStream();
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/BufferedSource.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/BufferedSource.java
new file mode 100644
index 0000000..a2fdad8
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/BufferedSource.java
@@ -0,0 +1,253 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.okio;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+
+/**
+ * A source that keeps a buffer internally so that callers can do small reads
+ * without a performance penalty. It also allows clients to read ahead,
+ * buffering as much as necessary before consuming input.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface BufferedSource extends Source {
+  /** Returns this source's internal buffer. */
+  Buffer buffer();
+
+  /**
+   * Returns true if there are no more bytes in this source. This will block
+   * until there are bytes to read or the source is definitely exhausted.
+   */
+  boolean exhausted() throws IOException;
+
+  /**
+   * Returns when the buffer contains at least {@code byteCount} bytes. Throws
+   * an {@link java.io.EOFException} if the source is exhausted before the
+   * required bytes can be read.
+   */
+  void require(long byteCount) throws IOException;
+
+  /**
+   * Returns true when the buffer contains at least {@code byteCount} bytes,
+   * expanding it as necessary. Returns false if the source is exhausted before
+   * the requested bytes can be read.
+   */
+  boolean request(long byteCount) throws IOException;
+
+  /** Removes a byte from this source and returns it. */
+  byte readByte() throws IOException;
+
+  /** Removes two bytes from this source and returns a big-endian short. */
+  short readShort() throws IOException;
+
+  /** Removes two bytes from this source and returns a little-endian short. */
+  short readShortLe() throws IOException;
+
+  /** Removes four bytes from this source and returns a big-endian int. */
+  int readInt() throws IOException;
+
+  /** Removes four bytes from this source and returns a little-endian int. */
+  int readIntLe() throws IOException;
+
+  /** Removes eight bytes from this source and returns a big-endian long. */
+  long readLong() throws IOException;
+
+  /** Removes eight bytes from this source and returns a little-endian long. */
+  long readLongLe() throws IOException;
+
+  /**
+   * Reads a long from this source in signed decimal form (i.e., as a string in base 10 with
+   * optional leading '-'). This will iterate until a non-digit character is found.
+   *
+   * @throws NumberFormatException if the found digits do not fit into a {@code long} or a decimal
+   * number was not present.
+   */
+  long readDecimalLong() throws IOException;
+
+  /**
+   * Reads a long form this source in hexadecimal form (i.e., as a string in base 16). This will
+   * iterate until a non-hexadecimal character is found.
+   *
+   * @throws NumberFormatException if the found hexadecimal does not fit into a {@code long} or
+   * hexadecimal was not found.
+   */
+  long readHexadecimalUnsignedLong() throws IOException;
+
+  /**
+   * Reads and discards {@code byteCount} bytes from this source. Throws an
+   * {@link java.io.EOFException} if the source is exhausted before the
+   * requested bytes can be skipped.
+   */
+  void skip(long byteCount) throws IOException;
+
+  /** Removes all bytes bytes from this and returns them as a byte string. */
+  ByteString readByteString() throws IOException;
+
+  /** Removes {@code byteCount} bytes from this and returns them as a byte string. */
+  ByteString readByteString(long byteCount) throws IOException;
+
+  /** Removes all bytes from this and returns them as a byte array. */
+  byte[] readByteArray() throws IOException;
+
+  /** Removes {@code byteCount} bytes from this and returns them as a byte array. */
+  byte[] readByteArray(long byteCount) throws IOException;
+
+  /**
+   * Removes up to {@code sink.length} bytes from this and copies them into {@code sink}.
+   * Returns the number of bytes read, or -1 if this source is exhausted.
+   */
+  int read(byte[] sink) throws IOException;
+
+  /**
+   * Removes exactly {@code sink.length} bytes from this and copies them into {@code sink}.
+   * Throws an {@link java.io.EOFException} if the requested number of bytes cannot be read.
+   */
+  void readFully(byte[] sink) throws IOException;
+
+  /**
+   * Removes up to {@code byteCount} bytes from this and copies them into {@code sink} at
+   * {@code offset}. Returns the number of bytes read, or -1 if this source is exhausted.
+   */
+  int read(byte[] sink, int offset, int byteCount) throws IOException;
+
+  /**
+   * Removes exactly {@code byteCount} bytes from this and appends them to
+   * {@code sink}. Throws an {@link java.io.EOFException} if the requested
+   * number of bytes cannot be read.
+   */
+  void readFully(Buffer sink, long byteCount) throws IOException;
+
+  /**
+   * Removes all bytes from this and appends them to {@code sink}. Returns the
+   * total number of bytes written to {@code sink} which will be 0 if this is
+   * exhausted.
+   */
+  long readAll(Sink sink) throws IOException;
+
+  /** Removes all bytes from this, decodes them as UTF-8, and returns the string. */
+  String readUtf8() throws IOException;
+
+  /**
+   * Removes {@code byteCount} bytes from this, decodes them as UTF-8, and
+   * returns the string.
+   */
+  String readUtf8(long byteCount) throws IOException;
+
+  /**
+   * Removes and returns characters up to but not including the next line break.
+   * A line break is either {@code "\n"} or {@code "\r\n"}; these characters are
+   * not included in the result.
+   *
+   * <p><strong>On the end of the stream this method returns null,</strong> just
+   * like {@link java.io.BufferedReader}. If the source doesn't end with a line
+   * break then an implicit line break is assumed. Null is returned once the
+   * source is exhausted. Use this for human-generated data, where a trailing
+   * line break is optional.
+   */
+  String readUtf8Line() throws IOException;
+
+  /**
+   * Removes and returns characters up to but not including the next line break.
+   * A line break is either {@code "\n"} or {@code "\r\n"}; these characters are
+   * not included in the result.
+   *
+   * <p><strong>On the end of the stream this method throws.</strong> Every call
+   * must consume either '\r\n' or '\n'. If these characters are absent in the
+   * stream, an {@link java.io.EOFException} is thrown. Use this for
+   * machine-generated data where a missing line break implies truncated input.
+   */
+  String readUtf8LineStrict() throws IOException;
+
+  /**
+   * Removes and returns a single UTF-8 code point, reading between 1 and 4 bytes as necessary.
+   *
+   * <p>If this source is exhausted before a complete code point can be read, this throws an {@link
+   * java.io.EOFException} and consumes no input.
+   *
+   * <p>If this source doesn't start with a properly-encoded UTF-8 code point, this method will
+   * remove 1 or more non-UTF-8 bytes and return the replacement character ({@code U+FFFD}). This
+   * covers encoding problems (the input is not properly-encoded UTF-8), characters out of range
+   * (beyond the 0x10ffff limit of Unicode), code points for UTF-16 surrogates (U+d800..U+dfff) and
+   * overlong encodings (such as {@code 0xc080} for the NUL character in modified UTF-8).
+   */
+  int readUtf8CodePoint() throws IOException;
+
+  /**
+   * Removes all bytes from this, decodes them as {@code charset}, and returns
+   * the string.
+   */
+  String readString(Charset charset) throws IOException;
+
+  /**
+   * Removes {@code byteCount} bytes from this, decodes them as {@code charset},
+   * and returns the string.
+   */
+  String readString(long byteCount, Charset charset) throws IOException;
+
+  /**
+   * Returns the index of the first {@code b} in the buffer. This expands the
+   * buffer as necessary until {@code b} is found. This reads an unbounded
+   * number of bytes into the buffer. Returns -1 if the stream is exhausted
+   * before the requested byte is found.
+   */
+  long indexOf(byte b) throws IOException;
+
+  /**
+   * Returns the index of the first {@code b} in the buffer at or after {@code
+   * fromIndex}. This expands the buffer as necessary until {@code b} is found.
+   * This reads an unbounded number of bytes into the buffer. Returns -1 if the
+   * stream is exhausted before the requested byte is found.
+   */
+  long indexOf(byte b, long fromIndex) throws IOException;
+
+  /**
+   * Returns the index of the first match for {@code bytes} in the buffer. This expands the buffer
+   * as necessary until {@code bytes} is found. This reads an unbounded number of bytes into the
+   * buffer. Returns -1 if the stream is exhausted before the requested bytes are found.
+   */
+  long indexOf(ByteString bytes) throws IOException;
+
+  /**
+   * Returns the index of the first match for {@code bytes} in the buffer at or after {@code
+   * fromIndex}. This expands the buffer as necessary until {@code bytes} is found. This reads an
+   * unbounded number of bytes into the buffer. Returns -1 if the stream is exhausted before the
+   * requested bytes are found.
+   */
+  long indexOf(ByteString bytes, long fromIndex) throws IOException;
+
+  /**
+   * Returns the index of the first byte in {@code targetBytes} in the buffer.
+   * This expands the buffer as necessary until a target byte is found. This
+   * reads an unbounded number of bytes into the buffer. Returns -1 if the
+   * stream is exhausted before the requested byte is found.
+   */
+  long indexOfElement(ByteString targetBytes) throws IOException;
+
+  /**
+   * Returns the index of the first byte in {@code targetBytes} in the buffer
+   * at or after {@code fromIndex}. This expands the buffer as necessary until
+   * a target byte is found. This reads an unbounded number of bytes into the
+   * buffer. Returns -1 if the stream is exhausted before the requested byte is
+   * found.
+   */
+  long indexOfElement(ByteString targetBytes, long fromIndex) throws IOException;
+
+  /** Returns an input stream that reads from this source. */
+  InputStream inputStream();
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/ByteString.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/ByteString.java
new file mode 100644
index 0000000..ade1ea2
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/ByteString.java
@@ -0,0 +1,381 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright 2014 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 com.android.okhttp.okio;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+
+import static com.android.okhttp.okio.Util.arrayRangeEquals;
+import static com.android.okhttp.okio.Util.checkOffsetAndCount;
+
+/**
+ * An immutable sequence of bytes.
+ *
+ * <p>Byte strings compare lexicographically as a sequence of <strong>unsigned</strong> bytes. That
+ * is, the byte string {@code ff} sorts after {@code 00}. This is counter to the sort order of the
+ * corresponding bytes, where {@code -1} sorts before {@code 0}.
+ *
+ * <p><strong>Full disclosure:</strong> this class provides untrusted input and output streams with
+ * raw access to the underlying byte array. A hostile stream implementation could keep a reference
+ * to the mutable byte string, violating the immutable guarantee of this class. For this reason a
+ * byte string's immutability guarantee cannot be relied upon for security in applets and other
+ * environments that run both trusted and untrusted code in the same process.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class ByteString implements Serializable, Comparable<ByteString> {
+  static final char[] HEX_DIGITS =
+      { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+  private static final long serialVersionUID = 1L;
+
+  /** A singleton empty {@code ByteString}. */
+  public static final ByteString EMPTY = ByteString.of();
+
+  final byte[] data;
+  transient int hashCode; // Lazily computed; 0 if unknown.
+  transient String utf8; // Lazily computed.
+
+  ByteString(byte[] data) {
+    this.data = data; // Trusted internal constructor doesn't clone data.
+  }
+
+  /**
+   * Returns a new byte string containing a clone of the bytes of {@code data}.
+   */
+  public static ByteString of(byte... data) {
+    if (data == null) throw new IllegalArgumentException("data == null");
+    return new ByteString(data.clone());
+  }
+
+  /**
+   * Returns a new byte string containing a copy of {@code byteCount} bytes of {@code data} starting
+   * at {@code offset}.
+   */
+  public static ByteString of(byte[] data, int offset, int byteCount) {
+    if (data == null) throw new IllegalArgumentException("data == null");
+    checkOffsetAndCount(data.length, offset, byteCount);
+
+    byte[] copy = new byte[byteCount];
+    System.arraycopy(data, offset, copy, 0, byteCount);
+    return new ByteString(copy);
+  }
+
+  /** Returns a new byte string containing the {@code UTF-8} bytes of {@code s}. */
+  public static ByteString encodeUtf8(String s) {
+    if (s == null) throw new IllegalArgumentException("s == null");
+    ByteString byteString = new ByteString(s.getBytes(Util.UTF_8));
+    byteString.utf8 = s;
+    return byteString;
+  }
+
+  /** Constructs a new {@code String} by decoding the bytes as {@code UTF-8}. */
+  public String utf8() {
+    String result = utf8;
+    // We don't care if we double-allocate in racy code.
+    return result != null ? result : (utf8 = new String(data, Util.UTF_8));
+  }
+
+  /**
+   * Returns this byte string encoded as <a
+   * href="http://www.ietf.org/rfc/rfc2045.txt">Base64</a>. In violation of the
+   * RFC, the returned string does not wrap lines at 76 columns.
+   */
+  public String base64() {
+    return Base64.encode(data);
+  }
+
+  /** Returns the MD5 hash of this byte string. */
+  public ByteString md5() {
+    return digest("MD5");
+  }
+
+  /** Returns the SHA-256 hash of this byte string. */
+  public ByteString sha256() {
+    return digest("SHA-256");
+  }
+
+  private ByteString digest(String digest) {
+    try {
+      return ByteString.of(MessageDigest.getInstance(digest).digest(data));
+    } catch (NoSuchAlgorithmException e) {
+      throw new AssertionError(e);
+    }
+  }
+
+  /**
+   * Returns this byte string encoded as <a href="http://www.ietf.org/rfc/rfc4648.txt">URL-safe
+   * Base64</a>.
+   */
+  public String base64Url() {
+    return Base64.encodeUrl(data);
+  }
+
+  /**
+   * Decodes the Base64-encoded bytes and returns their value as a byte string.
+   * Returns null if {@code base64} is not a Base64-encoded sequence of bytes.
+   */
+  public static ByteString decodeBase64(String base64) {
+    if (base64 == null) throw new IllegalArgumentException("base64 == null");
+    byte[] decoded = Base64.decode(base64);
+    return decoded != null ? new ByteString(decoded) : null;
+  }
+
+  /** Returns this byte string encoded in hexadecimal. */
+  public String hex() {
+    char[] result = new char[data.length * 2];
+    int c = 0;
+    for (byte b : data) {
+      result[c++] = HEX_DIGITS[(b >> 4) & 0xf];
+      result[c++] = HEX_DIGITS[b & 0xf];
+    }
+    return new String(result);
+  }
+
+  /** Decodes the hex-encoded bytes and returns their value a byte string. */
+  public static ByteString decodeHex(String hex) {
+    if (hex == null) throw new IllegalArgumentException("hex == null");
+    if (hex.length() % 2 != 0) throw new IllegalArgumentException("Unexpected hex string: " + hex);
+
+    byte[] result = new byte[hex.length() / 2];
+    for (int i = 0; i < result.length; i++) {
+      int d1 = decodeHexDigit(hex.charAt(i * 2)) << 4;
+      int d2 = decodeHexDigit(hex.charAt(i * 2 + 1));
+      result[i] = (byte) (d1 + d2);
+    }
+    return of(result);
+  }
+
+  private static int decodeHexDigit(char c) {
+    if (c >= '0' && c <= '9') return c - '0';
+    if (c >= 'a' && c <= 'f') return c - 'a' + 10;
+    if (c >= 'A' && c <= 'F') return c - 'A' + 10;
+    throw new IllegalArgumentException("Unexpected hex digit: " + c);
+  }
+
+  /**
+   * Reads {@code count} bytes from {@code in} and returns the result.
+   *
+   * @throws java.io.EOFException if {@code in} has fewer than {@code count}
+   *     bytes to read.
+   */
+  public static ByteString read(InputStream in, int byteCount) throws IOException {
+    if (in == null) throw new IllegalArgumentException("in == null");
+    if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
+
+    byte[] result = new byte[byteCount];
+    for (int offset = 0, read; offset < byteCount; offset += read) {
+      read = in.read(result, offset, byteCount - offset);
+      if (read == -1) throw new EOFException();
+    }
+    return new ByteString(result);
+  }
+
+  /**
+   * Returns a byte string equal to this byte string, but with the bytes 'A'
+   * through 'Z' replaced with the corresponding byte in 'a' through 'z'.
+   * Returns this byte string if it contains no bytes in 'A' through 'Z'.
+   */
+  public ByteString toAsciiLowercase() {
+    // Search for an uppercase character. If we don't find one, return this.
+    for (int i = 0; i < data.length; i++) {
+      byte c = data[i];
+      if (c < 'A' || c > 'Z') continue;
+
+      // If we reach this point, this string is not not lowercase. Create and
+      // return a new byte string.
+      byte[] lowercase = data.clone();
+      lowercase[i++] = (byte) (c - ('A' - 'a'));
+      for (; i < lowercase.length; i++) {
+        c = lowercase[i];
+        if (c < 'A' || c > 'Z') continue;
+        lowercase[i] = (byte) (c - ('A' - 'a'));
+      }
+      return new ByteString(lowercase);
+    }
+    return this;
+  }
+
+  /**
+   * Returns a byte string equal to this byte string, but with the bytes 'a'
+   * through 'z' replaced with the corresponding byte in 'A' through 'Z'.
+   * Returns this byte string if it contains no bytes in 'a' through 'z'.
+   */
+  public ByteString toAsciiUppercase() {
+    // Search for an lowercase character. If we don't find one, return this.
+    for (int i = 0; i < data.length; i++) {
+      byte c = data[i];
+      if (c < 'a' || c > 'z') continue;
+
+      // If we reach this point, this string is not not uppercase. Create and
+      // return a new byte string.
+      byte[] lowercase = data.clone();
+      lowercase[i++] = (byte) (c - ('a' - 'A'));
+      for (; i < lowercase.length; i++) {
+        c = lowercase[i];
+        if (c < 'a' || c > 'z') continue;
+        lowercase[i] = (byte) (c - ('a' - 'A'));
+      }
+      return new ByteString(lowercase);
+    }
+    return this;
+  }
+
+  /**
+   * Returns a byte string that is a substring of this byte string, beginning at the specified
+   * index until the end of this string. Returns this byte string if {@code beginIndex} is 0.
+   */
+  public ByteString substring(int beginIndex) {
+    return substring(beginIndex, data.length);
+  }
+
+  /**
+   * Returns a byte string that is a substring of this byte string, beginning at the specified
+   * {@code beginIndex} and ends at the specified {@code endIndex}. Returns this byte string if
+   * {@code beginIndex} is 0 and {@code endIndex} is the length of this byte string.
+   */
+  public ByteString substring(int beginIndex, int endIndex) {
+    if (beginIndex < 0) throw new IllegalArgumentException("beginIndex < 0");
+    if (endIndex > data.length) {
+      throw new IllegalArgumentException("endIndex > length(" + data.length + ")");
+    }
+
+    int subLen = endIndex - beginIndex;
+    if (subLen < 0) throw new IllegalArgumentException("endIndex < beginIndex");
+
+    if ((beginIndex == 0) && (endIndex == data.length)) {
+      return this;
+    }
+
+    byte[] copy = new byte[subLen];
+    System.arraycopy(data, beginIndex, copy, 0, subLen);
+    return new ByteString(copy);
+  }
+
+  /** Returns the byte at {@code pos}. */
+  public byte getByte(int pos) {
+    return data[pos];
+  }
+
+  /**
+   * Returns the number of bytes in this ByteString.
+   */
+  public int size() {
+    return data.length;
+  }
+
+  /**
+   * Returns a byte array containing a copy of the bytes in this {@code ByteString}.
+   */
+  public byte[] toByteArray() {
+    return data.clone();
+  }
+
+  /** Writes the contents of this byte string to {@code out}. */
+  public void write(OutputStream out) throws IOException {
+    if (out == null) throw new IllegalArgumentException("out == null");
+    out.write(data);
+  }
+
+  /** Writes the contents of this byte string to {@code buffer}. */
+  void write(Buffer buffer) {
+    buffer.write(data, 0, data.length);
+  }
+
+  /**
+   * Returns true if the bytes of this in {@code [offset..offset+byteCount)} equal the bytes of
+   * {@code other} in {@code [otherOffset..otherOffset+byteCount)}. Returns false if either range is
+   * out of bounds.
+   */
+  public boolean rangeEquals(int offset, ByteString other, int otherOffset, int byteCount) {
+    return other.rangeEquals(otherOffset, this.data, offset, byteCount);
+  }
+
+  /**
+   * Returns true if the bytes of this in {@code [offset..offset+byteCount)} equal the bytes of
+   * {@code other} in {@code [otherOffset..otherOffset+byteCount)}. Returns false if either range is
+   * out of bounds.
+   */
+  public boolean rangeEquals(int offset, byte[] other, int otherOffset, int byteCount) {
+    return offset <= data.length - byteCount
+        && otherOffset <= other.length - byteCount
+        && arrayRangeEquals(data, offset, other, otherOffset, byteCount);
+  }
+
+  @Override public boolean equals(Object o) {
+    if (o == this) return true;
+    return o instanceof ByteString
+        && ((ByteString) o).size() == data.length
+        && ((ByteString) o).rangeEquals(0, data, 0, data.length);
+  }
+
+  @Override public int hashCode() {
+    int result = hashCode;
+    return result != 0 ? result : (hashCode = Arrays.hashCode(data));
+  }
+
+  @Override public int compareTo(ByteString byteString) {
+    int sizeA = size();
+    int sizeB = byteString.size();
+    for (int i = 0, size = Math.min(sizeA, sizeB); i < size; i++) {
+      int byteA = getByte(i) & 0xff;
+      int byteB = byteString.getByte(i) & 0xff;
+      if (byteA == byteB) continue;
+      return byteA < byteB ? -1 : 1;
+    }
+    if (sizeA == sizeB) return 0;
+    return sizeA < sizeB ? -1 : 1;
+  }
+
+  @Override public String toString() {
+    if (data.length == 0) {
+      return "ByteString[size=0]";
+    }
+
+    if (data.length <= 16) {
+      return String.format("ByteString[size=%s data=%s]", data.length, hex());
+    }
+
+    return String.format("ByteString[size=%s md5=%s]", data.length, md5().hex());
+  }
+
+  private void readObject(ObjectInputStream in) throws IOException {
+    int dataLength = in.readInt();
+    ByteString byteString = ByteString.read(in, dataLength);
+    try {
+      Field field = ByteString.class.getDeclaredField("data");
+      field.setAccessible(true);
+      field.set(this, byteString.data);
+    } catch (NoSuchFieldException e) {
+      throw new AssertionError();
+    } catch (IllegalAccessException e) {
+      throw new AssertionError();
+    }
+  }
+
+  private void writeObject(ObjectOutputStream out) throws IOException {
+    out.writeInt(data.length);
+    out.write(data);
+  }
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/DeflaterSink.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/DeflaterSink.java
new file mode 100644
index 0000000..7df783e
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/DeflaterSink.java
@@ -0,0 +1,160 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.okio;
+
+import java.io.IOException;
+import java.util.zip.Deflater;
+
+import static com.android.okhttp.okio.Util.checkOffsetAndCount;
+
+/**
+ * A sink that uses <a href="http://tools.ietf.org/html/rfc1951">DEFLATE</a> to
+ * compress data written to another source.
+ *
+ * <h3>Sync flush</h3>
+ * Aggressive flushing of this stream may result in reduced compression. Each
+ * call to {@link #flush} immediately compresses all currently-buffered data;
+ * this early compression may be less effective than compression performed
+ * without flushing.
+ *
+ * <p>This is equivalent to using {@link Deflater} with the sync flush option.
+ * This class does not offer any partial flush mechanism. For best performance,
+ * only call {@link #flush} when application behavior requires it.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class DeflaterSink implements Sink {
+  private final BufferedSink sink;
+  private final Deflater deflater;
+  private boolean closed;
+
+  public DeflaterSink(Sink sink, Deflater deflater) {
+    this(Okio.buffer(sink), deflater);
+  }
+
+  /**
+   * This package-private constructor shares a buffer with its trusted caller.
+   * In general we can't share a BufferedSource because the deflater holds input
+   * bytes until they are inflated.
+   */
+  DeflaterSink(BufferedSink sink, Deflater deflater) {
+    if (sink == null) throw new IllegalArgumentException("source == null");
+    if (deflater == null) throw new IllegalArgumentException("inflater == null");
+    this.sink = sink;
+    this.deflater = deflater;
+  }
+
+  @Override public void write(Buffer source, long byteCount)
+      throws IOException {
+    checkOffsetAndCount(source.size, 0, byteCount);
+    while (byteCount > 0) {
+      // Share bytes from the head segment of 'source' with the deflater.
+      Segment head = source.head;
+      int toDeflate = (int) Math.min(byteCount, head.limit - head.pos);
+      deflater.setInput(head.data, head.pos, toDeflate);
+
+      // Deflate those bytes into sink.
+      deflate(false);
+
+      // Mark those bytes as read.
+      source.size -= toDeflate;
+      head.pos += toDeflate;
+      if (head.pos == head.limit) {
+        source.head = head.pop();
+        SegmentPool.recycle(head);
+      }
+
+      byteCount -= toDeflate;
+    }
+  }
+
+  // ANDROID-BEGIN
+  // @IgnoreJRERequirement
+  // ANDROID-END
+  private void deflate(boolean syncFlush) throws IOException {
+    Buffer buffer = sink.buffer();
+    while (true) {
+      Segment s = buffer.writableSegment(1);
+
+      // The 4-parameter overload of deflate() doesn't exist in the RI until
+      // Java 1.7, and is public (although with @hide) on Android since 2.3.
+      // The @hide tag means that this code won't compile against the Android
+      // 2.3 SDK, but it will run fine there.
+      int deflated = syncFlush
+          ? deflater.deflate(s.data, s.limit, Segment.SIZE - s.limit, Deflater.SYNC_FLUSH)
+          : deflater.deflate(s.data, s.limit, Segment.SIZE - s.limit);
+
+      if (deflated > 0) {
+        s.limit += deflated;
+        buffer.size += deflated;
+        sink.emitCompleteSegments();
+      } else if (deflater.needsInput()) {
+        if (s.pos == s.limit) {
+          // We allocated a tail segment, but didn't end up needing it. Recycle!
+          buffer.head = s.pop();
+          SegmentPool.recycle(s);
+        }
+        return;
+      }
+    }
+  }
+
+  @Override public void flush() throws IOException {
+    deflate(true);
+    sink.flush();
+  }
+
+  void finishDeflate() throws IOException {
+    deflater.finish();
+    deflate(false);
+  }
+
+  @Override public void close() throws IOException {
+    if (closed) return;
+
+    // Emit deflated data to the underlying sink. If this fails, we still need
+    // to close the deflater and the sink; otherwise we risk leaking resources.
+    Throwable thrown = null;
+    try {
+      finishDeflate();
+    } catch (Throwable e) {
+      thrown = e;
+    }
+
+    try {
+      deflater.end();
+    } catch (Throwable e) {
+      if (thrown == null) thrown = e;
+    }
+
+    try {
+      sink.close();
+    } catch (Throwable e) {
+      if (thrown == null) thrown = e;
+    }
+    closed = true;
+
+    if (thrown != null) Util.sneakyRethrow(thrown);
+  }
+
+  @Override public Timeout timeout() {
+    return sink.timeout();
+  }
+
+  @Override public String toString() {
+    return "DeflaterSink(" + sink + ")";
+  }
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/ForwardingSink.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/ForwardingSink.java
new file mode 100644
index 0000000..5dcad18
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/ForwardingSink.java
@@ -0,0 +1,55 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.okio;
+
+import java.io.IOException;
+
+/** A {@link Sink} which forwards calls to another. Useful for subclassing. 
+ * @hide This class is not part of the Android public SDK API*/
+public abstract class ForwardingSink implements Sink {
+  private final Sink delegate;
+
+  public ForwardingSink(Sink delegate) {
+    if (delegate == null) throw new IllegalArgumentException("delegate == null");
+    this.delegate = delegate;
+  }
+
+  /** {@link Sink} to which this instance is delegating. */
+  public final Sink delegate() {
+    return delegate;
+  }
+
+  @Override public void write(Buffer source, long byteCount) throws IOException {
+    delegate.write(source, byteCount);
+  }
+
+  @Override public void flush() throws IOException {
+    delegate.flush();
+  }
+
+  @Override public Timeout timeout() {
+    return delegate.timeout();
+  }
+
+  @Override public void close() throws IOException {
+    delegate.close();
+  }
+
+  @Override public String toString() {
+    return getClass().getSimpleName() + "(" + delegate.toString() + ")";
+  }
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/ForwardingSource.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/ForwardingSource.java
new file mode 100644
index 0000000..12fd15e
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/ForwardingSource.java
@@ -0,0 +1,51 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.okio;
+
+import java.io.IOException;
+
+/** A {@link Source} which forwards calls to another. Useful for subclassing. 
+ * @hide This class is not part of the Android public SDK API*/
+public abstract class ForwardingSource implements Source {
+  private final Source delegate;
+
+  public ForwardingSource(Source delegate) {
+    if (delegate == null) throw new IllegalArgumentException("delegate == null");
+    this.delegate = delegate;
+  }
+
+  /** {@link Source} to which this instance is delegating. */
+  public final Source delegate() {
+    return delegate;
+  }
+
+  @Override public long read(Buffer sink, long byteCount) throws IOException {
+    return delegate.read(sink, byteCount);
+  }
+
+  @Override public Timeout timeout() {
+    return delegate.timeout();
+  }
+
+  @Override public void close() throws IOException {
+    delegate.close();
+  }
+
+  @Override public String toString() {
+    return getClass().getSimpleName() + "(" + delegate.toString() + ")";
+  }
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/ForwardingTimeout.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/ForwardingTimeout.java
new file mode 100644
index 0000000..8f6e890
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/ForwardingTimeout.java
@@ -0,0 +1,74 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.okhttp.okio;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+/** A {@link Timeout} which forwards calls to another. Useful for subclassing. 
+ * @hide This class is not part of the Android public SDK API*/
+public class ForwardingTimeout extends Timeout {
+  private Timeout delegate;
+
+  public ForwardingTimeout(Timeout delegate) {
+    if (delegate == null) throw new IllegalArgumentException("delegate == null");
+    this.delegate = delegate;
+  }
+
+  /** {@link Timeout} instance to which this instance is currently delegating. */
+  public final Timeout delegate() {
+    return delegate;
+  }
+
+  public final ForwardingTimeout setDelegate(Timeout delegate) {
+    if (delegate == null) throw new IllegalArgumentException("delegate == null");
+    this.delegate = delegate;
+    return this;
+  }
+
+  @Override public Timeout timeout(long timeout, TimeUnit unit) {
+    return delegate.timeout(timeout, unit);
+  }
+
+  @Override public long timeoutNanos() {
+    return delegate.timeoutNanos();
+  }
+
+  @Override public boolean hasDeadline() {
+    return delegate.hasDeadline();
+  }
+
+  @Override public long deadlineNanoTime() {
+    return delegate.deadlineNanoTime();
+  }
+
+  @Override public Timeout deadlineNanoTime(long deadlineNanoTime) {
+    return delegate.deadlineNanoTime(deadlineNanoTime);
+  }
+
+  @Override public Timeout clearTimeout() {
+    return delegate.clearTimeout();
+  }
+
+  @Override public Timeout clearDeadline() {
+    return delegate.clearDeadline();
+  }
+
+  @Override public void throwIfReached() throws IOException {
+    delegate.throwIfReached();
+  }
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/GzipSink.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/GzipSink.java
new file mode 100644
index 0000000..a2d02b2
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/GzipSink.java
@@ -0,0 +1,139 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.okio;
+
+import java.io.IOException;
+import java.util.zip.CRC32;
+import java.util.zip.Deflater;
+
+import static java.util.zip.Deflater.DEFAULT_COMPRESSION;
+
+/**
+ * A sink that uses <a href="http://www.ietf.org/rfc/rfc1952.txt">GZIP</a> to
+ * compress written data to another sink.
+ *
+ * <h3>Sync flush</h3>
+ * Aggressive flushing of this stream may result in reduced compression. Each
+ * call to {@link #flush} immediately compresses all currently-buffered data;
+ * this early compression may be less effective than compression performed
+ * without flushing.
+ *
+ * <p>This is equivalent to using {@link Deflater} with the sync flush option.
+ * This class does not offer any partial flush mechanism. For best performance,
+ * only call {@link #flush} when application behavior requires it.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class GzipSink implements Sink {
+  /** Sink into which the GZIP format is written. */
+  private final BufferedSink sink;
+
+  /** The deflater used to compress the body. */
+  private final Deflater deflater;
+
+  /**
+   * The deflater sink takes care of moving data between decompressed source and
+   * compressed sink buffers.
+   */
+  private final DeflaterSink deflaterSink;
+
+  private boolean closed;
+
+  /** Checksum calculated for the compressed body. */
+  private final CRC32 crc = new CRC32();
+
+  public GzipSink(Sink sink) {
+    if (sink == null) throw new IllegalArgumentException("sink == null");
+    this.deflater = new Deflater(DEFAULT_COMPRESSION, true /* No wrap */);
+    this.sink = Okio.buffer(sink);
+    this.deflaterSink = new DeflaterSink(this.sink, deflater);
+
+    writeHeader();
+  }
+
+  @Override public void write(Buffer source, long byteCount) throws IOException {
+    if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
+    if (byteCount == 0) return;
+
+    updateCrc(source, byteCount);
+    deflaterSink.write(source, byteCount);
+  }
+
+  @Override public void flush() throws IOException {
+    deflaterSink.flush();
+  }
+
+  @Override public Timeout timeout() {
+    return sink.timeout();
+  }
+
+  @Override public void close() throws IOException {
+    if (closed) return;
+
+    // This method delegates to the DeflaterSink for finishing the deflate process
+    // but keeps responsibility for releasing the deflater's resources. This is
+    // necessary because writeFooter needs to query the processed byte count which
+    // only works when the deflater is still open.
+
+    Throwable thrown = null;
+    try {
+      deflaterSink.finishDeflate();
+      writeFooter();
+    } catch (Throwable e) {
+      thrown = e;
+    }
+
+    try {
+      deflater.end();
+    } catch (Throwable e) {
+      if (thrown == null) thrown = e;
+    }
+
+    try {
+      sink.close();
+    } catch (Throwable e) {
+      if (thrown == null) thrown = e;
+    }
+    closed = true;
+
+    if (thrown != null) Util.sneakyRethrow(thrown);
+  }
+
+  private void writeHeader() {
+    // Write the Gzip header directly into the buffer for the sink to avoid handling IOException.
+    Buffer buffer = this.sink.buffer();
+    buffer.writeShort(0x1f8b); // Two-byte Gzip ID.
+    buffer.writeByte(0x08); // 8 == Deflate compression method.
+    buffer.writeByte(0x00); // No flags.
+    buffer.writeInt(0x00); // No modification time.
+    buffer.writeByte(0x00); // No extra flags.
+    buffer.writeByte(0x00); // No OS.
+  }
+
+  private void writeFooter() throws IOException {
+    sink.writeIntLe((int) crc.getValue()); // CRC of original data.
+    sink.writeIntLe(deflater.getTotalIn()); // Length of original data.
+  }
+
+  /** Updates the CRC with the given bytes. */
+  private void updateCrc(Buffer buffer, long byteCount) {
+    for (Segment head = buffer.head; byteCount > 0; head = head.next) {
+      int segmentLength = (int) Math.min(byteCount, head.limit - head.pos);
+      crc.update(head.data, head.pos, segmentLength);
+      byteCount -= segmentLength;
+    }
+  }
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/GzipSource.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/GzipSource.java
new file mode 100644
index 0000000..f9586c0
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/GzipSource.java
@@ -0,0 +1,211 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.okio;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.util.zip.CRC32;
+import java.util.zip.Inflater;
+
+/**
+ * A source that uses <a href="http://www.ietf.org/rfc/rfc1952.txt">GZIP</a> to
+ * decompress data read from another source.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class GzipSource implements Source {
+  private static final byte FHCRC = 1;
+  private static final byte FEXTRA = 2;
+  private static final byte FNAME = 3;
+  private static final byte FCOMMENT = 4;
+
+  private static final byte SECTION_HEADER = 0;
+  private static final byte SECTION_BODY = 1;
+  private static final byte SECTION_TRAILER = 2;
+  private static final byte SECTION_DONE = 3;
+
+  /** The current section. Always progresses forward. */
+  private int section = SECTION_HEADER;
+
+  /**
+   * Our source should yield a GZIP header (which we consume directly), followed
+   * by deflated bytes (which we consume via an InflaterSource), followed by a
+   * GZIP trailer (which we also consume directly).
+   */
+  private final BufferedSource source;
+
+  /** The inflater used to decompress the deflated body. */
+  private final Inflater inflater;
+
+  /**
+   * The inflater source takes care of moving data between compressed source and
+   * decompressed sink buffers.
+   */
+  private final InflaterSource inflaterSource;
+
+  /** Checksum used to check both the GZIP header and decompressed body. */
+  private final CRC32 crc = new CRC32();
+
+  public GzipSource(Source source) {
+    if (source == null) throw new IllegalArgumentException("source == null");
+    this.inflater = new Inflater(true);
+    this.source = Okio.buffer(source);
+    this.inflaterSource = new InflaterSource(this.source, inflater);
+  }
+
+  @Override public long read(Buffer sink, long byteCount) throws IOException {
+    if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
+    if (byteCount == 0) return 0;
+
+    // If we haven't consumed the header, we must consume it before anything else.
+    if (section == SECTION_HEADER) {
+      consumeHeader();
+      section = SECTION_BODY;
+    }
+
+    // Attempt to read at least a byte of the body. If we do, we're done.
+    if (section == SECTION_BODY) {
+      long offset = sink.size;
+      long result = inflaterSource.read(sink, byteCount);
+      if (result != -1) {
+        updateCrc(sink, offset, result);
+        return result;
+      }
+      section = SECTION_TRAILER;
+    }
+
+    // The body is exhausted; time to read the trailer. We always consume the
+    // trailer before returning a -1 exhausted result; that way if you read to
+    // the end of a GzipSource you guarantee that the CRC has been checked.
+    if (section == SECTION_TRAILER) {
+      consumeTrailer();
+      section = SECTION_DONE;
+
+      // Gzip streams self-terminate: they return -1 before their underlying
+      // source returns -1. Here we attempt to force the underlying stream to
+      // return -1 which may trigger it to release its resources. If it doesn't
+      // return -1, then our Gzip data finished prematurely!
+      if (!source.exhausted()) {
+        throw new IOException("gzip finished without exhausting source");
+      }
+    }
+
+    return -1;
+  }
+
+  private void consumeHeader() throws IOException {
+    // Read the 10-byte header. We peek at the flags byte first so we know if we
+    // need to CRC the entire header. Then we read the magic ID1ID2 sequence.
+    // We can skip everything else in the first 10 bytes.
+    // +---+---+---+---+---+---+---+---+---+---+
+    // |ID1|ID2|CM |FLG|     MTIME     |XFL|OS | (more-->)
+    // +---+---+---+---+---+---+---+---+---+---+
+    source.require(10);
+    byte flags = source.buffer().getByte(3);
+    boolean fhcrc = ((flags >> FHCRC) & 1) == 1;
+    if (fhcrc) updateCrc(source.buffer(), 0, 10);
+
+    short id1id2 = source.readShort();
+    checkEqual("ID1ID2", (short) 0x1f8b, id1id2);
+    source.skip(8);
+
+    // Skip optional extra fields.
+    // +---+---+=================================+
+    // | XLEN  |...XLEN bytes of "extra field"...| (more-->)
+    // +---+---+=================================+
+    if (((flags >> FEXTRA) & 1) == 1) {
+      source.require(2);
+      if (fhcrc) updateCrc(source.buffer(), 0, 2);
+      int xlen = source.buffer().readShortLe();
+      source.require(xlen);
+      if (fhcrc) updateCrc(source.buffer(), 0, xlen);
+      source.skip(xlen);
+    }
+
+    // Skip an optional 0-terminated name.
+    // +=========================================+
+    // |...original file name, zero-terminated...| (more-->)
+    // +=========================================+
+    if (((flags >> FNAME) & 1) == 1) {
+      long index = source.indexOf((byte) 0);
+      if (index == -1) throw new EOFException();
+      if (fhcrc) updateCrc(source.buffer(), 0, index + 1);
+      source.skip(index + 1);
+    }
+
+    // Skip an optional 0-terminated comment.
+    // +===================================+
+    // |...file comment, zero-terminated...| (more-->)
+    // +===================================+
+    if (((flags >> FCOMMENT) & 1) == 1) {
+      long index = source.indexOf((byte) 0);
+      if (index == -1) throw new EOFException();
+      if (fhcrc) updateCrc(source.buffer(), 0, index + 1);
+      source.skip(index + 1);
+    }
+
+    // Confirm the optional header CRC.
+    // +---+---+
+    // | CRC16 |
+    // +---+---+
+    if (fhcrc) {
+      checkEqual("FHCRC", source.readShortLe(), (short) crc.getValue());
+      crc.reset();
+    }
+  }
+
+  private void consumeTrailer() throws IOException {
+    // Read the eight-byte trailer. Confirm the body's CRC and size.
+    // +---+---+---+---+---+---+---+---+
+    // |     CRC32     |     ISIZE     |
+    // +---+---+---+---+---+---+---+---+
+    checkEqual("CRC", source.readIntLe(), (int) crc.getValue());
+    checkEqual("ISIZE", source.readIntLe(), inflater.getTotalOut());
+  }
+
+  @Override public Timeout timeout() {
+    return source.timeout();
+  }
+
+  @Override public void close() throws IOException {
+    inflaterSource.close();
+  }
+
+  /** Updates the CRC with the given bytes. */
+  private void updateCrc(Buffer buffer, long offset, long byteCount) {
+    // Skip segments that we aren't checksumming.
+    Segment s = buffer.head;
+    for (; offset >= (s.limit - s.pos); s = s.next) {
+      offset -= (s.limit - s.pos);
+    }
+
+    // Checksum one segment at a time.
+    for (; byteCount > 0; s = s.next) {
+      int pos = (int) (s.pos + offset);
+      int toUpdate = (int) Math.min(s.limit - pos, byteCount);
+      crc.update(s.data, pos, toUpdate);
+      byteCount -= toUpdate;
+      offset = 0;
+    }
+  }
+
+  private void checkEqual(String name, int expected, int actual) throws IOException {
+    if (actual != expected) {
+      throw new IOException(String.format(
+          "%s: actual 0x%08x != expected 0x%08x", name, actual, expected));
+    }
+  }
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/InflaterSource.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/InflaterSource.java
new file mode 100644
index 0000000..f94fe9f
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/InflaterSource.java
@@ -0,0 +1,130 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.okio;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.util.zip.DataFormatException;
+import java.util.zip.Inflater;
+
+/**
+ * A source that uses <a href="http://tools.ietf.org/html/rfc1951">DEFLATE</a>
+ * to decompress data read from another source.
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class InflaterSource implements Source {
+  private final BufferedSource source;
+  private final Inflater inflater;
+
+  /**
+   * When we call Inflater.setInput(), the inflater keeps our byte array until
+   * it needs input again. This tracks how many bytes the inflater is currently
+   * holding on to.
+   */
+  private int bufferBytesHeldByInflater;
+  private boolean closed;
+
+  public InflaterSource(Source source, Inflater inflater) {
+    this(Okio.buffer(source), inflater);
+  }
+
+  /**
+   * This package-private constructor shares a buffer with its trusted caller.
+   * In general we can't share a BufferedSource because the inflater holds input
+   * bytes until they are inflated.
+   */
+  InflaterSource(BufferedSource source, Inflater inflater) {
+    if (source == null) throw new IllegalArgumentException("source == null");
+    if (inflater == null) throw new IllegalArgumentException("inflater == null");
+    this.source = source;
+    this.inflater = inflater;
+  }
+
+  @Override public long read(
+      Buffer sink, long byteCount) throws IOException {
+    if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
+    if (closed) throw new IllegalStateException("closed");
+    if (byteCount == 0) return 0;
+
+    while (true) {
+      boolean sourceExhausted = refill();
+
+      // Decompress the inflater's compressed data into the sink.
+      try {
+        Segment tail = sink.writableSegment(1);
+        int bytesInflated = inflater.inflate(tail.data, tail.limit, Segment.SIZE - tail.limit);
+        if (bytesInflated > 0) {
+          tail.limit += bytesInflated;
+          sink.size += bytesInflated;
+          return bytesInflated;
+        }
+        if (inflater.finished() || inflater.needsDictionary()) {
+          releaseInflatedBytes();
+          if (tail.pos == tail.limit) {
+            // We allocated a tail segment, but didn't end up needing it. Recycle!
+            sink.head = tail.pop();
+            SegmentPool.recycle(tail);
+          }
+          return -1;
+        }
+        if (sourceExhausted) throw new EOFException("source exhausted prematurely");
+      } catch (DataFormatException e) {
+        throw new IOException(e);
+      }
+    }
+  }
+
+  /**
+   * Refills the inflater with compressed data if it needs input. (And only if
+   * it needs input). Returns true if the inflater required input but the source
+   * was exhausted.
+   */
+  public boolean refill() throws IOException {
+    if (!inflater.needsInput()) return false;
+
+    releaseInflatedBytes();
+    if (inflater.getRemaining() != 0) throw new IllegalStateException("?"); // TODO: possible?
+
+    // If there are compressed bytes in the source, assign them to the inflater.
+    if (source.exhausted()) return true;
+
+    // Assign buffer bytes to the inflater.
+    Segment head = source.buffer().head;
+    bufferBytesHeldByInflater = head.limit - head.pos;
+    inflater.setInput(head.data, head.pos, bufferBytesHeldByInflater);
+    return false;
+  }
+
+  /** When the inflater has processed compressed data, remove it from the buffer. */
+  private void releaseInflatedBytes() throws IOException {
+    if (bufferBytesHeldByInflater == 0) return;
+    int toRelease = bufferBytesHeldByInflater - inflater.getRemaining();
+    bufferBytesHeldByInflater -= toRelease;
+    source.skip(toRelease);
+  }
+
+  @Override public Timeout timeout() {
+    return source.timeout();
+  }
+
+  @Override public void close() throws IOException {
+    if (closed) return;
+    inflater.end();
+    closed = true;
+    source.close();
+  }
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Okio.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Okio.java
new file mode 100644
index 0000000..d1dd017
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Okio.java
@@ -0,0 +1,247 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.okio;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import static com.android.okhttp.okio.Util.checkOffsetAndCount;
+
+/** Essential APIs for working with Okio. 
+ * @hide This class is not part of the Android public SDK API*/
+public final class Okio {
+  private static final Logger logger = Logger.getLogger(Okio.class.getName());
+
+  private Okio() {
+  }
+
+  /**
+   * Returns a new source that buffers reads from {@code source}. The returned
+   * source will perform bulk reads into its in-memory buffer. Use this wherever
+   * you read a source to get an ergonomic and efficient access to data.
+   */
+  public static BufferedSource buffer(Source source) {
+    if (source == null) throw new IllegalArgumentException("source == null");
+    return new RealBufferedSource(source);
+  }
+
+  /**
+   * Returns a new sink that buffers writes to {@code sink}. The returned sink
+   * will batch writes to {@code sink}. Use this wherever you write to a sink to
+   * get an ergonomic and efficient access to data.
+   */
+  public static BufferedSink buffer(Sink sink) {
+    if (sink == null) throw new IllegalArgumentException("sink == null");
+    return new RealBufferedSink(sink);
+  }
+
+  /** Returns a sink that writes to {@code out}. */
+  public static Sink sink(OutputStream out) {
+    return sink(out, new Timeout());
+  }
+
+  private static Sink sink(final OutputStream out, final Timeout timeout) {
+    if (out == null) throw new IllegalArgumentException("out == null");
+    if (timeout == null) throw new IllegalArgumentException("timeout == null");
+
+    return new Sink() {
+      @Override public void write(Buffer source, long byteCount) throws IOException {
+        checkOffsetAndCount(source.size, 0, byteCount);
+        while (byteCount > 0) {
+          timeout.throwIfReached();
+          Segment head = source.head;
+          int toCopy = (int) Math.min(byteCount, head.limit - head.pos);
+          out.write(head.data, head.pos, toCopy);
+
+          head.pos += toCopy;
+          byteCount -= toCopy;
+          source.size -= toCopy;
+
+          if (head.pos == head.limit) {
+            source.head = head.pop();
+            SegmentPool.recycle(head);
+          }
+        }
+      }
+
+      @Override public void flush() throws IOException {
+        out.flush();
+      }
+
+      @Override public void close() throws IOException {
+        out.close();
+      }
+
+      @Override public Timeout timeout() {
+        return timeout;
+      }
+
+      @Override public String toString() {
+        return "sink(" + out + ")";
+      }
+    };
+  }
+
+  /**
+   * Returns a sink that writes to {@code socket}. Prefer this over {@link
+   * #sink(OutputStream)} because this method honors timeouts. When the socket
+   * write times out, the socket is asynchronously closed by a watchdog thread.
+   */
+  public static Sink sink(Socket socket) throws IOException {
+    if (socket == null) throw new IllegalArgumentException("socket == null");
+    AsyncTimeout timeout = timeout(socket);
+    Sink sink = sink(socket.getOutputStream(), timeout);
+    return timeout.sink(sink);
+  }
+
+  /** Returns a source that reads from {@code in}. */
+  public static Source source(InputStream in) {
+    return source(in, new Timeout());
+  }
+
+  private static Source source(final InputStream in, final Timeout timeout) {
+    if (in == null) throw new IllegalArgumentException("in == null");
+    if (timeout == null) throw new IllegalArgumentException("timeout == null");
+
+    return new Source() {
+      @Override public long read(Buffer sink, long byteCount) throws IOException {
+        if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
+        if (byteCount == 0) return 0;
+        try {
+          timeout.throwIfReached();
+          Segment tail = sink.writableSegment(1);
+          int maxToCopy = (int) Math.min(byteCount, Segment.SIZE - tail.limit);
+          int bytesRead = in.read(tail.data, tail.limit, maxToCopy);
+          if (bytesRead == -1) return -1;
+          tail.limit += bytesRead;
+          sink.size += bytesRead;
+          return bytesRead;
+        } catch (AssertionError e) {
+          if (isAndroidGetsocknameError(e)) throw new IOException(e);
+          throw e;
+        }
+      }
+
+      @Override public void close() throws IOException {
+        in.close();
+      }
+
+      @Override public Timeout timeout() {
+        return timeout;
+      }
+
+      @Override public String toString() {
+        return "source(" + in + ")";
+      }
+    };
+  }
+
+  /** Returns a source that reads from {@code file}. */
+  public static Source source(File file) throws FileNotFoundException {
+    if (file == null) throw new IllegalArgumentException("file == null");
+    return source(new FileInputStream(file));
+  }
+
+  // ANDROID-BEGIN
+  //  /** Returns a source that reads from {@code path}. */
+  //  @IgnoreJRERequirement // Should only be invoked on Java 7+.
+  //  public static Source source(Path path, OpenOption... options) throws IOException {
+  //    if (path == null) throw new IllegalArgumentException("path == null");
+  //    return source(Files.newInputStream(path, options));
+  //  }
+  // ANDROID-END
+
+  /** Returns a sink that writes to {@code file}. */
+  public static Sink sink(File file) throws FileNotFoundException {
+    if (file == null) throw new IllegalArgumentException("file == null");
+    return sink(new FileOutputStream(file));
+  }
+
+  /** Returns a sink that appends to {@code file}. */
+  public static Sink appendingSink(File file) throws FileNotFoundException {
+    if (file == null) throw new IllegalArgumentException("file == null");
+    return sink(new FileOutputStream(file, true));
+  }
+
+  // ANDROID-BEGIN
+  //  /** Returns a sink that writes to {@code path}. */
+  //  @IgnoreJRERequirement // Should only be invoked on Java 7+.
+  //  public static Sink sink(Path path, OpenOption... options) throws IOException {
+  //    if (path == null) throw new IllegalArgumentException("path == null");
+  //    return sink(Files.newOutputStream(path, options));
+  //  }
+  // ANDROID-END
+
+  /**
+   * Returns a source that reads from {@code socket}. Prefer this over {@link
+   * #source(InputStream)} because this method honors timeouts. When the socket
+   * read times out, the socket is asynchronously closed by a watchdog thread.
+   */
+  public static Source source(Socket socket) throws IOException {
+    if (socket == null) throw new IllegalArgumentException("socket == null");
+    AsyncTimeout timeout = timeout(socket);
+    Source source = source(socket.getInputStream(), timeout);
+    return timeout.source(source);
+  }
+
+  private static AsyncTimeout timeout(final Socket socket) {
+    return new AsyncTimeout() {
+      @Override protected IOException newTimeoutException(IOException cause) {
+        InterruptedIOException ioe = new SocketTimeoutException("timeout");
+        if (cause != null) {
+          ioe.initCause(cause);
+        }
+        return ioe;
+      }
+
+      @Override protected void timedOut() {
+        try {
+          socket.close();
+        } catch (Exception e) {
+          logger.log(Level.WARNING, "Failed to close timed out socket " + socket, e);
+        } catch (AssertionError e) {
+          if (isAndroidGetsocknameError(e)) {
+            // Catch this exception due to a Firmware issue up to android 4.2.2
+            // https://code.google.com/p/android/issues/detail?id=54072
+            logger.log(Level.WARNING, "Failed to close timed out socket " + socket, e);
+          } else {
+            throw e;
+          }
+        }
+      }
+    };
+  }
+
+  /**
+   * Returns true if {@code e} is due to a firmware bug fixed after Android 4.2.2.
+   * https://code.google.com/p/android/issues/detail?id=54072
+   */
+  private static boolean isAndroidGetsocknameError(AssertionError e) {
+    return e.getCause() != null && e.getMessage() != null
+        && e.getMessage().contains("getsockname failed");
+  }
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/RealBufferedSink.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/RealBufferedSink.java
new file mode 100644
index 0000000..410e122
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/RealBufferedSink.java
@@ -0,0 +1,258 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.okio;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+
+final class RealBufferedSink implements BufferedSink {
+  public final Buffer buffer;
+  public final Sink sink;
+  private boolean closed;
+
+  public RealBufferedSink(Sink sink, Buffer buffer) {
+    if (sink == null) throw new IllegalArgumentException("sink == null");
+    this.buffer = buffer;
+    this.sink = sink;
+  }
+
+  public RealBufferedSink(Sink sink) {
+    this(sink, new Buffer());
+  }
+
+  @Override public Buffer buffer() {
+    return buffer;
+  }
+
+  @Override public void write(Buffer source, long byteCount)
+      throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    buffer.write(source, byteCount);
+    emitCompleteSegments();
+  }
+
+  @Override public BufferedSink write(ByteString byteString) throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    buffer.write(byteString);
+    return emitCompleteSegments();
+  }
+
+  @Override public BufferedSink writeUtf8(String string) throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    buffer.writeUtf8(string);
+    return emitCompleteSegments();
+  }
+
+  @Override public BufferedSink writeUtf8(String string, int beginIndex, int endIndex)
+      throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    buffer.writeUtf8(string, beginIndex, endIndex);
+    return emitCompleteSegments();
+  }
+
+  @Override public BufferedSink writeUtf8CodePoint(int codePoint) throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    buffer.writeUtf8CodePoint(codePoint);
+    return emitCompleteSegments();
+  }
+
+  @Override public BufferedSink writeString(String string, Charset charset) throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    buffer.writeString(string, charset);
+    return emitCompleteSegments();
+  }
+
+  @Override public BufferedSink writeString(String string, int beginIndex, int endIndex,
+      Charset charset) throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    buffer.writeString(string, beginIndex, endIndex, charset);
+    return emitCompleteSegments();
+  }
+
+  @Override public BufferedSink write(byte[] source) throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    buffer.write(source);
+    return emitCompleteSegments();
+  }
+
+  @Override public BufferedSink write(byte[] source, int offset, int byteCount) throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    buffer.write(source, offset, byteCount);
+    return emitCompleteSegments();
+  }
+
+  @Override public long writeAll(Source source) throws IOException {
+    if (source == null) throw new IllegalArgumentException("source == null");
+    long totalBytesRead = 0;
+    for (long readCount; (readCount = source.read(buffer, Segment.SIZE)) != -1; ) {
+      totalBytesRead += readCount;
+      emitCompleteSegments();
+    }
+    return totalBytesRead;
+  }
+
+  @Override public BufferedSink write(Source source, long byteCount) throws IOException {
+    while (byteCount > 0) {
+      long read = source.read(buffer, byteCount);
+      if (read == -1) throw new EOFException();
+      byteCount -= read;
+      emitCompleteSegments();
+    }
+    return this;
+  }
+
+  @Override public BufferedSink writeByte(int b) throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    buffer.writeByte(b);
+    return emitCompleteSegments();
+  }
+
+  @Override public BufferedSink writeShort(int s) throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    buffer.writeShort(s);
+    return emitCompleteSegments();
+  }
+
+  @Override public BufferedSink writeShortLe(int s) throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    buffer.writeShortLe(s);
+    return emitCompleteSegments();
+  }
+
+  @Override public BufferedSink writeInt(int i) throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    buffer.writeInt(i);
+    return emitCompleteSegments();
+  }
+
+  @Override public BufferedSink writeIntLe(int i) throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    buffer.writeIntLe(i);
+    return emitCompleteSegments();
+  }
+
+  @Override public BufferedSink writeLong(long v) throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    buffer.writeLong(v);
+    return emitCompleteSegments();
+  }
+
+  @Override public BufferedSink writeLongLe(long v) throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    buffer.writeLongLe(v);
+    return emitCompleteSegments();
+  }
+
+  @Override public BufferedSink writeDecimalLong(long v) throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    buffer.writeDecimalLong(v);
+    return emitCompleteSegments();
+  }
+
+  @Override public BufferedSink writeHexadecimalUnsignedLong(long v) throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    buffer.writeHexadecimalUnsignedLong(v);
+    return emitCompleteSegments();
+  }
+
+  @Override public BufferedSink emitCompleteSegments() throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    long byteCount = buffer.completeSegmentByteCount();
+    if (byteCount > 0) sink.write(buffer, byteCount);
+    return this;
+  }
+
+  @Override public BufferedSink emit() throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    long byteCount = buffer.size();
+    if (byteCount > 0) sink.write(buffer, byteCount);
+    return this;
+  }
+
+  @Override public OutputStream outputStream() {
+    return new OutputStream() {
+      @Override public void write(int b) throws IOException {
+        if (closed) throw new IOException("closed");
+        buffer.writeByte((byte) b);
+        emitCompleteSegments();
+      }
+
+      @Override public void write(byte[] data, int offset, int byteCount) throws IOException {
+        if (closed) throw new IOException("closed");
+        buffer.write(data, offset, byteCount);
+        emitCompleteSegments();
+      }
+
+      @Override public void flush() throws IOException {
+        // For backwards compatibility, a flush() on a closed stream is a no-op.
+        if (!closed) {
+          RealBufferedSink.this.flush();
+        }
+      }
+
+      @Override public void close() throws IOException {
+        RealBufferedSink.this.close();
+      }
+
+      @Override public String toString() {
+        return RealBufferedSink.this + ".outputStream()";
+      }
+    };
+  }
+
+  @Override public void flush() throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    if (buffer.size > 0) {
+      sink.write(buffer, buffer.size);
+    }
+    sink.flush();
+  }
+
+  @Override public void close() throws IOException {
+    if (closed) return;
+
+    // Emit buffered data to the underlying sink. If this fails, we still need
+    // to close the sink; otherwise we risk leaking resources.
+    Throwable thrown = null;
+    try {
+      if (buffer.size > 0) {
+        sink.write(buffer, buffer.size);
+      }
+    } catch (Throwable e) {
+      thrown = e;
+    }
+
+    try {
+      sink.close();
+    } catch (Throwable e) {
+      if (thrown == null) thrown = e;
+    }
+    closed = true;
+
+    if (thrown != null) Util.sneakyRethrow(thrown);
+  }
+
+  @Override public Timeout timeout() {
+    return sink.timeout();
+  }
+
+  @Override public String toString() {
+    return "buffer(" + sink + ")";
+  }
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/RealBufferedSource.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/RealBufferedSource.java
new file mode 100644
index 0000000..5e49106
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/RealBufferedSource.java
@@ -0,0 +1,408 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.okio;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+
+import static com.android.okhttp.okio.Util.checkOffsetAndCount;
+
+final class RealBufferedSource implements BufferedSource {
+  public final Buffer buffer;
+  public final Source source;
+  private boolean closed;
+
+  public RealBufferedSource(Source source, Buffer buffer) {
+    if (source == null) throw new IllegalArgumentException("source == null");
+    this.buffer = buffer;
+    this.source = source;
+  }
+
+  public RealBufferedSource(Source source) {
+    this(source, new Buffer());
+  }
+
+  @Override public Buffer buffer() {
+    return buffer;
+  }
+
+  @Override public long read(Buffer sink, long byteCount) throws IOException {
+    if (sink == null) throw new IllegalArgumentException("sink == null");
+    if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
+    if (closed) throw new IllegalStateException("closed");
+
+    if (buffer.size == 0) {
+      long read = source.read(buffer, Segment.SIZE);
+      if (read == -1) return -1;
+    }
+
+    long toRead = Math.min(byteCount, buffer.size);
+    return buffer.read(sink, toRead);
+  }
+
+  @Override public boolean exhausted() throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    return buffer.exhausted() && source.read(buffer, Segment.SIZE) == -1;
+  }
+
+  @Override public void require(long byteCount) throws IOException {
+    if (!request(byteCount)) throw new EOFException();
+  }
+
+  @Override public boolean request(long byteCount) throws IOException {
+    if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
+    if (closed) throw new IllegalStateException("closed");
+    while (buffer.size < byteCount) {
+      if (source.read(buffer, Segment.SIZE) == -1) return false;
+    }
+    return true;
+  }
+
+  @Override public byte readByte() throws IOException {
+    require(1);
+    return buffer.readByte();
+  }
+
+  @Override public ByteString readByteString() throws IOException {
+    buffer.writeAll(source);
+    return buffer.readByteString();
+  }
+
+  @Override public ByteString readByteString(long byteCount) throws IOException {
+    require(byteCount);
+    return buffer.readByteString(byteCount);
+  }
+
+  @Override public byte[] readByteArray() throws IOException {
+    buffer.writeAll(source);
+    return buffer.readByteArray();
+  }
+
+  @Override public byte[] readByteArray(long byteCount) throws IOException {
+    require(byteCount);
+    return buffer.readByteArray(byteCount);
+  }
+
+  @Override public int read(byte[] sink) throws IOException {
+    return read(sink, 0, sink.length);
+  }
+
+  @Override public void readFully(byte[] sink) throws IOException {
+    try {
+      require(sink.length);
+    } catch (EOFException e) {
+      // The underlying source is exhausted. Copy the bytes we got before rethrowing.
+      int offset = 0;
+      while (buffer.size > 0) {
+        int read = buffer.read(sink, offset, (int) buffer.size);
+        if (read == -1) throw new AssertionError();
+        offset += read;
+      }
+      throw e;
+    }
+    buffer.readFully(sink);
+  }
+
+  @Override public int read(byte[] sink, int offset, int byteCount) throws IOException {
+    checkOffsetAndCount(sink.length, offset, byteCount);
+
+    if (buffer.size == 0) {
+      long read = source.read(buffer, Segment.SIZE);
+      if (read == -1) return -1;
+    }
+
+    int toRead = (int) Math.min(byteCount, buffer.size);
+    return buffer.read(sink, offset, toRead);
+  }
+
+  @Override public void readFully(Buffer sink, long byteCount) throws IOException {
+    try {
+      require(byteCount);
+    } catch (EOFException e) {
+      // The underlying source is exhausted. Copy the bytes we got before rethrowing.
+      sink.writeAll(buffer);
+      throw e;
+    }
+    buffer.readFully(sink, byteCount);
+  }
+
+  @Override public long readAll(Sink sink) throws IOException {
+    if (sink == null) throw new IllegalArgumentException("sink == null");
+
+    long totalBytesWritten = 0;
+    while (source.read(buffer, Segment.SIZE) != -1) {
+      long emitByteCount = buffer.completeSegmentByteCount();
+      if (emitByteCount > 0) {
+        totalBytesWritten += emitByteCount;
+        sink.write(buffer, emitByteCount);
+      }
+    }
+    if (buffer.size() > 0) {
+      totalBytesWritten += buffer.size();
+      sink.write(buffer, buffer.size());
+    }
+    return totalBytesWritten;
+  }
+
+  @Override public String readUtf8() throws IOException {
+    buffer.writeAll(source);
+    return buffer.readUtf8();
+  }
+
+  @Override public String readUtf8(long byteCount) throws IOException {
+    require(byteCount);
+    return buffer.readUtf8(byteCount);
+  }
+
+  @Override public String readString(Charset charset) throws IOException {
+    if (charset == null) throw new IllegalArgumentException("charset == null");
+
+    buffer.writeAll(source);
+    return buffer.readString(charset);
+  }
+
+  @Override public String readString(long byteCount, Charset charset) throws IOException {
+    require(byteCount);
+    if (charset == null) throw new IllegalArgumentException("charset == null");
+    return buffer.readString(byteCount, charset);
+  }
+
+  @Override public String readUtf8Line() throws IOException {
+    long newline = indexOf((byte) '\n');
+
+    if (newline == -1) {
+      return buffer.size != 0 ? readUtf8(buffer.size) : null;
+    }
+
+    return buffer.readUtf8Line(newline);
+  }
+
+  @Override public String readUtf8LineStrict() throws IOException {
+    long newline = indexOf((byte) '\n');
+    if (newline == -1L) {
+      Buffer data = new Buffer();
+      buffer.copyTo(data, 0, Math.min(32, buffer.size()));
+      throw new EOFException("\\n not found: size=" + buffer.size()
+          + " content=" + data.readByteString().hex() + "...");
+    }
+    return buffer.readUtf8Line(newline);
+  }
+
+  @Override public int readUtf8CodePoint() throws IOException {
+    require(1);
+
+    byte b0 = buffer.getByte(0);
+    if ((b0 & 0xe0) == 0xc0) {
+      require(2);
+    } else if ((b0 & 0xf0) == 0xe0) {
+      require(3);
+    } else if ((b0 & 0xf8) == 0xf0) {
+      require(4);
+    }
+
+    return buffer.readUtf8CodePoint();
+  }
+
+  @Override public short readShort() throws IOException {
+    require(2);
+    return buffer.readShort();
+  }
+
+  @Override public short readShortLe() throws IOException {
+    require(2);
+    return buffer.readShortLe();
+  }
+
+  @Override public int readInt() throws IOException {
+    require(4);
+    return buffer.readInt();
+  }
+
+  @Override public int readIntLe() throws IOException {
+    require(4);
+    return buffer.readIntLe();
+  }
+
+  @Override public long readLong() throws IOException {
+    require(8);
+    return buffer.readLong();
+  }
+
+  @Override public long readLongLe() throws IOException {
+    require(8);
+    return buffer.readLongLe();
+  }
+
+  @Override public long readDecimalLong() throws IOException {
+    require(1);
+
+    for (int pos = 0; request(pos + 1); pos++) {
+      byte b = buffer.getByte(pos);
+      if ((b < '0' || b > '9') && (pos != 0 || b != '-')) {
+        // Non-digit, or non-leading negative sign.
+        if (pos == 0) {
+          throw new NumberFormatException(String.format(
+              "Expected leading [0-9] or '-' character but was %#x", b));
+        }
+        break;
+      }
+    }
+
+    return buffer.readDecimalLong();
+  }
+
+  @Override public long readHexadecimalUnsignedLong() throws IOException {
+    require(1);
+
+    for (int pos = 0; request(pos + 1); pos++) {
+      byte b = buffer.getByte(pos);
+      if ((b < '0' || b > '9') && (b < 'a' || b > 'f') && (b < 'A' || b > 'F')) {
+        // Non-digit, or non-leading negative sign.
+        if (pos == 0) {
+          throw new NumberFormatException(String.format(
+              "Expected leading [0-9a-fA-F] character but was %#x", b));
+        }
+        break;
+      }
+    }
+
+    return buffer.readHexadecimalUnsignedLong();
+  }
+
+  @Override public void skip(long byteCount) throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    while (byteCount > 0) {
+      if (buffer.size == 0 && source.read(buffer, Segment.SIZE) == -1) {
+        throw new EOFException();
+      }
+      long toSkip = Math.min(byteCount, buffer.size());
+      buffer.skip(toSkip);
+      byteCount -= toSkip;
+    }
+  }
+
+  @Override public long indexOf(byte b) throws IOException {
+    return indexOf(b, 0);
+  }
+
+  @Override public long indexOf(byte b, long fromIndex) throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    while (fromIndex >= buffer.size) {
+      if (source.read(buffer, Segment.SIZE) == -1) return -1L;
+    }
+    long index;
+    while ((index = buffer.indexOf(b, fromIndex)) == -1) {
+      fromIndex = buffer.size;
+      if (source.read(buffer, Segment.SIZE) == -1) return -1L;
+    }
+    return index;
+  }
+
+  @Override public long indexOf(ByteString bytes) throws IOException {
+    return indexOf(bytes, 0);
+  }
+
+  @Override public long indexOf(ByteString bytes, long fromIndex) throws IOException {
+    if (bytes.size() == 0) throw new IllegalArgumentException("bytes is empty");
+    while (true) {
+      fromIndex = indexOf(bytes.getByte(0), fromIndex);
+      if (fromIndex == -1) {
+        return -1;
+      }
+      if (rangeEquals(fromIndex, bytes)) {
+        return fromIndex;
+      }
+      fromIndex++;
+    }
+  }
+
+  @Override public long indexOfElement(ByteString targetBytes) throws IOException {
+    return indexOfElement(targetBytes, 0);
+  }
+
+  @Override public long indexOfElement(ByteString targetBytes, long fromIndex) throws IOException {
+    if (closed) throw new IllegalStateException("closed");
+    while (fromIndex >= buffer.size) {
+      if (source.read(buffer, Segment.SIZE) == -1) return -1L;
+    }
+    long index;
+    while ((index = buffer.indexOfElement(targetBytes, fromIndex)) == -1) {
+      fromIndex = buffer.size;
+      if (source.read(buffer, Segment.SIZE) == -1) return -1L;
+    }
+    return index;
+  }
+
+  private boolean rangeEquals(long offset, ByteString bytes) throws IOException {
+    return request(offset + bytes.size()) && buffer.rangeEquals(offset, bytes);
+  }
+
+  @Override public InputStream inputStream() {
+    return new InputStream() {
+      @Override public int read() throws IOException {
+        if (closed) throw new IOException("closed");
+        if (buffer.size == 0) {
+          long count = source.read(buffer, Segment.SIZE);
+          if (count == -1) return -1;
+        }
+        return buffer.readByte() & 0xff;
+      }
+
+      @Override public int read(byte[] data, int offset, int byteCount) throws IOException {
+        if (closed) throw new IOException("closed");
+        checkOffsetAndCount(data.length, offset, byteCount);
+
+        if (buffer.size == 0) {
+          long count = source.read(buffer, Segment.SIZE);
+          if (count == -1) return -1;
+        }
+
+        return buffer.read(data, offset, byteCount);
+      }
+
+      @Override public int available() throws IOException {
+        if (closed) throw new IOException("closed");
+        return (int) Math.min(buffer.size, Integer.MAX_VALUE);
+      }
+
+      @Override public void close() throws IOException {
+        RealBufferedSource.this.close();
+      }
+
+      @Override public String toString() {
+        return RealBufferedSource.this + ".inputStream()";
+      }
+    };
+  }
+
+  @Override public void close() throws IOException {
+    if (closed) return;
+    closed = true;
+    source.close();
+    buffer.clear();
+  }
+
+  @Override public Timeout timeout() {
+    return source.timeout();
+  }
+
+  @Override public String toString() {
+    return "buffer(" + source + ")";
+  }
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Segment.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Segment.java
new file mode 100644
index 0000000..5056a4f
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Segment.java
@@ -0,0 +1,150 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.okio;
+
+/**
+ * A segment of a buffer.
+ *
+ * <p>Each segment in a buffer is a circularly-linked list node referencing the following and
+ * preceding segments in the buffer.
+ *
+ * <p>Each segment in the pool is a singly-linked list node referencing the rest of segments in the
+ * pool.
+ *
+ * <p>The underlying byte arrays of segments may be shared between buffers and byte strings. When a
+ * segment's byte array is shared the segment may not be recycled, nor may its byte data be changed.
+ * The lone exception is that the owner segment is allowed to append to the segment, writing data at
+ * {@code limit} and beyond. There is a single owning segment for each byte array. Positions,
+ * limits, prev, and next references are not shared.
+ */
+final class Segment {
+  /** The size of all segments in bytes. */
+  static final int SIZE = 8192;
+
+  final byte[] data;
+
+  /** The next byte of application data byte to read in this segment. */
+  int pos;
+
+  /** The first byte of available data ready to be written to. */
+  int limit;
+
+  /** True if other segments or byte strings use the same byte array. */
+  boolean shared;
+
+  /** True if this segment owns the byte array and can append to it, extending {@code limit}. */
+  boolean owner;
+
+  /** Next segment in a linked or circularly-linked list. */
+  Segment next;
+
+  /** Previous segment in a circularly-linked list. */
+  Segment prev;
+
+  Segment() {
+    this.data = new byte[SIZE];
+    this.owner = true;
+    this.shared = false;
+  }
+
+  Segment(Segment shareFrom) {
+    this(shareFrom.data, shareFrom.pos, shareFrom.limit);
+    shareFrom.shared = true;
+  }
+
+  Segment(byte[] data, int pos, int limit) {
+    this.data = data;
+    this.pos = pos;
+    this.limit = limit;
+    this.owner = false;
+    this.shared = true;
+  }
+
+  /**
+   * Removes this segment of a circularly-linked list and returns its successor.
+   * Returns null if the list is now empty.
+   */
+  public Segment pop() {
+    Segment result = next != this ? next : null;
+    prev.next = next;
+    next.prev = prev;
+    next = null;
+    prev = null;
+    return result;
+  }
+
+  /**
+   * Appends {@code segment} after this segment in the circularly-linked list.
+   * Returns the pushed segment.
+   */
+  public Segment push(Segment segment) {
+    segment.prev = this;
+    segment.next = next;
+    next.prev = segment;
+    next = segment;
+    return segment;
+  }
+
+  /**
+   * Splits this head of a circularly-linked list into two segments. The first
+   * segment contains the data in {@code [pos..pos+byteCount)}. The second
+   * segment contains the data in {@code [pos+byteCount..limit)}. This can be
+   * useful when moving partial segments from one buffer to another.
+   *
+   * <p>Returns the new head of the circularly-linked list.
+   */
+  public Segment split(int byteCount) {
+    if (byteCount <= 0 || byteCount > limit - pos) throw new IllegalArgumentException();
+    Segment prefix = new Segment(this);
+    prefix.limit = prefix.pos + byteCount;
+    pos += byteCount;
+    prev.push(prefix);
+    return prefix;
+  }
+
+  /**
+   * Call this when the tail and its predecessor may both be less than half
+   * full. This will copy data so that segments can be recycled.
+   */
+  public void compact() {
+    if (prev == this) throw new IllegalStateException();
+    if (!prev.owner) return; // Cannot compact: prev isn't writable.
+    int byteCount = limit - pos;
+    int availableByteCount = SIZE - prev.limit + (prev.shared ? 0 : prev.pos);
+    if (byteCount > availableByteCount) return; // Cannot compact: not enough writable space.
+    writeTo(prev, byteCount);
+    pop();
+    SegmentPool.recycle(this);
+  }
+
+  /** Moves {@code byteCount} bytes from this segment to {@code sink}. */
+  public void writeTo(Segment sink, int byteCount) {
+    if (!sink.owner) throw new IllegalArgumentException();
+    if (sink.limit + byteCount > SIZE) {
+      // We can't fit byteCount bytes at the sink's current position. Shift sink first.
+      if (sink.shared) throw new IllegalArgumentException();
+      if (sink.limit + byteCount - sink.pos > SIZE) throw new IllegalArgumentException();
+      System.arraycopy(sink.data, sink.pos, sink.data, 0, sink.limit - sink.pos);
+      sink.limit -= sink.pos;
+      sink.pos = 0;
+    }
+
+    System.arraycopy(data, pos, sink.data, sink.limit, byteCount);
+    sink.limit += byteCount;
+    pos += byteCount;
+  }
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/SegmentPool.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/SegmentPool.java
new file mode 100644
index 0000000..fdc1395
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/SegmentPool.java
@@ -0,0 +1,61 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.okio;
+
+/**
+ * A collection of unused segments, necessary to avoid GC churn and zero-fill.
+ * This pool is a thread-safe static singleton.
+ */
+final class SegmentPool {
+  /** The maximum number of bytes to pool. */
+  // TODO: Is 64 KiB a good maximum size? Do we ever have that many idle segments?
+  static final long MAX_SIZE = 64 * 1024; // 64 KiB.
+
+  /** Singly-linked list of segments. */
+  static Segment next;
+
+  /** Total bytes in this pool. */
+  static long byteCount;
+
+  private SegmentPool() {
+  }
+
+  static Segment take() {
+    synchronized (SegmentPool.class) {
+      if (next != null) {
+        Segment result = next;
+        next = result.next;
+        result.next = null;
+        byteCount -= Segment.SIZE;
+        return result;
+      }
+    }
+    return new Segment(); // Pool is empty. Don't zero-fill while holding a lock.
+  }
+
+  static void recycle(Segment segment) {
+    if (segment.next != null || segment.prev != null) throw new IllegalArgumentException();
+    if (segment.shared) return; // This segment cannot be recycled.
+    synchronized (SegmentPool.class) {
+      if (byteCount + Segment.SIZE > MAX_SIZE) return; // Pool is full.
+      byteCount += Segment.SIZE;
+      segment.next = next;
+      segment.pos = segment.limit = 0;
+      next = segment;
+    }
+  }
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/SegmentedByteString.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/SegmentedByteString.java
new file mode 100644
index 0000000..bb2dd98
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/SegmentedByteString.java
@@ -0,0 +1,259 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2015 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 com.android.okhttp.okio;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Arrays;
+
+import static com.android.okhttp.okio.Util.arrayRangeEquals;
+import static com.android.okhttp.okio.Util.checkOffsetAndCount;
+
+/**
+ * An immutable byte string composed of segments of byte arrays. This class exists to implement
+ * efficient snapshots of buffers. It is implemented as an array of segments, plus a directory in
+ * two halves that describes how the segments compose this byte string.
+ *
+ * <p>The first half of the directory is the cumulative byte count covered by each segment. The
+ * element at {@code directory[0]} contains the number of bytes held in {@code segments[0]}; the
+ * element at {@code directory[1]} contains the number of bytes held in {@code segments[0] +
+ * segments[1]}, and so on. The element at {@code directory[segments.length - 1]} contains the total
+ * size of this byte string. The first half of the directory is always monotonically increasing.
+ *
+ * <p>The second half of the directory is the offset in {@code segments} of the first content byte.
+ * Bytes preceding this offset are unused, as are bytes beyond the segment's effective size.
+ *
+ * <p>Suppose we have a byte string, {@code [A, B, C, D, E, F, G, H, I, J, K, L, M]} that is stored
+ * across three byte arrays: {@code [x, x, x, x, A, B, C, D, E, x, x, x]}, {@code [x, F, G]}, and
+ * {@code [H, I, J, K, L, M, x, x, x, x, x, x]}. The three byte arrays would be stored in {@code
+ * segments} in order. Since the arrays contribute 5, 2, and 6 elements respectively, the directory
+ * starts with {@code [5, 7, 13} to hold the cumulative total at each position. Since the offsets
+ * into the arrays are 4, 1, and 0 respectively, the directory ends with {@code 4, 1, 0]}.
+ * Concatenating these two halves, the complete directory is {@code [5, 7, 13, 4, 1, 0]}.
+ *
+ * <p>This structure is chosen so that the segment holding a particular offset can be found by
+ * binary search. We use one array rather than two for the directory as a micro-optimization.
+ */
+final class SegmentedByteString extends ByteString {
+  transient final byte[][] segments;
+  transient final int[] directory;
+
+  SegmentedByteString(Buffer buffer, int byteCount) {
+    super(null);
+    checkOffsetAndCount(buffer.size, 0, byteCount);
+
+    // Walk through the buffer to count how many segments we'll need.
+    int offset = 0;
+    int segmentCount = 0;
+    for (Segment s = buffer.head; offset < byteCount; s = s.next) {
+      if (s.limit == s.pos) {
+        throw new AssertionError("s.limit == s.pos"); // Empty segment. This should not happen!
+      }
+      offset += s.limit - s.pos;
+      segmentCount++;
+    }
+
+    // Walk through the buffer again to assign segments and build the directory.
+    this.segments = new byte[segmentCount][];
+    this.directory = new int[segmentCount * 2];
+    offset = 0;
+    segmentCount = 0;
+    for (Segment s = buffer.head; offset < byteCount; s = s.next) {
+      segments[segmentCount] = s.data;
+      offset += s.limit - s.pos;
+      directory[segmentCount] = offset;
+      directory[segmentCount + segments.length] = s.pos;
+      s.shared = true;
+      segmentCount++;
+    }
+  }
+
+  @Override public String utf8() {
+    return toByteString().utf8();
+  }
+
+  @Override public String base64() {
+    return toByteString().base64();
+  }
+
+  @Override public String hex() {
+    return toByteString().hex();
+  }
+
+  @Override public ByteString toAsciiLowercase() {
+    return toByteString().toAsciiLowercase();
+  }
+
+  @Override public ByteString toAsciiUppercase() {
+    return toByteString().toAsciiUppercase();
+  }
+
+  @Override public ByteString md5() {
+    return toByteString().md5();
+  }
+
+  @Override public ByteString sha256() {
+    return toByteString().sha256();
+  }
+
+  @Override public String base64Url() {
+    return toByteString().base64Url();
+  }
+
+  @Override public ByteString substring(int beginIndex) {
+    return toByteString().substring(beginIndex);
+  }
+
+  @Override public ByteString substring(int beginIndex, int endIndex) {
+    return toByteString().substring(beginIndex, endIndex);
+  }
+
+  @Override public byte getByte(int pos) {
+    checkOffsetAndCount(directory[segments.length - 1], pos, 1);
+    int segment = segment(pos);
+    int segmentOffset = segment == 0 ? 0 : directory[segment - 1];
+    int segmentPos = directory[segment + segments.length];
+    return segments[segment][pos - segmentOffset + segmentPos];
+  }
+
+  /** Returns the index of the segment that contains the byte at {@code pos}. */
+  private int segment(int pos) {
+    // Search for (pos + 1) instead of (pos) because the directory holds sizes, not indexes.
+    int i = Arrays.binarySearch(directory, 0, segments.length, pos + 1);
+    return i >= 0 ? i : ~i; // If i is negative, bitflip to get the insert position.
+  }
+
+  @Override public int size() {
+    return directory[segments.length - 1];
+  }
+
+  @Override public byte[] toByteArray() {
+    byte[] result = new byte[directory[segments.length - 1]];
+    int segmentOffset = 0;
+    for (int s = 0, segmentCount = segments.length; s < segmentCount; s++) {
+      int segmentPos = directory[segmentCount + s];
+      int nextSegmentOffset = directory[s];
+      System.arraycopy(segments[s], segmentPos, result, segmentOffset,
+          nextSegmentOffset - segmentOffset);
+      segmentOffset = nextSegmentOffset;
+    }
+    return result;
+  }
+
+  @Override public void write(OutputStream out) throws IOException {
+    if (out == null) throw new IllegalArgumentException("out == null");
+    int segmentOffset = 0;
+    for (int s = 0, segmentCount = segments.length; s < segmentCount; s++) {
+      int segmentPos = directory[segmentCount + s];
+      int nextSegmentOffset = directory[s];
+      out.write(segments[s], segmentPos, nextSegmentOffset - segmentOffset);
+      segmentOffset = nextSegmentOffset;
+    }
+  }
+
+  @Override void write(Buffer buffer) {
+    int segmentOffset = 0;
+    for (int s = 0, segmentCount = segments.length; s < segmentCount; s++) {
+      int segmentPos = directory[segmentCount + s];
+      int nextSegmentOffset = directory[s];
+      Segment segment = new Segment(segments[s], segmentPos,
+          segmentPos + nextSegmentOffset - segmentOffset);
+      if (buffer.head == null) {
+        buffer.head = segment.next = segment.prev = segment;
+      } else {
+        buffer.head.prev.push(segment);
+      }
+      segmentOffset = nextSegmentOffset;
+    }
+    buffer.size += segmentOffset;
+  }
+
+  @Override public boolean rangeEquals(
+      int offset, ByteString other, int otherOffset, int byteCount) {
+    if (offset > size() - byteCount) return false;
+    // Go segment-by-segment through this, passing arrays to other's rangeEquals().
+    for (int s = segment(offset); byteCount > 0; s++) {
+      int segmentOffset = s == 0 ? 0 : directory[s - 1];
+      int segmentSize = directory[s] - segmentOffset;
+      int stepSize = Math.min(byteCount, segmentOffset + segmentSize - offset);
+      int segmentPos = directory[segments.length + s];
+      int arrayOffset = offset - segmentOffset + segmentPos;
+      if (!other.rangeEquals(otherOffset, segments[s], arrayOffset, stepSize)) return false;
+      offset += stepSize;
+      otherOffset += stepSize;
+      byteCount -= stepSize;
+    }
+    return true;
+  }
+
+  @Override public boolean rangeEquals(int offset, byte[] other, int otherOffset, int byteCount) {
+    if (offset > size() - byteCount || otherOffset > other.length - byteCount) return false;
+    // Go segment-by-segment through this, comparing ranges of arrays.
+    for (int s = segment(offset); byteCount > 0; s++) {
+      int segmentOffset = s == 0 ? 0 : directory[s - 1];
+      int segmentSize = directory[s] - segmentOffset;
+      int stepSize = Math.min(byteCount, segmentOffset + segmentSize - offset);
+      int segmentPos = directory[segments.length + s];
+      int arrayOffset = offset - segmentOffset + segmentPos;
+      if (!arrayRangeEquals(segments[s], arrayOffset, other, otherOffset, stepSize)) return false;
+      offset += stepSize;
+      otherOffset += stepSize;
+      byteCount -= stepSize;
+    }
+    return true;
+  }
+
+  /** Returns a copy as a non-segmented byte string. */
+  private ByteString toByteString() {
+    return new ByteString(toByteArray());
+  }
+
+  @Override public boolean equals(Object o) {
+    if (o == this) return true;
+    return o instanceof ByteString
+        && ((ByteString) o).size() == size()
+        && rangeEquals(0, ((ByteString) o), 0, size());
+  }
+
+  @Override public int hashCode() {
+    int result = hashCode;
+    if (result != 0) return result;
+
+    // Equivalent to Arrays.hashCode(toByteArray()).
+    result = 1;
+    int segmentOffset = 0;
+    for (int s = 0, segmentCount = segments.length; s < segmentCount; s++) {
+      byte[] segment = segments[s];
+      int segmentPos = directory[segmentCount + s];
+      int nextSegmentOffset = directory[s];
+      int segmentSize = nextSegmentOffset - segmentOffset;
+      for (int i = segmentPos, limit = segmentPos + segmentSize; i < limit; i++) {
+        result = (31 * result) + segment[i];
+      }
+      segmentOffset = nextSegmentOffset;
+    }
+    return (hashCode = result);
+  }
+
+  @Override public String toString() {
+    return toByteString().toString();
+  }
+
+  private Object writeReplace() {
+    return toByteString();
+  }
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Sink.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Sink.java
new file mode 100644
index 0000000..e0a4eea
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Sink.java
@@ -0,0 +1,69 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.okio;
+
+import java.io.Closeable;
+import java.io.Flushable;
+import java.io.IOException;
+
+/**
+ * Receives a stream of bytes. Use this interface to write data wherever it's
+ * needed: to the network, storage, or a buffer in memory. Sinks may be layered
+ * to transform received data, such as to compress, encrypt, throttle, or add
+ * protocol framing.
+ *
+ * <p>Most application code shouldn't operate on a sink directly, but rather
+ * {@link BufferedSink} which is both more efficient and more convenient. Use
+ * {@link Okio#buffer(Sink)} to wrap any sink with a buffer.
+ *
+ * <p>Sinks are easy to test: just use an {@link Buffer} in your tests, and
+ * read from it to confirm it received the data that was expected.
+ *
+ * <h3>Comparison with OutputStream</h3>
+ * This interface is functionally equivalent to {@link java.io.OutputStream}.
+ *
+ * <p>{@code OutputStream} requires multiple layers when emitted data is
+ * heterogeneous: a {@code DataOutputStream} for primitive values, a {@code
+ * BufferedOutputStream} for buffering, and {@code OutputStreamWriter} for
+ * charset encoding. This class uses {@code BufferedSink} for all of the above.
+ *
+ * <p>Sink is also easier to layer: there is no {@linkplain
+ * java.io.OutputStream#write(int) single-byte write} method that is awkward to
+ * implement efficiently.
+ *
+ * <h3>Interop with OutputStream</h3>
+ * Use {@link Okio#sink} to adapt an {@code OutputStream} to a sink. Use {@link
+ * BufferedSink#outputStream} to adapt a sink to an {@code OutputStream}.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface Sink extends Closeable, Flushable {
+  /** Removes {@code byteCount} bytes from {@code source} and appends them to this. */
+  void write(Buffer source, long byteCount) throws IOException;
+
+  /** Pushes all buffered bytes to their final destination. */
+  @Override void flush() throws IOException;
+
+  /** Returns the timeout for this sink. */
+  Timeout timeout();
+
+  /**
+   * Pushes all buffered bytes to their final destination and releases the
+   * resources held by this sink. It is an error to write a closed sink. It is
+   * safe to close a sink more than once.
+   */
+  @Override void close() throws IOException;
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Source.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Source.java
new file mode 100644
index 0000000..6af20cd
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Source.java
@@ -0,0 +1,80 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.okio;
+
+import java.io.Closeable;
+import java.io.IOException;
+
+/**
+ * Supplies a stream of bytes. Use this interface to read data from wherever
+ * it's located: from the network, storage, or a buffer in memory. Sources may
+ * be layered to transform supplied data, such as to decompress, decrypt, or
+ * remove protocol framing.
+ *
+ * <p>Most applications shouldn't operate on a source directly, but rather
+ * {@link BufferedSource} which is both more efficient and more convenient. Use
+ * {@link Okio#buffer(Source)} to wrap any source with a buffer.
+ *
+ * <p>Sources are easy to test: just use an {@link Buffer} in your tests, and
+ * fill it with the data your application is to read.
+ *
+ * <h3>Comparison with InputStream</h3>
+ * This interface is functionally equivalent to {@link java.io.InputStream}.
+ *
+ * <p>{@code InputStream} requires multiple layers when consumed data is
+ * heterogeneous: a {@code DataInputStream} for primitive values, a {@code
+ * BufferedInputStream} for buffering, and {@code InputStreamReader} for
+ * strings. This class uses {@code BufferedSource} for all of the above.
+ *
+ * <p>Source avoids the impossible-to-implement {@linkplain
+ * java.io.InputStream#available available()} method. Instead callers specify
+ * how many bytes they {@link BufferedSource#require require}.
+ *
+ * <p>Source omits the unsafe-to-compose {@linkplain java.io.InputStream#mark
+ * mark and reset} state that's tracked by {@code InputStream}; callers instead
+ * just buffer what they need.
+ *
+ * <p>When implementing a source, you need not worry about the {@linkplain
+ * java.io.InputStream#read single-byte read} method that is awkward to
+ * implement efficiently and that returns one of 257 possible values.
+ *
+ * <p>And source has a stronger {@code skip} method: {@link BufferedSource#skip}
+ * won't return prematurely.
+ *
+ * <h3>Interop with InputStream</h3>
+ * Use {@link Okio#source} to adapt an {@code InputStream} to a source. Use
+ * {@link BufferedSource#inputStream} to adapt a source to an {@code
+ * InputStream}.
+ * @hide This class is not part of the Android public SDK API
+ */
+public interface Source extends Closeable {
+  /**
+   * Removes at least 1, and up to {@code byteCount} bytes from this and appends
+   * them to {@code sink}. Returns the number of bytes read, or -1 if this
+   * source is exhausted.
+   */
+  long read(Buffer sink, long byteCount) throws IOException;
+
+  /** Returns the timeout for this source. */
+  Timeout timeout();
+
+  /**
+   * Closes this source and releases the resources held by this source. It is an
+   * error to read a closed source. It is safe to close a source more than once.
+   */
+  @Override void close() throws IOException;
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Timeout.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Timeout.java
new file mode 100644
index 0000000..7b757d2
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Timeout.java
@@ -0,0 +1,154 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.okio;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A policy on how much time to spend on a task before giving up. When a task
+ * times out, it is left in an unspecified state and should be abandoned. For
+ * example, if reading from a source times out, that source should be closed and
+ * the read should be retried later. If writing to a sink times out, the same
+ * rules apply: close the sink and retry later.
+ *
+ * <h3>Timeouts and Deadlines</h3>
+ * This class offers two complementary controls to define a timeout policy.
+ *
+ * <p><strong>Timeouts</strong> specify the maximum time to wait for a single
+ * operation to complete. Timeouts are typically used to detect problems like
+ * network partitions. For example, if a remote peer doesn't return <i>any</i>
+ * data for ten seconds, we may assume that the peer is unavailable.
+ *
+ * <p><strong>Deadlines</strong> specify the maximum time to spend on a job,
+ * composed of one or more operations. Use deadlines to set an upper bound on
+ * the time invested on a job. For example, a battery-conscious app may limit
+ * how much time it spends preloading content.
+ * @hide This class is not part of the Android public SDK API
+ */
+public class Timeout {
+  /**
+   * An empty timeout that neither tracks nor detects timeouts. Use this when
+   * timeouts aren't necessary, such as in implementations whose operations
+   * do not block.
+   */
+  public static final Timeout NONE = new Timeout() {
+    @Override public Timeout timeout(long timeout, TimeUnit unit) {
+      return this;
+    }
+
+    @Override public Timeout deadlineNanoTime(long deadlineNanoTime) {
+      return this;
+    }
+
+    @Override public void throwIfReached() throws IOException {
+    }
+  };
+
+  /**
+   * True if {@code deadlineNanoTime} is defined. There is no equivalent to null
+   * or 0 for {@link System#nanoTime}.
+   */
+  private boolean hasDeadline;
+  private long deadlineNanoTime;
+  private long timeoutNanos;
+
+  public Timeout() {
+  }
+
+  /**
+   * Wait at most {@code timeout} time before aborting an operation. Using a
+   * per-operation timeout means that as long as forward progress is being made,
+   * no sequence of operations will fail.
+   *
+   * <p>If {@code timeout == 0}, operations will run indefinitely. (Operating
+   * system timeouts may still apply.)
+   */
+  public Timeout timeout(long timeout, TimeUnit unit) {
+    if (timeout < 0) throw new IllegalArgumentException("timeout < 0: " + timeout);
+    if (unit == null) throw new IllegalArgumentException("unit == null");
+    this.timeoutNanos = unit.toNanos(timeout);
+    return this;
+  }
+
+  /** Returns the timeout in nanoseconds, or {@code 0} for no timeout. */
+  public long timeoutNanos() {
+    return timeoutNanos;
+  }
+
+  /** Returns true if a deadline is enabled. */
+  public boolean hasDeadline() {
+    return hasDeadline;
+  }
+
+  /**
+   * Returns the {@linkplain System#nanoTime() nano time} when the deadline will
+   * be reached.
+   *
+   * @throws IllegalStateException if no deadline is set.
+   */
+  public long deadlineNanoTime() {
+    if (!hasDeadline) throw new IllegalStateException("No deadline");
+    return deadlineNanoTime;
+  }
+
+  /**
+   * Sets the {@linkplain System#nanoTime() nano time} when the deadline will be
+   * reached. All operations must complete before this time. Use a deadline to
+   * set a maximum bound on the time spent on a sequence of operations.
+   */
+  public Timeout deadlineNanoTime(long deadlineNanoTime) {
+    this.hasDeadline = true;
+    this.deadlineNanoTime = deadlineNanoTime;
+    return this;
+  }
+
+  /** Set a deadline of now plus {@code duration} time. */
+  public final Timeout deadline(long duration, TimeUnit unit) {
+    if (duration <= 0) throw new IllegalArgumentException("duration <= 0: " + duration);
+    if (unit == null) throw new IllegalArgumentException("unit == null");
+    return deadlineNanoTime(System.nanoTime() + unit.toNanos(duration));
+  }
+
+  /** Clears the timeout. Operating system timeouts may still apply. */
+  public Timeout clearTimeout() {
+    this.timeoutNanos = 0;
+    return this;
+  }
+
+  /** Clears the deadline. */
+  public Timeout clearDeadline() {
+    this.hasDeadline = false;
+    return this;
+  }
+
+  /**
+   * Throws an {@link InterruptedIOException} if the deadline has been reached or if the current
+   * thread has been interrupted. This method doesn't detect timeouts; that should be implemented to
+   * asynchronously abort an in-progress operation.
+   */
+  public void throwIfReached() throws IOException {
+    if (Thread.interrupted()) {
+      throw new InterruptedIOException("thread interrupted");
+    }
+
+    if (hasDeadline && deadlineNanoTime - System.nanoTime() <= 0) {
+      throw new InterruptedIOException("deadline reached");
+    }
+  }
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Util.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Util.java
new file mode 100644
index 0000000..11ecf96
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/Util.java
@@ -0,0 +1,81 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/*
+ * Copyright (C) 2014 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 com.android.okhttp.okio;
+
+import java.nio.charset.Charset;
+
+final class Util {
+  /** A cheap and type-safe constant for the UTF-8 Charset. */
+  public static final Charset UTF_8 = Charset.forName("UTF-8");
+
+  private Util() {
+  }
+
+  public static void checkOffsetAndCount(long size, long offset, long byteCount) {
+    if ((offset | byteCount) < 0 || offset > size || size - offset < byteCount) {
+      throw new ArrayIndexOutOfBoundsException(
+          String.format("size=%s offset=%s byteCount=%s", size, offset, byteCount));
+    }
+  }
+
+  public static short reverseBytesShort(short s) {
+    int i = s & 0xffff;
+    int reversed = (i & 0xff00) >>> 8
+        |          (i & 0x00ff)  << 8;
+    return (short) reversed;
+  }
+
+  public static int reverseBytesInt(int i) {
+    return (i & 0xff000000) >>> 24
+        |  (i & 0x00ff0000) >>>  8
+        |  (i & 0x0000ff00)  <<  8
+        |  (i & 0x000000ff)  << 24;
+  }
+
+  public static long reverseBytesLong(long v) {
+    return (v & 0xff00000000000000L) >>> 56
+        |  (v & 0x00ff000000000000L) >>> 40
+        |  (v & 0x0000ff0000000000L) >>> 24
+        |  (v & 0x000000ff00000000L) >>>  8
+        |  (v & 0x00000000ff000000L)  <<  8
+        |  (v & 0x0000000000ff0000L)  << 24
+        |  (v & 0x000000000000ff00L)  << 40
+        |  (v & 0x00000000000000ffL)  << 56;
+  }
+
+  /**
+   * Throws {@code t}, even if the declared throws clause doesn't permit it.
+   * This is a terrible – but terribly convenient – hack that makes it easy to
+   * catch and rethrow exceptions after cleanup. See Java Puzzlers #43.
+   */
+  public static void sneakyRethrow(Throwable t) {
+    Util.<Error>sneakyThrow2(t);
+  }
+
+  @SuppressWarnings("unchecked")
+  private static <T extends Throwable> void sneakyThrow2(Throwable t) throws T {
+    throw (T) t;
+  }
+
+  public static boolean arrayRangeEquals(
+      byte[] a, int aOffset, byte[] b, int bOffset, int byteCount) {
+    for (int i = 0; i < byteCount; i++) {
+      if (a[i + aOffset] != b[i + bOffset]) return false;
+    }
+    return true;
+  }
+}
diff --git a/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/package-info.java b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/package-info.java
new file mode 100644
index 0000000..f4f659e
--- /dev/null
+++ b/repackaged/okio/okio/src/main/java/com/android/okhttp/okio/package-info.java
@@ -0,0 +1,6 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+/**
+ * Okio complements {@link java.io} and {@link java.nio} to make it much easier to access, store,
+ * and process your data.
+ */
+package com.android.okhttp.okio;
diff --git a/srcgen/generate_android_src.sh b/srcgen/generate_android_src.sh
new file mode 100755
index 0000000..b50c90d
--- /dev/null
+++ b/srcgen/generate_android_src.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+if [ -z "$ANDROID_BUILD_TOP" ]; then
+    echo "Missing environment variables. Did you run build/envsetup.sh and lunch?" 1>&2
+    exit 1
+fi
+
+CLASSPATH=${ANDROID_HOST_OUT}/framework/currysrc.jar
+PROJECT_DIR=${ANDROID_BUILD_TOP}/external/okhttp
+
+cd ${ANDROID_BUILD_TOP}
+make -j15 currysrc
+
+function do_transform() {
+  local SRC_IN_DIR=$1
+  local SRC_OUT_DIR=$2
+
+  if [ ! -d $SRC_OUT_DIR ]; then
+    echo ${SRC_OUT_DIR} does not exist >&2
+    exit 1
+  fi
+  rm -rf ${SRC_OUT_DIR}
+  mkdir -p ${SRC_OUT_DIR}
+
+  java -cp ${CLASSPATH} com.google.currysrc.aosp.RepackagingTransform \
+       --source-dir ${SRC_IN_DIR} \
+       --target-dir ${SRC_OUT_DIR} \
+       --package-transformation "com.squareup:com.android" \
+       --package-transformation "okio:com.android.okhttp.okio" \
+       --tab-size 2 \
+
+}
+
+REPACKAGED_DIR=${PROJECT_DIR}/repackaged
+for i in android okhttp okhttp-urlconnection okhttp-android-support okio/okio
+do
+  for s in src/main/java
+  do
+    IN=${PROJECT_DIR}/$i/$s
+    if [ -d $IN ]; then
+      OUT=${REPACKAGED_DIR}/$i/$s
+      do_transform ${IN} ${OUT}
+    fi
+  done
+done
+
+# Remove an unused source file:
+rm ${REPACKAGED_DIR}/okhttp/src/main/java/com/android/okhttp/internal/Platform.java
