diff --git a/.buildscript/prepare_mkdocs.sh b/.buildscript/prepare_mkdocs.sh
new file mode 100755
index 0000000..5dcb42c
--- /dev/null
+++ b/.buildscript/prepare_mkdocs.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+# The website is built using MkDocs with the Material theme.
+# https://squidfunk.github.io/mkdocs-material/
+# It requires Python to run.
+# Install the packages with the following command:
+# pip install mkdocs mkdocs-material
+
+set -ex
+
+# Generate the API docs
+./gradlew okio:dokkaHtml
+
+# Copy in special files that GitHub wants in the project root.
+cp CHANGELOG.md docs/changelog.md
+cp CONTRIBUTING.md docs/contributing.md
diff --git a/.buildscript/restore_v1_docs.sh b/.buildscript/restore_v1_docs.sh
new file mode 100644
index 0000000..220fed8
--- /dev/null
+++ b/.buildscript/restore_v1_docs.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+# Commit b3205fa199a19d6fbf13ee5c8e0c3d6d2b15b05f contains
+# Javadoc for Okio 1.x. Those should be present on 
+# gh-pages and published along with the other website 
+# content, but if for some reason they have to be re-added 
+# to gh-pages - run this script locally.
+
+set -ex
+
+REPO="git@github.com:square/okio.git"	
+DIR=temp-clone	
+
+# Delete any existing temporary website clone	
+rm -rf $DIR	
+
+# Clone the current repo into temp folder	
+git clone $REPO $DIR	
+
+# Move working directory into temp folder	
+cd $DIR
+
+# Restore Javadocs from 1.x	
+git checkout gh-pages	
+git cherry-pick b3205fa199a19d6fbf13ee5c8e0c3d6d2b15b05f	
+git push	
+
+# Delete our temp folder	
+cd ..	
+rm -rf $DIR
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..15d8bd6
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,5 @@
+[*.kt]
+indent_size = 2
+
+[*.gradle]
+indent_size = 2
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..26b2689
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,162 @@
+name: build
+
+on: [push, pull_request]
+
+env:
+  GRADLE_OPTS: "-Dorg.gradle.jvmargs=-Xmx4g -Dorg.gradle.daemon=false -Dkotlin.incremental=false"
+
+jobs:
+  jvm:
+    runs-on: ubuntu-latest
+
+    strategy:
+      fail-fast: false
+      matrix:
+        java-version:
+          - 1.8
+          - 9
+          - 10
+          - 11
+          - 12
+          - 13
+          - 14
+          - 15
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+
+      - name: Validate Gradle Wrapper
+        uses: gradle/wrapper-validation-action@v1
+
+      - name: Configure JDK
+        uses: actions/setup-java@v1
+        with:
+          java-version: ${{ matrix.java-version }}
+
+      - name: Test
+        run: |
+          ./gradlew -Dkjs=false -Dknative=false build
+
+      - name: Upload Japicmp report
+        if: failure()
+        uses: actions/upload-artifact@master
+        with:
+          name: japicmp-report
+          path: okio/jvm/japicmp/build/reports/japi.txt
+
+  multiplatform:
+    runs-on: macOS-latest
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+
+      - name: Validate Gradle Wrapper
+        uses: gradle/wrapper-validation-action@v1
+
+      - name: Configure JDK
+        uses: actions/setup-java@v1
+        with:
+          java-version: 14
+
+      - name: Test
+        run: |
+          ./gradlew build
+
+  windows:
+    runs-on: windows-latest
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+
+      - name: Validate Gradle Wrapper
+        uses: gradle/wrapper-validation-action@v1
+
+      - name: Configure JDK
+        uses: actions/setup-java@v1
+        with:
+          java-version: 1.8
+
+      - name: Test
+        run: |
+          ./gradlew build
+
+  publish:
+    runs-on: macOS-latest
+    if: github.ref == 'refs/heads/master'
+    needs: [jvm, multiplatform, windows]
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+
+      - name: Configure JDK
+        uses: actions/setup-java@v1
+        with:
+          java-version: 14
+
+      - name: Upload Artifacts
+        run: |
+          ./gradlew clean publish
+        env:
+          ORG_GRADLE_PROJECT_SONATYPE_NEXUS_USERNAME: ${{ secrets.SONATYPE_NEXUS_USERNAME }}
+          ORG_GRADLE_PROJECT_SONATYPE_NEXUS_PASSWORD: ${{ secrets.SONATYPE_NEXUS_PASSWORD }}
+
+  publish-windows:
+    runs-on: windows-latest
+    if: github.ref == 'refs/heads/master'
+    needs: [jvm, multiplatform, windows]
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+
+      - name: Configure JDK
+        uses: actions/setup-java@v1
+        with:
+          java-version: 1.8
+
+      - name: Upload Artifacts
+        run: |
+          ./gradlew clean publishMingwX64PublicationToMavenRepository
+        env:
+          ORG_GRADLE_PROJECT_SONATYPE_NEXUS_USERNAME: ${{ secrets.SONATYPE_NEXUS_USERNAME }}
+          ORG_GRADLE_PROJECT_SONATYPE_NEXUS_PASSWORD: ${{ secrets.SONATYPE_NEXUS_PASSWORD }}
+
+  publish-website:
+    runs-on: ubuntu-latest
+    if: github.ref == 'refs/heads/master'
+    needs: [jvm, multiplatform]
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+
+      - name: Configure JDK
+        uses: actions/setup-java@v1
+        with:
+          java-version: 14
+
+      - name: Set up Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: 3.8
+
+      - name: Prepare docs
+        run: .buildscript/prepare_mkdocs.sh
+
+      - name: Build mkdocs
+        run: |
+          pip3 install mkdocs-macros-plugin
+          mkdocs build
+
+      - name: Deploy docs
+        if: success()
+        uses: JamesIves/github-pages-deploy-action@releases/v3
+        with:
+          GITHUB_TOKEN: ${{ secrets.GH_CLIPPY_TOKEN }}
+          BRANCH: gh-pages
+          FOLDER: site
+          SINGLE_COMMIT: true
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..451ec21
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,30 @@
+.classpath
+.gradle
+.project
+.settings
+eclipsebin
+
+bin
+gen
+build
+out
+lib
+reports
+
+.idea
+*.iml
+*.ipr
+*.iws
+classes
+local.properties
+
+obj
+
+.DS_Store
+
+node_modules
+
+# Special Mkdocs files
+docs/2.x
+docs/changelog.md
+docs/contributing.md
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..cf49f1c
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,15 @@
+java_library {
+    name: "okio-lib",
+    srcs: [
+        "okio/src/jvmMain/**/*.kt",
+        "okio/src/commonMain/**/*.kt",
+    ],
+    static_libs: [
+        "guava-android-annotation-stubs",
+    ],
+    kotlincflags: [
+        "-Xmulti-platform",
+    ],
+    sdk_version: "current",
+    java_version: "1.7",
+}
diff --git a/BUG-BOUNTY.md b/BUG-BOUNTY.md
new file mode 100644
index 0000000..c8c3b94
--- /dev/null
+++ b/BUG-BOUNTY.md
@@ -0,0 +1,10 @@
+Serious about security
+======================
+
+Square recognizes the important contributions the security research community
+can make. We therefore encourage reporting security issues with the code
+contained in this repository.
+
+If you believe you have discovered a security vulnerability, please follow the
+guidelines at https://bugcrowd.com/squareopensource
+
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..48028d0
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,583 @@
+Change Log
+==========
+
+## Version 2.9.0
+
+_2020-10-04_
+
+ * Fix: Don't corrupt the `Buffer` when writing a slice of a segmented `ByteString`. We had a severe
+   bug where `ByteString` instances created with `snapshot()` and `readByteString()` incorrectly
+   adjusted the buffer's size by their full length, not the length of the slice. This would have
+   caused buffer reads to crash! We do not believe data was silently corrupted.
+ * New: `CipherSink` and `CipherSource`. Use these with `javax.crypto.Cipher` to encrypt and decrypt
+   streams of data. This is a low-level encryption API; most applications should use higher-level
+   APIs like TLS when available.
+ * New: Promote hash functions `md5`, `sha1()`, `sha512()`, and `sha256()` to common Kotlin. These
+   are currently only available on `ByteString`, multiplatform support for `HashingSource`,
+   `HashingSink`, and `Buffer` should come in a follow-up release. We wrote and optimized our own
+   implementations of these hash functions in Kotlin. On JVM and Android platforms Okio still uses
+   the platform's built-in hash functions.
+ * New: Support OSGi metadata.
+ * Upgrade: [Kotlin 1.4.10][kotlin_1_4_10].
+
+
+## Version 2.8.0
+
+_2020-08-17_
+
+ * New: Upgrade to Kotlin 1.4.0.
+
+
+## Version 2.7.0
+
+_2020-07-07_
+
+ * New: `Pipe.cancel()` causes in-progress and future reads and writes on the pipe to immediately
+   fail with an `IOException`. The streams may still be canceled normally.
+   
+ * New: Enlarge Okio's internal segment pool from a fixed 64 KiB total to 64 KiB per processor. For
+   example, on an Intel i9 8-core/16-thread machine the segment pool now uses up to 1 MiB of memory.  
+ 
+ * New: Migrate from `synchronized` to lock-free when accessing the segment pool. Combined with the
+   change above we saw throughput increase 3x on a synthetic benchmark designed to create
+   contention.
+
+
+## Version 2.6.0
+
+_2020-04-22_
+
+ * New: `InflaterSource.readOrInflate()` is like `InflaterSource.read()`, except it will return 0 if
+   consuming deflated bytes from the underlying stream did not produce new inflated bytes.
+
+
+## Version 2.5.0
+
+_2020-03-20_
+
+ * New: Upgrade to Kotlin 1.3.70.
+
+
+## Version 2.4.3
+
+_2019-12-20_
+
+ * New: Upgrade to Kotlin 1.3.61.
+
+
+## Version 2.4.2
+
+_2019-12-11_
+
+ * Fix: Don't crash when an `InputStream` source is exhausted exactly at a buffer segment boundary.
+   We had a bug where a sequence of reads could violate a buffer's invariants, and this could result
+   in a crash when subsequent reads encountered an unexpected empty segment.
+
+
+## Version 1.17.5
+
+_2019-12-11_
+
+ * Fix: Don't crash when an `InputStream` source is exhausted exactly at a buffer segment boundary.
+   We had a bug where a sequence of reads could violate a buffer's invariants, and this could result
+   in a crash when subsequent reads encountered an unexpected empty segment.
+
+
+### Version 2.4.1
+
+_2019-10-04_
+
+ * Fix: Don't cache hash code and UTF-8 string in `ByteString` on Kotlin/Native which prevented freezing.
+
+### Version 2.4.0
+
+_2019-08-26_
+
+ * New: Upgrade to Kotlin 1.3.50.
+
+
+### Version 2.3.0
+
+_2019-07-29_
+
+**This release changes our build from Kotlin-JVM to Kotlin-multiplatform (which includes JVM).**
+Both native and JavaScript platforms are unstable preview releases and subject to
+backwards-incompatible changes in forthcoming releases.
+
+To try Okio in a multiplatform project use this Maven coordinate:
+
+```kotlin
+api('com.squareup.okio:okio-multiplatform:2.3.0')
+```
+
+You’ll also need to [enable Gradle metadata][gradle_metadata] in your project's settings. The
+artifact name for JVM projects has not changed.
+
+ * New: Upgrade to Kotlin 1.3.40.
+ * Fix: Use Gradle `api` instead of `implementation` for the kotlin-stdlib dependency.
+ * Fix: Don't block unless strictly necessary in `BufferedSource.peek()`.
+
+## Version 1.17.4
+
+_2019-04-29_
+
+ * Fix: Don't block unless strictly necessary in `BufferedSource.peek()`.
+
+
+## Version 2.2.2
+
+_2019-01-28_
+
+ * Fix: Make `Pipe.fold()` close the underlying sink when necessary.
+
+
+## Version 1.17.3
+
+_2019-01-28_
+
+ * Fix: Make `Pipe.fold()` close the underlying sink when necessary.
+
+
+## Version 1.17.2
+
+_2019-01-17_
+
+ * Fix: Make `Pipe.fold()` flush the underlying sink.
+
+
+## Version 2.2.1
+
+_2019-01-17_
+
+ * Fix: Make `Pipe.fold()` flush the underlying sink.
+
+
+## Version 2.2.0
+
+_2019-01-16_
+
+ * New: `Throttler` limits sources and sinks to a maximum desired throughput. Multiple sources and
+   sinks can be attached to the same throttler and their combined throughput will not exceed the
+   desired throughput. Multiple throttlers can also be used on the same source or sink and they will
+   all be honored.
+
+ * New: `Pipe.fold()` replaces the actively-readable `Source` with a passively-writable `Sink`.
+   This can be used to forward one sink to a target that is initially undetermined.
+
+ * New: Optimize performance of ByteStrings created with `Buffer.snapshot()`.
+
+
+## Version 1.17.1
+
+_2019-01-16_
+
+ * Fix: Make the newly-backported `Pipe.fold()` public.
+
+
+## Version 1.17.0
+
+_2019-01-16_
+
+ * New: Backport `Pipe.fold()` to Okio 1.x.
+
+
+## Version 1.16.0
+
+_2018-10-08_
+
+ * New: Backport `BufferedSource.peek()` and `BufferedSource.getBuffer()` to Okio 1.x.
+ * Fix: Enforce timeouts when closing `AsyncTimeout` sources.
+
+
+## Version 2.1.0
+
+_2018-09-22_
+
+ * New: `BufferedSource.peek()` returns another `BufferedSource` that reads ahead on the current
+   source. Use this to process the same data multiple times.
+
+ * New: Deprecate `BufferedSource.buffer()`, replacing it with either `BufferedSource.getBuffer()`
+   (in Java) or `BufferedSource.buffer` (in Kotlin). We have done likewise for `BufferedSink`.
+   When we introduced the new extension method `Source.buffer()` in Okio 2.0 we inadvertently
+   collided with an existing method. This fixes that.
+
+ * New: Improve performance of `Buffer.writeUtf8()`. This comes alongside initial implementation of
+   UTF-8 encoding and decoding in JavaScript which [uses XOR masks][xor_utf8] for great performance.
+
+
+## Version 2.0.0
+
+_2018-08-27_
+
+This release commits to a stable 2.0 API. Read the 2.0.0-RC1 changes for advice on upgrading from
+1.x to 2.x.
+
+We've also added APIs to ease migration for Kotlin users. They use Kotlin's `@Deprecated` annotation
+to help you change call sites from the 1.x style to the 2.x style.
+
+
+## Version 2.0.0-RC1
+
+_2018-07-26_
+
+Okio 2 is a major release that upgrades the library's implementation language from Java to Kotlin.
+
+Okio 2.x is **binary-compatible** with Okio 1.x and does not change any behavior. Classes and .jar
+files compiled against 1.x can be used with 2.x without recompiling.
+
+Okio 2.x is **.java source compatible** with Okio 1.x in all but one corner case. In Okio 1.x
+`Buffer` would throw an unchecked `IllegalStateException` when attempting to read more bytes than
+available. Okio 2.x now throws a checked `EOFException` in this case. This is now consistent with
+the behavior of its `BufferedSource` interface. Java callers that don't already catch `IOException`
+will now need to.
+
+Okio 2.x is **.kt source-incompatible** with Okio 1.x. This release adopts Kotlin idioms where they
+are available.
+
+| Java                                     |  Kotlin                              | Idiom              |
+| :--------------------------------------- |  :---------------------------------- | :----------------- |
+| Buffer.getByte()                         |  operator fun Buffer.get()           | operator function  |
+| Buffer.size()                            |  val Buffer.size                     | val                |
+| ByteString.decodeBase64(String)          |  fun String.decodeBase64()           | extension function |
+| ByteString.decodeHex(String)             |  fun String.decodeHex()              | extension function |
+| ByteString.encodeString(String, Charset) |  fun String.encode(Charset)          | extension function |
+| ByteString.encodeUtf8(String)            |  fun String.encodeUtf8()             | extension function |
+| ByteString.getByte()                     |  operator fun ByteString.get()       | operator function  |
+| ByteString.of(ByteBuffer)                |  fun ByteBuffer.toByteString()       | extension function |
+| ByteString.of(byte[], int, int)          |  fun ByteArray.toByteString()        | extension function |
+| ByteString.read(InputStream, int)        |  fun InputStream.readByteString(Int) | extension function |
+| ByteString.size()                        |  val ByteString.size                 | val                |
+| DeflaterSink(Sink)                       |  fun Sink.deflater()                 | extension function |
+| ForwardingSink.delegate()                |  val ForwardingSink.delegate         | val                |
+| ForwardingSource.delegate()              |  val ForwardingSource.delegate       | val                |
+| GzipSink(Sink, Deflater)                 |  fun Sink.gzip()                     | extension function |
+| GzipSink.deflater()                      |  val GzipSink.deflater               | val                |
+| GzipSource(Source)                       |  fun Source.gzip()                   | extension function |
+| HashingSink.hash()                       |  val HashingSink.hash                | val                |
+| HashingSource.hash()                     |  val HashingSource.hash              | val                |
+| InflaterSink(Source)                     |  fun Source.inflater()               | extension function |
+| Okio.appendingSink(File)                 |  fun File.appendingSink()            | extension function |
+| Okio.blackhole()                         |  fun blackholeSink()                 | top level function |
+| Okio.buffer(Sink)                        |  fun Sink.buffer()                   | extension function |
+| Okio.buffer(Source)                      |  fun Source.buffer()                 | extension function |
+| Okio.sink(File)                          |  fun File.sink()                     | extension function |
+| Okio.sink(OutputStream)                  |  fun OutputStream.sink()             | extension function |
+| Okio.sink(Path)                          |  fun Path.sink()                     | extension function |
+| Okio.sink(Socket)                        |  fun Socket.sink()                   | extension function |
+| Okio.source(File)                        |  fun File.source()                   | extension function |
+| Okio.source(InputStream)                 |  fun InputStream.source()            | extension function |
+| Okio.source(Path)                        |  fun Path.source()                   | extension function |
+| Okio.source(Socket)                      |  fun Socket.source()                 | extension function |
+| Pipe.sink()                              |  val Pipe.sink                       | val                |
+| Pipe.source()                            |  val Pipe.source                     | val                |
+| Utf8.size(String)                        |  fun String.utf8Size()               | extension function |
+
+Okio 2.x has **similar performance** to Okio 1.x. We benchmarked both versions to find potential
+performance regressions. We found one regression and fixed it: we were using `==` instead of `===`.
+
+Other changes in this release:
+
+ * New: Add a dependency on kotlin-stdlib. Okio's transitive dependencies grow from none in 1.x to
+   three in 2.x. These are kotlin-stdlib (939 KiB), kotlin-stdlib-common (104 KiB), and JetBrains'
+   annotations (17 KiB).
+
+ * New: Change Okio to build with Gradle instead of Maven.
+
+
+## Version 1.15.0
+
+_2018-07-18_
+
+ * New: Trie-based `Buffer.select()`. This improves performance when selecting
+   among large lists of options.
+ * Fix: Retain interrupted state when throwing `InterruptedIOException`.
+
+
+## Version 1.14.0
+
+_2018-02-11_
+
+ * New: `Buffer.UnsafeCursor` provides direct access to Okio internals. This API
+   is like Okio's version of Java reflection: it's a very powerful API that can
+   be used for great things and dangerous things alike. The documentation is
+   extensive and anyone using it should review it carefully before proceeding!
+ * New: Change `BufferedSource` to implement `java.nio.ReadableByteChannel` and
+   `BufferedSink` to implement `java.nio.WritableByteChannel`. Now it's a little
+   easier to interop between Okio and NIO.
+ * New: Automatic module name of `okio` for use with the Java Platform Module
+   System.
+ * New: Optimize `Buffer.getByte()` to search backwards when doing so will be
+   more efficient.
+ * Fix: Honor the requested byte count in `InflaterSource`. Previously this
+   class could return more bytes than requested.
+ * Fix: Improve a performance bug in `AsyncTimeout.sink().write()`.
+
+
+## Version 1.13.0
+
+_2017-05-12_
+
+ * **Okio now uses `@Nullable` to annotate all possibly-null values.** We've
+   added a compile-time dependency on the JSR 305 annotations. This is a
+   [provided][maven_provided] dependency and does not need to be included in
+   your build configuration, `.jar` file, or `.apk`. We use
+   `@ParametersAreNonnullByDefault` and all parameters and return types are
+   never null unless explicitly annotated `@Nullable`.
+
+ * **Warning: this release is source-incompatible for Kotlin users.**
+   Nullability was previously ambiguous and lenient but now the compiler will
+   enforce strict null checks.
+
+
+## Version 1.12.0
+
+_2017-04-11_
+
+ * **Fix: Change Pipe's sink.flush() to not block.** Previously closing a pipe's
+   sink would block until the source had been exhausted. In practice this
+   blocked the caller for no benefit.
+ * **Fix: Change `writeUtf8CodePoint()` to emit `?` for partial surrogates.**
+   The previous behavior was inconsistent: given a malformed string with a
+   partial surrogate, `writeUtf8()` emitted `?` but `writeUtf8CodePoint()` threw
+   an `IllegalArgumentException`. Most applications will never encounter partial
+   surrogates, but for those that do this behavior was unexpected.
+ * New: Allow length of `readUtf8LineStrict()` to be limited.
+ * New: `Utf8.size()` method to get the number of bytes required to encode a
+   string as UTF-8. This may be useful for length-prefixed encodings.
+ * New: SHA-512 hash and HMAC APIs.
+
+
+## Version 1.11.0
+
+_2016-10-11_
+
+ * **Fix: The four-argument overload of `Buffer.writeString()` had a major bug
+   where it didn't respect offsets if the specified charset was UTF-8.** This
+   was because our short-circuit optimization omitted necessary offset
+   parameters.
+ * New: HMAC support in `HashingSource`, `HashingSink`, `ByteString`, and
+   `Buffer`. This makes it easy to create a keyed-hash message authentication
+   code (HMAC) wherever your data is. Unlike the other hashes, HMAC uses a
+   `ByteString` secret key for authentication.
+ * New: `ByteString.of(ByteBuffer)` makes it easier to mix NIO with Okio.
+
+
+## Version 1.10.0
+
+_2016-08-28_
+
+ * Fix: Support reading files larger than 2 GiB with `GzipSource`. Previously
+   attempting to decompress such files would fail due to an overflow when
+   validating the total length.
+ * Fix: Exit the watchdog thread after being idle for 60 seconds. This should
+   make it possible for class unloaders to fully unload Okio.
+ * New: `Okio.blackhole()` returns a sink where all bytes written are discarded.
+   This is Okio's equivalent of `/dev/null`.
+ * New: Encode a string with any charset using `ByteString.encodeString()` and
+   decode strings in any charset using `ByteString.string()`. Most applications
+   should prefer `ByteString.encodeUtf8()` and `ByteString.utf8()` unless it's
+   necessary to support a legacy charset.
+ * New: `GzipSink.deflater()` makes it possible to configure the compression
+   level.
+
+
+## Version 1.9.0
+
+_2016-07-01_
+
+ * New: `Pipe` makes it easy to connect a producer thread to a consumer thread.
+   Reads block until data is available to read. Writes block if the pipe's is
+   full. Both sources and sinks support timeouts.
+ * New: `BufferedSource.rangeEquals()` makes it easy to compare a range in a
+   stream to an expected value. This does the right thing: it blocks to load
+   the data required return a definitive result. But it won't block
+   unnecessarily.
+ * New: `Timeout.waitUntilNotified()` makes it possible to use nice timeout
+   abstractions on Java's built-in wait/notify primitives.
+ * Fix: Don't return incorrect results when `HashingSource` does large reads.
+   There was a bug where it wasn't traversing through the segments of the buffer
+   being hashed. This means that `HashingSource` was returning incorrect answers
+   for any writes that spanned multiple segment boundaries.
+
+## Version 1.8.0
+
+_2016-05-02_
+
+ * New: `BufferedSource.select(Options)` API for reading one of a set of
+   expected values.
+ * New: Make `ByteString.toString()` and `Buffer.toString()` friendlier.
+   These methods return text if the byte string is valid UTF-8.
+ * New: APIs to match byte strings: `indexOf()`, `startsWith()`, and
+   `endsWith()`.
+
+## Version 1.7.0
+
+_2016-04-10_
+
+ * New: Change the segment size to 8 KiB. This has been reported to dramatically
+   improve performance in some applications.
+ * New: `md5()`, `sha1()`, and `sha256()` methods on `Buffer`. Also add a
+   `sha1()` method on `ByteString` for symmetry.
+ * New: `HashingSource` and `HashingSink`. These classes are Okio’s equivalent
+   to the JDK’s `DigestInputStream` and `DigestOutputStream`. They offer
+   convenient `md5()`, `sha1()`, and `sha256()` factory methods to avoid an
+   impossible `NoSuchAlgorithmException`.
+ * New: `ByteString.asByteBuffer()`.
+ * Fix: Limit snapshot byte strings to requested size.
+ * Fix: Change write timeouts to have a maximum write size. Previously large
+   writes could easly suffer timeouts because the entire write was subject to a
+   single timeout.
+ * Fix: Recover from EBADF failures, which could be triggered by asynchronously
+   closing a stream on older versions of Android.
+ * Fix: Don't share segments if doing so only saves a small copy. This should
+   improve performance for all applications.
+ * Fix: Optimize `BufferedSource.indexOfElement()` and `indexOf(ByteString)`.
+   Previously this method had a bug that caused it to be very slow on large
+   buffers.
+
+## Version 1.6.0
+
+_2015-08-25_
+
+ * New: `BufferedSource.indexOf(ByteString)` searches a source for the next
+   occurrence of a byte string.
+ * Fix: Recover from unexpected `AssertionError` thrown on Android 4.2.2 and
+   earlier when asynchronously closing a socket.
+
+## Version 1.5.0
+
+_2015-06-19_
+
+ * Sockets streams now throw `SocketTimeoutException`. This builds on new
+   extension point in `AsyncTimeout` to customize the exception when a timeout
+   occurs.
+ * New: `ByteString` now implements `Comparable`. The comparison sorts bytes as
+   unsigned: {@code ff} sorts after {@code 00}.
+
+## Version 1.4.0
+
+_2015-05-16_
+
+ * **Timeout exception changed.** Previously `Timeout.throwIfReached()` would
+   throw `InterruptedIOException` on thread interruption, and `IOException` if
+   the deadline was reached. Now it throws `InterruptedIOException` in both
+   cases.
+ * Fix: throw `EOFException` when attempting to read digits from an empty
+   source. Previously this would crash with an unchecked exception.
+ * New: APIs to read and write UTF-8 code points without allocating strings.
+ * New: `BufferedSink` can now write substrings directly, potentially saving an
+   allocation for some callers.
+ * New: `ForwardingTimeout` class.
+
+## Version 1.3.0
+
+_2015-03-16_
+
+ * New: Read and write signed decimal and unsigned hexadecimal values in
+   `BufferedSource` and `BufferedSink`. Unlike the alternatives, these methods
+   don’t do any memory allocations!
+ * New: Segment sharing. This improves the runtime of operations like
+   `Buffer.clone()` and `Buffer.copyTo()` by sharing underlying segments between
+   buffers.
+ * New: `Buffer.snapshot()` returns an immutable snapshot of a buffer as a
+   `ByteString`. This builds on segment sharing so that snapshots are shallow,
+   immutable copies.
+ * New: `ByteString.rangeEquals()`.
+ * New: `ByteString.md5()` and `ByteString.sha256()`.
+ * New: `ByteString.base64Url()` returns URL-safe Base64. The existing
+   decoding method has been extended to support URL-safe Base64 input.
+ * New: `ByteString.substring()` returns a prefix, infix, or suffix.
+ * New: `Sink` now implements `java.io.Flushable`.
+ * Fix: `Buffer.write(Source, long)` now always writes fully. The previous
+   behavior would return as soon as any data had been written; this was
+   inconsistent with all other _write()_ methods in the API.
+ * Fix: don't leak empty segments in DeflaterSink and InflaterSource. (This was
+   unlikely to cause problems in practice.)
+
+## Version 1.2.0
+
+_2014-12-30_
+
+ * Fix: `Okio.buffer()` _always_ buffers for better predictability.
+ * Fix: Provide context when `readUtf8LineStrict()` throws.
+ * Fix: Buffers do not call through the `Source` on zero-byte writes.
+
+## Version 1.1.0
+
+_2014-12-11_
+
+ * Do UTF-8 encoding natively for a performance increase, particularly on Android.
+ * New APIs: `BufferedSink.emit()`, `BufferedSource.request()` and `BufferedSink.indexOfElement()`.
+ * Fixed a performance bug in `Buffer.indexOf()`
+
+## Version 1.0.1
+
+_2014-08-08_
+
+ * Added `read(byte[])`, `read(byte[], offset, byteCount)`,  and
+   `void readFully(byte[])` to `BufferedSource`.
+ * Refined declared checked exceptions on `Buffer` methods.
+
+
+## Version 1.0.0
+
+_2014-05-23_
+
+ * Bumped release version. No other changes!
+
+## Version 0.9.0
+
+_2014-05-03_
+
+ * Use 0 as a sentinel for no timeout.
+ * Make AsyncTimeout public.
+ * Remove checked exception from Buffer.readByteArray.
+
+## Version 0.8.0
+
+_2014-04-24_
+
+ * Eagerly verify preconditions on public APIs.
+ * Quick return on Buffer instance equivalence.
+ * Add delegate types for Sink and Source.
+ * Small changes to the way deadlines are managed.
+ * Add append variant of Okio.sink for File.
+ * Methods to exhaust BufferedSource to byte[] and ByteString.
+
+## Version 0.7.0
+
+_2014-04-18_
+
+ * Don't use getters in timeout.
+ * Use the watchdog to interrupt sockets that have reached deadlines.
+ * Add java.io and java.nio file source/sink helpers.
+
+## Version 0.6.1
+
+_2014-04-17_
+
+ * Methods to read a buffered source fully in UTF-8 or supplied charset.
+ * API to read a byte[] directly.
+ * New methods to move all data from a source to a sink.
+ * Fix a bug on input stream exhaustion.
+
+## Version 0.6.0
+
+_2014-04-15_
+
+ * Make ByteString serializable.
+ * New API: `ByteString.of(byte[] data, int offset, int byteCount)`
+ * New API: stream-based copy, write, and read helpers.
+
+## Version 0.5.0
+
+_2014-04-08_
+
+ * Initial public release.
+ * Imported from OkHttp.
+
+
+ [gradle_metadata]: https://blog.gradle.org/gradle-metadata-1.0
+ [kotlin_1_4_10]: https://github.com/JetBrains/kotlin/releases/tag/v1.4.10 
+ [maven_provided]: https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
+ [xor_utf8]: https://github.com/square/okio/blob/bbb29c459e5ccf0f286e0b17ccdcacd7ac4bc2a9/okio/src/main/kotlin/okio/Utf8.kt#L302
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..ac16ed7
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,38 @@
+Contributing
+============
+
+Keeping the project small and stable limits our ability to accept new contributors. We are not
+seeking new committers at this time, but some small contributions are welcome.
+
+If you've found a security problem, please follow our [bug bounty][security] program.
+
+If you've found a bug, please contribute a failing test case so we can study and fix it.
+
+Before code can be accepted all contributors must complete our
+[Individual Contributor License Agreement (CLA)][cla].
+
+
+Code Contributions
+------------------
+
+Get working code on a personal branch with tests passing before you submit a PR:
+
+```
+./gradlew clean check
+```
+
+Please make every effort to follow existing conventions and style in order to keep the code as
+readable as possible.
+
+Contribute code changes through GitHub by forking the repository and sending a pull request. We
+squash all pull requests on merge.
+
+
+Committer's Guides
+------------------
+
+ * [Releasing][releasing]
+
+ [cla]: https://spreadsheets.google.com/spreadsheet/viewform?formkey=dDViT2xzUHAwRkI3X3k5Z0lQM091OGc6MQ&ndplr=1
+ [releasing]: http://square.github.io/okio/releasing/
+ [security]: http://square.github.io/okio/security/
diff --git a/LICENSE b/LICENSE
new file mode 120000
index 0000000..85de3d4
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1 @@
+LICENSE.txt
\ No newline at end of file
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..659dfff
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,20 @@
+name: "okio"
+description:
+    "Okio is a library that complements java.io and java.nio to make it much "
+    "easier to access, store, and process your data. It started as a component "
+    "of OkHttp, the capable HTTP client included in Android. It's "
+    "well-exercised and ready to solve new problems."
+
+third_party {
+  url {
+    type: HOMEPAGE
+    value: "https://square.github.io/okio/"
+  }
+  url {
+    type: GIT
+    value: "https://github.com/square/okio/"
+  }
+  version: "47fb0ddcd0bcf768a897dff723a1699341eea10f"
+  last_upgrade_date { year: 2021 month: 4 day: 6 }
+  license_type: NOTICE
+}
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..25abe55
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,3 @@
+arangelov@google.com
+stanleytfwang@google.com
+alexkershaw@google.com
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..6a331ee
--- /dev/null
+++ b/README.md
@@ -0,0 +1,29 @@
+Okio
+====
+
+See the [project website][okio] for documentation and APIs.
+
+Okio is a library that complements `java.io` and `java.nio` to make it much
+easier to access, store, and process your data. It started as a component of
+[OkHttp][1], the capable HTTP client included in Android. It's well-exercised
+and ready to solve new problems.
+
+License
+--------
+
+    Copyright 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.
+    
+ [1]: https://github.com/square/okhttp
+ [okio]: https://square.github.io/okio/
diff --git a/android-test/README.md b/android-test/README.md
new file mode 100644
index 0000000..f624005
--- /dev/null
+++ b/android-test/README.md
@@ -0,0 +1,50 @@
+Android Test
+============
+
+This module runs Okio's test suite on a connected Android emulator or device. It requires the same
+set-up as [OkHttp's android-test module][okhttp_android_test].
+
+In brief, configure the Android SDK and PATH:
+
+```
+export ANDROID_SDK_ROOT=/Users/$USER/Library/Android/sdk
+export PATH=$PATH:$ANDROID_SDK_ROOT/tools/bin:$ANDROID_SDK_ROOT/platform-tools
+```
+
+Use `logcat` to stream test logs:
+
+```
+adb logcat '*:E' TestRunner:D TaskRunner:D GnssHAL_GnssInterface:F DeviceStateChecker:F memtrack:F
+```
+
+Then run the tests:
+
+```
+./gradlew :android-test:connectedAndroidTest
+```
+
+Or just a single test:
+
+```
+./gradlew :android-test:connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=okio.SystemFileSystemTest
+```
+
+
+### Watch Out For Crashing Failures
+
+Some of Okio's tests can cause the test process to crash. The test will be reported as a failure
+with a message like this:
+
+> Test failed to run to completion. Reason: 'Instrumentation run failed due to 'Process crashed.''.
+> Check device logcat for details
+
+When this happens, it's possible that tests are missing from the test run! One workaround is to
+exclude the crashing test and re-run the rest. You can confirm that the test run completed normally
+if a `run finished` line is printed in the logcat logs:
+
+```
+01-01 00:00:00.000 12345 23456 I TestRunner: run finished: 2976 tests, 0 failed, 3 ignored
+```
+
+
+[okhttp_android_test]: https://github.com/square/okhttp/tree/master/android-test
diff --git a/android-test/build.gradle b/android-test/build.gradle
new file mode 100644
index 0000000..56fcda7
--- /dev/null
+++ b/android-test/build.gradle
@@ -0,0 +1,73 @@
+apply plugin: 'com.android.library'
+apply plugin: 'org.jetbrains.kotlin.android'
+
+buildscript {
+  repositories {
+    mavenCentral()
+    gradlePluginPortal()
+    google()
+  }
+}
+
+def isIDE = properties.containsKey('android.injected.invoked.from.ide') ||
+  (System.getenv("XPC_SERVICE_NAME") ?: "").contains("intellij") ||
+  System.getenv("IDEA_INITIAL_DIRECTORY") != null
+
+android {
+  compileOptions {
+    sourceCompatibility JavaVersion.VERSION_1_8
+    targetCompatibility JavaVersion.VERSION_1_8
+    coreLibraryDesugaringEnabled true
+  }
+
+  kotlinOptions {
+    freeCompilerArgs += "-Xmulti-platform"
+  }
+
+  compileSdkVersion 30
+
+  defaultConfig {
+    minSdkVersion 15
+    targetSdkVersion 30
+    versionCode 1
+    versionName "1.0"
+    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+
+    // AndroidJUnitRunner wasn't finding tests in multidex artifacts when running on Android 4.0.3.
+    // Work around by adding all Okio classes to the keep list. That way they'll be in the main
+    // .dx file where TestRequestBuilder will find them.
+    multiDexEnabled true
+    multiDexKeepProguard file('multidex-config.pro')
+  }
+
+  if (!isIDE) {
+    sourceSets {
+      named("androidTest") {
+        it.java.srcDirs += [
+          project.file("../okio/src/commonMain/kotlin"),
+          project.file("../okio/src/commonTest/java"),
+          project.file("../okio/src/commonTest/kotlin"),
+          project.file("../okio/src/hashFunctions/kotlin"),
+          project.file("../okio/src/jvmMain/kotlin"),
+          project.file("../okio/src/jvmTest/java"),
+          project.file("../okio/src/jvmTest/kotlin"),
+        ]
+      }
+    }
+  }
+}
+
+
+dependencies {
+  coreLibraryDesugaring deps.android.desugarJdkLibs
+  androidTestImplementation deps.androidx.testExtJunit
+  androidTestImplementation deps.androidx.testRunner
+  androidTestImplementation deps.animalSniffer.annotations
+  androidTestImplementation deps.kotlin.stdLib.common
+  androidTestImplementation deps.kotlin.test.annotations
+  androidTestImplementation deps.kotlin.test.common
+  androidTestImplementation deps.kotlin.test.jdk
+  androidTestImplementation deps.kotlin.time
+  androidTestImplementation deps.test.assertj
+  androidTestImplementation deps.test.junit
+}
diff --git a/android-test/multidex-config.pro b/android-test/multidex-config.pro
new file mode 100644
index 0000000..ace307d
--- /dev/null
+++ b/android-test/multidex-config.pro
@@ -0,0 +1 @@
+-keep class okio.** { *; }
diff --git a/android-test/src/main/AndroidManifest.xml b/android-test/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..fe95031
--- /dev/null
+++ b/android-test/src/main/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:ignore="MissingClass"
+    package="com.squareup.okio">
+
+  <uses-permission android:name="android.permission.INTERNET" />
+
+  <!-- To access the system temporary directory. -->
+  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+
+  <application
+      android:name="androidx.multidex.MultiDexApplication"
+      android:usesCleartextTraffic="true" />
+
+</manifest>
diff --git a/android-test/src/main/res/values/strings.xml b/android-test/src/main/res/values/strings.xml
new file mode 100644
index 0000000..3f2b0bb
--- /dev/null
+++ b/android-test/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+<resources>
+  <string name="app_name">android-test</string>
+</resources>
diff --git a/android-test/src/main/res/xml/network_security_config.xml b/android-test/src/main/res/xml/network_security_config.xml
new file mode 100644
index 0000000..353fa80
--- /dev/null
+++ b/android-test/src/main/res/xml/network_security_config.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <base-config cleartextTrafficPermitted="false">
+  </base-config>
+</network-security-config>
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..4923686
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,120 @@
+buildscript {
+  // If false - JS targets will not be configured in multiplatform projects.
+  ext.kmpJsEnabled = Boolean.parseBoolean(System.getProperty('kjs', 'true'))
+
+  // If false - Native targets will not be configured in multiplatform projects.
+  ext.kmpNativeEnabled = Boolean.parseBoolean(System.getProperty('knative', 'true'))
+
+  ext.versions = [
+      'kotlin': '1.4.20',
+      'jmhPlugin': '0.5.0',
+      'animalSnifferPlugin': '1.5.0',
+      'dokka': '1.4.20',
+      'jmh': '1.23',
+      'animalSniffer': '1.16',
+      'junit': '4.12',
+      'assertj': '1.7.0',
+      'shadowPlugin': '5.2.0',
+      'spotless': '5.8.2',
+      'ktlint': '0.40.0',
+      'bndPlugin': '5.1.2'
+  ]
+
+  ext.deps = [
+      'android': [
+        'gradlePlugin': "com.android.tools.build:gradle:4.1.1",
+        'desugarJdkLibs': "com.android.tools:desugar_jdk_libs:1.1.1",
+      ],
+      'androidx': [
+        'testExtJunit': "androidx.test.ext:junit:1.1.2",
+        'testRunner': "androidx.test:runner:1.3.0",
+      ],
+      'kotlin': [
+          'gradlePlugin': "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}",
+          'stdLib': [
+              'common': "org.jetbrains.kotlin:kotlin-stdlib-common",
+              'jdk8': "org.jetbrains.kotlin:kotlin-stdlib-jdk8",
+              'jdk7': "org.jetbrains.kotlin:kotlin-stdlib-jdk7",
+              'jdk6': "org.jetbrains.kotlin:kotlin-stdlib",
+              'js': "org.jetbrains.kotlin:kotlin-stdlib-js",
+          ],
+          'test': [
+              'common': "org.jetbrains.kotlin:kotlin-test-common",
+              'annotations': "org.jetbrains.kotlin:kotlin-test-annotations-common",
+              'jdk': "org.jetbrains.kotlin:kotlin-test-junit",
+              'js': "org.jetbrains.kotlin:kotlin-test-js",
+          ],
+          'time': 'org.jetbrains.kotlinx:kotlinx-datetime:0.1.1',
+      ],
+      'jmh': [
+          'gradlePlugin': "me.champeau.gradle:jmh-gradle-plugin:${versions.jmhPlugin}",
+          'core': "org.openjdk.jmh:jmh-core:${versions.jmh}",
+          'generator': "org.openjdk.jmh:jmh-generator-annprocess:${versions.jmh}",
+      ],
+      'animalSniffer': [
+          'gradlePlugin': "ru.vyarus:gradle-animalsniffer-plugin:${versions.animalSnifferPlugin}",
+          'annotations': "org.codehaus.mojo:animal-sniffer-annotations:${versions.animalSniffer}",
+      ],
+      'japicmp': 'me.champeau.gradle:japicmp-gradle-plugin:0.2.8',
+      'dokka': "org.jetbrains.dokka:dokka-gradle-plugin:${versions.dokka}",
+      'shadow': "com.github.jengelman.gradle.plugins:shadow:${versions.shadowPlugin}",
+      'spotless': "com.diffplug.spotless:spotless-plugin-gradle:${versions.spotless}",
+      'bnd': "biz.aQute.bnd:biz.aQute.bnd.gradle:${versions.bndPlugin}",
+      'test': [
+          'junit': "junit:junit:${versions.junit}",
+          'assertj': "org.assertj:assertj-core:${versions.assertj}",
+      ]
+  ]
+
+  dependencies {
+    classpath deps.android.gradlePlugin
+    classpath deps.kotlin.gradlePlugin
+    classpath deps.animalSniffer.gradlePlugin
+    classpath deps.japicmp
+    classpath deps.dokka
+    classpath deps.shadow
+    classpath deps.jmh.gradlePlugin
+    classpath deps.spotless
+    classpath deps.bnd
+    // https://github.com/melix/japicmp-gradle-plugin/issues/36
+    classpath 'com.google.guava:guava:28.2-jre'
+  }
+
+  repositories {
+    mavenCentral()
+    gradlePluginPortal()
+    jcenter()
+    google()
+    maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
+    maven { url 'https://kotlin.bintray.com/kotlinx/' }
+  }
+}
+
+// when scripts are applied the buildscript classes are not accessible directly therefore we save the class here to make it accessible
+ext.bndBundleTaskConventionClass = aQute.bnd.gradle.BundleTaskConvention
+
+allprojects {
+  group = GROUP
+  version = VERSION_NAME
+}
+
+subprojects {
+  repositories {
+    mavenCentral()
+    jcenter()
+    google()
+    maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
+    maven { url 'https://kotlin.bintray.com/kotlinx/' }
+  }
+
+  apply plugin: "com.diffplug.spotless"
+
+  spotless {
+    kotlin {
+      target("**/*.kt")
+      ktlint(versions.ktlint).userData([indent_size: '2'])
+      trimTrailingWhitespace()
+      endWithNewline()
+    }
+  }
+}
diff --git a/docs/code_of_conduct.md b/docs/code_of_conduct.md
new file mode 100644
index 0000000..6a97690
--- /dev/null
+++ b/docs/code_of_conduct.md
@@ -0,0 +1,102 @@
+Open Source Code of Conduct
+===========================
+
+At Square, we are committed to contributing to the open source community and simplifying the process
+of releasing and managing open source software. We’ve seen incredible support and enthusiasm from
+thousands of people who have already contributed to our projects — and we want to ensure our community
+continues to be truly open for everyone.
+
+This code of conduct outlines our expectations for participants, as well as steps to reporting
+unacceptable behavior. We are committed to providing a welcoming and inspiring community for all and
+expect our code of conduct to be honored.
+
+Square’s open source community strives to:
+
+ * **Be open**: We invite anyone to participate in any aspect of our projects. Our community is
+   open, and any responsibility can be carried by a contributor who demonstrates the required
+   capacity and competence.
+
+ * **Be considerate**: People use our work, and we depend on the work of others. Consider users and
+   colleagues before taking action. For example, changes to code, infrastructure, policy, and
+   documentation may negatively impact others.
+
+ * **Be respectful**: We expect people to work together to resolve conflict, assume good intentions,
+   and act with empathy. Do not turn disagreements into personal attacks.
+
+ * **Be collaborative**: Collaboration reduces redundancy and improves the quality of our work. We
+   strive for transparency within our open source community, and we work closely with upstream
+   developers and others in the free software community to coordinate our efforts.
+
+ * **Be pragmatic**: Questions are encouraged and should be asked early in the process to avoid
+   problems later. Be thoughtful and considerate when seeking out the appropriate forum for your
+   questions. Those who are asked should be responsive and helpful.
+
+ * **Step down considerately**: Members of every project come and go. When somebody leaves or
+   disengages from the project, they should make it known and take the proper steps to ensure that
+   others can pick up where they left off.
+
+This code is not exhaustive or complete. It serves to distill our common understanding of a
+collaborative, shared environment, and goals. We expect it to be followed in spirit as much as in
+the letter.
+
+Diversity Statement
+-------------------
+
+We encourage everyone to participate and are committed to building a community for all. Although we
+may not be able to satisfy everyone, we all agree that everyone is equal.
+
+Whenever a participant has made a mistake, we expect them to take responsibility for it. If someone
+has been harmed or offended, it is our responsibility to listen carefully and respectfully, and do
+our best to right the wrong.
+
+Although this list cannot be exhaustive, we explicitly honor diversity in age, culture, ethnicity,
+gender identity or expression, language, national origin, political beliefs, profession, race,
+religion, sexual orientation, socioeconomic status, and technical ability. We will not tolerate
+discrimination based on any of the protected characteristics above, including participants with
+disabilities.
+
+Reporting Issues
+----------------
+
+If you experience or witness unacceptable behavior — or have any other concerns — please report it by
+emailing [codeofconduct@squareup.com][codeofconduct_at]. For more details, please see our Reporting
+Guidelines below.
+
+Thanks
+------
+
+Some of the ideas and wording for the statements and guidelines above were based on work by the
+[Twitter][twitter_coc], [Ubuntu][ubuntu_coc], [GDC][gdc_coc], and [Django][django_coc] communities.
+We are thankful for their work.
+
+Reporting Guide
+---------------
+
+If you experience or witness unacceptable behavior — or have any other concerns — please report it by
+emailing [codeofconduct@squareup.com][codeofconduct_at]. All reports will be handled with
+discretion.
+
+In your report please include:
+
+ * Your contact information.
+ * Names (real, nicknames, or pseudonyms) of any individuals involved. If there are additional
+   witnesses, please include them as well.
+ * Your account of what occurred, and if you believe the incident is ongoing. If there is a publicly
+   available record (e.g. a mailing list archive or a public IRC logger), please include a link.
+ * Any additional information that may be helpful.
+
+After filing a report, a representative from the Square Code of Conduct committee will contact you
+personally. The committee will then review the incident, follow up with any additional questions,
+and make a decision as to how to respond.
+
+Anyone asked to stop unacceptable behavior is expected to comply immediately. If an individual
+engages in unacceptable behavior, the Square Code of Conduct committee may take any action they deem
+appropriate, up to and including a permanent ban from all of Square spaces without warning.
+
+
+[codeofconduct_at]: mailto:codeofconduct@squareup.com
+[twitter_coc]: https://github.com/twitter/code-of-conduct/blob/master/code-of-conduct.md
+[ubuntu_coc]: https://ubuntu.com/community/code-of-conduct
+[gdc_coc]: https://www.gdconf.com/code-of-conduct
+[django_coc]: https://www.djangoproject.com/conduct/reporting/
+
diff --git a/docs/css/app.css b/docs/css/app.css
new file mode 100644
index 0000000..48136b7
--- /dev/null
+++ b/docs/css/app.css
@@ -0,0 +1,48 @@
+@font-face {
+    font-family: cash-market;
+    src: url("https://cash-f.squarecdn.com/static/fonts/cash-market/v2/CashMarket-Regular.woff2") format("woff2");
+    font-weight: 400;
+    font-style: normal
+}
+
+@font-face {
+    font-family: cash-market;
+    src: url("https://cash-f.squarecdn.com/static/fonts/cash-market/v2/CashMarket-Medium.woff2") format("woff2");
+    font-weight: 500;
+    font-style: normal
+}
+
+@font-face {
+    font-family: cash-market;
+    src: url("https://cash-f.squarecdn.com/static/fonts/cash-market/v2/CashMarket-Bold.woff2") format("woff2");
+    font-weight: 700;
+    font-style: normal
+}
+
+body, input {
+    font-family: cash-market,"Helvetica Neue",helvetica,sans-serif;
+}
+
+.md-typeset h1, .md-typeset h2, .md-typeset h3, .md-typeset h4 {
+    font-family: cash-market,"Helvetica Neue",helvetica,sans-serif;
+    line-height: normal;
+    font-weight: bold;
+    color: #353535;
+}
+
+button.dl {
+  font-weight: 300;
+  font-size: 25px;
+  line-height: 40px;
+  padding: 3px 10px;
+  display: inline-block;
+  border-radius: 6px;
+  color: #f0f0f0;
+  margin: 5px 0;
+  width: auto;
+}
+
+.logo {
+  text-align: center;
+  margin-top: 150px;
+}
diff --git a/docs/css/dokka-logo.css b/docs/css/dokka-logo.css
new file mode 100644
index 0000000..ae3a99e
--- /dev/null
+++ b/docs/css/dokka-logo.css
@@ -0,0 +1,6 @@
+#logo {
+    background-image: url(../images/logo-square.png);
+    background-size: auto;
+    padding-top: unset;
+    height: 60px;
+}
diff --git a/docs/images/icon-square.png b/docs/images/icon-square.png
new file mode 100644
index 0000000..bdc98d1
--- /dev/null
+++ b/docs/images/icon-square.png
Binary files differ
diff --git a/docs/images/logo-square.png b/docs/images/logo-square.png
new file mode 100644
index 0000000..788b301
--- /dev/null
+++ b/docs/images/logo-square.png
Binary files differ
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..d69c409
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,1163 @@
+Okio
+====
+
+Okio is a library that complements `java.io` and `java.nio` to make it much
+easier to access, store, and process your data. It started as a component of
+[OkHttp][1], the capable HTTP client included in Android. It's well-exercised
+and ready to solve new problems.
+
+ByteStrings and Buffers
+-----------------------
+
+Okio is built around two types that pack a lot of capability into a
+straightforward API:
+
+ * [**ByteString**][3] is an immutable sequence of bytes. For character data, `String`
+   is fundamental. `ByteString` is String's long-lost brother, making it easy to
+   treat binary data as a value. This class is ergonomic: it knows how to encode
+   and decode itself as hex, base64, and UTF-8.
+
+ * [**Buffer**][4] is a mutable sequence of bytes. Like `ArrayList`, you don't need
+   to size your buffer in advance. You read and write buffers as a queue: write
+   data to the end and read it from the front. There's no obligation to manage
+   positions, limits, or capacities.
+
+Internally, `ByteString` and `Buffer` do some clever things to save CPU and
+memory. If you encode a UTF-8 string as a `ByteString`, it caches a reference to
+that string so that if you decode it later, there's no work to do.
+
+`Buffer` is implemented as a linked list of segments. When you move data from
+one buffer to another, it _reassigns ownership_ of the segments rather than
+copying the data across. This approach is particularly helpful for multithreaded
+programs: a thread that talks to the network can exchange data with a worker
+thread without any copying or ceremony.
+
+Sources and Sinks
+-----------------
+
+An elegant part of the `java.io` design is how streams can be layered for
+transformations like encryption and compression. Okio includes its own stream
+types called [`Source`][5] and [`Sink`][6] that work like `InputStream` and
+`OutputStream`, but with some key differences:
+
+ * **Timeouts.** The streams provide access to the timeouts of the underlying
+   I/O mechanism. Unlike the `java.io` socket streams, both `read()` and
+   `write()` calls honor timeouts.
+
+ * **Easy to implement.** `Source` declares three methods: `read()`, `close()`,
+   and `timeout()`. There are no hazards like `available()` or single-byte reads
+   that cause correctness and performance surprises.
+
+ * **Easy to use.** Although _implementations_ of `Source` and `Sink` have only
+   three methods to write, _callers_ are given a rich API with the
+   [`BufferedSource`][7] and [`BufferedSink`][8] interfaces. These interfaces give you
+   everything you need in one place.
+
+ * **No artificial distinction between byte streams and char streams.** It's all
+   data. Read and write it as bytes, UTF-8 strings, big-endian 32-bit integers,
+   little-endian shorts; whatever you want. No more `InputStreamReader`!
+
+ * **Easy to test.** The `Buffer` class implements both `BufferedSource` and
+   `BufferedSink` so your test code is simple and clear.
+
+Sources and sinks interoperate with `InputStream` and `OutputStream`. You can
+view any `Source` as an `InputStream`, and you can view any `InputStream` as a
+`Source`. Similarly for `Sink` and `OutputStream`.
+
+
+Presentations
+-------------
+
+[A Few “Ok” Libraries][ok_libraries_talk] ([slides][ok_libraries_slides]): An introduction to Okio
+and three libraries written with it.
+
+[Decoding the Secrets of Binary Data][encoding_talk] ([slides][encoding_slides]): How data encoding
+works and how Okio does it.
+
+[Ok Multiplatform!][ok_multiplatform_talk] ([slides][ok_multiplatform_slides]): How we changed
+Okio’s implementation language from Java to Kotlin.
+
+
+Requirements
+------------
+
+Okio supports Android 4.0.3+ (API level 15+) and Java 7+.
+
+Okio depends on the [Kotlin standard library][kotlin]. It is a small library with strong
+backward-compatibility.
+
+
+Recipes
+-------
+
+We've written some recipes that demonstrate how to solve common problems with
+Okio. Read through them to learn about how everything works together.
+Cut-and-paste these examples freely; that's what they're for.
+
+### Read a text file line-by-line ([Java][ReadFileLineByLine]/[Kotlin][ReadFileLineByLineKt])
+
+Use `Okio.source(File)` to open a source stream to read a file. The returned
+`Source` interface is very small and has limited uses. Instead we wrap the
+source with a buffer. This has two benefits:
+
+ * **It makes the API more powerful.** Instead of the basic methods offered by
+   `Source`, `BufferedSource` has dozens of methods to address most common
+   problems concisely.
+
+ * **It makes your program run faster.** Buffering allows Okio to get more done
+   with fewer I/O operations.
+
+Each `Source` that is opened needs to be closed. The code that opens the stream
+is responsible for making sure it is closed. 
+
+=== "Java"
+    
+    Here we use Java's `try` blocks to close our sources automatically.
+    
+    ```java
+    public void readLines(File file) throws IOException {
+      try (Source fileSource = Okio.source(file);
+           BufferedSource bufferedSource = Okio.buffer(fileSource)) {
+    
+        while (true) {
+          String line = bufferedSource.readUtf8Line();
+          if (line == null) break;
+    
+          if (line.contains("square")) {
+            System.out.println(line);
+          }
+        }
+    
+      }
+    }
+    ```
+    
+=== "Kotlin"
+    
+    Note that static `Okio` methods become extension functions (`Okio.source(file)` => 
+    `file.source()`), and `use` is used to automatically close the streams:
+    
+    ```kotlin
+    @Throws(IOException::class)
+    fun readLines(file: File) {
+      file.source().use { fileSource ->
+        fileSource.buffer().use { bufferedFileSource ->
+          while (true) {
+            val line = bufferedFileSource.readUtf8Line() ?: break
+            if ("square" in line) {
+              println(line)
+            }
+          }
+        }
+      }
+    }
+    ``` 
+
+The `readUtf8Line()` API reads all of the data until the next line delimiter –
+either `\n`, `\r\n`, or the end of the file. It returns that data as a string,
+omitting the delimiter at the end. When it encounters empty lines the method
+will return an empty string. If there isn’t any more data to read it will
+return null.
+
+The above program can be written more compactly by inlining the `fileSource`
+variable and by using a fancy `for` loop instead of a `while`:
+
+```java
+public void readLines(File file) throws IOException {
+  try (BufferedSource source = Okio.buffer(Okio.source(file))) {
+    for (String line; (line = source.readUtf8Line()) != null; ) {
+      if (line.contains("square")) {
+        System.out.println(line);
+      }
+    }
+  }
+}
+```
+
+In Kotlin, we can wrap invocations of `source.readUtf8Line()` into the `generateSequence` builder to 
+create a sequence of lines that will end once null is returned. Plus, transforming streams is easy 
+thanks to the extension functions:
+
+```kotlin
+@Throws(IOException::class)
+fun readLines(file: File) {
+  file.source().buffer().use { source ->
+    generateSequence { source.readUtf8Line() }
+      .filter { line -> "square" in line }
+      .forEach(::println)
+  }
+}
+``` 
+
+The `readUtf8Line()` method is suitable for parsing most files. For certain
+use-cases you may also consider `readUtf8LineStrict()`. It is similar but it
+requires that each line is terminated by `\n` or `\r\n`. If it encounters the
+end of the file before that it will throw an `EOFException`. The strict variant
+also permits a byte limit to defend against malformed input.
+
+```java
+public void readLines(File file) throws IOException {
+  try (BufferedSource source = Okio.buffer(Okio.source(file))) {
+    while (!source.exhausted()) {
+      String line = source.readUtf8LineStrict(1024L);
+      if (line.contains("square")) {
+        System.out.println(line);
+      }
+    }
+  }
+}
+```
+
+Here's a similar example written in Kotlin:
+
+```kotlin
+@Throws(IOException::class)
+fun readLines(file: File) {
+  file.source().buffer().use { source ->
+    while (!source.exhausted()) {
+      val line = source.readUtf8LineStrict(1024)
+      if ("square" in line) {
+        println(line)
+      }
+    }
+  }
+}
+```
+
+### Write a text file ([Java][WriteFile]/[Kotlin][WriteFileKt])
+
+Above we used a `Source` and a `BufferedSource` to read a file. To write, we use
+a `Sink` and a `BufferedSink`. The advantages of buffering are the same: a more
+capable API and better performance.
+
+```java
+public void writeEnv(File file) throws IOException {
+  try (Sink fileSink = Okio.sink(file);
+       BufferedSink bufferedSink = Okio.buffer(fileSink)) {
+
+    for (Map.Entry<String, String> entry : System.getenv().entrySet()) {
+      bufferedSink.writeUtf8(entry.getKey());
+      bufferedSink.writeUtf8("=");
+      bufferedSink.writeUtf8(entry.getValue());
+      bufferedSink.writeUtf8("\n");
+    }
+
+  }
+}
+```
+
+There isn’t an API to write a line of input; instead we manually insert our own
+newline character. Most programs should hardcode `"\n"` as the newline
+character. In rare situations you may use `System.lineSeparator()` instead of
+`"\n"`: it returns `"\r\n"` on Windows and `"\n"` everywhere else.
+
+We can write the above program more compactly by inlining the `fileSink`
+variable and by taking advantage of method chaining:
+
+=== "Java"
+    
+    ```Java
+    public void writeEnv(File file) throws IOException {
+      try (BufferedSink sink = Okio.buffer(Okio.sink(file))) {
+        for (Map.Entry<String, String> entry : System.getenv().entrySet()) {
+          sink.writeUtf8(entry.getKey())
+              .writeUtf8("=")
+              .writeUtf8(entry.getValue())
+              .writeUtf8("\n");
+        }
+      }
+    }
+    ```
+    
+=== "Kotlin"
+    
+    ```Kotlin
+    @Throws(IOException::class)
+    fun writeEnv(file: File) {
+      file.sink().buffer().use { sink ->
+        for ((key, value) in System.getenv()) {
+          sink.writeUtf8(key)
+          sink.writeUtf8("=")
+          sink.writeUtf8(value)
+          sink.writeUtf8("\n")
+        }
+      }
+    }
+    ```
+
+In the above code we make four calls to `writeUtf8()`. Making four calls is
+more efficient than the code below because the VM doesn’t have to create and
+garbage collect a temporary string.
+
+```java
+sink.writeUtf8(entry.getKey() + "=" + entry.getValue() + "\n"); // Slower!
+```
+
+### UTF-8 ([Java][ExploreCharsets]/[Kotlin][ExploreCharsetsKt])
+
+In the above APIs you can see that Okio really likes UTF-8. Early computer
+systems suffered many incompatible character encodings: ISO-8859-1, ShiftJIS,
+ASCII, EBCDIC, etc. Writing software to support multiple character sets was
+awful and we didn’t even have emoji! Today we're lucky that the world has
+standardized on UTF-8 everywhere, with some rare uses of other charsets in
+legacy systems.
+
+If you need another character set, `readString()` and `writeString()` are there
+for you. These methods require that you specify a character set. Otherwise you
+may accidentally create data that is only readable by the local computer. Most
+programs should use the UTF-8 methods only.
+
+When encoding strings you need to be mindful of the different ways that strings
+are represented and encoded. When a glyph has an accent or another adornment
+it may be represented as a single complex code point (`é`) or as a simple code
+point (`e`) followed by its modifiers (`´`). When the entire glyph is a single
+code point that’s called [NFC][nfc]; when it’s multiple it’s [NFD][nfd].
+
+Though we use UTF-8 whenever we read or write strings in I/O, when they are in
+memory Java Strings use an obsolete character encoding called UTF-16. It is a
+bad encoding because it uses a 16-bit `char` for most characters, but some don’t
+fit. In particular, most emoji use two Java chars. This is problematic because
+`String.length()` returns a surprising result: the number of UTF-16 chars and
+not the natural number of glyphs.
+
+|                       | Café 🍩                     | Café 🍩                        |
+| --------------------: | :---------------------------| :------------------------------|
+|                  Form | [NFC][nfc]                  | [NFD][nfd]                     |
+|           Code Points | `c  a  f  é    ␣   🍩     ` | `c  a  f  e  ´    ␣   🍩     ` |
+|           UTF-8 bytes | `43 61 66 c3a9 20 f09f8da9` | `43 61 66 65 cc81 20 f09f8da9` |
+| String.codePointCount | 6                           | 7                              |
+|         String.length | 7                           | 8                              |
+|             Utf8.size | 10                          | 11                             |
+
+For the most part Okio lets you ignore these problems and focus on your data.
+But when you need them, there are convenient APIs for dealing with low-level
+UTF-8 strings.
+
+Use `Utf8.size()` to count the number of bytes required to encode a string as
+UTF-8 without actually encoding it. This is handy in length-prefixed encodings
+like protocol buffers.
+
+Use `BufferedSource.readUtf8CodePoint()` to read a single variable-length code
+point, and `BufferedSink.writeUtf8CodePoint()` to write one.
+
+### Golden Values ([Java][GoldenValue]/[Kotlin][GoldenValueKt])
+
+Okio likes testing. The library itself is heavily tested, and it has features
+that are often helpful when testing application code. One pattern we’ve found to
+be quite useful is “golden value” testing. The goal of such tests is to confirm
+that data encoded with earlier versions of a program can safely be decoded by
+the current program.
+
+We’ll illustrate this by encoding a value using Java Serialization. Though we
+must disclaim that Java Serialization is an awful encoding system and most
+programs should prefer other formats like JSON or protobuf! In any case, here’s
+a method that takes an object, serializes it, and returns the result as a
+`ByteString`:
+
+=== "Java"
+    
+    ```Java
+    private ByteString serialize(Object o) throws IOException {
+      Buffer buffer = new Buffer();
+      try (ObjectOutputStream objectOut = new ObjectOutputStream(buffer.outputStream())) {
+        objectOut.writeObject(o);
+      }
+      return buffer.readByteString();
+    }
+    ```
+    
+=== "Kotlin"
+    
+    ```Kotlin
+    @Throws(IOException::class)
+    private fun serialize(o: Any?): ByteString {
+      val buffer = Buffer()
+      ObjectOutputStream(buffer.outputStream()).use { objectOut ->
+        objectOut.writeObject(o)
+      }
+      return buffer.readByteString()
+    }
+    ```
+
+There’s a lot going on here.
+
+1. We create a buffer as a holding space for our serialized data. It’s a convenient
+   replacement for `ByteArrayOutputStream`.
+
+2. We ask the buffer for its output stream. Writes to a buffer or its output stream
+   always append data to the end of the buffer.
+
+3. We create an `ObjectOutputStream` (the encoding API for Java serialization) and
+   write our object. The try block takes care of closing the stream for us. Note
+   that closing a buffer has no effect.
+
+4. Finally we read a byte string from the buffer. The `readByteString()` method
+   allows us to specify how many bytes to read; here we don’t specify a count in
+   order to read the entire thing. Reads from a buffer always consume data from
+   the front of the buffer.
+
+With our `serialize()` method handy we are ready to compute and print a golden
+value.
+
+=== "Java"
+    
+    ```Java
+    Point point = new Point(8.0, 15.0);
+    ByteString pointBytes = serialize(point);
+    System.out.println(pointBytes.base64());
+    ```
+    
+=== "Kotlin"
+    
+    ```Kotlin
+    val point = Point(8.0, 15.0)
+    val pointBytes = serialize(point)
+    println(pointBytes.base64())
+    ```
+
+We print the `ByteString` as [base64][base64] because it’s a compact format
+that’s suitable for embedding in a test case. The program prints this:
+
+```
+rO0ABXNyAB5va2lvLnNhbXBsZXMuR29sZGVuVmFsdWUkUG9pbnTdUW8rMji1IwIAAkQAAXhEAAF5eHBAIAAAAAAAAEAuAAAAAAAA
+```
+    
+That’s our golden value! We can embed it in our test case using base64 again
+to convert it back into a `ByteString`:
+
+=== "Java"
+    
+    ```Java
+    ByteString goldenBytes = ByteString.decodeBase64("rO0ABXNyAB5va2lvLnNhbXBsZ"
+        + "XMuR29sZGVuVmFsdWUkUG9pbnTdUW8rMji1IwIAAkQAAXhEAAF5eHBAIAAAAAAAAEAuA"
+        + "AAAAAAA");
+    ```
+    
+=== "Kotlin"
+    
+    ```Kotlin
+    val goldenBytes = ("rO0ABXNyACRva2lvLnNhbXBsZXMuS290bGluR29sZGVuVmFsdWUkUG9pbnRF9yaY7cJ9EwIAA" +
+      "kQAAXhEAAF5eHBAIAAAAAAAAEAuAAAAAAAA").decodeBase64()
+    ```
+
+The next step is to deserialize the `ByteString` back into our value class. This
+method reverses the `serialize()` method above: we append a byte string to a
+buffer then consume it using an `ObjectInputStream`:
+
+=== "Java"
+    
+    ```Java
+    private Object deserialize(ByteString byteString) throws IOException, ClassNotFoundException {
+      Buffer buffer = new Buffer();
+      buffer.write(byteString);
+      try (ObjectInputStream objectIn = new ObjectInputStream(buffer.inputStream())) {
+        return objectIn.readObject();
+      }
+    }
+    ```
+    
+=== "Kotlin"
+    
+    ```Kotlin
+    @Throws(IOException::class, ClassNotFoundException::class)
+    private fun deserialize(byteString: ByteString): Any? {
+      val buffer = Buffer()
+      buffer.write(byteString)
+      ObjectInputStream(buffer.inputStream()).use { objectIn ->
+        return objectIn.readObject()
+      }
+    }
+    ```
+
+Now we can test the decoder against the golden value:
+
+=== "Java"
+    
+    ```Java
+    ByteString goldenBytes = ByteString.decodeBase64("rO0ABXNyAB5va2lvLnNhbXBsZ"
+        + "XMuR29sZGVuVmFsdWUkUG9pbnTdUW8rMji1IwIAAkQAAXhEAAF5eHBAIAAAAAAAAEAuA"
+        + "AAAAAAA");
+    Point decoded = (Point) deserialize(goldenBytes);
+    assertEquals(new Point(8.0, 15.0), decoded);
+    ```
+    
+=== "Kotlin"
+    
+    ```Kotlin
+    val goldenBytes = ("rO0ABXNyACRva2lvLnNhbXBsZXMuS290bGluR29sZGVuVmFsdWUkUG9pbnRF9yaY7cJ9EwIAA" +
+      "kQAAXhEAAF5eHBAIAAAAAAAAEAuAAAAAAAA").decodeBase64()!!
+    val decoded = deserialize(goldenBytes) as Point
+    assertEquals(point, decoded)
+    ```
+
+With this test we can change the serialization of the `Point` class without
+breaking compatibility.
+
+
+### Write a binary file ([Java][BitmapEncoder]/[Kotlin][BitmapEncoderKt])
+
+Encoding a binary file is not unlike encoding a text file. Okio uses the same
+`BufferedSink` and `BufferedSource` bytes for both. This is handy for binary
+formats that include both byte and character data.
+
+Writing binary data is more hazardous than text because if you make a mistake it
+is often quite difficult to diagnose. Avoid such mistakes by being careful
+around these traps:
+
+ * **The width of each field.** This is the number of bytes used. Okio doesn't
+   include a mechanism to emit partial bytes. If you need that, you’ll need to
+   do your own bit shifting and masking before writing.
+
+ * **The endianness of each field.** All fields that have more than one byte
+   have _endianness_: whether the bytes are ordered most-significant to least
+   (big endian) or least-significant to most (little endian). Okio uses the `Le`
+   suffix for little-endian methods; methods without a suffix are big-endian.
+
+ * **Signed vs. Unsigned.** Java doesn’t have unsigned primitive types (except
+   for `char`!) so coping with this is often something that happens at the
+   application layer. To make this a little easier Okio accepts `int` types for
+   `writeByte()` and `writeShort()`. You can pass an “unsigned” byte like 255
+   and Okio will do the right thing.
+
+| Method       | Width | Endianness |           Value | Encoded Value             |
+| :----------- | ----: | :--------- | --------------: | :------------------------ |
+| writeByte    |     1 |            |               3 | `03`                      |
+| writeShort   |     2 | big        |               3 | `00 03`                   |
+| writeInt     |     4 | big        |               3 | `00 00 00 03`             |
+| writeLong    |     8 | big        |               3 | `00 00 00 00 00 00 00 03` |
+| writeShortLe |     2 | little     |               3 | `03 00`                   |
+| writeIntLe   |     4 | little     |               3 | `03 00 00 00`             |
+| writeLongLe  |     8 | little     |               3 | `03 00 00 00 00 00 00 00` |
+| writeByte    |     1 |            |  Byte.MAX_VALUE | `7f`                      |
+| writeShort   |     2 | big        | Short.MAX_VALUE | `7f ff`                   |
+| writeInt     |     4 | big        |   Int.MAX_VALUE | `7f ff ff ff`             |
+| writeLong    |     8 | big        |  Long.MAX_VALUE | `7f ff ff ff ff ff ff ff` |
+| writeShortLe |     2 | little     | Short.MAX_VALUE | `ff 7f`                   |
+| writeIntLe   |     4 | little     |   Int.MAX_VALUE | `ff ff ff 7f`             |
+| writeLongLe  |     8 | little     |  Long.MAX_VALUE | `ff ff ff ff ff ff ff 7f` |
+
+This code encodes a bitmap following the [BMP file format][bmp].
+
+=== "Java"
+    
+    ```Java
+    void encode(Bitmap bitmap, BufferedSink sink) throws IOException {
+      int height = bitmap.height();
+      int width = bitmap.width();
+    
+      int bytesPerPixel = 3;
+      int rowByteCountWithoutPadding = (bytesPerPixel * width);
+      int rowByteCount = ((rowByteCountWithoutPadding + 3) / 4) * 4;
+      int pixelDataSize = rowByteCount * height;
+      int bmpHeaderSize = 14;
+      int dibHeaderSize = 40;
+    
+      // BMP Header
+      sink.writeUtf8("BM"); // ID.
+      sink.writeIntLe(bmpHeaderSize + dibHeaderSize + pixelDataSize); // File size.
+      sink.writeShortLe(0); // Unused.
+      sink.writeShortLe(0); // Unused.
+      sink.writeIntLe(bmpHeaderSize + dibHeaderSize); // Offset of pixel data.
+    
+      // DIB Header
+      sink.writeIntLe(dibHeaderSize);
+      sink.writeIntLe(width);
+      sink.writeIntLe(height);
+      sink.writeShortLe(1);  // Color plane count.
+      sink.writeShortLe(bytesPerPixel * Byte.SIZE);
+      sink.writeIntLe(0);    // No compression.
+      sink.writeIntLe(16);   // Size of bitmap data including padding.
+      sink.writeIntLe(2835); // Horizontal print resolution in pixels/meter. (72 dpi).
+      sink.writeIntLe(2835); // Vertical print resolution in pixels/meter. (72 dpi).
+      sink.writeIntLe(0);    // Palette color count.
+      sink.writeIntLe(0);    // 0 important colors.
+    
+      // Pixel data.
+      for (int y = height - 1; y >= 0; y--) {
+        for (int x = 0; x < width; x++) {
+          sink.writeByte(bitmap.blue(x, y));
+          sink.writeByte(bitmap.green(x, y));
+          sink.writeByte(bitmap.red(x, y));
+        }
+    
+        // Padding for 4-byte alignment.
+        for (int p = rowByteCountWithoutPadding; p < rowByteCount; p++) {
+          sink.writeByte(0);
+        }
+      }
+    }
+    ```
+    
+=== "Kotlin"
+    
+    ```Kotlin
+    @Throws(IOException::class)
+    fun encode(bitmap: Bitmap, sink: BufferedSink) {
+      val height = bitmap.height
+      val width = bitmap.width
+      val bytesPerPixel = 3
+      val rowByteCountWithoutPadding = bytesPerPixel * width
+      val rowByteCount = (rowByteCountWithoutPadding + 3) / 4 * 4
+      val pixelDataSize = rowByteCount * height
+      val bmpHeaderSize = 14
+      val dibHeaderSize = 40
+    
+      // BMP Header
+      sink.writeUtf8("BM") // ID.
+      sink.writeIntLe(bmpHeaderSize + dibHeaderSize + pixelDataSize) // File size.
+      sink.writeShortLe(0) // Unused.
+      sink.writeShortLe(0) // Unused.
+      sink.writeIntLe(bmpHeaderSize + dibHeaderSize) // Offset of pixel data.
+    
+      // DIB Header
+      sink.writeIntLe(dibHeaderSize)
+      sink.writeIntLe(width)
+      sink.writeIntLe(height)
+      sink.writeShortLe(1) // Color plane count.
+      sink.writeShortLe(bytesPerPixel * Byte.SIZE_BITS)
+      sink.writeIntLe(0) // No compression.
+      sink.writeIntLe(16) // Size of bitmap data including padding.
+      sink.writeIntLe(2835) // Horizontal print resolution in pixels/meter. (72 dpi).
+      sink.writeIntLe(2835) // Vertical print resolution in pixels/meter. (72 dpi).
+      sink.writeIntLe(0) // Palette color count.
+      sink.writeIntLe(0) // 0 important colors.
+    
+      // Pixel data.
+      for (y in height - 1 downTo 0) {
+        for (x in 0 until width) {
+          sink.writeByte(bitmap.blue(x, y))
+          sink.writeByte(bitmap.green(x, y))
+          sink.writeByte(bitmap.red(x, y))
+        }
+    
+        // Padding for 4-byte alignment.
+        for (p in rowByteCountWithoutPadding until rowByteCount) {
+          sink.writeByte(0)
+        }
+      }
+    }
+    ```
+
+The trickiest part of this program is the format’s required padding. The BMP
+format expects each row to begin on a 4-byte boundary so it is necessary to add
+zeros to maintain the alignment.
+
+Encoding other binary formats is usually quite similar. Some tips:
+
+ * Write tests with golden values! Confirming that your program emits the
+   expected result can make debugging easier.
+ * Use `Utf8.size()` to compute the number of bytes of an encoded string. This
+   is essential for length-prefixed formats.
+ * Use `Float.floatToIntBits()` and `Double.doubleToLongBits()` to encode
+   floating point values.
+
+
+### Communicate on a Socket ([Java][SocksProxyServer]/[Kotlin][SocksProxyServerKt])
+
+Sending and receiving data over the network is a bit like writing and reading
+files. We use `BufferedSink` to encode output and `BufferedSource` to decode
+input. Like files, network protocols can be text, binary, or a mix of both. But
+there are also some substantial differences between the network and the
+file system.
+
+With a file you’re either reading or writing but with the network you can do
+both! Some protocols handle this by taking turns: write a request, read a
+response, repeat. You can implement this kind of protocol with a single thread.
+In other protocols you may read and write simultaneously. Typically you’ll want
+one dedicated thread for reading. For writing you can use either a dedicated
+thread or use `synchronized` so that multiple threads can share a sink. Okio’s
+streams are not safe for concurrent use.
+
+Sinks buffer outbound data to minimize I/O operations. This is efficient but it
+means you must manually call `flush()` to transmit data. Typically
+message-oriented protocols flush after each message. Note that Okio will
+automatically flush when the buffered data exceeds some threshold. This is
+intended to save memory and you shouldn’t rely on it for interactive protocols.
+
+Okio builds on `java.io.Socket` for connectivity. Create your socket as a server
+or as a client, then use `Okio.source(Socket)` to read and `Okio.sink(Socket)`
+to write. These APIs also work with `SSLSocket`. You should use SSL unless you
+have a very good reason not to!
+
+Cancel a socket from any thread by calling `Socket.close()`; this will cause its
+sources and sinks to immediately fail with an `IOException`. You can also
+configure timeouts for all socket operations. You don’t need a reference to the
+socket to adjust timeouts: `Source` and `Sink` expose timeouts directly. This
+API works even if the streams are decorated.
+
+As a complete example of networking with Okio we wrote a [basic SOCKS
+proxy][SocksProxyServer] server. Some highlights:
+
+=== "Java"
+    
+    ```Java
+    Socket fromSocket = ...
+    BufferedSource fromSource = Okio.buffer(Okio.source(fromSocket));
+    BufferedSink fromSink = Okio.buffer(Okio.sink(fromSocket));
+    ```
+    
+=== "Kotlin"
+    
+    ```Kotlin
+    val fromSocket: Socket = ...
+    val fromSource = fromSocket.source().buffer()
+    val fromSink = fromSocket.sink().buffer()
+    ```
+
+Creating sources and sinks for sockets is the same as creating them for files.
+Once you create a `Source` or `Sink` for a socket you must not use its
+`InputStream` or `OutputStream`, respectively.
+
+=== "Java"
+    
+    ```Java
+    Buffer buffer = new Buffer();
+    for (long byteCount; (byteCount = source.read(buffer, 8192L)) != -1; ) {
+      sink.write(buffer, byteCount);
+      sink.flush();
+    }
+    ```
+    
+=== "Kotlin"
+    
+    ```Kotlin
+    val buffer = Buffer()
+    var byteCount: Long
+    while (source.read(buffer, 8192L).also { byteCount = it } != -1L) {
+      sink.write(buffer, byteCount)
+      sink.flush()
+    }
+    ```
+
+The above loop copies data from the source to the sink, flushing after each
+read. If we didn’t need the flushing we could replace this loop with a single
+call to `BufferedSink.writeAll(Source)`.
+
+The `8192` argument to `read()` is the maximum number of bytes to read before
+returning. We could have passed any value here, but we like 8 KiB because that’s
+the largest value Okio can do in a single system call. Most of the time
+application code doesn’t need to deal with such limits!
+
+=== "Java"
+    
+    ```Java
+    int addressType = fromSource.readByte() & 0xff;
+    int port = fromSource.readShort() & 0xffff;
+    ```
+    
+=== "Kotlin"
+    
+    ```Kotlin
+    val addressType = fromSource.readByte().toInt() and 0xff
+    val port = fromSource.readShort().toInt() and 0xffff
+    ```
+
+Okio uses signed types like `byte` and `short`, but often protocols want
+unsigned values. The bitwise `&` operator is Java’s preferred idiom to convert
+a signed value into an unsigned value. Here’s a cheat sheet for bytes, shorts,
+and ints:
+
+| Type  | Signed Range                  | Unsigned Range   | Signed to Unsigned          |
+| :---- | :---------------------------: | :--------------- | :-------------------------- |
+| byte  | -128..127                     | 0..255           | `int u = s & 0xff;`         |
+| short | -32,768..32,767               | 0..65,535        | `int u = s & 0xffff;`       |
+| int   | -2,147,483,648..2,147,483,647 | 0..4,294,967,295 | `long u = s & 0xffffffffL;` |
+
+Java has no primitive type that can represent unsigned longs.
+
+
+### Hashing ([Java][Hashing]/[Kotlin][HashingKt])
+
+We’re bombarded by hashing in our lives as Java programmers. Early on we're introduced to the
+`hashCode()` method, something we know we need to override otherwise unforeseen bad things happen.
+Later we’re shown `LinkedHashMap` and its friends. These build on that `hashCode()` method to
+organize data for fast retrieval.
+
+Elsewhere we have cryptographic hash functions. These get used all over the place. HTTPS
+certificates, Git commits, BitTorrent integrity checking, and Blockchain blocks all use
+cryptographic hashes. Good use of hashes can improve the performance, privacy, security, and
+simplicity of an application.
+
+Each cryptographic hash function accepts a variable-length stream of input bytes and produces a
+fixed-length byte string value called the “hash”. Hash functions have these important qualities:
+
+ * Deterministic: each input always produces the same output.
+ * Uniform: each output byte string is equally likely. It is very difficult to find or create pairs
+   of different inputs that yield the same output. This is called a “collision”.
+ * Non-reversible: knowing an output doesn't help you to find the input. Note that if you know some
+   possible inputs you can hash them to see if their hashes match.
+ * Well-known: the hash is implemented everywhere and rigorously understood.
+
+Good hash functions are very cheap to compute (dozens of microseconds) and expensive to reverse
+(quintillions of millenia). Steady advances in computing and mathematics have caused once-great hash
+functions to become inexpensive to reverse. When choosing a hash function, beware that not all are
+created equal! Okio supports these well-known cryptographic hash functions:
+
+ * **MD5**: a 128-bit (16 byte) cryptographic hash. It is both insecure and obsolete because it is
+   inexpensive to reverse! This hash is offered because it is popular and convenient for use in
+   legacy systems that are not security-sensitive.
+ * **SHA-1**: a 160-bit (20 byte) cryptographic hash. It was recently demonstrated that it is
+   feasible to create SHA-1 collisions. Consider upgrading from SHA-1 to SHA-256.
+ * **SHA-256**: a 256-bit (32 byte) cryptographic hash. SHA-256 is widely understood and expensive
+   to reverse. This is the hash most systems should use.
+ * **SHA-512**: a 512-bit (64 byte) cryptographic hash. It is expensive to reverse.
+
+Each hash creates a `ByteString` of the specified length. Use `hex()` to get the conventional
+human-readable form. Or leave it as a `ByteString` because that’s a convenient model type!
+
+Okio can produce cryptographic hashes from byte strings:
+
+=== "Java"
+    
+    ```Java
+    ByteString byteString = readByteString(new File("README.md"));
+    System.out.println("   md5: " + byteString.md5().hex());
+    System.out.println("  sha1: " + byteString.sha1().hex());
+    System.out.println("sha256: " + byteString.sha256().hex());
+    System.out.println("sha512: " + byteString.sha512().hex());
+    ```
+    
+=== "Kotlin"
+    
+    ```Kotlin
+    val byteString = readByteString(File("README.md"))
+    println("       md5: " + byteString.md5().hex())
+    println("      sha1: " + byteString.sha1().hex())
+    println("    sha256: " + byteString.sha256().hex())
+    println("    sha512: " + byteString.sha512().hex())
+    ```
+
+From buffers:
+
+=== "Java"
+    
+    ```Java
+    Buffer buffer = readBuffer(new File("README.md"));
+    System.out.println("   md5: " + buffer.md5().hex());
+    System.out.println("  sha1: " + buffer.sha1().hex());
+    System.out.println("sha256: " + buffer.sha256().hex());
+    System.out.println("sha512: " + buffer.sha512().hex());
+    ```
+    
+=== "Kotlin"
+    
+    ```Kotlin
+    val buffer = readBuffer(File("README.md"))
+    println("       md5: " + buffer.md5().hex())
+    println("      sha1: " + buffer.sha1().hex())
+    println("    sha256: " + buffer.sha256().hex())
+    println("    sha512: " + buffer.sha512().hex())
+    ```
+
+While streaming from a source:
+
+=== "Java"
+    
+    ```Java
+    try (HashingSink hashingSink = HashingSink.sha256(Okio.blackhole());
+         BufferedSource source = Okio.buffer(Okio.source(file))) {
+      source.readAll(hashingSink);
+      System.out.println("sha256: " + hashingSink.hash().hex());
+    }
+    ```
+    
+=== "Kotlin"
+    
+    ```Kotlin
+    sha256(blackholeSink()).use { hashingSink ->
+      file.source().buffer().use { source ->
+        source.readAll(hashingSink)
+        println("    sha256: " + hashingSink.hash.hex())
+      }
+    }
+    ```
+
+While streaming to a sink:
+
+=== "Java"
+    
+    ```Java
+    try (HashingSink hashingSink = HashingSink.sha256(Okio.blackhole());
+         BufferedSink sink = Okio.buffer(hashingSink);
+         Source source = Okio.source(file)) {
+      sink.writeAll(source);
+      sink.close(); // Emit anything buffered.
+      System.out.println("sha256: " + hashingSink.hash().hex());
+    }
+    ```
+    
+=== "Kotlin"
+    
+    ```Kotlin
+    sha256(blackholeSink()).use { hashingSink ->
+      hashingSink.buffer().use { sink ->
+        file.source().use { source ->
+          sink.writeAll(source)
+          sink.close() // Emit anything buffered.
+          println("    sha256: " + hashingSink.hash.hex())
+        }
+      }
+    }
+    ```
+
+Okio also supports HMAC (Hash Message Authentication Code) which combines a secret and a hash.
+Applications use HMAC for data integrity and authentication.
+
+=== "Java"
+    
+    ```Java
+    ByteString secret = ByteString.decodeHex("7065616e7574627574746572");
+    System.out.println("hmacSha256: " + byteString.hmacSha256(secret).hex());
+    ```
+
+=== "Kotlin"
+    
+    ```Kotlin
+    val secret = "7065616e7574627574746572".decodeHex()
+    println("hmacSha256: " + byteString.hmacSha256(secret).hex())
+    ```
+
+As with hashing, you can generate an HMAC from a `ByteString`, `Buffer`, `HashingSource`, and
+`HashingSink`. Note that Okio doesn’t implement HMAC for MD5. Okio uses Java’s
+`java.security.MessageDigest` for cryptographic hashes and `javax.crypto.Mac` for HMAC.
+
+### Encryption and Decryption
+
+Use `Okio.cipherSink(Sink, Cipher)` or `Okio.cipherSource(Source, Cipher)` to encrypt or decrypt a
+stream using a block cipher.
+
+Callers are responsible for the initialization of the encryption or decryption cipher with the 
+chosen algorithm, the key, and algorithm-specific additional parameters like the initialization 
+vector. The following example shows a typical usage with AES encryption, in which `key` and `iv`
+parameters should both be 16 bytes long.
+
+```java
+void encryptAes(ByteString bytes, File file, byte[] key, byte[] iv)
+    throws GeneralSecurityException, IOException {
+  Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+  cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv));
+  try (BufferedSink sink = Okio.buffer(Okio.cipherSink(Okio.sink(file), cipher))) {
+    sink.write(bytes);
+  }
+}
+
+ByteString decryptAesToByteString(File file, byte[] key, byte[] iv)
+    throws GeneralSecurityException, IOException {
+  Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+  cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv));
+  try (BufferedSource source = Okio.buffer(Okio.cipherSource(Okio.source(file), cipher))) {
+    return source.readByteString();
+  }
+}
+```
+
+In Kotlin, these encryption and decryption methods are extensions on `Cipher`:
+
+```kotlin
+fun encryptAes(bytes: ByteString, file: File, key: ByteArray, iv: ByteArray) {
+  val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
+  cipher.init(Cipher.ENCRYPT_MODE, SecretKeySpec(key, "AES"), IvParameterSpec(iv))
+  val cipherSink = file.sink().cipherSink(cipher)
+  cipherSink.buffer().use { 
+    it.write(bytes) 
+  }
+}
+
+fun decryptAesToByteString(file: File, key: ByteArray, iv: ByteArray): ByteString {
+  val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
+  cipher.init(Cipher.DECRYPT_MODE, SecretKeySpec(key, "AES"), IvParameterSpec(iv))
+  val cipherSource = file.source().cipherSource(cipher)
+  return cipherSource.buffer().use { 
+    it.readByteString()
+  }
+}
+```
+
+File System Examples
+--------------------
+
+Okio's recently gained a multiplatform file system API. These examples work on JVM, native, and
+Node.js platforms. In the examples below `fileSystem` is an instance of [FileSystem] such as
+`FileSystem.SYSTEM` or `FakeFileSystem`.
+
+Read all of `readme.md` as a string:
+
+```
+val path = "readme.md".toPath()
+val entireFileString = fileSystem.read(path) {
+  readUtf8()
+}
+```
+
+Read all of `thumbnail.png` as a [ByteString][3]:
+
+```
+val path = "thumbnail.png".toPath()
+val entireFileByteString = fileSystem.read(path) {
+  readByteString()
+}
+```
+
+Read all lines of `/etc/hosts` into a `List<String>`:
+
+```
+val path = "/etc/hosts".toPath()
+val allLines = fileSystem.read(path) {
+  generateSequence { readUtf8Line() }.toList()
+}
+```
+
+Read the prefix of `index.html` that precedes the first `<html>` substring:
+
+```
+val path = "index.html".toPath()
+val untilHtmlTag = fileSystem.read(path) {
+  val htmlTag = indexOf("<html>".encodeUtf8())
+  if (htmlTag != -1L) readUtf8(htmlTag) else null
+}
+```
+
+Write `readme.md` as a string:
+
+```
+val path = "readme.md".toPath()
+fileSystem.write(path) {
+  writeUtf8(
+    """
+    |Hello, World
+    |------------
+    |
+    |This is a sample file.
+    |""".trimMargin()
+  )
+}
+```     
+
+Write `data.bin` as a [ByteString][3]:
+
+```     
+val path = "data.bin".toPath()
+fileSystem.write(path) {
+  val byteString = "68656c6c6f20776f726c640a".decodeHex()
+  write(byteString)
+}
+```     
+
+Write `readme.md` from a `List<String>`:
+
+```     
+val path = "readme.md".toPath()
+val lines = listOf(
+  "Hello, World",
+  "------------",
+  "",
+  "This is a sample file.",
+  ""
+)
+fileSystem.write(path) {
+  for (line in lines) {
+    writeUtf8(line)
+    writeUtf8("\n")
+  }
+}
+```     
+
+Generate `binary.txt` programmatically:
+
+```     
+val path = "binary.txt".toPath()
+fileSystem.write(path) {
+  for (i in 1 until 100) {
+    writeUtf8("$i ${i.toString(2)}")
+    writeUtf8("\n")
+  }
+}
+```
+
+
+Releases
+--------
+
+Our [change log][changelog] has release history.
+
+```kotlin
+implementation("com.squareup.okio:okio:2.10.0")
+```
+
+<details>
+   <summary>Snapshot builds are also available</summary>
+      
+```kotlin
+repositories {
+    maven {
+        url = uri("https://oss.sonatype.org/content/repositories/snapshots/")
+    }
+}
+      
+dependencies {
+   implementation("com.squareup.okio:okio:2.10.0")
+}
+```   
+  
+</details>
+
+
+R8 / ProGuard
+--------
+
+If you are using R8 or ProGuard add the options from [this file][proguard].
+
+
+License
+--------
+
+    Copyright 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.
+    
+ [1]: https://github.com/square/okhttp
+ [3]: https://square.github.io/okio/2.x/okio/okio/-byte-string/index.html
+ [4]: https://square.github.io/okio/2.x/okio/okio/-buffer/index.html
+ [5]: https://square.github.io/okio/2.x/okio/okio/-source/index.html
+ [6]: https://square.github.io/okio/2.x/okio/okio/-sink/index.html
+ [7]: https://square.github.io/okio/2.x/okio/okio/-buffered-source/index.html
+ [8]: https://square.github.io/okio/2.x/okio/okio/-buffered-sink/index.html
+ [changelog]: http://square.github.io/okio/changelog/
+ [javadoc]: https://square.github.io/okio/2.x/okio/okio/index.html
+ [nfd]: https://docs.oracle.com/javase/7/docs/api/java/text/Normalizer.Form.html#NFD
+ [nfc]: https://docs.oracle.com/javase/7/docs/api/java/text/Normalizer.Form.html#NFC
+ [base64]: https://tools.ietf.org/html/rfc4648#section-4
+ [bmp]: https://en.wikipedia.org/wiki/BMP_file_format
+ [kotlin]: https://kotlinlang.org/
+ [ok_libraries_talk]: https://www.youtube.com/watch?v=WvyScM_S88c
+ [ok_libraries_slides]: https://speakerdeck.com/jakewharton/a-few-ok-libraries-droidcon-mtl-2015
+ [encoding_talk]: https://www.youtube.com/watch?v=T_p22jMZSrk
+ [encoding_slides]: https://speakerdeck.com/swankjesse/decoding-the-secrets-of-binary-data-droidcon-nyc-2016
+ [ok_multiplatform_talk]: https://www.youtube.com/watch?v=Q8B4eDirgk0
+ [ok_multiplatform_slides]: https://speakerdeck.com/swankjesse/ok-multiplatform
+ [ReadFileLineByLine]: https://github.com/square/okio/blob/master/samples/src/jvmMain/java/okio/samples/ReadFileLineByLine.java
+ [ReadFileLineByLineKt]: https://github.com/square/okio/blob/master/samples/src/jvmMain/kotlin/okio/samples/ReadFileLineByLine.kt
+ [WriteFile]: https://github.com/square/okio/blob/master/samples/src/jvmMain/java/okio/samples/WriteFile.java
+ [WriteFileKt]: https://github.com/square/okio/blob/master/samples/src/jvmMain/kotlin/okio/samples/WriteFile.kt
+ [ExploreCharsets]: https://github.com/square/okio/blob/master/samples/src/jvmMain/java/okio/samples/ExploreCharsets.java
+ [ExploreCharsetsKt]: https://github.com/square/okio/blob/master/samples/src/jvmMain/kotlin/okio/samples/ExploreCharsets.kt
+ [FileSystem]: https://square.github.io/okio/2.x/okio/okio/-file-system/index.html
+ [GoldenValue]: https://github.com/square/okio/blob/master/samples/src/jvmMain/java/okio/samples/GoldenValue.java
+ [GoldenValueKt]: https://github.com/square/okio/blob/master/samples/src/jvmMain/kotlin/okio/samples/GoldenValue.kt
+ [BitmapEncoder]: https://github.com/square/okio/blob/master/samples/src/jvmMain/java/okio/samples/BitmapEncoder.java
+ [BitmapEncoderKt]: https://github.com/square/okio/blob/master/samples/src/jvmMain/kotlin/okio/samples/BitmapEncoder.kt
+ [SocksProxyServer]: https://github.com/square/okio/blob/master/samples/src/jvmMain/java/okio/samples/SocksProxyServer.java
+ [SocksProxyServerKt]: https://github.com/square/okio/blob/master/samples/src/jvmMain/kotlin/okio/samples/SocksProxyServer.kt
+ [Hashing]: https://github.com/square/okio/blob/master/samples/src/jvmMain/java/okio/samples/Hashing.java
+ [HashingKt]: https://github.com/square/okio/blob/master/samples/src/jvmMain/kotlin/okio/samples/Hashing.kt
+ [proguard]: https://github.com/square/okio/blob/master/okio/src/jvmMain/resources/META-INF/proguard/okio.pro
diff --git a/docs/multiplatform.md b/docs/multiplatform.md
new file mode 100644
index 0000000..cad6863
--- /dev/null
+++ b/docs/multiplatform.md
@@ -0,0 +1,40 @@
+Multiplatform
+=============
+
+Okio is a [Kotlin Multiplatform][kotlin_multiplatform] project. We're still completing our feature
+coverage.
+
+
+### Compression (Deflater, Inflater, Gzip)
+
+JVM-only.
+
+
+### Concurrency (Pipe, Timeouts, Throttler)
+
+JVM-only.
+
+Timeout is on all platforms, but only the JVM has a useful implementation.
+
+
+### Core (Buffer, ByteString, Source, Sink)
+
+Available on all platforms.
+
+
+### File System
+
+Available on all platforms. For JavaScript this requires [Node.js][node_js].
+
+
+### Hashing
+
+Okio includes Kotlin implementations of MD5, SHA-1, SHA-256, and SHA-512. This includes both hash
+functions and HMAC functions.
+
+Okio uses the built-in implementations of these functions on the JVM.
+
+
+[kotlin_multiplatform]: https://kotlinlang.org/docs/reference/multiplatform.html
+[mingw]: http://www.mingw.org/
+[node_js]: https://nodejs.org/api/fs.html
diff --git a/docs/releasing.md b/docs/releasing.md
new file mode 100644
index 0000000..94a1a34
--- /dev/null
+++ b/docs/releasing.md
@@ -0,0 +1,105 @@
+Releasing
+=========
+
+### Prerequisite: Sonatype (Maven Central) Account
+
+Create an account on the [Sonatype issues site][sonatype_issues]. Ask an existing publisher to open
+an issue requesting publishing permissions for `com.squareup` projects.
+
+### Prerequisite: GPG Keys
+
+Generate a GPG key (RSA, 4096 bit, 3650 day) expiry, or use an existing one. You should leave the
+password empty for this key.
+
+```
+$ gpg --full-generate-key
+```
+
+Upload the GPG keys to public servers:
+
+```
+$ gpg --list-keys --keyid-format LONG
+/Users/johnbarber/.gnupg/pubring.kbx
+------------------------------
+pub   rsa4096/XXXXXXXXXXXXXXXX 2019-07-16 [SC] [expires: 2029-07-13]
+      YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
+uid           [ultimate] John Barber <jbarber@squareup.com>
+sub   rsa4096/ZZZZZZZZZZZZZZZZ 2019-07-16 [E] [expires: 2029-07-13]
+
+$ gpg --send-keys --keyserver keyserver.ubuntu.com XXXXXXXXXXXXXXXX
+```
+
+### Prerequisite: Gradle Properties
+
+Define publishing properties in `~/.gradle/gradle.properties`:
+
+```
+signing.keyId=1A2345F8
+signing.password=
+signing.secretKeyRingFile=/Users/jbarber/.gnupg/secring.gpg
+```
+
+`signing.keyId` is the GPG key's ID. Get it with this:
+
+   ```
+   $ gpg --list-keys --keyid-format SHORT
+   ```
+
+`signing.password` is the password for this key. This might be empty!
+
+`signing.secretKeyRingFile` is the absolute path for `secring.gpg`. You may need to export this
+file manually with the following command where `XXXXXXXX` is the `keyId` above:
+
+   ```
+   $ gpg --keyring secring.gpg --export-secret-key XXXXXXXX > ~/.gnupg/secring.gpg
+   ```
+
+
+Cutting a Release
+-----------------
+
+1. Update `CHANGELOG.md`.
+
+2. Set versions:
+
+    ```
+    export RELEASE_VERSION=X.Y.Z
+    export NEXT_VERSION=X.Y.Z-SNAPSHOT
+    ```
+
+3. Set environment variables with your [Sonatype credentials][sonatype_issues].
+
+    ```
+    export SONATYPE_NEXUS_USERNAME=johnbarber
+    export SONATYPE_NEXUS_PASSWORD=`pbpaste`
+    ```
+
+4. Update, build, and upload:
+
+    ```
+    sed -i "" \
+      "s/VERSION_NAME=.*/VERSION_NAME=$RELEASE_VERSION/g" \
+      gradle.properties
+    sed -i "" \
+      "s/\"com.squareup.okio:\([^\:]*\):[^\"]*\"/\"com.squareup.okio:\1:$RELEASE_VERSION\"/g" \
+      `find . -name "README.md"`
+    ./gradlew clean publish
+    ```
+
+5. Visit [Sonatype Nexus][sonatype_nexus] to promote (close then release) the artifact. Or drop it
+   if there is a problem!
+
+6. Tag the release, prepare for the next one, and push to GitHub.
+
+    ```
+    git commit -am "Prepare for release $RELEASE_VERSION."
+    git tag -a parent-$RELEASE_VERSION -m "Version $RELEASE_VERSION"
+    sed -i "" \
+      "s/VERSION_NAME=.*/VERSION_NAME=$NEXT_VERSION/g" \
+      gradle.properties
+    git commit -am "Prepare next development version."
+    git push && git push --tags
+    ```
+
+ [sonatype_issues]: https://issues.sonatype.org/
+ [sonatype_nexus]: https://oss.sonatype.org/
diff --git a/docs/security.md b/docs/security.md
new file mode 100644
index 0000000..1eb8149
--- /dev/null
+++ b/docs/security.md
@@ -0,0 +1,19 @@
+Security Policy
+===============
+
+## Supported Versions
+
+| Version | Supported  |
+| ------- | ---------- |
+| 2.x     | ✅         |
+| 1.x     | ✅         |
+
+
+## Reporting a Vulnerability
+
+Square recognizes the important contributions the security research community
+can make. We therefore encourage reporting security issues with the code
+contained in this repository.
+
+If you believe you have discovered a security vulnerability, please follow the
+guidelines at https://bugcrowd.com/squareopensource
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..21f92f0
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,25 @@
+org.gradle.jvmargs='-Dfile.encoding=UTF-8'
+android.enableJetifier=true
+android.useAndroidX=true
+
+# Publishing SHA 256 and 512 hashses of maven-metadata is not supported by Sonatype and Nexus.
+# See https://github.com/gradle/gradle/issues/11308 and
+# https://issues.sonatype.org/browse/NEXUS-21802
+systemProp.org.gradle.internal.publish.checksums.insecure=true
+
+GROUP=com.squareup.okio
+VERSION_NAME=2.11.0-SNAPSHOT
+
+POM_DESCRIPTION=A modern I/O API for Java
+
+POM_URL=https://github.com/square/okio/
+POM_SCM_URL=https://github.com/square/okio/
+POM_SCM_CONNECTION=scm:git:git://github.com/square/okio.git
+POM_SCM_DEV_CONNECTION=scm:git:ssh://git@github.com/square/okio.git
+
+POM_LICENCE_NAME=The Apache Software License, Version 2.0
+POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
+POM_LICENCE_DIST=repo
+
+POM_DEVELOPER_ID=square
+POM_DEVELOPER_NAME=Square, Inc.
diff --git a/gradle/gradle-mvn-mpp-push.gradle b/gradle/gradle-mvn-mpp-push.gradle
new file mode 100644
index 0000000..7ec9429
--- /dev/null
+++ b/gradle/gradle-mvn-mpp-push.gradle
@@ -0,0 +1,137 @@
+apply plugin: 'maven-publish'
+apply plugin: 'signing'
+apply plugin: 'org.jetbrains.dokka'
+
+def dokkaConfiguration = {
+  outputDirectory.set(file("$rootDir/docs/2.x"))
+
+  dokkaSourceSets {
+    configureEach {
+      reportUndocumented.set(false)
+      skipDeprecated.set(true)
+      jdkVersion.set(8)
+      perPackageOption {
+        matchingRegex.set("com\\.squareup.okio.*")
+        suppress.set(true)
+      }
+      perPackageOption {
+        matchingRegex.set("okio\\.internal.*")
+        suppress.set(true)
+      }
+    }
+  }
+}
+
+dokkaGfm.configure(dokkaConfiguration)
+dokkaHtml.configure(dokkaConfiguration)
+
+def rootRelativePath(path) {
+  return rootProject.file(path).toString().replace('\\', '/')
+}
+
+dokkaHtml.pluginsMapConfiguration.set([
+  "org.jetbrains.dokka.base.DokkaBase": """{ "customStyleSheets": ["${rootRelativePath("docs/css/dokka-logo.css")}"], "customAssets" : ["${rootRelativePath("docs/images/logo-square.png")}"]}"""
+])
+
+def isReleaseBuild() {
+  return VERSION_NAME.contains("SNAPSHOT") == false
+}
+
+def getReleaseRepositoryUrl() {
+  return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL :
+          "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
+}
+
+def getSnapshotRepositoryUrl() {
+  return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL :
+          "https://oss.sonatype.org/content/repositories/snapshots/"
+}
+
+def getRepositoryUsername() {
+  return hasProperty('SONATYPE_NEXUS_USERNAME') ? SONATYPE_NEXUS_USERNAME : ""
+}
+
+def getRepositoryPassword() {
+  return hasProperty('SONATYPE_NEXUS_PASSWORD') ? SONATYPE_NEXUS_PASSWORD : ""
+}
+
+task emptySourcesJar(type: Jar) {
+  classifier = 'sources'
+}
+
+task javadocsJar(type: Jar, dependsOn: dokkaGfm) {
+  classifier = 'javadoc'
+  from dokkaGfm.outputDirectory
+}
+
+signing {
+  required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }
+  sign(publishing.publications)
+}
+
+publishing {
+  publications.all {
+    artifact javadocsJar
+
+    pom.withXml {
+      def root = asNode()
+
+      root.children().last() + {
+        resolveStrategy = Closure.DELEGATE_FIRST
+
+        description POM_DESCRIPTION
+        name POM_NAME
+        url POM_URL
+        licenses {
+          license {
+            name POM_LICENCE_NAME
+            url POM_LICENCE_URL
+            distribution POM_LICENCE_DIST
+          }
+        }
+        scm {
+          url POM_SCM_URL
+          connection POM_SCM_CONNECTION
+          developerConnection POM_SCM_DEV_CONNECTION
+        }
+        developers {
+          developer {
+            id POM_DEVELOPER_ID
+            name POM_DEVELOPER_NAME
+          }
+        }
+      }
+    }
+  }
+  
+  // Use default artifact name for the JVM target
+  publications {
+    kotlinMultiplatform {
+      artifactId = POM_ARTIFACT_ID + '-multiplatform'
+    }
+    jvm {
+      artifactId = POM_ARTIFACT_ID
+    }
+  }
+
+  afterEvaluate {
+    publications.getByName('kotlinMultiplatform') {
+      // Source jars are only created for platforms, not the common artifact.
+      artifact emptySourcesJar
+    }
+  }
+
+  repositories {
+    maven {
+      url isReleaseBuild() ? getReleaseRepositoryUrl() : getSnapshotRepositoryUrl()
+      credentials {
+        username getRepositoryUsername()
+        password getRepositoryPassword()
+      }
+    }
+    maven {
+      name 'test'
+      url "file://${rootProject.buildDir}/localMaven"
+    }
+  }
+}
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..4d9ca16
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..4f906e0
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# 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
+#
+#      https://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.
+#
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=`expr $i + 1`
+    done
+    case $i in
+        0) set -- ;;
+        1) set -- "$args0" ;;
+        2) set -- "$args0" "$args1" ;;
+        3) set -- "$args0" "$args1" "$args2" ;;
+        4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..ac1b06f
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/mkdocs.yml b/mkdocs.yml
new file mode 100644
index 0000000..11fd77f
--- /dev/null
+++ b/mkdocs.yml
@@ -0,0 +1,59 @@
+site_name: Okio
+repo_name: Okio
+repo_url: https://github.com/square/okio
+site_description: "A modern I/O library for Android, Kotlin, and Java."
+site_author: Square, Inc.
+remote_branch: gh-pages
+edit_uri: ""
+
+copyright: 'Copyright &copy; 2019 Square, Inc.'
+
+theme:
+  name: 'material'
+  favicon: images/icon-square.png
+  logo: images/icon-square.png
+  palette:
+    primary: 'deep purple'
+    accent: 'white'
+  icon:
+    repo: fontawesome/brands/github
+
+extra:
+  social:
+    - icon: fontawesome/brands/twitter
+      link: https://twitter.com/squareeng
+    - icon: fontawesome/brands/stack-overflow
+      link: https://stackoverflow.com/questions/tagged/okio?sort=active
+
+extra_css:
+  - 'css/app.css'
+
+markdown_extensions:
+  - smarty
+  - codehilite:
+      guess_lang: false
+  - footnotes
+  - meta
+  - toc:
+      permalink: true
+  - pymdownx.betterem:
+      smart_enable: all
+  - pymdownx.caret
+  - pymdownx.inlinehilite
+  - pymdownx.magiclink
+  - pymdownx.smartsymbols
+  - pymdownx.superfences
+  - pymdownx.tabbed
+  - pymdownx.tilde
+  - tables
+
+nav:
+  - 'Overview': index.md
+  - 'Stack Overflow ⏏': https://stackoverflow.com/questions/tagged/okio?sort=active
+  - '2.x API': 2.x/okio/okio/index.html
+  - '1.x API ⏏': https://square.github.io/okio/1.x/okio/
+  - 'Change Log': changelog.md
+  - 'Multiplatform': multiplatform.md
+  - 'Contributing': contributing.md
+  - 'Code of Conduct': code_of_conduct.md
+
diff --git a/okio/build.gradle b/okio/build.gradle
new file mode 100644
index 0000000..980ecb0
--- /dev/null
+++ b/okio/build.gradle
@@ -0,0 +1,193 @@
+apply plugin: 'org.jetbrains.kotlin.multiplatform'
+
+/*
+ * Here's the main hierarchy of variants. Any `expect` functions in one level of the tree are
+ * `actual` functions in a (potentially indirect) child node.
+ *
+ * ```
+ *   common
+ *   |-- jvm
+ *   '-- nonJvm
+ *       |-- js
+ *       '-- native
+ *           |- unix
+ *           |   |-- apple
+ *           |   |   |-- iosArm64
+ *           |   |   |-- iosX64
+ *           |   |   |-- macosX64
+ *           |   |   |-- watchosArm32
+ *           |   |   |-- watchosArm64
+ *           |   |   '-- watchosX86
+ *           |   '-- linux
+ *           |       '-- linuxX64
+ *           '-- mingw
+ *               '-- mingwX64
+ * ```
+ *
+ * Every child of `native` also includes a source set that depends on the pointer size:
+ *
+ *  * sizet32 for watchOS, including watchOS 64-bit architectures
+ *  * sizet64 for everything else
+ *
+ * The `hashFunctions` source set builds on all platforms. It ships as a main source set on non-JVM
+ * platforms and as a test source set on the JVM platform.
+ */
+kotlin {
+  jvm {
+    withJava()
+  }
+  if (kmpJsEnabled) {
+    js {
+      configure([compilations.main, compilations.test]) {
+        tasks.getByName(compileKotlinTaskName).kotlinOptions {
+          moduleKind = "umd"
+          sourceMap = true
+          metaInfo = true
+        }
+      }
+      nodejs {
+        testTask {
+          useMocha {
+            timeout = "30s"
+          }
+        }
+      }
+    }
+  }
+  if (kmpNativeEnabled) {
+    iosX64()
+    iosArm64()
+    watchosArm32()
+    watchosArm64()
+    watchosX86()
+    // Required to generate tests tasks: https://youtrack.jetbrains.com/issue/KT-26547
+    linuxX64()
+    macosX64()
+    mingwX64()
+  }
+  sourceSets {
+    all {
+      languageSettings {
+        useExperimentalAnnotation('kotlin.RequiresOptIn')
+      }
+    }
+    commonMain {
+      dependencies {
+        api deps.kotlin.stdLib.common
+      }
+    }
+    commonTest {
+      dependencies {
+        implementation deps.kotlin.test.common
+        implementation deps.kotlin.test.annotations
+        implementation deps.kotlin.time
+      }
+    }
+    nonJvmMain {
+      kotlin.srcDirs += 'src/hashFunctions/kotlin'
+    }
+    jvmMain {
+      dependencies {
+        api deps.kotlin.stdLib.jdk6
+        compileOnly deps.animalSniffer.annotations
+      }
+    }
+    jvmTest {
+      kotlin.srcDirs += 'src/hashFunctions/kotlin'
+      dependencies {
+        implementation deps.test.junit
+        implementation deps.test.assertj
+        implementation deps.kotlin.test.jdk
+      }
+    }
+    jsMain {
+      dependsOn nonJvmMain
+      dependencies {
+        api deps.kotlin.stdLib.js
+      }
+    }
+    jsTest {
+      dependencies {
+        implementation deps.kotlin.test.js
+      }
+    }
+
+    nativeMain {
+      dependsOn nonJvmMain
+    }
+    nativeTest {
+      dependsOn commonTest
+    }
+
+    sizet32Main {
+      dependsOn nativeMain
+    }
+    sizet64Main {
+      dependsOn nativeMain
+    }
+
+    mingwMain {
+      dependsOn nativeMain
+    }
+    mingwX64Main {
+      dependsOn sizet64Main
+      dependsOn mingwMain
+    }
+    mingwX64Test {
+      dependsOn nativeTest
+    }
+
+    unixMain {
+      dependsOn nativeMain
+    }
+
+    appleMain {
+      dependsOn unixMain
+    }
+    appleTest {
+      dependsOn nativeTest
+    }
+    configure([iosX64Main, iosArm64Main, macosX64Main]) {
+      dependsOn sizet64Main
+      dependsOn appleMain
+    }
+    configure([iosX64Test, iosArm64Test, macosX64Test]) {
+      dependsOn appleTest
+    }
+    configure([watchosArm32Main, watchosArm64Main, watchosX86Main]) {
+      // Note that size_t is 32-bit on all watchOS versions (ie. pointers are always 32-bit).
+      dependsOn sizet32Main
+      dependsOn appleMain
+    }
+    configure([watchosArm32Test, watchosArm64Test, watchosX86Test]) {
+      dependsOn appleTest
+    }
+
+    linuxMain {
+      dependsOn unixMain
+      dependsOn nativeMain
+    }
+    linuxX64Main {
+      dependsOn sizet64Main
+      dependsOn linuxMain
+    }
+    linuxX64Test {
+      dependsOn nativeTest
+    }
+  }
+}
+
+tasks.withType(JavaCompile) {
+  options.encoding = 'UTF-8'
+  targetCompatibility = JavaVersion.VERSION_1_8
+}
+
+// modify these lines for MANIFEST.MF properties or for specific bnd instructions
+project.ext.bndManifest = '''
+    Export-Package: okio
+    Automatic-Module-Name: okio
+    Bundle-SymbolicName: com.squareup.okio
+    '''
+
+apply from: 'jvm/jvm.gradle'
+apply from: "$rootDir/gradle/gradle-mvn-mpp-push.gradle"
diff --git a/okio/gradle.properties b/okio/gradle.properties
new file mode 100644
index 0000000..775966e
--- /dev/null
+++ b/okio/gradle.properties
@@ -0,0 +1,2 @@
+POM_ARTIFACT_ID=okio
+POM_NAME=Okio
diff --git a/okio/jvm/japicmp/build.gradle b/okio/jvm/japicmp/build.gradle
new file mode 100644
index 0000000..782c699
--- /dev/null
+++ b/okio/jvm/japicmp/build.gradle
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+import me.champeau.gradle.japicmp.JapicmpTask
+
+apply plugin: 'java-library'
+apply plugin: 'me.champeau.gradle.japicmp'
+
+configurations {
+  baseline
+  latest
+}
+
+dependencies {
+  baseline('com.squareup.okio:okio:1.14.1') {
+    transitive = false
+    force = true
+  }
+  latest project(path: ':okio', configuration: 'jvmRuntimeElements')
+}
+
+task japicmp(type: JapicmpTask, dependsOn: 'jar') {
+  oldClasspath = configurations.baseline
+  newClasspath = configurations.latest
+  onlyBinaryIncompatibleModified = true
+  failOnModification = true
+  txtOutputFile = file("$buildDir/reports/japi.txt")
+  ignoreMissingClasses = true
+  includeSynthetic = true
+  classExcludes = [
+      'okio.ByteString', // Bytecode version changed from 51.0 to 50.0
+      'okio.RealBufferedSink', // Internal.
+      'okio.RealBufferedSource', // Internal.
+      'okio.SegmentedByteString', // Internal.
+      'okio.SegmentPool', // Internal.
+      'okio.Util', // Internal.
+      'okio.Options', // Bytecode version changed from 51.0 to 50.0
+  ]
+  methodExcludes = [
+      'okio.ByteString#getByte(int)', // Became 'final' in 1.15.0.
+      'okio.ByteString#size()', // Became 'final' in 1.15.0.
+  ]
+}
+check.dependsOn japicmp
diff --git a/okio/jvm/jmh/README.md b/okio/jvm/jmh/README.md
new file mode 100644
index 0000000..d7c6d77
--- /dev/null
+++ b/okio/jvm/jmh/README.md
@@ -0,0 +1,10 @@
+Okio Benchmarks
+===============
+
+This module contains JMH microbenchmarks. Run benchmarks locally with Gradle:
+
+```
+$ ./gradlew jmh
+```
+
+Select and configure benchmarks in the `jmh` section of `okio/jvm/jmh/build.gradle`.
diff --git a/okio/jvm/jmh/build.gradle b/okio/jvm/jmh/build.gradle
new file mode 100644
index 0000000..54eebdd
--- /dev/null
+++ b/okio/jvm/jmh/build.gradle
@@ -0,0 +1,36 @@
+import com.github.jengelman.gradle.plugins.shadow.transformers.DontIncludeResourceTransformer
+import com.github.jengelman.gradle.plugins.shadow.transformers.IncludeResourceTransformer
+
+apply plugin: 'java-library'
+apply plugin: 'org.jetbrains.kotlin.jvm'
+apply plugin: 'com.github.johnrengelman.shadow'
+apply plugin: 'me.champeau.gradle.jmh'
+
+jmhJar {
+  def excludeAllBenchmarkLists = new DontIncludeResourceTransformer()
+  excludeAllBenchmarkLists.resource = "META-INF/BenchmarkList"
+  transform(excludeAllBenchmarkLists)
+
+  def includeCorrectBenchmarkList = new IncludeResourceTransformer()
+  includeCorrectBenchmarkList.resource = "META-INF/BenchmarkList"
+  includeCorrectBenchmarkList.file = new File("${project.buildDir}/jmh-generated-resources/META-INF/BenchmarkList")
+  transform(includeCorrectBenchmarkList)
+}
+
+jmh {
+  jvmArgs = ['-Djmh.separateClasspathJAR=true']
+  include = ['com\\.squareup\\.okio\\.benchmarks\\.MessageDigestBenchmark.*']
+  duplicateClassesStrategy = 'warn'
+}
+
+dependencies {
+  compile project(':okio')
+  compile deps.kotlin.stdLib.jdk6
+  compile deps.jmh.core
+  jmh project(path: ':okio', configuration: 'jvmRuntimeElements')
+  jmh deps.kotlin.stdLib.jdk6
+  jmh deps.jmh.core
+  jmh deps.jmh.generator
+}
+
+assemble.dependsOn(jmhJar)
diff --git a/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/BenchmarkUtils.kt b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/BenchmarkUtils.kt
new file mode 100644
index 0000000..5c7b811
--- /dev/null
+++ b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/BenchmarkUtils.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2018 Square, Inc. and others.
+ *
+ * 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.squareup.okio.benchmarks
+
+import okio.internal.commonAsUtf8ToByteArray
+import okio.internal.commonToUtf8String
+
+// Necessary to make an invisible functions visible to Java.
+object BenchmarkUtils {
+  @JvmStatic
+  fun ByteArray.decodeUtf8(): String {
+    return commonToUtf8String()
+  }
+
+  @JvmStatic
+  fun String.encodeUtf8(): ByteArray {
+    return commonAsUtf8ToByteArray()
+  }
+}
diff --git a/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/BufferCursorSeekBenchmark.java b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/BufferCursorSeekBenchmark.java
new file mode 100644
index 0000000..8f6c007
--- /dev/null
+++ b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/BufferCursorSeekBenchmark.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2018 Square, Inc. and others.
+ *
+ * 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.squareup.okio.benchmarks;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+import okio.Buffer;
+import org.openjdk.jmh.Main;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.runner.RunnerException;
+
+@Fork(1)
+@Warmup(iterations = 5, time = 2)
+@Measurement(iterations = 5, time = 2)
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+public class BufferCursorSeekBenchmark {
+  Buffer buffer;
+  Buffer.UnsafeCursor cursor;
+
+  @Param({ "2097152" })
+  int bufferSize; // 2 MB = 256 Segments
+
+  @Setup
+  public void setup() throws IOException {
+    byte[] source = new byte[8192];
+    buffer = new Buffer();
+    while (buffer.size() < bufferSize) {
+      buffer.write(source);
+    }
+    cursor = new Buffer.UnsafeCursor();
+  }
+
+  @Benchmark
+  public void seekBeginning() {
+    buffer.readUnsafe(cursor);
+    try {
+      cursor.seek(0);
+    } finally {
+      cursor.close();
+    }
+  }
+
+  @Benchmark
+  public void seekEnd() {
+    buffer.readUnsafe(cursor);
+    try {
+      cursor.seek(buffer.size() - 1);
+    } finally {
+      cursor.close();
+    }
+  }
+
+  @Benchmark
+  public void seekForward() {
+    buffer.readUnsafe(cursor);
+    try {
+      cursor.seek(0);
+      cursor.seek(1);
+    } finally {
+      cursor.close();
+    }
+  }
+
+  @Benchmark
+  public void seekBackward() {
+    buffer.readUnsafe(cursor);
+    try {
+      cursor.seek(buffer.size() - 1);
+      cursor.seek(buffer.size() - 2);
+    } finally {
+      cursor.close();
+    }
+  }
+
+  public static void main(String[] args) throws IOException, RunnerException {
+    Main.main(new String[] {
+        BufferCursorSeekBenchmark.class.getName()
+    });
+  }
+}
diff --git a/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/BufferPerformanceBenchmark.java b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/BufferPerformanceBenchmark.java
new file mode 100644
index 0000000..22a73a2
--- /dev/null
+++ b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/BufferPerformanceBenchmark.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2014 Square, Inc. and others.
+ *
+ * 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.squareup.okio.benchmarks;
+
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Group;
+import org.openjdk.jmh.annotations.GroupThreads;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.annotations.Warmup;
+
+import okio.Buffer;
+import okio.BufferedSource;
+import okio.Okio;
+import okio.Sink;
+import okio.Timeout;
+
+import static java.util.Objects.requireNonNull;
+
+@Fork(1)
+@Warmup(iterations = 10, time = 10)
+@Measurement(iterations = 10, time = 10)
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+public class BufferPerformanceBenchmark {
+
+  public static final File OriginPath =
+      new File(System.getProperty("okio.bench.origin.path", "/dev/urandom"));
+
+  /* Test Workload
+   *
+   * Each benchmark thread maintains three buffers; a receive buffer, a process buffer
+   * and a send buffer. At every operation:
+   *
+   *   - We fill up the receive buffer using the origin, write the request to the process
+   *     buffer, and consume the process buffer.
+   *   - We fill up the process buffer using the origin, write the response to the send
+   *     buffer, and consume the send buffer.
+   *
+   * We use an "origin" source that serves as a preexisting sequence of bytes we can read
+   * from the file system. The request and response bytes are initialized in the beginning
+   * and reused throughout the benchmark in order to eliminate GC effects.
+   *
+   * Typically, we simulate the usage of small reads and large writes. Requests and
+   * responses are satisfied with precomputed buffers to eliminate GC effects on
+   * results.
+   *
+   * There are two types of benchmark tests; hot tests are "pedal to the metal" and
+   * use all CPU they can take. These are useful to magnify performance effects of
+   * changes but are not realistic use cases that should drive optimization efforts.
+   * Cold tests introduce think time between the receiving of the request and sending
+   * of the response. They are more useful as a reasonably realistic workload where
+   * buffers can be read from and written to during request/response handling but
+   * may hide subtle effects of most changes on performance. Prefer to look at the cold
+   * benchmarks first to decide if a bottleneck is worth pursuing, then use the hot
+   * benchmarks to fine tune optimization efforts.
+   *
+   * Benchmark threads do not explicitly communicate between each other (except to sync
+   * iterations as needed by JMH).
+   *
+   * We simulate think time for each benchmark thread by parking the thread for a
+   * configurable number of microseconds (1000 by default).
+   */
+
+
+  @Benchmark
+  @Threads(1)
+  public void threads1hot(HotBuffers buffers) throws IOException {
+    readWriteRecycle(buffers);
+  }
+
+  @Benchmark
+  @Threads(2)
+  public void threads2hot(HotBuffers buffers) throws IOException {
+    readWriteRecycle(buffers);
+  }
+
+  @Benchmark
+  @Threads(4)
+  public void threads4hot(HotBuffers buffers) throws IOException {
+    readWriteRecycle(buffers);
+  }
+
+  @Benchmark
+  @Threads(8)
+  public void threads8hot(HotBuffers buffers) throws IOException {
+    readWriteRecycle(buffers);
+  }
+
+  @Benchmark
+  @Threads(16)
+  public void threads16hot(HotBuffers buffers) throws IOException {
+    readWriteRecycle(buffers);
+  }
+
+  @Benchmark
+  @Threads(32)
+  public void threads32hot(HotBuffers buffers) throws IOException {
+    readWriteRecycle(buffers);
+  }
+
+  @Benchmark
+  @GroupThreads(1)
+  @Group("cold")
+  public void thinkReadHot(HotBuffers buffers) throws IOException {
+    buffers.receive(requestBytes).readAll(NullSink);
+  }
+
+  @Benchmark
+  @GroupThreads(3)
+  @Group("cold")
+  public void thinkWriteCold(ColdBuffers buffers) throws IOException {
+    buffers.transmit(responseBytes).readAll(NullSink);
+  }
+
+  private void readWriteRecycle(HotBuffers buffers) throws IOException {
+    buffers.receive(requestBytes).readAll(NullSink);
+    buffers.transmit(responseBytes).readAll(NullSink);
+  }
+
+  @Param({ "1000" })
+  int maxThinkMicros = 1000;
+
+  @Param({ "1024" })
+  int maxReadBytes = 1024;
+
+  @Param({ "1024" })
+  int maxWriteBytes = 1024;
+
+  @Param({ "2048" })
+  int requestSize = 2048;
+
+  @Param({ "1" })
+  int responseFactor = 1;
+
+  byte[] requestBytes;
+
+  byte[] responseBytes;
+
+  @Setup(Level.Trial)
+  public void storeRequestResponseData() throws IOException {
+    checkOrigin(OriginPath);
+
+    requestBytes = storeSourceData(new byte[requestSize]);
+    responseBytes = storeSourceData(new byte[requestSize * responseFactor]);
+  }
+
+  private byte[] storeSourceData(byte[] dest) throws IOException {
+    requireNonNull(dest, "dest == null");
+    try (BufferedSource source = Okio.buffer(Okio.source(OriginPath))) {
+      source.readFully(dest);
+    }
+    return dest;
+  }
+
+  private void checkOrigin(File path) throws IOException {
+    requireNonNull(path, "path == null");
+
+    if (!path.canRead()) {
+      throw new IllegalArgumentException("can not access: " + path);
+    }
+
+    try (InputStream in = new FileInputStream(path)) {
+      int available = in.read();
+      if (available < 0) {
+        throw new IllegalArgumentException("can not read: " + path);
+      }
+    }
+  }
+
+  /*
+   * The state class hierarchy is larger than it needs to be due to a JMH
+   * issue where states inheriting setup methods depending on another state
+   * do not get initialized correctly from benchmark methods making use
+   * of groups. To work around, we leave the common setup and teardown code
+   * in superclasses and move the setup method depending on the bench state
+   * to subclasses. Without the workaround, it would have been enough for
+   * `ColdBuffers` to inherit from `HotBuffers`.
+   */
+
+  @State(Scope.Thread)
+  public static class ColdBuffers extends BufferSetup {
+
+    @Setup(Level.Trial)
+    public void setupBench(BufferPerformanceBenchmark bench) {
+      super.bench = bench;
+    }
+
+    @Setup(Level.Invocation)
+    public void lag() throws InterruptedException {
+      TimeUnit.MICROSECONDS.sleep(bench.maxThinkMicros);
+    }
+
+  }
+
+  @State(Scope.Thread)
+  public static class HotBuffers extends BufferSetup {
+
+    @Setup(Level.Trial)
+    public void setupBench(BufferPerformanceBenchmark bench) {
+      super.bench = bench;
+    }
+
+  }
+
+  @State(Scope.Thread)
+  public abstract static class BufferSetup extends BufferState {
+    BufferPerformanceBenchmark bench;
+
+    public BufferedSource receive(byte[] bytes) throws IOException {
+      return super.receive(bytes, bench.maxReadBytes);
+    }
+
+    public BufferedSource transmit(byte[] bytes) throws IOException {
+      return super.transmit(bytes, bench.maxWriteBytes);
+    }
+
+    @TearDown
+    public void dispose() throws IOException {
+      releaseBuffers();
+    }
+
+  }
+
+  public static class BufferState {
+
+    @SuppressWarnings("resource")
+    final Buffer received = new Buffer();
+    @SuppressWarnings("resource")
+    final Buffer sent = new Buffer();
+    @SuppressWarnings("resource")
+    final Buffer process = new Buffer();
+
+    public void releaseBuffers() throws IOException {
+      received.clear();
+      sent.clear();
+      process.clear();
+    }
+
+    /**
+     * Fills up the receive buffer, hands off to process buffer and returns it for consuming.
+     * Expects receive and process buffers to be empty. Leaves the receive buffer empty and
+     * process buffer full.
+     */
+    protected Buffer receive(byte[] bytes, int maxChunkSize) throws IOException {
+      writeChunked(received, bytes, maxChunkSize).readAll(process);
+      return process;
+    }
+
+    /**
+     * Fills up the process buffer, hands off to send buffer and returns it for consuming.
+     * Expects process and sent buffers to be empty. Leaves the process buffer empty and
+     * sent buffer full.
+     */
+    protected BufferedSource transmit(byte[] bytes, int maxChunkSize) throws IOException {
+      writeChunked(process, bytes, maxChunkSize).readAll(sent);
+      return sent;
+    }
+
+    private BufferedSource writeChunked(Buffer buffer, byte[] bytes, final int chunkSize) {
+      int remaining = bytes.length;
+      int offset = 0;
+      while (remaining > 0) {
+        int bytesToWrite = Math.min(remaining, chunkSize);
+        buffer.write(bytes, offset, bytesToWrite);
+        remaining -= bytesToWrite;
+        offset += bytesToWrite;
+      }
+      return buffer;
+    }
+
+  }
+
+  @SuppressWarnings("resource")
+  private static final Sink NullSink = new Sink() {
+
+    @Override public void write(Buffer source, long byteCount) throws EOFException {
+      source.skip(byteCount);
+    }
+
+    @Override public void flush() {
+      // nothing
+    }
+
+    @Override public Timeout timeout() {
+      return Timeout.NONE;
+    }
+
+    @Override public void close() {
+      // nothing
+    }
+
+    @Override public String toString() {
+      return "NullSink{}";
+    }
+  };
+
+}
diff --git a/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/BufferUtf8Benchmark.java b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/BufferUtf8Benchmark.java
new file mode 100644
index 0000000..61ea059
--- /dev/null
+++ b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/BufferUtf8Benchmark.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2018 Square, Inc. and others.
+ *
+ * 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.squareup.okio.benchmarks;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.Main;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.runner.RunnerException;
+
+import okio.Buffer;
+import okio.ByteString;
+
+@Fork(1)
+@Warmup(iterations = 5, time = 2)
+@Measurement(iterations = 5, time = 2)
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+public class BufferUtf8Benchmark {
+  private static final Map<String, String> strings = new HashMap<>();
+
+  static {
+    strings.put(
+        "ascii",
+        "Um, I'll tell you the problem with the scientific power that you're using here, "
+            + "it didn't require any discipline to attain it. You read what others had done and you "
+            + "took the next step. You didn't earn the knowledge for yourselves, so you don't take any "
+            + "responsibility for it. You stood on the shoulders of geniuses to accomplish something "
+            + "as fast as you could, and before you even knew what you had, you patented it, and "
+            + "packaged it, and slapped it on a plastic lunchbox, and now you're selling it, you wanna "
+            + "sell it.");
+
+    strings.put(
+        "utf8",
+        "Սｍ, I'll 𝓽𝖾ll ᶌօ𝘂 ᴛℎ℮ 𝜚𝕣०ｂl𝖾ｍ ｗі𝕥𝒽 𝘵𝘩𝐞 𝓼𝙘𝐢𝔢𝓷𝗍𝜄𝚏𝑖ｃ 𝛠𝝾ｗ𝚎𝑟 𝕥ｈ⍺𝞃 𝛄𝓸𝘂'𝒓𝗲 υ𝖘𝓲𝗇ɡ 𝕙𝚎𝑟ｅ, "
+            + "𝛊𝓽 ⅆ𝕚𝐝𝝿'𝗍 𝔯𝙚𝙦ᴜ𝜾𝒓𝘦 𝔞𝘯𝐲 ԁ𝜄𝑠𝚌ι𝘱lι𝒏ｅ 𝑡𝜎 𝕒𝚝𝖙𝓪і𝞹 𝔦𝚝. 𝒀ο𝗎 𝔯𝑒⍺𝖉 ｗ𝐡𝝰𝔱 𝞂𝞽һ𝓮𝓇ƽ հ𝖺𝖉 ⅾ𝛐𝝅ⅇ 𝝰πԁ 𝔂ᴑᴜ 𝓉ﮨ၀𝚔 "
+            + "т𝒽𝑒 𝗇𝕖ⅹ𝚝 𝔰𝒕е𝓅. 𝘠ⲟ𝖚 𝖉ⅰԁ𝝕'τ 𝙚𝚊ｒ𝞹 𝘵Ꮒ𝖾 𝝒𝐧هｗl𝑒𝖉ƍ𝙚 𝓯૦ｒ 𝔂𝞼𝒖𝕣𝑠𝕖l𝙫𝖊𝓼, 𐑈о ｙ𝘰𝒖 ⅆە𝗇'ｔ 𝜏α𝒌𝕖 𝛂𝟉ℽ "
+            + "𝐫ⅇ𝗌ⲣ๐ϖ𝖘ꙇᖯ𝓲l𝓲𝒕𝘆 𝐟𝞼𝘳 𝚤𝑡. 𝛶𝛔𝔲 ｓ𝕥σσ𝐝 ﮩ𝕟 𝒕𝗁𝔢 𝘴𝐡𝜎ᴜlⅾ𝓮𝔯𝚜 𝛐𝙛 ᶃ𝚎ᴨᎥս𝚜𝘦𝓈 𝓽𝞸 ａ𝒄𝚌𝞸ｍρl𝛊ꜱ𝐡 𝓈𝚘ｍ𝚎𝞃𝔥⍳𝞹𝔤 𝐚𝗌 𝖋ａ𝐬𝒕 "
+            + "αｓ γ𝛐𝕦 𝔠ﻫ𝛖lԁ, 𝚊π𝑑 Ь𝑒𝙛૦𝓇𝘦 𝓎٥𝖚 ⅇｖℯ𝝅 𝜅ո𝒆ｗ ｗ𝗵𝒂𝘁 ᶌ੦𝗎 ｈ𝐚𝗱, 𝜸ﮨ𝒖 𝓹𝝰𝔱𝖾𝗇𝓽𝔢ⅆ і𝕥, 𝚊𝜛𝓭 𝓹𝖺ⅽϰ𝘢ℊеᏧ 𝑖𝞃, "
+            + "𝐚𝛑ꓒ 𝙨l𝔞р𝘱𝔢𝓭 ɩ𝗍 ہ𝛑 𝕒 ｐl𝛂ѕᴛ𝗂𝐜 l𝞄ℼ𝔠𝒽𝑏ﮪ⨯, 𝔞ϖ𝒹 ｎ𝛔ｗ 𝛾𝐨𝞄'𝗿𝔢 ꜱ℮ll𝙞ｎɡ ɩ𝘁, 𝙮𝕠𝛖 ｗ𝑎ℼ𝚗𝛂 𝕤𝓮ll 𝙞𝓉.");
+
+    // The first 't' is actually a '𝓽'
+    strings.put(
+        "sparse",
+        "Um, I'll 𝓽ell you the problem with the scientific power that you're using here, "
+            + "it didn't require any discipline to attain it. You read what others had done and you "
+            + "took the next step. You didn't earn the knowledge for yourselves, so you don't take any "
+            + "responsibility for it. You stood on the shoulders of geniuses to accomplish something "
+            + "as fast as you could, and before you even knew what you had, you patented it, and "
+            + "packaged it, and slapped it on a plastic lunchbox, and now you're selling it, you wanna "
+            + "sell it.");
+
+    strings.put("2bytes", "\u0080\u07ff");
+
+    strings.put("3bytes", "\u0800\ud7ff\ue000\uffff");
+
+    strings.put("4bytes", "\ud835\udeca");
+
+    // high surrogate, 'a', low surrogate, and 'a'
+    strings.put("bad", "\ud800\u0061\udc00\u0061");
+  }
+
+  @Param({"20", "2000", "200000"})
+  int length;
+
+  @Param({"ascii", "utf8", "sparse", "2bytes", "3bytes", "4bytes", "bad"})
+  String encoding;
+
+  Buffer buffer;
+  String encode;
+  ByteString decode;
+
+  @Setup
+  public void setup() {
+    String part = strings.get(encoding);
+
+    // Make all the strings the same length for comparison
+    StringBuilder builder = new StringBuilder(length + 1_000);
+    while (builder.length() < length) {
+      builder.append(part);
+    }
+    builder.setLength(length);
+
+    // Prepare a string and ByteString for encoding and decoding
+    buffer = new Buffer();
+    encode = builder.toString();
+    Buffer temp = new Buffer();
+    temp.writeUtf8(encode);
+    decode = temp.snapshot();
+  }
+
+  @Benchmark
+  public void writeUtf8() {
+    buffer.writeUtf8(encode);
+    buffer.clear();
+  }
+
+  @Benchmark
+  public String readUtf8() {
+    buffer.write(decode);
+    return buffer.readUtf8();
+  }
+
+  public static void main(String[] args) throws IOException, RunnerException {
+    Main.main(new String[] {BufferUtf8Benchmark.class.getName()});
+  }
+}
diff --git a/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/GetByteBenchmark.java b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/GetByteBenchmark.java
new file mode 100644
index 0000000..2a51635
--- /dev/null
+++ b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/GetByteBenchmark.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2018 Square, Inc. and others.
+ *
+ * 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.squareup.okio.benchmarks;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+import okio.Buffer;
+import org.openjdk.jmh.Main;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.runner.RunnerException;
+
+@Fork(1)
+@Warmup(iterations = 5, time = 2)
+@Measurement(iterations = 5, time = 2)
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+public class GetByteBenchmark {
+  Buffer buffer;
+
+  @Param({ "2097152" })
+  int bufferSize; // 2 MB = 256 Segments
+
+  @Setup
+  public void setup() throws IOException {
+    buffer = new Buffer();
+    while (buffer.size() < bufferSize) {
+      buffer.write(new byte[8192]);
+    }
+  }
+
+  @Benchmark
+  public void getByteBeginning() {
+    buffer.getByte(0);
+  }
+
+  @Benchmark
+  public void getByteEnd() {
+    buffer.getByte(buffer.size() - 1);
+  }
+
+  @Benchmark
+  public void getByteMiddle() {
+    buffer.getByte(buffer.size() / 2);
+  }
+
+  public static void main(String[] args) throws IOException, RunnerException {
+    Main.main(new String[] {
+        GetByteBenchmark.class.getName()
+    });
+  }
+}
diff --git a/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/HashFunctionBenchmark.java b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/HashFunctionBenchmark.java
new file mode 100644
index 0000000..dc11738
--- /dev/null
+++ b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/HashFunctionBenchmark.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2020 Square, Inc. and others.
+ *
+ * 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.squareup.okio.benchmarks;
+
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.Main;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+
+@Fork(1)
+@Warmup(iterations = 5, time = 1)
+@Measurement(iterations = 5, time = 1)
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+public class HashFunctionBenchmark {
+
+  MessageDigest jvm;
+
+  @Param({ "100", "1048576" })
+  public int messageSize;
+
+  @Param({ "SHA-1", "SHA-256", "SHA-512", "MD5" })
+  public String algorithm;
+
+  private byte[] message;
+
+  @Setup public void setup() throws NoSuchAlgorithmException {
+    jvm = MessageDigest.getInstance(algorithm);
+    message = new byte[messageSize];
+  }
+
+  @Benchmark public void jvm() {
+    jvm.update(message, 0, messageSize);
+    jvm.digest();
+  }
+
+  public static void main(String[] args) throws IOException {
+    Main.main(new String[] { HashFunctionBenchmark.class.getName() });
+  }
+}
diff --git a/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/IndexOfElementBenchmark.java b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/IndexOfElementBenchmark.java
new file mode 100644
index 0000000..c628b19
--- /dev/null
+++ b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/IndexOfElementBenchmark.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2016 Square, Inc. and others.
+ *
+ * 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.squareup.okio.benchmarks;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+import okio.Buffer;
+import okio.ByteString;
+import org.openjdk.jmh.Main;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.runner.RunnerException;
+
+@Fork(1)
+@Warmup(iterations = 5, time = 2)
+@Measurement(iterations = 5, time = 2)
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+public class IndexOfElementBenchmark {
+  ByteString byteString = ByteString.encodeUtf8("abcd");
+  Buffer buffer;
+
+  @Param({ "32768" })
+  int bufferSize;
+
+  @Setup
+  public void setup() throws IOException {
+    buffer = new Buffer()
+        .write(new byte[bufferSize / 2])
+        .write(byteString)
+        .write(new byte[(bufferSize / 2) - byteString.size()]);
+  }
+
+  @Benchmark
+  public void indexOfByte() throws IOException {
+    buffer.indexOf((byte) 'b', 0L);
+  }
+
+  @Benchmark
+  public void indexOfByteString() throws IOException {
+    buffer.indexOf(byteString, 0L);
+  }
+
+  @Benchmark
+  public void indexOfElement() throws IOException {
+    buffer.indexOfElement(byteString, 0L);
+  }
+
+  public static void main(String[] args) throws IOException, RunnerException {
+    Main.main(new String[] {
+        IndexOfElementBenchmark.class.getName()
+    });
+  }
+}
diff --git a/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/ReadByteStringBenchmark.java b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/ReadByteStringBenchmark.java
new file mode 100644
index 0000000..466f7aa
--- /dev/null
+++ b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/ReadByteStringBenchmark.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2019 Square, Inc. and others.
+ *
+ * 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.squareup.okio.benchmarks;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+import okio.Buffer;
+import org.openjdk.jmh.Main;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.runner.RunnerException;
+
+@Fork(1)
+@Warmup(iterations = 5, time = 2)
+@Measurement(iterations = 5, time = 2)
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+public class ReadByteStringBenchmark {
+
+  Buffer buffer;
+
+  @Param({"32768"})
+  int bufferSize;
+
+  @Param({"8", "16", "32", "64", "128", "256", "512", "1024", "2048", "4096", "8192", "16384",
+      "32768"})
+  int byteStringSize;
+
+  @Setup
+  public void setup() {
+    buffer = new Buffer().write(new byte[bufferSize]);
+  }
+
+  @Benchmark
+  public void readByteString() throws IOException {
+    buffer.write(buffer.readByteString(byteStringSize));
+  }
+
+  @Benchmark
+  public void readByteString_toByteArray() throws IOException {
+    buffer.write(buffer.readByteString(byteStringSize).toByteArray());
+  }
+
+  public static void main(String[] args) throws IOException, RunnerException {
+    Main.main(new String[]{
+        ReadByteStringBenchmark.class.getName()
+    });
+  }
+}
diff --git a/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/SegmentedByteStringBenchmark.java b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/SegmentedByteStringBenchmark.java
new file mode 100644
index 0000000..394c214
--- /dev/null
+++ b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/SegmentedByteStringBenchmark.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2018 Square, Inc. and others.
+ *
+ * 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.squareup.okio.benchmarks;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+import okio.Buffer;
+import okio.ByteString;
+import org.openjdk.jmh.Main;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.runner.RunnerException;
+
+@Fork(1)
+@Warmup(iterations = 5, time = 2)
+@Measurement(iterations = 5, time = 2)
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+public class SegmentedByteStringBenchmark {
+
+  private static final ByteString UNKNOWN = ByteString.encodeUtf8("UNKNOWN");
+  private static final ByteString SEARCH = ByteString.encodeUtf8("tell");
+
+  @Param({"20", "2000", "200000"})
+  int length;
+
+  private ByteString byteString;
+
+  @Setup
+  public void setup() {
+    String part =
+        "Um, I'll tell you the problem with the scientific power that you're using here, "
+            + "it didn't require any discipline to attain it. You read what others had done and you "
+            + "took the next step. You didn't earn the knowledge for yourselves, so you don't take any "
+            + "responsibility for it. You stood on the shoulders of geniuses to accomplish something "
+            + "as fast as you could, and before you even knew what you had, you patented it, and "
+            + "packaged it, and slapped it on a plastic lunchbox, and now you're selling it, you wanna "
+            + "sell it.";
+
+    Buffer buffer = new Buffer();
+    while (buffer.size() < length) {
+      buffer.writeUtf8(part);
+    }
+    byteString = buffer.snapshot(length);
+  }
+
+  @Benchmark
+  public ByteString substring() {
+    return byteString.substring(1, byteString.size() - 1);
+  }
+
+  @Benchmark
+  public ByteString md5() {
+    return byteString.md5();
+  }
+
+  @Benchmark
+  public int indexOfUnknown() {
+    return byteString.indexOf(UNKNOWN);
+  }
+
+  @Benchmark
+  public int lastIndexOfUnknown() {
+    return byteString.lastIndexOf(UNKNOWN);
+  }
+
+  @Benchmark
+  public int indexOfEarly() {
+    return byteString.indexOf(SEARCH);
+  }
+
+  @Benchmark
+  public int lastIndexOfEarly() {
+    return byteString.lastIndexOf(SEARCH);
+  }
+
+  public static void main(String[] args) throws IOException, RunnerException {
+    Main.main(new String[] {SegmentedByteStringBenchmark.class.getName()});
+  }
+}
diff --git a/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/SelectBenchmark.java b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/SelectBenchmark.java
new file mode 100644
index 0000000..eeb7267
--- /dev/null
+++ b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/SelectBenchmark.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2018 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.squareup.okio.benchmarks;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+import okio.Buffer;
+import okio.ByteString;
+import okio.Options;
+import org.openjdk.jmh.Main;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.runner.RunnerException;
+
+@Fork(1)
+@Warmup(iterations = 5, time = 2)
+@Measurement(iterations = 5, time = 2)
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+public class SelectBenchmark {
+  /** Representative sample field names as one might find in a JSON document. */
+  List<String> sampleValues = Arrays.asList("id", "name", "description", "type", "sku_ids",
+      "offers", "start_time", "end_time", "expires", "start_of_availability", "duration",
+      "allow_recording", "thumbnail_id", "thumbnail_formats", "is_episode", "is_live", "channel_id",
+      "genre_list", "provider_networks", "year", "video_flags", "is_repeat", "series_id",
+      "series_name", "series_description", "original_air_date", "letter_box", "category",
+      "child_protection_rating", "parental_control_minimum_age", "images", "episode_id",
+      "season_number", "episode_number", "directors_list", "scriptwriters_list", "actors_list",
+      "drm_rights", "is_location_chk_reqd", "is_catchup_enabled", "catchup_duration",
+      "is_timeshift_enabled", "timeshift_duration", "is_startover_enabled", "is_recording_enabled",
+      "suspension_time", "shared_ref_id", "linked_channel_number", "audio_lang", "subcategory",
+      "metadata_root_id", "ref_id", "ref_type", "display_position", "thumbnail_format_list",
+      "network", "external_url", "offer_type", "em_format", "em_artist_name", "assets",
+      "media_class", "media_id", "channel_number");
+
+  @Param({ "4", "8", "16", "32", "64" })
+  int optionCount;
+
+  @Param({ "2048" })
+  int selectCount;
+
+  Buffer buffer = new Buffer();
+  Options options;
+  ByteString sampleData;
+
+  @Setup
+  public void setup() throws IOException {
+    ByteString[] byteStrings = new ByteString[optionCount];
+    for (int i = 0; i < optionCount; i++) {
+      byteStrings[i] = ByteString.encodeUtf8(sampleValues.get(i) + "\"");
+    }
+    options = Options.of(byteStrings);
+
+    Random dice = new Random(0);
+    Buffer sampleDataBuffer = new Buffer();
+    for (int i = 0; i < selectCount; i++) {
+      sampleDataBuffer.write(byteStrings[dice.nextInt(optionCount)]);
+    }
+    sampleData = sampleDataBuffer.readByteString();
+  }
+
+  @Benchmark
+  public void select() throws IOException {
+    buffer.write(sampleData);
+    for (int i = 0; i < selectCount; i++) {
+      buffer.select(options);
+    }
+    if (!buffer.exhausted()) throw new AssertionError();
+  }
+
+  public static void main(String[] args) throws IOException, RunnerException {
+    Main.main(new String[] {
+        SelectBenchmark.class.getName()
+    });
+  }
+}
diff --git a/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/Utf8Benchmark.java b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/Utf8Benchmark.java
new file mode 100644
index 0000000..db0b1ef
--- /dev/null
+++ b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/Utf8Benchmark.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2018 Square, Inc. and others.
+ *
+ * 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.squareup.okio.benchmarks;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.Main;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.runner.RunnerException;
+
+@Fork(1)
+@Warmup(iterations = 5, time = 2)
+@Measurement(iterations = 5, time = 2)
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.SECONDS)
+public class Utf8Benchmark {
+  private static final Charset utf8 = StandardCharsets.UTF_8;
+  private static final Map<String, String> strings = new HashMap<>();
+
+  static {
+    strings.put(
+        "ascii",
+        "Um, I'll tell you the problem with the scientific power that you're using here, "
+            + "it didn't require any discipline to attain it. You read what others had done and you "
+            + "took the next step. You didn't earn the knowledge for yourselves, so you don't take any "
+            + "responsibility for it. You stood on the shoulders of geniuses to accomplish something "
+            + "as fast as you could, and before you even knew what you had, you patented it, and "
+            + "packaged it, and slapped it on a plastic lunchbox, and now you're selling it, you wanna "
+            + "sell it.");
+
+    strings.put(
+        "utf8",
+        "Սｍ, I'll 𝓽𝖾ll ᶌօ𝘂 ᴛℎ℮ 𝜚𝕣०ｂl𝖾ｍ ｗі𝕥𝒽 𝘵𝘩𝐞 𝓼𝙘𝐢𝔢𝓷𝗍𝜄𝚏𝑖ｃ 𝛠𝝾ｗ𝚎𝑟 𝕥ｈ⍺𝞃 𝛄𝓸𝘂'𝒓𝗲 υ𝖘𝓲𝗇ɡ 𝕙𝚎𝑟ｅ, "
+            + "𝛊𝓽 ⅆ𝕚𝐝𝝿'𝗍 𝔯𝙚𝙦ᴜ𝜾𝒓𝘦 𝔞𝘯𝐲 ԁ𝜄𝑠𝚌ι𝘱lι𝒏ｅ 𝑡𝜎 𝕒𝚝𝖙𝓪і𝞹 𝔦𝚝. 𝒀ο𝗎 𝔯𝑒⍺𝖉 ｗ𝐡𝝰𝔱 𝞂𝞽һ𝓮𝓇ƽ հ𝖺𝖉 ⅾ𝛐𝝅ⅇ 𝝰πԁ 𝔂ᴑᴜ 𝓉ﮨ၀𝚔 "
+            + "т𝒽𝑒 𝗇𝕖ⅹ𝚝 𝔰𝒕е𝓅. 𝘠ⲟ𝖚 𝖉ⅰԁ𝝕'τ 𝙚𝚊ｒ𝞹 𝘵Ꮒ𝖾 𝝒𝐧هｗl𝑒𝖉ƍ𝙚 𝓯૦ｒ 𝔂𝞼𝒖𝕣𝑠𝕖l𝙫𝖊𝓼, 𐑈о ｙ𝘰𝒖 ⅆە𝗇'ｔ 𝜏α𝒌𝕖 𝛂𝟉ℽ "
+            + "𝐫ⅇ𝗌ⲣ๐ϖ𝖘ꙇᖯ𝓲l𝓲𝒕𝘆 𝐟𝞼𝘳 𝚤𝑡. 𝛶𝛔𝔲 ｓ𝕥σσ𝐝 ﮩ𝕟 𝒕𝗁𝔢 𝘴𝐡𝜎ᴜlⅾ𝓮𝔯𝚜 𝛐𝙛 ᶃ𝚎ᴨᎥս𝚜𝘦𝓈 𝓽𝞸 ａ𝒄𝚌𝞸ｍρl𝛊ꜱ𝐡 𝓈𝚘ｍ𝚎𝞃𝔥⍳𝞹𝔤 𝐚𝗌 𝖋ａ𝐬𝒕 "
+            + "αｓ γ𝛐𝕦 𝔠ﻫ𝛖lԁ, 𝚊π𝑑 Ь𝑒𝙛૦𝓇𝘦 𝓎٥𝖚 ⅇｖℯ𝝅 𝜅ո𝒆ｗ ｗ𝗵𝒂𝘁 ᶌ੦𝗎 ｈ𝐚𝗱, 𝜸ﮨ𝒖 𝓹𝝰𝔱𝖾𝗇𝓽𝔢ⅆ і𝕥, 𝚊𝜛𝓭 𝓹𝖺ⅽϰ𝘢ℊеᏧ 𝑖𝞃, "
+            + "𝐚𝛑ꓒ 𝙨l𝔞р𝘱𝔢𝓭 ɩ𝗍 ہ𝛑 𝕒 ｐl𝛂ѕᴛ𝗂𝐜 l𝞄ℼ𝔠𝒽𝑏ﮪ⨯, 𝔞ϖ𝒹 ｎ𝛔ｗ 𝛾𝐨𝞄'𝗿𝔢 ꜱ℮ll𝙞ｎɡ ɩ𝘁, 𝙮𝕠𝛖 ｗ𝑎ℼ𝚗𝛂 𝕤𝓮ll 𝙞𝓉.");
+
+    // The first 't' is actually a '𝓽'
+    strings.put(
+        "sparse",
+        "Um, I'll 𝓽ell you the problem with the scientific power that you're using here, "
+            + "it didn't require any discipline to attain it. You read what others had done and you "
+            + "took the next step. You didn't earn the knowledge for yourselves, so you don't take any "
+            + "responsibility for it. You stood on the shoulders of geniuses to accomplish something "
+            + "as fast as you could, and before you even knew what you had, you patented it, and "
+            + "packaged it, and slapped it on a plastic lunchbox, and now you're selling it, you wanna "
+            + "sell it.");
+
+    strings.put("2bytes", "\u0080\u07ff");
+
+    strings.put("3bytes", "\u0800\ud7ff\ue000\uffff");
+
+    strings.put("4bytes", "\ud835\udeca");
+
+    // high surrogate, 'a', low surrogate, and 'a'
+    strings.put("bad", "\ud800\u0061\udc00\u0061");
+  }
+
+  @Param({"20", "2000", "200000"})
+  int length;
+
+  @Param({"ascii", "utf8", "sparse", "2bytes", "3bytes", "4bytes", "bad"})
+  String encoding;
+
+  String encode;
+  byte[] decodeArray;
+
+  @Setup
+  public void setup() {
+    String part = strings.get(encoding);
+
+    // Make all the strings the same length for comparison
+    StringBuilder builder = new StringBuilder(length + 1_000);
+    while (builder.length() < length) {
+      builder.append(part);
+    }
+    builder.setLength(length);
+
+    // Prepare a string and byte array for encoding and decoding
+    encode = builder.toString();
+    decodeArray = encode.getBytes(utf8);
+  }
+
+  @Benchmark
+  public byte[] stringToBytesOkio() {
+    return BenchmarkUtils.encodeUtf8(encode);
+  }
+
+  @Benchmark
+  public byte[] stringToBytesJava() {
+    return encode.getBytes(utf8);
+  }
+
+  @Benchmark
+  public String bytesToStringOkio() {
+    // For ASCII only decoding, this will never be faster than Java. Because
+    // Java can trust the decoded char array and it will be the correct size for
+    // ASCII, it is able to avoid the extra defensive copy Okio is forced to
+    // make because it doesn't have access to String internals.
+    return BenchmarkUtils.decodeUtf8(decodeArray);
+  }
+
+  @Benchmark
+  public String bytesToStringJava() {
+    return new String(decodeArray, utf8);
+  }
+
+  public static void main(String[] args) throws IOException, RunnerException {
+    Main.main(new String[] {Utf8Benchmark.class.getName()});
+  }
+}
diff --git a/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/WriteHexadecimalBenchmark.java b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/WriteHexadecimalBenchmark.java
new file mode 100644
index 0000000..4cc1fb6
--- /dev/null
+++ b/okio/jvm/jmh/src/jmh/java/com/squareup/okio/benchmarks/WriteHexadecimalBenchmark.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2019 Square, Inc. and others.
+ *
+ * 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.squareup.okio.benchmarks;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+import okio.Buffer;
+import org.openjdk.jmh.Main;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.runner.RunnerException;
+
+@Fork(1)
+@Warmup(iterations = 5, time = 2)
+@Measurement(iterations = 5, time = 2)
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+public class WriteHexadecimalBenchmark {
+
+  Buffer buffer;
+
+  @Param({"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16"})
+  int width;
+
+  @Setup
+  public void setup() {
+    buffer = new Buffer();
+  }
+
+  @TearDown(Level.Invocation)
+  public void teardown() {
+    buffer.clear();
+  }
+
+  @Benchmark
+  public void writeHex() {
+    buffer.writeHexadecimalUnsignedLong(1L << width);
+  }
+
+  public static void main(String[] args) throws IOException, RunnerException {
+    Main.main(new String[]{
+        WriteHexadecimalBenchmark.class.getName()
+    });
+  }
+}
diff --git a/okio/jvm/jvm.gradle b/okio/jvm/jvm.gradle
new file mode 100644
index 0000000..cd81891
--- /dev/null
+++ b/okio/jvm/jvm.gradle
@@ -0,0 +1,26 @@
+apply plugin: 'java-library'
+apply plugin: 'ru.vyarus.animalsniffer'
+
+kotlin.targets.matching { it.platformType.name == 'jvm' }.all { target ->
+  target.project.sourceCompatibility = JavaVersion.VERSION_1_7
+  target.project.targetCompatibility = JavaVersion.VERSION_1_7
+  
+  tasks['jvmJar'].configure { t ->
+    // the bnd task convention modifies this jar task accordingly
+    def bndConvention = bndBundleTaskConventionClass.newInstance(t);
+    bndConvention.bnd = project.ext.bndManifest
+    // call the convention when the task has finished to modify the jar to contain OSGi metadata
+    t.doLast {
+      bndConvention.buildBundle()
+    }
+  }
+
+  target.project.animalsniffer {
+    sourceSets = [target.project.sourceSets.main]
+  }
+  
+  target.project.dependencies {
+    signature 'net.sf.androidscents.signature:android-api-level-15:4.0.3_r5@signature'
+    signature 'org.codehaus.mojo.signature:java17:1.0@signature'
+  }
+}
diff --git a/okio/src/appleMain/kotlin/okio/ByteString.kt b/okio/src/appleMain/kotlin/okio/ByteString.kt
new file mode 100644
index 0000000..eb14103
--- /dev/null
+++ b/okio/src/appleMain/kotlin/okio/ByteString.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 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 okio
+
+import kotlinx.cinterop.addressOf
+import kotlinx.cinterop.usePinned
+import platform.Foundation.NSData
+import platform.posix.memcpy
+
+fun NSData.toByteString(): ByteString {
+  val data = this
+  return ByteString(
+    ByteArray(data.length.toInt()).apply {
+      usePinned { pinned ->
+        memcpy(pinned.addressOf(0), data.bytes, data.length)
+      }
+    }
+  )
+}
diff --git a/okio/src/appleTest/kotlin/okio/AppleByteStringTest.kt b/okio/src/appleTest/kotlin/okio/AppleByteStringTest.kt
new file mode 100644
index 0000000..5ff03b2
--- /dev/null
+++ b/okio/src/appleTest/kotlin/okio/AppleByteStringTest.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2020 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 okio
+
+import platform.Foundation.NSData
+import platform.Foundation.NSString
+import platform.Foundation.NSUTF8StringEncoding
+import platform.Foundation.dataUsingEncoding
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+class AppleByteStringTest {
+  @Test fun nsDataToByteString() {
+    val data = ("Hello" as NSString).dataUsingEncoding(NSUTF8StringEncoding) as NSData
+    val byteString = data.toByteString()
+    assertEquals("Hello", byteString.utf8())
+  }
+}
diff --git a/okio/src/commonMain/kotlin/okio/-Base64.kt b/okio/src/commonMain/kotlin/okio/-Base64.kt
new file mode 100644
index 0000000..98db0b5
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/-Base64.kt
@@ -0,0 +1,148 @@
+/*
+ *  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.
+ */
+
+@file:JvmName("-Base64")
+package okio
+
+import okio.ByteString.Companion.encodeUtf8
+import kotlin.jvm.JvmName
+
+/** @author Alexander Y. Kleymenov */
+
+internal val BASE64 =
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".encodeUtf8().data
+internal val BASE64_URL_SAFE =
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".encodeUtf8().data
+
+internal fun String.decodeBase64ToArray(): ByteArray? {
+  // Ignore trailing '=' padding and whitespace from the input.
+  var limit = length
+  while (limit > 0) {
+    val c = this[limit - 1]
+    if (c != '=' && c != '\n' && c != '\r' && c != ' ' && c != '\t') {
+      break
+    }
+    limit--
+  }
+
+  // If the input includes whitespace, this output array will be longer than necessary.
+  val out = ByteArray((limit * 6L / 8L).toInt())
+  var outCount = 0
+  var inCount = 0
+
+  var word = 0
+  for (pos in 0 until limit) {
+    val c = this[pos]
+
+    val bits: Int
+    if (c in 'A'..'Z') {
+      // char ASCII value
+      //  A    65    0
+      //  Z    90    25 (ASCII - 65)
+      bits = c.toInt() - 65
+    } else if (c in 'a'..'z') {
+      // char ASCII value
+      //  a    97    26
+      //  z    122   51 (ASCII - 71)
+      bits = c.toInt() - 71
+    } else if (c in '0'..'9') {
+      // char ASCII value
+      //  0    48    52
+      //  9    57    61 (ASCII + 4)
+      bits = c.toInt() + 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 shl 6 or bits
+
+    // For every 4 chars of input, we accumulate 24 bits of output. Emit 3 bytes.
+    inCount++
+    if (inCount % 4 == 0) {
+      out[outCount++] = (word shr 16).toByte()
+      out[outCount++] = (word shr 8).toByte()
+      out[outCount++] = word.toByte()
+    }
+  }
+
+  val lastWordChars = inCount % 4
+  when (lastWordChars) {
+    1 -> {
+      // We read 1 char followed by "===". But 6 bits is a truncated byte! Fail.
+      return null
+    }
+    2 -> {
+      // We read 2 chars followed by "==". Emit 1 byte with 8 of those 12 bits.
+      word = word shl 12
+      out[outCount++] = (word shr 16).toByte()
+    }
+    3 -> {
+      // We read 3 chars, followed by "=". Emit 2 bytes for 16 of those 18 bits.
+      word = word shl 6
+      out[outCount++] = (word shr 16).toByte()
+      out[outCount++] = (word shr 8).toByte()
+    }
+  }
+
+  // If we sized our out array perfectly, we're done.
+  if (outCount == out.size) return out
+
+  // Copy the decoded bytes to a new, right-sized array.
+  return out.copyOf(outCount)
+}
+
+internal fun ByteArray.encodeBase64(map: ByteArray = BASE64): String {
+  val length = (size + 2) / 3 * 4
+  val out = ByteArray(length)
+  var index = 0
+  val end = size - size % 3
+  var i = 0
+  while (i < end) {
+    val b0 = this[i++].toInt()
+    val b1 = this[i++].toInt()
+    val b2 = this[i++].toInt()
+    out[index++] = map[(b0 and 0xff shr 2)]
+    out[index++] = map[(b0 and 0x03 shl 4) or (b1 and 0xff shr 4)]
+    out[index++] = map[(b1 and 0x0f shl 2) or (b2 and 0xff shr 6)]
+    out[index++] = map[(b2 and 0x3f)]
+  }
+  when (size - end) {
+    1 -> {
+      val b0 = this[i].toInt()
+      out[index++] = map[b0 and 0xff shr 2]
+      out[index++] = map[b0 and 0x03 shl 4]
+      out[index++] = '='.toByte()
+      out[index] = '='.toByte()
+    }
+    2 -> {
+      val b0 = this[i++].toInt()
+      val b1 = this[i].toInt()
+      out[index++] = map[(b0 and 0xff shr 2)]
+      out[index++] = map[(b0 and 0x03 shl 4) or (b1 and 0xff shr 4)]
+      out[index++] = map[(b1 and 0x0f shl 2)]
+      out[index] = '='.toByte()
+    }
+  }
+  return out.toUtf8String()
+}
diff --git a/okio/src/commonMain/kotlin/okio/-Platform.kt b/okio/src/commonMain/kotlin/okio/-Platform.kt
new file mode 100644
index 0000000..4790d3c
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/-Platform.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+internal expect fun ByteArray.toUtf8String(): String
+
+internal expect fun String.asUtf8ToByteArray(): ByteArray
+
+// TODO make internal https://youtrack.jetbrains.com/issue/KT-37316
+expect class ArrayIndexOutOfBoundsException(message: String?) : IndexOutOfBoundsException
+
+internal expect inline fun <R> synchronized(lock: Any, block: () -> R): R
+
+expect open class IOException(message: String?, cause: Throwable?) : Exception {
+  constructor(message: String? = null)
+}
+
+expect open class EOFException(message: String? = null) : IOException
+
+expect class FileNotFoundException(message: String? = null) : IOException
+
+expect interface Closeable {
+  /**
+   * Closes this object and releases the resources it holds. It is an error to use an object after
+   * it has been closed. It is safe to close an object more than once.
+   */
+  @Throws(IOException::class)
+  fun close()
+}
diff --git a/okio/src/commonMain/kotlin/okio/-Util.kt b/okio/src/commonMain/kotlin/okio/-Util.kt
new file mode 100644
index 0000000..9ab3688
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/-Util.kt
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+@file:JvmName("-Util")
+
+package okio
+
+import okio.internal.HEX_DIGIT_CHARS
+import kotlin.jvm.JvmName
+
+internal fun checkOffsetAndCount(size: Long, offset: Long, byteCount: Long) {
+  if (offset or byteCount < 0 || offset > size || size - offset < byteCount) {
+    throw ArrayIndexOutOfBoundsException("size=$size offset=$offset byteCount=$byteCount")
+  }
+}
+
+/* ktlint-disable no-multi-spaces indent */
+
+internal fun Short.reverseBytes(): Short {
+  val i = toInt() and 0xffff
+  val reversed = (i and 0xff00 ushr 8) or
+    (i and 0x00ff  shl 8)
+  return reversed.toShort()
+}
+
+internal fun Int.reverseBytes(): Int {
+  return (this and -0x1000000 ushr 24) or
+    (this and 0x00ff0000 ushr  8) or
+    (this and 0x0000ff00  shl  8) or
+    (this and 0x000000ff  shl 24)
+}
+
+internal fun Long.reverseBytes(): Long {
+  return (this and -0x100000000000000L ushr 56) or
+    (this and 0x00ff000000000000L ushr 40) or
+    (this and 0x0000ff0000000000L ushr 24) or
+    (this and 0x000000ff00000000L ushr  8) or
+    (this and 0x00000000ff000000L  shl  8) or
+    (this and 0x0000000000ff0000L  shl 24) or
+    (this and 0x000000000000ff00L  shl 40) or
+    (this and 0x00000000000000ffL  shl 56)
+}
+
+/* ktlint-enable no-multi-spaces indent */
+
+internal inline infix fun Int.leftRotate(bitCount: Int): Int {
+  return (this shl bitCount) or (this ushr (32 - bitCount))
+}
+
+internal inline infix fun Long.rightRotate(bitCount: Int): Long {
+  return (this ushr bitCount) or (this shl (64 - bitCount))
+}
+
+@Suppress("NOTHING_TO_INLINE") // Syntactic sugar.
+internal inline infix fun Byte.shr(other: Int): Int = toInt() shr other
+
+@Suppress("NOTHING_TO_INLINE") // Syntactic sugar.
+internal inline infix fun Byte.shl(other: Int): Int = toInt() shl other
+
+@Suppress("NOTHING_TO_INLINE") // Syntactic sugar.
+internal inline infix fun Byte.and(other: Int): Int = toInt() and other
+
+@Suppress("NOTHING_TO_INLINE") // Syntactic sugar.
+internal inline infix fun Byte.and(other: Long): Long = toLong() and other
+
+@Suppress("NOTHING_TO_INLINE") // Pending `kotlin.experimental.xor` becoming stable
+internal inline infix fun Byte.xor(other: Byte): Byte = (toInt() xor other.toInt()).toByte()
+
+@Suppress("NOTHING_TO_INLINE") // Syntactic sugar.
+internal inline infix fun Int.and(other: Long): Long = toLong() and other
+
+@Suppress("NOTHING_TO_INLINE") // Syntactic sugar.
+internal inline fun minOf(a: Long, b: Int): Long = minOf(a, b.toLong())
+
+@Suppress("NOTHING_TO_INLINE") // Syntactic sugar.
+internal inline fun minOf(a: Int, b: Long): Long = minOf(a.toLong(), b)
+
+internal fun arrayRangeEquals(
+  a: ByteArray,
+  aOffset: Int,
+  b: ByteArray,
+  bOffset: Int,
+  byteCount: Int
+): Boolean {
+  for (i in 0 until byteCount) {
+    if (a[i + aOffset] != b[i + bOffset]) return false
+  }
+  return true
+}
+
+internal fun Byte.toHexString(): String {
+  val result = CharArray(2)
+  result[0] = HEX_DIGIT_CHARS[this shr 4 and 0xf]
+  result[1] = HEX_DIGIT_CHARS[this       and 0xf] // ktlint-disable no-multi-spaces
+  return String(result)
+}
+
+internal fun Int.toHexString(): String {
+  if (this == 0) return "0" // Required as code below does not handle 0
+
+  val result = CharArray(8)
+  result[0] = HEX_DIGIT_CHARS[this shr 28 and 0xf]
+  result[1] = HEX_DIGIT_CHARS[this shr 24 and 0xf]
+  result[2] = HEX_DIGIT_CHARS[this shr 20 and 0xf]
+  result[3] = HEX_DIGIT_CHARS[this shr 16 and 0xf]
+  result[4] = HEX_DIGIT_CHARS[this shr 12 and 0xf]
+  result[5] = HEX_DIGIT_CHARS[this shr 8  and 0xf] // ktlint-disable no-multi-spaces
+  result[6] = HEX_DIGIT_CHARS[this shr 4  and 0xf] // ktlint-disable no-multi-spaces
+  result[7] = HEX_DIGIT_CHARS[this        and 0xf] // ktlint-disable no-multi-spaces
+
+  // Find the first non-zero index
+  var i = 0
+  while (i < result.size) {
+    if (result[i] != '0') break
+    i++
+  }
+
+  return String(result, i, result.size - i)
+}
+
+internal fun Long.toHexString(): String {
+  if (this == 0L) return "0" // Required as code below does not handle 0
+
+  val result = CharArray(16)
+  result[ 0] = HEX_DIGIT_CHARS[(this shr 60 and 0xf).toInt()] // ktlint-disable no-multi-spaces
+  result[ 1] = HEX_DIGIT_CHARS[(this shr 56 and 0xf).toInt()] // ktlint-disable no-multi-spaces
+  result[ 2] = HEX_DIGIT_CHARS[(this shr 52 and 0xf).toInt()] // ktlint-disable no-multi-spaces
+  result[ 3] = HEX_DIGIT_CHARS[(this shr 48 and 0xf).toInt()] // ktlint-disable no-multi-spaces
+  result[ 4] = HEX_DIGIT_CHARS[(this shr 44 and 0xf).toInt()] // ktlint-disable no-multi-spaces
+  result[ 5] = HEX_DIGIT_CHARS[(this shr 40 and 0xf).toInt()] // ktlint-disable no-multi-spaces
+  result[ 6] = HEX_DIGIT_CHARS[(this shr 36 and 0xf).toInt()] // ktlint-disable no-multi-spaces
+  result[ 7] = HEX_DIGIT_CHARS[(this shr 32 and 0xf).toInt()] // ktlint-disable no-multi-spaces
+  result[ 8] = HEX_DIGIT_CHARS[(this shr 28 and 0xf).toInt()] // ktlint-disable no-multi-spaces
+  result[ 9] = HEX_DIGIT_CHARS[(this shr 24 and 0xf).toInt()] // ktlint-disable no-multi-spaces
+  result[10] = HEX_DIGIT_CHARS[(this shr 20 and 0xf).toInt()]
+  result[11] = HEX_DIGIT_CHARS[(this shr 16 and 0xf).toInt()]
+  result[12] = HEX_DIGIT_CHARS[(this shr 12 and 0xf).toInt()]
+  result[13] = HEX_DIGIT_CHARS[(this shr 8  and 0xf).toInt()] // ktlint-disable no-multi-spaces
+  result[14] = HEX_DIGIT_CHARS[(this shr 4  and 0xf).toInt()] // ktlint-disable no-multi-spaces
+  result[15] = HEX_DIGIT_CHARS[(this        and 0xf).toInt()] // ktlint-disable no-multi-spaces
+
+  // Find the first non-zero index
+  var i = 0
+  while (i < result.size) {
+    if (result[i] != '0') break
+    i++
+  }
+
+  return String(result, i, result.size - i)
+}
diff --git a/okio/src/commonMain/kotlin/okio/Buffer.kt b/okio/src/commonMain/kotlin/okio/Buffer.kt
new file mode 100644
index 0000000..16394d2
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/Buffer.kt
@@ -0,0 +1,408 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+import kotlin.jvm.JvmField
+
+/**
+ * A collection of bytes in memory.
+ *
+ * **Moving data from one buffer to another is fast.** Instead of copying bytes from one place in
+ * memory to another, this class just changes ownership of the underlying byte arrays.
+ *
+ * **This buffer grows with your data.** Just like ArrayList, each buffer starts small. It consumes
+ * only the memory it needs to.
+ *
+ * **This buffer pools its byte arrays.** 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.
+ */
+expect class Buffer() : BufferedSource, BufferedSink {
+  internal var head: Segment?
+
+  var size: Long
+    internal set
+
+  override val buffer: Buffer
+
+  override fun emitCompleteSegments(): Buffer
+
+  override fun emit(): Buffer
+
+  /** Copy `byteCount` bytes from this, starting at `offset`, to `out`.  */
+  fun copyTo(
+    out: Buffer,
+    offset: Long = 0L,
+    byteCount: Long
+  ): Buffer
+
+  /**
+   * Overload of [copyTo] with byteCount = size - offset, work around for
+   *  https://youtrack.jetbrains.com/issue/KT-30847
+   */
+  fun copyTo(
+    out: Buffer,
+    offset: Long = 0L
+  ): Buffer
+
+  /**
+   * 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.
+   */
+  fun completeSegmentByteCount(): Long
+
+  /** Returns the byte at `pos`. */
+  operator fun get(pos: Long): Byte
+
+  /**
+   * Discards all bytes in this buffer. Calling this method when you're done with a buffer will
+   * return its segments to the pool.
+   */
+  fun clear()
+
+  /** Discards `byteCount` bytes from the head of this buffer.  */
+  override fun skip(byteCount: Long)
+
+  override fun write(byteString: ByteString): Buffer
+
+  override fun write(byteString: ByteString, offset: Int, byteCount: Int): Buffer
+
+  override fun writeUtf8(string: String): Buffer
+
+  override fun writeUtf8(string: String, beginIndex: Int, endIndex: Int): Buffer
+
+  override fun writeUtf8CodePoint(codePoint: Int): Buffer
+
+  override fun write(source: ByteArray): Buffer
+
+  /**
+   * Returns a tail segment that we can write at least `minimumCapacity`
+   * bytes to, creating it if necessary.
+   */
+  internal fun writableSegment(minimumCapacity: Int): Segment
+
+  fun md5(): ByteString
+
+  fun sha1(): ByteString
+
+  fun sha256(): ByteString
+
+  fun sha512(): ByteString
+
+  /** Returns the 160-bit SHA-1 HMAC of this buffer.  */
+  fun hmacSha1(key: ByteString): ByteString
+
+  /** Returns the 256-bit SHA-256 HMAC of this buffer.  */
+  fun hmacSha256(key: ByteString): ByteString
+
+  /** Returns the 512-bit SHA-512 HMAC of this buffer.  */
+  fun hmacSha512(key: ByteString): ByteString
+
+  override fun write(source: ByteArray, offset: Int, byteCount: Int): Buffer
+
+  override fun write(source: Source, byteCount: Long): Buffer
+
+  override fun writeByte(b: Int): Buffer
+
+  override fun writeShort(s: Int): Buffer
+
+  override fun writeShortLe(s: Int): Buffer
+
+  override fun writeInt(i: Int): Buffer
+
+  override fun writeIntLe(i: Int): Buffer
+
+  override fun writeLong(v: Long): Buffer
+
+  override fun writeLongLe(v: Long): Buffer
+
+  override fun writeDecimalLong(v: Long): Buffer
+
+  override fun writeHexadecimalUnsignedLong(v: Long): Buffer
+
+  /** Returns a deep copy of this buffer.  */
+  fun copy(): Buffer
+
+  /** Returns an immutable copy of this buffer as a byte string.  */
+  fun snapshot(): ByteString
+
+  /** Returns an immutable copy of the first `byteCount` bytes of this buffer as a byte string. */
+  fun snapshot(byteCount: Int): ByteString
+
+  fun readUnsafe(unsafeCursor: UnsafeCursor = UnsafeCursor()): UnsafeCursor
+
+  fun readAndWriteUnsafe(unsafeCursor: UnsafeCursor = UnsafeCursor()): UnsafeCursor
+
+  /**
+   * A handle to the underlying data in a buffer. This handle is unsafe because it does not enforce
+   * its own invariants. Instead, it assumes a careful user who has studied Okio's implementation
+   * details and their consequences.
+   *
+   * Buffer Internals
+   * ----------------
+   *
+   * Most code should use `Buffer` as a black box: a class that holds 0 or more bytes of
+   * data with efficient APIs to append data to the end and to consume data from the front. Usually
+   * this is also the most efficient way to use buffers because it allows Okio to employ several
+   * optimizations, including:
+   *
+   *  * **Fast Allocation:** Buffers use a shared pool of memory that is not zero-filled before use.
+   *  * **Fast Resize:** A buffer's capacity can change without copying its contents.
+   *  * **Fast Move:** Memory ownership can be reassigned from one buffer to another.
+   *  * **Fast Copy:** Multiple buffers can share the same underlying memory.
+   *  * **Fast Encoding and Decoding:** Common operations like UTF-8 encoding and decimal decoding
+   *    do not require intermediate objects to be allocated.
+   *
+   * These optimizations all leverage the way Okio stores data internally. Okio Buffers are
+   * implemented using a doubly-linked list of segments. Each segment is a contiguous range within a
+   * 8 KiB `ByteArray`. Each segment has two indexes, `start`, the offset of the first byte of the
+   * array containing application data, and `end`, the offset of the first byte beyond `start` whose
+   * data is undefined.
+   *
+   * New buffers are empty and have no segments:
+   *
+   * ```
+   *   val buffer = Buffer()
+   * ```
+   *
+   * We append 7 bytes of data to the end of our empty buffer. Internally, the buffer allocates a
+   * segment and writes its new data there. The lone segment has an 8 KiB byte array but only 7
+   * bytes of data:
+   *
+   * ```
+   * buffer.writeUtf8("sealion")
+   *
+   * // [ 's', 'e', 'a', 'l', 'i', 'o', 'n', '?', '?', '?', ...]
+   * //    ^                                  ^
+   * // start = 0                          end = 7
+   * ```
+   *
+   * When we read 4 bytes of data from the buffer, it finds its first segment and returns that data
+   * to us. As bytes are read the data is consumed. The segment tracks this by adjusting its
+   * internal indices.
+   *
+   * ```
+   * buffer.readUtf8(4) // "seal"
+   *
+   * // [ 's', 'e', 'a', 'l', 'i', 'o', 'n', '?', '?', '?', ...]
+   * //                        ^              ^
+   * //                     start = 4      end = 7
+   * ```
+   *
+   * As we write data into a buffer we fill up its internal segments. When a write doesn't fit into
+   * a buffer's last segment, additional segments are allocated and appended to the linked list of
+   * segments. Each segment has its own start and end indexes tracking where the user's data begins
+   * and ends.
+   *
+   * ```
+   * val xoxo = new Buffer()
+   * xoxo.writeUtf8("xo".repeat(5_000))
+   *
+   * // [ 'x', 'o', 'x', 'o', 'x', 'o', 'x', 'o', ..., 'x', 'o', 'x', 'o']
+   * //    ^                                                               ^
+   * // start = 0                                                      end = 8192
+   * //
+   * // [ 'x', 'o', 'x', 'o', ..., 'x', 'o', 'x', 'o', '?', '?', '?', ...]
+   * //    ^                                            ^
+   * // start = 0                                   end = 1808
+   * ```
+   *
+   * The start index is always **inclusive** and the end index is always **exclusive**. The data
+   * preceding the start index is undefined, and the data at and following the end index is
+   * undefined.
+   *
+   * After the last byte of a segment has been read, that segment may be returned to an internal
+   * segment pool. In addition to reducing the need to do garbage collection, segment pooling also
+   * saves the JVM from needing to zero-fill byte arrays. Okio doesn't need to zero-fill its arrays
+   * because it always writes memory before it reads it. But if you look at a segment in a debugger
+   * you may see its effects. In this example, one of the "xoxo" segments above is reused in an
+   * unrelated buffer:
+   *
+   * ```
+   * val abc = new Buffer()
+   * abc.writeUtf8("abc")
+   *
+   * // [ 'a', 'b', 'c', 'o', 'x', 'o', 'x', 'o', ...]
+   * //    ^              ^
+   * // start = 0     end = 3
+   * ```
+   *
+   * There is an optimization in `Buffer.clone()` and other methods that allows two segments to
+   * share the same underlying byte array. Clones can't write to the shared byte array; instead they
+   * allocate a new (private) segment early.
+   *
+   * ```
+   * val nana = new Buffer()
+   * nana.writeUtf8("na".repeat(2_500))
+   * nana.readUtf8(2) // "na"
+   *
+   * // [ 'n', 'a', 'n', 'a', ..., 'n', 'a', 'n', 'a', '?', '?', '?', ...]
+   * //              ^                                  ^
+   * //           start = 2                         end = 5000
+   *
+   * nana2 = nana.clone()
+   * nana2.writeUtf8("batman")
+   *
+   * // [ 'n', 'a', 'n', 'a', ..., 'n', 'a', 'n', 'a', '?', '?', '?', ...]
+   * //              ^                                  ^
+   * //           start = 2                         end = 5000
+   * //
+   * // [ 'b', 'a', 't', 'm', 'a', 'n', '?', '?', '?', ...]
+   * //    ^                             ^
+   * //  start = 0                    end = 6
+   * ```
+   *
+   * Segments are not shared when the shared region is small (ie. less than 1 KiB). This is intended
+   * to prevent fragmentation in sharing-heavy use cases.
+   *
+   * Unsafe Cursor API
+   * -----------------
+   *
+   * This class exposes privileged access to the internal byte arrays of a buffer. A cursor either
+   * references the data of a single segment, it is before the first segment (`offset == -1`), or it
+   * is after the last segment (`offset == buffer.size`).
+   *
+   * Call [UnsafeCursor.seek] to move the cursor to the segment that contains a specified offset.
+   * After seeking, [UnsafeCursor.data] references the segment's internal byte array,
+   * [UnsafeCursor.start] is the segment's start and [UnsafeCursor.end] is its end.
+   *
+   * Call [UnsafeCursor.next] to advance the cursor to the next segment. This returns -1 if there
+   * are no further segments in the buffer.
+   *
+   * Use [Buffer.readUnsafe] to create a cursor to read buffer data and [Buffer.readAndWriteUnsafe]
+   * to create a cursor to read and write buffer data. In either case, always call
+   * [UnsafeCursor.close] when done with a cursor. This is convenient with Kotlin's
+   * [use] extension function. In this example we read all of the bytes in a buffer into a byte
+   * array:
+   *
+   * ```
+   * val bufferBytes = ByteArray(buffer.size.toInt())
+   *
+   * buffer.readUnsafe().use { cursor ->
+   *   while (cursor.next() != -1) {
+   *     System.arraycopy(cursor.data, cursor.start,
+   *         bufferBytes, cursor.offset.toInt(), cursor.end - cursor.start);
+   *   }
+   * }
+   * ```
+   *
+   * Change the capacity of a buffer with [resizeBuffer]. This is only permitted for read+write
+   * cursors. The buffer's size always changes from the end: shrinking it removes bytes from the
+   * end; growing it adds capacity to the end.
+   *
+   * Warnings
+   * --------
+   *
+   * Most application developers should avoid this API. Those that must use this API should
+   * respect these warnings.
+   *
+   * **Don't mutate a cursor.** This class has public, non-final fields because that is convenient
+   * for low-level I/O frameworks. Never assign values to these fields; instead use the cursor API
+   * to adjust these.
+   *
+   * **Never mutate `data` unless you have read+write access.** You are on the honor system to never
+   * write the buffer in read-only mode. Read-only mode may be more efficient than read+write mode
+   * because it does not need to make private copies of shared segments.
+   *
+   * **Only access data in `[start..end)`.** Other data in the byte array is undefined! It may
+   * contain private or sensitive data from other parts of your process.
+   *
+   * **Always fill the new capacity when you grow a buffer.** New capacity is not zero-filled and
+   * may contain data from other parts of your process. Avoid leaking this information by always
+   * writing something to the newly-allocated capacity. Do not assume that new capacity will be
+   * filled with `0`; it will not be.
+   *
+   * **Do not access a buffer while is being accessed by a cursor.** Even simple read-only
+   * operations like [Buffer.clone] are unsafe because they mark segments as shared.
+   *
+   * **Do not hard-code the segment size in your application.** It is possible that segment sizes
+   * will change with advances in hardware. Future versions of Okio may even have heterogeneous
+   * segment sizes.
+   *
+   * These warnings are intended to help you to use this API safely. It's here for developers
+   * that need absolutely the most throughput. Since that's you, here's one final performance tip.
+   * You can reuse instances of this class if you like. Use the overloads of [Buffer.readUnsafe] and
+   * [Buffer.readAndWriteUnsafe] that take a cursor and close it after use.
+   */
+  class UnsafeCursor constructor() {
+    @JvmField var buffer: Buffer?
+    @JvmField var readWrite: Boolean
+
+    internal var segment: Segment?
+    @JvmField var offset: Long
+    @JvmField var data: ByteArray?
+    @JvmField var start: Int
+    @JvmField var end: Int
+
+    /**
+     * Seeks to the next range of bytes, advancing the offset by `end - start`. Returns the size of
+     * the readable range (at least 1), or -1 if we have reached the end of the buffer and there are
+     * no more bytes to read.
+     */
+    fun next(): Int
+
+    /**
+     * Reposition the cursor so that the data at [offset] is readable at `data[start]`.
+     * Returns the number of bytes readable in [data] (at least 1), or -1 if there are no data
+     * to read.
+     */
+    fun seek(offset: Long): Int
+
+    /**
+     * Change the size of the buffer so that it equals [newSize] by either adding new capacity at
+     * the end or truncating the buffer at the end. Newly added capacity may span multiple segments.
+     *
+     * As a side-effect this cursor will [seek][UnsafeCursor.seek]. If the buffer is being enlarged
+     * it will move [UnsafeCursor.offset] to the first byte of newly-added capacity. This is the
+     * size of the buffer prior to the `resizeBuffer()` call. If the buffer is being shrunk it will move
+     * [UnsafeCursor.offset] to the end of the buffer.
+     *
+     * Warning: it is the caller’s responsibility to write new data to every byte of the
+     * newly-allocated capacity. Failure to do so may cause serious security problems as the data
+     * in the returned buffers is not zero filled. Buffers may contain dirty pooled segments that
+     * hold very sensitive data from other parts of the current process.
+     *
+     * @return the previous size of the buffer.
+     */
+    fun resizeBuffer(newSize: Long): Long
+
+    /**
+     * Grow the buffer by adding a **contiguous range** of capacity in a single segment. This adds
+     * at least [minByteCount] bytes but may add up to a full segment of additional capacity.
+     *
+     * As a side-effect this cursor will [seek][UnsafeCursor.seek]. It will move
+     * [offset][UnsafeCursor.offset] to the first byte of newly-added capacity. This is the size of
+     * the buffer prior to the `expandBuffer()` call.
+     *
+     * If [minByteCount] bytes are available in the buffer's current tail segment that will be used;
+     * otherwise another segment will be allocated and appended. In either case this returns the
+     * number of bytes of capacity added to this buffer.
+     *
+     * Warning: it is the caller’s responsibility to either write new data to every byte of the
+     * newly-allocated capacity, or to [shrink][UnsafeCursor.resizeBuffer] the buffer to the data
+     * written. Failure to do so may cause serious security problems as the data in the returned
+     * buffers is not zero filled. Buffers may contain dirty pooled segments that hold very
+     * sensitive data from other parts of the current process.
+     *
+     * @param minByteCount the size of the contiguous capacity. Must be positive and not greater
+     *     than the capacity size of a single segment (8 KiB).
+     * @return the number of bytes expanded by. Not less than `minByteCount`.
+     */
+    fun expandBuffer(minByteCount: Int): Long
+
+    fun close()
+  }
+}
diff --git a/okio/src/commonMain/kotlin/okio/BufferedSink.kt b/okio/src/commonMain/kotlin/okio/BufferedSink.kt
new file mode 100644
index 0000000..40c2658
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/BufferedSink.kt
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+/**
+ * A sink that keeps a buffer internally so that callers can do small writes without a performance
+ * penalty.
+ */
+expect interface BufferedSink : Sink {
+  /** This sink's internal buffer. */
+  val buffer: Buffer
+
+  fun write(byteString: ByteString): BufferedSink
+
+  fun write(byteString: ByteString, offset: Int, byteCount: Int): BufferedSink
+
+  /** Like [OutputStream.write], this writes a complete byte array to this sink. */
+  fun write(source: ByteArray): BufferedSink
+
+  /** Like [OutputStream.write], this writes `byteCount` bytes of `source`, starting at `offset`. */
+  fun write(source: ByteArray, offset: Int, byteCount: Int): BufferedSink
+
+  /**
+   * Removes all bytes from `source` and appends them to this sink. Returns the number of bytes read
+   * which will be 0 if `source` is exhausted.
+   */
+  fun writeAll(source: Source): Long
+
+  /** Removes `byteCount` bytes from `source` and appends them to this sink. */
+  fun write(source: Source, byteCount: Long): BufferedSink
+
+  /**
+   * Encodes `string` in UTF-8 and writes it to this sink.
+   * ```
+   * Buffer buffer = new Buffer();
+   * buffer.writeUtf8("Uh uh uh!");
+   * buffer.writeByte(' ');
+   * buffer.writeUtf8("You didn't say the magic word!");
+   *
+   * assertEquals("Uh uh uh! You didn't say the magic word!", buffer.readUtf8());
+   * ```
+   */
+  fun writeUtf8(string: String): BufferedSink
+
+  /**
+   * Encodes the characters at `beginIndex` up to `endIndex` from `string` in UTF-8 and writes it to
+   * this sink.
+   * ```
+   * Buffer buffer = new Buffer();
+   * buffer.writeUtf8("I'm a hacker!\n", 6, 12);
+   * buffer.writeByte(' ');
+   * buffer.writeUtf8("That's what I said: you're a nerd.\n", 29, 33);
+   * buffer.writeByte(' ');
+   * buffer.writeUtf8("I prefer to be called a hacker!\n", 24, 31);
+   *
+   * assertEquals("hacker nerd hacker!", buffer.readUtf8());
+   * ```
+   */
+  fun writeUtf8(string: String, beginIndex: Int, endIndex: Int): BufferedSink
+
+  /** Encodes `codePoint` in UTF-8 and writes it to this sink. */
+  fun writeUtf8CodePoint(codePoint: Int): BufferedSink
+
+  /** Writes a byte to this sink. */
+  fun writeByte(b: Int): BufferedSink
+
+  /**
+   * Writes a big-endian short to this sink using two bytes.
+   * ```
+   * Buffer buffer = new Buffer();
+   * buffer.writeShort(32767);
+   * buffer.writeShort(15);
+   *
+   * assertEquals(4, buffer.size());
+   * assertEquals((byte) 0x7f, buffer.readByte());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals((byte) 0x0f, buffer.readByte());
+   * assertEquals(0, buffer.size());
+   * ```
+   */
+  fun writeShort(s: Int): BufferedSink
+
+  /**
+   * Writes a little-endian short to this sink using two bytes.
+   * ```
+   * Buffer buffer = new Buffer();
+   * buffer.writeShortLe(32767);
+   * buffer.writeShortLe(15);
+   *
+   * assertEquals(4, buffer.size());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0x7f, buffer.readByte());
+   * assertEquals((byte) 0x0f, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals(0, buffer.size());
+   * ```
+   */
+  fun writeShortLe(s: Int): BufferedSink
+
+  /**
+   * Writes a big-endian int to this sink using four bytes.
+   * ```
+   * Buffer buffer = new Buffer();
+   * buffer.writeInt(2147483647);
+   * buffer.writeInt(15);
+   *
+   * assertEquals(8, buffer.size());
+   * assertEquals((byte) 0x7f, buffer.readByte());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals((byte) 0x0f, buffer.readByte());
+   * assertEquals(0, buffer.size());
+   * ```
+   */
+  fun writeInt(i: Int): BufferedSink
+
+  /**
+   * Writes a little-endian int to this sink using four bytes.
+   * ```
+   * Buffer buffer = new Buffer();
+   * buffer.writeIntLe(2147483647);
+   * buffer.writeIntLe(15);
+   *
+   * assertEquals(8, buffer.size());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0x7f, buffer.readByte());
+   * assertEquals((byte) 0x0f, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals(0, buffer.size());
+   * ```
+   */
+  fun writeIntLe(i: Int): BufferedSink
+
+  /**
+   * Writes a big-endian long to this sink using eight bytes.
+   * ```
+   * Buffer buffer = new Buffer();
+   * buffer.writeLong(9223372036854775807L);
+   * buffer.writeLong(15);
+   *
+   * assertEquals(16, buffer.size());
+   * assertEquals((byte) 0x7f, buffer.readByte());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals((byte) 0x0f, buffer.readByte());
+   * assertEquals(0, buffer.size());
+   * ```
+   */
+  fun writeLong(v: Long): BufferedSink
+
+  /**
+   * Writes a little-endian long to this sink using eight bytes.
+   * ```
+   * Buffer buffer = new Buffer();
+   * buffer.writeLongLe(9223372036854775807L);
+   * buffer.writeLongLe(15);
+   *
+   * assertEquals(16, buffer.size());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0xff, buffer.readByte());
+   * assertEquals((byte) 0x7f, buffer.readByte());
+   * assertEquals((byte) 0x0f, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals((byte) 0x00, buffer.readByte());
+   * assertEquals(0, buffer.size());
+   * ```
+   */
+  fun writeLongLe(v: Long): BufferedSink
+
+  /**
+   * Writes a long to this sink in signed decimal form (i.e., as a string in base 10).
+   * ```
+   * Buffer buffer = new Buffer();
+   * buffer.writeDecimalLong(8675309L);
+   * buffer.writeByte(' ');
+   * buffer.writeDecimalLong(-123L);
+   * buffer.writeByte(' ');
+   * buffer.writeDecimalLong(1L);
+   *
+   * assertEquals("8675309 -123 1", buffer.readUtf8());
+   * ```
+   */
+  fun writeDecimalLong(v: Long): BufferedSink
+
+  /**
+   * Writes a long to this sink in hexadecimal form (i.e., as a string in base 16).
+   * ```
+   * Buffer buffer = new Buffer();
+   * buffer.writeHexadecimalUnsignedLong(65535L);
+   * buffer.writeByte(' ');
+   * buffer.writeHexadecimalUnsignedLong(0xcafebabeL);
+   * buffer.writeByte(' ');
+   * buffer.writeHexadecimalUnsignedLong(0x10L);
+   *
+   * assertEquals("ffff cafebabe 10", buffer.readUtf8());
+   * ```
+   */
+  fun writeHexadecimalUnsignedLong(v: Long): BufferedSink
+
+  /**
+   * Writes all buffered data to the underlying sink, if one exists. Then that sink is recursively
+   * flushed which pushes data as far as possible towards its ultimate destination. Typically that
+   * destination is a network socket or file.
+   * ```
+   * BufferedSink b0 = new Buffer();
+   * BufferedSink b1 = Okio.buffer(b0);
+   * BufferedSink b2 = Okio.buffer(b1);
+   *
+   * b2.writeUtf8("hello");
+   * assertEquals(5, b2.buffer().size());
+   * assertEquals(0, b1.buffer().size());
+   * assertEquals(0, b0.buffer().size());
+   *
+   * b2.flush();
+   * assertEquals(0, b2.buffer().size());
+   * assertEquals(0, b1.buffer().size());
+   * assertEquals(5, b0.buffer().size());
+   * ```
+   */
+  override fun flush()
+
+  /**
+   * Writes all buffered data to the underlying sink, if one exists. Like [flush], but weaker. Call
+   * this before this buffered sink goes out of scope so that its data can reach its destination.
+   * ```
+   * BufferedSink b0 = new Buffer();
+   * BufferedSink b1 = Okio.buffer(b0);
+   * BufferedSink b2 = Okio.buffer(b1);
+   *
+   * b2.writeUtf8("hello");
+   * assertEquals(5, b2.buffer().size());
+   * assertEquals(0, b1.buffer().size());
+   * assertEquals(0, b0.buffer().size());
+   *
+   * b2.emit();
+   * assertEquals(0, b2.buffer().size());
+   * assertEquals(5, b1.buffer().size());
+   * assertEquals(0, b0.buffer().size());
+   *
+   * b1.emit();
+   * assertEquals(0, b2.buffer().size());
+   * assertEquals(0, b1.buffer().size());
+   * assertEquals(5, b0.buffer().size());
+   * ```
+   */
+  fun emit(): BufferedSink
+
+  /**
+   * Writes complete segments to the underlying sink, if one exists. Like [flush], but weaker. Use
+   * this to limit the memory held in the buffer to a single segment. Typically application code
+   * will not need to call this: it is only necessary when application code writes directly to this
+   * [sink's buffer][buffer].
+   * ```
+   * BufferedSink b0 = new Buffer();
+   * BufferedSink b1 = Okio.buffer(b0);
+   * BufferedSink b2 = Okio.buffer(b1);
+   *
+   * b2.buffer().write(new byte[20_000]);
+   * assertEquals(20_000, b2.buffer().size());
+   * assertEquals(     0, b1.buffer().size());
+   * assertEquals(     0, b0.buffer().size());
+   *
+   * b2.emitCompleteSegments();
+   * assertEquals( 3_616, b2.buffer().size());
+   * assertEquals(     0, b1.buffer().size());
+   * assertEquals(16_384, b0.buffer().size()); // This example assumes 8192 byte segments.
+   * ```
+   */
+  fun emitCompleteSegments(): BufferedSink
+}
diff --git a/okio/src/commonMain/kotlin/okio/BufferedSource.kt b/okio/src/commonMain/kotlin/okio/BufferedSource.kt
new file mode 100644
index 0000000..0ba4d15
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/BufferedSource.kt
@@ -0,0 +1,534 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+/**
+ * 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.
+ */
+expect interface BufferedSource : Source {
+  /** This source's internal buffer. */
+  val 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.
+   */
+  fun exhausted(): Boolean
+
+  /**
+   * Returns when the buffer contains at least `byteCount` bytes. Throws an
+   * [java.io.EOFException] if the source is exhausted before the required bytes can be read.
+   */
+  fun require(byteCount: Long)
+
+  /**
+   * Returns true when the buffer contains at least `byteCount` bytes, expanding it as
+   * necessary. Returns false if the source is exhausted before the requested bytes can be read.
+   */
+  fun request(byteCount: Long): Boolean
+
+  /** Removes a byte from this source and returns it. */
+  fun readByte(): Byte
+
+  /**
+   * Removes two bytes from this source and returns a big-endian short.
+   * ```
+   * Buffer buffer = new Buffer()
+   *     .writeByte(0x7f)
+   *     .writeByte(0xff)
+   *     .writeByte(0x00)
+   *     .writeByte(0x0f);
+   * assertEquals(4, buffer.size());
+   *
+   * assertEquals(32767, buffer.readShort());
+   * assertEquals(2, buffer.size());
+   *
+   * assertEquals(15, buffer.readShort());
+   * assertEquals(0, buffer.size());
+   * ```
+   */
+  fun readShort(): Short
+
+  /**
+   * Removes two bytes from this source and returns a little-endian short.
+   * ```
+   * Buffer buffer = new Buffer()
+   *     .writeByte(0xff)
+   *     .writeByte(0x7f)
+   *     .writeByte(0x0f)
+   *     .writeByte(0x00);
+   * assertEquals(4, buffer.size());
+   *
+   * assertEquals(32767, buffer.readShortLe());
+   * assertEquals(2, buffer.size());
+   *
+   * assertEquals(15, buffer.readShortLe());
+   * assertEquals(0, buffer.size());
+   * ```
+   */
+  fun readShortLe(): Short
+
+  /**
+   * Removes four bytes from this source and returns a big-endian int.
+   * ```
+   * Buffer buffer = new Buffer()
+   *     .writeByte(0x7f)
+   *     .writeByte(0xff)
+   *     .writeByte(0xff)
+   *     .writeByte(0xff)
+   *     .writeByte(0x00)
+   *     .writeByte(0x00)
+   *     .writeByte(0x00)
+   *     .writeByte(0x0f);
+   * assertEquals(8, buffer.size());
+   *
+   * assertEquals(2147483647, buffer.readInt());
+   * assertEquals(4, buffer.size());
+   *
+   * assertEquals(15, buffer.readInt());
+   * assertEquals(0, buffer.size());
+   * ```
+   */
+  fun readInt(): Int
+
+  /**
+   * Removes four bytes from this source and returns a little-endian int.
+   * ```
+   * Buffer buffer = new Buffer()
+   *     .writeByte(0xff)
+   *     .writeByte(0xff)
+   *     .writeByte(0xff)
+   *     .writeByte(0x7f)
+   *     .writeByte(0x0f)
+   *     .writeByte(0x00)
+   *     .writeByte(0x00)
+   *     .writeByte(0x00);
+   * assertEquals(8, buffer.size());
+   *
+   * assertEquals(2147483647, buffer.readIntLe());
+   * assertEquals(4, buffer.size());
+   *
+   * assertEquals(15, buffer.readIntLe());
+   * assertEquals(0, buffer.size());
+   * ```
+   */
+  fun readIntLe(): Int
+
+  /**
+   * Removes eight bytes from this source and returns a big-endian long.
+   * ```
+   * Buffer buffer = new Buffer()
+   *     .writeByte(0x7f)
+   *     .writeByte(0xff)
+   *     .writeByte(0xff)
+   *     .writeByte(0xff)
+   *     .writeByte(0xff)
+   *     .writeByte(0xff)
+   *     .writeByte(0xff)
+   *     .writeByte(0xff)
+   *     .writeByte(0x00)
+   *     .writeByte(0x00)
+   *     .writeByte(0x00)
+   *     .writeByte(0x00)
+   *     .writeByte(0x00)
+   *     .writeByte(0x00)
+   *     .writeByte(0x00)
+   *     .writeByte(0x0f);
+   * assertEquals(16, buffer.size());
+   *
+   * assertEquals(9223372036854775807L, buffer.readLong());
+   * assertEquals(8, buffer.size());
+   *
+   * assertEquals(15, buffer.readLong());
+   * assertEquals(0, buffer.size());
+   * ```
+   */
+  fun readLong(): Long
+
+  /**
+   * Removes eight bytes from this source and returns a little-endian long.
+   * ```
+   * Buffer buffer = new Buffer()
+   *     .writeByte(0xff)
+   *     .writeByte(0xff)
+   *     .writeByte(0xff)
+   *     .writeByte(0xff)
+   *     .writeByte(0xff)
+   *     .writeByte(0xff)
+   *     .writeByte(0xff)
+   *     .writeByte(0x7f)
+   *     .writeByte(0x0f)
+   *     .writeByte(0x00)
+   *     .writeByte(0x00)
+   *     .writeByte(0x00)
+   *     .writeByte(0x00)
+   *     .writeByte(0x00)
+   *     .writeByte(0x00)
+   *     .writeByte(0x00);
+   * assertEquals(16, buffer.size());
+   *
+   * assertEquals(9223372036854775807L, buffer.readLongLe());
+   * assertEquals(8, buffer.size());
+   *
+   * assertEquals(15, buffer.readLongLe());
+   * assertEquals(0, buffer.size());
+   * ```
+   */
+  fun readLongLe(): Long
+
+  /**
+   * 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.
+   * ```
+   * Buffer buffer = new Buffer()
+   *     .writeUtf8("8675309 -123 00001");
+   *
+   * assertEquals(8675309L, buffer.readDecimalLong());
+   * assertEquals(' ', buffer.readByte());
+   * assertEquals(-123L, buffer.readDecimalLong());
+   * assertEquals(' ', buffer.readByte());
+   * assertEquals(1L, buffer.readDecimalLong());
+   * ```
+   *
+   * @throws NumberFormatException if the found digits do not fit into a `long` or a decimal
+   * number was not present.
+   */
+  fun readDecimalLong(): Long
+
+  /**
+   * 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.
+   * ```
+   * Buffer buffer = new Buffer()
+   *     .writeUtf8("ffff CAFEBABE 10");
+   *
+   * assertEquals(65535L, buffer.readHexadecimalUnsignedLong());
+   * assertEquals(' ', buffer.readByte());
+   * assertEquals(0xcafebabeL, buffer.readHexadecimalUnsignedLong());
+   * assertEquals(' ', buffer.readByte());
+   * assertEquals(0x10L, buffer.readHexadecimalUnsignedLong());
+   * ```
+   *
+   * @throws NumberFormatException if the found hexadecimal does not fit into a `long` or
+   * hexadecimal was not found.
+   */
+  fun readHexadecimalUnsignedLong(): Long
+
+  /**
+   * Reads and discards `byteCount` bytes from this source. Throws an [java.io.EOFException] if the
+   * source is exhausted before the requested bytes can be skipped.
+   */
+  fun skip(byteCount: Long)
+
+  /** Removes all bytes from this and returns them as a byte string. */
+  fun readByteString(): ByteString
+
+  /** Removes `byteCount` bytes from this and returns them as a byte string. */
+  fun readByteString(byteCount: Long): ByteString
+
+  /**
+   * Finds the first string in `options` that is a prefix of this buffer, consumes it from this
+   * buffer, and returns its index. If no byte string in `options` is a prefix of this buffer this
+   * returns -1 and no bytes are consumed.
+   *
+   * This can be used as an alternative to [readByteString] or even [readUtf8] if the set of
+   * expected values is known in advance.
+   * ```
+   * Options FIELDS = Options.of(
+   *     ByteString.encodeUtf8("depth="),
+   *     ByteString.encodeUtf8("height="),
+   *     ByteString.encodeUtf8("width="));
+   *
+   * Buffer buffer = new Buffer()
+   *     .writeUtf8("width=640\n")
+   *     .writeUtf8("height=480\n");
+   *
+   * assertEquals(2, buffer.select(FIELDS));
+   * assertEquals(640, buffer.readDecimalLong());
+   * assertEquals('\n', buffer.readByte());
+   * assertEquals(1, buffer.select(FIELDS));
+   * assertEquals(480, buffer.readDecimalLong());
+   * assertEquals('\n', buffer.readByte());
+   * ```
+   */
+  fun select(options: Options): Int
+
+  /** Removes all bytes from this and returns them as a byte array. */
+  fun readByteArray(): ByteArray
+
+  /** Removes `byteCount` bytes from this and returns them as a byte array. */
+  fun readByteArray(byteCount: Long): ByteArray
+
+  /**
+   * Removes up to `sink.length` bytes from this and copies them into `sink`. Returns the number of
+   * bytes read, or -1 if this source is exhausted.
+   */
+  fun read(sink: ByteArray): Int
+
+  /**
+   * Removes exactly `sink.length` bytes from this and copies them into `sink`. Throws an
+   * [java.io.EOFException] if the requested number of bytes cannot be read.
+   */
+  fun readFully(sink: ByteArray)
+
+  /**
+   * Removes up to `byteCount` bytes from this and copies them into `sink` at `offset`. Returns the
+   * number of bytes read, or -1 if this source is exhausted.
+   */
+  fun read(sink: ByteArray, offset: Int, byteCount: Int): Int
+
+  /**
+   * Removes exactly `byteCount` bytes from this and appends them to `sink`. Throws an
+   * [java.io.EOFException] if the requested number of bytes cannot be read.
+   */
+  fun readFully(sink: Buffer, byteCount: Long)
+
+  /**
+   * Removes all bytes from this and appends them to `sink`. Returns the total number of bytes
+   * written to `sink` which will be 0 if this is exhausted.
+   */
+  fun readAll(sink: Sink): Long
+
+  /**
+   * Removes all bytes from this, decodes them as UTF-8, and returns the string. Returns the empty
+   * string if this source is empty.
+   * ```
+   * Buffer buffer = new Buffer()
+   *     .writeUtf8("Uh uh uh!")
+   *     .writeByte(' ')
+   *     .writeUtf8("You didn't say the magic word!");
+   *
+   * assertEquals("Uh uh uh! You didn't say the magic word!", buffer.readUtf8());
+   * assertEquals(0, buffer.size());
+   *
+   * assertEquals("", buffer.readUtf8());
+   * assertEquals(0, buffer.size());
+   * ```
+   */
+  fun readUtf8(): String
+
+  /**
+   * Removes `byteCount` bytes from this, decodes them as UTF-8, and returns the string.
+   * ```
+   * Buffer buffer = new Buffer()
+   *     .writeUtf8("Uh uh uh!")
+   *     .writeByte(' ')
+   *     .writeUtf8("You didn't say the magic word!");
+   * assertEquals(40, buffer.size());
+   *
+   * assertEquals("Uh uh uh! You ", buffer.readUtf8(14));
+   * assertEquals(26, buffer.size());
+   *
+   * assertEquals("didn't say the", buffer.readUtf8(14));
+   * assertEquals(12, buffer.size());
+   *
+   * assertEquals(" magic word!", buffer.readUtf8(12));
+   * assertEquals(0, buffer.size());
+   * ```
+   */
+  fun readUtf8(byteCount: Long): String
+
+  /**
+   * Removes and returns characters up to but not including the next line break. A line break is
+   * either `"\n"` or `"\r\n"`; these characters are not included in the result.
+   * ```
+   * Buffer buffer = new Buffer()
+   *     .writeUtf8("I'm a hacker!\n")
+   *     .writeUtf8("That's what I said: you're a nerd.\n")
+   *     .writeUtf8("I prefer to be called a hacker!\n");
+   * assertEquals(81, buffer.size());
+   *
+   * assertEquals("I'm a hacker!", buffer.readUtf8Line());
+   * assertEquals(67, buffer.size());
+   *
+   * assertEquals("That's what I said: you're a nerd.", buffer.readUtf8Line());
+   * assertEquals(32, buffer.size());
+   *
+   * assertEquals("I prefer to be called a hacker!", buffer.readUtf8Line());
+   * assertEquals(0, buffer.size());
+   *
+   * assertEquals(null, buffer.readUtf8Line());
+   * assertEquals(0, buffer.size());
+   * ```
+   *
+   * **On the end of the stream this method returns null,** just like [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.
+   */
+  fun readUtf8Line(): String?
+
+  /**
+   * Removes and returns characters up to but not including the next line break. A line break is
+   * either `"\n"` or `"\r\n"`; these characters are not included in the result.
+   *
+   * **On the end of the stream this method throws.** Every call must consume either
+   * '\r\n' or '\n'. If these characters are absent in the stream, an [java.io.EOFException]
+   * is thrown. Use this for machine-generated data where a missing line break implies truncated
+   * input.
+   */
+  fun readUtf8LineStrict(): String
+
+  /**
+   * Like [readUtf8LineStrict], except this allows the caller to specify the longest allowed match.
+   * Use this to protect against streams that may not include `"\n"` or `"\r\n"`.
+   *
+   * The returned string will have at most `limit` UTF-8 bytes, and the maximum number of bytes
+   * scanned is `limit + 2`. If `limit == 0` this will always throw an `EOFException` because no
+   * bytes will be scanned.
+   *
+   * This method is safe. No bytes are discarded if the match fails, and the caller is free to try
+   * another match:
+   * ```
+   * Buffer buffer = new Buffer();
+   * buffer.writeUtf8("12345\r\n");
+   *
+   * // This will throw! There must be \r\n or \n at the limit or before it.
+   * buffer.readUtf8LineStrict(4);
+   *
+   * // No bytes have been consumed so the caller can retry.
+   * assertEquals("12345", buffer.readUtf8LineStrict(5));
+   * ```
+   */
+  fun readUtf8LineStrict(limit: Long): String
+
+  /**
+   * Removes and returns a single UTF-8 code point, reading between 1 and 4 bytes as necessary.
+   *
+   * If this source is exhausted before a complete code point can be read, this throws an
+   * [java.io.EOFException] and consumes no input.
+   *
+   * 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 (`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 `0xc080` for the NUL character in modified UTF-8).
+   */
+  fun readUtf8CodePoint(): Int
+
+  /** Equivalent to [indexOf(b, 0)][indexOf]. */
+  fun indexOf(b: Byte): Long
+
+  /**
+   * Returns the index of the first `b` in the buffer at or after `fromIndex`. This expands the
+   * buffer as necessary until `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.
+   * ```
+   * Buffer buffer = new Buffer();
+   * buffer.writeUtf8("Don't move! He can't see us if we don't move.");
+   *
+   * byte m = 'm';
+   * assertEquals(6,  buffer.indexOf(m));
+   * assertEquals(40, buffer.indexOf(m, 12));
+   * ```
+   */
+  fun indexOf(b: Byte, fromIndex: Long): Long
+
+  /**
+   * Returns the index of `b` if it is found in the range of `fromIndex` inclusive to `toIndex`
+   * exclusive. If `b` isn't found, or if `fromIndex == toIndex`, then -1 is returned.
+   *
+   * The scan terminates at either `toIndex` or the end of the buffer, whichever comes first. The
+   * maximum number of bytes scanned is `toIndex-fromIndex`.
+   */
+  fun indexOf(b: Byte, fromIndex: Long, toIndex: Long): Long
+
+  /** Equivalent to [indexOf(bytes, 0)][indexOf]. */
+  fun indexOf(bytes: ByteString): Long
+
+  /**
+   * Returns the index of the first match for `bytes` in the buffer at or after `fromIndex`. This
+   * expands the buffer as necessary until `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.
+   * ```
+   * ByteString MOVE = ByteString.encodeUtf8("move");
+   *
+   * Buffer buffer = new Buffer();
+   * buffer.writeUtf8("Don't move! He can't see us if we don't move.");
+   *
+   * assertEquals(6,  buffer.indexOf(MOVE));
+   * assertEquals(40, buffer.indexOf(MOVE, 12));
+   * ```
+   */
+  fun indexOf(bytes: ByteString, fromIndex: Long): Long
+
+  /** Equivalent to [indexOfElement(targetBytes, 0)][indexOfElement]. */
+  fun indexOfElement(targetBytes: ByteString): Long
+
+  /**
+   * Returns the first index in this buffer that is at or after `fromIndex` and that contains any of
+   * the bytes in `targetBytes`. 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.
+   * ```
+   * ByteString ANY_VOWEL = ByteString.encodeUtf8("AEOIUaeoiu");
+   *
+   * Buffer buffer = new Buffer();
+   * buffer.writeUtf8("Dr. Alan Grant");
+   *
+   * assertEquals(4,  buffer.indexOfElement(ANY_VOWEL));    // 'A' in 'Alan'.
+   * assertEquals(11, buffer.indexOfElement(ANY_VOWEL, 9)); // 'a' in 'Grant'.
+   * ```
+   */
+  fun indexOfElement(targetBytes: ByteString, fromIndex: Long): Long
+
+  /**
+   * Returns true if the bytes at `offset` in this source equal `bytes`. This expands the buffer as
+   * necessary until a byte does not match, all bytes are matched, or if the stream is exhausted
+   * before enough bytes could determine a match.
+   * ```
+   * ByteString simonSays = ByteString.encodeUtf8("Simon says:");
+   *
+   * Buffer standOnOneLeg = new Buffer().writeUtf8("Simon says: Stand on one leg.");
+   * assertTrue(standOnOneLeg.rangeEquals(0, simonSays));
+   *
+   * Buffer payMeMoney = new Buffer().writeUtf8("Pay me $1,000,000.");
+   * assertFalse(payMeMoney.rangeEquals(0, simonSays));
+   * ```
+   */
+  fun rangeEquals(offset: Long, bytes: ByteString): Boolean
+
+  /**
+   * Returns true if `byteCount` bytes at `offset` in this source equal `bytes` at `bytesOffset`.
+   * This expands the buffer as necessary until a byte does not match, all bytes are matched, or if
+   * the stream is exhausted before enough bytes could determine a match.
+   */
+  fun rangeEquals(offset: Long, bytes: ByteString, bytesOffset: Int, byteCount: Int): Boolean
+
+  /**
+   * Returns a new `BufferedSource` that can read data from this `BufferedSource` without consuming
+   * it. The returned source becomes invalid once this source is next read or closed.
+   *
+   * For example, we can use `peek()` to lookahead and read the same data multiple times.
+   *
+   * ```
+   * val buffer = Buffer()
+   * buffer.writeUtf8("abcdefghi")
+   *
+   * buffer.readUtf8(3) // returns "abc", buffer contains "defghi"
+   *
+   * val peek = buffer.peek()
+   * peek.readUtf8(3) // returns "def", buffer contains "defghi"
+   * peek.readUtf8(3) // returns "ghi", buffer contains "defghi"
+   *
+   * buffer.readUtf8(3) // returns "def", buffer contains "ghi"
+   * ```
+   */
+  fun peek(): BufferedSource
+}
diff --git a/okio/src/commonMain/kotlin/okio/ByteString.kt b/okio/src/commonMain/kotlin/okio/ByteString.kt
new file mode 100644
index 0000000..7eb34c6
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/ByteString.kt
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+import kotlin.jvm.JvmField
+import kotlin.jvm.JvmName
+import kotlin.jvm.JvmOverloads
+import kotlin.jvm.JvmStatic
+
+/**
+ * An immutable sequence of bytes.
+ *
+ * Byte strings compare lexicographically as a sequence of **unsigned** bytes. That is, the byte
+ * string `ff` sorts after `00`. This is counter to the sort order of the corresponding bytes,
+ * where `-1` sorts before `0`.
+ *
+ * **Full disclosure:** 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.
+ */
+expect open class ByteString
+// Trusted internal constructor doesn't clone data.
+internal constructor(data: ByteArray) : Comparable<ByteString> {
+  internal val data: ByteArray
+
+  internal var hashCode: Int
+  internal var utf8: String?
+
+  /** Constructs a new `String` by decoding the bytes as `UTF-8`.  */
+  fun utf8(): String
+
+  /**
+   * Returns this byte string encoded as [Base64](http://www.ietf.org/rfc/rfc2045.txt). In violation
+   * of the RFC, the returned string does not wrap lines at 76 columns.
+   */
+  fun base64(): String
+
+  /** Returns this byte string encoded as [URL-safe Base64](http://www.ietf.org/rfc/rfc4648.txt). */
+  fun base64Url(): String
+
+  /** Returns this byte string encoded in hexadecimal.  */
+  fun hex(): String
+
+  /** Returns the 128-bit MD5 hash of this byte string.  */
+  fun md5(): ByteString
+
+  /** Returns the 160-bit SHA-1 hash of this byte string.  */
+  fun sha1(): ByteString
+
+  /** Returns the 256-bit SHA-256 hash of this byte string.  */
+  fun sha256(): ByteString
+
+  /** Returns the 512-bit SHA-512 hash of this byte string.  */
+  fun sha512(): ByteString
+
+  /** Returns the 160-bit SHA-1 HMAC of this byte string.  */
+  fun hmacSha1(key: ByteString): ByteString
+
+  /** Returns the 256-bit SHA-256 HMAC of this byte string.  */
+  fun hmacSha256(key: ByteString): ByteString
+
+  /** Returns the 512-bit SHA-512 HMAC of this byte string.  */
+  fun hmacSha512(key: ByteString): ByteString
+  /**
+   * 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'.
+   */
+  fun toAsciiLowercase(): ByteString
+
+  /**
+   * Returns a byte string that is a substring of this byte string, beginning at the specified
+   * `beginIndex` and ends at the specified `endIndex`. Returns this byte string if `beginIndex` is
+   * 0 and `endIndex` is the length of this byte string.
+   */
+  fun substring(beginIndex: Int = 0, endIndex: Int = size): ByteString
+
+  /**
+   * 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'.
+   */
+  fun toAsciiUppercase(): ByteString
+
+  /** Returns the byte at `pos`.  */
+  internal fun internalGet(pos: Int): Byte
+
+  /** Returns the byte at `index`.  */
+  @JvmName("getByte")
+  operator fun get(index: Int): Byte
+
+  /** Returns the number of bytes in this ByteString. */
+  val size: Int
+    @JvmName("size") get
+
+  // Hack to work around Kotlin's limitation for using JvmName on open/override vals/funs
+  internal fun getSize(): Int
+
+  /** Returns a byte array containing a copy of the bytes in this `ByteString`. */
+  fun toByteArray(): ByteArray
+
+  /** Writes the contents of this byte string to `buffer`.  */
+  internal fun write(buffer: Buffer, offset: Int, byteCount: Int)
+
+  /** Returns the bytes of this string without a defensive copy. Do not mutate!  */
+  internal fun internalArray(): ByteArray
+
+  /**
+   * Returns true if the bytes of this in `[offset..offset+byteCount)` equal the bytes of `other` in
+   * `[otherOffset..otherOffset+byteCount)`. Returns false if either range is out of bounds.
+   */
+  fun rangeEquals(offset: Int, other: ByteString, otherOffset: Int, byteCount: Int): Boolean
+
+  /**
+   * Returns true if the bytes of this in `[offset..offset+byteCount)` equal the bytes of `other` in
+   * `[otherOffset..otherOffset+byteCount)`. Returns false if either range is out of bounds.
+   */
+  fun rangeEquals(offset: Int, other: ByteArray, otherOffset: Int, byteCount: Int): Boolean
+
+  fun startsWith(prefix: ByteString): Boolean
+
+  fun startsWith(prefix: ByteArray): Boolean
+
+  fun endsWith(suffix: ByteString): Boolean
+
+  fun endsWith(suffix: ByteArray): Boolean
+
+  @JvmOverloads
+  fun indexOf(other: ByteString, fromIndex: Int = 0): Int
+
+  @JvmOverloads
+  fun indexOf(other: ByteArray, fromIndex: Int = 0): Int
+
+  fun lastIndexOf(other: ByteString, fromIndex: Int = size): Int
+
+  fun lastIndexOf(other: ByteArray, fromIndex: Int = size): Int
+
+  override fun equals(other: Any?): Boolean
+
+  override fun hashCode(): Int
+
+  override fun compareTo(other: ByteString): Int
+
+  /**
+   * Returns a human-readable string that describes the contents of this byte string. Typically this
+   * is a string like `[text=Hello]` or `[hex=0000ffff]`.
+   */
+  override fun toString(): String
+
+  companion object {
+    /** A singleton empty `ByteString`.  */
+    @JvmField
+    val EMPTY: ByteString
+
+    /** Returns a new byte string containing a clone of the bytes of `data`. */
+    @JvmStatic
+    fun of(vararg data: Byte): ByteString
+
+    /**
+     * Returns a new [ByteString] containing a copy of `byteCount` bytes of this [ByteArray]
+     * starting at `offset`.
+     */
+    @JvmStatic
+    fun ByteArray.toByteString(offset: Int = 0, byteCount: Int = size): ByteString
+
+    /** Returns a new byte string containing the `UTF-8` bytes of this [String].  */
+    @JvmStatic
+    fun String.encodeUtf8(): ByteString
+
+    /**
+     * Decodes the Base64-encoded bytes and returns their value as a byte string. Returns null if
+     * this is not a Base64-encoded sequence of bytes.
+     */
+    @JvmStatic
+    fun String.decodeBase64(): ByteString?
+
+    /** Decodes the hex-encoded bytes and returns their value a byte string.  */
+    @JvmStatic
+    fun String.decodeHex(): ByteString
+  }
+}
diff --git a/okio/src/commonMain/kotlin/okio/ExperimentalFileSystem.kt b/okio/src/commonMain/kotlin/okio/ExperimentalFileSystem.kt
new file mode 100644
index 0000000..7fc3a4a
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/ExperimentalFileSystem.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2020 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 okio
+
+import kotlin.RequiresOptIn.Level.ERROR
+import kotlin.annotation.AnnotationRetention.BINARY
+import kotlin.annotation.AnnotationTarget.CLASS
+import kotlin.annotation.AnnotationTarget.FUNCTION
+import kotlin.annotation.AnnotationTarget.PROPERTY
+
+@RequiresOptIn(level = ERROR, message = "okio's FileSystem is unstable and subject to change")
+@Retention(BINARY)
+@Target(CLASS, FUNCTION, PROPERTY)
+annotation class ExperimentalFileSystem
diff --git a/okio/src/commonMain/kotlin/okio/HashingSink.kt b/okio/src/commonMain/kotlin/okio/HashingSink.kt
new file mode 100644
index 0000000..06cb6bf
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/HashingSink.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2020 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 okio
+
+/**
+ * A sink that computes a hash of the full stream of bytes it has accepted. To use, create an
+ * instance with your preferred hash algorithm. Write all of the data to the sink and then call
+ * [hash] to compute the final hash value.
+ *
+ * In this example we use `HashingSink` with a [BufferedSink] to make writing to the
+ * sink easier.
+ * ```
+ * HashingSink hashingSink = HashingSink.sha256(s);
+ * BufferedSink bufferedSink = Okio.buffer(hashingSink);
+ *
+ * ... // Write to bufferedSink and either flush or close it.
+ *
+ * ByteString hash = hashingSink.hash();
+ * ```
+ */
+expect class HashingSink : Sink {
+
+  /**
+   * Returns the hash of the bytes accepted thus far and resets the internal state of this sink.
+   *
+   * **Warning:** This method is not idempotent. Each time this method is called its
+   * internal state is cleared. This starts a new hash with zero bytes accepted.
+   */
+  val hash: ByteString
+
+  companion object {
+    /** Returns a sink that uses the obsolete MD5 hash algorithm to produce 128-bit hashes. */
+    fun md5(sink: Sink): HashingSink
+
+    /** Returns a sink that uses the obsolete SHA-1 hash algorithm to produce 160-bit hashes. */
+    fun sha1(sink: Sink): HashingSink
+
+    /** Returns a sink that uses the SHA-256 hash algorithm to produce 256-bit hashes. */
+    fun sha256(sink: Sink): HashingSink
+
+    /** Returns a sink that uses the SHA-512 hash algorithm to produce 512-bit hashes. */
+    fun sha512(sink: Sink): HashingSink
+
+    /** Returns a sink that uses the obsolete SHA-1 HMAC algorithm to produce 160-bit hashes. */
+    fun hmacSha1(sink: Sink, key: ByteString): HashingSink
+
+    /** Returns a sink that uses the SHA-256 HMAC algorithm to produce 256-bit hashes. */
+    fun hmacSha256(sink: Sink, key: ByteString): HashingSink
+
+    /** Returns a sink that uses the SHA-512 HMAC algorithm to produce 512-bit hashes. */
+    fun hmacSha512(sink: Sink, key: ByteString): HashingSink
+  }
+}
diff --git a/okio/src/commonMain/kotlin/okio/HashingSource.kt b/okio/src/commonMain/kotlin/okio/HashingSource.kt
new file mode 100644
index 0000000..9c61c99
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/HashingSource.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2020 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 okio
+
+/**
+ * A source that computes a hash of the full stream of bytes it has supplied. To use, create an
+ * instance with your preferred hash algorithm. Exhaust the source by reading all of its bytes and
+ * then call [hash] to compute the final hash value.
+ *
+ *
+ * In this example we use `HashingSource` with a [BufferedSource] to make reading
+ * from the source easier.
+ * ```
+ * HashingSource hashingSource = HashingSource.sha256(rawSource);
+ * BufferedSource bufferedSource = Okio.buffer(hashingSource);
+ *
+ * ... // Read all of bufferedSource.
+ *
+ * ByteString hash = hashingSource.hash();
+ * ```
+ */
+expect class HashingSource : Source {
+
+  /**
+   * Returns the hash of the bytes supplied thus far and resets the internal state of this source.
+   *
+   * **Warning:** This method is not idempotent. Each time this method is called its
+   * internal state is cleared. This starts a new hash with zero bytes supplied.
+   */
+  val hash: ByteString
+
+  companion object {
+    /** Returns a source that uses the obsolete MD5 hash algorithm to produce 128-bit hashes. */
+    fun md5(source: Source): HashingSource
+
+    /** Returns a source that uses the obsolete SHA-1 hash algorithm to produce 160-bit hashes. */
+    fun sha1(source: Source): HashingSource
+
+    /** Returns a source that uses the SHA-256 hash algorithm to produce 256-bit hashes. */
+    fun sha256(source: Source): HashingSource
+
+    /** Returns a source that uses the SHA-512 hash algorithm to produce 512-bit hashes. */
+    fun sha512(source: Source): HashingSource
+
+    /** Returns a source that uses the obsolete SHA-1 HMAC algorithm to produce 160-bit hashes. */
+    fun hmacSha1(source: Source, key: ByteString): HashingSource
+
+    /** Returns a source that uses the SHA-256 HMAC algorithm to produce 256-bit hashes. */
+    fun hmacSha256(source: Source, key: ByteString): HashingSource
+
+    /** Returns a source that uses the SHA-512 HMAC algorithm to produce 512-bit hashes. */
+    fun hmacSha512(source: Source, key: ByteString): HashingSource
+  }
+}
diff --git a/okio/src/commonMain/kotlin/okio/Okio.kt b/okio/src/commonMain/kotlin/okio/Okio.kt
new file mode 100644
index 0000000..116678a
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/Okio.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+/** Essential APIs for working with Okio. */
+@file:JvmMultifileClass
+@file:JvmName("Okio")
+
+package okio
+
+import kotlin.jvm.JvmMultifileClass
+import kotlin.jvm.JvmName
+
+/**
+ * Returns a new source that buffers reads from `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.
+ */
+fun Source.buffer(): BufferedSource = RealBufferedSource(this)
+
+/**
+ * Returns a new sink that buffers writes to `sink`. The returned sink will batch writes to `sink`.
+ * Use this wherever you write to a sink to get an ergonomic and efficient access to data.
+ */
+fun Sink.buffer(): BufferedSink = RealBufferedSink(this)
+
+/** Returns a sink that writes nowhere. */
+@JvmName("blackhole")
+fun blackholeSink(): Sink = BlackholeSink()
+
+private class BlackholeSink : Sink {
+  override fun write(source: Buffer, byteCount: Long) = source.skip(byteCount)
+  override fun flush() {}
+  override fun timeout() = Timeout.NONE
+  override fun close() {}
+}
+
+/** Execute [block] then close this. This will be closed even if [block] throws. */
+inline fun <T : Closeable?, R> T.use(block: (T) -> R): R {
+  var result: R? = null
+  var thrown: Throwable? = null
+
+  try {
+    result = block(this)
+  } catch (t: Throwable) {
+    thrown = t
+  }
+
+  try {
+    this?.close()
+  } catch (t: Throwable) {
+    if (thrown == null) thrown = t
+    else thrown.addSuppressed(t)
+  }
+
+  if (thrown != null) throw thrown
+  return result!!
+}
diff --git a/okio/src/commonMain/kotlin/okio/Options.kt b/okio/src/commonMain/kotlin/okio/Options.kt
new file mode 100644
index 0000000..9ce0739
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/Options.kt
@@ -0,0 +1,235 @@
+/*
+ * 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 okio
+
+import kotlin.jvm.JvmStatic
+
+/** An indexed set of values that may be read with [BufferedSource.select].  */
+class Options private constructor(
+  internal val byteStrings: Array<out ByteString>,
+  internal val trie: IntArray
+) : AbstractList<ByteString>(), RandomAccess {
+
+  override val size: Int
+    get() = byteStrings.size
+
+  override fun get(index: Int) = byteStrings[index]
+
+  companion object {
+    @JvmStatic
+    fun of(vararg byteStrings: ByteString): Options {
+      if (byteStrings.isEmpty()) {
+        // With no choices we must always return -1. Create a trie that selects from an empty set.
+        return Options(arrayOf(), intArrayOf(0, -1))
+      }
+
+      // Sort the byte strings which is required when recursively building the trie. Map the sorted
+      // indexes to the caller's indexes.
+      val list = byteStrings.toMutableList()
+      list.sort()
+      val indexes = mutableListOf(*byteStrings.map { -1 }.toTypedArray())
+      byteStrings.forEachIndexed { callerIndex, byteString ->
+        val sortedIndex = list.binarySearch(byteString)
+        indexes[sortedIndex] = callerIndex
+      }
+      require(list[0].size > 0) { "the empty byte string is not a supported option" }
+
+      // Strip elements that will never be returned because they follow their own prefixes. For
+      // example, if the caller provides ["abc", "abcde"] we will never return "abcde" because we
+      // return as soon as we encounter "abc".
+      var a = 0
+      while (a < list.size) {
+        val prefix = list[a]
+        var b = a + 1
+        while (b < list.size) {
+          val byteString = list[b]
+          if (!byteString.startsWith(prefix)) break
+          require(byteString.size != prefix.size) { "duplicate option: $byteString" }
+          if (indexes[b] > indexes[a]) {
+            list.removeAt(b)
+            indexes.removeAt(b)
+          } else {
+            b++
+          }
+        }
+        a++
+      }
+
+      val trieBytes = Buffer()
+      buildTrieRecursive(node = trieBytes, byteStrings = list, indexes = indexes)
+
+      val trie = IntArray(trieBytes.intCount.toInt())
+      var i = 0
+      while (!trieBytes.exhausted()) {
+        trie[i++] = trieBytes.readInt()
+      }
+
+      return Options(byteStrings.copyOf() /* Defensive copy. */, trie)
+    }
+
+    /**
+     * Builds a trie encoded as an int array. Nodes in the trie are of two types: SELECT and SCAN.
+     *
+     * SELECT nodes are encoded as:
+     *  - selectChoiceCount: the number of bytes to choose between (a positive int)
+     *  - prefixIndex: the result index at the current position or -1 if the current position is not
+     *    a result on its own
+     *  - a sorted list of selectChoiceCount bytes to match against the input string
+     *  - a heterogeneous list of selectChoiceCount result indexes (>= 0) or offsets (< 0) of the
+     *    next node to follow. Elements in this list correspond to elements in the preceding list.
+     *    Offsets are negative and must be multiplied by -1 before being used.
+     *
+     * SCAN nodes are encoded as:
+     *  - scanByteCount: the number of bytes to match in sequence. This count is negative and must
+     *    be multiplied by -1 before being used.
+     *  - prefixIndex: the result index at the current position or -1 if the current position is not
+     *    a result on its own
+     *  - a list of scanByteCount bytes to match
+     *  - nextStep: the result index (>= 0) or offset (< 0) of the next node to follow. Offsets are
+     *    negative and must be multiplied by -1 before being used.
+     *
+     * This structure is used to improve locality and performance when selecting from a list of
+     * options.
+     */
+    private fun buildTrieRecursive(
+      nodeOffset: Long = 0L,
+      node: Buffer,
+      byteStringOffset: Int = 0,
+      byteStrings: List<ByteString>,
+      fromIndex: Int = 0,
+      toIndex: Int = byteStrings.size,
+      indexes: List<Int>
+    ) {
+      require(fromIndex < toIndex)
+      for (i in fromIndex until toIndex) {
+        require(byteStrings[i].size >= byteStringOffset)
+      }
+
+      var fromIndex = fromIndex
+      var from = byteStrings[fromIndex]
+      val to = byteStrings[toIndex - 1]
+      var prefixIndex = -1
+
+      // If the first element is already matched, that's our prefix.
+      if (byteStringOffset == from.size) {
+        prefixIndex = indexes[fromIndex]
+        fromIndex++
+        from = byteStrings[fromIndex]
+      }
+
+      if (from[byteStringOffset] != to[byteStringOffset]) {
+        // If we have multiple bytes to choose from, encode a SELECT node.
+        var selectChoiceCount = 1
+        for (i in fromIndex + 1 until toIndex) {
+          if (byteStrings[i - 1][byteStringOffset] != byteStrings[i][byteStringOffset]) {
+            selectChoiceCount++
+          }
+        }
+
+        // Compute the offset that childNodes will get when we append it to node.
+        val childNodesOffset = nodeOffset + node.intCount + 2 + (selectChoiceCount * 2)
+
+        node.writeInt(selectChoiceCount)
+        node.writeInt(prefixIndex)
+
+        for (i in fromIndex until toIndex) {
+          val rangeByte = byteStrings[i][byteStringOffset]
+          if (i == fromIndex || rangeByte != byteStrings[i - 1][byteStringOffset]) {
+            node.writeInt(rangeByte and 0xff)
+          }
+        }
+
+        val childNodes = Buffer()
+        var rangeStart = fromIndex
+        while (rangeStart < toIndex) {
+          val rangeByte = byteStrings[rangeStart][byteStringOffset]
+          var rangeEnd = toIndex
+          for (i in rangeStart + 1 until toIndex) {
+            if (rangeByte != byteStrings[i][byteStringOffset]) {
+              rangeEnd = i
+              break
+            }
+          }
+
+          if (rangeStart + 1 == rangeEnd &&
+            byteStringOffset + 1 == byteStrings[rangeStart].size
+          ) {
+            // The result is a single index.
+            node.writeInt(indexes[rangeStart])
+          } else {
+            // The result is another node.
+            node.writeInt(-1 * (childNodesOffset + childNodes.intCount).toInt())
+            buildTrieRecursive(
+              nodeOffset = childNodesOffset,
+              node = childNodes,
+              byteStringOffset = byteStringOffset + 1,
+              byteStrings = byteStrings,
+              fromIndex = rangeStart,
+              toIndex = rangeEnd,
+              indexes = indexes
+            )
+          }
+
+          rangeStart = rangeEnd
+        }
+
+        node.writeAll(childNodes)
+      } else {
+        // If all of the bytes are the same, encode a SCAN node.
+        var scanByteCount = 0
+        for (i in byteStringOffset until minOf(from.size, to.size)) {
+          if (from[i] == to[i]) {
+            scanByteCount++
+          } else {
+            break
+          }
+        }
+
+        // Compute the offset that childNodes will get when we append it to node.
+        val childNodesOffset = nodeOffset + node.intCount + 2 + scanByteCount + 1
+
+        node.writeInt(-scanByteCount)
+        node.writeInt(prefixIndex)
+
+        for (i in byteStringOffset until byteStringOffset + scanByteCount) {
+          node.writeInt(from[i] and 0xff)
+        }
+
+        if (fromIndex + 1 == toIndex) {
+          // The result is a single index.
+          check(byteStringOffset + scanByteCount == byteStrings[fromIndex].size)
+          node.writeInt(indexes[fromIndex])
+        } else {
+          // The result is another node.
+          val childNodes = Buffer()
+          node.writeInt(-1 * (childNodesOffset + childNodes.intCount).toInt())
+          buildTrieRecursive(
+            nodeOffset = childNodesOffset,
+            node = childNodes,
+            byteStringOffset = byteStringOffset + scanByteCount,
+            byteStrings = byteStrings,
+            fromIndex = fromIndex,
+            toIndex = toIndex,
+            indexes = indexes
+          )
+          node.writeAll(childNodes)
+        }
+      }
+    }
+
+    private val Buffer.intCount get() = size / 4
+  }
+}
diff --git a/okio/src/commonMain/kotlin/okio/PeekSource.kt b/okio/src/commonMain/kotlin/okio/PeekSource.kt
new file mode 100644
index 0000000..598d83d
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/PeekSource.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+/**
+ * A [Source] which peeks into an upstream [BufferedSource] and allows reading and expanding of the
+ * buffered data without consuming it. Does this by requesting additional data from the upstream
+ * source if needed and copying out of the internal buffer of the upstream source if possible.
+ *
+ * This source also maintains a snapshot of the starting location of the upstream buffer which it
+ * validates against on every read. If the upstream buffer is read from, this source will become
+ * invalid and throw [IllegalStateException] on any future reads.
+ */
+internal class PeekSource(
+  private val upstream: BufferedSource
+) : Source {
+  private val buffer = upstream.buffer
+  private var expectedSegment = buffer.head
+  private var expectedPos = buffer.head?.pos ?: -1
+
+  private var closed = false
+  private var pos = 0L
+
+  override fun read(sink: Buffer, byteCount: Long): Long {
+    require(byteCount >= 0L) { "byteCount < 0: $byteCount" }
+    check(!closed) { "closed" }
+    // Source becomes invalid if there is an expected Segment and it and the expected position
+    // do not match the current head and head position of the upstream buffer
+    check(
+      expectedSegment == null ||
+        expectedSegment === buffer.head && expectedPos == buffer.head!!.pos
+    ) {
+      "Peek source is invalid because upstream source was used"
+    }
+    if (byteCount == 0L) return 0L
+    if (!upstream.request(pos + 1)) return -1L
+
+    if (expectedSegment == null && buffer.head != null) {
+      // Only once the buffer actually holds data should an expected Segment and position be
+      // recorded. This allows reads from the peek source to repeatedly return -1 and for data to be
+      // added later. Unit tests depend on this behavior.
+      expectedSegment = buffer.head
+      expectedPos = buffer.head!!.pos
+    }
+
+    val toCopy = minOf(byteCount, buffer.size - pos)
+    buffer.copyTo(sink, pos, toCopy)
+    pos += toCopy
+    return toCopy
+  }
+
+  override fun timeout(): Timeout {
+    return upstream.timeout()
+  }
+
+  override fun close() {
+    closed = true
+  }
+}
diff --git a/okio/src/commonMain/kotlin/okio/RealBufferedSink.kt b/okio/src/commonMain/kotlin/okio/RealBufferedSink.kt
new file mode 100644
index 0000000..80e3fae
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/RealBufferedSink.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+internal expect class RealBufferedSink(
+  sink: Sink
+) : BufferedSink {
+  val sink: Sink
+  var closed: Boolean
+}
diff --git a/okio/src/commonMain/kotlin/okio/RealBufferedSource.kt b/okio/src/commonMain/kotlin/okio/RealBufferedSource.kt
new file mode 100644
index 0000000..b626e42
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/RealBufferedSource.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+internal expect class RealBufferedSource(
+  source: Source
+) : BufferedSource {
+  val source: Source
+  var closed: Boolean
+}
diff --git a/okio/src/commonMain/kotlin/okio/Segment.kt b/okio/src/commonMain/kotlin/okio/Segment.kt
new file mode 100644
index 0000000..3687949
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/Segment.kt
@@ -0,0 +1,184 @@
+/*
+ * 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 okio
+
+import kotlin.jvm.JvmField
+
+/**
+ * A segment of a buffer.
+ *
+ * Each segment in a buffer is a circularly-linked list node referencing the following and
+ * preceding segments in the buffer.
+ *
+ * Each segment in the pool is a singly-linked list node referencing the rest of segments in the
+ * pool.
+ *
+ * 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
+ * `limit` and beyond. There is a single owning segment for each byte array. Positions,
+ * limits, prev, and next references are not shared.
+ */
+internal class Segment {
+  @JvmField val data: ByteArray
+
+  /** The next byte of application data byte to read in this segment. */
+  @JvmField var pos: Int = 0
+
+  /**
+   * The first byte of available data ready to be written to.
+   *
+   * If the segment is free and linked in the segment pool, the field contains total
+   * byte count of this and next segments.
+   */
+  @JvmField var limit: Int = 0
+
+  /** True if other segments or byte strings use the same byte array. */
+  @JvmField var shared: Boolean = false
+
+  /** True if this segment owns the byte array and can append to it, extending `limit`. */
+  @JvmField var owner: Boolean = false
+
+  /** Next segment in a linked or circularly-linked list. */
+  @JvmField var next: Segment? = null
+
+  /** Previous segment in a circularly-linked list. */
+  @JvmField var prev: Segment? = null
+
+  constructor() {
+    this.data = ByteArray(SIZE)
+    this.owner = true
+    this.shared = false
+  }
+
+  constructor(data: ByteArray, pos: Int, limit: Int, shared: Boolean, owner: Boolean) {
+    this.data = data
+    this.pos = pos
+    this.limit = limit
+    this.shared = shared
+    this.owner = owner
+  }
+
+  /**
+   * Returns a new segment that shares the underlying byte array with this. Adjusting pos and limit
+   * are safe but writes are forbidden. This also marks the current segment as shared, which
+   * prevents it from being pooled.
+   */
+  fun sharedCopy(): Segment {
+    shared = true
+    return Segment(data, pos, limit, true, false)
+  }
+
+  /** Returns a new segment that its own private copy of the underlying byte array.  */
+  fun unsharedCopy() = Segment(data.copyOf(), pos, limit, false, true)
+
+  /**
+   * Removes this segment of a circularly-linked list and returns its successor.
+   * Returns null if the list is now empty.
+   */
+  fun pop(): Segment? {
+    val result = if (next !== this) next else null
+    prev!!.next = next
+    next!!.prev = prev
+    next = null
+    prev = null
+    return result
+  }
+
+  /**
+   * Appends `segment` after this segment in the circularly-linked list. Returns the pushed segment.
+   */
+  fun push(segment: 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 `[pos..pos+byteCount)`. The second segment contains the data in
+   * `[pos+byteCount..limit)`. This can be useful when moving partial segments from one buffer to
+   * another.
+   *
+   * Returns the new head of the circularly-linked list.
+   */
+  fun split(byteCount: Int): Segment {
+    require(byteCount > 0 && byteCount <= limit - pos) { "byteCount out of range" }
+    val prefix: Segment
+
+    // We have two competing performance goals:
+    //  - Avoid copying data. We accomplish this by sharing segments.
+    //  - Avoid short shared segments. These are bad for performance because they are readonly and
+    //    may lead to long chains of short segments.
+    // To balance these goals we only share segments when the copy will be large.
+    if (byteCount >= SHARE_MINIMUM) {
+      prefix = sharedCopy()
+    } else {
+      prefix = SegmentPool.take()
+      data.copyInto(prefix.data, startIndex = pos, endIndex = pos + byteCount)
+    }
+
+    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.
+   */
+  fun compact() {
+    check(prev !== this) { "cannot compact" }
+    if (!prev!!.owner) return // Cannot compact: prev isn't writable.
+    val byteCount = limit - pos
+    val availableByteCount = SIZE - prev!!.limit + if (prev!!.shared) 0 else prev!!.pos
+    if (byteCount > availableByteCount) return // Cannot compact: not enough writable space.
+    writeTo(prev!!, byteCount)
+    pop()
+    SegmentPool.recycle(this)
+  }
+
+  /** Moves `byteCount` bytes from this segment to `sink`.  */
+  fun writeTo(sink: Segment, byteCount: Int) {
+    check(sink.owner) { "only owner can write" }
+    if (sink.limit + byteCount > SIZE) {
+      // We can't fit byteCount bytes at the sink's current position. Shift sink first.
+      if (sink.shared) throw IllegalArgumentException()
+      if (sink.limit + byteCount - sink.pos > SIZE) throw IllegalArgumentException()
+      sink.data.copyInto(sink.data, startIndex = sink.pos, endIndex = sink.limit)
+      sink.limit -= sink.pos
+      sink.pos = 0
+    }
+
+    data.copyInto(
+      sink.data, destinationOffset = sink.limit, startIndex = pos,
+      endIndex = pos + byteCount
+    )
+    sink.limit += byteCount
+    pos += byteCount
+  }
+
+  companion object {
+    /** The size of all segments in bytes.  */
+    const val SIZE = 8192
+
+    /** Segments will be shared when doing so avoids `arraycopy()` of this many bytes.  */
+    const val SHARE_MINIMUM = 1024
+  }
+}
diff --git a/okio/src/commonMain/kotlin/okio/SegmentPool.kt b/okio/src/commonMain/kotlin/okio/SegmentPool.kt
new file mode 100644
index 0000000..f21c7a2
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/SegmentPool.kt
@@ -0,0 +1,36 @@
+/*
+ * 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 okio
+
+/**
+ * A collection of unused segments, necessary to avoid GC churn and zero-fill.
+ * This pool is a thread-safe static singleton.
+ */
+internal expect object SegmentPool {
+  val MAX_SIZE: Int
+
+  /**
+   * For testing only. Returns a snapshot of the number of bytes currently in the pool. If the pool
+   * is segmented such as by thread, this returns the byte count accessible to the calling thread.
+   */
+  val byteCount: Int
+
+  /** Return a segment for the caller's use. */
+  fun take(): Segment
+
+  /** Recycle a segment that the caller no longer needs. */
+  fun recycle(segment: Segment)
+}
diff --git a/okio/src/commonMain/kotlin/okio/SegmentedByteString.kt b/okio/src/commonMain/kotlin/okio/SegmentedByteString.kt
new file mode 100644
index 0000000..bda4f4a
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/SegmentedByteString.kt
@@ -0,0 +1,50 @@
+/*
+ * 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 okio
+
+/**
+ * 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.
+ *
+ * The first half of the directory is the cumulative byte count covered by each segment. The
+ * element at `directory[0]` contains the number of bytes held in `segments[0]`; the
+ * element at `directory[1]` contains the number of bytes held in `segments[0] +
+ * segments[1]`, and so on. The element at `directory[segments.length - 1]` contains the total
+ * size of this byte string. The first half of the directory is always monotonically increasing.
+ *
+ * The second half of the directory is the offset in `segments` of the first content byte.
+ * Bytes preceding this offset are unused, as are bytes beyond the segment's effective size.
+ *
+ * Suppose we have a byte string, `[A, B, C, D, E, F, G, H, I, J, K, L, M]` that is stored
+ * across three byte arrays: `[x, x, x, x, A, B, C, D, E, x, x, x]`, `[x, F, G]`, and `[H, I, J, K,
+ * L, M, x, x, x, x, x, x]`. The three byte arrays would be stored in `segments` in order. Since the
+ * arrays contribute 5, 2, and 6 elements respectively, the directory starts with `[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 `4, 1, 0]`. Concatenating these two halves, the complete
+ * directory is `[5, 7, 13, 4, 1, 0]`.
+ *
+ * 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.
+ */
+internal expect class SegmentedByteString internal constructor(
+  segments: Array<ByteArray>,
+  directory: IntArray
+) : ByteString {
+
+  internal val segments: Array<ByteArray>
+  internal val directory: IntArray
+}
diff --git a/okio/src/commonMain/kotlin/okio/Sink.kt b/okio/src/commonMain/kotlin/okio/Sink.kt
new file mode 100644
index 0000000..0a6af54
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/Sink.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+/**
+ * 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.
+ *
+ * Most application code shouldn't operate on a sink directly, but rather on a [BufferedSink] which
+ * is both more efficient and more convenient. Use [buffer] to wrap any sink with a buffer.
+ *
+ * Sinks are easy to test: just use a [Buffer] in your tests, and read from it to confirm it
+ * received the data that was expected.
+ *
+ * ### Comparison with OutputStream
+ *
+ * This interface is functionally equivalent to [java.io.OutputStream].
+ *
+ * `OutputStream` requires multiple layers when emitted data is heterogeneous: a `DataOutputStream`
+ * for primitive values, a `BufferedOutputStream` for buffering, and `OutputStreamWriter` for
+ * charset encoding. This library uses `BufferedSink` for all of the above.
+ *
+ * Sink is also easier to layer: there is no [write()][java.io.OutputStream.write] method that is
+ * awkward to implement efficiently.
+ *
+ * ### Interop with OutputStream
+ *
+ * Use [sink] to adapt an `OutputStream` to a sink. Use [outputStream()][BufferedSink.outputStream]
+ * to adapt a sink to an `OutputStream`.
+ */
+expect interface Sink : Closeable {
+  /** Removes `byteCount` bytes from `source` and appends them to this.  */
+  @Throws(IOException::class)
+  fun write(source: Buffer, byteCount: Long)
+
+  /** Pushes all buffered bytes to their final destination.  */
+  @Throws(IOException::class)
+  fun flush()
+
+  /** Returns the timeout for this sink.  */
+  fun 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.
+   */
+  @Throws(IOException::class)
+  override fun close()
+}
diff --git a/okio/src/commonMain/kotlin/okio/Source.kt b/okio/src/commonMain/kotlin/okio/Source.kt
new file mode 100644
index 0000000..97c6681
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/Source.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+/**
+ * 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.
+ *
+ * Most applications shouldn't operate on a source directly, but rather on a [BufferedSource] which
+ * is both more efficient and more convenient. Use [buffer] to wrap any source with a buffer.
+ *
+ * Sources are easy to test: just use a [Buffer] in your tests, and fill it with the data your
+ * application is to read.
+ *
+ * ### Comparison with InputStream
+
+ * This interface is functionally equivalent to [java.io.InputStream].
+ *
+ * `InputStream` requires multiple layers when consumed data is heterogeneous: a `DataInputStream`
+ * for primitive values, a `BufferedInputStream` for buffering, and `InputStreamReader` for strings.
+ * This library uses `BufferedSource` for all of the above.
+ *
+ * Source avoids the impossible-to-implement [available()][java.io.InputStream.available] method.
+ * Instead callers specify how many bytes they [require][BufferedSource.require].
+ *
+ * Source omits the unsafe-to-compose [mark and reset][java.io.InputStream.mark] state that's
+ * tracked by `InputStream`; instead, callers just buffer what they need.
+ *
+ * When implementing a source, you don't need to worry about the [read()][java.io.InputStream.read]
+ * method that is awkward to implement efficiently and returns one of 257 possible values.
+ *
+ * And source has a stronger `skip` method: [BufferedSource.skip] won't return prematurely.
+ *
+ * ### Interop with InputStream
+ *
+ * Use [source] to adapt an `InputStream` to a source. Use [BufferedSource.inputStream] to adapt a
+ * source to an `InputStream`.
+ */
+interface Source : Closeable {
+  /**
+   * Removes at least 1, and up to `byteCount` bytes from this and appends them to `sink`. Returns
+   * the number of bytes read, or -1 if this source is exhausted.
+   */
+  @Throws(IOException::class)
+  fun read(sink: Buffer, byteCount: Long): Long
+
+  /** Returns the timeout for this source.  */
+  fun 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.
+   */
+  @Throws(IOException::class)
+  override fun close()
+}
diff --git a/okio/src/commonMain/kotlin/okio/Timeout.kt b/okio/src/commonMain/kotlin/okio/Timeout.kt
new file mode 100644
index 0000000..62600bb
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/Timeout.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+/**
+ * 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.
+ *
+ * ### Timeouts and Deadlines
+ *
+ * This class offers two complementary controls to define a timeout policy.
+ *
+ * **Timeouts** 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 *any* data for ten seconds, we may assume that the peer is unavailable.
+ *
+ * **Deadlines** 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 pre-loading content.
+ */
+expect open class Timeout {
+  companion object {
+    /**
+     * 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.
+     */
+    val NONE: Timeout
+  }
+}
diff --git a/okio/src/commonMain/kotlin/okio/Utf8.kt b/okio/src/commonMain/kotlin/okio/Utf8.kt
new file mode 100644
index 0000000..ca20e21
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/Utf8.kt
@@ -0,0 +1,557 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+/**
+ * Okio assumes most applications use UTF-8 exclusively, and offers optimized implementations of
+ * common operations on UTF-8 strings.
+ *
+ * <table border="1" cellspacing="0" cellpadding="3" summary="">
+ * <tr>
+ * <th></th>
+ * <th>[ByteString]</th>
+ * <th>[Buffer], [BufferedSink], [BufferedSource]</th>
+ * </tr>
+ * <tr>
+ * <td>Encode a string</td>
+ * <td>[ByteString.encodeUtf8]</td>
+ * <td>[BufferedSink.writeUtf8]</td>
+ * </tr>
+ * <tr>
+ * <td>Encode a code point</td>
+ * <td></td>
+ * <td>[BufferedSink.writeUtf8CodePoint]</td>
+ * </tr>
+ * <tr>
+ * <td>Decode a string</td>
+ * <td>[ByteString.utf8]</td>
+ * <td>[BufferedSource.readUtf8], [BufferedSource.readUtf8]</td>
+ * </tr>
+ * <tr>
+ * <td>Decode a code point</td>
+ * <td></td>
+ * <td>[BufferedSource.readUtf8CodePoint]</td>
+ * </tr>
+ * <tr>
+ * <td>Decode until the next `\r\n` or `\n`</td>
+ * <td></td>
+ * <td>[BufferedSource.readUtf8LineStrict],
+ * [BufferedSource.readUtf8LineStrict]</td>
+ * </tr>
+ * <tr>
+ * <td>Decode until the next `\r\n`, `\n`, or `EOF`</td>
+ * <td></td>
+ * <td>[BufferedSource.readUtf8Line]</td>
+ * </tr>
+ * <tr>
+ * <td>Measure the bytes in a UTF-8 string</td>
+ * <td colspan="2">[Utf8.size], [Utf8.size]</td>
+ * </tr>
+ * </table>
+ */
+@file:JvmName("Utf8")
+
+package okio
+
+import kotlin.jvm.JvmName
+import kotlin.jvm.JvmOverloads
+
+/**
+ * Returns the number of bytes used to encode the slice of `string` as UTF-8 when using
+ * [BufferedSink.writeUtf8].
+ */
+@JvmOverloads
+@JvmName("size")
+fun String.utf8Size(beginIndex: Int = 0, endIndex: Int = length): Long {
+  require(beginIndex >= 0) { "beginIndex < 0: $beginIndex" }
+  require(endIndex >= beginIndex) { "endIndex < beginIndex: $endIndex < $beginIndex" }
+  require(endIndex <= length) { "endIndex > string.length: $endIndex > $length" }
+
+  var result = 0L
+  var i = beginIndex
+  while (i < endIndex) {
+    val c = this[i].toInt()
+
+    if (c < 0x80) {
+      // A 7-bit character with 1 byte.
+      result++
+      i++
+    } else if (c < 0x800) {
+      // An 11-bit character with 2 bytes.
+      result += 2
+      i++
+    } else if (c < 0xd800 || c > 0xdfff) {
+      // A 16-bit character with 3 bytes.
+      result += 3
+      i++
+    } else {
+      val low = if (i + 1 < endIndex) this[i + 1].toInt() else 0
+      if (c > 0xdbff || low < 0xdc00 || low > 0xdfff) {
+        // A malformed surrogate, which yields '?'.
+        result++
+        i++
+      } else {
+        // A 21-bit character with 4 bytes.
+        result += 4
+        i += 2
+      }
+    }
+  }
+
+  return result
+}
+
+internal const val REPLACEMENT_BYTE: Byte = '?'.toByte()
+internal const val REPLACEMENT_CHARACTER: Char = '\ufffd'
+internal const val REPLACEMENT_CODE_POINT: Int = REPLACEMENT_CHARACTER.toInt()
+
+@Suppress("NOTHING_TO_INLINE") // Syntactic sugar.
+internal inline fun isIsoControl(codePoint: Int): Boolean =
+  (codePoint in 0x00..0x1F) || (codePoint in 0x7F..0x9F)
+
+@Suppress("NOTHING_TO_INLINE") // Syntactic sugar.
+internal inline fun isUtf8Continuation(byte: Byte): Boolean {
+  // 0b10xxxxxx
+  return byte and 0xc0 == 0x80
+}
+
+// TODO combine with Buffer.writeUtf8?
+// TODO combine with Buffer.writeUtf8CodePoint?
+internal inline fun String.processUtf8Bytes(
+  beginIndex: Int,
+  endIndex: Int,
+  yield: (Byte) -> Unit
+) {
+  // Transcode a UTF-16 String to UTF-8 bytes.
+  var index = beginIndex
+  while (index < endIndex) {
+    val c = this[index]
+
+    when {
+      c < '\u0080' -> {
+        // Emit a 7-bit character with 1 byte.
+        yield(c.toByte()) // 0xxxxxxx
+        index++
+
+        // Assume there is going to be more ASCII
+        while (index < endIndex && this[index] < '\u0080') {
+          yield(this[index++].toByte())
+        }
+      }
+
+      c < '\u0800' -> {
+        // Emit a 11-bit character with 2 bytes.
+        /* ktlint-disable no-multi-spaces */
+        yield((c.toInt() shr 6          or 0xc0).toByte()) // 110xxxxx
+        yield((c.toInt()       and 0x3f or 0x80).toByte()) // 10xxxxxx
+        /* ktlint-enable no-multi-spaces */
+        index++
+      }
+
+      c !in '\ud800'..'\udfff' -> {
+        // Emit a 16-bit character with 3 bytes.
+        /* ktlint-disable no-multi-spaces */
+        yield((c.toInt() shr 12          or 0xe0).toByte()) // 1110xxxx
+        yield((c.toInt() shr  6 and 0x3f or 0x80).toByte()) // 10xxxxxx
+        yield((c.toInt()        and 0x3f or 0x80).toByte()) // 10xxxxxx
+        /* ktlint-enable no-multi-spaces */
+        index++
+      }
+
+      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
+        // byte.
+        if (c > '\udbff' ||
+          endIndex <= index + 1 ||
+          this[index + 1] !in '\udc00'..'\udfff'
+        ) {
+          yield(REPLACEMENT_BYTE)
+          index++
+        } else {
+          // UTF-16 high surrogate: 110110xxxxxxxxxx (10 bits)
+          // UTF-16 low surrogate:  110111yyyyyyyyyy (10 bits)
+          // Unicode code point:    00010000000000000000 + xxxxxxxxxxyyyyyyyyyy (21 bits)
+          val codePoint = (
+            ((c.toInt() shl 10) + this[index + 1].toInt()) +
+              (0x010000 - (0xd800 shl 10) - 0xdc00)
+            )
+
+          // Emit a 21-bit character with 4 bytes.
+          /* ktlint-disable no-multi-spaces */
+          yield((codePoint shr 18          or 0xf0).toByte()) // 11110xxx
+          yield((codePoint shr 12 and 0x3f or 0x80).toByte()) // 10xxxxxx
+          yield((codePoint shr 6  and 0x3f or 0x80).toByte()) // 10xxyyyy
+          yield((codePoint        and 0x3f or 0x80).toByte()) // 10yyyyyy
+          /* ktlint-enable no-multi-spaces */
+          index += 2
+        }
+      }
+    }
+  }
+}
+
+// TODO combine with Buffer.readUtf8CodePoint?
+internal inline fun ByteArray.processUtf8CodePoints(
+  beginIndex: Int,
+  endIndex: Int,
+  yield: (Int) -> Unit
+) {
+  var index = beginIndex
+  while (index < endIndex) {
+    val b0 = this[index]
+    when {
+      b0 >= 0 -> {
+        // 0b0xxxxxxx
+        yield(b0.toInt())
+        index++
+
+        // Assume there is going to be more ASCII
+        while (index < endIndex && this[index] >= 0) {
+          yield(this[index++].toInt())
+        }
+      }
+      b0 shr 5 == -2 -> {
+        // 0b110xxxxx
+        index += process2Utf8Bytes(index, endIndex) { yield(it) }
+      }
+      b0 shr 4 == -2 -> {
+        // 0b1110xxxx
+        index += process3Utf8Bytes(index, endIndex) { yield(it) }
+      }
+      b0 shr 3 == -2 -> {
+        // 0b11110xxx
+        index += process4Utf8Bytes(index, endIndex) { yield(it) }
+      }
+      else -> {
+        // 0b10xxxxxx - Unexpected continuation
+        // 0b111111xxx - Unknown encoding
+        yield(REPLACEMENT_CODE_POINT)
+        index++
+      }
+    }
+  }
+}
+
+// Value added to the high UTF-16 surrogate after shifting
+internal const val HIGH_SURROGATE_HEADER = 0xd800 - (0x010000 ushr 10)
+// Value added to the low UTF-16 surrogate after masking
+internal const val LOG_SURROGATE_HEADER = 0xdc00
+
+// TODO combine with Buffer.readUtf8?
+internal inline fun ByteArray.processUtf16Chars(
+  beginIndex: Int,
+  endIndex: Int,
+  yield: (Char) -> Unit
+) {
+  var index = beginIndex
+  while (index < endIndex) {
+    val b0 = this[index]
+    when {
+      b0 >= 0 -> {
+        // 0b0xxxxxxx
+        yield(b0.toChar())
+        index++
+
+        // Assume there is going to be more ASCII
+        // This is almost double the performance of the outer loop
+        while (index < endIndex && this[index] >= 0) {
+          yield(this[index++].toChar())
+        }
+      }
+      b0 shr 5 == -2 -> {
+        // 0b110xxxxx
+        index += process2Utf8Bytes(index, endIndex) { yield(it.toChar()) }
+      }
+      b0 shr 4 == -2 -> {
+        // 0b1110xxxx
+        index += process3Utf8Bytes(index, endIndex) { yield(it.toChar()) }
+      }
+      b0 shr 3 == -2 -> {
+        // 0b11110xxx
+        index += process4Utf8Bytes(index, endIndex) { codePoint ->
+          if (codePoint != REPLACEMENT_CODE_POINT) {
+            // Unicode code point:    00010000000000000000 + xxxxxxxxxxyyyyyyyyyy (21 bits)
+            // UTF-16 high surrogate: 110110xxxxxxxxxx (10 bits)
+            // UTF-16 low surrogate:  110111yyyyyyyyyy (10 bits)
+            /* ktlint-disable no-multi-spaces paren-spacing */
+            yield(((codePoint ushr 10   ) + HIGH_SURROGATE_HEADER).toChar())
+            /* ktlint-enable no-multi-spaces paren-spacing */
+            yield(((codePoint and 0x03ff) + LOG_SURROGATE_HEADER).toChar())
+          } else {
+            yield(REPLACEMENT_CHARACTER)
+          }
+        }
+      }
+      else -> {
+        // 0b10xxxxxx - Unexpected continuation
+        // 0b111111xxx - Unknown encoding
+        yield(REPLACEMENT_CHARACTER)
+        index++
+      }
+    }
+  }
+}
+
+// ===== UTF-8 Encoding and Decoding ===== //
+/*
+The following 3 methods take advantage of using XOR on 2's complement store
+numbers to quickly and efficiently combine the important data of UTF-8 encoded
+bytes. This will be best explained using an example, so lets take the following
+encoded character '∇' = \u2207.
+
+Using the Unicode code point for this character, 0x2207, we will split the
+binary representation into 3 sections as follows:
+
+    0x2207 = 0b0010 0010 0000 0111
+               xxxx yyyy yyzz zzzz
+
+Now take each section of bits and add the appropriate header:
+
+    utf8(0x2207) = 0b1110 xxxx 0b10yy yyyy 0b10zz zzzz
+                 = 0b1110 0010 0b1000 1000 0b1000 0111
+                 = 0xe2        0x88        0x87
+
+We have now just encoded this as a 3 byte UTF-8 character. More information
+about different sizes of characters can be found here:
+    https://en.wikipedia.org/wiki/UTF-8
+
+Encoding was pretty easy, but decoding is a bit more complicated. We need to
+first determine the number of bytes used to represent the character, strip all
+the headers, and then combine all the bits into a single integer. Let's use the
+character we just encoded and work backwards, taking advantage of 2's complement
+integer representation and the XOR function.
+
+Let's look at the decimal representation of these bytes:
+
+    0xe2, 0x88, 0x87 = -30, -120, -121
+
+The first interesting thing to notice is that UTF-8 headers all start with 1 -
+except for ASCII which is encoded as a single byte - which means all UTF-8 bytes
+will be negative. So converting these to integers results in a lot of 1's added
+because they are store as 2's complement:
+
+    0xe2 =  -30 = 0xffff ffe2
+    0x88 = -120 = 0xffff ff88
+    0x87 = -121 = 0xffff ff87
+
+Now let's XOR these with their corresponding UTF-8 byte headers to see what
+happens:
+
+    0xffff ffe2 xor 0xffff ffe0 = 0x0000 0002
+    0xffff ff88 xor 0xffff ff80 = 0x0000 0008
+    0xffff ff87 xor 0xffff ff80 = 0x0000 0007
+
+***This is why we must first convert the byte header mask to a byte and then
+back to an integer, so it is properly converted to a 2's complement negative
+number which can be applied to each byte.***
+
+Now let's look at the binary representation to see how we can combine these to
+create the Unicode code point:
+
+    0b0000 0010    0b0000 1000    0b0000 0111
+    0b1110 xxxx    0b10yy yyyy    0b10zz zzzz
+
+Combining each section will require some bit shifting, but then they can just
+be OR'd together. They can also be XOR'd together which makes use of a single,
+COMMUTATIVE, operator through the entire calculation.
+
+      << 12 = 00000010
+      <<  6 =       00001000
+      <<  0 =             00000111
+        XOR = 00000010001000000111
+
+ code point = 0b0010 0010 0000 0111
+            = 0x2207
+
+And there we have it! The decoded UTF-8 character '∇'! And because the XOR
+operator is commutative, we can re-arrange all this XOR and shifting to create
+a single mask that can be applied to 3-byte UTF-8 characters after their bytes
+have been shifted and XOR'd together.
+ */
+
+// Mask used to remove byte headers from a 2 byte encoded UTF-8 character
+internal const val MASK_2BYTES = 0x0f80
+// MASK_2BYTES =
+//    (0xc0.toByte() shl 6) xor
+//    (0x80.toByte().toInt())
+
+internal inline fun ByteArray.process2Utf8Bytes(
+  beginIndex: Int,
+  endIndex: Int,
+  yield: (Int) -> Unit
+): Int {
+  if (endIndex <= beginIndex + 1) {
+    yield(REPLACEMENT_CODE_POINT)
+    // Only 1 byte remaining - underflow
+    return 1
+  }
+
+  val b0 = this[beginIndex]
+  val b1 = this[beginIndex + 1]
+  if (!isUtf8Continuation(b1)) {
+    yield(REPLACEMENT_CODE_POINT)
+    return 1
+  }
+
+  val codePoint =
+    (
+      MASK_2BYTES
+        xor (b1.toInt())
+        xor (b0.toInt() shl 6)
+      )
+
+  when {
+    codePoint < 0x80 -> {
+      yield(REPLACEMENT_CODE_POINT) // Reject overlong code points.
+    }
+    else -> {
+      yield(codePoint)
+    }
+  }
+  return 2
+}
+
+// Mask used to remove byte headers from a 3 byte encoded UTF-8 character
+internal const val MASK_3BYTES = -0x01e080
+// MASK_3BYTES =
+//    (0xe0.toByte() shl 12) xor
+//    (0x80.toByte() shl 6) xor
+//    (0x80.toByte().toInt())
+
+internal inline fun ByteArray.process3Utf8Bytes(
+  beginIndex: Int,
+  endIndex: Int,
+  yield: (Int) -> Unit
+): Int {
+  if (endIndex <= beginIndex + 2) {
+    // At least 2 bytes remaining
+    yield(REPLACEMENT_CODE_POINT)
+    if (endIndex <= beginIndex + 1 || !isUtf8Continuation(this[beginIndex + 1])) {
+      // Only 1 byte remaining - underflow
+      // Or 2nd byte is not a continuation - malformed
+      return 1
+    } else {
+      // Only 2 bytes remaining - underflow
+      return 2
+    }
+  }
+
+  val b0 = this[beginIndex]
+  val b1 = this[beginIndex + 1]
+  if (!isUtf8Continuation(b1)) {
+    yield(REPLACEMENT_CODE_POINT)
+    return 1
+  }
+  val b2 = this[beginIndex + 2]
+  if (!isUtf8Continuation(b2)) {
+    yield(REPLACEMENT_CODE_POINT)
+    return 2
+  }
+
+  val codePoint =
+    (
+      MASK_3BYTES
+        xor (b2.toInt())
+        xor (b1.toInt() shl 6)
+        xor (b0.toInt() shl 12)
+      )
+
+  when {
+    codePoint < 0x800 -> {
+      yield(REPLACEMENT_CODE_POINT) // Reject overlong code points.
+    }
+    codePoint in 0xd800..0xdfff -> {
+      yield(REPLACEMENT_CODE_POINT) // Reject partial surrogates.
+    }
+    else -> {
+      yield(codePoint)
+    }
+  }
+  return 3
+}
+
+// Mask used to remove byte headers from a 4 byte encoded UTF-8 character
+internal const val MASK_4BYTES = 0x381f80
+// MASK_4BYTES =
+//    (0xf0.toByte() shl 18) xor
+//    (0x80.toByte() shl 12) xor
+//    (0x80.toByte() shl 6) xor
+//    (0x80.toByte().toInt())
+
+internal inline fun ByteArray.process4Utf8Bytes(
+  beginIndex: Int,
+  endIndex: Int,
+  yield: (Int) -> Unit
+): Int {
+  if (endIndex <= beginIndex + 3) {
+    // At least 3 bytes remaining
+    yield(REPLACEMENT_CODE_POINT)
+    if (endIndex <= beginIndex + 1 || !isUtf8Continuation(this[beginIndex + 1])) {
+      // Only 1 byte remaining - underflow
+      // Or 2nd byte is not a continuation - malformed
+      return 1
+    } else if (endIndex <= beginIndex + 2 || !isUtf8Continuation(this[beginIndex + 2])) {
+      // Only 2 bytes remaining - underflow
+      // Or 3rd byte is not a continuation - malformed
+      return 2
+    } else {
+      // Only 3 bytes remaining - underflow
+      return 3
+    }
+  }
+
+  val b0 = this[beginIndex]
+  val b1 = this[beginIndex + 1]
+  if (!isUtf8Continuation(b1)) {
+    yield(REPLACEMENT_CODE_POINT)
+    return 1
+  }
+  val b2 = this[beginIndex + 2]
+  if (!isUtf8Continuation(b2)) {
+    yield(REPLACEMENT_CODE_POINT)
+    return 2
+  }
+  val b3 = this[beginIndex + 3]
+  if (!isUtf8Continuation(b3)) {
+    yield(REPLACEMENT_CODE_POINT)
+    return 3
+  }
+
+  val codePoint =
+    (
+      MASK_4BYTES
+        xor (b3.toInt())
+        xor (b2.toInt() shl 6)
+        xor (b1.toInt() shl 12)
+        xor (b0.toInt() shl 18)
+      )
+
+  when {
+    codePoint > 0x10ffff -> {
+      yield(REPLACEMENT_CODE_POINT) // Reject code points larger than the Unicode maximum.
+    }
+    codePoint in 0xd800..0xdfff -> {
+      yield(REPLACEMENT_CODE_POINT) // Reject partial surrogates.
+    }
+    codePoint < 0x10000 -> {
+      yield(REPLACEMENT_CODE_POINT) // Reject overlong code points.
+    }
+    else -> {
+      yield(codePoint)
+    }
+  }
+  return 4
+}
diff --git a/okio/src/commonMain/kotlin/okio/internal/-Utf8.kt b/okio/src/commonMain/kotlin/okio/internal/-Utf8.kt
new file mode 100644
index 0000000..926f185
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/internal/-Utf8.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2018 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 okio.internal
+
+import okio.ArrayIndexOutOfBoundsException
+import okio.processUtf16Chars
+import okio.processUtf8Bytes
+
+// TODO For benchmarking, these methods need to be available but preferably invisible
+// to everything else. Putting them in this file, `-Utf8.kt`, makes them invisible to
+// Java but still visible to Kotlin.
+
+fun ByteArray.commonToUtf8String(beginIndex: Int = 0, endIndex: Int = size): String {
+  if (beginIndex < 0 || endIndex > size || beginIndex > endIndex) {
+    throw ArrayIndexOutOfBoundsException("size=$size beginIndex=$beginIndex endIndex=$endIndex")
+  }
+  val chars = CharArray(endIndex - beginIndex)
+
+  var length = 0
+  processUtf16Chars(beginIndex, endIndex) { c ->
+    chars[length++] = c
+  }
+
+  return String(chars, 0, length)
+}
+
+fun String.commonAsUtf8ToByteArray(): ByteArray {
+  val bytes = ByteArray(4 * length)
+
+  // Assume ASCII until a UTF-8 code point is observed. This is ugly but yields
+  // about a 2x performance increase for pure ASCII.
+  for (index in 0 until length) {
+    val b0 = this[index]
+    if (b0 >= '\u0080') {
+      var size = index
+      processUtf8Bytes(index, length) { c ->
+        bytes[size++] = c
+      }
+      return bytes.copyOf(size)
+    }
+    bytes[index] = b0.toByte()
+  }
+
+  return bytes.copyOf(length)
+}
diff --git a/okio/src/commonMain/kotlin/okio/internal/Buffer.kt b/okio/src/commonMain/kotlin/okio/internal/Buffer.kt
new file mode 100644
index 0000000..0cb15cc
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/internal/Buffer.kt
@@ -0,0 +1,1688 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// TODO move to Buffer class: https://youtrack.jetbrains.com/issue/KT-20427
+@file:Suppress("NOTHING_TO_INLINE")
+
+package okio.internal
+
+import okio.ArrayIndexOutOfBoundsException
+import okio.Buffer
+import okio.Buffer.UnsafeCursor
+import okio.ByteString
+import okio.EOFException
+import okio.Options
+import okio.REPLACEMENT_CODE_POINT
+import okio.Segment
+import okio.SegmentPool
+import okio.SegmentedByteString
+import okio.Sink
+import okio.Source
+import okio.and
+import okio.asUtf8ToByteArray
+import okio.checkOffsetAndCount
+import okio.minOf
+import okio.toHexString
+
+internal val HEX_DIGIT_BYTES = "0123456789abcdef".asUtf8ToByteArray()
+
+// Threshold determined empirically via ReadByteStringBenchmark
+/** Create SegmentedByteString when size is greater than this many bytes.  */
+internal const val SEGMENTING_THRESHOLD = 4096
+
+/**
+ * Returns true if the range within this buffer starting at `segmentPos` in `segment` is equal to
+ * `bytes[bytesOffset..bytesLimit)`.
+ */
+internal fun rangeEquals(
+  segment: Segment,
+  segmentPos: Int,
+  bytes: ByteArray,
+  bytesOffset: Int,
+  bytesLimit: Int
+): Boolean {
+  var segment = segment
+  var segmentPos = segmentPos
+  var segmentLimit = segment.limit
+  var data = segment.data
+
+  var i = bytesOffset
+  while (i < bytesLimit) {
+    if (segmentPos == segmentLimit) {
+      segment = segment.next!!
+      data = segment.data
+      segmentPos = segment.pos
+      segmentLimit = segment.limit
+    }
+
+    if (data[segmentPos] != bytes[i]) {
+      return false
+    }
+
+    segmentPos++
+    i++
+  }
+
+  return true
+}
+
+internal fun Buffer.readUtf8Line(newline: Long): String {
+  return when {
+    newline > 0 && this[newline - 1] == '\r'.toByte() -> {
+      // Read everything until '\r\n', then skip the '\r\n'.
+      val result = readUtf8(newline - 1L)
+      skip(2L)
+      result
+    }
+    else -> {
+      // Read everything until '\n', then skip the '\n'.
+      val result = readUtf8(newline)
+      skip(1L)
+      result
+    }
+  }
+}
+
+/**
+ * Invoke `lambda` with the segment and offset at `fromIndex`. Searches from the front or the back
+ * depending on what's closer to `fromIndex`.
+ */
+internal inline fun <T> Buffer.seek(
+  fromIndex: Long,
+  lambda: (Segment?, Long) -> T
+): T {
+  var s: Segment = head ?: return lambda(null, -1L)
+
+  if (size - fromIndex < fromIndex) {
+    // We're scanning in the back half of this buffer. Find the segment starting at the back.
+    var offset = size
+    while (offset > fromIndex) {
+      s = s.prev!!
+      offset -= (s.limit - s.pos).toLong()
+    }
+    return lambda(s, offset)
+  } else {
+    // We're scanning in the front half of this buffer. Find the segment starting at the front.
+    var offset = 0L
+    while (true) {
+      val nextOffset = offset + (s.limit - s.pos)
+      if (nextOffset > fromIndex) break
+      s = s.next!!
+      offset = nextOffset
+    }
+    return lambda(s, offset)
+  }
+}
+
+/**
+ * Returns the index of a value in options that is a prefix of this buffer. Returns -1 if no value
+ * is found. This method does two simultaneous iterations: it iterates the trie and it iterates
+ * this buffer. It returns when it reaches a result in the trie, when it mismatches in the trie,
+ * and when the buffer is exhausted.
+ *
+ * @param selectTruncated true to return -2 if a possible result is present but truncated. For
+ *     example, this will return -2 if the buffer contains [ab] and the options are [abc, abd].
+ *     Note that this is made complicated by the fact that options are listed in preference order,
+ *     and one option may be a prefix of another. For example, this returns -2 if the buffer
+ *     contains [ab] and the options are [abc, a].
+ */
+internal fun Buffer.selectPrefix(options: Options, selectTruncated: Boolean = false): Int {
+  val head = head ?: return if (selectTruncated) -2 else -1
+
+  var s: Segment? = head
+  var data = head.data
+  var pos = head.pos
+  var limit = head.limit
+
+  val trie = options.trie
+  var triePos = 0
+
+  var prefixIndex = -1
+
+  navigateTrie@
+  while (true) {
+    val scanOrSelect = trie[triePos++]
+
+    val possiblePrefixIndex = trie[triePos++]
+    if (possiblePrefixIndex != -1) {
+      prefixIndex = possiblePrefixIndex
+    }
+
+    val nextStep: Int
+
+    if (s == null) {
+      break@navigateTrie
+    } else if (scanOrSelect < 0) {
+      // Scan: take multiple bytes from the buffer and the trie, looking for any mismatch.
+      val scanByteCount = -1 * scanOrSelect
+      val trieLimit = triePos + scanByteCount
+      while (true) {
+        val byte = data[pos++] and 0xff
+        if (byte != trie[triePos++]) return prefixIndex // Fail 'cause we found a mismatch.
+        val scanComplete = (triePos == trieLimit)
+
+        // Advance to the next buffer segment if this one is exhausted.
+        if (pos == limit) {
+          s = s!!.next!!
+          pos = s.pos
+          data = s.data
+          limit = s.limit
+          if (s === head) {
+            if (!scanComplete) break@navigateTrie // We were exhausted before the scan completed.
+            s = null // We were exhausted at the end of the scan.
+          }
+        }
+
+        if (scanComplete) {
+          nextStep = trie[triePos]
+          break
+        }
+      }
+    } else {
+      // Select: take one byte from the buffer and find a match in the trie.
+      val selectChoiceCount = scanOrSelect
+      val byte = data[pos++] and 0xff
+      val selectLimit = triePos + selectChoiceCount
+      while (true) {
+        if (triePos == selectLimit) return prefixIndex // Fail 'cause we didn't find a match.
+
+        if (byte == trie[triePos]) {
+          nextStep = trie[triePos + selectChoiceCount]
+          break
+        }
+
+        triePos++
+      }
+
+      // Advance to the next buffer segment if this one is exhausted.
+      if (pos == limit) {
+        s = s.next!!
+        pos = s.pos
+        data = s.data
+        limit = s.limit
+        if (s === head) {
+          s = null // No more segments! The next trie node will be our last.
+        }
+      }
+    }
+
+    if (nextStep >= 0) return nextStep // Found a matching option.
+    triePos = -nextStep // Found another node to continue the search.
+  }
+
+  // We break out of the loop above when we've exhausted the buffer without exhausting the trie.
+  if (selectTruncated) return -2 // The buffer is a prefix of at least one option.
+  return prefixIndex // Return any matches we encountered while searching for a deeper match.
+}
+
+// TODO Kotlin's expect classes can't have default implementations, so platform implementations
+// have to call these functions. Remove all this nonsense when expect class allow actual code.
+
+internal inline fun Buffer.commonCopyTo(
+  out: Buffer,
+  offset: Long,
+  byteCount: Long
+): Buffer {
+  var offset = offset
+  var byteCount = byteCount
+  checkOffsetAndCount(size, offset, byteCount)
+  if (byteCount == 0L) return this
+
+  out.size += byteCount
+
+  // Skip segments that we aren't copying from.
+  var s = head
+  while (offset >= s!!.limit - s.pos) {
+    offset -= (s.limit - s.pos).toLong()
+    s = s.next
+  }
+
+  // Copy one segment at a time.
+  while (byteCount > 0L) {
+    val copy = s!!.sharedCopy()
+    copy.pos += offset.toInt()
+    copy.limit = minOf(copy.pos + byteCount.toInt(), copy.limit)
+    if (out.head == null) {
+      copy.prev = copy
+      copy.next = copy.prev
+      out.head = copy.next
+    } else {
+      out.head!!.prev!!.push(copy)
+    }
+    byteCount -= (copy.limit - copy.pos).toLong()
+    offset = 0L
+    s = s.next
+  }
+
+  return this
+}
+
+internal inline fun Buffer.commonCompleteSegmentByteCount(): Long {
+  var result = size
+  if (result == 0L) return 0L
+
+  // Omit the tail if it's still writable.
+  val tail = head!!.prev!!
+  if (tail.limit < Segment.SIZE && tail.owner) {
+    result -= (tail.limit - tail.pos).toLong()
+  }
+
+  return result
+}
+
+internal inline fun Buffer.commonReadByte(): Byte {
+  if (size == 0L) throw EOFException()
+
+  val segment = head!!
+  var pos = segment.pos
+  val limit = segment.limit
+
+  val data = segment.data
+  val b = data[pos++]
+  size -= 1L
+
+  if (pos == limit) {
+    head = segment.pop()
+    SegmentPool.recycle(segment)
+  } else {
+    segment.pos = pos
+  }
+
+  return b
+}
+
+internal inline fun Buffer.commonReadShort(): Short {
+  if (size < 2L) throw EOFException()
+
+  val segment = head!!
+  var pos = segment.pos
+  val limit = segment.limit
+
+  // If the short is split across multiple segments, delegate to readByte().
+  if (limit - pos < 2) {
+    val s = readByte() and 0xff shl 8 or (readByte() and 0xff)
+    return s.toShort()
+  }
+
+  val data = segment.data
+  val s = data[pos++] and 0xff shl 8 or (data[pos++] and 0xff)
+  size -= 2L
+
+  if (pos == limit) {
+    head = segment.pop()
+    SegmentPool.recycle(segment)
+  } else {
+    segment.pos = pos
+  }
+
+  return s.toShort()
+}
+
+internal inline fun Buffer.commonReadInt(): Int {
+  if (size < 4L) throw EOFException()
+
+  val segment = head!!
+  var pos = segment.pos
+  val limit = segment.limit
+
+  // If the int is split across multiple segments, delegate to readByte().
+  if (limit - pos < 4L) {
+    return (
+      readByte() and 0xff shl 24
+        or (readByte() and 0xff shl 16)
+        or (readByte() and 0xff shl 8) // ktlint-disable no-multi-spaces
+        or (readByte() and 0xff)
+      )
+  }
+
+  val data = segment.data
+  val i = (
+    data[pos++] and 0xff shl 24
+      or (data[pos++] and 0xff shl 16)
+      or (data[pos++] and 0xff shl 8)
+      or (data[pos++] and 0xff)
+    )
+  size -= 4L
+
+  if (pos == limit) {
+    head = segment.pop()
+    SegmentPool.recycle(segment)
+  } else {
+    segment.pos = pos
+  }
+
+  return i
+}
+
+internal inline fun Buffer.commonReadLong(): Long {
+  if (size < 8L) throw EOFException()
+
+  val segment = head!!
+  var pos = segment.pos
+  val limit = segment.limit
+
+  // If the long is split across multiple segments, delegate to readInt().
+  if (limit - pos < 8L) {
+    return (
+      readInt() and 0xffffffffL shl 32
+        or (readInt() and 0xffffffffL)
+      )
+  }
+
+  val data = segment.data
+  val v = (
+    data[pos++] and 0xffL shl 56
+      or (data[pos++] and 0xffL shl 48)
+      or (data[pos++] and 0xffL shl 40)
+      or (data[pos++] and 0xffL shl 32)
+      or (data[pos++] and 0xffL shl 24)
+      or (data[pos++] and 0xffL shl 16)
+      or (data[pos++] and 0xffL shl 8) // ktlint-disable no-multi-spaces
+      or (data[pos++] and 0xffL)
+    )
+  size -= 8L
+
+  if (pos == limit) {
+    head = segment.pop()
+    SegmentPool.recycle(segment)
+  } else {
+    segment.pos = pos
+  }
+
+  return v
+}
+
+internal inline fun Buffer.commonGet(pos: Long): Byte {
+  checkOffsetAndCount(size, pos, 1L)
+  seek(pos) { s, offset ->
+    return s!!.data[(s.pos + pos - offset).toInt()]
+  }
+}
+
+internal inline fun Buffer.commonClear() = skip(size)
+
+internal inline fun Buffer.commonSkip(byteCount: Long) {
+  var byteCount = byteCount
+  while (byteCount > 0) {
+    val head = this.head ?: throw EOFException()
+
+    val toSkip = minOf(byteCount, head.limit - head.pos).toInt()
+    size -= toSkip.toLong()
+    byteCount -= toSkip.toLong()
+    head.pos += toSkip
+
+    if (head.pos == head.limit) {
+      this.head = head.pop()
+      SegmentPool.recycle(head)
+    }
+  }
+}
+
+internal inline fun Buffer.commonWrite(
+  byteString: ByteString,
+  offset: Int = 0,
+  byteCount: Int = byteString.size
+): Buffer {
+  byteString.write(this, offset, byteCount)
+  return this
+}
+
+internal inline fun Buffer.commonWriteDecimalLong(v: Long): Buffer {
+  var v = v
+  if (v == 0L) {
+    // Both a shortcut and required since the following code can't handle zero.
+    return writeByte('0'.toInt())
+  }
+
+  var negative = false
+  if (v < 0L) {
+    v = -v
+    if (v < 0L) { // Only true for Long.MIN_VALUE.
+      return writeUtf8("-9223372036854775808")
+    }
+    negative = true
+  }
+
+  // Binary search for character width which favors matching lower numbers.
+  var width =
+    if (v < 100000000L)
+      if (v < 10000L)
+        if (v < 100L)
+          if (v < 10L) 1
+          else 2
+        else if (v < 1000L) 3
+        else 4
+      else if (v < 1000000L)
+        if (v < 100000L) 5
+        else 6
+      else if (v < 10000000L) 7
+      else 8
+    else if (v < 1000000000000L)
+      if (v < 10000000000L)
+        if (v < 1000000000L) 9
+        else 10
+      else if (v < 100000000000L) 11
+      else 12
+    else if (v < 1000000000000000L)
+      if (v < 10000000000000L) 13
+      else if (v < 100000000000000L) 14
+      else 15
+    else if (v < 100000000000000000L)
+      if (v < 10000000000000000L) 16
+      else 17
+    else if (v < 1000000000000000000L) 18
+    else 19
+  if (negative) {
+    ++width
+  }
+
+  val tail = writableSegment(width)
+  val data = tail.data
+  var pos = tail.limit + width // We write backwards from right to left.
+  while (v != 0L) {
+    val digit = (v % 10).toInt()
+    data[--pos] = HEX_DIGIT_BYTES[digit]
+    v /= 10
+  }
+  if (negative) {
+    data[--pos] = '-'.toByte()
+  }
+
+  tail.limit += width
+  this.size += width.toLong()
+  return this
+}
+
+internal inline fun Buffer.commonWriteHexadecimalUnsignedLong(v: Long): Buffer {
+  var v = v
+  if (v == 0L) {
+    // Both a shortcut and required since the following code can't handle zero.
+    return writeByte('0'.toInt())
+  }
+
+  // Mask every bit below the most significant bit to a 1
+  // http://aggregate.org/MAGIC/#Most%20Significant%201%20Bit
+  var x = v
+  x = x or (x ushr 1)
+  x = x or (x ushr 2)
+  x = x or (x ushr 4)
+  x = x or (x ushr 8)
+  x = x or (x ushr 16)
+  x = x or (x ushr 32)
+
+  // Count the number of 1s
+  // http://aggregate.org/MAGIC/#Population%20Count%20(Ones%20Count)
+  x -= x ushr 1 and 0x5555555555555555
+  x = (x ushr 2 and 0x3333333333333333) + (x and 0x3333333333333333)
+  x = (x ushr 4) + x and 0x0f0f0f0f0f0f0f0f
+  x += x ushr 8
+  x += x ushr 16
+  x = (x and 0x3f) + ((x ushr 32) and 0x3f)
+
+  // Round up to the nearest full byte
+  val width = ((x + 3) / 4).toInt()
+
+  val tail = writableSegment(width)
+  val data = tail.data
+  var pos = tail.limit + width - 1
+  val start = tail.limit
+  while (pos >= start) {
+    data[pos] = HEX_DIGIT_BYTES[(v and 0xF).toInt()]
+    v = v ushr 4
+    pos--
+  }
+  tail.limit += width
+  size += width.toLong()
+  return this
+}
+
+internal inline fun Buffer.commonWritableSegment(minimumCapacity: Int): Segment {
+  require(minimumCapacity >= 1 && minimumCapacity <= Segment.SIZE) { "unexpected capacity" }
+
+  if (head == null) {
+    val result = SegmentPool.take() // Acquire a first segment.
+    head = result
+    result.prev = result
+    result.next = result
+    return result
+  }
+
+  var 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
+}
+
+internal inline fun Buffer.commonWrite(source: ByteArray) = write(source, 0, source.size)
+
+internal inline fun Buffer.commonWrite(
+  source: ByteArray,
+  offset: Int,
+  byteCount: Int
+): Buffer {
+  var offset = offset
+  checkOffsetAndCount(source.size.toLong(), offset.toLong(), byteCount.toLong())
+
+  val limit = offset + byteCount
+  while (offset < limit) {
+    val tail = writableSegment(1)
+
+    val toCopy = minOf(limit - offset, Segment.SIZE - tail.limit)
+    source.copyInto(
+      destination = tail.data,
+      destinationOffset = tail.limit,
+      startIndex = offset,
+      endIndex = offset + toCopy
+    )
+
+    offset += toCopy
+    tail.limit += toCopy
+  }
+
+  size += byteCount.toLong()
+  return this
+}
+
+internal inline fun Buffer.commonReadByteArray() = readByteArray(size)
+
+internal inline fun Buffer.commonReadByteArray(byteCount: Long): ByteArray {
+  require(byteCount >= 0 && byteCount <= Int.MAX_VALUE) { "byteCount: $byteCount" }
+  if (size < byteCount) throw EOFException()
+
+  val result = ByteArray(byteCount.toInt())
+  readFully(result)
+  return result
+}
+
+internal inline fun Buffer.commonRead(sink: ByteArray) = read(sink, 0, sink.size)
+
+internal inline fun Buffer.commonReadFully(sink: ByteArray) {
+  var offset = 0
+  while (offset < sink.size) {
+    val read = read(sink, offset, sink.size - offset)
+    if (read == -1) throw EOFException()
+    offset += read
+  }
+}
+
+internal inline fun Buffer.commonRead(sink: ByteArray, offset: Int, byteCount: Int): Int {
+  checkOffsetAndCount(sink.size.toLong(), offset.toLong(), byteCount.toLong())
+
+  val s = head ?: return -1
+  val toCopy = minOf(byteCount, s.limit - s.pos)
+  s.data.copyInto(
+    destination = sink, destinationOffset = offset, startIndex = s.pos, endIndex = s.pos + toCopy
+  )
+
+  s.pos += toCopy
+  size -= toCopy.toLong()
+
+  if (s.pos == s.limit) {
+    head = s.pop()
+    SegmentPool.recycle(s)
+  }
+
+  return toCopy
+}
+
+internal const val OVERFLOW_ZONE = Long.MIN_VALUE / 10L
+internal const val OVERFLOW_DIGIT_START = Long.MIN_VALUE % 10L + 1
+
+internal inline fun Buffer.commonReadDecimalLong(): Long {
+  if (size == 0L) throw EOFException()
+
+  // This value is always built negatively in order to accommodate Long.MIN_VALUE.
+  var value = 0L
+  var seen = 0
+  var negative = false
+  var done = false
+
+  var overflowDigit = OVERFLOW_DIGIT_START
+
+  do {
+    val segment = head!!
+
+    val data = segment.data
+    var pos = segment.pos
+    val limit = segment.limit
+
+    while (pos < limit) {
+      val b = data[pos]
+      if (b >= '0'.toByte() && b <= '9'.toByte()) {
+        val digit = '0'.toByte() - b
+
+        // Detect when the digit would cause an overflow.
+        if (value < OVERFLOW_ZONE || value == OVERFLOW_ZONE && digit < overflowDigit) {
+          val buffer = Buffer().writeDecimalLong(value).writeByte(b.toInt())
+          if (!negative) buffer.readByte() // Skip negative sign.
+          throw NumberFormatException("Number too large: ${buffer.readUtf8()}")
+        }
+        value *= 10L
+        value += digit.toLong()
+      } else if (b == '-'.toByte() && seen == 0) {
+        negative = true
+        overflowDigit -= 1
+      } else {
+        if (seen == 0) {
+          throw NumberFormatException(
+            "Expected leading [0-9] or '-' character but was 0x${b.toHexString()}"
+          )
+        }
+        // Set a flag to stop iteration. We still need to run through segment updating below.
+        done = true
+        break
+      }
+      pos++
+      seen++
+    }
+
+    if (pos == limit) {
+      head = segment.pop()
+      SegmentPool.recycle(segment)
+    } else {
+      segment.pos = pos
+    }
+  } while (!done && head != null)
+
+  size -= seen.toLong()
+  return if (negative) value else -value
+}
+
+internal inline fun Buffer.commonReadHexadecimalUnsignedLong(): Long {
+  if (size == 0L) throw EOFException()
+
+  var value = 0L
+  var seen = 0
+  var done = false
+
+  do {
+    val segment = head!!
+
+    val data = segment.data
+    var pos = segment.pos
+    val limit = segment.limit
+
+    while (pos < limit) {
+      val digit: Int
+
+      val b = data[pos]
+      if (b >= '0'.toByte() && b <= '9'.toByte()) {
+        digit = b - '0'.toByte()
+      } else if (b >= 'a'.toByte() && b <= 'f'.toByte()) {
+        digit = b - 'a'.toByte() + 10
+      } else if (b >= 'A'.toByte() && b <= 'F'.toByte()) {
+        digit = b - 'A'.toByte() + 10 // We never write uppercase, but we support reading it.
+      } else {
+        if (seen == 0) {
+          throw NumberFormatException(
+            "Expected leading [0-9a-fA-F] character but was 0x${b.toHexString()}"
+          )
+        }
+        // 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 and -0x1000000000000000L != 0L) {
+        val buffer = Buffer().writeHexadecimalUnsignedLong(value).writeByte(b.toInt())
+        throw NumberFormatException("Number too large: " + buffer.readUtf8())
+      }
+
+      value = value shl 4
+      value = value or digit.toLong()
+      pos++
+      seen++
+    }
+
+    if (pos == limit) {
+      head = segment.pop()
+      SegmentPool.recycle(segment)
+    } else {
+      segment.pos = pos
+    }
+  } while (!done && head != null)
+
+  size -= seen.toLong()
+  return value
+}
+
+internal inline fun Buffer.commonReadByteString(): ByteString = readByteString(size)
+
+internal inline fun Buffer.commonReadByteString(byteCount: Long): ByteString {
+  require(byteCount >= 0 && byteCount <= Int.MAX_VALUE) { "byteCount: $byteCount" }
+  if (size < byteCount) throw EOFException()
+
+  if (byteCount >= SEGMENTING_THRESHOLD) {
+    return snapshot(byteCount.toInt()).also { skip(byteCount) }
+  } else {
+    return ByteString(readByteArray(byteCount))
+  }
+}
+
+internal inline fun Buffer.commonSelect(options: Options): Int {
+  val index = selectPrefix(options)
+  if (index == -1) return -1
+
+  // If the prefix match actually matched a full byte string, consume it and return it.
+  val selectedSize = options.byteStrings[index].size
+  skip(selectedSize.toLong())
+  return index
+}
+
+internal inline fun Buffer.commonReadFully(sink: Buffer, byteCount: Long) {
+  if (size < byteCount) {
+    sink.write(this, size) // Exhaust ourselves.
+    throw EOFException()
+  }
+  sink.write(this, byteCount)
+}
+
+internal inline fun Buffer.commonReadAll(sink: Sink): Long {
+  val byteCount = size
+  if (byteCount > 0L) {
+    sink.write(this, byteCount)
+  }
+  return byteCount
+}
+
+internal inline fun Buffer.commonReadUtf8(byteCount: Long): String {
+  require(byteCount >= 0 && byteCount <= Int.MAX_VALUE) { "byteCount: $byteCount" }
+  if (size < byteCount) throw EOFException()
+  if (byteCount == 0L) return ""
+
+  val s = head!!
+  if (s.pos + byteCount > s.limit) {
+    // If the string spans multiple segments, delegate to readBytes().
+
+    return readByteArray(byteCount).commonToUtf8String()
+  }
+
+  val result = s.data.commonToUtf8String(s.pos, s.pos + byteCount.toInt())
+  s.pos += byteCount.toInt()
+  size -= byteCount
+
+  if (s.pos == s.limit) {
+    head = s.pop()
+    SegmentPool.recycle(s)
+  }
+
+  return result
+}
+
+internal inline fun Buffer.commonReadUtf8Line(): String? {
+  val newline = indexOf('\n'.toByte())
+
+  return when {
+    newline != -1L -> readUtf8Line(newline)
+    size != 0L -> readUtf8(size)
+    else -> null
+  }
+}
+
+internal inline fun Buffer.commonReadUtf8LineStrict(limit: Long): String {
+  require(limit >= 0L) { "limit < 0: $limit" }
+  val scanLength = if (limit == Long.MAX_VALUE) Long.MAX_VALUE else limit + 1L
+  val newline = indexOf('\n'.toByte(), 0L, scanLength)
+  if (newline != -1L) return readUtf8Line(newline)
+  if (scanLength < size &&
+    this[scanLength - 1] == '\r'.toByte() &&
+    this[scanLength] == '\n'.toByte()
+  ) {
+    return readUtf8Line(scanLength) // The line was 'limit' UTF-8 bytes followed by \r\n.
+  }
+  val data = Buffer()
+  copyTo(data, 0, minOf(32, size))
+  throw EOFException(
+    "\\n not found: limit=${minOf(
+      size,
+      limit
+    )} content=${data.readByteString().hex()}${'…'}"
+  )
+}
+
+internal inline fun Buffer.commonReadUtf8CodePoint(): Int {
+  if (size == 0L) throw EOFException()
+
+  val b0 = this[0]
+  var codePoint: Int
+  val byteCount: Int
+  val min: Int
+
+  when {
+    b0 and 0x80 == 0 -> {
+      // 0xxxxxxx.
+      codePoint = b0 and 0x7f
+      byteCount = 1 // 7 bits (ASCII).
+      min = 0x0
+    }
+    b0 and 0xe0 == 0xc0 -> {
+      // 0x110xxxxx
+      codePoint = b0 and 0x1f
+      byteCount = 2 // 11 bits (5 + 6).
+      min = 0x80
+    }
+    b0 and 0xf0 == 0xe0 -> {
+      // 0x1110xxxx
+      codePoint = b0 and 0x0f
+      byteCount = 3 // 16 bits (4 + 6 + 6).
+      min = 0x800
+    }
+    b0 and 0xf8 == 0xf0 -> {
+      // 0x11110xxx
+      codePoint = b0 and 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_CODE_POINT
+    }
+  }
+
+  if (size < byteCount) {
+    throw EOFException("size < $byteCount: $size (to read code point prefixed 0x${b0.toHexString()})")
+  }
+
+  // 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 (i in 1 until byteCount) {
+    val b = this[i.toLong()]
+    if (b and 0xc0 == 0x80) {
+      // 0x10xxxxxx
+      codePoint = codePoint shl 6
+      codePoint = codePoint or (b and 0x3f)
+    } else {
+      skip(i.toLong())
+      return REPLACEMENT_CODE_POINT
+    }
+  }
+
+  skip(byteCount.toLong())
+
+  return when {
+    codePoint > 0x10ffff -> {
+      REPLACEMENT_CODE_POINT // Reject code points larger than the Unicode maximum.
+    }
+    codePoint in 0xd800..0xdfff -> {
+      REPLACEMENT_CODE_POINT // Reject partial surrogates.
+    }
+    codePoint < min -> {
+      REPLACEMENT_CODE_POINT // Reject overlong code points.
+    }
+    else -> codePoint
+  }
+}
+
+internal inline fun Buffer.commonWriteUtf8(string: String, beginIndex: Int, endIndex: Int): Buffer {
+  require(beginIndex >= 0) { "beginIndex < 0: $beginIndex" }
+  require(endIndex >= beginIndex) { "endIndex < beginIndex: $endIndex < $beginIndex" }
+  require(endIndex <= string.length) { "endIndex > string.length: $endIndex > ${string.length}" }
+
+  // Transcode a UTF-16 Java String to UTF-8 bytes.
+  var i = beginIndex
+  while (i < endIndex) {
+    var c = string[i].toInt()
+
+    when {
+      c < 0x80 -> {
+        val tail = writableSegment(1)
+        val data = tail.data
+        val segmentOffset = tail.limit - i
+        val runLimit = minOf(endIndex, Segment.SIZE - segmentOffset)
+
+        // Emit a 7-bit character with 1 byte.
+        data[segmentOffset + i++] = c.toByte() // 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[i].toInt()
+          if (c >= 0x80) break
+          data[segmentOffset + i++] = c.toByte() // 0xxxxxxx
+        }
+
+        val runSize = i + segmentOffset - tail.limit // Equivalent to i - (previous i).
+        tail.limit += runSize
+        size += runSize.toLong()
+      }
+
+      c < 0x800 -> {
+        // Emit a 11-bit character with 2 bytes.
+        val tail = writableSegment(2)
+        /* ktlint-disable no-multi-spaces */
+        tail.data[tail.limit    ] = (c shr 6          or 0xc0).toByte() // 110xxxxx
+        tail.data[tail.limit + 1] = (c       and 0x3f or 0x80).toByte() // 10xxxxxx
+        /* ktlint-enable no-multi-spaces */
+        tail.limit += 2
+        size += 2L
+        i++
+      }
+
+      c < 0xd800 || c > 0xdfff -> {
+        // Emit a 16-bit character with 3 bytes.
+        val tail = writableSegment(3)
+        /* ktlint-disable no-multi-spaces */
+        tail.data[tail.limit    ] = (c shr 12          or 0xe0).toByte() // 1110xxxx
+        tail.data[tail.limit + 1] = (c shr  6 and 0x3f or 0x80).toByte() // 10xxxxxx
+        tail.data[tail.limit + 2] = (c        and 0x3f or 0x80).toByte() // 10xxxxxx
+        /* ktlint-enable no-multi-spaces */
+        tail.limit += 3
+        size += 3L
+        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.
+        val low = (if (i + 1 < endIndex) string[i + 1].toInt() else 0)
+        if (c > 0xdbff || low !in 0xdc00..0xdfff) {
+          writeByte('?'.toInt())
+          i++
+        } else {
+          // UTF-16 high surrogate: 110110xxxxxxxxxx (10 bits)
+          // UTF-16 low surrogate:  110111yyyyyyyyyy (10 bits)
+          // Unicode code point:    00010000000000000000 + xxxxxxxxxxyyyyyyyyyy (21 bits)
+          val codePoint = 0x010000 + (c and 0x03ff shl 10 or (low and 0x03ff))
+
+          // Emit a 21-bit character with 4 bytes.
+          val tail = writableSegment(4)
+          /* ktlint-disable no-multi-spaces */
+          tail.data[tail.limit    ] = (codePoint shr 18          or 0xf0).toByte() // 11110xxx
+          tail.data[tail.limit + 1] = (codePoint shr 12 and 0x3f or 0x80).toByte() // 10xxxxxx
+          tail.data[tail.limit + 2] = (codePoint shr  6 and 0x3f or 0x80).toByte() // 10xxyyyy
+          tail.data[tail.limit + 3] = (codePoint        and 0x3f or 0x80).toByte() // 10yyyyyy
+          /* ktlint-enable no-multi-spaces */
+          tail.limit += 4
+          size += 4L
+          i += 2
+        }
+      }
+    }
+  }
+
+  return this
+}
+
+internal inline fun Buffer.commonWriteUtf8CodePoint(codePoint: Int): Buffer {
+  when {
+    codePoint < 0x80 -> {
+      // Emit a 7-bit code point with 1 byte.
+      writeByte(codePoint)
+    }
+    codePoint < 0x800 -> {
+      // Emit a 11-bit code point with 2 bytes.
+      val tail = writableSegment(2)
+      /* ktlint-disable no-multi-spaces */
+      tail.data[tail.limit    ] = (codePoint shr 6          or 0xc0).toByte() // 110xxxxx
+      tail.data[tail.limit + 1] = (codePoint       and 0x3f or 0x80).toByte() // 10xxxxxx
+      /* ktlint-enable no-multi-spaces */
+      tail.limit += 2
+      size += 2L
+    }
+    codePoint in 0xd800..0xdfff -> {
+      // Emit a replacement character for a partial surrogate.
+      writeByte('?'.toInt())
+    }
+    codePoint < 0x10000 -> {
+      // Emit a 16-bit code point with 3 bytes.
+      val tail = writableSegment(3)
+      /* ktlint-disable no-multi-spaces */
+      tail.data[tail.limit    ] = (codePoint shr 12          or 0xe0).toByte() // 1110xxxx
+      tail.data[tail.limit + 1] = (codePoint shr  6 and 0x3f or 0x80).toByte() // 10xxxxxx
+      tail.data[tail.limit + 2] = (codePoint        and 0x3f or 0x80).toByte() // 10xxxxxx
+      /* ktlint-enable no-multi-spaces */
+      tail.limit += 3
+      size += 3L
+    }
+    codePoint <= 0x10ffff -> {
+      // Emit a 21-bit code point with 4 bytes.
+      val tail = writableSegment(4)
+      /* ktlint-disable no-multi-spaces */
+      tail.data[tail.limit    ] = (codePoint shr 18          or 0xf0).toByte() // 11110xxx
+      tail.data[tail.limit + 1] = (codePoint shr 12 and 0x3f or 0x80).toByte() // 10xxxxxx
+      tail.data[tail.limit + 2] = (codePoint shr  6 and 0x3f or 0x80).toByte() // 10xxyyyy
+      tail.data[tail.limit + 3] = (codePoint        and 0x3f or 0x80).toByte() // 10yyyyyy
+      /* ktlint-enable no-multi-spaces */
+      tail.limit += 4
+      size += 4L
+    }
+    else -> {
+      throw IllegalArgumentException("Unexpected code point: 0x${codePoint.toHexString()}")
+    }
+  }
+
+  return this
+}
+
+internal inline fun Buffer.commonWriteAll(source: Source): Long {
+  var totalBytesRead = 0L
+  while (true) {
+    val readCount = source.read(this, Segment.SIZE.toLong())
+    if (readCount == -1L) break
+    totalBytesRead += readCount
+  }
+  return totalBytesRead
+}
+
+internal inline fun Buffer.commonWrite(source: Source, byteCount: Long): Buffer {
+  var byteCount = byteCount
+  while (byteCount > 0L) {
+    val read = source.read(this, byteCount)
+    if (read == -1L) throw EOFException()
+    byteCount -= read
+  }
+  return this
+}
+
+internal inline fun Buffer.commonWriteByte(b: Int): Buffer {
+  val tail = writableSegment(1)
+  tail.data[tail.limit++] = b.toByte()
+  size += 1L
+  return this
+}
+
+internal inline fun Buffer.commonWriteShort(s: Int): Buffer {
+  val tail = writableSegment(2)
+  val data = tail.data
+  var limit = tail.limit
+  data[limit++] = (s ushr 8 and 0xff).toByte()
+  data[limit++] = (s        and 0xff).toByte() // ktlint-disable no-multi-spaces
+  tail.limit = limit
+  size += 2L
+  return this
+}
+
+internal inline fun Buffer.commonWriteInt(i: Int): Buffer {
+  val tail = writableSegment(4)
+  val data = tail.data
+  var limit = tail.limit
+  data[limit++] = (i ushr 24 and 0xff).toByte()
+  data[limit++] = (i ushr 16 and 0xff).toByte()
+  data[limit++] = (i ushr  8 and 0xff).toByte() // ktlint-disable no-multi-spaces
+  data[limit++] = (i         and 0xff).toByte() // ktlint-disable no-multi-spaces
+  tail.limit = limit
+  size += 4L
+  return this
+}
+
+internal inline fun Buffer.commonWriteLong(v: Long): Buffer {
+  val tail = writableSegment(8)
+  val data = tail.data
+  var limit = tail.limit
+  data[limit++] = (v ushr 56 and 0xffL).toByte()
+  data[limit++] = (v ushr 48 and 0xffL).toByte()
+  data[limit++] = (v ushr 40 and 0xffL).toByte()
+  data[limit++] = (v ushr 32 and 0xffL).toByte()
+  data[limit++] = (v ushr 24 and 0xffL).toByte()
+  data[limit++] = (v ushr 16 and 0xffL).toByte()
+  data[limit++] = (v ushr  8 and 0xffL).toByte() // ktlint-disable no-multi-spaces
+  data[limit++] = (v         and 0xffL).toByte() // ktlint-disable no-multi-spaces
+  tail.limit = limit
+  size += 8L
+  return this
+}
+
+internal inline fun Buffer.commonWrite(source: Buffer, byteCount: Long) {
+  var byteCount = 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%].
+
+  require(source !== this) { "source == this" }
+  checkOffsetAndCount(source.size, 0, byteCount)
+
+  while (byteCount > 0L) {
+    // Is a prefix of the source's head segment all that we need to move?
+    if (byteCount < source.head!!.limit - source.head!!.pos) {
+      val tail = if (head != null) head!!.prev else null
+      if (tail != null && tail.owner &&
+        byteCount + tail.limit - (if (tail.shared) 0 else tail.pos) <= Segment.SIZE
+      ) {
+        // Our existing segments are sufficient. Move bytes from source's head to our tail.
+        source.head!!.writeTo(tail, byteCount.toInt())
+        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(byteCount.toInt())
+      }
+    }
+
+    // Remove the source's head segment and append it to our tail.
+    val segmentToMove = source.head
+    val movedByteCount = (segmentToMove!!.limit - segmentToMove.pos).toLong()
+    source.head = segmentToMove.pop()
+    if (head == null) {
+      head = segmentToMove
+      segmentToMove.prev = segmentToMove
+      segmentToMove.next = segmentToMove.prev
+    } else {
+      var tail = head!!.prev
+      tail = tail!!.push(segmentToMove)
+      tail.compact()
+    }
+    source.size -= movedByteCount
+    size += movedByteCount
+    byteCount -= movedByteCount
+  }
+}
+
+internal inline fun Buffer.commonRead(sink: Buffer, byteCount: Long): Long {
+  var byteCount = byteCount
+  require(byteCount >= 0L) { "byteCount < 0: $byteCount" }
+  if (size == 0L) return -1L
+  if (byteCount > size) byteCount = size
+  sink.write(this, byteCount)
+  return byteCount
+}
+
+internal inline fun Buffer.commonIndexOf(b: Byte, fromIndex: Long, toIndex: Long): Long {
+  var fromIndex = fromIndex
+  var toIndex = toIndex
+  require(fromIndex in 0..toIndex) { "size=$size fromIndex=$fromIndex toIndex=$toIndex" }
+
+  if (toIndex > size) toIndex = size
+  if (fromIndex == toIndex) return -1L
+
+  seek(fromIndex) { s, offset ->
+    var s = s ?: return -1L
+    var offset = offset
+
+    // Scan through the segments, searching for b.
+    while (offset < toIndex) {
+      val data = s.data
+      val limit = minOf(s.limit.toLong(), s.pos + toIndex - offset).toInt()
+      var pos = (s.pos + fromIndex - offset).toInt()
+      while (pos < limit) {
+        if (data[pos] == b) {
+          return pos - s.pos + offset
+        }
+        pos++
+      }
+
+      // Not in this segment. Try the next one.
+      offset += (s.limit - s.pos).toLong()
+      fromIndex = offset
+      s = s.next!!
+    }
+
+    return -1L
+  }
+}
+
+internal inline fun Buffer.commonIndexOf(bytes: ByteString, fromIndex: Long): Long {
+  var fromIndex = fromIndex
+  require(bytes.size > 0) { "bytes is empty" }
+  require(fromIndex >= 0L) { "fromIndex < 0: $fromIndex" }
+
+  seek(fromIndex) { s, offset ->
+    var s = s ?: return -1L
+    var offset = offset
+
+    // Scan through the segments, searching for the lead byte. Each time that is found, delegate
+    // to rangeEquals() to check for a complete match.
+    val targetByteArray = bytes.internalArray()
+    val b0 = targetByteArray[0]
+    val bytesSize = bytes.size
+    val resultLimit = size - bytesSize + 1L
+    while (offset < resultLimit) {
+      // Scan through the current segment.
+      val data = s.data
+      val segmentLimit = okio.minOf(s.limit, s.pos + resultLimit - offset).toInt()
+      for (pos in (s.pos + fromIndex - offset).toInt() until segmentLimit) {
+        if (data[pos] == b0 && rangeEquals(s, pos + 1, targetByteArray, 1, bytesSize)) {
+          return pos - s.pos + offset
+        }
+      }
+
+      // Not in this segment. Try the next one.
+      offset += (s.limit - s.pos).toLong()
+      fromIndex = offset
+      s = s.next!!
+    }
+
+    return -1L
+  }
+}
+
+internal inline fun Buffer.commonIndexOfElement(targetBytes: ByteString, fromIndex: Long): Long {
+  var fromIndex = fromIndex
+  require(fromIndex >= 0L) { "fromIndex < 0: $fromIndex" }
+
+  seek(fromIndex) { s, offset ->
+    var s = s ?: return -1L
+    var offset = offset
+
+    // Special case searching for one of two bytes. This is a common case for tools like Moshi,
+    // which search for pairs of chars like `\r` and `\n` or {@code `"` and `\`. The impact of this
+    // optimization is a ~5x speedup for this case without a substantial cost to other cases.
+    if (targetBytes.size == 2) {
+      // Scan through the segments, searching for either of the two bytes.
+      val b0 = targetBytes[0]
+      val b1 = targetBytes[1]
+      while (offset < size) {
+        val data = s.data
+        var pos = (s.pos + fromIndex - offset).toInt()
+        val limit = s.limit
+        while (pos < limit) {
+          val b = data[pos].toInt()
+          if (b == b0.toInt() || b == b1.toInt()) {
+            return pos - s.pos + offset
+          }
+          pos++
+        }
+
+        // Not in this segment. Try the next one.
+        offset += (s.limit - s.pos).toLong()
+        fromIndex = offset
+        s = s.next!!
+      }
+    } else {
+      // Scan through the segments, searching for a byte that's also in the array.
+      val targetByteArray = targetBytes.internalArray()
+      while (offset < size) {
+        val data = s.data
+        var pos = (s.pos + fromIndex - offset).toInt()
+        val limit = s.limit
+        while (pos < limit) {
+          val b = data[pos].toInt()
+          for (t in targetByteArray) {
+            if (b == t.toInt()) return pos - s.pos + offset
+          }
+          pos++
+        }
+
+        // Not in this segment. Try the next one.
+        offset += (s.limit - s.pos).toLong()
+        fromIndex = offset
+        s = s.next!!
+      }
+    }
+
+    return -1L
+  }
+}
+
+internal inline fun Buffer.commonRangeEquals(
+  offset: Long,
+  bytes: ByteString,
+  bytesOffset: Int,
+  byteCount: Int
+): Boolean {
+  if (offset < 0L ||
+    bytesOffset < 0 ||
+    byteCount < 0 ||
+    size - offset < byteCount ||
+    bytes.size - bytesOffset < byteCount
+  ) {
+    return false
+  }
+  for (i in 0 until byteCount) {
+    if (this[offset + i] != bytes[bytesOffset + i]) {
+      return false
+    }
+  }
+  return true
+}
+
+internal inline fun Buffer.commonEquals(other: Any?): Boolean {
+  if (this === other) return true
+  if (other !is Buffer) return false
+  if (size != other.size) return false
+  if (size == 0L) return true // Both buffers are empty.
+
+  var sa = this.head!!
+  var sb = other.head!!
+  var posA = sa.pos
+  var posB = sb.pos
+
+  var pos = 0L
+  var count: Long
+  while (pos < size) {
+    count = minOf(sa.limit - posA, sb.limit - posB).toLong()
+
+    for (i in 0L until count) {
+      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
+    }
+    pos += count
+  }
+
+  return true
+}
+
+internal inline fun Buffer.commonHashCode(): Int {
+  var s = head ?: return 0
+  var result = 1
+  do {
+    var pos = s.pos
+    val limit = s.limit
+    while (pos < limit) {
+      result = 31 * result + s.data[pos]
+      pos++
+    }
+    s = s.next!!
+  } while (s !== head)
+  return result
+}
+
+internal inline fun Buffer.commonCopy(): Buffer {
+  val result = Buffer()
+  if (size == 0L) return result
+
+  val head = head!!
+  val headCopy = head.sharedCopy()
+
+  result.head = headCopy
+  headCopy.prev = result.head
+  headCopy.next = headCopy.prev
+
+  var s = head.next
+  while (s !== head) {
+    headCopy.prev!!.push(s!!.sharedCopy())
+    s = s.next
+  }
+
+  result.size = size
+  return result
+}
+
+/** Returns an immutable copy of this buffer as a byte string.  */
+internal inline fun Buffer.commonSnapshot(): ByteString {
+  check(size <= Int.MAX_VALUE) { "size > Int.MAX_VALUE: $size" }
+  return snapshot(size.toInt())
+}
+
+/** Returns an immutable copy of the first `byteCount` bytes of this buffer as a byte string. */
+internal inline fun Buffer.commonSnapshot(byteCount: Int): ByteString {
+  if (byteCount == 0) return ByteString.EMPTY
+  checkOffsetAndCount(size, 0, byteCount.toLong())
+
+  // Walk through the buffer to count how many segments we'll need.
+  var offset = 0
+  var segmentCount = 0
+  var s = head
+  while (offset < byteCount) {
+    if (s!!.limit == s.pos) {
+      throw AssertionError("s.limit == s.pos") // Empty segment. This should not happen!
+    }
+    offset += s.limit - s.pos
+    segmentCount++
+    s = s.next
+  }
+
+  // Walk through the buffer again to assign segments and build the directory.
+  val segments = arrayOfNulls<ByteArray?>(segmentCount)
+  val directory = IntArray(segmentCount * 2)
+  offset = 0
+  segmentCount = 0
+  s = head
+  while (offset < byteCount) {
+    segments[segmentCount] = s!!.data
+    offset += s.limit - s.pos
+    // Despite sharing more bytes, only report having up to byteCount.
+    directory[segmentCount] = minOf(offset, byteCount)
+    directory[segmentCount + segments.size] = s.pos
+    s.shared = true
+    segmentCount++
+    s = s.next
+  }
+  @Suppress("UNCHECKED_CAST")
+  return SegmentedByteString(segments as Array<ByteArray>, directory)
+}
+
+internal fun Buffer.commonReadUnsafe(unsafeCursor: UnsafeCursor): UnsafeCursor {
+  check(unsafeCursor.buffer == null) { "already attached to a buffer" }
+
+  unsafeCursor.buffer = this
+  unsafeCursor.readWrite = false
+  return unsafeCursor
+}
+
+internal fun Buffer.commonReadAndWriteUnsafe(unsafeCursor: UnsafeCursor): UnsafeCursor {
+  check(unsafeCursor.buffer == null) { "already attached to a buffer" }
+
+  unsafeCursor.buffer = this
+  unsafeCursor.readWrite = true
+  return unsafeCursor
+}
+
+internal inline fun UnsafeCursor.commonNext(): Int {
+  check(offset != buffer!!.size) { "no more bytes" }
+  return if (offset == -1L) seek(0L) else seek(offset + (end - start))
+}
+
+internal inline fun UnsafeCursor.commonSeek(offset: Long): Int {
+  val buffer = checkNotNull(buffer) { "not attached to a buffer" }
+  if (offset < -1 || offset > buffer.size) {
+    throw ArrayIndexOutOfBoundsException("offset=$offset > size=${buffer.size}")
+  }
+
+  if (offset == -1L || offset == buffer.size) {
+    this.segment = null
+    this.offset = offset
+    this.data = null
+    this.start = -1
+    this.end = -1
+    return -1
+  }
+
+  // Navigate to the segment that contains `offset`. Start from our current segment if possible.
+  var min = 0L
+  var max = buffer.size
+  var head = buffer.head
+  var tail = buffer.head
+  if (this.segment != null) {
+    val segmentOffset = this.offset - (this.start - this.segment!!.pos)
+    if (segmentOffset > offset) {
+      // Set the cursor segment to be the 'end'
+      max = segmentOffset
+      tail = this.segment
+    } else {
+      // Set the cursor segment to be the 'beginning'
+      min = segmentOffset
+      head = this.segment
+    }
+  }
+
+  var next: Segment?
+  var nextOffset: Long
+  if (max - offset > offset - min) {
+    // Start at the 'beginning' and search forwards
+    next = head
+    nextOffset = min
+    while (offset >= nextOffset + (next!!.limit - next.pos)) {
+      nextOffset += (next.limit - next.pos).toLong()
+      next = next.next
+    }
+  } else {
+    // Start at the 'end' and search backwards
+    next = tail
+    nextOffset = max
+    while (nextOffset > offset) {
+      next = next!!.prev
+      nextOffset -= (next!!.limit - next.pos).toLong()
+    }
+  }
+
+  // If we're going to write and our segment is shared, swap it for a read-write one.
+  if (readWrite && next!!.shared) {
+    val unsharedNext = next.unsharedCopy()
+    if (buffer.head === next) {
+      buffer.head = unsharedNext
+    }
+    next = next.push(unsharedNext)
+    next.prev!!.pop()
+  }
+
+  // Update this cursor to the requested offset within the found segment.
+  this.segment = next
+  this.offset = offset
+  this.data = next!!.data
+  this.start = next.pos + (offset - nextOffset).toInt()
+  this.end = next.limit
+  return end - start
+}
+
+internal inline fun UnsafeCursor.commonResizeBuffer(newSize: Long): Long {
+  val buffer = checkNotNull(buffer) { "not attached to a buffer" }
+  check(readWrite) { "resizeBuffer() only permitted for read/write buffers" }
+
+  val oldSize = buffer.size
+  if (newSize <= oldSize) {
+    require(newSize >= 0L) { "newSize < 0: $newSize" }
+    // Shrink the buffer by either shrinking segments or removing them.
+    var bytesToSubtract = oldSize - newSize
+    while (bytesToSubtract > 0L) {
+      val tail = buffer.head!!.prev
+      val tailSize = tail!!.limit - tail.pos
+      if (tailSize <= bytesToSubtract) {
+        buffer.head = tail.pop()
+        okio.SegmentPool.recycle(tail)
+        bytesToSubtract -= tailSize.toLong()
+      } else {
+        tail.limit -= bytesToSubtract.toInt()
+        break
+      }
+    }
+    // Seek to the end.
+    this.segment = null
+    this.offset = newSize
+    this.data = null
+    this.start = -1
+    this.end = -1
+  } else if (newSize > oldSize) {
+    // Enlarge the buffer by either enlarging segments or adding them.
+    var needsToSeek = true
+    var bytesToAdd = newSize - oldSize
+    while (bytesToAdd > 0L) {
+      val tail = buffer.writableSegment(1)
+      val segmentBytesToAdd = minOf(bytesToAdd, Segment.SIZE - tail.limit).toInt()
+      tail.limit += segmentBytesToAdd
+      bytesToAdd -= segmentBytesToAdd.toLong()
+
+      // If this is the first segment we're adding, seek to it.
+      if (needsToSeek) {
+        this.segment = tail
+        this.offset = oldSize
+        this.data = tail.data
+        this.start = tail.limit - segmentBytesToAdd
+        this.end = tail.limit
+        needsToSeek = false
+      }
+    }
+  }
+
+  buffer.size = newSize
+
+  return oldSize
+}
+
+internal inline fun UnsafeCursor.commonExpandBuffer(minByteCount: Int): Long {
+  require(minByteCount > 0) { "minByteCount <= 0: $minByteCount" }
+  require(minByteCount <= Segment.SIZE) { "minByteCount > Segment.SIZE: $minByteCount" }
+  val buffer = checkNotNull(buffer) { "not attached to a buffer" }
+  check(readWrite) { "expandBuffer() only permitted for read/write buffers" }
+
+  val oldSize = buffer.size
+  val tail = buffer.writableSegment(minByteCount)
+  val result = Segment.SIZE - tail.limit
+  tail.limit = Segment.SIZE
+  buffer.size = oldSize + result
+
+  // Seek to the old size.
+  this.segment = tail
+  this.offset = oldSize
+  this.data = tail.data
+  this.start = Segment.SIZE - result
+  this.end = Segment.SIZE
+
+  return result.toLong()
+}
+
+internal inline fun UnsafeCursor.commonClose() {
+  // TODO(jwilson): use edit counts or other information to track unexpected changes?
+  check(buffer != null) { "not attached to a buffer" }
+
+  buffer = null
+  segment = null
+  offset = -1L
+  data = null
+  start = -1
+  end = -1
+}
diff --git a/okio/src/commonMain/kotlin/okio/internal/ByteString.kt b/okio/src/commonMain/kotlin/okio/internal/ByteString.kt
new file mode 100644
index 0000000..7a1a488
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/internal/ByteString.kt
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2018 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 okio.internal
+
+import okio.BASE64_URL_SAFE
+import okio.Buffer
+import okio.ByteString
+import okio.REPLACEMENT_CODE_POINT
+import okio.and
+import okio.arrayRangeEquals
+import okio.asUtf8ToByteArray
+import okio.checkOffsetAndCount
+import okio.decodeBase64ToArray
+import okio.encodeBase64
+import okio.isIsoControl
+import okio.processUtf8CodePoints
+import okio.shr
+import okio.toUtf8String
+
+// TODO Kotlin's expect classes can't have default implementations, so platform implementations
+// have to call these functions. Remove all this nonsense when expect class allow actual code.
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonUtf8(): String {
+  var result = utf8
+  if (result == null) {
+    // We don't care if we double-allocate in racy code.
+    result = internalArray().toUtf8String()
+    utf8 = result
+  }
+  return result
+}
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonBase64(): String = data.encodeBase64()
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonBase64Url() = data.encodeBase64(map = BASE64_URL_SAFE)
+
+internal val HEX_DIGIT_CHARS =
+  charArrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f')
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonHex(): String {
+  val result = CharArray(data.size * 2)
+  var c = 0
+  for (b in data) {
+    result[c++] = HEX_DIGIT_CHARS[b shr 4 and 0xf]
+    result[c++] = HEX_DIGIT_CHARS[b       and 0xf] // ktlint-disable no-multi-spaces
+  }
+  return String(result)
+}
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonToAsciiLowercase(): ByteString {
+  // Search for an uppercase character. If we don't find one, return this.
+  var i = 0
+  while (i < data.size) {
+    var c = data[i]
+    if (c < 'A'.toByte() || c > 'Z'.toByte()) {
+      i++
+      continue
+    }
+
+    // This string is needs to be lowercased. Create and return a new byte string.
+    val lowercase = data.copyOf()
+    lowercase[i++] = (c - ('A' - 'a')).toByte()
+    while (i < lowercase.size) {
+      c = lowercase[i]
+      if (c < 'A'.toByte() || c > 'Z'.toByte()) {
+        i++
+        continue
+      }
+      lowercase[i] = (c - ('A' - 'a')).toByte()
+      i++
+    }
+    return ByteString(lowercase)
+  }
+  return this
+}
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonToAsciiUppercase(): ByteString {
+  // Search for an lowercase character. If we don't find one, return this.
+  var i = 0
+  while (i < data.size) {
+    var c = data[i]
+    if (c < 'a'.toByte() || c > 'z'.toByte()) {
+      i++
+      continue
+    }
+
+    // This string is needs to be uppercased. Create and return a new byte string.
+    val lowercase = data.copyOf()
+    lowercase[i++] = (c - ('a' - 'A')).toByte()
+    while (i < lowercase.size) {
+      c = lowercase[i]
+      if (c < 'a'.toByte() || c > 'z'.toByte()) {
+        i++
+        continue
+      }
+      lowercase[i] = (c - ('a' - 'A')).toByte()
+      i++
+    }
+    return ByteString(lowercase)
+  }
+  return this
+}
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonSubstring(beginIndex: Int, endIndex: Int): ByteString {
+  require(beginIndex >= 0) { "beginIndex < 0" }
+  require(endIndex <= data.size) { "endIndex > length(${data.size})" }
+
+  val subLen = endIndex - beginIndex
+  require(subLen >= 0) { "endIndex < beginIndex" }
+
+  if (beginIndex == 0 && endIndex == data.size) {
+    return this
+  }
+  return ByteString(data.copyOfRange(beginIndex, endIndex))
+}
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonGetByte(pos: Int) = data[pos]
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonGetSize() = data.size
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonToByteArray() = data.copyOf()
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonInternalArray() = data
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonRangeEquals(
+  offset: Int,
+  other: ByteString,
+  otherOffset: Int,
+  byteCount: Int
+): Boolean = other.rangeEquals(otherOffset, this.data, offset, byteCount)
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonRangeEquals(
+  offset: Int,
+  other: ByteArray,
+  otherOffset: Int,
+  byteCount: Int
+): Boolean {
+  return (
+    offset >= 0 && offset <= data.size - byteCount &&
+      otherOffset >= 0 && otherOffset <= other.size - byteCount &&
+      arrayRangeEquals(data, offset, other, otherOffset, byteCount)
+    )
+}
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonStartsWith(prefix: ByteString) =
+  rangeEquals(0, prefix, 0, prefix.size)
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonStartsWith(prefix: ByteArray) =
+  rangeEquals(0, prefix, 0, prefix.size)
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonEndsWith(suffix: ByteString) =
+  rangeEquals(size - suffix.size, suffix, 0, suffix.size)
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonEndsWith(suffix: ByteArray) =
+  rangeEquals(size - suffix.size, suffix, 0, suffix.size)
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonIndexOf(other: ByteArray, fromIndex: Int): Int {
+  val limit = data.size - other.size
+  for (i in maxOf(fromIndex, 0)..limit) {
+    if (arrayRangeEquals(data, i, other, 0, other.size)) {
+      return i
+    }
+  }
+  return -1
+}
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonLastIndexOf(
+  other: ByteString,
+  fromIndex: Int
+) = lastIndexOf(other.internalArray(), fromIndex)
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonLastIndexOf(other: ByteArray, fromIndex: Int): Int {
+  val limit = data.size - other.size
+  for (i in minOf(fromIndex, limit) downTo 0) {
+    if (arrayRangeEquals(data, i, other, 0, other.size)) {
+      return i
+    }
+  }
+  return -1
+}
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonEquals(other: Any?): Boolean {
+  return when {
+    other === this -> true
+    other is ByteString -> other.size == data.size && other.rangeEquals(0, data, 0, data.size)
+    else -> false
+  }
+}
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonHashCode(): Int {
+  val result = hashCode
+  if (result != 0) return result
+  return data.contentHashCode().also {
+    hashCode = it
+  }
+}
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonCompareTo(other: ByteString): Int {
+  val sizeA = size
+  val sizeB = other.size
+  var i = 0
+  val size = minOf(sizeA, sizeB)
+  while (i < size) {
+    val byteA = this[i] and 0xff
+    val byteB = other[i] and 0xff
+    if (byteA == byteB) {
+      i++
+      continue
+    }
+    return if (byteA < byteB) -1 else 1
+  }
+  if (sizeA == sizeB) return 0
+  return if (sizeA < sizeB) -1 else 1
+}
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun commonOf(data: ByteArray) = ByteString(data.copyOf())
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteArray.commonToByteString(offset: Int, byteCount: Int): ByteString {
+  checkOffsetAndCount(size.toLong(), offset.toLong(), byteCount.toLong())
+  return ByteString(copyOfRange(offset, offset + byteCount))
+}
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun String.commonEncodeUtf8(): ByteString {
+  val byteString = ByteString(asUtf8ToByteArray())
+  byteString.utf8 = this
+  return byteString
+}
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun String.commonDecodeBase64(): ByteString? {
+  val decoded = decodeBase64ToArray()
+  return if (decoded != null) ByteString(decoded) else null
+}
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun String.commonDecodeHex(): ByteString {
+  require(length % 2 == 0) { "Unexpected hex string: $this" }
+
+  val result = ByteArray(length / 2)
+  for (i in result.indices) {
+    val d1 = decodeHexDigit(this[i * 2]) shl 4
+    val d2 = decodeHexDigit(this[i * 2 + 1])
+    result[i] = (d1 + d2).toByte()
+  }
+  return ByteString(result)
+}
+
+/** Writes the contents of this byte string to `buffer`.  */
+internal fun ByteString.commonWrite(buffer: Buffer, offset: Int, byteCount: Int) {
+  buffer.write(data, offset, byteCount)
+}
+
+private fun decodeHexDigit(c: Char): Int {
+  return when (c) {
+    in '0'..'9' -> c - '0'
+    in 'a'..'f' -> c - 'a' + 10
+    in 'A'..'F' -> c - 'A' + 10
+    else -> throw IllegalArgumentException("Unexpected hex digit: $c")
+  }
+}
+
+@Suppress("NOTHING_TO_INLINE")
+internal inline fun ByteString.commonToString(): String {
+  if (data.isEmpty()) return "[size=0]"
+
+  val i = codePointIndexToCharIndex(data, 64)
+  if (i == -1) {
+    return if (data.size <= 64) {
+      "[hex=${hex()}]"
+    } else {
+      "[size=${data.size} hex=${commonSubstring(0, 64).hex()}…]"
+    }
+  }
+
+  val text = utf8()
+  val safeText = text.substring(0, i)
+    .replace("\\", "\\\\")
+    .replace("\n", "\\n")
+    .replace("\r", "\\r")
+  return if (i < text.length) {
+    "[size=${data.size} text=$safeText…]"
+  } else {
+    "[text=$safeText]"
+  }
+}
+
+private fun codePointIndexToCharIndex(s: ByteArray, codePointCount: Int): Int {
+  var charCount = 0
+  var j = 0
+  s.processUtf8CodePoints(0, s.size) { c ->
+    if (j++ == codePointCount) {
+      return charCount
+    }
+
+    if ((c != '\n'.toInt() && c != '\r'.toInt() && isIsoControl(c)) ||
+      c == REPLACEMENT_CODE_POINT
+    ) {
+      return -1
+    }
+
+    charCount += if (c < 0x10000) 1 else 2
+  }
+  return charCount
+}
diff --git a/okio/src/commonMain/kotlin/okio/internal/RealBufferedSink.kt b/okio/src/commonMain/kotlin/okio/internal/RealBufferedSink.kt
new file mode 100644
index 0000000..49b0c4d
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/internal/RealBufferedSink.kt
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// TODO move to RealBufferedSink class: https://youtrack.jetbrains.com/issue/KT-20427
+@file:Suppress("NOTHING_TO_INLINE")
+
+package okio.internal
+
+import okio.Buffer
+import okio.BufferedSink
+import okio.ByteString
+import okio.EOFException
+import okio.RealBufferedSink
+import okio.Segment
+import okio.Source
+
+internal inline fun RealBufferedSink.commonWrite(source: Buffer, byteCount: Long) {
+  check(!closed) { "closed" }
+  buffer.write(source, byteCount)
+  emitCompleteSegments()
+}
+
+internal inline fun RealBufferedSink.commonWrite(byteString: ByteString): BufferedSink {
+  check(!closed) { "closed" }
+  buffer.write(byteString)
+  return emitCompleteSegments()
+}
+
+internal inline fun RealBufferedSink.commonWrite(
+  byteString: ByteString,
+  offset: Int,
+  byteCount: Int
+): BufferedSink {
+  check(!closed) { "closed" }
+  buffer.write(byteString, offset, byteCount)
+  return emitCompleteSegments()
+}
+
+internal inline fun RealBufferedSink.commonWriteUtf8(string: String): BufferedSink {
+  check(!closed) { "closed" }
+  buffer.writeUtf8(string)
+  return emitCompleteSegments()
+}
+
+internal inline fun RealBufferedSink.commonWriteUtf8(
+  string: String,
+  beginIndex: Int,
+  endIndex: Int
+): BufferedSink {
+  check(!closed) { "closed" }
+  buffer.writeUtf8(string, beginIndex, endIndex)
+  return emitCompleteSegments()
+}
+
+internal inline fun RealBufferedSink.commonWriteUtf8CodePoint(codePoint: Int): BufferedSink {
+  check(!closed) { "closed" }
+  buffer.writeUtf8CodePoint(codePoint)
+  return emitCompleteSegments()
+}
+
+internal inline fun RealBufferedSink.commonWrite(source: ByteArray): BufferedSink {
+  check(!closed) { "closed" }
+  buffer.write(source)
+  return emitCompleteSegments()
+}
+
+internal inline fun RealBufferedSink.commonWrite(
+  source: ByteArray,
+  offset: Int,
+  byteCount: Int
+): BufferedSink {
+  check(!closed) { "closed" }
+  buffer.write(source, offset, byteCount)
+  return emitCompleteSegments()
+}
+
+internal inline fun RealBufferedSink.commonWriteAll(source: Source): Long {
+  var totalBytesRead = 0L
+  while (true) {
+    val readCount: Long = source.read(buffer, Segment.SIZE.toLong())
+    if (readCount == -1L) break
+    totalBytesRead += readCount
+    emitCompleteSegments()
+  }
+  return totalBytesRead
+}
+
+internal inline fun RealBufferedSink.commonWrite(source: Source, byteCount: Long): BufferedSink {
+  var byteCount = byteCount
+  while (byteCount > 0L) {
+    val read = source.read(buffer, byteCount)
+    if (read == -1L) throw EOFException()
+    byteCount -= read
+    emitCompleteSegments()
+  }
+  return this
+}
+
+internal inline fun RealBufferedSink.commonWriteByte(b: Int): BufferedSink {
+  check(!closed) { "closed" }
+  buffer.writeByte(b)
+  return emitCompleteSegments()
+}
+
+internal inline fun RealBufferedSink.commonWriteShort(s: Int): BufferedSink {
+  check(!closed) { "closed" }
+  buffer.writeShort(s)
+  return emitCompleteSegments()
+}
+
+internal inline fun RealBufferedSink.commonWriteShortLe(s: Int): BufferedSink {
+  check(!closed) { "closed" }
+  buffer.writeShortLe(s)
+  return emitCompleteSegments()
+}
+
+internal inline fun RealBufferedSink.commonWriteInt(i: Int): BufferedSink {
+  check(!closed) { "closed" }
+  buffer.writeInt(i)
+  return emitCompleteSegments()
+}
+
+internal inline fun RealBufferedSink.commonWriteIntLe(i: Int): BufferedSink {
+  check(!closed) { "closed" }
+  buffer.writeIntLe(i)
+  return emitCompleteSegments()
+}
+
+internal inline fun RealBufferedSink.commonWriteLong(v: Long): BufferedSink {
+  check(!closed) { "closed" }
+  buffer.writeLong(v)
+  return emitCompleteSegments()
+}
+
+internal inline fun RealBufferedSink.commonWriteLongLe(v: Long): BufferedSink {
+  check(!closed) { "closed" }
+  buffer.writeLongLe(v)
+  return emitCompleteSegments()
+}
+
+internal inline fun RealBufferedSink.commonWriteDecimalLong(v: Long): BufferedSink {
+  check(!closed) { "closed" }
+  buffer.writeDecimalLong(v)
+  return emitCompleteSegments()
+}
+
+internal inline fun RealBufferedSink.commonWriteHexadecimalUnsignedLong(v: Long): BufferedSink {
+  check(!closed) { "closed" }
+  buffer.writeHexadecimalUnsignedLong(v)
+  return emitCompleteSegments()
+}
+
+internal inline fun RealBufferedSink.commonEmitCompleteSegments(): BufferedSink {
+  check(!closed) { "closed" }
+  val byteCount = buffer.completeSegmentByteCount()
+  if (byteCount > 0L) sink.write(buffer, byteCount)
+  return this
+}
+
+internal inline fun RealBufferedSink.commonEmit(): BufferedSink {
+  check(!closed) { "closed" }
+  val byteCount = buffer.size
+  if (byteCount > 0L) sink.write(buffer, byteCount)
+  return this
+}
+
+internal inline fun RealBufferedSink.commonFlush() {
+  check(!closed) { "closed" }
+  if (buffer.size > 0L) {
+    sink.write(buffer, buffer.size)
+  }
+  sink.flush()
+}
+
+internal inline fun RealBufferedSink.commonClose() {
+  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.
+  var thrown: Throwable? = null
+  try {
+    if (buffer.size > 0) {
+      sink.write(buffer, buffer.size)
+    }
+  } catch (e: Throwable) {
+    thrown = e
+  }
+
+  try {
+    sink.close()
+  } catch (e: Throwable) {
+    if (thrown == null) thrown = e
+  }
+
+  closed = true
+
+  if (thrown != null) throw thrown
+}
+
+internal inline fun RealBufferedSink.commonTimeout() = sink.timeout()
+
+internal inline fun RealBufferedSink.commonToString() = "buffer($sink)"
diff --git a/okio/src/commonMain/kotlin/okio/internal/RealBufferedSource.kt b/okio/src/commonMain/kotlin/okio/internal/RealBufferedSource.kt
new file mode 100644
index 0000000..4b90143
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/internal/RealBufferedSource.kt
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// TODO move to RealBufferedSource class: https://youtrack.jetbrains.com/issue/KT-20427
+@file:Suppress("NOTHING_TO_INLINE")
+
+package okio.internal
+
+import okio.Buffer
+import okio.BufferedSource
+import okio.ByteString
+import okio.EOFException
+import okio.Options
+import okio.PeekSource
+import okio.RealBufferedSource
+import okio.Segment
+import okio.Sink
+import okio.buffer
+import okio.checkOffsetAndCount
+
+internal inline fun RealBufferedSource.commonRead(sink: Buffer, byteCount: Long): Long {
+  require(byteCount >= 0L) { "byteCount < 0: $byteCount" }
+  check(!closed) { "closed" }
+
+  if (buffer.size == 0L) {
+    val read = source.read(buffer, Segment.SIZE.toLong())
+    if (read == -1L) return -1L
+  }
+
+  val toRead = minOf(byteCount, buffer.size)
+  return buffer.read(sink, toRead)
+}
+
+internal inline fun RealBufferedSource.commonExhausted(): Boolean {
+  check(!closed) { "closed" }
+  return buffer.exhausted() && source.read(buffer, Segment.SIZE.toLong()) == -1L
+}
+
+internal inline fun RealBufferedSource.commonRequire(byteCount: Long) {
+  if (!request(byteCount)) throw EOFException()
+}
+
+internal inline fun RealBufferedSource.commonRequest(byteCount: Long): Boolean {
+  require(byteCount >= 0L) { "byteCount < 0: $byteCount" }
+  check(!closed) { "closed" }
+  while (buffer.size < byteCount) {
+    if (source.read(buffer, Segment.SIZE.toLong()) == -1L) return false
+  }
+  return true
+}
+
+internal inline fun RealBufferedSource.commonReadByte(): Byte {
+  require(1)
+  return buffer.readByte()
+}
+
+internal inline fun RealBufferedSource.commonReadByteString(): ByteString {
+  buffer.writeAll(source)
+  return buffer.readByteString()
+}
+
+internal inline fun RealBufferedSource.commonReadByteString(byteCount: Long): ByteString {
+  require(byteCount)
+  return buffer.readByteString(byteCount)
+}
+
+internal inline fun RealBufferedSource.commonSelect(options: Options): Int {
+  check(!closed) { "closed" }
+
+  while (true) {
+    val index = buffer.selectPrefix(options, selectTruncated = true)
+    when (index) {
+      -1 -> {
+        return -1
+      }
+      -2 -> {
+        // We need to grow the buffer. Do that, then try it all again.
+        if (source.read(buffer, Segment.SIZE.toLong()) == -1L) return -1
+      }
+      else -> {
+        // We matched a full byte string: consume it and return it.
+        val selectedSize = options.byteStrings[index].size
+        buffer.skip(selectedSize.toLong())
+        return index
+      }
+    }
+  }
+}
+
+internal inline fun RealBufferedSource.commonReadByteArray(): ByteArray {
+  buffer.writeAll(source)
+  return buffer.readByteArray()
+}
+
+internal inline fun RealBufferedSource.commonReadByteArray(byteCount: Long): ByteArray {
+  require(byteCount)
+  return buffer.readByteArray(byteCount)
+}
+
+internal inline fun RealBufferedSource.commonReadFully(sink: ByteArray) {
+  try {
+    require(sink.size.toLong())
+  } catch (e: EOFException) {
+    // The underlying source is exhausted. Copy the bytes we got before rethrowing.
+    var offset = 0
+    while (buffer.size > 0L) {
+      val read = buffer.read(sink, offset, buffer.size.toInt())
+      if (read == -1) throw AssertionError()
+      offset += read
+    }
+    throw e
+  }
+
+  buffer.readFully(sink)
+}
+
+internal inline fun RealBufferedSource.commonRead(sink: ByteArray, offset: Int, byteCount: Int): Int {
+  checkOffsetAndCount(sink.size.toLong(), offset.toLong(), byteCount.toLong())
+
+  if (buffer.size == 0L) {
+    val read = source.read(buffer, Segment.SIZE.toLong())
+    if (read == -1L) return -1
+  }
+
+  val toRead = okio.minOf(byteCount, buffer.size).toInt()
+  return buffer.read(sink, offset, toRead)
+}
+
+internal inline fun RealBufferedSource.commonReadFully(sink: Buffer, byteCount: Long) {
+  try {
+    require(byteCount)
+  } catch (e: EOFException) {
+    // The underlying source is exhausted. Copy the bytes we got before rethrowing.
+    sink.writeAll(buffer)
+    throw e
+  }
+
+  buffer.readFully(sink, byteCount)
+}
+
+internal inline fun RealBufferedSource.commonReadAll(sink: Sink): Long {
+  var totalBytesWritten: Long = 0
+  while (source.read(buffer, Segment.SIZE.toLong()) != -1L) {
+    val emitByteCount = buffer.completeSegmentByteCount()
+    if (emitByteCount > 0L) {
+      totalBytesWritten += emitByteCount
+      sink.write(buffer, emitByteCount)
+    }
+  }
+  if (buffer.size > 0L) {
+    totalBytesWritten += buffer.size
+    sink.write(buffer, buffer.size)
+  }
+  return totalBytesWritten
+}
+
+internal inline fun RealBufferedSource.commonReadUtf8(): String {
+  buffer.writeAll(source)
+  return buffer.readUtf8()
+}
+
+internal inline fun RealBufferedSource.commonReadUtf8(byteCount: Long): String {
+  require(byteCount)
+  return buffer.readUtf8(byteCount)
+}
+
+internal inline fun RealBufferedSource.commonReadUtf8Line(): String? {
+  val newline = indexOf('\n'.toByte())
+
+  return if (newline == -1L) {
+    if (buffer.size != 0L) {
+      readUtf8(buffer.size)
+    } else {
+      null
+    }
+  } else {
+    buffer.readUtf8Line(newline)
+  }
+}
+
+internal inline fun RealBufferedSource.commonReadUtf8LineStrict(limit: Long): String {
+  require(limit >= 0) { "limit < 0: $limit" }
+  val scanLength = if (limit == Long.MAX_VALUE) Long.MAX_VALUE else limit + 1
+  val newline = indexOf('\n'.toByte(), 0, scanLength)
+  if (newline != -1L) return buffer.readUtf8Line(newline)
+  if (scanLength < Long.MAX_VALUE &&
+    request(scanLength) && buffer[scanLength - 1] == '\r'.toByte() &&
+    request(scanLength + 1) && buffer[scanLength] == '\n'.toByte()
+  ) {
+    return buffer.readUtf8Line(scanLength) // The line was 'limit' UTF-8 bytes followed by \r\n.
+  }
+  val data = Buffer()
+  buffer.copyTo(data, 0, okio.minOf(32, buffer.size))
+  throw EOFException(
+    "\\n not found: limit=" + minOf(buffer.size, limit) +
+      " content=" + data.readByteString().hex() + '…'.toString()
+  )
+}
+
+internal inline fun RealBufferedSource.commonReadUtf8CodePoint(): Int {
+  require(1)
+
+  val b0 = buffer[0].toInt()
+  when {
+    b0 and 0xe0 == 0xc0 -> require(2)
+    b0 and 0xf0 == 0xe0 -> require(3)
+    b0 and 0xf8 == 0xf0 -> require(4)
+  }
+
+  return buffer.readUtf8CodePoint()
+}
+
+internal inline fun RealBufferedSource.commonReadShort(): Short {
+  require(2)
+  return buffer.readShort()
+}
+
+internal inline fun RealBufferedSource.commonReadShortLe(): Short {
+  require(2)
+  return buffer.readShortLe()
+}
+
+internal inline fun RealBufferedSource.commonReadInt(): Int {
+  require(4)
+  return buffer.readInt()
+}
+
+internal inline fun RealBufferedSource.commonReadIntLe(): Int {
+  require(4)
+  return buffer.readIntLe()
+}
+
+internal inline fun RealBufferedSource.commonReadLong(): Long {
+  require(8)
+  return buffer.readLong()
+}
+
+internal inline fun RealBufferedSource.commonReadLongLe(): Long {
+  require(8)
+  return buffer.readLongLe()
+}
+
+internal inline fun RealBufferedSource.commonReadDecimalLong(): Long {
+  require(1)
+
+  var pos = 0L
+  while (request(pos + 1)) {
+    val b = buffer[pos]
+    if ((b < '0'.toByte() || b > '9'.toByte()) && (pos != 0L || b != '-'.toByte())) {
+      // Non-digit, or non-leading negative sign.
+      if (pos == 0L) {
+        throw NumberFormatException("Expected leading [0-9] or '-' character but was 0x${b.toString(16)}")
+      }
+      break
+    }
+    pos++
+  }
+
+  return buffer.readDecimalLong()
+}
+
+internal inline fun RealBufferedSource.commonReadHexadecimalUnsignedLong(): Long {
+  require(1)
+
+  var pos = 0
+  while (request((pos + 1).toLong())) {
+    val b = buffer[pos.toLong()]
+    if ((b < '0'.toByte() || b > '9'.toByte()) &&
+      (b < 'a'.toByte() || b > 'f'.toByte()) &&
+      (b < 'A'.toByte() || b > 'F'.toByte())
+    ) {
+      // Non-digit, or non-leading negative sign.
+      if (pos == 0) {
+        throw NumberFormatException("Expected leading [0-9a-fA-F] character but was 0x${b.toString(16)}")
+      }
+      break
+    }
+    pos++
+  }
+
+  return buffer.readHexadecimalUnsignedLong()
+}
+
+internal inline fun RealBufferedSource.commonSkip(byteCount: Long) {
+  var byteCount = byteCount
+  check(!closed) { "closed" }
+  while (byteCount > 0) {
+    if (buffer.size == 0L && source.read(buffer, Segment.SIZE.toLong()) == -1L) {
+      throw EOFException()
+    }
+    val toSkip = minOf(byteCount, buffer.size)
+    buffer.skip(toSkip)
+    byteCount -= toSkip
+  }
+}
+
+internal inline fun RealBufferedSource.commonIndexOf(b: Byte, fromIndex: Long, toIndex: Long): Long {
+  var fromIndex = fromIndex
+  check(!closed) { "closed" }
+  require(fromIndex in 0L..toIndex) { "fromIndex=$fromIndex toIndex=$toIndex" }
+
+  while (fromIndex < toIndex) {
+    val result = buffer.indexOf(b, fromIndex, toIndex)
+    if (result != -1L) return result
+
+    // The byte wasn't in the buffer. Give up if we've already reached our target size or if the
+    // underlying stream is exhausted.
+    val lastBufferSize = buffer.size
+    if (lastBufferSize >= toIndex || source.read(buffer, Segment.SIZE.toLong()) == -1L) return -1L
+
+    // Continue the search from where we left off.
+    fromIndex = maxOf(fromIndex, lastBufferSize)
+  }
+  return -1L
+}
+
+internal inline fun RealBufferedSource.commonIndexOf(bytes: ByteString, fromIndex: Long): Long {
+  var fromIndex = fromIndex
+  check(!closed) { "closed" }
+
+  while (true) {
+    val result = buffer.indexOf(bytes, fromIndex)
+    if (result != -1L) return result
+
+    val lastBufferSize = buffer.size
+    if (source.read(buffer, Segment.SIZE.toLong()) == -1L) return -1L
+
+    // Keep searching, picking up from where we left off.
+    fromIndex = maxOf(fromIndex, lastBufferSize - bytes.size + 1)
+  }
+}
+
+internal inline fun RealBufferedSource.commonIndexOfElement(targetBytes: ByteString, fromIndex: Long): Long {
+  var fromIndex = fromIndex
+  check(!closed) { "closed" }
+
+  while (true) {
+    val result = buffer.indexOfElement(targetBytes, fromIndex)
+    if (result != -1L) return result
+
+    val lastBufferSize = buffer.size
+    if (source.read(buffer, Segment.SIZE.toLong()) == -1L) return -1L
+
+    // Keep searching, picking up from where we left off.
+    fromIndex = maxOf(fromIndex, lastBufferSize)
+  }
+}
+
+internal inline fun RealBufferedSource.commonRangeEquals(
+  offset: Long,
+  bytes: ByteString,
+  bytesOffset: Int,
+  byteCount: Int
+): Boolean {
+  check(!closed) { "closed" }
+
+  if (offset < 0L ||
+    bytesOffset < 0 ||
+    byteCount < 0 ||
+    bytes.size - bytesOffset < byteCount
+  ) {
+    return false
+  }
+  for (i in 0 until byteCount) {
+    val bufferOffset = offset + i
+    if (!request(bufferOffset + 1)) return false
+    if (buffer[bufferOffset] != bytes[bytesOffset + i]) return false
+  }
+  return true
+}
+
+internal inline fun RealBufferedSource.commonPeek(): BufferedSource {
+  return PeekSource(this).buffer()
+}
+
+internal inline fun RealBufferedSource.commonClose() {
+  if (closed) return
+  closed = true
+  source.close()
+  buffer.clear()
+}
+
+internal inline fun RealBufferedSource.commonTimeout() = source.timeout()
+
+internal inline fun RealBufferedSource.commonToString() = "buffer($source)"
diff --git a/okio/src/commonMain/kotlin/okio/internal/SegmentedByteString.kt b/okio/src/commonMain/kotlin/okio/internal/SegmentedByteString.kt
new file mode 100644
index 0000000..f46e138
--- /dev/null
+++ b/okio/src/commonMain/kotlin/okio/internal/SegmentedByteString.kt
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// TODO move to SegmentedByteString class: https://youtrack.jetbrains.com/issue/KT-20427
+@file:Suppress("NOTHING_TO_INLINE")
+
+package okio.internal
+
+import okio.Buffer
+import okio.ByteString
+import okio.Segment
+import okio.SegmentedByteString
+import okio.arrayRangeEquals
+import okio.checkOffsetAndCount
+
+internal fun IntArray.binarySearch(value: Int, fromIndex: Int, toIndex: Int): Int {
+  var left = fromIndex
+  var right = toIndex - 1
+
+  while (left <= right) {
+    val mid = (left + right) ushr 1 // protect from overflow
+    val midVal = this[mid]
+
+    when {
+      midVal < value -> left = mid + 1
+      midVal > value -> right = mid - 1
+      else -> return mid
+    }
+  }
+
+  // no exact match, return negative of where it should match
+  return -left - 1
+}
+
+/** Returns the index of the segment that contains the byte at `pos`.  */
+internal fun SegmentedByteString.segment(pos: Int): Int {
+  // Search for (pos + 1) instead of (pos) because the directory holds sizes, not indexes.
+  val i = directory.binarySearch(pos + 1, 0, segments.size)
+  return if (i >= 0) i else i.inv() // If i is negative, bitflip to get the insert position.
+}
+
+/** Processes all segments, invoking `action` with the ByteArray and range of valid data. */
+internal inline fun SegmentedByteString.forEachSegment(
+  action: (data: ByteArray, offset: Int, byteCount: Int) -> Unit
+) {
+  val segmentCount = segments.size
+  var s = 0
+  var pos = 0
+  while (s < segmentCount) {
+    val segmentPos = directory[segmentCount + s]
+    val nextSegmentOffset = directory[s]
+
+    action(segments[s], segmentPos, nextSegmentOffset - pos)
+    pos = nextSegmentOffset
+    s++
+  }
+}
+
+/**
+ * Processes the segments between `beginIndex` and `endIndex`, invoking `action` with the ByteArray
+ * and range of the valid data.
+ */
+private inline fun SegmentedByteString.forEachSegment(
+  beginIndex: Int,
+  endIndex: Int,
+  action: (data: ByteArray, offset: Int, byteCount: Int) -> Unit
+) {
+  var s = segment(beginIndex)
+  var pos = beginIndex
+  while (pos < endIndex) {
+    val segmentOffset = if (s == 0) 0 else directory[s - 1]
+    val segmentSize = directory[s] - segmentOffset
+    val segmentPos = directory[segments.size + s]
+
+    val byteCount = minOf(endIndex, segmentOffset + segmentSize) - pos
+    val offset = segmentPos + (pos - segmentOffset)
+    action(segments[s], offset, byteCount)
+    pos += byteCount
+    s++
+  }
+}
+
+// TODO Kotlin's expect classes can't have default implementations, so platform implementations
+// have to call these functions. Remove all this nonsense when expect class allow actual code.
+
+internal inline fun SegmentedByteString.commonSubstring(beginIndex: Int, endIndex: Int): ByteString {
+  require(beginIndex >= 0) { "beginIndex=$beginIndex < 0" }
+  require(endIndex <= size) { "endIndex=$endIndex > length($size)" }
+
+  val subLen = endIndex - beginIndex
+  require(subLen >= 0) { "endIndex=$endIndex < beginIndex=$beginIndex" }
+
+  when {
+    beginIndex == 0 && endIndex == size -> return this
+    beginIndex == endIndex -> return ByteString.EMPTY
+  }
+
+  val beginSegment = segment(beginIndex) // First segment to include
+  val endSegment = segment(endIndex - 1) // Last segment to include
+
+  val newSegments = segments.copyOfRange(beginSegment, endSegment + 1)
+  val newDirectory = IntArray(newSegments.size * 2)
+  var index = 0
+  for (s in beginSegment..endSegment) {
+    newDirectory[index] = minOf(directory[s] - beginIndex, subLen)
+    newDirectory[index++ + newSegments.size] = directory[s + segments.size]
+  }
+
+  // Set the new position of the first segment
+  val segmentOffset = if (beginSegment == 0) 0 else directory[beginSegment - 1]
+  newDirectory[newSegments.size] += beginIndex - segmentOffset
+
+  return SegmentedByteString(newSegments, newDirectory)
+}
+
+internal inline fun SegmentedByteString.commonInternalGet(pos: Int): Byte {
+  checkOffsetAndCount(directory[segments.size - 1].toLong(), pos.toLong(), 1)
+  val segment = segment(pos)
+  val segmentOffset = if (segment == 0) 0 else directory[segment - 1]
+  val segmentPos = directory[segment + segments.size]
+  return segments[segment][pos - segmentOffset + segmentPos]
+}
+
+internal inline fun SegmentedByteString.commonGetSize() = directory[segments.size - 1]
+
+internal inline fun SegmentedByteString.commonToByteArray(): ByteArray {
+  val result = ByteArray(size)
+  var resultPos = 0
+  forEachSegment { data, offset, byteCount ->
+    data.copyInto(
+      result, destinationOffset = resultPos, startIndex = offset,
+      endIndex = offset + byteCount
+    )
+    resultPos += byteCount
+  }
+  return result
+}
+
+internal inline fun SegmentedByteString.commonWrite(buffer: Buffer, offset: Int, byteCount: Int) {
+  forEachSegment(offset, offset + byteCount) { data, offset, byteCount ->
+    val segment = Segment(data, offset, offset + byteCount, true, false)
+    if (buffer.head == null) {
+      segment.prev = segment
+      segment.next = segment.prev
+      buffer.head = segment.next
+    } else {
+      buffer.head!!.prev!!.push(segment)
+    }
+  }
+  buffer.size += byteCount
+}
+
+internal inline fun SegmentedByteString.commonRangeEquals(
+  offset: Int,
+  other: ByteString,
+  otherOffset: Int,
+  byteCount: Int
+): Boolean {
+  if (offset < 0 || offset > size - byteCount) return false
+  // Go segment-by-segment through this, passing arrays to other's rangeEquals().
+  var otherOffset = otherOffset
+  forEachSegment(offset, offset + byteCount) { data, offset, byteCount ->
+    if (!other.rangeEquals(otherOffset, data, offset, byteCount)) return false
+    otherOffset += byteCount
+  }
+  return true
+}
+
+internal inline fun SegmentedByteString.commonRangeEquals(
+  offset: Int,
+  other: ByteArray,
+  otherOffset: Int,
+  byteCount: Int
+): Boolean {
+  if (offset < 0 || offset > size - byteCount ||
+    otherOffset < 0 || otherOffset > other.size - byteCount
+  ) {
+    return false
+  }
+  // Go segment-by-segment through this, comparing ranges of arrays.
+  var otherOffset = otherOffset
+  forEachSegment(offset, offset + byteCount) { data, offset, byteCount ->
+    if (!arrayRangeEquals(data, offset, other, otherOffset, byteCount)) return false
+    otherOffset += byteCount
+  }
+  return true
+}
+
+internal inline fun SegmentedByteString.commonEquals(other: Any?): Boolean {
+  return when {
+    other === this -> true
+    other is ByteString -> other.size == size && rangeEquals(0, other, 0, size)
+    else -> false
+  }
+}
+
+internal inline fun SegmentedByteString.commonHashCode(): Int {
+  var result = hashCode
+  if (result != 0) return result
+
+  // Equivalent to Arrays.hashCode(toByteArray()).
+  result = 1
+  forEachSegment { data, offset, byteCount ->
+    var i = offset
+    val limit = offset + byteCount
+    while (i < limit) {
+      result = 31 * result + data[i]
+      i++
+    }
+  }
+  hashCode = result
+  return result
+}
diff --git a/okio/src/commonTest/kotlin/okio/AbstractBufferedSinkTest.kt b/okio/src/commonTest/kotlin/okio/AbstractBufferedSinkTest.kt
new file mode 100644
index 0000000..49bff8d
--- /dev/null
+++ b/okio/src/commonTest/kotlin/okio/AbstractBufferedSinkTest.kt
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+import okio.ByteString.Companion.decodeHex
+import okio.ByteString.Companion.encodeUtf8
+import kotlin.math.pow
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+
+class BufferSinkTest : AbstractBufferedSinkTest(BufferedSinkFactory.BUFFER)
+class RealBufferedSinkTest : AbstractBufferedSinkTest(BufferedSinkFactory.REAL_BUFFERED_SINK)
+
+abstract class AbstractBufferedSinkTest internal constructor(
+  factory: BufferedSinkFactory
+) {
+  private val data: Buffer = Buffer()
+  private val sink: BufferedSink = factory.create(data)
+
+  @Test fun writeNothing() {
+    sink.writeUtf8("")
+    sink.flush()
+    assertEquals(0, data.size)
+  }
+
+  @Test fun writeBytes() {
+    sink.writeByte(0xab)
+    sink.writeByte(0xcd)
+    sink.flush()
+    assertEquals("[hex=abcd]", data.toString())
+  }
+
+  @Test fun writeLastByteInSegment() {
+    sink.writeUtf8("a".repeat(Segment.SIZE - 1))
+    sink.writeByte(0x20)
+    sink.writeByte(0x21)
+    sink.flush()
+    assertEquals(listOf(Segment.SIZE, 1), segmentSizes(data))
+    assertEquals("a".repeat(Segment.SIZE - 1), data.readUtf8(Segment.SIZE - 1L))
+    assertEquals("[text= !]", data.toString())
+  }
+
+  @Test fun writeShort() {
+    sink.writeShort(0xabcd)
+    sink.writeShort(0x4321)
+    sink.flush()
+    assertEquals("[hex=abcd4321]", data.toString())
+  }
+
+  @Test fun writeShortLe() {
+    sink.writeShortLe(0xcdab)
+    sink.writeShortLe(0x2143)
+    sink.flush()
+    assertEquals("[hex=abcd4321]", data.toString())
+  }
+
+  @Test fun writeInt() {
+    sink.writeInt(-0x543210ff)
+    sink.writeInt(-0x789abcdf)
+    sink.flush()
+    assertEquals("[hex=abcdef0187654321]", data.toString())
+  }
+
+  @Test fun writeLastIntegerInSegment() {
+    sink.writeUtf8("a".repeat(Segment.SIZE - 4))
+    sink.writeInt(-0x543210ff)
+    sink.writeInt(-0x789abcdf)
+    sink.flush()
+    assertEquals(listOf(Segment.SIZE, 4), segmentSizes(data))
+    assertEquals("a".repeat(Segment.SIZE - 4), data.readUtf8(Segment.SIZE - 4L))
+    assertEquals("[hex=abcdef0187654321]", data.toString())
+  }
+
+  @Test fun writeIntegerDoesNotQuiteFitInSegment() {
+    sink.writeUtf8("a".repeat(Segment.SIZE - 3))
+    sink.writeInt(-0x543210ff)
+    sink.writeInt(-0x789abcdf)
+    sink.flush()
+    assertEquals(listOf(Segment.SIZE - 3, 8), segmentSizes(data))
+    assertEquals("a".repeat(Segment.SIZE - 3), data.readUtf8(Segment.SIZE - 3L))
+    assertEquals("[hex=abcdef0187654321]", data.toString())
+  }
+
+  @Test fun writeIntLe() {
+    sink.writeIntLe(-0x543210ff)
+    sink.writeIntLe(-0x789abcdf)
+    sink.flush()
+    assertEquals("[hex=01efcdab21436587]", data.toString())
+  }
+
+  @Test fun writeLong() {
+    sink.writeLong(-0x543210fe789abcdfL)
+    sink.writeLong(-0x350145414f4ea400L)
+    sink.flush()
+    assertEquals("[hex=abcdef0187654321cafebabeb0b15c00]", data.toString())
+  }
+
+  @Test fun writeLongLe() {
+    sink.writeLongLe(-0x543210fe789abcdfL)
+    sink.writeLongLe(-0x350145414f4ea400L)
+    sink.flush()
+    assertEquals("[hex=2143658701efcdab005cb1b0bebafeca]", data.toString())
+  }
+
+  @Test fun writeByteString() {
+    sink.write("təˈranəˌsôr".encodeUtf8())
+    sink.flush()
+    assertEquals("74c999cb8872616ec999cb8c73c3b472".decodeHex(), data.readByteString())
+  }
+
+  @Test fun writeByteStringOffset() {
+    sink.write("təˈranəˌsôr".encodeUtf8(), 5, 5)
+    sink.flush()
+    assertEquals("72616ec999".decodeHex(), data.readByteString())
+  }
+
+  @Test fun writeSegmentedByteString() {
+    sink.write(Buffer().write("təˈranəˌsôr".encodeUtf8()).snapshot())
+    sink.flush()
+    assertEquals("74c999cb8872616ec999cb8c73c3b472".decodeHex(), data.readByteString())
+  }
+
+  @Test fun writeSegmentedByteStringOffset() {
+    sink.write(Buffer().write("təˈranəˌsôr".encodeUtf8()).snapshot(), 5, 5)
+    sink.flush()
+    assertEquals("72616ec999".decodeHex(), data.readByteString())
+  }
+
+  @Test fun writeStringUtf8() {
+    sink.writeUtf8("təˈranəˌsôr")
+    sink.flush()
+    assertEquals("74c999cb8872616ec999cb8c73c3b472".decodeHex(), data.readByteString())
+  }
+
+  @Test fun writeSubstringUtf8() {
+    sink.writeUtf8("təˈranəˌsôr", 3, 7)
+    sink.flush()
+    assertEquals("72616ec999".decodeHex(), data.readByteString())
+  }
+
+  @Test fun writeAll() {
+    val source = Buffer().writeUtf8("abcdef")
+
+    assertEquals(6, sink.writeAll(source))
+    assertEquals(0, source.size)
+    sink.flush()
+    assertEquals("abcdef", data.readUtf8())
+  }
+
+  @Test fun writeSource() {
+    val source = Buffer().writeUtf8("abcdef")
+
+    // Force resolution of the Source method overload.
+    sink.write(source as Source, 4)
+    sink.flush()
+    assertEquals("abcd", data.readUtf8())
+    assertEquals("ef", source.readUtf8())
+  }
+
+  @Test fun writeSourceReadsFully() {
+    val source = object : Source by Buffer() {
+      override fun read(sink: Buffer, byteCount: Long): Long {
+        sink.writeUtf8("abcd")
+        return 4
+      }
+    }
+
+    sink.write(source, 8)
+    sink.flush()
+    assertEquals("abcdabcd", data.readUtf8())
+  }
+
+  @Test fun writeSourcePropagatesEof() {
+    val source: Source = Buffer().writeUtf8("abcd")
+
+    assertFailsWith<EOFException> {
+      sink.write(source, 8)
+    }
+
+    // Ensure that whatever was available was correctly written.
+    sink.flush()
+    assertEquals("abcd", data.readUtf8())
+  }
+
+  @Test fun writeSourceWithZeroIsNoOp() {
+    // This test ensures that a zero byte count never calls through to read the source. It may be
+    // tied to something like a socket which will potentially block trying to read a segment when
+    // ultimately we don't want any data.
+    val source = object : Source by Buffer() {
+      override fun read(sink: Buffer, byteCount: Long): Long {
+        throw AssertionError()
+      }
+    }
+    sink.write(source, 0)
+    assertEquals(0, data.size)
+  }
+
+  @Test fun writeAllExhausted() {
+    val source = Buffer()
+    assertEquals(0, sink.writeAll(source))
+    assertEquals(0, source.size)
+  }
+
+  @Test fun closeEmitsBufferedBytes() {
+    sink.writeByte('a'.toInt())
+    sink.close()
+    assertEquals('a', data.readByte().toChar())
+  }
+
+  @Test fun longDecimalString() {
+    assertLongDecimalString(0)
+    assertLongDecimalString(Long.MIN_VALUE)
+    assertLongDecimalString(Long.MAX_VALUE)
+
+    for (i in 1..19) {
+      val value = 10.0.pow(i).toLong()
+      assertLongDecimalString(value - 1)
+      assertLongDecimalString(value)
+    }
+  }
+
+  private fun assertLongDecimalString(value: Long) {
+    sink.writeDecimalLong(value).writeUtf8("zzz").flush()
+    val expected = "${value}zzz"
+    val actual = data.readUtf8()
+    assertEquals(expected, actual, "$value expected $expected but was $actual")
+  }
+
+  @Test fun longHexString() {
+    assertLongHexString(0)
+    assertLongHexString(Long.MIN_VALUE)
+    assertLongHexString(Long.MAX_VALUE)
+
+    for (i in 0..62) {
+      assertLongHexString((1L shl i) - 1)
+      assertLongHexString(1L shl i)
+    }
+  }
+
+  private fun assertLongHexString(value: Long) {
+    sink.writeHexadecimalUnsignedLong(value).writeUtf8("zzz").flush()
+    val expected = "${value.toHexString()}zzz"
+    val actual = data.readUtf8()
+    assertEquals(expected, actual, "$value expected $expected but was $actual")
+  }
+}
diff --git a/okio/src/commonTest/kotlin/okio/AbstractBufferedSourceTest.kt b/okio/src/commonTest/kotlin/okio/AbstractBufferedSourceTest.kt
new file mode 100644
index 0000000..b15d369
--- /dev/null
+++ b/okio/src/commonTest/kotlin/okio/AbstractBufferedSourceTest.kt
@@ -0,0 +1,1281 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+import okio.ByteString.Companion.decodeHex
+import okio.ByteString.Companion.encodeUtf8
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+import kotlin.test.fail
+
+class BufferSourceTest : AbstractBufferedSourceTest(BufferedSourceFactory.BUFFER)
+class RealBufferedSourceTest : AbstractBufferedSourceTest(BufferedSourceFactory.REAL_BUFFERED_SOURCE)
+class OneByteAtATimeBufferedSourceTest : AbstractBufferedSourceTest(BufferedSourceFactory.ONE_BYTE_AT_A_TIME_BUFFERED_SOURCE)
+class OneByteAtATimeBufferTest : AbstractBufferedSourceTest(BufferedSourceFactory.ONE_BYTE_AT_A_TIME_BUFFER)
+class PeekBufferTest : AbstractBufferedSourceTest(BufferedSourceFactory.PEEK_BUFFER)
+class PeekBufferedSourceTest : AbstractBufferedSourceTest(BufferedSourceFactory.PEEK_BUFFERED_SOURCE)
+
+abstract class AbstractBufferedSourceTest internal constructor(
+  private val factory: BufferedSourceFactory
+) {
+  private val sink: BufferedSink
+  private val source: BufferedSource
+
+  init {
+    val pipe = factory.pipe()
+    sink = pipe.sink
+    source = pipe.source
+  }
+
+  @Test fun readBytes() {
+    sink.write(byteArrayOf(0xab.toByte(), 0xcd.toByte()))
+    sink.emit()
+    assertEquals(0xab, (source.readByte() and 0xff).toLong())
+    assertEquals(0xcd, (source.readByte() and 0xff).toLong())
+    assertTrue(source.exhausted())
+  }
+
+  @Test fun readByteTooShortThrows() {
+    assertFailsWith<EOFException> {
+      source.readByte()
+    }
+  }
+
+  @Test fun readShort() {
+    sink.write(byteArrayOf(0xab.toByte(), 0xcd.toByte(), 0xef.toByte(), 0x01.toByte()))
+    sink.emit()
+    assertEquals(0xabcd.toShort().toLong(), source.readShort().toLong())
+    assertEquals(0xef01.toShort().toLong(), source.readShort().toLong())
+    assertTrue(source.exhausted())
+  }
+
+  @Test fun readShortLe() {
+    sink.write(byteArrayOf(0xab.toByte(), 0xcd.toByte(), 0xef.toByte(), 0x10.toByte()))
+    sink.emit()
+    assertEquals(0xcdab.toShort().toLong(), source.readShortLe().toLong())
+    assertEquals(0x10ef.toShort().toLong(), source.readShortLe().toLong())
+    assertTrue(source.exhausted())
+  }
+
+  @Test fun readShortSplitAcrossMultipleSegments() {
+    sink.writeUtf8("a".repeat(Segment.SIZE - 1))
+    sink.write(byteArrayOf(0xab.toByte(), 0xcd.toByte()))
+    sink.emit()
+    source.skip((Segment.SIZE - 1).toLong())
+    assertEquals(0xabcd.toShort().toLong(), source.readShort().toLong())
+    assertTrue(source.exhausted())
+  }
+
+  @Test fun readShortTooShortThrows() {
+    sink.writeShort(Short.MAX_VALUE.toInt())
+    sink.emit()
+    source.readByte()
+    assertFailsWith<EOFException> {
+      source.readShort()
+    }
+  }
+
+  @Test fun readShortLeTooShortThrows() {
+    sink.writeShortLe(Short.MAX_VALUE.toInt())
+    sink.emit()
+    source.readByte()
+    assertFailsWith<EOFException> {
+      source.readShortLe()
+    }
+  }
+
+  @Test fun readInt() {
+    sink.write(
+      byteArrayOf(
+        0xab.toByte(),
+        0xcd.toByte(),
+        0xef.toByte(),
+        0x01.toByte(),
+        0x87.toByte(),
+        0x65.toByte(),
+        0x43.toByte(),
+        0x21.toByte()
+      )
+    )
+    sink.emit()
+    assertEquals(-0x543210ff, source.readInt().toLong())
+    assertEquals(-0x789abcdf, source.readInt().toLong())
+    assertTrue(source.exhausted())
+  }
+
+  @Test fun readIntLe() {
+    sink.write(
+      byteArrayOf(
+        0xab.toByte(),
+        0xcd.toByte(),
+        0xef.toByte(),
+        0x10.toByte(),
+        0x87.toByte(),
+        0x65.toByte(),
+        0x43.toByte(),
+        0x21.toByte()
+      )
+    )
+    sink.emit()
+    assertEquals(0x10efcdab, source.readIntLe().toLong())
+    assertEquals(0x21436587, source.readIntLe().toLong())
+    assertTrue(source.exhausted())
+  }
+
+  @Test fun readIntSplitAcrossMultipleSegments() {
+    sink.writeUtf8("a".repeat(Segment.SIZE - 3))
+    sink.write(byteArrayOf(0xab.toByte(), 0xcd.toByte(), 0xef.toByte(), 0x01.toByte()))
+    sink.emit()
+    source.skip((Segment.SIZE - 3).toLong())
+    assertEquals(-0x543210ff, source.readInt().toLong())
+    assertTrue(source.exhausted())
+  }
+
+  @Test fun readIntTooShortThrows() {
+    sink.writeInt(Int.MAX_VALUE)
+    sink.emit()
+    source.readByte()
+    assertFailsWith<EOFException> {
+      source.readInt()
+    }
+  }
+
+  @Test fun readIntLeTooShortThrows() {
+    sink.writeIntLe(Int.MAX_VALUE)
+    sink.emit()
+    source.readByte()
+    assertFailsWith<EOFException> {
+      source.readIntLe()
+    }
+  }
+
+  @Test fun readLong() {
+    sink.write(
+      byteArrayOf(
+        0xab.toByte(),
+        0xcd.toByte(),
+        0xef.toByte(),
+        0x10.toByte(),
+        0x87.toByte(),
+        0x65.toByte(),
+        0x43.toByte(),
+        0x21.toByte(),
+        0x36.toByte(),
+        0x47.toByte(),
+        0x58.toByte(),
+        0x69.toByte(),
+        0x12.toByte(),
+        0x23.toByte(),
+        0x34.toByte(),
+        0x45.toByte()
+      )
+    )
+    sink.emit()
+    assertEquals(-0x543210ef789abcdfL, source.readLong())
+    assertEquals(0x3647586912233445L, source.readLong())
+    assertTrue(source.exhausted())
+  }
+
+  @Test fun readLongLe() {
+    sink.write(
+      byteArrayOf(
+        0xab.toByte(),
+        0xcd.toByte(),
+        0xef.toByte(),
+        0x10.toByte(),
+        0x87.toByte(),
+        0x65.toByte(),
+        0x43.toByte(),
+        0x21.toByte(),
+        0x36.toByte(),
+        0x47.toByte(),
+        0x58.toByte(),
+        0x69.toByte(),
+        0x12.toByte(),
+        0x23.toByte(),
+        0x34.toByte(),
+        0x45.toByte()
+      )
+    )
+    sink.emit()
+    assertEquals(0x2143658710efcdabL, source.readLongLe())
+    assertEquals(0x4534231269584736L, source.readLongLe())
+    assertTrue(source.exhausted())
+  }
+
+  @Test fun readLongSplitAcrossMultipleSegments() {
+    sink.writeUtf8("a".repeat(Segment.SIZE - 7))
+    sink.write(
+      byteArrayOf(
+        0xab.toByte(),
+        0xcd.toByte(),
+        0xef.toByte(),
+        0x01.toByte(),
+        0x87.toByte(),
+        0x65.toByte(),
+        0x43.toByte(),
+        0x21.toByte()
+      )
+    )
+    sink.emit()
+    source.skip((Segment.SIZE - 7).toLong())
+    assertEquals(-0x543210fe789abcdfL, source.readLong())
+    assertTrue(source.exhausted())
+  }
+
+  @Test fun readLongTooShortThrows() {
+    sink.writeLong(Long.MAX_VALUE)
+    sink.emit()
+    source.readByte()
+    assertFailsWith<EOFException> {
+      source.readLong()
+    }
+  }
+
+  @Test fun readLongLeTooShortThrows() {
+    sink.writeLongLe(Long.MAX_VALUE)
+    sink.emit()
+    source.readByte()
+    assertFailsWith<EOFException> {
+      source.readLongLe()
+    }
+  }
+
+  @Test fun readAll() {
+    source.buffer.writeUtf8("abc")
+    sink.writeUtf8("def")
+    sink.emit()
+
+    val sink = Buffer()
+    assertEquals(6, source.readAll(sink))
+    assertEquals("abcdef", sink.readUtf8())
+    assertTrue(source.exhausted())
+  }
+
+  @Test fun readAllExhausted() {
+    val mockSink = MockSink()
+    assertEquals(0, source.readAll(mockSink))
+    assertTrue(source.exhausted())
+    mockSink.assertLog()
+  }
+
+  @Test fun readExhaustedSource() {
+    val sink = Buffer()
+    sink.writeUtf8("a".repeat(10))
+    assertEquals(-1, source.read(sink, 10))
+    assertEquals(10, sink.size)
+    assertTrue(source.exhausted())
+  }
+
+  @Test fun readZeroBytesFromSource() {
+    val sink = Buffer()
+    sink.writeUtf8("a".repeat(10))
+
+    // Either 0 or -1 is reasonable here. For consistency with Android's
+    // ByteArrayInputStream we return 0.
+    assertEquals(-1, source.read(sink, 0))
+    assertEquals(10, sink.size)
+    assertTrue(source.exhausted())
+  }
+
+  @Test fun readFully() {
+    sink.writeUtf8("a".repeat(10000))
+    sink.emit()
+    val sink = Buffer()
+    source.readFully(sink, 9999)
+    assertEquals("a".repeat(9999), sink.readUtf8())
+    assertEquals("a", source.readUtf8())
+  }
+
+  @Test fun readFullyTooShortThrows() {
+    sink.writeUtf8("Hi")
+    sink.emit()
+    val sink = Buffer()
+    assertFailsWith<EOFException> {
+      source.readFully(sink, 5)
+    }
+
+    // Verify we read all that we could from the source.
+    assertEquals("Hi", sink.readUtf8())
+  }
+
+  @Test fun readFullyByteArray() {
+    val data = Buffer()
+    data.writeUtf8("Hello").writeUtf8("e".repeat(Segment.SIZE))
+
+    val expected = data.copy().readByteArray()
+    sink.write(data, data.size)
+    sink.emit()
+
+    val sink = ByteArray(Segment.SIZE + 5)
+    source.readFully(sink)
+    assertArrayEquals(expected, sink)
+  }
+
+  @Test fun readFullyByteArrayTooShortThrows() {
+    sink.writeUtf8("Hello")
+    sink.emit()
+
+    val array = ByteArray(6)
+    assertFailsWith<EOFException> {
+      source.readFully(array)
+    }
+
+    // Verify we read all that we could from the source.
+    assertArrayEquals(
+      byteArrayOf(
+        'H'.toByte(),
+        'e'.toByte(),
+        'l'.toByte(),
+        'l'.toByte(),
+        'o'.toByte(),
+        0
+      ),
+      array
+    )
+  }
+
+  @Test fun readIntoByteArray() {
+    sink.writeUtf8("abcd")
+    sink.emit()
+
+    val sink = ByteArray(3)
+    val read = source.read(sink)
+    if (factory.isOneByteAtATime) {
+      assertEquals(1, read.toLong())
+      val expected = byteArrayOf('a'.toByte(), 0, 0)
+      assertArrayEquals(expected, sink)
+    } else {
+      assertEquals(3, read.toLong())
+      val expected = byteArrayOf('a'.toByte(), 'b'.toByte(), 'c'.toByte())
+      assertArrayEquals(expected, sink)
+    }
+  }
+
+  @Test fun readIntoByteArrayNotEnough() {
+    sink.writeUtf8("abcd")
+    sink.emit()
+
+    val sink = ByteArray(5)
+    val read = source.read(sink)
+    if (factory.isOneByteAtATime) {
+      assertEquals(1, read.toLong())
+      val expected = byteArrayOf('a'.toByte(), 0, 0, 0, 0)
+      assertArrayEquals(expected, sink)
+    } else {
+      assertEquals(4, read.toLong())
+      val expected = byteArrayOf('a'.toByte(), 'b'.toByte(), 'c'.toByte(), 'd'.toByte(), 0)
+      assertArrayEquals(expected, sink)
+    }
+  }
+
+  @Test fun readIntoByteArrayOffsetAndCount() {
+    sink.writeUtf8("abcd")
+    sink.emit()
+
+    val sink = ByteArray(7)
+    val read = source.read(sink, 2, 3)
+    if (factory.isOneByteAtATime) {
+      assertEquals(1, read.toLong())
+      val expected = byteArrayOf(0, 0, 'a'.toByte(), 0, 0, 0, 0)
+      assertArrayEquals(expected, sink)
+    } else {
+      assertEquals(3, read.toLong())
+      val expected = byteArrayOf(0, 0, 'a'.toByte(), 'b'.toByte(), 'c'.toByte(), 0, 0)
+      assertArrayEquals(expected, sink)
+    }
+  }
+
+  @Test fun readByteArray() {
+    val string = "abcd" + "e".repeat(Segment.SIZE)
+    sink.writeUtf8(string)
+    sink.emit()
+    assertArrayEquals(string.asUtf8ToByteArray(), source.readByteArray())
+  }
+
+  @Test fun readByteArrayPartial() {
+    sink.writeUtf8("abcd")
+    sink.emit()
+    assertEquals("[97, 98, 99]", source.readByteArray(3).contentToString())
+    assertEquals("d", source.readUtf8(1))
+  }
+
+  @Test fun readByteArrayTooShortThrows() {
+    sink.writeUtf8("abc")
+    sink.emit()
+    assertFailsWith<EOFException> {
+      source.readByteArray(4)
+    }
+
+    assertEquals("abc", source.readUtf8()) // The read shouldn't consume any data.
+  }
+
+  @Test fun readByteString() {
+    sink.writeUtf8("abcd").writeUtf8("e".repeat(Segment.SIZE))
+    sink.emit()
+    assertEquals("abcd" + "e".repeat(Segment.SIZE), source.readByteString().utf8())
+  }
+
+  @Test fun readByteStringPartial() {
+    sink.writeUtf8("abcd").writeUtf8("e".repeat(Segment.SIZE))
+    sink.emit()
+    assertEquals("abc", source.readByteString(3).utf8())
+    assertEquals("d", source.readUtf8(1))
+  }
+
+  @Test fun readByteStringTooShortThrows() {
+    sink.writeUtf8("abc")
+    sink.emit()
+    assertFailsWith<EOFException> {
+      source.readByteString(4)
+    }
+
+    assertEquals("abc", source.readUtf8()) // The read shouldn't consume any data.
+  }
+
+  @Test fun readUtf8SpansSegments() {
+    sink.writeUtf8("a".repeat(Segment.SIZE * 2))
+    sink.emit()
+    source.skip((Segment.SIZE - 1).toLong())
+    assertEquals("aa", source.readUtf8(2))
+  }
+
+  @Test fun readUtf8Segment() {
+    sink.writeUtf8("a".repeat(Segment.SIZE))
+    sink.emit()
+    assertEquals("a".repeat(Segment.SIZE), source.readUtf8(Segment.SIZE.toLong()))
+  }
+
+  @Test fun readUtf8PartialBuffer() {
+    sink.writeUtf8("a".repeat(Segment.SIZE + 20))
+    sink.emit()
+    assertEquals("a".repeat(Segment.SIZE + 10), source.readUtf8((Segment.SIZE + 10).toLong()))
+  }
+
+  @Test fun readUtf8EntireBuffer() {
+    sink.writeUtf8("a".repeat(Segment.SIZE * 2))
+    sink.emit()
+    assertEquals("a".repeat(Segment.SIZE * 2), source.readUtf8())
+  }
+
+  @Test fun readUtf8TooShortThrows() {
+    sink.writeUtf8("abc")
+    sink.emit()
+    assertFailsWith<EOFException> {
+      source.readUtf8(4L)
+    }
+
+    assertEquals("abc", source.readUtf8()) // The read shouldn't consume any data.
+  }
+
+  @Test fun skip() {
+    sink.writeUtf8("a")
+    sink.writeUtf8("b".repeat(Segment.SIZE))
+    sink.writeUtf8("c")
+    sink.emit()
+    source.skip(1)
+    assertEquals('b'.toLong(), (source.readByte() and 0xff).toLong())
+    source.skip((Segment.SIZE - 2).toLong())
+    assertEquals('b'.toLong(), (source.readByte() and 0xff).toLong())
+    source.skip(1)
+    assertTrue(source.exhausted())
+  }
+
+  @Test fun skipInsufficientData() {
+    sink.writeUtf8("a")
+    sink.emit()
+
+    assertFailsWith<EOFException> {
+      source.skip(2)
+    }
+  }
+
+  @Test fun indexOf() {
+    // The segment is empty.
+    assertEquals(-1, source.indexOf('a'.toByte()))
+
+    // The segment has one value.
+    sink.writeUtf8("a") // a
+    sink.emit()
+    assertEquals(0, source.indexOf('a'.toByte()))
+    assertEquals(-1, source.indexOf('b'.toByte()))
+
+    // The segment has lots of data.
+    sink.writeUtf8("b".repeat(Segment.SIZE - 2)) // ab...b
+    sink.emit()
+    assertEquals(0, source.indexOf('a'.toByte()))
+    assertEquals(1, source.indexOf('b'.toByte()))
+    assertEquals(-1, source.indexOf('c'.toByte()))
+
+    // The segment doesn't start at 0, it starts at 2.
+    source.skip(2) // b...b
+    assertEquals(-1, source.indexOf('a'.toByte()))
+    assertEquals(0, source.indexOf('b'.toByte()))
+    assertEquals(-1, source.indexOf('c'.toByte()))
+
+    // The segment is full.
+    sink.writeUtf8("c") // b...bc
+    sink.emit()
+    assertEquals(-1, source.indexOf('a'.toByte()))
+    assertEquals(0, source.indexOf('b'.toByte()))
+    assertEquals((Segment.SIZE - 3).toLong(), source.indexOf('c'.toByte()))
+
+    // The segment doesn't start at 2, it starts at 4.
+    source.skip(2) // b...bc
+    assertEquals(-1, source.indexOf('a'.toByte()))
+    assertEquals(0, source.indexOf('b'.toByte()))
+    assertEquals((Segment.SIZE - 5).toLong(), source.indexOf('c'.toByte()))
+
+    // Two segments.
+    sink.writeUtf8("d") // b...bcd, d is in the 2nd segment.
+    sink.emit()
+    assertEquals((Segment.SIZE - 4).toLong(), source.indexOf('d'.toByte()))
+    assertEquals(-1, source.indexOf('e'.toByte()))
+  }
+
+  @Test fun indexOfByteWithStartOffset() {
+    sink.writeUtf8("a").writeUtf8("b".repeat(Segment.SIZE)).writeUtf8("c")
+    sink.emit()
+    assertEquals(-1, source.indexOf('a'.toByte(), 1))
+    assertEquals(15, source.indexOf('b'.toByte(), 15))
+  }
+
+  @Test fun indexOfByteWithBothOffsets() {
+    if (factory.isOneByteAtATime) {
+      // When run on Travis this causes out-of-memory errors.
+      return
+    }
+    val a = 'a'.toByte()
+    val c = 'c'.toByte()
+
+    val size = Segment.SIZE * 5
+    val bytes = ByteArray(size) { a }
+
+    // These are tricky places where the buffer
+    // starts, ends, or segments come together.
+    val points = intArrayOf(
+      0,
+      1,
+      2,
+      Segment.SIZE - 1,
+      Segment.SIZE,
+      Segment.SIZE + 1,
+      size / 2 - 1,
+      size / 2,
+      size / 2 + 1,
+      size - Segment.SIZE - 1,
+      size - Segment.SIZE,
+      size - Segment.SIZE + 1,
+      size - 3,
+      size - 2,
+      size - 1
+    )
+
+    // In each iteration, we write c to the known point and then search for it using different
+    // windows. Some of the windows don't overlap with c's position, and therefore a match shouldn't
+    // be found.
+    for (p in points) {
+      bytes[p] = c
+      sink.write(bytes)
+      sink.emit()
+
+      assertEquals(p.toLong(), source.indexOf(c, 0, size.toLong()))
+      assertEquals(p.toLong(), source.indexOf(c, 0, (p + 1).toLong()))
+      assertEquals(p.toLong(), source.indexOf(c, p.toLong(), size.toLong()))
+      assertEquals(p.toLong(), source.indexOf(c, p.toLong(), (p + 1).toLong()))
+      assertEquals(p.toLong(), source.indexOf(c, (p / 2).toLong(), (p * 2 + 1).toLong()))
+      assertEquals(-1, source.indexOf(c, 0, (p / 2).toLong()))
+      assertEquals(-1, source.indexOf(c, 0, p.toLong()))
+      assertEquals(-1, source.indexOf(c, 0, 0))
+      assertEquals(-1, source.indexOf(c, p.toLong(), p.toLong()))
+
+      // Reset.
+      source.readUtf8()
+      bytes[p] = a
+    }
+  }
+
+  @Test fun indexOfByteInvalidBoundsThrows() {
+    sink.writeUtf8("abc")
+    sink.emit()
+
+    try {
+      source.indexOf('a'.toByte(), -1)
+      fail("Expected failure: fromIndex < 0")
+    } catch (expected: IllegalArgumentException) {
+    }
+
+    try {
+      source.indexOf('a'.toByte(), 10, 0)
+      fail("Expected failure: fromIndex > toIndex")
+    } catch (expected: IllegalArgumentException) {
+    }
+  }
+
+  @Test fun indexOfByteString() {
+    assertEquals(-1, source.indexOf("flop".encodeUtf8()))
+
+    sink.writeUtf8("flip flop")
+    sink.emit()
+    assertEquals(5, source.indexOf("flop".encodeUtf8()))
+    source.readUtf8() // Clear stream.
+
+    // Make sure we backtrack and resume searching after partial match.
+    sink.writeUtf8("hi hi hi hey")
+    sink.emit()
+    assertEquals(3, source.indexOf("hi hi hey".encodeUtf8()))
+  }
+
+  @Test fun indexOfByteStringAtSegmentBoundary() {
+    sink.writeUtf8("a".repeat(Segment.SIZE - 1))
+    sink.writeUtf8("bcd")
+    sink.emit()
+    assertEquals(
+      (Segment.SIZE - 3).toLong(),
+      source.indexOf("aabc".encodeUtf8(), (Segment.SIZE - 4).toLong())
+    )
+    assertEquals(
+      (Segment.SIZE - 3).toLong(),
+      source.indexOf("aabc".encodeUtf8(), (Segment.SIZE - 3).toLong())
+    )
+    assertEquals(
+      (Segment.SIZE - 2).toLong(),
+      source.indexOf("abcd".encodeUtf8(), (Segment.SIZE - 2).toLong())
+    )
+    assertEquals(
+      (Segment.SIZE - 2).toLong(),
+      source.indexOf("abc".encodeUtf8(), (Segment.SIZE - 2).toLong())
+    )
+    assertEquals(
+      (Segment.SIZE - 2).toLong(),
+      source.indexOf("abc".encodeUtf8(), (Segment.SIZE - 2).toLong())
+    )
+    assertEquals(
+      (Segment.SIZE - 2).toLong(),
+      source.indexOf("ab".encodeUtf8(), (Segment.SIZE - 2).toLong())
+    )
+    assertEquals(
+      (Segment.SIZE - 2).toLong(),
+      source.indexOf("a".encodeUtf8(), (Segment.SIZE - 2).toLong())
+    )
+    assertEquals(
+      (Segment.SIZE - 1).toLong(),
+      source.indexOf("bc".encodeUtf8(), (Segment.SIZE - 2).toLong())
+    )
+    assertEquals(
+      (Segment.SIZE - 1).toLong(),
+      source.indexOf("b".encodeUtf8(), (Segment.SIZE - 2).toLong())
+    )
+    assertEquals(
+      Segment.SIZE.toLong(),
+      source.indexOf("c".encodeUtf8(), (Segment.SIZE - 2).toLong())
+    )
+    assertEquals(
+      Segment.SIZE.toLong(),
+      source.indexOf("c".encodeUtf8(), Segment.SIZE.toLong())
+    )
+    assertEquals(
+      (Segment.SIZE + 1).toLong(),
+      source.indexOf("d".encodeUtf8(), (Segment.SIZE - 2).toLong())
+    )
+    assertEquals(
+      (Segment.SIZE + 1).toLong(),
+      source.indexOf("d".encodeUtf8(), (Segment.SIZE + 1).toLong())
+    )
+  }
+
+  @Test fun indexOfDoesNotWrapAround() {
+    sink.writeUtf8("a".repeat(Segment.SIZE - 1))
+    sink.writeUtf8("bcd")
+    sink.emit()
+    assertEquals(-1, source.indexOf("abcda".encodeUtf8(), (Segment.SIZE - 3).toLong()))
+  }
+
+  @Test fun indexOfByteStringWithOffset() {
+    assertEquals(-1, source.indexOf("flop".encodeUtf8(), 1))
+
+    sink.writeUtf8("flop flip flop")
+    sink.emit()
+    assertEquals(10, source.indexOf("flop".encodeUtf8(), 1))
+    source.readUtf8() // Clear stream
+
+    // Make sure we backtrack and resume searching after partial match.
+    sink.writeUtf8("hi hi hi hi hey")
+    sink.emit()
+    assertEquals(6, source.indexOf("hi hi hey".encodeUtf8(), 1))
+  }
+
+  @Test fun indexOfByteStringInvalidArgumentsThrows() {
+    try {
+      source.indexOf(ByteString.of())
+      fail()
+    } catch (e: IllegalArgumentException) {
+      assertEquals("bytes is empty", e.message)
+    }
+
+    try {
+      source.indexOf("hi".encodeUtf8(), -1)
+      fail()
+    } catch (e: IllegalArgumentException) {
+      assertEquals("fromIndex < 0: -1", e.message)
+    }
+  }
+
+  /**
+   * With [BufferedSourceFactory.ONE_BYTE_AT_A_TIME_BUFFERED_SOURCE], this code was extremely slow.
+   * https://github.com/square/okio/issues/171
+   */
+  @Test fun indexOfByteStringAcrossSegmentBoundaries() {
+    sink.writeUtf8("a".repeat(Segment.SIZE * 2 - 3))
+    sink.writeUtf8("bcdefg")
+    sink.emit()
+    assertEquals((Segment.SIZE * 2 - 4).toLong(), source.indexOf("ab".encodeUtf8()))
+    assertEquals((Segment.SIZE * 2 - 4).toLong(), source.indexOf("abc".encodeUtf8()))
+    assertEquals((Segment.SIZE * 2 - 4).toLong(), source.indexOf("abcd".encodeUtf8()))
+    assertEquals((Segment.SIZE * 2 - 4).toLong(), source.indexOf("abcde".encodeUtf8()))
+    assertEquals((Segment.SIZE * 2 - 4).toLong(), source.indexOf("abcdef".encodeUtf8()))
+    assertEquals((Segment.SIZE * 2 - 4).toLong(), source.indexOf("abcdefg".encodeUtf8()))
+    assertEquals((Segment.SIZE * 2 - 3).toLong(), source.indexOf("bcdefg".encodeUtf8()))
+    assertEquals((Segment.SIZE * 2 - 2).toLong(), source.indexOf("cdefg".encodeUtf8()))
+    assertEquals((Segment.SIZE * 2 - 1).toLong(), source.indexOf("defg".encodeUtf8()))
+    assertEquals((Segment.SIZE * 2).toLong(), source.indexOf("efg".encodeUtf8()))
+    assertEquals((Segment.SIZE * 2 + 1).toLong(), source.indexOf("fg".encodeUtf8()))
+    assertEquals((Segment.SIZE * 2 + 2).toLong(), source.indexOf("g".encodeUtf8()))
+  }
+
+  @Test fun indexOfElement() {
+    sink.writeUtf8("a").writeUtf8("b".repeat(Segment.SIZE)).writeUtf8("c")
+    sink.emit()
+    assertEquals(0, source.indexOfElement("DEFGaHIJK".encodeUtf8()))
+    assertEquals(1, source.indexOfElement("DEFGHIJKb".encodeUtf8()))
+    assertEquals((Segment.SIZE + 1).toLong(), source.indexOfElement("cDEFGHIJK".encodeUtf8()))
+    assertEquals(1, source.indexOfElement("DEFbGHIc".encodeUtf8()))
+    assertEquals(-1L, source.indexOfElement("DEFGHIJK".encodeUtf8()))
+    assertEquals(-1L, source.indexOfElement("".encodeUtf8()))
+  }
+
+  @Test fun indexOfElementWithOffset() {
+    sink.writeUtf8("a").writeUtf8("b".repeat(Segment.SIZE)).writeUtf8("c")
+    sink.emit()
+    assertEquals(-1, source.indexOfElement("DEFGaHIJK".encodeUtf8(), 1))
+    assertEquals(15, source.indexOfElement("DEFGHIJKb".encodeUtf8(), 15))
+  }
+
+  @Test fun indexOfByteWithFromIndex() {
+    sink.writeUtf8("aaa")
+    sink.emit()
+    assertEquals(0, source.indexOf('a'.toByte()))
+    assertEquals(0, source.indexOf('a'.toByte(), 0))
+    assertEquals(1, source.indexOf('a'.toByte(), 1))
+    assertEquals(2, source.indexOf('a'.toByte(), 2))
+  }
+
+  @Test fun indexOfByteStringWithFromIndex() {
+    sink.writeUtf8("aaa")
+    sink.emit()
+    assertEquals(0, source.indexOf("a".encodeUtf8()))
+    assertEquals(0, source.indexOf("a".encodeUtf8(), 0))
+    assertEquals(1, source.indexOf("a".encodeUtf8(), 1))
+    assertEquals(2, source.indexOf("a".encodeUtf8(), 2))
+  }
+
+  @Test fun indexOfElementWithFromIndex() {
+    sink.writeUtf8("aaa")
+    sink.emit()
+    assertEquals(0, source.indexOfElement("a".encodeUtf8()))
+    assertEquals(0, source.indexOfElement("a".encodeUtf8(), 0))
+    assertEquals(1, source.indexOfElement("a".encodeUtf8(), 1))
+    assertEquals(2, source.indexOfElement("a".encodeUtf8(), 2))
+  }
+
+  @Test fun request() {
+    sink.writeUtf8("a").writeUtf8("b".repeat(Segment.SIZE)).writeUtf8("c")
+    sink.emit()
+    assertTrue(source.request((Segment.SIZE + 2).toLong()))
+    assertFalse(source.request((Segment.SIZE + 3).toLong()))
+  }
+
+  @Test fun require() {
+    sink.writeUtf8("a").writeUtf8("b".repeat(Segment.SIZE)).writeUtf8("c")
+    sink.emit()
+    source.require((Segment.SIZE + 2).toLong())
+    assertFailsWith<EOFException> {
+      source.require((Segment.SIZE + 3).toLong())
+    }
+  }
+
+  @Test fun longHexString() {
+    assertLongHexString("8000000000000000", Long.MIN_VALUE)
+    assertLongHexString("fffffffffffffffe", -0x2L)
+    assertLongHexString("FFFFFFFFFFFFFFFe", -0x2L)
+    assertLongHexString("ffffffffffffffff", -0x1L)
+    assertLongHexString("FFFFFFFFFFFFFFFF", -0x1L)
+    assertLongHexString("0000000000000000", 0x0L)
+    assertLongHexString("0000000000000001", 0x1L)
+    assertLongHexString("7999999999999999", 0x7999999999999999L)
+
+    assertLongHexString("FF", 0xFF)
+    assertLongHexString("0000000000000001", 0x1)
+  }
+
+  @Test fun hexStringWithManyLeadingZeros() {
+    assertLongHexString("00000000000000001", 0x1)
+    assertLongHexString("0000000000000000ffffffffffffffff", -0x1L)
+    assertLongHexString("00000000000000007fffffffffffffff", 0x7fffffffffffffffL)
+    assertLongHexString("0".repeat(Segment.SIZE + 1) + "1", 0x1)
+  }
+
+  private fun assertLongHexString(s: String, expected: Long) {
+    sink.writeUtf8(s)
+    sink.emit()
+    val actual = source.readHexadecimalUnsignedLong()
+    assertEquals(expected, actual, "$s --> $expected")
+  }
+
+  @Test fun longHexStringAcrossSegment() {
+    sink.writeUtf8("a".repeat(Segment.SIZE - 8)).writeUtf8("FFFFFFFFFFFFFFFF")
+    sink.emit()
+    source.skip((Segment.SIZE - 8).toLong())
+    assertEquals(-1, source.readHexadecimalUnsignedLong())
+  }
+
+  @Test fun longHexStringTooLongThrows() {
+    try {
+      sink.writeUtf8("fffffffffffffffff")
+      sink.emit()
+      source.readHexadecimalUnsignedLong()
+      fail()
+    } catch (e: NumberFormatException) {
+      assertEquals("Number too large: fffffffffffffffff", e.message)
+    }
+  }
+
+  @Test fun longHexStringTooShortThrows() {
+    try {
+      sink.writeUtf8(" ")
+      sink.emit()
+      source.readHexadecimalUnsignedLong()
+      fail()
+    } catch (e: NumberFormatException) {
+      assertEquals("Expected leading [0-9a-fA-F] character but was 0x20", e.message)
+    }
+  }
+
+  @Test fun longHexEmptySourceThrows() {
+    try {
+      sink.writeUtf8("")
+      sink.emit()
+      source.readHexadecimalUnsignedLong()
+      fail()
+    } catch (expected: EOFException) {
+    }
+  }
+
+  @Test fun longDecimalString() {
+    assertLongDecimalString("-9223372036854775808", Long.MIN_VALUE)
+    assertLongDecimalString("-1", -1L)
+    assertLongDecimalString("0", 0L)
+    assertLongDecimalString("1", 1L)
+    assertLongDecimalString("9223372036854775807", Long.MAX_VALUE)
+
+    assertLongDecimalString("00000001", 1L)
+    assertLongDecimalString("-000001", -1L)
+  }
+
+  private fun assertLongDecimalString(s: String, expected: Long) {
+    sink.writeUtf8(s)
+    sink.writeUtf8("zzz")
+    sink.emit()
+    val actual = source.readDecimalLong()
+    assertEquals(expected, actual, "$s --> $expected")
+    assertEquals("zzz", source.readUtf8())
+  }
+
+  @Test fun longDecimalStringAcrossSegment() {
+    sink.writeUtf8("a".repeat(Segment.SIZE - 8)).writeUtf8("1234567890123456")
+    sink.writeUtf8("zzz")
+    sink.emit()
+    source.skip((Segment.SIZE - 8).toLong())
+    assertEquals(1234567890123456L, source.readDecimalLong())
+    assertEquals("zzz", source.readUtf8())
+  }
+
+  @Test fun longDecimalStringTooLongThrows() {
+    try {
+      sink.writeUtf8("12345678901234567890") // Too many digits.
+      sink.emit()
+      source.readDecimalLong()
+      fail()
+    } catch (e: NumberFormatException) {
+      assertEquals("Number too large: 12345678901234567890", e.message)
+    }
+  }
+
+  @Test fun longDecimalStringTooHighThrows() {
+    try {
+      sink.writeUtf8("9223372036854775808") // Right size but cannot fit.
+      sink.emit()
+      source.readDecimalLong()
+      fail()
+    } catch (e: NumberFormatException) {
+      assertEquals("Number too large: 9223372036854775808", e.message)
+    }
+  }
+
+  @Test fun longDecimalStringTooLowThrows() {
+    try {
+      sink.writeUtf8("-9223372036854775809") // Right size but cannot fit.
+      sink.emit()
+      source.readDecimalLong()
+      fail()
+    } catch (e: NumberFormatException) {
+      assertEquals("Number too large: -9223372036854775809", e.message)
+    }
+  }
+
+  @Test fun longDecimalStringTooShortThrows() {
+    try {
+      sink.writeUtf8(" ")
+      sink.emit()
+      source.readDecimalLong()
+      fail()
+    } catch (e: NumberFormatException) {
+      assertEquals("Expected leading [0-9] or '-' character but was 0x20", e.message)
+    }
+  }
+
+  @Test fun longDecimalEmptyThrows() {
+    try {
+      sink.writeUtf8("")
+      sink.emit()
+      source.readDecimalLong()
+      fail()
+    } catch (expected: EOFException) {
+    }
+  }
+
+  @Test fun codePoints() {
+    sink.write("7f".decodeHex())
+    sink.emit()
+    assertEquals(0x7f, source.readUtf8CodePoint().toLong())
+
+    sink.write("dfbf".decodeHex())
+    sink.emit()
+    assertEquals(0x07ff, source.readUtf8CodePoint().toLong())
+
+    sink.write("efbfbf".decodeHex())
+    sink.emit()
+    assertEquals(0xffff, source.readUtf8CodePoint().toLong())
+
+    sink.write("f48fbfbf".decodeHex())
+    sink.emit()
+    assertEquals(0x10ffff, source.readUtf8CodePoint().toLong())
+  }
+
+  @Test fun decimalStringWithManyLeadingZeros() {
+    assertLongDecimalString("00000000000000001", 1)
+    assertLongDecimalString("00000000000000009223372036854775807", Long.MAX_VALUE)
+    assertLongDecimalString("-00000000000000009223372036854775808", Long.MIN_VALUE)
+    assertLongDecimalString("0".repeat(Segment.SIZE + 1) + "1", 1)
+  }
+
+  @Test fun select() {
+    val options = Options.of(
+      "ROCK".encodeUtf8(),
+      "SCISSORS".encodeUtf8(),
+      "PAPER".encodeUtf8()
+    )
+
+    sink.writeUtf8("PAPER,SCISSORS,ROCK")
+    sink.emit()
+    assertEquals(2, source.select(options).toLong())
+    assertEquals(','.toLong(), source.readByte().toLong())
+    assertEquals(1, source.select(options).toLong())
+    assertEquals(','.toLong(), source.readByte().toLong())
+    assertEquals(0, source.select(options).toLong())
+    assertTrue(source.exhausted())
+  }
+
+  /** Note that this test crashes the VM on Android. */
+  @Test fun selectSpanningMultipleSegments() {
+    val commonPrefix = randomBytes(Segment.SIZE + 10)
+    val a = Buffer().write(commonPrefix).writeUtf8("a").readByteString()
+    val bc = Buffer().write(commonPrefix).writeUtf8("bc").readByteString()
+    val bd = Buffer().write(commonPrefix).writeUtf8("bd").readByteString()
+    val options = Options.of(a, bc, bd)
+
+    sink.write(bd)
+    sink.write(a)
+    sink.write(bc)
+    sink.emit()
+
+    assertEquals(2, source.select(options).toLong())
+    assertEquals(0, source.select(options).toLong())
+    assertEquals(1, source.select(options).toLong())
+    assertTrue(source.exhausted())
+  }
+
+  @Test fun selectNotFound() {
+    val options = Options.of(
+      "ROCK".encodeUtf8(),
+      "SCISSORS".encodeUtf8(),
+      "PAPER".encodeUtf8()
+    )
+
+    sink.writeUtf8("SPOCK")
+    sink.emit()
+    assertEquals(-1, source.select(options).toLong())
+    assertEquals("SPOCK", source.readUtf8())
+  }
+
+  @Test fun selectValuesHaveCommonPrefix() {
+    val options = Options.of(
+      "abcd".encodeUtf8(),
+      "abce".encodeUtf8(),
+      "abcc".encodeUtf8()
+    )
+
+    sink.writeUtf8("abcc").writeUtf8("abcd").writeUtf8("abce")
+    sink.emit()
+    assertEquals(2, source.select(options).toLong())
+    assertEquals(0, source.select(options).toLong())
+    assertEquals(1, source.select(options).toLong())
+  }
+
+  @Test fun selectLongerThanSource() {
+    val options = Options.of(
+      "abcd".encodeUtf8(),
+      "abce".encodeUtf8(),
+      "abcc".encodeUtf8()
+    )
+    sink.writeUtf8("abc")
+    sink.emit()
+    assertEquals(-1, source.select(options).toLong())
+    assertEquals("abc", source.readUtf8())
+  }
+
+  @Test fun selectReturnsFirstByteStringThatMatches() {
+    val options = Options.of(
+      "abcd".encodeUtf8(),
+      "abc".encodeUtf8(),
+      "abcde".encodeUtf8()
+    )
+    sink.writeUtf8("abcdef")
+    sink.emit()
+    assertEquals(0, source.select(options).toLong())
+    assertEquals("ef", source.readUtf8())
+  }
+
+  @Test fun selectFromEmptySource() {
+    val options = Options.of(
+      "abc".encodeUtf8(),
+      "def".encodeUtf8()
+    )
+    assertEquals(-1, source.select(options).toLong())
+  }
+
+  @Test fun selectNoByteStringsFromEmptySource() {
+    val options = Options.of()
+    assertEquals(-1, source.select(options).toLong())
+  }
+
+  @Test fun peek() {
+    sink.writeUtf8("abcdefghi")
+    sink.emit()
+
+    assertEquals("abc", source.readUtf8(3))
+
+    val peek = source.peek()
+    assertEquals("def", peek.readUtf8(3))
+    assertEquals("ghi", peek.readUtf8(3))
+    assertFalse(peek.request(1))
+
+    assertEquals("def", source.readUtf8(3))
+  }
+
+  @Test fun peekMultiple() {
+    sink.writeUtf8("abcdefghi")
+    sink.emit()
+
+    assertEquals("abc", source.readUtf8(3))
+
+    val peek1 = source.peek()
+    val peek2 = source.peek()
+
+    assertEquals("def", peek1.readUtf8(3))
+
+    assertEquals("def", peek2.readUtf8(3))
+    assertEquals("ghi", peek2.readUtf8(3))
+    assertFalse(peek2.request(1))
+
+    assertEquals("ghi", peek1.readUtf8(3))
+    assertFalse(peek1.request(1))
+
+    assertEquals("def", source.readUtf8(3))
+  }
+
+  @Test fun peekLarge() {
+    sink.writeUtf8("abcdef")
+    sink.writeUtf8("g".repeat(2 * Segment.SIZE))
+    sink.writeUtf8("hij")
+    sink.emit()
+
+    assertEquals("abc", source.readUtf8(3))
+
+    val peek = source.peek()
+    assertEquals("def", peek.readUtf8(3))
+    peek.skip((2 * Segment.SIZE).toLong())
+    assertEquals("hij", peek.readUtf8(3))
+    assertFalse(peek.request(1))
+
+    assertEquals("def", source.readUtf8(3))
+    source.skip((2 * Segment.SIZE).toLong())
+    assertEquals("hij", source.readUtf8(3))
+  }
+
+  @Test fun peekInvalid() {
+    sink.writeUtf8("abcdefghi")
+    sink.emit()
+
+    assertEquals("abc", source.readUtf8(3))
+
+    val peek = source.peek()
+    assertEquals("def", peek.readUtf8(3))
+    assertEquals("ghi", peek.readUtf8(3))
+    assertFalse(peek.request(1))
+
+    assertEquals("def", source.readUtf8(3))
+
+    try {
+      peek.readUtf8()
+      fail()
+    } catch (e: IllegalStateException) {
+      assertEquals("Peek source is invalid because upstream source was used", e.message)
+    }
+  }
+
+  @Test fun peekSegmentThenInvalid() {
+    sink.writeUtf8("abc")
+    sink.writeUtf8("d".repeat(2 * Segment.SIZE))
+    sink.emit()
+
+    assertEquals("abc", source.readUtf8(3))
+
+    // Peek a little data and skip the rest of the upstream source
+    val peek = source.peek()
+    assertEquals("ddd", peek.readUtf8(3))
+    source.readAll(blackholeSink())
+
+    // Skip the rest of the buffered data
+    peek.skip(peek.buffer.size)
+
+    try {
+      peek.readByte()
+      fail()
+    } catch (e: IllegalStateException) {
+      assertEquals("Peek source is invalid because upstream source was used", e.message)
+    }
+  }
+
+  @Test fun peekDoesntReadTooMuch() {
+    // 6 bytes in source's buffer plus 3 bytes upstream.
+    sink.writeUtf8("abcdef")
+    sink.emit()
+    source.require(6L)
+    sink.writeUtf8("ghi")
+    sink.emit()
+
+    val peek = source.peek()
+
+    // Read 3 bytes. This reads some of the buffered data.
+    assertTrue(peek.request(3))
+    if (source !is Buffer) {
+      assertEquals(6, source.buffer.size)
+      assertEquals(6, peek.buffer.size)
+    }
+    assertEquals("abc", peek.readUtf8(3L))
+
+    // Read 3 more bytes. This exhausts the buffered data.
+    assertTrue(peek.request(3))
+    if (source !is Buffer) {
+      assertEquals(6, source.buffer.size)
+      assertEquals(3, peek.buffer.size)
+    }
+    assertEquals("def", peek.readUtf8(3L))
+
+    // Read 3 more bytes. This draws new bytes.
+    assertTrue(peek.request(3))
+    assertEquals(9, source.buffer.size)
+    assertEquals(3, peek.buffer.size)
+    assertEquals("ghi", peek.readUtf8(3L))
+  }
+
+  @Test fun rangeEquals() {
+    sink.writeUtf8("A man, a plan, a canal. Panama.")
+    sink.emit()
+    assertTrue(source.rangeEquals(7, "a plan".encodeUtf8()))
+    assertTrue(source.rangeEquals(0, "A man".encodeUtf8()))
+    assertTrue(source.rangeEquals(24, "Panama".encodeUtf8()))
+    assertFalse(source.rangeEquals(24, "Panama. Panama. Panama.".encodeUtf8()))
+  }
+
+  @Test fun rangeEqualsWithOffsetAndCount() {
+    sink.writeUtf8("A man, a plan, a canal. Panama.")
+    sink.emit()
+    assertTrue(source.rangeEquals(7, "aaa plannn".encodeUtf8(), 2, 6))
+    assertTrue(source.rangeEquals(0, "AAA mannn".encodeUtf8(), 2, 5))
+    assertTrue(source.rangeEquals(24, "PPPanamaaa".encodeUtf8(), 2, 6))
+  }
+
+  @Test fun rangeEqualsOnlyReadsUntilMismatch() {
+    if (factory !== BufferedSourceFactory.ONE_BYTE_AT_A_TIME_BUFFERED_SOURCE) return // Other sources read in chunks anyway.
+
+    sink.writeUtf8("A man, a plan, a canal. Panama.")
+    sink.emit()
+    assertFalse(source.rangeEquals(0, ("A man.").encodeUtf8()))
+    assertEquals("A man,", source.buffer.readUtf8())
+  }
+
+  @Test fun rangeEqualsArgumentValidation() {
+    // Negative source offset.
+    assertFalse(source.rangeEquals(-1, "A".encodeUtf8()))
+    // Negative bytes offset.
+    assertFalse(source.rangeEquals(0, "A".encodeUtf8(), -1, 1))
+    // Bytes offset longer than bytes length.
+    assertFalse(source.rangeEquals(0, "A".encodeUtf8(), 2, 1))
+    // Negative byte count.
+    assertFalse(source.rangeEquals(0, "A".encodeUtf8(), 0, -1))
+    // Byte count longer than bytes length.
+    assertFalse(source.rangeEquals(0, "A".encodeUtf8(), 0, 2))
+    // Bytes offset plus byte count longer than bytes length.
+    assertFalse(source.rangeEquals(0, "A".encodeUtf8(), 1, 1))
+  }
+
+  @Test fun factorySegmentSizes() {
+    sink.writeUtf8("abc")
+    sink.emit()
+    source.require(3)
+    if (factory.isOneByteAtATime) {
+      assertEquals(listOf(1, 1, 1), segmentSizes(source.buffer))
+    } else {
+      assertEquals(listOf(3), segmentSizes(source.buffer))
+    }
+  }
+}
diff --git a/okio/src/commonTest/kotlin/okio/BufferCommonTest.kt b/okio/src/commonTest/kotlin/okio/BufferCommonTest.kt
new file mode 100644
index 0000000..842faff
--- /dev/null
+++ b/okio/src/commonTest/kotlin/okio/BufferCommonTest.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+import okio.ByteString.Companion.encodeUtf8
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+class BufferCommonTest {
+
+  @Test fun copyToBuffer() {
+    val source = Buffer()
+    source.write("party".encodeUtf8())
+
+    val target = Buffer()
+    source.copyTo(target)
+    assertEquals("party", target.readByteString().utf8())
+    assertEquals("party", source.readByteString().utf8())
+  }
+
+  @Test fun copyToBufferWithOffset() {
+    val source = Buffer()
+    source.write("party".encodeUtf8())
+
+    val target = Buffer()
+    source.copyTo(target, 2)
+    assertEquals("rty", target.readByteString().utf8())
+    assertEquals("party", source.readByteString().utf8())
+  }
+
+  @Test fun copyToBufferWithByteCount() {
+    val source = Buffer()
+    source.write("party".encodeUtf8())
+
+    val target = Buffer()
+    source.copyTo(target, 0, 3)
+    assertEquals("par", target.readByteString().utf8())
+    assertEquals("party", source.readByteString().utf8())
+  }
+
+  @Test fun copyToBufferWithOffsetAndByteCount() {
+    val source = Buffer()
+    source.write("party".encodeUtf8())
+
+    val target = Buffer()
+    source.copyTo(target, 1, 3)
+    assertEquals("art", target.readByteString().utf8())
+    assertEquals("party", source.readByteString().utf8())
+  }
+
+  @Test fun completeSegmentByteCountOnEmptyBuffer() {
+    val buffer = Buffer()
+    assertEquals(0, buffer.completeSegmentByteCount())
+  }
+
+  @Test fun completeSegmentByteCountOnBufferWithFullSegments() {
+    val buffer = Buffer()
+    buffer.writeUtf8("a".repeat(Segment.SIZE * 4))
+    assertEquals((Segment.SIZE * 4).toLong(), buffer.completeSegmentByteCount())
+  }
+
+  @Test fun completeSegmentByteCountOnBufferWithIncompleteTailSegment() {
+    val buffer = Buffer()
+    buffer.writeUtf8("a".repeat(Segment.SIZE * 4 - 10))
+    assertEquals((Segment.SIZE * 3).toLong(), buffer.completeSegmentByteCount())
+  }
+
+  @Test fun testHash() {
+    val buffer = Buffer().apply { write("Kevin".encodeUtf8()) }
+    with(buffer) {
+      assertEquals("e043899daa0c7add37bc99792b2c045d6abbc6dc", sha1().hex())
+      assertEquals("f1cd318e412b5f7226e5f377a9544ff7", md5().hex())
+      assertEquals("0e4dd66217fc8d2e298b78c8cd9392870dcd065d0ff675d0edff5bcd227837e9", sha256().hex())
+      assertEquals("483676b93c4417198b465083d196ec6a9fab8d004515874b8ff47e041f5f56303cc08179625030b8b5b721c09149a18f0f59e64e7ae099518cea78d3d83167e1", sha512().hex())
+    }
+  }
+}
diff --git a/okio/src/commonTest/kotlin/okio/BufferedSinkFactory.kt b/okio/src/commonTest/kotlin/okio/BufferedSinkFactory.kt
new file mode 100644
index 0000000..8f4f29a
--- /dev/null
+++ b/okio/src/commonTest/kotlin/okio/BufferedSinkFactory.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+internal interface BufferedSinkFactory {
+
+  fun create(data: Buffer): BufferedSink
+
+  companion object {
+    val BUFFER: BufferedSinkFactory = object : BufferedSinkFactory {
+      override fun create(data: Buffer): BufferedSink {
+        return data
+      }
+    }
+
+    val REAL_BUFFERED_SINK: BufferedSinkFactory = object : BufferedSinkFactory {
+      override fun create(data: Buffer): BufferedSink {
+        return (data as Sink).buffer()
+      }
+    }
+  }
+}
diff --git a/okio/src/commonTest/kotlin/okio/BufferedSourceFactory.kt b/okio/src/commonTest/kotlin/okio/BufferedSourceFactory.kt
new file mode 100644
index 0000000..b983620
--- /dev/null
+++ b/okio/src/commonTest/kotlin/okio/BufferedSourceFactory.kt
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+interface BufferedSourceFactory {
+  class Pipe(
+    var sink: BufferedSink,
+    var source: BufferedSource
+  )
+
+  val isOneByteAtATime: Boolean
+
+  fun pipe(): Pipe
+
+  companion object {
+    val BUFFER: BufferedSourceFactory = object : BufferedSourceFactory {
+
+      override val isOneByteAtATime: Boolean
+        get() = false
+
+      override fun pipe(): Pipe {
+        val buffer = Buffer()
+        return Pipe(
+          buffer,
+          buffer
+        )
+      }
+    }
+
+    val REAL_BUFFERED_SOURCE: BufferedSourceFactory = object :
+      BufferedSourceFactory {
+
+      override val isOneByteAtATime: Boolean
+        get() = false
+
+      override fun pipe(): Pipe {
+        val buffer = Buffer()
+        return Pipe(
+          buffer,
+          (buffer as Source).buffer()
+        )
+      }
+    }
+
+    /**
+     * A factory deliberately written to create buffers whose internal segments are always 1 byte
+     * long. We like testing with these segments because are likely to trigger bugs!
+     */
+    val ONE_BYTE_AT_A_TIME_BUFFERED_SOURCE: BufferedSourceFactory = object :
+      BufferedSourceFactory {
+
+      override val isOneByteAtATime: Boolean
+        get() = true
+
+      override fun pipe(): Pipe {
+        val buffer = Buffer()
+        return Pipe(
+          buffer,
+          object : Source by buffer {
+            override fun read(sink: Buffer, byteCount: Long): Long {
+              // Read one byte into a new buffer, then clone it so that the segment is shared.
+              // Shared segments cannot be compacted so we'll get a long chain of short segments.
+              val box = Buffer()
+              val result = buffer.read(box, minOf(byteCount, 1L))
+              if (result > 0L) sink.write(box.copy(), result)
+              return result
+            }
+          }.buffer()
+        )
+      }
+    }
+
+    val ONE_BYTE_AT_A_TIME_BUFFER: BufferedSourceFactory = object :
+      BufferedSourceFactory {
+
+      override val isOneByteAtATime: Boolean
+        get() = true
+
+      override fun pipe(): Pipe {
+        val buffer = Buffer()
+        return Pipe(
+          object : Sink by buffer {
+            override fun write(source: Buffer, byteCount: Long) {
+              // Write each byte into a new buffer, then clone it so that the segments are shared.
+              // Shared segments cannot be compacted so we'll get a long chain of short segments.
+              for (i in 0 until byteCount) {
+                val box = Buffer()
+                box.write(source, 1)
+                buffer.write(box.copy(), 1)
+              }
+            }
+          }.buffer(),
+          buffer
+        )
+      }
+    }
+
+    val PEEK_BUFFER: BufferedSourceFactory = object : BufferedSourceFactory {
+
+      override val isOneByteAtATime: Boolean
+        get() = false
+
+      override fun pipe(): Pipe {
+        val buffer = Buffer()
+        return Pipe(
+          buffer,
+          buffer.peek()
+        )
+      }
+    }
+
+    val PEEK_BUFFERED_SOURCE: BufferedSourceFactory = object :
+      BufferedSourceFactory {
+
+      override val isOneByteAtATime: Boolean
+        get() = false
+
+      override fun pipe(): Pipe {
+        val buffer = Buffer()
+        return Pipe(
+          buffer,
+          (buffer as Source).buffer().peek()
+        )
+      }
+    }
+
+    val PARAMETERIZED_TEST_VALUES = mutableListOf<Array<Any>>(
+      arrayOf(BUFFER),
+      arrayOf(REAL_BUFFERED_SOURCE),
+      arrayOf(ONE_BYTE_AT_A_TIME_BUFFERED_SOURCE),
+      arrayOf(ONE_BYTE_AT_A_TIME_BUFFER),
+      arrayOf(PEEK_BUFFER),
+      arrayOf(PEEK_BUFFERED_SOURCE)
+    )
+  }
+}
diff --git a/okio/src/commonTest/kotlin/okio/ByteStringFactory.kt b/okio/src/commonTest/kotlin/okio/ByteStringFactory.kt
new file mode 100644
index 0000000..bbf6cc6
--- /dev/null
+++ b/okio/src/commonTest/kotlin/okio/ByteStringFactory.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+import okio.ByteString.Companion.decodeHex
+import okio.ByteString.Companion.encodeUtf8
+import okio.internal.commonAsUtf8ToByteArray
+
+internal interface ByteStringFactory {
+  fun decodeHex(hex: String): ByteString
+
+  fun encodeUtf8(s: String): ByteString
+
+  companion object {
+    val BYTE_STRING: ByteStringFactory = object : ByteStringFactory {
+      override fun decodeHex(hex: String) = hex.decodeHex()
+      override fun encodeUtf8(s: String) = s.encodeUtf8()
+    }
+
+    val SEGMENTED_BYTE_STRING: ByteStringFactory = object : ByteStringFactory {
+      override fun decodeHex(hex: String) = Buffer().apply { write(hex.decodeHex()) }.snapshot()
+      override fun encodeUtf8(s: String) = Buffer().apply { writeUtf8(s) }.snapshot()
+    }
+
+    val ONE_BYTE_PER_SEGMENT: ByteStringFactory = object : ByteStringFactory {
+      override fun decodeHex(hex: String) = makeSegments(hex.decodeHex())
+      override fun encodeUtf8(s: String) = makeSegments(s.encodeUtf8())
+    }
+
+    // For Kotlin/JVM, the native Java UTF-8 encoder is used. This forces
+    // testing of the Okio encoder used for Kotlin/JS and Kotlin/Native to be
+    // tested on JVM as well.
+    val OKIO_ENCODER: ByteStringFactory = object : ByteStringFactory {
+      override fun decodeHex(hex: String) = hex.decodeHex()
+      override fun encodeUtf8(s: String) =
+        ByteString.of(*s.commonAsUtf8ToByteArray())
+    }
+  }
+}
diff --git a/okio/src/commonTest/kotlin/okio/ByteStringTest.kt b/okio/src/commonTest/kotlin/okio/ByteStringTest.kt
new file mode 100644
index 0000000..c75c458
--- /dev/null
+++ b/okio/src/commonTest/kotlin/okio/ByteStringTest.kt
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+import okio.ByteString.Companion.decodeBase64
+import okio.ByteString.Companion.decodeHex
+import okio.ByteString.Companion.encodeUtf8
+import okio.internal.commonAsUtf8ToByteArray
+import kotlin.random.Random
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+import kotlin.test.assertFalse
+import kotlin.test.assertNotEquals
+import kotlin.test.assertSame
+import kotlin.test.assertTrue
+import kotlin.test.fail
+
+class ByteStringTest : AbstractByteStringTest(ByteStringFactory.BYTE_STRING)
+class SegmentedByteStringTest : AbstractByteStringTest(ByteStringFactory.SEGMENTED_BYTE_STRING)
+class ByteStringOneBytePerSegmentTest : AbstractByteStringTest(ByteStringFactory.ONE_BYTE_PER_SEGMENT)
+class OkioEncoderTest : AbstractByteStringTest(ByteStringFactory.OKIO_ENCODER)
+
+abstract class AbstractByteStringTest internal constructor(
+  private val factory: ByteStringFactory
+) {
+  @Test fun get() {
+    val actual = factory.encodeUtf8("abc")
+    assertEquals(3, actual.size)
+    assertEquals(actual[0], 'a'.toByte())
+    assertEquals(actual[1], 'b'.toByte())
+    assertEquals(actual[2], 'c'.toByte())
+    try {
+      actual[-1]
+      fail("no index out of bounds: -1")
+    } catch (expected: IndexOutOfBoundsException) {
+    }
+    try {
+      actual[3]
+      fail("no index out of bounds: 3")
+    } catch (expected: IndexOutOfBoundsException) {
+    }
+  }
+
+  @Test fun getByte() {
+    val byteString = factory.decodeHex("ab12")
+    assertEquals(-85, byteString[0].toLong())
+    assertEquals(18, byteString[1].toLong())
+  }
+
+  @Test fun startsWithByteString() {
+    val byteString = factory.decodeHex("112233")
+    assertTrue(byteString.startsWith("".decodeHex()))
+    assertTrue(byteString.startsWith("11".decodeHex()))
+    assertTrue(byteString.startsWith("1122".decodeHex()))
+    assertTrue(byteString.startsWith("112233".decodeHex()))
+    assertFalse(byteString.startsWith("2233".decodeHex()))
+    assertFalse(byteString.startsWith("11223344".decodeHex()))
+    assertFalse(byteString.startsWith("112244".decodeHex()))
+  }
+
+  @Test fun endsWithByteString() {
+    val byteString = factory.decodeHex("112233")
+    assertTrue(byteString.endsWith("".decodeHex()))
+    assertTrue(byteString.endsWith("33".decodeHex()))
+    assertTrue(byteString.endsWith("2233".decodeHex()))
+    assertTrue(byteString.endsWith("112233".decodeHex()))
+    assertFalse(byteString.endsWith("1122".decodeHex()))
+    assertFalse(byteString.endsWith("00112233".decodeHex()))
+    assertFalse(byteString.endsWith("002233".decodeHex()))
+  }
+
+  @Test fun startsWithByteArray() {
+    val byteString = factory.decodeHex("112233")
+    assertTrue(byteString.startsWith("".decodeHex().toByteArray()))
+    assertTrue(byteString.startsWith("11".decodeHex().toByteArray()))
+    assertTrue(byteString.startsWith("1122".decodeHex().toByteArray()))
+    assertTrue(byteString.startsWith("112233".decodeHex().toByteArray()))
+    assertFalse(byteString.startsWith("2233".decodeHex().toByteArray()))
+    assertFalse(byteString.startsWith("11223344".decodeHex().toByteArray()))
+    assertFalse(byteString.startsWith("112244".decodeHex().toByteArray()))
+  }
+
+  @Test fun endsWithByteArray() {
+    val byteString = factory.decodeHex("112233")
+    assertTrue(byteString.endsWith("".decodeHex().toByteArray()))
+    assertTrue(byteString.endsWith("33".decodeHex().toByteArray()))
+    assertTrue(byteString.endsWith("2233".decodeHex().toByteArray()))
+    assertTrue(byteString.endsWith("112233".decodeHex().toByteArray()))
+    assertFalse(byteString.endsWith("1122".decodeHex().toByteArray()))
+    assertFalse(byteString.endsWith("00112233".decodeHex().toByteArray()))
+    assertFalse(byteString.endsWith("002233".decodeHex().toByteArray()))
+  }
+
+  @Test fun indexOfByteString() {
+    val byteString = factory.decodeHex("112233")
+    assertEquals(0, byteString.indexOf("112233".decodeHex()).toLong())
+    assertEquals(0, byteString.indexOf("1122".decodeHex()).toLong())
+    assertEquals(0, byteString.indexOf("11".decodeHex()).toLong())
+    assertEquals(0, byteString.indexOf("11".decodeHex(), 0).toLong())
+    assertEquals(0, byteString.indexOf("".decodeHex()).toLong())
+    assertEquals(0, byteString.indexOf("".decodeHex(), 0).toLong())
+    assertEquals(1, byteString.indexOf("2233".decodeHex()).toLong())
+    assertEquals(1, byteString.indexOf("22".decodeHex()).toLong())
+    assertEquals(1, byteString.indexOf("22".decodeHex(), 1).toLong())
+    assertEquals(1, byteString.indexOf("".decodeHex(), 1).toLong())
+    assertEquals(2, byteString.indexOf("33".decodeHex()).toLong())
+    assertEquals(2, byteString.indexOf("33".decodeHex(), 2).toLong())
+    assertEquals(2, byteString.indexOf("".decodeHex(), 2).toLong())
+    assertEquals(3, byteString.indexOf("".decodeHex(), 3).toLong())
+    assertEquals(-1, byteString.indexOf("112233".decodeHex(), 1).toLong())
+    assertEquals(-1, byteString.indexOf("44".decodeHex()).toLong())
+    assertEquals(-1, byteString.indexOf("11223344".decodeHex()).toLong())
+    assertEquals(-1, byteString.indexOf("112244".decodeHex()).toLong())
+    assertEquals(-1, byteString.indexOf("112233".decodeHex(), 1).toLong())
+    assertEquals(-1, byteString.indexOf("2233".decodeHex(), 2).toLong())
+    assertEquals(-1, byteString.indexOf("33".decodeHex(), 3).toLong())
+    assertEquals(-1, byteString.indexOf("".decodeHex(), 4).toLong())
+  }
+
+  @Test fun indexOfWithOffset() {
+    val byteString = factory.decodeHex("112233112233")
+    assertEquals(0, byteString.indexOf("112233".decodeHex(), -1).toLong())
+    assertEquals(0, byteString.indexOf("112233".decodeHex(), 0).toLong())
+    assertEquals(0, byteString.indexOf("112233".decodeHex()).toLong())
+    assertEquals(3, byteString.indexOf("112233".decodeHex(), 1).toLong())
+    assertEquals(3, byteString.indexOf("112233".decodeHex(), 2).toLong())
+    assertEquals(3, byteString.indexOf("112233".decodeHex(), 3).toLong())
+    assertEquals(-1, byteString.indexOf("112233".decodeHex(), 4).toLong())
+  }
+
+  @Test fun indexOfByteArray() {
+    val byteString = factory.decodeHex("112233")
+    assertEquals(0, byteString.indexOf("112233".decodeHex().toByteArray()).toLong())
+    assertEquals(1, byteString.indexOf("2233".decodeHex().toByteArray()).toLong())
+    assertEquals(2, byteString.indexOf("33".decodeHex().toByteArray()).toLong())
+    assertEquals(-1, byteString.indexOf("112244".decodeHex().toByteArray()).toLong())
+  }
+
+  @Test fun lastIndexOfByteString() {
+    val byteString = factory.decodeHex("112233")
+    assertEquals(0, byteString.lastIndexOf("112233".decodeHex()).toLong())
+    assertEquals(0, byteString.lastIndexOf("1122".decodeHex()).toLong())
+    assertEquals(0, byteString.lastIndexOf("11".decodeHex()).toLong())
+    assertEquals(0, byteString.lastIndexOf("11".decodeHex(), 3).toLong())
+    assertEquals(0, byteString.lastIndexOf("11".decodeHex(), 0).toLong())
+    assertEquals(0, byteString.lastIndexOf("".decodeHex(), 0).toLong())
+    assertEquals(1, byteString.lastIndexOf("2233".decodeHex()).toLong())
+    assertEquals(1, byteString.lastIndexOf("22".decodeHex()).toLong())
+    assertEquals(1, byteString.lastIndexOf("22".decodeHex(), 3).toLong())
+    assertEquals(1, byteString.lastIndexOf("22".decodeHex(), 1).toLong())
+    assertEquals(1, byteString.lastIndexOf("".decodeHex(), 1).toLong())
+    assertEquals(2, byteString.lastIndexOf("33".decodeHex()).toLong())
+    assertEquals(2, byteString.lastIndexOf("33".decodeHex(), 3).toLong())
+    assertEquals(2, byteString.lastIndexOf("33".decodeHex(), 2).toLong())
+    assertEquals(2, byteString.lastIndexOf("".decodeHex(), 2).toLong())
+    assertEquals(3, byteString.lastIndexOf("".decodeHex(), 3).toLong())
+    assertEquals(3, byteString.lastIndexOf("".decodeHex()).toLong())
+    assertEquals(-1, byteString.lastIndexOf("112233".decodeHex(), -1).toLong())
+    assertEquals(-1, byteString.lastIndexOf("112233".decodeHex(), -2).toLong())
+    assertEquals(-1, byteString.lastIndexOf("44".decodeHex()).toLong())
+    assertEquals(-1, byteString.lastIndexOf("11223344".decodeHex()).toLong())
+    assertEquals(-1, byteString.lastIndexOf("112244".decodeHex()).toLong())
+    assertEquals(-1, byteString.lastIndexOf("2233".decodeHex(), 0).toLong())
+    assertEquals(-1, byteString.lastIndexOf("33".decodeHex(), 1).toLong())
+    assertEquals(-1, byteString.lastIndexOf("".decodeHex(), -1).toLong())
+  }
+
+  @Test fun lastIndexOfByteArray() {
+    val byteString = factory.decodeHex("112233")
+    assertEquals(0, byteString.lastIndexOf("112233".decodeHex().toByteArray()).toLong())
+    assertEquals(1, byteString.lastIndexOf("2233".decodeHex().toByteArray()).toLong())
+    assertEquals(2, byteString.lastIndexOf("33".decodeHex().toByteArray()).toLong())
+    assertEquals(3, byteString.lastIndexOf("".decodeHex().toByteArray()).toLong())
+  }
+
+  @Test fun equalsTest() {
+    val byteString = factory.decodeHex("000102")
+    assertEquals(byteString, byteString)
+    assertEquals(byteString, "000102".decodeHex())
+    assertNotEquals(byteString, Any())
+    assertNotEquals(byteString, "000201".decodeHex())
+  }
+
+  @Test fun equalsEmptyTest() {
+    assertEquals(factory.decodeHex(""), ByteString.EMPTY)
+    assertEquals(factory.decodeHex(""), ByteString.of())
+    assertEquals(ByteString.EMPTY, factory.decodeHex(""))
+    assertEquals(ByteString.of(), factory.decodeHex(""))
+  }
+
+  private val bronzeHorseman = "На берегу пустынных волн"
+
+  @Test fun utf8() {
+    val byteString = factory.encodeUtf8(bronzeHorseman)
+    assertEquals(byteString.toByteArray().toList(), bronzeHorseman.commonAsUtf8ToByteArray().toList())
+    assertTrue(byteString == ByteString.of(*bronzeHorseman.commonAsUtf8ToByteArray()))
+    assertEquals(
+      byteString,
+      (
+        "d09dd0b020d0b1d0b5d180d0b5d0b3d18320d0bfd183d181" +
+          "d182d18bd0bdd0bdd18bd18520d0b2d0bed0bbd0bd"
+        ).decodeHex()
+    )
+    assertEquals(byteString.utf8(), bronzeHorseman)
+  }
+
+  @Test fun testHashCode() {
+    val byteString = factory.decodeHex("0102")
+    assertEquals(byteString.hashCode().toLong(), byteString.hashCode().toLong())
+    assertEquals(byteString.hashCode().toLong(), "0102".decodeHex().hashCode().toLong())
+  }
+
+  @Test fun toAsciiLowerCaseNoUppercase() {
+    val s = factory.encodeUtf8("a1_+")
+    assertEquals(s, s.toAsciiLowercase())
+    if (factory === ByteStringFactory.BYTE_STRING) {
+      assertSame(s, s.toAsciiLowercase())
+    }
+  }
+
+  @Test fun toAsciiAllUppercase() {
+    assertEquals("ab".encodeUtf8(), factory.encodeUtf8("AB").toAsciiLowercase())
+  }
+
+  @Test fun toAsciiStartsLowercaseEndsUppercase() {
+    assertEquals("abcd".encodeUtf8(), factory.encodeUtf8("abCD").toAsciiLowercase())
+  }
+
+  @Test fun toAsciiStartsUppercaseEndsLowercase() {
+    assertEquals("ABCD".encodeUtf8(), factory.encodeUtf8("ABcd").toAsciiUppercase())
+  }
+
+  @Test fun substring() {
+    val byteString = factory.encodeUtf8("Hello, World!")
+
+    assertEquals(byteString.substring(0), byteString)
+    assertEquals(byteString.substring(0, 5), "Hello".encodeUtf8())
+    assertEquals(byteString.substring(7), "World!".encodeUtf8())
+    assertEquals(byteString.substring(6, 6), "".encodeUtf8())
+  }
+
+  @Test fun substringWithInvalidBounds() {
+    val byteString = factory.encodeUtf8("Hello, World!")
+
+    assertFailsWith<IllegalArgumentException> {
+      byteString.substring(-1)
+    }
+
+    assertFailsWith<IllegalArgumentException> {
+      byteString.substring(0, 14)
+    }
+
+    assertFailsWith<IllegalArgumentException> {
+      byteString.substring(8, 7)
+    }
+  }
+
+  @Test fun encodeBase64() {
+    assertEquals("", factory.encodeUtf8("").base64())
+    assertEquals("AA==", factory.encodeUtf8("\u0000").base64())
+    assertEquals("AAA=", factory.encodeUtf8("\u0000\u0000").base64())
+    assertEquals("AAAA", factory.encodeUtf8("\u0000\u0000\u0000").base64())
+    assertEquals(
+      "SG93IG1hbnkgbGluZXMgb2YgY29kZSBhcmUgdGhlcmU/ICdib3V0IDIgbWlsbGlvbi4=",
+      factory.encodeUtf8("How many lines of code are there? 'bout 2 million.").base64()
+    )
+  }
+
+  @Test fun encodeBase64Url() {
+    assertEquals("", factory.encodeUtf8("").base64Url())
+    assertEquals("AA==", factory.encodeUtf8("\u0000").base64Url())
+    assertEquals("AAA=", factory.encodeUtf8("\u0000\u0000").base64Url())
+    assertEquals("AAAA", factory.encodeUtf8("\u0000\u0000\u0000").base64Url())
+    assertEquals(
+      "SG93IG1hbnkgbGluZXMgb2YgY29kZSBhcmUgdGhlcmU_ICdib3V0IDIgbWlsbGlvbi4=",
+      factory.encodeUtf8("How many lines of code are there? 'bout 2 million.").base64Url()
+    )
+  }
+
+  @Test fun ignoreUnnecessaryPadding() {
+    assertEquals("", "====".decodeBase64()!!.utf8())
+    assertEquals("\u0000\u0000\u0000", "AAAA====".decodeBase64()!!.utf8())
+  }
+
+  @Test fun decodeBase64() {
+    assertEquals("", "".decodeBase64()!!.utf8())
+    assertEquals(null, "/===".decodeBase64()) // Can't do anything with 6 bits!
+    assertEquals("ff".decodeHex(), "//==".decodeBase64())
+    assertEquals("ff".decodeHex(), "__==".decodeBase64())
+    assertEquals("ffff".decodeHex(), "///=".decodeBase64())
+    assertEquals("ffff".decodeHex(), "___=".decodeBase64())
+    assertEquals("ffffff".decodeHex(), "////".decodeBase64())
+    assertEquals("ffffff".decodeHex(), "____".decodeBase64())
+    assertEquals("ffffffffffff".decodeHex(), "////////".decodeBase64())
+    assertEquals("ffffffffffff".decodeHex(), "________".decodeBase64())
+    assertEquals(
+      "What's to be scared about? It's just a little hiccup in the power...",
+      (
+        "V2hhdCdzIHRvIGJlIHNjYXJlZCBhYm91dD8gSXQncyBqdXN0IGEgbGl0dGxlIGhpY2" +
+          "N1cCBpbiB0aGUgcG93ZXIuLi4="
+        ).decodeBase64()!!.utf8()
+    )
+    // Uses two encoding styles. Malformed, but supported as a side-effect.
+    assertEquals("ffffff".decodeHex(), "__//".decodeBase64())
+  }
+
+  @Test fun decodeBase64WithWhitespace() {
+    assertEquals("\u0000\u0000\u0000", " AA AA ".decodeBase64()!!.utf8())
+    assertEquals("\u0000\u0000\u0000", " AA A\r\nA ".decodeBase64()!!.utf8())
+    assertEquals("\u0000\u0000\u0000", "AA AA".decodeBase64()!!.utf8())
+    assertEquals("\u0000\u0000\u0000", " AA AA ".decodeBase64()!!.utf8())
+    assertEquals("\u0000\u0000\u0000", " AA A\r\nA ".decodeBase64()!!.utf8())
+    assertEquals("\u0000\u0000\u0000", "A    AAA".decodeBase64()!!.utf8())
+    assertEquals("", "    ".decodeBase64()!!.utf8())
+  }
+
+  @Test fun encodeHex() {
+    assertEquals("000102", ByteString.of(0x0, 0x1, 0x2).hex())
+  }
+
+  @Test fun decodeHex() {
+    val actual = "CAFEBABE".decodeHex()
+    val expected = ByteString.of(-54, -2, -70, -66)
+    assertEquals(expected, actual)
+  }
+
+  @Test fun decodeHexOddNumberOfChars() {
+    assertFailsWith<IllegalArgumentException> {
+      "aaa".decodeHex()
+    }
+  }
+
+  @Test fun decodeHexInvalidChar() {
+    assertFailsWith<IllegalArgumentException> {
+      "a\u0000".decodeHex()
+    }
+  }
+
+  @Test fun toStringOnEmpty() {
+    assertEquals("[size=0]", factory.decodeHex("").toString())
+  }
+
+  @Test fun toStringOnShortText() {
+    assertEquals(
+      "[text=Tyrannosaur]",
+      factory.encodeUtf8("Tyrannosaur").toString()
+    )
+    assertEquals(
+      "[text=təˈranəˌsôr]",
+      factory.decodeHex("74c999cb8872616ec999cb8c73c3b472").toString()
+    )
+  }
+
+  @Test fun toStringOnLongTextIsTruncated() {
+    val raw = (
+      "Um, I'll tell you the problem with the scientific power that you're using here, " +
+        "it didn't require any discipline to attain it. You read what others had done and you " +
+        "took the next step. You didn't earn the knowledge for yourselves, so you don't take any " +
+        "responsibility for it. You stood on the shoulders of geniuses to accomplish something " +
+        "as fast as you could, and before you even knew what you had, you patented it, and " +
+        "packaged it, and slapped it on a plastic lunchbox, and now you're selling it, you wanna " +
+        "sell it."
+      )
+    assertEquals(
+      "[size=517 text=Um, I'll tell you the problem with the scientific power that " +
+        "you…]",
+      factory.encodeUtf8(raw).toString()
+    )
+    val war = (
+      "Սｍ, I'll 𝓽𝖾ll ᶌօ𝘂 ᴛℎ℮ 𝜚𝕣०ｂl𝖾ｍ ｗі𝕥𝒽 𝘵𝘩𝐞 𝓼𝙘𝐢𝔢𝓷𝗍𝜄𝚏𝑖ｃ 𝛠𝝾ｗ𝚎𝑟 𝕥ｈ⍺𝞃 𝛄𝓸𝘂'𝒓𝗲 υ𝖘𝓲𝗇ɡ 𝕙𝚎𝑟ｅ, " +
+        "𝛊𝓽 ⅆ𝕚𝐝𝝿'𝗍 𝔯𝙚𝙦ᴜ𝜾𝒓𝘦 𝔞𝘯𝐲 ԁ𝜄𝑠𝚌ι𝘱lι𝒏ｅ 𝑡𝜎 𝕒𝚝𝖙𝓪і𝞹 𝔦𝚝. 𝒀ο𝗎 𝔯𝑒⍺𝖉 ｗ𝐡𝝰𝔱 𝞂𝞽һ𝓮𝓇ƽ հ𝖺𝖉 ⅾ𝛐𝝅ⅇ 𝝰πԁ 𝔂ᴑᴜ 𝓉ﮨ၀𝚔 " +
+        "т𝒽𝑒 𝗇𝕖ⅹ𝚝 𝔰𝒕е𝓅. 𝘠ⲟ𝖚 𝖉ⅰԁ𝝕'τ 𝙚𝚊ｒ𝞹 𝘵Ꮒ𝖾 𝝒𝐧هｗl𝑒𝖉ƍ𝙚 𝓯૦ｒ 𝔂𝞼𝒖𝕣𝑠𝕖l𝙫𝖊𝓼, 𐑈о ｙ𝘰𝒖 ⅆە𝗇'ｔ 𝜏α𝒌𝕖 𝛂𝟉ℽ " +
+        "𝐫ⅇ𝗌ⲣ๐ϖ𝖘ꙇᖯ𝓲l𝓲𝒕𝘆 𝐟𝞼𝘳 𝚤𝑡. 𝛶𝛔𝔲 ｓ𝕥σσ𝐝 ﮩ𝕟 𝒕𝗁𝔢 𝘴𝐡𝜎ᴜlⅾ𝓮𝔯𝚜 𝛐𝙛 ᶃ𝚎ᴨᎥս𝚜𝘦𝓈 𝓽𝞸 ａ𝒄𝚌𝞸ｍρl𝛊ꜱ𝐡 𝓈𝚘ｍ𝚎𝞃𝔥⍳𝞹𝔤 𝐚𝗌 𝖋ａ𝐬𝒕 " +
+        "αｓ γ𝛐𝕦 𝔠ﻫ𝛖lԁ, 𝚊π𝑑 Ь𝑒𝙛૦𝓇𝘦 𝓎٥𝖚 ⅇｖℯ𝝅 𝜅ո𝒆ｗ ｗ𝗵𝒂𝘁 ᶌ੦𝗎 ｈ𝐚𝗱, 𝜸ﮨ𝒖 𝓹𝝰𝔱𝖾𝗇𝓽𝔢ⅆ і𝕥, 𝚊𝜛𝓭 𝓹𝖺ⅽϰ𝘢ℊеᏧ 𝑖𝞃, " +
+        "𝐚𝛑ꓒ 𝙨l𝔞р𝘱𝔢𝓭 ɩ𝗍 ہ𝛑 𝕒 ｐl𝛂ѕᴛ𝗂𝐜 l𝞄ℼ𝔠𝒽𝑏ﮪ⨯, 𝔞ϖ𝒹 ｎ𝛔ｗ 𝛾𝐨𝞄'𝗿𝔢 ꜱ℮ll𝙞ｎɡ ɩ𝘁, 𝙮𝕠𝛖 ｗ𝑎ℼ𝚗𝛂 𝕤𝓮ll 𝙞𝓉."
+      )
+    assertEquals(
+      "[size=1496 text=Սｍ, I'll 𝓽𝖾ll ᶌօ𝘂 ᴛℎ℮ 𝜚𝕣०ｂl𝖾ｍ ｗі𝕥𝒽 𝘵𝘩𝐞 𝓼𝙘𝐢𝔢𝓷𝗍𝜄𝚏𝑖ｃ 𝛠𝝾ｗ𝚎𝑟 𝕥ｈ⍺𝞃 " +
+        "𝛄𝓸𝘂…]",
+      factory.encodeUtf8(war).toString()
+    )
+  }
+
+  @Test fun toStringOnTextWithNewlines() {
+    // Instead of emitting a literal newline in the toString(), these are escaped as "\n".
+    assertEquals(
+      "[text=a\\r\\nb\\nc\\rd\\\\e]",
+      factory.encodeUtf8("a\r\nb\nc\rd\\e").toString()
+    )
+  }
+
+  @Test fun toStringOnData() {
+    val byteString = factory.decodeHex(
+      "" +
+        "60b420bb3851d9d47acb933dbe70399bf6c92da33af01d4fb770e98c0325f41d3ebaf8986da712c82bcd4d55" +
+        "4bf0b54023c29b624de9ef9c2f931efc580f9afb"
+    )
+    assertEquals(
+      "[hex=" +
+        "60b420bb3851d9d47acb933dbe70399bf6c92da33af01d4fb770e98c0325f41d3ebaf8986da712c82bcd4d55" +
+        "4bf0b54023c29b624de9ef9c2f931efc580f9afb]",
+      byteString.toString()
+    )
+  }
+
+  @Test fun toStringOnLongDataIsTruncated() {
+    val byteString = factory.decodeHex(
+      "" +
+        "60b420bb3851d9d47acb933dbe70399bf6c92da33af01d4fb770e98c0325f41d3ebaf8986da712c82bcd4d55" +
+        "4bf0b54023c29b624de9ef9c2f931efc580f9afba1"
+    )
+    assertEquals(
+      "[size=65 hex=" +
+        "60b420bb3851d9d47acb933dbe70399bf6c92da33af01d4fb770e98c0325f41d3ebaf8986da712c82bcd4d55" +
+        "4bf0b54023c29b624de9ef9c2f931efc580f9afb…]",
+      byteString.toString()
+    )
+  }
+
+  @Test fun compareToSingleBytes() {
+    val originalByteStrings = listOf(
+      factory.decodeHex("00"),
+      factory.decodeHex("01"),
+      factory.decodeHex("7e"),
+      factory.decodeHex("7f"),
+      factory.decodeHex("80"),
+      factory.decodeHex("81"),
+      factory.decodeHex("fe"),
+      factory.decodeHex("ff")
+    )
+
+    val sortedByteStrings = originalByteStrings.toMutableList()
+    sortedByteStrings.shuffle(Random(0))
+    assertNotEquals(originalByteStrings, sortedByteStrings)
+
+    sortedByteStrings.sort()
+    assertEquals(originalByteStrings, sortedByteStrings)
+  }
+
+  @Test fun compareToMultipleBytes() {
+    val originalByteStrings = listOf(
+      factory.decodeHex(""),
+      factory.decodeHex("00"),
+      factory.decodeHex("0000"),
+      factory.decodeHex("000000"),
+      factory.decodeHex("00000000"),
+      factory.decodeHex("0000000000"),
+      factory.decodeHex("0000000001"),
+      factory.decodeHex("000001"),
+      factory.decodeHex("00007f"),
+      factory.decodeHex("0000ff"),
+      factory.decodeHex("000100"),
+      factory.decodeHex("000101"),
+      factory.decodeHex("007f00"),
+      factory.decodeHex("00ff00"),
+      factory.decodeHex("010000"),
+      factory.decodeHex("010001"),
+      factory.decodeHex("01007f"),
+      factory.decodeHex("0100ff"),
+      factory.decodeHex("010100"),
+      factory.decodeHex("01010000"),
+      factory.decodeHex("0101000000"),
+      factory.decodeHex("0101000001"),
+      factory.decodeHex("010101"),
+      factory.decodeHex("7f0000"),
+      factory.decodeHex("7f0000ffff"),
+      factory.decodeHex("ffffff")
+    )
+
+    val sortedByteStrings = originalByteStrings.toMutableList()
+    sortedByteStrings.shuffle(Random(0))
+    assertNotEquals(originalByteStrings, sortedByteStrings)
+
+    sortedByteStrings.sort()
+    assertEquals(originalByteStrings, sortedByteStrings)
+  }
+
+  @Test fun testHash() = with(factory.encodeUtf8("Kevin")) {
+    assertEquals("e043899daa0c7add37bc99792b2c045d6abbc6dc", sha1().hex())
+    assertEquals("f1cd318e412b5f7226e5f377a9544ff7", md5().hex())
+    assertEquals("0e4dd66217fc8d2e298b78c8cd9392870dcd065d0ff675d0edff5bcd227837e9", sha256().hex())
+    assertEquals("483676b93c4417198b465083d196ec6a9fab8d004515874b8ff47e041f5f56303cc08179625030b8b5b721c09149a18f0f59e64e7ae099518cea78d3d83167e1", sha512().hex())
+  }
+}
diff --git a/okio/src/commonTest/kotlin/okio/CommonBufferTest.kt b/okio/src/commonTest/kotlin/okio/CommonBufferTest.kt
new file mode 100644
index 0000000..292e3c5
--- /dev/null
+++ b/okio/src/commonTest/kotlin/okio/CommonBufferTest.kt
@@ -0,0 +1,430 @@
+/*
+ * 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 okio
+
+import okio.ByteString.Companion.decodeHex
+import kotlin.random.Random
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+
+/**
+ * Tests solely for the behavior of Buffer's implementation. For generic BufferedSink or
+ * BufferedSource behavior use BufferedSinkTest or BufferedSourceTest, respectively.
+ */
+class CommonBufferTest {
+  @Test fun readAndWriteUtf8() {
+    val buffer = Buffer()
+    buffer.writeUtf8("ab")
+    assertEquals(2, buffer.size)
+    buffer.writeUtf8("cdef")
+    assertEquals(6, buffer.size)
+    assertEquals("abcd", buffer.readUtf8(4))
+    assertEquals(2, buffer.size)
+    assertEquals("ef", buffer.readUtf8(2))
+    assertEquals(0, buffer.size)
+    assertFailsWith<EOFException> {
+      buffer.readUtf8(1)
+    }
+  }
+
+  /** Buffer's toString is the same as ByteString's.  */
+  @Test fun bufferToString() {
+    assertEquals("[size=0]", Buffer().toString())
+    assertEquals(
+      "[text=a\\r\\nb\\nc\\rd\\\\e]",
+      Buffer().writeUtf8("a\r\nb\nc\rd\\e").toString()
+    )
+    assertEquals(
+      "[text=Tyrannosaur]",
+      Buffer().writeUtf8("Tyrannosaur").toString()
+    )
+    assertEquals(
+      "[text=təˈranəˌsôr]",
+      Buffer()
+        .write("74c999cb8872616ec999cb8c73c3b472".decodeHex())
+        .toString()
+    )
+    assertEquals(
+      "[hex=0000000000000000000000000000000000000000000000000000000000000000000000000000" +
+        "0000000000000000000000000000000000000000000000000000]",
+      Buffer().write(ByteArray(64)).toString()
+    )
+  }
+
+  @Test fun multipleSegmentBuffers() {
+    val buffer = Buffer()
+    buffer.writeUtf8('a'.repeat(1000))
+    buffer.writeUtf8('b'.repeat(2500))
+    buffer.writeUtf8('c'.repeat(5000))
+    buffer.writeUtf8('d'.repeat(10000))
+    buffer.writeUtf8('e'.repeat(25000))
+    buffer.writeUtf8('f'.repeat(50000))
+
+    assertEquals('a'.repeat(999), buffer.readUtf8(999)) // a...a
+    assertEquals("a" + 'b'.repeat(2500) + "c", buffer.readUtf8(2502)) // ab...bc
+    assertEquals('c'.repeat(4998), buffer.readUtf8(4998)) // c...c
+    assertEquals("c" + 'd'.repeat(10000) + "e", buffer.readUtf8(10002)) // cd...de
+    assertEquals('e'.repeat(24998), buffer.readUtf8(24998)) // e...e
+    assertEquals("e" + 'f'.repeat(50000), buffer.readUtf8(50001)) // ef...f
+    assertEquals(0, buffer.size)
+  }
+
+  @Test fun fillAndDrainPool() {
+    val buffer = Buffer()
+
+    // Take 2 * MAX_SIZE segments. This will drain the pool, even if other tests filled it.
+    buffer.write(ByteArray(SegmentPool.MAX_SIZE))
+    buffer.write(ByteArray(SegmentPool.MAX_SIZE))
+    assertEquals(0, SegmentPool.byteCount)
+
+    // Recycle MAX_SIZE segments. They're all in the pool.
+    buffer.skip(SegmentPool.MAX_SIZE.toLong())
+    assertEquals(SegmentPool.MAX_SIZE, SegmentPool.byteCount)
+
+    // Recycle MAX_SIZE more segments. The pool is full so they get garbage collected.
+    buffer.skip(SegmentPool.MAX_SIZE.toLong())
+    assertEquals(SegmentPool.MAX_SIZE, SegmentPool.byteCount)
+
+    // Take MAX_SIZE segments to drain the pool.
+    buffer.write(ByteArray(SegmentPool.MAX_SIZE))
+    assertEquals(0, SegmentPool.byteCount)
+
+    // Take MAX_SIZE more segments. The pool is drained so these will need to be allocated.
+    buffer.write(ByteArray(SegmentPool.MAX_SIZE))
+    assertEquals(0, SegmentPool.byteCount)
+  }
+
+  @Test fun moveBytesBetweenBuffersShareSegment() {
+    val size = Segment.SIZE / 2 - 1
+    val segmentSizes = moveBytesBetweenBuffers('a'.repeat(size), 'b'.repeat(size))
+    assertEquals(listOf(size * 2), segmentSizes)
+  }
+
+  @Test fun moveBytesBetweenBuffersReassignSegment() {
+    val size = Segment.SIZE / 2 + 1
+    val segmentSizes = moveBytesBetweenBuffers('a'.repeat(size), 'b'.repeat(size))
+    assertEquals(listOf(size, size), segmentSizes)
+  }
+
+  @Test fun moveBytesBetweenBuffersMultipleSegments() {
+    val size = 3 * Segment.SIZE + 1
+    val segmentSizes = moveBytesBetweenBuffers('a'.repeat(size), 'b'.repeat(size))
+    assertEquals(
+      listOf(
+        Segment.SIZE, Segment.SIZE, Segment.SIZE, 1,
+        Segment.SIZE, Segment.SIZE, Segment.SIZE, 1
+      ),
+      segmentSizes
+    )
+  }
+
+  private fun moveBytesBetweenBuffers(vararg contents: String): List<Int> {
+    val expected = StringBuilder()
+    val buffer = Buffer()
+    for (s in contents) {
+      val source = Buffer()
+      source.writeUtf8(s)
+      buffer.writeAll(source)
+      expected.append(s)
+    }
+    val segmentSizes = segmentSizes(buffer)
+    assertEquals(expected.toString(), buffer.readUtf8(expected.length.toLong()))
+    return segmentSizes
+  }
+
+  /** The big part of source's first segment is being moved.  */
+  @Test fun writeSplitSourceBufferLeft() {
+    val writeSize = Segment.SIZE / 2 + 1
+
+    val sink = Buffer()
+    sink.writeUtf8('b'.repeat(Segment.SIZE - 10))
+
+    val source = Buffer()
+    source.writeUtf8('a'.repeat(Segment.SIZE * 2))
+    sink.write(source, writeSize.toLong())
+
+    assertEquals(listOf(Segment.SIZE - 10, writeSize), segmentSizes(sink))
+    assertEquals(listOf(Segment.SIZE - writeSize, Segment.SIZE), segmentSizes(source))
+  }
+
+  /** The big part of source's first segment is staying put.  */
+  @Test fun writeSplitSourceBufferRight() {
+    val writeSize = Segment.SIZE / 2 - 1
+
+    val sink = Buffer()
+    sink.writeUtf8('b'.repeat(Segment.SIZE - 10))
+
+    val source = Buffer()
+    source.writeUtf8('a'.repeat(Segment.SIZE * 2))
+    sink.write(source, writeSize.toLong())
+
+    assertEquals(listOf(Segment.SIZE - 10, writeSize), segmentSizes(sink))
+    assertEquals(listOf(Segment.SIZE - writeSize, Segment.SIZE), segmentSizes(source))
+  }
+
+  @Test fun writePrefixDoesntSplit() {
+    val sink = Buffer()
+    sink.writeUtf8('b'.repeat(10))
+
+    val source = Buffer()
+    source.writeUtf8('a'.repeat(Segment.SIZE * 2))
+    sink.write(source, 20)
+
+    assertEquals(listOf(30), segmentSizes(sink))
+    assertEquals(listOf(Segment.SIZE - 20, Segment.SIZE), segmentSizes(source))
+    assertEquals(30, sink.size)
+    assertEquals((Segment.SIZE * 2 - 20).toLong(), source.size)
+  }
+
+  @Test fun writePrefixDoesntSplitButRequiresCompact() {
+    val sink = Buffer()
+    sink.writeUtf8('b'.repeat(Segment.SIZE - 10)) // limit = size - 10
+    sink.readUtf8((Segment.SIZE - 20).toLong()) // pos = size = 20
+
+    val source = Buffer()
+    source.writeUtf8('a'.repeat(Segment.SIZE * 2))
+    sink.write(source, 20)
+
+    assertEquals(listOf(30), segmentSizes(sink))
+    assertEquals(listOf(Segment.SIZE - 20, Segment.SIZE), segmentSizes(source))
+    assertEquals(30, sink.size)
+    assertEquals((Segment.SIZE * 2 - 20).toLong(), source.size)
+  }
+
+  @Test fun moveAllRequestedBytesWithRead() {
+    val sink = Buffer()
+    sink.writeUtf8('a'.repeat(10))
+
+    val source = Buffer()
+    source.writeUtf8('b'.repeat(15))
+
+    assertEquals(10, source.read(sink, 10))
+    assertEquals(20, sink.size)
+    assertEquals(5, source.size)
+    assertEquals('a'.repeat(10) + 'b'.repeat(10), sink.readUtf8(20))
+  }
+
+  @Test fun moveFewerThanRequestedBytesWithRead() {
+    val sink = Buffer()
+    sink.writeUtf8('a'.repeat(10))
+
+    val source = Buffer()
+    source.writeUtf8('b'.repeat(20))
+
+    assertEquals(20, source.read(sink, 25))
+    assertEquals(30, sink.size)
+    assertEquals(0, source.size)
+    assertEquals('a'.repeat(10) + 'b'.repeat(20), sink.readUtf8(30))
+  }
+
+  @Test fun indexOfWithOffset() {
+    val buffer = Buffer()
+    val halfSegment = Segment.SIZE / 2
+    buffer.writeUtf8('a'.repeat(halfSegment))
+    buffer.writeUtf8('b'.repeat(halfSegment))
+    buffer.writeUtf8('c'.repeat(halfSegment))
+    buffer.writeUtf8('d'.repeat(halfSegment))
+    assertEquals(0, buffer.indexOf('a'.toByte(), 0))
+    assertEquals((halfSegment - 1).toLong(), buffer.indexOf('a'.toByte(), (halfSegment - 1).toLong()))
+    assertEquals(halfSegment.toLong(), buffer.indexOf('b'.toByte(), (halfSegment - 1).toLong()))
+    assertEquals((halfSegment * 2).toLong(), buffer.indexOf('c'.toByte(), (halfSegment - 1).toLong()))
+    assertEquals((halfSegment * 3).toLong(), buffer.indexOf('d'.toByte(), (halfSegment - 1).toLong()))
+    assertEquals((halfSegment * 3).toLong(), buffer.indexOf('d'.toByte(), (halfSegment * 2).toLong()))
+    assertEquals((halfSegment * 3).toLong(), buffer.indexOf('d'.toByte(), (halfSegment * 3).toLong()))
+    assertEquals((halfSegment * 4 - 1).toLong(), buffer.indexOf('d'.toByte(), (halfSegment * 4 - 1).toLong()))
+  }
+
+  @Test fun byteAt() {
+    val buffer = Buffer()
+    buffer.writeUtf8("a")
+    buffer.writeUtf8('b'.repeat(Segment.SIZE))
+    buffer.writeUtf8("c")
+    assertEquals('a'.toLong(), buffer[0].toLong())
+    assertEquals('a'.toLong(), buffer[0].toLong()) // getByte doesn't mutate!
+    assertEquals('c'.toLong(), buffer[buffer.size - 1].toLong())
+    assertEquals('b'.toLong(), buffer[buffer.size - 2].toLong())
+    assertEquals('b'.toLong(), buffer[buffer.size - 3].toLong())
+  }
+
+  @Test fun getByteOfEmptyBuffer() {
+    val buffer = Buffer()
+    assertFailsWith<IndexOutOfBoundsException> {
+      buffer[0]
+    }
+  }
+
+  @Test
+  fun writePrefixToEmptyBuffer() {
+    val sink = Buffer()
+    val source = Buffer()
+    source.writeUtf8("abcd")
+    sink.write(source, 2)
+    assertEquals("ab", sink.readUtf8(2))
+  }
+
+  @Suppress("ReplaceAssertBooleanWithAssertEquality")
+  @Test fun equalsAndHashCodeEmpty() {
+    val a = Buffer()
+    val b = Buffer()
+    assertTrue(a == b)
+    assertTrue(a.hashCode() == b.hashCode())
+  }
+
+  @Suppress("ReplaceAssertBooleanWithAssertEquality")
+  @Test fun equalsAndHashCode() {
+    val a = Buffer().writeUtf8("dog")
+    val b = Buffer().writeUtf8("hotdog")
+    assertFalse(a == b)
+    assertFalse(a.hashCode() == b.hashCode())
+
+    b.readUtf8(3) // Leaves b containing 'dog'.
+    assertTrue(a == b)
+    assertTrue(a.hashCode() == b.hashCode())
+  }
+
+  @Suppress("ReplaceAssertBooleanWithAssertEquality")
+  @Test fun equalsAndHashCodeSpanningSegments() {
+    val data = ByteArray(1024 * 1024)
+    val dice = Random(0)
+    dice.nextBytes(data)
+
+    val a = bufferWithRandomSegmentLayout(dice, data)
+    val b = bufferWithRandomSegmentLayout(dice, data)
+    assertTrue(a == b)
+    assertTrue(a.hashCode() == b.hashCode())
+
+    data[data.size / 2]++ // Change a single byte.
+    val c = bufferWithRandomSegmentLayout(dice, data)
+    assertFalse(a == c)
+    assertFalse(a.hashCode() == c.hashCode())
+  }
+
+  /**
+   * When writing data that's already buffered, there's no reason to page the
+   * data by segment.
+   */
+  @Test fun readAllWritesAllSegmentsAtOnce() {
+    val write1 = Buffer().writeUtf8(
+      'a'.repeat(Segment.SIZE) +
+        'b'.repeat(Segment.SIZE) +
+        'c'.repeat(Segment.SIZE)
+    )
+
+    val source = Buffer().writeUtf8(
+      'a'.repeat(Segment.SIZE) +
+        'b'.repeat(Segment.SIZE) +
+        'c'.repeat(Segment.SIZE)
+    )
+
+    val mockSink = MockSink()
+
+    assertEquals((Segment.SIZE * 3).toLong(), source.readAll(mockSink))
+    assertEquals(0, source.size)
+    mockSink.assertLog("write($write1, ${write1.size})")
+  }
+
+  @Test fun writeAllMultipleSegments() {
+    val source = Buffer().writeUtf8('a'.repeat(Segment.SIZE * 3))
+    val sink = Buffer()
+
+    assertEquals((Segment.SIZE * 3).toLong(), sink.writeAll(source))
+    assertEquals(0, source.size)
+    assertEquals('a'.repeat(Segment.SIZE * 3), sink.readUtf8())
+  }
+
+  @Test fun copyTo() {
+    val source = Buffer()
+    source.writeUtf8("party")
+
+    val target = Buffer()
+    source.copyTo(target, 1, 3)
+
+    assertEquals("art", target.readUtf8())
+    assertEquals("party", source.readUtf8())
+  }
+
+  @Test fun copyToOnSegmentBoundary() {
+    val `as` = 'a'.repeat(Segment.SIZE)
+    val bs = 'b'.repeat(Segment.SIZE)
+    val cs = 'c'.repeat(Segment.SIZE)
+    val ds = 'd'.repeat(Segment.SIZE)
+
+    val source = Buffer()
+    source.writeUtf8(`as`)
+    source.writeUtf8(bs)
+    source.writeUtf8(cs)
+
+    val target = Buffer()
+    target.writeUtf8(ds)
+
+    source.copyTo(target, `as`.length.toLong(), (bs.length + cs.length).toLong())
+    assertEquals(ds + bs + cs, target.readUtf8())
+  }
+
+  @Test fun copyToOffSegmentBoundary() {
+    val `as` = 'a'.repeat(Segment.SIZE - 1)
+    val bs = 'b'.repeat(Segment.SIZE + 2)
+    val cs = 'c'.repeat(Segment.SIZE - 4)
+    val ds = 'd'.repeat(Segment.SIZE + 8)
+
+    val source = Buffer()
+    source.writeUtf8(`as`)
+    source.writeUtf8(bs)
+    source.writeUtf8(cs)
+
+    val target = Buffer()
+    target.writeUtf8(ds)
+
+    source.copyTo(target, `as`.length.toLong(), (bs.length + cs.length).toLong())
+    assertEquals(ds + bs + cs, target.readUtf8())
+  }
+
+  @Test fun copyToSourceAndTargetCanBeTheSame() {
+    val `as` = 'a'.repeat(Segment.SIZE)
+    val bs = 'b'.repeat(Segment.SIZE)
+
+    val source = Buffer()
+    source.writeUtf8(`as`)
+    source.writeUtf8(bs)
+
+    source.copyTo(source, 0, source.size)
+    assertEquals(`as` + bs + `as` + bs, source.readUtf8())
+  }
+
+  @Test fun copyToEmptySource() {
+    val source = Buffer()
+    val target = Buffer().writeUtf8("aaa")
+    source.copyTo(target, 0L, 0L)
+    assertEquals("", source.readUtf8())
+    assertEquals("aaa", target.readUtf8())
+  }
+
+  @Test fun copyToEmptyTarget() {
+    val source = Buffer().writeUtf8("aaa")
+    val target = Buffer()
+    source.copyTo(target, 0L, 3L)
+    assertEquals("aaa", source.readUtf8())
+    assertEquals("aaa", target.readUtf8())
+  }
+
+  @Test fun snapshotReportsAccurateSize() {
+    val buf = Buffer().write(byteArrayOf(0, 1, 2, 3))
+    assertEquals(1, buf.snapshot(1).size)
+  }
+}
diff --git a/okio/src/commonTest/kotlin/okio/CommonOkioKotlinTest.kt b/okio/src/commonTest/kotlin/okio/CommonOkioKotlinTest.kt
new file mode 100644
index 0000000..131dffb
--- /dev/null
+++ b/okio/src/commonTest/kotlin/okio/CommonOkioKotlinTest.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+class CommonOkioKotlinTest {
+  @Test fun sourceBuffer() {
+    val source = Buffer().writeUtf8("a")
+    val buffered = (source as Source).buffer()
+    assertEquals(buffered.readUtf8(), "a")
+    assertEquals(source.size, 0L)
+  }
+
+  @Test fun sinkBuffer() {
+    val sink = Buffer()
+    val buffered = (sink as Sink).buffer()
+    buffered.writeUtf8("a")
+    assertEquals(sink.size, 0L)
+    buffered.flush()
+    assertEquals(sink.size, 1L)
+  }
+
+  @Test fun blackhole() {
+    blackholeSink().write(Buffer().writeUtf8("a"), 1L)
+  }
+}
diff --git a/okio/src/commonTest/kotlin/okio/CommonOptionsTest.kt b/okio/src/commonTest/kotlin/okio/CommonOptionsTest.kt
new file mode 100644
index 0000000..bb45321
--- /dev/null
+++ b/okio/src/commonTest/kotlin/okio/CommonOptionsTest.kt
@@ -0,0 +1,440 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+import okio.ByteString.Companion.encodeUtf8
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+import kotlin.test.fail
+
+class CommonOptionsTest {
+  /** Confirm that options prefers the first-listed option, not the longest or shortest one. */
+  @Test fun optionOrderTakesPrecedence() {
+    assertSelect("abcdefg", 0, "abc", "abcdef")
+    assertSelect("abcdefg", 0, "abcdef", "abc")
+  }
+
+  @Test fun simpleOptionsTrie() {
+    assertEquals(
+      utf8Options("hotdog", "hoth", "hot").trieString(),
+      """
+        |hot
+        |   -> 2
+        |   d
+        |    og -> 0
+        |   h -> 1
+        |""".trimMargin()
+    )
+  }
+
+  @Test fun realisticOptionsTrie() {
+    // These are the fields of OkHttpClient in 3.10.
+    val options = utf8Options(
+      "dispatcher",
+      "proxy",
+      "protocols",
+      "connectionSpecs",
+      "interceptors",
+      "networkInterceptors",
+      "eventListenerFactory",
+      "proxySelector", // No index 7 in the trie because 'proxy' is a prefix!
+      "cookieJar",
+      "cache",
+      "internalCache",
+      "socketFactory",
+      "sslSocketFactory",
+      "certificateChainCleaner",
+      "hostnameVerifier",
+      "certificatePinner",
+      "proxyAuthenticator", // No index 16 in the trie because 'proxy' is a prefix!
+      "authenticator",
+      "connectionPool",
+      "dns",
+      "followSslRedirects",
+      "followRedirects",
+      "retryOnConnectionFailure",
+      "connectTimeout",
+      "readTimeout",
+      "writeTimeout",
+      "pingInterval"
+    )
+    assertEquals(
+      options.trieString(),
+      """
+        |a
+        | uthenticator -> 17
+        |c
+        | a
+        |  che -> 9
+        | e
+        |  rtificate
+        |           C
+        |            hainCleaner -> 13
+        |           P
+        |            inner -> 15
+        | o
+        |  n
+        |   nect
+        |       T
+        |        imeout -> 23
+        |       i
+        |        on
+        |          P
+        |           ool -> 18
+        |          S
+        |           pecs -> 3
+        |  o
+        |   kieJar -> 8
+        |d
+        | i
+        |  spatcher -> 0
+        | n
+        |  s -> 19
+        |e
+        | ventListenerFactory -> 6
+        |f
+        | ollow
+        |      R
+        |       edirects -> 21
+        |      S
+        |       slRedirects -> 20
+        |h
+        | ostnameVerifier -> 14
+        |i
+        | nter
+        |     c
+        |      eptors -> 4
+        |     n
+        |      alCache -> 10
+        |n
+        | etworkInterceptors -> 5
+        |p
+        | i
+        |  ngInterval -> 26
+        | r
+        |  o
+        |   t
+        |    ocols -> 2
+        |   x
+        |    y -> 1
+        |r
+        | e
+        |  a
+        |   dTimeout -> 24
+        |  t
+        |   ryOnConnectionFailure -> 22
+        |s
+        | o
+        |  cketFactory -> 11
+        | s
+        |  lSocketFactory -> 12
+        |w
+        | riteTimeout -> 25
+        |""".trimMargin()
+    )
+    assertSelect("", -1, options)
+    assertSelect("a", -1, options)
+    assertSelect("eventListenerFactor", -1, options)
+    assertSelect("dnst", 19, options)
+    assertSelect("proxyproxy", 1, options)
+    assertSelect("prox", -1, options)
+
+    assertSelect("dispatcher", 0, options)
+    assertSelect("proxy", 1, options)
+    assertSelect("protocols", 2, options)
+    assertSelect("connectionSpecs", 3, options)
+    assertSelect("interceptors", 4, options)
+    assertSelect("networkInterceptors", 5, options)
+    assertSelect("eventListenerFactory", 6, options)
+    assertSelect("proxySelector", 1, options) // 'proxy' is a prefix.
+    assertSelect("cookieJar", 8, options)
+    assertSelect("cache", 9, options)
+    assertSelect("internalCache", 10, options)
+    assertSelect("socketFactory", 11, options)
+    assertSelect("sslSocketFactory", 12, options)
+    assertSelect("certificateChainCleaner", 13, options)
+    assertSelect("hostnameVerifier", 14, options)
+    assertSelect("certificatePinner", 15, options)
+    assertSelect("proxyAuthenticator", 1, options) // 'proxy' is a prefix.
+    assertSelect("authenticator", 17, options)
+    assertSelect("connectionPool", 18, options)
+    assertSelect("dns", 19, options)
+    assertSelect("followSslRedirects", 20, options)
+    assertSelect("followRedirects", 21, options)
+    assertSelect("retryOnConnectionFailure", 22, options)
+    assertSelect("connectTimeout", 23, options)
+    assertSelect("readTimeout", 24, options)
+    assertSelect("writeTimeout", 25, options)
+    assertSelect("pingInterval", 26, options)
+  }
+
+  @Test fun emptyOptions() {
+    val options = utf8Options()
+    assertSelect("", -1, options)
+    assertSelect("a", -1, options)
+    assertSelect("abc", -1, options)
+  }
+
+  @Test fun emptyStringInOptionsTrie() {
+    assertFailsWith<IllegalArgumentException> {
+      utf8Options("")
+    }
+    assertFailsWith<IllegalArgumentException> {
+      utf8Options("abc", "")
+    }
+  }
+
+  @Test fun multipleIdenticalValues() {
+    try {
+      utf8Options("abc", "abc")
+      fail()
+    } catch (expected: IllegalArgumentException) {
+      assertEquals(expected.message, "duplicate option: [text=abc]")
+    }
+  }
+
+  @Test fun prefixesAreStripped() {
+    val options = utf8Options("abcA", "abc", "abcB")
+    assertEquals(
+      options.trieString(),
+      """
+        |abc
+        |   -> 1
+        |   A -> 0
+        |""".trimMargin()
+    )
+    assertSelect("abc", 1, options)
+    assertSelect("abcA", 0, options)
+    assertSelect("abcB", 1, options)
+    assertSelect("abcC", 1, options)
+    assertSelect("ab", -1, options)
+  }
+
+  @Test fun multiplePrefixesAreStripped() {
+    assertEquals(
+      utf8Options("a", "ab", "abc", "abcd", "abcde").trieString(),
+      """
+        |a -> 0
+        |""".trimMargin()
+    )
+    assertEquals(
+      utf8Options("abc", "a", "ab", "abe", "abcd", "abcf").trieString(),
+      """
+        |a
+        | -> 1
+        | bc -> 0
+        |""".trimMargin()
+    )
+    assertEquals(
+      utf8Options("abc", "ab", "a").trieString(),
+      """
+        |a
+        | -> 2
+        | b
+        |  -> 1
+        |  c -> 0
+        |""".trimMargin()
+    )
+    assertEquals(
+      utf8Options("abcd", "abce", "abc", "abcf", "abcg").trieString(),
+      """
+        |abc
+        |   -> 2
+        |   d -> 0
+        |   e -> 1
+        |""".trimMargin()
+    )
+  }
+
+  @Test fun scan() {
+    val options = utf8Options("abc")
+    assertSelect("abcde", 0, options)
+  }
+
+  @Test fun scanReturnsPrefix() {
+    val options = utf8Options("abcdefg", "ab")
+    assertSelect("ab", 1, options)
+    assertSelect("abcd", 1, options)
+    assertSelect("abcdefg", 0, options)
+    assertSelect("abcdefghi", 0, options)
+    assertSelect("abcdhi", 1, options)
+  }
+
+  @Test fun select() {
+    val options = utf8Options("a", "b", "c")
+    assertSelect("a", 0, options)
+    assertSelect("b", 1, options)
+    assertSelect("c", 2, options)
+    assertSelect("d", -1, options)
+    assertSelect("aa", 0, options)
+    assertSelect("bb", 1, options)
+    assertSelect("cc", 2, options)
+    assertSelect("dd", -1, options)
+  }
+
+  @Test fun selectSelect() {
+    val options = utf8Options("aa", "ab", "ba", "bb")
+    assertSelect("a", -1, options)
+    assertSelect("b", -1, options)
+    assertSelect("c", -1, options)
+    assertSelect("aa", 0, options)
+    assertSelect("ab", 1, options)
+    assertSelect("ac", -1, options)
+    assertSelect("ba", 2, options)
+    assertSelect("bb", 3, options)
+    assertSelect("bc", -1, options)
+    assertSelect("ca", -1, options)
+    assertSelect("cb", -1, options)
+    assertSelect("cc", -1, options)
+  }
+
+  @Test fun selectScan() {
+    val options = utf8Options("abcd", "defg")
+    assertSelect("a", -1, options)
+    assertSelect("d", -1, options)
+    assertSelect("h", -1, options)
+    assertSelect("ab", -1, options)
+    assertSelect("ae", -1, options)
+    assertSelect("de", -1, options)
+    assertSelect("db", -1, options)
+    assertSelect("hi", -1, options)
+    assertSelect("abcd", 0, options)
+    assertSelect("aefg", -1, options)
+    assertSelect("defg", 1, options)
+    assertSelect("dbcd", -1, options)
+    assertSelect("hijk", -1, options)
+    assertSelect("abcdh", 0, options)
+    assertSelect("defgh", 1, options)
+    assertSelect("hijkl", -1, options)
+  }
+
+  @Test fun scanSelect() {
+    val options = utf8Options("abcd", "abce")
+    assertSelect("a", -1, options)
+    assertSelect("f", -1, options)
+    assertSelect("abc", -1, options)
+    assertSelect("abf", -1, options)
+    assertSelect("abcd", 0, options)
+    assertSelect("abce", 1, options)
+    assertSelect("abcf", -1, options)
+    assertSelect("abcdf", 0, options)
+    assertSelect("abcef", 1, options)
+  }
+
+  @Test fun scanSpansSegments() {
+    val options = utf8Options("abcd")
+    assertSelect(bufferWithSegments("a", "bcd"), 0, options)
+    assertSelect(bufferWithSegments("a", "bcde"), 0, options)
+    assertSelect(bufferWithSegments("ab", "cd"), 0, options)
+    assertSelect(bufferWithSegments("ab", "cde"), 0, options)
+    assertSelect(bufferWithSegments("abc", "d"), 0, options)
+    assertSelect(bufferWithSegments("abc", "de"), 0, options)
+    assertSelect(bufferWithSegments("abcd", "e"), 0, options)
+    assertSelect(bufferWithSegments("a", "bce"), -1, options)
+    assertSelect(bufferWithSegments("a", "bce"), -1, options)
+    assertSelect(bufferWithSegments("ab", "ce"), -1, options)
+    assertSelect(bufferWithSegments("ab", "ce"), -1, options)
+    assertSelect(bufferWithSegments("abc", "e"), -1, options)
+    assertSelect(bufferWithSegments("abc", "ef"), -1, options)
+    assertSelect(bufferWithSegments("abce", "f"), -1, options)
+  }
+
+  @Test fun selectSpansSegments() {
+    val options = utf8Options("aa", "ab", "ba", "bb")
+    assertSelect(bufferWithSegments("a", "a"), 0, options)
+    assertSelect(bufferWithSegments("a", "b"), 1, options)
+    assertSelect(bufferWithSegments("a", "c"), -1, options)
+    assertSelect(bufferWithSegments("b", "a"), 2, options)
+    assertSelect(bufferWithSegments("b", "b"), 3, options)
+    assertSelect(bufferWithSegments("b", "c"), -1, options)
+    assertSelect(bufferWithSegments("c", "a"), -1, options)
+    assertSelect(bufferWithSegments("c", "b"), -1, options)
+    assertSelect(bufferWithSegments("c", "c"), -1, options)
+    assertSelect(bufferWithSegments("a", "ad"), 0, options)
+    assertSelect(bufferWithSegments("a", "bd"), 1, options)
+    assertSelect(bufferWithSegments("a", "cd"), -1, options)
+    assertSelect(bufferWithSegments("b", "ad"), 2, options)
+    assertSelect(bufferWithSegments("b", "bd"), 3, options)
+    assertSelect(bufferWithSegments("b", "cd"), -1, options)
+    assertSelect(bufferWithSegments("c", "ad"), -1, options)
+    assertSelect(bufferWithSegments("c", "bd"), -1, options)
+    assertSelect(bufferWithSegments("c", "cd"), -1, options)
+  }
+
+  private fun utf8Options(vararg options: String): Options {
+    return Options.of(*options.map { it.encodeUtf8() }.toTypedArray())
+  }
+
+  private fun assertSelect(data: String, expected: Int, options: Options) {
+    assertSelect(Buffer().writeUtf8(data), expected, options)
+  }
+
+  private fun assertSelect(data: String, expected: Int, vararg options: String) {
+    assertSelect(data, expected, utf8Options(*options))
+  }
+
+  private fun assertSelect(data: Buffer, expected: Int, options: Options) {
+    val initialSize = data.size
+    val actual = data.select(options)
+
+    assertEquals(actual, expected)
+    if (expected == -1) {
+      assertEquals(data.size, initialSize)
+    } else {
+      assertEquals(data.size + options[expected].size, initialSize)
+    }
+  }
+
+  private fun Options.trieString(): String {
+    val result = StringBuilder()
+    printTrieNode(result, 0)
+    return result.toString()
+  }
+
+  private fun Options.printTrieNode(out: StringBuilder, offset: Int = 0, indent: String = "") {
+    if (trie[offset + 1] != -1) {
+      // Print the prefix.
+      out.append("$indent-> ${trie[offset + 1]}\n")
+    }
+
+    if (trie[offset] > 0) {
+      // Print the select.
+      val selectChoiceCount = trie[offset]
+      for (i in 0 until selectChoiceCount) {
+        out.append("$indent${trie[offset + 2 + i].toChar()}")
+        printTrieResult(out, trie[offset + 2 + selectChoiceCount + i], "$indent ")
+      }
+    } else {
+      // Print the scan.
+      val scanByteCount = -1 * trie[offset]
+      out.append(indent)
+      for (i in 0 until scanByteCount) {
+        out.append(trie[offset + 2 + i].toChar())
+      }
+      printTrieResult(out, trie[offset + 2 + scanByteCount], "$indent${" ".repeat(scanByteCount)}")
+    }
+  }
+
+  private fun Options.printTrieResult(out: StringBuilder, result: Int, indent: String) {
+    if (result >= 0) {
+      out.append(" -> $result\n")
+    } else {
+      out.append("\n")
+      printTrieNode(out, -1 * result, indent)
+    }
+  }
+}
diff --git a/okio/src/commonTest/kotlin/okio/CommonRealBufferedSinkTest.kt b/okio/src/commonTest/kotlin/okio/CommonRealBufferedSinkTest.kt
new file mode 100644
index 0000000..abbbae8
--- /dev/null
+++ b/okio/src/commonTest/kotlin/okio/CommonRealBufferedSinkTest.kt
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+import kotlin.test.fail
+
+/**
+ * Tests solely for the behavior of RealBufferedSink's implementation. For generic
+ * BufferedSink behavior use BufferedSinkTest.
+ */
+class CommonRealBufferedSinkTest {
+  @Test fun bufferedSinkEmitsTailWhenItIsComplete() {
+    val sink = Buffer()
+    val bufferedSink = (sink as Sink).buffer()
+    bufferedSink.writeUtf8("a".repeat(Segment.SIZE - 1))
+    assertEquals(0, sink.size)
+    bufferedSink.writeByte(0)
+    assertEquals(Segment.SIZE.toLong(), sink.size)
+    assertEquals(0, bufferedSink.buffer.size)
+  }
+
+  @Test fun bufferedSinkEmitMultipleSegments() {
+    val sink = Buffer()
+    val bufferedSink = (sink as Sink).buffer()
+    bufferedSink.writeUtf8("a".repeat(Segment.SIZE * 4 - 1))
+    assertEquals(Segment.SIZE.toLong() * 3L, sink.size)
+    assertEquals(Segment.SIZE.toLong() - 1L, bufferedSink.buffer.size)
+  }
+
+  @Test fun bufferedSinkFlush() {
+    val sink = Buffer()
+    val bufferedSink = (sink as Sink).buffer()
+    bufferedSink.writeByte('a'.toInt())
+    assertEquals(0, sink.size)
+    bufferedSink.flush()
+    assertEquals(0, bufferedSink.buffer.size)
+    assertEquals(1, sink.size)
+  }
+
+  @Test fun bytesEmittedToSinkWithFlush() {
+    val sink = Buffer()
+    val bufferedSink = (sink as Sink).buffer()
+    bufferedSink.writeUtf8("abc")
+    bufferedSink.flush()
+    assertEquals(3, sink.size)
+  }
+
+  @Test fun bytesNotEmittedToSinkWithoutFlush() {
+    val sink = Buffer()
+    val bufferedSink = (sink as Sink).buffer()
+    bufferedSink.writeUtf8("abc")
+    assertEquals(0, sink.size)
+  }
+
+  @Test fun bytesEmittedToSinkWithEmit() {
+    val sink = Buffer()
+    val bufferedSink = (sink as Sink).buffer()
+    bufferedSink.writeUtf8("abc")
+    bufferedSink.emit()
+    assertEquals(3, sink.size)
+  }
+
+  @Test fun completeSegmentsEmitted() {
+    val sink = Buffer()
+    val bufferedSink = (sink as Sink).buffer()
+    bufferedSink.writeUtf8("a".repeat(Segment.SIZE * 3))
+    assertEquals(Segment.SIZE.toLong() * 3L, sink.size)
+  }
+
+  @Test fun incompleteSegmentsNotEmitted() {
+    val sink = Buffer()
+    val bufferedSink = (sink as Sink).buffer()
+    bufferedSink.writeUtf8("a".repeat(Segment.SIZE * 3 - 1))
+    assertEquals(Segment.SIZE.toLong() * 2L, sink.size)
+  }
+
+  @Test fun closeWithExceptionWhenWriting() {
+    val mockSink = MockSink()
+    mockSink.scheduleThrow(0, IOException())
+    val bufferedSink = mockSink.buffer()
+    bufferedSink.writeByte('a'.toInt())
+    assertFailsWith<IOException> {
+      bufferedSink.close()
+    }
+
+    mockSink.assertLog("write([text=a], 1)", "close()")
+  }
+
+  @Test fun closeWithExceptionWhenClosing() {
+    val mockSink = MockSink()
+    mockSink.scheduleThrow(1, IOException())
+    val bufferedSink = mockSink.buffer()
+    bufferedSink.writeByte('a'.toInt())
+    assertFailsWith<IOException> {
+      bufferedSink.close()
+    }
+
+    mockSink.assertLog("write([text=a], 1)", "close()")
+  }
+
+  @Test fun closeWithExceptionWhenWritingAndClosing() {
+    val mockSink = MockSink()
+    mockSink.scheduleThrow(0, IOException("first"))
+    mockSink.scheduleThrow(1, IOException("second"))
+    val bufferedSink = mockSink.buffer()
+    bufferedSink.writeByte('a'.toInt())
+    try {
+      bufferedSink.close()
+      fail()
+    } catch (expected: IOException) {
+      assertEquals("first", expected.message)
+    }
+
+    mockSink.assertLog("write([text=a], 1)", "close()")
+  }
+
+  @Test fun operationsAfterClose() {
+    val mockSink = MockSink()
+    val bufferedSink = mockSink.buffer()
+    bufferedSink.writeByte('a'.toInt())
+    bufferedSink.close()
+
+    // Test a sample set of methods.
+    assertFailsWith<IllegalStateException> {
+      bufferedSink.writeByte('a'.toInt())
+    }
+
+    assertFailsWith<IllegalStateException> {
+      bufferedSink.write(ByteArray(10))
+    }
+
+    assertFailsWith<IllegalStateException> {
+      bufferedSink.emitCompleteSegments()
+    }
+
+    assertFailsWith<IllegalStateException> {
+      bufferedSink.emit()
+    }
+
+    assertFailsWith<IllegalStateException> {
+      bufferedSink.flush()
+    }
+  }
+
+  @Test fun writeAll() {
+    val mockSink = MockSink()
+    val bufferedSink = mockSink.buffer()
+
+    bufferedSink.buffer.writeUtf8("abc")
+    assertEquals(3, bufferedSink.writeAll(Buffer().writeUtf8("def")))
+
+    assertEquals(6, bufferedSink.buffer.size)
+    assertEquals("abcdef", bufferedSink.buffer.readUtf8(6))
+    mockSink.assertLog() // No writes.
+  }
+
+  @Test fun writeAllExhausted() {
+    val mockSink = MockSink()
+    val bufferedSink = mockSink.buffer()
+
+    assertEquals(0, bufferedSink.writeAll(Buffer()))
+    assertEquals(0, bufferedSink.buffer.size)
+    mockSink.assertLog() // No writes.
+  }
+
+  @Test fun writeAllWritesOneSegmentAtATime() {
+    val write1 = Buffer().writeUtf8("a".repeat(Segment.SIZE))
+    val write2 = Buffer().writeUtf8("b".repeat(Segment.SIZE))
+    val write3 = Buffer().writeUtf8("c".repeat(Segment.SIZE))
+
+    val source = Buffer().writeUtf8(
+      "${"a".repeat(Segment.SIZE)}${"b".repeat(Segment.SIZE)}${"c".repeat(Segment.SIZE)}"
+    )
+
+    val mockSink = MockSink()
+    val bufferedSink = mockSink.buffer()
+    assertEquals(Segment.SIZE.toLong() * 3L, bufferedSink.writeAll(source))
+
+    mockSink.assertLog(
+      "write($write1, ${write1.size})",
+      "write($write2, ${write2.size})",
+      "write($write3, ${write3.size})"
+    )
+  }
+}
diff --git a/okio/src/commonTest/kotlin/okio/CommonRealBufferedSourceTest.kt b/okio/src/commonTest/kotlin/okio/CommonRealBufferedSourceTest.kt
new file mode 100644
index 0000000..4663919
--- /dev/null
+++ b/okio/src/commonTest/kotlin/okio/CommonRealBufferedSourceTest.kt
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+
+/**
+ * Tests solely for the behavior of RealBufferedSource's implementation. For generic
+ * BufferedSource behavior use BufferedSourceTest.
+ */
+class CommonRealBufferedSourceTest {
+  @Test fun indexOfStopsReadingAtLimit() {
+    val buffer = Buffer().writeUtf8("abcdef")
+    val bufferedSource = (
+      object : Source by buffer {
+        override fun read(sink: Buffer, byteCount: Long): Long {
+          return buffer.read(sink, minOf(1, byteCount))
+        }
+      }
+      ).buffer()
+
+    assertEquals(6, buffer.size)
+    assertEquals(-1, bufferedSource.indexOf('e'.toByte(), 0, 4))
+    assertEquals(2, buffer.size)
+  }
+
+  @Test fun requireTracksBufferFirst() {
+    val source = Buffer()
+    source.writeUtf8("bb")
+
+    val bufferedSource = (source as Source).buffer()
+    bufferedSource.buffer.writeUtf8("aa")
+
+    bufferedSource.require(2)
+    assertEquals(2, bufferedSource.buffer.size)
+    assertEquals(2, source.size)
+  }
+
+  @Test fun requireIncludesBufferBytes() {
+    val source = Buffer()
+    source.writeUtf8("b")
+
+    val bufferedSource = (source as Source).buffer()
+    bufferedSource.buffer.writeUtf8("a")
+
+    bufferedSource.require(2)
+    assertEquals("ab", bufferedSource.buffer.readUtf8(2))
+  }
+
+  @Test fun requireInsufficientData() {
+    val source = Buffer()
+    source.writeUtf8("a")
+
+    val bufferedSource = (source as Source).buffer()
+
+    assertFailsWith<EOFException> {
+      bufferedSource.require(2)
+    }
+  }
+
+  @Test fun requireReadsOneSegmentAtATime() {
+    val source = Buffer()
+    source.writeUtf8("a".repeat(Segment.SIZE))
+    source.writeUtf8("b".repeat(Segment.SIZE))
+
+    val bufferedSource = (source as Source).buffer()
+
+    bufferedSource.require(2)
+    assertEquals(Segment.SIZE.toLong(), source.size)
+    assertEquals(Segment.SIZE.toLong(), bufferedSource.buffer.size)
+  }
+
+  @Test fun skipReadsOneSegmentAtATime() {
+    val source = Buffer()
+    source.writeUtf8("a".repeat(Segment.SIZE))
+    source.writeUtf8("b".repeat(Segment.SIZE))
+    val bufferedSource = (source as Source).buffer()
+    bufferedSource.skip(2)
+    assertEquals(Segment.SIZE.toLong(), source.size)
+    assertEquals(Segment.SIZE.toLong() - 2L, bufferedSource.buffer.size)
+  }
+
+  @Test fun skipTracksBufferFirst() {
+    val source = Buffer()
+    source.writeUtf8("bb")
+
+    val bufferedSource = (source as Source).buffer()
+    bufferedSource.buffer.writeUtf8("aa")
+
+    bufferedSource.skip(2)
+    assertEquals(0, bufferedSource.buffer.size)
+    assertEquals(2, source.size)
+  }
+
+  @Test fun operationsAfterClose() {
+    val source = Buffer()
+    val bufferedSource = (source as Source).buffer()
+    bufferedSource.close()
+
+    // Test a sample set of methods.
+    assertFailsWith<IllegalStateException> {
+      bufferedSource.indexOf(1.toByte())
+    }
+
+    assertFailsWith<IllegalStateException> {
+      bufferedSource.skip(1)
+    }
+
+    assertFailsWith<IllegalStateException> {
+      bufferedSource.readByte()
+    }
+
+    assertFailsWith<IllegalStateException> {
+      bufferedSource.readByteString(10)
+    }
+  }
+
+  /**
+   * We don't want readAll to buffer an unbounded amount of data. Instead it
+   * should buffer a segment, write it, and repeat.
+   */
+  @Test fun readAllReadsOneSegmentAtATime() {
+    val write1 = Buffer().writeUtf8("a".repeat(Segment.SIZE))
+    val write2 = Buffer().writeUtf8("b".repeat(Segment.SIZE))
+    val write3 = Buffer().writeUtf8("c".repeat(Segment.SIZE))
+
+    val source = Buffer().writeUtf8(
+      "${"a".repeat(Segment.SIZE)}${"b".repeat(Segment.SIZE)}${"c".repeat(Segment.SIZE)}"
+    )
+
+    val mockSink = MockSink()
+    val bufferedSource = (source as Source).buffer()
+    assertEquals(Segment.SIZE.toLong() * 3L, bufferedSource.readAll(mockSink))
+    mockSink.assertLog(
+      "write($write1, ${write1.size})",
+      "write($write2, ${write2.size})",
+      "write($write3, ${write3.size})"
+    )
+  }
+}
diff --git a/okio/src/commonTest/kotlin/okio/FakeClock.kt b/okio/src/commonTest/kotlin/okio/FakeClock.kt
new file mode 100644
index 0000000..31cf550
--- /dev/null
+++ b/okio/src/commonTest/kotlin/okio/FakeClock.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 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 okio
+
+import kotlinx.datetime.Clock
+import kotlinx.datetime.Instant
+import kotlin.time.Duration
+import kotlin.time.ExperimentalTime
+
+@ExperimentalTime
+internal class FakeClock : Clock {
+  var time = Instant.parse("2021-01-01T00:00:00Z")
+
+  override fun now() = time
+
+  fun sleep(duration: Duration) {
+    time = time.plus(duration)
+  }
+}
diff --git a/okio/src/commonTest/kotlin/okio/HashingSinkTest.kt b/okio/src/commonTest/kotlin/okio/HashingSinkTest.kt
new file mode 100644
index 0000000..db1aeee
--- /dev/null
+++ b/okio/src/commonTest/kotlin/okio/HashingSinkTest.kt
@@ -0,0 +1,119 @@
+/*
+ * 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 okio
+
+import okio.HashingSink.Companion.hmacSha1
+import okio.HashingSink.Companion.hmacSha256
+import okio.HashingSink.Companion.hmacSha512
+import okio.HashingSink.Companion.sha1
+import okio.HashingSink.Companion.sha256
+import okio.HashingSink.Companion.sha512
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+class HashingSinkTest {
+  private val source = Buffer()
+  private val sink = Buffer()
+
+  @Test fun md5() {
+    val hashingSink: HashingSink = HashingSink.md5(sink)
+    source.writeUtf8("abc")
+    hashingSink.write(source, 3L)
+    assertEquals(HashingTest.MD5_abc, hashingSink.hash)
+  }
+
+  @Test fun sha1() {
+    val hashingSink = sha1(sink)
+    source.writeUtf8("abc")
+    hashingSink.write(source, 3L)
+    assertEquals(HashingTest.SHA1_abc, hashingSink.hash)
+  }
+
+  @Test fun sha256() {
+    val hashingSink = sha256(sink)
+    source.writeUtf8("abc")
+    hashingSink.write(source, 3L)
+    assertEquals(HashingTest.SHA256_abc, hashingSink.hash)
+  }
+
+  @Test fun sha512() {
+    val hashingSink = sha512(sink)
+    source.writeUtf8("abc")
+    hashingSink.write(source, 3L)
+    assertEquals(HashingTest.SHA512_abc, hashingSink.hash)
+  }
+
+  @Test fun hmacSha1() {
+    val hashingSink = hmacSha1(sink, HashingTest.HMAC_KEY)
+    source.writeUtf8("abc")
+    hashingSink.write(source, 3L)
+    assertEquals(HashingTest.HMAC_SHA1_abc, hashingSink.hash)
+  }
+
+  @Test fun hmacSha256() {
+    val hashingSink = hmacSha256(sink, HashingTest.HMAC_KEY)
+    source.writeUtf8("abc")
+    hashingSink.write(source, 3L)
+    assertEquals(HashingTest.HMAC_SHA256_abc, hashingSink.hash)
+  }
+
+  @Test fun hmacSha512() {
+    val hashingSink = hmacSha512(sink, HashingTest.HMAC_KEY)
+    source.writeUtf8("abc")
+    hashingSink.write(source, 3L)
+    assertEquals(HashingTest.HMAC_SHA512_abc, hashingSink.hash)
+  }
+
+  @Test fun multipleWrites() {
+    val hashingSink = sha256(sink)
+    source.writeUtf8("a")
+    hashingSink.write(source, 1L)
+    source.writeUtf8("b")
+    hashingSink.write(source, 1L)
+    source.writeUtf8("c")
+    hashingSink.write(source, 1L)
+    assertEquals(HashingTest.SHA256_abc, hashingSink.hash)
+  }
+
+  @Test fun multipleHashes() {
+    val hashingSink = sha256(sink)
+    source.writeUtf8("abc")
+    hashingSink.write(source, 3L)
+    val hash_abc = hashingSink.hash
+    assertEquals(HashingTest.SHA256_abc, hash_abc)
+    source.writeUtf8("def")
+    hashingSink.write(source, 3L)
+    assertEquals(HashingTest.SHA256_def, hashingSink.hash)
+    assertEquals(HashingTest.SHA256_abc, hash_abc)
+  }
+
+  @Test fun multipleSegments() {
+    val hashingSink = sha256(sink)
+    source.write(HashingTest.r32k)
+    hashingSink.write(source, HashingTest.r32k.size.toLong())
+    assertEquals(HashingTest.SHA256_r32k, hashingSink.hash)
+  }
+
+  @Test fun readFromPrefixOfBuffer() {
+    source.writeUtf8("z")
+    source.write(HashingTest.r32k)
+    source.skip(1)
+    source.writeUtf8("z".repeat(Segment.SIZE * 2 - 1))
+    val hashingSink = sha256(sink)
+    hashingSink.write(source, HashingTest.r32k.size.toLong())
+    assertEquals(HashingTest.SHA256_r32k, hashingSink.hash)
+  }
+}
diff --git a/okio/src/commonTest/kotlin/okio/HashingSourceTest.kt b/okio/src/commonTest/kotlin/okio/HashingSourceTest.kt
new file mode 100644
index 0000000..83e2e26
--- /dev/null
+++ b/okio/src/commonTest/kotlin/okio/HashingSourceTest.kt
@@ -0,0 +1,128 @@
+/*
+ * 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 okio
+
+import okio.HashingSource.Companion.hmacSha1
+import okio.HashingSource.Companion.hmacSha256
+import okio.HashingSource.Companion.hmacSha512
+import okio.HashingSource.Companion.md5
+import okio.HashingSource.Companion.sha1
+import okio.HashingSource.Companion.sha256
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.fail
+
+class HashingSourceTest {
+  private val source = Buffer()
+  private val sink = Buffer()
+
+  @Test fun md5() {
+    val hashingSource = md5(source)
+    source.writeUtf8("abc")
+    assertEquals(3L, hashingSource.read(sink, Long.MAX_VALUE))
+    assertEquals(HashingTest.MD5_abc, hashingSource.hash)
+  }
+
+  @Test fun sha1() {
+    val hashingSource = sha1(source)
+    source.writeUtf8("abc")
+    assertEquals(3L, hashingSource.read(sink, Long.MAX_VALUE))
+    assertEquals(HashingTest.SHA1_abc, hashingSource.hash)
+  }
+
+  @Test fun sha256() {
+    val hashingSource = sha256(source)
+    source.writeUtf8("abc")
+    assertEquals(3L, hashingSource.read(sink, Long.MAX_VALUE))
+    assertEquals(HashingTest.SHA256_abc, hashingSource.hash)
+  }
+
+  @Test fun sha512() {
+    val hashingSource: HashingSource = HashingSource.sha512(source)
+    source.writeUtf8("abc")
+    assertEquals(3L, hashingSource.read(sink, Long.MAX_VALUE))
+    assertEquals(HashingTest.SHA512_abc, hashingSource.hash)
+  }
+
+  @Test fun hmacSha1() {
+    val hashingSource = hmacSha1(source, HashingTest.HMAC_KEY)
+    source.writeUtf8("abc")
+    assertEquals(3L, hashingSource.read(sink, Long.MAX_VALUE))
+    assertEquals(HashingTest.HMAC_SHA1_abc, hashingSource.hash)
+  }
+
+  @Test fun hmacSha256() {
+    val hashingSource = hmacSha256(source, HashingTest.HMAC_KEY)
+    source.writeUtf8("abc")
+    assertEquals(3L, hashingSource.read(sink, Long.MAX_VALUE))
+    assertEquals(HashingTest.HMAC_SHA256_abc, hashingSource.hash)
+  }
+
+  @Test fun hmacSha512() {
+    val hashingSource = hmacSha512(source, HashingTest.HMAC_KEY)
+    source.writeUtf8("abc")
+    assertEquals(3L, hashingSource.read(sink, Long.MAX_VALUE))
+    assertEquals(HashingTest.HMAC_SHA512_abc, hashingSource.hash)
+  }
+
+  @Test fun multipleReads() {
+    val hashingSource = sha256(source)
+    val bufferedSource = hashingSource.buffer()
+    source.writeUtf8("a")
+    assertEquals('a'.toLong(), bufferedSource.readUtf8CodePoint().toLong())
+    source.writeUtf8("b")
+    assertEquals('b'.toLong(), bufferedSource.readUtf8CodePoint().toLong())
+    source.writeUtf8("c")
+    assertEquals('c'.toLong(), bufferedSource.readUtf8CodePoint().toLong())
+    assertEquals(HashingTest.SHA256_abc, hashingSource.hash)
+  }
+
+  @Test fun multipleHashes() {
+    val hashingSource = sha256(source)
+    source.writeUtf8("abc")
+    assertEquals(3L, hashingSource.read(sink, Long.MAX_VALUE))
+    val hash_abc = hashingSource.hash
+    assertEquals(HashingTest.SHA256_abc, hash_abc)
+    source.writeUtf8("def")
+    assertEquals(3L, hashingSource.read(sink, Long.MAX_VALUE))
+    assertEquals(HashingTest.SHA256_def, hashingSource.hash)
+    assertEquals(HashingTest.SHA256_abc, hash_abc)
+  }
+
+  @Test fun multipleSegments() {
+    val hashingSource = sha256(source)
+    val bufferedSource = hashingSource.buffer()
+    source.write(HashingTest.r32k)
+    assertEquals(HashingTest.r32k, bufferedSource.readByteString())
+    assertEquals(HashingTest.SHA256_r32k, hashingSource.hash)
+  }
+
+  @Test fun readIntoSuffixOfBuffer() {
+    val hashingSource = sha256(source)
+    source.write(HashingTest.r32k)
+    sink.writeUtf8("z".repeat(Segment.SIZE * 2 - 1))
+    assertEquals(HashingTest.r32k.size.toLong(), hashingSource.read(sink, Long.MAX_VALUE))
+    assertEquals(HashingTest.SHA256_r32k, hashingSource.hash)
+  }
+
+  @Test fun hmacEmptyKey() {
+    try {
+      hmacSha256(source, ByteString.EMPTY)
+      fail()
+    } catch (expected: IllegalArgumentException) {
+    }
+  }
+}
diff --git a/okio/src/commonTest/kotlin/okio/HashingTest.kt b/okio/src/commonTest/kotlin/okio/HashingTest.kt
new file mode 100644
index 0000000..1cae58d
--- /dev/null
+++ b/okio/src/commonTest/kotlin/okio/HashingTest.kt
@@ -0,0 +1,143 @@
+/*
+ * 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 okio
+
+import okio.ByteString.Companion.decodeHex
+import okio.ByteString.Companion.encodeUtf8
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+class HashingTest {
+  @Test fun byteStringMd5() {
+    assertEquals(MD5_abc, "abc".encodeUtf8().md5())
+  }
+
+  @Test fun byteStringSha1() {
+    assertEquals(SHA1_abc, "abc".encodeUtf8().sha1())
+  }
+
+  @Test fun byteStringSha256() {
+    assertEquals(SHA256_abc, "abc".encodeUtf8().sha256())
+  }
+
+  @Test fun byteStringSha512() {
+    assertEquals(SHA512_abc, "abc".encodeUtf8().sha512())
+  }
+
+  @Test fun byteStringHmacSha1() {
+    assertEquals(HMAC_SHA1_abc, "abc".encodeUtf8().hmacSha1(HMAC_KEY))
+  }
+
+  @Test fun byteStringHmacSha256() {
+    assertEquals(HMAC_SHA256_abc, "abc".encodeUtf8().hmacSha256(HMAC_KEY))
+  }
+
+  @Test fun byteStringHmacSha512() {
+    assertEquals(HMAC_SHA512_abc, "abc".encodeUtf8().hmacSha512(HMAC_KEY))
+  }
+
+  @Test fun bufferMd5() {
+    assertEquals(MD5_abc, Buffer().writeUtf8("abc").md5())
+  }
+
+  @Test fun bufferSha1() {
+    assertEquals(SHA1_abc, Buffer().writeUtf8("abc").sha1())
+  }
+
+  @Test fun bufferSha256() {
+    assertEquals(SHA256_abc, Buffer().writeUtf8("abc").sha256())
+  }
+
+  @Test fun bufferSha512() {
+    assertEquals(SHA512_abc, Buffer().writeUtf8("abc").sha512())
+  }
+
+  @Test fun hashEmptySha256Buffer() {
+    assertEquals(SHA256_empty, Buffer().sha256())
+  }
+
+  @Test fun hashEmptySha512Buffer() {
+    assertEquals(SHA512_empty, Buffer().sha512())
+  }
+
+  @Test fun bufferHmacSha1() {
+    assertEquals(HMAC_SHA1_abc, Buffer().writeUtf8("abc").hmacSha1(HMAC_KEY))
+  }
+
+  @Test fun bufferHmacSha256() {
+    assertEquals(HMAC_SHA256_abc, Buffer().writeUtf8("abc").hmacSha256(HMAC_KEY))
+  }
+
+  @Test fun bufferHmacSha512() {
+    assertEquals(HMAC_SHA512_abc, Buffer().writeUtf8("abc").hmacSha512(HMAC_KEY))
+  }
+
+  @Test fun hmacSha256EmptyBuffer() {
+    assertEquals(HMAC_SHA256_empty, Buffer().sha256())
+  }
+
+  @Test fun hmacSha512EmptyBuffer() {
+    assertEquals(HMAC_SHA512_empty, Buffer().sha512())
+  }
+
+  @Test fun bufferHashIsNotDestructive() {
+    val buffer = Buffer()
+
+    buffer.writeUtf8("abc")
+    assertEquals(SHA256_abc, buffer.sha256())
+    assertEquals("abc", buffer.readUtf8())
+
+    buffer.writeUtf8("def")
+    assertEquals(SHA256_def, buffer.sha256())
+    assertEquals("def", buffer.readUtf8())
+
+    buffer.write(r32k)
+    assertEquals(SHA256_r32k, buffer.sha256())
+    assertEquals(r32k, buffer.readByteString())
+  }
+
+  companion object {
+    val HMAC_KEY =
+      "0102030405060708".decodeHex()
+    val MD5_abc =
+      "900150983cd24fb0d6963f7d28e17f72".decodeHex()
+    val SHA1_abc =
+      "a9993e364706816aba3e25717850c26c9cd0d89d".decodeHex()
+    val HMAC_SHA1_abc =
+      "987af8649982ff7d9fbb1b8aa35099146997af51".decodeHex()
+    val SHA256_abc =
+      "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad".decodeHex()
+    val SHA256_empty =
+      "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855".decodeHex()
+    val SHA256_def =
+      "cb8379ac2098aa165029e3938a51da0bcecfc008fd6795f401178647f96c5b34".decodeHex()
+    val SHA256_r32k =
+      "dadec7297f49bdf219895bd9942454047d394e1f20f247fbdc591080b4e8731e".decodeHex()
+    val SHA512_abc =
+      "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f".decodeHex()
+    val SHA512_empty =
+      "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e".decodeHex()
+    val HMAC_SHA256_empty =
+      "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855".decodeHex()
+    val HMAC_SHA256_abc =
+      "446d1715583cf1c30dfffbec0df4ff1f9d39d493211ab4c97ed6f3f0eb579b47".decodeHex()
+    val HMAC_SHA512_empty =
+      "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e".decodeHex()
+    val HMAC_SHA512_abc =
+      "24391790e7131050b05b606f2079a8983313894a1642a5ed97d094e7cabd00cfaa857d92c1f320ca3b6aaabb84c7155d6f1b10940dc133ded1b40baee8900be6".decodeHex()
+    val r32k = randomBytes(32768)
+  }
+}
diff --git a/okio/src/commonTest/kotlin/okio/MockSink.kt b/okio/src/commonTest/kotlin/okio/MockSink.kt
new file mode 100644
index 0000000..7e099f4
--- /dev/null
+++ b/okio/src/commonTest/kotlin/okio/MockSink.kt
@@ -0,0 +1,63 @@
+/*
+ * 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 okio
+
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
+
+/** A scriptable sink. Like Mockito, but worse and requiring less configuration.  */
+class MockSink : Sink {
+  private val log = mutableListOf<String>()
+  private val callThrows = mutableMapOf<Int, IOException>()
+
+  fun assertLog(vararg messages: String) {
+    assertEquals(messages.toList(), log)
+  }
+
+  fun assertLogContains(message: String) {
+    assertTrue(message in log)
+  }
+
+  fun scheduleThrow(call: Int, e: IOException) {
+    callThrows[call] = e
+  }
+
+  private fun throwIfScheduled() {
+    val exception = callThrows[log.size - 1]
+    if (exception != null) throw exception
+  }
+
+  override fun write(source: Buffer, byteCount: Long) {
+    log.add("write($source, $byteCount)")
+    source.skip(byteCount)
+    throwIfScheduled()
+  }
+
+  override fun flush() {
+    log.add("flush()")
+    throwIfScheduled()
+  }
+
+  override fun timeout(): Timeout {
+    log.add("timeout()")
+    return Timeout.NONE
+  }
+
+  override fun close() {
+    log.add("close()")
+    throwIfScheduled()
+  }
+}
diff --git a/okio/src/commonTest/kotlin/okio/UnsafeCursorTest.kt b/okio/src/commonTest/kotlin/okio/UnsafeCursorTest.kt
new file mode 100644
index 0000000..680ebdc
--- /dev/null
+++ b/okio/src/commonTest/kotlin/okio/UnsafeCursorTest.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2020 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 okio
+
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+class UnsafeCursorTest {
+  @Test fun acquireForRead() {
+    val buffer = Buffer()
+    buffer.writeUtf8("xo".repeat(5000))
+
+    val cursor = buffer.readAndWriteUnsafe()
+    try {
+      val copy = Buffer()
+      while (cursor.next() != -1) {
+        copy.write(cursor.data!!, cursor.start, cursor.end - cursor.start)
+      }
+    } finally {
+      cursor.close()
+    }
+
+    assertEquals("xo".repeat(5000), buffer.readUtf8())
+  }
+
+  @Test fun acquireForWrite() {
+    val buffer = Buffer()
+    buffer.writeUtf8("xo".repeat(5000))
+
+    val cursor = buffer.readAndWriteUnsafe()
+    try {
+      while (cursor.next() != -1) {
+        cursor.data!!.fill('z'.toByte(), cursor.start, cursor.end)
+      }
+    } finally {
+      cursor.close()
+    }
+
+    assertEquals("zz".repeat(5000), buffer.readUtf8())
+  }
+
+  @Test fun expand() {
+    val buffer = Buffer()
+
+    val cursor = buffer.readAndWriteUnsafe()
+    try {
+      cursor.expandBuffer(100)
+      cursor.data!!.fill('z'.toByte(), cursor.start, cursor.start + 100)
+      cursor.resizeBuffer(100L)
+    } finally {
+      cursor.close()
+    }
+
+    val expected = "z".repeat(100)
+    val actual = buffer.readUtf8()
+    println(actual)
+    println(expected)
+    assertEquals(expected, actual)
+  }
+
+  @Test fun resizeBuffer() {
+    val buffer = Buffer()
+
+    val cursor = buffer.readAndWriteUnsafe()
+    try {
+      cursor.resizeBuffer(100L)
+      cursor.data!!.fill('z'.toByte(), cursor.start, cursor.end)
+    } finally {
+      cursor.close()
+    }
+
+    assertEquals("z".repeat(100), buffer.readUtf8())
+  }
+}
diff --git a/okio/src/commonTest/kotlin/okio/Utf8KotlinTest.kt b/okio/src/commonTest/kotlin/okio/Utf8KotlinTest.kt
new file mode 100644
index 0000000..1ade417
--- /dev/null
+++ b/okio/src/commonTest/kotlin/okio/Utf8KotlinTest.kt
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+import okio.ByteString.Companion.decodeHex
+import okio.internal.commonAsUtf8ToByteArray
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+
+class Utf8KotlinTest {
+  @Test fun oneByteCharacters() {
+    assertEncoded("00", 0x00) // Smallest 1-byte character.
+    assertEncoded("20", ' '.toInt())
+    assertEncoded("7e", '~'.toInt())
+    assertEncoded("7f", 0x7f) // Largest 1-byte character.
+  }
+
+  @Test fun twoByteCharacters() {
+    assertEncoded("c280", 0x0080) // Smallest 2-byte character.
+    assertEncoded("c3bf", 0x00ff)
+    assertEncoded("c480", 0x0100)
+    assertEncoded("dfbf", 0x07ff) // Largest 2-byte character.
+  }
+
+  @Test fun threeByteCharacters() {
+    assertEncoded("e0a080", 0x0800) // Smallest 3-byte character.
+    assertEncoded("e0bfbf", 0x0fff)
+    assertEncoded("e18080", 0x1000)
+    assertEncoded("e1bfbf", 0x1fff)
+    assertEncoded("ed8080", 0xd000)
+    assertEncoded("ed9fbf", 0xd7ff) // Largest character lower than the min surrogate.
+    assertEncoded("ee8080", 0xe000) // Smallest character greater than the max surrogate.
+    assertEncoded("eebfbf", 0xefff)
+    assertEncoded("ef8080", 0xf000)
+    assertEncoded("efbfbf", 0xffff) // Largest 3-byte character.
+  }
+
+  @Test fun fourByteCharacters() {
+    assertEncoded("f0908080", 0x010000) // Smallest surrogate pair.
+    assertEncoded("f48fbfbf", 0x10ffff) // Largest code point expressible by UTF-16.
+  }
+
+  @Test fun unknownBytes() {
+    assertCodePointDecoded("f8", REPLACEMENT_CODE_POINT) // Too large
+    assertCodePointDecoded("f0f8", REPLACEMENT_CODE_POINT, REPLACEMENT_CODE_POINT)
+    assertCodePointDecoded("ff", REPLACEMENT_CODE_POINT) // Largest
+    assertCodePointDecoded("f0ff", REPLACEMENT_CODE_POINT, REPLACEMENT_CODE_POINT)
+
+    // Lone continuation
+    assertCodePointDecoded("80", REPLACEMENT_CODE_POINT) // Smallest
+    assertCodePointDecoded("bf", REPLACEMENT_CODE_POINT) // Largest
+  }
+
+  @Test fun overlongSequences() {
+    // Overlong representation of the NUL character
+    assertCodePointDecoded("c080", REPLACEMENT_CODE_POINT)
+    assertCodePointDecoded("e08080", REPLACEMENT_CODE_POINT)
+    assertCodePointDecoded("f0808080", REPLACEMENT_CODE_POINT)
+
+    // Maximum overlong sequences
+    assertCodePointDecoded("c1bf", REPLACEMENT_CODE_POINT)
+    assertCodePointDecoded("e09fbf", REPLACEMENT_CODE_POINT)
+    assertCodePointDecoded("f08fbfbf", REPLACEMENT_CODE_POINT)
+  }
+
+  @Test fun danglingHighSurrogate() {
+    assertStringEncoded("3f", "\ud800") // "?"
+    assertCodePointDecoded("eda080", REPLACEMENT_CODE_POINT)
+  }
+
+  @Test fun lowSurrogateWithoutHighSurrogate() {
+    assertStringEncoded("3f", "\udc00") // "?"
+    assertCodePointDecoded("edb080", REPLACEMENT_CODE_POINT)
+  }
+
+  @Test fun highSurrogateFollowedByNonSurrogate() {
+    assertStringEncoded("3fee8080", "\ud800\ue000") // "?\ue000": Following character is too high.
+    assertCodePointDecoded("f090ee8080", REPLACEMENT_CODE_POINT, '\ue000'.toInt())
+
+    assertStringEncoded("3f61", "\ud800\u0061") // "?a": Following character is too low.
+    assertCodePointDecoded("f09061", REPLACEMENT_CODE_POINT, 'a'.toInt())
+  }
+
+  @Test fun doubleLowSurrogate() {
+    assertStringEncoded("3f3f", "\udc00\udc00") // "??"
+    assertCodePointDecoded("edb080edb080", REPLACEMENT_CODE_POINT, REPLACEMENT_CODE_POINT)
+  }
+
+  @Test fun doubleHighSurrogate() {
+    assertStringEncoded("3f3f", "\ud800\ud800") // "??"
+    assertCodePointDecoded("eda080eda080", REPLACEMENT_CODE_POINT, REPLACEMENT_CODE_POINT)
+  }
+
+  @Test fun lowSurrogateHighSurrogate() {
+    assertStringEncoded("3f3f", "\udc00\ud800") // "??"
+    assertCodePointDecoded("edb080eda080", REPLACEMENT_CODE_POINT, REPLACEMENT_CODE_POINT)
+  }
+
+  @Test fun writeSurrogateCodePoint() {
+    assertStringEncoded("ed9fbf", "\ud7ff") // Below lowest surrogate is okay.
+    assertCodePointDecoded("ed9fbf", '\ud7ff'.toInt())
+
+    assertStringEncoded("3f", "\ud800") // Lowest surrogate gets '?'.
+    assertCodePointDecoded("eda080", REPLACEMENT_CODE_POINT)
+
+    assertStringEncoded("3f", "\udfff") // Highest surrogate gets '?'.
+    assertCodePointDecoded("edbfbf", REPLACEMENT_CODE_POINT)
+
+    assertStringEncoded("ee8080", "\ue000") // Above highest surrogate is okay.
+    assertCodePointDecoded("ee8080", '\ue000'.toInt())
+  }
+
+  @Test fun size() {
+    assertEquals(0, "".utf8Size())
+    assertEquals(3, "abc".utf8Size())
+    assertEquals(16, "təˈranəˌsôr".utf8Size())
+  }
+
+  @Test fun sizeWithBounds() {
+    assertEquals(0, "".utf8Size(0, 0))
+    assertEquals(0, "abc".utf8Size(0, 0))
+    assertEquals(1, "abc".utf8Size(1, 2))
+    assertEquals(2, "abc".utf8Size(0, 2))
+    assertEquals(3, "abc".utf8Size(0, 3))
+    assertEquals(16, "təˈranəˌsôr".utf8Size(0, 11))
+    assertEquals(5, "təˈranəˌsôr".utf8Size(3, 7))
+  }
+
+  @Test fun sizeBoundsCheck() {
+    assertFailsWith<IllegalArgumentException> {
+      "abc".utf8Size(-1, 2)
+    }
+
+    assertFailsWith<IllegalArgumentException> {
+      "abc".utf8Size(2, 1)
+    }
+
+    assertFailsWith<IllegalArgumentException> {
+      "abc".utf8Size(1, 4)
+    }
+  }
+
+  private fun assertEncoded(hex: String, vararg codePoints: Int) {
+    assertCodePointDecoded(hex, *codePoints)
+  }
+
+  private fun assertCodePointDecoded(hex: String, vararg codePoints: Int) {
+    val bytes = hex.decodeHex().toByteArray()
+    var i = 0
+    bytes.processUtf8CodePoints(0, bytes.size) { codePoint ->
+      if (i < codePoints.size) assertEquals(codePoints[i], codePoint, "index=$i")
+      i++
+    }
+    assertEquals(i, codePoints.size) // Checked them all
+  }
+
+  private fun assertStringEncoded(hex: String, string: String) {
+    val expectedUtf8 = hex.decodeHex()
+
+    // Confirm our expectations are consistent with the platform.
+    val platformUtf8 = ByteString.of(*string.asUtf8ToByteArray())
+    assertEquals(expectedUtf8, platformUtf8)
+
+    // Confirm our implementations matches those expectations.
+    val actualUtf8 = ByteString.of(*string.commonAsUtf8ToByteArray())
+    assertEquals(expectedUtf8, actualUtf8)
+
+    // TODO Confirm we are consistent when writing one code point at a time.
+
+    // Confirm we are consistent when measuring lengths.
+    assertEquals(expectedUtf8.size.toLong(), string.utf8Size())
+    assertEquals(expectedUtf8.size.toLong(), string.utf8Size(0, string.length))
+  }
+}
diff --git a/okio/src/commonTest/kotlin/okio/util.kt b/okio/src/commonTest/kotlin/okio/util.kt
new file mode 100644
index 0000000..953eef8
--- /dev/null
+++ b/okio/src/commonTest/kotlin/okio/util.kt
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+import kotlin.random.Random
+import kotlin.test.assertEquals
+
+fun Char.repeat(count: Int): String {
+  return toString().repeat(count)
+}
+
+fun segmentSizes(buffer: Buffer): List<Int> {
+  var segment = buffer.head ?: return emptyList()
+
+  val sizes = mutableListOf(segment.limit - segment.pos)
+  segment = segment.next!!
+  while (segment !== buffer.head) {
+    sizes.add(segment.limit - segment.pos)
+    segment = segment.next!!
+  }
+  return sizes
+}
+
+fun assertArrayEquals(a: ByteArray, b: ByteArray) {
+  assertEquals(a.contentToString(), b.contentToString())
+}
+
+fun randomBytes(length: Int): ByteString {
+  val random = Random(0)
+  val randomBytes = ByteArray(length)
+  random.nextBytes(randomBytes)
+  return ByteString.of(*randomBytes)
+}
+
+fun bufferWithRandomSegmentLayout(dice: Random, data: ByteArray): Buffer {
+  val result = Buffer()
+
+  // Writing to result directly will yield packed segments. Instead, write to
+  // other buffers, then write those buffers to result.
+  var pos = 0
+  var byteCount: Int
+  while (pos < data.size) {
+    byteCount = Segment.SIZE / 2 + dice.nextInt(Segment.SIZE / 2)
+    if (byteCount > data.size - pos) byteCount = data.size - pos
+    val offset = dice.nextInt(Segment.SIZE - byteCount)
+
+    val segment = Buffer()
+    segment.write(ByteArray(offset))
+    segment.write(data, pos, byteCount)
+    segment.skip(offset.toLong())
+
+    result.write(segment, byteCount.toLong())
+    pos += byteCount
+  }
+
+  return result
+}
+
+fun bufferWithSegments(vararg segments: String): Buffer {
+  val result = Buffer()
+  for (s in segments) {
+    val offsetInSegment = if (s.length < Segment.SIZE) (Segment.SIZE - s.length) / 2 else 0
+    val buffer = Buffer()
+    buffer.writeUtf8('_'.repeat(offsetInSegment))
+    buffer.writeUtf8(s)
+    buffer.skip(offsetInSegment.toLong())
+    result.write(buffer.copyTo(Buffer()), buffer.size)
+  }
+  return result
+}
+
+fun makeSegments(source: ByteString): ByteString {
+  val buffer = Buffer()
+  for (i in 0 until source.size) {
+    val segment = buffer.writableSegment(Segment.SIZE)
+    segment.data[segment.pos] = source[i]
+    segment.limit++
+    buffer.size++
+  }
+  return buffer.snapshot()
+}
diff --git a/okio/src/hashFunctions/kotlin/okio/internal/HashFunction.kt b/okio/src/hashFunctions/kotlin/okio/internal/HashFunction.kt
new file mode 100644
index 0000000..5948ab0
--- /dev/null
+++ b/okio/src/hashFunctions/kotlin/okio/internal/HashFunction.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2020 Square, Inc. and others.
+ *
+ * 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 okio.internal
+
+/** A cryptographic hash function. */
+internal interface HashFunction {
+  fun update(
+    input: ByteArray,
+    offset: Int = 0,
+    byteCount: Int = input.size
+  )
+
+  fun digest(): ByteArray
+}
diff --git a/okio/src/hashFunctions/kotlin/okio/internal/Hmac.kt b/okio/src/hashFunctions/kotlin/okio/internal/Hmac.kt
new file mode 100644
index 0000000..95e3c5d
--- /dev/null
+++ b/okio/src/hashFunctions/kotlin/okio/internal/Hmac.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2020 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 okio.internal
+
+import okio.ByteString
+import okio.xor
+
+internal class Hmac private constructor(
+  private val hashFunction: HashFunction,
+  private val outerKey: ByteArray
+) : HashFunction {
+  override fun update(input: ByteArray, offset: Int, byteCount: Int) {
+    hashFunction.update(input, offset, byteCount)
+  }
+
+  override fun digest(): ByteArray {
+    val digest = hashFunction.digest()
+
+    hashFunction.update(outerKey)
+    hashFunction.update(digest)
+
+    return hashFunction.digest()
+  }
+
+  companion object {
+    private const val IPAD: Byte = 54
+    private const val OPAD: Byte = 92
+
+    fun sha1(key: ByteString) =
+      create(key, hashFunction = Sha1(), blockLength = 64)
+
+    fun sha256(key: ByteString) =
+      create(key, hashFunction = Sha256(), blockLength = 64)
+
+    fun sha512(key: ByteString) =
+      create(key, hashFunction = Sha512(), blockLength = 128)
+
+    private fun create(
+      key: ByteString,
+      hashFunction: HashFunction,
+      blockLength: Int
+    ): Hmac {
+      val keySize = key.size
+      val paddedKey = when {
+        keySize == 0 -> throw IllegalArgumentException("Empty key")
+        keySize == blockLength -> key.data
+        keySize < blockLength -> key.data.copyOf(blockLength)
+        else -> hashFunction.apply { update(key.data) }.digest().copyOf(blockLength)
+      }
+
+      val innerKey = ByteArray(blockLength) { paddedKey[it] xor IPAD }
+      val outerKey = ByteArray(blockLength) { paddedKey[it] xor OPAD }
+
+      hashFunction.update(innerKey)
+
+      return Hmac(
+        hashFunction,
+        outerKey
+      )
+    }
+  }
+}
diff --git a/okio/src/hashFunctions/kotlin/okio/internal/Md5.kt b/okio/src/hashFunctions/kotlin/okio/internal/Md5.kt
new file mode 100644
index 0000000..e43e447
--- /dev/null
+++ b/okio/src/hashFunctions/kotlin/okio/internal/Md5.kt
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2020 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 okio.internal
+
+import okio.leftRotate
+
+internal class Md5 : HashFunction {
+  private var messageLength = 0L
+  private val unprocessed = ByteArray(64)
+  private var unprocessedLimit = 0
+  private val words = IntArray(16)
+
+  private var h0: Int = 1732584193
+  private var h1: Int = -271733879
+  private var h2: Int = -1732584194
+  private var h3: Int = 271733878
+
+  override fun update(
+    input: ByteArray,
+    offset: Int,
+    byteCount: Int
+  ) {
+    messageLength += byteCount
+    var pos = offset
+    val limit = pos + byteCount
+    val unprocessed = this.unprocessed
+    val unprocessedLimit = this.unprocessedLimit
+
+    if (unprocessedLimit > 0) {
+      if (unprocessedLimit + byteCount < 64) {
+        // Not enough bytes for a chunk.
+        input.copyInto(unprocessed, unprocessedLimit, pos, limit)
+        this.unprocessedLimit = unprocessedLimit + byteCount
+        return
+      }
+
+      // Process a chunk combining leftover bytes and the input.
+      val consumeByteCount = 64 - unprocessedLimit
+      input.copyInto(unprocessed, unprocessedLimit, pos, pos + consumeByteCount)
+      processChunk(unprocessed, 0)
+      this.unprocessedLimit = 0
+      pos += consumeByteCount
+    }
+
+    while (pos < limit) {
+      val nextPos = pos + 64
+
+      if (nextPos > limit) {
+        // Not enough bytes for a chunk.
+        input.copyInto(unprocessed, 0, pos, limit)
+        this.unprocessedLimit = limit - pos
+        return
+      }
+
+      // Process a chunk.
+      processChunk(input, pos)
+      pos = nextPos
+    }
+  }
+
+  private fun processChunk(input: ByteArray, pos: Int) {
+    val words = this.words
+
+    var pos = pos
+    for (w in 0 until 16) {
+      words[w] = ((input[pos++].toInt() and 0xff)) or
+        ((input[pos++].toInt() and 0xff) shl 8) or
+        ((input[pos++].toInt() and 0xff) shl 16) or
+        ((input[pos++].toInt() and 0xff) shl 24)
+    }
+
+    hash(words)
+  }
+
+  private fun hash(words: IntArray) {
+    val localK = k
+    val localS = s
+
+    var a = h0
+    var b = h1
+    var c = h2
+    var d = h3
+
+    for (i in 0 until 16) {
+      val g = i
+      val f = ((b and c) or (b.inv() and d)) + a + localK[i] + words[g]
+      a = d
+      d = c
+      c = b
+      b += f leftRotate localS[i]
+    }
+
+    for (i in 16 until 32) {
+      val g = ((5 * i) + 1) % 16
+      val f = ((d and b) or (d.inv() and c)) + a + localK[i] + words[g]
+      a = d
+      d = c
+      c = b
+      b += f leftRotate localS[i]
+    }
+
+    for (i in 32 until 48) {
+      val g = ((3 * i) + 5) % 16
+      val f = (b xor c xor d) + a + localK[i] + words[g]
+      a = d
+      d = c
+      c = b
+      b += f leftRotate localS[i]
+    }
+
+    for (i in 48 until 64) {
+      val g = (7 * i) % 16
+      val f = (c xor (b or d.inv())) + a + localK[i] + words[g]
+      a = d
+      d = c
+      c = b
+      b += f leftRotate localS[i]
+    }
+
+    h0 += a
+    h1 += b
+    h2 += c
+    h3 += d
+  }
+
+  /* ktlint-disable */
+  override fun digest(): ByteArray {
+    val messageLengthBits = messageLength * 8
+
+    unprocessed[unprocessedLimit++] = 0x80.toByte()
+    if (unprocessedLimit > 56) {
+      unprocessed.fill(0, unprocessedLimit, 64)
+      processChunk(unprocessed, 0)
+      unprocessed.fill(0, 0, unprocessedLimit)
+    } else {
+      unprocessed.fill(0, unprocessedLimit, 56)
+    }
+    unprocessed[56] = (messageLengthBits        ).toByte()
+    unprocessed[57] = (messageLengthBits ushr  8).toByte()
+    unprocessed[58] = (messageLengthBits ushr 16).toByte()
+    unprocessed[59] = (messageLengthBits ushr 24).toByte()
+    unprocessed[60] = (messageLengthBits ushr 32).toByte()
+    unprocessed[61] = (messageLengthBits ushr 40).toByte()
+    unprocessed[62] = (messageLengthBits ushr 48).toByte()
+    unprocessed[63] = (messageLengthBits ushr 56).toByte()
+    processChunk(unprocessed, 0)
+
+    val a = h0
+    val b = h1
+    val c = h2
+    val d = h3
+
+    return byteArrayOf(
+      (a       ).toByte(),
+      (a shr  8).toByte(),
+      (a shr 16).toByte(),
+      (a shr 24).toByte(),
+      (b       ).toByte(),
+      (b shr  8).toByte(),
+      (b shr 16).toByte(),
+      (b shr 24).toByte(),
+      (c       ).toByte(),
+      (c shr  8).toByte(),
+      (c shr 16).toByte(),
+      (c shr 24).toByte(),
+      (d       ).toByte(),
+      (d shr  8).toByte(),
+      (d shr 16).toByte(),
+      (d shr 24).toByte()
+    )
+  }
+  /* ktlint-enable */
+
+  companion object {
+    private val s = intArrayOf(
+      7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9,
+      14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15,
+      21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
+    )
+
+    private val k = intArrayOf(
+      -680876936, -389564586, 606105819, -1044525330, -176418897, 1200080426, -1473231341,
+      -45705983, 1770035416, -1958414417, -42063, -1990404162, 1804603682, -40341101, -1502002290,
+      1236535329, -165796510, -1069501632, 643717713, -373897302, -701558691, 38016083, -660478335,
+      -405537848, 568446438, -1019803690, -187363961, 1163531501, -1444681467, -51403784,
+      1735328473, -1926607734, -378558, -2022574463, 1839030562, -35309556, -1530992060, 1272893353,
+      -155497632, -1094730640, 681279174, -358537222, -722521979, 76029189, -640364487, -421815835,
+      530742520, -995338651, -198630844, 1126891415, -1416354905, -57434055, 1700485571,
+      -1894986606, -1051523, -2054922799, 1873313359, -30611744, -1560198380, 1309151649,
+      -145523070, -1120210379, 718787259, -343485551
+    )
+  }
+}
diff --git a/okio/src/hashFunctions/kotlin/okio/internal/Sha1.kt b/okio/src/hashFunctions/kotlin/okio/internal/Sha1.kt
new file mode 100644
index 0000000..e9a8de1
--- /dev/null
+++ b/okio/src/hashFunctions/kotlin/okio/internal/Sha1.kt
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2020 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 okio.internal
+
+import okio.leftRotate
+
+internal class Sha1 : HashFunction {
+  private var messageLength = 0L
+  private val unprocessed = ByteArray(64)
+  private var unprocessedLimit = 0
+  private val words = IntArray(80)
+
+  private var h0 = 1732584193
+  private var h1 = -271733879
+  private var h2 = -1732584194
+  private var h3 = 271733878
+  private var h4 = -1009589776
+
+  override fun update(
+    input: ByteArray,
+    offset: Int,
+    byteCount: Int
+  ) {
+    messageLength += byteCount
+    var pos = offset
+    val limit = pos + byteCount
+    val unprocessed = this.unprocessed
+    val unprocessedLimit = this.unprocessedLimit
+
+    if (unprocessedLimit > 0) {
+      if (unprocessedLimit + byteCount < 64) {
+        // Not enough bytes for a chunk.
+        input.copyInto(unprocessed, unprocessedLimit, pos, limit)
+        this.unprocessedLimit = unprocessedLimit + byteCount
+        return
+      }
+
+      // Process a chunk combining leftover bytes and the input.
+      val consumeByteCount = 64 - unprocessedLimit
+      input.copyInto(unprocessed, unprocessedLimit, pos, pos + consumeByteCount)
+      processChunk(unprocessed, 0)
+      this.unprocessedLimit = 0
+      pos += consumeByteCount
+    }
+
+    while (pos < limit) {
+      val nextPos = pos + 64
+
+      if (nextPos > limit) {
+        // Not enough bytes for a chunk.
+        input.copyInto(unprocessed, 0, pos, limit)
+        this.unprocessedLimit = limit - pos
+        return
+      }
+
+      // Process a chunk.
+      processChunk(input, pos)
+      pos = nextPos
+    }
+  }
+
+  private fun processChunk(input: ByteArray, pos: Int) {
+    val words = this.words
+
+    var pos = pos
+    for (w in 0 until 16) {
+      words[w] =
+        ((input[pos++].toInt() and 0xff) shl 24) or
+        ((input[pos++].toInt() and 0xff) shl 16) or
+        ((input[pos++].toInt() and 0xff) shl 8) or
+        ((input[pos++].toInt() and 0xff))
+    }
+
+    for (w in 16 until 80) {
+      words[w] = (words[w - 3] xor words[w - 8] xor words[w - 14] xor words[w - 16]) leftRotate 1
+    }
+
+    var a = h0
+    var b = h1
+    var c = h2
+    var d = h3
+    var e = h4
+
+    for (i in 0 until 80) {
+      val a2 = when {
+        i < 20 -> {
+          val f = d xor (b and (c xor d))
+          val k = 1518500249
+          (a leftRotate 5) + f + e + k + words[i]
+        }
+        i < 40 -> {
+          val f = b xor c xor d
+          val k = 1859775393
+          (a leftRotate 5) + f + e + k + words[i]
+        }
+        i < 60 -> {
+          val f = (b and c) or (b and d) or (c and d)
+          val k = -1894007588
+          (a leftRotate 5) + f + e + k + words[i]
+        }
+        else -> {
+          val f = b xor c xor d
+          val k = -899497514
+          (a leftRotate 5) + f + e + k + words[i]
+        }
+      }
+
+      e = d
+      d = c
+      c = b leftRotate 30
+      b = a
+      a = a2
+    }
+
+    h0 += a
+    h1 += b
+    h2 += c
+    h3 += d
+    h4 += e
+  }
+
+  /* ktlint-disable */
+  override fun digest(): ByteArray {
+    val unprocessed = this.unprocessed
+    var unprocessedLimit = this.unprocessedLimit
+    val messageLengthBits = messageLength * 8
+
+    unprocessed[unprocessedLimit++] = 0x80.toByte()
+    if (unprocessedLimit > 56) {
+      unprocessed.fill(0, unprocessedLimit, 64)
+      processChunk(unprocessed, 0)
+      unprocessed.fill(0, 0, unprocessedLimit)
+    } else {
+      unprocessed.fill(0, unprocessedLimit, 56)
+    }
+    unprocessed[56] = (messageLengthBits ushr 56).toByte()
+    unprocessed[57] = (messageLengthBits ushr 48).toByte()
+    unprocessed[58] = (messageLengthBits ushr 40).toByte()
+    unprocessed[59] = (messageLengthBits ushr 32).toByte()
+    unprocessed[60] = (messageLengthBits ushr 24).toByte()
+    unprocessed[61] = (messageLengthBits ushr 16).toByte()
+    unprocessed[62] = (messageLengthBits ushr  8).toByte()
+    unprocessed[63] = (messageLengthBits        ).toByte()
+    processChunk(unprocessed, 0)
+
+    val a = h0
+    val b = h1
+    val c = h2
+    val d = h3
+    val e = h4
+
+    reset()
+
+    return byteArrayOf(
+      (a shr 24).toByte(),
+      (a shr 16).toByte(),
+      (a shr  8).toByte(),
+      (a       ).toByte(),
+      (b shr 24).toByte(),
+      (b shr 16).toByte(),
+      (b shr  8).toByte(),
+      (b       ).toByte(),
+      (c shr 24).toByte(),
+      (c shr 16).toByte(),
+      (c shr  8).toByte(),
+      (c       ).toByte(),
+      (d shr 24).toByte(),
+      (d shr 16).toByte(),
+      (d shr  8).toByte(),
+      (d       ).toByte(),
+      (e shr 24).toByte(),
+      (e shr 16).toByte(),
+      (e shr  8).toByte(),
+      (e       ).toByte()
+    )
+  }
+  /* ktlint-enable */
+
+  private fun reset() {
+    messageLength = 0L
+    unprocessed.fill(0)
+    unprocessedLimit = 0
+    words.fill(0)
+
+    h0 = 1732584193
+    h1 = -271733879
+    h2 = -1732584194
+    h3 = 271733878
+    h4 = -1009589776
+  }
+}
diff --git a/okio/src/hashFunctions/kotlin/okio/internal/Sha256.kt b/okio/src/hashFunctions/kotlin/okio/internal/Sha256.kt
new file mode 100644
index 0000000..aa0d24d
--- /dev/null
+++ b/okio/src/hashFunctions/kotlin/okio/internal/Sha256.kt
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2020 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 okio.internal
+
+import okio.and
+
+internal class Sha256 : HashFunction {
+  private var messageLength = 0L
+  private val unprocessed = ByteArray(64)
+  private var unprocessedLimit = 0
+  private val words = IntArray(64)
+
+  private var h0 = 1779033703
+  private var h1 = -1150833019
+  private var h2 = 1013904242
+  private var h3 = -1521486534
+  private var h4 = 1359893119
+  private var h5 = -1694144372
+  private var h6 = 528734635
+  private var h7 = 1541459225
+
+  override fun update(
+    input: ByteArray,
+    offset: Int,
+    byteCount: Int
+  ) {
+    messageLength += byteCount
+    var pos = offset
+    val limit = pos + byteCount
+    val unprocessed = this.unprocessed
+    val unprocessedLimit = this.unprocessedLimit
+
+    if (unprocessedLimit > 0) {
+      if (unprocessedLimit + byteCount < 64) {
+        // Not enough bytes for a chunk.
+        input.copyInto(unprocessed, unprocessedLimit, pos, limit)
+        this.unprocessedLimit = unprocessedLimit + byteCount
+        return
+      }
+
+      // Process a chunk combining leftover bytes and the input.
+      val consumeByteCount = 64 - unprocessedLimit
+      input.copyInto(unprocessed, unprocessedLimit, pos, pos + consumeByteCount)
+      processChunk(unprocessed, 0)
+      this.unprocessedLimit = 0
+      pos += consumeByteCount
+    }
+
+    while (pos < limit) {
+      val nextPos = pos + 64
+
+      if (nextPos > limit) {
+        // Not enough bytes for a chunk.
+        input.copyInto(unprocessed, 0, pos, limit)
+        this.unprocessedLimit = limit - pos
+        return
+      }
+
+      // Process a chunk.
+      processChunk(input, pos)
+      pos = nextPos
+    }
+  }
+
+  private fun processChunk(input: ByteArray, pos: Int) {
+    val words = this.words
+
+    var pos = pos
+    for (w in 0 until 16) {
+      words[w] = ((input[pos++] and 0xff) shl 24) or
+        ((input[pos++] and 0xff) shl 16) or
+        ((input[pos++] and 0xff) shl 8) or
+        ((input[pos++] and 0xff))
+    }
+
+    for (w in 16 until 64) {
+      val w15 = words[w - 15]
+      val s0 = ((w15 ushr 7) or (w15 shl 25)) xor ((w15 ushr 18) or (w15 shl 14)) xor (w15 ushr 3)
+      val w2 = words[w - 2]
+      val s1 = ((w2 ushr 17) or (w2 shl 15)) xor ((w2 ushr 19) or (w2 shl 13)) xor (w2 ushr 10)
+      val w16 = words[w - 16]
+      val w7 = words[w - 7]
+      words[w] = w16 + s0 + w7 + s1
+    }
+
+    hash(words)
+  }
+
+  private fun hash(
+    words: IntArray
+  ) {
+    val localK = k
+    var a = h0
+    var b = h1
+    var c = h2
+    var d = h3
+    var e = h4
+    var f = h5
+    var g = h6
+    var h = h7
+
+    for (i in 0 until 64) {
+      val s0 = ((a ushr 2) or (a shl 30)) xor
+        ((a ushr 13) or (a shl 19)) xor
+        ((a ushr 22) or (a shl 10))
+      val s1 = ((e ushr 6) or (e shl 26)) xor
+        ((e ushr 11) or (e shl 21)) xor
+        ((e ushr 25) or (e shl 7))
+
+      val ch = (e and f) xor
+        (e.inv() and g)
+      val maj = (a and b) xor
+        (a and c) xor
+        (b and c)
+
+      val t1 = h + s1 + ch + localK[i] + words[i]
+      val t2 = s0 + maj
+
+      h = g
+      g = f
+      f = e
+      e = d + t1
+      d = c
+      c = b
+      b = a
+      a = t1 + t2
+    }
+
+    h0 += a
+    h1 += b
+    h2 += c
+    h3 += d
+    h4 += e
+    h5 += f
+    h6 += g
+    h7 += h
+  }
+
+  /* ktlint-disable */
+  override fun digest(): ByteArray {
+    val unprocessed = this.unprocessed
+    var unprocessedLimit = this.unprocessedLimit
+    val messageLengthBits = messageLength * 8
+
+    unprocessed[unprocessedLimit++] = 0x80.toByte()
+    if (unprocessedLimit > 56) {
+      unprocessed.fill(0, unprocessedLimit, 64)
+      processChunk(unprocessed, 0)
+      unprocessed.fill(0, 0, unprocessedLimit)
+    } else {
+      unprocessed.fill(0, unprocessedLimit, 56)
+    }
+    unprocessed[56] = (messageLengthBits ushr 56).toByte()
+    unprocessed[57] = (messageLengthBits ushr 48).toByte()
+    unprocessed[58] = (messageLengthBits ushr 40).toByte()
+    unprocessed[59] = (messageLengthBits ushr 32).toByte()
+    unprocessed[60] = (messageLengthBits ushr 24).toByte()
+    unprocessed[61] = (messageLengthBits ushr 16).toByte()
+    unprocessed[62] = (messageLengthBits ushr  8).toByte()
+    unprocessed[63] = (messageLengthBits        ).toByte()
+    processChunk(unprocessed, 0)
+
+    val a = h0
+    val b = h1
+    val c = h2
+    val d = h3
+    val e = h4
+    val f = h5
+    val g = h6
+    val h = h7
+
+    reset()
+
+    return byteArrayOf(
+      (a shr 24).toByte(),
+      (a shr 16).toByte(),
+      (a shr  8).toByte(),
+      (a       ).toByte(),
+      (b shr 24).toByte(),
+      (b shr 16).toByte(),
+      (b shr  8).toByte(),
+      (b       ).toByte(),
+      (c shr 24).toByte(),
+      (c shr 16).toByte(),
+      (c shr  8).toByte(),
+      (c       ).toByte(),
+      (d shr 24).toByte(),
+      (d shr 16).toByte(),
+      (d shr  8).toByte(),
+      (d       ).toByte(),
+      (e shr 24).toByte(),
+      (e shr 16).toByte(),
+      (e shr  8).toByte(),
+      (e       ).toByte(),
+      (f shr 24).toByte(),
+      (f shr 16).toByte(),
+      (f shr  8).toByte(),
+      (f       ).toByte(),
+      (g shr 24).toByte(),
+      (g shr 16).toByte(),
+      (g shr  8).toByte(),
+      (g       ).toByte(),
+      (h shr 24).toByte(),
+      (h shr 16).toByte(),
+      (h shr  8).toByte(),
+      (h       ).toByte()
+    )
+  }
+  /* ktlint-enable */
+
+  private fun reset() {
+    messageLength = 0L
+    unprocessed.fill(0)
+    unprocessedLimit = 0
+    words.fill(0)
+
+    h0 = 1779033703
+    h1 = -1150833019
+    h2 = 1013904242
+    h3 = -1521486534
+    h4 = 1359893119
+    h5 = -1694144372
+    h6 = 528734635
+    h7 = 1541459225
+  }
+
+  companion object {
+    private val k = intArrayOf(
+      1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993, -1841331548,
+      -1424204075, -670586216, 310598401, 607225278, 1426881987, 1925078388, -2132889090,
+      -1680079193, -1046744716, -459576895, -272742522, 264347078, 604807628, 770255983, 1249150122,
+      1555081692, 1996064986, -1740746414, -1473132947, -1341970488, -1084653625, -958395405,
+      -710438585, 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, 1695183700,
+      1986661051, -2117940946, -1838011259, -1564481375, -1474664885, -1035236496, -949202525,
+      -778901479, -694614492, -200395387, 275423344, 430227734, 506948616, 659060556, 883997877,
+      958139571, 1322822218, 1537002063, 1747873779, 1955562222, 2024104815, -2067236844,
+      -1933114872, -1866530822, -1538233109, -1090935817, -965641998
+    )
+  }
+}
diff --git a/okio/src/hashFunctions/kotlin/okio/internal/Sha512.kt b/okio/src/hashFunctions/kotlin/okio/internal/Sha512.kt
new file mode 100644
index 0000000..390a50a
--- /dev/null
+++ b/okio/src/hashFunctions/kotlin/okio/internal/Sha512.kt
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2020 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 okio.internal
+
+import okio.rightRotate
+
+internal class Sha512 : HashFunction {
+  private var messageLength = 0L
+  private val unprocessed = ByteArray(128)
+  private var unprocessedLimit = 0
+  private val words = LongArray(80)
+
+  private var h0 = 7640891576956012808L
+  private var h1 = -4942790177534073029L
+  private var h2 = 4354685564936845355L
+  private var h3 = -6534734903238641935L
+  private var h4 = 5840696475078001361L
+  private var h5 = -7276294671716946913L
+  private var h6 = 2270897969802886507L
+  private var h7 = 6620516959819538809L
+
+  override fun update(
+    input: ByteArray,
+    offset: Int,
+    byteCount: Int
+  ) {
+    messageLength += byteCount
+    var pos = offset
+    val limit = pos + byteCount
+    val unprocessed = this.unprocessed
+    val unprocessedLimit = this.unprocessedLimit
+
+    if (unprocessedLimit > 0) {
+      if (unprocessedLimit + byteCount < 128) {
+        // Not enough bytes for a chunk.
+        input.copyInto(unprocessed, unprocessedLimit, pos, limit)
+        this.unprocessedLimit = unprocessedLimit + byteCount
+        return
+      }
+
+      // Process a chunk combining leftover bytes and the input.
+      val consumeByteCount = 128 - unprocessedLimit
+      input.copyInto(unprocessed, unprocessedLimit, pos, pos + consumeByteCount)
+      processChunk(unprocessed, 0)
+      this.unprocessedLimit = 0
+      pos += consumeByteCount
+    }
+
+    while (pos < limit) {
+      val nextPos = pos + 128
+
+      if (nextPos > limit) {
+        // Not enough bytes for a chunk.
+        input.copyInto(unprocessed, 0, pos, limit)
+        this.unprocessedLimit = limit - pos
+        return
+      }
+
+      // Process a chunk.
+      processChunk(input, pos)
+      pos = nextPos
+    }
+  }
+
+  private fun processChunk(input: ByteArray, pos: Int) {
+    val words = this.words
+
+    var pos = pos
+    for (w in 0 until 16) {
+      words[w] = ((input[pos++].toLong() and 0xff) shl 56) or
+        ((input[pos++].toLong() and 0xff) shl 48) or
+        ((input[pos++].toLong() and 0xff) shl 40) or
+        ((input[pos++].toLong() and 0xff) shl 32) or
+        ((input[pos++].toLong() and 0xff) shl 24) or
+        ((input[pos++].toLong() and 0xff) shl 16) or
+        ((input[pos++].toLong() and 0xff) shl 8) or
+        ((input[pos++].toLong() and 0xff))
+    }
+
+    for (i in 16 until 80) {
+      val w15 = words[i - 15]
+      val s0 = (w15 rightRotate 1) xor (w15 rightRotate 8) xor (w15 ushr 7)
+      val w2 = words[i - 2]
+      val s1 = (w2 rightRotate 19) xor (w2 rightRotate 61) xor (w2 ushr 6)
+      val w16 = words[i - 16]
+      val w7 = words[i - 7]
+      words[i] = w16 + s0 + w7 + s1
+    }
+
+    hash(words)
+  }
+
+  private fun hash(words: LongArray) {
+    val localK = k
+    var a = h0
+    var b = h1
+    var c = h2
+    var d = h3
+    var e = h4
+    var f = h5
+    var g = h6
+    var h = h7
+
+    for (i in 0 until 80) {
+      val s0 = (a rightRotate 28) xor (a rightRotate 34) xor (a rightRotate 39)
+      val s1 = (e rightRotate 14) xor (e rightRotate 18) xor (e rightRotate 41)
+
+      val ch = (e and f) xor (e.inv() and g)
+      val maj = (a and b) xor (a and c) xor (b and c)
+
+      val t1 = h + s1 + ch + localK[i] + words[i]
+      val t2 = s0 + maj
+
+      h = g
+      g = f
+      f = e
+      e = d + t1
+      d = c
+      c = b
+      b = a
+      a = t1 + t2
+    }
+
+    h0 += a
+    h1 += b
+    h2 += c
+    h3 += d
+    h4 += e
+    h5 += f
+    h6 += g
+    h7 += h
+  }
+
+  /* ktlint-disable */
+  override fun digest(): ByteArray {
+    val unprocessed = this.unprocessed
+    var unprocessedLimit = this.unprocessedLimit
+    val messageLengthBits = messageLength * 8
+
+    unprocessed[unprocessedLimit++] = 0x80.toByte()
+    if (unprocessedLimit > 112) {
+      unprocessed.fill(0, unprocessedLimit, 128)
+      processChunk(unprocessed, 0)
+      unprocessed.fill(0, 0, unprocessedLimit)
+    } else {
+      unprocessed.fill(0, unprocessedLimit, 120)
+    }
+    unprocessed[120] = (messageLengthBits ushr 56).toByte()
+    unprocessed[121] = (messageLengthBits ushr 48).toByte()
+    unprocessed[122] = (messageLengthBits ushr 40).toByte()
+    unprocessed[123] = (messageLengthBits ushr 32).toByte()
+    unprocessed[124] = (messageLengthBits ushr 24).toByte()
+    unprocessed[125] = (messageLengthBits ushr 16).toByte()
+    unprocessed[126] = (messageLengthBits ushr  8).toByte()
+    unprocessed[127] = (messageLengthBits        ).toByte()
+    processChunk(unprocessed, 0)
+
+    val a = h0
+    val b = h1
+    val c = h2
+    val d = h3
+    val e = h4
+    val f = h5
+    val g = h6
+    val h = h7
+
+    reset()
+
+    return byteArrayOf(
+      (a shr 56).toByte(),
+      (a shr 48).toByte(),
+      (a shr 40).toByte(),
+      (a shr 32).toByte(),
+      (a shr 24).toByte(),
+      (a shr 16).toByte(),
+      (a shr  8).toByte(),
+      (a       ).toByte(),
+      (b shr 56).toByte(),
+      (b shr 48).toByte(),
+      (b shr 40).toByte(),
+      (b shr 32).toByte(),
+      (b shr 24).toByte(),
+      (b shr 16).toByte(),
+      (b shr  8).toByte(),
+      (b       ).toByte(),
+      (c shr 56).toByte(),
+      (c shr 48).toByte(),
+      (c shr 40).toByte(),
+      (c shr 32).toByte(),
+      (c shr 24).toByte(),
+      (c shr 16).toByte(),
+      (c shr  8).toByte(),
+      (c       ).toByte(),
+      (d shr 56).toByte(),
+      (d shr 48).toByte(),
+      (d shr 40).toByte(),
+      (d shr 32).toByte(),
+      (d shr 24).toByte(),
+      (d shr 16).toByte(),
+      (d shr  8).toByte(),
+      (d       ).toByte(),
+      (e shr 56).toByte(),
+      (e shr 48).toByte(),
+      (e shr 40).toByte(),
+      (e shr 32).toByte(),
+      (e shr 24).toByte(),
+      (e shr 16).toByte(),
+      (e shr  8).toByte(),
+      (e       ).toByte(),
+      (f shr 56).toByte(),
+      (f shr 48).toByte(),
+      (f shr 40).toByte(),
+      (f shr 32).toByte(),
+      (f shr 24).toByte(),
+      (f shr 16).toByte(),
+      (f shr  8).toByte(),
+      (f       ).toByte(),
+      (g shr 56).toByte(),
+      (g shr 48).toByte(),
+      (g shr 40).toByte(),
+      (g shr 32).toByte(),
+      (g shr 24).toByte(),
+      (g shr 16).toByte(),
+      (g shr  8).toByte(),
+      (g       ).toByte(),
+      (h shr 56).toByte(),
+      (h shr 48).toByte(),
+      (h shr 40).toByte(),
+      (h shr 32).toByte(),
+      (h shr 24).toByte(),
+      (h shr 16).toByte(),
+      (h shr  8).toByte(),
+      (h       ).toByte()
+    )
+  }
+  /* ktlint-enable */
+
+  private fun reset() {
+    messageLength = 0L
+    unprocessed.fill(0)
+    unprocessedLimit = 0
+    words.fill(0)
+
+    h0 = 7640891576956012808L
+    h1 = -4942790177534073029L
+    h2 = 4354685564936845355L
+    h3 = -6534734903238641935L
+    h4 = 5840696475078001361L
+    h5 = -7276294671716946913L
+    h6 = 2270897969802886507L
+    h7 = 6620516959819538809L
+  }
+
+  companion object {
+    private val k = longArrayOf(
+      4794697086780616226L, 8158064640168781261L, -5349999486874862801L, -1606136188198331460L,
+      4131703408338449720L, 6480981068601479193L, -7908458776815382629L, -6116909921290321640L,
+      -2880145864133508542L, 1334009975649890238L, 2608012711638119052L, 6128411473006802146L,
+      8268148722764581231L, -9160688886553864527L, -7215885187991268811L, -4495734319001033068L,
+      -1973867731355612462L, -1171420211273849373L, 1135362057144423861L, 2597628984639134821L,
+      3308224258029322869L, 5365058923640841347L, 6679025012923562964L, 8573033837759648693L,
+      -7476448914759557205L, -6327057829258317296L, -5763719355590565569L, -4658551843659510044L,
+      -4116276920077217854L, -3051310485924567259L, 489312712824947311L, 1452737877330783856L,
+      2861767655752347644L, 3322285676063803686L, 5560940570517711597L, 5996557281743188959L,
+      7280758554555802590L, 8532644243296465576L, -9096487096722542874L, -7894198246740708037L,
+      -6719396339535248540L, -6333637450476146687L, -4446306890439682159L, -4076793802049405392L,
+      -3345356375505022440L, -2983346525034927856L, -860691631967231958L, 1182934255886127544L,
+      1847814050463011016L, 2177327727835720531L, 2830643537854262169L, 3796741975233480872L,
+      4115178125766777443L, 5681478168544905931L, 6601373596472566643L, 7507060721942968483L,
+      8399075790359081724L, 8693463985226723168L, -8878714635349349518L, -8302665154208450068L,
+      -8016688836872298968L, -6606660893046293015L, -4685533653050689259L, -4147400797238176981L,
+      -3880063495543823972L, -3348786107499101689L, -1523767162380948706L, -757361751448694408L,
+      500013540394364858L, 748580250866718886L, 1242879168328830382L, 1977374033974150939L,
+      2944078676154940804L, 3659926193048069267L, 4368137639120453308L, 4836135668995329356L,
+      5532061633213252278L, 6448918945643986474L, 6902733635092675308L, 7801388544844847127L
+    )
+  }
+}
diff --git a/okio/src/jvmMain/kotlin/okio/-DeprecatedOkio.kt b/okio/src/jvmMain/kotlin/okio/-DeprecatedOkio.kt
new file mode 100644
index 0000000..7b6835e
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/-DeprecatedOkio.kt
@@ -0,0 +1,147 @@
+// ktlint-disable filename
+/*
+ * Copyright (C) 2018 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 okio
+
+import java.io.File
+import java.io.InputStream
+import java.io.OutputStream
+import java.net.Socket
+import java.nio.file.OpenOption
+import java.nio.file.Path
+
+@Deprecated(message = "changed in Okio 2.x")
+object `-DeprecatedOkio` {
+  @Deprecated(
+    message = "moved to extension function",
+    replaceWith = ReplaceWith(
+      expression = "file.appendingSink()",
+      imports = ["okio.appendingSink"]
+    ),
+    level = DeprecationLevel.ERROR
+  )
+  fun appendingSink(file: File) = file.appendingSink()
+
+  @Deprecated(
+    message = "moved to extension function",
+    replaceWith = ReplaceWith(
+      expression = "sink.buffer()",
+      imports = ["okio.buffer"]
+    ),
+    level = DeprecationLevel.ERROR
+  )
+  fun buffer(sink: Sink) = sink.buffer()
+
+  @Deprecated(
+    message = "moved to extension function",
+    replaceWith = ReplaceWith(
+      expression = "source.buffer()",
+      imports = ["okio.buffer"]
+    ),
+    level = DeprecationLevel.ERROR
+  )
+  fun buffer(source: Source) = source.buffer()
+
+  @Deprecated(
+    message = "moved to extension function",
+    replaceWith = ReplaceWith(
+      expression = "file.sink()",
+      imports = ["okio.sink"]
+    ),
+    level = DeprecationLevel.ERROR
+  )
+  fun sink(file: File) = file.sink()
+
+  @Deprecated(
+    message = "moved to extension function",
+    replaceWith = ReplaceWith(
+      expression = "outputStream.sink()",
+      imports = ["okio.sink"]
+    ),
+    level = DeprecationLevel.ERROR
+  )
+  fun sink(outputStream: OutputStream) = outputStream.sink()
+
+  @Deprecated(
+    message = "moved to extension function",
+    replaceWith = ReplaceWith(
+      expression = "path.sink(*options)",
+      imports = ["okio.sink"]
+    ),
+    level = DeprecationLevel.ERROR
+  )
+  fun sink(path: Path, vararg options: OpenOption) = path.sink(*options)
+
+  @Deprecated(
+    message = "moved to extension function",
+    replaceWith = ReplaceWith(
+      expression = "socket.sink()",
+      imports = ["okio.sink"]
+    ),
+    level = DeprecationLevel.ERROR
+  )
+  fun sink(socket: Socket) = socket.sink()
+
+  @Deprecated(
+    message = "moved to extension function",
+    replaceWith = ReplaceWith(
+      expression = "file.source()",
+      imports = ["okio.source"]
+    ),
+    level = DeprecationLevel.ERROR
+  )
+  fun source(file: File) = file.source()
+
+  @Deprecated(
+    message = "moved to extension function",
+    replaceWith = ReplaceWith(
+      expression = "inputStream.source()",
+      imports = ["okio.source"]
+    ),
+    level = DeprecationLevel.ERROR
+  )
+  fun source(inputStream: InputStream) = inputStream.source()
+
+  @Deprecated(
+    message = "moved to extension function",
+    replaceWith = ReplaceWith(
+      expression = "path.source(*options)",
+      imports = ["okio.source"]
+    ),
+    level = DeprecationLevel.ERROR
+  )
+  fun source(path: Path, vararg options: OpenOption) = path.source(*options)
+
+  @Deprecated(
+    message = "moved to extension function",
+    replaceWith = ReplaceWith(
+      expression = "socket.source()",
+      imports = ["okio.source"]
+    ),
+    level = DeprecationLevel.ERROR
+  )
+  fun source(socket: Socket) = socket.source()
+
+  @Deprecated(
+    message = "moved to extension function",
+    replaceWith = ReplaceWith(
+      expression = "blackholeSink()",
+      imports = ["okio.blackholeSink"]
+    ),
+    level = DeprecationLevel.ERROR
+  )
+  fun blackhole() = blackholeSink()
+}
diff --git a/okio/src/jvmMain/kotlin/okio/-DeprecatedUpgrade.kt b/okio/src/jvmMain/kotlin/okio/-DeprecatedUpgrade.kt
new file mode 100644
index 0000000..5f95547
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/-DeprecatedUpgrade.kt
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+@file:JvmName("-DeprecatedUpgrade")
+package okio
+
+val Okio = `-DeprecatedOkio`
+val Utf8 = `-DeprecatedUtf8`
diff --git a/okio/src/jvmMain/kotlin/okio/-DeprecatedUtf8.kt b/okio/src/jvmMain/kotlin/okio/-DeprecatedUtf8.kt
new file mode 100644
index 0000000..b4bc757
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/-DeprecatedUtf8.kt
@@ -0,0 +1,40 @@
+// ktlint-disable filename
+/*
+ * Copyright (C) 2018 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 okio
+
+@Deprecated(message = "changed in Okio 2.x")
+object `-DeprecatedUtf8` {
+  @Deprecated(
+    message = "moved to extension function",
+    replaceWith = ReplaceWith(
+      expression = "string.utf8Size()",
+      imports = ["okio.utf8Size"]
+    ),
+    level = DeprecationLevel.ERROR
+  )
+  fun size(string: String) = string.utf8Size()
+
+  @Deprecated(
+    message = "moved to extension function",
+    replaceWith = ReplaceWith(
+      expression = "string.utf8Size(beginIndex, endIndex)",
+      imports = ["okio.utf8Size"]
+    ),
+    level = DeprecationLevel.ERROR
+  )
+  fun size(string: String, beginIndex: Int, endIndex: Int) = string.utf8Size(beginIndex, endIndex)
+}
diff --git a/okio/src/jvmMain/kotlin/okio/-Platform.kt b/okio/src/jvmMain/kotlin/okio/-Platform.kt
new file mode 100644
index 0000000..4edb3ce
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/-Platform.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+@file:JvmName("-Platform")
+package okio
+
+internal actual fun ByteArray.toUtf8String(): String = String(this, Charsets.UTF_8)
+
+internal actual fun String.asUtf8ToByteArray(): ByteArray = toByteArray(Charsets.UTF_8)
+
+// TODO remove if https://youtrack.jetbrains.com/issue/KT-20641 provides a better solution
+actual typealias ArrayIndexOutOfBoundsException = java.lang.ArrayIndexOutOfBoundsException
+
+internal actual inline fun <R> synchronized(lock: Any, block: () -> R): R {
+  return kotlin.synchronized(lock, block)
+}
+
+actual typealias IOException = java.io.IOException
+
+actual typealias EOFException = java.io.EOFException
+
+actual typealias FileNotFoundException = java.io.FileNotFoundException
+
+actual typealias Closeable = java.io.Closeable
diff --git a/okio/src/jvmMain/kotlin/okio/AsyncTimeout.kt b/okio/src/jvmMain/kotlin/okio/AsyncTimeout.kt
new file mode 100644
index 0000000..2077832
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/AsyncTimeout.kt
@@ -0,0 +1,328 @@
+/*
+ * 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 okio
+
+import java.io.IOException
+import java.io.InterruptedIOException
+import java.util.concurrent.TimeUnit
+
+/**
+ * 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.
+ *
+ * Subclasses should override [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.
+ *
+ * Use [sink] and [source] to apply this timeout to a stream. The returned value will apply the
+ * timeout to each operation on the wrapped stream.
+ *
+ * Callers should call [enter] before doing work that is subject to timeouts, and [exit] afterwards.
+ * The return value of [exit] indicates whether a timeout was triggered. Note that the call to
+ * [timedOut] is asynchronous, and may be called after [exit].
+ */
+open class AsyncTimeout : Timeout() {
+  /** True if this node is currently in the queue.  */
+  private var inQueue = false
+
+  /** The next node in the linked list.  */
+  private var next: AsyncTimeout? = null
+
+  /** If scheduled, this is the time that the watchdog should time this out.  */
+  private var timeoutAt = 0L
+
+  fun enter() {
+    val timeoutNanos = timeoutNanos()
+    val hasDeadline = hasDeadline()
+    if (timeoutNanos == 0L && !hasDeadline) {
+      return // No timeout and no deadline? Don't bother with the queue.
+    }
+    scheduleTimeout(this, timeoutNanos, hasDeadline)
+  }
+
+  /** Returns true if the timeout occurred.  */
+  fun exit(): Boolean {
+    return cancelScheduledTimeout(this)
+  }
+
+  /**
+   * 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 fun remainingNanos(now: Long) = timeoutAt - now
+
+  /**
+   * Invoked by the watchdog thread when the time between calls to [enter] and [exit] has exceeded
+   * the timeout.
+   */
+  protected open fun timedOut() {}
+
+  /**
+   * Returns a new sink that delegates to [sink], using this to implement timeouts. This works
+   * best if [timedOut] is overridden to interrupt [sink]'s current operation.
+   */
+  fun sink(sink: Sink): Sink {
+    return object : Sink {
+      override fun write(source: Buffer, byteCount: Long) {
+        checkOffsetAndCount(source.size, 0, byteCount)
+
+        var remaining = byteCount
+        while (remaining > 0L) {
+          // Count how many bytes to write. This loop guarantees we split on a segment boundary.
+          var toWrite = 0L
+          var s = source.head!!
+          while (toWrite < TIMEOUT_WRITE_SIZE) {
+            val segmentSize = s.limit - s.pos
+            toWrite += segmentSize.toLong()
+            if (toWrite >= remaining) {
+              toWrite = remaining
+              break
+            }
+            s = s.next!!
+          }
+
+          // Emit one write. Only this section is subject to the timeout.
+          withTimeout { sink.write(source, toWrite) }
+          remaining -= toWrite
+        }
+      }
+
+      override fun flush() {
+        withTimeout { sink.flush() }
+      }
+
+      override fun close() {
+        withTimeout { sink.close() }
+      }
+
+      override fun timeout() = this@AsyncTimeout
+
+      override fun toString() = "AsyncTimeout.sink($sink)"
+    }
+  }
+
+  /**
+   * Returns a new source that delegates to [source], using this to implement timeouts. This works
+   * best if [timedOut] is overridden to interrupt [source]'s current operation.
+   */
+  fun source(source: Source): Source {
+    return object : Source {
+      override fun read(sink: Buffer, byteCount: Long): Long {
+        return withTimeout { source.read(sink, byteCount) }
+      }
+
+      override fun close() {
+        withTimeout { source.close() }
+      }
+
+      override fun timeout() = this@AsyncTimeout
+
+      override fun toString() = "AsyncTimeout.source($source)"
+    }
+  }
+
+  /**
+   * Surrounds [block] with calls to [enter] and [exit], throwing an exception from
+   * [newTimeoutException] if a timeout occurred.
+   */
+  inline fun <T> withTimeout(block: () -> T): T {
+    var throwOnTimeout = false
+    enter()
+    try {
+      val result = block()
+      throwOnTimeout = true
+      return result
+    } catch (e: IOException) {
+      throw if (!exit()) e else `access$newTimeoutException`(e)
+    } finally {
+      val timedOut = exit()
+      if (timedOut && throwOnTimeout) throw `access$newTimeoutException`(null)
+    }
+  }
+
+  @PublishedApi // Binary compatible trampoline function
+  internal fun `access$newTimeoutException`(cause: IOException?) = newTimeoutException(cause)
+
+  /**
+   * Returns an [IOException] to represent a timeout. By default this method returns
+   * [InterruptedIOException]. If [cause] is non-null it is set as the cause of the
+   * returned exception.
+   */
+  protected open fun newTimeoutException(cause: IOException?): IOException {
+    val e = InterruptedIOException("timeout")
+    if (cause != null) {
+      e.initCause(cause)
+    }
+    return e
+  }
+
+  private class Watchdog internal constructor() : Thread("Okio Watchdog") {
+    init {
+      isDaemon = true
+    }
+
+    override fun run() {
+      while (true) {
+        try {
+          var timedOut: AsyncTimeout? = null
+          synchronized(AsyncTimeout::class.java) {
+            timedOut = awaitTimeout()
+
+            // The queue is completely empty. Let this thread exit and let another watchdog thread
+            // get created on the next call to scheduleTimeout().
+            if (timedOut === head) {
+              head = null
+              return
+            }
+          }
+
+          // Close the timed out node, if one was found.
+          timedOut?.timedOut()
+        } catch (ignored: InterruptedException) {
+        }
+      }
+    }
+  }
+
+  companion object {
+    /**
+     * Don't write more than 64 KiB of data at a time, give or take a segment. Otherwise slow
+     * connections may suffer timeouts even when they're making (slow) progress. Without this,
+     * writing a single 1 MiB buffer may never succeed on a sufficiently slow connection.
+     */
+    private const val TIMEOUT_WRITE_SIZE = 64 * 1024
+
+    /** Duration for the watchdog thread to be idle before it shuts itself down.  */
+    private val IDLE_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(60)
+    private val IDLE_TIMEOUT_NANOS = TimeUnit.MILLISECONDS.toNanos(IDLE_TIMEOUT_MILLIS)
+
+    /**
+     * 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.
+     *
+     * 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 and also after being idle for [AsyncTimeout.IDLE_TIMEOUT_MILLIS].
+     */
+    private var head: AsyncTimeout? = null
+
+    private fun scheduleTimeout(node: AsyncTimeout, timeoutNanos: Long, hasDeadline: Boolean) {
+      synchronized(AsyncTimeout::class.java) {
+        check(!node.inQueue) { "Unbalanced enter/exit" }
+        node.inQueue = true
+
+        // Start the watchdog thread and create the head node when the first timeout is scheduled.
+        if (head == null) {
+          head = AsyncTimeout()
+          Watchdog().start()
+        }
+
+        val now = System.nanoTime()
+        if (timeoutNanos != 0L && hasDeadline) {
+          // Compute the earliest event; either timeout or deadline. Because nanoTime can wrap
+          // around, minOf() is undefined for absolute values, but meaningful for relative ones.
+          node.timeoutAt = now + minOf(timeoutNanos, node.deadlineNanoTime() - now)
+        } else if (timeoutNanos != 0L) {
+          node.timeoutAt = now + timeoutNanos
+        } else if (hasDeadline) {
+          node.timeoutAt = node.deadlineNanoTime()
+        } else {
+          throw AssertionError()
+        }
+
+        // Insert the node in sorted order.
+        val remainingNanos = node.remainingNanos(now)
+        var prev = head!!
+        while (true) {
+          if (prev.next == null || remainingNanos < prev.next!!.remainingNanos(now)) {
+            node.next = prev.next
+            prev.next = node
+            if (prev === head) {
+              // Wake up the watchdog when inserting at the front.
+              (AsyncTimeout::class.java as Object).notify()
+            }
+            break
+          }
+          prev = prev.next!!
+        }
+      }
+    }
+
+    /** Returns true if the timeout occurred. */
+    private fun cancelScheduledTimeout(node: AsyncTimeout): Boolean {
+      synchronized(AsyncTimeout::class.java) {
+        if (!node.inQueue) return false
+        node.inQueue = false
+
+        // Remove the node from the linked list.
+        var prev = head
+        while (prev != null) {
+          if (prev.next === node) {
+            prev.next = node.next
+            node.next = null
+            return false
+          }
+          prev = prev.next
+        }
+
+        // The node wasn't found in the linked list: it must have timed out!
+        return true
+      }
+    }
+
+    /**
+     * Removes and returns the node at the head of the list, waiting for it to time out if
+     * necessary. This returns [head] if there was no node at the head of the list when starting,
+     * and there continues to be no node after waiting [IDLE_TIMEOUT_NANOS]. It returns null if a
+     * new node was inserted while waiting. Otherwise this returns the node being waited on that has
+     * been removed.
+     */
+    @Throws(InterruptedException::class)
+    internal fun awaitTimeout(): AsyncTimeout? {
+      // Get the next eligible node.
+      val node = head!!.next
+
+      // The queue is empty. Wait until either something is enqueued or the idle timeout elapses.
+      if (node == null) {
+        val startNanos = System.nanoTime()
+        (AsyncTimeout::class.java as Object).wait(IDLE_TIMEOUT_MILLIS)
+        return if (head!!.next == null && System.nanoTime() - startNanos >= IDLE_TIMEOUT_NANOS) {
+          head // The idle timeout elapsed.
+        } else {
+          null // The situation has changed.
+        }
+      }
+
+      var 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.
+        val waitMillis = waitNanos / 1000000L
+        waitNanos -= waitMillis * 1000000L
+        (AsyncTimeout::class.java as Object).wait(waitMillis, waitNanos.toInt())
+        return null
+      }
+
+      // The head of the queue has timed out. Remove it.
+      head!!.next = node.next
+      node.next = null
+      return node
+    }
+  }
+}
diff --git a/okio/src/jvmMain/kotlin/okio/Buffer.kt b/okio/src/jvmMain/kotlin/okio/Buffer.kt
new file mode 100644
index 0000000..857c983
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/Buffer.kt
@@ -0,0 +1,622 @@
+/*
+ * 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 okio
+
+import okio.internal.commonClear
+import okio.internal.commonClose
+import okio.internal.commonCompleteSegmentByteCount
+import okio.internal.commonCopy
+import okio.internal.commonCopyTo
+import okio.internal.commonEquals
+import okio.internal.commonExpandBuffer
+import okio.internal.commonGet
+import okio.internal.commonHashCode
+import okio.internal.commonIndexOf
+import okio.internal.commonIndexOfElement
+import okio.internal.commonNext
+import okio.internal.commonRangeEquals
+import okio.internal.commonRead
+import okio.internal.commonReadAll
+import okio.internal.commonReadAndWriteUnsafe
+import okio.internal.commonReadByte
+import okio.internal.commonReadByteArray
+import okio.internal.commonReadByteString
+import okio.internal.commonReadDecimalLong
+import okio.internal.commonReadFully
+import okio.internal.commonReadHexadecimalUnsignedLong
+import okio.internal.commonReadInt
+import okio.internal.commonReadLong
+import okio.internal.commonReadShort
+import okio.internal.commonReadUnsafe
+import okio.internal.commonReadUtf8CodePoint
+import okio.internal.commonReadUtf8Line
+import okio.internal.commonReadUtf8LineStrict
+import okio.internal.commonResizeBuffer
+import okio.internal.commonSeek
+import okio.internal.commonSelect
+import okio.internal.commonSkip
+import okio.internal.commonSnapshot
+import okio.internal.commonWritableSegment
+import okio.internal.commonWrite
+import okio.internal.commonWriteAll
+import okio.internal.commonWriteByte
+import okio.internal.commonWriteDecimalLong
+import okio.internal.commonWriteHexadecimalUnsignedLong
+import okio.internal.commonWriteInt
+import okio.internal.commonWriteLong
+import okio.internal.commonWriteShort
+import okio.internal.commonWriteUtf8
+import okio.internal.commonWriteUtf8CodePoint
+import java.io.Closeable
+import java.io.EOFException
+import java.io.IOException
+import java.io.InputStream
+import java.io.OutputStream
+import java.nio.ByteBuffer
+import java.nio.channels.ByteChannel
+import java.nio.charset.Charset
+import java.security.InvalidKeyException
+import java.security.MessageDigest
+import javax.crypto.Mac
+import javax.crypto.spec.SecretKeySpec
+
+actual class Buffer : BufferedSource, BufferedSink, Cloneable, ByteChannel {
+  @JvmField internal actual var head: Segment? = null
+
+  @get:JvmName("size")
+  actual var size: Long = 0L
+    internal set
+
+  override fun buffer() = this
+
+  actual override val buffer get() = this
+
+  override fun outputStream(): OutputStream {
+    return object : OutputStream() {
+      override fun write(b: Int) {
+        writeByte(b)
+      }
+
+      override fun write(data: ByteArray, offset: Int, byteCount: Int) {
+        this@Buffer.write(data, offset, byteCount)
+      }
+
+      override fun flush() {}
+
+      override fun close() {}
+
+      override fun toString(): String = "${this@Buffer}.outputStream()"
+    }
+  }
+
+  actual override fun emitCompleteSegments() = this // Nowhere to emit to!
+
+  actual override fun emit() = this // Nowhere to emit to!
+
+  override fun exhausted() = size == 0L
+
+  @Throws(EOFException::class)
+  override fun require(byteCount: Long) {
+    if (size < byteCount) throw EOFException()
+  }
+
+  override fun request(byteCount: Long) = size >= byteCount
+
+  override fun peek(): BufferedSource {
+    return PeekSource(this).buffer()
+  }
+
+  override fun inputStream(): InputStream {
+    return object : InputStream() {
+      override fun read(): Int {
+        return if (size > 0L) {
+          readByte() and 0xff
+        } else {
+          -1
+        }
+      }
+
+      override fun read(sink: ByteArray, offset: Int, byteCount: Int): Int {
+        return this@Buffer.read(sink, offset, byteCount)
+      }
+
+      override fun available() = minOf(size, Integer.MAX_VALUE).toInt()
+
+      override fun close() {}
+
+      override fun toString() = "${this@Buffer}.inputStream()"
+    }
+  }
+
+  /** Copy `byteCount` bytes from this, starting at `offset`, to `out`. */
+  @Throws(IOException::class)
+  @JvmOverloads
+  fun copyTo(
+    out: OutputStream,
+    offset: Long = 0L,
+    byteCount: Long = size - offset
+  ): Buffer {
+    var offset = offset
+    var byteCount = byteCount
+    checkOffsetAndCount(size, offset, byteCount)
+    if (byteCount == 0L) return this
+
+    // Skip segments that we aren't copying from.
+    var s = head
+    while (offset >= s!!.limit - s.pos) {
+      offset -= (s.limit - s.pos).toLong()
+      s = s.next
+    }
+
+    // Copy from one segment at a time.
+    while (byteCount > 0L) {
+      val pos = (s!!.pos + offset).toInt()
+      val toCopy = minOf(s.limit - pos, byteCount).toInt()
+      out.write(s.data, pos, toCopy)
+      byteCount -= toCopy.toLong()
+      offset = 0L
+      s = s.next
+    }
+
+    return this
+  }
+
+  actual fun copyTo(
+    out: Buffer,
+    offset: Long,
+    byteCount: Long
+  ): Buffer = commonCopyTo(out, offset, byteCount)
+
+  actual fun copyTo(
+    out: Buffer,
+    offset: Long
+  ): Buffer = copyTo(out, offset, size - offset)
+
+  /** Write `byteCount` bytes from this to `out`.  */
+  @Throws(IOException::class)
+  @JvmOverloads
+  fun writeTo(out: OutputStream, byteCount: Long = size): Buffer {
+    var byteCount = byteCount
+    checkOffsetAndCount(size, 0, byteCount)
+
+    var s = head
+    while (byteCount > 0L) {
+      val toCopy = minOf(byteCount, s!!.limit - s.pos).toInt()
+      out.write(s.data, s.pos, toCopy)
+
+      s.pos += toCopy
+      size -= toCopy.toLong()
+      byteCount -= toCopy.toLong()
+
+      if (s.pos == s.limit) {
+        val toRecycle = s
+        s = toRecycle.pop()
+        head = s
+        SegmentPool.recycle(toRecycle)
+      }
+    }
+
+    return this
+  }
+
+  /** Read and exhaust bytes from `input` into this.  */
+  @Throws(IOException::class)
+  fun readFrom(input: InputStream): Buffer {
+    readFrom(input, Long.MAX_VALUE, true)
+    return this
+  }
+
+  /** Read `byteCount` bytes from `input` into this.  */
+  @Throws(IOException::class)
+  fun readFrom(input: InputStream, byteCount: Long): Buffer {
+    require(byteCount >= 0L) { "byteCount < 0: $byteCount" }
+    readFrom(input, byteCount, false)
+    return this
+  }
+
+  @Throws(IOException::class)
+  private fun readFrom(input: InputStream, byteCount: Long, forever: Boolean) {
+    var byteCount = byteCount
+    while (byteCount > 0L || forever) {
+      val tail = writableSegment(1)
+      val maxToCopy = minOf(byteCount, Segment.SIZE - tail.limit).toInt()
+      val bytesRead = input.read(tail.data, tail.limit, maxToCopy)
+      if (bytesRead == -1) {
+        if (tail.pos == tail.limit) {
+          // We allocated a tail segment, but didn't end up needing it. Recycle!
+          head = tail.pop()
+          SegmentPool.recycle(tail)
+        }
+        if (forever) return
+        throw EOFException()
+      }
+      tail.limit += bytesRead
+      size += bytesRead.toLong()
+      byteCount -= bytesRead.toLong()
+    }
+  }
+
+  actual fun completeSegmentByteCount(): Long = commonCompleteSegmentByteCount()
+
+  @Throws(EOFException::class)
+  override fun readByte(): Byte = commonReadByte()
+
+  @JvmName("getByte")
+  actual operator fun get(pos: Long): Byte = commonGet(pos)
+
+  @Throws(EOFException::class)
+  override fun readShort(): Short = commonReadShort()
+
+  @Throws(EOFException::class)
+  override fun readInt(): Int = commonReadInt()
+
+  @Throws(EOFException::class)
+  override fun readLong(): Long = commonReadLong()
+
+  @Throws(EOFException::class)
+  override fun readShortLe() = readShort().reverseBytes()
+
+  @Throws(EOFException::class)
+  override fun readIntLe() = readInt().reverseBytes()
+
+  @Throws(EOFException::class)
+  override fun readLongLe() = readLong().reverseBytes()
+
+  @Throws(EOFException::class)
+  override fun readDecimalLong(): Long = commonReadDecimalLong()
+
+  @Throws(EOFException::class)
+  override fun readHexadecimalUnsignedLong(): Long = commonReadHexadecimalUnsignedLong()
+
+  override fun readByteString(): ByteString = commonReadByteString()
+
+  @Throws(EOFException::class)
+  override fun readByteString(byteCount: Long) = commonReadByteString(byteCount)
+
+  override fun select(options: Options): Int = commonSelect(options)
+
+  @Throws(EOFException::class)
+  override fun readFully(sink: Buffer, byteCount: Long): Unit = commonReadFully(sink, byteCount)
+
+  @Throws(IOException::class)
+  override fun readAll(sink: Sink): Long = commonReadAll(sink)
+
+  override fun readUtf8() = readString(size, Charsets.UTF_8)
+
+  @Throws(EOFException::class)
+  override fun readUtf8(byteCount: Long) = readString(byteCount, Charsets.UTF_8)
+
+  override fun readString(charset: Charset) = readString(size, charset)
+
+  @Throws(EOFException::class)
+  override fun readString(byteCount: Long, charset: Charset): String {
+    require(byteCount >= 0 && byteCount <= Integer.MAX_VALUE) { "byteCount: $byteCount" }
+    if (size < byteCount) throw EOFException()
+    if (byteCount == 0L) return ""
+
+    val s = head!!
+    if (s.pos + byteCount > s.limit) {
+      // If the string spans multiple segments, delegate to readBytes().
+      return String(readByteArray(byteCount), charset)
+    }
+
+    val result = String(s.data, s.pos, byteCount.toInt(), charset)
+    s.pos += byteCount.toInt()
+    size -= byteCount
+
+    if (s.pos == s.limit) {
+      head = s.pop()
+      SegmentPool.recycle(s)
+    }
+
+    return result
+  }
+
+  @Throws(EOFException::class)
+  override fun readUtf8Line(): String? = commonReadUtf8Line()
+
+  @Throws(EOFException::class)
+  override fun readUtf8LineStrict() = readUtf8LineStrict(Long.MAX_VALUE)
+
+  @Throws(EOFException::class)
+  override fun readUtf8LineStrict(limit: Long): String = commonReadUtf8LineStrict(limit)
+
+  @Throws(EOFException::class)
+  override fun readUtf8CodePoint(): Int = commonReadUtf8CodePoint()
+
+  override fun readByteArray() = commonReadByteArray()
+
+  @Throws(EOFException::class)
+  override fun readByteArray(byteCount: Long): ByteArray = commonReadByteArray(byteCount)
+
+  override fun read(sink: ByteArray) = commonRead(sink)
+
+  @Throws(EOFException::class)
+  override fun readFully(sink: ByteArray) = commonReadFully(sink)
+
+  override fun read(sink: ByteArray, offset: Int, byteCount: Int): Int =
+    commonRead(sink, offset, byteCount)
+
+  @Throws(IOException::class)
+  override fun read(sink: ByteBuffer): Int {
+    val s = head ?: return -1
+
+    val toCopy = minOf(sink.remaining(), s.limit - s.pos)
+    sink.put(s.data, s.pos, toCopy)
+
+    s.pos += toCopy
+    size -= toCopy.toLong()
+
+    if (s.pos == s.limit) {
+      head = s.pop()
+      SegmentPool.recycle(s)
+    }
+
+    return toCopy
+  }
+
+  actual fun clear() = commonClear()
+
+  @Throws(EOFException::class)
+  actual override fun skip(byteCount: Long) = commonSkip(byteCount)
+
+  actual override fun write(byteString: ByteString): Buffer = commonWrite(byteString)
+
+  actual override fun write(byteString: ByteString, offset: Int, byteCount: Int) =
+    commonWrite(byteString, offset, byteCount)
+
+  actual override fun writeUtf8(string: String): Buffer = writeUtf8(string, 0, string.length)
+
+  actual override fun writeUtf8(string: String, beginIndex: Int, endIndex: Int): Buffer =
+    commonWriteUtf8(string, beginIndex, endIndex)
+
+  actual override fun writeUtf8CodePoint(codePoint: Int): Buffer =
+    commonWriteUtf8CodePoint(codePoint)
+
+  override fun writeString(string: String, charset: Charset) = writeString(
+    string, 0, string.length,
+    charset
+  )
+
+  override fun writeString(
+    string: String,
+    beginIndex: Int,
+    endIndex: Int,
+    charset: Charset
+  ): Buffer {
+    require(beginIndex >= 0) { "beginIndex < 0: $beginIndex" }
+    require(endIndex >= beginIndex) { "endIndex < beginIndex: $endIndex < $beginIndex" }
+    require(endIndex <= string.length) { "endIndex > string.length: $endIndex > ${string.length}" }
+    if (charset == Charsets.UTF_8) return writeUtf8(string, beginIndex, endIndex)
+    val data = string.substring(beginIndex, endIndex).toByteArray(charset)
+    return write(data, 0, data.size)
+  }
+
+  actual override fun write(source: ByteArray): Buffer = commonWrite(source)
+
+  actual override fun write(
+    source: ByteArray,
+    offset: Int,
+    byteCount: Int
+  ): Buffer = commonWrite(source, offset, byteCount)
+
+  @Throws(IOException::class)
+  override fun write(source: ByteBuffer): Int {
+    val byteCount = source.remaining()
+    var remaining = byteCount
+    while (remaining > 0) {
+      val tail = writableSegment(1)
+
+      val toCopy = minOf(remaining, Segment.SIZE - tail.limit)
+      source.get(tail.data, tail.limit, toCopy)
+
+      remaining -= toCopy
+      tail.limit += toCopy
+    }
+
+    size += byteCount.toLong()
+    return byteCount
+  }
+
+  @Throws(IOException::class)
+  override fun writeAll(source: Source): Long = commonWriteAll(source)
+
+  @Throws(IOException::class)
+  actual override fun write(source: Source, byteCount: Long): Buffer =
+    commonWrite(source, byteCount)
+
+  actual override fun writeByte(b: Int): Buffer = commonWriteByte(b)
+
+  actual override fun writeShort(s: Int): Buffer = commonWriteShort(s)
+
+  actual override fun writeShortLe(s: Int) = writeShort(s.toShort().reverseBytes().toInt())
+
+  actual override fun writeInt(i: Int): Buffer = commonWriteInt(i)
+
+  actual override fun writeIntLe(i: Int) = writeInt(i.reverseBytes())
+
+  actual override fun writeLong(v: Long): Buffer = commonWriteLong(v)
+
+  actual override fun writeLongLe(v: Long) = writeLong(v.reverseBytes())
+
+  actual override fun writeDecimalLong(v: Long): Buffer = commonWriteDecimalLong(v)
+
+  actual override fun writeHexadecimalUnsignedLong(v: Long): Buffer =
+    commonWriteHexadecimalUnsignedLong(v)
+
+  internal actual fun writableSegment(minimumCapacity: Int): Segment =
+    commonWritableSegment(minimumCapacity)
+
+  override fun write(source: Buffer, byteCount: Long): Unit = commonWrite(source, byteCount)
+
+  override fun read(sink: Buffer, byteCount: Long): Long = commonRead(sink, byteCount)
+
+  override fun indexOf(b: Byte) = indexOf(b, 0, Long.MAX_VALUE)
+
+  /**
+   * Returns the index of `b` in this at or beyond `fromIndex`, or -1 if this buffer does not
+   * contain `b` in that range.
+   */
+  override fun indexOf(b: Byte, fromIndex: Long) = indexOf(b, fromIndex, Long.MAX_VALUE)
+
+  override fun indexOf(b: Byte, fromIndex: Long, toIndex: Long): Long = commonIndexOf(b, fromIndex, toIndex)
+
+  @Throws(IOException::class)
+  override fun indexOf(bytes: ByteString): Long = indexOf(bytes, 0)
+
+  @Throws(IOException::class)
+  override fun indexOf(bytes: ByteString, fromIndex: Long): Long = commonIndexOf(bytes, fromIndex)
+
+  override fun indexOfElement(targetBytes: ByteString) = indexOfElement(targetBytes, 0L)
+
+  override fun indexOfElement(targetBytes: ByteString, fromIndex: Long): Long =
+    commonIndexOfElement(targetBytes, fromIndex)
+
+  override fun rangeEquals(offset: Long, bytes: ByteString) =
+    rangeEquals(offset, bytes, 0, bytes.size)
+
+  override fun rangeEquals(
+    offset: Long,
+    bytes: ByteString,
+    bytesOffset: Int,
+    byteCount: Int
+  ): Boolean = commonRangeEquals(offset, bytes, bytesOffset, byteCount)
+
+  override fun flush() {}
+
+  override fun isOpen() = true
+
+  override fun close() {}
+
+  override fun timeout() = Timeout.NONE
+
+  /** Returns the 128-bit MD5 hash of this buffer.  */
+  actual fun md5() = digest("MD5")
+
+  /** Returns the 160-bit SHA-1 hash of this buffer.  */
+  actual fun sha1() = digest("SHA-1")
+
+  /** Returns the 256-bit SHA-256 hash of this buffer.  */
+  actual fun sha256() = digest("SHA-256")
+
+  /** Returns the 512-bit SHA-512 hash of this buffer.  */
+  actual fun sha512() = digest("SHA-512")
+
+  private fun digest(algorithm: String): ByteString {
+    val messageDigest = MessageDigest.getInstance(algorithm)
+    head?.let { head ->
+      messageDigest.update(head.data, head.pos, head.limit - head.pos)
+      var s = head.next!!
+      while (s !== head) {
+        messageDigest.update(s.data, s.pos, s.limit - s.pos)
+        s = s.next!!
+      }
+    }
+    return ByteString(messageDigest.digest())
+  }
+
+  /** Returns the 160-bit SHA-1 HMAC of this buffer.  */
+  actual fun hmacSha1(key: ByteString) = hmac("HmacSHA1", key)
+
+  /** Returns the 256-bit SHA-256 HMAC of this buffer.  */
+  actual fun hmacSha256(key: ByteString) = hmac("HmacSHA256", key)
+
+  /** Returns the 512-bit SHA-512 HMAC of this buffer.  */
+  actual fun hmacSha512(key: ByteString) = hmac("HmacSHA512", key)
+
+  private fun hmac(algorithm: String, key: ByteString): ByteString {
+    try {
+      val mac = Mac.getInstance(algorithm)
+      mac.init(SecretKeySpec(key.internalArray(), algorithm))
+      head?.let { head ->
+        mac.update(head.data, head.pos, head.limit - head.pos)
+        var s = head.next!!
+        while (s !== head) {
+          mac.update(s.data, s.pos, s.limit - s.pos)
+          s = s.next!!
+        }
+      }
+      return ByteString(mac.doFinal())
+    } catch (e: InvalidKeyException) {
+      throw IllegalArgumentException(e)
+    }
+  }
+
+  override fun equals(other: Any?): Boolean = commonEquals(other)
+
+  override fun hashCode(): Int = commonHashCode()
+
+  /**
+   * Returns a human-readable string that describes the contents of this buffer. Typically this
+   * is a string like `[text=Hello]` or `[hex=0000ffff]`.
+   */
+  override fun toString() = snapshot().toString()
+
+  actual fun copy(): Buffer = commonCopy()
+
+  /** Returns a deep copy of this buffer. */
+  public override fun clone(): Buffer = copy()
+
+  actual fun snapshot(): ByteString = commonSnapshot()
+
+  actual fun snapshot(byteCount: Int): ByteString = commonSnapshot(byteCount)
+
+  @JvmOverloads
+  actual fun readUnsafe(unsafeCursor: UnsafeCursor): UnsafeCursor = commonReadUnsafe(unsafeCursor)
+
+  @JvmOverloads
+  actual fun readAndWriteUnsafe(unsafeCursor: UnsafeCursor): UnsafeCursor =
+    commonReadAndWriteUnsafe(unsafeCursor)
+
+  @JvmName("-deprecated_getByte")
+  @Deprecated(
+    message = "moved to operator function",
+    replaceWith = ReplaceWith(expression = "this[index]"),
+    level = DeprecationLevel.ERROR
+  )
+  fun getByte(index: Long) = this[index]
+
+  @JvmName("-deprecated_size")
+  @Deprecated(
+    message = "moved to val",
+    replaceWith = ReplaceWith(expression = "size"),
+    level = DeprecationLevel.ERROR
+  )
+  fun size() = size
+
+  actual class UnsafeCursor : Closeable {
+    @JvmField actual var buffer: Buffer? = null
+    @JvmField actual var readWrite: Boolean = false
+
+    internal actual var segment: Segment? = null
+    @JvmField actual var offset = -1L
+    @JvmField actual var data: ByteArray? = null
+    @JvmField actual var start = -1
+    @JvmField actual var end = -1
+
+    actual fun next(): Int = commonNext()
+
+    actual fun seek(offset: Long): Int = commonSeek(offset)
+
+    actual fun resizeBuffer(newSize: Long): Long = commonResizeBuffer(newSize)
+
+    actual fun expandBuffer(minByteCount: Int): Long = commonExpandBuffer(minByteCount)
+
+    actual override fun close() {
+      commonClose()
+    }
+  }
+}
diff --git a/okio/src/jvmMain/kotlin/okio/BufferedSink.kt b/okio/src/jvmMain/kotlin/okio/BufferedSink.kt
new file mode 100644
index 0000000..4aa1bb0
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/BufferedSink.kt
@@ -0,0 +1,105 @@
+/*
+ * 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 okio
+
+import java.io.IOException
+import java.io.OutputStream
+import java.nio.channels.WritableByteChannel
+import java.nio.charset.Charset
+
+actual interface BufferedSink : Sink, WritableByteChannel {
+  /** Returns this sink's internal buffer. */
+  @Deprecated(
+    message = "moved to val: use getBuffer() instead",
+    replaceWith = ReplaceWith(expression = "buffer"),
+    level = DeprecationLevel.WARNING
+  )
+  fun buffer(): Buffer
+
+  actual val buffer: Buffer
+
+  @Throws(IOException::class)
+  actual fun write(byteString: ByteString): BufferedSink
+
+  @Throws(IOException::class)
+  actual fun write(byteString: ByteString, offset: Int, byteCount: Int): BufferedSink
+
+  @Throws(IOException::class)
+  actual fun write(source: ByteArray): BufferedSink
+
+  @Throws(IOException::class)
+  actual fun write(source: ByteArray, offset: Int, byteCount: Int): BufferedSink
+
+  @Throws(IOException::class)
+  actual fun writeAll(source: Source): Long
+
+  @Throws(IOException::class)
+  actual fun write(source: Source, byteCount: Long): BufferedSink
+
+  @Throws(IOException::class)
+  actual fun writeUtf8(string: String): BufferedSink
+
+  @Throws(IOException::class)
+  actual fun writeUtf8(string: String, beginIndex: Int, endIndex: Int): BufferedSink
+
+  @Throws(IOException::class)
+  actual fun writeUtf8CodePoint(codePoint: Int): BufferedSink
+
+  @Throws(IOException::class)
+  fun writeString(string: String, charset: Charset): BufferedSink
+
+  @Throws(IOException::class)
+  fun writeString(string: String, beginIndex: Int, endIndex: Int, charset: Charset): BufferedSink
+
+  @Throws(IOException::class)
+  actual fun writeByte(b: Int): BufferedSink
+
+  @Throws(IOException::class)
+  actual fun writeShort(s: Int): BufferedSink
+
+  @Throws(IOException::class)
+  actual fun writeShortLe(s: Int): BufferedSink
+
+  @Throws(IOException::class)
+  actual fun writeInt(i: Int): BufferedSink
+
+  @Throws(IOException::class)
+  actual fun writeIntLe(i: Int): BufferedSink
+
+  @Throws(IOException::class)
+  actual fun writeLong(v: Long): BufferedSink
+
+  @Throws(IOException::class)
+  actual fun writeLongLe(v: Long): BufferedSink
+
+  @Throws(IOException::class)
+  actual fun writeDecimalLong(v: Long): BufferedSink
+
+  @Throws(IOException::class)
+  actual fun writeHexadecimalUnsignedLong(v: Long): BufferedSink
+
+  @Throws(IOException::class)
+  actual override fun flush()
+
+  @Throws(IOException::class)
+  actual fun emit(): BufferedSink
+
+  @Throws(IOException::class)
+  actual fun emitCompleteSegments(): BufferedSink
+
+  /** Returns an output stream that writes to this sink. */
+  fun outputStream(): OutputStream
+}
diff --git a/okio/src/jvmMain/kotlin/okio/BufferedSource.kt b/okio/src/jvmMain/kotlin/okio/BufferedSource.kt
new file mode 100644
index 0000000..b312d56
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/BufferedSource.kt
@@ -0,0 +1,163 @@
+/*
+ * 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 okio
+
+import java.io.IOException
+import java.io.InputStream
+import java.nio.channels.ReadableByteChannel
+import java.nio.charset.Charset
+
+actual interface BufferedSource : Source, ReadableByteChannel {
+  /** Returns this source's internal buffer. */
+  @Deprecated(
+    message = "moved to val: use getBuffer() instead",
+    replaceWith = ReplaceWith(expression = "buffer"),
+    level = DeprecationLevel.WARNING
+  )
+  fun buffer(): Buffer
+
+  actual val buffer: Buffer
+
+  @Throws(IOException::class)
+  actual fun exhausted(): Boolean
+
+  @Throws(IOException::class)
+  actual fun require(byteCount: Long)
+
+  @Throws(IOException::class)
+  actual fun request(byteCount: Long): Boolean
+
+  @Throws(IOException::class)
+  actual fun readByte(): Byte
+
+  @Throws(IOException::class)
+  actual fun readShort(): Short
+
+  @Throws(IOException::class)
+  actual fun readShortLe(): Short
+
+  @Throws(IOException::class)
+  actual fun readInt(): Int
+
+  @Throws(IOException::class)
+  actual fun readIntLe(): Int
+
+  @Throws(IOException::class)
+  actual fun readLong(): Long
+
+  @Throws(IOException::class)
+  actual fun readLongLe(): Long
+
+  @Throws(IOException::class)
+  actual fun readDecimalLong(): Long
+
+  @Throws(IOException::class)
+  actual fun readHexadecimalUnsignedLong(): Long
+
+  @Throws(IOException::class)
+  actual fun skip(byteCount: Long)
+
+  @Throws(IOException::class)
+  actual fun readByteString(): ByteString
+
+  @Throws(IOException::class)
+  actual fun readByteString(byteCount: Long): ByteString
+
+  @Throws(IOException::class)
+  actual fun select(options: Options): Int
+
+  @Throws(IOException::class)
+  actual fun readByteArray(): ByteArray
+
+  @Throws(IOException::class)
+  actual fun readByteArray(byteCount: Long): ByteArray
+
+  @Throws(IOException::class)
+  actual fun read(sink: ByteArray): Int
+
+  @Throws(IOException::class)
+  actual fun readFully(sink: ByteArray)
+
+  @Throws(IOException::class)
+  actual fun read(sink: ByteArray, offset: Int, byteCount: Int): Int
+
+  @Throws(IOException::class)
+  actual fun readFully(sink: Buffer, byteCount: Long)
+
+  @Throws(IOException::class)
+  actual fun readAll(sink: Sink): Long
+
+  @Throws(IOException::class)
+  actual fun readUtf8(): String
+
+  @Throws(IOException::class)
+  actual fun readUtf8(byteCount: Long): String
+
+  @Throws(IOException::class)
+  actual fun readUtf8Line(): String?
+
+  @Throws(IOException::class)
+  actual fun readUtf8LineStrict(): String
+
+  @Throws(IOException::class)
+  actual fun readUtf8LineStrict(limit: Long): String
+
+  @Throws(IOException::class)
+  actual fun readUtf8CodePoint(): Int
+
+  /** Removes all bytes from this, decodes them as `charset`, and returns the string. */
+  @Throws(IOException::class)
+  fun readString(charset: Charset): String
+
+  /**
+   * Removes `byteCount` bytes from this, decodes them as `charset`, and returns the
+   * string.
+   */
+  @Throws(IOException::class)
+  fun readString(byteCount: Long, charset: Charset): String
+
+  @Throws(IOException::class)
+  actual fun indexOf(b: Byte): Long
+
+  @Throws(IOException::class)
+  actual fun indexOf(b: Byte, fromIndex: Long): Long
+
+  @Throws(IOException::class)
+  actual fun indexOf(b: Byte, fromIndex: Long, toIndex: Long): Long
+
+  @Throws(IOException::class)
+  actual fun indexOf(bytes: ByteString): Long
+
+  @Throws(IOException::class)
+  actual fun indexOf(bytes: ByteString, fromIndex: Long): Long
+
+  @Throws(IOException::class)
+  actual fun indexOfElement(targetBytes: ByteString): Long
+
+  @Throws(IOException::class)
+  actual fun indexOfElement(targetBytes: ByteString, fromIndex: Long): Long
+
+  @Throws(IOException::class)
+  actual fun rangeEquals(offset: Long, bytes: ByteString): Boolean
+
+  @Throws(IOException::class)
+  actual fun rangeEquals(offset: Long, bytes: ByteString, bytesOffset: Int, byteCount: Int): Boolean
+
+  actual fun peek(): BufferedSource
+
+  /** Returns an input stream that reads from this source. */
+  fun inputStream(): InputStream
+}
diff --git a/okio/src/jvmMain/kotlin/okio/ByteString.kt b/okio/src/jvmMain/kotlin/okio/ByteString.kt
new file mode 100644
index 0000000..0edad9c
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/ByteString.kt
@@ -0,0 +1,354 @@
+/*
+ * 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 okio
+
+import okio.internal.commonBase64
+import okio.internal.commonBase64Url
+import okio.internal.commonCompareTo
+import okio.internal.commonDecodeBase64
+import okio.internal.commonDecodeHex
+import okio.internal.commonEncodeUtf8
+import okio.internal.commonEndsWith
+import okio.internal.commonEquals
+import okio.internal.commonGetByte
+import okio.internal.commonGetSize
+import okio.internal.commonHashCode
+import okio.internal.commonHex
+import okio.internal.commonIndexOf
+import okio.internal.commonInternalArray
+import okio.internal.commonLastIndexOf
+import okio.internal.commonOf
+import okio.internal.commonRangeEquals
+import okio.internal.commonStartsWith
+import okio.internal.commonSubstring
+import okio.internal.commonToAsciiLowercase
+import okio.internal.commonToAsciiUppercase
+import okio.internal.commonToByteArray
+import okio.internal.commonToByteString
+import okio.internal.commonToString
+import okio.internal.commonUtf8
+import okio.internal.commonWrite
+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.nio.ByteBuffer
+import java.nio.charset.Charset
+import java.security.InvalidKeyException
+import java.security.MessageDigest
+import javax.crypto.Mac
+import javax.crypto.spec.SecretKeySpec
+
+actual open class ByteString
+internal actual constructor(
+  internal actual val data: ByteArray
+) : Serializable, Comparable<ByteString> {
+  @Transient internal actual var hashCode: Int = 0 // Lazily computed; 0 if unknown.
+  @Transient internal actual var utf8: String? = null // Lazily computed.
+
+  actual open fun utf8(): String = commonUtf8()
+
+  /** Constructs a new `String` by decoding the bytes using `charset`.  */
+  open fun string(charset: Charset) = String(data, charset)
+
+  actual open fun base64() = commonBase64()
+
+  actual fun md5() = digest("MD5")
+
+  actual fun sha1() = digest("SHA-1")
+
+  actual fun sha256() = digest("SHA-256")
+
+  actual fun sha512() = digest("SHA-512")
+
+  internal open fun digest(algorithm: String): ByteString {
+    val digestBytes = MessageDigest.getInstance(algorithm).run {
+      update(data, 0, size)
+      digest()
+    }
+    return ByteString(digestBytes)
+  }
+
+  /** Returns the 160-bit SHA-1 HMAC of this byte string.  */
+  actual open fun hmacSha1(key: ByteString) = hmac("HmacSHA1", key)
+
+  /** Returns the 256-bit SHA-256 HMAC of this byte string.  */
+  actual open fun hmacSha256(key: ByteString) = hmac("HmacSHA256", key)
+
+  /** Returns the 512-bit SHA-512 HMAC of this byte string.  */
+  actual open fun hmacSha512(key: ByteString) = hmac("HmacSHA512", key)
+
+  internal open fun hmac(algorithm: String, key: ByteString): ByteString {
+    try {
+      val mac = Mac.getInstance(algorithm)
+      mac.init(SecretKeySpec(key.toByteArray(), algorithm))
+      return ByteString(mac.doFinal(data))
+    } catch (e: InvalidKeyException) {
+      throw IllegalArgumentException(e)
+    }
+  }
+
+  actual open fun base64Url() = commonBase64Url()
+
+  actual open fun hex(): String = commonHex()
+
+  actual open fun toAsciiLowercase(): ByteString = commonToAsciiLowercase()
+
+  actual open fun toAsciiUppercase(): ByteString = commonToAsciiUppercase()
+
+  @JvmOverloads
+  actual open fun substring(beginIndex: Int, endIndex: Int): ByteString =
+    commonSubstring(beginIndex, endIndex)
+
+  internal actual open fun internalGet(pos: Int) = commonGetByte(pos)
+
+  @JvmName("getByte")
+  actual operator fun get(index: Int): Byte = internalGet(index)
+
+  actual val size
+    @JvmName("size") get() = getSize()
+
+  internal actual open fun getSize() = commonGetSize()
+
+  actual open fun toByteArray() = commonToByteArray()
+
+  internal actual open fun internalArray() = commonInternalArray()
+
+  /** Returns a `ByteBuffer` view of the bytes in this `ByteString`. */
+  open fun asByteBuffer(): ByteBuffer = ByteBuffer.wrap(data).asReadOnlyBuffer()
+
+  /** Writes the contents of this byte string to `out`.  */
+  @Throws(IOException::class)
+  open fun write(out: OutputStream) {
+    out.write(data)
+  }
+
+  internal actual open fun write(buffer: Buffer, offset: Int, byteCount: Int) =
+    commonWrite(buffer, offset, byteCount)
+
+  actual open fun rangeEquals(
+    offset: Int,
+    other: ByteString,
+    otherOffset: Int,
+    byteCount: Int
+  ): Boolean = commonRangeEquals(offset, other, otherOffset, byteCount)
+
+  actual open fun rangeEquals(
+    offset: Int,
+    other: ByteArray,
+    otherOffset: Int,
+    byteCount: Int
+  ): Boolean = commonRangeEquals(offset, other, otherOffset, byteCount)
+
+  actual fun startsWith(prefix: ByteString) = commonStartsWith(prefix)
+
+  actual fun startsWith(prefix: ByteArray) = commonStartsWith(prefix)
+
+  actual fun endsWith(suffix: ByteString) = commonEndsWith(suffix)
+
+  actual fun endsWith(suffix: ByteArray) = commonEndsWith(suffix)
+
+  @JvmOverloads
+  actual fun indexOf(other: ByteString, fromIndex: Int) = indexOf(other.internalArray(), fromIndex)
+
+  @JvmOverloads
+  actual open fun indexOf(other: ByteArray, fromIndex: Int) = commonIndexOf(other, fromIndex)
+
+  @JvmOverloads
+  actual fun lastIndexOf(other: ByteString, fromIndex: Int) = commonLastIndexOf(other, fromIndex)
+
+  @JvmOverloads
+  actual open fun lastIndexOf(other: ByteArray, fromIndex: Int) = commonLastIndexOf(other, fromIndex)
+
+  actual override fun equals(other: Any?) = commonEquals(other)
+
+  actual override fun hashCode() = commonHashCode()
+
+  actual override fun compareTo(other: ByteString) = commonCompareTo(other)
+
+  actual override fun toString() = commonToString()
+
+  @Throws(IOException::class)
+  private fun readObject(`in`: ObjectInputStream) {
+    val dataLength = `in`.readInt()
+    val byteString = `in`.readByteString(dataLength)
+    val field = ByteString::class.java.getDeclaredField("data")
+    field.isAccessible = true
+    field.set(this, byteString.data)
+  }
+
+  @Throws(IOException::class)
+  private fun writeObject(out: ObjectOutputStream) {
+    out.writeInt(data.size)
+    out.write(data)
+  }
+
+  @JvmName("-deprecated_getByte")
+  @Deprecated(
+    message = "moved to operator function",
+    replaceWith = ReplaceWith(expression = "this[index]"),
+    level = DeprecationLevel.ERROR
+  )
+  fun getByte(index: Int) = this[index]
+
+  @JvmName("-deprecated_size")
+  @Deprecated(
+    message = "moved to val",
+    replaceWith = ReplaceWith(expression = "size"),
+    level = DeprecationLevel.ERROR
+  )
+  fun size() = size
+
+  actual companion object {
+    private const val serialVersionUID = 1L
+
+    @JvmField
+    actual val EMPTY: ByteString = ByteString(byteArrayOf())
+
+    @JvmStatic
+    actual fun of(vararg data: Byte) = commonOf(data)
+
+    @JvmStatic
+    @JvmName("of")
+    actual fun ByteArray.toByteString(offset: Int, byteCount: Int): ByteString =
+      commonToByteString(offset, byteCount)
+
+    /** Returns a [ByteString] containing a copy of this [ByteBuffer]. */
+    @JvmStatic
+    @JvmName("of")
+    fun ByteBuffer.toByteString(): ByteString {
+      val copy = ByteArray(remaining())
+      get(copy)
+      return ByteString(copy)
+    }
+
+    @JvmStatic
+    actual fun String.encodeUtf8(): ByteString = commonEncodeUtf8()
+
+    /** Returns a new [ByteString] containing the `charset`-encoded bytes of this [String].  */
+    @JvmStatic
+    @JvmName("encodeString")
+    fun String.encode(charset: Charset = Charsets.UTF_8) = ByteString(toByteArray(charset))
+
+    @JvmStatic
+    actual fun String.decodeBase64() = commonDecodeBase64()
+
+    @JvmStatic
+    actual fun String.decodeHex() = commonDecodeHex()
+
+    /**
+     * Reads `count` bytes from this [InputStream] and returns the result.
+     *
+     * @throws java.io.EOFException if `in` has fewer than `count` bytes to read.
+     */
+    @Throws(IOException::class)
+    @JvmStatic
+    @JvmName("read")
+    fun InputStream.readByteString(byteCount: Int): ByteString {
+      require(byteCount >= 0) { "byteCount < 0: $byteCount" }
+
+      val result = ByteArray(byteCount)
+      var offset = 0
+      var read: Int
+      while (offset < byteCount) {
+        read = read(result, offset, byteCount - offset)
+        if (read == -1) throw EOFException()
+        offset += read
+      }
+      return ByteString(result)
+    }
+
+    @JvmName("-deprecated_decodeBase64")
+    @Deprecated(
+      message = "moved to extension function",
+      replaceWith = ReplaceWith(
+        expression = "string.decodeBase64()",
+        imports = ["okio.ByteString.Companion.decodeBase64"]
+      ),
+      level = DeprecationLevel.ERROR
+    )
+    fun decodeBase64(string: String) = string.decodeBase64()
+
+    @JvmName("-deprecated_decodeHex")
+    @Deprecated(
+      message = "moved to extension function",
+      replaceWith = ReplaceWith(
+        expression = "string.decodeHex()",
+        imports = ["okio.ByteString.Companion.decodeHex"]
+      ),
+      level = DeprecationLevel.ERROR
+    )
+    fun decodeHex(string: String) = string.decodeHex()
+
+    @JvmName("-deprecated_encodeString")
+    @Deprecated(
+      message = "moved to extension function",
+      replaceWith = ReplaceWith(
+        expression = "string.encode(charset)",
+        imports = ["okio.ByteString.Companion.encode"]
+      ),
+      level = DeprecationLevel.ERROR
+    )
+    fun encodeString(string: String, charset: Charset) = string.encode(charset)
+
+    @JvmName("-deprecated_encodeUtf8")
+    @Deprecated(
+      message = "moved to extension function",
+      replaceWith = ReplaceWith(
+        expression = "string.encodeUtf8()",
+        imports = ["okio.ByteString.Companion.encodeUtf8"]
+      ),
+      level = DeprecationLevel.ERROR
+    )
+    fun encodeUtf8(string: String) = string.encodeUtf8()
+
+    @JvmName("-deprecated_of")
+    @Deprecated(
+      message = "moved to extension function",
+      replaceWith = ReplaceWith(
+        expression = "buffer.toByteString()",
+        imports = ["okio.ByteString.Companion.toByteString"]
+      ),
+      level = DeprecationLevel.ERROR
+    )
+    fun of(buffer: ByteBuffer) = buffer.toByteString()
+
+    @JvmName("-deprecated_of")
+    @Deprecated(
+      message = "moved to extension function",
+      replaceWith = ReplaceWith(
+        expression = "array.toByteString(offset, byteCount)",
+        imports = ["okio.ByteString.Companion.toByteString"]
+      ),
+      level = DeprecationLevel.ERROR
+    )
+    fun of(array: ByteArray, offset: Int, byteCount: Int) = array.toByteString(offset, byteCount)
+
+    @JvmName("-deprecated_read")
+    @Deprecated(
+      message = "moved to extension function",
+      replaceWith = ReplaceWith(
+        expression = "inputstream.readByteString(byteCount)",
+        imports = ["okio.ByteString.Companion.readByteString"]
+      ),
+      level = DeprecationLevel.ERROR
+    )
+    fun read(inputstream: InputStream, byteCount: Int) = inputstream.readByteString(byteCount)
+  }
+}
diff --git a/okio/src/jvmMain/kotlin/okio/CipherSink.kt b/okio/src/jvmMain/kotlin/okio/CipherSink.kt
new file mode 100644
index 0000000..aa48284
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/CipherSink.kt
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2020 Square, Inc. and others.
+ *
+ * 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 okio
+
+import java.io.IOException
+import javax.crypto.Cipher
+
+class CipherSink(
+  private val sink: BufferedSink,
+  val cipher: Cipher
+) : Sink {
+  private val blockSize = cipher.blockSize
+  private var closed = false
+
+  init {
+    // Require block cipher
+    require(blockSize > 0) { "Block cipher required $cipher" }
+  }
+
+  @Throws(IOException::class)
+  override fun write(source: Buffer, byteCount: Long) {
+    checkOffsetAndCount(source.size, 0, byteCount)
+    check(!closed) { "closed" }
+
+    var remaining = byteCount
+    while (remaining > 0) {
+      val size = update(source, remaining)
+      remaining -= size
+    }
+  }
+
+  private fun update(source: Buffer, remaining: Long): Int {
+    val head = source.head!!
+    var size = minOf(remaining, head.limit - head.pos).toInt()
+    val buffer = sink.buffer
+
+    // Shorten input until output is guaranteed to fit within a segment
+    var outputSize = cipher.getOutputSize(size)
+    while (outputSize > Segment.SIZE) {
+      check(size > blockSize) { "Unexpected output size $outputSize for input size $size" }
+      size -= blockSize
+      outputSize = cipher.getOutputSize(size)
+    }
+    val s = buffer.writableSegment(outputSize)
+
+    val ciphered = cipher.update(head.data, head.pos, size, s.data, s.limit)
+
+    s.limit += ciphered
+    buffer.size += ciphered
+
+    // We allocated a tail segment, but didn't end up needing it. Recycle!
+    if (s.pos == s.limit) {
+      buffer.head = s.pop()
+      SegmentPool.recycle(s)
+    }
+
+    sink.emitCompleteSegments()
+
+    // Mark those bytes as read.
+    source.size -= size
+    head.pos += size
+    if (head.pos == head.limit) {
+      source.head = head.pop()
+      SegmentPool.recycle(head)
+    }
+
+    return size
+  }
+
+  override fun flush() = sink.flush()
+
+  override fun timeout() = sink.timeout()
+
+  @Throws(IOException::class)
+  override fun close() {
+    if (closed) return
+    closed = true
+
+    var thrown = doFinal()
+
+    try {
+      sink.close()
+    } catch (e: Throwable) {
+      if (thrown == null) thrown = e
+    }
+
+    if (thrown != null) throw thrown
+  }
+
+  private fun doFinal(): Throwable? {
+    val outputSize = cipher.getOutputSize(0)
+    if (outputSize == 0) return null
+
+    var thrown: Throwable? = null
+    val buffer = sink.buffer
+
+    // For block cipher, output size cannot exceed block size in doFinal
+    val s = buffer.writableSegment(outputSize)
+
+    try {
+      val ciphered = cipher.doFinal(s.data, s.limit)
+
+      s.limit += ciphered
+      buffer.size += ciphered
+    } catch (e: Throwable) {
+      thrown = e
+    }
+
+    if (s.pos == s.limit) {
+      buffer.head = s.pop()
+      SegmentPool.recycle(s)
+    }
+
+    return thrown
+  }
+}
diff --git a/okio/src/jvmMain/kotlin/okio/CipherSource.kt b/okio/src/jvmMain/kotlin/okio/CipherSource.kt
new file mode 100644
index 0000000..154371f
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/CipherSource.kt
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2020 Square, Inc. and others.
+ *
+ * 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 okio
+
+import java.io.IOException
+import javax.crypto.Cipher
+
+class CipherSource(
+  private val source: BufferedSource,
+  val cipher: Cipher
+) : Source {
+  private val blockSize = cipher.blockSize
+  private val buffer = Buffer()
+  private var final = false
+  private var closed = false
+
+  init {
+    // Require block cipher
+    require(blockSize > 0) { "Block cipher required $cipher" }
+  }
+
+  @Throws(IOException::class)
+  override fun read(sink: Buffer, byteCount: Long): Long {
+    require(byteCount >= 0L) { "byteCount < 0: $byteCount" }
+    check(!closed) { "closed" }
+    if (byteCount == 0L) return 0L
+    if (final) return buffer.read(sink, byteCount)
+
+    refill()
+
+    return buffer.read(sink, byteCount)
+  }
+
+  private fun refill() {
+    while (buffer.size == 0L) {
+      if (source.exhausted()) {
+        final = true
+        doFinal()
+        break
+      } else {
+        update()
+      }
+    }
+  }
+
+  private fun update() {
+    val head = source.buffer.head!!
+    var size = head.limit - head.pos
+
+    // Shorten input until output is guaranteed to fit within a segment
+    var outputSize = cipher.getOutputSize(size)
+    while (outputSize > Segment.SIZE) {
+      check(size > blockSize) { "Unexpected output size $outputSize for input size $size" }
+      size -= blockSize
+      outputSize = cipher.getOutputSize(size)
+    }
+    val s = buffer.writableSegment(outputSize)
+
+    val ciphered =
+      cipher.update(head.data, head.pos, size, s.data, s.pos)
+
+    source.skip(size.toLong())
+
+    s.limit += ciphered
+    buffer.size += ciphered
+
+    // We allocated a tail segment, but didn't end up needing it. Recycle!
+    if (s.pos == s.limit) {
+      buffer.head = s.pop()
+      SegmentPool.recycle(s)
+    }
+  }
+
+  private fun doFinal() {
+    val outputSize = cipher.getOutputSize(0)
+    if (outputSize == 0) return
+
+    // For block cipher, output size cannot exceed block size in doFinal.
+    val s = buffer.writableSegment(outputSize)
+
+    val ciphered = cipher.doFinal(s.data, s.pos)
+
+    s.limit += ciphered
+    buffer.size += ciphered
+
+    // We allocated a tail segment, but didn't end up needing it. Recycle!
+    if (s.pos == s.limit) {
+      buffer.head = s.pop()
+      SegmentPool.recycle(s)
+    }
+  }
+
+  override fun timeout() = source.timeout()
+
+  @Throws(IOException::class)
+  override fun close() {
+    closed = true
+    source.close()
+  }
+}
diff --git a/okio/src/jvmMain/kotlin/okio/DeflaterSink.kt b/okio/src/jvmMain/kotlin/okio/DeflaterSink.kt
new file mode 100644
index 0000000..e71cdff
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/DeflaterSink.kt
@@ -0,0 +1,161 @@
+/*
+ * 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.
+ */
+
+@file:JvmName("-DeflaterSinkExtensions")
+@file:Suppress("NOTHING_TO_INLINE") // Aliases to public API.
+
+package okio
+
+import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
+import java.io.IOException
+import java.util.zip.Deflater
+
+/**
+ * A sink that uses [DEFLATE](http://tools.ietf.org/html/rfc1951) to
+ * compress data written to another source.
+ *
+ * ### Sync flush
+ *
+ * Aggressive flushing of this stream may result in reduced compression. Each
+ * call to [flush] immediately compresses all currently-buffered data;
+ * this early compression may be less effective than compression performed
+ * without flushing.
+ *
+ * This is equivalent to using [Deflater] with the sync flush option.
+ * This class does not offer any partial flush mechanism. For best performance,
+ * only call [flush] when application behavior requires it.
+ */
+class DeflaterSink
+/**
+ * This internal 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.
+ */
+internal constructor(private val sink: BufferedSink, private val deflater: Deflater) : Sink {
+  constructor(sink: Sink, deflater: Deflater) : this(sink.buffer(), deflater)
+
+  private var closed = false
+
+  @Throws(IOException::class)
+  override fun write(source: Buffer, byteCount: Long) {
+    checkOffsetAndCount(source.size, 0, byteCount)
+
+    var remaining = byteCount
+    while (remaining > 0) {
+      // Share bytes from the head segment of 'source' with the deflater.
+      val head = source.head!!
+      val toDeflate = minOf(remaining, head.limit - head.pos).toInt()
+      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)
+      }
+
+      remaining -= toDeflate
+    }
+  }
+
+  @IgnoreJRERequirement
+  private fun deflate(syncFlush: Boolean) {
+    val buffer = sink.buffer
+    while (true) {
+      val 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.
+      val deflated = if (syncFlush) {
+        deflater.deflate(s.data, s.limit, Segment.SIZE - s.limit, Deflater.SYNC_FLUSH)
+      } else {
+        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
+      }
+    }
+  }
+
+  @Throws(IOException::class)
+  override fun flush() {
+    deflate(true)
+    sink.flush()
+  }
+
+  internal fun finishDeflate() {
+    deflater.finish()
+    deflate(false)
+  }
+
+  @Throws(IOException::class)
+  override fun close() {
+    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.
+    var thrown: Throwable? = null
+    try {
+      finishDeflate()
+    } catch (e: Throwable) {
+      thrown = e
+    }
+
+    try {
+      deflater.end()
+    } catch (e: Throwable) {
+      if (thrown == null) thrown = e
+    }
+
+    try {
+      sink.close()
+    } catch (e: Throwable) {
+      if (thrown == null) thrown = e
+    }
+
+    closed = true
+
+    if (thrown != null) throw thrown
+  }
+
+  override fun timeout(): Timeout = sink.timeout()
+
+  override fun toString() = "DeflaterSink($sink)"
+}
+
+/**
+ * Returns an [DeflaterSink] that DEFLATE-compresses data to this [Sink] while writing.
+ *
+ * @see DeflaterSink
+ */
+inline fun Sink.deflate(deflater: Deflater = Deflater()): DeflaterSink =
+  DeflaterSink(this, deflater)
diff --git a/okio/src/jvmMain/kotlin/okio/ForwardingSink.kt b/okio/src/jvmMain/kotlin/okio/ForwardingSink.kt
new file mode 100644
index 0000000..8f0eb2f
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/ForwardingSink.kt
@@ -0,0 +1,48 @@
+/*
+ * 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 okio
+
+import java.io.IOException
+
+/** A [Sink] which forwards calls to another. Useful for subclassing. */
+abstract class ForwardingSink(
+  /** [Sink] to which this instance is delegating. */
+  @get:JvmName("delegate")
+  val delegate: Sink
+) : Sink {
+  // TODO 'Sink by delegate' once https://youtrack.jetbrains.com/issue/KT-23935 is fixed.
+
+  @Throws(IOException::class)
+  override fun write(source: Buffer, byteCount: Long) = delegate.write(source, byteCount)
+
+  @Throws(IOException::class)
+  override fun flush() = delegate.flush()
+
+  override fun timeout() = delegate.timeout()
+
+  @Throws(IOException::class)
+  override fun close() = delegate.close()
+
+  override fun toString() = "${javaClass.simpleName}($delegate)"
+
+  @JvmName("-deprecated_delegate")
+  @Deprecated(
+    message = "moved to val",
+    replaceWith = ReplaceWith(expression = "delegate"),
+    level = DeprecationLevel.ERROR
+  )
+  fun delegate() = delegate
+}
diff --git a/okio/src/jvmMain/kotlin/okio/ForwardingSource.kt b/okio/src/jvmMain/kotlin/okio/ForwardingSource.kt
new file mode 100644
index 0000000..30a47f6
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/ForwardingSource.kt
@@ -0,0 +1,45 @@
+/*
+ * 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 okio
+
+import java.io.IOException
+
+/** A [Source] which forwards calls to another. Useful for subclassing. */
+abstract class ForwardingSource(
+  /** [Source] to which this instance is delegating. */
+  @get:JvmName("delegate")
+  val delegate: Source
+) : Source {
+  // TODO 'Source by delegate' once https://youtrack.jetbrains.com/issue/KT-23935 is fixed.
+
+  @Throws(IOException::class)
+  override fun read(sink: Buffer, byteCount: Long): Long = delegate.read(sink, byteCount)
+
+  override fun timeout() = delegate.timeout()
+
+  @Throws(IOException::class)
+  override fun close() = delegate.close()
+
+  override fun toString() = "${javaClass.simpleName}($delegate)"
+
+  @JvmName("-deprecated_delegate")
+  @Deprecated(
+    message = "moved to val",
+    replaceWith = ReplaceWith(expression = "delegate"),
+    level = DeprecationLevel.ERROR
+  )
+  fun delegate() = delegate
+}
diff --git a/okio/src/jvmMain/kotlin/okio/ForwardingTimeout.kt b/okio/src/jvmMain/kotlin/okio/ForwardingTimeout.kt
new file mode 100644
index 0000000..23d83aa
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/ForwardingTimeout.kt
@@ -0,0 +1,52 @@
+/*
+ * 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 okio
+
+import java.io.IOException
+import java.util.concurrent.TimeUnit
+
+/** A [Timeout] which forwards calls to another. Useful for subclassing.  */
+open class ForwardingTimeout(
+  @get:JvmName("delegate")
+  @set:JvmSynthetic // So .java callers get the setter that returns this.
+  var delegate: Timeout
+) : Timeout() {
+
+  // For backwards compatibility with Okio 1.x, this exists so it can return `ForwardingTimeout`.
+  fun setDelegate(delegate: Timeout): ForwardingTimeout {
+    this.delegate = delegate
+    return this
+  }
+
+  override fun timeout(timeout: Long, unit: TimeUnit) = delegate.timeout(timeout, unit)
+
+  override fun timeoutNanos() = delegate.timeoutNanos()
+
+  override fun hasDeadline() = delegate.hasDeadline()
+
+  override fun deadlineNanoTime() = delegate.deadlineNanoTime()
+
+  override fun deadlineNanoTime(deadlineNanoTime: Long) = delegate.deadlineNanoTime(
+    deadlineNanoTime
+  )
+
+  override fun clearTimeout() = delegate.clearTimeout()
+
+  override fun clearDeadline() = delegate.clearDeadline()
+
+  @Throws(IOException::class)
+  override fun throwIfReached() = delegate.throwIfReached()
+}
diff --git a/okio/src/jvmMain/kotlin/okio/GzipSink.kt b/okio/src/jvmMain/kotlin/okio/GzipSink.kt
new file mode 100644
index 0000000..db87daf
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/GzipSink.kt
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+@file:JvmName("-GzipSinkExtensions")
+@file:Suppress("NOTHING_TO_INLINE") // Aliases to public API.
+
+package okio
+
+import java.io.IOException
+import java.util.zip.CRC32
+import java.util.zip.Deflater
+import java.util.zip.Deflater.DEFAULT_COMPRESSION
+
+/**
+ * A sink that uses [GZIP](http://www.ietf.org/rfc/rfc1952.txt) to
+ * compress written data to another sink.
+ *
+ * ### Sync flush
+ *
+ * Aggressive flushing of this stream may result in reduced compression. Each
+ * call to [flush] immediately compresses all currently-buffered data;
+ * this early compression may be less effective than compression performed
+ * without flushing.
+ *
+ * This is equivalent to using [Deflater] with the sync flush option.
+ * This class does not offer any partial flush mechanism. For best performance,
+ * only call [flush] when application behavior requires it.
+ */
+class GzipSink(sink: Sink) : Sink {
+  /** Sink into which the GZIP format is written. */
+  private val sink = RealBufferedSink(sink)
+
+  /** The deflater used to compress the body. */
+  @get:JvmName("deflater")
+  val deflater = Deflater(DEFAULT_COMPRESSION, true /* No wrap */)
+
+  /**
+   * The deflater sink takes care of moving data between decompressed source and
+   * compressed sink buffers.
+   */
+  private val deflaterSink = DeflaterSink(this.sink, deflater)
+
+  private var closed = false
+
+  /** Checksum calculated for the compressed body. */
+  private val crc = CRC32()
+
+  init {
+    // Write the Gzip header directly into the buffer for the sink to avoid handling IOException.
+    this.sink.buffer.apply {
+      writeShort(0x1f8b) // Two-byte Gzip ID.
+      writeByte(0x08) // 8 == Deflate compression method.
+      writeByte(0x00) // No flags.
+      writeInt(0x00) // No modification time.
+      writeByte(0x00) // No extra flags.
+      writeByte(0x00) // No OS.
+    }
+  }
+
+  @Throws(IOException::class)
+  override fun write(source: Buffer, byteCount: Long) {
+    require(byteCount >= 0L) { "byteCount < 0: $byteCount" }
+    if (byteCount == 0L) return
+
+    updateCrc(source, byteCount)
+    deflaterSink.write(source, byteCount)
+  }
+
+  @Throws(IOException::class)
+  override fun flush() = deflaterSink.flush()
+
+  override fun timeout(): Timeout = sink.timeout()
+
+  @Throws(IOException::class)
+  override fun close() {
+    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.
+
+    var thrown: Throwable? = null
+    try {
+      deflaterSink.finishDeflate()
+      writeFooter()
+    } catch (e: Throwable) {
+      thrown = e
+    }
+
+    try {
+      deflater.end()
+    } catch (e: Throwable) {
+      if (thrown == null) thrown = e
+    }
+
+    try {
+      sink.close()
+    } catch (e: Throwable) {
+      if (thrown == null) thrown = e
+    }
+
+    closed = true
+
+    if (thrown != null) throw thrown
+  }
+
+  private fun writeFooter() {
+    sink.writeIntLe(crc.value.toInt()) // CRC of original data.
+    sink.writeIntLe(deflater.bytesRead.toInt()) // Length of original data.
+  }
+
+  /** Updates the CRC with the given bytes. */
+  private fun updateCrc(buffer: Buffer, byteCount: Long) {
+    var head = buffer.head!!
+    var remaining = byteCount
+    while (remaining > 0) {
+      val segmentLength = minOf(remaining, head.limit - head.pos).toInt()
+      crc.update(head.data, head.pos, segmentLength)
+      remaining -= segmentLength
+      head = head.next!!
+    }
+  }
+
+  @JvmName("-deprecated_deflater")
+  @Deprecated(
+    message = "moved to val",
+    replaceWith = ReplaceWith(expression = "deflater"),
+    level = DeprecationLevel.ERROR
+  )
+  fun deflater() = deflater
+}
+
+/**
+ * Returns a [GzipSink] that gzip-compresses to this [Sink] while writing.
+ *
+ * @see GzipSource
+ */
+inline fun Sink.gzip() = GzipSink(this)
diff --git a/okio/src/jvmMain/kotlin/okio/GzipSource.kt b/okio/src/jvmMain/kotlin/okio/GzipSource.kt
new file mode 100644
index 0000000..ff1e3d3
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/GzipSource.kt
@@ -0,0 +1,219 @@
+/*
+ * 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.
+ */
+
+@file:JvmName("-GzipSourceExtensions")
+@file:Suppress("NOTHING_TO_INLINE") // Aliases to public API.
+
+package okio
+
+import java.io.EOFException
+import java.io.IOException
+import java.util.zip.CRC32
+import java.util.zip.Inflater
+
+/**
+ * A source that uses [GZIP](http://www.ietf.org/rfc/rfc1952.txt) to
+ * decompress data read from another source.
+ */
+class GzipSource(source: Source) : Source {
+
+  /** The current section. Always progresses forward. */
+  private var 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 val source = RealBufferedSource(source)
+
+  /** The inflater used to decompress the deflated body. */
+  private val inflater = Inflater(true)
+
+  /**
+   * The inflater source takes care of moving data between compressed source and
+   * decompressed sink buffers.
+   */
+  private val inflaterSource = InflaterSource(this.source, inflater)
+
+  /** Checksum used to check both the GZIP header and decompressed body. */
+  private val crc = CRC32()
+
+  @Throws(IOException::class)
+  override fun read(sink: Buffer, byteCount: Long): Long {
+    require(byteCount >= 0L) { "byteCount < 0: $byteCount" }
+    if (byteCount == 0L) return 0L
+
+    // 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) {
+      val offset = sink.size
+      val result = inflaterSource.read(sink, byteCount)
+      if (result != -1L) {
+        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 IOException("gzip finished without exhausting source")
+      }
+    }
+
+    return -1
+  }
+
+  @Throws(IOException::class)
+  private fun consumeHeader() {
+    // 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)
+    val flags = source.buffer[3].toInt()
+    val fhcrc = flags.getBit(FHCRC)
+    if (fhcrc) updateCrc(source.buffer, 0, 10)
+
+    val id1id2 = source.readShort()
+    checkEqual("ID1ID2", 0x1f8b, id1id2.toInt())
+    source.skip(8)
+
+    // Skip optional extra fields.
+    // +---+---+=================================+
+    // | XLEN  |...XLEN bytes of "extra field"...| (more-->)
+    // +---+---+=================================+
+    if (flags.getBit(FEXTRA)) {
+      source.require(2)
+      if (fhcrc) updateCrc(source.buffer, 0, 2)
+      val xlen = source.buffer.readShortLe().toLong()
+      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.getBit(FNAME)) {
+      val index = source.indexOf(0)
+      if (index == -1L) throw 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.getBit(FCOMMENT)) {
+      val index = source.indexOf(0)
+      if (index == -1L) throw 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().toInt(), crc.value.toShort().toInt())
+      crc.reset()
+    }
+  }
+
+  @Throws(IOException::class)
+  private fun consumeTrailer() {
+    // Read the eight-byte trailer. Confirm the body's CRC and size.
+    // +---+---+---+---+---+---+---+---+
+    // |     CRC32     |     ISIZE     |
+    // +---+---+---+---+---+---+---+---+
+    checkEqual("CRC", source.readIntLe(), crc.value.toInt())
+    checkEqual("ISIZE", source.readIntLe(), inflater.bytesWritten.toInt())
+  }
+
+  override fun timeout(): Timeout = source.timeout()
+
+  @Throws(IOException::class)
+  override fun close() = inflaterSource.close()
+
+  /** Updates the CRC with the given bytes.  */
+  private fun updateCrc(buffer: Buffer, offset: Long, byteCount: Long) {
+    var offset = offset
+    var byteCount = byteCount
+    // Skip segments that we aren't checksumming.
+    var s = buffer.head!!
+    while (offset >= s.limit - s.pos) {
+      offset -= s.limit - s.pos
+      s = s.next!!
+    }
+
+    // Checksum one segment at a time.
+    while (byteCount > 0) {
+      val pos = (s.pos + offset).toInt()
+      val toUpdate = minOf(s.limit - pos, byteCount).toInt()
+      crc.update(s.data, pos, toUpdate)
+      byteCount -= toUpdate
+      offset = 0
+      s = s.next!!
+    }
+  }
+
+  private fun checkEqual(name: String, expected: Int, actual: Int) {
+    if (actual != expected) {
+      throw IOException("%s: actual 0x%08x != expected 0x%08x".format(name, actual, expected))
+    }
+  }
+}
+
+private inline fun Int.getBit(bit: Int) = this shr bit and 1 == 1
+
+private const val FHCRC = 1
+private const val FEXTRA = 2
+private const val FNAME = 3
+private const val FCOMMENT = 4
+
+private const val SECTION_HEADER: Byte = 0
+private const val SECTION_BODY: Byte = 1
+private const val SECTION_TRAILER: Byte = 2
+private const val SECTION_DONE: Byte = 3
+
+/**
+ * Returns a [GzipSource] that gzip-decompresses this [Source] while reading.
+ *
+ * @see GzipSource
+ */
+inline fun Source.gzip() = GzipSource(this)
diff --git a/okio/src/jvmMain/kotlin/okio/HashingSink.kt b/okio/src/jvmMain/kotlin/okio/HashingSink.kt
new file mode 100644
index 0000000..36bfd2b
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/HashingSink.kt
@@ -0,0 +1,139 @@
+/*
+ * 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 okio
+
+import java.io.IOException
+import java.security.InvalidKeyException
+import java.security.MessageDigest
+import javax.crypto.Mac
+import javax.crypto.spec.SecretKeySpec
+
+/**
+ * A sink that computes a hash of the full stream of bytes it has accepted. To use, create an
+ * instance with your preferred hash algorithm. Write all of the data to the sink and then call
+ * [hash] to compute the final hash value.
+ *
+ * In this example we use `HashingSink` with a [BufferedSink] to make writing to the
+ * sink easier.
+ * ```
+ * HashingSink hashingSink = HashingSink.sha256(s);
+ * BufferedSink bufferedSink = Okio.buffer(hashingSink);
+ *
+ * ... // Write to bufferedSink and either flush or close it.
+ *
+ * ByteString hash = hashingSink.hash();
+ * ```
+ */
+actual class HashingSink : ForwardingSink, Sink { // Need to explicitly declare sink pending fix for https://youtrack.jetbrains.com/issue/KT-20641
+  private val messageDigest: MessageDigest?
+  private val mac: Mac?
+
+  internal constructor(sink: Sink, digest: MessageDigest) : super(sink) {
+    this.messageDigest = digest
+    this.mac = null
+  }
+
+  internal constructor(sink: Sink, algorithm: String) : this(sink, MessageDigest.getInstance(algorithm))
+
+  internal constructor(sink: Sink, mac: Mac) : super(sink) {
+    this.mac = mac
+    this.messageDigest = null
+  }
+
+  internal constructor(sink: Sink, key: ByteString, algorithm: String) : this(
+    sink,
+    try {
+      Mac.getInstance(algorithm).apply {
+        init(SecretKeySpec(key.toByteArray(), algorithm))
+      }
+    } catch (e: InvalidKeyException) {
+      throw IllegalArgumentException(e)
+    }
+  )
+
+  @Throws(IOException::class)
+  override fun write(source: Buffer, byteCount: Long) {
+    checkOffsetAndCount(source.size, 0, byteCount)
+
+    // Hash byteCount bytes from the prefix of source.
+    var hashedCount = 0L
+    var s = source.head!!
+    while (hashedCount < byteCount) {
+      val toHash = minOf(byteCount - hashedCount, s.limit - s.pos).toInt()
+      if (messageDigest != null) {
+        messageDigest.update(s.data, s.pos, toHash)
+      } else {
+        mac!!.update(s.data, s.pos, toHash)
+      }
+      hashedCount += toHash
+      s = s.next!!
+    }
+
+    // Write those bytes to the sink.
+    super.write(source, byteCount)
+  }
+
+  /**
+   * Returns the hash of the bytes accepted thus far and resets the internal state of this sink.
+   *
+   * **Warning:** This method is not idempotent. Each time this method is called its
+   * internal state is cleared. This starts a new hash with zero bytes accepted.
+   */
+  @get:JvmName("hash")
+  actual val hash: ByteString
+    get() {
+      val result = if (messageDigest != null) messageDigest.digest() else mac!!.doFinal()
+      return ByteString(result)
+    }
+
+  @JvmName("-deprecated_hash")
+  @Deprecated(
+    message = "moved to val",
+    replaceWith = ReplaceWith(expression = "hash"),
+    level = DeprecationLevel.ERROR
+  )
+  fun hash() = hash
+
+  actual companion object {
+    /** Returns a sink that uses the obsolete MD5 hash algorithm to produce 128-bit hashes. */
+    @JvmStatic
+    actual fun md5(sink: Sink) = HashingSink(sink, "MD5")
+
+    /** Returns a sink that uses the obsolete SHA-1 hash algorithm to produce 160-bit hashes. */
+    @JvmStatic
+    actual fun sha1(sink: Sink) = HashingSink(sink, "SHA-1")
+
+    /** Returns a sink that uses the SHA-256 hash algorithm to produce 256-bit hashes. */
+    @JvmStatic
+    actual fun sha256(sink: Sink) = HashingSink(sink, "SHA-256")
+
+    /** Returns a sink that uses the SHA-512 hash algorithm to produce 512-bit hashes. */
+    @JvmStatic
+    actual fun sha512(sink: Sink) = HashingSink(sink, "SHA-512")
+
+    /** Returns a sink that uses the obsolete SHA-1 HMAC algorithm to produce 160-bit hashes. */
+    @JvmStatic
+    actual fun hmacSha1(sink: Sink, key: ByteString) = HashingSink(sink, key, "HmacSHA1")
+
+    /** Returns a sink that uses the SHA-256 HMAC algorithm to produce 256-bit hashes. */
+    @JvmStatic
+    actual fun hmacSha256(sink: Sink, key: ByteString) = HashingSink(sink, key, "HmacSHA256")
+
+    /** Returns a sink that uses the SHA-512 HMAC algorithm to produce 512-bit hashes. */
+    @JvmStatic
+    actual fun hmacSha512(sink: Sink, key: ByteString) = HashingSink(sink, key, "HmacSHA512")
+  }
+}
diff --git a/okio/src/jvmMain/kotlin/okio/HashingSource.kt b/okio/src/jvmMain/kotlin/okio/HashingSource.kt
new file mode 100644
index 0000000..25b695d
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/HashingSource.kt
@@ -0,0 +1,150 @@
+/*
+ * 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 okio
+
+import java.io.IOException
+import java.security.InvalidKeyException
+import java.security.MessageDigest
+import javax.crypto.Mac
+import javax.crypto.spec.SecretKeySpec
+
+/**
+ * A source that computes a hash of the full stream of bytes it has supplied. To use, create an
+ * instance with your preferred hash algorithm. Exhaust the source by reading all of its bytes and
+ * then call [hash] to compute the final hash value.
+ *
+ *
+ * In this example we use `HashingSource` with a [BufferedSource] to make reading
+ * from the source easier.
+ * ```
+ * HashingSource hashingSource = HashingSource.sha256(rawSource);
+ * BufferedSource bufferedSource = Okio.buffer(hashingSource);
+ *
+ * ... // Read all of bufferedSource.
+ *
+ * ByteString hash = hashingSource.hash();
+ * ```
+ */
+actual class HashingSource : ForwardingSource, Source { // Need to explicitly declare source pending fix for https://youtrack.jetbrains.com/issue/KT-20641
+  private val messageDigest: MessageDigest?
+  private val mac: Mac?
+
+  internal constructor(source: Source, digest: MessageDigest) : super(source) {
+    this.messageDigest = digest
+    this.mac = null
+  }
+
+  internal constructor(source: Source, algorithm: String) : this(source, MessageDigest.getInstance(algorithm))
+
+  internal constructor(source: Source, mac: Mac) : super(source) {
+    this.mac = mac
+    this.messageDigest = null
+  }
+
+  internal constructor(source: Source, key: ByteString, algorithm: String) : this(
+    source,
+    try {
+      Mac.getInstance(algorithm).apply {
+        init(SecretKeySpec(key.toByteArray(), algorithm))
+      }
+    } catch (e: InvalidKeyException) {
+      throw IllegalArgumentException(e)
+    }
+  )
+
+  @Throws(IOException::class)
+  override fun read(sink: Buffer, byteCount: Long): Long {
+    val result = super.read(sink, byteCount)
+
+    if (result != -1L) {
+      var start = sink.size - result
+
+      // Find the first segment that has new bytes.
+      var offset = sink.size
+      var s = sink.head!!
+      while (offset > start) {
+        s = s.prev!!
+        offset -= (s.limit - s.pos).toLong()
+      }
+
+      // Hash that segment and all the rest until the end.
+      while (offset < sink.size) {
+        val pos = (s.pos + start - offset).toInt()
+        if (messageDigest != null) {
+          messageDigest.update(s.data, pos, s.limit - pos)
+        } else {
+          mac!!.update(s.data, pos, s.limit - pos)
+        }
+        offset += s.limit - s.pos
+        start = offset
+        s = s.next!!
+      }
+    }
+
+    return result
+  }
+
+  /**
+   * Returns the hash of the bytes supplied thus far and resets the internal state of this source.
+   *
+   * **Warning:** This method is not idempotent. Each time this method is called its
+   * internal state is cleared. This starts a new hash with zero bytes supplied.
+   */
+  @get:JvmName("hash")
+  actual val hash: ByteString
+    get() {
+      val result = if (messageDigest != null) messageDigest.digest() else mac!!.doFinal()
+      return ByteString(result)
+    }
+
+  @JvmName("-deprecated_hash")
+  @Deprecated(
+    message = "moved to val",
+    replaceWith = ReplaceWith(expression = "hash"),
+    level = DeprecationLevel.ERROR
+  )
+  fun hash() = hash
+
+  actual companion object {
+    /** Returns a source that uses the obsolete MD5 hash algorithm to produce 128-bit hashes. */
+    @JvmStatic
+    actual fun md5(source: Source) = HashingSource(source, "MD5")
+
+    /** Returns a source that uses the obsolete SHA-1 hash algorithm to produce 160-bit hashes. */
+    @JvmStatic
+    actual fun sha1(source: Source) = HashingSource(source, "SHA-1")
+
+    /** Returns a source that uses the SHA-256 hash algorithm to produce 256-bit hashes. */
+    @JvmStatic
+    actual fun sha256(source: Source) = HashingSource(source, "SHA-256")
+
+    /** Returns a source that uses the SHA-512 hash algorithm to produce 512-bit hashes. */
+    @JvmStatic
+    actual fun sha512(source: Source) = HashingSource(source, "SHA-512")
+
+    /** Returns a source that uses the obsolete SHA-1 HMAC algorithm to produce 160-bit hashes. */
+    @JvmStatic
+    actual fun hmacSha1(source: Source, key: ByteString) = HashingSource(source, key, "HmacSHA1")
+
+    /** Returns a source that uses the SHA-256 HMAC algorithm to produce 256-bit hashes. */
+    @JvmStatic
+    actual fun hmacSha256(source: Source, key: ByteString) = HashingSource(source, key, "HmacSHA256")
+
+    /** Returns a source that uses the SHA-512 HMAC algorithm to produce 512-bit hashes. */
+    @JvmStatic
+    actual fun hmacSha512(source: Source, key: ByteString) = HashingSource(source, key, "HmacSHA512")
+  }
+}
diff --git a/okio/src/jvmMain/kotlin/okio/InflaterSource.kt b/okio/src/jvmMain/kotlin/okio/InflaterSource.kt
new file mode 100644
index 0000000..6fe1feb
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/InflaterSource.kt
@@ -0,0 +1,146 @@
+/*
+ * 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.
+ */
+
+@file:JvmName("-InflaterSourceExtensions")
+@file:Suppress("NOTHING_TO_INLINE") // Aliases to public API.
+
+package okio
+
+import java.io.IOException
+import java.util.zip.DataFormatException
+import java.util.zip.Inflater
+
+/**
+ * A source that uses [DEFLATE](http://tools.ietf.org/html/rfc1951) to decompress data read from
+ * another source.
+ */
+class InflaterSource
+/**
+ * This internal 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.
+ */
+internal constructor(private val source: BufferedSource, private val inflater: Inflater) : Source {
+
+  /**
+   * 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 var bufferBytesHeldByInflater = 0
+  private var closed = false
+
+  constructor(source: Source, inflater: Inflater) : this(source.buffer(), inflater)
+
+  @Throws(IOException::class)
+  override fun read(sink: Buffer, byteCount: Long): Long {
+    while (true) {
+      val bytesInflated = readOrInflate(sink, byteCount)
+      if (bytesInflated > 0) return bytesInflated
+      if (inflater.finished() || inflater.needsDictionary()) return -1L
+      if (source.exhausted()) throw EOFException("source exhausted prematurely")
+    }
+  }
+
+  /**
+   * Consume deflated bytes from the underlying source, and write any inflated bytes to [sink].
+   * Returns the number of inflated bytes written to [sink]. This may return 0L, though it will
+   * always consume 1 or more bytes from the underlying source if it is not exhausted.
+   *
+   * Use this instead of [read] when it is useful to consume the deflated stream even when doing so
+   * doesn't yield inflated bytes.
+   */
+  @Throws(IOException::class)
+  fun readOrInflate(sink: Buffer, byteCount: Long): Long {
+    require(byteCount >= 0L) { "byteCount < 0: $byteCount" }
+    check(!closed) { "closed" }
+    if (byteCount == 0L) return 0L
+
+    try {
+      // Prepare the destination that we'll write into.
+      val tail = sink.writableSegment(1)
+      val toRead = minOf(byteCount, Segment.SIZE - tail.limit).toInt()
+
+      // Prepare the source that we'll read from.
+      refill()
+
+      // Decompress the inflater's compressed data into the sink.
+      val bytesInflated = inflater.inflate(tail.data, tail.limit, toRead)
+
+      // Release consumed bytes from the source.
+      releaseBytesAfterInflate()
+
+      // Track produced bytes in the destination.
+      if (bytesInflated > 0) {
+        tail.limit += bytesInflated
+        sink.size += bytesInflated
+        return bytesInflated.toLong()
+      }
+
+      // We allocated a tail segment but didn't end up needing it. Recycle!
+      if (tail.pos == tail.limit) {
+        sink.head = tail.pop()
+        SegmentPool.recycle(tail)
+      }
+
+      return 0L
+    } catch (e: DataFormatException) {
+      throw 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.
+   */
+  @Throws(IOException::class)
+  fun refill(): Boolean {
+    if (!inflater.needsInput()) return false
+
+    // If there are no further bytes in the source, we cannot refill.
+    if (source.exhausted()) return true
+
+    // Assign buffer bytes to the inflater.
+    val 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 fun releaseBytesAfterInflate() {
+    if (bufferBytesHeldByInflater == 0) return
+    val toRelease = bufferBytesHeldByInflater - inflater.remaining
+    bufferBytesHeldByInflater -= toRelease
+    source.skip(toRelease.toLong())
+  }
+
+  override fun timeout(): Timeout = source.timeout()
+
+  @Throws(IOException::class)
+  override fun close() {
+    if (closed) return
+    inflater.end()
+    closed = true
+    source.close()
+  }
+}
+
+/**
+ * Returns an [InflaterSource] that DEFLATE-decompresses this [Source] while reading.
+ *
+ * @see InflaterSource
+ */
+inline fun Source.inflate(inflater: Inflater = Inflater()): InflaterSource =
+  InflaterSource(this, inflater)
diff --git a/okio/src/jvmMain/kotlin/okio/JvmOkio.kt b/okio/src/jvmMain/kotlin/okio/JvmOkio.kt
new file mode 100644
index 0000000..25d5516
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/JvmOkio.kt
@@ -0,0 +1,235 @@
+/*
+ * 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.
+ */
+
+/** Essential APIs for working with Okio. */
+@file:JvmMultifileClass
+@file:JvmName("Okio")
+
+package okio
+
+import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
+import java.io.File
+import java.io.FileNotFoundException
+import java.io.FileOutputStream
+import java.io.IOException
+import java.io.InputStream
+import java.io.OutputStream
+import java.net.Socket
+import java.net.SocketTimeoutException
+import java.nio.file.Files
+import java.nio.file.OpenOption
+import java.nio.file.Path
+import java.security.MessageDigest
+import java.util.logging.Level
+import java.util.logging.Logger
+import javax.crypto.Cipher
+import javax.crypto.Mac
+
+/** Returns a sink that writes to `out`. */
+fun OutputStream.sink(): Sink = OutputStreamSink(this, Timeout())
+
+private class OutputStreamSink(
+  private val out: OutputStream,
+  private val timeout: Timeout
+) : Sink {
+
+  override fun write(source: Buffer, byteCount: Long) {
+    checkOffsetAndCount(source.size, 0, byteCount)
+    var remaining = byteCount
+    while (remaining > 0) {
+      timeout.throwIfReached()
+      val head = source.head!!
+      val toCopy = minOf(remaining, head.limit - head.pos).toInt()
+      out.write(head.data, head.pos, toCopy)
+
+      head.pos += toCopy
+      remaining -= toCopy
+      source.size -= toCopy
+
+      if (head.pos == head.limit) {
+        source.head = head.pop()
+        SegmentPool.recycle(head)
+      }
+    }
+  }
+
+  override fun flush() = out.flush()
+
+  override fun close() = out.close()
+
+  override fun timeout() = timeout
+
+  override fun toString() = "sink($out)"
+}
+
+/** Returns a source that reads from `in`. */
+fun InputStream.source(): Source = InputStreamSource(this, Timeout())
+
+private class InputStreamSource(
+  private val input: InputStream,
+  private val timeout: Timeout
+) : Source {
+
+  override fun read(sink: Buffer, byteCount: Long): Long {
+    if (byteCount == 0L) return 0L
+    require(byteCount >= 0L) { "byteCount < 0: $byteCount" }
+    try {
+      timeout.throwIfReached()
+      val tail = sink.writableSegment(1)
+      val maxToCopy = minOf(byteCount, Segment.SIZE - tail.limit).toInt()
+      val bytesRead = input.read(tail.data, tail.limit, maxToCopy)
+      if (bytesRead == -1) {
+        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
+      }
+      tail.limit += bytesRead
+      sink.size += bytesRead
+      return bytesRead.toLong()
+    } catch (e: AssertionError) {
+      if (e.isAndroidGetsocknameError) throw IOException(e)
+      throw e
+    }
+  }
+
+  override fun close() = input.close()
+
+  override fun timeout() = timeout
+
+  override fun toString() = "source($input)"
+}
+
+/**
+ * Returns a sink that writes to `socket`. Prefer this over [sink]
+ * because this method honors timeouts. When the socket
+ * write times out, the socket is asynchronously closed by a watchdog thread.
+ */
+@Throws(IOException::class)
+fun Socket.sink(): Sink {
+  val timeout = SocketAsyncTimeout(this)
+  val sink = OutputStreamSink(getOutputStream(), timeout)
+  return timeout.sink(sink)
+}
+
+/**
+ * Returns a source that reads from `socket`. Prefer this over [source]
+ * because this method honors timeouts. When the socket
+ * read times out, the socket is asynchronously closed by a watchdog thread.
+ */
+@Throws(IOException::class)
+fun Socket.source(): Source {
+  val timeout = SocketAsyncTimeout(this)
+  val source = InputStreamSource(getInputStream(), timeout)
+  return timeout.source(source)
+}
+
+private val logger = Logger.getLogger("okio.Okio")
+
+private class SocketAsyncTimeout(private val socket: Socket) : AsyncTimeout() {
+  override fun newTimeoutException(cause: IOException?): IOException {
+    val ioe = SocketTimeoutException("timeout")
+    if (cause != null) {
+      ioe.initCause(cause)
+    }
+    return ioe
+  }
+
+  override fun timedOut() {
+    try {
+      socket.close()
+    } catch (e: Exception) {
+      logger.log(Level.WARNING, "Failed to close timed out socket $socket", e)
+    } catch (e: AssertionError) {
+      if (e.isAndroidGetsocknameError) {
+        // 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 a sink that writes to `file`. */
+@JvmOverloads
+@Throws(FileNotFoundException::class)
+fun File.sink(append: Boolean = false): Sink = FileOutputStream(this, append).sink()
+
+/** Returns a sink that writes to `file`. */
+@Throws(FileNotFoundException::class)
+fun File.appendingSink(): Sink = FileOutputStream(this, true).sink()
+
+/** Returns a source that reads from `file`. */
+@Throws(FileNotFoundException::class)
+fun File.source(): Source = inputStream().source()
+
+/** Returns a source that reads from `path`. */
+@Throws(IOException::class)
+@IgnoreJRERequirement // Can only be invoked on Java 7+.
+fun Path.sink(vararg options: OpenOption): Sink =
+  Files.newOutputStream(this, *options).sink()
+
+/** Returns a sink that writes to `path`. */
+@Throws(IOException::class)
+@IgnoreJRERequirement // Can only be invoked on Java 7+.
+fun Path.source(vararg options: OpenOption): Source =
+  Files.newInputStream(this, *options).source()
+
+/**
+ * Returns a sink that uses [cipher] to encrypt or decrypt [this].
+ *
+ * @throws IllegalArgumentException if [cipher] isn't a block cipher.
+ */
+fun Sink.cipherSink(cipher: Cipher): CipherSink = CipherSink(this.buffer(), cipher)
+
+/**
+ * Returns a source that uses [cipher] to encrypt or decrypt [this].
+ *
+ * @throws IllegalArgumentException if [cipher] isn't a block cipher.
+ */
+fun Source.cipherSource(cipher: Cipher): CipherSource = CipherSource(this.buffer(), cipher)
+
+/**
+ * Returns a sink that uses [mac] to hash [this].
+ */
+fun Sink.hashingSink(mac: Mac): HashingSink = HashingSink(this, mac)
+
+/**
+ * Returns a source that uses [mac] to hash [this].
+ */
+fun Source.hashingSource(mac: Mac): HashingSource = HashingSource(this, mac)
+
+/**
+ * Returns a sink that uses [digest] to hash [this].
+ */
+fun Sink.hashingSink(digest: MessageDigest): HashingSink = HashingSink(this, digest)
+
+/**
+ * Returns a source that uses [digest] to hash [this].
+ */
+fun Source.hashingSource(digest: MessageDigest): HashingSource = HashingSource(this, digest)
+
+/**
+ * Returns true if this error is due to a firmware bug fixed after Android 4.2.2.
+ * https://code.google.com/p/android/issues/detail?id=54072
+ */
+internal val AssertionError.isAndroidGetsocknameError: Boolean get() {
+  return cause != null && message?.contains("getsockname failed") ?: false
+}
diff --git a/okio/src/jvmMain/kotlin/okio/Pipe.kt b/okio/src/jvmMain/kotlin/okio/Pipe.kt
new file mode 100644
index 0000000..43c23bf
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/Pipe.kt
@@ -0,0 +1,249 @@
+/*
+ * 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 okio
+
+/**
+ * A source and a sink that are attached. The sink's output is the source's input. Typically each
+ * is accessed by its own thread: a producer thread writes data to the sink and a consumer thread
+ * reads data from the source.
+ *
+ * This class uses a buffer to decouple source and sink. This buffer has a user-specified maximum
+ * size. When a producer thread outruns its consumer the buffer fills up and eventually writes to
+ * the sink will block until the consumer has caught up. Symmetrically, if a consumer outruns its
+ * producer reads block until there is data to be read. Limits on the amount of time spent waiting
+ * for the other party can be configured with [timeouts][Timeout] on the source and the
+ * sink.
+ *
+ * When the sink is closed, source reads will continue to complete normally until the buffer has
+ * been exhausted. At that point reads will return -1, indicating the end of the stream. But if the
+ * source is closed first, writes to the sink will immediately fail with an [IOException].
+ *
+ * A pipe may be canceled to immediately fail writes to the sink and reads from the source.
+ */
+class Pipe(internal val maxBufferSize: Long) {
+  internal val buffer = Buffer()
+  internal var canceled = false
+  internal var sinkClosed = false
+  internal var sourceClosed = false
+  internal var foldedSink: Sink? = null
+
+  init {
+    require(maxBufferSize >= 1L) { "maxBufferSize < 1: $maxBufferSize" }
+  }
+
+  @get:JvmName("sink")
+  val sink = object : Sink {
+    private val timeout = Timeout()
+
+    override fun write(source: Buffer, byteCount: Long) {
+      var byteCount = byteCount
+      var delegate: Sink? = null
+      synchronized(buffer) {
+        check(!sinkClosed) { "closed" }
+        if (canceled) throw IOException("canceled")
+
+        while (byteCount > 0) {
+          foldedSink?.let {
+            delegate = it
+            return@synchronized
+          }
+
+          if (sourceClosed) throw IOException("source is closed")
+
+          val bufferSpaceAvailable = maxBufferSize - buffer.size
+          if (bufferSpaceAvailable == 0L) {
+            timeout.waitUntilNotified(buffer) // Wait until the source drains the buffer.
+            if (canceled) throw IOException("canceled")
+            continue
+          }
+
+          val bytesToWrite = minOf(bufferSpaceAvailable, byteCount)
+          buffer.write(source, bytesToWrite)
+          byteCount -= bytesToWrite
+          (buffer as Object).notifyAll() // Notify the source that it can resume reading.
+        }
+      }
+
+      delegate?.forward { write(source, byteCount) }
+    }
+
+    override fun flush() {
+      var delegate: Sink? = null
+      synchronized(buffer) {
+        check(!sinkClosed) { "closed" }
+        if (canceled) throw IOException("canceled")
+
+        foldedSink?.let {
+          delegate = it
+          return@synchronized
+        }
+
+        if (sourceClosed && buffer.size > 0L) {
+          throw IOException("source is closed")
+        }
+      }
+
+      delegate?.forward { flush() }
+    }
+
+    override fun close() {
+      var delegate: Sink? = null
+      synchronized(buffer) {
+        if (sinkClosed) return
+
+        foldedSink?.let {
+          delegate = it
+          return@synchronized
+        }
+
+        if (sourceClosed && buffer.size > 0L) throw IOException("source is closed")
+        sinkClosed = true
+        (buffer as Object).notifyAll() // Notify the source that no more bytes are coming.
+      }
+
+      delegate?.forward { close() }
+    }
+
+    override fun timeout(): Timeout = timeout
+  }
+
+  @get:JvmName("source")
+  val source = object : Source {
+    private val timeout = Timeout()
+
+    override fun read(sink: Buffer, byteCount: Long): Long {
+      synchronized(buffer) {
+        check(!sourceClosed) { "closed" }
+        if (canceled) throw IOException("canceled")
+
+        while (buffer.size == 0L) {
+          if (sinkClosed) return -1L
+          timeout.waitUntilNotified(buffer) // Wait until the sink fills the buffer.
+          if (canceled) throw IOException("canceled")
+        }
+
+        val result = buffer.read(sink, byteCount)
+        (buffer as Object).notifyAll() // Notify the sink that it can resume writing.
+        return result
+      }
+    }
+
+    override fun close() {
+      synchronized(buffer) {
+        sourceClosed = true
+        (buffer as Object).notifyAll() // Notify the sink that no more bytes are desired.
+      }
+    }
+
+    override fun timeout(): Timeout = timeout
+  }
+
+  /**
+   * Writes any buffered contents of this pipe to `sink`, then replace this pipe's source with
+   * `sink`. This pipe's source is closed and attempts to read it will throw an
+   * [IllegalStateException].
+   *
+   * This method must not be called while concurrently accessing this pipe's source. It is safe,
+   * however, to call this while concurrently writing this pipe's sink.
+   */
+  @Throws(IOException::class)
+  fun fold(sink: Sink) {
+    while (true) {
+      // Either the buffer is empty and we can swap and return. Or the buffer is non-empty and we
+      // must copy it to sink without holding any locks, then try it all again.
+      var closed = false
+      lateinit var sinkBuffer: Buffer
+      synchronized(buffer) {
+        check(foldedSink == null) { "sink already folded" }
+
+        if (canceled) {
+          foldedSink = sink
+          throw IOException("canceled")
+        }
+
+        if (buffer.exhausted()) {
+          sourceClosed = true
+          foldedSink = sink
+          return@fold
+        }
+
+        closed = sinkClosed
+        sinkBuffer = Buffer()
+        sinkBuffer.write(buffer, buffer.size)
+        (buffer as Object).notifyAll() // Notify the sink that it can resume writing.
+      }
+
+      var success = false
+      try {
+        sink.write(sinkBuffer, sinkBuffer.size)
+        if (closed) {
+          sink.close()
+        } else {
+          sink.flush()
+        }
+        success = true
+      } finally {
+        if (!success) {
+          synchronized(buffer) {
+            sourceClosed = true
+            (buffer as Object).notifyAll() // Notify the sink that it can resume writing.
+          }
+        }
+      }
+    }
+  }
+
+  private inline fun Sink.forward(block: Sink.() -> Unit) {
+    this.timeout().intersectWith(this@Pipe.sink.timeout()) { this.block() }
+  }
+
+  @JvmName("-deprecated_sink")
+  @Deprecated(
+    message = "moved to val",
+    replaceWith = ReplaceWith(expression = "sink"),
+    level = DeprecationLevel.ERROR
+  )
+  fun sink() = sink
+
+  @JvmName("-deprecated_source")
+  @Deprecated(
+    message = "moved to val",
+    replaceWith = ReplaceWith(expression = "source"),
+    level = DeprecationLevel.ERROR
+  )
+  fun source() = source
+
+  /**
+   * Fail any in-flight and future operations. After canceling:
+   *
+   *  * Any attempt to write or flush [sink] will fail immediately with an [IOException].
+   *  * Any attempt to read [source] will fail immediately with an [IOException].
+   *  * Any attempt to [fold] will fail immediately with an [IOException].
+   *
+   * Closing the source and the sink will complete normally even after a pipe has been canceled. If
+   * this sink has been folded, closing it will close the folded sink. This operation may block.
+   *
+   * This operation may be called by any thread at any time. It is safe to call concurrently while
+   * operating on the source or the sink.
+   */
+  fun cancel() {
+    synchronized(buffer) {
+      canceled = true
+      buffer.clear()
+      (buffer as Object).notifyAll() // Notify the source and sink that they're canceled.
+    }
+  }
+}
diff --git a/okio/src/jvmMain/kotlin/okio/RealBufferedSink.kt b/okio/src/jvmMain/kotlin/okio/RealBufferedSink.kt
new file mode 100644
index 0000000..7df3f93
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/RealBufferedSink.kt
@@ -0,0 +1,140 @@
+/*
+ * 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 okio
+
+import okio.internal.commonClose
+import okio.internal.commonEmit
+import okio.internal.commonEmitCompleteSegments
+import okio.internal.commonFlush
+import okio.internal.commonTimeout
+import okio.internal.commonToString
+import okio.internal.commonWrite
+import okio.internal.commonWriteAll
+import okio.internal.commonWriteByte
+import okio.internal.commonWriteDecimalLong
+import okio.internal.commonWriteHexadecimalUnsignedLong
+import okio.internal.commonWriteInt
+import okio.internal.commonWriteIntLe
+import okio.internal.commonWriteLong
+import okio.internal.commonWriteLongLe
+import okio.internal.commonWriteShort
+import okio.internal.commonWriteShortLe
+import okio.internal.commonWriteUtf8
+import okio.internal.commonWriteUtf8CodePoint
+import java.io.IOException
+import java.io.OutputStream
+import java.nio.ByteBuffer
+import java.nio.charset.Charset
+
+internal actual class RealBufferedSink actual constructor(
+  @JvmField actual val sink: Sink
+) : BufferedSink {
+  @JvmField val bufferField = Buffer()
+  @JvmField actual var closed: Boolean = false
+
+  @Suppress("OVERRIDE_BY_INLINE") // Prevent internal code from calling the getter.
+  override val buffer: Buffer
+    inline get() = bufferField
+
+  override fun buffer() = bufferField
+
+  override fun write(source: Buffer, byteCount: Long) = commonWrite(source, byteCount)
+  override fun write(byteString: ByteString) = commonWrite(byteString)
+  override fun write(byteString: ByteString, offset: Int, byteCount: Int) =
+    commonWrite(byteString, offset, byteCount)
+  override fun writeUtf8(string: String) = commonWriteUtf8(string)
+  override fun writeUtf8(string: String, beginIndex: Int, endIndex: Int) =
+    commonWriteUtf8(string, beginIndex, endIndex)
+
+  override fun writeUtf8CodePoint(codePoint: Int) = commonWriteUtf8CodePoint(codePoint)
+
+  override fun writeString(string: String, charset: Charset): BufferedSink {
+    check(!closed) { "closed" }
+    buffer.writeString(string, charset)
+    return emitCompleteSegments()
+  }
+
+  override fun writeString(
+    string: String,
+    beginIndex: Int,
+    endIndex: Int,
+    charset: Charset
+  ): BufferedSink {
+    check(!closed) { "closed" }
+    buffer.writeString(string, beginIndex, endIndex, charset)
+    return emitCompleteSegments()
+  }
+
+  override fun write(source: ByteArray) = commonWrite(source)
+  override fun write(source: ByteArray, offset: Int, byteCount: Int) =
+    commonWrite(source, offset, byteCount)
+
+  override fun write(source: ByteBuffer): Int {
+    check(!closed) { "closed" }
+    val result = buffer.write(source)
+    emitCompleteSegments()
+    return result
+  }
+
+  override fun writeAll(source: Source) = commonWriteAll(source)
+  override fun write(source: Source, byteCount: Long): BufferedSink = commonWrite(source, byteCount)
+  override fun writeByte(b: Int) = commonWriteByte(b)
+  override fun writeShort(s: Int) = commonWriteShort(s)
+  override fun writeShortLe(s: Int) = commonWriteShortLe(s)
+  override fun writeInt(i: Int) = commonWriteInt(i)
+  override fun writeIntLe(i: Int) = commonWriteIntLe(i)
+  override fun writeLong(v: Long) = commonWriteLong(v)
+  override fun writeLongLe(v: Long) = commonWriteLongLe(v)
+  override fun writeDecimalLong(v: Long) = commonWriteDecimalLong(v)
+  override fun writeHexadecimalUnsignedLong(v: Long) = commonWriteHexadecimalUnsignedLong(v)
+  override fun emitCompleteSegments() = commonEmitCompleteSegments()
+  override fun emit() = commonEmit()
+
+  override fun outputStream(): OutputStream {
+    return object : OutputStream() {
+      override fun write(b: Int) {
+        if (closed) throw IOException("closed")
+        buffer.writeByte(b.toByte().toInt())
+        emitCompleteSegments()
+      }
+
+      override fun write(data: ByteArray, offset: Int, byteCount: Int) {
+        if (closed) throw IOException("closed")
+        buffer.write(data, offset, byteCount)
+        emitCompleteSegments()
+      }
+
+      override fun flush() {
+        // For backwards compatibility, a flush() on a closed stream is a no-op.
+        if (!closed) {
+          this@RealBufferedSink.flush()
+        }
+      }
+
+      override fun close() = this@RealBufferedSink.close()
+
+      override fun toString() = "${this@RealBufferedSink}.outputStream()"
+    }
+  }
+
+  override fun flush() = commonFlush()
+
+  override fun isOpen() = !closed
+
+  override fun close() = commonClose()
+  override fun timeout() = commonTimeout()
+  override fun toString() = commonToString()
+}
diff --git a/okio/src/jvmMain/kotlin/okio/RealBufferedSource.kt b/okio/src/jvmMain/kotlin/okio/RealBufferedSource.kt
new file mode 100644
index 0000000..109ef14
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/RealBufferedSource.kt
@@ -0,0 +1,181 @@
+/*
+ * 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 okio
+
+import okio.internal.commonClose
+import okio.internal.commonExhausted
+import okio.internal.commonIndexOf
+import okio.internal.commonIndexOfElement
+import okio.internal.commonPeek
+import okio.internal.commonRangeEquals
+import okio.internal.commonRead
+import okio.internal.commonReadAll
+import okio.internal.commonReadByte
+import okio.internal.commonReadByteArray
+import okio.internal.commonReadByteString
+import okio.internal.commonReadDecimalLong
+import okio.internal.commonReadFully
+import okio.internal.commonReadHexadecimalUnsignedLong
+import okio.internal.commonReadInt
+import okio.internal.commonReadIntLe
+import okio.internal.commonReadLong
+import okio.internal.commonReadLongLe
+import okio.internal.commonReadShort
+import okio.internal.commonReadShortLe
+import okio.internal.commonReadUtf8
+import okio.internal.commonReadUtf8CodePoint
+import okio.internal.commonReadUtf8Line
+import okio.internal.commonReadUtf8LineStrict
+import okio.internal.commonRequest
+import okio.internal.commonRequire
+import okio.internal.commonSelect
+import okio.internal.commonSkip
+import okio.internal.commonTimeout
+import okio.internal.commonToString
+import java.io.IOException
+import java.io.InputStream
+import java.nio.ByteBuffer
+import java.nio.charset.Charset
+
+internal actual class RealBufferedSource actual constructor(
+  @JvmField actual val source: Source
+) : BufferedSource {
+  @JvmField val bufferField = Buffer()
+  @JvmField actual var closed: Boolean = false
+
+  @Suppress("OVERRIDE_BY_INLINE") // Prevent internal code from calling the getter.
+  override val buffer: Buffer
+    inline get() = bufferField
+
+  override fun buffer() = bufferField
+
+  override fun read(sink: Buffer, byteCount: Long): Long = commonRead(sink, byteCount)
+  override fun exhausted(): Boolean = commonExhausted()
+  override fun require(byteCount: Long): Unit = commonRequire(byteCount)
+  override fun request(byteCount: Long): Boolean = commonRequest(byteCount)
+  override fun readByte(): Byte = commonReadByte()
+  override fun readByteString(): ByteString = commonReadByteString()
+  override fun readByteString(byteCount: Long): ByteString = commonReadByteString(byteCount)
+  override fun select(options: Options): Int = commonSelect(options)
+  override fun readByteArray(): ByteArray = commonReadByteArray()
+  override fun readByteArray(byteCount: Long): ByteArray = commonReadByteArray(byteCount)
+  override fun read(sink: ByteArray): Int = read(sink, 0, sink.size)
+  override fun readFully(sink: ByteArray): Unit = commonReadFully(sink)
+  override fun read(sink: ByteArray, offset: Int, byteCount: Int): Int =
+    commonRead(sink, offset, byteCount)
+
+  override fun read(sink: ByteBuffer): Int {
+    if (buffer.size == 0L) {
+      val read = source.read(buffer, Segment.SIZE.toLong())
+      if (read == -1L) return -1
+    }
+
+    return buffer.read(sink)
+  }
+
+  override fun readFully(sink: Buffer, byteCount: Long): Unit = commonReadFully(sink, byteCount)
+  override fun readAll(sink: Sink): Long = commonReadAll(sink)
+  override fun readUtf8(): String = commonReadUtf8()
+  override fun readUtf8(byteCount: Long): String = commonReadUtf8(byteCount)
+
+  override fun readString(charset: Charset): String {
+    buffer.writeAll(source)
+    return buffer.readString(charset)
+  }
+
+  override fun readString(byteCount: Long, charset: Charset): String {
+    require(byteCount)
+    return buffer.readString(byteCount, charset)
+  }
+
+  override fun readUtf8Line(): String? = commonReadUtf8Line()
+  override fun readUtf8LineStrict() = readUtf8LineStrict(Long.MAX_VALUE)
+  override fun readUtf8LineStrict(limit: Long): String = commonReadUtf8LineStrict(limit)
+  override fun readUtf8CodePoint(): Int = commonReadUtf8CodePoint()
+  override fun readShort(): Short = commonReadShort()
+  override fun readShortLe(): Short = commonReadShortLe()
+  override fun readInt(): Int = commonReadInt()
+  override fun readIntLe(): Int = commonReadIntLe()
+  override fun readLong(): Long = commonReadLong()
+  override fun readLongLe(): Long = commonReadLongLe()
+  override fun readDecimalLong(): Long = commonReadDecimalLong()
+  override fun readHexadecimalUnsignedLong(): Long = commonReadHexadecimalUnsignedLong()
+  override fun skip(byteCount: Long): Unit = commonSkip(byteCount)
+  override fun indexOf(b: Byte): Long = indexOf(b, 0L, Long.MAX_VALUE)
+  override fun indexOf(b: Byte, fromIndex: Long): Long = indexOf(b, fromIndex, Long.MAX_VALUE)
+  override fun indexOf(b: Byte, fromIndex: Long, toIndex: Long): Long =
+    commonIndexOf(b, fromIndex, toIndex)
+
+  override fun indexOf(bytes: ByteString): Long = indexOf(bytes, 0L)
+  override fun indexOf(bytes: ByteString, fromIndex: Long): Long = commonIndexOf(bytes, fromIndex)
+  override fun indexOfElement(targetBytes: ByteString): Long = indexOfElement(targetBytes, 0L)
+  override fun indexOfElement(targetBytes: ByteString, fromIndex: Long): Long =
+    commonIndexOfElement(targetBytes, fromIndex)
+
+  override fun rangeEquals(offset: Long, bytes: ByteString) = rangeEquals(
+    offset, bytes, 0,
+    bytes.size
+  )
+
+  override fun rangeEquals(
+    offset: Long,
+    bytes: ByteString,
+    bytesOffset: Int,
+    byteCount: Int
+  ): Boolean = commonRangeEquals(offset, bytes, bytesOffset, byteCount)
+
+  override fun peek(): BufferedSource = commonPeek()
+
+  override fun inputStream(): InputStream {
+    return object : InputStream() {
+      override fun read(): Int {
+        if (closed) throw IOException("closed")
+        if (buffer.size == 0L) {
+          val count = source.read(buffer, Segment.SIZE.toLong())
+          if (count == -1L) return -1
+        }
+        return buffer.readByte() and 0xff
+      }
+
+      override fun read(data: ByteArray, offset: Int, byteCount: Int): Int {
+        if (closed) throw IOException("closed")
+        checkOffsetAndCount(data.size.toLong(), offset.toLong(), byteCount.toLong())
+
+        if (buffer.size == 0L) {
+          val count = source.read(buffer, Segment.SIZE.toLong())
+          if (count == -1L) return -1
+        }
+
+        return buffer.read(data, offset, byteCount)
+      }
+
+      override fun available(): Int {
+        if (closed) throw IOException("closed")
+        return minOf(buffer.size, Integer.MAX_VALUE).toInt()
+      }
+
+      override fun close() = this@RealBufferedSource.close()
+
+      override fun toString() = "${this@RealBufferedSource}.inputStream()"
+    }
+  }
+
+  override fun isOpen() = !closed
+
+  override fun close(): Unit = commonClose()
+  override fun timeout(): Timeout = commonTimeout()
+  override fun toString(): String = commonToString()
+}
diff --git a/okio/src/jvmMain/kotlin/okio/SegmentPool.kt b/okio/src/jvmMain/kotlin/okio/SegmentPool.kt
new file mode 100644
index 0000000..7a7b049
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/SegmentPool.kt
@@ -0,0 +1,127 @@
+/*
+ * 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 okio
+
+import okio.SegmentPool.LOCK
+import okio.SegmentPool.recycle
+import okio.SegmentPool.take
+import java.util.concurrent.atomic.AtomicReference
+
+/**
+ * This class pools segments in a lock-free singly-linked stack. Though this code is lock-free it
+ * does use a sentinel [LOCK] value to defend against races. Conflicted operations are not retried,
+ * so there is no chance of blocking despite the term "lock".
+ *
+ * On [take], a caller swaps the stack's next pointer with the [LOCK] sentinel. If the stack was
+ * not already locked, the caller replaces the head node with its successor.
+ *
+ * On [recycle], a caller swaps the head with a new node whose successor is the replaced head.
+ *
+ * On conflict, operations succeed, but segments are not pushed into the stack. For example, a
+ * [take] that loses a race allocates a new segment regardless of the pool size. A [recycle] call
+ * that loses a race will not increase the size of the pool. Under significant contention, this pool
+ * will have fewer hits and the VM will do more GC and zero filling of arrays.
+ *
+ * This tracks the number of bytes in each linked list in its [Segment.limit] property. Each element
+ * has a limit that's one segment size greater than its successor element. The maximum size of the
+ * pool is a product of [MAX_SIZE] and [HASH_BUCKET_COUNT].
+ */
+internal actual object SegmentPool {
+  /** The maximum number of bytes to pool per hash bucket. */
+  // TODO: Is 64 KiB a good maximum size? Do we ever have that many idle segments?
+  actual val MAX_SIZE = 64 * 1024 // 64 KiB.
+
+  /** A sentinel segment to indicate that the linked list is currently being modified. */
+  private val LOCK = Segment(ByteArray(0), pos = 0, limit = 0, shared = false, owner = false)
+
+  /**
+   * The number of hash buckets. This number needs to balance keeping the pool small and contention
+   * low. We use the number of processors rounded up to the nearest power of two. For example a
+   * machine with 6 cores will have 8 hash buckets.
+   */
+  private val HASH_BUCKET_COUNT =
+    Integer.highestOneBit(Runtime.getRuntime().availableProcessors() * 2 - 1)
+
+  /**
+   * Hash buckets each contain a singly-linked list of segments. The index/key is a hash function of
+   * thread ID because it may reduce contention or increase locality.
+   *
+   * We don't use [ThreadLocal] because we don't know how many threads the host process has and we
+   * don't want to leak memory for the duration of a thread's life.
+   */
+  private val hashBuckets: Array<AtomicReference<Segment?>> = Array(HASH_BUCKET_COUNT) {
+    AtomicReference<Segment?>() // null value implies an empty bucket
+  }
+
+  actual val byteCount: Int
+    get() {
+      val first = firstRef().get() ?: return 0
+      return first.limit
+    }
+
+  @JvmStatic
+  actual fun take(): Segment {
+    val firstRef = firstRef()
+
+    val first = firstRef.getAndSet(LOCK)
+    when {
+      first === LOCK -> {
+        // We didn't acquire the lock. Don't take a pooled segment.
+        return Segment()
+      }
+      first == null -> {
+        // We acquired the lock but the pool was empty. Unlock and return a new segment.
+        firstRef.set(null)
+        return Segment()
+      }
+      else -> {
+        // We acquired the lock and the pool was not empty. Pop the first element and return it.
+        firstRef.set(first.next)
+        first.next = null
+        first.limit = 0
+        return first
+      }
+    }
+  }
+
+  @JvmStatic
+  actual fun recycle(segment: Segment) {
+    require(segment.next == null && segment.prev == null)
+    if (segment.shared) return // This segment cannot be recycled.
+
+    val firstRef = firstRef()
+
+    val first = firstRef.get()
+    if (first === LOCK) return // A take() is currently in progress.
+    val firstLimit = first?.limit ?: 0
+    if (firstLimit >= MAX_SIZE) return // Pool is full.
+
+    segment.next = first
+    segment.pos = 0
+    segment.limit = firstLimit + Segment.SIZE
+
+    // If we lost a race with another operation, don't recycle this segment.
+    if (!firstRef.compareAndSet(first, segment)) {
+      segment.next = null // Don't leak a reference in the pool either!
+    }
+  }
+
+  private fun firstRef(): AtomicReference<Segment?> {
+    // Get a value in [0..HASH_BUCKET_COUNT) based on the current thread.
+    val hashBucket = (Thread.currentThread().id and (HASH_BUCKET_COUNT - 1L)).toInt()
+    return hashBuckets[hashBucket]
+  }
+}
diff --git a/okio/src/jvmMain/kotlin/okio/SegmentedByteString.kt b/okio/src/jvmMain/kotlin/okio/SegmentedByteString.kt
new file mode 100644
index 0000000..bce9d5a
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/SegmentedByteString.kt
@@ -0,0 +1,131 @@
+/*
+ * 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 okio
+
+import okio.internal.commonEquals
+import okio.internal.commonGetSize
+import okio.internal.commonHashCode
+import okio.internal.commonInternalGet
+import okio.internal.commonRangeEquals
+import okio.internal.commonSubstring
+import okio.internal.commonToByteArray
+import okio.internal.commonWrite
+import okio.internal.forEachSegment
+import java.io.IOException
+import java.io.OutputStream
+import java.nio.ByteBuffer
+import java.nio.charset.Charset
+import java.security.InvalidKeyException
+import java.security.MessageDigest
+import javax.crypto.Mac
+import javax.crypto.spec.SecretKeySpec
+
+internal actual class SegmentedByteString internal actual constructor(
+  @Transient internal actual val segments: Array<ByteArray>,
+  @Transient internal actual val directory: IntArray
+) : ByteString(EMPTY.data) {
+
+  override fun string(charset: Charset) = toByteString().string(charset)
+
+  override fun base64() = toByteString().base64()
+
+  override fun hex() = toByteString().hex()
+
+  override fun toAsciiLowercase() = toByteString().toAsciiLowercase()
+
+  override fun toAsciiUppercase() = toByteString().toAsciiUppercase()
+
+  override fun digest(algorithm: String): ByteString {
+    val digestBytes = MessageDigest.getInstance(algorithm).run {
+      forEachSegment { data, offset, byteCount ->
+        update(data, offset, byteCount)
+      }
+      digest()
+    }
+    return ByteString(digestBytes)
+  }
+
+  override fun hmac(algorithm: String, key: ByteString): ByteString {
+    try {
+      val mac = Mac.getInstance(algorithm)
+      mac.init(SecretKeySpec(key.toByteArray(), algorithm))
+      forEachSegment { data, offset, byteCount ->
+        mac.update(data, offset, byteCount)
+      }
+      return ByteString(mac.doFinal())
+    } catch (e: InvalidKeyException) {
+      throw IllegalArgumentException(e)
+    }
+  }
+
+  override fun base64Url() = toByteString().base64Url()
+
+  override fun substring(beginIndex: Int, endIndex: Int): ByteString =
+    commonSubstring(beginIndex, endIndex)
+
+  override fun internalGet(pos: Int): Byte = commonInternalGet(pos)
+
+  override fun getSize() = commonGetSize()
+
+  override fun toByteArray(): ByteArray = commonToByteArray()
+
+  override fun asByteBuffer(): ByteBuffer = ByteBuffer.wrap(toByteArray()).asReadOnlyBuffer()
+
+  @Throws(IOException::class)
+  override fun write(out: OutputStream) {
+    forEachSegment { data, offset, byteCount ->
+      out.write(data, offset, byteCount)
+    }
+  }
+
+  override fun write(buffer: Buffer, offset: Int, byteCount: Int): Unit =
+    commonWrite(buffer, offset, byteCount)
+
+  override fun rangeEquals(
+    offset: Int,
+    other: ByteString,
+    otherOffset: Int,
+    byteCount: Int
+  ): Boolean = commonRangeEquals(offset, other, otherOffset, byteCount)
+
+  override fun rangeEquals(
+    offset: Int,
+    other: ByteArray,
+    otherOffset: Int,
+    byteCount: Int
+  ): Boolean = commonRangeEquals(offset, other, otherOffset, byteCount)
+
+  override fun indexOf(other: ByteArray, fromIndex: Int) = toByteString().indexOf(other, fromIndex)
+
+  override fun lastIndexOf(other: ByteArray, fromIndex: Int) = toByteString().lastIndexOf(
+    other,
+    fromIndex
+  )
+
+  /** Returns a copy as a non-segmented byte string.  */
+  private fun toByteString() = ByteString(toByteArray())
+
+  override fun internalArray() = toByteArray()
+
+  override fun equals(other: Any?): Boolean = commonEquals(other)
+
+  override fun hashCode(): Int = commonHashCode()
+
+  override fun toString() = toByteString().toString()
+
+  @Suppress("unused", "PLATFORM_CLASS_MAPPED_TO_KOTLIN") // For Java Serialization.
+  private fun writeReplace(): Object = toByteString() as Object
+}
diff --git a/okio/src/jvmMain/kotlin/okio/Sink.kt b/okio/src/jvmMain/kotlin/okio/Sink.kt
new file mode 100644
index 0000000..e93ffb5
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/Sink.kt
@@ -0,0 +1,33 @@
+/*
+ * 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 okio
+
+import java.io.Closeable
+import java.io.Flushable
+import java.io.IOException
+
+actual interface Sink : Closeable, Flushable {
+  @Throws(IOException::class)
+  actual fun write(source: Buffer, byteCount: Long)
+
+  @Throws(IOException::class)
+  actual override fun flush()
+
+  actual fun timeout(): Timeout
+
+  @Throws(IOException::class)
+  actual override fun close()
+}
diff --git a/okio/src/jvmMain/kotlin/okio/Throttler.kt b/okio/src/jvmMain/kotlin/okio/Throttler.kt
new file mode 100644
index 0000000..dbb83fe
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/Throttler.kt
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+import java.io.IOException
+import java.io.InterruptedIOException
+
+/**
+ * Enables limiting of Source and Sink throughput. Attach to this throttler via [source] and [sink]
+ * and set the desired throughput via [bytesPerSecond]. Multiple Sources and Sinks can be
+ * attached to a single Throttler and they will be throttled as a group, where their combined
+ * throughput will not exceed the desired throughput. The same Source or Sink can be attached to
+ * multiple Throttlers and its throughput will not exceed the desired throughput of any of the
+ * Throttlers.
+ *
+ * This class has these tuning parameters:
+ *
+ *  * `bytesPerSecond`: Maximum sustained throughput. Use 0 for no limit.
+ *  * `waitByteCount`: When the requested byte count is greater than this many bytes and isn't
+ *    immediately available, only wait until we can allocate at least this many bytes. Use this to
+ *    set the ideal byte count during sustained throughput.
+ *  * `maxByteCount`: Maximum number of bytes to allocate on any call. This is also the number of
+ *    bytes that will be returned before any waiting.
+ */
+class Throttler internal constructor(
+  /**
+   * The nanoTime that we've consumed all bytes through. This is never greater than the current
+   * nanoTime plus nanosForMaxByteCount.
+   */
+  private var allocatedUntil: Long
+) {
+  private var bytesPerSecond: Long = 0L
+  private var waitByteCount: Long = 8 * 1024 // 8 KiB.
+  private var maxByteCount: Long = 256 * 1024 // 256 KiB.
+
+  constructor() : this(allocatedUntil = System.nanoTime())
+
+  /** Sets the rate at which bytes will be allocated. Use 0 for no limit. */
+  @JvmOverloads
+  fun bytesPerSecond(
+    bytesPerSecond: Long,
+    waitByteCount: Long = this.waitByteCount,
+    maxByteCount: Long = this.maxByteCount
+  ) {
+    synchronized(this) {
+      require(bytesPerSecond >= 0)
+      require(waitByteCount > 0)
+      require(maxByteCount >= waitByteCount)
+
+      this.bytesPerSecond = bytesPerSecond
+      this.waitByteCount = waitByteCount
+      this.maxByteCount = maxByteCount
+      (this as Object).notifyAll()
+    }
+  }
+
+  /**
+   * Take up to `byteCount` bytes, waiting if necessary. Returns the number of bytes that were
+   * taken.
+   */
+  internal fun take(byteCount: Long): Long {
+    require(byteCount > 0)
+
+    synchronized(this) {
+      while (true) {
+        val now = System.nanoTime()
+        val byteCountOrWaitNanos = byteCountOrWaitNanos(now, byteCount)
+        if (byteCountOrWaitNanos >= 0) return byteCountOrWaitNanos
+        waitNanos(-byteCountOrWaitNanos)
+      }
+    }
+    throw AssertionError() // Unreachable, but synchronized() doesn't know that.
+  }
+
+  /**
+   * Returns the byte count to take immediately or -1 times the number of nanos to wait until the
+   * next attempt. If the returned value is negative it should be interpreted as a duration in
+   * nanos; if it is positive it should be interpreted as a byte count.
+   */
+  internal fun byteCountOrWaitNanos(now: Long, byteCount: Long): Long {
+    if (bytesPerSecond == 0L) return byteCount // No limits.
+
+    val idleInNanos = maxOf(allocatedUntil - now, 0L)
+    val immediateBytes = maxByteCount - idleInNanos.nanosToBytes()
+
+    // Fulfill the entire request without waiting.
+    if (immediateBytes >= byteCount) {
+      allocatedUntil = now + idleInNanos + byteCount.bytesToNanos()
+      return byteCount
+    }
+
+    // Fulfill a big-enough block without waiting.
+    if (immediateBytes >= waitByteCount) {
+      allocatedUntil = now + maxByteCount.bytesToNanos()
+      return immediateBytes
+    }
+
+    // Looks like we'll need to wait until we can take the minimum required bytes.
+    val minByteCount = minOf(waitByteCount, byteCount)
+    val minWaitNanos = idleInNanos + (minByteCount - maxByteCount).bytesToNanos()
+
+    // But if the wait duration truncates to zero nanos after division, don't wait.
+    if (minWaitNanos == 0L) {
+      allocatedUntil = now + maxByteCount.bytesToNanos()
+      return minByteCount
+    }
+
+    return -minWaitNanos
+  }
+
+  private fun Long.nanosToBytes() = this * bytesPerSecond / 1_000_000_000L
+
+  private fun Long.bytesToNanos() = this * 1_000_000_000L / bytesPerSecond
+
+  private fun waitNanos(nanosToWait: Long) {
+    val millisToWait = nanosToWait / 1_000_000L
+    val remainderNanos = nanosToWait - (millisToWait * 1_000_000L)
+    (this as Object).wait(millisToWait, remainderNanos.toInt())
+  }
+
+  /** Create a Source which honors this Throttler.  */
+  fun source(source: Source): Source {
+    return object : ForwardingSource(source) {
+      override fun read(sink: Buffer, byteCount: Long): Long {
+        try {
+          val toRead = take(byteCount)
+          return super.read(sink, toRead)
+        } catch (e: InterruptedException) {
+          Thread.currentThread().interrupt()
+          throw InterruptedIOException("interrupted")
+        }
+      }
+    }
+  }
+
+  /** Create a Sink which honors this Throttler.  */
+  fun sink(sink: Sink): Sink {
+    return object : ForwardingSink(sink) {
+      @Throws(IOException::class)
+      override fun write(source: Buffer, byteCount: Long) {
+        try {
+          var remaining = byteCount
+          while (remaining > 0L) {
+            val toWrite = take(remaining)
+            super.write(source, toWrite)
+            remaining -= toWrite
+          }
+        } catch (e: InterruptedException) {
+          Thread.currentThread().interrupt()
+          throw InterruptedIOException("interrupted")
+        }
+      }
+    }
+  }
+}
diff --git a/okio/src/jvmMain/kotlin/okio/Timeout.kt b/okio/src/jvmMain/kotlin/okio/Timeout.kt
new file mode 100644
index 0000000..c522380
--- /dev/null
+++ b/okio/src/jvmMain/kotlin/okio/Timeout.kt
@@ -0,0 +1,233 @@
+/*
+ * 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 okio
+
+import java.io.IOException
+import java.io.InterruptedIOException
+import java.util.concurrent.TimeUnit
+
+actual open class Timeout {
+  /**
+   * True if `deadlineNanoTime` is defined. There is no equivalent to null or 0 for
+   * [System.nanoTime].
+   */
+  private var hasDeadline = false
+  private var deadlineNanoTime = 0L
+  private var timeoutNanos = 0L
+
+  /**
+   * Wait at most `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.
+   *
+   * If `timeout == 0`, operations will run indefinitely. (Operating system timeouts may still
+   * apply.)
+   */
+  open fun timeout(timeout: Long, unit: TimeUnit): Timeout {
+    require(timeout >= 0) { "timeout < 0: $timeout" }
+    timeoutNanos = unit.toNanos(timeout)
+    return this
+  }
+
+  /** Returns the timeout in nanoseconds, or `0` for no timeout. */
+  open fun timeoutNanos(): Long = timeoutNanos
+
+  /** Returns true if a deadline is enabled. */
+  open fun hasDeadline(): Boolean = hasDeadline
+
+  /**
+   * Returns the [nano time][System.nanoTime] when the deadline will be reached.
+   *
+   * @throws IllegalStateException if no deadline is set.
+   */
+  open fun deadlineNanoTime(): Long {
+    check(hasDeadline) { "No deadline" }
+    return deadlineNanoTime
+  }
+
+  /**
+   * Sets the [nano time][System.nanoTime] 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.
+   */
+  open fun deadlineNanoTime(deadlineNanoTime: Long): Timeout {
+    this.hasDeadline = true
+    this.deadlineNanoTime = deadlineNanoTime
+    return this
+  }
+
+  /** Set a deadline of now plus `duration` time.  */
+  fun deadline(duration: Long, unit: TimeUnit): Timeout {
+    require(duration > 0) { "duration <= 0: $duration" }
+    return deadlineNanoTime(System.nanoTime() + unit.toNanos(duration))
+  }
+
+  /** Clears the timeout. Operating system timeouts may still apply. */
+  open fun clearTimeout(): Timeout {
+    timeoutNanos = 0
+    return this
+  }
+
+  /** Clears the deadline. */
+  open fun clearDeadline(): Timeout {
+    hasDeadline = false
+    return this
+  }
+
+  /**
+   * Throws an [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.
+   */
+  @Throws(IOException::class)
+  open fun throwIfReached() {
+    if (Thread.currentThread().isInterrupted) {
+      // If the current thread has been interrupted.
+      throw InterruptedIOException("interrupted")
+    }
+
+    if (hasDeadline && deadlineNanoTime - System.nanoTime() <= 0) {
+      throw InterruptedIOException("deadline reached")
+    }
+  }
+
+  /**
+   * Waits on `monitor` until it is notified. Throws [InterruptedIOException] if either the thread
+   * is interrupted or if this timeout elapses before `monitor` is notified. The caller must be
+   * synchronized on `monitor`.
+   *
+   * Here's a sample class that uses `waitUntilNotified()` to await a specific state. Note that the
+   * call is made within a loop to avoid unnecessary waiting and to mitigate spurious notifications.
+   * ```
+   * class Dice {
+   *   Random random = new Random();
+   *   int latestTotal;
+   *
+   *   public synchronized void roll() {
+   *     latestTotal = 2 + random.nextInt(6) + random.nextInt(6);
+   *     System.out.println("Rolled " + latestTotal);
+   *     notifyAll();
+   *   }
+   *
+   *   public void rollAtFixedRate(int period, TimeUnit timeUnit) {
+   *     Executors.newScheduledThreadPool(0).scheduleAtFixedRate(new Runnable() {
+   *       public void run() {
+   *         roll();
+   *       }
+   *     }, 0, period, timeUnit);
+   *   }
+   *
+   *   public synchronized void awaitTotal(Timeout timeout, int total)
+   *       throws InterruptedIOException {
+   *     while (latestTotal != total) {
+   *       timeout.waitUntilNotified(this);
+   *     }
+   *   }
+   * }
+   * ```
+   */
+  @Throws(InterruptedIOException::class)
+  fun waitUntilNotified(monitor: Any) {
+    try {
+      val hasDeadline = hasDeadline()
+      val timeoutNanos = timeoutNanos()
+
+      if (!hasDeadline && timeoutNanos == 0L) {
+        (monitor as Object).wait() // There is no timeout: wait forever.
+        return
+      }
+
+      // Compute how long we'll wait.
+      val start = System.nanoTime()
+      val waitNanos = if (hasDeadline && timeoutNanos != 0L) {
+        val deadlineNanos = deadlineNanoTime() - start
+        minOf(timeoutNanos, deadlineNanos)
+      } else if (hasDeadline) {
+        deadlineNanoTime() - start
+      } else {
+        timeoutNanos
+      }
+
+      // Attempt to wait that long. This will break out early if the monitor is notified.
+      var elapsedNanos = 0L
+      if (waitNanos > 0L) {
+        val waitMillis = waitNanos / 1000000L
+        (monitor as Object).wait(waitMillis, (waitNanos - waitMillis * 1000000L).toInt())
+        elapsedNanos = System.nanoTime() - start
+      }
+
+      // Throw if the timeout elapsed before the monitor was notified.
+      if (elapsedNanos >= waitNanos) {
+        throw InterruptedIOException("timeout")
+      }
+    } catch (e: InterruptedException) {
+      Thread.currentThread().interrupt() // Retain interrupted status.
+      throw InterruptedIOException("interrupted")
+    }
+  }
+
+  /**
+   * Applies the minimum intersection between this timeout and `other`, run `block`, then finally
+   * rollback this timeout's values.
+   */
+  inline fun intersectWith(other: Timeout, block: () -> Unit) {
+    val originalTimeout = this.timeoutNanos()
+    this.timeout(minTimeout(other.timeoutNanos(), this.timeoutNanos()), TimeUnit.NANOSECONDS)
+
+    if (this.hasDeadline()) {
+      val originalDeadline = this.deadlineNanoTime()
+      if (other.hasDeadline()) {
+        this.deadlineNanoTime(Math.min(this.deadlineNanoTime(), other.deadlineNanoTime()))
+      }
+      try {
+        block()
+      } finally {
+        this.timeout(originalTimeout, TimeUnit.NANOSECONDS)
+        if (other.hasDeadline()) {
+          this.deadlineNanoTime(originalDeadline)
+        }
+      }
+    } else {
+      if (other.hasDeadline()) {
+        this.deadlineNanoTime(other.deadlineNanoTime())
+      }
+      try {
+        block()
+      } finally {
+        this.timeout(originalTimeout, TimeUnit.NANOSECONDS)
+        if (other.hasDeadline()) {
+          this.clearDeadline()
+        }
+      }
+    }
+  }
+
+  actual companion object {
+    @JvmField actual val NONE: Timeout = object : Timeout() {
+      override fun timeout(timeout: Long, unit: TimeUnit): Timeout = this
+
+      override fun deadlineNanoTime(deadlineNanoTime: Long): Timeout = this
+
+      override fun throwIfReached() {}
+    }
+
+    fun minTimeout(aNanos: Long, bNanos: Long) = when {
+      aNanos == 0L -> bNanos
+      bNanos == 0L -> aNanos
+      aNanos < bNanos -> aNanos
+      else -> bNanos
+    }
+  }
+}
diff --git a/okio/src/jvmMain/resources/META-INF/proguard/okio.pro b/okio/src/jvmMain/resources/META-INF/proguard/okio.pro
new file mode 100644
index 0000000..2b69834
--- /dev/null
+++ b/okio/src/jvmMain/resources/META-INF/proguard/okio.pro
@@ -0,0 +1,2 @@
+# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
+-dontwarn org.codehaus.mojo.animal_sniffer.*
diff --git a/okio/src/jvmTest/java/okio/AsyncTimeoutTest.java b/okio/src/jvmTest/java/okio/AsyncTimeoutTest.java
new file mode 100644
index 0000000..974218b
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/AsyncTimeoutTest.java
@@ -0,0 +1,392 @@
+/*
+ * 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 okio;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Random;
+import java.util.concurrent.BlockingDeque;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.TimeUnit;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static okio.TestUtil.bufferWithRandomSegmentLayout;
+import static org.junit.Assert.*;
+
+/**
+ * This test uses four timeouts of varying durations: 250ms, 500ms, 750ms and
+ * 1000ms, named 'a', 'b', 'c' and 'd'.
+ */
+public final class AsyncTimeoutTest {
+  private final BlockingDeque<AsyncTimeout> timedOut = new LinkedBlockingDeque<>();
+  private final AsyncTimeout a = new RecordingAsyncTimeout();
+  private final AsyncTimeout b = new RecordingAsyncTimeout();
+  private final AsyncTimeout c = new RecordingAsyncTimeout();
+  private final AsyncTimeout d = new RecordingAsyncTimeout();
+
+  @Before public void setUp() throws Exception {
+    a.timeout( 250, TimeUnit.MILLISECONDS);
+    b.timeout( 500, TimeUnit.MILLISECONDS);
+    c.timeout( 750, TimeUnit.MILLISECONDS);
+    d.timeout(1000, TimeUnit.MILLISECONDS);
+  }
+
+  @Test public void zeroTimeoutIsNoTimeout() throws Exception {
+    AsyncTimeout timeout = new RecordingAsyncTimeout();
+    timeout.timeout(0, TimeUnit.MILLISECONDS);
+    timeout.enter();
+    Thread.sleep(250);
+    assertFalse(timeout.exit());
+    assertTimedOut();
+  }
+
+  @Test public void singleInstanceTimedOut() throws Exception {
+    a.enter();
+    Thread.sleep(500);
+    assertTrue(a.exit());
+    assertTimedOut(a);
+  }
+
+  @Test public void singleInstanceNotTimedOut() throws Exception {
+    b.enter();
+    Thread.sleep(250);
+    b.exit();
+    assertFalse(b.exit());
+    assertTimedOut();
+  }
+
+  @Test public void instancesAddedAtEnd() throws Exception {
+    a.enter();
+    b.enter();
+    c.enter();
+    d.enter();
+    Thread.sleep(1250);
+    assertTrue(a.exit());
+    assertTrue(b.exit());
+    assertTrue(c.exit());
+    assertTrue(d.exit());
+    assertTimedOut(a, b, c, d);
+  }
+
+  @Test public void instancesAddedAtFront() throws Exception {
+    d.enter();
+    c.enter();
+    b.enter();
+    a.enter();
+    Thread.sleep(1250);
+    assertTrue(d.exit());
+    assertTrue(c.exit());
+    assertTrue(b.exit());
+    assertTrue(a.exit());
+    assertTimedOut(a, b, c, d);
+  }
+
+  @Test public void instancesRemovedAtFront() throws Exception {
+    a.enter();
+    b.enter();
+    c.enter();
+    d.enter();
+    assertFalse(a.exit());
+    assertFalse(b.exit());
+    assertFalse(c.exit());
+    assertFalse(d.exit());
+    assertTimedOut();
+  }
+
+  @Test public void instancesRemovedAtEnd() throws Exception {
+    a.enter();
+    b.enter();
+    c.enter();
+    d.enter();
+    assertFalse(d.exit());
+    assertFalse(c.exit());
+    assertFalse(b.exit());
+    assertFalse(a.exit());
+    assertTimedOut();
+  }
+
+  @Test public void doubleEnter() throws Exception {
+    a.enter();
+    try {
+      a.enter();
+      fail();
+    } catch (IllegalStateException expected) {
+    }
+  }
+
+  @Test public void reEnter() throws Exception {
+    a.timeout(10, SECONDS);
+    a.enter();
+    assertFalse(a.exit());
+    a.enter();
+    assertFalse(a.exit());
+  }
+
+  @Test public void reEnterAfterTimeout() throws Exception {
+    a.timeout(1, MILLISECONDS);
+    a.enter();
+    assertSame(a, timedOut.take());
+    assertTrue(a.exit());
+    a.enter();
+    assertFalse(a.exit());
+  }
+
+  @Test public void deadlineOnly() throws Exception {
+    RecordingAsyncTimeout timeout = new RecordingAsyncTimeout();
+    timeout.deadline(250, TimeUnit.MILLISECONDS);
+    timeout.enter();
+    Thread.sleep(500);
+    assertTrue(timeout.exit());
+    assertTimedOut(timeout);
+  }
+
+  @Test public void deadlineBeforeTimeout() throws Exception {
+    RecordingAsyncTimeout timeout = new RecordingAsyncTimeout();
+    timeout.deadline(250, TimeUnit.MILLISECONDS);
+    timeout.timeout(750, TimeUnit.MILLISECONDS);
+    timeout.enter();
+    Thread.sleep(500);
+    assertTrue(timeout.exit());
+    assertTimedOut(timeout);
+  }
+
+  @Test public void deadlineAfterTimeout() throws Exception {
+    RecordingAsyncTimeout timeout = new RecordingAsyncTimeout();
+    timeout.timeout(250, TimeUnit.MILLISECONDS);
+    timeout.deadline(750, TimeUnit.MILLISECONDS);
+    timeout.enter();
+    Thread.sleep(500);
+    assertTrue(timeout.exit());
+    assertTimedOut(timeout);
+  }
+
+  @Test public void deadlineStartsBeforeEnter() throws Exception {
+    RecordingAsyncTimeout timeout = new RecordingAsyncTimeout();
+    timeout.deadline(500, TimeUnit.MILLISECONDS);
+    Thread.sleep(500);
+    timeout.enter();
+    Thread.sleep(250);
+    assertTrue(timeout.exit());
+    assertTimedOut(timeout);
+  }
+
+  @Test public void deadlineInThePast() throws Exception {
+    RecordingAsyncTimeout timeout = new RecordingAsyncTimeout();
+    timeout.deadlineNanoTime(System.nanoTime() - 1);
+    timeout.enter();
+    Thread.sleep(250);
+    assertTrue(timeout.exit());
+    assertTimedOut(timeout);
+  }
+
+  @Test public void wrappedSinkTimesOut() throws Exception {
+    Sink sink = new ForwardingSink(new Buffer()) {
+      @Override public void write(Buffer source, long byteCount) throws IOException {
+        try {
+          Thread.sleep(500);
+        } catch (InterruptedException e) {
+          throw new AssertionError();
+        }
+      }
+    };
+    AsyncTimeout timeout = new AsyncTimeout();
+    timeout.timeout(250, TimeUnit.MILLISECONDS);
+    Sink timeoutSink = timeout.sink(sink);
+    Buffer data = new Buffer().writeUtf8("a");
+    try {
+      timeoutSink.write(data, 1);
+      fail();
+    } catch (InterruptedIOException expected) {
+    }
+  }
+
+  @Test public void wrappedSinkFlushTimesOut() throws Exception {
+    Sink sink = new ForwardingSink(new Buffer()) {
+      @Override public void flush() throws IOException {
+        try {
+          Thread.sleep(500);
+        } catch (InterruptedException e) {
+          throw new AssertionError();
+        }
+      }
+    };
+    AsyncTimeout timeout = new AsyncTimeout();
+    timeout.timeout(250, TimeUnit.MILLISECONDS);
+    Sink timeoutSink = timeout.sink(sink);
+    try {
+      timeoutSink.flush();
+      fail();
+    } catch (InterruptedIOException expected) {
+    }
+  }
+
+  @Test public void wrappedSinkCloseTimesOut() throws Exception {
+    Sink sink = new ForwardingSink(new Buffer()) {
+      @Override public void close() throws IOException {
+        try {
+          Thread.sleep(500);
+        } catch (InterruptedException e) {
+          throw new AssertionError();
+        }
+      }
+    };
+    AsyncTimeout timeout = new AsyncTimeout();
+    timeout.timeout(250, TimeUnit.MILLISECONDS);
+    Sink timeoutSink = timeout.sink(sink);
+    try {
+      timeoutSink.close();
+      fail();
+    } catch (InterruptedIOException expected) {
+    }
+  }
+
+  @Test public void wrappedSourceTimesOut() throws Exception {
+    Source source = new ForwardingSource(new Buffer()) {
+      @Override public long read(Buffer sink, long byteCount) throws IOException {
+        try {
+          Thread.sleep(500);
+          return -1;
+        } catch (InterruptedException e) {
+          throw new AssertionError();
+        }
+      }
+    };
+    AsyncTimeout timeout = new AsyncTimeout();
+    timeout.timeout(250, TimeUnit.MILLISECONDS);
+    Source timeoutSource = timeout.source(source);
+    try {
+      timeoutSource.read(new Buffer(), 0);
+      fail();
+    } catch (InterruptedIOException expected) {
+    }
+  }
+
+  @Test public void wrappedSourceCloseTimesOut() throws Exception {
+    Source source = new ForwardingSource(new Buffer()) {
+      @Override public void close() throws IOException {
+        try {
+          Thread.sleep(500);
+        } catch (InterruptedException e) {
+          throw new AssertionError();
+        }
+      }
+    };
+    AsyncTimeout timeout = new AsyncTimeout();
+    timeout.timeout(250, TimeUnit.MILLISECONDS);
+    Source timeoutSource = timeout.source(source);
+    try {
+      timeoutSource.close();
+      fail();
+    } catch (InterruptedIOException expected) {
+    }
+  }
+
+  @Test public void wrappedThrowsWithTimeout() throws Exception {
+    Sink sink = new ForwardingSink(new Buffer()) {
+      @Override public void write(Buffer source, long byteCount) throws IOException {
+        try {
+          Thread.sleep(500);
+          throw new IOException("exception and timeout");
+        } catch (InterruptedException e) {
+          throw new AssertionError();
+        }
+      }
+    };
+    AsyncTimeout timeout = new AsyncTimeout();
+    timeout.timeout(250, TimeUnit.MILLISECONDS);
+    Sink timeoutSink = timeout.sink(sink);
+    Buffer data = new Buffer().writeUtf8("a");
+    try {
+      timeoutSink.write(data, 1);
+      fail();
+    } catch (InterruptedIOException expected) {
+      assertEquals("timeout", expected.getMessage());
+      assertEquals("exception and timeout", expected.getCause().getMessage());
+    }
+  }
+
+  @Test public void wrappedThrowsWithoutTimeout() throws Exception {
+    Sink sink = new ForwardingSink(new Buffer()) {
+      @Override public void write(Buffer source, long byteCount) throws IOException {
+        throw new IOException("no timeout occurred");
+      }
+    };
+    AsyncTimeout timeout = new AsyncTimeout();
+    timeout.timeout(250, TimeUnit.MILLISECONDS);
+    Sink timeoutSink = timeout.sink(sink);
+    Buffer data = new Buffer().writeUtf8("a");
+    try {
+      timeoutSink.write(data, 1);
+      fail();
+    } catch (IOException expected) {
+      assertEquals("no timeout occurred", expected.getMessage());
+    }
+  }
+
+  /**
+   * We had a bug where writing a very large buffer would fail with an
+   * unexpected timeout because although the sink was making steady forward
+   * progress, doing it all as a single write caused a timeout.
+   */
+  @Ignore("Flaky")
+  @Test public void sinkSplitsLargeWrites() throws Exception {
+    byte[] data = new byte[512 * 1024];
+    Random dice = new Random(0);
+    dice.nextBytes(data);
+    final Buffer source = bufferWithRandomSegmentLayout(dice, data);
+    final Buffer target = new Buffer();
+
+    Sink sink = new ForwardingSink(new Buffer()) {
+      @Override public void write(Buffer source, long byteCount) throws IOException {
+        try {
+          Thread.sleep(byteCount / 500); // ~500 KiB/s.
+          target.write(source, byteCount);
+        } catch (InterruptedException e) {
+          throw new AssertionError();
+        }
+      }
+    };
+
+    // Timeout after 250 ms of inactivity.
+    AsyncTimeout timeout = new AsyncTimeout();
+    timeout.timeout(250, TimeUnit.MILLISECONDS);
+    Sink timeoutSink = timeout.sink(sink);
+
+    // Transmit 500 KiB of data, which should take ~1 second. But expect no timeout!
+    timeoutSink.write(source, source.size());
+
+    // The data should all have arrived.
+    assertEquals(ByteString.of(data), target.readByteString());
+  }
+
+  /** Asserts which timeouts fired, and in which order. */
+  private void assertTimedOut(Timeout... expected) {
+    assertEquals(Arrays.asList(expected), new ArrayList<Timeout>(timedOut));
+  }
+
+  class RecordingAsyncTimeout extends AsyncTimeout {
+    @Override protected void timedOut() {
+      timedOut.add(this);
+    }
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/BufferCursorTest.java b/okio/src/jvmTest/java/okio/BufferCursorTest.java
new file mode 100644
index 0000000..4cad858
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/BufferCursorTest.java
@@ -0,0 +1,468 @@
+/*
+ * Copyright (C) 2018 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 okio;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+import static kotlin.text.StringsKt.repeat;
+import static okio.Buffer.UnsafeCursor;
+import static okio.TestUtil.SEGMENT_SIZE;
+import static okio.TestUtil.deepCopy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+@RunWith(Parameterized.class)
+public final class BufferCursorTest {
+
+  @Parameters(name = "{0}")
+  public static List<Object[]> parameters() throws Exception {
+    List<Object[]> result = new ArrayList<>();
+    for (BufferFactory bufferFactory : BufferFactory.values()) {
+      result.add(new Object[] {bufferFactory});
+    }
+    return result;
+  }
+
+  @Parameter public BufferFactory bufferFactory;
+
+  @Test public void apiExample() throws Exception {
+    Buffer buffer = new Buffer();
+
+    try (UnsafeCursor cursor = buffer.readAndWriteUnsafe()) {
+      cursor.resizeBuffer(1000_000);
+
+      do {
+        Arrays.fill(cursor.data, cursor.start, cursor.end, (byte) 'x');
+      } while (cursor.next() != -1);
+
+      cursor.seek(3);
+      cursor.data[cursor.start] = 'o';
+
+      cursor.seek(1);
+      cursor.data[cursor.start] = 'o';
+
+      cursor.resizeBuffer(4);
+    }
+
+    assertEquals(new Buffer().writeUtf8("xoxo"), buffer);
+  }
+
+  @Test public void accessSegmentBySegment() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    try (UnsafeCursor cursor = buffer.readUnsafe()) {
+      Buffer actual = new Buffer();
+      while (cursor.next() != -1L) {
+        actual.write(cursor.data, cursor.start, cursor.end - cursor.start);
+      }
+      assertEquals(buffer, actual);
+    }
+  }
+
+  @Test public void seekToNegativeOneSeeksBeforeFirstSegment() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    try (UnsafeCursor cursor = buffer.readUnsafe()) {
+      cursor.seek(-1L);
+      assertEquals(-1, cursor.offset);
+      assertEquals(null, cursor.data);
+      assertEquals(-1, cursor.start);
+      assertEquals(-1, cursor.end);
+
+      cursor.next();
+      assertEquals(0, cursor.offset);
+    }
+  }
+
+  @Test public void accessByteByByte() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    try (UnsafeCursor cursor = buffer.readUnsafe()) {
+      byte[] actual = new byte[(int) buffer.size()];
+      for (int i = 0; i < buffer.size(); i++) {
+        cursor.seek(i);
+        actual[i] = cursor.data[cursor.start];
+      }
+      assertEquals(ByteString.of(actual), buffer.snapshot());
+    }
+  }
+
+  @Test public void accessByteByByteReverse() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    try (UnsafeCursor cursor = buffer.readUnsafe()) {
+      byte[] actual = new byte[(int) buffer.size()];
+      for (int i = (int) (buffer.size() - 1); i >= 0; i--) {
+        cursor.seek(i);
+        actual[i] = cursor.data[cursor.start];
+      }
+      assertEquals(ByteString.of(actual), buffer.snapshot());
+    }
+  }
+
+  @Test public void accessByteByByteAlwaysResettingToZero() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    try (UnsafeCursor cursor = buffer.readUnsafe()) {
+      byte[] actual = new byte[(int) buffer.size()];
+      for (int i = 0; i < buffer.size(); i++) {
+        cursor.seek(i);
+        actual[i] = cursor.data[cursor.start];
+        cursor.seek(0L);
+      }
+      assertEquals(ByteString.of(actual), buffer.snapshot());
+    }
+  }
+
+  @Test public void segmentBySegmentNavigation() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    UnsafeCursor cursor = buffer.readUnsafe();
+    assertEquals(-1, cursor.offset);
+    try {
+      long lastOffset = cursor.offset;
+      while (cursor.next() != -1L) {
+        assertTrue(cursor.offset > lastOffset);
+        lastOffset = cursor.offset;
+      }
+      assertEquals(buffer.size(), cursor.offset);
+      assertNull(cursor.data);
+      assertEquals(-1, cursor.start);
+      assertEquals(-1, cursor.end);
+    } finally {
+      cursor.close();
+    }
+  }
+
+  @Test public void seekWithinSegment() throws Exception {
+    assumeTrue(bufferFactory == BufferFactory.SMALL_SEGMENTED_BUFFER);
+    Buffer buffer = bufferFactory.newBuffer();
+    assertEquals("abcdefghijkl", buffer.clone().readUtf8());
+
+    // Seek to the 'f' in the "defg" segment.
+    try (UnsafeCursor cursor = buffer.readUnsafe()) {
+      assertEquals(2, cursor.seek(5)); // 2 for 2 bytes left in the segment: "fg".
+      assertEquals(5, cursor.offset);
+      assertEquals(2, cursor.end - cursor.start);
+      assertEquals('d', (char) cursor.data[cursor.start - 2]); // Out of bounds!
+      assertEquals('e', (char) cursor.data[cursor.start - 1]); // Out of bounds!
+      assertEquals('f', (char) cursor.data[cursor.start]);
+      assertEquals('g', (char) cursor.data[cursor.start + 1]);
+    }
+  }
+
+  @Test public void acquireAndRelease() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    UnsafeCursor cursor = new UnsafeCursor();
+
+    // Nothing initialized before acquire.
+    assertEquals(-1, cursor.offset);
+    assertNull(cursor.data);
+    assertEquals(-1, cursor.start);
+    assertEquals(-1, cursor.end);
+
+    buffer.readUnsafe(cursor);
+    cursor.close();
+
+    // Nothing initialized after close.
+    assertEquals(-1, cursor.offset);
+    assertNull(cursor.data);
+    assertEquals(-1, cursor.start);
+    assertEquals(-1, cursor.end);
+  }
+
+  @Test public void doubleAcquire() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    try (UnsafeCursor cursor = buffer.readUnsafe()) {
+      buffer.readUnsafe(cursor);
+      fail();
+    } catch (IllegalStateException expected) {
+    }
+  }
+
+  @Test public void releaseWithoutAcquire() throws Exception {
+    UnsafeCursor cursor = new UnsafeCursor();
+    try {
+      cursor.close();
+      fail();
+    } catch (IllegalStateException expected) {
+    }
+  }
+
+  @Test public void releaseAfterRelease() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    UnsafeCursor cursor = buffer.readUnsafe();
+    cursor.close();
+    try {
+      cursor.close();
+      fail();
+    } catch (IllegalStateException expected) {
+    }
+  }
+
+  @Test public void enlarge() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    long originalSize = buffer.size();
+
+    Buffer expected = deepCopy(buffer);
+    expected.writeUtf8("abc");
+
+    try (UnsafeCursor cursor = buffer.readAndWriteUnsafe()) {
+      assertEquals(originalSize, cursor.resizeBuffer(originalSize + 3));
+      cursor.seek(originalSize);
+      cursor.data[cursor.start] = 'a';
+      cursor.seek(originalSize + 1);
+      cursor.data[cursor.start] = 'b';
+      cursor.seek(originalSize + 2);
+      cursor.data[cursor.start] = 'c';
+    }
+
+    assertEquals(expected, buffer);
+  }
+
+  @Test public void enlargeByManySegments() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    long originalSize = buffer.size();
+
+    Buffer expected = deepCopy(buffer);
+    expected.writeUtf8(repeat("x", 1_000_000));
+
+    try (UnsafeCursor cursor = buffer.readAndWriteUnsafe()) {
+      cursor.resizeBuffer(originalSize + 1_000_000);
+      cursor.seek(originalSize);
+      do {
+        Arrays.fill(cursor.data, cursor.start, cursor.end, (byte) 'x');
+      } while (cursor.next() != -1);
+    }
+
+    assertEquals(expected, buffer);
+  }
+
+  @Test public void resizeNotAcquired() throws Exception {
+    UnsafeCursor cursor = new UnsafeCursor();
+    try {
+      cursor.resizeBuffer(10);
+      fail();
+    } catch (IllegalStateException expected) {
+    }
+  }
+
+  @Test public void expandNotAcquired() throws Exception {
+    UnsafeCursor cursor = new UnsafeCursor();
+    try {
+      cursor.expandBuffer(10);
+      fail();
+    } catch (IllegalStateException expected) {
+    }
+  }
+
+  @Test public void resizeAcquiredReadOnly() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+
+    try (UnsafeCursor cursor = buffer.readUnsafe()) {
+      cursor.resizeBuffer(10);
+      fail();
+    } catch (IllegalStateException expected) {
+    }
+  }
+
+  @Test public void expandAcquiredReadOnly() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+
+    try (UnsafeCursor cursor = buffer.readUnsafe()) {
+      cursor.expandBuffer(10);
+      fail();
+    } catch (IllegalStateException expected) {
+    }
+  }
+
+  @Test public void shrink() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    assumeTrue(buffer.size() > 3);
+    long originalSize = buffer.size();
+
+    Buffer expected = new Buffer();
+    deepCopy(buffer).copyTo(expected, 0, originalSize - 3);
+
+    try (UnsafeCursor cursor = buffer.readAndWriteUnsafe()) {
+      assertEquals(originalSize, cursor.resizeBuffer(originalSize - 3));
+    }
+
+    assertEquals(expected, buffer);
+  }
+
+  @Test public void shrinkByManySegments() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    assumeTrue(buffer.size() <= 1_000_000);
+    long originalSize = buffer.size();
+
+    Buffer toShrink = new Buffer();
+    toShrink.writeUtf8(repeat("x", 1_000_000));
+    deepCopy(buffer).copyTo(toShrink, 0, originalSize);
+
+    UnsafeCursor cursor = new UnsafeCursor();
+    toShrink.readAndWriteUnsafe(cursor);
+    try {
+      cursor.resizeBuffer(originalSize);
+    } finally {
+      cursor.close();
+    }
+
+    Buffer expected = new Buffer();
+    expected.writeUtf8(repeat("x", (int) originalSize));
+    assertEquals(expected, toShrink);
+  }
+
+  @Test public void shrinkAdjustOffset() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    assumeTrue(buffer.size() > 4);
+
+    try (UnsafeCursor cursor = buffer.readAndWriteUnsafe()) {
+      cursor.seek(buffer.size() - 1);
+      cursor.resizeBuffer(3);
+      assertEquals(3, cursor.offset);
+      assertEquals(null, cursor.data);
+      assertEquals(-1, cursor.start);
+      assertEquals(-1, cursor.end);
+    }
+  }
+
+  @Test public void resizeToSameSizeSeeksToEnd() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    long originalSize = buffer.size();
+
+    try (UnsafeCursor cursor = buffer.readAndWriteUnsafe()) {
+      cursor.seek(buffer.size() / 2);
+      assertEquals(originalSize, buffer.size());
+      cursor.resizeBuffer(originalSize);
+      assertEquals(originalSize, buffer.size());
+      assertEquals(originalSize, cursor.offset);
+      assertNull(cursor.data);
+      assertEquals(-1, cursor.start);
+      assertEquals(-1, cursor.end);
+    }
+  }
+
+  @Test public void resizeEnlargeMovesCursorToOldSize() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    long originalSize = buffer.size();
+
+    Buffer expected = deepCopy(buffer);
+    expected.writeUtf8("a");
+
+    try (UnsafeCursor cursor = buffer.readAndWriteUnsafe()) {
+      cursor.seek(buffer.size() / 2);
+      assertEquals(originalSize, buffer.size());
+      cursor.resizeBuffer(originalSize + 1);
+      assertEquals(originalSize, cursor.offset);
+      assertNotNull(cursor.data);
+      assertNotEquals(-1, cursor.start);
+      assertEquals(cursor.start + 1, cursor.end);
+      cursor.data[cursor.start] = 'a';
+    }
+
+    assertEquals(expected, buffer);
+  }
+
+  @Test public void resizeShrinkMovesCursorToEnd() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    assumeTrue(buffer.size() > 0);
+    long originalSize = buffer.size();
+
+    try (UnsafeCursor cursor = buffer.readAndWriteUnsafe()) {
+      cursor.seek(buffer.size() / 2);
+      assertEquals(originalSize, buffer.size());
+      cursor.resizeBuffer(originalSize - 1);
+      assertEquals(originalSize - 1, cursor.offset);
+      assertNull(cursor.data);
+      assertEquals(-1, cursor.start);
+      assertEquals(-1, cursor.end);
+    }
+  }
+
+  @Test public void expand() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    long originalSize = buffer.size();
+
+    Buffer expected = deepCopy(buffer);
+    expected.writeUtf8("abcde");
+
+    try (UnsafeCursor cursor = buffer.readAndWriteUnsafe()) {
+      cursor.expandBuffer(5);
+
+      for (int i = 0; i < 5; i++) {
+        cursor.data[cursor.start + i] = (byte) ('a' + i);
+      }
+
+      cursor.resizeBuffer(originalSize + 5);
+    }
+
+    assertEquals(expected, buffer);
+  }
+
+  @Test public void expandSameSegment() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    long originalSize = buffer.size();
+    assumeTrue(originalSize > 0);
+
+    try (UnsafeCursor cursor = buffer.readAndWriteUnsafe()) {
+      cursor.seek(originalSize - 1);
+      int originalEnd = cursor.end;
+      assumeTrue(originalEnd < SEGMENT_SIZE);
+
+      long addedByteCount = cursor.expandBuffer(1);
+      assertEquals(SEGMENT_SIZE - originalEnd, addedByteCount);
+
+      assertEquals(originalSize + addedByteCount, buffer.size());
+      assertEquals(originalSize, cursor.offset);
+      assertEquals(originalEnd, cursor.start);
+      assertEquals(SEGMENT_SIZE, cursor.end);
+    }
+  }
+
+  @Test public void expandNewSegment() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    long originalSize = buffer.size();
+
+    try (UnsafeCursor cursor = buffer.readAndWriteUnsafe()) {
+      long addedByteCount = cursor.expandBuffer(SEGMENT_SIZE);
+      assertEquals(SEGMENT_SIZE, addedByteCount);
+
+      assertEquals(originalSize, cursor.offset);
+      assertEquals(0, cursor.start);
+      assertEquals(SEGMENT_SIZE, cursor.end);
+    }
+  }
+
+  @Test public void expandMovesOffsetToOldSize() throws Exception {
+    Buffer buffer = bufferFactory.newBuffer();
+    long originalSize = buffer.size();
+
+    try (UnsafeCursor cursor = buffer.readAndWriteUnsafe()) {
+      cursor.seek(buffer.size() / 2);
+      assertEquals(originalSize, buffer.size());
+      long addedByteCount = cursor.expandBuffer(5);
+      assertEquals(originalSize + addedByteCount, buffer.size());
+      assertEquals(originalSize, cursor.offset);
+    }
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/BufferTest.java b/okio/src/jvmTest/java/okio/BufferTest.java
new file mode 100644
index 0000000..f5586d4
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/BufferTest.java
@@ -0,0 +1,580 @@
+/*
+ * 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 okio;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+import org.junit.Test;
+
+import static java.util.Arrays.asList;
+import static kotlin.text.Charsets.UTF_8;
+import static kotlin.text.StringsKt.repeat;
+import static okio.TestUtil.SEGMENT_POOL_MAX_SIZE;
+import static okio.TestUtil.SEGMENT_SIZE;
+import static okio.TestUtil.assertNoEmptySegments;
+import static okio.TestUtil.bufferWithRandomSegmentLayout;
+import static okio.TestUtil.segmentPoolByteCount;
+import static okio.TestUtil.segmentSizes;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests solely for the behavior of Buffer's implementation. For generic BufferedSink or
+ * BufferedSource behavior use BufferedSinkTest or BufferedSourceTest, respectively.
+ */
+public final class BufferTest {
+  @Test public void readAndWriteUtf8() throws Exception {
+    Buffer buffer = new Buffer();
+    buffer.writeUtf8("ab");
+    assertEquals(2, buffer.size());
+    buffer.writeUtf8("cdef");
+    assertEquals(6, buffer.size());
+    assertEquals("abcd", buffer.readUtf8(4));
+    assertEquals(2, buffer.size());
+    assertEquals("ef", buffer.readUtf8(2));
+    assertEquals(0, buffer.size());
+    try {
+      buffer.readUtf8(1);
+      fail();
+    } catch (EOFException expected) {
+    }
+  }
+
+  /** Buffer's toString is the same as ByteString's. */
+  @Test public void bufferToString() {
+    assertEquals("[size=0]", new Buffer().toString());
+    assertEquals("[text=a\\r\\nb\\nc\\rd\\\\e]",
+        new Buffer().writeUtf8("a\r\nb\nc\rd\\e").toString());
+    assertEquals("[text=Tyrannosaur]",
+        new Buffer().writeUtf8("Tyrannosaur").toString());
+    assertEquals("[text=təˈranəˌsôr]", new Buffer()
+        .write(ByteString.decodeHex("74c999cb8872616ec999cb8c73c3b472"))
+        .toString());
+    assertEquals("[hex=0000000000000000000000000000000000000000000000000000000000000000000000000000"
+        + "0000000000000000000000000000000000000000000000000000]",
+        new Buffer().write(new byte[64]).toString());
+  }
+
+  @Test public void multipleSegmentBuffers() throws Exception {
+    Buffer buffer = new Buffer();
+    buffer.writeUtf8(repeat("a", 1000));
+    buffer.writeUtf8(repeat("b", 2500));
+    buffer.writeUtf8(repeat("c", 5000));
+    buffer.writeUtf8(repeat("d", 10000));
+    buffer.writeUtf8(repeat("e", 25000));
+    buffer.writeUtf8(repeat("f", 50000));
+
+    assertEquals(repeat("a", 999), buffer.readUtf8(999)); // a...a
+    assertEquals("a" + repeat("b", 2500) + "c", buffer.readUtf8(2502)); // ab...bc
+    assertEquals(repeat("c", 4998), buffer.readUtf8(4998)); // c...c
+    assertEquals("c" + repeat("d", 10000) + "e", buffer.readUtf8(10002)); // cd...de
+    assertEquals(repeat("e", 24998), buffer.readUtf8(24998)); // e...e
+    assertEquals("e" + repeat("f", 50000), buffer.readUtf8(50001)); // ef...f
+    assertEquals(0, buffer.size());
+  }
+
+  @Test public void fillAndDrainPool() throws Exception {
+    Buffer buffer = new Buffer();
+
+    // Take 2 * MAX_SIZE segments. This will drain the pool, even if other tests filled it.
+    buffer.write(new byte[(int) SEGMENT_POOL_MAX_SIZE]);
+    buffer.write(new byte[(int) SEGMENT_POOL_MAX_SIZE]);
+    assertEquals(0, segmentPoolByteCount());
+
+    // Recycle MAX_SIZE segments. They're all in the pool.
+    buffer.skip(SEGMENT_POOL_MAX_SIZE);
+    assertEquals(SEGMENT_POOL_MAX_SIZE, segmentPoolByteCount());
+
+    // Recycle MAX_SIZE more segments. The pool is full so they get garbage collected.
+    buffer.skip(SEGMENT_POOL_MAX_SIZE);
+    assertEquals(SEGMENT_POOL_MAX_SIZE, segmentPoolByteCount());
+
+    // Take MAX_SIZE segments to drain the pool.
+    buffer.write(new byte[(int) SEGMENT_POOL_MAX_SIZE]);
+    assertEquals(0, segmentPoolByteCount());
+
+    // Take MAX_SIZE more segments. The pool is drained so these will need to be allocated.
+    buffer.write(new byte[(int) SEGMENT_POOL_MAX_SIZE]);
+    assertEquals(0, segmentPoolByteCount());
+  }
+
+  @Test public void moveBytesBetweenBuffersShareSegment() throws Exception {
+    int size = (SEGMENT_SIZE / 2) - 1;
+    List<Integer> segmentSizes = moveBytesBetweenBuffers(repeat("a", size), repeat("b", size));
+    assertEquals(asList(size * 2), segmentSizes);
+  }
+
+  @Test public void moveBytesBetweenBuffersReassignSegment() throws Exception {
+    int size = (SEGMENT_SIZE / 2) + 1;
+    List<Integer> segmentSizes = moveBytesBetweenBuffers(repeat("a", size), repeat("b", size));
+    assertEquals(asList(size, size), segmentSizes);
+  }
+
+  @Test public void moveBytesBetweenBuffersMultipleSegments() throws Exception {
+    int size = 3 * SEGMENT_SIZE + 1;
+    List<Integer> segmentSizes = moveBytesBetweenBuffers(repeat("a", size), repeat("b", size));
+    assertEquals(asList(SEGMENT_SIZE, SEGMENT_SIZE, SEGMENT_SIZE, 1,
+        SEGMENT_SIZE, SEGMENT_SIZE, SEGMENT_SIZE, 1), segmentSizes);
+  }
+
+  private List<Integer> moveBytesBetweenBuffers(String... contents) throws IOException {
+    StringBuilder expected = new StringBuilder();
+    Buffer buffer = new Buffer();
+    for (String s : contents) {
+      Buffer source = new Buffer();
+      source.writeUtf8(s);
+      buffer.writeAll(source);
+      expected.append(s);
+    }
+    List<Integer> segmentSizes = segmentSizes(buffer);
+    assertEquals(expected.toString(), buffer.readUtf8(expected.length()));
+    return segmentSizes;
+  }
+
+  /** The big part of source's first segment is being moved. */
+  @Test public void writeSplitSourceBufferLeft() {
+    int writeSize = SEGMENT_SIZE / 2 + 1;
+
+    Buffer sink = new Buffer();
+    sink.writeUtf8(repeat("b", SEGMENT_SIZE - 10));
+
+    Buffer source = new Buffer();
+    source.writeUtf8(repeat("a", SEGMENT_SIZE * 2));
+    sink.write(source, writeSize);
+
+    assertEquals(asList(SEGMENT_SIZE - 10, writeSize), segmentSizes(sink));
+    assertEquals(asList(SEGMENT_SIZE - writeSize, SEGMENT_SIZE), segmentSizes(source));
+  }
+
+  /** The big part of source's first segment is staying put. */
+  @Test public void writeSplitSourceBufferRight() {
+    int writeSize = SEGMENT_SIZE / 2 - 1;
+
+    Buffer sink = new Buffer();
+    sink.writeUtf8(repeat("b", SEGMENT_SIZE - 10));
+
+    Buffer source = new Buffer();
+    source.writeUtf8(repeat("a", SEGMENT_SIZE * 2));
+    sink.write(source, writeSize);
+
+    assertEquals(asList(SEGMENT_SIZE - 10, writeSize), segmentSizes(sink));
+    assertEquals(asList(SEGMENT_SIZE - writeSize, SEGMENT_SIZE), segmentSizes(source));
+  }
+
+  @Test public void writePrefixDoesntSplit() {
+    Buffer sink = new Buffer();
+    sink.writeUtf8(repeat("b", 10));
+
+    Buffer source = new Buffer();
+    source.writeUtf8(repeat("a", SEGMENT_SIZE * 2));
+    sink.write(source, 20);
+
+    assertEquals(asList(30), segmentSizes(sink));
+    assertEquals(asList(SEGMENT_SIZE - 20, SEGMENT_SIZE), segmentSizes(source));
+    assertEquals(30, sink.size());
+    assertEquals(SEGMENT_SIZE * 2 - 20, source.size());
+  }
+
+  @Test public void writePrefixDoesntSplitButRequiresCompact() throws Exception {
+    Buffer sink = new Buffer();
+    sink.writeUtf8(repeat("b", SEGMENT_SIZE - 10)); // limit = size - 10
+    sink.readUtf8(SEGMENT_SIZE - 20); // pos = size = 20
+
+    Buffer source = new Buffer();
+    source.writeUtf8(repeat("a", SEGMENT_SIZE * 2));
+    sink.write(source, 20);
+
+    assertEquals(asList(30), segmentSizes(sink));
+    assertEquals(asList(SEGMENT_SIZE - 20, SEGMENT_SIZE), segmentSizes(source));
+    assertEquals(30, sink.size());
+    assertEquals(SEGMENT_SIZE * 2 - 20, source.size());
+  }
+
+  @Test public void copyToSpanningSegments() throws Exception {
+    Buffer source = new Buffer();
+    source.writeUtf8(repeat("a", SEGMENT_SIZE * 2));
+    source.writeUtf8(repeat("b", SEGMENT_SIZE * 2));
+
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+    source.copyTo(out, 10, SEGMENT_SIZE * 3);
+
+    assertEquals(repeat("a", SEGMENT_SIZE * 2 - 10) + repeat("b", SEGMENT_SIZE + 10),
+        out.toString());
+    assertEquals(repeat("a", SEGMENT_SIZE * 2) + repeat("b", SEGMENT_SIZE * 2),
+        source.readUtf8(SEGMENT_SIZE * 4));
+  }
+
+  @Test public void copyToStream() throws Exception {
+    Buffer buffer = new Buffer().writeUtf8("hello, world!");
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+    buffer.copyTo(out);
+    String outString = new String(out.toByteArray(), UTF_8);
+    assertEquals("hello, world!", outString);
+    assertEquals("hello, world!", buffer.readUtf8());
+  }
+
+  @Test public void writeToSpanningSegments() throws Exception {
+    Buffer buffer = new Buffer();
+    buffer.writeUtf8(repeat("a", SEGMENT_SIZE * 2));
+    buffer.writeUtf8(repeat("b", SEGMENT_SIZE * 2));
+
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+    buffer.skip(10);
+    buffer.writeTo(out, SEGMENT_SIZE * 3);
+
+    assertEquals(repeat("a", SEGMENT_SIZE * 2 - 10) + repeat("b", SEGMENT_SIZE + 10),
+        out.toString());
+    assertEquals(repeat("b", SEGMENT_SIZE - 10), buffer.readUtf8(buffer.size()));
+  }
+
+  @Test public void writeToStream() throws Exception {
+    Buffer buffer = new Buffer().writeUtf8("hello, world!");
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+    buffer.writeTo(out);
+    String outString = new String(out.toByteArray(), UTF_8);
+    assertEquals("hello, world!", outString);
+    assertEquals(0, buffer.size());
+  }
+
+  @Test public void readFromStream() throws Exception {
+    InputStream in = new ByteArrayInputStream("hello, world!".getBytes(UTF_8));
+    Buffer buffer = new Buffer();
+    buffer.readFrom(in);
+    String out = buffer.readUtf8();
+    assertEquals("hello, world!", out);
+  }
+
+  @Test public void readFromSpanningSegments() throws Exception {
+    InputStream in = new ByteArrayInputStream("hello, world!".getBytes(UTF_8));
+    Buffer buffer = new Buffer().writeUtf8(repeat("a", SEGMENT_SIZE - 10));
+    buffer.readFrom(in);
+    String out = buffer.readUtf8();
+    assertEquals(repeat("a", SEGMENT_SIZE - 10) + "hello, world!", out);
+  }
+
+  @Test public void readFromStreamWithCount() throws Exception {
+    InputStream in = new ByteArrayInputStream("hello, world!".getBytes(UTF_8));
+    Buffer buffer = new Buffer();
+    buffer.readFrom(in, 10);
+    String out = buffer.readUtf8();
+    assertEquals("hello, wor", out);
+  }
+
+  @Test public void readFromDoesNotLeaveEmptyTailSegment() throws IOException {
+    Buffer buffer = new Buffer();
+    buffer.readFrom(new ByteArrayInputStream(new byte[SEGMENT_SIZE]));
+    assertNoEmptySegments(buffer);
+  }
+
+  @Test public void moveAllRequestedBytesWithRead() throws Exception {
+    Buffer sink = new Buffer();
+    sink.writeUtf8(repeat("a", 10));
+
+    Buffer source = new Buffer();
+    source.writeUtf8(repeat("b", 15));
+
+    assertEquals(10, source.read(sink, 10));
+    assertEquals(20, sink.size());
+    assertEquals(5, source.size());
+    assertEquals(repeat("a", 10) + repeat("b", 10), sink.readUtf8(20));
+  }
+
+  @Test public void moveFewerThanRequestedBytesWithRead() throws Exception {
+    Buffer sink = new Buffer();
+    sink.writeUtf8(repeat("a", 10));
+
+    Buffer source = new Buffer();
+    source.writeUtf8(repeat("b", 20));
+
+    assertEquals(20, source.read(sink, 25));
+    assertEquals(30, sink.size());
+    assertEquals(0, source.size());
+    assertEquals(repeat("a", 10) + repeat("b", 20), sink.readUtf8(30));
+  }
+
+  @Test public void indexOfWithOffset() {
+    Buffer buffer = new Buffer();
+    int halfSegment = SEGMENT_SIZE / 2;
+    buffer.writeUtf8(repeat("a", halfSegment));
+    buffer.writeUtf8(repeat("b", halfSegment));
+    buffer.writeUtf8(repeat("c", halfSegment));
+    buffer.writeUtf8(repeat("d", halfSegment));
+    assertEquals(0, buffer.indexOf((byte) 'a', 0));
+    assertEquals(halfSegment - 1, buffer.indexOf((byte) 'a', halfSegment - 1));
+    assertEquals(halfSegment, buffer.indexOf((byte) 'b', halfSegment - 1));
+    assertEquals(halfSegment * 2, buffer.indexOf((byte) 'c', halfSegment - 1));
+    assertEquals(halfSegment * 3, buffer.indexOf((byte) 'd', halfSegment - 1));
+    assertEquals(halfSegment * 3, buffer.indexOf((byte) 'd', halfSegment * 2));
+    assertEquals(halfSegment * 3, buffer.indexOf((byte) 'd', halfSegment * 3));
+    assertEquals(halfSegment * 4 - 1, buffer.indexOf((byte) 'd', halfSegment * 4 - 1));
+  }
+
+  @Test public void byteAt() {
+    Buffer buffer = new Buffer();
+    buffer.writeUtf8("a");
+    buffer.writeUtf8(repeat("b", SEGMENT_SIZE));
+    buffer.writeUtf8("c");
+    assertEquals('a', buffer.getByte(0));
+    assertEquals('a', buffer.getByte(0)); // getByte doesn't mutate!
+    assertEquals('c', buffer.getByte(buffer.size() - 1));
+    assertEquals('b', buffer.getByte(buffer.size() - 2));
+    assertEquals('b', buffer.getByte(buffer.size() - 3));
+  }
+
+  @Test public void getByteOfEmptyBuffer() {
+    Buffer buffer = new Buffer();
+    try {
+      buffer.getByte(0);
+      fail();
+    } catch (IndexOutOfBoundsException expected) {
+    }
+  }
+
+  @Test public void writePrefixToEmptyBuffer() throws IOException {
+    Buffer sink = new Buffer();
+    Buffer source = new Buffer();
+    source.writeUtf8("abcd");
+    sink.write(source, 2);
+    assertEquals("ab", sink.readUtf8(2));
+  }
+
+  @Test public void cloneDoesNotObserveWritesToOriginal() {
+    Buffer original = new Buffer();
+    Buffer clone = original.clone();
+    original.writeUtf8("abc");
+    assertEquals(0, clone.size());
+  }
+
+  @Test public void cloneDoesNotObserveReadsFromOriginal() throws Exception {
+    Buffer original = new Buffer();
+    original.writeUtf8("abc");
+    Buffer clone = original.clone();
+    assertEquals("abc", original.readUtf8(3));
+    assertEquals(3, clone.size());
+    assertEquals("ab", clone.readUtf8(2));
+  }
+
+  @Test public void originalDoesNotObserveWritesToClone() {
+    Buffer original = new Buffer();
+    Buffer clone = original.clone();
+    clone.writeUtf8("abc");
+    assertEquals(0, original.size());
+  }
+
+  @Test public void originalDoesNotObserveReadsFromClone() throws Exception {
+    Buffer original = new Buffer();
+    original.writeUtf8("abc");
+    Buffer clone = original.clone();
+    assertEquals("abc", clone.readUtf8(3));
+    assertEquals(3, original.size());
+    assertEquals("ab", original.readUtf8(2));
+  }
+
+  @Test public void cloneMultipleSegments() throws Exception {
+    Buffer original = new Buffer();
+    original.writeUtf8(repeat("a", SEGMENT_SIZE * 3));
+    Buffer clone = original.clone();
+    original.writeUtf8(repeat("b", SEGMENT_SIZE * 3));
+    clone.writeUtf8(repeat("c", SEGMENT_SIZE * 3));
+
+    assertEquals(repeat("a", SEGMENT_SIZE * 3) + repeat("b", SEGMENT_SIZE * 3),
+        original.readUtf8(SEGMENT_SIZE * 6));
+    assertEquals(repeat("a", SEGMENT_SIZE * 3) + repeat("c", SEGMENT_SIZE * 3),
+        clone.readUtf8(SEGMENT_SIZE * 6));
+  }
+
+  @Test public void equalsAndHashCodeEmpty() {
+    Buffer a = new Buffer();
+    Buffer b = new Buffer();
+    assertTrue(a.equals(b));
+    assertTrue(a.hashCode() == b.hashCode());
+  }
+
+  @Test public void equalsAndHashCode() throws Exception {
+    Buffer a = new Buffer().writeUtf8("dog");
+    Buffer b = new Buffer().writeUtf8("hotdog");
+    assertFalse(a.equals(b));
+    assertFalse(a.hashCode() == b.hashCode());
+
+    b.readUtf8(3); // Leaves b containing 'dog'.
+    assertTrue(a.equals(b));
+    assertTrue(a.hashCode() == b.hashCode());
+  }
+
+  @Test public void equalsAndHashCodeSpanningSegments() throws Exception {
+    byte[] data = new byte[1024 * 1024];
+    Random dice = new Random(0);
+    dice.nextBytes(data);
+
+    Buffer a = bufferWithRandomSegmentLayout(dice, data);
+    Buffer b = bufferWithRandomSegmentLayout(dice, data);
+    assertTrue(a.equals(b));
+    assertTrue(a.hashCode() == b.hashCode());
+
+    data[data.length / 2]++; // Change a single byte.
+    Buffer c = bufferWithRandomSegmentLayout(dice, data);
+    assertFalse(a.equals(c));
+    assertFalse(a.hashCode() == c.hashCode());
+  }
+
+  @Test public void bufferInputStreamByteByByte() throws Exception {
+    Buffer source = new Buffer();
+    source.writeUtf8("abc");
+
+    InputStream in = source.inputStream();
+    assertEquals(3, in.available());
+    assertEquals('a', in.read());
+    assertEquals('b', in.read());
+    assertEquals('c', in.read());
+    assertEquals(-1, in.read());
+    assertEquals(0, in.available());
+  }
+
+  @Test public void bufferInputStreamBulkReads() throws Exception {
+    Buffer source = new Buffer();
+    source.writeUtf8("abc");
+
+    byte[] byteArray = new byte[4];
+
+    Arrays.fill(byteArray, (byte) -5);
+    InputStream in = source.inputStream();
+    assertEquals(3, in.read(byteArray));
+    assertEquals("[97, 98, 99, -5]", Arrays.toString(byteArray));
+
+    Arrays.fill(byteArray, (byte) -7);
+    assertEquals(-1, in.read(byteArray));
+    assertEquals("[-7, -7, -7, -7]", Arrays.toString(byteArray));
+  }
+
+  /**
+   * When writing data that's already buffered, there's no reason to page the
+   * data by segment.
+   */
+  @Test public void readAllWritesAllSegmentsAtOnce() throws Exception {
+    Buffer write1 = new Buffer().writeUtf8(""
+        + repeat("a", SEGMENT_SIZE)
+        + repeat("b", SEGMENT_SIZE)
+        + repeat("c", SEGMENT_SIZE));
+
+    Buffer source = new Buffer().writeUtf8(""
+        + repeat("a", SEGMENT_SIZE)
+        + repeat("b", SEGMENT_SIZE)
+        + repeat("c", SEGMENT_SIZE));
+
+    MockSink mockSink = new MockSink();
+
+    assertEquals(SEGMENT_SIZE * 3, source.readAll(mockSink));
+    assertEquals(0, source.size());
+    mockSink.assertLog("write(" + write1 + ", " + write1.size() + ")");
+  }
+
+  @Test public void writeAllMultipleSegments() throws Exception {
+    Buffer source = new Buffer().writeUtf8(repeat("a", SEGMENT_SIZE * 3));
+    Buffer sink = new Buffer();
+
+    assertEquals(SEGMENT_SIZE * 3, sink.writeAll(source));
+    assertEquals(0, source.size());
+    assertEquals(repeat("a", SEGMENT_SIZE * 3), sink.readUtf8());
+  }
+
+  @Test public void copyTo() {
+    Buffer source = new Buffer();
+    source.writeUtf8("party");
+
+    Buffer target = new Buffer();
+    source.copyTo(target, 1, 3);
+
+    assertEquals("art", target.readUtf8());
+    assertEquals("party", source.readUtf8());
+  }
+
+  @Test public void copyToOnSegmentBoundary() {
+    String as = repeat("a", SEGMENT_SIZE);
+    String bs = repeat("b", SEGMENT_SIZE);
+    String cs = repeat("c", SEGMENT_SIZE);
+    String ds = repeat("d", SEGMENT_SIZE);
+
+    Buffer source = new Buffer();
+    source.writeUtf8(as);
+    source.writeUtf8(bs);
+    source.writeUtf8(cs);
+
+    Buffer target = new Buffer();
+    target.writeUtf8(ds);
+
+    source.copyTo(target, as.length(), bs.length() + cs.length());
+    assertEquals(ds + bs + cs, target.readUtf8());
+  }
+
+  @Test public void copyToOffSegmentBoundary() {
+    String as = repeat("a", SEGMENT_SIZE - 1);
+    String bs = repeat("b", SEGMENT_SIZE + 2);
+    String cs = repeat("c", SEGMENT_SIZE - 4);
+    String ds = repeat("d", SEGMENT_SIZE + 8);
+
+    Buffer source = new Buffer();
+    source.writeUtf8(as);
+    source.writeUtf8(bs);
+    source.writeUtf8(cs);
+
+    Buffer target = new Buffer();
+    target.writeUtf8(ds);
+
+    source.copyTo(target, as.length(), bs.length() + cs.length());
+    assertEquals(ds + bs + cs, target.readUtf8());
+  }
+
+  @Test public void copyToSourceAndTargetCanBeTheSame() {
+    String as = repeat("a", SEGMENT_SIZE);
+    String bs = repeat("b", SEGMENT_SIZE);
+
+    Buffer source = new Buffer();
+    source.writeUtf8(as);
+    source.writeUtf8(bs);
+
+    source.copyTo(source, 0, source.size());
+    assertEquals(as + bs + as + bs, source.readUtf8());
+  }
+
+  @Test public void copyToEmptySource() {
+    Buffer source = new Buffer();
+    Buffer target = new Buffer().writeUtf8("aaa");
+    source.copyTo(target, 0L, 0L);
+    assertEquals("", source.readUtf8());
+    assertEquals("aaa", target.readUtf8());
+  }
+
+  @Test public void copyToEmptyTarget() {
+    Buffer source = new Buffer().writeUtf8("aaa");
+    Buffer target = new Buffer();
+    source.copyTo(target, 0L, 3L);
+    assertEquals("aaa", source.readUtf8());
+    assertEquals("aaa", target.readUtf8());
+  }
+
+  @Test public void snapshotReportsAccurateSize() {
+    Buffer buf = new Buffer().write(new byte[] { 0, 1, 2, 3 });
+    assertEquals(1, buf.snapshot(1).size());
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/BufferedSinkJavaTest.java b/okio/src/jvmTest/java/okio/BufferedSinkJavaTest.java
new file mode 100644
index 0000000..357b992
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/BufferedSinkJavaTest.java
@@ -0,0 +1,245 @@
+/*
+ * 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 okio;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import org.junit.Test;
+
+import static kotlin.text.StringsKt.repeat;
+import static okio.TestUtil.SEGMENT_SIZE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests solely for the behavior of RealBufferedSink's implementation. For generic
+ * BufferedSink behavior use BufferedSinkTest.
+ */
+public final class BufferedSinkJavaTest {
+  @Test public void inputStreamCloses() throws Exception {
+    BufferedSink sink = Okio.buffer((Sink) new Buffer());
+    OutputStream out = sink.outputStream();
+    out.close();
+    try {
+      sink.writeUtf8("Hi!");
+      fail();
+    } catch (IllegalStateException e) {
+      assertEquals("closed", e.getMessage());
+    }
+  }
+
+  @Test public void bufferedSinkEmitsTailWhenItIsComplete() throws IOException {
+    Buffer sink = new Buffer();
+    BufferedSink bufferedSink = Okio.buffer((Sink) sink);
+    bufferedSink.writeUtf8(repeat("a", SEGMENT_SIZE - 1));
+    assertEquals(0, sink.size());
+    bufferedSink.writeByte(0);
+    assertEquals(SEGMENT_SIZE, sink.size());
+    assertEquals(0, bufferedSink.getBuffer().size());
+  }
+
+  @Test public void bufferedSinkEmitMultipleSegments() throws IOException {
+    Buffer sink = new Buffer();
+    BufferedSink bufferedSink = Okio.buffer((Sink) sink);
+    bufferedSink.writeUtf8(repeat("a", SEGMENT_SIZE * 4 - 1));
+    assertEquals(SEGMENT_SIZE * 3, sink.size());
+    assertEquals(SEGMENT_SIZE - 1, bufferedSink.getBuffer().size());
+  }
+
+  @Test public void bufferedSinkFlush() throws IOException {
+    Buffer sink = new Buffer();
+    BufferedSink bufferedSink = Okio.buffer((Sink) sink);
+    bufferedSink.writeByte('a');
+    assertEquals(0, sink.size());
+    bufferedSink.flush();
+    assertEquals(0, bufferedSink.getBuffer().size());
+    assertEquals(1, sink.size());
+  }
+
+  @Test public void bytesEmittedToSinkWithFlush() throws Exception {
+    Buffer sink = new Buffer();
+    BufferedSink bufferedSink = Okio.buffer((Sink) sink);
+    bufferedSink.writeUtf8("abc");
+    bufferedSink.flush();
+    assertEquals(3, sink.size());
+  }
+
+  @Test public void bytesNotEmittedToSinkWithoutFlush() throws Exception {
+    Buffer sink = new Buffer();
+    BufferedSink bufferedSink = Okio.buffer((Sink) sink);
+    bufferedSink.writeUtf8("abc");
+    assertEquals(0, sink.size());
+  }
+
+  @Test public void bytesEmittedToSinkWithEmit() throws Exception {
+    Buffer sink = new Buffer();
+    BufferedSink bufferedSink = Okio.buffer((Sink) sink);
+    bufferedSink.writeUtf8("abc");
+    bufferedSink.emit();
+    assertEquals(3, sink.size());
+  }
+
+  @Test public void completeSegmentsEmitted() throws Exception {
+    Buffer sink = new Buffer();
+    BufferedSink bufferedSink = Okio.buffer((Sink) sink);
+    bufferedSink.writeUtf8(repeat("a", SEGMENT_SIZE * 3));
+    assertEquals(SEGMENT_SIZE * 3, sink.size());
+  }
+
+  @Test public void incompleteSegmentsNotEmitted() throws Exception {
+    Buffer sink = new Buffer();
+    BufferedSink bufferedSink = Okio.buffer((Sink) sink);
+    bufferedSink.writeUtf8(repeat("a", SEGMENT_SIZE * 3 - 1));
+    assertEquals(SEGMENT_SIZE * 2, sink.size());
+  }
+
+  @Test public void closeWithExceptionWhenWriting() throws IOException {
+    MockSink mockSink = new MockSink();
+    mockSink.scheduleThrow(0, new IOException());
+    BufferedSink bufferedSink = Okio.buffer(mockSink);
+    bufferedSink.writeByte('a');
+    try {
+      bufferedSink.close();
+      fail();
+    } catch (IOException expected) {
+    }
+    mockSink.assertLog("write([text=a], 1)", "close()");
+  }
+
+  @Test public void closeWithExceptionWhenClosing() throws IOException {
+    MockSink mockSink = new MockSink();
+    mockSink.scheduleThrow(1, new IOException());
+    BufferedSink bufferedSink = Okio.buffer(mockSink);
+    bufferedSink.writeByte('a');
+    try {
+      bufferedSink.close();
+      fail();
+    } catch (IOException expected) {
+    }
+    mockSink.assertLog("write([text=a], 1)", "close()");
+  }
+
+  @Test public void closeWithExceptionWhenWritingAndClosing() throws IOException {
+    MockSink mockSink = new MockSink();
+    mockSink.scheduleThrow(0, new IOException("first"));
+    mockSink.scheduleThrow(1, new IOException("second"));
+    BufferedSink bufferedSink = Okio.buffer(mockSink);
+    bufferedSink.writeByte('a');
+    try {
+      bufferedSink.close();
+      fail();
+    } catch (IOException expected) {
+      assertEquals("first", expected.getMessage());
+    }
+    mockSink.assertLog("write([text=a], 1)", "close()");
+  }
+
+  @Test public void operationsAfterClose() throws IOException {
+    MockSink mockSink = new MockSink();
+    BufferedSink bufferedSink = Okio.buffer(mockSink);
+    bufferedSink.writeByte('a');
+    bufferedSink.close();
+
+    // Test a sample set of methods.
+    try {
+      bufferedSink.writeByte('a');
+      fail();
+    } catch (IllegalStateException expected) {
+    }
+
+    try {
+      bufferedSink.write(new byte[10]);
+      fail();
+    } catch (IllegalStateException expected) {
+    }
+
+    try {
+      bufferedSink.emitCompleteSegments();
+      fail();
+    } catch (IllegalStateException expected) {
+    }
+
+    try {
+      bufferedSink.emit();
+      fail();
+    } catch (IllegalStateException expected) {
+    }
+
+    try {
+      bufferedSink.flush();
+      fail();
+    } catch (IllegalStateException expected) {
+    }
+
+    // Test a sample set of methods on the OutputStream.
+    OutputStream os = bufferedSink.outputStream();
+    try {
+      os.write('a');
+      fail();
+    } catch (IOException expected) {
+    }
+
+    try {
+      os.write(new byte[10]);
+      fail();
+    } catch (IOException expected) {
+    }
+
+    // Permitted
+    os.flush();
+  }
+
+  @Test public void writeAll() throws IOException {
+    MockSink mockSink = new MockSink();
+    BufferedSink bufferedSink = Okio.buffer(mockSink);
+
+    bufferedSink.getBuffer().writeUtf8("abc");
+    assertEquals(3, bufferedSink.writeAll(new Buffer().writeUtf8("def")));
+
+    assertEquals(6, bufferedSink.getBuffer().size());
+    assertEquals("abcdef", bufferedSink.getBuffer().readUtf8(6));
+    mockSink.assertLog(); // No writes.
+ }
+
+  @Test public void writeAllExhausted() throws IOException {
+    MockSink mockSink = new MockSink();
+    BufferedSink bufferedSink = Okio.buffer(mockSink);
+
+    assertEquals(0, bufferedSink.writeAll(new Buffer()));
+    assertEquals(0, bufferedSink.getBuffer().size());
+    mockSink.assertLog(); // No writes.
+ }
+
+  @Test public void writeAllWritesOneSegmentAtATime() throws IOException {
+    Buffer write1 = new Buffer().writeUtf8(repeat("a", SEGMENT_SIZE));
+    Buffer write2 = new Buffer().writeUtf8(repeat("b", SEGMENT_SIZE));
+    Buffer write3 = new Buffer().writeUtf8(repeat("c", SEGMENT_SIZE));
+
+    Buffer source = new Buffer().writeUtf8(""
+        + repeat("a", SEGMENT_SIZE)
+        + repeat("b", SEGMENT_SIZE)
+        + repeat("c", SEGMENT_SIZE));
+
+    MockSink mockSink = new MockSink();
+    BufferedSink bufferedSink = Okio.buffer(mockSink);
+    assertEquals(SEGMENT_SIZE * 3, bufferedSink.writeAll(source));
+
+    mockSink.assertLog(
+        "write(" + write1 + ", " + write1.size() + ")",
+        "write(" + write2 + ", " + write2.size() + ")",
+        "write(" + write3 + ", " + write3.size() + ")");
+ }
+}
diff --git a/okio/src/jvmTest/java/okio/BufferedSinkTest.java b/okio/src/jvmTest/java/okio/BufferedSinkTest.java
new file mode 100644
index 0000000..e013284
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/BufferedSinkTest.java
@@ -0,0 +1,380 @@
+/*
+ * 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 okio;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+import static java.util.Arrays.asList;
+import static kotlin.text.Charsets.UTF_8;
+import static kotlin.text.StringsKt.repeat;
+import static okio.TestUtil.SEGMENT_SIZE;
+import static okio.TestUtil.segmentSizes;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+@RunWith(Parameterized.class)
+public final class BufferedSinkTest {
+  private interface Factory {
+    Factory BUFFER = new Factory() {
+      @Override public BufferedSink create(Buffer data) {
+        return data;
+      }
+
+      @Override public String toString() {
+        return "Buffer";
+      }
+    };
+
+    Factory REAL_BUFFERED_SINK = new Factory() {
+      @Override public BufferedSink create(Buffer data) {
+        return Okio.buffer((Sink) data);
+      }
+
+      @Override public String toString() {
+        return "RealBufferedSink";
+      }
+    };
+
+    BufferedSink create(Buffer data);
+  }
+
+  @Parameters(name = "{0}")
+  public static List<Object[]> parameters() {
+    return Arrays.asList(
+        new Object[] {Factory.BUFFER},
+        new Object[] {Factory.REAL_BUFFERED_SINK});
+  }
+
+  @Parameter public Factory factory;
+  private Buffer data;
+  private BufferedSink sink;
+
+  @Before public void setUp() {
+    data = new Buffer();
+    sink = factory.create(data);
+  }
+
+  @Test public void writeNothing() throws IOException {
+    sink.writeUtf8("");
+    sink.flush();
+    assertEquals(0, data.size());
+  }
+
+  @Test public void writeBytes() throws Exception {
+    sink.writeByte(0xab);
+    sink.writeByte(0xcd);
+    sink.flush();
+    assertEquals("[hex=abcd]", data.toString());
+  }
+
+  @Test public void writeLastByteInSegment() throws Exception {
+    sink.writeUtf8(repeat("a", SEGMENT_SIZE - 1));
+    sink.writeByte(0x20);
+    sink.writeByte(0x21);
+    sink.flush();
+    assertEquals(asList(SEGMENT_SIZE, 1), segmentSizes(data));
+    assertEquals(repeat("a", SEGMENT_SIZE - 1), data.readUtf8(SEGMENT_SIZE - 1));
+    assertEquals("[text= !]", data.toString());
+  }
+
+  @Test public void writeShort() throws Exception {
+    sink.writeShort(0xabcd);
+    sink.writeShort(0x4321);
+    sink.flush();
+    assertEquals("[hex=abcd4321]", data.toString());
+  }
+
+  @Test public void writeShortLe() throws Exception {
+    sink.writeShortLe(0xcdab);
+    sink.writeShortLe(0x2143);
+    sink.flush();
+    assertEquals("[hex=abcd4321]", data.toString());
+  }
+
+  @Test public void writeInt() throws Exception {
+    sink.writeInt(0xabcdef01);
+    sink.writeInt(0x87654321);
+    sink.flush();
+    assertEquals("[hex=abcdef0187654321]", data.toString());
+  }
+
+  @Test public void writeLastIntegerInSegment() throws Exception {
+    sink.writeUtf8(repeat("a", SEGMENT_SIZE - 4));
+    sink.writeInt(0xabcdef01);
+    sink.writeInt(0x87654321);
+    sink.flush();
+    assertEquals(asList(SEGMENT_SIZE, 4), segmentSizes(data));
+    assertEquals(repeat("a", SEGMENT_SIZE - 4), data.readUtf8(SEGMENT_SIZE - 4));
+    assertEquals("[hex=abcdef0187654321]", data.toString());
+  }
+
+  @Test public void writeIntegerDoesNotQuiteFitInSegment() throws Exception {
+    sink.writeUtf8(repeat("a", SEGMENT_SIZE - 3));
+    sink.writeInt(0xabcdef01);
+    sink.writeInt(0x87654321);
+    sink.flush();
+    assertEquals(asList(SEGMENT_SIZE - 3, 8), segmentSizes(data));
+    assertEquals(repeat("a", SEGMENT_SIZE - 3), data.readUtf8(SEGMENT_SIZE - 3));
+    assertEquals("[hex=abcdef0187654321]", data.toString());
+  }
+
+  @Test public void writeIntLe() throws Exception {
+    sink.writeIntLe(0xabcdef01);
+    sink.writeIntLe(0x87654321);
+    sink.flush();
+    assertEquals("[hex=01efcdab21436587]", data.toString());
+  }
+
+  @Test public void writeLong() throws Exception {
+    sink.writeLong(0xabcdef0187654321L);
+    sink.writeLong(0xcafebabeb0b15c00L);
+    sink.flush();
+    assertEquals("[hex=abcdef0187654321cafebabeb0b15c00]", data.toString());
+  }
+
+  @Test public void writeLongLe() throws Exception {
+    sink.writeLongLe(0xabcdef0187654321L);
+    sink.writeLongLe(0xcafebabeb0b15c00L);
+    sink.flush();
+    assertEquals("[hex=2143658701efcdab005cb1b0bebafeca]", data.toString());
+  }
+
+  @Test public void writeByteString() throws IOException {
+    sink.write(ByteString.encodeUtf8("təˈranəˌsôr"));
+    sink.flush();
+    assertEquals(ByteString.decodeHex("74c999cb8872616ec999cb8c73c3b472"), data.readByteString());
+  }
+
+  @Test public void writeByteStringOffset() throws IOException {
+    sink.write(ByteString.encodeUtf8("təˈranəˌsôr"), 5, 5);
+    sink.flush();
+    assertEquals(ByteString.decodeHex("72616ec999"), data.readByteString());
+  }
+
+  @Test public void writeSegmentedByteString() throws IOException {
+    sink.write(new Buffer().write(ByteString.encodeUtf8("təˈranəˌsôr")).snapshot());
+    sink.flush();
+    assertEquals(ByteString.decodeHex("74c999cb8872616ec999cb8c73c3b472"), data.readByteString());
+  }
+
+  @Test public void writeSegmentedByteStringOffset() throws IOException {
+    sink.write(new Buffer().write(ByteString.encodeUtf8("təˈranəˌsôr")).snapshot(), 5, 5);
+    sink.flush();
+    assertEquals(ByteString.decodeHex("72616ec999"), data.readByteString());
+  }
+
+  @Test public void writeStringUtf8() throws IOException {
+    sink.writeUtf8("təˈranəˌsôr");
+    sink.flush();
+    assertEquals(ByteString.decodeHex("74c999cb8872616ec999cb8c73c3b472"), data.readByteString());
+  }
+
+  @Test public void writeSubstringUtf8() throws IOException {
+    sink.writeUtf8("təˈranəˌsôr", 3, 7);
+    sink.flush();
+    assertEquals(ByteString.decodeHex("72616ec999"), data.readByteString());
+  }
+
+  @Test public void writeStringWithCharset() throws IOException {
+    sink.writeString("təˈranəˌsôr", Charset.forName("utf-32be"));
+    sink.flush();
+    assertEquals(ByteString.decodeHex("0000007400000259000002c800000072000000610000006e00000259"
+        + "000002cc00000073000000f400000072"), data.readByteString());
+  }
+
+  @Test public void writeSubstringWithCharset() throws IOException {
+    sink.writeString("təˈranəˌsôr", 3, 7, Charset.forName("utf-32be"));
+    sink.flush();
+    assertEquals(ByteString.decodeHex("00000072000000610000006e00000259"), data.readByteString());
+  }
+
+  @Test public void writeUtf8SubstringWithCharset() throws IOException {
+    sink.writeString("təˈranəˌsôr", 3, 7, Charset.forName("utf-8"));
+    sink.flush();
+    assertEquals(ByteString.encodeUtf8("ranə"), data.readByteString());
+  }
+
+  @Test public void writeAll() throws Exception {
+    Buffer source = new Buffer().writeUtf8("abcdef");
+
+    assertEquals(6, sink.writeAll(source));
+    assertEquals(0, source.size());
+    sink.flush();
+    assertEquals("abcdef", data.readUtf8());
+  }
+
+  @Test public void writeSource() throws Exception {
+    Buffer source = new Buffer().writeUtf8("abcdef");
+
+    // Force resolution of the Source method overload.
+    sink.write((Source) source, 4);
+    sink.flush();
+    assertEquals("abcd", data.readUtf8());
+    assertEquals("ef", source.readUtf8());
+  }
+
+  @Test public void writeSourceReadsFully() throws Exception {
+    Source source = new ForwardingSource(new Buffer()) {
+      @Override public long read(Buffer sink, long byteCount) throws IOException {
+        sink.writeUtf8("abcd");
+        return 4;
+      }
+    };
+
+    sink.write(source, 8);
+    sink.flush();
+    assertEquals("abcdabcd", data.readUtf8());
+  }
+
+  @Test public void writeSourcePropagatesEof() throws IOException {
+    Source source = new Buffer().writeUtf8("abcd");
+
+    try {
+      sink.write(source, 8);
+      fail();
+    } catch (EOFException expected) {
+    }
+
+    // Ensure that whatever was available was correctly written.
+    sink.flush();
+    assertEquals("abcd", data.readUtf8());
+  }
+
+  @Test public void writeSourceWithZeroIsNoOp() throws IOException {
+    // This test ensures that a zero byte count never calls through to read the source. It may be
+    // tied to something like a socket which will potentially block trying to read a segment when
+    // ultimately we don't want any data.
+    Source source = new ForwardingSource(new Buffer()) {
+      @Override public long read(Buffer sink, long byteCount) throws IOException {
+        throw new AssertionError();
+      }
+    };
+    sink.write(source, 0);
+    assertEquals(0, data.size());
+  }
+
+  @Test public void writeAllExhausted() throws Exception {
+    Buffer source = new Buffer();
+    assertEquals(0, sink.writeAll(source));
+    assertEquals(0, source.size());
+  }
+
+  @Test public void closeEmitsBufferedBytes() throws IOException {
+    sink.writeByte('a');
+    sink.close();
+    assertEquals('a', data.readByte());
+  }
+
+  @Test public void outputStream() throws Exception {
+    OutputStream out = sink.outputStream();
+    out.write('a');
+    out.write(repeat("b", 9998).getBytes(UTF_8));
+    out.write('c');
+    out.flush();
+    assertEquals("a" + repeat("b", 9998) + "c", data.readUtf8());
+  }
+
+  @Test public void outputStreamBounds() throws Exception {
+    OutputStream out = sink.outputStream();
+    try {
+      out.write(new byte[100], 50, 51);
+      fail();
+    } catch (ArrayIndexOutOfBoundsException expected) {
+    }
+  }
+
+  @Test public void longDecimalString() throws IOException {
+    assertLongDecimalString(0);
+    assertLongDecimalString(Long.MIN_VALUE);
+    assertLongDecimalString(Long.MAX_VALUE);
+
+    for (int i = 1; i < 20; i++) {
+      long value = BigInteger.valueOf(10L).pow(i).longValue();
+      assertLongDecimalString(value - 1);
+      assertLongDecimalString(value);
+    }
+  }
+
+  private void assertLongDecimalString(long value) throws IOException {
+    sink.writeDecimalLong(value).writeUtf8("zzz").flush();
+    String expected = Long.toString(value) + "zzz";
+    String actual = data.readUtf8();
+    assertEquals(value + " expected " + expected + " but was " + actual, actual, expected);
+  }
+
+  @Test public void longHexString() throws IOException {
+    assertLongHexString(0);
+    assertLongHexString(Long.MIN_VALUE);
+    assertLongHexString(Long.MAX_VALUE);
+
+    for (int i = 0; i < 63; i++) {
+      assertLongHexString((1L << i) - 1);
+      assertLongHexString(1L << i);
+    }
+  }
+
+  @Test public void writeNioBuffer() throws Exception {
+    String expected = "abcdefg";
+
+    ByteBuffer nioByteBuffer = ByteBuffer.allocate(1024);
+    nioByteBuffer.put("abcdefg".getBytes(UTF_8));
+    nioByteBuffer.flip();
+
+    int byteCount = sink.write(nioByteBuffer);
+    assertEquals(expected.length(), byteCount);
+    assertEquals(expected.length(), nioByteBuffer.position());
+    assertEquals(expected.length(), nioByteBuffer.limit());
+
+    sink.flush();
+    assertEquals(expected, data.readUtf8());
+  }
+
+  @Test public void writeLargeNioBufferWritesAllData() throws Exception {
+    String expected = repeat("a", SEGMENT_SIZE * 3);
+
+    ByteBuffer nioByteBuffer = ByteBuffer.allocate(SEGMENT_SIZE * 4);
+    nioByteBuffer.put(repeat("a", SEGMENT_SIZE * 3).getBytes(UTF_8));
+    nioByteBuffer.flip();
+
+    int byteCount = sink.write(nioByteBuffer);
+    assertEquals(expected.length(), byteCount);
+    assertEquals(expected.length(), nioByteBuffer.position());
+    assertEquals(expected.length(), nioByteBuffer.limit());
+
+    sink.flush();
+    assertEquals(expected, data.readUtf8());
+  }
+
+  private void assertLongHexString(long value) throws IOException {
+    sink.writeHexadecimalUnsignedLong(value).writeUtf8("zzz").flush();
+    String expected = String.format("%x", value) + "zzz";
+    String actual = data.readUtf8();
+    assertEquals(value + " expected " + expected + " but was " + actual, actual, expected);
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/BufferedSourceJavaTest.java b/okio/src/jvmTest/java/okio/BufferedSourceJavaTest.java
new file mode 100644
index 0000000..470a2dd
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/BufferedSourceJavaTest.java
@@ -0,0 +1,232 @@
+/*
+ * 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 okio;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import org.junit.Test;
+
+import static kotlin.text.Charsets.UTF_8;
+import static kotlin.text.StringsKt.repeat;
+import static okio.TestUtil.SEGMENT_SIZE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests solely for the behavior of RealBufferedSource's implementation. For generic
+ * BufferedSource behavior use BufferedSourceTest.
+ */
+public final class BufferedSourceJavaTest {
+  @Test public void inputStreamTracksSegments() throws Exception {
+    Buffer source = new Buffer();
+    source.writeUtf8("a");
+    source.writeUtf8(repeat("b", SEGMENT_SIZE));
+    source.writeUtf8("c");
+
+    InputStream in = Okio.buffer((Source) source).inputStream();
+    assertEquals(0, in.available());
+    assertEquals(SEGMENT_SIZE + 2, source.size());
+
+    // Reading one byte buffers a full segment.
+    assertEquals('a', in.read());
+    assertEquals(SEGMENT_SIZE - 1, in.available());
+    assertEquals(2, source.size());
+
+    // Reading as much as possible reads the rest of that buffered segment.
+    byte[] data = new byte[SEGMENT_SIZE * 2];
+    assertEquals(SEGMENT_SIZE - 1, in.read(data, 0, data.length));
+    assertEquals(repeat("b", SEGMENT_SIZE - 1), new String(data, 0, SEGMENT_SIZE - 1, UTF_8));
+    assertEquals(2, source.size());
+
+    // Continuing to read buffers the next segment.
+    assertEquals('b', in.read());
+    assertEquals(1, in.available());
+    assertEquals(0, source.size());
+
+    // Continuing to read reads from the buffer.
+    assertEquals('c', in.read());
+    assertEquals(0, in.available());
+    assertEquals(0, source.size());
+
+    // Once we've exhausted the source, we're done.
+    assertEquals(-1, in.read());
+    assertEquals(0, source.size());
+  }
+
+  @Test public void inputStreamCloses() throws Exception {
+    BufferedSource source = Okio.buffer((Source) new Buffer());
+    InputStream in = source.inputStream();
+    in.close();
+    try {
+      source.require(1);
+      fail();
+    } catch (IllegalStateException e) {
+      assertEquals("closed", e.getMessage());
+    }
+  }
+
+  @Test public void indexOfStopsReadingAtLimit() throws Exception {
+    Buffer buffer = new Buffer().writeUtf8("abcdef");
+    BufferedSource bufferedSource = Okio.buffer(new ForwardingSource(buffer) {
+      @Override public long read(Buffer sink, long byteCount) throws IOException {
+        return super.read(sink, Math.min(1, byteCount));
+      }
+    });
+
+    assertEquals(6, buffer.size());
+    assertEquals(-1, bufferedSource.indexOf((byte) 'e', 0, 4));
+    assertEquals(2, buffer.size());
+  }
+
+  @Test public void requireTracksBufferFirst() throws Exception {
+    Buffer source = new Buffer();
+    source.writeUtf8("bb");
+
+    BufferedSource bufferedSource = Okio.buffer((Source) source);
+    bufferedSource.getBuffer().writeUtf8("aa");
+
+    bufferedSource.require(2);
+    assertEquals(2, bufferedSource.getBuffer().size());
+    assertEquals(2, source.size());
+  }
+
+  @Test public void requireIncludesBufferBytes() throws Exception {
+    Buffer source = new Buffer();
+    source.writeUtf8("b");
+
+    BufferedSource bufferedSource = Okio.buffer((Source) source);
+    bufferedSource.getBuffer().writeUtf8("a");
+
+    bufferedSource.require(2);
+    assertEquals("ab", bufferedSource.getBuffer().readUtf8(2));
+  }
+
+  @Test public void requireInsufficientData() throws Exception {
+    Buffer source = new Buffer();
+    source.writeUtf8("a");
+
+    BufferedSource bufferedSource = Okio.buffer((Source) source);
+
+    try {
+      bufferedSource.require(2);
+      fail();
+    } catch (EOFException expected) {
+    }
+  }
+
+  @Test public void requireReadsOneSegmentAtATime() throws Exception {
+    Buffer source = new Buffer();
+    source.writeUtf8(repeat("a", SEGMENT_SIZE));
+    source.writeUtf8(repeat("b", SEGMENT_SIZE));
+
+    BufferedSource bufferedSource = Okio.buffer((Source) source);
+
+    bufferedSource.require(2);
+    assertEquals(SEGMENT_SIZE, source.size());
+    assertEquals(SEGMENT_SIZE, bufferedSource.getBuffer().size());
+  }
+
+  @Test public void skipReadsOneSegmentAtATime() throws Exception {
+    Buffer source = new Buffer();
+    source.writeUtf8(repeat("a", SEGMENT_SIZE));
+    source.writeUtf8(repeat("b", SEGMENT_SIZE));
+    BufferedSource bufferedSource = Okio.buffer((Source) source);
+    bufferedSource.skip(2);
+    assertEquals(SEGMENT_SIZE, source.size());
+    assertEquals(SEGMENT_SIZE - 2, bufferedSource.getBuffer().size());
+  }
+
+  @Test public void skipTracksBufferFirst() throws Exception {
+    Buffer source = new Buffer();
+    source.writeUtf8("bb");
+
+    BufferedSource bufferedSource = Okio.buffer((Source) source);
+    bufferedSource.getBuffer().writeUtf8("aa");
+
+    bufferedSource.skip(2);
+    assertEquals(0, bufferedSource.getBuffer().size());
+    assertEquals(2, source.size());
+  }
+
+  @Test public void operationsAfterClose() throws IOException {
+    Buffer source = new Buffer();
+    BufferedSource bufferedSource = Okio.buffer((Source) source);
+    bufferedSource.close();
+
+    // Test a sample set of methods.
+    try {
+      bufferedSource.indexOf((byte) 1);
+      fail();
+    } catch (IllegalStateException expected) {
+    }
+
+    try {
+      bufferedSource.skip(1);
+      fail();
+    } catch (IllegalStateException expected) {
+    }
+
+    try {
+      bufferedSource.readByte();
+      fail();
+    } catch (IllegalStateException expected) {
+    }
+
+    try {
+      bufferedSource.readByteString(10);
+      fail();
+    } catch (IllegalStateException expected) {
+    }
+
+    // Test a sample set of methods on the InputStream.
+    InputStream is = bufferedSource.inputStream();
+    try {
+      is.read();
+      fail();
+    } catch (IOException expected) {
+    }
+
+    try {
+      is.read(new byte[10]);
+      fail();
+    } catch (IOException expected) {
+    }
+  }
+
+  /**
+   * We don't want readAll to buffer an unbounded amount of data. Instead it
+   * should buffer a segment, write it, and repeat.
+   */
+  @Test public void readAllReadsOneSegmentAtATime() throws IOException {
+    Buffer write1 = new Buffer().writeUtf8(repeat("a", SEGMENT_SIZE));
+    Buffer write2 = new Buffer().writeUtf8(repeat("b", SEGMENT_SIZE));
+    Buffer write3 = new Buffer().writeUtf8(repeat("c", SEGMENT_SIZE));
+
+    Buffer source = new Buffer().writeUtf8(""
+        + repeat("a", SEGMENT_SIZE)
+        + repeat("b", SEGMENT_SIZE)
+        + repeat("c", SEGMENT_SIZE));
+
+    MockSink mockSink = new MockSink();
+    BufferedSource bufferedSource = Okio.buffer((Source) source);
+    assertEquals(SEGMENT_SIZE * 3, bufferedSource.readAll(mockSink));
+    mockSink.assertLog(
+        "write(" + write1 + ", " + write1.size() + ")",
+        "write(" + write2 + ", " + write2.size() + ")",
+        "write(" + write3 + ", " + write3.size() + ")");
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/BufferedSourceTest.java b/okio/src/jvmTest/java/okio/BufferedSourceTest.java
new file mode 100644
index 0000000..149ae64
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/BufferedSourceTest.java
@@ -0,0 +1,1492 @@
+/*
+ * 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 okio;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+import static kotlin.text.Charsets.US_ASCII;
+import static kotlin.text.Charsets.UTF_8;
+import static kotlin.text.StringsKt.repeat;
+import static okio.TestUtil.SEGMENT_SIZE;
+import static okio.TestUtil.assertByteArrayEquals;
+import static okio.TestUtil.assertByteArraysEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+@RunWith(Parameterized.class)
+public final class BufferedSourceTest {
+  interface Factory {
+    Factory BUFFER = new Factory() {
+      @Override public Pipe pipe() {
+        Buffer buffer = new Buffer();
+        Pipe result = new Pipe();
+        result.sink = buffer;
+        result.source = buffer;
+        return result;
+      }
+
+      @Override public boolean isOneByteAtATime() {
+        return false;
+      }
+
+      @Override public String toString() {
+        return "Buffer";
+      }
+    };
+
+    Factory REAL_BUFFERED_SOURCE = new Factory() {
+      @Override public Pipe pipe() {
+        Buffer buffer = new Buffer();
+        Pipe result = new Pipe();
+        result.sink = buffer;
+        result.source = Okio.buffer((Source) buffer);
+        return result;
+      }
+
+      @Override public boolean isOneByteAtATime() {
+        return false;
+      }
+
+      @Override public String toString() {
+        return "RealBufferedSource";
+      }
+    };
+
+    /**
+     * A factory deliberately written to create buffers whose internal segments are always 1 byte
+     * long. We like testing with these segments because are likely to trigger bugs!
+     */
+    Factory ONE_BYTE_AT_A_TIME_BUFFERED_SOURCE = new Factory() {
+      @Override public Pipe pipe() {
+        Buffer buffer = new Buffer();
+        Pipe result = new Pipe();
+        result.sink = buffer;
+        result.source = Okio.buffer(new ForwardingSource(buffer) {
+          @Override public long read(Buffer sink, long byteCount) throws IOException {
+            // Read one byte into a new buffer, then clone it so that the segment is shared.
+            // Shared segments cannot be compacted so we'll get a long chain of short segments.
+            Buffer box = new Buffer();
+            long result = super.read(box, Math.min(byteCount, 1L));
+            if (result > 0L) sink.write(box.clone(), result);
+            return result;
+          }
+        });
+        return result;
+      }
+
+      @Override public boolean isOneByteAtATime() {
+        return true;
+      }
+
+      @Override public String toString() {
+        return "OneByteAtATimeBufferedSource";
+      }
+    };
+
+    Factory ONE_BYTE_AT_A_TIME_BUFFER = new Factory() {
+      @Override public Pipe pipe() {
+        Buffer buffer = new Buffer();
+        Pipe result = new Pipe();
+        result.source = buffer;
+        result.sink = Okio.buffer(new ForwardingSink(buffer) {
+          @Override public void write(Buffer source, long byteCount) throws IOException {
+            // Write each byte into a new buffer, then clone it so that the segments are shared.
+            // Shared segments cannot be compacted so we'll get a long chain of short segments.
+            for (int i = 0; i < byteCount; i++) {
+              Buffer box = new Buffer();
+              box.write(source, 1);
+              super.write(box.clone(), 1);
+            }
+          }
+        });
+        return result;
+      }
+
+      @Override public boolean isOneByteAtATime() {
+        return true;
+      }
+
+      @Override public String toString() {
+        return "OneByteAtATimeBuffer";
+      }
+    };
+
+    Factory PEEK_BUFFER = new Factory() {
+      @Override public Pipe pipe() {
+        Buffer buffer = new Buffer();
+        Pipe result = new Pipe();
+        result.sink = buffer;
+        result.source = buffer.peek();
+        return result;
+      }
+
+      @Override public boolean isOneByteAtATime() {
+        return false;
+      }
+
+      @Override public String toString() {
+        return "PeekBuffer";
+      }
+    };
+
+    Factory PEEK_BUFFERED_SOURCE = new Factory() {
+      @Override public Pipe pipe() {
+        Buffer buffer = new Buffer();
+        Pipe result = new Pipe();
+        result.sink = buffer;
+        result.source = Okio.buffer((Source) buffer).peek();
+        return result;
+      }
+
+      @Override public boolean isOneByteAtATime() {
+        return false;
+      }
+
+      @Override public String toString() {
+        return "PeekBufferedSource";
+      }
+    };
+
+    Pipe pipe();
+
+    boolean isOneByteAtATime();
+  }
+
+  private static class Pipe {
+    BufferedSink sink;
+    BufferedSource source;
+  }
+
+  @Parameters(name = "{0}")
+  public static List<Object[]> parameters() {
+    return Arrays.asList(
+        new Object[] { Factory.BUFFER },
+        new Object[] { Factory.REAL_BUFFERED_SOURCE },
+        new Object[] { Factory.ONE_BYTE_AT_A_TIME_BUFFERED_SOURCE },
+        new Object[] { Factory.ONE_BYTE_AT_A_TIME_BUFFER },
+        new Object[] { Factory.PEEK_BUFFER },
+        new Object[] { Factory.PEEK_BUFFERED_SOURCE });
+  }
+
+  @Parameter public Factory factory;
+  private BufferedSink sink;
+  private BufferedSource source;
+
+  @Before public void setUp() {
+    Pipe pipe = factory.pipe();
+    sink = pipe.sink;
+    source = pipe.source;
+  }
+
+  @Test public void readBytes() throws Exception {
+    sink.write(new byte[] { (byte) 0xab, (byte) 0xcd });
+    sink.emit();
+    assertEquals(0xab, source.readByte() & 0xff);
+    assertEquals(0xcd, source.readByte() & 0xff);
+    assertTrue(source.exhausted());
+  }
+
+  @Test public void readByteTooShortThrows() throws IOException {
+    try {
+      source.readByte();
+      fail();
+    } catch (EOFException expected) {
+    }
+  }
+
+  @Test public void readShort() throws Exception {
+    sink.write(new byte[] {
+        (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x01
+    });
+    sink.emit();
+    assertEquals((short) 0xabcd, source.readShort());
+    assertEquals((short) 0xef01, source.readShort());
+    assertTrue(source.exhausted());
+  }
+
+  @Test public void readShortLe() throws Exception {
+    sink.write(new byte[] {
+        (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x10
+    });
+    sink.emit();
+    assertEquals((short) 0xcdab, source.readShortLe());
+    assertEquals((short) 0x10ef, source.readShortLe());
+    assertTrue(source.exhausted());
+  }
+
+  @Test public void readShortSplitAcrossMultipleSegments() throws Exception {
+    sink.writeUtf8(repeat("a", SEGMENT_SIZE - 1));
+    sink.write(new byte[] { (byte) 0xab, (byte) 0xcd });
+    sink.emit();
+    source.skip(SEGMENT_SIZE - 1);
+    assertEquals((short) 0xabcd, source.readShort());
+    assertTrue(source.exhausted());
+  }
+
+  @Test public void readShortTooShortThrows() throws IOException {
+    sink.writeShort(Short.MAX_VALUE);
+    sink.emit();
+    source.readByte();
+    try {
+      source.readShort();
+      fail();
+    } catch (EOFException expected) {
+    }
+  }
+
+  @Test public void readShortLeTooShortThrows() throws IOException {
+    sink.writeShortLe(Short.MAX_VALUE);
+    sink.emit();
+    source.readByte();
+    try {
+      source.readShortLe();
+      fail();
+    } catch (EOFException expected) {
+    }
+  }
+
+  @Test public void readInt() throws Exception {
+    sink.write(new byte[] {
+        (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x01, (byte) 0x87, (byte) 0x65, (byte) 0x43,
+        (byte) 0x21
+    });
+    sink.emit();
+    assertEquals(0xabcdef01, source.readInt());
+    assertEquals(0x87654321, source.readInt());
+    assertTrue(source.exhausted());
+  }
+
+  @Test public void readIntLe() throws Exception {
+    sink.write(new byte[] {
+        (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x10, (byte) 0x87, (byte) 0x65, (byte) 0x43,
+        (byte) 0x21
+    });
+    sink.emit();
+    assertEquals(0x10efcdab, source.readIntLe());
+    assertEquals(0x21436587, source.readIntLe());
+    assertTrue(source.exhausted());
+  }
+
+  @Test public void readIntSplitAcrossMultipleSegments() throws Exception {
+    sink.writeUtf8(repeat("a", SEGMENT_SIZE - 3));
+    sink.write(new byte[] {
+        (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x01
+    });
+    sink.emit();
+    source.skip(SEGMENT_SIZE - 3);
+    assertEquals(0xabcdef01, source.readInt());
+    assertTrue(source.exhausted());
+  }
+
+  @Test public void readIntTooShortThrows() throws IOException {
+    sink.writeInt(Integer.MAX_VALUE);
+    sink.emit();
+    source.readByte();
+    try {
+      source.readInt();
+      fail();
+    } catch (EOFException expected) {
+    }
+  }
+
+  @Test public void readIntLeTooShortThrows() throws IOException {
+    sink.writeIntLe(Integer.MAX_VALUE);
+    sink.emit();
+    source.readByte();
+    try {
+      source.readIntLe();
+      fail();
+    } catch (EOFException expected) {
+    }
+  }
+
+  @Test public void readLong() throws Exception {
+    sink.write(new byte[] {
+        (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x10, (byte) 0x87, (byte) 0x65, (byte) 0x43,
+        (byte) 0x21, (byte) 0x36, (byte) 0x47, (byte) 0x58, (byte) 0x69, (byte) 0x12, (byte) 0x23,
+        (byte) 0x34, (byte) 0x45
+    });
+    sink.emit();
+    assertEquals(0xabcdef1087654321L, source.readLong());
+    assertEquals(0x3647586912233445L, source.readLong());
+    assertTrue(source.exhausted());
+  }
+
+  @Test public void readLongLe() throws Exception {
+    sink.write(new byte[] {
+        (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x10, (byte) 0x87, (byte) 0x65, (byte) 0x43,
+        (byte) 0x21, (byte) 0x36, (byte) 0x47, (byte) 0x58, (byte) 0x69, (byte) 0x12, (byte) 0x23,
+        (byte) 0x34, (byte) 0x45
+    });
+    sink.emit();
+    assertEquals(0x2143658710efcdabL, source.readLongLe());
+    assertEquals(0x4534231269584736L, source.readLongLe());
+    assertTrue(source.exhausted());
+  }
+
+  @Test public void readLongSplitAcrossMultipleSegments() throws Exception {
+    sink.writeUtf8(repeat("a", SEGMENT_SIZE - 7));
+    sink.write(new byte[] {
+        (byte) 0xab, (byte) 0xcd, (byte) 0xef, (byte) 0x01, (byte) 0x87, (byte) 0x65, (byte) 0x43,
+        (byte) 0x21,
+    });
+    sink.emit();
+    source.skip(SEGMENT_SIZE - 7);
+    assertEquals(0xabcdef0187654321L, source.readLong());
+    assertTrue(source.exhausted());
+  }
+
+  @Test public void readLongTooShortThrows() throws IOException {
+    sink.writeLong(Long.MAX_VALUE);
+    sink.emit();
+    source.readByte();
+    try {
+      source.readLong();
+      fail();
+    } catch (EOFException expected) {
+    }
+  }
+
+  @Test public void readLongLeTooShortThrows() throws IOException {
+    sink.writeLongLe(Long.MAX_VALUE);
+    sink.emit();
+    source.readByte();
+    try {
+      source.readLongLe();
+      fail();
+    } catch (EOFException expected) {
+    }
+  }
+
+  @Test public void readAll() throws IOException {
+    source.getBuffer().writeUtf8("abc");
+    sink.writeUtf8("def");
+    sink.emit();
+
+    Buffer sink = new Buffer();
+    assertEquals(6, source.readAll(sink));
+    assertEquals("abcdef", sink.readUtf8());
+    assertTrue(source.exhausted());
+  }
+
+  @Test public void readAllExhausted() throws IOException {
+    MockSink mockSink = new MockSink();
+    assertEquals(0, source.readAll(mockSink));
+    assertTrue(source.exhausted());
+    mockSink.assertLog();
+  }
+
+  @Test public void readExhaustedSource() throws Exception {
+    Buffer sink = new Buffer();
+    sink.writeUtf8(repeat("a", 10));
+    assertEquals(-1, source.read(sink, 10));
+    assertEquals(10, sink.size());
+    assertTrue(source.exhausted());
+  }
+
+  @Test public void readZeroBytesFromSource() throws Exception {
+    Buffer sink = new Buffer();
+    sink.writeUtf8(repeat("a", 10));
+
+    // Either 0 or -1 is reasonable here. For consistency with Android's
+    // ByteArrayInputStream we return 0.
+    assertEquals(-1, source.read(sink, 0));
+    assertEquals(10, sink.size());
+    assertTrue(source.exhausted());
+  }
+
+  @Test public void readFully() throws Exception {
+    sink.writeUtf8(repeat("a", 10000));
+    sink.emit();
+    Buffer sink = new Buffer();
+    source.readFully(sink, 9999);
+    assertEquals(repeat("a", 9999), sink.readUtf8());
+    assertEquals("a", source.readUtf8());
+  }
+
+  @Test public void readFullyTooShortThrows() throws IOException {
+    sink.writeUtf8("Hi");
+    sink.emit();
+    Buffer sink = new Buffer();
+    try {
+      source.readFully(sink, 5);
+      fail();
+    } catch (EOFException ignored) {
+    }
+
+    // Verify we read all that we could from the source.
+    assertEquals("Hi", sink.readUtf8());
+  }
+
+  @Test public void readFullyByteArray() throws IOException {
+    Buffer data = new Buffer();
+    data.writeUtf8("Hello").writeUtf8(repeat("e", SEGMENT_SIZE));
+
+    byte[] expected = data.clone().readByteArray();
+    sink.write(data, data.size());
+    sink.emit();
+
+    byte[] sink = new byte[SEGMENT_SIZE + 5];
+    source.readFully(sink);
+    assertByteArraysEquals(expected, sink);
+  }
+
+  @Test public void readFullyByteArrayTooShortThrows() throws IOException {
+    sink.writeUtf8("Hello");
+    sink.emit();
+
+    byte[] array = new byte[6];
+    try {
+      source.readFully(array);
+      fail();
+    } catch (EOFException ignored) {
+    }
+
+    // Verify we read all that we could from the source.
+    assertByteArraysEquals(new byte[] { 'H', 'e', 'l', 'l', 'o', 0 }, array);
+  }
+
+  @Test public void readIntoByteArray() throws IOException {
+    sink.writeUtf8("abcd");
+    sink.emit();
+
+    byte[] sink = new byte[3];
+    int read = source.read(sink);
+    if (factory.isOneByteAtATime()) {
+      assertEquals(1, read);
+      byte[] expected = { 'a', 0, 0 };
+      assertByteArraysEquals(expected, sink);
+    } else {
+      assertEquals(3, read);
+      byte[] expected = { 'a', 'b', 'c' };
+      assertByteArraysEquals(expected, sink);
+    }
+  }
+
+  @Test public void readIntoByteArrayNotEnough() throws IOException {
+    sink.writeUtf8("abcd");
+    sink.emit();
+
+    byte[] sink = new byte[5];
+    int read = source.read(sink);
+    if (factory.isOneByteAtATime()) {
+      assertEquals(1, read);
+      byte[] expected = { 'a', 0, 0, 0, 0 };
+      assertByteArraysEquals(expected, sink);
+    } else {
+      assertEquals(4, read);
+      byte[] expected = { 'a', 'b', 'c', 'd', 0 };
+      assertByteArraysEquals(expected, sink);
+    }
+  }
+
+  @Test public void readIntoByteArrayOffsetAndCount() throws IOException {
+    sink.writeUtf8("abcd");
+    sink.emit();
+
+    byte[] sink = new byte[7];
+    int read = source.read(sink, 2, 3);
+    if (factory.isOneByteAtATime()) {
+      assertEquals(1, read);
+      byte[] expected = { 0, 0, 'a', 0, 0, 0, 0 };
+      assertByteArraysEquals(expected, sink);
+    } else {
+      assertEquals(3, read);
+      byte[] expected = { 0, 0, 'a', 'b', 'c', 0, 0 };
+      assertByteArraysEquals(expected, sink);
+    }
+  }
+
+  @Test public void readByteArray() throws IOException {
+    String string = "abcd" + repeat("e", SEGMENT_SIZE);
+    sink.writeUtf8(string);
+    sink.emit();
+    assertByteArraysEquals(string.getBytes(UTF_8), source.readByteArray());
+  }
+
+  @Test public void readByteArrayPartial() throws IOException {
+    sink.writeUtf8("abcd");
+    sink.emit();
+    assertEquals("[97, 98, 99]", Arrays.toString(source.readByteArray(3)));
+    assertEquals("d", source.readUtf8(1));
+  }
+
+  @Test public void readByteArrayTooShortThrows() throws IOException {
+    sink.writeUtf8("abc");
+    sink.emit();
+    try {
+      source.readByteArray(4);
+      fail();
+    } catch (EOFException expected) {
+    }
+    assertEquals("abc", source.readUtf8()); // The read shouldn't consume any data.
+  }
+
+  @Test public void readByteString() throws IOException {
+    sink.writeUtf8("abcd").writeUtf8(repeat("e", SEGMENT_SIZE));
+    sink.emit();
+    assertEquals("abcd" + repeat("e", SEGMENT_SIZE), source.readByteString().utf8());
+  }
+
+  @Test public void readByteStringPartial() throws IOException {
+    sink.writeUtf8("abcd").writeUtf8(repeat("e", SEGMENT_SIZE));
+    sink.emit();
+    assertEquals("abc", source.readByteString(3).utf8());
+    assertEquals("d", source.readUtf8(1));
+  }
+
+  @Test public void readByteStringTooShortThrows() throws IOException {
+    sink.writeUtf8("abc");
+    sink.emit();
+    try {
+      source.readByteString(4);
+      fail();
+    } catch (EOFException expected) {
+    }
+    assertEquals("abc", source.readUtf8()); // The read shouldn't consume any data.
+  }
+
+  @Test public void readSpecificCharsetPartial() throws Exception {
+    sink.write(ByteString.decodeHex("0000007600000259000002c80000006c000000e40000007300000259"
+        + "000002cc000000720000006100000070000000740000025900000072"));
+    sink.emit();
+    assertEquals("vəˈläsə", source.readString(7 * 4, Charset.forName("utf-32")));
+  }
+
+  @Test public void readSpecificCharset() throws Exception {
+    sink.write(ByteString.decodeHex("0000007600000259000002c80000006c000000e40000007300000259"
+        + "000002cc000000720000006100000070000000740000025900000072"));
+    sink.emit();
+    assertEquals("vəˈläsəˌraptər", source.readString(Charset.forName("utf-32")));
+  }
+
+  @Test public void readStringTooShortThrows() throws IOException {
+    sink.writeString("abc", US_ASCII);
+    sink.emit();
+    try {
+      source.readString(4, US_ASCII);
+      fail();
+    } catch (EOFException expected) {
+    }
+    assertEquals("abc", source.readUtf8()); // The read shouldn't consume any data.
+  }
+
+  @Test public void readUtf8SpansSegments() throws Exception {
+    sink.writeUtf8(repeat("a", SEGMENT_SIZE * 2));
+    sink.emit();
+    source.skip(SEGMENT_SIZE - 1);
+    assertEquals("aa", source.readUtf8(2));
+  }
+
+  @Test public void readUtf8Segment() throws Exception {
+    sink.writeUtf8(repeat("a", SEGMENT_SIZE));
+    sink.emit();
+    assertEquals(repeat("a", SEGMENT_SIZE), source.readUtf8(SEGMENT_SIZE));
+  }
+
+  @Test public void readUtf8PartialBuffer() throws Exception {
+    sink.writeUtf8(repeat("a", SEGMENT_SIZE + 20));
+    sink.emit();
+    assertEquals(repeat("a", SEGMENT_SIZE + 10), source.readUtf8(SEGMENT_SIZE + 10));
+  }
+
+  @Test public void readUtf8EntireBuffer() throws Exception {
+    sink.writeUtf8(repeat("a", SEGMENT_SIZE * 2));
+    sink.emit();
+    assertEquals(repeat("a", SEGMENT_SIZE * 2), source.readUtf8());
+  }
+
+  @Test public void readUtf8TooShortThrows() throws IOException {
+    sink.writeUtf8("abc");
+    sink.emit();
+    try {
+      source.readUtf8(4L);
+      fail();
+    } catch (EOFException expected) {
+    }
+    assertEquals("abc", source.readUtf8()); // The read shouldn't consume any data.
+  }
+
+  @Test public void skip() throws Exception {
+    sink.writeUtf8("a");
+    sink.writeUtf8(repeat("b", SEGMENT_SIZE));
+    sink.writeUtf8("c");
+    sink.emit();
+    source.skip(1);
+    assertEquals('b', source.readByte() & 0xff);
+    source.skip(SEGMENT_SIZE - 2);
+    assertEquals('b', source.readByte() & 0xff);
+    source.skip(1);
+    assertTrue(source.exhausted());
+  }
+
+  @Test public void skipInsufficientData() throws Exception {
+    sink.writeUtf8("a");
+    sink.emit();
+
+    try {
+      source.skip(2);
+      fail();
+    } catch (EOFException ignored) {
+    }
+  }
+
+  @Test public void indexOf() throws Exception {
+    // The segment is empty.
+    assertEquals(-1, source.indexOf((byte) 'a'));
+
+    // The segment has one value.
+    sink.writeUtf8("a"); // a
+    sink.emit();
+    assertEquals(0, source.indexOf((byte) 'a'));
+    assertEquals(-1, source.indexOf((byte) 'b'));
+
+    // The segment has lots of data.
+    sink.writeUtf8(repeat("b", SEGMENT_SIZE - 2)); // ab...b
+    sink.emit();
+    assertEquals(0, source.indexOf((byte) 'a'));
+    assertEquals(1, source.indexOf((byte) 'b'));
+    assertEquals(-1, source.indexOf((byte) 'c'));
+
+    // The segment doesn't start at 0, it starts at 2.
+    source.skip(2); // b...b
+    assertEquals(-1, source.indexOf((byte) 'a'));
+    assertEquals(0, source.indexOf((byte) 'b'));
+    assertEquals(-1, source.indexOf((byte) 'c'));
+
+    // The segment is full.
+    sink.writeUtf8("c"); // b...bc
+    sink.emit();
+    assertEquals(-1, source.indexOf((byte) 'a'));
+    assertEquals(0, source.indexOf((byte) 'b'));
+    assertEquals(SEGMENT_SIZE - 3, source.indexOf((byte) 'c'));
+
+    // The segment doesn't start at 2, it starts at 4.
+    source.skip(2); // b...bc
+    assertEquals(-1, source.indexOf((byte) 'a'));
+    assertEquals(0, source.indexOf((byte) 'b'));
+    assertEquals(SEGMENT_SIZE - 5, source.indexOf((byte) 'c'));
+
+    // Two segments.
+    sink.writeUtf8("d"); // b...bcd, d is in the 2nd segment.
+    sink.emit();
+    assertEquals(SEGMENT_SIZE - 4, source.indexOf((byte) 'd'));
+    assertEquals(-1, source.indexOf((byte) 'e'));
+  }
+
+  @Test public void indexOfByteWithStartOffset() throws IOException {
+    sink.writeUtf8("a").writeUtf8(repeat("b", SEGMENT_SIZE)).writeUtf8("c");
+    sink.emit();
+    assertEquals(-1, source.indexOf((byte) 'a', 1));
+    assertEquals(15, source.indexOf((byte) 'b', 15));
+  }
+
+  @Test public void indexOfByteWithBothOffsets() throws IOException {
+    if (factory.isOneByteAtATime()) {
+      // When run on Travis this causes out-of-memory errors.
+      return;
+    }
+    byte a = (byte) 'a';
+    byte c = (byte) 'c';
+
+    int size = SEGMENT_SIZE * 5;
+    byte[] bytes = new byte[size];
+    Arrays.fill(bytes, a);
+
+    // These are tricky places where the buffer
+    // starts, ends, or segments come together.
+    int[] points = {
+        0,                       1,                   2,
+        SEGMENT_SIZE - 1,        SEGMENT_SIZE,        SEGMENT_SIZE + 1,
+        size / 2 - 1,            size / 2,            size / 2 + 1,
+        size - SEGMENT_SIZE - 1, size - SEGMENT_SIZE, size - SEGMENT_SIZE + 1,
+        size - 3,                size - 2,            size - 1
+    };
+
+    // In each iteration, we write c to the known point and then search for it using different
+    // windows. Some of the windows don't overlap with c's position, and therefore a match shouldn't
+    // be found.
+    for (int p : points) {
+      bytes[p] = c;
+      sink.write(bytes);
+      sink.emit();
+
+      assertEquals( p, source.indexOf(c, 0,      size     ));
+      assertEquals( p, source.indexOf(c, 0,      p + 1    ));
+      assertEquals( p, source.indexOf(c, p,      size     ));
+      assertEquals( p, source.indexOf(c, p,      p + 1    ));
+      assertEquals( p, source.indexOf(c, p / 2,  p * 2 + 1));
+      assertEquals(-1, source.indexOf(c, 0,      p / 2    ));
+      assertEquals(-1, source.indexOf(c, 0,      p        ));
+      assertEquals(-1, source.indexOf(c, 0,      0        ));
+      assertEquals(-1, source.indexOf(c, p,      p        ));
+
+      // Reset.
+      source.readUtf8();
+      bytes[p] = a;
+    }
+  }
+
+  @Test public void indexOfByteInvalidBoundsThrows() throws IOException {
+    sink.writeUtf8("abc");
+    sink.emit();
+
+    try {
+      source.indexOf((byte) 'a', -1);
+      fail("Expected failure: fromIndex < 0");
+    } catch (IllegalArgumentException expected) {
+    }
+
+    try {
+      source.indexOf((byte) 'a', 10, 0);
+      fail("Expected failure: fromIndex > toIndex");
+    } catch (IllegalArgumentException expected) {
+    }
+  }
+
+  @Test public void indexOfByteString() throws IOException {
+    assertEquals(-1, source.indexOf(ByteString.encodeUtf8("flop")));
+
+    sink.writeUtf8("flip flop");
+    sink.emit();
+    assertEquals(5, source.indexOf(ByteString.encodeUtf8("flop")));
+    source.readUtf8(); // Clear stream.
+
+    // Make sure we backtrack and resume searching after partial match.
+    sink.writeUtf8("hi hi hi hey");
+    sink.emit();
+    assertEquals(3, source.indexOf(ByteString.encodeUtf8("hi hi hey")));
+  }
+
+  @Test public void indexOfByteStringAtSegmentBoundary() throws IOException {
+    sink.writeUtf8(repeat("a", SEGMENT_SIZE - 1));
+    sink.writeUtf8("bcd");
+    sink.emit();
+    assertEquals(SEGMENT_SIZE - 3, source.indexOf(ByteString.encodeUtf8("aabc"), SEGMENT_SIZE - 4));
+    assertEquals(SEGMENT_SIZE - 3, source.indexOf(ByteString.encodeUtf8("aabc"), SEGMENT_SIZE - 3));
+    assertEquals(SEGMENT_SIZE - 2, source.indexOf(ByteString.encodeUtf8("abcd"), SEGMENT_SIZE - 2));
+    assertEquals(SEGMENT_SIZE - 2, source.indexOf(ByteString.encodeUtf8("abc"),  SEGMENT_SIZE - 2));
+    assertEquals(SEGMENT_SIZE - 2, source.indexOf(ByteString.encodeUtf8("abc"),  SEGMENT_SIZE - 2));
+    assertEquals(SEGMENT_SIZE - 2, source.indexOf(ByteString.encodeUtf8("ab"),   SEGMENT_SIZE - 2));
+    assertEquals(SEGMENT_SIZE - 2, source.indexOf(ByteString.encodeUtf8("a"),    SEGMENT_SIZE - 2));
+    assertEquals(SEGMENT_SIZE - 1, source.indexOf(ByteString.encodeUtf8("bc"),   SEGMENT_SIZE - 2));
+    assertEquals(SEGMENT_SIZE - 1, source.indexOf(ByteString.encodeUtf8("b"),    SEGMENT_SIZE - 2));
+    assertEquals(SEGMENT_SIZE,     source.indexOf(ByteString.encodeUtf8("c"),    SEGMENT_SIZE - 2));
+    assertEquals(SEGMENT_SIZE,     source.indexOf(ByteString.encodeUtf8("c"),    SEGMENT_SIZE    ));
+    assertEquals(SEGMENT_SIZE + 1, source.indexOf(ByteString.encodeUtf8("d"),    SEGMENT_SIZE - 2));
+    assertEquals(SEGMENT_SIZE + 1, source.indexOf(ByteString.encodeUtf8("d"),    SEGMENT_SIZE + 1));
+  }
+
+  @Test public void indexOfDoesNotWrapAround() throws IOException {
+    sink.writeUtf8(repeat("a", SEGMENT_SIZE - 1));
+    sink.writeUtf8("bcd");
+    sink.emit();
+    assertEquals(-1, source.indexOf(ByteString.encodeUtf8("abcda"), SEGMENT_SIZE - 3));
+  }
+
+  @Test public void indexOfByteStringWithOffset() throws IOException {
+    assertEquals(-1, source.indexOf(ByteString.encodeUtf8("flop"), 1));
+
+    sink.writeUtf8("flop flip flop");
+    sink.emit();
+    assertEquals(10, source.indexOf(ByteString.encodeUtf8("flop"), 1));
+    source.readUtf8(); // Clear stream
+
+    // Make sure we backtrack and resume searching after partial match.
+    sink.writeUtf8("hi hi hi hi hey");
+    sink.emit();
+    assertEquals(6, source.indexOf(ByteString.encodeUtf8("hi hi hey"), 1));
+  }
+
+  @Test public void indexOfByteStringInvalidArgumentsThrows() throws IOException {
+    try {
+      source.indexOf(ByteString.of());
+      fail();
+    } catch (IllegalArgumentException e) {
+      assertEquals("bytes is empty", e.getMessage());
+    }
+    try {
+      source.indexOf(ByteString.encodeUtf8("hi"), -1);
+      fail();
+    } catch (IllegalArgumentException e) {
+      assertEquals("fromIndex < 0: -1", e.getMessage());
+    }
+  }
+
+  /**
+   * With {@link Factory#ONE_BYTE_AT_A_TIME_BUFFERED_SOURCE}, this code was extremely slow.
+   * https://github.com/square/okio/issues/171
+   */
+  @Test public void indexOfByteStringAcrossSegmentBoundaries() throws IOException {
+    sink.writeUtf8(repeat("a", SEGMENT_SIZE * 2 - 3));
+    sink.writeUtf8("bcdefg");
+    sink.emit();
+    assertEquals(SEGMENT_SIZE * 2 - 4, source.indexOf(ByteString.encodeUtf8("ab")));
+    assertEquals(SEGMENT_SIZE * 2 - 4, source.indexOf(ByteString.encodeUtf8("abc")));
+    assertEquals(SEGMENT_SIZE * 2 - 4, source.indexOf(ByteString.encodeUtf8("abcd")));
+    assertEquals(SEGMENT_SIZE * 2 - 4, source.indexOf(ByteString.encodeUtf8("abcde")));
+    assertEquals(SEGMENT_SIZE * 2 - 4, source.indexOf(ByteString.encodeUtf8("abcdef")));
+    assertEquals(SEGMENT_SIZE * 2 - 4, source.indexOf(ByteString.encodeUtf8("abcdefg")));
+    assertEquals(SEGMENT_SIZE * 2 - 3, source.indexOf(ByteString.encodeUtf8("bcdefg")));
+    assertEquals(SEGMENT_SIZE * 2 - 2, source.indexOf(ByteString.encodeUtf8("cdefg")));
+    assertEquals(SEGMENT_SIZE * 2 - 1, source.indexOf(ByteString.encodeUtf8("defg")));
+    assertEquals(SEGMENT_SIZE * 2,     source.indexOf(ByteString.encodeUtf8("efg")));
+    assertEquals(SEGMENT_SIZE * 2 + 1, source.indexOf(ByteString.encodeUtf8("fg")));
+    assertEquals(SEGMENT_SIZE * 2 + 2, source.indexOf(ByteString.encodeUtf8("g")));
+  }
+
+  @Test public void indexOfElement() throws IOException {
+    sink.writeUtf8("a").writeUtf8(repeat("b", SEGMENT_SIZE)).writeUtf8("c");
+    sink.emit();
+    assertEquals(0, source.indexOfElement(ByteString.encodeUtf8("DEFGaHIJK")));
+    assertEquals(1, source.indexOfElement(ByteString.encodeUtf8("DEFGHIJKb")));
+    assertEquals(SEGMENT_SIZE + 1, source.indexOfElement(ByteString.encodeUtf8("cDEFGHIJK")));
+    assertEquals(1, source.indexOfElement(ByteString.encodeUtf8("DEFbGHIc")));
+    assertEquals(-1L, source.indexOfElement(ByteString.encodeUtf8("DEFGHIJK")));
+    assertEquals(-1L, source.indexOfElement(ByteString.encodeUtf8("")));
+  }
+
+  @Test public void indexOfElementWithOffset() throws IOException {
+    sink.writeUtf8("a").writeUtf8(repeat("b", SEGMENT_SIZE)).writeUtf8("c");
+    sink.emit();
+    assertEquals(-1, source.indexOfElement(ByteString.encodeUtf8("DEFGaHIJK"), 1));
+    assertEquals(15, source.indexOfElement(ByteString.encodeUtf8("DEFGHIJKb"), 15));
+  }
+
+  @Test public void indexOfByteWithFromIndex() throws Exception {
+    sink.writeUtf8("aaa");
+    sink.emit();
+    assertEquals(0, source.indexOf((byte) 'a'));
+    assertEquals(0, source.indexOf((byte) 'a', 0));
+    assertEquals(1, source.indexOf((byte) 'a', 1));
+    assertEquals(2, source.indexOf((byte) 'a', 2));
+  }
+
+  @Test public void indexOfByteStringWithFromIndex() throws Exception {
+    sink.writeUtf8("aaa");
+    sink.emit();
+    assertEquals(0, source.indexOf(ByteString.encodeUtf8("a")));
+    assertEquals(0, source.indexOf(ByteString.encodeUtf8("a"), 0));
+    assertEquals(1, source.indexOf(ByteString.encodeUtf8("a"), 1));
+    assertEquals(2, source.indexOf(ByteString.encodeUtf8("a"), 2));
+  }
+
+  @Test public void indexOfElementWithFromIndex() throws Exception {
+    sink.writeUtf8("aaa");
+    sink.emit();
+    assertEquals(0, source.indexOfElement(ByteString.encodeUtf8("a")));
+    assertEquals(0, source.indexOfElement(ByteString.encodeUtf8("a"), 0));
+    assertEquals(1, source.indexOfElement(ByteString.encodeUtf8("a"), 1));
+    assertEquals(2, source.indexOfElement(ByteString.encodeUtf8("a"), 2));
+  }
+
+  @Test public void request() throws IOException {
+    sink.writeUtf8("a").writeUtf8(repeat("b", SEGMENT_SIZE)).writeUtf8("c");
+    sink.emit();
+    assertTrue(source.request(SEGMENT_SIZE + 2));
+    assertFalse(source.request(SEGMENT_SIZE + 3));
+  }
+
+  @Test public void require() throws IOException {
+    sink.writeUtf8("a").writeUtf8(repeat("b", SEGMENT_SIZE)).writeUtf8("c");
+    sink.emit();
+    source.require(SEGMENT_SIZE + 2);
+    try {
+      source.require(SEGMENT_SIZE + 3);
+      fail();
+    } catch (EOFException expected) {
+    }
+  }
+
+  @Test public void inputStream() throws Exception {
+    sink.writeUtf8("abc");
+    sink.emit();
+    InputStream in = source.inputStream();
+    byte[] bytes = { 'z', 'z', 'z' };
+    int read = in.read(bytes);
+    if (factory.isOneByteAtATime()) {
+      assertEquals(1, read);
+      assertByteArrayEquals("azz", bytes);
+
+      read = in.read(bytes);
+      assertEquals(1, read);
+      assertByteArrayEquals("bzz", bytes);
+
+      read = in.read(bytes);
+      assertEquals(1, read);
+      assertByteArrayEquals("czz", bytes);
+    } else {
+      assertEquals(3, read);
+      assertByteArrayEquals("abc", bytes);
+    }
+
+    assertEquals(-1, in.read());
+  }
+
+  @Test public void inputStreamOffsetCount() throws Exception {
+    sink.writeUtf8("abcde");
+    sink.emit();
+    InputStream in = source.inputStream();
+    byte[] bytes = { 'z', 'z', 'z', 'z', 'z' };
+    int read = in.read(bytes, 1, 3);
+    if (factory.isOneByteAtATime()) {
+      assertEquals(1, read);
+      assertByteArrayEquals("zazzz", bytes);
+    } else {
+      assertEquals(3, read);
+      assertByteArrayEquals("zabcz", bytes);
+    }
+  }
+
+  @Test public void inputStreamSkip() throws Exception {
+    sink.writeUtf8("abcde");
+    sink.emit();
+    InputStream in = source.inputStream();
+    assertEquals(4, in.skip(4));
+    assertEquals('e', in.read());
+
+    sink.writeUtf8("abcde");
+    sink.emit();
+    assertEquals(5, in.skip(10)); // Try to skip too much.
+    assertEquals(0, in.skip(1)); // Try to skip when exhausted.
+  }
+
+  @Test public void inputStreamCharByChar() throws Exception {
+    sink.writeUtf8("abc");
+    sink.emit();
+    InputStream in = source.inputStream();
+    assertEquals('a', in.read());
+    assertEquals('b', in.read());
+    assertEquals('c', in.read());
+    assertEquals(-1, in.read());
+  }
+
+  @Test public void inputStreamBounds() throws IOException {
+    sink.writeUtf8(repeat("a", 100));
+    sink.emit();
+    InputStream in = source.inputStream();
+    try {
+      in.read(new byte[100], 50, 51);
+      fail();
+    } catch (ArrayIndexOutOfBoundsException expected) {
+    }
+  }
+
+  @Test public void longHexString() throws IOException {
+    assertLongHexString("8000000000000000", 0x8000000000000000L);
+    assertLongHexString("fffffffffffffffe", 0xFFFFFFFFFFFFFFFEL);
+    assertLongHexString("FFFFFFFFFFFFFFFe", 0xFFFFFFFFFFFFFFFEL);
+    assertLongHexString("ffffffffffffffff", 0xffffffffffffffffL);
+    assertLongHexString("FFFFFFFFFFFFFFFF", 0xFFFFFFFFFFFFFFFFL);
+    assertLongHexString("0000000000000000", 0x0);
+    assertLongHexString("0000000000000001", 0x1);
+    assertLongHexString("7999999999999999", 0x7999999999999999L);
+
+    assertLongHexString("FF", 0xFF);
+    assertLongHexString("0000000000000001", 0x1);
+  }
+
+  @Test public void hexStringWithManyLeadingZeros() throws IOException {
+    assertLongHexString("00000000000000001", 0x1);
+    assertLongHexString("0000000000000000ffffffffffffffff", 0xffffffffffffffffL);
+    assertLongHexString("00000000000000007fffffffffffffff", 0x7fffffffffffffffL);
+    assertLongHexString(repeat("0", SEGMENT_SIZE + 1) + "1", 0x1);
+  }
+
+  private void assertLongHexString(String s, long expected) throws IOException {
+    sink.writeUtf8(s);
+    sink.emit();
+    long actual = source.readHexadecimalUnsignedLong();
+    assertEquals(s + " --> " + expected, expected, actual);
+  }
+
+  @Test public void longHexStringAcrossSegment() throws IOException {
+    sink.writeUtf8(repeat("a", SEGMENT_SIZE - 8)).writeUtf8("FFFFFFFFFFFFFFFF");
+    sink.emit();
+    source.skip(SEGMENT_SIZE - 8);
+    assertEquals(-1, source.readHexadecimalUnsignedLong());
+  }
+
+  @Test public void longHexStringTooLongThrows() throws IOException {
+    try {
+      sink.writeUtf8("fffffffffffffffff");
+      sink.emit();
+      source.readHexadecimalUnsignedLong();
+      fail();
+    } catch (NumberFormatException e) {
+      assertEquals("Number too large: fffffffffffffffff", e.getMessage());
+    }
+  }
+
+  @Test public void longHexStringTooShortThrows() throws IOException {
+    try {
+      sink.writeUtf8(" ");
+      sink.emit();
+      source.readHexadecimalUnsignedLong();
+      fail();
+    } catch (NumberFormatException e) {
+      assertEquals("Expected leading [0-9a-fA-F] character but was 0x20", e.getMessage());
+    }
+  }
+
+  @Test public void longHexEmptySourceThrows() throws IOException {
+    try {
+      sink.writeUtf8("");
+      sink.emit();
+      source.readHexadecimalUnsignedLong();
+      fail();
+    } catch (EOFException expected) {
+    }
+  }
+
+  @Test public void longDecimalString() throws IOException {
+    assertLongDecimalString("-9223372036854775808", -9223372036854775808L);
+    assertLongDecimalString("-1", -1L);
+    assertLongDecimalString("0", 0L);
+    assertLongDecimalString("1", 1L);
+    assertLongDecimalString("9223372036854775807", 9223372036854775807L);
+
+    assertLongDecimalString("00000001", 1L);
+    assertLongDecimalString("-000001", -1L);
+  }
+
+  private void assertLongDecimalString(String s, long expected) throws IOException {
+    sink.writeUtf8(s);
+    sink.writeUtf8("zzz");
+    sink.emit();
+    long actual = source.readDecimalLong();
+    assertEquals(s + " --> " + expected, expected, actual);
+    assertEquals("zzz", source.readUtf8());
+  }
+
+  @Test public void longDecimalStringAcrossSegment() throws IOException {
+    sink.writeUtf8(repeat("a", SEGMENT_SIZE - 8)).writeUtf8("1234567890123456");
+    sink.writeUtf8("zzz");
+    sink.emit();
+    source.skip(SEGMENT_SIZE - 8);
+    assertEquals(1234567890123456L, source.readDecimalLong());
+    assertEquals("zzz", source.readUtf8());
+  }
+
+  @Test public void longDecimalStringTooLongThrows() throws IOException {
+    try {
+      sink.writeUtf8("12345678901234567890"); // Too many digits.
+      sink.emit();
+      source.readDecimalLong();
+      fail();
+    } catch (NumberFormatException e) {
+      assertEquals("Number too large: 12345678901234567890", e.getMessage());
+    }
+  }
+
+  @Test public void longDecimalStringTooHighThrows() throws IOException {
+    try {
+      sink.writeUtf8("9223372036854775808"); // Right size but cannot fit.
+      sink.emit();
+      source.readDecimalLong();
+      fail();
+    } catch (NumberFormatException e) {
+      assertEquals("Number too large: 9223372036854775808", e.getMessage());
+    }
+  }
+
+  @Test public void longDecimalStringTooLowThrows() throws IOException {
+    try {
+      sink.writeUtf8("-9223372036854775809"); // Right size but cannot fit.
+      sink.emit();
+      source.readDecimalLong();
+      fail();
+    } catch (NumberFormatException e) {
+      assertEquals("Number too large: -9223372036854775809", e.getMessage());
+    }
+  }
+
+  @Test public void longDecimalStringTooShortThrows() throws IOException {
+    try {
+      sink.writeUtf8(" ");
+      sink.emit();
+      source.readDecimalLong();
+      fail();
+    } catch (NumberFormatException e) {
+      assertEquals("Expected leading [0-9] or '-' character but was 0x20", e.getMessage());
+    }
+  }
+
+  @Test public void longDecimalEmptyThrows() throws IOException {
+    try {
+      sink.writeUtf8("");
+      sink.emit();
+      source.readDecimalLong();
+      fail();
+    } catch (EOFException expected) {
+    }
+  }
+
+  @Test public void codePoints() throws IOException {
+    sink.write(ByteString.decodeHex("7f"));
+    sink.emit();
+    assertEquals(0x7f, source.readUtf8CodePoint());
+
+    sink.write(ByteString.decodeHex("dfbf"));
+    sink.emit();
+    assertEquals(0x07ff, source.readUtf8CodePoint());
+
+    sink.write(ByteString.decodeHex("efbfbf"));
+    sink.emit();
+    assertEquals(0xffff, source.readUtf8CodePoint());
+
+    sink.write(ByteString.decodeHex("f48fbfbf"));
+    sink.emit();
+    assertEquals(0x10ffff, source.readUtf8CodePoint());
+  }
+
+  @Test public void decimalStringWithManyLeadingZeros() throws IOException {
+    assertLongDecimalString("00000000000000001", 1);
+    assertLongDecimalString("00000000000000009223372036854775807", 9223372036854775807L);
+    assertLongDecimalString("-00000000000000009223372036854775808", -9223372036854775808L);
+    assertLongDecimalString(repeat("0", SEGMENT_SIZE + 1) + "1", 1);
+  }
+
+  @Test public void select() throws IOException {
+    Options options = Options.Companion.of(
+        ByteString.encodeUtf8("ROCK"),
+        ByteString.encodeUtf8("SCISSORS"),
+        ByteString.encodeUtf8("PAPER"));
+
+    sink.writeUtf8("PAPER,SCISSORS,ROCK");
+    sink.emit();
+    assertEquals(2, source.select(options));
+    assertEquals(',', source.readByte());
+    assertEquals(1, source.select(options));
+    assertEquals(',', source.readByte());
+    assertEquals(0, source.select(options));
+    assertTrue(source.exhausted());
+  }
+
+  /** Note that this test crashes the VM on Android. */
+  @Test public void selectSpanningMultipleSegments() throws IOException {
+    ByteString commonPrefix = TestUtil.randomBytes(SEGMENT_SIZE + 10);
+    ByteString a = new Buffer().write(commonPrefix).writeUtf8("a").readByteString();
+    ByteString bc = new Buffer().write(commonPrefix).writeUtf8("bc").readByteString();
+    ByteString bd = new Buffer().write(commonPrefix).writeUtf8("bd").readByteString();
+    Options options = Options.Companion.of(a, bc, bd);
+
+    sink.write(bd);
+    sink.write(a);
+    sink.write(bc);
+    sink.emit();
+
+    assertEquals(2, source.select(options));
+    assertEquals(0, source.select(options));
+    assertEquals(1, source.select(options));
+    assertTrue(source.exhausted());
+  }
+
+  @Test public void selectNotFound() throws IOException {
+    Options options = Options.Companion.of(
+        ByteString.encodeUtf8("ROCK"),
+        ByteString.encodeUtf8("SCISSORS"),
+        ByteString.encodeUtf8("PAPER"));
+
+    sink.writeUtf8("SPOCK");
+    sink.emit();
+    assertEquals(-1, source.select(options));
+    assertEquals("SPOCK", source.readUtf8());
+  }
+
+  @Test public void selectValuesHaveCommonPrefix() throws IOException {
+    Options options = Options.Companion.of(
+        ByteString.encodeUtf8("abcd"),
+        ByteString.encodeUtf8("abce"),
+        ByteString.encodeUtf8("abcc"));
+
+    sink.writeUtf8("abcc").writeUtf8("abcd").writeUtf8("abce");
+    sink.emit();
+    assertEquals(2, source.select(options));
+    assertEquals(0, source.select(options));
+    assertEquals(1, source.select(options));
+  }
+
+  @Test public void selectLongerThanSource() throws IOException {
+    Options options = Options.Companion.of(
+        ByteString.encodeUtf8("abcd"),
+        ByteString.encodeUtf8("abce"),
+        ByteString.encodeUtf8("abcc"));
+    sink.writeUtf8("abc");
+    sink.emit();
+    assertEquals(-1, source.select(options));
+    assertEquals("abc", source.readUtf8());
+  }
+
+  @Test public void selectReturnsFirstByteStringThatMatches() throws IOException {
+    Options options = Options.Companion.of(
+        ByteString.encodeUtf8("abcd"),
+        ByteString.encodeUtf8("abc"),
+        ByteString.encodeUtf8("abcde"));
+    sink.writeUtf8("abcdef");
+    sink.emit();
+    assertEquals(0, source.select(options));
+    assertEquals("ef", source.readUtf8());
+  }
+
+  @Test public void selectFromEmptySource() throws IOException {
+    Options options = Options.Companion.of(
+        ByteString.encodeUtf8("abc"),
+        ByteString.encodeUtf8("def"));
+    assertEquals(-1, source.select(options));
+  }
+
+  @Test public void selectNoByteStringsFromEmptySource() throws IOException {
+    Options options = Options.of();
+    assertEquals(-1, source.select(options));
+  }
+
+  @Test public void peek() throws IOException {
+    sink.writeUtf8("abcdefghi");
+    sink.emit();
+
+    assertEquals("abc", source.readUtf8(3));
+
+    BufferedSource peek = source.peek();
+    assertEquals("def", peek.readUtf8(3));
+    assertEquals("ghi", peek.readUtf8(3));
+    assertFalse(peek.request(1));
+
+    assertEquals("def", source.readUtf8(3));
+  }
+
+  @Test public void peekMultiple() throws IOException {
+    sink.writeUtf8("abcdefghi");
+    sink.emit();
+
+    assertEquals("abc", source.readUtf8(3));
+
+    BufferedSource peek1 = source.peek();
+    BufferedSource peek2 = source.peek();
+
+    assertEquals("def", peek1.readUtf8(3));
+
+    assertEquals("def", peek2.readUtf8(3));
+    assertEquals("ghi", peek2.readUtf8(3));
+    assertFalse(peek2.request(1));
+
+    assertEquals("ghi", peek1.readUtf8(3));
+    assertFalse(peek1.request(1));
+
+    assertEquals("def", source.readUtf8(3));
+  }
+
+  @Test public void peekLarge() throws IOException {
+    sink.writeUtf8("abcdef");
+    sink.writeUtf8(repeat("g", 2 * SEGMENT_SIZE));
+    sink.writeUtf8("hij");
+    sink.emit();
+
+    assertEquals("abc", source.readUtf8(3));
+
+    BufferedSource peek = source.peek();
+    assertEquals("def", peek.readUtf8(3));
+    peek.skip(2 * SEGMENT_SIZE);
+    assertEquals("hij", peek.readUtf8(3));
+    assertFalse(peek.request(1));
+
+    assertEquals("def", source.readUtf8(3));
+    source.skip(2 * SEGMENT_SIZE);
+    assertEquals("hij", source.readUtf8(3));
+  }
+
+  @Test public void peekInvalid() throws IOException {
+    sink.writeUtf8("abcdefghi");
+    sink.emit();
+
+    assertEquals("abc", source.readUtf8(3));
+
+    BufferedSource peek = source.peek();
+    assertEquals("def", peek.readUtf8(3));
+    assertEquals("ghi", peek.readUtf8(3));
+    assertFalse(peek.request(1));
+
+    assertEquals("def", source.readUtf8(3));
+
+    try {
+      peek.readUtf8();
+      fail();
+    } catch (IllegalStateException e) {
+      assertEquals("Peek source is invalid because upstream source was used", e.getMessage());
+    }
+  }
+
+  @Test public void peekSegmentThenInvalid() throws IOException {
+    sink.writeUtf8("abc");
+    sink.writeUtf8(repeat("d", 2 * SEGMENT_SIZE));
+    sink.emit();
+
+    assertEquals("abc", source.readUtf8(3));
+
+    // Peek a little data and skip the rest of the upstream source
+    BufferedSource peek = source.peek();
+    assertEquals("ddd", peek.readUtf8(3));
+    source.readAll(Okio.blackhole());
+
+    // Skip the rest of the buffered data
+    peek.skip(peek.getBuffer().size());
+
+    try {
+      peek.readByte();
+      fail();
+    } catch (IllegalStateException e) {
+      assertEquals("Peek source is invalid because upstream source was used", e.getMessage());
+    }
+  }
+
+  @Test public void peekDoesntReadTooMuch() throws IOException {
+    // 6 bytes in source's buffer plus 3 bytes upstream.
+    sink.writeUtf8("abcdef");
+    sink.emit();
+    source.require(6L);
+    sink.writeUtf8("ghi");
+    sink.emit();
+
+    BufferedSource peek = source.peek();
+
+    // Read 3 bytes. This reads some of the buffered data.
+    assertTrue(peek.request(3));
+    if (!(source instanceof Buffer)) {
+      assertEquals(6, source.getBuffer().size());
+      assertEquals(6, peek.getBuffer().size());
+    }
+    assertEquals("abc", peek.readUtf8(3L));
+
+    // Read 3 more bytes. This exhausts the buffered data.
+    assertTrue(peek.request(3));
+    if (!(source instanceof Buffer)) {
+      assertEquals(6, source.getBuffer().size());
+      assertEquals(3, peek.getBuffer().size());
+    }
+    assertEquals("def", peek.readUtf8(3L));
+
+    // Read 3 more bytes. This draws new bytes.
+    assertTrue(peek.request(3));
+    assertEquals(9, source.getBuffer().size());
+    assertEquals(3, peek.getBuffer().size());
+    assertEquals("ghi", peek.readUtf8(3L));
+  }
+
+  @Test public void rangeEquals() throws IOException {
+    sink.writeUtf8("A man, a plan, a canal. Panama.");
+    sink.emit();
+    assertTrue(source.rangeEquals(7 , ByteString.encodeUtf8("a plan")));
+    assertTrue(source.rangeEquals(0 , ByteString.encodeUtf8("A man")));
+    assertTrue(source.rangeEquals(24, ByteString.encodeUtf8("Panama")));
+    assertFalse(source.rangeEquals(24, ByteString.encodeUtf8("Panama. Panama. Panama.")));
+  }
+
+  @Test public void rangeEqualsWithOffsetAndCount() throws IOException {
+    sink.writeUtf8("A man, a plan, a canal. Panama.");
+    sink.emit();
+    assertTrue(source.rangeEquals(7 , ByteString.encodeUtf8("aaa plannn"), 2, 6));
+    assertTrue(source.rangeEquals(0 , ByteString.encodeUtf8("AAA mannn"), 2, 5));
+    assertTrue(source.rangeEquals(24, ByteString.encodeUtf8("PPPanamaaa"), 2, 6));
+  }
+
+  @Test public void rangeEqualsOnlyReadsUntilMismatch() throws IOException {
+    assumeTrue(factory == Factory.ONE_BYTE_AT_A_TIME_BUFFERED_SOURCE); // Other sources read in chunks anyway.
+
+    sink.writeUtf8("A man, a plan, a canal. Panama.");
+    sink.emit();
+    assertFalse(source.rangeEquals(0, ByteString.encodeUtf8("A man.")));
+    assertEquals("A man,", source.getBuffer().readUtf8());
+  }
+
+  @Test public void rangeEqualsArgumentValidation() throws IOException {
+    // Negative source offset.
+    assertFalse(source.rangeEquals(-1, ByteString.encodeUtf8("A")));
+    // Negative bytes offset.
+    assertFalse(source.rangeEquals(0, ByteString.encodeUtf8("A"), -1, 1));
+    // Bytes offset longer than bytes length.
+    assertFalse(source.rangeEquals(0, ByteString.encodeUtf8("A"), 2, 1));
+    // Negative byte count.
+    assertFalse(source.rangeEquals(0, ByteString.encodeUtf8("A"), 0, -1));
+    // Byte count longer than bytes length.
+    assertFalse(source.rangeEquals(0, ByteString.encodeUtf8("A"), 0, 2));
+    // Bytes offset plus byte count longer than bytes length.
+    assertFalse(source.rangeEquals(0, ByteString.encodeUtf8("A"), 1, 1));
+  }
+
+  @Test public void readNioBuffer() throws Exception {
+    String expected = factory.isOneByteAtATime() ? "a" : "abcdefg";
+    sink.writeUtf8("abcdefg");
+    sink.emit();
+
+    ByteBuffer nioByteBuffer = ByteBuffer.allocate(1024);
+    int byteCount = source.read(nioByteBuffer);
+    assertEquals(expected.length(), byteCount);
+    assertEquals(expected.length(), nioByteBuffer.position());
+    assertEquals(nioByteBuffer.capacity(), nioByteBuffer.limit());
+
+    nioByteBuffer.flip();
+    byte[] data = new byte[expected.length()];
+    nioByteBuffer.get(data);
+    assertEquals(expected, new String(data));
+  }
+
+  /** Note that this test crashes the VM on Android. */
+  @Test public void readLargeNioBufferOnlyReadsOneSegment() throws Exception {
+    String expected = factory.isOneByteAtATime()
+        ? "a"
+        : repeat("a", SEGMENT_SIZE);
+    sink.writeUtf8(repeat("a", SEGMENT_SIZE * 4));
+    sink.emit();
+
+    ByteBuffer nioByteBuffer = ByteBuffer.allocate(SEGMENT_SIZE * 3);
+    int byteCount = source.read(nioByteBuffer);
+    assertEquals(expected.length(), byteCount);
+    assertEquals(expected.length(), nioByteBuffer.position());
+    assertEquals(nioByteBuffer.capacity(), nioByteBuffer.limit());
+
+    nioByteBuffer.flip();
+    byte[] data = new byte[expected.length()];
+    nioByteBuffer.get(data);
+    assertEquals(expected, new String(data));
+  }
+
+  @Test public void factorySegmentSizes() throws Exception {
+    sink.writeUtf8("abc");
+    sink.emit();
+    source.require(3);
+    if (factory.isOneByteAtATime()) {
+      assertEquals(Arrays.asList(1, 1, 1), TestUtil.segmentSizes(source.getBuffer()));
+    } else {
+      assertEquals(Collections.singletonList(3), TestUtil.segmentSizes(source.getBuffer()));
+    }
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/ByteStringJavaTest.java b/okio/src/jvmTest/java/okio/ByteStringJavaTest.java
new file mode 100644
index 0000000..f1b6624
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/ByteStringJavaTest.java
@@ -0,0 +1,633 @@
+/*
+ * 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 okio;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import kotlin.text.Charsets;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+import static okio.TestUtil.assertByteArraysEquals;
+import static okio.TestUtil.assertEquivalent;
+import static okio.TestUtil.makeSegments;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+@RunWith(Parameterized.class)
+public final class ByteStringJavaTest {
+  interface Factory {
+    Factory BYTE_STRING = new Factory() {
+      @Override public ByteString decodeHex(String hex) {
+        return ByteString.decodeHex(hex);
+      }
+
+      @Override public ByteString encodeUtf8(String s) {
+        return ByteString.encodeUtf8(s);
+      }
+    };
+
+    Factory SEGMENTED_BYTE_STRING = new Factory() {
+      @Override public ByteString decodeHex(String hex) {
+        Buffer buffer = new Buffer();
+        buffer.write(ByteString.decodeHex(hex));
+        return buffer.snapshot();
+      }
+
+      @Override public ByteString encodeUtf8(String s) {
+        Buffer buffer = new Buffer();
+        buffer.writeUtf8(s);
+        return buffer.snapshot();
+      }
+    };
+
+    Factory ONE_BYTE_PER_SEGMENT = new Factory() {
+      @Override public ByteString decodeHex(String hex) {
+        return makeSegments(ByteString.decodeHex(hex));
+      }
+
+      @Override public ByteString encodeUtf8(String s) {
+        return makeSegments(ByteString.encodeUtf8(s));
+      }
+    };
+
+    ByteString decodeHex(String hex);
+    ByteString encodeUtf8(String s);
+  }
+
+  @Parameters(name = "{1}")
+  public static List<Object[]> parameters() {
+    return Arrays.asList(
+        new Object[] { Factory.BYTE_STRING, "ByteString" },
+        new Object[] { Factory.SEGMENTED_BYTE_STRING, "SegmentedByteString" },
+        new Object[] { Factory.ONE_BYTE_PER_SEGMENT, "SegmentedByteString (one-at-a-time)" });
+  }
+
+  @Parameter(0) public Factory factory;
+  @Parameter(1) public String name;
+
+  @Test public void ofCopy() {
+    byte[] bytes = "Hello, World!".getBytes(Charsets.UTF_8);
+    ByteString byteString = ByteString.of(bytes);
+    // Verify that the bytes were copied out.
+    bytes[4] = (byte) 'a';
+    assertEquals("Hello, World!", byteString.utf8());
+  }
+
+  @Test public void ofCopyRange() {
+    byte[] bytes = "Hello, World!".getBytes(Charsets.UTF_8);
+    ByteString byteString = ByteString.of(bytes, 2, 9);
+    // Verify that the bytes were copied out.
+    bytes[4] = (byte) 'a';
+    assertEquals("llo, Worl", byteString.utf8());
+  }
+
+  @Test public void ofByteBuffer() {
+    byte[] bytes = "Hello, World!".getBytes(Charsets.UTF_8);
+    ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
+    byteBuffer.position(2).limit(11);
+    ByteString byteString = ByteString.of(byteBuffer);
+    // Verify that the bytes were copied out.
+    byteBuffer.put(4, (byte) 'a');
+    assertEquals("llo, Worl", byteString.utf8());
+  }
+
+  @Test public void getByte() throws Exception {
+    ByteString byteString = factory.decodeHex("ab12");
+    assertEquals(-85, byteString.getByte(0));
+    assertEquals(18, byteString.getByte(1));
+  }
+
+  @Test public void getByteOutOfBounds() throws Exception {
+    ByteString byteString = factory.decodeHex("ab12");
+    try {
+      byteString.getByte(2);
+      fail();
+    } catch (IndexOutOfBoundsException expected) {
+    }
+  }
+
+  @Test public void startsWithByteString() throws Exception {
+    ByteString byteString = factory.decodeHex("112233");
+    assertTrue(byteString.startsWith(ByteString.decodeHex("")));
+    assertTrue(byteString.startsWith(ByteString.decodeHex("11")));
+    assertTrue(byteString.startsWith(ByteString.decodeHex("1122")));
+    assertTrue(byteString.startsWith(ByteString.decodeHex("112233")));
+    assertFalse(byteString.startsWith(ByteString.decodeHex("2233")));
+    assertFalse(byteString.startsWith(ByteString.decodeHex("11223344")));
+    assertFalse(byteString.startsWith(ByteString.decodeHex("112244")));
+  }
+
+  @Test public void endsWithByteString() throws Exception {
+    ByteString byteString = factory.decodeHex("112233");
+    assertTrue(byteString.endsWith(ByteString.decodeHex("")));
+    assertTrue(byteString.endsWith(ByteString.decodeHex("33")));
+    assertTrue(byteString.endsWith(ByteString.decodeHex("2233")));
+    assertTrue(byteString.endsWith(ByteString.decodeHex("112233")));
+    assertFalse(byteString.endsWith(ByteString.decodeHex("1122")));
+    assertFalse(byteString.endsWith(ByteString.decodeHex("00112233")));
+    assertFalse(byteString.endsWith(ByteString.decodeHex("002233")));
+  }
+
+  @Test public void startsWithByteArray() throws Exception {
+    ByteString byteString = factory.decodeHex("112233");
+    assertTrue(byteString.startsWith(ByteString.decodeHex("").toByteArray()));
+    assertTrue(byteString.startsWith(ByteString.decodeHex("11").toByteArray()));
+    assertTrue(byteString.startsWith(ByteString.decodeHex("1122").toByteArray()));
+    assertTrue(byteString.startsWith(ByteString.decodeHex("112233").toByteArray()));
+    assertFalse(byteString.startsWith(ByteString.decodeHex("2233").toByteArray()));
+    assertFalse(byteString.startsWith(ByteString.decodeHex("11223344").toByteArray()));
+    assertFalse(byteString.startsWith(ByteString.decodeHex("112244").toByteArray()));
+  }
+
+  @Test public void endsWithByteArray() throws Exception {
+    ByteString byteString = factory.decodeHex("112233");
+    assertTrue(byteString.endsWith(ByteString.decodeHex("").toByteArray()));
+    assertTrue(byteString.endsWith(ByteString.decodeHex("33").toByteArray()));
+    assertTrue(byteString.endsWith(ByteString.decodeHex("2233").toByteArray()));
+    assertTrue(byteString.endsWith(ByteString.decodeHex("112233").toByteArray()));
+    assertFalse(byteString.endsWith(ByteString.decodeHex("1122").toByteArray()));
+    assertFalse(byteString.endsWith(ByteString.decodeHex("00112233").toByteArray()));
+    assertFalse(byteString.endsWith(ByteString.decodeHex("002233").toByteArray()));
+  }
+
+  @Test public void indexOfByteString() throws Exception {
+    ByteString byteString = factory.decodeHex("112233");
+    assertEquals(0, byteString.indexOf(ByteString.decodeHex("112233")));
+    assertEquals(0, byteString.indexOf(ByteString.decodeHex("1122")));
+    assertEquals(0, byteString.indexOf(ByteString.decodeHex("11")));
+    assertEquals(0, byteString.indexOf(ByteString.decodeHex("11"), 0));
+    assertEquals(0, byteString.indexOf(ByteString.decodeHex("")));
+    assertEquals(0, byteString.indexOf(ByteString.decodeHex(""), 0));
+    assertEquals(1, byteString.indexOf(ByteString.decodeHex("2233")));
+    assertEquals(1, byteString.indexOf(ByteString.decodeHex("22")));
+    assertEquals(1, byteString.indexOf(ByteString.decodeHex("22"), 1));
+    assertEquals(1, byteString.indexOf(ByteString.decodeHex(""), 1));
+    assertEquals(2, byteString.indexOf(ByteString.decodeHex("33")));
+    assertEquals(2, byteString.indexOf(ByteString.decodeHex("33"), 2));
+    assertEquals(2, byteString.indexOf(ByteString.decodeHex(""), 2));
+    assertEquals(3, byteString.indexOf(ByteString.decodeHex(""), 3));
+    assertEquals(-1, byteString.indexOf(ByteString.decodeHex("112233"), 1));
+    assertEquals(-1, byteString.indexOf(ByteString.decodeHex("44")));
+    assertEquals(-1, byteString.indexOf(ByteString.decodeHex("11223344")));
+    assertEquals(-1, byteString.indexOf(ByteString.decodeHex("112244")));
+    assertEquals(-1, byteString.indexOf(ByteString.decodeHex("112233"), 1));
+    assertEquals(-1, byteString.indexOf(ByteString.decodeHex("2233"), 2));
+    assertEquals(-1, byteString.indexOf(ByteString.decodeHex("33"), 3));
+    assertEquals(-1, byteString.indexOf(ByteString.decodeHex(""), 4));
+  }
+
+  @Test public void indexOfWithOffset() throws Exception {
+    ByteString byteString = factory.decodeHex("112233112233");
+    assertEquals(0, byteString.indexOf(ByteString.decodeHex("112233"), -1));
+    assertEquals(0, byteString.indexOf(ByteString.decodeHex("112233"), 0));
+    assertEquals(0, byteString.indexOf(ByteString.decodeHex("112233")));
+    assertEquals(3, byteString.indexOf(ByteString.decodeHex("112233"), 1));
+    assertEquals(3, byteString.indexOf(ByteString.decodeHex("112233"), 2));
+    assertEquals(3, byteString.indexOf(ByteString.decodeHex("112233"), 3));
+    assertEquals(-1, byteString.indexOf(ByteString.decodeHex("112233"), 4));
+  }
+
+  @Test public void indexOfByteArray() throws Exception {
+    ByteString byteString = factory.decodeHex("112233");
+    assertEquals(0, byteString.indexOf(ByteString.decodeHex("112233").toByteArray()));
+    assertEquals(1, byteString.indexOf(ByteString.decodeHex("2233").toByteArray()));
+    assertEquals(2, byteString.indexOf(ByteString.decodeHex("33").toByteArray()));
+    assertEquals(-1, byteString.indexOf(ByteString.decodeHex("112244").toByteArray()));
+  }
+
+  @Test public void lastIndexOfByteString() throws Exception {
+    ByteString byteString = factory.decodeHex("112233");
+    assertEquals(0, byteString.lastIndexOf(ByteString.decodeHex("112233")));
+    assertEquals(0, byteString.lastIndexOf(ByteString.decodeHex("1122")));
+    assertEquals(0, byteString.lastIndexOf(ByteString.decodeHex("11")));
+    assertEquals(0, byteString.lastIndexOf(ByteString.decodeHex("11"), 3));
+    assertEquals(0, byteString.lastIndexOf(ByteString.decodeHex("11"), 0));
+    assertEquals(0, byteString.lastIndexOf(ByteString.decodeHex(""), 0));
+    assertEquals(1, byteString.lastIndexOf(ByteString.decodeHex("2233")));
+    assertEquals(1, byteString.lastIndexOf(ByteString.decodeHex("22")));
+    assertEquals(1, byteString.lastIndexOf(ByteString.decodeHex("22"), 3));
+    assertEquals(1, byteString.lastIndexOf(ByteString.decodeHex("22"), 1));
+    assertEquals(1, byteString.lastIndexOf(ByteString.decodeHex(""), 1));
+    assertEquals(2, byteString.lastIndexOf(ByteString.decodeHex("33")));
+    assertEquals(2, byteString.lastIndexOf(ByteString.decodeHex("33"), 3));
+    assertEquals(2, byteString.lastIndexOf(ByteString.decodeHex("33"), 2));
+    assertEquals(2, byteString.lastIndexOf(ByteString.decodeHex(""), 2));
+    assertEquals(3, byteString.lastIndexOf(ByteString.decodeHex(""), 3));
+    assertEquals(3, byteString.lastIndexOf(ByteString.decodeHex("")));
+    assertEquals(-1, byteString.lastIndexOf(ByteString.decodeHex("112233"), -1));
+    assertEquals(-1, byteString.lastIndexOf(ByteString.decodeHex("112233"), -2));
+    assertEquals(-1, byteString.lastIndexOf(ByteString.decodeHex("44")));
+    assertEquals(-1, byteString.lastIndexOf(ByteString.decodeHex("11223344")));
+    assertEquals(-1, byteString.lastIndexOf(ByteString.decodeHex("112244")));
+    assertEquals(-1, byteString.lastIndexOf(ByteString.decodeHex("2233"), 0));
+    assertEquals(-1, byteString.lastIndexOf(ByteString.decodeHex("33"), 1));
+    assertEquals(-1, byteString.lastIndexOf(ByteString.decodeHex(""), -1));
+  }
+
+  @Test public void lastIndexOfByteArray() throws Exception {
+    ByteString byteString = factory.decodeHex("112233");
+    assertEquals(0, byteString.lastIndexOf(ByteString.decodeHex("112233").toByteArray()));
+    assertEquals(1, byteString.lastIndexOf(ByteString.decodeHex("2233").toByteArray()));
+    assertEquals(2, byteString.lastIndexOf(ByteString.decodeHex("33").toByteArray()));
+    assertEquals(3, byteString.lastIndexOf(ByteString.decodeHex("").toByteArray()));
+  }
+
+  @SuppressWarnings("SelfEquals")
+  @Test public void equals() throws Exception {
+    ByteString byteString = factory.decodeHex("000102");
+    assertTrue(byteString.equals(byteString));
+    assertTrue(byteString.equals(ByteString.decodeHex("000102")));
+    assertTrue(factory.decodeHex("").equals(ByteString.EMPTY));
+    assertTrue(factory.decodeHex("").equals(ByteString.of()));
+    assertTrue(ByteString.EMPTY.equals(factory.decodeHex("")));
+    assertTrue(ByteString.of().equals(factory.decodeHex("")));
+    assertFalse(byteString.equals(new Object()));
+    assertFalse(byteString.equals(ByteString.decodeHex("000201")));
+  }
+
+  private final String bronzeHorseman = "На берегу пустынных волн";
+
+  @Test public void utf8() throws Exception {
+    ByteString byteString = factory.encodeUtf8(bronzeHorseman);
+    assertByteArraysEquals(byteString.toByteArray(), bronzeHorseman.getBytes(Charsets.UTF_8));
+    assertTrue(byteString.equals(ByteString.of(bronzeHorseman.getBytes(Charsets.UTF_8))));
+    assertEquals(byteString.utf8(), bronzeHorseman);
+  }
+
+  @Test public void encodeNullCharset() throws Exception {
+    try {
+      ByteString.encodeString("hello", null);
+      fail();
+    } catch (NullPointerException expected) {
+    }
+  }
+
+  @Test public void encodeNullString() throws Exception {
+    try {
+      ByteString.encodeString(null, Charset.forName("UTF-8"));
+      fail();
+    } catch (NullPointerException expected) {
+    }
+  }
+
+  @Test public void decodeNullCharset() throws Exception {
+    try {
+      ByteString.of().string(null);
+      fail();
+    } catch (NullPointerException expected) {
+    }
+  }
+
+  @Test public void encodeDecodeStringUtf8() throws Exception {
+    Charset utf8 = Charset.forName("UTF-8");
+    ByteString byteString = ByteString.encodeString(bronzeHorseman, utf8);
+    assertByteArraysEquals(byteString.toByteArray(), bronzeHorseman.getBytes(utf8));
+    assertEquals(byteString, ByteString.decodeHex("d09dd0b020d0b1d0b5d180d0b5d0b3d18320d0bfd183d181"
+        + "d182d18bd0bdd0bdd18bd18520d0b2d0bed0bbd0bd"));
+    assertEquals(bronzeHorseman, byteString.string(utf8));
+  }
+
+  @Test public void encodeDecodeStringUtf16be() throws Exception {
+    Charset utf16be = Charset.forName("UTF-16BE");
+    ByteString byteString = ByteString.encodeString(bronzeHorseman, utf16be);
+    assertByteArraysEquals(byteString.toByteArray(), bronzeHorseman.getBytes(utf16be));
+    assertEquals(byteString, ByteString.decodeHex("041d043000200431043504400435043304430020043f0443"
+        + "04410442044b043d043d044b044500200432043e043b043d"));
+    assertEquals(bronzeHorseman, byteString.string(utf16be));
+  }
+
+  @Test public void encodeDecodeStringUtf32be() throws Exception {
+    Charset utf32be = Charset.forName("UTF-32BE");
+    ByteString byteString = ByteString.encodeString(bronzeHorseman, utf32be);
+    assertByteArraysEquals(byteString.toByteArray(), bronzeHorseman.getBytes(utf32be));
+    assertEquals(byteString, ByteString.decodeHex("0000041d0000043000000020000004310000043500000440"
+        + "000004350000043300000443000000200000043f0000044300000441000004420000044b0000043d0000043d"
+        + "0000044b0000044500000020000004320000043e0000043b0000043d"));
+    assertEquals(bronzeHorseman, byteString.string(utf32be));
+  }
+
+  @Test public void encodeDecodeStringAsciiIsLossy() throws Exception {
+    Charset ascii = Charset.forName("US-ASCII");
+    ByteString byteString = ByteString.encodeString(bronzeHorseman, ascii);
+    assertByteArraysEquals(byteString.toByteArray(), bronzeHorseman.getBytes(ascii));
+    assertEquals(byteString,
+        ByteString.decodeHex("3f3f203f3f3f3f3f3f203f3f3f3f3f3f3f3f3f203f3f3f3f"));
+    assertEquals("?? ?????? ????????? ????", byteString.string(ascii));
+  }
+
+  @Test public void decodeMalformedStringReturnsReplacementCharacter() throws Exception {
+    Charset utf16be = Charset.forName("UTF-16BE");
+    String string = ByteString.decodeHex("04").string(utf16be);
+    assertEquals("\ufffd", string);
+  }
+
+  @Test public void testHashCode() throws Exception {
+    ByteString byteString = factory.decodeHex("0102");
+    assertEquals(byteString.hashCode(), byteString.hashCode());
+    assertEquals(byteString.hashCode(), ByteString.decodeHex("0102").hashCode());
+  }
+
+  @Test public void read() throws Exception {
+    InputStream in = new ByteArrayInputStream("abc".getBytes(Charsets.UTF_8));
+    assertEquals(ByteString.decodeHex("6162"), ByteString.read(in, 2));
+    assertEquals(ByteString.decodeHex("63"), ByteString.read(in, 1));
+    assertEquals(ByteString.of(), ByteString.read(in, 0));
+  }
+
+  @Test public void readAndToLowercase() throws Exception {
+    InputStream in = new ByteArrayInputStream("ABC".getBytes(Charsets.UTF_8));
+    assertEquals(ByteString.encodeUtf8("ab"), ByteString.read(in, 2).toAsciiLowercase());
+    assertEquals(ByteString.encodeUtf8("c"), ByteString.read(in, 1).toAsciiLowercase());
+    assertEquals(ByteString.EMPTY, ByteString.read(in, 0).toAsciiLowercase());
+  }
+
+  @Test public void toAsciiLowerCaseNoUppercase() throws Exception {
+    ByteString s = factory.encodeUtf8("a1_+");
+    assertEquals(s, s.toAsciiLowercase());
+    if (factory == Factory.BYTE_STRING) {
+      assertSame(s, s.toAsciiLowercase());
+    }
+  }
+
+  @Test public void toAsciiAllUppercase() throws Exception {
+    assertEquals(ByteString.encodeUtf8("ab"), factory.encodeUtf8("AB").toAsciiLowercase());
+  }
+
+  @Test public void toAsciiStartsLowercaseEndsUppercase() throws Exception {
+    assertEquals(ByteString.encodeUtf8("abcd"), factory.encodeUtf8("abCD").toAsciiLowercase());
+  }
+
+  @Test public void readAndToUppercase() throws Exception {
+    InputStream in = new ByteArrayInputStream("abc".getBytes(Charsets.UTF_8));
+    assertEquals(ByteString.encodeUtf8("AB"), ByteString.read(in, 2).toAsciiUppercase());
+    assertEquals(ByteString.encodeUtf8("C"), ByteString.read(in, 1).toAsciiUppercase());
+    assertEquals(ByteString.EMPTY, ByteString.read(in, 0).toAsciiUppercase());
+  }
+
+  @Test public void toAsciiStartsUppercaseEndsLowercase() throws Exception {
+    assertEquals(ByteString.encodeUtf8("ABCD"), factory.encodeUtf8("ABcd").toAsciiUppercase());
+  }
+
+  @Test public void substring() throws Exception {
+    ByteString byteString = factory.encodeUtf8("Hello, World!");
+
+    assertEquals(byteString.substring(0), byteString);
+    assertEquals(byteString.substring(0, 5), ByteString.encodeUtf8("Hello"));
+    assertEquals(byteString.substring(7), ByteString.encodeUtf8("World!"));
+    assertEquals(byteString.substring(6, 6), ByteString.encodeUtf8(""));
+  }
+
+  @Test public void substringWithInvalidBounds() throws Exception {
+    ByteString byteString = factory.encodeUtf8("Hello, World!");
+
+    try {
+      byteString.substring(-1);
+      fail();
+    } catch (IllegalArgumentException expected) {
+    }
+
+    try {
+      byteString.substring(0, 14);
+      fail();
+    } catch (IllegalArgumentException expected) {
+    }
+
+    try {
+      byteString.substring(8, 7);
+      fail();
+    } catch (IllegalArgumentException expected) {
+    }
+  }
+
+  @Test public void write() throws Exception {
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+    factory.decodeHex("616263").write(out);
+    assertByteArraysEquals(new byte[] { 0x61, 0x62, 0x63 }, out.toByteArray());
+  }
+
+  @Test public void encodeBase64() {
+    assertEquals("", factory.encodeUtf8("").base64());
+    assertEquals("AA==", factory.encodeUtf8("\u0000").base64());
+    assertEquals("AAA=", factory.encodeUtf8("\u0000\u0000").base64());
+    assertEquals("AAAA", factory.encodeUtf8("\u0000\u0000\u0000").base64());
+    assertEquals("SG93IG1hbnkgbGluZXMgb2YgY29kZSBhcmUgdGhlcmU/ICdib3V0IDIgbWlsbGlvbi4=",
+        factory.encodeUtf8("How many lines of code are there? 'bout 2 million.").base64());
+  }
+
+  @Test public void encodeBase64Url() {
+    assertEquals("", factory.encodeUtf8("").base64Url());
+    assertEquals("AA==", factory.encodeUtf8("\u0000").base64Url());
+    assertEquals("AAA=", factory.encodeUtf8("\u0000\u0000").base64Url());
+    assertEquals("AAAA", factory.encodeUtf8("\u0000\u0000\u0000").base64Url());
+    assertEquals("SG93IG1hbnkgbGluZXMgb2YgY29kZSBhcmUgdGhlcmU_ICdib3V0IDIgbWlsbGlvbi4=",
+        factory.encodeUtf8("How many lines of code are there? 'bout 2 million.").base64Url());
+  }
+
+  @Test public void ignoreUnnecessaryPadding() {
+    assertEquals("", ByteString.decodeBase64("====").utf8());
+    assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64("AAAA====").utf8());
+  }
+
+  @Test public void decodeBase64() {
+    assertEquals("", ByteString.decodeBase64("").utf8());
+    assertEquals(null, ByteString.decodeBase64("/===")); // Can't do anything with 6 bits!
+    assertEquals(ByteString.decodeHex("ff"), ByteString.decodeBase64("//=="));
+    assertEquals(ByteString.decodeHex("ff"), ByteString.decodeBase64("__=="));
+    assertEquals(ByteString.decodeHex("ffff"), ByteString.decodeBase64("///="));
+    assertEquals(ByteString.decodeHex("ffff"), ByteString.decodeBase64("___="));
+    assertEquals(ByteString.decodeHex("ffffff"), ByteString.decodeBase64("////"));
+    assertEquals(ByteString.decodeHex("ffffff"), ByteString.decodeBase64("____"));
+    assertEquals(ByteString.decodeHex("ffffffffffff"), ByteString.decodeBase64("////////"));
+    assertEquals(ByteString.decodeHex("ffffffffffff"), ByteString.decodeBase64("________"));
+    assertEquals("What's to be scared about? It's just a little hiccup in the power...",
+        ByteString.decodeBase64("V2hhdCdzIHRvIGJlIHNjYXJlZCBhYm91dD8gSXQncyBqdXN0IGEgbGl0dGxlIGhpY2"
+            + "N1cCBpbiB0aGUgcG93ZXIuLi4=").utf8());
+    // Uses two encoding styles. Malformed, but supported as a side-effect.
+    assertEquals(ByteString.decodeHex("ffffff"), ByteString.decodeBase64("__//"));
+  }
+
+  @Test public void decodeBase64WithWhitespace() {
+    assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64(" AA AA ").utf8());
+    assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64(" AA A\r\nA ").utf8());
+    assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64("AA AA").utf8());
+    assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64(" AA AA ").utf8());
+    assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64(" AA A\r\nA ").utf8());
+    assertEquals("\u0000\u0000\u0000", ByteString.decodeBase64("A    AAA").utf8());
+    assertEquals("", ByteString.decodeBase64("    ").utf8());
+  }
+
+  @Test public void encodeHex() throws Exception {
+    assertEquals("000102", ByteString.of((byte) 0x0, (byte) 0x1, (byte) 0x2).hex());
+  }
+
+  @Test public void decodeHex() throws Exception {
+    assertEquals(ByteString.of((byte) 0x0, (byte) 0x1, (byte) 0x2), ByteString.decodeHex("000102"));
+  }
+
+  @Test public void decodeHexOddNumberOfChars() throws Exception {
+    try {
+      ByteString.decodeHex("aaa");
+      fail();
+    } catch (IllegalArgumentException expected) {
+    }
+  }
+
+  @Test public void decodeHexInvalidChar() throws Exception {
+    try {
+      ByteString.decodeHex("a\u0000");
+      fail();
+    } catch (IllegalArgumentException expected) {
+    }
+  }
+
+  @Test public void toStringOnEmpty() {
+    assertEquals("[size=0]", factory.decodeHex("").toString());
+  }
+
+  @Test public void toStringOnShortText() {
+    assertEquals("[text=Tyrannosaur]",
+        factory.encodeUtf8("Tyrannosaur").toString());
+    assertEquals("[text=təˈranəˌsôr]",
+        factory.decodeHex("74c999cb8872616ec999cb8c73c3b472").toString());
+  }
+
+  @Test public void toStringOnLongTextIsTruncated() {
+    String raw = "Um, I'll tell you the problem with the scientific power that you're using here, "
+        + "it didn't require any discipline to attain it. You read what others had done and you "
+        + "took the next step. You didn't earn the knowledge for yourselves, so you don't take any "
+        + "responsibility for it. You stood on the shoulders of geniuses to accomplish something "
+        + "as fast as you could, and before you even knew what you had, you patented it, and "
+        + "packaged it, and slapped it on a plastic lunchbox, and now you're selling it, you wanna "
+        + "sell it.";
+    assertEquals("[size=517 text=Um, I'll tell you the problem with the scientific power that "
+        + "you…]", factory.encodeUtf8(raw).toString());
+    String war = "Սｍ, I'll 𝓽𝖾ll ᶌօ𝘂 ᴛℎ℮ 𝜚𝕣०ｂl𝖾ｍ ｗі𝕥𝒽 𝘵𝘩𝐞 𝓼𝙘𝐢𝔢𝓷𝗍𝜄𝚏𝑖ｃ 𝛠𝝾ｗ𝚎𝑟 𝕥ｈ⍺𝞃 𝛄𝓸𝘂'𝒓𝗲 υ𝖘𝓲𝗇ɡ 𝕙𝚎𝑟ｅ, "
+        + "𝛊𝓽 ⅆ𝕚𝐝𝝿'𝗍 𝔯𝙚𝙦ᴜ𝜾𝒓𝘦 𝔞𝘯𝐲 ԁ𝜄𝑠𝚌ι𝘱lι𝒏ｅ 𝑡𝜎 𝕒𝚝𝖙𝓪і𝞹 𝔦𝚝. 𝒀ο𝗎 𝔯𝑒⍺𝖉 ｗ𝐡𝝰𝔱 𝞂𝞽һ𝓮𝓇ƽ հ𝖺𝖉 ⅾ𝛐𝝅ⅇ 𝝰πԁ 𝔂ᴑᴜ 𝓉ﮨ၀𝚔 "
+        + "т𝒽𝑒 𝗇𝕖ⅹ𝚝 𝔰𝒕е𝓅. 𝘠ⲟ𝖚 𝖉ⅰԁ𝝕'τ 𝙚𝚊ｒ𝞹 𝘵Ꮒ𝖾 𝝒𝐧هｗl𝑒𝖉ƍ𝙚 𝓯૦ｒ 𝔂𝞼𝒖𝕣𝑠𝕖l𝙫𝖊𝓼, 𐑈о ｙ𝘰𝒖 ⅆە𝗇'ｔ 𝜏α𝒌𝕖 𝛂𝟉ℽ "
+        + "𝐫ⅇ𝗌ⲣ๐ϖ𝖘ꙇᖯ𝓲l𝓲𝒕𝘆 𝐟𝞼𝘳 𝚤𝑡. 𝛶𝛔𝔲 ｓ𝕥σσ𝐝 ﮩ𝕟 𝒕𝗁𝔢 𝘴𝐡𝜎ᴜlⅾ𝓮𝔯𝚜 𝛐𝙛 ᶃ𝚎ᴨᎥս𝚜𝘦𝓈 𝓽𝞸 ａ𝒄𝚌𝞸ｍρl𝛊ꜱ𝐡 𝓈𝚘ｍ𝚎𝞃𝔥⍳𝞹𝔤 𝐚𝗌 𝖋ａ𝐬𝒕 "
+        + "αｓ γ𝛐𝕦 𝔠ﻫ𝛖lԁ, 𝚊π𝑑 Ь𝑒𝙛૦𝓇𝘦 𝓎٥𝖚 ⅇｖℯ𝝅 𝜅ո𝒆ｗ ｗ𝗵𝒂𝘁 ᶌ੦𝗎 ｈ𝐚𝗱, 𝜸ﮨ𝒖 𝓹𝝰𝔱𝖾𝗇𝓽𝔢ⅆ і𝕥, 𝚊𝜛𝓭 𝓹𝖺ⅽϰ𝘢ℊеᏧ 𝑖𝞃, "
+        + "𝐚𝛑ꓒ 𝙨l𝔞р𝘱𝔢𝓭 ɩ𝗍 ہ𝛑 𝕒 ｐl𝛂ѕᴛ𝗂𝐜 l𝞄ℼ𝔠𝒽𝑏ﮪ⨯, 𝔞ϖ𝒹 ｎ𝛔ｗ 𝛾𝐨𝞄'𝗿𝔢 ꜱ℮ll𝙞ｎɡ ɩ𝘁, 𝙮𝕠𝛖 ｗ𝑎ℼ𝚗𝛂 𝕤𝓮ll 𝙞𝓉.";
+    assertEquals( "[size=1496 text=Սｍ, I'll 𝓽𝖾ll ᶌօ𝘂 ᴛℎ℮ 𝜚𝕣०ｂl𝖾ｍ ｗі𝕥𝒽 𝘵𝘩𝐞 𝓼𝙘𝐢𝔢𝓷𝗍𝜄𝚏𝑖ｃ 𝛠𝝾ｗ𝚎𝑟 𝕥ｈ⍺𝞃 "
+        + "𝛄𝓸𝘂…]", factory.encodeUtf8(war).toString());
+  }
+
+  @Test public void toStringOnTextWithNewlines() {
+    // Instead of emitting a literal newline in the toString(), these are escaped as "\n".
+    assertEquals("[text=a\\r\\nb\\nc\\rd\\\\e]",
+        factory.encodeUtf8("a\r\nb\nc\rd\\e").toString());
+  }
+
+  @Test public void toStringOnData() {
+    ByteString byteString = factory.decodeHex(""
+        + "60b420bb3851d9d47acb933dbe70399bf6c92da33af01d4fb770e98c0325f41d3ebaf8986da712c82bcd4d55"
+        + "4bf0b54023c29b624de9ef9c2f931efc580f9afb");
+    assertEquals("[hex="
+        + "60b420bb3851d9d47acb933dbe70399bf6c92da33af01d4fb770e98c0325f41d3ebaf8986da712c82bcd4d55"
+        + "4bf0b54023c29b624de9ef9c2f931efc580f9afb]", byteString.toString());
+  }
+
+  @Test public void toStringOnLongDataIsTruncated() {
+    ByteString byteString = factory.decodeHex(""
+        + "60b420bb3851d9d47acb933dbe70399bf6c92da33af01d4fb770e98c0325f41d3ebaf8986da712c82bcd4d55"
+        + "4bf0b54023c29b624de9ef9c2f931efc580f9afba1");
+    assertEquals("[size=65 hex="
+        + "60b420bb3851d9d47acb933dbe70399bf6c92da33af01d4fb770e98c0325f41d3ebaf8986da712c82bcd4d55"
+        + "4bf0b54023c29b624de9ef9c2f931efc580f9afb…]", byteString.toString());
+  }
+
+  @Test public void javaSerializationTestNonEmpty() throws Exception {
+    ByteString byteString = factory.encodeUtf8(bronzeHorseman);
+    assertEquivalent(byteString, TestUtil.<ByteString>reserialize(byteString));
+  }
+
+  @Test public void javaSerializationTestEmpty() throws Exception {
+    ByteString byteString = factory.decodeHex("");
+    assertEquivalent(byteString, TestUtil.<ByteString>reserialize(byteString));
+  }
+
+  @Test public void compareToSingleBytes() throws Exception {
+    List<ByteString> originalByteStrings = Arrays.asList(
+        factory.decodeHex("00"),
+        factory.decodeHex("01"),
+        factory.decodeHex("7e"),
+        factory.decodeHex("7f"),
+        factory.decodeHex("80"),
+        factory.decodeHex("81"),
+        factory.decodeHex("fe"),
+        factory.decodeHex("ff"));
+
+    List<ByteString> sortedByteStrings = new ArrayList<>(originalByteStrings);
+    Collections.shuffle(sortedByteStrings, new Random(0));
+    Collections.sort(sortedByteStrings);
+
+    assertEquals(originalByteStrings, sortedByteStrings);
+  }
+
+  @Test public void compareToMultipleBytes() throws Exception {
+    List<ByteString> originalByteStrings = Arrays.asList(
+        factory.decodeHex(""),
+        factory.decodeHex("00"),
+        factory.decodeHex("0000"),
+        factory.decodeHex("000000"),
+        factory.decodeHex("00000000"),
+        factory.decodeHex("0000000000"),
+        factory.decodeHex("0000000001"),
+        factory.decodeHex("000001"),
+        factory.decodeHex("00007f"),
+        factory.decodeHex("0000ff"),
+        factory.decodeHex("000100"),
+        factory.decodeHex("000101"),
+        factory.decodeHex("007f00"),
+        factory.decodeHex("00ff00"),
+        factory.decodeHex("010000"),
+        factory.decodeHex("010001"),
+        factory.decodeHex("01007f"),
+        factory.decodeHex("0100ff"),
+        factory.decodeHex("010100"),
+        factory.decodeHex("01010000"),
+        factory.decodeHex("0101000000"),
+        factory.decodeHex("0101000001"),
+        factory.decodeHex("010101"),
+        factory.decodeHex("7f0000"),
+        factory.decodeHex("7f0000ffff"),
+        factory.decodeHex("ffffff"));
+
+    List<ByteString> sortedByteStrings = new ArrayList<>(originalByteStrings);
+    Collections.shuffle(sortedByteStrings, new Random(0));
+    Collections.sort(sortedByteStrings);
+
+    assertEquals(originalByteStrings, sortedByteStrings);
+  }
+
+  @Test public void asByteBuffer() {
+    assertEquals(0x42, ByteString.of((byte) 0x41, (byte) 0x42, (byte) 0x43).asByteBuffer().get(1));
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/DeflaterSinkTest.java b/okio/src/jvmTest/java/okio/DeflaterSinkTest.java
new file mode 100644
index 0000000..f0a31f0
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/DeflaterSinkTest.java
@@ -0,0 +1,149 @@
+/*
+ * 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 okio;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
+import java.util.zip.InflaterInputStream;
+import org.junit.Test;
+
+import static kotlin.text.StringsKt.repeat;
+import static okio.TestUtil.SEGMENT_SIZE;
+import static okio.TestUtil.randomBytes;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public final class DeflaterSinkTest {
+  @Test public void deflateWithClose() throws Exception {
+    Buffer data = new Buffer();
+    String original = "They're moving in herds. They do move in herds.";
+    data.writeUtf8(original);
+    Buffer sink = new Buffer();
+    DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater());
+    deflaterSink.write(data, data.size());
+    deflaterSink.close();
+    Buffer inflated = inflate(sink);
+    assertEquals(original, inflated.readUtf8());
+  }
+
+  @Test public void deflateWithSyncFlush() throws Exception {
+    String original = "Yes, yes, yes. That's why we're taking extreme precautions.";
+    Buffer data = new Buffer();
+    data.writeUtf8(original);
+    Buffer sink = new Buffer();
+    DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater());
+    deflaterSink.write(data, data.size());
+    deflaterSink.flush();
+    Buffer inflated = inflate(sink);
+    assertEquals(original, inflated.readUtf8());
+  }
+
+  @Test public void deflateWellCompressed() throws IOException {
+    String original = repeat("a", 1024 * 1024);
+    Buffer data = new Buffer();
+    data.writeUtf8(original);
+    Buffer sink = new Buffer();
+    DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater());
+    deflaterSink.write(data, data.size());
+    deflaterSink.close();
+    Buffer inflated = inflate(sink);
+    assertEquals(original, inflated.readUtf8());
+  }
+
+  @Test public void deflatePoorlyCompressed() throws IOException {
+    ByteString original = randomBytes(1024 * 1024);
+    Buffer data = new Buffer();
+    data.write(original);
+    Buffer sink = new Buffer();
+    DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater());
+    deflaterSink.write(data, data.size());
+    deflaterSink.close();
+    Buffer inflated = inflate(sink);
+    assertEquals(original, inflated.readByteString());
+  }
+
+  @Test public void multipleSegmentsWithoutCompression() throws IOException {
+    Buffer buffer = new Buffer();
+    Deflater deflater = new Deflater();
+    deflater.setLevel(Deflater.NO_COMPRESSION);
+    DeflaterSink deflaterSink = new DeflaterSink(buffer, deflater);
+    int byteCount = SEGMENT_SIZE * 4;
+    deflaterSink.write(new Buffer().writeUtf8(repeat("a", byteCount)), byteCount);
+    deflaterSink.close();
+    assertEquals(repeat("a", byteCount), inflate(buffer).readUtf8(byteCount));
+  }
+
+  @Test public void deflateIntoNonemptySink() throws Exception {
+    String original = "They're moving in herds. They do move in herds.";
+
+    // Exercise all possible offsets for the outgoing segment.
+    for (int i = 0; i < SEGMENT_SIZE; i++) {
+      Buffer data = new Buffer().writeUtf8(original);
+      Buffer sink = new Buffer().writeUtf8(repeat("a", i));
+
+      DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater());
+      deflaterSink.write(data, data.size());
+      deflaterSink.close();
+
+      sink.skip(i);
+      Buffer inflated = inflate(sink);
+      assertEquals(original, inflated.readUtf8());
+    }
+  }
+
+  /**
+   * This test deflates a single segment of without compression because that's
+   * the easiest way to force close() to emit a large amount of data to the
+   * underlying sink.
+   */
+  @Test public void closeWithExceptionWhenWritingAndClosing() throws IOException {
+    MockSink mockSink = new MockSink();
+    mockSink.scheduleThrow(0, new IOException("first"));
+    mockSink.scheduleThrow(1, new IOException("second"));
+    Deflater deflater = new Deflater();
+    deflater.setLevel(Deflater.NO_COMPRESSION);
+    DeflaterSink deflaterSink = new DeflaterSink(mockSink, deflater);
+    deflaterSink.write(new Buffer().writeUtf8(repeat("a", SEGMENT_SIZE)), SEGMENT_SIZE);
+    try {
+      deflaterSink.close();
+      fail();
+    } catch (IOException expected) {
+      assertEquals("first", expected.getMessage());
+    }
+    mockSink.assertLogContains("close()");
+  }
+
+  /**
+   * Uses streaming decompression to inflate {@code deflated}. The input must
+   * either be finished or have a trailing sync flush.
+   */
+  private Buffer inflate(Buffer deflated) throws IOException {
+    InputStream deflatedIn = deflated.inputStream();
+    Inflater inflater = new Inflater();
+    InputStream inflatedIn = new InflaterInputStream(deflatedIn, inflater);
+    Buffer result = new Buffer();
+    byte[] buffer = new byte[8192];
+    while (!inflater.needsInput() || deflated.size() > 0 || deflatedIn.available() > 0) {
+      int count = inflatedIn.read(buffer, 0, buffer.length);
+      if (count != -1) {
+        result.write(buffer, 0, count);
+      }
+    }
+    return result;
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/ForwardingTimeoutTest.java b/okio/src/jvmTest/java/okio/ForwardingTimeoutTest.java
new file mode 100644
index 0000000..45536fc
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/ForwardingTimeoutTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 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 okio;
+
+import java.util.concurrent.TimeUnit;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ForwardingTimeoutTest {
+  @Test public void getAndSetDelegate() {
+    Timeout timeout1 = new Timeout();
+    Timeout timeout2 = new Timeout();
+
+    ForwardingTimeout forwardingTimeout = new ForwardingTimeout(timeout1);
+    forwardingTimeout.timeout(5, TimeUnit.SECONDS);
+    assertThat(timeout1.timeoutNanos()).isNotEqualTo(0L);
+    assertThat(timeout2.timeoutNanos()).isEqualTo(0L);
+    forwardingTimeout.clearTimeout();
+    assertThat(timeout1.timeoutNanos()).isEqualTo(0L);
+    assertThat(timeout2.timeoutNanos()).isEqualTo(0L);
+    assertThat(forwardingTimeout.delegate()).isEqualTo(timeout1);
+
+    assertThat(forwardingTimeout.setDelegate(timeout2)).isEqualTo(forwardingTimeout);
+    forwardingTimeout.timeout(5, TimeUnit.SECONDS);
+    assertThat(timeout1.timeoutNanos()).isEqualTo(0L);
+    assertThat(timeout2.timeoutNanos()).isNotEqualTo(0L);
+    forwardingTimeout.clearTimeout();
+    assertThat(timeout1.timeoutNanos()).isEqualTo(0L);
+    assertThat(timeout2.timeoutNanos()).isEqualTo(0L);
+    assertThat(forwardingTimeout.delegate()).isEqualTo(timeout2);
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/GzipSinkTest.java b/okio/src/jvmTest/java/okio/GzipSinkTest.java
new file mode 100644
index 0000000..848ff02
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/GzipSinkTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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 okio;
+
+import java.io.IOException;
+import org.junit.Test;
+
+import static kotlin.text.StringsKt.repeat;
+import static okio.TestUtil.SEGMENT_SIZE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public final class GzipSinkTest {
+  @Test public void gzipGunzip() throws Exception {
+    Buffer data = new Buffer();
+    String original = "It's a UNIX system! I know this!";
+    data.writeUtf8(original);
+    Buffer sink = new Buffer();
+    GzipSink gzipSink = new GzipSink(sink);
+    gzipSink.write(data, data.size());
+    gzipSink.close();
+    Buffer inflated = gunzip(sink);
+    assertEquals(original, inflated.readUtf8());
+  }
+
+  @Test public void closeWithExceptionWhenWritingAndClosing() throws IOException {
+    MockSink mockSink = new MockSink();
+    mockSink.scheduleThrow(0, new IOException("first"));
+    mockSink.scheduleThrow(1, new IOException("second"));
+    GzipSink gzipSink = new GzipSink(mockSink);
+    gzipSink.write(new Buffer().writeUtf8(repeat("a", SEGMENT_SIZE)), SEGMENT_SIZE);
+    try {
+      gzipSink.close();
+      fail();
+    } catch (IOException expected) {
+      assertEquals("first", expected.getMessage());
+    }
+    mockSink.assertLogContains("close()");
+  }
+
+  private Buffer gunzip(Buffer gzipped) throws IOException {
+    Buffer result = new Buffer();
+    GzipSource source = new GzipSource(gzipped);
+    while (source.read(result, Integer.MAX_VALUE) != -1) {
+    }
+    return result;
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/GzipSourceTest.java b/okio/src/jvmTest/java/okio/GzipSourceTest.java
new file mode 100644
index 0000000..69b81e3
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/GzipSourceTest.java
@@ -0,0 +1,233 @@
+/*
+ * 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 okio;
+
+import java.io.IOException;
+import java.util.zip.CRC32;
+import org.junit.Test;
+
+import static kotlin.text.Charsets.UTF_8;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public final class GzipSourceTest {
+
+  @Test public void gunzip() throws Exception {
+    Buffer gzipped = new Buffer();
+    gzipped.write(gzipHeader);
+    gzipped.write(deflated);
+    gzipped.write(gzipTrailer);
+    assertGzipped(gzipped);
+  }
+
+  @Test public void gunzip_withHCRC() throws Exception {
+    CRC32 hcrc = new CRC32();
+    ByteString gzipHeader = gzipHeaderWithFlags((byte) 0x02);
+    hcrc.update(gzipHeader.toByteArray());
+
+    Buffer gzipped = new Buffer();
+    gzipped.write(gzipHeader);
+    gzipped.writeShort(TestUtil.reverseBytes((short) hcrc.getValue())); // little endian
+    gzipped.write(deflated);
+    gzipped.write(gzipTrailer);
+    assertGzipped(gzipped);
+  }
+
+  @Test public void gunzip_withExtra() throws Exception {
+    Buffer gzipped = new Buffer();
+    gzipped.write(gzipHeaderWithFlags((byte) 0x04));
+    gzipped.writeShort(TestUtil.reverseBytes((short) 7)); // little endian extra length
+    gzipped.write("blubber".getBytes(UTF_8), 0, 7);
+    gzipped.write(deflated);
+    gzipped.write(gzipTrailer);
+    assertGzipped(gzipped);
+  }
+
+  @Test public void gunzip_withName() throws Exception {
+    Buffer gzipped = new Buffer();
+    gzipped.write(gzipHeaderWithFlags((byte) 0x08));
+    gzipped.write("foo.txt".getBytes(UTF_8), 0, 7);
+    gzipped.writeByte(0); // zero-terminated
+    gzipped.write(deflated);
+    gzipped.write(gzipTrailer);
+    assertGzipped(gzipped);
+  }
+
+  @Test public void gunzip_withComment() throws Exception {
+    Buffer gzipped = new Buffer();
+    gzipped.write(gzipHeaderWithFlags((byte) 0x10));
+    gzipped.write("rubbish".getBytes(UTF_8), 0, 7);
+    gzipped.writeByte(0); // zero-terminated
+    gzipped.write(deflated);
+    gzipped.write(gzipTrailer);
+    assertGzipped(gzipped);
+  }
+
+  /**
+   * For portability, it is a good idea to export the gzipped bytes and try running gzip.  Ex.
+   * {@code echo gzipped | base64 --decode | gzip -l -v}
+   */
+  @Test public void gunzip_withAll() throws Exception {
+    Buffer gzipped = new Buffer();
+    gzipped.write(gzipHeaderWithFlags((byte) 0x1c));
+    gzipped.writeShort(TestUtil.reverseBytes((short) 7)); // little endian extra length
+    gzipped.write("blubber".getBytes(UTF_8), 0, 7);
+    gzipped.write("foo.txt".getBytes(UTF_8), 0, 7);
+    gzipped.writeByte(0); // zero-terminated
+    gzipped.write("rubbish".getBytes(UTF_8), 0, 7);
+    gzipped.writeByte(0); // zero-terminated
+    gzipped.write(deflated);
+    gzipped.write(gzipTrailer);
+    assertGzipped(gzipped);
+  }
+
+  private void assertGzipped(Buffer gzipped) throws IOException {
+    Buffer gunzipped = gunzip(gzipped);
+    assertEquals("It's a UNIX system! I know this!", gunzipped.readUtf8());
+  }
+
+  /**
+   * Note that you cannot test this with old versions of gzip, as they interpret flag bit 1 as
+   * CONTINUATION, not HCRC. For example, this is the case with the default gzip on osx.
+   */
+  @Test public void gunzipWhenHeaderCRCIncorrect() {
+    Buffer gzipped = new Buffer();
+    gzipped.write(gzipHeaderWithFlags((byte) 0x02));
+    gzipped.writeShort((short) 0); // wrong HCRC!
+    gzipped.write(deflated);
+    gzipped.write(gzipTrailer);
+
+    try {
+      gunzip(gzipped);
+      fail();
+    } catch (IOException e) {
+      assertEquals("FHCRC: actual 0x0000261d != expected 0x00000000", e.getMessage());
+    }
+  }
+
+  @Test public void gunzipWhenCRCIncorrect() {
+    Buffer gzipped = new Buffer();
+    gzipped.write(gzipHeader);
+    gzipped.write(deflated);
+    gzipped.writeInt(TestUtil.reverseBytes(0x1234567)); // wrong CRC
+    gzipped.write(gzipTrailer.toByteArray(), 3, 4);
+
+    try {
+      gunzip(gzipped);
+      fail();
+    } catch (IOException e) {
+      assertEquals("CRC: actual 0x37ad8f8d != expected 0x01234567", e.getMessage());
+    }
+  }
+
+  @Test public void gunzipWhenLengthIncorrect() {
+    Buffer gzipped = new Buffer();
+    gzipped.write(gzipHeader);
+    gzipped.write(deflated);
+    gzipped.write(gzipTrailer.toByteArray(), 0, 4);
+    gzipped.writeInt(TestUtil.reverseBytes(0x123456)); // wrong length
+
+    try {
+      gunzip(gzipped);
+      fail();
+    } catch (IOException e) {
+      assertEquals("ISIZE: actual 0x00000020 != expected 0x00123456", e.getMessage());
+    }
+  }
+
+  @Test public void gunzipExhaustsSource() throws Exception {
+    Buffer gzippedSource = new Buffer()
+        .write(ByteString.decodeHex("1f8b08000000000000004b4c4a0600c241243503000000")); // 'abc'
+
+    ExhaustableSource exhaustableSource = new ExhaustableSource(gzippedSource);
+    BufferedSource gunzippedSource = Okio.buffer(new GzipSource(exhaustableSource));
+
+    assertEquals('a', gunzippedSource.readByte());
+    assertEquals('b', gunzippedSource.readByte());
+    assertEquals('c', gunzippedSource.readByte());
+    assertFalse(exhaustableSource.exhausted);
+    assertEquals(-1, gunzippedSource.read(new Buffer(), 1));
+    assertTrue(exhaustableSource.exhausted);
+  }
+
+  @Test public void gunzipThrowsIfSourceIsNotExhausted() throws Exception {
+    Buffer gzippedSource = new Buffer()
+        .write(ByteString.decodeHex("1f8b08000000000000004b4c4a0600c241243503000000")); // 'abc'
+    gzippedSource.writeByte('d'); // This byte shouldn't be here!
+
+    BufferedSource gunzippedSource = Okio.buffer(new GzipSource(gzippedSource));
+
+    assertEquals('a', gunzippedSource.readByte());
+    assertEquals('b', gunzippedSource.readByte());
+    assertEquals('c', gunzippedSource.readByte());
+    try {
+      gunzippedSource.readByte();
+      fail();
+    } catch (IOException expected) {
+    }
+  }
+
+  private ByteString gzipHeaderWithFlags(byte flags) {
+    byte[] result = gzipHeader.toByteArray();
+    result[3] = flags;
+    return ByteString.of(result);
+  }
+
+  private final ByteString gzipHeader = ByteString.decodeHex("1f8b0800000000000000");
+
+  // Deflated "It's a UNIX system! I know this!"
+  private final ByteString deflated = ByteString.decodeHex(
+      "f32c512f56485408f5f38c5028ae2c2e49cd5554f054c8cecb2f5728c9c82c560400");
+
+  private final ByteString gzipTrailer = ByteString.decodeHex(""
+      + "8d8fad37" // Checksum of deflated.
+      + "20000000" // 32 in little endian.
+  );
+
+  private Buffer gunzip(Buffer gzipped) throws IOException {
+    Buffer result = new Buffer();
+    GzipSource source = new GzipSource(gzipped);
+    while (source.read(result, Integer.MAX_VALUE) != -1) {
+    }
+    return result;
+  }
+
+  /** This source keeps track of whether its read has returned -1. */
+  static class ExhaustableSource implements Source {
+    private final Source source;
+    private boolean exhausted;
+
+    ExhaustableSource(Source source) {
+      this.source = source;
+    }
+
+    @Override public long read(Buffer sink, long byteCount) throws IOException {
+      long result = source.read(sink, byteCount);
+      if (result == -1) exhausted = true;
+      return result;
+    }
+
+    @Override public Timeout timeout() {
+      return source.timeout();
+    }
+
+    @Override public void close() throws IOException {
+      source.close();
+    }
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/InflaterSourceTest.java b/okio/src/jvmTest/java/okio/InflaterSourceTest.java
new file mode 100644
index 0000000..0486638
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/InflaterSourceTest.java
@@ -0,0 +1,210 @@
+/*
+ * 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 okio;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.util.List;
+import java.util.zip.DeflaterOutputStream;
+import java.util.zip.Inflater;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import static kotlin.text.StringsKt.repeat;
+import static okio.TestUtil.SEGMENT_SIZE;
+import static okio.TestUtil.randomBytes;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
+
+@RunWith(Parameterized.class)
+public final class InflaterSourceTest {
+  /**
+   * Use a parameterized test to control how many bytes the InflaterSource gets with each request
+   * for more bytes.
+   */
+  @Parameters(name = "{0}")
+  public static List<Object[]> parameters() {
+    return BufferedSourceFactory.Companion.getPARAMETERIZED_TEST_VALUES();
+  }
+
+  public final BufferedSourceFactory bufferFactory;
+  public BufferedSink deflatedSink;
+  public BufferedSource deflatedSource;
+
+  public InflaterSourceTest(BufferedSourceFactory bufferFactory) {
+    this.bufferFactory = bufferFactory;
+    resetDeflatedSourceAndSink();
+  }
+
+  private void resetDeflatedSourceAndSink() {
+    BufferedSourceFactory.Pipe pipe = bufferFactory.pipe();
+    this.deflatedSink = pipe.getSink();
+    this.deflatedSource = pipe.getSource();
+  }
+
+  @Test public void inflate() throws Exception {
+    decodeBase64("eJxzz09RyEjNKVAoLdZRKE9VL0pVyMxTKMlIVchIzEspVshPU0jNS8/MS00tKtYDAF6CD5s=");
+    Buffer inflated = inflate(deflatedSource);
+    assertEquals("God help us, we're in the hands of engineers.", inflated.readUtf8());
+  }
+
+  @Test public void inflateTruncated() throws Exception {
+    decodeBase64("eJxzz09RyEjNKVAoLdZRKE9VL0pVyMxTKMlIVchIzEspVshPU0jNS8/MS00tKtYDAF6CDw==");
+    try {
+      inflate(deflatedSource);
+      fail();
+    } catch (EOFException expected) {
+    }
+  }
+
+  @Test public void inflateWellCompressed() throws Exception {
+    decodeBase64("eJztwTEBAAAAwqCs61/CEL5AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8BtFeWvE=");
+    String original = repeat("a", 1024 * 1024);
+    deflate(ByteString.encodeUtf8(original));
+    Buffer inflated = inflate(deflatedSource);
+    assertEquals(original, inflated.readUtf8());
+  }
+
+  @Test public void inflatePoorlyCompressed() throws Exception {
+    assumeFalse(bufferFactory.isOneByteAtATime()); // 8 GiB for 1 byte per segment!
+
+    ByteString original = randomBytes(1024 * 1024);
+    deflate(original);
+    Buffer inflated = inflate(deflatedSource);
+    assertEquals(original, inflated.readByteString());
+  }
+
+  @Test public void inflateIntoNonemptySink() throws Exception {
+    for (int i = 0; i < SEGMENT_SIZE; i++) {
+      resetDeflatedSourceAndSink();
+      Buffer inflated = new Buffer().writeUtf8(repeat("a", i));
+      deflate(ByteString.encodeUtf8("God help us, we're in the hands of engineers."));
+      InflaterSource source = new InflaterSource(deflatedSource, new Inflater());
+      while (source.read(inflated, Integer.MAX_VALUE) != -1) {
+      }
+      inflated.skip(i);
+      assertEquals("God help us, we're in the hands of engineers.", inflated.readUtf8());
+    }
+  }
+
+  @Test public void inflateSingleByte() throws Exception {
+    Buffer inflated = new Buffer();
+    decodeBase64("eJxzz09RyEjNKVAoLdZRKE9VL0pVyMxTKMlIVchIzEspVshPU0jNS8/MS00tKtYDAF6CD5s=");
+    InflaterSource source = new InflaterSource(deflatedSource, new Inflater());
+    source.read(inflated, 1);
+    source.close();
+    assertEquals("G", inflated.readUtf8());
+    assertEquals(0, inflated.size());
+  }
+
+  @Test public void inflateByteCount() throws Exception {
+    assumeFalse(bufferFactory.isOneByteAtATime()); // This test assumes one step.
+
+    Buffer inflated = new Buffer();
+    decodeBase64("eJxzz09RyEjNKVAoLdZRKE9VL0pVyMxTKMlIVchIzEspVshPU0jNS8/MS00tKtYDAF6CD5s=");
+    InflaterSource source = new InflaterSource(deflatedSource, new Inflater());
+    source.read(inflated, 11);
+    source.close();
+    assertEquals("God help us", inflated.readUtf8());
+    assertEquals(0, inflated.size());
+  }
+
+  @Test public void sourceExhaustedPrematurelyOnRead() throws Exception {
+    // Deflate 0 bytes of data that lacks the in-stream terminator.
+    decodeBase64("eJwAAAD//w==");
+
+    Buffer inflated = new Buffer();
+    Inflater inflater = new Inflater();
+    InflaterSource source = new InflaterSource(deflatedSource, inflater);
+    assertThat(deflatedSource.exhausted()).isFalse();
+    try {
+      source.read(inflated, Long.MAX_VALUE);
+      fail();
+    } catch (EOFException expected) {
+      assertThat(expected).hasMessage("source exhausted prematurely");
+    }
+
+    // Despite the exception, the read() call made forward progress on the underlying stream!
+    assertThat(deflatedSource.exhausted()).isTrue();
+  }
+
+  /**
+   * Confirm that {@link InflaterSource#readOrInflate} consumes a byte on each call even if it
+   * doesn't produce a byte on every call.
+   */
+  @Test public void readOrInflateMakesByteByByteProgress() throws Exception {
+    // Deflate 0 bytes of data that lacks the in-stream terminator.
+    decodeBase64("eJwAAAD//w==");
+    int deflatedByteCount = 7;
+
+    Buffer inflated = new Buffer();
+    Inflater inflater = new Inflater();
+    InflaterSource source = new InflaterSource(deflatedSource, inflater);
+    assertThat(deflatedSource.exhausted()).isFalse();
+
+    if (bufferFactory.isOneByteAtATime()) {
+      for (int i = 0; i < deflatedByteCount; i++) {
+        assertThat(inflater.getBytesRead()).isEqualTo(i);
+        assertThat(source.readOrInflate(inflated, Long.MAX_VALUE)).isEqualTo(0L);
+      }
+    } else {
+      assertThat(source.readOrInflate(inflated, Long.MAX_VALUE)).isEqualTo(0L);
+    }
+
+    assertThat(inflater.getBytesRead()).isEqualTo(deflatedByteCount);
+    assertThat(deflatedSource.exhausted());
+  }
+
+  private void decodeBase64(String s) throws IOException {
+    deflatedSink.write(ByteString.decodeBase64(s));
+    deflatedSink.flush();
+  }
+
+  /** Use DeflaterOutputStream to deflate source. */
+  private void deflate(ByteString source) throws IOException {
+    Sink sink = Okio.sink(new DeflaterOutputStream(deflatedSink.outputStream()));
+    sink.write(new Buffer().write(source), source.size());
+    sink.close();
+  }
+
+  /** Returns a new buffer containing the inflated contents of {@code deflated}. */
+  private Buffer inflate(BufferedSource deflated) throws IOException {
+    Buffer result = new Buffer();
+    InflaterSource source = new InflaterSource(deflated, new Inflater());
+    while (source.read(result, Integer.MAX_VALUE) != -1) {
+    }
+    return result;
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/LargeStreamsTest.java b/okio/src/jvmTest/java/okio/LargeStreamsTest.java
new file mode 100644
index 0000000..b9be1a2
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/LargeStreamsTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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 okio;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.zip.Deflater;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+import org.junit.Test;
+
+import static okio.TestUtil.SEGMENT_SIZE;
+import static okio.TestUtil.randomSource;
+import static org.junit.Assert.assertEquals;
+
+/** Slow running tests that run a large amount of data through a stream. */
+public final class LargeStreamsTest {
+  /** 4 GiB plus 1 byte. This is greater than what can be expressed in an unsigned int. */
+  public static final long FOUR_GIB_PLUS_ONE = 0x100000001L;
+
+  /** SHA-256 of {@code TestUtil.randomSource(FOUR_GIB_PLUS_ONE)}. */
+  public static final ByteString SHA256_RANDOM_FOUR_GIB_PLUS_1 = ByteString.decodeHex(
+      "9654947a655c5efc445502fd1bf11117d894b7812b7974fde8ca4a02c5066315");
+
+  @Test public void test() throws Exception {
+    Pipe pipe = new Pipe(1024 * 1024);
+
+    Future<Long> future = readAllAndCloseAsync(randomSource(FOUR_GIB_PLUS_ONE), pipe.sink());
+
+    HashingSink hashingSink = HashingSink.sha256(Okio.blackhole());
+    readAllAndClose(pipe.source(), hashingSink);
+
+    assertEquals(FOUR_GIB_PLUS_ONE, (long) future.get());
+    assertEquals(SHA256_RANDOM_FOUR_GIB_PLUS_1, hashingSink.hash());
+  }
+
+  /** Note that this test hangs on Android. */
+  @Test public void gzipSource() throws Exception {
+    Pipe pipe = new Pipe(1024 * 1024);
+
+    OutputStream gzipOut = new GZIPOutputStream(Okio.buffer(pipe.sink()).outputStream()) {
+      {
+        // Disable compression to speed up a slow test. Improved from 141s to 33s on one machine.
+        def.setLevel(Deflater.NO_COMPRESSION);
+      }
+    };
+    Future<Long> future = readAllAndCloseAsync(
+        randomSource(FOUR_GIB_PLUS_ONE), Okio.sink(gzipOut));
+
+    HashingSink hashingSink = HashingSink.sha256(Okio.blackhole());
+    GzipSource gzipSource = new GzipSource(pipe.source());
+    readAllAndClose(gzipSource, hashingSink);
+
+    assertEquals(FOUR_GIB_PLUS_ONE, (long) future.get());
+    assertEquals(SHA256_RANDOM_FOUR_GIB_PLUS_1, hashingSink.hash());
+  }
+
+  /** Note that this test hangs on Android. */
+  @Test public void gzipSink() throws Exception {
+    Pipe pipe = new Pipe(1024 * 1024);
+
+    GzipSink gzipSink = new GzipSink(pipe.sink());
+
+    // Disable compression to speed up a slow test. Improved from 141s to 35s on one machine.
+    gzipSink.deflater().setLevel(Deflater.NO_COMPRESSION);
+    Future<Long> future = readAllAndCloseAsync(randomSource(FOUR_GIB_PLUS_ONE), gzipSink);
+
+    HashingSink hashingSink = HashingSink.sha256(Okio.blackhole());
+    GZIPInputStream gzipIn = new GZIPInputStream(Okio.buffer(pipe.source()).inputStream());
+    readAllAndClose(Okio.source(gzipIn), hashingSink);
+
+    assertEquals(FOUR_GIB_PLUS_ONE, (long) future.get());
+    assertEquals(SHA256_RANDOM_FOUR_GIB_PLUS_1, hashingSink.hash());
+  }
+
+  /** Reads all bytes from {@code source} and writes them to {@code sink}. */
+  private Long readAllAndClose(Source source, Sink sink) throws IOException {
+    long result = 0L;
+    Buffer buffer = new Buffer();
+    for (long count; (count = source.read(buffer, SEGMENT_SIZE)) != -1L; result += count) {
+      sink.write(buffer, count);
+    }
+    source.close();
+    sink.close();
+    return result;
+  }
+
+  /** Calls {@link #readAllAndClose} on a background thread. */
+  private Future<Long> readAllAndCloseAsync(final Source source, final Sink sink) {
+    ExecutorService executor = Executors.newSingleThreadExecutor();
+    try {
+      return executor.submit(new Callable<Long>() {
+        @Override public Long call() throws Exception {
+          return readAllAndClose(source, sink);
+        }
+      });
+    } finally {
+      executor.shutdown();
+    }
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/MessageDigestConsistencyTest.kt b/okio/src/jvmTest/java/okio/MessageDigestConsistencyTest.kt
new file mode 100644
index 0000000..962d011
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/MessageDigestConsistencyTest.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2020 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 okio
+
+import okio.ByteString.Companion.toByteString
+import okio.internal.HashFunction
+import okio.internal.Md5
+import okio.internal.Sha1
+import okio.internal.Sha256
+import okio.internal.Sha512
+import org.assertj.core.api.Assertions.assertThat
+import java.security.MessageDigest
+import java.util.Random
+import kotlin.test.Test
+
+/**
+ * Confirm Okio is consistent with the JDK's MessageDigest algorithms for various sizes and slices.
+ * This makes repeated calls to update() with byte arrays of various sizes and contents to defend
+ * against bugs in batching inputs.
+ */
+class MessageDigestConsistencyTest {
+  @Test fun sha1() {
+    test("SHA-1") { Sha1() }
+  }
+
+  @Test fun sha256() {
+    test("SHA-256") { Sha256() }
+  }
+
+  @Test fun sha512() {
+    test("SHA-512") { Sha512() }
+  }
+
+  @Test fun md5() {
+    test("MD5") { Md5() }
+  }
+
+  private fun test(algorithm: String, newHashFunction: () -> HashFunction) {
+    for (seed in 0L until 1000L) {
+      for (updateCount in 0 until 10) {
+        test(
+          algorithm = algorithm,
+          hashFunction = newHashFunction(),
+          seed = seed,
+          updateCount = updateCount
+        )
+      }
+    }
+  }
+
+  private fun test(
+    algorithm: String,
+    hashFunction: HashFunction,
+    seed: Long,
+    updateCount: Int
+  ) {
+    val data = Buffer()
+
+    val random = Random(seed)
+    for (i in 0 until updateCount) {
+      val size = random.nextInt(1000) + 1 // size must be >= 1.
+      val byteArray = ByteArray(size).also { random.nextBytes(it) }
+      val offset = random.nextInt(size)
+      val byteCount = random.nextInt(size - offset)
+
+      hashFunction.update(
+        input = byteArray,
+        offset = offset,
+        byteCount = byteCount
+      )
+
+      data.write(
+        source = byteArray,
+        offset = offset,
+        byteCount = byteCount
+      )
+    }
+
+    val okioHash = hashFunction.digest()
+
+    val byteArray = data.readByteArray()
+    val jdkMessageDigest = MessageDigest.getInstance(algorithm)
+    val jdkHash = jdkMessageDigest.digest(byteArray)
+
+    assertThat(okioHash.toByteString()).isEqualTo(jdkHash.toByteString())
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/NioTest.java b/okio/src/jvmTest/java/okio/NioTest.java
new file mode 100644
index 0000000..aec1773
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/NioTest.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2018 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 okio;
+
+import java.io.File;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.WritableByteChannel;
+import java.nio.file.StandardOpenOption;
+import kotlin.text.Charsets;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertFalse;
+import static junit.framework.TestCase.assertTrue;
+
+/** Test interop between our beloved Okio and java.nio. */
+public final class NioTest {
+  @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Test public void sourceIsOpen() throws Exception {
+    BufferedSource source = Okio.buffer((Source) new Buffer());
+    assertTrue(source.isOpen());
+    source.close();
+    assertFalse(source.isOpen());
+  }
+
+  @Test public void sinkIsOpen() throws Exception {
+    BufferedSink sink = Okio.buffer((Sink) new Buffer());
+    assertTrue(sink.isOpen());
+    sink.close();
+    assertFalse(sink.isOpen());
+  }
+
+  @Test public void writableChannelNioFile() throws Exception {
+    File file = temporaryFolder.newFile();
+    FileChannel fileChannel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE);
+    testWritableByteChannel(fileChannel);
+
+    BufferedSource emitted = Okio.buffer(Okio.source(file));
+    assertEquals("defghijklmnopqrstuvw", emitted.readUtf8());
+    emitted.close();
+  }
+
+  @Test public void writableChannelBuffer() throws Exception {
+    Buffer buffer = new Buffer();
+    testWritableByteChannel(buffer);
+    assertEquals("defghijklmnopqrstuvw", buffer.readUtf8());
+  }
+
+  @Test public void writableChannelBufferedSink() throws Exception {
+    Buffer buffer = new Buffer();
+    BufferedSink bufferedSink = Okio.buffer((Sink) buffer);
+    testWritableByteChannel(bufferedSink);
+    assertEquals("defghijklmnopqrstuvw", buffer.readUtf8());
+  }
+
+  @Test public void readableChannelNioFile() throws Exception {
+    File file = temporaryFolder.newFile();
+
+    BufferedSink initialData = Okio.buffer(Okio.sink(file));
+    initialData.writeUtf8("abcdefghijklmnopqrstuvwxyz");
+    initialData.close();
+
+    FileChannel fileChannel = FileChannel.open(file.toPath(), StandardOpenOption.READ);
+    testReadableByteChannel(fileChannel);
+  }
+
+  @Test public void readableChannelBuffer() throws Exception {
+    Buffer buffer = new Buffer();
+    buffer.writeUtf8("abcdefghijklmnopqrstuvwxyz");
+
+    testReadableByteChannel(buffer);
+  }
+
+  @Test public void readableChannelBufferedSource() throws Exception {
+    Buffer buffer = new Buffer();
+    BufferedSource bufferedSource = Okio.buffer((Source) buffer);
+    buffer.writeUtf8("abcdefghijklmnopqrstuvwxyz");
+
+    testReadableByteChannel(bufferedSource);
+  }
+
+  /**
+   * Does some basic writes to {@code channel}. We execute this against both Okio's channels and
+   * also a standard implementation from the JDK to confirm that their behavior is consistent.
+   */
+  private void testWritableByteChannel(WritableByteChannel channel) throws Exception {
+    assertTrue(channel.isOpen());
+
+    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
+    byteBuffer.put("abcdefghijklmnopqrstuvwxyz".getBytes(Charsets.UTF_8));
+    byteBuffer.flip();
+    byteBuffer.position(3);
+    byteBuffer.limit(23);
+
+    int byteCount = channel.write(byteBuffer);
+    assertEquals(20, byteCount);
+    assertEquals(23, byteBuffer.position());
+    assertEquals(23, byteBuffer.limit());
+
+    channel.close();
+    assertEquals(channel instanceof Buffer, channel.isOpen()); // Buffer.close() does nothing.
+  }
+
+  /**
+   * Does some basic reads from {@code channel}. We execute this against both Okio's channels and
+   * also a standard implementation from the JDK to confirm that their behavior is consistent.
+   */
+  private void testReadableByteChannel(ReadableByteChannel channel) throws Exception {
+    assertTrue(channel.isOpen());
+
+    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
+    byteBuffer.position(3);
+    byteBuffer.limit(23);
+
+    int byteCount = channel.read(byteBuffer);
+    assertEquals(20, byteCount);
+    assertEquals(23, byteBuffer.position());
+    assertEquals(23, byteBuffer.limit());
+
+    channel.close();
+    assertEquals(channel instanceof Buffer, channel.isOpen()); // Buffer.close() does nothing.
+
+    byteBuffer.flip();
+    byteBuffer.position(3);
+    byte[] data = new byte[byteBuffer.remaining()];
+    byteBuffer.get(data);
+    assertEquals("abcdefghijklmnopqrst", new String(data, Charsets.UTF_8));
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/OkioTest.java b/okio/src/jvmTest/java/okio/OkioTest.java
new file mode 100644
index 0000000..71a4447
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/OkioTest.java
@@ -0,0 +1,169 @@
+/*
+ * 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 okio;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import static kotlin.text.Charsets.UTF_8;
+import static kotlin.text.StringsKt.repeat;
+import static okio.TestUtil.SEGMENT_SIZE;
+import static okio.TestUtil.assertNoEmptySegments;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public final class OkioTest {
+  @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Test public void readWriteFile() throws Exception {
+    File file = temporaryFolder.newFile();
+
+    BufferedSink sink = Okio.buffer(Okio.sink(file));
+    sink.writeUtf8("Hello, java.io file!");
+    sink.close();
+    assertTrue(file.exists());
+    assertEquals(20, file.length());
+
+    BufferedSource source = Okio.buffer(Okio.source(file));
+    assertEquals("Hello, java.io file!", source.readUtf8());
+    source.close();
+  }
+
+  @Test public void appendFile() throws Exception {
+    File file = temporaryFolder.newFile();
+
+    BufferedSink sink = Okio.buffer(Okio.appendingSink(file));
+    sink.writeUtf8("Hello, ");
+    sink.close();
+    assertTrue(file.exists());
+    assertEquals(7, file.length());
+
+    sink = Okio.buffer(Okio.appendingSink(file));
+    sink.writeUtf8("java.io file!");
+    sink.close();
+    assertEquals(20, file.length());
+
+    BufferedSource source = Okio.buffer(Okio.source(file));
+    assertEquals("Hello, java.io file!", source.readUtf8());
+    source.close();
+  }
+
+  @Test public void readWritePath() throws Exception {
+    Path path = temporaryFolder.newFile().toPath();
+
+    BufferedSink sink = Okio.buffer(Okio.sink(path));
+    sink.writeUtf8("Hello, java.nio file!");
+    sink.close();
+    assertTrue(Files.exists(path));
+    assertEquals(21, Files.size(path));
+
+    BufferedSource source = Okio.buffer(Okio.source(path));
+    assertEquals("Hello, java.nio file!", source.readUtf8());
+    source.close();
+  }
+
+  @Test public void sinkFromOutputStream() throws Exception {
+    Buffer data = new Buffer();
+    data.writeUtf8("a");
+    data.writeUtf8(repeat("b", 9998));
+    data.writeUtf8("c");
+
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+    Sink sink = Okio.sink(out);
+    sink.write(data, 3);
+    assertEquals("abb", out.toString("UTF-8"));
+    sink.write(data, data.size());
+    assertEquals("a" + repeat("b", 9998) + "c", out.toString("UTF-8"));
+  }
+
+  @Test public void sourceFromInputStream() throws Exception {
+    InputStream in = new ByteArrayInputStream(
+        ("a" + repeat("b", SEGMENT_SIZE * 2) + "c").getBytes(UTF_8));
+
+    // Source: ab...bc
+    Source source = Okio.source(in);
+    Buffer sink = new Buffer();
+
+    // Source: b...bc. Sink: abb.
+    assertEquals(3, source.read(sink, 3));
+    assertEquals("abb", sink.readUtf8(3));
+
+    // Source: b...bc. Sink: b...b.
+    assertEquals(SEGMENT_SIZE, source.read(sink, 20000));
+    assertEquals(repeat("b", SEGMENT_SIZE), sink.readUtf8());
+
+    // Source: b...bc. Sink: b...bc.
+    assertEquals(SEGMENT_SIZE - 1, source.read(sink, 20000));
+    assertEquals(repeat("b", SEGMENT_SIZE - 2) + "c", sink.readUtf8());
+
+    // Source and sink are empty.
+    assertEquals(-1, source.read(sink, 1));
+  }
+
+  @Test public void sourceFromInputStreamWithSegmentSize() throws Exception {
+    InputStream in = new ByteArrayInputStream(new byte[SEGMENT_SIZE]);
+    Source source = Okio.source(in);
+    Buffer sink = new Buffer();
+
+    assertEquals(SEGMENT_SIZE, source.read(sink, SEGMENT_SIZE));
+    assertEquals(-1, source.read(sink, SEGMENT_SIZE));
+
+    assertNoEmptySegments(sink);
+  }
+
+  @Test public void sourceFromInputStreamBounds() throws Exception {
+    Source source = Okio.source(new ByteArrayInputStream(new byte[100]));
+    try {
+      source.read(new Buffer(), -1);
+      fail();
+    } catch (IllegalArgumentException expected) {
+    }
+  }
+
+  @Test public void bufferSinkThrowsOnNull() {
+    try {
+      Okio.buffer((Sink) null);
+      fail();
+    } catch (NullPointerException expected) {
+    }
+  }
+
+  @Test public void bufferSourceThrowsOnNull() {
+    try {
+      Okio.buffer((Source) null);
+      fail();
+    } catch (NullPointerException expected) {
+    }
+  }
+
+  @Test public void blackhole() throws Exception {
+    Buffer data = new Buffer();
+    data.writeUtf8("blackhole");
+
+    Sink blackhole = Okio.blackhole();
+    blackhole.write(data, 5);
+
+    assertEquals("hole", data.readUtf8());
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/PipeTest.java b/okio/src/jvmTest/java/okio/PipeTest.java
new file mode 100644
index 0000000..030e6ba
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/PipeTest.java
@@ -0,0 +1,376 @@
+/*
+ * 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 okio;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.util.Random;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import org.junit.After;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public final class PipeTest {
+  final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2);
+
+  @After public void tearDown() throws Exception {
+    executorService.shutdown();
+  }
+
+  @Test public void test() throws Exception {
+    Pipe pipe = new Pipe(6);
+    pipe.sink().write(new Buffer().writeUtf8("abc"), 3L);
+
+    Source source = pipe.source();
+    Buffer readBuffer = new Buffer();
+    assertEquals(3L, source.read(readBuffer, 6L));
+    assertEquals("abc", readBuffer.readUtf8());
+
+    pipe.sink().close();
+    assertEquals(-1L, source.read(readBuffer, 6L));
+
+    source.close();
+  }
+
+  /**
+   * A producer writes the first 16 MiB of bytes generated by {@code new Random(0)} to a sink, and a
+   * consumer consumes them. Both compute hashes of their data to confirm that they're as expected.
+   */
+  @Test public void largeDataset() throws Exception {
+    final Pipe pipe = new Pipe(1000L); // An awkward size to force producer/consumer exchange.
+    final long totalBytes = 16L * 1024L * 1024L;
+    ByteString expectedHash = ByteString.decodeHex("7c3b224bea749086babe079360cf29f98d88262d");
+
+    // Write data to the sink.
+    Future<ByteString> sinkHash = executorService.submit(new Callable<ByteString>() {
+      @Override public ByteString call() throws Exception {
+        HashingSink hashingSink = HashingSink.sha1(pipe.sink());
+        Random random = new Random(0);
+        byte[] data = new byte[8192];
+
+        Buffer buffer = new Buffer();
+        for (long i = 0L; i < totalBytes; i += data.length) {
+          random.nextBytes(data);
+          buffer.write(data);
+          hashingSink.write(buffer, buffer.size());
+        }
+
+        hashingSink.close();
+        return hashingSink.hash();
+      }
+    });
+
+    // Read data from the source.
+    Future<ByteString> sourceHash = executorService.submit(new Callable<ByteString>() {
+      @Override public ByteString call() throws Exception {
+        Buffer blackhole = new Buffer();
+        HashingSink hashingSink = HashingSink.sha1(blackhole);
+
+        Buffer buffer = new Buffer();
+        while (pipe.source().read(buffer, Long.MAX_VALUE) != -1) {
+          hashingSink.write(buffer, buffer.size());
+          blackhole.clear();
+        }
+
+        pipe.source().close();
+        return hashingSink.hash();
+      }
+    });
+
+    assertEquals(expectedHash, sinkHash.get());
+    assertEquals(expectedHash, sourceHash.get());
+  }
+
+  @Test public void sinkTimeout() throws Exception {
+    TestUtil.INSTANCE.assumeNotWindows();
+
+    Pipe pipe = new Pipe(3);
+    pipe.sink().timeout().timeout(1000, TimeUnit.MILLISECONDS);
+    pipe.sink().write(new Buffer().writeUtf8("abc"), 3L);
+    double start = now();
+    try {
+      pipe.sink().write(new Buffer().writeUtf8("def"), 3L);
+      fail();
+    } catch (InterruptedIOException expected) {
+      assertEquals("timeout", expected.getMessage());
+    }
+    assertElapsed(1000.0, start);
+
+    Buffer readBuffer = new Buffer();
+    assertEquals(3L, pipe.source().read(readBuffer, 6L));
+    assertEquals("abc", readBuffer.readUtf8());
+  }
+
+  @Test public void sourceTimeout() throws Exception {
+    TestUtil.INSTANCE.assumeNotWindows();
+
+    Pipe pipe = new Pipe(3L);
+    pipe.source().timeout().timeout(1000, TimeUnit.MILLISECONDS);
+    double start = now();
+    Buffer readBuffer = new Buffer();
+    try {
+      pipe.source().read(readBuffer, 6L);
+      fail();
+    } catch (InterruptedIOException expected) {
+      assertEquals("timeout", expected.getMessage());
+    }
+    assertElapsed(1000.0, start);
+    assertEquals(0, readBuffer.size());
+  }
+
+  /**
+   * The writer is writing 12 bytes as fast as it can to a 3 byte buffer. The reader alternates
+   * sleeping 1000 ms, then reading 3 bytes. That should make for an approximate timeline like
+   * this:
+   *
+   *    0: writer writes 'abc', blocks 0: reader sleeps until 1000
+   * 1000: reader reads 'abc', sleeps until 2000
+   * 1000: writer writes 'def', blocks
+   * 2000: reader reads 'def', sleeps until 3000
+   * 2000: writer writes 'ghi', blocks
+   * 3000: reader reads 'ghi', sleeps until 4000
+   * 3000: writer writes 'jkl', returns
+   * 4000: reader reads 'jkl', returns
+   *
+   * Because the writer is writing to a buffer, it finishes before the reader does.
+   */
+  @Test public void sinkBlocksOnSlowReader() throws Exception {
+    final Pipe pipe = new Pipe(3L);
+    executorService.execute(new Runnable() {
+      @Override public void run() {
+        try {
+          Buffer buffer = new Buffer();
+          Thread.sleep(1000L);
+          assertEquals(3, pipe.source().read(buffer, Long.MAX_VALUE));
+          assertEquals("abc", buffer.readUtf8());
+          Thread.sleep(1000L);
+          assertEquals(3, pipe.source().read(buffer, Long.MAX_VALUE));
+          assertEquals("def", buffer.readUtf8());
+          Thread.sleep(1000L);
+          assertEquals(3, pipe.source().read(buffer, Long.MAX_VALUE));
+          assertEquals("ghi", buffer.readUtf8());
+          Thread.sleep(1000L);
+          assertEquals(3, pipe.source().read(buffer, Long.MAX_VALUE));
+          assertEquals("jkl", buffer.readUtf8());
+        } catch (IOException | InterruptedException e) {
+          throw new AssertionError();
+        }
+      }
+    });
+
+    double start = now();
+    pipe.sink().write(new Buffer().writeUtf8("abcdefghijkl"), 12);
+    assertElapsed(3000.0, start);
+  }
+
+  @Test public void sinkWriteFailsByClosedReader() throws Exception {
+    final Pipe pipe = new Pipe(3L);
+    executorService.schedule(new Runnable() {
+      @Override public void run() {
+        try {
+          pipe.source().close();
+        } catch (IOException e) {
+          throw new AssertionError();
+        }
+      }
+    }, 1000, TimeUnit.MILLISECONDS);
+
+    double start = now();
+    try {
+      pipe.sink().write(new Buffer().writeUtf8("abcdef"), 6);
+      fail();
+    } catch (IOException expected) {
+      assertEquals("source is closed", expected.getMessage());
+      assertElapsed(1000.0, start);
+    }
+  }
+
+  @Test public void sinkFlushDoesntWaitForReader() throws Exception {
+    Pipe pipe = new Pipe(100L);
+    pipe.sink().write(new Buffer().writeUtf8("abc"), 3);
+    pipe.sink().flush();
+
+    BufferedSource bufferedSource = Okio.buffer(pipe.source());
+    assertEquals("abc", bufferedSource.readUtf8(3));
+  }
+
+  @Test public void sinkFlushFailsIfReaderIsClosedBeforeAllDataIsRead() throws Exception {
+    Pipe pipe = new Pipe(100L);
+    pipe.sink().write(new Buffer().writeUtf8("abc"), 3);
+    pipe.source().close();
+    try {
+      pipe.sink().flush();
+      fail();
+    } catch (IOException expected) {
+      assertEquals("source is closed", expected.getMessage());
+    }
+  }
+
+  @Test public void sinkCloseFailsIfReaderIsClosedBeforeAllDataIsRead() throws Exception {
+    Pipe pipe = new Pipe(100L);
+    pipe.sink().write(new Buffer().writeUtf8("abc"), 3);
+    pipe.source().close();
+    try {
+      pipe.sink().close();
+      fail();
+    } catch (IOException expected) {
+      assertEquals("source is closed", expected.getMessage());
+    }
+  }
+
+  @Test public void sinkClose() throws Exception {
+    Pipe pipe = new Pipe(100L);
+    pipe.sink().close();
+    try {
+      pipe.sink().write(new Buffer().writeUtf8("abc"), 3);
+      fail();
+    } catch (IllegalStateException expected) {
+      assertEquals("closed", expected.getMessage());
+    }
+    try {
+      pipe.sink().flush();
+      fail();
+    } catch (IllegalStateException expected) {
+      assertEquals("closed", expected.getMessage());
+    }
+  }
+
+  @Test public void sinkMultipleClose() throws Exception {
+    Pipe pipe = new Pipe(100L);
+    pipe.sink().close();
+    pipe.sink().close();
+  }
+
+  @Test public void sinkCloseDoesntWaitForSourceRead() throws Exception {
+    Pipe pipe = new Pipe(100L);
+    pipe.sink().write(new Buffer().writeUtf8("abc"), 3);
+    pipe.sink().close();
+
+    BufferedSource bufferedSource = Okio.buffer(pipe.source());
+    assertEquals("abc", bufferedSource.readUtf8());
+    assertTrue(bufferedSource.exhausted());
+  }
+
+  @Test public void sourceClose() throws Exception {
+    Pipe pipe = new Pipe(100L);
+    pipe.source().close();
+    try {
+      pipe.source().read(new Buffer(), 3);
+      fail();
+    } catch (IllegalStateException expected) {
+      assertEquals("closed", expected.getMessage());
+    }
+  }
+
+  @Test public void sourceMultipleClose() throws Exception {
+    Pipe pipe = new Pipe(100L);
+    pipe.source().close();
+    pipe.source().close();
+  }
+
+  @Test public void sourceReadUnblockedByClosedSink() throws Exception {
+    final Pipe pipe = new Pipe(3L);
+    executorService.schedule(new Runnable() {
+      @Override public void run() {
+        try {
+          pipe.sink().close();
+        } catch (IOException e) {
+          throw new AssertionError();
+        }
+      }
+    }, 1000, TimeUnit.MILLISECONDS);
+
+    double start = now();
+    Buffer readBuffer = new Buffer();
+    assertEquals(-1, pipe.source().read(readBuffer, Long.MAX_VALUE));
+    assertEquals(0, readBuffer.size());
+    assertElapsed(1000.0, start);
+  }
+
+  /**
+   * The writer has 12 bytes to write. It alternates sleeping 1000 ms, then writing 3 bytes. The
+   * reader is reading as fast as it can. That should make for an approximate timeline like this:
+   *
+   *    0: writer sleeps until 1000
+   *    0: reader blocks
+   * 1000: writer writes 'abc', sleeps until 2000
+   * 1000: reader reads 'abc'
+   * 2000: writer writes 'def', sleeps until 3000
+   * 2000: reader reads 'def'
+   * 3000: writer writes 'ghi', sleeps until 4000
+   * 3000: reader reads 'ghi'
+   * 4000: writer writes 'jkl', returns
+   * 4000: reader reads 'jkl', returns
+   */
+  @Test public void sourceBlocksOnSlowWriter() throws Exception {
+    final Pipe pipe = new Pipe(100L);
+    executorService.execute(new Runnable() {
+      @Override public void run() {
+        try {
+          Thread.sleep(1000L);
+          pipe.sink().write(new Buffer().writeUtf8("abc"), 3);
+          Thread.sleep(1000L);
+          pipe.sink().write(new Buffer().writeUtf8("def"), 3);
+          Thread.sleep(1000L);
+          pipe.sink().write(new Buffer().writeUtf8("ghi"), 3);
+          Thread.sleep(1000L);
+          pipe.sink().write(new Buffer().writeUtf8("jkl"), 3);
+        } catch (IOException | InterruptedException e) {
+          throw new AssertionError();
+        }
+      }
+    });
+
+    double start = now();
+    Buffer readBuffer = new Buffer();
+
+    assertEquals(3, pipe.source().read(readBuffer, Long.MAX_VALUE));
+    assertEquals("abc", readBuffer.readUtf8());
+    assertElapsed(1000.0, start);
+
+    assertEquals(3, pipe.source().read(readBuffer, Long.MAX_VALUE));
+    assertEquals("def", readBuffer.readUtf8());
+    assertElapsed(2000.0, start);
+
+    assertEquals(3, pipe.source().read(readBuffer, Long.MAX_VALUE));
+    assertEquals("ghi", readBuffer.readUtf8());
+    assertElapsed(3000.0, start);
+
+    assertEquals(3, pipe.source().read(readBuffer, Long.MAX_VALUE));
+    assertEquals("jkl", readBuffer.readUtf8());
+    assertElapsed(4000.0, start);
+  }
+
+  /** Returns the nanotime in milliseconds as a double for measuring timeouts. */
+  private double now() {
+    return System.nanoTime() / 1000000.0d;
+  }
+
+  /**
+   * Fails the test unless the time from start until now is duration, accepting differences in
+   * -50..+450 milliseconds.
+   */
+  private void assertElapsed(double duration, double start) {
+    assertEquals(duration, now() - start - 200d, 250.0);
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/ReadUtf8LineTest.java b/okio/src/jvmTest/java/okio/ReadUtf8LineTest.java
new file mode 100644
index 0000000..9cc177f
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/ReadUtf8LineTest.java
@@ -0,0 +1,212 @@
+/*
+ * 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 okio;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import static kotlin.text.StringsKt.repeat;
+import static okio.TestUtil.SEGMENT_SIZE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+@RunWith(Parameterized.class)
+public final class ReadUtf8LineTest {
+  private interface Factory {
+    BufferedSource create(Buffer data);
+  }
+
+  @Parameterized.Parameters(name = "{0}")
+  public static List<Object[]> parameters() {
+    return Arrays.asList(
+        new Object[] { new Factory() {
+          @Override public BufferedSource create(Buffer data) {
+            return data;
+          }
+
+          @Override public String toString() {
+            return "Buffer";
+          }
+        }},
+        new Object[] { new Factory() {
+          @Override public BufferedSource create(Buffer data) {
+            return new RealBufferedSource(data);
+          }
+
+          @Override public String toString() {
+            return "RealBufferedSource";
+          }
+        }},
+        new Object[] { new Factory() {
+          @Override public BufferedSource create(Buffer data) {
+            return new RealBufferedSource(new ForwardingSource(data) {
+              @Override public long read(Buffer sink, long byteCount) throws IOException {
+                return super.read(sink, Math.min(1, byteCount));
+              }
+            });
+          }
+
+          @Override public String toString() {
+            return "Slow RealBufferedSource";
+          }
+        }}
+    );
+  }
+
+  @Parameterized.Parameter
+  public Factory factory;
+
+  private Buffer data;
+  private BufferedSource source;
+
+  @Before public void setUp() {
+    data = new Buffer();
+    source = factory.create(data);
+  }
+
+  @Test public void readLines() throws IOException {
+    data.writeUtf8("abc\ndef\n");
+    assertEquals("abc", source.readUtf8LineStrict());
+    assertEquals("def", source.readUtf8LineStrict());
+    try {
+      source.readUtf8LineStrict();
+      fail();
+    } catch (EOFException expected) {
+      assertEquals("\\n not found: limit=0 content=…", expected.getMessage());
+    }
+  }
+
+  @Test public void readUtf8LineStrictWithLimits() throws IOException {
+    int[] lens = {1, SEGMENT_SIZE - 2, SEGMENT_SIZE - 1, SEGMENT_SIZE, SEGMENT_SIZE * 10};
+    for (int len : lens) {
+      data.writeUtf8(repeat("a", len)).writeUtf8("\n");
+      assertEquals(len, source.readUtf8LineStrict(len).length());
+      source.readUtf8();
+
+      data.writeUtf8(repeat("a", len)).writeUtf8("\n").writeUtf8(repeat("a", len));
+      assertEquals(len, source.readUtf8LineStrict(len).length());
+      source.readUtf8();
+
+      data.writeUtf8(repeat("a", len)).writeUtf8("\r\n");
+      assertEquals(len, source.readUtf8LineStrict(len).length());
+      source.readUtf8();
+
+      data.writeUtf8(repeat("a", len)).writeUtf8("\r\n").writeUtf8(repeat("a", len));
+      assertEquals(len, source.readUtf8LineStrict(len).length());
+      source.readUtf8();
+    }
+  }
+
+  @Test public void readUtf8LineStrictNoBytesConsumedOnFailure() throws IOException {
+    data.writeUtf8("abc\n");
+    try {
+      source.readUtf8LineStrict(2);
+      fail();
+    } catch (EOFException expected) {
+      assertTrue(expected.getMessage().startsWith("\\n not found: limit=2 content=61626"));
+    }
+    assertEquals("abc", source.readUtf8LineStrict(3));
+  }
+
+  @Test public void readUtf8LineStrictEmptyString() throws IOException {
+    data.writeUtf8("\r\nabc");
+    assertEquals("", source.readUtf8LineStrict(0));
+    assertEquals("abc", source.readUtf8());
+  }
+
+  @Test public void readUtf8LineStrictNonPositive() throws IOException {
+    data.writeUtf8("\r\n");
+    try {
+      source.readUtf8LineStrict(-1);
+      fail("Expected failure: limit must be greater than 0");
+    } catch (IllegalArgumentException expected) {
+    }
+  }
+
+  @Test public void eofExceptionProvidesLimitedContent() throws IOException {
+    data.writeUtf8("aaaaaaaabbbbbbbbccccccccdddddddde");
+    try {
+      source.readUtf8LineStrict();
+      fail();
+    } catch (EOFException expected) {
+      assertEquals("\\n not found: limit=33 content=616161616161616162626262626262626363636363636363"
+          + "6464646464646464…", expected.getMessage());
+    }
+  }
+
+  @Test public void newlineAtEnd() throws IOException {
+    data.writeUtf8("abc\n");
+    assertEquals("abc", source.readUtf8LineStrict(3));
+    assertTrue(source.exhausted());
+
+    data.writeUtf8("abc\r\n");
+    assertEquals("abc", source.readUtf8LineStrict(3));
+    assertTrue(source.exhausted());
+
+    data.writeUtf8("abc\r");
+    try {
+      source.readUtf8LineStrict(3);
+      fail();
+    } catch (EOFException expected) {
+      assertEquals("\\n not found: limit=3 content=6162630d…", expected.getMessage());
+    }
+    source.readUtf8();
+
+    data.writeUtf8("abc");
+    try {
+      source.readUtf8LineStrict(3);
+      fail();
+    } catch (EOFException expected) {
+      assertEquals("\\n not found: limit=3 content=616263…", expected.getMessage());
+    }
+  }
+
+  @Test public void emptyLines() throws IOException {
+    data.writeUtf8("\n\n\n");
+    assertEquals("", source.readUtf8LineStrict());
+    assertEquals("", source.readUtf8LineStrict());
+    assertEquals("", source.readUtf8LineStrict());
+    assertTrue(source.exhausted());
+  }
+
+  @Test public void crDroppedPrecedingLf() throws IOException {
+    data.writeUtf8("abc\r\ndef\r\nghi\rjkl\r\n");
+    assertEquals("abc", source.readUtf8LineStrict());
+    assertEquals("def", source.readUtf8LineStrict());
+    assertEquals("ghi\rjkl", source.readUtf8LineStrict());
+  }
+
+  @Test public void bufferedReaderCompatible() throws IOException {
+    data.writeUtf8("abc\ndef");
+    assertEquals("abc", source.readUtf8Line());
+    assertEquals("def", source.readUtf8Line());
+    assertEquals(null, source.readUtf8Line());
+  }
+
+  @Test public void bufferedReaderCompatibleWithTrailingNewline() throws IOException {
+    data.writeUtf8("abc\ndef\n");
+    assertEquals("abc", source.readUtf8Line());
+    assertEquals("def", source.readUtf8Line());
+    assertEquals(null, source.readUtf8Line());
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/SocketTimeoutTest.java b/okio/src/jvmTest/java/okio/SocketTimeoutTest.java
new file mode 100644
index 0000000..6a6aadc
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/SocketTimeoutTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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 okio;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.util.concurrent.TimeUnit;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public final class SocketTimeoutTest {
+
+  // The size of the socket buffers to use. Less than half the data transferred during tests to
+  // ensure send and receive buffers are flooded and any necessary blocking behavior takes place.
+  private static final int SOCKET_BUFFER_SIZE = 256 * 1024;
+  private static final int ONE_MB = 1024 * 1024;
+
+  @Test public void readWithoutTimeout() throws Exception {
+    Socket socket = socket(ONE_MB, 0);
+    BufferedSource source = Okio.buffer(Okio.source(socket));
+    source.timeout().timeout(5000, TimeUnit.MILLISECONDS);
+    source.require(ONE_MB);
+    socket.close();
+  }
+
+  @Test public void readWithTimeout() throws Exception {
+    Socket socket = socket(0, 0);
+    BufferedSource source = Okio.buffer(Okio.source(socket));
+    source.timeout().timeout(250, TimeUnit.MILLISECONDS);
+    try {
+      source.require(ONE_MB);
+      fail();
+    } catch (SocketTimeoutException expected) {
+    }
+    socket.close();
+  }
+
+  @Test public void writeWithoutTimeout() throws Exception {
+    Socket socket = socket(0, ONE_MB);
+    Sink sink = Okio.buffer(Okio.sink(socket));
+    sink.timeout().timeout(500, TimeUnit.MILLISECONDS);
+    byte[] data = new byte[ONE_MB];
+    sink.write(new Buffer().write(data), data.length);
+    sink.flush();
+    socket.close();
+  }
+
+  @Test public void writeWithTimeout() throws Exception {
+    Socket socket = socket(0, 0);
+    Sink sink = Okio.sink(socket);
+    sink.timeout().timeout(500, TimeUnit.MILLISECONDS);
+    byte[] data = new byte[ONE_MB];
+    long start = System.nanoTime();
+    try {
+      sink.write(new Buffer().write(data), data.length);
+      sink.flush();
+      fail();
+    } catch (SocketTimeoutException expected) {
+    }
+    long elapsed = System.nanoTime() - start;
+    socket.close();
+
+    assertTrue("elapsed: " + elapsed, TimeUnit.NANOSECONDS.toMillis(elapsed) >= 500);
+    assertTrue("elapsed: " + elapsed, TimeUnit.NANOSECONDS.toMillis(elapsed) <= 750);
+  }
+
+  /**
+   * Returns a socket that can read {@code readableByteCount} incoming bytes and
+   * will accept {@code writableByteCount} written bytes. The socket will idle
+   * for 5 seconds when the required data has been read and written.
+   */
+  static Socket socket(final int readableByteCount, final int writableByteCount) throws IOException {
+    final ServerSocket serverSocket = new ServerSocket(0);
+    serverSocket.setReuseAddress(true);
+    serverSocket.setReceiveBufferSize(SOCKET_BUFFER_SIZE);
+
+    Thread peer = new Thread("peer") {
+      @Override public void run() {
+        Socket socket = null;
+        try {
+          socket = serverSocket.accept();
+          socket.setSendBufferSize(SOCKET_BUFFER_SIZE);
+          writeFully(socket.getOutputStream(), readableByteCount);
+          readFully(socket.getInputStream(), writableByteCount);
+          Thread.sleep(5000); // Sleep 5 seconds so the peer can close the connection.
+        } catch (Exception ignored) {
+        } finally {
+          try {
+            if (socket != null) socket.close();
+          } catch (IOException ignored) {
+          }
+        }
+      }
+    };
+    peer.start();
+
+    Socket socket = new Socket(serverSocket.getInetAddress(), serverSocket.getLocalPort());
+    socket.setReceiveBufferSize(SOCKET_BUFFER_SIZE);
+    socket.setSendBufferSize(SOCKET_BUFFER_SIZE);
+    return socket;
+  }
+
+  private static void writeFully(OutputStream out, int byteCount) throws IOException {
+    out.write(new byte[byteCount]);
+    out.flush();
+  }
+
+  private static byte[] readFully(InputStream in, int byteCount) throws IOException {
+    int count = 0;
+    byte[] result = new byte[byteCount];
+    while (count < byteCount) {
+      int read = in.read(result, count, result.length - count);
+      if (read == -1) throw new EOFException();
+      count += read;
+    }
+    return result;
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/Utf8Test.java b/okio/src/jvmTest/java/okio/Utf8Test.java
new file mode 100644
index 0000000..63e0b7d
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/Utf8Test.java
@@ -0,0 +1,282 @@
+/*
+ * 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 okio;
+
+import java.io.EOFException;
+import kotlin.text.Charsets;
+import org.junit.Test;
+
+import static kotlin.text.StringsKt.repeat;
+import static okio.TestUtil.REPLACEMENT_CODE_POINT;
+import static okio.TestUtil.SEGMENT_SIZE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public final class Utf8Test {
+  @Test public void oneByteCharacters() throws Exception {
+    assertEncoded("00", 0x00); // Smallest 1-byte character.
+    assertEncoded("20", ' ');
+    assertEncoded("7e", '~');
+    assertEncoded("7f", 0x7f); // Largest 1-byte character.
+  }
+
+  @Test public void twoByteCharacters() throws Exception {
+    assertEncoded("c280", 0x0080); // Smallest 2-byte character.
+    assertEncoded("c3bf", 0x00ff);
+    assertEncoded("c480", 0x0100);
+    assertEncoded("dfbf", 0x07ff); // Largest 2-byte character.
+  }
+
+  @Test public void threeByteCharacters() throws Exception {
+    assertEncoded("e0a080", 0x0800); // Smallest 3-byte character.
+    assertEncoded("e0bfbf", 0x0fff);
+    assertEncoded("e18080", 0x1000);
+    assertEncoded("e1bfbf", 0x1fff);
+    assertEncoded("ed8080", 0xd000);
+    assertEncoded("ed9fbf", 0xd7ff); // Largest character lower than the min surrogate.
+    assertEncoded("ee8080", 0xe000); // Smallest character greater than the max surrogate.
+    assertEncoded("eebfbf", 0xefff);
+    assertEncoded("ef8080", 0xf000);
+    assertEncoded("efbfbf", 0xffff); // Largest 3-byte character.
+  }
+
+  @Test public void fourByteCharacters() throws Exception {
+    assertEncoded("f0908080", 0x010000); // Smallest surrogate pair.
+    assertEncoded("f48fbfbf", 0x10ffff); // Largest code point expressible by UTF-16.
+  }
+
+  @Test public void danglingHighSurrogate() throws Exception {
+    assertStringEncoded("3f", "\ud800"); // "?"
+  }
+
+  @Test public void lowSurrogateWithoutHighSurrogate() throws Exception {
+    assertStringEncoded("3f", "\udc00"); // "?"
+  }
+
+  @Test public void highSurrogateFollowedByNonSurrogate() throws Exception {
+    assertStringEncoded("3f61", "\ud800\u0061"); // "?a": Following character is too low.
+    assertStringEncoded("3fee8080", "\ud800\ue000"); // "?\ue000": Following character is too high.
+  }
+
+  @Test public void doubleLowSurrogate() throws Exception {
+    assertStringEncoded("3f3f", "\udc00\udc00"); // "??"
+  }
+
+  @Test public void doubleHighSurrogate() throws Exception {
+    assertStringEncoded("3f3f", "\ud800\ud800"); // "??"
+  }
+
+  @Test public void highSurrogateLowSurrogate() throws Exception {
+    assertStringEncoded("3f3f", "\udc00\ud800"); // "??"
+  }
+
+  @Test public void multipleSegmentString() throws Exception {
+    String a = repeat("a", SEGMENT_SIZE + SEGMENT_SIZE + 1);
+    Buffer encoded = new Buffer().writeUtf8(a);
+    Buffer expected = new Buffer().write(a.getBytes(Charsets.UTF_8));
+    assertEquals(expected, encoded);
+  }
+
+  @Test public void stringSpansSegments() throws Exception {
+    Buffer buffer = new Buffer();
+    String a = repeat("a", SEGMENT_SIZE - 1);
+    String b = "bb";
+    String c = repeat("c", SEGMENT_SIZE - 1);
+    buffer.writeUtf8(a);
+    buffer.writeUtf8(b);
+    buffer.writeUtf8(c);
+    assertEquals(a + b + c, buffer.readUtf8());
+  }
+
+  @Test public void readEmptyBufferThrowsEofException() throws Exception {
+    Buffer buffer = new Buffer();
+    try {
+      buffer.readUtf8CodePoint();
+      fail();
+    } catch (EOFException expected) {
+    }
+  }
+
+  @Test public void readLeadingContinuationByteReturnsReplacementCharacter() throws Exception {
+    Buffer buffer = new Buffer();
+    buffer.writeByte(0xbf);
+    assertEquals(REPLACEMENT_CODE_POINT, buffer.readUtf8CodePoint());
+    assertTrue(buffer.exhausted());
+  }
+
+  @Test public void readMissingContinuationBytesThrowsEofException() throws Exception {
+    Buffer buffer = new Buffer();
+    buffer.writeByte(0xdf);
+    try {
+      buffer.readUtf8CodePoint();
+      fail();
+    } catch (EOFException expected) {
+    }
+    assertFalse(buffer.exhausted()); // Prefix byte wasn't consumed.
+  }
+
+  @Test public void readTooLargeCodepointReturnsReplacementCharacter() throws Exception {
+    // 5-byte and 6-byte code points are not supported.
+    Buffer buffer = new Buffer();
+    buffer.write(ByteString.decodeHex("f888808080"));
+    assertEquals(REPLACEMENT_CODE_POINT, buffer.readUtf8CodePoint());
+    assertEquals(REPLACEMENT_CODE_POINT, buffer.readUtf8CodePoint());
+    assertEquals(REPLACEMENT_CODE_POINT, buffer.readUtf8CodePoint());
+    assertEquals(REPLACEMENT_CODE_POINT, buffer.readUtf8CodePoint());
+    assertEquals(REPLACEMENT_CODE_POINT, buffer.readUtf8CodePoint());
+    assertTrue(buffer.exhausted());
+  }
+
+  @Test public void readNonContinuationBytesReturnsReplacementCharacter() throws Exception {
+    // Use a non-continuation byte where a continuation byte is expected.
+    Buffer buffer = new Buffer();
+    buffer.write(ByteString.decodeHex("df20"));
+    assertEquals(REPLACEMENT_CODE_POINT, buffer.readUtf8CodePoint());
+    assertEquals(0x20, buffer.readUtf8CodePoint()); // Non-continuation character not consumed.
+    assertTrue(buffer.exhausted());
+  }
+
+  @Test public void readCodePointBeyondUnicodeMaximum() throws Exception {
+    // A 4-byte encoding with data above the U+10ffff Unicode maximum.
+    Buffer buffer = new Buffer();
+    buffer.write(ByteString.decodeHex("f4908080"));
+    assertEquals(REPLACEMENT_CODE_POINT, buffer.readUtf8CodePoint());
+    assertTrue(buffer.exhausted());
+  }
+
+  @Test public void readSurrogateCodePoint() throws Exception {
+    Buffer buffer = new Buffer();
+    buffer.write(ByteString.decodeHex("eda080"));
+    assertEquals(REPLACEMENT_CODE_POINT, buffer.readUtf8CodePoint());
+    assertTrue(buffer.exhausted());
+    buffer.write(ByteString.decodeHex("edbfbf"));
+    assertEquals(REPLACEMENT_CODE_POINT, buffer.readUtf8CodePoint());
+    assertTrue(buffer.exhausted());
+  }
+
+  @Test public void readOverlongCodePoint() throws Exception {
+    // Use 2 bytes to encode data that only needs 1 byte.
+    Buffer buffer = new Buffer();
+    buffer.write(ByteString.decodeHex("c080"));
+    assertEquals(REPLACEMENT_CODE_POINT, buffer.readUtf8CodePoint());
+    assertTrue(buffer.exhausted());
+  }
+
+  @Test public void writeSurrogateCodePoint() throws Exception {
+    assertStringEncoded("ed9fbf", "\ud7ff"); // Below lowest surrogate is okay.
+    assertStringEncoded("3f", "\ud800"); // Lowest surrogate gets '?'.
+    assertStringEncoded("3f", "\udfff"); // Highest surrogate gets '?'.
+    assertStringEncoded("ee8080", "\ue000"); // Above highest surrogate is okay.
+  }
+
+  @Test public void writeCodePointBeyondUnicodeMaximum() throws Exception {
+    Buffer buffer = new Buffer();
+    try {
+      buffer.writeUtf8CodePoint(0x110000);
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertEquals("Unexpected code point: 0x110000", expected.getMessage());
+    }
+  }
+
+  @Test public void size() throws Exception {
+    assertEquals(0, Utf8.size(""));
+    assertEquals(3, Utf8.size("abc"));
+    assertEquals(16, Utf8.size("təˈranəˌsôr"));
+  }
+
+  @Test public void sizeWithBounds() throws Exception {
+    assertEquals(0, Utf8.size("", 0, 0));
+    assertEquals(0, Utf8.size("abc", 0, 0));
+    assertEquals(1, Utf8.size("abc", 1, 2));
+    assertEquals(2, Utf8.size("abc", 0, 2));
+    assertEquals(3, Utf8.size("abc", 0, 3));
+    assertEquals(16, Utf8.size("təˈranəˌsôr", 0, 11));
+    assertEquals(5, Utf8.size("təˈranəˌsôr", 3, 7));
+  }
+
+  @Test public void sizeBoundsCheck() throws Exception {
+    try {
+      Utf8.size(null, 0, 0);
+      fail();
+    } catch (NullPointerException expected) {
+    }
+    try {
+      Utf8.size("abc", -1, 2);
+      fail();
+    } catch (IllegalArgumentException expected) {
+    }
+    try {
+      Utf8.size("abc", 2, 1);
+      fail();
+    } catch (IllegalArgumentException expected) {
+    }
+    try {
+      Utf8.size("abc", 1, 4);
+      fail();
+    } catch (IllegalArgumentException expected) {
+    }
+  }
+
+  private void assertEncoded(String hex, int... codePoints) throws Exception {
+    assertCodePointEncoded(hex, codePoints);
+    assertCodePointDecoded(hex, codePoints);
+    assertStringEncoded(hex, new String(codePoints, 0, codePoints.length));
+  }
+
+  private void assertCodePointEncoded(String hex, int... codePoints) throws Exception {
+    Buffer buffer = new Buffer();
+    for (int codePoint : codePoints) {
+      buffer.writeUtf8CodePoint(codePoint);
+    }
+    assertEquals(buffer.readByteString(), ByteString.decodeHex(hex));
+  }
+
+  private void assertCodePointDecoded(String hex, int... codePoints) throws Exception {
+    Buffer buffer = new Buffer().write(ByteString.decodeHex(hex));
+    for (int codePoint : codePoints) {
+      assertEquals(codePoint, buffer.readUtf8CodePoint());
+    }
+    assertTrue(buffer.exhausted());
+  }
+
+  private void assertStringEncoded(String hex, String string) throws Exception {
+    ByteString expectedUtf8 = ByteString.decodeHex(hex);
+
+    // Confirm our expectations are consistent with the platform.
+    ByteString platformUtf8 = ByteString.of(string.getBytes("UTF-8"));
+    assertEquals(expectedUtf8, platformUtf8);
+
+    // Confirm our implementation matches those expectations.
+    ByteString actualUtf8 = new Buffer().writeUtf8(string).readByteString();
+    assertEquals(expectedUtf8, actualUtf8);
+
+    // Confirm we are consistent when writing one code point at a time.
+    Buffer bufferUtf8 = new Buffer();
+    for (int i = 0; i < string.length(); ) {
+      int c = string.codePointAt(i);
+      bufferUtf8.writeUtf8CodePoint(c);
+      i += Character.charCount(c);
+    }
+    assertEquals(expectedUtf8, bufferUtf8.readByteString());
+
+    // Confirm we are consistent when measuring lengths.
+    assertEquals(expectedUtf8.size(), Utf8.size(string));
+    assertEquals(expectedUtf8.size(), Utf8.size(string, 0, string.length()));
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/WaitUntilNotifiedTest.java b/okio/src/jvmTest/java/okio/WaitUntilNotifiedTest.java
new file mode 100644
index 0000000..e440528
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/WaitUntilNotifiedTest.java
@@ -0,0 +1,172 @@
+/*
+ * 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 okio;
+
+import java.io.InterruptedIOException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import org.junit.After;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public final class WaitUntilNotifiedTest {
+  final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(0);
+
+  @After public void tearDown() {
+    executorService.shutdown();
+  }
+
+  @Test public synchronized void notified() throws InterruptedIOException {
+    Timeout timeout = new Timeout();
+    timeout.timeout(5000, TimeUnit.MILLISECONDS);
+
+    double start = now();
+    executorService.schedule(new Runnable() {
+      @Override public void run() {
+        synchronized (WaitUntilNotifiedTest.this) {
+          WaitUntilNotifiedTest.this.notify();
+        }
+      }
+    }, 1000, TimeUnit.MILLISECONDS);
+
+    timeout.waitUntilNotified(this);
+    assertElapsed(1000.0, start);
+  }
+
+  @Test public synchronized void timeout() {
+    TestUtil.INSTANCE.assumeNotWindows();
+
+    Timeout timeout = new Timeout();
+    timeout.timeout(1000, TimeUnit.MILLISECONDS);
+    double start = now();
+    try {
+      timeout.waitUntilNotified(this);
+      fail();
+    } catch (InterruptedIOException expected) {
+      assertEquals("timeout", expected.getMessage());
+    }
+    assertElapsed(1000.0, start);
+  }
+
+  @Test public synchronized void deadline() {
+    TestUtil.INSTANCE.assumeNotWindows();
+
+    Timeout timeout = new Timeout();
+    timeout.deadline(1000, TimeUnit.MILLISECONDS);
+    double start = now();
+    try {
+      timeout.waitUntilNotified(this);
+      fail();
+    } catch (InterruptedIOException expected) {
+      assertEquals("timeout", expected.getMessage());
+    }
+    assertElapsed(1000.0, start);
+  }
+
+  @Test public synchronized void deadlineBeforeTimeout() {
+    TestUtil.INSTANCE.assumeNotWindows();
+
+    Timeout timeout = new Timeout();
+    timeout.timeout(5000, TimeUnit.MILLISECONDS);
+    timeout.deadline(1000, TimeUnit.MILLISECONDS);
+    double start = now();
+    try {
+      timeout.waitUntilNotified(this);
+      fail();
+    } catch (InterruptedIOException expected) {
+      assertEquals("timeout", expected.getMessage());
+    }
+    assertElapsed(1000.0, start);
+  }
+
+  @Test public synchronized void timeoutBeforeDeadline() {
+    TestUtil.INSTANCE.assumeNotWindows();
+
+    Timeout timeout = new Timeout();
+    timeout.timeout(1000, TimeUnit.MILLISECONDS);
+    timeout.deadline(5000, TimeUnit.MILLISECONDS);
+    double start = now();
+    try {
+      timeout.waitUntilNotified(this);
+      fail();
+    } catch (InterruptedIOException expected) {
+      assertEquals("timeout", expected.getMessage());
+    }
+    assertElapsed(1000.0, start);
+  }
+
+  @Test public synchronized void deadlineAlreadyReached() {
+    TestUtil.INSTANCE.assumeNotWindows();
+
+    Timeout timeout = new Timeout();
+    timeout.deadlineNanoTime(System.nanoTime());
+    double start = now();
+    try {
+      timeout.waitUntilNotified(this);
+      fail();
+    } catch (InterruptedIOException expected) {
+      assertEquals("timeout", expected.getMessage());
+    }
+    assertElapsed(0.0, start);
+  }
+
+  @Test public synchronized void threadInterrupted() {
+    TestUtil.INSTANCE.assumeNotWindows();
+
+    Timeout timeout = new Timeout();
+    double start = now();
+    Thread.currentThread().interrupt();
+    try {
+      timeout.waitUntilNotified(this);
+      fail();
+    } catch (InterruptedIOException expected) {
+      assertEquals("interrupted", expected.getMessage());
+      assertTrue(Thread.interrupted());
+    }
+    assertElapsed(0.0, start);
+  }
+
+  @Test public synchronized void threadInterruptedOnThrowIfReached() throws Exception {
+    TestUtil.INSTANCE.assumeNotWindows();
+
+    Timeout timeout = new Timeout();
+    Thread.currentThread().interrupt();
+    try {
+      timeout.throwIfReached();
+      fail();
+    } catch (InterruptedIOException expected) {
+      assertEquals("interrupted", expected.getMessage());
+      assertTrue(Thread.interrupted());
+    }
+  }
+
+  /** Returns the nanotime in milliseconds as a double for measuring timeouts. */
+  private double now() {
+    return System.nanoTime() / 1000000.0d;
+  }
+
+  /**
+   * Fails the test unless the time from start until now is duration, accepting differences in
+   * -50..+450 milliseconds.
+   */
+  private void assertElapsed(double duration, double start) {
+    assertEquals(duration, now() - start - 200d, 250.0);
+  }
+}
diff --git a/okio/src/jvmTest/java/okio/internal/HmacTest.kt b/okio/src/jvmTest/java/okio/internal/HmacTest.kt
new file mode 100644
index 0000000..0c5a7f4
--- /dev/null
+++ b/okio/src/jvmTest/java/okio/internal/HmacTest.kt
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2020 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 okio.internal
+
+import okio.ByteString
+import org.junit.Assert.assertArrayEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import javax.crypto.Mac
+import javax.crypto.spec.SecretKeySpec
+import kotlin.random.Random
+
+/**
+ * Check the [Hmac] implementation against the reference [Mac] JVM implementation.
+ */
+@RunWith(Parameterized::class)
+class HmacTest(val parameters: Parameters) {
+
+  companion object {
+    @get:Parameterized.Parameters(name = "{0}")
+    @get:JvmStatic
+    val parameters: List<Parameters>
+      get() {
+        val algorithms = enumValues<Parameters.Algorithm>()
+        val keySizes = listOf(8, 32, 48, 64, 128, 256)
+        val dataSizes = listOf(0, 32, 64, 128, 256, 512)
+        return algorithms.flatMap { algorithm ->
+          keySizes.flatMap { keySize ->
+            dataSizes.map { dataSize ->
+              Parameters(
+                algorithm,
+                keySize,
+                dataSize
+              )
+            }
+          }
+        }
+      }
+  }
+
+  private val keySize
+    get() = parameters.keySize
+  private val dataSize
+    get() = parameters.dataSize
+  private val algorithm
+    get() = parameters.algorithmName
+
+  private val random = Random(682741861446)
+
+  private val key = random.nextBytes(keySize)
+  private val bytes = random.nextBytes(dataSize)
+  private val mac = parameters.createMac(key)
+
+  private val expected = hmac(algorithm, key, bytes)
+
+  @Test
+  fun hmac() {
+    mac.update(bytes)
+    val hmacValue = mac.digest()
+
+    assertArrayEquals(expected, hmacValue)
+  }
+
+  @Test
+  fun hmacBytes() {
+    for (byte in bytes) {
+      mac.update(byteArrayOf(byte))
+    }
+    val hmacValue = mac.digest()
+
+    assertArrayEquals(expected, hmacValue)
+  }
+
+  data class Parameters(
+    val algorithm: Algorithm,
+    val keySize: Int,
+    val dataSize: Int
+  ) {
+    val algorithmName
+      get() = algorithm.algorithmName
+
+    internal fun createMac(key: ByteArray) =
+      algorithm.HmacFactory(ByteString(key))
+
+    enum class Algorithm(
+      val algorithmName: String,
+      internal val HmacFactory: (key: ByteString) -> Hmac
+    ) {
+      SHA_1("HmacSha1", Hmac.Companion::sha1),
+      SHA_256("HmacSha256", Hmac.Companion::sha256),
+      SHA_512("HmacSha512", Hmac.Companion::sha512),
+    }
+  }
+}
+
+private fun hmac(algorithm: String, key: ByteArray, bytes: ByteArray) =
+  Mac.getInstance(algorithm).apply { init(SecretKeySpec(key, algorithm)) }.doFinal(bytes)
diff --git a/okio/src/jvmTest/kotlin/okio/BufferCursorKotlinTest.kt b/okio/src/jvmTest/kotlin/okio/BufferCursorKotlinTest.kt
new file mode 100644
index 0000000..ddbc4c5
--- /dev/null
+++ b/okio/src/jvmTest/kotlin/okio/BufferCursorKotlinTest.kt
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+import okio.Buffer.UnsafeCursor
+import okio.TestUtil.deepCopy
+import org.junit.Assume.assumeTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import org.junit.runners.Parameterized.Parameter
+import org.junit.runners.Parameterized.Parameters
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+import kotlin.test.assertNotSame
+import kotlin.test.assertSame
+import kotlin.test.assertTrue
+
+@RunWith(Parameterized::class)
+class BufferCursorKotlinTest {
+  companion object {
+    @Parameters(name = "{0}")
+    @JvmStatic
+    fun parameters(): List<Array<out Any?>> {
+      return BufferFactory.values().map { arrayOf(it) }
+    }
+  }
+
+  @Parameter lateinit var bufferFactory: BufferFactory
+
+  @Test fun acquireReadOnlyDoesNotCopySharedDataArray() {
+    val buffer = deepCopy(bufferFactory.newBuffer())
+    assumeTrue(buffer.size > 0L)
+
+    val shared = buffer.clone()
+    assertTrue(buffer.head!!.shared)
+
+    buffer.readUnsafe().use { cursor ->
+      cursor.seek(0)
+      assertSame(cursor.data, shared.head!!.data)
+    }
+  }
+
+  @Test fun acquireReadWriteDoesNotCopyUnsharedDataArray() {
+    val buffer = deepCopy(bufferFactory.newBuffer())
+    assumeTrue(buffer.size > 0L)
+    assertFalse(buffer.head!!.shared)
+
+    val originalData = buffer.head!!.data
+
+    buffer.readAndWriteUnsafe().use { cursor ->
+      cursor.seek(0)
+      assertSame(cursor.data, originalData)
+    }
+  }
+
+  @Test fun acquireReadWriteCopiesSharedDataArray() {
+    val buffer = deepCopy(bufferFactory.newBuffer())
+    assumeTrue(buffer.size > 0L)
+
+    val shared = buffer.clone()
+    assertTrue(buffer.head!!.shared)
+
+    buffer.readAndWriteUnsafe().use { cursor ->
+      cursor.seek(0)
+      assertNotSame(cursor.data, shared.head!!.data)
+    }
+  }
+
+  @Test fun writeSharedSegments() {
+    val buffer = bufferFactory.newBuffer()
+
+    // Make a deep copy. This buffer's segments are not shared.
+    val deepCopy = deepCopy(buffer)
+    assertTrue(deepCopy.head == null || !deepCopy.head!!.shared)
+
+    // Make a shallow copy. Both buffers' segments are shared as a side effect.
+    val shallowCopy = buffer.clone()
+    assertTrue(shallowCopy.head == null || shallowCopy.head!!.shared)
+    assertTrue(buffer.head == null || buffer.head!!.shared)
+
+    val expected = Buffer()
+    expected.writeUtf8("x".repeat(buffer.size.toInt()))
+
+    buffer.readAndWriteUnsafe().use { cursor ->
+      while (cursor.next() != -1) {
+        cursor.data!!.fill('x'.toByte(), cursor.start, cursor.end)
+      }
+    }
+
+    // The buffer was fully changed.
+    assertEquals(expected, buffer)
+
+    // The buffer we're shared with is unchanged.
+    assertEquals(deepCopy, shallowCopy)
+  }
+
+  /** As an optimization it's okay to use the same cursor on multiple buffers.  */
+  @Test fun cursorReuse() {
+    val cursor = UnsafeCursor()
+
+    val buffer1 = bufferFactory.newBuffer()
+    buffer1.readUnsafe(cursor)
+    assertSame(buffer1, cursor.buffer)
+    assertFalse(cursor.readWrite)
+    cursor.close()
+    assertSame(null, cursor.buffer)
+
+    val buffer2 = bufferFactory.newBuffer()
+    buffer2.readAndWriteUnsafe(cursor)
+    assertSame(buffer2, cursor.buffer)
+    assertTrue(cursor.readWrite)
+    cursor.close()
+    assertSame(null, cursor.buffer)
+  }
+}
diff --git a/okio/src/jvmTest/kotlin/okio/BufferFactory.kt b/okio/src/jvmTest/kotlin/okio/BufferFactory.kt
new file mode 100644
index 0000000..e1533d2
--- /dev/null
+++ b/okio/src/jvmTest/kotlin/okio/BufferFactory.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+import okio.TestUtil.bufferWithRandomSegmentLayout
+import okio.TestUtil.bufferWithSegments
+import java.util.Random
+
+enum class BufferFactory {
+  EMPTY {
+    override fun newBuffer(): Buffer {
+      return Buffer()
+    }
+  },
+
+  SMALL_BUFFER {
+    override fun newBuffer(): Buffer {
+      return Buffer().writeUtf8("abcde")
+    }
+  },
+
+  SMALL_SEGMENTED_BUFFER {
+    @Throws(Exception::class)
+    override fun newBuffer(): Buffer {
+      return bufferWithSegments("abc", "defg", "hijkl")
+    }
+  },
+
+  LARGE_BUFFER {
+    @Throws(Exception::class)
+    override fun newBuffer(): Buffer {
+      val dice = Random(0)
+      val largeByteArray = ByteArray(512 * 1024)
+      dice.nextBytes(largeByteArray)
+
+      return Buffer().write(largeByteArray)
+    }
+  },
+
+  LARGE_BUFFER_WITH_RANDOM_LAYOUT {
+    @Throws(Exception::class)
+    override fun newBuffer(): Buffer {
+      val dice = Random(0)
+      val largeByteArray = ByteArray(512 * 1024)
+      dice.nextBytes(largeByteArray)
+
+      return bufferWithRandomSegmentLayout(dice, largeByteArray)
+    }
+  };
+
+  @Throws(Exception::class)
+  abstract fun newBuffer(): Buffer
+}
diff --git a/okio/src/jvmTest/kotlin/okio/BufferKotlinTest.kt b/okio/src/jvmTest/kotlin/okio/BufferKotlinTest.kt
new file mode 100644
index 0000000..eda7989
--- /dev/null
+++ b/okio/src/jvmTest/kotlin/okio/BufferKotlinTest.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+import org.assertj.core.api.Assertions.assertThat
+import org.junit.Test
+import kotlin.test.assertFailsWith
+
+class BufferKotlinTest {
+  @Test fun get() {
+    val actual = Buffer().writeUtf8("abc")
+    assertThat(actual[0]).isEqualTo('a'.toByte())
+    assertThat(actual[1]).isEqualTo('b'.toByte())
+    assertThat(actual[2]).isEqualTo('c'.toByte())
+    assertFailsWith<IndexOutOfBoundsException> {
+      actual[-1]
+    }
+    assertFailsWith<IndexOutOfBoundsException> {
+      actual[3]
+    }
+  }
+
+  @Test fun copyToOutputStream() {
+    val source = Buffer()
+    source.writeUtf8("party")
+
+    val target = Buffer()
+    source.copyTo(target.outputStream())
+    assertThat(target.readUtf8()).isEqualTo("party")
+    assertThat(source.readUtf8()).isEqualTo("party")
+  }
+
+  @Test fun copyToOutputStreamWithOffset() {
+    val source = Buffer()
+    source.writeUtf8("party")
+
+    val target = Buffer()
+    source.copyTo(target.outputStream(), offset = 2)
+    assertThat(target.readUtf8()).isEqualTo("rty")
+    assertThat(source.readUtf8()).isEqualTo("party")
+  }
+
+  @Test fun copyToOutputStreamWithByteCount() {
+    val source = Buffer()
+    source.writeUtf8("party")
+
+    val target = Buffer()
+    source.copyTo(target.outputStream(), byteCount = 3)
+    assertThat(target.readUtf8()).isEqualTo("par")
+    assertThat(source.readUtf8()).isEqualTo("party")
+  }
+
+  @Test fun copyToOutputStreamWithOffsetAndByteCount() {
+    val source = Buffer()
+    source.writeUtf8("party")
+
+    val target = Buffer()
+    source.copyTo(target.outputStream(), offset = 1, byteCount = 3)
+    assertThat(target.readUtf8()).isEqualTo("art")
+    assertThat(source.readUtf8()).isEqualTo("party")
+  }
+
+  @Test fun writeToOutputStream() {
+    val source = Buffer()
+    source.writeUtf8("party")
+
+    val target = Buffer()
+    source.writeTo(target.outputStream())
+    assertThat(target.readUtf8()).isEqualTo("party")
+    assertThat(source.readUtf8()).isEqualTo("")
+  }
+
+  @Test fun writeToOutputStreamWithByteCount() {
+    val source = Buffer()
+    source.writeUtf8("party")
+
+    val target = Buffer()
+    source.writeTo(target.outputStream(), byteCount = 3)
+    assertThat(target.readUtf8()).isEqualTo("par")
+    assertThat(source.readUtf8()).isEqualTo("ty")
+  }
+}
diff --git a/okio/src/jvmTest/kotlin/okio/ByteStringKotlinTest.kt b/okio/src/jvmTest/kotlin/okio/ByteStringKotlinTest.kt
new file mode 100644
index 0000000..c554251
--- /dev/null
+++ b/okio/src/jvmTest/kotlin/okio/ByteStringKotlinTest.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+import okio.ByteString.Companion.encode
+import okio.ByteString.Companion.encodeUtf8
+import okio.ByteString.Companion.readByteString
+import okio.ByteString.Companion.toByteString
+import java.io.ByteArrayInputStream
+import java.nio.ByteBuffer
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+class ByteStringKotlinTest {
+  @Test fun arrayToByteString() {
+    val actual = byteArrayOf(1, 2, 3, 4).toByteString()
+    val expected = ByteString.of(1, 2, 3, 4)
+    assertEquals(actual, expected)
+  }
+
+  @Test fun arraySubsetToByteString() {
+    val actual = byteArrayOf(1, 2, 3, 4).toByteString(1, 2)
+    val expected = ByteString.of(2, 3)
+    assertEquals(actual, expected)
+  }
+
+  @Test fun byteBufferToByteString() {
+    val actual = ByteBuffer.wrap(byteArrayOf(1, 2, 3, 4)).toByteString()
+    val expected = ByteString.of(1, 2, 3, 4)
+    assertEquals(actual, expected)
+  }
+
+  @Test fun stringEncodeByteStringDefaultCharset() {
+    val actual = "a\uD83C\uDF69c".encode()
+    val expected = "a\uD83C\uDF69c".encodeUtf8()
+    assertEquals(actual, expected)
+  }
+
+  @Test fun streamReadByteString() {
+    val stream = ByteArrayInputStream(byteArrayOf(1, 2, 3, 4, 5, 6, 7, 8))
+    val actual = stream.readByteString(4)
+    val expected = ByteString.of(1, 2, 3, 4)
+    assertEquals(actual, expected)
+  }
+
+  @Test fun substring() {
+    val byteString = "abcdef".encodeUtf8()
+    assertEquals(byteString.substring(), "abcdef".encodeUtf8())
+    assertEquals(byteString.substring(endIndex = 3), "abc".encodeUtf8())
+    assertEquals(byteString.substring(beginIndex = 3), "def".encodeUtf8())
+    assertEquals(byteString.substring(beginIndex = 1, endIndex = 5), "bcde".encodeUtf8())
+  }
+}
diff --git a/okio/src/jvmTest/kotlin/okio/CipherAlgorithm.kt b/okio/src/jvmTest/kotlin/okio/CipherAlgorithm.kt
new file mode 100644
index 0000000..f9f42b0
--- /dev/null
+++ b/okio/src/jvmTest/kotlin/okio/CipherAlgorithm.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2020 Square, Inc. and others.
+ *
+ * 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 okio
+
+import javax.crypto.spec.IvParameterSpec
+import javax.crypto.spec.SecretKeySpec
+import kotlin.random.Random
+
+data class CipherAlgorithm(
+  val transformation: String,
+  val padding: Boolean,
+  val keyLength: Int,
+  val ivLength: Int? = null
+) {
+  fun createCipherFactory(random: Random): CipherFactory {
+    val key = random.nextBytes(keyLength)
+    val secretKeySpec = SecretKeySpec(key, transformation.substringBefore('/'))
+    return if (ivLength == null) {
+      CipherFactory(transformation) { mode ->
+        init(mode, secretKeySpec)
+      }
+    } else {
+      val iv = random.nextBytes(ivLength)
+      val ivParameterSpec = IvParameterSpec(iv)
+      CipherFactory(transformation) { mode ->
+        init(mode, secretKeySpec, ivParameterSpec)
+      }
+    }
+  }
+
+  override fun toString() = transformation
+
+  companion object {
+    val BLOCK_CIPHER_ALGORITHMS
+      get() = listOf(
+        CipherAlgorithm("AES/CBC/NoPadding", false, 16, 16),
+        CipherAlgorithm("AES/CBC/PKCS5Padding", true, 16, 16),
+        CipherAlgorithm("AES/ECB/NoPadding", false, 16),
+        CipherAlgorithm("AES/ECB/PKCS5Padding", true, 16),
+        CipherAlgorithm("DES/CBC/NoPadding", false, 8, 8),
+        CipherAlgorithm("DES/CBC/PKCS5Padding", true, 8, 8),
+        CipherAlgorithm("DES/ECB/NoPadding", false, 8),
+        CipherAlgorithm("DES/ECB/PKCS5Padding", true, 8),
+        CipherAlgorithm("DESede/CBC/NoPadding", false, 24, 8),
+        CipherAlgorithm("DESede/CBC/PKCS5Padding", true, 24, 8),
+        CipherAlgorithm("DESede/ECB/NoPadding", false, 24),
+        CipherAlgorithm("DESede/ECB/PKCS5Padding", true, 24)
+      )
+  }
+}
diff --git a/okio/src/jvmTest/kotlin/okio/CipherFactory.kt b/okio/src/jvmTest/kotlin/okio/CipherFactory.kt
new file mode 100644
index 0000000..7b93c65
--- /dev/null
+++ b/okio/src/jvmTest/kotlin/okio/CipherFactory.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 Square, Inc. and others.
+ *
+ * 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 okio
+
+import javax.crypto.Cipher
+
+class CipherFactory(
+  private val transformation: String,
+  private val init: Cipher.(mode: Int) -> Unit
+) {
+  val blockSize
+    get() = newCipher().blockSize
+
+  val encrypt: Cipher
+    get() = create(Cipher.ENCRYPT_MODE)
+
+  val decrypt: Cipher
+    get() = create(Cipher.DECRYPT_MODE)
+
+  private fun newCipher(): Cipher = Cipher.getInstance(transformation)
+
+  private fun create(mode: Int): Cipher = newCipher().apply { init(mode) }
+}
diff --git a/okio/src/jvmTest/kotlin/okio/CipherSinkTest.kt b/okio/src/jvmTest/kotlin/okio/CipherSinkTest.kt
new file mode 100644
index 0000000..f273971
--- /dev/null
+++ b/okio/src/jvmTest/kotlin/okio/CipherSinkTest.kt
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2020 Square, Inc. and others.
+ *
+ * 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 okio
+
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import kotlin.random.Random
+
+@RunWith(Parameterized::class)
+class CipherSinkTest(private val cipherAlgorithm: CipherAlgorithm) {
+  companion object {
+    @get:Parameterized.Parameters(name = "{0}")
+    @get:JvmStatic
+    val parameters: List<CipherAlgorithm>
+      get() = CipherAlgorithm.BLOCK_CIPHER_ALGORITHMS
+  }
+
+  @Test
+  fun encrypt() {
+    val random = Random(8912860393601532863)
+    val cipherFactory = cipherAlgorithm.createCipherFactory(random)
+    val data = random.nextBytes(32)
+
+    val buffer = Buffer()
+    val cipherSink = buffer.cipherSink(cipherFactory.encrypt)
+    cipherSink.buffer().use { it.write(data) }
+    val actualEncryptedData = buffer.readByteArray()
+
+    val expectedEncryptedData = cipherFactory.encrypt.doFinal(data)
+    assertArrayEquals(expectedEncryptedData, actualEncryptedData)
+  }
+
+  @Test
+  fun encryptEmpty() {
+    val random = Random(3014415396541767201)
+    val cipherFactory = cipherAlgorithm.createCipherFactory(random)
+    val data = ByteArray(0)
+
+    val buffer = Buffer()
+    val cipherSink = buffer.cipherSink(cipherFactory.encrypt)
+    cipherSink.buffer().close()
+    val actualEncryptedData = buffer.readByteArray()
+
+    val expectedEncryptedData = cipherFactory.encrypt.doFinal(data)
+    assertArrayEquals(expectedEncryptedData, actualEncryptedData)
+  }
+
+  @Test
+  fun encryptLarge() {
+    val random = Random(4800508322764694019)
+    val cipherFactory = cipherAlgorithm.createCipherFactory(random)
+    val data = random.nextBytes(Segment.SIZE * 16 + Segment.SIZE / 2)
+
+    val buffer = Buffer()
+    val cipherSink = buffer.cipherSink(cipherFactory.encrypt)
+    cipherSink.buffer().use { it.write(data) }
+    val actualEncryptedData = buffer.readByteArray()
+
+    val expectedEncryptedData = cipherFactory.encrypt.doFinal(data)
+    assertArrayEquals(expectedEncryptedData, actualEncryptedData)
+  }
+
+  @Test
+  fun encryptSingleByteWrite() {
+    val random = Random(4374178522096702290)
+    val cipherFactory = cipherAlgorithm.createCipherFactory(random)
+    val data = random.nextBytes(32)
+
+    val buffer = Buffer()
+    val cipherSink = buffer.cipherSink(cipherFactory.encrypt)
+    cipherSink.buffer().use {
+      data.forEach {
+        byte ->
+        it.writeByte(byte.toInt())
+      }
+    }
+    val actualEncryptedData = buffer.readByteArray()
+
+    val expectedEncryptedData = cipherFactory.encrypt.doFinal(data)
+    assertArrayEquals(expectedEncryptedData, actualEncryptedData)
+  }
+
+  /** Only relevant for algorithms which handle padding. */
+  @Test
+  fun encryptPaddingRequired() {
+    val random = Random(7515202505362968404)
+    val cipherFactory = cipherAlgorithm.createCipherFactory(random)
+    val blockSize = cipherFactory.blockSize
+    val dataSize = blockSize * 4 + if (cipherAlgorithm.padding) blockSize / 2 else 0
+    val data = random.nextBytes(dataSize)
+
+    val buffer = Buffer()
+    val cipherSink = buffer.cipherSink(cipherFactory.encrypt)
+    cipherSink.buffer().use { it.write(data) }
+    val actualEncryptedData = buffer.readByteArray()
+
+    val expectedEncryptedData = cipherFactory.encrypt.doFinal(data)
+    assertArrayEquals(expectedEncryptedData, actualEncryptedData)
+  }
+
+  @Test
+  fun decrypt() {
+    val random = Random(488375923060579687)
+    val cipherFactory = cipherAlgorithm.createCipherFactory(random)
+    val expectedData = random.nextBytes(32)
+    val encryptedData = cipherFactory.encrypt.doFinal(expectedData)
+
+    val buffer = Buffer()
+    val cipherSink = buffer.cipherSink(cipherFactory.decrypt)
+    cipherSink.buffer().use { it.write(encryptedData) }
+    val actualData = buffer.readByteArray()
+
+    assertArrayEquals(expectedData, actualData)
+  }
+
+  @Test
+  fun decryptEmpty() {
+    val random = Random(-9063010151894844496)
+    val cipherFactory = cipherAlgorithm.createCipherFactory(random)
+    val expectedData = ByteArray(0)
+    val encryptedData = cipherFactory.encrypt.doFinal(expectedData)
+
+    val buffer = Buffer()
+    val cipherSink = buffer.cipherSink(cipherFactory.decrypt)
+    cipherSink.buffer().use { it.write(encryptedData) }
+    val actualData = buffer.readByteArray()
+
+    assertArrayEquals(expectedData, actualData)
+  }
+
+  @Test
+  fun decryptLarge() {
+    val random = Random(993064087526004362)
+    val cipherFactory = cipherAlgorithm.createCipherFactory(random)
+    val expectedData = random.nextBytes(Segment.SIZE * 16 + Segment.SIZE / 2)
+    val encryptedData = cipherFactory.encrypt.doFinal(expectedData)
+
+    val buffer = Buffer()
+    val cipherSink = buffer.cipherSink(cipherFactory.decrypt)
+    cipherSink.buffer().use { it.write(encryptedData) }
+    val actualData = buffer.readByteArray()
+
+    assertArrayEquals(expectedData, actualData)
+  }
+
+  @Test
+  fun decryptSingleByteWrite() {
+    val random = Random(2621474675920878975)
+    val cipherFactory = cipherAlgorithm.createCipherFactory(random)
+    val expectedData = random.nextBytes(32)
+    val encryptedData = cipherFactory.encrypt.doFinal(expectedData)
+
+    val buffer = Buffer()
+    val cipherSink = buffer.cipherSink(cipherFactory.decrypt)
+    cipherSink.buffer().use {
+      encryptedData.forEach { byte ->
+        it.writeByte(byte.toInt())
+      }
+    }
+    val actualData = buffer.readByteArray()
+
+    assertArrayEquals(expectedData, actualData)
+  }
+
+  /** Only relevant for algorithms which handle padding. */
+  @Test
+  fun decryptPaddingRequired() {
+    val random = Random(7689061926945836562)
+    val cipherFactory = cipherAlgorithm.createCipherFactory(random)
+    val blockSize = cipherFactory.blockSize
+    val dataSize = blockSize * 4 + if (cipherAlgorithm.padding) blockSize / 2 else 0
+    val expectedData = random.nextBytes(dataSize)
+    val encryptedData = cipherFactory.encrypt.doFinal(expectedData)
+
+    val buffer = Buffer()
+    val cipherSink = buffer.cipherSink(cipherFactory.decrypt)
+    cipherSink.buffer().use { it.write(encryptedData) }
+    val actualData = buffer.readByteArray()
+
+    assertArrayEquals(expectedData, actualData)
+  }
+}
diff --git a/okio/src/jvmTest/kotlin/okio/CipherSourceTest.kt b/okio/src/jvmTest/kotlin/okio/CipherSourceTest.kt
new file mode 100644
index 0000000..f97258e
--- /dev/null
+++ b/okio/src/jvmTest/kotlin/okio/CipherSourceTest.kt
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2020 Square, Inc. and others.
+ *
+ * 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 okio
+
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import kotlin.random.Random
+
+@RunWith(Parameterized::class)
+class CipherSourceTest(private val cipherAlgorithm: CipherAlgorithm) {
+  companion object {
+    @get:Parameterized.Parameters(name = "{0}")
+    @get:JvmStatic
+    val parameters: List<CipherAlgorithm>
+      get() = CipherAlgorithm.BLOCK_CIPHER_ALGORITHMS
+  }
+
+  @Test
+  fun encrypt() {
+    val random = Random(787679144228763091)
+    val cipherFactory = cipherAlgorithm.createCipherFactory(random)
+    val data = random.nextBytes(32)
+
+    val buffer = Buffer().apply { write(data) }
+    val cipherSource = buffer.cipherSource(cipherFactory.encrypt)
+    val actualEncryptedData = cipherSource.buffer().use { it.readByteArray() }
+
+    val expectedEncryptedData = cipherFactory.encrypt.doFinal(data)
+    assertArrayEquals(expectedEncryptedData, actualEncryptedData)
+  }
+
+  @Test
+  fun encryptEmpty() {
+    val random = Random(1057830944394705953)
+    val cipherFactory = cipherAlgorithm.createCipherFactory(random)
+    val data = ByteArray(0)
+
+    val buffer = Buffer()
+    val cipherSource = buffer.cipherSource(cipherFactory.encrypt)
+    val actualEncryptedData = cipherSource.buffer().use { it.readByteArray() }
+
+    val expectedEncryptedData = cipherFactory.encrypt.doFinal(data)
+    assertArrayEquals(expectedEncryptedData, actualEncryptedData)
+  }
+
+  @Test
+  fun encryptLarge() {
+    val random = Random(8185922876836480815)
+    val cipherFactory = cipherAlgorithm.createCipherFactory(random)
+    val data = random.nextBytes(Segment.SIZE * 16 + Segment.SIZE / 2)
+
+    val buffer = Buffer().apply { write(data) }
+    val cipherSource = buffer.cipherSource(cipherFactory.encrypt)
+    val actualEncryptedData = cipherSource.buffer().use { it.readByteArray() }
+
+    val expectedEncryptedData = cipherFactory.encrypt.doFinal(data)
+    assertArrayEquals(expectedEncryptedData, actualEncryptedData)
+  }
+
+  @Test
+  fun encryptSingleByteSource() {
+    val random = Random(6085265142433950622)
+    val cipherFactory = cipherAlgorithm.createCipherFactory(random)
+    val data = random.nextBytes(32)
+
+    val buffer = Buffer().apply { write(data) }
+    val cipherSource = buffer.emitSingleBytes().cipherSource(cipherFactory.encrypt)
+    val actualEncryptedData = cipherSource.buffer().use { it.readByteArray() }
+
+    val expectedEncryptedData = cipherFactory.encrypt.doFinal(data)
+    assertArrayEquals(expectedEncryptedData, actualEncryptedData)
+  }
+
+  /** Only relevant for algorithms which handle padding. */
+  @Test
+  fun encryptPaddingRequired() {
+    val random = Random(4190481737015278225)
+    val cipherFactory = cipherAlgorithm.createCipherFactory(random)
+    val blockSize = cipherFactory.blockSize
+    val dataSize = blockSize * 4 + if (cipherAlgorithm.padding) blockSize / 2 else 0
+    val data = random.nextBytes(dataSize)
+
+    val buffer = Buffer().apply { write(data) }
+    val cipherSource = buffer.cipherSource(cipherFactory.encrypt)
+    val actualEncryptedData = cipherSource.buffer().use { it.readByteArray() }
+
+    val expectedEncryptedData = cipherFactory.encrypt.doFinal(data)
+    assertArrayEquals(expectedEncryptedData, actualEncryptedData)
+  }
+
+  @Test
+  fun decrypt() {
+    val random = Random(8067587635762239433)
+    val cipherFactory = cipherAlgorithm.createCipherFactory(random)
+    val expectedData = random.nextBytes(32)
+    val encryptedData = cipherFactory.encrypt.doFinal(expectedData)
+
+    val buffer = Buffer().apply { write(encryptedData) }
+    val cipherSource = buffer.cipherSource(cipherFactory.decrypt)
+    val actualData = cipherSource.buffer().use { it.readByteArray() }
+
+    assertArrayEquals(expectedData, actualData)
+  }
+
+  @Test
+  fun decryptEmpty() {
+    val random = Random(8722996896871347396)
+    val cipherFactory = cipherAlgorithm.createCipherFactory(random)
+    val expectedData = ByteArray(0)
+    val encryptedData = cipherFactory.encrypt.doFinal(expectedData)
+
+    val buffer = Buffer().apply { write(encryptedData) }
+    val cipherSource = buffer.cipherSource(cipherFactory.decrypt)
+    val actualData = cipherSource.buffer().use { it.readByteArray() }
+
+    assertArrayEquals(expectedData, actualData)
+  }
+
+  @Test
+  fun decryptLarge() {
+    val random = Random(4007116131070653181)
+    val cipherFactory = cipherAlgorithm.createCipherFactory(random)
+    val expectedData = random.nextBytes(Segment.SIZE * 16 + Segment.SIZE / 2)
+    val encryptedData = cipherFactory.encrypt.doFinal(expectedData)
+
+    val buffer = Buffer().apply { write(encryptedData) }
+    val cipherSource = buffer.cipherSource(cipherFactory.decrypt)
+    val actualData = cipherSource.buffer().use { it.readByteArray() }
+
+    assertArrayEquals(expectedData, actualData)
+  }
+
+  @Test
+  fun decryptSingleByteSource() {
+    val random = Random(1555017938547616655)
+    val cipherFactory = cipherAlgorithm.createCipherFactory(random)
+    val expectedData = random.nextBytes(32)
+    val encryptedData = cipherFactory.encrypt.doFinal(expectedData)
+
+    val buffer = Buffer().apply { write(encryptedData) }
+    val cipherSource = buffer.emitSingleBytes().cipherSource(cipherFactory.decrypt)
+    val actualData = cipherSource.buffer().use {
+      it.readByteArray()
+    }
+
+    assertArrayEquals(expectedData, actualData)
+  }
+
+  /** Only relevant for algorithms which handle padding. */
+  @Test
+  fun decryptPaddingRequired() {
+    val random = Random(5717921427007554469)
+    val cipherFactory = cipherAlgorithm.createCipherFactory(random)
+    val blockSize = cipherFactory.blockSize
+    val dataSize = blockSize * 4 + if (cipherAlgorithm.padding) blockSize / 2 else 0
+    val expectedData = random.nextBytes(dataSize)
+    val encryptedData = cipherFactory.encrypt.doFinal(expectedData)
+
+    val buffer = Buffer().apply { write(encryptedData) }
+    val cipherSource = buffer.cipherSource(cipherFactory.decrypt)
+    val actualData = cipherSource.buffer().use { it.readByteArray() }
+
+    assertArrayEquals(expectedData, actualData)
+  }
+
+  private fun Source.emitSingleBytes(): Source =
+    SingleByteSource(this)
+
+  private class SingleByteSource(source: Source) : ForwardingSource(source) {
+    override fun read(sink: Buffer, byteCount: Long): Long =
+      delegate.read(sink, 1L)
+  }
+}
diff --git a/okio/src/jvmTest/kotlin/okio/DeflateKotlinTest.kt b/okio/src/jvmTest/kotlin/okio/DeflateKotlinTest.kt
new file mode 100644
index 0000000..7a1744a
--- /dev/null
+++ b/okio/src/jvmTest/kotlin/okio/DeflateKotlinTest.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+import okio.ByteString.Companion.decodeHex
+import org.junit.Test
+import java.util.zip.Deflater
+import java.util.zip.Inflater
+import kotlin.test.assertEquals
+
+class DeflateKotlinTest {
+  @Test fun deflate() {
+    val data = Buffer()
+    val deflater = (data as Sink).deflate()
+    deflater.buffer().writeUtf8("Hi!").close()
+    assertEquals("789cf3c854040001ce00d3", data.readByteString().hex())
+  }
+
+  @Test fun deflateWithDeflater() {
+    val data = Buffer()
+    val deflater = (data as Sink).deflate(Deflater(0, true))
+    deflater.buffer().writeUtf8("Hi!").close()
+    assertEquals("010300fcff486921", data.readByteString().hex())
+  }
+
+  @Test fun inflate() {
+    val buffer = Buffer().write("789cf3c854040001ce00d3".decodeHex())
+    val inflated = (buffer as Source).inflate()
+    assertEquals("Hi!", inflated.buffer().readUtf8())
+  }
+
+  @Test fun inflateWithInflater() {
+    val buffer = Buffer().write("010300fcff486921".decodeHex())
+    val inflated = (buffer as Source).inflate(Inflater(true))
+    assertEquals("Hi!", inflated.buffer().readUtf8())
+  }
+}
diff --git a/okio/src/jvmTest/kotlin/okio/ForwardingTimeoutKotlinTest.kt b/okio/src/jvmTest/kotlin/okio/ForwardingTimeoutKotlinTest.kt
new file mode 100644
index 0000000..4db02c5
--- /dev/null
+++ b/okio/src/jvmTest/kotlin/okio/ForwardingTimeoutKotlinTest.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+import org.assertj.core.api.Assertions.assertThat
+import org.junit.Test
+import java.util.concurrent.TimeUnit
+
+class ForwardingTimeoutKotlinTest {
+  @Test fun getAndSetDelegate() {
+    val timeout1 = Timeout()
+    val timeout2 = Timeout()
+
+    val forwardingTimeout = ForwardingTimeout(timeout1)
+    forwardingTimeout.timeout(5, TimeUnit.SECONDS)
+    assertThat(timeout1.timeoutNanos()).isNotEqualTo(0L)
+    assertThat(timeout2.timeoutNanos()).isEqualTo(0L)
+    forwardingTimeout.clearTimeout()
+    assertThat(timeout1.timeoutNanos()).isEqualTo(0L)
+    assertThat(timeout2.timeoutNanos()).isEqualTo(0L)
+    assertThat(forwardingTimeout.delegate).isEqualTo(timeout1)
+
+    forwardingTimeout.delegate = timeout2
+    forwardingTimeout.timeout(5, TimeUnit.SECONDS)
+    assertThat(timeout1.timeoutNanos()).isEqualTo(0L)
+    assertThat(timeout2.timeoutNanos()).isNotEqualTo(0L)
+    forwardingTimeout.clearTimeout()
+    assertThat(timeout1.timeoutNanos()).isEqualTo(0L)
+    assertThat(timeout2.timeoutNanos()).isEqualTo(0L)
+    assertThat(forwardingTimeout.delegate).isEqualTo(timeout2)
+  }
+}
diff --git a/okio/src/jvmTest/kotlin/okio/GzipKotlinTest.kt b/okio/src/jvmTest/kotlin/okio/GzipKotlinTest.kt
new file mode 100644
index 0000000..6bbe9b5
--- /dev/null
+++ b/okio/src/jvmTest/kotlin/okio/GzipKotlinTest.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+import okio.ByteString.Companion.decodeHex
+import org.junit.Test
+import kotlin.test.assertEquals
+
+class GzipKotlinTest {
+  @Test fun sink() {
+    val data = Buffer()
+    val gzip = (data as Sink).gzip()
+    gzip.buffer().writeUtf8("Hi!").close()
+    assertEquals("1f8b0800000000000000f3c8540400dac59e7903000000", data.readByteString().hex())
+  }
+
+  @Test fun source() {
+    val buffer = Buffer().write("1f8b0800000000000000f3c8540400dac59e7903000000".decodeHex())
+    val gzip = (buffer as Source).gzip()
+    assertEquals("Hi!", gzip.buffer().readUtf8())
+  }
+}
diff --git a/okio/src/jvmTest/kotlin/okio/OkioKotlinTest.kt b/okio/src/jvmTest/kotlin/okio/OkioKotlinTest.kt
new file mode 100644
index 0000000..58c6bca
--- /dev/null
+++ b/okio/src/jvmTest/kotlin/okio/OkioKotlinTest.kt
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+import org.assertj.core.api.Assertions.assertThat
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TemporaryFolder
+import java.io.ByteArrayInputStream
+import java.io.ByteArrayOutputStream
+import java.io.File
+import java.net.Socket
+import java.nio.file.StandardOpenOption
+import java.nio.file.StandardOpenOption.APPEND
+
+class OkioKotlinTest {
+  @get:Rule val temp = TemporaryFolder()
+
+  @Test fun outputStreamSink() {
+    val baos = ByteArrayOutputStream()
+    val sink = baos.sink()
+    sink.write(Buffer().writeUtf8("a"), 1L)
+    assertThat(baos.toByteArray()).isEqualTo(byteArrayOf(0x61))
+  }
+
+  @Test fun inputStreamSource() {
+    val bais = ByteArrayInputStream(byteArrayOf(0x61))
+    val source = bais.source()
+    val buffer = Buffer()
+    source.read(buffer, 1)
+    assertThat(buffer.readUtf8()).isEqualTo("a")
+  }
+
+  @Test fun fileSink() {
+    val file = temp.newFile()
+    val sink = file.sink()
+    sink.write(Buffer().writeUtf8("a"), 1L)
+    assertThat(file.readText()).isEqualTo("a")
+  }
+
+  @Test fun fileAppendingSink() {
+    val file = temp.newFile()
+    file.writeText("a")
+    val sink = file.sink(append = true)
+    sink.write(Buffer().writeUtf8("b"), 1L)
+    sink.close()
+    assertThat(file.readText()).isEqualTo("ab")
+  }
+
+  @Test fun fileSource() {
+    val file = temp.newFile()
+    file.writeText("a")
+    val source = file.source()
+    val buffer = Buffer()
+    source.read(buffer, 1L)
+    assertThat(buffer.readUtf8()).isEqualTo("a")
+  }
+
+  @Test fun pathSink() {
+    val file = temp.newFile()
+    val sink = file.toPath().sink()
+    sink.write(Buffer().writeUtf8("a"), 1L)
+    assertThat(file.readText()).isEqualTo("a")
+  }
+
+  @Test fun pathSinkWithOptions() {
+    val file = temp.newFile()
+    file.writeText("a")
+    val sink = file.toPath().sink(APPEND)
+    sink.write(Buffer().writeUtf8("b"), 1L)
+    assertThat(file.readText()).isEqualTo("ab")
+  }
+
+  @Test fun pathSource() {
+    val file = temp.newFile()
+    file.writeText("a")
+    val source = file.toPath().source()
+    val buffer = Buffer()
+    source.read(buffer, 1L)
+    assertThat(buffer.readUtf8()).isEqualTo("a")
+  }
+
+  @Ignore("Not sure how to test this")
+  @Test fun pathSourceWithOptions() {
+    val folder = temp.newFolder()
+    val file = File(folder, "new.txt")
+    file.toPath().source(StandardOpenOption.CREATE_NEW)
+    // This still throws NoSuchFileException...
+  }
+
+  @Test fun socketSink() {
+    val baos = ByteArrayOutputStream()
+    val socket = object : Socket() {
+      override fun getOutputStream() = baos
+    }
+    val sink = socket.sink()
+    sink.write(Buffer().writeUtf8("a"), 1L)
+    assertThat(baos.toByteArray()).isEqualTo(byteArrayOf(0x61))
+  }
+
+  @Test fun socketSource() {
+    val bais = ByteArrayInputStream(byteArrayOf(0x61))
+    val socket = object : Socket() {
+      override fun getInputStream() = bais
+    }
+    val source = socket.source()
+    val buffer = Buffer()
+    source.read(buffer, 1L)
+    assertThat(buffer.readUtf8()).isEqualTo("a")
+  }
+}
diff --git a/okio/src/jvmTest/kotlin/okio/PipeKotlinTest.kt b/okio/src/jvmTest/kotlin/okio/PipeKotlinTest.kt
new file mode 100644
index 0000000..3a41e74
--- /dev/null
+++ b/okio/src/jvmTest/kotlin/okio/PipeKotlinTest.kt
@@ -0,0 +1,883 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+import org.junit.After
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Assert.fail
+import org.junit.Rule
+import org.junit.Test
+import java.io.IOException
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.Executors
+import java.util.concurrent.TimeUnit
+import kotlin.test.assertFailsWith
+import org.junit.rules.Timeout as JUnitTimeout
+
+class PipeKotlinTest {
+  @JvmField @Rule val timeout = JUnitTimeout(5, TimeUnit.SECONDS)
+
+  private val executorService = Executors.newScheduledThreadPool(1)
+
+  @After @Throws(Exception::class)
+  fun tearDown() {
+    executorService.shutdown()
+  }
+
+  @Test fun pipe() {
+    val pipe = Pipe(6)
+    pipe.sink.write(Buffer().writeUtf8("abc"), 3L)
+
+    val readBuffer = Buffer()
+    assertEquals(3L, pipe.source.read(readBuffer, 6L))
+    assertEquals("abc", readBuffer.readUtf8())
+
+    pipe.sink.close()
+    assertEquals(-1L, pipe.source.read(readBuffer, 6L))
+
+    pipe.source.close()
+  }
+
+  @Test fun fold() {
+    val pipe = Pipe(128)
+
+    val pipeSink = pipe.sink.buffer()
+    pipeSink.writeUtf8("hello")
+    pipeSink.emit()
+
+    val pipeSource = pipe.source.buffer()
+    assertEquals("hello", pipeSource.readUtf8(5))
+
+    val foldedSinkBuffer = Buffer()
+    var foldedSinkClosed = false
+    val foldedSink = object : ForwardingSink(foldedSinkBuffer) {
+      override fun close() {
+        foldedSinkClosed = true
+        super.close()
+      }
+    }
+    pipe.fold(foldedSink)
+
+    pipeSink.writeUtf8("world")
+    pipeSink.emit()
+    assertEquals("world", foldedSinkBuffer.readUtf8(5))
+
+    assertFailsWith<IllegalStateException> {
+      pipeSource.readUtf8()
+    }
+
+    pipeSink.close()
+    assertTrue(foldedSinkClosed)
+  }
+
+  @Test fun foldWritesPipeContentsToSink() {
+    val pipe = Pipe(128)
+
+    val pipeSink = pipe.sink.buffer()
+    pipeSink.writeUtf8("hello")
+    pipeSink.emit()
+
+    val foldSink = Buffer()
+    pipe.fold(foldSink)
+
+    assertEquals("hello", foldSink.readUtf8(5))
+  }
+
+  @Test fun foldUnblocksBlockedWrite() {
+    val pipe = Pipe(4)
+    val foldSink = Buffer()
+
+    val latch = CountDownLatch(1)
+    executorService.schedule(
+      {
+        pipe.fold(foldSink)
+        latch.countDown()
+      },
+      500, TimeUnit.MILLISECONDS
+    )
+
+    val sink = pipe.sink.buffer()
+    sink.writeUtf8("abcdefgh") // Blocks writing 8 bytes to a 4 byte pipe.
+    sink.close()
+
+    latch.await()
+    assertEquals("abcdefgh", foldSink.readUtf8())
+  }
+
+  @Test fun accessSourceAfterFold() {
+    val pipe = Pipe(100L)
+    pipe.fold(Buffer())
+    assertFailsWith<IllegalStateException> {
+      pipe.source.read(Buffer(), 1L)
+    }
+  }
+
+  @Test fun honorsPipeSinkTimeoutOnWritingWhenItIsSmaller() {
+    val pipe = Pipe(4)
+    val underlying = TimeoutWritingSink()
+
+    underlying.timeout.timeout(biggerTimeoutNanos, TimeUnit.NANOSECONDS)
+    pipe.sink.timeout().timeout(smallerTimeoutNanos, TimeUnit.NANOSECONDS)
+
+    pipe.fold(underlying)
+
+    assertDuration(smallerTimeoutNanos) {
+      pipe.sink.write(Buffer().writeUtf8("abc"), 3)
+    }
+    assertEquals(biggerTimeoutNanos, underlying.timeout().timeoutNanos())
+  }
+
+  @Test fun honorsUnderlyingTimeoutOnWritingWhenItIsSmaller() {
+    val pipe = Pipe(4)
+    val underlying = TimeoutWritingSink()
+
+    underlying.timeout.timeout(smallerTimeoutNanos, TimeUnit.NANOSECONDS)
+    pipe.sink.timeout().timeout(biggerTimeoutNanos, TimeUnit.NANOSECONDS)
+
+    pipe.fold(underlying)
+
+    assertDuration(smallerTimeoutNanos) {
+      pipe.sink.write(Buffer().writeUtf8("abc"), 3)
+    }
+    assertEquals(smallerTimeoutNanos, underlying.timeout().timeoutNanos())
+  }
+
+  @Test fun honorsPipeSinkTimeoutOnFlushingWhenItIsSmaller() {
+    val pipe = Pipe(4)
+    val underlying = TimeoutFlushingSink()
+
+    underlying.timeout.timeout(biggerTimeoutNanos, TimeUnit.NANOSECONDS)
+    pipe.sink.timeout().timeout(smallerTimeoutNanos, TimeUnit.NANOSECONDS)
+
+    pipe.fold(underlying)
+
+    assertDuration(smallerTimeoutNanos) {
+      pipe.sink.flush()
+    }
+    assertEquals(biggerTimeoutNanos, underlying.timeout().timeoutNanos())
+  }
+
+  @Test fun honorsUnderlyingTimeoutOnFlushingWhenItIsSmaller() {
+    val pipe = Pipe(4)
+    val underlying = TimeoutFlushingSink()
+
+    underlying.timeout.timeout(smallerTimeoutNanos, TimeUnit.NANOSECONDS)
+    pipe.sink.timeout().timeout(biggerTimeoutNanos, TimeUnit.NANOSECONDS)
+
+    pipe.fold(underlying)
+
+    assertDuration(smallerTimeoutNanos) {
+      pipe.sink.flush()
+    }
+    assertEquals(smallerTimeoutNanos, underlying.timeout().timeoutNanos())
+  }
+
+  @Test fun honorsPipeSinkTimeoutOnClosingWhenItIsSmaller() {
+    val pipe = Pipe(4)
+    val underlying = TimeoutClosingSink()
+
+    underlying.timeout.timeout(biggerTimeoutNanos, TimeUnit.NANOSECONDS)
+    pipe.sink.timeout().timeout(smallerTimeoutNanos, TimeUnit.NANOSECONDS)
+
+    pipe.fold(underlying)
+
+    assertDuration(smallerTimeoutNanos) {
+      pipe.sink.close()
+    }
+    assertEquals(biggerTimeoutNanos, underlying.timeout().timeoutNanos())
+  }
+
+  @Test fun honorsUnderlyingTimeoutOnClosingWhenItIsSmaller() {
+    val pipe = Pipe(4)
+    val underlying = TimeoutClosingSink()
+
+    underlying.timeout.timeout(smallerTimeoutNanos, TimeUnit.NANOSECONDS)
+    pipe.sink.timeout().timeout(biggerTimeoutNanos, TimeUnit.NANOSECONDS)
+
+    pipe.fold(underlying)
+
+    assertDuration(smallerTimeoutNanos) {
+      pipe.sink.close()
+    }
+    assertEquals(smallerTimeoutNanos, underlying.timeout().timeoutNanos())
+  }
+
+  @Test fun honorsPipeSinkTimeoutOnWritingWhenUnderlyingSinkTimeoutIsZero() {
+    val pipeSinkTimeoutNanos = smallerTimeoutNanos
+
+    val pipe = Pipe(4)
+    val underlying = TimeoutWritingSink()
+
+    pipe.sink.timeout().timeout(pipeSinkTimeoutNanos, TimeUnit.NANOSECONDS)
+
+    pipe.fold(underlying)
+
+    assertDuration(pipeSinkTimeoutNanos) {
+      pipe.sink.write(Buffer().writeUtf8("abc"), 3)
+    }
+    assertEquals(0L, underlying.timeout().timeoutNanos())
+  }
+
+  @Test fun honorsUnderlyingSinkTimeoutOnWritingWhenPipeSinkTimeoutIsZero() {
+    val underlyingSinkTimeoutNanos = smallerTimeoutNanos
+
+    val pipe = Pipe(4)
+    val underlying = TimeoutWritingSink()
+
+    underlying.timeout().timeout(underlyingSinkTimeoutNanos, TimeUnit.NANOSECONDS)
+
+    pipe.fold(underlying)
+
+    assertDuration(underlyingSinkTimeoutNanos) {
+      pipe.sink.write(Buffer().writeUtf8("abc"), 3)
+    }
+    assertEquals(underlyingSinkTimeoutNanos, underlying.timeout().timeoutNanos())
+  }
+
+  @Test fun honorsPipeSinkTimeoutOnFlushingWhenUnderlyingSinkTimeoutIsZero() {
+    val pipeSinkTimeoutNanos = smallerTimeoutNanos
+
+    val pipe = Pipe(4)
+    val underlying = TimeoutFlushingSink()
+
+    pipe.sink.timeout().timeout(pipeSinkTimeoutNanos, TimeUnit.NANOSECONDS)
+
+    pipe.fold(underlying)
+
+    assertDuration(pipeSinkTimeoutNanos) {
+      pipe.sink.flush()
+    }
+    assertEquals(0L, underlying.timeout().timeoutNanos())
+  }
+
+  @Test fun honorsUnderlyingSinkTimeoutOnFlushingWhenPipeSinkTimeoutIsZero() {
+    val underlyingSinkTimeoutNanos = smallerTimeoutNanos
+
+    val pipe = Pipe(4)
+    val underlying = TimeoutFlushingSink()
+
+    underlying.timeout().timeout(underlyingSinkTimeoutNanos, TimeUnit.NANOSECONDS)
+
+    pipe.fold(underlying)
+
+    assertDuration(underlyingSinkTimeoutNanos) {
+      pipe.sink.flush()
+    }
+    assertEquals(underlyingSinkTimeoutNanos, underlying.timeout().timeoutNanos())
+  }
+
+  @Test fun honorsPipeSinkTimeoutOnClosingWhenUnderlyingSinkTimeoutIsZero() {
+    val pipeSinkTimeoutNanos = smallerTimeoutNanos
+
+    val pipe = Pipe(4)
+    val underlying = TimeoutClosingSink()
+
+    pipe.sink.timeout().timeout(pipeSinkTimeoutNanos, TimeUnit.NANOSECONDS)
+
+    pipe.fold(underlying)
+
+    assertDuration(pipeSinkTimeoutNanos) {
+      pipe.sink.close()
+    }
+    assertEquals(0L, underlying.timeout().timeoutNanos())
+  }
+
+  @Test fun honorsUnderlyingSinkTimeoutOnClosingWhenPipeSinkTimeoutIsZero() {
+    val underlyingSinkTimeoutNanos = smallerTimeoutNanos
+
+    val pipe = Pipe(4)
+    val underlying = TimeoutClosingSink()
+
+    underlying.timeout().timeout(underlyingSinkTimeoutNanos, TimeUnit.NANOSECONDS)
+
+    pipe.fold(underlying)
+
+    assertDuration(underlyingSinkTimeoutNanos) {
+      pipe.sink.close()
+    }
+    assertEquals(underlyingSinkTimeoutNanos, underlying.timeout().timeoutNanos())
+  }
+
+  @Test fun honorsPipeSinkDeadlineOnWritingWhenItIsSmaller() {
+    val pipe = Pipe(4)
+    val underlying = TimeoutWritingSink()
+
+    val underlyingOriginalDeadline = System.nanoTime() + biggerDeadlineNanos
+    underlying.timeout.deadlineNanoTime(underlyingOriginalDeadline)
+    pipe.sink.timeout().deadlineNanoTime(System.nanoTime() + smallerDeadlineNanos)
+
+    pipe.fold(underlying)
+
+    assertDuration(smallerDeadlineNanos) {
+      pipe.sink.write(Buffer().writeUtf8("abc"), 3)
+    }
+    assertEquals(underlyingOriginalDeadline, underlying.timeout().deadlineNanoTime())
+  }
+
+  @Test fun honorsPipeSinkDeadlineOnWritingWhenUnderlyingSinkHasNoDeadline() {
+    val deadlineNanos = smallerDeadlineNanos
+
+    val pipe = Pipe(4)
+    val underlying = TimeoutWritingSink()
+
+    underlying.timeout.clearDeadline()
+    pipe.sink.timeout().deadlineNanoTime(System.nanoTime() + deadlineNanos)
+
+    pipe.fold(underlying)
+
+    assertDuration(deadlineNanos) {
+      pipe.sink.write(Buffer().writeUtf8("abc"), 3)
+    }
+    assertFalse(underlying.timeout().hasDeadline())
+  }
+
+  @Test fun honorsUnderlyingSinkDeadlineOnWritingWhenItIsSmaller() {
+    val pipe = Pipe(4)
+    val underlying = TimeoutWritingSink()
+
+    val underlyingOriginalDeadline = System.nanoTime() + smallerDeadlineNanos
+    underlying.timeout.deadlineNanoTime(underlyingOriginalDeadline)
+    pipe.sink.timeout().deadlineNanoTime(System.nanoTime() + biggerDeadlineNanos)
+
+    pipe.fold(underlying)
+
+    assertDuration(smallerDeadlineNanos) {
+      pipe.sink.write(Buffer().writeUtf8("abc"), 3)
+    }
+    assertEquals(underlyingOriginalDeadline, underlying.timeout().deadlineNanoTime())
+  }
+
+  @Test fun honorsUnderlyingSinkDeadlineOnWritingWhenPipeSinkHasNoDeadline() {
+    val deadlineNanos = smallerDeadlineNanos
+
+    val pipe = Pipe(4)
+    val underlying = TimeoutWritingSink()
+
+    val underlyingOriginalDeadline = System.nanoTime() + deadlineNanos
+    underlying.timeout().deadlineNanoTime(underlyingOriginalDeadline)
+    pipe.sink.timeout().clearDeadline()
+
+    pipe.fold(underlying)
+
+    assertDuration(deadlineNanos) {
+      pipe.sink.write(Buffer().writeUtf8("abc"), 3)
+    }
+    assertEquals(underlyingOriginalDeadline, underlying.timeout().deadlineNanoTime())
+  }
+
+  @Test fun honorsPipeSinkDeadlineOnFlushingWhenItIsSmaller() {
+    val pipe = Pipe(4)
+    val underlying = TimeoutFlushingSink()
+
+    val underlyingOriginalDeadline = System.nanoTime() + biggerDeadlineNanos
+    underlying.timeout.deadlineNanoTime(underlyingOriginalDeadline)
+    pipe.sink.timeout().deadlineNanoTime(System.nanoTime() + smallerDeadlineNanos)
+
+    pipe.fold(underlying)
+
+    assertDuration(smallerDeadlineNanos) {
+      pipe.sink.flush()
+    }
+    assertEquals(underlyingOriginalDeadline, underlying.timeout().deadlineNanoTime())
+  }
+
+  @Test fun honorsPipeSinkDeadlineOnFlushingWhenUnderlyingSinkHasNoDeadline() {
+    val deadlineNanos = smallerDeadlineNanos
+
+    val pipe = Pipe(4)
+    val underlying = TimeoutFlushingSink()
+
+    underlying.timeout.clearDeadline()
+    pipe.sink.timeout().deadlineNanoTime(System.nanoTime() + deadlineNanos)
+
+    pipe.fold(underlying)
+
+    assertDuration(deadlineNanos) {
+      pipe.sink.flush()
+    }
+    assertFalse(underlying.timeout().hasDeadline())
+  }
+
+  @Test fun honorsUnderlyingSinkDeadlineOnFlushingWhenItIsSmaller() {
+    val pipe = Pipe(4)
+    val underlying = TimeoutFlushingSink()
+
+    val underlyingOriginalDeadline = System.nanoTime() + smallerDeadlineNanos
+    underlying.timeout.deadlineNanoTime(underlyingOriginalDeadline)
+    pipe.sink.timeout().deadlineNanoTime(System.nanoTime() + biggerDeadlineNanos)
+
+    pipe.fold(underlying)
+
+    assertDuration(smallerDeadlineNanos) {
+      pipe.sink.flush()
+    }
+    assertEquals(underlyingOriginalDeadline, underlying.timeout().deadlineNanoTime())
+  }
+
+  @Test fun honorsUnderlyingSinkDeadlineOnFlushingWhenPipeSinkHasNoDeadline() {
+    val deadlineNanos = smallerDeadlineNanos
+
+    val pipe = Pipe(4)
+    val underlying = TimeoutFlushingSink()
+
+    val underlyingOriginalDeadline = System.nanoTime() + deadlineNanos
+    underlying.timeout().deadlineNanoTime(underlyingOriginalDeadline)
+    pipe.sink.timeout().clearDeadline()
+
+    pipe.fold(underlying)
+
+    assertDuration(deadlineNanos) {
+      pipe.sink.flush()
+    }
+    assertEquals(underlyingOriginalDeadline, underlying.timeout().deadlineNanoTime())
+  }
+
+  @Test fun honorsPipeSinkDeadlineOnClosingWhenItIsSmaller() {
+    val pipe = Pipe(4)
+    val underlying = TimeoutClosingSink()
+
+    val underlyingOriginalDeadline = System.nanoTime() + biggerDeadlineNanos
+    underlying.timeout.deadlineNanoTime(underlyingOriginalDeadline)
+    pipe.sink.timeout().deadlineNanoTime(System.nanoTime() + smallerDeadlineNanos)
+
+    pipe.fold(underlying)
+
+    assertDuration(smallerDeadlineNanos) {
+      pipe.sink.close()
+    }
+    assertEquals(underlyingOriginalDeadline, underlying.timeout().deadlineNanoTime())
+  }
+
+  @Test fun honorsPipeSinkDeadlineOnClosingWhenUnderlyingSinkHasNoDeadline() {
+    val deadlineNanos = smallerDeadlineNanos
+
+    val pipe = Pipe(4)
+    val underlying = TimeoutClosingSink()
+
+    underlying.timeout.clearDeadline()
+    pipe.sink.timeout().deadlineNanoTime(System.nanoTime() + deadlineNanos)
+
+    pipe.fold(underlying)
+
+    assertDuration(deadlineNanos) {
+      pipe.sink.close()
+    }
+    assertFalse(underlying.timeout().hasDeadline())
+  }
+
+  @Test fun honorsUnderlyingSinkDeadlineOnClosingWhenItIsSmaller() {
+    val pipe = Pipe(4)
+    val underlying = TimeoutClosingSink()
+
+    val underlyingOriginalDeadline = System.nanoTime() + smallerDeadlineNanos
+    underlying.timeout.deadlineNanoTime(underlyingOriginalDeadline)
+    pipe.sink.timeout().deadlineNanoTime(System.nanoTime() + biggerDeadlineNanos)
+
+    pipe.fold(underlying)
+
+    assertDuration(smallerDeadlineNanos) {
+      pipe.sink.close()
+    }
+    assertEquals(underlyingOriginalDeadline, underlying.timeout().deadlineNanoTime())
+  }
+
+  @Test fun honorsUnderlyingSinkDeadlineOnClosingWhenPipeSinkHasNoDeadline() {
+    val deadlineNanos = smallerDeadlineNanos
+
+    val pipe = Pipe(4)
+    val underlying = TimeoutClosingSink()
+
+    val underlyingOriginalDeadline = System.nanoTime() + deadlineNanos
+    underlying.timeout().deadlineNanoTime(underlyingOriginalDeadline)
+    pipe.sink.timeout().clearDeadline()
+
+    pipe.fold(underlying)
+
+    assertDuration(deadlineNanos) {
+      pipe.sink.close()
+    }
+    assertEquals(underlyingOriginalDeadline, underlying.timeout().deadlineNanoTime())
+  }
+
+  @Test fun foldingTwiceThrows() {
+    val pipe = Pipe(128)
+    pipe.fold(Buffer())
+    assertFailsWith<IllegalStateException> {
+      pipe.fold(Buffer())
+    }
+  }
+
+  @Test fun sinkWriteThrowsIOExceptionUnblockBlockedWriter() {
+    val pipe = Pipe(4)
+
+    val foldFuture = executorService.schedule(
+      {
+        val foldFailure = assertFailsWith<IOException> {
+          pipe.fold(object : ForwardingSink(blackholeSink()) {
+            override fun write(source: Buffer, byteCount: Long) {
+              throw IOException("boom")
+            }
+          })
+        }
+        assertEquals("boom", foldFailure.message)
+      },
+      500, TimeUnit.MILLISECONDS
+    )
+
+    val writeFailure = assertFailsWith<IOException> {
+      val pipeSink = pipe.sink.buffer()
+      pipeSink.writeUtf8("abcdefghij")
+      pipeSink.emit() // Block writing 10 bytes to a 4 byte pipe.
+    }
+    assertEquals("source is closed", writeFailure.message)
+
+    foldFuture.get() // Confirm no unexpected exceptions.
+  }
+
+  @Test fun foldHoldsNoLocksWhenForwardingWrites() {
+    val pipe = Pipe(4)
+
+    val pipeSink = pipe.sink.buffer()
+    pipeSink.writeUtf8("abcd")
+    pipeSink.emit()
+
+    pipe.fold(object : ForwardingSink(blackholeSink()) {
+      override fun write(source: Buffer, byteCount: Long) {
+        assertFalse(Thread.holdsLock(pipe.buffer))
+      }
+    })
+  }
+
+  /**
+   * Flushing the pipe wasn't causing the sink to be flushed when it was later folded. This was
+   * causing problems because the folded data was stalled.
+   */
+  @Test fun foldFlushesWhenThereIsFoldedData() {
+    val pipe = Pipe(128)
+    val pipeSink = pipe.sink.buffer()
+    pipeSink.writeUtf8("hello")
+    pipeSink.emit()
+
+    val ultimateSink = Buffer()
+    val unnecessaryWrapper = (ultimateSink as Sink).buffer()
+
+    pipe.fold(unnecessaryWrapper)
+
+    // Data should not have been flushed through the wrapper to the ultimate sink.
+    assertEquals("hello", ultimateSink.readUtf8())
+  }
+
+  @Test fun foldDoesNotFlushWhenThereIsNoFoldedData() {
+    val pipe = Pipe(128)
+
+    val ultimateSink = Buffer()
+    val unnecessaryWrapper = (ultimateSink as Sink).buffer()
+    unnecessaryWrapper.writeUtf8("hello")
+
+    pipe.fold(unnecessaryWrapper)
+
+    // Data should not have been flushed through the wrapper to the ultimate sink.
+    assertEquals("", ultimateSink.readUtf8())
+  }
+
+  @Test fun foldingClosesUnderlyingSinkWhenPipeSinkIsClose() {
+    val pipe = Pipe(128)
+
+    val pipeSink = pipe.sink.buffer()
+    pipeSink.writeUtf8("world")
+    pipeSink.close()
+
+    val foldedSinkBuffer = Buffer()
+    var foldedSinkClosed = false
+    val foldedSink = object : ForwardingSink(foldedSinkBuffer) {
+      override fun close() {
+        foldedSinkClosed = true
+        super.close()
+      }
+    }
+
+    pipe.fold(foldedSink)
+    assertEquals("world", foldedSinkBuffer.readUtf8(5))
+    assertTrue(foldedSinkClosed)
+  }
+
+  @Test fun cancelPreventsSinkWrite() {
+    val pipe = Pipe(8)
+    pipe.cancel()
+
+    val pipeSink = pipe.sink.buffer()
+    pipeSink.writeUtf8("hello world")
+
+    try {
+      pipeSink.emit()
+      fail()
+    } catch (e: IOException) {
+      assertEquals("canceled", e.message)
+    }
+  }
+
+  @Test fun cancelPreventsSinkFlush() {
+    val pipe = Pipe(8)
+    pipe.cancel()
+
+    try {
+      pipe.sink.flush()
+      fail()
+    } catch (e: IOException) {
+      assertEquals("canceled", e.message)
+    }
+  }
+
+  @Test fun sinkCloseAfterCancelDoesNotThrow() {
+    val pipe = Pipe(8)
+    pipe.cancel()
+    pipe.sink.close()
+  }
+
+  @Test fun cancelInterruptsSinkWrite() {
+    val pipe = Pipe(8)
+
+    executorService.schedule(
+      {
+        pipe.cancel()
+      },
+      smallerTimeoutNanos, TimeUnit.NANOSECONDS
+    )
+
+    val pipeSink = pipe.sink.buffer()
+    pipeSink.writeUtf8("hello world")
+
+    assertDuration(smallerTimeoutNanos) {
+      try {
+        pipeSink.emit()
+        fail()
+      } catch (e: IOException) {
+        assertEquals("canceled", e.message)
+      }
+    }
+  }
+
+  @Test fun cancelPreventsSourceRead() {
+    val pipe = Pipe(8)
+    pipe.cancel()
+
+    val pipeSource = pipe.source.buffer()
+
+    try {
+      pipeSource.require(1)
+      fail()
+    } catch (e: IOException) {
+      assertEquals("canceled", e.message)
+    }
+  }
+
+  @Test fun sourceCloseAfterCancelDoesNotThrow() {
+    val pipe = Pipe(8)
+    pipe.cancel()
+    pipe.source.close()
+  }
+
+  @Test fun cancelInterruptsSourceRead() {
+    val pipe = Pipe(8)
+
+    executorService.schedule(
+      {
+        pipe.cancel()
+      },
+      smallerTimeoutNanos, TimeUnit.NANOSECONDS
+    )
+
+    val pipeSource = pipe.source.buffer()
+
+    assertDuration(smallerTimeoutNanos) {
+      try {
+        pipeSource.require(1)
+        fail()
+      } catch (e: IOException) {
+        assertEquals("canceled", e.message)
+      }
+    }
+  }
+
+  @Test fun cancelPreventsSinkFold() {
+    val pipe = Pipe(8)
+    pipe.cancel()
+
+    var foldedSinkClosed = false
+    val foldedSink = object : ForwardingSink(Buffer()) {
+      override fun close() {
+        foldedSinkClosed = true
+        super.close()
+      }
+    }
+
+    try {
+      pipe.fold(foldedSink)
+      fail()
+    } catch (e: IOException) {
+      assertEquals("canceled", e.message)
+    }
+
+    // But the fold is still performed so close() closes everything.
+    assertFalse(foldedSinkClosed)
+    pipe.sink.close()
+    assertTrue(foldedSinkClosed)
+  }
+
+  @Test fun cancelInterruptsSinkFold() {
+    val pipe = Pipe(128)
+    val pipeSink = pipe.sink.buffer()
+    pipeSink.writeUtf8("hello")
+    pipeSink.emit()
+
+    var foldedSinkClosed = false
+    val foldedSink = object : ForwardingSink(Buffer()) {
+      override fun write(source: Buffer, byteCount: Long) {
+        assertEquals("hello", source.readUtf8(byteCount))
+
+        // Write bytes to the original pipe so the pipe write doesn't complete!
+        pipeSink.writeUtf8("more bytes")
+        pipeSink.emit()
+
+        // Cancel while the pipe is writing.
+        pipe.cancel()
+      }
+
+      override fun close() {
+        foldedSinkClosed = true
+        super.close()
+      }
+    }
+
+    try {
+      pipe.fold(foldedSink)
+      fail()
+    } catch (e: IOException) {
+      assertEquals("canceled", e.message)
+    }
+
+    // But the fold is still performed so close() closes everything.
+    assertFalse(foldedSinkClosed)
+    pipe.sink.close()
+    assertTrue(foldedSinkClosed)
+  }
+
+  private fun assertDuration(expected: Long, block: () -> Unit) {
+    val start = System.currentTimeMillis()
+    block()
+    val elapsed = TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis() - start)
+
+    assertEquals(
+      expected.toDouble(), elapsed.toDouble(),
+      TimeUnit.MILLISECONDS.toNanos(200).toDouble()
+    )
+  }
+
+  /** Writes on this sink never complete. They can only time out. */
+  class TimeoutWritingSink : Sink {
+    val timeout = object : AsyncTimeout() {
+      override fun timedOut() {
+        synchronized(this@TimeoutWritingSink) {
+          (this@TimeoutWritingSink as Object).notifyAll()
+        }
+      }
+    }
+
+    override fun write(source: Buffer, byteCount: Long) {
+      timeout.enter()
+      try {
+        synchronized(this) {
+          (this as Object).wait()
+        }
+      } finally {
+        timeout.exit()
+      }
+      source.skip(byteCount)
+    }
+
+    override fun flush() = Unit
+
+    override fun close() = Unit
+
+    override fun timeout() = timeout
+  }
+
+  /** Flushes on this sink never complete. They can only time out. */
+  class TimeoutFlushingSink : Sink {
+    val timeout = object : AsyncTimeout() {
+      override fun timedOut() {
+        synchronized(this@TimeoutFlushingSink) {
+          (this@TimeoutFlushingSink as Object).notifyAll()
+        }
+      }
+    }
+
+    override fun write(source: Buffer, byteCount: Long) = source.skip(byteCount)
+
+    override fun flush() {
+      timeout.enter()
+      try {
+        synchronized(this) {
+          (this as Object).wait()
+        }
+      } finally {
+        timeout.exit()
+      }
+    }
+
+    override fun close() = Unit
+
+    override fun timeout() = timeout
+  }
+
+  /** Closes on this sink never complete. They can only time out. */
+  class TimeoutClosingSink : Sink {
+    val timeout = object : AsyncTimeout() {
+      override fun timedOut() {
+        synchronized(this@TimeoutClosingSink) {
+          (this@TimeoutClosingSink as Object).notifyAll()
+        }
+      }
+    }
+
+    override fun write(source: Buffer, byteCount: Long) = source.skip(byteCount)
+
+    override fun flush() = Unit
+
+    override fun close() {
+      timeout.enter()
+      try {
+        synchronized(this) {
+          (this as Object).wait()
+        }
+      } finally {
+        timeout.exit()
+      }
+    }
+
+    override fun timeout() = timeout
+  }
+
+  companion object {
+    val smallerTimeoutNanos = TimeUnit.MILLISECONDS.toNanos(500L)
+    val biggerTimeoutNanos = TimeUnit.MILLISECONDS.toNanos(1500L)
+
+    val smallerDeadlineNanos = TimeUnit.MILLISECONDS.toNanos(500L)
+    val biggerDeadlineNanos = TimeUnit.MILLISECONDS.toNanos(1500L)
+  }
+}
diff --git a/okio/src/jvmTest/kotlin/okio/SegmentSharingTest.kt b/okio/src/jvmTest/kotlin/okio/SegmentSharingTest.kt
new file mode 100644
index 0000000..73e74d9
--- /dev/null
+++ b/okio/src/jvmTest/kotlin/okio/SegmentSharingTest.kt
@@ -0,0 +1,175 @@
+/*
+ * 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 okio
+
+import okio.ByteString.Companion.encodeUtf8
+import okio.TestUtil.assertEquivalent
+import okio.TestUtil.bufferWithSegments
+import okio.TestUtil.takeAllPoolSegments
+import org.junit.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+import kotlin.test.assertTrue
+
+/** Tests behavior optimized by sharing segments between buffers and byte strings.  */
+class SegmentSharingTest {
+  @Test fun snapshotOfEmptyBuffer() {
+    val snapshot = Buffer().snapshot()
+    assertEquivalent(snapshot, ByteString.EMPTY)
+  }
+
+  @Test fun snapshotsAreEquivalent() {
+    val byteString = bufferWithSegments(xs, ys, zs).snapshot()
+    assertEquivalent(byteString, bufferWithSegments(xs, ys + zs).snapshot())
+    assertEquivalent(byteString, bufferWithSegments(xs + ys + zs).snapshot())
+    assertEquivalent(byteString, (xs + ys + zs).encodeUtf8())
+  }
+
+  @Test fun snapshotGetByte() {
+    val byteString = bufferWithSegments(xs, ys, zs).snapshot()
+    assertEquals('x', byteString[0].toChar())
+    assertEquals('x', byteString[xs.length - 1].toChar())
+    assertEquals('y', byteString[xs.length].toChar())
+    assertEquals('y', byteString[xs.length + ys.length - 1].toChar())
+    assertEquals('z', byteString[xs.length + ys.length].toChar())
+    assertEquals('z', byteString[xs.length + ys.length + zs.length - 1].toChar())
+    assertFailsWith<IndexOutOfBoundsException> {
+      byteString[-1]
+    }
+
+    assertFailsWith<IndexOutOfBoundsException> {
+      byteString[xs.length + ys.length + zs.length]
+    }
+  }
+
+  @Test fun snapshotWriteToOutputStream() {
+    val byteString = bufferWithSegments(xs, ys, zs).snapshot()
+    val out = Buffer()
+    byteString.write(out.outputStream())
+    assertEquals(xs + ys + zs, out.readUtf8())
+  }
+
+  /**
+   * Snapshots share their backing byte arrays with the source buffers. Those byte arrays must not
+   * be recycled, otherwise the new writer could corrupt the segment.
+   */
+  @Test fun snapshotSegmentsAreNotRecycled() {
+    val buffer = bufferWithSegments(xs, ys, zs)
+    val snapshot = buffer.snapshot()
+    assertEquals(xs + ys + zs, snapshot.utf8())
+
+    // Confirm that clearing the buffer doesn't release its segments.
+    val bufferHead = buffer.head
+    takeAllPoolSegments() // Make room for new segments.
+    buffer.clear()
+    assertTrue(bufferHead !in takeAllPoolSegments())
+  }
+
+  /**
+   * Clones share their backing byte arrays with the source buffers. Those byte arrays must not
+   * be recycled, otherwise the new writer could corrupt the segment.
+   */
+  @Test fun cloneSegmentsAreNotRecycled() {
+    val buffer = bufferWithSegments(xs, ys, zs)
+    val clone = buffer.clone()
+
+    // While locking the pool, confirm that clearing the buffer doesn't release its segments.
+    val bufferHead = buffer.head!!
+    takeAllPoolSegments() // Make room for new segments.
+    buffer.clear()
+    assertTrue(bufferHead !in takeAllPoolSegments())
+
+    val cloneHead = clone.head!!
+    takeAllPoolSegments() // Make room for new segments.
+    clone.clear()
+    assertTrue(cloneHead !in takeAllPoolSegments())
+  }
+
+  @Test fun snapshotJavaSerialization() {
+    val byteString = bufferWithSegments(xs, ys, zs).snapshot()
+    assertEquivalent(byteString, TestUtil.reserialize(byteString))
+  }
+
+  @Test fun clonesAreEquivalent() {
+    val bufferA = bufferWithSegments(xs, ys, zs)
+    val bufferB = bufferA.clone()
+    assertEquivalent(bufferA, bufferB)
+    assertEquivalent(bufferA, bufferWithSegments(xs + ys, zs))
+  }
+
+  /** Even though some segments are shared, clones can be mutated independently.  */
+  @Test fun mutateAfterClone() {
+    val bufferA = Buffer()
+    bufferA.writeUtf8("abc")
+    val bufferB = bufferA.clone()
+    bufferA.writeUtf8("def")
+    bufferB.writeUtf8("DEF")
+    assertEquals("abcdef", bufferA.readUtf8())
+    assertEquals("abcDEF", bufferB.readUtf8())
+  }
+
+  @Test fun concatenateSegmentsCanCombine() {
+    val bufferA = Buffer().writeUtf8(ys).writeUtf8(us)
+    assertEquals(ys, bufferA.readUtf8(ys.length.toLong()))
+    val bufferB = Buffer().writeUtf8(vs).writeUtf8(ws)
+    val bufferC = bufferA.clone()
+    bufferA.write(bufferB, vs.length.toLong())
+    bufferC.writeUtf8(xs)
+
+    assertEquals(us + vs, bufferA.readUtf8())
+    assertEquals(ws, bufferB.readUtf8())
+    assertEquals(us + xs, bufferC.readUtf8())
+  }
+
+  @Test fun shareAndSplit() {
+    val bufferA = Buffer().writeUtf8("xxxx")
+    val snapshot = bufferA.snapshot() // Share the segment.
+    val bufferB = Buffer()
+    bufferB.write(bufferA, 2) // Split the shared segment in two.
+    bufferB.writeUtf8("yy") // Append to the first half of the shared segment.
+    assertEquals("xxxx", snapshot.utf8())
+  }
+
+  @Test fun appendSnapshotToEmptyBuffer() {
+    val bufferA = bufferWithSegments(xs, ys)
+    val snapshot = bufferA.snapshot()
+    val bufferB = Buffer()
+    bufferB.write(snapshot)
+    assertEquivalent(bufferB, bufferA)
+  }
+
+  @Test fun appendSnapshotToNonEmptyBuffer() {
+    val bufferA = bufferWithSegments(xs, ys)
+    val snapshot = bufferA.snapshot()
+    val bufferB = Buffer().writeUtf8(us)
+    bufferB.write(snapshot)
+    assertEquivalent(bufferB, Buffer().writeUtf8(us + xs + ys))
+  }
+
+  @Test fun copyToSegmentSharing() {
+    val bufferA = bufferWithSegments(ws, xs + "aaaa", ys, "bbbb$zs")
+    val bufferB = bufferWithSegments(us)
+    bufferA.copyTo(bufferB, (ws.length + xs.length).toLong(), (4 + ys.length + 4).toLong())
+    assertEquivalent(bufferB, Buffer().writeUtf8(us + "aaaa" + ys + "bbbb"))
+  }
+}
+
+private val us = "u".repeat(Segment.SIZE / 2 - 2)
+private val vs = "v".repeat(Segment.SIZE / 2 - 1)
+private val ws = "w".repeat(Segment.SIZE / 2)
+private val xs = "x".repeat(Segment.SIZE / 2 + 1)
+private val ys = "y".repeat(Segment.SIZE / 2 + 2)
+private val zs = "z".repeat(Segment.SIZE / 2 + 3)
diff --git a/okio/src/jvmTest/kotlin/okio/Stopwatch.kt b/okio/src/jvmTest/kotlin/okio/Stopwatch.kt
new file mode 100644
index 0000000..4f4a022
--- /dev/null
+++ b/okio/src/jvmTest/kotlin/okio/Stopwatch.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+import org.assertj.core.api.Assertions.assertThat
+import org.assertj.core.api.Assertions.within
+
+/** Stopwatch for asserting elapsed time during unit tests. */
+internal class Stopwatch {
+  private val start = System.nanoTime() / 1e9
+  private var offset = 0.0
+
+  /**
+   * Fails the test unless the time from the last assertion until now is `elapsed`, accepting
+   * differences in -200..+200 milliseconds.
+   */
+  fun assertElapsed(elapsed: Double) {
+    offset += elapsed
+    assertThat(System.nanoTime() / 1e9 - start).isCloseTo(offset, within(0.2))
+  }
+}
diff --git a/okio/src/jvmTest/kotlin/okio/TestUtil.kt b/okio/src/jvmTest/kotlin/okio/TestUtil.kt
new file mode 100644
index 0000000..f9f61e6
--- /dev/null
+++ b/okio/src/jvmTest/kotlin/okio/TestUtil.kt
@@ -0,0 +1,302 @@
+/*
+ * 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 okio
+
+import okio.ByteString.Companion.encodeUtf8
+import org.junit.Assume
+import java.io.IOException
+import java.io.ObjectInputStream
+import java.io.ObjectOutputStream
+import java.io.Serializable
+import java.util.Random
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+
+object TestUtil {
+  // Necessary to make an internal member visible to Java.
+  @JvmField val SEGMENT_POOL_MAX_SIZE = SegmentPool.MAX_SIZE
+  const val SEGMENT_SIZE = Segment.SIZE
+  const val REPLACEMENT_CODE_POINT: Int = okio.REPLACEMENT_CODE_POINT
+
+  @JvmStatic fun segmentPoolByteCount() = SegmentPool.byteCount
+
+  @JvmStatic
+  fun segmentSizes(buffer: Buffer): List<Int> = okio.segmentSizes(buffer)
+
+  @JvmStatic
+  fun assertNoEmptySegments(buffer: Buffer) {
+    assertTrue(segmentSizes(buffer).all { it != 0 }, "Expected all segments to be non-empty")
+  }
+
+  @JvmStatic
+  fun assertByteArraysEquals(a: ByteArray, b: ByteArray) {
+    assertEquals(a.contentToString(), b.contentToString())
+  }
+
+  @JvmStatic
+  fun assertByteArrayEquals(expectedUtf8: String, b: ByteArray) {
+    assertEquals(expectedUtf8, b.toString(Charsets.UTF_8))
+  }
+
+  @JvmStatic
+  fun randomBytes(length: Int): ByteString {
+    val random = Random(0)
+    val randomBytes = ByteArray(length)
+    random.nextBytes(randomBytes)
+    return ByteString.of(*randomBytes)
+  }
+
+  @JvmStatic
+  fun randomSource(size: Long): Source {
+    return object : Source {
+      internal var random = Random(0)
+      internal var bytesLeft = size
+      internal var closed: Boolean = false
+
+      @Throws(IOException::class)
+      override fun read(sink: Buffer, byteCount: Long): Long {
+        var byteCount = byteCount
+        if (closed) throw IllegalStateException("closed")
+        if (bytesLeft == 0L) return -1L
+        if (byteCount > bytesLeft) byteCount = bytesLeft
+
+        // If we can read a full segment we can save a copy.
+        if (byteCount >= Segment.SIZE) {
+          val segment = sink.writableSegment(Segment.SIZE)
+          random.nextBytes(segment.data)
+          segment.limit += Segment.SIZE
+          sink.size += Segment.SIZE.toLong()
+          bytesLeft -= Segment.SIZE.toLong()
+          return Segment.SIZE.toLong()
+        } else {
+          val data = ByteArray(byteCount.toInt())
+          random.nextBytes(data)
+          sink.write(data)
+          bytesLeft -= byteCount
+          return byteCount
+        }
+      }
+
+      override fun timeout() = Timeout.NONE
+
+      @Throws(IOException::class)
+      override fun close() {
+        closed = true
+      }
+    }
+  }
+
+  @JvmStatic
+  fun assertEquivalent(b1: ByteString, b2: ByteString) {
+    // Equals.
+    assertTrue(b1 == b2)
+    assertTrue(b1 == b1)
+    assertTrue(b2 == b1)
+
+    // Hash code.
+    assertEquals(b1.hashCode().toLong(), b2.hashCode().toLong())
+    assertEquals(b1.hashCode().toLong(), b1.hashCode().toLong())
+    assertEquals(b1.toString(), b2.toString())
+
+    // Content.
+    assertEquals(b1.size.toLong(), b2.size.toLong())
+    val b2Bytes = b2.toByteArray()
+    for (i in b2Bytes.indices) {
+      val b = b2Bytes[i]
+      assertEquals(b.toLong(), b1[i].toLong())
+    }
+    assertByteArraysEquals(b1.toByteArray(), b2Bytes)
+
+    // Doesn't equal a different byte string.
+    assertFalse(b1 == null)
+    assertFalse(b1 == Any())
+    if (b2Bytes.size > 0) {
+      val b3Bytes = b2Bytes.clone()
+      b3Bytes[b3Bytes.size - 1]++
+      val b3 = ByteString(b3Bytes)
+      assertFalse(b1 == b3)
+      assertFalse(b1.hashCode() == b3.hashCode())
+    } else {
+      val b3 = "a".encodeUtf8()
+      assertFalse(b1 == b3)
+      assertFalse(b1.hashCode() == b3.hashCode())
+    }
+  }
+
+  @JvmStatic
+  fun assertEquivalent(b1: Buffer, b2: Buffer) {
+    // Equals.
+    assertTrue(b1 == b2)
+    assertTrue(b1 == b1)
+    assertTrue(b2 == b1)
+
+    // Hash code.
+    assertEquals(b1.hashCode().toLong(), b2.hashCode().toLong())
+    assertEquals(b1.hashCode().toLong(), b1.hashCode().toLong())
+    assertEquals(b1.toString(), b2.toString())
+
+    // Content.
+    assertEquals(b1.size, b2.size)
+    val buffer = Buffer()
+    b2.copyTo(buffer, 0, b2.size)
+    val b2Bytes = b2.readByteArray()
+    for (i in b2Bytes.indices) {
+      val b = b2Bytes[i]
+      assertEquals(b.toLong(), b1[i.toLong()].toLong())
+    }
+
+    // Doesn't equal a different buffer.
+    assertFalse(b1 == Any())
+    if (b2Bytes.size > 0) {
+      val b3Bytes = b2Bytes.clone()
+      b3Bytes[b3Bytes.size - 1]++
+      val b3 = Buffer().write(b3Bytes)
+      assertFalse(b1 == b3)
+      assertFalse(b1.hashCode() == b3.hashCode())
+    } else {
+      val b3 = Buffer().writeUtf8("a")
+      assertFalse(b1 == b3)
+      assertFalse(b1.hashCode() == b3.hashCode())
+    }
+  }
+
+  /** Serializes original to bytes, then deserializes those bytes and returns the result.  */
+  @Suppress("UNCHECKED_CAST")
+  @Throws(Exception::class)
+  @JvmStatic
+  // Assume serialization doesn't change types.
+  fun <T : Serializable> reserialize(original: T): T {
+    val buffer = Buffer()
+    val out = ObjectOutputStream(buffer.outputStream())
+    out.writeObject(original)
+    val input = ObjectInputStream(buffer.inputStream())
+    return input.readObject() as T
+  }
+
+  /**
+   * Returns a new buffer containing the data in `data` and a segment
+   * layout determined by `dice`.
+   */
+  @Throws(IOException::class)
+  @JvmStatic
+  fun bufferWithRandomSegmentLayout(dice: Random, data: ByteArray): Buffer {
+    val result = Buffer()
+
+    // Writing to result directly will yield packed segments. Instead, write to
+    // other buffers, then write those buffers to result.
+    var pos = 0
+    var byteCount: Int
+    while (pos < data.size) {
+      byteCount = Segment.SIZE / 2 + dice.nextInt(Segment.SIZE / 2)
+      if (byteCount > data.size - pos) byteCount = data.size - pos
+      val offset = dice.nextInt(Segment.SIZE - byteCount)
+
+      val segment = Buffer()
+      segment.write(ByteArray(offset))
+      segment.write(data, pos, byteCount)
+      segment.skip(offset.toLong())
+
+      result.write(segment, byteCount.toLong())
+      pos += byteCount
+    }
+
+    return result
+  }
+
+  /**
+   * Returns a new buffer containing the contents of `segments`, attempting to isolate each
+   * string to its own segment in the returned buffer. This clones buffers so that segments are
+   * shared, preventing compaction from occurring.
+   */
+  @Throws(Exception::class)
+  @JvmStatic
+  fun bufferWithSegments(vararg segments: String): Buffer {
+    val result = Buffer()
+    for (s in segments) {
+      val offsetInSegment = if (s.length < Segment.SIZE) (Segment.SIZE - s.length) / 2 else 0
+      val buffer = Buffer()
+      buffer.writeUtf8("_".repeat(offsetInSegment))
+      buffer.writeUtf8(s)
+      buffer.skip(offsetInSegment.toLong())
+      result.write(buffer.clone(), buffer.size)
+    }
+    return result
+  }
+
+  @JvmStatic
+  fun makeSegments(source: ByteString): ByteString {
+    val buffer = Buffer()
+    for (i in 0 until source.size) {
+      val segment = buffer.writableSegment(SEGMENT_SIZE)
+      segment.data[segment.pos] = source[i]
+      segment.limit++
+      buffer.size++
+    }
+    return buffer.snapshot()
+  }
+
+  /** Remove all segments from the pool and return them as a list. */
+  @JvmStatic
+  internal fun takeAllPoolSegments(): List<Segment> {
+    val result = mutableListOf<Segment>()
+    while (SegmentPool.byteCount > 0) {
+      result += SegmentPool.take()
+    }
+    return result
+  }
+
+  /** Returns a copy of `buffer` with no segments with `original`.  */
+  @JvmStatic
+  fun deepCopy(original: Buffer): Buffer {
+    val result = Buffer()
+    if (original.size == 0L) return result
+
+    result.head = original.head!!.unsharedCopy()
+    result.head!!.prev = result.head
+    result.head!!.next = result.head!!.prev
+    var s = original.head!!.next
+    while (s !== original.head) {
+      result.head!!.prev!!.push(s!!.unsharedCopy())
+      s = s.next
+    }
+    result.size = original.size
+
+    return result
+  }
+
+  @JvmStatic
+  fun Int.reverseBytes(): Int {
+    /* ktlint-disable no-multi-spaces indent */
+    return (this and -0x1000000 ushr 24) or
+      (this and 0x00ff0000 ushr  8) or
+      (this and 0x0000ff00  shl  8) or
+      (this and 0x000000ff  shl 24)
+    /* ktlint-enable no-multi-spaces indent */
+  }
+
+  @JvmStatic
+  fun Short.reverseBytes(): Short {
+    val i = toInt() and 0xffff
+    /* ktlint-disable no-multi-spaces indent */
+    val reversed = (i and 0xff00 ushr 8) or
+      (i and 0x00ff  shl 8)
+    /* ktlint-enable no-multi-spaces indent */
+    return reversed.toShort()
+  }
+
+  fun assumeNotWindows() = Assume.assumeFalse(System.getProperty("os.name").toLowerCase().contains("win"))
+}
diff --git a/okio/src/jvmTest/kotlin/okio/ThrottlerTakeTest.kt b/okio/src/jvmTest/kotlin/okio/ThrottlerTakeTest.kt
new file mode 100644
index 0000000..aab94b3
--- /dev/null
+++ b/okio/src/jvmTest/kotlin/okio/ThrottlerTakeTest.kt
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+import org.assertj.core.api.Assertions.assertThat
+import org.junit.Test
+import java.util.concurrent.TimeUnit
+
+class ThrottlerTakeTest {
+  private var nowNanos = 0L
+  private var elapsedNanos = 0L
+  private val throttler = Throttler(allocatedUntil = nowNanos)
+
+  @Test fun takeByByteCount() {
+    throttler.bytesPerSecond(bytesPerSecond = 20, waitByteCount = 5, maxByteCount = 10)
+
+    // We get the first 10 bytes immediately (that's maxByteCount).
+    assertThat(take(100L)).isEqualTo(10L)
+    assertElapsed(0L)
+
+    // Wait a quarter second for each subsequent 5 bytes (that's waitByteCount).
+    assertThat(take(100L)).isEqualTo(5L)
+    assertElapsed(250L)
+
+    assertThat(take(100L)).isEqualTo(5L)
+    assertElapsed(250L)
+
+    // Wait three quarters of a second to build up 15 bytes of potential.
+    // Since maxByteCount = 10, there will only be 10 bytes of potential.
+    sleep(750L)
+    assertElapsed(750L)
+
+    // We get 10 bytes immediately (that's maxByteCount again).
+    assertThat(take(100L)).isEqualTo(10L)
+    assertElapsed(0L)
+
+    // Wait a quarter second for each subsequent 5 bytes (that's waitByteCount again).
+    assertThat(take(100L)).isEqualTo(5L)
+    assertElapsed(250L)
+  }
+
+  @Test fun takeFullyTimeElapsed() {
+    throttler.bytesPerSecond(bytesPerSecond = 20, waitByteCount = 5, maxByteCount = 10)
+
+    // We write the first 10 bytes immediately (that's maxByteCount again).
+    takeFully(10L)
+    assertElapsed(0L)
+
+    // Wait a quarter second for each subsequent 5 bytes (that's waitByteCount).
+    takeFully(5L)
+    assertElapsed(250L)
+
+    // Wait a half second for 10 bytes.
+    takeFully(10L)
+    assertElapsed(500L)
+
+    // Wait a three quarters of a second to build up 15 bytes of potential.
+    // Since maxByteCount = 10, there will only be 10 bytes of potential.
+    sleep(750L)
+    assertElapsed(750L)
+
+    // We write the first 10 bytes immediately (that's maxByteCount again).
+    // Wait a quarter second for each subsequent 5 bytes (that's waitByteCount again).
+    takeFully(15L)
+    assertElapsed(250L)
+  }
+
+  @Test fun takeFullyWhenSaturated() {
+    throttler.bytesPerSecond(400L, 5L, 10L)
+
+    // Saturate the throttler.
+    assertThat(take(10L)).isEqualTo(10L)
+    assertElapsed(0L)
+
+    // At 400 bytes per second it takes 250 ms to read 100 bytes.
+    takeFully(100L)
+    assertElapsed(250L)
+  }
+
+  @Test fun takeFullyNoLimit() {
+    throttler.bytesPerSecond(0L, 5L, 10L)
+    takeFully(100L)
+    assertElapsed(0L)
+  }
+
+  /**
+   * We had a bug where integer division truncation would cause us to call wait() for 0 nanos. We
+   * fixed it by minimizing integer division generally, and by handling that case specifically.
+   */
+  @Test fun infiniteWait() {
+    throttler.bytesPerSecond(3, maxByteCount = 4, waitByteCount = 4)
+    takeFully(7)
+    assertElapsed(1000L)
+  }
+
+  /** Take at least the minimum and up to `byteCount` bytes, sleeping once if necessary. */
+  private fun take(byteCount: Long): Long {
+    val byteCountOrWaitNanos = throttler.byteCountOrWaitNanos(nowNanos, byteCount)
+    if (byteCountOrWaitNanos >= 0L) return byteCountOrWaitNanos
+
+    nowNanos += -byteCountOrWaitNanos
+
+    val resultAfterWait = throttler.byteCountOrWaitNanos(nowNanos, byteCount)
+    assertThat(resultAfterWait).isGreaterThan(0L)
+    return resultAfterWait
+  }
+
+  /** Take all of `byteCount` bytes, advancing the clock until they're all taken. */
+  private fun takeFully(byteCount: Long) {
+    var remaining = byteCount
+    while (remaining > 0L) {
+      val byteCountOrWaitNanos = throttler.byteCountOrWaitNanos(nowNanos, remaining)
+      if (byteCountOrWaitNanos >= 0L) {
+        remaining -= byteCountOrWaitNanos
+      } else {
+        nowNanos += -byteCountOrWaitNanos
+      }
+    }
+  }
+
+  private fun assertElapsed(millis: Long) {
+    elapsedNanos += TimeUnit.MILLISECONDS.toNanos(millis)
+    assertThat(nowNanos).isEqualTo(elapsedNanos)
+  }
+
+  private fun sleep(millis: Long) {
+    nowNanos += TimeUnit.MILLISECONDS.toNanos(millis)
+  }
+}
diff --git a/okio/src/jvmTest/kotlin/okio/ThrottlerTest.kt b/okio/src/jvmTest/kotlin/okio/ThrottlerTest.kt
new file mode 100644
index 0000000..0b15179
--- /dev/null
+++ b/okio/src/jvmTest/kotlin/okio/ThrottlerTest.kt
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+import okio.TestUtil.randomSource
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import java.util.concurrent.Executors
+import kotlin.test.Ignore
+
+@Ignore("These tests are flaky and fail on slower hardware, need to be improved")
+class ThrottlerTest {
+  private val size = 1024L * 80L // 80 KiB
+  private val source = randomSource(size)
+
+  private val throttler = Throttler()
+  private val throttlerSlow = Throttler()
+
+  private val threads = 4
+  private val executorService = Executors.newFixedThreadPool(threads)
+  private var stopwatch = Stopwatch()
+
+  @Before fun setup() {
+    throttler.bytesPerSecond(4 * size, 4096, 8192)
+    throttlerSlow.bytesPerSecond(2 * size, 4096, 8192)
+    stopwatch = Stopwatch()
+  }
+
+  @After fun teardown() {
+    executorService.shutdown()
+  }
+
+  @Test fun source() {
+    throttler.source(source).buffer().readAll(blackholeSink())
+    stopwatch.assertElapsed(0.25)
+  }
+
+  @Test fun sink() {
+    source.buffer().readAll(throttler.sink(blackholeSink()))
+    stopwatch.assertElapsed(0.25)
+  }
+
+  @Test fun doubleSourceThrottle() {
+    throttler.source(throttler.source(source)).buffer().readAll(blackholeSink())
+    stopwatch.assertElapsed(0.5)
+  }
+
+  @Test fun doubleSinkThrottle() {
+    source.buffer().readAll(throttler.sink(throttler.sink(blackholeSink())))
+    stopwatch.assertElapsed(0.5)
+  }
+
+  @Test fun singleSourceMultiThrottleSlowerThenSlow() {
+    source.buffer().readAll(throttler.sink(throttlerSlow.sink(blackholeSink())))
+    stopwatch.assertElapsed(0.5)
+  }
+
+  @Test fun singleSourceMultiThrottleSlowThenSlower() {
+    source.buffer().readAll(throttlerSlow.sink(throttler.sink(blackholeSink())))
+    stopwatch.assertElapsed(0.5)
+  }
+
+  @Test fun slowSourceSlowerSink() {
+    throttler.source(source).buffer().readAll(throttlerSlow.sink(blackholeSink()))
+    stopwatch.assertElapsed(0.5)
+  }
+
+  @Test fun slowSinkSlowerSource() {
+    throttlerSlow.source(source).buffer().readAll(throttler.sink(blackholeSink()))
+    stopwatch.assertElapsed(0.5)
+  }
+
+  @Test fun parallel() {
+    val futures = List(threads) {
+      executorService.submit {
+        val source = randomSource(size)
+        source.buffer().readAll(throttler.sink(blackholeSink()))
+      }
+    }
+    for (future in futures) {
+      future.get()
+    }
+    stopwatch.assertElapsed(1.0)
+  }
+
+  @Test fun parallelFastThenSlower() {
+    val futures = List(threads) {
+      executorService.submit {
+        val source = randomSource(size)
+        source.buffer().readAll(throttler.sink(blackholeSink()))
+      }
+    }
+    Thread.sleep(500)
+    throttler.bytesPerSecond(2 * size)
+    for (future in futures) {
+      future.get()
+    }
+    stopwatch.assertElapsed(1.5)
+  }
+
+  @Test fun parallelSlowThenFaster() {
+    val futures = List(threads) {
+      executorService.submit {
+        val source = randomSource(size)
+        source.buffer().readAll(throttlerSlow.sink(blackholeSink()))
+      }
+    }
+    Thread.sleep(1_000)
+    throttlerSlow.bytesPerSecond(4 * size)
+    for (future in futures) {
+      future.get()
+    }
+    stopwatch.assertElapsed(1.5)
+  }
+
+  @Test fun parallelIndividualThrottle() {
+    val futures = List(threads) {
+      executorService.submit {
+        val throttlerLocal = Throttler()
+        throttlerLocal.bytesPerSecond(4 * size, maxByteCount = 8192)
+
+        val source = randomSource(size)
+        source.buffer().readAll(throttlerLocal.sink(blackholeSink()))
+      }
+    }
+    for (future in futures) {
+      future.get()
+    }
+    stopwatch.assertElapsed(0.25)
+  }
+
+  @Test fun parallelGroupAndIndividualThrottle() {
+    val futures = List(threads) {
+      executorService.submit {
+        val throttlerLocal = Throttler()
+        throttlerLocal.bytesPerSecond(4 * size, maxByteCount = 8192)
+
+        val source = randomSource(size)
+        source.buffer().readAll(throttler.sink(throttlerLocal.sink(blackholeSink())))
+      }
+    }
+    for (future in futures) {
+      future.get()
+    }
+    stopwatch.assertElapsed(1.0)
+  }
+}
diff --git a/okio/src/nonJvmMain/kotlin/okio/-Platform.kt b/okio/src/nonJvmMain/kotlin/okio/-Platform.kt
new file mode 100644
index 0000000..90fcd36
--- /dev/null
+++ b/okio/src/nonJvmMain/kotlin/okio/-Platform.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+import okio.internal.commonAsUtf8ToByteArray
+import okio.internal.commonToUtf8String
+
+internal actual fun ByteArray.toUtf8String(): String = commonToUtf8String()
+
+internal actual fun String.asUtf8ToByteArray(): ByteArray = commonAsUtf8ToByteArray()
+
+actual open class ArrayIndexOutOfBoundsException actual constructor(
+  message: String?
+) : IndexOutOfBoundsException(message)
+
+internal actual inline fun <R> synchronized(lock: Any, block: () -> R): R = block()
+
+actual open class IOException actual constructor(
+  message: String?,
+  cause: Throwable?
+) : Exception(message, cause) {
+  actual constructor(message: String?) : this(message, null)
+}
+
+actual open class EOFException actual constructor(message: String?) : IOException(message)
+
+actual open class FileNotFoundException actual constructor(message: String?) : IOException(message)
+
+actual interface Closeable {
+  @Throws(IOException::class)
+  actual fun close()
+}
diff --git a/okio/src/nonJvmMain/kotlin/okio/Buffer.kt b/okio/src/nonJvmMain/kotlin/okio/Buffer.kt
new file mode 100644
index 0000000..ec28f63
--- /dev/null
+++ b/okio/src/nonJvmMain/kotlin/okio/Buffer.kt
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+import okio.internal.HashFunction
+import okio.internal.Hmac
+import okio.internal.Md5
+import okio.internal.Sha1
+import okio.internal.Sha256
+import okio.internal.Sha512
+import okio.internal.commonClear
+import okio.internal.commonClose
+import okio.internal.commonCompleteSegmentByteCount
+import okio.internal.commonCopy
+import okio.internal.commonCopyTo
+import okio.internal.commonEquals
+import okio.internal.commonExpandBuffer
+import okio.internal.commonGet
+import okio.internal.commonHashCode
+import okio.internal.commonIndexOf
+import okio.internal.commonIndexOfElement
+import okio.internal.commonNext
+import okio.internal.commonRangeEquals
+import okio.internal.commonRead
+import okio.internal.commonReadAll
+import okio.internal.commonReadAndWriteUnsafe
+import okio.internal.commonReadByte
+import okio.internal.commonReadByteArray
+import okio.internal.commonReadByteString
+import okio.internal.commonReadDecimalLong
+import okio.internal.commonReadFully
+import okio.internal.commonReadHexadecimalUnsignedLong
+import okio.internal.commonReadInt
+import okio.internal.commonReadLong
+import okio.internal.commonReadShort
+import okio.internal.commonReadUnsafe
+import okio.internal.commonReadUtf8
+import okio.internal.commonReadUtf8CodePoint
+import okio.internal.commonReadUtf8Line
+import okio.internal.commonReadUtf8LineStrict
+import okio.internal.commonResizeBuffer
+import okio.internal.commonSeek
+import okio.internal.commonSelect
+import okio.internal.commonSkip
+import okio.internal.commonSnapshot
+import okio.internal.commonWritableSegment
+import okio.internal.commonWrite
+import okio.internal.commonWriteAll
+import okio.internal.commonWriteByte
+import okio.internal.commonWriteDecimalLong
+import okio.internal.commonWriteHexadecimalUnsignedLong
+import okio.internal.commonWriteInt
+import okio.internal.commonWriteLong
+import okio.internal.commonWriteShort
+import okio.internal.commonWriteUtf8
+import okio.internal.commonWriteUtf8CodePoint
+
+actual class Buffer : BufferedSource, BufferedSink {
+  internal actual var head: Segment? = null
+
+  actual var size: Long = 0L
+    internal set
+
+  actual override val buffer: Buffer get() = this
+
+  actual override fun emitCompleteSegments(): Buffer = this // Nowhere to emit to!
+
+  actual override fun emit(): Buffer = this // Nowhere to emit to!
+
+  override fun exhausted(): Boolean = size == 0L
+
+  override fun require(byteCount: Long) {
+    if (size < byteCount) throw EOFException(null)
+  }
+
+  override fun request(byteCount: Long): Boolean = size >= byteCount
+
+  override fun peek(): BufferedSource = PeekSource(this).buffer()
+
+  actual fun copyTo(
+    out: Buffer,
+    offset: Long,
+    byteCount: Long
+  ): Buffer = commonCopyTo(out, offset, byteCount)
+
+  actual fun copyTo(
+    out: Buffer,
+    offset: Long
+  ): Buffer = copyTo(out, offset, size - offset)
+
+  actual operator fun get(pos: Long): Byte = commonGet(pos)
+
+  actual fun completeSegmentByteCount(): Long = commonCompleteSegmentByteCount()
+
+  override fun readByte(): Byte = commonReadByte()
+
+  override fun readShort(): Short = commonReadShort()
+
+  override fun readInt(): Int = commonReadInt()
+
+  override fun readLong(): Long = commonReadLong()
+
+  override fun readShortLe(): Short = readShort().reverseBytes()
+
+  override fun readIntLe(): Int = readInt().reverseBytes()
+
+  override fun readLongLe(): Long = readLong().reverseBytes()
+
+  override fun readDecimalLong(): Long = commonReadDecimalLong()
+
+  override fun readHexadecimalUnsignedLong(): Long = commonReadHexadecimalUnsignedLong()
+
+  override fun readByteString(): ByteString = commonReadByteString()
+
+  override fun readByteString(byteCount: Long): ByteString = commonReadByteString(byteCount)
+
+  override fun readFully(sink: Buffer, byteCount: Long): Unit = commonReadFully(sink, byteCount)
+
+  override fun readAll(sink: Sink): Long = commonReadAll(sink)
+
+  override fun readUtf8(): String = readUtf8(size)
+
+  override fun readUtf8(byteCount: Long): String = commonReadUtf8(byteCount)
+
+  override fun readUtf8Line(): String? = commonReadUtf8Line()
+
+  override fun readUtf8LineStrict(): String = readUtf8LineStrict(Long.MAX_VALUE)
+
+  override fun readUtf8LineStrict(limit: Long): String = commonReadUtf8LineStrict(limit)
+
+  override fun readUtf8CodePoint(): Int = commonReadUtf8CodePoint()
+
+  override fun select(options: Options): Int = commonSelect(options)
+
+  override fun readByteArray(): ByteArray = commonReadByteArray()
+
+  override fun readByteArray(byteCount: Long): ByteArray = commonReadByteArray(byteCount)
+
+  override fun read(sink: ByteArray): Int = commonRead(sink)
+
+  override fun readFully(sink: ByteArray): Unit = commonReadFully(sink)
+
+  override fun read(sink: ByteArray, offset: Int, byteCount: Int): Int =
+    commonRead(sink, offset, byteCount)
+
+  actual fun clear(): Unit = commonClear()
+
+  actual override fun skip(byteCount: Long): Unit = commonSkip(byteCount)
+
+  actual override fun write(byteString: ByteString): Buffer = commonWrite(byteString)
+
+  actual override fun write(byteString: ByteString, offset: Int, byteCount: Int) =
+    commonWrite(byteString, offset, byteCount)
+
+  internal actual fun writableSegment(minimumCapacity: Int): Segment =
+    commonWritableSegment(minimumCapacity)
+
+  actual override fun writeUtf8(string: String): Buffer = writeUtf8(string, 0, string.length)
+
+  actual override fun writeUtf8(string: String, beginIndex: Int, endIndex: Int): Buffer =
+    commonWriteUtf8(string, beginIndex, endIndex)
+
+  actual override fun writeUtf8CodePoint(codePoint: Int): Buffer =
+    commonWriteUtf8CodePoint(codePoint)
+
+  actual override fun write(source: ByteArray): Buffer = commonWrite(source)
+
+  actual override fun write(source: ByteArray, offset: Int, byteCount: Int): Buffer =
+    commonWrite(source, offset, byteCount)
+
+  override fun writeAll(source: Source): Long = commonWriteAll(source)
+
+  actual override fun write(source: Source, byteCount: Long): Buffer =
+    commonWrite(source, byteCount)
+
+  actual override fun writeByte(b: Int): Buffer = commonWriteByte(b)
+
+  actual override fun writeShort(s: Int): Buffer = commonWriteShort(s)
+
+  actual override fun writeShortLe(s: Int): Buffer = writeShort(s.toShort().reverseBytes().toInt())
+
+  actual override fun writeInt(i: Int): Buffer = commonWriteInt(i)
+
+  actual override fun writeIntLe(i: Int): Buffer = writeInt(i.reverseBytes())
+
+  actual override fun writeLong(v: Long): Buffer = commonWriteLong(v)
+
+  actual override fun writeLongLe(v: Long): Buffer = writeLong(v.reverseBytes())
+
+  actual override fun writeDecimalLong(v: Long): Buffer = commonWriteDecimalLong(v)
+
+  actual override fun writeHexadecimalUnsignedLong(v: Long): Buffer =
+    commonWriteHexadecimalUnsignedLong(v)
+
+  override fun write(source: Buffer, byteCount: Long): Unit = commonWrite(source, byteCount)
+
+  override fun read(sink: Buffer, byteCount: Long): Long = commonRead(sink, byteCount)
+
+  override fun indexOf(b: Byte): Long = indexOf(b, 0, Long.MAX_VALUE)
+
+  override fun indexOf(b: Byte, fromIndex: Long): Long = indexOf(b, fromIndex, Long.MAX_VALUE)
+
+  override fun indexOf(b: Byte, fromIndex: Long, toIndex: Long): Long =
+    commonIndexOf(b, fromIndex, toIndex)
+
+  override fun indexOf(bytes: ByteString): Long = indexOf(bytes, 0)
+
+  override fun indexOf(bytes: ByteString, fromIndex: Long): Long = commonIndexOf(bytes, fromIndex)
+
+  override fun indexOfElement(targetBytes: ByteString): Long = indexOfElement(targetBytes, 0L)
+
+  override fun indexOfElement(targetBytes: ByteString, fromIndex: Long): Long =
+    commonIndexOfElement(targetBytes, fromIndex)
+
+  override fun rangeEquals(offset: Long, bytes: ByteString): Boolean =
+    rangeEquals(offset, bytes, 0, bytes.size)
+
+  override fun rangeEquals(
+    offset: Long,
+    bytes: ByteString,
+    bytesOffset: Int,
+    byteCount: Int
+  ): Boolean = commonRangeEquals(offset, bytes, bytesOffset, byteCount)
+
+  override fun flush() = Unit
+
+  override fun close() = Unit
+
+  override fun timeout(): Timeout = Timeout.NONE
+
+  override fun equals(other: Any?): Boolean = commonEquals(other)
+
+  override fun hashCode(): Int = commonHashCode()
+
+  /**
+   * Returns a human-readable string that describes the contents of this buffer. Typically this
+   * is a string like `[text=Hello]` or `[hex=0000ffff]`.
+   */
+  override fun toString() = snapshot().toString()
+
+  actual fun copy(): Buffer = commonCopy()
+
+  actual fun snapshot(): ByteString = commonSnapshot()
+
+  actual fun snapshot(byteCount: Int): ByteString = commonSnapshot(byteCount)
+
+  actual fun md5() = digest(Md5())
+
+  actual fun sha1() = digest(Sha1())
+
+  actual fun sha256() = digest(Sha256())
+
+  actual fun sha512() = digest(Sha512())
+
+  /** Returns the 160-bit SHA-1 HMAC of this buffer.  */
+  actual fun hmacSha1(key: ByteString) = digest(Hmac.sha1(key))
+
+  /** Returns the 256-bit SHA-256 HMAC of this buffer.  */
+  actual fun hmacSha256(key: ByteString) = digest(Hmac.sha256(key))
+
+  /** Returns the 512-bit SHA-512 HMAC of this buffer.  */
+  actual fun hmacSha512(key: ByteString) = digest(Hmac.sha512(key))
+
+  private fun digest(hash: HashFunction): ByteString {
+    forEachSegment { segment ->
+      hash.update(segment.data, segment.pos, segment.limit - segment.pos)
+    }
+
+    return ByteString(hash.digest())
+  }
+
+  private fun forEachSegment(action: (Segment) -> Unit) {
+    head?.let { head ->
+      var segment: Segment? = head
+      do {
+        segment?.let(action)
+        segment = segment?.next
+      } while (segment !== head)
+    }
+  }
+
+  actual fun readUnsafe(unsafeCursor: UnsafeCursor): UnsafeCursor = commonReadUnsafe(unsafeCursor)
+
+  actual fun readAndWriteUnsafe(unsafeCursor: UnsafeCursor): UnsafeCursor =
+    commonReadAndWriteUnsafe(unsafeCursor)
+
+  actual class UnsafeCursor {
+    actual var buffer: Buffer? = null
+    actual var readWrite: Boolean = false
+
+    internal actual var segment: Segment? = null
+    actual var offset = -1L
+    actual var data: ByteArray? = null
+    actual var start = -1
+    actual var end = -1
+
+    actual fun next(): Int = commonNext()
+
+    actual fun seek(offset: Long): Int = commonSeek(offset)
+
+    actual fun resizeBuffer(newSize: Long): Long = commonResizeBuffer(newSize)
+
+    actual fun expandBuffer(minByteCount: Int): Long = commonExpandBuffer(minByteCount)
+
+    actual fun close() {
+      commonClose()
+    }
+  }
+}
diff --git a/okio/src/nonJvmMain/kotlin/okio/BufferedSink.kt b/okio/src/nonJvmMain/kotlin/okio/BufferedSink.kt
new file mode 100644
index 0000000..65d717c
--- /dev/null
+++ b/okio/src/nonJvmMain/kotlin/okio/BufferedSink.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+actual interface BufferedSink : Sink {
+  actual val buffer: Buffer
+
+  actual fun write(byteString: ByteString): BufferedSink
+
+  actual fun write(byteString: ByteString, offset: Int, byteCount: Int): BufferedSink
+
+  actual fun write(source: ByteArray): BufferedSink
+
+  actual fun write(source: ByteArray, offset: Int, byteCount: Int): BufferedSink
+
+  actual fun writeAll(source: Source): Long
+
+  actual fun write(source: Source, byteCount: Long): BufferedSink
+
+  actual fun writeUtf8(string: String): BufferedSink
+
+  actual fun writeUtf8(string: String, beginIndex: Int, endIndex: Int): BufferedSink
+
+  actual fun writeUtf8CodePoint(codePoint: Int): BufferedSink
+
+  actual fun writeByte(b: Int): BufferedSink
+
+  actual fun writeShort(s: Int): BufferedSink
+
+  actual fun writeShortLe(s: Int): BufferedSink
+
+  actual fun writeInt(i: Int): BufferedSink
+
+  actual fun writeIntLe(i: Int): BufferedSink
+
+  actual fun writeLong(v: Long): BufferedSink
+
+  actual fun writeLongLe(v: Long): BufferedSink
+
+  actual fun writeDecimalLong(v: Long): BufferedSink
+
+  actual fun writeHexadecimalUnsignedLong(v: Long): BufferedSink
+
+  actual fun emit(): BufferedSink
+
+  actual fun emitCompleteSegments(): BufferedSink
+}
diff --git a/okio/src/nonJvmMain/kotlin/okio/BufferedSource.kt b/okio/src/nonJvmMain/kotlin/okio/BufferedSource.kt
new file mode 100644
index 0000000..98b7718
--- /dev/null
+++ b/okio/src/nonJvmMain/kotlin/okio/BufferedSource.kt
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+actual interface BufferedSource : Source {
+  actual val buffer: Buffer
+
+  actual fun exhausted(): Boolean
+
+  actual fun require(byteCount: Long)
+
+  actual fun request(byteCount: Long): Boolean
+
+  actual fun readByte(): Byte
+
+  actual fun readShort(): Short
+
+  actual fun readShortLe(): Short
+
+  actual fun readInt(): Int
+
+  actual fun readIntLe(): Int
+
+  actual fun readLong(): Long
+
+  actual fun readLongLe(): Long
+
+  actual fun readDecimalLong(): Long
+
+  actual fun readHexadecimalUnsignedLong(): Long
+
+  actual fun skip(byteCount: Long)
+
+  actual fun readByteString(): ByteString
+
+  actual fun readByteString(byteCount: Long): ByteString
+
+  actual fun select(options: Options): Int
+
+  actual fun readByteArray(): ByteArray
+
+  actual fun readByteArray(byteCount: Long): ByteArray
+
+  actual fun read(sink: ByteArray): Int
+
+  actual fun readFully(sink: ByteArray)
+
+  actual fun read(sink: ByteArray, offset: Int, byteCount: Int): Int
+
+  actual fun readFully(sink: Buffer, byteCount: Long)
+
+  actual fun readAll(sink: Sink): Long
+
+  actual fun readUtf8(): String
+
+  actual fun readUtf8(byteCount: Long): String
+
+  actual fun readUtf8Line(): String?
+
+  actual fun readUtf8LineStrict(): String
+
+  actual fun readUtf8LineStrict(limit: Long): String
+
+  actual fun readUtf8CodePoint(): Int
+
+  actual fun indexOf(b: Byte): Long
+
+  actual fun indexOf(b: Byte, fromIndex: Long): Long
+
+  actual fun indexOf(b: Byte, fromIndex: Long, toIndex: Long): Long
+
+  actual fun indexOf(bytes: ByteString): Long
+
+  actual fun indexOf(bytes: ByteString, fromIndex: Long): Long
+
+  actual fun indexOfElement(targetBytes: ByteString): Long
+
+  actual fun indexOfElement(targetBytes: ByteString, fromIndex: Long): Long
+
+  actual fun rangeEquals(offset: Long, bytes: ByteString): Boolean
+
+  actual fun rangeEquals(offset: Long, bytes: ByteString, bytesOffset: Int, byteCount: Int): Boolean
+
+  actual fun peek(): BufferedSource
+}
diff --git a/okio/src/nonJvmMain/kotlin/okio/ByteString.kt b/okio/src/nonJvmMain/kotlin/okio/ByteString.kt
new file mode 100644
index 0000000..f0f038b
--- /dev/null
+++ b/okio/src/nonJvmMain/kotlin/okio/ByteString.kt
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2018 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 okio
+
+import okio.internal.HashFunction
+import okio.internal.Hmac
+import okio.internal.Md5
+import okio.internal.Sha1
+import okio.internal.Sha256
+import okio.internal.Sha512
+import okio.internal.commonBase64
+import okio.internal.commonBase64Url
+import okio.internal.commonCompareTo
+import okio.internal.commonDecodeBase64
+import okio.internal.commonDecodeHex
+import okio.internal.commonEncodeUtf8
+import okio.internal.commonEndsWith
+import okio.internal.commonEquals
+import okio.internal.commonGetByte
+import okio.internal.commonGetSize
+import okio.internal.commonHashCode
+import okio.internal.commonHex
+import okio.internal.commonIndexOf
+import okio.internal.commonInternalArray
+import okio.internal.commonLastIndexOf
+import okio.internal.commonOf
+import okio.internal.commonRangeEquals
+import okio.internal.commonStartsWith
+import okio.internal.commonSubstring
+import okio.internal.commonToAsciiLowercase
+import okio.internal.commonToAsciiUppercase
+import okio.internal.commonToByteArray
+import okio.internal.commonToByteString
+import okio.internal.commonToString
+import okio.internal.commonUtf8
+import okio.internal.commonWrite
+
+actual open class ByteString
+internal actual constructor(
+  internal actual val data: ByteArray
+) : Comparable<ByteString> {
+  @Suppress("SetterBackingFieldAssignment")
+  internal actual var hashCode: Int = 0 // 0 if unknown.
+    set(value) {
+      // Do nothing to avoid IllegalImmutabilityException.
+    }
+  @Suppress("SetterBackingFieldAssignment")
+  internal actual var utf8: String? = null
+    set(value) {
+      // Do nothing to avoid IllegalImmutabilityException.
+    }
+
+  actual open fun utf8(): String = commonUtf8()
+
+  actual open fun base64(): String = commonBase64()
+
+  actual open fun base64Url(): String = commonBase64Url()
+
+  actual open fun hex(): String = commonHex()
+
+  actual fun md5() = digest(Md5())
+
+  actual fun sha1() = digest(Sha1())
+
+  actual fun sha256() = digest(Sha256())
+
+  actual fun sha512() = digest(Sha512())
+
+  /** Returns the 160-bit SHA-1 HMAC of this byte string.  */
+  actual fun hmacSha1(key: ByteString) = digest(Hmac.sha1(key))
+
+  /** Returns the 256-bit SHA-256 HMAC of this byte string.  */
+  actual fun hmacSha256(key: ByteString) = digest(Hmac.sha256(key))
+
+  /** Returns the 512-bit SHA-512 HMAC of this byte string.  */
+  actual fun hmacSha512(key: ByteString) = digest(Hmac.sha512(key))
+
+  internal open fun digest(hashFunction: HashFunction): ByteString {
+    hashFunction.update(data, 0, size)
+    val digestBytes = hashFunction.digest()
+    return ByteString(digestBytes)
+  }
+
+  actual open fun toAsciiLowercase(): ByteString = commonToAsciiLowercase()
+
+  actual open fun toAsciiUppercase(): ByteString = commonToAsciiUppercase()
+
+  actual open fun substring(beginIndex: Int, endIndex: Int): ByteString =
+    commonSubstring(beginIndex, endIndex)
+
+  internal actual open fun internalGet(pos: Int): Byte {
+    if (pos >= size || pos < 0) throw ArrayIndexOutOfBoundsException("size=$size pos=$pos")
+    return commonGetByte(pos)
+  }
+
+  actual operator fun get(index: Int): Byte = internalGet(index)
+
+  actual val size
+    get() = getSize()
+
+  internal actual open fun getSize() = commonGetSize()
+
+  actual open fun toByteArray() = commonToByteArray()
+
+  internal actual open fun internalArray() = commonInternalArray()
+
+  internal actual open fun write(buffer: Buffer, offset: Int, byteCount: Int) =
+    commonWrite(buffer, offset, byteCount)
+
+  actual open fun rangeEquals(
+    offset: Int,
+    other: ByteString,
+    otherOffset: Int,
+    byteCount: Int
+  ): Boolean = commonRangeEquals(offset, other, otherOffset, byteCount)
+
+  actual open fun rangeEquals(
+    offset: Int,
+    other: ByteArray,
+    otherOffset: Int,
+    byteCount: Int
+  ): Boolean = commonRangeEquals(offset, other, otherOffset, byteCount)
+
+  actual fun startsWith(prefix: ByteString) = commonStartsWith(prefix)
+
+  actual fun startsWith(prefix: ByteArray) = commonStartsWith(prefix)
+
+  actual fun endsWith(suffix: ByteString) = commonEndsWith(suffix)
+
+  actual fun endsWith(suffix: ByteArray) = commonEndsWith(suffix)
+
+  actual fun indexOf(other: ByteString, fromIndex: Int) = indexOf(other.internalArray(), fromIndex)
+
+  actual open fun indexOf(other: ByteArray, fromIndex: Int) = commonIndexOf(other, fromIndex)
+
+  actual fun lastIndexOf(other: ByteString, fromIndex: Int) = commonLastIndexOf(other, fromIndex)
+
+  actual open fun lastIndexOf(other: ByteArray, fromIndex: Int) = commonLastIndexOf(other, fromIndex)
+
+  actual override fun equals(other: Any?) = commonEquals(other)
+
+  actual override fun hashCode() = commonHashCode()
+
+  actual override fun compareTo(other: ByteString) = commonCompareTo(other)
+
+  /**
+   * Returns a human-readable string that describes the contents of this byte string. Typically this
+   * is a string like `[text=Hello]` or `[hex=0000ffff]`.
+   */
+  actual override fun toString() = commonToString()
+
+  actual companion object {
+    actual val EMPTY: ByteString = ByteString(byteArrayOf())
+
+    actual fun of(vararg data: Byte) = commonOf(data)
+
+    actual fun ByteArray.toByteString(offset: Int, byteCount: Int): ByteString =
+      commonToByteString(offset, byteCount)
+
+    actual fun String.encodeUtf8(): ByteString = commonEncodeUtf8()
+
+    actual fun String.decodeBase64(): ByteString? = commonDecodeBase64()
+
+    actual fun String.decodeHex() = commonDecodeHex()
+  }
+}
diff --git a/okio/src/nonJvmMain/kotlin/okio/HashingSink.kt b/okio/src/nonJvmMain/kotlin/okio/HashingSink.kt
new file mode 100644
index 0000000..cbd14a2
--- /dev/null
+++ b/okio/src/nonJvmMain/kotlin/okio/HashingSink.kt
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2020 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 okio
+
+import okio.internal.HashFunction
+import okio.internal.Hmac
+import okio.internal.Md5
+import okio.internal.Sha1
+import okio.internal.Sha256
+import okio.internal.Sha512
+
+actual class HashingSink internal constructor(
+  private val sink: Sink,
+  private val hashFunction: HashFunction
+) : Sink {
+
+  override fun write(source: Buffer, byteCount: Long) {
+    checkOffsetAndCount(source.size, 0, byteCount)
+
+    // Hash byteCount bytes from the prefix of source.
+    var hashedCount = 0L
+    var s = source.head!!
+    while (hashedCount < byteCount) {
+      val toHash = minOf(byteCount - hashedCount, s.limit - s.pos).toInt()
+      hashFunction.update(s.data, s.pos, toHash)
+      hashedCount += toHash
+      s = s.next!!
+    }
+
+    // Write those bytes to the sink.
+    sink.write(source, byteCount)
+  }
+
+  override fun flush() = sink.flush()
+
+  override fun timeout(): Timeout = sink.timeout()
+
+  override fun close() = sink.close()
+
+  /**
+   * Returns the hash of the bytes accepted thus far and resets the internal state of this sink.
+   *
+   * **Warning:** This method is not idempotent. Each time this method is called its
+   * internal state is cleared. This starts a new hash with zero bytes accepted.
+   */
+  actual val hash: ByteString
+    get() {
+      val result = hashFunction.digest()
+      return ByteString(result)
+    }
+
+  actual companion object {
+
+    /** Returns a sink that uses the obsolete MD5 hash algorithm to produce 128-bit hashes. */
+    actual fun md5(sink: Sink) = HashingSink(sink, Md5())
+
+    /** Returns a sink that uses the obsolete SHA-1 hash algorithm to produce 160-bit hashes. */
+    actual fun sha1(sink: Sink) = HashingSink(sink, Sha1())
+
+    /** Returns a sink that uses the SHA-256 hash algorithm to produce 256-bit hashes. */
+    actual fun sha256(sink: Sink) = HashingSink(sink, Sha256())
+
+    /** Returns a sink that uses the SHA-512 hash algorithm to produce 512-bit hashes. */
+    actual fun sha512(sink: Sink) = HashingSink(sink, Sha512())
+
+    /** Returns a sink that uses the obsolete SHA-1 HMAC algorithm to produce 160-bit hashes. */
+    actual fun hmacSha1(sink: Sink, key: ByteString) = HashingSink(sink, Hmac.sha1(key))
+
+    /** Returns a sink that uses the SHA-256 HMAC algorithm to produce 256-bit hashes. */
+    actual fun hmacSha256(sink: Sink, key: ByteString) = HashingSink(sink, Hmac.sha256(key))
+
+    /** Returns a sink that uses the SHA-512 HMAC algorithm to produce 512-bit hashes. */
+    actual fun hmacSha512(sink: Sink, key: ByteString) = HashingSink(sink, Hmac.sha512(key))
+  }
+}
diff --git a/okio/src/nonJvmMain/kotlin/okio/HashingSource.kt b/okio/src/nonJvmMain/kotlin/okio/HashingSource.kt
new file mode 100644
index 0000000..62bfd60
--- /dev/null
+++ b/okio/src/nonJvmMain/kotlin/okio/HashingSource.kt
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2020 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 okio
+
+import okio.internal.HashFunction
+import okio.internal.Hmac
+import okio.internal.Md5
+import okio.internal.Sha1
+import okio.internal.Sha256
+import okio.internal.Sha512
+
+actual class HashingSource internal constructor(
+  private val source: Source,
+  private val hashFunction: HashFunction
+) : Source {
+
+  override fun read(sink: Buffer, byteCount: Long): Long {
+    val result = source.read(sink, byteCount)
+
+    if (result != -1L) {
+      var start = sink.size - result
+
+      // Find the first segment that has new bytes.
+      var offset = sink.size
+      var s = sink.head!!
+      while (offset > start) {
+        s = s.prev!!
+        offset -= (s.limit - s.pos).toLong()
+      }
+
+      // Hash that segment and all the rest until the end.
+      while (offset < sink.size) {
+        val pos = (s.pos + start - offset).toInt()
+        hashFunction.update(s.data, pos, s.limit - pos)
+        offset += s.limit - s.pos
+        start = offset
+        s = s.next!!
+      }
+    }
+
+    return result
+  }
+
+  override fun timeout(): Timeout =
+    source.timeout()
+
+  override fun close() =
+    source.close()
+
+  actual val hash: ByteString
+    get() {
+      val result = hashFunction.digest()
+      return ByteString(result)
+    }
+
+  actual companion object {
+
+    /** Returns a source that uses the obsolete MD5 hash algorithm to produce 128-bit hashes. */
+    actual fun md5(source: Source) = HashingSource(source, Md5())
+
+    /** Returns a source that uses the obsolete SHA-1 hash algorithm to produce 160-bit hashes. */
+    actual fun sha1(source: Source) = HashingSource(source, Sha1())
+
+    /** Returns a source that uses the SHA-256 hash algorithm to produce 256-bit hashes. */
+    actual fun sha256(source: Source) = HashingSource(source, Sha256())
+
+    /** Returns a source that uses the SHA-512 hash algorithm to produce 512-bit hashes. */
+    actual fun sha512(source: Source) = HashingSource(source, Sha512())
+
+    /** Returns a source that uses the obsolete SHA-1 HMAC algorithm to produce 160-bit hashes. */
+    actual fun hmacSha1(source: Source, key: ByteString) = HashingSource(source, Hmac.sha1(key))
+
+    /** Returns a source that uses the SHA-256 HMAC algorithm to produce 256-bit hashes. */
+    actual fun hmacSha256(source: Source, key: ByteString) = HashingSource(source, Hmac.sha256(key))
+
+    /** Returns a source that uses the SHA-512 HMAC algorithm to produce 512-bit hashes. */
+    actual fun hmacSha512(source: Source, key: ByteString) = HashingSource(source, Hmac.sha512(key))
+  }
+}
diff --git a/okio/src/nonJvmMain/kotlin/okio/RealBufferedSink.kt b/okio/src/nonJvmMain/kotlin/okio/RealBufferedSink.kt
new file mode 100644
index 0000000..ed03094
--- /dev/null
+++ b/okio/src/nonJvmMain/kotlin/okio/RealBufferedSink.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+import okio.internal.commonClose
+import okio.internal.commonEmit
+import okio.internal.commonEmitCompleteSegments
+import okio.internal.commonFlush
+import okio.internal.commonTimeout
+import okio.internal.commonToString
+import okio.internal.commonWrite
+import okio.internal.commonWriteAll
+import okio.internal.commonWriteByte
+import okio.internal.commonWriteDecimalLong
+import okio.internal.commonWriteHexadecimalUnsignedLong
+import okio.internal.commonWriteInt
+import okio.internal.commonWriteIntLe
+import okio.internal.commonWriteLong
+import okio.internal.commonWriteLongLe
+import okio.internal.commonWriteShort
+import okio.internal.commonWriteShortLe
+import okio.internal.commonWriteUtf8
+import okio.internal.commonWriteUtf8CodePoint
+
+internal actual class RealBufferedSink actual constructor(
+  actual val sink: Sink
+) : BufferedSink {
+  actual var closed: Boolean = false
+  override val buffer = Buffer()
+
+  override fun write(source: Buffer, byteCount: Long) = commonWrite(source, byteCount)
+  override fun write(byteString: ByteString) = commonWrite(byteString)
+  override fun write(byteString: ByteString, offset: Int, byteCount: Int) =
+    commonWrite(byteString, offset, byteCount)
+  override fun writeUtf8(string: String) = commonWriteUtf8(string)
+  override fun writeUtf8(string: String, beginIndex: Int, endIndex: Int) =
+    commonWriteUtf8(string, beginIndex, endIndex)
+
+  override fun writeUtf8CodePoint(codePoint: Int) = commonWriteUtf8CodePoint(codePoint)
+  override fun write(source: ByteArray) = commonWrite(source)
+  override fun write(source: ByteArray, offset: Int, byteCount: Int) =
+    commonWrite(source, offset, byteCount)
+
+  override fun writeAll(source: Source) = commonWriteAll(source)
+  override fun write(source: Source, byteCount: Long): BufferedSink = commonWrite(source, byteCount)
+  override fun writeByte(b: Int) = commonWriteByte(b)
+  override fun writeShort(s: Int) = commonWriteShort(s)
+  override fun writeShortLe(s: Int) = commonWriteShortLe(s)
+  override fun writeInt(i: Int) = commonWriteInt(i)
+  override fun writeIntLe(i: Int) = commonWriteIntLe(i)
+  override fun writeLong(v: Long) = commonWriteLong(v)
+  override fun writeLongLe(v: Long) = commonWriteLongLe(v)
+  override fun writeDecimalLong(v: Long) = commonWriteDecimalLong(v)
+  override fun writeHexadecimalUnsignedLong(v: Long) = commonWriteHexadecimalUnsignedLong(v)
+  override fun emitCompleteSegments() = commonEmitCompleteSegments()
+  override fun emit() = commonEmit()
+  override fun flush() = commonFlush()
+  override fun close() = commonClose()
+  override fun timeout() = commonTimeout()
+  override fun toString() = commonToString()
+}
diff --git a/okio/src/nonJvmMain/kotlin/okio/RealBufferedSource.kt b/okio/src/nonJvmMain/kotlin/okio/RealBufferedSource.kt
new file mode 100644
index 0000000..d6f4b94
--- /dev/null
+++ b/okio/src/nonJvmMain/kotlin/okio/RealBufferedSource.kt
@@ -0,0 +1,114 @@
+/*
+ * 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 okio
+
+import okio.internal.commonClose
+import okio.internal.commonExhausted
+import okio.internal.commonIndexOf
+import okio.internal.commonIndexOfElement
+import okio.internal.commonPeek
+import okio.internal.commonRangeEquals
+import okio.internal.commonRead
+import okio.internal.commonReadAll
+import okio.internal.commonReadByte
+import okio.internal.commonReadByteArray
+import okio.internal.commonReadByteString
+import okio.internal.commonReadDecimalLong
+import okio.internal.commonReadFully
+import okio.internal.commonReadHexadecimalUnsignedLong
+import okio.internal.commonReadInt
+import okio.internal.commonReadIntLe
+import okio.internal.commonReadLong
+import okio.internal.commonReadLongLe
+import okio.internal.commonReadShort
+import okio.internal.commonReadShortLe
+import okio.internal.commonReadUtf8
+import okio.internal.commonReadUtf8CodePoint
+import okio.internal.commonReadUtf8Line
+import okio.internal.commonReadUtf8LineStrict
+import okio.internal.commonRequest
+import okio.internal.commonRequire
+import okio.internal.commonSelect
+import okio.internal.commonSkip
+import okio.internal.commonTimeout
+import okio.internal.commonToString
+
+internal actual class RealBufferedSource actual constructor(
+  actual val source: Source
+) : BufferedSource {
+  actual var closed: Boolean = false
+  override val buffer: Buffer = Buffer()
+
+  override fun read(sink: Buffer, byteCount: Long): Long = commonRead(sink, byteCount)
+  override fun exhausted(): Boolean = commonExhausted()
+  override fun require(byteCount: Long): Unit = commonRequire(byteCount)
+  override fun request(byteCount: Long): Boolean = commonRequest(byteCount)
+  override fun readByte(): Byte = commonReadByte()
+  override fun readByteString(): ByteString = commonReadByteString()
+  override fun readByteString(byteCount: Long): ByteString = commonReadByteString(byteCount)
+  override fun select(options: Options): Int = commonSelect(options)
+  override fun readByteArray(): ByteArray = commonReadByteArray()
+  override fun readByteArray(byteCount: Long): ByteArray = commonReadByteArray(byteCount)
+  override fun read(sink: ByteArray): Int = read(sink, 0, sink.size)
+  override fun readFully(sink: ByteArray): Unit = commonReadFully(sink)
+  override fun read(sink: ByteArray, offset: Int, byteCount: Int): Int =
+    commonRead(sink, offset, byteCount)
+
+  override fun readFully(sink: Buffer, byteCount: Long): Unit = commonReadFully(sink, byteCount)
+  override fun readAll(sink: Sink): Long = commonReadAll(sink)
+  override fun readUtf8(): String = commonReadUtf8()
+  override fun readUtf8(byteCount: Long): String = commonReadUtf8(byteCount)
+  override fun readUtf8Line(): String? = commonReadUtf8Line()
+  override fun readUtf8LineStrict() = readUtf8LineStrict(Long.MAX_VALUE)
+  override fun readUtf8LineStrict(limit: Long): String = commonReadUtf8LineStrict(limit)
+  override fun readUtf8CodePoint(): Int = commonReadUtf8CodePoint()
+  override fun readShort(): Short = commonReadShort()
+  override fun readShortLe(): Short = commonReadShortLe()
+  override fun readInt(): Int = commonReadInt()
+  override fun readIntLe(): Int = commonReadIntLe()
+  override fun readLong(): Long = commonReadLong()
+  override fun readLongLe(): Long = commonReadLongLe()
+  override fun readDecimalLong(): Long = commonReadDecimalLong()
+  override fun readHexadecimalUnsignedLong(): Long = commonReadHexadecimalUnsignedLong()
+  override fun skip(byteCount: Long): Unit = commonSkip(byteCount)
+  override fun indexOf(b: Byte): Long = indexOf(b, 0L, Long.MAX_VALUE)
+  override fun indexOf(b: Byte, fromIndex: Long): Long = indexOf(b, fromIndex, Long.MAX_VALUE)
+  override fun indexOf(b: Byte, fromIndex: Long, toIndex: Long): Long =
+    commonIndexOf(b, fromIndex, toIndex)
+
+  override fun indexOf(bytes: ByteString): Long = indexOf(bytes, 0L)
+  override fun indexOf(bytes: ByteString, fromIndex: Long): Long = commonIndexOf(bytes, fromIndex)
+  override fun indexOfElement(targetBytes: ByteString): Long = indexOfElement(targetBytes, 0L)
+  override fun indexOfElement(targetBytes: ByteString, fromIndex: Long): Long =
+    commonIndexOfElement(targetBytes, fromIndex)
+
+  override fun rangeEquals(offset: Long, bytes: ByteString) = rangeEquals(
+    offset, bytes, 0,
+    bytes.size
+  )
+
+  override fun rangeEquals(
+    offset: Long,
+    bytes: ByteString,
+    bytesOffset: Int,
+    byteCount: Int
+  ): Boolean = commonRangeEquals(offset, bytes, bytesOffset, byteCount)
+
+  override fun peek(): BufferedSource = commonPeek()
+  override fun close(): Unit = commonClose()
+  override fun timeout(): Timeout = commonTimeout()
+  override fun toString(): String = commonToString()
+}
diff --git a/okio/src/nonJvmMain/kotlin/okio/SegmentPool.kt b/okio/src/nonJvmMain/kotlin/okio/SegmentPool.kt
new file mode 100644
index 0000000..50e7099
--- /dev/null
+++ b/okio/src/nonJvmMain/kotlin/okio/SegmentPool.kt
@@ -0,0 +1,27 @@
+/*
+ * 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 okio
+
+internal actual object SegmentPool {
+  actual val MAX_SIZE: Int = 0
+
+  actual val byteCount: Int = 0
+
+  actual fun take(): Segment = Segment()
+
+  actual fun recycle(segment: Segment) {
+  }
+}
diff --git a/okio/src/nonJvmMain/kotlin/okio/SegmentedByteString.kt b/okio/src/nonJvmMain/kotlin/okio/SegmentedByteString.kt
new file mode 100644
index 0000000..fe71890
--- /dev/null
+++ b/okio/src/nonJvmMain/kotlin/okio/SegmentedByteString.kt
@@ -0,0 +1,95 @@
+/*
+ * 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 okio
+
+import okio.internal.HashFunction
+import okio.internal.commonEquals
+import okio.internal.commonGetSize
+import okio.internal.commonHashCode
+import okio.internal.commonInternalGet
+import okio.internal.commonRangeEquals
+import okio.internal.commonSubstring
+import okio.internal.commonToByteArray
+import okio.internal.commonWrite
+import okio.internal.forEachSegment
+
+internal actual class SegmentedByteString internal actual constructor(
+  internal actual val segments: Array<ByteArray>,
+  internal actual val directory: IntArray
+) : ByteString(EMPTY.data) {
+
+  override fun base64() = toByteString().base64()
+
+  override fun hex() = toByteString().hex()
+
+  override fun toAsciiLowercase() = toByteString().toAsciiLowercase()
+
+  override fun toAsciiUppercase() = toByteString().toAsciiUppercase()
+
+  override fun base64Url() = toByteString().base64Url()
+
+  override fun substring(beginIndex: Int, endIndex: Int): ByteString =
+    commonSubstring(beginIndex, endIndex)
+
+  override fun internalGet(pos: Int): Byte = commonInternalGet(pos)
+
+  override fun getSize() = commonGetSize()
+
+  override fun toByteArray(): ByteArray = commonToByteArray()
+
+  override fun write(buffer: Buffer, offset: Int, byteCount: Int): Unit =
+    commonWrite(buffer, offset, byteCount)
+
+  override fun rangeEquals(
+    offset: Int,
+    other: ByteString,
+    otherOffset: Int,
+    byteCount: Int
+  ): Boolean = commonRangeEquals(offset, other, otherOffset, byteCount)
+
+  override fun rangeEquals(
+    offset: Int,
+    other: ByteArray,
+    otherOffset: Int,
+    byteCount: Int
+  ): Boolean = commonRangeEquals(offset, other, otherOffset, byteCount)
+
+  override fun indexOf(other: ByteArray, fromIndex: Int) = toByteString().indexOf(other, fromIndex)
+
+  override fun lastIndexOf(other: ByteArray, fromIndex: Int) = toByteString().lastIndexOf(
+    other,
+    fromIndex
+  )
+
+  override fun digest(hashFunction: HashFunction): ByteString {
+    forEachSegment { data, offset, byteCount ->
+      hashFunction.update(data, offset, byteCount)
+    }
+    val digestBytes = hashFunction.digest()
+    return ByteString(digestBytes)
+  }
+
+  /** Returns a copy as a non-segmented byte string.  */
+  private fun toByteString() = ByteString(toByteArray())
+
+  override fun internalArray() = toByteArray()
+
+  override fun equals(other: Any?): Boolean = commonEquals(other)
+
+  override fun hashCode(): Int = commonHashCode()
+
+  override fun toString() = toByteString().toString()
+}
diff --git a/okio/src/nonJvmMain/kotlin/okio/Sink.kt b/okio/src/nonJvmMain/kotlin/okio/Sink.kt
new file mode 100644
index 0000000..d114647
--- /dev/null
+++ b/okio/src/nonJvmMain/kotlin/okio/Sink.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+actual interface Sink : Closeable {
+  @Throws(IOException::class)
+  actual fun write(source: Buffer, byteCount: Long)
+
+  @Throws(IOException::class)
+  actual fun flush()
+
+  actual fun timeout(): Timeout
+
+  @Throws(IOException::class)
+  actual override fun close()
+}
diff --git a/okio/src/nonJvmMain/kotlin/okio/Timeout.kt b/okio/src/nonJvmMain/kotlin/okio/Timeout.kt
new file mode 100644
index 0000000..d66a027
--- /dev/null
+++ b/okio/src/nonJvmMain/kotlin/okio/Timeout.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2019 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 okio
+
+actual open class Timeout {
+  actual companion object {
+    actual val NONE = Timeout()
+  }
+}
diff --git a/samples/build.gradle b/samples/build.gradle
new file mode 100644
index 0000000..efaef19
--- /dev/null
+++ b/samples/build.gradle
@@ -0,0 +1,23 @@
+apply plugin: 'org.jetbrains.kotlin.multiplatform'
+apply plugin: 'application'
+
+mainClassName = System.getProperty("mainClass")
+
+kotlin {
+  jvm {
+    withJava()
+  }
+  sourceSets {
+    commonMain {
+      dependencies {
+        implementation project(':okio')
+      }
+    }
+    jvmTest {
+      dependencies {
+        implementation deps.test.junit
+        implementation deps.test.assertj
+      }
+    }
+  }
+}
diff --git a/samples/src/jvmMain/java/okio/samples/BitmapEncoder.java b/samples/src/jvmMain/java/okio/samples/BitmapEncoder.java
new file mode 100644
index 0000000..a505f6d
--- /dev/null
+++ b/samples/src/jvmMain/java/okio/samples/BitmapEncoder.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2018 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 okio.samples;
+
+import java.io.File;
+import java.io.IOException;
+import okio.BufferedSink;
+import okio.Okio;
+
+public final class BitmapEncoder {
+  static final class Bitmap {
+    private final int[][] pixels;
+
+    Bitmap(int[][] pixels) {
+      this.pixels = pixels;
+    }
+
+    int width() {
+      return pixels[0].length;
+    }
+
+    int height() {
+      return pixels.length;
+    }
+
+    int red(int x, int y) {
+      return (pixels[y][x] & 0xff0000) >> 16;
+    }
+
+    int green(int x, int y) {
+      return (pixels[y][x] & 0xff00) >> 8;
+    }
+
+    int blue(int x, int y) {
+      return (pixels[y][x] & 0xff);
+    }
+  }
+
+  /**
+   * Returns a bitmap that lights up red subpixels at the bottom, green subpixels on the right, and
+   * blue subpixels in bottom-right.
+   */
+  Bitmap generateGradient() {
+    int[][] pixels = new int[1080][1920];
+    for (int y = 0; y < 1080; y++) {
+      for (int x = 0; x < 1920; x++) {
+        int r = (int) (y / 1080f * 255);
+        int g = (int) (x / 1920f * 255);
+        int b = (int) ((Math.hypot(x, y) / Math.hypot(1080, 1920)) * 255);
+        pixels[y][x] = r << 16 | g << 8 | b;
+      }
+    }
+    return new Bitmap(pixels);
+  }
+
+  void encode(Bitmap bitmap, File file) throws IOException {
+    try (BufferedSink sink = Okio.buffer(Okio.sink(file))) {
+      encode(bitmap, sink);
+    }
+  }
+
+  /** https://en.wikipedia.org/wiki/BMP_file_format */
+  void encode(Bitmap bitmap, BufferedSink sink) throws IOException {
+    int height = bitmap.height();
+    int width = bitmap.width();
+
+    int bytesPerPixel = 3;
+    int rowByteCountWithoutPadding = (bytesPerPixel * width);
+    int rowByteCount = ((rowByteCountWithoutPadding + 3) / 4) * 4;
+    int pixelDataSize = rowByteCount * height;
+    int bmpHeaderSize = 14;
+    int dibHeaderSize = 40;
+
+    // BMP Header
+    sink.writeUtf8("BM"); // ID.
+    sink.writeIntLe(bmpHeaderSize + dibHeaderSize + pixelDataSize); // File size.
+    sink.writeShortLe(0); // Unused.
+    sink.writeShortLe(0); // Unused.
+    sink.writeIntLe(bmpHeaderSize + dibHeaderSize); // Offset of pixel data.
+
+    // DIB Header
+    sink.writeIntLe(dibHeaderSize);
+    sink.writeIntLe(width);
+    sink.writeIntLe(height);
+    sink.writeShortLe(1);  // Color plane count.
+    sink.writeShortLe(bytesPerPixel * Byte.SIZE);
+    sink.writeIntLe(0);    // No compression.
+    sink.writeIntLe(16);   // Size of bitmap data including padding.
+    sink.writeIntLe(2835); // Horizontal print resolution in pixels/meter. (72 dpi).
+    sink.writeIntLe(2835); // Vertical print resolution in pixels/meter. (72 dpi).
+    sink.writeIntLe(0);    // Palette color count.
+    sink.writeIntLe(0);    // 0 important colors.
+
+    // Pixel data.
+    for (int y = height - 1; y >= 0; y--) {
+      for (int x = 0; x < width; x++) {
+        sink.writeByte(bitmap.blue(x, y));
+        sink.writeByte(bitmap.green(x, y));
+        sink.writeByte(bitmap.red(x, y));
+      }
+
+      // Padding for 4-byte alignment.
+      for (int p = rowByteCountWithoutPadding; p < rowByteCount; p++) {
+        sink.writeByte(0);
+      }
+    }
+  }
+
+  public static void main(String[] args) throws Exception {
+    BitmapEncoder encoder = new BitmapEncoder();
+    Bitmap bitmap = encoder.generateGradient();
+    encoder.encode(bitmap, new File("gradient.bmp"));
+  }
+}
diff --git a/samples/src/jvmMain/java/okio/samples/ByteChannelSink.java b/samples/src/jvmMain/java/okio/samples/ByteChannelSink.java
new file mode 100644
index 0000000..ba4a9af
--- /dev/null
+++ b/samples/src/jvmMain/java/okio/samples/ByteChannelSink.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2018 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 okio.samples;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.WritableByteChannel;
+import okio.Buffer;
+import okio.Sink;
+import okio.Timeout;
+
+/**
+ * Creates a Sink around a WritableByteChannel and efficiently writes data using an UnsafeCursor.
+ *
+ * <p>This is a basic example showing another use for the UnsafeCursor. Using the
+ * {@link ByteBuffer#wrap(byte[], int, int) ByteBuffer.wrap()} along with access to Buffer segments,
+ * a WritableByteChannel can be given direct access to Buffer data without having to copy the data.
+ */
+final class ByteChannelSink implements Sink {
+  private final WritableByteChannel channel;
+  private final Timeout timeout;
+
+  private final Buffer.UnsafeCursor cursor = new Buffer.UnsafeCursor();
+
+  ByteChannelSink(WritableByteChannel channel, Timeout timeout) {
+    this.channel = channel;
+    this.timeout = timeout;
+  }
+
+  @Override public void write(Buffer source, long byteCount) throws IOException {
+    if (!channel.isOpen()) throw new IllegalStateException("closed");
+    if (byteCount == 0) return;
+
+    long remaining = byteCount;
+    while (remaining > 0) {
+      timeout.throwIfReached();
+
+      try (Buffer.UnsafeCursor ignored = source.readUnsafe(cursor)) {
+        cursor.seek(0);
+        int length = (int) Math.min(cursor.end - cursor.start, remaining);
+        int written = channel.write(ByteBuffer.wrap(cursor.data, cursor.start, length));
+        remaining -= written;
+        source.skip(written);
+      }
+    }
+  }
+
+  @Override public void flush() {}
+
+  @Override public Timeout timeout() {
+    return timeout;
+  }
+
+  @Override public void close() throws IOException {
+    channel.close();
+  }
+}
diff --git a/samples/src/jvmMain/java/okio/samples/ByteChannelSource.java b/samples/src/jvmMain/java/okio/samples/ByteChannelSource.java
new file mode 100644
index 0000000..f1f2875
--- /dev/null
+++ b/samples/src/jvmMain/java/okio/samples/ByteChannelSource.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2018 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 okio.samples;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.ReadableByteChannel;
+import okio.Buffer;
+import okio.Source;
+import okio.Timeout;
+
+/**
+ * Creates a Source around a ReadableByteChannel and efficiently reads data using an UnsafeCursor.
+ *
+ * <p>This is a basic example showing another use for the UnsafeCursor. Using the
+ * {@link ByteBuffer#wrap(byte[], int, int) ByteBuffer.wrap()} along with access to Buffer segments,
+ * a ReadableByteChannel can be given direct access to Buffer data without having to copy the data.
+ */
+final class ByteChannelSource implements Source {
+  private final ReadableByteChannel channel;
+  private final Timeout timeout;
+
+  private final Buffer.UnsafeCursor cursor = new Buffer.UnsafeCursor();
+
+  ByteChannelSource(ReadableByteChannel channel, Timeout timeout) {
+    this.channel = channel;
+    this.timeout = timeout;
+  }
+
+  @Override public long read(Buffer sink, long byteCount) throws IOException {
+    if (!channel.isOpen()) throw new IllegalStateException("closed");
+
+    try (Buffer.UnsafeCursor ignored = sink.readAndWriteUnsafe(cursor)) {
+      timeout.throwIfReached();
+      long oldSize = sink.size();
+      int length = (int) Math.min(8192, byteCount);
+
+      cursor.expandBuffer(length);
+      int read = channel.read(ByteBuffer.wrap(cursor.data, cursor.start, length));
+      if (read == -1) {
+        cursor.resizeBuffer(oldSize);
+        return -1;
+      } else {
+        cursor.resizeBuffer(oldSize + read);
+        return read;
+      }
+    }
+  }
+
+  @Override public Timeout timeout() {
+    return timeout;
+  }
+
+  @Override public void close() throws IOException {
+    channel.close();
+  }
+}
diff --git a/samples/src/jvmMain/java/okio/samples/ExploreCharsets.java b/samples/src/jvmMain/java/okio/samples/ExploreCharsets.java
new file mode 100644
index 0000000..3b20295
--- /dev/null
+++ b/samples/src/jvmMain/java/okio/samples/ExploreCharsets.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 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 okio.samples;
+
+import java.io.IOException;
+import okio.ByteString;
+import okio.Utf8;
+
+public final class ExploreCharsets {
+  public void run() throws Exception {
+    dumpStringData("Café \uD83C\uDF69"); // NFC: é is one code point.
+    dumpStringData("Café \uD83C\uDF69"); // NFD: e is one code point, its accent is another.
+  }
+
+  public void dumpStringData(String s) throws IOException {
+    System.out.println("                       " + s);
+    System.out.println("        String.length: " + s.length());
+    System.out.println("String.codePointCount: " + s.codePointCount(0, s.length()));
+    System.out.println("            Utf8.size: " + Utf8.size(s));
+    System.out.println("          UTF-8 bytes: " + ByteString.encodeUtf8(s).hex());
+    System.out.println();
+  }
+
+  public static void main(String... args) throws Exception {
+    new ExploreCharsets().run();
+  }
+}
diff --git a/samples/src/jvmMain/java/okio/samples/FileChannelSink.java b/samples/src/jvmMain/java/okio/samples/FileChannelSink.java
new file mode 100644
index 0000000..b810a32
--- /dev/null
+++ b/samples/src/jvmMain/java/okio/samples/FileChannelSink.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 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 okio.samples;
+
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.ReadableByteChannel;
+import okio.Buffer;
+import okio.Sink;
+import okio.Timeout;
+
+/**
+ * Special Sink for a FileChannel to take advantage of the
+ * {@link FileChannel#transferFrom(ReadableByteChannel, long, long) transfer} method available.
+ */
+final class FileChannelSink implements Sink {
+  private final FileChannel channel;
+  private final Timeout timeout;
+
+  private long position;
+
+  FileChannelSink(FileChannel channel, Timeout timeout) throws IOException {
+    this.channel = channel;
+    this.timeout = timeout;
+
+    this.position = channel.position();
+  }
+
+  @Override public void write(Buffer source, long byteCount) throws IOException {
+    if (!channel.isOpen()) throw new IllegalStateException("closed");
+    if (byteCount == 0) return;
+
+    long remaining = byteCount;
+    while (remaining > 0) {
+      long written = channel.transferFrom(source, position, remaining);
+      position += written;
+      remaining -= written;
+    }
+  }
+
+  @Override public void flush() throws IOException {
+    // Cannot alter meta data through this Sink
+    channel.force(false);
+  }
+
+  @Override public Timeout timeout() {
+    return timeout;
+  }
+
+  @Override public void close() throws IOException {
+    channel.close();
+  }
+}
diff --git a/samples/src/jvmMain/java/okio/samples/FileChannelSource.java b/samples/src/jvmMain/java/okio/samples/FileChannelSource.java
new file mode 100644
index 0000000..db5ec93
--- /dev/null
+++ b/samples/src/jvmMain/java/okio/samples/FileChannelSource.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018 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 okio.samples;
+
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.WritableByteChannel;
+import okio.Buffer;
+import okio.Source;
+import okio.Timeout;
+
+/**
+ * Special Source for a FileChannel to take advantage of the
+ * {@link FileChannel#transferTo(long, long, WritableByteChannel) transfer} method available.
+ */
+final class FileChannelSource implements Source {
+  private final FileChannel channel;
+  private final Timeout timeout;
+
+  private long position;
+
+  FileChannelSource(FileChannel channel, Timeout timeout) throws IOException {
+    this.channel = channel;
+    this.timeout = timeout;
+
+    this.position = channel.position();
+  }
+
+  @Override public long read(Buffer sink, long byteCount) throws IOException {
+    if (!channel.isOpen()) throw new IllegalStateException("closed");
+    if (position == channel.size()) return -1L;
+
+    long read = channel.transferTo(position, byteCount, sink);
+    position += read;
+    return read;
+  }
+
+  @Override public Timeout timeout() {
+    return timeout;
+  }
+
+  @Override public void close() throws IOException {
+    channel.close();
+  }
+}
diff --git a/samples/src/jvmMain/java/okio/samples/GoldenValue.java b/samples/src/jvmMain/java/okio/samples/GoldenValue.java
new file mode 100644
index 0000000..aeeaa0f
--- /dev/null
+++ b/samples/src/jvmMain/java/okio/samples/GoldenValue.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2018 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 okio.samples;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import okio.Buffer;
+import okio.ByteString;
+
+public final class GoldenValue {
+  public void run() throws Exception {
+    Point point = new Point(8.0, 15.0);
+    ByteString pointBytes = serialize(point);
+    System.out.println(pointBytes.base64());
+
+    ByteString goldenBytes = ByteString.decodeBase64("rO0ABXNyAB5va2lvLnNhbXBsZ"
+        + "XMuR29sZGVuVmFsdWUkUG9pbnTdUW8rMji1IwIAAkQAAXhEAAF5eHBAIAAAAAAAAEAuA"
+        + "AAAAAAA");
+    Point decoded = (Point) deserialize(goldenBytes);
+    assertEquals(point, decoded);
+  }
+
+  private ByteString serialize(Object o) throws IOException {
+    Buffer buffer = new Buffer();
+    try (ObjectOutputStream objectOut = new ObjectOutputStream(buffer.outputStream())) {
+      objectOut.writeObject(o);
+    }
+    return buffer.readByteString();
+  }
+
+  private Object deserialize(ByteString byteString) throws IOException, ClassNotFoundException {
+    Buffer buffer = new Buffer();
+    buffer.write(byteString);
+    try (ObjectInputStream objectIn = new ObjectInputStream(buffer.inputStream())) {
+      Object result = objectIn.readObject();
+      if (objectIn.read() != -1) throw new IOException("Unconsumed bytes in stream");
+      return result;
+    }
+  }
+
+  static final class Point implements Serializable {
+    double x;
+    double y;
+
+    Point(double x, double y) {
+      this.x = x;
+      this.y = y;
+    }
+  }
+
+  private void assertEquals(Point a, Point b) {
+    if (a.x != b.x || a.y != b.y) throw new AssertionError();
+  }
+
+  public static void main(String... args) throws Exception {
+    new GoldenValue().run();
+  }
+}
diff --git a/samples/src/jvmMain/java/okio/samples/Hashing.java b/samples/src/jvmMain/java/okio/samples/Hashing.java
new file mode 100644
index 0000000..0f2b447
--- /dev/null
+++ b/samples/src/jvmMain/java/okio/samples/Hashing.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2018 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 okio.samples;
+
+import java.io.File;
+import java.io.IOException;
+import okio.Buffer;
+import okio.BufferedSink;
+import okio.BufferedSource;
+import okio.ByteString;
+import okio.HashingSink;
+import okio.HashingSource;
+import okio.Okio;
+import okio.Source;
+
+public final class Hashing {
+  public void run() throws Exception {
+    File file = new File("../README.md");
+
+    System.out.println("ByteString");
+    ByteString byteString = readByteString(file);
+    System.out.println("       md5: " + byteString.md5().hex());
+    System.out.println("      sha1: " + byteString.sha1().hex());
+    System.out.println("    sha256: " + byteString.sha256().hex());
+    System.out.println("    sha512: " + byteString.sha512().hex());
+    System.out.println();
+
+    System.out.println("Buffer");
+    Buffer buffer = readBuffer(file);
+    System.out.println("       md5: " + buffer.md5().hex());
+    System.out.println("      sha1: " + buffer.sha1().hex());
+    System.out.println("    sha256: " + buffer.sha256().hex());
+    System.out.println("    sha512: " + buffer.sha512().hex());
+    System.out.println();
+
+    System.out.println("HashingSource");
+    try (HashingSource hashingSource = HashingSource.sha256(Okio.source(file));
+         BufferedSource source = Okio.buffer(hashingSource)) {
+      source.readAll(Okio.blackhole());
+      System.out.println("    sha256: " + hashingSource.hash().hex());
+    }
+    System.out.println();
+
+    System.out.println("HashingSink");
+    try (HashingSink hashingSink = HashingSink.sha256(Okio.blackhole());
+         BufferedSink sink = Okio.buffer(hashingSink);
+         Source source = Okio.source(file)) {
+      sink.writeAll(source);
+      sink.close(); // Emit anything buffered.
+      System.out.println("    sha256: " + hashingSink.hash().hex());
+    }
+    System.out.println();
+
+    System.out.println("HMAC");
+    ByteString secret = ByteString.decodeHex("7065616e7574627574746572");
+    System.out.println("hmacSha256: " + byteString.hmacSha256(secret).hex());
+    System.out.println();
+  }
+
+  public ByteString readByteString(File file) throws IOException {
+    try (BufferedSource source = Okio.buffer(Okio.source(file))) {
+      return source.readByteString();
+    }
+  }
+
+  public Buffer readBuffer(File file) throws IOException {
+    try (Source source = Okio.source(file)) {
+      Buffer buffer = new Buffer();
+      buffer.writeAll(source);
+      return buffer;
+    }
+  }
+
+  public static void main(String[] args) throws Exception {
+    new Hashing().run();
+  }
+}
diff --git a/samples/src/jvmMain/java/okio/samples/Interceptors.java b/samples/src/jvmMain/java/okio/samples/Interceptors.java
new file mode 100644
index 0000000..85cbbba
--- /dev/null
+++ b/samples/src/jvmMain/java/okio/samples/Interceptors.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2018 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 okio.samples;
+
+import java.io.IOException;
+import java.util.Random;
+import okio.Buffer;
+import okio.ForwardingSink;
+import okio.ForwardingSource;
+import okio.Sink;
+import okio.Source;
+
+/**
+ * Demonstrates use of the {@link Buffer.UnsafeCursor} class. While other
+ * samples might demonstrate real use cases, this sample hopes to show the
+ * basics of using an {@link Buffer.UnsafeCursor}:
+ * <ul>
+ *   <li>Efficient reuse of a single cursor instance.</li>
+ *   <li>Guaranteed release of an attached cursor.</li>
+ *   <li>Safe traversal of the data in a Buffer.</li>
+ * </ul>
+ *
+ * <p>This sample implements a
+ * <a href="https://en.wikipedia.org/wiki/Cipher_disk">circular cipher</a> by
+ * creating a Source which will intercept all bytes written to the wire and
+ * decrease their value by a specific amount. Then create a Sink which will
+ * intercept all bytes read from the wire and increase their value by that same
+ * specific amount. This creates an incredibly insecure way of encrypting data
+ * written to the wire but demonstrates the power of the
+ * {@link Buffer.UnsafeCursor} class for efficient operations on the bytes
+ * being written and read.
+ */
+public final class Interceptors {
+  public void run() throws Exception {
+    final byte cipher = (byte) (new Random().nextInt(256) - 128);
+    System.out.println("Cipher   : " + cipher);
+
+    Buffer wire = new Buffer();
+
+    // Create a Sink which will intercept and negatively rotate each byte by `cipher`
+    Sink sink = new InterceptingSink(wire) {
+      @Override
+      protected void intercept(byte[] data, int offset, int length) {
+        for (int i = offset, end = offset + length; i < end; i++) {
+          data[i] -= cipher;
+        }
+      }
+    };
+
+    // Create a Source which will intercept and positively rotate each byte by `cipher`
+    Source source = new InterceptingSource(wire) {
+      @Override
+      protected void intercept(byte[] data, int offset, int length) {
+        for (int i = offset, end = offset + length; i < end; i++) {
+          data[i] += cipher;
+        }
+      }
+    };
+
+    Buffer transmit = new Buffer();
+    transmit.writeUtf8("This is not really a secure message");
+    System.out.println("Transmit : " + transmit);
+
+    sink.write(transmit, transmit.size());
+    System.out.println("Wire     : " + wire);
+
+    Buffer receive = new Buffer();
+    source.read(receive, Long.MAX_VALUE);
+    System.out.println("Receive  : " + receive);
+  }
+
+  abstract class InterceptingSource extends ForwardingSource {
+
+    private final Buffer.UnsafeCursor cursor = new Buffer.UnsafeCursor();
+
+    InterceptingSource(Source source) {
+      super(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;
+
+      long result = super.read(sink, byteCount);
+      if (result == -1L) return result;
+
+      sink.readUnsafe(cursor);
+      try {
+        long remaining = result;
+        for (int length = cursor.seek(sink.size() - result);
+             remaining > 0 && length > 0;
+             length = cursor.next()) {
+          int toIntercept = (int) Math.min(length, remaining);
+          intercept(cursor.data, cursor.start, toIntercept);
+          remaining -= toIntercept;
+        }
+      } finally {
+        cursor.close();
+      }
+
+      return result;
+    }
+
+    protected abstract void intercept(byte[] data, int offset, int length) throws IOException;
+  }
+
+
+  abstract class InterceptingSink extends ForwardingSink {
+
+    private final Buffer.UnsafeCursor cursor = new Buffer.UnsafeCursor();
+
+    InterceptingSink(Sink delegate) {
+      super(delegate);
+    }
+
+    @Override
+    public void write(Buffer source, long byteCount) throws IOException {
+      if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
+      if (source.size() < byteCount) {
+        throw new IllegalArgumentException("size=" + source.size() + " byteCount=" + byteCount);
+      }
+      if (byteCount == 0) return;
+
+      source.readUnsafe(cursor);
+      try {
+        long remaining = byteCount;
+        for (int length = cursor.seek(0);
+             remaining > 0 && length > 0;
+             length = cursor.next()) {
+          int toIntercept = (int) Math.min(length, remaining);
+          intercept(cursor.data, cursor.start, toIntercept);
+          remaining -= toIntercept;
+        }
+      } finally {
+        cursor.close();
+      }
+
+      super.write(source, byteCount);
+    }
+
+    protected abstract void intercept(byte[] data, int offset, int length) throws IOException;
+  }
+
+  public static void main(String... args) throws Exception {
+    new Interceptors().run();
+  }
+}
diff --git a/samples/src/jvmMain/java/okio/samples/Randoms.java b/samples/src/jvmMain/java/okio/samples/Randoms.java
new file mode 100644
index 0000000..631ebc9
--- /dev/null
+++ b/samples/src/jvmMain/java/okio/samples/Randoms.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2018 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 okio.samples;
+
+import java.io.IOException;
+import java.util.Random;
+import okio.Buffer;
+import okio.BufferedSource;
+import okio.Okio;
+import okio.Source;
+import okio.Timeout;
+
+public final class Randoms {
+  public void run() throws IOException, InterruptedException {
+    Random random = new Random(3782615686L);
+    BufferedSource source = Okio.buffer(new RandomSource(random, 5));
+    System.out.println(source.readUtf8());
+  }
+
+  static final class RandomSource implements Source {
+    private final Random random;
+    private long bytesLeft;
+
+    RandomSource(Random random, long bytesLeft) {
+      this.random = random;
+      this.bytesLeft = bytesLeft;
+    }
+
+    @Override public long read(Buffer sink, long byteCount) throws IOException {
+      if (bytesLeft == -1L) throw new IllegalStateException("closed");
+      if (bytesLeft == 0L) return -1L;
+      if (byteCount > Integer.MAX_VALUE) byteCount = Integer.MAX_VALUE;
+      if (byteCount > bytesLeft) byteCount = bytesLeft;
+
+      // Random is most efficient when computing 32 bits of randomness. Start with that.
+      int ints = (int) (byteCount / 4);
+      for (int i = 0; i < ints; i++) {
+        sink.writeInt(random.nextInt());
+      }
+
+      // If we need 1, 2, or 3 bytes more, keep going. We'll discard 24, 16 or 8 random bits!
+      int bytes = (int) (byteCount - ints * 4);
+      if (bytes > 0) {
+        int bits = random.nextInt();
+        for (int i = 0; i < bytes; i++) {
+          sink.writeByte(bits & 0xff);
+          bits >>>= 8;
+        }
+      }
+
+      bytesLeft -= byteCount;
+      return byteCount;
+    }
+
+    @Override public Timeout timeout() {
+      return Timeout.NONE;
+    }
+
+    @Override public void close() throws IOException {
+      bytesLeft = -1L;
+    }
+  }
+
+  public static void main(String... args) throws Exception {
+    new Randoms().run();
+  }
+}
diff --git a/samples/src/jvmMain/java/okio/samples/ReadFileLineByLine.java b/samples/src/jvmMain/java/okio/samples/ReadFileLineByLine.java
new file mode 100644
index 0000000..b195a51
--- /dev/null
+++ b/samples/src/jvmMain/java/okio/samples/ReadFileLineByLine.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2018 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 okio.samples;
+
+import java.io.File;
+import java.io.IOException;
+import okio.BufferedSource;
+import okio.Okio;
+import okio.Source;
+
+public final class ReadFileLineByLine {
+  public void run() throws Exception {
+    readLines(new File("../README.md"));
+  }
+
+  public void readLines(File file) throws IOException {
+    try (Source fileSource = Okio.source(file);
+         BufferedSource bufferedFileSource = Okio.buffer(fileSource)) {
+
+      while (true) {
+        String line = bufferedFileSource.readUtf8Line();
+        if (line == null) break;
+
+        if (line.contains("square")) {
+          System.out.println(line);
+        }
+      }
+
+    }
+  }
+
+  public static void main(String... args) throws Exception {
+    new ReadFileLineByLine().run();
+  }
+}
diff --git a/samples/src/jvmMain/java/okio/samples/SocksProxyServer.java b/samples/src/jvmMain/java/okio/samples/SocksProxyServer.java
new file mode 100644
index 0000000..d770d82
--- /dev/null
+++ b/samples/src/jvmMain/java/okio/samples/SocksProxyServer.java
@@ -0,0 +1,199 @@
+/*
+ * 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 okio.samples;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ProtocolException;
+import java.net.Proxy;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import okio.Buffer;
+import okio.BufferedSink;
+import okio.BufferedSource;
+import okio.Okio;
+import okio.Sink;
+import okio.Source;
+
+/**
+ * A partial implementation of SOCKS Protocol Version 5.
+ * See <a href="https://www.ietf.org/rfc/rfc1928.txt">RFC 1928</a>.
+ */
+public final class SocksProxyServer {
+  private static final int VERSION_5 = 5;
+  private static final int METHOD_NO_AUTHENTICATION_REQUIRED = 0;
+  private static final int ADDRESS_TYPE_IPV4 = 1;
+  private static final int ADDRESS_TYPE_DOMAIN_NAME = 3;
+  private static final int COMMAND_CONNECT = 1;
+  private static final int REPLY_SUCCEEDED = 0;
+
+  private final ExecutorService executor = Executors.newCachedThreadPool();
+  private ServerSocket serverSocket;
+  private final Set<Socket> openSockets =
+      Collections.newSetFromMap(new ConcurrentHashMap<>());
+
+  public void start() throws IOException {
+    serverSocket = new ServerSocket(0);
+    executor.execute(this::acceptSockets);
+  }
+
+  public void shutdown() throws IOException {
+    serverSocket.close();
+    executor.shutdown();
+  }
+
+  public Proxy proxy() {
+    return new Proxy(Proxy.Type.SOCKS,
+        InetSocketAddress.createUnresolved("localhost", serverSocket.getLocalPort()));
+  }
+
+  private void acceptSockets() {
+    try {
+      while (true) {
+        final Socket from = serverSocket.accept();
+        openSockets.add(from);
+        executor.execute(() -> handleSocket(from));
+      }
+    } catch (IOException e) {
+      System.out.println("shutting down: " + e);
+    } finally {
+      for (Socket socket : openSockets) {
+        closeQuietly(socket);
+      }
+    }
+  }
+
+  private void handleSocket(final Socket fromSocket) {
+    try {
+      final BufferedSource fromSource = Okio.buffer(Okio.source(fromSocket));
+      final BufferedSink fromSink = Okio.buffer(Okio.sink(fromSocket));
+
+      // Read the hello.
+      int socksVersion = fromSource.readByte() & 0xff;
+      if (socksVersion != VERSION_5) throw new ProtocolException();
+      int methodCount = fromSource.readByte() & 0xff;
+      boolean foundSupportedMethod = false;
+      for (int i = 0; i < methodCount; i++) {
+        int method = fromSource.readByte() & 0xff;
+        foundSupportedMethod |= method == METHOD_NO_AUTHENTICATION_REQUIRED;
+      }
+      if (!foundSupportedMethod) throw new ProtocolException();
+
+      // Respond to hello.
+      fromSink.writeByte(VERSION_5)
+          .writeByte(METHOD_NO_AUTHENTICATION_REQUIRED)
+          .emit();
+
+      // Read a command.
+      int version = fromSource.readByte() & 0xff;
+      int command = fromSource.readByte() & 0xff;
+      int reserved = fromSource.readByte() & 0xff;
+      if (version != VERSION_5 || command != COMMAND_CONNECT || reserved != 0) {
+        throw new ProtocolException();
+      }
+
+      // Read an address.
+      int addressType = fromSource.readByte() & 0xff;
+      InetAddress inetAddress;
+      if (addressType == ADDRESS_TYPE_IPV4) {
+        inetAddress = InetAddress.getByAddress(fromSource.readByteArray(4L));
+      } else if (addressType == ADDRESS_TYPE_DOMAIN_NAME){
+        int domainNameLength = fromSource.readByte() & 0xff;
+        inetAddress = InetAddress.getByName(fromSource.readUtf8(domainNameLength));
+      } else {
+        throw new ProtocolException();
+      }
+      int port = fromSource.readShort() & 0xffff;
+
+      // Connect to the caller's specified host.
+      final Socket toSocket = new Socket(inetAddress, port);
+      openSockets.add(toSocket);
+      byte[] localAddress = toSocket.getLocalAddress().getAddress();
+      if (localAddress.length != 4) throw new ProtocolException();
+
+      // Write the reply.
+      fromSink.writeByte(VERSION_5)
+          .writeByte(REPLY_SUCCEEDED)
+          .writeByte(0)
+          .writeByte(ADDRESS_TYPE_IPV4)
+          .write(localAddress)
+          .writeShort(toSocket.getLocalPort())
+          .emit();
+
+      // Connect sources to sinks in both directions.
+      final Sink toSink = Okio.sink(toSocket);
+      executor.execute(() -> transfer(fromSocket, fromSource, toSink));
+      final Source toSource = Okio.source(toSocket);
+      executor.execute(() -> transfer(toSocket, toSource, fromSink));
+    } catch (IOException e) {
+      closeQuietly(fromSocket);
+      openSockets.remove(fromSocket);
+      System.out.println("connect failed for " + fromSocket + ": " + e);
+    }
+  }
+
+  /**
+   * Read data from {@code source} and write it to {@code sink}. This doesn't use {@link
+   * BufferedSink#writeAll} because that method doesn't flush aggressively and we need that.
+   */
+  private void transfer(Socket sourceSocket, Source source, Sink sink) {
+    try {
+      Buffer buffer = new Buffer();
+      for (long byteCount; (byteCount = source.read(buffer, 8192L)) != -1; ) {
+        sink.write(buffer, byteCount);
+        sink.flush();
+      }
+    } catch (IOException e) {
+      System.out.println("transfer failed from " + sourceSocket + ": " + e);
+    } finally {
+      closeQuietly(sink);
+      closeQuietly(source);
+      closeQuietly(sourceSocket);
+      openSockets.remove(sourceSocket);
+    }
+  }
+
+  private void closeQuietly(Closeable c) {
+    try {
+      c.close();
+    } catch (IOException ignored) {
+    }
+  }
+
+  public static void main(String[] args) throws IOException {
+    SocksProxyServer proxyServer = new SocksProxyServer();
+    proxyServer.start();
+
+    URL url = new URL("https://publicobject.com/helloworld.txt");
+    URLConnection connection = url.openConnection(proxyServer.proxy());
+    try (BufferedSource source = Okio.buffer(Okio.source(connection.getInputStream()))) {
+      for (String line; (line = source.readUtf8Line()) != null; ) {
+        System.out.println(line);
+      }
+    }
+
+    proxyServer.shutdown();
+  }
+}
diff --git a/samples/src/jvmMain/java/okio/samples/SourceMarker.java b/samples/src/jvmMain/java/okio/samples/SourceMarker.java
new file mode 100644
index 0000000..8deef05
--- /dev/null
+++ b/samples/src/jvmMain/java/okio/samples/SourceMarker.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2018 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 okio.samples;
+
+import java.io.IOException;
+import okio.Buffer;
+import okio.BufferedSource;
+import okio.ForwardingSource;
+import okio.Okio;
+import okio.Source;
+
+/**
+ * Builds a buffered source that can rewind to a marked position earlier in the stream.
+ *
+ * <p>Mark potential positions to rewind back to with {@link #mark}; rewind back to these positions
+ * with {@link #reset}. Both operations apply to the position in the {@linkplain #source() buffered
+ * source}; resetting will impact the buffer.
+ *
+ * <p>When marking it is necessary to specify how much data to retain. Once you advance above this
+ * limit, the mark is discarded and resetting is not permitted. This may be used to lookahead a
+ * fixed number of bytes without loading an entire stream into memory. To reset an arbitrary
+ * number of bytes use {@code mark(Long#MAX_VALUE)}.
+ */
+public final class SourceMarker {
+
+  /*
+   * This class wraps the underlying source in a MarkSource to support mark and reset. It creates a
+   * BufferedSource for the caller so that it can track its offsets and manipulate its buffer.
+   */
+
+  /**
+   * The offset into the underlying source. To compute the user's offset start with this and
+   * subtract userBuffer.size().
+   */
+  long offset;
+
+  /** The offset of the earliest mark, or -1 for no mark. */
+  long mark = -1L;
+
+  /** The offset of the latest readLimit, or -1 for no mark. */
+  long limit = -1L;
+
+  boolean closed;
+
+  final MarkSource markSource;
+  final BufferedSource userSource;
+
+  /** A copy of the underlying source's data beginning at {@code mark}. */
+  final Buffer markBuffer;
+
+  /** Just the userSource's buffer. */
+  final Buffer userBuffer;
+
+  public SourceMarker(Source source) {
+    this.markSource = new MarkSource(source);
+    this.markBuffer = new Buffer();
+    this.userSource = Okio.buffer(markSource);
+    this.userBuffer = userSource.getBuffer();
+  }
+
+  public BufferedSource source() {
+    return userSource;
+  }
+
+  /**
+   * Marks the current position in the stream as one to potentially return back to. Returns the
+   * offset of this position. Call {@link #reset(long)} with this position to return to it later. It
+   * is an error to call {@link #reset(long)} after consuming more than {@code readLimit} bytes from
+   * {@linkplain #source() the source}.
+   */
+  public long mark(long readLimit) throws IOException {
+    if (readLimit < 0L) {
+      throw new IllegalArgumentException("readLimit < 0: " + readLimit);
+    }
+
+    if (closed) {
+      throw new IllegalStateException("closed");
+    }
+
+    // Mark the current position in the buffered source.
+    long userOffset = offset - userBuffer.size();
+
+    // If this is a new mark promote userBuffer data into the markBuffer.
+    if (mark == -1L) {
+      markBuffer.writeAll(userBuffer);
+      mark = userOffset;
+      offset = userOffset;
+    }
+
+    // Grow the limit if necessary.
+    long newMarkBufferLimit = userOffset + readLimit;
+    if (newMarkBufferLimit < 0) newMarkBufferLimit = Long.MAX_VALUE; // Long overflow!
+    limit = Math.max(limit, newMarkBufferLimit);
+
+    return userOffset;
+  }
+
+  /** Resets {@linkplain #source() the source} to {@code userOffset}. */
+  public void reset(long userOffset) throws IOException {
+    if (closed) {
+      throw new IllegalStateException("closed");
+    }
+
+    if (userOffset < mark // userOffset is before mark.
+        || userOffset > limit // userOffset is beyond limit.
+        || userOffset > mark + markBuffer.size() // userOffset is in the future.
+        || offset - userBuffer.size() > limit) { // Stream advanced beyond limit.
+      throw new IOException("cannot reset to " + userOffset + ": out of range");
+    }
+
+    // Clear userBuffer to cause data at 'offset' to be returned by the next read.
+    offset = userOffset;
+    userBuffer.clear();
+  }
+
+  final class MarkSource extends ForwardingSource {
+    MarkSource(Source source) {
+      super(source);
+    }
+
+    @Override public long read(Buffer sink, long byteCount) throws IOException {
+      if (closed) {
+        throw new IllegalStateException("closed");
+      }
+
+      // If there's no mark, go to the underlying source.
+      if (mark == -1L) {
+        long result = super.read(sink, byteCount);
+        if (result == -1L) return -1L;
+        offset += result;
+        return result;
+      }
+
+      // If we can read from markBuffer, do that.
+      if (offset < mark + markBuffer.size()) {
+        long posInBuffer = offset - mark;
+        long result = Math.min(byteCount, markBuffer.size() - posInBuffer);
+        markBuffer.copyTo(sink, posInBuffer, result);
+        offset += result;
+        return result;
+      }
+
+      // If we can write to markBuffer, do that.
+      if (offset < limit) {
+        long byteCountBeforeLimit = limit - (mark + markBuffer.size());
+        long result = super.read(markBuffer, Math.min(byteCount, byteCountBeforeLimit));
+        if (result == -1L) return -1L;
+        markBuffer.copyTo(sink, markBuffer.size() - result, result);
+        offset += result;
+        return result;
+      }
+
+      // Attempt to read past the limit. Data will not be saved.
+      long result = super.read(sink, byteCount);
+      if (result == -1L) return -1L;
+
+      // We read past the limit. Discard marked data.
+      markBuffer.clear();
+      mark = -1L;
+      limit = -1L;
+      return result;
+    }
+
+    @Override public void close() throws IOException {
+      if (closed) return;
+
+      closed = true;
+      markBuffer.clear();
+      super.close();
+    }
+  }
+}
diff --git a/samples/src/jvmMain/java/okio/samples/WriteFile.java b/samples/src/jvmMain/java/okio/samples/WriteFile.java
new file mode 100644
index 0000000..e613abe
--- /dev/null
+++ b/samples/src/jvmMain/java/okio/samples/WriteFile.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2018 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 okio.samples;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+import okio.BufferedSink;
+import okio.Okio;
+import okio.Sink;
+
+public final class WriteFile {
+  public void run() throws Exception {
+    writeEnv(new File("env.txt"));
+  }
+
+  public void writeEnv(File file) throws IOException {
+    try (Sink fileSink = Okio.sink(file);
+         BufferedSink bufferedSink = Okio.buffer(fileSink)) {
+
+      for (Map.Entry<String, String> entry : System.getenv().entrySet()) {
+        bufferedSink.writeUtf8(entry.getKey());
+        bufferedSink.writeUtf8("=");
+        bufferedSink.writeUtf8(entry.getValue());
+        bufferedSink.writeUtf8("\n");
+      }
+
+    }
+  }
+
+  public static void main(String... args) throws Exception {
+    new WriteFile().run();
+  }
+}
diff --git a/samples/src/jvmMain/kotlin/okio/samples/BitmapEncoder.kt b/samples/src/jvmMain/kotlin/okio/samples/BitmapEncoder.kt
new file mode 100644
index 0000000..8642283
--- /dev/null
+++ b/samples/src/jvmMain/kotlin/okio/samples/BitmapEncoder.kt
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2018 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 okio.samples
+
+import okio.BufferedSink
+import okio.buffer
+import okio.sink
+import java.io.File
+import java.io.IOException
+import kotlin.math.hypot
+
+class KotlinBitmapEncoder {
+  class Bitmap(
+    private val pixels: Array<IntArray>
+  ) {
+    val width: Int = pixels[0].size
+    val height: Int = pixels.size
+
+    fun red(x: Int, y: Int): Int = pixels[y][x] and 0xff0000 shr 16
+
+    fun green(x: Int, y: Int): Int = pixels[y][x] and 0xff00 shr 8
+
+    fun blue(x: Int, y: Int): Int = pixels[y][x] and 0xff
+  }
+
+  /**
+   * Returns a bitmap that lights up red subpixels at the bottom, green subpixels on the right, and
+   * blue subpixels in bottom-right.
+   */
+  fun generateGradient(): Bitmap {
+    val pixels = Array(1080) { IntArray(1920) }
+    for (y in 0 until 1080) {
+      for (x in 0 until 1920) {
+        val r = (y / 1080f * 255).toInt()
+        val g = (x / 1920f * 255).toInt()
+        val b = (hypot(x.toDouble(), y.toDouble()) / hypot(1080.0, 1920.0) * 255).toInt()
+        pixels[y][x] = r shl 16 or (g shl 8) or b
+      }
+    }
+    return Bitmap(pixels)
+  }
+
+  @Throws(IOException::class)
+  fun encode(bitmap: Bitmap, file: File) {
+    file.sink().buffer().use { sink -> encode(bitmap, sink) }
+  }
+
+  /** https://en.wikipedia.org/wiki/BMP_file_format  */
+  @Throws(IOException::class)
+  fun encode(bitmap: Bitmap, sink: BufferedSink) {
+    val height = bitmap.height
+    val width = bitmap.width
+    val bytesPerPixel = 3
+    val rowByteCountWithoutPadding = bytesPerPixel * width
+    val rowByteCount = (rowByteCountWithoutPadding + 3) / 4 * 4
+    val pixelDataSize = rowByteCount * height
+    val bmpHeaderSize = 14
+    val dibHeaderSize = 40
+
+    // BMP Header
+    sink.writeUtf8("BM") // ID.
+    sink.writeIntLe(bmpHeaderSize + dibHeaderSize + pixelDataSize) // File size.
+    sink.writeShortLe(0) // Unused.
+    sink.writeShortLe(0) // Unused.
+    sink.writeIntLe(bmpHeaderSize + dibHeaderSize) // Offset of pixel data.
+
+    // DIB Header
+    sink.writeIntLe(dibHeaderSize)
+    sink.writeIntLe(width)
+    sink.writeIntLe(height)
+    sink.writeShortLe(1) // Color plane count.
+    sink.writeShortLe(bytesPerPixel * Byte.SIZE_BITS)
+    sink.writeIntLe(0) // No compression.
+    sink.writeIntLe(16) // Size of bitmap data including padding.
+    sink.writeIntLe(2835) // Horizontal print resolution in pixels/meter. (72 dpi).
+    sink.writeIntLe(2835) // Vertical print resolution in pixels/meter. (72 dpi).
+    sink.writeIntLe(0) // Palette color count.
+    sink.writeIntLe(0) // 0 important colors.
+
+    // Pixel data.
+    for (y in height - 1 downTo 0) {
+      for (x in 0 until width) {
+        sink.writeByte(bitmap.blue(x, y))
+        sink.writeByte(bitmap.green(x, y))
+        sink.writeByte(bitmap.red(x, y))
+      }
+
+      // Padding for 4-byte alignment.
+      for (p in rowByteCountWithoutPadding until rowByteCount) {
+        sink.writeByte(0)
+      }
+    }
+  }
+}
+
+fun main() {
+  val encoder = KotlinBitmapEncoder()
+  val bitmap = encoder.generateGradient()
+  encoder.encode(bitmap, File("gradient.bmp"))
+}
diff --git a/samples/src/jvmMain/kotlin/okio/samples/ExploreCharsets.kt b/samples/src/jvmMain/kotlin/okio/samples/ExploreCharsets.kt
new file mode 100644
index 0000000..824a01e
--- /dev/null
+++ b/samples/src/jvmMain/kotlin/okio/samples/ExploreCharsets.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2018 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 okio.samples
+
+import okio.ByteString.Companion.encodeUtf8
+import okio.utf8Size
+import java.io.IOException
+
+@Throws(IOException::class)
+fun dumpStringData(s: String) {
+  println("                       " + s)
+  println("        String.length: " + s.length)
+  println("String.codePointCount: " + s.codePointCount(0, s.length))
+  println("            Utf8.size: " + s.utf8Size())
+  println("          UTF-8 bytes: " + s.encodeUtf8().hex())
+  println()
+}
+
+fun main() {
+  dumpStringData("Café \uD83C\uDF69") // NFC: é is one code point.
+  dumpStringData("Café \uD83C\uDF69") // NFD: e is one code point, its accent is another.
+}
diff --git a/samples/src/jvmMain/kotlin/okio/samples/GoldenValue.kt b/samples/src/jvmMain/kotlin/okio/samples/GoldenValue.kt
new file mode 100644
index 0000000..2e86ff7
--- /dev/null
+++ b/samples/src/jvmMain/kotlin/okio/samples/GoldenValue.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2018 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 okio.samples
+
+import okio.Buffer
+import okio.ByteString
+import okio.ByteString.Companion.decodeBase64
+import java.io.IOException
+import java.io.ObjectInputStream
+import java.io.ObjectOutputStream
+import java.io.Serializable
+
+class KotlinGoldenValue {
+  fun run() {
+    val point = Point(8.0, 15.0)
+    val pointBytes = serialize(point)
+    println(pointBytes.base64())
+    val goldenBytes = (
+      "rO0ABXNyACRva2lvLnNhbXBsZXMuS290bGluR29sZGVuVmFsdWUkUG9pbnRF9yaY7cJ9EwIAA" +
+        "kQAAXhEAAF5eHBAIAAAAAAAAEAuAAAAAAAA"
+      ).decodeBase64()!!
+    val decoded = deserialize(goldenBytes) as Point
+    assertEquals(point, decoded)
+  }
+
+  @Throws(IOException::class)
+  private fun serialize(o: Any?): ByteString {
+    val buffer = Buffer()
+    ObjectOutputStream(buffer.outputStream()).use { objectOut ->
+      objectOut.writeObject(o)
+    }
+    return buffer.readByteString()
+  }
+
+  @Throws(IOException::class, ClassNotFoundException::class)
+  private fun deserialize(byteString: ByteString): Any? {
+    val buffer = Buffer()
+    buffer.write(byteString)
+    ObjectInputStream(buffer.inputStream()).use { objectIn ->
+      val result = objectIn.readObject()
+      if (objectIn.read() != -1) throw IOException("Unconsumed bytes in stream")
+      return result
+    }
+  }
+
+  internal class Point(var x: Double, var y: Double) : Serializable
+
+  private fun assertEquals(
+    a: Point,
+    b: Point
+  ) {
+    if (a.x != b.x || a.y != b.y) throw AssertionError()
+  }
+}
+
+fun main() {
+  KotlinGoldenValue().run()
+}
diff --git a/samples/src/jvmMain/kotlin/okio/samples/Hashing.kt b/samples/src/jvmMain/kotlin/okio/samples/Hashing.kt
new file mode 100644
index 0000000..3169d4e
--- /dev/null
+++ b/samples/src/jvmMain/kotlin/okio/samples/Hashing.kt
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 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 okio.samples
+
+import okio.Buffer
+import okio.ByteString
+import okio.ByteString.Companion.decodeHex
+import okio.HashingSink.Companion.sha256
+import okio.HashingSource.Companion.sha256
+import okio.blackholeSink
+import okio.buffer
+import okio.source
+import java.io.File
+import java.io.IOException
+
+class KotlinHashing {
+  fun run() {
+    val file = File("../README.md")
+
+    println("ByteString")
+    val byteString = readByteString(file)
+    println("       md5: " + byteString.md5().hex())
+    println("      sha1: " + byteString.sha1().hex())
+    println("    sha256: " + byteString.sha256().hex())
+    println("    sha512: " + byteString.sha512().hex())
+    println()
+
+    println("Buffer")
+    val buffer = readBuffer(file)
+    println("       md5: " + buffer.md5().hex())
+    println("      sha1: " + buffer.sha1().hex())
+    println("    sha256: " + buffer.sha256().hex())
+    println("    sha512: " + buffer.sha512().hex())
+    println()
+
+    println("HashingSource")
+    sha256(file.source()).use { hashingSource ->
+      hashingSource.buffer().use { source ->
+        source.readAll(blackholeSink())
+        println("    sha256: " + hashingSource.hash.hex())
+      }
+    }
+    println()
+
+    println("HashingSink")
+    sha256(blackholeSink()).use { hashingSink ->
+      hashingSink.buffer().use { sink ->
+        file.source().use { source ->
+          sink.writeAll(source)
+          sink.close() // Emit anything buffered.
+          println("    sha256: " + hashingSink.hash.hex())
+        }
+      }
+    }
+    println()
+
+    println("HMAC")
+    val secret = "7065616e7574627574746572".decodeHex()
+    println("hmacSha256: " + byteString.hmacSha256(secret).hex())
+    println()
+  }
+
+  @Throws(IOException::class)
+  fun readByteString(file: File): ByteString {
+    return file.source().buffer().use { it.readByteString() }
+  }
+
+  @Throws(IOException::class)
+  fun readBuffer(file: File): Buffer {
+    return file.source().use { source ->
+      Buffer().also { it.writeAll(source) }
+    }
+  }
+}
+
+fun main() {
+  KotlinHashing().run()
+}
diff --git a/samples/src/jvmMain/kotlin/okio/samples/ReadFileLineByLine.kt b/samples/src/jvmMain/kotlin/okio/samples/ReadFileLineByLine.kt
new file mode 100644
index 0000000..b3fa31b
--- /dev/null
+++ b/samples/src/jvmMain/kotlin/okio/samples/ReadFileLineByLine.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 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 okio.samples
+
+import okio.buffer
+import okio.source
+import java.io.File
+import java.io.IOException
+
+@Throws(IOException::class)
+fun readLines(file: File) {
+  file.source().use { fileSource ->
+    fileSource.buffer().use { bufferedFileSource ->
+      while (true) {
+        val line = bufferedFileSource.readUtf8Line() ?: break
+        if ("square" in line) {
+          println(line)
+        }
+      }
+    }
+  }
+}
+
+fun main() {
+  readLines(File("../README.md"))
+}
diff --git a/samples/src/jvmMain/kotlin/okio/samples/SocksProxyServer.kt b/samples/src/jvmMain/kotlin/okio/samples/SocksProxyServer.kt
new file mode 100644
index 0000000..d3b786a
--- /dev/null
+++ b/samples/src/jvmMain/kotlin/okio/samples/SocksProxyServer.kt
@@ -0,0 +1,189 @@
+/*
+ * 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 okio.samples
+
+import okio.Buffer
+import okio.BufferedSink
+import okio.Sink
+import okio.Source
+import okio.buffer
+import okio.sink
+import okio.source
+import java.io.IOException
+import java.net.InetAddress
+import java.net.InetSocketAddress
+import java.net.ProtocolException
+import java.net.Proxy
+import java.net.ServerSocket
+import java.net.Socket
+import java.net.URL
+import java.util.Collections
+import java.util.concurrent.ConcurrentHashMap
+import java.util.concurrent.Executors
+
+private const val VERSION_5 = 5
+private const val METHOD_NO_AUTHENTICATION_REQUIRED = 0
+private const val ADDRESS_TYPE_IPV4 = 1
+private const val ADDRESS_TYPE_DOMAIN_NAME = 3
+private const val COMMAND_CONNECT = 1
+private const val REPLY_SUCCEEDED = 0
+
+/**
+ * A partial implementation of SOCKS Protocol Version 5.
+ * See [RFC 1928](https://www.ietf.org/rfc/rfc1928.txt).
+ */
+class KotlinSocksProxyServer {
+  private val executor = Executors.newCachedThreadPool()
+  private lateinit var serverSocket: ServerSocket
+  private val openSockets: MutableSet<Socket> = Collections.newSetFromMap(ConcurrentHashMap())
+
+  @Throws(IOException::class)
+  fun start() {
+    serverSocket = ServerSocket(0)
+    executor.execute { acceptSockets() }
+  }
+
+  @Throws(IOException::class)
+  fun shutdown() {
+    serverSocket.close()
+    executor.shutdown()
+  }
+
+  fun proxy(): Proxy = Proxy(
+    Proxy.Type.SOCKS,
+    InetSocketAddress.createUnresolved("localhost", serverSocket.localPort)
+  )
+
+  private fun acceptSockets() {
+    try {
+      while (true) {
+        val from = serverSocket.accept()
+        openSockets.add(from)
+        executor.execute { handleSocket(from) }
+      }
+    } catch (e: IOException) {
+      println("shutting down: $e")
+    } finally {
+      for (socket in openSockets) {
+        socket.close()
+      }
+    }
+  }
+
+  private fun handleSocket(fromSocket: Socket) {
+    try {
+      val fromSource = fromSocket.source().buffer()
+      val fromSink = fromSocket.sink().buffer()
+
+      // Read the hello.
+      val socksVersion = fromSource.readByte().toInt() and 0xff
+      if (socksVersion != VERSION_5) throw ProtocolException()
+      val methodCount = fromSource.readByte().toInt() and 0xff
+      var foundSupportedMethod = false
+      for (i in 0 until methodCount) {
+        val method: Int = fromSource.readByte().toInt() and 0xff
+        foundSupportedMethod = foundSupportedMethod or (method == METHOD_NO_AUTHENTICATION_REQUIRED)
+      }
+      if (!foundSupportedMethod) throw ProtocolException()
+
+      // Respond to hello.
+      fromSink.writeByte(VERSION_5)
+        .writeByte(METHOD_NO_AUTHENTICATION_REQUIRED)
+        .emit()
+
+      // Read a command.
+      val version = fromSource.readByte().toInt() and 0xff
+      val command = fromSource.readByte().toInt() and 0xff
+      val reserved = fromSource.readByte().toInt() and 0xff
+      if (version != VERSION_5 || command != COMMAND_CONNECT || reserved != 0) {
+        throw ProtocolException()
+      }
+
+      // Read an address.
+      val addressType = fromSource.readByte().toInt() and 0xff
+      val inetAddress = when (addressType) {
+        ADDRESS_TYPE_IPV4 -> InetAddress.getByAddress(fromSource.readByteArray(4L))
+        ADDRESS_TYPE_DOMAIN_NAME -> {
+          val domainNameLength: Int = fromSource.readByte().toInt() and 0xff
+          InetAddress.getByName(fromSource.readUtf8(domainNameLength.toLong()))
+        }
+        else -> throw ProtocolException()
+      }
+      val port = fromSource.readShort().toInt() and 0xffff
+
+      // Connect to the caller's specified host.
+      val toSocket = Socket(inetAddress, port)
+      openSockets.add(toSocket)
+      val localAddress = toSocket.localAddress.address
+      if (localAddress.size != 4) throw ProtocolException()
+
+      // Write the reply.
+      fromSink.writeByte(VERSION_5)
+        .writeByte(REPLY_SUCCEEDED)
+        .writeByte(0)
+        .writeByte(ADDRESS_TYPE_IPV4)
+        .write(localAddress)
+        .writeShort(toSocket.localPort)
+        .emit()
+
+      // Connect sources to sinks in both directions.
+      val toSink = toSocket.sink()
+      executor.execute { transfer(fromSocket, fromSource, toSink) }
+      val toSource = toSocket.source()
+      executor.execute { transfer(toSocket, toSource, fromSink) }
+    } catch (e: IOException) {
+      fromSocket.close()
+      openSockets.remove(fromSocket)
+      println("connect failed for $fromSocket: $e")
+    }
+  }
+
+  /**
+   * Read data from `source` and write it to `sink`. This doesn't use [BufferedSink.writeAll]
+   * because that method doesn't flush aggressively and we need that.
+   */
+  private fun transfer(sourceSocket: Socket, source: Source, sink: Sink) {
+    try {
+      val buffer = Buffer()
+      var byteCount: Long
+      while (source.read(buffer, 8192L).also { byteCount = it } != -1L) {
+        sink.write(buffer, byteCount)
+        sink.flush()
+      }
+    } catch (e: IOException) {
+      println("transfer failed from $sourceSocket: $e")
+    } finally {
+      sink.close()
+      source.close()
+      sourceSocket.close()
+      openSockets.remove(sourceSocket)
+    }
+  }
+}
+
+fun main() {
+  val proxyServer = KotlinSocksProxyServer()
+  proxyServer.start()
+
+  val url = URL("https://publicobject.com/helloworld.txt")
+  val connection = url.openConnection(proxyServer.proxy())
+  connection.getInputStream().source().buffer().use { source ->
+    generateSequence { source.readUtf8Line() }
+      .forEach(::println)
+  }
+
+  proxyServer.shutdown()
+}
diff --git a/samples/src/jvmMain/kotlin/okio/samples/WriteFile.kt b/samples/src/jvmMain/kotlin/okio/samples/WriteFile.kt
new file mode 100644
index 0000000..5672693
--- /dev/null
+++ b/samples/src/jvmMain/kotlin/okio/samples/WriteFile.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2018 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 okio.samples
+
+import okio.buffer
+import okio.sink
+import java.io.File
+import java.io.IOException
+
+@Throws(IOException::class)
+fun writeEnv(file: File) {
+  file.sink().buffer().use { sink ->
+    for ((key, value) in System.getenv()) {
+      sink.writeUtf8(key)
+      sink.writeUtf8("=")
+      sink.writeUtf8(value)
+      sink.writeUtf8("\n")
+    }
+  }
+}
+
+fun main() {
+  writeEnv(File("env.txt"))
+}
diff --git a/samples/src/jvmTest/java/okio/samples/ChannelsTest.java b/samples/src/jvmTest/java/okio/samples/ChannelsTest.java
new file mode 100644
index 0000000..8c49747
--- /dev/null
+++ b/samples/src/jvmTest/java/okio/samples/ChannelsTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2018 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 okio.samples;
+
+import java.nio.channels.FileChannel;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.util.EnumSet;
+import java.util.Set;
+import okio.Buffer;
+import okio.BufferedSource;
+import okio.Okio;
+import okio.Sink;
+import okio.Source;
+import okio.Timeout;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import static java.nio.file.StandardOpenOption.APPEND;
+import static java.nio.file.StandardOpenOption.READ;
+import static java.nio.file.StandardOpenOption.WRITE;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public final class ChannelsTest {
+  private static final String quote =
+      "John, the kind of control you're attempting simply is... it's not "
+          + "possible. If there is one thing the history of evolution has "
+          + "taught us it's that life will not be contained. Life breaks "
+          + "free, it expands to new territories and crashes through "
+          + "barriers, painfully, maybe even dangerously, but, uh... well, "
+          + "there it is.";
+
+  private static final Set<StandardOpenOption> r = EnumSet.of(READ);
+  private static final Set<StandardOpenOption> w = EnumSet.of(WRITE);
+  private static final Set<StandardOpenOption> append = EnumSet.of(WRITE, APPEND);
+
+  @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  @Test public void testReadChannel() throws Exception {
+    ReadableByteChannel channel = new Buffer().writeUtf8(quote);
+
+    Buffer buffer = new Buffer();
+    Source source = new ByteChannelSource(channel, Timeout.NONE);
+    source.read(buffer, 75);
+
+    assertThat(buffer.readUtf8())
+        .isEqualTo("John, the kind of control you're attempting simply is... it's not possible.");
+  }
+
+  @Test public void testReadChannelFully() throws Exception {
+    ReadableByteChannel channel = new Buffer().writeUtf8(quote);
+
+    BufferedSource source = Okio.buffer(new ByteChannelSource(channel, Timeout.NONE));
+    assertThat(source.readUtf8())
+        .isEqualTo(quote);
+  }
+
+  @Test public void testWriteChannel() throws Exception {
+    Buffer channel = new Buffer();
+
+    Sink sink = new ByteChannelSink(channel, Timeout.NONE);
+    sink.write(new Buffer().writeUtf8(quote), 75);
+
+    assertThat(channel.readUtf8())
+        .isEqualTo("John, the kind of control you're attempting simply is... it's not possible.");
+  }
+
+  @Test public void testReadWriteFile() throws Exception {
+    Path path = temporaryFolder.newFile().toPath();
+
+    Sink sink = new FileChannelSink(FileChannel.open(path, w), Timeout.NONE);
+    sink.write(new Buffer().writeUtf8(quote), 317);
+    sink.close();
+    assertTrue(Files.exists(path));
+    assertEquals(quote.length(), Files.size(path));
+
+    Buffer buffer = new Buffer();
+    Source source = new FileChannelSource(FileChannel.open(path, r), Timeout.NONE);
+
+    source.read(buffer, 44);
+    assertThat(buffer.readUtf8())
+        .isEqualTo("John, the kind of control you're attempting ");
+
+    source.read(buffer, 31);
+    assertThat(buffer.readUtf8())
+        .isEqualTo("simply is... it's not possible.");
+  }
+
+  @Test public void testAppend() throws Exception {
+    Path path = temporaryFolder.newFile().toPath();
+
+    Buffer buffer = new Buffer().writeUtf8(quote);
+    Sink sink;
+    BufferedSource source;
+
+    sink = new FileChannelSink(FileChannel.open(path, w), Timeout.NONE);
+    sink.write(buffer, 75);
+    sink.close();
+    assertTrue(Files.exists(path));
+    assertEquals(75, Files.size(path));
+
+    source = Okio.buffer(new FileChannelSource(FileChannel.open(path, r), Timeout.NONE));
+    assertThat(source.readUtf8())
+        .isEqualTo("John, the kind of control you're attempting simply is... it's not possible.");
+
+    sink = new FileChannelSink(FileChannel.open(path, append), Timeout.NONE);
+    sink.write(buffer, buffer.size());
+    sink.close();
+    assertTrue(Files.exists(path));
+    assertEquals(quote.length(), Files.size(path));
+
+    source = Okio.buffer(new FileChannelSource(FileChannel.open(path, r), Timeout.NONE));
+    assertThat(source.readUtf8())
+        .isEqualTo(quote);
+  }
+}
diff --git a/samples/src/jvmTest/java/okio/samples/SourceMarkerTest.java b/samples/src/jvmTest/java/okio/samples/SourceMarkerTest.java
new file mode 100644
index 0000000..cdc363e
--- /dev/null
+++ b/samples/src/jvmTest/java/okio/samples/SourceMarkerTest.java
@@ -0,0 +1,243 @@
+/*
+ * 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 okio.samples;
+
+import java.io.IOException;
+import java.util.Arrays;
+import okio.Buffer;
+import okio.BufferedSource;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.fail;
+
+public final class SourceMarkerTest {
+  @Test public void test() throws Exception {
+    SourceMarker marker = new SourceMarker(new Buffer().writeUtf8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+    BufferedSource source = marker.source();
+
+    assertThat(source.readUtf8(3)).isEqualTo("ABC");
+    long pos3 = marker.mark(7); // DEFGHIJ
+    assertThat(source.readUtf8(4)).isEqualTo("DEFG");
+    long pos7 = marker.mark(5); // HIJKL
+    assertThat(source.readUtf8(4)).isEqualTo("HIJK");
+    marker.reset(pos7); // Back to 'H'
+    assertThat(source.readUtf8(3)).isEqualTo("HIJ");
+    marker.reset(pos3); // Back to 'D'
+    assertThat(source.readUtf8(7)).isEqualTo("DEFGHIJ");
+    marker.reset(pos7); // Back to 'H' again.
+    assertThat(source.readUtf8(6)).isEqualTo("HIJKLM");
+    try {
+      marker.reset(pos7);
+      fail();
+    } catch (IOException expected) {
+      assertThat(expected).hasMessage("cannot reset to 7: out of range");
+    }
+    try {
+      marker.reset(pos3);
+      fail();
+    } catch (IOException expected) {
+      assertThat(expected).hasMessage("cannot reset to 3: out of range");
+    }
+  }
+
+  @Test public void exceedLimitTest() throws Exception {
+    SourceMarker marker = new SourceMarker(new Buffer().writeUtf8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+    BufferedSource source = marker.source();
+
+    assertThat(source.readUtf8(3)).isEqualTo("ABC");
+    long pos3 = marker.mark(Long.MAX_VALUE); // D...
+    assertThat(source.readUtf8(4)).isEqualTo("DEFG");
+    long pos7 = marker.mark(5); // H...
+    assertThat(source.readUtf8(4)).isEqualTo("HIJK");
+    marker.reset(pos7); // Back to 'H'
+    assertThat(source.readUtf8(3)).isEqualTo("HIJ");
+    marker.reset(pos3); // Back to 'D'
+    assertThat(source.readUtf8(7)).isEqualTo("DEFGHIJ");
+    marker.reset(pos7); // Back to 'H' again.
+    assertThat(source.readUtf8(6)).isEqualTo("HIJKLM");
+
+    marker.reset(pos7); // Back to 'H' again despite the original limit being exceeded
+    assertThat(source.readUtf8(2)).isEqualTo("HI"); // confirm we're really back at H
+
+    marker.reset(pos3); // Back to 'D' again despite the original limit being exceeded
+    assertThat(source.readUtf8(2)).isEqualTo("DE"); // confirm that we're really back at D
+  }
+
+  @Test public void markAndLimitSmallerThanUserBuffer() throws Exception {
+    SourceMarker marker = new SourceMarker(new Buffer().writeUtf8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+    BufferedSource source = marker.source();
+
+    // Load 5 bytes into the user buffer, then mark 0..3 and confirm that resetting from 4 fails.
+    source.require(5);
+    long pos0 = marker.mark(3);
+    assertThat(source.readUtf8(3)).isEqualTo("ABC");
+    marker.reset(pos0);
+    assertThat(source.readUtf8(4)).isEqualTo("ABCD");
+    try {
+      marker.reset(pos0);
+      fail();
+    } catch (IOException expected) {
+      assertThat(expected).hasMessage("cannot reset to 0: out of range");
+    }
+  }
+
+  @Test public void resetTooLow() throws Exception {
+    SourceMarker marker = new SourceMarker(new Buffer().writeUtf8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+    BufferedSource source = marker.source();
+
+    source.skip(3);
+    marker.mark(3);
+    source.skip(2);
+    try {
+      marker.reset(2);
+      fail();
+    } catch (IOException expected) {
+      assertThat(expected).hasMessage("cannot reset to 2: out of range");
+    }
+  }
+
+  @Test public void resetTooHigh() throws Exception {
+    SourceMarker marker = new SourceMarker(new Buffer().writeUtf8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+    BufferedSource source = marker.source();
+
+    marker.mark(3);
+    source.skip(6);
+    try {
+      marker.reset(4);
+      fail();
+    } catch (IOException expected) {
+      assertThat(expected).hasMessage("cannot reset to 4: out of range");
+    }
+  }
+
+  @Test public void resetUnread() throws Exception {
+    SourceMarker marker = new SourceMarker(new Buffer().writeUtf8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+
+    marker.mark(3);
+    try {
+      marker.reset(2);
+      fail();
+    } catch (IOException expected) {
+      assertThat(expected).hasMessage("cannot reset to 2: out of range");
+    }
+  }
+
+  @Test public void markNothingBuffered() throws Exception {
+    SourceMarker marker = new SourceMarker(new Buffer().writeUtf8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+    BufferedSource source = marker.source();
+
+    long pos0 = marker.mark(5);
+    assertThat(source.readUtf8(4)).isEqualTo("ABCD");
+    marker.reset(pos0);
+    assertThat(source.readUtf8(6)).isEqualTo("ABCDEF");
+  }
+
+  @Test public void mark0() throws Exception {
+    SourceMarker marker = new SourceMarker(new Buffer().writeUtf8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+    BufferedSource source = marker.source();
+
+    long pos0 = marker.mark(0);
+    marker.reset(pos0);
+    assertThat(source.readUtf8(3)).isEqualTo("ABC");
+  }
+
+  @Test public void markNegative() throws Exception {
+    SourceMarker marker = new SourceMarker(new Buffer().writeUtf8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+
+    try {
+      marker.mark(-1L);
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertThat(expected).hasMessage("readLimit < 0: -1");
+    }
+  }
+
+  @Test public void resetAfterEof() throws Exception {
+    SourceMarker marker = new SourceMarker(new Buffer().writeUtf8("ABCDE"));
+    BufferedSource source = marker.source();
+
+    long pos0 = marker.mark(5);
+    assertThat(source.readUtf8()).isEqualTo("ABCDE");
+    marker.reset(pos0);
+    assertThat(source.readUtf8(3)).isEqualTo("ABC");
+  }
+
+  @Test public void closeThenMark() throws Exception {
+    SourceMarker marker = new SourceMarker(new Buffer().writeUtf8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+    BufferedSource source = marker.source();
+
+    source.close();
+    try {
+      marker.mark(5);
+      fail();
+    } catch (IllegalStateException expected) {
+      assertThat(expected).hasMessage("closed");
+    }
+  }
+
+  @Test public void closeThenReset() throws Exception {
+    SourceMarker marker = new SourceMarker(new Buffer().writeUtf8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+    BufferedSource source = marker.source();
+
+    long pos0 = marker.mark(5);
+    source.close();
+    try {
+      marker.reset(pos0);
+      fail();
+    } catch (IllegalStateException expected) {
+      assertThat(expected).hasMessage("closed");
+    }
+  }
+
+  @Test public void closeThenRead() throws Exception {
+    SourceMarker marker = new SourceMarker(new Buffer().writeUtf8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+    BufferedSource source = marker.source();
+
+    source.close();
+    try {
+      source.readUtf8(3);
+      fail();
+    } catch (IllegalStateException expected) {
+      assertThat(expected).hasMessage("closed");
+    }
+  }
+
+  @Test public void multipleSegments() throws Exception {
+    String as = repeat('a', 10_000);
+    String bs = repeat('b', 10_000);
+    String cs = repeat('c', 10_000);
+    String ds = repeat('d', 10_000);
+
+    SourceMarker marker = new SourceMarker(new Buffer().writeUtf8(as + bs + cs + ds));
+    BufferedSource source = marker.source();
+
+    assertThat(source.readUtf8(10_000)).isEqualTo(as);
+    long pos10k = marker.mark(15_000);
+    assertThat(source.readUtf8(10_000)).isEqualTo(bs);
+    long pos20k = marker.mark(15_000);
+    assertThat(source.readUtf8(10_000)).isEqualTo(cs);
+    marker.reset(pos20k);
+    marker.reset(pos10k);
+    assertThat(source.readUtf8(30_000)).isEqualTo(bs + cs + ds);
+  }
+
+  private String repeat(char c, int count) {
+    char[] array = new char[count];
+    Arrays.fill(array, c);
+    return new String(array);
+  }
+}
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..97f9d9e
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,14 @@
+rootProject.name = 'okio-parent'
+
+include ':okio'
+include ':okio:jvm:japicmp'
+include ':okio:jvm:jmh'
+include ':samples'
+
+enableFeaturePreview("GRADLE_METADATA")
+
+// The Android test module doesn't work in IntelliJ. Use Android Studio or the command line.
+if (properties.containsKey('android.injected.invoked.from.ide') ||
+  System.getenv('ANDROID_SDK_ROOT') != null) {
+  include ':android-test'
+}
