Bug 1391523 - P5: Compile in audioipc crates. r=rillian draft
authorDan Glastonbury <dan.glastonbury@gmail.com>
Fri, 11 Aug 2017 12:41:35 +1000
changeset 652728 6203fa31c9eea8cf7e9f0b02fbd923d755ee56cc
parent 652727 0c18bcec9246429a62209faa6433b9d9b11023af
child 652729 58b855e514c99406d98993803e6d043524c2b290
push id76138
push userbmo:dglastonbury@mozilla.com
push dateFri, 25 Aug 2017 06:15:19 +0000
reviewersrillian
bugs1391523
milestone57.0a1
Bug 1391523 - P5: Compile in audioipc crates. r=rillian MozReview-Commit-ID: 6BC0fu1rrEE
third_party/rust/error-chain/.cargo-checksum.json
third_party/rust/error-chain/.cargo-ok
third_party/rust/error-chain/.travis.yml
third_party/rust/error-chain/CHANGELOG.md
third_party/rust/error-chain/Cargo.toml
third_party/rust/error-chain/README.md
third_party/rust/error-chain/examples/all.rs
third_party/rust/error-chain/examples/doc.rs
third_party/rust/error-chain/examples/quickstart.rs
third_party/rust/error-chain/examples/size.rs
third_party/rust/error-chain/src/error_chain.rs
third_party/rust/error-chain/src/example_generated.rs
third_party/rust/error-chain/src/lib.rs
third_party/rust/error-chain/src/quick_error.rs
third_party/rust/error-chain/src/quick_main.rs
third_party/rust/error-chain/tests/quick_main.rs
third_party/rust/error-chain/tests/tests.rs
third_party/rust/fs2/.appveyor.yml
third_party/rust/fs2/.cargo-checksum.json
third_party/rust/fs2/.cargo-ok
third_party/rust/fs2/.travis.yml
third_party/rust/fs2/Cargo.toml
third_party/rust/fs2/LICENSE-APACHE
third_party/rust/fs2/LICENSE-MIT
third_party/rust/fs2/README.md
third_party/rust/fs2/src/lib.rs
third_party/rust/fs2/src/unix.rs
third_party/rust/fs2/src/windows.rs
third_party/rust/iovec/.cargo-checksum.json
third_party/rust/iovec/.cargo-ok
third_party/rust/iovec/.travis.yml
third_party/rust/iovec/Cargo.toml
third_party/rust/iovec/LICENSE-APACHE
third_party/rust/iovec/LICENSE-MIT
third_party/rust/iovec/README.md
third_party/rust/iovec/appveyor.yml
third_party/rust/iovec/src/lib.rs
third_party/rust/iovec/src/sys/mod.rs
third_party/rust/iovec/src/sys/unix.rs
third_party/rust/iovec/src/sys/windows.rs
third_party/rust/iovec/src/unix.rs
third_party/rust/iovec/src/windows.rs
third_party/rust/lazycell/.cargo-checksum.json
third_party/rust/lazycell/.cargo-ok
third_party/rust/lazycell/CHANGELOG.md
third_party/rust/lazycell/Cargo.toml
third_party/rust/lazycell/LICENSE-APACHE
third_party/rust/lazycell/LICENSE-MIT
third_party/rust/lazycell/README.md
third_party/rust/lazycell/src/lib.rs
third_party/rust/memmap/.appveyor.yml
third_party/rust/memmap/.cargo-checksum.json
third_party/rust/memmap/.cargo-ok
third_party/rust/memmap/.travis.yml
third_party/rust/memmap/Cargo.toml
third_party/rust/memmap/LICENSE-APACHE
third_party/rust/memmap/LICENSE-MIT
third_party/rust/memmap/README.md
third_party/rust/memmap/ci/install.sh
third_party/rust/memmap/ci/script.sh
third_party/rust/memmap/examples/cat.rs
third_party/rust/memmap/src/lib.rs
third_party/rust/memmap/src/unix.rs
third_party/rust/memmap/src/windows.rs
third_party/rust/mio-uds/.cargo-checksum.json
third_party/rust/mio-uds/.cargo-ok
third_party/rust/mio-uds/.travis.yml
third_party/rust/mio-uds/Cargo.toml
third_party/rust/mio-uds/LICENSE-APACHE
third_party/rust/mio-uds/LICENSE-MIT
third_party/rust/mio-uds/README.md
third_party/rust/mio-uds/src/datagram.rs
third_party/rust/mio-uds/src/lib.rs
third_party/rust/mio-uds/src/listener.rs
third_party/rust/mio-uds/src/socket.rs
third_party/rust/mio-uds/src/stream.rs
third_party/rust/mio-uds/tests/echo.rs
third_party/rust/mio-uds/tests/smoke.rs
third_party/rust/mio/.cargo-checksum.json
third_party/rust/mio/.cargo-ok
third_party/rust/mio/CHANGELOG.md
third_party/rust/mio/Cargo.toml
third_party/rust/mio/LICENSE
third_party/rust/mio/README.md
third_party/rust/mio/appveyor.yml
third_party/rust/mio/benches/bench_poll.rs
third_party/rust/mio/ci/docker/aarch64-linux-android/Dockerfile
third_party/rust/mio/ci/docker/aarch64-linux-android/accept-licenses.sh
third_party/rust/mio/ci/docker/aarch64-linux-android/cargo_config
third_party/rust/mio/ci/docker/aarch64-linux-android/install-ndk.sh
third_party/rust/mio/ci/docker/aarch64-linux-android/install-sdk.sh
third_party/rust/mio/ci/docker/arm-linux-androideabi/Dockerfile
third_party/rust/mio/ci/docker/arm-linux-androideabi/accept-licenses.sh
third_party/rust/mio/ci/docker/arm-linux-androideabi/cargo_config
third_party/rust/mio/ci/docker/arm-linux-androideabi/install-ndk.sh
third_party/rust/mio/ci/docker/arm-linux-androideabi/install-sdk.sh
third_party/rust/mio/ci/ios/deploy_and_run_on_ios_simulator.rs
third_party/rust/mio/ci/run-docker.sh
third_party/rust/mio/ci/run-ios.sh
third_party/rust/mio/ci/run.sh
third_party/rust/mio/ci/trust/install.sh
third_party/rust/mio/ci/trust/script.sh
third_party/rust/mio/src/channel.rs
third_party/rust/mio/src/deprecated/event_loop.rs
third_party/rust/mio/src/deprecated/handler.rs
third_party/rust/mio/src/deprecated/io.rs
third_party/rust/mio/src/deprecated/mod.rs
third_party/rust/mio/src/deprecated/notify.rs
third_party/rust/mio/src/deprecated/unix.rs
third_party/rust/mio/src/event_imp.rs
third_party/rust/mio/src/io.rs
third_party/rust/mio/src/lib.rs
third_party/rust/mio/src/net/mod.rs
third_party/rust/mio/src/net/tcp.rs
third_party/rust/mio/src/net/udp.rs
third_party/rust/mio/src/poll.rs
third_party/rust/mio/src/sys/mod.rs
third_party/rust/mio/src/sys/unix/awakener.rs
third_party/rust/mio/src/sys/unix/dlsym.rs
third_party/rust/mio/src/sys/unix/epoll.rs
third_party/rust/mio/src/sys/unix/eventedfd.rs
third_party/rust/mio/src/sys/unix/io.rs
third_party/rust/mio/src/sys/unix/kqueue.rs
third_party/rust/mio/src/sys/unix/mod.rs
third_party/rust/mio/src/sys/unix/ready.rs
third_party/rust/mio/src/sys/unix/tcp.rs
third_party/rust/mio/src/sys/unix/udp.rs
third_party/rust/mio/src/sys/unix/uds.rs
third_party/rust/mio/src/sys/windows/awakener.rs
third_party/rust/mio/src/sys/windows/buffer_pool.rs
third_party/rust/mio/src/sys/windows/from_raw_arc.rs
third_party/rust/mio/src/sys/windows/mod.rs
third_party/rust/mio/src/sys/windows/selector.rs
third_party/rust/mio/src/sys/windows/tcp.rs
third_party/rust/mio/src/sys/windows/udp.rs
third_party/rust/mio/src/timer.rs
third_party/rust/mio/src/token.rs
third_party/rust/mio/src/udp.rs
third_party/rust/miow/.cargo-checksum.json
third_party/rust/miow/.cargo-ok
third_party/rust/miow/Cargo.toml
third_party/rust/miow/LICENSE-APACHE
third_party/rust/miow/LICENSE-MIT
third_party/rust/miow/README.md
third_party/rust/miow/appveyor.yml
third_party/rust/miow/src/handle.rs
third_party/rust/miow/src/iocp.rs
third_party/rust/miow/src/lib.rs
third_party/rust/miow/src/net.rs
third_party/rust/miow/src/overlapped.rs
third_party/rust/miow/src/pipe.rs
third_party/rust/net2/.cargo-checksum.json
third_party/rust/net2/.cargo-ok
third_party/rust/net2/.travis.yml
third_party/rust/net2/Cargo.toml
third_party/rust/net2/LICENSE-APACHE
third_party/rust/net2/LICENSE-MIT
third_party/rust/net2/README.md
third_party/rust/net2/appveyor.yml
third_party/rust/net2/src/ext.rs
third_party/rust/net2/src/lib.rs
third_party/rust/net2/src/socket.rs
third_party/rust/net2/src/sys/unix/impls.rs
third_party/rust/net2/src/sys/unix/mod.rs
third_party/rust/net2/src/sys/windows/impls.rs
third_party/rust/net2/src/sys/windows/mod.rs
third_party/rust/net2/src/tcp.rs
third_party/rust/net2/src/udp.rs
third_party/rust/net2/src/unix.rs
third_party/rust/net2/src/utils.rs
third_party/rust/net2/tests/all.rs
third_party/rust/slab/.cargo-checksum.json
third_party/rust/slab/.cargo-ok
third_party/rust/slab/Cargo.toml
third_party/rust/slab/README.md
third_party/rust/slab/src/lib.rs
third_party/rust/ws2_32-sys/.cargo-checksum.json
third_party/rust/ws2_32-sys/.cargo-ok
third_party/rust/ws2_32-sys/Cargo.toml
third_party/rust/ws2_32-sys/README.md
third_party/rust/ws2_32-sys/build.rs
third_party/rust/ws2_32-sys/src/lib.rs
toolkit/library/gtest/rust/Cargo.lock
toolkit/library/gtest/rust/Cargo.toml
toolkit/library/rust/Cargo.lock
toolkit/library/rust/Cargo.toml
toolkit/library/rust/gkrust-features.mozbuild
toolkit/library/rust/shared/Cargo.toml
toolkit/library/rust/shared/lib.rs
toolkit/moz.configure
new file mode 100644
--- /dev/null
+++ b/third_party/rust/error-chain/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"d56246d6c8796c638b5012c2d7a91d9b6ec101b6a47128e2d4bfa957c1c784e8","CHANGELOG.md":"4f602de0b17e0d0121371482dfcf3caf2265b70bf92e8b5db1cba5dd8f391469","Cargo.toml":"8e4d1f0b25be862107a6938190c9817cd7ea516db50e688de1d0fe87519105ee","README.md":"6771ca940645b2f7e7a018c8cd25b25f8bf35786e229b54fa2fded1f2d0ae411","examples/all.rs":"6f073ea0e3db541a4eefb41436fc03a121a1f932fd6a2798b485a72d64bd1a3c","examples/doc.rs":"574948eb776c3d363f5cff9a48015bab6c17828c7306dc3eb8818afa90a31a83","examples/quickstart.rs":"c3142d5139d89c3861b119507a372fba47ac3d7df61aa90b068d518dea8fd6f6","examples/size.rs":"7922acd891dfd06f1d36308a3ccdf03def2646b2f39bfd1b15cf2896247bad8f","src/error_chain.rs":"d0cb3e4a93f9c358e4bd18ab8443573e57ace15442f4697ad95963d10408f882","src/example_generated.rs":"7d5220020aada7def70d3b3e396dadb0b139ed104b1253d06ac53f48517ec668","src/lib.rs":"0d1c972252dd1df3117ddf0a71a4734cdb350b41376e09cbe4b868afb0e2762b","src/quick_error.rs":"1889b9ca1f7a5e9124275fd5da81e709d0d6bd3b06915bf320c23d4c4f083301","src/quick_main.rs":"106a0cf44a6a2fbb9fb1d8932d234f43cd7af230fc6685b28f6b9dfaca2a3210","tests/quick_main.rs":"1d6a726856b954d4cffddab00602583921972ceeeb2bf7ba9ebbac6a51584b53","tests/tests.rs":"67b6acf87f4986fa013f018195e3becd6dd63d8101a7af07a417e8e526cf50ad"},"package":"d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8"}
\ No newline at end of file
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/third_party/rust/error-chain/.travis.yml
@@ -0,0 +1,45 @@
+language: rust
+rust:
+- stable
+- beta
+- nightly
+# Oldest supported version for all features.
+# Use of https://github.com/rust-lang/rfcs/pull/16
+- 1.13.0
+# Oldest supported version as dependency, with no features, tests, or examples.
+- 1.10.0
+
+sudo: false
+cache: cargo
+addons:
+  apt:
+    packages:
+    - libcurl4-openssl-dev
+    - libelf-dev
+    - libdw-dev
+
+before_script:
+- |
+  pip install 'travis-cargo<0.2' --user &&
+  export PATH=$HOME/.local/bin:$PATH
+
+script:
+- travis-cargo build -- $FEATURES
+- travis-cargo --skip 1.10.0 test -- $FEATURES
+
+after_success:
+- travis-cargo --only stable doc
+- travis-cargo --only stable doc-upload
+
+env:
+  global:
+  - secure: ncxJbvJM1vCZfcEftjsFKJMxxhKLgWKaR8Go9AMo0VB5fB2XVW/6NYO5bQEEYpOf1Nc/+2FbI2+Dkz0S/mJpUcNSfBgablCHgwU2sHse7KsoaqfHj2mf1E3exjzSHoP96hPGicC5zAjSXFjCgJPOUSGqqRaJ7z5AsJLhJT6LuK7QpvwPBZzklUN8T+n1sVmws8TNmRIbaniq/q6wYHANHcy6Dl59dx4sKwniUGiZdUhCiddVpoxbECSxc0A8mN2pk7/aW+WGxK3goBs5ZF7+JXF318F62pDcXQmR5CX6WdpenIcJ25g1Vg1WhQ4Ifpe17CN0bfxV8ShuzrQUThCDMffZCo9XySBtODdEowwK1UIpjnFLfIxjOs45Cd8o3tM2j0CfvtnjOz6BCdUU0qiwNPPNx0wFkx3ZiOfSh+FhBhvyPM12HN2tdN0esgVBItFmEci+sSIIXqjVL6DNiu5zTjbu0bs6COwlUWdmL6vmsZtq5tl7Cno9+C3szxRVAkShGydd04l9NYjqNEzTa1EPG50OsnVRKGdRiFzSxhc3BWExNKvcQ4v867t6/PpPkW6s4oXmYI3+De+8O7ExWc6a4alcrDXKlMs5fCb5Pcd4Ju9kowcjkoJo5yf2wW3Ox5R8SJpaEEpvyhx5O/qtIxjhHNzeo8Wsr/6gdNDv20r91TI=
+  - TRAVIS_CARGO_NIGHTLY_FEATURE=""
+  matrix:
+  - FEATURES=--features=backtrace
+  - FEATURES=--no-default-features
+
+matrix:
+  exclude:
+  - env: FEATURES=--features=backtrace
+    rust: 1.10.0
new file mode 100644
--- /dev/null
+++ b/third_party/rust/error-chain/CHANGELOG.md
@@ -0,0 +1,100 @@
+# Unreleased
+
+# 0.10.0
+
+- [Add a new constructor for `Error`: `with_chain`.](https://github.com/brson/error-chain/pull/126)
+- [Add the `ensure!` macro.](https://github.com/brson/error-chain/pull/135)
+
+# 0.9.0
+
+- Revert [Add a `Sync` bound to errors](https://github.com/brson/error-chain/pull/110)
+
+# 0.8.1
+
+- Add crates.io categorie.
+
+# 0.8.0
+
+- [Add a `Sync` bound to errors](https://github.com/brson/error-chain/pull/110)
+- [Add `ChainedError::display` to format error chains](https://github.com/brson/error-chain/pull/113)
+
+# 0.7.2
+
+- Add `quick_main!` (#88).
+- `allow(unused)` for the `Result` wrapper.
+- Minimum rust version supported is now 1.10 on some conditions (#103).
+
+# 0.7.1
+
+- [Add the `bail!` macro](https://github.com/brson/error-chain/pull/76)
+
+# 0.7.0
+
+- [Rollback several design changes to fix regressions](https://github.com/brson/error-chain/pull/75)
+- New `Variant(Error) #[attrs]` for `links` and `foreign_links`.
+- Hide implementation details from the doc.
+- Always generate `Error::backtrace`.
+
+# 0.6.2
+
+- Allow dead code.
+
+# 0.6.1
+
+- Fix wrong trait constraint in ResultExt implementation (#66).
+
+# 0.6.0
+
+- Conditional compilation for error variants.
+- Backtrace generation is now a feature.
+- More standard trait implementations for extra convenience.
+- Remove ChainErr.
+- Remove need to specify `ErrorKind` in `links {}`.
+- Add ResultExt trait.
+- Error.1 is a struct instead of a tuple.
+- Error is now a struct.
+- The declarations order is more flexible.
+- Way better error reporting when there is a syntax error in the macro call.
+- `Result` generation can be disabled.
+- At most one declaration of each type can be present.
+
+# 0.5.0
+
+- [Only generate backtraces with RUST_BACKTRACE set](https://github.com/brson/error-chain/pull/27)
+- [Fixup matching, disallow repeating "types" section](https://github.com/brson/error-chain/pull/26)
+- [Fix tests on stable/beta](https://github.com/brson/error-chain/pull/28)
+- [Only deploy docs when tagged](https://github.com/brson/error-chain/pull/30)
+
+Contributors: benaryorg, Brian Anderson, Georg Brandl
+
+# 0.4.2
+
+- [Fix the resolution of the ErrorKind description method](https://github.com/brson/error-chain/pull/24)
+
+Contributors: Brian Anderson
+
+# 0.4.1 (yanked)
+
+- [Fix a problem with resolving methods of the standard Error type](https://github.com/brson/error-chain/pull/22)
+
+Contributors: Brian Anderson
+
+# 0.4.0 (yanked)
+
+- [Remove the foreign link description and forward to the foreign error](https://github.com/brson/error-chain/pull/19)
+- [Allow missing sections](https://github.com/brson/error-chain/pull/17)
+
+Contributors: Brian Anderson, Taylor Cramer
+
+# 0.3.0
+
+- [Forward Display implementation for foreign errors](https://github.com/brson/error-chain/pull/13)
+
+Contributors: Brian Anderson, Taylor Cramer
+
+# 0.2.2
+
+- [Don't require `types` section in macro invocation](https://github.com/brson/error-chain/pull/8)
+- [Add "quick start" to README](https://github.com/brson/error-chain/pull/9)
+
+Contributors: Brian Anderson, Jake Shadle, Nate Mara
new file mode 100644
--- /dev/null
+++ b/third_party/rust/error-chain/Cargo.toml
@@ -0,0 +1,26 @@
+[package]
+
+name = "error-chain"
+version = "0.10.0"
+authors = [ "Brian Anderson <banderson@mozilla.com>",
+            "Paul Colomiets <paul@colomiets.name>",
+            "Colin Kiegel <kiegel@gmx.de>",
+            "Yamakaky <yamakaky@yamaworld.fr>"]
+description = "Yet another error boilerplate library."
+categories = ["rust-patterns"]
+
+documentation = "https://docs.rs/error-chain"
+homepage = "https://github.com/brson/error-chain"
+repository = "https://github.com/brson/error-chain"
+
+license = "MIT/Apache-2.0"
+
+[badges]
+travis-ci = { repository = "brson/error-chain" }
+
+[features]
+default = ["backtrace", "example_generated"]
+example_generated = []
+
+[dependencies]
+backtrace = { version = "0.3", optional = true }
new file mode 100644
--- /dev/null
+++ b/third_party/rust/error-chain/README.md
@@ -0,0 +1,36 @@
+# error-chain - Consistent error handling for Rust
+
+[![Build Status](https://api.travis-ci.org/brson/error-chain.svg?branch=master)](https://travis-ci.org/brson/error-chain)
+[![Latest Version](https://img.shields.io/crates/v/error-chain.svg)](https://crates.io/crates/error-chain)
+[![License](https://img.shields.io/github/license/brson/error-chain.svg)](https://github.com/brson/error-chain)
+
+`error-chain` makes it easy to take full advantage of Rust's error
+handling features without the overhead of maintaining boilerplate
+error types and conversions. It implements an opinionated strategy for
+defining your own error types, as well as conversions from others'
+error types.
+
+[Documentation (crates.io)](https://docs.rs/error-chain).
+
+[Documentation (master)](https://brson.github.io/error-chain).
+
+## Quick start
+
+If you just want to set up your new project with error-chain,
+follow the [quickstart.rs] template, and read this [intro]
+to error-chain.
+
+[quickstart.rs]: https://github.com/brson/error-chain/blob/master/examples/quickstart.rs
+[intro]: http://brson.github.io/2016/11/30/starting-with-error-chain
+
+## Supported Rust version
+
+Please view the beginning of the [Travis configuration file](.travis.yml)
+to see the oldest supported Rust version.
+
+Note that `error-chain` supports older versions of Rust when built with
+`default-features = false`.
+
+## License
+
+MIT/Apache-2.0
new file mode 100644
--- /dev/null
+++ b/third_party/rust/error-chain/examples/all.rs
@@ -0,0 +1,36 @@
+#[macro_use]
+extern crate error_chain;
+
+pub mod inner {
+    error_chain! {}
+}
+
+#[cfg(feature = "a_feature")]
+pub mod feature {
+    error_chain! {}
+}
+
+error_chain! {
+    // Types generated by the macro. If empty or absent, it defaults to
+    //     Error, ErrorKind, Result;
+    types {
+        // With custom names:
+        MyError, MyErrorKind, MyResult;
+        // Without the `Result` wrapper:
+        //     Error, ErrorKind;
+    }
+
+    // Automatic bindings to other error types generated by `error_chain!`.
+    links {
+        Inner(inner::Error, inner::ErrorKind);
+        // Attributes can be added at the end of the declaration.
+        Feature(feature::Error, feature::ErrorKind) #[cfg(feature = "a_feature")];
+    }
+
+    // Bindings to types implementing std::error::Error.
+    foreign_links {
+        Io(::std::io::Error);
+    }
+}
+
+fn main() {}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/error-chain/examples/doc.rs
@@ -0,0 +1,29 @@
+#![deny(missing_docs)]
+
+//! This module is used to check that all generated items are documented.
+
+#[macro_use]
+extern crate error_chain;
+
+/// Inner module.
+pub mod inner {
+    error_chain! {
+    }
+}
+
+error_chain! {
+    links {
+        Inner(inner::Error, inner::ErrorKind) #[doc = "Doc"];
+    }
+    foreign_links {
+        Io(::std::io::Error) #[doc = "Io"];
+    }
+    errors {
+        /// Doc
+        Test2 {
+
+        }
+    }
+}
+
+fn main() {}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/error-chain/examples/quickstart.rs
@@ -0,0 +1,77 @@
+// Simple and robust error handling with error-chain!
+// Use this as a template for new projects.
+
+// `error_chain!` can recurse deeply
+#![recursion_limit = "1024"]
+
+// Import the macro. Don't forget to add `error-chain` in your
+// `Cargo.toml`!
+#[macro_use]
+extern crate error_chain;
+
+// We'll put our errors in an `errors` module, and other modules in
+// this crate will `use errors::*;` to get access to everything
+// `error_chain!` creates.
+mod errors {
+    // Create the Error, ErrorKind, ResultExt, and Result types
+    error_chain! { }
+}
+
+use errors::*;
+
+fn main() {
+    if let Err(ref e) = run() {
+        use ::std::io::Write;
+        let stderr = &mut ::std::io::stderr();
+        let errmsg = "Error writing to stderr";
+
+        writeln!(stderr, "error: {}", e).expect(errmsg);
+
+        for e in e.iter().skip(1) {
+            writeln!(stderr, "caused by: {}", e).expect(errmsg);
+        }
+
+        // The backtrace is not always generated. Try to run this example
+        // with `RUST_BACKTRACE=1`.
+        if let Some(backtrace) = e.backtrace() {
+            writeln!(stderr, "backtrace: {:?}", backtrace).expect(errmsg);
+        }
+
+        ::std::process::exit(1);
+    }
+}
+
+// The above main gives you maximum control over how the error is
+// formatted. If you don't care (i.e. you want to display the full
+// error during an assert) you can just call the `display` method
+// on the error object
+#[allow(dead_code)]
+fn alternative_main() {
+    if let Err(ref e) = run() {
+        use std::io::Write;
+        use error_chain::ChainedError; // trait which holds `display`
+        let stderr = &mut ::std::io::stderr();
+        let errmsg = "Error writing to stderr";
+
+        writeln!(stderr, "{}", e.display()).expect(errmsg);
+        ::std::process::exit(1);
+    }
+}
+
+// Use this macro to auto-generate the main above. You may want to
+// set the `RUST_BACKTRACE` env variable to see a backtrace.
+//quick_main!(run);
+
+
+// Most functions will return the `Result` type, imported from the
+// `errors` module. It is a typedef of the standard `Result` type
+// for which the error type is always our own `Error`.
+fn run() -> Result<()> {
+    use std::fs::File;
+
+    // This operation will fail
+    File::open("tretrete")
+        .chain_err(|| "unable to open tretrete file")?;
+
+    Ok(())
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/error-chain/examples/size.rs
@@ -0,0 +1,40 @@
+#[macro_use]
+extern crate error_chain;
+
+use std::mem::{size_of, size_of_val};
+
+error_chain! {
+    errors {
+        AVariant
+        Another
+    }
+}
+
+fn main() {
+    println!("Memory usage in bytes");
+    println!("---------------------");
+    println!("Result<()>: {}", size_of::<Result<()>>());
+    println!("  (): {}", size_of::<()>());
+    println!("  Error: {}", size_of::<Error>());
+    println!("    ErrorKind: {}", size_of::<ErrorKind>());
+    let msg = ErrorKind::Msg("test".into());
+    println!("      ErrorKind::Msg: {}", size_of_val(&msg));
+    println!("        String: {}", size_of::<String>());
+    println!("    State: {}", size_of::<error_chain::State>());
+    #[cfg(feature = "backtrace")]
+    {
+        let state = error_chain::State {
+            next_error: None,
+            backtrace: None,
+        };
+        println!("      State.next_error: {}", size_of_val(&state.next_error));
+        println!("      State.backtrace: {}", size_of_val(&state.backtrace));
+    }
+    #[cfg(not(feature = "backtrace"))]
+    {
+        let state = error_chain::State {
+            next_error: None,
+        };
+        println!("      State.next_error: {}", size_of_val(&state.next_error));
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/error-chain/src/error_chain.rs
@@ -0,0 +1,426 @@
+/// Prefer to use `error_chain` instead of this macro.
+#[macro_export]
+macro_rules! error_chain_processed {
+    // Default values for `types`.
+    (
+        types {}
+        $( $rest: tt )*
+    ) => {
+        error_chain_processed! {
+            types {
+                Error, ErrorKind, ResultExt, Result;
+            }
+            $( $rest )*
+        }
+    };
+    // With `Result` wrapper.
+    (
+        types {
+            $error_name:ident, $error_kind_name:ident,
+            $result_ext_name:ident, $result_name:ident;
+        }
+        $( $rest: tt )*
+    ) => {
+        error_chain_processed! {
+            types {
+                $error_name, $error_kind_name,
+                $result_ext_name;
+            }
+            $( $rest )*
+        }
+        /// Convenient wrapper around `std::Result`.
+        #[allow(unused)]
+        pub type $result_name<T> = ::std::result::Result<T, $error_name>;
+    };
+    // Without `Result` wrapper.
+    (
+        types {
+            $error_name:ident, $error_kind_name:ident,
+            $result_ext_name:ident;
+        }
+
+        links {
+            $( $link_variant:ident ( $link_error_path:path, $link_kind_path:path )
+               $( #[$meta_links:meta] )*; ) *
+        }
+
+        foreign_links {
+            $( $foreign_link_variant:ident ( $foreign_link_error_path:path )
+               $( #[$meta_foreign_links:meta] )*; )*
+        }
+
+        errors {
+            $( $error_chunks:tt ) *
+        }
+
+    ) => {
+        /// The Error type.
+        ///
+        /// This tuple struct is made of two elements:
+        ///
+        /// - an `ErrorKind` which is used to determine the type of the error.
+        /// - An internal `State`, not meant for direct use outside of `error_chain`
+        ///   internals, containing:
+        ///   - a backtrace, generated when the error is created.
+        ///   - an error chain, used for the implementation of `Error::cause()`.
+        #[derive(Debug)]
+        pub struct $error_name(
+            // The members must be `pub` for `links`.
+            /// The kind of the error.
+            pub $error_kind_name,
+            /// Contains the error chain and the backtrace.
+            #[doc(hidden)]
+            pub $crate::State,
+        );
+
+        impl $crate::ChainedError for $error_name {
+            type ErrorKind = $error_kind_name;
+
+            fn new(kind: $error_kind_name, state: $crate::State) -> $error_name {
+                $error_name(kind, state)
+            }
+
+            fn from_kind(kind: Self::ErrorKind) -> Self {
+                Self::from_kind(kind)
+            }
+
+            fn with_chain<E, K>(error: E, kind: K)
+                -> Self
+                where E: ::std::error::Error + Send + 'static,
+                      K: Into<Self::ErrorKind>
+            {
+                Self::with_chain(error, kind)
+            }
+
+            fn kind(&self) -> &Self::ErrorKind {
+                self.kind()
+            }
+
+            fn iter(&self) -> $crate::ErrorChainIter {
+                $crate::ErrorChainIter(Some(self))
+            }
+
+            fn backtrace(&self) -> Option<&$crate::Backtrace> {
+                self.backtrace()
+            }
+
+            impl_extract_backtrace!($error_name
+                                    $error_kind_name
+                                    $([$link_error_path, $(#[$meta_links])*])*);
+        }
+
+        #[allow(dead_code)]
+        impl $error_name {
+            /// Constructs an error from a kind, and generates a backtrace.
+            pub fn from_kind(kind: $error_kind_name) -> $error_name {
+                $error_name(
+                    kind,
+                    $crate::State::default(),
+                )
+            }
+
+            /// Constructs a chained error from another error and a kind, and generates a backtrace.
+            pub fn with_chain<E, K>(error: E, kind: K)
+                -> $error_name
+                where E: ::std::error::Error + Send + 'static,
+                      K: Into<$error_kind_name>
+            {
+                $error_name(
+                    kind.into(),
+                    $crate::State::new::<$error_name>(Box::new(error), ),
+                )
+            }
+
+            /// Returns the kind of the error.
+            pub fn kind(&self) -> &$error_kind_name {
+                &self.0
+            }
+
+            /// Iterates over the error chain.
+            pub fn iter(&self) -> $crate::ErrorChainIter {
+                $crate::ChainedError::iter(self)
+            }
+
+            /// Returns the backtrace associated with this error.
+            pub fn backtrace(&self) -> Option<&$crate::Backtrace> {
+                self.1.backtrace()
+            }
+        }
+
+        impl ::std::error::Error for $error_name {
+            fn description(&self) -> &str {
+                self.0.description()
+            }
+
+            fn cause(&self) -> Option<&::std::error::Error> {
+                match self.1.next_error {
+                    Some(ref c) => Some(&**c),
+                    None => {
+                        match self.0 {
+                            $(
+                                $(#[$meta_foreign_links])*
+                                $error_kind_name::$foreign_link_variant(ref foreign_err) => {
+                                    foreign_err.cause()
+                                }
+                            ) *
+                            _ => None
+                        }
+                    }
+                }
+            }
+        }
+
+        impl ::std::fmt::Display for $error_name {
+            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+                ::std::fmt::Display::fmt(&self.0, f)
+            }
+        }
+
+        $(
+            $(#[$meta_links])*
+            impl From<$link_error_path> for $error_name {
+                fn from(e: $link_error_path) -> Self {
+                    $error_name(
+                        $error_kind_name::$link_variant(e.0),
+                        e.1,
+                    )
+                }
+            }
+        ) *
+
+        $(
+            $(#[$meta_foreign_links])*
+            impl From<$foreign_link_error_path> for $error_name {
+                fn from(e: $foreign_link_error_path) -> Self {
+                    $error_name::from_kind(
+                        $error_kind_name::$foreign_link_variant(e)
+                    )
+                }
+            }
+        ) *
+
+        impl From<$error_kind_name> for $error_name {
+            fn from(e: $error_kind_name) -> Self {
+                $error_name::from_kind(e)
+            }
+        }
+
+        impl<'a> From<&'a str> for $error_name {
+            fn from(s: &'a str) -> Self {
+                $error_name::from_kind(s.into())
+            }
+        }
+
+        impl From<String> for $error_name {
+            fn from(s: String) -> Self {
+                $error_name::from_kind(s.into())
+            }
+        }
+
+        impl ::std::ops::Deref for $error_name {
+            type Target = $error_kind_name;
+
+            fn deref(&self) -> &Self::Target {
+                &self.0
+            }
+        }
+
+
+        // The ErrorKind type
+        // --------------
+
+        quick_error! {
+            /// The kind of an error.
+            #[derive(Debug)]
+            pub enum $error_kind_name {
+
+                /// A convenient variant for String.
+                Msg(s: String) {
+                    description(&s)
+                    display("{}", s)
+                }
+
+                $(
+                    $(#[$meta_links])*
+                    $link_variant(e: $link_kind_path) {
+                        description(e.description())
+                        display("{}", e)
+                    }
+                ) *
+
+                $(
+                    $(#[$meta_foreign_links])*
+                    $foreign_link_variant(err: $foreign_link_error_path) {
+                        description(::std::error::Error::description(err))
+                        display("{}", err)
+                    }
+                ) *
+
+                $($error_chunks)*
+            }
+        }
+
+        $(
+            $(#[$meta_links])*
+            impl From<$link_kind_path> for $error_kind_name {
+                fn from(e: $link_kind_path) -> Self {
+                    $error_kind_name::$link_variant(e)
+                }
+            }
+        ) *
+
+        impl<'a> From<&'a str> for $error_kind_name {
+            fn from(s: &'a str) -> Self {
+                $error_kind_name::Msg(s.to_string())
+            }
+        }
+
+        impl From<String> for $error_kind_name {
+            fn from(s: String) -> Self {
+                $error_kind_name::Msg(s)
+            }
+        }
+
+        impl From<$error_name> for $error_kind_name {
+            fn from(e: $error_name) -> Self {
+                e.0
+            }
+        }
+
+        // The ResultExt trait defines the `chain_err` method.
+
+        /// Additional methods for `Result`, for easy interaction with this crate.
+        pub trait $result_ext_name<T, E> {
+            /// If the `Result` is an `Err` then `chain_err` evaluates the closure,
+            /// which returns *some type that can be converted to `ErrorKind`*, boxes
+            /// the original error to store as the cause, then returns a new error
+            /// containing the original error.
+            fn chain_err<F, EK>(self, callback: F) -> ::std::result::Result<T, $error_name>
+                where F: FnOnce() -> EK,
+                      EK: Into<$error_kind_name>;
+        }
+
+        impl<T, E> $result_ext_name<T, E> for ::std::result::Result<T, E> where E: ::std::error::Error + Send + 'static {
+            fn chain_err<F, EK>(self, callback: F) -> ::std::result::Result<T, $error_name>
+                where F: FnOnce() -> EK,
+                      EK: Into<$error_kind_name> {
+                self.map_err(move |e| {
+                    let state = $crate::State::new::<$error_name>(Box::new(e), );
+                    $crate::ChainedError::new(callback().into(), state)
+                })
+            }
+        }
+
+
+    };
+}
+
+/// Internal macro used for reordering of the fields.
+#[doc(hidden)]
+#[macro_export]
+macro_rules! error_chain_processing {
+    (
+        ({}, $b:tt, $c:tt, $d:tt)
+        types $content:tt
+        $( $tail:tt )*
+    ) => {
+        error_chain_processing! {
+            ($content, $b, $c, $d)
+            $($tail)*
+        }
+    };
+    (
+        ($a:tt, {}, $c:tt, $d:tt)
+        links $content:tt
+        $( $tail:tt )*
+    ) => {
+        error_chain_processing! {
+            ($a, $content, $c, $d)
+            $($tail)*
+        }
+    };
+    (
+        ($a:tt, $b:tt, {}, $d:tt)
+        foreign_links $content:tt
+        $( $tail:tt )*
+    ) => {
+        error_chain_processing! {
+            ($a, $b, $content, $d)
+            $($tail)*
+        }
+    };
+    (
+        ($a:tt, $b:tt, $c:tt, {})
+        errors $content:tt
+        $( $tail:tt )*
+    ) => {
+        error_chain_processing! {
+            ($a, $b, $c, $content)
+            $($tail)*
+        }
+    };
+    ( ($a:tt, $b:tt, $c:tt, $d:tt) ) => {
+        error_chain_processed! {
+            types $a
+            links $b
+            foreign_links $c
+            errors $d
+        }
+    };
+}
+
+/// This macro is used for handling of duplicated and out-of-order fields. For
+/// the exact rules, see `error_chain_processed`.
+#[macro_export]
+macro_rules! error_chain {
+    ( $( $block_name:ident { $( $block_content:tt )* } )* ) => {
+        error_chain_processing! {
+            ({}, {}, {}, {})
+            $($block_name { $( $block_content )* })*
+        }
+    };
+}
+
+/// Macro used to manage the `backtrace` feature.
+///
+/// See
+/// https://www.reddit.com/r/rust/comments/57virt/hey_rustaceans_got_an_easy_question_ask_here/da5r4ti/?context=3
+/// for more details.
+#[macro_export]
+#[doc(hidden)]
+#[cfg(feature = "backtrace")]
+macro_rules! impl_extract_backtrace {
+    ($error_name: ident
+     $error_kind_name: ident
+     $([$link_error_path: path, $(#[$meta_links: meta])*])*) => {
+        fn extract_backtrace(e: &(::std::error::Error + Send + 'static))
+            -> Option<::std::sync::Arc<$crate::Backtrace>> {
+            if let Some(e) = e.downcast_ref::<$error_name>() {
+                return e.1.backtrace.clone();
+            }
+            $(
+                $( #[$meta_links] )*
+                {
+                    if let Some(e) = e.downcast_ref::<$link_error_path>() {
+                        return e.1.backtrace.clone();
+                    }
+                }
+            ) *
+            None
+        }
+    }
+}
+
+/// Macro used to manage the `backtrace` feature.
+///
+/// See
+/// https://www.reddit.com/r/rust/comments/57virt/hey_rustaceans_got_an_easy_question_ask_here/da5r4ti/?context=3
+/// for more details.
+#[macro_export]
+#[doc(hidden)]
+#[cfg(not(feature = "backtrace"))]
+macro_rules! impl_extract_backtrace {
+    ($error_name: ident
+     $error_kind_name: ident
+     $([$link_error_path: path, $(#[$meta_links: meta])*])*) => {}
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/error-chain/src/example_generated.rs
@@ -0,0 +1,38 @@
+//! These modules show an example of code generated by the macro. **IT MUST NOT BE
+//! USED OUTSIDE THIS CRATE**.
+//!
+//! This is the basic error structure. You can see that `ErrorKind`
+//! has been populated in a variety of ways. All `ErrorKind`s get a
+//! `Msg` variant for basic errors. When strings are converted to
+//! `ErrorKind`s they become `ErrorKind::Msg`. The "links" defined in
+//! the macro are expanded to the `Inner` variant, and the
+//! "foreign links" to the `Io` variant.
+//!
+//! Both types come with a variety of `From` conversions as well:
+//! `Error` can be created from `ErrorKind`, `&str` and `String`,
+//! and the `links` and `foreign_links` error types. `ErrorKind`
+//! can be created from the corresponding `ErrorKind`s of the link
+//! types, as well as from `&str` and `String`.
+//!
+//! `into()` and `From::from` are used heavily to massage types into
+//! the right shape. Which one to use in any specific case depends on
+//! the influence of type inference, but there are some patterns that
+//! arise frequently.
+
+/// Another code generated by the macro.
+pub mod inner {
+    error_chain! {}
+}
+
+error_chain! {
+    links {
+        Inner(inner::Error, inner::ErrorKind) #[doc = "Link to another `ErrorChain`."];
+    }
+    foreign_links {
+        Io(::std::io::Error) #[doc = "Link to a `std::error::Error` type."];
+    }
+    errors {
+        #[doc = "A custom error kind."]
+        Custom
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/error-chain/src/lib.rs
@@ -0,0 +1,659 @@
+#![deny(missing_docs)]
+
+//! A library for consistent and reliable error handling
+//!
+//! error-chain makes it easy to take full advantage of Rust's
+//! powerful error handling features without the overhead of
+//! maintaining boilerplate error types and conversions. It implements
+//! an opinionated strategy for defining your own error types, as well
+//! as conversions from others' error types.
+//!
+//! ## Quick start
+//!
+//! If you just want to set up your new project with error-chain,
+//! follow the [quickstart.rs] template, and read this [intro]
+//! to error-chain.
+//!
+//! [quickstart.rs]: https://github.com/brson/error-chain/blob/master/examples/quickstart.rs
+//! [intro]: http://brson.github.io/2016/11/30/starting-with-error-chain
+//!
+//! ## Why error chain?
+//!
+//! * error-chain is easy to configure. Handle errors robustly with minimal
+//!   effort.
+//! * Basic error handling requires no maintenance of custom error types
+//!   nor the `From` conversions that make `?` work.
+//! * error-chain scales from simple error handling strategies to more
+//!   rigorous.  Return formatted strings for simple errors, only
+//!   introducing error variants and their strong typing as needed for
+//!   advanced error recovery.
+//! * error-chain makes it trivial to correctly manage the [cause] of
+//!   the errors generated by your own code. This is the "chaining"
+//!   in "error-chain".
+//!
+//! [cause]: https://doc.rust-lang.org/std/error/trait.Error.html#method.cause
+//!
+//! ## Principles of error-chain
+//!
+//! error-chain is based on the following principles:
+//!
+//! * No error should ever be discarded. This library primarily
+//!   makes it easy to "chain" errors with the `chain_err` method.
+//! * Introducing new errors is trivial. Simple errors can be introduced
+//!   at the error site with just a string.
+//! * Handling errors is possible with pattern matching.
+//! * Conversions between error types are done in an automatic and
+//!   consistent way - `From` conversion behavior is never specified
+//!   explicitly.
+//! * Errors implement Send.
+//! * Errors can carry backtraces.
+//!
+//! Similar to other libraries like [error-type] and [quick-error],
+//! this library introduces the error chaining mechanism originally
+//! employed by Cargo.  The `error_chain!` macro declares the types
+//! and implementation boilerplate necessary for fulfilling a
+//! particular error-handling strategy. Most importantly it defines a
+//! custom error type (called `Error` by convention) and the `From`
+//! conversions that let the `try!` macro and `?` operator work.
+//!
+//! This library differs in a few ways from previous error libs:
+//!
+//! * Instead of defining the custom `Error` type as an enum, it is a
+//!   struct containing an `ErrorKind` (which defines the
+//!   `description` and `display` methods for the error), an opaque,
+//!   optional, boxed `std::error::Error + Send + 'static` object
+//!   (which defines the `cause`, and establishes the links in the
+//!   error chain), and a `Backtrace`.
+//! * The macro also defines a `ResultExt` trait that defines a
+//!   `chain_err` method. This method on all `std::error::Error + Send + 'static`
+//!   types extends the error chain by boxing the current
+//!   error into an opaque object and putting it inside a new concrete
+//!   error.
+//! * It provides automatic `From` conversions between other error types
+//!   defined by the `error_chain!` that preserve type information,
+//!   and facilitate seamless error composition and matching of composed
+//!   errors.
+//! * It provides automatic `From` conversions between any other error
+//!   type that hides the type of the other error in the `cause` box.
+//! * If `RUST_BACKTRACE` is enabled, it collects a single backtrace at
+//!   the earliest opportunity and propagates it down the stack through
+//!   `From` and `ResultExt` conversions.
+//!
+//! To accomplish its goals it makes some tradeoffs:
+//!
+//! * The split between the `Error` and `ErrorKind` types can make it
+//!   slightly more cumbersome to instantiate new (unchained) errors,
+//!   requiring an `Into` or `From` conversion; as well as slightly
+//!   more cumbersome to match on errors with another layer of types
+//!   to match.
+//! * Because the error type contains `std::error::Error + Send + 'static` objects,
+//!   it can't implement `PartialEq` for easy comparisons.
+//!
+//! ## Declaring error types
+//!
+//! Generally, you define one family of error types per crate, though
+//! it's also perfectly fine to define error types on a finer-grained
+//! basis, such as per module.
+//!
+//! Assuming you are using crate-level error types, typically you will
+//! define an `errors` module and inside it call `error_chain!`:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! mod other_error {
+//!     error_chain! {}
+//! }
+//!
+//! error_chain! {
+//!     // The type defined for this error. These are the conventional
+//!     // and recommended names, but they can be arbitrarily chosen.
+//!     //
+//!     // It is also possible to leave this section out entirely, or
+//!     // leave it empty, and these names will be used automatically.
+//!     types {
+//!         Error, ErrorKind, ResultExt, Result;
+//!     }
+//!
+//!     // Without the `Result` wrapper:
+//!     //
+//!     // types {
+//!     //     Error, ErrorKind, ResultExt;
+//!     // }
+//!
+//!     // Automatic conversions between this error chain and other
+//!     // error chains. In this case, it will e.g. generate an
+//!     // `ErrorKind` variant called `Another` which in turn contains
+//!     // the `other_error::ErrorKind`, with conversions from
+//!     // `other_error::Error`.
+//!     //
+//!     // Optionally, some attributes can be added to a variant.
+//!     //
+//!     // This section can be empty.
+//!     links {
+//!         Another(other_error::Error, other_error::ErrorKind) #[cfg(unix)];
+//!     }
+//!
+//!     // Automatic conversions between this error chain and other
+//!     // error types not defined by the `error_chain!`. These will be
+//!     // wrapped in a new error with, in the first case, the
+//!     // `ErrorKind::Fmt` variant. The description and cause will
+//!     // forward to the description and cause of the original error.
+//!     //
+//!     // Optionally, some attributes can be added to a variant.
+//!     //
+//!     // This section can be empty.
+//!     foreign_links {
+//!         Fmt(::std::fmt::Error);
+//!         Io(::std::io::Error) #[cfg(unix)];
+//!     }
+//!
+//!     // Define additional `ErrorKind` variants. The syntax here is
+//!     // the same as `quick_error!`, but the `from()` and `cause()`
+//!     // syntax is not supported.
+//!     errors {
+//!         InvalidToolchainName(t: String) {
+//!             description("invalid toolchain name")
+//!             display("invalid toolchain name: '{}'", t)
+//!         }
+//!     }
+//! }
+//!
+//! # fn main() {}
+//! ```
+//!
+//! Each section, `types`, `links`, `foreign_links`, and `errors` may
+//! be omitted if it is empty.
+//!
+//! This populates the module with a number of definitions,
+//! the most important of which are the `Error` type
+//! and the `ErrorKind` type. An example of generated code can be found in the
+//! [example_generated](example_generated) module.
+//!
+//! ## Returning new errors
+//!
+//! Introducing new error chains, with a string message:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # error_chain! {}
+//! fn foo() -> Result<()> {
+//!     Err("foo error!".into())
+//! }
+//! ```
+//!
+//! Introducing new error chains, with an `ErrorKind`:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! error_chain! {
+//!     errors { FooError }
+//! }
+//!
+//! fn foo() -> Result<()> {
+//!     Err(ErrorKind::FooError.into())
+//! }
+//! ```
+//!
+//! Note that the return type is the typedef `Result`, which is
+//! defined by the macro as `pub type Result<T> =
+//! ::std::result::Result<T, Error>`. Note that in both cases
+//! `.into()` is called to convert a type into the `Error` type; both
+//! strings and `ErrorKind` have `From` conversions to turn them into
+//! `Error`.
+//!
+//! When the error is emitted inside a `try!` macro or behind the
+//! `?` operator, the explicit conversion isn't needed; `try!` will
+//! automatically convert `Err(ErrorKind)` to `Err(Error)`. So the
+//! below is equivalent to the previous:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # error_chain! { errors { FooError } }
+//! fn foo() -> Result<()> {
+//!     Ok(try!(Err(ErrorKind::FooError)))
+//! }
+//!
+//! fn bar() -> Result<()> {
+//!     Ok(try!(Err("bogus!")))
+//! }
+//! ```
+//!
+//! ## The `bail!` macro
+//!
+//! The above method of introducing new errors works but is a little
+//! verbose. Instead we can use the `bail!` macro, which, much like `try!`
+//! and `?`, performs an early return with conversions. With `bail!` the
+//! previous examples look like:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # error_chain! { errors { FooError } }
+//! fn foo() -> Result<()> {
+//!     if true {
+//!         bail!(ErrorKind::FooError);
+//!     } else {
+//!         Ok(())
+//!     }
+//! }
+//!
+//! fn bar() -> Result<()> {
+//!     if true {
+//!         bail!("bogus!");
+//!     } else {
+//!         Ok(())
+//!     }
+//! }
+//! ```
+//!
+//! ## Chaining errors
+//!
+//! To extend the error chain:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # error_chain! {}
+//! # fn do_something() -> Result<()> { unimplemented!() }
+//! # fn test() -> Result<()> {
+//! let res: Result<()> = do_something().chain_err(|| "something went wrong");
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! `chain_err` can be called on any `Result` type where the contained
+//! error type implements `std::error::Error + Send + 'static`.  If
+//! the `Result` is an `Err` then `chain_err` evaluates the closure,
+//! which returns *some type that can be converted to `ErrorKind`*,
+//! boxes the original error to store as the cause, then returns a new
+//! error containing the original error.
+//!
+//! ## Matching errors
+//!
+//! error-chain error variants are matched with simple patterns.
+//! `Error` is a tuple struct and its first field is the `ErrorKind`,
+//! making dispatching on error kinds relatively compact:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {
+//! error_chain! {
+//!     errors {
+//!         InvalidToolchainName(t: String) {
+//!             description("invalid toolchain name")
+//!             display("invalid toolchain name: '{}'", t)
+//!         }
+//!     }
+//! }
+//!
+//! match Error::from("error!") {
+//!     Error(ErrorKind::InvalidToolchainName(_), _) => { }
+//!     Error(ErrorKind::Msg(_), _) => { }
+//! }
+//! # }
+//! ```
+//!
+//! Chained errors are also matched with (relatively) compact syntax
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! mod utils {
+//!     error_chain! {
+//!         errors {
+//!             BadStuff {
+//!                 description("bad stuff")
+//!             }
+//!         }
+//!     }
+//! }
+//!
+//! mod app {
+//!     error_chain! {
+//!         links {
+//!             Utils(::utils::Error, ::utils::ErrorKind);
+//!         }
+//!     }
+//! }
+//!
+//!
+//! # fn main() {
+//! match app::Error::from("error!") {
+//!     app::Error(app::ErrorKind::Utils(utils::ErrorKind::BadStuff), _) => { }
+//!     _ => { }
+//! }
+//! # }
+//! ```
+//!
+//! ## Foreign links
+//!
+//! Errors that do not conform to the same conventions as this library
+//! can still be included in the error chain. They are considered "foreign
+//! errors", and are declared using the `foreign_links` block of the
+//! `error_chain!` macro. `Error`s are automatically created from
+//! foreign errors by the `try!` macro.
+//!
+//! Foreign links and regular links have one crucial difference:
+//! `From` conversions for regular links *do not introduce a new error
+//! into the error chain*, while conversions for foreign links *always
+//! introduce a new error into the error chain*. So for the example
+//! above all errors deriving from the `temp::Error` type will be
+//! presented to the user as a new `ErrorKind::Temp` variant, and the
+//! cause will be the original `temp::Error` error. In contrast, when
+//! `rustup_utils::Error` is converted to `Error` the two `ErrorKind`s
+//! are converted between each other to create a new `Error` but the
+//! old error is discarded; there is no "cause" created from the
+//! original error.
+//!
+//! ## Backtraces
+//!
+//! If the `RUST_BACKTRACE` environment variable is set to anything
+//! but ``0``, the earliest non-foreign error to be generated creates
+//! a single backtrace, which is passed through all `From` conversions
+//! and `chain_err` invocations of compatible types. To read the
+//! backtrace just call the `backtrace()` method.
+//!
+//! Backtrace generation can be disabled by turning off the `backtrace` feature.
+//!
+//! ## Iteration
+//!
+//! The `iter` method returns an iterator over the chain of error boxes.
+//!
+//! [error-type]: https://github.com/DanielKeep/rust-error-type
+//! [quick-error]: https://github.com/tailhook/quick-error
+
+
+#[cfg(feature = "backtrace")]
+extern crate backtrace;
+
+use std::error;
+use std::iter::Iterator;
+#[cfg(feature = "backtrace")]
+use std::sync::Arc;
+use std::fmt;
+
+#[cfg(feature = "backtrace")]
+pub use backtrace::Backtrace;
+#[cfg(not(feature = "backtrace"))]
+/// Dummy type used when the `backtrace` feature is disabled.
+pub type Backtrace = ();
+
+#[macro_use]
+mod quick_error;
+#[macro_use]
+mod error_chain;
+#[macro_use]
+mod quick_main;
+pub use quick_main::ExitCode;
+#[cfg(feature = "example_generated")]
+pub mod example_generated;
+
+/// Iterator over the error chain using the `Error::cause()` method.
+pub struct ErrorChainIter<'a>(pub Option<&'a error::Error>);
+
+impl<'a> Iterator for ErrorChainIter<'a> {
+    type Item = &'a error::Error;
+
+    fn next<'b>(&'b mut self) -> Option<&'a error::Error> {
+        match self.0.take() {
+            Some(e) => {
+                self.0 = e.cause();
+                Some(e)
+            }
+            None => None,
+        }
+    }
+}
+
+/// Returns a backtrace of the current call stack if `RUST_BACKTRACE`
+/// is set to anything but ``0``, and `None` otherwise.  This is used
+/// in the generated error implementations.
+#[cfg(feature = "backtrace")]
+#[doc(hidden)]
+pub fn make_backtrace() -> Option<Arc<Backtrace>> {
+    match std::env::var_os("RUST_BACKTRACE") {
+        Some(ref val) if val != "0" => Some(Arc::new(Backtrace::new())),
+        _ => None,
+    }
+}
+
+/// This trait is implemented on all the errors generated by the `error_chain`
+/// macro.
+pub trait ChainedError: error::Error + Send + 'static {
+    /// Associated kind type.
+    type ErrorKind;
+
+    /// Constructs an error from a kind, and generates a backtrace.
+    fn from_kind(kind: Self::ErrorKind) -> Self where Self: Sized;
+
+    /// Constructs a chained error from another error and a kind, and generates a backtrace.
+    fn with_chain<E, K>(error: E, kind: K) -> Self
+        where Self: Sized,
+              E: ::std::error::Error + Send + 'static,
+              K: Into<Self::ErrorKind>;
+
+    /// Returns the kind of the error.
+    fn kind(&self) -> &Self::ErrorKind;
+
+    /// Iterates over the error chain.
+    fn iter(&self) -> ErrorChainIter;
+
+    /// Returns the backtrace associated with this error.
+    fn backtrace(&self) -> Option<&Backtrace>;
+
+    /// Returns an object which implements `Display` for printing the full
+    /// context of this error.
+    ///
+    /// The full cause chain and backtrace, if present, will be printed.
+    fn display<'a>(&'a self) -> Display<'a, Self> {
+        Display(self)
+    }
+
+    /// Creates an error from its parts.
+    #[doc(hidden)]
+    fn new(kind: Self::ErrorKind, state: State) -> Self where Self: Sized;
+
+    /// Returns the first known backtrace, either from its State or from one
+    /// of the errors from `foreign_links`.
+    #[cfg(feature = "backtrace")]
+    #[doc(hidden)]
+    fn extract_backtrace(e: &(error::Error + Send + 'static)) -> Option<Arc<Backtrace>>
+        where Self: Sized;
+}
+
+/// A struct which formats an error for output.
+#[derive(Debug)]
+pub struct Display<'a, T: 'a + ?Sized>(&'a T);
+
+impl<'a, T> fmt::Display for Display<'a, T>
+    where T: ChainedError
+{
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        try!(writeln!(fmt, "Error: {}", self.0));
+
+        for e in self.0.iter().skip(1) {
+            try!(writeln!(fmt, "Caused by: {}", e));
+        }
+
+        if let Some(backtrace) = self.0.backtrace() {
+            try!(writeln!(fmt, "{:?}", backtrace));
+        }
+
+        Ok(())
+    }
+}
+
+/// Common state between errors.
+#[derive(Debug)]
+#[doc(hidden)]
+pub struct State {
+    /// Next error in the error chain.
+    pub next_error: Option<Box<error::Error + Send>>,
+    /// Backtrace for the current error.
+    #[cfg(feature = "backtrace")]
+    pub backtrace: Option<Arc<Backtrace>>,
+}
+
+impl Default for State {
+    #[cfg(feature = "backtrace")]
+    fn default() -> State {
+        State {
+            next_error: None,
+            backtrace: make_backtrace(),
+        }
+    }
+
+    #[cfg(not(feature = "backtrace"))]
+    fn default() -> State {
+        State { next_error: None }
+    }
+}
+
+impl State {
+    /// Creates a new State type
+    #[cfg(feature = "backtrace")]
+    pub fn new<CE: ChainedError>(e: Box<error::Error + Send>) -> State {
+        let backtrace = CE::extract_backtrace(&*e).or_else(make_backtrace);
+        State {
+            next_error: Some(e),
+            backtrace: backtrace,
+        }
+    }
+
+    /// Creates a new State type
+    #[cfg(not(feature = "backtrace"))]
+    pub fn new<CE: ChainedError>(e: Box<error::Error + Send>) -> State {
+        State { next_error: Some(e) }
+    }
+
+    /// Returns the inner backtrace if present.
+    #[cfg(feature = "backtrace")]
+    pub fn backtrace(&self) -> Option<&Backtrace> {
+        self.backtrace.as_ref().map(|v| &**v)
+    }
+
+    /// Returns the inner backtrace if present.
+    #[cfg(not(feature = "backtrace"))]
+    pub fn backtrace(&self) -> Option<&Backtrace> {
+        None
+    }
+}
+
+/// Exits a function early with an error
+///
+/// The `bail!` macro provides an easy way to exit a function.
+/// `bail!(expr)` is equivalent to writing.
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! { }
+/// # fn main() { }
+/// # fn foo() -> Result<()> {
+/// # let expr = "";
+///     return Err(expr.into());
+/// # }
+/// ```
+///
+/// And as shorthand it takes a formatting string a la `println!`:
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! { }
+/// # fn main() { }
+/// # fn foo() -> Result<()> {
+/// # let n = 0;
+/// bail!("bad number: {}", n);
+/// # }
+/// ```
+///
+/// # Examples
+///
+/// Bailing on a custom error:
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # fn main() {}
+/// error_chain! {
+///     errors { FooError }
+/// }
+///
+/// fn foo() -> Result<()> {
+///     if bad_condition() {
+///         bail!(ErrorKind::FooError);
+///     }
+///
+///     Ok(())
+/// }
+///
+/// # fn bad_condition() -> bool { true }
+/// ```
+///
+/// Bailing on a formatted string:
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # fn main() {}
+/// error_chain! { }
+///
+/// fn foo() -> Result<()> {
+///     if let Some(bad_num) = bad_condition() {
+///         bail!("so bad: {}", bad_num);
+///     }
+///
+///     Ok(())
+/// }
+///
+/// # fn bad_condition() -> Option<i8> { None }
+/// ```
+#[macro_export]
+macro_rules! bail {
+    ($e:expr) => {
+        return Err($e.into());
+    };
+    ($fmt:expr, $($arg:tt)+) => {
+        return Err(format!($fmt, $($arg)+).into());
+    };
+}
+
+/// Exits a function early with an error if the condition is not satisfied
+///
+/// The `ensure!` macro is a convenience helper that provides a way to exit
+/// a function with an error if the given condition fails.
+///
+/// As an example, `ensure!(condition, "error code: {}", errcode)` is equivalent to
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! { }
+/// # fn main() { }
+/// # fn foo() -> Result<()> {
+/// # let errcode = 0u8;
+/// # let condition = true;
+/// if !condition {
+///     bail!("error code: {}", errcode);
+/// }
+/// # Ok(())
+/// # }
+/// ```
+///
+/// See documentation for `bail!` macro for further details.
+#[macro_export]
+macro_rules! ensure {
+    ($cond:expr, $e:expr) => {
+        if !($cond) {
+            bail!($e);
+        }
+    };
+    ($cond:expr, $fmt:expr, $($arg:tt)+) => {
+        if !($cond) {
+            bail!($fmt, $($arg)+);
+        }
+    };
+}
+
+#[doc(hidden)]
+pub mod mock {
+    error_chain!{}
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/error-chain/src/quick_error.rs
@@ -0,0 +1,529 @@
+// From https://github.com/tailhook/quick-error
+// Changes:
+//   - replace `impl Error` by `impl Item::description`
+//   - $imeta
+
+#[macro_export]
+macro_rules! quick_error {
+    (   $(#[$meta:meta])*
+        pub enum $name:ident { $($chunks:tt)* }
+    ) => {
+        quick_error!(SORT [pub enum $name $(#[$meta])* ]
+            items [] buf []
+            queue [ $($chunks)* ]);
+    };
+    (   $(#[$meta:meta])*
+        enum $name:ident { $($chunks:tt)* }
+    ) => {
+        quick_error!(SORT [enum $name $(#[$meta])* ]
+            items [] buf []
+            queue [ $($chunks)* ]);
+    };
+    // Queue is empty, can do the work
+    (SORT [enum $name:ident $( #[$meta:meta] )*]
+        items [$($( #[$imeta:meta] )*
+                  => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+                                {$( $ifuncs:tt )*} )* ]
+        buf [ ]
+        queue [ ]
+    ) => {
+        quick_error!(ENUM_DEFINITION [enum $name $( #[$meta] )*]
+            body []
+            queue [$($( #[$imeta] )*
+                      => $iitem: $imode [$( $ivar: $ityp ),*] )*]
+        );
+        quick_error!(IMPLEMENTATIONS $name {$(
+           $iitem: $imode [$(#[$imeta])*] [$( $ivar: $ityp ),*] {$( $ifuncs )*}
+           )*});
+        $(
+            quick_error!(ERROR_CHECK $imode $($ifuncs)*);
+        )*
+    };
+    (SORT [pub enum $name:ident $( #[$meta:meta] )*]
+        items [$($( #[$imeta:meta] )*
+                  => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+                                {$( $ifuncs:tt )*} )* ]
+        buf [ ]
+        queue [ ]
+    ) => {
+        quick_error!(ENUM_DEFINITION [pub enum $name $( #[$meta] )*]
+            body []
+            queue [$($( #[$imeta] )*
+                      => $iitem: $imode [$( $ivar: $ityp ),*] )*]
+        );
+        quick_error!(IMPLEMENTATIONS $name {$(
+           $iitem: $imode [$(#[$imeta])*] [$( $ivar: $ityp ),*] {$( $ifuncs )*}
+           )*});
+        $(
+            quick_error!(ERROR_CHECK $imode $($ifuncs)*);
+        )*
+    };
+    // Add meta to buffer
+    (SORT [$( $def:tt )*]
+        items [$($( #[$imeta:meta] )*
+                  => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+                                {$( $ifuncs:tt )*} )* ]
+        buf [$( #[$bmeta:meta] )*]
+        queue [ #[$qmeta:meta] $( $tail:tt )*]
+    ) => {
+        quick_error!(SORT [$( $def )*]
+            items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
+            buf [$( #[$bmeta] )* #[$qmeta] ]
+            queue [$( $tail )*]);
+    };
+    // Add ident to buffer
+    (SORT [$( $def:tt )*]
+        items [$($( #[$imeta:meta] )*
+                  => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+                                {$( $ifuncs:tt )*} )* ]
+        buf [$( #[$bmeta:meta] )*]
+        queue [ $qitem:ident $( $tail:tt )*]
+    ) => {
+        quick_error!(SORT [$( $def )*]
+            items [$( $(#[$imeta])*
+                      => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
+            buf [$(#[$bmeta])* => $qitem : UNIT [ ] ]
+            queue [$( $tail )*]);
+    };
+    // Flush buffer on meta after ident
+    (SORT [$( $def:tt )*]
+        items [$($( #[$imeta:meta] )*
+                  => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+                                {$( $ifuncs:tt )*} )* ]
+        buf [$( #[$bmeta:meta] )*
+            => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ]
+        queue [ #[$qmeta:meta] $( $tail:tt )*]
+    ) => {
+        quick_error!(SORT [$( $def )*]
+            enum [$( $(#[$emeta])* => $eitem $(( $($etyp),* ))* )*
+                     $(#[$bmeta])* => $bitem: $bmode $(( $($btyp),* ))*]
+            items [$($( #[$imeta:meta] )*
+                      => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*
+                     $bitem: $bmode [$( $bvar:$btyp ),*] {} ]
+            buf [ #[$qmeta] ]
+            queue [$( $tail )*]);
+    };
+    // Add tuple enum-variant
+    (SORT [$( $def:tt )*]
+        items [$($( #[$imeta:meta] )*
+                  => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+                                {$( $ifuncs:tt )*} )* ]
+        buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ]
+        queue [($( $qvar:ident: $qtyp:ty ),+) $( $tail:tt )*]
+    ) => {
+        quick_error!(SORT [$( $def )*]
+            items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
+            buf [$( #[$bmeta] )* => $bitem: TUPLE [$( $qvar:$qtyp ),*] ]
+            queue [$( $tail )*]
+        );
+    };
+    // Add struct enum-variant - e.g. { descr: &'static str }
+    (SORT [$( $def:tt )*]
+        items [$($( #[$imeta:meta] )*
+                  => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+                                {$( $ifuncs:tt )*} )* ]
+        buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ]
+        queue [{ $( $qvar:ident: $qtyp:ty ),+} $( $tail:tt )*]
+    ) => {
+        quick_error!(SORT [$( $def )*]
+            items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
+            buf [$( #[$bmeta] )* => $bitem: STRUCT [$( $qvar:$qtyp ),*] ]
+            queue [$( $tail )*]);
+    };
+    // Add struct enum-variant, with excess comma - e.g. { descr: &'static str, }
+    (SORT [$( $def:tt )*]
+        items [$($( #[$imeta:meta] )*
+                  => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+                                {$( $ifuncs:tt )*} )* ]
+        buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ]
+        queue [{$( $qvar:ident: $qtyp:ty ),+ ,} $( $tail:tt )*]
+    ) => {
+        quick_error!(SORT [$( $def )*]
+            items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
+            buf [$( #[$bmeta] )* => $bitem: STRUCT [$( $qvar:$qtyp ),*] ]
+            queue [$( $tail )*]);
+    };
+    // Add braces and flush always on braces
+    (SORT [$( $def:tt )*]
+        items [$($( #[$imeta:meta] )*
+                  => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+                                {$( $ifuncs:tt )*} )* ]
+        buf [$( #[$bmeta:meta] )*
+                 => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ]
+        queue [ {$( $qfuncs:tt )*} $( $tail:tt )*]
+    ) => {
+        quick_error!(SORT [$( $def )*]
+            items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*
+                      $(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {$( $qfuncs )*} ]
+            buf [ ]
+            queue [$( $tail )*]);
+    };
+    // Flush buffer on double ident
+    (SORT [$( $def:tt )*]
+        items [$($( #[$imeta:meta] )*
+                  => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+                                {$( $ifuncs:tt )*} )* ]
+        buf [$( #[$bmeta:meta] )*
+                 => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ]
+        queue [ $qitem:ident $( $tail:tt )*]
+    ) => {
+        quick_error!(SORT [$( $def )*]
+            items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*
+                     $(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {} ]
+            buf [ => $qitem : UNIT [ ] ]
+            queue [$( $tail )*]);
+    };
+    // Flush buffer on end
+    (SORT [$( $def:tt )*]
+        items [$($( #[$imeta:meta] )*
+                  => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+                                {$( $ifuncs:tt )*} )* ]
+        buf [$( #[$bmeta:meta] )*
+            => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ]
+        queue [ ]
+    ) => {
+        quick_error!(SORT [$( $def )*]
+            items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*
+                     $(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {} ]
+            buf [ ]
+            queue [ ]);
+    };
+    // Public enum (Queue Empty)
+    (ENUM_DEFINITION [pub enum $name:ident $( #[$meta:meta] )*]
+        body [$($( #[$imeta:meta] )*
+            => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
+        queue [ ]
+    ) => {
+        $(#[$meta])*
+        pub enum $name {
+            $(
+                $(#[$imeta])*
+                $iitem $(($( $ttyp ),*))* $({$( $svar: $styp ),*})*,
+            )*
+        }
+    };
+    // Private enum (Queue Empty)
+    (ENUM_DEFINITION [enum $name:ident $( #[$meta:meta] )*]
+        body [$($( #[$imeta:meta] )*
+            => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
+        queue [ ]
+    ) => {
+        $(#[$meta])*
+        enum $name {
+            $(
+                $(#[$imeta])*
+                $iitem $(($( $ttyp ),*))* $({$( $svar: $styp ),*})*,
+            )*
+        }
+    };
+    // Unit variant
+    (ENUM_DEFINITION [$( $def:tt )*]
+        body [$($( #[$imeta:meta] )*
+            => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
+        queue [$( #[$qmeta:meta] )*
+            => $qitem:ident: UNIT [ ] $( $queue:tt )*]
+    ) => {
+        quick_error!(ENUM_DEFINITION [ $($def)* ]
+            body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )*
+                    $( #[$qmeta] )* => $qitem () {} ]
+            queue [ $($queue)* ]
+        );
+    };
+    // Tuple variant
+    (ENUM_DEFINITION [$( $def:tt )*]
+        body [$($( #[$imeta:meta] )*
+            => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
+        queue [$( #[$qmeta:meta] )*
+            => $qitem:ident: TUPLE [$( $qvar:ident: $qtyp:ty ),+] $( $queue:tt )*]
+    ) => {
+        quick_error!(ENUM_DEFINITION [ $($def)* ]
+            body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )*
+                    $( #[$qmeta] )* => $qitem (($( $qtyp ),*)) {} ]
+            queue [ $($queue)* ]
+        );
+    };
+    // Struct variant
+    (ENUM_DEFINITION [$( $def:tt )*]
+        body [$($( #[$imeta:meta] )*
+            => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
+        queue [$( #[$qmeta:meta] )*
+            => $qitem:ident: STRUCT [$( $qvar:ident: $qtyp:ty ),*] $( $queue:tt )*]
+    ) => {
+        quick_error!(ENUM_DEFINITION [ $($def)* ]
+            body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )*
+                    $( #[$qmeta] )* => $qitem () {{$( $qvar: $qtyp ),*}} ]
+            queue [ $($queue)* ]
+        );
+    };
+    (IMPLEMENTATIONS
+        $name:ident {$(
+            $item:ident: $imode:tt [$(#[$imeta:meta])*] [$( $var:ident: $typ:ty ),*] {$( $funcs:tt )*}
+        )*}
+    ) => {
+        #[allow(unused)]
+        impl ::std::fmt::Display for $name {
+            fn fmt(&self, fmt: &mut ::std::fmt::Formatter)
+                -> ::std::fmt::Result
+            {
+                match *self {
+                    $(
+                        $(#[$imeta])*
+                        quick_error!(ITEM_PATTERN
+                            $name $item: $imode [$( ref $var ),*]
+                        ) => {
+                            let display_fn = quick_error!(FIND_DISPLAY_IMPL
+                                $name $item: $imode
+                                {$( $funcs )*});
+
+                            display_fn(self, fmt)
+                        }
+                    )*
+                }
+            }
+        }
+        /*#[allow(unused)]
+        impl ::std::error::Error for $name {
+            fn description(&self) -> &str {
+                match *self {
+                    $(
+                        quick_error!(ITEM_PATTERN
+                            $name $item: $imode [$( ref $var ),*]
+                        ) => {
+                            quick_error!(FIND_DESCRIPTION_IMPL
+                                $item: $imode self fmt [$( $var ),*]
+                                {$( $funcs )*})
+                        }
+                    )*
+                }
+            }
+            fn cause(&self) -> Option<&::std::error::Error> {
+                match *self {
+                    $(
+                        quick_error!(ITEM_PATTERN
+                            $name $item: $imode [$( ref $var ),*]
+                        ) => {
+                            quick_error!(FIND_CAUSE_IMPL
+                                $item: $imode [$( $var ),*]
+                                {$( $funcs )*})
+                        }
+                    )*
+                }
+            }
+        }*/
+        #[allow(unused)]
+        impl $name {
+            /// A string describing the error kind.
+            pub fn description(&self) -> &str {
+                match *self {
+                    $(
+                        $(#[$imeta])*
+                        quick_error!(ITEM_PATTERN
+                            $name $item: $imode [$( ref $var ),*]
+                        ) => {
+                            quick_error!(FIND_DESCRIPTION_IMPL
+                                $item: $imode self fmt [$( $var ),*]
+                                {$( $funcs )*})
+                        }
+                    )*
+                }
+            }
+        }
+        $(
+            quick_error!(FIND_FROM_IMPL
+                $name $item: $imode [$( $var:$typ ),*]
+                {$( $funcs )*});
+        )*
+    };
+    (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+        { display($self_:tt) -> ($( $exprs:tt )*) $( $tail:tt )*}
+    ) => {
+        |quick_error!(IDENT $self_): &$name, f: &mut ::std::fmt::Formatter| {
+            write!(f, $( $exprs )*)
+        }
+    };
+    (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+        { display($pattern:expr) $( $tail:tt )*}
+    ) => {
+        |_, f: &mut ::std::fmt::Formatter| { write!(f, $pattern) }
+    };
+    (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+        { display($pattern:expr, $( $exprs:tt )*) $( $tail:tt )*}
+    ) => {
+        |_, f: &mut ::std::fmt::Formatter| { write!(f, $pattern, $( $exprs )*) }
+    };
+    (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+        { $t:tt $( $tail:tt )*}
+    ) => {
+        quick_error!(FIND_DISPLAY_IMPL
+            $name $item: $imode
+            {$( $tail )*})
+    };
+    (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+        { }
+    ) => {
+        |self_: &$name, f: &mut ::std::fmt::Formatter| {
+            write!(f, "{}", self_.description())
+        }
+    };
+    (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident
+        [$( $var:ident ),*]
+        { description($expr:expr) $( $tail:tt )*}
+    ) => {
+        $expr
+    };
+    (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident
+        [$( $var:ident ),*]
+        { $t:tt $( $tail:tt )*}
+    ) => {
+        quick_error!(FIND_DESCRIPTION_IMPL
+            $item: $imode $me $fmt [$( $var ),*]
+            {$( $tail )*})
+    };
+    (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident
+        [$( $var:ident ),*]
+        { }
+    ) => {
+        stringify!($item)
+    };
+    (FIND_CAUSE_IMPL $item:ident: $imode:tt
+        [$( $var:ident ),*]
+        { cause($expr:expr) $( $tail:tt )*}
+    ) => {
+        Some($expr)
+    };
+    (FIND_CAUSE_IMPL $item:ident: $imode:tt
+        [$( $var:ident ),*]
+        { $t:tt $( $tail:tt )*}
+    ) => {
+        quick_error!(FIND_CAUSE_IMPL
+            $item: $imode [$( $var ),*]
+            { $($tail)* })
+    };
+    (FIND_CAUSE_IMPL $item:ident: $imode:tt
+        [$( $var:ident ),*]
+        { }
+    ) => {
+        None
+    };
+    (FIND_FROM_IMPL $name:ident $item:ident: $imode:tt
+        [$( $var:ident: $typ:ty ),*]
+        { from() $( $tail:tt )*}
+    ) => {
+        $(
+            impl From<$typ> for $name {
+                fn from($var: $typ) -> $name {
+                    $name::$item($var)
+                }
+            }
+        )*
+        quick_error!(FIND_FROM_IMPL
+            $name $item: $imode [$( $var:$typ ),*]
+            {$( $tail )*});
+    };
+    (FIND_FROM_IMPL $name:ident $item:ident: UNIT
+        [ ]
+        { from($ftyp:ty) $( $tail:tt )*}
+    ) => {
+        impl From<$ftyp> for $name {
+            fn from(_discarded_error: $ftyp) -> $name {
+                $name::$item
+            }
+        }
+        quick_error!(FIND_FROM_IMPL
+            $name $item: UNIT [  ]
+            {$( $tail )*});
+    };
+    (FIND_FROM_IMPL $name:ident $item:ident: TUPLE
+        [$( $var:ident: $typ:ty ),*]
+        { from($fvar:ident: $ftyp:ty) -> ($( $texpr:expr ),*) $( $tail:tt )*}
+    ) => {
+        impl From<$ftyp> for $name {
+            fn from($fvar: $ftyp) -> $name {
+                $name::$item($( $texpr ),*)
+            }
+        }
+        quick_error!(FIND_FROM_IMPL
+            $name $item: TUPLE [$( $var:$typ ),*]
+            { $($tail)* });
+    };
+    (FIND_FROM_IMPL $name:ident $item:ident: STRUCT
+        [$( $var:ident: $typ:ty ),*]
+        { from($fvar:ident: $ftyp:ty) -> {$( $tvar:ident: $texpr:expr ),*} $( $tail:tt )*}
+    ) => {
+        impl From<$ftyp> for $name {
+            fn from($fvar: $ftyp) -> $name {
+                $name::$item {
+                    $( $tvar: $texpr ),*
+                }
+            }
+        }
+        quick_error!(FIND_FROM_IMPL
+            $name $item: STRUCT [$( $var:$typ ),*]
+            { $($tail)* });
+    };
+    (FIND_FROM_IMPL $name:ident $item:ident: $imode:tt
+        [$( $var:ident: $typ:ty ),*]
+        { $t:tt $( $tail:tt )*}
+    ) => {
+        quick_error!(FIND_FROM_IMPL
+            $name $item: $imode [$( $var:$typ ),*]
+            {$( $tail )*}
+        );
+    };
+    (FIND_FROM_IMPL $name:ident $item:ident: $imode:tt
+        [$( $var:ident: $typ:ty ),*]
+        { }
+    ) => {
+    };
+    (ITEM_BODY $(#[$imeta:meta])* $item:ident: UNIT
+    ) => { };
+    (ITEM_BODY $(#[$imeta:meta])* $item:ident: TUPLE
+        [$( $typ:ty ),*]
+    ) => {
+        ($( $typ ),*)
+    };
+    (ITEM_BODY $(#[$imeta:meta])* $item:ident: STRUCT
+        [$( $var:ident: $typ:ty ),*]
+    ) => {
+        {$( $var:$typ ),*}
+    };
+    (ITEM_PATTERN $name:ident $item:ident: UNIT []
+    ) => {
+        $name::$item
+    };
+    (ITEM_PATTERN $name:ident $item:ident: TUPLE
+        [$( ref $var:ident ),*]
+    ) => {
+        $name::$item ($( ref $var ),*)
+    };
+    (ITEM_PATTERN $name:ident $item:ident: STRUCT
+        [$( ref $var:ident ),*]
+    ) => {
+        $name::$item {$( ref $var ),*}
+    };
+    // This one should match all allowed sequences in "funcs" but not match
+    // anything else.
+    // This is to contrast FIND_* clauses which just find stuff they need and
+    // skip everything else completely
+    (ERROR_CHECK $imode:tt display($self_:tt) -> ($( $exprs:tt )*) $( $tail:tt )*)
+    => { quick_error!(ERROR_CHECK $imode $($tail)*); };
+    (ERROR_CHECK $imode:tt display($pattern: expr) $( $tail:tt )*)
+    => { quick_error!(ERROR_CHECK $imode $($tail)*); };
+    (ERROR_CHECK $imode:tt display($pattern: expr, $( $exprs:tt )*) $( $tail:tt )*)
+    => { quick_error!(ERROR_CHECK $imode $($tail)*); };
+    (ERROR_CHECK $imode:tt description($expr:expr) $( $tail:tt )*)
+    => { quick_error!(ERROR_CHECK $imode $($tail)*); };
+    (ERROR_CHECK $imode:tt cause($expr:expr) $($tail:tt)*)
+    => { quick_error!(ERROR_CHECK $imode $($tail)*); };
+    (ERROR_CHECK $imode:tt from() $($tail:tt)*)
+    => { quick_error!(ERROR_CHECK $imode $($tail)*); };
+    (ERROR_CHECK $imode:tt from($ftyp:ty) $($tail:tt)*)
+    => { quick_error!(ERROR_CHECK $imode $($tail)*); };
+    (ERROR_CHECK TUPLE from($fvar:ident: $ftyp:ty) -> ($( $e:expr ),*) $( $tail:tt )*)
+    => { quick_error!(ERROR_CHECK TUPLE $($tail)*); };
+    (ERROR_CHECK STRUCT from($fvar:ident: $ftyp:ty) -> {$( $v:ident: $e:expr ),*} $( $tail:tt )*)
+    => { quick_error!(ERROR_CHECK STRUCT $($tail)*); };
+    (ERROR_CHECK $imode:tt ) => {};
+    // Utility functions
+    (IDENT $ident:ident) => { $ident }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/error-chain/src/quick_main.rs
@@ -0,0 +1,73 @@
+/// Convenient wrapper to be able to use `try!` and such in the main. You can
+/// use it with a separated function:
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! {}
+/// # fn main() {
+/// quick_main!(run);
+/// # }
+///
+/// fn run() -> Result<()> {
+///     Err("error".into())
+/// }
+/// ```
+///
+/// or with a closure:
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! {}
+/// # fn main() {
+/// quick_main!(|| -> Result<()> {
+///     Err("error".into())
+/// });
+/// # }
+/// ```
+///
+/// You can also set the exit value of the process by returning a type that implements [`ExitCode`](trait.ExitCode.html):
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! {}
+/// # fn main() {
+/// quick_main!(run);
+/// # }
+///
+/// fn run() -> Result<i32> {
+///     Err("error".into())
+/// }
+/// ```
+#[macro_export]
+macro_rules! quick_main {
+    ($main:expr) => {
+        fn main() {
+            use ::std::io::Write;
+
+            ::std::process::exit(match $main() {
+                Ok(ret) => $crate::ExitCode::code(ret),
+                Err(ref e) => {
+                    write!(&mut ::std::io::stderr(), "{}", $crate::ChainedError::display(e))
+                        .expect("Error writing to stderr");
+
+                    1
+                }
+            });
+        }
+    };
+}
+
+/// Represents a value that can be used as the exit status of the process.
+/// See [`quick_main!`](macro.quick_main.html).
+pub trait ExitCode {
+    /// Returns the value to use as the exit status.
+    fn code(self) -> i32;
+}
+
+impl ExitCode for i32 {
+    fn code(self) -> i32 { self }
+}
+
+impl ExitCode for () {
+    fn code(self) -> i32 { 0 }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/error-chain/tests/quick_main.rs
@@ -0,0 +1,30 @@
+#![allow(dead_code)]
+#[macro_use]
+extern crate error_chain;
+
+error_chain!();
+
+mod unit {
+    use super::*;
+    quick_main!(run);
+
+    fn run() -> Result<()> {
+        Ok(())
+    }
+}
+
+mod i32 {
+    use super::*;
+    quick_main!(run);
+
+    fn run() -> Result<i32> {
+        Ok(1)
+    }
+}
+
+mod closure {
+    use super::*;
+    quick_main!(|| -> Result<()> {
+        Ok(())
+    });
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/error-chain/tests/tests.rs
@@ -0,0 +1,595 @@
+#![allow(dead_code)]
+//#![feature(trace_macros)]
+//
+//trace_macros!(true);
+
+#[macro_use]
+extern crate error_chain;
+
+#[test]
+fn smoke_test_1() {
+    error_chain! {
+        types {
+            Error, ErrorKind, ResultExt, Result;
+        }
+
+        links { }
+
+        foreign_links { }
+
+        errors { }
+    };
+}
+
+#[test]
+fn smoke_test_2() {
+    error_chain! {
+        types { }
+
+        links { }
+
+        foreign_links { }
+
+        errors { }
+    };
+}
+
+#[test]
+fn smoke_test_3() {
+    error_chain! {
+        links { }
+
+        foreign_links { }
+
+        errors { }
+    };
+}
+
+#[test]
+fn smoke_test_4() {
+    error_chain! {
+        links { }
+
+        foreign_links { }
+
+        errors {
+            HttpStatus(e: u32) {
+                description("http request returned an unsuccessful status code")
+                display("http request returned an unsuccessful status code: {}", e)
+            }
+        }
+    };
+}
+
+#[test]
+fn smoke_test_5() {
+    error_chain! {
+        types { }
+
+        links { }
+
+        foreign_links { }
+
+        errors {
+            HttpStatus(e: u32) {
+                description("http request returned an unsuccessful status code")
+                display("http request returned an unsuccessful status code: {}", e)
+            }
+        }
+    };
+}
+
+#[test]
+fn smoke_test_6() {
+    error_chain! {
+        errors {
+            HttpStatus(e: u32) {
+                description("http request returned an unsuccessful status code")
+                display("http request returned an unsuccessful status code: {}", e)
+            }
+        }
+    };
+}
+
+#[test]
+fn smoke_test_7() {
+    error_chain! {
+        types { }
+
+        foreign_links { }
+
+        errors {
+            HttpStatus(e: u32) {
+                description("http request returned an unsuccessful status code")
+                display("http request returned an unsuccessful status code: {}", e)
+            }
+        }
+    };
+}
+
+#[test]
+fn smoke_test_8() {
+    error_chain! {
+        types { }
+
+        links { }
+        links { }
+
+        foreign_links { }
+        foreign_links { }
+
+        errors {
+            FileNotFound
+            AccessDenied
+        }
+    };
+}
+
+#[test]
+fn order_test_1() {
+    error_chain! { types { } links { } foreign_links { } errors { } };
+}
+
+#[test]
+fn order_test_2() {
+    error_chain! { links { } types { } foreign_links { } errors { } };
+}
+
+#[test]
+fn order_test_3() {
+    error_chain! { foreign_links { }  links { }  errors { } types { } };
+}
+
+#[test]
+fn order_test_4() {
+    error_chain! { errors { } types { } foreign_links { } };
+}
+
+#[test]
+fn order_test_5() {
+    error_chain! { foreign_links { } types { }  };
+}
+
+#[test]
+fn order_test_6() {
+    error_chain! {
+        links { }
+
+        errors {
+            HttpStatus(e: u32) {
+                description("http request returned an unsuccessful status code")
+                display("http request returned an unsuccessful status code: {}", e)
+            }
+        }
+
+
+        foreign_links { }
+    };
+}
+
+#[test]
+fn order_test_7() {
+    error_chain! {
+        links { }
+
+        foreign_links { }
+
+        types {
+            Error, ErrorKind, ResultExt, Result;
+        }
+    };
+}
+
+
+#[test]
+fn order_test_8() {
+    error_chain! {
+        links { }
+
+        foreign_links { }
+        foreign_links { }
+
+        types {
+            Error, ErrorKind, ResultExt, Result;
+        }
+    };
+}
+
+#[test]
+fn empty() {
+    error_chain! { };
+}
+
+#[test]
+#[cfg(feature = "backtrace")]
+fn has_backtrace_depending_on_env() {
+    use std::env;
+
+    error_chain! {
+        types {}
+        links {}
+        foreign_links {}
+        errors {
+            MyError
+        }
+    }
+
+    let original_value = env::var_os("RUST_BACKTRACE");
+
+    // missing RUST_BACKTRACE and RUST_BACKTRACE=0
+    env::remove_var("RUST_BACKTRACE");
+    let err = Error::from(ErrorKind::MyError);
+    assert!(err.backtrace().is_none());
+    env::set_var("RUST_BACKTRACE", "0");
+    let err = Error::from(ErrorKind::MyError);
+    assert!(err.backtrace().is_none());
+
+    // RUST_BACKTRACE set to anything but 0
+    env::set_var("RUST_BACKTRACE", "yes");
+    let err = Error::from(ErrorKind::MyError);
+    assert!(err.backtrace().is_some());
+
+    if let Some(var) = original_value {
+        env::set_var("RUST_BACKTRACE", var);
+    }
+}
+
+#[test]
+fn chain_err() {
+    use std::fmt;
+
+    error_chain! {
+        foreign_links {
+            Fmt(fmt::Error);
+        }
+        errors {
+            Test
+        }
+    }
+
+    let _: Result<()> = Err(fmt::Error).chain_err(|| "");
+    let _: Result<()> = Err(Error::from_kind(ErrorKind::Test)).chain_err(|| "");
+}
+
+#[test]
+fn links() {
+    mod test {
+        error_chain! {}
+    }
+
+    error_chain! {
+        links {
+            Test(test::Error, test::ErrorKind);
+        }
+    }
+}
+
+#[cfg(test)]
+mod foreign_link_test {
+
+    use std::fmt;
+
+    // Note: foreign errors must be `pub` because they appear in the
+    // signature of the public foreign_link_error_path
+    #[derive(Debug)]
+    pub struct ForeignError {
+        cause: ForeignErrorCause
+    }
+
+    impl ::std::error::Error for ForeignError {
+        fn description(&self) -> &'static str {
+            "Foreign error description"
+        }
+
+        fn cause(&self) -> Option<&::std::error::Error> { Some(&self.cause) }
+    }
+
+    impl fmt::Display for ForeignError {
+        fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+            write!(formatter, "Foreign error display")
+        }
+    }
+
+    #[derive(Debug)]
+    pub struct ForeignErrorCause {}
+
+    impl ::std::error::Error for ForeignErrorCause {
+        fn description(&self) -> &'static str {
+            "Foreign error cause description"
+        }
+
+        fn cause(&self) -> Option<&::std::error::Error> { None }
+    }
+
+    impl fmt::Display for ForeignErrorCause {
+        fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+            write!(formatter, "Foreign error cause display")
+        }
+    }
+
+    error_chain! {
+        types{
+            Error, ErrorKind, ResultExt, Result;
+        }
+        links {}
+        foreign_links {
+            Foreign(ForeignError);
+            Io(::std::io::Error);
+        }
+        errors {}
+    }
+
+    #[test]
+    fn display_underlying_error() {
+        let chained_error = try_foreign_error().err().unwrap();
+        assert_eq!(
+            format!("{}", ForeignError{ cause: ForeignErrorCause{} }),
+            format!("{}", chained_error)
+        );
+    }
+
+    #[test]
+    fn finds_cause() {
+        let chained_error = try_foreign_error().err().unwrap();
+        assert_eq!(
+            format!("{}", ForeignErrorCause{}),
+            format!("{}", ::std::error::Error::cause(&chained_error).unwrap())
+        );
+    }
+
+    #[test]
+    fn iterates() {
+        let chained_error = try_foreign_error().err().unwrap();
+        let mut error_iter = chained_error.iter();
+        assert_eq!(
+            format!("{}", ForeignError{ cause: ForeignErrorCause{} }),
+            format!("{}", error_iter.next().unwrap())
+        );
+        assert_eq!(
+            format!("{}", ForeignErrorCause{}),
+            format!("{}", error_iter.next().unwrap())
+        );
+        assert_eq!(
+            format!("{:?}", None as Option<&::std::error::Error>),
+            format!("{:?}", error_iter.next())
+        );
+    }
+
+    fn try_foreign_error() -> Result<()> {
+        try!(Err(ForeignError{
+            cause: ForeignErrorCause{}
+        }));
+        Ok(())
+    }
+}
+
+#[cfg(test)]
+mod attributes_test {
+    #[allow(unused_imports)]
+    use std::io;
+
+    #[cfg(not(test))]
+    mod inner {
+        error_chain! {
+
+        }
+    }
+
+    error_chain! {
+        types {
+            Error, ErrorKind, ResultExt, Result;
+        }
+
+        links {
+            Inner(inner::Error, inner::ErrorKind) #[cfg(not(test))];
+        }
+
+        foreign_links {
+            Io(io::Error) #[cfg(not(test))];
+        }
+
+        errors {
+            #[cfg(not(test))]
+            AnError {
+
+            }
+        }
+    }
+}
+
+#[test]
+fn with_result() {
+    error_chain! {
+        types {
+            Error, ErrorKind, ResultExt, Result;
+        }
+    }
+    let _: Result<()> = Ok(());
+}
+
+#[test]
+fn without_result() {
+    error_chain! {
+        types {
+            Error, ErrorKind, ResultExt;
+        }
+    }
+    let _: Result<(), ()> = Ok(());
+}
+
+#[test]
+fn documentation() {
+    mod inner {
+        error_chain! {}
+    }
+
+    error_chain! {
+        links {
+            Inner(inner::Error, inner::ErrorKind) #[doc = "Doc"];
+        }
+        foreign_links {
+            Io(::std::io::Error) #[doc = "Doc"];
+        }
+        errors {
+            /// Doc
+            Variant
+        }
+    }
+}
+
+#[cfg(test)]
+mod multiple_error_same_mod {
+    error_chain! {
+        types {
+            MyError, MyErrorKind, MyResultExt, MyResult;
+        }
+    }
+    error_chain! {}
+}
+
+#[doc(test)]
+#[deny(dead_code)]
+mod allow_dead_code {
+    error_chain! {}
+}
+
+// Make sure links actually work!
+#[test]
+fn rustup_regression() {
+    error_chain! {
+        links {
+            Download(error_chain::mock::Error, error_chain::mock::ErrorKind);
+        }
+
+        foreign_links { }
+
+        errors {
+            LocatingWorkingDir {
+                description("could not locate working directory")
+            }
+        }
+    }
+}
+
+#[test]
+fn error_patterns() {
+    error_chain! {
+        links { }
+
+        foreign_links { }
+
+        errors { }
+    }
+
+    // Tuples look nice when matching errors
+    match Error::from("Test") {
+        Error(ErrorKind::Msg(_), _) => {
+        }
+    }
+}
+
+#[test]
+fn error_first() {
+    error_chain! {
+        errors {
+            LocatingWorkingDir {
+                description("could not locate working directory")
+            }
+        }
+
+        links {
+            Download(error_chain::mock::Error, error_chain::mock::ErrorKind);
+        }
+
+        foreign_links { }
+    }
+}
+
+#[test]
+fn bail() {
+    error_chain! {
+        errors { Foo }
+    }
+
+    fn foo() -> Result<()> {
+        bail!(ErrorKind::Foo)
+    }
+
+    fn bar() -> Result<()> {
+        bail!("bar")
+    }
+
+    fn baz() -> Result<()> {
+        bail!("{}", "baz")
+    }
+}
+
+#[test]
+fn ensure() {
+    error_chain! {
+        errors { Bar }
+    }
+
+    fn foo(x: u8) -> Result<()> {
+        ensure!(x == 42, ErrorKind::Bar);
+        Ok(())
+    }
+
+    assert!(foo(42).is_ok());
+    assert!(foo(0).is_err());
+}
+
+/// Since the `types` declaration is a list of symbols, check if we
+/// don't change their meaning or order.
+#[test]
+fn types_declarations() {
+    error_chain! {
+        types {
+            MyError, MyErrorKind, MyResultExt, MyResult;
+        }
+    }
+
+    MyError::from_kind(MyErrorKind::Msg("".into()));
+
+    let err: Result<(), ::std::io::Error> = Ok(());
+    MyResultExt::chain_err(err, || "").unwrap();
+
+    let _: MyResult<()> = Ok(());
+}
+
+#[test]
+/// Calling chain_err over a `Result` containing an error to get a chained error
+//// and constructing a MyError directly, passing it an error should be equivalent.
+fn rewrapping() {
+
+    use std::env::VarError::{self, NotPresent, NotUnicode};
+
+    error_chain! {
+        foreign_links {
+            VarErr(VarError);
+        }
+
+        types {
+            MyError, MyErrorKind, MyResultExt, MyResult;
+        }
+    }
+
+    let result_a_from_func: Result<String, _> = Err(VarError::NotPresent);
+    let result_b_from_func: Result<String, _> = Err(VarError::NotPresent);
+
+    let our_error_a = result_a_from_func.map_err(|e| match e {
+        NotPresent => MyError::with_chain(e, "env var wasn't provided"),
+        NotUnicode(_) => MyError::with_chain(e, "env var was bork文字化ã"),
+    });
+
+    let our_error_b = result_b_from_func.or_else(|e| match e {
+        NotPresent => Err(e).chain_err(|| "env var wasn't provided"),
+        NotUnicode(_) => Err(e).chain_err(|| "env var was bork文字化ã"),
+    });
+
+    assert_eq!(
+        format!("{}", our_error_a.unwrap_err()),
+        format!("{}", our_error_b.unwrap_err())
+    );
+
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fs2/.appveyor.yml
@@ -0,0 +1,18 @@
+environment:
+  matrix:
+    - TARGET: x86_64-pc-windows-msvc
+    - TARGET: i686-pc-windows-msvc
+    - TARGET: x86_64-pc-windows-gnu
+    - TARGET: i686-pc-windows-gnu
+
+install:
+  - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe" -FileName "rust-nightly.exe"
+  - ps: .\rust-nightly.exe /VERYSILENT /NORESTART /DIR="C:\rust" | Out-Null
+  - ps: $env:PATH="$env:PATH;C:\rust\bin"
+
+build_script:
+  - cargo build -v
+
+test_script:
+  - SET RUST_BACKTRACE=1
+  - cargo test -v
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fs2/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".appveyor.yml":"15c5548159ad6ebcc02960bb6a3269e729e772df2733b7d4c7cc1583c413ae45",".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"5733d01f7cd27cbdd17a46399103e83eca528727e6cad7f355f6748e772ef916","Cargo.toml":"c257476252f17472f1a78c9fa92b137dc435873797ec1a137aa73043b3ad06a7","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"7667acd3dfd050dadccf8b7815435b9108c24c5704944085281beed6a181e220","src/lib.rs":"106e402d1c5ae68558f4e8a3971b646c12f19762363d2cf15c13a1c2aeb1d1e7","src/unix.rs":"67f0244c118cff918f01b6c164dfe604039ce9160a099ba6e4ff86dcf8ec0097","src/windows.rs":"5767d923280998e341504f8d2a015b8b0c3f8b2b1188610aa4c1b6a343da5682"},"package":"9ab76cfd2aaa59b7bf6688ad9ba15bbae64bff97f04ea02144cfd3443e5c2866"}
\ No newline at end of file
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fs2/.travis.yml
@@ -0,0 +1,21 @@
+language: rust
+
+rust:
+- 1.8.0
+- stable
+- nightly
+
+os:
+  - linux
+  - osx
+
+env:
+  matrix:
+    - ARCH=x86_64
+    - ARCH=i686
+
+script:
+  - cargo build --verbose
+  - if [[ $TRAVIS_RUST_VERSION = nightly* ]]; then
+      env RUST_BACKTRACE=1 cargo test -v;
+    fi
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fs2/Cargo.toml
@@ -0,0 +1,30 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g. crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+name = "fs2"
+version = "0.4.2"
+authors = ["Dan Burkert <dan@danburkert.com>"]
+description = "Cross-platform file locks and file duplication."
+documentation = "https://docs.rs/fs2"
+keywords = ["file", "file-system", "lock", "duplicate", "flock"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/danburkert/fs2-rs"
+[dev-dependencies.tempdir]
+version = "0.3"
+[target."cfg(windows)".dependencies.winapi]
+version = "0.2"
+
+[target."cfg(windows)".dependencies.kernel32-sys]
+version = "0.2"
+[target."cfg(unix)".dependencies.libc]
+version = "0.2.2"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fs2/LICENSE-APACHE
@@ -0,0 +1,201 @@
+                              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.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fs2/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2015 The Rust Project Developers
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fs2/README.md
@@ -0,0 +1,50 @@
+# fs2
+
+Extended utilities for working with files and filesystems in Rust. `fs2`
+requires Rust stable 1.8 or greater.
+
+[Documentation](https://docs.rs/fs2)
+
+[![Linux Status](https://travis-ci.org/danburkert/fs2-rs.svg?branch=master)](https://travis-ci.org/danburkert/fs2-rs)
+[![Windows Status](https://ci.appveyor.com/api/projects/status/iuvjv1aaaml0rntt/branch/master?svg=true)](https://ci.appveyor.com/project/danburkert/fs2-rs)
+
+## Features
+
+- [x] file descriptor duplication.
+- [x] file locks.
+- [x] file (pre)allocation.
+- [x] file allocation information.
+- [x] filesystem space usage information.
+
+## Platforms
+
+`fs2` should work on any platform supported by
+[`libc`](https://github.com/rust-lang-nursery/libc#platforms-and-documentation).
+
+`fs2` is continuously tested on:
+  * `x86_64-unknown-linux-gnu` (Linux)
+  * `i686-unknown-linux-gnu`
+  * `x86_64-apple-darwin` (OSX)
+  * `i686-apple-darwin`
+  * `x86_64-pc-windows-msvc` (Windows)
+  * `i686-pc-windows-msvc`
+  * `x86_64-pc-windows-gnu`
+  * `i686-pc-windows-gnu`
+
+## Benchmarks
+
+Simple benchmarks are provided for the methods provided. Many of these
+benchmarks use files in a temporary directory. On many modern Linux distros the
+default temporary directory, `/tmp`, is mounted on a tempfs filesystem, which
+will have different performance characteristics than a disk-backed filesystem.
+The temporary directory is configurable at runtime through the environment (see
+[`env::temp_dir`](https://doc.rust-lang.org/stable/std/env/fn.temp_dir.html)).
+
+## License
+
+`fs2` is primarily distributed under the terms of both the MIT license and the
+Apache License (Version 2.0).
+
+See [LICENSE-APACHE](LICENSE-APACHE), [LICENSE-MIT](LICENSE-MIT) for details.
+
+Copyright (c) 2015 Dan Burkert.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fs2/src/lib.rs
@@ -0,0 +1,452 @@
+#![cfg_attr(test, feature(test))]
+#![deny(warnings)]
+
+#[cfg(unix)]
+mod unix;
+#[cfg(unix)]
+use unix as sys;
+
+#[cfg(windows)]
+mod windows;
+#[cfg(windows)]
+use windows as sys;
+
+use std::fs::File;
+use std::io::{Error, Result};
+use std::path::Path;
+
+/// Extension trait for `std::fs::File` which provides allocation, duplication and locking methods.
+///
+/// ## Notes on File Locks
+///
+/// This library provides whole-file locks in both shared (read) and exclusive
+/// (read-write) varieties.
+///
+/// File locks are a cross-platform hazard since the file lock APIs exposed by
+/// operating system kernels vary in subtle and not-so-subtle ways.
+///
+/// The API exposed by this library can be safely used across platforms as long
+/// as the following rules are followed:
+///
+///   * Multiple locks should not be created on an individual `File` instance
+///     concurrently.
+///   * Duplicated files should not be locked without great care.
+///   * Files to be locked should be opened with at least read or write
+///     permissions.
+///   * File locks may only be relied upon to be advisory.
+///
+/// See the tests in `lib.rs` for cross-platform lock behavior that may be
+/// relied upon; see the tests in `unix.rs` and `windows.rs` for examples of
+/// platform-specific behavior. File locks are implemented with
+/// [`flock(2)`](http://man7.org/linux/man-pages/man2/flock.2.html) on Unix and
+/// [`LockFile`](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365202(v=vs.85).aspx)
+/// on Windows.
+pub trait FileExt {
+
+    /// Returns a duplicate instance of the file.
+    ///
+    /// The returned file will share the same file position as the original
+    /// file.
+    ///
+    /// If using rustc version 1.9 or later, prefer using `File::try_clone` to this.
+    ///
+    /// # Notes
+    ///
+    /// This is implemented with
+    /// [`dup(2)`](http://man7.org/linux/man-pages/man2/dup.2.html) on Unix and
+    /// [`DuplicateHandle`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724251(v=vs.85).aspx)
+    /// on Windows.
+    fn duplicate(&self) -> Result<File>;
+
+    /// Returns the amount of physical space allocated for a file.
+    fn allocated_size(&self) -> Result<u64>;
+
+    /// Ensures that at least `len` bytes of disk space are allocated for the
+    /// file, and the file size is at least `len` bytes. After a successful call
+    /// to `allocate`, subsequent writes to the file within the specified length
+    /// are guaranteed not to fail because of lack of disk space.
+    fn allocate(&self, len: u64) -> Result<()>;
+
+    /// Locks the file for shared usage, blocking if the file is currently
+    /// locked exclusively.
+    fn lock_shared(&self) -> Result<()>;
+
+    /// Locks the file for exclusive usage, blocking if the file is currently
+    /// locked.
+    fn lock_exclusive(&self) -> Result<()>;
+
+    /// Locks the file for shared usage, or returns a an error if the file is
+    /// currently locked (see `lock_contended_error`).
+    fn try_lock_shared(&self) -> Result<()>;
+
+    /// Locks the file for shared usage, or returns a an error if the file is
+    /// currently locked (see `lock_contended_error`).
+    fn try_lock_exclusive(&self) -> Result<()>;
+
+    /// Unlocks the file.
+    fn unlock(&self) -> Result<()>;
+}
+
+impl FileExt for File {
+    fn duplicate(&self) -> Result<File> {
+        sys::duplicate(self)
+    }
+    fn allocated_size(&self) -> Result<u64> {
+        sys::allocated_size(self)
+    }
+    fn allocate(&self, len: u64) -> Result<()> {
+        sys::allocate(self, len)
+    }
+    fn lock_shared(&self) -> Result<()> {
+        sys::lock_shared(self)
+    }
+    fn lock_exclusive(&self) -> Result<()> {
+        sys::lock_exclusive(self)
+    }
+    fn try_lock_shared(&self) -> Result<()> {
+        sys::try_lock_shared(self)
+    }
+    fn try_lock_exclusive(&self) -> Result<()> {
+        sys::try_lock_exclusive(self)
+    }
+    fn unlock(&self) -> Result<()> {
+        sys::unlock(self)
+    }
+}
+
+/// Returns the error that a call to a try lock method on a contended file will
+/// return.
+pub fn lock_contended_error() -> Error {
+    sys::lock_error()
+}
+
+/// `FsStats` contains some common stats about a file system.
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+pub struct FsStats {
+    free_space: u64,
+    available_space: u64,
+    total_space: u64,
+    allocation_granularity: u64,
+}
+
+impl FsStats {
+    /// Returns the number of free bytes in the file system containing the provided
+    /// path.
+    pub fn free_space(&self) -> u64 {
+        self.free_space
+    }
+
+    /// Returns the available space in bytes to non-priveleged users in the file
+    /// system containing the provided path.
+    pub fn available_space(&self) -> u64 {
+        self.available_space
+    }
+
+    /// Returns the total space in bytes in the file system containing the provided
+    /// path.
+    pub fn total_space(&self) -> u64 {
+        self.total_space
+    }
+
+    /// Returns the filesystem's disk space allocation granularity in bytes.
+    /// The provided path may be for any file in the filesystem.
+    ///
+    /// On Posix, this is equivalent to the filesystem's block size.
+    /// On Windows, this is equivalent to the filesystem's cluster size.
+    pub fn allocation_granularity(&self) -> u64 {
+        self.allocation_granularity
+    }
+}
+
+/// Get the stats of the file system containing the provided path.
+pub fn statvfs<P>(path: P) -> Result<FsStats> where P: AsRef<Path> {
+    sys::statvfs(path.as_ref())
+}
+
+/// Returns the number of free bytes in the file system containing the provided
+/// path.
+pub fn free_space<P>(path: P) -> Result<u64> where P: AsRef<Path> {
+    statvfs(path).map(|stat| stat.free_space)
+}
+
+/// Returns the available space in bytes to non-priveleged users in the file
+/// system containing the provided path.
+pub fn available_space<P>(path: P) -> Result<u64> where P: AsRef<Path> {
+    statvfs(path).map(|stat| stat.available_space)
+}
+
+/// Returns the total space in bytes in the file system containing the provided
+/// path.
+pub fn total_space<P>(path: P) -> Result<u64> where P: AsRef<Path> {
+    statvfs(path).map(|stat| stat.total_space)
+}
+
+/// Returns the filesystem's disk space allocation granularity in bytes.
+/// The provided path may be for any file in the filesystem.
+///
+/// On Posix, this is equivalent to the filesystem's block size.
+/// On Windows, this is equivalent to the filesystem's cluster size.
+pub fn allocation_granularity<P>(path: P) -> Result<u64> where P: AsRef<Path> {
+    statvfs(path).map(|stat| stat.allocation_granularity)
+}
+
+#[cfg(test)]
+mod test {
+
+    extern crate tempdir;
+    extern crate test;
+
+    use std::fs;
+    use super::*;
+    use std::io::{Read, Seek, SeekFrom, Write};
+
+    /// Tests file duplication.
+    #[test]
+    fn duplicate() {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("fs2");
+        let mut file1 =
+            fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap();
+        let mut file2 = file1.duplicate().unwrap();
+
+        // Write into the first file and then drop it.
+        file1.write_all(b"foo").unwrap();
+        drop(file1);
+
+        let mut buf = vec![];
+
+        // Read from the second file; since the position is shared it will already be at EOF.
+        file2.read_to_end(&mut buf).unwrap();
+        assert_eq!(0, buf.len());
+
+        // Rewind and read.
+        file2.seek(SeekFrom::Start(0)).unwrap();
+        file2.read_to_end(&mut buf).unwrap();
+        assert_eq!(&buf, &b"foo");
+    }
+
+    /// Tests shared file lock operations.
+    #[test]
+    fn lock_shared() {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("fs2");
+        let file1 = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap();
+        let file2 = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap();
+        let file3 = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap();
+
+        // Concurrent shared access is OK, but not shared and exclusive.
+        file1.lock_shared().unwrap();
+        file2.lock_shared().unwrap();
+        assert_eq!(file3.try_lock_exclusive().unwrap_err().kind(),
+                   lock_contended_error().kind());
+        file1.unlock().unwrap();
+        assert_eq!(file3.try_lock_exclusive().unwrap_err().kind(),
+                   lock_contended_error().kind());
+
+        // Once all shared file locks are dropped, an exclusive lock may be created;
+        file2.unlock().unwrap();
+        file3.lock_exclusive().unwrap();
+    }
+
+    /// Tests exclusive file lock operations.
+    #[test]
+    fn lock_exclusive() {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("fs2");
+        let file1 = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap();
+        let file2 = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap();
+
+        // No other access is possible once an exclusive lock is created.
+        file1.lock_exclusive().unwrap();
+        assert_eq!(file2.try_lock_exclusive().unwrap_err().kind(),
+                   lock_contended_error().kind());
+        assert_eq!(file2.try_lock_shared().unwrap_err().kind(),
+                   lock_contended_error().kind());
+
+        // Once the exclusive lock is dropped, the second file is able to create a lock.
+        file1.unlock().unwrap();
+        file2.lock_exclusive().unwrap();
+    }
+
+    /// Tests that a lock is released after the file that owns it is dropped.
+    #[test]
+    fn lock_cleanup() {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("fs2");
+        let file1 = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap();
+        let file2 = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap();
+
+        file1.lock_exclusive().unwrap();
+        assert_eq!(file2.try_lock_shared().unwrap_err().kind(),
+                   lock_contended_error().kind());
+
+        // Drop file1; the lock should be released.
+        drop(file1);
+        file2.lock_shared().unwrap();
+    }
+
+    /// Tests file allocation.
+    #[test]
+    fn allocate() {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("fs2");
+        let file = fs::OpenOptions::new().write(true).create(true).open(&path).unwrap();
+        let blksize = allocation_granularity(&path).unwrap();
+
+        // New files are created with no allocated size.
+        assert_eq!(0, file.allocated_size().unwrap());
+        assert_eq!(0, file.metadata().unwrap().len());
+
+        // Allocate space for the file, checking that the allocated size steps
+        // up by block size, and the file length matches the allocated size.
+
+        file.allocate(2 * blksize - 1).unwrap();
+        assert_eq!(2 * blksize, file.allocated_size().unwrap());
+        assert_eq!(2 * blksize - 1, file.metadata().unwrap().len());
+
+        // Truncate the file, checking that the allocated size steps down by
+        // block size.
+
+        file.set_len(blksize + 1).unwrap();
+        assert_eq!(2 * blksize, file.allocated_size().unwrap());
+        assert_eq!(blksize + 1, file.metadata().unwrap().len());
+    }
+
+    /// Checks filesystem space methods.
+    #[test]
+    fn filesystem_space() {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let total_space = total_space(&tempdir.path()).unwrap();
+        let free_space = free_space(&tempdir.path()).unwrap();
+        let available_space = available_space(&tempdir.path()).unwrap();
+
+        assert!(total_space > free_space);
+        assert!(total_space > available_space);
+        assert!(available_space <= free_space);
+    }
+
+    /// Benchmarks creating and removing a file. This is a baseline benchmark
+    /// for comparing against the truncate and allocate benchmarks.
+    #[bench]
+    fn bench_file_create(b: &mut test::Bencher) {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("file");
+
+        b.iter(|| {
+            fs::OpenOptions::new()
+                            .read(true)
+                            .write(true)
+                            .create(true)
+                            .open(&path)
+                            .unwrap();
+            fs::remove_file(&path).unwrap();
+        });
+    }
+
+    /// Benchmarks creating a file, truncating it to 32MiB, and deleting it.
+    #[bench]
+    fn bench_file_truncate(b: &mut test::Bencher) {
+        let size = 32 * 1024 * 1024;
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("file");
+
+        b.iter(|| {
+            let file = fs::OpenOptions::new()
+                                       .read(true)
+                                       .write(true)
+                                       .create(true)
+                                       .open(&path)
+                                       .unwrap();
+            file.set_len(size).unwrap();
+            fs::remove_file(&path).unwrap();
+        });
+    }
+
+    /// Benchmarks creating a file, allocating 32MiB for it, and deleting it.
+    #[bench]
+    fn bench_file_allocate(b: &mut test::Bencher) {
+        let size = 32 * 1024 * 1024;
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("file");
+
+        b.iter(|| {
+            let file = fs::OpenOptions::new()
+                                       .read(true)
+                                       .write(true)
+                                       .create(true)
+                                       .open(&path)
+                                       .unwrap();
+            file.allocate(size).unwrap();
+            fs::remove_file(&path).unwrap();
+        });
+    }
+
+    /// Benchmarks creating a file, allocating 32MiB for it, and deleting it.
+    #[bench]
+    fn bench_allocated_size(b: &mut test::Bencher) {
+        let size = 32 * 1024 * 1024;
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("file");
+        let file = fs::OpenOptions::new()
+                                   .read(true)
+                                   .write(true)
+                                   .create(true)
+                                   .open(&path)
+                                   .unwrap();
+        file.allocate(size).unwrap();
+
+        b.iter(|| {
+            file.allocated_size().unwrap();
+        });
+    }
+
+    /// Benchmarks duplicating a file descriptor or handle.
+    #[bench]
+    fn bench_duplicate(b: &mut test::Bencher) {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("fs2");
+        let file = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap();
+
+        b.iter(|| test::black_box(file.duplicate().unwrap()));
+    }
+
+    /// Benchmarks locking and unlocking a file lock.
+    #[bench]
+    fn bench_lock_unlock(b: &mut test::Bencher) {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("fs2");
+        let file = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap();
+
+        b.iter(|| {
+            file.lock_exclusive().unwrap();
+            file.unlock().unwrap();
+        });
+    }
+
+    /// Benchmarks the free space method.
+    #[bench]
+    fn bench_free_space(b: &mut test::Bencher) {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        b.iter(|| {
+            test::black_box(free_space(&tempdir.path()).unwrap());
+        });
+    }
+
+    /// Benchmarks the available space method.
+    #[bench]
+    fn bench_available_space(b: &mut test::Bencher) {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        b.iter(|| {
+            test::black_box(available_space(&tempdir.path()).unwrap());
+        });
+    }
+
+    /// Benchmarks the total space method.
+    #[bench]
+    fn bench_total_space(b: &mut test::Bencher) {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        b.iter(|| {
+            test::black_box(total_space(&tempdir.path()).unwrap());
+        });
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fs2/src/unix.rs
@@ -0,0 +1,250 @@
+extern crate libc;
+
+use std::ffi::CString;
+use std::fs::File;
+use std::io::{Error, ErrorKind, Result};
+use std::mem;
+use std::os::unix::ffi::OsStrExt;
+use std::os::unix::fs::MetadataExt;
+use std::os::unix::io::{AsRawFd, FromRawFd};
+use std::path::Path;
+
+use FsStats;
+
+pub fn duplicate(file: &File) -> Result<File> {
+    unsafe {
+        let fd = libc::dup(file.as_raw_fd());
+
+        if fd < 0 {
+            Err(Error::last_os_error())
+        } else {
+            Ok(File::from_raw_fd(fd))
+        }
+    }
+}
+
+pub fn lock_shared(file: &File) -> Result<()> {
+    flock(file, libc::LOCK_SH)
+}
+
+pub fn lock_exclusive(file: &File) -> Result<()> {
+    flock(file, libc::LOCK_EX)
+}
+
+pub fn try_lock_shared(file: &File) -> Result<()> {
+    flock(file, libc::LOCK_SH | libc::LOCK_NB)
+}
+
+pub fn try_lock_exclusive(file: &File) -> Result<()> {
+    flock(file, libc::LOCK_EX | libc::LOCK_NB)
+}
+
+pub fn unlock(file: &File) -> Result<()> {
+    flock(file, libc::LOCK_UN)
+}
+
+pub fn lock_error() -> Error {
+    Error::from_raw_os_error(libc::EWOULDBLOCK)
+}
+
+#[cfg(not(target_os = "solaris"))]
+fn flock(file: &File, flag: libc::c_int) -> Result<()> {
+    let ret = unsafe { libc::flock(file.as_raw_fd(), flag) };
+    if ret < 0 { Err(Error::last_os_error()) } else { Ok(()) }
+}
+
+/// Simulate flock() using fcntl(); primarily for Oracle Solaris.
+#[cfg(target_os = "solaris")]
+fn flock(file: &File, flag: libc::c_int) -> Result<()> {
+    let mut fl = libc::flock {
+        l_whence: 0,
+        l_start: 0,
+        l_len: 0,
+        l_type: 0,
+        l_pad: [0; 4],
+        l_pid: 0,
+        l_sysid: 0,
+    };
+
+    // In non-blocking mode, use F_SETLK for cmd, F_SETLKW otherwise, and don't forget to clear
+    // LOCK_NB.
+    let (cmd, operation) = match flag & libc::LOCK_NB {
+        0 => (libc::F_SETLKW, flag),
+        _ => (libc::F_SETLK, flag & !libc::LOCK_NB),
+    };
+
+    match operation {
+        libc::LOCK_SH => fl.l_type |= libc::F_RDLCK,
+        libc::LOCK_EX => fl.l_type |= libc::F_WRLCK,
+        libc::LOCK_UN => fl.l_type |= libc::F_UNLCK,
+        _ => return Err(Error::from_raw_os_error(libc::EINVAL)),
+    }
+
+    let ret = unsafe { libc::fcntl(file.as_raw_fd(), cmd, &fl) };
+    match ret {
+        // Translate EACCES to EWOULDBLOCK
+        -1 => match Error::last_os_error().raw_os_error() {
+            Some(libc::EACCES) => return Err(lock_error()),
+            _ => return Err(Error::last_os_error())
+        },
+        _ => Ok(())
+    }
+}
+
+pub fn allocated_size(file: &File) -> Result<u64> {
+    file.metadata().map(|m| m.blocks() as u64 * 512)
+}
+
+#[cfg(any(target_os = "linux",
+          target_os = "freebsd",
+          target_os = "android",
+          target_os = "nacl"))]
+pub fn allocate(file: &File, len: u64) -> Result<()> {
+    let ret = unsafe { libc::posix_fallocate(file.as_raw_fd(), 0, len as libc::off_t) };
+    if ret == 0 { Ok(()) } else { Err(Error::last_os_error()) }
+}
+
+#[cfg(any(target_os = "macos", target_os = "ios"))]
+pub fn allocate(file: &File, len: u64) -> Result<()> {
+    let stat = try!(file.metadata());
+
+    if len > stat.blocks() as u64 * 512 {
+        let mut fstore = libc::fstore_t {
+            fst_flags: libc::F_ALLOCATECONTIG,
+            fst_posmode: libc::F_PEOFPOSMODE,
+            fst_offset: 0,
+            fst_length: len as libc::off_t,
+            fst_bytesalloc: 0,
+        };
+
+        let ret = unsafe { libc::fcntl(file.as_raw_fd(), libc::F_PREALLOCATE, &fstore) };
+        if ret == -1 {
+            // Unable to allocate contiguous disk space; attempt to allocate non-contiguously.
+            fstore.fst_flags = libc::F_ALLOCATEALL;
+            let ret = unsafe { libc::fcntl(file.as_raw_fd(), libc::F_PREALLOCATE, &fstore) };
+            if ret == -1 {
+                return Err(Error::last_os_error());
+            }
+        }
+    }
+
+    if len > stat.size() as u64 {
+        file.set_len(len)
+    } else {
+        Ok(())
+    }
+}
+
+#[cfg(any(target_os = "openbsd",
+          target_os = "netbsd",
+          target_os = "dragonfly",
+          target_os = "solaris",
+          target_os = "haiku"))]
+pub fn allocate(file: &File, len: u64) -> Result<()> {
+    // No file allocation API available, just set the length if necessary.
+    if len > try!(file.metadata()).len() as u64 {
+        file.set_len(len)
+    } else {
+        Ok(())
+    }
+}
+
+pub fn statvfs(path: &Path) -> Result<FsStats> {
+    let cstr = match CString::new(path.as_os_str().as_bytes()) {
+        Ok(cstr) => cstr,
+        Err(..) => return Err(Error::new(ErrorKind::InvalidInput, "path contained a null")),
+    };
+
+    unsafe {
+        let mut stat: libc::statvfs = mem::zeroed();
+        // danburkert/fs2-rs#1: cast is necessary for platforms where c_char != u8.
+        if libc::statvfs(cstr.as_ptr() as *const _, &mut stat) != 0 {
+            Err(Error::last_os_error())
+        } else {
+            Ok(FsStats {
+                free_space: stat.f_frsize as u64 * stat.f_bfree as u64,
+                available_space: stat.f_frsize as u64 * stat.f_bavail as u64,
+                total_space: stat.f_frsize as u64 * stat.f_blocks as u64,
+                allocation_granularity: stat.f_frsize as u64,
+            })
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    extern crate tempdir;
+    extern crate libc;
+
+    use std::fs::{self, File};
+    use std::os::unix::io::AsRawFd;
+
+    use {FileExt, lock_contended_error};
+
+    /// The duplicate method returns a file with a new file descriptor.
+    #[test]
+    fn duplicate_new_fd() {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("fs2");
+        let file1 = fs::OpenOptions::new().write(true).create(true).open(&path).unwrap();
+        let file2 = file1.duplicate().unwrap();
+        assert!(file1.as_raw_fd() != file2.as_raw_fd());
+    }
+
+    /// The duplicate method should preservesthe close on exec flag.
+    #[test]
+    fn duplicate_cloexec() {
+
+        fn flags(file: &File) -> libc::c_int {
+            unsafe { libc::fcntl(file.as_raw_fd(), libc::F_GETFL, 0) }
+        }
+
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("fs2");
+        let file1 = fs::OpenOptions::new().write(true).create(true).open(&path).unwrap();
+        let file2 = file1.duplicate().unwrap();
+
+        assert_eq!(flags(&file1), flags(&file2));
+    }
+
+    /// Tests that locking a file descriptor will replace any existing locks
+    /// held on the file descriptor.
+    #[test]
+    fn lock_replace() {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("fs2");
+        let file1 = fs::OpenOptions::new().write(true).create(true).open(&path).unwrap();
+        let file2 = fs::OpenOptions::new().write(true).create(true).open(&path).unwrap();
+
+        // Creating a shared lock will drop an exclusive lock.
+        file1.lock_exclusive().unwrap();
+        file1.lock_shared().unwrap();
+        file2.lock_shared().unwrap();
+
+        // Attempting to replace a shared lock with an exclusive lock will fail
+        // with multiple lock holders, and remove the original shared lock.
+        assert_eq!(file2.try_lock_exclusive().unwrap_err().raw_os_error(),
+                   lock_contended_error().raw_os_error());
+        file1.lock_shared().unwrap();
+    }
+
+    /// Tests that locks are shared among duplicated file descriptors.
+    #[test]
+    fn lock_duplicate() {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("fs2");
+        let file1 = fs::OpenOptions::new().write(true).create(true).open(&path).unwrap();
+        let file2 = file1.duplicate().unwrap();
+        let file3 = fs::OpenOptions::new().write(true).create(true).open(&path).unwrap();
+
+        // Create a lock through fd1, then replace it through fd2.
+        file1.lock_shared().unwrap();
+        file2.lock_exclusive().unwrap();
+        assert_eq!(file3.try_lock_shared().unwrap_err().raw_os_error(),
+                   lock_contended_error().raw_os_error());
+
+        // Either of the file descriptors should be able to unlock.
+        file1.unlock().unwrap();
+        file3.lock_shared().unwrap();
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/fs2/src/windows.rs
@@ -0,0 +1,271 @@
+extern crate kernel32;
+extern crate winapi;
+
+use std::fs::File;
+use std::io::{Error, Result};
+use std::mem;
+use std::os::windows::ffi::OsStrExt;
+use std::os::windows::io::{AsRawHandle, FromRawHandle};
+use std::path::Path;
+use std::ptr;
+
+use FsStats;
+
+pub fn duplicate(file: &File) -> Result<File> {
+    unsafe {
+        let mut handle = ptr::null_mut();
+        let current_process = kernel32::GetCurrentProcess();
+        let ret = kernel32::DuplicateHandle(current_process,
+                                            file.as_raw_handle(),
+                                            current_process,
+                                            &mut handle,
+                                            0,
+                                            true as winapi::BOOL,
+                                            winapi::DUPLICATE_SAME_ACCESS);
+        if ret == 0 {
+            Err(Error::last_os_error())
+        } else {
+            Ok(File::from_raw_handle(handle))
+        }
+    }
+}
+
+pub fn allocated_size(file: &File) -> Result<u64> {
+    unsafe {
+        let mut info: winapi::FILE_STANDARD_INFO = mem::zeroed();
+
+        let ret = kernel32::GetFileInformationByHandleEx(
+            file.as_raw_handle(),
+            winapi::FileStandardInfo,
+            &mut info as *mut _ as *mut _,
+            mem::size_of::<winapi::FILE_STANDARD_INFO>() as winapi::DWORD);
+
+        if ret == 0 {
+            Err(Error::last_os_error())
+        } else {
+            Ok(info.AllocationSize as u64)
+        }
+    }
+}
+
+pub fn allocate(file: &File, len: u64) -> Result<()> {
+    if try!(allocated_size(file)) < len {
+        unsafe {
+            let mut info: winapi::FILE_ALLOCATION_INFO = mem::zeroed();
+            info.AllocationSize = len as i64;
+            let ret = kernel32::SetFileInformationByHandle(
+                file.as_raw_handle(),
+                winapi::FileAllocationInfo,
+                &mut info as *mut _ as *mut _,
+                mem::size_of::<winapi::FILE_ALLOCATION_INFO>() as winapi::DWORD);
+            if ret == 0 {
+                return Err(Error::last_os_error());
+            }
+        }
+    }
+    if try!(file.metadata()).len() < len {
+        file.set_len(len)
+    } else {
+        Ok(())
+    }
+}
+
+pub fn lock_shared(file: &File) -> Result<()> {
+    lock_file(file, 0)
+}
+
+pub fn lock_exclusive(file: &File) -> Result<()> {
+    lock_file(file, winapi::LOCKFILE_EXCLUSIVE_LOCK)
+}
+
+pub fn try_lock_shared(file: &File) -> Result<()> {
+    lock_file(file, winapi::LOCKFILE_FAIL_IMMEDIATELY)
+}
+
+pub fn try_lock_exclusive(file: &File) -> Result<()> {
+    lock_file(file, winapi::LOCKFILE_EXCLUSIVE_LOCK | winapi::LOCKFILE_FAIL_IMMEDIATELY)
+}
+
+pub fn unlock(file: &File) -> Result<()> {
+    unsafe {
+        let ret = kernel32::UnlockFile(file.as_raw_handle(), 0, 0, !0, !0);
+        if ret == 0 { Err(Error::last_os_error()) } else { Ok(()) }
+    }
+}
+
+pub fn lock_error() -> Error {
+    Error::from_raw_os_error(winapi::ERROR_LOCK_VIOLATION as i32)
+}
+
+fn lock_file(file: &File, flags: winapi::DWORD) -> Result<()> {
+    unsafe {
+        let mut overlapped = mem::zeroed();
+        let ret = kernel32::LockFileEx(file.as_raw_handle(), flags, 0, !0, !0, &mut overlapped);
+        if ret == 0 { Err(Error::last_os_error()) } else { Ok(()) }
+    }
+}
+
+fn volume_path(path: &Path, volume_path: &mut [u16]) -> Result<()> {
+    let path_utf8: Vec<u16> = path.as_os_str().encode_wide().chain(Some(0)).collect();
+    unsafe {
+        let ret = kernel32::GetVolumePathNameW(path_utf8.as_ptr(),
+                                               volume_path.as_mut_ptr(),
+                                               volume_path.len() as winapi::DWORD);
+        if ret == 0 { Err(Error::last_os_error()) } else { Ok(())
+        }
+    }
+}
+
+pub fn statvfs(path: &Path) -> Result<FsStats> {
+    let root_path: &mut [u16] = &mut [0; 261];
+    try!(volume_path(path, root_path));
+    unsafe {
+
+        let mut sectors_per_cluster = 0;
+        let mut bytes_per_sector = 0;
+        let mut number_of_free_clusters = 0;
+        let mut total_number_of_clusters = 0;
+        let ret = kernel32::GetDiskFreeSpaceW(root_path.as_ptr(),
+                                              &mut sectors_per_cluster,
+                                              &mut bytes_per_sector,
+                                              &mut number_of_free_clusters,
+                                              &mut total_number_of_clusters);
+        if ret == 0 {
+            Err(Error::last_os_error())
+        } else {
+            let bytes_per_cluster = sectors_per_cluster as u64 * bytes_per_sector as u64;
+            let free_space = bytes_per_cluster * number_of_free_clusters as u64;
+            let total_space = bytes_per_cluster * total_number_of_clusters as u64;
+            Ok(FsStats {
+                free_space: free_space,
+                available_space: free_space,
+                total_space: total_space,
+                allocation_granularity: bytes_per_cluster,
+            })
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+
+    extern crate tempdir;
+
+    use std::fs;
+    use std::os::windows::io::AsRawHandle;
+
+    use {FileExt, lock_contended_error};
+
+    /// The duplicate method returns a file with a new file handle.
+    #[test]
+    fn duplicate_new_handle() {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("fs2");
+        let file1 = fs::OpenOptions::new().write(true).create(true).open(&path).unwrap();
+        let file2 = file1.duplicate().unwrap();
+        assert!(file1.as_raw_handle() != file2.as_raw_handle());
+    }
+
+    /// A duplicated file handle does not have access to the original handle's locks.
+    #[test]
+    fn lock_duplicate_handle_independence() {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("fs2");
+        let file1 = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap();
+        let file2 = file1.duplicate().unwrap();
+
+        // Locking the original file handle will block the duplicate file handle from opening a lock.
+        file1.lock_shared().unwrap();
+        assert_eq!(file2.try_lock_exclusive().unwrap_err().raw_os_error(),
+                   lock_contended_error().raw_os_error());
+
+        // Once the original file handle is unlocked, the duplicate handle can proceed with a lock.
+        file1.unlock().unwrap();
+        file2.lock_exclusive().unwrap();
+    }
+
+    /// A file handle may not be exclusively locked multiple times, or exclusively locked and then
+    /// shared locked.
+    #[test]
+    fn lock_non_reentrant() {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("fs2");
+        let file = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap();
+
+        // Multiple exclusive locks fails.
+        file.lock_exclusive().unwrap();
+        assert_eq!(file.try_lock_exclusive().unwrap_err().raw_os_error(),
+                   lock_contended_error().raw_os_error());
+        file.unlock().unwrap();
+
+        // Shared then Exclusive locks fails.
+        file.lock_shared().unwrap();
+        assert_eq!(file.try_lock_exclusive().unwrap_err().raw_os_error(),
+                   lock_contended_error().raw_os_error());
+    }
+
+    /// A file handle can hold an exclusive lock and any number of shared locks, all of which must
+    /// be unlocked independently.
+    #[test]
+    fn lock_layering() {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("fs2");
+        let file = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap();
+
+        // Open two shared locks on the file, and then try and fail to open an exclusive lock.
+        file.lock_exclusive().unwrap();
+        file.lock_shared().unwrap();
+        file.lock_shared().unwrap();
+        assert_eq!(file.try_lock_exclusive().unwrap_err().raw_os_error(),
+                   lock_contended_error().raw_os_error());
+
+        // Pop one of the shared locks and try again.
+        file.unlock().unwrap();
+        assert_eq!(file.try_lock_exclusive().unwrap_err().raw_os_error(),
+                   lock_contended_error().raw_os_error());
+
+        // Pop the second shared lock and try again.
+        file.unlock().unwrap();
+        assert_eq!(file.try_lock_exclusive().unwrap_err().raw_os_error(),
+                   lock_contended_error().raw_os_error());
+
+        // Pop the exclusive lock and finally succeed.
+        file.unlock().unwrap();
+        file.lock_exclusive().unwrap();
+    }
+
+    /// A file handle with multiple open locks will have all locks closed on drop.
+    #[test]
+    fn lock_layering_cleanup() {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("fs2");
+        let file1 = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap();
+        let file2 = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap();
+
+        // Open two shared locks on the file, and then try and fail to open an exclusive lock.
+        file1.lock_shared().unwrap();
+        assert_eq!(file2.try_lock_exclusive().unwrap_err().raw_os_error(),
+                   lock_contended_error().raw_os_error());
+
+        drop(file1);
+        file2.lock_exclusive().unwrap();
+    }
+
+    /// A file handle's locks will not be released until the original handle and all of its
+    /// duplicates have been closed. This on really smells like a bug in Windows.
+    #[test]
+    fn lock_duplicate_cleanup() {
+        let tempdir = tempdir::TempDir::new("fs2").unwrap();
+        let path = tempdir.path().join("fs2");
+        let file1 = fs::OpenOptions::new().read(true).write(true).create(true).open(&path).unwrap();
+        let file2 = file1.duplicate().unwrap();
+
+        // Open a lock on the original handle, then close it.
+        file1.lock_shared().unwrap();
+        drop(file1);
+
+        // Attempting to create a lock on the file with the duplicate handle will fail.
+        assert_eq!(file2.try_lock_exclusive().unwrap_err().raw_os_error(),
+                   lock_contended_error().raw_os_error());
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/iovec/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"647d4a5498a3bef693b45603933e604b6ccf7aba8823a33b764ca1833797768b","Cargo.toml":"1c82b292358c72b779205f71efaef3fa343b42143e2cd1845fc44ffd95527a77","LICENSE-APACHE":"01b5abb4a95cc87b220efbd67a1e99c74bef3d744806dd44b4d57e81db814962","LICENSE-MIT":"d4784f55731ba75b77ad73a52808914b26b2f93b69dd4c03249528a75afbd946","README.md":"247302d4c1dc621f150bc06fc0d37f7ad5a4f2dcf1aafe25f8dfe8eb4fe35921","appveyor.yml":"8c309c2779904317005c7f7404470daf2aad344571168a37da214e37833be2a9","src/lib.rs":"aab60277edb10e3b93a5f1a307054fd78c263f3a597b5088e5d7280378c7b028","src/sys/mod.rs":"4c3765602032675d6d236a25b99c00f20515f7e86b7f8afa3148aeaaef58def1","src/sys/unix.rs":"bbf6c36a4a4d48342581ae6c17f8d7ef95d22f4958cf71193429ce53ec4555c2","src/sys/windows.rs":"f0690442f4842b0f0e8fc34739397f0dca8912fde424563d8540d954868f64c7","src/unix.rs":"76e76333e31dd53d1ea6704a880f4188014af09fe8be3cecd5239003b2a1fe7c","src/windows.rs":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"},"package":"29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be"}
\ No newline at end of file
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/third_party/rust/iovec/.travis.yml
@@ -0,0 +1,24 @@
+---
+language: rust
+sudo: false
+
+rust:
+  - stable
+
+os:
+  - linux
+  - osx
+
+matrix:
+  include:
+    - os: linux
+      # Oldest supported Rust (this should track Mio)
+      rust: 1.9.0
+
+script:
+  - cargo build
+  - cargo test
+
+notifications:
+  email:
+    on_success: never
new file mode 100644
--- /dev/null
+++ b/third_party/rust/iovec/Cargo.toml
@@ -0,0 +1,20 @@
+[package]
+name = "iovec"
+version = "0.1.0"
+authors = ["Carl Lerche <me@carllerche.com>"]
+license = "MIT/Apache-2.0"
+readme = "README.md"
+keywords = ["scatter", "gather", "vectored", "io", "networking"]
+repository = "https://github.com/carllerche/iovec"
+homepage = "https://github.com/carllerche/iovec"
+documentation = "https://docs.rs/iovec"
+description = """
+Portable buffer type for scatter/gather I/O operations
+"""
+categories = ["network-programming", "api-bindings"]
+
+[target.'cfg(unix)'.dependencies]
+libc   = "0.2"
+
+[target.'cfg(windows)'.dependencies]
+winapi = "0.2"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/iovec/LICENSE-APACHE
@@ -0,0 +1,201 @@
+                              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 2017 Carl Lerche
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+	http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/iovec/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2017 Carl Lerche
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/iovec/README.md
@@ -0,0 +1,35 @@
+# IoVec
+
+A specialized byte slice type for performing vectored I/O operations.
+
+[![Crates.io](https://img.shields.io/crates/v/iovec.svg?maxAge=2592000)](https://crates.io/crates/iovec)
+[![Build Status](https://travis-ci.org/carllerche/iovec.svg?branch=master)](https://travis-ci.org/carllerche/iovec)
+
+[Documentation](https://docs.rs/iovec)
+
+## Usage
+
+To use `iovec`, first add this to your `Cargo.toml`:
+
+```toml
+[dependencies]
+iovec = "0.1"
+```
+
+Next, add this to your crate:
+
+```rust
+extern crate iovec;
+
+use iovec::IoVec;
+```
+
+For more detail, see [documentation](https://docs.rs/iovec).
+
+# License
+
+`iovec` is primarily distributed under the terms of both the MIT license and the
+Apache License (Version 2.0), with portions covered by various BSD-like
+licenses.
+
+See LICENSE-APACHE, and LICENSE-MIT for details.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/iovec/appveyor.yml
@@ -0,0 +1,16 @@
+environment:
+  matrix:
+  - TARGET: x86_64-pc-windows-msvc
+
+install:
+  - curl -sSf -o rustup-init.exe https://win.rustup.rs/
+  - rustup-init.exe -y --default-host %TARGET%
+  - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
+  - rustc -V
+  - cargo -V
+
+build: false
+
+test_script:
+  - cargo build
+  - cargo test
new file mode 100644
--- /dev/null
+++ b/third_party/rust/iovec/src/lib.rs
@@ -0,0 +1,134 @@
+//! A specialized byte slice type for performing vectored I/O operations.
+//!
+//! For more detail, see [`IoVec`] documentation.
+//!
+//! [`IoVec`]: struct.IoVec.html
+
+#[cfg(unix)]
+extern crate libc;
+
+#[cfg(windows)]
+extern crate winapi;
+
+mod sys;
+
+use std::{ops, mem};
+
+#[cfg(unix)]
+pub mod unix;
+
+/// Max length of an `IoVec` slice.
+///
+/// Attempts to convert slices longer than this value will result in a panic.
+pub const MAX_LENGTH: usize = sys::MAX_LENGTH;
+
+/// A specialized byte slice type for performing vectored I/O operations.
+///
+/// On all systems, the types needed to peform vectored I/O systems have the
+/// same size as Rust's [slice]. However, the layout is not necessarily the
+/// same. `IoVec` provides a portable compatibility layer.
+///
+/// The `IoVec` behaves like like a Rust [slice], providing the same functions.
+/// It also provides conversion functions to and from the OS specific vectored
+/// types.
+///
+/// # Examples
+///
+/// ```
+/// use iovec::IoVec;
+///
+/// let mut data = vec![];
+/// data.extend_from_slice(b"hello");
+///
+/// let iovec: &IoVec = data.as_slice().into();
+///
+/// assert_eq!(&iovec[..], &b"hello"[..]);
+/// ```
+///
+/// # Panics
+///
+/// Attempting to convert a slice longer than [`MAX_LENGTH`] to an `IoVec` will
+/// result in a panic.
+///
+/// [`MAX_LENGTH`]: constant.MAX_LENGTH.html
+pub struct IoVec {
+    sys: sys::IoVec,
+}
+
+impl IoVec {
+    #[deprecated(since = "0.1.0", note = "deref instead")]
+    #[doc(hidden)]
+    pub fn as_bytes(&self) -> &[u8] {
+        &**self
+    }
+
+    #[deprecated(since = "0.1.0", note = "deref instead")]
+    #[doc(hidden)]
+    pub fn as_mut_bytes(&mut self) -> &mut [u8] {
+        &mut **self
+    }
+}
+
+impl ops::Deref for IoVec {
+    type Target = [u8];
+
+    fn deref(&self) -> &[u8] {
+        &self.sys.as_ref()
+    }
+}
+
+impl ops::DerefMut for IoVec {
+    fn deref_mut(&mut self) -> &mut [u8] {
+        self.sys.as_mut()
+    }
+}
+
+impl<'a> From<&'a [u8]> for &'a IoVec {
+    fn from(bytes: &'a [u8]) -> &'a IoVec {
+        unsafe {
+            let iovec: &sys::IoVec = bytes.into();
+            mem::transmute(iovec)
+        }
+    }
+}
+
+impl<'a> From<&'a mut [u8]> for &'a mut IoVec {
+    fn from(bytes: &'a mut [u8]) -> &'a mut IoVec {
+        unsafe {
+            let iovec: &mut sys::IoVec = bytes.into();
+            mem::transmute(iovec)
+        }
+    }
+}
+
+impl<'a> Default for &'a IoVec {
+    fn default() -> Self {
+        let b: &[u8] = Default::default();
+        b.into()
+    }
+}
+
+impl<'a> Default for &'a mut IoVec {
+    fn default() -> Self {
+        let b: &mut [u8] = Default::default();
+        b.into()
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::IoVec;
+
+    #[test]
+    fn convert_ref() {
+        let buf: &IoVec = (&b"hello world"[..]).into();
+        assert_eq!(buf[..], b"hello world"[..]);
+    }
+
+    #[test]
+    fn convert_mut() {
+        let mut buf: Vec<u8> = b"hello world".to_vec();
+        let buf: &mut IoVec = (&mut buf[..]).into();
+        assert_eq!(buf[..], b"hello world"[..]);
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/iovec/src/sys/mod.rs
@@ -0,0 +1,17 @@
+#[cfg(unix)]
+mod unix;
+
+#[cfg(unix)]
+pub use self::unix::{
+    IoVec,
+    MAX_LENGTH,
+};
+
+#[cfg(windows)]
+mod windows;
+
+#[cfg(windows)]
+pub use self::windows::{
+    IoVec,
+    MAX_LENGTH,
+};
new file mode 100644
--- /dev/null
+++ b/third_party/rust/iovec/src/sys/unix.rs
@@ -0,0 +1,50 @@
+use libc;
+use std::{mem, slice, usize};
+
+pub struct IoVec {
+    inner: [u8],
+}
+
+pub const MAX_LENGTH: usize = usize::MAX;
+
+impl IoVec {
+    pub fn as_ref(&self) -> &[u8] {
+        unsafe {
+            let vec = self.iovec();
+            slice::from_raw_parts(vec.iov_base as *const u8, vec.iov_len)
+        }
+    }
+
+    pub fn as_mut(&mut self) -> &mut [u8] {
+        unsafe {
+            let vec = self.iovec();
+            slice::from_raw_parts_mut(vec.iov_base as *mut u8, vec.iov_len)
+        }
+    }
+
+    unsafe fn iovec(&self) -> libc::iovec {
+        mem::transmute(&self.inner)
+    }
+}
+
+impl<'a> From<&'a [u8]> for &'a IoVec {
+    fn from(src: &'a [u8]) -> Self {
+        unsafe {
+            mem::transmute(libc::iovec {
+                iov_base: src.as_ptr() as *mut _,
+                iov_len: src.len(),
+            })
+        }
+    }
+}
+
+impl<'a> From<&'a mut [u8]> for &'a mut IoVec {
+    fn from(src: &'a mut [u8]) -> Self {
+        unsafe {
+            mem::transmute(libc::iovec {
+                iov_base: src.as_ptr() as *mut _,
+                iov_len: src.len(),
+            })
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/iovec/src/sys/windows.rs
@@ -0,0 +1,54 @@
+use winapi::{WSABUF, DWORD};
+use std::{mem, slice, u32};
+
+pub struct IoVec {
+    inner: [u8],
+}
+
+pub const MAX_LENGTH: usize = u32::MAX as usize;
+
+impl IoVec {
+    pub fn as_ref(&self) -> &[u8] {
+        unsafe {
+            let vec = self.wsabuf();
+            slice::from_raw_parts(vec.buf as *const u8, vec.len as usize)
+        }
+    }
+
+    pub fn as_mut(&mut self) -> &mut [u8] {
+        unsafe {
+            let vec = self.wsabuf();
+            slice::from_raw_parts_mut(vec.buf as *mut u8, vec.len as usize)
+        }
+    }
+
+    unsafe fn wsabuf(&self) -> WSABUF {
+        mem::transmute(&self.inner)
+    }
+}
+
+impl<'a> From<&'a [u8]> for &'a IoVec {
+    fn from(src: &'a [u8]) -> Self {
+        assert!(src.len() <= MAX_LENGTH);
+
+        unsafe {
+            mem::transmute(WSABUF {
+                buf: src.as_ptr() as *mut _,
+                len: src.len() as DWORD,
+            })
+        }
+    }
+}
+
+impl<'a> From<&'a mut [u8]> for &'a mut IoVec {
+    fn from(src: &'a mut [u8]) -> Self {
+        assert!(src.len() <= MAX_LENGTH);
+
+        unsafe {
+            mem::transmute(WSABUF {
+                buf: src.as_ptr() as *mut _,
+                len: src.len() as DWORD,
+            })
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/iovec/src/unix.rs
@@ -0,0 +1,68 @@
+//! IoVec extensions for Unix platforms.
+//!
+//! These functions provide conversions to unix specific representations of the
+//! vectored data.
+//!
+//! # Examples
+//!
+//! ```
+//! use iovec::IoVec;
+//! use iovec::unix;
+//!
+//! let a = b"hello".to_vec();
+//! let b = b"world".to_vec();
+//!
+//! let bufs: &[&IoVec] = &[(&a[..]).into(), (&b[..]).into()];
+//! let os_bufs = unix::as_os_slice(&bufs[..]);
+//!
+//! // Use the `os_bufs` slice with `writev`.
+//! ```
+
+use IoVec;
+use libc;
+
+use std::mem;
+
+/// Convert a slice of `IoVec` refs to a slice of `libc::iovec`.
+///
+/// The return value can be passed to `writev` bindings.
+///
+/// # Examples
+///
+/// ```
+/// use iovec::IoVec;
+/// use iovec::unix;
+///
+/// let a = b"hello".to_vec();
+/// let b = b"world".to_vec();
+///
+/// let bufs: &[&IoVec] = &[a[..].into(), b[..].into()];
+/// let os_bufs = unix::as_os_slice(bufs);
+///
+/// // Use the `os_bufs` slice with `writev`.
+/// ```
+pub fn as_os_slice<'a>(iov: &'a [&IoVec]) -> &'a [libc::iovec] {
+    unsafe { mem::transmute(iov) }
+}
+
+/// Convert a mutable slice of `IoVec` refs to a mutable slice of `libc::iovec`.
+///
+/// The return value can be passed to `readv` bindings.
+///
+/// # Examples
+///
+/// ```
+/// use iovec::IoVec;
+/// use iovec::unix;
+///
+/// let mut a = [0; 10];
+/// let mut b = [0; 10];
+///
+/// let bufs: &mut [&mut IoVec] = &mut [(&mut a[..]).into(), (&mut b[..]).into()];
+/// let os_bufs = unix::as_os_slice_mut(bufs);
+///
+/// // Use the `os_bufs` slice with `readv`.
+/// ```
+pub fn as_os_slice_mut<'a>(iov: &'a mut [&mut IoVec]) -> &'a mut [libc::iovec] {
+    unsafe { mem::transmute(iov) }
+}
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/third_party/rust/lazycell/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","CHANGELOG.md":"a8defced70d220e04f77271ccced7e207d4e1417ed5e512b3dd4c8f9979e6a52","Cargo.toml":"46631e96c028ae56b797ec10524d6d9912fdd9857c3bea82957b1c394050b224","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6fc4fe1f402475d5c3f6e1b5c35407c5f489daa58bf8bb085d231909b5fac666","README.md":"fb8373bbd59d2885e119bdacf25898e0e3b98d4a97ea840c62cf967db28c61a2","src/lib.rs":"efcff18d06fdcc4bca2ead19e41b33dbc83f9c7d1591cd98206f657dad704580"},"package":"ce12306c4739d86ee97c23139f3a34ddf0387bbf181bc7929d287025a8c3ef6b"}
\ No newline at end of file
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/third_party/rust/lazycell/CHANGELOG.md
@@ -0,0 +1,80 @@
+<a name="v0.4.0"></a>
+##  (2016-08-17)
+
+
+#### Breaking Changes
+
+* **LazyCell:**  return Err(value) on full cell ([68f3415d](https://github.com/indiv0/lazycell/commit/68f3415dd5d6a66ba047a133b7028ebe4f1c5070), breaks [#](https://github.com/indiv0/lazycell/issues/))
+
+#### Improvements
+
+* **LazyCell:**  return Err(value) on full cell ([68f3415d](https://github.com/indiv0/lazycell/commit/68f3415dd5d6a66ba047a133b7028ebe4f1c5070), breaks [#](https://github.com/indiv0/lazycell/issues/))
+
+
+
+<a name="v0.3.0"></a>
+##  (2016-08-16)
+
+
+#### Features
+
+*   add AtomicLazyCell which is thread-safe ([85afbd36](https://github.com/indiv0/lazycell/commit/85afbd36d8a148e14cc53654b39ddb523980124d))
+
+#### Improvements
+
+*   Use UnsafeCell instead of RefCell ([3347a8e9](https://github.com/indiv0/lazycell/commit/3347a8e97d2215a47e25c1e2fc953e8052ad8eb6))
+
+
+
+<a name="v0.2.1"></a>
+##  (2016-04-18)
+
+
+#### Documentation
+
+*   put types in between backticks ([607cf939](https://github.com/indiv0/lazycell/commit/607cf939b05e35001ba3070ec7a0b17b064e7be1))
+
+
+
+<a name="v0.2.0"></a>
+## v0.2.0 (2016-03-28)
+
+
+#### Features
+
+* **lazycell:**
+  *  add tests for `LazyCell` struct ([38f1313d](https://github.com/indiv0/lazycell/commit/38f1313d98542ca8c98b424edfa9ba9c3975f99e), closes [#30](https://github.com/indiv0/lazycell/issues/30))
+  *  remove unnecessary `Default` impl ([68c16d2d](https://github.com/indiv0/lazycell/commit/68c16d2df4e9d13d5298162c06edf918246fd758))
+
+#### Documentation
+
+* **CHANGELOG:**  removed unnecessary sections ([1cc0555d](https://github.com/indiv0/lazycell/commit/1cc0555d875898a01b0832ff967aed6b40e720eb))
+* **README:**  add link to documentation ([c8dc33f0](https://github.com/indiv0/lazycell/commit/c8dc33f01f2c0dc187f59ee53a2b73081053012b), closes [#13](https://github.com/indiv0/lazycell/issues/13))
+
+
+
+<a name="v0.1.0"></a>
+## v0.1.0 (2016-03-16)
+
+
+#### Features
+
+* **lib.rs:**  implement Default trait for LazyCell ([150a6304](https://github.com/indiv0/LazyCell/commit/150a6304a230ee1de8424e49c447ec1b2d6578ce))
+
+
+
+<a name="v0.0.1"></a>
+## v0.0.1 (2016-03-16)
+
+
+#### Bug Fixes
+
+* **Cargo.toml:**  loosen restrictions on Clippy version ([84dd8f96](https://github.com/indiv0/LazyCell/commit/84dd8f960000294f9dad47d776a41b98ed812981))
+
+#### Features
+
+*   add initial implementation ([4b39764a](https://github.com/indiv0/LazyCell/commit/4b39764a575bcb701dbd8047b966f72720fd18a4))
+*   add initial commit ([a80407a9](https://github.com/indiv0/LazyCell/commit/a80407a907ef7c9401f120104663172f6965521a))
+
+
+
new file mode 100644
--- /dev/null
+++ b/third_party/rust/lazycell/Cargo.toml
@@ -0,0 +1,26 @@
+[package]
+name = "lazycell"
+version = "0.4.0"
+authors = ["Alex Crichton <alex@alexcrichton.com>",
+           "Nikita Pekin <contact@nikitapek.in>"]
+description = "A library providing a lazily filled Cell struct"
+repository = "https://github.com/indiv0/lazycell"
+documentation = "http://indiv0.github.io/lazycell/lazycell/"
+readme = "README.md"
+keywords = ["lazycell", "lazy", "cell", "library"]
+license = "MIT/Apache-2.0"
+include = [
+    "CHANGELOG.md",
+    "Cargo.toml",
+    "LICENSE-MIT",
+    "LICENSE-APACHE",
+    "README.md",
+    "src/**/*.rs",
+]
+
+[dependencies]
+clippy = { version = "0.0", optional = true }
+
+[features]
+nightly = []
+nightly-testing = ["clippy", "nightly"]
new file mode 100644
--- /dev/null
+++ b/third_party/rust/lazycell/LICENSE-APACHE
@@ -0,0 +1,201 @@
+                              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.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/lazycell/LICENSE-MIT
@@ -0,0 +1,26 @@
+Original work Copyright (c) 2014 The Rust Project Developers
+Modified work Copyright (c) 2016 Nikita Pekin and lazycell contributors
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/lazycell/README.md
@@ -0,0 +1,76 @@
+# lazycell
+
+<table>
+    <tr>
+        <td><strong>Linux / OS X</strong></td>
+        <td><a href="https://travis-ci.org/indiv0/lazycell" title="Travis Build Status"><img src="https://travis-ci.org/indiv0/lazycell.svg?branch=master" alt="travis-badge"></img></a></td>
+    </tr>
+    <tr>
+        <td><strong>Windows</strong></td>
+        <td><a href="https://ci.appveyor.com/project/indiv0/lazycell" title="Appveyor Build Status"><img src="https://ci.appveyor.com/api/projects/status/8sql0kict385l3cy?svg=true" alt="appveyor-badge"></img></a></td>
+    </tr>
+    <tr>
+        <td colspan="2">
+            <a href="https://indiv0.github.io/lazycell/lazycell" title="API Docs"><img src="https://img.shields.io/badge/API-docs-blue.svg" alt="api-docs-badge"></img></a>
+            <a href="https://crates.io/crates/lazycell" title="Crates.io"><img src="https://img.shields.io/crates/v/lazycell.svg" alt="crates-io"></img></a>
+            <a href="#license" title="License: MIT/Apache-2.0"><img src="https://img.shields.io/crates/l/lazycell.svg" alt="license-badge"></img></a>
+            <a href="https://coveralls.io/github/indiv0/lazycell?branch=master" title="Coverage Status"><img src="https://coveralls.io/repos/github/indiv0/lazycell/badge.svg?branch=master" alt="coveralls-badge"></img></a>
+        </td>
+    </tr>
+</table>
+
+Rust library providing a lazily filled Cell.
+
+# Table of Contents
+
+* [Usage](#usage)
+* [Contributing](#contributing)
+* [Credits](#credits)
+* [License](#license)
+
+## Usage
+
+Add the following to your `Cargo.toml`:
+
+```toml
+[dependencies]
+lazycell = "0.4"
+```
+
+And in your `lib.rs` or `main.rs`:
+
+```rust
+extern crate lazycell;
+```
+
+See the [API docs][api-docs] for information on using the crate in your library.
+
+## Contributing
+
+Contributions are always welcome!
+If you have an idea for something to add (code, documentation, tests, examples,
+etc.) feel free to give it a shot.
+
+Please read [CONTRIBUTING.md][contributing] before you start contributing.
+
+## Credits
+
+The LazyCell library is based originally on work by The Rust Project Developers
+for the project [crates.io][crates-io-repo].
+
+The list of contributors to this project can be found at
+[CONTRIBUTORS.md][contributors].
+
+## License
+
+LazyCell is distributed under the terms of both the MIT license and the Apache
+License (Version 2.0).
+
+See [LICENSE-APACHE][license-apache], and [LICENSE-MIT][license-mit] for details.
+
+[api-docs]: https://indiv0.github.io/lazycell/lazycell
+[contributing]: https://github.com/indiv0/lazycell/blob/master/CONTRIBUTING.md "Contribution Guide"
+[contributors]: https://github.com/indiv0/lazycell/blob/master/CONTRIBUTORS.md "List of Contributors"
+[crates-io-repo]: https://github.com/rust-lang/crates.io "rust-lang/crates.io: Source code for crates.io"
+[license-apache]: https://github.com/indiv0/lazycell/blob/master/LICENSE-APACHE "Apache-2.0 License"
+[license-mit]: https://github.com/indiv0/lazycell/blob/master/LICENSE-MIT "MIT License"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/lazycell/src/lib.rs
@@ -0,0 +1,234 @@
+// Original work Copyright (c) 2014 The Rust Project Developers
+// Modified work Copyright (c) 2016 Nikita Pekin and the lazycell contributors
+// See the README.md file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![deny(missing_docs)]
+#![cfg_attr(feature = "nightly", feature(plugin))]
+#![cfg_attr(feature = "clippy", plugin(clippy))]
+
+//! This crate provides a `LazyCell` struct which acts as a lazily filled
+//! `Cell`, but with frozen contents.
+//!
+//! With a `RefCell`, the inner contents cannot be borrowed for the lifetime of
+//! the entire object, but only of the borrows returned. A `LazyCell` is a
+//! variation on `RefCell` which allows borrows to be tied to the lifetime of
+//! the outer object.
+//!
+//! The limitation of a `LazyCell` is that after it is initialized, it can never
+//! be modified.
+//!
+//! # Example
+//!
+//! The following example shows a quick example of the basic functionality of
+//! `LazyCell`.
+//!
+//! ```
+//! use lazycell::LazyCell;
+//!
+//! let lazycell = LazyCell::new();
+//!
+//! assert_eq!(lazycell.borrow(), None);
+//! assert!(!lazycell.filled());
+//! lazycell.fill(1).ok();
+//! assert!(lazycell.filled());
+//! assert_eq!(lazycell.borrow(), Some(&1));
+//! assert_eq!(lazycell.into_inner(), Some(1));
+//! ```
+//!
+//! `AtomicLazyCell` is a variant that uses an atomic variable to manage
+//! coordination in a thread-safe fashion.
+
+use std::cell::UnsafeCell;
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+/// A lazily filled `Cell`, with frozen contents.
+pub struct LazyCell<T> {
+    inner: UnsafeCell<Option<T>>,
+}
+
+impl<T> LazyCell<T> {
+    /// Creates a new, empty, `LazyCell`.
+    pub fn new() -> LazyCell<T> {
+        LazyCell { inner: UnsafeCell::new(None) }
+    }
+
+    /// Put a value into this cell.
+    ///
+    /// This function will return Err(value) is the cell is already full.
+    pub fn fill(&self, t: T) -> Result<(), T> {
+        let mut slot = unsafe { &mut *self.inner.get() };
+        if slot.is_some() {
+	    return Err(t);
+        }
+        *slot = Some(t);
+
+	Ok(())
+    }
+
+    /// Test whether this cell has been previously filled.
+    pub fn filled(&self) -> bool {
+        self.borrow().is_some()
+    }
+
+    /// Borrows the contents of this lazy cell for the duration of the cell
+    /// itself.
+    ///
+    /// This function will return `Some` if the cell has been previously
+    /// initialized, and `None` if it has not yet been initialized.
+    pub fn borrow(&self) -> Option<&T> {
+        unsafe { &*self.inner.get() }.as_ref()
+    }
+
+    /// Consumes this `LazyCell`, returning the underlying value.
+    pub fn into_inner(self) -> Option<T> {
+        unsafe { self.inner.into_inner() }
+    }
+}
+
+// Tracks the AtomicLazyCell inner state
+const NONE: usize = 0;
+const LOCK: usize = 1;
+const SOME: usize = 2;
+
+/// A lazily filled `Cell`, with frozen contents.
+pub struct AtomicLazyCell<T> {
+    inner: UnsafeCell<Option<T>>,
+    state: AtomicUsize,
+}
+
+impl<T> AtomicLazyCell<T> {
+    /// Creates a new, empty, `AtomicLazyCell`.
+    pub fn new() -> AtomicLazyCell<T> {
+        AtomicLazyCell {
+            inner: UnsafeCell::new(None),
+            state: AtomicUsize::new(NONE),
+        }
+    }
+
+    /// Put a value into this cell.
+    ///
+    /// This function will return Err(value) is the cell is already full.
+    pub fn fill(&self, t: T) -> Result<(), T> {
+        if NONE != self.state.compare_and_swap(NONE, LOCK, Ordering::Acquire) {
+            return Err(t);
+        }
+
+        unsafe { *self.inner.get() = Some(t) };
+
+        if LOCK != self.state.compare_and_swap(LOCK, SOME, Ordering::Release) {
+            panic!("unable to release lock");
+        }
+
+        Ok(())
+    }
+
+    /// Test whether this cell has been previously filled.
+    pub fn filled(&self) -> bool {
+        self.state.load(Ordering::Acquire) == SOME
+    }
+
+    /// Borrows the contents of this lazy cell for the duration of the cell
+    /// itself.
+    ///
+    /// This function will return `Some` if the cell has been previously
+    /// initialized, and `None` if it has not yet been initialized.
+    pub fn borrow(&self) -> Option<&T> {
+        match self.state.load(Ordering::Acquire) {
+            SOME => unsafe { &*self.inner.get() }.as_ref(),
+            _ => None,
+        }
+    }
+
+    /// Consumes this `LazyCell`, returning the underlying value.
+    pub fn into_inner(self) -> Option<T> {
+        unsafe { self.inner.into_inner() }
+    }
+}
+
+unsafe impl<T: Sync> Sync for AtomicLazyCell<T> { }
+unsafe impl<T: Send> Send for AtomicLazyCell<T> { }
+
+#[cfg(test)]
+mod tests {
+    use super::{LazyCell, AtomicLazyCell};
+
+    #[test]
+    fn test_borrow_from_empty() {
+        let lazycell: LazyCell<usize> = LazyCell::new();
+
+        let value = lazycell.borrow();
+        assert_eq!(value, None);
+    }
+
+    #[test]
+    fn test_fill_and_borrow() {
+        let lazycell = LazyCell::new();
+
+        assert!(!lazycell.filled());
+        lazycell.fill(1).unwrap();
+        assert!(lazycell.filled());
+
+        let value = lazycell.borrow();
+        assert_eq!(value, Some(&1));
+    }
+
+    #[test]
+    fn test_already_filled_error() {
+        let lazycell = LazyCell::new();
+
+        lazycell.fill(1).unwrap();
+        assert_eq!(lazycell.fill(1), Err(1));
+    }
+
+    #[test]
+    fn test_into_inner() {
+        let lazycell = LazyCell::new();
+
+        lazycell.fill(1).unwrap();
+        let value = lazycell.into_inner();
+        assert_eq!(value, Some(1));
+    }
+
+    #[test]
+    fn test_atomic_borrow_from_empty() {
+        let lazycell: AtomicLazyCell<usize> = AtomicLazyCell::new();
+
+        let value = lazycell.borrow();
+        assert_eq!(value, None);
+    }
+
+    #[test]
+    fn test_atomic_fill_and_borrow() {
+        let lazycell = AtomicLazyCell::new();
+
+        assert!(!lazycell.filled());
+        lazycell.fill(1).unwrap();
+        assert!(lazycell.filled());
+
+        let value = lazycell.borrow();
+        assert_eq!(value, Some(&1));
+    }
+
+    #[test]
+    fn test_atomic_already_filled_panic() {
+        let lazycell = AtomicLazyCell::new();
+
+        lazycell.fill(1).unwrap();
+        assert_eq!(1, lazycell.fill(1).unwrap_err());
+    }
+
+    #[test]
+    fn test_atomic_into_inner() {
+        let lazycell = AtomicLazyCell::new();
+
+        lazycell.fill(1).unwrap();
+        let value = lazycell.into_inner();
+        assert_eq!(value, Some(1));
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/memmap/.appveyor.yml
@@ -0,0 +1,59 @@
+# Based on the "trust" template v0.1.1
+# https://github.com/japaric/trust/tree/v0.1.1
+
+environment:
+  global:
+  # TODO This is the Rust channel that build jobs will use by default but can be
+  # overridden on a case by case basis down below
+    RUST_VERSION: stable
+
+  # TODO These are all the build jobs. Adjust as necessary. Comment out what you
+  # don't need
+  matrix:
+    # MinGW
+    - TARGET: i686-pc-windows-gnu
+    - TARGET: x86_64-pc-windows-gnu
+
+    # MSVC
+    - TARGET: i686-pc-windows-msvc
+    - TARGET: x86_64-pc-windows-msvc
+
+    # Testing other channels
+    - TARGET: x86_64-pc-windows-gnu
+      RUST_VERSION: nightly
+    - TARGET: x86_64-pc-windows-msvc
+      RUST_VERSION: nightly
+
+install:
+  - ps: >-
+      If ($Env:TARGET -eq 'x86_64-pc-windows-gnu') {
+        $Env:PATH += ';C:\msys64\mingw64\bin'
+      } ElseIf ($Env:TARGET -eq 'i686-pc-windows-gnu') {
+        $Env:PATH += ';C:\msys64\mingw32\bin'
+      }
+  - curl -sSf -o rustup-init.exe https://win.rustup.rs/
+  - rustup-init.exe -y --default-host %TARGET% --default-toolchain %RUST_VERSION%
+  - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
+  - rustc -Vv
+  - cargo -V
+
+# TODO This is the "test phase", tweak it as you see fit
+test_script:
+  # we don't run the "test phase" when doing deploys
+  - if [%APPVEYOR_REPO_TAG%]==[false] (
+      cargo build --target %TARGET% &&
+      cargo build --target %TARGET% --release &&
+      cargo test --target %TARGET% &&
+      cargo test --target %TARGET% --release
+    )
+
+cache:
+  - C:\Users\appveyor\.cargo\registry
+  - target
+
+notifications:
+  - provider: Email
+    on_build_success: false
+
+# disable automatic builds
+build: false
new file mode 100644
--- /dev/null
+++ b/third_party/rust/memmap/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".appveyor.yml":"715ca44917107f2a6a79163b7ea2a1faa5f06d6f6ec01d18e0279cca0b2c9da3",".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"888f10c4e7364e7a299a4d3460410a8271b02c425e78c320528e1ecdea872b72","Cargo.toml":"0471662940a928f6b0304f44c0a9fded42f53d99f0a5392e6908745d216e61c3","LICENSE-APACHE":"04ea4849dba9dcae07113850c6f1b1a69052c625210639914eee352023f750ad","LICENSE-MIT":"bd1d8f06a6ce1f7645991e347b95864b970eed43624305eb4bb78c09aef8692d","README.md":"f60620f4edcbdfc29d752fe08c1bea6867daeefcf256e9e5db085cd6be72d89e","ci/install.sh":"8b165fc99df296261fcc9cdcbc8b8a177c11c505cdc9255cc19efb66cb0055db","ci/script.sh":"ad444efa1c26fbe8133c5c67448224569bf25fc64c2b8d6c301ab0ca23b8fc38","examples/cat.rs":"ee76408175b7a96776da063e975bdae217656392b59f84ba06e6775f1b561e93","src/lib.rs":"6e57576f52492cfb874063e07dcd34dc862b7e4ba1daeea02222e3b79260965c","src/unix.rs":"93547aa35e051f08d3f14ad985f5845b86a51ccdc0dbda6964c167d5c60d75ae","src/windows.rs":"645eb0f85fa26cc5d6af7095e303dd8d777b7df928cbdeccaeb9f424659ea091"},"package":"46f3c7359028b31999287dae4e5047ddfe90a23b7dca2282ce759b491080c99b"}
\ No newline at end of file
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/third_party/rust/memmap/.travis.yml
@@ -0,0 +1,69 @@
+# Based on the "trust" template v0.1.1
+# https://github.com/japaric/trust/tree/v0.1.1
+
+dist: trusty
+language: rust
+services: docker
+sudo: required
+
+rust: nightly
+env: TARGET=x86_64-unknown-linux-gnu
+
+matrix:
+  # TODO These are all the build jobs. Adjust as necessary. Comment out what you
+  # don't need
+  include:
+    # Linux
+    - env: TARGET=i686-unknown-linux-gnu
+    - env: TARGET=i686-unknown-linux-musl
+    # - env: TARGET=x86_64-unknown-linux-gnu  # this is the default job
+    - env: TARGET=x86_64-unknown-linux-musl
+
+    # OSX
+    - env: TARGET=i686-apple-darwin
+      os: osx
+    - env: TARGET=x86_64-apple-darwin
+      os: osx
+
+    # *BSD
+    - env: TARGET=i686-unknown-freebsd DISABLE_TESTS=1
+    - env: TARGET=x86_64-unknown-freebsd DISABLE_TESTS=1
+    - env: TARGET=x86_64-unknown-netbsd DISABLE_TESTS=1
+
+    # Other architectures
+    - env: TARGET=aarch64-unknown-linux-gnu
+    - env: TARGET=armv7-unknown-linux-gnueabihf
+    - env: TARGET=mips-unknown-linux-gnu
+    - env: TARGET=mips64-unknown-linux-gnuabi64
+    - env: TARGET=mips64el-unknown-linux-gnuabi64
+    - env: TARGET=mipsel-unknown-linux-gnu
+    - env: TARGET=powerpc-unknown-linux-gnu
+    - env: TARGET=powerpc64-unknown-linux-gnu
+    - env: TARGET=powerpc64le-unknown-linux-gnu
+    - env: TARGET=s390x-unknown-linux-gnu DISABLE_TESTS=1
+
+    # Testing other channels
+    - env: TARGET=x86_64-unknown-linux-gnu
+      rust: 1.8.0
+    - env: TARGET=x86_64-unknown-linux-gnu
+      rust: stable
+
+before_install: set -e
+
+install:
+  - sh ci/install.sh
+  - source ~/.cargo/env || true
+
+script:
+  - bash ci/script.sh
+
+after_script: set +e
+
+cache: cargo
+before_cache:
+  # Travis can't cache files that are not readable by "others"
+  - chmod -R a+r $HOME/.cargo
+
+notifications:
+  email:
+    on_success: never
new file mode 100644
--- /dev/null
+++ b/third_party/rust/memmap/Cargo.toml
@@ -0,0 +1,20 @@
+[package]
+name = "memmap"
+version = "0.5.2"
+authors = ["Dan Burkert <dan@danburkert.com>"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/danburkert/memmap-rs"
+documentation = "https://docs.rs/memmap"
+description = "Cross-platform Rust API for memory-mapped file IO"
+keywords = ["mmap", "memory-map", "io", "file"]
+
+[target.'cfg(unix)'.dependencies]
+libc = "0.2"
+
+[target.'cfg(windows)'.dependencies]
+winapi = "0.2"
+fs2 = "0.4"
+kernel32-sys = "0.2"
+
+[dev-dependencies]
+tempdir = "0.3"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/memmap/LICENSE-APACHE
@@ -0,0 +1,201 @@
+                              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 [2015] [Dan Burkert]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+	http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/memmap/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2015 Dan Burkert
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/memmap/README.md
@@ -0,0 +1,53 @@
+# memmap
+
+A Rust library for cross-platform memory-mapped file IO. `memmap` requires Rust
+stable 1.8 or greater.
+
+[Documentation](https://docs.rs/memmap)
+
+[![Linux Status](https://travis-ci.org/danburkert/memmap-rs.svg?branch=master)](https://travis-ci.org/danburkert/memmap-rs)
+[![Build status](https://ci.appveyor.com/api/projects/status/ubka00959pstatkg/branch/master?svg=true)](https://ci.appveyor.com/project/danburkert/mmap)
+
+## Features
+
+- [x] file-backed memory maps
+- [x] anonymous memory maps
+- [x] synchronous and asynchronous flushing
+- [x] copy-on-write memory maps
+- [x] read-only memory maps
+- [x] stack support (`MAP_STACK` on unix)
+- [x] executable memory maps
+- [ ] huge page support
+
+## Platforms
+
+`memmap` should work on any platform supported by
+[`libc`](https://github.com/rust-lang-nursery/libc#platforms-and-documentation).
+
+`memmap` is continuously tested on:
+  * `x86_64-unknown-linux-gnu` (Linux)
+  * `i686-unknown-linux-gnu`
+  * `x86_64-unknown-linux-musl` (Linux MUSL)
+  * `x86_64-apple-darwin` (OSX)
+  * `i686-apple-darwin`
+  * `x86_64-pc-windows-msvc` (Windows)
+  * `i686-pc-windows-msvc`
+  * `x86_64-pc-windows-gnu`
+  * `i686-pc-windows-gnu`
+
+`memmap` is continuously cross-compile against:
+  * `arm-linux-androideabi` (Android)
+  * `aarch64-unknown-linux-gnu` (ARM)
+  * `arm-unknown-linux-gnueabihf`
+  * `mips-unknown-linux-gnu` (MIPS)
+  * `x86_64-apple-ios` (iOS)
+  * `i686-apple-ios`
+
+## License
+
+`memmap` is primarily distributed under the terms of both the MIT license and the
+Apache License (Version 2.0).
+
+See [LICENSE-APACHE](LICENSE-APACHE), [LICENSE-MIT](LICENSE-MIT) for details.
+
+Copyright (c) 2015 Dan Burkert.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/memmap/ci/install.sh
@@ -0,0 +1,31 @@
+set -ex
+
+main() {
+    curl https://sh.rustup.rs -sSf | \
+        sh -s -- -y --default-toolchain $TRAVIS_RUST_VERSION
+
+    local target=
+    if [ $TRAVIS_OS_NAME = linux ]; then
+        target=x86_64-unknown-linux-gnu
+        sort=sort
+    else
+        target=x86_64-apple-darwin
+        sort=gsort  # for `sort --sort-version`, from brew's coreutils.
+    fi
+
+    # This fetches latest stable release
+    local tag=$(git ls-remote --tags --refs --exit-code https://github.com/japaric/cross \
+                       | cut -d/ -f3 \
+                       | grep -E '^v[0-9.]+$' \
+                       | $sort --version-sort \
+                       | tail -n1)
+    echo cross version: $tag
+    curl -LSfs https://japaric.github.io/trust/install.sh | \
+        sh -s -- \
+           --force \
+           --git japaric/cross \
+           --tag $tag \
+           --target $target
+}
+
+main
new file mode 100644
--- /dev/null
+++ b/third_party/rust/memmap/ci/script.sh
@@ -0,0 +1,21 @@
+# This script takes care of testing your crate
+
+set -ex
+
+# TODO This is the "test phase", tweak it as you see fit
+main() {
+    cross build --target $TARGET
+    cross build --target $TARGET --release
+
+    if [ ! -z $DISABLE_TESTS ]; then
+        return
+    fi
+
+    cross test --target $TARGET
+    cross test --target $TARGET --release
+}
+
+# we don't run the "test phase" when doing deploys
+if [ -z $TRAVIS_TAG ]; then
+    main
+fi
new file mode 100644
--- /dev/null
+++ b/third_party/rust/memmap/examples/cat.rs
@@ -0,0 +1,16 @@
+extern crate memmap;
+
+use std::env;
+use std::io::{self, Write};
+
+use memmap::{Mmap, Protection};
+
+/// Output a file's contents to stdout. The file path must be provided as the first process
+/// argument.
+fn main() {
+    let path = env::args().nth(1).expect("supply a single path as the program argument");
+
+    let mmap = Mmap::open_path(path, Protection::Read).unwrap();
+
+    io::stdout().write_all(unsafe { mmap.as_slice() }).unwrap();
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/memmap/src/lib.rs
@@ -0,0 +1,933 @@
+//! A cross-platform Rust API for memory maps.
+
+#![deny(warnings)]
+
+#[cfg(windows)]
+mod windows;
+#[cfg(windows)]
+use windows::MmapInner;
+
+#[cfg(unix)]
+mod unix;
+#[cfg(unix)]
+use unix::MmapInner;
+
+use std::cell::UnsafeCell;
+use std::fmt;
+use std::fs::{self, File};
+use std::io::{Error, ErrorKind, Result};
+use std::path::Path;
+use std::rc::Rc;
+use std::slice;
+use std::sync::Arc;
+use std::usize;
+
+/// Memory map protection.
+///
+/// Determines how a memory map may be used. If the memory map is backed by a
+/// file, then the file must have permissions corresponding to the operations
+/// the protection level allows.
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum Protection {
+
+    /// A read-only memory map. Writes to the memory map will result in a panic.
+    Read,
+
+    /// A read-write memory map. Writes to the memory map will be reflected in
+    /// the file after a call to `Mmap::flush` or after the `Mmap` is dropped.
+    ReadWrite,
+
+    /// A read, copy-on-write memory map. Writes to the memory map will not be
+    /// carried through to the underlying file. It is unspecified whether
+    /// changes made to the file after the memory map is created will be
+    /// visible.
+    ReadCopy,
+
+    /// A readable and executable mapping.
+    ReadExecute,
+}
+
+impl Protection {
+
+    fn as_open_options(self) -> fs::OpenOptions {
+        let mut options = fs::OpenOptions::new();
+        options.read(true)
+               .write(self.write());
+
+        options
+    }
+
+    /// Returns `true` if the `Protection` is writable.
+    pub fn write(self) -> bool {
+        match self {
+            Protection::ReadWrite | Protection::ReadCopy => true,
+            _ => false,
+        }
+    }
+}
+
+#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
+pub struct MmapOptions {
+    /// Indicates that the memory map should be suitable for a stack.
+    ///
+    /// This option should only be used with anonymous memory maps.
+    pub stack: bool,
+}
+
+/// A memory-mapped buffer.
+///
+/// A file-backed `Mmap` buffer may be used to read or write data to a file. Use
+/// `Mmap::open(..)` to create a file-backed memory map. An anonymous `Mmap`
+/// buffer may be used any place that an in-memory byte buffer is needed, and
+/// gives the added features of a memory map. Use `Mmap::anonymous(..)` to
+/// create an anonymous memory map.
+///
+/// Changes written to a memory-mapped file are not guaranteed to be durable
+/// until the memory map is flushed, or it is dropped.
+///
+/// ```
+/// use std::io::Write;
+/// use memmap::{Mmap, Protection};
+///
+/// let file_mmap = Mmap::open_path("README.md", Protection::Read).unwrap();
+/// let bytes: &[u8] = unsafe { file_mmap.as_slice() };
+/// assert_eq!(b"# memmap", &bytes[0..8]);
+///
+/// let mut anon_mmap = Mmap::anonymous(4096, Protection::ReadWrite).unwrap();
+/// unsafe { anon_mmap.as_mut_slice() }.write(b"foo").unwrap();
+/// assert_eq!(b"foo\0\0", unsafe { &anon_mmap.as_slice()[0..5] });
+/// ```
+pub struct Mmap {
+    inner: MmapInner
+}
+
+impl Mmap {
+
+    /// Opens a file-backed memory map.
+    ///
+    /// The file must be opened with read permissions, and write permissions if
+    /// the supplied protection is `ReadWrite`. The file must not be empty.
+    pub fn open(file: &File, prot: Protection) -> Result<Mmap> {
+        let len = try!(file.metadata()).len();
+        if len > usize::MAX as u64 {
+            return Err(Error::new(ErrorKind::InvalidData,
+                                  "file length overflows usize"));
+        }
+        MmapInner::open(file, prot, 0, len as usize).map(|inner| Mmap { inner: inner })
+    }
+
+    /// Opens a file-backed memory map.
+    ///
+    /// The file must not be empty.
+    pub fn open_path<P>(path: P, prot: Protection) -> Result<Mmap>
+    where P: AsRef<Path> {
+        let file = try!(prot.as_open_options().open(path));
+        let len = try!(file.metadata()).len();
+        if len > usize::MAX as u64 {
+            return Err(Error::new(ErrorKind::InvalidData,
+                                  "file length overflows usize"));
+        }
+        MmapInner::open(&file, prot, 0, len as usize).map(|inner| Mmap { inner: inner })
+    }
+
+    /// Opens a file-backed memory map with the specified offset and length.
+    ///
+    /// The file must be opened with read permissions, and write permissions if
+    /// the supplied protection is `ReadWrite`. The file must not be empty. The
+    /// length must be greater than zero.
+    pub fn open_with_offset(file: &File,
+                            prot: Protection,
+                            offset: usize,
+                            len: usize) -> Result<Mmap> {
+        MmapInner::open(file, prot, offset, len).map(|inner| Mmap { inner: inner })
+    }
+
+    /// Opens an anonymous memory map.
+    ///
+    /// The length must be greater than zero.
+    pub fn anonymous(len: usize, prot: Protection) -> Result<Mmap> {
+        Mmap::anonymous_with_options(len, prot, Default::default())
+    }
+
+    /// Opens an anonymous memory map with the provided options.
+    ///
+    /// The length must be greater than zero.
+    pub fn anonymous_with_options(len: usize,
+                                  prot: Protection,
+                                  options: MmapOptions) -> Result<Mmap> {
+        MmapInner::anonymous(len, prot, options).map(|inner| Mmap { inner: inner })
+    }
+
+    /// Flushes outstanding memory map modifications to disk.
+    ///
+    /// When this returns with a non-error result, all outstanding changes to a
+    /// file-backed memory map are guaranteed to be durably stored. The file's
+    /// metadata (including last modification timestamp) may not be updated.
+    pub fn flush(&self) -> Result<()> {
+        let len = self.len();
+        self.inner.flush(0, len)
+    }
+
+    /// Asynchronously flushes outstanding memory map modifications to disk.
+    ///
+    /// This method initiates flushing modified pages to durable storage, but it
+    /// will not wait for the operation to complete before returning. The file's
+    /// metadata (including last modification timestamp) may not be updated.
+    pub fn flush_async(&self) -> Result<()> {
+        let len = self.len();
+        self.inner.flush_async(0, len)
+    }
+
+    /// Flushes outstanding memory map modifications in the range to disk.
+    ///
+    /// The offset and length must be in the bounds of the mmap.
+    ///
+    /// When this returns with a non-error result, all outstanding changes to a
+    /// file-backed memory in the range are guaranteed to be durable stored. The
+    /// file's metadata (including last modification timestamp) may not be
+    /// updated. It is not guaranteed the only the changes in the specified
+    /// range are flushed; other outstanding changes to the mmap may be flushed
+    /// as well.
+    pub fn flush_range(&self, offset: usize, len: usize) -> Result<()> {
+        self.inner.flush(offset, len)
+    }
+
+    /// Asynchronously flushes outstanding memory map modifications in the range
+    /// to disk.
+    ///
+    /// The offset and length must be in the bounds of the mmap.
+    ///
+    /// This method initiates flushing modified pages to durable storage, but it
+    /// will not wait for the operation to complete before returning. The file's
+    /// metadata (including last modification timestamp) may not be updated. It
+    /// is not guaranteed that the only changes flushed are those in the
+    /// specified range; other outstanding changes to the mmap may be flushed as
+    /// well.
+    pub fn flush_async_range(&self, offset: usize, len: usize) -> Result<()> {
+        self.inner.flush_async(offset, len)
+    }
+
+    /// Change the `Protection` this mapping was created with.
+    ///
+    /// If you create a read-only file-backed mapping, you can **not** use this method to make the
+    /// mapping writeable. Remap the file instead.
+    pub fn set_protection(&mut self, prot: Protection) -> Result<()> {
+        self.inner.set_protection(prot)
+    }
+
+    /// Returns the length of the memory map.
+    pub fn len(&self) -> usize {
+        self.inner.len()
+    }
+
+    /// Returns a pointer to the mapped memory.
+    ///
+    /// See `Mmap::as_slice` for invariants that must hold when dereferencing
+    /// the pointer.
+    pub fn ptr(&self) -> *const u8 {
+        self.inner.ptr()
+    }
+
+    /// Returns a pointer to the mapped memory.
+    ///
+    /// See `Mmap::as_mut_slice` for invariants that must hold when
+    /// dereferencing the pointer.
+    pub fn mut_ptr(&mut self) -> *mut u8 {
+        self.inner.mut_ptr()
+    }
+
+    /// Returns the memory mapped file as an immutable slice.
+    ///
+    /// ## Unsafety
+    ///
+    /// The caller must ensure that the file is not concurrently modified.
+    pub unsafe fn as_slice(&self) -> &[u8] {
+        slice::from_raw_parts(self.ptr(), self.len())
+    }
+
+    /// Returns the memory mapped file as a mutable slice.
+    ///
+    /// ## Unsafety
+    ///
+    /// The caller must ensure that the file is not concurrently accessed.
+    pub unsafe fn as_mut_slice(&mut self) -> &mut [u8] {
+        slice::from_raw_parts_mut(self.mut_ptr(), self.len())
+    }
+
+    /// Creates a splittable mmap view from the mmap.
+    pub fn into_view(self) -> MmapView {
+        let len = self.len();
+        MmapView { inner: Rc::new(UnsafeCell::new(self)),
+                   offset: 0,
+                   len: len }
+    }
+
+    /// Creates a thread-safe splittable mmap view from the mmap.
+    pub fn into_view_sync(self) -> MmapViewSync {
+        let len = self.len();
+        MmapViewSync { inner: Arc::new(UnsafeCell::new(self)),
+                       offset: 0,
+                       len: len }
+    }
+}
+
+impl fmt::Debug for Mmap {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "Mmap {{ ptr: {:?}, len: {} }}", self.ptr(), self.len())
+    }
+}
+
+/// A view of a memory map.
+///
+/// The view may be split into disjoint ranges, each of which will share the
+/// underlying memory map.
+pub struct MmapView {
+    inner: Rc<UnsafeCell<Mmap>>,
+    offset: usize,
+    len: usize,
+}
+
+impl MmapView {
+
+    /// Split the view into disjoint pieces at the specified offset.
+    ///
+    /// The provided offset must be less than the view's length.
+    pub fn split_at(self, offset: usize) -> Result<(MmapView, MmapView)> {
+        if self.len < offset {
+            return Err(Error::new(ErrorKind::InvalidInput,
+                                  "mmap view split offset must be less than the view length"));
+        }
+        let MmapView { inner, offset: self_offset, len: self_len } = self;
+        Ok((MmapView { inner: inner.clone(),
+                       offset: self_offset,
+                       len: offset },
+            MmapView { inner: inner,
+                       offset: self_offset + offset,
+                       len: self_len - offset }))
+    }
+
+    /// Restricts the range of the view to the provided offset and length.
+    ///
+    /// The provided range must be a subset of the current range
+    /// (`offset + len < view.len()`).
+    pub fn restrict(&mut self, offset: usize, len: usize) -> Result<()> {
+        if offset + len > self.len {
+            return Err(Error::new(ErrorKind::InvalidInput,
+                                  "mmap view may only be restricted to a subrange \
+                                   of the current view"));
+        }
+        self.offset = self.offset + offset;
+        self.len = len;
+        Ok(())
+    }
+
+    /// Get a reference to the inner mmap.
+    ///
+    /// The caller must ensure that memory outside the `offset`/`len` range is
+    /// not accessed.
+    fn inner(&self) -> &Mmap {
+        unsafe {
+            &*self.inner.get()
+        }
+    }
+
+    /// Get a mutable reference to the inner mmap.
+    ///
+    /// The caller must ensure that memory outside the `offset`/`len` range is
+    /// not accessed.
+    fn inner_mut(&self) -> &mut Mmap {
+        unsafe {
+            &mut *self.inner.get()
+        }
+    }
+
+    /// Flushes outstanding view modifications to disk.
+    ///
+    /// When this returns with a non-error result, all outstanding changes to a
+    /// file-backed memory map view are guaranteed to be durably stored. The
+    /// file's metadata (including last modification timestamp) may not be
+    /// updated.
+    pub fn flush(&self) -> Result<()> {
+        self.inner_mut().flush_range(self.offset, self.len)
+    }
+
+    /// Asynchronously flushes outstanding memory map view modifications to
+    /// disk.
+    ///
+    /// This method initiates flushing modified pages to durable storage, but it
+    /// will not wait for the operation to complete before returning. The file's
+    /// metadata (including last modification timestamp) may not be updated.
+    pub fn flush_async(&self) -> Result<()> {
+        self.inner_mut().flush_async_range(self.offset, self.len)
+    }
+
+    /// Returns the length of the memory map view.
+    pub fn len(&self) -> usize {
+        self.len
+    }
+
+    /// Returns a shared pointer to the mapped memory.
+    ///
+    /// See `Mmap::as_slice` for invariants that must hold when dereferencing
+    /// the pointer.
+    pub fn ptr(&self) -> *const u8 {
+        unsafe { self.inner().ptr().offset(self.offset as isize) }
+    }
+
+    /// Returns a mutable pointer to the mapped memory.
+    ///
+    /// See `Mmap::as_mut_slice` for invariants that must hold when
+    /// dereferencing the pointer.
+    pub fn mut_ptr(&mut self) -> *mut u8 {
+        unsafe { self.inner_mut().mut_ptr().offset(self.offset as isize) }
+    }
+
+    /// Returns the memory mapped file as an immutable slice.
+    ///
+    /// ## Unsafety
+    ///
+    /// The caller must ensure that the file is not concurrently modified.
+    pub unsafe fn as_slice(&self) -> &[u8] {
+        &self.inner().as_slice()[self.offset..self.offset + self.len]
+    }
+
+    /// Returns the memory mapped file as a mutable slice.
+    ///
+    /// ## Unsafety
+    ///
+    /// The caller must ensure that the file is not concurrently accessed.
+    pub unsafe fn as_mut_slice(&mut self) -> &mut [u8] {
+        &mut self.inner_mut().as_mut_slice()[self.offset..self.offset + self.len]
+    }
+
+    /// Clones the view of the memory map.
+    ///
+    /// The underlying memory map is shared, and thus the caller must ensure that the memory
+    /// underlying the view is not illegally aliased.
+    pub unsafe fn clone(&self) -> MmapView {
+        MmapView {
+            inner: self.inner.clone(),
+            offset: self.offset,
+            len: self.len,
+        }
+    }
+}
+
+impl fmt::Debug for MmapView {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "MmapView {{ ptr: {:?}, offset: {}, len: {} }}",
+               self.inner().ptr(), self.offset, self.len)
+    }
+}
+
+/// A thread-safe view of a memory map.
+///
+/// The view may be split into disjoint ranges, each of which will share the
+/// underlying memory map.
+pub struct MmapViewSync {
+    inner: Arc<UnsafeCell<Mmap>>,
+    offset: usize,
+    len: usize,
+}
+
+impl MmapViewSync {
+
+    /// Split the view into disjoint pieces at the specified offset.
+    ///
+    /// The provided offset must be less than the view's length.
+    pub fn split_at(self, offset: usize) -> Result<(MmapViewSync, MmapViewSync)> {
+        if self.len < offset {
+            return Err(Error::new(ErrorKind::InvalidInput,
+                                      "mmap view split offset must be less than the view length"));
+        }
+        let MmapViewSync { inner, offset: self_offset, len: self_len } = self;
+        Ok((MmapViewSync { inner: inner.clone(),
+                           offset: self_offset,
+                           len: offset },
+            MmapViewSync { inner: inner,
+                           offset: self_offset + offset,
+                           len: self_len - offset }))
+    }
+
+    /// Restricts the range of this view to the provided offset and length.
+    ///
+    /// The provided range must be a subset of the current range (`offset + len < view.len()`).
+    pub fn restrict(&mut self, offset: usize, len: usize) -> Result<()> {
+        if offset + len > self.len {
+            return Err(Error::new(ErrorKind::InvalidInput,
+                                      "mmap view may only be restricted to a subrange \
+                                       of the current view"));
+        }
+        self.offset = self.offset + offset;
+        self.len = len;
+        Ok(())
+    }
+
+    /// Get a reference to the inner mmap.
+    ///
+    /// The caller must ensure that memory outside the `offset`/`len` range is not accessed.
+    fn inner(&self) -> &Mmap {
+        unsafe {
+            &*self.inner.get()
+        }
+    }
+
+    /// Get a mutable reference to the inner mmap.
+    ///
+    /// The caller must ensure that memory outside the `offset`/`len` range is not accessed.
+    fn inner_mut(&self) -> &mut Mmap {
+        unsafe {
+            &mut *self.inner.get()
+        }
+    }
+
+    /// Flushes outstanding view modifications to disk.
+    ///
+    /// When this returns with a non-error result, all outstanding changes to a file-backed memory
+    /// map view are guaranteed to be durably stored. The file's metadata (including last
+    /// modification timestamp) may not be updated.
+    pub fn flush(&self) -> Result<()> {
+        self.inner_mut().flush_range(self.offset, self.len)
+    }
+
+    /// Asynchronously flushes outstanding memory map view modifications to disk.
+    ///
+    /// This method initiates flushing modified pages to durable storage, but it will not wait
+    /// for the operation to complete before returning. The file's metadata (including last
+    /// modification timestamp) may not be updated.
+    pub fn flush_async(&self) -> Result<()> {
+        self.inner_mut().flush_async_range(self.offset, self.len)
+    }
+
+    /// Returns the length of the memory map view.
+    pub fn len(&self) -> usize {
+        self.len
+    }
+
+    /// Returns a shared pointer to the mapped memory.
+    ///
+    /// See `Mmap::as_slice` for invariants that must hold when dereferencing the pointer.
+    pub fn ptr(&self) -> *const u8 {
+        unsafe { self.inner().ptr().offset(self.offset as isize) }
+    }
+
+    /// Returns a mutable pointer to the mapped memory.
+    ///
+    /// See `Mmap::as_mut_slice` for invariants that must hold when dereferencing the pointer.
+    pub fn mut_ptr(&mut self) -> *mut u8 {
+        unsafe { self.inner_mut().mut_ptr().offset(self.offset as isize) }
+    }
+
+    /// Returns the memory mapped file as an immutable slice.
+    ///
+    /// ## Unsafety
+    ///
+    /// The caller must ensure that the file is not concurrently modified.
+    pub unsafe fn as_slice(&self) -> &[u8] {
+        &self.inner().as_slice()[self.offset..self.offset + self.len]
+    }
+
+    /// Returns the memory mapped file as a mutable slice.
+    ///
+    /// ## Unsafety
+    ///
+    /// The caller must ensure that the file is not concurrently accessed.
+    pub unsafe fn as_mut_slice(&mut self) -> &mut [u8] {
+        &mut self.inner_mut().as_mut_slice()[self.offset..self.offset + self.len]
+    }
+
+    /// Clones the view of the memory map.
+    ///
+    /// The underlying memory map is shared, and thus the caller must ensure that the memory
+    /// underlying the view is not illegally aliased.
+    pub unsafe fn clone(&self) -> MmapViewSync {
+        MmapViewSync {
+            inner: self.inner.clone(),
+            offset: self.offset,
+            len: self.len,
+        }
+    }
+}
+
+impl fmt::Debug for MmapViewSync {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "MmapViewSync {{ ptr: {:?}, offset: {}, len: {} }}",
+               self.inner().ptr(), self.offset, self.len)
+    }
+}
+
+unsafe impl Sync for MmapViewSync {}
+unsafe impl Send for MmapViewSync {}
+
+#[cfg(test)]
+mod test {
+    extern crate tempdir;
+
+    use std::{fs, iter};
+    use std::io::{Read, Write};
+    use std::thread;
+    use std::sync::Arc;
+    use std::ptr;
+
+    use super::*;
+
+    #[test]
+    fn map_file() {
+        let expected_len = 128;
+        let tempdir = tempdir::TempDir::new("mmap").unwrap();
+        let path = tempdir.path().join("mmap");
+
+        fs::OpenOptions::new()
+                        .write(true)
+                        .create(true)
+                        .open(&path).unwrap()
+                        .set_len(expected_len as u64).unwrap();
+
+        let mut mmap = Mmap::open_path(path, Protection::ReadWrite).unwrap();
+        let len = mmap.len();
+        assert_eq!(expected_len, len);
+
+        let zeros = iter::repeat(0).take(len).collect::<Vec<_>>();
+        let incr = (0..len).map(|n| n as u8).collect::<Vec<_>>();
+
+        // check that the mmap is empty
+        assert_eq!(&zeros[..], unsafe { mmap.as_slice() });
+
+        // write values into the mmap
+        unsafe { mmap.as_mut_slice() }.write_all(&incr[..]).unwrap();
+
+        // read values back
+        assert_eq!(&incr[..], unsafe { mmap.as_slice() });
+    }
+
+    /// Checks that a 0-length file will not be mapped.
+    #[test]
+    fn map_empty_file() {
+        let tempdir = tempdir::TempDir::new("mmap").unwrap();
+        let path = tempdir.path().join("mmap");
+
+        fs::OpenOptions::new()
+                        .write(true)
+                        .create(true)
+                        .open(&path).unwrap();
+
+        assert!(Mmap::open_path(path, Protection::ReadWrite).is_err());
+    }
+
+    #[test]
+    fn map_anon() {
+        let expected_len = 128;
+        let mut mmap = Mmap::anonymous(expected_len, Protection::ReadWrite).unwrap();
+        let len = mmap.len();
+        assert_eq!(expected_len, len);
+
+        let zeros = iter::repeat(0).take(len).collect::<Vec<_>>();
+        let incr = (0..len).map(|n| n as u8).collect::<Vec<_>>();
+
+        // check that the mmap is empty
+        assert_eq!(&zeros[..], unsafe { mmap.as_slice() });
+
+        // write values into the mmap
+        unsafe { mmap.as_mut_slice() }.write_all(&incr[..]).unwrap();
+
+        // read values back
+        assert_eq!(&incr[..], unsafe { mmap.as_slice() });
+    }
+
+    #[test]
+    fn file_write() {
+        let tempdir = tempdir::TempDir::new("mmap").unwrap();
+        let path = tempdir.path().join("mmap");
+
+        let mut file = fs::OpenOptions::new()
+                                       .read(true)
+                                       .write(true)
+                                       .create(true)
+                                       .open(&path).unwrap();
+        file.set_len(128).unwrap();
+
+        let write = b"abc123";
+        let mut read = [0u8; 6];
+
+        let mut mmap = Mmap::open_path(&path, Protection::ReadWrite).unwrap();
+        unsafe { mmap.as_mut_slice() }.write_all(write).unwrap();
+        mmap.flush().unwrap();
+
+        file.read(&mut read).unwrap();
+        assert_eq!(write, &read);
+    }
+
+    #[test]
+    fn flush_range() {
+        let tempdir = tempdir::TempDir::new("mmap").unwrap();
+        let path = tempdir.path().join("mmap");
+
+        let file = fs::OpenOptions::new()
+                                   .read(true)
+                                   .write(true)
+                                   .create(true)
+                                   .open(&path).unwrap();
+        file.set_len(128).unwrap();
+        let write = b"abc123";
+
+        let mut mmap = Mmap::open_with_offset(&file, Protection::ReadWrite, 2, write.len()).unwrap();
+        unsafe { mmap.as_mut_slice() }.write_all(write).unwrap();
+        mmap.flush_range(0, write.len()).unwrap();
+    }
+
+    #[test]
+    fn map_copy() {
+        let tempdir = tempdir::TempDir::new("mmap").unwrap();
+        let path = tempdir.path().join("mmap");
+
+        let mut file = fs::OpenOptions::new()
+                                       .read(true)
+                                       .write(true)
+                                       .create(true)
+                                       .open(&path).unwrap();
+        file.set_len(128).unwrap();
+
+        let nulls = b"\0\0\0\0\0\0";
+        let write = b"abc123";
+        let mut read = [0u8; 6];
+
+        let mut mmap = Mmap::open_path(&path, Protection::ReadCopy).unwrap();
+        unsafe { mmap.as_mut_slice() }.write(write).unwrap();
+        mmap.flush().unwrap();
+
+        // The mmap contains the write
+        unsafe { mmap.as_slice() }.read(&mut read).unwrap();
+        assert_eq!(write, &read);
+
+        // The file does not contain the write
+        file.read(&mut read).unwrap();
+        assert_eq!(nulls, &read);
+
+        // another mmap does not contain the write
+        let mmap2 = Mmap::open_path(&path, Protection::Read).unwrap();
+        unsafe { mmap2.as_slice() }.read(&mut read).unwrap();
+        assert_eq!(nulls, &read);
+    }
+
+    #[test]
+    fn map_offset() {
+        let tempdir = tempdir::TempDir::new("mmap").unwrap();
+        let path = tempdir.path().join("mmap");
+
+        let file = fs::OpenOptions::new()
+                                   .read(true)
+                                   .write(true)
+                                   .create(true)
+                                   .open(&path)
+                                   .unwrap();
+
+        file.set_len(500000 as u64).unwrap();
+
+        let offset = 5099;
+        let len = 50050;
+
+        let mut mmap = Mmap::open_with_offset(&file,
+                                              Protection::ReadWrite,
+                                              offset,
+                                              len).unwrap();
+        assert_eq!(len, mmap.len());
+
+        let zeros = iter::repeat(0).take(len).collect::<Vec<_>>();
+        let incr = (0..len).map(|n| n as u8).collect::<Vec<_>>();
+
+        // check that the mmap is empty
+        assert_eq!(&zeros[..], unsafe { mmap.as_slice() });
+
+        // write values into the mmap
+        unsafe { mmap.as_mut_slice() }.write_all(&incr[..]).unwrap();
+
+        // read values back
+        assert_eq!(&incr[..], unsafe { mmap.as_slice() });
+    }
+
+    #[test]
+    fn index() {
+        let mut mmap = Mmap::anonymous(128, Protection::ReadWrite).unwrap();
+        unsafe { mmap.as_mut_slice()[0] = 42 };
+        assert_eq!(42, unsafe { mmap.as_slice()[0] });
+    }
+
+    #[test]
+    fn sync_send() {
+        let mmap = Arc::new(Mmap::anonymous(128, Protection::ReadWrite).unwrap());
+        thread::spawn(move || {
+            unsafe {
+                mmap.as_slice();
+            }
+        });
+    }
+
+    #[test]
+    fn view() {
+        let len = 128;
+        let split = 32;
+        let mut view = Mmap::anonymous(len, Protection::ReadWrite).unwrap().into_view();
+        let incr = (0..len).map(|n| n as u8).collect::<Vec<_>>();
+        // write values into the view
+        unsafe { view.as_mut_slice() }.write_all(&incr[..]).unwrap();
+
+        let (mut view1, view2) = view.split_at(32).unwrap();
+        assert_eq!(view1.len(), split);
+        assert_eq!(view2.len(), len - split);
+
+        assert_eq!(&incr[0..split], unsafe { view1.as_slice() });
+        assert_eq!(&incr[split..], unsafe { view2.as_slice() });
+
+        view1.restrict(10, 10).unwrap();
+        assert_eq!(&incr[10..20], unsafe { view1.as_slice() })
+    }
+
+    #[test]
+    fn view_sync() {
+        let len = 128;
+        let split = 32;
+        let mut view = Mmap::anonymous(len, Protection::ReadWrite).unwrap().into_view_sync();
+        let incr = (0..len).map(|n| n as u8).collect::<Vec<_>>();
+        // write values into the view
+        unsafe { view.as_mut_slice() }.write_all(&incr[..]).unwrap();
+
+        let (mut view1, view2) = view.split_at(32).unwrap();
+        assert_eq!(view1.len(), split);
+        assert_eq!(view2.len(), len - split);
+
+        assert_eq!(&incr[0..split], unsafe { view1.as_slice() });
+        assert_eq!(&incr[split..], unsafe { view2.as_slice() });
+
+        view1.restrict(10, 10).unwrap();
+        assert_eq!(&incr[10..20], unsafe { view1.as_slice() })
+    }
+
+    #[test]
+    fn view_write() {
+        let len   = 131072; // 256KiB
+        let split =  66560; // 65KiB + 10B
+
+        let tempdir = tempdir::TempDir::new("mmap").unwrap();
+        let path = tempdir.path().join("mmap");
+
+        let mut file = fs::OpenOptions::new()
+                                       .read(true)
+                                       .write(true)
+                                       .create(true)
+                                       .open(&path).unwrap();
+        file.set_len(len).unwrap();
+
+        let incr = (0..len).map(|n| n as u8).collect::<Vec<_>>();
+        let incr1 = incr[0..split].to_owned();
+        let incr2 = incr[split..].to_owned();
+
+        let (mut view1, mut view2) = Mmap::open_path(&path, Protection::ReadWrite)
+                                         .unwrap()
+                                         .into_view_sync()
+                                         .split_at(split)
+                                         .unwrap();
+
+
+        let join1 = thread::spawn(move || {
+            unsafe { view1.as_mut_slice() }.write(&incr1).unwrap();
+            view1.flush().unwrap();
+        });
+
+        let join2 = thread::spawn(move || {
+            unsafe { view2.as_mut_slice() }.write(&incr2).unwrap();
+            view2.flush().unwrap();
+        });
+
+        join1.join().unwrap();
+        join2.join().unwrap();
+
+        let mut buf = Vec::new();
+        file.read_to_end(&mut buf).unwrap();
+        assert_eq!(incr, &buf[..]);
+    }
+
+    #[test]
+    fn view_sync_send() {
+        let view = Arc::new(Mmap::anonymous(128, Protection::ReadWrite).unwrap().into_view_sync());
+        thread::spawn(move || {
+            unsafe {
+                view.as_slice();
+            }
+        });
+    }
+
+    #[test]
+    fn set_prot() {
+        let mut map = Mmap::anonymous(1, Protection::Read).unwrap();
+        map.set_protection(Protection::ReadWrite).unwrap();
+
+        // We should now be able to write to the memory. If not this will cause a SIGSEGV.
+        unsafe { ptr::write(map.mut_ptr(), 0xf1); }
+
+        map.set_protection(Protection::Read).unwrap();
+
+        assert_eq!(unsafe { ptr::read(map.mut_ptr()) }, 0xf1);
+    }
+
+    #[test]
+    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+    fn jit_x86() {
+        use std::mem;
+
+        let mut map = Mmap::anonymous(4096, Protection::ReadWrite).unwrap();
+
+        {
+            let mut jitmem = unsafe { map.as_mut_slice() };
+            jitmem[0] = 0xB8;   // mov eax, 0xAB
+            jitmem[1] = 0xAB;
+            jitmem[2] = 0x00;
+            jitmem[3] = 0x00;
+            jitmem[4] = 0x00;
+            jitmem[5] = 0xC3;   // ret
+        }
+
+        map.set_protection(Protection::ReadExecute).unwrap();
+
+        let jitfn: extern "C" fn() -> u8 = unsafe { mem::transmute(map.mut_ptr()) };
+        assert_eq!(jitfn(), 0xab);
+    }
+
+    #[test]
+    fn offset_set_protection() {
+        let tempdir = tempdir::TempDir::new("mmap").unwrap();
+        let path = tempdir.path().join("mmap");
+
+        let file = fs::OpenOptions::new()
+                                   .read(true)
+                                   .write(true)
+                                   .create(true)
+                                   .open(&path)
+                                   .unwrap();
+
+        file.set_len(500000 as u64).unwrap();
+
+        let offset = 5099;
+        let len = 50050;
+
+        let mut mmap = Mmap::open_with_offset(&file,
+                                              Protection::ReadWrite,
+                                              offset,
+                                              len).unwrap();
+        assert_eq!(len, mmap.len());
+
+        let zeros = iter::repeat(0).take(len).collect::<Vec<_>>();
+        let incr = (0..len).map(|n| n as u8).collect::<Vec<_>>();
+
+        // check that the mmap is empty
+        assert_eq!(&zeros[..], unsafe { mmap.as_slice() });
+
+        // write values into the mmap
+        unsafe { mmap.as_mut_slice() }.write_all(&incr[..]).unwrap();
+
+        // change to read-only protection
+        mmap.set_protection(Protection::Read).unwrap();
+
+        // read values back
+        assert_eq!(&incr[..], unsafe { mmap.as_slice() });
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/memmap/src/unix.rs
@@ -0,0 +1,182 @@
+extern crate libc;
+
+use std::{io, ptr};
+use std::fs::File;
+use std::os::unix::io::AsRawFd;
+
+use ::Protection;
+use ::MmapOptions;
+
+impl Protection {
+
+    /// Returns the `Protection` value as a POSIX protection flag.
+    fn as_prot(self) -> libc::c_int {
+        match self {
+            Protection::Read => libc::PROT_READ,
+            Protection::ReadWrite => libc::PROT_READ | libc::PROT_WRITE,
+            Protection::ReadCopy => libc::PROT_READ | libc::PROT_WRITE,
+            Protection::ReadExecute => libc::PROT_READ | libc::PROT_EXEC,
+        }
+    }
+
+    fn as_flag(self) -> libc::c_int {
+        match self {
+            Protection::Read => libc::MAP_SHARED,
+            Protection::ReadWrite => libc::MAP_SHARED,
+            Protection::ReadCopy => libc::MAP_PRIVATE,
+            Protection::ReadExecute => libc::MAP_SHARED,
+        }
+    }
+}
+
+#[cfg(any(all(target_os = "linux", not(target_arch="mips")),
+          target_os = "freebsd",
+          target_os = "android"))]
+const MAP_STACK: libc::c_int = libc::MAP_STACK;
+
+#[cfg(not(any(all(target_os = "linux", not(target_arch="mips")),
+              target_os = "freebsd",
+              target_os = "android")))]
+const MAP_STACK: libc::c_int = 0;
+
+impl MmapOptions {
+    fn as_flag(self) -> libc::c_int {
+        let mut flag = 0;
+        if self.stack { flag |= MAP_STACK }
+        flag
+    }
+}
+
+pub struct MmapInner {
+    ptr: *mut libc::c_void,
+    len: usize,
+}
+
+impl MmapInner {
+
+    pub fn open(file: &File, prot: Protection, offset: usize, len: usize) -> io::Result<MmapInner> {
+        let alignment = offset % page_size();
+        let aligned_offset = offset - alignment;
+        let aligned_len = len + alignment;
+        if aligned_len == 0 {
+            // Normally the OS would catch this, but it segfaults under QEMU.
+            return Err(io::Error::new(io::ErrorKind::InvalidInput,
+                                      "memory map must have a non-zero length"));
+        }
+
+        unsafe {
+            let ptr = libc::mmap(ptr::null_mut(),
+                                 aligned_len as libc::size_t,
+                                 prot.as_prot(),
+                                 prot.as_flag(),
+                                 file.as_raw_fd(),
+                                 aligned_offset as libc::off_t);
+
+            if ptr == libc::MAP_FAILED {
+                Err(io::Error::last_os_error())
+            } else {
+                Ok(MmapInner {
+                    ptr: ptr.offset(alignment as isize),
+                    len: len,
+                })
+            }
+        }
+    }
+
+    /// Open an anonymous memory map.
+    pub fn anonymous(len: usize, prot: Protection, options: MmapOptions) -> io::Result<MmapInner> {
+        let ptr = unsafe {
+            libc::mmap(ptr::null_mut(),
+                       len as libc::size_t,
+                       prot.as_prot(),
+                       options.as_flag() | prot.as_flag() | libc::MAP_ANON,
+                       -1,
+                       0)
+        };
+
+        if ptr == libc::MAP_FAILED {
+            Err(io::Error::last_os_error())
+        } else {
+            Ok(MmapInner {
+                ptr: ptr,
+                len: len as usize,
+            })
+        }
+    }
+
+    pub fn flush(&self, offset: usize, len: usize) -> io::Result<()> {
+        let alignment = (self.ptr as usize + offset) % page_size();
+        let offset = offset as isize - alignment as isize;
+        let len = len + alignment;
+        let result = unsafe { libc::msync(self.ptr.offset(offset),
+                                          len as libc::size_t,
+                                          libc::MS_SYNC) };
+        if result == 0 {
+            Ok(())
+        } else {
+            Err(io::Error::last_os_error())
+        }
+    }
+
+    pub fn flush_async(&self, offset: usize, len: usize) -> io::Result<()> {
+        let alignment = offset % page_size();
+        let aligned_offset = offset - alignment;
+        let aligned_len = len + alignment;
+        let result = unsafe { libc::msync(self.ptr.offset(aligned_offset as isize),
+                                          aligned_len as libc::size_t,
+                                          libc::MS_ASYNC) };
+        if result == 0 {
+            Ok(())
+        } else {
+            Err(io::Error::last_os_error())
+        }
+    }
+
+    pub fn set_protection(&mut self, prot: Protection) -> io::Result<()> {
+        unsafe {
+            let alignment = self.ptr as usize % page_size();
+            let ptr = self.ptr.offset(- (alignment as isize));
+            let len = self.len + alignment;
+            let result = libc::mprotect(ptr,
+                                        len,
+                                        prot.as_prot());
+            if result == 0 {
+                Ok(())
+            } else {
+                Err(io::Error::last_os_error())
+            }
+        }
+    }
+
+    pub fn ptr(&self) -> *const u8 {
+        self.ptr as *const u8
+    }
+
+    pub fn mut_ptr(&mut self) -> *mut u8 {
+        self.ptr as *mut u8
+    }
+
+    pub fn len(&self) -> usize {
+        self.len
+    }
+}
+
+impl Drop for MmapInner {
+    fn drop(&mut self) {
+        let alignment = self.ptr as usize % page_size();
+        unsafe {
+            assert!(libc::munmap(self.ptr.offset(- (alignment as isize)),
+                                 (self.len + alignment) as libc::size_t) == 0,
+                    "unable to unmap mmap: {}", io::Error::last_os_error());
+        }
+    }
+}
+
+unsafe impl Sync for MmapInner { }
+unsafe impl Send for MmapInner { }
+
+fn page_size() -> usize {
+    unsafe {
+        libc::sysconf(libc::_SC_PAGESIZE) as usize
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/memmap/src/windows.rs
@@ -0,0 +1,194 @@
+extern crate fs2;
+extern crate kernel32;
+extern crate winapi;
+
+use std::{io, mem, ptr};
+use std::fs::File;
+use std::os::raw::c_void;
+use std::os::windows::io::AsRawHandle;
+
+use self::fs2::FileExt;
+
+use ::Protection;
+use ::MmapOptions;
+
+impl Protection {
+
+    /// Returns the `Protection` as a flag appropriate for a call to `CreateFileMapping`.
+    fn as_mapping_flag(self) -> winapi::DWORD {
+        match self {
+            Protection::Read => winapi::PAGE_READONLY,
+            Protection::ReadWrite => winapi::PAGE_READWRITE,
+            Protection::ReadCopy => winapi::PAGE_READONLY,
+            Protection::ReadExecute => winapi::PAGE_EXECUTE_READ,
+        }
+    }
+
+    /// Returns the `Protection` as a flag appropriate for a call to `MapViewOfFile`.
+    fn as_view_flag(self) -> winapi::DWORD {
+        match self {
+            Protection::Read => winapi::FILE_MAP_READ,
+            Protection::ReadWrite => winapi::FILE_MAP_ALL_ACCESS,
+            Protection::ReadCopy => winapi::FILE_MAP_COPY,
+            Protection::ReadExecute => winapi::FILE_MAP_READ | winapi::FILE_MAP_EXECUTE,
+        }
+    }
+}
+
+pub struct MmapInner {
+    file: Option<File>,
+    ptr: *mut c_void,
+    len: usize,
+}
+
+impl MmapInner {
+
+    pub fn open(file: &File, prot: Protection, offset: usize, len: usize) -> io::Result<MmapInner> {
+        let alignment = offset % allocation_granularity();
+        let aligned_offset = offset - alignment;
+        let aligned_len = len + alignment;
+
+        unsafe {
+            let handle = kernel32::CreateFileMappingW(file.as_raw_handle(),
+                                                      ptr::null_mut(),
+                                                      prot.as_mapping_flag(),
+                                                      0,
+                                                      0,
+                                                      ptr::null());
+            if handle == ptr::null_mut() {
+                return Err(io::Error::last_os_error());
+            }
+
+            let ptr = kernel32::MapViewOfFile(handle,
+                                              prot.as_view_flag(),
+                                              (aligned_offset >> 16 >> 16) as winapi::DWORD,
+                                              (aligned_offset & 0xffffffff) as winapi::DWORD,
+                                              aligned_len as winapi::SIZE_T);
+            kernel32::CloseHandle(handle);
+
+            if ptr == ptr::null_mut() {
+                Err(io::Error::last_os_error())
+            } else {
+                Ok(MmapInner {
+                    file: Some(try!(file.duplicate())),
+                    ptr: ptr.offset(alignment as isize),
+                    len: len as usize,
+                })
+            }
+        }
+    }
+
+    pub fn anonymous(len: usize, prot: Protection, _options: MmapOptions) -> io::Result<MmapInner> {
+        unsafe {
+            // Create a mapping and view with maximum access permissions, then use `VirtualProtect`
+            // to set the actual `Protection`. This way, we can set more permissive protection later
+            // on.
+            // Also see https://msdn.microsoft.com/en-us/library/windows/desktop/aa366537.aspx
+
+            let handle = kernel32::CreateFileMappingW(winapi::INVALID_HANDLE_VALUE,
+                                                      ptr::null_mut(),
+                                                      winapi::PAGE_EXECUTE_READWRITE,
+                                                      (len >> 16 >> 16) as winapi::DWORD,
+                                                      (len & 0xffffffff) as winapi::DWORD,
+                                                      ptr::null());
+            if handle == ptr::null_mut() {
+                return Err(io::Error::last_os_error());
+            }
+            let access = winapi::FILE_MAP_ALL_ACCESS | winapi::FILE_MAP_EXECUTE;
+            let ptr = kernel32::MapViewOfFile(handle,
+                                              access,
+                                              0,
+                                              0,
+                                              len as winapi::SIZE_T);
+            kernel32::CloseHandle(handle);
+
+            if ptr == ptr::null_mut() {
+                return Err(io::Error::last_os_error());
+            }
+
+            let mut old = 0;
+            let result = kernel32::VirtualProtect(ptr,
+                                                  len as winapi::SIZE_T,
+                                                  prot.as_mapping_flag(),
+                                                  &mut old);
+            if result != 0 {
+                Ok(MmapInner {
+                    file: None,
+                    ptr: ptr,
+                    len: len as usize,
+                })
+            } else {
+                Err(io::Error::last_os_error())
+            }
+        }
+    }
+
+    pub fn flush(&self, offset: usize, len: usize) -> io::Result<()> {
+        try!(self.flush_async(offset, len));
+        if let Some(ref file) = self.file { file.sync_data() } else { Ok(()) }
+    }
+
+    pub fn flush_async(&self, offset: usize, len: usize) -> io::Result<()> {
+        let result = unsafe { kernel32::FlushViewOfFile(self.ptr.offset(offset as isize),
+                                                        len as winapi::SIZE_T) };
+        if result != 0 {
+            Ok(())
+        } else {
+            Err(io::Error::last_os_error())
+        }
+    }
+
+    pub fn set_protection(&mut self, prot: Protection) -> io::Result<()> {
+        unsafe {
+            let alignment = self.ptr as usize % allocation_granularity();
+            let ptr = self.ptr.offset(- (alignment as isize));
+            let aligned_len = self.len as winapi::SIZE_T + alignment as winapi::SIZE_T;
+
+            let mut old = 0;
+            let result = kernel32::VirtualProtect(ptr,
+                                                  aligned_len,
+                                                  prot.as_mapping_flag(),
+                                                  &mut old);
+
+            if result != 0 {
+                Ok(())
+            } else {
+                Err(io::Error::last_os_error())
+            }
+        }
+    }
+
+    pub fn ptr(&self) -> *const u8 {
+        self.ptr as *const u8
+    }
+
+    pub fn mut_ptr(&mut self) -> *mut u8 {
+        self.ptr as *mut u8
+    }
+
+    pub fn len(&self) -> usize {
+        self.len
+    }
+}
+
+impl Drop for MmapInner {
+    fn drop(&mut self) {
+        let alignment = self.ptr as usize % allocation_granularity();
+        unsafe {
+            let ptr = self.ptr.offset(- (alignment as isize));
+            assert!(kernel32::UnmapViewOfFile(ptr) != 0,
+                    "unable to unmap mmap: {}", io::Error::last_os_error());
+        }
+    }
+}
+
+unsafe impl Sync for MmapInner { }
+unsafe impl Send for MmapInner { }
+
+fn allocation_granularity() -> usize {
+    unsafe {
+        let mut info = mem::zeroed();
+        kernel32::GetSystemInfo(&mut info);
+        return info.dwAllocationGranularity as usize;
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio-uds/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"0602d18a229e5bd001e2aaf8ff26c1bdb3dba926f911aec8901c0ee7bed27ca9","Cargo.toml":"e503ea1d349539b2c75e3659660bc6232a447719ce2c7f7b7bec38fbbab6f640","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"322030d7ae24aec8fb2d2c32a7245c7a6dab5b885b439d599d3acd2ddca9bd80","src/datagram.rs":"b4311804bd4e330905fbf3e47e8c738759bbc039bf6ad2045490080a958d48c2","src/lib.rs":"381e167fff02b16d5234fe8bfa3f85684fee4796f83356c2dfdcbfe09fa9a1fe","src/listener.rs":"1cf1d1ca896f4718df27d1affbbc9125d86484c60f3dc479741f50ecb484a290","src/socket.rs":"6f14598a19d66cf76e50fe6a72c17dc840bf46216597a2e055a3bb5efff267e4","src/stream.rs":"7353ebe4a104ed0226c849e638cf9f6922083488b81b2e862c17b59d404ac15f","tests/echo.rs":"3056f97689f0696e970cc401bf0b1f5c0cd4f9952b6fe2dda60831c870f6171c","tests/smoke.rs":"2a6ee54b3f9d58a63cb3beecda8646f17ebdb3d20aa59c740f8c972cc06063e9"},"package":"1731a873077147b626d89cc6c2a0db6288d607496c5d10c0cfcf3adc697ec673"}
\ No newline at end of file
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio-uds/.travis.yml
@@ -0,0 +1,23 @@
+language: rust
+rust:
+  - stable
+  - beta
+  - nightly
+sudo: false
+before_script:
+  - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
+script:
+  - cargo test
+  - cargo doc
+after_success:
+  - travis-cargo --only nightly doc-upload
+env:
+  global:
+    secure: "V+dRcbwjNbHJxvoEcASMMdXY74YSmQqZXA9P2oa4gzP7lI0fXqM47pBIVfA4Mj4dhZywByywc/EBDc51JOjdORZognENxLUymTlTcTu7zcq+r7woXYPQHmm7BEvrEKBbQTaV/sO+200CN4d5mT1sPNJoFMp8lUL7/QtoczH+vGWSzWBb8F59oxRpNqD1MhaTpo0oWVMp8yskLvylgIjEoCY8E1uKp7rkqgAxUj8RmZt3hnFAr1SIu32tYUhj7STw8Ad++pI+kdx6SH0bslBy7TQcEhsTPQ4Q66u1z5pkVhv/Q0u3QLiJcI8WWEukTa3lwRUusXwZXfuME2Lz6PiKWa7jSGDc0UBc83oy7FOxyY+tutk74MQU0861dh2UlJgzzw+A7NnZHXueNQyT3RaD3K1ce3aPdCMBPM6GcRFkMcm+6llz5weGBhWHo5Uyeuy+Y88OF/ZZS7a5PdmvPfapB3Ir6MRZaDse/bDEWaBd5wO7ZMk8YyFumxJWuksHWxnIYTEjkn+4zHH1doCSr5axjryv9oDa8Agjcd1ePRNUAlgszslUeyU5ACfX2rJi2VlEL+DC01WfUQC0z0M8ISOOaQdoVRnwYOYpw6qQHZDU2Es7f1TihIzAOmzkgnz9wpInzs73EDjHqyROVRnHQO8P/epapbisWlakWWmUn7GJA3Y="
+
+notifications:
+  email:
+    on_success: never
+os:
+  - linux
+  - osx
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio-uds/Cargo.toml
@@ -0,0 +1,23 @@
+[package]
+name = "mio-uds"
+version = "0.6.4"
+authors = ["Alex Crichton <alex@alexcrichton.com>"]
+license = "MIT/Apache-2.0"
+readme = "README.md"
+repository = "https://github.com/alexcrichton/mio-uds"
+homepage = "https://github.com/alexcrichton/mio-uds"
+documentation = "https://docs.rs/mio-uds"
+description = """
+Unix domain socket bindings for mio
+"""
+categories = ["asynchronous"]
+
+[badges]
+travis-ci = { repository = "alexcrichton/mio-uds" }
+
+[target."cfg(unix)".dependencies]
+libc = "0.2"
+mio = "0.6.5"
+
+[dev-dependencies]
+tempdir = "0.3"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio-uds/LICENSE-APACHE
@@ -0,0 +1,201 @@
+                              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.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio-uds/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2014 Alex Crichton
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio-uds/README.md
@@ -0,0 +1,35 @@
+# mio-uds
+
+[![Build Status](https://travis-ci.org/alexcrichton/mio-uds.svg?branch=master)](https://travis-ci.org/alexcrichton/mio-uds)
+
+[Documentation](https://docs.rs/mio-uds)
+
+A library for integrating Unix Domain Sockets with [mio]. Based on the standard
+library's [support for Unix sockets][std], except all of the abstractions and
+types are nonblocking to conform with the expectations of mio.
+
+[mio]: https://github.com/carllerche/mio
+[std]: https://doc.rust-lang.org/std/os/unix/net/
+
+```toml
+# Cargo.toml
+[dependencies]
+mio-uds = "0.6"
+mio = "0.6"
+```
+
+## Usage
+
+The three exported types at the top level, `UnixStream`, `UnixListener`, and
+`UnixDatagram`, are thin wrappers around the libstd counterparts. They can be
+used in similar fashions to mio's TCP and UDP types in terms of registration and
+API.
+
+# License
+
+`mio-uds` is primarily distributed under the terms of both the MIT license and
+the Apache License (Version 2.0), with portions covered by various BSD-like
+licenses.
+
+See LICENSE-APACHE, and LICENSE-MIT for details.
+
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio-uds/src/datagram.rs
@@ -0,0 +1,183 @@
+use std::io;
+use std::net::Shutdown;
+use std::os::unix::net;
+use std::os::unix::prelude::*;
+use std::path::Path;
+
+use libc;
+use mio::event::Evented;
+use mio::unix::EventedFd;
+use mio::{Poll, Token, Ready, PollOpt};
+
+use cvt;
+use socket::{sockaddr_un, Socket};
+
+/// A Unix datagram socket.
+#[derive(Debug)]
+pub struct UnixDatagram {
+    inner: net::UnixDatagram,
+}
+
+impl UnixDatagram {
+    /// Creates a Unix datagram socket bound to the given path.
+    pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixDatagram> {
+        UnixDatagram::_bind(path.as_ref())
+    }
+
+    fn _bind(path: &Path) -> io::Result<UnixDatagram> {
+        unsafe {
+            let (addr, len) = try!(sockaddr_un(path));
+            let fd = try!(Socket::new(libc::SOCK_DGRAM));
+
+            let addr = &addr as *const _ as *const _;
+            try!(cvt(libc::bind(fd.fd(), addr, len)));
+
+            Ok(UnixDatagram::from_raw_fd(fd.into_fd()))
+        }
+    }
+
+    /// Consumes a standard library `UnixDatagram` and returns a wrapped
+    /// `UnixDatagram` compatible with mio.
+    ///
+    /// The returned stream is moved into nonblocking mode and is otherwise
+    /// ready to get associated with an event loop.
+    pub fn from_datagram(stream: net::UnixDatagram) -> io::Result<UnixDatagram> {
+        try!(stream.set_nonblocking(true));
+        Ok(UnixDatagram { inner: stream })
+    }
+
+    /// Create an unnamed pair of connected sockets.
+    ///
+    /// Returns two `UnixDatagrams`s which are connected to each other.
+    pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
+        unsafe {
+            let (a, b) = try!(Socket::pair(libc::SOCK_DGRAM));
+            Ok((UnixDatagram::from_raw_fd(a.into_fd()),
+                UnixDatagram::from_raw_fd(b.into_fd())))
+        }
+    }
+
+    /// Creates a Unix Datagram socket which is not bound to any address.
+    pub fn unbound() -> io::Result<UnixDatagram> {
+        let stream = try!(net::UnixDatagram::unbound());
+        try!(stream.set_nonblocking(true));
+        Ok(UnixDatagram { inner: stream })
+    }
+
+    /// Connects the socket to the specified address.
+    ///
+    /// The `send` method may be used to send data to the specified address.
+    /// `recv` and `recv_from` will only receive data from that address.
+    pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
+        self.inner.connect(path)
+    }
+
+    /// Creates a new independently owned handle to the underlying socket.
+    ///
+    /// The returned `UnixListener` is a reference to the same socket that this
+    /// object references. Both handles can be used to accept incoming
+    /// connections and options set on one listener will affect the other.
+    pub fn try_clone(&self) -> io::Result<UnixDatagram> {
+        self.inner.try_clone().map(|i| {
+            UnixDatagram { inner: i }
+        })
+    }
+
+    /// Returns the address of this socket.
+    pub fn local_addr(&self) -> io::Result<net::SocketAddr> {
+        self.inner.local_addr()
+    }
+
+    /// Returns the address of this socket's peer.
+    ///
+    /// The `connect` method will connect the socket to a peer.
+    pub fn peer_addr(&self) -> io::Result<net::SocketAddr> {
+        self.inner.peer_addr()
+    }
+
+    /// Receives data from the socket.
+    ///
+    /// On success, returns the number of bytes read and the address from
+    /// whence the data came.
+    pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, net::SocketAddr)> {
+        self.inner.recv_from(buf)
+    }
+
+    /// Receives data from the socket.
+    ///
+    /// On success, returns the number of bytes read.
+    pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
+        self.inner.recv(buf)
+    }
+
+    /// Sends data on the socket to the specified address.
+    ///
+    /// On success, returns the number of bytes written.
+    pub fn send_to<P: AsRef<Path>>(&self, buf: &[u8], path: P) -> io::Result<usize> {
+        self.inner.send_to(buf, path)
+    }
+
+    /// Sends data on the socket to the socket's peer.
+    ///
+    /// The peer address may be set by the `connect` method, and this method
+    /// will return an error if the socket has not already been connected.
+    ///
+    /// On success, returns the number of bytes written.
+    pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
+        self.inner.send(buf)
+    }
+
+    /// Returns the value of the `SO_ERROR` option.
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        self.inner.take_error()
+    }
+
+    /// Shut down the read, write, or both halves of this connection.
+    ///
+    /// This function will cause all pending and future I/O calls on the
+    /// specified portions to immediately return with an appropriate value
+    /// (see the documentation of `Shutdown`).
+    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
+        self.inner.shutdown(how)
+    }
+}
+
+impl Evented for UnixDatagram {
+    fn register(&self,
+                poll: &Poll,
+                token: Token,
+                events: Ready,
+                opts: PollOpt) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).register(poll, token, events, opts)
+    }
+
+    fn reregister(&self,
+                  poll: &Poll,
+                  token: Token,
+                  events: Ready,
+                  opts: PollOpt) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).reregister(poll, token, events, opts)
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).deregister(poll)
+    }
+}
+
+impl AsRawFd for UnixDatagram {
+    fn as_raw_fd(&self) -> i32 {
+        self.inner.as_raw_fd()
+    }
+}
+
+impl IntoRawFd for UnixDatagram {
+    fn into_raw_fd(self) -> i32 {
+        self.inner.into_raw_fd()
+    }
+}
+
+impl FromRawFd for UnixDatagram {
+    unsafe fn from_raw_fd(fd: i32) -> UnixDatagram {
+        UnixDatagram { inner: net::UnixDatagram::from_raw_fd(fd) }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio-uds/src/lib.rs
@@ -0,0 +1,27 @@
+//! MIO bindings for Unix Domain Sockets
+
+#![cfg(unix)]
+#![deny(missing_docs)]
+#![doc(html_root_url = "https://docs.rs/mio-uds/0.6")]
+
+extern crate libc;
+extern crate mio;
+
+use std::io;
+
+mod datagram;
+mod listener;
+mod socket;
+mod stream;
+
+pub use stream::UnixStream;
+pub use listener::UnixListener;
+pub use datagram::UnixDatagram;
+
+fn cvt(i: libc::c_int) -> io::Result<libc::c_int> {
+    if i == -1 {
+        Err(io::Error::last_os_error())
+    } else {
+        Ok(i)
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio-uds/src/listener.rs
@@ -0,0 +1,134 @@
+use std::io;
+use std::os::unix::net;
+use std::os::unix::prelude::*;
+use std::path::Path;
+
+use libc;
+use mio::event::Evented;
+use mio::unix::EventedFd;
+use mio::{Poll, Token, Ready, PollOpt};
+
+use UnixStream;
+use cvt;
+use socket::{sockaddr_un, Socket};
+
+/// A structure representing a Unix domain socket server.
+///
+/// This listener can be used to accept new streams connected to a remote
+/// endpoint, through which the `read` and `write` methods can be used to
+/// communicate.
+#[derive(Debug)]
+pub struct UnixListener {
+    inner: net::UnixListener,
+}
+
+impl UnixListener {
+    /// Creates a new `UnixListener` bound to the specified socket.
+    pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
+        UnixListener::_bind(path.as_ref())
+    }
+
+    fn _bind(path: &Path) -> io::Result<UnixListener> {
+        unsafe {
+            let (addr, len) = try!(sockaddr_un(path));
+            let fd = try!(Socket::new(libc::SOCK_STREAM));
+
+            let addr = &addr as *const _ as *const _;
+            try!(cvt(libc::bind(fd.fd(), addr, len)));
+            try!(cvt(libc::listen(fd.fd(), 128)));
+
+            Ok(UnixListener::from_raw_fd(fd.into_fd()))
+        }
+    }
+
+    /// Consumes a standard library `UnixListener` and returns a wrapped
+    /// `UnixListener` compatible with mio.
+    ///
+    /// The returned stream is moved into nonblocking mode and is otherwise
+    /// ready to get associated with an event loop.
+    pub fn from_listener(stream: net::UnixListener) -> io::Result<UnixListener> {
+        try!(stream.set_nonblocking(true));
+        Ok(UnixListener { inner: stream })
+    }
+
+    /// Accepts a new incoming connection to this listener.
+    ///
+    /// When established, the corresponding `UnixStream` and the remote peer's
+    /// address will be returned as `Ok(Some(...))`. If there is no connection
+    /// waiting to be accepted, then `Ok(None)` is returned.
+    ///
+    /// If an error happens while accepting, `Err` is returned.
+    pub fn accept(&self) -> io::Result<Option<(UnixStream, net::SocketAddr)>> {
+        match self.inner.accept() {
+            Ok((socket, addr)) => {
+                try!(socket.set_nonblocking(true));
+                Ok(Some(unsafe {
+                    (UnixStream::from_raw_fd(socket.into_raw_fd()), addr)
+                }))
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => Ok(None),
+            Err(e) => Err(e),
+        }
+    }
+
+    /// Creates a new independently owned handle to the underlying socket.
+    ///
+    /// The returned `UnixListener` is a reference to the same socket that this
+    /// object references. Both handles can be used to accept incoming
+    /// connections and options set on one listener will affect the other.
+    pub fn try_clone(&self) -> io::Result<UnixListener> {
+        self.inner.try_clone().map(|l| {
+            UnixListener { inner: l }
+        })
+    }
+
+    /// Returns the local socket address of this listener.
+    pub fn local_addr(&self) -> io::Result<net::SocketAddr> {
+        self.inner.local_addr()
+    }
+
+    /// Returns the value of the `SO_ERROR` option.
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        self.inner.take_error()
+    }
+}
+
+impl Evented for UnixListener {
+    fn register(&self,
+                poll: &Poll,
+                token: Token,
+                events: Ready,
+                opts: PollOpt) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).register(poll, token, events, opts)
+    }
+
+    fn reregister(&self,
+                  poll: &Poll,
+                  token: Token,
+                  events: Ready,
+                  opts: PollOpt) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).reregister(poll, token, events, opts)
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).deregister(poll)
+    }
+}
+
+impl AsRawFd for UnixListener {
+    fn as_raw_fd(&self) -> i32 {
+        self.inner.as_raw_fd()
+    }
+}
+
+impl IntoRawFd for UnixListener {
+    fn into_raw_fd(self) -> i32 {
+        self.inner.into_raw_fd()
+    }
+}
+
+impl FromRawFd for UnixListener {
+    unsafe fn from_raw_fd(fd: i32) -> UnixListener {
+        UnixListener { inner: net::UnixListener::from_raw_fd(fd) }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio-uds/src/socket.rs
@@ -0,0 +1,141 @@
+use std::cmp::Ordering;
+use std::io;
+use std::mem;
+use std::os::unix::prelude::*;
+use std::path::Path;
+
+use libc::{self, c_int, c_ulong};
+
+use cvt;
+
+// See below for the usage of SOCK_CLOEXEC, but this constant is only defined on
+// Linux currently (e.g. support doesn't exist on other platforms). In order to
+// get name resolution to work and things to compile we just define a dummy
+// SOCK_CLOEXEC here for other platforms. Note that the dummy constant isn't
+// actually ever used (the blocks below are wrapped in `if cfg!` as well.
+#[cfg(target_os = "linux")]
+use libc::{SOCK_CLOEXEC, SOCK_NONBLOCK};
+#[cfg(not(target_os = "linux"))]
+const SOCK_CLOEXEC: c_int = 0;
+#[cfg(not(target_os = "linux"))]
+const SOCK_NONBLOCK: c_int = 0;
+
+pub struct Socket {
+    fd: c_int,
+}
+
+impl Socket {
+    pub fn new(ty: c_int) -> io::Result<Socket> {
+        unsafe {
+            // On linux we first attempt to pass the SOCK_CLOEXEC flag to
+            // atomically create the socket and set it as CLOEXEC. Support for
+            // this option, however, was added in 2.6.27, and we still support
+            // 2.6.18 as a kernel, so if the returned error is EINVAL we
+            // fallthrough to the fallback.
+            if cfg!(target_os = "linux") {
+                let flags = ty | SOCK_CLOEXEC | SOCK_NONBLOCK;
+                match cvt(libc::socket(libc::AF_UNIX, flags, 0)) {
+                    Ok(fd) => return Ok(Socket { fd: fd }),
+                    Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {}
+                    Err(e) => return Err(e),
+                }
+            }
+
+            let fd = Socket { fd: try!(cvt(libc::socket(libc::AF_UNIX, ty, 0))) };
+            try!(cvt(libc::ioctl(fd.fd, libc::FIOCLEX)));
+            let mut nonblocking = 1 as c_ulong;
+            try!(cvt(libc::ioctl(fd.fd, libc::FIONBIO, &mut nonblocking)));
+            Ok(fd)
+        }
+    }
+
+    pub fn pair(ty: c_int) -> io::Result<(Socket, Socket)> {
+        unsafe {
+            let mut fds = [0, 0];
+
+            // Like above, see if we can set cloexec atomically
+            if cfg!(target_os = "linux") {
+                let flags = ty | SOCK_CLOEXEC | SOCK_NONBLOCK;
+                match cvt(libc::socketpair(libc::AF_UNIX, flags, 0, fds.as_mut_ptr())) {
+                    Ok(_) => {
+                        return Ok((Socket { fd: fds[0] }, Socket { fd: fds[1] }))
+                    }
+                    Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {},
+                    Err(e) => return Err(e),
+                }
+            }
+
+            try!(cvt(libc::socketpair(libc::AF_UNIX, ty, 0, fds.as_mut_ptr())));
+            let a = Socket { fd: fds[0] };
+            let b = Socket { fd: fds[1] };
+            try!(cvt(libc::ioctl(a.fd, libc::FIOCLEX)));
+            try!(cvt(libc::ioctl(b.fd, libc::FIOCLEX)));
+            let mut nonblocking = 1 as c_ulong;
+            try!(cvt(libc::ioctl(a.fd, libc::FIONBIO, &mut nonblocking)));
+            try!(cvt(libc::ioctl(b.fd, libc::FIONBIO, &mut nonblocking)));
+            Ok((a, b))
+        }
+    }
+
+    pub fn fd(&self) -> c_int {
+        self.fd
+    }
+
+    pub fn into_fd(self) -> c_int {
+        let ret = self.fd;
+        mem::forget(self);
+        ret
+    }
+}
+
+impl Drop for Socket {
+    fn drop(&mut self) {
+        unsafe {
+            let _ = libc::close(self.fd);
+        }
+    }
+}
+
+pub unsafe fn sockaddr_un(path: &Path)
+                          -> io::Result<(libc::sockaddr_un, libc::socklen_t)> {
+    let mut addr: libc::sockaddr_un = mem::zeroed();
+    addr.sun_family = libc::AF_UNIX as libc::sa_family_t;
+
+    let bytes = path.as_os_str().as_bytes();
+
+    match (bytes.get(0), bytes.len().cmp(&addr.sun_path.len())) {
+        // Abstract paths don't need a null terminator
+        (Some(&0), Ordering::Greater) => {
+            return Err(io::Error::new(io::ErrorKind::InvalidInput,
+                                      "path must be no longer than SUN_LEN"));
+        }
+        (_, Ordering::Greater) | (_, Ordering::Equal) => {
+            return Err(io::Error::new(io::ErrorKind::InvalidInput,
+                                      "path must be shorter than SUN_LEN"));
+        }
+        _ => {}
+    }
+    for (dst, src) in addr.sun_path.iter_mut().zip(bytes.iter()) {
+        *dst = *src as libc::c_char;
+    }
+    // null byte for pathname addresses is already there because we zeroed the
+    // struct
+
+    let mut len = sun_path_offset() + bytes.len();
+    match bytes.get(0) {
+        Some(&0) | None => {}
+        Some(_) => len += 1,
+    }
+    Ok((addr, len as libc::socklen_t))
+}
+
+fn sun_path_offset() -> usize {
+    unsafe {
+        // Work with an actual instance of the type since using a null pointer is UB
+        let addr: libc::sockaddr_un = mem::uninitialized();
+        let base = &addr as *const _ as usize;
+        let path = &addr.sun_path as *const _ as usize;
+        path - base
+    }
+}
+
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio-uds/src/stream.rs
@@ -0,0 +1,189 @@
+use std::io::prelude::*;
+use std::io;
+use std::os::unix::net;
+use std::os::unix::prelude::*;
+use std::path::Path;
+use std::net::Shutdown;
+
+use libc;
+use mio::event::Evented;
+use mio::unix::EventedFd;
+use mio::{Poll, Token, Ready, PollOpt};
+
+use cvt;
+use socket::{sockaddr_un, Socket};
+
+/// A Unix stream socket.
+///
+/// This type represents a `SOCK_STREAM` connection of the `AF_UNIX` family,
+/// otherwise known as Unix domain sockets or Unix sockets. This stream is
+/// readable/writable and acts similarly to a TCP stream where reads/writes are
+/// all in order with respect to the other connected end.
+///
+/// Streams can either be connected to paths locally or another ephemeral socket
+/// created by the `pair` function.
+///
+/// A `UnixStream` implements the `Read`, `Write`, `Evented`, `AsRawFd`,
+/// `IntoRawFd`, and `FromRawFd` traits for interoperating with other I/O code.
+///
+/// Note that all values of this type are typically in nonblocking mode, so the
+/// `read` and `write` methods may return an error with the kind of
+/// `WouldBlock`, indicating that it's not ready to read/write just yet.
+#[derive(Debug)]
+pub struct UnixStream {
+    inner: net::UnixStream,
+}
+
+impl UnixStream {
+    /// Connects to the socket named by `path`.
+    ///
+    /// The socket returned may not be readable and/or writable yet, as the
+    /// connection may be in progress. The socket should be registered with an
+    /// event loop to wait on both of these properties being available.
+    pub fn connect<P: AsRef<Path>>(p: P) -> io::Result<UnixStream> {
+        UnixStream::_connect(p.as_ref())
+    }
+
+    fn _connect(path: &Path) -> io::Result<UnixStream> {
+        unsafe {
+            let (addr, len) = try!(sockaddr_un(path));
+            let socket = try!(Socket::new(libc::SOCK_STREAM));
+            let addr = &addr as *const _ as *const _;
+            match cvt(libc::connect(socket.fd(), addr, len)) {
+                Ok(_) => {}
+                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
+                Err(e) => return Err(e),
+            }
+
+            Ok(UnixStream::from_raw_fd(socket.into_fd()))
+        }
+    }
+
+    /// Consumes a standard library `UnixStream` and returns a wrapped
+    /// `UnixStream` compatible with mio.
+    ///
+    /// The returned stream is moved into nonblocking mode and is otherwise
+    /// ready to get associated with an event loop.
+    pub fn from_stream(stream: net::UnixStream) -> io::Result<UnixStream> {
+        try!(stream.set_nonblocking(true));
+        Ok(UnixStream { inner: stream })
+    }
+
+    /// Creates an unnamed pair of connected sockets.
+    ///
+    /// Returns two `UnixStream`s which are connected to each other.
+    pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
+        Socket::pair(libc::SOCK_STREAM).map(|(a, b)| unsafe {
+            (UnixStream::from_raw_fd(a.into_fd()),
+             UnixStream::from_raw_fd(b.into_fd()))
+        })
+    }
+
+    /// Creates a new independently owned handle to the underlying socket.
+    ///
+    /// The returned `UnixStream` is a reference to the same stream that this
+    /// object references. Both handles will read and write the same stream of
+    /// data, and options set on one stream will be propogated to the other
+    /// stream.
+    pub fn try_clone(&self) -> io::Result<UnixStream> {
+        self.inner.try_clone().map(|s| {
+            UnixStream { inner: s }
+        })
+    }
+
+    /// Returns the socket address of the local half of this connection.
+    pub fn local_addr(&self) -> io::Result<net::SocketAddr> {
+        self.inner.local_addr()
+    }
+
+    /// Returns the socket address of the remote half of this connection.
+    pub fn peer_addr(&self) -> io::Result<net::SocketAddr> {
+        self.inner.peer_addr()
+    }
+
+    /// Returns the value of the `SO_ERROR` option.
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        self.inner.take_error()
+    }
+
+    /// Shuts down the read, write, or both halves of this connection.
+    ///
+    /// This function will cause all pending and future I/O calls on the
+    /// specified portions to immediately return with an appropriate value
+    /// (see the documentation of `Shutdown`).
+    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
+        self.inner.shutdown(how)
+    }
+}
+
+impl Evented for UnixStream {
+    fn register(&self,
+                poll: &Poll,
+                token: Token,
+                events: Ready,
+                opts: PollOpt) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).register(poll, token, events, opts)
+    }
+
+    fn reregister(&self,
+                  poll: &Poll,
+                  token: Token,
+                  events: Ready,
+                  opts: PollOpt) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).reregister(poll, token, events, opts)
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).deregister(poll)
+    }
+}
+
+impl Read for UnixStream {
+    fn read(&mut self, bytes: &mut [u8]) -> io::Result<usize> {
+        self.inner.read(bytes)
+    }
+}
+
+impl<'a> Read for &'a UnixStream {
+    fn read(&mut self, bytes: &mut [u8]) -> io::Result<usize> {
+        (&self.inner).read(bytes)
+    }
+}
+
+impl Write for UnixStream {
+    fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
+        self.inner.write(bytes)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        self.inner.flush()
+    }
+}
+
+impl<'a> Write for &'a UnixStream {
+    fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
+        (&self.inner).write(bytes)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        (&self.inner).flush()
+    }
+}
+
+impl AsRawFd for UnixStream {
+    fn as_raw_fd(&self) -> i32 {
+        self.inner.as_raw_fd()
+    }
+}
+
+impl IntoRawFd for UnixStream {
+    fn into_raw_fd(self) -> i32 {
+        self.inner.into_raw_fd()
+    }
+}
+
+impl FromRawFd for UnixStream {
+    unsafe fn from_raw_fd(fd: i32) -> UnixStream {
+        UnixStream { inner: net::UnixStream::from_raw_fd(fd) }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio-uds/tests/echo.rs
@@ -0,0 +1,276 @@
+extern crate mio;
+extern crate tempdir;
+extern crate mio_uds;
+
+use std::io::{self, Write, Read};
+use std::io::ErrorKind::WouldBlock;
+
+use tempdir::TempDir;
+
+use mio::*;
+use mio_uds::*;
+
+macro_rules! t {
+    ($e:expr) => (match $e {
+        Ok(e) => e,
+        Err(e) => panic!("{} failed with {}", stringify!($e), e),
+    })
+}
+
+const SERVER: Token = Token(0);
+const CLIENT: Token = Token(1);
+
+struct EchoConn {
+    sock: UnixStream,
+    buf: Vec<u8>,
+    token: Option<Token>,
+    interest: Ready,
+}
+
+impl EchoConn {
+    fn new(sock: UnixStream) -> EchoConn {
+        EchoConn {
+            sock: sock,
+            buf: Vec::new(),
+            token: None,
+            interest: Ready::readable(),
+        }
+    }
+
+    fn writable(&mut self, poll: &Poll) -> io::Result<()> {
+        match self.sock.write(&self.buf) {
+            Ok(n) => {
+                assert_eq!(n, self.buf.len());
+                self.interest.insert(Ready::readable());
+                self.interest.remove(Ready::writable());
+            }
+            Err(ref e) if e.kind() == WouldBlock => {
+                self.interest.insert(Ready::writable());
+            }
+            Err(e) => panic!("not implemented; client err={:?}", e),
+        }
+
+        assert!(self.interest.is_readable() || self.interest.is_writable(),
+                "actual={:?}", self.interest);
+        poll.reregister(&self.sock, self.token.unwrap(), self.interest,
+                        PollOpt::edge() | PollOpt::oneshot())
+    }
+
+    fn readable(&mut self, poll: &Poll) -> io::Result<()> {
+        let mut buf = [0; 1024];
+
+        match self.sock.read(&mut buf) {
+            Ok(r) => {
+                self.buf = buf[..r].to_vec();
+
+                self.interest.remove(Ready::readable());
+                self.interest.insert(Ready::writable());
+            }
+            Err(ref e) if e.kind() == WouldBlock => {}
+            Err(_e) => {
+                self.interest.remove(Ready::readable());
+            }
+        }
+
+        assert!(self.interest.is_readable() || self.interest.is_writable(),
+                "actual={:?}", self.interest);
+        poll.reregister(&self.sock, self.token.unwrap(), self.interest,
+                        PollOpt::edge() | PollOpt::oneshot())
+    }
+}
+
+struct EchoServer {
+    sock: UnixListener,
+    conns: Vec<Option<EchoConn>>,
+}
+
+impl EchoServer {
+    fn accept(&mut self, poll: &Poll) -> io::Result<()> {
+        let sock = t!(self.sock.accept()).unwrap().0;
+        let conn = EchoConn::new(sock);
+        let tok = Token(self.conns.len() + 2);
+        self.conns.push(Some(conn));
+
+        // Register the connection
+        self.conn(tok).token = Some(tok);
+        t!(poll.register(&self.conn(tok).sock, tok,
+                         Ready::readable(),
+                         PollOpt::edge() | PollOpt::oneshot()));
+
+        Ok(())
+    }
+
+    fn conn_readable(&mut self, poll: &Poll, tok: Token) -> io::Result<()> {
+        self.conn(tok).readable(poll)
+    }
+
+    fn conn_writable(&mut self, poll: &Poll, tok: Token) -> io::Result<()> {
+        self.conn(tok).writable(poll)
+    }
+
+    fn conn<'a>(&'a mut self, tok: Token) -> &'a mut EchoConn {
+        self.conns[usize::from(tok) - 2].as_mut().unwrap()
+    }
+}
+
+struct EchoClient {
+    sock: UnixStream,
+    msgs: Vec<&'static str>,
+    tx: &'static [u8],
+    rx: &'static [u8],
+    token: Token,
+    interest: Ready,
+    active: bool,
+}
+
+
+// Sends a message and expects to receive the same exact message, one at a time
+impl EchoClient {
+    fn new(sock: UnixStream, tok: Token,  mut msgs: Vec<&'static str>) -> EchoClient {
+        let curr = msgs.remove(0);
+
+        EchoClient {
+            sock: sock,
+            msgs: msgs,
+            tx: curr.as_bytes(),
+            rx: curr.as_bytes(),
+            token: tok,
+            interest: Ready::empty(),
+            active: true,
+        }
+    }
+
+    fn readable(&mut self, poll: &Poll) -> io::Result<()> {
+        let mut buf = [0; 1024];
+        match self.sock.read(&mut buf) {
+            Ok(n) => {
+                assert_eq!(&self.rx[..n], &buf[..n]);
+                self.rx = &self.rx[n..];
+
+                self.interest.remove(Ready::readable());
+
+                if self.rx.len() == 0 {
+                    self.next_msg(poll).unwrap();
+                }
+            }
+            Err(ref e) if e.kind() == WouldBlock => {}
+            Err(e) => panic!("error {}", e),
+        }
+
+        if !self.interest.is_empty() {
+            assert!(self.interest.is_readable() || self.interest.is_writable(),
+                    "actual={:?}", self.interest);
+            try!(poll.reregister(&self.sock, self.token, self.interest,
+                                 PollOpt::edge() | PollOpt::oneshot()));
+        }
+
+        Ok(())
+    }
+
+    fn writable(&mut self, poll: &Poll) -> io::Result<()> {
+        match self.sock.write(self.tx) {
+            Ok(r) => {
+                self.tx = &self.tx[r..];
+                self.interest.insert(Ready::readable());
+                self.interest.remove(Ready::writable());
+            }
+            Err(ref e) if e.kind() == WouldBlock => {
+                self.interest.insert(Ready::writable());
+            }
+            Err(e) => panic!("not implemented; client err={:?}", e)
+        }
+
+        assert!(self.interest.is_readable() || self.interest.is_writable(),
+                "actual={:?}", self.interest);
+        poll.reregister(&self.sock, self.token, self.interest,
+                        PollOpt::edge() | PollOpt::oneshot())
+    }
+
+    fn next_msg(&mut self, poll: &Poll) -> io::Result<()> {
+        if self.msgs.is_empty() {
+            self.active = false;
+            return Ok(());
+        }
+
+        let curr = self.msgs.remove(0);
+
+        self.tx = curr.as_bytes();
+        self.rx = curr.as_bytes();
+
+        self.interest.insert(Ready::writable());
+        assert!(self.interest.is_readable() || self.interest.is_writable(),
+                "actual={:?}", self.interest);
+        poll.reregister(&self.sock, self.token, self.interest,
+                        PollOpt::edge() | PollOpt::oneshot())
+    }
+}
+
+struct Echo {
+    server: EchoServer,
+    client: EchoClient,
+}
+
+impl Echo {
+    fn new(srv: UnixListener, client: UnixStream, msgs: Vec<&'static str>) -> Echo {
+        Echo {
+            server: EchoServer {
+                sock: srv,
+                conns: Vec::new(),
+            },
+            client: EchoClient::new(client, CLIENT, msgs)
+        }
+    }
+
+    fn ready(&mut self,
+             poll: &Poll,
+             token: Token,
+             events: Ready) {
+        println!("ready {:?} {:?}", token, events);
+        if events.is_readable() {
+            match token {
+                SERVER => self.server.accept(poll).unwrap(),
+                CLIENT => self.client.readable(poll).unwrap(),
+                i => self.server.conn_readable(poll, i).unwrap()
+            }
+        }
+
+        if events.is_writable() {
+            match token {
+                SERVER => panic!("received writable for token 0"),
+                CLIENT => self.client.writable(poll).unwrap(),
+                _ => self.server.conn_writable(poll, token).unwrap()
+            }
+        }
+    }
+}
+
+#[test]
+fn echo_server() {
+    let tmp_dir = t!(TempDir::new("mio-uds"));
+    let addr = tmp_dir.path().join("sock");
+
+    let poll = t!(Poll::new());
+    let mut events = Events::with_capacity(1024);
+
+    let srv = t!(UnixListener::bind(&addr));
+    t!(poll.register(&srv,
+                     SERVER,
+                     Ready::readable(),
+                     PollOpt::edge() | PollOpt::oneshot()));
+
+    let sock = t!(UnixStream::connect(&addr));
+    t!(poll.register(&sock,
+                     CLIENT,
+                     Ready::writable(),
+                     PollOpt::edge() | PollOpt::oneshot()));
+
+    let mut echo = Echo::new(srv, sock, vec!["foo", "bar"]);
+    while echo.client.active {
+        t!(poll.poll(&mut events, None));
+
+        for i in 0..events.len() {
+            let event = events.get(i).unwrap();
+            echo.ready(&poll, event.token(), event.readiness());
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio-uds/tests/smoke.rs
@@ -0,0 +1,66 @@
+extern crate mio;
+extern crate tempdir;
+extern crate mio_uds;
+
+use std::io::prelude::*;
+use std::time::Duration;
+
+use mio::*;
+use mio_uds::*;
+use tempdir::TempDir;
+
+macro_rules! t {
+    ($e:expr) => (match $e {
+        Ok(e) => e,
+        Err(e) => panic!("{} failed with {}", stringify!($e), e),
+    })
+}
+
+#[test]
+fn listener() {
+    let td = t!(TempDir::new("uds"));
+    let a = t!(UnixListener::bind(td.path().join("foo")));
+    assert!(t!(a.accept()).is_none());
+    t!(a.local_addr());
+    assert!(t!(a.take_error()).is_none());
+    let b = t!(a.try_clone());
+    assert!(t!(b.accept()).is_none());
+
+    let poll = t!(Poll::new());
+    let mut events = Events::with_capacity(1024);
+
+    t!(poll.register(&a, Token(1), Ready::readable(), PollOpt::edge()));
+
+    let s = t!(UnixStream::connect(td.path().join("foo")));
+
+    assert_eq!(t!(poll.poll(&mut events, None)), 1);
+
+    let (s2, addr) = t!(a.accept()).unwrap();
+
+    assert_eq!(t!(s.peer_addr()).as_pathname(), t!(s2.local_addr()).as_pathname());
+    assert_eq!(t!(s.local_addr()).as_pathname(), t!(s2.peer_addr()).as_pathname());
+    assert_eq!(addr.as_pathname(), t!(s.local_addr()).as_pathname());
+}
+
+#[test]
+fn stream() {
+    let poll = t!(Poll::new());
+    let mut events = Events::with_capacity(1024);
+    let (mut a, mut b) = t!(UnixStream::pair());
+
+    let both = Ready::readable() | Ready::writable();
+    t!(poll.register(&a, Token(1), both, PollOpt::edge()));
+    t!(poll.register(&b, Token(2), both, PollOpt::edge()));
+
+    assert_eq!(t!(poll.poll(&mut events, Some(Duration::new(0, 0)))), 2);
+    assert_eq!(events.get(0).unwrap().readiness(), Ready::writable());
+    assert_eq!(events.get(1).unwrap().readiness(), Ready::writable());
+
+    assert_eq!(t!(a.write(&[3])), 1);
+
+    assert_eq!(t!(poll.poll(&mut events, Some(Duration::new(0, 0)))), 1);
+    assert!(events.get(0).unwrap().readiness().is_readable());
+    assert_eq!(events.get(0).unwrap().token(), Token(2));
+
+    assert_eq!(t!(b.read(&mut [0; 1024])), 1);
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","CHANGELOG.md":"859b996b1d16ad6025c86d6d723f9db687dbe69fc15f85bf5a5dbeb1cdf89145","Cargo.toml":"1e24366fa1469647457574af270b42bfc3eccf92f92c04c81f8cf54682fceadf","LICENSE":"07919255c7e04793d8ea760d6c2ce32d19f9ff02bdbdde3ce90b1e1880929a9b","README.md":"18c1685d784a5ce3a02f9019b1e9f85035e8061bd78fdbeded57f53cc5860171","appveyor.yml":"d270d3d60d368e4dc62bb87c17fc407b524d441fdf69eff27090a6043e50d342","benches/bench_poll.rs":"ab1e38ad309d58f4c1924fdef1868fd6b899536959f08d2f33247f057c8962d0","ci/docker/aarch64-linux-android/Dockerfile":"350e18f37e45f8332e802d32e7c05c824fdaf441174c8bc5fb5602865f85b516","ci/docker/aarch64-linux-android/accept-licenses.sh":"b425a5561694c3bf065ef10a00f904c2536e63d6b11782e35a567f2808118ef2","ci/docker/aarch64-linux-android/cargo_config":"ef57da8986b41bbca9ca77d2dbceb857185d341dbb3d97a3f95cc680467e4985","ci/docker/aarch64-linux-android/install-ndk.sh":"e9e58a151ba4f71e7c23fca256bebd9b8a5ed1b3161c6154a634870174f33484","ci/docker/aarch64-linux-android/install-sdk.sh":"e068d8f16bc6297613f3de7bfab72c803594f44edaab7e546d6d8f393389b72b","ci/docker/arm-linux-androideabi/Dockerfile":"c6f153172df91bc5c7d3a859f8970ce54e1cc5c92ab295c1c9cf91c81a49fd51","ci/docker/arm-linux-androideabi/accept-licenses.sh":"84ad00815f628005ed22c5d6cd14990ebc97812a7163bd275b2877904eddab53","ci/docker/arm-linux-androideabi/cargo_config":"ec54caa043c093c699cfb3a1cc3dc35651039b50e29fb416b43f3f4dbd778397","ci/docker/arm-linux-androideabi/install-ndk.sh":"eef063bb01a16c0f90471dbce1b5a395b53141d7704e15a3c9a1c4fc5e06d4b1","ci/docker/arm-linux-androideabi/install-sdk.sh":"42c04b17c4a35bef58757332e960a6e4aba1b5e41f8fc0182265163ff93f6182","ci/ios/deploy_and_run_on_ios_simulator.rs":"977ed5ee02864e85b5583d61549865c72e70c16e62d5b4d3ea1fe486609c193e","ci/run-docker.sh":"7f6c68dbca93788111170ac4678608957a179e76cfe8c5a51d11dfea1742d7f2","ci/run-ios.sh":"2a3069d5378a8e1fdae3aeb79fda490da5b0e5c0e6c775edf37d93986305463a","ci/run.sh":"f496e9d3506aee0c26e00407a2658ada83b736ca50f4b159af219e53c3fe3acf","ci/trust/install.sh":"8b165fc99df296261fcc9cdcbc8b8a177c11c505cdc9255cc19efb66cb0055db","ci/trust/script.sh":"d5d581703524b4b770ad99d5beed4d68733e16497a50b4d0f416115526dae319","src/channel.rs":"e76baed95be4ab4af050ba731916d2a3a03057d145e68f053571e7b8ae277c28","src/deprecated/event_loop.rs":"8432e097e29a0237e6187dfaff2782f077d8c44da4fffcdb83c7991958fbd920","src/deprecated/handler.rs":"13cbc0c193f43a331e125e05d5eddf3712fe86e41a8721186d3672518ef8a9cc","src/deprecated/io.rs":"4948217ffeeba4f508cc89744da5d6af858b4ad7b4be23f927a00df93bdf2984","src/deprecated/mod.rs":"504d718e7c786c69619d27d5b6302ffca3f174b7ffba1bcd72b58e7bac8d83c6","src/deprecated/notify.rs":"8cb108387ebcfb75764e4dd2868d80eb00d793c4b7c867c08cd86ef10b91b023","src/deprecated/unix.rs":"771cf2f475f7655b8b0918d907f78acce6f729f4eb608f657f1af0e5d50ab641","src/event_imp.rs":"374ddc5ccf439bf3c8c02b3796af5bc39bbb4ee8156534752cbe63743d659802","src/io.rs":"26d42aee058dc7a94e1b6fc6f29b34d6f70029fcbf6809574b5758b0c1afd905","src/lib.rs":"979fc24e9013a2672d75b097781ac699f5f88e06455cbec65f8ef1d088e358fa","src/net/mod.rs":"340c63a8efe9ee774b7bf8ed8c0f72fc7563e5c4b35f6a8b243f92d366e145a2","src/net/tcp.rs":"73b8e98f9e474fadf8193a2b3b9cb50743d97d8e27749c063918908d28012d54","src/net/udp.rs":"2d9e4a7eb3c30e36c3ca0b38d572c0eb9006c7602a339e72c19de823f5452a95","src/poll.rs":"08129340bd814e1d2b7fad64641d0dd2a2b6862640309ae68f489a4471b046ec","src/sys/mod.rs":"e6d068be2ed80e56d768aac8ae59886db0f2c8e53f1319b03b02ff35aa031ba7","src/sys/unix/awakener.rs":"7efbec6de6562cc3dcd641f224d466403e1435334e5ad2a82c967ed5a9c30345","src/sys/unix/dlsym.rs":"559337d1f6c10e6c1172bd3908a9dcfa5a0828b53b04f7ca3a0d926afa85cd63","src/sys/unix/epoll.rs":"558cd0dd23afd43a655a778b8b7e876a2372d05a9a132b8a6547c3091c7c00c6","src/sys/unix/eventedfd.rs":"c12f916ed98930ccacb1c15d0d3ea49eb85f872e4127e1bddabb3875ac16ab38","src/sys/unix/io.rs":"5e3c48ef5cd8e3aa2bd6831eea5f9578e82a84c092add7b042675c1c0f01cad1","src/sys/unix/kqueue.rs":"567399be003ac7007e0f068856ebb402382f52c7ffef5b5044edd0290f890a80","src/sys/unix/mod.rs":"dc8bece30046f5cdb25ace072a836b6b3a085eb91c64017b3242c368aa221ef1","src/sys/unix/ready.rs":"152561f335330c8cdce65f9bcc1018e76def6180e45b26e76fa71c41625067bf","src/sys/unix/tcp.rs":"08d2617e3bb172b258d9ee56f46304fa5abd6937f9fa29289a0d9af809a25750","src/sys/unix/udp.rs":"3bedb61c9ee9966f64a6a1ba715bf64e906fc5b118bf1903d7f8aeb2931cfccd","src/sys/unix/uds.rs":"5126490860d2c980e94abc9326dd67473411b20b380aadaeeabc450571e21427","src/sys/windows/awakener.rs":"ea7dcd0370a673421f58a2d804c8da9a7f159dca1a0af87e006ac0df3d3ffa74","src/sys/windows/buffer_pool.rs":"636f4b7510a507f9985987699ce8ec140b2ed852abb231443ee1486c80759eed","src/sys/windows/from_raw_arc.rs":"c2cee14a0355256beb55a1feb54ccdcc50c8ab2d9abb3b7f114be00ed8a5583f","src/sys/windows/mod.rs":"d3b2bf7dd9011e3930d2712aa990b9599bf4060572dc4296f123eb3908ad58ab","src/sys/windows/selector.rs":"b13c9bcba172887f6fef1dffd6e5511489329f7640dd0c9a4e34bb2973bda883","src/sys/windows/tcp.rs":"b0591fc3c89d163129e9c6dbfb1b04a19edc759036e1e66bac54416944ede785","src/sys/windows/udp.rs":"d4cfefee1091d5712cc133eec9c21aafdea9f9959f1384453d1b61c6ea5e8fb5","src/timer.rs":"13c386666720e3e85cfdd5807e098396958e94980e22a21a1b706e69093fab76","src/token.rs":"9fea166777a6fd70b902ee96e395da71f41156f82f923087e61a56b3d1af641e","src/udp.rs":"a02e64c8bb585e6b8637666260809bd9ed708bef0f84bab2d46ca8655e76a03b"},"package":"9e965267d4d58496fc4f740e9861118367f13570cadf66316ed2c3f2f14d87c7"}
\ No newline at end of file
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/CHANGELOG.md
@@ -0,0 +1,128 @@
+# 0.6.9 (June 7, 2017)
+
+* More socket options are exposed through the TCP types, brought in through the
+  `net2` crate.
+
+# 0.6.8 (May 26, 2017)
+
+* Support Fuchia
+* POSIX AIO support
+* Fix memory leak caused by Register::new2
+* Windows: fix handling failed TCP connections
+* Fix build on aarch64-linux-android
+* Fix usage of `O_CLOEXEC` with `SETFL`
+
+# 0.6.7 (April 27, 2017)
+
+* Ignore EPIPE coming out of `kevent`
+* Timer thread should exit when timer is dropped.
+
+# 0.6.6 (March 22, 2017)
+
+* Add send(), recv() and connect() to UDPSocket.
+* Fix bug in custom readiness queue
+* Move net types into `net` module
+
+# 0.6.5 (March 14, 2017)
+
+* Misc improvements to kqueue bindings
+* Add official support for iOS, Android, BSD
+* Reimplement custom readiness queue
+* `Poll` is now `Sync`
+* Officially deprecate non-core functionality (timers, channel, etc...)
+* `Registration` now implements `Evented`
+* Fix bug around error conditions with `connect` on windows.
+* Use iovec crate for scatter / gather operations
+* Only support readable and writable readiness on all platforms
+* Expose additional readiness in a platform specific capacity
+
+# 0.6.4 (January 24, 2017)
+
+* Fix compilation on musl
+* Add `TcpStream::from_stream` which conversts a std TCP stream to Mio.
+
+# 0.6.3 (January 22, 2017)
+
+* Implement readv/writev for `TcpStream`, allowing vectored reads/writes to
+  work across platforms
+* Remove `nix` dependency
+* Implement `Display` and `Error` for some channel error types.
+* Optimize TCP on Windows through `SetFileCompletionNotificationModes`
+
+# 0.6.2 (December 18, 2016)
+
+* Allow registration of custom handles on Windows (like `EventedFd` on Unix)
+* Send only one byte for the awakener on Unix instead of four
+* Fix a bug in the timer implementation which caused an infinite loop
+
+# 0.6.1 (October 30, 2016)
+
+* Update dependency of `libc` to 0.2.16
+* Fix channel `dec` logic
+* Fix a timer bug around timeout cancellation
+* Don't allocate buffers for TCP reads on Windows
+* Touched up documentation in a few places
+* Fix an infinite looping timer thread on OSX
+* Fix compile on 32-bit OSX
+* Fix compile on FreeBSD
+
+# 0.6.0 (September 2, 2016)
+
+* Shift primary API towards `Poll`
+* `EventLoop` and types to `deprecated` mod. All contents of the
+  `deprecated` mod will be removed by Mio 1.0.
+* Increase minimum supported Rust version to 1.9.0
+* Deprecate unix domain socket implementation in favor of using a
+  version external to Mio. For example: https://github.com/alexcrichton/mio-uds.
+* Remove various types now included in `std`
+* Updated TCP & UDP APIs to match the versions in `std`
+* Enable implementing `Evented` for any type via `Registration`
+* Rename `IoEvent` -> `Event`
+* Access `Event` data via functions vs. public fields.
+* Expose `Events` as a public type that is passed into `Poll`
+* Use `std::time::Duration` for all APIs that require a time duration.
+* Polled events are now retrieved via `Events` type.
+* Implement `std::error::Error` for `TimerError`
+* Relax `Send` bound on notify messages.
+* Remove `Clone` impl for `Timeout` (future proof)
+* Remove `mio::prelude`
+* Remove `mio::util`
+* Remove dependency on bytes
+
+# 0.5.0 (December 3, 2015)
+
+* Windows support (#239)
+* NetBSD support (#306)
+* Android support (#295)
+* Don't re-export bytes types
+* Renamed `EventLoop::register_opt` to `EventLoop::register` (#257)
+* `EventLoopConfig` is now a builder instead of having public struct fields. It
+  is also no longer `Copy`. (#259)
+* `TcpSocket` is no longer exported in the public API (#262)
+* Integrate with net2. (#262)
+* `TcpListener` now returns the remote peer address from `accept` as well (#275)
+* The `UdpSocket::{send_to, recv_from}` methods are no longer generic over `Buf`
+  or `MutBuf` but instead take slices directly. The return types have also been
+  updated to return the number of bytes transferred. (#260)
+* Fix bug with kqueue where an error on registration prevented the
+  changelist from getting flushed (#276)
+* Support sending/receiving FDs over UNIX sockets (#291)
+* Mio's socket types are permanently associated with an EventLoop (#308)
+* Reduce unnecessary poll wakeups (#314)
+
+
+# 0.4.1 (July 21, 2015)
+
+* [BUGFIX] Fix notify channel concurrency bug (#216)
+
+# 0.4.0 (July 16, 2015)
+
+* [BUGFIX] EventLoop::register requests all events, not just readable.
+* [BUGFIX] Attempting to send a message to a shutdown event loop fails correctly.
+* [FEATURE] Expose TCP shutdown
+* [IMPROVEMENT] Coalesce readable & writable into `ready` event (#184)
+* [IMPROVEMENT] Rename TryRead & TryWrite function names to avoid conflict with std.
+* [IMPROVEMENT] Provide TCP and UDP types in mio (path to windows #155)
+* [IMPROVEMENT] Use clock_ticks crate instead of time (path to windows #155)
+* [IMPROVEMENT] Move unix specific features into mio::unix module
+* [IMPROVEMENT] TcpListener sets SO_REUSEADDR by default
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/Cargo.toml
@@ -0,0 +1,47 @@
+[package]
+
+name          = "mio"
+version       = "0.6.9"
+license       = "MIT"
+authors       = ["Carl Lerche <me@carllerche.com>"]
+description   = "Lightweight non-blocking IO"
+documentation = "https://docs.rs/mio"
+homepage      = "https://github.com/carllerche/mio"
+repository    = "https://github.com/carllerche/mio"
+readme        = "README.md"
+keywords      = ["io", "async", "non-blocking"]
+categories    = ["asynchronous"]
+exclude       = [
+  ".gitignore",
+  ".travis.yml",
+  "deploy.sh",
+  "test/**/*",
+]
+
+[features]
+with-deprecated = []
+default = ["with-deprecated"]
+
+[dependencies]
+lazycell = "0.4.0"
+log      = "0.3.1"
+slab     = "0.3.0"
+net2     = "0.2.29"
+iovec    = "0.1.0"
+
+[target.'cfg(unix)'.dependencies]
+libc   = "0.2.19"
+
+[target.'cfg(windows)'.dependencies]
+winapi = "0.2.1"
+miow   = "0.2.1"
+kernel32-sys = "0.2"
+
+[dev-dependencies]
+env_logger = { version = "0.3.0", default-features = false }
+tempdir    = "0.3.4"
+bytes      = "0.3.0"
+
+[[test]]
+name = "test"
+path = "test/mod.rs"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2014 Carl Lerche and other MIO contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/README.md
@@ -0,0 +1,89 @@
+# Mio - Metal IO
+
+Mio is a lightweight I/O library for Rust with a focus on adding as little
+overhead as possible over the OS abstractions.
+
+[![crates.io](http://meritbadge.herokuapp.com/mio)](https://crates.io/crates/mio)
+[![Build Status](https://travis-ci.org/carllerche/mio.svg?branch=master)](https://travis-ci.org/carllerche/mio)
+[![Build status](https://ci.appveyor.com/api/projects/status/ok90r1tcgkyndnvw/branch/master?svg=true)](https://ci.appveyor.com/project/carllerche/mio/branch/master)
+
+**API documentation**
+
+* [master](http://carllerche.github.io/mio)
+* [v0.6](https://docs.rs/mio/^0.6)
+* [v0.5](https://docs.rs/mio/^0.5)
+
+This is a low level library, if you are looking for something easier to get
+started with, see [Tokio](https://tokio.rs).
+
+## Usage
+
+To use `mio`, first add this to your `Cargo.toml`:
+
+```toml
+[dependencies]
+mio = "0.6"
+```
+
+Then, add this to your crate root:
+
+```rust
+extern crate mio;
+```
+
+## Features
+
+* Event loop backed by epoll, kqueue.
+* Zero allocations at runtime
+* Non-blocking TCP, UDP and Unix domain sockets
+* High performance timer system
+* Thread safe message channel for cross thread communication
+
+## Non goals
+
+The following are specifically omitted from MIO and are left to the user
+or higher level libraries.
+
+* File operations
+* Thread pools / multi-threaded event loop
+
+## Platforms
+
+Currently supported platforms:
+
+* Linux
+* OS X
+* Windows
+* NetBSD
+* Android
+* iOS
+
+There are potentially others. If you find that Mio works on another
+platform, submit a PR to update the list!
+
+### Libraries
+
+* [tokio-core](//github.com/tokio-rs/tokio-core) - Underlying event loop
+  for the [Tokio project](//github.com/tokio-rs/tokio).
+* [mioco](//github.com/dpc/mioco) - Mio COroutines
+* [simplesched](//github.com/zonyitoo/simplesched) - Coroutine I/O with a simple scheduler
+* [coio-rs](//github.com/zonyitoo/coio-rs) - Coroutine I/O with work-stealing scheduler
+* [rotor](//github.com/tailhook/rotor) - A wrapper that allows to create composable I/O libraries on top of mio
+* [ws-rs](//github.com/housleyjk/ws-rs) - WebSockets based on Mio
+
+## Community
+
+A group of mio users hang out in the #mio channel on the Mozilla IRC
+server (irc.mozilla.org). This can be a good place to go for questions.
+
+## Contributing
+
+Interested in getting involved? We would love to help you! For simple
+bug fixes, just submit a PR with the fix and we can discuss the fix
+directly in the PR. If the fix is more complex, start with an issue.
+
+If you want to propose an API change, create an issue to start a
+discussion with the community. Also, feel free to talk with us in the
+IRC channel.
+
+Finally, be kind. We support the [Rust Code of Conduct](https://www.rust-lang.org/conduct.html).
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/appveyor.yml
@@ -0,0 +1,20 @@
+environment:
+  matrix:
+  - TARGET: x86_64-pc-windows-msvc
+  - TARGET: i686-pc-windows-msvc
+  - TARGET: i686-pc-windows-gnu
+
+install:
+  - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe"
+  - rust-nightly-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
+  - SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin
+  - SET PATH=%PATH%;C:\MinGW\bin
+  - rustc -V
+  - cargo -V
+
+build: false
+
+test_script:
+  # Ensure that the build works without default features
+  - cargo build --no-default-features
+  - cargo test
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/benches/bench_poll.rs
@@ -0,0 +1,52 @@
+#![feature(test)]
+
+extern crate mio;
+extern crate test;
+
+use mio::*;
+use test::Bencher;
+use std::sync::Arc;
+use std::thread;
+
+#[bench]
+fn bench_poll(bench: &mut Bencher) {
+    const NUM: usize = 10_000;
+    const THREADS: usize = 4;
+
+    let poll = Poll::new().unwrap();
+    let mut events = Events::with_capacity(1024);
+
+    let mut registrations = vec![];
+    let mut set_readiness = vec![];
+
+    for i in 0..NUM {
+        let (r, s) = Registration::new(
+            &poll,
+            Token(i),
+            Ready::readable(),
+            PollOpt::edge());
+
+        registrations.push(r);
+        set_readiness.push(s);
+    }
+
+    let set_readiness = Arc::new(set_readiness);
+
+    bench.iter(move || {
+        for mut i in 0..THREADS {
+            let set_readiness = set_readiness.clone();
+            thread::spawn(move || {
+                while i < NUM {
+                    set_readiness[i].set_readiness(Ready::readable()).unwrap();
+                    i += THREADS;
+                }
+            });
+        }
+
+        let mut n = 0;
+
+        while n < NUM {
+            n += poll.poll(&mut events, None).unwrap();
+        }
+    })
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/ci/docker/aarch64-linux-android/Dockerfile
@@ -0,0 +1,48 @@
+FROM ubuntu:16.04
+
+
+
+
+
+RUN dpkg --add-architecture i386 && \
+    dpkg --add-architecture amd64 && \
+    apt-get update && \
+    apt-get install -y --no-install-recommends \
+  file \
+  curl \
+  ca-certificates \
+  python \
+  unzip \
+  expect \
+  openjdk-9-jre \
+  libstdc++6:i386 \
+  gcc \
+  libc6-dev \
+  qt5-default zlib1g:i386 libx11-6:i386 \
+  libpulse0:amd64 libpulse0:i386
+
+
+
+
+
+
+COPY cargo_config /etc/cargo_config
+
+WORKDIR /android/
+
+COPY install-ndk.sh /android/
+RUN sh /android/install-ndk.sh
+
+ENV PATH=$PATH:/android/ndk-arm64/bin:/android/sdk/tools:/android/sdk/tools/bin:/android/sdk/platform-tools:/android/sdk/emulator/qemu/linux-x86_64
+
+COPY install-sdk.sh /android/
+RUN sh /android/install-sdk.sh
+
+ENV PATH=$PATH:/rust/bin \
+    CARGO_TARGET_ARM_LINUX_ANDROIDEABI_LINKER=aarch64-linux-android-gcc \
+    ANDROID_EMULATOR_FORCE_32BIT=0 \
+    HOME=/tmp
+RUN chmod 755 /android/sdk/tools/* /android/sdk/emulator/qemu/linux-x86_64/*
+
+RUN cp -r /root/.android /tmp
+RUN chmod 777 -R /tmp/.android
new file mode 100755
--- /dev/null
+++ b/third_party/rust/mio/ci/docker/aarch64-linux-android/accept-licenses.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/expect -f
+# ignore-license
+
+set timeout 1800
+set cmd [lindex $argv 0]
+set licenses [lindex $argv 1]
+
+spawn {*}$cmd
+expect {
+  "Accept? (y/N):*" {
+        exp_send "y\r"
+        exp_continue
+  }
+  eof
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/ci/docker/aarch64-linux-android/cargo_config
@@ -0,0 +1,16 @@
+
+[target.aarch64-linux-android]
+ar = "/android/ndk-arm64/bin/aarch64-linux-android-ar"
+linker = "/android/ndk-arm64/bin/aarch64-linux-android-gcc"
+
+[target.arm-linux-androideabi]
+ar = "/android/ndk-arm64/bin/arm-linux-androideabi-ar"
+linker = "/android/ndk-arm64/bin/arm-linux-androideabi-gcc"
+
+[target.armv7-linux-androideabi]
+ar = "/android/ndk-arm64/bin/arm-linux-androideabi-ar"
+linker = "/android/ndk-arm64/bin/arm-linux-androideabi-gcc"
+
+[target.i686-linux-android]
+ar = "/android/ndk-arm64/bin/i686-linux-android-ar"
+linker = "/android/ndk-arm64/bin/i686-linux-android-gcc"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/ci/docker/aarch64-linux-android/install-ndk.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+# Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+# file at the top-level directory of this distribution and at
+# http://rust-lang.org/COPYRIGHT.
+#
+# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+# option. This file may not be copied, modified, or distributed
+# except according to those terms.
+
+set -ex
+
+curl -O https://dl.google.com/android/repository/android-ndk-r14b-linux-x86_64.zip
+unzip -q android-ndk-r14b-linux-x86_64.zip
+android-ndk-r14b/build/tools/make_standalone_toolchain.py \
+        --install-dir /android/ndk-arm64 \
+        --arch arm64 \
+        --api 24
+
+rm -rf ./android-ndk-r14b-linux-x86_64.zip ./android-ndk-r14b
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/ci/docker/aarch64-linux-android/install-sdk.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+# Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+# file at the top-level directory of this distribution and at
+# http://rust-lang.org/COPYRIGHT.
+#
+# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+# option. This file may not be copied, modified, or distributed
+# except according to those terms.
+
+set -ex
+
+# Prep the SDK and emulator
+#
+# Note that the update process requires that we accept a bunch of licenses, and
+# we can't just pipe `yes` into it for some reason, so we take the same strategy
+# located in https://github.com/appunite/docker by just wrapping it in a script
+# which apparently magically accepts the licenses.
+
+mkdir sdk
+
+curl -o sdk-tools-linux-3859397.zip https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip && \
+    unzip sdk-tools-linux-3859397.zip && \
+    mv tools sdk/
+
+
+
+yes | sdkmanager --licenses
+sdkmanager tools platform-tools "build-tools;25.0.2" "platforms;android-24" "system-images;android-24;default;arm64-v8a"
+
+echo "no" | avdmanager create avd \
+                --force \
+                --name arm64-24 \
+                --package "system-images;android-24;default;arm64-v8a" \
+                --abi arm64-v8a \
+                --sdcard 256M
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/ci/docker/arm-linux-androideabi/Dockerfile
@@ -0,0 +1,37 @@
+FROM ubuntu:16.04
+
+RUN dpkg --add-architecture i386 && \
+    apt-get update && \
+    apt-get install -y --no-install-recommends \
+  file \
+  curl \
+  ca-certificates \
+  python \
+  unzip \
+  expect \
+  openjdk-9-jre \
+  libstdc++6:i386 \
+  gcc \
+  libc6-dev
+
+
+COPY cargo_config /etc/cargo_config
+
+WORKDIR /android/
+
+COPY install-ndk.sh /android/
+RUN sh /android/install-ndk.sh
+
+ENV PATH=$PATH:/android/ndk-arm/bin:/android/sdk/tools:/android/sdk/platform-tools
+
+COPY install-sdk.sh accept-licenses.sh /android/
+RUN sh /android/install-sdk.sh
+
+ENV PATH=$PATH:/rust/bin \
+    CARGO_TARGET_ARM_LINUX_ANDROIDEABI_LINKER=arm-linux-androideabi-gcc \
+    ANDROID_EMULATOR_FORCE_32BIT=1 \
+    HOME=/tmp
+RUN chmod 755 /android/sdk/tools/* /android/sdk/tools/qemu/linux-x86_64/* /android/sdk/tools/qemu/linux-x86/*
+
+RUN cp -r /root/.android /tmp
+RUN chmod 777 -R /tmp/.android
new file mode 100755
--- /dev/null
+++ b/third_party/rust/mio/ci/docker/arm-linux-androideabi/accept-licenses.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/expect -f
+# ignore-license
+
+set timeout 1800
+set cmd [lindex $argv 0]
+set licenses [lindex $argv 1]
+
+spawn {*}$cmd
+expect {
+  "Do you accept the license '*'*" {
+        exp_send "y\r"
+        exp_continue
+  }
+  eof
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/ci/docker/arm-linux-androideabi/cargo_config
@@ -0,0 +1,16 @@
+
+[target.aarch64-linux-android]
+ar = "/android/ndk-arm/bin/aarch64-linux-android-ar"
+linker = "/android/ndk-arm/bin/aarch64-linux-android-gcc"
+
+[target.arm-linux-androideabi]
+ar = "/android/ndk-arm/bin/arm-linux-androideabi-ar"
+linker = "/android/ndk-arm/bin/arm-linux-androideabi-gcc"
+
+[target.armv7-linux-androideabi]
+ar = "/android/ndk-arm/bin/arm-linux-androideabi-ar"
+linker = "/android/ndk-arm/bin/arm-linux-androideabi-gcc"
+
+[target.i686-linux-android]
+ar = "/android/ndk-arm/bin/i686-linux-android-ar"
+linker = "/android/ndk-arm/bin/i686-linux-android-gcc"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/ci/docker/arm-linux-androideabi/install-ndk.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+# Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+# file at the top-level directory of this distribution and at
+# http://rust-lang.org/COPYRIGHT.
+#
+# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+# option. This file may not be copied, modified, or distributed
+# except according to those terms.
+
+set -ex
+
+curl -O https://dl.google.com/android/repository/android-ndk-r13b-linux-x86_64.zip
+unzip -q android-ndk-r13b-linux-x86_64.zip
+android-ndk-r13b/build/tools/make_standalone_toolchain.py \
+        --install-dir /android/ndk-arm \
+        --arch arm \
+        --api 24
+
+rm -rf ./android-ndk-r13b-linux-x86_64.zip ./android-ndk-r13b
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/ci/docker/arm-linux-androideabi/install-sdk.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+# Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+# file at the top-level directory of this distribution and at
+# http://rust-lang.org/COPYRIGHT.
+#
+# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+# option. This file may not be copied, modified, or distributed
+# except according to those terms.
+
+set -ex
+
+# Prep the SDK and emulator
+#
+# Note that the update process requires that we accept a bunch of licenses, and
+# we can't just pipe `yes` into it for some reason, so we take the same strategy
+# located in https://github.com/appunite/docker by just wrapping it in a script
+# which apparently magically accepts the licenses.
+
+mkdir sdk
+curl https://dl.google.com/android/android-sdk_r24.4.1-linux.tgz | \
+    tar xzf - -C sdk --strip-components=1
+
+filter="platform-tools,android-21"
+filter="$filter,sys-img-armeabi-v7a-android-21"
+
+./accept-licenses.sh "android - update sdk -a --no-ui --filter $filter"
+
+echo "no" | android create avd \
+                --name arm-21 \
+                --target android-21 \
+                --abi armeabi-v7a
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/ci/ios/deploy_and_run_on_ios_simulator.rs
@@ -0,0 +1,202 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This is a script to deploy and execute a binary on an iOS simulator.
+// The primary use of this is to be able to run unit tests on the simulator and
+// retrieve the results.
+//
+// To do this through Cargo instead, use Dinghy
+// (https://github.com/snipsco/dinghy): cargo dinghy install, then cargo dinghy
+// test.
+
+use std::env;
+use std::fs::{self, File};
+use std::io::Write;
+use std::path::Path;
+use std::thread;
+use std::process::{self, Command, Stdio};
+
+macro_rules! t {
+    ($e:expr) => (match $e {
+        Ok(e) => e,
+        Err(e) => panic!("{} failed with: {}", stringify!($e), e),
+    })
+}
+
+// Step one: Wrap as an app
+fn package_as_simulator_app(crate_name: &str, test_binary_path: &Path) {
+    println!("Packaging simulator app");
+    drop(fs::remove_dir_all("ios_simulator_app"));
+    t!(fs::create_dir("ios_simulator_app"));
+    t!(fs::copy(test_binary_path,
+                Path::new("ios_simulator_app").join(crate_name)));
+
+    let mut f = t!(File::create("ios_simulator_app/Info.plist"));
+    t!(f.write_all(format!(r#"
+        <?xml version="1.0" encoding="UTF-8"?>
+        <!DOCTYPE plist PUBLIC
+                "-//Apple//DTD PLIST 1.0//EN"
+                "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+        <plist version="1.0">
+            <dict>
+                <key>CFBundleExecutable</key>
+                <string>{}</string>
+                <key>CFBundleIdentifier</key>
+                <string>com.rust.unittests</string>
+            </dict>
+        </plist>
+    "#, crate_name).as_bytes()));
+}
+
+// Step two: Start the iOS simulator
+fn start_simulator() {
+    println!("Looking for iOS simulator");
+    let output = t!(Command::new("xcrun").arg("simctl").arg("list").output());
+    assert!(output.status.success());
+    let mut simulator_exists = false;
+    let mut simulator_booted = false;
+    let mut found_rust_sim = false;
+    let stdout = t!(String::from_utf8(output.stdout));
+    for line in stdout.lines() {
+        if line.contains("rust_ios") {
+            if found_rust_sim {
+                panic!("Duplicate rust_ios simulators found. Please \
+                        double-check xcrun simctl list.");
+            }
+            simulator_exists = true;
+            simulator_booted = line.contains("(Booted)");
+            found_rust_sim = true;
+        }
+    }
+
+    if simulator_exists == false {
+        println!("Creating iOS simulator");
+        Command::new("xcrun")
+                .arg("simctl")
+                .arg("create")
+                .arg("rust_ios")
+                .arg("com.apple.CoreSimulator.SimDeviceType.iPhone-SE")
+                .arg("com.apple.CoreSimulator.SimRuntime.iOS-10-2")
+                .check_status();
+    } else if simulator_booted == true {
+        println!("Shutting down already-booted simulator");
+        Command::new("xcrun")
+                .arg("simctl")
+                .arg("shutdown")
+                .arg("rust_ios")
+                .check_status();
+    }
+
+    println!("Starting iOS simulator");
+    // We can't uninstall the app (if present) as that will hang if the
+    // simulator isn't completely booted; just erase the simulator instead.
+    Command::new("xcrun").arg("simctl").arg("erase").arg("rust_ios").check_status();
+    Command::new("xcrun").arg("simctl").arg("boot").arg("rust_ios").check_status();
+}
+
+// Step three: Install the app
+fn install_app_to_simulator() {
+    println!("Installing app to simulator");
+    Command::new("xcrun")
+            .arg("simctl")
+            .arg("install")
+            .arg("booted")
+            .arg("ios_simulator_app/")
+            .check_status();
+}
+
+// Step four: Run the app
+fn run_app_on_simulator() {
+    use std::io::{self, Read, Write};
+
+    println!("Running app");
+    let mut child = t!(Command::new("xcrun")
+                    .arg("simctl")
+                    .arg("launch")
+                    .arg("--console")
+                    .arg("booted")
+                    .arg("com.rust.unittests")
+                    .arg("--color")
+                    .arg("never")
+                    .stdout(Stdio::piped())
+                    .stderr(Stdio::piped())
+                    .spawn());
+
+    let stdout = child.stdout.take().unwrap();
+    let stderr = child.stderr.take().unwrap();
+
+    let th = thread::spawn(move || {
+        let mut out = vec![];
+
+        for b in stdout.bytes() {
+            let b = b.unwrap();
+            out.push(b);
+            let out = [b];
+            io::stdout().write(&out[..]).unwrap();
+        }
+
+        out
+    });
+
+    thread::spawn(move || {
+        for b in stderr.bytes() {
+            let out = [b.unwrap()];
+            io::stderr().write(&out[..]).unwrap();
+        }
+    });
+
+    println!("Waiting for cmd to finish");
+    child.wait().unwrap();
+
+    println!("Waiting for stdout");
+    let stdout = th.join().unwrap();
+    let stdout = String::from_utf8_lossy(&stdout);
+    let passed = stdout.lines()
+                       .find(|l| l.contains("test result"))
+                       .map(|l| l.contains(" 0 failed"))
+                       .unwrap_or(false);
+
+    println!("Shutting down simulator");
+    Command::new("xcrun")
+        .arg("simctl")
+        .arg("shutdown")
+        .arg("rust_ios")
+        .check_status();
+    if !passed {
+        panic!("tests didn't pass");
+    }
+}
+
+trait CheckStatus {
+    fn check_status(&mut self);
+}
+
+impl CheckStatus for Command {
+    fn check_status(&mut self) {
+        println!("\trunning: {:?}", self);
+        assert!(t!(self.status()).success());
+    }
+}
+
+fn main() {
+    let args: Vec<String> = env::args().collect();
+    if args.len() != 2 {
+        println!("Usage: {} <executable>", args[0]);
+        process::exit(-1);
+    }
+
+    let test_binary_path = Path::new(&args[1]);
+    let crate_name = test_binary_path.file_name().unwrap();
+
+    package_as_simulator_app(crate_name.to_str().unwrap(), test_binary_path);
+    start_simulator();
+    install_app_to_simulator();
+    run_app_on_simulator();
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/ci/run-docker.sh
@@ -0,0 +1,33 @@
+# Small script to run tests for a target (or all targets) inside all the
+# respective docker images.
+
+set -ex
+
+run() {
+    echo $1
+    docker build -t libc ci/docker/$1
+    mkdir -p target
+    docker run \
+      --user `id -u`:`id -g` \
+      --rm \
+      --volume $HOME/.cargo:/cargo \
+      --env CARGO_HOME=/cargo \
+      --volume `rustc --print sysroot`:/rust:ro \
+      --volume `pwd`:/checkout:ro \
+      --volume `pwd`/target:/checkout/target \
+      --env CARGO_TARGET_DIR=/checkout/target \
+      --workdir /checkout \
+      --privileged \
+      --interactive \
+      --tty \
+      libc \
+      ci/run.sh $1
+}
+
+if [ -z "$1" ]; then
+  for d in `ls ci/docker/`; do
+    run $d
+  done
+else
+  run $1
+fi
new file mode 100755
--- /dev/null
+++ b/third_party/rust/mio/ci/run-ios.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+# Builds and runs tests for a particular target passed as an argument to this
+# script.
+
+set -ex
+
+TARGET=$1
+
+
+case "$TARGET" in
+  *-apple-ios)
+    # Download the iOS test harness
+    curl -vv -L https://github.com/carllerche/ios-test-harness/releases/download/v0.1.0/libiosharness-$TARGET.a > libiosharness.a;
+
+    # Build the test
+    cargo rustc --test test --target $TARGET -- \
+        -L . \
+        -C link-args="-mios-simulator-version-min=7.0 -e _ios_main -liosharness";
+
+
+    # Find the file to run
+    TEST_FILE="$(find target/$TARGET/debug -maxdepth 1 -type f -name test-* | head -1)";
+
+    rustc -O ./ci/ios/deploy_and_run_on_ios_simulator.rs;
+    ./deploy_and_run_on_ios_simulator $TEST_FILE;
+
+    ;;
+
+  *)
+    echo "unsupported target $TARGET";
+    exit 1;
+    ;;
+esac
new file mode 100755
--- /dev/null
+++ b/third_party/rust/mio/ci/run.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+# Builds and runs tests for a particular target passed as an argument to this
+# script.
+
+set -ex
+
+TARGET=$1
+
+if [ -f /etc/cargo_config ] && [ -d /cargo ]; then cp -f /etc/cargo_config /cargo/config; fi
+cargo build --target=$TARGET --test test --verbose
+
+# Find the file to run
+TEST_FILE=$(find target/$TARGET/debug -maxdepth 1 -type f -perm -111 -name "test-*" | head -1)
+
+case "$TARGET" in
+  arm-linux-androideabi)
+    # Use the 64bit emulator
+    emulator64-arm @arm-21 -no-window &
+    adb wait-for-device
+    adb push $TEST_FILE /data/mio-test
+    adb shell /data/mio-test 2>&1 | tee /tmp/out
+    grep "^test result.* 0 failed" /tmp/out
+    ;;
+
+  aarch64-linux-android)
+    # Use the 64bit emulator
+    export LD_LIBRARY_PATH="/android/sdk/emulator/lib64/qt/lib:/usr/lib/x86_64-linux-gnu"
+    qemu-system-aarch64 @arm64-24 -memory 768 -accel off -gpu off -no-skin -no-window -no-audio -no-snapshot-load -no-snapshot-save &
+    adb wait-for-device
+    adb root
+    adb push $TEST_FILE /data/mio-test
+    #adb unroot
+    adb shell chmod 755 /data/mio-test
+    adb shell /data/mio-test 2>&1 | tee /tmp/out
+    grep "^test result.* 0 failed" /tmp/out
+    ;;
+
+  *)
+    exit 1;
+    ;;
+esac
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/ci/trust/install.sh
@@ -0,0 +1,31 @@
+set -ex
+
+main() {
+    curl https://sh.rustup.rs -sSf | \
+        sh -s -- -y --default-toolchain $TRAVIS_RUST_VERSION
+
+    local target=
+    if [ $TRAVIS_OS_NAME = linux ]; then
+        target=x86_64-unknown-linux-gnu
+        sort=sort
+    else
+        target=x86_64-apple-darwin
+        sort=gsort  # for `sort --sort-version`, from brew's coreutils.
+    fi
+
+    # This fetches latest stable release
+    local tag=$(git ls-remote --tags --refs --exit-code https://github.com/japaric/cross \
+                       | cut -d/ -f3 \
+                       | grep -E '^v[0-9.]+$' \
+                       | $sort --version-sort \
+                       | tail -n1)
+    echo cross version: $tag
+    curl -LSfs https://japaric.github.io/trust/install.sh | \
+        sh -s -- \
+           --force \
+           --git japaric/cross \
+           --tag $tag \
+           --target $target
+}
+
+main
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/ci/trust/script.sh
@@ -0,0 +1,19 @@
+# This script takes care of testing your crate
+
+set -ex
+
+# TODO This is the "test phase", tweak it as you see fit
+main() {
+    cross build --target $TARGET
+
+    if [ ! -z $DISABLE_TESTS ]; then
+        return
+    fi
+
+    cross test --target $TARGET
+}
+
+# we don't run the "test phase" when doing deploys
+if [ -z $TRAVIS_TAG ]; then
+    main
+fi
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/channel.rs
@@ -0,0 +1,389 @@
+//! Thread safe communication channel implementing `Evented`
+
+#![allow(unused_imports, deprecated, missing_debug_implementations)]
+
+use {io, Evented, Ready, Poll, PollOpt, Registration, SetReadiness, Token};
+use lazycell::{LazyCell, AtomicLazyCell};
+use std::any::Any;
+use std::fmt;
+use std::error;
+use std::sync::{mpsc, Arc};
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+/// Creates a new asynchronous channel, where the `Receiver` can be registered
+/// with `Poll`.
+pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
+    let (tx_ctl, rx_ctl) = ctl_pair();
+    let (tx, rx) = mpsc::channel();
+
+    let tx = Sender {
+        tx: tx,
+        ctl: tx_ctl,
+    };
+
+    let rx = Receiver {
+        rx: rx,
+        ctl: rx_ctl,
+    };
+
+    (tx, rx)
+}
+
+/// Creates a new synchronous, bounded channel where the `Receiver` can be
+/// registered with `Poll`.
+pub fn sync_channel<T>(bound: usize) -> (SyncSender<T>, Receiver<T>) {
+    let (tx_ctl, rx_ctl) = ctl_pair();
+    let (tx, rx) = mpsc::sync_channel(bound);
+
+    let tx = SyncSender {
+        tx: tx,
+        ctl: tx_ctl,
+    };
+
+    let rx = Receiver {
+        rx: rx,
+        ctl: rx_ctl,
+    };
+
+    (tx, rx)
+}
+
+pub fn ctl_pair() -> (SenderCtl, ReceiverCtl) {
+    let inner = Arc::new(Inner {
+        pending: AtomicUsize::new(0),
+        senders: AtomicUsize::new(1),
+        set_readiness: AtomicLazyCell::new(),
+    });
+
+    let tx = SenderCtl {
+        inner: inner.clone(),
+    };
+
+    let rx = ReceiverCtl {
+        registration: LazyCell::new(),
+        inner: inner,
+    };
+
+    (tx, rx)
+}
+
+/// Tracks messages sent on a channel in order to update readiness.
+pub struct SenderCtl {
+    inner: Arc<Inner>,
+}
+
+/// Tracks messages received on a channel in order to track readiness.
+pub struct ReceiverCtl {
+    registration: LazyCell<Registration>,
+    inner: Arc<Inner>,
+}
+
+pub struct Sender<T> {
+    tx: mpsc::Sender<T>,
+    ctl: SenderCtl,
+}
+
+pub struct SyncSender<T> {
+    tx: mpsc::SyncSender<T>,
+    ctl: SenderCtl,
+}
+
+pub struct Receiver<T> {
+    rx: mpsc::Receiver<T>,
+    ctl: ReceiverCtl,
+}
+
+pub enum SendError<T> {
+    Io(io::Error),
+    Disconnected(T),
+}
+
+pub enum TrySendError<T> {
+    Io(io::Error),
+    Full(T),
+    Disconnected(T),
+}
+
+struct Inner {
+    // The number of outstanding messages for the receiver to read
+    pending: AtomicUsize,
+    // The number of sender handles
+    senders: AtomicUsize,
+    // The set readiness handle
+    set_readiness: AtomicLazyCell<SetReadiness>,
+}
+
+impl<T> Sender<T> {
+    pub fn send(&self, t: T) -> Result<(), SendError<T>> {
+        self.tx.send(t)
+            .map_err(SendError::from)
+            .and_then(|_| {
+                try!(self.ctl.inc());
+                Ok(())
+            })
+    }
+}
+
+impl<T> Clone for Sender<T> {
+    fn clone(&self) -> Sender<T> {
+        Sender {
+            tx: self.tx.clone(),
+            ctl: self.ctl.clone(),
+        }
+    }
+}
+
+impl<T> SyncSender<T> {
+    pub fn send(&self, t: T) -> Result<(), SendError<T>> {
+        self.tx.send(t)
+            .map_err(From::from)
+            .and_then(|_| {
+                try!(self.ctl.inc());
+                Ok(())
+            })
+    }
+
+    pub fn try_send(&self, t: T) -> Result<(), TrySendError<T>> {
+        self.tx.try_send(t)
+            .map_err(From::from)
+            .and_then(|_| {
+                try!(self.ctl.inc());
+                Ok(())
+            })
+    }
+}
+
+impl<T> Clone for SyncSender<T> {
+    fn clone(&self) -> SyncSender<T> {
+        SyncSender {
+            tx: self.tx.clone(),
+            ctl: self.ctl.clone(),
+        }
+    }
+}
+
+impl<T> Receiver<T> {
+    pub fn try_recv(&self) -> Result<T, mpsc::TryRecvError> {
+        self.rx.try_recv().and_then(|res| {
+            let _ = self.ctl.dec();
+            Ok(res)
+        })
+    }
+}
+
+impl<T> Evented for Receiver<T> {
+    fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.ctl.register(poll, token, interest, opts)
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.ctl.reregister(poll, token, interest, opts)
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        self.ctl.deregister(poll)
+    }
+}
+
+/*
+ *
+ * ===== SenderCtl / ReceiverCtl =====
+ *
+ */
+
+impl SenderCtl {
+    /// Call to track that a message has been sent
+    pub fn inc(&self) -> io::Result<()> {
+        let cnt = self.inner.pending.fetch_add(1, Ordering::Acquire);
+
+        if 0 == cnt {
+            // Toggle readiness to readable
+            if let Some(set_readiness) = self.inner.set_readiness.borrow() {
+                try!(set_readiness.set_readiness(Ready::readable()));
+            }
+        }
+
+        Ok(())
+    }
+}
+
+impl Clone for SenderCtl {
+    fn clone(&self) -> SenderCtl {
+        self.inner.senders.fetch_add(1, Ordering::Relaxed);
+        SenderCtl { inner: self.inner.clone() }
+    }
+}
+
+impl Drop for SenderCtl {
+    fn drop(&mut self) {
+        if self.inner.senders.fetch_sub(1, Ordering::Release) == 1 {
+            let _ = self.inc();
+        }
+    }
+}
+
+impl ReceiverCtl {
+    pub fn dec(&self) -> io::Result<()> {
+        let first = self.inner.pending.load(Ordering::Acquire);
+
+        if first == 1 {
+            // Unset readiness
+            if let Some(set_readiness) = self.inner.set_readiness.borrow() {
+                try!(set_readiness.set_readiness(Ready::empty()));
+            }
+        }
+
+        // Decrement
+        let second = self.inner.pending.fetch_sub(1, Ordering::AcqRel);
+
+        if first == 1 && second > 1 {
+            // There are still pending messages. Since readiness was
+            // previously unset, it must be reset here
+            if let Some(set_readiness) = self.inner.set_readiness.borrow() {
+                try!(set_readiness.set_readiness(Ready::readable()));
+            }
+        }
+
+        Ok(())
+    }
+}
+
+impl Evented for ReceiverCtl {
+    fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        if self.registration.borrow().is_some() {
+            return Err(io::Error::new(io::ErrorKind::Other, "receiver already registered"));
+        }
+
+        let (registration, set_readiness) = Registration::new(poll, token, interest, opts);
+
+
+        if self.inner.pending.load(Ordering::Relaxed) > 0 {
+            // TODO: Don't drop readiness
+            let _ = set_readiness.set_readiness(Ready::readable());
+        }
+
+        self.registration.fill(registration).ok().expect("unexpected state encountered");
+        self.inner.set_readiness.fill(set_readiness).ok().expect("unexpected state encountered");
+
+        Ok(())
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        match self.registration.borrow() {
+            Some(registration) => registration.update(poll, token, interest, opts),
+            None => Err(io::Error::new(io::ErrorKind::Other, "receiver not registered")),
+        }
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        match self.registration.borrow() {
+            Some(registration) => registration.deregister(poll),
+            None => Err(io::Error::new(io::ErrorKind::Other, "receiver not registered")),
+        }
+    }
+}
+
+/*
+ *
+ * ===== Error conversions =====
+ *
+ */
+
+impl<T> From<mpsc::SendError<T>> for SendError<T> {
+    fn from(src: mpsc::SendError<T>) -> SendError<T> {
+        SendError::Disconnected(src.0)
+    }
+}
+
+impl<T> From<io::Error> for SendError<T> {
+    fn from(src: io::Error) -> SendError<T> {
+        SendError::Io(src)
+    }
+}
+
+impl<T> From<mpsc::TrySendError<T>> for TrySendError<T> {
+    fn from(src: mpsc::TrySendError<T>) -> TrySendError<T> {
+        match src {
+            mpsc::TrySendError::Full(v) => TrySendError::Full(v),
+            mpsc::TrySendError::Disconnected(v) => TrySendError::Disconnected(v),
+        }
+    }
+}
+
+impl<T> From<mpsc::SendError<T>> for TrySendError<T> {
+    fn from(src: mpsc::SendError<T>) -> TrySendError<T> {
+        TrySendError::Disconnected(src.0)
+    }
+}
+
+impl<T> From<io::Error> for TrySendError<T> {
+    fn from(src: io::Error) -> TrySendError<T> {
+        TrySendError::Io(src)
+    }
+}
+
+/*
+ *
+ * ===== Implement Error, Debug and Display for Errors =====
+ *
+ */
+
+impl<T: Any> error::Error for SendError<T> {
+    fn description(&self) -> &str {
+        match self {
+            &SendError::Io(ref io_err) => io_err.description(),
+            &SendError::Disconnected(..) => "Disconnected",
+        }
+    }
+}
+
+impl<T: Any> error::Error for TrySendError<T> {
+    fn description(&self) -> &str {
+        match self {
+            &TrySendError::Io(ref io_err) => io_err.description(),
+            &TrySendError::Full(..) => "Full",
+            &TrySendError::Disconnected(..) => "Disconnected",
+        }
+    }
+}
+
+impl<T> fmt::Debug for SendError<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        format_send_error(self, f)
+    }
+}
+
+impl<T> fmt::Display for SendError<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        format_send_error(self, f)
+    }
+}
+
+impl<T> fmt::Debug for TrySendError<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        format_try_send_error(self, f)
+    }
+}
+
+impl<T> fmt::Display for TrySendError<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        format_try_send_error(self, f)
+    }
+}
+
+#[inline]
+fn format_send_error<T>(e: &SendError<T>, f: &mut fmt::Formatter) -> fmt::Result {
+    match e {
+        &SendError::Io(ref io_err) => write!(f, "{}", io_err),
+        &SendError::Disconnected(..) => write!(f, "Disconnected"),
+    }
+}
+
+#[inline]
+fn format_try_send_error<T>(e: &TrySendError<T>, f: &mut fmt::Formatter) -> fmt::Result {
+    match e {
+        &TrySendError::Io(ref io_err) => write!(f, "{}", io_err),
+        &TrySendError::Full(..) => write!(f, "Full"),
+        &TrySendError::Disconnected(..) => write!(f, "Disconnected"),
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/deprecated/event_loop.rs
@@ -0,0 +1,396 @@
+use {channel, Evented, Poll, Events, Token};
+use deprecated::{Handler, NotifyError};
+use event_imp::{Event, Ready, PollOpt};
+use timer::{self, Timer, Timeout};
+use std::{io, fmt, usize};
+use std::default::Default;
+use std::time::Duration;
+
+#[derive(Debug, Default, Clone)]
+pub struct EventLoopBuilder {
+    config: Config,
+}
+
+/// `EventLoop` configuration details
+#[derive(Clone, Debug)]
+struct Config {
+    // == Notifications ==
+    notify_capacity: usize,
+    messages_per_tick: usize,
+
+    // == Timer ==
+    timer_tick: Duration,
+    timer_wheel_size: usize,
+    timer_capacity: usize,
+}
+
+impl Default for Config {
+    fn default() -> Config {
+        // Default EventLoop configuration values
+        Config {
+            notify_capacity: 4_096,
+            messages_per_tick: 256,
+            timer_tick: Duration::from_millis(100),
+            timer_wheel_size: 1_024,
+            timer_capacity: 65_536,
+        }
+    }
+}
+
+impl EventLoopBuilder {
+    /// Construct a new `EventLoopBuilder` with the default configuration
+    /// values.
+    pub fn new() -> EventLoopBuilder {
+        EventLoopBuilder::default()
+    }
+
+    /// Sets the maximum number of messages that can be buffered on the event
+    /// loop's notification channel before a send will fail.
+    ///
+    /// The default value for this is 4096.
+    pub fn notify_capacity(&mut self, capacity: usize) -> &mut Self {
+        self.config.notify_capacity = capacity;
+        self
+    }
+
+    /// Sets the maximum number of messages that can be processed on any tick of
+    /// the event loop.
+    ///
+    /// The default value for this is 256.
+    pub fn messages_per_tick(&mut self, messages: usize) -> &mut Self {
+        self.config.messages_per_tick = messages;
+        self
+    }
+
+    pub fn timer_tick(&mut self, val: Duration) -> &mut Self {
+        self.config.timer_tick = val;
+        self
+    }
+
+    pub fn timer_wheel_size(&mut self, size: usize) -> &mut Self {
+        self.config.timer_wheel_size = size;
+        self
+    }
+
+    pub fn timer_capacity(&mut self, cap: usize) -> &mut Self {
+        self.config.timer_capacity = cap;
+        self
+    }
+
+    /// Constructs a new `EventLoop` using the configured values. The
+    /// `EventLoop` will not be running.
+    pub fn build<H: Handler>(self) -> io::Result<EventLoop<H>> {
+        EventLoop::configured(self.config)
+    }
+}
+
+/// Single threaded IO event loop.
+pub struct EventLoop<H: Handler> {
+    run: bool,
+    poll: Poll,
+    events: Events,
+    timer: Timer<H::Timeout>,
+    notify_tx: channel::SyncSender<H::Message>,
+    notify_rx: channel::Receiver<H::Message>,
+    config: Config,
+}
+
+// Token used to represent notifications
+const NOTIFY: Token = Token(usize::MAX - 1);
+const TIMER: Token = Token(usize::MAX - 2);
+
+impl<H: Handler> EventLoop<H> {
+
+    /// Constructs a new `EventLoop` using the default configuration values.
+    /// The `EventLoop` will not be running.
+    pub fn new() -> io::Result<EventLoop<H>> {
+        EventLoop::configured(Config::default())
+    }
+
+    fn configured(config: Config) -> io::Result<EventLoop<H>> {
+        // Create the IO poller
+        let poll = try!(Poll::new());
+
+        let timer = timer::Builder::default()
+            .tick_duration(config.timer_tick)
+            .num_slots(config.timer_wheel_size)
+            .capacity(config.timer_capacity)
+            .build();
+
+        // Create cross thread notification queue
+        let (tx, rx) = channel::sync_channel(config.notify_capacity);
+
+        // Register the notification wakeup FD with the IO poller
+        try!(poll.register(&rx, NOTIFY, Ready::readable(), PollOpt::edge() | PollOpt::oneshot()));
+        try!(poll.register(&timer, TIMER, Ready::readable(), PollOpt::edge()));
+
+        Ok(EventLoop {
+            run: true,
+            poll: poll,
+            timer: timer,
+            notify_tx: tx,
+            notify_rx: rx,
+            config: config,
+            events: Events::with_capacity(1024),
+        })
+    }
+
+    /// Returns a sender that allows sending messages to the event loop in a
+    /// thread-safe way, waking up the event loop if needed.
+    ///
+    /// # Example
+    /// ```
+    /// use std::thread;
+    /// use mio::deprecated::{EventLoop, Handler};
+    ///
+    /// struct MyHandler;
+    ///
+    /// impl Handler for MyHandler {
+    ///     type Timeout = ();
+    ///     type Message = u32;
+    ///
+    ///     fn notify(&mut self, event_loop: &mut EventLoop<MyHandler>, msg: u32) {
+    ///         assert_eq!(msg, 123);
+    ///         event_loop.shutdown();
+    ///     }
+    /// }
+    ///
+    /// let mut event_loop = EventLoop::new().unwrap();
+    /// let sender = event_loop.channel();
+    ///
+    /// // Send the notification from another thread
+    /// thread::spawn(move || {
+    ///     let _ = sender.send(123);
+    /// });
+    ///
+    /// let _ = event_loop.run(&mut MyHandler);
+    /// ```
+    ///
+    /// # Implementation Details
+    ///
+    /// Each [EventLoop](#) contains a lock-free queue with a pre-allocated
+    /// buffer size. The size can be changed by modifying
+    /// [EventLoopConfig.notify_capacity](struct.EventLoopConfig.html#method.notify_capacity).
+    /// When a message is sent to the EventLoop, it is first pushed on to the
+    /// queue. Then, if the EventLoop is currently running, an atomic flag is
+    /// set to indicate that the next loop iteration should be started without
+    /// waiting.
+    ///
+    /// If the loop is blocked waiting for IO events, then it is woken up. The
+    /// strategy for waking up the event loop is platform dependent. For
+    /// example, on a modern Linux OS, eventfd is used. On older OSes, a pipe
+    /// is used.
+    ///
+    /// The strategy of setting an atomic flag if the event loop is not already
+    /// sleeping allows avoiding an expensive wakeup operation if at all possible.
+    pub fn channel(&self) -> Sender<H::Message> {
+        Sender::new(self.notify_tx.clone())
+    }
+
+    /// Schedules a timeout after the requested time interval. When the
+    /// duration has been reached,
+    /// [Handler::timeout](trait.Handler.html#method.timeout) will be invoked
+    /// passing in the supplied token.
+    ///
+    /// Returns a handle to the timeout that can be used to cancel the timeout
+    /// using [#clear_timeout](#method.clear_timeout).
+    ///
+    /// # Example
+    /// ```
+    /// use mio::deprecated::{EventLoop, Handler};
+    /// use std::time::Duration;
+    ///
+    /// struct MyHandler;
+    ///
+    /// impl Handler for MyHandler {
+    ///     type Timeout = u32;
+    ///     type Message = ();
+    ///
+    ///     fn timeout(&mut self, event_loop: &mut EventLoop<MyHandler>, timeout: u32) {
+    ///         assert_eq!(timeout, 123);
+    ///         event_loop.shutdown();
+    ///     }
+    /// }
+    ///
+    ///
+    /// let mut event_loop = EventLoop::new().unwrap();
+    /// let timeout = event_loop.timeout(123, Duration::from_millis(300)).unwrap();
+    /// let _ = event_loop.run(&mut MyHandler);
+    /// ```
+    pub fn timeout(&mut self, token: H::Timeout, delay: Duration) -> timer::Result<Timeout> {
+        self.timer.set_timeout(delay, token)
+    }
+
+    /// If the supplied timeout has not been triggered, cancel it such that it
+    /// will not be triggered in the future.
+    pub fn clear_timeout(&mut self, timeout: &Timeout) -> bool {
+        self.timer.cancel_timeout(&timeout).is_some()
+    }
+
+    /// Tells the event loop to exit after it is done handling all events in the
+    /// current iteration.
+    pub fn shutdown(&mut self) {
+        self.run = false;
+    }
+
+    /// Indicates whether the event loop is currently running. If it's not it has either
+    /// stopped or is scheduled to stop on the next tick.
+    pub fn is_running(&self) -> bool {
+        self.run
+    }
+
+    /// Registers an IO handle with the event loop.
+    pub fn register<E: ?Sized>(&mut self, io: &E, token: Token, interest: Ready, opt: PollOpt) -> io::Result<()>
+        where E: Evented
+    {
+        self.poll.register(io, token, interest, opt)
+    }
+
+    /// Re-Registers an IO handle with the event loop.
+    pub fn reregister<E: ?Sized>(&mut self, io: &E, token: Token, interest: Ready, opt: PollOpt) -> io::Result<()>
+        where E: Evented
+    {
+        self.poll.reregister(io, token, interest, opt)
+    }
+
+    /// Keep spinning the event loop indefinitely, and notify the handler whenever
+    /// any of the registered handles are ready.
+    pub fn run(&mut self, handler: &mut H) -> io::Result<()> {
+        self.run = true;
+
+        while self.run {
+            // Execute ticks as long as the event loop is running
+            try!(self.run_once(handler, None));
+        }
+
+        Ok(())
+    }
+
+    /// Deregisters an IO handle with the event loop.
+    ///
+    /// Both kqueue and epoll will automatically clear any pending events when closing a
+    /// file descriptor (socket). In that case, this method does not need to be called
+    /// prior to dropping a connection from the slab.
+    ///
+    /// Warning: kqueue effectively builds in deregister when using edge-triggered mode with
+    /// oneshot. Calling `deregister()` on the socket will cause a TcpStream error.
+    pub fn deregister<E: ?Sized>(&mut self, io: &E) -> io::Result<()> where E: Evented {
+        self.poll.deregister(io)
+    }
+
+    /// Spin the event loop once, with a given timeout (forever if `None`),
+    /// and notify the handler if any of the registered handles become ready
+    /// during that time.
+    pub fn run_once(&mut self, handler: &mut H, timeout: Option<Duration>) -> io::Result<()> {
+        trace!("event loop tick");
+
+        // Check the registered IO handles for any new events. Each poll
+        // is for one second, so a shutdown request can last as long as
+        // one second before it takes effect.
+        let events = match self.io_poll(timeout) {
+            Ok(e) => e,
+            Err(err) => {
+                if err.kind() == io::ErrorKind::Interrupted {
+                    handler.interrupted(self);
+                    0
+                } else {
+                    return Err(err);
+                }
+            }
+        };
+
+        self.io_process(handler, events);
+        handler.tick(self);
+        Ok(())
+    }
+
+    #[inline]
+    fn io_poll(&mut self, timeout: Option<Duration>) -> io::Result<usize> {
+        self.poll.poll(&mut self.events, timeout)
+    }
+
+    // Process IO events that have been previously polled
+    fn io_process(&mut self, handler: &mut H, cnt: usize) {
+        let mut i = 0;
+
+        trace!("io_process(..); cnt={}; len={}", cnt, self.events.len());
+
+        // Iterate over the notifications. Each event provides the token
+        // it was registered with (which usually represents, at least, the
+        // handle that the event is about) as well as information about
+        // what kind of event occurred (readable, writable, signal, etc.)
+        while i < cnt {
+            let evt = self.events.get(i).unwrap();
+
+            trace!("event={:?}; idx={:?}", evt, i);
+
+            match evt.token() {
+                NOTIFY => self.notify(handler),
+                TIMER => self.timer_process(handler),
+                _ => self.io_event(handler, evt)
+            }
+
+            i += 1;
+        }
+    }
+
+    fn io_event(&mut self, handler: &mut H, evt: Event) {
+        handler.ready(self, evt.token(), evt.kind());
+    }
+
+    fn notify(&mut self, handler: &mut H) {
+        for _ in 0..self.config.messages_per_tick {
+            match self.notify_rx.try_recv() {
+                Ok(msg) => handler.notify(self, msg),
+                _ => break,
+            }
+        }
+
+        // Re-register
+        let _ = self.poll.reregister(&self.notify_rx, NOTIFY, Ready::readable(), PollOpt::edge() | PollOpt::oneshot());
+    }
+
+    fn timer_process(&mut self, handler: &mut H) {
+        while let Some(t) = self.timer.poll() {
+            handler.timeout(self, t);
+        }
+    }
+}
+
+impl<H: Handler> fmt::Debug for EventLoop<H> {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        fmt.debug_struct("EventLoop")
+            .field("run", &self.run)
+            .field("poll", &self.poll)
+            .field("config", &self.config)
+            .finish()
+    }
+}
+
+/// Sends messages to the EventLoop from other threads.
+pub struct Sender<M> {
+    tx: channel::SyncSender<M>
+}
+
+impl<M> fmt::Debug for Sender<M> {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        write!(fmt, "Sender<?> {{ ... }}")
+    }
+}
+
+impl<M> Clone for Sender <M> {
+    fn clone(&self) -> Sender<M> {
+        Sender { tx: self.tx.clone() }
+    }
+}
+
+impl<M> Sender<M> {
+    fn new(tx: channel::SyncSender<M>) -> Sender<M> {
+        Sender { tx: tx }
+    }
+
+    pub fn send(&self, msg: M) -> Result<(), NotifyError<M>> {
+        try!(self.tx.try_send(msg));
+        Ok(())
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/deprecated/handler.rs
@@ -0,0 +1,37 @@
+use {Ready, Token};
+use deprecated::{EventLoop};
+
+#[allow(unused_variables)]
+pub trait Handler: Sized {
+    type Timeout;
+    type Message;
+
+    /// Invoked when the socket represented by `token` is ready to be operated
+    /// on. `events` indicates the specific operations that are
+    /// ready to be performed.
+    ///
+    /// For example, when a TCP socket is ready to be read from, `events` will
+    /// have `readable` set. When the socket is ready to be written to,
+    /// `events` will have `writable` set.
+    ///
+    /// This function will only be invoked a single time per socket per event
+    /// loop tick.
+    fn ready(&mut self, event_loop: &mut EventLoop<Self>, token: Token, events: Ready) {
+    }
+
+    /// Invoked when a message has been received via the event loop's channel.
+    fn notify(&mut self, event_loop: &mut EventLoop<Self>, msg: Self::Message) {
+    }
+
+    /// Invoked when a timeout has completed.
+    fn timeout(&mut self, event_loop: &mut EventLoop<Self>, timeout: Self::Timeout) {
+    }
+
+    /// Invoked when `EventLoop` has been interrupted by a signal interrupt.
+    fn interrupted(&mut self, event_loop: &mut EventLoop<Self>) {
+    }
+
+    /// Invoked at the end of an event loop tick.
+    fn tick(&mut self, event_loop: &mut EventLoop<Self>) {
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/deprecated/io.rs
@@ -0,0 +1,28 @@
+use ::io::MapNonBlock;
+use std::io::{self, Read, Write};
+
+pub trait TryRead {
+    fn try_read(&mut self, buf: &mut [u8]) -> io::Result<Option<usize>>;
+}
+
+pub trait TryWrite {
+    fn try_write(&mut self, buf: &[u8]) -> io::Result<Option<usize>>;
+}
+
+impl<T: Read> TryRead for T {
+    fn try_read(&mut self, dst: &mut [u8]) -> io::Result<Option<usize>> {
+        self.read(dst).map_non_block()
+    }
+}
+
+impl<T: Write> TryWrite for T {
+    fn try_write(&mut self, src: &[u8]) -> io::Result<Option<usize>> {
+        self.write(src).map_non_block()
+    }
+}
+
+pub trait TryAccept {
+    type Output;
+
+    fn accept(&self) -> io::Result<Option<Self::Output>>;
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/deprecated/mod.rs
@@ -0,0 +1,36 @@
+#![allow(deprecated)]
+
+mod event_loop;
+mod io;
+mod handler;
+mod notify;
+
+#[cfg(unix)]
+pub mod unix;
+
+pub use self::event_loop::{
+    EventLoop,
+    EventLoopBuilder,
+    Sender,
+};
+pub use self::io::{
+    TryAccept,
+    TryRead,
+    TryWrite,
+};
+pub use self::handler::{
+    Handler,
+};
+pub use self::notify::{
+    NotifyError,
+};
+#[cfg(unix)]
+pub use self::unix::{
+    pipe,
+    PipeReader,
+    PipeWriter,
+    UnixListener,
+    UnixSocket,
+    UnixStream,
+    Shutdown,
+};
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/deprecated/notify.rs
@@ -0,0 +1,63 @@
+use {channel};
+use std::{fmt, io, error, any};
+
+pub enum NotifyError<T> {
+    Io(io::Error),
+    Full(T),
+    Closed(Option<T>),
+}
+
+impl<M> fmt::Debug for NotifyError<M> {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            NotifyError::Io(ref e) => {
+                write!(fmt, "NotifyError::Io({:?})", e)
+            }
+            NotifyError::Full(..) => {
+                write!(fmt, "NotifyError::Full(..)")
+            }
+            NotifyError::Closed(..) => {
+                write!(fmt, "NotifyError::Closed(..)")
+            }
+        }
+    }
+}
+
+impl<M> fmt::Display for NotifyError<M> {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            NotifyError::Io(ref e) => {
+                write!(fmt, "IO error: {}", e)
+            }
+            NotifyError::Full(..) => write!(fmt, "Full"),
+            NotifyError::Closed(..) => write!(fmt, "Closed")
+        }
+    }
+}
+
+impl<M: any::Any> error::Error for NotifyError<M> {
+    fn description(&self) -> &str {
+        match *self {
+            NotifyError::Io(ref err) => err.description(),
+            NotifyError::Closed(..) => "The receiving end has hung up",
+            NotifyError::Full(..) => "Queue is full"
+        }
+    }
+
+    fn cause(&self) -> Option<&error::Error> {
+        match *self {
+            NotifyError::Io(ref err) => Some(err),
+            _ => None
+        }
+    }
+}
+
+impl<M> From<channel::TrySendError<M>> for NotifyError<M> {
+    fn from(src: channel::TrySendError<M>) -> NotifyError<M> {
+        match src {
+            channel::TrySendError::Io(e) => NotifyError::Io(e),
+            channel::TrySendError::Full(v) => NotifyError::Full(v),
+            channel::TrySendError::Disconnected(v) => NotifyError::Closed(Some(v)),
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/deprecated/unix.rs
@@ -0,0 +1,422 @@
+use {io, sys, Evented, Ready, Poll, PollOpt, Token};
+use deprecated::TryAccept;
+use io::MapNonBlock;
+use std::io::{Read, Write};
+use std::path::Path;
+pub use std::net::Shutdown;
+use std::process;
+
+pub use sys::Io;
+
+#[derive(Debug)]
+pub struct UnixSocket {
+    sys: sys::UnixSocket,
+}
+
+impl UnixSocket {
+    /// Returns a new, unbound, non-blocking Unix domain socket
+    pub fn stream() -> io::Result<UnixSocket> {
+        sys::UnixSocket::stream()
+            .map(From::from)
+    }
+
+    /// Connect the socket to the specified address
+    pub fn connect<P: AsRef<Path> + ?Sized>(self, addr: &P) -> io::Result<(UnixStream, bool)> {
+        let complete = match self.sys.connect(addr) {
+            Ok(()) => true,
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => false,
+            Err(e) => return Err(e),
+        };
+        Ok((From::from(self.sys), complete))
+    }
+
+    /// Bind the socket to the specified address
+    pub fn bind<P: AsRef<Path> + ?Sized>(&self, addr: &P) -> io::Result<()> {
+        self.sys.bind(addr)
+    }
+
+    /// Listen for incoming requests
+    pub fn listen(self, backlog: usize) -> io::Result<UnixListener> {
+        try!(self.sys.listen(backlog));
+        Ok(From::from(self.sys))
+    }
+
+    pub fn try_clone(&self) -> io::Result<UnixSocket> {
+        self.sys.try_clone()
+            .map(From::from)
+    }
+}
+
+impl Evented for UnixSocket {
+    fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.sys.register(poll, token, interest, opts)
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.sys.reregister(poll, token, interest, opts)
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        self.sys.deregister(poll)
+    }
+}
+
+impl From<sys::UnixSocket> for UnixSocket {
+    fn from(sys: sys::UnixSocket) -> UnixSocket {
+        UnixSocket { sys: sys }
+    }
+}
+
+/*
+ *
+ * ===== UnixStream =====
+ *
+ */
+
+#[derive(Debug)]
+pub struct UnixStream {
+    sys: sys::UnixSocket,
+}
+
+impl UnixStream {
+    pub fn connect<P: AsRef<Path> + ?Sized>(path: &P) -> io::Result<UnixStream> {
+        UnixSocket::stream()
+            .and_then(|sock| sock.connect(path))
+            .map(|(sock, _)| sock)
+    }
+
+    pub fn try_clone(&self) -> io::Result<UnixStream> {
+        self.sys.try_clone()
+            .map(From::from)
+    }
+
+    pub fn shutdown(&self, how: Shutdown) -> io::Result<usize> {
+        self.sys.shutdown(how).map(|_| 0)
+    }
+
+    pub fn read_recv_fd(&mut self, buf: &mut [u8]) -> io::Result<(usize, Option<RawFd>)> {
+        self.sys.read_recv_fd(buf)
+    }
+
+    pub fn try_read_recv_fd(&mut self, buf: &mut [u8]) -> io::Result<Option<(usize, Option<RawFd>)>> {
+        self.read_recv_fd(buf).map_non_block()
+    }
+
+    pub fn write_send_fd(&mut self, buf: &[u8], fd: RawFd) -> io::Result<usize> {
+        self.sys.write_send_fd(buf, fd)
+    }
+
+    pub fn try_write_send_fd(&mut self, buf: &[u8], fd: RawFd) -> io::Result<Option<usize>> {
+        self.write_send_fd(buf, fd).map_non_block()
+    }
+}
+
+impl Read for UnixStream {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        self.sys.read(buf)
+    }
+}
+
+impl Write for UnixStream {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.sys.write(buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        self.sys.flush()
+    }
+}
+
+impl Evented for UnixStream {
+    fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.sys.register(poll, token, interest, opts)
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.sys.reregister(poll, token, interest, opts)
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        self.sys.deregister(poll)
+    }
+}
+
+impl From<sys::UnixSocket> for UnixStream {
+    fn from(sys: sys::UnixSocket) -> UnixStream {
+        UnixStream { sys: sys }
+    }
+}
+
+/*
+ *
+ * ===== UnixListener =====
+ *
+ */
+
+#[derive(Debug)]
+pub struct UnixListener {
+    sys: sys::UnixSocket,
+}
+
+impl UnixListener {
+    pub fn bind<P: AsRef<Path> + ?Sized>(addr: &P) -> io::Result<UnixListener> {
+        UnixSocket::stream().and_then(|sock| {
+            try!(sock.bind(addr));
+            sock.listen(256)
+        })
+    }
+
+    pub fn accept(&self) -> io::Result<UnixStream> {
+        self.sys.accept().map(From::from)
+    }
+
+    pub fn try_clone(&self) -> io::Result<UnixListener> {
+        self.sys.try_clone().map(From::from)
+    }
+}
+
+impl Evented for UnixListener {
+    fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.sys.register(poll, token, interest, opts)
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.sys.reregister(poll, token, interest, opts)
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        self.sys.deregister(poll)
+    }
+}
+
+impl TryAccept for UnixListener {
+    type Output = UnixStream;
+
+    fn accept(&self) -> io::Result<Option<UnixStream>> {
+        UnixListener::accept(self).map_non_block()
+    }
+}
+
+impl From<sys::UnixSocket> for UnixListener {
+    fn from(sys: sys::UnixSocket) -> UnixListener {
+        UnixListener { sys: sys }
+    }
+}
+
+/*
+ *
+ * ===== Pipe =====
+ *
+ */
+
+pub fn pipe() -> io::Result<(PipeReader, PipeWriter)> {
+    let (rd, wr) = try!(sys::pipe());
+    Ok((From::from(rd), From::from(wr)))
+}
+
+#[derive(Debug)]
+pub struct PipeReader {
+    io: Io,
+}
+
+impl PipeReader {
+    pub fn from_stdout(stdout: process::ChildStdout) -> io::Result<Self> {
+        match sys::set_nonblock(stdout.as_raw_fd()) {
+            Err(e) => return Err(e),
+            _ => {},
+        }
+        return Ok(PipeReader::from(unsafe { Io::from_raw_fd(stdout.into_raw_fd()) }));
+    }
+    pub fn from_stderr(stderr: process::ChildStderr) -> io::Result<Self> {
+        match sys::set_nonblock(stderr.as_raw_fd()) {
+            Err(e) => return Err(e),
+            _ => {},
+        }
+        return Ok(PipeReader::from(unsafe { Io::from_raw_fd(stderr.into_raw_fd()) }));
+    }
+}
+
+impl Read for PipeReader {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        self.io.read(buf)
+    }
+}
+
+impl<'a> Read for &'a PipeReader {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        (&self.io).read(buf)
+    }
+}
+
+impl Evented for PipeReader {
+    fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.io.register(poll, token, interest, opts)
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.io.reregister(poll, token, interest, opts)
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        self.io.deregister(poll)
+    }
+}
+
+impl From<Io> for PipeReader {
+    fn from(io: Io) -> PipeReader {
+        PipeReader { io: io }
+    }
+}
+
+#[derive(Debug)]
+pub struct PipeWriter {
+    io: Io,
+}
+
+impl PipeWriter {
+    pub fn from_stdin(stdin: process::ChildStdin) -> io::Result<Self> {
+        match sys::set_nonblock(stdin.as_raw_fd()) {
+            Err(e) => return Err(e),
+            _ => {},
+        }
+        return Ok(PipeWriter::from(unsafe { Io::from_raw_fd(stdin.into_raw_fd()) }));
+    }
+}
+
+impl Write for PipeWriter {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.io.write(buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        self.io.flush()
+    }
+}
+
+impl<'a> Write for &'a PipeWriter {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        (&self.io).write(buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        (&self.io).flush()
+    }
+}
+
+impl Evented for PipeWriter {
+    fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.io.register(poll, token, interest, opts)
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.io.reregister(poll, token, interest, opts)
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        self.io.deregister(poll)
+    }
+}
+
+impl From<Io> for PipeWriter {
+    fn from(io: Io) -> PipeWriter {
+        PipeWriter { io: io }
+    }
+}
+
+/*
+ *
+ * ===== Conversions =====
+ *
+ */
+
+use std::os::unix::io::{RawFd, IntoRawFd, AsRawFd, FromRawFd};
+
+impl IntoRawFd for UnixSocket {
+    fn into_raw_fd(self) -> RawFd {
+        self.sys.into_raw_fd()
+    }
+}
+
+impl AsRawFd for UnixSocket {
+    fn as_raw_fd(&self) -> RawFd {
+        self.sys.as_raw_fd()
+    }
+}
+
+impl FromRawFd for UnixSocket {
+    unsafe fn from_raw_fd(fd: RawFd) -> UnixSocket {
+        UnixSocket { sys: FromRawFd::from_raw_fd(fd) }
+    }
+}
+
+impl IntoRawFd for UnixStream {
+    fn into_raw_fd(self) -> RawFd {
+        self.sys.into_raw_fd()
+    }
+}
+
+impl AsRawFd for UnixStream {
+    fn as_raw_fd(&self) -> RawFd {
+        self.sys.as_raw_fd()
+    }
+}
+
+impl FromRawFd for UnixStream {
+    unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
+        UnixStream { sys: FromRawFd::from_raw_fd(fd) }
+    }
+}
+
+impl IntoRawFd for UnixListener {
+    fn into_raw_fd(self) -> RawFd {
+        self.sys.into_raw_fd()
+    }
+}
+
+impl AsRawFd for UnixListener {
+    fn as_raw_fd(&self) -> RawFd {
+        self.sys.as_raw_fd()
+    }
+}
+
+impl FromRawFd for UnixListener {
+    unsafe fn from_raw_fd(fd: RawFd) -> UnixListener {
+        UnixListener { sys: FromRawFd::from_raw_fd(fd) }
+    }
+}
+
+impl IntoRawFd for PipeReader {
+    fn into_raw_fd(self) -> RawFd {
+        self.io.into_raw_fd()
+    }
+}
+
+impl AsRawFd for PipeReader {
+    fn as_raw_fd(&self) -> RawFd {
+        self.io.as_raw_fd()
+    }
+}
+
+impl FromRawFd for PipeReader {
+    unsafe fn from_raw_fd(fd: RawFd) -> PipeReader {
+        PipeReader { io: FromRawFd::from_raw_fd(fd) }
+    }
+}
+
+impl IntoRawFd for PipeWriter {
+    fn into_raw_fd(self) -> RawFd {
+        self.io.into_raw_fd()
+    }
+}
+
+impl AsRawFd for PipeWriter {
+    fn as_raw_fd(&self) -> RawFd {
+        self.io.as_raw_fd()
+    }
+}
+
+impl FromRawFd for PipeWriter {
+    unsafe fn from_raw_fd(fd: RawFd) -> PipeWriter {
+        PipeWriter { io: FromRawFd::from_raw_fd(fd) }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/event_imp.rs
@@ -0,0 +1,1003 @@
+use {Poll, Token};
+use std::{fmt, io, ops};
+
+/// A value that may be registered with `Poll`
+///
+/// Values that implement `Evented` can be registered with `Poll`. Users of Mio
+/// should not use the `Evented` trait functions directly. Instead, the
+/// equivalent functions on `Poll` should be used.
+///
+/// See [`Poll`] for more details.
+///
+/// # Implementing `Evented`
+///
+/// There are two types of `Evented` values.
+///
+/// * **System** handles, which are backed by sockets or other system handles.
+/// These `Evented` handles will be monitored by the system selector. In this
+/// case, an implementation of `Evented` delegates to a lower level handle.
+///
+/// * **User** handles, which are driven entirely in user space using
+/// [`Registration`] and [`SetReadiness`]. In this case, the implementer takes
+/// responsibility for driving the readiness state changes.
+///
+/// [`Poll`]: struct.Poll.html
+/// [`Registration`]: struct.Registration.html
+/// [`SetReadiness`]: struct.SetReadiness.html
+///
+/// # Examples
+///
+/// Implementing `Evented` on a struct containing a socket:
+///
+/// ```
+/// use mio::{Ready, Poll, PollOpt, Token};
+/// use mio::event::Evented;
+/// use mio::tcp::TcpStream;
+///
+/// use std::io;
+///
+/// pub struct MyEvented {
+///     socket: TcpStream,
+/// }
+///
+/// impl Evented for MyEvented {
+///     fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt)
+///         -> io::Result<()>
+///     {
+///         // Delegate the `register` call to `socket`
+///         self.socket.register(poll, token, interest, opts)
+///     }
+///
+///     fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt)
+///         -> io::Result<()>
+///     {
+///         // Delegate the `reregister` call to `socket`
+///         self.socket.reregister(poll, token, interest, opts)
+///     }
+///
+///     fn deregister(&self, poll: &Poll) -> io::Result<()> {
+///         // Delegate the `deregister` call to `socket`
+///         self.socket.deregister(poll)
+///     }
+/// }
+/// ```
+///
+/// Implement `Evented` using [`Registration`] and [`SetReadiness`].
+///
+/// ```
+/// use mio::{Ready, Registration, Poll, PollOpt, Token};
+/// use mio::event::Evented;
+///
+/// use std::io;
+/// use std::time::Instant;
+/// use std::thread;
+///
+/// pub struct Deadline {
+///     when: Instant,
+///     registration: Registration,
+/// }
+///
+/// impl Deadline {
+///     pub fn new(when: Instant) -> Deadline {
+///         let (registration, set_readiness) = Registration::new2();
+///
+///         thread::spawn(move || {
+///             let now = Instant::now();
+///
+///             if now < when {
+///                 thread::sleep(when - now);
+///             }
+///
+///             set_readiness.set_readiness(Ready::readable());
+///         });
+///
+///         Deadline {
+///             when: when,
+///             registration: registration,
+///         }
+///     }
+///
+///     pub fn is_elapsed(&self) -> bool {
+///         Instant::now() >= self.when
+///     }
+/// }
+///
+/// impl Evented for Deadline {
+///     fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt)
+///         -> io::Result<()>
+///     {
+///         self.registration.register(poll, token, interest, opts)
+///     }
+///
+///     fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt)
+///         -> io::Result<()>
+///     {
+///         self.registration.reregister(poll, token, interest, opts)
+///     }
+///
+///     fn deregister(&self, poll: &Poll) -> io::Result<()> {
+///         self.registration.deregister(poll)
+///     }
+/// }
+/// ```
+pub trait Evented {
+    /// Register `self` with the given `Poll` instance.
+    ///
+    /// This function should not be called directly. Use [`Poll::register`]
+    /// instead. Implementors should handle registration by either delegating
+    /// the call to another `Evented` type or creating a [`Registration`].
+    ///
+    /// See [struct] documentation for more details.
+    ///
+    /// [`Poll::register`]: struct.Poll.html#method.register
+    /// [`Registration`]: struct.Registration.html
+    /// [struct]: #
+    fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()>;
+
+    /// Re-register `self` with the given `Poll` instance.
+    ///
+    /// This function should not be called directly. Use [`Poll::reregister`]
+    /// instead. Implementors should handle re-registration by either delegating
+    /// the call to another `Evented` type or calling [`Registration::update`].
+    ///
+    /// See [struct] documentation for more details.
+    ///
+    /// [`Poll::reregister`]: struct.Poll.html#method.register
+    /// [`Registration::update`]: struct.Registration.html#method.update
+    /// [struct]: #
+    fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()>;
+
+    /// Deregister `self` from the given `Poll` instance
+    ///
+    /// This function should not be called directly. Use [`Poll::deregister`]
+    /// instead. Implementors shuld handle deregistration by either delegating
+    /// the call to another `Evented` type or by dropping the [`Registration`]
+    /// associated with `self`.
+    ///
+    /// See [struct] documentation for more details.
+    ///
+    /// [`Poll::deregister`]: struct.Poll.html#method.deregister
+    /// [`Registration`]: struct.Registration.html
+    /// [struct]: #
+    fn deregister(&self, poll: &Poll) -> io::Result<()>;
+}
+
+/// Options supplied when registering an `Evented` handle with `Poll`
+///
+/// `PollOpt` values can be combined together using the various bitwise
+/// operators.
+///
+/// For high level documentation on polling and poll options, see [`Poll`].
+///
+/// # Examples
+///
+/// ```
+/// use mio::PollOpt;
+///
+/// let opts = PollOpt::edge() | PollOpt::oneshot();
+///
+/// assert!(opts.is_edge());
+/// assert!(opts.is_oneshot());
+/// assert!(!opts.is_level());
+/// ```
+///
+/// [`Poll`]: struct.Poll.html
+#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord)]
+pub struct PollOpt(usize);
+
+impl PollOpt {
+    /// Return a `PollOpt` representing no set options.
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::PollOpt;
+    ///
+    /// let opt = PollOpt::empty();
+    ///
+    /// assert!(!opt.is_level());
+    /// ```
+    ///
+    /// [`Poll`]: struct.Poll.html
+    #[inline]
+    pub fn empty() -> PollOpt {
+        PollOpt(0)
+    }
+
+    /// Return a `PollOpt` representing edge-triggered notifications.
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::PollOpt;
+    ///
+    /// let opt = PollOpt::edge();
+    ///
+    /// assert!(opt.is_edge());
+    /// ```
+    ///
+    /// [`Poll`]: struct.Poll.html
+    #[inline]
+    pub fn edge() -> PollOpt {
+        PollOpt(0b0001)
+    }
+
+    /// Return a `PollOpt` representing level-triggered notifications.
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::PollOpt;
+    ///
+    /// let opt = PollOpt::level();
+    ///
+    /// assert!(opt.is_level());
+    /// ```
+    ///
+    /// [`Poll`]: struct.Poll.html
+    #[inline]
+    pub fn level() -> PollOpt {
+        PollOpt(0b0010)
+    }
+
+    /// Return a `PollOpt` representing oneshot notifications.
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::PollOpt;
+    ///
+    /// let opt = PollOpt::oneshot();
+    ///
+    /// assert!(opt.is_oneshot());
+    /// ```
+    ///
+    /// [`Poll`]: struct.Poll.html
+    #[inline]
+    pub fn oneshot() -> PollOpt {
+        PollOpt(0b0100)
+    }
+
+    #[deprecated(since = "0.6.5", note = "removed")]
+    #[cfg(feature = "with-deprecated")]
+    #[doc(hidden)]
+    #[inline]
+    pub fn urgent() -> PollOpt {
+        PollOpt(0b1000)
+    }
+
+    #[deprecated(since = "0.6.5", note = "removed")]
+    #[cfg(feature = "with-deprecated")]
+    #[doc(hidden)]
+    #[inline]
+    pub fn all() -> PollOpt {
+        PollOpt::edge() | PollOpt::level() | PollOpt::oneshot()
+    }
+
+    /// Returns true if the options include edge-triggered notifications.
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::PollOpt;
+    ///
+    /// let opt = PollOpt::edge();
+    ///
+    /// assert!(opt.is_edge());
+    /// ```
+    ///
+    /// [`Poll`]: struct.Poll.html
+    #[inline]
+    pub fn is_edge(&self) -> bool {
+        self.contains(PollOpt::edge())
+    }
+
+    /// Returns true if the options include level-triggered notifications.
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::PollOpt;
+    ///
+    /// let opt = PollOpt::level();
+    ///
+    /// assert!(opt.is_level());
+    /// ```
+    ///
+    /// [`Poll`]: struct.Poll.html
+    #[inline]
+    pub fn is_level(&self) -> bool {
+        self.contains(PollOpt::level())
+    }
+
+    /// Returns true if the options includes oneshot.
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::PollOpt;
+    ///
+    /// let opt = PollOpt::oneshot();
+    ///
+    /// assert!(opt.is_oneshot());
+    /// ```
+    ///
+    /// [`Poll`]: struct.Poll.html
+    #[inline]
+    pub fn is_oneshot(&self) -> bool {
+        self.contains(PollOpt::oneshot())
+    }
+
+    #[deprecated(since = "0.6.5", note = "removed")]
+    #[cfg(feature = "with-deprecated")]
+    #[doc(hidden)]
+    #[allow(deprecated)]
+    #[inline]
+    pub fn is_urgent(&self) -> bool {
+        self.contains(PollOpt::urgent())
+    }
+
+    #[deprecated(since = "0.6.5", note = "removed")]
+    #[cfg(feature = "with-deprecated")]
+    #[doc(hidden)]
+    #[inline]
+    pub fn bits(&self) -> usize {
+        self.0
+    }
+
+    /// Returns true if `self` is a superset of `other`.
+    ///
+    /// `other` may represent more than one option, in which case the function
+    /// only returns true if `self` contains all of the options specified in
+    /// `other`.
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::PollOpt;
+    ///
+    /// let opt = PollOpt::oneshot();
+    ///
+    /// assert!(opt.contains(PollOpt::oneshot()));
+    /// assert!(!opt.contains(PollOpt::edge()));
+    /// ```
+    ///
+    /// ```
+    /// use mio::PollOpt;
+    ///
+    /// let opt = PollOpt::oneshot() | PollOpt::edge();
+    ///
+    /// assert!(opt.contains(PollOpt::oneshot()));
+    /// assert!(opt.contains(PollOpt::edge()));
+    /// ```
+    ///
+    /// ```
+    /// use mio::PollOpt;
+    ///
+    /// let opt = PollOpt::oneshot() | PollOpt::edge();
+    ///
+    /// assert!(!PollOpt::oneshot().contains(opt));
+    /// assert!(opt.contains(opt));
+    /// assert!((opt | PollOpt::level()).contains(opt));
+    /// ```
+    ///
+    /// [`Poll`]: struct.Poll.html
+    #[inline]
+    pub fn contains(&self, other: PollOpt) -> bool {
+        (*self & other) == other
+    }
+
+    /// Adds all options represented by `other` into `self`.
+    ///
+    /// This is equivalent to `*self = *self | other`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::PollOpt;
+    ///
+    /// let mut opt = PollOpt::empty();
+    /// opt.insert(PollOpt::oneshot());
+    ///
+    /// assert!(opt.is_oneshot());
+    /// ```
+    #[inline]
+    pub fn insert(&mut self, other: PollOpt) {
+        self.0 |= other.0;
+    }
+
+    /// Removes all options represented by `other` from `self`.
+    ///
+    /// This is equivalent to `*self = *self & !other`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::PollOpt;
+    ///
+    /// let mut opt = PollOpt::oneshot();
+    /// opt.remove(PollOpt::oneshot());
+    ///
+    /// assert!(!opt.is_oneshot());
+    /// ```
+    #[inline]
+    pub fn remove(&mut self, other: PollOpt) {
+        self.0 &= !other.0;
+    }
+}
+
+impl ops::BitOr for PollOpt {
+    type Output = PollOpt;
+
+    #[inline]
+    fn bitor(self, other: PollOpt) -> PollOpt {
+        PollOpt(self.0 | other.0)
+    }
+}
+
+impl ops::BitXor for PollOpt {
+    type Output = PollOpt;
+
+    #[inline]
+    fn bitxor(self, other: PollOpt) -> PollOpt {
+        PollOpt(self.0 ^ other.0)
+    }
+}
+
+impl ops::BitAnd for PollOpt {
+    type Output = PollOpt;
+
+    #[inline]
+    fn bitand(self, other: PollOpt) -> PollOpt {
+        PollOpt(self.0 & other.0)
+    }
+}
+
+impl ops::Sub for PollOpt {
+    type Output = PollOpt;
+
+    #[inline]
+    fn sub(self, other: PollOpt) -> PollOpt {
+        PollOpt(self.0 & !other.0)
+    }
+}
+
+impl ops::Not for PollOpt {
+    type Output = PollOpt;
+
+    #[inline]
+    fn not(self) -> PollOpt {
+        PollOpt(!self.0)
+    }
+}
+
+impl fmt::Debug for PollOpt {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        let mut one = false;
+        let flags = [
+            (PollOpt::edge(), "Edge-Triggered"),
+            (PollOpt::level(), "Level-Triggered"),
+            (PollOpt::oneshot(), "OneShot")];
+
+        for &(flag, msg) in &flags {
+            if self.contains(flag) {
+                if one { try!(write!(fmt, " | ")) }
+                try!(write!(fmt, "{}", msg));
+
+                one = true
+            }
+        }
+
+        Ok(())
+    }
+}
+
+/// A set of readiness event kinds
+///
+/// `Ready` is a set of operation descriptors indicating which kind of an
+/// operation is ready to be performed. For example, `Ready::readable()`
+/// indicates that the associated `Evented` handle is ready to perform a
+/// `read` operation.
+///
+/// This struct only represents portable event kinds. Since only readable and
+/// writable events are guaranteed to be raised on all systems, those are the
+/// only ones available via the `Ready` struct. There are also platform specific
+/// extensions to `Ready`, i.e. `UnixReady`, which provide additional readiness
+/// event kinds only available on unix platforms.
+///
+/// `Ready` values can be combined together using the various bitwise operators.
+///
+/// For high level documentation on polling and readiness, see [`Poll`].
+///
+/// # Examples
+///
+/// ```
+/// use mio::Ready;
+///
+/// let ready = Ready::readable() | Ready::writable();
+///
+/// assert!(ready.is_readable());
+/// assert!(ready.is_writable());
+/// ```
+///
+/// [`Poll`]: struct.Poll.html
+/// [`readable`]: #method.readable
+/// [`writable`]: #method.writable
+/// [readiness]: struct.Poll.html#readiness-operations
+#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord)]
+pub struct Ready(usize);
+
+const READABLE: usize = 0b00001;
+const WRITABLE: usize = 0b00010;
+const ERROR: usize    = 0b00100;
+const HUP: usize      = 0b01000;
+
+impl Ready {
+    /// Returns the empty `Ready` set.
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::Ready;
+    ///
+    /// let ready = Ready::empty();
+    ///
+    /// assert!(!ready.is_readable());
+    /// ```
+    ///
+    /// [`Poll`]: struct.Poll.html
+    pub fn empty() -> Ready {
+        Ready(0)
+    }
+
+    #[deprecated(since = "0.6.5", note = "use Ready::empty instead")]
+    #[cfg(feature = "with-deprecated")]
+    #[doc(hidden)]
+    pub fn none() -> Ready {
+        Ready::empty()
+    }
+
+    /// Returns a `Ready` representing readable readiness.
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::Ready;
+    ///
+    /// let ready = Ready::readable();
+    ///
+    /// assert!(ready.is_readable());
+    /// ```
+    ///
+    /// [`Poll`]: struct.Poll.html
+    #[inline]
+    pub fn readable() -> Ready {
+        Ready(READABLE)
+    }
+
+    /// Returns a `Ready` representing writable readiness.
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::Ready;
+    ///
+    /// let ready = Ready::writable();
+    ///
+    /// assert!(ready.is_writable());
+    /// ```
+    ///
+    /// [`Poll`]: struct.Poll.html
+    #[inline]
+    pub fn writable() -> Ready {
+        Ready(WRITABLE)
+    }
+
+    #[deprecated(since = "0.6.5", note = "use UnixReady instead")]
+    #[cfg(feature = "with-deprecated")]
+    #[doc(hidden)]
+    #[inline]
+    pub fn error() -> Ready {
+        Ready(ERROR)
+    }
+
+    #[deprecated(since = "0.6.5", note = "use UnixReady instead")]
+    #[cfg(feature = "with-deprecated")]
+    #[doc(hidden)]
+    #[inline]
+    pub fn hup() -> Ready {
+        Ready(HUP)
+    }
+
+    #[deprecated(since = "0.6.5", note = "removed")]
+    #[cfg(feature = "with-deprecated")]
+    #[doc(hidden)]
+    #[inline]
+    pub fn all() -> Ready {
+        Ready::readable() |
+            Ready::writable()
+    }
+
+    /// Returns true if `Ready` is the empty set
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::Ready;
+    ///
+    /// let ready = Ready::empty();
+    /// assert!(ready.is_empty());
+    /// ```
+    #[inline]
+    pub fn is_empty(&self) -> bool {
+        *self == Ready::empty()
+    }
+
+    #[deprecated(since = "0.6.5", note = "use Ready::is_empty instead")]
+    #[cfg(feature = "with-deprecated")]
+    #[doc(hidden)]
+    #[inline]
+    pub fn is_none(&self) -> bool {
+        self.is_empty()
+    }
+
+    /// Returns true if the value includes readable readiness
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::Ready;
+    ///
+    /// let ready = Ready::readable();
+    ///
+    /// assert!(ready.is_readable());
+    /// ```
+    ///
+    /// [`Poll`]: struct.Poll.html
+    #[inline]
+    pub fn is_readable(&self) -> bool {
+        self.contains(Ready::readable())
+    }
+
+    /// Returns true if the value includes writable readiness
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::Ready;
+    ///
+    /// let ready = Ready::writable();
+    ///
+    /// assert!(ready.is_writable());
+    /// ```
+    ///
+    /// [`Poll`]: struct.Poll.html
+    #[inline]
+    pub fn is_writable(&self) -> bool {
+        self.contains(Ready::writable())
+    }
+
+    #[deprecated(since = "0.6.5", note = "use UnixReady instead")]
+    #[cfg(feature = "with-deprecated")]
+    #[doc(hidden)]
+    #[inline]
+    pub fn is_error(&self) -> bool {
+        self.contains(Ready(ERROR))
+    }
+
+    #[deprecated(since = "0.6.5", note = "use UnixReady instead")]
+    #[cfg(feature = "with-deprecated")]
+    #[doc(hidden)]
+    #[inline]
+    pub fn is_hup(&self) -> bool {
+        self.contains(Ready(HUP))
+    }
+
+    /// Adds all readiness represented by `other` into `self`.
+    ///
+    /// This is equivalent to `*self = *self | other`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::Ready;
+    ///
+    /// let mut readiness = Ready::empty();
+    /// readiness.insert(Ready::readable());
+    ///
+    /// assert!(readiness.is_readable());
+    /// ```
+    #[inline]
+    pub fn insert<T: Into<Self>>(&mut self, other: T) {
+        let other = other.into();
+        self.0 |= other.0;
+    }
+
+    /// Removes all options represented by `other` from `self`.
+    ///
+    /// This is equivalent to `*self = *self & !other`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::Ready;
+    ///
+    /// let mut readiness = Ready::readable();
+    /// readiness.remove(Ready::readable());
+    ///
+    /// assert!(!readiness.is_readable());
+    /// ```
+    #[inline]
+    pub fn remove<T: Into<Self>>(&mut self, other: T) {
+        let other = other.into();
+        self.0 &= !other.0;
+    }
+
+    #[deprecated(since = "0.6.5", note = "removed")]
+    #[cfg(feature = "with-deprecated")]
+    #[doc(hidden)]
+    #[inline]
+    pub fn bits(&self) -> usize {
+        self.0
+    }
+
+    /// Returns true if `self` is a superset of `other`.
+    ///
+    /// `other` may represent more than one readiness operations, in which case
+    /// the function only returns true if `self` contains all readiness
+    /// specified in `other`.
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::Ready;
+    ///
+    /// let readiness = Ready::readable();
+    ///
+    /// assert!(readiness.contains(Ready::readable()));
+    /// assert!(!readiness.contains(Ready::writable()));
+    /// ```
+    ///
+    /// ```
+    /// use mio::Ready;
+    ///
+    /// let readiness = Ready::readable() | Ready::writable();
+    ///
+    /// assert!(readiness.contains(Ready::readable()));
+    /// assert!(readiness.contains(Ready::writable()));
+    /// ```
+    ///
+    /// ```
+    /// use mio::Ready;
+    ///
+    /// let readiness = Ready::readable() | Ready::writable();
+    ///
+    /// assert!(!Ready::readable().contains(readiness));
+    /// assert!(readiness.contains(readiness));
+    /// assert!((readiness | Ready::hup()).contains(readiness));
+    /// ```
+    ///
+    /// [`Poll`]: struct.Poll.html
+    #[inline]
+    pub fn contains<T: Into<Self>>(&self, other: T) -> bool {
+        let other = other.into();
+        (*self & other) == other
+    }
+}
+
+impl<T: Into<Ready>> ops::BitOr<T> for Ready {
+    type Output = Ready;
+
+    #[inline]
+    fn bitor(self, other: T) -> Ready {
+        Ready(self.0 | other.into().0)
+    }
+}
+
+impl<T: Into<Ready>> ops::BitXor<T> for Ready {
+    type Output = Ready;
+
+    #[inline]
+    fn bitxor(self, other: T) -> Ready {
+        Ready(self.0 ^ other.into().0)
+    }
+}
+
+impl<T: Into<Ready>> ops::BitAnd<T> for Ready {
+    type Output = Ready;
+
+    #[inline]
+    fn bitand(self, other: T) -> Ready {
+        Ready(self.0 & other.into().0)
+    }
+}
+
+impl<T: Into<Ready>> ops::Sub<T> for Ready {
+    type Output = Ready;
+
+    #[inline]
+    fn sub(self, other: T) -> Ready {
+        Ready(self.0 & !other.into().0)
+    }
+}
+
+impl ops::Not for Ready {
+    type Output = Ready;
+
+    #[inline]
+    fn not(self) -> Ready {
+        Ready(!self.0)
+    }
+}
+
+// TODO: impl Debug for UnixReady
+impl fmt::Debug for Ready {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        let mut one = false;
+        let flags = [
+            (Ready::readable(), "Readable"),
+            (Ready::writable(), "Writable"),
+            (Ready(ERROR), "Error"),
+            (Ready(HUP), "Hup")];
+
+        try!(write!(fmt, "Ready {{"));
+
+        for &(flag, msg) in &flags {
+            if self.contains(flag) {
+                if one { try!(write!(fmt, " | ")) }
+                try!(write!(fmt, "{}", msg));
+
+                one = true
+            }
+        }
+
+        try!(write!(fmt, "}}"));
+
+        Ok(())
+    }
+}
+
+/// An readiness event returned by [`Poll::poll`].
+///
+/// `Event` is a [readiness state] paired with a [`Token`]. It is returned by
+/// [`Poll::poll`].
+///
+/// For more documentation on polling and events, see [`Poll`].
+///
+/// # Examples
+///
+/// ```
+/// use mio::{Event, Ready, Token};
+///
+/// let event = Event::new(Ready::all(), Token(0));
+///
+/// assert_eq!(event.readiness(), Ready::all());
+/// assert_eq!(event.token(), Token(0));
+/// ```
+///
+/// [`Poll::poll`]: struct.Poll.html#method.poll
+/// [`Poll`]: struct.Poll.html
+/// [readiness state ]: struct.Ready.html
+/// [`Token`]: struct.Token.html
+#[derive(Copy, Clone, Eq, PartialEq, Debug)]
+pub struct Event {
+    kind: Ready,
+    token: Token
+}
+
+impl Event {
+    /// Creates a new `Event` containing `readiness` and `token`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::{Event, Ready, Token};
+    ///
+    /// let event = Event::new(Ready::all(), Token(0));
+    ///
+    /// assert_eq!(event.readiness(), Ready::all());
+    /// assert_eq!(event.token(), Token(0));
+    /// ```
+    pub fn new(readiness: Ready, token: Token) -> Event {
+        Event {
+            kind: readiness,
+            token: token,
+        }
+    }
+
+    /// Returns the event's readiness.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::{Event, Ready, Token};
+    ///
+    /// let event = Event::new(Ready::all(), Token(0));
+    ///
+    /// assert_eq!(event.readiness(), Ready::all());
+    /// ```
+    pub fn readiness(&self) -> Ready {
+        self.kind
+    }
+
+    #[deprecated(since = "0.6.5", note = "use Event::readiness()")]
+    #[cfg(feature = "with-deprecated")]
+    #[doc(hidden)]
+    pub fn kind(&self) -> Ready {
+        self.kind
+    }
+
+    /// Returns the event's token.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::{Event, Ready, Token};
+    ///
+    /// let event = Event::new(Ready::all(), Token(0));
+    ///
+    /// assert_eq!(event.token(), Token(0));
+    /// ```
+    pub fn token(&self) -> Token {
+        self.token
+    }
+}
+
+/*
+ *
+ * ===== Mio internal helpers =====
+ *
+ */
+
+pub fn ready_as_usize(events: Ready) -> usize {
+    events.0
+}
+
+pub fn opt_as_usize(opt: PollOpt) -> usize {
+    opt.0
+}
+
+pub fn ready_from_usize(events: usize) -> Ready {
+    Ready(events)
+}
+
+pub fn opt_from_usize(opt: usize) -> PollOpt {
+    PollOpt(opt)
+}
+
+// Used internally to mutate an `Event` in place
+// Not used on all platforms
+#[allow(dead_code)]
+pub fn kind_mut(event: &mut Event) -> &mut Ready {
+    &mut event.kind
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/io.rs
@@ -0,0 +1,41 @@
+// Re-export the io::Result / Error types for convenience
+pub use std::io::{Read, Write, Result, Error, ErrorKind};
+
+// TODO: Delete this
+/// A helper trait to provide the map_non_block function on Results.
+pub trait MapNonBlock<T> {
+    /// Maps a `Result<T>` to a `Result<Option<T>>` by converting
+    /// operation-would-block errors into `Ok(None)`.
+    fn map_non_block(self) -> Result<Option<T>>;
+}
+
+impl<T> MapNonBlock<T> for Result<T> {
+    fn map_non_block(self) -> Result<Option<T>> {
+        use std::io::ErrorKind::WouldBlock;
+
+        match self {
+            Ok(value) => Ok(Some(value)),
+            Err(err) => {
+                if let WouldBlock = err.kind() {
+                    Ok(None)
+                } else {
+                    Err(err)
+                }
+            }
+        }
+    }
+}
+
+#[cfg(feature = "with-deprecated")]
+pub mod deprecated {
+    #[cfg(unix)]
+    const WOULDBLOCK: i32 = ::libc::EAGAIN;
+
+    #[cfg(windows)]
+    const WOULDBLOCK: i32 = ::winapi::winerror::WSAEWOULDBLOCK as i32;
+
+    /// Returns a std `WouldBlock` error without allocating
+    pub fn would_block() -> ::std::io::Error {
+        ::std::io::Error::from_raw_os_error(WOULDBLOCK)
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/lib.rs
@@ -0,0 +1,266 @@
+//! A fast, low-level IO library for Rust focusing on non-blocking APIs, event
+//! notification, and other useful utilities for building high performance IO
+//! apps.
+//!
+//! # Goals
+//!
+//! * Fast - minimal overhead over the equivalent OS facilities (epoll, kqueue, etc...)
+//! * Zero allocations
+//! * A scalable readiness-based API, similar to epoll on Linux
+//! * Design to allow for stack allocated buffers when possible (avoid double buffering).
+//! * Provide utilities such as a timers, a notification channel, buffer abstractions, and a slab.
+//!
+//! # Usage
+//!
+//! Using mio starts by creating a [`Poll`], which reads events from the OS and
+//! put them into [`Events`]. You can handle IO events from the OS with it.
+//!
+//! For more detail, see [`Poll`].
+//!
+//! [`Poll`]: struct.Poll.html
+//! [`Events`]: struct.Events.html
+//!
+//! # Example
+//!
+//! ```
+//! use mio::*;
+//! use mio::tcp::{TcpListener, TcpStream};
+//!
+//! // Setup some tokens to allow us to identify which event is
+//! // for which socket.
+//! const SERVER: Token = Token(0);
+//! const CLIENT: Token = Token(1);
+//!
+//! let addr = "127.0.0.1:13265".parse().unwrap();
+//!
+//! // Setup the server socket
+//! let server = TcpListener::bind(&addr).unwrap();
+//!
+//! // Create a poll instance
+//! let poll = Poll::new().unwrap();
+//!
+//! // Start listening for incoming connections
+//! poll.register(&server, SERVER, Ready::readable(),
+//!               PollOpt::edge()).unwrap();
+//!
+//! // Setup the client socket
+//! let sock = TcpStream::connect(&addr).unwrap();
+//!
+//! // Register the socket
+//! poll.register(&sock, CLIENT, Ready::readable(),
+//!               PollOpt::edge()).unwrap();
+//!
+//! // Create storage for events
+//! let mut events = Events::with_capacity(1024);
+//!
+//! loop {
+//!     poll.poll(&mut events, None).unwrap();
+//!
+//!     for event in events.iter() {
+//!         match event.token() {
+//!             SERVER => {
+//!                 // Accept and drop the socket immediately, this will close
+//!                 // the socket and notify the client of the EOF.
+//!                 let _ = server.accept();
+//!             }
+//!             CLIENT => {
+//!                 // The server just shuts down the socket, let's just exit
+//!                 // from our event loop.
+//!                 return;
+//!             }
+//!             _ => unreachable!(),
+//!         }
+//!     }
+//! }
+//!
+//! ```
+
+#![doc(html_root_url = "https://docs.rs/mio/0.6.1")]
+#![crate_name = "mio"]
+
+#![deny(warnings, missing_docs, missing_debug_implementations)]
+
+extern crate lazycell;
+extern crate net2;
+extern crate slab;
+extern crate iovec;
+
+#[cfg(unix)]
+extern crate libc;
+
+#[cfg(windows)]
+extern crate miow;
+
+#[cfg(windows)]
+extern crate winapi;
+
+#[cfg(windows)]
+extern crate kernel32;
+
+#[macro_use]
+extern crate log;
+
+#[cfg(test)]
+extern crate env_logger;
+
+mod event_imp;
+mod io;
+mod poll;
+mod sys;
+mod token;
+
+pub mod net;
+
+#[deprecated(since = "0.6.5", note = "use mio-more instead")]
+#[cfg(feature = "with-deprecated")]
+#[doc(hidden)]
+pub mod channel;
+
+#[deprecated(since = "0.6.5", note = "use mio-more instead")]
+#[cfg(feature = "with-deprecated")]
+#[doc(hidden)]
+pub mod timer;
+
+#[deprecated(since = "0.6.5", note = "update to use `Poll`")]
+#[cfg(feature = "with-deprecated")]
+#[doc(hidden)]
+pub mod deprecated;
+
+#[deprecated(since = "0.6.5", note = "use iovec crate directly")]
+#[cfg(feature = "with-deprecated")]
+#[doc(hidden)]
+pub use iovec::IoVec;
+
+#[deprecated(since = "0.6.6", note = "use net module instead")]
+#[cfg(feature = "with-deprecated")]
+#[doc(hidden)]
+pub mod tcp {
+    pub use net::{TcpListener, TcpStream};
+    pub use std::net::Shutdown;
+}
+
+#[deprecated(since = "0.6.6", note = "use net module instead")]
+#[cfg(feature = "with-deprecated")]
+#[doc(hidden)]
+pub mod udp;
+
+pub use poll::{
+    Poll,
+    Registration,
+    SetReadiness,
+};
+pub use event_imp::{
+    PollOpt,
+    Ready,
+};
+pub use token::Token;
+
+pub mod event {
+    //! Readiness event types and utilities.
+
+    pub use super::poll::{Events, Iter};
+    pub use super::event_imp::{Event, Evented};
+}
+
+pub use event::{
+    Events,
+};
+
+#[deprecated(since = "0.6.5", note = "use events:: instead")]
+#[cfg(feature = "with-deprecated")]
+#[doc(hidden)]
+pub use event::{Event, Evented};
+
+#[deprecated(since = "0.6.5", note = "use events::Iter instead")]
+#[cfg(feature = "with-deprecated")]
+#[doc(hidden)]
+pub use poll::Iter as EventsIter;
+
+#[deprecated(since = "0.6.5", note = "std::io::Error can avoid the allocation now")]
+#[cfg(feature = "with-deprecated")]
+#[doc(hidden)]
+pub use io::deprecated::would_block;
+
+#[cfg(unix)]
+pub mod unix {
+    //! Unix only extensions
+    pub use sys::{
+        EventedFd,
+    };
+    pub use sys::unix::UnixReady;
+}
+
+/// Windows-only extensions to the mio crate.
+///
+/// Mio on windows is currently implemented with IOCP for a high-performance
+/// implementation of asynchronous I/O. Mio then provides TCP and UDP as sample
+/// bindings for the system to connect networking types to asynchronous I/O. On
+/// Unix this scheme is then also extensible to all other file descriptors with
+/// the `EventedFd` type, but on Windows no such analog is available. The
+/// purpose of this module, however, is to similarly provide a mechanism for
+/// foreign I/O types to get hooked up into the IOCP event loop.
+///
+/// This module provides two types for interfacing with a custom IOCP handle:
+///
+/// * `Binding` - this type is intended to govern binding with mio's `Poll`
+///   type. Each I/O object should contain an instance of `Binding` that's
+///   interfaced with for the implementation of the `Evented` trait. The
+///   `register`, `reregister`, and `deregister` methods for the `Evented` trait
+///   all have rough analogs with `Binding`.
+///
+///   Note that this type **does not handle readiness**. That is, this type does
+///   not handle whether sockets are readable/writable/etc. It's intended that
+///   IOCP types will internally manage this state with a `SetReadiness` type
+///   from the `poll` module. The `SetReadiness` is typically lazily created on
+///   the first time that `Evented::register` is called and then stored in the
+///   I/O object.
+///
+///   Also note that for types which represent streams of bytes the mio
+///   interface of *readiness* doesn't map directly to the Windows model of
+///   *completion*. This means that types will have to perform internal
+///   buffering to ensure that a readiness interface can be provided. For a
+///   sample implementation see the TCP/UDP modules in mio itself.
+///
+/// * `Overlapped` - this type is intended to be used as the concreate instances
+///   of the `OVERLAPPED` type that most win32 methods expect. It's crucial, for
+///   safety, that all asynchronous operations are initiated with an instance of
+///   `Overlapped` and not another instantiation of `OVERLAPPED`.
+///
+///   Mio's `Overlapped` type is created with a function pointer that receives
+///   a `OVERLAPPED_ENTRY` type when called. This `OVERLAPPED_ENTRY` type is
+///   defined in the `winapi` crate. Whenever a completion is posted to an IOCP
+///   object the `OVERLAPPED` that was signaled will be interpreted as
+///   `Overlapped` in the mio crate and this function pointer will be invoked.
+///   Through this function pointer, and through the `OVERLAPPED` pointer,
+///   implementations can handle management of I/O events.
+///
+/// When put together these two types enable custom Windows handles to be
+/// registered with mio's event loops. The `Binding` type is used to associate
+/// handles and the `Overlapped` type is used to execute I/O operations. When
+/// the I/O operations are completed a custom function pointer is called which
+/// typically modifies a `SetReadiness` set by `Evented` methods which will get
+/// later hooked into the mio event loop.
+#[cfg(windows)]
+pub mod windows {
+
+    pub use sys::{Overlapped, Binding};
+}
+
+#[cfg(feature = "with-deprecated")]
+mod convert {
+    use std::time::Duration;
+
+    const NANOS_PER_MILLI: u32 = 1_000_000;
+    const MILLIS_PER_SEC: u64 = 1_000;
+
+    /// Convert a `Duration` to milliseconds, rounding up and saturating at
+    /// `u64::MAX`.
+    ///
+    /// The saturating is fine because `u64::MAX` milliseconds are still many
+    /// million years.
+    pub fn millis(duration: Duration) -> u64 {
+        // Round up.
+        let millis = (duration.subsec_nanos() + NANOS_PER_MILLI - 1) / NANOS_PER_MILLI;
+        duration.as_secs().saturating_mul(MILLIS_PER_SEC).saturating_add(millis as u64)
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/net/mod.rs
@@ -0,0 +1,14 @@
+//! Networking primitives
+//!
+//! The types provided in this module are non-blocking by default and are
+//! designed to be portable across all supported Mio platforms. As long as the
+//! [portability guidelines] are followed, the behavior should be identical no
+//! matter the target platform.
+//!
+//! [portability guidelines]: ../struct.Poll.html#portability
+
+mod tcp;
+mod udp;
+
+pub use self::tcp::{TcpListener, TcpStream};
+pub use self::udp::UdpSocket;
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/net/tcp.rs
@@ -0,0 +1,670 @@
+//! Primitives for working with TCP
+//!
+//! The types provided in this module are non-blocking by default and are
+//! designed to be portable across all supported Mio platforms. As long as the
+//! [portability guidelines] are followed, the behavior should be identical no
+//! matter the target platform.
+//!
+/// [portability guidelines]: ../struct.Poll.html#portability
+
+
+use std::io::{Read, Write};
+use std::net::{self, SocketAddr, SocketAddrV4, SocketAddrV6, Ipv4Addr, Ipv6Addr};
+use std::time::Duration;
+
+use net2::TcpBuilder;
+use iovec::IoVec;
+
+use {io, sys, Ready, Poll, PollOpt, Token};
+use event::Evented;
+use poll::SelectorId;
+
+/*
+ *
+ * ===== TcpStream =====
+ *
+ */
+
+/// A non-blocking TCP stream between a local socket and a remote socket.
+///
+/// The socket will be closed when the value is dropped.
+///
+/// # Examples
+///
+/// ```
+/// # use std::net::TcpListener;
+/// # let _listener = TcpListener::bind("127.0.0.1:3454").unwrap();
+/// use mio::{Events, Ready, Poll, PollOpt, Token};
+/// use mio::tcp::TcpStream;
+/// use std::time::Duration;
+///
+/// let stream = TcpStream::connect(&"127.0.0.1:34254".parse().unwrap()).unwrap();
+///
+/// let poll = Poll::new().unwrap();
+/// let mut events = Events::with_capacity(128);
+///
+/// // Register the socket with `Poll`
+/// poll.register(&stream, Token(0), Ready::writable(),
+///               PollOpt::edge()).unwrap();
+///
+/// poll.poll(&mut events, Some(Duration::from_millis(100))).unwrap();
+///
+/// // The socket might be ready at this point
+/// ```
+#[derive(Debug)]
+pub struct TcpStream {
+    sys: sys::TcpStream,
+    selector_id: SelectorId,
+}
+
+use std::net::Shutdown;
+
+impl TcpStream {
+    /// Create a new TCP stream and issue a non-blocking connect to the
+    /// specified address.
+    ///
+    /// This convenience method is available and uses the system's default
+    /// options when creating a socket which is then connected. If fine-grained
+    /// control over the creation of the socket is desired, you can use
+    /// `net2::TcpBuilder` to configure a socket and then pass its socket to
+    /// `TcpStream::connect_stream` to transfer ownership into mio and schedule
+    /// the connect operation.
+    pub fn connect(addr: &SocketAddr) -> io::Result<TcpStream> {
+        let sock = try!(match *addr {
+            SocketAddr::V4(..) => TcpBuilder::new_v4(),
+            SocketAddr::V6(..) => TcpBuilder::new_v6(),
+        });
+        // Required on Windows for a future `connect_overlapped` operation to be
+        // executed successfully.
+        if cfg!(windows) {
+            try!(sock.bind(&inaddr_any(addr)));
+        }
+        TcpStream::connect_stream(try!(sock.to_tcp_stream()), addr)
+    }
+
+    /// Creates a new `TcpStream` from the pending socket inside the given
+    /// `std::net::TcpBuilder`, connecting it to the address specified.
+    ///
+    /// This constructor allows configuring the socket before it's actually
+    /// connected, and this function will transfer ownership to the returned
+    /// `TcpStream` if successful. An unconnected `TcpStream` can be created
+    /// with the `net2::TcpBuilder` type (and also configured via that route).
+    ///
+    /// The platform specific behavior of this function looks like:
+    ///
+    /// * On Unix, the socket is placed into nonblocking mode and then a
+    ///   `connect` call is issued.
+    ///
+    /// * On Windows, the address is stored internally and the connect operation
+    ///   is issued when the returned `TcpStream` is registered with an event
+    ///   loop. Note that on Windows you must `bind` a socket before it can be
+    ///   connected, so if a custom `TcpBuilder` is used it should be bound
+    ///   (perhaps to `INADDR_ANY`) before this method is called.
+    pub fn connect_stream(stream: net::TcpStream,
+                          addr: &SocketAddr) -> io::Result<TcpStream> {
+        Ok(TcpStream {
+            sys: try!(sys::TcpStream::connect(stream, addr)),
+            selector_id: SelectorId::new(),
+        })
+    }
+
+    /// Creates a new `TcpStream` from a standard `net::TcpStream`.
+    ///
+    /// This function is intended to be used to wrap a TCP stream from the
+    /// standard library in the mio equivalent. The conversion here will
+    /// automatically set `stream` to nonblocking and the returned object should
+    /// be ready to get associated with an event loop.
+    ///
+    /// Note that the TCP stream here will not have `connect` called on it, so
+    /// it should already be connected via some other means (be it manually, the
+    /// net2 crate, or the standard library).
+    pub fn from_stream(stream: net::TcpStream) -> io::Result<TcpStream> {
+        try!(stream.set_nonblocking(true));
+        Ok(TcpStream {
+            sys: sys::TcpStream::from_stream(stream),
+            selector_id: SelectorId::new(),
+        })
+    }
+
+    /// Returns the socket address of the remote peer of this TCP connection.
+    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+        self.sys.peer_addr()
+    }
+
+    /// Returns the socket address of the local half of this TCP connection.
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
+        self.sys.local_addr()
+    }
+
+    /// Creates a new independently owned handle to the underlying socket.
+    ///
+    /// The returned `TcpStream` is a reference to the same stream that this
+    /// object references. Both handles will read and write the same stream of
+    /// data, and options set on one stream will be propagated to the other
+    /// stream.
+    pub fn try_clone(&self) -> io::Result<TcpStream> {
+        self.sys.try_clone().map(|s| {
+            TcpStream {
+                sys: s,
+                selector_id: self.selector_id.clone(),
+            }
+        })
+    }
+
+    /// Shuts down the read, write, or both halves of this connection.
+    ///
+    /// This function will cause all pending and future I/O on the specified
+    /// portions to return immediately with an appropriate value (see the
+    /// documentation of `Shutdown`).
+    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
+        self.sys.shutdown(how)
+    }
+
+    /// Sets the value of the `TCP_NODELAY` option on this socket.
+    ///
+    /// If set, this option disables the Nagle algorithm. This means that
+    /// segments are always sent as soon as possible, even if there is only a
+    /// small amount of data. When not set, data is buffered until there is a
+    /// sufficient amount to send out, thereby avoiding the frequent sending of
+    /// small packets.
+    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
+        self.sys.set_nodelay(nodelay)
+    }
+
+    /// Gets the value of the `TCP_NODELAY` option on this socket.
+    ///
+    /// For more information about this option, see [`set_nodelay`][link].
+    ///
+    /// [link]: #method.set_nodelay
+    pub fn nodelay(&self) -> io::Result<bool> {
+        self.sys.nodelay()
+    }
+
+    /// Sets the value of the `SO_RCVBUF` option on this socket.
+    ///
+    /// Changes the size of the operating system's receive buffer associated
+    /// with the socket.
+    pub fn set_recv_buffer_size(&self, size: usize) -> io::Result<()> {
+        self.sys.set_recv_buffer_size(size)
+    }
+
+    /// Gets the value of the `SO_RCVBUF` option on this socket.
+    ///
+    /// For more information about this option, see
+    /// [`set_recv_buffer_size`][link].
+    ///
+    /// [link]: #tymethod.set_recv_buffer_size
+    pub fn recv_buffer_size(&self) -> io::Result<usize> {
+        self.sys.recv_buffer_size()
+    }
+
+    /// Sets the value of the `SO_SNDBUF` option on this socket.
+    ///
+    /// Changes the size of the operating system's send buffer associated with
+    /// the socket.
+    pub fn set_send_buffer_size(&self, size: usize) -> io::Result<()> {
+        self.sys.set_send_buffer_size(size)
+    }
+
+    /// Gets the value of the `SO_SNDBUF` option on this socket.
+    ///
+    /// For more information about this option, see [`set_send_buffer`][link].
+    ///
+    /// [link]: #tymethod.set_send_buffer
+    pub fn send_buffer_size(&self) -> io::Result<usize> {
+        self.sys.send_buffer_size()
+    }
+
+    /// Sets whether keepalive messages are enabled to be sent on this socket.
+    ///
+    /// On Unix, this option will set the `SO_KEEPALIVE` as well as the
+    /// `TCP_KEEPALIVE` or `TCP_KEEPIDLE` option (depending on your platform).
+    /// On Windows, this will set the `SIO_KEEPALIVE_VALS` option.
+    ///
+    /// If `None` is specified then keepalive messages are disabled, otherwise
+    /// the duration specified will be the time to remain idle before sending a
+    /// TCP keepalive probe.
+    ///
+    /// Some platforms specify this value in seconds, so sub-second
+    /// specifications may be omitted.
+    pub fn set_keepalive(&self, keepalive: Option<Duration>) -> io::Result<()> {
+        self.sys.set_keepalive(keepalive)
+    }
+
+    /// Returns whether keepalive messages are enabled on this socket, and if so
+    /// the duration of time between them.
+    ///
+    /// For more information about this option, see [`set_keepalive`][link].
+    ///
+    /// [link]: #tymethod.set_keepalive
+    pub fn keepalive(&self) -> io::Result<Option<Duration>> {
+        self.sys.keepalive()
+    }
+
+    /// Sets the value for the `IP_TTL` option on this socket.
+    ///
+    /// This value sets the time-to-live field that is used in every packet sent
+    /// from this socket.
+    pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
+        self.sys.set_ttl(ttl)
+    }
+
+    /// Gets the value of the `IP_TTL` option for this socket.
+    ///
+    /// For more information about this option, see [`set_ttl`][link].
+    ///
+    /// [link]: #tymethod.set_ttl
+    pub fn ttl(&self) -> io::Result<u32> {
+        self.sys.ttl()
+    }
+
+    /// Sets the value for the `IPV6_V6ONLY` option on this socket.
+    ///
+    /// If this is set to `true` then the socket is restricted to sending and
+    /// receiving IPv6 packets only. In this case two IPv4 and IPv6 applications
+    /// can bind the same port at the same time.
+    ///
+    /// If this is set to `false` then the socket can be used to send and
+    /// receive packets from an IPv4-mapped IPv6 address.
+    pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
+        self.sys.set_only_v6(only_v6)
+    }
+
+    /// Gets the value of the `IPV6_V6ONLY` option for this socket.
+    ///
+    /// For more information about this option, see [`set_only_v6`][link].
+    ///
+    /// [link]: #tymethod.set_only_v6
+    pub fn only_v6(&self) -> io::Result<bool> {
+        self.sys.only_v6()
+    }
+
+    /// Sets the linger duration of this socket by setting the SO_LINGER option
+    pub fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
+        self.sys.set_linger(dur)
+    }
+
+    /// reads the linger duration for this socket by getting the SO_LINGER option
+    pub fn linger(&self) -> io::Result<Option<Duration>> {
+        self.sys.linger()
+    }
+
+    #[deprecated(since = "0.6.9", note = "use set_keepalive")]
+    #[cfg(feature = "with-deprecated")]
+    #[doc(hidden)]
+    pub fn set_keepalive_ms(&self, keepalive: Option<u32>) -> io::Result<()> {
+        self.set_keepalive(keepalive.map(|v| Duration::from_millis(v as u64)))
+    }
+
+    #[deprecated(since = "0.6.9", note = "use keepalive")]
+    #[cfg(feature = "with-deprecated")]
+    #[doc(hidden)]
+    pub fn keepalive_ms(&self) -> io::Result<Option<u32>> {
+        self.keepalive().map(|v| {
+            v.map(|v| {
+                ::convert::millis(v) as u32
+            })
+        })
+    }
+
+    /// Get the value of the `SO_ERROR` option on this socket.
+    ///
+    /// This will retrieve the stored error in the underlying socket, clearing
+    /// the field in the process. This can be useful for checking errors between
+    /// calls.
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        self.sys.take_error()
+    }
+
+    /// Read in a list of buffers all at once.
+    ///
+    /// This operation will attempt to read bytes from this socket and place
+    /// them into the list of buffers provided. Note that each buffer is an
+    /// `IoVec` which can be created from a byte slice.
+    ///
+    /// The buffers provided will be filled in sequentially. A buffer will be
+    /// entirely filled up before the next is written to.
+    ///
+    /// The number of bytes read is returned, if successful, or an error is
+    /// returned otherwise. If no bytes are available to be read yet then
+    /// a "would block" error is returned. This operation does not block.
+    ///
+    /// On Unix this corresponds to the `readv` syscall.
+    pub fn read_bufs(&self, bufs: &mut [&mut IoVec]) -> io::Result<usize> {
+        self.sys.readv(bufs)
+    }
+
+    /// Write a list of buffers all at once.
+    ///
+    /// This operation will attempt to write a list of byte buffers to this
+    /// socket. Note that each buffer is an `IoVec` which can be created from a
+    /// byte slice.
+    ///
+    /// The buffers provided will be written sequentially. A buffer will be
+    /// entirely written before the next is written.
+    ///
+    /// The number of bytes written is returned, if successful, or an error is
+    /// returned otherwise. If the socket is not currently writable then a
+    /// "would block" error is returned. This operation does not block.
+    ///
+    /// On Unix this corresponds to the `writev` syscall.
+    pub fn write_bufs(&self, bufs: &[&IoVec]) -> io::Result<usize> {
+        self.sys.writev(bufs)
+    }
+}
+
+fn inaddr_any(other: &SocketAddr) -> SocketAddr {
+    match *other {
+        SocketAddr::V4(..) => {
+            let any = Ipv4Addr::new(0, 0, 0, 0);
+            let addr = SocketAddrV4::new(any, 0);
+            SocketAddr::V4(addr)
+        }
+        SocketAddr::V6(..) => {
+            let any = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);
+            let addr = SocketAddrV6::new(any, 0, 0, 0);
+            SocketAddr::V6(addr)
+        }
+    }
+}
+
+impl Read for TcpStream {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        (&self.sys).read(buf)
+    }
+}
+
+impl<'a> Read for &'a TcpStream {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        (&self.sys).read(buf)
+    }
+}
+
+impl Write for TcpStream {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        (&self.sys).write(buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        (&self.sys).flush()
+    }
+}
+
+impl<'a> Write for &'a TcpStream {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        (&self.sys).write(buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        (&self.sys).flush()
+    }
+}
+
+impl Evented for TcpStream {
+    fn register(&self, poll: &Poll, token: Token,
+                interest: Ready, opts: PollOpt) -> io::Result<()> {
+        try!(self.selector_id.associate_selector(poll));
+        self.sys.register(poll, token, interest, opts)
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token,
+                  interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.sys.reregister(poll, token, interest, opts)
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        self.sys.deregister(poll)
+    }
+}
+
+/*
+ *
+ * ===== TcpListener =====
+ *
+ */
+
+/// A structure representing a socket server
+///
+/// # Examples
+///
+/// ```
+/// use mio::{Events, Ready, Poll, PollOpt, Token};
+/// use mio::tcp::TcpListener;
+/// use std::time::Duration;
+///
+/// let listener = TcpListener::bind(&"127.0.0.1:34254".parse().unwrap()).unwrap();
+///
+/// let poll = Poll::new().unwrap();
+/// let mut events = Events::with_capacity(128);
+///
+/// // Register the socket with `Poll`
+/// poll.register(&listener, Token(0), Ready::writable(),
+///               PollOpt::edge()).unwrap();
+///
+/// poll.poll(&mut events, Some(Duration::from_millis(100))).unwrap();
+///
+/// // There may be a socket ready to be accepted
+/// ```
+#[derive(Debug)]
+pub struct TcpListener {
+    sys: sys::TcpListener,
+    selector_id: SelectorId,
+}
+
+impl TcpListener {
+    /// Convenience method to bind a new TCP listener to the specified address
+    /// to receive new connections.
+    ///
+    /// This function will take the following steps:
+    ///
+    /// 1. Create a new TCP socket.
+    /// 2. Set the `SO_REUSEADDR` option on the socket.
+    /// 3. Bind the socket to the specified address.
+    /// 4. Call `listen` on the socket to prepare it to receive new connections.
+    ///
+    /// If fine-grained control over the binding and listening process for a
+    /// socket is desired then the `net2::TcpBuilder` methods can be used in
+    /// combination with the `TcpListener::from_listener` method to transfer
+    /// ownership into mio.
+    pub fn bind(addr: &SocketAddr) -> io::Result<TcpListener> {
+        // Create the socket
+        let sock = try!(match *addr {
+            SocketAddr::V4(..) => TcpBuilder::new_v4(),
+            SocketAddr::V6(..) => TcpBuilder::new_v6(),
+        });
+
+        // Set SO_REUSEADDR, but only on Unix (mirrors what libstd does)
+        if cfg!(unix) {
+            try!(sock.reuse_address(true));
+        }
+
+        // Bind the socket
+        try!(sock.bind(addr));
+
+        // listen
+        let listener = try!(sock.listen(1024));
+        Ok(TcpListener {
+            sys: try!(sys::TcpListener::new(listener, addr)),
+            selector_id: SelectorId::new(),
+        })
+    }
+
+    /// Creates a new `TcpListener` from an instance of a
+    /// `std::net::TcpListener` type.
+    ///
+    /// This function will set the `listener` provided into nonblocking mode on
+    /// Unix, and otherwise the stream will just be wrapped up in an mio stream
+    /// ready to accept new connections and become associated with an event
+    /// loop.
+    ///
+    /// The address provided must be the address that the listener is bound to.
+    pub fn from_listener(listener: net::TcpListener, addr: &SocketAddr)
+                         -> io::Result<TcpListener> {
+        sys::TcpListener::new(listener, addr).map(|s| {
+            TcpListener {
+                sys: s,
+                selector_id: SelectorId::new(),
+            }
+        })
+    }
+
+    /// Accepts a new `TcpStream`.
+    ///
+    /// This may return an `Err(e)` where `e.kind()` is
+    /// `io::ErrorKind::WouldBlock`. This means a stream may be ready at a later
+    /// point and one should wait for a notification before calling `accept`
+    /// again.
+    ///
+    /// If an accepted stream is returned, the remote address of the peer is
+    /// returned along with it.
+    pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
+        self.sys.accept().map(|(s, a)| {
+            let stream = TcpStream {
+                sys: s,
+                selector_id: SelectorId::new(),
+            };
+
+            (stream, a)
+        })
+    }
+
+    /// Returns the local socket address of this listener.
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
+        self.sys.local_addr()
+    }
+
+    /// Creates a new independently owned handle to the underlying socket.
+    ///
+    /// The returned `TcpListener` is a reference to the same socket that this
+    /// object references. Both handles can be used to accept incoming
+    /// connections and options set on one listener will affect the other.
+    pub fn try_clone(&self) -> io::Result<TcpListener> {
+        self.sys.try_clone().map(|s| {
+            TcpListener {
+                sys: s,
+                selector_id: self.selector_id.clone(),
+            }
+        })
+    }
+
+    /// Sets the value for the `IP_TTL` option on this socket.
+    ///
+    /// This value sets the time-to-live field that is used in every packet sent
+    /// from this socket.
+    pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
+        self.sys.set_ttl(ttl)
+    }
+
+    /// Gets the value of the `IP_TTL` option for this socket.
+    ///
+    /// For more information about this option, see [`set_ttl`][link].
+    ///
+    /// [link]: #method.set_ttl
+    pub fn ttl(&self) -> io::Result<u32> {
+        self.sys.ttl()
+    }
+
+    /// Sets the value for the `IPV6_V6ONLY` option on this socket.
+    ///
+    /// If this is set to `true` then the socket is restricted to sending and
+    /// receiving IPv6 packets only. In this case two IPv4 and IPv6 applications
+    /// can bind the same port at the same time.
+    ///
+    /// If this is set to `false` then the socket can be used to send and
+    /// receive packets from an IPv4-mapped IPv6 address.
+    pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
+        self.sys.set_only_v6(only_v6)
+    }
+
+    /// Gets the value of the `IPV6_V6ONLY` option for this socket.
+    ///
+    /// For more information about this option, see [`set_only_v6`][link].
+    ///
+    /// [link]: #method.set_only_v6
+    pub fn only_v6(&self) -> io::Result<bool> {
+        self.sys.only_v6()
+    }
+
+    /// Get the value of the `SO_ERROR` option on this socket.
+    ///
+    /// This will retrieve the stored error in the underlying socket, clearing
+    /// the field in the process. This can be useful for checking errors between
+    /// calls.
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        self.sys.take_error()
+    }
+}
+
+impl Evented for TcpListener {
+    fn register(&self, poll: &Poll, token: Token,
+                interest: Ready, opts: PollOpt) -> io::Result<()> {
+        try!(self.selector_id.associate_selector(poll));
+        self.sys.register(poll, token, interest, opts)
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token,
+                  interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.sys.reregister(poll, token, interest, opts)
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        self.sys.deregister(poll)
+    }
+}
+
+/*
+ *
+ * ===== UNIX ext =====
+ *
+ */
+
+#[cfg(unix)]
+use std::os::unix::io::{IntoRawFd, AsRawFd, FromRawFd, RawFd};
+
+#[cfg(unix)]
+impl IntoRawFd for TcpStream {
+    fn into_raw_fd(self) -> RawFd {
+        self.sys.into_raw_fd()
+    }
+}
+
+#[cfg(unix)]
+impl AsRawFd for TcpStream {
+    fn as_raw_fd(&self) -> RawFd {
+        self.sys.as_raw_fd()
+    }
+}
+
+#[cfg(unix)]
+impl FromRawFd for TcpStream {
+    unsafe fn from_raw_fd(fd: RawFd) -> TcpStream {
+        TcpStream {
+            sys: FromRawFd::from_raw_fd(fd),
+            selector_id: SelectorId::new(),
+        }
+    }
+}
+
+#[cfg(unix)]
+impl IntoRawFd for TcpListener {
+    fn into_raw_fd(self) -> RawFd {
+        self.sys.into_raw_fd()
+    }
+}
+
+#[cfg(unix)]
+impl AsRawFd for TcpListener {
+    fn as_raw_fd(&self) -> RawFd {
+        self.sys.as_raw_fd()
+    }
+}
+
+#[cfg(unix)]
+impl FromRawFd for TcpListener {
+    unsafe fn from_raw_fd(fd: RawFd) -> TcpListener {
+        TcpListener {
+            sys: FromRawFd::from_raw_fd(fd),
+            selector_id: SelectorId::new(),
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/net/udp.rs
@@ -0,0 +1,304 @@
+//! Primitives for working with UDP
+//!
+//! The types provided in this module are non-blocking by default and are
+//! designed to be portable across all supported Mio platforms. As long as the
+//! [portability guidelines] are followed, the behavior should be identical no
+//! matter the target platform.
+//!
+/// [portability guidelines]: ../struct.Poll.html#portability
+
+use {io, sys, Ready, Poll, PollOpt, Token};
+use event::Evented;
+use poll::SelectorId;
+use std::net::{self, Ipv4Addr, Ipv6Addr, SocketAddr};
+
+/// A User Datagram Protocol socket.
+///
+/// This is an implementation of a bound UDP socket. This supports both IPv4 and
+/// IPv6 addresses, and there is no corresponding notion of a server because UDP
+/// is a datagram protocol.
+#[derive(Debug)]
+pub struct UdpSocket {
+    sys: sys::UdpSocket,
+    selector_id: SelectorId,
+}
+
+impl UdpSocket {
+    /// Creates a UDP socket from the given address.
+    pub fn bind(addr: &SocketAddr) -> io::Result<UdpSocket> {
+        let socket = try!(net::UdpSocket::bind(addr));
+        UdpSocket::from_socket(socket)
+    }
+
+    /// Creates a new mio-wrapped socket from an underlying and bound std
+    /// socket.
+    ///
+    /// This function requires that `socket` has previously been bound to an
+    /// address to work correctly, and returns an I/O object which can be used
+    /// with mio to send/receive UDP messages.
+    ///
+    /// This can be used in conjunction with net2's `UdpBuilder` interface to
+    /// configure a socket before it's handed off to mio, such as setting
+    /// options like `reuse_address` or binding to multiple addresses.
+    pub fn from_socket(socket: net::UdpSocket) -> io::Result<UdpSocket> {
+        Ok(UdpSocket {
+            sys: try!(sys::UdpSocket::new(socket)),
+            selector_id: SelectorId::new(),
+        })
+    }
+
+    /// Returns the socket address that this socket was created from.
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
+        self.sys.local_addr()
+    }
+
+    /// Creates a new independently owned handle to the underlying socket.
+    ///
+    /// The returned `UdpSocket` is a reference to the same socket that this
+    /// object references. Both handles will read and write the same port, and
+    /// options set on one socket will be propagated to the other.
+    pub fn try_clone(&self) -> io::Result<UdpSocket> {
+        self.sys.try_clone()
+            .map(|s| {
+                UdpSocket {
+                    sys: s,
+                    selector_id: self.selector_id.clone(),
+                }
+            })
+    }
+
+    /// Sends data on the socket to the given address. On success, returns the
+    /// number of bytes written.
+    ///
+    /// Address type can be any implementor of `ToSocketAddrs` trait. See its
+    /// documentation for concrete examples.
+    pub fn send_to(&self, buf: &[u8], target: &SocketAddr) -> io::Result<usize> {
+        self.sys.send_to(buf, target)
+    }
+
+    /// Receives data from the socket. On success, returns the number of bytes
+    /// read and the address from whence the data came.
+    pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
+        self.sys.recv_from(buf)
+    }
+
+    /// Sends data on the socket to the address previously bound via connect(). On success,
+    /// returns the number of bytes written.
+    ///
+    /// Address type can be any implementor of `ToSocketAddrs` trait. See its
+    /// documentation for concrete examples.
+    pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
+        self.sys.send(buf)
+    }
+
+    /// Receives data from the socket previously bound with connect(). On success, returns
+    /// the number of bytes read and the address from whence the data came.
+    pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
+        self.sys.recv(buf)
+    }
+
+    /// Connects the UDP socket setting the default destination for `send()`
+    /// and limiting packets that are read via `recv` from the address specified
+    /// in `addr`.
+    pub fn connect(&self, addr: SocketAddr) -> io::Result<()> {
+        self.sys.connect(addr)
+    }
+
+    /// Gets the value of the `SO_BROADCAST` option for this socket.
+    ///
+    /// For more information about this option, see
+    /// [`set_broadcast`][link].
+    ///
+    /// [link]: #method.set_broadcast
+    pub fn broadcast(&self) -> io::Result<bool> {
+        self.sys.broadcast()
+    }
+
+    /// Sets the value of the `SO_BROADCAST` option for this socket.
+    ///
+    /// When enabled, this socket is allowed to send packets to a broadcast
+    /// address.
+    pub fn set_broadcast(&self, on: bool) -> io::Result<()> {
+        self.sys.set_broadcast(on)
+    }
+
+    /// Gets the value of the `IP_MULTICAST_LOOP` option for this socket.
+    ///
+    /// For more information about this option, see
+    /// [`set_multicast_loop_v4`][link].
+    ///
+    /// [link]: #method.set_multicast_loop_v4
+    pub fn multicast_loop_v4(&self) -> io::Result<bool> {
+        self.sys.multicast_loop_v4()
+    }
+
+    /// Sets the value of the `IP_MULTICAST_LOOP` option for this socket.
+    ///
+    /// If enabled, multicast packets will be looped back to the local socket.
+    /// Note that this may not have any affect on IPv6 sockets.
+    pub fn set_multicast_loop_v4(&self, on: bool) -> io::Result<()> {
+        self.sys.set_multicast_loop_v4(on)
+    }
+
+    /// Gets the value of the `IP_MULTICAST_TTL` option for this socket.
+    ///
+    /// For more information about this option, see
+    /// [`set_multicast_ttl_v4`][link].
+    ///
+    /// [link]: #method.set_multicast_ttl_v4
+    pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
+        self.sys.multicast_ttl_v4()
+    }
+
+    /// Sets the value of the `IP_MULTICAST_TTL` option for this socket.
+    ///
+    /// Indicates the time-to-live value of outgoing multicast packets for
+    /// this socket. The default value is 1 which means that multicast packets
+    /// don't leave the local network unless explicitly requested.
+    ///
+    /// Note that this may not have any affect on IPv6 sockets.
+    pub fn set_multicast_ttl_v4(&self, ttl: u32) -> io::Result<()> {
+        self.sys.set_multicast_ttl_v4(ttl)
+    }
+
+    /// Gets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
+    ///
+    /// For more information about this option, see
+    /// [`set_multicast_loop_v6`][link].
+    ///
+    /// [link]: #method.set_multicast_loop_v6
+    pub fn multicast_loop_v6(&self) -> io::Result<bool> {
+        self.sys.multicast_loop_v6()
+    }
+
+    /// Sets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
+    ///
+    /// Controls whether this socket sees the multicast packets it sends itself.
+    /// Note that this may not have any affect on IPv4 sockets.
+    pub fn set_multicast_loop_v6(&self, on: bool) -> io::Result<()> {
+        self.sys.set_multicast_loop_v6(on)
+    }
+
+    /// Gets the value of the `IP_TTL` option for this socket.
+    ///
+    /// For more information about this option, see [`set_ttl`][link].
+    ///
+    /// [link]: #method.set_ttl
+    pub fn ttl(&self) -> io::Result<u32> {
+        self.sys.ttl()
+    }
+
+    /// Sets the value for the `IP_TTL` option on this socket.
+    ///
+    /// This value sets the time-to-live field that is used in every packet sent
+    /// from this socket.
+    pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
+        self.sys.set_ttl(ttl)
+    }
+
+    /// Executes an operation of the `IP_ADD_MEMBERSHIP` type.
+    ///
+    /// This function specifies a new multicast group for this socket to join.
+    /// The address must be a valid multicast address, and `interface` is the
+    /// address of the local interface with which the system should join the
+    /// multicast group. If it's equal to `INADDR_ANY` then an appropriate
+    /// interface is chosen by the system.
+    pub fn join_multicast_v4(&self,
+                             multiaddr: &Ipv4Addr,
+                             interface: &Ipv4Addr) -> io::Result<()> {
+        self.sys.join_multicast_v4(multiaddr, interface)
+    }
+
+    /// Executes an operation of the `IPV6_ADD_MEMBERSHIP` type.
+    ///
+    /// This function specifies a new multicast group for this socket to join.
+    /// The address must be a valid multicast address, and `interface` is the
+    /// index of the interface to join/leave (or 0 to indicate any interface).
+    pub fn join_multicast_v6(&self,
+                             multiaddr: &Ipv6Addr,
+                             interface: u32) -> io::Result<()> {
+        self.sys.join_multicast_v6(multiaddr, interface)
+    }
+
+    /// Executes an operation of the `IP_DROP_MEMBERSHIP` type.
+    ///
+    /// For more information about this option, see
+    /// [`join_multicast_v4`][link].
+    ///
+    /// [link]: #method.join_multicast_v4
+    pub fn leave_multicast_v4(&self,
+                              multiaddr: &Ipv4Addr,
+                              interface: &Ipv4Addr) -> io::Result<()> {
+        self.sys.leave_multicast_v4(multiaddr, interface)
+    }
+
+    /// Executes an operation of the `IPV6_DROP_MEMBERSHIP` type.
+    ///
+    /// For more information about this option, see
+    /// [`join_multicast_v6`][link].
+    ///
+    /// [link]: #method.join_multicast_v6
+    pub fn leave_multicast_v6(&self,
+                              multiaddr: &Ipv6Addr,
+                              interface: u32) -> io::Result<()> {
+        self.sys.leave_multicast_v6(multiaddr, interface)
+    }
+
+    /// Get the value of the `SO_ERROR` option on this socket.
+    ///
+    /// This will retrieve the stored error in the underlying socket, clearing
+    /// the field in the process. This can be useful for checking errors between
+    /// calls.
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        self.sys.take_error()
+    }
+}
+
+impl Evented for UdpSocket {
+    fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        try!(self.selector_id.associate_selector(poll));
+        self.sys.register(poll, token, interest, opts)
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.sys.reregister(poll, token, interest, opts)
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        self.sys.deregister(poll)
+    }
+}
+
+/*
+ *
+ * ===== UNIX ext =====
+ *
+ */
+
+#[cfg(unix)]
+use std::os::unix::io::{IntoRawFd, AsRawFd, FromRawFd, RawFd};
+
+#[cfg(unix)]
+impl IntoRawFd for UdpSocket {
+    fn into_raw_fd(self) -> RawFd {
+        self.sys.into_raw_fd()
+    }
+}
+
+#[cfg(unix)]
+impl AsRawFd for UdpSocket {
+    fn as_raw_fd(&self) -> RawFd {
+        self.sys.as_raw_fd()
+    }
+}
+
+#[cfg(unix)]
+impl FromRawFd for UdpSocket {
+    unsafe fn from_raw_fd(fd: RawFd) -> UdpSocket {
+        UdpSocket {
+            sys: FromRawFd::from_raw_fd(fd),
+            selector_id: SelectorId::new(),
+        }
+    }
+}
+
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/poll.rs
@@ -0,0 +1,2526 @@
+use {sys, Token};
+use event_imp::{self as event, Ready, Event, Evented, PollOpt};
+use std::{fmt, io, ptr, usize};
+use std::cell::UnsafeCell;
+use std::{mem, ops, isize};
+#[cfg(unix)]
+use std::os::unix::io::AsRawFd;
+#[cfg(unix)]
+use std::os::unix::io::RawFd;
+use std::sync::{Arc, Mutex, Condvar};
+use std::sync::atomic::{AtomicUsize, AtomicPtr, AtomicBool};
+use std::sync::atomic::Ordering::{self, Acquire, Release, AcqRel, Relaxed, SeqCst};
+use std::time::{Duration, Instant};
+#[cfg(unix)]
+use sys::unix::UnixReady;
+
+// Poll is backed by two readiness queues. The first is a system readiness queue
+// represented by `sys::Selector`. The system readiness queue handles events
+// provided by the system, such as TCP and UDP. The second readiness queue is
+// implemented in user space by `ReadinessQueue`. It provides a way to implement
+// purely user space `Evented` types.
+//
+// `ReadinessQueue` is is backed by a MPSC queue that supports reuse of linked
+// list nodes. This significantly reduces the number of required allocations.
+// Each `Registration` / `SetReadiness` pair allocates a single readiness node
+// that is used for the lifetime of the registration.
+//
+// The readiness node also includes a single atomic variable, `state` that
+// tracks most of the state associated with the registration. This includes the
+// current readiness, interest, poll options, and internal state. When the node
+// state is mutated, it is queued in the MPSC channel. A call to
+// `ReadinessQueue::poll` will dequeue and process nodes. The node state can
+// still be mutated while it is queued in the channel for processing.
+// Intermediate state values do not matter as long as the final state is
+// included in the call to `poll`. This is the eventually consistent nature of
+// the readiness queue.
+//
+// The readiness node is ref counted using the `ref_count` field. On creation,
+// the ref_count is initialized to 3: one `Registration` handle, one
+// `SetReadiness` handle, and one for the readiness queue. Since the readiness queue
+// doesn't *always* hold a handle to the node, we don't use the Arc type for
+// managing ref counts (this is to avoid constantly incrementing and
+// decrementing the ref count when pushing & popping from the queue). When the
+// `Registration` handle is dropped, the `dropped` flag is set on the node, then
+// the node is pushed into the registration queue. When Poll::poll pops the
+// node, it sees the drop flag is set, and decrements it's ref count.
+//
+// The MPSC queue is a modified version of the intrusive MPSC node based queue
+// described by 1024cores [1].
+//
+// The first modification is that two markers are used instead of a single
+// `stub`. The second marker is a `sleep_marker` which is used to signal to
+// producers that the consumer is going to sleep. This sleep_marker is only used
+// when the queue is empty, implying that the only node in the queue is
+// `end_marker`.
+//
+// The second modification is an `until` argument passed to the dequeue
+// function. When `poll` encounters a level-triggered node, the node will be
+// immediately pushed back into the queue. In order to avoid an infinite loop,
+// `poll` before pushing the node, the pointer is saved off and then passed
+// again as the `until` argument. If the next node to pop is `until`, then
+// `Dequeue::Empty` is returned.
+//
+// [1] http://www.1024cores.net/home/lock-free-algorithms/queues/intrusive-mpsc-node-based-queue
+
+
+/// Polls for readiness events on all registered values.
+///
+/// `Poll` allows a program to monitor a large number of `Evented` types,
+/// waiting until one or more become "ready" for some class of operations; e.g.
+/// reading and writing. An `Evented` type is considered ready if it is possible
+/// to immediately perform a corresponding operation; e.g. [`read`] or
+/// [`write`].
+///
+/// To use `Poll`, an `Evented` type must first be registered with the `Poll`
+/// instance using the [`register`] method, supplying readiness interest. The
+/// readiness interest tells `Poll` which specific operations on the handle to
+/// monitor for readiness. A `Token` is also passed to the [`register`]
+/// function. When `Poll` returns a readiness event, it will include this token.
+/// This associates the event with the `Evented` handle that generated the
+/// event.
+///
+/// [`read`]: tcp/struct.TcpStream.html#method.read
+/// [`write`]: tcp/struct.TcpStream.html#method.write
+/// [`register`]: #method.register
+///
+/// # Examples
+///
+/// A basic example -- establishing a `TcpStream` connection.
+///
+/// ```
+/// use mio::{Events, Poll, Ready, PollOpt, Token};
+/// use mio::tcp::TcpStream;
+///
+/// use std::net::{TcpListener, SocketAddr};
+///
+/// // Bind a server socket to connect to.
+/// let addr: SocketAddr = "127.0.0.1:0".parse().unwrap();
+/// let server = TcpListener::bind(&addr).unwrap();
+///
+/// // Construct a new `Poll` handle as well as the `Events` we'll store into
+/// let poll = Poll::new().unwrap();
+/// let mut events = Events::with_capacity(1024);
+///
+/// // Connect the stream
+/// let stream = TcpStream::connect(&server.local_addr().unwrap()).unwrap();
+///
+/// // Register the stream with `Poll`
+/// poll.register(&stream, Token(0), Ready::all(), PollOpt::edge()).unwrap();
+///
+/// // Wait for the socket to become ready. This has to happens in a loop to
+/// // handle spurious wakeups.
+/// loop {
+///     poll.poll(&mut events, None).unwrap();
+///
+///     for event in &events {
+///         if event.token() == Token(0) && event.readiness().is_writable() {
+///             // The socket connected (probably, it could still be a spurious
+///             // wakeup)
+///             return;
+///         }
+///     }
+/// }
+/// ```
+///
+/// # Edge-triggered and level-triggered
+///
+/// An [`Evented`] registration may request edge-triggered events or
+/// level-triggered events. This is done by setting `register`'s
+/// [`PollOpt`] argument to either [`edge`] or [`level`].
+///
+/// The difference between the two can be described as follows. Supposed that
+/// this scenario happens:
+///
+/// 1. A [`TcpStream`] is registered with `Poll`.
+/// 2. The socket receives 2kb of data.
+/// 3. A call to [`Poll::poll`] returns the token associated with the socket
+///    indicating readable readiness.
+/// 4. 1kb is read from the socket.
+/// 5. Another call to [`Poll::poll`] is made.
+///
+/// If when the socket was registered with `Poll`, edge triggered events were
+/// requested, then the call to [`Poll::poll`] done in step **5** will
+/// (probably) hang despite there being another 1kb still present in the socket
+/// read buffer. The reason for this is that edge-triggered mode delivers events
+/// only when changes occur on the monitored [`Evented`]. So, in step *5* the
+/// caller might end up waiting for some data that is already present inside the
+/// socket buffer.
+///
+/// With edge-triggered events, operations **must** be performed on the
+/// `Evented` type until [`WouldBlock`] is returned. In other words, after
+/// receiving an event indicating readiness for a certain operation, one should
+/// assume that [`Poll::poll`] may never return another event for the same token
+/// and readiness until the operation returns [`WouldBlock`].
+///
+/// By contrast, when level-triggered notfications was requested, each call to
+/// [`Poll::poll`] will return an event for the socket as long as data remains
+/// in the socket buffer. Generally, level-triggered events should be avoided if
+/// high performance is a concern.
+///
+/// Since even with edge-triggered events, multiple events can be generated upon
+/// receipt of multiple chunks of data, the caller has the option to set the
+/// [`oneshot`] flag. This tells `Poll` to disable the associated [`Evented`]
+/// after the event is returned from [`Poll::poll`]. The subsequent calls to
+/// [`Poll::poll`] will no longer include events for [`Evented`] handles that
+/// are disabled even if the readiness state changes. The handle can be
+/// re-enabled by calling [`reregister`]. When handles are disabled, internal
+/// resources used to monitor the handle are maintained until the handle is
+/// dropped or deregistered. This makes re-registering the handle a fast
+/// operation.
+///
+/// For example, in the following scenario:
+///
+/// 1. A [`TcpStream`] is registered with `Poll`.
+/// 2. The socket receives 2kb of data.
+/// 3. A call to [`Poll::poll`] returns the token associated with the socket
+///    indicating readable readiness.
+/// 4. 2kb is read from the socket.
+/// 5. Another call to read is issued and [`WouldBlock`] is returned
+/// 6. The socket receives another 2kb of data.
+/// 7. Another call to [`Poll::poll`] is made.
+///
+/// Assuming the socket was registered with `Poll` with the [`edge`] and
+/// [`oneshot`] options, then the call to [`Poll::poll`] in step 7 would block. This
+/// is because, [`oneshot`] tells `Poll` to disable events for the socket after
+/// returning an event.
+///
+/// In order to receive the event for the data received in step 6, the socket
+/// would need to be reregistered using [`reregister`].
+///
+/// [`PollOpt`]: struct.PollOpt.html
+/// [`edge`]: struct.PollOpt.html#method.edge
+/// [`level`]: struct.PollOpt.html#method.level
+/// [`Poll::poll`]: struct.Poll.html#method.poll
+/// [`WouldBlock`]: https://doc.rust-lang.org/std/io/enum.ErrorKind.html#variant.WouldBlock
+/// [`Evented`]: event/trait.Evented.html
+/// [`TcpStream`]: tcp/struct.TcpStream.html
+/// [`reregister`]: #method.reregister
+/// [`oneshot`]: struct.PollOpt.html#method.oneshot
+///
+/// # Portability
+///
+/// Using `Poll` provides a portable interface across supported platforms as
+/// long as the caller takes the following into consideration:
+///
+/// ### Spurious events
+///
+/// [`Poll::poll`] may return readiness events even if the associated
+/// [`Evented`] handle is not actually ready. Given the same code, this may
+/// happen more on some platforms than others. It is important to never assume
+/// that, just because a readiness notification was received, that the
+/// associated operation will as well.
+///
+/// If operation fails with [`WouldBlock`], then the caller should not treat
+/// this as an error and wait until another readiness event is received.
+///
+/// ### Draining readiness
+///
+/// When using edge-triggered mode, once a readiness event is received, the
+/// corresponding operation must be performed repeatedly until it returns
+/// [`WouldBlock`]. Unless this is done, there is no guarantee that another
+/// readiness event will be delivered, even if further data is received for the
+/// [`Evented`] handle.
+///
+/// For example, in the first scenario described above, after step 5, even if
+/// the socket receives more data there is no guarantee that another readiness
+/// event will be delivered.
+///
+/// ### Readiness operations
+///
+/// The only readiness operations that are guaranteed to be present on all
+/// supported platforms are [`readable`] and [`writable`]. All other readiness
+/// operations may have false negatives and as such should be considered
+/// **hints**. This means that if a socket is registered with [`readable`],
+/// [`error`], and [`hup`] interest, and either an error or hup is received, a
+/// readiness event will be generated for the socket, but it **may** only
+/// include `readable` readiness. Also note that, given the potential for
+/// spurious events, receiving a readiness event with `hup` or `error` doesn't
+/// actually mean that a `read` on the socket will return a result matching the
+/// readiness event.
+///
+/// In other words, portable programs that explicitly check for [`hup`] or
+/// [`error`] readiness should be doing so as an **optimization** and always be
+/// able to handle an error or HUP situation when performing the actual read
+/// operation.
+///
+/// [`readable`]: struct.Ready.html#method.readable
+/// [`writable`]: struct.Ready.html#method.writable
+/// [`error`]: struct.Ready.html#method.error
+/// [`hup`]: struct.Ready.html#method.hup
+///
+/// ### Registering handles
+///
+/// Unless otherwise noted, it should be assumed that types implementing
+/// [`Evented`] will never be become ready unless they are registered with `Poll`.
+///
+/// For example:
+///
+/// ```
+/// use mio::{Poll, Ready, PollOpt, Token};
+/// use mio::tcp::TcpStream;
+/// use std::time::Duration;
+/// use std::thread;
+///
+/// let sock = TcpStream::connect(&"216.58.193.100:80".parse().unwrap()).unwrap();
+///
+/// thread::sleep(Duration::from_secs(1));
+///
+/// let poll = Poll::new().unwrap();
+///
+/// // The connect is not guaranteed to have started until it is registered at
+/// // this point
+/// poll.register(&sock, Token(0), Ready::all(), PollOpt::edge()).unwrap();
+/// ```
+///
+/// # Implementation notes
+///
+/// `Poll` is backed by the selector provided by the operating system.
+///
+/// |      OS    |  Selector |
+/// |------------|-----------|
+/// | Linux      | [epoll]   |
+/// | OS X, iOS  | [kqueue]  |
+/// | Windows    | [IOCP]    |
+/// | FreeBSD    | [kqueue]  |
+/// | Android    | [epoll]   |
+///
+/// On all supported platforms, socket operations are handled by using the
+/// system selector. Platform specific extensions (e.g. [`EventedFd`]) allow
+/// accessing other features provided by individual system selectors. For
+/// example, Linux's [`signalfd`] feature can be used by registering the FD with
+/// `Poll` via [`EventedFd`].
+///
+/// On all platforms except windows, a call to [`Poll::poll`] is mostly just a
+/// direct call to the system selector. However, [IOCP] uses a completion model
+/// instead of a readiness model. In this case, `Poll` must adapt the completion
+/// model Mio's API. While non-trivial, the bridge layer is still quite
+/// efficient. The most expensive part being calls to `read` and `write` require
+/// data to be copied into an intermediate buffer before it is passed to the
+/// kernel.
+///
+/// Notifications generated by [`SetReadiness`] are handled by an internal
+/// readiness queue. A single call to [`Poll::poll`] will collect events from
+/// both from the system selector and the internal readiness queue.
+///
+/// [epoll]: http://man7.org/linux/man-pages/man7/epoll.7.html
+/// [kqueue]: https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2
+/// [IOCP]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365198(v=vs.85).aspx
+/// [`signalfd`]: http://man7.org/linux/man-pages/man2/signalfd.2.html
+/// [`EventedFd`]: unix/struct.EventedFd.html
+/// [`SetReadiness`]: struct.SetReadiness.html
+/// [`Poll::poll`]: struct.Poll.html#method.poll
+pub struct Poll {
+    // Platform specific IO selector
+    selector: sys::Selector,
+
+    // Custom readiness queue
+    readiness_queue: ReadinessQueue,
+
+    // Use an atomic to first check if a full lock will be required. This is a
+    // fast-path check for single threaded cases avoiding the extra syscall
+    lock_state: AtomicUsize,
+
+    // Sequences concurrent calls to `Poll::poll`
+    lock: Mutex<()>,
+
+    // Wakeup the next waiter
+    condvar: Condvar,
+}
+
+/// Handle to a user space `Poll` registration.
+///
+/// `Registration` allows implementing [`Evented`] for types that cannot work
+/// with the [system selector]. A `Registration` is always paired with a
+/// `SetReadiness`, which allows updating the registration's readiness state.
+/// When [`set_readiness`] is called and the `Registration` is associated with a
+/// [`Poll`] instance, a readiness event will be created and eventually returned
+/// by [`poll`].
+///
+/// A `Registration` / `SetReadiness` pair is created by calling
+/// [`Registration::new2`]. At this point, the registration is not being
+/// monitored by a [`Poll`] instance, so calls to `set_readiness` will not
+/// result in any readiness notifications.
+///
+/// `Registration` implements [`Evented`], so it can be used with [`Poll`] using
+/// the same [`register`], [`reregister`], and [`deregister`] functions used
+/// with TCP, UDP, etc... types. Once registered with [`Poll`], readiness state
+/// changes result in readiness events being dispatched to the [`Poll`] instance
+/// with which `Registration` is registered.
+///
+/// **Note**, before using `Registration` be sure to read the
+/// [`set_readiness`] documentation and the [portability] notes. The
+/// guarantees offered by `Registration` may be weaker than expected.
+///
+/// For high level documentation, see [`Poll`].
+///
+/// # Examples
+///
+/// ```
+/// use mio::{Ready, Registration, Poll, PollOpt, Token};
+/// use mio::event::Evented;
+///
+/// use std::io;
+/// use std::time::Instant;
+/// use std::thread;
+///
+/// pub struct Deadline {
+///     when: Instant,
+///     registration: Registration,
+/// }
+///
+/// impl Deadline {
+///     pub fn new(when: Instant) -> Deadline {
+///         let (registration, set_readiness) = Registration::new2();
+///
+///         thread::spawn(move || {
+///             let now = Instant::now();
+///
+///             if now < when {
+///                 thread::sleep(when - now);
+///             }
+///
+///             set_readiness.set_readiness(Ready::readable());
+///         });
+///
+///         Deadline {
+///             when: when,
+///             registration: registration,
+///         }
+///     }
+///
+///     pub fn is_elapsed(&self) -> bool {
+///         Instant::now() >= self.when
+///     }
+/// }
+///
+/// impl Evented for Deadline {
+///     fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt)
+///         -> io::Result<()>
+///     {
+///         self.registration.register(poll, token, interest, opts)
+///     }
+///
+///     fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt)
+///         -> io::Result<()>
+///     {
+///         self.registration.reregister(poll, token, interest, opts)
+///     }
+///
+///     fn deregister(&self, poll: &Poll) -> io::Result<()> {
+///         self.registration.deregister(poll)
+///     }
+/// }
+/// ```
+///
+/// [system selector]: struct.Poll.html#implementation-notes
+/// [`Poll`]: struct.Poll.html
+/// [`Registration::new2`]: struct.Registration.html#method.new2
+/// [`Evented`]: event/trait.Evented.html
+pub struct Registration {
+    inner: RegistrationInner,
+}
+
+unsafe impl Send for Registration {}
+unsafe impl Sync for Registration {}
+
+/// Updates the readiness state of the associated [`Registration`].
+///
+/// See [`Registration`] for more documentation on using `SetReadiness` and
+/// [`Poll`] for high level polling documentation.
+///
+/// [`Registration`]
+#[derive(Clone)]
+pub struct SetReadiness {
+    inner: RegistrationInner,
+}
+
+unsafe impl Send for SetReadiness {}
+unsafe impl Sync for SetReadiness {}
+
+/// Used to associate an IO type with a Selector
+#[derive(Debug)]
+pub struct SelectorId {
+    id: AtomicUsize,
+}
+
+struct RegistrationInner {
+    // Unsafe pointer to the registration's node. The node is ref counted. This
+    // cannot "simply" be tracked by an Arc because `Poll::poll` has an implicit
+    // handle though it isn't stored anywhere. In other words, `Poll::poll`
+    // needs to decrement the ref count before the node is freed.
+    node: *mut ReadinessNode,
+}
+
+#[derive(Clone)]
+struct ReadinessQueue {
+    inner: Arc<ReadinessQueueInner>,
+}
+
+unsafe impl Send for ReadinessQueue {}
+unsafe impl Sync for ReadinessQueue {}
+
+struct ReadinessQueueInner {
+    // Used to wake up `Poll` when readiness is set in another thread.
+    awakener: sys::Awakener,
+
+    // Head of the MPSC queue used to signal readiness to `Poll::poll`.
+    head_readiness: AtomicPtr<ReadinessNode>,
+
+    // Tail of the readiness queue.
+    //
+    // Only accessed by Poll::poll. Coordination will be handled by the poll fn
+    tail_readiness: UnsafeCell<*mut ReadinessNode>,
+
+    // Fake readiness node used to punctuate the end of the readiness queue.
+    // Before attempting to read from the queue, this node is inserted in order
+    // to partition the queue between nodes that are "owned" by the dequeue end
+    // and nodes that will be pushed on by producers.
+    end_marker: Box<ReadinessNode>,
+
+    // Similar to `end_marker`, but this node signals to producers that `Poll`
+    // has gone to sleep and must be woken up.
+    sleep_marker: Box<ReadinessNode>,
+
+    // Similar to `end_marker`, but the node signals that the queue is closed.
+    // This happens when `ReadyQueue` is dropped and signals to producers that
+    // the nodes should no longer be pushed into the queue.
+    closed_marker: Box<ReadinessNode>,
+}
+
+/// Node shared by a `Registration` / `SetReadiness` pair as well as the node
+/// queued into the MPSC channel.
+struct ReadinessNode {
+    // Node state, see struct docs for `ReadinessState`
+    //
+    // This variable is the primary point of coordination between all the
+    // various threads concurrently accessing the node.
+    state: AtomicState,
+
+    // The registration token cannot fit into the `state` variable, so it is
+    // broken out here. In order to atomically update both the state and token
+    // we have to jump through a few hoops.
+    //
+    // First, `state` includes `token_read_pos` and `token_write_pos`. These can
+    // either be 0, 1, or 2 which represent a token slot. `token_write_pos` is
+    // the token slot that contains the most up to date registration token.
+    // `token_read_pos` is the token slot that `poll` is currently reading from.
+    //
+    // When a call to `update` includes a different token than the one currently
+    // associated with the registration (token_write_pos), first an unused token
+    // slot is found. The unused slot is the one not represented by
+    // `token_read_pos` OR `token_write_pos`. The new token is written to this
+    // slot, then `state` is updated with the new `token_write_pos` value. This
+    // requires that there is only a *single* concurrent call to `update`.
+    //
+    // When `poll` reads a node state, it checks that `token_read_pos` matches
+    // `token_write_pos`. If they do not match, then it atomically updates
+    // `state` such that `token_read_pos` is set to `token_write_pos`. It will
+    // then read the token at the newly updated `token_read_pos`.
+    token_0: UnsafeCell<Token>,
+    token_1: UnsafeCell<Token>,
+    token_2: UnsafeCell<Token>,
+
+    // Used when the node is queued in the readiness linked list. Accessing
+    // this field requires winning the "queue" lock
+    next_readiness: AtomicPtr<ReadinessNode>,
+
+    // Ensures that there is only one concurrent call to `update`.
+    //
+    // Each call to `update` will attempt to swap `update_lock` from `false` to
+    // `true`. If the CAS succeeds, the thread has obtained the update lock. If
+    // the CAS fails, then the `update` call returns immediately and the update
+    // is discarded.
+    update_lock: AtomicBool,
+
+    // Pointer to Arc<ReadinessQueueInner>
+    readiness_queue: AtomicPtr<()>,
+
+    // Tracks the number of `ReadyRef` pointers
+    ref_count: AtomicUsize,
+}
+
+/// Stores the ReadinessNode state in an AtomicUsize. This wrapper around the
+/// atomic variable handles encoding / decoding `ReadinessState` values.
+struct AtomicState {
+    inner: AtomicUsize,
+}
+
+const MASK_2: usize = 4 - 1;
+const MASK_4: usize = 16 - 1;
+const QUEUED_MASK: usize = 1 << QUEUED_SHIFT;
+const DROPPED_MASK: usize = 1 << DROPPED_SHIFT;
+
+const READINESS_SHIFT: usize = 0;
+const INTEREST_SHIFT: usize = 4;
+const POLL_OPT_SHIFT: usize = 8;
+const TOKEN_RD_SHIFT: usize = 12;
+const TOKEN_WR_SHIFT: usize = 14;
+const QUEUED_SHIFT: usize = 16;
+const DROPPED_SHIFT: usize = 17;
+
+/// Tracks all state for a single `ReadinessNode`. The state is packed into a
+/// `usize` variable from low to high bit as follows:
+///
+/// 4 bits: Registration current readiness
+/// 4 bits: Registration interest
+/// 4 bits: Poll options
+/// 2 bits: Token position currently being read from by `poll`
+/// 2 bits: Token position last written to by `update`
+/// 1 bit:  Queued flag, set when node is being pushed into MPSC queue.
+/// 1 bit:  Dropped flag, set when all `Registration` handles have been dropped.
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+struct ReadinessState(usize);
+
+/// Returned by `dequeue_node`. Represents the different states as described by
+/// the queue documentation on 1024cores.net.
+enum Dequeue {
+    Data(*mut ReadinessNode),
+    Empty,
+    Inconsistent,
+}
+
+const AWAKEN: Token = Token(usize::MAX);
+const MAX_REFCOUNT: usize = (isize::MAX) as usize;
+
+/*
+ *
+ * ===== Poll =====
+ *
+ */
+
+impl Poll {
+    /// Return a new `Poll` handle.
+    ///
+    /// This function will make a syscall to the operating system to create the
+    /// system selector. If this syscall fails, `Poll::new` will return with the
+    /// error.
+    ///
+    /// See [struct] level docs for more details.
+    ///
+    /// [struct]: struct.Poll.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::{Poll, Events};
+    /// use std::time::Duration;
+    ///
+    /// let poll = match Poll::new() {
+    ///     Ok(poll) => poll,
+    ///     Err(e) => panic!("failed to create Poll instance; err={:?}", e),
+    /// };
+    ///
+    /// // Create a structure to receive polled events
+    /// let mut events = Events::with_capacity(1024);
+    ///
+    /// // Wait for events, but none will be received because no `Evented`
+    /// // handles have been registered with this `Poll` instance.
+    /// let n = poll.poll(&mut events, Some(Duration::from_millis(500))).unwrap();
+    /// assert_eq!(n, 0);
+    /// ```
+    pub fn new() -> io::Result<Poll> {
+        is_send::<Poll>();
+        is_sync::<Poll>();
+
+        let poll = Poll {
+            selector: try!(sys::Selector::new()),
+            readiness_queue: try!(ReadinessQueue::new()),
+            lock_state: AtomicUsize::new(0),
+            lock: Mutex::new(()),
+            condvar: Condvar::new(),
+        };
+
+        // Register the notification wakeup FD with the IO poller
+        try!(poll.readiness_queue.inner.awakener.register(&poll, AWAKEN, Ready::readable(), PollOpt::edge()));
+
+        Ok(poll)
+    }
+
+    /// Register an `Evented` handle with the `Poll` instance.
+    ///
+    /// Once registerd, the `Poll` instance will monitor the `Evented` handle
+    /// for readiness state changes. When it notices a state change, it will
+    /// return a readiness event for the handle the next time [`poll`] is
+    /// called.
+    ///
+    /// See the [`struct`] docs for a high level overview.
+    ///
+    /// # Arguments
+    ///
+    /// `handle: &E: Evented`: This is the handle that the `Poll` instance
+    /// should monitor for readiness state changes.
+    ///
+    /// `token: Token`: The caller picks a token to associate with the socket.
+    /// When [`poll`] returns an event for the handle, this token is included.
+    /// This allows the caller to map the event to its handle. The token
+    /// associated with the `Evented` handle can be changed at any time by
+    /// calling [`reregister`].
+    ///
+    /// `token` cannot be `Token(usize::MAX)` as it is reserved for internal
+    /// usage.
+    ///
+    /// See documentation on [`Token`] for an example showing how to pick
+    /// [`Token`] values.
+    ///
+    /// `interest: Ready`: Specifies which operations `Poll` should monitor for
+    /// readiness. `Poll` will only return readiness events for operations
+    /// specified by this argument.
+    ///
+    /// If a socket is registered with [`readable`] interest and the socket
+    /// becomes writable, no event will be returned from [`poll`].
+    ///
+    /// The readiness interest for an `Evented` handle can be changed at any
+    /// time by calling [`reregister`].
+    ///
+    /// `opts: PollOpt`: Specifies the registration options. The most common
+    /// options being [`level`] for level-triggered events, [`edge`] for
+    /// edge-triggered events, and [`oneshot`].
+    ///
+    /// The registration options for an `Evented` handle can be changed at any
+    /// time by calling [`reregister`].
+    ///
+    /// # Notes
+    ///
+    /// Unless otherwise specified, the caller should assume that once an
+    /// `Evented` handle is registered with a `Poll` instance, it is bound to
+    /// that `Poll` instance for the lifetime of the `Evented` handle. This
+    /// remains true even if the `Evented` handle is deregistered from the poll
+    /// instance using [`deregister`].
+    ///
+    /// This function is **thread safe**. It can be called concurrently from
+    /// multiple threads.
+    ///
+    /// [`struct`]: #
+    /// [`reregister`]: #method.reregister
+    /// [`deregister`]: #method.deregister
+    /// [`poll`]: #method.poll
+    /// [`level`]: struct.PollOpt.html#method.level
+    /// [`edge`]: struct.PollOpt.html#method.edge
+    /// [`oneshot`]: struct.PollOpt.html#method.oneshot
+    /// [`Token`]: struct.Token.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::{Events, Poll, Ready, PollOpt, Token};
+    /// use mio::tcp::TcpStream;
+    /// use std::time::{Duration, Instant};
+    ///
+    /// let poll = Poll::new().unwrap();
+    /// let socket = TcpStream::connect(&"216.58.193.100:80".parse().unwrap()).unwrap();
+    ///
+    /// // Register the socket with `poll`
+    /// poll.register(&socket, Token(0), Ready::all(), PollOpt::edge()).unwrap();
+    ///
+    /// let mut events = Events::with_capacity(1024);
+    /// let start = Instant::now();
+    /// let timeout = Duration::from_millis(500);
+    ///
+    /// loop {
+    ///     let elapsed = start.elapsed();
+    ///
+    ///     if elapsed >= timeout {
+    ///         // Connection timed out
+    ///         return;
+    ///     }
+    ///
+    ///     let remaining = timeout - elapsed;
+    ///     poll.poll(&mut events, Some(remaining)).unwrap();
+    ///
+    ///     for event in &events {
+    ///         if event.token() == Token(0) {
+    ///             // Something (probably) happened on the socket.
+    ///             return;
+    ///         }
+    ///     }
+    /// }
+    /// ```
+    pub fn register<E: ?Sized>(&self, handle: &E, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()>
+        where E: Evented
+    {
+        try!(validate_args(token, interest));
+
+        /*
+         * Undefined behavior:
+         * - Reusing a token with a different `Evented` without deregistering
+         * (or closing) the original `Evented`.
+         */
+        trace!("registering with poller");
+
+        // Register interests for this socket
+        try!(handle.register(self, token, interest, opts));
+
+        Ok(())
+    }
+
+    /// Re-register an `Evented` handle with the `Poll` instance.
+    ///
+    /// Re-registering an `Evented` handle allows changing the details of the
+    /// registration. Specifically, it allows updating the associated `token`,
+    /// `interest`, and `opts` specified in previous `register` and `reregister`
+    /// calls.
+    ///
+    /// The `reregister` arguments fully override the previous values. In other
+    /// words, if a socket is registered with [`readable`] interest and the call
+    /// to `reregister` specifies [`writable`], then read interest is no longer
+    /// requested for the handle.
+    ///
+    /// The `Evented` handle must have previously been registered with this
+    /// instance of `Poll` otherwise the call to `reregister` will return with
+    /// an error.
+    ///
+    /// `token` cannot be `Token(usize::MAX)` as it is reserved for internal
+    /// usage.
+    ///
+    /// See the [`register`] documentation for details about the function
+    /// arguments and see the [`struct`] docs for a high level overview of
+    /// polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::{Poll, Ready, PollOpt, Token};
+    /// use mio::tcp::TcpStream;
+    ///
+    /// let poll = Poll::new().unwrap();
+    /// let socket = TcpStream::connect(&"216.58.193.100:80".parse().unwrap()).unwrap();
+    ///
+    /// // Register the socket with `poll`, requesting readable
+    /// poll.register(&socket, Token(0), Ready::readable(), PollOpt::edge()).unwrap();
+    ///
+    /// // Reregister the socket specifying a different token and write interest
+    /// // instead. `PollOpt::edge()` must be specified even though that value
+    /// // is not being changed.
+    /// poll.reregister(&socket, Token(2), Ready::writable(), PollOpt::edge()).unwrap();
+    /// ```
+    ///
+    /// [`struct`]: #
+    /// [`register`]: #method.register
+    /// [`readable`]: struct.Ready.html#method.readable
+    /// [`writable`]: struct.Ready.html#method.writable
+    pub fn reregister<E: ?Sized>(&self, handle: &E, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()>
+        where E: Evented
+    {
+        try!(validate_args(token, interest));
+
+        trace!("registering with poller");
+
+        // Register interests for this socket
+        try!(handle.reregister(self, token, interest, opts));
+
+        Ok(())
+    }
+
+    /// Deregister an `Evented` handle with the `Poll` instance.
+    ///
+    /// When an `Evented` handle is deregistered, the `Poll` instance will
+    /// no longer monitor it for readiness state changes. Unlike disabling
+    /// handles with [`oneshot`], deregistering clears up any internal resources
+    /// needed to track the handle.
+    ///
+    /// A handle can be passed back to `register` after it has been
+    /// deregistered; however, it must be passed back to the **same** `Poll`
+    /// instance.
+    ///
+    /// `Evented` handles are automatically deregistered when they are dropped.
+    /// It is common to never need to explicitly call `deregister`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::{Events, Poll, Ready, PollOpt, Token};
+    /// use mio::tcp::TcpStream;
+    /// use std::time::Duration;
+    ///
+    /// let poll = Poll::new().unwrap();
+    /// let socket = TcpStream::connect(&"216.58.193.100:80".parse().unwrap()).unwrap();
+    ///
+    /// // Register the socket with `poll`
+    /// poll.register(&socket, Token(0), Ready::readable(), PollOpt::edge()).unwrap();
+    ///
+    /// poll.deregister(&socket).unwrap();
+    ///
+    /// let mut events = Events::with_capacity(1024);
+    ///
+    /// // Set a timeout because this poll should never receive any events.
+    /// let n = poll.poll(&mut events, Some(Duration::from_secs(1))).unwrap();
+    /// assert_eq!(0, n);
+    /// ```
+    pub fn deregister<E: ?Sized>(&self, handle: &E) -> io::Result<()>
+        where E: Evented
+    {
+        trace!("deregistering handle with poller");
+
+        // Deregister interests for this socket
+        try!(handle.deregister(self));
+
+        Ok(())
+    }
+
+    /// Wait for readiness events
+    ///
+    /// Blocks the current thread and waits for readiness events for any of the
+    /// `Evented` handles that have been registered with this `Poll` instance.
+    /// The function will block until either at least one readiness event has
+    /// been received or `timeout` has elapsed. A `timeout` of `None` means that
+    /// `poll` will block until a readiness event has been received.
+    ///
+    /// The supplied `events` will be cleared and newly received readinss events
+    /// will be pushed onto the end. At most `events.capacity()` events will be
+    /// returned. If there are further pending readiness events, they will be
+    /// returned on the next call to `poll`.
+    ///
+    /// A single call to `poll` may result in multiple readiness events being
+    /// returned for a single `Evented` handle. For example, if a TCP socket
+    /// becomes both readable and writable, it may be possible for a single
+    /// readiness event to be returned with both [`readable`] and [`writable`]
+    /// readiness **OR** two separate events may be returned, one with
+    /// [`readable`] set and one with [`writable`] set.
+    ///
+    /// Note that the `timeout` will be rounded up to the system clock
+    /// granularity (usually 1ms), and kernel scheduling delays mean that
+    /// the blocking interval may be overrun by a small amount.
+    ///
+    /// `poll` returns the number of readiness events that have been pushed into
+    /// `events` or `Err` when an error has been encountered with the system
+    /// selector.
+    ///
+    /// See the [struct] level documentation for a higher level discussion of
+    /// polling.
+    ///
+    /// [`readable`]: struct.Ready.html#method.readable
+    /// [`writable`]: struct.Ready.html#method.writable
+    /// [struct]: #
+    ///
+    /// # Examples
+    ///
+    /// A basic example -- establishing a `TcpStream` connection.
+    ///
+    /// ```
+    /// use mio::{Events, Poll, Ready, PollOpt, Token};
+    /// use mio::tcp::TcpStream;
+    ///
+    /// use std::net::{TcpListener, SocketAddr};
+    /// use std::thread;
+    ///
+    /// // Bind a server socket to connect to.
+    /// let addr: SocketAddr = "127.0.0.1:0".parse().unwrap();
+    /// let server = TcpListener::bind(&addr).unwrap();
+    /// let addr = server.local_addr().unwrap().clone();
+    ///
+    /// // Spawn a thread to accept the socket
+    /// thread::spawn(move || {
+    ///     let _ = server.accept();
+    /// });
+    ///
+    /// // Construct a new `Poll` handle as well as the `Events` we'll store into
+    /// let poll = Poll::new().unwrap();
+    /// let mut events = Events::with_capacity(1024);
+    ///
+    /// // Connect the stream
+    /// let stream = TcpStream::connect(&addr).unwrap();
+    ///
+    /// // Register the stream with `Poll`
+    /// poll.register(&stream, Token(0), Ready::all(), PollOpt::edge()).unwrap();
+    ///
+    /// // Wait for the socket to become ready. This has to happens in a loop to
+    /// // handle spurious wakeups.
+    /// loop {
+    ///     poll.poll(&mut events, None).unwrap();
+    ///
+    ///     for event in &events {
+    ///         if event.token() == Token(0) && event.readiness().is_writable() {
+    ///             // The socket connected (probably, it could still be a spurious
+    ///             // wakeup)
+    ///             return;
+    ///         }
+    ///     }
+    /// }
+    /// ```
+    ///
+    /// [struct]: #
+    pub fn poll(&self, events: &mut Events, mut timeout: Option<Duration>) -> io::Result<usize> {
+        let zero = Some(Duration::from_millis(0));
+
+        // At a high level, the synchronization strategy is to acquire access to
+        // the critical section by transitioning the atomic from unlocked ->
+        // locked. If the attempt fails, the thread will wait on the condition
+        // variable.
+        //
+        // # Some more detail
+        //
+        // The `lock_state` atomic usize combines:
+        //
+        // - locked flag, stored in the least significant bit
+        // - number of waiting threads, stored in the rest of the bits.
+        //
+        // When a thread transitions the locked flag from 0 -> 1, it has
+        // obtained access to the critical section.
+        //
+        // When entering `poll`, a compare-and-swap from 0 -> 1 is attempted.
+        // This is a fast path for the case when there are no concurrent calls
+        // to poll, which is very common.
+        //
+        // On failure, the mutex is locked, and the thread attempts to increment
+        // the number of waiting threads component of `lock_state`. If this is
+        // successfully done while the locked flag is set, then the thread can
+        // wait on the condition variable.
+        //
+        // When a thread exits the critical section, it unsets the locked flag.
+        // If there are any waiters, which is atomically determined while
+        // unsetting the locked flag, then the condvar is notified.
+
+        let mut curr = self.lock_state.compare_and_swap(0, 1, SeqCst);
+
+        if 0 != curr {
+            // Enter slower path
+            let mut lock = self.lock.lock().unwrap();
+            let mut inc = false;
+
+            loop {
+                if curr & 1 == 0 {
+                    // The lock is currently free, attempt to grab it
+                    let mut next = curr | 1;
+
+                    if inc {
+                        // The waiter count has previously been incremented, so
+                        // decrement it here
+                        next -= 2;
+                    }
+
+                    let actual = self.lock_state.compare_and_swap(curr, next, SeqCst);
+
+                    if actual != curr {
+                        curr = actual;
+                        continue;
+                    }
+
+                    // Lock acquired, break from the loop
+                    break;
+                }
+
+                if timeout == zero {
+                    if inc {
+                        self.lock_state.fetch_sub(2, SeqCst);
+                    }
+
+                    return Ok(0);
+                }
+
+                // The lock is currently held, so wait for it to become
+                // free. If the waiter count hasn't been incremented yet, do
+                // so now
+                if !inc {
+                    let next = curr.checked_add(2).expect("overflow");
+                    let actual = self.lock_state.compare_and_swap(curr, next, SeqCst);
+
+                    if actual != curr {
+                        curr = actual;
+                        continue;
+                    }
+
+                    // Track that the waiter count has been incremented for
+                    // this thread and fall through to the condvar waiting
+                    inc = true;
+                }
+
+                lock = match timeout {
+                    Some(to) => {
+                        let now = Instant::now();
+
+                        // Wait to be notified
+                        let (l, _) = self.condvar.wait_timeout(lock, to).unwrap();
+
+                        // See how much time was elapsed in the wait
+                        let elapsed = now.elapsed();
+
+                        // Update `timeout` to reflect how much time is left to
+                        // wait.
+                        if elapsed >= to {
+                            timeout = zero;
+                        } else {
+                            // Update the timeout
+                            timeout = Some(to - elapsed);
+                        }
+
+                        l
+                    }
+                    None => {
+                        self.condvar.wait(lock).unwrap()
+                    }
+                };
+
+                // Reload the state
+                curr = self.lock_state.load(SeqCst);
+
+                // Try to lock again...
+            }
+        }
+
+        let ret = self.poll2(events, timeout);
+
+        // Release the lock
+        if 1 != self.lock_state.fetch_and(!1, Release) {
+            // Acquire the mutex
+            let _lock = self.lock.lock().unwrap();
+
+            // There is at least one waiting thread, so notify one
+            self.condvar.notify_one();
+        }
+
+        ret
+    }
+
+    #[inline]
+    fn poll2(&self, events: &mut Events, timeout: Option<Duration>) -> io::Result<usize> {
+        // Compute the timeout value passed to the system selector. If the
+        // readiness queue has pending nodes, we still want to poll the system
+        // selector for new events, but we don't want to block the thread to
+        // wait for new events.
+        let timeout = if timeout == Some(Duration::from_millis(0)) {
+            // If blocking is not requested, then there is no need to prepare
+            // the queue for sleep
+            timeout
+        } else if self.readiness_queue.prepare_for_sleep() {
+            // The readiness queue is empty. The call to `prepare_for_sleep`
+            // inserts `sleep_marker` into the queue. This signals to any
+            // threads setting readiness that the `Poll::poll` is going to
+            // sleep, so the awakener should be used.
+            timeout
+        } else {
+            // The readiness queue is not empty, so do not block the thread.
+            Some(Duration::from_millis(0))
+        };
+
+        // First get selector events
+        let res = self.selector.select(&mut events.inner, AWAKEN, timeout);
+
+        if try!(res) {
+            // Some awakeners require reading from a FD.
+            self.readiness_queue.inner.awakener.cleanup();
+        }
+
+        // Poll custom event queue
+        self.readiness_queue.poll(&mut events.inner);
+
+        // Return number of polled events
+        Ok(events.len())
+    }
+}
+
+#[cfg(unix)]
+fn registerable(interest: Ready) -> bool {
+    let unixinterest = UnixReady::from(interest);
+    unixinterest.is_readable() || unixinterest.is_writable() || unixinterest.is_aio()
+}
+
+#[cfg(not(unix))]
+fn registerable(interest: Ready) -> bool {
+    interest.is_readable() || interest.is_writable()
+}
+
+fn validate_args(token: Token, interest: Ready) -> io::Result<()> {
+    if token == AWAKEN {
+        return Err(io::Error::new(io::ErrorKind::Other, "invalid token"));
+    }
+
+    if !registerable(interest) {
+        return Err(io::Error::new(io::ErrorKind::Other, "interest must include readable or writable or aio"));
+    }
+
+    Ok(())
+}
+
+impl fmt::Debug for Poll {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        write!(fmt, "Poll")
+    }
+}
+
+#[cfg(unix)]
+impl AsRawFd for Poll {
+    fn as_raw_fd(&self) -> RawFd {
+        self.selector.as_raw_fd()
+    }
+}
+
+/// A collection of readiness events.
+///
+/// `Events` is passed as an argument to [`Poll::poll`] and will be used to
+/// receive any new readiness events received since the last call to [`poll`].
+/// Usually, a single `Events` instance is created at the same time as the
+/// [`Poll`] and the single instance is reused for each call to [`poll`].
+///
+/// See [`Poll`] for more documentation on polling.
+///
+/// # Examples
+///
+/// ```
+/// use mio::{Events, Poll};
+/// use std::time::Duration;
+///
+/// let mut events = Events::with_capacity(1024);
+/// let poll = Poll::new().unwrap();
+///
+/// assert_eq!(0, events.len());
+///
+/// // Register `Evented` handles with `poll`
+///
+/// poll.poll(&mut events, Some(Duration::from_millis(100))).unwrap();
+///
+/// for event in &events {
+///     println!("event={:?}", event);
+/// }
+/// ```
+///
+/// [`Poll::poll`]: struct.Poll.html#method.poll
+/// [`poll`]: struct.Poll.html#method.poll
+/// [`Poll`]: struct.Poll.html
+pub struct Events {
+    inner: sys::Events,
+}
+
+/// [`Events`] iterator.
+///
+/// This struct is created by the [`iter`] method on [`Events`].
+///
+/// # Examples
+///
+/// ```
+/// use mio::{Events, Poll};
+/// use std::time::Duration;
+///
+/// let mut events = Events::with_capacity(1024);
+/// let poll = Poll::new().unwrap();
+///
+/// // Register handles with `poll`
+///
+/// poll.poll(&mut events, Some(Duration::from_millis(100))).unwrap();
+///
+/// for event in events.iter() {
+///     println!("event={:?}", event);
+/// }
+/// ```
+///
+/// [`Events`]: struct.Events.html
+/// [`iter`]: struct.Events.html#method.iter
+#[derive(Debug)]
+pub struct Iter<'a> {
+    inner: &'a Events,
+    pos: usize,
+}
+
+impl Events {
+    /// Return a new `Events` capable of holding up to `capacity` events.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::Events;
+    ///
+    /// let events = Events::with_capacity(1024);
+    ///
+    /// assert_eq!(1024, events.capacity());
+    /// ```
+    pub fn with_capacity(capacity: usize) -> Events {
+        Events {
+            inner: sys::Events::with_capacity(capacity),
+        }
+    }
+
+    /// Returns the `Event` at the given index, or `None` if the index is out of
+    /// bounds.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::{Events, Poll};
+    /// use std::time::Duration;
+    ///
+    /// let mut events = Events::with_capacity(1024);
+    /// let poll = Poll::new().unwrap();
+    ///
+    /// // Register handles with `poll`
+    ///
+    /// let n = poll.poll(&mut events, Some(Duration::from_millis(100))).unwrap();
+    ///
+    /// for i in 0..n {
+    ///     println!("event={:?}", events.get(i).unwrap());
+    /// }
+    /// ```
+    pub fn get(&self, idx: usize) -> Option<Event> {
+        self.inner.get(idx)
+    }
+
+    /// Returns the number of `Event` values currently in `self`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::Events;
+    ///
+    /// let events = Events::with_capacity(1024);
+    ///
+    /// assert_eq!(0, events.len());
+    /// ```
+    pub fn len(&self) -> usize {
+        self.inner.len()
+    }
+
+    /// Returns the number of `Event` values that `self` can hold.
+    ///
+    /// ```
+    /// use mio::Events;
+    ///
+    /// let events = Events::with_capacity(1024);
+    ///
+    /// assert_eq!(1024, events.capacity());
+    /// ```
+    pub fn capacity(&self) -> usize {
+        self.inner.capacity()
+    }
+
+    /// Returns `true` if `self` contains no `Event` values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::Events;
+    ///
+    /// let events = Events::with_capacity(1024);
+    ///
+    /// assert!(events.is_empty());
+    /// ```
+    pub fn is_empty(&self) -> bool {
+        self.inner.is_empty()
+    }
+
+    /// Returns an iterator over the `Event` values.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::{Events, Poll};
+    /// use std::time::Duration;
+    ///
+    /// let mut events = Events::with_capacity(1024);
+    /// let poll = Poll::new().unwrap();
+    ///
+    /// // Register handles with `poll`
+    ///
+    /// poll.poll(&mut events, Some(Duration::from_millis(100))).unwrap();
+    ///
+    /// for event in events.iter() {
+    ///     println!("event={:?}", event);
+    /// }
+    /// ```
+    pub fn iter(&self) -> Iter {
+        Iter {
+            inner: self,
+            pos: 0
+        }
+    }
+}
+
+impl<'a> IntoIterator for &'a Events {
+    type Item = Event;
+    type IntoIter = Iter<'a>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        self.iter()
+    }
+}
+
+impl<'a> Iterator for Iter<'a> {
+    type Item = Event;
+
+    fn next(&mut self) -> Option<Event> {
+        let ret = self.inner.get(self.pos);
+        self.pos += 1;
+        ret
+    }
+}
+
+impl fmt::Debug for Events {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Events")
+            .field("len", &self.len())
+            .field("capacity", &self.capacity())
+            .finish()
+    }
+}
+
+// ===== Accessors for internal usage =====
+
+pub fn selector(poll: &Poll) -> &sys::Selector {
+    &poll.selector
+}
+
+/*
+ *
+ * ===== Registration =====
+ *
+ */
+
+// TODO: get rid of this, windows depends on it for now
+#[allow(dead_code)]
+pub fn new_registration(poll: &Poll, token: Token, ready: Ready, opt: PollOpt)
+        -> (Registration, SetReadiness)
+{
+    Registration::new_priv(poll, token, ready, opt)
+}
+
+impl Registration {
+    /// Create and return a new `Registration` and the associated
+    /// `SetReadiness`.
+    ///
+    /// See [struct] documentation for more detail and [`Poll`]
+    /// for high level documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::{Events, Ready, Registration, Poll, PollOpt, Token};
+    /// use std::thread;
+    ///
+    /// let (registration, set_readiness) = Registration::new2();
+    ///
+    /// thread::spawn(move || {
+    ///     use std::time::Duration;
+    ///     thread::sleep(Duration::from_millis(500));
+    ///
+    ///     set_readiness.set_readiness(Ready::readable());
+    /// });
+    ///
+    /// let poll = Poll::new().unwrap();
+    /// poll.register(&registration, Token(0), Ready::all(), PollOpt::edge()).unwrap();
+    ///
+    /// let mut events = Events::with_capacity(256);
+    ///
+    /// loop {
+    ///     poll.poll(&mut events, None);
+    ///
+    ///     for event in &events {
+    ///         if event.token() == Token(0) && event.readiness().is_readable() {
+    ///             return;
+    ///         }
+    ///     }
+    /// }
+    ///
+    /// ```
+    /// [struct]: #
+    /// [`Poll`]: struct.Poll.html
+    pub fn new2() -> (Registration, SetReadiness) {
+        // Allocate the registration node. The new node will have `ref_count`
+        // set to 2: one SetReadiness, one Registration.
+        let node = Box::into_raw(Box::new(ReadinessNode::new(
+                    ptr::null_mut(), Token(0), Ready::empty(), PollOpt::empty(), 2)));
+
+        let registration = Registration {
+            inner: RegistrationInner {
+                node: node,
+            },
+        };
+
+        let set_readiness = SetReadiness {
+            inner: RegistrationInner {
+                node: node,
+            },
+        };
+
+        (registration, set_readiness)
+    }
+
+    #[deprecated(since = "0.6.5", note = "use `new2` instead")]
+    #[cfg(feature = "with-deprecated")]
+    #[doc(hidden)]
+    pub fn new(poll: &Poll, token: Token, interest: Ready, opt: PollOpt)
+        -> (Registration, SetReadiness)
+    {
+        Registration::new_priv(poll, token, interest, opt)
+    }
+
+    // TODO: Get rid of this (windows depends on it for now)
+    fn new_priv(poll: &Poll, token: Token, interest: Ready, opt: PollOpt)
+        -> (Registration, SetReadiness)
+    {
+        is_send::<Registration>();
+        is_sync::<Registration>();
+        is_send::<SetReadiness>();
+        is_sync::<SetReadiness>();
+
+        // Clone handle to the readiness queue, this bumps the ref count
+        let queue = poll.readiness_queue.inner.clone();
+
+        // Convert to a *mut () pointer
+        let queue: *mut () = unsafe { mem::transmute(queue) };
+
+        // Allocate the registration node. The new node will have `ref_count`
+        // set to 3: one SetReadiness, one Registration, and one Poll handle.
+        let node = Box::into_raw(Box::new(ReadinessNode::new(
+                    queue, token, interest, opt, 3)));
+
+        let registration = Registration {
+            inner: RegistrationInner {
+                node: node,
+            },
+        };
+
+        let set_readiness = SetReadiness {
+            inner: RegistrationInner {
+                node: node,
+            },
+        };
+
+        (registration, set_readiness)
+    }
+
+    #[deprecated(since = "0.6.5", note = "use `Evented` impl")]
+    #[cfg(feature = "with-deprecated")]
+    #[doc(hidden)]
+    pub fn update(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.inner.update(poll, token, interest, opts)
+    }
+
+    #[deprecated(since = "0.6.5", note = "use `Evented` impl")]
+    #[cfg(feature = "with-deprecated")]
+    #[doc(hidden)]
+    pub fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        self.inner.update(poll, Token(0), Ready::empty(), PollOpt::empty())
+    }
+}
+
+impl Evented for Registration {
+    fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.inner.update(poll, token, interest, opts)
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.inner.update(poll, token, interest, opts)
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        self.inner.update(poll, Token(0), Ready::empty(), PollOpt::empty())
+    }
+}
+
+impl Drop for Registration {
+    fn drop(&mut self) {
+        // `flag_as_dropped` toggles the `dropped` flag and notifies
+        // `Poll::poll` to release its handle (which is just decrementing
+        // the ref count).
+        if self.inner.state.flag_as_dropped() {
+            // Can't do anything if the queuing fails
+            let _ = self.inner.enqueue_with_wakeup();
+        }
+    }
+}
+
+impl fmt::Debug for Registration {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        fmt.debug_struct("Registration")
+            .finish()
+    }
+}
+
+impl SetReadiness {
+    /// Returns the registration's current readiness.
+    ///
+    /// # Note
+    ///
+    /// There is no guarantee that `readiness` establishes any sort of memory
+    /// ordering. Any concurrent data access must be synchronized using another
+    /// strategy.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::{Registration, Ready};
+    ///
+    /// let (registration, set_readiness) = Registration::new2();
+    ///
+    /// assert!(set_readiness.readiness().is_empty());
+    ///
+    /// set_readiness.set_readiness(Ready::readable()).unwrap();
+    /// assert!(set_readiness.readiness().is_readable());
+    /// ```
+    pub fn readiness(&self) -> Ready {
+        self.inner.readiness()
+    }
+
+    /// Set the registration's readiness
+    ///
+    /// If the associated `Registration` is registered with a [`Poll`] instance
+    /// and has requested readiness events that include `ready`, then a call
+    /// [`poll`] will receive a readiness event representing the readiness
+    /// state change.
+    ///
+    /// # Note
+    ///
+    /// There is no guarantee that `readiness` establishes any sort of memory
+    /// ordering. Any concurrent data access must be synchronized using another
+    /// strategy.
+    ///
+    /// There is also no guarantee as to when the readiness event will be
+    /// delivered to poll. A best attempt will be made to make the delivery in a
+    /// "timely" fashion. For example, the following is **not** guaranteed to
+    /// work:
+    ///
+    /// ```
+    /// use mio::{Events, Registration, Ready, Poll, PollOpt, Token};
+    ///
+    /// let poll = Poll::new().unwrap();
+    /// let (registration, set_readiness) = Registration::new2();
+    ///
+    /// poll.register(&registration,
+    ///               Token(0),
+    ///               Ready::readable(),
+    ///               PollOpt::edge()).unwrap();
+    ///
+    /// // Set the readiness, then immediately poll to try to get the readiness
+    /// // event
+    /// set_readiness.set_readiness(Ready::readable()).unwrap();
+    ///
+    /// let mut events = Events::with_capacity(1024);
+    /// poll.poll(&mut events, None).unwrap();
+    ///
+    /// // There is NO guarantee that the following will work. It is possible
+    /// // that the readiness event will be delivered at a later time.
+    /// let event = events.get(0).unwrap();
+    /// assert_eq!(event.token(), Token(0));
+    /// assert!(event.readiness().is_readable());
+    /// ```
+    ///
+    /// # Examples
+    ///
+    /// A simple example, for a more elaborate example, see the [`Evented`]
+    /// documentation.
+    ///
+    /// ```
+    /// use mio::{Registration, Ready};
+    ///
+    /// let (registration, set_readiness) = Registration::new2();
+    ///
+    /// assert!(set_readiness.readiness().is_empty());
+    ///
+    /// set_readiness.set_readiness(Ready::readable()).unwrap();
+    /// assert!(set_readiness.readiness().is_readable());
+    /// ```
+    ///
+    /// [`Registration`]: struct.Registration.html
+    /// [`Poll`]: struct.Poll.html
+    /// [`poll`]: struct.Poll.html#method.poll
+    pub fn set_readiness(&self, ready: Ready) -> io::Result<()> {
+        self.inner.set_readiness(ready)
+    }
+}
+
+impl fmt::Debug for SetReadiness {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "SetReadiness")
+    }
+}
+
+impl RegistrationInner {
+    /// Get the registration's readiness.
+    fn readiness(&self) -> Ready {
+        self.state.load(Relaxed).readiness()
+    }
+
+    /// Set the registration's readiness.
+    ///
+    /// This function can be called concurrently by an arbitrary number of
+    /// SetReadiness handles.
+    fn set_readiness(&self, ready: Ready) -> io::Result<()> {
+        // Load the current atomic state.
+        let mut state = self.state.load(Acquire);
+        let mut next;
+
+        loop {
+            next = state;
+
+            if state.is_dropped() {
+                // Node is dropped, no more notifications
+                return Ok(());
+            }
+
+            // Update the readiness
+            next.set_readiness(ready);
+
+            // If the readiness is not blank, try to obtain permission to
+            // push the node into the readiness queue.
+            if !next.effective_readiness().is_empty() {
+                next.set_queued();
+            }
+
+            let actual = self.state.compare_and_swap(state, next, AcqRel);
+
+            if state == actual {
+                break;
+            }
+
+            state = actual;
+        }
+
+        if !state.is_queued() && next.is_queued() {
+            // We toggled the queued flag, making us responsible for queuing the
+            // node in the MPSC readiness queue.
+            try!(self.enqueue_with_wakeup());
+        }
+
+        Ok(())
+    }
+
+    /// Update the registration details associated with the node
+    fn update(&self, poll: &Poll, token: Token, interest: Ready, opt: PollOpt) -> io::Result<()> {
+        // First, ensure poll instances match
+        //
+        // Load the queue pointer, `Relaxed` is sufficient here as only the
+        // pointer is being operated on. The actual memory is guaranteed to be
+        // visible the `poll: &Poll` ref passed as an argument to the function.
+        let mut queue = self.readiness_queue.load(Relaxed);
+        let other: &*mut () = unsafe { mem::transmute(&poll.readiness_queue.inner) };
+        let other = *other;
+
+        debug_assert!(mem::size_of::<Arc<ReadinessQueueInner>>() == mem::size_of::<*mut ()>());
+
+        if queue.is_null() {
+            // Attempt to set the queue pointer. `Release` ordering synchronizes
+            // with `Acquire` in `ensure_with_wakeup`.
+            let actual = self.readiness_queue.compare_and_swap(
+                queue, other, Release);
+
+            if actual.is_null() {
+                // The CAS succeeded, this means that the node's ref count
+                // should be incremented to reflect that the `poll` function
+                // effectively owns the node as well.
+                //
+                // `Relaxed` ordering used for the same reason as in
+                // RegistrationInner::clone
+                self.ref_count.fetch_add(1, Relaxed);
+
+                // Note that the `queue` reference stored in our
+                // `readiness_queue` field is intended to be a strong reference,
+                // so now that we've successfully claimed the reference we bump
+                // the refcount here.
+                //
+                // Down below in `release_node` when we deallocate this
+                // `RegistrationInner` is where we'll transmute this back to an
+                // arc and decrement the reference count.
+                mem::forget(poll.readiness_queue.clone());
+            } else {
+                // The CAS failed, another thread set the queue pointer, so ensure
+                // that the pointer and `other` match
+                if actual != other {
+                    return Err(io::Error::new(io::ErrorKind::Other, "registration handle associated with another `Poll` instance"));
+                }
+            }
+
+            queue = other;
+        } else if queue != other {
+            return Err(io::Error::new(io::ErrorKind::Other, "registration handle associated with another `Poll` instance"));
+        }
+
+        unsafe {
+            let actual = &poll.readiness_queue.inner as *const _ as *const usize;
+            debug_assert_eq!(queue as usize, *actual);
+        }
+
+        // The `update_lock` atomic is used as a flag ensuring only a single
+        // thread concurrently enters the `update` critical section. Any
+        // concurrent calls to update are discarded. If coordinated updates are
+        // required, the Mio user is responsible for handling that.
+        //
+        // Acquire / Release ordering is used on `update_lock` to ensure that
+        // data access to the `token_*` variables are scoped to the critical
+        // section.
+
+        // Acquire the update lock.
+        if self.update_lock.compare_and_swap(false, true, Acquire) {
+            // The lock is already held. Discard the update
+            return Ok(());
+        }
+
+        // Relaxed ordering is acceptable here as the only memory that needs to
+        // be visible as part of the update are the `token_*` variables, and
+        // ordering has already been handled by the `update_lock` access.
+        let mut state = self.state.load(Relaxed);
+        let mut next;
+
+        // Read the current token, again this memory has been ordered by the
+        // acquire on `update_lock`.
+        let curr_token_pos = state.token_write_pos();
+        let curr_token = unsafe { self::token(self, curr_token_pos) };
+
+        let mut next_token_pos = curr_token_pos;
+
+        // If the `update` call is changing the token, then compute the next
+        // available token slot and write the token there.
+        //
+        // Note that this computation is happening *outside* of the
+        // compare-and-swap loop. The update lock ensures that only a single
+        // thread could be mutating the write_token_position, so the
+        // `next_token_pos` will never need to be recomputed even if
+        // `token_read_pos` concurrently changes. This is because
+        // `token_read_pos` can ONLY concurrently change to the current value of
+        // `token_write_pos`, so `next_token_pos` will always remain valid.
+        if token != curr_token {
+            next_token_pos = state.next_token_pos();
+
+            // Update the token
+            match next_token_pos {
+                0 => unsafe { *self.token_0.get() = token },
+                1 => unsafe { *self.token_1.get() = token },
+                2 => unsafe { *self.token_2.get() = token },
+                _ => unreachable!(),
+            }
+        }
+
+        // Now enter the compare-and-swap loop
+        loop {
+            next = state;
+
+            // The node is only dropped once all `Registration` handles are
+            // dropped. Only `Registration` can call `update`.
+            debug_assert!(!state.is_dropped());
+
+            // Update the write token position, this will also release the token
+            // to Poll::poll.
+            next.set_token_write_pos(next_token_pos);
+
+            // Update readiness and poll opts
+            next.set_interest(interest);
+            next.set_poll_opt(opt);
+
+            // If there is effective readiness, the node will need to be queued
+            // for processing. This exact behavior is still TBD, so we are
+            // conservative for now and always fire.
+            //
+            // See https://github.com/carllerche/mio/issues/535.
+            if !next.effective_readiness().is_empty() {
+                next.set_queued();
+            }
+
+            // compare-and-swap the state values. Only `Release` is needed here.
+            // The `Release` ensures that `Poll::poll` will see the token
+            // update and the update function doesn't care about any other
+            // memory visibility.
+            let actual = self.state.compare_and_swap(state, next, Release);
+
+            if actual == state {
+                break;
+            }
+
+            // CAS failed, but `curr_token_pos` should not have changed given
+            // that we still hold the update lock.
+            debug_assert_eq!(curr_token_pos, actual.token_write_pos());
+
+            state = actual;
+        }
+
+        // Release the lock
+        self.update_lock.store(false, Release);
+
+        if !state.is_queued() && next.is_queued() {
+            // We are responsible for enqueing the node.
+            try!(enqueue_with_wakeup(queue, self));
+        }
+
+        Ok(())
+    }
+}
+
+impl ops::Deref for RegistrationInner {
+    type Target = ReadinessNode;
+
+    fn deref(&self) -> &ReadinessNode {
+        unsafe { &*self.node }
+    }
+}
+
+impl Clone for RegistrationInner {
+    fn clone(&self) -> RegistrationInner {
+        // Using a relaxed ordering is alright here, as knowledge of the
+        // original reference prevents other threads from erroneously deleting
+        // the object.
+        //
+        // As explained in the [Boost documentation][1], Increasing the
+        // reference counter can always be done with memory_order_relaxed: New
+        // references to an object can only be formed from an existing
+        // reference, and passing an existing reference from one thread to
+        // another must already provide any required synchronization.
+        //
+        // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
+        let old_size = self.ref_count.fetch_add(1, Relaxed);
+
+        // However we need to guard against massive refcounts in case someone
+        // is `mem::forget`ing Arcs. If we don't do this the count can overflow
+        // and users will use-after free. We racily saturate to `isize::MAX` on
+        // the assumption that there aren't ~2 billion threads incrementing
+        // the reference count at once. This branch will never be taken in
+        // any realistic program.
+        //
+        // We abort because such a program is incredibly degenerate, and we
+        // don't care to support it.
+        if old_size & !MAX_REFCOUNT != 0 {
+            // TODO: This should really abort the process
+            panic!();
+        }
+
+        RegistrationInner {
+            node: self.node.clone(),
+        }
+    }
+}
+
+impl Drop for RegistrationInner {
+    fn drop(&mut self) {
+        // Only handles releasing from `Registration` and `SetReadiness`
+        // handles. Poll has to call this itself.
+        release_node(self.node);
+    }
+}
+
+/*
+ *
+ * ===== ReadinessQueue =====
+ *
+ */
+
+impl ReadinessQueue {
+    /// Create a new `ReadinessQueue`.
+    fn new() -> io::Result<ReadinessQueue> {
+        is_send::<Self>();
+        is_sync::<Self>();
+
+        let end_marker = Box::new(ReadinessNode::marker());
+        let sleep_marker = Box::new(ReadinessNode::marker());
+        let closed_marker = Box::new(ReadinessNode::marker());
+
+        let ptr = &*end_marker as *const _ as *mut _;
+
+        Ok(ReadinessQueue {
+            inner: Arc::new(ReadinessQueueInner {
+                awakener: try!(sys::Awakener::new()),
+                head_readiness: AtomicPtr::new(ptr),
+                tail_readiness: UnsafeCell::new(ptr),
+                end_marker: end_marker,
+                sleep_marker: sleep_marker,
+                closed_marker: closed_marker,
+            })
+        })
+    }
+
+    /// Poll the queue for new events
+    fn poll(&self, dst: &mut sys::Events) {
+        // `until` is set with the first node that gets re-enqueued due to being
+        // set to have level-triggered notifications. This prevents an infinite
+        // loop where `Poll::poll` will keep dequeuing nodes it enqueues.
+        let mut until = ptr::null_mut();
+
+        'outer:
+        while dst.len() < dst.capacity() {
+            // Dequeue a node. If the queue is in an inconsistent state, then
+            // stop polling. `Poll::poll` will be called again shortly and enter
+            // a syscall, which should be enough to enable the other thread to
+            // finish the queuing process.
+            let ptr = match unsafe { self.inner.dequeue_node(until) } {
+                Dequeue::Empty | Dequeue::Inconsistent => break,
+                Dequeue::Data(ptr) => ptr,
+            };
+
+            let node = unsafe { &*ptr };
+
+            // Read the node state with Acquire ordering. This allows reading
+            // the token variables.
+            let mut state = node.state.load(Acquire);
+            let mut next;
+            let mut readiness;
+            let mut opt;
+
+            loop {
+                // Build up any changes to the readiness node's state and
+                // attempt the CAS at the end
+                next = state;
+
+                // Given that the node was just read from the queue, the
+                // `queued` flag should still be set.
+                debug_assert!(state.is_queued());
+
+                // The dropped flag means we need to release the node and
+                // perform no further processing on it.
+                if state.is_dropped() {
+                    // Release the node and continue
+                    release_node(ptr);
+                    continue 'outer;
+                }
+
+                // Process the node
+                readiness = state.effective_readiness();
+                opt = state.poll_opt();
+
+                if opt.is_edge() {
+                    // Mark the node as dequeued
+                    next.set_dequeued();
+
+                    if opt.is_oneshot() && !readiness.is_empty() {
+                        next.disarm();
+                    }
+                } else if readiness.is_empty() {
+                    next.set_dequeued();
+                }
+
+                // Ensure `token_read_pos` is set to `token_write_pos` so that
+                // we read the most up to date token value.
+                next.update_token_read_pos();
+
+                if state == next {
+                    break;
+                }
+
+                let actual = node.state.compare_and_swap(state, next, AcqRel);
+
+                if actual == state {
+                    break;
+                }
+
+                state = actual;
+            }
+
+            // If the queued flag is still set, then the node must be requeued.
+            // This typically happens when using level-triggered notifications.
+            if next.is_queued() {
+                if until.is_null() {
+                    // We never want to see the node again
+                    until = ptr;
+                }
+
+                // Requeue the node
+                self.inner.enqueue_node(node);
+            }
+
+            if !readiness.is_empty() {
+                // Get the token
+                let token = unsafe { token(node, next.token_read_pos()) };
+
+                // Push the event
+                dst.push_event(Event::new(readiness, token));
+            }
+        }
+    }
+
+    /// Prepare the queue for the `Poll::poll` thread to block in the system
+    /// selector. This involves changing `head_readiness` to `sleep_marker`.
+    /// Returns true if successfull and `poll` can block.
+    fn prepare_for_sleep(&self) -> bool {
+        let end_marker = self.inner.end_marker();
+        let sleep_marker = self.inner.sleep_marker();
+
+        let tail = unsafe { *self.inner.tail_readiness.get() };
+
+        // If the tail is currently set to the sleep_marker, then check if the
+        // head is as well. If it is, then the queue is currently ready to
+        // sleep. If it is not, then the queue is not empty and there should be
+        // no sleeping.
+        if tail == sleep_marker {
+            return self.inner.head_readiness.load(Acquire) == sleep_marker;
+        }
+
+        // If the tail is not currently set to `end_marker`, then the queue is
+        // not empty.
+        if tail != end_marker {
+            return false;
+        }
+
+        self.inner.sleep_marker.next_readiness.store(ptr::null_mut(), Relaxed);
+
+        let actual = self.inner.head_readiness.compare_and_swap(
+            end_marker, sleep_marker, AcqRel);
+
+        debug_assert!(actual != sleep_marker);
+
+        if actual != end_marker {
+            // The readiness queue is not empty
+            return false;
+        }
+
+        // The current tail should be pointing to `end_marker`
+        debug_assert!(unsafe { *self.inner.tail_readiness.get() == end_marker });
+        // The `end_marker` next pointer should be null
+        debug_assert!(self.inner.end_marker.next_readiness.load(Relaxed).is_null());
+
+        // Update tail pointer.
+        unsafe { *self.inner.tail_readiness.get() = sleep_marker; }
+        true
+    }
+}
+
+impl Drop for ReadinessQueue {
+    fn drop(&mut self) {
+        // Close the queue by enqueuing the closed node
+        self.inner.enqueue_node(&*self.inner.closed_marker);
+
+        loop {
+            // Free any nodes that happen to be left in the readiness queue
+            let ptr = match unsafe { self.inner.dequeue_node(ptr::null_mut()) } {
+                Dequeue::Empty => break,
+                Dequeue::Inconsistent => {
+                    // This really shouldn't be possible as all other handles to
+                    // `ReadinessQueueInner` are dropped, but handle this by
+                    // spinning I guess?
+                    continue;
+                }
+                Dequeue::Data(ptr) => ptr,
+            };
+
+            let node = unsafe { &*ptr };
+
+            let state = node.state.load(Acquire);
+
+            debug_assert!(state.is_queued());
+
+            release_node(ptr);
+        }
+    }
+}
+
+impl ReadinessQueueInner {
+    fn wakeup(&self) -> io::Result<()> {
+        self.awakener.wakeup()
+    }
+
+    /// Prepend the given node to the head of the readiness queue. This is done
+    /// with relaxed ordering. Returns true if `Poll` needs to be woken up.
+    fn enqueue_node_with_wakeup(&self, node: &ReadinessNode) -> io::Result<()> {
+        if self.enqueue_node(node) {
+            try!(self.wakeup());
+        }
+
+        Ok(())
+    }
+
+    /// Push the node into the readiness queue
+    fn enqueue_node(&self, node: &ReadinessNode) -> bool {
+        // This is the 1024cores.net intrusive MPSC queue [1] "push" function.
+        let node_ptr = node as *const _ as *mut _;
+
+        // Relaxed used as the ordering is "released" when swapping
+        // `head_readiness`
+        node.next_readiness.store(ptr::null_mut(), Relaxed);
+
+        unsafe {
+            let mut prev = self.head_readiness.load(Acquire);
+
+            loop {
+                if prev == self.closed_marker() {
+                    debug_assert!(node_ptr != self.closed_marker());
+                    // debug_assert!(node_ptr != self.end_marker());
+                    debug_assert!(node_ptr != self.sleep_marker());
+
+                    if node_ptr != self.end_marker() {
+                        // The readiness queue is shutdown, but the enqueue flag was
+                        // set. This means that we are responsible for decrementing
+                        // the ready queue's ref count
+                        debug_assert!(node.ref_count.load(Relaxed) >= 2);
+                        release_node(node_ptr);
+                    }
+
+                    return false;
+                }
+
+                let act = self.head_readiness.compare_and_swap(prev, node_ptr, AcqRel);
+
+                if prev == act {
+                    break;
+                }
+
+                prev = act;
+            }
+
+            debug_assert!((*prev).next_readiness.load(Relaxed).is_null());
+
+            (*prev).next_readiness.store(node_ptr, Release);
+
+            prev == self.sleep_marker()
+        }
+    }
+
+    /// Must only be called in `poll` or `drop`
+    unsafe fn dequeue_node(&self, until: *mut ReadinessNode) -> Dequeue {
+        // This is the 1024cores.net intrusive MPSC queue [1] "pop" function
+        // with the modifications mentioned at the top of the file.
+        let mut tail = *self.tail_readiness.get();
+        let mut next = (*tail).next_readiness.load(Acquire);
+
+        if tail == self.end_marker() || tail == self.sleep_marker() || tail == self.closed_marker() {
+            if next.is_null() {
+                return Dequeue::Empty;
+            }
+
+            *self.tail_readiness.get() = next;
+            tail = next;
+            next = (*next).next_readiness.load(Acquire);
+        }
+
+        // Only need to check `until` at this point. `until` is either null,
+        // which will never match tail OR it is a node that was pushed by
+        // the current thread. This means that either:
+        //
+        // 1) The queue is inconsistent, which is handled explicitly
+        // 2) We encounter `until` at this point in dequeue
+        // 3) we will pop a different node
+        if tail == until {
+            return Dequeue::Empty;
+        }
+
+        if !next.is_null() {
+            *self.tail_readiness.get() = next;
+            return Dequeue::Data(tail);
+        }
+
+        if self.head_readiness.load(Acquire) != tail {
+            return Dequeue::Inconsistent;
+        }
+
+        // Push the stub node
+        self.enqueue_node(&*self.end_marker);
+
+        next = (*tail).next_readiness.load(Acquire);
+
+        if !next.is_null() {
+            *self.tail_readiness.get() = next;
+            return Dequeue::Data(tail);
+        }
+
+        Dequeue::Inconsistent
+    }
+
+    fn end_marker(&self) -> *mut ReadinessNode {
+        &*self.end_marker as *const ReadinessNode as *mut ReadinessNode
+    }
+
+    fn sleep_marker(&self) -> *mut ReadinessNode {
+        &*self.sleep_marker as *const ReadinessNode as *mut ReadinessNode
+    }
+
+    fn closed_marker(&self) -> *mut ReadinessNode {
+        &*self.closed_marker as *const ReadinessNode as *mut ReadinessNode
+    }
+}
+
+impl ReadinessNode {
+    /// Return a new `ReadinessNode`, initialized with a ref_count of 3.
+    fn new(queue: *mut (),
+           token: Token,
+           interest: Ready,
+           opt: PollOpt,
+           ref_count: usize) -> ReadinessNode
+    {
+        ReadinessNode {
+            state: AtomicState::new(interest, opt),
+            // Only the first token is set, the others are initialized to 0
+            token_0: UnsafeCell::new(token),
+            token_1: UnsafeCell::new(Token(0)),
+            token_2: UnsafeCell::new(Token(0)),
+            next_readiness: AtomicPtr::new(ptr::null_mut()),
+            update_lock: AtomicBool::new(false),
+            readiness_queue: AtomicPtr::new(queue),
+            ref_count: AtomicUsize::new(ref_count),
+        }
+    }
+
+    fn marker() -> ReadinessNode {
+        ReadinessNode {
+            state: AtomicState::new(Ready::empty(), PollOpt::empty()),
+            token_0: UnsafeCell::new(Token(0)),
+            token_1: UnsafeCell::new(Token(0)),
+            token_2: UnsafeCell::new(Token(0)),
+            next_readiness: AtomicPtr::new(ptr::null_mut()),
+            update_lock: AtomicBool::new(false),
+            readiness_queue: AtomicPtr::new(ptr::null_mut()),
+            ref_count: AtomicUsize::new(0),
+        }
+    }
+
+    fn enqueue_with_wakeup(&self) -> io::Result<()> {
+        let queue = self.readiness_queue.load(Acquire);
+
+        if queue.is_null() {
+            // Not associated with a queue, nothing to do
+            return Ok(());
+        }
+
+        enqueue_with_wakeup(queue, self)
+    }
+}
+
+fn enqueue_with_wakeup(queue: *mut (), node: &ReadinessNode) -> io::Result<()> {
+    debug_assert!(!queue.is_null());
+    // This is ugly... but we don't want to bump the ref count.
+    let queue: &Arc<ReadinessQueueInner> = unsafe { mem::transmute(&queue) };
+    queue.enqueue_node_with_wakeup(node)
+}
+
+unsafe fn token(node: &ReadinessNode, pos: usize) -> Token {
+    match pos {
+        0 => *node.token_0.get(),
+        1 => *node.token_1.get(),
+        2 => *node.token_2.get(),
+        _ => unreachable!(),
+    }
+}
+
+fn release_node(ptr: *mut ReadinessNode) {
+    unsafe {
+        // `AcqRel` synchronizes with other `release_node` functions and ensures
+        // that the drop happens after any reads / writes on other threads.
+        if (*ptr).ref_count.fetch_sub(1, AcqRel) != 1 {
+            return;
+        }
+
+        let node = Box::from_raw(ptr);
+
+        // Decrement the readiness_queue Arc
+        let queue = node.readiness_queue.load(Acquire);
+
+        if queue.is_null() {
+            return;
+        }
+
+        let _: Arc<ReadinessQueueInner> = mem::transmute(queue);
+    }
+}
+
+impl AtomicState {
+    fn new(interest: Ready, opt: PollOpt) -> AtomicState {
+        let state = ReadinessState::new(interest, opt);
+
+        AtomicState {
+            inner: AtomicUsize::new(state.into()),
+        }
+    }
+
+    /// Loads the current `ReadinessState`
+    fn load(&self, order: Ordering) -> ReadinessState {
+        self.inner.load(order).into()
+    }
+
+    /// Stores a state if the current state is the same as `current`.
+    fn compare_and_swap(&self, current: ReadinessState, new: ReadinessState, order: Ordering) -> ReadinessState {
+        self.inner.compare_and_swap(current.into(), new.into(), order).into()
+    }
+
+    // Returns `true` if the node should be queued
+    fn flag_as_dropped(&self) -> bool {
+        let prev: ReadinessState = self.inner.fetch_or(DROPPED_MASK | QUEUED_MASK, Release).into();
+        // The flag should not have been previously set
+        debug_assert!(!prev.is_dropped());
+
+        !prev.is_queued()
+    }
+}
+
+impl ReadinessState {
+    // Create a `ReadinessState` initialized with the provided arguments
+    #[inline]
+    fn new(interest: Ready, opt: PollOpt) -> ReadinessState {
+        let interest = event::ready_as_usize(interest);
+        let opt = event::opt_as_usize(opt);
+
+        debug_assert!(interest <= MASK_4);
+        debug_assert!(opt <= MASK_4);
+
+        let mut val = interest << INTEREST_SHIFT;
+        val |= opt << POLL_OPT_SHIFT;
+
+        ReadinessState(val)
+    }
+
+    #[inline]
+    fn get(&self, mask: usize, shift: usize) -> usize{
+        (self.0 >> shift) & mask
+    }
+
+    #[inline]
+    fn set(&mut self, val: usize, mask: usize, shift: usize) {
+        self.0 = (self.0 & !(mask << shift)) | (val << shift)
+    }
+
+    /// Get the readiness
+    #[inline]
+    fn readiness(&self) -> Ready {
+        let v = self.get(MASK_4, READINESS_SHIFT);
+        event::ready_from_usize(v)
+    }
+
+    #[inline]
+    fn effective_readiness(&self) -> Ready {
+        self.readiness() & self.interest()
+    }
+
+    /// Set the readiness
+    #[inline]
+    fn set_readiness(&mut self, v: Ready) {
+        self.set(event::ready_as_usize(v), MASK_4, READINESS_SHIFT);
+    }
+
+    /// Get the interest
+    #[inline]
+    fn interest(&self) -> Ready {
+        let v = self.get(MASK_4, INTEREST_SHIFT);
+        event::ready_from_usize(v)
+    }
+
+    /// Set the interest
+    #[inline]
+    fn set_interest(&mut self, v: Ready) {
+        self.set(event::ready_as_usize(v), MASK_4, INTEREST_SHIFT);
+    }
+
+    #[inline]
+    fn disarm(&mut self) {
+        self.set_interest(Ready::empty());
+    }
+
+    /// Get the poll options
+    #[inline]
+    fn poll_opt(&self) -> PollOpt {
+        let v = self.get(MASK_4, POLL_OPT_SHIFT);
+        event::opt_from_usize(v)
+    }
+
+    /// Set the poll options
+    #[inline]
+    fn set_poll_opt(&mut self, v: PollOpt) {
+        self.set(event::opt_as_usize(v), MASK_4, POLL_OPT_SHIFT);
+    }
+
+    #[inline]
+    fn is_queued(&self) -> bool {
+        self.0 & QUEUED_MASK == QUEUED_MASK
+    }
+
+    /// Set the queued flag
+    #[inline]
+    fn set_queued(&mut self) {
+        // Dropped nodes should never be queued
+        debug_assert!(!self.is_dropped());
+        self.0 |= QUEUED_MASK;
+    }
+
+    #[inline]
+    fn set_dequeued(&mut self) {
+        debug_assert!(self.is_queued());
+        self.0 &= !QUEUED_MASK
+    }
+
+    #[inline]
+    fn is_dropped(&self) -> bool {
+        self.0 & DROPPED_MASK == DROPPED_MASK
+    }
+
+    #[inline]
+    fn token_read_pos(&self) -> usize {
+        self.get(MASK_2, TOKEN_RD_SHIFT)
+    }
+
+    #[inline]
+    fn token_write_pos(&self) -> usize {
+        self.get(MASK_2, TOKEN_WR_SHIFT)
+    }
+
+    #[inline]
+    fn next_token_pos(&self) -> usize {
+        let rd = self.token_read_pos();
+        let wr = self.token_write_pos();
+
+        match wr {
+            0 => {
+                match rd {
+                    1 => 2,
+                    2 => 1,
+                    0 => 1,
+                    _ => unreachable!(),
+                }
+            }
+            1 => {
+                match rd {
+                    0 => 2,
+                    2 => 0,
+                    1 => 2,
+                    _ => unreachable!(),
+                }
+            }
+            2 => {
+                match rd {
+                    0 => 1,
+                    1 => 0,
+                    2 => 0,
+                    _ => unreachable!(),
+                }
+            }
+            _ => unreachable!(),
+        }
+    }
+
+    #[inline]
+    fn set_token_write_pos(&mut self, val: usize) {
+        self.set(val, MASK_2, TOKEN_WR_SHIFT);
+    }
+
+    #[inline]
+    fn update_token_read_pos(&mut self) {
+        let val = self.token_write_pos();
+        self.set(val, MASK_2, TOKEN_RD_SHIFT);
+    }
+}
+
+impl From<ReadinessState> for usize {
+    fn from(src: ReadinessState) -> usize {
+        src.0
+    }
+}
+
+impl From<usize> for ReadinessState {
+    fn from(src: usize) -> ReadinessState {
+        ReadinessState(src)
+    }
+}
+
+fn is_send<T: Send>() {}
+fn is_sync<T: Sync>() {}
+
+impl SelectorId {
+    pub fn new() -> SelectorId {
+        SelectorId {
+            id: AtomicUsize::new(0),
+        }
+    }
+
+    pub fn associate_selector(&self, poll: &Poll) -> io::Result<()> {
+        let selector_id = self.id.load(Ordering::SeqCst);
+
+        if selector_id != 0 && selector_id != poll.selector.id() {
+            Err(io::Error::new(io::ErrorKind::Other, "socket already registered"))
+        } else {
+            self.id.store(poll.selector.id(), Ordering::SeqCst);
+            Ok(())
+        }
+    }
+}
+
+impl Clone for SelectorId {
+    fn clone(&self) -> SelectorId {
+        SelectorId {
+            id: AtomicUsize::new(self.id.load(Ordering::SeqCst)),
+        }
+    }
+}
+
+#[test]
+#[cfg(unix)]
+pub fn as_raw_fd() {
+    let poll = Poll::new().unwrap();
+    assert!(poll.as_raw_fd() > 0);
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/sys/mod.rs
@@ -0,0 +1,35 @@
+#[cfg(unix)]
+pub use self::unix::{
+    Awakener,
+    EventedFd,
+    Events,
+    Io,
+    Selector,
+    TcpStream,
+    TcpListener,
+    UdpSocket,
+    pipe,
+    set_nonblock,
+};
+
+#[cfg(unix)]
+#[cfg(feature = "with-deprecated")]
+pub use self::unix::UnixSocket;
+
+#[cfg(unix)]
+pub mod unix;
+
+#[cfg(windows)]
+pub use self::windows::{
+    Awakener,
+    Events,
+    Selector,
+    TcpStream,
+    TcpListener,
+    UdpSocket,
+    Overlapped,
+    Binding,
+};
+
+#[cfg(windows)]
+mod windows;
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/sys/unix/awakener.rs
@@ -0,0 +1,74 @@
+pub use self::pipe::Awakener;
+
+/// Default awakener backed by a pipe
+mod pipe {
+    use sys::unix;
+    use {io, Ready, Poll, PollOpt, Token};
+    use event::Evented;
+    use std::io::{Read, Write};
+
+    /*
+     *
+     * ===== Awakener =====
+     *
+     */
+
+    pub struct Awakener {
+        reader: unix::Io,
+        writer: unix::Io,
+    }
+
+    impl Awakener {
+        pub fn new() -> io::Result<Awakener> {
+            let (rd, wr) = try!(unix::pipe());
+
+            Ok(Awakener {
+                reader: rd,
+                writer: wr,
+            })
+        }
+
+        pub fn wakeup(&self) -> io::Result<()> {
+            match (&self.writer).write(&[1]) {
+                Ok(_) => Ok(()),
+                Err(e) => {
+                    if e.kind() == io::ErrorKind::WouldBlock {
+                        Ok(())
+                    } else {
+                        Err(e)
+                    }
+                }
+            }
+        }
+
+        pub fn cleanup(&self) {
+            let mut buf = [0; 128];
+
+            loop {
+                // Consume data until all bytes are purged
+                match (&self.reader).read(&mut buf) {
+                    Ok(i) if i > 0 => {},
+                    _ => return,
+                }
+            }
+        }
+
+        fn reader(&self) -> &unix::Io {
+            &self.reader
+        }
+    }
+
+    impl Evented for Awakener {
+        fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+            self.reader().register(poll, token, interest, opts)
+        }
+
+        fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+            self.reader().reregister(poll, token, interest, opts)
+        }
+
+        fn deregister(&self, poll: &Poll) -> io::Result<()> {
+            self.reader().deregister(poll)
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/sys/unix/dlsym.rs
@@ -0,0 +1,47 @@
+use std::marker;
+use std::mem;
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+use libc;
+
+macro_rules! dlsym {
+    (fn $name:ident($($t:ty),*) -> $ret:ty) => (
+        #[allow(bad_style)]
+        static $name: ::sys::unix::dlsym::DlSym<unsafe extern fn($($t),*) -> $ret> =
+            ::sys::unix::dlsym::DlSym {
+                name: concat!(stringify!($name), "\0"),
+                addr: ::std::sync::atomic::ATOMIC_USIZE_INIT,
+                _marker: ::std::marker::PhantomData,
+            };
+    )
+}
+
+pub struct DlSym<F> {
+    pub name: &'static str,
+    pub addr: AtomicUsize,
+    pub _marker: marker::PhantomData<F>,
+}
+
+impl<F> DlSym<F> {
+    pub fn get(&self) -> Option<&F> {
+        assert_eq!(mem::size_of::<F>(), mem::size_of::<usize>());
+        unsafe {
+            if self.addr.load(Ordering::SeqCst) == 0 {
+                self.addr.store(fetch(self.name), Ordering::SeqCst);
+            }
+            if self.addr.load(Ordering::SeqCst) == 1 {
+                None
+            } else {
+                mem::transmute::<&AtomicUsize, Option<&F>>(&self.addr)
+            }
+        }
+    }
+}
+
+unsafe fn fetch(name: &str) -> usize {
+    assert_eq!(name.as_bytes()[name.len() - 1], 0);
+    match libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr() as *const _) as usize {
+        0 => 1,
+        n => n,
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/sys/unix/epoll.rs
@@ -0,0 +1,277 @@
+#![allow(deprecated)]
+use std::os::unix::io::AsRawFd;
+use std::os::unix::io::RawFd;
+use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
+use std::time::Duration;
+use std::{cmp, i32};
+
+use libc::c_int;
+use libc;
+use libc::{EPOLLERR, EPOLLHUP};
+use libc::{EPOLLET, EPOLLOUT, EPOLLIN, EPOLLPRI};
+
+#[cfg(not(target_os = "android"))]
+use libc::{EPOLLRDHUP, EPOLLONESHOT};
+
+// libc doesn't define these constants on android, but they are supported.
+#[cfg(target_os = "android")]
+const EPOLLRDHUP: libc::c_int = 0x00002000;
+#[cfg(target_os = "android")]
+const EPOLLONESHOT: libc::c_int = 0x40000000;
+
+use {io, Ready, PollOpt, Token};
+use event_imp::Event;
+use sys::unix::{cvt, UnixReady};
+use sys::unix::io::set_cloexec;
+
+/// Each Selector has a globally unique(ish) ID associated with it. This ID
+/// gets tracked by `TcpStream`, `TcpListener`, etc... when they are first
+/// registered with the `Selector`. If a type that is previously associated with
+/// a `Selector` attempts to register itself with a different `Selector`, the
+/// operation will return with an error. This matches windows behavior.
+static NEXT_ID: AtomicUsize = ATOMIC_USIZE_INIT;
+
+#[derive(Debug)]
+pub struct Selector {
+    id: usize,
+    epfd: RawFd,
+}
+
+impl Selector {
+    pub fn new() -> io::Result<Selector> {
+        let epfd = unsafe {
+            // Emulate `epoll_create` by using `epoll_create1` if it's available
+            // and otherwise falling back to `epoll_create` followed by a call to
+            // set the CLOEXEC flag.
+            dlsym!(fn epoll_create1(c_int) -> c_int);
+
+            match epoll_create1.get() {
+                Some(epoll_create1_fn) => {
+                    try!(cvt(epoll_create1_fn(libc::EPOLL_CLOEXEC)))
+                }
+                None => {
+                    let fd = try!(cvt(libc::epoll_create(1024)));
+                    drop(set_cloexec(fd));
+                    fd
+                }
+            }
+        };
+
+        // offset by 1 to avoid choosing 0 as the id of a selector
+        let id = NEXT_ID.fetch_add(1, Ordering::Relaxed) + 1;
+
+        Ok(Selector {
+            id: id,
+            epfd: epfd,
+        })
+    }
+
+    pub fn id(&self) -> usize {
+        self.id
+    }
+
+    /// Wait for events from the OS
+    pub fn select(&self, evts: &mut Events, awakener: Token, timeout: Option<Duration>) -> io::Result<bool> {
+        let timeout_ms = timeout
+            .map(|to| cmp::min(millis(to), i32::MAX as u64) as i32)
+            .unwrap_or(-1);
+
+        // Wait for epoll events for at most timeout_ms milliseconds
+        unsafe {
+            evts.events.set_len(0);
+            let cnt = try!(cvt(libc::epoll_wait(self.epfd,
+                                                evts.events.as_mut_ptr(),
+                                                evts.events.capacity() as i32,
+                                                timeout_ms)));
+            let cnt = cnt as usize;
+            evts.events.set_len(cnt);
+
+            for i in 0..cnt {
+                if evts.events[i].u64 as usize == awakener.into() {
+                    evts.events.remove(i);
+                    return Ok(true);
+                }
+            }
+        }
+
+        Ok(false)
+    }
+
+    /// Register event interests for the given IO handle with the OS
+    pub fn register(&self, fd: RawFd, token: Token, interests: Ready, opts: PollOpt) -> io::Result<()> {
+        let mut info = libc::epoll_event {
+            events: ioevent_to_epoll(interests, opts),
+            u64: usize::from(token) as u64
+        };
+
+        unsafe {
+            try!(cvt(libc::epoll_ctl(self.epfd, libc::EPOLL_CTL_ADD, fd, &mut info)));
+            Ok(())
+        }
+    }
+
+    /// Register event interests for the given IO handle with the OS
+    pub fn reregister(&self, fd: RawFd, token: Token, interests: Ready, opts: PollOpt) -> io::Result<()> {
+        let mut info = libc::epoll_event {
+            events: ioevent_to_epoll(interests, opts),
+            u64: usize::from(token) as u64
+        };
+
+        unsafe {
+            try!(cvt(libc::epoll_ctl(self.epfd, libc::EPOLL_CTL_MOD, fd, &mut info)));
+            Ok(())
+        }
+    }
+
+    /// Deregister event interests for the given IO handle with the OS
+    pub fn deregister(&self, fd: RawFd) -> io::Result<()> {
+        // The &info argument should be ignored by the system,
+        // but linux < 2.6.9 required it to be not null.
+        // For compatibility, we provide a dummy EpollEvent.
+        let mut info = libc::epoll_event {
+            events: 0,
+            u64: 0,
+        };
+
+        unsafe {
+            try!(cvt(libc::epoll_ctl(self.epfd, libc::EPOLL_CTL_DEL, fd, &mut info)));
+            Ok(())
+        }
+    }
+}
+
+#[cfg(feature = "with-deprecated")]
+#[allow(deprecated)]
+fn is_urgent(opts: PollOpt) -> bool {
+    opts.is_urgent()
+}
+
+#[cfg(not(feature = "with-deprecated"))]
+fn is_urgent(_: PollOpt) -> bool {
+    false
+}
+
+fn ioevent_to_epoll(interest: Ready, opts: PollOpt) -> u32 {
+    let mut kind = 0;
+
+    if interest.is_readable() {
+        if is_urgent(opts) {
+            kind |= EPOLLPRI;
+        } else {
+            kind |= EPOLLIN;
+        }
+    }
+
+    if interest.is_writable() {
+        kind |= EPOLLOUT;
+    }
+
+    if UnixReady::from(interest).is_hup() {
+        kind |= EPOLLRDHUP;
+    }
+
+    if opts.is_edge() {
+        kind |= EPOLLET;
+    }
+
+    if opts.is_oneshot() {
+        kind |= EPOLLONESHOT;
+    }
+
+    if opts.is_level() {
+        kind &= !EPOLLET;
+    }
+
+    kind as u32
+}
+
+impl AsRawFd for Selector {
+    fn as_raw_fd(&self) -> RawFd {
+        self.epfd
+    }
+}
+
+impl Drop for Selector {
+    fn drop(&mut self) {
+        unsafe {
+            let _ = libc::close(self.epfd);
+        }
+    }
+}
+
+pub struct Events {
+    events: Vec<libc::epoll_event>,
+}
+
+impl Events {
+    pub fn with_capacity(u: usize) -> Events {
+        Events {
+            events: Vec::with_capacity(u)
+        }
+    }
+
+    #[inline]
+    pub fn len(&self) -> usize {
+        self.events.len()
+    }
+
+    #[inline]
+    pub fn capacity(&self) -> usize {
+        self.events.capacity()
+    }
+
+    #[inline]
+    pub fn is_empty(&self) -> bool {
+        self.events.is_empty()
+    }
+
+    #[inline]
+    pub fn get(&self, idx: usize) -> Option<Event> {
+        self.events.get(idx).map(|event| {
+            let epoll = event.events as c_int;
+            let mut kind = Ready::empty();
+
+            if (epoll & EPOLLIN) != 0 || (epoll & EPOLLPRI) != 0 {
+                kind = kind | Ready::readable();
+            }
+
+            if (epoll & EPOLLOUT) != 0 {
+                kind = kind | Ready::writable();
+            }
+
+            // EPOLLHUP - Usually means a socket error happened
+            if (epoll & EPOLLERR) != 0 {
+                kind = kind | UnixReady::error();
+            }
+
+            if (epoll & EPOLLRDHUP) != 0 || (epoll & EPOLLHUP) != 0 {
+                kind = kind | UnixReady::hup();
+            }
+
+            let token = self.events[idx].u64;
+
+            Event::new(kind, Token(token as usize))
+        })
+    }
+
+    pub fn push_event(&mut self, event: Event) {
+        self.events.push(libc::epoll_event {
+            events: ioevent_to_epoll(event.readiness(), PollOpt::empty()),
+            u64: usize::from(event.token()) as u64
+        });
+    }
+}
+
+const NANOS_PER_MILLI: u32 = 1_000_000;
+const MILLIS_PER_SEC: u64 = 1_000;
+
+/// Convert a `Duration` to milliseconds, rounding up and saturating at
+/// `u64::MAX`.
+///
+/// The saturating is fine because `u64::MAX` milliseconds are still many
+/// million years.
+pub fn millis(duration: Duration) -> u64 {
+    // Round up.
+    let millis = (duration.subsec_nanos() + NANOS_PER_MILLI - 1) / NANOS_PER_MILLI;
+    duration.as_secs().saturating_mul(MILLIS_PER_SEC).saturating_add(millis as u64)
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/sys/unix/eventedfd.rs
@@ -0,0 +1,98 @@
+use {io, poll, Ready, Poll, PollOpt, Token};
+use event::Evented;
+use std::os::unix::io::RawFd;
+
+/*
+ *
+ * ===== EventedFd =====
+ *
+ */
+
+#[derive(Debug)]
+
+/// Adapter for [`RawFd`] providing an [`Evented`] implementation.
+///
+/// `EventedFd` enables registering any type with an FD with [`Poll`].
+///
+/// While only implementations for TCP and UDP are provided, Mio supports
+/// registering any FD that can be registered with the underlying OS selector.
+/// `EventedFd` provides the necessary bridge.
+///
+/// Note that `EventedFd` takes a `&RawFd`. This is because `EventedFd` **does
+/// not** take ownership of the FD. Specifically, it will not manage any
+/// lifecycle related operations, such as closing the FD on drop. It is expected
+/// that the `EventedFd` is constructed right before a call to
+/// [`Poll::register`]. See the examples for more detail.
+///
+/// # Examples
+///
+/// Basic usage
+///
+/// ```
+/// use mio::{Ready, Poll, PollOpt, Token};
+/// use mio::unix::EventedFd;
+///
+/// use std::os::unix::io::AsRawFd;
+/// use std::net::TcpListener;
+///
+/// // Bind a std listener
+/// let listener = TcpListener::bind("127.0.0.1:0").unwrap();
+///
+/// let poll = Poll::new().unwrap();
+///
+/// // Register the listener
+/// poll.register(&EventedFd(&listener.as_raw_fd()),
+///              Token(0), Ready::readable(), PollOpt::edge()).unwrap();
+/// ```
+///
+/// Implementing `Evented` for a custom type backed by a `RawFd`.
+///
+/// ```
+/// use mio::{Ready, Poll, PollOpt, Token};
+/// use mio::event::Evented;
+/// use mio::unix::EventedFd;
+///
+/// use std::os::unix::io::RawFd;
+/// use std::io;
+///
+/// pub struct MyIo {
+///     fd: RawFd,
+/// }
+///
+/// impl Evented for MyIo {
+///     fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt)
+///         -> io::Result<()>
+///     {
+///         EventedFd(&self.fd).register(poll, token, interest, opts)
+///     }
+///
+///     fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt)
+///         -> io::Result<()>
+///     {
+///         EventedFd(&self.fd).reregister(poll, token, interest, opts)
+///     }
+///
+///     fn deregister(&self, poll: &Poll) -> io::Result<()> {
+///         EventedFd(&self.fd).deregister(poll)
+///     }
+/// }
+/// ```
+///
+/// [`RawFd`]: #
+/// [`Evented`]: #
+/// [`Poll`]: #
+pub struct EventedFd<'a>(pub &'a RawFd);
+
+impl<'a> Evented for EventedFd<'a> {
+    fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        poll::selector(poll).register(*self.0, token, interest, opts)
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        poll::selector(poll).reregister(*self.0, token, interest, opts)
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        poll::selector(poll).deregister(*self.0)
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/sys/unix/io.rs
@@ -0,0 +1,107 @@
+use std::fs::File;
+use std::io::{Read, Write};
+use std::os::unix::io::{IntoRawFd, AsRawFd, FromRawFd, RawFd};
+
+use libc;
+
+use {io, Ready, Poll, PollOpt, Token};
+use event::Evented;
+use unix::EventedFd;
+use sys::unix::cvt;
+
+pub fn set_nonblock(fd: libc::c_int) -> io::Result<()> {
+    unsafe {
+        let flags = libc::fcntl(fd, libc::F_GETFL);
+        cvt(libc::fcntl(fd, libc::F_SETFL, flags | libc::O_NONBLOCK)).map(|_|())
+    }
+}
+
+pub fn set_cloexec(fd: libc::c_int) -> io::Result<()> {
+    unsafe {
+        let flags = libc::fcntl(fd, libc::F_GETFD);
+        cvt(libc::fcntl(fd, libc::F_SETFD, flags | libc::FD_CLOEXEC)).map(|_| ())
+    }
+}
+
+/*
+ *
+ * ===== Basic IO type =====
+ *
+ */
+
+/// Manages a FD
+#[derive(Debug)]
+pub struct Io {
+    fd: File,
+}
+
+impl Io {
+    /// Try to clone the FD
+    pub fn try_clone(&self) -> io::Result<Io> {
+        Ok(Io { fd: try!(self.fd.try_clone()) })
+    }
+}
+
+impl FromRawFd for Io {
+    unsafe fn from_raw_fd(fd: RawFd) -> Io {
+        Io { fd: File::from_raw_fd(fd) }
+    }
+}
+
+impl IntoRawFd for Io {
+    fn into_raw_fd(self) -> RawFd {
+        self.fd.into_raw_fd()
+    }
+}
+
+impl AsRawFd for Io {
+    fn as_raw_fd(&self) -> RawFd {
+        self.fd.as_raw_fd()
+    }
+}
+
+impl Evented for Io {
+    fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).register(poll, token, interest, opts)
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).reregister(poll, token, interest, opts)
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).deregister(poll)
+    }
+}
+
+impl Read for Io {
+    fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
+        (&self.fd).read(dst)
+    }
+}
+
+impl<'a> Read for &'a Io {
+    fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
+        (&self.fd).read(dst)
+    }
+}
+
+impl Write for Io {
+    fn write(&mut self, src: &[u8]) -> io::Result<usize> {
+        (&self.fd).write(src)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        (&self.fd).flush()
+    }
+}
+
+impl<'a> Write for &'a Io {
+    fn write(&mut self, src: &[u8]) -> io::Result<usize> {
+        (&self.fd).write(src)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        (&self.fd).flush()
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/sys/unix/kqueue.rs
@@ -0,0 +1,326 @@
+use std::{cmp, fmt, ptr};
+use std::os::raw::c_int;
+use std::os::unix::io::AsRawFd;
+use std::os::unix::io::RawFd;
+use std::collections::HashMap;
+use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
+use std::time::Duration;
+
+use libc::{self, time_t};
+
+use {io, Ready, PollOpt, Token};
+use event_imp::{self as event, Event};
+use sys::unix::{cvt, UnixReady};
+use sys::unix::io::set_cloexec;
+
+/// Each Selector has a globally unique(ish) ID associated with it. This ID
+/// gets tracked by `TcpStream`, `TcpListener`, etc... when they are first
+/// registered with the `Selector`. If a type that is previously associated with
+/// a `Selector` attempts to register itself with a different `Selector`, the
+/// operation will return with an error. This matches windows behavior.
+static NEXT_ID: AtomicUsize = ATOMIC_USIZE_INIT;
+
+macro_rules! kevent {
+    ($id: expr, $filter: expr, $flags: expr, $data: expr) => {
+        libc::kevent {
+            ident: $id as ::libc::uintptr_t,
+            filter: $filter,
+            flags: $flags,
+            fflags: 0,
+            data: 0,
+            udata: $data as *mut _,
+        }
+    }
+}
+
+pub struct Selector {
+    id: usize,
+    kq: RawFd,
+}
+
+impl Selector {
+    pub fn new() -> io::Result<Selector> {
+        // offset by 1 to avoid choosing 0 as the id of a selector
+        let id = NEXT_ID.fetch_add(1, Ordering::Relaxed) + 1;
+        let kq = unsafe { try!(cvt(libc::kqueue())) };
+        drop(set_cloexec(kq));
+
+        Ok(Selector {
+            id: id,
+            kq: kq,
+        })
+    }
+
+    pub fn id(&self) -> usize {
+        self.id
+    }
+
+    pub fn select(&self, evts: &mut Events, awakener: Token, timeout: Option<Duration>) -> io::Result<bool> {
+        let timeout = timeout.map(|to| {
+            libc::timespec {
+                tv_sec: cmp::min(to.as_secs(), time_t::max_value() as u64) as time_t,
+                tv_nsec: to.subsec_nanos() as libc::c_long,
+            }
+        });
+        let timeout = timeout.as_ref().map(|s| s as *const _).unwrap_or(ptr::null_mut());
+
+        unsafe {
+            let cnt = try!(cvt(libc::kevent(self.kq,
+                                            ptr::null(),
+                                            0,
+                                            evts.sys_events.0.as_mut_ptr(),
+            // FIXME: needs a saturating cast here.
+                                            evts.sys_events.0.capacity() as c_int,
+                                            timeout)));
+            evts.sys_events.0.set_len(cnt as usize);
+            Ok(evts.coalesce(awakener))
+        }
+    }
+
+    pub fn register(&self, fd: RawFd, token: Token, interests: Ready, opts: PollOpt) -> io::Result<()> {
+        trace!("registering; token={:?}; interests={:?}", token, interests);
+
+        let flags = if opts.contains(PollOpt::edge()) { libc::EV_CLEAR } else { 0 } |
+                    if opts.contains(PollOpt::oneshot()) { libc::EV_ONESHOT } else { 0 } |
+                    libc::EV_RECEIPT;
+
+        unsafe {
+            let r = if interests.contains(Ready::readable()) { libc::EV_ADD } else { libc::EV_DELETE };
+            let w = if interests.contains(Ready::writable()) { libc::EV_ADD } else { libc::EV_DELETE };
+            let mut changes = [
+                kevent!(fd, libc::EVFILT_READ, flags | r, usize::from(token)),
+                kevent!(fd, libc::EVFILT_WRITE, flags | w, usize::from(token)),
+            ];
+            try!(cvt(libc::kevent(self.kq, changes.as_ptr(), changes.len() as c_int,
+                                           changes.as_mut_ptr(), changes.len() as c_int,
+                                           ::std::ptr::null())));
+            for change in changes.iter() {
+                debug_assert_eq!(change.flags & libc::EV_ERROR, libc::EV_ERROR);
+
+                // Test to see if an error happened
+                if change.data == 0 {
+                    continue
+                }
+
+                // Older versions of OSX (10.11 and 10.10 have been witnessed)
+                // can return EPIPE when registering a pipe file descriptor
+                // where the other end has already disappeared. For example code
+                // that creates a pipe, closes a file descriptor, and then
+                // registers the other end will see an EPIPE returned from
+                // `register`.
+                //
+                // It also turns out that kevent will still report events on the
+                // file descriptor, telling us that it's readable/hup at least
+                // after we've done this registration. As a result we just
+                // ignore `EPIPE` here instead of propagating it.
+                //
+                // More info can be found at carllerche/mio#582
+                if change.data as i32 == libc::EPIPE &&
+                   change.filter == libc::EVFILT_WRITE {
+                    continue
+                }
+
+                // ignore ENOENT error for EV_DELETE
+                let orig_flags = if change.filter == libc::EVFILT_READ { r } else { w };
+                if change.data as i32 == libc::ENOENT && orig_flags & libc::EV_DELETE != 0 {
+                    continue
+                }
+
+                return Err(::std::io::Error::from_raw_os_error(change.data as i32));
+            }
+            Ok(())
+        }
+    }
+
+    pub fn reregister(&self, fd: RawFd, token: Token, interests: Ready, opts: PollOpt) -> io::Result<()> {
+        // Just need to call register here since EV_ADD is a mod if already
+        // registered
+        self.register(fd, token, interests, opts)
+    }
+
+    pub fn deregister(&self, fd: RawFd) -> io::Result<()> {
+        unsafe {
+            // EV_RECEIPT is a nice way to apply changes and get back per-event results while not
+            // draining the actual changes.
+            let filter = libc::EV_DELETE | libc::EV_RECEIPT;
+            let mut changes = [
+                kevent!(fd, libc::EVFILT_READ, filter, ptr::null_mut()),
+                kevent!(fd, libc::EVFILT_WRITE, filter, ptr::null_mut()),
+            ];
+            try!(cvt(libc::kevent(self.kq, changes.as_ptr(), changes.len() as c_int,
+                                           changes.as_mut_ptr(), changes.len() as c_int,
+                                           ::std::ptr::null())).map(|_| ()));
+            if changes[0].data as i32 == libc::ENOENT && changes[1].data as i32 == libc::ENOENT {
+                return Err(::std::io::Error::from_raw_os_error(changes[0].data as i32));
+            }
+            for change in changes.iter() {
+                debug_assert_eq!(libc::EV_ERROR & change.flags, libc::EV_ERROR);
+                if change.data != 0 && change.data as i32 != libc::ENOENT {
+                    return Err(::std::io::Error::from_raw_os_error(changes[0].data as i32));
+                }
+            }
+            Ok(())
+        }
+    }
+}
+
+impl fmt::Debug for Selector {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        fmt.debug_struct("Selector")
+            .field("id", &self.id)
+            .field("kq", &self.kq)
+            .finish()
+    }
+}
+
+impl AsRawFd for Selector {
+    fn as_raw_fd(&self) -> RawFd {
+        self.kq
+    }
+}
+
+impl Drop for Selector {
+    fn drop(&mut self) {
+        unsafe {
+            let _ = libc::close(self.kq);
+        }
+    }
+}
+
+pub struct Events {
+    sys_events: KeventList,
+    events: Vec<Event>,
+    event_map: HashMap<Token, usize>,
+}
+
+struct KeventList(Vec<libc::kevent>);
+
+unsafe impl Send for KeventList {}
+unsafe impl Sync for KeventList {}
+
+impl Events {
+    pub fn with_capacity(cap: usize) -> Events {
+        Events {
+            sys_events: KeventList(Vec::with_capacity(cap)),
+            events: Vec::with_capacity(cap),
+            event_map: HashMap::with_capacity(cap)
+        }
+    }
+
+    #[inline]
+    pub fn len(&self) -> usize {
+        self.events.len()
+    }
+
+    #[inline]
+    pub fn capacity(&self) -> usize {
+        self.events.capacity()
+    }
+
+    #[inline]
+    pub fn is_empty(&self) -> bool {
+        self.events.is_empty()
+    }
+
+    pub fn get(&self, idx: usize) -> Option<Event> {
+        self.events.get(idx).map(|e| *e)
+    }
+
+    fn coalesce(&mut self, awakener: Token) -> bool {
+        let mut ret = false;
+        self.events.clear();
+        self.event_map.clear();
+
+        for e in self.sys_events.0.iter() {
+            let token = Token(e.udata as usize);
+            let len = self.events.len();
+
+            if token == awakener {
+                // TODO: Should this return an error if event is an error. It
+                // is not critical as spurious wakeups are permitted.
+                ret = true;
+                continue;
+            }
+
+            let idx = *self.event_map.entry(token)
+                .or_insert(len);
+
+            if idx == len {
+                // New entry, insert the default
+                self.events.push(Event::new(Ready::empty(), token));
+
+            }
+
+            if e.flags & libc::EV_ERROR != 0 {
+                event::kind_mut(&mut self.events[idx]).insert(*UnixReady::error());
+            }
+
+            if e.filter == libc::EVFILT_READ {
+                event::kind_mut(&mut self.events[idx]).insert(Ready::readable());
+            } else if e.filter == libc::EVFILT_WRITE {
+                event::kind_mut(&mut self.events[idx]).insert(Ready::writable());
+            }
+#[cfg(any(target_os = "dragonfly",
+    target_os = "freebsd", target_os = "ios", target_os = "macos"))]
+            {
+                if e.filter == libc::EVFILT_AIO {
+                    event::kind_mut(&mut self.events[idx]).insert(UnixReady::aio());
+                }
+            }
+
+            if e.flags & libc::EV_EOF != 0 {
+                event::kind_mut(&mut self.events[idx]).insert(UnixReady::hup());
+
+                // When the read end of the socket is closed, EV_EOF is set on
+                // flags, and fflags contains the error if there is one.
+                if e.fflags != 0 {
+                    event::kind_mut(&mut self.events[idx]).insert(UnixReady::error());
+                }
+            }
+        }
+
+        ret
+    }
+
+    pub fn push_event(&mut self, event: Event) {
+        self.events.push(event);
+    }
+}
+
+impl fmt::Debug for Events {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        write!(fmt, "Events {{ len: {} }}", self.sys_events.0.len())
+    }
+}
+
+#[test]
+fn does_not_register_rw() {
+    #![allow(deprecated)]
+
+    use ::deprecated::{EventLoopBuilder, Handler};
+    use ::unix::EventedFd;
+    struct Nop;
+    impl Handler for Nop {
+        type Timeout = ();
+        type Message = ();
+    }
+
+    // registering kqueue fd will fail if write is requested (On anything but some versions of OS
+    // X)
+    let kq = unsafe { libc::kqueue() };
+    let kqf = EventedFd(&kq);
+    let mut evtloop = EventLoopBuilder::new().build::<Nop>().expect("evt loop builds");
+    evtloop.register(&kqf, Token(1234), Ready::readable(),
+                     PollOpt::edge() | PollOpt::oneshot()).unwrap();
+}
+
+#[cfg(any(target_os = "dragonfly",
+    target_os = "freebsd", target_os = "ios", target_os = "macos"))]
+#[test]
+fn test_coalesce_aio() {
+    let mut events = Events::with_capacity(1);
+    events.sys_events.0.push(kevent!(0x1234, libc::EVFILT_AIO, 0, 42));
+    events.coalesce(Token(0));
+    assert!(events.events[0].readiness() == UnixReady::aio().into());
+    assert!(events.events[0].token() == Token(42));
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/sys/unix/mod.rs
@@ -0,0 +1,90 @@
+use libc::{self, c_int};
+
+#[macro_use]
+pub mod dlsym;
+
+#[cfg(any(target_os = "linux", target_os = "android", target_os = "fuchsia"))]
+mod epoll;
+
+#[cfg(any(target_os = "linux", target_os = "android", target_os = "fuchsia"))]
+pub use self::epoll::{Events, Selector};
+
+#[cfg(any(target_os = "bitrig", target_os = "dragonfly",
+          target_os = "freebsd", target_os = "ios", target_os = "macos",
+          target_os = "netbsd", target_os = "openbsd"))]
+mod kqueue;
+
+#[cfg(any(target_os = "bitrig", target_os = "dragonfly",
+          target_os = "freebsd", target_os = "ios", target_os = "macos",
+          target_os = "netbsd", target_os = "openbsd"))]
+pub use self::kqueue::{Events, Selector};
+
+mod awakener;
+mod eventedfd;
+mod io;
+mod ready;
+mod tcp;
+mod udp;
+
+#[cfg(feature = "with-deprecated")]
+mod uds;
+
+pub use self::awakener::Awakener;
+pub use self::eventedfd::EventedFd;
+pub use self::io::{Io, set_nonblock};
+pub use self::ready::UnixReady;
+pub use self::tcp::{TcpStream, TcpListener};
+pub use self::udp::UdpSocket;
+
+#[cfg(feature = "with-deprecated")]
+pub use self::uds::UnixSocket;
+
+pub use iovec::IoVec;
+
+use std::os::unix::io::FromRawFd;
+
+pub fn pipe() -> ::io::Result<(Io, Io)> {
+    // Use pipe2 for atomically setting O_CLOEXEC if we can, but otherwise
+    // just fall back to using `pipe`.
+    dlsym!(fn pipe2(*mut c_int, c_int) -> c_int);
+
+    let mut pipes = [0; 2];
+    let flags = libc::O_NONBLOCK | libc::O_CLOEXEC;
+    unsafe {
+        match pipe2.get() {
+            Some(pipe2_fn) => {
+                try!(cvt(pipe2_fn(pipes.as_mut_ptr(), flags)));
+            }
+            None => {
+                try!(cvt(libc::pipe(pipes.as_mut_ptr())));
+                libc::fcntl(pipes[0], libc::F_SETFL, flags);
+                libc::fcntl(pipes[1], libc::F_SETFL, flags);
+            }
+        }
+    }
+
+    unsafe {
+        Ok((Io::from_raw_fd(pipes[0]), Io::from_raw_fd(pipes[1])))
+    }
+}
+
+trait IsMinusOne {
+    fn is_minus_one(&self) -> bool;
+}
+
+impl IsMinusOne for i32 {
+    fn is_minus_one(&self) -> bool { *self == -1 }
+}
+impl IsMinusOne for isize {
+    fn is_minus_one(&self) -> bool { *self == -1 }
+}
+
+fn cvt<T: IsMinusOne>(t: T) -> ::io::Result<T> {
+    use std::io;
+
+    if t.is_minus_one() {
+        Err(io::Error::last_os_error())
+    } else {
+        Ok(t)
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/sys/unix/ready.rs
@@ -0,0 +1,308 @@
+use event_imp::{Ready, ready_from_usize};
+
+use std::ops;
+
+/// Unix specific extensions to `Ready`
+///
+/// Provides additional readiness event kinds that are available on unix
+/// platforms. Unix platforms are able to provide readiness events for
+/// additional socket events, such as HUP and error.
+///
+/// HUP events occur when the remote end of a socket hangs up. In the TCP case,
+/// this occurs when the remote end of a TCP socket shuts down writes.
+///
+/// Error events occur when the socket enters an error state. In this case, the
+/// socket will also receive a readable or writable event. Reading or writing to
+/// the socket will result in an error.
+///
+/// Conversion traits are implemented between `Ready` and `UnixReady`. See the
+/// examples.
+///
+/// For high level documentation on polling and readiness, see [`Poll`].
+///
+/// # Examples
+///
+/// Most of the time, all that is needed is using bit operations
+///
+/// ```
+/// use mio::Ready;
+/// use mio::unix::UnixReady;
+///
+/// let ready = Ready::readable() | UnixReady::hup();
+///
+/// assert!(ready.is_readable());
+/// assert!(UnixReady::from(ready).is_hup());
+/// ```
+///
+/// Basic conversion between ready types.
+///
+/// ```
+/// use mio::Ready;
+/// use mio::unix::UnixReady;
+///
+/// // Start with a portable ready
+/// let ready = Ready::readable();
+///
+/// // Convert to a unix ready, adding HUP
+/// let mut unix_ready = UnixReady::from(ready) | UnixReady::hup();
+///
+/// unix_ready.insert(UnixReady::error());
+///
+/// // `unix_ready` maintains readable interest
+/// assert!(unix_ready.is_readable());
+/// assert!(unix_ready.is_hup());
+/// assert!(unix_ready.is_error());
+///
+/// // Convert back to `Ready`
+/// let ready = Ready::from(unix_ready);
+///
+/// // Readable is maintained
+/// assert!(ready.is_readable());
+/// ```
+///
+/// Registering readable and error interest on a socket
+///
+/// ```
+/// use mio::{Ready, Poll, PollOpt, Token};
+/// use mio::tcp::TcpStream;
+/// use mio::unix::UnixReady;
+///
+/// let addr = "216.58.193.68:80".parse().unwrap();
+/// let socket = TcpStream::connect(&addr).unwrap();
+///
+/// let poll = Poll::new().unwrap();
+///
+/// poll.register(&socket,
+///               Token(0),
+///               Ready::readable() | UnixReady::error(),
+///               PollOpt::edge()).unwrap();
+///
+/// ```
+///
+/// [`Poll`]: struct.Poll.html
+/// [readiness]: struct.Poll.html#readiness-operations
+#[derive(Debug, Copy, PartialEq, Eq, Clone, PartialOrd, Ord)]
+pub struct UnixReady(Ready);
+
+const ERROR: usize = 0b00100;
+const HUP: usize   = 0b01000;
+const AIO: usize   = 0b10000;
+
+impl UnixReady {
+    /// Returns a `Ready` representing AIO completion readiness
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::unix::UnixReady;
+    ///
+    /// let ready = UnixReady::aio();
+    ///
+    /// assert!(ready.is_aio());
+    /// ```
+    ///
+    /// [`Poll`]: struct.Poll.html
+    #[inline]
+    pub fn aio() -> UnixReady {
+        UnixReady(ready_from_usize(AIO))
+    }
+
+    /// Returns a `Ready` representing error readiness.
+    ///
+    /// **Note that only readable and writable readiness is guaranteed to be
+    /// supported on all platforms**. This means that `error` readiness
+    /// should be treated as a hint. For more details, see [readiness] in the
+    /// poll documentation.
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::Ready;
+    ///
+    /// let ready = Ready::error();
+    ///
+    /// assert!(ready.is_error());
+    /// ```
+    ///
+    /// [`Poll`]: struct.Poll.html
+    /// [readiness]: struct.Poll.html#readiness-operations
+    #[inline]
+    pub fn error() -> UnixReady {
+        UnixReady(ready_from_usize(ERROR))
+    }
+
+    /// Returns a `Ready` representing HUP readiness.
+    ///
+    /// A HUP (or hang-up) signifies that a stream socket **peer** closed the
+    /// connection, or shut down the writing half of the connection.
+    ///
+    /// **Note that only readable and writable readiness is guaranteed to be
+    /// supported on all platforms**. This means that `hup` readiness
+    /// should be treated as a hint. For more details, see [readiness] in the
+    /// poll documentation.
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::Ready;
+    ///
+    /// let ready = Ready::hup();
+    ///
+    /// assert!(ready.is_hup());
+    /// ```
+    ///
+    /// [`Poll`]: struct.Poll.html
+    /// [readiness]: struct.Poll.html#readiness-operations
+    #[inline]
+    pub fn hup() -> UnixReady {
+        UnixReady(ready_from_usize(HUP))
+    }
+
+    /// Returns true if `Ready` contains AIO readiness
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::unix::UnixReady;
+    ///
+    /// let ready = UnixReady::aio();
+    ///
+    /// assert!(ready.is_aio());
+    /// ```
+    #[inline]
+    pub fn is_aio(&self) -> bool {
+        self.contains(ready_from_usize(AIO))
+    }
+
+    /// Returns true if the value includes error readiness
+    ///
+    /// **Note that only readable and writable readiness is guaranteed to be
+    /// supported on all platforms**. This means that `error` readiness should
+    /// be treated as a hint. For more details, see [readiness] in the poll
+    /// documentation.
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::Ready;
+    ///
+    /// let ready = Ready::error();
+    ///
+    /// assert!(ready.is_error());
+    /// ```
+    ///
+    /// [`Poll`]: struct.Poll.html
+    #[inline]
+    pub fn is_error(&self) -> bool {
+        self.contains(ready_from_usize(ERROR))
+    }
+
+    /// Returns true if the value includes HUP readiness
+    ///
+    /// A HUP (or hang-up) signifies that a stream socket **peer** closed the
+    /// connection, or shut down the writing half of the connection.
+    ///
+    /// **Note that only readable and writable readiness is guaranteed to be
+    /// supported on all platforms**. This means that `hup` readiness
+    /// should be treated as a hint. For more details, see [readiness] in the
+    /// poll documentation.
+    ///
+    /// See [`Poll`] for more documentation on polling.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use mio::Ready;
+    ///
+    /// let ready = Ready::hup();
+    ///
+    /// assert!(ready.is_hup());
+    /// ```
+    ///
+    /// [`Poll`]: struct.Poll.html
+    #[inline]
+    pub fn is_hup(&self) -> bool {
+        self.contains(ready_from_usize(HUP))
+    }
+}
+
+impl From<Ready> for UnixReady {
+    fn from(src: Ready) -> UnixReady {
+        UnixReady(src)
+    }
+}
+
+impl From<UnixReady> for Ready {
+    fn from(src: UnixReady) -> Ready {
+        src.0
+    }
+}
+
+impl ops::Deref for UnixReady {
+    type Target = Ready;
+
+    fn deref(&self) -> &Ready {
+        &self.0
+    }
+}
+
+impl ops::DerefMut for UnixReady {
+    fn deref_mut(&mut self) -> &mut Ready {
+        &mut self.0
+    }
+}
+
+impl ops::BitOr for UnixReady {
+    type Output = UnixReady;
+
+    #[inline]
+    fn bitor(self, other: UnixReady) -> UnixReady {
+        (self.0 | other.0).into()
+    }
+}
+
+impl ops::BitXor for UnixReady {
+    type Output = UnixReady;
+
+    #[inline]
+    fn bitxor(self, other: UnixReady) -> UnixReady {
+        (self.0 ^ other.0).into()
+    }
+}
+
+impl ops::BitAnd for UnixReady {
+    type Output = UnixReady;
+
+    #[inline]
+    fn bitand(self, other: UnixReady) -> UnixReady {
+        (self.0 & other.0).into()
+    }
+}
+
+impl ops::Sub for UnixReady {
+    type Output = UnixReady;
+
+    #[inline]
+    fn sub(self, other: UnixReady) -> UnixReady {
+        (self.0 & !other.0).into()
+    }
+}
+
+impl ops::Not for UnixReady {
+    type Output = UnixReady;
+
+    #[inline]
+    fn not(self) -> UnixReady {
+        (!self.0).into()
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/sys/unix/tcp.rs
@@ -0,0 +1,299 @@
+use std::cmp;
+use std::io::{Read, Write};
+use std::net::{self, SocketAddr};
+use std::os::unix::io::{RawFd, FromRawFd, IntoRawFd, AsRawFd};
+use std::time::Duration;
+
+use libc;
+use net2::TcpStreamExt;
+use iovec::IoVec;
+use iovec::unix as iovec;
+
+use {io, Ready, Poll, PollOpt, Token};
+use event::Evented;
+
+use sys::unix::eventedfd::EventedFd;
+use sys::unix::io::set_nonblock;
+
+#[derive(Debug)]
+pub struct TcpStream {
+    inner: net::TcpStream,
+}
+
+#[derive(Debug)]
+pub struct TcpListener {
+    inner: net::TcpListener,
+}
+
+impl TcpStream {
+    pub fn connect(stream: net::TcpStream, addr: &SocketAddr) -> io::Result<TcpStream> {
+        try!(set_nonblock(stream.as_raw_fd()));
+
+        match stream.connect(addr) {
+            Ok(..) => {}
+            Err(ref e) if e.raw_os_error() == Some(libc::EINPROGRESS) => {}
+            Err(e) => return Err(e),
+        }
+
+        Ok(TcpStream {
+            inner: stream,
+        })
+    }
+
+    pub fn from_stream(stream: net::TcpStream) -> TcpStream {
+        TcpStream {
+            inner: stream,
+        }
+    }
+
+    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+        self.inner.peer_addr()
+    }
+
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
+        self.inner.local_addr()
+    }
+
+    pub fn try_clone(&self) -> io::Result<TcpStream> {
+        self.inner.try_clone().map(|s| {
+            TcpStream {
+                inner: s,
+            }
+        })
+    }
+
+    pub fn shutdown(&self, how: net::Shutdown) -> io::Result<()> {
+        self.inner.shutdown(how)
+    }
+
+    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
+        self.inner.set_nodelay(nodelay)
+    }
+
+    pub fn nodelay(&self) -> io::Result<bool> {
+        self.inner.nodelay()
+    }
+
+    pub fn set_recv_buffer_size(&self, size: usize) -> io::Result<()> {
+        self.inner.set_recv_buffer_size(size)
+    }
+
+    pub fn recv_buffer_size(&self) -> io::Result<usize> {
+        self.inner.recv_buffer_size()
+    }
+
+    pub fn set_send_buffer_size(&self, size: usize) -> io::Result<()> {
+        self.inner.set_send_buffer_size(size)
+    }
+
+    pub fn send_buffer_size(&self) -> io::Result<usize> {
+        self.inner.send_buffer_size()
+    }
+
+    pub fn set_keepalive(&self, keepalive: Option<Duration>) -> io::Result<()> {
+        self.inner.set_keepalive(keepalive)
+    }
+
+    pub fn keepalive(&self) -> io::Result<Option<Duration>> {
+        self.inner.keepalive()
+    }
+
+    pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
+        self.inner.set_ttl(ttl)
+    }
+
+    pub fn ttl(&self) -> io::Result<u32> {
+        self.inner.ttl()
+    }
+
+    pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
+        self.inner.set_only_v6(only_v6)
+    }
+
+    pub fn only_v6(&self) -> io::Result<bool> {
+        self.inner.only_v6()
+    }
+
+    pub fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
+        self.inner.set_linger(dur)
+    }
+
+    pub fn linger(&self) -> io::Result<Option<Duration>> {
+        self.inner.linger()
+    }
+
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        self.inner.take_error()
+    }
+
+    pub fn readv(&self, bufs: &mut [&mut IoVec]) -> io::Result<usize> {
+        unsafe {
+            let slice = iovec::as_os_slice_mut(bufs);
+            let len = cmp::min(<libc::c_int>::max_value() as usize, slice.len());
+            let rc = libc::readv(self.inner.as_raw_fd(),
+                                 slice.as_ptr(),
+                                 len as libc::c_int);
+            if rc < 0 {
+                Err(io::Error::last_os_error())
+            } else {
+                Ok(rc as usize)
+            }
+        }
+    }
+
+    pub fn writev(&self, bufs: &[&IoVec]) -> io::Result<usize> {
+        unsafe {
+            let slice = iovec::as_os_slice(bufs);
+            let len = cmp::min(<libc::c_int>::max_value() as usize, slice.len());
+            let rc = libc::writev(self.inner.as_raw_fd(),
+                                  slice.as_ptr(),
+                                  len as libc::c_int);
+            if rc < 0 {
+                Err(io::Error::last_os_error())
+            } else {
+                Ok(rc as usize)
+            }
+        }
+    }
+}
+
+impl<'a> Read for &'a TcpStream {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        (&self.inner).read(buf)
+    }
+}
+
+impl<'a> Write for &'a TcpStream {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        (&self.inner).write(buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        (&self.inner).flush()
+    }
+}
+
+impl Evented for TcpStream {
+    fn register(&self, poll: &Poll, token: Token,
+                interest: Ready, opts: PollOpt) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).register(poll, token, interest, opts)
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token,
+                  interest: Ready, opts: PollOpt) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).reregister(poll, token, interest, opts)
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).deregister(poll)
+    }
+}
+
+impl FromRawFd for TcpStream {
+    unsafe fn from_raw_fd(fd: RawFd) -> TcpStream {
+        TcpStream {
+            inner: net::TcpStream::from_raw_fd(fd),
+        }
+    }
+}
+
+impl IntoRawFd for TcpStream {
+    fn into_raw_fd(self) -> RawFd {
+        self.inner.into_raw_fd()
+    }
+}
+
+impl AsRawFd for TcpStream {
+    fn as_raw_fd(&self) -> RawFd {
+        self.inner.as_raw_fd()
+    }
+}
+
+impl TcpListener {
+    pub fn new(inner: net::TcpListener, _addr: &SocketAddr) -> io::Result<TcpListener> {
+        try!(set_nonblock(inner.as_raw_fd()));
+        Ok(TcpListener {
+            inner: inner,
+        })
+    }
+
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
+        self.inner.local_addr()
+    }
+
+    pub fn try_clone(&self) -> io::Result<TcpListener> {
+        self.inner.try_clone().map(|s| {
+            TcpListener {
+                inner: s,
+            }
+        })
+    }
+
+    pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
+        self.inner.accept().and_then(|(s, a)| {
+            try!(set_nonblock(s.as_raw_fd()));
+            Ok((TcpStream {
+                inner: s,
+            }, a))
+        })
+    }
+
+    #[allow(deprecated)]
+    pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
+        self.inner.set_only_v6(only_v6)
+    }
+
+    #[allow(deprecated)]
+    pub fn only_v6(&self) -> io::Result<bool> {
+        self.inner.only_v6()
+    }
+
+    pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
+        self.inner.set_ttl(ttl)
+    }
+
+    pub fn ttl(&self) -> io::Result<u32> {
+        self.inner.ttl()
+    }
+
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        self.inner.take_error()
+    }
+}
+
+impl Evented for TcpListener {
+    fn register(&self, poll: &Poll, token: Token,
+                interest: Ready, opts: PollOpt) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).register(poll, token, interest, opts)
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token,
+                  interest: Ready, opts: PollOpt) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).reregister(poll, token, interest, opts)
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).deregister(poll)
+    }
+}
+
+impl FromRawFd for TcpListener {
+    unsafe fn from_raw_fd(fd: RawFd) -> TcpListener {
+        TcpListener {
+            inner: net::TcpListener::from_raw_fd(fd),
+        }
+    }
+}
+
+impl IntoRawFd for TcpListener {
+    fn into_raw_fd(self) -> RawFd {
+        self.inner.into_raw_fd()
+    }
+}
+
+impl AsRawFd for TcpListener {
+    fn as_raw_fd(&self) -> RawFd {
+        self.inner.as_raw_fd()
+    }
+}
+
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/sys/unix/udp.rs
@@ -0,0 +1,157 @@
+use {io, Ready, Poll, PollOpt, Token};
+use event::Evented;
+use unix::EventedFd;
+use std::net::{self, Ipv4Addr, Ipv6Addr, SocketAddr};
+use std::os::unix::io::{RawFd, IntoRawFd, AsRawFd, FromRawFd};
+
+#[allow(unused_imports)] // only here for Rust 1.8
+use net2::UdpSocketExt;
+
+#[derive(Debug)]
+pub struct UdpSocket {
+    io: net::UdpSocket,
+}
+
+impl UdpSocket {
+    pub fn new(socket: net::UdpSocket) -> io::Result<UdpSocket> {
+        try!(socket.set_nonblocking(true));
+        Ok(UdpSocket {
+            io: socket,
+        })
+    }
+
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
+        self.io.local_addr()
+    }
+
+    pub fn try_clone(&self) -> io::Result<UdpSocket> {
+        self.io.try_clone().map(|io| {
+            UdpSocket {
+                io: io,
+            }
+        })
+    }
+
+    pub fn send_to(&self, buf: &[u8], target: &SocketAddr) -> io::Result<usize> {
+        self.io.send_to(buf, target)
+    }
+
+    pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
+        self.io.recv_from(buf)
+    }
+
+    pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
+        self.io.send(buf)
+    }
+
+    pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
+        self.io.recv(buf)
+    }
+
+    pub fn connect(&self, addr: SocketAddr)
+                     -> io::Result<()> {
+        self.io.connect(addr)
+    }
+
+    pub fn broadcast(&self) -> io::Result<bool> {
+        self.io.broadcast()
+    }
+
+    pub fn set_broadcast(&self, on: bool) -> io::Result<()> {
+        self.io.set_broadcast(on)
+    }
+
+    pub fn multicast_loop_v4(&self) -> io::Result<bool> {
+        self.io.multicast_loop_v4()
+    }
+
+    pub fn set_multicast_loop_v4(&self, on: bool) -> io::Result<()> {
+        self.io.set_multicast_loop_v4(on)
+    }
+
+    pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
+        self.io.multicast_ttl_v4()
+    }
+
+    pub fn set_multicast_ttl_v4(&self, ttl: u32) -> io::Result<()> {
+        self.io.set_multicast_ttl_v4(ttl)
+    }
+
+    pub fn multicast_loop_v6(&self) -> io::Result<bool> {
+        self.io.multicast_loop_v6()
+    }
+
+    pub fn set_multicast_loop_v6(&self, on: bool) -> io::Result<()> {
+        self.io.set_multicast_loop_v6(on)
+    }
+
+    pub fn ttl(&self) -> io::Result<u32> {
+        self.io.ttl()
+    }
+
+    pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
+        self.io.set_ttl(ttl)
+    }
+
+    pub fn join_multicast_v4(&self,
+                             multiaddr: &Ipv4Addr,
+                             interface: &Ipv4Addr) -> io::Result<()> {
+        self.io.join_multicast_v4(multiaddr, interface)
+    }
+
+    pub fn join_multicast_v6(&self,
+                             multiaddr: &Ipv6Addr,
+                             interface: u32) -> io::Result<()> {
+        self.io.join_multicast_v6(multiaddr, interface)
+    }
+
+    pub fn leave_multicast_v4(&self,
+                              multiaddr: &Ipv4Addr,
+                              interface: &Ipv4Addr) -> io::Result<()> {
+        self.io.leave_multicast_v4(multiaddr, interface)
+    }
+
+    pub fn leave_multicast_v6(&self,
+                              multiaddr: &Ipv6Addr,
+                              interface: u32) -> io::Result<()> {
+        self.io.leave_multicast_v6(multiaddr, interface)
+    }
+
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        self.io.take_error()
+    }
+}
+
+impl Evented for UdpSocket {
+    fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).register(poll, token, interest, opts)
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).reregister(poll, token, interest, opts)
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        EventedFd(&self.as_raw_fd()).deregister(poll)
+    }
+}
+
+impl FromRawFd for UdpSocket {
+    unsafe fn from_raw_fd(fd: RawFd) -> UdpSocket {
+        UdpSocket {
+            io: net::UdpSocket::from_raw_fd(fd),
+        }
+    }
+}
+
+impl IntoRawFd for UdpSocket {
+    fn into_raw_fd(self) -> RawFd {
+        self.io.into_raw_fd()
+    }
+}
+
+impl AsRawFd for UdpSocket {
+    fn as_raw_fd(&self) -> RawFd {
+        self.io.as_raw_fd()
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/sys/unix/uds.rs
@@ -0,0 +1,273 @@
+use std::io::{Read, Write};
+use std::mem;
+use std::net::Shutdown;
+use std::os::unix::prelude::*;
+use std::path::Path;
+
+use libc;
+
+use {io, Evented, Ready, Poll, PollOpt, Token};
+use sys::unix::{cvt, Io};
+use sys::unix::io::{set_nonblock, set_cloexec};
+
+trait MyInto<T> {
+    fn my_into(self) -> T;
+}
+
+impl MyInto<u32> for usize {
+    fn my_into(self) -> u32 { self as u32 }
+}
+
+impl MyInto<usize> for usize {
+    fn my_into(self) -> usize { self }
+}
+
+unsafe fn sockaddr_un(path: &Path)
+                      -> io::Result<(libc::sockaddr_un, libc::socklen_t)> {
+    let mut addr: libc::sockaddr_un = mem::zeroed();
+    addr.sun_family = libc::AF_UNIX as libc::sa_family_t;
+
+    let bytes = path.as_os_str().as_bytes();
+
+    if bytes.len() >= addr.sun_path.len() {
+        return Err(io::Error::new(io::ErrorKind::InvalidInput,
+                                  "path must be shorter than SUN_LEN"))
+    }
+    for (dst, src) in addr.sun_path.iter_mut().zip(bytes.iter()) {
+        *dst = *src as libc::c_char;
+    }
+    // null byte for pathname addresses is already there because we zeroed the
+    // struct
+
+    let mut len = sun_path_offset() + bytes.len();
+    match bytes.get(0) {
+        Some(&0) | None => {}
+        Some(_) => len += 1,
+    }
+    Ok((addr, len as libc::socklen_t))
+}
+
+fn sun_path_offset() -> usize {
+    unsafe {
+        // Work with an actual instance of the type since using a null pointer is UB
+        let addr: libc::sockaddr_un = mem::uninitialized();
+        let base = &addr as *const _ as usize;
+        let path = &addr.sun_path as *const _ as usize;
+        path - base
+    }
+}
+
+#[derive(Debug)]
+pub struct UnixSocket {
+    io: Io,
+}
+
+impl UnixSocket {
+    /// Returns a new, unbound, non-blocking Unix domain socket
+    pub fn stream() -> io::Result<UnixSocket> {
+        #[cfg(target_os = "linux")]
+        use libc::{SOCK_CLOEXEC, SOCK_NONBLOCK};
+        #[cfg(not(target_os = "linux"))]
+        const SOCK_CLOEXEC: libc::c_int = 0;
+        #[cfg(not(target_os = "linux"))]
+        const SOCK_NONBLOCK: libc::c_int = 0;
+
+        unsafe {
+            if cfg!(target_os = "linux") {
+                let flags = libc::SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK;
+                match cvt(libc::socket(libc::AF_UNIX, flags, 0)) {
+                    Ok(fd) => return Ok(UnixSocket::from_raw_fd(fd)),
+                    Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {}
+                    Err(e) => return Err(e),
+                }
+            }
+
+            let fd = try!(cvt(libc::socket(libc::AF_UNIX, libc::SOCK_STREAM, 0)));
+            let fd = UnixSocket::from_raw_fd(fd);
+            try!(set_cloexec(fd.as_raw_fd()));
+            try!(set_nonblock(fd.as_raw_fd()));
+            Ok(fd)
+        }
+    }
+
+    /// Connect the socket to the specified address
+    pub fn connect<P: AsRef<Path> + ?Sized>(&self, addr: &P) -> io::Result<()> {
+        unsafe {
+            let (addr, len) = try!(sockaddr_un(addr.as_ref()));
+            try!(cvt(libc::connect(self.as_raw_fd(),
+                                   &addr as *const _ as *const _,
+                                   len)));
+            Ok(())
+        }
+    }
+
+    /// Listen for incoming requests
+    pub fn listen(&self, backlog: usize) -> io::Result<()> {
+        unsafe {
+            try!(cvt(libc::listen(self.as_raw_fd(), backlog as i32)));
+            Ok(())
+        }
+    }
+
+    pub fn accept(&self) -> io::Result<UnixSocket> {
+        unsafe {
+            let fd = try!(cvt(libc::accept(self.as_raw_fd(),
+                                           0 as *mut _,
+                                           0 as *mut _)));
+            let fd = Io::from_raw_fd(fd);
+            try!(set_cloexec(fd.as_raw_fd()));
+            try!(set_nonblock(fd.as_raw_fd()));
+            Ok(UnixSocket { io: fd })
+        }
+    }
+
+    /// Bind the socket to the specified address
+    #[cfg(not(all(target_arch = "aarch64",target_os = "android")))]
+    pub fn bind<P: AsRef<Path> + ?Sized>(&self, addr: &P) -> io::Result<()> {
+        unsafe {
+            let (addr, len) = try!(sockaddr_un(addr.as_ref()));
+            try!(cvt(libc::bind(self.as_raw_fd(),
+                                &addr as *const _ as *const _,
+                                len)));
+            Ok(())
+        }
+    }
+
+    #[cfg(all(target_arch = "aarch64",target_os = "android"))]
+    pub fn bind<P: AsRef<Path> + ?Sized>(&self, addr: &P) -> io::Result<()> {
+        unsafe {
+            let (addr, len) = try!(sockaddr_un(addr.as_ref()));
+            let len_i32 = len as i32;
+            try!(cvt(libc::bind(self.as_raw_fd(),
+                                &addr as *const _ as *const _,
+                                len_i32)));
+            Ok(())
+        }
+    }
+
+    pub fn try_clone(&self) -> io::Result<UnixSocket> {
+        Ok(UnixSocket { io: try!(self.io.try_clone()) })
+    }
+
+    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
+        let how = match how {
+            Shutdown::Read => libc::SHUT_RD,
+            Shutdown::Write => libc::SHUT_WR,
+            Shutdown::Both => libc::SHUT_RDWR,
+        };
+        unsafe {
+            try!(cvt(libc::shutdown(self.as_raw_fd(), how)));
+            Ok(())
+        }
+    }
+
+    pub fn read_recv_fd(&mut self, buf: &mut [u8]) -> io::Result<(usize, Option<RawFd>)> {
+        unsafe {
+            let mut iov = libc::iovec {
+                iov_base: buf.as_mut_ptr() as *mut _,
+                iov_len: buf.len(),
+            };
+            struct Cmsg {
+                hdr: libc::cmsghdr,
+                data: [libc::c_int; 1],
+            }
+            let mut cmsg: Cmsg = mem::zeroed();
+            let mut msg: libc::msghdr = mem::zeroed();
+            msg.msg_iov = &mut iov;
+            msg.msg_iovlen = 1;
+            msg.msg_control = &mut cmsg as *mut _ as *mut _;
+            msg.msg_controllen = mem::size_of_val(&cmsg).my_into();
+            let bytes = try!(cvt(libc::recvmsg(self.as_raw_fd(), &mut msg, 0)));
+
+            const SCM_RIGHTS: libc::c_int = 1;
+
+            let fd = if cmsg.hdr.cmsg_level == libc::SOL_SOCKET &&
+                        cmsg.hdr.cmsg_type == SCM_RIGHTS {
+                Some(cmsg.data[0])
+            } else {
+                None
+            };
+            Ok((bytes as usize, fd))
+        }
+    }
+
+    pub fn write_send_fd(&mut self, buf: &[u8], fd: RawFd) -> io::Result<usize> {
+        unsafe {
+            let mut iov = libc::iovec {
+                iov_base: buf.as_ptr() as *mut _,
+                iov_len: buf.len(),
+            };
+            struct Cmsg {
+                hdr: libc::cmsghdr,
+                data: [libc::c_int; 1],
+            }
+            let mut cmsg: Cmsg = mem::zeroed();
+            cmsg.hdr.cmsg_len = mem::size_of_val(&cmsg).my_into();
+            cmsg.hdr.cmsg_level = libc::SOL_SOCKET;
+            cmsg.hdr.cmsg_type = 1; // SCM_RIGHTS
+            cmsg.data[0] = fd;
+            let mut msg: libc::msghdr = mem::zeroed();
+            msg.msg_iov = &mut iov;
+            msg.msg_iovlen = 1;
+            msg.msg_control = &mut cmsg as *mut _ as *mut _;
+            msg.msg_controllen = mem::size_of_val(&cmsg).my_into();
+            let bytes = try!(cvt(libc::sendmsg(self.as_raw_fd(), &msg, 0)));
+            Ok(bytes as usize)
+        }
+    }
+}
+
+impl Read for UnixSocket {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        self.io.read(buf)
+    }
+}
+
+impl Write for UnixSocket {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.io.write(buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        self.io.flush()
+    }
+}
+
+impl Evented for UnixSocket {
+    fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.io.register(poll, token, interest, opts)
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.io.reregister(poll, token, interest, opts)
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        self.io.deregister(poll)
+    }
+}
+
+
+impl From<Io> for UnixSocket {
+    fn from(io: Io) -> UnixSocket {
+        UnixSocket { io: io }
+    }
+}
+
+impl FromRawFd for UnixSocket {
+    unsafe fn from_raw_fd(fd: RawFd) -> UnixSocket {
+        UnixSocket { io: Io::from_raw_fd(fd) }
+    }
+}
+
+impl IntoRawFd for UnixSocket {
+    fn into_raw_fd(self) -> RawFd {
+        self.io.into_raw_fd()
+    }
+}
+
+impl AsRawFd for UnixSocket {
+    fn as_raw_fd(&self) -> RawFd {
+        self.io.as_raw_fd()
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/sys/windows/awakener.rs
@@ -0,0 +1,66 @@
+use std::sync::Mutex;
+
+use miow::iocp::CompletionStatus;
+use {io, poll, Ready, Poll, PollOpt, Token};
+use event::Evented;
+use sys::windows::Selector;
+
+pub struct Awakener {
+    inner: Mutex<Option<AwakenerInner>>,
+}
+
+struct AwakenerInner {
+    token: Token,
+    selector: Selector,
+}
+
+impl Awakener {
+    pub fn new() -> io::Result<Awakener> {
+        Ok(Awakener {
+            inner: Mutex::new(None),
+        })
+    }
+
+    pub fn wakeup(&self) -> io::Result<()> {
+        // Each wakeup notification has NULL as its `OVERLAPPED` pointer to
+        // indicate that it's from this awakener and not part of an I/O
+        // operation. This is specially recognized by the selector.
+        //
+        // If we haven't been registered with an event loop yet just silently
+        // succeed.
+        if let Some(inner) = self.inner.lock().unwrap().as_ref() {
+            let status = CompletionStatus::new(0,
+                                               usize::from(inner.token),
+                                               0 as *mut _);
+            try!(inner.selector.port().post(status));
+        }
+        Ok(())
+    }
+
+    pub fn cleanup(&self) {
+        // noop
+    }
+}
+
+impl Evented for Awakener {
+    fn register(&self, poll: &Poll, token: Token, events: Ready,
+                opts: PollOpt) -> io::Result<()> {
+        assert_eq!(opts, PollOpt::edge());
+        assert_eq!(events, Ready::readable());
+        *self.inner.lock().unwrap() = Some(AwakenerInner {
+            selector: poll::selector(poll).clone_ref(),
+            token: token,
+        });
+        Ok(())
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token, events: Ready,
+                  opts: PollOpt) -> io::Result<()> {
+        self.register(poll, token, events, opts)
+    }
+
+    fn deregister(&self, _poll: &Poll) -> io::Result<()> {
+        *self.inner.lock().unwrap() = None;
+        Ok(())
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/sys/windows/buffer_pool.rs
@@ -0,0 +1,20 @@
+pub struct BufferPool {
+    pool: Vec<Vec<u8>>,
+}
+
+impl BufferPool {
+    pub fn new(cap: usize) -> BufferPool {
+        BufferPool { pool: Vec::with_capacity(cap) }
+    }
+
+    pub fn get(&mut self, default_cap: usize) -> Vec<u8> {
+        self.pool.pop().unwrap_or_else(|| Vec::with_capacity(default_cap))
+    }
+
+    pub fn put(&mut self, mut buf: Vec<u8>) {
+        if self.pool.len() < self.pool.capacity(){
+            unsafe { buf.set_len(0); }
+            self.pool.push(buf);
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/sys/windows/from_raw_arc.rs
@@ -0,0 +1,116 @@
+//! A "Manual Arc" which allows manually frobbing the reference count
+//!
+//! This module contains a copy of the `Arc` found in the standard library,
+//! stripped down to the bare bones of what we actually need. The reason this is
+//! done is for the ability to concretely know the memory layout of the `Inner`
+//! structure of the arc pointer itself (e.g. `ArcInner` in the standard
+//! library).
+//!
+//! We do some unsafe casting from `*mut OVERLAPPED` to a `FromRawArc<T>` to
+//! ensure that data lives for the length of an I/O operation, but this means
+//! that we have to know the layouts of the structures involved. This
+//! representation primarily guarantees that the data, `T` is at the front of
+//! the inner pointer always.
+//!
+//! Note that we're missing out on some various optimizations implemented in the
+//! standard library:
+//!
+//! * The size of `FromRawArc` is actually two words because of the drop flag
+//! * The compiler doesn't understand that the pointer in `FromRawArc` is never
+//!   null, so Option<FromRawArc<T>> is not a nullable pointer.
+
+use std::ops::Deref;
+use std::mem;
+use std::sync::atomic::{self, AtomicUsize, Ordering};
+
+pub struct FromRawArc<T> {
+    _inner: *mut Inner<T>,
+}
+
+unsafe impl<T: Sync + Send> Send for FromRawArc<T> { }
+unsafe impl<T: Sync + Send> Sync for FromRawArc<T> { }
+
+#[repr(C)]
+struct Inner<T> {
+    data: T,
+    cnt: AtomicUsize,
+}
+
+impl<T> FromRawArc<T> {
+    pub fn new(data: T) -> FromRawArc<T> {
+        let x = Box::new(Inner {
+            data: data,
+            cnt: AtomicUsize::new(1),
+        });
+        FromRawArc { _inner: unsafe { mem::transmute(x) } }
+    }
+
+    pub unsafe fn from_raw(ptr: *mut T) -> FromRawArc<T> {
+        // Note that if we could use `mem::transmute` here to get a libstd Arc
+        // (guaranteed) then we could just use std::sync::Arc, but this is the
+        // crucial reason this currently exists.
+        FromRawArc { _inner: ptr as *mut Inner<T> }
+    }
+}
+
+impl<T> Clone for FromRawArc<T> {
+    fn clone(&self) -> FromRawArc<T> {
+        // Atomic ordering of Relaxed lifted from libstd, but the general idea
+        // is that you need synchronization to communicate this increment to
+        // another thread, so this itself doesn't need to be synchronized.
+        unsafe {
+            (*self._inner).cnt.fetch_add(1, Ordering::Relaxed);
+        }
+        FromRawArc { _inner: self._inner }
+    }
+}
+
+impl<T> Deref for FromRawArc<T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe { &(*self._inner).data }
+    }
+}
+
+impl<T> Drop for FromRawArc<T> {
+    fn drop(&mut self) {
+        unsafe {
+            // Atomic orderings lifted from the standard library
+            if (*self._inner).cnt.fetch_sub(1, Ordering::Release) != 1 {
+                return
+            }
+            atomic::fence(Ordering::Acquire);
+            drop(mem::transmute::<_, Box<T>>(self._inner));
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::FromRawArc;
+
+    #[test]
+    fn smoke() {
+        let a = FromRawArc::new(1);
+        assert_eq!(*a, 1);
+        assert_eq!(*a.clone(), 1);
+    }
+
+    #[test]
+    fn drops() {
+        struct A<'a>(&'a mut bool);
+        impl<'a> Drop for A<'a> {
+            fn drop(&mut self) {
+                *self.0 = true;
+            }
+        }
+        let mut a = false;
+        {
+            let a = FromRawArc::new(A(&mut a));
+            a.clone();
+            assert!(!*a.0);
+        }
+        assert!(a);
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/sys/windows/mod.rs
@@ -0,0 +1,191 @@
+//! Implementation of mio for Windows using IOCP
+//!
+//! This module uses I/O Completion Ports (IOCP) on Windows to implement mio's
+//! Unix epoll-like interface. Unfortunately these two I/O models are
+//! fundamentally incompatible:
+//!
+//! * IOCP is a completion-based model where work is submitted to the kernel and
+//!   a program is notified later when the work finished.
+//! * epoll is a readiness-based model where the kernel is queried as to what
+//!   work can be done, and afterwards the work is done.
+//!
+//! As a result, this implementation for Windows is much less "low level" than
+//! the Unix implementation of mio. This design decision was intentional,
+//! however.
+//!
+//! ## What is IOCP?
+//!
+//! The [official docs][docs] have a comprehensive explanation of what IOCP is,
+//! but at a high level it requires the following operations to be executed to
+//! perform some I/O:
+//!
+//! 1. A completion port is created
+//! 2. An I/O handle and a token is registered with this completion port
+//! 3. Some I/O is issued on the handle. This generally means that an API was
+//!    invoked with a zeroed `OVERLAPPED` structure. The API will immediately
+//!    return.
+//! 4. After some time, the application queries the I/O port for completed
+//!    events. The port will returned a pointer to the `OVERLAPPED` along with
+//!    the token presented at registration time.
+//!
+//! Many I/O operations can be fired off before waiting on a port, and the port
+//! will block execution of the calling thread until an I/O event has completed
+//! (or a timeout has elapsed).
+//!
+//! Currently all of these low-level operations are housed in a separate `miow`
+//! crate to provide a 0-cost abstraction over IOCP. This crate uses that to
+//! implement all fiddly bits so there's very few actual Windows API calls or
+//! `unsafe` blocks as a result.
+//!
+//! [docs]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365198%28v=vs.85%29.aspx
+//!
+//! ## Safety of IOCP
+//!
+//! Unfortunately for us, IOCP is pretty unsafe in terms of Rust lifetimes and
+//! such. When an I/O operation is submitted to the kernel, it involves handing
+//! the kernel a few pointers like a buffer to read/write, an `OVERLAPPED`
+//! structure pointer, and perhaps some other buffers such as for socket
+//! addresses. These pointers all have to remain valid **for the entire I/O
+//! operation's duration**.
+//!
+//! There's no way to define a safe lifetime for these pointers/buffers over
+//! the span of an I/O operation, so we're forced to add a layer of abstraction
+//! (not 0-cost) to make these APIs safe. Currently this implementation
+//! basically just boxes everything up on the heap to give it a stable address
+//! and then keys off that most of the time.
+//!
+//! ## From completion to readiness
+//!
+//! Translating a completion-based model to a readiness-based model is also no
+//! easy task, and a significant portion of this implementation is managing this
+//! translation. The basic idea behind this implementation is to issue I/O
+//! operations preemptively and then translate their completions to a "I'm
+//! ready" event.
+//!
+//! For example, in the case of reading a `TcpSocket`, as soon as a socket is
+//! connected (or registered after an accept) a read operation is executed.
+//! While the read is in progress calls to `read` will return `WouldBlock`, and
+//! once the read is completed we translate the completion notification into a
+//! `readable` event. Once the internal buffer is drained (e.g. all data from it
+//! has been read) a read operation is re-issued.
+//!
+//! Write operations are a little different from reads, and the current
+//! implementation is to just schedule a write as soon as `write` is first
+//! called. While that write operation is in progress all future calls to
+//! `write` will return `WouldBlock`. Completion of the write then translates to
+//! a `writable` event. Note that this will probably want to add some layer of
+//! internal buffering in the future.
+//!
+//! ## Buffer Management
+//!
+//! As there's lots of I/O operations in flight at any one point in time,
+//! there's lots of live buffers that need to be juggled around (e.g. this
+//! implementation's own internal buffers).
+//!
+//! Currently all buffers are created for the I/O operation at hand and are then
+//! discarded when it completes (this is listed as future work below).
+//!
+//! ## Callback Management
+//!
+//! When the main event loop receives a notification that an I/O operation has
+//! completed, some work needs to be done to translate that to a set of events
+//! or perhaps some more I/O needs to be scheduled. For example after a
+//! `TcpStream` is connected it generates a writable event and also schedules a
+//! read.
+//!
+//! To manage all this the `Selector` uses the `OVERLAPPED` pointer from the
+//! completion status. The selector assumes that all `OVERLAPPED` pointers are
+//! actually pointers to the interior of a `selector::Overlapped` which means
+//! that right after the `OVERLAPPED` itself there's a function pointer. This
+//! function pointer is given the completion status as well as another callback
+//! to push events onto the selector.
+//!
+//! The callback for each I/O operation doesn't have any environment, so it
+//! relies on memory layout and unsafe casting to translate an `OVERLAPPED`
+//! pointer (or in this case a `selector::Overlapped` pointer) to a type of
+//! `FromRawArc<T>` (see module docs for why this type exists).
+//!
+//! ## Thread Safety
+//!
+//! Currently all of the I/O primitives make liberal use of `Arc` and `Mutex`
+//! as an implementation detail. The main reason for this is to ensure that the
+//! types are `Send` and `Sync`, but the implementations have not been stressed
+//! in multithreaded situations yet. As a result, there are bound to be
+//! functional surprises in using these concurrently.
+//!
+//! ## Future Work
+//!
+//! First up, let's take a look at unimplemented portions of this module:
+//!
+//! * The `PollOpt::level()` option is currently entirely unimplemented.
+//! * Each `EventLoop` currently owns its completion port, but this prevents an
+//!   I/O handle from being added to multiple event loops (something that can be
+//!   done on Unix). Additionally, it hinders event loops moving across threads.
+//!   This should be solved by likely having a global `Selector` which all
+//!   others then communicate with.
+//! * Although Unix sockets don't exist on Windows, there are named pipes and
+//!   those should likely be bound here in a similar fashion to `TcpStream`.
+//!
+//! Next up, there are a few performance improvements and optimizations that can
+//! still be implemented
+//!
+//! * Buffer management right now is pretty bad, they're all just allocated
+//!   right before an I/O operation and discarded right after. There should at
+//!   least be some form of buffering buffers.
+//! * No calls to `write` are internally buffered before being scheduled, which
+//!   means that writing performance is abysmal compared to Unix. There should
+//!   be some level of buffering of writes probably.
+
+use std::io;
+use std::os::windows::prelude::*;
+
+use kernel32;
+use winapi;
+
+mod awakener;
+#[macro_use]
+mod selector;
+mod tcp;
+mod udp;
+mod from_raw_arc;
+mod buffer_pool;
+
+pub use self::awakener::Awakener;
+pub use self::selector::{Events, Selector, Overlapped, Binding};
+pub use self::tcp::{TcpStream, TcpListener};
+pub use self::udp::UdpSocket;
+
+#[derive(Copy, Clone)]
+enum Family {
+    V4, V6,
+}
+
+fn wouldblock() -> io::Error {
+    io::Error::new(io::ErrorKind::WouldBlock, "operation would block")
+}
+
+unsafe fn cancel(socket: &AsRawSocket,
+                 overlapped: &Overlapped) -> io::Result<()> {
+    let handle = socket.as_raw_socket() as winapi::HANDLE;
+    let ret = kernel32::CancelIoEx(handle, overlapped.as_mut_ptr());
+    if ret == 0 {
+        Err(io::Error::last_os_error())
+    } else {
+        Ok(())
+    }
+}
+
+unsafe fn no_notify_on_instant_completion(handle: winapi::HANDLE) -> io::Result<()> {
+    // TODO: move those to winapi
+    const FILE_SKIP_COMPLETION_PORT_ON_SUCCESS: winapi::UCHAR = 1;
+    const FILE_SKIP_SET_EVENT_ON_HANDLE: winapi::UCHAR = 2;
+
+    let flags = FILE_SKIP_COMPLETION_PORT_ON_SUCCESS | FILE_SKIP_SET_EVENT_ON_HANDLE;
+
+    let r = kernel32::SetFileCompletionNotificationModes(handle, flags);
+    if r == winapi::TRUE {
+        Ok(())
+    } else {
+        Err(io::Error::last_os_error())
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/sys/windows/selector.rs
@@ -0,0 +1,528 @@
+#![allow(deprecated)]
+
+use std::{fmt, io, u32};
+use std::cell::UnsafeCell;
+use std::os::windows::prelude::*;
+use std::sync::{Arc, Mutex};
+use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
+use std::time::Duration;
+
+use lazycell::AtomicLazyCell;
+
+use winapi::*;
+use miow;
+use miow::iocp::{CompletionPort, CompletionStatus};
+
+use event_imp::{Event, Evented, Ready};
+use poll::{self, Poll};
+use sys::windows::buffer_pool::BufferPool;
+use {Token, PollOpt};
+
+/// Each Selector has a globally unique(ish) ID associated with it. This ID
+/// gets tracked by `TcpStream`, `TcpListener`, etc... when they are first
+/// registered with the `Selector`. If a type that is previously associated with
+/// a `Selector` attempts to register itself with a different `Selector`, the
+/// operation will return with an error. This matches windows behavior.
+static NEXT_ID: AtomicUsize = ATOMIC_USIZE_INIT;
+
+/// The guts of the Windows event loop, this is the struct which actually owns
+/// a completion port.
+///
+/// Internally this is just an `Arc`, and this allows handing out references to
+/// the internals to I/O handles registered on this selector. This is
+/// required to schedule I/O operations independently of being inside the event
+/// loop (e.g. when a call to `write` is seen we're not "in the event loop").
+pub struct Selector {
+    inner: Arc<SelectorInner>,
+}
+
+struct SelectorInner {
+    /// Unique identifier of the `Selector`
+    id: usize,
+
+    /// The actual completion port that's used to manage all I/O
+    port: CompletionPort,
+
+    /// A pool of buffers usable by this selector.
+    ///
+    /// Primitives will take buffers from this pool to perform I/O operations,
+    /// and once complete they'll be put back in.
+    buffers: Mutex<BufferPool>,
+}
+
+impl Selector {
+    pub fn new() -> io::Result<Selector> {
+        // offset by 1 to avoid choosing 0 as the id of a selector
+        let id = NEXT_ID.fetch_add(1, Ordering::Relaxed) + 1;
+
+        CompletionPort::new(1).map(|cp| {
+            Selector {
+                inner: Arc::new(SelectorInner {
+                    id: id,
+                    port: cp,
+                    buffers: Mutex::new(BufferPool::new(256)),
+                }),
+            }
+        })
+    }
+
+    pub fn select(&self,
+                  events: &mut Events,
+                  awakener: Token,
+                  timeout: Option<Duration>) -> io::Result<bool> {
+        trace!("select; timeout={:?}", timeout);
+
+        // Clear out the previous list of I/O events and get some more!
+        events.events.truncate(0);
+
+        trace!("polling IOCP");
+        let n = match self.inner.port.get_many(&mut events.statuses, timeout) {
+            Ok(statuses) => statuses.len(),
+            Err(ref e) if e.raw_os_error() == Some(WAIT_TIMEOUT as i32) => 0,
+            Err(e) => return Err(e),
+        };
+
+        let mut ret = false;
+        for status in events.statuses[..n].iter() {
+            // This should only ever happen from the awakener, and we should
+            // only ever have one awakener right not, so assert as such.
+            if status.overlapped() as usize == 0 {
+                assert_eq!(status.token(), usize::from(awakener));
+                ret = true;
+                continue;
+            }
+
+            let callback = unsafe {
+                (*(status.overlapped() as *mut Overlapped)).callback
+            };
+
+            trace!("select; -> got overlapped");
+            callback(status.entry());
+        }
+
+        trace!("returning");
+        Ok(ret)
+    }
+
+    /// Gets a reference to the underlying `CompletionPort` structure.
+    pub fn port(&self) -> &CompletionPort {
+        &self.inner.port
+    }
+
+    /// Gets a new reference to this selector, although all underlying data
+    /// structures will refer to the same completion port.
+    pub fn clone_ref(&self) -> Selector {
+        Selector { inner: self.inner.clone() }
+    }
+
+    /// Return the `Selector`'s identifier
+    pub fn id(&self) -> usize {
+        self.inner.id
+    }
+}
+
+impl SelectorInner {
+    fn identical(&self, other: &SelectorInner) -> bool {
+        (self as *const SelectorInner) == (other as *const SelectorInner)
+    }
+}
+
+// A registration is stored in each I/O object which keeps track of how it is
+// associated with a `Selector` above.
+//
+// Once associated with a `Selector`, a registration can never be un-associated
+// (due to IOCP requirements). This is actually implemented through the
+// `poll::Registration` and `poll::SetReadiness` APIs to keep track of all the
+// level/edge/filtering business.
+/// A `Binding` is embedded in all I/O objects associated with a `Poll`
+/// object.
+///
+/// Each registration keeps track of which selector the I/O object is
+/// associated with, ensuring that implementations of `Evented` can be
+/// conformant for the various methods on Windows.
+///
+/// If you're working with custom IOCP-enabled objects then you'll want to
+/// ensure that one of these instances is stored in your object and used in the
+/// implementation of `Evented`.
+///
+/// For more information about how to use this see the `windows` module
+/// documentation in this crate.
+pub struct Binding {
+    selector: AtomicLazyCell<Arc<SelectorInner>>,
+}
+
+impl Binding {
+    /// Creates a new blank binding ready to be inserted into an I/O
+    /// object.
+    ///
+    /// Won't actually do anything until associated with a `Poll` loop.
+    pub fn new() -> Binding {
+        Binding { selector: AtomicLazyCell::new() }
+    }
+
+    /// Registers a new handle with the `Poll` specified, also assigning the
+    /// `token` specified.
+    ///
+    /// This function is intended to be used as part of `Evented::register` for
+    /// custom IOCP objects. It will add the specified handle to the internal
+    /// IOCP object with the provided `token`. All future events generated by
+    /// the handled provided will be received by the `Poll`'s internal IOCP
+    /// object.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe as the `Poll` instance has assumptions about
+    /// what the `OVERLAPPED` pointer used for each I/O operation looks like.
+    /// Specifically they must all be instances of the `Overlapped` type in
+    /// this crate. More information about this can be found on the
+    /// `windows` module in this crate.
+    pub unsafe fn register_handle(&self,
+                                  handle: &AsRawHandle,
+                                  token: Token,
+                                  poll: &Poll) -> io::Result<()> {
+        let selector = poll::selector(poll);
+
+        // Ignore errors, we'll see them on the next line.
+        drop(self.selector.fill(selector.inner.clone()));
+        try!(self.check_same_selector(poll));
+
+        selector.inner.port.add_handle(usize::from(token), handle)
+    }
+
+    /// Same as `register_handle` but for sockets.
+    pub unsafe fn register_socket(&self,
+                                  handle: &AsRawSocket,
+                                  token: Token,
+                                  poll: &Poll) -> io::Result<()> {
+        let selector = poll::selector(poll);
+        drop(self.selector.fill(selector.inner.clone()));
+        try!(self.check_same_selector(poll));
+        selector.inner.port.add_socket(usize::from(token), handle)
+    }
+
+    /// Reregisters the handle provided from the `Poll` provided.
+    ///
+    /// This is intended to be used as part of `Evented::reregister` but note
+    /// that this function does not currently reregister the provided handle
+    /// with the `poll` specified. IOCP has a special binding for changing the
+    /// token which has not yet been implemented. Instead this function should
+    /// be used to assert that the call to `reregister` happened on the same
+    /// `Poll` that was passed into to `register`.
+    ///
+    /// Eventually, though, the provided `handle` will be re-assigned to have
+    /// the token `token` on the given `poll` assuming that it's been
+    /// previously registered with it.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe for similar reasons to `register`. That is,
+    /// there may be pending I/O events and such which aren't handled correctly.
+    pub unsafe fn reregister_handle(&self,
+                                    _handle: &AsRawHandle,
+                                    _token: Token,
+                                    poll: &Poll) -> io::Result<()> {
+        self.check_same_selector(poll)
+    }
+
+    /// Same as `reregister_handle`, but for sockets.
+    pub unsafe fn reregister_socket(&self,
+                                    _socket: &AsRawSocket,
+                                    _token: Token,
+                                    poll: &Poll) -> io::Result<()> {
+        self.check_same_selector(poll)
+    }
+
+    /// Deregisters the handle provided from the `Poll` provided.
+    ///
+    /// This is intended to be used as part of `Evented::deregister` but note
+    /// that this function does not currently deregister the provided handle
+    /// from the `poll` specified. IOCP has a special binding for that which has
+    /// not yet been implemented. Instead this function should be used to assert
+    /// that the call to `deregister` happened on the same `Poll` that was
+    /// passed into to `register`.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe for similar reasons to `register`. That is,
+    /// there may be pending I/O events and such which aren't handled correctly.
+    pub unsafe fn deregister_handle(&self,
+                                    _handle: &AsRawHandle,
+                                    poll: &Poll) -> io::Result<()> {
+        self.check_same_selector(poll)
+    }
+
+    /// Same as `deregister_handle`, but for sockets.
+    pub unsafe fn deregister_socket(&self,
+                                    _socket: &AsRawSocket,
+                                    poll: &Poll) -> io::Result<()> {
+        self.check_same_selector(poll)
+    }
+
+    fn check_same_selector(&self, poll: &Poll) -> io::Result<()> {
+        let selector = poll::selector(poll);
+        match self.selector.borrow() {
+            Some(prev) if prev.identical(&selector.inner) => Ok(()),
+            Some(_) |
+            None => Err(other("socket already registered")),
+        }
+    }
+}
+
+impl fmt::Debug for Binding {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "Binding")
+    }
+}
+
+/// Helper struct used for TCP and UDP which bundles a `binding` with a
+/// `SetReadiness` handle.
+pub struct ReadyBinding {
+    binding: Binding,
+    readiness: Option<poll::SetReadiness>,
+}
+
+impl ReadyBinding {
+    /// Creates a new blank binding ready to be inserted into an I/O object.
+    ///
+    /// Won't actually do anything until associated with an `Selector` loop.
+    pub fn new() -> ReadyBinding {
+        ReadyBinding {
+            binding: Binding::new(),
+            readiness: None,
+        }
+    }
+
+    /// Returns whether this binding has been associated with a selector
+    /// yet.
+    pub fn registered(&self) -> bool {
+        self.readiness.is_some()
+    }
+
+    /// Acquires a buffer with at least `size` capacity.
+    ///
+    /// If associated with a selector, this will attempt to pull a buffer from
+    /// that buffer pool. If not associated with a selector, this will allocate
+    /// a fresh buffer.
+    pub fn get_buffer(&self, size: usize) -> Vec<u8> {
+        match self.binding.selector.borrow() {
+            Some(i) => i.buffers.lock().unwrap().get(size),
+            None => Vec::with_capacity(size),
+        }
+    }
+
+    /// Returns a buffer to this binding.
+    ///
+    /// If associated with a selector, this will push the buffer back into the
+    /// selector's pool of buffers. Otherwise this will just drop the buffer.
+    pub fn put_buffer(&self, buf: Vec<u8>) {
+        if let Some(i) = self.binding.selector.borrow() {
+            i.buffers.lock().unwrap().put(buf);
+        }
+    }
+
+    /// Sets the readiness of this I/O object to a particular `set`.
+    ///
+    /// This is later used to fill out and respond to requests to `poll`. Note
+    /// that this is all implemented through the `SetReadiness` structure in the
+    /// `poll` module.
+    pub fn set_readiness(&self, set: Ready) {
+        if let Some(ref i) = self.readiness {
+            trace!("set readiness to {:?}", set);
+            i.set_readiness(set).expect("event loop disappeared?");
+        }
+    }
+
+    /// Queries what the current readiness of this I/O object is.
+    ///
+    /// This is what's being used to generate events returned by `poll`.
+    pub fn readiness(&self) -> Ready {
+        match self.readiness {
+            Some(ref i) => i.readiness(),
+            None => Ready::empty(),
+        }
+    }
+
+    /// Implementation of the `Evented::register` function essentially.
+    ///
+    /// Returns an error if we're already registered with another event loop,
+    /// and otherwise just reassociates ourselves with the event loop to
+    /// possible change tokens.
+    pub fn register_socket(&mut self,
+                           socket: &AsRawSocket,
+                           poll: &Poll,
+                           token: Token,
+                           events: Ready,
+                           opts: PollOpt,
+                           registration: &Mutex<Option<poll::Registration>>)
+                           -> io::Result<()> {
+        trace!("register {:?} {:?}", token, events);
+        unsafe {
+            try!(self.binding.register_socket(socket, token, poll));
+        }
+
+        let (r, s) = poll::new_registration(poll, token, events, opts);
+        self.readiness = Some(s);
+        *registration.lock().unwrap() = Some(r);
+        Ok(())
+    }
+
+    /// Implementation of `Evented::reregister` function.
+    pub fn reregister_socket(&mut self,
+                             socket: &AsRawSocket,
+                             poll: &Poll,
+                             token: Token,
+                             events: Ready,
+                             opts: PollOpt,
+                             registration: &Mutex<Option<poll::Registration>>)
+                             -> io::Result<()> {
+        trace!("reregister {:?} {:?}", token, events);
+        unsafe {
+            try!(self.binding.reregister_socket(socket, token, poll));
+        }
+
+        registration.lock().unwrap()
+                    .as_mut().unwrap()
+                    .reregister(poll, token, events, opts)
+    }
+
+    /// Implementation of the `Evented::deregister` function.
+    ///
+    /// Doesn't allow registration with another event loop, just shuts down
+    /// readiness notifications and such.
+    pub fn deregister(&mut self,
+                      socket: &AsRawSocket,
+                      poll: &Poll,
+                      registration: &Mutex<Option<poll::Registration>>)
+                      -> io::Result<()> {
+        trace!("deregistering");
+        unsafe {
+            try!(self.binding.deregister_socket(socket, poll));
+        }
+
+        registration.lock().unwrap()
+                    .as_ref().unwrap()
+                    .deregister(poll)
+    }
+}
+
+fn other(s: &str) -> io::Error {
+    io::Error::new(io::ErrorKind::Other, s)
+}
+
+#[derive(Debug)]
+pub struct Events {
+    /// Raw I/O event completions are filled in here by the call to `get_many`
+    /// on the completion port above. These are then processed to run callbacks
+    /// which figure out what to do after the event is done.
+    statuses: Box<[CompletionStatus]>,
+
+    /// Literal events returned by `get` to the upwards `EventLoop`. This file
+    /// doesn't really modify this (except for the awakener), instead almost all
+    /// events are filled in by the `ReadinessQueue` from the `poll` module.
+    events: Vec<Event>,
+}
+
+impl Events {
+    pub fn with_capacity(cap: usize) -> Events {
+        // Note that it's possible for the output `events` to grow beyond the
+        // capacity as it can also include deferred events, but that's certainly
+        // not the end of the world!
+        Events {
+            statuses: vec![CompletionStatus::zero(); cap].into_boxed_slice(),
+            events: Vec::with_capacity(cap),
+        }
+    }
+
+    pub fn is_empty(&self) -> bool {
+        self.events.is_empty()
+    }
+
+    pub fn len(&self) -> usize {
+        self.events.len()
+    }
+
+    pub fn capacity(&self) -> usize {
+        self.events.capacity()
+    }
+
+    pub fn get(&self, idx: usize) -> Option<Event> {
+        self.events.get(idx).map(|e| *e)
+    }
+
+    pub fn push_event(&mut self, event: Event) {
+        self.events.push(event);
+    }
+}
+
+macro_rules! overlapped2arc {
+    ($e:expr, $t:ty, $($field:ident).+) => ({
+        let offset = offset_of!($t, $($field).+);
+        debug_assert!(offset < mem::size_of::<$t>());
+        FromRawArc::from_raw(($e as usize - offset) as *mut $t)
+    })
+}
+
+macro_rules! offset_of {
+    ($t:ty, $($field:ident).+) => (
+        &(*(0 as *const $t)).$($field).+ as *const _ as usize
+    )
+}
+
+// See sys::windows module docs for why this exists.
+//
+// The gist of it is that `Selector` assumes that all `OVERLAPPED` pointers are
+// actually inside one of these structures so it can use the `Callback` stored
+// right after it.
+//
+// We use repr(C) here to ensure that we can assume the overlapped pointer is
+// at the start of the structure so we can just do a cast.
+/// A wrapper around an internal instance over `miow::Overlapped` which is in
+/// turn a wrapper around the Windows type `OVERLAPPED`.
+///
+/// This type is required to be used for all IOCP operations on handles that are
+/// registered with an event loop. The event loop will receive notifications
+/// over `OVERLAPPED` pointers that have completed, and it will cast that
+/// pointer to a pointer to this structure and invoke the associated callback.
+#[repr(C)]
+pub struct Overlapped {
+    inner: UnsafeCell<miow::Overlapped>,
+    callback: fn(&OVERLAPPED_ENTRY),
+}
+
+impl Overlapped {
+    /// Creates a new `Overlapped` which will invoke the provided `cb` callback
+    /// whenever it's triggered.
+    ///
+    /// The returned `Overlapped` must be used as the `OVERLAPPED` passed to all
+    /// I/O operations that are registered with mio's event loop. When the I/O
+    /// operation associated with an `OVERLAPPED` pointer completes the event
+    /// loop will invoke the function pointer provided by `cb`.
+    pub fn new(cb: fn(&OVERLAPPED_ENTRY)) -> Overlapped {
+        Overlapped {
+            inner: UnsafeCell::new(miow::Overlapped::zero()),
+            callback: cb,
+        }
+    }
+
+    /// Get the underlying `Overlapped` instance as a raw pointer.
+    ///
+    /// This can be useful when only a shared borrow is held and the overlapped
+    /// pointer needs to be passed down to winapi.
+    pub fn as_mut_ptr(&self) -> *mut OVERLAPPED {
+        unsafe {
+            (*self.inner.get()).raw()
+        }
+    }
+}
+
+impl fmt::Debug for Overlapped {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "Overlapped")
+    }
+}
+
+// Overlapped's APIs are marked as unsafe Overlapped's APIs are marked as
+// unsafe as they must be used with caution to ensure thread safety. The
+// structure itself is safe to send across threads.
+unsafe impl Send for Overlapped {}
+unsafe impl Sync for Overlapped {}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/sys/windows/tcp.rs
@@ -0,0 +1,827 @@
+use std::fmt;
+use std::io::{self, Read, ErrorKind};
+use std::mem;
+use std::net::{self, SocketAddr, Shutdown};
+use std::os::windows::prelude::*;
+use std::sync::{Mutex, MutexGuard};
+use std::time::Duration;
+
+use miow::iocp::CompletionStatus;
+use miow::net::*;
+use net2::{TcpBuilder, TcpStreamExt as Net2TcpExt};
+use winapi::*;
+use iovec::IoVec;
+
+use {poll, Ready, Poll, PollOpt, Token};
+use event::Evented;
+use sys::windows::from_raw_arc::FromRawArc;
+use sys::windows::selector::{Overlapped, ReadyBinding};
+use sys::windows::{wouldblock, Family};
+
+pub struct TcpStream {
+    /// Separately stored implementation to ensure that the `Drop`
+    /// implementation on this type is only executed when it's actually dropped
+    /// (many clones of this `imp` are made).
+    imp: StreamImp,
+    registration: Mutex<Option<poll::Registration>>,
+}
+
+pub struct TcpListener {
+    imp: ListenerImp,
+    registration: Mutex<Option<poll::Registration>>,
+}
+
+#[derive(Clone)]
+struct StreamImp {
+    /// A stable address and synchronized access for all internals. This serves
+    /// to ensure that all `Overlapped` pointers are valid for a long period of
+    /// time as well as allowing completion callbacks to have access to the
+    /// internals without having ownership.
+    ///
+    /// Note that the reference count also allows us "loan out" copies to
+    /// completion ports while I/O is running to guarantee that this stays alive
+    /// until the I/O completes. You'll notice a number of calls to
+    /// `mem::forget` below, and these only happen on successful scheduling of
+    /// I/O and are paired with `overlapped2arc!` macro invocations in the
+    /// completion callbacks (to have a decrement match the increment).
+    inner: FromRawArc<StreamIo>,
+}
+
+#[derive(Clone)]
+struct ListenerImp {
+    inner: FromRawArc<ListenerIo>,
+}
+
+struct StreamIo {
+    inner: Mutex<StreamInner>,
+    read: Overlapped, // also used for connect
+    write: Overlapped,
+    socket: net::TcpStream,
+}
+
+struct ListenerIo {
+    inner: Mutex<ListenerInner>,
+    accept: Overlapped,
+    family: Family,
+    socket: net::TcpListener,
+}
+
+struct StreamInner {
+    iocp: ReadyBinding,
+    deferred_connect: Option<SocketAddr>,
+    read: State<(), ()>,
+    write: State<(Vec<u8>, usize), (Vec<u8>, usize)>,
+    /// whether we are instantly notified of success
+    /// (FILE_SKIP_COMPLETION_PORT_ON_SUCCESS,
+    ///  without a roundtrip through the event loop)
+    instant_notify: bool,
+}
+
+struct ListenerInner {
+    iocp: ReadyBinding,
+    accept: State<net::TcpStream, (net::TcpStream, SocketAddr)>,
+    accept_buf: AcceptAddrsBuf,
+    instant_notify: bool,
+}
+
+enum State<T, U> {
+    Empty,              // no I/O operation in progress
+    Pending(T),         // an I/O operation is in progress
+    Ready(U),           // I/O has finished with this value
+    Error(io::Error),   // there was an I/O error
+}
+
+impl TcpStream {
+    fn new(socket: net::TcpStream,
+           deferred_connect: Option<SocketAddr>) -> TcpStream {
+        TcpStream {
+            registration: Mutex::new(None),
+            imp: StreamImp {
+                inner: FromRawArc::new(StreamIo {
+                    read: Overlapped::new(read_done),
+                    write: Overlapped::new(write_done),
+                    socket: socket,
+                    inner: Mutex::new(StreamInner {
+                        iocp: ReadyBinding::new(),
+                        deferred_connect: deferred_connect,
+                        read: State::Empty,
+                        write: State::Empty,
+                        instant_notify: false,
+                    }),
+                }),
+            },
+        }
+    }
+
+    pub fn connect(socket: net::TcpStream, addr: &SocketAddr)
+                   -> io::Result<TcpStream> {
+        try!(socket.set_nonblocking(true));
+        Ok(TcpStream::new(socket, Some(*addr)))
+    }
+
+    pub fn from_stream(stream: net::TcpStream) -> TcpStream {
+        TcpStream::new(stream, None)
+    }
+
+    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+        self.imp.inner.socket.peer_addr()
+    }
+
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
+        self.imp.inner.socket.local_addr()
+    }
+
+    pub fn try_clone(&self) -> io::Result<TcpStream> {
+        self.imp.inner.socket.try_clone().map(|s| TcpStream::new(s, None))
+    }
+
+    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
+        self.imp.inner.socket.shutdown(how)
+    }
+
+    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
+        self.imp.inner.socket.set_nodelay(nodelay)
+    }
+
+    pub fn nodelay(&self) -> io::Result<bool> {
+        self.imp.inner.socket.nodelay()
+    }
+
+    pub fn set_recv_buffer_size(&self, size: usize) -> io::Result<()> {
+        self.imp.inner.socket.set_recv_buffer_size(size)
+    }
+
+    pub fn recv_buffer_size(&self) -> io::Result<usize> {
+        self.imp.inner.socket.recv_buffer_size()
+    }
+
+    pub fn set_send_buffer_size(&self, size: usize) -> io::Result<()> {
+        self.imp.inner.socket.set_send_buffer_size(size)
+    }
+
+    pub fn send_buffer_size(&self) -> io::Result<usize> {
+        self.imp.inner.socket.send_buffer_size()
+    }
+
+    pub fn set_keepalive(&self, keepalive: Option<Duration>) -> io::Result<()> {
+        self.imp.inner.socket.set_keepalive(keepalive)
+    }
+
+    pub fn keepalive(&self) -> io::Result<Option<Duration>> {
+        self.imp.inner.socket.keepalive()
+    }
+
+    pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
+        self.imp.inner.socket.set_ttl(ttl)
+    }
+
+    pub fn ttl(&self) -> io::Result<u32> {
+        self.imp.inner.socket.ttl()
+    }
+
+    pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
+        self.imp.inner.socket.set_only_v6(only_v6)
+    }
+
+    pub fn only_v6(&self) -> io::Result<bool> {
+        self.imp.inner.socket.only_v6()
+    }
+
+    pub fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
+        self.imp.inner.socket.set_linger(dur)
+    }
+
+    pub fn linger(&self) -> io::Result<Option<Duration>> {
+        self.imp.inner.socket.linger()
+    }
+
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        if let Some(e) = try!(self.imp.inner.socket.take_error()) {
+            return Ok(Some(e))
+        }
+
+        // If the syscall didn't return anything then also check to see if we've
+        // squirreled away an error elsewhere for example as part of a connect
+        // operation.
+        //
+        // Typically this is used like so:
+        //
+        // 1. A `connect` is issued
+        // 2. Wait for the socket to be writable
+        // 3. Call `take_error` to see if the connect succeeded.
+        //
+        // Right now the `connect` operation finishes in `read_done` below and
+        // fill will in `State::Error` in the `read` slot if it fails, so we
+        // extract that here.
+        let mut me = self.inner();
+        match mem::replace(&mut me.read, State::Empty) {
+            State::Error(e) => {
+                self.imp.schedule_read(&mut me);
+                Ok(Some(e))
+            }
+            other => {
+                me.read = other;
+                Ok(None)
+            }
+        }
+    }
+
+    fn inner(&self) -> MutexGuard<StreamInner> {
+        self.imp.inner()
+    }
+
+    fn post_register(&self, interest: Ready, me: &mut StreamInner) {
+        if interest.is_readable() {
+            self.imp.schedule_read(me);
+        }
+
+        // At least with epoll, if a socket is registered with an interest in
+        // writing and it's immediately writable then a writable event is
+        // generated immediately, so do so here.
+        if interest.is_writable() {
+            if let State::Empty = me.write {
+                self.imp.add_readiness(me, Ready::writable());
+            }
+        }
+    }
+
+    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
+        self.readv(&mut [buf.into()])
+    }
+
+    pub fn readv(&self, bufs: &mut [&mut IoVec]) -> io::Result<usize> {
+        let mut me = self.inner();
+
+        match me.read {
+            // Empty == we're not associated yet, and if we're pending then
+            // these are both cases where we return "would block"
+            State::Empty |
+            State::Pending(()) => return Err(wouldblock()),
+
+            // If we got a delayed error as part of a `read_overlapped` below,
+            // return that here. Also schedule another read in case it was
+            // transient.
+            State::Error(_) => {
+                let e = match mem::replace(&mut me.read, State::Empty) {
+                    State::Error(e) => e,
+                    _ => panic!(),
+                };
+                self.imp.schedule_read(&mut me);
+                return Err(e)
+            }
+
+            // If we're ready for a read then some previous 0-byte read has
+            // completed. In that case the OS's socket buffer has something for
+            // us, so we just keep pulling out bytes while we can in the loop
+            // below.
+            State::Ready(()) => {}
+        }
+
+        // TODO: Does WSARecv work on a nonblocking sockets? We ideally want to
+        //       call that instead of looping over all the buffers and calling
+        //       `recv` on each buffer. I'm not sure though if an overlapped
+        //       socket in nonblocking mode would work with that use case,
+        //       however, so for now we just call `recv`.
+
+        let mut amt = 0;
+        for buf in bufs {
+            match (&self.imp.inner.socket).read(buf) {
+                // If we did a partial read, then return what we've read so far
+                Ok(n) if n < buf.len() => return Ok(amt + n),
+
+                // Otherwise filled this buffer entirely, so try to fill the
+                // next one as well.
+                Ok(n) => amt += n,
+
+                // If we hit an error then things get tricky if we've already
+                // read some data. If the error is "would block" then we just
+                // return the data we've read so far while scheduling another
+                // 0-byte read.
+                //
+                // If we've read data and the error kind is not "would block",
+                // then we stash away the error to get returned later and return
+                // the data that we've read.
+                //
+                // Finally if we haven't actually read any data we just
+                // reschedule a 0-byte read to happen again and then return the
+                // error upwards.
+                Err(e) => {
+                    if amt > 0 && e.kind() == io::ErrorKind::WouldBlock {
+                        me.read = State::Empty;
+                        self.imp.schedule_read(&mut me);
+                        return Ok(amt)
+                    } else if amt > 0 {
+                        me.read = State::Error(e);
+                        return Ok(amt)
+                    } else {
+                        me.read = State::Empty;
+                        self.imp.schedule_read(&mut me);
+                        return Err(e)
+                    }
+                }
+            }
+        }
+
+        Ok(amt)
+    }
+
+    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
+        self.writev(&[buf.into()])
+    }
+
+    pub fn writev(&self, bufs: &[&IoVec]) -> io::Result<usize> {
+        let mut me = self.inner();
+        let me = &mut *me;
+
+        match me.write {
+            State::Empty => {}
+            _ => return Err(wouldblock())
+        }
+
+        if !me.iocp.registered() {
+            return Err(wouldblock())
+        }
+
+        if bufs.len() == 0 {
+            return Ok(0)
+        }
+
+        let len = bufs.iter().map(|b| b.len()).fold(0, |a, b| a + b);
+        let mut intermediate = me.iocp.get_buffer(len);
+        for buf in bufs {
+            intermediate.extend_from_slice(buf);
+        }
+        self.imp.schedule_write(intermediate, 0, me);
+        Ok(len)
+    }
+
+    pub fn flush(&self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
+impl StreamImp {
+    fn inner(&self) -> MutexGuard<StreamInner> {
+        self.inner.inner.lock().unwrap()
+    }
+
+    fn schedule_connect(&self, addr: &SocketAddr) -> io::Result<()> {
+        unsafe {
+            trace!("scheduling a connect");
+            try!(self.inner.socket.connect_overlapped(addr, &[], self.inner.read.as_mut_ptr()));
+        }
+        // see docs above on StreamImp.inner for rationale on forget
+        mem::forget(self.clone());
+        Ok(())
+    }
+
+    /// Schedule a read to happen on this socket, enqueuing us to receive a
+    /// notification when a read is ready.
+    ///
+    /// Note that this does *not* work with a buffer. When reading a TCP stream
+    /// we actually read into a 0-byte buffer so Windows will send us a
+    /// notification when the socket is otherwise ready for reading. This allows
+    /// us to avoid buffer allocations for in-flight reads.
+    fn schedule_read(&self, me: &mut StreamInner) {
+        match me.read {
+            State::Empty => {}
+            State::Ready(_) | State::Error(_) => {
+                self.add_readiness(me, Ready::readable());
+                return;
+            }
+            _ => return,
+        }
+
+        me.iocp.set_readiness(me.iocp.readiness() & !Ready::readable());
+
+        trace!("scheduling a read");
+        let res = unsafe {
+            self.inner.socket.read_overlapped(&mut [], self.inner.read.as_mut_ptr())
+        };
+        match res {
+            // Note that `Ok(true)` means that this completed immediately and
+            // our socket is readable. This typically means that the caller of
+            // this function (likely `read` above) can try again as an
+            // optimization and return bytes quickly.
+            //
+            // Normally, though, although the read completed immediately
+            // there's still an IOCP completion packet enqueued that we're going
+            // to receive.
+            //
+            // You can configure this behavior (miow) with
+            // SetFileCompletionNotificationModes to indicate that `Ok(true)`
+            // does **not** enqueue a completion packet. (This is the case
+            // for me.instant_notify)
+            //
+            // Note that apparently libuv has scary code to work around bugs in
+            // `WSARecv` for UDP sockets apparently for handles which have had
+            // the `SetFileCompletionNotificationModes` function called on them,
+            // worth looking into!
+            Ok(Some(_)) if me.instant_notify => {
+                me.read = State::Ready(());
+                self.add_readiness(me, Ready::readable());
+            }
+            Ok(_) => {
+                // see docs above on StreamImp.inner for rationale on forget
+                me.read = State::Pending(());
+                mem::forget(self.clone());
+            }
+            Err(e) => {
+                me.read = State::Error(e);
+                self.add_readiness(me, Ready::readable());
+            }
+        }
+    }
+
+    /// Similar to `schedule_read`, except that this issues, well, writes.
+    ///
+    /// This function will continually attempt to write the entire contents of
+    /// the buffer `buf` until they have all been written. The `pos` argument is
+    /// the current offset within the buffer up to which the contents have
+    /// already been written.
+    ///
+    /// A new writable event (e.g. allowing another write) will only happen once
+    /// the buffer has been written completely (or hit an error).
+    fn schedule_write(&self,
+                      buf: Vec<u8>,
+                      mut pos: usize,
+                      me: &mut StreamInner) {
+
+        // About to write, clear any pending level triggered events
+        me.iocp.set_readiness(me.iocp.readiness() & !Ready::writable());
+
+        trace!("scheduling a write");
+        loop {
+            let ret = unsafe {
+                self.inner.socket.write_overlapped(&buf[pos..], self.inner.write.as_mut_ptr())
+            };
+            match ret {
+                Ok(Some(transferred_bytes)) if me.instant_notify => {
+                    if transferred_bytes == buf.len() - pos {
+                        self.add_readiness(me, Ready::writable());
+                        me.write = State::Empty;
+                        break;
+                    }
+                    pos += transferred_bytes;
+                }
+                Ok(_) => {
+                    // see docs above on StreamImp.inner for rationale on forget
+                    me.write = State::Pending((buf, pos));
+                    mem::forget(self.clone());
+                    break;
+                }
+                Err(e) => {
+                    me.write = State::Error(e);
+                    self.add_readiness(me, Ready::writable());
+                    me.iocp.put_buffer(buf);
+                    break;
+                }
+            }
+        }
+    }
+
+    /// Pushes an event for this socket onto the selector its registered for.
+    ///
+    /// When an event is generated on this socket, if it happened after the
+    /// socket was closed then we don't want to actually push the event onto our
+    /// selector as otherwise it's just a spurious notification.
+    fn add_readiness(&self, me: &mut StreamInner, set: Ready) {
+        me.iocp.set_readiness(set | me.iocp.readiness());
+    }
+}
+
+fn read_done(status: &OVERLAPPED_ENTRY) {
+    let status = CompletionStatus::from_entry(status);
+    let me2 = StreamImp {
+        inner: unsafe { overlapped2arc!(status.overlapped(), StreamIo, read) },
+    };
+
+    let mut me = me2.inner();
+    match mem::replace(&mut me.read, State::Empty) {
+        State::Pending(()) => {
+            trace!("finished a read: {}", status.bytes_transferred());
+            assert_eq!(status.bytes_transferred(), 0);
+            me.read = State::Ready(());
+            return me2.add_readiness(&mut me, Ready::readable())
+        }
+        s => me.read = s,
+    }
+
+    // If a read didn't complete, then the connect must have just finished.
+    trace!("finished a connect");
+
+    // By guarding with socket.result(), we ensure that a connection
+    // was successfully made before performing operations requiring a
+    // connected socket.
+    match unsafe { me2.inner.socket.result(status.overlapped()) }
+        .and_then(|_| me2.inner.socket.connect_complete())
+    {
+        Ok(()) => {
+            me2.add_readiness(&mut me, Ready::writable());
+            me2.schedule_read(&mut me);
+        }
+        Err(e) => {
+            me2.add_readiness(&mut me, Ready::readable() | Ready::writable());
+            me.read = State::Error(e);
+        }
+    }
+}
+
+fn write_done(status: &OVERLAPPED_ENTRY) {
+    let status = CompletionStatus::from_entry(status);
+    trace!("finished a write {}", status.bytes_transferred());
+    let me2 = StreamImp {
+        inner: unsafe { overlapped2arc!(status.overlapped(), StreamIo, write) },
+    };
+    let mut me = me2.inner();
+    let (buf, pos) = match mem::replace(&mut me.write, State::Empty) {
+        State::Pending(pair) => pair,
+        _ => unreachable!(),
+    };
+    let new_pos = pos + (status.bytes_transferred() as usize);
+    if new_pos == buf.len() {
+        me2.add_readiness(&mut me, Ready::writable());
+    } else {
+        me2.schedule_write(buf, new_pos, &mut me);
+    }
+}
+
+impl Evented for TcpStream {
+    fn register(&self, poll: &Poll, token: Token,
+                interest: Ready, opts: PollOpt) -> io::Result<()> {
+        let mut me = self.inner();
+        try!(me.iocp.register_socket(&self.imp.inner.socket, poll, token,
+                                     interest, opts, &self.registration));
+
+        unsafe {
+            try!(super::no_notify_on_instant_completion(self.imp.inner.socket.as_raw_socket() as HANDLE));
+            me.instant_notify = true;
+        }
+
+        // If we were connected before being registered process that request
+        // here and go along our merry ways. Note that the callback for a
+        // successful connect will worry about generating writable/readable
+        // events and scheduling a new read.
+        if let Some(addr) = me.deferred_connect.take() {
+            return self.imp.schedule_connect(&addr).map(|_| ())
+        }
+        self.post_register(interest, &mut me);
+        Ok(())
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token,
+                  interest: Ready, opts: PollOpt) -> io::Result<()> {
+        let mut me = self.inner();
+        try!(me.iocp.reregister_socket(&self.imp.inner.socket, poll, token,
+                                       interest, opts, &self.registration));
+        self.post_register(interest, &mut me);
+        Ok(())
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        self.inner().iocp.deregister(&self.imp.inner.socket,
+                                     poll, &self.registration)
+    }
+}
+
+impl fmt::Debug for TcpStream {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        "TcpStream { ... }".fmt(f)
+    }
+}
+
+impl Drop for TcpStream {
+    fn drop(&mut self) {
+        // If we're still internally reading, we're no longer interested. Note
+        // though that we don't cancel any writes which may have been issued to
+        // preserve the same semantics as Unix.
+        //
+        // Note that "Empty" here may mean that a connect is pending, so we
+        // cancel even if that happens as well.
+        unsafe {
+            match self.inner().read {
+                State::Pending(_) | State::Empty => {
+                    trace!("cancelling active TCP read");
+                    drop(super::cancel(&self.imp.inner.socket,
+                                       &self.imp.inner.read));
+                }
+                State::Ready(_) | State::Error(_) => {}
+            }
+        }
+    }
+}
+
+impl TcpListener {
+    pub fn new(socket: net::TcpListener, addr: &SocketAddr)
+               -> io::Result<TcpListener> {
+        Ok(TcpListener::new_family(socket, match *addr {
+            SocketAddr::V4(..) => Family::V4,
+            SocketAddr::V6(..) => Family::V6,
+        }))
+    }
+
+    fn new_family(socket: net::TcpListener, family: Family) -> TcpListener {
+        TcpListener {
+            registration: Mutex::new(None),
+            imp: ListenerImp {
+                inner: FromRawArc::new(ListenerIo {
+                    accept: Overlapped::new(accept_done),
+                    family: family,
+                    socket: socket,
+                    inner: Mutex::new(ListenerInner {
+                        iocp: ReadyBinding::new(),
+                        accept: State::Empty,
+                        accept_buf: AcceptAddrsBuf::new(),
+                        instant_notify: false,
+                    }),
+                }),
+            },
+        }
+    }
+
+    pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
+        let mut me = self.inner();
+
+        let ret = match mem::replace(&mut me.accept, State::Empty) {
+            State::Empty => return Err(would_block()),
+            State::Pending(t) => {
+                me.accept = State::Pending(t);
+                return Err(would_block());
+            }
+            State::Ready((s, a)) => {
+                try!(s.set_nonblocking(true));
+                Ok((TcpStream::new(s, None), a))
+            }
+            State::Error(e) => Err(e),
+        };
+
+        self.imp.schedule_accept(&mut me);
+
+        return ret
+    }
+
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
+        self.imp.inner.socket.local_addr()
+    }
+
+    pub fn try_clone(&self) -> io::Result<TcpListener> {
+        self.imp.inner.socket.try_clone().map(|s| {
+            TcpListener::new_family(s, self.imp.inner.family)
+        })
+    }
+
+    #[allow(deprecated)]
+    pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
+        self.imp.inner.socket.set_only_v6(only_v6)
+    }
+
+    #[allow(deprecated)]
+    pub fn only_v6(&self) -> io::Result<bool> {
+        self.imp.inner.socket.only_v6()
+    }
+
+    pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
+        self.imp.inner.socket.set_ttl(ttl)
+    }
+
+    pub fn ttl(&self) -> io::Result<u32> {
+        self.imp.inner.socket.ttl()
+    }
+
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        self.imp.inner.socket.take_error()
+    }
+
+    fn inner(&self) -> MutexGuard<ListenerInner> {
+        self.imp.inner()
+    }
+}
+
+impl ListenerImp {
+    fn inner(&self) -> MutexGuard<ListenerInner> {
+        self.inner.inner.lock().unwrap()
+    }
+
+    fn schedule_accept(&self, me: &mut ListenerInner) {
+        match me.accept {
+            State::Empty => {}
+            _ => return
+        }
+
+        me.iocp.set_readiness(me.iocp.readiness() & !Ready::readable());
+
+        let res = match self.inner.family {
+            Family::V4 => TcpBuilder::new_v4(),
+            Family::V6 => TcpBuilder::new_v6(),
+        }.and_then(|builder| unsafe {
+            trace!("scheduling an accept");
+            self.inner.socket.accept_overlapped(&builder, &mut me.accept_buf,
+                                                self.inner.accept.as_mut_ptr())
+        });
+        match res {
+            Ok((socket, _)) => {
+                // see docs above on StreamImp.inner for rationale on forget
+                me.accept = State::Pending(socket);
+                mem::forget(self.clone());
+            }
+            Err(e) => {
+                me.accept = State::Error(e);
+                self.add_readiness(me, Ready::readable());
+            }
+        }
+    }
+
+    // See comments in StreamImp::push
+    fn add_readiness(&self, me: &mut ListenerInner, set: Ready) {
+        me.iocp.set_readiness(set | me.iocp.readiness());
+    }
+}
+
+fn accept_done(status: &OVERLAPPED_ENTRY) {
+    let status = CompletionStatus::from_entry(status);
+    let me2 = ListenerImp {
+        inner: unsafe { overlapped2arc!(status.overlapped(), ListenerIo, accept) },
+    };
+
+    let mut me = me2.inner();
+    let socket = match mem::replace(&mut me.accept, State::Empty) {
+        State::Pending(s) => s,
+        _ => unreachable!(),
+    };
+    trace!("finished an accept");
+    let result = me2.inner.socket.accept_complete(&socket).and_then(|()| {
+        me.accept_buf.parse(&me2.inner.socket)
+    }).and_then(|buf| {
+        buf.remote().ok_or_else(|| {
+            io::Error::new(ErrorKind::Other, "could not obtain remote address")
+        })
+    });
+    me.accept = match result {
+        Ok(remote_addr) => State::Ready((socket, remote_addr)),
+        Err(e) => State::Error(e),
+    };
+    me2.add_readiness(&mut me, Ready::readable());
+}
+
+impl Evented for TcpListener {
+    fn register(&self, poll: &Poll, token: Token,
+                interest: Ready, opts: PollOpt) -> io::Result<()> {
+        let mut me = self.inner();
+        try!(me.iocp.register_socket(&self.imp.inner.socket, poll, token,
+                                     interest, opts, &self.registration));
+
+        unsafe {
+            try!(super::no_notify_on_instant_completion(self.imp.inner.socket.as_raw_socket() as HANDLE));
+            me.instant_notify = true;
+        }
+
+        self.imp.schedule_accept(&mut me);
+        Ok(())
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token,
+                  interest: Ready, opts: PollOpt) -> io::Result<()> {
+        let mut me = self.inner();
+        try!(me.iocp.reregister_socket(&self.imp.inner.socket, poll, token,
+                                       interest, opts, &self.registration));
+        self.imp.schedule_accept(&mut me);
+        Ok(())
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        self.inner().iocp.deregister(&self.imp.inner.socket,
+                                     poll, &self.registration)
+    }
+}
+
+impl fmt::Debug for TcpListener {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        "TcpListener { ... }".fmt(f)
+    }
+}
+
+impl Drop for TcpListener {
+    fn drop(&mut self) {
+        // If we're still internally reading, we're no longer interested.
+        unsafe {
+            match self.inner().accept {
+                State::Pending(_) => {
+                    trace!("cancelling active TCP accept");
+                    drop(super::cancel(&self.imp.inner.socket,
+                                       &self.imp.inner.accept));
+                }
+                State::Empty |
+                State::Ready(_) |
+                State::Error(_) => {}
+            }
+        }
+    }
+}
+
+// TODO: Use std's allocation free io::Error
+const WOULDBLOCK: i32 = ::winapi::winerror::WSAEWOULDBLOCK as i32;
+
+/// Returns a std `WouldBlock` error without allocating
+pub fn would_block() -> ::std::io::Error {
+    ::std::io::Error::from_raw_os_error(WOULDBLOCK)
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/sys/windows/udp.rs
@@ -0,0 +1,412 @@
+//! UDP for IOCP
+//!
+//! Note that most of this module is quite similar to the TCP module, so if
+//! something seems odd you may also want to try the docs over there.
+
+use std::fmt;
+use std::io::prelude::*;
+use std::io;
+use std::mem;
+use std::net::{self, Ipv4Addr, Ipv6Addr, SocketAddr};
+use std::sync::{Mutex, MutexGuard};
+
+#[allow(unused_imports)]
+use net2::{UdpBuilder, UdpSocketExt};
+use winapi::*;
+use miow::iocp::CompletionStatus;
+use miow::net::SocketAddrBuf;
+use miow::net::UdpSocketExt as MiowUdpSocketExt;
+
+use {poll, Ready, Poll, PollOpt, Token};
+use event::Evented;
+use sys::windows::from_raw_arc::FromRawArc;
+use sys::windows::selector::{Overlapped, ReadyBinding};
+
+pub struct UdpSocket {
+    imp: Imp,
+    registration: Mutex<Option<poll::Registration>>,
+}
+
+#[derive(Clone)]
+struct Imp {
+    inner: FromRawArc<Io>,
+}
+
+struct Io {
+    read: Overlapped,
+    write: Overlapped,
+    socket: net::UdpSocket,
+    inner: Mutex<Inner>,
+}
+
+struct Inner {
+    iocp: ReadyBinding,
+    read: State<Vec<u8>, Vec<u8>>,
+    write: State<Vec<u8>, (Vec<u8>, usize)>,
+    read_buf: SocketAddrBuf,
+}
+
+enum State<T, U> {
+    Empty,
+    Pending(T),
+    Ready(U),
+    Error(io::Error),
+}
+
+impl UdpSocket {
+    pub fn new(socket: net::UdpSocket) -> io::Result<UdpSocket> {
+        Ok(UdpSocket {
+            registration: Mutex::new(None),
+            imp: Imp {
+                inner: FromRawArc::new(Io {
+                    read: Overlapped::new(recv_done),
+                    write: Overlapped::new(send_done),
+                    socket: socket,
+                    inner: Mutex::new(Inner {
+                        iocp: ReadyBinding::new(),
+                        read: State::Empty,
+                        write: State::Empty,
+                        read_buf: SocketAddrBuf::new(),
+                    }),
+                }),
+            },
+        })
+    }
+
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
+        self.imp.inner.socket.local_addr()
+    }
+
+    pub fn try_clone(&self) -> io::Result<UdpSocket> {
+        self.imp.inner.socket.try_clone().and_then(UdpSocket::new)
+    }
+
+    /// Note that unlike `TcpStream::write` this function will not attempt to
+    /// continue writing `buf` until its entirely written.
+    ///
+    /// TODO: This... may be wrong in the long run. We're reporting that we
+    ///       successfully wrote all of the bytes in `buf` but it's possible
+    ///       that we don't actually end up writing all of them!
+    pub fn send_to(&self, buf: &[u8], target: &SocketAddr)
+                   -> io::Result<usize> {
+        let mut me = self.inner();
+        let me = &mut *me;
+
+        match me.write {
+            State::Empty => {}
+            _ => return Err(would_block()),
+        }
+
+        if !me.iocp.registered() {
+            return Err(would_block())
+        }
+
+        let interest = me.iocp.readiness();
+        me.iocp.set_readiness(interest & !Ready::writable());
+
+        let mut owned_buf = me.iocp.get_buffer(64 * 1024);
+        let amt = try!(owned_buf.write(buf));
+        try!(unsafe {
+            trace!("scheduling a send");
+            self.imp.inner.socket.send_to_overlapped(&owned_buf, target,
+                                                     self.imp.inner.write.as_mut_ptr())
+        });
+        me.write = State::Pending(owned_buf);
+        mem::forget(self.imp.clone());
+        Ok(amt)
+    }
+
+    /// Note that unlike `TcpStream::write` this function will not attempt to
+    /// continue writing `buf` until its entirely written.
+    ///
+    /// TODO: This... may be wrong in the long run. We're reporting that we
+    ///       successfully wrote all of the bytes in `buf` but it's possible
+    ///       that we don't actually end up writing all of them!
+    pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
+        let mut me = self.inner();
+        let me = &mut *me;
+
+        match me.write {
+            State::Empty => {}
+            _ => return Err(would_block()),
+        }
+
+        if !me.iocp.registered() {
+            return Err(would_block())
+        }
+
+        let interest = me.iocp.readiness();
+        me.iocp.set_readiness(interest & !Ready::writable());
+
+        let mut owned_buf = me.iocp.get_buffer(64 * 1024);
+        let amt = try!(owned_buf.write(buf));
+        try!(unsafe {
+            trace!("scheduling a send");
+            self.imp.inner.socket.send_overlapped(&owned_buf, self.imp.inner.write.as_mut_ptr())
+
+        });
+        me.write = State::Pending(owned_buf);
+        mem::forget(self.imp.clone());
+        Ok(amt)
+    }
+
+    pub fn recv_from(&self, mut buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
+        let mut me = self.inner();
+        match mem::replace(&mut me.read, State::Empty) {
+            State::Empty => Err(would_block()),
+            State::Pending(b) => { me.read = State::Pending(b); Err(would_block()) }
+            State::Ready(data) => {
+                // If we weren't provided enough space to receive the message
+                // then don't actually read any data, just return an error.
+                if buf.len() < data.len() {
+                    me.read = State::Ready(data);
+                    Err(io::Error::from_raw_os_error(WSAEMSGSIZE as i32))
+                } else {
+                    let r = if let Some(addr) = me.read_buf.to_socket_addr() {
+                        buf.write(&data).unwrap();
+                        Ok((data.len(), addr))
+                    } else {
+                        Err(io::Error::new(io::ErrorKind::Other,
+                                           "failed to parse socket address"))
+                    };
+                    me.iocp.put_buffer(data);
+                    self.imp.schedule_read_from(&mut me);
+                    r
+                }
+            }
+            State::Error(e) => {
+                self.imp.schedule_read_from(&mut me);
+                Err(e)
+            }
+        }
+    }
+
+    pub fn recv(&self, mut buf: &mut [u8])
+                     -> io::Result<usize> {
+        //Since recv_from can be used on connected sockets just call it and drop the address.
+        self.recv_from(buf).map(|(size,_)| size)
+    }
+
+    pub fn connect(&self, addr: SocketAddr) -> io::Result<()> {
+        self.imp.inner.socket.connect(addr)
+    }
+
+    pub fn broadcast(&self) -> io::Result<bool> {
+        self.imp.inner.socket.broadcast()
+    }
+
+    pub fn set_broadcast(&self, on: bool) -> io::Result<()> {
+        self.imp.inner.socket.set_broadcast(on)
+    }
+
+    pub fn multicast_loop_v4(&self) -> io::Result<bool> {
+        self.imp.inner.socket.multicast_loop_v4()
+    }
+
+    pub fn set_multicast_loop_v4(&self, on: bool) -> io::Result<()> {
+        self.imp.inner.socket.set_multicast_loop_v4(on)
+    }
+
+    pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
+        self.imp.inner.socket.multicast_ttl_v4()
+    }
+
+    pub fn set_multicast_ttl_v4(&self, ttl: u32) -> io::Result<()> {
+        self.imp.inner.socket.set_multicast_ttl_v4(ttl)
+    }
+
+    pub fn multicast_loop_v6(&self) -> io::Result<bool> {
+        self.imp.inner.socket.multicast_loop_v6()
+    }
+
+    pub fn set_multicast_loop_v6(&self, on: bool) -> io::Result<()> {
+        self.imp.inner.socket.set_multicast_loop_v6(on)
+    }
+
+    pub fn ttl(&self) -> io::Result<u32> {
+        self.imp.inner.socket.ttl()
+    }
+
+    pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
+        self.imp.inner.socket.set_ttl(ttl)
+    }
+
+    pub fn join_multicast_v4(&self,
+                             multiaddr: &Ipv4Addr,
+                             interface: &Ipv4Addr) -> io::Result<()> {
+        self.imp.inner.socket.join_multicast_v4(multiaddr, interface)
+    }
+
+    pub fn join_multicast_v6(&self,
+                             multiaddr: &Ipv6Addr,
+                             interface: u32) -> io::Result<()> {
+        self.imp.inner.socket.join_multicast_v6(multiaddr, interface)
+    }
+
+    pub fn leave_multicast_v4(&self,
+                              multiaddr: &Ipv4Addr,
+                              interface: &Ipv4Addr) -> io::Result<()> {
+        self.imp.inner.socket.leave_multicast_v4(multiaddr, interface)
+    }
+
+    pub fn leave_multicast_v6(&self,
+                              multiaddr: &Ipv6Addr,
+                              interface: u32) -> io::Result<()> {
+        self.imp.inner.socket.leave_multicast_v6(multiaddr, interface)
+    }
+
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        self.imp.inner.socket.take_error()
+    }
+
+    fn inner(&self) -> MutexGuard<Inner> {
+        self.imp.inner()
+    }
+
+    fn post_register(&self, interest: Ready, me: &mut Inner) {
+        if interest.is_readable() {
+            //We use recv_from here since it is well specified for both
+            //connected and non-connected sockets and we can discard the address
+            //when calling recv().
+            self.imp.schedule_read_from(me);
+        }
+        // See comments in TcpSocket::post_register for what's going on here
+        if interest.is_writable() {
+            if let State::Empty = me.write {
+                self.imp.add_readiness(me, Ready::writable());
+            }
+        }
+    }
+}
+
+impl Imp {
+    fn inner(&self) -> MutexGuard<Inner> {
+        self.inner.inner.lock().unwrap()
+    }
+
+    fn schedule_read_from(&self, me: &mut Inner) {
+        match me.read {
+            State::Empty => {}
+            _ => return,
+        }
+
+        let interest = me.iocp.readiness();
+        me.iocp.set_readiness(interest & !Ready::readable());
+
+        let mut buf = me.iocp.get_buffer(64 * 1024);
+        let res = unsafe {
+            trace!("scheduling a read");
+            let cap = buf.capacity();
+            buf.set_len(cap);
+            self.inner.socket.recv_from_overlapped(&mut buf, &mut me.read_buf,
+                                                   self.inner.read.as_mut_ptr())
+        };
+        match res {
+            Ok(_) => {
+                me.read = State::Pending(buf);
+                mem::forget(self.clone());
+            }
+            Err(e) => {
+                me.read = State::Error(e);
+                self.add_readiness(me, Ready::readable());
+                me.iocp.put_buffer(buf);
+            }
+        }
+    }
+
+    // See comments in tcp::StreamImp::push
+    fn add_readiness(&self, me: &Inner, set: Ready) {
+        me.iocp.set_readiness(set | me.iocp.readiness());
+    }
+}
+
+impl Evented for UdpSocket {
+    fn register(&self, poll: &Poll, token: Token,
+                interest: Ready, opts: PollOpt) -> io::Result<()> {
+        let mut me = self.inner();
+        try!(me.iocp.register_socket(&self.imp.inner.socket,
+                                     poll, token, interest, opts,
+                                     &self.registration));
+        self.post_register(interest, &mut me);
+        Ok(())
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token,
+                  interest: Ready, opts: PollOpt) -> io::Result<()> {
+        let mut me = self.inner();
+        try!(me.iocp.reregister_socket(&self.imp.inner.socket,
+                                       poll, token, interest,
+                                       opts, &self.registration));
+        self.post_register(interest, &mut me);
+        Ok(())
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        self.inner().iocp.deregister(&self.imp.inner.socket,
+                                     poll, &self.registration)
+    }
+}
+
+impl fmt::Debug for UdpSocket {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        "UdpSocket { ... }".fmt(f)
+    }
+}
+
+impl Drop for UdpSocket {
+    fn drop(&mut self) {
+        let inner = self.inner();
+
+        // If we're still internally reading, we're no longer interested. Note
+        // though that we don't cancel any writes which may have been issued to
+        // preserve the same semantics as Unix.
+        unsafe {
+            match inner.read {
+                State::Pending(_) => {
+                    drop(super::cancel(&self.imp.inner.socket,
+                                       &self.imp.inner.read));
+                }
+                State::Empty |
+                State::Ready(_) |
+                State::Error(_) => {}
+            }
+        }
+    }
+}
+
+fn send_done(status: &OVERLAPPED_ENTRY) {
+    let status = CompletionStatus::from_entry(status);
+    trace!("finished a send {}", status.bytes_transferred());
+    let me2 = Imp {
+        inner: unsafe { overlapped2arc!(status.overlapped(), Io, write) },
+    };
+    let mut me = me2.inner();
+    me.write = State::Empty;
+    me2.add_readiness(&mut me, Ready::writable());
+}
+
+fn recv_done(status: &OVERLAPPED_ENTRY) {
+    let status = CompletionStatus::from_entry(status);
+    trace!("finished a recv {}", status.bytes_transferred());
+    let me2 = Imp {
+        inner: unsafe { overlapped2arc!(status.overlapped(), Io, read) },
+    };
+    let mut me = me2.inner();
+    let mut buf = match mem::replace(&mut me.read, State::Empty) {
+        State::Pending(buf) => buf,
+        _ => unreachable!(),
+    };
+    unsafe {
+        buf.set_len(status.bytes_transferred() as usize);
+    }
+    me.read = State::Ready(buf);
+    me2.add_readiness(&mut me, Ready::readable());
+}
+
+// TODO: Use std's allocation free io::Error
+const WOULDBLOCK: i32 = ::winapi::winerror::WSAEWOULDBLOCK as i32;
+
+/// Returns a std `WouldBlock` error without allocating
+pub fn would_block() -> ::std::io::Error {
+    ::std::io::Error::from_raw_os_error(WOULDBLOCK)
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/timer.rs
@@ -0,0 +1,526 @@
+//! Timer optimized for I/O related operations
+
+#![allow(deprecated, missing_debug_implementations)]
+
+use {convert, io, Evented, Ready, Poll, PollOpt, Registration, SetReadiness, Token};
+use lazycell::LazyCell;
+use std::{cmp, error, fmt, u64, usize, iter, thread};
+use std::sync::Arc;
+use std::sync::atomic::{AtomicUsize, Ordering};
+use std::time::{Duration, Instant};
+
+use self::TimerErrorKind::TimerOverflow;
+
+pub struct Timer<T> {
+    // Size of each tick in milliseconds
+    tick_ms: u64,
+    // Slab of timeout entries
+    entries: Slab<Entry<T>>,
+    // Timeout wheel. Each tick, the timer will look at the next slot for
+    // timeouts that match the current tick.
+    wheel: Vec<WheelEntry>,
+    // Tick 0's time instant
+    start: Instant,
+    // The current tick
+    tick: Tick,
+    // The next entry to possibly timeout
+    next: Token,
+    // Masks the target tick to get the slot
+    mask: u64,
+    // Set on registration with Poll
+    inner: LazyCell<Inner>,
+}
+
+pub struct Builder {
+    // Approximate duration of each tick
+    tick: Duration,
+    // Number of slots in the timer wheel
+    num_slots: usize,
+    // Max number of timeouts that can be in flight at a given time.
+    capacity: usize,
+}
+
+#[derive(Clone, Debug)]
+pub struct Timeout {
+    // Reference into the timer entry slab
+    token: Token,
+    // Tick that it should match up with
+    tick: u64,
+}
+
+struct Inner {
+    registration: Registration,
+    set_readiness: SetReadiness,
+    wakeup_state: WakeupState,
+    wakeup_thread: thread::JoinHandle<()>,
+}
+
+impl Drop for Inner {
+    fn drop(&mut self) {
+        // 1. Set wakeup state to TERMINATE_THREAD (https://github.com/carllerche/mio/blob/master/src/timer.rs#L451)
+        self.wakeup_state.store(TERMINATE_THREAD, Ordering::Release);
+        // 2. Wake him up
+        self.wakeup_thread.thread().unpark();
+    }
+}
+
+#[derive(Copy, Clone, Debug)]
+struct WheelEntry {
+    next_tick: Tick,
+    head: Token,
+}
+
+// Doubly linked list of timer entries. Allows for efficient insertion /
+// removal of timeouts.
+struct Entry<T> {
+    state: T,
+    links: EntryLinks,
+}
+
+#[derive(Copy, Clone)]
+struct EntryLinks {
+    tick: Tick,
+    prev: Token,
+    next: Token
+}
+
+type Tick = u64;
+
+const TICK_MAX: Tick = u64::MAX;
+
+// Manages communication with wakeup thread
+type WakeupState = Arc<AtomicUsize>;
+
+type Slab<T> = ::slab::Slab<T, ::Token>;
+
+pub type Result<T> = ::std::result::Result<T, TimerError>;
+// TODO: remove
+pub type TimerResult<T> = Result<T>;
+
+
+#[derive(Debug)]
+pub struct TimerError {
+    kind: TimerErrorKind,
+    desc: &'static str,
+}
+
+#[derive(Debug)]
+pub enum TimerErrorKind {
+    TimerOverflow,
+}
+
+// TODO: Remove
+pub type OldTimerResult<T> = Result<T>;
+
+const TERMINATE_THREAD: usize = 0;
+const EMPTY: Token = Token(usize::MAX);
+
+impl Builder {
+    pub fn tick_duration(mut self, duration: Duration) -> Builder {
+        self.tick = duration;
+        self
+    }
+
+    pub fn num_slots(mut self, num_slots: usize) -> Builder {
+        self.num_slots = num_slots;
+        self
+    }
+
+    pub fn capacity(mut self, capacity: usize) -> Builder {
+        self.capacity = capacity;
+        self
+    }
+
+    pub fn build<T>(self) -> Timer<T> {
+        Timer::new(convert::millis(self.tick), self.num_slots, self.capacity, Instant::now())
+    }
+}
+
+impl Default for Builder {
+    fn default() -> Builder {
+        Builder {
+            tick: Duration::from_millis(100),
+            num_slots: 256,
+            capacity: 65_536,
+        }
+    }
+}
+
+impl<T> Timer<T> {
+    fn new(tick_ms: u64, num_slots: usize, capacity: usize, start: Instant) -> Timer<T> {
+        let num_slots = num_slots.next_power_of_two();
+        let capacity = capacity.next_power_of_two();
+        let mask = (num_slots as u64) - 1;
+        let wheel = iter::repeat(WheelEntry { next_tick: TICK_MAX, head: EMPTY })
+            .take(num_slots).collect();
+
+        Timer {
+            tick_ms: tick_ms,
+            entries: Slab::with_capacity(capacity),
+            wheel: wheel,
+            start: start,
+            tick: 0,
+            next: EMPTY,
+            mask: mask,
+            inner: LazyCell::new(),
+        }
+    }
+
+    pub fn set_timeout(&mut self, delay_from_now: Duration, state: T) -> Result<Timeout> {
+        let delay_from_start = self.start.elapsed() + delay_from_now;
+        self.set_timeout_at(delay_from_start, state)
+    }
+
+    fn set_timeout_at(&mut self, delay_from_start: Duration, state: T) -> Result<Timeout> {
+        let mut tick = duration_to_tick(delay_from_start, self.tick_ms);
+        trace!("setting timeout; delay={:?}; tick={:?}; current-tick={:?}", delay_from_start, tick, self.tick);
+
+        // Always target at least 1 tick in the future
+        if tick <= self.tick {
+            tick = self.tick + 1;
+        }
+
+        self.insert(tick, state)
+    }
+
+    fn insert(&mut self, tick: Tick, state: T) -> Result<Timeout> {
+        // Get the slot for the requested tick
+        let slot = (tick & self.mask) as usize;
+        let curr = self.wheel[slot];
+
+        // Insert the new entry
+        let token = try!(
+            self.entries.insert(Entry::new(state, tick, curr.head))
+            .map_err(|_| TimerError::overflow()));
+
+        if curr.head != EMPTY {
+            // If there was a previous entry, set its prev pointer to the new
+            // entry
+            self.entries[curr.head].links.prev = token;
+        }
+
+        // Update the head slot
+        self.wheel[slot] = WheelEntry {
+            next_tick: cmp::min(tick, curr.next_tick),
+            head: token,
+        };
+
+        self.schedule_readiness(tick);
+
+        trace!("inserted timout; slot={}; token={:?}", slot, token);
+
+        // Return the new timeout
+        Ok(Timeout {
+            token: token,
+            tick: tick
+        })
+    }
+
+    pub fn cancel_timeout(&mut self, timeout: &Timeout) -> Option<T> {
+        let links = match self.entries.get(timeout.token) {
+            Some(e) => e.links,
+            None => return None
+        };
+
+        // Sanity check
+        if links.tick != timeout.tick {
+            return None;
+        }
+
+        self.unlink(&links, timeout.token);
+        self.entries.remove(timeout.token).map(|e| e.state)
+    }
+
+    pub fn poll(&mut self) -> Option<T> {
+        let target_tick = current_tick(self.start, self.tick_ms);
+        self.poll_to(target_tick)
+    }
+
+    fn poll_to(&mut self, mut target_tick: Tick) -> Option<T> {
+        trace!("tick_to; target_tick={}; current_tick={}", target_tick, self.tick);
+
+        if target_tick < self.tick {
+            target_tick = self.tick;
+        }
+
+        while self.tick <= target_tick {
+            let curr = self.next;
+
+            trace!("ticking; curr={:?}", curr);
+
+            if curr == EMPTY {
+                self.tick += 1;
+
+                let slot = self.slot_for(self.tick);
+                self.next = self.wheel[slot].head;
+
+                // Handle the case when a slot has a single timeout which gets
+                // canceled before the timeout expires. In this case, the
+                // slot's head is EMPTY but there is a value for next_tick. Not
+                // resetting next_tick here causes the timer to get stuck in a
+                // loop.
+                if self.next == EMPTY {
+                    self.wheel[slot].next_tick = TICK_MAX;
+                }
+            } else {
+                let slot = self.slot_for(self.tick);
+
+                if curr == self.wheel[slot].head {
+                    self.wheel[slot].next_tick = TICK_MAX;
+                }
+
+                let links = self.entries[curr].links;
+
+                if links.tick <= self.tick {
+                    trace!("triggering; token={:?}", curr);
+
+                    // Unlink will also advance self.next
+                    self.unlink(&links, curr);
+
+                    // Remove and return the token
+                    return self.entries.remove(curr)
+                        .map(|e| e.state);
+                } else {
+                    let next_tick = self.wheel[slot].next_tick;
+                    self.wheel[slot].next_tick = cmp::min(next_tick, links.tick);
+                    self.next = links.next;
+                }
+            }
+        }
+
+        // No more timeouts to poll
+        if let Some(inner) = self.inner.borrow() {
+            trace!("unsetting readiness");
+            let _ = inner.set_readiness.set_readiness(Ready::empty());
+
+            if let Some(tick) = self.next_tick() {
+                self.schedule_readiness(tick);
+            }
+        }
+
+        None
+    }
+
+    fn unlink(&mut self, links: &EntryLinks, token: Token) {
+       trace!("unlinking timeout; slot={}; token={:?}",
+               self.slot_for(links.tick), token);
+
+        if links.prev == EMPTY {
+            let slot = self.slot_for(links.tick);
+            self.wheel[slot].head = links.next;
+        } else {
+            self.entries[links.prev].links.next = links.next;
+        }
+
+        if links.next != EMPTY {
+            self.entries[links.next].links.prev = links.prev;
+
+            if token == self.next {
+                self.next = links.next;
+            }
+        } else if token == self.next {
+            self.next = EMPTY;
+        }
+    }
+
+    fn schedule_readiness(&self, tick: Tick) {
+        if let Some(inner) = self.inner.borrow() {
+            // Coordinate setting readiness w/ the wakeup thread
+            let mut curr = inner.wakeup_state.load(Ordering::Acquire);
+
+            loop {
+                if curr as Tick <= tick {
+                    // Nothing to do, wakeup is already scheduled
+                    return;
+                }
+
+                // Attempt to move the wakeup time forward
+                trace!("advancing the wakeup time; target={}; curr={}", tick, curr);
+                let actual = inner.wakeup_state.compare_and_swap(curr, tick as usize, Ordering::Release);
+
+                if actual == curr {
+                    // Signal to the wakeup thread that the wakeup time has
+                    // been changed.
+                    trace!("unparking wakeup thread");
+                    inner.wakeup_thread.thread().unpark();
+                    return;
+                }
+
+                curr = actual;
+            }
+        }
+    }
+
+    // Next tick containing a timeout
+    fn next_tick(&self) -> Option<Tick> {
+        if self.next != EMPTY {
+            let slot = self.slot_for(self.entries[self.next].links.tick);
+
+            if self.wheel[slot].next_tick == self.tick {
+                // There is data ready right now
+                return Some(self.tick);
+            }
+        }
+
+        self.wheel.iter().map(|e| e.next_tick).min()
+    }
+
+    fn slot_for(&self, tick: Tick) -> usize {
+        (self.mask & tick) as usize
+    }
+}
+
+impl<T> Default for Timer<T> {
+    fn default() -> Timer<T> {
+        Builder::default().build()
+    }
+}
+
+impl<T> Evented for Timer<T> {
+    fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        if self.inner.borrow().is_some() {
+            return Err(io::Error::new(io::ErrorKind::Other, "timer already registered"));
+        }
+
+        let (registration, set_readiness) = Registration::new(poll, token, interest, opts);
+        let wakeup_state = Arc::new(AtomicUsize::new(usize::MAX));
+        let thread_handle = spawn_wakeup_thread(
+            wakeup_state.clone(),
+            set_readiness.clone(),
+            self.start, self.tick_ms);
+
+        self.inner.fill(Inner {
+            registration: registration,
+            set_readiness: set_readiness,
+            wakeup_state: wakeup_state,
+            wakeup_thread: thread_handle,
+        }).ok().expect("timer already registered");
+
+        if let Some(next_tick) = self.next_tick() {
+            self.schedule_readiness(next_tick);
+        }
+
+        Ok(())
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        match self.inner.borrow() {
+            Some(inner) => inner.registration.update(poll, token, interest, opts),
+            None => Err(io::Error::new(io::ErrorKind::Other, "receiver not registered")),
+        }
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        match self.inner.borrow() {
+            Some(inner) => inner.registration.deregister(poll),
+            None => Err(io::Error::new(io::ErrorKind::Other, "receiver not registered")),
+        }
+    }
+}
+
+impl fmt::Debug for Inner {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        fmt.debug_struct("Inner")
+            .field("registration", &self.registration)
+            .field("wakeup_state", &self.wakeup_state.load(Ordering::Relaxed))
+            .finish()
+    }
+}
+
+fn spawn_wakeup_thread(state: WakeupState, set_readiness: SetReadiness, start: Instant, tick_ms: u64) -> thread::JoinHandle<()> {
+    thread::spawn(move || {
+        let mut sleep_until_tick = state.load(Ordering::Acquire) as Tick;
+
+        loop {
+            if sleep_until_tick == TERMINATE_THREAD as Tick {
+                return;
+            }
+
+            let now_tick = current_tick(start, tick_ms);
+
+            trace!("wakeup thread: sleep_until_tick={:?}; now_tick={:?}", sleep_until_tick, now_tick);
+
+            if now_tick < sleep_until_tick {
+                // Calling park_timeout with u64::MAX leads to undefined
+                // behavior in pthread, causing the park to return immediately
+                // and causing the thread to tightly spin. Instead of u64::MAX
+                // on large values, simply use a blocking park.
+                match tick_ms.checked_mul(sleep_until_tick - now_tick) {
+                    Some(sleep_duration) => {
+                        trace!("sleeping; tick_ms={}; now_tick={}; sleep_until_tick={}; duration={:?}",
+                               tick_ms, now_tick, sleep_until_tick, sleep_duration);
+                        thread::park_timeout(Duration::from_millis(sleep_duration));
+                    }
+                    None => {
+                        trace!("sleeping; tick_ms={}; now_tick={}; blocking sleep",
+                               tick_ms, now_tick);
+                        thread::park();
+                    }
+                }
+                sleep_until_tick = state.load(Ordering::Acquire) as Tick;
+            } else {
+                let actual = state.compare_and_swap(sleep_until_tick as usize, usize::MAX, Ordering::AcqRel) as Tick;
+
+                if actual == sleep_until_tick {
+                    trace!("setting readiness from wakeup thread");
+                    let _ = set_readiness.set_readiness(Ready::readable());
+                    sleep_until_tick = usize::MAX as Tick;
+                } else {
+                    sleep_until_tick = actual as Tick;
+                }
+            }
+        }
+    })
+}
+
+fn duration_to_tick(elapsed: Duration, tick_ms: u64) -> Tick {
+    // Calculate tick rounding up to the closest one
+    let elapsed_ms = convert::millis(elapsed);
+    elapsed_ms.saturating_add(tick_ms / 2) / tick_ms
+}
+
+fn current_tick(start: Instant, tick_ms: u64) -> Tick {
+    duration_to_tick(start.elapsed(), tick_ms)
+}
+
+impl<T> Entry<T> {
+    fn new(state: T, tick: u64, next: Token) -> Entry<T> {
+        Entry {
+            state: state,
+            links: EntryLinks {
+                tick: tick,
+                prev: EMPTY,
+                next: next,
+            },
+        }
+    }
+}
+
+impl fmt::Display for TimerError {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        write!(fmt, "{}: {}", self.kind, self.desc)
+    }
+}
+
+impl TimerError {
+    fn overflow() -> TimerError {
+        TimerError {
+            kind: TimerOverflow,
+            desc: "too many timer entries"
+        }
+    }
+}
+
+impl error::Error for TimerError {
+    fn description(&self) -> &str {
+        self.desc
+    }
+}
+
+impl fmt::Display for TimerErrorKind {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            TimerOverflow => write!(fmt, "TimerOverflow"),
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/token.rs
@@ -0,0 +1,145 @@
+/// Associates readiness notifications with [`Evented`] handles.
+///
+/// `Token` is a wrapper around `usize` and is used as an argument to
+/// [`Poll::register`] and [`Poll::reregister`].
+///
+/// See [`Poll`] for more documentation on polling.
+///
+/// # Example
+///
+/// Using `Token` to track which socket generated the notification. In this
+/// example, `HashMap` is used, but usually something like [`slab`] is better.
+///
+/// ```
+/// use mio::{Events, Ready, Poll, PollOpt, Token};
+/// use mio::tcp::TcpListener;
+///
+/// use std::thread;
+/// use std::io::{self, Read};
+/// use std::collections::HashMap;
+///
+/// // After this number of sockets is accepted, the server will shutdown.
+/// const MAX_SOCKETS: usize = 32;
+///
+/// // Pick a token that will not be used by any other socket and use that one
+/// // for the listener.
+/// const LISTENER: Token = Token(1024);
+///
+/// // Used to store the sockets.
+/// let mut sockets = HashMap::new();
+///
+/// // This is used to generate a unique token for a socket
+/// let mut next_socket_index = 0;
+///
+/// // The `Poll` instance
+/// let poll = Poll::new().unwrap();
+///
+/// // Tcp listener
+/// let listener = TcpListener::bind(&"127.0.0.1:0".parse().unwrap()).unwrap();
+///
+/// // Register the listener
+/// poll.register(&listener,
+///               LISTENER,
+///               Ready::readable(),
+///               PollOpt::edge()).unwrap();
+///
+/// // Spawn a thread that will connect a bunch of sockets then close them
+/// let addr = listener.local_addr().unwrap();
+/// thread::spawn(move || {
+///     use std::net::TcpStream;
+///
+///     // +1 here is to connect an extra socket to signal the socket to close
+///     for _ in 0..(MAX_SOCKETS+1) {
+///         // Connect then drop the socket
+///         let _ = TcpStream::connect(&addr).unwrap();
+///     }
+/// });
+///
+/// // Event storage
+/// let mut events = Events::with_capacity(1024);
+///
+/// // Read buffer, this will never actually get filled
+/// let mut buf = [0; 256];
+///
+/// // The main event loop
+/// loop {
+///     // Wait for events
+///     poll.poll(&mut events, None).unwrap();
+///
+///     for event in &events {
+///         match event.token() {
+///             LISTENER => {
+///                 // Perform operations in a loop until `WouldBlock` is
+///                 // encountered.
+///                 loop {
+///                     match listener.accept() {
+///                         Ok((socket, _)) => {
+///                             // Shutdown the server
+///                             if next_socket_index == MAX_SOCKETS {
+///                                 return;
+///                             }
+///
+///                             // Get the token for the socket
+///                             let token = Token(next_socket_index);
+///                             next_socket_index += 1;
+///
+///                             // Register the new socket w/ poll
+///                             poll.register(&socket,
+///                                          token,
+///                                          Ready::readable(),
+///                                          PollOpt::edge()).unwrap();
+///
+///                             // Store the socket
+///                             sockets.insert(token, socket);
+///                         }
+///                         Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+///                             // Socket is not ready anymore, stop accepting
+///                             break;
+///                         }
+///                         e => panic!("err={:?}", e), // Unexpected error
+///                     }
+///                 }
+///             }
+///             token => {
+///                 // Always operate in a loop
+///                 loop {
+///                     match sockets.get_mut(&token).unwrap().read(&mut buf) {
+///                         Ok(0) => {
+///                             // Socket is closed, remove it from the map
+///                             sockets.remove(&token);
+///                             break;
+///                         }
+///                         // Data is not actually sent in this example
+///                         Ok(_) => unreachable!(),
+///                         Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+///                             // Socket is not ready anymore, stop reading
+///                             continue;
+///                         }
+///                         e => panic!("err={:?}", e), // Unexpected error
+///                     }
+///                 }
+///             }
+///         }
+///     }
+/// }
+/// ```
+///
+/// [`Evented`]: event/trait.Evented.html
+/// [`Poll`]: struct.Poll.html
+/// [`Poll::register`]: struct.Poll.html#method.register
+/// [`Poll::reregister`]: struct.Poll.html#method.reregister
+/// [`slab`]: https://crates.io/crates/slab
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct Token(pub usize);
+
+impl From<usize> for Token {
+    fn from(val: usize) -> Token {
+        Token(val)
+    }
+}
+
+impl From<Token> for usize {
+    fn from(val: Token) -> usize {
+        val.0
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/mio/src/udp.rs
@@ -0,0 +1,311 @@
+//! Primitives for working with UDP
+//!
+//! The types provided in this module are non-blocking by default and are
+//! designed to be portable across all supported Mio platforms. As long as the
+//! [portability guidelines] are followed, the behavior should be identical no
+//! matter the target platform.
+//!
+//! [portability guidelines]: ../struct.Poll.html#portability
+
+#![allow(deprecated)]
+
+use {sys, Ready, Poll, PollOpt, Token};
+use io::{self, MapNonBlock};
+use event::Evented;
+use poll::SelectorId;
+use std::net::{self, Ipv4Addr, Ipv6Addr, SocketAddr};
+
+/// A User Datagram Protocol socket.
+///
+/// This is an implementation of a bound UDP socket. This supports both IPv4 and
+/// IPv6 addresses, and there is no corresponding notion of a server because UDP
+/// is a datagram protocol.
+#[derive(Debug)]
+pub struct UdpSocket {
+    sys: sys::UdpSocket,
+    selector_id: SelectorId,
+}
+
+impl UdpSocket {
+    /// Creates a UDP socket from the given address.
+    pub fn bind(addr: &SocketAddr) -> io::Result<UdpSocket> {
+        let socket = try!(net::UdpSocket::bind(addr));
+        UdpSocket::from_socket(socket)
+    }
+
+    /// Creates a new mio-wrapped socket from an underlying and bound std
+    /// socket.
+    ///
+    /// This function requires that `socket` has previously been bound to an
+    /// address to work correctly, and returns an I/O object which can be used
+    /// with mio to send/receive UDP messages.
+    ///
+    /// This can be used in conjunction with net2's `UdpBuilder` interface to
+    /// configure a socket before it's handed off to mio, such as setting
+    /// options like `reuse_address` or binding to multiple addresses.
+    pub fn from_socket(socket: net::UdpSocket) -> io::Result<UdpSocket> {
+        Ok(UdpSocket {
+            sys: try!(sys::UdpSocket::new(socket)),
+            selector_id: SelectorId::new(),
+        })
+    }
+
+    /// Returns the socket address that this socket was created from.
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
+        self.sys.local_addr()
+    }
+
+    /// Creates a new independently owned handle to the underlying socket.
+    ///
+    /// The returned `UdpSocket` is a reference to the same socket that this
+    /// object references. Both handles will read and write the same port, and
+    /// options set on one socket will be propagated to the other.
+    pub fn try_clone(&self) -> io::Result<UdpSocket> {
+        self.sys.try_clone()
+            .map(|s| {
+                UdpSocket {
+                    sys: s,
+                    selector_id: self.selector_id.clone(),
+                }
+            })
+    }
+
+    /// Sends data on the socket to the given address. On success, returns the
+    /// number of bytes written.
+    ///
+    /// Address type can be any implementor of `ToSocketAddrs` trait. See its
+    /// documentation for concrete examples.
+    pub fn send_to(&self, buf: &[u8], target: &SocketAddr)
+                   -> io::Result<Option<usize>> {
+        self.sys.send_to(buf, target).map_non_block()
+    }
+
+    /// Receives data from the socket. On success, returns the number of bytes
+    /// read and the address from whence the data came.
+    pub fn recv_from(&self, buf: &mut [u8])
+                     -> io::Result<Option<(usize, SocketAddr)>> {
+        self.sys.recv_from(buf).map_non_block()
+    }
+
+    /// Sends data on the socket to the address previously bound via connect(). On success,
+    /// returns the number of bytes written.
+    ///
+    /// Address type can be any implementor of `ToSocketAddrs` trait. See its
+    /// documentation for concrete examples.
+    pub fn send(&self, buf: &[u8])
+                   -> io::Result<Option<usize>> {
+        self.sys.send(buf).map_non_block()
+    }
+
+    /// Receives data from the socket previously bound with connect(). On success, returns
+    /// the number of bytes read and the address from whence the data came.
+    pub fn recv(&self, buf: &mut [u8])
+                     -> io::Result<Option<usize>> {
+        self.sys.recv(buf).map_non_block()
+    }
+
+    /// Connects the UDP socket setting the default destination for `send()` 
+    /// and limiting packets that are read via `recv` from the address specified
+    /// in `addr`.
+    pub fn connect(&self, addr: SocketAddr)
+                 -> io::Result<()> {
+        self.sys.connect(addr)
+    }
+
+    /// Gets the value of the `SO_BROADCAST` option for this socket.
+    ///
+    /// For more information about this option, see
+    /// [`set_broadcast`][link].
+    ///
+    /// [link]: #method.set_broadcast
+    pub fn broadcast(&self) -> io::Result<bool> {
+        self.sys.broadcast()
+    }
+
+    /// Sets the value of the `SO_BROADCAST` option for this socket.
+    ///
+    /// When enabled, this socket is allowed to send packets to a broadcast
+    /// address.
+    pub fn set_broadcast(&self, on: bool) -> io::Result<()> {
+        self.sys.set_broadcast(on)
+    }
+
+    /// Gets the value of the `IP_MULTICAST_LOOP` option for this socket.
+    ///
+    /// For more information about this option, see
+    /// [`set_multicast_loop_v4`][link].
+    ///
+    /// [link]: #method.set_multicast_loop_v4
+    pub fn multicast_loop_v4(&self) -> io::Result<bool> {
+        self.sys.multicast_loop_v4()
+    }
+
+    /// Sets the value of the `IP_MULTICAST_LOOP` option for this socket.
+    ///
+    /// If enabled, multicast packets will be looped back to the local socket.
+    /// Note that this may not have any affect on IPv6 sockets.
+    pub fn set_multicast_loop_v4(&self, on: bool) -> io::Result<()> {
+        self.sys.set_multicast_loop_v4(on)
+    }
+
+    /// Gets the value of the `IP_MULTICAST_TTL` option for this socket.
+    ///
+    /// For more information about this option, see
+    /// [`set_multicast_ttl_v4`][link].
+    ///
+    /// [link]: #method.set_multicast_ttl_v4
+    pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
+        self.sys.multicast_ttl_v4()
+    }
+
+    /// Sets the value of the `IP_MULTICAST_TTL` option for this socket.
+    ///
+    /// Indicates the time-to-live value of outgoing multicast packets for
+    /// this socket. The default value is 1 which means that multicast packets
+    /// don't leave the local network unless explicitly requested.
+    ///
+    /// Note that this may not have any affect on IPv6 sockets.
+    pub fn set_multicast_ttl_v4(&self, ttl: u32) -> io::Result<()> {
+        self.sys.set_multicast_ttl_v4(ttl)
+    }
+
+    /// Gets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
+    ///
+    /// For more information about this option, see
+    /// [`set_multicast_loop_v6`][link].
+    ///
+    /// [link]: #method.set_multicast_loop_v6
+    pub fn multicast_loop_v6(&self) -> io::Result<bool> {
+        self.sys.multicast_loop_v6()
+    }
+
+    /// Sets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
+    ///
+    /// Controls whether this socket sees the multicast packets it sends itself.
+    /// Note that this may not have any affect on IPv4 sockets.
+    pub fn set_multicast_loop_v6(&self, on: bool) -> io::Result<()> {
+        self.sys.set_multicast_loop_v6(on)
+    }
+
+    /// Gets the value of the `IP_TTL` option for this socket.
+    ///
+    /// For more information about this option, see [`set_ttl`][link].
+    ///
+    /// [link]: #method.set_ttl
+    pub fn ttl(&self) -> io::Result<u32> {
+        self.sys.ttl()
+    }
+
+    /// Sets the value for the `IP_TTL` option on this socket.
+    ///
+    /// This value sets the time-to-live field that is used in every packet sent
+    /// from this socket.
+    pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
+        self.sys.set_ttl(ttl)
+    }
+
+    /// Executes an operation of the `IP_ADD_MEMBERSHIP` type.
+    ///
+    /// This function specifies a new multicast group for this socket to join.
+    /// The address must be a valid multicast address, and `interface` is the
+    /// address of the local interface with which the system should join the
+    /// multicast group. If it's equal to `INADDR_ANY` then an appropriate
+    /// interface is chosen by the system.
+    pub fn join_multicast_v4(&self,
+                             multiaddr: &Ipv4Addr,
+                             interface: &Ipv4Addr) -> io::Result<()> {
+        self.sys.join_multicast_v4(multiaddr, interface)
+    }
+
+    /// Executes an operation of the `IPV6_ADD_MEMBERSHIP` type.
+    ///
+    /// This function specifies a new multicast group for this socket to join.
+    /// The address must be a valid multicast address, and `interface` is the
+    /// index of the interface to join/leave (or 0 to indicate any interface).
+    pub fn join_multicast_v6(&self,
+                             multiaddr: &Ipv6Addr,
+                             interface: u32) -> io::Result<()> {
+        self.sys.join_multicast_v6(multiaddr, interface)
+    }
+
+    /// Executes an operation of the `IP_DROP_MEMBERSHIP` type.
+    ///
+    /// For more information about this option, see
+    /// [`join_multicast_v4`][link].
+    ///
+    /// [link]: #method.join_multicast_v4
+    pub fn leave_multicast_v4(&self,
+                              multiaddr: &Ipv4Addr,
+                              interface: &Ipv4Addr) -> io::Result<()> {
+        self.sys.leave_multicast_v4(multiaddr, interface)
+    }
+
+    /// Executes an operation of the `IPV6_DROP_MEMBERSHIP` type.
+    ///
+    /// For more information about this option, see
+    /// [`join_multicast_v6`][link].
+    ///
+    /// [link]: #method.join_multicast_v6
+    pub fn leave_multicast_v6(&self,
+                              multiaddr: &Ipv6Addr,
+                              interface: u32) -> io::Result<()> {
+        self.sys.leave_multicast_v6(multiaddr, interface)
+    }
+
+    /// Get the value of the `SO_ERROR` option on this socket.
+    ///
+    /// This will retrieve the stored error in the underlying socket, clearing
+    /// the field in the process. This can be useful for checking errors between
+    /// calls.
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        self.sys.take_error()
+    }
+}
+
+impl Evented for UdpSocket {
+    fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        try!(self.selector_id.associate_selector(poll));
+        self.sys.register(poll, token, interest, opts)
+    }
+
+    fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> {
+        self.sys.reregister(poll, token, interest, opts)
+    }
+
+    fn deregister(&self, poll: &Poll) -> io::Result<()> {
+        self.sys.deregister(poll)
+    }
+}
+
+/*
+ *
+ * ===== UNIX ext =====
+ *
+ */
+
+#[cfg(unix)]
+use std::os::unix::io::{IntoRawFd, AsRawFd, FromRawFd, RawFd};
+
+#[cfg(unix)]
+impl IntoRawFd for UdpSocket {
+    fn into_raw_fd(self) -> RawFd {
+        self.sys.into_raw_fd()
+    }
+}
+
+#[cfg(unix)]
+impl AsRawFd for UdpSocket {
+    fn as_raw_fd(&self) -> RawFd {
+        self.sys.as_raw_fd()
+    }
+}
+
+#[cfg(unix)]
+impl FromRawFd for UdpSocket {
+    unsafe fn from_raw_fd(fd: RawFd) -> UdpSocket {
+        UdpSocket {
+            sys: FromRawFd::from_raw_fd(fd),
+            selector_id: SelectorId::new(),
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/miow/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"7a72c6e4b9cce0cd1105ab0234e8b3caae6c1bd7af2c41eae39f031becfc5a37","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"05cefe09de4f980658e2868df1a220e3da5fd6ddb6d6c1eab1b5e6f5cb000879","appveyor.yml":"ffdfb9572a6362866bea6787a726b0d4e43f6bb6516f3a38ebdd561859531602","src/handle.rs":"ada6cf8482d49bc7be6d26adeb8ae47df9ff0a5637424474aa4a86ad699be63d","src/iocp.rs":"002fef559bbaf52ada0fcb7b94d6dbbaaedc94840b5870c186243e79120b7cfc","src/lib.rs":"0d30428e89c7a2be7e479148211360a56d6c6b3b5a86d5ee7254277484506efa","src/net.rs":"054b8772bf51acc80b74a261f2d759645332288e03c72e2bd05c555364fe05bf","src/overlapped.rs":"b3c7f7b45fd9b22090bd11563decb09e9c412db8757c0e7484cfaa9ec5e29b9c","src/pipe.rs":"97ef5d456d7e5a72af2c4509a8155bd45a2a755275524ce1cd2d79f44f264c65"},"package":"8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"}
\ No newline at end of file
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/third_party/rust/miow/Cargo.toml
@@ -0,0 +1,23 @@
+[package]
+name = "miow"
+version = "0.2.1"
+authors = ["Alex Crichton <alex@alexcrichton.com>"]
+license = "MIT/Apache-2.0"
+readme = "README.md"
+keywords = ["iocp", "windows", "io", "overlapped"]
+repository = "https://github.com/alexcrichton/miow"
+homepage = "https://github.com/alexcrichton/miow"
+documentation = "https://docs.rs/miow/0.1/x86_64-pc-windows-msvc/miow/"
+description = """
+A zero overhead I/O library for Windows, focusing on IOCP and Async I/O
+abstractions.
+"""
+
+[dependencies]
+winapi = "0.2"
+kernel32-sys = "0.2"
+ws2_32-sys = "0.2"
+net2 = { version = "0.2.5", default-features = false }
+
+[dev-dependencies]
+rand = "0.3"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/miow/LICENSE-APACHE
@@ -0,0 +1,201 @@
+                              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.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/miow/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2014 Alex Crichton
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/miow/README.md
@@ -0,0 +1,22 @@
+# miow
+
+[![Build status](https://ci.appveyor.com/api/projects/status/tc5lsxokjk86949l?svg=true)](https://ci.appveyor.com/project/alexcrichton/miow)
+
+[Documentation](https://docs.rs/miow/0.1/x86_64-pc-windows-msvc/miow/)
+
+A zero overhead Windows I/O library focusing on IOCP and other async I/O
+features.
+
+```toml
+# Cargo.toml
+[dependencies]
+miow = "0.1"
+```
+
+# License
+
+`miow` is primarily distributed under the terms of both the MIT license and
+the Apache License (Version 2.0), with portions covered by various BSD-like
+licenses.
+
+See LICENSE-APACHE, and LICENSE-MIT for details.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/miow/appveyor.yml
@@ -0,0 +1,20 @@
+environment:
+  matrix:
+  - TARGET: x86_64-pc-windows-msvc
+  - TARGET: i686-pc-windows-msvc
+  - TARGET: i686-pc-windows-gnu
+  GH_TOKEN:
+    secure: nHB4fVo+y/Aak+L0nYfrT8Rcs8OfUNm0F2xcIVFVYJ9ehf0CzvCmSMUvWguM0kKp
+
+install:
+  - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe"
+  - rust-nightly-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
+  - SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin
+  - SET PATH=%PATH%;C:\MinGW\bin
+  - rustc -V
+  - cargo -V
+
+build: false
+
+test_script:
+  - cargo test --target %TARGET%
new file mode 100644
--- /dev/null
+++ b/third_party/rust/miow/src/handle.rs
@@ -0,0 +1,93 @@
+use std::io;
+use std::cmp;
+
+use winapi::*;
+use kernel32::*;
+
+#[derive(Debug)]
+pub struct Handle(HANDLE);
+
+unsafe impl Send for Handle {}
+unsafe impl Sync for Handle {}
+
+impl Handle {
+    pub fn new(handle: HANDLE) -> Handle {
+        Handle(handle)
+    }
+
+    pub fn raw(&self) -> HANDLE { self.0 }
+
+    pub fn into_raw(self) -> HANDLE {
+        use std::mem;
+
+        let ret = self.0;
+        mem::forget(self);
+        ret
+    }
+
+    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
+        let mut bytes = 0;
+        let len = cmp::min(buf.len(), <DWORD>::max_value() as usize) as DWORD;
+        try!(::cvt(unsafe {
+            WriteFile(self.0, buf.as_ptr() as *const _, len, &mut bytes,
+                      0 as *mut _)
+        }));
+        Ok(bytes as usize)
+    }
+
+    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
+        let mut bytes = 0;
+        let len = cmp::min(buf.len(), <DWORD>::max_value() as usize) as DWORD;
+        try!(::cvt(unsafe {
+            ReadFile(self.0, buf.as_mut_ptr() as *mut _, len, &mut bytes,
+                     0 as *mut _)
+        }));
+        Ok(bytes as usize)
+    }
+
+    pub unsafe fn read_overlapped(&self, buf: &mut [u8],
+                                  overlapped: *mut OVERLAPPED)
+                                  -> io::Result<Option<usize>> {
+        let len = cmp::min(buf.len(), <DWORD>::max_value() as usize) as DWORD;
+        let mut bytes = 0;
+        let res = ::cvt({
+            ReadFile(self.0,
+                     buf.as_mut_ptr() as *mut _,
+                     len,
+                     &mut bytes,
+                     overlapped)
+        });
+        match res {
+            Ok(_) => Ok(Some(bytes as usize)),
+            Err(ref e) if e.raw_os_error() == Some(ERROR_IO_PENDING as i32)
+                => Ok(None),
+            Err(e) => Err(e),
+        }
+    }
+
+    pub unsafe fn write_overlapped(&self, buf: &[u8],
+                                   overlapped: *mut OVERLAPPED)
+                                   -> io::Result<Option<usize>> {
+        let len = cmp::min(buf.len(), <DWORD>::max_value() as usize) as DWORD;
+        let mut bytes = 0;
+        let res = ::cvt({
+            WriteFile(self.0,
+                      buf.as_ptr() as *const _,
+                      len,
+                      &mut bytes,
+                      overlapped)
+        });
+        match res {
+            Ok(_) => Ok(Some(bytes as usize)),
+            Err(ref e) if e.raw_os_error() == Some(ERROR_IO_PENDING as i32)
+                => Ok(None),
+            Err(e) => Err(e),
+        }
+    }
+}
+
+impl Drop for Handle {
+    fn drop(&mut self) {
+        unsafe { CloseHandle(self.0) };
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/miow/src/iocp.rs
@@ -0,0 +1,313 @@
+//! Bindings to IOCP, I/O Completion Ports
+
+use std::cmp;
+use std::io;
+use std::mem;
+use std::os::windows::io::*;
+use std::time::Duration;
+
+use handle::Handle;
+use winapi::*;
+use kernel32::*;
+use Overlapped;
+
+/// A handle to an Windows I/O Completion Port.
+#[derive(Debug)]
+pub struct CompletionPort {
+    handle: Handle,
+}
+
+/// A status message received from an I/O completion port.
+///
+/// These statuses can be created via the `new` or `empty` constructors and then
+/// provided to a completion port, or they are read out of a completion port.
+/// The fields of each status are read through its accessor methods.
+#[derive(Clone, Copy, Debug)]
+pub struct CompletionStatus(OVERLAPPED_ENTRY);
+
+unsafe impl Send for CompletionStatus {}
+unsafe impl Sync for CompletionStatus {}
+
+impl CompletionPort {
+    /// Creates a new I/O completion port with the specified concurrency value.
+    ///
+    /// The number of threads given corresponds to the level of concurrency
+    /// allowed for threads associated with this port. Consult the Windows
+    /// documentation for more information about this value.
+    pub fn new(threads: u32) -> io::Result<CompletionPort> {
+        let ret = unsafe {
+            CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0 as *mut _,
+                                   0, threads)
+        };
+        if ret.is_null() {
+            Err(io::Error::last_os_error())
+        } else {
+            Ok(CompletionPort { handle: Handle::new(ret) })
+        }
+    }
+
+    /// Associates a new `HANDLE` to this I/O completion port.
+    ///
+    /// This function will associate the given handle to this port with the
+    /// given `token` to be returned in status messages whenever it receives a
+    /// notification.
+    ///
+    /// Any object which is convertible to a `HANDLE` via the `AsRawHandle`
+    /// trait can be provided to this function, such as `std::fs::File` and
+    /// friends.
+    pub fn add_handle<T: AsRawHandle + ?Sized>(&self, token: usize,
+                                               t: &T) -> io::Result<()> {
+        self._add(token, t.as_raw_handle())
+    }
+
+    /// Associates a new `SOCKET` to this I/O completion port.
+    ///
+    /// This function will associate the given socket to this port with the
+    /// given `token` to be returned in status messages whenever it receives a
+    /// notification.
+    ///
+    /// Any object which is convertible to a `SOCKET` via the `AsRawSocket`
+    /// trait can be provided to this function, such as `std::net::TcpStream`
+    /// and friends.
+    pub fn add_socket<T: AsRawSocket + ?Sized>(&self, token: usize,
+                                               t: &T) -> io::Result<()> {
+        self._add(token, t.as_raw_socket() as HANDLE)
+    }
+
+    fn _add(&self, token: usize, handle: HANDLE) -> io::Result<()> {
+        assert_eq!(mem::size_of_val(&token), mem::size_of::<ULONG_PTR>());
+        let ret = unsafe {
+            CreateIoCompletionPort(handle, self.handle.raw(),
+                                   token as ULONG_PTR, 0)
+        };
+        if ret.is_null() {
+            Err(io::Error::last_os_error())
+        } else {
+            debug_assert_eq!(ret, self.handle.raw());
+            Ok(())
+        }
+    }
+
+    /// Dequeue a completion status from this I/O completion port.
+    ///
+    /// This function will associate the calling thread with this completion
+    /// port and then wait for a status message to become available. The precise
+    /// semantics on when this function returns depends on the concurrency value
+    /// specified when the port was created.
+    ///
+    /// A timeout can optionally be specified to this function. If `None` is
+    /// provided this function will not time out, and otherwise it will time out
+    /// after the specified duration has passed.
+    ///
+    /// On success this will return the status message which was dequeued from
+    /// this completion port.
+    pub fn get(&self, timeout: Option<Duration>) -> io::Result<CompletionStatus> {
+        let mut bytes = 0;
+        let mut token = 0;
+        let mut overlapped = 0 as *mut _;
+        let timeout = ::dur2ms(timeout);
+        let ret = unsafe {
+            GetQueuedCompletionStatus(self.handle.raw(),
+                                      &mut bytes,
+                                      &mut token,
+                                      &mut overlapped,
+                                      timeout)
+        };
+        ::cvt(ret).map(|_| {
+            CompletionStatus(OVERLAPPED_ENTRY {
+                dwNumberOfBytesTransferred: bytes,
+                lpCompletionKey: token,
+                lpOverlapped: overlapped,
+                Internal: 0,
+            })
+        })
+    }
+
+    /// Dequeues a number of completion statuses from this I/O completion port.
+    ///
+    /// This function is the same as `get` except that it may return more than
+    /// one status. A buffer of "zero" statuses is provided (the contents are
+    /// not read) and then on success this function will return a sub-slice of
+    /// statuses which represent those which were dequeued from this port. This
+    /// function does not wait to fill up the entire list of statuses provided.
+    ///
+    /// Like with `get`, a timeout may be specified for this operation.
+    pub fn get_many<'a>(&self,
+                        list: &'a mut [CompletionStatus],
+                        timeout: Option<Duration>)
+                        -> io::Result<&'a mut [CompletionStatus]>
+    {
+        debug_assert_eq!(mem::size_of::<CompletionStatus>(),
+                         mem::size_of::<OVERLAPPED_ENTRY>());
+        let mut removed = 0;
+        let timeout = ::dur2ms(timeout);
+        let len = cmp::min(list.len(), <ULONG>::max_value() as usize) as ULONG;
+        let ret = unsafe {
+            GetQueuedCompletionStatusEx(self.handle.raw(),
+                                        list.as_ptr() as *mut _,
+                                        len,
+                                        &mut removed,
+                                        timeout,
+                                        FALSE)
+        };
+        match ::cvt(ret) {
+            Ok(_) => Ok(&mut list[..removed as usize]),
+            Err(e) => Err(e),
+        }
+    }
+
+    /// Posts a new completion status onto this I/O completion port.
+    ///
+    /// This function will post the given status, with custom parameters, to the
+    /// port. Threads blocked in `get` or `get_many` will eventually receive
+    /// this status.
+    pub fn post(&self, status: CompletionStatus) -> io::Result<()> {
+        let ret = unsafe {
+            PostQueuedCompletionStatus(self.handle.raw(),
+                                       status.0.dwNumberOfBytesTransferred,
+                                       status.0.lpCompletionKey,
+                                       status.0.lpOverlapped)
+        };
+        ::cvt(ret).map(|_| ())
+    }
+}
+
+impl AsRawHandle for CompletionPort {
+    fn as_raw_handle(&self) -> HANDLE {
+        self.handle.raw()
+    }
+}
+
+impl FromRawHandle for CompletionPort {
+    unsafe fn from_raw_handle(handle: HANDLE) -> CompletionPort {
+        CompletionPort { handle: Handle::new(handle) }
+    }
+}
+
+impl IntoRawHandle for CompletionPort {
+    fn into_raw_handle(self) -> HANDLE {
+        self.handle.into_raw()
+    }
+}
+
+impl CompletionStatus {
+    /// Creates a new completion status with the provided parameters.
+    ///
+    /// This function is useful when creating a status to send to a port with
+    /// the `post` method. The parameters are opaquely passed through and not
+    /// interpreted by the system at all.
+    pub fn new(bytes: u32, token: usize, overlapped: *mut Overlapped)
+               -> CompletionStatus {
+        assert_eq!(mem::size_of_val(&token), mem::size_of::<ULONG_PTR>());
+        CompletionStatus(OVERLAPPED_ENTRY {
+            dwNumberOfBytesTransferred: bytes,
+            lpCompletionKey: token as ULONG_PTR,
+            lpOverlapped: overlapped as *mut _,
+            Internal: 0,
+        })
+    }
+
+    /// Creates a new borrowed completion status from the borrowed
+    /// `OVERLAPPED_ENTRY` argument provided.
+    ///
+    /// This method will wrap the `OVERLAPPED_ENTRY` in a `CompletionStatus`,
+    /// returning the wrapped structure.
+    pub fn from_entry(entry: &OVERLAPPED_ENTRY) -> &CompletionStatus {
+        unsafe { &*(entry as *const _ as *const _) }
+    }
+
+    /// Creates a new "zero" completion status.
+    ///
+    /// This function is useful when creating a stack buffer or vector of
+    /// completion statuses to be passed to the `get_many` function.
+    pub fn zero() -> CompletionStatus {
+        CompletionStatus::new(0, 0, 0 as *mut _)
+    }
+
+    /// Returns the number of bytes that were transferred for the I/O operation
+    /// associated with this completion status.
+    pub fn bytes_transferred(&self) -> u32 {
+        self.0.dwNumberOfBytesTransferred
+    }
+
+    /// Returns the completion key value associated with the file handle whose
+    /// I/O operation has completed.
+    ///
+    /// A completion key is a per-handle key that is specified when it is added
+    /// to an I/O completion port via `add_handle` or `add_socket`.
+    pub fn token(&self) -> usize {
+        self.0.lpCompletionKey as usize
+    }
+
+    /// Returns a pointer to the `Overlapped` structure that was specified when
+    /// the I/O operation was started.
+    pub fn overlapped(&self) -> *mut OVERLAPPED {
+        self.0.lpOverlapped
+    }
+
+    /// Returns a pointer to the internal `OVERLAPPED_ENTRY` object.
+    pub fn entry(&self) -> &OVERLAPPED_ENTRY {
+        &self.0
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::mem;
+    use std::time::Duration;
+
+    use winapi::*;
+
+    use iocp::{CompletionPort, CompletionStatus};
+
+    #[test]
+    fn is_send_sync() {
+        fn is_send_sync<T: Send + Sync>() {}
+        is_send_sync::<CompletionPort>();
+    }
+
+    #[test]
+    fn token_right_size() {
+        assert_eq!(mem::size_of::<usize>(), mem::size_of::<ULONG_PTR>());
+    }
+
+    #[test]
+    fn timeout() {
+        let c = CompletionPort::new(1).unwrap();
+        let err = c.get(Some(Duration::from_millis(1))).unwrap_err();
+        assert_eq!(err.raw_os_error(), Some(WAIT_TIMEOUT as i32));
+    }
+
+    #[test]
+    fn get() {
+        let c = CompletionPort::new(1).unwrap();
+        c.post(CompletionStatus::new(1, 2, 3 as *mut _)).unwrap();
+        let s = c.get(None).unwrap();
+        assert_eq!(s.bytes_transferred(), 1);
+        assert_eq!(s.token(), 2);
+        assert_eq!(s.overlapped(), 3 as *mut _);
+    }
+
+    #[test]
+    fn get_many() {
+        let c = CompletionPort::new(1).unwrap();
+
+        c.post(CompletionStatus::new(1, 2, 3 as *mut _)).unwrap();
+        c.post(CompletionStatus::new(4, 5, 6 as *mut _)).unwrap();
+
+        let mut s = vec![CompletionStatus::zero(); 4];
+        {
+            let s = c.get_many(&mut s, None).unwrap();
+            assert_eq!(s.len(), 2);
+            assert_eq!(s[0].bytes_transferred(), 1);
+            assert_eq!(s[0].token(), 2);
+            assert_eq!(s[0].overlapped(), 3 as *mut _);
+            assert_eq!(s[1].bytes_transferred(), 4);
+            assert_eq!(s[1].token(), 5);
+            assert_eq!(s[1].overlapped(), 6 as *mut _);
+        }
+        assert_eq!(s[2].bytes_transferred(), 0);
+        assert_eq!(s[2].token(), 0);
+        assert_eq!(s[2].overlapped(), 0 as *mut _);
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/miow/src/lib.rs
@@ -0,0 +1,57 @@
+//! A zero overhead Windows I/O library
+
+#![cfg(windows)]
+#![deny(missing_docs)]
+#![allow(bad_style)]
+#![doc(html_root_url = "https://docs.rs/miow/0.1/x86_64-pc-windows-msvc/")]
+
+extern crate kernel32;
+extern crate net2;
+extern crate winapi;
+extern crate ws2_32;
+
+#[cfg(test)] extern crate rand;
+
+use std::cmp;
+use std::io;
+use std::time::Duration;
+
+use winapi::*;
+
+macro_rules! t {
+    ($e:expr) => (match $e {
+        Ok(e) => e,
+        Err(e) => panic!("{} failed with {:?}", stringify!($e), e),
+    })
+}
+
+mod handle;
+mod overlapped;
+
+pub mod iocp;
+pub mod net;
+pub mod pipe;
+
+pub use overlapped::Overlapped;
+
+fn cvt(i: BOOL) -> io::Result<BOOL> {
+    if i == 0 {
+        Err(io::Error::last_os_error())
+    } else {
+        Ok(i)
+    }
+}
+
+fn dur2ms(dur: Option<Duration>) -> u32 {
+    let dur = match dur {
+        Some(dur) => dur,
+        None => return INFINITE,
+    };
+    let ms = dur.as_secs().checked_mul(1_000);
+    let ms_extra = dur.subsec_nanos() / 1_000_000;
+    ms.and_then(|ms| {
+        ms.checked_add(ms_extra as u64)
+    }).map(|ms| {
+        cmp::min(u32::max_value() as u64, ms) as u32
+    }).unwrap_or(INFINITE - 1)
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/miow/src/net.rs
@@ -0,0 +1,1183 @@
+//! Extensions and types for the standard networking primitives.
+//!
+//! This module contains a number of extension traits for the types in
+//! `std::net` for Windows-specific functionality.
+
+use std::cmp;
+use std::io;
+use std::mem;
+use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
+use std::net::{TcpStream, UdpSocket, SocketAddr, TcpListener};
+use std::net::{SocketAddrV4, Ipv4Addr, SocketAddrV6, Ipv6Addr};
+use std::os::windows::prelude::*;
+
+use net2::TcpBuilder;
+use winapi::*;
+use ws2_32::*;
+
+/// A type to represent a buffer in which a socket address will be stored.
+///
+/// This type is used with the `recv_from_overlapped` function on the
+/// `UdpSocketExt` trait to provide space for the overlapped I/O operation to
+/// fill in the address upon completion.
+#[derive(Clone, Copy)]
+pub struct SocketAddrBuf {
+    buf: SOCKADDR_STORAGE,
+    len: c_int,
+}
+
+/// A type to represent a buffer in which an accepted socket's address will be
+/// stored.
+///
+/// This type is used with the `accept_overlapped` method on the
+/// `TcpListenerExt` trait to provide space for the overlapped I/O operation to
+/// fill in the socket addresses upon completion.
+#[repr(C)]
+pub struct AcceptAddrsBuf {
+    // For AcceptEx we've got the restriction that the addresses passed in that
+    // buffer need to be at least 16 bytes more than the maximum address length
+    // for the protocol in question, so add some extra here and there
+    local: SOCKADDR_STORAGE,
+    _pad1: [u8; 16],
+    remote: SOCKADDR_STORAGE,
+    _pad2: [u8; 16],
+}
+
+/// The parsed return value of `AcceptAddrsBuf`.
+pub struct AcceptAddrs<'a> {
+    local: LPSOCKADDR,
+    local_len: c_int,
+    remote: LPSOCKADDR,
+    remote_len: c_int,
+    _data: &'a AcceptAddrsBuf,
+}
+
+struct WsaExtension {
+    guid: GUID,
+    val: AtomicUsize,
+}
+
+/// Additional methods for the `TcpStream` type in the standard library.
+pub trait TcpStreamExt {
+    /// Execute an overlapped read I/O operation on this TCP stream.
+    ///
+    /// This function will issue an overlapped I/O read (via `WSARecv`) on this
+    /// socket. The provided buffer will be filled in when the operation
+    /// completes and the given `OVERLAPPED` instance is used to track the
+    /// overlapped operation.
+    ///
+    /// If the operation succeeds, `Ok(Some(n))` is returned indicating how
+    /// many bytes were read. If the operation returns an error indicating that
+    /// the I/O is currently pending, `Ok(None)` is returned. Otherwise, the
+    /// error associated with the operation is returned and no overlapped
+    /// operation is enqueued.
+    ///
+    /// The number of bytes read will be returned as part of the completion
+    /// notification when the I/O finishes.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe because the kernel requires that the `buf` and
+    /// `overlapped` pointers are valid until the end of the I/O operation. The
+    /// kernel also requires that `overlapped` is unique for this I/O operation
+    /// and is not in use for any other I/O.
+    ///
+    /// To safely use this function callers must ensure that these two input
+    /// pointers are valid until the I/O operation is completed, typically via
+    /// completion ports and waiting to receive the completion notification on
+    /// the port.
+    unsafe fn read_overlapped(&self,
+                              buf: &mut [u8],
+                              overlapped: *mut OVERLAPPED)
+                              -> io::Result<Option<usize>>;
+
+    /// Execute an overlapped write I/O operation on this TCP stream.
+    ///
+    /// This function will issue an overlapped I/O write (via `WSASend`) on this
+    /// socket. The provided buffer will be written when the operation completes
+    /// and the given `OVERLAPPED` instance is used to track the overlapped
+    /// operation.
+    ///
+    /// If the operation succeeds, `Ok(Some(n))` is returned where `n` is the
+    /// number of bytes that were written. If the operation returns an error
+    /// indicating that the I/O is currently pending, `Ok(None)` is returned.
+    /// Otherwise, the error associated with the operation is returned and no
+    /// overlapped operation is enqueued.
+    ///
+    /// The number of bytes written will be returned as part of the completion
+    /// notification when the I/O finishes.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe because the kernel requires that the `buf` and
+    /// `overlapped` pointers are valid until the end of the I/O operation. The
+    /// kernel also requires that `overlapped` is unique for this I/O operation
+    /// and is not in use for any other I/O.
+    ///
+    /// To safely use this function callers must ensure that these two input
+    /// pointers are valid until the I/O operation is completed, typically via
+    /// completion ports and waiting to receive the completion notification on
+    /// the port.
+    unsafe fn write_overlapped(&self,
+                               buf: &[u8],
+                               overlapped: *mut OVERLAPPED)
+                               -> io::Result<Option<usize>>;
+
+    /// Execute a connection operation for this socket.
+    ///
+    /// For more information about this method, see the
+    /// [`TcpBuilderExt::connect_overlapped`][link] documentation.
+    ///
+    /// [link]: trait.TcpBuilderExt.html#tymethod.connect_overlapped
+    unsafe fn connect_overlapped(&self,
+                                 addr: &SocketAddr,
+                                 buf: &[u8],
+                                 overlapped: *mut OVERLAPPED)
+                                 -> io::Result<Option<usize>>;
+
+    /// Once a `connect_overlapped` has finished, this function needs to be
+    /// called to finish the connect operation.
+    ///
+    /// Currently this just calls `setsockopt` with `SO_UPDATE_CONNECT_CONTEXT`
+    /// to ensure that further functions like `getpeername` and `getsockname`
+    /// work correctly.
+    fn connect_complete(&self) -> io::Result<()>;
+
+    /// Calls the `GetOverlappedResult` function to get the result of an
+    /// overlapped operation for this handle.
+    ///
+    /// This function takes the `OVERLAPPED` argument which must have been used
+    /// to initiate an overlapped I/O operation, and returns either the
+    /// successful number of bytes transferred during the operation or an error
+    /// if one occurred, along with the results of the `lpFlags` parameter of
+    /// the relevant operation, if applicable.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe as `overlapped` must have previously been used
+    /// to execute an operation for this handle, and it must also be a valid
+    /// pointer to an `OVERLAPPED` instance.
+    ///
+    /// # Panics
+    ///
+    /// This function will panic
+    unsafe fn result(&self, overlapped: *mut OVERLAPPED)
+                     -> io::Result<(usize, u32)>;
+}
+
+/// Additional methods for the `UdpSocket` type in the standard library.
+pub trait UdpSocketExt {
+    /// Execute an overlapped receive I/O operation on this UDP socket.
+    ///
+    /// This function will issue an overlapped I/O read (via `WSARecvFrom`) on
+    /// this socket. The provided buffer will be filled in when the operation
+    /// completes, the source from where the data came from will be written to
+    /// `addr`, and the given `OVERLAPPED` instance is used to track the
+    /// overlapped operation.
+    ///
+    /// If the operation succeeds, `Ok(Some(n))` is returned where `n` is the
+    /// number of bytes that were read. If the operation returns an error
+    /// indicating that the I/O is currently pending, `Ok(None)` is returned.
+    /// Otherwise, the error associated with the operation is returned and no
+    /// overlapped operation is enqueued.
+    ///
+    /// The number of bytes read will be returned as part of the completion
+    /// notification when the I/O finishes.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe because the kernel requires that the `buf`,
+    /// `addr`, and `overlapped` pointers are valid until the end of the I/O
+    /// operation. The kernel also requires that `overlapped` is unique for this
+    /// I/O operation and is not in use for any other I/O.
+    ///
+    /// To safely use this function callers must ensure that these two input
+    /// pointers are valid until the I/O operation is completed, typically via
+    /// completion ports and waiting to receive the completion notification on
+    /// the port.
+    unsafe fn recv_from_overlapped(&self,
+                                   buf: &mut [u8],
+                                   addr: *mut SocketAddrBuf,
+                                   overlapped: *mut OVERLAPPED)
+                                   -> io::Result<Option<usize>>;
+
+    /// Execute an overlapped receive I/O operation on this UDP socket.
+    ///
+    /// This function will issue an overlapped I/O read (via `WSARecv`) on
+    /// this socket. The provided buffer will be filled in when the operation
+    /// completes, the source from where the data came from will be written to
+    /// `addr`, and the given `OVERLAPPED` instance is used to track the
+    /// overlapped operation.
+    ///
+    /// If the operation succeeds, `Ok(Some(n))` is returned where `n` is the
+    /// number of bytes that were read. If the operation returns an error
+    /// indicating that the I/O is currently pending, `Ok(None)` is returned.
+    /// Otherwise, the error associated with the operation is returned and no
+    /// overlapped operation is enqueued.
+    ///
+    /// The number of bytes read will be returned as part of the completion
+    /// notification when the I/O finishes.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe because the kernel requires that the `buf`,
+    /// and `overlapped` pointers are valid until the end of the I/O
+    /// operation. The kernel also requires that `overlapped` is unique for this
+    /// I/O operation and is not in use for any other I/O.
+    ///
+    /// To safely use this function callers must ensure that these two input
+    /// pointers are valid until the I/O operation is completed, typically via
+    /// completion ports and waiting to receive the completion notification on
+    /// the port.
+    unsafe fn recv_overlapped(&self,
+                              buf: &mut [u8],
+                              overlapped: *mut OVERLAPPED)
+                              -> io::Result<Option<usize>>;
+
+    /// Execute an overlapped send I/O operation on this UDP socket.
+    ///
+    /// This function will issue an overlapped I/O write (via `WSASendTo`) on
+    /// this socket to the address specified by `addr`. The provided buffer will
+    /// be written when the operation completes and the given `OVERLAPPED`
+    /// instance is used to track the overlapped operation.
+    ///
+    /// If the operation succeeds, `Ok(Some(n0)` is returned where `n` byte
+    /// were written. If the operation returns an error indicating that the I/O
+    /// is currently pending, `Ok(None)` is returned. Otherwise, the error
+    /// associated with the operation is returned and no overlapped operation
+    /// is enqueued.
+    ///
+    /// The number of bytes written will be returned as part of the completion
+    /// notification when the I/O finishes.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe because the kernel requires that the `buf` and
+    /// `overlapped` pointers are valid until the end of the I/O operation. The
+    /// kernel also requires that `overlapped` is unique for this I/O operation
+    /// and is not in use for any other I/O.
+    ///
+    /// To safely use this function callers must ensure that these two input
+    /// pointers are valid until the I/O operation is completed, typically via
+    /// completion ports and waiting to receive the completion notification on
+    /// the port.
+    unsafe fn send_to_overlapped(&self,
+                                 buf: &[u8],
+                                 addr: &SocketAddr,
+                                 overlapped: *mut OVERLAPPED)
+                                 -> io::Result<Option<usize>>;
+
+    /// Execute an overlapped send I/O operation on this UDP socket.
+    ///
+    /// This function will issue an overlapped I/O write (via `WSASend`) on
+    /// this socket to the address it was previously connected to. The provided 
+    /// buffer will be written when the operation completes and the given `OVERLAPPED`
+    /// instance is used to track the overlapped operation.
+    ///
+    /// If the operation succeeds, `Ok(Some(n0)` is returned where `n` byte
+    /// were written. If the operation returns an error indicating that the I/O
+    /// is currently pending, `Ok(None)` is returned. Otherwise, the error
+    /// associated with the operation is returned and no overlapped operation
+    /// is enqueued.
+    ///
+    /// The number of bytes written will be returned as part of the completion
+    /// notification when the I/O finishes.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe because the kernel requires that the `buf` and
+    /// `overlapped` pointers are valid until the end of the I/O operation. The
+    /// kernel also requires that `overlapped` is unique for this I/O operation
+    /// and is not in use for any other I/O.
+    ///
+    /// To safely use this function callers must ensure that these two input
+    /// pointers are valid until the I/O operation is completed, typically via
+    /// completion ports and waiting to receive the completion notification on
+    /// the port.
+    unsafe fn send_overlapped(&self,
+                                 buf: &[u8],
+                                 overlapped: *mut OVERLAPPED)
+                                 -> io::Result<Option<usize>>;
+ 
+    /// Calls the `GetOverlappedResult` function to get the result of an
+    /// overlapped operation for this handle.
+    ///
+    /// This function takes the `OVERLAPPED` argument which must have been used
+    /// to initiate an overlapped I/O operation, and returns either the
+    /// successful number of bytes transferred during the operation or an error
+    /// if one occurred, along with the results of the `lpFlags` parameter of
+    /// the relevant operation, if applicable.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe as `overlapped` must have previously been used
+    /// to execute an operation for this handle, and it must also be a valid
+    /// pointer to an `OVERLAPPED` instance.
+    ///
+    /// # Panics
+    ///
+    /// This function will panic
+    unsafe fn result(&self, overlapped: *mut OVERLAPPED)
+                     -> io::Result<(usize, u32)>;
+}
+
+/// Additional methods for the `TcpBuilder` type in the `net2` library.
+pub trait TcpBuilderExt {
+    /// Attempt to consume the internal socket in this builder by executing an
+    /// overlapped connect operation.
+    ///
+    /// This function will issue a connect operation to the address specified on
+    /// the underlying socket, flagging it as an overlapped operation which will
+    /// complete asynchronously. If successful this function will return the
+    /// corresponding TCP stream.
+    ///
+    /// The `buf` argument provided is an initial buffer of data that should be
+    /// sent after the connection is initiated. It's acceptable to
+    /// pass an empty slice here.
+    ///
+    /// This function will also return whether the connect immediately
+    /// succeeded or not. If `None` is returned then the I/O operation is still
+    /// pending and will complete at a later date, and if `Some(bytes)` is
+    /// returned then that many bytes were transferred.
+    ///
+    /// Note that to succeed this requires that the underlying socket has
+    /// previously been bound via a call to `bind` to a local address.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe because the kernel requires that the
+    /// `overlapped` and `buf` pointers to be  valid until the end of the I/O
+    /// operation. The kernel also requires that `overlapped` is unique for
+    /// this I/O operation and is not in use for any other I/O.
+    ///
+    /// To safely use this function callers must ensure that this pointer is
+    /// valid until the I/O operation is completed, typically via completion
+    /// ports and waiting to receive the completion notification on the port.
+    unsafe fn connect_overlapped(&self,
+                                 addr: &SocketAddr,
+                                 buf: &[u8],
+                                 overlapped: *mut OVERLAPPED)
+                                 -> io::Result<(TcpStream, Option<usize>)>;
+
+    /// Calls the `GetOverlappedResult` function to get the result of an
+    /// overlapped operation for this handle.
+    ///
+    /// This function takes the `OVERLAPPED` argument which must have been used
+    /// to initiate an overlapped I/O operation, and returns either the
+    /// successful number of bytes transferred during the operation or an error
+    /// if one occurred, along with the results of the `lpFlags` parameter of
+    /// the relevant operation, if applicable.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe as `overlapped` must have previously been used
+    /// to execute an operation for this handle, and it must also be a valid
+    /// pointer to an `OVERLAPPED` instance.
+    ///
+    /// # Panics
+    ///
+    /// This function will panic
+    unsafe fn result(&self, overlapped: *mut OVERLAPPED)
+                     -> io::Result<(usize, u32)>;
+}
+
+/// Additional methods for the `TcpListener` type in the standard library.
+pub trait TcpListenerExt {
+    /// Perform an accept operation on this listener, accepting a connection in
+    /// an overlapped fashion.
+    ///
+    /// This function will issue an I/O request to accept an incoming connection
+    /// with the specified overlapped instance. The `socket` provided must be a
+    /// configured but not bound or connected socket, and if successful this
+    /// will consume the internal socket of the builder to return a TCP stream.
+    ///
+    /// The `addrs` buffer provided will be filled in with the local and remote
+    /// addresses of the connection upon completion.
+    ///
+    /// If the accept succeeds immediately, `Ok(stream, true)` is returned. If
+    /// the connect indicates that the I/O is currently pending, `Ok(stream,
+    /// false)` is returned. Otherwise, the error associated with the operation
+    /// is returned and no overlapped operation is enqueued.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe because the kernel requires that the
+    /// `addrs` and `overlapped` pointers are valid until the end of the I/O
+    /// operation. The kernel also requires that `overlapped` is unique for this
+    /// I/O operation and is not in use for any other I/O.
+    ///
+    /// To safely use this function callers must ensure that the pointers are
+    /// valid until the I/O operation is completed, typically via completion
+    /// ports and waiting to receive the completion notification on the port.
+    unsafe fn accept_overlapped(&self,
+                                socket: &TcpBuilder,
+                                addrs: &mut AcceptAddrsBuf,
+                                overlapped: *mut OVERLAPPED)
+                                -> io::Result<(TcpStream, bool)>;
+
+    /// Once an `accept_overlapped` has finished, this function needs to be
+    /// called to finish the accept operation.
+    ///
+    /// Currently this just calls `setsockopt` with `SO_UPDATE_ACCEPT_CONTEXT`
+    /// to ensure that further functions like `getpeername` and `getsockname`
+    /// work correctly.
+    fn accept_complete(&self, socket: &TcpStream) -> io::Result<()>;
+
+    /// Calls the `GetOverlappedResult` function to get the result of an
+    /// overlapped operation for this handle.
+    ///
+    /// This function takes the `OVERLAPPED` argument which must have been used
+    /// to initiate an overlapped I/O operation, and returns either the
+    /// successful number of bytes transferred during the operation or an error
+    /// if one occurred, along with the results of the `lpFlags` parameter of
+    /// the relevant operation, if applicable.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe as `overlapped` must have previously been used
+    /// to execute an operation for this handle, and it must also be a valid
+    /// pointer to an `OVERLAPPED` instance.
+    ///
+    /// # Panics
+    ///
+    /// This function will panic
+    unsafe fn result(&self, overlapped: *mut OVERLAPPED)
+                     -> io::Result<(usize, u32)>;
+}
+
+#[doc(hidden)]
+trait NetInt {
+    fn from_be(i: Self) -> Self;
+    fn to_be(&self) -> Self;
+}
+macro_rules! doit {
+    ($($t:ident)*) => ($(impl NetInt for $t {
+        fn from_be(i: Self) -> Self { <$t>::from_be(i) }
+        fn to_be(&self) -> Self { <$t>::to_be(*self) }
+    })*)
+}
+doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
+
+// fn hton<I: NetInt>(i: I) -> I { i.to_be() }
+fn ntoh<I: NetInt>(i: I) -> I { I::from_be(i) }
+
+fn last_err() -> io::Result<Option<usize>> {
+    let err = unsafe { WSAGetLastError() };
+    if err == WSA_IO_PENDING as i32 {
+        Ok(None)
+    } else {
+        Err(io::Error::from_raw_os_error(err))
+    }
+}
+
+fn cvt(i: c_int, size: DWORD) -> io::Result<Option<usize>> {
+    if i == SOCKET_ERROR {
+        last_err()
+    } else {
+        Ok(Some(size as usize))
+    }
+}
+
+fn socket_addr_to_ptrs(addr: &SocketAddr) -> (*const SOCKADDR, c_int) {
+    match *addr {
+        SocketAddr::V4(ref a) => {
+            (a as *const _ as *const _, mem::size_of::<SOCKADDR_IN>() as c_int)
+        }
+        SocketAddr::V6(ref a) => {
+            (a as *const _ as *const _, mem::size_of::<sockaddr_in6>() as c_int)
+        }
+    }
+}
+
+unsafe fn ptrs_to_socket_addr(ptr: *const SOCKADDR,
+                              len: c_int) -> Option<SocketAddr> {
+    if (len as usize) < mem::size_of::<c_int>() {
+        return None
+    }
+    match (*ptr).sa_family as i32 {
+        AF_INET if len as usize >= mem::size_of::<SOCKADDR_IN>() => {
+            let b = &*(ptr as *const SOCKADDR_IN);
+            let ip = ntoh(b.sin_addr.S_un);
+            let ip = Ipv4Addr::new((ip >> 24) as u8,
+                                   (ip >> 16) as u8,
+                                   (ip >>  8) as u8,
+                                   (ip >>  0) as u8);
+            Some(SocketAddr::V4(SocketAddrV4::new(ip, ntoh(b.sin_port))))
+        }
+        AF_INET6 if len as usize >= mem::size_of::<sockaddr_in6>() => {
+            let b = &*(ptr as *const sockaddr_in6);
+            let arr = &b.sin6_addr.s6_addr;
+            let ip = Ipv6Addr::new(
+                ((arr[0] as u16) << 8) | (arr[1] as u16),
+                ((arr[2] as u16) << 8) | (arr[3] as u16),
+                ((arr[4] as u16) << 8) | (arr[5] as u16),
+                ((arr[6] as u16) << 8) | (arr[7] as u16),
+                ((arr[8] as u16) << 8) | (arr[9] as u16),
+                ((arr[10] as u16) << 8) | (arr[11] as u16),
+                ((arr[12] as u16) << 8) | (arr[13] as u16),
+                ((arr[14] as u16) << 8) | (arr[15] as u16));
+            let addr = SocketAddrV6::new(ip, ntoh(b.sin6_port),
+                                         ntoh(b.sin6_flowinfo),
+                                         ntoh(b.sin6_scope_id));
+            Some(SocketAddr::V6(addr))
+        }
+        _ => None
+    }
+}
+
+unsafe fn slice2buf(slice: &[u8]) -> WSABUF {
+    WSABUF {
+        len: cmp::min(slice.len(), <u_long>::max_value() as usize) as u_long,
+        buf: slice.as_ptr() as *mut _,
+    }
+}
+
+unsafe fn result(socket: SOCKET, overlapped: *mut OVERLAPPED)
+                 -> io::Result<(usize, u32)> {
+    let mut transferred = 0;
+    let mut flags = 0;
+    let r = WSAGetOverlappedResult(socket,
+                                   overlapped,
+                                   &mut transferred,
+                                   FALSE,
+                                   &mut flags);
+    if r == 0 {
+        Err(io::Error::last_os_error())
+    } else {
+        Ok((transferred as usize, flags))
+    }
+}
+
+impl TcpStreamExt for TcpStream {
+    unsafe fn read_overlapped(&self,
+                              buf: &mut [u8],
+                              overlapped: *mut OVERLAPPED)
+                              -> io::Result<Option<usize>> {
+        let mut buf = slice2buf(buf);
+        let mut flags = 0;
+        let mut bytes_read: DWORD = 0;
+        let r = WSARecv(self.as_raw_socket(), &mut buf, 1,
+                        &mut bytes_read, &mut flags, overlapped, None);
+        cvt(r, bytes_read)
+    }
+
+    unsafe fn write_overlapped(&self,
+                               buf: &[u8],
+                               overlapped: *mut OVERLAPPED)
+                               -> io::Result<Option<usize>> {
+        let mut buf = slice2buf(buf);
+        let mut bytes_written = 0;
+
+        // Note here that we capture the number of bytes written. The
+        // documentation on MSDN, however, states:
+        //
+        // > Use NULL for this parameter if the lpOverlapped parameter is not
+        // > NULL to avoid potentially erroneous results. This parameter can be
+        // > NULL only if the lpOverlapped parameter is not NULL.
+        //
+        // If we're not passing a null overlapped pointer here, then why are we
+        // then capturing the number of bytes! Well so it turns out that this is
+        // clearly faster to learn the bytes here rather than later calling
+        // `WSAGetOverlappedResult`, and in practice almost all implementations
+        // use this anyway [1].
+        //
+        // As a result we use this to and report back the result.
+        //
+        // [1]: https://github.com/carllerche/mio/pull/520#issuecomment-273983823
+        let r = WSASend(self.as_raw_socket(), &mut buf, 1,
+                        &mut bytes_written, 0, overlapped, None);
+        cvt(r, bytes_written)
+    }
+
+    unsafe fn connect_overlapped(&self,
+                                 addr: &SocketAddr,
+                                 buf: &[u8],
+                                 overlapped: *mut OVERLAPPED)
+                                 -> io::Result<Option<usize>> {
+        connect_overlapped(self.as_raw_socket(), addr, buf, overlapped)
+    }
+
+    fn connect_complete(&self) -> io::Result<()> {
+        const SO_UPDATE_CONNECT_CONTEXT: c_int = 0x7010;
+        let result = unsafe {
+            setsockopt(self.as_raw_socket(),
+                       SOL_SOCKET,
+                       SO_UPDATE_CONNECT_CONTEXT,
+                       0 as *const _,
+                       0)
+        };
+        if result == 0 {
+            Ok(())
+        } else {
+            Err(io::Error::last_os_error())
+        }
+    }
+
+    unsafe fn result(&self, overlapped: *mut OVERLAPPED)
+                     -> io::Result<(usize, u32)> {
+        result(self.as_raw_socket(), overlapped)
+    }
+}
+
+unsafe fn connect_overlapped(socket: SOCKET,
+                             addr: &SocketAddr,
+                             buf: &[u8],
+                             overlapped: *mut OVERLAPPED)
+                             -> io::Result<Option<usize>> {
+    static CONNECTEX: WsaExtension = WsaExtension {
+        guid: GUID {
+            Data1: 0x25a207b9,
+            Data2: 0xddf3,
+            Data3: 0x4660,
+            Data4: [0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e],
+        },
+        val: ATOMIC_USIZE_INIT,
+    };
+    type ConnectEx = unsafe extern "system" fn(SOCKET, *const SOCKADDR,
+                                               c_int, PVOID, DWORD, LPDWORD,
+                                               LPOVERLAPPED) -> BOOL;
+
+    let ptr = try!(CONNECTEX.get(socket));
+    assert!(ptr != 0);
+    let connect_ex = mem::transmute::<_, ConnectEx>(ptr);
+
+    let (addr_buf, addr_len) = socket_addr_to_ptrs(addr);
+    let mut bytes_sent: DWORD = 0;
+    let r = connect_ex(socket, addr_buf, addr_len,
+                       buf.as_ptr() as *mut _,
+                       buf.len() as u32,
+                       &mut bytes_sent, overlapped);
+    if r == TRUE {
+        Ok(Some(bytes_sent as usize))
+    } else {
+        last_err()
+    }
+}
+
+impl UdpSocketExt for UdpSocket {
+    unsafe fn recv_from_overlapped(&self,
+                                   buf: &mut [u8],
+                                   addr: *mut SocketAddrBuf,
+                                   overlapped: *mut OVERLAPPED)
+                                   -> io::Result<Option<usize>> {
+        let mut buf = slice2buf(buf);
+        let mut flags = 0;
+        let mut received_bytes: DWORD = 0;
+        let r = WSARecvFrom(self.as_raw_socket(), &mut buf, 1,
+                            &mut received_bytes, &mut flags,
+                            &mut (*addr).buf as *mut _ as *mut _,
+                            &mut (*addr).len,
+                            overlapped, None);
+        cvt(r, received_bytes)
+    }
+
+    unsafe fn recv_overlapped(&self,
+                              buf: &mut [u8],
+                              overlapped: *mut OVERLAPPED)
+                              -> io::Result<Option<usize>> {
+        let mut buf = slice2buf(buf);
+        let mut flags = 0;
+        let mut received_bytes: DWORD = 0;
+        let r = WSARecv(self.as_raw_socket(), &mut buf, 1,
+                            &mut received_bytes, &mut flags,
+                            overlapped, None);
+        cvt(r, received_bytes)
+    }
+
+    unsafe fn send_to_overlapped(&self,
+                                 buf: &[u8],
+                                 addr: &SocketAddr,
+                                 overlapped: *mut OVERLAPPED)
+                                 -> io::Result<Option<usize>> {
+        let (addr_buf, addr_len) = socket_addr_to_ptrs(addr);
+        let mut buf = slice2buf(buf);
+        let mut sent_bytes = 0;
+        let r = WSASendTo(self.as_raw_socket(), &mut buf, 1,
+                          &mut sent_bytes, 0,
+                          addr_buf as *const _, addr_len,
+                          overlapped, None);
+        cvt(r, sent_bytes)
+    }
+
+    unsafe fn send_overlapped(&self,
+                              buf: &[u8],
+                              overlapped: *mut OVERLAPPED)
+                              -> io::Result<Option<usize>> {
+        let mut buf = slice2buf(buf);
+        let mut sent_bytes = 0;
+        let r = WSASend(self.as_raw_socket(), &mut buf, 1,
+                          &mut sent_bytes, 0,
+                          overlapped, None);
+        cvt(r, sent_bytes)
+    }
+
+    unsafe fn result(&self, overlapped: *mut OVERLAPPED)
+                     -> io::Result<(usize, u32)> {
+        result(self.as_raw_socket(), overlapped)
+    }
+}
+
+impl TcpBuilderExt for TcpBuilder {
+    unsafe fn connect_overlapped(&self,
+                                 addr: &SocketAddr,
+                                 buf: &[u8],
+                                 overlapped: *mut OVERLAPPED)
+                                 -> io::Result<(TcpStream, Option<usize>)> {
+        connect_overlapped(self.as_raw_socket(), addr, buf, overlapped).map(|s| {
+            (self.to_tcp_stream().unwrap(), s)
+        })
+    }
+
+    unsafe fn result(&self, overlapped: *mut OVERLAPPED)
+                     -> io::Result<(usize, u32)> {
+        result(self.as_raw_socket(), overlapped)
+    }
+}
+
+impl TcpListenerExt for TcpListener {
+    unsafe fn accept_overlapped(&self,
+                                socket: &TcpBuilder,
+                                addrs: &mut AcceptAddrsBuf,
+                                overlapped: *mut OVERLAPPED)
+                                -> io::Result<(TcpStream, bool)> {
+        static ACCEPTEX: WsaExtension = WsaExtension {
+            guid: GUID {
+                Data1: 0xb5367df1,
+                Data2: 0xcbac,
+                Data3: 0x11cf,
+                Data4: [0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92],
+            },
+            val: ATOMIC_USIZE_INIT,
+        };
+        type AcceptEx = unsafe extern "system" fn(SOCKET, SOCKET, PVOID,
+                                                  DWORD, DWORD, DWORD, LPDWORD,
+                                                  LPOVERLAPPED) -> BOOL;
+
+        let ptr = try!(ACCEPTEX.get(self.as_raw_socket()));
+        assert!(ptr != 0);
+        let accept_ex = mem::transmute::<_, AcceptEx>(ptr);
+
+        let mut bytes = 0;
+        let (a, b, c, d) = (*addrs).args();
+        let r = accept_ex(self.as_raw_socket(), socket.as_raw_socket(),
+                          a, b, c, d, &mut bytes, overlapped);
+        let succeeded = if r == TRUE {
+            true
+        } else {
+            try!(last_err());
+            false
+        };
+        // NB: this unwrap() should be guaranteed to succeed, and this is an
+        // assert that it does indeed succeed.
+        Ok((socket.to_tcp_stream().unwrap(), succeeded))
+    }
+
+    fn accept_complete(&self, socket: &TcpStream) -> io::Result<()> {
+        const SO_UPDATE_ACCEPT_CONTEXT: c_int = 0x700B;
+        let me = self.as_raw_socket();
+        let result = unsafe {
+            setsockopt(socket.as_raw_socket(),
+                       SOL_SOCKET,
+                       SO_UPDATE_ACCEPT_CONTEXT,
+                       &me as *const _ as *const _,
+                       mem::size_of_val(&me) as c_int)
+        };
+        if result == 0 {
+            Ok(())
+        } else {
+            Err(io::Error::last_os_error())
+        }
+    }
+
+    unsafe fn result(&self, overlapped: *mut OVERLAPPED)
+                     -> io::Result<(usize, u32)> {
+        result(self.as_raw_socket(), overlapped)
+    }
+}
+
+impl SocketAddrBuf {
+    /// Creates a new blank socket address buffer.
+    ///
+    /// This should be used before a call to `recv_from_overlapped` overlapped
+    /// to create an instance to pass down.
+    pub fn new() -> SocketAddrBuf {
+        SocketAddrBuf {
+            buf: unsafe { mem::zeroed() },
+            len: mem::size_of::<SOCKADDR_STORAGE>() as c_int,
+        }
+    }
+
+    /// Parses this buffer to return a standard socket address.
+    ///
+    /// This function should be called after the buffer has been filled in with
+    /// a call to `recv_from_overlapped` being completed. It will interpret the
+    /// address filled in and return the standard socket address type.
+    ///
+    /// If an error is encountered then `None` is returned.
+    pub fn to_socket_addr(&self) -> Option<SocketAddr> {
+        unsafe {
+            ptrs_to_socket_addr(&self.buf as *const _ as *const _, self.len)
+        }
+    }
+}
+
+static GETACCEPTEXSOCKADDRS: WsaExtension = WsaExtension {
+    guid: GUID {
+        Data1: 0xb5367df2,
+        Data2: 0xcbac,
+        Data3: 0x11cf,
+        Data4: [0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92],
+    },
+    val: ATOMIC_USIZE_INIT,
+};
+type GetAcceptExSockaddrs = unsafe extern "system" fn(PVOID, DWORD, DWORD, DWORD,
+                                                      *mut LPSOCKADDR, LPINT,
+                                                      *mut LPSOCKADDR, LPINT);
+
+impl AcceptAddrsBuf {
+    /// Creates a new blank buffer ready to be passed to a call to
+    /// `accept_overlapped`.
+    pub fn new() -> AcceptAddrsBuf {
+        unsafe { mem::zeroed() }
+    }
+
+    /// Parses the data contained in this address buffer, returning the parsed
+    /// result if successful.
+    ///
+    /// This function can be called after a call to `accept_overlapped` has
+    /// succeeded to parse out the data that was written in.
+    pub fn parse(&self, socket: &TcpListener) -> io::Result<AcceptAddrs> {
+        let mut ret = AcceptAddrs {
+            local: 0 as *mut _, local_len: 0,
+            remote: 0 as *mut _, remote_len: 0,
+            _data: self,
+        };
+        let ptr = try!(GETACCEPTEXSOCKADDRS.get(socket.as_raw_socket()));
+        assert!(ptr != 0);
+        unsafe {
+            let get_sockaddrs = mem::transmute::<_, GetAcceptExSockaddrs>(ptr);
+            let (a, b, c, d) = self.args();
+            get_sockaddrs(a, b, c, d,
+                          &mut ret.local, &mut ret.local_len,
+                          &mut ret.remote, &mut ret.remote_len);
+            Ok(ret)
+        }
+    }
+
+    fn args(&self) -> (PVOID, DWORD, DWORD, DWORD) {
+        let remote_offset = unsafe {
+            &(*(0 as *const AcceptAddrsBuf)).remote as *const _ as usize
+        };
+        (self as *const _ as *mut _, 0, remote_offset as DWORD,
+         (mem::size_of_val(self) - remote_offset) as DWORD)
+    }
+}
+
+impl<'a> AcceptAddrs<'a> {
+    /// Returns the local socket address contained in this buffer.
+    pub fn local(&self) -> Option<SocketAddr> {
+        unsafe { ptrs_to_socket_addr(self.local, self.local_len) }
+    }
+
+    /// Returns the remote socket address contained in this buffer.
+    pub fn remote(&self) -> Option<SocketAddr> {
+        unsafe { ptrs_to_socket_addr(self.remote, self.remote_len) }
+    }
+}
+
+impl WsaExtension {
+    fn get(&self, socket: SOCKET) -> io::Result<usize> {
+        let prev = self.val.load(Ordering::SeqCst);
+        if prev != 0 && !cfg!(debug_assertions) {
+            return Ok(prev)
+        }
+        let mut ret = 0 as usize;
+        let mut bytes = 0;
+        let r = unsafe {
+            WSAIoctl(socket, SIO_GET_EXTENSION_FUNCTION_POINTER,
+                     &self.guid as *const _ as *mut _,
+                     mem::size_of_val(&self.guid) as DWORD,
+                     &mut ret as *mut _ as *mut _,
+                     mem::size_of_val(&ret) as DWORD,
+                     &mut bytes,
+                     0 as *mut _, None)
+        };
+        cvt(r, 0).map(|_| {
+            debug_assert_eq!(bytes as usize, mem::size_of_val(&ret));
+            debug_assert!(prev == 0 || prev == ret);
+            self.val.store(ret, Ordering::SeqCst);
+            ret
+        })
+
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::net::{TcpListener, UdpSocket, TcpStream, SocketAddr};
+    use std::thread;
+    use std::io::prelude::*;
+
+    use Overlapped;
+    use iocp::CompletionPort;
+    use net::{TcpStreamExt, UdpSocketExt, SocketAddrBuf};
+    use net::{TcpBuilderExt, TcpListenerExt, AcceptAddrsBuf};
+    use net2::TcpBuilder;
+
+    fn each_ip(f: &mut FnMut(SocketAddr)) {
+        f(t!("127.0.0.1:0".parse()));
+        f(t!("[::1]:0".parse()));
+    }
+
+    #[test]
+    fn tcp_read() {
+        each_ip(&mut |addr| {
+            let l = t!(TcpListener::bind(addr));
+            let addr = t!(l.local_addr());
+            let t = thread::spawn(move || {
+                let mut a = t!(l.accept()).0;
+                t!(a.write_all(&[1, 2, 3]));
+            });
+
+            let cp = t!(CompletionPort::new(1));
+            let s = t!(TcpStream::connect(addr));
+            t!(cp.add_socket(1, &s));
+
+            let mut b = [0; 10];
+            let a = Overlapped::zero();
+            unsafe {
+                t!(s.read_overlapped(&mut b, a.raw()));
+            }
+            let status = t!(cp.get(None));
+            assert_eq!(status.bytes_transferred(), 3);
+            assert_eq!(status.token(), 1);
+            assert_eq!(status.overlapped(), a.raw());
+            assert_eq!(&b[0..3], &[1, 2, 3]);
+
+            t!(t.join());
+        })
+    }
+
+    #[test]
+    fn tcp_write() {
+        each_ip(&mut |addr| {
+            let l = t!(TcpListener::bind(addr));
+            let addr = t!(l.local_addr());
+            let t = thread::spawn(move || {
+                let mut a = t!(l.accept()).0;
+                let mut b = [0; 10];
+                let n = t!(a.read(&mut b));
+                assert_eq!(n, 3);
+                assert_eq!(&b[0..3], &[1, 2, 3]);
+            });
+
+            let cp = t!(CompletionPort::new(1));
+            let s = t!(TcpStream::connect(addr));
+            t!(cp.add_socket(1, &s));
+
+            let b = [1, 2, 3];
+            let a = Overlapped::zero();
+            unsafe {
+                t!(s.write_overlapped(&b, a.raw()));
+            }
+            let status = t!(cp.get(None));
+            assert_eq!(status.bytes_transferred(), 3);
+            assert_eq!(status.token(), 1);
+            assert_eq!(status.overlapped(), a.raw());
+
+            t!(t.join());
+        })
+    }
+
+    #[test]
+    fn tcp_connect() {
+        each_ip(&mut |addr_template| {
+            let l = t!(TcpListener::bind(addr_template));
+            let addr = t!(l.local_addr());
+            let t = thread::spawn(move || {
+                t!(l.accept());
+            });
+
+            let cp = t!(CompletionPort::new(1));
+            let builder = match addr {
+                SocketAddr::V4(..) => t!(TcpBuilder::new_v4()),
+                SocketAddr::V6(..) => t!(TcpBuilder::new_v6()),
+            };
+            t!(cp.add_socket(1, &builder));
+
+            let a = Overlapped::zero();
+            t!(builder.bind(addr_template));
+            let (s, _) = unsafe {
+                t!(builder.connect_overlapped(&addr, &[], a.raw()))
+            };
+            let status = t!(cp.get(None));
+            assert_eq!(status.bytes_transferred(), 0);
+            assert_eq!(status.token(), 1);
+            assert_eq!(status.overlapped(), a.raw());
+            t!(s.connect_complete());
+
+            t!(t.join());
+        })
+    }
+
+    #[test]
+    fn udp_recv_from() {
+        each_ip(&mut |addr| {
+            let a = t!(UdpSocket::bind(addr));
+            let b = t!(UdpSocket::bind(addr));
+            let a_addr = t!(a.local_addr());
+            let b_addr = t!(b.local_addr());
+            let t = thread::spawn(move || {
+                t!(a.send_to(&[1, 2, 3], b_addr));
+            });
+
+            let cp = t!(CompletionPort::new(1));
+            t!(cp.add_socket(1, &b));
+
+            let mut buf = [0; 10];
+            let a = Overlapped::zero();
+            let mut addr = SocketAddrBuf::new();
+            unsafe {
+                t!(b.recv_from_overlapped(&mut buf, &mut addr, a.raw()));
+            }
+            let status = t!(cp.get(None));
+            assert_eq!(status.bytes_transferred(), 3);
+            assert_eq!(status.token(), 1);
+            assert_eq!(status.overlapped(), a.raw());
+            assert_eq!(&buf[..3], &[1, 2, 3]);
+            assert_eq!(addr.to_socket_addr(), Some(a_addr));
+
+            t!(t.join());
+        })
+    }
+
+    #[test]
+    fn udp_recv() {
+        each_ip(&mut |addr| {
+            let a = t!(UdpSocket::bind(addr));
+            let b = t!(UdpSocket::bind(addr));
+            let a_addr = t!(a.local_addr());
+            let b_addr = t!(b.local_addr());
+            assert!(b.connect(a_addr).is_ok());
+            assert!(a.connect(b_addr).is_ok());
+            let t = thread::spawn(move || {
+                t!(a.send_to(&[1, 2, 3], b_addr));
+            });
+
+            let cp = t!(CompletionPort::new(1));
+            t!(cp.add_socket(1, &b));
+
+            let mut buf = [0; 10];
+            let a = Overlapped::zero();
+            unsafe {
+                t!(b.recv_overlapped(&mut buf, a.raw()));
+            }
+            let status = t!(cp.get(None));
+            assert_eq!(status.bytes_transferred(), 3);
+            assert_eq!(status.token(), 1);
+            assert_eq!(status.overlapped(), a.raw());
+            assert_eq!(&buf[..3], &[1, 2, 3]);
+
+            t!(t.join());
+        })
+    }
+
+    #[test]
+    fn udp_send_to() {
+        each_ip(&mut |addr| {
+            let a = t!(UdpSocket::bind(addr));
+            let b = t!(UdpSocket::bind(addr));
+            let a_addr = t!(a.local_addr());
+            let b_addr = t!(b.local_addr());
+            let t = thread::spawn(move || {
+                let mut b = [0; 100];
+                let (n, addr) = t!(a.recv_from(&mut b));
+                assert_eq!(n, 3);
+                assert_eq!(addr, b_addr);
+                assert_eq!(&b[..3], &[1, 2, 3]);
+            });
+
+            let cp = t!(CompletionPort::new(1));
+            t!(cp.add_socket(1, &b));
+
+            let a = Overlapped::zero();
+            unsafe {
+                t!(b.send_to_overlapped(&[1, 2, 3], &a_addr, a.raw()));
+            }
+            let status = t!(cp.get(None));
+            assert_eq!(status.bytes_transferred(), 3);
+            assert_eq!(status.token(), 1);
+            assert_eq!(status.overlapped(), a.raw());
+
+            t!(t.join());
+        })
+    }
+
+    #[test]
+    fn udp_send() {
+        each_ip(&mut |addr| {
+            let a = t!(UdpSocket::bind(addr));
+            let b = t!(UdpSocket::bind(addr));
+            let a_addr = t!(a.local_addr());
+            let b_addr = t!(b.local_addr());
+            assert!(b.connect(a_addr).is_ok());
+            assert!(a.connect(b_addr).is_ok());
+            let t = thread::spawn(move || {
+                let mut b = [0; 100];
+                let (n, addr) = t!(a.recv_from(&mut b));
+                assert_eq!(n, 3);
+                assert_eq!(addr, b_addr);
+                assert_eq!(&b[..3], &[1, 2, 3]);
+            });
+
+            let cp = t!(CompletionPort::new(1));
+            t!(cp.add_socket(1, &b));
+
+            let a = Overlapped::zero();
+            unsafe {
+                t!(b.send_overlapped(&[1, 2, 3], a.raw()));
+            }
+            let status = t!(cp.get(None));
+            assert_eq!(status.bytes_transferred(), 3);
+            assert_eq!(status.token(), 1);
+            assert_eq!(status.overlapped(), a.raw());
+
+            t!(t.join());
+        })
+    }
+
+    #[test]
+    fn tcp_accept() {
+        each_ip(&mut |addr_template| {
+            let l = t!(TcpListener::bind(addr_template));
+            let addr = t!(l.local_addr());
+            let t = thread::spawn(move || {
+                let socket = t!(TcpStream::connect(addr));
+                (socket.local_addr().unwrap(), socket.peer_addr().unwrap())
+            });
+
+            let cp = t!(CompletionPort::new(1));
+            let builder = match addr {
+                SocketAddr::V4(..) => t!(TcpBuilder::new_v4()),
+                SocketAddr::V6(..) => t!(TcpBuilder::new_v6()),
+            };
+            t!(cp.add_socket(1, &l));
+
+            let a = Overlapped::zero();
+            let mut addrs = AcceptAddrsBuf::new();
+            let (s, _) = unsafe {
+                t!(l.accept_overlapped(&builder, &mut addrs, a.raw()))
+            };
+            let status = t!(cp.get(None));
+            assert_eq!(status.bytes_transferred(), 0);
+            assert_eq!(status.token(), 1);
+            assert_eq!(status.overlapped(), a.raw());
+            t!(l.accept_complete(&s));
+
+            let (remote, local) = t!(t.join());
+            let addrs = addrs.parse(&l).unwrap();
+            assert_eq!(addrs.local(), Some(local));
+            assert_eq!(addrs.remote(), Some(remote));
+        })
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/miow/src/overlapped.rs
@@ -0,0 +1,66 @@
+use std::mem;
+
+use winapi::*;
+
+/// A wrapper around `OVERLAPPED` to provide "rustic" accessors and
+/// initializers.
+#[derive(Debug)]
+pub struct Overlapped(OVERLAPPED);
+
+unsafe impl Send for Overlapped {}
+unsafe impl Sync for Overlapped {}
+
+impl Overlapped {
+    /// Creates a new zeroed out instance of an overlapped I/O tracking state.
+    ///
+    /// This is suitable for passing to methods which will then later get
+    /// notified via an I/O Completion Port.
+    pub fn zero() -> Overlapped {
+        Overlapped(unsafe { mem::zeroed() })
+    }
+
+    /// Creates a new `Overlapped` function pointer from the underlying
+    /// `OVERLAPPED`, wrapping in the "rusty" wrapper for working with
+    /// accessors.
+    ///
+    /// # Unsafety
+    ///
+    /// This function doesn't validate `ptr` nor the lifetime of the returned
+    /// pointer at all, it's recommended to use this method with extreme
+    /// caution.
+    pub unsafe fn from_raw<'a>(ptr: *mut OVERLAPPED) -> &'a mut Overlapped {
+        &mut *(ptr as *mut Overlapped)
+    }
+
+    /// Gain access to the raw underlying data
+    pub fn raw(&self) -> *mut OVERLAPPED {
+        &self.0 as *const _ as *mut _
+    }
+
+    /// Sets the offset inside this overlapped structure.
+    ///
+    /// Note that for I/O operations in general this only has meaning for I/O
+    /// handles that are on a seeking device that supports the concept of an
+    /// offset.
+    pub fn set_offset(&mut self, offset: u64) {
+        self.0.Offset = offset as u32;
+        self.0.OffsetHigh = (offset >> 32) as u32;
+    }
+
+    /// Reads the offset inside this overlapped structure.
+    pub fn offset(&self) -> u64 {
+        (self.0.Offset as u64) | ((self.0.OffsetHigh as u64) << 32)
+    }
+
+    /// Sets the `hEvent` field of this structure.
+    ///
+    /// The event specified can be null.
+    pub fn set_event(&mut self, event: HANDLE) {
+        self.0.hEvent = event;
+    }
+
+    /// Reads the `hEvent` field of this structure, may return null.
+    pub fn event(&self) -> HANDLE {
+        self.0.hEvent
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/miow/src/pipe.rs
@@ -0,0 +1,611 @@
+//! Named pipes
+
+use std::ffi::OsStr;
+use std::fs::{OpenOptions, File};
+use std::io::prelude::*;
+use std::io;
+use std::os::windows::ffi::*;
+use std::os::windows::io::*;
+use std::time::Duration;
+
+use winapi::*;
+use kernel32::*;
+use handle::Handle;
+
+/// Readable half of an anonymous pipe.
+#[derive(Debug)]
+pub struct AnonRead(Handle);
+
+/// Writable half of an anonymous pipe.
+#[derive(Debug)]
+pub struct AnonWrite(Handle);
+
+/// A named pipe that can accept connections.
+#[derive(Debug)]
+pub struct NamedPipe(Handle);
+
+/// A builder structure for creating a new named pipe.
+#[derive(Debug)]
+pub struct NamedPipeBuilder {
+    name: Vec<u16>,
+    dwOpenMode: DWORD,
+    dwPipeMode: DWORD,
+    nMaxInstances: DWORD,
+    nOutBufferSize: DWORD,
+    nInBufferSize: DWORD,
+    nDefaultTimeOut: DWORD,
+}
+
+/// Creates a new anonymous in-memory pipe, returning the read/write ends of the
+/// pipe.
+///
+/// The buffer size for this pipe may also be specified, but the system will
+/// normally use this as a suggestion and it's not guaranteed that the buffer
+/// will be precisely this size.
+pub fn anonymous(buffer_size: u32) -> io::Result<(AnonRead, AnonWrite)> {
+    let mut read = 0 as HANDLE;
+    let mut write = 0 as HANDLE;
+    try!(::cvt(unsafe {
+        CreatePipe(&mut read, &mut write, 0 as *mut _, buffer_size)
+    }));
+    Ok((AnonRead(Handle::new(read)), AnonWrite(Handle::new(write))))
+}
+
+impl Read for AnonRead {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
+}
+impl<'a> Read for &'a AnonRead {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
+}
+
+impl AsRawHandle for AnonRead {
+    fn as_raw_handle(&self) -> HANDLE { self.0.raw() }
+}
+impl FromRawHandle for AnonRead {
+    unsafe fn from_raw_handle(handle: HANDLE) -> AnonRead {
+        AnonRead(Handle::new(handle))
+    }
+}
+impl IntoRawHandle for AnonRead {
+    fn into_raw_handle(self) -> HANDLE { self.0.into_raw() }
+}
+
+impl Write for AnonWrite {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
+    fn flush(&mut self) -> io::Result<()> { Ok(()) }
+}
+impl<'a> Write for &'a AnonWrite {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
+    fn flush(&mut self) -> io::Result<()> { Ok(()) }
+}
+
+impl AsRawHandle for AnonWrite {
+    fn as_raw_handle(&self) -> HANDLE { self.0.raw() }
+}
+impl FromRawHandle for AnonWrite {
+    unsafe fn from_raw_handle(handle: HANDLE) -> AnonWrite {
+        AnonWrite(Handle::new(handle))
+    }
+}
+impl IntoRawHandle for AnonWrite {
+    fn into_raw_handle(self) -> HANDLE { self.0.into_raw() }
+}
+
+/// A convenience function to connect to a named pipe.
+///
+/// This function will block the calling process until it can connect to the
+/// pipe server specified by `addr`. This will use `NamedPipe::wait` internally
+/// to block until it can connect.
+pub fn connect<A: AsRef<OsStr>>(addr: A) -> io::Result<File> {
+    _connect(addr.as_ref())
+}
+
+fn _connect(addr: &OsStr) -> io::Result<File> {
+    let mut r = OpenOptions::new();
+    let mut w = OpenOptions::new();
+    let mut rw = OpenOptions::new();
+    r.read(true);
+    w.write(true);
+    rw.read(true).write(true);
+    loop {
+        let res = rw.open(addr).or_else(|_| r.open(addr))
+                               .or_else(|_| w.open(addr));
+        match res {
+            Ok(f) => return Ok(f),
+            Err(ref e) if e.raw_os_error() == Some(ERROR_PIPE_BUSY as i32)
+                => {}
+            Err(e) => return Err(e),
+        }
+
+        try!(NamedPipe::wait(addr, Some(Duration::new(20, 0))));
+    }
+}
+
+impl NamedPipe {
+    /// Creates a new initial named pipe.
+    ///
+    /// This function is equivalent to:
+    ///
+    /// ```
+    /// use miow::pipe::NamedPipeBuilder;
+    ///
+    /// # let addr = "foo";
+    /// NamedPipeBuilder::new(addr)
+    ///                  .first(true)
+    ///                  .inbound(true)
+    ///                  .outbound(true)
+    ///                  .out_buffer_size(65536)
+    ///                  .in_buffer_size(65536)
+    ///                  .create();
+    /// ```
+    pub fn new<A: AsRef<OsStr>>(addr: A) -> io::Result<NamedPipe> {
+        NamedPipeBuilder::new(addr).create()
+    }
+
+    /// Waits until either a time-out interval elapses or an instance of the
+    /// specified named pipe is available for connection.
+    ///
+    /// If this function succeeds the process can create a `File` to connect to
+    /// the named pipe.
+    pub fn wait<A: AsRef<OsStr>>(addr: A, timeout: Option<Duration>)
+                                 -> io::Result<()> {
+        NamedPipe::_wait(addr.as_ref(), timeout)
+    }
+
+    fn _wait(addr: &OsStr, timeout: Option<Duration>) -> io::Result<()> {
+        let addr = addr.encode_wide().chain(Some(0)).collect::<Vec<_>>();
+        let timeout = ::dur2ms(timeout);
+        ::cvt(unsafe {
+            WaitNamedPipeW(addr.as_ptr(), timeout)
+        }).map(|_| ())
+    }
+
+    /// Connects this named pipe to a client, blocking until one becomes
+    /// available.
+    ///
+    /// This function will call the `ConnectNamedPipe` function to await for a
+    /// client to connect. This can be called immediately after the pipe is
+    /// created, or after it has been disconnected from a previous client.
+    pub fn connect(&self) -> io::Result<()> {
+        match ::cvt(unsafe { ConnectNamedPipe(self.0.raw(), 0 as *mut _) }) {
+            Ok(_) => Ok(()),
+            Err(ref e) if e.raw_os_error() == Some(ERROR_PIPE_CONNECTED as i32)
+                => Ok(()),
+            Err(e) => Err(e),
+        }
+    }
+
+    /// Issue a connection request with the specified overlapped operation.
+    ///
+    /// This function will issue a request to connect a client to this server,
+    /// returning immediately after starting the overlapped operation.
+    ///
+    /// If this function immediately succeeds then `Ok(true)` is returned. If
+    /// the overlapped operation is enqueued and pending, then `Ok(false)` is
+    /// returned. Otherwise an error is returned indicating what went wrong.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe because the kernel requires that the
+    /// `overlapped` pointer is valid until the end of the I/O operation. The
+    /// kernel also requires that `overlapped` is unique for this I/O operation
+    /// and is not in use for any other I/O.
+    ///
+    /// To safely use this function callers must ensure that this pointer is
+    /// valid until the I/O operation is completed, typically via completion
+    /// ports and waiting to receive the completion notification on the port.
+    pub unsafe fn connect_overlapped(&self, overlapped: *mut OVERLAPPED)
+                                     -> io::Result<bool> {
+        match ::cvt(ConnectNamedPipe(self.0.raw(), overlapped)) {
+            Ok(_) => Ok(true),
+            Err(ref e) if e.raw_os_error() == Some(ERROR_PIPE_CONNECTED as i32)
+                => Ok(true),
+            Err(ref e) if e.raw_os_error() == Some(ERROR_IO_PENDING as i32)
+                => Ok(false),
+            Err(e) => Err(e),
+        }
+    }
+
+    /// Disconnects this named pipe from any connected client.
+    pub fn disconnect(&self) -> io::Result<()> {
+        ::cvt(unsafe {
+            DisconnectNamedPipe(self.0.raw())
+        }).map(|_| ())
+    }
+
+    /// Issues an overlapped read operation to occur on this pipe.
+    ///
+    /// This function will issue an asynchronous read to occur in an overlapped
+    /// fashion, returning immediately. The `buf` provided will be filled in
+    /// with data and the request is tracked by the `overlapped` function
+    /// provided.
+    ///
+    /// If the operation succeeds immediately, `Ok(Some(n))` is returned where
+    /// `n` is the number of bytes read. If an asynchronous operation is
+    /// enqueued, then `Ok(None)` is returned. Otherwise if an error occurred
+    /// it is returned.
+    ///
+    /// When this operation completes (or if it completes immediately), another
+    /// mechanism must be used to learn how many bytes were transferred (such as
+    /// looking at the filed in the IOCP status message).
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe because the kernel requires that the `buf` and
+    /// `overlapped` pointers to be valid until the end of the I/O operation.
+    /// The kernel also requires that `overlapped` is unique for this I/O
+    /// operation and is not in use for any other I/O.
+    ///
+    /// To safely use this function callers must ensure that the pointers are
+    /// valid until the I/O operation is completed, typically via completion
+    /// ports and waiting to receive the completion notification on the port.
+    pub unsafe fn read_overlapped(&self,
+                                  buf: &mut [u8],
+                                  overlapped: *mut OVERLAPPED)
+                                  -> io::Result<Option<usize>> {
+        self.0.read_overlapped(buf, overlapped)
+    }
+
+    /// Issues an overlapped write operation to occur on this pipe.
+    ///
+    /// This function will issue an asynchronous write to occur in an overlapped
+    /// fashion, returning immediately. The `buf` provided will be filled in
+    /// with data and the request is tracked by the `overlapped` function
+    /// provided.
+    ///
+    /// If the operation succeeds immediately, `Ok(Some(n))` is returned where
+    /// `n` is the number of bytes written. If an asynchronous operation is
+    /// enqueued, then `Ok(None)` is returned. Otherwise if an error occurred
+    /// it is returned.
+    ///
+    /// When this operation completes (or if it completes immediately), another
+    /// mechanism must be used to learn how many bytes were transferred (such as
+    /// looking at the filed in the IOCP status message).
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe because the kernel requires that the `buf` and
+    /// `overlapped` pointers to be valid until the end of the I/O operation.
+    /// The kernel also requires that `overlapped` is unique for this I/O
+    /// operation and is not in use for any other I/O.
+    ///
+    /// To safely use this function callers must ensure that the pointers are
+    /// valid until the I/O operation is completed, typically via completion
+    /// ports and waiting to receive the completion notification on the port.
+    pub unsafe fn write_overlapped(&self,
+                                   buf: &[u8],
+                                   overlapped: *mut OVERLAPPED)
+                                   -> io::Result<Option<usize>> {
+        self.0.write_overlapped(buf, overlapped)
+    }
+
+    /// Calls the `GetOverlappedResult` function to get the result of an
+    /// overlapped operation for this handle.
+    ///
+    /// This function takes the `OVERLAPPED` argument which must have been used
+    /// to initiate an overlapped I/O operation, and returns either the
+    /// successful number of bytes transferred during the operation or an error
+    /// if one occurred.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe as `overlapped` must have previously been used
+    /// to execute an operation for this handle, and it must also be a valid
+    /// pointer to an `Overlapped` instance.
+    ///
+    /// # Panics
+    ///
+    /// This function will panic
+    pub unsafe fn result(&self, overlapped: *mut OVERLAPPED)
+                         -> io::Result<usize> {
+        let mut transferred = 0;
+        let r = GetOverlappedResult(self.0.raw(),
+                                    overlapped,
+                                    &mut transferred,
+                                    FALSE);
+        if r == 0 {
+            Err(io::Error::last_os_error())
+        } else {
+            Ok(transferred as usize)
+        }
+    }
+}
+
+impl Read for NamedPipe {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
+}
+impl<'a> Read for &'a NamedPipe {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
+}
+
+impl Write for NamedPipe {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
+    fn flush(&mut self) -> io::Result<()> {
+        <&NamedPipe as Write>::flush(&mut &*self)
+    }
+}
+impl<'a> Write for &'a NamedPipe {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
+    fn flush(&mut self) -> io::Result<()> {
+        ::cvt(unsafe { FlushFileBuffers(self.0.raw()) }).map(|_| ())
+    }
+}
+
+impl AsRawHandle for NamedPipe {
+    fn as_raw_handle(&self) -> HANDLE { self.0.raw() }
+}
+impl FromRawHandle for NamedPipe {
+    unsafe fn from_raw_handle(handle: HANDLE) -> NamedPipe {
+        NamedPipe(Handle::new(handle))
+    }
+}
+impl IntoRawHandle for NamedPipe {
+    fn into_raw_handle(self) -> HANDLE { self.0.into_raw() }
+}
+
+fn flag(slot: &mut DWORD, on: bool, val: DWORD) {
+    if on {
+        *slot |= val;
+    } else {
+        *slot &= !val;
+    }
+}
+
+impl NamedPipeBuilder {
+    /// Creates a new named pipe builder with the default settings.
+    pub fn new<A: AsRef<OsStr>>(addr: A) -> NamedPipeBuilder {
+        NamedPipeBuilder {
+            name: addr.as_ref().encode_wide().chain(Some(0)).collect(),
+            dwOpenMode: PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE |
+                        FILE_FLAG_OVERLAPPED,
+            dwPipeMode: PIPE_TYPE_BYTE,
+            nMaxInstances: PIPE_UNLIMITED_INSTANCES,
+            nOutBufferSize: 65536,
+            nInBufferSize: 65536,
+            nDefaultTimeOut: 0,
+        }
+    }
+
+    /// Indicates whether data is allowed to flow from the client to the server.
+    pub fn inbound(&mut self, allowed: bool) -> &mut Self {
+        flag(&mut self.dwOpenMode, allowed, PIPE_ACCESS_INBOUND);
+        self
+    }
+
+    /// Indicates whether data is allowed to flow from the server to the client.
+    pub fn outbound(&mut self, allowed: bool) -> &mut Self {
+        flag(&mut self.dwOpenMode, allowed, PIPE_ACCESS_OUTBOUND);
+        self
+    }
+
+    /// Indicates that this pipe must be the first instance.
+    ///
+    /// If set to true, then creation will fail if there's already an instance
+    /// elsewhere.
+    pub fn first(&mut self, first: bool) -> &mut Self {
+        flag(&mut self.dwOpenMode, first, FILE_FLAG_FIRST_PIPE_INSTANCE);
+        self
+    }
+
+    /// Indicates whether this server can accept remote clients or not.
+    pub fn accept_remote(&mut self, accept: bool) -> &mut Self {
+        flag(&mut self.dwPipeMode, !accept, PIPE_REJECT_REMOTE_CLIENTS);
+        self
+    }
+
+    /// Specifies the maximum number of instances of the server pipe that are
+    /// allowed.
+    ///
+    /// The first instance of a pipe can specify this value. A value of 255
+    /// indicates that there is no limit to the number of instances.
+    pub fn max_instances(&mut self, instances: u8) -> &mut Self {
+        self.nMaxInstances = instances as DWORD;
+        self
+    }
+
+    /// Specifies the number of bytes to reserver for the output buffer
+    pub fn out_buffer_size(&mut self, buffer: u32) -> &mut Self {
+        self.nOutBufferSize = buffer as DWORD;
+        self
+    }
+
+    /// Specifies the number of bytes to reserver for the input buffer
+    pub fn in_buffer_size(&mut self, buffer: u32) -> &mut Self {
+        self.nInBufferSize = buffer as DWORD;
+        self
+    }
+
+    /// Using the options in this builder, attempt to create a new named pipe.
+    ///
+    /// This function will call the `CreateNamedPipe` function and return the
+    /// result.
+    pub fn create(&mut self) -> io::Result<NamedPipe> {
+        let h = unsafe {
+            CreateNamedPipeW(self.name.as_ptr(),
+                             self.dwOpenMode, self.dwPipeMode,
+                             self.nMaxInstances, self.nOutBufferSize,
+                             self.nInBufferSize, self.nDefaultTimeOut,
+                             0 as *mut _)
+        };
+        if h == INVALID_HANDLE_VALUE {
+            Err(io::Error::last_os_error())
+        } else {
+            Ok(NamedPipe(Handle::new(h)))
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::fs::{File, OpenOptions};
+    use std::io::prelude::*;
+    use std::sync::mpsc::channel;
+    use std::thread;
+    use std::time::Duration;
+
+    use rand::{thread_rng, Rng};
+
+    use super::{anonymous, NamedPipe, NamedPipeBuilder};
+    use iocp::CompletionPort;
+    use Overlapped;
+
+    fn name() -> String {
+        let name = thread_rng().gen_ascii_chars().take(30).collect::<String>();
+        format!(r"\\.\pipe\{}", name)
+    }
+
+    #[test]
+    fn anon() {
+        let (mut read, mut write) = t!(anonymous(256));
+        assert_eq!(t!(write.write(&[1, 2, 3])), 3);
+        let mut b = [0; 10];
+        assert_eq!(t!(read.read(&mut b)), 3);
+        assert_eq!(&b[..3], &[1, 2, 3]);
+    }
+
+    #[test]
+    fn named_not_first() {
+        let name = name();
+        let _a = t!(NamedPipe::new(&name));
+        assert!(NamedPipe::new(&name).is_err());
+
+        t!(NamedPipeBuilder::new(&name).first(false).create());
+    }
+
+    #[test]
+    fn named_connect() {
+        let name = name();
+        let a = t!(NamedPipe::new(&name));
+
+        let t = thread::spawn(move || {
+            t!(File::open(name));
+        });
+
+        t!(a.connect());
+        t!(a.disconnect());
+        t!(t.join());
+    }
+
+    #[test]
+    fn named_wait() {
+        let name = name();
+        let a = t!(NamedPipe::new(&name));
+
+        let (tx, rx) = channel();
+        let t = thread::spawn(move || {
+            t!(NamedPipe::wait(&name, None));
+            t!(File::open(&name));
+            assert!(NamedPipe::wait(&name, Some(Duration::from_millis(1))).is_err());
+            t!(tx.send(()));
+        });
+
+        t!(a.connect());
+        t!(rx.recv());
+        t!(a.disconnect());
+        t!(t.join());
+    }
+
+    #[test]
+    fn named_connect_overlapped() {
+        let name = name();
+        let a = t!(NamedPipe::new(&name));
+
+        let t = thread::spawn(move || {
+            t!(File::open(name));
+        });
+
+        let cp = t!(CompletionPort::new(1));
+        t!(cp.add_handle(2, &a));
+
+        let over = Overlapped::zero();
+        unsafe {
+            t!(a.connect_overlapped(over.raw()));
+        }
+
+        let status = t!(cp.get(None));
+        assert_eq!(status.bytes_transferred(), 0);
+        assert_eq!(status.token(), 2);
+        assert_eq!(status.overlapped(), over.raw());
+        t!(t.join());
+    }
+
+    #[test]
+    fn named_read_write() {
+        let name = name();
+        let mut a = t!(NamedPipe::new(&name));
+
+        let t = thread::spawn(move || {
+            let mut f = t!(OpenOptions::new().read(true).write(true).open(name));
+            t!(f.write_all(&[1, 2, 3]));
+            let mut b = [0; 10];
+            assert_eq!(t!(f.read(&mut b)), 3);
+            assert_eq!(&b[..3], &[1, 2, 3]);
+        });
+
+        t!(a.connect());
+        let mut b = [0; 10];
+        assert_eq!(t!(a.read(&mut b)), 3);
+        assert_eq!(&b[..3], &[1, 2, 3]);
+        t!(a.write_all(&[1, 2, 3]));
+        t!(a.flush());
+        t!(a.disconnect());
+        t!(t.join());
+    }
+
+    #[test]
+    fn named_read_overlapped() {
+        let name = name();
+        let a = t!(NamedPipe::new(&name));
+
+        let t = thread::spawn(move || {
+            let mut f = t!(File::create(name));
+            t!(f.write_all(&[1, 2, 3]));
+        });
+
+        let cp = t!(CompletionPort::new(1));
+        t!(cp.add_handle(3, &a));
+        t!(a.connect());
+
+        let mut b = [0; 10];
+        let over = Overlapped::zero();
+        unsafe {
+            t!(a.read_overlapped(&mut b, over.raw()));
+        }
+        let status = t!(cp.get(None));
+        assert_eq!(status.bytes_transferred(), 3);
+        assert_eq!(status.token(), 3);
+        assert_eq!(status.overlapped(), over.raw());
+        assert_eq!(&b[..3], &[1, 2, 3]);
+
+        t!(t.join());
+    }
+
+    #[test]
+    fn named_write_overlapped() {
+        let name = name();
+        let a = t!(NamedPipe::new(&name));
+
+        let t = thread::spawn(move || {
+            let mut f = t!(super::connect(name));
+            let mut b = [0; 10];
+            assert_eq!(t!(f.read(&mut b)), 3);
+            assert_eq!(&b[..3], &[1, 2, 3])
+        });
+
+        let cp = t!(CompletionPort::new(1));
+        t!(cp.add_handle(3, &a));
+        t!(a.connect());
+
+        let over = Overlapped::zero();
+        unsafe {
+            t!(a.write_overlapped(&[1, 2, 3], over.raw()));
+        }
+
+        let status = t!(cp.get(None));
+        assert_eq!(status.bytes_transferred(), 3);
+        assert_eq!(status.token(), 3);
+        assert_eq!(status.overlapped(), over.raw());
+
+        t!(t.join());
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/net2/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"4c3bd4917e81d86c9d1b9783e5bfaf690f2f87ac8a53d4518fab5c57851d74a5","Cargo.toml":"71b916e2e9121e4d1ddd49750b04ed92cf292eb94872c5576deed51fe1a540b6","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"c367926adcb26dd48a679ba370b127efd37fc7a51354b3c9176f0576f2efb17b","appveyor.yml":"6e3173d907ccfa65e289c99042cb29d4a23b9d1f4ec5bf7afa6c0d65365bab54","src/ext.rs":"0b5d073592fc0720b3ca9f8821c79f3f7ca0fbb62e5ca618a5c5d6daac506568","src/lib.rs":"c8eedd4215f5a71f7faf4117c6c65b766bfecb7480013937b548d2310eda7d42","src/socket.rs":"a76f72198e33de37b7cf46e7ecf03b1f5c29a20174fd189e0cb97a60975d15a9","src/sys/unix/impls.rs":"05f123226e8fe7559317d50864021650b2455d25d01a9aff1c65c01ae26cf4ef","src/sys/unix/mod.rs":"1ac3a75714fd7a5ad11d9b97a25e2dbb6a0fa6db529f2752a0d83ff0fc212eaf","src/sys/windows/impls.rs":"5e8824f5477184a57e79809a0ca8c00db75ba230648d321aec44019cc9c1a362","src/sys/windows/mod.rs":"de6896d64217816719c8b974fd2c7ba78379edcd6e33ae33ea8abe2d19b6e68d","src/tcp.rs":"0bebf5cca75714151de30c8f2d7697ca519c57da065e93ba81796bce04673f8d","src/udp.rs":"8af5a55a4ae5e4120ffe18dcc4dc24072e18da34bf3591a02b18653e5d3e8ac8","src/unix.rs":"fe9cdbd75ef2e1fafc128d1abb5f32500eaf0b674aa618d837e06ab1d0dc6687","src/utils.rs":"d31de5333a6fa2f5c99b64cc937be596888d9863264632e6bc6b36b30197fa5b","tests/all.rs":"12cb4616c842f655ece1b477664d41821f95b3051053da641b1d85026ee18274"},"package":"3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09"}
\ No newline at end of file
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/third_party/rust/net2/.travis.yml
@@ -0,0 +1,31 @@
+language: rust
+rust:
+  - stable
+  - beta
+  - nightly
+sudo: false
+before_script:
+  - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
+script:
+  - if [ "$TRAVIS_RUST_VERSION" = "1.1.0" ]; then
+      cargo test --no-default-features;
+    else
+      cargo test;
+    fi
+  - if [ "$TRAVIS_RUST_VERSION" = "nightly" ]; then
+      cargo test --features nightly;
+      cargo doc --features nightly --no-deps;
+    fi
+  - rustdoc --test README.md -L target/debug -L target/debug/deps
+after_success:
+  - travis-cargo --only nightly doc-upload
+notifications:
+  email:
+    on_success: never
+env:
+  global:
+    secure: "n7C4SSdi9Q1WcPxc9BKQi/vhPhhxCfK/ljqG0l8PpNhkJ1BzFgb/0O4zA2W1/JzHxp0VB7rGwRCTSZkePvH1ycZuNtIezFc2HktElpRGwmo8X2OHp2+GLkTKozjhV0qZho+XoQnB0zgZRAdTq+MSN2EpTUKsaNvZwrTK90MprUPKU06Hvq93oEWmDh0jyKee0LlMezS6ihTgNk43zIa6bNumIWoaUM9ePnN7IvKSnoiynKjrBU52GPF5cWKih35mTXNxXW89Ht2h1NhIAHwmUpNfyOsBb2LOfvathVitfqk81R6+1qWzFyWSHdFoDAM0HHs8sySFK3P2YVcAp4tNIBw29oAtCpSGK6XeDyxmEU9VAq2H7DzEaBnkZM5A4oNnJWsValBmY+8m21OwV/XRed+eiqg5WUfnjeEoBn/5BJxMsc+kkVztS1Yos1meHZazTIaSpICxJ8fieHnzTOKD3wKgHwXSQaCAQHAErM301DRlChkXj61txDCmLVrU4qVRSMrAQQFPUBeploNaQtvCr/JI7huOhw5A6DphnGH8bbNivwATuUnbvQRJF+VGU3yOkJieJAQzArjGQ1A+qMds+DKlfFH/mPMxQcKv7bEE7cTZ3DY8ZzJfMzsh6YIa/YP0hpDZ5z4tJaeEXRyNVPEAwMGk4pCITP949WaTs97XOpM="
+
+os:
+  - linux
+  - osx
new file mode 100644
--- /dev/null
+++ b/third_party/rust/net2/Cargo.toml
@@ -0,0 +1,47 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g. crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+name = "net2"
+version = "0.2.31"
+authors = ["Alex Crichton <alex@alexcrichton.com>"]
+description = "Extensions to the standard library's networking types as proposed in RFC 1158.\n"
+homepage = "https://github.com/rust-lang-nursery/net2-rs"
+documentation = "https://doc.rust-lang.org/net2-rs/"
+readme = "README.md"
+license = "MIT/Apache-2.0"
+repository = "https://github.com/rust-lang-nursery/net2-rs"
+[dependencies.cfg-if]
+version = "0.1"
+
+[features]
+nightly = []
+default = ["duration"]
+duration = []
+[target.i686-unknown-linux-gnu.dependencies.libc]
+version = "0.2.16"
+[target.x86_64-unknown-linux-gnu.dependencies.libc]
+version = "0.2.16"
+[target.i686-apple-darwin.dependencies.libc]
+version = "0.2.16"
+[target.x86_64-apple-darwin.dependencies.libc]
+version = "0.2.16"
+[target."cfg(windows)".dependencies.kernel32-sys]
+version = "0.2"
+
+[target."cfg(windows)".dependencies.winapi]
+version = "0.2"
+
+[target."cfg(windows)".dependencies.ws2_32-sys]
+version = "0.2"
+[target."cfg(unix)".dependencies.libc]
+version = "0.2.16"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/net2/LICENSE-APACHE
@@ -0,0 +1,201 @@
+                              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.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/net2/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2014 The Rust Project Developers
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/net2/README.md
@@ -0,0 +1,26 @@
+# net2
+
+[![Build Status](https://travis-ci.org/rust-lang-nursery/net2-rs.svg?branch=master)](https://travis-ci.org/rust-lang-nursery/net2-rs)
+[![Build status](https://ci.appveyor.com/api/projects/status/ns78f02jt2uvd2lp?svg=true)](https://ci.appveyor.com/project/alexcrichton/net2-rs)
+
+[Documentation](https://doc.rust-lang.org/net2-rs/)
+
+Extensions to the standard library's networking types, proposed in [RFC
+1158][rfc].
+
+
+[rfc]: https://github.com/alexcrichton/rfcs/blob/net2.1/text/0000-io-net-2.1.md
+
+```toml
+# Cargo.toml
+[dependencies]
+net2 = "0.2"
+```
+
+# License
+
+`net2-rs` is primarily distributed under the terms of both the MIT license and
+the Apache License (Version 2.0), with portions covered by various BSD-like
+licenses.
+
+See LICENSE-APACHE, and LICENSE-MIT for details.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/net2/appveyor.yml
@@ -0,0 +1,17 @@
+environment:
+  matrix:
+  - TARGET: x86_64-pc-windows-msvc
+  - TARGET: i686-pc-windows-msvc
+  - TARGET: i686-pc-windows-gnu
+install:
+  - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe"
+  - rust-nightly-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
+  - SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin
+  - SET PATH=%PATH%;C:\MinGW\bin
+  - rustc -V
+  - cargo -V
+
+build: false
+
+test_script:
+  - cargo test --verbose --features nightly --target %TARGET%
new file mode 100644
--- /dev/null
+++ b/third_party/rust/net2/src/ext.rs
@@ -0,0 +1,1308 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(bad_style, dead_code)]
+
+use std::io;
+use std::mem;
+use std::net::{TcpStream, TcpListener, UdpSocket, Ipv4Addr, Ipv6Addr};
+use std::net::ToSocketAddrs;
+
+use {TcpBuilder, UdpBuilder, FromInner};
+use sys;
+use socket;
+
+cfg_if! {
+    if #[cfg(any(target_os = "dragonfly",
+                 target_os = "freebsd",
+                 target_os = "ios",
+                 target_os = "macos",
+                 target_os = "netbsd",
+                 target_os = "openbsd",
+                 target_os = "solaris",
+                 target_env = "uclibc"))] {
+        use libc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP;
+        use libc::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP;
+    } else {
+        // ...
+    }
+}
+
+use std::time::Duration;
+
+#[cfg(unix)] pub type Socket = c_int;
+#[cfg(unix)] use std::os::unix::prelude::*;
+#[cfg(unix)] use libc::*;
+#[cfg(windows)] pub type Socket = SOCKET;
+#[cfg(windows)] use std::os::windows::prelude::*;
+#[cfg(windows)] use ws2_32::*;
+#[cfg(windows)] use winapi::*;
+
+#[cfg(windows)] const SIO_KEEPALIVE_VALS: DWORD = 0x98000004;
+#[cfg(windows)]
+#[repr(C)]
+struct tcp_keepalive {
+    onoff: c_ulong,
+    keepalivetime: c_ulong,
+    keepaliveinterval: c_ulong,
+}
+
+#[cfg(windows)] fn v(opt: IPPROTO) -> c_int { opt.0 as c_int }
+#[cfg(unix)] fn v(opt: c_int) -> c_int { opt }
+
+pub fn set_opt<T: Copy>(sock: Socket, opt: c_int, val: c_int,
+                       payload: T) -> io::Result<()> {
+    unsafe {
+        let payload = &payload as *const T as *const c_void;
+        try!(::cvt(setsockopt(sock, opt, val, payload as *const _,
+                              mem::size_of::<T>() as socklen_t)));
+        Ok(())
+    }
+}
+
+pub fn get_opt<T: Copy>(sock: Socket, opt: c_int, val: c_int) -> io::Result<T> {
+    unsafe {
+        let mut slot: T = mem::zeroed();
+        let mut len = mem::size_of::<T>() as socklen_t;
+        try!(::cvt(getsockopt(sock, opt, val,
+                              &mut slot as *mut _ as *mut _,
+                              &mut len)));
+        assert_eq!(len as usize, mem::size_of::<T>());
+        Ok(slot)
+    }
+}
+
+/// Extension methods for the standard [`TcpStream` type][link] in `std::net`.
+///
+/// [link]: https://doc.rust-lang.org/std/net/struct.TcpStream.html
+pub trait TcpStreamExt {
+    /// Sets the value of the `TCP_NODELAY` option on this socket.
+    ///
+    /// If set, this option disables the Nagle algorithm. This means that
+    /// segments are always sent as soon as possible, even if there is only a
+    /// small amount of data. When not set, data is buffered until there is a
+    /// sufficient amount to send out, thereby avoiding the frequent sending of
+    /// small packets.
+    fn set_nodelay(&self, nodelay: bool) -> io::Result<()>;
+
+    /// Gets the value of the `TCP_NODELAY` option on this socket.
+    ///
+    /// For more information about this option, see [`set_nodelay`][link].
+    ///
+    /// [link]: #tymethod.set_nodelay
+    fn nodelay(&self) -> io::Result<bool>;
+
+    /// Sets the value of the `SO_RCVBUF` option on this socket.
+    ///
+    /// Changes the size of the operating system's receive buffer associated with the socket.
+    fn set_recv_buffer_size(&self, size: usize) -> io::Result<()>;
+
+    /// Gets the value of the `SO_RCVBUF` option on this socket.
+    ///
+    /// For more information about this option, see [`set_recv_buffer_size`][link].
+    ///
+    /// [link]: #tymethod.set_recv_buffer_size
+    fn recv_buffer_size(&self) -> io::Result<usize>;
+
+    /// Sets the value of the `SO_SNDBUF` option on this socket.
+    ///
+    /// Changes the size of the operating system's send buffer associated with the socket.
+    fn set_send_buffer_size(&self, size: usize) -> io::Result<()>;
+
+    /// Gets the value of the `SO_SNDBUF` option on this socket.
+    ///
+    /// For more information about this option, see [`set_send_buffer`][link].
+    ///
+    /// [link]: #tymethod.set_send_buffer
+    fn send_buffer_size(&self) -> io::Result<usize>;
+
+    /// Sets whether keepalive messages are enabled to be sent on this socket.
+    ///
+    /// On Unix, this option will set the `SO_KEEPALIVE` as well as the
+    /// `TCP_KEEPALIVE` or `TCP_KEEPIDLE` option (depending on your platform).
+    /// On Windows, this will set the `SIO_KEEPALIVE_VALS` option.
+    ///
+    /// If `None` is specified then keepalive messages are disabled, otherwise
+    /// the number of milliseconds specified will be the time to remain idle
+    /// before sending a TCP keepalive probe.
+    ///
+    /// Some platforms specify this value in seconds, so sub-second millisecond
+    /// specifications may be omitted.
+    fn set_keepalive_ms(&self, keepalive: Option<u32>) -> io::Result<()>;
+
+    /// Returns whether keepalive messages are enabled on this socket, and if so
+    /// the amount of milliseconds between them.
+    ///
+    /// For more information about this option, see [`set_keepalive_ms`][link].
+    ///
+    /// [link]: #tymethod.set_keepalive_ms
+    fn keepalive_ms(&self) -> io::Result<Option<u32>>;
+
+    /// Sets whether keepalive messages are enabled to be sent on this socket.
+    ///
+    /// On Unix, this option will set the `SO_KEEPALIVE` as well as the
+    /// `TCP_KEEPALIVE` or `TCP_KEEPIDLE` option (depending on your platform).
+    /// On Windows, this will set the `SIO_KEEPALIVE_VALS` option.
+    ///
+    /// If `None` is specified then keepalive messages are disabled, otherwise
+    /// the duration specified will be the time to remain idle before sending a
+    /// TCP keepalive probe.
+    ///
+    /// Some platforms specify this value in seconds, so sub-second
+    /// specifications may be omitted.
+    fn set_keepalive(&self, keepalive: Option<Duration>) -> io::Result<()>;
+
+    /// Returns whether keepalive messages are enabled on this socket, and if so
+    /// the duration of time between them.
+    ///
+    /// For more information about this option, see [`set_keepalive`][link].
+    ///
+    /// [link]: #tymethod.set_keepalive
+    fn keepalive(&self) -> io::Result<Option<Duration>>;
+
+    /// Sets the `SO_RCVTIMEO` option for this socket.
+    ///
+    /// This option specifies the timeout, in milliseconds, of how long calls to
+    /// this socket's `read` function will wait before returning a timeout. A
+    /// value of `None` means that no read timeout should be specified and
+    /// otherwise `Some` indicates the number of milliseconds for the timeout.
+    fn set_read_timeout_ms(&self, val: Option<u32>) -> io::Result<()>;
+
+    /// Sets the `SO_RCVTIMEO` option for this socket.
+    ///
+    /// This option specifies the timeout of how long calls to this socket's
+    /// `read` function will wait before returning a timeout. A value of `None`
+    /// means that no read timeout should be specified and otherwise `Some`
+    /// indicates the number of duration of the timeout.
+    fn set_read_timeout(&self, val: Option<Duration>) -> io::Result<()>;
+
+    /// Gets the value of the `SO_RCVTIMEO` option for this socket.
+    ///
+    /// For more information about this option, see [`set_read_timeout_ms`][link].
+    ///
+    /// [link]: #tymethod.set_read_timeout_ms
+    fn read_timeout_ms(&self) -> io::Result<Option<u32>>;
+
+    /// Gets the value of the `SO_RCVTIMEO` option for this socket.
+    ///
+    /// For more information about this option, see [`set_read_timeout`][link].
+    ///
+    /// [link]: #tymethod.set_read_timeout
+    fn read_timeout(&self) -> io::Result<Option<Duration>>;
+
+    /// Sets the `SO_SNDTIMEO` option for this socket.
+    ///
+    /// This option specifies the timeout, in milliseconds, of how long calls to
+    /// this socket's `write` function will wait before returning a timeout. A
+    /// value of `None` means that no read timeout should be specified and
+    /// otherwise `Some` indicates the number of milliseconds for the timeout.
+    fn set_write_timeout_ms(&self, val: Option<u32>) -> io::Result<()>;
+
+    /// Sets the `SO_SNDTIMEO` option for this socket.
+    ///
+    /// This option specifies the timeout of how long calls to this socket's
+    /// `write` function will wait before returning a timeout. A value of `None`
+    /// means that no read timeout should be specified and otherwise `Some`
+    /// indicates the duration of the timeout.
+    fn set_write_timeout(&self, val: Option<Duration>) -> io::Result<()>;
+
+    /// Gets the value of the `SO_SNDTIMEO` option for this socket.
+    ///
+    /// For more information about this option, see [`set_write_timeout_ms`][link].
+    ///
+    /// [link]: #tymethod.set_write_timeout_ms
+    fn write_timeout_ms(&self) -> io::Result<Option<u32>>;
+
+    /// Gets the value of the `SO_SNDTIMEO` option for this socket.
+    ///
+    /// For more information about this option, see [`set_write_timeout`][link].
+    ///
+    /// [link]: #tymethod.set_write_timeout
+    fn write_timeout(&self) -> io::Result<Option<Duration>>;
+
+    /// Sets the value for the `IP_TTL` option on this socket.
+    ///
+    /// This value sets the time-to-live field that is used in every packet sent
+    /// from this socket.
+    fn set_ttl(&self, ttl: u32) -> io::Result<()>;
+
+    /// Gets the value of the `IP_TTL` option for this socket.
+    ///
+    /// For more information about this option, see [`set_ttl`][link].
+    ///
+    /// [link]: #tymethod.set_ttl
+    fn ttl(&self) -> io::Result<u32>;
+
+    /// Sets the value for the `IPV6_V6ONLY` option on this socket.
+    ///
+    /// If this is set to `true` then the socket is restricted to sending and
+    /// receiving IPv6 packets only. In this case two IPv4 and IPv6 applications
+    /// can bind the same port at the same time.
+    ///
+    /// If this is set to `false` then the socket can be used to send and
+    /// receive packets from an IPv4-mapped IPv6 address.
+    fn set_only_v6(&self, only_v6: bool) -> io::Result<()>;
+
+    /// Gets the value of the `IPV6_V6ONLY` option for this socket.
+    ///
+    /// For more information about this option, see [`set_only_v6`][link].
+    ///
+    /// [link]: #tymethod.set_only_v6
+    fn only_v6(&self) -> io::Result<bool>;
+
+    /// Executes a `connect` operation on this socket, establishing a connection
+    /// to the host specified by `addr`.
+    ///
+    /// Note that this normally does not need to be called on a `TcpStream`,
+    /// it's typically automatically done as part of a normal
+    /// `TcpStream::connect` function call or `TcpBuilder::connect` method call.
+    ///
+    /// This should only be necessary if an unconnected socket was extracted
+    /// from a `TcpBuilder` and then needs to be connected.
+    fn connect<T: ToSocketAddrs>(&self, addr: T) -> io::Result<()>;
+
+    /// Get the value of the `SO_ERROR` option on this socket.
+    ///
+    /// This will retrieve the stored error in the underlying socket, clearing
+    /// the field in the process. This can be useful for checking errors between
+    /// calls.
+    fn take_error(&self) -> io::Result<Option<io::Error>>;
+
+    /// Moves this TCP stream into or out of nonblocking mode.
+    ///
+    /// On Unix this corresponds to calling fcntl, and on Windows this
+    /// corresponds to calling ioctlsocket.
+    fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()>;
+
+    /// Sets the linger duration of this socket by setting the SO_LINGER option
+    fn set_linger(&self, dur: Option<Duration>) -> io::Result<()>;
+
+    /// reads the linger duration for this socket by getting the SO_LINGER option
+    fn linger(&self) -> io::Result<Option<Duration>>;
+}
+
+/// Extension methods for the standard [`TcpListener` type][link] in `std::net`.
+///
+/// [link]: https://doc.rust-lang.org/std/net/struct.TcpListener.html
+pub trait TcpListenerExt {
+    /// Sets the value for the `IP_TTL` option on this socket.
+    ///
+    /// This is the same as [`TcpStreamExt::set_ttl`][other].
+    ///
+    /// [other]: trait.TcpStreamExt.html#tymethod.set_ttl
+    fn set_ttl(&self, ttl: u32) -> io::Result<()>;
+
+    /// Gets the value of the `IP_TTL` option for this socket.
+    ///
+    /// For more information about this option, see
+    /// [`TcpStreamExt::set_ttl`][link].
+    ///
+    /// [link]: trait.TcpStreamExt.html#tymethod.set_ttl
+    fn ttl(&self) -> io::Result<u32>;
+
+    /// Sets the value for the `IPV6_V6ONLY` option on this socket.
+    ///
+    /// For more information about this option, see
+    /// [`TcpStreamExt::set_only_v6`][link].
+    ///
+    /// [link]: trait.TcpStreamExt.html#tymethod.set_only_v6
+    fn set_only_v6(&self, only_v6: bool) -> io::Result<()>;
+
+    /// Gets the value of the `IPV6_V6ONLY` option for this socket.
+    ///
+    /// For more information about this option, see
+    /// [`TcpStreamExt::set_only_v6`][link].
+    ///
+    /// [link]: trait.TcpStreamExt.html#tymethod.set_only_v6
+    fn only_v6(&self) -> io::Result<bool>;
+
+    /// Get the value of the `SO_ERROR` option on this socket.
+    ///
+    /// This will retrieve the stored error in the underlying socket, clearing
+    /// the field in the process. This can be useful for checking errors between
+    /// calls.
+    fn take_error(&self) -> io::Result<Option<io::Error>>;
+
+    /// Moves this TCP listener into or out of nonblocking mode.
+    ///
+    /// For more information about this option, see
+    /// [`TcpStreamExt::set_nonblocking`][link].
+    ///
+    /// [link]: trait.TcpStreamExt.html#tymethod.set_nonblocking
+    fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()>;
+
+    /// Sets the linger duration of this socket by setting the SO_LINGER option
+    fn set_linger(&self, dur: Option<Duration>) -> io::Result<()>;
+
+    /// reads the linger duration for this socket by getting the SO_LINGER option
+    fn linger(&self) -> io::Result<Option<Duration>>;
+}
+
+/// Extension methods for the standard [`UdpSocket` type][link] in `std::net`.
+///
+/// [link]: https://doc.rust-lang.org/std/net/struct.UdpSocket.html
+pub trait UdpSocketExt {
+    /// Sets the value of the `SO_RCVBUF` option on this socket.
+    ///
+    /// Changes the size of the operating system's receive buffer associated with the socket.
+    fn set_recv_buffer_size(&self, size: usize) -> io::Result<()>;
+
+    /// Gets the value of the `SO_RCVBUF` option on this socket.
+    ///
+    /// For more information about this option, see [`set_recv_buffer_size`][link].
+    ///
+    /// [link]: #tymethod.set_recv_buffer_size
+    fn recv_buffer_size(&self) -> io::Result<usize>;
+
+    /// Sets the value of the `SO_SNDBUF` option on this socket.
+    ///
+    /// Changes the size of the operating system's send buffer associated with the socket.
+    fn set_send_buffer_size(&self, size: usize) -> io::Result<()>;
+
+    /// Gets the value of the `SO_SNDBUF` option on this socket.
+    ///
+    /// For more information about this option, see [`set_send_buffer`][link].
+    ///
+    /// [link]: #tymethod.set_send_buffer
+    fn send_buffer_size(&self) -> io::Result<usize>;
+
+    /// Sets the value of the `SO_BROADCAST` option for this socket.
+    ///
+    /// When enabled, this socket is allowed to send packets to a broadcast
+    /// address.
+    fn set_broadcast(&self, broadcast: bool) -> io::Result<()>;
+
+    /// Gets the value of the `SO_BROADCAST` option for this socket.
+    ///
+    /// For more information about this option, see
+    /// [`set_broadcast`][link].
+    ///
+    /// [link]: #tymethod.set_broadcast
+    fn broadcast(&self) -> io::Result<bool>;
+
+    /// Sets the value of the `IP_MULTICAST_LOOP` option for this socket.
+    ///
+    /// If enabled, multicast packets will be looped back to the local socket.
+    /// Note that this may not have any affect on IPv6 sockets.
+    fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()>;
+
+    /// Gets the value of the `IP_MULTICAST_LOOP` option for this socket.
+    ///
+    /// For more information about this option, see
+    /// [`set_multicast_loop_v4`][link].
+    ///
+    /// [link]: #tymethod.set_multicast_loop_v4
+    fn multicast_loop_v4(&self) -> io::Result<bool>;
+
+    /// Sets the value of the `IP_MULTICAST_TTL` option for this socket.
+    ///
+    /// Indicates the time-to-live value of outgoing multicast packets for
+    /// this socket. The default value is 1 which means that multicast packets
+    /// don't leave the local network unless explicitly requested.
+    ///
+    /// Note that this may not have any affect on IPv6 sockets.
+    fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()>;
+
+    /// Gets the value of the `IP_MULTICAST_TTL` option for this socket.
+    ///
+    /// For more information about this option, see
+    /// [`set_multicast_ttl_v4`][link].
+    ///
+    /// [link]: #tymethod.set_multicast_ttl_v4
+    fn multicast_ttl_v4(&self) -> io::Result<u32>;
+
+    /// Sets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
+    ///
+    /// Controls whether this socket sees the multicast packets it sends itself.
+    /// Note that this may not have any affect on IPv4 sockets.
+    fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()>;
+
+    /// Gets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
+    ///
+    /// For more information about this option, see
+    /// [`set_multicast_loop_v6`][link].
+    ///
+    /// [link]: #tymethod.set_multicast_loop_v6
+    fn multicast_loop_v6(&self) -> io::Result<bool>;
+
+    /// Sets the value for the `IP_TTL` option on this socket.
+    ///
+    /// This is the same as [`TcpStreamExt::set_ttl`][other].
+    ///
+    /// [other]: trait.TcpStreamExt.html#tymethod.set_ttl
+    fn set_ttl(&self, ttl: u32) -> io::Result<()>;
+
+    /// Gets the value of the `IP_TTL` option for this socket.
+    ///
+    /// For more information about this option, see
+    /// [`TcpStreamExt::set_ttl`][link].
+    ///
+    /// [link]: trait.TcpStreamExt.html#tymethod.set_ttl
+    fn ttl(&self) -> io::Result<u32>;
+
+    /// Sets the value for the `IPV6_V6ONLY` option on this socket.
+    ///
+    /// For more information about this option, see
+    /// [`TcpStreamExt::set_only_v6`][link].
+    ///
+    /// [link]: trait.TcpStreamExt.html#tymethod.set_only_v6
+    fn set_only_v6(&self, only_v6: bool) -> io::Result<()>;
+
+    /// Gets the value of the `IPV6_V6ONLY` option for this socket.
+    ///
+    /// For more information about this option, see
+    /// [`TcpStreamExt::set_only_v6`][link].
+    ///
+    /// [link]: trait.TcpStreamExt.html#tymethod.set_only_v6
+    fn only_v6(&self) -> io::Result<bool>;
+
+    /// Executes an operation of the `IP_ADD_MEMBERSHIP` type.
+    ///
+    /// This function specifies a new multicast group for this socket to join.
+    /// The address must be a valid multicast address, and `interface` is the
+    /// address of the local interface with which the system should join the
+    /// multicast group. If it's equal to `INADDR_ANY` then an appropriate
+    /// interface is chosen by the system.
+    fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr)
+                         -> io::Result<()>;
+
+    /// Executes an operation of the `IPV6_ADD_MEMBERSHIP` type.
+    ///
+    /// This function specifies a new multicast group for this socket to join.
+    /// The address must be a valid multicast address, and `interface` is the
+    /// index of the interface to join/leave (or 0 to indicate any interface).
+    fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32)
+                         -> io::Result<()>;
+
+    /// Executes an operation of the `IP_DROP_MEMBERSHIP` type.
+    ///
+    /// For more information about this option, see
+    /// [`join_multicast_v4`][link].
+    ///
+    /// [link]: #tymethod.join_multicast_v4
+    fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr)
+                          -> io::Result<()>;
+
+    /// Executes an operation of the `IPV6_DROP_MEMBERSHIP` type.
+    ///
+    /// For more information about this option, see
+    /// [`join_multicast_v6`][link].
+    ///
+    /// [link]: #tymethod.join_multicast_v6
+    fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32)
+                          -> io::Result<()>;
+
+    /// Sets the `SO_RCVTIMEO` option for this socket.
+    ///
+    /// This option specifies the timeout, in milliseconds, of how long calls to
+    /// this socket's `read` function will wait before returning a timeout. A
+    /// value of `None` means that no read timeout should be specified and
+    /// otherwise `Some` indicates the number of milliseconds for the timeout.
+    fn set_read_timeout_ms(&self, val: Option<u32>) -> io::Result<()>;
+
+    /// Sets the `SO_RCVTIMEO` option for this socket.
+    ///
+    /// This option specifies the timeout of how long calls to this socket's
+    /// `read` function will wait before returning a timeout. A value of `None`
+    /// means that no read timeout should be specified and otherwise `Some`
+    /// indicates the number of duration of the timeout.
+    fn set_read_timeout(&self, val: Option<Duration>) -> io::Result<()>;
+
+    /// Gets the value of the `SO_RCVTIMEO` option for this socket.
+    ///
+    /// For more information about this option, see [`set_read_timeout_ms`][link].
+    ///
+    /// [link]: #tymethod.set_read_timeout_ms
+    fn read_timeout_ms(&self) -> io::Result<Option<u32>>;
+
+    /// Gets the value of the `SO_RCVTIMEO` option for this socket.
+    ///
+    /// For more information about this option, see [`set_read_timeout`][link].
+    ///
+    /// [link]: #tymethod.set_read_timeout
+    fn read_timeout(&self) -> io::Result<Option<Duration>>;
+
+    /// Sets the `SO_SNDTIMEO` option for this socket.
+    ///
+    /// This option specifies the timeout, in milliseconds, of how long calls to
+    /// this socket's `write` function will wait before returning a timeout. A
+    /// value of `None` means that no read timeout should be specified and
+    /// otherwise `Some` indicates the number of milliseconds for the timeout.
+    fn set_write_timeout_ms(&self, val: Option<u32>) -> io::Result<()>;
+
+    /// Sets the `SO_SNDTIMEO` option for this socket.
+    ///
+    /// This option specifies the timeout of how long calls to this socket's
+    /// `write` function will wait before returning a timeout. A value of `None`
+    /// means that no read timeout should be specified and otherwise `Some`
+    /// indicates the duration of the timeout.
+    fn set_write_timeout(&self, val: Option<Duration>) -> io::Result<()>;
+
+    /// Gets the value of the `SO_SNDTIMEO` option for this socket.
+    ///
+    /// For more information about this option, see [`set_write_timeout_ms`][link].
+    ///
+    /// [link]: #tymethod.set_write_timeout_ms
+    fn write_timeout_ms(&self) -> io::Result<Option<u32>>;
+
+    /// Gets the value of the `SO_SNDTIMEO` option for this socket.
+    ///
+    /// For more information about this option, see [`set_write_timeout`][link].
+    ///
+    /// [link]: #tymethod.set_write_timeout
+    fn write_timeout(&self) -> io::Result<Option<Duration>>;
+
+    /// Get the value of the `SO_ERROR` option on this socket.
+    ///
+    /// This will retrieve the stored error in the underlying socket, clearing
+    /// the field in the process. This can be useful for checking errors between
+    /// calls.
+    fn take_error(&self) -> io::Result<Option<io::Error>>;
+
+    /// Connects this UDP socket to a remote address, allowing the `send` and
+    /// `recv` syscalls to be used to send data and also applies filters to only
+    /// receive data from the specified address.
+    fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()>;
+
+    /// Sends data on the socket to the remote address to which it is connected.
+    ///
+    /// The `connect` method will connect this socket to a remote address. This
+    /// method will fail if the socket is not connected.
+    fn send(&self, buf: &[u8]) -> io::Result<usize>;
+
+    /// Receives data on the socket from the remote address to which it is
+    /// connected.
+    ///
+    /// The `connect` method will connect this socket to a remote address. This
+    /// method will fail if the socket is not connected.
+    fn recv(&self, buf: &mut [u8]) -> io::Result<usize>;
+
+    /// Moves this UDP socket into or out of nonblocking mode.
+    ///
+    /// For more information about this option, see
+    /// [`TcpStreamExt::set_nonblocking`][link].
+    ///
+    /// [link]: trait.TcpStreamExt.html#tymethod.set_nonblocking
+    fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()>;
+}
+
+#[doc(hidden)]
+pub trait AsSock {
+    fn as_sock(&self) -> Socket;
+}
+
+#[cfg(unix)]
+impl<T: AsRawFd> AsSock for T {
+    fn as_sock(&self) -> Socket { self.as_raw_fd() }
+}
+#[cfg(windows)]
+impl<T: AsRawSocket> AsSock for T {
+    fn as_sock(&self) -> Socket { self.as_raw_socket() }
+}
+
+cfg_if! {
+    if #[cfg(any(target_os = "macos", target_os = "ios"))] {
+        use libc::TCP_KEEPALIVE as KEEPALIVE_OPTION;
+    } else if #[cfg(any(target_os = "openbsd", target_os = "netbsd"))] {
+        use libc::SO_KEEPALIVE as KEEPALIVE_OPTION;
+    } else if #[cfg(unix)] {
+        use libc::TCP_KEEPIDLE as KEEPALIVE_OPTION;
+    } else {
+        // ...
+    }
+}
+
+impl TcpStreamExt for TcpStream {
+
+    fn set_recv_buffer_size(&self, size: usize) -> io::Result<()> {
+        // TODO: casting usize to a c_int should be a checked cast
+        set_opt(self.as_sock(), SOL_SOCKET, SO_RCVBUF, size as c_int)
+    }
+
+    fn recv_buffer_size(&self) -> io::Result<usize> {
+        get_opt(self.as_sock(), SOL_SOCKET, SO_RCVBUF).map(int2usize)
+    }
+
+    fn set_send_buffer_size(&self, size: usize) -> io::Result<()> {
+        set_opt(self.as_sock(), SOL_SOCKET, SO_SNDBUF, size as c_int)
+    }
+
+    fn send_buffer_size(&self) -> io::Result<usize> {
+        get_opt(self.as_sock(), SOL_SOCKET, SO_SNDBUF).map(int2usize)
+    }
+
+    fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
+        set_opt(self.as_sock(), v(IPPROTO_TCP), TCP_NODELAY,
+               nodelay as c_int)
+    }
+    fn nodelay(&self) -> io::Result<bool> {
+        get_opt(self.as_sock(), v(IPPROTO_TCP), TCP_NODELAY)
+            .map(int2bool)
+    }
+
+    fn set_keepalive(&self, keepalive: Option<Duration>) -> io::Result<()> {
+        self.set_keepalive_ms(keepalive.map(dur2ms))
+    }
+
+    fn keepalive(&self) -> io::Result<Option<Duration>> {
+        self.keepalive_ms().map(|o| o.map(ms2dur))
+    }
+
+    #[cfg(unix)]
+    fn set_keepalive_ms(&self, keepalive: Option<u32>) -> io::Result<()> {
+        try!(set_opt(self.as_sock(), SOL_SOCKET, SO_KEEPALIVE,
+                    keepalive.is_some() as c_int));
+        if let Some(dur) = keepalive {
+            try!(set_opt(self.as_sock(), v(IPPROTO_TCP), KEEPALIVE_OPTION,
+                        (dur / 1000) as c_int));
+        }
+        Ok(())
+    }
+
+    #[cfg(unix)]
+    fn keepalive_ms(&self) -> io::Result<Option<u32>> {
+        let keepalive = try!(get_opt::<c_int>(self.as_sock(), SOL_SOCKET,
+                                             SO_KEEPALIVE));
+        if keepalive == 0 {
+            return Ok(None)
+        }
+        let secs = try!(get_opt::<c_int>(self.as_sock(), v(IPPROTO_TCP),
+                                        KEEPALIVE_OPTION));
+        Ok(Some((secs as u32) * 1000))
+    }
+
+    #[cfg(windows)]
+    fn set_keepalive_ms(&self, keepalive: Option<u32>) -> io::Result<()> {
+        let ms = keepalive.unwrap_or(INFINITE);
+        let ka = tcp_keepalive {
+            onoff: keepalive.is_some() as c_ulong,
+            keepalivetime: ms as c_ulong,
+            keepaliveinterval: ms as c_ulong,
+        };
+        unsafe {
+            ::cvt_win(WSAIoctl(self.as_sock(),
+                               SIO_KEEPALIVE_VALS,
+                               &ka as *const _ as *mut _,
+                               mem::size_of_val(&ka) as DWORD,
+                               0 as *mut _,
+                               0,
+                               0 as *mut _,
+                               0 as *mut _,
+                               None)).map(|_| ())
+        }
+    }
+
+    #[cfg(windows)]
+    fn keepalive_ms(&self) -> io::Result<Option<u32>> {
+        let mut ka = tcp_keepalive {
+            onoff: 0,
+            keepalivetime: 0,
+            keepaliveinterval: 0,
+        };
+        unsafe {
+            try!(::cvt_win(WSAIoctl(self.as_sock(),
+                                    SIO_KEEPALIVE_VALS,
+                                    0 as *mut _,
+                                    0,
+                                    &mut ka as *mut _ as *mut _,
+                                    mem::size_of_val(&ka) as DWORD,
+                                    0 as *mut _,
+                                    0 as *mut _,
+                                    None)));
+        }
+        Ok({
+            if ka.onoff == 0 {
+                None
+            } else {
+                timeout2ms(ka.keepaliveinterval as DWORD)
+            }
+        })
+    }
+
+    fn set_read_timeout_ms(&self, dur: Option<u32>) -> io::Result<()> {
+        set_opt(self.as_sock(), SOL_SOCKET, SO_RCVTIMEO,
+               ms2timeout(dur))
+    }
+
+    fn read_timeout_ms(&self) -> io::Result<Option<u32>> {
+        get_opt(self.as_sock(), SOL_SOCKET, SO_RCVTIMEO)
+            .map(timeout2ms)
+    }
+
+    fn set_write_timeout_ms(&self, dur: Option<u32>) -> io::Result<()> {
+        set_opt(self.as_sock(), SOL_SOCKET, SO_SNDTIMEO,
+               ms2timeout(dur))
+    }
+
+    fn write_timeout_ms(&self) -> io::Result<Option<u32>> {
+        get_opt(self.as_sock(), SOL_SOCKET, SO_SNDTIMEO)
+            .map(timeout2ms)
+    }
+
+    fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
+        self.set_read_timeout_ms(dur.map(dur2ms))
+    }
+
+    fn read_timeout(&self) -> io::Result<Option<Duration>> {
+        self.read_timeout_ms().map(|o| o.map(ms2dur))
+    }
+
+    fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
+        self.set_write_timeout_ms(dur.map(dur2ms))
+    }
+
+    fn write_timeout(&self) -> io::Result<Option<Duration>> {
+        self.write_timeout_ms().map(|o| o.map(ms2dur))
+    }
+
+    fn set_ttl(&self, ttl: u32) -> io::Result<()> {
+        set_opt(self.as_sock(), IPPROTO_IP, IP_TTL, ttl as c_int)
+    }
+
+    fn ttl(&self) -> io::Result<u32> {
+        get_opt::<c_int>(self.as_sock(), IPPROTO_IP, IP_TTL)
+            .map(|b| b as u32)
+    }
+
+    fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
+        set_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_V6ONLY, only_v6 as c_int)
+    }
+
+    fn only_v6(&self) -> io::Result<bool> {
+        get_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_V6ONLY).map(int2bool)
+    }
+
+    fn connect<T: ToSocketAddrs>(&self, addr: T) -> io::Result<()> {
+        do_connect(self.as_sock(), addr)
+    }
+
+    fn take_error(&self) -> io::Result<Option<io::Error>> {
+        get_opt(self.as_sock(), SOL_SOCKET, SO_ERROR).map(int2err)
+    }
+
+    fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
+        set_nonblocking(self.as_sock(), nonblocking)
+    }
+
+    fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
+        set_opt(self.as_sock(), SOL_SOCKET, SO_LINGER, dur2linger(dur))
+    }
+
+    fn linger(&self) -> io::Result<Option<Duration>> {
+        get_opt(self.as_sock(), SOL_SOCKET, SO_LINGER).map(linger2dur)
+    }
+}
+
+#[cfg(unix)]
+fn ms2timeout(dur: Option<u32>) -> timeval {
+    // TODO: be more rigorous
+    match dur {
+        Some(d) => timeval {
+            tv_sec: (d / 1000) as time_t,
+            tv_usec: (d % 1000) as suseconds_t,
+        },
+        None => timeval { tv_sec: 0, tv_usec: 0 },
+    }
+}
+
+#[cfg(unix)]
+fn timeout2ms(dur: timeval) -> Option<u32> {
+    if dur.tv_sec == 0 && dur.tv_usec == 0 {
+        None
+    } else {
+        Some(dur.tv_sec as u32 * 1000 + dur.tv_usec as u32 / 1000)
+    }
+}
+
+#[cfg(windows)]
+fn ms2timeout(dur: Option<u32>) -> DWORD {
+    dur.unwrap_or(0)
+}
+
+#[cfg(windows)]
+fn timeout2ms(dur: DWORD) -> Option<u32> {
+    if dur == 0 {
+        None
+    } else {
+        Some(dur)
+    }
+}
+
+fn linger2dur(linger_opt: linger) -> Option<Duration> {
+    if linger_opt.l_onoff == 0 {
+        None
+    }
+    else {
+        Some(Duration::from_secs(linger_opt.l_linger as u64))
+    }
+}
+
+#[cfg(windows)]
+fn dur2linger(dur: Option<Duration>) -> linger {
+    match dur {
+        Some(d) => {
+            linger {
+                l_onoff: 1,
+                l_linger: d.as_secs() as u16,
+            }
+        },
+        None => linger { l_onoff: 0, l_linger: 0 },
+    }
+}
+
+#[cfg(unix)]
+fn dur2linger(dur: Option<Duration>) -> linger {
+    match dur {
+        Some(d) => {
+            linger {
+                l_onoff: 1,
+                l_linger: d.as_secs() as c_int,
+            }
+        },
+        None => linger { l_onoff: 0, l_linger: 0 },
+    }
+}
+
+fn ms2dur(ms: u32) -> Duration {
+    Duration::new((ms as u64) / 1000, (ms as u32) % 1000 * 1_000_000)
+}
+
+fn dur2ms(dur: Duration) -> u32 {
+    (dur.as_secs() as u32 * 1000) + (dur.subsec_nanos() / 1_000_000)
+}
+
+pub fn int2bool(n: c_int) -> bool {
+    if n == 0 {false} else {true}
+}
+
+pub fn int2usize(n: c_int) -> usize {
+    // TODO: casting c_int to a usize should be a checked cast
+    n as usize
+}
+
+pub fn int2err(n: c_int) -> Option<io::Error> {
+    if n == 0 {
+        None
+    } else {
+        Some(io::Error::from_raw_os_error(n as i32))
+    }
+}
+
+impl UdpSocketExt for UdpSocket {
+
+    fn set_recv_buffer_size(&self, size: usize) -> io::Result<()> {
+        set_opt(self.as_sock(), SOL_SOCKET, SO_RCVBUF, size as c_int)
+    }
+
+    fn recv_buffer_size(&self) -> io::Result<usize> {
+        get_opt(self.as_sock(), SOL_SOCKET, SO_RCVBUF).map(int2usize)
+    }
+
+    fn set_send_buffer_size(&self, size: usize) -> io::Result<()> {
+        set_opt(self.as_sock(), SOL_SOCKET, SO_SNDBUF, size as c_int)
+    }
+
+    fn send_buffer_size(&self) -> io::Result<usize> {
+        get_opt(self.as_sock(), SOL_SOCKET, SO_SNDBUF).map(int2usize)
+    }
+
+    fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
+        set_opt(self.as_sock(), SOL_SOCKET, SO_BROADCAST,
+               broadcast as c_int)
+    }
+    fn broadcast(&self) -> io::Result<bool> {
+        get_opt(self.as_sock(), SOL_SOCKET, SO_BROADCAST)
+            .map(int2bool)
+    }
+    fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> {
+        set_opt(self.as_sock(), IPPROTO_IP, IP_MULTICAST_LOOP,
+               multicast_loop_v4 as c_int)
+    }
+    fn multicast_loop_v4(&self) -> io::Result<bool> {
+        get_opt(self.as_sock(), IPPROTO_IP, IP_MULTICAST_LOOP)
+            .map(int2bool)
+    }
+    fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> {
+        set_opt(self.as_sock(), IPPROTO_IP, IP_MULTICAST_TTL,
+               multicast_ttl_v4 as c_int)
+    }
+    fn multicast_ttl_v4(&self) -> io::Result<u32> {
+        get_opt::<c_int>(self.as_sock(), IPPROTO_IP, IP_MULTICAST_TTL)
+            .map(|b| b as u32)
+    }
+    fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> {
+        set_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_MULTICAST_LOOP,
+               multicast_loop_v6 as c_int)
+    }
+    fn multicast_loop_v6(&self) -> io::Result<bool> {
+        get_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_MULTICAST_LOOP)
+            .map(int2bool)
+    }
+
+    fn set_ttl(&self, ttl: u32) -> io::Result<()> {
+        set_opt(self.as_sock(), IPPROTO_IP, IP_TTL, ttl as c_int)
+    }
+
+    fn ttl(&self) -> io::Result<u32> {
+        get_opt::<c_int>(self.as_sock(), IPPROTO_IP, IP_TTL)
+            .map(|b| b as u32)
+    }
+
+    fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
+        set_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_V6ONLY, only_v6 as c_int)
+    }
+
+    fn only_v6(&self) -> io::Result<bool> {
+        get_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_V6ONLY).map(int2bool)
+    }
+
+    fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr)
+                         -> io::Result<()> {
+        let mreq = ip_mreq {
+            imr_multiaddr: ip2in_addr(multiaddr),
+            imr_interface: ip2in_addr(interface),
+        };
+        set_opt(self.as_sock(), IPPROTO_IP, IP_ADD_MEMBERSHIP, mreq)
+    }
+
+    fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32)
+                         -> io::Result<()> {
+        let mreq = ipv6_mreq {
+            ipv6mr_multiaddr: ip2in6_addr(multiaddr),
+            ipv6mr_interface: to_ipv6mr_interface(interface),
+        };
+        set_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_ADD_MEMBERSHIP,
+               mreq)
+    }
+
+    fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr)
+                          -> io::Result<()> {
+        let mreq = ip_mreq {
+            imr_multiaddr: ip2in_addr(multiaddr),
+            imr_interface: ip2in_addr(interface),
+        };
+        set_opt(self.as_sock(), IPPROTO_IP, IP_DROP_MEMBERSHIP, mreq)
+    }
+
+    fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32)
+                          -> io::Result<()> {
+        let mreq = ipv6_mreq {
+            ipv6mr_multiaddr: ip2in6_addr(multiaddr),
+            ipv6mr_interface: to_ipv6mr_interface(interface),
+        };
+        set_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_DROP_MEMBERSHIP,
+               mreq)
+    }
+
+    fn set_read_timeout_ms(&self, dur: Option<u32>) -> io::Result<()> {
+        set_opt(self.as_sock(), SOL_SOCKET, SO_RCVTIMEO,
+               ms2timeout(dur))
+    }
+
+    fn read_timeout_ms(&self) -> io::Result<Option<u32>> {
+        get_opt(self.as_sock(), SOL_SOCKET, SO_RCVTIMEO)
+            .map(timeout2ms)
+    }
+
+    fn set_write_timeout_ms(&self, dur: Option<u32>) -> io::Result<()> {
+        set_opt(self.as_sock(), SOL_SOCKET, SO_SNDTIMEO,
+               ms2timeout(dur))
+    }
+
+    fn write_timeout_ms(&self) -> io::Result<Option<u32>> {
+        get_opt(self.as_sock(), SOL_SOCKET, SO_SNDTIMEO)
+            .map(timeout2ms)
+    }
+
+    fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
+        self.set_read_timeout_ms(dur.map(dur2ms))
+    }
+
+    fn read_timeout(&self) -> io::Result<Option<Duration>> {
+        self.read_timeout_ms().map(|o| o.map(ms2dur))
+    }
+
+    fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
+        self.set_write_timeout_ms(dur.map(dur2ms))
+    }
+
+    fn write_timeout(&self) -> io::Result<Option<Duration>> {
+        self.write_timeout_ms().map(|o| o.map(ms2dur))
+    }
+
+    fn take_error(&self) -> io::Result<Option<io::Error>> {
+        get_opt(self.as_sock(), SOL_SOCKET, SO_ERROR).map(int2err)
+    }
+
+    fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()> {
+        do_connect(self.as_sock(), addr)
+    }
+
+    #[cfg(unix)]
+    fn send(&self, buf: &[u8]) -> io::Result<usize> {
+        unsafe {
+            ::cvt(send(self.as_sock(), buf.as_ptr() as *const _, buf.len(), 0)).map(|n| n as usize)
+        }
+    }
+
+    #[cfg(windows)]
+    fn send(&self, buf: &[u8]) -> io::Result<usize> {
+        let len = ::std::cmp::min(buf.len(), c_int::max_value() as usize);
+        let buf = &buf[..len];
+        unsafe {
+            ::cvt(send(self.as_sock(), buf.as_ptr() as *const _, len as c_int, 0))
+                .map(|n| n as usize)
+        }
+    }
+
+    #[cfg(unix)]
+    fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
+        unsafe {
+            ::cvt(recv(self.as_sock(), buf.as_mut_ptr() as *mut _, buf.len(), 0))
+                .map(|n| n as usize)
+        }
+    }
+
+    #[cfg(windows)]
+    fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
+        let len = ::std::cmp::min(buf.len(), c_int::max_value() as usize);
+        let buf = &mut buf[..len];
+        unsafe {
+            ::cvt(recv(self.as_sock(), buf.as_mut_ptr() as *mut _, buf.len() as c_int, 0))
+                .map(|n| n as usize)
+        }
+    }
+
+    fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
+        set_nonblocking(self.as_sock(), nonblocking)
+    }
+}
+
+fn do_connect<A: ToSocketAddrs>(sock: Socket, addr: A) -> io::Result<()> {
+    let err = io::Error::new(io::ErrorKind::Other,
+                             "no socket addresses resolved");
+    let addrs = try!(addr.to_socket_addrs());
+    let sys = sys::Socket::from_inner(sock);
+    let sock = socket::Socket::from_inner(sys);
+    let ret = addrs.fold(Err(err), |prev, addr| {
+        prev.or_else(|_| sock.connect(&addr))
+    });
+    mem::forget(sock);
+    return ret
+}
+
+#[cfg(unix)]
+fn set_nonblocking(sock: Socket, nonblocking: bool) -> io::Result<()> {
+    let mut nonblocking = nonblocking as c_ulong;
+    ::cvt(unsafe {
+        ioctl(sock, FIONBIO, &mut nonblocking)
+    }).map(|_| ())
+}
+
+#[cfg(windows)]
+fn set_nonblocking(sock: Socket, nonblocking: bool) -> io::Result<()> {
+    let mut nonblocking = nonblocking as c_ulong;
+    ::cvt(unsafe {
+        ioctlsocket(sock, FIONBIO as c_int, &mut nonblocking)
+    }).map(|_| ())
+}
+
+#[cfg(unix)]
+fn ip2in_addr(ip: &Ipv4Addr) -> in_addr {
+    let oct = ip.octets();
+    in_addr {
+        s_addr: ::hton(((oct[0] as u32) << 24) |
+                       ((oct[1] as u32) << 16) |
+                       ((oct[2] as u32) <<  8) |
+                       ((oct[3] as u32) <<  0)),
+    }
+}
+
+#[cfg(windows)]
+fn ip2in_addr(ip: &Ipv4Addr) -> in_addr {
+    let oct = ip.octets();
+    in_addr {
+        S_un: ::hton(((oct[0] as u32) << 24) |
+                     ((oct[1] as u32) << 16) |
+                     ((oct[2] as u32) <<  8) |
+                     ((oct[3] as u32) <<  0)),
+    }
+}
+
+#[cfg(target_os = "android")]
+fn to_ipv6mr_interface(value: u32) -> c_int {
+    value as c_int
+}
+
+#[cfg(not(target_os = "android"))]
+fn to_ipv6mr_interface(value: u32) -> c_uint {
+    value as c_uint
+}
+
+fn ip2in6_addr(ip: &Ipv6Addr) -> in6_addr {
+    let mut ret: in6_addr = unsafe { mem::zeroed() };
+    let seg = ip.segments();
+    ret.s6_addr = [
+        (seg[0] >> 8) as u8,
+        (seg[0] >> 0) as u8,
+        (seg[1] >> 8) as u8,
+        (seg[1] >> 0) as u8,
+        (seg[2] >> 8) as u8,
+        (seg[2] >> 0) as u8,
+        (seg[3] >> 8) as u8,
+        (seg[3] >> 0) as u8,
+        (seg[4] >> 8) as u8,
+        (seg[4] >> 0) as u8,
+        (seg[5] >> 8) as u8,
+        (seg[5] >> 0) as u8,
+        (seg[6] >> 8) as u8,
+        (seg[6] >> 0) as u8,
+        (seg[7] >> 8) as u8,
+        (seg[7] >> 0) as u8,
+    ];
+    return ret
+}
+
+impl TcpListenerExt for TcpListener {
+    fn set_ttl(&self, ttl: u32) -> io::Result<()> {
+        set_opt(self.as_sock(), IPPROTO_IP, IP_TTL, ttl as c_int)
+    }
+
+    fn ttl(&self) -> io::Result<u32> {
+        get_opt::<c_int>(self.as_sock(), IPPROTO_IP, IP_TTL)
+            .map(|b| b as u32)
+    }
+
+    fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
+        set_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_V6ONLY, only_v6 as c_int)
+    }
+
+    fn only_v6(&self) -> io::Result<bool> {
+        get_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_V6ONLY).map(int2bool)
+    }
+
+    fn take_error(&self) -> io::Result<Option<io::Error>> {
+        get_opt(self.as_sock(), SOL_SOCKET, SO_ERROR).map(int2err)
+    }
+
+    fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
+        set_nonblocking(self.as_sock(), nonblocking)
+    }
+
+    fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
+        set_opt(self.as_sock(), SOL_SOCKET, SO_LINGER, dur2linger(dur))
+    }
+
+    fn linger(&self) -> io::Result<Option<Duration>> {
+        get_opt(self.as_sock(), SOL_SOCKET, SO_LINGER).map(linger2dur)
+    }
+}
+
+impl TcpBuilder {
+    /// Sets the value for the `IP_TTL` option on this socket.
+    ///
+    /// This is the same as [`TcpStreamExt::set_ttl`][other].
+    ///
+    /// [other]: trait.TcpStreamExt.html#tymethod.set_ttl
+    pub fn ttl(&self, ttl: u32) -> io::Result<&Self> {
+        set_opt(self.as_sock(), IPPROTO_IP, IP_TTL, ttl as c_int)
+            .map(|()| self)
+    }
+
+    /// Sets the value for the `IPV6_V6ONLY` option on this socket.
+    ///
+    /// This is the same as [`TcpStreamExt::set_only_v6`][other].
+    ///
+    /// [other]: trait.TcpStreamExt.html#tymethod.set_only_v6
+    pub fn only_v6(&self, only_v6: bool) -> io::Result<&Self> {
+        set_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_V6ONLY, only_v6 as c_int)
+            .map(|()| self)
+    }
+
+    /// Set value for the `SO_REUSEADDR` option on this socket.
+    ///
+    /// This indicates that futher calls to `bind` may allow reuse of local
+    /// addresses. For IPv4 sockets this means that a socket may bind even when
+    /// there's a socket already listening on this port.
+    pub fn reuse_address(&self, reuse: bool) -> io::Result<&Self> {
+        set_opt(self.as_sock(), SOL_SOCKET, SO_REUSEADDR,
+               reuse as c_int).map(|()| self)
+    }
+
+    /// Check the `SO_REUSEADDR` option on this socket.
+    pub fn get_reuse_address(&self) -> io::Result<bool> {
+        get_opt(self.as_sock(), SOL_SOCKET, SO_REUSEADDR).map(int2bool)
+    }
+
+    /// Get the value of the `SO_ERROR` option on this socket.
+    ///
+    /// This will retrieve the stored error in the underlying socket, clearing
+    /// the field in the process. This can be useful for checking errors between
+    /// calls.
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        get_opt(self.as_sock(), SOL_SOCKET, SO_ERROR).map(int2err)
+    }
+
+    /// Sets the linger option for this socket
+    fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
+        set_opt(self.as_sock(), SOL_SOCKET, SO_LINGER, dur2linger(dur))
+    }
+
+    /// Gets the linger option for this socket
+    fn linger(&self) -> io::Result<Option<Duration>> {
+        get_opt(self.as_sock(), SOL_SOCKET, SO_LINGER).map(linger2dur)
+    }
+}
+
+impl UdpBuilder {
+    /// Sets the value for the `IP_TTL` option on this socket.
+    ///
+    /// This is the same as [`TcpStreamExt::set_ttl`][other].
+    ///
+    /// [other]: trait.TcpStreamExt.html#tymethod.set_ttl
+    pub fn ttl(&self, ttl: u32) -> io::Result<&Self> {
+        set_opt(self.as_sock(), IPPROTO_IP, IP_TTL, ttl as c_int)
+            .map(|()| self)
+    }
+
+    /// Sets the value for the `IPV6_V6ONLY` option on this socket.
+    ///
+    /// This is the same as [`TcpStream::only_v6`][other].
+    ///
+    /// [other]: struct.TcpBuilder.html#method.only_v6
+    pub fn only_v6(&self, only_v6: bool) -> io::Result<&Self> {
+        set_opt(self.as_sock(), v(IPPROTO_IPV6), IPV6_V6ONLY, only_v6 as c_int)
+            .map(|()| self)
+    }
+
+    /// Set value for the `SO_REUSEADDR` option on this socket.
+    ///
+    /// This is the same as [`TcpBuilder::reuse_address`][other].
+    ///
+    /// [other]: struct.TcpBuilder.html#method.reuse_address
+    pub fn reuse_address(&self, reuse: bool) -> io::Result<&Self> {
+        set_opt(self.as_sock(), SOL_SOCKET, SO_REUSEADDR,
+               reuse as c_int).map(|()| self)
+    }
+
+    /// Check the `SO_REUSEADDR` option on this socket.
+    pub fn get_reuse_address(&self) -> io::Result<bool> {
+        get_opt(self.as_sock(), SOL_SOCKET, SO_REUSEADDR).map(int2bool)
+    }
+
+    /// Get the value of the `SO_ERROR` option on this socket.
+    ///
+    /// This will retrieve the stored error in the underlying socket, clearing
+    /// the field in the process. This can be useful for checking errors between
+    /// calls.
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        get_opt(self.as_sock(), SOL_SOCKET, SO_ERROR).map(int2err)
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/net2/src/lib.rs
@@ -0,0 +1,123 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Extensions to `std::net` networking types.
+//!
+//! This crate implements a number of extensions to the standard `std::net`
+//! networking types, hopefully being slated for inclusion into the standard
+//! library in the future. The goal of this crate is to expose all sorts of
+//! cross-platform and platform-specific configuration options of UDP/TCP
+//! sockets. System APIs are wrapped with as thin a layer as possible instead of
+//! bundling multiple actions into one API call.
+//!
+//! More information about the design of this crate can be found in the
+//! [associated rfc][rfc]
+//!
+//! [rfc]: https://github.com/rust-lang/rfcs/pull/1158
+//!
+//! # Examples
+//!
+//! ```no_run
+//! use net2::TcpBuilder;
+//!
+//! let tcp = TcpBuilder::new_v4().unwrap();
+//! tcp.reuse_address(true).unwrap()
+//!    .only_v6(false).unwrap();
+//!
+//! let mut stream = tcp.connect("127.0.0.1:80").unwrap();
+//!
+//! // use `stream` as a TcpStream
+//! ```
+
+#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
+       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
+       html_root_url = "https://doc.rust-lang.org/net2-rs")]
+#![deny(missing_docs, warnings)]
+
+
+#[cfg(unix)] extern crate libc;
+
+#[cfg(windows)] extern crate kernel32;
+#[cfg(windows)] extern crate winapi;
+#[cfg(windows)] extern crate ws2_32;
+
+#[macro_use] extern crate cfg_if;
+
+use std::io;
+use std::ops::Neg;
+use std::net::{ToSocketAddrs, SocketAddr};
+
+use utils::{One, NetInt};
+
+mod tcp;
+mod udp;
+mod socket;
+mod ext;
+mod utils;
+
+#[cfg(unix)] #[path = "sys/unix/mod.rs"] mod sys;
+#[cfg(windows)] #[path = "sys/windows/mod.rs"] mod sys;
+#[cfg(all(unix, not(any(target_os = "solaris"))))] pub mod unix;
+
+pub use tcp::TcpBuilder;
+pub use udp::UdpBuilder;
+pub use ext::{TcpStreamExt, TcpListenerExt, UdpSocketExt};
+
+fn one_addr<T: ToSocketAddrs>(tsa: T) -> io::Result<SocketAddr> {
+    let mut addrs = try!(tsa.to_socket_addrs());
+    let addr = match addrs.next() {
+        Some(addr) => addr,
+        None => return Err(io::Error::new(io::ErrorKind::Other,
+                                          "no socket addresses could be resolved"))
+    };
+    if addrs.next().is_none() {
+        Ok(addr)
+    } else {
+        Err(io::Error::new(io::ErrorKind::Other,
+                           "more than one address resolved"))
+    }
+}
+
+fn cvt<T: One + PartialEq + Neg<Output=T>>(t: T) -> io::Result<T> {
+    let one: T = T::one();
+    if t == -one {
+        Err(io::Error::last_os_error())
+    } else {
+        Ok(t)
+    }
+}
+
+#[cfg(windows)]
+fn cvt_win<T: PartialEq + utils::Zero>(t: T) -> io::Result<T> {
+    if t == T::zero() {
+        Err(io::Error::last_os_error())
+    } else {
+        Ok(t)
+    }
+}
+
+fn hton<I: NetInt>(i: I) -> I { i.to_be() }
+
+fn ntoh<I: NetInt>(i: I) -> I { I::from_be(i) }
+
+trait AsInner {
+    type Inner;
+    fn as_inner(&self) -> &Self::Inner;
+}
+
+trait FromInner {
+    type Inner;
+    fn from_inner(inner: Self::Inner) -> Self;
+}
+
+trait IntoInner {
+    type Inner;
+    fn into_inner(self) -> Self::Inner;
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/net2/src/socket.rs
@@ -0,0 +1,143 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::fmt;
+use std::io;
+use std::mem;
+use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
+#[cfg(unix)]
+use libc::c_int;
+#[cfg(windows)]
+use winapi::c_int;
+
+use sys;
+use sys::c;
+
+pub struct Socket {
+    inner: sys::Socket,
+}
+
+impl Socket {
+    pub fn new(family: c_int, ty: c_int) -> io::Result<Socket> {
+        Ok(Socket { inner: try!(sys::Socket::new(family, ty)) })
+    }
+
+    pub fn bind(&self, addr: &SocketAddr) -> io::Result<()> {
+        #[cfg(not(all(any(target_arch = "aarch64", target_arch = "x86_64"), target_os = "android")))]
+        use sys::c::socklen_t as len_t;
+        #[cfg(all(any(target_arch = "aarch64", target_arch = "x86_64"), target_os = "android"))]
+        use libc::c_int as len_t;
+
+        let (addr, len) = addr2raw(addr);
+        unsafe {
+            ::cvt(c::bind(self.inner.raw(), addr, len as len_t)).map(|_| ())
+        }
+    }
+
+    pub fn listen(&self, backlog: i32) -> io::Result<()> {
+        unsafe {
+            ::cvt(c::listen(self.inner.raw(), backlog)).map(|_| ())
+        }
+    }
+
+    pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> {
+        let (addr, len) = addr2raw(addr);
+        unsafe {
+            ::cvt(c::connect(self.inner.raw(), addr, len)).map(|_| ())
+        }
+    }
+
+    pub fn getsockname(&self) -> io::Result<SocketAddr> {
+        unsafe {
+            let mut storage: c::sockaddr_storage = mem::zeroed();
+            let mut len = mem::size_of_val(&storage) as c::socklen_t;
+            try!(::cvt(c::getsockname(self.inner.raw(),
+                                      &mut storage as *mut _ as *mut _,
+                                      &mut len)));
+            raw2addr(&storage, len)
+        }
+    }
+}
+
+impl fmt::Debug for Socket {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.inner.raw().fmt(f)
+    }
+}
+
+impl ::AsInner for Socket {
+    type Inner = sys::Socket;
+    fn as_inner(&self) -> &sys::Socket { &self.inner }
+}
+
+impl ::FromInner for Socket {
+    type Inner = sys::Socket;
+    fn from_inner(sock: sys::Socket) -> Socket {
+        Socket { inner: sock }
+    }
+}
+
+impl ::IntoInner for Socket {
+    type Inner = sys::Socket;
+    fn into_inner(self) -> sys::Socket { self.inner }
+}
+
+fn addr2raw(addr: &SocketAddr) -> (*const c::sockaddr, c::socklen_t) {
+    match *addr {
+        SocketAddr::V4(ref a) => {
+            (a as *const _ as *const _, mem::size_of_val(a) as c::socklen_t)
+        }
+        SocketAddr::V6(ref a) => {
+            (a as *const _ as *const _, mem::size_of_val(a) as c::socklen_t)
+        }
+    }
+}
+
+fn raw2addr(storage: &c::sockaddr_storage, len: c::socklen_t) -> io::Result<SocketAddr> {
+    match storage.ss_family as c_int {
+        c::AF_INET => {
+            unsafe {
+                assert!(len as usize >= mem::size_of::<c::sockaddr_in>());
+                let sa = storage as *const _ as *const c::sockaddr_in;
+                let bits = c::sockaddr_in_u32(&(*sa));
+                let ip = Ipv4Addr::new((bits >> 24) as u8,
+                                       (bits >> 16) as u8,
+                                       (bits >> 8) as u8,
+                                       bits as u8);
+                Ok(SocketAddr::V4(SocketAddrV4::new(ip, ::ntoh((*sa).sin_port))))
+            }
+        }
+        c::AF_INET6 => {
+            unsafe {
+                assert!(len as usize >= mem::size_of::<c::sockaddr_in6>());
+
+                let sa = storage as *const _ as *const c::sockaddr_in6;
+                let arr = (*sa).sin6_addr.s6_addr;
+
+                let ip = Ipv6Addr::new(
+                    (arr[0] as u16) << 8 | (arr[1] as u16),
+                    (arr[2] as u16) << 8 | (arr[3] as u16),
+                    (arr[4] as u16) << 8 | (arr[5] as u16),
+                    (arr[6] as u16) << 8 | (arr[7] as u16),
+                    (arr[8] as u16) << 8 | (arr[9] as u16),
+                    (arr[10] as u16) << 8 | (arr[11] as u16),
+                    (arr[12] as u16) << 8 | (arr[13] as u16),
+                    (arr[14] as u16) << 8 | (arr[15] as u16),
+                );
+
+                Ok(SocketAddr::V6(SocketAddrV6::new(ip,
+                                                    ::ntoh((*sa).sin6_port),
+                                                    (*sa).sin6_flowinfo,
+                                                    (*sa).sin6_scope_id)))
+            }
+        }
+        _ => Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid argument")),
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/net2/src/sys/unix/impls.rs
@@ -0,0 +1,44 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::os::unix::io::{FromRawFd, AsRawFd};
+use libc::c_int;
+
+use {TcpBuilder, UdpBuilder, FromInner, AsInner};
+use socket::Socket;
+use sys;
+
+impl FromRawFd for TcpBuilder {
+    unsafe fn from_raw_fd(fd: c_int) -> TcpBuilder {
+        let sock = sys::Socket::from_inner(fd);
+        TcpBuilder::from_inner(Socket::from_inner(sock))
+    }
+}
+
+impl AsRawFd for TcpBuilder {
+    fn as_raw_fd(&self) -> c_int {
+        // TODO: this unwrap() is very bad
+        self.as_inner().borrow().as_ref().unwrap().as_inner().raw()
+    }
+}
+
+impl FromRawFd for UdpBuilder {
+    unsafe fn from_raw_fd(fd: c_int) -> UdpBuilder {
+        let sock = sys::Socket::from_inner(fd);
+        UdpBuilder::from_inner(Socket::from_inner(sock))
+    }
+}
+
+impl AsRawFd for UdpBuilder {
+    fn as_raw_fd(&self) -> c_int {
+        // TODO: this unwrap() is very bad
+        self.as_inner().borrow().as_ref().unwrap().as_inner().raw()
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/net2/src/sys/unix/mod.rs
@@ -0,0 +1,100 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+use std::io;
+use std::mem;
+use std::net::{TcpListener, TcpStream, UdpSocket};
+use std::os::unix::io::FromRawFd;
+use libc::{self, c_int};
+#[cfg(not(any(target_os = "solaris", target_os = "emscripten")))]
+use libc::{ioctl, FIOCLEX};
+
+mod impls;
+
+pub mod c {
+    pub use libc::*;
+
+    pub fn sockaddr_in_u32(sa: &sockaddr_in) -> u32 {
+        ::ntoh((*sa).sin_addr.s_addr)
+    }
+}
+
+pub struct Socket {
+    fd: c_int,
+}
+
+impl Socket {
+    #[cfg(not(any(target_os = "solaris", target_os = "emscripten")))]
+    pub fn new(family: c_int, ty: c_int) -> io::Result<Socket> {
+        unsafe {
+            // Linux >2.6.26 overloads the type argument to accept SOCK_CLOEXEC,
+            // avoiding a race with another thread running fork/exec between
+            // socket() and ioctl()
+            #[cfg(any(target_os = "linux", target_os = "android"))]
+            match ::cvt(libc::socket(family, ty | libc::SOCK_CLOEXEC, 0)) {
+                Ok(fd) => return Ok(Socket { fd: fd }),
+                // Older versions of Linux return EINVAL; fall back to ioctl
+                Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {}
+                Err(e) => return Err(e),
+            }
+
+            let fd = try!(::cvt(libc::socket(family, ty, 0)));
+            ioctl(fd, FIOCLEX);
+            Ok(Socket { fd: fd })
+        }
+    }
+
+    // ioctl(FIOCLEX) is not supported by Solaris/Illumos or emscripten,
+    // use fcntl(FD_CLOEXEC) instead
+    #[cfg(any(target_os = "solaris", target_os = "emscripten"))]
+    pub fn new(family: c_int, ty: c_int) -> io::Result<Socket> {
+        unsafe {
+            let fd = try!(::cvt(libc::socket(family, ty, 0)));
+            libc::fcntl(fd, libc::FD_CLOEXEC);
+            Ok(Socket { fd: fd })
+        }
+    }
+
+    pub fn raw(&self) -> c_int { self.fd }
+
+    fn into_fd(self) -> c_int {
+        let fd = self.fd;
+        mem::forget(self);
+        fd
+    }
+
+    pub fn into_tcp_listener(self) -> TcpListener {
+        unsafe { TcpListener::from_raw_fd(self.into_fd()) }
+    }
+
+    pub fn into_tcp_stream(self) -> TcpStream {
+        unsafe { TcpStream::from_raw_fd(self.into_fd()) }
+    }
+
+    pub fn into_udp_socket(self) -> UdpSocket {
+        unsafe { UdpSocket::from_raw_fd(self.into_fd()) }
+    }
+}
+
+impl ::FromInner for Socket {
+    type Inner = c_int;
+    fn from_inner(fd: c_int) -> Socket {
+        Socket { fd: fd }
+    }
+}
+
+impl Drop for Socket {
+    fn drop(&mut self) {
+        unsafe {
+            let _ = libc::close(self.fd);
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/net2/src/sys/windows/impls.rs
@@ -0,0 +1,44 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::os::windows::io::{FromRawSocket, AsRawSocket};
+use winapi::SOCKET;
+
+use {TcpBuilder, UdpBuilder, FromInner, AsInner};
+use socket::Socket;
+use sys;
+
+impl FromRawSocket for TcpBuilder {
+    unsafe fn from_raw_socket(fd: SOCKET) -> TcpBuilder {
+        let sock = sys::Socket::from_inner(fd);
+        TcpBuilder::from_inner(Socket::from_inner(sock))
+    }
+}
+
+impl AsRawSocket for TcpBuilder {
+    fn as_raw_socket(&self) -> SOCKET {
+        // TODO: this unwrap() is very bad
+        self.as_inner().borrow().as_ref().unwrap().as_inner().raw()
+    }
+}
+
+impl FromRawSocket for UdpBuilder {
+    unsafe fn from_raw_socket(fd: SOCKET) -> UdpBuilder {
+        let sock = sys::Socket::from_inner(fd);
+        UdpBuilder::from_inner(Socket::from_inner(sock))
+    }
+}
+
+impl AsRawSocket for UdpBuilder {
+    fn as_raw_socket(&self) -> SOCKET {
+        // TODO: this unwrap() is very bad
+        self.as_inner().borrow().as_ref().unwrap().as_inner().raw()
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/net2/src/sys/windows/mod.rs
@@ -0,0 +1,110 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(bad_style)]
+
+use std::io;
+use std::mem;
+use std::net::{TcpListener, TcpStream, UdpSocket};
+use std::os::windows::io::FromRawSocket;
+use std::sync::{Once, ONCE_INIT};
+
+use winapi::*;
+use ws2_32::*;
+use kernel32::*;
+
+const WSA_FLAG_OVERLAPPED: DWORD = 0x01;
+const HANDLE_FLAG_INHERIT: DWORD = 0x00000001;
+
+pub mod c {
+    pub use winapi::*;
+    pub use ws2_32::*;
+
+    pub use winapi::SOCKADDR as sockaddr;
+    pub use winapi::SOCKADDR_STORAGE as sockaddr_storage;
+    pub use winapi::SOCKADDR_IN as sockaddr_in;
+
+    pub fn sockaddr_in_u32(sa: &sockaddr_in) -> u32 {
+        ::ntoh(sa.sin_addr.S_un)
+    }
+}
+
+mod impls;
+
+fn init() {
+    static INIT: Once = ONCE_INIT;
+
+    INIT.call_once(|| {
+        // Initialize winsock through the standard library by just creating a
+        // dummy socket. Whether this is successful or not we drop the result as
+        // libstd will be sure to have initialized winsock.
+        let _ = UdpSocket::bind("127.0.0.1:34254");
+    });
+}
+
+pub struct Socket {
+    socket: SOCKET,
+}
+
+impl Socket {
+    pub fn new(family: c_int, ty: c_int) -> io::Result<Socket> {
+        init();
+        let socket = try!(unsafe {
+            match WSASocketW(family, ty, 0, 0 as *mut _, 0,
+                             WSA_FLAG_OVERLAPPED) {
+                INVALID_SOCKET => Err(io::Error::last_os_error()),
+                n => Ok(Socket { socket: n }),
+            }
+        });
+        try!(socket.set_no_inherit());
+        Ok(socket)
+    }
+
+    pub fn raw(&self) -> SOCKET { self.socket }
+
+    fn into_socket(self) -> SOCKET {
+        let socket = self.socket;
+        mem::forget(self);
+        socket
+    }
+
+    pub fn into_tcp_listener(self) -> TcpListener {
+        unsafe { TcpListener::from_raw_socket(self.into_socket()) }
+    }
+
+    pub fn into_tcp_stream(self) -> TcpStream {
+        unsafe { TcpStream::from_raw_socket(self.into_socket()) }
+    }
+
+    pub fn into_udp_socket(self) -> UdpSocket {
+        unsafe { UdpSocket::from_raw_socket(self.into_socket()) }
+    }
+
+    fn set_no_inherit(&self) -> io::Result<()> {
+        ::cvt_win(unsafe {
+            SetHandleInformation(self.socket as HANDLE, HANDLE_FLAG_INHERIT, 0)
+        }).map(|_| ())
+    }
+}
+
+impl ::FromInner for Socket {
+    type Inner = SOCKET;
+    fn from_inner(socket: SOCKET) -> Socket {
+        Socket { socket: socket }
+    }
+}
+
+impl Drop for Socket {
+    fn drop(&mut self) {
+        unsafe {
+            let _ = closesocket(self.socket);
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/net2/src/tcp.rs
@@ -0,0 +1,161 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::cell::RefCell;
+use std::io;
+use std::net::{SocketAddr, ToSocketAddrs, TcpListener, TcpStream};
+use std::fmt;
+
+use IntoInner;
+use socket::Socket;
+use sys::c;
+
+/// An "in progress" TCP socket which has not yet been connected or listened.
+///
+/// Allows configuration of a socket before one of these operations is executed.
+pub struct TcpBuilder {
+    socket: RefCell<Option<Socket>>,
+}
+
+impl TcpBuilder {
+    /// Constructs a new TcpBuilder with the `AF_INET` domain, the `SOCK_STREAM`
+    /// type, and with a protocol argument of 0.
+    ///
+    /// Note that passing other kinds of flags or arguments can be done through
+    /// the `FromRaw{Fd,Socket}` implementation.
+    pub fn new_v4() -> io::Result<TcpBuilder> {
+        Socket::new(c::AF_INET, c::SOCK_STREAM).map(::FromInner::from_inner)
+    }
+
+    /// Constructs a new TcpBuilder with the `AF_INET6` domain, the `SOCK_STREAM`
+    /// type, and with a protocol argument of 0.
+    ///
+    /// Note that passing other kinds of flags or arguments can be done through
+    /// the `FromRaw{Fd,Socket}` implementation.
+    pub fn new_v6() -> io::Result<TcpBuilder> {
+        Socket::new(c::AF_INET6, c::SOCK_STREAM).map(::FromInner::from_inner)
+    }
+
+    /// Binds this socket to the specified address.
+    ///
+    /// This function directly corresponds to the bind(2) function on Windows
+    /// and Unix.
+    pub fn bind<T>(&self, addr: T) -> io::Result<&TcpBuilder>
+        where T: ToSocketAddrs
+    {
+        self.with_socket(|sock| {
+            let addr = try!(::one_addr(addr));
+            sock.bind(&addr)
+        }).map(|()| self)
+    }
+
+    /// Mark a socket as ready to accept incoming connection requests using
+    /// accept()
+    ///
+    /// This function directly corresponds to the listen(2) function on Windows
+    /// and Unix.
+    ///
+    /// An error will be returned if `listen` or `connect` has already been
+    /// called on this builder.
+    pub fn listen(&self, backlog: i32) -> io::Result<TcpListener> {
+        self.with_socket(|sock| {
+            sock.listen(backlog)
+        }).and_then(|()| {
+            self.to_tcp_listener()
+        })
+    }
+
+    /// Initiate a connection on this socket to the specified address.
+    ///
+    /// This function directly corresponds to the connect(2) function on Windows
+    /// and Unix.
+    ///
+    /// An error will be returned if `listen` or `connect` has already been
+    /// called on this builder.
+    pub fn connect<T>(&self, addr: T) -> io::Result<TcpStream>
+        where T: ToSocketAddrs
+    {
+        self.with_socket(|sock| {
+            let err = io::Error::new(io::ErrorKind::Other,
+                                     "no socket addresses resolved");
+            try!(addr.to_socket_addrs()).fold(Err(err), |prev, addr| {
+                prev.or_else(|_| sock.connect(&addr))
+            })
+        }).and_then(|()| {
+            self.to_tcp_stream()
+        })
+    }
+
+    /// Converts this builder into a `TcpStream`
+    ///
+    /// This function will consume the internal socket and return it re-wrapped
+    /// as a `TcpStream`. An error will be returned if the internal socket has
+    /// already been consumed from a successful call to `connect`, `listen`,
+    /// etc.
+    pub fn to_tcp_stream(&self) -> io::Result<TcpStream> {
+        self.socket.borrow_mut().take().map(|s| s.into_inner().into_tcp_stream())
+            .ok_or(io::Error::new(io::ErrorKind::Other,
+                                  "socket has already been consumed"))
+    }
+
+    /// Converts this builder into a `TcpListener`
+    ///
+    /// This function will consume the internal socket and return it re-wrapped
+    /// as a `TcpListener`. An error will be returned if the internal socket has
+    /// already been consumed from a successful call to `connect`, `listen`,
+    /// etc.
+    pub fn to_tcp_listener(&self) -> io::Result<TcpListener> {
+        self.socket.borrow_mut().take()
+            .map(|s| s.into_inner().into_tcp_listener())
+            .ok_or(io::Error::new(io::ErrorKind::Other,
+                                  "socket has already been consumed"))
+    }
+
+    /// Returns the address of the local half of this TCP socket.
+    ///
+    /// An error will be returned if `listen` or `connect` has already been
+    /// called on this builder.
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
+        match *self.socket.borrow() {
+            Some(ref s) => s.getsockname(),
+            None => Err(io::Error::new(io::ErrorKind::Other,
+                                       "builder has already finished its socket")),
+        }
+    }
+
+    fn with_socket<F>(&self, f: F) -> io::Result<()>
+        where F: FnOnce(&Socket) -> io::Result<()>
+    {
+        match *self.socket.borrow() {
+            Some(ref s) => f(s),
+            None => Err(io::Error::new(io::ErrorKind::Other,
+                                       "builder has already finished its socket")),
+        }
+    }
+}
+
+impl fmt::Debug for TcpBuilder {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "TcpBuilder {{ socket: {:?} }}",
+               self.socket.borrow().as_ref().unwrap())
+    }
+}
+
+impl ::AsInner for TcpBuilder {
+    type Inner = RefCell<Option<Socket>>;
+    fn as_inner(&self) -> &RefCell<Option<Socket>> { &self.socket }
+}
+
+impl ::FromInner for TcpBuilder {
+    type Inner = Socket;
+    fn from_inner(sock: Socket) -> TcpBuilder {
+        TcpBuilder { socket: RefCell::new(Some(sock)) }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/net2/src/udp.rs
@@ -0,0 +1,89 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::cell::RefCell;
+use std::fmt;
+use std::io;
+use std::net::{ToSocketAddrs, UdpSocket};
+
+use IntoInner;
+use socket::Socket;
+use sys::c;
+
+/// An "in progress" UDP socket which has not yet been connected.
+///
+/// Allows configuration of a socket before the socket is connected.
+pub struct UdpBuilder {
+    socket: RefCell<Option<Socket>>,
+}
+
+impl UdpBuilder {
+    /// Constructs a new UdpBuilder with the `AF_INET` domain, the `SOCK_DGRAM`
+    /// type, and with a protocol argument of 0.
+    ///
+    /// Note that passing other kinds of flags or arguments can be done through
+    /// the `FromRaw{Fd,Socket}` implementation.
+    pub fn new_v4() -> io::Result<UdpBuilder> {
+        Socket::new(c::AF_INET, c::SOCK_DGRAM).map(::FromInner::from_inner)
+    }
+
+    /// Constructs a new UdpBuilder with the `AF_INET6` domain, the `SOCK_DGRAM`
+    /// type, and with a protocol argument of 0.
+    ///
+    /// Note that passing other kinds of flags or arguments can be done through
+    /// the `FromRaw{Fd,Socket}` implementation.
+    pub fn new_v6() -> io::Result<UdpBuilder> {
+        Socket::new(c::AF_INET6, c::SOCK_DGRAM).map(::FromInner::from_inner)
+    }
+
+    /// Binds this socket to the specified address.
+    ///
+    /// This function directly corresponds to the bind(2) function on Windows
+    /// and Unix.
+    pub fn bind<T>(&self, addr: T) -> io::Result<UdpSocket>
+        where T: ToSocketAddrs
+    {
+        try!(self.with_socket(|sock| {
+            let addr = try!(::one_addr(addr));
+            sock.bind(&addr)
+        }));
+        Ok(self.socket.borrow_mut().take().unwrap().into_inner().into_udp_socket())
+    }
+
+    fn with_socket<F>(&self, f: F) -> io::Result<()>
+        where F: FnOnce(&Socket) -> io::Result<()>
+    {
+        match *self.socket.borrow() {
+            Some(ref s) => f(s),
+            None => Err(io::Error::new(io::ErrorKind::Other,
+                                       "builder has already finished its socket")),
+        }
+    }
+}
+
+impl fmt::Debug for UdpBuilder {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "UdpBuilder {{ socket: {:?} }}",
+               self.socket.borrow().as_ref().unwrap())
+    }
+}
+
+impl ::AsInner for UdpBuilder {
+    type Inner = RefCell<Option<Socket>>;
+    fn as_inner(&self) -> &RefCell<Option<Socket>> { &self.socket }
+}
+
+impl ::FromInner for UdpBuilder {
+    type Inner = Socket;
+    fn from_inner(sock: Socket) -> UdpBuilder {
+        UdpBuilder { socket: RefCell::new(Some(sock)) }
+    }
+}
+
new file mode 100644
--- /dev/null
+++ b/third_party/rust/net2/src/unix.rs
@@ -0,0 +1,57 @@
+//! Unix-specific extensions to the `std::net` types.
+
+use std::io;
+use sys::c::{self, c_int};
+
+use {TcpBuilder, UdpBuilder};
+use ext::{self, AsSock};
+
+/// Unix-specific extensions for the `TcpBuilder` type in this library.
+pub trait UnixTcpBuilderExt {
+    /// Set value for the `SO_REUSEPORT` option on this socket.
+    ///
+    /// This indicates that futher calls to `bind` may allow reuse of local
+    /// addresses. For IPv4 sockets this means that a socket may bind even when
+    /// there's a socket already listening on this port.
+    fn reuse_port(&self, reuse: bool) -> io::Result<&Self>;
+
+    /// Check the value of the `SO_REUSEPORT` option on this socket.
+    fn get_reuse_port(&self) -> io::Result<bool>;
+}
+
+impl UnixTcpBuilderExt for TcpBuilder {
+    fn reuse_port(&self, reuse: bool) -> io::Result<&Self> {
+        ext::set_opt(self.as_sock(), c::SOL_SOCKET, c::SO_REUSEPORT,
+                    reuse as c_int).map(|()| self)
+    }
+
+    fn get_reuse_port(&self) -> io::Result<bool> {
+        ext::get_opt(self.as_sock(), c::SOL_SOCKET, c::SO_REUSEPORT)
+            .map(ext::int2bool)
+    }
+}
+
+/// Unix-specific extensions for the `UdpBuilder` type in this library.
+pub trait UnixUdpBuilderExt {
+    /// Set value for the `SO_REUSEPORT` option on this socket.
+    ///
+    /// This indicates that futher calls to `bind` may allow reuse of local
+    /// addresses. For IPv4 sockets this means that a socket may bind even when
+    /// there's a socket already listening on this port.
+    fn reuse_port(&self, reuse: bool) -> io::Result<&Self>;
+
+    /// Check the value of the `SO_REUSEPORT` option on this socket.
+    fn get_reuse_port(&self) -> io::Result<bool>;
+}
+
+impl UnixUdpBuilderExt for UdpBuilder {
+    fn reuse_port(&self, reuse: bool) -> io::Result<&Self> {
+        ext::set_opt(self.as_sock(), c::SOL_SOCKET, c::SO_REUSEPORT,
+                    reuse as c_int).map(|()| self)
+    }
+
+    fn get_reuse_port(&self) -> io::Result<bool> {
+        ext::get_opt(self.as_sock(), c::SOL_SOCKET, c::SO_REUSEPORT)
+            .map(ext::int2bool)
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/net2/src/utils.rs
@@ -0,0 +1,51 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+#[doc(hidden)]
+pub trait NetInt {
+    fn from_be(i: Self) -> Self;
+    fn to_be(&self) -> Self;
+}
+macro_rules! doit {
+    ($($t:ident)*) => ($(impl NetInt for $t {
+        fn from_be(i: Self) -> Self { <$t>::from_be(i) }
+        fn to_be(&self) -> Self { <$t>::to_be(*self) }
+    })*)
+}
+doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
+
+#[doc(hidden)]
+pub trait One {
+    fn one() -> Self;
+}
+
+macro_rules! one {
+    ($($t:ident)*) => ($(
+        impl One for $t { fn one() -> $t { 1 } }
+    )*)
+}
+
+one! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
+
+
+#[doc(hidden)]
+pub trait Zero {
+    fn zero() -> Self;
+}
+
+macro_rules! zero {
+    ($($t:ident)*) => ($(
+        impl Zero for $t { fn zero() -> $t { 0 } }
+    )*)
+}
+
+zero! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
+
new file mode 100644
--- /dev/null
+++ b/third_party/rust/net2/tests/all.rs
@@ -0,0 +1,45 @@
+extern crate net2;
+
+use std::net::{TcpStream, IpAddr, Ipv4Addr, Ipv6Addr};
+use std::io::prelude::*;
+use std::thread;
+
+use net2::TcpBuilder;
+
+macro_rules! t {
+    ($e:expr) => (match $e {
+        Ok(e) => e,
+        Err(e) => panic!("{} failed with: {}", stringify!($e), e),
+    })
+}
+
+#[test]
+fn smoke_build_listener() {
+    let b = t!(TcpBuilder::new_v4());
+    t!(b.bind("127.0.0.1:0"));
+
+    let addr = t!(b.local_addr());
+    assert_eq!(addr.ip(), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
+
+    let listener = t!(b.listen(200));
+
+    let t = thread::spawn(move || {
+        let mut s = t!(listener.accept()).0;
+        let mut b = [0; 4];
+        t!(s.read(&mut b));
+        assert_eq!(b, [1, 2, 3, 0]);
+    });
+
+    let mut stream = t!(TcpStream::connect(&addr));
+    t!(stream.write(&[1,2,3]));
+    t.join().unwrap();
+}
+
+#[test]
+fn smoke_build_listener_v6() {
+    let b = t!(TcpBuilder::new_v6());
+    t!(b.bind("::1:0"));
+
+    let addr = t!(b.local_addr());
+    assert_eq!(addr.ip(), IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)));
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/slab/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"4cd8cbaedfe34dd4e0cc476e1484dc950b7ae90b693073fa89a298b014e6c0a1","README.md":"36ba748d4deb1875f5355dbf997be6ef1cb857709d78db7127c24d640e90300a","src/lib.rs":"003277f46755d1870148756841dbaad216109812cd659e4862e220e7a5b0c963"},"package":"17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"}
\ No newline at end of file
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/third_party/rust/slab/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+
+name = "slab"
+version = "0.3.0"
+license = "MIT"
+authors = ["Carl Lerche <me@carllerche.com>"]
+description = "Simple slab allocator"
+documentation = "https://docs.rs/slab/0.3.0/slab/"
+homepage = "https://github.com/carllerche/slab"
+repository = "https://github.com/carllerche/slab"
+readme = "README.md"
+keywords = ["slab", "allocator"]
+exclude = [
+    ".gitignore",
+    ".travis.yml",
+    "test/**/*",
+]
new file mode 100644
--- /dev/null
+++ b/third_party/rust/slab/README.md
@@ -0,0 +1,3 @@
+Slab Allocator for Rust
+
+Preallocate memory for values of a given type.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/slab/src/lib.rs
@@ -0,0 +1,837 @@
+use std::{fmt, mem, usize};
+use std::iter::IntoIterator;
+use std::ops;
+use std::marker::PhantomData;
+
+/// A preallocated chunk of memory for storing objects of the same type.
+pub struct Slab<T, I = usize> {
+    // Chunk of memory
+    entries: Vec<Slot<T>>,
+
+    // Number of Filled elements currently in the slab
+    len: usize,
+
+    // Offset of the next available slot in the slab. Set to the slab's
+    // capacity when the slab is full.
+    next: usize,
+
+    _marker: PhantomData<I>,
+}
+
+/// A handle to an occupied slot in the `Slab`
+pub struct Entry<'a, T: 'a, I: 'a> {
+    slab: &'a mut Slab<T, I>,
+    idx: usize,
+}
+
+/// A handle to a vacant slot in the `Slab`
+pub struct VacantEntry<'a, T: 'a, I: 'a> {
+    slab: &'a mut Slab<T, I>,
+    idx: usize,
+}
+
+/// An iterator over the values stored in the `Slab`
+pub struct Iter<'a, T: 'a, I: 'a> {
+    slab: &'a Slab<T, I>,
+    cur_idx: usize,
+    yielded: usize,
+}
+
+/// A mutable iterator over the values stored in the `Slab`
+pub struct IterMut<'a, T: 'a, I: 'a> {
+    slab: *mut Slab<T, I>,
+    cur_idx: usize,
+    yielded: usize,
+    _marker: PhantomData<&'a mut ()>,
+}
+
+enum Slot<T> {
+    Empty(usize),
+    Filled(T),
+    Invalid,
+}
+
+unsafe impl<T, I> Send for Slab<T, I> where T: Send {}
+
+macro_rules! some {
+    ($expr:expr) => (match $expr {
+        Some(val) => val,
+        None => return None,
+    })
+}
+
+impl<T, I> Slab<T, I> {
+    /// Returns an empty `Slab` with the requested capacity
+    pub fn with_capacity(capacity: usize) -> Slab<T, I> {
+        let entries = (1..capacity + 1)
+            .map(Slot::Empty)
+            .collect::<Vec<_>>();
+
+        Slab {
+            entries: entries,
+            next: 0,
+            len: 0,
+            _marker: PhantomData,
+        }
+    }
+
+    /// Returns the number of values stored by the `Slab`
+    pub fn len(&self) -> usize {
+        self.len
+    }
+
+    /// Returns the total capacity of the `Slab`
+    pub fn capacity(&self) -> usize {
+        self.entries.len()
+    }
+
+    /// Returns true if the `Slab` is storing no values
+    pub fn is_empty(&self) -> bool {
+        self.len == 0
+    }
+
+    /// Returns the number of available slots remaining in the `Slab`
+    pub fn available(&self) -> usize {
+        self.entries.len() - self.len
+    }
+
+    /// Returns true if the `Slab` has available slots
+    pub fn has_available(&self) -> bool {
+        self.available() > 0
+    }
+}
+
+impl<T, I: Into<usize> + From<usize>> Slab<T, I> {
+    /// Returns true if the `Slab` contains a value for the given token
+    pub fn contains(&self, idx: I) -> bool {
+        self.get(idx).is_some()
+    }
+
+    /// Get a reference to the value associated with the given token
+    pub fn get(&self, idx: I) -> Option<&T> {
+        let idx = some!(self.local_index(idx));
+
+        match self.entries[idx] {
+            Slot::Filled(ref val) => Some(val),
+            Slot::Empty(_) => None,
+            Slot::Invalid => panic!("Slab corrupt"),
+        }
+    }
+
+    /// Get a mutable reference to the value associated with the given token
+    pub fn get_mut(&mut self, idx: I) -> Option<&mut T> {
+        let idx = some!(self.local_index(idx));
+
+        match self.entries[idx] {
+            Slot::Filled(ref mut v) => Some(v),
+            _ => None,
+        }
+    }
+
+    /// Insert a value into the slab, returning the associated token
+    pub fn insert(&mut self, val: T) -> Result<I, T> {
+        match self.vacant_entry() {
+            Some(entry) => Ok(entry.insert(val).index()),
+            None => Err(val),
+        }
+    }
+
+    /// Returns a handle to an entry.
+    ///
+    /// This allows more advanced manipulation of the value stored at the given
+    /// index.
+    pub fn entry(&mut self, idx: I) -> Option<Entry<T, I>> {
+        let idx = some!(self.local_index(idx));
+
+        match self.entries[idx] {
+            Slot::Filled(_) => {
+                Some(Entry {
+                    slab: self,
+                    idx: idx,
+                })
+            }
+            Slot::Empty(_) => None,
+            Slot::Invalid => panic!("Slab corrupt"),
+        }
+    }
+
+    /// Returns a handle to a vacant entry.
+    ///
+    /// This allows optionally inserting a value that is constructed with the
+    /// index.
+    pub fn vacant_entry(&mut self) -> Option<VacantEntry<T, I>> {
+        let idx = self.next;
+
+        if idx >= self.entries.len() {
+            return None;
+        }
+
+        Some(VacantEntry {
+            slab: self,
+            idx: idx,
+        })
+    }
+
+    /// Releases the given slot
+    pub fn remove(&mut self, idx: I) -> Option<T> {
+        self.entry(idx).map(Entry::remove)
+    }
+
+    /// Retain only the elements specified by the predicate.
+    ///
+    /// In other words, remove all elements `e` such that `f(&e)` returns false.
+    /// This method operates in place and preserves the order of the retained
+    /// elements.
+    pub fn retain<F>(&mut self, mut f: F)
+        where F: FnMut(&T) -> bool
+    {
+        for i in 0..self.entries.len() {
+            if let Some(e) = self.entry(I::from(i)) {
+                if !f(e.get()) {
+                    e.remove();
+                }
+            }
+        }
+    }
+
+    /// An iterator for visiting all elements stored in the `Slab`
+    pub fn iter(&self) -> Iter<T, I> {
+        Iter {
+            slab: self,
+            cur_idx: 0,
+            yielded: 0,
+        }
+    }
+
+    /// A mutable iterator for visiting all elements stored in the `Slab`
+    pub fn iter_mut(&mut self) -> IterMut<T, I> {
+        IterMut {
+            slab: self as *mut Slab<T, I>,
+            cur_idx: 0,
+            yielded: 0,
+            _marker: PhantomData,
+        }
+    }
+
+    /// Empty the slab, by freeing all entries
+    pub fn clear(&mut self) {
+        for (i, e) in self.entries.iter_mut().enumerate() {
+            *e = Slot::Empty(i + 1)
+        }
+        self.next = 0;
+        self.len = 0;
+    }
+
+    /// Reserves the minimum capacity for exactly `additional` more elements to
+    /// be inserted in the given `Slab`. Does nothing if the capacity is
+    /// already sufficient.
+    pub fn reserve_exact(&mut self, additional: usize) {
+        let prev_len = self.entries.len();
+
+        // Ensure `entries_num` isn't too big
+        assert!(additional < usize::MAX - prev_len, "capacity too large");
+
+        let prev_len_next = prev_len + 1;
+        self.entries.extend((prev_len_next..(prev_len_next + additional)).map(Slot::Empty));
+
+        debug_assert_eq!(self.entries.len(), prev_len + additional);
+    }
+
+    fn insert_at(&mut self, idx: usize, value: T) -> I {
+        self.next = match self.entries[idx] {
+            Slot::Empty(next) => next,
+            Slot::Filled(_) => panic!("Index already contains value"),
+            Slot::Invalid => panic!("Slab corrupt"),
+        };
+
+        self.entries[idx] = Slot::Filled(value);
+        self.len += 1;
+
+        I::from(idx)
+    }
+
+    fn replace(&mut self, idx: usize, e: Slot<T>) -> Option<T> {
+        if let Slot::Filled(val) = mem::replace(&mut self.entries[idx], e) {
+            self.next = idx;
+            return Some(val);
+        }
+
+        None
+    }
+
+    fn local_index(&self, idx: I) -> Option<usize> {
+        let idx: usize = idx.into();
+
+        if idx >= self.entries.len() {
+            return None;
+        }
+
+        Some(idx)
+    }
+}
+
+impl<T, I: From<usize> + Into<usize>> ops::Index<I> for Slab<T, I> {
+    type Output = T;
+
+    fn index(&self, index: I) -> &T {
+        self.get(index).expect("invalid index")
+    }
+}
+
+impl<T, I: From<usize> + Into<usize>> ops::IndexMut<I> for Slab<T, I> {
+    fn index_mut(&mut self, index: I) -> &mut T {
+        self.get_mut(index).expect("invalid index")
+    }
+}
+
+impl<T, I> fmt::Debug for Slab<T, I>
+    where T: fmt::Debug,
+          I: fmt::Debug,
+{
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        write!(fmt,
+               "Slab {{ len: {}, cap: {} }}",
+               self.len,
+               self.capacity())
+    }
+}
+
+impl<'a, T, I: From<usize> + Into<usize>> IntoIterator for &'a Slab<T, I> {
+    type Item = &'a T;
+    type IntoIter = Iter<'a, T, I>;
+
+    fn into_iter(self) -> Iter<'a, T, I> {
+        self.iter()
+    }
+}
+
+impl<'a, T, I: From<usize> + Into<usize>> IntoIterator for &'a mut Slab<T, I> {
+    type Item = &'a mut T;
+    type IntoIter = IterMut<'a, T, I>;
+
+    fn into_iter(self) -> IterMut<'a, T, I> {
+        self.iter_mut()
+    }
+}
+
+/*
+ *
+ * ===== Entry =====
+ *
+ */
+
+impl<'a, T, I: From<usize> + Into<usize>> Entry<'a, T, I> {
+
+    /// Replace the value stored in the entry
+    pub fn replace(&mut self, val: T) -> T {
+        match mem::replace(&mut self.slab.entries[self.idx], Slot::Filled(val)) {
+            Slot::Filled(v) => v,
+            _ => panic!("Slab corrupt"),
+        }
+    }
+
+    /// Apply the function to the current value, replacing it with the result
+    /// of the function.
+    pub fn replace_with<F>(&mut self, f: F)
+        where F: FnOnce(T) -> T
+    {
+        let idx = self.idx;
+
+        // Take the value out of the entry, temporarily setting it to Invalid
+        let val = match mem::replace(&mut self.slab.entries[idx], Slot::Invalid) {
+            Slot::Filled(v) => f(v),
+            _ => panic!("Slab corrupt"),
+        };
+
+        self.slab.entries[idx] = Slot::Filled(val);
+    }
+
+    /// Remove and return the value stored in the entry
+    pub fn remove(self) -> T {
+        let next = self.slab.next;
+
+        if let Some(v) = self.slab.replace(self.idx, Slot::Empty(next)) {
+            self.slab.len -= 1;
+            v
+        } else {
+            panic!("Slab corrupt");
+        }
+    }
+
+    /// Get a reference to the value stored in the entry
+    pub fn get(&self) -> &T {
+        let idx = self.index();
+        self.slab
+            .get(idx)
+            .expect("Filled slot in Entry")
+    }
+
+    /// Get a mutable reference to the value stored in the entry
+    pub fn get_mut(&mut self) -> &mut T {
+        let idx = self.index();
+        self.slab
+            .get_mut(idx)
+            .expect("Filled slot in Entry")
+    }
+
+    /// Convert the entry handle to a mutable reference
+    pub fn into_mut(self) -> &'a mut T {
+        let idx = self.index();
+        self.slab
+            .get_mut(idx)
+            .expect("Filled slot in Entry")
+    }
+
+    /// Return the entry index
+    pub fn index(&self) -> I {
+        I::from(self.idx)
+    }
+}
+
+/*
+ *
+ * ===== VacantEntry =====
+ *
+ */
+
+impl<'a, T, I: From<usize> + Into<usize>> VacantEntry<'a, T, I> {
+    /// Insert a value into the entry
+    pub fn insert(self, val: T) -> Entry<'a, T, I> {
+        self.slab.insert_at(self.idx, val);
+
+        Entry {
+            slab: self.slab,
+            idx: self.idx,
+        }
+    }
+
+    /// Returns the entry index
+    pub fn index(&self) -> I {
+        I::from(self.idx)
+    }
+}
+
+/*
+ *
+ * ===== Iter =====
+ *
+ */
+
+impl<'a, T, I> Iterator for Iter<'a, T, I> {
+    type Item = &'a T;
+
+    fn next(&mut self) -> Option<&'a T> {
+        while self.yielded < self.slab.len {
+            match self.slab.entries[self.cur_idx] {
+                Slot::Filled(ref v) => {
+                    self.cur_idx += 1;
+                    self.yielded += 1;
+                    return Some(v);
+                }
+                Slot::Empty(_) => {
+                    self.cur_idx += 1;
+                }
+                Slot::Invalid => {
+                    panic!("Slab corrupt");
+                }
+            }
+        }
+
+        None
+    }
+}
+
+/*
+ *
+ * ===== IterMut =====
+ *
+ */
+
+impl<'a, T, I> Iterator for IterMut<'a, T, I> {
+    type Item = &'a mut T;
+
+    fn next(&mut self) -> Option<&'a mut T> {
+        unsafe {
+            while self.yielded < (*self.slab).len {
+                let idx = self.cur_idx;
+
+                match (*self.slab).entries[idx] {
+                    Slot::Filled(ref mut v) => {
+                        self.cur_idx += 1;
+                        self.yielded += 1;
+                        return Some(v);
+                    }
+                    Slot::Empty(_) => {
+                        self.cur_idx += 1;
+                    }
+                    Slot::Invalid => {
+                        panic!("Slab corrupt");
+                    }
+                }
+            }
+
+            None
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+    pub struct MyIndex(pub usize);
+
+    impl From<usize> for MyIndex {
+        fn from(i: usize) -> MyIndex {
+            MyIndex(i)
+        }
+    }
+
+    impl Into<usize> for MyIndex {
+        fn into(self) -> usize {
+            self.0
+        }
+    }
+
+    #[test]
+    fn test_index_trait() {
+        let mut slab = Slab::<usize, MyIndex>::with_capacity(1);
+        let idx = slab.insert(10).ok().expect("Failed to insert");
+        assert_eq!(idx, MyIndex(0));
+        assert_eq!(slab[idx], 10);
+    }
+
+    #[test]
+    fn test_insertion() {
+        let mut slab = Slab::<usize, usize>::with_capacity(1);
+        assert_eq!(slab.is_empty(), true);
+        assert_eq!(slab.has_available(), true);
+        assert_eq!(slab.available(), 1);
+        let idx = slab.insert(10).ok().expect("Failed to insert");
+        assert_eq!(slab[idx], 10);
+        assert_eq!(slab.is_empty(), false);
+        assert_eq!(slab.has_available(), false);
+        assert_eq!(slab.available(), 0);
+    }
+
+    #[test]
+    fn test_insert_with() {
+        let mut slab = Slab::<usize, usize>::with_capacity(1);
+
+        {
+            let e = slab.vacant_entry().unwrap();
+            assert_eq!(e.index(), 0);
+            let e = e.insert(5);
+            assert_eq!(5, *e.get());
+        }
+
+        assert_eq!(Some(&5), slab.get(0));
+    }
+
+    #[test]
+    fn test_repeated_insertion() {
+        let mut slab = Slab::<usize, usize>::with_capacity(10);
+
+        for i in 0..10 {
+            let idx = slab.insert(i + 10).ok().expect("Failed to insert");
+            assert_eq!(slab[idx], i + 10);
+        }
+
+        slab.insert(20).err().expect("Inserted when full");
+    }
+
+    #[test]
+    fn test_repeated_insertion_and_removal() {
+        let mut slab = Slab::<usize, usize>::with_capacity(10);
+        let mut indices = vec![];
+
+        for i in 0..10 {
+            let idx = slab.insert(i + 10).ok().expect("Failed to insert");
+            indices.push(idx);
+            assert_eq!(slab[idx], i + 10);
+        }
+
+        for &i in indices.iter() {
+            slab.remove(i);
+        }
+
+        slab.insert(20).ok().expect("Failed to insert in newly empty slab");
+    }
+
+    #[test]
+    fn test_insertion_when_full() {
+        let mut slab = Slab::<usize, usize>::with_capacity(1);
+        slab.insert(10).ok().expect("Failed to insert");
+        slab.insert(10).err().expect("Inserted into a full slab");
+    }
+
+    #[test]
+    fn test_removal_at_boundries() {
+        let mut slab = Slab::<usize, usize>::with_capacity(1);
+        assert_eq!(slab.remove(0), None);
+        assert_eq!(slab.remove(1), None);
+    }
+
+    #[test]
+    fn test_removal_is_successful() {
+        let mut slab = Slab::<usize, usize>::with_capacity(1);
+        let t1 = slab.insert(10).ok().expect("Failed to insert");
+        slab.remove(t1);
+        let t2 = slab.insert(20).ok().expect("Failed to insert");
+        assert_eq!(slab[t2], 20);
+    }
+
+    #[test]
+    fn test_remove_empty_entry() {
+        let mut s = Slab::<(), usize>::with_capacity(3);
+        let t1 = s.insert(()).unwrap();
+        assert!(s.remove(t1).is_some());
+        assert!(s.remove(t1).is_none());
+        assert!(s.insert(()).is_ok());
+        assert!(s.insert(()).is_ok());
+    }
+
+    #[test]
+    fn test_mut_retrieval() {
+        let mut slab = Slab::<_, usize>::with_capacity(1);
+        let t1 = slab.insert("foo".to_string()).ok().expect("Failed to insert");
+
+        slab[t1].push_str("bar");
+
+        assert_eq!(&slab[t1][..], "foobar");
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_reusing_slots_1() {
+        let mut slab = Slab::<usize, usize>::with_capacity(16);
+
+        let t0 = slab.insert(123).unwrap();
+        let t1 = slab.insert(456).unwrap();
+
+        assert!(slab.len() == 2);
+        assert!(slab.available() == 14);
+
+        slab.remove(t0);
+
+        assert!(slab.len() == 1, "actual={}", slab.len());
+        assert!(slab.available() == 15);
+
+        slab.remove(t1);
+
+        assert!(slab.len() == 0);
+        assert!(slab.available() == 16);
+
+        let _ = slab[t1];
+    }
+
+    #[test]
+    fn test_reusing_slots_2() {
+        let mut slab = Slab::<usize, usize>::with_capacity(16);
+
+        let t0 = slab.insert(123).unwrap();
+
+        assert!(slab[t0] == 123);
+        assert!(slab.remove(t0) == Some(123));
+
+        let t0 = slab.insert(456).unwrap();
+
+        assert!(slab[t0] == 456);
+
+        let t1 = slab.insert(789).unwrap();
+
+        assert!(slab[t0] == 456);
+        assert!(slab[t1] == 789);
+
+        assert!(slab.remove(t0).unwrap() == 456);
+        assert!(slab.remove(t1).unwrap() == 789);
+
+        assert!(slab.len() == 0);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_accessing_out_of_bounds() {
+        let slab = Slab::<usize, usize>::with_capacity(16);
+        slab[0];
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_capacity_too_large1() {
+        use std::usize;
+        Slab::<usize, usize>::with_capacity(usize::MAX);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_capacity_too_large_in_reserve_exact() {
+        use std::usize;
+        let mut slab = Slab::<usize, usize>::with_capacity(100);
+        slab.reserve_exact(usize::MAX - 100);
+    }
+
+    #[test]
+    fn test_contains() {
+        let mut slab = Slab::with_capacity(16);
+        assert!(!slab.contains(0));
+
+        let idx = slab.insert(111).unwrap();
+        assert!(slab.contains(idx));
+    }
+
+    #[test]
+    fn test_get() {
+        let mut slab = Slab::<usize, usize>::with_capacity(16);
+        let tok = slab.insert(5).unwrap();
+        assert_eq!(slab.get(tok), Some(&5));
+        assert_eq!(slab.get(1), None);
+        assert_eq!(slab.get(23), None);
+    }
+
+    #[test]
+    fn test_get_mut() {
+        let mut slab = Slab::<u32, usize>::with_capacity(16);
+        let tok = slab.insert(5u32).unwrap();
+        {
+            let mut_ref = slab.get_mut(tok).unwrap();
+            assert_eq!(*mut_ref, 5);
+            *mut_ref = 12;
+        }
+        assert_eq!(slab[tok], 12);
+        assert_eq!(slab.get_mut(1), None);
+        assert_eq!(slab.get_mut(23), None);
+    }
+
+    #[test]
+    fn test_replace() {
+        let mut slab = Slab::<usize, usize>::with_capacity(16);
+        let tok = slab.insert(5).unwrap();
+
+        slab.entry(tok).unwrap().replace(6);
+        assert!(slab.entry(tok + 1).is_none());
+
+        assert_eq!(slab[tok], 6);
+        assert_eq!(slab.len(), 1);
+    }
+
+    #[test]
+    fn test_replace_again() {
+        let mut slab = Slab::<usize, usize>::with_capacity(16);
+        let tok = slab.insert(5).unwrap();
+
+        slab.entry(tok).unwrap().replace(6);
+        slab.entry(tok).unwrap().replace(7);
+        slab.entry(tok).unwrap().replace(8);
+        assert_eq!(slab[tok], 8);
+    }
+
+    #[test]
+    fn test_replace_with() {
+        let mut slab = Slab::<u32, usize>::with_capacity(16);
+        let tok = slab.insert(5u32).unwrap();
+        slab.entry(tok).unwrap().replace_with(|x| x + 1);
+        assert_eq!(slab[tok], 6);
+    }
+
+    #[test]
+    fn test_retain() {
+        let mut slab = Slab::<usize, usize>::with_capacity(2);
+        let tok1 = slab.insert(0).unwrap();
+        let tok2 = slab.insert(1).unwrap();
+        slab.retain(|x| x % 2 == 0);
+        assert_eq!(slab.len(), 1);
+        assert_eq!(slab[tok1], 0);
+        assert_eq!(slab.contains(tok2), false);
+    }
+
+    #[test]
+    fn test_iter() {
+        let mut slab = Slab::<u32, usize>::with_capacity(4);
+        for i in 0..4 {
+            slab.insert(i).unwrap();
+        }
+
+        let vals: Vec<u32> = slab.iter().map(|r| *r).collect();
+        assert_eq!(vals, vec![0, 1, 2, 3]);
+
+        slab.remove(1);
+
+        let vals: Vec<u32> = slab.iter().map(|r| *r).collect();
+        assert_eq!(vals, vec![0, 2, 3]);
+    }
+
+    #[test]
+    fn test_iter_mut() {
+        let mut slab = Slab::<u32, usize>::with_capacity(4);
+        for i in 0..4 {
+            slab.insert(i).unwrap();
+        }
+        for e in slab.iter_mut() {
+            *e = *e + 1;
+        }
+
+        let vals: Vec<u32> = slab.iter().map(|r| *r).collect();
+        assert_eq!(vals, vec![1, 2, 3, 4]);
+
+        slab.remove(2);
+        for e in slab.iter_mut() {
+            *e = *e + 1;
+        }
+
+        let vals: Vec<u32> = slab.iter().map(|r| *r).collect();
+        assert_eq!(vals, vec![2, 3, 5]);
+    }
+
+    #[test]
+    fn test_reserve_exact() {
+        let mut slab = Slab::<u32, usize>::with_capacity(4);
+        for i in 0..4 {
+            slab.insert(i).unwrap();
+        }
+
+        assert!(slab.insert(0).is_err());
+
+        slab.reserve_exact(3);
+
+        let vals: Vec<u32> = slab.iter().map(|r| *r).collect();
+        assert_eq!(vals, vec![0, 1, 2, 3]);
+
+        for i in 0..3 {
+            slab.insert(i).unwrap();
+        }
+        assert!(slab.insert(0).is_err());
+
+        let vals: Vec<u32> = slab.iter().map(|r| *r).collect();
+        assert_eq!(vals, vec![0, 1, 2, 3, 0, 1, 2]);
+    }
+
+    #[test]
+    fn test_clear() {
+        let mut slab = Slab::<u32, usize>::with_capacity(4);
+        for i in 0..4 {
+            slab.insert(i).unwrap();
+        }
+
+        // clear full
+        slab.clear();
+
+        let vals: Vec<u32> = slab.iter().map(|r| *r).collect();
+        assert_eq!(vals, vec![]);
+
+        for i in 0..2 {
+            slab.insert(i).unwrap();
+        }
+
+        let vals: Vec<u32> = slab.iter().map(|r| *r).collect();
+        assert_eq!(vals, vec![0, 1]);
+
+
+        // clear half-filled
+        slab.clear();
+
+        let vals: Vec<u32> = slab.iter().map(|r| *r).collect();
+        assert_eq!(vals, vec![]);
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/ws2_32-sys/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"b5c32ebeb474fcf68bd5d6f296f12163d1627dca02dbe06341ee3d378535cdaa","README.md":"ad92627d07dcd015a10440590041e72723b1e5a3ca86f50d6d059e7e4e78433f","build.rs":"84b7d5871797983a021d1ae8cd9698687b7d2bddd4622e82b30c693218400f09","src/lib.rs":"71b9f929fe5227d63326e71ed2f49a96adb560318b8862d55927aac2d247e82d"},"package":"d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"}
\ No newline at end of file
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/third_party/rust/ws2_32-sys/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "ws2_32-sys"
+version = "0.2.1"
+authors = ["Peter Atashian <retep998@gmail.com>"]
+description = "Contains function definitions for the Windows API library ws2_32. See winapi for types and constants."
+documentation = "https://retep998.github.io/doc/ws2_32/"
+repository = "https://github.com/retep998/winapi-rs"
+readme = "README.md"
+keywords = ["windows", "ffi", "win32"]
+license = "MIT"
+build = "build.rs"
+[lib]
+name = "ws2_32"
+[dependencies]
+winapi = { version = "0.2.5", path = "../.." }
+[build-dependencies]
+winapi-build = { version = "0.1.1", path = "../../build" }
new file mode 100644
--- /dev/null
+++ b/third_party/rust/ws2_32-sys/README.md
@@ -0,0 +1,13 @@
+# ws2_32 #
+Contains function definitions for the Windows API library ws2_32. See winapi for types and constants.
+
+```toml
+[dependencies]
+ws2_32-sys = "0.2.0"
+```
+
+```rust
+extern crate ws2_32;
+```
+
+[Documentation](https://retep998.github.io/doc/ws2_32/)
new file mode 100644
--- /dev/null
+++ b/third_party/rust/ws2_32-sys/build.rs
@@ -0,0 +1,6 @@
+// Copyright © 2015, Peter Atashian
+// Licensed under the MIT License <LICENSE.md>
+extern crate build;
+fn main() {
+    build::link("ws2_32", false)
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/ws2_32-sys/src/lib.rs
@@ -0,0 +1,483 @@
+// Copyright © 2015, Peter Atashian
+// Licensed under the MIT License <LICENSE.md>
+//! FFI bindings to ws2_32.
+#![cfg(windows)]
+extern crate winapi;
+use winapi::*;
+extern "system" {
+    pub fn FreeAddrInfoEx(pAddrInfoEx: PADDRINFOEXA);
+    pub fn FreeAddrInfoExW(pAddrInfoEx: PADDRINFOEXW);
+    pub fn FreeAddrInfoW(pAddrInfo: PADDRINFOW);
+    pub fn GetAddrInfoExA(
+        pName: PCSTR, pServiceName: PCSTR, dwNameSpace: DWORD, lpNspId: LPGUID,
+        hints: *const ADDRINFOEXA, ppResult: *mut PADDRINFOEXA, timeout: *mut timeval,
+        lpOverlapped: LPOVERLAPPED, lpCompletionRoutine: LPLOOKUPSERVICE_COMPLETION_ROUTINE,
+        lpNameHandle: LPHANDLE,
+    ) -> INT;
+    pub fn GetAddrInfoExCancel(lpHandle: LPHANDLE) -> INT;
+    pub fn GetAddrInfoExOverlappedResult(lpOverlapped: LPOVERLAPPED) -> INT;
+    pub fn GetAddrInfoExW(
+        pName: PCWSTR, pServiceName: PCWSTR, dwNameSpace: DWORD, lpNspId: LPGUID,
+        hints: *const ADDRINFOEXW, ppResult: *mut PADDRINFOEXW, timeout: *mut timeval,
+        lpOverlapped: LPOVERLAPPED, lpCompletionRoutine: LPLOOKUPSERVICE_COMPLETION_ROUTINE,
+        lpNameHandle: LPHANDLE,
+    ) -> INT;
+    pub fn GetAddrInfoW(
+        pNodeName: PCWSTR, pServiceName: PCWSTR, pHints: *const ADDRINFOW,
+        ppResult: *mut PADDRINFOW,
+    ) -> INT;
+    pub fn GetHostNameW(name: PWSTR, namelen: c_int) -> c_int;
+    pub fn GetNameInfoW(
+        pSockaddr: *const SOCKADDR, SockaddrLength: socklen_t, pNodeBuffer: PWCHAR,
+        NodeBufferSize: DWORD, pServiceBuffer: PWCHAR, ServiceBufferSize: DWORD, Flags: INT,
+    ) -> INT;
+    pub fn InetNtopW(Family: INT, pAddr: PVOID, pStringBuf: PWSTR, StringBufSize: size_t) -> PCWSTR;
+    pub fn InetPtonW(Family: INT, pszAddrString: PCWSTR, pAddrBuf: PVOID) -> INT;
+    pub fn SetAddrInfoExA(
+        pName: PCSTR, pServiceName: PCSTR, pAddresses: *mut SOCKET_ADDRESS, dwAddressCount: DWORD,
+        lpBlob: LPBLOB, dwFlags: DWORD, dwNameSpace: DWORD, lpNspId: LPGUID, timeout: *mut timeval,
+        lpOverlapped: LPOVERLAPPED, lpCompletionRoutine: LPLOOKUPSERVICE_COMPLETION_ROUTINE,
+        lpNameHandle: LPHANDLE,
+    ) -> INT;
+    pub fn SetAddrInfoExW(
+        pName: PCWSTR, pServiceName: PCWSTR, pAddresses: *mut SOCKET_ADDRESS, dwAddressCount: DWORD,
+        lpBlob: LPBLOB, dwFlags: DWORD, dwNameSpace: DWORD, lpNspId: LPGUID, timeout: *mut timeval,
+        lpOverlapped: LPOVERLAPPED, lpCompletionRoutine: LPLOOKUPSERVICE_COMPLETION_ROUTINE,
+        lpNameHandle: LPHANDLE,
+    ) -> INT;
+    // pub fn WEP();
+    pub fn WPUCompleteOverlappedRequest(
+        s: SOCKET, lpOverlapped: LPWSAOVERLAPPED, dwError: DWORD, cbTransferred: DWORD,
+        lpErrno: LPINT,
+    ) -> c_int;
+    // pub fn WPUGetProviderPathEx();
+    pub fn WSAAccept(
+        s: SOCKET, addr: *mut SOCKADDR, addrlen: LPINT, lpfnCondition: LPCONDITIONPROC,
+        dwCallbackData: DWORD_PTR,
+    ) -> SOCKET;
+    pub fn WSAAddressToStringA(
+        lpsaAddress: LPSOCKADDR, dwAddressLength: DWORD, lpProtocolInfo: LPWSAPROTOCOL_INFOA,
+        lpszAddressString: LPSTR, lpdwAddressStringLength: LPDWORD,
+    ) -> INT;
+    pub fn WSAAddressToStringW(
+        lpsaAddress: LPSOCKADDR, dwAddressLength: DWORD, lpProtocolInfo: LPWSAPROTOCOL_INFOW,
+        lpszAddressString: LPWSTR, lpdwAddressStringLength: LPDWORD,
+    ) -> INT;
+    pub fn WSAAdvertiseProvider(
+        puuidProviderId: *const GUID, pNSPv2Routine: *const LPCNSPV2_ROUTINE,
+    ) -> INT;
+    pub fn WSAAsyncGetHostByAddr(
+        hWnd: HWND, wMsg: u_int, addr: *const c_char, len: c_int, _type: c_int, buf: *mut c_char,
+        buflen: c_int,
+    ) -> HANDLE;
+    pub fn WSAAsyncGetHostByName(
+        hWnd: HWND, wMsg: u_int, name: *const c_char, buf: *mut c_char, buflen: c_int,
+    ) -> HANDLE;
+    pub fn WSAAsyncGetProtoByName(
+        hWnd: HWND, wMsg: u_int, name: *const c_char, buf: *mut c_char, buflen: c_int,
+    ) -> HANDLE;
+    pub fn WSAAsyncGetProtoByNumber(
+        hWnd: HWND, wMsg: u_int, number: c_int, buf: *mut c_char, buflen: c_int,
+    ) -> HANDLE;
+    pub fn WSAAsyncGetServByName(
+        hWnd: HWND, wMsg: u_int, name: *const c_char, proto: *const c_char, buf: *mut c_char,
+        buflen: c_int,
+    ) -> HANDLE;
+    pub fn WSAAsyncGetServByPort(
+        hWnd: HWND, wMsg: u_int, port: c_int, proto: *const c_char, buf: *mut c_char, buflen: c_int,
+    ) -> HANDLE;
+    pub fn WSAAsyncSelect(s: SOCKET, hWnd: HWND, wMsg: u_int, lEvent: c_long) -> c_int;
+    pub fn WSACancelAsyncRequest(hAsyncTaskHandle: HANDLE) -> c_int;
+    pub fn WSACancelBlockingCall() -> c_int;
+    pub fn WSACleanup() -> c_int;
+    pub fn WSACloseEvent(hEvent: WSAEVENT) -> BOOL;
+    pub fn WSAConnect(
+        s: SOCKET, name: *const SOCKADDR, namelen: c_int, lpCallerData: LPWSABUF,
+        lpCalleeData: LPWSABUF, lpSQOS: LPQOS, lpGQOS: LPQOS,
+    ) -> c_int;
+    pub fn WSAConnectByList(
+        s: SOCKET, SocketAddress: PSOCKET_ADDRESS_LIST, LocalAddressLength: LPDWORD,
+        LocalAddress: LPSOCKADDR, RemoteAddressLength: LPDWORD, RemoteAddress: LPSOCKADDR,
+        timeout: *const timeval, Reserved: LPWSAOVERLAPPED,
+    ) -> BOOL;
+    pub fn WSAConnectByNameA(
+        s: SOCKET, nodename: LPCSTR, servicename: LPCSTR, LocalAddressLength: LPDWORD,
+        LocalAddress: LPSOCKADDR, RemoteAddressLength: LPDWORD, RemoteAddress: LPSOCKADDR,
+        timeout: *const timeval, Reserved: LPWSAOVERLAPPED,
+    ) -> BOOL;
+    pub fn WSAConnectByNameW(
+        s: SOCKET, nodename: LPWSTR, servicename: LPWSTR, LocalAddressLength: LPDWORD,
+        LocalAddress: LPSOCKADDR, RemoteAddressLength: LPDWORD, RemoteAddress: LPSOCKADDR,
+        timeout: *const timeval, Reserved: LPWSAOVERLAPPED,
+    ) -> BOOL;
+    pub fn WSACreateEvent() -> WSAEVENT;
+    pub fn WSADuplicateSocketA(
+        s: SOCKET, dwProcessId: DWORD, lpProtocolInfo: LPWSAPROTOCOL_INFOA,
+    ) -> c_int;
+    pub fn WSADuplicateSocketW(
+        s: SOCKET, dwProcessId: DWORD, lpProtocolInfo: LPWSAPROTOCOL_INFOW,
+    ) -> c_int;
+    pub fn WSAEnumNameSpaceProvidersA(
+        lpdwBufferLength: LPDWORD, lpnspBuffer: LPWSANAMESPACE_INFOA,
+    ) -> INT;
+    pub fn WSAEnumNameSpaceProvidersExA(
+        lpdwBufferLength: LPDWORD, lpnspBuffer: LPWSANAMESPACE_INFOEXA,
+    ) -> INT;
+    pub fn WSAEnumNameSpaceProvidersExW(
+        lpdwBufferLength: LPDWORD, lpnspBuffer: LPWSANAMESPACE_INFOEXW,
+    ) -> INT;
+    pub fn WSAEnumNameSpaceProvidersW(
+        lpdwBufferLength: LPDWORD, lpnspBuffer: LPWSANAMESPACE_INFOW,
+    ) -> INT;
+    pub fn WSAEnumNetworkEvents(
+        s: SOCKET, hEventObject: WSAEVENT, lpNetworkEvents: LPWSANETWORKEVENTS,
+    ) -> c_int;
+    pub fn WSAEnumProtocolsA(
+        lpiProtocols: LPINT, lpProtocolBuffer: LPWSAPROTOCOL_INFOA, lpdwBufferLength: LPDWORD,
+    ) -> c_int;
+    pub fn WSAEnumProtocolsW(
+        lpiProtocols: LPINT, lpProtocolBuffer: LPWSAPROTOCOL_INFOW, lpdwBufferLength: LPDWORD,
+    ) -> c_int;
+    pub fn WSAEventSelect(s: SOCKET, hEventObject: WSAEVENT, lNetworkEvents: c_long) -> c_int;
+    pub fn WSAGetLastError() -> c_int;
+    pub fn WSAGetOverlappedResult(
+        s: SOCKET, lpOverlapped: LPWSAOVERLAPPED, lpcbTransfer: LPDWORD, fWait: BOOL,
+        lpdwFlags: LPDWORD,
+    ) -> BOOL;
+    pub fn WSAGetQOSByName(s: SOCKET, lpQOSName: LPWSABUF, lpQOS: LPQOS) -> BOOL;
+    pub fn WSAGetServiceClassInfoA(
+        lpProviderId: LPGUID, lpServiceClassId: LPGUID, lpdwBufSize: LPDWORD,
+        lpServiceClassInfo: LPWSASERVICECLASSINFOA,
+    ) -> INT;
+    pub fn WSAGetServiceClassInfoW(
+        lpProviderId: LPGUID, lpServiceClassId: LPGUID, lpdwBufSize: LPDWORD,
+        lpServiceClassInfo: LPWSASERVICECLASSINFOW,
+    ) -> INT;
+    pub fn WSAGetServiceClassNameByClassIdA(
+        lpServiceClassId: LPGUID, lpszServiceClassName: LPSTR, lpdwBufferLength: LPDWORD,
+    ) -> INT;
+    pub fn WSAGetServiceClassNameByClassIdW(
+        lpServiceClassId: LPGUID, lpszServiceClassName: LPWSTR, lpdwBufferLength: LPDWORD,
+    ) -> INT;
+    pub fn WSAHtonl(s: SOCKET, hostlong: u_long, lpnetlong: *mut u_long) -> c_int;
+    pub fn WSAHtons(s: SOCKET, hostshort: u_short, lpnetshort: *mut u_short) -> c_int;
+    pub fn WSAInstallServiceClassA(lpServiceClassInfo: LPWSASERVICECLASSINFOA) -> INT;
+    pub fn WSAInstallServiceClassW(lpServiceClassInfo: LPWSASERVICECLASSINFOW) -> INT;
+    pub fn WSAIoctl(
+        s: SOCKET, dwIoControlCode: DWORD, lpvInBuffer: LPVOID, cbInBuffer: DWORD,
+        lpvOutBuffer: LPVOID, cbOutBuffer: DWORD, lpcbBytesReturned: LPDWORD,
+        lpOverlapped: LPWSAOVERLAPPED, lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
+    ) -> c_int;
+    pub fn WSAIsBlocking() -> BOOL;
+    pub fn WSAJoinLeaf(
+        s: SOCKET, name: *const SOCKADDR, namelen: c_int, lpCallerData: LPWSABUF,
+        lpCalleeData: LPWSABUF, lpSQOS: LPQOS, lpGQOS: LPQOS, dwFlags: DWORD,
+    ) -> SOCKET;
+    pub fn WSALookupServiceBeginA(
+        lpqsRestrictions: LPWSAQUERYSETA, dwControlFlags: DWORD, lphLookup: LPHANDLE,
+    ) -> INT;
+    pub fn WSALookupServiceBeginW(
+        lpqsRestrictions: LPWSAQUERYSETW, dwControlFlags: DWORD, lphLookup: LPHANDLE,
+    ) -> INT;
+    pub fn WSALookupServiceEnd(hLookup: HANDLE) -> INT;
+    pub fn WSALookupServiceNextA(
+        hLookup: HANDLE, dwControlFlags: DWORD, lpdwBufferLength: LPDWORD,
+        lpqsResults: LPWSAQUERYSETA,
+    ) -> INT;
+    pub fn WSALookupServiceNextW(
+        hLookup: HANDLE, dwControlFlags: DWORD, lpdwBufferLength: LPDWORD,
+        lpqsResults: LPWSAQUERYSETW,
+    ) -> INT;
+    pub fn WSANSPIoctl(
+        hLookup: HANDLE, dwControlFlags: DWORD, lpvInBuffer: LPVOID, cbInBuffer: DWORD,
+        lpvOutBuffer: LPVOID, cbOutBuffer: DWORD, lpcbBytesReturned: LPDWORD,
+        lpCompletion: LPWSACOMPLETION,
+    ) -> INT;
+    pub fn WSANtohl(s: SOCKET, netlong: u_long, lphostlong: *mut c_long) -> c_int;
+    pub fn WSANtohs(s: SOCKET, netshort: u_short, lphostshort: *mut c_short) -> c_int;
+    pub fn WSAPoll(fdArray: LPWSAPOLLFD, fds: ULONG, timeout: INT) -> c_int;
+    pub fn WSAProviderCompleteAsyncCall(hAsyncCall: HANDLE, iRetCode: INT) -> INT;
+    pub fn WSAProviderConfigChange(
+        lpNotificationHandle: LPHANDLE, lpOverlapped: LPWSAOVERLAPPED,
+        lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
+    ) -> INT;
+    pub fn WSARecv(
+        s: SOCKET, lpBuffers: LPWSABUF, dwBufferCount: DWORD, lpNumberOfBytesRecvd: LPDWORD,
+        lpFlags: LPDWORD, lpOverlapped: LPWSAOVERLAPPED,
+        lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
+    ) -> c_int;
+    pub fn WSARecvDisconnect(s: SOCKET, lpInboundDisconnectData: LPWSABUF) -> c_int;
+    pub fn WSARecvFrom(
+        s: SOCKET, lpBuffers: LPWSABUF, dwBufferCount: DWORD, lpNumberOfBytesRecvd: LPDWORD,
+        lpFlags: LPDWORD, lpFrom: *mut SOCKADDR, lpFromlen: LPINT, lpOverlapped: LPWSAOVERLAPPED,
+        lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
+    ) -> c_int;
+    pub fn WSARemoveServiceClass(lpServiceClassId: LPGUID) -> INT;
+    pub fn WSAResetEvent(hEvent: WSAEVENT) -> BOOL;
+    pub fn WSASend(
+        s: SOCKET, lpBuffers: LPWSABUF, dwBufferCount: DWORD, lpNumberOfBytesSent: LPDWORD,
+        dwFlags: DWORD, lpOverlapped: LPWSAOVERLAPPED,
+        lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
+    ) -> c_int;
+    pub fn WSASendDisconnect(s: SOCKET, lpOutboundDisconnectData: LPWSABUF) -> c_int;
+    pub fn WSASendMsg(
+        Handle: SOCKET, lpMsg: LPWSAMSG, dwFlags: DWORD, lpNumberOfBytesSent: LPDWORD,
+        lpOverlapped: LPWSAOVERLAPPED, lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
+    ) -> c_int;
+    pub fn WSASendTo(
+        s: SOCKET, lpBuffers: LPWSABUF, dwBufferCount: DWORD, lpNumberOfBytesSent: LPDWORD,
+        dwFlags: DWORD, lpTo: *const SOCKADDR, iToLen: c_int, lpOverlapped: LPWSAOVERLAPPED,
+        lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE,
+    ) -> c_int;
+    pub fn WSASetBlockingHook(lpBlockFunc: FARPROC) -> FARPROC;
+    pub fn WSASetEvent(hEvent: WSAEVENT) -> BOOL;
+    pub fn WSASetLastError(iError: c_int);
+    pub fn WSASetServiceA(
+        lpqsRegInfo: LPWSAQUERYSETA, essoperation: WSAESETSERVICEOP, dwControlFlags: DWORD,
+    ) -> INT;
+    pub fn WSASetServiceW(
+        lpqsRegInfo: LPWSAQUERYSETW, essoperation: WSAESETSERVICEOP, dwControlFlags: DWORD,
+    ) -> INT;
+    pub fn WSASocketA(
+        af: c_int, _type: c_int, protocol: c_int, lpProtocolInfo: LPWSAPROTOCOL_INFOA, g: GROUP,
+        dwFlags: DWORD,
+    ) -> SOCKET;
+    pub fn WSASocketW(
+        af: c_int, _type: c_int, protocol: c_int, lpProtocolInfo: LPWSAPROTOCOL_INFOW, g: GROUP,
+        dwFlags: DWORD,
+    ) -> SOCKET;
+    pub fn WSAStartup(wVersionRequested: WORD, lpWSAData: LPWSADATA) -> c_int;
+    pub fn WSAStringToAddressA(
+        AddressString: LPSTR, AddressFamily: INT, lpProtocolInfo: LPWSAPROTOCOL_INFOA,
+        lpAddress: LPSOCKADDR, lpAddressLength: LPINT,
+    ) -> INT;
+    pub fn WSAStringToAddressW(
+        AddressString: LPWSTR, AddressFamily: INT, lpProtocolInfo: LPWSAPROTOCOL_INFOW,
+        lpAddress: LPSOCKADDR, lpAddressLength: LPINT,
+    ) -> INT;
+    pub fn WSAUnadvertiseProvider(puuidProviderId: *const GUID) -> INT;
+    pub fn WSAUnhookBlockingHook() -> c_int;
+    pub fn WSAWaitForMultipleEvents(
+        cEvents: DWORD, lphEvents: *const WSAEVENT, fWaitAll: BOOL, dwTimeout: DWORD,
+        fAlertable: BOOL,
+    ) -> DWORD;
+    pub fn WSCDeinstallProvider(lpProviderId: LPGUID, lpErrno: LPINT) -> c_int;
+    // pub fn WSCDeinstallProviderEx();
+    pub fn WSCEnableNSProvider(lpProviderId: LPGUID, fEnable: BOOL) -> INT;
+    pub fn WSCEnumProtocols(
+        lpiProtocols: LPINT, lpProtocolBuffer: LPWSAPROTOCOL_INFOW, lpdwBufferLength: LPDWORD,
+        lpErrno: LPINT,
+    ) -> c_int;
+    // pub fn WSCEnumProtocolsEx();
+    pub fn WSCGetApplicationCategory(
+        Path: LPCWSTR, PathLength: DWORD, Extra: LPCWSTR, ExtraLength: DWORD,
+        pPermittedLspCategories: *mut DWORD, lpErrno: LPINT,
+    ) -> c_int;
+    // pub fn WSCGetApplicationCategoryEx();
+    pub fn WSCGetProviderInfo(
+        lpProviderId: LPGUID, InfoType: WSC_PROVIDER_INFO_TYPE, Info: PBYTE, InfoSize: *mut size_t,
+        Flags: DWORD, lpErrno: LPINT,
+    ) -> c_int;
+    pub fn WSCGetProviderPath(
+        lpProviderId: LPGUID, lpszProviderDllPath: *mut WCHAR, lpProviderDllPathLen: LPINT,
+        lpErrno: LPINT,
+    ) -> c_int;
+    pub fn WSCInstallNameSpace(
+        lpszIdentifier: LPWSTR, lpszPathName: LPWSTR, dwNameSpace: DWORD, dwVersion: DWORD,
+        lpProviderId: LPGUID,
+    ) -> INT;
+    pub fn WSCInstallNameSpaceEx(
+        lpszIdentifier: LPWSTR, lpszPathName: LPWSTR, dwNameSpace: DWORD, dwVersion: DWORD,
+        lpProviderId: LPGUID, lpProviderSpecific: LPBLOB,
+    ) -> INT;
+    // pub fn WSCInstallNameSpaceEx2();
+    pub fn WSCInstallProvider(
+        lpProviderId: LPGUID, lpszProviderDllPath: *const WCHAR,
+        lpProtocolInfoList: LPWSAPROTOCOL_INFOW, dwNumberOfEntries: DWORD, lpErrno: LPINT,
+    ) -> c_int;
+    // pub fn WSCInstallProviderEx();
+    pub fn WSCSetApplicationCategory(
+        Path: LPCWSTR, PathLength: DWORD, Extra: LPCWSTR, ExtraLength: DWORD,
+        PermittedLspCategories: DWORD, pPrevPermLspCat: *mut DWORD, lpErrno: LPINT,
+    ) -> c_int;
+    // pub fn WSCSetApplicationCategoryEx();
+    pub fn WSCSetProviderInfo(
+        lpProviderId: LPGUID, InfoType: WSC_PROVIDER_INFO_TYPE, Info: PBYTE, InfoSize: size_t,
+        Flags: DWORD, lpErrno: LPINT,
+    ) -> c_int;
+    pub fn WSCUnInstallNameSpace(lpProviderId: LPGUID) -> INT;
+    // pub fn WSCUnInstallNameSpaceEx2();
+    pub fn WSCUpdateProvider(
+        lpProviderId: LPGUID, lpszProviderDllPath: *const WCHAR,
+        lpProtocolInfoList: LPWSAPROTOCOL_INFOW, dwNumberOfEntries: DWORD, lpErrno: LPINT,
+    ) -> c_int;
+    // pub fn WSCUpdateProviderEx();
+    pub fn WSCWriteNameSpaceOrder(lpProviderId: LPGUID, dwNumberOfEntries: DWORD) -> c_int;
+    pub fn WSCWriteProviderOrder(lpwdCatalogEntryId: LPDWORD, dwNumberOfEntries: DWORD) -> c_int;
+    // pub fn WSCWriteProviderOrderEx();
+    // pub fn WahCloseApcHelper();
+    // pub fn WahCloseHandleHelper();
+    // pub fn WahCloseNotificationHandleHelper();
+    // pub fn WahCloseSocketHandle();
+    // pub fn WahCloseThread();
+    // pub fn WahCompleteRequest();
+    // pub fn WahCreateHandleContextTable();
+    // pub fn WahCreateNotificationHandle();
+    // pub fn WahCreateSocketHandle();
+    // pub fn WahDestroyHandleContextTable();
+    // pub fn WahDisableNonIFSHandleSupport();
+    // pub fn WahEnableNonIFSHandleSupport();
+    // pub fn WahEnumerateHandleContexts();
+    // pub fn WahInsertHandleContext();
+    // pub fn WahNotifyAllProcesses();
+    // pub fn WahOpenApcHelper();
+    // pub fn WahOpenCurrentThread();
+    // pub fn WahOpenHandleHelper();
+    // pub fn WahOpenNotificationHandleHelper();
+    // pub fn WahQueueUserApc();
+    // pub fn WahReferenceContextByHandle();
+    // pub fn WahRemoveHandleContext();
+    // pub fn WahWaitForNotification();
+    // pub fn WahWriteLSPEvent();
+    pub fn __WSAFDIsSet(fd: SOCKET, _: *mut fd_set) -> c_int;
+    pub fn accept(s: SOCKET, addr: *mut SOCKADDR, addrlen: *mut c_int) -> SOCKET;
+    pub fn bind(s: SOCKET, name: *const SOCKADDR, namelen: c_int) -> c_int;
+    pub fn closesocket(s: SOCKET) -> c_int;
+    pub fn connect(s: SOCKET, name: *const SOCKADDR, namelen: c_int) -> c_int;
+    pub fn freeaddrinfo(pAddrInfo: PADDRINFOA);
+    pub fn getaddrinfo(
+        pNodeName: PCSTR, pServiceName: PCSTR, pHints: *const ADDRINFOA, ppResult: *mut PADDRINFOA,
+    ) -> INT;
+    pub fn gethostbyaddr(addr: *const c_char, len: c_int, _type: c_int) -> *mut hostent;
+    pub fn gethostbyname(name: *const c_char) -> *mut hostent;
+    pub fn gethostname(name: *mut c_char, namelen: c_int) -> c_int;
+    pub fn getnameinfo(
+        pSockaddr: *const SOCKADDR, SockaddrLength: socklen_t, pNodeBuffer: PCHAR,
+        NodeBufferSize: DWORD, pServiceBuffer: PCHAR, ServiceBufferSize: DWORD, Flags: INT,
+    ) -> INT;
+    pub fn getpeername(s: SOCKET, name: *mut SOCKADDR, namelen: *mut c_int) -> c_int;
+    pub fn getprotobyname(name: *const c_char) -> *mut protoent;
+    pub fn getprotobynumber(number: c_int) -> *mut protoent;
+    pub fn getservbyname(name: *const c_char, proto: *const c_char) -> *mut servent;
+    pub fn getservbyport(port: c_int, proto: *const c_char) -> *mut servent;
+    pub fn getsockname(s: SOCKET, name: *mut SOCKADDR, namelen: *mut c_int) -> c_int;
+    pub fn getsockopt(
+        s: SOCKET, level: c_int, optname: c_int, optval: *mut c_char, optlen: *mut c_int,
+    ) -> c_int;
+    pub fn htonl(hostlong: u_long) -> u_long;
+    pub fn htons(hostshort: u_short) -> u_short;
+    pub fn inet_addr(cp: *const c_char) -> c_ulong;
+    pub fn inet_ntoa(_in: in_addr) -> *mut c_char;
+    pub fn inet_ntop(Family: INT, pAddr: PVOID, pStringBuf: PSTR, StringBufSize: size_t) -> PCSTR;
+    pub fn inet_pton(Family: INT, pszAddrString: PCSTR, pAddrBuf: PVOID) -> INT;
+    pub fn ioctlsocket(s: SOCKET, cmd: c_long, argp: *mut u_long) -> c_int;
+    pub fn listen(s: SOCKET, backlog: c_int) -> c_int;
+    pub fn ntohl(netlong: u_long) -> u_long;
+    pub fn ntohs(netshort: u_short) -> u_short;
+    pub fn recv(s: SOCKET, buf: *mut c_char, len: c_int, flags: c_int) -> c_int;
+    pub fn recvfrom(
+        s: SOCKET, buf: *mut c_char, len: c_int, flags: c_int, from: *mut SOCKADDR,
+        fromlen: *mut c_int,
+    ) -> c_int;
+    pub fn select(
+        nfds: c_int, readfds: *mut fd_set, writefds: *mut fd_set, exceptfds: *mut fd_set,
+        timeout: *const timeval,
+    ) -> c_int;
+    pub fn send(s: SOCKET, buf: *const c_char, len: c_int, flags: c_int) -> c_int;
+    pub fn sendto(
+        s: SOCKET, buf: *const c_char, len: c_int, flags: c_int, to: *const SOCKADDR, tolen: c_int,
+    ) -> c_int;
+    pub fn setsockopt(
+        s: SOCKET, level: c_int, optname: c_int, optval: *const c_char, optlen: c_int,
+    ) -> c_int;
+    pub fn shutdown(s: SOCKET, how: c_int) -> c_int;
+    pub fn socket(af: c_int, _type: c_int, protocol: c_int) -> SOCKET;
+}
+#[cfg(any(target_arch = "x86", target_arch = "arm"))]
+extern "system" {
+    pub fn WSCInstallProviderAndChains(
+        lpProviderId: LPGUID, lpszProviderDllPath: LPWSTR, lpszLspName: LPWSTR,
+        dwServiceFlags: DWORD, lpProtocolInfoList: LPWSAPROTOCOL_INFOW, dwNumberOfEntries: DWORD,
+        lpdwCatalogEntryId: LPDWORD, lpErrno: LPINT,
+    ) -> c_int;
+}
+#[cfg(target_arch = "x86_64")]
+extern "system" {
+    pub fn WSCDeinstallProvider32(lpProviderId: LPGUID, lpErrno: LPINT) -> c_int;
+    pub fn WSCEnableNSProvider32(lpProviderId: LPGUID, fEnable: BOOL) -> INT;
+    pub fn WSCEnumNameSpaceProviders32(
+        lpdwBufferLength: LPDWORD, lpnspBuffer: LPWSANAMESPACE_INFOW,
+    ) -> INT;
+    pub fn WSCEnumNameSpaceProvidersEx32(
+        lpdwBufferLength: LPDWORD, lpnspBuffer: LPWSANAMESPACE_INFOEXW,
+    ) -> INT;
+    pub fn WSCEnumProtocols32(
+        lpiProtocols: LPINT, lpProtocolBuffer: LPWSAPROTOCOL_INFOW, lpdwBufferLength: LPDWORD,
+        lpErrno: LPINT,
+    ) -> c_int;
+    pub fn WSCGetProviderInfo32(
+        lpProviderId: LPGUID, InfoType: WSC_PROVIDER_INFO_TYPE, Info: PBYTE, InfoSize: *mut size_t,
+        Flags: DWORD, lpErrno: LPINT,
+    ) -> c_int;
+    pub fn WSCGetProviderPath32(
+        lpProviderId: LPGUID, lpszProviderDllPath: *mut WCHAR, lpProviderDllPathLen: LPINT,
+        lpErrno: LPINT,
+    ) -> c_int;
+    pub fn WSCInstallNameSpace32(
+        lpszIdentifier: LPWSTR, lpszPathName: LPWSTR, dwNameSpace: DWORD, dwVersion: DWORD,
+        lpProviderId: LPGUID,
+    ) -> INT;
+    pub fn WSCInstallNameSpaceEx32(
+        lpszIdentifier: LPWSTR, lpszPathName: LPWSTR, dwNameSpace: DWORD, dwVersion: DWORD,
+        lpProviderId: LPGUID, lpProviderSpecific: LPBLOB,
+    ) -> INT;
+    pub fn WSCInstallProvider64_32(
+        lpProviderId: LPGUID, lpszProviderDllPath: *const WCHAR,
+        lpProtocolInfoList: LPWSAPROTOCOL_INFOW, dwNumberOfEntries: DWORD, lpErrno: LPINT,
+    ) -> c_int;
+    pub fn WSCInstallProviderAndChains64_32(
+        lpProviderId: LPGUID, lpszProviderDllPath: LPWSTR, lpszProviderDllPath32: LPWSTR,
+        lpszLspName: LPWSTR, dwServiceFlags: DWORD, lpProtocolInfoList: LPWSAPROTOCOL_INFOW,
+        dwNumberOfEntries: DWORD, lpdwCatalogEntryId: LPDWORD, lpErrno: LPINT,
+    ) -> c_int;
+    pub fn WSCSetProviderInfo32(
+        lpProviderId: LPGUID, InfoType: WSC_PROVIDER_INFO_TYPE, Info: PBYTE, InfoSize: size_t,
+        Flags: DWORD, lpErrno: LPINT,
+    ) -> c_int;
+    pub fn WSCUnInstallNameSpace32(lpProviderId: LPGUID) -> INT;
+    pub fn WSCUpdateProvider32(
+        lpProviderId: LPGUID, lpszProviderDllPath: *const WCHAR,
+        lpProtocolInfoList: LPWSAPROTOCOL_INFOW, dwNumberOfEntries: DWORD, lpErrno: LPINT,
+    ) -> c_int;
+    pub fn WSCWriteNameSpaceOrder32(lpProviderId: LPGUID, dwNumberOfEntries: DWORD) -> c_int;
+    pub fn WSCWriteProviderOrder32(lpwdCatalogEntryId: LPDWORD, dwNumberOfEntries: DWORD) -> c_int;
+}
+extern {
+    // pub static AddressFamilyInformation;
+    // pub static eui48_broadcast;
+    // pub static in4addr_alligmpv3routersonlink;
+    // pub static in4addr_allnodesonlink;
+    // pub static in4addr_allroutersonlink;
+    // pub static in4addr_allteredohostsonlink;
+    // pub static in4addr_any;
+    // pub static in4addr_broadcast;
+    // pub static in4addr_linklocalprefix;
+    // pub static in4addr_loopback;
+    // pub static in4addr_multicastprefix;
+    // pub static in6addr_6to4prefix;
+    // pub static in6addr_allmldv2routersonlink;
+    // pub static in6addr_allnodesonlink;
+    // pub static in6addr_allnodesonnode;
+    // pub static in6addr_allroutersonlink;
+    // pub static in6addr_any;
+    // pub static in6addr_linklocalprefix;
+    // pub static in6addr_loopback;
+    // pub static in6addr_multicastprefix;
+    // pub static in6addr_solicitednodemulticastprefix;
+    // pub static in6addr_teredoinitiallinklocaladdress;
+    // pub static in6addr_teredoprefix;
+    // pub static in6addr_teredoprefix_old;
+    // pub static in6addr_v4mappedprefix;
+    // pub static scopeid_unspecified;
+    // pub static sockaddr_size;
+}
--- a/toolkit/library/gtest/rust/Cargo.lock
+++ b/toolkit/library/gtest/rust/Cargo.lock
@@ -68,16 +68,80 @@ version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "audioipc"
+version = "0.1.0"
+dependencies = [
+ "bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cubeb-core 0.1.0",
+ "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "audioipc-client"
+version = "0.1.0"
+dependencies = [
+ "audioipc 0.1.0",
+ "cubeb-backend 0.2.0",
+ "cubeb-core 0.1.0",
+ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "audioipc-server"
+version = "0.1.0"
+dependencies = [
+ "audioipc 0.1.0",
+ "cubeb 0.3.0",
+ "cubeb-core 0.1.0",
+ "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "backtrace"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "backtrace-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "backtrace-sys"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "gcc 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "binary-space-partition"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "bincode"
 version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -251,16 +315,38 @@ source = "registry+https://github.com/ru
 dependencies = [
  "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "cubeb"
+version = "0.3.0"
+dependencies = [
+ "cubeb-core 0.1.0",
+ "libcubeb-sys 0.1.0",
+]
+
+[[package]]
+name = "cubeb-backend"
+version = "0.2.0"
+dependencies = [
+ "cubeb-core 0.1.0",
+]
+
+[[package]]
+name = "cubeb-core"
+version = "0.1.0"
+dependencies = [
+ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "cubeb-ffi"
 version = "0.0.1"
 dependencies = [
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cubeb-pulse"
@@ -298,16 +384,25 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "darling_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "dbghelp-sys"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "dtoa"
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "dtoa-short"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -365,16 +460,24 @@ name = "env_logger"
 version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "error-chain"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "euclid"
 version = "0.15.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -389,16 +492,26 @@ source = "registry+https://github.com/ru
 name = "freetype"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "fs2"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "futures"
 version = "0.1.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "fxhash"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -410,16 +523,21 @@ dependencies = [
 name = "gamma-lut"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "gcc"
+version = "0.3.42"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "gdi32-sys"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -439,16 +557,21 @@ dependencies = [
  "style 0.0.1",
  "style_traits 0.0.1",
 ]
 
 [[package]]
 name = "gkrust-shared"
 version = "0.1.0"
 dependencies = [
+ "audioipc-client 0.1.0",
+ "audioipc-server 0.1.0",
+ "cubeb 0.3.0",
+ "cubeb-backend 0.2.0",
+ "cubeb-core 0.1.0",
  "cubeb-pulse 0.0.1",
  "encoding_c 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "encoding_glue 0.1.0",
  "geckoservo 0.0.1",
  "mp4parse_capi 0.8.0",
  "nserror 0.1.0",
  "nsstring 0.1.0",
  "rust_url_capi 0.0.1",
@@ -498,16 +621,25 @@ version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-bidi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "iovec"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "itertools"
 version = "0.5.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -530,21 +662,33 @@ version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "lazy_static"
 version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "lazycell"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "libc"
 version = "0.2.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "libcubeb-sys"
+version = "0.1.0"
+dependencies = [
+ "cubeb-core 0.1.0",
+]
+
+[[package]]
 name = "libloading"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -563,16 +707,63 @@ source = "registry+https://github.com/ru
 name = "memchr"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "memmap"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "mio"
+version = "0.6.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "mio-uds"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "miow"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "mp4parse"
 version = "0.8.0"
 dependencies = [
  "bitreader 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -585,16 +776,28 @@ name = "mp4parse_capi"
 version = "0.8.0"
 dependencies = [
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "mp4parse 0.8.0",
  "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "net2"
+version = "0.2.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "nodrop"
 version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -864,16 +1067,21 @@ version = "0.0.1"
 dependencies = [
  "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "nserror 0.1.0",
  "nsstring 0.1.0",
  "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "rustc-demangle"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "rustc-serialize"
 version = "0.3.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "same-file"
 version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -957,16 +1165,21 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "siphasher"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "slab"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "smallvec"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "smallvec"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1308,32 +1521,43 @@ version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "winapi-build"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "ws2_32-sys"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "xml-rs"
 version = "0.3.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [metadata]
 "checksum aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0638fd549427caa90c499814196d1b9e3725eb4d15d7339d6de073a680ed0ca2"
 "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
 "checksum app_units 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7ff4f3fe57393a150b39b026b6f6f4b9a6c4f49b52d0a4e2d61d08d926358438"
 "checksum arraydeque 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "96e774cadb24c2245225280c6799793f9802b918a58a79615e9490607489a717"
 "checksum arrayvec 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "699e63a93b79d717e8c3b5eb1b28b7780d0d6d9e59a72eb769291c83b0c8dc67"
 "checksum aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfdf7355d9db158df68f976ed030ab0f6578af811f5a7bb6dcf221ec24e0e0"
 "checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21"
 "checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
+"checksum backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72f9b4182546f4b04ebc4ab7f84948953a118bd6021a1b6a6c909e3e94f6be76"
+"checksum backtrace-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d192fd129132fbc97497c1f2ec2c2c5174e376b95f535199ef4fe0a293d33842"
 "checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff"
 "checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e"
 "checksum bindgen 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c338079dafc81bef7d581f494b906603d12359c4306979eae6ca081925a4984"
 "checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c"
 "checksum bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5b97c2c8e8bbb4251754f559df8af22fb264853c7d009084a576cdf12565089d"
 "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
 "checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"
 "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
@@ -1348,46 +1572,57 @@ dependencies = [
 "checksum core-foundation-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "41115a6aa5d3e1e5ef98148373f25971d1fad53818553f216495f9e67e90a624"
 "checksum core-graphics 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a9f841e9637adec70838c537cae52cb4c751cc6514ad05669b51d107c2021c79"
 "checksum core-text 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ce16d9ed00181016c11ff48e561314bec92bfbce9fe48f319366618d4e5de6"
 "checksum cssparser 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1f9442c00898020a56c9485d64c9c8f14ae30ba45be89d15846046593383467f"
 "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df"
 "checksum darling 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9861a8495606435477df581bc858ccf15a3469747edf175b94a4704fd9aaedac"
 "checksum darling_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1486a8b00b45062c997f767738178b43219133dd0c8c826cb811e60563810821"
 "checksum darling_macro 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a86ec160aa0c3dd492dd4a14ec8104ad8f1a9400a820624db857998cc1f80f9"
+"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
 "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
 "checksum dtoa-short 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe6f727b406462fd57c95fed84d1b0dbfb5f0136fcac005adba9ea0367c05cc8"
 "checksum dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "36e3b27cd0b8a68e00f07e8d8e1e4f4d8a6b8b873290a734f63bd56d792d23e1"
 "checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a"
 "checksum encoding_c 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1e563195f16d7439103c49281b8b00bd0f223c16e19f0d500448239a27712570"
 "checksum encoding_rs 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e00a1b1e95eb46988805ceee6f34cd95c46a6753e290cb3ff0486931989d4a4c"
 "checksum env_logger 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ed39959122ea027670b704fb70539f4286ddf4a49eefede23bf0b4b2a069ec03"
+"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8"
 "checksum euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7be9fcb1ce77782eb620253eb02bc1f000545f3c360841a26cda572f10fad4ff"
 "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
 "checksum freetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "398b8a11884898184d55aca9806f002b3cf68f0e860e0cbb4586f834ee39b0e7"
+"checksum fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ab76cfd2aaa59b7bf6688ad9ba15bbae64bff97f04ea02144cfd3443e5c2866"
 "checksum futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "55f0008e13fc853f79ea8fc86e931486860d4c4c156cdffb59fa5f7fa833660a"
 "checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
 "checksum gamma-lut 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "41f72af1e933f296b827361eb9e70d0267abf8ad0de9ec7fa667bbe67177b297"
+"checksum gcc 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "291055c78f59ca3d84c99026c9501c469413d386bb46be1e1cf1d285cd1db3b0"
 "checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
 "checksum gl_generator 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0940975a4ca12b088d32b5d5134826c47d2e73de4b0b459b05244c01503eccbb"
 "checksum gleam 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "bf887141f0c2a83eae026cbf3fba74f0a5cb0f01d20e5cdfcd8c4ad39295be1e"
 "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
 "checksum heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c7593b1522161003928c959c20a2ca421c68e940d63d75573316a009e48a6d4"
 "checksum ident_case 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9826188e666f2ed92071d2dadef6edc430b11b158b5b2b3f4babbcc891eaaa"
 "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
+"checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be"
 "checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc"
 "checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
 "checksum khronos_api 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d5a08e2a31d665af8f1ca437eab6d00a93c9d62a549f73f9ed8fc2e55b5a91a7"
 "checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf"
+"checksum lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce12306c4739d86ee97c23139f3a34ddf0387bbf181bc7929d287025a8c3ef6b"
 "checksum libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)" = "38f5c2b18a287cf78b4097db62e20f43cace381dc76ae5c0a3073067f78b7ddc"
 "checksum libloading 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "be99f814beb3e9503a786a592c909692bb6d4fc5a695f6ed7987223acfbd5194"
 "checksum log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ab83497bf8bf4ed2a74259c1c802351fcd67a65baa86394b6ba73c36f4838054"
 "checksum matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efd7622e3022e1a6eaa602c4cea8912254e5582c9c692e9167714182244801b1"
 "checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4"
+"checksum memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46f3c7359028b31999287dae4e5047ddfe90a23b7dca2282ce759b491080c99b"
+"checksum mio 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9e965267d4d58496fc4f740e9861118367f13570cadf66316ed2c3f2f14d87c7"
+"checksum mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1731a873077147b626d89cc6c2a0db6288d607496c5d10c0cfcf3adc697ec673"
+"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
+"checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09"
 "checksum nodrop 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "52cd74cd09beba596430cc6e3091b74007169a56246e1262f0ba451ea95117b2"
 "checksum nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b8c256fd9471521bcb84c3cdba98921497f1a331cbc15b8030fc63b82050ce"
 "checksum num-integer 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)" = "21e4df1098d1d797d27ef0c69c178c3fab64941559b290fcae198e0825c9c8b5"
 "checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99"
 "checksum num_cpus 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a225d1e2717567599c24f88e49f00856c6e825a12125181ee42c4257e3688d39"
 "checksum odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "c3df9b730298cea3a1c3faa90b7e2f9df3a9c400d0936d6015e6165734eefcba"
 "checksum ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "da12c96037889ae0be29dd2bdd260e5a62a7df24e6466d5a15bb8131c1c200a8"
 "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
@@ -1408,26 +1643,28 @@ dependencies = [
 "checksum quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9e25fa23c044c1803f43ca59c98dac608976dd04ce799411edd58ece776d4"
 "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
 "checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
 "checksum rayon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "705cf28d52a26a9ab548930a9a3d9799eb77cf84d66d7cc6e52fa222ca662424"
 "checksum rayon-core 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2c21a92a5dca958fb030787c1158446c6deb7f976399b72fa8074603f169e2a"
 "checksum redox_syscall 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd35cc9a8bdec562c757e3d43c1526b5c6d2653e23e2315065bc25556550753"
 "checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01"
 "checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457"
+"checksum rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3058a43ada2c2d0b92b3ae38007a2d0fa5e9db971be260e0171408a4ff471c95"
 "checksum rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "237546c689f20bb44980270c73c3b9edd0891c1be49cc1274406134a66d3957b"
 "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
 "checksum scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c79eb2c3ac4bc2507cda80e7f3ac5b88bd8eae4c0914d5663e6a8933994be918"
 "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 "checksum serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f530d36fb84ec48fb7146936881f026cdbf4892028835fd9398475f82c1bb4"
 "checksum serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "10552fad5500771f3902d0c5ba187c5881942b811b7ba0d8fbbfbf84d80806d3"
 "checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a"
 "checksum simd 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a94d14a2ae1f1f110937de5fb69e494372560181c7e1739a097fcc2cee37ba0"
 "checksum siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ffc669b726f2bc9a3bcff66e5e23b56ba6bf70e22a34c3d7b6d0b3450b65b84"
+"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
 "checksum smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4f8266519bc1d17d0b5b16f6c21295625d562841c708f6376f49028a43e9c11e"
 "checksum smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e40af10aafe98b4d8294ae8388d8a5cd0707c65d364872efe72d063ec44bee0"
 "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
 "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
 "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
 "checksum synom 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "27e31aa4b09b9f4cb12dff3c30ba503e17b1a624413d764d32dab76e3920e5bc"
 "checksum synstructure 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cf318c34a2f8381a4f3d4db2c91b45bca2b1cd8cbe56caced900647be164800c"
 "checksum syntex 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a8f5e3aaa79319573d19938ea38d068056b826db9883a5d47f86c1cecc688f0e"
@@ -1449,9 +1686,10 @@ dependencies = [
 "checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91"
 "checksum url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb819346883532a271eb626deb43c4a1bb4c4dd47c519bd78137c3e72a4fe27"
 "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
 "checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
 "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
 "checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff"
 "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
 "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
+"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
 "checksum xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7ec6c39eaa68382c8e31e35239402c0a9489d4141a8ceb0c716099a0b515b562"
--- a/toolkit/library/gtest/rust/Cargo.toml
+++ b/toolkit/library/gtest/rust/Cargo.toml
@@ -4,16 +4,17 @@ version = "0.1.0"
 authors = ["nobody@mozilla.org"]
 license = "MPL-2.0"
 description = "Testing code for libgkrust"
 
 [features]
 bindgen = ["gkrust-shared/bindgen"]
 servo = ["gkrust-shared/servo"]
 quantum_render = ["gkrust-shared/quantum_render"]
+cubeb-remoting = ["gkrust-shared/cubeb-remoting"]
 cubeb_pulse_rust = ["gkrust-shared/cubeb_pulse_rust"]
 gecko_debug = ["gkrust-shared/gecko_debug"]
 simd-accel = ["gkrust-shared/simd-accel"]
 no-static-ideograph-encoder-tables = ["gkrust-shared/no-static-ideograph-encoder-tables"]
 # parallel-utf8 = ["gkrust-shared/parallel-utf8"]
 
 [dependencies]
 mp4parse-gtest = { path = "../../../../dom/media/gtest" }
--- a/toolkit/library/rust/Cargo.lock
+++ b/toolkit/library/rust/Cargo.lock
@@ -66,16 +66,80 @@ version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "audioipc"
+version = "0.1.0"
+dependencies = [
+ "bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cubeb-core 0.1.0",
+ "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "audioipc-client"
+version = "0.1.0"
+dependencies = [
+ "audioipc 0.1.0",
+ "cubeb-backend 0.2.0",
+ "cubeb-core 0.1.0",
+ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "audioipc-server"
+version = "0.1.0"
+dependencies = [
+ "audioipc 0.1.0",
+ "cubeb 0.3.0",
+ "cubeb-core 0.1.0",
+ "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "backtrace"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "backtrace-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "backtrace-sys"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "gcc 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "binary-space-partition"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "bincode"
 version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -249,16 +313,38 @@ source = "registry+https://github.com/ru
 dependencies = [
  "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
  "procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "cubeb"
+version = "0.3.0"
+dependencies = [
+ "cubeb-core 0.1.0",
+ "libcubeb-sys 0.1.0",
+]
+
+[[package]]
+name = "cubeb-backend"
+version = "0.2.0"
+dependencies = [
+ "cubeb-core 0.1.0",
+]
+
+[[package]]
+name = "cubeb-core"
+version = "0.1.0"
+dependencies = [
+ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "cubeb-ffi"
 version = "0.0.1"
 dependencies = [
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cubeb-pulse"
@@ -296,16 +382,25 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "darling_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "dbghelp-sys"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "dtoa"
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "dtoa-short"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -363,16 +458,24 @@ name = "env_logger"
 version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "error-chain"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "euclid"
 version = "0.15.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -387,16 +490,26 @@ source = "registry+https://github.com/ru
 name = "freetype"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "fs2"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "futures"
 version = "0.1.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "fxhash"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -408,16 +521,21 @@ dependencies = [
 name = "gamma-lut"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "gcc"
+version = "0.3.42"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "gdi32-sys"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -437,16 +555,21 @@ dependencies = [
  "style 0.0.1",
  "style_traits 0.0.1",
 ]
 
 [[package]]
 name = "gkrust-shared"
 version = "0.1.0"
 dependencies = [
+ "audioipc-client 0.1.0",
+ "audioipc-server 0.1.0",
+ "cubeb 0.3.0",
+ "cubeb-backend 0.2.0",
+ "cubeb-core 0.1.0",
  "cubeb-pulse 0.0.1",
  "encoding_c 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "encoding_glue 0.1.0",
  "geckoservo 0.0.1",
  "mp4parse_capi 0.8.0",
  "nserror 0.1.0",
  "nsstring 0.1.0",
  "rust_url_capi 0.0.1",
@@ -496,16 +619,25 @@ version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-bidi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "iovec"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "itertools"
 version = "0.5.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -528,21 +660,33 @@ version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "lazy_static"
 version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "lazycell"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "libc"
 version = "0.2.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "libcubeb-sys"
+version = "0.1.0"
+dependencies = [
+ "cubeb-core 0.1.0",
+]
+
+[[package]]
 name = "libloading"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -561,16 +705,63 @@ source = "registry+https://github.com/ru
 name = "memchr"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "memmap"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "mio"
+version = "0.6.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "mio-uds"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "miow"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "mp4parse"
 version = "0.8.0"
 dependencies = [
  "bitreader 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -579,16 +770,28 @@ name = "mp4parse_capi"
 version = "0.8.0"
 dependencies = [
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "mp4parse 0.8.0",
  "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "net2"
+version = "0.2.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "nodrop"
 version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -851,16 +1054,21 @@ version = "0.0.1"
 dependencies = [
  "libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "nserror 0.1.0",
  "nsstring 0.1.0",
  "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "rustc-demangle"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "rustc-serialize"
 version = "0.3.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "same-file"
 version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -944,16 +1152,21 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "siphasher"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "slab"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "smallvec"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "smallvec"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1295,32 +1508,43 @@ version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "winapi-build"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "ws2_32-sys"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "xml-rs"
 version = "0.3.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [metadata]
 "checksum aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0638fd549427caa90c499814196d1b9e3725eb4d15d7339d6de073a680ed0ca2"
 "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
 "checksum app_units 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7ff4f3fe57393a150b39b026b6f6f4b9a6c4f49b52d0a4e2d61d08d926358438"
 "checksum arraydeque 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "96e774cadb24c2245225280c6799793f9802b918a58a79615e9490607489a717"
 "checksum arrayvec 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "699e63a93b79d717e8c3b5eb1b28b7780d0d6d9e59a72eb769291c83b0c8dc67"
 "checksum aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfdf7355d9db158df68f976ed030ab0f6578af811f5a7bb6dcf221ec24e0e0"
 "checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21"
 "checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
+"checksum backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72f9b4182546f4b04ebc4ab7f84948953a118bd6021a1b6a6c909e3e94f6be76"
+"checksum backtrace-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d192fd129132fbc97497c1f2ec2c2c5174e376b95f535199ef4fe0a293d33842"
 "checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff"
 "checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e"
 "checksum bindgen 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c338079dafc81bef7d581f494b906603d12359c4306979eae6ca081925a4984"
 "checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c"
 "checksum bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5b97c2c8e8bbb4251754f559df8af22fb264853c7d009084a576cdf12565089d"
 "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
 "checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"
 "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
@@ -1335,46 +1559,57 @@ dependencies = [
 "checksum core-foundation-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "41115a6aa5d3e1e5ef98148373f25971d1fad53818553f216495f9e67e90a624"
 "checksum core-graphics 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a9f841e9637adec70838c537cae52cb4c751cc6514ad05669b51d107c2021c79"
 "checksum core-text 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ce16d9ed00181016c11ff48e561314bec92bfbce9fe48f319366618d4e5de6"
 "checksum cssparser 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1f9442c00898020a56c9485d64c9c8f14ae30ba45be89d15846046593383467f"
 "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df"
 "checksum darling 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9861a8495606435477df581bc858ccf15a3469747edf175b94a4704fd9aaedac"
 "checksum darling_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1486a8b00b45062c997f767738178b43219133dd0c8c826cb811e60563810821"
 "checksum darling_macro 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a86ec160aa0c3dd492dd4a14ec8104ad8f1a9400a820624db857998cc1f80f9"
+"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
 "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
 "checksum dtoa-short 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe6f727b406462fd57c95fed84d1b0dbfb5f0136fcac005adba9ea0367c05cc8"
 "checksum dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "36e3b27cd0b8a68e00f07e8d8e1e4f4d8a6b8b873290a734f63bd56d792d23e1"
 "checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a"
 "checksum encoding_c 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1e563195f16d7439103c49281b8b00bd0f223c16e19f0d500448239a27712570"
 "checksum encoding_rs 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e00a1b1e95eb46988805ceee6f34cd95c46a6753e290cb3ff0486931989d4a4c"
 "checksum env_logger 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ed39959122ea027670b704fb70539f4286ddf4a49eefede23bf0b4b2a069ec03"
+"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8"
 "checksum euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7be9fcb1ce77782eb620253eb02bc1f000545f3c360841a26cda572f10fad4ff"
 "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
 "checksum freetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "398b8a11884898184d55aca9806f002b3cf68f0e860e0cbb4586f834ee39b0e7"
+"checksum fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ab76cfd2aaa59b7bf6688ad9ba15bbae64bff97f04ea02144cfd3443e5c2866"
 "checksum futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "55f0008e13fc853f79ea8fc86e931486860d4c4c156cdffb59fa5f7fa833660a"
 "checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
 "checksum gamma-lut 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "41f72af1e933f296b827361eb9e70d0267abf8ad0de9ec7fa667bbe67177b297"
+"checksum gcc 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "291055c78f59ca3d84c99026c9501c469413d386bb46be1e1cf1d285cd1db3b0"
 "checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
 "checksum gl_generator 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0940975a4ca12b088d32b5d5134826c47d2e73de4b0b459b05244c01503eccbb"
 "checksum gleam 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "bf887141f0c2a83eae026cbf3fba74f0a5cb0f01d20e5cdfcd8c4ad39295be1e"
 "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
 "checksum heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c7593b1522161003928c959c20a2ca421c68e940d63d75573316a009e48a6d4"
 "checksum ident_case 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9826188e666f2ed92071d2dadef6edc430b11b158b5b2b3f4babbcc891eaaa"
 "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
+"checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be"
 "checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc"
 "checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
 "checksum khronos_api 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d5a08e2a31d665af8f1ca437eab6d00a93c9d62a549f73f9ed8fc2e55b5a91a7"
 "checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf"
+"checksum lazycell 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce12306c4739d86ee97c23139f3a34ddf0387bbf181bc7929d287025a8c3ef6b"
 "checksum libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)" = "38f5c2b18a287cf78b4097db62e20f43cace381dc76ae5c0a3073067f78b7ddc"
 "checksum libloading 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "be99f814beb3e9503a786a592c909692bb6d4fc5a695f6ed7987223acfbd5194"
 "checksum log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ab83497bf8bf4ed2a74259c1c802351fcd67a65baa86394b6ba73c36f4838054"
 "checksum matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efd7622e3022e1a6eaa602c4cea8912254e5582c9c692e9167714182244801b1"
 "checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4"
+"checksum memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46f3c7359028b31999287dae4e5047ddfe90a23b7dca2282ce759b491080c99b"
+"checksum mio 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9e965267d4d58496fc4f740e9861118367f13570cadf66316ed2c3f2f14d87c7"
+"checksum mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1731a873077147b626d89cc6c2a0db6288d607496c5d10c0cfcf3adc697ec673"
+"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
+"checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09"
 "checksum nodrop 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "52cd74cd09beba596430cc6e3091b74007169a56246e1262f0ba451ea95117b2"
 "checksum nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b8c256fd9471521bcb84c3cdba98921497f1a331cbc15b8030fc63b82050ce"
 "checksum num-integer 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)" = "21e4df1098d1d797d27ef0c69c178c3fab64941559b290fcae198e0825c9c8b5"
 "checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99"
 "checksum num_cpus 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a225d1e2717567599c24f88e49f00856c6e825a12125181ee42c4257e3688d39"
 "checksum odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "c3df9b730298cea3a1c3faa90b7e2f9df3a9c400d0936d6015e6165734eefcba"
 "checksum ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "da12c96037889ae0be29dd2bdd260e5a62a7df24e6466d5a15bb8131c1c200a8"
 "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
@@ -1395,26 +1630,28 @@ dependencies = [
 "checksum quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9e25fa23c044c1803f43ca59c98dac608976dd04ce799411edd58ece776d4"
 "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
 "checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
 "checksum rayon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "705cf28d52a26a9ab548930a9a3d9799eb77cf84d66d7cc6e52fa222ca662424"
 "checksum rayon-core 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2c21a92a5dca958fb030787c1158446c6deb7f976399b72fa8074603f169e2a"
 "checksum redox_syscall 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd35cc9a8bdec562c757e3d43c1526b5c6d2653e23e2315065bc25556550753"
 "checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01"
 "checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457"
+"checksum rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3058a43ada2c2d0b92b3ae38007a2d0fa5e9db971be260e0171408a4ff471c95"
 "checksum rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "237546c689f20bb44980270c73c3b9edd0891c1be49cc1274406134a66d3957b"
 "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
 "checksum scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c79eb2c3ac4bc2507cda80e7f3ac5b88bd8eae4c0914d5663e6a8933994be918"
 "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 "checksum serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f530d36fb84ec48fb7146936881f026cdbf4892028835fd9398475f82c1bb4"
 "checksum serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "10552fad5500771f3902d0c5ba187c5881942b811b7ba0d8fbbfbf84d80806d3"
 "checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a"
 "checksum simd 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a94d14a2ae1f1f110937de5fb69e494372560181c7e1739a097fcc2cee37ba0"
 "checksum siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ffc669b726f2bc9a3bcff66e5e23b56ba6bf70e22a34c3d7b6d0b3450b65b84"
+"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
 "checksum smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4f8266519bc1d17d0b5b16f6c21295625d562841c708f6376f49028a43e9c11e"
 "checksum smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e40af10aafe98b4d8294ae8388d8a5cd0707c65d364872efe72d063ec44bee0"
 "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
 "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
 "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
 "checksum synom 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "27e31aa4b09b9f4cb12dff3c30ba503e17b1a624413d764d32dab76e3920e5bc"
 "checksum synstructure 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cf318c34a2f8381a4f3d4db2c91b45bca2b1cd8cbe56caced900647be164800c"
 "checksum syntex 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a8f5e3aaa79319573d19938ea38d068056b826db9883a5d47f86c1cecc688f0e"
@@ -1436,9 +1673,10 @@ dependencies = [
 "checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91"
 "checksum url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb819346883532a271eb626deb43c4a1bb4c4dd47c519bd78137c3e72a4fe27"
 "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
 "checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
 "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
 "checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff"
 "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
 "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
+"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
 "checksum xml-rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7ec6c39eaa68382c8e31e35239402c0a9489d4141a8ceb0c716099a0b515b562"
--- a/toolkit/library/rust/Cargo.toml
+++ b/toolkit/library/rust/Cargo.toml
@@ -4,16 +4,17 @@ version = "0.1.0"
 authors = ["nobody@mozilla.org"]
 license = "MPL-2.0"
 description = "Rust code for libxul"
 
 [features]
 bindgen = ["gkrust-shared/bindgen"]
 servo = ["gkrust-shared/servo"]
 quantum_render = ["gkrust-shared/quantum_render"]
+cubeb-remoting = ["gkrust-shared/cubeb-remoting"]
 cubeb_pulse_rust = ["gkrust-shared/cubeb_pulse_rust"]
 gecko_debug = ["gkrust-shared/gecko_debug"]
 simd-accel = ["gkrust-shared/simd-accel"]
 no-static-ideograph-encoder-tables = ["gkrust-shared/no-static-ideograph-encoder-tables"]
 # parallel-utf8 = ["gkrust-shared/parallel-utf8"]
 
 [dependencies]
 gkrust-shared = { path = "shared" }
--- a/toolkit/library/rust/gkrust-features.mozbuild
+++ b/toolkit/library/rust/gkrust-features.mozbuild
@@ -18,9 +18,12 @@ if CONFIG['MOZ_BUILD_WEBRENDER']:
     gkrust_features += ['quantum_render']
 
 if CONFIG['MOZ_PULSEAUDIO']:
     gkrust_features += ['cubeb_pulse_rust']
 
 if CONFIG['MOZ_RUST_SIMD']:
     gkrust_features += ['simd-accel']
 
+if CONFIG['MOZ_CUBEB_REMOTING']:
+    gkrust_features += ['cubeb-remoting']
+
 gkrust_features += ['no-static-ideograph-encoder-tables']
--- a/toolkit/library/rust/shared/Cargo.toml
+++ b/toolkit/library/rust/shared/Cargo.toml
@@ -8,24 +8,30 @@ description = "Shared Rust code for libx
 [dependencies]
 geckoservo = { path = "../../../../servo/ports/geckolib", optional = true }
 mp4parse_capi = { path = "../../../../media/libstagefright/binding/mp4parse_capi" }
 nsstring = { path = "../../../../xpcom/rust/nsstring" }
 nserror = { path = "../../../../xpcom/rust/nserror" }
 rust_url_capi = { path = "../../../../netwerk/base/rust-url-capi" }
 webrender_bindings = { path = "../../../../gfx/webrender_bindings", optional = true }
 cubeb-pulse = { path = "../../../../media/libcubeb/cubeb-pulse-rs", optional = true, features=["pulse-dlopen"] }
+cubeb-core = { path = "../../../../media/cubeb-rs/cubeb-core", optional = true }
+cubeb = { path = "../../../../media/cubeb-rs/cubeb-api", optional = true }
+cubeb-backend = { path = "../../../../media/cubeb-rs/cubeb-backend", optional = true }
 encoding_c = "0.7.1"
 encoding_glue = { path = "../../../../intl/encoding_glue" }
+audioipc-client = { path = "../../../../media/audioipc/client", optional = true }
+audioipc-server = { path = "../../../../media/audioipc/server", optional = true }
 
 [features]
 default = []
 bindgen = ["geckoservo/bindgen"]
 servo = ["geckoservo"]
 quantum_render = ["webrender_bindings"]
+cubeb-remoting = ["cubeb-core", "cubeb", "cubeb-backend", "audioipc-client", "audioipc-server"]
 cubeb_pulse_rust = ["cubeb-pulse"]
 gecko_debug = ["geckoservo/gecko_debug"]
 simd-accel = ["encoding_c/simd-accel", "encoding_glue/simd-accel"]
 no-static-ideograph-encoder-tables = ["encoding_c/no-static-ideograph-encoder-tables", "encoding_glue/no-static-ideograph-encoder-tables"]
 parallel-utf8 = ["encoding_c/parallel-utf8", "encoding_glue/parallel-utf8"]
 
 [lib]
 path = "lib.rs"
--- a/toolkit/library/rust/shared/lib.rs
+++ b/toolkit/library/rust/shared/lib.rs
@@ -10,16 +10,20 @@ extern crate nsstring;
 extern crate nserror;
 extern crate rust_url_capi;
 #[cfg(feature = "quantum_render")]
 extern crate webrender_bindings;
 #[cfg(feature = "cubeb_pulse_rust")]
 extern crate cubeb_pulse;
 extern crate encoding_c;
 extern crate encoding_glue;
+#[cfg(feature = "cubeb-remoting")]
+extern crate audioipc_client;
+#[cfg(feature = "cubeb-remoting")]
+extern crate audioipc_server;
 
 use std::boxed::Box;
 use std::ffi::CStr;
 use std::os::raw::c_char;
 use std::panic;
 
 
 
--- a/toolkit/moz.configure
+++ b/toolkit/moz.configure
@@ -1171,8 +1171,22 @@ option('--enable-coverage', env='MOZ_COD
 
 @depends('--enable-coverage')
 def code_coverage(value):
     if value:
         return True
 
 set_config('MOZ_CODE_COVERAGE', code_coverage)
 set_define('MOZ_CODE_COVERAGE', code_coverage)
+
+# Cubeb Audio Remoting
+# ==============================================================
+
+option('--enable-cubeb-remoting', env='MOZ_CUBEB_REMOTING',
+       help='Enable cubeb audio remoting')
+
+@depends('--enable-cubeb-remoting')
+def cubeb_remoting(value):
+    if value:
+        return True
+
+set_config('MOZ_CUBEB_REMOTING', cubeb_remoting)
+set_define('MOZ_CUBEB_REMOTING', cubeb_remoting)