diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
new file mode 100644
index 0000000..3668676
--- /dev/null
+++ b/.cargo_vcs_info.json
@@ -0,0 +1,5 @@
+{
+  "git": {
+    "sha1": "defde6fb0ce20b0c8c4e672aa9ae821f7d1f5b38"
+  }
+}
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..b41f2bc
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,76 @@
+name: ci
+on:
+  pull_request:
+  push:
+    branches:
+    - master
+  schedule:
+  - cron: '00 01 * * *'
+jobs:
+  test:
+    name: test
+    runs-on: ${{ matrix.os }}
+    strategy:
+      matrix:
+        build:
+        - pinned
+        - stable
+        - beta
+        - nightly
+        - macos
+        - win-msvc
+        - win-gnu
+        include:
+        - build: pinned
+          os: ubuntu-18.04
+          rust: 1.46.0
+        - build: stable
+          os: ubuntu-18.04
+          rust: stable
+        - build: beta
+          os: ubuntu-18.04
+          rust: beta
+        - build: nightly
+          os: ubuntu-18.04
+          rust: nightly
+        - build: macos
+          os: macos-latest
+          rust: stable
+        - build: win-msvc
+          os: windows-2019
+          rust: stable
+        - build: win-gnu
+          os: windows-2019
+          rust: stable-x86_64-gnu
+    steps:
+    - name: Checkout repository
+      uses: actions/checkout@v1
+      with:
+        fetch-depth: 1
+    - name: Install Rust
+      uses: hecrj/setup-rust-action@v1
+      with:
+        rust-version: ${{ matrix.rust }}
+    - run: cargo build --verbose
+    - run: cargo doc --verbose
+    - run: cargo test --verbose
+    - run: cargo build --verbose --manifest-path quickcheck_macros/Cargo.toml
+    - run: cargo test --verbose --manifest-path quickcheck_macros/Cargo.toml
+
+  rustfmt:
+    name: rustfmt
+    runs-on: ubuntu-18.04
+    steps:
+    - name: Checkout repository
+      uses: actions/checkout@v1
+      with:
+        fetch-depth: 1
+    - name: Install Rust
+      uses: hecrj/setup-rust-action@v1
+      with:
+        rust-version: stable
+    - name: Install rustfmt
+      run: rustup component add rustfmt
+    - name: Check formatting
+      run: |
+        cargo fmt --all -- --check
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..002549c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+doc
+.*.swp
+tags
+target
+build
+Cargo.lock
+*~
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..bb9c20a
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,3 @@
+This project is dual-licensed under the Unlicense and MIT licenses.
+
+You may use this code under the terms of either license.
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..aa4ad58
--- /dev/null
+++ b/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]
+edition = "2018"
+name = "quickcheck"
+version = "1.0.3"
+authors = ["Andrew Gallant <jamslam@gmail.com>"]
+exclude = ["/.travis.yml", "/Makefile", "/ctags.rust", "/session.vim"]
+description = "Automatic property based testing with shrinking."
+homepage = "https://github.com/BurntSushi/quickcheck"
+documentation = "https://docs.rs/quickcheck"
+readme = "README.md"
+keywords = ["testing", "quickcheck", "property", "shrinking", "fuzz"]
+categories = ["development-tools::testing"]
+license = "Unlicense/MIT"
+repository = "https://github.com/BurntSushi/quickcheck"
+
+[lib]
+name = "quickcheck"
+[dependencies.env_logger]
+version = "0.8.2"
+optional = true
+default-features = false
+
+[dependencies.log]
+version = "0.4"
+optional = true
+
+[dependencies.rand]
+version = "0.8"
+features = ["getrandom", "small_rng"]
+default-features = false
+
+[features]
+default = ["regex", "use_logging"]
+regex = ["env_logger/regex"]
+use_logging = ["log", "env_logger"]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
new file mode 100644
index 0000000..17cc17a
--- /dev/null
+++ b/Cargo.toml.orig
@@ -0,0 +1,30 @@
+[package]
+name = "quickcheck"
+version = "1.0.3"  #:version
+authors = ["Andrew Gallant <jamslam@gmail.com>"]
+description = "Automatic property based testing with shrinking."
+documentation = "https://docs.rs/quickcheck"
+homepage = "https://github.com/BurntSushi/quickcheck"
+repository = "https://github.com/BurntSushi/quickcheck"
+readme = "README.md"
+keywords = ["testing", "quickcheck", "property", "shrinking", "fuzz"]
+categories = ["development-tools::testing"]
+license = "Unlicense/MIT"
+exclude = ["/.travis.yml", "/Makefile", "/ctags.rust", "/session.vim"]
+edition = "2018"
+
+[workspace]
+members = ["quickcheck_macros"]
+
+[features]
+default = ["regex", "use_logging"]
+use_logging = ["log", "env_logger"]
+regex = ["env_logger/regex"]
+
+[lib]
+name = "quickcheck"
+
+[dependencies]
+env_logger = { version = "0.8.2", default-features = false, optional = true }
+log = { version = "0.4", optional = true }
+rand = { version = "0.8", default-features = false, features = ["getrandom", "small_rng"] }
diff --git a/LICENSE b/LICENSE
new file mode 120000
index 0000000..7f9a88e
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1 @@
+LICENSE-MIT
\ No newline at end of file
diff --git a/LICENSE-MIT b/LICENSE-MIT
new file mode 100644
index 0000000..3b0a5dc
--- /dev/null
+++ b/LICENSE-MIT
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Andrew Gallant
+
+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.
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..b67fcbf
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,19 @@
+name: "quickcheck"
+description: "Automatic property based testing with shrinking."
+third_party {
+  url {
+    type: HOMEPAGE
+    value: "https://crates.io/crates/quickcheck"
+  }
+  url {
+    type: ARCHIVE
+    value: "https://static.crates.io/crates/quickcheck/quickcheck-1.0.3.crate"
+  }
+  version: "1.0.3"
+  license_type: NOTICE
+  last_upgrade_date {
+    year: 2021
+    month: 10
+    day: 19
+  }
+}
diff --git a/MODULE_LICENSE_MIT b/MODULE_LICENSE_MIT
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_MIT
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..45dc4dd
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1 @@
+include platform/prebuilts/rust:master:/OWNERS
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..2546a63
--- /dev/null
+++ b/README.md
@@ -0,0 +1,583 @@
+quickcheck
+==========
+QuickCheck is a way to do property based testing using randomly generated
+input. This crate comes with the ability to randomly generate and shrink
+integers, floats, tuples, booleans, lists, strings, options and results.
+All QuickCheck needs is a property function—it will then randomly generate
+inputs to that function and call the property for each set of inputs. If the
+property fails (whether by a runtime error like index out-of-bounds or by not
+satisfying your property), the inputs are "shrunk" to find a smaller
+counter-example.
+
+The shrinking strategies for lists and numbers use a binary search to cover
+the input space quickly. (It should be the same strategy used in
+[Koen Claessen's QuickCheck for
+Haskell](https://hackage.haskell.org/package/QuickCheck).)
+
+[![Build status](https://github.com/BurntSushi/quickcheck/workflows/ci/badge.svg)](https://github.com/BurntSushi/quickcheck/actions)
+[![](https://meritbadge.herokuapp.com/quickcheck)](https://crates.io/crates/quickcheck)
+
+Dual-licensed under MIT or the [UNLICENSE](https://unlicense.org).
+
+
+### Documentation
+
+The API is fully documented:
+[https://docs.rs/quickcheck](https://docs.rs/quickcheck).
+
+
+### Simple example
+
+Here's an example that tests a function that reverses a vector:
+
+```rust
+#[cfg(test)]
+#[macro_use]
+extern crate quickcheck;
+
+fn reverse<T: Clone>(xs: &[T]) -> Vec<T> {
+    let mut rev = vec!();
+    for x in xs.iter() {
+        rev.insert(0, x.clone())
+    }
+    rev
+}
+
+#[cfg(test)]
+mod tests {
+  quickcheck! {
+      fn prop(xs: Vec<u32>) -> bool {
+          xs == reverse(&reverse(&xs))
+      }
+  }
+}
+```
+
+This example uses the `quickcheck!` macro, which is backwards compatible with
+old versions of Rust.
+
+### The `#[quickcheck]` attribute
+
+To make it easier to write QuickCheck tests, the `#[quickcheck]` attribute
+will convert a property function into a `#[test]` function.
+
+To use the `#[quickcheck]` attribute, you must import the `quickcheck` macro
+from the `quickcheck_macros` crate:
+
+```rust
+#[cfg(test)]
+extern crate quickcheck;
+#[cfg(test)]
+#[macro_use(quickcheck)]
+extern crate quickcheck_macros;
+
+#[cfg(test)]
+mod tests {
+    fn reverse<T: Clone>(xs: &[T]) -> Vec<T> {
+        let mut rev = vec!();
+        for x in xs {
+            rev.insert(0, x.clone())
+        }
+        rev
+    }
+
+    #[quickcheck]
+    fn double_reversal_is_identity(xs: Vec<isize>) -> bool {
+        xs == reverse(&reverse(&xs))
+    }
+}
+```
+
+
+### Installation
+
+`quickcheck` is on `crates.io`, so you can include it in your project like so:
+
+```toml
+[dependencies]
+quickcheck = "1"
+```
+
+If you're only using `quickcheck` in your test code, then you can add it as a
+development dependency instead:
+
+```toml
+[dev-dependencies]
+quickcheck = "1"
+```
+
+If you want to use the `#[quickcheck]` attribute, then add `quickcheck_macros`
+
+```toml
+[dev-dependencies]
+quickcheck = "1"
+quickcheck_macros = "1"
+```
+
+N.B. When using `quickcheck` (either directly or via the attributes),
+`RUST_LOG=quickcheck` enables `info!` so that it shows useful output
+(like the number of tests passed). This is **not** needed to show
+witnesses for failures.
+
+Crate features:
+
+- `"use_logging"`: (Enabled by default.) Enables the log messages governed
+  `RUST_LOG`.
+- `"regex"`: (Enabled by default.) Enables the use of regexes with
+  `env_logger`.
+
+
+### Minimum Rust version policy
+
+This crate's minimum supported `rustc` version is `1.46.0`.
+
+The current policy is that the minimum Rust version required to use this crate
+can be increased in minor version updates. For example, if `crate 1.0` requires
+Rust 1.20.0, then `crate 1.0.z` for all values of `z` will also require Rust
+1.20.0 or newer. However, `crate 1.y` for `y > 0` may require a newer minimum
+version of Rust.
+
+In general, this crate will be conservative with respect to the minimum
+supported version of Rust.
+
+With all of that said, currently, `rand` is a public dependency of
+`quickcheck`. Therefore, the MSRV policy above only applies when it is more
+aggressive than `rand`'s MSRV policy. Otherwise, `quickcheck` will defer to
+`rand`'s MSRV policy.
+
+
+### Compatibility
+
+In general, this crate considers the `Arbitrary` implementations provided as
+implementation details. Strategies may or may not change over time, which may
+cause new test failures, presumably due to the discovery of new bugs due to a
+new kind of witness being generated. These sorts of changes may happen in
+semver compatible releases.
+
+
+### Alternative Rust crates for property testing
+
+The [`proptest`](https://docs.rs/proptest) crate is inspired by the
+[Hypothesis](https://hypothesis.works) framework for Python.
+You can read a comparison between `proptest` and `quickcheck`
+[here](https://github.com/AltSysrq/proptest/blob/master/proptest/README.md#differences-between-quickcheck-and-proptest)
+and
+[here](https://github.com/AltSysrq/proptest/issues/15#issuecomment-348382287).
+In particular, `proptest` improves on the concept of shrinking. So if you've
+ever had problems/frustration with shrinking in `quickcheck`, then `proptest`
+might be worth a try!
+
+
+### Alternatives for fuzzing
+
+Please see the
+[Rust Fuzz Book](https://rust-fuzz.github.io/book/introduction.html)
+and the
+[`arbitrary`](https://crates.io/crates/arbitrary) crate.
+
+
+### Discarding test results (or, properties are polymorphic!)
+
+Sometimes you want to test a property that only holds for a *subset* of the
+possible inputs, so that when your property is given an input that is outside
+of that subset, you'd discard it. In particular, the property should *neither*
+pass nor fail on inputs outside of the subset you want to test. But properties
+return boolean values—which either indicate pass or fail.
+
+To fix this, we need to take a step back and look at the type of the
+`quickcheck` function:
+
+```rust
+pub fn quickcheck<A: Testable>(f: A) {
+    // elided
+}
+```
+
+So `quickcheck` can test any value with a type that satisfies the `Testable`
+trait. Great, so what is this `Testable` business?
+
+```rust
+pub trait Testable {
+    fn result(&self, &mut Gen) -> TestResult;
+}
+```
+
+This trait states that a type is testable if it can produce a `TestResult`
+given a source of randomness. (A `TestResult` stores information about the
+results of a test, like whether it passed, failed or has been discarded.)
+
+Sure enough, `bool` satisfies the `Testable` trait:
+
+```rust
+impl Testable for bool {
+    fn result(&self, _: &mut Gen) -> TestResult {
+        TestResult::from_bool(*self)
+    }
+}
+```
+
+But in the example, we gave a *function* to `quickcheck`. Yes, functions can
+satisfy `Testable` too!
+
+```rust
+impl<A: Arbitrary + Debug, B: Testable> Testable for fn(A) -> B {
+    fn result(&self, g: &mut Gen) -> TestResult {
+        // elided
+    }
+}
+```
+
+Which says that a function satisfies `Testable` if and only if it has a single
+parameter type (whose values can be randomly generated and shrunk) and returns
+any type (that also satisfies `Testable`). So a function with type `fn(usize)
+-> bool` satisfies `Testable` since `usize` satisfies `Arbitrary` and `bool`
+satisfies `Testable`.
+
+So to discard a test, we need to return something other than `bool`. What if we
+just returned a `TestResult` directly? That should work, but we'll need to
+make sure `TestResult` satisfies `Testable`:
+
+```rust
+impl Testable for TestResult {
+    fn result(&self, _: &mut Gen) -> TestResult { self.clone() }
+}
+```
+
+Now we can test functions that return a `TestResult` directly.
+
+As an example, let's test our reverse function to make sure that the reverse of
+a vector of length 1 is equal to the vector itself.
+
+```rust
+fn prop(xs: Vec<isize>) -> TestResult {
+    if xs.len() != 1 {
+        return TestResult::discard()
+    }
+    TestResult::from_bool(xs == reverse(&xs))
+}
+quickcheck(prop as fn(Vec<isize>) -> TestResult);
+```
+
+(A full working program for this example is in
+[`examples/reverse_single.rs`](https://github.com/BurntSushi/quickcheck/blob/master/examples/reverse_single.rs).)
+
+So now our property returns a `TestResult`, which allows us to encode a bit
+more information. There are a few more
+[convenience functions defined for the `TestResult`
+type](https://docs.rs/quickcheck/*/quickcheck/struct.TestResult.html).
+For example, we can't just return a `bool`, so we convert a `bool` value to a
+`TestResult`.
+
+(The ability to discard tests allows you to get similar functionality as
+Haskell's `==>` combinator.)
+
+N.B. Since discarding a test means it neither passes nor fails, `quickcheck`
+will try to replace the discarded test with a fresh one. However, if your
+condition is seldom met, it's possible that `quickcheck` will have to settle
+for running fewer tests than usual. By default, if `quickcheck` can't find
+`100` valid tests after trying `10,000` times, then it will give up.
+These parameters may be changed using
+[`QuickCheck::tests`](https://docs.rs/quickcheck/*/quickcheck/struct.QuickCheck.html#method.tests)
+and [`QuickCheck::max_tests`](https://docs.rs/quickcheck/*/quickcheck/struct.QuickCheck.html#method.max_tests),
+or by setting the `QUICKCHECK_TESTS` and `QUICKCHECK_MAX_TESTS`
+environment variables.
+There is also `QUICKCHECK_MIN_TESTS_PASSED` which sets the minimum number of
+valid tests that need pass (defaults to `0`) in order for it to be considered a
+success.
+
+
+### Shrinking
+
+Shrinking is a crucial part of QuickCheck that simplifies counter-examples for
+your properties automatically. For example, if you erroneously defined a
+function for reversing vectors as: (my apologies for the contrived example)
+
+```rust
+fn reverse<T: Clone>(xs: &[T]) -> Vec<T> {
+    let mut rev = vec![];
+    for i in 1..xs.len() {
+        rev.insert(0, xs[i].clone())
+    }
+    rev
+}
+```
+
+And a property to test that `xs == reverse(reverse(xs))`:
+
+```rust
+fn prop(xs: Vec<isize>) -> bool {
+    xs == reverse(&reverse(&xs))
+}
+quickcheck(prop as fn(Vec<isize>) -> bool);
+```
+
+Then without shrinking, you might get a counter-example like:
+
+```
+[quickcheck] TEST FAILED. Arguments: ([-17, 13, -12, 17, -8, -10, 15, -19,
+-19, -9, 11, -5, 1, 19, -16, 6])
+```
+
+Which is pretty mysterious. But with shrinking enabled, you're nearly
+guaranteed to get this counter-example every time:
+
+```
+[quickcheck] TEST FAILED. Arguments: ([0])
+```
+
+Which is going to be much easier to debug.
+
+### More Thorough Checking
+
+Quickcheck uses random input to test, so it won't
+always find bugs that could be uncovered with a particular
+property. You can improve your odds of finding these latent
+bugs by spending more CPU cycles asking quickcheck to find
+them for you. There are a few different ways to do this, and
+which one you choose is mostly a matter of taste.
+
+If you are finding yourself doing this sort of thing a
+lot, you might also be interested in trying out
+[`cargo fuzz`](https://github.com/rust-fuzz/cargo-fuzz),
+which runs in a loop by default.
+
+##### Running in a Loop
+
+One approach is to run your quickcheck properties in a loop that
+just keeps going until you tell it to stop or it finds a bug.
+For example, you could use a bash script such as the following
+one.
+
+```bash
+#!/usr/bin/bash
+
+while true
+do
+    cargo test qc_
+    if [[ x$? != x0 ]] ; then
+        exit $?
+    fi
+done
+```
+
+One thing to note is that this script passes the `qc_` filter to
+`cargo test`. This assumes that you've prefixed all your quickcheck
+properties with `qc_`. You could leave off the filter, but then
+you would be running all your deterministic tests as well, which
+would take time away from quickcheck!
+
+Checking the return code and exiting is also important. Without that
+test, you won't ever notice when a failure happens.
+
+##### Cranking the Number of Tests
+
+Another approach is to just ask quickcheck to run properties more
+times. You can do this either via the
+[tests()](https://docs.rs/quickcheck/*/quickcheck/struct.QuickCheck.html#method.tests)
+method, or via the `QUICKCHECK_TESTS` environment variable.
+This will cause quickcheck to run for a much longer time. Unlike,
+the loop approach this will take a bounded amount of time, which
+makes it more suitable for something like a release cycle that
+wants to really hammer your software.
+
+##### Making Arbitrary Smarter
+
+This approach entails spending more time generating interesting
+inputs in your implementations of Arbitrary. The idea is to
+focus on the corner cases. This approach can be tricky because
+programmers are not usually great at intuiting corner cases,
+and the whole idea of property checking is to take that burden
+off the programmer. Despite the theoretical discomfort, this
+approach can turn out to be practical.
+
+### Generating Structs
+
+It is very simple to generate structs in QuickCheck. Consider the following
+example, where the struct `Point` is defined:
+
+```rust
+struct Point {
+    x: i32,
+    y: i32,
+}
+```
+
+In order to generate a random `Point` instance, you need to implement
+the trait `Arbitrary` for the struct `Point`:
+
+```rust
+use quickcheck::{Arbitrary, Gen};
+
+impl Arbitrary for Point {
+    fn arbitrary(g: &mut Gen) -> Point {
+        Point {
+            x: i32::arbitrary(g),
+            y: i32::arbitrary(g),
+        }
+    }
+}
+```
+
+
+### Case study: The Sieve of Eratosthenes
+
+The [Sieve of Eratosthenes](https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes)
+is a simple and elegant way to find all primes less than or equal to `N`.
+Briefly, the algorithm works by allocating an array with `N` slots containing
+booleans. Slots marked with `false` correspond to prime numbers (or numbers
+not known to be prime while building the sieve) and slots marked with `true`
+are known to not be prime. For each `n`, all of its multiples in this array
+are marked as true. When all `n` have been checked, the numbers marked `false`
+are returned as the primes.
+
+As you might imagine, there's a lot of potential for off-by-one errors, which
+makes it ideal for randomized testing. So let's take a look at my
+implementation and see if we can spot the bug:
+
+```rust
+fn sieve(n: usize) -> Vec<usize> {
+    if n <= 1 {
+        return vec![];
+    }
+
+    let mut marked = vec![false; n+1];
+    marked[0] = true;
+    marked[1] = true;
+    marked[2] = true;
+    for p in 2..n {
+        for i in (2*p..n).filter(|&n| n % p == 0) {
+            marked[i] = true;
+        }
+    }
+    marked.iter()
+          .enumerate()
+          .filter_map(|(i, &m)| if m { None } else { Some(i) })
+          .collect()
+}
+```
+
+Let's try it on a few inputs by hand:
+
+```
+sieve(3) => [2, 3]
+sieve(5) => [2, 3, 5]
+sieve(8) => [2, 3, 5, 7, 8] # !!!
+```
+
+Something has gone wrong! But where? The bug is rather subtle, but it's an
+easy one to make. It's OK if you can't spot it, because we're going to use
+QuickCheck to help us track it down.
+
+Even before looking at some example outputs, it's good to try and come up with
+some *properties* that are always satisfiable by the output of the function. An
+obvious one for the prime number sieve is to check if all numbers returned are
+prime. For that, we'll need an `is_prime` function:
+
+```rust
+fn is_prime(n: usize) -> bool {
+    n != 0 && n != 1 && (2..).take_while(|i| i*i <= n).all(|i| n % i != 0)
+}
+```
+
+All this is doing is checking to see if any number in `[2, sqrt(n)]` divides
+`n` with base cases for `0` and `1`.
+
+Now we can write our QuickCheck property:
+
+```rust
+fn prop_all_prime(n: usize) -> bool {
+    sieve(n).into_iter().all(is_prime)
+}
+```
+
+And finally, we need to invoke `quickcheck` with our property:
+
+```rust
+fn main() {
+    quickcheck(prop_all_prime as fn(usize) -> bool);
+}
+```
+
+A fully working source file with this code is in
+[`examples/sieve.rs`](https://github.com/BurntSushi/quickcheck/blob/master/examples/sieve.rs).
+
+The output of running this program has this message:
+
+```
+[quickcheck] TEST FAILED. Arguments: (4)
+```
+
+Which says that `sieve` failed the `prop_all_prime` test when given `n = 4`.
+Because of shrinking, it was able to find a (hopefully) minimal counter-example
+for our property.
+
+With such a short counter-example, it's hopefully a bit easier to narrow down
+where the bug is. Since `4` is returned, it's likely never marked as being not
+prime. Since `4` is a multiple of `2`, its slot should be marked as `true` when
+`p = 2` on these lines:
+
+```rust
+for i in (2*p..n).filter(|&n| n % p == 0) {
+    marked[i] = true;
+}
+```
+
+Ah! But does the `..` (range) operator include `n`? Nope! This particular
+operator is a half-open interval.
+
+A `2*p..n` range will never yield `4` when `n = 4`. When we change this to
+`2*p..n+1`, all tests pass.
+
+In addition, if our bug happened to result in an index out-of-bounds error,
+then `quickcheck` can handle it just like any other failure—including
+shrinking on failures caused by runtime errors.
+
+But hold on... we're not done yet. Right now, our property tests that all
+the numbers returned by `sieve` are prime but it doesn't test if the list is
+complete. It does not ensure that all the primes between `0` and `n` are found.
+
+Here's a property that is more comprehensive:
+
+```rust
+fn prop_prime_iff_in_the_sieve(n: usize) -> bool {
+    sieve(n) == (0..(n + 1)).filter(|&i| is_prime(i)).collect::<Vec<_>>()
+}
+```
+
+It tests that for each number between 0 and n, inclusive, the naive primality test
+yields the same result as the sieve.
+
+Now, if we run it:
+
+```rust
+fn main() {
+    quickcheck(prop_all_prime as fn(usize) -> bool);
+    quickcheck(prop_prime_iff_in_the_sieve as fn(usize) -> bool);
+}
+```
+
+we see that it fails immediately for value n = 2.
+
+```
+[quickcheck] TEST FAILED. Arguments: (2)
+```
+
+If we inspect `sieve()` once again, we see that we mistakenly mark `2` as
+non-prime. Removing the line `marked[2] = true;` results in both properties
+passing.
+
+### What's not in this port of QuickCheck?
+
+I think I've captured the key features, but there are still things missing:
+
+* Only functions with 8 or fewer parameters can be quickchecked. This
+limitation can be lifted to some `N`, but requires an implementation for each
+`n` of the `Testable` trait.
+* Functions that fail because of a stack overflow are not caught by QuickCheck.
+Therefore, such failures will not have a witness attached
+to them. (I'd like to fix this, but I don't know how.)
+* `Coarbitrary` does not exist in any form in this package. It's unlikely that
+it ever will.
+* `Arbitrary` is not implemented for closures. See
+[issue #56](https://github.com/BurntSushi/quickcheck/issues/56)
+for more details on why.
diff --git a/UNLICENSE b/UNLICENSE
new file mode 100644
index 0000000..68a49da
--- /dev/null
+++ b/UNLICENSE
@@ -0,0 +1,24 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+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 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.
+
+For more information, please refer to <http://unlicense.org/>
diff --git a/examples/btree_set_range.rs b/examples/btree_set_range.rs
new file mode 100644
index 0000000..0e7418b
--- /dev/null
+++ b/examples/btree_set_range.rs
@@ -0,0 +1,55 @@
+use std::collections::BTreeSet;
+use std::ops::Bound::{self, *};
+
+use quickcheck::{quickcheck, TestResult};
+
+/// Covers every `std::ops::Range*` plus variants with exclusive start.
+type RangeAny<T> = (Bound<T>, Bound<T>);
+
+/// Mimic `RangeBounds::contains`, stabilized in Rust 1.35.
+trait RangeBounds<T> {
+    fn contains(&self, _: &T) -> bool;
+}
+
+impl<T: PartialOrd> RangeBounds<T> for RangeAny<T> {
+    fn contains(&self, item: &T) -> bool {
+        (match &self.0 {
+            Included(start) => start <= item,
+            Excluded(start) => start < item,
+            Unbounded => true,
+        }) && (match &self.1 {
+            Included(end) => item <= end,
+            Excluded(end) => item < end,
+            Unbounded => true,
+        })
+    }
+}
+
+/// Checks conditions where `BTreeSet::range` panics:
+/// - Panics if range start > end.
+/// - Panics if range start == end and both bounds are Excluded.
+fn panics<T: PartialOrd>(range: RangeAny<T>) -> bool {
+    match (&range.0, &range.1) {
+        (Excluded(start), Excluded(end)) => start >= end,
+        (Included(start), Excluded(end))
+        | (Excluded(start), Included(end))
+        | (Included(start), Included(end)) => start > end,
+        (Unbounded, _) | (_, Unbounded) => false,
+    }
+}
+
+/// Checks that `BTreeSet::range` returns all items contained in the given `range`.
+fn check_range(set: BTreeSet<i32>, range: RangeAny<i32>) -> TestResult {
+    if panics(range) {
+        TestResult::discard()
+    } else {
+        let xs: BTreeSet<_> = set.range(range).cloned().collect();
+        TestResult::from_bool(
+            set.iter().all(|x| range.contains(x) == xs.contains(x)),
+        )
+    }
+}
+
+fn main() {
+    quickcheck(check_range as fn(_, _) -> TestResult);
+}
diff --git a/examples/out_of_bounds.rs b/examples/out_of_bounds.rs
new file mode 100644
index 0000000..10da938
--- /dev/null
+++ b/examples/out_of_bounds.rs
@@ -0,0 +1,13 @@
+use quickcheck::{quickcheck, TestResult};
+
+fn main() {
+    fn prop(length: usize, index: usize) -> TestResult {
+        let v: Vec<_> = (0..length).collect();
+        if index < length {
+            TestResult::discard()
+        } else {
+            TestResult::must_fail(move || v[index])
+        }
+    }
+    quickcheck(prop as fn(usize, usize) -> TestResult);
+}
diff --git a/examples/reverse.rs b/examples/reverse.rs
new file mode 100644
index 0000000..fff6e71
--- /dev/null
+++ b/examples/reverse.rs
@@ -0,0 +1,16 @@
+use quickcheck::quickcheck;
+
+fn reverse<T: Clone>(xs: &[T]) -> Vec<T> {
+    let mut rev = vec![];
+    for x in xs {
+        rev.insert(0, x.clone())
+    }
+    rev
+}
+
+fn main() {
+    fn equality_after_applying_twice(xs: Vec<isize>) -> bool {
+        xs == reverse(&reverse(&xs))
+    }
+    quickcheck(equality_after_applying_twice as fn(Vec<isize>) -> bool);
+}
diff --git a/examples/reverse_single.rs b/examples/reverse_single.rs
new file mode 100644
index 0000000..6112509
--- /dev/null
+++ b/examples/reverse_single.rs
@@ -0,0 +1,19 @@
+use quickcheck::{quickcheck, TestResult};
+
+fn reverse<T: Clone>(xs: &[T]) -> Vec<T> {
+    let mut rev = vec![];
+    for x in xs {
+        rev.insert(0, x.clone())
+    }
+    rev
+}
+
+fn main() {
+    fn prop(xs: Vec<isize>) -> TestResult {
+        if xs.len() != 1 {
+            return TestResult::discard();
+        }
+        TestResult::from_bool(xs == reverse(&*xs))
+    }
+    quickcheck(prop as fn(Vec<isize>) -> TestResult);
+}
diff --git a/examples/sieve.rs b/examples/sieve.rs
new file mode 100644
index 0000000..f05b8e3
--- /dev/null
+++ b/examples/sieve.rs
@@ -0,0 +1,39 @@
+use quickcheck::quickcheck;
+
+fn sieve(n: usize) -> Vec<usize> {
+    if n <= 1 {
+        return vec![];
+    }
+
+    let mut marked = vec![false; n + 1];
+    marked[0] = true;
+    marked[1] = true;
+    marked[2] = true;
+    for p in 2..n {
+        for i in (2 * p..n).filter(|&n| n % p == 0) {
+            marked[i] = true;
+        }
+    }
+    marked
+        .iter()
+        .enumerate()
+        .filter_map(|(i, &m)| if m { None } else { Some(i) })
+        .collect()
+}
+
+fn is_prime(n: usize) -> bool {
+    n != 0 && n != 1 && (2..).take_while(|i| i * i <= n).all(|i| n % i != 0)
+}
+
+fn main() {
+    fn prop_all_prime(n: usize) -> bool {
+        sieve(n).into_iter().all(is_prime)
+    }
+
+    fn prop_prime_iff_in_the_sieve(n: usize) -> bool {
+        sieve(n) == (0..(n + 1)).filter(|&i| is_prime(i)).collect::<Vec<_>>()
+    }
+
+    quickcheck(prop_all_prime as fn(usize) -> bool);
+    quickcheck(prop_prime_iff_in_the_sieve as fn(usize) -> bool);
+}
diff --git a/examples/sort.rs b/examples/sort.rs
new file mode 100644
index 0000000..0f495a0
--- /dev/null
+++ b/examples/sort.rs
@@ -0,0 +1,46 @@
+// This is a buggy quick sort implementation, QuickCheck will find the bug for
+// you.
+
+use quickcheck::quickcheck;
+
+fn smaller_than<T: Clone + Ord>(xs: &[T], pivot: &T) -> Vec<T> {
+    xs.iter().filter(|&x| *x < *pivot).map(|x| x.clone()).collect()
+}
+
+fn larger_than<T: Clone + Ord>(xs: &[T], pivot: &T) -> Vec<T> {
+    xs.iter().filter(|&x| *x > *pivot).map(|x| x.clone()).collect()
+}
+
+fn sortk<T: Clone + Ord>(x: &T, xs: &[T]) -> Vec<T> {
+    let mut result: Vec<T> = sort(&*smaller_than(xs, x));
+    let last_part = sort(&*larger_than(xs, x));
+    result.push(x.clone());
+    result.extend(last_part.iter().map(|x| x.clone()));
+    result
+}
+
+fn sort<T: Clone + Ord>(list: &[T]) -> Vec<T> {
+    if list.is_empty() {
+        vec![]
+    } else {
+        sortk(&list[0], &list[1..])
+    }
+}
+
+fn main() {
+    fn is_sorted(xs: Vec<isize>) -> bool {
+        for win in xs.windows(2) {
+            if win[0] > win[1] {
+                return false;
+            }
+        }
+        true
+    }
+
+    fn keeps_length(xs: Vec<isize>) -> bool {
+        xs.len() == sort(&*xs).len()
+    }
+    quickcheck(keeps_length as fn(Vec<isize>) -> bool);
+
+    quickcheck(is_sorted as fn(Vec<isize>) -> bool)
+}
diff --git a/rustfmt.toml b/rustfmt.toml
new file mode 100644
index 0000000..aa37a21
--- /dev/null
+++ b/rustfmt.toml
@@ -0,0 +1,2 @@
+max_width = 79
+use_small_heuristics = "max"
diff --git a/src/arbitrary.rs b/src/arbitrary.rs
new file mode 100644
index 0000000..92f893b
--- /dev/null
+++ b/src/arbitrary.rs
@@ -0,0 +1,1586 @@
+use std::char;
+use std::collections::{
+    BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque,
+};
+use std::env;
+use std::ffi::{CString, OsString};
+use std::hash::{BuildHasher, Hash};
+use std::iter::{empty, once};
+use std::net::{
+    IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6,
+};
+use std::num::Wrapping;
+use std::num::{
+    NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,
+};
+use std::ops::{
+    Bound, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo,
+    RangeToInclusive,
+};
+use std::path::PathBuf;
+use std::sync::Arc;
+use std::time::{Duration, SystemTime, UNIX_EPOCH};
+
+use rand::seq::SliceRandom;
+use rand::{self, Rng, SeedableRng};
+
+/// Gen represents a PRNG.
+///
+/// It is the source of randomness from which QuickCheck will generate
+/// values. An instance of `Gen` is passed to every invocation of
+/// `Arbitrary::arbitrary`, which permits callers to use lower level RNG
+/// routines to generate values.
+///
+/// It is unspecified whether this is a secure RNG or not. Therefore, callers
+/// should assume it is insecure.
+pub struct Gen {
+    rng: rand::rngs::SmallRng,
+    size: usize,
+}
+
+impl Gen {
+    /// Returns a `Gen` with the given size configuration.
+    ///
+    /// The `size` parameter controls the size of random values generated.
+    /// For example, it specifies the maximum length of a randomly generated
+    /// vector, but is and should not be used to control the range of a
+    /// randomly generated number. (Unless that number is used to control the
+    /// size of a data structure.)
+    pub fn new(size: usize) -> Gen {
+        Gen { rng: rand::rngs::SmallRng::from_entropy(), size: size }
+    }
+
+    /// Returns the size configured with this generator.
+    pub fn size(&self) -> usize {
+        self.size
+    }
+
+    /// Choose among the possible alternatives in the slice given. If the slice
+    /// is empty, then `None` is returned. Otherwise, a non-`None` value is
+    /// guaranteed to be returned.
+    pub fn choose<'a, T>(&mut self, slice: &'a [T]) -> Option<&'a T> {
+        slice.choose(&mut self.rng)
+    }
+
+    fn gen<T>(&mut self) -> T
+    where
+        rand::distributions::Standard: rand::distributions::Distribution<T>,
+    {
+        self.rng.gen()
+    }
+
+    fn gen_range<T, R>(&mut self, range: R) -> T
+    where
+        T: rand::distributions::uniform::SampleUniform,
+        R: rand::distributions::uniform::SampleRange<T>,
+    {
+        self.rng.gen_range(range)
+    }
+}
+
+/// Creates a shrinker with zero elements.
+pub fn empty_shrinker<A: 'static>() -> Box<dyn Iterator<Item = A>> {
+    Box::new(empty())
+}
+
+/// Creates a shrinker with a single element.
+pub fn single_shrinker<A: 'static>(value: A) -> Box<dyn Iterator<Item = A>> {
+    Box::new(once(value))
+}
+
+/// `Arbitrary` describes types whose values can be randomly generated and
+/// shrunk.
+///
+/// Aside from shrinking, `Arbitrary` is different from typical RNGs in that
+/// it respects `Gen::size()` for controlling how much memory a particular
+/// value uses, for practical purposes. For example, `Vec::arbitrary()`
+/// respects `Gen::size()` to decide the maximum `len()` of the vector.
+/// This behavior is necessary due to practical speed and size limitations.
+/// Conversely, `i32::arbitrary()` ignores `size()` since all `i32` values
+/// require `O(1)` memory and operations between `i32`s require `O(1)` time
+/// (with the exception of exponentiation).
+///
+/// Additionally, all types that implement `Arbitrary` must also implement
+/// `Clone`.
+pub trait Arbitrary: Clone + 'static {
+    /// Return an arbitrary value.
+    ///
+    /// Implementations should respect `Gen::size()` when decisions about how
+    /// big a particular value should be. Implementations should generally
+    /// defer to other `Arbitrary` implementations to generate other random
+    /// values when necessary. The `Gen` type also offers a few RNG helper
+    /// routines.
+    fn arbitrary(g: &mut Gen) -> Self;
+
+    /// Return an iterator of values that are smaller than itself.
+    ///
+    /// The way in which a value is "smaller" is implementation defined. In
+    /// some cases, the interpretation is obvious: shrinking an integer should
+    /// produce integers smaller than itself. Others are more complex, for
+    /// example, shrinking a `Vec` should both shrink its size and shrink its
+    /// component values.
+    ///
+    /// The iterator returned should be bounded to some reasonable size.
+    ///
+    /// It is always correct to return an empty iterator, and indeed, this
+    /// is the default implementation. The downside of this approach is that
+    /// witnesses to failures in properties will be more inscrutable.
+    fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
+        empty_shrinker()
+    }
+}
+
+impl Arbitrary for () {
+    fn arbitrary(_: &mut Gen) -> () {
+        ()
+    }
+}
+
+impl Arbitrary for bool {
+    fn arbitrary(g: &mut Gen) -> bool {
+        g.gen()
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item = bool>> {
+        if *self {
+            single_shrinker(false)
+        } else {
+            empty_shrinker()
+        }
+    }
+}
+
+impl<A: Arbitrary> Arbitrary for Option<A> {
+    fn arbitrary(g: &mut Gen) -> Option<A> {
+        if g.gen() {
+            None
+        } else {
+            Some(Arbitrary::arbitrary(g))
+        }
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item = Option<A>>> {
+        match *self {
+            None => empty_shrinker(),
+            Some(ref x) => {
+                let chain = single_shrinker(None).chain(x.shrink().map(Some));
+                Box::new(chain)
+            }
+        }
+    }
+}
+
+impl<A: Arbitrary, B: Arbitrary> Arbitrary for Result<A, B> {
+    fn arbitrary(g: &mut Gen) -> Result<A, B> {
+        if g.gen() {
+            Ok(Arbitrary::arbitrary(g))
+        } else {
+            Err(Arbitrary::arbitrary(g))
+        }
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item = Result<A, B>>> {
+        match *self {
+            Ok(ref x) => {
+                let xs = x.shrink();
+                let tagged = xs.map(Ok);
+                Box::new(tagged)
+            }
+            Err(ref x) => {
+                let xs = x.shrink();
+                let tagged = xs.map(Err);
+                Box::new(tagged)
+            }
+        }
+    }
+}
+
+macro_rules! impl_arb_for_single_tuple {
+    ($(($type_param:ident, $tuple_index:tt),)*) => {
+        impl<$($type_param),*> Arbitrary for ($($type_param,)*)
+            where $($type_param: Arbitrary,)*
+        {
+            fn arbitrary(g: &mut Gen) -> ($($type_param,)*) {
+                (
+                    $(
+                        $type_param::arbitrary(g),
+                    )*
+                )
+            }
+
+            fn shrink(&self) -> Box<dyn Iterator<Item=($($type_param,)*)>> {
+                let iter = ::std::iter::empty();
+                $(
+                    let cloned = self.clone();
+                    let iter = iter.chain(
+                        self.$tuple_index.shrink().map(move |shr_value| {
+                            let mut result = cloned.clone();
+                            result.$tuple_index = shr_value;
+                            result
+                        })
+                    );
+                )*
+                Box::new(iter)
+            }
+        }
+    };
+}
+
+macro_rules! impl_arb_for_tuples {
+    (@internal [$($acc:tt,)*]) => { };
+    (@internal [$($acc:tt,)*] ($type_param:ident, $tuple_index:tt), $($rest:tt,)*) => {
+        impl_arb_for_single_tuple!($($acc,)* ($type_param, $tuple_index),);
+        impl_arb_for_tuples!(@internal [$($acc,)* ($type_param, $tuple_index),] $($rest,)*);
+    };
+    ($(($type_param:ident, $tuple_index:tt),)*) => {
+        impl_arb_for_tuples!(@internal [] $(($type_param, $tuple_index),)*);
+    };
+}
+
+impl_arb_for_tuples! {
+    (A, 0),
+    (B, 1),
+    (C, 2),
+    (D, 3),
+    (E, 4),
+    (F, 5),
+    (G, 6),
+    (H, 7),
+}
+
+impl<A: Arbitrary> Arbitrary for Vec<A> {
+    fn arbitrary(g: &mut Gen) -> Vec<A> {
+        let size = {
+            let s = g.size();
+            g.gen_range(0..s)
+        };
+        (0..size).map(|_| A::arbitrary(g)).collect()
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item = Vec<A>>> {
+        VecShrinker::new(self.clone())
+    }
+}
+
+///Iterator which returns successive attempts to shrink the vector `seed`
+struct VecShrinker<A> {
+    seed: Vec<A>,
+    /// How much which is removed when trying with smaller vectors
+    size: usize,
+    /// The end of the removed elements
+    offset: usize,
+    /// The shrinker for the element at `offset` once shrinking of individual
+    /// elements are attempted
+    element_shrinker: Box<dyn Iterator<Item = A>>,
+}
+
+impl<A: Arbitrary> VecShrinker<A> {
+    fn new(seed: Vec<A>) -> Box<dyn Iterator<Item = Vec<A>>> {
+        let es = match seed.get(0) {
+            Some(e) => e.shrink(),
+            None => return empty_shrinker(),
+        };
+        let size = seed.len();
+        Box::new(VecShrinker {
+            seed: seed,
+            size: size,
+            offset: size,
+            element_shrinker: es,
+        })
+    }
+
+    /// Returns the next shrunk element if any, `offset` points to the index
+    /// after the returned element after the function returns
+    fn next_element(&mut self) -> Option<A> {
+        loop {
+            match self.element_shrinker.next() {
+                Some(e) => return Some(e),
+                None => match self.seed.get(self.offset) {
+                    Some(e) => {
+                        self.element_shrinker = e.shrink();
+                        self.offset += 1;
+                    }
+                    None => return None,
+                },
+            }
+        }
+    }
+}
+
+impl<A> Iterator for VecShrinker<A>
+where
+    A: Arbitrary,
+{
+    type Item = Vec<A>;
+    fn next(&mut self) -> Option<Vec<A>> {
+        // Try with an empty vector first
+        if self.size == self.seed.len() {
+            self.size /= 2;
+            self.offset = self.size;
+            return Some(vec![]);
+        }
+        if self.size != 0 {
+            // Generate a smaller vector by removing the elements between
+            // (offset - size) and offset
+            let xs1 = self.seed[..(self.offset - self.size)]
+                .iter()
+                .chain(&self.seed[self.offset..])
+                .cloned()
+                .collect();
+            self.offset += self.size;
+            // Try to reduce the amount removed from the vector once all
+            // previous sizes tried
+            if self.offset > self.seed.len() {
+                self.size /= 2;
+                self.offset = self.size;
+            }
+            Some(xs1)
+        } else {
+            // A smaller vector did not work so try to shrink each element of
+            // the vector instead Reuse `offset` as the index determining which
+            // element to shrink
+
+            // The first element shrinker is already created so skip the first
+            // offset (self.offset == 0 only on first entry to this part of the
+            // iterator)
+            if self.offset == 0 {
+                self.offset = 1
+            }
+
+            match self.next_element() {
+                Some(e) => Some(
+                    self.seed[..self.offset - 1]
+                        .iter()
+                        .cloned()
+                        .chain(Some(e).into_iter())
+                        .chain(self.seed[self.offset..].iter().cloned())
+                        .collect(),
+                ),
+                None => None,
+            }
+        }
+    }
+}
+
+impl<K: Arbitrary + Ord, V: Arbitrary> Arbitrary for BTreeMap<K, V> {
+    fn arbitrary(g: &mut Gen) -> BTreeMap<K, V> {
+        let vec: Vec<(K, V)> = Arbitrary::arbitrary(g);
+        vec.into_iter().collect()
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item = BTreeMap<K, V>>> {
+        let vec: Vec<(K, V)> = self.clone().into_iter().collect();
+        Box::new(
+            vec.shrink().map(|v| v.into_iter().collect::<BTreeMap<K, V>>()),
+        )
+    }
+}
+
+impl<
+        K: Arbitrary + Eq + Hash,
+        V: Arbitrary,
+        S: BuildHasher + Default + Clone + 'static,
+    > Arbitrary for HashMap<K, V, S>
+{
+    fn arbitrary(g: &mut Gen) -> Self {
+        let vec: Vec<(K, V)> = Arbitrary::arbitrary(g);
+        vec.into_iter().collect()
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
+        let vec: Vec<(K, V)> = self.clone().into_iter().collect();
+        Box::new(vec.shrink().map(|v| v.into_iter().collect::<Self>()))
+    }
+}
+
+impl<T: Arbitrary + Ord> Arbitrary for BTreeSet<T> {
+    fn arbitrary(g: &mut Gen) -> BTreeSet<T> {
+        let vec: Vec<T> = Arbitrary::arbitrary(g);
+        vec.into_iter().collect()
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item = BTreeSet<T>>> {
+        let vec: Vec<T> = self.clone().into_iter().collect();
+        Box::new(vec.shrink().map(|v| v.into_iter().collect::<BTreeSet<T>>()))
+    }
+}
+
+impl<T: Arbitrary + Ord> Arbitrary for BinaryHeap<T> {
+    fn arbitrary(g: &mut Gen) -> BinaryHeap<T> {
+        let vec: Vec<T> = Arbitrary::arbitrary(g);
+        vec.into_iter().collect()
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item = BinaryHeap<T>>> {
+        let vec: Vec<T> = self.clone().into_iter().collect();
+        Box::new(
+            vec.shrink().map(|v| v.into_iter().collect::<BinaryHeap<T>>()),
+        )
+    }
+}
+
+impl<T: Arbitrary + Eq + Hash, S: BuildHasher + Default + Clone + 'static>
+    Arbitrary for HashSet<T, S>
+{
+    fn arbitrary(g: &mut Gen) -> Self {
+        let vec: Vec<T> = Arbitrary::arbitrary(g);
+        vec.into_iter().collect()
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
+        let vec: Vec<T> = self.clone().into_iter().collect();
+        Box::new(vec.shrink().map(|v| v.into_iter().collect::<Self>()))
+    }
+}
+
+impl<T: Arbitrary> Arbitrary for LinkedList<T> {
+    fn arbitrary(g: &mut Gen) -> LinkedList<T> {
+        let vec: Vec<T> = Arbitrary::arbitrary(g);
+        vec.into_iter().collect()
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item = LinkedList<T>>> {
+        let vec: Vec<T> = self.clone().into_iter().collect();
+        Box::new(
+            vec.shrink().map(|v| v.into_iter().collect::<LinkedList<T>>()),
+        )
+    }
+}
+
+impl<T: Arbitrary> Arbitrary for VecDeque<T> {
+    fn arbitrary(g: &mut Gen) -> VecDeque<T> {
+        let vec: Vec<T> = Arbitrary::arbitrary(g);
+        vec.into_iter().collect()
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item = VecDeque<T>>> {
+        let vec: Vec<T> = self.clone().into_iter().collect();
+        Box::new(vec.shrink().map(|v| v.into_iter().collect::<VecDeque<T>>()))
+    }
+}
+
+impl Arbitrary for IpAddr {
+    fn arbitrary(g: &mut Gen) -> IpAddr {
+        let ipv4: bool = g.gen();
+        if ipv4 {
+            IpAddr::V4(Arbitrary::arbitrary(g))
+        } else {
+            IpAddr::V6(Arbitrary::arbitrary(g))
+        }
+    }
+}
+
+impl Arbitrary for Ipv4Addr {
+    fn arbitrary(g: &mut Gen) -> Ipv4Addr {
+        Ipv4Addr::new(g.gen(), g.gen(), g.gen(), g.gen())
+    }
+}
+
+impl Arbitrary for Ipv6Addr {
+    fn arbitrary(g: &mut Gen) -> Ipv6Addr {
+        Ipv6Addr::new(
+            g.gen(),
+            g.gen(),
+            g.gen(),
+            g.gen(),
+            g.gen(),
+            g.gen(),
+            g.gen(),
+            g.gen(),
+        )
+    }
+}
+
+impl Arbitrary for SocketAddr {
+    fn arbitrary(g: &mut Gen) -> SocketAddr {
+        SocketAddr::new(Arbitrary::arbitrary(g), g.gen())
+    }
+}
+
+impl Arbitrary for SocketAddrV4 {
+    fn arbitrary(g: &mut Gen) -> SocketAddrV4 {
+        SocketAddrV4::new(Arbitrary::arbitrary(g), g.gen())
+    }
+}
+
+impl Arbitrary for SocketAddrV6 {
+    fn arbitrary(g: &mut Gen) -> SocketAddrV6 {
+        SocketAddrV6::new(Arbitrary::arbitrary(g), g.gen(), g.gen(), g.gen())
+    }
+}
+
+impl Arbitrary for PathBuf {
+    fn arbitrary(g: &mut Gen) -> PathBuf {
+        // use some real directories as guesses, so we may end up with
+        // actual working directories in case that is relevant.
+        let here =
+            env::current_dir().unwrap_or(PathBuf::from("/test/directory"));
+        let temp = env::temp_dir();
+        #[allow(deprecated)]
+        let home = env::home_dir().unwrap_or(PathBuf::from("/home/user"));
+        let mut p = g
+            .choose(&[
+                here,
+                temp,
+                home,
+                PathBuf::from("."),
+                PathBuf::from(".."),
+                PathBuf::from("../../.."),
+                PathBuf::new(),
+            ])
+            .unwrap()
+            .to_owned();
+        p.extend(Vec::<OsString>::arbitrary(g).iter());
+        p
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item = PathBuf>> {
+        let mut shrunk = vec![];
+        let mut popped = self.clone();
+        if popped.pop() {
+            shrunk.push(popped);
+        }
+
+        // Iterating over a Path performs a small amount of normalization.
+        let normalized = self.iter().collect::<PathBuf>();
+        if normalized.as_os_str() != self.as_os_str() {
+            shrunk.push(normalized);
+        }
+
+        // Add the canonicalized variant only if canonicalizing the path
+        // actually does something, making it (hopefully) smaller. Also, ignore
+        // canonicalization if canonicalization errors.
+        if let Ok(canonicalized) = self.canonicalize() {
+            if canonicalized.as_os_str() != self.as_os_str() {
+                shrunk.push(canonicalized);
+            }
+        }
+
+        Box::new(shrunk.into_iter())
+    }
+}
+
+impl Arbitrary for OsString {
+    fn arbitrary(g: &mut Gen) -> OsString {
+        OsString::from(String::arbitrary(g))
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item = OsString>> {
+        let mystring: String = self.clone().into_string().unwrap();
+        Box::new(mystring.shrink().map(|s| OsString::from(s)))
+    }
+}
+
+impl Arbitrary for String {
+    fn arbitrary(g: &mut Gen) -> String {
+        let size = {
+            let s = g.size();
+            g.gen_range(0..s)
+        };
+        (0..size).map(|_| char::arbitrary(g)).collect()
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item = String>> {
+        // Shrink a string by shrinking a vector of its characters.
+        let chars: Vec<char> = self.chars().collect();
+        Box::new(chars.shrink().map(|x| x.into_iter().collect::<String>()))
+    }
+}
+
+impl Arbitrary for CString {
+    fn arbitrary(g: &mut Gen) -> Self {
+        let size = {
+            let s = g.size();
+            g.gen_range(0..s)
+        };
+        // Use either random bytes or random UTF-8 encoded codepoints.
+        let utf8: bool = g.gen();
+        if utf8 {
+            CString::new(
+                (0..)
+                    .map(|_| char::arbitrary(g))
+                    .filter(|&c| c != '\0')
+                    .take(size)
+                    .collect::<String>(),
+            )
+        } else {
+            CString::new(
+                (0..)
+                    .map(|_| u8::arbitrary(g))
+                    .filter(|&c| c != b'\0')
+                    .take(size)
+                    .collect::<Vec<u8>>(),
+            )
+        }
+        .expect("null characters should have been filtered out")
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item = CString>> {
+        // Use the implementation for a vec here, but make sure null characters
+        // are filtered out.
+        Box::new(VecShrinker::new(self.as_bytes().to_vec()).map(|bytes| {
+            CString::new(
+                bytes.into_iter().filter(|&c| c != 0).collect::<Vec<u8>>(),
+            )
+            .expect("null characters should have been filtered out")
+        }))
+    }
+}
+
+impl Arbitrary for char {
+    fn arbitrary(g: &mut Gen) -> char {
+        let mode = g.gen_range(0..100);
+        match mode {
+            0..=49 => {
+                // ASCII + some control characters
+                g.gen_range(0..0xB0) as u8 as char
+            }
+            50..=59 => {
+                // Unicode BMP characters
+                loop {
+                    if let Some(x) = char::from_u32(g.gen_range(0..0x10000)) {
+                        return x;
+                    }
+                    // ignore surrogate pairs
+                }
+            }
+            60..=84 => {
+                // Characters often used in programming languages
+                g.choose(&[
+                    ' ', ' ', ' ', '\t', '\n', '~', '`', '!', '@', '#', '$',
+                    '%', '^', '&', '*', '(', ')', '_', '-', '=', '+', '[',
+                    ']', '{', '}', ':', ';', '\'', '"', '\\', '|', ',', '<',
+                    '>', '.', '/', '?', '0', '1', '2', '3', '4', '5', '6',
+                    '7', '8', '9',
+                ])
+                .unwrap()
+                .to_owned()
+            }
+            85..=89 => {
+                // Tricky Unicode, part 1
+                g.choose(&[
+                    '\u{0149}', // a deprecated character
+                    '\u{fff0}', // some of "Other, format" category:
+                    '\u{fff1}',
+                    '\u{fff2}',
+                    '\u{fff3}',
+                    '\u{fff4}',
+                    '\u{fff5}',
+                    '\u{fff6}',
+                    '\u{fff7}',
+                    '\u{fff8}',
+                    '\u{fff9}',
+                    '\u{fffA}',
+                    '\u{fffB}',
+                    '\u{fffC}',
+                    '\u{fffD}',
+                    '\u{fffE}',
+                    '\u{fffF}',
+                    '\u{0600}',
+                    '\u{0601}',
+                    '\u{0602}',
+                    '\u{0603}',
+                    '\u{0604}',
+                    '\u{0605}',
+                    '\u{061C}',
+                    '\u{06DD}',
+                    '\u{070F}',
+                    '\u{180E}',
+                    '\u{110BD}',
+                    '\u{1D173}',
+                    '\u{e0001}', // tag
+                    '\u{e0020}', //  tag space
+                    '\u{e000}',
+                    '\u{e001}',
+                    '\u{ef8ff}', // private use
+                    '\u{f0000}',
+                    '\u{ffffd}',
+                    '\u{ffffe}',
+                    '\u{fffff}',
+                    '\u{100000}',
+                    '\u{10FFFD}',
+                    '\u{10FFFE}',
+                    '\u{10FFFF}',
+                    // "Other, surrogate" characters are so that very special
+                    // that they are not even allowed in safe Rust,
+                    //so omitted here
+                    '\u{3000}', // ideographic space
+                    '\u{1680}',
+                    // other space characters are already covered by two next
+                    // branches
+                ])
+                .unwrap()
+                .to_owned()
+            }
+            90..=94 => {
+                // Tricky unicode, part 2
+                char::from_u32(g.gen_range(0x2000..0x2070)).unwrap()
+            }
+            95..=99 => {
+                // Completely arbitrary characters
+                g.gen()
+            }
+            _ => unreachable!(),
+        }
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item = char>> {
+        Box::new((*self as u32).shrink().filter_map(char::from_u32))
+    }
+}
+
+macro_rules! unsigned_shrinker {
+    ($ty:ty) => {
+        mod shrinker {
+            pub struct UnsignedShrinker {
+                x: $ty,
+                i: $ty,
+            }
+
+            impl UnsignedShrinker {
+                pub fn new(x: $ty) -> Box<dyn Iterator<Item = $ty>> {
+                    if x == 0 {
+                        super::empty_shrinker()
+                    } else {
+                        Box::new(
+                            vec![0]
+                                .into_iter()
+                                .chain(UnsignedShrinker { x: x, i: x / 2 }),
+                        )
+                    }
+                }
+            }
+
+            impl Iterator for UnsignedShrinker {
+                type Item = $ty;
+                fn next(&mut self) -> Option<$ty> {
+                    if self.x - self.i < self.x {
+                        let result = Some(self.x - self.i);
+                        self.i = self.i / 2;
+                        result
+                    } else {
+                        None
+                    }
+                }
+            }
+        }
+    };
+}
+
+macro_rules! unsigned_problem_values {
+    ($t:ty) => {
+        &[<$t>::min_value(), 1, <$t>::max_value()]
+    };
+}
+
+macro_rules! unsigned_arbitrary {
+    ($($ty:tt),*) => {
+        $(
+            impl Arbitrary for $ty {
+                fn arbitrary(g: &mut Gen) -> $ty {
+                    match g.gen_range(0..10) {
+                        0 => {
+                            *g.choose(unsigned_problem_values!($ty)).unwrap()
+                        },
+                        _ => g.gen()
+                    }
+                }
+                fn shrink(&self) -> Box<dyn Iterator<Item=$ty>> {
+                    unsigned_shrinker!($ty);
+                    shrinker::UnsignedShrinker::new(*self)
+                }
+            }
+        )*
+    }
+}
+
+unsigned_arbitrary! {
+    usize, u8, u16, u32, u64, u128
+}
+
+macro_rules! signed_shrinker {
+    ($ty:ty) => {
+        mod shrinker {
+            pub struct SignedShrinker {
+                x: $ty,
+                i: $ty,
+            }
+
+            impl SignedShrinker {
+                pub fn new(x: $ty) -> Box<dyn Iterator<Item = $ty>> {
+                    if x == 0 {
+                        super::empty_shrinker()
+                    } else {
+                        let shrinker = SignedShrinker { x: x, i: x / 2 };
+                        let mut items = vec![0];
+                        if shrinker.i < 0 && shrinker.x != <$ty>::MIN {
+                            items.push(shrinker.x.abs());
+                        }
+                        Box::new(items.into_iter().chain(shrinker))
+                    }
+                }
+            }
+
+            impl Iterator for SignedShrinker {
+                type Item = $ty;
+                fn next(&mut self) -> Option<$ty> {
+                    if self.x == <$ty>::MIN
+                        || (self.x - self.i).abs() < self.x.abs()
+                    {
+                        let result = Some(self.x - self.i);
+                        self.i = self.i / 2;
+                        result
+                    } else {
+                        None
+                    }
+                }
+            }
+        }
+    };
+}
+
+macro_rules! signed_problem_values {
+    ($t:ty) => {
+        &[<$t>::min_value(), 0, <$t>::max_value()]
+    };
+}
+
+macro_rules! signed_arbitrary {
+    ($($ty:tt),*) => {
+        $(
+            impl Arbitrary for $ty {
+                fn arbitrary(g: &mut Gen) -> $ty {
+                    match g.gen_range(0..10) {
+                        0 => {
+                            *g.choose(signed_problem_values!($ty)).unwrap()
+                        },
+                        _ => g.gen()
+                    }
+                }
+                fn shrink(&self) -> Box<dyn Iterator<Item=$ty>> {
+                    signed_shrinker!($ty);
+                    shrinker::SignedShrinker::new(*self)
+                }
+            }
+        )*
+    }
+}
+
+signed_arbitrary! {
+    isize, i8, i16, i32, i64, i128
+}
+
+macro_rules! float_problem_values {
+    ($path:path) => {{
+        // hack. see: https://github.com/rust-lang/rust/issues/48067
+        use $path as p;
+        &[p::NAN, p::NEG_INFINITY, p::MIN, -0., 0., p::MAX, p::INFINITY]
+    }};
+}
+
+macro_rules! float_arbitrary {
+    ($($t:ty, $path:path, $shrinkable:ty),+) => {$(
+        impl Arbitrary for $t {
+            fn arbitrary(g: &mut Gen) -> $t {
+                match g.gen_range(0..10) {
+                    0 => *g.choose(float_problem_values!($path)).unwrap(),
+                    _ => {
+                        use $path as p;
+                        let exp = g.gen_range((0.)..p::MAX_EXP as i16 as $t);
+                        let mantissa = g.gen_range((1.)..2.);
+                        let sign = *g.choose(&[-1., 1.]).unwrap();
+                        sign * mantissa * exp.exp2()
+                    }
+                }
+            }
+            fn shrink(&self) -> Box<dyn Iterator<Item = $t>> {
+                signed_shrinker!($shrinkable);
+                let it = shrinker::SignedShrinker::new(*self as $shrinkable);
+                Box::new(it.map(|x| x as $t))
+            }
+        }
+    )*};
+}
+
+float_arbitrary!(f32, std::f32, i32, f64, std::f64, i64);
+
+macro_rules! unsigned_non_zero_shrinker {
+    ($ty:tt) => {
+        mod shrinker {
+            pub struct UnsignedNonZeroShrinker {
+                x: $ty,
+                i: $ty,
+            }
+
+            impl UnsignedNonZeroShrinker {
+                pub fn new(x: $ty) -> Box<dyn Iterator<Item = $ty>> {
+                    debug_assert!(x > 0);
+
+                    if x == 1 {
+                        super::empty_shrinker()
+                    } else {
+                        Box::new(
+                            std::iter::once(1).chain(
+                                UnsignedNonZeroShrinker { x: x, i: x / 2 },
+                            ),
+                        )
+                    }
+                }
+            }
+
+            impl Iterator for UnsignedNonZeroShrinker {
+                type Item = $ty;
+
+                fn next(&mut self) -> Option<$ty> {
+                    if self.x - self.i < self.x {
+                        let result = Some(self.x - self.i);
+                        self.i = self.i / 2;
+                        result
+                    } else {
+                        None
+                    }
+                }
+            }
+        }
+    };
+}
+
+macro_rules! unsigned_non_zero_arbitrary {
+    ($($ty:tt => $inner:tt),*) => {
+        $(
+            impl Arbitrary for $ty {
+                fn arbitrary(g: &mut Gen) -> $ty {
+                    let mut v: $inner = g.gen();
+                    if v == 0 {
+                        v += 1;
+                    }
+                    $ty::new(v).expect("non-zero value contsturction failed")
+                }
+
+                fn shrink(&self) -> Box<dyn Iterator<Item = $ty>> {
+                    unsigned_non_zero_shrinker!($inner);
+                    Box::new(shrinker::UnsignedNonZeroShrinker::new(self.get())
+                        .map($ty::new)
+                        .map(Option::unwrap))
+                }
+            }
+        )*
+    }
+}
+
+unsigned_non_zero_arbitrary! {
+    NonZeroUsize => usize,
+    NonZeroU8    => u8,
+    NonZeroU16   => u16,
+    NonZeroU32   => u32,
+    NonZeroU64   => u64,
+    NonZeroU128  => u128
+}
+
+impl<T: Arbitrary> Arbitrary for Wrapping<T> {
+    fn arbitrary(g: &mut Gen) -> Wrapping<T> {
+        Wrapping(T::arbitrary(g))
+    }
+    fn shrink(&self) -> Box<dyn Iterator<Item = Wrapping<T>>> {
+        Box::new(self.0.shrink().map(|inner| Wrapping(inner)))
+    }
+}
+
+impl<T: Arbitrary> Arbitrary for Bound<T> {
+    fn arbitrary(g: &mut Gen) -> Bound<T> {
+        match g.gen_range(0..3) {
+            0 => Bound::Included(T::arbitrary(g)),
+            1 => Bound::Excluded(T::arbitrary(g)),
+            _ => Bound::Unbounded,
+        }
+    }
+    fn shrink(&self) -> Box<dyn Iterator<Item = Bound<T>>> {
+        match *self {
+            Bound::Included(ref x) => {
+                Box::new(x.shrink().map(Bound::Included))
+            }
+            Bound::Excluded(ref x) => {
+                Box::new(x.shrink().map(Bound::Excluded))
+            }
+            Bound::Unbounded => empty_shrinker(),
+        }
+    }
+}
+
+impl<T: Arbitrary + Clone + PartialOrd> Arbitrary for Range<T> {
+    fn arbitrary(g: &mut Gen) -> Range<T> {
+        Arbitrary::arbitrary(g)..Arbitrary::arbitrary(g)
+    }
+    fn shrink(&self) -> Box<dyn Iterator<Item = Range<T>>> {
+        Box::new(
+            (self.start.clone(), self.end.clone()).shrink().map(|(s, e)| s..e),
+        )
+    }
+}
+
+impl<T: Arbitrary + Clone + PartialOrd> Arbitrary for RangeInclusive<T> {
+    fn arbitrary(g: &mut Gen) -> RangeInclusive<T> {
+        Arbitrary::arbitrary(g)..=Arbitrary::arbitrary(g)
+    }
+    fn shrink(&self) -> Box<dyn Iterator<Item = RangeInclusive<T>>> {
+        Box::new(
+            (self.start().clone(), self.end().clone())
+                .shrink()
+                .map(|(s, e)| s..=e),
+        )
+    }
+}
+
+impl<T: Arbitrary + Clone + PartialOrd> Arbitrary for RangeFrom<T> {
+    fn arbitrary(g: &mut Gen) -> RangeFrom<T> {
+        Arbitrary::arbitrary(g)..
+    }
+    fn shrink(&self) -> Box<dyn Iterator<Item = RangeFrom<T>>> {
+        Box::new(self.start.clone().shrink().map(|start| start..))
+    }
+}
+
+impl<T: Arbitrary + Clone + PartialOrd> Arbitrary for RangeTo<T> {
+    fn arbitrary(g: &mut Gen) -> RangeTo<T> {
+        ..Arbitrary::arbitrary(g)
+    }
+    fn shrink(&self) -> Box<dyn Iterator<Item = RangeTo<T>>> {
+        Box::new(self.end.clone().shrink().map(|end| ..end))
+    }
+}
+
+impl<T: Arbitrary + Clone + PartialOrd> Arbitrary for RangeToInclusive<T> {
+    fn arbitrary(g: &mut Gen) -> RangeToInclusive<T> {
+        ..=Arbitrary::arbitrary(g)
+    }
+    fn shrink(&self) -> Box<dyn Iterator<Item = RangeToInclusive<T>>> {
+        Box::new(self.end.clone().shrink().map(|end| ..=end))
+    }
+}
+
+impl Arbitrary for RangeFull {
+    fn arbitrary(_: &mut Gen) -> RangeFull {
+        ..
+    }
+}
+
+impl Arbitrary for Duration {
+    fn arbitrary(gen: &mut Gen) -> Self {
+        let seconds = gen.gen_range(0..gen.size() as u64);
+        let nanoseconds = gen.gen_range(0..1_000_000);
+        Duration::new(seconds, nanoseconds)
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
+        Box::new(
+            (self.as_secs(), self.subsec_nanos())
+                .shrink()
+                .map(|(secs, nanos)| Duration::new(secs, nanos % 1_000_000)),
+        )
+    }
+}
+
+impl<A: Arbitrary> Arbitrary for Box<A> {
+    fn arbitrary(g: &mut Gen) -> Box<A> {
+        Box::new(A::arbitrary(g))
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item = Box<A>>> {
+        Box::new((**self).shrink().map(Box::new))
+    }
+}
+
+impl<A: Arbitrary + Sync> Arbitrary for Arc<A> {
+    fn arbitrary(g: &mut Gen) -> Arc<A> {
+        Arc::new(A::arbitrary(g))
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item = Arc<A>>> {
+        Box::new((**self).shrink().map(Arc::new))
+    }
+}
+
+impl Arbitrary for SystemTime {
+    fn arbitrary(gen: &mut Gen) -> Self {
+        let after_epoch = bool::arbitrary(gen);
+        let duration = Duration::arbitrary(gen);
+        if after_epoch {
+            UNIX_EPOCH + duration
+        } else {
+            UNIX_EPOCH - duration
+        }
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
+        let duration = match self.duration_since(UNIX_EPOCH) {
+            Ok(duration) => duration,
+            Err(e) => e.duration(),
+        };
+        Box::new(
+            duration
+                .shrink()
+                .flat_map(|d| vec![UNIX_EPOCH + d, UNIX_EPOCH - d]),
+        )
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use std::collections::{
+        BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque,
+    };
+    use std::fmt::Debug;
+    use std::hash::Hash;
+    use std::num::Wrapping;
+    use std::path::PathBuf;
+
+    use super::{Arbitrary, Gen};
+
+    #[test]
+    fn arby_unit() {
+        assert_eq!(arby::<()>(), ());
+    }
+
+    macro_rules! arby_int {
+        ( $signed:expr, $($t:ty),+) => {$(
+            let mut arbys = (0..1_000_000).map(|_| arby::<$t>());
+            let mut problems = if $signed {
+                    signed_problem_values!($t).iter()
+                } else {
+                    unsigned_problem_values!($t).iter()
+                };
+            assert!(problems.all(|p| arbys.any(|arby| arby == *p)),
+                "Arbitrary does not generate all problematic values");
+            let max = <$t>::max_value();
+            let mid = (max + <$t>::min_value()) / 2;
+            // split full range of $t into chunks
+            // Arbitrary must return some value in each chunk
+            let double_chunks: $t = 9;
+            let chunks = double_chunks * 2;  // chunks must be even
+            let lim: Box<dyn Iterator<Item=$t>> = if $signed {
+                Box::new((0..=chunks)
+                        .map(|idx| idx - chunks / 2)
+                        .map(|x| mid + max / (chunks / 2) * x))
+            } else {
+                Box::new((0..=chunks).map(|idx| max / chunks * idx))
+            };
+            let mut lim = lim.peekable();
+            while let (Some(low), Some(&high)) = (lim.next(), lim.peek()) {
+                assert!(arbys.any(|arby| low <= arby && arby <= high),
+                    "Arbitrary doesn't generate numbers in {}..={}", low, high)
+            }
+        )*};
+    }
+
+    #[test]
+    fn arby_int() {
+        arby_int!(true, i8, i16, i32, i64, isize, i128);
+    }
+
+    #[test]
+    fn arby_uint() {
+        arby_int!(false, u8, u16, u32, u64, usize, u128);
+    }
+
+    macro_rules! arby_float {
+        ($($t:ty, $path:path),+) => {$({
+            use $path as p;
+            let mut arbys = (0..1_000_000).map(|_| arby::<$t>());
+            //NaN != NaN
+            assert!(arbys.any(|f| f.is_nan()),
+                "Arbitrary does not generate the problematic value NaN"
+            );
+            for p in float_problem_values!($path).iter().filter(|f| !f.is_nan()) {
+                assert!(arbys.any(|arby| arby == *p),
+                    "Arbitrary does not generate the problematic value {}",
+                    p
+                );
+            }
+            // split full range of $t into chunks
+            // Arbitrary must return some value in each chunk
+            let double_chunks: i8 = 9;
+            let chunks = double_chunks * 2;  // chunks must be even
+            let lim = (-double_chunks..=double_chunks)
+                        .map(|idx| <$t>::from(idx))
+                        .map(|idx| p::MAX/(<$t>::from(chunks/2)) * idx);
+            let mut lim = lim.peekable();
+            while let (Some(low), Some(&high)) = (lim.next(), lim.peek()) {
+                assert!(
+                    arbys.any(|arby| low <= arby && arby <= high),
+                    "Arbitrary doesn't generate numbers in {:e}..={:e}",
+                    low,
+                    high,
+                )
+            }
+        })*};
+    }
+
+    #[test]
+    fn arby_float() {
+        arby_float!(f32, std::f32, f64, std::f64);
+    }
+
+    fn arby<A: Arbitrary>() -> A {
+        Arbitrary::arbitrary(&mut Gen::new(5))
+    }
+
+    // Shrink testing.
+    #[test]
+    fn unit() {
+        eq((), vec![]);
+    }
+
+    #[test]
+    fn bools() {
+        eq(false, vec![]);
+        eq(true, vec![false]);
+    }
+
+    #[test]
+    fn options() {
+        eq(None::<()>, vec![]);
+        eq(Some(false), vec![None]);
+        eq(Some(true), vec![None, Some(false)]);
+    }
+
+    #[test]
+    fn results() {
+        // Result<A, B> doesn't implement the Hash trait, so these tests
+        // depends on the order of shrunk results. Ug.
+        // TODO: Fix this.
+        ordered_eq(Ok::<bool, ()>(true), vec![Ok(false)]);
+        ordered_eq(Err::<(), bool>(true), vec![Err(false)]);
+    }
+
+    #[test]
+    fn tuples() {
+        eq((false, false), vec![]);
+        eq((true, false), vec![(false, false)]);
+        eq((true, true), vec![(false, true), (true, false)]);
+    }
+
+    #[test]
+    fn triples() {
+        eq((false, false, false), vec![]);
+        eq((true, false, false), vec![(false, false, false)]);
+        eq(
+            (true, true, false),
+            vec![(false, true, false), (true, false, false)],
+        );
+    }
+
+    #[test]
+    fn quads() {
+        eq((false, false, false, false), vec![]);
+        eq((true, false, false, false), vec![(false, false, false, false)]);
+        eq(
+            (true, true, false, false),
+            vec![(false, true, false, false), (true, false, false, false)],
+        );
+    }
+
+    #[test]
+    fn ints() {
+        // TODO: Test overflow?
+        eq(5isize, vec![0, 3, 4]);
+        eq(-5isize, vec![5, 0, -3, -4]);
+        eq(0isize, vec![]);
+    }
+
+    #[test]
+    fn ints8() {
+        eq(5i8, vec![0, 3, 4]);
+        eq(-5i8, vec![5, 0, -3, -4]);
+        eq(0i8, vec![]);
+    }
+
+    #[test]
+    fn ints16() {
+        eq(5i16, vec![0, 3, 4]);
+        eq(-5i16, vec![5, 0, -3, -4]);
+        eq(0i16, vec![]);
+    }
+
+    #[test]
+    fn ints32() {
+        eq(5i32, vec![0, 3, 4]);
+        eq(-5i32, vec![5, 0, -3, -4]);
+        eq(0i32, vec![]);
+    }
+
+    #[test]
+    fn ints64() {
+        eq(5i64, vec![0, 3, 4]);
+        eq(-5i64, vec![5, 0, -3, -4]);
+        eq(0i64, vec![]);
+    }
+
+    #[test]
+    fn ints128() {
+        eq(5i128, vec![0, 3, 4]);
+        eq(-5i128, vec![5, 0, -3, -4]);
+        eq(0i128, vec![]);
+    }
+
+    #[test]
+    fn uints() {
+        eq(5usize, vec![0, 3, 4]);
+        eq(0usize, vec![]);
+    }
+
+    #[test]
+    fn uints8() {
+        eq(5u8, vec![0, 3, 4]);
+        eq(0u8, vec![]);
+    }
+
+    #[test]
+    fn uints16() {
+        eq(5u16, vec![0, 3, 4]);
+        eq(0u16, vec![]);
+    }
+
+    #[test]
+    fn uints32() {
+        eq(5u32, vec![0, 3, 4]);
+        eq(0u32, vec![]);
+    }
+
+    #[test]
+    fn uints64() {
+        eq(5u64, vec![0, 3, 4]);
+        eq(0u64, vec![]);
+    }
+
+    #[test]
+    fn uints128() {
+        eq(5u128, vec![0, 3, 4]);
+        eq(0u128, vec![]);
+    }
+
+    macro_rules! define_float_eq {
+        ($ty:ty) => {
+            fn eq(s: $ty, v: Vec<$ty>) {
+                let shrunk: Vec<$ty> = s.shrink().collect();
+                for n in v {
+                    let found = shrunk.iter().any(|&i| i == n);
+                    if !found {
+                        panic!(format!(
+                            "Element {:?} was not found \
+                             in shrink results {:?}",
+                            n, shrunk
+                        ));
+                    }
+                }
+            }
+        };
+    }
+
+    #[test]
+    fn floats32() {
+        define_float_eq!(f32);
+
+        eq(0.0, vec![]);
+        eq(-0.0, vec![]);
+        eq(1.0, vec![0.0]);
+        eq(2.0, vec![0.0, 1.0]);
+        eq(-2.0, vec![0.0, 2.0, -1.0]);
+        eq(1.5, vec![0.0]);
+    }
+
+    #[test]
+    fn floats64() {
+        define_float_eq!(f64);
+
+        eq(0.0, vec![]);
+        eq(-0.0, vec![]);
+        eq(1.0, vec![0.0]);
+        eq(2.0, vec![0.0, 1.0]);
+        eq(-2.0, vec![0.0, 2.0, -1.0]);
+        eq(1.5, vec![0.0]);
+    }
+
+    #[test]
+    fn wrapping_ints32() {
+        eq(Wrapping(5i32), vec![Wrapping(0), Wrapping(3), Wrapping(4)]);
+        eq(
+            Wrapping(-5i32),
+            vec![Wrapping(5), Wrapping(0), Wrapping(-3), Wrapping(-4)],
+        );
+        eq(Wrapping(0i32), vec![]);
+    }
+
+    #[test]
+    fn vecs() {
+        eq(
+            {
+                let it: Vec<isize> = vec![];
+                it
+            },
+            vec![],
+        );
+        eq(
+            {
+                let it: Vec<Vec<isize>> = vec![vec![]];
+                it
+            },
+            vec![vec![]],
+        );
+        eq(vec![1isize], vec![vec![], vec![0]]);
+        eq(vec![11isize], vec![vec![], vec![0], vec![6], vec![9], vec![10]]);
+        eq(
+            vec![3isize, 5],
+            vec![
+                vec![],
+                vec![5],
+                vec![3],
+                vec![0, 5],
+                vec![2, 5],
+                vec![3, 0],
+                vec![3, 3],
+                vec![3, 4],
+            ],
+        );
+    }
+
+    macro_rules! map_tests {
+        ($name:ident, $ctor:expr) => {
+            #[test]
+            fn $name() {
+                ordered_eq($ctor, vec![]);
+
+                {
+                    let mut map = $ctor;
+                    map.insert(1usize, 1isize);
+
+                    let shrinks = vec![
+                        $ctor,
+                        {
+                            let mut m = $ctor;
+                            m.insert(0, 1);
+                            m
+                        },
+                        {
+                            let mut m = $ctor;
+                            m.insert(1, 0);
+                            m
+                        },
+                    ];
+
+                    ordered_eq(map, shrinks);
+                }
+            }
+        };
+    }
+
+    map_tests!(btreemap, BTreeMap::<usize, isize>::new());
+    map_tests!(hashmap, HashMap::<usize, isize>::new());
+
+    macro_rules! list_tests {
+        ($name:ident, $ctor:expr, $push:ident) => {
+            #[test]
+            fn $name() {
+                ordered_eq($ctor, vec![]);
+
+                {
+                    let mut list = $ctor;
+                    list.$push(2usize);
+
+                    let shrinks = vec![
+                        $ctor,
+                        {
+                            let mut m = $ctor;
+                            m.$push(0);
+                            m
+                        },
+                        {
+                            let mut m = $ctor;
+                            m.$push(1);
+                            m
+                        },
+                    ];
+
+                    ordered_eq(list, shrinks);
+                }
+            }
+        };
+    }
+
+    list_tests!(btreesets, BTreeSet::<usize>::new(), insert);
+    list_tests!(hashsets, HashSet::<usize>::new(), insert);
+    list_tests!(linkedlists, LinkedList::<usize>::new(), push_back);
+    list_tests!(vecdeques, VecDeque::<usize>::new(), push_back);
+
+    #[test]
+    fn binaryheaps() {
+        ordered_eq(
+            BinaryHeap::<usize>::new().into_iter().collect::<Vec<_>>(),
+            vec![],
+        );
+
+        {
+            let mut heap = BinaryHeap::<usize>::new();
+            heap.push(2usize);
+
+            let shrinks = vec![vec![], vec![0], vec![1]];
+
+            ordered_eq(heap.into_iter().collect::<Vec<_>>(), shrinks);
+        }
+    }
+
+    #[test]
+    fn chars() {
+        eq('\x00', vec![]);
+    }
+
+    // All this jazz is for testing set equality on the results of a shrinker.
+    fn eq<A: Arbitrary + Eq + Debug + Hash>(s: A, v: Vec<A>) {
+        let (left, right) = (shrunk(s), set(v));
+        assert_eq!(left, right);
+    }
+    fn shrunk<A: Arbitrary + Eq + Hash>(s: A) -> HashSet<A> {
+        set(s.shrink())
+    }
+    fn set<A: Hash + Eq, I: IntoIterator<Item = A>>(xs: I) -> HashSet<A> {
+        xs.into_iter().collect()
+    }
+
+    fn ordered_eq<A: Arbitrary + Eq + Debug>(s: A, v: Vec<A>) {
+        let (left, right) = (s.shrink().collect::<Vec<A>>(), v);
+        assert_eq!(left, right);
+    }
+
+    #[test]
+    fn bounds() {
+        use std::ops::Bound::*;
+        for i in -5..=5 {
+            ordered_eq(Included(i), i.shrink().map(Included).collect());
+            ordered_eq(Excluded(i), i.shrink().map(Excluded).collect());
+        }
+        eq(Unbounded::<i32>, vec![]);
+    }
+
+    #[test]
+    fn ranges() {
+        ordered_eq(0..0, vec![]);
+        ordered_eq(1..1, vec![0..1, 1..0]);
+        ordered_eq(3..5, vec![0..5, 2..5, 3..0, 3..3, 3..4]);
+        ordered_eq(5..3, vec![0..3, 3..3, 4..3, 5..0, 5..2]);
+        ordered_eq(3.., vec![0.., 2..]);
+        ordered_eq(..3, vec![..0, ..2]);
+        ordered_eq(.., vec![]);
+        ordered_eq(3..=5, vec![0..=5, 2..=5, 3..=0, 3..=3, 3..=4]);
+        ordered_eq(..=3, vec![..=0, ..=2]);
+    }
+
+    #[test]
+    fn pathbuf() {
+        ordered_eq(
+            PathBuf::from("/home/foo//.././bar"),
+            vec![
+                PathBuf::from("/home/foo//.."),
+                PathBuf::from("/home/foo/../bar"),
+            ],
+        );
+    }
+}
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..58dc99d
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,93 @@
+/*!
+This crate is a port of
+[Haskell's QuickCheck](https://hackage.haskell.org/package/QuickCheck).
+
+For detailed examples, please see the
+[README](https://github.com/BurntSushi/quickcheck).
+
+# Compatibility
+
+In general, this crate considers the `Arbitrary` implementations provided as
+implementation details. Strategies may or may not change over time, which may
+cause new test failures, presumably due to the discovery of new bugs due to a
+new kind of witness being generated. These sorts of changes may happen in
+semver compatible releases.
+*/
+
+pub use crate::arbitrary::{empty_shrinker, single_shrinker, Arbitrary, Gen};
+pub use crate::tester::{quickcheck, QuickCheck, TestResult, Testable};
+
+/// A macro for writing quickcheck tests.
+///
+/// This macro takes as input one or more property functions to test, and
+/// produces a proper `#[test]` function for each property. If the property
+/// fails, the behavior is as if `quickcheck` were called on the property
+/// (i.e., it panics and fails the test).
+///
+/// Note that this macro doesn't support `mut` or patterns in parameters.
+///
+/// # Example
+///
+/// ```rust
+/// # #[macro_use] extern crate quickcheck; fn main() {
+/// quickcheck! {
+///     fn prop_reverse_reverse(xs: Vec<usize>) -> bool {
+///         let rev: Vec<_> = xs.clone().into_iter().rev().collect();
+///         let revrev: Vec<_> = rev.into_iter().rev().collect();
+///         xs == revrev
+///     }
+/// };
+/// # }
+/// ```
+#[macro_export]
+macro_rules! quickcheck {
+    (@as_items $($i:item)*) => ($($i)*);
+    {
+        $(
+            $(#[$m:meta])*
+            fn $fn_name:ident($($arg_name:ident : $arg_ty:ty),*) -> $ret:ty {
+                $($code:tt)*
+            }
+        )*
+    } => (
+        $crate::quickcheck! {
+            @as_items
+            $(
+                #[test]
+                $(#[$m])*
+                fn $fn_name() {
+                    fn prop($($arg_name: $arg_ty),*) -> $ret {
+                        $($code)*
+                    }
+                    $crate::quickcheck(prop as fn($($arg_ty),*) -> $ret);
+                }
+            )*
+        }
+    )
+}
+
+#[cfg(feature = "use_logging")]
+fn env_logger_init() -> Result<(), log::SetLoggerError> {
+    env_logger::try_init()
+}
+#[cfg(feature = "use_logging")]
+macro_rules! info {
+    ($($tt:tt)*) => {
+        log::info!($($tt)*)
+    };
+}
+
+#[cfg(not(feature = "use_logging"))]
+fn env_logger_init() {}
+#[cfg(not(feature = "use_logging"))]
+macro_rules! info {
+    ($($_ignore:tt)*) => {
+        ()
+    };
+}
+
+mod arbitrary;
+mod tester;
+
+#[cfg(test)]
+mod tests;
diff --git a/src/tester.rs b/src/tester.rs
new file mode 100644
index 0000000..e2eaa20
--- /dev/null
+++ b/src/tester.rs
@@ -0,0 +1,451 @@
+use std::cmp;
+use std::env;
+use std::fmt::Debug;
+use std::panic;
+
+use crate::{
+    tester::Status::{Discard, Fail, Pass},
+    Arbitrary, Gen,
+};
+
+/// The main QuickCheck type for setting configuration and running QuickCheck.
+pub struct QuickCheck {
+    tests: u64,
+    max_tests: u64,
+    min_tests_passed: u64,
+    gen: Gen,
+}
+
+fn qc_tests() -> u64 {
+    let default = 100;
+    match env::var("QUICKCHECK_TESTS") {
+        Ok(val) => val.parse().unwrap_or(default),
+        Err(_) => default,
+    }
+}
+
+fn qc_max_tests() -> u64 {
+    let default = 10_000;
+    match env::var("QUICKCHECK_MAX_TESTS") {
+        Ok(val) => val.parse().unwrap_or(default),
+        Err(_) => default,
+    }
+}
+
+fn qc_gen_size() -> usize {
+    let default = 100;
+    match env::var("QUICKCHECK_GENERATOR_SIZE") {
+        Ok(val) => val.parse().unwrap_or(default),
+        Err(_) => default,
+    }
+}
+
+fn qc_min_tests_passed() -> u64 {
+    let default = 0;
+    match env::var("QUICKCHECK_MIN_TESTS_PASSED") {
+        Ok(val) => val.parse().unwrap_or(default),
+        Err(_) => default,
+    }
+}
+
+impl QuickCheck {
+    /// Creates a new QuickCheck value.
+    ///
+    /// This can be used to run QuickCheck on things that implement `Testable`.
+    /// You may also adjust the configuration, such as the number of tests to
+    /// run.
+    ///
+    /// By default, the maximum number of passed tests is set to `100`, the max
+    /// number of overall tests is set to `10000` and the generator is created
+    /// with a size of `100`.
+    pub fn new() -> QuickCheck {
+        let gen = Gen::new(qc_gen_size());
+        let tests = qc_tests();
+        let max_tests = cmp::max(tests, qc_max_tests());
+        let min_tests_passed = qc_min_tests_passed();
+
+        QuickCheck { tests, max_tests, min_tests_passed, gen }
+    }
+
+    /// Set the random number generator to be used by QuickCheck.
+    pub fn gen(self, gen: Gen) -> QuickCheck {
+        QuickCheck { gen, ..self }
+    }
+
+    /// Set the number of tests to run.
+    ///
+    /// This actually refers to the maximum number of *passed* tests that
+    /// can occur. Namely, if a test causes a failure, future testing on that
+    /// property stops. Additionally, if tests are discarded, there may be
+    /// fewer than `tests` passed.
+    pub fn tests(mut self, tests: u64) -> QuickCheck {
+        self.tests = tests;
+        self
+    }
+
+    /// Set the maximum number of tests to run.
+    ///
+    /// The number of invocations of a property will never exceed this number.
+    /// This is necessary to cap the number of tests because QuickCheck
+    /// properties can discard tests.
+    pub fn max_tests(mut self, max_tests: u64) -> QuickCheck {
+        self.max_tests = max_tests;
+        self
+    }
+
+    /// Set the minimum number of tests that needs to pass.
+    ///
+    /// This actually refers to the minimum number of *valid* *passed* tests
+    /// that needs to pass for the property to be considered successful.
+    pub fn min_tests_passed(mut self, min_tests_passed: u64) -> QuickCheck {
+        self.min_tests_passed = min_tests_passed;
+        self
+    }
+
+    /// Tests a property and returns the result.
+    ///
+    /// The result returned is either the number of tests passed or a witness
+    /// of failure.
+    ///
+    /// (If you're using Rust's unit testing infrastructure, then you'll
+    /// want to use the `quickcheck` method, which will `panic!` on failure.)
+    pub fn quicktest<A>(&mut self, f: A) -> Result<u64, TestResult>
+    where
+        A: Testable,
+    {
+        let mut n_tests_passed = 0;
+        for _ in 0..self.max_tests {
+            if n_tests_passed >= self.tests {
+                break;
+            }
+            match f.result(&mut self.gen) {
+                TestResult { status: Pass, .. } => n_tests_passed += 1,
+                TestResult { status: Discard, .. } => continue,
+                r @ TestResult { status: Fail, .. } => return Err(r),
+            }
+        }
+        Ok(n_tests_passed)
+    }
+
+    /// Tests a property and calls `panic!` on failure.
+    ///
+    /// The `panic!` message will include a (hopefully) minimal witness of
+    /// failure.
+    ///
+    /// It is appropriate to use this method with Rust's unit testing
+    /// infrastructure.
+    ///
+    /// Note that if the environment variable `RUST_LOG` is set to enable
+    /// `info` level log messages for the `quickcheck` crate, then this will
+    /// include output on how many QuickCheck tests were passed.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use quickcheck::QuickCheck;
+    ///
+    /// fn prop_reverse_reverse() {
+    ///     fn revrev(xs: Vec<usize>) -> bool {
+    ///         let rev: Vec<_> = xs.clone().into_iter().rev().collect();
+    ///         let revrev: Vec<_> = rev.into_iter().rev().collect();
+    ///         xs == revrev
+    ///     }
+    ///     QuickCheck::new().quickcheck(revrev as fn(Vec<usize>) -> bool);
+    /// }
+    /// ```
+    pub fn quickcheck<A>(&mut self, f: A)
+    where
+        A: Testable,
+    {
+        // Ignore log init failures, implying it has already been done.
+        let _ = crate::env_logger_init();
+
+        let n_tests_passed = match self.quicktest(f) {
+            Ok(n_tests_passed) => n_tests_passed,
+            Err(result) => panic!(result.failed_msg()),
+        };
+
+        if n_tests_passed >= self.min_tests_passed {
+            info!("(Passed {} QuickCheck tests.)", n_tests_passed)
+        } else {
+            panic!(
+                "(Unable to generate enough tests, {} not discarded.)",
+                n_tests_passed
+            )
+        }
+    }
+}
+
+/// Convenience function for running QuickCheck.
+///
+/// This is an alias for `QuickCheck::new().quickcheck(f)`.
+pub fn quickcheck<A: Testable>(f: A) {
+    QuickCheck::new().quickcheck(f)
+}
+
+/// Describes the status of a single instance of a test.
+///
+/// All testable things must be capable of producing a `TestResult`.
+#[derive(Clone, Debug)]
+pub struct TestResult {
+    status: Status,
+    arguments: Vec<String>,
+    err: Option<String>,
+}
+
+/// Whether a test has passed, failed or been discarded.
+#[derive(Clone, Debug)]
+enum Status {
+    Pass,
+    Fail,
+    Discard,
+}
+
+impl TestResult {
+    /// Produces a test result that indicates the current test has passed.
+    pub fn passed() -> TestResult {
+        TestResult::from_bool(true)
+    }
+
+    /// Produces a test result that indicates the current test has failed.
+    pub fn failed() -> TestResult {
+        TestResult::from_bool(false)
+    }
+
+    /// Produces a test result that indicates failure from a runtime error.
+    pub fn error<S: Into<String>>(msg: S) -> TestResult {
+        let mut r = TestResult::from_bool(false);
+        r.err = Some(msg.into());
+        r
+    }
+
+    /// Produces a test result that instructs `quickcheck` to ignore it.
+    /// This is useful for restricting the domain of your properties.
+    /// When a test is discarded, `quickcheck` will replace it with a
+    /// fresh one (up to a certain limit).
+    pub fn discard() -> TestResult {
+        TestResult { status: Discard, arguments: vec![], err: None }
+    }
+
+    /// Converts a `bool` to a `TestResult`. A `true` value indicates that
+    /// the test has passed and a `false` value indicates that the test
+    /// has failed.
+    pub fn from_bool(b: bool) -> TestResult {
+        TestResult {
+            status: if b { Pass } else { Fail },
+            arguments: vec![],
+            err: None,
+        }
+    }
+
+    /// Tests if a "procedure" fails when executed. The test passes only if
+    /// `f` generates a task failure during its execution.
+    pub fn must_fail<T, F>(f: F) -> TestResult
+    where
+        F: FnOnce() -> T,
+        F: 'static,
+        T: 'static,
+    {
+        let f = panic::AssertUnwindSafe(f);
+        TestResult::from_bool(panic::catch_unwind(f).is_err())
+    }
+
+    /// Returns `true` if and only if this test result describes a failing
+    /// test.
+    pub fn is_failure(&self) -> bool {
+        match self.status {
+            Fail => true,
+            Pass | Discard => false,
+        }
+    }
+
+    /// Returns `true` if and only if this test result describes a failing
+    /// test as a result of a run time error.
+    pub fn is_error(&self) -> bool {
+        self.is_failure() && self.err.is_some()
+    }
+
+    fn failed_msg(&self) -> String {
+        match self.err {
+            None => format!(
+                "[quickcheck] TEST FAILED. Arguments: ({})",
+                self.arguments.join(", ")
+            ),
+            Some(ref err) => format!(
+                "[quickcheck] TEST FAILED (runtime error). \
+                 Arguments: ({})\nError: {}",
+                self.arguments.join(", "),
+                err
+            ),
+        }
+    }
+}
+
+/// `Testable` describes types (e.g., a function) whose values can be
+/// tested.
+///
+/// Anything that can be tested must be capable of producing a `TestResult`
+/// given a random number generator. This is trivial for types like `bool`,
+/// which are just converted to either a passing or failing test result.
+///
+/// For functions, an implementation must generate random arguments
+/// and potentially shrink those arguments if they produce a failure.
+///
+/// It's unlikely that you'll have to implement this trait yourself.
+pub trait Testable: 'static {
+    fn result(&self, _: &mut Gen) -> TestResult;
+}
+
+impl Testable for bool {
+    fn result(&self, _: &mut Gen) -> TestResult {
+        TestResult::from_bool(*self)
+    }
+}
+
+impl Testable for () {
+    fn result(&self, _: &mut Gen) -> TestResult {
+        TestResult::passed()
+    }
+}
+
+impl Testable for TestResult {
+    fn result(&self, _: &mut Gen) -> TestResult {
+        self.clone()
+    }
+}
+
+impl<A, E> Testable for Result<A, E>
+where
+    A: Testable,
+    E: Debug + 'static,
+{
+    fn result(&self, g: &mut Gen) -> TestResult {
+        match *self {
+            Ok(ref r) => r.result(g),
+            Err(ref err) => TestResult::error(format!("{:?}", err)),
+        }
+    }
+}
+
+/// Return a vector of the debug formatting of each item in `args`
+fn debug_reprs(args: &[&dyn Debug]) -> Vec<String> {
+    args.iter().map(|x| format!("{:?}", x)).collect()
+}
+
+macro_rules! testable_fn {
+    ($($name: ident),*) => {
+
+impl<T: Testable,
+     $($name: Arbitrary + Debug),*> Testable for fn($($name),*) -> T {
+    #[allow(non_snake_case)]
+    fn result(&self, g: &mut Gen) -> TestResult {
+        fn shrink_failure<T: Testable, $($name: Arbitrary + Debug),*>(
+            g: &mut Gen,
+            self_: fn($($name),*) -> T,
+            a: ($($name,)*),
+        ) -> Option<TestResult> {
+            for t in a.shrink() {
+                let ($($name,)*) = t.clone();
+                let mut r_new = safe(move || {self_($($name),*)}).result(g);
+                if r_new.is_failure() {
+                    {
+                        let ($(ref $name,)*) : ($($name,)*) = t;
+                        r_new.arguments = debug_reprs(&[$($name),*]);
+                    }
+
+                    // The shrunk value *does* witness a failure, so keep
+                    // trying to shrink it.
+                    let shrunk = shrink_failure(g, self_, t);
+
+                    // If we couldn't witness a failure on any shrunk value,
+                    // then return the failure we already have.
+                    return Some(shrunk.unwrap_or(r_new))
+                }
+            }
+            None
+        }
+
+        let self_ = *self;
+        let a: ($($name,)*) = Arbitrary::arbitrary(g);
+        let ( $($name,)* ) = a.clone();
+        let mut r = safe(move || {self_($($name),*)}).result(g);
+
+        {
+            let ( $(ref $name,)* ) = a;
+            r.arguments = debug_reprs(&[$($name),*]);
+        }
+        match r.status {
+            Pass|Discard => r,
+            Fail => {
+                shrink_failure(g, self_, a).unwrap_or(r)
+            }
+        }
+    }
+}}}
+
+testable_fn!();
+testable_fn!(A);
+testable_fn!(A, B);
+testable_fn!(A, B, C);
+testable_fn!(A, B, C, D);
+testable_fn!(A, B, C, D, E);
+testable_fn!(A, B, C, D, E, F);
+testable_fn!(A, B, C, D, E, F, G);
+testable_fn!(A, B, C, D, E, F, G, H);
+
+fn safe<T, F>(fun: F) -> Result<T, String>
+where
+    F: FnOnce() -> T,
+    F: 'static,
+    T: 'static,
+{
+    panic::catch_unwind(panic::AssertUnwindSafe(fun)).map_err(|any_err| {
+        // Extract common types of panic payload:
+        // panic and assert produce &str or String
+        if let Some(&s) = any_err.downcast_ref::<&str>() {
+            s.to_owned()
+        } else if let Some(s) = any_err.downcast_ref::<String>() {
+            s.to_owned()
+        } else {
+            "UNABLE TO SHOW RESULT OF PANIC.".to_owned()
+        }
+    })
+}
+
+/// Convenient aliases.
+trait AShow: Arbitrary + Debug {}
+impl<A: Arbitrary + Debug> AShow for A {}
+
+#[cfg(test)]
+mod test {
+    use crate::{Gen, QuickCheck};
+
+    #[test]
+    fn shrinking_regression_issue_126() {
+        fn thetest(vals: Vec<bool>) -> bool {
+            vals.iter().filter(|&v| *v).count() < 2
+        }
+        let failing_case = QuickCheck::new()
+            .quicktest(thetest as fn(vals: Vec<bool>) -> bool)
+            .unwrap_err();
+        let expected_argument = format!("{:?}", [true, true]);
+        assert_eq!(failing_case.arguments, vec![expected_argument]);
+    }
+
+    #[test]
+    fn size_for_small_types_issue_143() {
+        fn t(_: i8) -> bool {
+            true
+        }
+        QuickCheck::new().gen(Gen::new(129)).quickcheck(t as fn(i8) -> bool);
+    }
+
+    #[test]
+    fn regression_signed_shrinker_panic() {
+        fn foo_can_shrink(v: i8) -> bool {
+            let _ = crate::Arbitrary::shrink(&v).take(100).count();
+            true
+        }
+        crate::quickcheck(foo_can_shrink as fn(i8) -> bool);
+    }
+}
diff --git a/src/tests.rs b/src/tests.rs
new file mode 100644
index 0000000..465ef15
--- /dev/null
+++ b/src/tests.rs
@@ -0,0 +1,288 @@
+use std::cmp::Ord;
+use std::collections::hash_map::DefaultHasher;
+use std::collections::{HashMap, HashSet};
+use std::ffi::CString;
+use std::hash::BuildHasherDefault;
+use std::path::PathBuf;
+
+use super::{quickcheck, Gen, QuickCheck, TestResult};
+
+#[test]
+fn prop_oob() {
+    fn prop() -> bool {
+        let zero: Vec<bool> = vec![];
+        zero[0]
+    }
+    match QuickCheck::new().quicktest(prop as fn() -> bool) {
+        Ok(n) => panic!(
+            "prop_oob should fail with a runtime error \
+             but instead it passed {} tests.",
+            n
+        ),
+        _ => return,
+    }
+}
+
+#[test]
+fn prop_reverse_reverse() {
+    fn prop(xs: Vec<usize>) -> bool {
+        let rev: Vec<_> = xs.clone().into_iter().rev().collect();
+        let revrev: Vec<_> = rev.into_iter().rev().collect();
+        xs == revrev
+    }
+    quickcheck(prop as fn(Vec<usize>) -> bool);
+}
+
+quickcheck! {
+    fn prop_reverse_reverse_macro(xs: Vec<usize>) -> bool {
+        let rev: Vec<_> = xs.clone().into_iter().rev().collect();
+        let revrev: Vec<_> = rev.into_iter().rev().collect();
+        xs == revrev
+    }
+
+    #[should_panic]
+    fn prop_macro_panic(_x: u32) -> bool {
+        assert!(false);
+        false
+    }
+}
+
+#[test]
+fn reverse_single() {
+    fn prop(xs: Vec<usize>) -> TestResult {
+        if xs.len() != 1 {
+            TestResult::discard()
+        } else {
+            TestResult::from_bool(
+                xs == xs.clone().into_iter().rev().collect::<Vec<_>>(),
+            )
+        }
+    }
+    quickcheck(prop as fn(Vec<usize>) -> TestResult);
+}
+
+#[test]
+fn reverse_app() {
+    fn prop(xs: Vec<usize>, ys: Vec<usize>) -> bool {
+        let mut app = xs.clone();
+        app.extend(ys.iter().cloned());
+        let app_rev: Vec<usize> = app.into_iter().rev().collect();
+
+        let rxs: Vec<usize> = xs.into_iter().rev().collect();
+        let mut rev_app = ys.into_iter().rev().collect::<Vec<usize>>();
+        rev_app.extend(rxs.into_iter());
+
+        app_rev == rev_app
+    }
+    quickcheck(prop as fn(Vec<usize>, Vec<usize>) -> bool);
+}
+
+#[test]
+fn max() {
+    fn prop(x: isize, y: isize) -> TestResult {
+        if x > y {
+            TestResult::discard()
+        } else {
+            TestResult::from_bool(::std::cmp::max(x, y) == y)
+        }
+    }
+    quickcheck(prop as fn(isize, isize) -> TestResult);
+}
+
+#[test]
+fn sort() {
+    fn prop(mut xs: Vec<isize>) -> bool {
+        xs.sort_by(|x, y| x.cmp(y));
+        for i in xs.windows(2) {
+            if i[0] > i[1] {
+                return false;
+            }
+        }
+        true
+    }
+    quickcheck(prop as fn(Vec<isize>) -> bool);
+}
+
+fn sieve(n: usize) -> Vec<usize> {
+    if n <= 1 {
+        return vec![];
+    }
+
+    let mut marked = vec![false; n + 1];
+    marked[0] = true;
+    marked[1] = true;
+    marked[2] = true;
+    for p in 2..n {
+        for i in (2 * p..n).filter(|&n| n % p == 0) {
+            marked[i] = true;
+        }
+    }
+    marked
+        .iter()
+        .enumerate()
+        .filter_map(|(i, &m)| if m { None } else { Some(i) })
+        .collect()
+}
+
+fn is_prime(n: usize) -> bool {
+    n != 0 && n != 1 && (2..).take_while(|i| i * i <= n).all(|i| n % i != 0)
+}
+
+#[test]
+#[should_panic]
+fn sieve_not_prime() {
+    fn prop_all_prime(n: u8) -> bool {
+        sieve(n as usize).into_iter().all(is_prime)
+    }
+    quickcheck(prop_all_prime as fn(u8) -> bool);
+}
+
+#[test]
+#[should_panic]
+fn sieve_not_all_primes() {
+    fn prop_prime_iff_in_the_sieve(n: u8) -> bool {
+        let n = n as usize;
+        sieve(n) == (0..(n + 1)).filter(|&i| is_prime(i)).collect::<Vec<_>>()
+    }
+    quickcheck(prop_prime_iff_in_the_sieve as fn(u8) -> bool);
+}
+
+#[test]
+fn testable_result() {
+    fn result() -> Result<bool, String> {
+        Ok(true)
+    }
+    quickcheck(result as fn() -> Result<bool, String>);
+}
+
+#[test]
+#[should_panic]
+fn testable_result_err() {
+    quickcheck(Err::<bool, i32> as fn(i32) -> Result<bool, i32>);
+}
+
+#[test]
+fn testable_unit() {
+    fn do_nothing() {}
+    quickcheck(do_nothing as fn());
+}
+
+#[test]
+fn testable_unit_panic() {
+    fn panic() {
+        panic!()
+    }
+    assert!(QuickCheck::new().quicktest(panic as fn()).is_err());
+}
+
+#[test]
+fn regression_issue_83() {
+    fn prop(_: u8) -> bool {
+        true
+    }
+    QuickCheck::new().gen(Gen::new(1024)).quickcheck(prop as fn(u8) -> bool)
+}
+
+#[test]
+fn regression_issue_83_signed() {
+    fn prop(_: i8) -> bool {
+        true
+    }
+    QuickCheck::new().gen(Gen::new(1024)).quickcheck(prop as fn(i8) -> bool)
+}
+
+// Test that we can show the message after panic
+#[test]
+#[should_panic(expected = "foo")]
+fn panic_msg_1() {
+    fn prop() -> bool {
+        panic!("foo");
+    }
+    quickcheck(prop as fn() -> bool);
+}
+
+#[test]
+#[should_panic(expected = "foo")]
+fn panic_msg_2() {
+    fn prop() -> bool {
+        assert!("foo" == "bar");
+        true
+    }
+    quickcheck(prop as fn() -> bool);
+}
+
+#[test]
+#[should_panic(expected = "foo")]
+fn panic_msg_3() {
+    fn prop() -> bool {
+        assert_eq!("foo", "bar");
+        true
+    }
+    quickcheck(prop as fn() -> bool);
+}
+
+#[test]
+#[should_panic]
+fn regression_issue_107_hang() {
+    fn prop(a: Vec<u8>) -> bool {
+        a.contains(&1)
+    }
+    quickcheck(prop as fn(_) -> bool);
+}
+
+#[test]
+#[should_panic(
+    expected = "(Unable to generate enough tests, 0 not discarded.)"
+)]
+fn all_tests_discarded_min_tests_passed_set() {
+    fn prop_discarded(_: u8) -> TestResult {
+        TestResult::discard()
+    }
+
+    QuickCheck::new()
+        .tests(16)
+        .min_tests_passed(8)
+        .quickcheck(prop_discarded as fn(u8) -> TestResult)
+}
+
+#[test]
+fn all_tests_discarded_min_tests_passed_missing() {
+    fn prop_discarded(_: u8) -> TestResult {
+        TestResult::discard()
+    }
+
+    QuickCheck::new().quickcheck(prop_discarded as fn(u8) -> TestResult)
+}
+
+quickcheck! {
+    /// The following is a very simplistic test, which only verifies
+    /// that our PathBuf::arbitrary does not panic.  Still, that's
+    /// something!  :)
+    fn pathbuf(_p: PathBuf) -> bool {
+        true
+    }
+
+    fn basic_hashset(_set: HashSet<u8>) -> bool {
+        true
+    }
+
+    fn basic_hashmap(_map: HashMap<u8, u8>) -> bool {
+        true
+    }
+
+    fn substitute_hashset(
+        _set: HashSet<u8, BuildHasherDefault<DefaultHasher>>
+    ) -> bool {
+        true
+    }
+
+    fn substitute_hashmap(
+        _map: HashMap<u8, u8, BuildHasherDefault<DefaultHasher>>
+    ) -> bool {
+        true
+    }
+
+    fn cstring(_p: CString) -> bool {
+        true
+    }
+}
