diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
new file mode 100644
index 0000000..ca20d51
--- /dev/null
+++ b/.cargo_vcs_info.json
@@ -0,0 +1,5 @@
+{
+  "git": {
+    "sha1": "b085c523681146151866ead66ae8a4b8967fd005"
+  }
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..96ef6c0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/target
+Cargo.lock
diff --git a/.rustfmt.toml b/.rustfmt.toml
new file mode 100644
index 0000000..06eb57a
--- /dev/null
+++ b/.rustfmt.toml
@@ -0,0 +1,3 @@
+# Temporarily disable rustfmt completely to avoid conflicts of newly formatted
+# code with old PRs.
+ignore = ["/"]
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..8c4a598
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,20 @@
+language: rust
+sudo: false
+matrix:
+  include:
+    - rust: 1.32.0
+    - rust: stable
+    - rust: beta
+    - rust: nightly
+branches:
+  only:
+    - master
+    # bors branches
+    - staging
+    - trying
+script:
+  - |
+      cargo build --verbose --no-default-features &&
+      cargo build --verbose --features "$FEATURES" &&
+      cargo test --verbose --features "$FEATURES" &&
+      cargo bench --verbose --features "$FEATURES"
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..67633ab
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,319 @@
+# Changelog
+
+## 0.9.0
+  - Fix potential overflow in `MergeJoinBy::size_hint` (#385)
+  - Add `derive(Clone)` where possible (#382)
+  - Add `try_collect` method (#394)
+  - Add `HomogeneousTuple` trait (#389)
+  - Fix `combinations(0)` and `combinations_with_replacement(0)` (#383)
+  - Don't require `ParitalEq` to the `Item` of `DedupBy` (#397)
+  - Implement missing specializations on the `PutBack` adaptor and on the `MergeJoinBy` iterator (#372)
+  - Add `position_*` methods (#412)
+  - Derive `Hash` for `EitherOrBoth` (#417)
+  - Increase minimum supported Rust version to 1.32.0
+
+## 0.8.2
+  - Use `slice::iter` instead of `into_iter` to avoid future breakage (#378, by @LukasKalbertodt)
+## 0.8.1
+  - Added a [`.exactly_one()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.exactly_one) iterator method that, on success, extracts the single value of an iterator ; by @Xaeroxe
+  - Added combinatory iterator adaptors:
+    - [`.permutations(k)`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.permutations):
+
+      `[0, 1, 2].iter().permutations(2)` yields
+
+      ```rust
+      [
+        vec![0, 1],
+        vec![0, 2],
+        vec![1, 0],
+        vec![1, 2],
+        vec![2, 0],
+        vec![2, 1],
+      ]
+      ```
+
+      ; by @tobz1000
+
+    - [`.combinations_with_replacement(k)`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.combinations_with_replacement):
+
+      `[0, 1, 2].iter().combinations_with_replacement(2)` yields
+
+      ```rust
+      [
+        vec![0, 0],
+        vec![0, 1],
+        vec![0, 2],
+        vec![1, 1],
+        vec![1, 2],
+        vec![2, 2],
+      ]
+      ```
+
+      ; by @tommilligan
+
+    - For reference, these methods join the already existing [`.combinations(k)`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.combinations):
+
+      `[0, 1, 2].iter().combinations(2)` yields
+
+      ```rust
+      [
+        vec![0, 1],
+        vec![0, 2],
+        vec![1, 2],
+      ]
+      ```
+
+  - Improved the performance of [`.fold()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.fold)-based internal iteration for the [`.intersperse()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.intersperse) iterator ; by @jswrenn
+  - Added [`.dedup_by()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.dedup_by), [`.merge_by()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.merge_by) and [`.kmerge_by()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.kmerge_by) adaptors that work like [`.dedup()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.dedup), [`.merge()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.merge) and [`.kmerge()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.kmerge), but taking an additional custom comparison closure parameter. ; by @phimuemue
+  - Improved the performance of [`.all_equal()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.all_equal) ; by @fyrchik
+  - Loosened the bounds on [`.partition_map()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.partition_map) to take just a `FnMut` closure rather than a `Fn` closure, and made its implementation use internal iteration for better performance ; by @danielhenrymantilla
+  - Added convenience methods to [`EitherOrBoth`](https://docs.rs/itertools/0.8.1/itertools/enum.EitherOrBoth.html) elements yielded from the [`.zip_longest()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.zip_longest) iterator adaptor ; by @Avi-D-coder
+  - Added [`.sum1()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.sum1) and [`.product1()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.product1) iterator methods that respectively try to return the sum and the product of the elements of an iterator **when it is not empty**, otherwise they return `None` ; by @Emerentius
+## 0.8.0
+  - Added new adaptor `.map_into()` for conversions using `Into` by @vorner
+  - Improved `Itertools` docs by @JohnHeitmann
+  - The return type of `.sorted_by_by_key()` is now an iterator, not a Vec.
+  - The return type of the `izip!(x, y)` macro with exactly two arguments is now the usual `Iterator::zip`.
+  - Remove `.flatten()` in favour of std's `.flatten()`
+  - Deprecate `.foreach()` in favour of std's `.for_each()`
+  - Deprecate `.step()` in favour of std's `.step_by()`
+  - Deprecate `repeat_call` in favour of std's `repeat_with`
+  - Deprecate `.fold_while()` in favour of std's `.try_fold()`
+  - Require Rust 1.24 as minimal version.
+## 0.7.11
+  - Add convenience methods to `EitherOrBoth`, making it more similar to `Option` and `Either` by @jethrogb
+## 0.7.10
+  - No changes.
+## 0.7.9
+  - New inclusion policy: See the readme about suggesting features for std before accepting them in itertools.
+  - The `FoldWhile` type now implements `Eq` and `PartialEq` by @jturner314
+## 0.7.8
+  - Add new iterator method `.tree_fold1()` which is like `.fold1()` except items are combined in a tree structure (see its docs). By @scottmcm
+  - Add more `Debug` impls by @phimuemue: KMerge, KMergeBy, MergeJoinBy, ConsTuples, Intersperse, ProcessResults, RcIter, Tee, TupleWindows, Tee, ZipLongest, ZipEq, Zip.
+## 0.7.7
+  - Add new iterator method `.into_group_map() -> HashMap<K, Vec<V>>` which turns an iterator of `(K, V)` elements into such a hash table, where values are grouped by key. By @tobz1000
+  - Add new free function `flatten` for the `.flatten()` adaptor. **NOTE:** recent Rust nightlies have `Iterator::flatten` and thus a clash with our flatten adaptor. One workaround is to use the itertools `flatten` free function.
+## 0.7.6
+  - Add new adaptor `.multi_cartesian_product()` which is an n-ary product iterator by @tobz1000
+  - Add new method `.sorted_by_key()` by @Xion
+  - Provide simpler and faster `.count()` for `.unique()` and `.unique_by()`
+## 0.7.5
+  - `.multipeek()` now implements `PeekingNext`, by @nicopap.
+## 0.7.4
+  - Add new adaptor `.update()` by @lucasem; this adaptor is used to modify an element before passing it on in an iterator chain.
+## 0.7.3
+  - Add new method `.collect_tuple()` by @matklad; it makes a tuple out of the iterator's elements if the number of them matches **exactly**.
+  - Implement `fold` and `collect` for `.map_results()` which means it reuses the code of the standard `.map()` for these methods.
+## 0.7.2
+  - Add new adaptor `.merge_join_by` by @srijs; a heterogeneous merge join for two ordered sequences.
+## 0.7.1
+  - Iterator adaptors and iterators in itertools now use the same `must_use` reminder that the standard library adaptors do, by @matematikaedit and @bluss *“iterator adaptors are lazy and do nothing unless consumed”*.
+## 0.7.0
+  - Faster `izip!()` by @krdln
+    - `izip!()` is now a wrapper for repeated regular `.zip()` and a single `.map()`. This means it optimizes as well as the standard library `.zip()` it uses. **Note:** `multizip` and `izip!()` are now different! The former has a named type but the latter optimizes better.
+  - Faster `.unique()`
+  - `no_std` support, which is opt-in!
+    - Many lovable features are still there without std, like `izip!()` or `.format()` or `.merge()`, but not those that use collections.
+  - Trait bounds were required up front instead of just on the type: `group_by`'s `PartialEq` by @Phlosioneer and `repeat_call`'s `FnMut`.
+  - Removed deprecated constructor `Zip::new` — use `izip!()` or `multizip()`
+## 0.6.5
+  - Fix bug in `.cartesian_product()`'s fold (which only was visible for unfused iterators).
+## 0.6.4
+  - Add specific `fold` implementations for `.cartesian_product()` and `cons_tuples()`, which improves their performance in fold, foreach, and iterator consumers derived from them.
+## 0.6.3
+  - Add iterator adaptor `.positions(predicate)` by @tmccombs
+## 0.6.2
+  - Add function `process_results` which can “lift” a function of the regular values of an iterator so that it can process the `Ok` values from an iterator of `Results` instead, by @shepmaster
+  - Add iterator method `.concat()` which combines all iterator elements into a single collection using the `Extend` trait, by @srijs
+## 0.6.1
+  - Better size hint testing and subsequent size hint bugfixes by @rkarp. Fixes bugs in product, `interleave_shortest` size hints.
+  - New iterator method `.all_equal()` by @phimuemue
+## 0.6.0
+  - Deprecated names were removed in favour of their replacements
+  - `.flatten()` does not implement double ended iteration anymore
+  - `.fold_while()` uses `&mut self` and returns `FoldWhile<T>`, for composability #168
+  - `.foreach()` and `.fold1()` use `self`, like `.fold()` does.
+  - `.combinations(0)` now produces a single empty vector. #174
+## 0.5.10
+  - Add itertools method `.kmerge_by()` (and corresponding free function)
+  - Relaxed trait requirement of `.kmerge()` and `.minmax()` to PartialOrd.
+## 0.5.9
+  - Add multipeek method `.reset_peek()`
+  - Add categories
+## 0.5.8
+  - Add iterator adaptor `.peeking_take_while()` and its trait `PeekingNext`.
+## 0.5.7
+  - Add iterator adaptor `.with_position()`
+  - Fix multipeek's performance for long peeks by using `VecDeque`.
+## 0.5.6
+  - Add `.map_results()`
+## 0.5.5
+  - Many more adaptors now implement `Debug`
+  - Add free function constructor `repeat_n`. `RepeatN::new` is now deprecated.
+## 0.5.4
+  - Add infinite generator function `iterate`, that takes a seed and a closure.
+## 0.5.3
+  - Special-cased `.fold()` for flatten and put back. `.foreach()` now uses fold on the iterator, to pick up any iterator specific loop implementation.
+  - `.combinations(n)` asserts up front that `n != 0`, instead of running into an error on the second iterator element.
+## 0.5.2
+  - Add `.tuples::<T>()` that iterates by two, three or four elements at a time (where `T` is a tuple type).
+  - Add `.tuple_windows::<T>()` that iterates using a window of the two, three or four most recent elements.
+  - Add `.next_tuple::<T>()` method, that picks the next two, three or four elements in one go.
+  - `.interleave()` now has an accurate size hint.
+## 0.5.1
+  - Workaround module/function name clash that made racer crash on completing itertools. Only internal changes needed.
+## 0.5.0
+  - [Release announcement](http://bluss.github.io/rust/2016/09/26/itertools-0.5.0/)
+  - Renamed:
+    - `combinations` is now `tuple_combinations`
+    - `combinations_n` to `combinations`
+    - `group_by_lazy`, `chunks_lazy` to `group_by`, `chunks`
+    - `Unfold::new` to `unfold()`
+    - `RepeatCall::new` to `repeat_call()`
+    - `Zip::new` to `multizip`
+    - `PutBack::new`, `PutBackN::new` to `put_back`, `put_back_n`
+    - `PutBack::with_value` is now a builder setter, not a constructor
+    - `MultiPeek::new`, `.multipeek()` to `multipeek()`
+    - `format` to `format_with` and `format_default` to `format`
+    - `.into_rc()` to `rciter`
+    - `Partition` enum is now `Either`
+  - Module reorganization:
+    - All iterator structs are under `itertools::structs` but also reexported to the top level, for backwards compatibility
+    - All free functions are reexported at the root, `itertools::free` will be removed in the next version
+  - Removed:
+    - `ZipSlices`, use `.zip()` instead
+    - `.enumerate_from()`, `ZipTrusted`, due to being unstable
+    - `.mend_slices()`, moved to crate `odds`
+    - Stride, StrideMut, moved to crate `odds`
+    - `linspace()`, moved to crate `itertools-num`
+    - `.sort_by()`, use `.sorted_by()`
+    - `.is_empty_hint()`, use `.size_hint()`
+    - `.dropn()`, use `.dropping()`
+    - `.map_fn()`, use `.map()`
+    - `.slice()`, use `.take()` / `.skip()`
+    - helper traits in `misc`
+    - `new` constructors on iterator structs, use `Itertools` trait or free functions instead
+    - `itertools::size_hint` is now private
+  - Behaviour changes:
+    - `format` and `format_with` helpers now panic if you try to format them more than once.
+    - `repeat_call` is not double ended anymore
+  - New features:
+    - tuple flattening iterator is constructible with `cons_tuples`
+    - itertools reexports `Either` from the `either` crate. `Either<L, R>` is an iterator when `L, R` are.
+    - `MinMaxResult` now implements `Copy` and `Clone`
+    - `tuple_combinations` supports 1-4 tuples of combinations (previously just 2)
+## 0.4.19
+  - Add `.minmax_by()`
+  - Add `itertools::free::cloned`
+  - Add `itertools::free::rciter`
+  - Improve `.step(n)` slightly to take advantage of specialized Fuse better.
+## 0.4.18
+  - Only changes related to the "unstable" crate feature. This feature is more or less deprecated.
+    - Use deprecated warnings when unstable is enabled. `.enumerate_from()` will be removed imminently since it's using a deprecated libstd trait.
+## 0.4.17
+  - Fix bug in `.kmerge()` that caused it to often produce the wrong order #134
+## 0.4.16
+  - Improve precision of the `interleave_shortest` adaptor's size hint (it is now computed exactly when possible).
+## 0.4.15
+  - Fixup on top of the workaround in 0.4.14. A function in `itertools::free` was removed by mistake and now it is added back again.
+## 0.4.14
+  - Workaround an upstream regression in a rust nightly build that broke compilation of of `itertools::free::{interleave, merge}`
+## 0.4.13
+  - Add `.minmax()` and `.minmax_by_key()`, iterator methods for finding both minimum and maximum in one scan.
+  - Add `.format_default()`, a simpler version of `.format()` (lazy formatting for iterators).
+## 0.4.12
+  - Add `.zip_eq()`, an adaptor like `.zip()` except it ensures iterators of inequal length don't pass silently (instead it panics).
+  - Add `.fold_while()`, an iterator method that is a fold that can short-circuit.
+  - Add `.partition_map()`, an iterator method that can separate elements into two collections.
+## 0.4.11
+  - Add `.get()` for `Stride{,Mut}` and `.get_mut()` for `StrideMut`
+## 0.4.10
+  - Improve performance of `.kmerge()`
+## 0.4.9
+  - Add k-ary merge adaptor `.kmerge()`
+  - Fix a bug in `.islice()` with ranges `a..b` where a `> b`.
+## 0.4.8
+  - Implement `Clone`, `Debug` for `Linspace`
+## 0.4.7
+  - Add function `diff_with()` that compares two iterators
+  - Add `.combinations_n()`, an n-ary combinations iterator
+  - Add methods `PutBack::with_value` and `PutBack::into_parts`.
+## 0.4.6
+  - Add method `.sorted()`
+  - Add module `itertools::free` with free function variants of common iterator adaptors and methods. For example `enumerate(iterable)`, `rev(iterable)`, and so on.
+## 0.4.5
+  - Add `.flatten()`
+## 0.4.4
+  - Allow composing `ZipSlices` with itself
+## 0.4.3
+  - Write `iproduct!()` as a single expression; this allows temporary values in its arguments.
+## 0.4.2
+  - Add `.fold_options()`
+  - Require Rust 1.1 or later
+## 0.4.1
+  - Update `.dropping()` to take advantage of `.nth()`
+## 0.4.0
+  - `.merge()`, `.unique()` and `.dedup()` now perform better due to not using function pointers
+  - Add free functions `enumerate()` and `rev()`
+  - Breaking changes:
+    - Return types of `.merge()` and `.merge_by()` renamed and changed
+    - Method `Merge::new` removed
+    - `.merge_by()` now takes a closure that returns bool.
+    - Return type of `.dedup()` changed
+    - Return type of `.mend_slices()` changed
+    - Return type of `.unique()` changed
+    - Removed function `times()`, struct `Times`: use a range instead
+    - Removed deprecated macro `icompr!()`
+    - Removed deprecated `FnMap` and method `.fn_map()`: use `.map_fn()`
+    - `.interleave_shortest()` is no longer guaranteed to act like fused
+## 0.3.25
+  - Rename `.sort_by()` to `.sorted_by()`. Old name is deprecated.
+  - Fix well-formedness warnings from RFC 1214, no user visible impact
+## 0.3.24
+  - Improve performance of `.merge()`'s ordering function slightly
+## 0.3.23
+  - Added `.chunks()`, similar to (and based on) `.group_by_lazy()`.
+  - Tweak linspace to match numpy.linspace and make it double ended.
+## 0.3.22
+  - Added `ZipSlices`, a fast zip for slices
+## 0.3.21
+  - Remove `Debug` impl for `Format`, it will have different use later
+## 0.3.20
+  - Optimize `.group_by_lazy()`
+## 0.3.19
+  - Added `.group_by_lazy()`, a possibly nonallocating group by
+  - Added `.format()`, a nonallocating formatting helper for iterators
+  - Remove uses of `RandomAccessIterator` since it has been deprecated in rust.
+## 0.3.17
+  - Added (adopted) `Unfold` from rust
+## 0.3.16
+  - Added adaptors `.unique()`, `.unique_by()`
+## 0.3.15
+  - Added method `.sort_by()`
+## 0.3.14
+  - Added adaptor `.while_some()`
+## 0.3.13
+  - Added adaptor `.interleave_shortest()`
+  - Added adaptor `.pad_using()`
+## 0.3.11
+  - Added `assert_equal` function
+## 0.3.10
+  - Bugfix `.combinations()` `size_hint`.
+## 0.3.8
+  - Added source `RepeatCall`
+## 0.3.7
+  - Added adaptor `PutBackN`
+  - Added adaptor `.combinations()`
+## 0.3.6
+  - Added `itertools::partition`, partition a sequence in place based on a predicate.
+  - Deprecate `icompr!()` with no replacement.
+## 0.3.5
+  - `.map_fn()` replaces deprecated `.fn_map()`.
+## 0.3.4
+  - `.take_while_ref()` *by-ref adaptor*
+  - `.coalesce()` *adaptor*
+  - `.mend_slices()` *adaptor*
+## 0.3.3
+  - `.dropping_back()` *method*
+  - `.fold1()` *method*
+  - `.is_empty_hint()` *method*
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..d8a9b8c
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,75 @@
+# 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 = "itertools"
+version = "0.9.0"
+authors = ["bluss"]
+exclude = ["/bors.toml"]
+description = "Extra iterator adaptors, iterator methods, free functions, and macros."
+documentation = "https://docs.rs/itertools/"
+keywords = ["iterator", "data-structure", "zip", "product", "group-by"]
+categories = ["algorithms", "rust-patterns"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/bluss/rust-itertools"
+[package.metadata.release]
+no-dev-version = true
+[profile.bench]
+debug = true
+
+[lib]
+test = false
+bench = false
+
+[[bench]]
+name = "tuple_combinations"
+harness = false
+
+[[bench]]
+name = "tuples"
+harness = false
+
+[[bench]]
+name = "fold_specialization"
+harness = false
+
+[[bench]]
+name = "combinations_with_replacement"
+harness = false
+
+[[bench]]
+name = "tree_fold1"
+harness = false
+
+[[bench]]
+name = "bench1"
+harness = false
+[dependencies.either]
+version = "1.0"
+default-features = false
+[dev-dependencies.criterion]
+version = "=0.3.0"
+
+[dev-dependencies.permutohedron]
+version = "0.2"
+
+[dev-dependencies.quickcheck]
+version = "0.9"
+default-features = false
+
+[dev-dependencies.rand]
+version = "0.7"
+
+[features]
+default = ["use_std"]
+use_std = []
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
new file mode 100644
index 0000000..472a27a
--- /dev/null
+++ b/Cargo.toml.orig
@@ -0,0 +1,68 @@
+[package]
+name = "itertools"
+version = "0.9.0"
+
+license = "MIT/Apache-2.0"
+repository = "https://github.com/bluss/rust-itertools"
+documentation = "https://docs.rs/itertools/"
+authors = ["bluss"]
+
+description = "Extra iterator adaptors, iterator methods, free functions, and macros."
+
+keywords = ["iterator", "data-structure", "zip", "product", "group-by"]
+categories = ["algorithms", "rust-patterns"]
+exclude = ["/bors.toml"]
+
+edition = "2018"
+
+[package.metadata.release]
+no-dev-version = true
+
+[lib]
+bench = false
+test = false
+
+[dependencies]
+either = { version = "1.0", default-features = false }
+
+[dev-dependencies]
+rand = "0.7"
+criterion = "=0.3.0" # TODO update criterion version once it becomes compatible with our minimum required Rust verision or bump minimum required rust version
+
+[dev-dependencies.quickcheck]
+version = "0.9"
+default-features = false
+
+[dev-dependencies.permutohedron]
+version = "0.2"
+
+[features]
+default = ["use_std"]
+use_std = []
+
+[profile]
+bench = { debug = true }
+
+[[bench]]
+name = "tuple_combinations"
+harness = false
+
+[[bench]]
+name = "tuples"
+harness = false
+
+[[bench]]
+name = "fold_specialization"
+harness = false
+
+[[bench]]
+name = "combinations_with_replacement"
+harness = false
+
+[[bench]]
+name = "tree_fold1"
+harness = false
+
+[[bench]]
+name = "bench1"
+harness = false
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..24c99d3
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,55 @@
+
+Itertools
+=========
+
+Extra iterator adaptors, functions and macros.
+
+Please read the `API documentation here`__
+
+__ https://docs.rs/itertools/
+
+|build_status|_ |crates|_
+
+.. |build_status| image:: https://travis-ci.org/rust-itertools/itertools.svg?branch=master
+.. _build_status: https://travis-ci.org/rust-itertools/itertools
+
+.. |crates| image:: http://meritbadge.herokuapp.com/itertools
+.. _crates: https://crates.io/crates/itertools
+
+How to use with cargo:
+
+.. code:: toml
+
+    [dependencies]
+    itertools = "0.8"
+
+How to use in your crate:
+
+.. code:: rust
+
+    use itertools::Itertools;
+
+How to contribute
+-----------------
+
+- Fix a bug or implement a new thing
+- Include tests for your new feature, preferably a quickcheck test
+- Make a Pull Request
+
+For new features, please first consider filing a PR to `rust-lang/rust <https://github.com/rust-lang/rust/>`_,
+adding your new feature to the `Iterator` trait of the standard library, if you believe it is reasonable.
+If it isn't accepted there, proposing it for inclusion in ``itertools`` is a good idea.
+The reason for doing is this is so that we avoid future breakage as with ``.flatten()``.
+However, if your feature involves heap allocation, such as storing elements in a ``Vec<T>``,
+then it can't be accepted into ``libcore``, and you should propose it for ``itertools`` directly instead.
+
+License
+-------
+
+Dual-licensed to be compatible with the Rust project.
+
+Licensed under the Apache License, Version 2.0
+http://www.apache.org/licenses/LICENSE-2.0 or the MIT license
+http://opensource.org/licenses/MIT, at your
+option. This file may not be copied, modified, or distributed
+except according to those terms.
diff --git a/benches/bench1.rs b/benches/bench1.rs
new file mode 100644
index 0000000..71278d1
--- /dev/null
+++ b/benches/bench1.rs
@@ -0,0 +1,877 @@
+use criterion::{black_box, criterion_group, criterion_main, Criterion};
+use itertools::Itertools;
+use itertools::free::cloned;
+use itertools::iproduct;
+
+use std::iter::repeat;
+use std::cmp;
+use std::ops::{Add, Range};
+
+mod extra;
+
+use crate::extra::ZipSlices;
+
+fn slice_iter(c: &mut Criterion) {
+    let xs: Vec<_> = repeat(1i32).take(20).collect();
+
+    c.bench_function("slice iter", move |b| {
+        b.iter(|| for elt in xs.iter() {
+            black_box(elt);
+        })
+    });
+}
+
+fn slice_iter_rev(c: &mut Criterion) {
+    let xs: Vec<_> = repeat(1i32).take(20).collect();
+
+    c.bench_function("slice iter rev", move |b| {
+        b.iter(|| for elt in xs.iter().rev() {
+            black_box(elt);
+        })
+    });
+}
+
+fn zip_default_zip(c: &mut Criterion) {
+    let xs = vec![0; 1024];
+    let ys = vec![0; 768];
+    let xs = black_box(xs);
+    let ys = black_box(ys);
+
+    c.bench_function("zip default zip", move |b| {
+        b.iter(|| {
+            for (&x, &y) in xs.iter().zip(&ys) {
+                black_box(x);
+                black_box(y);
+            }
+        })
+    });
+}
+
+fn zipdot_i32_default_zip(c: &mut Criterion) {
+    let xs = vec![2; 1024];
+    let ys = vec![2; 768];
+    let xs = black_box(xs);
+    let ys = black_box(ys);
+
+    c.bench_function("zipdot i32 default zip", move |b| {
+        b.iter(|| {
+            let mut s = 0;
+            for (&x, &y) in xs.iter().zip(&ys) {
+                s += x * y;
+            }
+            s
+        })
+    });
+}
+
+fn zipdot_f32_default_zip(c: &mut Criterion) {
+    let xs = vec![2f32; 1024];
+    let ys = vec![2f32; 768];
+    let xs = black_box(xs);
+    let ys = black_box(ys);
+
+    c.bench_function("zipdot f32 default zip", move |b| {
+        b.iter(|| {
+            let mut s = 0.;
+            for (&x, &y) in xs.iter().zip(&ys) {
+                s += x * y;
+            }
+            s
+        })
+    });
+}
+
+fn zip_default_zip3(c: &mut Criterion) {
+    let xs = vec![0; 1024];
+    let ys = vec![0; 768];
+    let zs = vec![0; 766];
+    let xs = black_box(xs);
+    let ys = black_box(ys);
+    let zs = black_box(zs);
+
+    c.bench_function("zip default zip3", move |b| {
+        b.iter(|| {
+            for ((&x, &y), &z) in xs.iter().zip(&ys).zip(&zs) {
+                black_box(x);
+                black_box(y);
+                black_box(z);
+            }
+        })
+    });
+}
+
+fn zip_slices_ziptuple(c: &mut Criterion) {
+    let xs = vec![0; 1024];
+    let ys = vec![0; 768];
+
+    c.bench_function("zip slices ziptuple", move |b| {
+        b.iter(|| {
+            let xs = black_box(&xs);
+            let ys = black_box(&ys);
+            for (&x, &y) in itertools::multizip((xs, ys)) {
+                black_box(x);
+                black_box(y);
+            }
+        })
+    });
+}
+
+fn zipslices(c: &mut Criterion) {
+    let xs = vec![0; 1024];
+    let ys = vec![0; 768];
+    let xs = black_box(xs);
+    let ys = black_box(ys);
+
+    c.bench_function("zipslices", move |b| {
+        b.iter(|| {
+            for (&x, &y) in ZipSlices::new(&xs, &ys) {
+                black_box(x);
+                black_box(y);
+            }
+        })
+    });
+}
+
+fn zipslices_mut(c: &mut Criterion) {
+    let xs = vec![0; 1024];
+    let ys = vec![0; 768];
+    let xs = black_box(xs);
+    let mut ys = black_box(ys);
+
+    c.bench_function("zipslices mut", move |b| {
+        b.iter(|| {
+            for (&x, &mut y) in ZipSlices::from_slices(&xs[..], &mut ys[..]) {
+                black_box(x);
+                black_box(y);
+            }
+        })
+    });
+}
+
+fn zipdot_i32_zipslices(c: &mut Criterion) {
+    let xs = vec![2; 1024];
+    let ys = vec![2; 768];
+    let xs = black_box(xs);
+    let ys = black_box(ys);
+
+    c.bench_function("zipdot i32 zipslices", move |b| {
+        b.iter(|| {
+            let mut s = 0i32;
+            for (&x, &y) in ZipSlices::new(&xs, &ys) {
+                s += x * y;
+            }
+            s
+        })
+    });
+}
+
+fn zipdot_f32_zipslices(c: &mut Criterion) {
+    let xs = vec![2f32; 1024];
+    let ys = vec![2f32; 768];
+    let xs = black_box(xs);
+    let ys = black_box(ys);
+
+    c.bench_function("zipdot f32 zipslices", move |b| {
+        b.iter(|| {
+            let mut s = 0.;
+            for (&x, &y) in ZipSlices::new(&xs, &ys) {
+                s += x * y;
+            }
+            s
+        })
+    });
+}
+
+fn zip_checked_counted_loop(c: &mut Criterion) {
+    let xs = vec![0; 1024];
+    let ys = vec![0; 768];
+    let xs = black_box(xs);
+    let ys = black_box(ys);
+
+    c.bench_function("zip checked counted loop", move |b| {
+        b.iter(|| {
+            // Must slice to equal lengths, and then bounds checks are eliminated!
+            let len = cmp::min(xs.len(), ys.len());
+            let xs = &xs[..len];
+            let ys = &ys[..len];
+
+            for i in 0..len {
+                let x = xs[i];
+                let y = ys[i];
+                black_box(x);
+                black_box(y);
+            }
+        })
+    });
+}
+
+fn zipdot_i32_checked_counted_loop(c: &mut Criterion) {
+    let xs = vec![2; 1024];
+    let ys = vec![2; 768];
+    let xs = black_box(xs);
+    let ys = black_box(ys);
+
+    c.bench_function("zipdot i32 checked counted loop", move |b| {
+        b.iter(|| {
+            // Must slice to equal lengths, and then bounds checks are eliminated!
+            let len = cmp::min(xs.len(), ys.len());
+            let xs = &xs[..len];
+            let ys = &ys[..len];
+
+            let mut s = 0i32;
+
+            for i in 0..len {
+                s += xs[i] * ys[i];
+            }
+            s
+        })
+    });
+}
+
+fn zipdot_f32_checked_counted_loop(c: &mut Criterion) {
+    let xs = vec![2f32; 1024];
+    let ys = vec![2f32; 768];
+    let xs = black_box(xs);
+    let ys = black_box(ys);
+
+    c.bench_function("zipdot f32 checked counted loop", move |b| {
+        b.iter(|| {
+            // Must slice to equal lengths, and then bounds checks are eliminated!
+            let len = cmp::min(xs.len(), ys.len());
+            let xs = &xs[..len];
+            let ys = &ys[..len];
+
+            let mut s = 0.;
+
+            for i in 0..len {
+                s += xs[i] * ys[i];
+            }
+            s
+        })
+    });
+}
+
+fn zipdot_f32_checked_counted_unrolled_loop(c: &mut Criterion) {
+    let xs = vec![2f32; 1024];
+    let ys = vec![2f32; 768];
+    let xs = black_box(xs);
+    let ys = black_box(ys);
+
+    c.bench_function("zipdot f32 checked counted unrolled loop", move |b| {
+        b.iter(|| {
+            // Must slice to equal lengths, and then bounds checks are eliminated!
+            let len = cmp::min(xs.len(), ys.len());
+            let mut xs = &xs[..len];
+            let mut ys = &ys[..len];
+
+            let mut s = 0.;
+            let (mut p0, mut p1, mut p2, mut p3, mut p4, mut p5, mut p6, mut p7) =
+                (0., 0., 0., 0., 0., 0., 0., 0.);
+
+            // how to unroll and have bounds checks eliminated (by cristicbz)
+            // split sum into eight parts to enable vectorization (by bluss)
+            while xs.len() >= 8 {
+                p0 += xs[0] * ys[0];
+                p1 += xs[1] * ys[1];
+                p2 += xs[2] * ys[2];
+                p3 += xs[3] * ys[3];
+                p4 += xs[4] * ys[4];
+                p5 += xs[5] * ys[5];
+                p6 += xs[6] * ys[6];
+                p7 += xs[7] * ys[7];
+
+                xs = &xs[8..];
+                ys = &ys[8..];
+            }
+            s += p0 + p4;
+            s += p1 + p5;
+            s += p2 + p6;
+            s += p3 + p7;
+
+            for i in 0..xs.len() {
+                s += xs[i] * ys[i];
+            }
+            s
+        })
+    });
+}
+
+fn zip_unchecked_counted_loop(c: &mut Criterion) {
+    let xs = vec![0; 1024];
+    let ys = vec![0; 768];
+    let xs = black_box(xs);
+    let ys = black_box(ys);
+
+    c.bench_function("zip unchecked counted loop", move |b| {
+        b.iter(|| {
+            let len = cmp::min(xs.len(), ys.len());
+            for i in 0..len {
+                unsafe {
+                let x = *xs.get_unchecked(i);
+                let y = *ys.get_unchecked(i);
+                black_box(x);
+                black_box(y);
+                }
+            }
+        })
+    });
+}
+
+fn zipdot_i32_unchecked_counted_loop(c: &mut Criterion) {
+    let xs = vec![2; 1024];
+    let ys = vec![2; 768];
+    let xs = black_box(xs);
+    let ys = black_box(ys);
+
+    c.bench_function("zipdot i32 unchecked counted loop", move |b| {
+        b.iter(|| {
+            let len = cmp::min(xs.len(), ys.len());
+            let mut s = 0i32;
+            for i in 0..len {
+                unsafe {
+                let x = *xs.get_unchecked(i);
+                let y = *ys.get_unchecked(i);
+                s += x * y;
+                }
+            }
+            s
+        })
+    });
+}
+
+fn zipdot_f32_unchecked_counted_loop(c: &mut Criterion) {
+    let xs = vec![2.; 1024];
+    let ys = vec![2.; 768];
+    let xs = black_box(xs);
+    let ys = black_box(ys);
+
+    c.bench_function("zipdot f32 unchecked counted loop", move |b| {
+        b.iter(|| {
+            let len = cmp::min(xs.len(), ys.len());
+            let mut s = 0f32;
+            for i in 0..len {
+                unsafe {
+                let x = *xs.get_unchecked(i);
+                let y = *ys.get_unchecked(i);
+                s += x * y;
+                }
+            }
+            s
+        })
+    });
+}
+
+fn zip_unchecked_counted_loop3(c: &mut Criterion) {
+    let xs = vec![0; 1024];
+    let ys = vec![0; 768];
+    let zs = vec![0; 766];
+    let xs = black_box(xs);
+    let ys = black_box(ys);
+    let zs = black_box(zs);
+
+    c.bench_function("zip unchecked counted loop3", move |b| {
+        b.iter(|| {
+            let len = cmp::min(xs.len(), cmp::min(ys.len(), zs.len()));
+            for i in 0..len {
+                unsafe {
+                let x = *xs.get_unchecked(i);
+                let y = *ys.get_unchecked(i);
+                let z = *zs.get_unchecked(i);
+                black_box(x);
+                black_box(y);
+                black_box(z);
+                }
+            }
+        })
+    });
+}
+
+fn group_by_lazy_1(c: &mut Criterion) {
+    let mut data = vec![0; 1024];
+    for (index, elt) in data.iter_mut().enumerate() {
+        *elt = index / 10;
+    }
+
+    let data = black_box(data);
+
+    c.bench_function("group by lazy 1", move |b| {
+        b.iter(|| {
+            for (_key, group) in &data.iter().group_by(|elt| **elt) {
+                for elt in group {
+                    black_box(elt);
+                }
+            }
+        })
+    });
+}
+
+fn group_by_lazy_2(c: &mut Criterion) {
+    let mut data = vec![0; 1024];
+    for (index, elt) in data.iter_mut().enumerate() {
+        *elt = index / 2;
+    }
+
+    let data = black_box(data);
+
+    c.bench_function("group by lazy 2", move |b| {
+        b.iter(|| {
+            for (_key, group) in &data.iter().group_by(|elt| **elt) {
+                for elt in group {
+                    black_box(elt);
+                }
+            }
+        })
+    });
+}
+
+fn slice_chunks(c: &mut Criterion) {
+    let data = vec![0; 1024];
+
+    let data = black_box(data);
+    let sz = black_box(10);
+
+    c.bench_function("slice chunks", move |b| {
+        b.iter(|| {
+            for group in data.chunks(sz) {
+                for elt in group {
+                    black_box(elt);
+                }
+            }
+        })
+    });
+}
+
+fn chunks_lazy_1(c: &mut Criterion) {
+    let data = vec![0; 1024];
+
+    let data = black_box(data);
+    let sz = black_box(10);
+
+    c.bench_function("chunks lazy 1", move |b| {
+        b.iter(|| {
+            for group in &data.iter().chunks(sz) {
+                for elt in group {
+                    black_box(elt);
+                }
+            }
+        })
+    });
+}
+
+fn equal(c: &mut Criterion) {
+    let data = vec![7; 1024];
+    let l = data.len();
+    let alpha = black_box(&data[1..]);
+    let beta = black_box(&data[..l - 1]);
+
+    c.bench_function("equal", move |b| {
+        b.iter(|| {
+            itertools::equal(alpha, beta)
+        })
+    });
+}
+
+fn merge_default(c: &mut Criterion) {
+    let mut data1 = vec![0; 1024];
+    let mut data2 = vec![0; 800];
+    let mut x = 0;
+    for (_, elt) in data1.iter_mut().enumerate() {
+        *elt = x;
+        x += 1;
+    }
+
+    let mut y = 0;
+    for (i, elt) in data2.iter_mut().enumerate() {
+        *elt += y;
+        if i % 3 == 0 {
+            y += 3;
+        } else {
+            y += 0;
+        }
+    }
+    let data1 = black_box(data1);
+    let data2 = black_box(data2);
+
+    c.bench_function("merge default", move |b| {
+        b.iter(|| {
+            data1.iter().merge(&data2).count()
+        })
+    });
+}
+
+fn merge_by_cmp(c: &mut Criterion) {
+    let mut data1 = vec![0; 1024];
+    let mut data2 = vec![0; 800];
+    let mut x = 0;
+    for (_, elt) in data1.iter_mut().enumerate() {
+        *elt = x;
+        x += 1;
+    }
+
+    let mut y = 0;
+    for (i, elt) in data2.iter_mut().enumerate() {
+        *elt += y;
+        if i % 3 == 0 {
+            y += 3;
+        } else {
+            y += 0;
+        }
+    }
+    let data1 = black_box(data1);
+    let data2 = black_box(data2);
+
+    c.bench_function("merge by cmp", move |b| {
+        b.iter(|| {
+            data1.iter().merge_by(&data2, PartialOrd::le).count()
+        })
+    });
+}
+
+fn merge_by_lt(c: &mut Criterion) {
+    let mut data1 = vec![0; 1024];
+    let mut data2 = vec![0; 800];
+    let mut x = 0;
+    for (_, elt) in data1.iter_mut().enumerate() {
+        *elt = x;
+        x += 1;
+    }
+
+    let mut y = 0;
+    for (i, elt) in data2.iter_mut().enumerate() {
+        *elt += y;
+        if i % 3 == 0 {
+            y += 3;
+        } else {
+            y += 0;
+        }
+    }
+    let data1 = black_box(data1);
+    let data2 = black_box(data2);
+
+    c.bench_function("merge by lt", move |b| {
+        b.iter(|| {
+            data1.iter().merge_by(&data2, |a, b| a <= b).count()
+        })
+    });
+}
+
+fn kmerge_default(c: &mut Criterion) {
+    let mut data1 = vec![0; 1024];
+    let mut data2 = vec![0; 800];
+    let mut x = 0;
+    for (_, elt) in data1.iter_mut().enumerate() {
+        *elt = x;
+        x += 1;
+    }
+
+    let mut y = 0;
+    for (i, elt) in data2.iter_mut().enumerate() {
+        *elt += y;
+        if i % 3 == 0 {
+            y += 3;
+        } else {
+            y += 0;
+        }
+    }
+    let data1 = black_box(data1);
+    let data2 = black_box(data2);
+    let its = &[data1.iter(), data2.iter()];
+
+    c.bench_function("kmerge default", move |b| {
+        b.iter(|| {
+            its.iter().cloned().kmerge().count()
+        })
+    });
+}
+
+fn kmerge_tenway(c: &mut Criterion) {
+    let mut data = vec![0; 10240];
+
+    let mut state = 1729u16;
+    fn rng(state: &mut u16) -> u16 {
+        let new = state.wrapping_mul(31421) + 6927;
+        *state = new;
+        new
+    }
+
+    for elt in &mut data {
+        *elt = rng(&mut state);
+    }
+
+    let mut chunks = Vec::new();
+    let mut rest = &mut data[..];
+    while rest.len() > 0 {
+        let chunk_len = 1 + rng(&mut state) % 512;
+        let chunk_len = cmp::min(rest.len(), chunk_len as usize);
+        let (fst, tail) = {rest}.split_at_mut(chunk_len);
+        fst.sort();
+        chunks.push(fst.iter().cloned());
+        rest = tail;
+    }
+
+    // println!("Chunk lengths: {}", chunks.iter().format_with(", ", |elt, f| f(&elt.len())));
+
+    c.bench_function("kmerge tenway", move |b| {
+        b.iter(|| {
+            chunks.iter().cloned().kmerge().count()
+        })
+    });
+}
+
+fn fast_integer_sum<I>(iter: I) -> I::Item
+    where I: IntoIterator,
+          I::Item: Default + Add<Output=I::Item>
+{
+    iter.into_iter().fold(<_>::default(), |x, y| x + y)
+}
+
+fn step_vec_2(c: &mut Criterion) {
+    let v = vec![0; 1024];
+
+    c.bench_function("step vec 2", move |b| {
+        b.iter(|| {
+            fast_integer_sum(cloned(v.iter().step_by(2)))
+        })
+    });
+}
+
+fn step_vec_10(c: &mut Criterion) {
+    let v = vec![0; 1024];
+
+    c.bench_function("step vec 10", move |b| {
+        b.iter(|| {
+            fast_integer_sum(cloned(v.iter().step_by(10)))
+        })
+    });
+}
+
+fn step_range_2(c: &mut Criterion) {
+    let v = black_box(0..1024);
+
+    c.bench_function("step range 2", move |b| {
+        b.iter(|| {
+            fast_integer_sum(v.clone().step_by(2))
+        })
+    });
+}
+
+fn step_range_10(c: &mut Criterion) {
+    let v = black_box(0..1024);
+
+    c.bench_function("step range 10", move |b| {
+        b.iter(|| {
+            fast_integer_sum(v.clone().step_by(10))
+        })
+    });
+}
+
+fn cartesian_product_iterator(c: &mut Criterion) {
+    let xs = vec![0; 16];
+
+    c.bench_function("cartesian product iterator", move |b| {
+        b.iter(|| {
+            let mut sum = 0;
+            for (&x, &y, &z) in iproduct!(&xs, &xs, &xs) {
+                sum += x;
+                sum += y;
+                sum += z;
+            }
+            sum
+        })
+    });
+}
+
+fn cartesian_product_fold(c: &mut Criterion) {
+    let xs = vec![0; 16];
+
+    c.bench_function("cartesian product fold", move |b| {
+        b.iter(|| {
+            let mut sum = 0;
+            iproduct!(&xs, &xs, &xs).fold((), |(), (&x, &y, &z)| {
+                sum += x;
+                sum += y;
+                sum += z;
+            });
+            sum
+        })
+    });
+}
+
+fn multi_cartesian_product_iterator(c: &mut Criterion) {
+    let xs = [vec![0; 16], vec![0; 16], vec![0; 16]];
+
+    c.bench_function("multi cartesian product iterator", move |b| {
+        b.iter(|| {
+            let mut sum = 0;
+            for x in xs.iter().multi_cartesian_product() {
+                sum += x[0];
+                sum += x[1];
+                sum += x[2];
+            }
+            sum
+        })
+    });
+}
+
+fn multi_cartesian_product_fold(c: &mut Criterion) {
+    let xs = [vec![0; 16], vec![0; 16], vec![0; 16]];
+
+    c.bench_function("multi cartesian product fold", move |b| {
+        b.iter(|| {
+            let mut sum = 0;
+            xs.iter().multi_cartesian_product().fold((), |(), x| {
+                sum += x[0];
+                sum += x[1];
+                sum += x[2];
+            });
+            sum
+        })
+    });
+}
+
+fn cartesian_product_nested_for(c: &mut Criterion) {
+    let xs = vec![0; 16];
+
+    c.bench_function("cartesian product nested for", move |b| {
+        b.iter(|| {
+            let mut sum = 0;
+            for &x in &xs {
+                for &y in &xs {
+                    for &z in &xs {
+                        sum += x;
+                        sum += y;
+                        sum += z;
+                    }
+                }
+            }
+            sum
+        })
+    });
+}
+
+fn all_equal(c: &mut Criterion) {
+    let mut xs = vec![0; 5_000_000];
+    xs.extend(vec![1; 5_000_000]);
+
+    c.bench_function("all equal", move |b| {
+        b.iter(|| xs.iter().all_equal())
+    });
+}
+
+fn all_equal_for(c: &mut Criterion) {
+    let mut xs = vec![0; 5_000_000];
+    xs.extend(vec![1; 5_000_000]);
+
+    c.bench_function("all equal for", move |b| {
+        b.iter(|| {
+            for &x in &xs {
+                if x != xs[0] {
+                    return false;
+                }
+            }
+            true
+        })
+    });
+}
+
+fn all_equal_default(c: &mut Criterion) {
+    let mut xs = vec![0; 5_000_000];
+    xs.extend(vec![1; 5_000_000]);
+
+    c.bench_function("all equal default", move |b| {
+        b.iter(|| xs.iter().dedup().nth(1).is_none())
+    });
+}
+
+const PERM_COUNT: usize = 6;
+
+fn permutations_iter(c: &mut Criterion) {
+    struct NewIterator(Range<usize>);
+
+    impl Iterator for NewIterator {
+        type Item = usize;
+
+        fn next(&mut self) -> Option<Self::Item> {
+            self.0.next()
+        }
+    }
+
+    c.bench_function("permutations iter", move |b| {
+        b.iter(|| {
+            for _ in NewIterator(0..PERM_COUNT).permutations(PERM_COUNT) {
+
+            }
+        })
+    });
+}
+
+fn permutations_range(c: &mut Criterion) {
+    c.bench_function("permutations range", move |b| {
+        b.iter(|| {
+            for _ in (0..PERM_COUNT).permutations(PERM_COUNT) {
+
+            }
+        })
+    });
+}
+
+fn permutations_slice(c: &mut Criterion) {
+    let v = (0..PERM_COUNT).collect_vec();
+
+    c.bench_function("permutations slice", move |b| {
+        b.iter(|| {
+            for _ in v.as_slice().iter().permutations(PERM_COUNT) {
+
+            }
+        })
+    });
+}
+
+criterion_group!(
+    benches,
+    slice_iter,
+    slice_iter_rev,
+    zip_default_zip,
+    zipdot_i32_default_zip,
+    zipdot_f32_default_zip,
+    zip_default_zip3,
+    zip_slices_ziptuple,
+    zipslices,
+    zipslices_mut,
+    zipdot_i32_zipslices,
+    zipdot_f32_zipslices,
+    zip_checked_counted_loop,
+    zipdot_i32_checked_counted_loop,
+    zipdot_f32_checked_counted_loop,
+    zipdot_f32_checked_counted_unrolled_loop,
+    zip_unchecked_counted_loop,
+    zipdot_i32_unchecked_counted_loop,
+    zipdot_f32_unchecked_counted_loop,
+    zip_unchecked_counted_loop3,
+    group_by_lazy_1,
+    group_by_lazy_2,
+    slice_chunks,
+    chunks_lazy_1,
+    equal,
+    merge_default,
+    merge_by_cmp,
+    merge_by_lt,
+    kmerge_default,
+    kmerge_tenway,
+    step_vec_2,
+    step_vec_10,
+    step_range_2,
+    step_range_10,
+    cartesian_product_iterator,
+    cartesian_product_fold,
+    multi_cartesian_product_iterator,
+    multi_cartesian_product_fold,
+    cartesian_product_nested_for,
+    all_equal,
+    all_equal_for,
+    all_equal_default,
+    permutations_iter,
+    permutations_range,
+    permutations_slice,
+);
+criterion_main!(benches);
diff --git a/benches/combinations_with_replacement.rs b/benches/combinations_with_replacement.rs
new file mode 100644
index 0000000..8e4fa3d
--- /dev/null
+++ b/benches/combinations_with_replacement.rs
@@ -0,0 +1,40 @@
+use criterion::{black_box, criterion_group, criterion_main, Criterion};
+use itertools::Itertools;
+
+fn comb_replacement_n10_k5(c: &mut Criterion) {
+    c.bench_function("comb replacement n10k5", move |b| {
+        b.iter(|| {
+            for i in (0..10).combinations_with_replacement(5) {
+                black_box(i);
+            }
+        })
+    });
+}
+
+fn comb_replacement_n5_k10(c: &mut Criterion) {
+    c.bench_function("comb replacement n5 k10", move |b| {
+        b.iter(|| {
+            for i in (0..5).combinations_with_replacement(10) {
+                black_box(i);
+            }
+        })
+    });
+}
+
+fn comb_replacement_n10_k10(c: &mut Criterion) {
+    c.bench_function("comb replacement n10 k10", move |b| {
+        b.iter(|| {
+            for i in (0..10).combinations_with_replacement(10) {
+                black_box(i);
+            }
+        })
+    });
+}
+
+criterion_group!(
+    benches,
+    comb_replacement_n10_k5,
+    comb_replacement_n5_k10,
+    comb_replacement_n10_k10,
+);
+criterion_main!(benches);
diff --git a/benches/extra/mod.rs b/benches/extra/mod.rs
new file mode 100644
index 0000000..52fe5cc
--- /dev/null
+++ b/benches/extra/mod.rs
@@ -0,0 +1,2 @@
+pub use self::zipslices::ZipSlices;
+mod zipslices;
diff --git a/benches/extra/zipslices.rs b/benches/extra/zipslices.rs
new file mode 100644
index 0000000..8bf3967
--- /dev/null
+++ b/benches/extra/zipslices.rs
@@ -0,0 +1,188 @@
+use std::cmp;
+
+// Note: There are different ways to implement ZipSlices.
+// This version performed the best in benchmarks.
+//
+// I also implemented a version with three pointes (tptr, tend, uptr),
+// that mimiced slice::Iter and only checked bounds by using tptr == tend,
+// but that was inferior to this solution.
+
+/// An iterator which iterates two slices simultaneously.
+///
+/// `ZipSlices` acts like a double-ended `.zip()` iterator.
+///
+/// It was intended to be more efficient than `.zip()`, and it was, then
+/// rustc changed how it optimizes so it can not promise improved performance
+/// at this time.
+///
+/// Note that elements past the end of the shortest of the two slices are ignored.
+///
+/// Iterator element type for `ZipSlices<T, U>` is `(T::Item, U::Item)`. For example,
+/// for a `ZipSlices<&'a [A], &'b mut [B]>`, the element type is `(&'a A, &'b mut B)`.
+#[derive(Clone)]
+pub struct ZipSlices<T, U> {
+    t: T,
+    u: U,
+    len: usize,
+    index: usize,
+}
+
+impl<'a, 'b, A, B> ZipSlices<&'a [A], &'b [B]> {
+    /// Create a new `ZipSlices` from slices `a` and `b`.
+    ///
+    /// Act like a double-ended `.zip()` iterator, but more efficiently.
+    ///
+    /// Note that elements past the end of the shortest of the two slices are ignored.
+    #[inline(always)]
+    pub fn new(a: &'a [A], b: &'b [B]) -> Self {
+        let minl = cmp::min(a.len(), b.len());
+        ZipSlices {
+            t: a,
+            u: b,
+            len: minl,
+            index: 0,
+        }
+    }
+}
+
+impl<T, U> ZipSlices<T, U>
+    where T: Slice,
+          U: Slice
+{
+    /// Create a new `ZipSlices` from slices `a` and `b`.
+    ///
+    /// Act like a double-ended `.zip()` iterator, but more efficiently.
+    ///
+    /// Note that elements past the end of the shortest of the two slices are ignored.
+    #[inline(always)]
+    pub fn from_slices(a: T, b: U) -> Self {
+        let minl = cmp::min(a.len(), b.len());
+        ZipSlices {
+            t: a,
+            u: b,
+            len: minl,
+            index: 0,
+        }
+    }
+}
+
+impl<T, U> Iterator for ZipSlices<T, U>
+    where T: Slice,
+          U: Slice
+{
+    type Item = (T::Item, U::Item);
+
+    #[inline(always)]
+    fn next(&mut self) -> Option<Self::Item> {
+        unsafe {
+            if self.index >= self.len {
+                None
+            } else {
+                let i = self.index;
+                self.index += 1;
+                Some((
+                    self.t.get_unchecked(i),
+                    self.u.get_unchecked(i)))
+            }
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let len = self.len - self.index;
+        (len, Some(len))
+    }
+}
+
+impl<T, U> DoubleEndedIterator for ZipSlices<T, U>
+    where T: Slice,
+          U: Slice
+{
+    #[inline(always)]
+    fn next_back(&mut self) -> Option<Self::Item> {
+        unsafe {
+            if self.index >= self.len {
+                None
+            } else {
+                self.len -= 1;
+                let i = self.len;
+                Some((
+                    self.t.get_unchecked(i),
+                    self.u.get_unchecked(i)))
+            }
+        }
+    }
+}
+
+impl<T, U> ExactSizeIterator for ZipSlices<T, U>
+    where T: Slice,
+          U: Slice
+{}
+
+unsafe impl<T, U> Slice for ZipSlices<T, U>
+    where T: Slice,
+          U: Slice
+{
+    type Item = (T::Item, U::Item);
+
+    fn len(&self) -> usize {
+        self.len - self.index
+    }
+
+    unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item {
+        (self.t.get_unchecked(i),
+         self.u.get_unchecked(i))
+    }
+}
+
+/// A helper trait to let `ZipSlices` accept both `&[T]` and `&mut [T]`.
+///
+/// Unsafe trait because:
+///
+/// - Implementors must guarantee that `get_unchecked` is valid for all indices `0..len()`.
+pub unsafe trait Slice {
+    /// The type of a reference to the slice's elements
+    type Item;
+    #[doc(hidden)]
+    fn len(&self) -> usize;
+    #[doc(hidden)]
+    unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item;
+}
+
+unsafe impl<'a, T> Slice for &'a [T] {
+    type Item = &'a T;
+    #[inline(always)]
+    fn len(&self) -> usize { (**self).len() }
+    #[inline(always)]
+    unsafe fn get_unchecked(&mut self, i: usize) -> &'a T {
+        debug_assert!(i < self.len());
+        (**self).get_unchecked(i)
+    }
+}
+
+unsafe impl<'a, T> Slice for &'a mut [T] {
+    type Item = &'a mut T;
+    #[inline(always)]
+    fn len(&self) -> usize { (**self).len() }
+    #[inline(always)]
+    unsafe fn get_unchecked(&mut self, i: usize) -> &'a mut T {
+        debug_assert!(i < self.len());
+        // override the lifetime constraints of &mut &'a mut [T]
+        (*(*self as *mut [T])).get_unchecked_mut(i)
+    }
+}
+
+#[test]
+fn zipslices() {
+
+    let xs = [1, 2, 3, 4, 5, 6];
+    let ys = [1, 2, 3, 7];
+    ::itertools::assert_equal(ZipSlices::new(&xs, &ys), xs.iter().zip(&ys));
+
+    let xs = [1, 2, 3, 4, 5, 6];
+    let mut ys = [0; 6];
+    for (x, y) in ZipSlices::from_slices(&xs[..], &mut ys[..]) {
+        *y = *x;
+    }
+    ::itertools::assert_equal(&xs, &ys);
+}
diff --git a/benches/fold_specialization.rs b/benches/fold_specialization.rs
new file mode 100644
index 0000000..53319a5
--- /dev/null
+++ b/benches/fold_specialization.rs
@@ -0,0 +1,73 @@
+use criterion::{criterion_group, criterion_main, Criterion};
+use itertools::Itertools;
+
+struct Unspecialized<I>(I);
+
+impl<I> Iterator for Unspecialized<I>
+where I: Iterator
+{
+    type Item = I::Item;
+
+    #[inline(always)]
+    fn next(&mut self) -> Option<I::Item> {
+        self.0.next()
+    }
+
+    #[inline(always)]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.0.size_hint()
+    }
+}
+
+mod specialization {
+    use super::*;
+
+    pub mod intersperse {
+        use super::*;
+
+        pub fn external(c: &mut Criterion)
+        {
+            let arr = [1; 1024];
+
+            c.bench_function("external", move |b| {
+                b.iter(|| {
+                    let mut sum = 0;
+                    for &x in arr.iter().intersperse(&0) {
+                        sum += x;
+                    }
+                    sum
+                })
+            });
+        }
+
+        pub fn internal_specialized(c: &mut Criterion)
+        {
+            let arr = [1; 1024];
+
+            c.bench_function("internal specialized", move |b| {
+                b.iter(|| {
+                    arr.iter().intersperse(&0).fold(0, |acc, x| acc + x)
+                })
+            });
+        }
+
+        pub fn internal_unspecialized(c: &mut Criterion)
+        {
+            let arr = [1; 1024];
+
+            c.bench_function("internal unspecialized", move |b| {
+                b.iter(|| {
+                    Unspecialized(arr.iter().intersperse(&0)).fold(0, |acc, x| acc + x)
+                })
+            });
+        }
+    }
+}
+
+criterion_group!(
+    benches,
+    specialization::intersperse::external,
+    specialization::intersperse::internal_specialized,
+    specialization::intersperse::internal_unspecialized,
+);
+criterion_main!(benches);
diff --git a/benches/tree_fold1.rs b/benches/tree_fold1.rs
new file mode 100644
index 0000000..f12995d
--- /dev/null
+++ b/benches/tree_fold1.rs
@@ -0,0 +1,144 @@
+use criterion::{criterion_group, criterion_main, Criterion};
+use itertools::{Itertools, cloned};
+
+trait IterEx : Iterator {
+    // Another efficient implementation against which to compare,
+    // but needs `std` so is less desirable.
+    fn tree_fold1_vec<F>(self, mut f: F) -> Option<Self::Item>
+        where F: FnMut(Self::Item, Self::Item) -> Self::Item,
+              Self: Sized,
+    {
+        let hint = self.size_hint().0;
+        let cap = std::mem::size_of::<usize>() * 8 - hint.leading_zeros() as usize;
+        let mut stack = Vec::with_capacity(cap);
+        self.enumerate().for_each(|(mut i, mut x)| {
+            while (i & 1) != 0 {
+                x = f(stack.pop().unwrap(), x);
+                i >>= 1;
+            }
+            stack.push(x);
+        });
+        stack.into_iter().fold1(f)
+    }
+}
+impl<T:Iterator> IterEx for T {}
+
+macro_rules! def_benchs {
+    ($N:expr,
+     $FUN:ident,
+     $BENCH_NAME:ident,
+     ) => (
+        mod $BENCH_NAME {
+            use super::*;
+
+            pub fn sum(c: &mut Criterion) {
+                let v: Vec<u32> = (0.. $N).collect();
+
+                c.bench_function(&(stringify!($BENCH_NAME).replace('_', " ") + " sum"), move |b| {
+                    b.iter(|| {
+                        cloned(&v).$FUN(|x, y| x + y)
+                    })
+                });
+            }
+
+            pub fn complex_iter(c: &mut Criterion) {
+                let u = (3..).take($N / 2);
+                let v = (5..).take($N / 2);
+                let it = u.chain(v);
+
+                c.bench_function(&(stringify!($BENCH_NAME).replace('_', " ") + " complex iter"), move |b| {
+                    b.iter(|| {
+                        it.clone().map(|x| x as f32).$FUN(f32::atan2)
+                    })
+                });
+            }
+
+            pub fn string_format(c: &mut Criterion) {
+                // This goes quadratic with linear `fold1`, so use a smaller
+                // size to not waste too much time in travis.  The allocations
+                // in here are so expensive anyway that it'll still take
+                // way longer per iteration than the other two benchmarks.
+                let v: Vec<u32> = (0.. ($N/4)).collect();
+
+                c.bench_function(&(stringify!($BENCH_NAME).replace('_', " ") + " string format"), move |b| {
+                    b.iter(|| {
+                        cloned(&v).map(|x| x.to_string()).$FUN(|x, y| format!("{} + {}", x, y))
+                    })
+                });
+            }
+        }
+
+        criterion_group!(
+            $BENCH_NAME,
+            $BENCH_NAME::sum,
+            $BENCH_NAME::complex_iter,
+            $BENCH_NAME::string_format,
+        );
+    )
+}
+
+def_benchs!{
+    10_000,
+    fold1,
+    fold1_10k,
+}
+
+def_benchs!{
+    10_000,
+    tree_fold1,
+    tree_fold1_stack_10k,
+}
+
+def_benchs!{
+    10_000,
+    tree_fold1_vec,
+    tree_fold1_vec_10k,
+}
+
+def_benchs!{
+    100,
+    fold1,
+    fold1_100,
+}
+
+def_benchs!{
+    100,
+    tree_fold1,
+    tree_fold1_stack_100,
+}
+
+def_benchs!{
+    100,
+    tree_fold1_vec,
+    tree_fold1_vec_100,
+}
+
+def_benchs!{
+    8,
+    fold1,
+    fold1_08,
+}
+
+def_benchs!{
+    8,
+    tree_fold1,
+    tree_fold1_stack_08,
+}
+
+def_benchs!{
+    8,
+    tree_fold1_vec,
+    tree_fold1_vec_08,
+}
+
+criterion_main!(
+    fold1_10k,
+    tree_fold1_stack_10k,
+    tree_fold1_vec_10k,
+    fold1_100,
+    tree_fold1_stack_100,
+    tree_fold1_vec_100,
+    fold1_08,
+    tree_fold1_stack_08,
+    tree_fold1_vec_08,
+);
diff --git a/benches/tuple_combinations.rs b/benches/tuple_combinations.rs
new file mode 100644
index 0000000..84411ef
--- /dev/null
+++ b/benches/tuple_combinations.rs
@@ -0,0 +1,113 @@
+use criterion::{black_box, criterion_group, criterion_main, Criterion};
+use itertools::Itertools;
+
+// approximate 100_000 iterations for each combination
+const N1: usize = 100_000;
+const N2: usize = 448;
+const N3: usize = 86;
+const N4: usize = 41;
+
+fn comb_for1(c: &mut Criterion) {
+    c.bench_function("comb for1", move |b| {
+        b.iter(|| {
+            for i in 0..N1 {
+                black_box(i);
+            }
+        })
+    });
+}
+
+fn comb_for2(c: &mut Criterion) {
+    c.bench_function("comb for2", move |b| {
+        b.iter(|| {
+            for i in 0..N2 {
+                for j in (i + 1)..N2 {
+                    black_box(i + j);
+                }
+            }
+        })
+    });
+}
+
+fn comb_for3(c: &mut Criterion) {
+    c.bench_function("comb for3", move |b| {
+        b.iter(|| {
+            for i in 0..N3 {
+                for j in (i + 1)..N3 {
+                    for k in (j + 1)..N3 {
+                        black_box(i + j + k);
+                    }
+                }
+            }
+        })
+    });
+}
+
+fn comb_for4(c: &mut Criterion) {
+    c.bench_function("comb for4", move |b| {
+        b.iter(|| {
+            for i in 0..N4 {
+                for j in (i + 1)..N4 {
+                    for k in (j + 1)..N4 {
+                        for l in (k + 1)..N4 {
+                            black_box(i + j + k + l);
+                        }
+                    }
+                }
+            }
+        })
+    });
+}
+
+fn comb_c1(c: &mut Criterion) {
+    c.bench_function("comb c1", move |b| {
+        b.iter(|| {
+            for (i,) in (0..N1).tuple_combinations() {
+                black_box(i);
+            }
+        })
+    });
+}
+
+fn comb_c2(c: &mut Criterion) {
+    c.bench_function("comb c2", move |b| {
+        b.iter(|| {
+            for (i, j) in (0..N2).tuple_combinations() {
+                black_box(i + j);
+            }
+        })
+    });
+}
+
+fn comb_c3(c: &mut Criterion) {
+    c.bench_function("comb c3", move |b| {
+        b.iter(|| {
+            for (i, j, k) in (0..N3).tuple_combinations() {
+                black_box(i + j + k);
+            }
+        })
+    });
+}
+
+fn comb_c4(c: &mut Criterion) {
+    c.bench_function("comb c4", move |b| {
+        b.iter(|| {
+            for (i, j, k, l) in (0..N4).tuple_combinations() {
+                black_box(i + j + k + l);
+            }
+        })
+    });
+}
+
+criterion_group!(
+    benches,
+    comb_for1,
+    comb_for2,
+    comb_for3,
+    comb_for4,
+    comb_c1,
+    comb_c2,
+    comb_c3,
+    comb_c4,
+);
+criterion_main!(benches);
diff --git a/benches/tuples.rs b/benches/tuples.rs
new file mode 100644
index 0000000..ea50aaa
--- /dev/null
+++ b/benches/tuples.rs
@@ -0,0 +1,213 @@
+use criterion::{criterion_group, criterion_main, Criterion};
+use itertools::Itertools;
+
+fn s1(a: u32) -> u32 {
+    a
+}
+
+fn s2(a: u32, b: u32) -> u32 {
+    a + b
+}
+
+fn s3(a: u32, b: u32, c: u32) -> u32 {
+    a + b + c
+}
+
+fn s4(a: u32, b: u32, c: u32, d: u32) -> u32 {
+    a + b + c + d
+}
+
+fn sum_s1(s: &[u32]) -> u32 {
+    s1(s[0])
+}
+
+fn sum_s2(s: &[u32]) -> u32 {
+    s2(s[0], s[1])
+}
+
+fn sum_s3(s: &[u32]) -> u32 {
+    s3(s[0], s[1], s[2])
+}
+
+fn sum_s4(s: &[u32]) -> u32 {
+    s4(s[0], s[1], s[2], s[3])
+}
+
+fn sum_t1(s: &(&u32, )) -> u32 {
+    s1(*s.0)
+}
+
+fn sum_t2(s: &(&u32, &u32)) -> u32 {
+    s2(*s.0, *s.1)
+}
+
+fn sum_t3(s: &(&u32, &u32, &u32)) -> u32 {
+    s3(*s.0, *s.1, *s.2)
+}
+
+fn sum_t4(s: &(&u32, &u32, &u32, &u32)) -> u32 {
+    s4(*s.0, *s.1, *s.2, *s.3)
+}
+
+macro_rules! def_benchs {
+    ($N:expr;
+     $BENCH_GROUP:ident,
+     $TUPLE_FUN:ident,
+     $TUPLES:ident,
+     $TUPLE_WINDOWS:ident;
+     $SLICE_FUN:ident,
+     $CHUNKS:ident,
+     $WINDOWS:ident;
+     $FOR_CHUNKS:ident,
+     $FOR_WINDOWS:ident
+     ) => (
+        fn $FOR_CHUNKS(c: &mut Criterion) {
+            let v: Vec<u32> = (0.. $N * 1_000).collect();
+            let mut s = 0;
+            c.bench_function(&stringify!($FOR_CHUNKS).replace('_', " "), move |b| {
+                b.iter(|| {
+                    let mut j = 0;
+                    for _ in 0..1_000 {
+                        s += $SLICE_FUN(&v[j..(j + $N)]);
+                        j += $N;
+                    }
+                    s
+                })
+            });
+        }
+
+        fn $FOR_WINDOWS(c: &mut Criterion) {
+            let v: Vec<u32> = (0..1_000).collect();
+            let mut s = 0;
+            c.bench_function(&stringify!($FOR_WINDOWS).replace('_', " "), move |b| {
+                b.iter(|| {
+                    for i in 0..(1_000 - $N) {
+                        s += $SLICE_FUN(&v[i..(i + $N)]);
+                    }
+                    s
+                })
+            });
+        }
+
+        fn $TUPLES(c: &mut Criterion) {
+            let v: Vec<u32> = (0.. $N * 1_000).collect();
+            let mut s = 0;
+            c.bench_function(&stringify!($TUPLES).replace('_', " "), move |b| {
+                b.iter(|| {
+                    for x in v.iter().tuples() {
+                        s += $TUPLE_FUN(&x);
+                    }
+                    s
+                })
+            });
+        }
+
+        fn $CHUNKS(c: &mut Criterion) {
+            let v: Vec<u32> = (0.. $N * 1_000).collect();
+            let mut s = 0;
+            c.bench_function(&stringify!($CHUNKS).replace('_', " "), move |b| {
+                b.iter(|| {
+                    for x in v.chunks($N) {
+                        s += $SLICE_FUN(x);
+                    }
+                    s
+                })
+            });
+        }
+
+        fn $TUPLE_WINDOWS(c: &mut Criterion) {
+            let v: Vec<u32> = (0..1_000).collect();
+            let mut s = 0;
+            c.bench_function(&stringify!($TUPLE_WINDOWS).replace('_', " "), move |b| {
+                b.iter(|| {
+                    for x in v.iter().tuple_windows() {
+                        s += $TUPLE_FUN(&x);
+                    }
+                    s
+                })
+            });
+        }
+
+        fn $WINDOWS(c: &mut Criterion) {
+            let v: Vec<u32> = (0..1_000).collect();
+            let mut s = 0;
+            c.bench_function(&stringify!($WINDOWS).replace('_', " "), move |b| {
+                b.iter(|| {
+                    for x in v.windows($N) {
+                        s += $SLICE_FUN(x);
+                    }
+                    s
+                })
+            });
+        }
+
+        criterion_group!(
+            $BENCH_GROUP,
+            $FOR_CHUNKS,
+            $FOR_WINDOWS,
+            $TUPLES,
+            $CHUNKS,
+            $TUPLE_WINDOWS,
+            $WINDOWS,
+        );
+    )
+}
+
+def_benchs!{
+    1;
+    benches_1,
+    sum_t1,
+    tuple_chunks_1,
+    tuple_windows_1;
+    sum_s1,
+    slice_chunks_1,
+    slice_windows_1;
+    for_chunks_1,
+    for_windows_1
+}
+
+def_benchs!{
+    2;
+    benches_2,
+    sum_t2,
+    tuple_chunks_2,
+    tuple_windows_2;
+    sum_s2,
+    slice_chunks_2,
+    slice_windows_2;
+    for_chunks_2,
+    for_windows_2
+}
+
+def_benchs!{
+    3;
+    benches_3,
+    sum_t3,
+    tuple_chunks_3,
+    tuple_windows_3;
+    sum_s3,
+    slice_chunks_3,
+    slice_windows_3;
+    for_chunks_3,
+    for_windows_3
+}
+
+def_benchs!{
+    4;
+    benches_4,
+    sum_t4,
+    tuple_chunks_4,
+    tuple_windows_4;
+    sum_s4,
+    slice_chunks_4,
+    slice_windows_4;
+    for_chunks_4,
+    for_windows_4
+}
+
+criterion_main!(
+    benches_1,
+    benches_2,
+    benches_3,
+    benches_4,
+);
diff --git a/examples/iris.data b/examples/iris.data
new file mode 100644
index 0000000..a3490e0
--- /dev/null
+++ b/examples/iris.data
@@ -0,0 +1,150 @@
+5.1,3.5,1.4,0.2,Iris-setosa
+4.9,3.0,1.4,0.2,Iris-setosa
+4.7,3.2,1.3,0.2,Iris-setosa
+4.6,3.1,1.5,0.2,Iris-setosa
+5.0,3.6,1.4,0.2,Iris-setosa
+5.4,3.9,1.7,0.4,Iris-setosa
+4.6,3.4,1.4,0.3,Iris-setosa
+5.0,3.4,1.5,0.2,Iris-setosa
+4.4,2.9,1.4,0.2,Iris-setosa
+4.9,3.1,1.5,0.1,Iris-setosa
+5.4,3.7,1.5,0.2,Iris-setosa
+4.8,3.4,1.6,0.2,Iris-setosa
+4.8,3.0,1.4,0.1,Iris-setosa
+4.3,3.0,1.1,0.1,Iris-setosa
+5.8,4.0,1.2,0.2,Iris-setosa
+5.7,4.4,1.5,0.4,Iris-setosa
+5.4,3.9,1.3,0.4,Iris-setosa
+5.1,3.5,1.4,0.3,Iris-setosa
+5.7,3.8,1.7,0.3,Iris-setosa
+5.1,3.8,1.5,0.3,Iris-setosa
+5.4,3.4,1.7,0.2,Iris-setosa
+5.1,3.7,1.5,0.4,Iris-setosa
+4.6,3.6,1.0,0.2,Iris-setosa
+5.1,3.3,1.7,0.5,Iris-setosa
+4.8,3.4,1.9,0.2,Iris-setosa
+5.0,3.0,1.6,0.2,Iris-setosa
+5.0,3.4,1.6,0.4,Iris-setosa
+5.2,3.5,1.5,0.2,Iris-setosa
+5.2,3.4,1.4,0.2,Iris-setosa
+4.7,3.2,1.6,0.2,Iris-setosa
+4.8,3.1,1.6,0.2,Iris-setosa
+5.4,3.4,1.5,0.4,Iris-setosa
+5.2,4.1,1.5,0.1,Iris-setosa
+5.5,4.2,1.4,0.2,Iris-setosa
+4.9,3.1,1.5,0.1,Iris-setosa
+5.0,3.2,1.2,0.2,Iris-setosa
+5.5,3.5,1.3,0.2,Iris-setosa
+4.9,3.1,1.5,0.1,Iris-setosa
+4.4,3.0,1.3,0.2,Iris-setosa
+5.1,3.4,1.5,0.2,Iris-setosa
+5.0,3.5,1.3,0.3,Iris-setosa
+4.5,2.3,1.3,0.3,Iris-setosa
+4.4,3.2,1.3,0.2,Iris-setosa
+5.0,3.5,1.6,0.6,Iris-setosa
+5.1,3.8,1.9,0.4,Iris-setosa
+4.8,3.0,1.4,0.3,Iris-setosa
+5.1,3.8,1.6,0.2,Iris-setosa
+4.6,3.2,1.4,0.2,Iris-setosa
+5.3,3.7,1.5,0.2,Iris-setosa
+5.0,3.3,1.4,0.2,Iris-setosa
+7.0,3.2,4.7,1.4,Iris-versicolor
+6.4,3.2,4.5,1.5,Iris-versicolor
+6.9,3.1,4.9,1.5,Iris-versicolor
+5.5,2.3,4.0,1.3,Iris-versicolor
+6.5,2.8,4.6,1.5,Iris-versicolor
+5.7,2.8,4.5,1.3,Iris-versicolor
+6.3,3.3,4.7,1.6,Iris-versicolor
+4.9,2.4,3.3,1.0,Iris-versicolor
+6.6,2.9,4.6,1.3,Iris-versicolor
+5.2,2.7,3.9,1.4,Iris-versicolor
+5.0,2.0,3.5,1.0,Iris-versicolor
+5.9,3.0,4.2,1.5,Iris-versicolor
+6.0,2.2,4.0,1.0,Iris-versicolor
+6.1,2.9,4.7,1.4,Iris-versicolor
+5.6,2.9,3.6,1.3,Iris-versicolor
+6.7,3.1,4.4,1.4,Iris-versicolor
+5.6,3.0,4.5,1.5,Iris-versicolor
+5.8,2.7,4.1,1.0,Iris-versicolor
+6.2,2.2,4.5,1.5,Iris-versicolor
+5.6,2.5,3.9,1.1,Iris-versicolor
+5.9,3.2,4.8,1.8,Iris-versicolor
+6.1,2.8,4.0,1.3,Iris-versicolor
+6.3,2.5,4.9,1.5,Iris-versicolor
+6.1,2.8,4.7,1.2,Iris-versicolor
+6.4,2.9,4.3,1.3,Iris-versicolor
+6.6,3.0,4.4,1.4,Iris-versicolor
+6.8,2.8,4.8,1.4,Iris-versicolor
+6.7,3.0,5.0,1.7,Iris-versicolor
+6.0,2.9,4.5,1.5,Iris-versicolor
+5.7,2.6,3.5,1.0,Iris-versicolor
+5.5,2.4,3.8,1.1,Iris-versicolor
+5.5,2.4,3.7,1.0,Iris-versicolor
+5.8,2.7,3.9,1.2,Iris-versicolor
+6.0,2.7,5.1,1.6,Iris-versicolor
+5.4,3.0,4.5,1.5,Iris-versicolor
+6.0,3.4,4.5,1.6,Iris-versicolor
+6.7,3.1,4.7,1.5,Iris-versicolor
+6.3,2.3,4.4,1.3,Iris-versicolor
+5.6,3.0,4.1,1.3,Iris-versicolor
+5.5,2.5,4.0,1.3,Iris-versicolor
+5.5,2.6,4.4,1.2,Iris-versicolor
+6.1,3.0,4.6,1.4,Iris-versicolor
+5.8,2.6,4.0,1.2,Iris-versicolor
+5.0,2.3,3.3,1.0,Iris-versicolor
+5.6,2.7,4.2,1.3,Iris-versicolor
+5.7,3.0,4.2,1.2,Iris-versicolor
+5.7,2.9,4.2,1.3,Iris-versicolor
+6.2,2.9,4.3,1.3,Iris-versicolor
+5.1,2.5,3.0,1.1,Iris-versicolor
+5.7,2.8,4.1,1.3,Iris-versicolor
+6.3,3.3,6.0,2.5,Iris-virginica
+5.8,2.7,5.1,1.9,Iris-virginica
+7.1,3.0,5.9,2.1,Iris-virginica
+6.3,2.9,5.6,1.8,Iris-virginica
+6.5,3.0,5.8,2.2,Iris-virginica
+7.6,3.0,6.6,2.1,Iris-virginica
+4.9,2.5,4.5,1.7,Iris-virginica
+7.3,2.9,6.3,1.8,Iris-virginica
+6.7,2.5,5.8,1.8,Iris-virginica
+7.2,3.6,6.1,2.5,Iris-virginica
+6.5,3.2,5.1,2.0,Iris-virginica
+6.4,2.7,5.3,1.9,Iris-virginica
+6.8,3.0,5.5,2.1,Iris-virginica
+5.7,2.5,5.0,2.0,Iris-virginica
+5.8,2.8,5.1,2.4,Iris-virginica
+6.4,3.2,5.3,2.3,Iris-virginica
+6.5,3.0,5.5,1.8,Iris-virginica
+7.7,3.8,6.7,2.2,Iris-virginica
+7.7,2.6,6.9,2.3,Iris-virginica
+6.0,2.2,5.0,1.5,Iris-virginica
+6.9,3.2,5.7,2.3,Iris-virginica
+5.6,2.8,4.9,2.0,Iris-virginica
+7.7,2.8,6.7,2.0,Iris-virginica
+6.3,2.7,4.9,1.8,Iris-virginica
+6.7,3.3,5.7,2.1,Iris-virginica
+7.2,3.2,6.0,1.8,Iris-virginica
+6.2,2.8,4.8,1.8,Iris-virginica
+6.1,3.0,4.9,1.8,Iris-virginica
+6.4,2.8,5.6,2.1,Iris-virginica
+7.2,3.0,5.8,1.6,Iris-virginica
+7.4,2.8,6.1,1.9,Iris-virginica
+7.9,3.8,6.4,2.0,Iris-virginica
+6.4,2.8,5.6,2.2,Iris-virginica
+6.3,2.8,5.1,1.5,Iris-virginica
+6.1,2.6,5.6,1.4,Iris-virginica
+7.7,3.0,6.1,2.3,Iris-virginica
+6.3,3.4,5.6,2.4,Iris-virginica
+6.4,3.1,5.5,1.8,Iris-virginica
+6.0,3.0,4.8,1.8,Iris-virginica
+6.9,3.1,5.4,2.1,Iris-virginica
+6.7,3.1,5.6,2.4,Iris-virginica
+6.9,3.1,5.1,2.3,Iris-virginica
+5.8,2.7,5.1,1.9,Iris-virginica
+6.8,3.2,5.9,2.3,Iris-virginica
+6.7,3.3,5.7,2.5,Iris-virginica
+6.7,3.0,5.2,2.3,Iris-virginica
+6.3,2.5,5.0,1.9,Iris-virginica
+6.5,3.0,5.2,2.0,Iris-virginica
+6.2,3.4,5.4,2.3,Iris-virginica
+5.9,3.0,5.1,1.8,Iris-virginica
diff --git a/examples/iris.rs b/examples/iris.rs
new file mode 100644
index 0000000..25ab373
--- /dev/null
+++ b/examples/iris.rs
@@ -0,0 +1,137 @@
+///
+/// This example parses, sorts and groups the iris dataset
+/// and does some simple manipulations.
+///
+/// Iterators and itertools functionality are used throughout.
+
+use itertools::Itertools;
+use std::collections::HashMap;
+use std::iter::repeat;
+use std::num::ParseFloatError;
+use std::str::FromStr;
+
+static DATA: &'static str = include_str!("iris.data");
+
+#[derive(Clone, Debug)]
+struct Iris {
+    name: String,
+    data: [f32; 4],
+}
+
+#[derive(Clone, Debug)]
+enum ParseError {
+    Numeric(ParseFloatError),
+    Other(&'static str),
+}
+
+impl From<ParseFloatError> for ParseError {
+    fn from(err: ParseFloatError) -> Self {
+        ParseError::Numeric(err)
+    }
+}
+
+/// Parse an Iris from a comma-separated line
+impl FromStr for Iris {
+    type Err = ParseError;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        let mut iris = Iris { name: "".into(), data: [0.; 4] };
+        let mut parts = s.split(",").map(str::trim);
+
+        // using Iterator::by_ref()
+        for (index, part) in parts.by_ref().take(4).enumerate() {
+            iris.data[index] = part.parse::<f32>()?;
+        }
+        if let Some(name) = parts.next() {
+            iris.name = name.into();
+        } else {
+            return Err(ParseError::Other("Missing name"))
+        }
+        Ok(iris)
+    }
+}
+
+fn main() {
+    // using Itertools::fold_results to create the result of parsing
+    let irises = DATA.lines()
+                     .map(str::parse)
+                     .fold_results(Vec::new(), |mut v, iris: Iris| {
+                         v.push(iris);
+                         v
+                     });
+    let mut irises = match irises {
+        Err(e) => {
+            println!("Error parsing: {:?}", e);
+            std::process::exit(1);
+        }
+        Ok(data) => data,
+    };
+
+    // Sort them and group them
+    irises.sort_by(|a, b| Ord::cmp(&a.name, &b.name));
+
+    // using Iterator::cycle()
+    let mut plot_symbols = "+ox".chars().cycle();
+    let mut symbolmap = HashMap::new();
+
+    // using Itertools::group_by
+    for (species, species_group) in &irises.iter().group_by(|iris| &iris.name) {
+        // assign a plot symbol
+        symbolmap.entry(species).or_insert_with(|| {
+            plot_symbols.next().unwrap()
+        });
+        println!("{} (symbol={})", species, symbolmap[species]);
+
+        for iris in species_group {
+            // using Itertools::format for lazy formatting
+            println!("{:>3.1}", iris.data.iter().format(", "));
+        }
+
+    }
+
+    // Look at all combinations of the four columns
+    //
+    // See https://en.wikipedia.org/wiki/Iris_flower_data_set
+    //
+    let n = 30; // plot size
+    let mut plot = vec![' '; n * n];
+
+    // using Itertools::tuple_combinations
+    for (a, b) in (0..4).tuple_combinations() {
+        println!("Column {} vs {}:", a, b);
+
+        // Clear plot
+        //
+        // using std::iter::repeat;
+        // using Itertools::set_from
+        plot.iter_mut().set_from(repeat(' '));
+
+        // using Itertools::minmax
+        let min_max = |data: &[Iris], col| {
+            data.iter()
+                .map(|iris| iris.data[col])
+                .minmax()
+                .into_option()
+                .expect("Can't find min/max of empty iterator")
+        };
+        let (min_x, max_x) = min_max(&irises, a);
+        let (min_y, max_y) = min_max(&irises, b);
+
+        // Plot the data points
+        let round_to_grid = |x, min, max| ((x - min) / (max - min) * ((n - 1) as f32)) as usize;
+        let flip = |ix| n - 1 - ix; // reverse axis direction
+
+        for iris in &irises {
+            let ix = round_to_grid(iris.data[a], min_x, max_x);
+            let iy = flip(round_to_grid(iris.data[b], min_y, max_y));
+            plot[n * iy + ix] = symbolmap[&iris.name];
+        }
+
+        // render plot
+        //
+        // using Itertools::join
+        for line in plot.chunks(n) {
+            println!("{}", line.iter().join(" "))
+        }
+    }
+}
diff --git a/src/adaptors/mod.rs b/src/adaptors/mod.rs
new file mode 100644
index 0000000..7d61f11
--- /dev/null
+++ b/src/adaptors/mod.rs
@@ -0,0 +1,1260 @@
+//! Licensed under the Apache License, Version 2.0
+//! http://www.apache.org/licenses/LICENSE-2.0 or the MIT license
+//! http://opensource.org/licenses/MIT, at your
+//! option. This file may not be copied, modified, or distributed
+//! except according to those terms.
+
+mod multi_product;
+#[cfg(feature = "use_std")]
+pub use self::multi_product::*;
+
+use std::fmt;
+use std::mem::replace;
+use std::iter::{Fuse, Peekable, FromIterator};
+use std::marker::PhantomData;
+use crate::size_hint;
+
+/// An iterator adaptor that alternates elements from two iterators until both
+/// run out.
+///
+/// This iterator is *fused*.
+///
+/// See [`.interleave()`](../trait.Itertools.html#method.interleave) for more information.
+#[derive(Clone, Debug)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Interleave<I, J> {
+    a: Fuse<I>,
+    b: Fuse<J>,
+    flag: bool,
+}
+
+/// Create an iterator that interleaves elements in `i` and `j`.
+///
+/// `IntoIterator` enabled version of `i.interleave(j)`.
+///
+/// ```
+/// use itertools::interleave;
+///
+/// for elt in interleave(&[1, 2, 3], &[2, 3, 4]) {
+///     /* loop body */
+/// }
+/// ```
+pub fn interleave<I, J>(i: I, j: J) -> Interleave<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter>
+    where I: IntoIterator,
+          J: IntoIterator<Item = I::Item>
+{
+    Interleave {
+        a: i.into_iter().fuse(),
+        b: j.into_iter().fuse(),
+        flag: false,
+    }
+}
+
+impl<I, J> Iterator for Interleave<I, J>
+    where I: Iterator,
+          J: Iterator<Item = I::Item>
+{
+    type Item = I::Item;
+    #[inline]
+    fn next(&mut self) -> Option<I::Item> {
+        self.flag = !self.flag;
+        if self.flag {
+            match self.a.next() {
+                None => self.b.next(),
+                r => r,
+            }
+        } else {
+            match self.b.next() {
+                None => self.a.next(),
+                r => r,
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        size_hint::add(self.a.size_hint(), self.b.size_hint())
+    }
+}
+
+/// An iterator adaptor that alternates elements from the two iterators until
+/// one of them runs out.
+///
+/// This iterator is *fused*.
+///
+/// See [`.interleave_shortest()`](../trait.Itertools.html#method.interleave_shortest)
+/// for more information.
+#[derive(Clone, Debug)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct InterleaveShortest<I, J>
+    where I: Iterator,
+          J: Iterator<Item = I::Item>
+{
+    it0: I,
+    it1: J,
+    phase: bool, // false ==> it0, true ==> it1
+}
+
+/// Create a new `InterleaveShortest` iterator.
+pub fn interleave_shortest<I, J>(a: I, b: J) -> InterleaveShortest<I, J>
+    where I: Iterator,
+          J: Iterator<Item = I::Item>
+{
+    InterleaveShortest {
+        it0: a,
+        it1: b,
+        phase: false,
+    }
+}
+
+impl<I, J> Iterator for InterleaveShortest<I, J>
+    where I: Iterator,
+          J: Iterator<Item = I::Item>
+{
+    type Item = I::Item;
+
+    #[inline]
+    fn next(&mut self) -> Option<I::Item> {
+        match self.phase {
+            false => match self.it0.next() {
+                None => None,
+                e => {
+                    self.phase = true;
+                    e
+                }
+            },
+            true => match self.it1.next() {
+                None => None,
+                e => {
+                    self.phase = false;
+                    e
+                }
+            },
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let (curr_hint, next_hint) = {
+            let it0_hint = self.it0.size_hint();
+            let it1_hint = self.it1.size_hint();
+            if self.phase {
+                (it1_hint, it0_hint)
+            } else {
+                (it0_hint, it1_hint)
+            }
+        };
+        let (curr_lower, curr_upper) = curr_hint;
+        let (next_lower, next_upper) = next_hint;
+        let (combined_lower, combined_upper) =
+            size_hint::mul_scalar(size_hint::min(curr_hint, next_hint), 2);
+        let lower =
+            if curr_lower > next_lower {
+                combined_lower + 1
+            } else {
+                combined_lower
+            };
+        let upper = {
+            let extra_elem = match (curr_upper, next_upper) {
+                (_, None) => false,
+                (None, Some(_)) => true,
+                (Some(curr_max), Some(next_max)) => curr_max > next_max,
+            };
+            if extra_elem {
+                combined_upper.and_then(|x| x.checked_add(1))
+            } else {
+                combined_upper
+            }
+        };
+        (lower, upper)
+    }
+}
+
+#[derive(Clone, Debug)]
+/// An iterator adaptor that allows putting back a single
+/// item to the front of the iterator.
+///
+/// Iterator element type is `I::Item`.
+pub struct PutBack<I>
+    where I: Iterator
+{
+    top: Option<I::Item>,
+    iter: I,
+}
+
+/// Create an iterator where you can put back a single item
+pub fn put_back<I>(iterable: I) -> PutBack<I::IntoIter>
+    where I: IntoIterator
+{
+    PutBack {
+        top: None,
+        iter: iterable.into_iter(),
+    }
+}
+
+impl<I> PutBack<I>
+    where I: Iterator
+{
+    /// put back value `value` (builder method)
+    pub fn with_value(mut self, value: I::Item) -> Self {
+        self.put_back(value);
+        self
+    }
+
+    /// Split the `PutBack` into its parts.
+    #[inline]
+    pub fn into_parts(self) -> (Option<I::Item>, I) {
+        let PutBack{top, iter} = self;
+        (top, iter)
+    }
+
+    /// Put back a single value to the front of the iterator.
+    ///
+    /// If a value is already in the put back slot, it is overwritten.
+    #[inline]
+    pub fn put_back(&mut self, x: I::Item) {
+        self.top = Some(x)
+    }
+}
+
+impl<I> Iterator for PutBack<I>
+    where I: Iterator
+{
+    type Item = I::Item;
+    #[inline]
+    fn next(&mut self) -> Option<I::Item> {
+        match self.top {
+            None => self.iter.next(),
+            ref mut some => some.take(),
+        }
+    }
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        // Not ExactSizeIterator because size may be larger than usize
+        size_hint::add_scalar(self.iter.size_hint(), self.top.is_some() as usize)
+    }
+
+    fn count(self) -> usize {
+        self.iter.count() + (self.top.is_some() as usize)
+    }
+
+    fn last(self) -> Option<Self::Item> {
+        self.iter.last().or(self.top)
+    }
+
+    fn nth(&mut self, n: usize) -> Option<Self::Item> {
+        match self.top {
+            None => self.iter.nth(n),
+            ref mut some => {
+                if n == 0 {
+                    some.take()
+                } else {
+                    *some = None;
+                    self.iter.nth(n - 1)
+                }
+            }
+        }
+    }
+
+    fn all<G>(&mut self, mut f: G) -> bool
+        where G: FnMut(Self::Item) -> bool
+    {
+        if let Some(elt) = self.top.take() {
+            if !f(elt) {
+                return false;
+            }
+        }
+        self.iter.all(f)
+    }
+
+    fn fold<Acc, G>(mut self, init: Acc, mut f: G) -> Acc
+        where G: FnMut(Acc, Self::Item) -> Acc,
+    {
+        let mut accum = init;
+        if let Some(elt) = self.top.take() {
+            accum = f(accum, elt);
+        }
+        self.iter.fold(accum, f)
+    }
+}
+
+#[derive(Debug, Clone)]
+/// An iterator adaptor that iterates over the cartesian product of
+/// the element sets of two iterators `I` and `J`.
+///
+/// Iterator element type is `(I::Item, J::Item)`.
+///
+/// See [`.cartesian_product()`](../trait.Itertools.html#method.cartesian_product) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Product<I, J>
+    where I: Iterator
+{
+    a: I,
+    a_cur: Option<I::Item>,
+    b: J,
+    b_orig: J,
+}
+
+/// Create a new cartesian product iterator
+///
+/// Iterator element type is `(I::Item, J::Item)`.
+pub fn cartesian_product<I, J>(mut i: I, j: J) -> Product<I, J>
+    where I: Iterator,
+          J: Clone + Iterator,
+          I::Item: Clone
+{
+    Product {
+        a_cur: i.next(),
+        a: i,
+        b: j.clone(),
+        b_orig: j,
+    }
+}
+
+
+impl<I, J> Iterator for Product<I, J>
+    where I: Iterator,
+          J: Clone + Iterator,
+          I::Item: Clone
+{
+    type Item = (I::Item, J::Item);
+    fn next(&mut self) -> Option<(I::Item, J::Item)> {
+        let elt_b = match self.b.next() {
+            None => {
+                self.b = self.b_orig.clone();
+                match self.b.next() {
+                    None => return None,
+                    Some(x) => {
+                        self.a_cur = self.a.next();
+                        x
+                    }
+                }
+            }
+            Some(x) => x
+        };
+        match self.a_cur {
+            None => None,
+            Some(ref a) => {
+                Some((a.clone(), elt_b))
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let has_cur = self.a_cur.is_some() as usize;
+        // Not ExactSizeIterator because size may be larger than usize
+        let (b_min, b_max) = self.b.size_hint();
+
+        // Compute a * b_orig + b for both lower and upper bound
+        size_hint::add(
+            size_hint::mul(self.a.size_hint(), self.b_orig.size_hint()),
+            (b_min * has_cur, b_max.map(move |x| x * has_cur)))
+    }
+
+    fn fold<Acc, G>(mut self, mut accum: Acc, mut f: G) -> Acc
+        where G: FnMut(Acc, Self::Item) -> Acc,
+    {
+        // use a split loop to handle the loose a_cur as well as avoiding to
+        // clone b_orig at the end.
+        if let Some(mut a) = self.a_cur.take() {
+            let mut b = self.b;
+            loop {
+                accum = b.fold(accum, |acc, elt| f(acc, (a.clone(), elt)));
+
+                // we can only continue iterating a if we had a first element;
+                if let Some(next_a) = self.a.next() {
+                    b = self.b_orig.clone();
+                    a = next_a;
+                } else {
+                    break;
+                }
+            }
+        }
+        accum
+    }
+}
+
+/// A “meta iterator adaptor”. Its closure receives a reference to the iterator
+/// and may pick off as many elements as it likes, to produce the next iterator element.
+///
+/// Iterator element type is *X*, if the return type of `F` is *Option\<X\>*.
+///
+/// See [`.batching()`](../trait.Itertools.html#method.batching) for more information.
+#[derive(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Batching<I, F> {
+    f: F,
+    iter: I,
+}
+
+impl<I, F> fmt::Debug for Batching<I, F> where I: fmt::Debug {
+    debug_fmt_fields!(Batching, iter);
+}
+
+/// Create a new Batching iterator.
+pub fn batching<I, F>(iter: I, f: F) -> Batching<I, F> {
+    Batching { f, iter }
+}
+
+impl<B, F, I> Iterator for Batching<I, F>
+    where I: Iterator,
+          F: FnMut(&mut I) -> Option<B>
+{
+    type Item = B;
+    #[inline]
+    fn next(&mut self) -> Option<B> {
+        (self.f)(&mut self.iter)
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        // No information about closue behavior
+        (0, None)
+    }
+}
+
+/// An iterator adaptor that steps a number elements in the base iterator
+/// for each iteration.
+///
+/// The iterator steps by yielding the next element from the base iterator,
+/// then skipping forward *n-1* elements.
+///
+/// See [`.step()`](../trait.Itertools.html#method.step) for more information.
+#[deprecated(note="Use std .step_by() instead", since="0.8")]
+#[allow(deprecated)]
+#[derive(Clone, Debug)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Step<I> {
+    iter: Fuse<I>,
+    skip: usize,
+}
+
+/// Create a `Step` iterator.
+///
+/// **Panics** if the step is 0.
+#[allow(deprecated)]
+pub fn step<I>(iter: I, step: usize) -> Step<I>
+    where I: Iterator
+{
+    assert!(step != 0);
+    Step {
+        iter: iter.fuse(),
+        skip: step - 1,
+    }
+}
+
+#[allow(deprecated)]
+impl<I> Iterator for Step<I>
+    where I: Iterator
+{
+    type Item = I::Item;
+    #[inline]
+    fn next(&mut self) -> Option<I::Item> {
+        let elt = self.iter.next();
+        if self.skip > 0 {
+            self.iter.nth(self.skip - 1);
+        }
+        elt
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let (low, high) = self.iter.size_hint();
+        let div = |x: usize| {
+            if x == 0 {
+                0
+            } else {
+                1 + (x - 1) / (self.skip + 1)
+            }
+        };
+        (div(low), high.map(div))
+    }
+}
+
+// known size
+#[allow(deprecated)]
+impl<I> ExactSizeIterator for Step<I>
+    where I: ExactSizeIterator
+{}
+
+pub trait MergePredicate<T> {
+    fn merge_pred(&mut self, a: &T, b: &T) -> bool;
+}
+
+#[derive(Clone)]
+pub struct MergeLte;
+
+impl<T: PartialOrd> MergePredicate<T> for MergeLte {
+    fn merge_pred(&mut self, a: &T, b: &T) -> bool {
+        a <= b
+    }
+}
+
+/// An iterator adaptor that merges the two base iterators in ascending order.
+/// If both base iterators are sorted (ascending), the result is sorted.
+///
+/// Iterator element type is `I::Item`.
+///
+/// See [`.merge()`](../trait.Itertools.html#method.merge_by) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub type Merge<I, J> = MergeBy<I, J, MergeLte>;
+
+/// Create an iterator that merges elements in `i` and `j`.
+///
+/// `IntoIterator` enabled version of `i.merge(j)`.
+///
+/// ```
+/// use itertools::merge;
+///
+/// for elt in merge(&[1, 2, 3], &[2, 3, 4]) {
+///     /* loop body */
+/// }
+/// ```
+pub fn merge<I, J>(i: I, j: J) -> Merge<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter>
+    where I: IntoIterator,
+          J: IntoIterator<Item = I::Item>,
+          I::Item: PartialOrd
+{
+    merge_by_new(i, j, MergeLte)
+}
+
+/// An iterator adaptor that merges the two base iterators in ascending order.
+/// If both base iterators are sorted (ascending), the result is sorted.
+///
+/// Iterator element type is `I::Item`.
+///
+/// See [`.merge_by()`](../trait.Itertools.html#method.merge_by) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct MergeBy<I, J, F>
+    where I: Iterator,
+          J: Iterator<Item = I::Item>
+{
+    a: Peekable<I>,
+    b: Peekable<J>,
+    fused: Option<bool>,
+    cmp: F,
+}
+
+impl<I, J, F> fmt::Debug for MergeBy<I, J, F>
+    where I: Iterator + fmt::Debug, J: Iterator<Item = I::Item> + fmt::Debug,
+          I::Item: fmt::Debug,
+{
+    debug_fmt_fields!(MergeBy, a, b);
+}
+
+impl<T, F: FnMut(&T, &T)->bool> MergePredicate<T> for F {
+    fn merge_pred(&mut self, a: &T, b: &T) -> bool {
+        self(a, b)
+    }
+}
+
+/// Create a `MergeBy` iterator.
+pub fn merge_by_new<I, J, F>(a: I, b: J, cmp: F) -> MergeBy<I::IntoIter, J::IntoIter, F>
+    where I: IntoIterator,
+          J: IntoIterator<Item = I::Item>,
+          F: MergePredicate<I::Item>,
+{
+    MergeBy {
+        a: a.into_iter().peekable(),
+        b: b.into_iter().peekable(),
+        fused: None,
+        cmp,
+    }
+}
+
+impl<I, J, F> Clone for MergeBy<I, J, F>
+    where I: Iterator,
+          J: Iterator<Item = I::Item>,
+          Peekable<I>: Clone,
+          Peekable<J>: Clone,
+          F: Clone
+{
+    clone_fields!(a, b, fused, cmp);
+}
+
+impl<I, J, F> Iterator for MergeBy<I, J, F>
+    where I: Iterator,
+          J: Iterator<Item = I::Item>,
+          F: MergePredicate<I::Item>
+{
+    type Item = I::Item;
+
+    fn next(&mut self) -> Option<I::Item> {
+        let less_than = match self.fused {
+            Some(lt) => lt,
+            None => match (self.a.peek(), self.b.peek()) {
+                (Some(a), Some(b)) => self.cmp.merge_pred(a, b),
+                (Some(_), None) => {
+                    self.fused = Some(true);
+                    true
+                }
+                (None, Some(_)) => {
+                    self.fused = Some(false);
+                    false
+                }
+                (None, None) => return None,
+            }
+        };
+        if less_than {
+            self.a.next()
+        } else {
+            self.b.next()
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        // Not ExactSizeIterator because size may be larger than usize
+        size_hint::add(self.a.size_hint(), self.b.size_hint())
+    }
+}
+
+#[derive(Clone, Debug)]
+pub struct CoalesceCore<I>
+    where I: Iterator
+{
+    iter: I,
+    last: Option<I::Item>,
+}
+
+impl<I> CoalesceCore<I>
+    where I: Iterator
+{
+    fn next_with<F>(&mut self, mut f: F) -> Option<I::Item>
+        where F: FnMut(I::Item, I::Item) -> Result<I::Item, (I::Item, I::Item)>
+    {
+        // this fuses the iterator
+        let mut last = match self.last.take() {
+            None => return None,
+            Some(x) => x,
+        };
+        for next in &mut self.iter {
+            match f(last, next) {
+                Ok(joined) => last = joined,
+                Err((last_, next_)) => {
+                    self.last = Some(next_);
+                    return Some(last_);
+                }
+            }
+        }
+
+        Some(last)
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let (low, hi) = size_hint::add_scalar(self.iter.size_hint(),
+                                              self.last.is_some() as usize);
+        ((low > 0) as usize, hi)
+    }
+}
+
+/// An iterator adaptor that may join together adjacent elements.
+///
+/// See [`.coalesce()`](../trait.Itertools.html#method.coalesce) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Coalesce<I, F>
+    where I: Iterator
+{
+    iter: CoalesceCore<I>,
+    f: F,
+}
+
+impl<I: Clone, F: Clone> Clone for Coalesce<I, F>
+    where I: Iterator,
+          I::Item: Clone
+{
+    clone_fields!(iter, f);
+}
+
+impl<I, F> fmt::Debug for Coalesce<I, F>
+    where I: Iterator + fmt::Debug,
+          I::Item: fmt::Debug,
+{
+    debug_fmt_fields!(Coalesce, iter);
+}
+
+/// Create a new `Coalesce`.
+pub fn coalesce<I, F>(mut iter: I, f: F) -> Coalesce<I, F>
+    where I: Iterator
+{
+    Coalesce {
+        iter: CoalesceCore {
+            last: iter.next(),
+            iter,
+        },
+        f,
+    }
+}
+
+impl<I, F> Iterator for Coalesce<I, F>
+    where I: Iterator,
+          F: FnMut(I::Item, I::Item) -> Result<I::Item, (I::Item, I::Item)>
+{
+    type Item = I::Item;
+
+    fn next(&mut self) -> Option<I::Item> {
+        self.iter.next_with(&mut self.f)
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+}
+
+/// An iterator adaptor that removes repeated duplicates, determining equality using a comparison function.
+///
+/// See [`.dedup_by()`](../trait.Itertools.html#method.dedup_by) or [`.dedup()`](../trait.Itertools.html#method.dedup) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct DedupBy<I, Pred>
+    where I: Iterator
+{
+    iter: CoalesceCore<I>,
+    dedup_pred: Pred,
+}
+
+pub trait DedupPredicate<T> { // TODO replace by Fn(&T, &T)->bool once Rust supports it
+    fn dedup_pair(&mut self, a: &T, b: &T) -> bool;
+}
+
+#[derive(Clone)]
+pub struct DedupEq;
+
+impl<T: PartialEq> DedupPredicate<T> for DedupEq {
+    fn dedup_pair(&mut self, a: &T, b: &T) -> bool {
+        a==b
+    }
+}
+
+impl<T, F: FnMut(&T, &T)->bool> DedupPredicate<T> for F {
+    fn dedup_pair(&mut self, a: &T, b: &T) -> bool {
+        self(a, b)
+    }
+}
+
+/// An iterator adaptor that removes repeated duplicates.
+///
+/// See [`.dedup()`](../trait.Itertools.html#method.dedup) for more information.
+pub type Dedup<I>=DedupBy<I, DedupEq>;
+
+impl<I: Clone, Pred: Clone> Clone for DedupBy<I, Pred>
+    where I: Iterator,
+          I::Item: Clone,
+{
+    clone_fields!(iter, dedup_pred);
+}
+
+/// Create a new `DedupBy`.
+pub fn dedup_by<I, Pred>(mut iter: I, dedup_pred: Pred) -> DedupBy<I, Pred>
+    where I: Iterator,
+{
+    DedupBy {
+        iter: CoalesceCore {
+            last: iter.next(),
+            iter,
+        },
+        dedup_pred,
+    }
+}
+
+/// Create a new `Dedup`.
+pub fn dedup<I>(iter: I) -> Dedup<I>
+    where I: Iterator
+{
+    dedup_by(iter, DedupEq)
+}
+
+impl<I, Pred> fmt::Debug for DedupBy<I, Pred>
+    where I: Iterator + fmt::Debug,
+          I::Item: fmt::Debug,
+{
+    debug_fmt_fields!(Dedup, iter);
+}
+
+impl<I, Pred> Iterator for DedupBy<I, Pred>
+    where I: Iterator,
+          Pred: DedupPredicate<I::Item>,
+{
+    type Item = I::Item;
+
+    fn next(&mut self) -> Option<I::Item> {
+        let ref mut dedup_pred = self.dedup_pred;
+        self.iter.next_with(|x, y| {
+            if dedup_pred.dedup_pair(&x, &y) { Ok(x) } else { Err((x, y)) }
+        })
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+
+    fn fold<Acc, G>(self, mut accum: Acc, mut f: G) -> Acc
+        where G: FnMut(Acc, Self::Item) -> Acc,
+    {
+        if let Some(mut last) = self.iter.last {
+            let mut dedup_pred = self.dedup_pred;
+            accum = self.iter.iter.fold(accum, |acc, elt| {
+                if dedup_pred.dedup_pair(&elt, &last) {
+                    acc
+                } else {
+                    f(acc, replace(&mut last, elt))
+                }
+            });
+            f(accum, last)
+        } else {
+            accum
+        }
+    }
+}
+
+/// An iterator adaptor that borrows from a `Clone`-able iterator
+/// to only pick off elements while the predicate returns `true`.
+///
+/// See [`.take_while_ref()`](../trait.Itertools.html#method.take_while_ref) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct TakeWhileRef<'a, I: 'a, F> {
+    iter: &'a mut I,
+    f: F,
+}
+
+impl<'a, I, F> fmt::Debug for TakeWhileRef<'a, I, F>
+    where I: Iterator + fmt::Debug,
+{
+    debug_fmt_fields!(TakeWhileRef, iter);
+}
+
+/// Create a new `TakeWhileRef` from a reference to clonable iterator.
+pub fn take_while_ref<I, F>(iter: &mut I, f: F) -> TakeWhileRef<I, F>
+    where I: Iterator + Clone
+{
+    TakeWhileRef { iter, f }
+}
+
+impl<'a, I, F> Iterator for TakeWhileRef<'a, I, F>
+    where I: Iterator + Clone,
+          F: FnMut(&I::Item) -> bool
+{
+    type Item = I::Item;
+
+    fn next(&mut self) -> Option<I::Item> {
+        let old = self.iter.clone();
+        match self.iter.next() {
+            None => None,
+            Some(elt) => {
+                if (self.f)(&elt) {
+                    Some(elt)
+                } else {
+                    *self.iter = old;
+                    None
+                }
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let (_, hi) = self.iter.size_hint();
+        (0, hi)
+    }
+}
+
+/// An iterator adaptor that filters `Option<A>` iterator elements
+/// and produces `A`. Stops on the first `None` encountered.
+///
+/// See [`.while_some()`](../trait.Itertools.html#method.while_some) for more information.
+#[derive(Clone, Debug)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct WhileSome<I> {
+    iter: I,
+}
+
+/// Create a new `WhileSome<I>`.
+pub fn while_some<I>(iter: I) -> WhileSome<I> {
+    WhileSome { iter }
+}
+
+impl<I, A> Iterator for WhileSome<I>
+    where I: Iterator<Item = Option<A>>
+{
+    type Item = A;
+
+    fn next(&mut self) -> Option<A> {
+        match self.iter.next() {
+            None | Some(None) => None,
+            Some(elt) => elt,
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let sh = self.iter.size_hint();
+        (0, sh.1)
+    }
+}
+
+/// An iterator to iterate through all combinations in a `Clone`-able iterator that produces tuples
+/// of a specific size.
+///
+/// See [`.tuple_combinations()`](../trait.Itertools.html#method.tuple_combinations) for more
+/// information.
+#[derive(Clone, Debug)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct TupleCombinations<I, T>
+    where I: Iterator,
+          T: HasCombination<I>
+{
+    iter: T::Combination,
+    _mi: PhantomData<I>,
+    _mt: PhantomData<T>
+}
+
+pub trait HasCombination<I>: Sized {
+    type Combination: From<I> + Iterator<Item = Self>;
+}
+
+/// Create a new `TupleCombinations` from a clonable iterator.
+pub fn tuple_combinations<T, I>(iter: I) -> TupleCombinations<I, T>
+    where I: Iterator + Clone,
+          I::Item: Clone,
+          T: HasCombination<I>,
+{
+    TupleCombinations {
+        iter: T::Combination::from(iter),
+        _mi: PhantomData,
+        _mt: PhantomData,
+    }
+}
+
+impl<I, T> Iterator for TupleCombinations<I, T>
+    where I: Iterator,
+          T: HasCombination<I>,
+{
+    type Item = T;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.iter.next()
+    }
+}
+
+#[derive(Clone, Debug)]
+pub struct Tuple1Combination<I> {
+    iter: I,
+}
+
+impl<I> From<I> for Tuple1Combination<I> {
+    fn from(iter: I) -> Self {
+        Tuple1Combination { iter }
+    }
+}
+
+impl<I: Iterator> Iterator for Tuple1Combination<I> {
+    type Item = (I::Item,);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.iter.next().map(|x| (x,))
+    }
+}
+
+impl<I: Iterator> HasCombination<I> for (I::Item,) {
+    type Combination = Tuple1Combination<I>;
+}
+
+macro_rules! impl_tuple_combination {
+    ($C:ident $P:ident ; $A:ident, $($I:ident),* ; $($X:ident)*) => (
+        #[derive(Clone, Debug)]
+        pub struct $C<I: Iterator> {
+            item: Option<I::Item>,
+            iter: I,
+            c: $P<I>,
+        }
+
+        impl<I: Iterator + Clone> From<I> for $C<I> {
+            fn from(mut iter: I) -> Self {
+                $C {
+                    item: iter.next(),
+                    iter: iter.clone(),
+                    c: $P::from(iter),
+                }
+            }
+        }
+
+        impl<I: Iterator + Clone> From<I> for $C<Fuse<I>> {
+            fn from(iter: I) -> Self {
+                let mut iter = iter.fuse();
+                $C {
+                    item: iter.next(),
+                    iter: iter.clone(),
+                    c: $P::from(iter),
+                }
+            }
+        }
+
+        impl<I, $A> Iterator for $C<I>
+            where I: Iterator<Item = $A> + Clone,
+                  I::Item: Clone
+        {
+            type Item = ($($I),*);
+
+            fn next(&mut self) -> Option<Self::Item> {
+                if let Some(($($X),*,)) = self.c.next() {
+                    let z = self.item.clone().unwrap();
+                    Some((z, $($X),*))
+                } else {
+                    self.item = self.iter.next();
+                    self.item.clone().and_then(|z| {
+                        self.c = $P::from(self.iter.clone());
+                        self.c.next().map(|($($X),*,)| (z, $($X),*))
+                    })
+                }
+            }
+        }
+
+        impl<I, $A> HasCombination<I> for ($($I),*)
+            where I: Iterator<Item = $A> + Clone,
+                  I::Item: Clone
+        {
+            type Combination = $C<Fuse<I>>;
+        }
+    )
+}
+
+impl_tuple_combination!(Tuple2Combination Tuple1Combination ; A, A, A ; a);
+impl_tuple_combination!(Tuple3Combination Tuple2Combination ; A, A, A, A ; a b);
+impl_tuple_combination!(Tuple4Combination Tuple3Combination ; A, A, A, A, A; a b c);
+
+/// An iterator adapter to apply `Into` conversion to each element.
+///
+/// See [`.map_into()`](../trait.Itertools.html#method.map_into) for more information.
+#[derive(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct MapInto<I, R> {
+    iter: I,
+    _res: PhantomData<fn() -> R>,
+}
+
+/// Create a new [`MapInto`](struct.MapInto.html) iterator.
+pub fn map_into<I, R>(iter: I) -> MapInto<I, R> {
+    MapInto {
+        iter,
+        _res: PhantomData,
+    }
+}
+
+impl<I, R> Iterator for MapInto<I, R>
+    where I: Iterator,
+          I::Item: Into<R>,
+{
+    type Item = R;
+
+    fn next(&mut self) -> Option<R> {
+        self.iter
+            .next()
+            .map(|i| i.into())
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+
+    fn fold<Acc, Fold>(self, init: Acc, mut fold_f: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        self.iter.fold(init, move |acc, v| fold_f(acc, v.into()))
+    }
+}
+
+impl<I, R> DoubleEndedIterator for MapInto<I, R>
+    where I: DoubleEndedIterator,
+          I::Item: Into<R>,
+{
+    fn next_back(&mut self) -> Option<Self::Item> {
+        self.iter
+            .next_back()
+            .map(|i| i.into())
+    }
+}
+
+impl<I, R> ExactSizeIterator for MapInto<I, R>
+where
+    I: ExactSizeIterator,
+    I::Item: Into<R>,
+{}
+
+/// An iterator adapter to apply a transformation within a nested `Result`.
+///
+/// See [`.map_results()`](../trait.Itertools.html#method.map_results) for more information.
+#[derive(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct MapResults<I, F> {
+    iter: I,
+    f: F
+}
+
+/// Create a new `MapResults` iterator.
+pub fn map_results<I, F, T, U, E>(iter: I, f: F) -> MapResults<I, F>
+    where I: Iterator<Item = Result<T, E>>,
+          F: FnMut(T) -> U,
+{
+    MapResults {
+        iter,
+        f,
+    }
+}
+
+impl<I, F, T, U, E> Iterator for MapResults<I, F>
+    where I: Iterator<Item = Result<T, E>>,
+          F: FnMut(T) -> U,
+{
+    type Item = Result<U, E>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.iter.next().map(|v| v.map(&mut self.f))
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+
+    fn fold<Acc, Fold>(self, init: Acc, mut fold_f: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        let mut f = self.f;
+        self.iter.fold(init, move |acc, v| fold_f(acc, v.map(&mut f)))
+    }
+
+    fn collect<C>(self) -> C
+        where C: FromIterator<Self::Item>
+    {
+        let mut f = self.f;
+        self.iter.map(move |v| v.map(&mut f)).collect()
+    }
+}
+
+/// An iterator adapter to get the positions of each element that matches a predicate.
+///
+/// See [`.positions()`](../trait.Itertools.html#method.positions) for more information.
+#[derive(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Positions<I, F> {
+    iter: I,
+    f: F,
+    count: usize,
+}
+
+/// Create a new `Positions` iterator.
+pub fn positions<I, F>(iter: I, f: F) -> Positions<I, F>
+    where I: Iterator,
+          F: FnMut(I::Item) -> bool,
+{
+    Positions {
+        iter,
+        f,
+        count: 0
+    }
+}
+
+impl<I, F> Iterator for Positions<I, F>
+    where I: Iterator,
+          F: FnMut(I::Item) -> bool,
+{
+    type Item = usize;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        while let Some(v) = self.iter.next() {
+            let i = self.count;
+            self.count = i + 1;
+            if (self.f)(v) {
+                return Some(i);
+            }
+        }
+        None
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (0, self.iter.size_hint().1)
+    }
+}
+
+impl<I, F> DoubleEndedIterator for Positions<I, F>
+    where I: DoubleEndedIterator + ExactSizeIterator,
+          F: FnMut(I::Item) -> bool,
+{
+    fn next_back(&mut self) -> Option<Self::Item> {
+        while let Some(v) = self.iter.next_back() {
+            if (self.f)(v) {
+                return Some(self.count + self.iter.len())
+            }
+        }
+        None
+    }
+}
+
+/// An iterator adapter to apply a mutating function to each element before yielding it.
+///
+/// See [`.update()`](../trait.Itertools.html#method.update) for more information.
+#[derive(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Update<I, F> {
+    iter: I,
+    f: F,
+}
+
+/// Create a new `Update` iterator.
+pub fn update<I, F>(iter: I, f: F) -> Update<I, F>
+where
+    I: Iterator,
+    F: FnMut(&mut I::Item),
+{
+    Update { iter, f }
+}
+
+impl<I, F> Iterator for Update<I, F>
+where
+    I: Iterator,
+    F: FnMut(&mut I::Item),
+{
+    type Item = I::Item;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if let Some(mut v) = self.iter.next() {
+            (self.f)(&mut v);
+            Some(v)
+        } else {
+            None
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+
+    fn fold<Acc, G>(self, init: Acc, mut g: G) -> Acc
+        where G: FnMut(Acc, Self::Item) -> Acc,
+    {
+        let mut f = self.f;
+        self.iter.fold(init, move |acc, mut v| { f(&mut v); g(acc, v) })
+    }
+
+    // if possible, re-use inner iterator specializations in collect
+    fn collect<C>(self) -> C
+        where C: FromIterator<Self::Item>
+    {
+        let mut f = self.f;
+        self.iter.map(move |mut v| { f(&mut v); v }).collect()
+    }
+}
+
+impl<I, F> ExactSizeIterator for Update<I, F>
+where
+    I: ExactSizeIterator,
+    F: FnMut(&mut I::Item),
+{}
+
+impl<I, F> DoubleEndedIterator for Update<I, F>
+where
+    I: DoubleEndedIterator,
+    F: FnMut(&mut I::Item),
+{
+    fn next_back(&mut self) -> Option<Self::Item> {
+        if let Some(mut v) = self.iter.next_back() {
+            (self.f)(&mut v);
+            Some(v)
+        } else {
+            None
+        }
+    }
+}
diff --git a/src/adaptors/multi_product.rs b/src/adaptors/multi_product.rs
new file mode 100644
index 0000000..4a31713
--- /dev/null
+++ b/src/adaptors/multi_product.rs
@@ -0,0 +1,220 @@
+#![cfg(feature = "use_std")]
+
+use crate::size_hint;
+use crate::Itertools;
+
+#[derive(Clone)]
+/// An iterator adaptor that iterates over the cartesian product of
+/// multiple iterators of type `I`.
+///
+/// An iterator element type is `Vec<I>`.
+///
+/// See [`.multi_cartesian_product()`](../trait.Itertools.html#method.multi_cartesian_product)
+/// for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct MultiProduct<I>(Vec<MultiProductIter<I>>)
+    where I: Iterator + Clone,
+          I::Item: Clone;
+
+/// Create a new cartesian product iterator over an arbitrary number
+/// of iterators of the same type.
+///
+/// Iterator element is of type `Vec<H::Item::Item>`.
+pub fn multi_cartesian_product<H>(iters: H) -> MultiProduct<<H::Item as IntoIterator>::IntoIter>
+    where H: Iterator,
+          H::Item: IntoIterator,
+          <H::Item as IntoIterator>::IntoIter: Clone,
+          <H::Item as IntoIterator>::Item: Clone
+{
+    MultiProduct(iters.map(|i| MultiProductIter::new(i.into_iter())).collect())
+}
+
+#[derive(Clone, Debug)]
+/// Holds the state of a single iterator within a MultiProduct.
+struct MultiProductIter<I>
+    where I: Iterator + Clone,
+          I::Item: Clone
+{
+    cur: Option<I::Item>,
+    iter: I,
+    iter_orig: I,
+}
+
+/// Holds the current state during an iteration of a MultiProduct.
+#[derive(Debug)]
+enum MultiProductIterState {
+    StartOfIter,
+    MidIter { on_first_iter: bool },
+}
+
+impl<I> MultiProduct<I>
+    where I: Iterator + Clone,
+          I::Item: Clone
+{
+    /// Iterates the rightmost iterator, then recursively iterates iterators
+    /// to the left if necessary.
+    ///
+    /// Returns true if the iteration succeeded, else false.
+    fn iterate_last(
+        multi_iters: &mut [MultiProductIter<I>],
+        mut state: MultiProductIterState
+    ) -> bool {
+        use self::MultiProductIterState::*;
+
+        if let Some((last, rest)) = multi_iters.split_last_mut() {
+            let on_first_iter = match state {
+                StartOfIter => {
+                    let on_first_iter = !last.in_progress();
+                    state = MidIter { on_first_iter };
+                    on_first_iter
+                },
+                MidIter { on_first_iter } => on_first_iter
+            };
+
+            if !on_first_iter {
+                last.iterate();
+            }
+
+            if last.in_progress() {
+                true
+            } else if MultiProduct::iterate_last(rest, state) {
+                last.reset();
+                last.iterate();
+                // If iterator is None twice consecutively, then iterator is
+                // empty; whole product is empty.
+                last.in_progress()
+            } else {
+                false
+            }
+        } else {
+            // Reached end of iterator list. On initialisation, return true.
+            // At end of iteration (final iterator finishes), finish.
+            match state {
+                StartOfIter => false,
+                MidIter { on_first_iter } => on_first_iter
+            }
+        }
+    }
+
+    /// Returns the unwrapped value of the next iteration.
+    fn curr_iterator(&self) -> Vec<I::Item> {
+        self.0.iter().map(|multi_iter| {
+            multi_iter.cur.clone().unwrap()
+        }).collect()
+    }
+
+    /// Returns true if iteration has started and has not yet finished; false
+    /// otherwise.
+    fn in_progress(&self) -> bool {
+        if let Some(last) = self.0.last() {
+            last.in_progress()
+        } else {
+            false
+        }
+    }
+}
+
+impl<I> MultiProductIter<I>
+    where I: Iterator + Clone,
+          I::Item: Clone
+{
+    fn new(iter: I) -> Self {
+        MultiProductIter {
+            cur: None,
+            iter: iter.clone(),
+            iter_orig: iter
+        }
+    }
+
+    /// Iterate the managed iterator.
+    fn iterate(&mut self) {
+        self.cur = self.iter.next();
+    }
+
+    /// Reset the managed iterator.
+    fn reset(&mut self) {
+        self.iter = self.iter_orig.clone();
+    }
+
+    /// Returns true if the current iterator has been started and has not yet
+    /// finished; false otherwise.
+    fn in_progress(&self) -> bool {
+        self.cur.is_some()
+    }
+}
+
+impl<I> Iterator for MultiProduct<I>
+    where I: Iterator + Clone,
+          I::Item: Clone
+{
+    type Item = Vec<I::Item>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if MultiProduct::iterate_last(
+            &mut self.0,
+            MultiProductIterState::StartOfIter
+        ) {
+            Some(self.curr_iterator())
+        } else {
+            None
+        }
+    }
+
+    fn count(self) -> usize {
+        if self.0.len() == 0 {
+            return 0;
+        }
+
+        if !self.in_progress() {
+            return self.0.into_iter().fold(1, |acc, multi_iter| {
+                acc * multi_iter.iter.count()
+            });
+        }
+
+        self.0.into_iter().fold(
+            0,
+            |acc, MultiProductIter { iter, iter_orig, cur: _ }| {
+                let total_count = iter_orig.count();
+                let cur_count = iter.count();
+                acc * total_count + cur_count
+            }
+        )
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        // Not ExactSizeIterator because size may be larger than usize
+        if self.0.len() == 0 {
+            return (0, Some(0));
+        }
+
+        if !self.in_progress() {
+            return self.0.iter().fold((1, Some(1)), |acc, multi_iter| {
+                size_hint::mul(acc, multi_iter.iter.size_hint())
+            });
+        }
+
+        self.0.iter().fold(
+            (0, Some(0)),
+            |acc, &MultiProductIter { ref iter, ref iter_orig, cur: _ }| {
+                let cur_size = iter.size_hint();
+                let total_size = iter_orig.size_hint();
+                size_hint::add(size_hint::mul(acc, total_size), cur_size)
+            }
+        )
+    }
+
+    fn last(self) -> Option<Self::Item> {
+        let iter_count = self.0.len();
+
+        let lasts: Self::Item = self.0.into_iter()
+            .map(|multi_iter| multi_iter.iter.last())
+            .while_some()
+            .collect();
+
+        if lasts.len() == iter_count {
+            Some(lasts)
+        } else {
+            None
+        }
+    }
+}
diff --git a/src/combinations.rs b/src/combinations.rs
new file mode 100644
index 0000000..8759518
--- /dev/null
+++ b/src/combinations.rs
@@ -0,0 +1,89 @@
+use std::fmt;
+
+use super::lazy_buffer::LazyBuffer;
+
+/// An iterator to iterate through all the `k`-length combinations in an iterator.
+///
+/// See [`.combinations()`](../trait.Itertools.html#method.combinations) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Combinations<I: Iterator> {
+    indices: Vec<usize>,
+    pool: LazyBuffer<I>,
+    first: bool,
+}
+
+impl<I> Clone for Combinations<I>
+    where I: Clone + Iterator,
+          I::Item: Clone,
+{
+    clone_fields!(indices, pool, first);
+}
+
+impl<I> fmt::Debug for Combinations<I>
+    where I: Iterator + fmt::Debug,
+          I::Item: fmt::Debug,
+{
+    debug_fmt_fields!(Combinations, indices, pool, first);
+}
+
+/// Create a new `Combinations` from a clonable iterator.
+pub fn combinations<I>(iter: I, k: usize) -> Combinations<I>
+    where I: Iterator
+{
+    let mut pool: LazyBuffer<I> = LazyBuffer::new(iter);
+
+    for _ in 0..k {
+        if !pool.get_next() {
+            break;
+        }
+    }
+
+    Combinations {
+        indices: (0..k).collect(),
+        pool,
+        first: true,
+    }
+}
+
+impl<I> Iterator for Combinations<I>
+    where I: Iterator,
+          I::Item: Clone
+{
+    type Item = Vec<I::Item>;
+    fn next(&mut self) -> Option<Self::Item> {
+        if self.first {
+            if self.pool.is_done() {
+                return None;
+            }
+            self.first = false;
+        } else if self.indices.len() == 0 {
+            return None;
+        } else {
+            // Scan from the end, looking for an index to increment
+            let mut i: usize = self.indices.len() - 1;
+
+            // Check if we need to consume more from the iterator
+            if self.indices[i] == self.pool.len() - 1 {
+                self.pool.get_next(); // may change pool size
+            }
+
+            while self.indices[i] == i + self.pool.len() - self.indices.len() {
+                if i > 0 {
+                    i -= 1;
+                } else {
+                    // Reached the last combination
+                    return None;
+                }
+            }
+
+            // Increment index, and reset the ones to its right
+            self.indices[i] += 1;
+            for j in i+1..self.indices.len() {
+                self.indices[j] = self.indices[j - 1] + 1;
+            }
+        }
+
+        // Create result vector based on the indices
+        Some(self.indices.iter().map(|i| self.pool[*i].clone()).collect())
+    }
+}
diff --git a/src/combinations_with_replacement.rs b/src/combinations_with_replacement.rs
new file mode 100644
index 0000000..d511545
--- /dev/null
+++ b/src/combinations_with_replacement.rs
@@ -0,0 +1,107 @@
+use std::fmt;
+
+use super::lazy_buffer::LazyBuffer;
+
+/// An iterator to iterate through all the `n`-length combinations in an iterator, with replacement.
+///
+/// See [`.combinations_with_replacement()`](../trait.Itertools.html#method.combinations_with_replacement) for more information.
+#[derive(Clone)]
+pub struct CombinationsWithReplacement<I>
+where
+    I: Iterator,
+    I::Item: Clone,
+{
+    k: usize,
+    indices: Vec<usize>,
+    // The current known max index value. This increases as pool grows.
+    max_index: usize,
+    pool: LazyBuffer<I>,
+    first: bool,
+}
+
+impl<I> fmt::Debug for CombinationsWithReplacement<I>
+where
+    I: Iterator + fmt::Debug,
+    I::Item: fmt::Debug + Clone,
+{
+    debug_fmt_fields!(Combinations, k, indices, max_index, pool, first);
+}
+
+impl<I> CombinationsWithReplacement<I>
+where
+    I: Iterator,
+    I::Item: Clone,
+{
+    /// Map the current mask over the pool to get an output combination
+    fn current(&self) -> Vec<I::Item> {
+        self.indices.iter().map(|i| self.pool[*i].clone()).collect()
+    }
+}
+
+/// Create a new `CombinationsWithReplacement` from a clonable iterator.
+pub fn combinations_with_replacement<I>(iter: I, k: usize) -> CombinationsWithReplacement<I>
+where
+    I: Iterator,
+    I::Item: Clone,
+{
+    let indices: Vec<usize> = vec![0; k];
+    let pool: LazyBuffer<I> = LazyBuffer::new(iter);
+
+    CombinationsWithReplacement {
+        k,
+        indices,
+        max_index: 0,
+        pool,
+        first: true,
+    }
+}
+
+impl<I> Iterator for CombinationsWithReplacement<I>
+where
+    I: Iterator,
+    I::Item: Clone,
+{
+    type Item = Vec<I::Item>;
+    fn next(&mut self) -> Option<Self::Item> {
+        // If this is the first iteration, return early
+        if self.first {
+            // In empty edge cases, stop iterating immediately
+            return if self.k != 0 && !self.pool.get_next() {
+                None
+            // Otherwise, yield the initial state
+            } else {
+                self.first = false;
+                Some(self.current())
+            };
+        }
+
+        // Check if we need to consume more from the iterator
+        // This will run while we increment our first index digit
+        if self.pool.get_next() {
+            self.max_index = self.pool.len() - 1;
+        }
+
+        // Work out where we need to update our indices
+        let mut increment: Option<(usize, usize)> = None;
+        for (i, indices_int) in self.indices.iter().enumerate().rev() {
+            if indices_int < &self.max_index {
+                increment = Some((i, indices_int + 1));
+                break;
+            }
+        }
+
+        match increment {
+            // If we can update the indices further
+            Some((increment_from, increment_value)) => {
+                // We need to update the rightmost non-max value
+                // and all those to the right
+                for indices_index in increment_from..self.indices.len() {
+                    self.indices[indices_index] = increment_value
+                }
+                Some(self.current())
+            }
+            // Otherwise, we're done
+            None => None,
+        }
+    }
+}
diff --git a/src/concat_impl.rs b/src/concat_impl.rs
new file mode 100644
index 0000000..6048d18
--- /dev/null
+++ b/src/concat_impl.rs
@@ -0,0 +1,22 @@
+use crate::Itertools;
+
+/// Combine all an iterator's elements into one element by using `Extend`.
+///
+/// `IntoIterator`-enabled version of `.concat()`
+///
+/// This combinator will extend the first item with each of the rest of the
+/// items of the iterator. If the iterator is empty, the default value of
+/// `I::Item` is returned.
+///
+/// ```rust
+/// use itertools::concat;
+/// 
+/// let input = vec![vec![1], vec![2, 3], vec![4, 5, 6]];
+/// assert_eq!(concat(input), vec![1, 2, 3, 4, 5, 6]);
+/// ```
+pub fn concat<I>(iterable: I) -> I::Item
+    where I: IntoIterator,
+          I::Item: Extend<<<I as IntoIterator>::Item as IntoIterator>::Item> + IntoIterator + Default
+{
+    iterable.into_iter().fold1(|mut a, b| { a.extend(b); a }).unwrap_or_else(|| <_>::default())
+}
diff --git a/src/cons_tuples_impl.rs b/src/cons_tuples_impl.rs
new file mode 100644
index 0000000..3cdfe0d
--- /dev/null
+++ b/src/cons_tuples_impl.rs
@@ -0,0 +1,64 @@
+
+macro_rules! impl_cons_iter(
+    ($_A:ident, $_B:ident, ) => (); // stop
+
+    ($A:ident, $($B:ident,)*) => (
+        impl_cons_iter!($($B,)*);
+        #[allow(non_snake_case)]
+        impl<X, Iter, $($B),*> Iterator for ConsTuples<Iter, (($($B,)*), X)>
+            where Iter: Iterator<Item = (($($B,)*), X)>,
+        {
+            type Item = ($($B,)* X, );
+            fn next(&mut self) -> Option<Self::Item> {
+                self.iter.next().map(|(($($B,)*), x)| ($($B,)* x, ))
+            }
+
+            fn size_hint(&self) -> (usize, Option<usize>) {
+                self.iter.size_hint()
+            }
+            fn fold<Acc, Fold>(self, accum: Acc, mut f: Fold) -> Acc
+                where Fold: FnMut(Acc, Self::Item) -> Acc,
+            {
+                self.iter.fold(accum, move |acc, (($($B,)*), x)| f(acc, ($($B,)* x, )))
+            }
+        }
+
+        #[allow(non_snake_case)]
+        impl<X, Iter, $($B),*> DoubleEndedIterator for ConsTuples<Iter, (($($B,)*), X)>
+            where Iter: DoubleEndedIterator<Item = (($($B,)*), X)>,
+        {
+            fn next_back(&mut self) -> Option<Self::Item> {
+                self.iter.next().map(|(($($B,)*), x)| ($($B,)* x, ))
+            }
+        }
+
+    );
+);
+
+impl_cons_iter!(A, B, C, D, E, F, G, H,);
+
+/// An iterator that maps an iterator of tuples like
+/// `((A, B), C)` to an iterator of `(A, B, C)`.
+///
+/// Used by the `iproduct!()` macro.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[derive(Debug)]
+pub struct ConsTuples<I, J>
+    where I: Iterator<Item=J>,
+{
+    iter: I,
+}
+
+impl<I, J> Clone for ConsTuples<I, J>
+    where I: Clone + Iterator<Item=J>,
+{
+    clone_fields!(iter);
+}
+
+/// Create an iterator that maps for example iterators of
+/// `((A, B), C)` to `(A, B, C)`.
+pub fn cons_tuples<I, J>(iterable: I) -> ConsTuples<I, J>
+    where I: Iterator<Item=J>
+{
+    ConsTuples { iter: iterable.into_iter() }
+}
diff --git a/src/diff.rs b/src/diff.rs
new file mode 100644
index 0000000..c196d8d
--- /dev/null
+++ b/src/diff.rs
@@ -0,0 +1,61 @@
+//! "Diff"ing iterators for caching elements to sequential collections without requiring the new
+//! elements' iterator to be `Clone`.
+//!
+//! - [**Diff**](./enum.Diff.html) (produced by the [**diff_with**](./fn.diff_with.html) function)
+//! describes the difference between two non-`Clone` iterators `I` and `J` after breaking ASAP from
+//! a lock-step comparison.
+
+use crate::free::put_back;
+use crate::structs::PutBack;
+
+/// A type returned by the [`diff_with`](./fn.diff_with.html) function.
+///
+/// `Diff` represents the way in which the elements yielded by the iterator `I` differ to some
+/// iterator `J`.
+pub enum Diff<I, J>
+    where I: Iterator,
+          J: Iterator
+{
+    /// The index of the first non-matching element along with both iterator's remaining elements
+    /// starting with the first mis-match.
+    FirstMismatch(usize, PutBack<I>, PutBack<J>),
+    /// The total number of elements that were in `J` along with the remaining elements of `I`.
+    Shorter(usize, PutBack<I>),
+    /// The total number of elements that were in `I` along with the remaining elements of `J`.
+    Longer(usize, PutBack<J>),
+}
+
+/// Compares every element yielded by both `i` and `j` with the given function in lock-step and
+/// returns a `Diff` which describes how `j` differs from `i`.
+///
+/// If the number of elements yielded by `j` is less than the number of elements yielded by `i`,
+/// the number of `j` elements yielded will be returned along with `i`'s remaining elements as
+/// `Diff::Shorter`.
+///
+/// If the two elements of a step differ, the index of those elements along with the remaining
+/// elements of both `i` and `j` are returned as `Diff::FirstMismatch`.
+///
+/// If `i` becomes exhausted before `j` becomes exhausted, the number of elements in `i` along with
+/// the remaining `j` elements will be returned as `Diff::Longer`.
+pub fn diff_with<I, J, F>(i: I, j: J, is_equal: F)
+    -> Option<Diff<I::IntoIter, J::IntoIter>>
+    where I: IntoIterator,
+          J: IntoIterator,
+          F: Fn(&I::Item, &J::Item) -> bool
+{
+    let mut i = i.into_iter();
+    let mut j = j.into_iter();
+    let mut idx = 0;
+    while let Some(i_elem) = i.next() {
+        match j.next() {
+            None => return Some(Diff::Shorter(idx, put_back(i).with_value(i_elem))),
+            Some(j_elem) => if !is_equal(&i_elem, &j_elem) {
+                let remaining_i = put_back(i).with_value(i_elem);
+                let remaining_j = put_back(j).with_value(j_elem);
+                return Some(Diff::FirstMismatch(idx, remaining_i, remaining_j));
+            },
+        }
+        idx += 1;
+    }
+    j.next().map(|j_elem| Diff::Longer(idx, put_back(j).with_value(j_elem)))
+}
diff --git a/src/either_or_both.rs b/src/either_or_both.rs
new file mode 100644
index 0000000..a03a4f1
--- /dev/null
+++ b/src/either_or_both.rs
@@ -0,0 +1,190 @@
+use crate::EitherOrBoth::*;
+
+use either::Either;
+
+/// Value that either holds a single A or B, or both.
+#[derive(Clone, PartialEq, Eq, Hash, Debug)]
+pub enum EitherOrBoth<A, B> {
+    /// Both values are present.
+    Both(A, B),
+    /// Only the left value of type `A` is present.
+    Left(A),
+    /// Only the right value of type `B` is present.
+    Right(B),
+}
+
+impl<A, B> EitherOrBoth<A, B> {
+    /// If `Left`, or `Both`, return true, otherwise, return false.
+    pub fn has_left(&self) -> bool {
+        self.as_ref().left().is_some()
+    }
+
+    /// If `Right`, or `Both`, return true, otherwise, return false.
+    pub fn has_right(&self) -> bool {
+        self.as_ref().right().is_some()
+    }
+
+    /// If Left, return true otherwise, return false.
+    /// Exclusive version of [`has_left`].
+    pub fn is_left(&self) -> bool {
+        match *self {
+            Left(_) => true,
+            _ => false,
+        }
+    }
+
+    /// If Right, return true otherwise, return false.
+    /// Exclusive version of [`has_right`].
+    pub fn is_right(&self) -> bool {
+        match *self {
+            Right(_) => true,
+            _ => false,
+        }
+    }
+
+    /// If Right, return true otherwise, return false.
+    /// Equivalent to `self.as_ref().both().is_some()`.
+    pub fn is_both(&self) -> bool {
+        self.as_ref().both().is_some()
+    }
+
+    /// If `Left`, or `Both`, return `Some` with the left value, otherwise, return `None`.
+    pub fn left(self) -> Option<A> {
+        match self {
+            Left(left) | Both(left, _) => Some(left),
+            _ => None,
+        }
+    }
+
+    /// If `Right`, or `Both`, return `Some` with the right value, otherwise, return `None`.
+    pub fn right(self) -> Option<B> {
+        match self {
+            Right(right) | Both(_, right) => Some(right),
+            _ => None,
+        }
+    }
+
+    /// If Both, return `Some` tuple containing left and right.
+    pub fn both(self) -> Option<(A, B)> {
+        match self {
+            Both(a, b) => Some((a, b)),
+            _ => None,
+        }
+    }
+
+    /// Converts from `&EitherOrBoth<A, B>` to `EitherOrBoth<&A, &B>`.
+    pub fn as_ref(&self) -> EitherOrBoth<&A, &B> {
+        match *self {
+            Left(ref left) => Left(left),
+            Right(ref right) => Right(right),
+            Both(ref left, ref right) => Both(left, right),
+        }
+    }
+
+    /// Converts from `&mut EitherOrBoth<A, B>` to `EitherOrBoth<&mut A, &mut B>`.
+    pub fn as_mut(&mut self) -> EitherOrBoth<&mut A, &mut B> {
+        match *self {
+            Left(ref mut left) => Left(left),
+            Right(ref mut right) => Right(right),
+            Both(ref mut left, ref mut right) => Both(left, right),
+        }
+    }
+
+    /// Convert `EitherOrBoth<A, B>` to `EitherOrBoth<B, A>`.
+    pub fn flip(self) -> EitherOrBoth<B, A> {
+        match self {
+            Left(a) => Right(a),
+            Right(b) => Left(b),
+            Both(a, b) => Both(b, a),
+        }
+    }
+
+    /// Apply the function `f` on the value `a` in `Left(a)` or `Both(a, b)` variants. If it is
+    /// present rewrapping the result in `self`'s original variant.
+    pub fn map_left<F, M>(self, f: F) -> EitherOrBoth<M, B>
+    where
+        F: FnOnce(A) -> M,
+    {
+        match self {
+            Both(a, b) => Both(f(a), b),
+            Left(a) => Left(f(a)),
+            Right(b) => Right(b),
+        }
+    }
+
+    /// Apply the function `f` on the value `b` in `Right(b)` or `Both(a, b)` variants.
+    /// If it is present rewrapping the result in `self`'s original variant.
+    pub fn map_right<F, M>(self, f: F) -> EitherOrBoth<A, M>
+    where
+        F: FnOnce(B) -> M,
+    {
+        match self {
+            Left(a) => Left(a),
+            Right(b) => Right(f(b)),
+            Both(a, b) => Both(a, f(b)),
+        }
+    }
+
+    /// Apply the functions `f` and `g` on the value `a` and `b` respectively;
+    /// found in `Left(a)`, `Right(b)`, or `Both(a, b)` variants.
+    /// The Result is rewrapped `self`'s original variant.
+    pub fn map_any<F, L, G, R>(self, f: F, g: G) -> EitherOrBoth<L, R>
+    where
+        F: FnOnce(A) -> L,
+        G: FnOnce(B) -> R,
+    {
+        match self {
+            Left(a) => Left(f(a)),
+            Right(b) => Right(g(b)),
+            Both(a, b) => Both(f(a), g(b)),
+        }
+    }
+
+    /// Apply the function `f` on the value `b` in `Right(b)` or `Both(a, _)` variants if it is
+    /// present.
+    pub fn left_and_then<F, L>(self, f: F) -> EitherOrBoth<L, B>
+    where
+        F: FnOnce(A) -> EitherOrBoth<L, B>,
+    {
+        match self {
+            Left(a) | Both(a, _) => f(a),
+            Right(b) => Right(b),
+        }
+    }
+
+    /// Apply the function `f` on the value `a`
+    /// in `Left(a)` or `Both(a, _)` variants if it is present.
+    pub fn right_and_then<F, R>(self, f: F) -> EitherOrBoth<A, R>
+    where
+        F: FnOnce(B) -> EitherOrBoth<A, R>,
+    {
+        match self {
+            Left(a) => Left(a),
+            Right(b) | Both(_, b) => f(b),
+        }
+    }
+}
+
+impl<T> EitherOrBoth<T, T> {
+    /// Return either value of left, right, or the product of `f` applied where `Both` are present.
+    pub fn reduce<F>(self, f: F) -> T
+    where
+        F: FnOnce(T, T) -> T,
+    {
+        match self {
+            Left(a) => a,
+            Right(b) => b,
+            Both(a, b) => f(a, b),
+        }
+    }
+}
+
+impl<A, B> Into<Option<Either<A, B>>> for EitherOrBoth<A, B> {
+    fn into(self) -> Option<Either<A, B>> {
+        match self {
+            EitherOrBoth::Left(l) => Some(Either::Left(l)),
+            EitherOrBoth::Right(r) => Some(Either::Right(r)),
+            _ => None,
+        }
+    }
+}
diff --git a/src/exactly_one_err.rs b/src/exactly_one_err.rs
new file mode 100644
index 0000000..e4925ff
--- /dev/null
+++ b/src/exactly_one_err.rs
@@ -0,0 +1,58 @@
+use std::iter::ExactSizeIterator;
+
+use crate::size_hint;
+
+/// Iterator returned for the error case of `IterTools::exactly_one()`
+/// This iterator yields exactly the same elements as the input iterator.
+///
+/// During the execution of exactly_one the iterator must be mutated.  This wrapper
+/// effectively "restores" the state of the input iterator when it's handed back.
+///
+/// This is very similar to PutBackN except this iterator only supports 0-2 elements and does not
+/// use a `Vec`.
+#[derive(Debug, Clone)]
+pub struct ExactlyOneError<I>
+where
+    I: Iterator,
+{
+    first_two: (Option<I::Item>, Option<I::Item>),
+    inner: I,
+}
+
+impl<I> ExactlyOneError<I>
+where
+    I: Iterator,
+{
+    /// Creates a new `ExactlyOneErr` iterator.
+    pub(crate) fn new(first_two: (Option<I::Item>, Option<I::Item>), inner: I) -> Self {
+        Self { first_two, inner }
+    }
+}
+
+impl<I> Iterator for ExactlyOneError<I>
+where
+    I: Iterator,
+{
+    type Item = I::Item;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.first_two
+            .0
+            .take()
+            .or_else(|| self.first_two.1.take())
+            .or_else(|| self.inner.next())
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let mut additional_len = 0;
+        if self.first_two.0.is_some() {
+            additional_len += 1;
+        }
+        if self.first_two.1.is_some() {
+            additional_len += 1;
+        }
+        size_hint::add_scalar(self.inner.size_hint(), additional_len)
+    }
+}
+
+impl<I> ExactSizeIterator for ExactlyOneError<I> where I: ExactSizeIterator {}
diff --git a/src/format.rs b/src/format.rs
new file mode 100644
index 0000000..f72ed39
--- /dev/null
+++ b/src/format.rs
@@ -0,0 +1,114 @@
+use std::fmt;
+use std::cell::RefCell;
+
+/// Format all iterator elements lazily, separated by `sep`.
+///
+/// The format value can only be formatted once, after that the iterator is
+/// exhausted.
+///
+/// See [`.format_with()`](../trait.Itertools.html#method.format_with) for more information.
+#[derive(Clone)]
+pub struct FormatWith<'a, I, F> {
+    sep: &'a str,
+    /// FormatWith uses interior mutability because Display::fmt takes &self.
+    inner: RefCell<Option<(I, F)>>,
+}
+
+/// Format all iterator elements lazily, separated by `sep`.
+///
+/// The format value can only be formatted once, after that the iterator is
+/// exhausted.
+///
+/// See [`.format()`](../trait.Itertools.html#method.format)
+/// for more information.
+#[derive(Clone)]
+pub struct Format<'a, I> {
+    sep: &'a str,
+    /// Format uses interior mutability because Display::fmt takes &self.
+    inner: RefCell<Option<I>>,
+}
+
+pub fn new_format<'a, I, F>(iter: I, separator: &'a str, f: F) -> FormatWith<'a, I, F>
+    where I: Iterator,
+          F: FnMut(I::Item, &mut dyn FnMut(&dyn fmt::Display) -> fmt::Result) -> fmt::Result
+{
+    FormatWith {
+        sep: separator,
+        inner: RefCell::new(Some((iter, f))),
+    }
+}
+
+pub fn new_format_default<'a, I>(iter: I, separator: &'a str) -> Format<'a, I>
+    where I: Iterator,
+{
+    Format {
+        sep: separator,
+        inner: RefCell::new(Some(iter)),
+    }
+}
+
+impl<'a, I, F> fmt::Display for FormatWith<'a, I, F>
+    where I: Iterator,
+          F: FnMut(I::Item, &mut dyn  FnMut(&dyn fmt::Display) -> fmt::Result) -> fmt::Result
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let (mut iter, mut format) = match self.inner.borrow_mut().take() {
+            Some(t) => t,
+            None => panic!("FormatWith: was already formatted once"),
+        };
+
+        if let Some(fst) = iter.next() {
+            format(fst, &mut |disp: &dyn fmt::Display| disp.fmt(f))?;
+            for elt in iter {
+                if self.sep.len() > 0 {
+
+                    f.write_str(self.sep)?;
+                }
+                format(elt, &mut |disp: &dyn fmt::Display| disp.fmt(f))?;
+            }
+        }
+        Ok(())
+    }
+}
+
+impl<'a, I> Format<'a, I>
+    where I: Iterator,
+{
+    fn format<F>(&self, f: &mut fmt::Formatter, mut cb: F) -> fmt::Result
+        where F: FnMut(&I::Item, &mut fmt::Formatter) -> fmt::Result,
+    {
+        let mut iter = match self.inner.borrow_mut().take() {
+            Some(t) => t,
+            None => panic!("Format: was already formatted once"),
+        };
+
+        if let Some(fst) = iter.next() {
+            cb(&fst, f)?;
+            for elt in iter {
+                if self.sep.len() > 0 {
+                    f.write_str(self.sep)?;
+                }
+                cb(&elt, f)?;
+            }
+        }
+        Ok(())
+    }
+}
+
+macro_rules! impl_format {
+    ($($fmt_trait:ident)*) => {
+        $(
+            impl<'a, I> fmt::$fmt_trait for Format<'a, I>
+                where I: Iterator,
+                      I::Item: fmt::$fmt_trait,
+            {
+                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+                    self.format(f, fmt::$fmt_trait::fmt)
+                }
+            }
+        )*
+    }
+}
+
+impl_format!{Display Debug
+             UpperExp LowerExp UpperHex LowerHex Octal Binary Pointer}
diff --git a/src/free.rs b/src/free.rs
new file mode 100644
index 0000000..a6bc1bd
--- /dev/null
+++ b/src/free.rs
@@ -0,0 +1,236 @@
+//! Free functions that create iterator adaptors or call iterator methods.
+//!
+//! The benefit of free functions is that they accept any `IntoIterator` as
+//! argument, so the resulting code may be easier to read.
+
+#[cfg(feature = "use_std")]
+use std::fmt::Display;
+use std::iter::{self, Zip};
+#[cfg(feature = "use_std")]
+type VecIntoIter<T> = ::std::vec::IntoIter<T>;
+
+#[cfg(feature = "use_std")]
+use crate::Itertools;
+
+pub use crate::adaptors::{
+    interleave,
+    merge,
+    put_back,
+};
+#[cfg(feature = "use_std")]
+pub use crate::put_back_n_impl::put_back_n;
+#[cfg(feature = "use_std")]
+pub use crate::multipeek_impl::multipeek;
+#[cfg(feature = "use_std")]
+pub use crate::kmerge_impl::kmerge;
+pub use crate::zip_eq_impl::zip_eq;
+pub use crate::merge_join::merge_join_by;
+#[cfg(feature = "use_std")]
+pub use crate::rciter_impl::rciter;
+
+/// Iterate `iterable` with a running index.
+///
+/// `IntoIterator` enabled version of `.enumerate()`.
+///
+/// ```
+/// use itertools::enumerate;
+///
+/// for (i, elt) in enumerate(&[1, 2, 3]) {
+///     /* loop body */
+/// }
+/// ```
+pub fn enumerate<I>(iterable: I) -> iter::Enumerate<I::IntoIter>
+    where I: IntoIterator
+{
+    iterable.into_iter().enumerate()
+}
+
+/// Iterate `iterable` in reverse.
+///
+/// `IntoIterator` enabled version of `.rev()`.
+///
+/// ```
+/// use itertools::rev;
+///
+/// for elt in rev(&[1, 2, 3]) {
+///     /* loop body */
+/// }
+/// ```
+pub fn rev<I>(iterable: I) -> iter::Rev<I::IntoIter>
+    where I: IntoIterator,
+          I::IntoIter: DoubleEndedIterator
+{
+    iterable.into_iter().rev()
+}
+
+/// Iterate `i` and `j` in lock step.
+///
+/// `IntoIterator` enabled version of `i.zip(j)`.
+///
+/// ```
+/// use itertools::zip;
+///
+/// let data = [1, 2, 3, 4, 5];
+/// for (a, b) in zip(&data, &data[1..]) {
+///     /* loop body */
+/// }
+/// ```
+pub fn zip<I, J>(i: I, j: J) -> Zip<I::IntoIter, J::IntoIter>
+    where I: IntoIterator,
+          J: IntoIterator
+{
+    i.into_iter().zip(j)
+}
+
+/// Create an iterator that first iterates `i` and then `j`.
+///
+/// `IntoIterator` enabled version of `i.chain(j)`.
+///
+/// ```
+/// use itertools::chain;
+///
+/// for elt in chain(&[1, 2, 3], &[4]) {
+///     /* loop body */
+/// }
+/// ```
+pub fn chain<I, J>(i: I, j: J) -> iter::Chain<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter>
+    where I: IntoIterator,
+          J: IntoIterator<Item = I::Item>
+{
+    i.into_iter().chain(j)
+}
+
+/// Create an iterator that clones each element from &T to T
+///
+/// `IntoIterator` enabled version of `i.cloned()`.
+///
+/// ```
+/// use itertools::cloned;
+///
+/// assert_eq!(cloned(b"abc").next(), Some(b'a'));
+/// ```
+pub fn cloned<'a, I, T: 'a>(iterable: I) -> iter::Cloned<I::IntoIter>
+    where I: IntoIterator<Item=&'a T>,
+          T: Clone,
+{
+    iterable.into_iter().cloned()
+}
+
+/// Perform a fold operation over the iterable.
+///
+/// `IntoIterator` enabled version of `i.fold(init, f)`
+///
+/// ```
+/// use itertools::fold;
+///
+/// assert_eq!(fold(&[1., 2., 3.], 0., |a, &b| f32::max(a, b)), 3.);
+/// ```
+pub fn fold<I, B, F>(iterable: I, init: B, f: F) -> B
+    where I: IntoIterator,
+          F: FnMut(B, I::Item) -> B
+{
+    iterable.into_iter().fold(init, f)
+}
+
+/// Test whether the predicate holds for all elements in the iterable.
+///
+/// `IntoIterator` enabled version of `i.all(f)`
+///
+/// ```
+/// use itertools::all;
+///
+/// assert!(all(&[1, 2, 3], |elt| *elt > 0));
+/// ```
+pub fn all<I, F>(iterable: I, f: F) -> bool
+    where I: IntoIterator,
+          F: FnMut(I::Item) -> bool
+{
+    iterable.into_iter().all(f)
+}
+
+/// Test whether the predicate holds for any elements in the iterable.
+///
+/// `IntoIterator` enabled version of `i.any(f)`
+///
+/// ```
+/// use itertools::any;
+///
+/// assert!(any(&[0, -1, 2], |elt| *elt > 0));
+/// ```
+pub fn any<I, F>(iterable: I, f: F) -> bool
+    where I: IntoIterator,
+          F: FnMut(I::Item) -> bool
+{
+    iterable.into_iter().any(f)
+}
+
+/// Return the maximum value of the iterable.
+///
+/// `IntoIterator` enabled version of `i.max()`.
+///
+/// ```
+/// use itertools::max;
+///
+/// assert_eq!(max(0..10), Some(9));
+/// ```
+pub fn max<I>(iterable: I) -> Option<I::Item>
+    where I: IntoIterator,
+          I::Item: Ord
+{
+    iterable.into_iter().max()
+}
+
+/// Return the minimum value of the iterable.
+///
+/// `IntoIterator` enabled version of `i.min()`.
+///
+/// ```
+/// use itertools::min;
+///
+/// assert_eq!(min(0..10), Some(0));
+/// ```
+pub fn min<I>(iterable: I) -> Option<I::Item>
+    where I: IntoIterator,
+          I::Item: Ord
+{
+    iterable.into_iter().min()
+}
+
+
+/// Combine all iterator elements into one String, seperated by `sep`.
+///
+/// `IntoIterator` enabled version of `iterable.join(sep)`.
+///
+/// ```
+/// use itertools::join;
+///
+/// assert_eq!(join(&[1, 2, 3], ", "), "1, 2, 3");
+/// ```
+#[cfg(feature = "use_std")]
+pub fn join<I>(iterable: I, sep: &str) -> String
+    where I: IntoIterator,
+          I::Item: Display
+{
+    iterable.into_iter().join(sep)
+}
+
+/// Sort all iterator elements into a new iterator in ascending order.
+///
+/// `IntoIterator` enabled version of [`iterable.sorted()`][1].
+///
+/// [1]: trait.Itertools.html#method.sorted
+///
+/// ```
+/// use itertools::sorted;
+/// use itertools::assert_equal;
+///
+/// assert_equal(sorted("rust".chars()), "rstu".chars());
+/// ```
+#[cfg(feature = "use_std")]
+pub fn sorted<I>(iterable: I) -> VecIntoIter<I::Item>
+    where I: IntoIterator,
+          I::Item: Ord
+{
+    iterable.into_iter().sorted()
+}
+
diff --git a/src/group_map.rs b/src/group_map.rs
new file mode 100644
index 0000000..be9f842
--- /dev/null
+++ b/src/group_map.rs
@@ -0,0 +1,22 @@
+#![cfg(feature = "use_std")]
+
+use std::collections::HashMap;
+use std::hash::Hash;
+use std::iter::Iterator;
+
+/// Return a `HashMap` of keys mapped to a list of their corresponding values.
+///
+/// See [`.into_group_map()`](../trait.Itertools.html#method.into_group_map)
+/// for more information.
+pub fn into_group_map<I, K, V>(iter: I) -> HashMap<K, Vec<V>>
+    where I: Iterator<Item=(K, V)>,
+          K: Hash + Eq,
+{
+    let mut lookup = HashMap::new();
+
+    for (key, val) in iter {
+        lookup.entry(key).or_insert(Vec::new()).push(val);
+    }
+
+    lookup
+}
\ No newline at end of file
diff --git a/src/groupbylazy.rs b/src/groupbylazy.rs
new file mode 100644
index 0000000..bf6e3c7
--- /dev/null
+++ b/src/groupbylazy.rs
@@ -0,0 +1,571 @@
+use std::cell::{Cell, RefCell};
+use std::vec;
+
+/// A trait to unify FnMut for GroupBy with the chunk key in IntoChunks
+trait KeyFunction<A> {
+    type Key;
+    fn call_mut(&mut self, arg: A) -> Self::Key;
+}
+
+impl<'a, A, K, F: ?Sized> KeyFunction<A> for F
+    where F: FnMut(A) -> K
+{
+    type Key = K;
+    #[inline]
+    fn call_mut(&mut self, arg: A) -> Self::Key {
+        (*self)(arg)
+    }
+}
+
+
+/// ChunkIndex acts like the grouping key function for IntoChunks
+#[derive(Debug)]
+struct ChunkIndex {
+    size: usize,
+    index: usize,
+    key: usize,
+}
+
+impl ChunkIndex {
+    #[inline(always)]
+    fn new(size: usize) -> Self {
+        ChunkIndex {
+            size,
+            index: 0,
+            key: 0,
+        }
+    }
+}
+
+impl<'a, A> KeyFunction<A> for ChunkIndex {
+    type Key = usize;
+    #[inline(always)]
+    fn call_mut(&mut self, _arg: A) -> Self::Key {
+        if self.index == self.size {
+            self.key += 1;
+            self.index = 0;
+        }
+        self.index += 1;
+        self.key
+    }
+}
+
+
+struct GroupInner<K, I, F>
+    where I: Iterator
+{
+    key: F,
+    iter: I,
+    current_key: Option<K>,
+    current_elt: Option<I::Item>,
+    /// flag set if iterator is exhausted
+    done: bool,
+    /// Index of group we are currently buffering or visiting
+    top_group: usize,
+    /// Least index for which we still have elements buffered
+    oldest_buffered_group: usize,
+    /// Group index for `buffer[0]` -- the slots
+    /// bottom_group..oldest_buffered_group are unused and will be erased when
+    /// that range is large enough.
+    bottom_group: usize,
+    /// Buffered groups, from `bottom_group` (index 0) to `top_group`.
+    buffer: Vec<vec::IntoIter<I::Item>>,
+    /// index of last group iter that was dropped, usize::MAX == none
+    dropped_group: usize,
+}
+
+impl<K, I, F> GroupInner<K, I, F>
+    where I: Iterator,
+          F: for<'a> KeyFunction<&'a I::Item, Key=K>,
+          K: PartialEq,
+{
+    /// `client`: Index of group that requests next element
+    #[inline(always)]
+    fn step(&mut self, client: usize) -> Option<I::Item> {
+        /*
+        println!("client={}, bottom_group={}, oldest_buffered_group={}, top_group={}, buffers=[{}]",
+                 client, self.bottom_group, self.oldest_buffered_group,
+                 self.top_group,
+                 self.buffer.iter().map(|elt| elt.len()).format(", "));
+        */
+        if client < self.oldest_buffered_group {
+            None
+        } else if client < self.top_group ||
+            (client == self.top_group &&
+             self.buffer.len() > self.top_group - self.bottom_group)
+        {
+            self.lookup_buffer(client)
+        } else if self.done {
+            None
+        } else if self.top_group == client {
+            self.step_current()
+        } else {
+            self.step_buffering(client)
+        }
+    }
+
+    #[inline(never)]
+    fn lookup_buffer(&mut self, client: usize) -> Option<I::Item> {
+        // if `bufidx` doesn't exist in self.buffer, it might be empty
+        let bufidx = client - self.bottom_group;
+        if client < self.oldest_buffered_group {
+            return None;
+        }
+        let elt = self.buffer.get_mut(bufidx).and_then(|queue| queue.next());
+        if elt.is_none() && client == self.oldest_buffered_group {
+            // FIXME: VecDeque is unfortunately not zero allocation when empty,
+            // so we do this job manually.
+            // `bottom_group..oldest_buffered_group` is unused, and if it's large enough, erase it.
+            self.oldest_buffered_group += 1;
+            // skip forward further empty queues too
+            while self.buffer.get(self.oldest_buffered_group - self.bottom_group)
+                             .map_or(false, |buf| buf.len() == 0)
+            {
+                self.oldest_buffered_group += 1;
+            }
+
+            let nclear = self.oldest_buffered_group - self.bottom_group;
+            if nclear > 0 && nclear >= self.buffer.len() / 2 {
+                let mut i = 0;
+                self.buffer.retain(|buf| {
+                    i += 1;
+                    debug_assert!(buf.len() == 0 || i > nclear);
+                    i > nclear
+                });
+                self.bottom_group = self.oldest_buffered_group;
+            }
+        }
+        elt
+    }
+
+    /// Take the next element from the iterator, and set the done
+    /// flag if exhausted. Must not be called after done.
+    #[inline(always)]
+    fn next_element(&mut self) -> Option<I::Item> {
+        debug_assert!(!self.done);
+        match self.iter.next() {
+            None => { self.done = true; None }
+            otherwise => otherwise,
+        }
+    }
+
+
+    #[inline(never)]
+    fn step_buffering(&mut self, client: usize) -> Option<I::Item> {
+        // requested a later group -- walk through the current group up to
+        // the requested group index, and buffer the elements (unless
+        // the group is marked as dropped).
+        // Because the `Groups` iterator is always the first to request
+        // each group index, client is the next index efter top_group.
+        debug_assert!(self.top_group + 1 == client);
+        let mut group = Vec::new();
+
+        if let Some(elt) = self.current_elt.take() {
+            if self.top_group != self.dropped_group {
+                group.push(elt);
+            }
+        }
+        let mut first_elt = None; // first element of the next group
+
+        while let Some(elt) = self.next_element() {
+            let key = self.key.call_mut(&elt);
+            match self.current_key.take() {
+                None => {}
+                Some(old_key) => if old_key != key {
+                    self.current_key = Some(key);
+                    first_elt = Some(elt);
+                    break;
+                },
+            }
+            self.current_key = Some(key);
+            if self.top_group != self.dropped_group {
+                group.push(elt);
+            }
+        }
+
+        if self.top_group != self.dropped_group {
+            self.push_next_group(group);
+        }
+        if first_elt.is_some() {
+            self.top_group += 1;
+            debug_assert!(self.top_group == client);
+        }
+        first_elt
+    }
+
+    fn push_next_group(&mut self, group: Vec<I::Item>) {
+        // When we add a new buffered group, fill up slots between oldest_buffered_group and top_group
+        while self.top_group - self.bottom_group > self.buffer.len() {
+            if self.buffer.is_empty() {
+                self.bottom_group += 1;
+                self.oldest_buffered_group += 1;
+            } else {
+                self.buffer.push(Vec::new().into_iter());
+            }
+        }
+        self.buffer.push(group.into_iter());
+        debug_assert!(self.top_group + 1 - self.bottom_group == self.buffer.len());
+    }
+
+    /// This is the immediate case, where we use no buffering
+    #[inline]
+    fn step_current(&mut self) -> Option<I::Item> {
+        debug_assert!(!self.done);
+        if let elt @ Some(..) = self.current_elt.take() {
+            return elt;
+        }
+        match self.next_element() {
+            None => None,
+            Some(elt) => {
+                let key = self.key.call_mut(&elt);
+                match self.current_key.take() {
+                    None => {}
+                    Some(old_key) => if old_key != key {
+                        self.current_key = Some(key);
+                        self.current_elt = Some(elt);
+                        self.top_group += 1;
+                        return None;
+                    },
+                }
+                self.current_key = Some(key);
+                Some(elt)
+            }
+        }
+    }
+
+    /// Request the just started groups' key.
+    ///
+    /// `client`: Index of group
+    ///
+    /// **Panics** if no group key is available.
+    fn group_key(&mut self, client: usize) -> K {
+        // This can only be called after we have just returned the first
+        // element of a group.
+        // Perform this by simply buffering one more element, grabbing the
+        // next key.
+        debug_assert!(!self.done);
+        debug_assert!(client == self.top_group);
+        debug_assert!(self.current_key.is_some());
+        debug_assert!(self.current_elt.is_none());
+        let old_key = self.current_key.take().unwrap();
+        if let Some(elt) = self.next_element() {
+            let key = self.key.call_mut(&elt);
+            if old_key != key {
+                self.top_group += 1;
+            }
+            self.current_key = Some(key);
+            self.current_elt = Some(elt);
+        }
+        old_key
+    }
+}
+
+impl<K, I, F> GroupInner<K, I, F>
+    where I: Iterator,
+{
+    /// Called when a group is dropped
+    fn drop_group(&mut self, client: usize) {
+        // It's only useful to track the maximal index
+        if self.dropped_group == !0 || client > self.dropped_group {
+            self.dropped_group = client;
+        }
+    }
+}
+
+/// `GroupBy` is the storage for the lazy grouping operation.
+///
+/// If the groups are consumed in their original order, or if each
+/// group is dropped without keeping it around, then `GroupBy` uses
+/// no allocations. It needs allocations only if several group iterators
+/// are alive at the same time.
+///
+/// This type implements `IntoIterator` (it is **not** an iterator
+/// itself), because the group iterators need to borrow from this
+/// value. It should be stored in a local variable or temporary and
+/// iterated.
+///
+/// See [`.group_by()`](../trait.Itertools.html#method.group_by) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct GroupBy<K, I, F>
+    where I: Iterator,
+{
+    inner: RefCell<GroupInner<K, I, F>>,
+    // the group iterator's current index. Keep this in the main value
+    // so that simultaneous iterators all use the same state.
+    index: Cell<usize>,
+}
+
+/// Create a new
+pub fn new<K, J, F>(iter: J, f: F) -> GroupBy<K, J::IntoIter, F>
+    where J: IntoIterator,
+          F: FnMut(&J::Item) -> K,
+{
+    GroupBy {
+        inner: RefCell::new(GroupInner {
+            key: f,
+            iter: iter.into_iter(),
+            current_key: None,
+            current_elt: None,
+            done: false,
+            top_group: 0,
+            oldest_buffered_group: 0,
+            bottom_group: 0,
+            buffer: Vec::new(),
+            dropped_group: !0,
+        }),
+        index: Cell::new(0),
+    }
+}
+
+impl<K, I, F> GroupBy<K, I, F>
+    where I: Iterator,
+{
+    /// `client`: Index of group that requests next element
+    fn step(&self, client: usize) -> Option<I::Item>
+        where F: FnMut(&I::Item) -> K,
+              K: PartialEq,
+    {
+        self.inner.borrow_mut().step(client)
+    }
+
+    /// `client`: Index of group
+    fn drop_group(&self, client: usize) {
+        self.inner.borrow_mut().drop_group(client)
+    }
+}
+
+impl<'a, K, I, F> IntoIterator for &'a GroupBy<K, I, F>
+    where I: Iterator,
+          I::Item: 'a,
+          F: FnMut(&I::Item) -> K,
+          K: PartialEq
+{
+    type Item = (K, Group<'a, K, I, F>);
+    type IntoIter = Groups<'a, K, I, F>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        Groups { parent: self }
+    }
+}
+
+
+/// An iterator that yields the Group iterators.
+///
+/// Iterator element type is `(K, Group)`:
+/// the group's key `K` and the group's iterator.
+///
+/// See [`.group_by()`](../trait.Itertools.html#method.group_by) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Groups<'a, K: 'a, I: 'a, F: 'a>
+    where I: Iterator,
+          I::Item: 'a
+{
+    parent: &'a GroupBy<K, I, F>,
+}
+
+impl<'a, K, I, F> Iterator for Groups<'a, K, I, F>
+    where I: Iterator,
+          I::Item: 'a,
+          F: FnMut(&I::Item) -> K,
+          K: PartialEq
+{
+    type Item = (K, Group<'a, K, I, F>);
+
+    #[inline]
+    fn next(&mut self) -> Option<Self::Item> {
+        let index = self.parent.index.get();
+        self.parent.index.set(index + 1);
+        let inner = &mut *self.parent.inner.borrow_mut();
+        inner.step(index).map(|elt| {
+            let key = inner.group_key(index);
+            (key, Group {
+                parent: self.parent,
+                index,
+                first: Some(elt),
+            })
+        })
+    }
+}
+
+/// An iterator for the elements in a single group.
+///
+/// Iterator element type is `I::Item`.
+pub struct Group<'a, K: 'a, I: 'a, F: 'a>
+    where I: Iterator,
+          I::Item: 'a,
+{
+    parent: &'a GroupBy<K, I, F>,
+    index: usize,
+    first: Option<I::Item>,
+}
+
+impl<'a, K, I, F> Drop for Group<'a, K, I, F>
+    where I: Iterator,
+          I::Item: 'a,
+{
+    fn drop(&mut self) {
+        self.parent.drop_group(self.index);
+    }
+}
+
+impl<'a, K, I, F> Iterator for Group<'a, K, I, F>
+    where I: Iterator,
+          I::Item: 'a,
+          F: FnMut(&I::Item) -> K,
+          K: PartialEq,
+{
+    type Item = I::Item;
+    #[inline]
+    fn next(&mut self) -> Option<Self::Item> {
+        if let elt @ Some(..) = self.first.take() {
+            return elt;
+        }
+        self.parent.step(self.index)
+    }
+}
+
+///// IntoChunks /////
+
+/// Create a new
+pub fn new_chunks<J>(iter: J, size: usize) -> IntoChunks<J::IntoIter>
+    where J: IntoIterator,
+{
+    IntoChunks {
+        inner: RefCell::new(GroupInner {
+            key: ChunkIndex::new(size),
+            iter: iter.into_iter(),
+            current_key: None,
+            current_elt: None,
+            done: false,
+            top_group: 0,
+            oldest_buffered_group: 0,
+            bottom_group: 0,
+            buffer: Vec::new(),
+            dropped_group: !0,
+        }),
+        index: Cell::new(0),
+    }
+}
+
+
+/// `ChunkLazy` is the storage for a lazy chunking operation.
+///
+/// `IntoChunks` behaves just like `GroupBy`: it is iterable, and
+/// it only buffers if several chunk iterators are alive at the same time.
+///
+/// This type implements `IntoIterator` (it is **not** an iterator
+/// itself), because the chunk iterators need to borrow from this
+/// value. It should be stored in a local variable or temporary and
+/// iterated.
+///
+/// Iterator element type is `Chunk`, each chunk's iterator.
+///
+/// See [`.chunks()`](../trait.Itertools.html#method.chunks) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct IntoChunks<I>
+    where I: Iterator,
+{
+    inner: RefCell<GroupInner<usize, I, ChunkIndex>>,
+    // the chunk iterator's current index. Keep this in the main value
+    // so that simultaneous iterators all use the same state.
+    index: Cell<usize>,
+}
+
+
+impl<I> IntoChunks<I>
+    where I: Iterator,
+{
+    /// `client`: Index of chunk that requests next element
+    fn step(&self, client: usize) -> Option<I::Item> {
+        self.inner.borrow_mut().step(client)
+    }
+
+    /// `client`: Index of chunk
+    fn drop_group(&self, client: usize) {
+        self.inner.borrow_mut().drop_group(client)
+    }
+}
+
+impl<'a, I> IntoIterator for &'a IntoChunks<I>
+    where I: Iterator,
+          I::Item: 'a,
+{
+    type Item = Chunk<'a, I>;
+    type IntoIter = Chunks<'a, I>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        Chunks {
+            parent: self,
+        }
+    }
+}
+
+
+/// An iterator that yields the Chunk iterators.
+///
+/// Iterator element type is `Chunk`.
+///
+/// See [`.chunks()`](../trait.Itertools.html#method.chunks) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Chunks<'a, I: 'a>
+    where I: Iterator,
+          I::Item: 'a,
+{
+    parent: &'a IntoChunks<I>,
+}
+
+impl<'a, I> Iterator for Chunks<'a, I>
+    where I: Iterator,
+          I::Item: 'a,
+{
+    type Item = Chunk<'a, I>;
+
+    #[inline]
+    fn next(&mut self) -> Option<Self::Item> {
+        let index = self.parent.index.get();
+        self.parent.index.set(index + 1);
+        let inner = &mut *self.parent.inner.borrow_mut();
+        inner.step(index).map(|elt| {
+            Chunk {
+                parent: self.parent,
+                index,
+                first: Some(elt),
+            }
+        })
+    }
+}
+
+/// An iterator for the elements in a single chunk.
+///
+/// Iterator element type is `I::Item`.
+pub struct Chunk<'a, I: 'a>
+    where I: Iterator,
+          I::Item: 'a,
+{
+    parent: &'a IntoChunks<I>,
+    index: usize,
+    first: Option<I::Item>,
+}
+
+impl<'a, I> Drop for Chunk<'a, I>
+    where I: Iterator,
+          I::Item: 'a,
+{
+    fn drop(&mut self) {
+        self.parent.drop_group(self.index);
+    }
+}
+
+impl<'a, I> Iterator for Chunk<'a, I>
+    where I: Iterator,
+          I::Item: 'a,
+{
+    type Item = I::Item;
+    #[inline]
+    fn next(&mut self) -> Option<Self::Item> {
+        if let elt @ Some(..) = self.first.take() {
+            return elt;
+        }
+        self.parent.step(self.index)
+    }
+}
diff --git a/src/impl_macros.rs b/src/impl_macros.rs
new file mode 100644
index 0000000..04ab8e1
--- /dev/null
+++ b/src/impl_macros.rs
@@ -0,0 +1,24 @@
+//! 
+//! Implementation's internal macros
+
+macro_rules! debug_fmt_fields {
+    ($tyname:ident, $($($field:ident).+),*) => {
+        fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+            f.debug_struct(stringify!($tyname))
+                $(
+              .field(stringify!($($field).+), &self.$($field).+)
+              )*
+              .finish()
+        }
+    }
+}
+
+macro_rules! clone_fields {
+    ($($field:ident),*) => {
+        fn clone(&self) -> Self {
+            Self {
+                $($field: self.$field.clone(),)*
+            }
+        }
+    }
+}
diff --git a/src/intersperse.rs b/src/intersperse.rs
new file mode 100644
index 0000000..0579299
--- /dev/null
+++ b/src/intersperse.rs
@@ -0,0 +1,79 @@
+use std::iter::Fuse;
+use super::size_hint;
+
+#[derive(Clone)]
+/// An iterator adaptor to insert a particular value
+/// between each element of the adapted iterator.
+///
+/// Iterator element type is `I::Item`
+///
+/// This iterator is *fused*.
+///
+/// See [`.intersperse()`](../trait.Itertools.html#method.intersperse) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[derive(Debug)]
+pub struct Intersperse<I>
+    where I: Iterator
+{
+    element: I::Item,
+    iter: Fuse<I>,
+    peek: Option<I::Item>,
+}
+
+/// Create a new Intersperse iterator
+pub fn intersperse<I>(iter: I, elt: I::Item) -> Intersperse<I>
+    where I: Iterator
+{
+    let mut iter = iter.fuse();
+    Intersperse {
+        peek: iter.next(),
+        iter,
+        element: elt,
+    }
+}
+
+impl<I> Iterator for Intersperse<I>
+    where I: Iterator,
+          I::Item: Clone
+{
+    type Item = I::Item;
+    #[inline]
+    fn next(&mut self) -> Option<I::Item> {
+        if self.peek.is_some() {
+            self.peek.take()
+        } else {
+            self.peek = self.iter.next();
+            if self.peek.is_some() {
+                Some(self.element.clone())
+            } else {
+                None
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        // 2 * SH + { 1 or 0 }
+        let has_peek = self.peek.is_some() as usize;
+        let sh = self.iter.size_hint();
+        size_hint::add_scalar(size_hint::add(sh, sh), has_peek)
+    }
+
+    fn fold<B, F>(mut self, init: B, mut f: F) -> B where
+        Self: Sized, F: FnMut(B, Self::Item) -> B,
+    {
+        let mut accum = init;
+        
+        if let Some(x) = self.peek.take() {
+            accum = f(accum, x);
+        }
+
+        let element = &self.element;
+
+        self.iter.fold(accum,
+            |accum, x| {
+                let accum = f(accum, element.clone());
+                let accum = f(accum, x);
+                accum
+        })
+    }
+}
diff --git a/src/kmerge_impl.rs b/src/kmerge_impl.rs
new file mode 100644
index 0000000..8f68aeb
--- /dev/null
+++ b/src/kmerge_impl.rs
@@ -0,0 +1,216 @@
+use crate::size_hint;
+use crate::Itertools;
+
+use std::mem::replace;
+use std::fmt;
+
+/// Head element and Tail iterator pair
+///
+/// `PartialEq`, `Eq`, `PartialOrd` and `Ord` are implemented by comparing sequences based on
+/// first items (which are guaranteed to exist).
+///
+/// The meanings of `PartialOrd` and `Ord` are reversed so as to turn the heap used in
+/// `KMerge` into a min-heap.
+#[derive(Debug)]
+struct HeadTail<I>
+    where I: Iterator
+{
+    head: I::Item,
+    tail: I,
+}
+
+impl<I> HeadTail<I>
+    where I: Iterator
+{
+    /// Constructs a `HeadTail` from an `Iterator`. Returns `None` if the `Iterator` is empty.
+    fn new(mut it: I) -> Option<HeadTail<I>> {
+        let head = it.next();
+        head.map(|h| {
+            HeadTail {
+                head: h,
+                tail: it,
+            }
+        })
+    }
+
+    /// Get the next element and update `head`, returning the old head in `Some`.
+    ///
+    /// Returns `None` when the tail is exhausted (only `head` then remains).
+    fn next(&mut self) -> Option<I::Item> {
+        if let Some(next) = self.tail.next() {
+            Some(replace(&mut self.head, next))
+        } else {
+            None
+        }
+    }
+
+    /// Hints at the size of the sequence, same as the `Iterator` method.
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        size_hint::add_scalar(self.tail.size_hint(), 1)
+    }
+}
+
+impl<I> Clone for HeadTail<I>
+    where I: Iterator + Clone,
+          I::Item: Clone
+{
+    clone_fields!(head, tail);
+}
+
+/// Make `data` a heap (min-heap w.r.t the sorting).
+fn heapify<T, S>(data: &mut [T], mut less_than: S)
+    where S: FnMut(&T, &T) -> bool
+{
+    for i in (0..data.len() / 2).rev() {
+        sift_down(data, i, &mut less_than);
+    }
+}
+
+/// Sift down element at `index` (`heap` is a min-heap wrt the ordering)
+fn sift_down<T, S>(heap: &mut [T], index: usize, mut less_than: S)
+    where S: FnMut(&T, &T) -> bool
+{
+    debug_assert!(index <= heap.len());
+    let mut pos = index;
+    let mut child = 2 * pos + 1;
+    // the `pos` conditional is to avoid a bounds check
+    while pos < heap.len() && child < heap.len() {
+        let right = child + 1;
+
+        // pick the smaller of the two children
+        if right < heap.len() && less_than(&heap[right], &heap[child]) {
+            child = right;
+        }
+
+        // sift down is done if we are already in order
+        if !less_than(&heap[child], &heap[pos]) {
+            return;
+        }
+        heap.swap(pos, child);
+        pos = child;
+        child = 2 * pos + 1;
+    }
+}
+
+/// An iterator adaptor that merges an abitrary number of base iterators in ascending order.
+/// If all base iterators are sorted (ascending), the result is sorted.
+///
+/// Iterator element type is `I::Item`.
+///
+/// See [`.kmerge()`](../trait.Itertools.html#method.kmerge) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub type KMerge<I> = KMergeBy<I, KMergeByLt>;
+
+pub trait KMergePredicate<T> {
+    fn kmerge_pred(&mut self, a: &T, b: &T) -> bool;
+}
+
+#[derive(Clone)]
+pub struct KMergeByLt;
+
+impl<T: PartialOrd> KMergePredicate<T> for KMergeByLt {
+    fn kmerge_pred(&mut self, a: &T, b: &T) -> bool {
+        a < b
+    }
+}
+
+impl<T, F: FnMut(&T, &T)->bool> KMergePredicate<T> for F {
+    fn kmerge_pred(&mut self, a: &T, b: &T) -> bool {
+        self(a, b)
+    }
+}
+
+/// Create an iterator that merges elements of the contained iterators using
+/// the ordering function.
+///
+/// Equivalent to `iterable.into_iter().kmerge()`.
+///
+/// ```
+/// use itertools::kmerge;
+///
+/// for elt in kmerge(vec![vec![0, 2, 4], vec![1, 3, 5], vec![6, 7]]) {
+///     /* loop body */
+/// }
+/// ```
+pub fn kmerge<I>(iterable: I) -> KMerge<<I::Item as IntoIterator>::IntoIter>
+    where I: IntoIterator,
+          I::Item: IntoIterator,
+          <<I as IntoIterator>::Item as IntoIterator>::Item: PartialOrd
+{
+    kmerge_by(iterable, KMergeByLt)
+}
+
+/// An iterator adaptor that merges an abitrary number of base iterators
+/// according to an ordering function.
+///
+/// Iterator element type is `I::Item`.
+///
+/// See [`.kmerge_by()`](../trait.Itertools.html#method.kmerge_by) for more
+/// information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct KMergeBy<I, F>
+    where I: Iterator,
+{
+    heap: Vec<HeadTail<I>>,
+    less_than: F,
+}
+
+impl<I, F> fmt::Debug for KMergeBy<I, F>
+    where I: Iterator + fmt::Debug,
+          I::Item: fmt::Debug,
+{
+    debug_fmt_fields!(KMergeBy, heap);
+}
+
+/// Create an iterator that merges elements of the contained iterators.
+///
+/// Equivalent to `iterable.into_iter().kmerge_by(less_than)`.
+pub fn kmerge_by<I, F>(iterable: I, mut less_than: F)
+    -> KMergeBy<<I::Item as IntoIterator>::IntoIter, F>
+    where I: IntoIterator,
+          I::Item: IntoIterator,
+          F: KMergePredicate<<<I as IntoIterator>::Item as IntoIterator>::Item>,
+{
+    let iter = iterable.into_iter();
+    let (lower, _) = iter.size_hint();
+    let mut heap: Vec<_> = Vec::with_capacity(lower);
+    heap.extend(iter.filter_map(|it| HeadTail::new(it.into_iter())));
+    heapify(&mut heap, |a, b| less_than.kmerge_pred(&a.head, &b.head));
+    KMergeBy { heap, less_than }
+}
+
+impl<I, F> Clone for KMergeBy<I, F>
+    where I: Iterator + Clone,
+          I::Item: Clone,
+          F: Clone,
+{
+    clone_fields!(heap, less_than);
+}
+
+impl<I, F> Iterator for KMergeBy<I, F>
+    where I: Iterator,
+          F: KMergePredicate<I::Item>
+{
+    type Item = I::Item;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if self.heap.is_empty() {
+            return None;
+        }
+        let result = if let Some(next) = self.heap[0].next() {
+            next
+        } else {
+            self.heap.swap_remove(0).head
+        };
+        let less_than = &mut self.less_than;
+        sift_down(&mut self.heap, 0, |a, b| less_than.kmerge_pred(&a.head, &b.head));
+        Some(result)
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.heap.iter()
+                 .map(|i| i.size_hint())
+                 .fold1(size_hint::add)
+                 .unwrap_or((0, Some(0)))
+    }
+}
diff --git a/src/lazy_buffer.rs b/src/lazy_buffer.rs
new file mode 100644
index 0000000..01123d4
--- /dev/null
+++ b/src/lazy_buffer.rs
@@ -0,0 +1,59 @@
+use std::ops::Index;
+
+#[derive(Debug, Clone)]
+pub struct LazyBuffer<I: Iterator> {
+    pub it: I,
+    done: bool,
+    buffer: Vec<I::Item>,
+}
+
+impl<I> LazyBuffer<I>
+where
+    I: Iterator,
+{
+    pub fn new(it: I) -> LazyBuffer<I> {
+        LazyBuffer {
+            it,
+            done: false,
+            buffer: Vec::new(),
+        }
+    }
+
+    pub fn len(&self) -> usize {
+        self.buffer.len()
+    }
+
+    pub fn is_done(&self) -> bool {
+        self.done
+    }
+
+    pub fn get_next(&mut self) -> bool {
+        if self.done {
+            return false;
+        }
+        let next_item = self.it.next();
+        match next_item {
+            Some(x) => {
+                self.buffer.push(x);
+                true
+            }
+            None => {
+                self.done = true;
+                false
+            }
+        }
+    }
+}
+
+impl<I, J> Index<J> for LazyBuffer<I>
+where
+    I: Iterator,
+    I::Item: Sized,
+    Vec<I::Item>: Index<J>
+{
+    type Output = <Vec<I::Item> as Index<J>>::Output;
+
+    fn index(&self, _index: J) -> &Self::Output {
+        self.buffer.index(_index)
+    }
+}
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..b8daefd
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,2721 @@
+#![warn(missing_docs)]
+#![crate_name="itertools"]
+#![cfg_attr(not(feature = "use_std"), no_std)]
+
+//! Extra iterator adaptors, functions and macros.
+//!
+//! To extend [`Iterator`] with methods in this crate, import
+//! the [`Itertools` trait](./trait.Itertools.html):
+//!
+//! ```
+//! use itertools::Itertools;
+//! ```
+//!
+//! Now, new methods like [`interleave`](./trait.Itertools.html#method.interleave)
+//! are available on all iterators:
+//!
+//! ```
+//! use itertools::Itertools;
+//!
+//! let it = (1..3).interleave(vec![-1, -2]);
+//! itertools::assert_equal(it, vec![1, -1, 2, -2]);
+//! ```
+//!
+//! Most iterator methods are also provided as functions (with the benefit
+//! that they convert parameters using [`IntoIterator`]):
+//!
+//! ```
+//! use itertools::interleave;
+//!
+//! for elt in interleave(&[1, 2, 3], &[2, 3, 4]) {
+//!     /* loop body */
+//! }
+//! ```
+//!
+//! ## Crate Features
+//!
+//! - `use_std`
+//!   - Enabled by default.
+//!   - Disable to compile itertools using `#![no_std]`. This disables
+//!     any items that depend on collections (like `group_by`, `unique`,
+//!     `kmerge`, `join` and many more).
+//!
+//! ## Rust Version
+//!
+//! This version of itertools requires Rust 1.32 or later.
+//!
+//! [`Iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html
+#![doc(html_root_url="https://docs.rs/itertools/0.8/")]
+
+#[cfg(not(feature = "use_std"))]
+extern crate core as std;
+
+pub use either::Either;
+
+#[cfg(feature = "use_std")]
+use std::collections::HashMap;
+use std::iter::{IntoIterator, once};
+use std::cmp::Ordering;
+use std::fmt;
+#[cfg(feature = "use_std")]
+use std::hash::Hash;
+#[cfg(feature = "use_std")]
+use std::fmt::Write;
+#[cfg(feature = "use_std")]
+type VecIntoIter<T> = ::std::vec::IntoIter<T>;
+#[cfg(feature = "use_std")]
+use std::iter::FromIterator;
+
+#[macro_use]
+mod impl_macros;
+
+// for compatibility with no std and macros
+#[doc(hidden)]
+pub use std::iter as __std_iter;
+
+/// The concrete iterator types.
+pub mod structs {
+    pub use crate::adaptors::{
+        Dedup,
+        DedupBy,
+        Interleave,
+        InterleaveShortest,
+        Product,
+        PutBack,
+        Batching,
+        MapInto,
+        MapResults,
+        Merge,
+        MergeBy,
+        TakeWhileRef,
+        WhileSome,
+        Coalesce,
+        TupleCombinations,
+        Positions,
+        Update,
+    };
+    #[allow(deprecated)]
+    pub use crate::adaptors::Step;
+    #[cfg(feature = "use_std")]
+    pub use crate::adaptors::MultiProduct;
+    #[cfg(feature = "use_std")]
+    pub use crate::combinations::Combinations;
+    #[cfg(feature = "use_std")]
+    pub use crate::combinations_with_replacement::CombinationsWithReplacement;
+    pub use crate::cons_tuples_impl::ConsTuples;
+    pub use crate::exactly_one_err::ExactlyOneError;
+    pub use crate::format::{Format, FormatWith};
+    #[cfg(feature = "use_std")]
+    pub use crate::groupbylazy::{IntoChunks, Chunk, Chunks, GroupBy, Group, Groups};
+    pub use crate::intersperse::Intersperse;
+    #[cfg(feature = "use_std")]
+    pub use crate::kmerge_impl::{KMerge, KMergeBy};
+    pub use crate::merge_join::MergeJoinBy;
+    #[cfg(feature = "use_std")]
+    pub use crate::multipeek_impl::MultiPeek;
+    pub use crate::pad_tail::PadUsing;
+    pub use crate::peeking_take_while::PeekingTakeWhile;
+    #[cfg(feature = "use_std")]
+    pub use crate::permutations::Permutations;
+    pub use crate::process_results_impl::ProcessResults;
+    #[cfg(feature = "use_std")]
+    pub use crate::put_back_n_impl::PutBackN;
+    #[cfg(feature = "use_std")]
+    pub use crate::rciter_impl::RcIter;
+    pub use crate::repeatn::RepeatN;
+    #[allow(deprecated)]
+    pub use crate::sources::{RepeatCall, Unfold, Iterate};
+    #[cfg(feature = "use_std")]
+    pub use crate::tee::Tee;
+    pub use crate::tuple_impl::{TupleBuffer, TupleWindows, Tuples};
+    #[cfg(feature = "use_std")]
+    pub use crate::unique_impl::{Unique, UniqueBy};
+    pub use crate::with_position::WithPosition;
+    pub use crate::zip_eq_impl::ZipEq;
+    pub use crate::zip_longest::ZipLongest;
+    pub use crate::ziptuple::Zip;
+}
+
+/// Traits helpful for using certain `Itertools` methods in generic contexts.
+pub mod traits {
+    pub use crate::tuple_impl::HomogeneousTuple;
+}
+
+#[allow(deprecated)]
+pub use crate::structs::*;
+pub use crate::concat_impl::concat;
+pub use crate::cons_tuples_impl::cons_tuples;
+pub use crate::diff::diff_with;
+pub use crate::diff::Diff;
+#[cfg(feature = "use_std")]
+pub use crate::kmerge_impl::{kmerge_by};
+pub use crate::minmax::MinMaxResult;
+pub use crate::peeking_take_while::PeekingNext;
+pub use crate::process_results_impl::process_results;
+pub use crate::repeatn::repeat_n;
+#[allow(deprecated)]
+pub use crate::sources::{repeat_call, unfold, iterate};
+pub use crate::with_position::Position;
+pub use crate::ziptuple::multizip;
+mod adaptors;
+mod either_or_both;
+pub use crate::either_or_both::EitherOrBoth;
+#[doc(hidden)]
+pub mod free;
+#[doc(inline)]
+pub use crate::free::*;
+mod concat_impl;
+mod cons_tuples_impl;
+#[cfg(feature = "use_std")]
+mod combinations;
+#[cfg(feature = "use_std")]
+mod combinations_with_replacement;
+mod exactly_one_err;
+mod diff;
+mod format;
+#[cfg(feature = "use_std")]
+mod group_map;
+#[cfg(feature = "use_std")]
+mod groupbylazy;
+mod intersperse;
+#[cfg(feature = "use_std")]
+mod kmerge_impl;
+#[cfg(feature = "use_std")]
+mod lazy_buffer;
+mod merge_join;
+mod minmax;
+#[cfg(feature = "use_std")]
+mod multipeek_impl;
+mod pad_tail;
+mod peeking_take_while;
+#[cfg(feature = "use_std")]
+mod permutations;
+mod process_results_impl;
+#[cfg(feature = "use_std")]
+mod put_back_n_impl;
+#[cfg(feature = "use_std")]
+mod rciter_impl;
+mod repeatn;
+mod size_hint;
+mod sources;
+#[cfg(feature = "use_std")]
+mod tee;
+mod tuple_impl;
+#[cfg(feature = "use_std")]
+mod unique_impl;
+mod with_position;
+mod zip_eq_impl;
+mod zip_longest;
+mod ziptuple;
+
+#[macro_export]
+/// Create an iterator over the “cartesian product” of iterators.
+///
+/// Iterator element type is like `(A, B, ..., E)` if formed
+/// from iterators `(I, J, ..., M)` with element types `I::Item = A`, `J::Item = B`, etc.
+///
+/// ```
+/// # use itertools::iproduct;
+/// #
+/// # fn main() {
+/// // Iterate over the coordinates of a 4 x 4 x 4 grid
+/// // from (0, 0, 0), (0, 0, 1), .., (0, 1, 0), (0, 1, 1), .. etc until (3, 3, 3)
+/// for (i, j, k) in iproduct!(0..4, 0..4, 0..4) {
+///    // ..
+/// }
+/// # }
+/// ```
+macro_rules! iproduct {
+    (@flatten $I:expr,) => (
+        $I
+    );
+    (@flatten $I:expr, $J:expr, $($K:expr,)*) => (
+        iproduct!(@flatten $crate::cons_tuples(iproduct!($I, $J)), $($K,)*)
+    );
+    ($I:expr) => (
+        $crate::__std_iter::IntoIterator::into_iter($I)
+    );
+    ($I:expr, $J:expr) => (
+        $crate::Itertools::cartesian_product(iproduct!($I), iproduct!($J))
+    );
+    ($I:expr, $J:expr, $($K:expr),+) => (
+        iproduct!(@flatten iproduct!($I, $J), $($K,)+)
+    );
+}
+
+#[macro_export]
+/// Create an iterator running multiple iterators in lockstep.
+///
+/// The `izip!` iterator yields elements until any subiterator
+/// returns `None`.
+///
+/// This is a version of the standard ``.zip()`` that's supporting more than
+/// two iterators. The iterator element type is a tuple with one element
+/// from each of the input iterators. Just like ``.zip()``, the iteration stops
+/// when the shortest of the inputs reaches its end.
+///
+/// **Note:** The result of this macro is in the general case an iterator
+/// composed of repeated `.zip()` and a `.map()`; it has an anonymous type.
+/// The special cases of one and two arguments produce the equivalent of
+/// `$a.into_iter()` and `$a.into_iter().zip($b)` respectively.
+///
+/// Prefer this macro `izip!()` over [`multizip`] for the performance benefits
+/// of using the standard library `.zip()`.
+///
+/// [`multizip`]: fn.multizip.html
+///
+/// ```
+/// # use itertools::izip;
+/// #
+/// # fn main() {
+///
+/// // iterate over three sequences side-by-side
+/// let mut results = [0, 0, 0, 0];
+/// let inputs = [3, 7, 9, 6];
+///
+/// for (r, index, input) in izip!(&mut results, 0..10, &inputs) {
+///     *r = index * 10 + input;
+/// }
+///
+/// assert_eq!(results, [0 + 3, 10 + 7, 29, 36]);
+/// # }
+/// ```
+macro_rules! izip {
+    // @closure creates a tuple-flattening closure for .map() call. usage:
+    // @closure partial_pattern => partial_tuple , rest , of , iterators
+    // eg. izip!( @closure ((a, b), c) => (a, b, c) , dd , ee )
+    ( @closure $p:pat => $tup:expr ) => {
+        |$p| $tup
+    };
+
+    // The "b" identifier is a different identifier on each recursion level thanks to hygiene.
+    ( @closure $p:pat => ( $($tup:tt)* ) , $_iter:expr $( , $tail:expr )* ) => {
+        izip!(@closure ($p, b) => ( $($tup)*, b ) $( , $tail )*)
+    };
+
+    // unary
+    ($first:expr $(,)*) => {
+        $crate::__std_iter::IntoIterator::into_iter($first)
+    };
+
+    // binary
+    ($first:expr, $second:expr $(,)*) => {
+        izip!($first)
+            .zip($second)
+    };
+
+    // n-ary where n > 2
+    ( $first:expr $( , $rest:expr )* $(,)* ) => {
+        izip!($first)
+            $(
+                .zip($rest)
+            )*
+            .map(
+                izip!(@closure a => (a) $( , $rest )*)
+            )
+    };
+}
+
+/// An [`Iterator`] blanket implementation that provides extra adaptors and
+/// methods.
+///
+/// This trait defines a number of methods. They are divided into two groups:
+///
+/// * *Adaptors* take an iterator and parameter as input, and return
+/// a new iterator value. These are listed first in the trait. An example
+/// of an adaptor is [`.interleave()`](#method.interleave)
+///
+/// * *Regular methods* are those that don't return iterators and instead
+/// return a regular value of some other kind.
+/// [`.next_tuple()`](#method.next_tuple) is an example and the first regular
+/// method in the list.
+///
+/// [`Iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html
+pub trait Itertools : Iterator {
+    // adaptors
+
+    /// Alternate elements from two iterators until both have run out.
+    ///
+    /// Iterator element type is `Self::Item`.
+    ///
+    /// This iterator is *fused*.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let it = (1..7).interleave(vec![-1, -2]);
+    /// itertools::assert_equal(it, vec![1, -1, 2, -2, 3, 4, 5, 6]);
+    /// ```
+    fn interleave<J>(self, other: J) -> Interleave<Self, J::IntoIter>
+        where J: IntoIterator<Item = Self::Item>,
+              Self: Sized
+    {
+        interleave(self, other)
+    }
+
+    /// Alternate elements from two iterators until at least one of them has run
+    /// out.
+    ///
+    /// Iterator element type is `Self::Item`.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let it = (1..7).interleave_shortest(vec![-1, -2]);
+    /// itertools::assert_equal(it, vec![1, -1, 2, -2, 3]);
+    /// ```
+    fn interleave_shortest<J>(self, other: J) -> InterleaveShortest<Self, J::IntoIter>
+        where J: IntoIterator<Item = Self::Item>,
+              Self: Sized
+    {
+        adaptors::interleave_shortest(self, other.into_iter())
+    }
+
+    /// An iterator adaptor to insert a particular value
+    /// between each element of the adapted iterator.
+    ///
+    /// Iterator element type is `Self::Item`.
+    ///
+    /// This iterator is *fused*.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// itertools::assert_equal((0..3).intersperse(8), vec![0, 8, 1, 8, 2]);
+    /// ```
+    fn intersperse(self, element: Self::Item) -> Intersperse<Self>
+        where Self: Sized,
+              Self::Item: Clone
+    {
+        intersperse::intersperse(self, element)
+    }
+
+    /// Create an iterator which iterates over both this and the specified
+    /// iterator simultaneously, yielding pairs of two optional elements.
+    ///
+    /// This iterator is *fused*.
+    ///
+    /// As long as neither input iterator is exhausted yet, it yields two values
+    /// via `EitherOrBoth::Both`.
+    ///
+    /// When the parameter iterator is exhausted, it only yields a value from the
+    /// `self` iterator via `EitherOrBoth::Left`.
+    ///
+    /// When the `self` iterator is exhausted, it only yields a value from the
+    /// parameter iterator via `EitherOrBoth::Right`.
+    ///
+    /// When both iterators return `None`, all further invocations of `.next()`
+    /// will return `None`.
+    ///
+    /// Iterator element type is
+    /// [`EitherOrBoth<Self::Item, J::Item>`](enum.EitherOrBoth.html).
+    ///
+    /// ```rust
+    /// use itertools::EitherOrBoth::{Both, Right};
+    /// use itertools::Itertools;
+    /// let it = (0..1).zip_longest(1..3);
+    /// itertools::assert_equal(it, vec![Both(0, 1), Right(2)]);
+    /// ```
+    #[inline]
+    fn zip_longest<J>(self, other: J) -> ZipLongest<Self, J::IntoIter>
+        where J: IntoIterator,
+              Self: Sized
+    {
+        zip_longest::zip_longest(self, other.into_iter())
+    }
+
+    /// Create an iterator which iterates over both this and the specified
+    /// iterator simultaneously, yielding pairs of elements.
+    ///
+    /// **Panics** if the iterators reach an end and they are not of equal
+    /// lengths.
+    #[inline]
+    fn zip_eq<J>(self, other: J) -> ZipEq<Self, J::IntoIter>
+        where J: IntoIterator,
+              Self: Sized
+    {
+        zip_eq(self, other)
+    }
+
+    /// A “meta iterator adaptor”. Its closure receives a reference to the
+    /// iterator and may pick off as many elements as it likes, to produce the
+    /// next iterator element.
+    ///
+    /// Iterator element type is `B`.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// // An adaptor that gathers elements in pairs
+    /// let pit = (0..4).batching(|it| {
+    ///            match it.next() {
+    ///                None => None,
+    ///                Some(x) => match it.next() {
+    ///                    None => None,
+    ///                    Some(y) => Some((x, y)),
+    ///                }
+    ///            }
+    ///        });
+    ///
+    /// itertools::assert_equal(pit, vec![(0, 1), (2, 3)]);
+    /// ```
+    ///
+    fn batching<B, F>(self, f: F) -> Batching<Self, F>
+        where F: FnMut(&mut Self) -> Option<B>,
+              Self: Sized
+    {
+        adaptors::batching(self, f)
+    }
+
+    /// Return an *iterable* that can group iterator elements.
+    /// Consecutive elements that map to the same key (“runs”), are assigned
+    /// to the same group.
+    ///
+    /// `GroupBy` is the storage for the lazy grouping operation.
+    ///
+    /// If the groups are consumed in order, or if each group's iterator is
+    /// dropped without keeping it around, then `GroupBy` uses no
+    /// allocations.  It needs allocations only if several group iterators
+    /// are alive at the same time.
+    ///
+    /// This type implements `IntoIterator` (it is **not** an iterator
+    /// itself), because the group iterators need to borrow from this
+    /// value. It should be stored in a local variable or temporary and
+    /// iterated.
+    ///
+    /// Iterator element type is `(K, Group)`: the group's key and the
+    /// group iterator.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// // group data into runs of larger than zero or not.
+    /// let data = vec![1, 3, -2, -2, 1, 0, 1, 2];
+    /// // groups:     |---->|------>|--------->|
+    ///
+    /// // Note: The `&` is significant here, `GroupBy` is iterable
+    /// // only by reference. You can also call `.into_iter()` explicitly.
+    /// let mut data_grouped = Vec::new();
+    /// for (key, group) in &data.into_iter().group_by(|elt| *elt >= 0) {
+    ///     data_grouped.push((key, group.collect()));
+    /// }
+    /// assert_eq!(data_grouped, vec![(true, vec![1, 3]), (false, vec![-2, -2]), (true, vec![1, 0, 1, 2])]);
+    /// ```
+    #[cfg(feature = "use_std")]
+    fn group_by<K, F>(self, key: F) -> GroupBy<K, Self, F>
+        where Self: Sized,
+              F: FnMut(&Self::Item) -> K,
+              K: PartialEq,
+    {
+        groupbylazy::new(self, key)
+    }
+
+    /// Return an *iterable* that can chunk the iterator.
+    ///
+    /// Yield subiterators (chunks) that each yield a fixed number elements,
+    /// determined by `size`. The last chunk will be shorter if there aren't
+    /// enough elements.
+    ///
+    /// `IntoChunks` is based on `GroupBy`: it is iterable (implements
+    /// `IntoIterator`, **not** `Iterator`), and it only buffers if several
+    /// chunk iterators are alive at the same time.
+    ///
+    /// Iterator element type is `Chunk`, each chunk's iterator.
+    ///
+    /// **Panics** if `size` is 0.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let data = vec![1, 1, 2, -2, 6, 0, 3, 1];
+    /// //chunk size=3 |------->|-------->|--->|
+    ///
+    /// // Note: The `&` is significant here, `IntoChunks` is iterable
+    /// // only by reference. You can also call `.into_iter()` explicitly.
+    /// for chunk in &data.into_iter().chunks(3) {
+    ///     // Check that the sum of each chunk is 4.
+    ///     assert_eq!(4, chunk.sum());
+    /// }
+    /// ```
+    #[cfg(feature = "use_std")]
+    fn chunks(self, size: usize) -> IntoChunks<Self>
+        where Self: Sized,
+    {
+        assert!(size != 0);
+        groupbylazy::new_chunks(self, size)
+    }
+
+    /// Return an iterator over all contiguous windows producing tuples of
+    /// a specific size (up to 4).
+    ///
+    /// `tuple_windows` clones the iterator elements so that they can be
+    /// part of successive windows, this makes it most suited for iterators
+    /// of references and other values that are cheap to copy.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    /// let mut v = Vec::new();
+    /// for (a, b) in (1..5).tuple_windows() {
+    ///     v.push((a, b));
+    /// }
+    /// assert_eq!(v, vec![(1, 2), (2, 3), (3, 4)]);
+    ///
+    /// let mut it = (1..5).tuple_windows();
+    /// assert_eq!(Some((1, 2, 3)), it.next());
+    /// assert_eq!(Some((2, 3, 4)), it.next());
+    /// assert_eq!(None, it.next());
+    ///
+    /// // this requires a type hint
+    /// let it = (1..5).tuple_windows::<(_, _, _)>();
+    /// itertools::assert_equal(it, vec![(1, 2, 3), (2, 3, 4)]);
+    ///
+    /// // you can also specify the complete type
+    /// use itertools::TupleWindows;
+    /// use std::ops::Range;
+    ///
+    /// let it: TupleWindows<Range<u32>, (u32, u32, u32)> = (1..5).tuple_windows();
+    /// itertools::assert_equal(it, vec![(1, 2, 3), (2, 3, 4)]);
+    /// ```
+    fn tuple_windows<T>(self) -> TupleWindows<Self, T>
+        where Self: Sized + Iterator<Item = T::Item>,
+              T: traits::HomogeneousTuple,
+              T::Item: Clone
+    {
+        tuple_impl::tuple_windows(self)
+    }
+
+    /// Return an iterator that groups the items in tuples of a specific size
+    /// (up to 4).
+    ///
+    /// See also the method [`.next_tuple()`](#method.next_tuple).
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    /// let mut v = Vec::new();
+    /// for (a, b) in (1..5).tuples() {
+    ///     v.push((a, b));
+    /// }
+    /// assert_eq!(v, vec![(1, 2), (3, 4)]);
+    ///
+    /// let mut it = (1..7).tuples();
+    /// assert_eq!(Some((1, 2, 3)), it.next());
+    /// assert_eq!(Some((4, 5, 6)), it.next());
+    /// assert_eq!(None, it.next());
+    ///
+    /// // this requires a type hint
+    /// let it = (1..7).tuples::<(_, _, _)>();
+    /// itertools::assert_equal(it, vec![(1, 2, 3), (4, 5, 6)]);
+    ///
+    /// // you can also specify the complete type
+    /// use itertools::Tuples;
+    /// use std::ops::Range;
+    ///
+    /// let it: Tuples<Range<u32>, (u32, u32, u32)> = (1..7).tuples();
+    /// itertools::assert_equal(it, vec![(1, 2, 3), (4, 5, 6)]);
+    /// ```
+    ///
+    /// See also [`Tuples::into_buffer`](structs/struct.Tuples.html#method.into_buffer).
+    fn tuples<T>(self) -> Tuples<Self, T>
+        where Self: Sized + Iterator<Item = T::Item>,
+              T: traits::HomogeneousTuple
+    {
+        tuple_impl::tuples(self)
+    }
+
+    /// Split into an iterator pair that both yield all elements from
+    /// the original iterator.
+    ///
+    /// **Note:** If the iterator is clonable, prefer using that instead
+    /// of using this method. It is likely to be more efficient.
+    ///
+    /// Iterator element type is `Self::Item`.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    /// let xs = vec![0, 1, 2, 3];
+    ///
+    /// let (mut t1, t2) = xs.into_iter().tee();
+    /// itertools::assert_equal(t1.next(), Some(0));
+    /// itertools::assert_equal(t2, 0..4);
+    /// itertools::assert_equal(t1, 1..4);
+    /// ```
+    #[cfg(feature = "use_std")]
+    fn tee(self) -> (Tee<Self>, Tee<Self>)
+        where Self: Sized,
+              Self::Item: Clone
+    {
+        tee::new(self)
+    }
+
+    /// Return an iterator adaptor that steps `n` elements in the base iterator
+    /// for each iteration.
+    ///
+    /// The iterator steps by yielding the next element from the base iterator,
+    /// then skipping forward `n - 1` elements.
+    ///
+    /// Iterator element type is `Self::Item`.
+    ///
+    /// **Panics** if the step is 0.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let it = (0..8).step(3);
+    /// itertools::assert_equal(it, vec![0, 3, 6]);
+    /// ```
+    #[deprecated(note="Use std .step_by() instead", since="0.8")]
+    #[allow(deprecated)]
+    fn step(self, n: usize) -> Step<Self>
+        where Self: Sized
+    {
+        adaptors::step(self, n)
+    }
+
+    /// Convert each item of the iterator using the `Into` trait.
+    ///
+    /// ```rust
+    /// use itertools::Itertools;
+    ///
+    /// (1i32..42i32).map_into::<f64>().collect_vec();
+    /// ```
+    fn map_into<R>(self) -> MapInto<Self, R>
+        where Self: Sized,
+              Self::Item: Into<R>,
+    {
+        adaptors::map_into(self)
+    }
+
+    /// Return an iterator adaptor that applies the provided closure
+    /// to every `Result::Ok` value. `Result::Err` values are
+    /// unchanged.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let input = vec![Ok(41), Err(false), Ok(11)];
+    /// let it = input.into_iter().map_results(|i| i + 1);
+    /// itertools::assert_equal(it, vec![Ok(42), Err(false), Ok(12)]);
+    /// ```
+    fn map_results<F, T, U, E>(self, f: F) -> MapResults<Self, F>
+        where Self: Iterator<Item = Result<T, E>> + Sized,
+              F: FnMut(T) -> U,
+    {
+        adaptors::map_results(self, f)
+    }
+
+    /// Return an iterator adaptor that merges the two base iterators in
+    /// ascending order.  If both base iterators are sorted (ascending), the
+    /// result is sorted.
+    ///
+    /// Iterator element type is `Self::Item`.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let a = (0..11).step(3);
+    /// let b = (0..11).step(5);
+    /// let it = a.merge(b);
+    /// itertools::assert_equal(it, vec![0, 0, 3, 5, 6, 9, 10]);
+    /// ```
+    fn merge<J>(self, other: J) -> Merge<Self, J::IntoIter>
+        where Self: Sized,
+              Self::Item: PartialOrd,
+              J: IntoIterator<Item = Self::Item>
+    {
+        merge(self, other)
+    }
+
+    /// Return an iterator adaptor that merges the two base iterators in order.
+    /// This is much like `.merge()` but allows for a custom ordering.
+    ///
+    /// This can be especially useful for sequences of tuples.
+    ///
+    /// Iterator element type is `Self::Item`.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let a = (0..).zip("bc".chars());
+    /// let b = (0..).zip("ad".chars());
+    /// let it = a.merge_by(b, |x, y| x.1 <= y.1);
+    /// itertools::assert_equal(it, vec![(0, 'a'), (0, 'b'), (1, 'c'), (1, 'd')]);
+    /// ```
+
+    fn merge_by<J, F>(self, other: J, is_first: F) -> MergeBy<Self, J::IntoIter, F>
+        where Self: Sized,
+              J: IntoIterator<Item = Self::Item>,
+              F: FnMut(&Self::Item, &Self::Item) -> bool
+    {
+        adaptors::merge_by_new(self, other.into_iter(), is_first)
+    }
+
+    /// Create an iterator that merges items from both this and the specified
+    /// iterator in ascending order.
+    ///
+    /// It chooses whether to pair elements based on the `Ordering` returned by the
+    /// specified compare function. At any point, inspecting the tip of the
+    /// iterators `I` and `J` as items `i` of type `I::Item` and `j` of type
+    /// `J::Item` respectively, the resulting iterator will:
+    ///
+    /// - Emit `EitherOrBoth::Left(i)` when `i < j`,
+    ///   and remove `i` from its source iterator
+    /// - Emit `EitherOrBoth::Right(j)` when `i > j`,
+    ///   and remove `j` from its source iterator
+    /// - Emit `EitherOrBoth::Both(i, j)` when  `i == j`,
+    ///   and remove both `i` and `j` from their respective source iterators
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    /// use itertools::EitherOrBoth::{Left, Right, Both};
+    ///
+    /// let ki = (0..10).step(3);
+    /// let ku = (0..10).step(5);
+    /// let ki_ku = ki.merge_join_by(ku, |i, j| i.cmp(j)).map(|either| {
+    ///     match either {
+    ///         Left(_) => "Ki",
+    ///         Right(_) => "Ku",
+    ///         Both(_, _) => "KiKu"
+    ///     }
+    /// });
+    ///
+    /// itertools::assert_equal(ki_ku, vec!["KiKu", "Ki", "Ku", "Ki", "Ki"]);
+    /// ```
+    #[inline]
+    fn merge_join_by<J, F>(self, other: J, cmp_fn: F) -> MergeJoinBy<Self, J::IntoIter, F>
+        where J: IntoIterator,
+              F: FnMut(&Self::Item, &J::Item) -> std::cmp::Ordering,
+              Self: Sized
+    {
+        merge_join_by(self, other, cmp_fn)
+    }
+
+
+    /// Return an iterator adaptor that flattens an iterator of iterators by
+    /// merging them in ascending order.
+    ///
+    /// If all base iterators are sorted (ascending), the result is sorted.
+    ///
+    /// Iterator element type is `Self::Item`.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let a = (0..6).step(3);
+    /// let b = (1..6).step(3);
+    /// let c = (2..6).step(3);
+    /// let it = vec![a, b, c].into_iter().kmerge();
+    /// itertools::assert_equal(it, vec![0, 1, 2, 3, 4, 5]);
+    /// ```
+    #[cfg(feature = "use_std")]
+    fn kmerge(self) -> KMerge<<Self::Item as IntoIterator>::IntoIter>
+        where Self: Sized,
+              Self::Item: IntoIterator,
+              <Self::Item as IntoIterator>::Item: PartialOrd,
+    {
+        kmerge(self)
+    }
+
+    /// Return an iterator adaptor that flattens an iterator of iterators by
+    /// merging them according to the given closure.
+    ///
+    /// The closure `first` is called with two elements *a*, *b* and should
+    /// return `true` if *a* is ordered before *b*.
+    ///
+    /// If all base iterators are sorted according to `first`, the result is
+    /// sorted.
+    ///
+    /// Iterator element type is `Self::Item`.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let a = vec![-1f64, 2., 3., -5., 6., -7.];
+    /// let b = vec![0., 2., -4.];
+    /// let mut it = vec![a, b].into_iter().kmerge_by(|a, b| a.abs() < b.abs());
+    /// assert_eq!(it.next(), Some(0.));
+    /// assert_eq!(it.last(), Some(-7.));
+    /// ```
+    #[cfg(feature = "use_std")]
+    fn kmerge_by<F>(self, first: F)
+        -> KMergeBy<<Self::Item as IntoIterator>::IntoIter, F>
+        where Self: Sized,
+              Self::Item: IntoIterator,
+              F: FnMut(&<Self::Item as IntoIterator>::Item,
+                       &<Self::Item as IntoIterator>::Item) -> bool
+    {
+        kmerge_by(self, first)
+    }
+
+    /// Return an iterator adaptor that iterates over the cartesian product of
+    /// the element sets of two iterators `self` and `J`.
+    ///
+    /// Iterator element type is `(Self::Item, J::Item)`.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let it = (0..2).cartesian_product("αβ".chars());
+    /// itertools::assert_equal(it, vec![(0, 'α'), (0, 'β'), (1, 'α'), (1, 'β')]);
+    /// ```
+    fn cartesian_product<J>(self, other: J) -> Product<Self, J::IntoIter>
+        where Self: Sized,
+              Self::Item: Clone,
+              J: IntoIterator,
+              J::IntoIter: Clone
+    {
+        adaptors::cartesian_product(self, other.into_iter())
+    }
+
+    /// Return an iterator adaptor that iterates over the cartesian product of
+    /// all subiterators returned by meta-iterator `self`.
+    ///
+    /// All provided iterators must yield the same `Item` type. To generate
+    /// the product of iterators yielding multiple types, use the
+    /// [`iproduct`](macro.iproduct.html) macro instead.
+    ///
+    ///
+    /// The iterator element type is `Vec<T>`, where `T` is the iterator element
+    /// of the subiterators.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    /// let mut multi_prod = (0..3).map(|i| (i * 2)..(i * 2 + 2))
+    ///     .multi_cartesian_product();
+    /// assert_eq!(multi_prod.next(), Some(vec![0, 2, 4]));
+    /// assert_eq!(multi_prod.next(), Some(vec![0, 2, 5]));
+    /// assert_eq!(multi_prod.next(), Some(vec![0, 3, 4]));
+    /// assert_eq!(multi_prod.next(), Some(vec![0, 3, 5]));
+    /// assert_eq!(multi_prod.next(), Some(vec![1, 2, 4]));
+    /// assert_eq!(multi_prod.next(), Some(vec![1, 2, 5]));
+    /// assert_eq!(multi_prod.next(), Some(vec![1, 3, 4]));
+    /// assert_eq!(multi_prod.next(), Some(vec![1, 3, 5]));
+    /// assert_eq!(multi_prod.next(), None);
+    /// ```
+    #[cfg(feature = "use_std")]
+    fn multi_cartesian_product(self) -> MultiProduct<<Self::Item as IntoIterator>::IntoIter>
+        where Self: Iterator + Sized,
+              Self::Item: IntoIterator,
+              <Self::Item as IntoIterator>::IntoIter: Clone,
+              <Self::Item as IntoIterator>::Item: Clone
+    {
+        adaptors::multi_cartesian_product(self)
+    }
+
+    /// Return an iterator adaptor that uses the passed-in closure to
+    /// optionally merge together consecutive elements.
+    ///
+    /// The closure `f` is passed two elements, `previous` and `current` and may
+    /// return either (1) `Ok(combined)` to merge the two values or
+    /// (2) `Err((previous', current'))` to indicate they can't be merged.
+    /// In (2), the value `previous'` is emitted by the iterator.
+    /// Either (1) `combined` or (2) `current'` becomes the previous value
+    /// when coalesce continues with the next pair of elements to merge. The
+    /// value that remains at the end is also emitted by the iterator.
+    ///
+    /// Iterator element type is `Self::Item`.
+    ///
+    /// This iterator is *fused*.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// // sum same-sign runs together
+    /// let data = vec![-1., -2., -3., 3., 1., 0., -1.];
+    /// itertools::assert_equal(data.into_iter().coalesce(|x, y|
+    ///         if (x >= 0.) == (y >= 0.) {
+    ///             Ok(x + y)
+    ///         } else {
+    ///             Err((x, y))
+    ///         }),
+    ///         vec![-6., 4., -1.]);
+    /// ```
+    fn coalesce<F>(self, f: F) -> Coalesce<Self, F>
+        where Self: Sized,
+              F: FnMut(Self::Item, Self::Item)
+                       -> Result<Self::Item, (Self::Item, Self::Item)>
+    {
+        adaptors::coalesce(self, f)
+    }
+
+    /// Remove duplicates from sections of consecutive identical elements.
+    /// If the iterator is sorted, all elements will be unique.
+    ///
+    /// Iterator element type is `Self::Item`.
+    ///
+    /// This iterator is *fused*.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let data = vec![1., 1., 2., 3., 3., 2., 2.];
+    /// itertools::assert_equal(data.into_iter().dedup(),
+    ///                         vec![1., 2., 3., 2.]);
+    /// ```
+    fn dedup(self) -> Dedup<Self>
+        where Self: Sized,
+              Self::Item: PartialEq,
+    {
+        adaptors::dedup(self)
+    }
+
+    /// Remove duplicates from sections of consecutive identical elements,
+    /// determining equality using a comparison function.
+    /// If the iterator is sorted, all elements will be unique.
+    ///
+    /// Iterator element type is `Self::Item`.
+    ///
+    /// This iterator is *fused*.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let data = vec![(0, 1.), (1, 1.), (0, 2.), (0, 3.), (1, 3.), (1, 2.), (2, 2.)];
+    /// itertools::assert_equal(data.into_iter().dedup_by(|x, y| x.1==y.1),
+    ///                         vec![(0, 1.), (0, 2.), (0, 3.), (1, 2.)]);
+    /// ```
+    fn dedup_by<Cmp>(self, cmp: Cmp) -> DedupBy<Self, Cmp>
+        where Self: Sized,
+              Cmp: FnMut(&Self::Item, &Self::Item)->bool,
+    {
+        adaptors::dedup_by(self, cmp)
+    }
+
+    /// Return an iterator adaptor that filters out elements that have
+    /// already been produced once during the iteration. Duplicates
+    /// are detected using hash and equality.
+    ///
+    /// Clones of visited elements are stored in a hash set in the
+    /// iterator.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let data = vec![10, 20, 30, 20, 40, 10, 50];
+    /// itertools::assert_equal(data.into_iter().unique(),
+    ///                         vec![10, 20, 30, 40, 50]);
+    /// ```
+    #[cfg(feature = "use_std")]
+    fn unique(self) -> Unique<Self>
+        where Self: Sized,
+              Self::Item: Clone + Eq + Hash
+    {
+        unique_impl::unique(self)
+    }
+
+    /// Return an iterator adaptor that filters out elements that have
+    /// already been produced once during the iteration.
+    ///
+    /// Duplicates are detected by comparing the key they map to
+    /// with the keying function `f` by hash and equality.
+    /// The keys are stored in a hash set in the iterator.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let data = vec!["a", "bb", "aa", "c", "ccc"];
+    /// itertools::assert_equal(data.into_iter().unique_by(|s| s.len()),
+    ///                         vec!["a", "bb", "ccc"]);
+    /// ```
+    #[cfg(feature = "use_std")]
+    fn unique_by<V, F>(self, f: F) -> UniqueBy<Self, V, F>
+        where Self: Sized,
+              V: Eq + Hash,
+              F: FnMut(&Self::Item) -> V
+    {
+        unique_impl::unique_by(self, f)
+    }
+
+    /// Return an iterator adaptor that borrows from this iterator and
+    /// takes items while the closure `accept` returns `true`.
+    ///
+    /// This adaptor can only be used on iterators that implement `PeekingNext`
+    /// like `.peekable()`, `put_back` and a few other collection iterators.
+    ///
+    /// The last and rejected element (first `false`) is still available when
+    /// `peeking_take_while` is done.
+    ///
+    ///
+    /// See also [`.take_while_ref()`](#method.take_while_ref)
+    /// which is a similar adaptor.
+    fn peeking_take_while<F>(&mut self, accept: F) -> PeekingTakeWhile<Self, F>
+        where Self: Sized + PeekingNext,
+              F: FnMut(&Self::Item) -> bool,
+    {
+        peeking_take_while::peeking_take_while(self, accept)
+    }
+
+    /// Return an iterator adaptor that borrows from a `Clone`-able iterator
+    /// to only pick off elements while the predicate `accept` returns `true`.
+    ///
+    /// It uses the `Clone` trait to restore the original iterator so that the
+    /// last and rejected element (first `false`) is still available when
+    /// `take_while_ref` is done.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let mut hexadecimals = "0123456789abcdef".chars();
+    ///
+    /// let decimals = hexadecimals.take_while_ref(|c| c.is_numeric())
+    ///                            .collect::<String>();
+    /// assert_eq!(decimals, "0123456789");
+    /// assert_eq!(hexadecimals.next(), Some('a'));
+    ///
+    /// ```
+    fn take_while_ref<F>(&mut self, accept: F) -> TakeWhileRef<Self, F>
+        where Self: Clone,
+              F: FnMut(&Self::Item) -> bool
+    {
+        adaptors::take_while_ref(self, accept)
+    }
+
+    /// Return an iterator adaptor that filters `Option<A>` iterator elements
+    /// and produces `A`. Stops on the first `None` encountered.
+    ///
+    /// Iterator element type is `A`, the unwrapped element.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// // List all hexadecimal digits
+    /// itertools::assert_equal(
+    ///     (0..).map(|i| std::char::from_digit(i, 16)).while_some(),
+    ///     "0123456789abcdef".chars());
+    ///
+    /// ```
+    fn while_some<A>(self) -> WhileSome<Self>
+        where Self: Sized + Iterator<Item = Option<A>>
+    {
+        adaptors::while_some(self)
+    }
+
+    /// Return an iterator adaptor that iterates over the combinations of the
+    /// elements from an iterator.
+    ///
+    /// Iterator element can be any homogeneous tuple of type `Self::Item` with
+    /// size up to 4.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let mut v = Vec::new();
+    /// for (a, b) in (1..5).tuple_combinations() {
+    ///     v.push((a, b));
+    /// }
+    /// assert_eq!(v, vec![(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]);
+    ///
+    /// let mut it = (1..5).tuple_combinations();
+    /// assert_eq!(Some((1, 2, 3)), it.next());
+    /// assert_eq!(Some((1, 2, 4)), it.next());
+    /// assert_eq!(Some((1, 3, 4)), it.next());
+    /// assert_eq!(Some((2, 3, 4)), it.next());
+    /// assert_eq!(None, it.next());
+    ///
+    /// // this requires a type hint
+    /// let it = (1..5).tuple_combinations::<(_, _, _)>();
+    /// itertools::assert_equal(it, vec![(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]);
+    ///
+    /// // you can also specify the complete type
+    /// use itertools::TupleCombinations;
+    /// use std::ops::Range;
+    ///
+    /// let it: TupleCombinations<Range<u32>, (u32, u32, u32)> = (1..5).tuple_combinations();
+    /// itertools::assert_equal(it, vec![(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]);
+    /// ```
+    fn tuple_combinations<T>(self) -> TupleCombinations<Self, T>
+        where Self: Sized + Clone,
+              Self::Item: Clone,
+              T: adaptors::HasCombination<Self>,
+    {
+        adaptors::tuple_combinations(self)
+    }
+
+    /// Return an iterator adaptor that iterates over the `k`-length combinations of
+    /// the elements from an iterator.
+    ///
+    /// Iterator element type is `Vec<Self::Item>`. The iterator produces a new Vec per iteration,
+    /// and clones the iterator elements.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let it = (1..5).combinations(3);
+    /// itertools::assert_equal(it, vec![
+    ///     vec![1, 2, 3],
+    ///     vec![1, 2, 4],
+    ///     vec![1, 3, 4],
+    ///     vec![2, 3, 4],
+    /// ]);
+    /// ```
+    ///
+    /// Note: Combinations does not take into account the equality of the iterated values.
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let it = vec![1, 2, 2].into_iter().combinations(2);
+    /// itertools::assert_equal(it, vec![
+    ///     vec![1, 2], // Note: these are the same
+    ///     vec![1, 2], // Note: these are the same
+    ///     vec![2, 2],
+    /// ]);
+    /// ```
+    #[cfg(feature = "use_std")]
+    fn combinations(self, k: usize) -> Combinations<Self>
+        where Self: Sized,
+              Self::Item: Clone
+    {
+        combinations::combinations(self, k)
+    }
+
+    /// Return an iterator that iterates over the `k`-length combinations of
+    /// the elements from an iterator, with replacement.
+    ///
+    /// Iterator element type is `Vec<Self::Item>`. The iterator produces a new Vec per iteration,
+    /// and clones the iterator elements.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let it = (1..4).combinations_with_replacement(2);
+    /// itertools::assert_equal(it, vec![
+    ///     vec![1, 1],
+    ///     vec![1, 2],
+    ///     vec![1, 3],
+    ///     vec![2, 2],
+    ///     vec![2, 3],
+    ///     vec![3, 3],
+    /// ]);
+    /// ```
+    #[cfg(feature = "use_std")]
+    fn combinations_with_replacement(self, k: usize) -> CombinationsWithReplacement<Self>
+    where
+        Self: Sized,
+        Self::Item: Clone,
+    {
+        combinations_with_replacement::combinations_with_replacement(self, k)
+    }
+
+    /// Return an iterator adaptor that iterates over all k-permutations of the
+    /// elements from an iterator.
+    ///
+    /// Iterator element type is `Vec<Self::Item>` with length `k`. The iterator
+    /// produces a new Vec per iteration, and clones the iterator elements.
+    ///
+    /// If `k` is greater than the length of the input iterator, the resultant
+    /// iterator adaptor will be empty.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let perms = (5..8).permutations(2);
+    /// itertools::assert_equal(perms, vec![
+    ///     vec![5, 6],
+    ///     vec![5, 7],
+    ///     vec![6, 5],
+    ///     vec![6, 7],
+    ///     vec![7, 5],
+    ///     vec![7, 6],
+    /// ]);
+    /// ```
+    ///
+    /// Note: Permutations does not take into account the equality of the iterated values.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let it = vec![2, 2].into_iter().permutations(2);
+    /// itertools::assert_equal(it, vec![
+    ///     vec![2, 2], // Note: these are the same
+    ///     vec![2, 2], // Note: these are the same
+    /// ]);
+    /// ```
+    ///
+    /// Note: The source iterator is collected lazily, and will not be
+    /// re-iterated if the permutations adaptor is completed and re-iterated.
+    #[cfg(feature = "use_std")]
+    fn permutations(self, k: usize) -> Permutations<Self>
+        where Self: Sized,
+              Self::Item: Clone
+    {
+        permutations::permutations(self, k)
+    }
+
+    /// Return an iterator adaptor that pads the sequence to a minimum length of
+    /// `min` by filling missing elements using a closure `f`.
+    ///
+    /// Iterator element type is `Self::Item`.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let it = (0..5).pad_using(10, |i| 2*i);
+    /// itertools::assert_equal(it, vec![0, 1, 2, 3, 4, 10, 12, 14, 16, 18]);
+    ///
+    /// let it = (0..10).pad_using(5, |i| 2*i);
+    /// itertools::assert_equal(it, vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
+    ///
+    /// let it = (0..5).pad_using(10, |i| 2*i).rev();
+    /// itertools::assert_equal(it, vec![18, 16, 14, 12, 10, 4, 3, 2, 1, 0]);
+    /// ```
+    fn pad_using<F>(self, min: usize, f: F) -> PadUsing<Self, F>
+        where Self: Sized,
+              F: FnMut(usize) -> Self::Item
+    {
+        pad_tail::pad_using(self, min, f)
+    }
+
+    /// Return an iterator adaptor that wraps each element in a `Position` to
+    /// ease special-case handling of the first or last elements.
+    ///
+    /// Iterator element type is
+    /// [`Position<Self::Item>`](enum.Position.html)
+    ///
+    /// ```
+    /// use itertools::{Itertools, Position};
+    ///
+    /// let it = (0..4).with_position();
+    /// itertools::assert_equal(it,
+    ///                         vec![Position::First(0),
+    ///                              Position::Middle(1),
+    ///                              Position::Middle(2),
+    ///                              Position::Last(3)]);
+    ///
+    /// let it = (0..1).with_position();
+    /// itertools::assert_equal(it, vec![Position::Only(0)]);
+    /// ```
+    fn with_position(self) -> WithPosition<Self>
+        where Self: Sized,
+    {
+        with_position::with_position(self)
+    }
+
+    /// Return an iterator adaptor that yields the indices of all elements
+    /// satisfying a predicate, counted from the start of the iterator.
+    ///
+    /// Equivalent to `iter.enumerate().filter(|(_, v)| predicate(v)).map(|(i, _)| i)`.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let data = vec![1, 2, 3, 3, 4, 6, 7, 9];
+    /// itertools::assert_equal(data.iter().positions(|v| v % 2 == 0), vec![1, 4, 5]);
+    ///
+    /// itertools::assert_equal(data.iter().positions(|v| v % 2 == 1).rev(), vec![7, 6, 3, 2, 0]);
+    /// ```
+    fn positions<P>(self, predicate: P) -> Positions<Self, P>
+        where Self: Sized,
+              P: FnMut(Self::Item) -> bool,
+    {
+        adaptors::positions(self, predicate)
+    }
+
+    /// Return an iterator adaptor that applies a mutating function
+    /// to each element before yielding it.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let input = vec![vec![1], vec![3, 2, 1]];
+    /// let it = input.into_iter().update(|mut v| v.push(0));
+    /// itertools::assert_equal(it, vec![vec![1, 0], vec![3, 2, 1, 0]]);
+    /// ```
+    fn update<F>(self, updater: F) -> Update<Self, F>
+        where Self: Sized,
+              F: FnMut(&mut Self::Item),
+    {
+        adaptors::update(self, updater)
+    }
+
+    // non-adaptor methods
+    /// Advances the iterator and returns the next items grouped in a tuple of
+    /// a specific size (up to 4).
+    ///
+    /// If there are enough elements to be grouped in a tuple, then the tuple is
+    /// returned inside `Some`, otherwise `None` is returned.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let mut iter = 1..5;
+    ///
+    /// assert_eq!(Some((1, 2)), iter.next_tuple());
+    /// ```
+    fn next_tuple<T>(&mut self) -> Option<T>
+        where Self: Sized + Iterator<Item = T::Item>,
+              T: traits::HomogeneousTuple
+    {
+        T::collect_from_iter_no_buf(self)
+    }
+
+    /// Collects all items from the iterator into a tuple of a specific size
+    /// (up to 4).
+    ///
+    /// If the number of elements inside the iterator is **exactly** equal to
+    /// the tuple size, then the tuple is returned inside `Some`, otherwise
+    /// `None` is returned.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let iter = 1..3;
+    ///
+    /// if let Some((x, y)) = iter.collect_tuple() {
+    ///     assert_eq!((x, y), (1, 2))
+    /// } else {
+    ///     panic!("Expected two elements")
+    /// }
+    /// ```
+    fn collect_tuple<T>(mut self) -> Option<T>
+        where Self: Sized + Iterator<Item = T::Item>,
+              T: traits::HomogeneousTuple
+    {
+        match self.next_tuple() {
+            elt @ Some(_) => match self.next() {
+                Some(_) => None,
+                None => elt,
+            },
+            _ => None
+        }
+    }
+
+
+    /// Find the position and value of the first element satisfying a predicate.
+    ///
+    /// The iterator is not advanced past the first element found.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let text = "Hα";
+    /// assert_eq!(text.chars().find_position(|ch| ch.is_lowercase()), Some((1, 'α')));
+    /// ```
+    fn find_position<P>(&mut self, mut pred: P) -> Option<(usize, Self::Item)>
+        where P: FnMut(&Self::Item) -> bool
+    {
+        let mut index = 0usize;
+        for elt in self {
+            if pred(&elt) {
+                return Some((index, elt));
+            }
+            index += 1;
+        }
+        None
+    }
+
+    /// Check whether all elements compare equal.
+    ///
+    /// Empty iterators are considered to have equal elements:
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let data = vec![1, 1, 1, 2, 2, 3, 3, 3, 4, 5, 5];
+    /// assert!(!data.iter().all_equal());
+    /// assert!(data[0..3].iter().all_equal());
+    /// assert!(data[3..5].iter().all_equal());
+    /// assert!(data[5..8].iter().all_equal());
+    ///
+    /// let data : Option<usize> = None;
+    /// assert!(data.into_iter().all_equal());
+    /// ```
+    fn all_equal(&mut self) -> bool
+        where Self: Sized,
+              Self::Item: PartialEq,
+    {
+        match self.next() {
+            None => true,
+            Some(a) => self.all(|x| a == x),
+        }
+    }
+
+    /// Consume the first `n` elements from the iterator eagerly,
+    /// and return the same iterator again.
+    ///
+    /// It works similarly to *.skip(* `n` *)* except it is eager and
+    /// preserves the iterator type.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let mut iter = "αβγ".chars().dropping(2);
+    /// itertools::assert_equal(iter, "γ".chars());
+    /// ```
+    ///
+    /// *Fusing notes: if the iterator is exhausted by dropping,
+    /// the result of calling `.next()` again depends on the iterator implementation.*
+    fn dropping(mut self, n: usize) -> Self
+        where Self: Sized
+    {
+        if n > 0 {
+            self.nth(n - 1);
+        }
+        self
+    }
+
+    /// Consume the last `n` elements from the iterator eagerly,
+    /// and return the same iterator again.
+    ///
+    /// This is only possible on double ended iterators. `n` may be
+    /// larger than the number of elements.
+    ///
+    /// Note: This method is eager, dropping the back elements immediately and
+    /// preserves the iterator type.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let init = vec![0, 3, 6, 9].into_iter().dropping_back(1);
+    /// itertools::assert_equal(init, vec![0, 3, 6]);
+    /// ```
+    fn dropping_back(mut self, n: usize) -> Self
+        where Self: Sized,
+              Self: DoubleEndedIterator
+    {
+        if n > 0 {
+            (&mut self).rev().nth(n - 1);
+        }
+        self
+    }
+
+    /// Run the closure `f` eagerly on each element of the iterator.
+    ///
+    /// Consumes the iterator until its end.
+    ///
+    /// ```
+    /// use std::sync::mpsc::channel;
+    /// use itertools::Itertools;
+    ///
+    /// let (tx, rx) = channel();
+    ///
+    /// // use .foreach() to apply a function to each value -- sending it
+    /// (0..5).map(|x| x * 2 + 1).foreach(|x| { tx.send(x).unwrap(); } );
+    ///
+    /// drop(tx);
+    ///
+    /// itertools::assert_equal(rx.iter(), vec![1, 3, 5, 7, 9]);
+    /// ```
+    #[deprecated(note="Use .for_each() instead", since="0.8")]
+    fn foreach<F>(self, f: F)
+        where F: FnMut(Self::Item),
+              Self: Sized,
+    {
+        self.for_each(f)
+    }
+
+    /// Combine all an iterator's elements into one element by using `Extend`.
+    ///
+    /// This combinator will extend the first item with each of the rest of the
+    /// items of the iterator. If the iterator is empty, the default value of
+    /// `I::Item` is returned.
+    ///
+    /// ```rust
+    /// use itertools::Itertools;
+    ///
+    /// let input = vec![vec![1], vec![2, 3], vec![4, 5, 6]];
+    /// assert_eq!(input.into_iter().concat(),
+    ///            vec![1, 2, 3, 4, 5, 6]);
+    /// ```
+    fn concat(self) -> Self::Item
+        where Self: Sized,
+              Self::Item: Extend<<<Self as Iterator>::Item as IntoIterator>::Item> + IntoIterator + Default
+    {
+        concat(self)
+    }
+
+    /// `.collect_vec()` is simply a type specialization of `.collect()`,
+    /// for convenience.
+    #[cfg(feature = "use_std")]
+    fn collect_vec(self) -> Vec<Self::Item>
+        where Self: Sized
+    {
+        self.collect()
+    }
+
+    /// `.try_collect()` is more convenient way of writing
+    /// `.collect::<Result<_, _>>()`
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::{fs, io};
+    /// use itertools::Itertools;
+    ///
+    /// fn process_dir_entries(entries: &[fs::DirEntry]) {
+    ///     // ...
+    /// }
+    ///
+    /// fn do_stuff() -> std::io::Result<()> {
+    ///     let entries: Vec<_> = fs::read_dir(".")?.try_collect()?;
+    ///     process_dir_entries(&entries);
+    ///
+    ///     Ok(())
+    /// }
+    /// ```
+    #[cfg(feature = "use_std")]
+    fn try_collect<T, U, E>(self) -> Result<U, E>
+    where
+        Self: Sized + Iterator<Item = Result<T, E>>,
+        Result<U, E>: FromIterator<Result<T, E>>,
+    {
+        self.collect()
+    }
+
+    /// Assign to each reference in `self` from the `from` iterator,
+    /// stopping at the shortest of the two iterators.
+    ///
+    /// The `from` iterator is queried for its next element before the `self`
+    /// iterator, and if either is exhausted the method is done.
+    ///
+    /// Return the number of elements written.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let mut xs = [0; 4];
+    /// xs.iter_mut().set_from(1..);
+    /// assert_eq!(xs, [1, 2, 3, 4]);
+    /// ```
+    #[inline]
+    fn set_from<'a, A: 'a, J>(&mut self, from: J) -> usize
+        where Self: Iterator<Item = &'a mut A>,
+              J: IntoIterator<Item = A>
+    {
+        let mut count = 0;
+        for elt in from {
+            match self.next() {
+                None => break,
+                Some(ptr) => *ptr = elt,
+            }
+            count += 1;
+        }
+        count
+    }
+
+    /// Combine all iterator elements into one String, separated by `sep`.
+    ///
+    /// Use the `Display` implementation of each element.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// assert_eq!(["a", "b", "c"].iter().join(", "), "a, b, c");
+    /// assert_eq!([1, 2, 3].iter().join(", "), "1, 2, 3");
+    /// ```
+    #[cfg(feature = "use_std")]
+    fn join(&mut self, sep: &str) -> String
+        where Self::Item: std::fmt::Display
+    {
+        match self.next() {
+            None => String::new(),
+            Some(first_elt) => {
+                // estimate lower bound of capacity needed
+                let (lower, _) = self.size_hint();
+                let mut result = String::with_capacity(sep.len() * lower);
+                write!(&mut result, "{}", first_elt).unwrap();
+                for elt in self {
+                    result.push_str(sep);
+                    write!(&mut result, "{}", elt).unwrap();
+                }
+                result
+            }
+        }
+    }
+
+    /// Format all iterator elements, separated by `sep`.
+    ///
+    /// All elements are formatted (any formatting trait)
+    /// with `sep` inserted between each element.
+    ///
+    /// **Panics** if the formatter helper is formatted more than once.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let data = [1.1, 2.71828, -3.];
+    /// assert_eq!(
+    ///     format!("{:.2}", data.iter().format(", ")),
+    ///            "1.10, 2.72, -3.00");
+    /// ```
+    fn format(self, sep: &str) -> Format<Self>
+        where Self: Sized,
+    {
+        format::new_format_default(self, sep)
+    }
+
+    /// Format all iterator elements, separated by `sep`.
+    ///
+    /// This is a customizable version of `.format()`.
+    ///
+    /// The supplied closure `format` is called once per iterator element,
+    /// with two arguments: the element and a callback that takes a
+    /// `&Display` value, i.e. any reference to type that implements `Display`.
+    ///
+    /// Using `&format_args!(...)` is the most versatile way to apply custom
+    /// element formatting. The callback can be called multiple times if needed.
+    ///
+    /// **Panics** if the formatter helper is formatted more than once.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let data = [1.1, 2.71828, -3.];
+    /// let data_formatter = data.iter().format_with(", ", |elt, f| f(&format_args!("{:.2}", elt)));
+    /// assert_eq!(format!("{}", data_formatter),
+    ///            "1.10, 2.72, -3.00");
+    ///
+    /// // .format_with() is recursively composable
+    /// let matrix = [[1., 2., 3.],
+    ///               [4., 5., 6.]];
+    /// let matrix_formatter = matrix.iter().format_with("\n", |row, f| {
+    ///                                 f(&row.iter().format_with(", ", |elt, g| g(&elt)))
+    ///                              });
+    /// assert_eq!(format!("{}", matrix_formatter),
+    ///            "1, 2, 3\n4, 5, 6");
+    ///
+    ///
+    /// ```
+    fn format_with<F>(self, sep: &str, format: F) -> FormatWith<Self, F>
+        where Self: Sized,
+              F: FnMut(Self::Item, &mut dyn FnMut(&dyn fmt::Display) -> fmt::Result) -> fmt::Result,
+    {
+        format::new_format(self, sep, format)
+    }
+
+    /// Fold `Result` values from an iterator.
+    ///
+    /// Only `Ok` values are folded. If no error is encountered, the folded
+    /// value is returned inside `Ok`. Otherwise, the operation terminates
+    /// and returns the first `Err` value it encounters. No iterator elements are
+    /// consumed after the first error.
+    ///
+    /// The first accumulator value is the `start` parameter.
+    /// Each iteration passes the accumulator value and the next value inside `Ok`
+    /// to the fold function `f` and its return value becomes the new accumulator value.
+    ///
+    /// For example the sequence *Ok(1), Ok(2), Ok(3)* will result in a
+    /// computation like this:
+    ///
+    /// ```ignore
+    /// let mut accum = start;
+    /// accum = f(accum, 1);
+    /// accum = f(accum, 2);
+    /// accum = f(accum, 3);
+    /// ```
+    ///
+    /// With a `start` value of 0 and an addition as folding function,
+    /// this effectively results in *((0 + 1) + 2) + 3*
+    ///
+    /// ```
+    /// use std::ops::Add;
+    /// use itertools::Itertools;
+    ///
+    /// let values = [1, 2, -2, -1, 2, 1];
+    /// assert_eq!(
+    ///     values.iter()
+    ///           .map(Ok::<_, ()>)
+    ///           .fold_results(0, Add::add),
+    ///     Ok(3)
+    /// );
+    /// assert!(
+    ///     values.iter()
+    ///           .map(|&x| if x >= 0 { Ok(x) } else { Err("Negative number") })
+    ///           .fold_results(0, Add::add)
+    ///           .is_err()
+    /// );
+    /// ```
+    fn fold_results<A, E, B, F>(&mut self, mut start: B, mut f: F) -> Result<B, E>
+        where Self: Iterator<Item = Result<A, E>>,
+              F: FnMut(B, A) -> B
+    {
+        for elt in self {
+            match elt {
+                Ok(v) => start = f(start, v),
+                Err(u) => return Err(u),
+            }
+        }
+        Ok(start)
+    }
+
+    /// Fold `Option` values from an iterator.
+    ///
+    /// Only `Some` values are folded. If no `None` is encountered, the folded
+    /// value is returned inside `Some`. Otherwise, the operation terminates
+    /// and returns `None`. No iterator elements are consumed after the `None`.
+    ///
+    /// This is the `Option` equivalent to `fold_results`.
+    ///
+    /// ```
+    /// use std::ops::Add;
+    /// use itertools::Itertools;
+    ///
+    /// let mut values = vec![Some(1), Some(2), Some(-2)].into_iter();
+    /// assert_eq!(values.fold_options(5, Add::add), Some(5 + 1 + 2 - 2));
+    ///
+    /// let mut more_values = vec![Some(2), None, Some(0)].into_iter();
+    /// assert!(more_values.fold_options(0, Add::add).is_none());
+    /// assert_eq!(more_values.next().unwrap(), Some(0));
+    /// ```
+    fn fold_options<A, B, F>(&mut self, mut start: B, mut f: F) -> Option<B>
+        where Self: Iterator<Item = Option<A>>,
+              F: FnMut(B, A) -> B
+    {
+        for elt in self {
+            match elt {
+                Some(v) => start = f(start, v),
+                None => return None,
+            }
+        }
+        Some(start)
+    }
+
+    /// Accumulator of the elements in the iterator.
+    ///
+    /// Like `.fold()`, without a base case. If the iterator is
+    /// empty, return `None`. With just one element, return it.
+    /// Otherwise elements are accumulated in sequence using the closure `f`.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// assert_eq!((0..10).fold1(|x, y| x + y).unwrap_or(0), 45);
+    /// assert_eq!((0..0).fold1(|x, y| x * y), None);
+    /// ```
+    fn fold1<F>(mut self, f: F) -> Option<Self::Item>
+        where F: FnMut(Self::Item, Self::Item) -> Self::Item,
+              Self: Sized,
+    {
+        self.next().map(move |x| self.fold(x, f))
+    }
+
+    /// Accumulate the elements in the iterator in a tree-like manner.
+    ///
+    /// You can think of it as, while there's more than one item, repeatedly
+    /// combining adjacent items.  It does so in bottom-up-merge-sort order,
+    /// however, so that it needs only logarithmic stack space.
+    ///
+    /// This produces a call tree like the following (where the calls under
+    /// an item are done after reading that item):
+    ///
+    /// ```text
+    /// 1 2 3 4 5 6 7
+    /// │ │ │ │ │ │ │
+    /// └─f └─f └─f │
+    ///   │   │   │ │
+    ///   └───f   └─f
+    ///       │     │
+    ///       └─────f
+    /// ```
+    ///
+    /// Which, for non-associative functions, will typically produce a different
+    /// result than the linear call tree used by `fold1`:
+    ///
+    /// ```text
+    /// 1 2 3 4 5 6 7
+    /// │ │ │ │ │ │ │
+    /// └─f─f─f─f─f─f
+    /// ```
+    ///
+    /// If `f` is associative, prefer the normal `fold1` instead.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// // The same tree as above
+    /// let num_strings = (1..8).map(|x| x.to_string());
+    /// assert_eq!(num_strings.tree_fold1(|x, y| format!("f({}, {})", x, y)),
+    ///     Some(String::from("f(f(f(1, 2), f(3, 4)), f(f(5, 6), 7))")));
+    ///
+    /// // Like fold1, an empty iterator produces None
+    /// assert_eq!((0..0).tree_fold1(|x, y| x * y), None);
+    ///
+    /// // tree_fold1 matches fold1 for associative operations...
+    /// assert_eq!((0..10).tree_fold1(|x, y| x + y),
+    ///     (0..10).fold1(|x, y| x + y));
+    /// // ...but not for non-associative ones
+    /// assert_ne!((0..10).tree_fold1(|x, y| x - y),
+    ///     (0..10).fold1(|x, y| x - y));
+    /// ```
+    fn tree_fold1<F>(mut self, mut f: F) -> Option<Self::Item>
+        where F: FnMut(Self::Item, Self::Item) -> Self::Item,
+              Self: Sized,
+    {
+        type State<T> = Result<T, Option<T>>;
+
+        fn inner0<T, II, FF>(it: &mut II, f: &mut FF) -> State<T>
+            where
+                II: Iterator<Item = T>,
+                FF: FnMut(T, T) -> T
+        {
+            // This function could be replaced with `it.next().ok_or(None)`,
+            // but half the useful tree_fold1 work is combining adjacent items,
+            // so put that in a form that LLVM is more likely to optimize well.
+
+            let a =
+                if let Some(v) = it.next() { v }
+                else { return Err(None) };
+            let b =
+                if let Some(v) = it.next() { v }
+                else { return Err(Some(a)) };
+            Ok(f(a, b))
+        }
+
+        fn inner<T, II, FF>(stop: usize, it: &mut II, f: &mut FF) -> State<T>
+            where
+                II: Iterator<Item = T>,
+                FF: FnMut(T, T) -> T
+        {
+            let mut x = inner0(it, f)?;
+            for height in 0..stop {
+                // Try to get another tree the same size with which to combine it,
+                // creating a new tree that's twice as big for next time around.
+                let next =
+                    if height == 0 {
+                        inner0(it, f)
+                    } else {
+                        inner(height, it, f)
+                    };
+                match next {
+                    Ok(y) => x = f(x, y),
+
+                    // If we ran out of items, combine whatever we did manage
+                    // to get.  It's better combined with the current value
+                    // than something in a parent frame, because the tree in
+                    // the parent is always as least as big as this one.
+                    Err(None) => return Err(Some(x)),
+                    Err(Some(y)) => return Err(Some(f(x, y))),
+                }
+            }
+            Ok(x)
+        }
+
+        match inner(usize::max_value(), &mut self, &mut f) {
+            Err(x) => x,
+            _ => unreachable!(),
+        }
+    }
+
+    /// An iterator method that applies a function, producing a single, final value.
+    ///
+    /// `fold_while()` is basically equivalent to `fold()` but with additional support for
+    /// early exit via short-circuiting.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    /// use itertools::FoldWhile::{Continue, Done};
+    ///
+    /// let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+    ///
+    /// let mut result = 0;
+    ///
+    /// // for loop:
+    /// for i in &numbers {
+    ///     if *i > 5 {
+    ///         break;
+    ///     }
+    ///     result = result + i;
+    /// }
+    ///
+    /// // fold:
+    /// let result2 = numbers.iter().fold(0, |acc, x| {
+    ///     if *x > 5 { acc } else { acc + x }
+    /// });
+    ///
+    /// // fold_while:
+    /// let result3 = numbers.iter().fold_while(0, |acc, x| {
+    ///     if *x > 5 { Done(acc) } else { Continue(acc + x) }
+    /// }).into_inner();
+    ///
+    /// // they're the same
+    /// assert_eq!(result, result2);
+    /// assert_eq!(result2, result3);
+    /// ```
+    ///
+    /// The big difference between the computations of `result2` and `result3` is that while
+    /// `fold()` called the provided closure for every item of the callee iterator,
+    /// `fold_while()` actually stopped iterating as soon as it encountered `Fold::Done(_)`.
+    #[deprecated(note="Use .try_fold() instead", since="0.8")]
+    fn fold_while<B, F>(&mut self, init: B, mut f: F) -> FoldWhile<B>
+        where Self: Sized,
+              F: FnMut(B, Self::Item) -> FoldWhile<B>
+    {
+        let mut acc = init;
+        while let Some(item) = self.next() {
+            match f(acc, item) {
+                FoldWhile::Continue(res) => acc = res,
+                res @ FoldWhile::Done(_) => return res,
+            }
+        }
+        FoldWhile::Continue(acc)
+    }
+
+    /// Iterate over the entire iterator and add all the elements.
+    ///
+    /// An empty iterator returns `None`, otherwise `Some(sum)`.
+    ///
+    /// # Panics
+    ///
+    /// When calling `sum1()` and a primitive integer type is being returned, this
+    /// method will panic if the computation overflows and debug assertions are
+    /// enabled.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let empty_sum = (1..1).sum1::<i32>();
+    /// assert_eq!(empty_sum, None);
+    ///
+    /// let nonempty_sum = (1..11).sum1::<i32>();
+    /// assert_eq!(nonempty_sum, Some(55));
+    /// ```
+    fn sum1<S>(mut self) -> Option<S>
+        where Self: Sized,
+              S: std::iter::Sum<Self::Item>,
+    {
+        self.next()
+            .map(|first| once(first).chain(self).sum())
+    }
+
+    /// Iterate over the entire iterator and multiply all the elements.
+    ///
+    /// An empty iterator returns `None`, otherwise `Some(product)`.
+    ///
+    /// # Panics
+    ///
+    /// When calling `product1()` and a primitive integer type is being returned,
+    /// method will panic if the computation overflows and debug assertions are
+    /// enabled.
+    ///
+    /// # Examples
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let empty_product = (1..1).product1::<i32>();
+    /// assert_eq!(empty_product, None);
+    ///
+    /// let nonempty_product = (1..11).product1::<i32>();
+    /// assert_eq!(nonempty_product, Some(3628800));
+    /// ```
+    fn product1<P>(mut self) -> Option<P>
+        where Self: Sized,
+              P: std::iter::Product<Self::Item>,
+    {
+        self.next()
+            .map(|first| once(first).chain(self).product())
+    }
+
+
+    /// Sort all iterator elements into a new iterator in ascending order.
+    ///
+    /// **Note:** This consumes the entire iterator, uses the
+    /// `slice::sort()` method and returns the result as a new
+    /// iterator that owns its elements.
+    ///
+    /// The sorted iterator, if directly collected to a `Vec`, is converted
+    /// without any extra copying or allocation cost.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// // sort the letters of the text in ascending order
+    /// let text = "bdacfe";
+    /// itertools::assert_equal(text.chars().sorted(),
+    ///                         "abcdef".chars());
+    /// ```
+    #[cfg(feature = "use_std")]
+    fn sorted(self) -> VecIntoIter<Self::Item>
+        where Self: Sized,
+              Self::Item: Ord
+    {
+        // Use .sort() directly since it is not quite identical with
+        // .sort_by(Ord::cmp)
+        let mut v = Vec::from_iter(self);
+        v.sort();
+        v.into_iter()
+    }
+
+    /// Sort all iterator elements into a new iterator in ascending order.
+    ///
+    /// **Note:** This consumes the entire iterator, uses the
+    /// `slice::sort_by()` method and returns the result as a new
+    /// iterator that owns its elements.
+    ///
+    /// The sorted iterator, if directly collected to a `Vec`, is converted
+    /// without any extra copying or allocation cost.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// // sort people in descending order by age
+    /// let people = vec![("Jane", 20), ("John", 18), ("Jill", 30), ("Jack", 27)];
+    ///
+    /// let oldest_people_first = people
+    ///     .into_iter()
+    ///     .sorted_by(|a, b| Ord::cmp(&b.1, &a.1))
+    ///     .map(|(person, _age)| person);
+    ///
+    /// itertools::assert_equal(oldest_people_first,
+    ///                         vec!["Jill", "Jack", "Jane", "John"]);
+    /// ```
+    #[cfg(feature = "use_std")]
+    fn sorted_by<F>(self, cmp: F) -> VecIntoIter<Self::Item>
+        where Self: Sized,
+              F: FnMut(&Self::Item, &Self::Item) -> Ordering,
+    {
+        let mut v = Vec::from_iter(self);
+        v.sort_by(cmp);
+        v.into_iter()
+    }
+
+    /// Sort all iterator elements into a new iterator in ascending order.
+    ///
+    /// **Note:** This consumes the entire iterator, uses the
+    /// `slice::sort_by_key()` method and returns the result as a new
+    /// iterator that owns its elements.
+    ///
+    /// The sorted iterator, if directly collected to a `Vec`, is converted
+    /// without any extra copying or allocation cost.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// // sort people in descending order by age
+    /// let people = vec![("Jane", 20), ("John", 18), ("Jill", 30), ("Jack", 27)];
+    ///
+    /// let oldest_people_first = people
+    ///     .into_iter()
+    ///     .sorted_by_key(|x| -x.1)
+    ///     .map(|(person, _age)| person);
+    ///
+    /// itertools::assert_equal(oldest_people_first,
+    ///                         vec!["Jill", "Jack", "Jane", "John"]);
+    /// ```
+    #[cfg(feature = "use_std")]
+    fn sorted_by_key<K, F>(self, f: F) -> VecIntoIter<Self::Item>
+        where Self: Sized,
+              K: Ord,
+              F: FnMut(&Self::Item) -> K,
+    {
+        let mut v = Vec::from_iter(self);
+        v.sort_by_key(f);
+        v.into_iter()
+    }
+
+    /// Collect all iterator elements into one of two
+    /// partitions. Unlike `Iterator::partition`, each partition may
+    /// have a distinct type.
+    ///
+    /// ```
+    /// use itertools::{Itertools, Either};
+    ///
+    /// let successes_and_failures = vec![Ok(1), Err(false), Err(true), Ok(2)];
+    ///
+    /// let (successes, failures): (Vec<_>, Vec<_>) = successes_and_failures
+    ///     .into_iter()
+    ///     .partition_map(|r| {
+    ///         match r {
+    ///             Ok(v) => Either::Left(v),
+    ///             Err(v) => Either::Right(v),
+    ///         }
+    ///     });
+    ///
+    /// assert_eq!(successes, [1, 2]);
+    /// assert_eq!(failures, [false, true]);
+    /// ```
+    fn partition_map<A, B, F, L, R>(self, mut predicate: F) -> (A, B)
+        where Self: Sized,
+              F: FnMut(Self::Item) -> Either<L, R>,
+              A: Default + Extend<L>,
+              B: Default + Extend<R>,
+    {
+        let mut left = A::default();
+        let mut right = B::default();
+
+        self.for_each(|val| match predicate(val) {
+            Either::Left(v) => left.extend(Some(v)),
+            Either::Right(v) => right.extend(Some(v)),
+        });
+
+        (left, right)
+    }
+
+    /// Return a `HashMap` of keys mapped to `Vec`s of values. Keys and values
+    /// are taken from `(Key, Value)` tuple pairs yielded by the input iterator.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let data = vec![(0, 10), (2, 12), (3, 13), (0, 20), (3, 33), (2, 42)];
+    /// let lookup = data.into_iter().into_group_map();
+    ///
+    /// assert_eq!(lookup[&0], vec![10, 20]);
+    /// assert_eq!(lookup.get(&1), None);
+    /// assert_eq!(lookup[&2], vec![12, 42]);
+    /// assert_eq!(lookup[&3], vec![13, 33]);
+    /// ```
+    #[cfg(feature = "use_std")]
+    fn into_group_map<K, V>(self) -> HashMap<K, Vec<V>>
+        where Self: Iterator<Item=(K, V)> + Sized,
+              K: Hash + Eq,
+    {
+        group_map::into_group_map(self)
+    }
+
+    /// Return the minimum and maximum elements in the iterator.
+    ///
+    /// The return type `MinMaxResult` is an enum of three variants:
+    ///
+    /// - `NoElements` if the iterator is empty.
+    /// - `OneElement(x)` if the iterator has exactly one element.
+    /// - `MinMax(x, y)` is returned otherwise, where `x <= y`. Two
+    ///    values are equal if and only if there is more than one
+    ///    element in the iterator and all elements are equal.
+    ///
+    /// On an iterator of length `n`, `minmax` does `1.5 * n` comparisons,
+    /// and so is faster than calling `min` and `max` separately which does
+    /// `2 * n` comparisons.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    /// use itertools::MinMaxResult::{NoElements, OneElement, MinMax};
+    ///
+    /// let a: [i32; 0] = [];
+    /// assert_eq!(a.iter().minmax(), NoElements);
+    ///
+    /// let a = [1];
+    /// assert_eq!(a.iter().minmax(), OneElement(&1));
+    ///
+    /// let a = [1, 2, 3, 4, 5];
+    /// assert_eq!(a.iter().minmax(), MinMax(&1, &5));
+    ///
+    /// let a = [1, 1, 1, 1];
+    /// assert_eq!(a.iter().minmax(), MinMax(&1, &1));
+    /// ```
+    ///
+    /// The elements can be floats but no particular result is guaranteed
+    /// if an element is NaN.
+    fn minmax(self) -> MinMaxResult<Self::Item>
+        where Self: Sized, Self::Item: PartialOrd
+    {
+        minmax::minmax_impl(self, |_| (), |x, y, _, _| x < y)
+    }
+
+    /// Return the minimum and maximum element of an iterator, as determined by
+    /// the specified function.
+    ///
+    /// The return value is a variant of `MinMaxResult` like for `minmax()`.
+    ///
+    /// For the minimum, the first minimal element is returned.  For the maximum,
+    /// the last maximal element wins.  This matches the behavior of the standard
+    /// `Iterator::min()` and `Iterator::max()` methods.
+    ///
+    /// The keys can be floats but no particular result is guaranteed
+    /// if a key is NaN.
+    fn minmax_by_key<K, F>(self, key: F) -> MinMaxResult<Self::Item>
+        where Self: Sized, K: PartialOrd, F: FnMut(&Self::Item) -> K
+    {
+        minmax::minmax_impl(self, key, |_, _, xk, yk| xk < yk)
+    }
+
+    /// Return the minimum and maximum element of an iterator, as determined by
+    /// the specified comparison function.
+    ///
+    /// The return value is a variant of `MinMaxResult` like for `minmax()`.
+    ///
+    /// For the minimum, the first minimal element is returned.  For the maximum,
+    /// the last maximal element wins.  This matches the behavior of the standard
+    /// `Iterator::min()` and `Iterator::max()` methods.
+    fn minmax_by<F>(self, mut compare: F) -> MinMaxResult<Self::Item>
+        where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering
+    {
+        minmax::minmax_impl(
+            self,
+            |_| (),
+            |x, y, _, _| Ordering::Less == compare(x, y)
+        )
+    }
+
+    /// Return the position of the maximum element in the iterator.
+    ///
+    /// If several elements are equally maximum, the position of the
+    /// last of them is returned.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let a: [i32; 0] = [];
+    /// assert_eq!(a.iter().position_max(), None);
+    ///
+    /// let a = [-3, 0, 1, 5, -10];
+    /// assert_eq!(a.iter().position_max(), Some(3));
+    ///
+    /// let a = [1, 1, -1, -1];
+    /// assert_eq!(a.iter().position_max(), Some(1));
+    /// ```
+    fn position_max(self) -> Option<usize>
+        where Self: Sized, Self::Item: Ord
+    {
+        self.enumerate()
+            .max_by(|x, y| Ord::cmp(&x.1, &y.1))
+            .map(|x| x.0)
+    }
+
+    /// Return the position of the maximum element in the iterator, as
+    /// determined by the specified function.
+    ///
+    /// If several elements are equally maximum, the position of the
+    /// last of them is returned.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let a: [i32; 0] = [];
+    /// assert_eq!(a.iter().position_max_by_key(|x| x.abs()), None);
+    ///
+    /// let a = [-3_i32, 0, 1, 5, -10];
+    /// assert_eq!(a.iter().position_max_by_key(|x| x.abs()), Some(4));
+    ///
+    /// let a = [1_i32, 1, -1, -1];
+    /// assert_eq!(a.iter().position_max_by_key(|x| x.abs()), Some(3));
+    /// ```
+    fn position_max_by_key<K, F>(self, mut key: F) -> Option<usize>
+        where Self: Sized, K: Ord, F: FnMut(&Self::Item) -> K
+    {
+        self.enumerate()
+            .max_by(|x, y| Ord::cmp(&key(&x.1), &key(&y.1)))
+            .map(|x| x.0)
+    }
+
+    /// Return the position of the maximum element in the iterator, as
+    /// determined by the specified comparison function.
+    ///
+    /// If several elements are equally maximum, the position of the
+    /// last of them is returned.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let a: [i32; 0] = [];
+    /// assert_eq!(a.iter().position_max_by(|x, y| x.cmp(y)), None);
+    ///
+    /// let a = [-3_i32, 0, 1, 5, -10];
+    /// assert_eq!(a.iter().position_max_by(|x, y| x.cmp(y)), Some(3));
+    ///
+    /// let a = [1_i32, 1, -1, -1];
+    /// assert_eq!(a.iter().position_max_by(|x, y| x.cmp(y)), Some(1));
+    /// ```
+    fn position_max_by<F>(self, mut compare: F) -> Option<usize>
+        where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering
+    {
+        self.enumerate()
+            .max_by(|x, y| compare(&x.1, &y.1))
+            .map(|x| x.0)
+    }
+
+    /// Return the position of the minimum element in the iterator.
+    ///
+    /// If several elements are equally minimum, the position of the
+    /// first of them is returned.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let a: [i32; 0] = [];
+    /// assert_eq!(a.iter().position_min(), None);
+    ///
+    /// let a = [-3, 0, 1, 5, -10];
+    /// assert_eq!(a.iter().position_min(), Some(4));
+    ///
+    /// let a = [1, 1, -1, -1];
+    /// assert_eq!(a.iter().position_min(), Some(2));
+    /// ```
+    fn position_min(self) -> Option<usize>
+        where Self: Sized, Self::Item: Ord
+    {
+        self.enumerate()
+            .min_by(|x, y| Ord::cmp(&x.1, &y.1))
+            .map(|x| x.0)
+    }
+
+    /// Return the position of the minimum element in the iterator, as
+    /// determined by the specified function.
+    ///
+    /// If several elements are equally minimum, the position of the
+    /// first of them is returned.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let a: [i32; 0] = [];
+    /// assert_eq!(a.iter().position_min_by_key(|x| x.abs()), None);
+    ///
+    /// let a = [-3_i32, 0, 1, 5, -10];
+    /// assert_eq!(a.iter().position_min_by_key(|x| x.abs()), Some(1));
+    ///
+    /// let a = [1_i32, 1, -1, -1];
+    /// assert_eq!(a.iter().position_min_by_key(|x| x.abs()), Some(0));
+    /// ```
+    fn position_min_by_key<K, F>(self, mut key: F) -> Option<usize>
+        where Self: Sized, K: Ord, F: FnMut(&Self::Item) -> K
+    {
+        self.enumerate()
+            .min_by(|x, y| Ord::cmp(&key(&x.1), &key(&y.1)))
+            .map(|x| x.0)
+    }
+
+    /// Return the position of the minimum element in the iterator, as
+    /// determined by the specified comparison function.
+    ///
+    /// If several elements are equally minimum, the position of the
+    /// first of them is returned.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let a: [i32; 0] = [];
+    /// assert_eq!(a.iter().position_min_by(|x, y| x.cmp(y)), None);
+    ///
+    /// let a = [-3_i32, 0, 1, 5, -10];
+    /// assert_eq!(a.iter().position_min_by(|x, y| x.cmp(y)), Some(4));
+    ///
+    /// let a = [1_i32, 1, -1, -1];
+    /// assert_eq!(a.iter().position_min_by(|x, y| x.cmp(y)), Some(2));
+    /// ```
+    fn position_min_by<F>(self, mut compare: F) -> Option<usize>
+        where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering
+    {
+        self.enumerate()
+            .min_by(|x, y| compare(&x.1, &y.1))
+            .map(|x| x.0)
+    }
+
+    /// Return the positions of the minimum and maximum elements in
+    /// the iterator.
+    ///
+    /// The return type [`MinMaxResult`] is an enum of three variants:
+    ///
+    /// - `NoElements` if the iterator is empty.
+    /// - `OneElement(xpos)` if the iterator has exactly one element.
+    /// - `MinMax(xpos, ypos)` is returned otherwise, where the
+    ///    element at `xpos` ≤ the element at `ypos`. While the
+    ///    referenced elements themselves may be equal, `xpos` cannot
+    ///    be equal to `ypos`.
+    ///
+    /// On an iterator of length `n`, `position_minmax` does `1.5 * n`
+    /// comparisons, and so is faster than calling `positon_min` and
+    /// `position_max` separately which does `2 * n` comparisons.
+    ///
+    /// For the minimum, if several elements are equally minimum, the
+    /// position of the first of them is returned. For the maximum, if
+    /// several elements are equally maximum, the position of the last
+    /// of them is returned.
+    ///
+    /// The elements can be floats but no particular result is
+    /// guaranteed if an element is NaN.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    /// use itertools::MinMaxResult::{NoElements, OneElement, MinMax};
+    ///
+    /// let a: [i32; 0] = [];
+    /// assert_eq!(a.iter().position_minmax(), NoElements);
+    ///
+    /// let a = [10];
+    /// assert_eq!(a.iter().position_minmax(), OneElement(0));
+    ///
+    /// let a = [-3, 0, 1, 5, -10];
+    /// assert_eq!(a.iter().position_minmax(), MinMax(4, 3));
+    ///
+    /// let a = [1, 1, -1, -1];
+    /// assert_eq!(a.iter().position_minmax(), MinMax(2, 1));
+    /// ```
+    ///
+    /// [`MinMaxResult`]: enum.MinMaxResult.html
+    fn position_minmax(self) -> MinMaxResult<usize>
+        where Self: Sized, Self::Item: PartialOrd
+    {
+        use crate::MinMaxResult::{NoElements, OneElement, MinMax};
+        match minmax::minmax_impl(self.enumerate(), |_| (), |x, y, _, _| x.1 < y.1) {
+            NoElements => NoElements,
+            OneElement(x) => OneElement(x.0),
+            MinMax(x, y) => MinMax(x.0, y.0),
+        }
+    }
+
+    /// Return the postions of the minimum and maximum elements of an
+    /// iterator, as determined by the specified function.
+    ///
+    /// The return value is a variant of [`MinMaxResult`] like for
+    /// [`position_minmax`].
+    ///
+    /// For the minimum, if several elements are equally minimum, the
+    /// position of the first of them is returned. For the maximum, if
+    /// several elements are equally maximum, the position of the last
+    /// of them is returned.
+    ///
+    /// The keys can be floats but no particular result is guaranteed
+    /// if a key is NaN.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    /// use itertools::MinMaxResult::{NoElements, OneElement, MinMax};
+    ///
+    /// let a: [i32; 0] = [];
+    /// assert_eq!(a.iter().position_minmax_by_key(|x| x.abs()), NoElements);
+    ///
+    /// let a = [10_i32];
+    /// assert_eq!(a.iter().position_minmax_by_key(|x| x.abs()), OneElement(0));
+    ///
+    /// let a = [-3_i32, 0, 1, 5, -10];
+    /// assert_eq!(a.iter().position_minmax_by_key(|x| x.abs()), MinMax(1, 4));
+    ///
+    /// let a = [1_i32, 1, -1, -1];
+    /// assert_eq!(a.iter().position_minmax_by_key(|x| x.abs()), MinMax(0, 3));
+    /// ```
+    ///
+    /// [`MinMaxResult`]: enum.MinMaxResult.html
+    /// [`position_minmax`]: #method.position_minmax
+    fn position_minmax_by_key<K, F>(self, mut key: F) -> MinMaxResult<usize>
+        where Self: Sized, K: PartialOrd, F: FnMut(&Self::Item) -> K
+    {
+        use crate::MinMaxResult::{NoElements, OneElement, MinMax};
+        match self.enumerate().minmax_by_key(|e| key(&e.1)) {
+            NoElements => NoElements,
+            OneElement(x) => OneElement(x.0),
+            MinMax(x, y) => MinMax(x.0, y.0),
+        }
+    }
+
+    /// Return the postions of the minimum and maximum elements of an
+    /// iterator, as determined by the specified comparison function.
+    ///
+    /// The return value is a variant of [`MinMaxResult`] like for
+    /// [`position_minmax`].
+    ///
+    /// For the minimum, if several elements are equally minimum, the
+    /// position of the first of them is returned. For the maximum, if
+    /// several elements are equally maximum, the position of the last
+    /// of them is returned.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    /// use itertools::MinMaxResult::{NoElements, OneElement, MinMax};
+    ///
+    /// let a: [i32; 0] = [];
+    /// assert_eq!(a.iter().position_minmax_by(|x, y| x.cmp(y)), NoElements);
+    ///
+    /// let a = [10_i32];
+    /// assert_eq!(a.iter().position_minmax_by(|x, y| x.cmp(y)), OneElement(0));
+    ///
+    /// let a = [-3_i32, 0, 1, 5, -10];
+    /// assert_eq!(a.iter().position_minmax_by(|x, y| x.cmp(y)), MinMax(4, 3));
+    ///
+    /// let a = [1_i32, 1, -1, -1];
+    /// assert_eq!(a.iter().position_minmax_by(|x, y| x.cmp(y)), MinMax(2, 1));
+    /// ```
+    ///
+    /// [`MinMaxResult`]: enum.MinMaxResult.html
+    /// [`position_minmax`]: #method.position_minmax
+    fn position_minmax_by<F>(self, mut compare: F) -> MinMaxResult<usize>
+        where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering
+    {
+        use crate::MinMaxResult::{NoElements, OneElement, MinMax};
+        match self.enumerate().minmax_by(|x, y| compare(&x.1, &y.1)) {
+            NoElements => NoElements,
+            OneElement(x) => OneElement(x.0),
+            MinMax(x, y) => MinMax(x.0, y.0),
+        }
+    }
+
+    /// If the iterator yields exactly one element, that element will be returned, otherwise
+    /// an error will be returned containing an iterator that has the same output as the input
+    /// iterator.
+    ///
+    /// This provides an additional layer of validation over just calling `Iterator::next()`.
+    /// If your assumption that there should only be one element yielded is false this provides
+    /// the opportunity to detect and handle that, preventing errors at a distance.
+    ///
+    /// # Examples
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// assert_eq!((0..10).filter(|&x| x == 2).exactly_one().unwrap(), 2);
+    /// assert!((0..10).filter(|&x| x > 1 && x < 4).exactly_one().unwrap_err().eq(2..4));
+    /// assert!((0..10).filter(|&x| x > 1 && x < 5).exactly_one().unwrap_err().eq(2..5));
+    /// assert!((0..10).filter(|&_| false).exactly_one().unwrap_err().eq(0..0));
+    /// ```
+    fn exactly_one(mut self) -> Result<Self::Item, ExactlyOneError<Self>>
+    where
+        Self: Sized,
+    {
+        match self.next() {
+            Some(first) => {
+                match self.next() {
+                    Some(second) => {
+                        Err(ExactlyOneError::new((Some(first), Some(second)), self))
+                    }
+                    None => {
+                        Ok(first)
+                    }
+                }
+            }
+            None => Err(ExactlyOneError::new((None, None), self)),
+        }
+    }
+}
+
+impl<T: ?Sized> Itertools for T where T: Iterator { }
+
+/// Return `true` if both iterables produce equal sequences
+/// (elements pairwise equal and sequences of the same length),
+/// `false` otherwise.
+///
+/// This is an `IntoIterator` enabled function that is similar to the standard
+/// library method `Iterator::eq`.
+///
+/// ```
+/// assert!(itertools::equal(vec![1, 2, 3], 1..4));
+/// assert!(!itertools::equal(&[0, 0], &[0, 0, 0]));
+/// ```
+pub fn equal<I, J>(a: I, b: J) -> bool
+    where I: IntoIterator,
+          J: IntoIterator,
+          I::Item: PartialEq<J::Item>
+{
+    let mut ia = a.into_iter();
+    let mut ib = b.into_iter();
+    loop {
+        match ia.next() {
+            Some(x) => match ib.next() {
+                Some(y) => if x != y { return false; },
+                None => return false,
+            },
+            None => return ib.next().is_none()
+        }
+    }
+}
+
+/// Assert that two iterables produce equal sequences, with the same
+/// semantics as *equal(a, b)*.
+///
+/// **Panics** on assertion failure with a message that shows the
+/// two iteration elements.
+///
+/// ```ignore
+/// assert_equal("exceed".split('c'), "excess".split('c'));
+/// // ^PANIC: panicked at 'Failed assertion Some("eed") == Some("ess") for iteration 1',
+/// ```
+pub fn assert_equal<I, J>(a: I, b: J)
+    where I: IntoIterator,
+          J: IntoIterator,
+          I::Item: fmt::Debug + PartialEq<J::Item>,
+          J::Item: fmt::Debug,
+{
+    let mut ia = a.into_iter();
+    let mut ib = b.into_iter();
+    let mut i = 0;
+    loop {
+        match (ia.next(), ib.next()) {
+            (None, None) => return,
+            (a, b) => {
+                let equal = match (&a, &b) {
+                    (&Some(ref a), &Some(ref b)) => a == b,
+                    _ => false,
+                };
+                assert!(equal, "Failed assertion {a:?} == {b:?} for iteration {i}",
+                        i=i, a=a, b=b);
+                i += 1;
+            }
+        }
+    }
+}
+
+/// Partition a sequence using predicate `pred` so that elements
+/// that map to `true` are placed before elements which map to `false`.
+///
+/// The order within the partitions is arbitrary.
+///
+/// Return the index of the split point.
+///
+/// ```
+/// use itertools::partition;
+///
+/// # // use repeated numbers to not promise any ordering
+/// let mut data = [7, 1, 1, 7, 1, 1, 7];
+/// let split_index = partition(&mut data, |elt| *elt >= 3);
+///
+/// assert_eq!(data, [7, 7, 7, 1, 1, 1, 1]);
+/// assert_eq!(split_index, 3);
+/// ```
+pub fn partition<'a, A: 'a, I, F>(iter: I, mut pred: F) -> usize
+    where I: IntoIterator<Item = &'a mut A>,
+          I::IntoIter: DoubleEndedIterator,
+          F: FnMut(&A) -> bool
+{
+    let mut split_index = 0;
+    let mut iter = iter.into_iter();
+    'main: while let Some(front) = iter.next() {
+        if !pred(front) {
+            loop {
+                match iter.next_back() {
+                    Some(back) => if pred(back) {
+                        std::mem::swap(front, back);
+                        break;
+                    },
+                    None => break 'main,
+                }
+            }
+        }
+        split_index += 1;
+    }
+    split_index
+}
+
+/// An enum used for controlling the execution of `.fold_while()`.
+///
+/// See [`.fold_while()`](trait.Itertools.html#method.fold_while) for more information.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum FoldWhile<T> {
+    /// Continue folding with this value
+    Continue(T),
+    /// Fold is complete and will return this value
+    Done(T),
+}
+
+impl<T> FoldWhile<T> {
+    /// Return the value in the continue or done.
+    pub fn into_inner(self) -> T {
+        match self {
+            FoldWhile::Continue(x) | FoldWhile::Done(x) => x,
+        }
+    }
+
+    /// Return true if `self` is `Done`, false if it is `Continue`.
+    pub fn is_done(&self) -> bool {
+        match *self {
+            FoldWhile::Continue(_) => false,
+            FoldWhile::Done(_) => true,
+        }
+    }
+}
diff --git a/src/merge_join.rs b/src/merge_join.rs
new file mode 100644
index 0000000..0f87ae4
--- /dev/null
+++ b/src/merge_join.rs
@@ -0,0 +1,167 @@
+use std::cmp::Ordering;
+use std::iter::Fuse;
+use std::fmt;
+
+use super::adaptors::{PutBack, put_back};
+use crate::either_or_both::EitherOrBoth;
+
+/// Return an iterator adaptor that merge-joins items from the two base iterators in ascending order.
+///
+/// See [`.merge_join_by()`](trait.Itertools.html#method.merge_join_by) for more information.
+pub fn merge_join_by<I, J, F>(left: I, right: J, cmp_fn: F)
+    -> MergeJoinBy<I::IntoIter, J::IntoIter, F>
+    where I: IntoIterator,
+          J: IntoIterator,
+          F: FnMut(&I::Item, &J::Item) -> Ordering
+{
+    MergeJoinBy {
+        left: put_back(left.into_iter().fuse()),
+        right: put_back(right.into_iter().fuse()),
+        cmp_fn,
+    }
+}
+
+/// An iterator adaptor that merge-joins items from the two base iterators in ascending order.
+///
+/// See [`.merge_join_by()`](../trait.Itertools.html#method.merge_join_by) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct MergeJoinBy<I: Iterator, J: Iterator, F> {
+    left: PutBack<Fuse<I>>,
+    right: PutBack<Fuse<J>>,
+    cmp_fn: F
+}
+
+impl<I, J, F> Clone for MergeJoinBy<I, J, F>
+    where I: Iterator,
+          J: Iterator,
+          PutBack<Fuse<I>>: Clone,
+          PutBack<Fuse<J>>: Clone,
+          F: Clone,
+{
+    clone_fields!(left, right, cmp_fn);
+}
+
+impl<I, J, F> fmt::Debug for MergeJoinBy<I, J, F>
+    where I: Iterator + fmt::Debug,
+          I::Item: fmt::Debug,
+          J: Iterator + fmt::Debug,
+          J::Item: fmt::Debug,
+{
+    debug_fmt_fields!(MergeJoinBy, left, right);
+}
+
+impl<I, J, F> Iterator for MergeJoinBy<I, J, F>
+    where I: Iterator,
+          J: Iterator,
+          F: FnMut(&I::Item, &J::Item) -> Ordering
+{
+    type Item = EitherOrBoth<I::Item, J::Item>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        match (self.left.next(), self.right.next()) {
+            (None, None) => None,
+            (Some(left), None) =>
+                Some(EitherOrBoth::Left(left)),
+            (None, Some(right)) =>
+                Some(EitherOrBoth::Right(right)),
+            (Some(left), Some(right)) => {
+                match (self.cmp_fn)(&left, &right) {
+                    Ordering::Equal =>
+                        Some(EitherOrBoth::Both(left, right)),
+                    Ordering::Less => {
+                        self.right.put_back(right);
+                        Some(EitherOrBoth::Left(left))
+                    },
+                    Ordering::Greater => {
+                        self.left.put_back(left);
+                        Some(EitherOrBoth::Right(right))
+                    }
+                }
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let (a_lower, a_upper) = self.left.size_hint();
+        let (b_lower, b_upper) = self.right.size_hint();
+
+        let lower = ::std::cmp::max(a_lower, b_lower);
+
+        let upper = match (a_upper, b_upper) {
+            (Some(x), Some(y)) => x.checked_add(y),
+            _ => None,
+        };
+
+        (lower, upper)
+    }
+
+    fn count(mut self) -> usize {
+        let mut count = 0;
+        loop {
+            match (self.left.next(), self.right.next()) {
+                (None, None) => break count,
+                (Some(_left), None) => break count + 1 + self.left.into_parts().1.count(),
+                (None, Some(_right)) => break count + 1 + self.right.into_parts().1.count(),
+                (Some(left), Some(right)) => {
+                    count += 1;
+                    match (self.cmp_fn)(&left, &right) {
+                        Ordering::Equal => {}
+                        Ordering::Less => self.right.put_back(right),
+                        Ordering::Greater => self.left.put_back(left),
+                    }
+                }
+            }
+        }
+    }
+
+    fn last(mut self) -> Option<Self::Item> {
+        let mut previous_element = None;
+        loop {
+            match (self.left.next(), self.right.next()) {
+                (None, None) => break previous_element,
+                (Some(left), None) => {
+                    break Some(EitherOrBoth::Left(
+                        self.left.into_parts().1.last().unwrap_or(left),
+                    ))
+                }
+                (None, Some(right)) => {
+                    break Some(EitherOrBoth::Right(
+                        self.right.into_parts().1.last().unwrap_or(right),
+                    ))
+                }
+                (Some(left), Some(right)) => {
+                    previous_element = match (self.cmp_fn)(&left, &right) {
+                        Ordering::Equal => Some(EitherOrBoth::Both(left, right)),
+                        Ordering::Less => {
+                            self.right.put_back(right);
+                            Some(EitherOrBoth::Left(left))
+                        }
+                        Ordering::Greater => {
+                            self.left.put_back(left);
+                            Some(EitherOrBoth::Right(right))
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
+        loop {
+            if n == 0 {
+                break self.next();
+            }
+            n -= 1;
+            match (self.left.next(), self.right.next()) {
+                (None, None) => break None,
+                (Some(_left), None) => break self.left.nth(n).map(EitherOrBoth::Left),
+                (None, Some(_right)) => break self.right.nth(n).map(EitherOrBoth::Right),
+                (Some(left), Some(right)) => match (self.cmp_fn)(&left, &right) {
+                    Ordering::Equal => {}
+                    Ordering::Less => self.right.put_back(right),
+                    Ordering::Greater => self.left.put_back(left),
+                },
+            }
+        }
+    }
+}
diff --git a/src/minmax.rs b/src/minmax.rs
new file mode 100644
index 0000000..38180ef
--- /dev/null
+++ b/src/minmax.rs
@@ -0,0 +1,114 @@
+
+/// `MinMaxResult` is an enum returned by `minmax`. See `Itertools::minmax()` for
+/// more detail.
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub enum MinMaxResult<T> {
+    /// Empty iterator
+    NoElements,
+
+    /// Iterator with one element, so the minimum and maximum are the same
+    OneElement(T),
+
+    /// More than one element in the iterator, the first element is not larger
+    /// than the second
+    MinMax(T, T)
+}
+
+impl<T: Clone> MinMaxResult<T> {
+    /// `into_option` creates an `Option` of type `(T, T)`. The returned `Option`
+    /// has variant `None` if and only if the `MinMaxResult` has variant
+    /// `NoElements`. Otherwise `Some((x, y))` is returned where `x <= y`.
+    /// If the `MinMaxResult` has variant `OneElement(x)`, performing this
+    /// operation will make one clone of `x`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use itertools::MinMaxResult::{self, NoElements, OneElement, MinMax};
+    ///
+    /// let r: MinMaxResult<i32> = NoElements;
+    /// assert_eq!(r.into_option(), None);
+    ///
+    /// let r = OneElement(1);
+    /// assert_eq!(r.into_option(), Some((1, 1)));
+    ///
+    /// let r = MinMax(1, 2);
+    /// assert_eq!(r.into_option(), Some((1, 2)));
+    /// ```
+    pub fn into_option(self) -> Option<(T,T)> {
+        match self {
+            MinMaxResult::NoElements => None,
+            MinMaxResult::OneElement(x) => Some((x.clone(), x)),
+            MinMaxResult::MinMax(x, y) => Some((x, y))
+        }
+    }
+}
+
+/// Implementation guts for `minmax` and `minmax_by_key`.
+pub fn minmax_impl<I, K, F, L>(mut it: I, mut key_for: F,
+                               mut lt: L) -> MinMaxResult<I::Item>
+    where I: Iterator,
+          F: FnMut(&I::Item) -> K,
+          L: FnMut(&I::Item, &I::Item, &K, &K) -> bool,
+{
+    let (mut min, mut max, mut min_key, mut max_key) = match it.next() {
+        None => return MinMaxResult::NoElements,
+        Some(x) => {
+            match it.next() {
+                None => return MinMaxResult::OneElement(x),
+                Some(y) => {
+                    let xk = key_for(&x);
+                    let yk = key_for(&y);
+                    if !lt(&y, &x, &yk, &xk) {(x, y, xk, yk)} else {(y, x, yk, xk)}
+                }
+            }
+        }
+    };
+
+    loop {
+        // `first` and `second` are the two next elements we want to look
+        // at.  We first compare `first` and `second` (#1). The smaller one
+        // is then compared to current minimum (#2). The larger one is
+        // compared to current maximum (#3). This way we do 3 comparisons
+        // for 2 elements.
+        let first = match it.next() {
+            None => break,
+            Some(x) => x
+        };
+        let second = match it.next() {
+            None => {
+                let first_key = key_for(&first);
+                if lt(&first, &min, &first_key, &min_key) {
+                    min = first;
+                } else if !lt(&first, &max, &first_key, &max_key) {
+                    max = first;
+                }
+                break;
+            }
+            Some(x) => x
+        };
+        let first_key = key_for(&first);
+        let second_key = key_for(&second);
+        if !lt(&second, &first, &second_key, &first_key) {
+            if lt(&first, &min, &first_key, &min_key) {
+                min = first;
+                min_key = first_key;
+            }
+            if !lt(&second, &max, &second_key, &max_key) {
+                max = second;
+                max_key = second_key;
+            }
+        } else {
+            if lt(&second, &min, &second_key, &min_key) {
+                min = second;
+                min_key = second_key;
+            }
+            if !lt(&first, &max, &first_key, &max_key) {
+                max = first;
+                max_key = first_key;
+            }
+        }
+    }
+
+    MinMaxResult::MinMax(min, max)
+}
diff --git a/src/multipeek_impl.rs b/src/multipeek_impl.rs
new file mode 100644
index 0000000..0b64e1d
--- /dev/null
+++ b/src/multipeek_impl.rs
@@ -0,0 +1,102 @@
+use std::iter::Fuse;
+use std::collections::VecDeque;
+use crate::size_hint;
+use crate::PeekingNext;
+
+/// See [`multipeek()`](../fn.multipeek.html) for more information.
+#[derive(Clone, Debug)]
+pub struct MultiPeek<I>
+    where I: Iterator
+{
+    iter: Fuse<I>,
+    buf: VecDeque<I::Item>,
+    index: usize,
+}
+
+/// An iterator adaptor that allows the user to peek at multiple `.next()`
+/// values without advancing the base iterator.
+pub fn multipeek<I>(iterable: I) -> MultiPeek<I::IntoIter>
+    where I: IntoIterator
+{
+    MultiPeek {
+        iter: iterable.into_iter().fuse(),
+        buf: VecDeque::new(),
+        index: 0,
+    }
+}
+
+impl<I> MultiPeek<I>
+    where I: Iterator
+{
+    /// Reset the peeking “cursor”
+    pub fn reset_peek(&mut self) {
+        self.index = 0;
+    }
+}
+
+impl<I: Iterator> MultiPeek<I> {
+    /// Works exactly like `.next()` with the only difference that it doesn't
+    /// advance itself. `.peek()` can be called multiple times, to peek
+    /// further ahead.
+    pub fn peek(&mut self) -> Option<&I::Item> {
+        let ret = if self.index < self.buf.len() {
+            Some(&self.buf[self.index])
+        } else {
+            match self.iter.next() {
+                Some(x) => {
+                    self.buf.push_back(x);
+                    Some(&self.buf[self.index])
+                }
+                None => return None,
+            }
+        };
+
+        self.index += 1;
+        ret
+    }
+}
+
+impl<I> PeekingNext for MultiPeek<I>
+    where I: Iterator,
+{
+    fn peeking_next<F>(&mut self, accept: F) -> Option<Self::Item>
+        where F: FnOnce(&Self::Item) -> bool
+    {
+        if self.buf.is_empty() {
+            if let Some(r) = self.peek() {
+                if !accept(r) { return None }
+            }
+        } else {
+            if let Some(r) = self.buf.get(0) {
+                if !accept(r) { return None }
+            }
+        }
+        self.next()
+    }
+}
+
+impl<I> Iterator for MultiPeek<I>
+    where I: Iterator
+{
+    type Item = I::Item;
+
+    fn next(&mut self) -> Option<I::Item> {
+        self.index = 0;
+        if self.buf.is_empty() {
+            self.iter.next()
+        } else {
+            self.buf.pop_front()
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        size_hint::add_scalar(self.iter.size_hint(), self.buf.len())
+    }
+}
+
+// Same size
+impl<I> ExactSizeIterator for MultiPeek<I>
+    where I: ExactSizeIterator
+{}
+
+
diff --git a/src/pad_tail.rs b/src/pad_tail.rs
new file mode 100644
index 0000000..8d9d5ff
--- /dev/null
+++ b/src/pad_tail.rs
@@ -0,0 +1,83 @@
+use std::iter::Fuse;
+use crate::size_hint;
+
+/// An iterator adaptor that pads a sequence to a minimum length by filling
+/// missing elements using a closure.
+///
+/// Iterator element type is `I::Item`.
+///
+/// See [`.pad_using()`](../trait.Itertools.html#method.pad_using) for more information.
+#[derive(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct PadUsing<I, F> {
+    iter: Fuse<I>,
+    min: usize,
+    pos: usize,
+    filler: F,
+}
+
+/// Create a new **PadUsing** iterator.
+pub fn pad_using<I, F>(iter: I, min: usize, filler: F) -> PadUsing<I, F>
+    where I: Iterator,
+          F: FnMut(usize) -> I::Item
+{
+    PadUsing {
+        iter: iter.fuse(),
+        min,
+        pos: 0,
+        filler,
+    }
+}
+
+impl<I, F> Iterator for PadUsing<I, F>
+    where I: Iterator,
+          F: FnMut(usize) -> I::Item
+{
+    type Item = I::Item;
+
+    #[inline]
+    fn next(&mut self) -> Option<I::Item> {
+        match self.iter.next() {
+            None => {
+                if self.pos < self.min {
+                    let e = Some((self.filler)(self.pos));
+                    self.pos += 1;
+                    e
+                } else {
+                    None
+                }
+            },
+            e => {
+                self.pos += 1;
+                e
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let tail = self.min.saturating_sub(self.pos);
+        size_hint::max(self.iter.size_hint(), (tail, Some(tail)))
+    }
+}
+
+impl<I, F> DoubleEndedIterator for PadUsing<I, F>
+    where I: DoubleEndedIterator + ExactSizeIterator,
+          F: FnMut(usize) -> I::Item
+{
+    fn next_back(&mut self) -> Option<I::Item> {
+        if self.min == 0 {
+            self.iter.next_back()
+        } else if self.iter.len() >= self.min {
+            self.min -= 1;
+            self.iter.next_back()
+        } else {
+            self.min -= 1;
+            Some((self.filler)(self.min))
+        }
+    }
+}
+
+impl<I, F> ExactSizeIterator for PadUsing<I, F>
+    where I: ExactSizeIterator,
+          F: FnMut(usize) -> I::Item
+{}
diff --git a/src/peeking_take_while.rs b/src/peeking_take_while.rs
new file mode 100644
index 0000000..b404904
--- /dev/null
+++ b/src/peeking_take_while.rs
@@ -0,0 +1,148 @@
+use std::iter::Peekable;
+use crate::PutBack;
+#[cfg(feature = "use_std")]
+use crate::PutBackN;
+
+/// An iterator that allows peeking at an element before deciding to accept it.
+///
+/// See [`.peeking_take_while()`](trait.Itertools.html#method.peeking_take_while)
+/// for more information.
+///
+/// This is implemented by peeking adaptors like peekable and put back,
+/// but also by a few iterators that can be peeked natively, like the slice’s
+/// by reference iterator (`std::slice::Iter`).
+pub trait PeekingNext : Iterator {
+    /// Pass a reference to the next iterator element to the closure `accept`;
+    /// if `accept` returns true, return it as the next element,
+    /// else None.
+    fn peeking_next<F>(&mut self, accept: F) -> Option<Self::Item>
+        where F: FnOnce(&Self::Item) -> bool;
+}
+
+impl<I> PeekingNext for Peekable<I>
+    where I: Iterator,
+{
+    fn peeking_next<F>(&mut self, accept: F) -> Option<Self::Item>
+        where F: FnOnce(&Self::Item) -> bool
+    {
+        if let Some(r) = self.peek() {
+            if !accept(r) {
+                return None;
+            }
+        }
+        self.next()
+    }
+}
+
+impl<I> PeekingNext for PutBack<I>
+    where I: Iterator,
+{
+    fn peeking_next<F>(&mut self, accept: F) -> Option<Self::Item>
+        where F: FnOnce(&Self::Item) -> bool
+    {
+        if let Some(r) = self.next() {
+            if !accept(&r) {
+                self.put_back(r);
+                return None;
+            }
+            Some(r)
+        } else {
+            None
+        }
+    }
+}
+
+#[cfg(feature = "use_std")]
+impl<I> PeekingNext for PutBackN<I>
+    where I: Iterator,
+{
+    fn peeking_next<F>(&mut self, accept: F) -> Option<Self::Item>
+        where F: FnOnce(&Self::Item) -> bool
+    {
+        if let Some(r) = self.next() {
+            if !accept(&r) {
+                self.put_back(r);
+                return None;
+            }
+            Some(r)
+        } else {
+            None
+        }
+    }
+}
+
+/// An iterator adaptor that takes items while a closure returns `true`.
+///
+/// See [`.peeking_take_while()`](../trait.Itertools.html#method.peeking_take_while)
+/// for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct PeekingTakeWhile<'a, I: 'a, F>
+    where I: Iterator,
+{
+    iter: &'a mut I,
+    f: F,
+}
+
+/// Create a PeekingTakeWhile
+pub fn peeking_take_while<I, F>(iter: &mut I, f: F) -> PeekingTakeWhile<I, F>
+    where I: Iterator,
+{
+    PeekingTakeWhile {
+        iter,
+        f,
+    }
+}
+
+impl<'a, I, F> Iterator for PeekingTakeWhile<'a, I, F>
+    where I: PeekingNext,
+          F: FnMut(&I::Item) -> bool,
+
+{
+    type Item = I::Item;
+    fn next(&mut self) -> Option<Self::Item> {
+        self.iter.peeking_next(&mut self.f)
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let (_, hi) = self.iter.size_hint();
+        (0, hi)
+    }
+}
+
+// Some iterators are so lightweight we can simply clone them to save their
+// state and use that for peeking.
+macro_rules! peeking_next_by_clone {
+    ([$($typarm:tt)*] $type_:ty) => {
+        impl<$($typarm)*> PeekingNext for $type_ {
+            fn peeking_next<F>(&mut self, accept: F) -> Option<Self::Item>
+                where F: FnOnce(&Self::Item) -> bool
+            {
+                let saved_state = self.clone();
+                if let Some(r) = self.next() {
+                    if !accept(&r) {
+                        *self = saved_state;
+                    } else {
+                        return Some(r)
+                    }
+                }
+                None
+            }
+        }
+    }
+}
+
+peeking_next_by_clone! { ['a, T] ::std::slice::Iter<'a, T> }
+peeking_next_by_clone! { ['a] ::std::str::Chars<'a> }
+peeking_next_by_clone! { ['a] ::std::str::CharIndices<'a> }
+peeking_next_by_clone! { ['a] ::std::str::Bytes<'a> }
+peeking_next_by_clone! { ['a, T] ::std::option::Iter<'a, T> }
+peeking_next_by_clone! { ['a, T] ::std::result::Iter<'a, T> }
+peeking_next_by_clone! { [T] ::std::iter::Empty<T> }
+#[cfg(feature = "use_std")]
+peeking_next_by_clone! { ['a, T] ::std::collections::linked_list::Iter<'a, T> }
+#[cfg(feature = "use_std")]
+peeking_next_by_clone! { ['a, T] ::std::collections::vec_deque::Iter<'a, T> }
+
+// cloning a Rev has no extra overhead; peekable and put backs are never DEI.
+peeking_next_by_clone! { [I: Clone + PeekingNext + DoubleEndedIterator]
+                         ::std::iter::Rev<I> }
diff --git a/src/permutations.rs b/src/permutations.rs
new file mode 100644
index 0000000..fb4dd50
--- /dev/null
+++ b/src/permutations.rs
@@ -0,0 +1,279 @@
+use std::fmt;
+use std::iter::once;
+
+use super::lazy_buffer::LazyBuffer;
+
+/// An iterator adaptor that iterates through all the `k`-permutations of the
+/// elements from an iterator.
+///
+/// See [`.permutations()`](../trait.Itertools.html#method.permutations) for
+/// more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Permutations<I: Iterator> {
+    vals: LazyBuffer<I>,
+    state: PermutationState,
+}
+
+impl<I> Clone for Permutations<I>
+    where I: Clone + Iterator,
+          I::Item: Clone,
+{
+    clone_fields!(vals, state);
+}
+
+#[derive(Clone, Debug)]
+enum PermutationState {
+    StartUnknownLen {
+        k: usize,
+    },
+    OngoingUnknownLen {
+        k: usize,
+        min_n: usize,
+    },
+    Complete(CompleteState),
+    Empty,
+}
+
+#[derive(Clone, Debug)]
+enum CompleteState {
+    Start {
+        n: usize,
+        k: usize,
+    },
+    Ongoing {
+        indices: Vec<usize>,
+        cycles: Vec<usize>,
+    }
+}
+
+enum CompleteStateRemaining {
+    Known(usize),
+    Overflow,
+}
+
+impl<I> fmt::Debug for Permutations<I>
+    where I: Iterator + fmt::Debug,
+          I::Item: fmt::Debug,
+{
+    debug_fmt_fields!(Permutations, vals, state);
+}
+
+pub fn permutations<I: Iterator>(iter: I, k: usize) -> Permutations<I> {
+    let mut vals = LazyBuffer::new(iter);
+
+    if k == 0 {
+        // Special case, yields single empty vec; `n` is irrelevant
+        let state = PermutationState::Complete(CompleteState::Start { n: 0, k: 0 });
+
+        return Permutations {
+            vals,
+            state
+        };
+    }
+
+    let mut enough_vals = true;
+
+    while vals.len() < k {
+        if !vals.get_next() {
+            enough_vals = false;
+            break;
+        }
+    }
+
+    let state = if enough_vals {
+        PermutationState::StartUnknownLen { k }
+    } else {
+        PermutationState::Empty
+    };
+
+    Permutations {
+        vals,
+        state
+    }
+}
+
+impl<I> Iterator for Permutations<I>
+where
+    I: Iterator,
+    I::Item: Clone
+{
+    type Item = Vec<I::Item>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.advance();
+
+        let &mut Permutations { ref vals, ref state } = self;
+
+        match state {
+            &PermutationState::StartUnknownLen { .. } => panic!("unexpected iterator state"),
+            &PermutationState::OngoingUnknownLen { k, min_n } => {
+                let latest_idx = min_n - 1;
+                let indices = (0..(k - 1)).chain(once(latest_idx));
+
+                Some(indices.map(|i| vals[i].clone()).collect())
+            }
+            &PermutationState::Complete(CompleteState::Start { .. }) => None,
+            &PermutationState::Complete(CompleteState::Ongoing { ref indices, ref cycles }) => {
+                let k = cycles.len();
+
+                Some(indices[0..k].iter().map(|&i| vals[i].clone()).collect())
+            },
+            &PermutationState::Empty => None
+        }
+    }
+
+    fn count(self) -> usize {
+        let Permutations { vals, state } = self;
+
+        fn from_complete(complete_state: CompleteState) -> usize {
+            match complete_state.remaining() {
+                CompleteStateRemaining::Known(count) => count,
+                CompleteStateRemaining::Overflow => {
+                    panic!("Iterator count greater than usize::MAX");
+                }
+            }
+        }
+
+        match state {
+            PermutationState::StartUnknownLen { k } => {
+                let n = vals.len() + vals.it.count();
+                let complete_state = CompleteState::Start { n, k };
+
+                from_complete(complete_state)
+            }
+            PermutationState::OngoingUnknownLen { k, min_n } => {
+                let prev_iteration_count = min_n - k + 1;
+                let n = vals.len() + vals.it.count();
+                let complete_state = CompleteState::Start { n, k };
+
+                from_complete(complete_state) - prev_iteration_count
+            },
+            PermutationState::Complete(state) => from_complete(state),
+            PermutationState::Empty => 0
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        match self.state {
+            PermutationState::StartUnknownLen { .. } |
+            PermutationState::OngoingUnknownLen { .. } => (0, None), // TODO can we improve this lower bound?
+            PermutationState::Complete(ref state) => match state.remaining() {
+                CompleteStateRemaining::Known(count) => (count, Some(count)),
+                CompleteStateRemaining::Overflow => (::std::usize::MAX, None)
+            }
+            PermutationState::Empty => (0, Some(0))
+        }
+    }
+}
+
+impl<I> Permutations<I>
+where
+    I: Iterator,
+    I::Item: Clone
+{
+    fn advance(&mut self) {
+        let &mut Permutations { ref mut vals, ref mut state } = self;
+
+        *state = match state {
+            &mut PermutationState::StartUnknownLen { k } => {
+                PermutationState::OngoingUnknownLen { k, min_n: k }
+            }
+            &mut PermutationState::OngoingUnknownLen { k, min_n } => {
+                if vals.get_next() {
+                    PermutationState::OngoingUnknownLen { k, min_n: min_n + 1 }
+                } else {
+                    let n = min_n;
+                    let prev_iteration_count = n - k + 1;
+                    let mut complete_state = CompleteState::Start { n, k };
+
+                    // Advance the complete-state iterator to the correct point
+                    for _ in 0..(prev_iteration_count + 1) {
+                        complete_state.advance();
+                    }
+
+                    PermutationState::Complete(complete_state)
+                }
+            }
+            &mut PermutationState::Complete(ref mut state) => {
+                state.advance();
+
+                return;
+            }
+            &mut PermutationState::Empty => { return; }
+        };
+    }
+}
+
+impl CompleteState {
+    fn advance(&mut self) {
+        *self = match self {
+            &mut CompleteState::Start { n, k } => {
+                let indices = (0..n).collect();
+                let cycles = ((n - k)..n).rev().collect();
+
+                CompleteState::Ongoing {
+                    cycles,
+                    indices
+                }
+            },
+            &mut CompleteState::Ongoing { ref mut indices, ref mut cycles } => {
+                let n = indices.len();
+                let k = cycles.len();
+
+                for i in (0..k).rev() {
+                    if cycles[i] == 0 {
+                        cycles[i] = n - i - 1;
+
+                        let to_push = indices.remove(i);
+                        indices.push(to_push);
+                    } else {
+                        let swap_index = n - cycles[i];
+                        indices.swap(i, swap_index);
+
+                        cycles[i] -= 1;
+                        return;
+                    }
+                }
+
+                CompleteState::Start { n, k }
+            }
+        }
+    }
+
+    fn remaining(&self) -> CompleteStateRemaining {
+        use self::CompleteStateRemaining::{Known, Overflow};
+
+        match self {
+            &CompleteState::Start { n, k } => {
+                if n < k {
+                    return Known(0);
+                }
+
+                let count: Option<usize> = (n - k + 1..n + 1).fold(Some(1), |acc, i| {
+                    acc.and_then(|acc| acc.checked_mul(i))
+                });
+
+                match count {
+                    Some(count) => Known(count),
+                    None => Overflow
+                }
+            }
+            &CompleteState::Ongoing { ref indices, ref cycles } => {
+                let mut count: usize = 0;
+
+                for (i, &c) in cycles.iter().enumerate() {
+                    let radix = indices.len() - i;
+                    let next_count = count.checked_mul(radix)
+                        .and_then(|count| count.checked_add(c));
+
+                    count = match next_count {
+                        Some(count) => count,
+                        None => { return Overflow; }
+                    };
+                }
+
+                Known(count)
+            }
+        }
+    }
+}
diff --git a/src/process_results_impl.rs b/src/process_results_impl.rs
new file mode 100644
index 0000000..c819f50
--- /dev/null
+++ b/src/process_results_impl.rs
@@ -0,0 +1,81 @@
+
+/// An iterator that produces only the `T` values as long as the
+/// inner iterator produces `Ok(T)`.
+///
+/// Used by [`process_results`](../fn.process_results.html), see its docs
+/// for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[derive(Debug)]
+pub struct ProcessResults<'a, I, E: 'a> {
+    error: &'a mut Result<(), E>,
+    iter: I,
+}
+
+impl<'a, I, T, E> Iterator for ProcessResults<'a, I, E>
+    where I: Iterator<Item = Result<T, E>>
+{
+    type Item = T;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        match self.iter.next() {
+            Some(Ok(x)) => Some(x),
+            Some(Err(e)) => {
+                *self.error = Err(e);
+                None
+            }
+            None => None,
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let (_, hi) = self.iter.size_hint();
+        (0, hi)
+    }
+}
+
+/// “Lift” a function of the values of an iterator so that it can process
+/// an iterator of `Result` values instead.
+///
+/// `iterable` is an iterator or iterable with `Result<T, E>` elements, where
+/// `T` is the value type and `E` the error type.
+///
+/// `processor` is a closure that receives an adapted version of the iterable
+/// as the only argument — the adapted iterator produces elements of type `T`,
+/// as long as the original iterator produces `Ok` values.
+///
+/// If the original iterable produces an error at any point, the adapted
+/// iterator ends and the `process_results` function will return the
+/// error iself.
+///
+/// Otherwise, the return value from the closure is returned wrapped
+/// inside `Ok`.
+///
+/// # Example
+///
+/// ```
+/// use itertools::process_results;
+///
+/// type R = Result<i32, &'static str>;
+///
+/// let first_values: Vec<R> = vec![Ok(1), Ok(0), Ok(3)];
+/// let second_values: Vec<R> = vec![Ok(2), Ok(1), Err("overflow")];
+///
+/// // “Lift” the iterator .max() method to work on the values in Results using process_results
+///
+/// let first_max = process_results(first_values, |iter| iter.max().unwrap_or(0));
+/// let second_max = process_results(second_values, |iter| iter.max().unwrap_or(0));
+///
+/// assert_eq!(first_max, Ok(3));
+/// assert!(second_max.is_err());
+/// ```
+pub fn process_results<I, F, T, E, R>(iterable: I, processor: F) -> Result<R, E>
+    where I: IntoIterator<Item = Result<T, E>>,
+          F: FnOnce(ProcessResults<I::IntoIter, E>) -> R
+{
+    let iter = iterable.into_iter();
+    let mut error = Ok(());
+
+    let result = processor(ProcessResults { error: &mut error, iter });
+
+    error.map(|_| result)
+}
diff --git a/src/put_back_n_impl.rs b/src/put_back_n_impl.rs
new file mode 100644
index 0000000..dcb2894
--- /dev/null
+++ b/src/put_back_n_impl.rs
@@ -0,0 +1,63 @@
+use crate::size_hint;
+
+/// An iterator adaptor that allows putting multiple
+/// items in front of the iterator.
+///
+/// Iterator element type is `I::Item`.
+#[derive(Debug, Clone)]
+pub struct PutBackN<I: Iterator> {
+    top: Vec<I::Item>,
+    iter: I,
+}
+
+/// Create an iterator where you can put back multiple values to the front
+/// of the iteration.
+///
+/// Iterator element type is `I::Item`.
+pub fn put_back_n<I>(iterable: I) -> PutBackN<I::IntoIter>
+    where I: IntoIterator
+{
+    PutBackN {
+        top: Vec::new(),
+        iter: iterable.into_iter(),
+    }
+}
+
+impl<I: Iterator> PutBackN<I> {
+    /// Puts x in front of the iterator.
+    /// The values are yielded in order of the most recently put back
+    /// values first.
+    ///
+    /// ```rust
+    /// use itertools::put_back_n;
+    ///
+    /// let mut it = put_back_n(1..5);
+    /// it.next();
+    /// it.put_back(1);
+    /// it.put_back(0);
+    ///
+    /// assert!(itertools::equal(it, 0..5));
+    /// ```
+    #[inline]
+    pub fn put_back(&mut self, x: I::Item) {
+        self.top.push(x);
+    }
+}
+
+impl<I: Iterator> Iterator for PutBackN<I> {
+    type Item = I::Item;
+    #[inline]
+    fn next(&mut self) -> Option<I::Item> {
+        if self.top.is_empty() {
+            self.iter.next()
+        } else {
+            self.top.pop()
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        size_hint::add_scalar(self.iter.size_hint(), self.top.len())
+    }
+}
+
diff --git a/src/rciter_impl.rs b/src/rciter_impl.rs
new file mode 100644
index 0000000..6ee90ad
--- /dev/null
+++ b/src/rciter_impl.rs
@@ -0,0 +1,96 @@
+
+use std::iter::IntoIterator;
+use std::rc::Rc;
+use std::cell::RefCell;
+
+/// A wrapper for `Rc<RefCell<I>>`, that implements the `Iterator` trait.
+#[derive(Debug)]
+pub struct RcIter<I> {
+    /// The boxed iterator.
+    pub rciter: Rc<RefCell<I>>,
+}
+
+/// Return an iterator inside a `Rc<RefCell<_>>` wrapper.
+///
+/// The returned `RcIter` can be cloned, and each clone will refer back to the
+/// same original iterator.
+///
+/// `RcIter` allows doing interesting things like using `.zip()` on an iterator with
+/// itself, at the cost of runtime borrow checking which may have a performance
+/// penalty.
+///
+/// Iterator element type is `Self::Item`.
+///
+/// ```
+/// use itertools::rciter;
+/// use itertools::zip;
+///
+/// // In this example a range iterator is created and we iterate it using
+/// // three separate handles (two of them given to zip).
+/// // We also use the IntoIterator implementation for `&RcIter`.
+///
+/// let mut iter = rciter(0..9);
+/// let mut z = zip(&iter, &iter);
+///
+/// assert_eq!(z.next(), Some((0, 1)));
+/// assert_eq!(z.next(), Some((2, 3)));
+/// assert_eq!(z.next(), Some((4, 5)));
+/// assert_eq!(iter.next(), Some(6));
+/// assert_eq!(z.next(), Some((7, 8)));
+/// assert_eq!(z.next(), None);
+/// ```
+///
+/// **Panics** in iterator methods if a borrow error is encountered in the
+/// iterator methods. It can only happen if the `RcIter` is reentered in
+/// `.next()`, i.e. if it somehow participates in an “iterator knot”
+/// where it is an adaptor of itself.
+pub fn rciter<I>(iterable: I) -> RcIter<I::IntoIter>
+    where I: IntoIterator
+{
+    RcIter { rciter: Rc::new(RefCell::new(iterable.into_iter())) }
+}
+
+impl<I> Clone for RcIter<I> {
+    #[inline]
+    clone_fields!(rciter);
+}
+
+impl<A, I> Iterator for RcIter<I>
+    where I: Iterator<Item = A>
+{
+    type Item = A;
+    #[inline]
+    fn next(&mut self) -> Option<A> {
+        self.rciter.borrow_mut().next()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        // To work sanely with other API that assume they own an iterator,
+        // so it can't change in other places, we can't guarantee as much
+        // in our size_hint. Other clones may drain values under our feet.
+        let (_, hi) = self.rciter.borrow().size_hint();
+        (0, hi)
+    }
+}
+
+impl<I> DoubleEndedIterator for RcIter<I>
+    where I: DoubleEndedIterator
+{
+    #[inline]
+    fn next_back(&mut self) -> Option<I::Item> {
+        self.rciter.borrow_mut().next_back()
+    }
+}
+
+/// Return an iterator from `&RcIter<I>` (by simply cloning it).
+impl<'a, I> IntoIterator for &'a RcIter<I>
+    where I: Iterator
+{
+    type Item = I::Item;
+    type IntoIter = RcIter<I>;
+
+    fn into_iter(self) -> RcIter<I> {
+        self.clone()
+    }
+}
diff --git a/src/repeatn.rs b/src/repeatn.rs
new file mode 100644
index 0000000..8bc4850
--- /dev/null
+++ b/src/repeatn.rs
@@ -0,0 +1,54 @@
+
+/// An iterator that produces *n* repetitions of an element.
+///
+/// See [`repeat_n()`](../fn.repeat_n.html) for more information.
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[derive(Clone, Debug)]
+pub struct RepeatN<A> {
+    elt: Option<A>,
+    n: usize,
+}
+
+/// Create an iterator that produces `n` repetitions of `element`.
+pub fn repeat_n<A>(element: A, n: usize) -> RepeatN<A>
+    where A: Clone,
+{
+    if n == 0 {
+        RepeatN { elt: None, n, }
+    } else {
+        RepeatN { elt: Some(element), n, }
+    }
+}
+
+impl<A> Iterator for RepeatN<A>
+    where A: Clone
+{
+    type Item = A;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if self.n > 1 {
+            self.n -= 1;
+            self.elt.as_ref().cloned()
+        } else {
+            self.n = 0;
+            self.elt.take()
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (self.n, Some(self.n))
+    }
+}
+
+impl<A> DoubleEndedIterator for RepeatN<A>
+    where A: Clone
+{
+    #[inline]
+    fn next_back(&mut self) -> Option<Self::Item> {
+        self.next()
+    }
+}
+
+impl<A> ExactSizeIterator for RepeatN<A>
+    where A: Clone
+{}
diff --git a/src/size_hint.rs b/src/size_hint.rs
new file mode 100644
index 0000000..be54443
--- /dev/null
+++ b/src/size_hint.rs
@@ -0,0 +1,104 @@
+//! Arithmetic on **Iterator** *.size_hint()* values.
+//!
+
+use std::usize;
+use std::cmp;
+
+/// **SizeHint** is the return type of **Iterator::size_hint()**.
+pub type SizeHint = (usize, Option<usize>);
+
+/// Add **SizeHint** correctly.
+#[inline]
+pub fn add(a: SizeHint, b: SizeHint) -> SizeHint {
+    let min = a.0.checked_add(b.0).unwrap_or(usize::MAX);
+    let max = match (a.1, b.1) {
+        (Some(x), Some(y)) => x.checked_add(y),
+        _ => None,
+    };
+
+    (min, max)
+}
+
+/// Add **x** correctly to a **SizeHint**.
+#[inline]
+pub fn add_scalar(sh: SizeHint, x: usize) -> SizeHint {
+    let (mut low, mut hi) = sh;
+    low = low.saturating_add(x);
+    hi = hi.and_then(|elt| elt.checked_add(x));
+    (low, hi)
+}
+
+/// Sbb **x** correctly to a **SizeHint**.
+#[inline]
+#[allow(dead_code)]
+pub fn sub_scalar(sh: SizeHint, x: usize) -> SizeHint {
+    let (mut low, mut hi) = sh;
+    low = low.saturating_sub(x);
+    hi = hi.map(|elt| elt.saturating_sub(x));
+    (low, hi)
+}
+
+
+/// Multiply **SizeHint** correctly
+///
+/// ```ignore
+/// use std::usize;
+/// use itertools::size_hint;
+///
+/// assert_eq!(size_hint::mul((3, Some(4)), (3, Some(4))),
+///            (9, Some(16)));
+///
+/// assert_eq!(size_hint::mul((3, Some(4)), (usize::MAX, None)),
+///            (usize::MAX, None));
+///
+/// assert_eq!(size_hint::mul((3, None), (0, Some(0))),
+///            (0, Some(0)));
+/// ```
+#[inline]
+pub fn mul(a: SizeHint, b: SizeHint) -> SizeHint {
+    let low = a.0.checked_mul(b.0).unwrap_or(usize::MAX);
+    let hi = match (a.1, b.1) {
+        (Some(x), Some(y)) => x.checked_mul(y),
+        (Some(0), None) | (None, Some(0)) => Some(0),
+        _ => None,
+    };
+    (low, hi)
+}
+
+/// Multiply **x** correctly with a **SizeHint**.
+#[inline]
+pub fn mul_scalar(sh: SizeHint, x: usize) -> SizeHint {
+    let (mut low, mut hi) = sh;
+    low = low.saturating_mul(x);
+    hi = hi.and_then(|elt| elt.checked_mul(x));
+    (low, hi)
+}
+
+/// Return the maximum
+#[inline]
+pub fn max(a: SizeHint, b: SizeHint) -> SizeHint {
+    let (a_lower, a_upper) = a;
+    let (b_lower, b_upper) = b;
+
+    let lower = cmp::max(a_lower, b_lower);
+
+    let upper = match (a_upper, b_upper) {
+        (Some(x), Some(y)) => Some(cmp::max(x, y)),
+        _ => None,
+    };
+
+    (lower, upper)
+}
+
+/// Return the minimum
+#[inline]
+pub fn min(a: SizeHint, b: SizeHint) -> SizeHint {
+    let (a_lower, a_upper) = a;
+    let (b_lower, b_upper) = b;
+    let lower = cmp::min(a_lower, b_lower);
+    let upper = match (a_upper, b_upper) {
+        (Some(u1), Some(u2)) => Some(cmp::min(u1, u2)),
+        _ => a_upper.or(b_upper),
+    };
+    (lower, upper)
+}
diff --git a/src/sources.rs b/src/sources.rs
new file mode 100644
index 0000000..17d9ff9
--- /dev/null
+++ b/src/sources.rs
@@ -0,0 +1,191 @@
+//! Iterators that are sources (produce elements from parameters,
+//! not from another iterator).
+#![allow(deprecated)]
+
+use std::fmt;
+use std::mem;
+
+/// See [`repeat_call`](../fn.repeat_call.html) for more information.
+#[derive(Clone)]
+#[deprecated(note="Use std repeat_with() instead", since="0.8")]
+pub struct RepeatCall<F> {
+    f: F,
+}
+
+impl<F> fmt::Debug for RepeatCall<F>
+{
+    debug_fmt_fields!(RepeatCall, );
+}
+
+/// An iterator source that produces elements indefinitely by calling
+/// a given closure.
+///
+/// Iterator element type is the return type of the closure.
+///
+/// ```
+/// use itertools::repeat_call;
+/// use itertools::Itertools;
+/// use std::collections::BinaryHeap;
+///
+/// let mut heap = BinaryHeap::from(vec![2, 5, 3, 7, 8]);
+///
+/// // extract each element in sorted order
+/// for element in repeat_call(|| heap.pop()).while_some() {
+///     print!("{}", element);
+/// }
+///
+/// itertools::assert_equal(
+///     repeat_call(|| 1).take(5),
+///     vec![1, 1, 1, 1, 1]
+/// );
+/// ```
+#[deprecated(note="Use std repeat_with() instead", since="0.8")]
+pub fn repeat_call<F, A>(function: F) -> RepeatCall<F>
+    where F: FnMut() -> A
+{
+    RepeatCall { f: function }
+}
+
+impl<A, F> Iterator for RepeatCall<F>
+    where F: FnMut() -> A
+{
+    type Item = A;
+
+    #[inline]
+    fn next(&mut self) -> Option<A> {
+        Some((self.f)())
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (usize::max_value(), None)
+    }
+}
+
+/// Creates a new unfold source with the specified closure as the "iterator
+/// function" and an initial state to eventually pass to the closure
+///
+/// `unfold` is a general iterator builder: it has a mutable state value,
+/// and a closure with access to the state that produces the next value.
+///
+/// This more or less equivalent to a regular struct with an `Iterator`
+/// implementation, and is useful for one-off iterators.
+///
+/// ```
+/// // an iterator that yields sequential Fibonacci numbers,
+/// // and stops at the maximum representable value.
+///
+/// use itertools::unfold;
+///
+/// let (mut x1, mut x2) = (1u32, 1u32);
+/// let mut fibonacci = unfold((), move |_| {
+///     // Attempt to get the next Fibonacci number
+///     let next = x1.saturating_add(x2);
+///
+///     // Shift left: ret <- x1 <- x2 <- next
+///     let ret = x1;
+///     x1 = x2;
+///     x2 = next;
+///
+///     // If addition has saturated at the maximum, we are finished
+///     if ret == x1 && ret > 1 {
+///         return None;
+///     }
+///
+///     Some(ret)
+/// });
+///
+/// itertools::assert_equal(fibonacci.by_ref().take(8),
+///                         vec![1, 1, 2, 3, 5, 8, 13, 21]);
+/// assert_eq!(fibonacci.last(), Some(2_971_215_073))
+/// ```
+pub fn unfold<A, St, F>(initial_state: St, f: F) -> Unfold<St, F>
+    where F: FnMut(&mut St) -> Option<A>
+{
+    Unfold {
+        f,
+        state: initial_state,
+    }
+}
+
+impl<St, F> fmt::Debug for Unfold<St, F>
+    where St: fmt::Debug,
+{
+    debug_fmt_fields!(Unfold, state);
+}
+
+/// See [`unfold`](../fn.unfold.html) for more information.
+#[derive(Clone)]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+pub struct Unfold<St, F> {
+    f: F,
+    /// Internal state that will be passed to the closure on the next iteration
+    pub state: St,
+}
+
+impl<A, St, F> Iterator for Unfold<St, F>
+    where F: FnMut(&mut St) -> Option<A>
+{
+    type Item = A;
+
+    #[inline]
+    fn next(&mut self) -> Option<A> {
+        (self.f)(&mut self.state)
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        // no possible known bounds at this point
+        (0, None)
+    }
+}
+
+/// An iterator that infinitely applies function to value and yields results.
+///
+/// This `struct` is created by the [`iterate()`] function. See its documentation for more.
+///
+/// [`iterate()`]: ../fn.iterate.html
+#[derive(Clone)]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+pub struct Iterate<St, F> {
+    state: St,
+    f: F,
+}
+
+impl<St, F> fmt::Debug for Iterate<St, F>
+    where St: fmt::Debug,
+{
+    debug_fmt_fields!(Iterate, state);
+}
+
+impl<St, F> Iterator for Iterate<St, F>
+    where F: FnMut(&St) -> St
+{
+    type Item = St;
+
+    #[inline]
+    fn next(&mut self) -> Option<Self::Item> {
+        let next_state = (self.f)(&self.state);
+        Some(mem::replace(&mut self.state, next_state))
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (usize::max_value(), None)
+    }
+}
+
+/// Creates a new iterator that infinitely applies function to value and yields results.
+///
+/// ```
+/// use itertools::iterate;
+///
+/// itertools::assert_equal(iterate(1, |&i| i * 3).take(5), vec![1, 3, 9, 27, 81]);
+/// ```
+pub fn iterate<St, F>(initial_value: St, f: F) -> Iterate<St, F>
+    where F: FnMut(&St) -> St
+{
+    Iterate {
+        state: initial_value,
+        f,
+    }
+}
diff --git a/src/tee.rs b/src/tee.rs
new file mode 100644
index 0000000..aa4be41
--- /dev/null
+++ b/src/tee.rs
@@ -0,0 +1,78 @@
+use super::size_hint;
+
+use std::cell::RefCell;
+use std::collections::VecDeque;
+use std::rc::Rc;
+
+/// Common buffer object for the two tee halves
+#[derive(Debug)]
+struct TeeBuffer<A, I> {
+    backlog: VecDeque<A>,
+    iter: I,
+    /// The owner field indicates which id should read from the backlog
+    owner: bool,
+}
+
+/// One half of an iterator pair where both return the same elements.
+///
+/// See [`.tee()`](../trait.Itertools.html#method.tee) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[derive(Debug)]
+pub struct Tee<I>
+    where I: Iterator
+{
+    rcbuffer: Rc<RefCell<TeeBuffer<I::Item, I>>>,
+    id: bool,
+}
+
+pub fn new<I>(iter: I) -> (Tee<I>, Tee<I>)
+    where I: Iterator
+{
+    let buffer = TeeBuffer{backlog: VecDeque::new(), iter, owner: false};
+    let t1 = Tee{rcbuffer: Rc::new(RefCell::new(buffer)), id: true};
+    let t2 = Tee{rcbuffer: t1.rcbuffer.clone(), id: false};
+    (t1, t2)
+}
+
+impl<I> Iterator for Tee<I>
+    where I: Iterator,
+          I::Item: Clone
+{
+    type Item = I::Item;
+    fn next(&mut self) -> Option<I::Item> {
+        // .borrow_mut may fail here -- but only if the user has tied some kind of weird
+        // knot where the iterator refers back to itself.
+        let mut buffer = self.rcbuffer.borrow_mut();
+        if buffer.owner == self.id {
+            match buffer.backlog.pop_front() {
+                None => {}
+                some_elt => return some_elt,
+            }
+        }
+        match buffer.iter.next() {
+            None => None,
+            Some(elt) => {
+                buffer.backlog.push_back(elt.clone());
+                buffer.owner = !self.id;
+                Some(elt)
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let buffer = self.rcbuffer.borrow();
+        let sh = buffer.iter.size_hint();
+
+        if buffer.owner == self.id {
+            let log_len = buffer.backlog.len();
+            size_hint::add_scalar(sh, log_len)
+        } else {
+            sh
+        }
+    }
+}
+
+impl<I> ExactSizeIterator for Tee<I>
+    where I: ExactSizeIterator,
+          I::Item: Clone
+{}
diff --git a/src/tuple_impl.rs b/src/tuple_impl.rs
new file mode 100644
index 0000000..f205f01
--- /dev/null
+++ b/src/tuple_impl.rs
@@ -0,0 +1,279 @@
+//! Some iterator that produces tuples
+
+use std::iter::Fuse;
+
+// `HomogeneousTuple` is a public facade for `TupleCollect`, allowing
+// tuple-related methods to be used by clients in generic contexts, while
+// hiding the implementation details of `TupleCollect`.
+// See https://github.com/rust-itertools/itertools/issues/387
+
+/// Implemented for homogeneous tuples of size up to 4.
+pub trait HomogeneousTuple
+    : TupleCollect
+{}
+
+impl<T: TupleCollect> HomogeneousTuple for T {}
+
+/// An iterator over a incomplete tuple.
+///
+/// See [`.tuples()`](../trait.Itertools.html#method.tuples) and
+/// [`Tuples::into_buffer()`](struct.Tuples.html#method.into_buffer).
+#[derive(Clone, Debug)]
+pub struct TupleBuffer<T>
+    where T: HomogeneousTuple
+{
+    cur: usize,
+    buf: T::Buffer,
+}
+
+impl<T> TupleBuffer<T>
+    where T: HomogeneousTuple
+{
+    fn new(buf: T::Buffer) -> Self {
+        TupleBuffer {
+            cur: 0,
+            buf,
+        }
+    }
+}
+
+impl<T> Iterator for TupleBuffer<T>
+    where T: HomogeneousTuple
+{
+    type Item = T::Item;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let s = self.buf.as_mut();
+        if let Some(ref mut item) = s.get_mut(self.cur) {
+            self.cur += 1;
+            item.take()
+        } else {
+            None
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let buffer = &self.buf.as_ref()[self.cur..];
+        let len = if buffer.len() == 0 {
+            0
+        } else {
+            buffer.iter()
+                  .position(|x| x.is_none())
+                  .unwrap_or(buffer.len())
+        };
+        (len, Some(len))
+    }
+}
+
+impl<T> ExactSizeIterator for TupleBuffer<T>
+    where T: HomogeneousTuple
+{
+}
+
+/// An iterator that groups the items in tuples of a specific size.
+///
+/// See [`.tuples()`](../trait.Itertools.html#method.tuples) for more information.
+#[derive(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Tuples<I, T>
+    where I: Iterator<Item = T::Item>,
+          T: HomogeneousTuple
+{
+    iter: Fuse<I>,
+    buf: T::Buffer,
+}
+
+/// Create a new tuples iterator.
+pub fn tuples<I, T>(iter: I) -> Tuples<I, T>
+    where I: Iterator<Item = T::Item>,
+          T: HomogeneousTuple
+{
+    Tuples {
+        iter: iter.fuse(),
+        buf: Default::default(),
+    }
+}
+
+impl<I, T> Iterator for Tuples<I, T>
+    where I: Iterator<Item = T::Item>,
+          T: HomogeneousTuple
+{
+    type Item = T;
+
+    fn next(&mut self) -> Option<T> {
+        T::collect_from_iter(&mut self.iter, &mut self.buf)
+    }
+}
+
+impl<I, T> Tuples<I, T>
+    where I: Iterator<Item = T::Item>,
+          T: HomogeneousTuple
+{
+    /// Return a buffer with the produced items that was not enough to be grouped in a tuple.
+    ///
+    /// ```
+    /// use itertools::Itertools;
+    ///
+    /// let mut iter = (0..5).tuples();
+    /// assert_eq!(Some((0, 1, 2)), iter.next());
+    /// assert_eq!(None, iter.next());
+    /// itertools::assert_equal(vec![3, 4], iter.into_buffer());
+    /// ```
+    pub fn into_buffer(self) -> TupleBuffer<T> {
+        TupleBuffer::new(self.buf)
+    }
+}
+
+
+/// An iterator over all contiguous windows that produces tuples of a specific size.
+///
+/// See [`.tuple_windows()`](../trait.Itertools.html#method.tuple_windows) for more
+/// information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[derive(Clone, Debug)]
+pub struct TupleWindows<I, T>
+    where I: Iterator<Item = T::Item>,
+          T: HomogeneousTuple
+{
+    iter: I,
+    last: Option<T>,
+}
+
+/// Create a new tuple windows iterator.
+pub fn tuple_windows<I, T>(mut iter: I) -> TupleWindows<I, T>
+    where I: Iterator<Item = T::Item>,
+          T: HomogeneousTuple,
+          T::Item: Clone
+{
+    use std::iter::once;
+
+    let mut last = None;
+    if T::num_items() != 1 {
+        // put in a duplicate item in front of the tuple; this simplifies
+        // .next() function.
+        if let Some(item) = iter.next() {
+            let iter = once(item.clone()).chain(once(item)).chain(&mut iter);
+            last = T::collect_from_iter_no_buf(iter);
+        }
+    }
+
+    TupleWindows {
+        last,
+        iter,
+    }
+}
+
+impl<I, T> Iterator for TupleWindows<I, T>
+    where I: Iterator<Item = T::Item>,
+          T: HomogeneousTuple + Clone,
+          T::Item: Clone
+{
+    type Item = T;
+
+    fn next(&mut self) -> Option<T> {
+        if T::num_items() == 1 {
+            return T::collect_from_iter_no_buf(&mut self.iter)
+        }
+        if let Some(ref mut last) = self.last {
+            if let Some(new) = self.iter.next() {
+                last.left_shift_push(new);
+                return Some(last.clone());
+            }
+        }
+        None
+    }
+}
+
+pub trait TupleCollect: Sized {
+    type Item;
+    type Buffer: Default + AsRef<[Option<Self::Item>]> + AsMut<[Option<Self::Item>]>;
+
+    fn collect_from_iter<I>(iter: I, buf: &mut Self::Buffer) -> Option<Self>
+        where I: IntoIterator<Item = Self::Item>;
+
+    fn collect_from_iter_no_buf<I>(iter: I) -> Option<Self>
+        where I: IntoIterator<Item = Self::Item>;
+
+    fn num_items() -> usize;
+
+    fn left_shift_push(&mut self, item: Self::Item);
+}
+
+macro_rules! impl_tuple_collect {
+    () => ();
+    ($N:expr; $A:ident ; $($X:ident),* ; $($Y:ident),* ; $($Y_rev:ident),*) => (
+        impl<$A> TupleCollect for ($($X),*,) {
+            type Item = $A;
+            type Buffer = [Option<$A>; $N - 1];
+
+            #[allow(unused_assignments, unused_mut)]
+            fn collect_from_iter<I>(iter: I, buf: &mut Self::Buffer) -> Option<Self>
+                where I: IntoIterator<Item = $A>
+            {
+                let mut iter = iter.into_iter();
+                $(
+                    let mut $Y = None;
+                )*
+
+                loop {
+                    $(
+                        $Y = iter.next();
+                        if $Y.is_none() {
+                            break
+                        }
+                    )*
+                    return Some(($($Y.unwrap()),*,))
+                }
+
+                let mut i = 0;
+                let mut s = buf.as_mut();
+                $(
+                    if i < s.len() {
+                        s[i] = $Y;
+                        i += 1;
+                    }
+                )*
+                return None;
+            }
+
+            #[allow(unused_assignments)]
+            fn collect_from_iter_no_buf<I>(iter: I) -> Option<Self>
+                where I: IntoIterator<Item = $A>
+            {
+                let mut iter = iter.into_iter();
+                loop {
+                    $(
+                        let $Y = if let Some($Y) = iter.next() {
+                            $Y
+                        } else {
+                            break;
+                        };
+                    )*
+                    return Some(($($Y),*,))
+                }
+
+                return None;
+            }
+
+            fn num_items() -> usize {
+                $N
+            }
+
+            fn left_shift_push(&mut self, item: $A) {
+                use std::mem::replace;
+
+                let &mut ($(ref mut $Y),*,) = self;
+                let tmp = item;
+                $(
+                    let tmp = replace($Y_rev, tmp);
+                )*
+                drop(tmp);
+            }
+        }
+    )
+}
+
+impl_tuple_collect!(1; A; A; a; a);
+impl_tuple_collect!(2; A; A, A; a, b; b, a);
+impl_tuple_collect!(3; A; A, A, A; a, b, c; c, b, a);
+impl_tuple_collect!(4; A; A, A, A, A; a, b, c, d; d, c, b, a);
diff --git a/src/unique_impl.rs b/src/unique_impl.rs
new file mode 100644
index 0000000..cf8675c
--- /dev/null
+++ b/src/unique_impl.rs
@@ -0,0 +1,134 @@
+
+use std::collections::HashMap;
+use std::collections::hash_map::{Entry};
+use std::hash::Hash;
+use std::fmt;
+
+/// An iterator adapter to filter out duplicate elements.
+///
+/// See [`.unique_by()`](../trait.Itertools.html#method.unique) for more information.
+#[derive(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct UniqueBy<I: Iterator, V, F> {
+    iter: I,
+    // Use a hashmap for the entry API
+    used: HashMap<V, ()>,
+    f: F,
+}
+
+impl<I, V, F> fmt::Debug for UniqueBy<I, V, F>
+    where I: Iterator + fmt::Debug,
+          V: fmt::Debug + Hash + Eq,
+{
+    debug_fmt_fields!(UniqueBy, iter, used);
+}
+
+/// Create a new `UniqueBy` iterator.
+pub fn unique_by<I, V, F>(iter: I, f: F) -> UniqueBy<I, V, F>
+    where V: Eq + Hash,
+          F: FnMut(&I::Item) -> V,
+          I: Iterator,
+{
+    UniqueBy {
+        iter,
+        used: HashMap::new(),
+        f,
+    }
+}
+
+// count the number of new unique keys in iterable (`used` is the set already seen)
+fn count_new_keys<I, K>(mut used: HashMap<K, ()>, iterable: I) -> usize
+    where I: IntoIterator<Item=K>,
+          K: Hash + Eq,
+{
+    let iter = iterable.into_iter();
+    let current_used = used.len();
+    used.extend(iter.map(|key| (key, ())));
+    used.len() - current_used
+}
+
+impl<I, V, F> Iterator for UniqueBy<I, V, F>
+    where I: Iterator,
+          V: Eq + Hash,
+          F: FnMut(&I::Item) -> V
+{
+    type Item = I::Item;
+
+    fn next(&mut self) -> Option<I::Item> {
+        while let Some(v) = self.iter.next() {
+            let key = (self.f)(&v);
+            if self.used.insert(key, ()).is_none() {
+                return Some(v);
+            }
+        }
+        None
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let (low, hi) = self.iter.size_hint();
+        ((low > 0 && self.used.is_empty()) as usize, hi)
+    }
+
+    fn count(self) -> usize {
+        let mut key_f = self.f;
+        count_new_keys(self.used, self.iter.map(move |elt| key_f(&elt)))
+    }
+}
+
+impl<I> Iterator for Unique<I>
+    where I: Iterator,
+          I::Item: Eq + Hash + Clone
+{
+    type Item = I::Item;
+
+    fn next(&mut self) -> Option<I::Item> {
+        while let Some(v) = self.iter.iter.next() {
+            if let Entry::Vacant(entry) = self.iter.used.entry(v) {
+                let elt = entry.key().clone();
+                entry.insert(());
+                return Some(elt);
+            }
+        }
+        None
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let (low, hi) = self.iter.iter.size_hint();
+        ((low > 0 && self.iter.used.is_empty()) as usize, hi)
+    }
+
+    fn count(self) -> usize {
+        count_new_keys(self.iter.used, self.iter.iter)
+    }
+}
+
+/// An iterator adapter to filter out duplicate elements.
+///
+/// See [`.unique()`](../trait.Itertools.html#method.unique) for more information.
+#[derive(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Unique<I: Iterator> {
+    iter: UniqueBy<I, I::Item, ()>,
+}
+
+impl<I> fmt::Debug for Unique<I>
+    where I: Iterator + fmt::Debug,
+          I::Item: Hash + Eq + fmt::Debug,
+{
+    debug_fmt_fields!(Unique, iter);
+}
+
+pub fn unique<I>(iter: I) -> Unique<I>
+    where I: Iterator,
+          I::Item: Eq + Hash,
+{
+    Unique {
+        iter: UniqueBy {
+            iter,
+            used: HashMap::new(),
+            f: (),
+        }
+    }
+}
diff --git a/src/with_position.rs b/src/with_position.rs
new file mode 100644
index 0000000..1440fb6
--- /dev/null
+++ b/src/with_position.rs
@@ -0,0 +1,97 @@
+use std::iter::{Fuse,Peekable};
+
+/// An iterator adaptor that wraps each element in an [`Position`](../enum.Position.html).
+///
+/// Iterator element type is `Position<I::Item>`.
+///
+/// See [`.with_position()`](../trait.Itertools.html#method.with_position) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct WithPosition<I>
+    where I: Iterator,
+{
+    handled_first: bool,
+    peekable: Peekable<Fuse<I>>,
+}
+
+impl<I> Clone for WithPosition<I>
+    where I: Clone + Iterator,
+          I::Item: Clone,
+{
+    clone_fields!(handled_first, peekable);
+}
+
+/// Create a new `WithPosition` iterator.
+pub fn with_position<I>(iter: I) -> WithPosition<I>
+    where I: Iterator,
+{
+    WithPosition {
+        handled_first: false,
+        peekable: iter.fuse().peekable(),
+    }
+}
+
+/// A value yielded by `WithPosition`.
+/// Indicates the position of this element in the iterator results.
+///
+/// See [`.with_position()`](trait.Itertools.html#method.with_position) for more information.
+#[derive(Copy, Clone, Debug, PartialEq)]
+pub enum Position<T> {
+    /// This is the first element.
+    First(T),
+    /// This is neither the first nor the last element.
+    Middle(T),
+    /// This is the last element.
+    Last(T),
+    /// This is the only element.
+    Only(T),
+}
+
+impl<T> Position<T> {
+    /// Return the inner value.
+    pub fn into_inner(self) -> T {
+        match self {
+            Position::First(x) |
+            Position::Middle(x) |
+            Position::Last(x) |
+            Position::Only(x) => x,
+        }
+    }
+}
+
+impl<I: Iterator> Iterator for WithPosition<I> {
+    type Item = Position<I::Item>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        match self.peekable.next() {
+            Some(item) => {
+                if !self.handled_first {
+                    // Haven't seen the first item yet, and there is one to give.
+                    self.handled_first = true;
+                    // Peek to see if this is also the last item,
+                    // in which case tag it as `Only`.
+                    match self.peekable.peek() {
+                        Some(_) => Some(Position::First(item)),
+                        None => Some(Position::Only(item)),
+                    }
+                } else {
+                    // Have seen the first item, and there's something left.
+                    // Peek to see if this is the last item.
+                    match self.peekable.peek() {
+                        Some(_) => Some(Position::Middle(item)),
+                        None => Some(Position::Last(item)),
+                    }
+                }
+            }
+            // Iterator is finished.
+            None => None,
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.peekable.size_hint()
+    }
+}
+
+impl<I> ExactSizeIterator for WithPosition<I>
+    where I: ExactSizeIterator,
+{ }
diff --git a/src/zip_eq_impl.rs b/src/zip_eq_impl.rs
new file mode 100644
index 0000000..857465d
--- /dev/null
+++ b/src/zip_eq_impl.rs
@@ -0,0 +1,60 @@
+use super::size_hint;
+
+/// An iterator which iterates two other iterators simultaneously
+///
+/// See [`.zip_eq()`](../trait.Itertools.html#method.zip_eq) for more information.
+#[derive(Clone, Debug)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct ZipEq<I, J> {
+    a: I,
+    b: J,
+}
+
+/// Iterate `i` and `j` in lock step.
+///
+/// **Panics** if the iterators are not of the same length.
+///
+/// `IntoIterator` enabled version of `i.zip_eq(j)`.
+///
+/// ```
+/// use itertools::zip_eq;
+///
+/// let data = [1, 2, 3, 4, 5];
+/// for (a, b) in zip_eq(&data[..data.len() - 1], &data[1..]) {
+///     /* loop body */
+/// }
+/// ```
+pub fn zip_eq<I, J>(i: I, j: J) -> ZipEq<I::IntoIter, J::IntoIter>
+    where I: IntoIterator,
+          J: IntoIterator
+{
+    ZipEq {
+        a: i.into_iter(),
+        b: j.into_iter(),
+    }
+}
+
+impl<I, J> Iterator for ZipEq<I, J>
+    where I: Iterator,
+          J: Iterator
+{
+    type Item = (I::Item, J::Item);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        match (self.a.next(), self.b.next()) {
+            (None, None) => None,
+            (Some(a), Some(b)) => Some((a, b)),
+            (None, Some(_)) | (Some(_), None) =>
+            panic!("itertools: .zip_eq() reached end of one iterator before the other")
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        size_hint::min(self.a.size_hint(), self.b.size_hint())
+    }
+}
+
+impl<I, J> ExactSizeIterator for ZipEq<I, J>
+    where I: ExactSizeIterator,
+          J: ExactSizeIterator
+{}
diff --git a/src/zip_longest.rs b/src/zip_longest.rs
new file mode 100644
index 0000000..1395c84
--- /dev/null
+++ b/src/zip_longest.rs
@@ -0,0 +1,78 @@
+use std::cmp::Ordering::{Equal, Greater, Less};
+use super::size_hint;
+use std::iter::Fuse;
+
+use crate::either_or_both::EitherOrBoth;
+
+// ZipLongest originally written by SimonSapin,
+// and dedicated to itertools https://github.com/rust-lang/rust/pull/19283
+
+/// An iterator which iterates two other iterators simultaneously
+///
+/// This iterator is *fused*.
+///
+/// See [`.zip_longest()`](../trait.Itertools.html#method.zip_longest) for more information.
+#[derive(Clone, Debug)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct ZipLongest<T, U> {
+    a: Fuse<T>,
+    b: Fuse<U>,
+}
+
+/// Create a new `ZipLongest` iterator.
+pub fn zip_longest<T, U>(a: T, b: U) -> ZipLongest<T, U> 
+    where T: Iterator,
+          U: Iterator
+{
+    ZipLongest {
+        a: a.fuse(),
+        b: b.fuse(),
+    }
+}
+
+impl<T, U> Iterator for ZipLongest<T, U>
+    where T: Iterator,
+          U: Iterator
+{
+    type Item = EitherOrBoth<T::Item, U::Item>;
+
+    #[inline]
+    fn next(&mut self) -> Option<Self::Item> {
+        match (self.a.next(), self.b.next()) {
+            (None, None) => None,
+            (Some(a), None) => Some(EitherOrBoth::Left(a)),
+            (None, Some(b)) => Some(EitherOrBoth::Right(b)),
+            (Some(a), Some(b)) => Some(EitherOrBoth::Both(a, b)),
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        size_hint::max(self.a.size_hint(), self.b.size_hint())
+    }
+}
+
+impl<T, U> DoubleEndedIterator for ZipLongest<T, U>
+    where T: DoubleEndedIterator + ExactSizeIterator,
+          U: DoubleEndedIterator + ExactSizeIterator
+{
+    #[inline]
+    fn next_back(&mut self) -> Option<Self::Item> {
+        match self.a.len().cmp(&self.b.len()) {
+            Equal => match (self.a.next_back(), self.b.next_back()) {
+                (None, None) => None,
+                (Some(a), Some(b)) => Some(EitherOrBoth::Both(a, b)),
+                // These can only happen if .len() is inconsistent with .next_back()
+                (Some(a), None) => Some(EitherOrBoth::Left(a)),
+                (None, Some(b)) => Some(EitherOrBoth::Right(b)),
+            },
+            Greater => self.a.next_back().map(EitherOrBoth::Left),
+            Less => self.b.next_back().map(EitherOrBoth::Right),
+        }
+    }
+}
+
+impl<T, U> ExactSizeIterator for ZipLongest<T, U>
+    where T: ExactSizeIterator,
+          U: ExactSizeIterator
+{}
diff --git a/src/ziptuple.rs b/src/ziptuple.rs
new file mode 100644
index 0000000..2dc3ea5
--- /dev/null
+++ b/src/ziptuple.rs
@@ -0,0 +1,111 @@
+use super::size_hint;
+
+/// See [`multizip`](../fn.multizip.html) for more information.
+#[derive(Clone, Debug)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Zip<T> {
+    t: T,
+}
+
+/// An iterator that generalizes *.zip()* and allows running multiple iterators in lockstep.
+///
+/// The iterator `Zip<(I, J, ..., M)>` is formed from a tuple of iterators (or values that
+/// implement `IntoIterator`) and yields elements
+/// until any of the subiterators yields `None`.
+///
+/// The iterator element type is a tuple like like `(A, B, ..., E)` where `A` to `E` are the
+/// element types of the subiterator.
+///
+/// **Note:** The result of this macro is a value of a named type (`Zip<(I, J,
+/// ..)>` of each component iterator `I, J, ...`) if each component iterator is
+/// nameable.
+///
+/// Prefer [`izip!()`] over `multizip` for the performance benefits of using the
+/// standard library `.zip()`. Prefer `multizip` if a nameable type is needed.
+///
+/// [`izip!()`]: macro.izip.html
+///
+/// ```
+/// use itertools::multizip;
+///
+/// // iterate over three sequences side-by-side
+/// let mut results = [0, 0, 0, 0];
+/// let inputs = [3, 7, 9, 6];
+///
+/// for (r, index, input) in multizip((&mut results, 0..10, &inputs)) {
+///     *r = index * 10 + input;
+/// }
+///
+/// assert_eq!(results, [0 + 3, 10 + 7, 29, 36]);
+/// ```
+pub fn multizip<T, U>(t: U) -> Zip<T>
+    where Zip<T>: From<U>,
+          Zip<T>: Iterator,
+{
+    Zip::from(t)
+}
+
+macro_rules! impl_zip_iter {
+    ($($B:ident),*) => (
+        #[allow(non_snake_case)]
+        impl<$($B: IntoIterator),*> From<($($B,)*)> for Zip<($($B::IntoIter,)*)> {
+            fn from(t: ($($B,)*)) -> Self {
+                let ($($B,)*) = t;
+                Zip { t: ($($B.into_iter(),)*) }
+            }
+        }
+
+        #[allow(non_snake_case)]
+        #[allow(unused_assignments)]
+        impl<$($B),*> Iterator for Zip<($($B,)*)>
+            where
+            $(
+                $B: Iterator,
+            )*
+        {
+            type Item = ($($B::Item,)*);
+
+            fn next(&mut self) -> Option<Self::Item>
+            {
+                let ($(ref mut $B,)*) = self.t;
+
+                // NOTE: Just like iter::Zip, we check the iterators
+                // for None in order. We may finish unevenly (some
+                // iterators gave n + 1 elements, some only n).
+                $(
+                    let $B = match $B.next() {
+                        None => return None,
+                        Some(elt) => elt
+                    };
+                )*
+                Some(($($B,)*))
+            }
+
+            fn size_hint(&self) -> (usize, Option<usize>)
+            {
+                let sh = (::std::usize::MAX, None);
+                let ($(ref $B,)*) = self.t;
+                $(
+                    let sh = size_hint::min($B.size_hint(), sh);
+                )*
+                sh
+            }
+        }
+
+        #[allow(non_snake_case)]
+        impl<$($B),*> ExactSizeIterator for Zip<($($B,)*)> where
+            $(
+                $B: ExactSizeIterator,
+            )*
+        { }
+    );
+}
+
+impl_zip_iter!(A);
+impl_zip_iter!(A, B);
+impl_zip_iter!(A, B, C);
+impl_zip_iter!(A, B, C, D);
+impl_zip_iter!(A, B, C, D, E);
+impl_zip_iter!(A, B, C, D, E, F);
+impl_zip_iter!(A, B, C, D, E, F, G);
+impl_zip_iter!(A, B, C, D, E, F, G, H);
diff --git a/tests/adaptors_no_collect.rs b/tests/adaptors_no_collect.rs
new file mode 100644
index 0000000..a47f906
--- /dev/null
+++ b/tests/adaptors_no_collect.rs
@@ -0,0 +1,47 @@
+use itertools::Itertools;
+
+struct PanickingCounter {
+    curr: usize,
+    max: usize,
+}
+
+impl Iterator for PanickingCounter {
+    type Item = ();
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.curr += 1;
+
+        if self.curr == self.max {
+            panic!(
+                "Input iterator reached maximum of {} suggesting collection by adaptor",
+                self.max
+            );
+        }
+
+        Some(())
+    }
+}
+
+fn no_collect_test<A, T>(to_adaptor: T)
+    where A: Iterator, T: Fn(PanickingCounter) -> A
+{
+    let counter = PanickingCounter { curr: 0, max: 10_000 };
+    let adaptor = to_adaptor(counter);
+
+    for _ in adaptor.take(5) {}
+}
+
+#[test]
+fn permutations_no_collect() {
+    no_collect_test(|iter| iter.permutations(5))
+}
+
+#[test]
+fn combinations_no_collect() {
+    no_collect_test(|iter| iter.combinations(5))
+}
+
+#[test]
+fn combinations_with_replacement_no_collect() {
+    no_collect_test(|iter| iter.combinations_with_replacement(5))
+}
\ No newline at end of file
diff --git a/tests/fold_specialization.rs b/tests/fold_specialization.rs
new file mode 100644
index 0000000..a984b40
--- /dev/null
+++ b/tests/fold_specialization.rs
@@ -0,0 +1,13 @@
+use itertools::Itertools;
+
+#[test]
+fn specialization_intersperse() {
+    let mut iter = (1..2).intersperse(0);
+    iter.clone().for_each(|x| assert_eq!(Some(x), iter.next()));
+
+    let mut iter = (1..3).intersperse(0);
+    iter.clone().for_each(|x| assert_eq!(Some(x), iter.next()));
+
+    let mut iter = (1..4).intersperse(0);
+    iter.clone().for_each(|x| assert_eq!(Some(x), iter.next()));
+}
diff --git a/tests/merge_join.rs b/tests/merge_join.rs
new file mode 100644
index 0000000..3280b7d
--- /dev/null
+++ b/tests/merge_join.rs
@@ -0,0 +1,108 @@
+use itertools::EitherOrBoth;
+use itertools::free::merge_join_by;
+
+#[test]
+fn empty() {
+    let left: Vec<u32> = vec![];
+    let right: Vec<u32> = vec![];
+    let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![];
+    let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
+        .collect::<Vec<_>>();
+    assert_eq!(expected_result, actual_result);
+}
+
+#[test]
+fn left_only() {
+    let left: Vec<u32> = vec![1,2,3];
+    let right: Vec<u32> = vec![];
+    let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![
+        EitherOrBoth::Left(1),
+        EitherOrBoth::Left(2),
+        EitherOrBoth::Left(3)
+    ];
+    let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
+        .collect::<Vec<_>>();
+    assert_eq!(expected_result, actual_result);
+}
+
+#[test]
+fn right_only() {
+    let left: Vec<u32> = vec![];
+    let right: Vec<u32> = vec![1,2,3];
+    let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![
+        EitherOrBoth::Right(1),
+        EitherOrBoth::Right(2),
+        EitherOrBoth::Right(3)
+    ];
+    let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
+        .collect::<Vec<_>>();
+    assert_eq!(expected_result, actual_result);
+}
+
+#[test]
+fn first_left_then_right() {
+    let left: Vec<u32> = vec![1,2,3];
+    let right: Vec<u32> = vec![4,5,6];
+    let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![
+        EitherOrBoth::Left(1),
+        EitherOrBoth::Left(2),
+        EitherOrBoth::Left(3),
+        EitherOrBoth::Right(4),
+        EitherOrBoth::Right(5),
+        EitherOrBoth::Right(6)
+    ];
+    let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
+        .collect::<Vec<_>>();
+    assert_eq!(expected_result, actual_result);
+}
+
+#[test]
+fn first_right_then_left() {
+    let left: Vec<u32> = vec![4,5,6];
+    let right: Vec<u32> = vec![1,2,3];
+    let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![
+        EitherOrBoth::Right(1),
+        EitherOrBoth::Right(2),
+        EitherOrBoth::Right(3),
+        EitherOrBoth::Left(4),
+        EitherOrBoth::Left(5),
+        EitherOrBoth::Left(6)
+    ];
+    let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
+        .collect::<Vec<_>>();
+    assert_eq!(expected_result, actual_result);
+}
+
+#[test]
+fn interspersed_left_and_right() {
+    let left: Vec<u32> = vec![1,3,5];
+    let right: Vec<u32> = vec![2,4,6];
+    let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![
+        EitherOrBoth::Left(1),
+        EitherOrBoth::Right(2),
+        EitherOrBoth::Left(3),
+        EitherOrBoth::Right(4),
+        EitherOrBoth::Left(5),
+        EitherOrBoth::Right(6)
+    ];
+    let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
+        .collect::<Vec<_>>();
+    assert_eq!(expected_result, actual_result);
+}
+
+#[test]
+fn overlapping_left_and_right() {
+    let left: Vec<u32> = vec![1,3,4,6];
+    let right: Vec<u32> = vec![2,3,4,5];
+    let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![
+        EitherOrBoth::Left(1),
+        EitherOrBoth::Right(2),
+        EitherOrBoth::Both(3, 3),
+        EitherOrBoth::Both(4, 4),
+        EitherOrBoth::Right(5),
+        EitherOrBoth::Left(6)
+    ];
+    let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
+        .collect::<Vec<_>>();
+    assert_eq!(expected_result, actual_result);
+}
diff --git a/tests/peeking_take_while.rs b/tests/peeking_take_while.rs
new file mode 100644
index 0000000..a114702
--- /dev/null
+++ b/tests/peeking_take_while.rs
@@ -0,0 +1,50 @@
+use itertools::Itertools;
+use itertools::{put_back, put_back_n};
+
+#[test]
+fn peeking_take_while_peekable() {
+    let mut r = (0..10).peekable();
+    r.peeking_take_while(|x| *x <= 3).count();
+    assert_eq!(r.next(), Some(4));
+}
+
+#[test]
+fn peeking_take_while_put_back() {
+    let mut r = put_back(0..10);
+    r.peeking_take_while(|x| *x <= 3).count();
+    assert_eq!(r.next(), Some(4));
+    r.peeking_take_while(|_| true).count();
+    assert_eq!(r.next(), None);
+}
+
+#[test]
+fn peeking_take_while_put_back_n() {
+    let mut r = put_back_n(6..10);
+    for elt in (0..6).rev() {
+        r.put_back(elt);
+    }
+    r.peeking_take_while(|x| *x <= 3).count();
+    assert_eq!(r.next(), Some(4));
+    r.peeking_take_while(|_| true).count();
+    assert_eq!(r.next(), None);
+}
+
+#[test]
+fn peeking_take_while_slice_iter() {
+    let v = [1, 2, 3, 4, 5, 6];
+    let mut r = v.iter();
+    r.peeking_take_while(|x| **x <= 3).count();
+    assert_eq!(r.next(), Some(&4));
+    r.peeking_take_while(|_| true).count();
+    assert_eq!(r.next(), None);
+}
+
+#[test]
+fn peeking_take_while_slice_iter_rev() {
+    let v = [1, 2, 3, 4, 5, 6];
+    let mut r = v.iter().rev();
+    r.peeking_take_while(|x| **x >= 3).count();
+    assert_eq!(r.next(), Some(&2));
+    r.peeking_take_while(|_| true).count();
+    assert_eq!(r.next(), None);
+}
diff --git a/tests/quick.rs b/tests/quick.rs
new file mode 100644
index 0000000..683ba7a
--- /dev/null
+++ b/tests/quick.rs
@@ -0,0 +1,1157 @@
+//! The purpose of these tests is to cover corner cases of iterators
+//! and adaptors.
+//!
+//! In particular we test the tedious size_hint and exact size correctness.
+
+use quickcheck as qc;
+use std::default::Default;
+use std::ops::Range;
+use std::cmp::{max, min, Ordering};
+use std::collections::HashSet;
+use itertools::Itertools;
+use itertools::{
+    multizip,
+    EitherOrBoth,
+    iproduct,
+    izip,
+};
+use itertools::free::{
+    cloned,
+    enumerate,
+    multipeek,
+    put_back,
+    put_back_n,
+    rciter,
+    zip,
+    zip_eq,
+};
+
+use rand::Rng;
+use rand::seq::SliceRandom;
+use quickcheck::TestResult;
+
+/// Trait for size hint modifier types
+trait HintKind: Copy + Send + qc::Arbitrary {
+    fn loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>);
+}
+
+/// Exact size hint variant that leaves hints unchanged
+#[derive(Clone, Copy, Debug)]
+struct Exact {}
+
+impl HintKind for Exact {
+    fn loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>) {
+        org_hint
+    }
+}
+
+impl qc::Arbitrary for Exact {
+    fn arbitrary<G: qc::Gen>(_: &mut G) -> Self {
+        Exact {}
+    }
+}
+
+/// Inexact size hint variant to simulate imprecise (but valid) size hints
+///
+/// Will always decrease the lower bound and increase the upper bound
+/// of the size hint by set amounts.
+#[derive(Clone, Copy, Debug)]
+struct Inexact {
+    underestimate: usize,
+    overestimate: usize,
+}
+
+impl HintKind for Inexact {
+    fn loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>) {
+        let (org_lower, org_upper) = org_hint;
+        (org_lower.saturating_sub(self.underestimate),
+         org_upper.and_then(move |x| x.checked_add(self.overestimate)))
+    }
+}
+
+impl qc::Arbitrary for Inexact {
+    fn arbitrary<G: qc::Gen>(g: &mut G) -> Self {
+        let ue_value = usize::arbitrary(g);
+        let oe_value = usize::arbitrary(g);
+        // Compensate for quickcheck using extreme values too rarely
+        let ue_choices = &[0, ue_value, usize::max_value()];
+        let oe_choices = &[0, oe_value, usize::max_value()];
+        Inexact {
+            underestimate: *ue_choices.choose(g).unwrap(),
+            overestimate: *oe_choices.choose(g).unwrap(),
+        }
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item=Self>> {
+        let underestimate_value = self.underestimate;
+        let overestimate_value = self.overestimate;
+        Box::new(
+            underestimate_value.shrink().flat_map(move |ue_value|
+                overestimate_value.shrink().map(move |oe_value|
+                    Inexact {
+                        underestimate: ue_value,
+                        overestimate: oe_value,
+                    }
+                )
+            )
+        )
+    }
+}
+
+/// Our base iterator that we can impl Arbitrary for
+///
+/// By default we'll return inexact bounds estimates for size_hint
+/// to make tests harder to pass.
+///
+/// NOTE: Iter is tricky and is not fused, to help catch bugs.
+/// At the end it will return None once, then return Some(0),
+/// then return None again.
+#[derive(Clone, Debug)]
+struct Iter<T, SK: HintKind = Inexact> {
+    iterator: Range<T>,
+    // fuse/done flag
+    fuse_flag: i32,
+    hint_kind: SK,
+}
+
+impl<T, HK> Iter<T, HK> where HK: HintKind
+{
+    fn new(it: Range<T>, hint_kind: HK) -> Self {
+        Iter {
+            iterator: it,
+            fuse_flag: 0,
+            hint_kind,
+        }
+    }
+}
+
+impl<T, HK> Iterator for Iter<T, HK>
+    where Range<T>: Iterator,
+          <Range<T> as Iterator>::Item: Default,
+          HK: HintKind,
+{
+    type Item = <Range<T> as Iterator>::Item;
+
+    fn next(&mut self) -> Option<Self::Item>
+    {
+        let elt = self.iterator.next();
+        if elt.is_none() {
+            self.fuse_flag += 1;
+            // check fuse flag
+            if self.fuse_flag == 2 {
+                return Some(Default::default())
+            }
+        }
+        elt
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>)
+    {
+        let org_hint = self.iterator.size_hint();
+        self.hint_kind.loosen_bounds(org_hint)
+    }
+}
+
+impl<T, HK> DoubleEndedIterator for Iter<T, HK>
+    where Range<T>: DoubleEndedIterator,
+          <Range<T> as Iterator>::Item: Default,
+          HK: HintKind
+{
+    fn next_back(&mut self) -> Option<Self::Item> { self.iterator.next_back() }
+}
+
+impl<T> ExactSizeIterator for Iter<T, Exact> where Range<T>: ExactSizeIterator,
+    <Range<T> as Iterator>::Item: Default,
+{ }
+
+impl<T, HK> qc::Arbitrary for Iter<T, HK>
+    where T: qc::Arbitrary,
+          HK: HintKind,
+{
+    fn arbitrary<G: qc::Gen>(g: &mut G) -> Self
+    {
+        Iter::new(T::arbitrary(g)..T::arbitrary(g), HK::arbitrary(g))
+    }
+
+    fn shrink(&self) -> Box<dyn Iterator<Item=Iter<T, HK>>>
+    {
+        let r = self.iterator.clone();
+        let hint_kind = self.hint_kind;
+        Box::new(
+            r.start.shrink().flat_map(move |a|
+                r.end.shrink().map(move |b|
+                    Iter::new(a.clone()..b, hint_kind)
+                )
+            )
+        )
+    }
+}
+
+/// A meta-iterator which yields `Iter<i32>`s whose start/endpoints are
+/// increased or decreased linearly on each iteration.
+#[derive(Clone, Debug)]
+struct ShiftRange<HK = Inexact> {
+    range_start: i32,
+    range_end: i32,
+    start_step: i32,
+    end_step: i32,
+    iter_count: u32,
+    hint_kind: HK,
+}
+
+impl<HK> Iterator for ShiftRange<HK> where HK: HintKind {
+    type Item = Iter<i32, HK>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if self.iter_count == 0 {
+            return None;
+        }
+
+        let iter = Iter::new(self.range_start..self.range_end, self.hint_kind);
+
+        self.range_start += self.start_step;
+        self.range_end += self.end_step;
+        self.iter_count -= 1;
+
+        Some(iter)
+    }
+}
+
+impl ExactSizeIterator for ShiftRange<Exact> { }
+
+impl<HK> qc::Arbitrary for ShiftRange<HK>
+    where HK: HintKind
+{
+    fn arbitrary<G: qc::Gen>(g: &mut G) -> Self {
+        const MAX_STARTING_RANGE_DIFF: i32 = 32;
+        const MAX_STEP_MODULO: i32 = 8;
+        const MAX_ITER_COUNT: u32 = 3;
+
+        let range_start = qc::Arbitrary::arbitrary(g);
+        let range_end = range_start + g.gen_range(0, MAX_STARTING_RANGE_DIFF + 1);
+        let start_step = g.gen_range(-MAX_STEP_MODULO, MAX_STEP_MODULO + 1);
+        let end_step = g.gen_range(-MAX_STEP_MODULO, MAX_STEP_MODULO + 1);
+        let iter_count = g.gen_range(0, MAX_ITER_COUNT + 1);
+        let hint_kind = qc::Arbitrary::arbitrary(g);
+
+        ShiftRange {
+            range_start,
+            range_end,
+            start_step,
+            end_step,
+            iter_count,
+            hint_kind,
+        }
+    }
+}
+
+fn correct_count<I, F>(get_it: F) -> bool
+where
+    I: Iterator,
+    F: Fn() -> I
+{
+    let mut counts = vec![get_it().count()];
+
+    'outer: loop {
+        let mut it = get_it();
+
+        for _ in 0..(counts.len() - 1) {
+            if let None = it.next() {
+                panic!("Iterator shouldn't be finished, may not be deterministic");
+            }
+        }
+
+        if let None = it.next() {
+            break 'outer;
+        }
+
+        counts.push(it.count());
+    }
+
+    let total_actual_count = counts.len() - 1;
+
+    for (i, returned_count) in counts.into_iter().enumerate() {
+        let actual_count = total_actual_count - i;
+        if actual_count != returned_count {
+            println!("Total iterations: {} True count: {} returned count: {}", i, actual_count, returned_count);
+
+            return false;
+        }
+    }
+
+    true
+}
+
+fn correct_size_hint<I: Iterator>(mut it: I) -> bool {
+    // record size hint at each iteration
+    let initial_hint = it.size_hint();
+    let mut hints = Vec::with_capacity(initial_hint.0 + 1);
+    hints.push(initial_hint);
+    while let Some(_) = it.next() {
+        hints.push(it.size_hint())
+    }
+
+    let mut true_count = hints.len(); // start off +1 too much
+
+    // check all the size hints
+    for &(low, hi) in &hints {
+        true_count -= 1;
+        if low > true_count ||
+            (hi.is_some() && hi.unwrap() < true_count)
+        {
+            println!("True size: {:?}, size hint: {:?}", true_count, (low, hi));
+            //println!("All hints: {:?}", hints);
+            return false
+        }
+    }
+    true
+}
+
+fn exact_size<I: ExactSizeIterator>(mut it: I) -> bool {
+    // check every iteration
+    let (mut low, mut hi) = it.size_hint();
+    if Some(low) != hi { return false; }
+    while let Some(_) = it.next() {
+        let (xlow, xhi) = it.size_hint();
+        if low != xlow + 1 { return false; }
+        low = xlow;
+        hi = xhi;
+        if Some(low) != hi { return false; }
+    }
+    let (low, hi) = it.size_hint();
+    low == 0 && hi == Some(0)
+}
+
+// Exact size for this case, without ExactSizeIterator
+fn exact_size_for_this<I: Iterator>(mut it: I) -> bool {
+    // check every iteration
+    let (mut low, mut hi) = it.size_hint();
+    if Some(low) != hi { return false; }
+    while let Some(_) = it.next() {
+        let (xlow, xhi) = it.size_hint();
+        if low != xlow + 1 { return false; }
+        low = xlow;
+        hi = xhi;
+        if Some(low) != hi { return false; }
+    }
+    let (low, hi) = it.size_hint();
+    low == 0 && hi == Some(0)
+}
+
+/*
+ * NOTE: Range<i8> is broken!
+ * (all signed ranges are)
+#[quickcheck]
+fn size_range_i8(a: Iter<i8>) -> bool {
+    exact_size(a)
+}
+
+#[quickcheck]
+fn size_range_i16(a: Iter<i16>) -> bool {
+    exact_size(a)
+}
+
+#[quickcheck]
+fn size_range_u8(a: Iter<u8>) -> bool {
+    exact_size(a)
+}
+ */
+
+macro_rules! quickcheck {
+    // accept several property function definitions
+    // The property functions can use pattern matching and `mut` as usual
+    // in the function arguments, but the functions can not be generic.
+    {$($(#$attr:tt)* fn $fn_name:ident($($arg:tt)*) -> $ret:ty { $($code:tt)* })*} => (
+        $(
+            #[test]
+            $(#$attr)*
+            fn $fn_name() {
+                fn prop($($arg)*) -> $ret {
+                    $($code)*
+                }
+                ::quickcheck::quickcheck(quickcheck!(@fn prop [] $($arg)*));
+            }
+        )*
+    );
+    // parse argument list (with patterns allowed) into prop as fn(_, _) -> _
+    (@fn $f:ident [$($t:tt)*]) => {
+        $f as fn($($t),*) -> _
+    };
+    (@fn $f:ident [$($p:tt)*] : $($tail:tt)*) => {
+        quickcheck!(@fn $f [$($p)* _] $($tail)*)
+    };
+    (@fn $f:ident [$($p:tt)*] $t:tt $($tail:tt)*) => {
+        quickcheck!(@fn $f [$($p)*] $($tail)*)
+    };
+}
+
+quickcheck! {
+
+    fn size_product(a: Iter<u16>, b: Iter<u16>) -> bool {
+        correct_size_hint(a.cartesian_product(b))
+    }
+    fn size_product3(a: Iter<u16>, b: Iter<u16>, c: Iter<u16>) -> bool {
+        correct_size_hint(iproduct!(a, b, c))
+    }
+
+    fn correct_cartesian_product3(a: Iter<u16>, b: Iter<u16>, c: Iter<u16>,
+                                  take_manual: usize) -> ()
+    {
+        // test correctness of iproduct through regular iteration (take)
+        // and through fold.
+        let ac = a.clone();
+        let br = &b.clone();
+        let cr = &c.clone();
+        let answer: Vec<_> = ac.flat_map(move |ea| br.clone().flat_map(move |eb| cr.clone().map(move |ec| (ea, eb, ec)))).collect();
+        let mut product_iter = iproduct!(a, b, c);
+        let mut actual = Vec::new();
+
+        actual.extend((&mut product_iter).take(take_manual));
+        if actual.len() == take_manual {
+            product_iter.fold((), |(), elt| actual.push(elt));
+        }
+        assert_eq!(answer, actual);
+    }
+
+    fn size_multi_product(a: ShiftRange) -> bool {
+        correct_size_hint(a.multi_cartesian_product())
+    }
+    fn correct_multi_product3(a: ShiftRange, take_manual: usize) -> () {
+        // Fix no. of iterators at 3
+        let a = ShiftRange { iter_count: 3, ..a };
+
+        // test correctness of MultiProduct through regular iteration (take)
+        // and through fold.
+        let mut iters = a.clone();
+        let i0 = iters.next().unwrap();
+        let i1r = &iters.next().unwrap();
+        let i2r = &iters.next().unwrap();
+        let answer: Vec<_> = i0.flat_map(move |ei0| i1r.clone().flat_map(move |ei1| i2r.clone().map(move |ei2| vec![ei0, ei1, ei2]))).collect();
+        let mut multi_product = a.clone().multi_cartesian_product();
+        let mut actual = Vec::new();
+
+        actual.extend((&mut multi_product).take(take_manual));
+        if actual.len() == take_manual {
+            multi_product.fold((), |(), elt| actual.push(elt));
+        }
+        assert_eq!(answer, actual);
+
+        assert_eq!(answer.into_iter().last(), a.clone().multi_cartesian_product().last());
+    }
+
+    #[allow(deprecated)]
+    fn size_step(a: Iter<i16, Exact>, s: usize) -> bool {
+        let mut s = s;
+        if s == 0 {
+            s += 1; // never zero
+        }
+        let filt = a.clone().dedup();
+        correct_size_hint(filt.step(s)) &&
+            exact_size(a.step(s))
+    }
+
+    #[allow(deprecated)]
+    fn equal_step(a: Iter<i16>, s: usize) -> bool {
+        let mut s = s;
+        if s == 0 {
+            s += 1; // never zero
+        }
+        let mut i = 0;
+        itertools::equal(a.clone().step(s), a.filter(|_| {
+            let keep = i % s == 0;
+            i += 1;
+            keep
+        }))
+    }
+
+    #[allow(deprecated)]
+    fn equal_step_vec(a: Vec<i16>, s: usize) -> bool {
+        let mut s = s;
+        if s == 0 {
+            s += 1; // never zero
+        }
+        let mut i = 0;
+        itertools::equal(a.iter().step(s), a.iter().filter(|_| {
+            let keep = i % s == 0;
+            i += 1;
+            keep
+        }))
+    }
+
+    fn size_multipeek(a: Iter<u16, Exact>, s: u8) -> bool {
+        let mut it = multipeek(a);
+        // peek a few times
+        for _ in 0..s {
+            it.peek();
+        }
+        exact_size(it)
+    }
+
+    fn equal_merge(a: Vec<i16>, b: Vec<i16>) -> bool {
+        let mut sa = a.clone();
+        let mut sb = b.clone();
+        sa.sort();
+        sb.sort();
+        let mut merged = sa.clone();
+        merged.extend(sb.iter().cloned());
+        merged.sort();
+        itertools::equal(&merged, sa.iter().merge(&sb))
+    }
+    fn size_merge(a: Iter<u16>, b: Iter<u16>) -> bool {
+        correct_size_hint(a.merge(b))
+    }
+    fn size_zip(a: Iter<i16, Exact>, b: Iter<i16, Exact>, c: Iter<i16, Exact>) -> bool {
+        let filt = a.clone().dedup();
+        correct_size_hint(multizip((filt, b.clone(), c.clone()))) &&
+            exact_size(multizip((a, b, c)))
+    }
+    fn size_zip_rc(a: Iter<i16>, b: Iter<i16>) -> bool {
+        let rc = rciter(a.clone());
+        correct_size_hint(multizip((&rc, &rc, b)))
+    }
+
+    fn size_zip_macro(a: Iter<i16, Exact>, b: Iter<i16, Exact>, c: Iter<i16, Exact>) -> bool {
+        let filt = a.clone().dedup();
+        correct_size_hint(izip!(filt, b.clone(), c.clone())) &&
+            exact_size(izip!(a, b, c))
+    }
+    fn equal_kmerge(a: Vec<i16>, b: Vec<i16>, c: Vec<i16>) -> bool {
+        use itertools::free::kmerge;
+        let mut sa = a.clone();
+        let mut sb = b.clone();
+        let mut sc = c.clone();
+        sa.sort();
+        sb.sort();
+        sc.sort();
+        let mut merged = sa.clone();
+        merged.extend(sb.iter().cloned());
+        merged.extend(sc.iter().cloned());
+        merged.sort();
+        itertools::equal(merged.into_iter(), kmerge(vec![sa, sb, sc]))
+    }
+
+    // Any number of input iterators
+    fn equal_kmerge_2(mut inputs: Vec<Vec<i16>>) -> bool {
+        use itertools::free::kmerge;
+        // sort the inputs
+        for input in &mut inputs {
+            input.sort();
+        }
+        let mut merged = inputs.concat();
+        merged.sort();
+        itertools::equal(merged.into_iter(), kmerge(inputs))
+    }
+
+    // Any number of input iterators
+    fn equal_kmerge_by_ge(mut inputs: Vec<Vec<i16>>) -> bool {
+        // sort the inputs
+        for input in &mut inputs {
+            input.sort();
+            input.reverse();
+        }
+        let mut merged = inputs.concat();
+        merged.sort();
+        merged.reverse();
+        itertools::equal(merged.into_iter(),
+                         inputs.into_iter().kmerge_by(|x, y| x >= y))
+    }
+
+    // Any number of input iterators
+    fn equal_kmerge_by_lt(mut inputs: Vec<Vec<i16>>) -> bool {
+        // sort the inputs
+        for input in &mut inputs {
+            input.sort();
+        }
+        let mut merged = inputs.concat();
+        merged.sort();
+        itertools::equal(merged.into_iter(),
+                         inputs.into_iter().kmerge_by(|x, y| x < y))
+    }
+
+    // Any number of input iterators
+    fn equal_kmerge_by_le(mut inputs: Vec<Vec<i16>>) -> bool {
+        // sort the inputs
+        for input in &mut inputs {
+            input.sort();
+        }
+        let mut merged = inputs.concat();
+        merged.sort();
+        itertools::equal(merged.into_iter(),
+                         inputs.into_iter().kmerge_by(|x, y| x <= y))
+    }
+    fn size_kmerge(a: Iter<i16>, b: Iter<i16>, c: Iter<i16>) -> bool {
+        use itertools::free::kmerge;
+        correct_size_hint(kmerge(vec![a, b, c]))
+    }
+    fn equal_zip_eq(a: Vec<i32>, b: Vec<i32>) -> bool {
+        let len = std::cmp::min(a.len(), b.len());
+        let a = &a[..len];
+        let b = &b[..len];
+        itertools::equal(zip_eq(a, b), zip(a, b))
+    }
+    fn size_zip_longest(a: Iter<i16, Exact>, b: Iter<i16, Exact>) -> bool {
+        let filt = a.clone().dedup();
+        let filt2 = b.clone().dedup();
+        correct_size_hint(filt.zip_longest(b.clone())) &&
+        correct_size_hint(a.clone().zip_longest(filt2)) &&
+            exact_size(a.zip_longest(b))
+    }
+    fn size_2_zip_longest(a: Iter<i16>, b: Iter<i16>) -> bool {
+        let it = a.clone().zip_longest(b.clone());
+        let jt = a.clone().zip_longest(b.clone());
+        itertools::equal(a.clone(),
+                         it.filter_map(|elt| match elt {
+                             EitherOrBoth::Both(x, _) => Some(x),
+                             EitherOrBoth::Left(x) => Some(x),
+                             _ => None,
+                         }
+                         ))
+            &&
+        itertools::equal(b.clone(),
+                         jt.filter_map(|elt| match elt {
+                             EitherOrBoth::Both(_, y) => Some(y),
+                             EitherOrBoth::Right(y) => Some(y),
+                             _ => None,
+                         }
+                         ))
+    }
+    fn size_interleave(a: Iter<i16>, b: Iter<i16>) -> bool {
+        correct_size_hint(a.interleave(b))
+    }
+    fn exact_interleave(a: Iter<i16, Exact>, b: Iter<i16, Exact>) -> bool {
+        exact_size_for_this(a.interleave(b))
+    }
+    fn size_interleave_shortest(a: Iter<i16>, b: Iter<i16>) -> bool {
+        correct_size_hint(a.interleave_shortest(b))
+    }
+    fn exact_interleave_shortest(a: Vec<()>, b: Vec<()>) -> bool {
+        exact_size_for_this(a.iter().interleave_shortest(&b))
+    }
+    fn size_intersperse(a: Iter<i16>, x: i16) -> bool {
+        correct_size_hint(a.intersperse(x))
+    }
+    fn equal_intersperse(a: Vec<i32>, x: i32) -> bool {
+        let mut inter = false;
+        let mut i = 0;
+        for elt in a.iter().cloned().intersperse(x) {
+            if inter {
+                if elt != x { return false }
+            } else {
+                if elt != a[i] { return false }
+                i += 1;
+            }
+            inter = !inter;
+        }
+        true
+    }
+
+    fn equal_combinations_2(a: Vec<u8>) -> bool {
+        let mut v = Vec::new();
+        for (i, x) in enumerate(&a) {
+            for y in &a[i + 1..] {
+                v.push((x, y));
+            }
+        }
+        itertools::equal(a.iter().tuple_combinations::<(_, _)>(), v)
+    }
+
+    fn collect_tuple_matches_size(a: Iter<i16>) -> bool {
+        let size = a.clone().count();
+        a.collect_tuple::<(_, _, _)>().is_some() == (size == 3)
+    }
+
+    fn correct_permutations(vals: HashSet<i32>, k: usize) -> () {
+        // Test permutations only on iterators of distinct integers, to prevent
+        // false positives.
+
+        const MAX_N: usize = 5;
+
+        let n = min(vals.len(), MAX_N);
+        let vals: HashSet<i32> = vals.into_iter().take(n).collect();
+
+        let perms = vals.iter().permutations(k);
+
+        let mut actual = HashSet::new();
+
+        for perm in perms {
+            assert_eq!(perm.len(), k);
+
+            let all_items_valid = perm.iter().all(|p| vals.contains(p));
+            assert!(all_items_valid, "perm contains value not from input: {:?}", perm);
+
+            // Check that all perm items are distinct
+            let distinct_len = {
+                let perm_set: HashSet<_> = perm.iter().collect();
+                perm_set.len()
+            };
+            assert_eq!(perm.len(), distinct_len);
+
+            // Check that the perm is new
+            assert!(actual.insert(perm.clone()), "perm already encountered: {:?}", perm);
+        }
+    }
+
+    fn permutations_lexic_order(a: usize, b: usize) -> () {
+        let a = a % 6;
+        let b = b % 6;
+
+        let n = max(a, b);
+        let k = min (a, b);
+
+        let expected_first: Vec<usize> = (0..k).collect();
+        let expected_last: Vec<usize> = ((n - k)..n).rev().collect();
+
+        let mut perms = (0..n).permutations(k);
+
+        let mut curr_perm = match perms.next() {
+            Some(p) => p,
+            None => { return; }
+        };
+
+        assert_eq!(expected_first, curr_perm);
+
+        while let Some(next_perm) = perms.next() {
+            assert!(
+                next_perm > curr_perm,
+                "next perm isn't greater-than current; next_perm={:?} curr_perm={:?} n={}",
+                next_perm, curr_perm, n
+            );
+
+            curr_perm = next_perm;
+        }
+
+        assert_eq!(expected_last, curr_perm);
+
+    }
+
+    fn permutations_count(n: usize, k: usize) -> bool {
+        let n = n % 6;
+
+        correct_count(|| (0..n).permutations(k))
+    }
+
+    fn permutations_size(a: Iter<i32>, k: usize) -> bool {
+        correct_size_hint(a.take(5).permutations(k))
+    }
+
+    fn permutations_k0_yields_once(n: usize) -> () {
+        let k = 0;
+        let expected: Vec<Vec<usize>> = vec![vec![]];
+        let actual = (0..n).permutations(k).collect_vec();
+
+        assert_eq!(expected, actual);
+    }
+}
+
+quickcheck! {
+    fn equal_dedup(a: Vec<i32>) -> bool {
+        let mut b = a.clone();
+        b.dedup();
+        itertools::equal(&b, a.iter().dedup())
+    }
+}
+
+quickcheck! {
+    fn equal_dedup_by(a: Vec<(i32, i32)>) -> bool {
+        let mut b = a.clone();
+        b.dedup_by(|x, y| x.0==y.0);
+        itertools::equal(&b, a.iter().dedup_by(|x, y| x.0==y.0))
+    }
+}
+
+quickcheck! {
+    fn size_dedup(a: Vec<i32>) -> bool {
+        correct_size_hint(a.iter().dedup())
+    }
+}
+
+quickcheck! {
+    fn size_dedup_by(a: Vec<(i32, i32)>) -> bool {
+        correct_size_hint(a.iter().dedup_by(|x, y| x.0==y.0))
+    }
+}
+
+quickcheck! {
+    fn exact_repeatn((n, x): (usize, i32)) -> bool {
+        let it = itertools::repeat_n(x, n);
+        exact_size(it)
+    }
+}
+
+quickcheck! {
+    fn size_put_back(a: Vec<u8>, x: Option<u8>) -> bool {
+        let mut it = put_back(a.into_iter());
+        match x {
+            Some(t) => it.put_back(t),
+            None => {}
+        }
+        correct_size_hint(it)
+    }
+}
+
+quickcheck! {
+    fn size_put_backn(a: Vec<u8>, b: Vec<u8>) -> bool {
+        let mut it = put_back_n(a.into_iter());
+        for elt in b {
+            it.put_back(elt)
+        }
+        correct_size_hint(it)
+    }
+}
+
+quickcheck! {
+    fn size_tee(a: Vec<u8>) -> bool {
+        let (mut t1, mut t2) = a.iter().tee();
+        t1.next();
+        t1.next();
+        t2.next();
+        exact_size(t1) && exact_size(t2)
+    }
+}
+
+quickcheck! {
+    fn size_tee_2(a: Vec<u8>) -> bool {
+        let (mut t1, mut t2) = a.iter().dedup().tee();
+        t1.next();
+        t1.next();
+        t2.next();
+        correct_size_hint(t1) && correct_size_hint(t2)
+    }
+}
+
+quickcheck! {
+    fn size_take_while_ref(a: Vec<u8>, stop: u8) -> bool {
+        correct_size_hint(a.iter().take_while_ref(|x| **x != stop))
+    }
+}
+
+quickcheck! {
+    fn equal_partition(a: Vec<i32>) -> bool {
+        let mut a = a;
+        let mut ap = a.clone();
+        let split_index = itertools::partition(&mut ap, |x| *x >= 0);
+        let parted = (0..split_index).all(|i| ap[i] >= 0) &&
+            (split_index..a.len()).all(|i| ap[i] < 0);
+
+        a.sort();
+        ap.sort();
+        parted && (a == ap)
+    }
+}
+
+quickcheck! {
+    fn size_combinations(it: Iter<i16>) -> bool {
+        correct_size_hint(it.tuple_combinations::<(_, _)>())
+    }
+}
+
+quickcheck! {
+    fn equal_combinations(it: Iter<i16>) -> bool {
+        let values = it.clone().collect_vec();
+        let mut cmb = it.tuple_combinations();
+        for i in 0..values.len() {
+            for j in i+1..values.len() {
+                let pair = (values[i], values[j]);
+                if pair != cmb.next().unwrap() {
+                    return false;
+                }
+            }
+        }
+        cmb.next() == None
+    }
+}
+
+quickcheck! {
+    fn size_pad_tail(it: Iter<i8>, pad: u8) -> bool {
+        correct_size_hint(it.clone().pad_using(pad as usize, |_| 0)) &&
+            correct_size_hint(it.dropping(1).rev().pad_using(pad as usize, |_| 0))
+    }
+}
+
+quickcheck! {
+    fn size_pad_tail2(it: Iter<i8, Exact>, pad: u8) -> bool {
+        exact_size(it.pad_using(pad as usize, |_| 0))
+    }
+}
+
+quickcheck! {
+    fn size_unique(it: Iter<i8>) -> bool {
+        correct_size_hint(it.unique())
+    }
+
+    fn count_unique(it: Vec<i8>, take_first: u8) -> () {
+        let answer = {
+            let mut v = it.clone();
+            v.sort(); v.dedup();
+            v.len()
+        };
+        let mut iter = cloned(&it).unique();
+        let first_count = (&mut iter).take(take_first as usize).count();
+        let rest_count = iter.count();
+        assert_eq!(answer, first_count + rest_count);
+    }
+}
+
+quickcheck! {
+    fn fuzz_group_by_lazy_1(it: Iter<u8>) -> bool {
+        let jt = it.clone();
+        let groups = it.group_by(|k| *k);
+        let res = itertools::equal(jt, groups.into_iter().flat_map(|(_, x)| x));
+        res
+    }
+}
+
+quickcheck! {
+    fn fuzz_group_by_lazy_2(data: Vec<u8>) -> bool {
+        let groups = data.iter().group_by(|k| *k / 10);
+        let res = itertools::equal(data.iter(), groups.into_iter().flat_map(|(_, x)| x));
+        res
+    }
+}
+
+quickcheck! {
+    fn fuzz_group_by_lazy_3(data: Vec<u8>) -> bool {
+        let grouper = data.iter().group_by(|k| *k / 10);
+        let groups = grouper.into_iter().collect_vec();
+        let res = itertools::equal(data.iter(), groups.into_iter().flat_map(|(_, x)| x));
+        res
+    }
+}
+
+quickcheck! {
+    fn fuzz_group_by_lazy_duo(data: Vec<u8>, order: Vec<(bool, bool)>) -> bool {
+        let grouper = data.iter().group_by(|k| *k / 3);
+        let mut groups1 = grouper.into_iter();
+        let mut groups2 = grouper.into_iter();
+        let mut elts = Vec::<&u8>::new();
+        let mut old_groups = Vec::new();
+
+        let tup1 = |(_, b)| b;
+        for &(ord, consume_now) in &order {
+            let iter = &mut [&mut groups1, &mut groups2][ord as usize];
+            match iter.next() {
+                Some((_, gr)) => if consume_now {
+                    for og in old_groups.drain(..) {
+                        elts.extend(og);
+                    }
+                    elts.extend(gr);
+                } else {
+                    old_groups.push(gr);
+                },
+                None => break,
+            }
+        }
+        for og in old_groups.drain(..) {
+            elts.extend(og);
+        }
+        for gr in groups1.map(&tup1) { elts.extend(gr); }
+        for gr in groups2.map(&tup1) { elts.extend(gr); }
+        itertools::assert_equal(&data, elts);
+        true
+    }
+}
+
+quickcheck! {
+    fn equal_chunks_lazy(a: Vec<u8>, size: u8) -> bool {
+        let mut size = size;
+        if size == 0 {
+            size += 1;
+        }
+        let chunks = a.iter().chunks(size as usize);
+        let it = a.chunks(size as usize);
+        for (a, b) in chunks.into_iter().zip(it) {
+            if !itertools::equal(a, b) {
+                return false;
+            }
+        }
+        true
+    }
+}
+
+quickcheck! {
+    fn equal_tuple_windows_1(a: Vec<u8>) -> bool {
+        let x = a.windows(1).map(|s| (&s[0], ));
+        let y = a.iter().tuple_windows::<(_,)>();
+        itertools::equal(x, y)
+    }
+
+    fn equal_tuple_windows_2(a: Vec<u8>) -> bool {
+        let x = a.windows(2).map(|s| (&s[0], &s[1]));
+        let y = a.iter().tuple_windows::<(_, _)>();
+        itertools::equal(x, y)
+    }
+
+    fn equal_tuple_windows_3(a: Vec<u8>) -> bool {
+        let x = a.windows(3).map(|s| (&s[0], &s[1], &s[2]));
+        let y = a.iter().tuple_windows::<(_, _, _)>();
+        itertools::equal(x, y)
+    }
+
+    fn equal_tuple_windows_4(a: Vec<u8>) -> bool {
+        let x = a.windows(4).map(|s| (&s[0], &s[1], &s[2], &s[3]));
+        let y = a.iter().tuple_windows::<(_, _, _, _)>();
+        itertools::equal(x, y)
+    }
+
+    fn equal_tuples_1(a: Vec<u8>) -> bool {
+        let x = a.chunks(1).map(|s| (&s[0], ));
+        let y = a.iter().tuples::<(_,)>();
+        itertools::equal(x, y)
+    }
+
+    fn equal_tuples_2(a: Vec<u8>) -> bool {
+        let x = a.chunks(2).filter(|s| s.len() == 2).map(|s| (&s[0], &s[1]));
+        let y = a.iter().tuples::<(_, _)>();
+        itertools::equal(x, y)
+    }
+
+    fn equal_tuples_3(a: Vec<u8>) -> bool {
+        let x = a.chunks(3).filter(|s| s.len() == 3).map(|s| (&s[0], &s[1], &s[2]));
+        let y = a.iter().tuples::<(_, _, _)>();
+        itertools::equal(x, y)
+    }
+
+    fn equal_tuples_4(a: Vec<u8>) -> bool {
+        let x = a.chunks(4).filter(|s| s.len() == 4).map(|s| (&s[0], &s[1], &s[2], &s[3]));
+        let y = a.iter().tuples::<(_, _, _, _)>();
+        itertools::equal(x, y)
+    }
+
+    fn exact_tuple_buffer(a: Vec<u8>) -> bool {
+        let mut iter = a.iter().tuples::<(_, _, _, _)>();
+        (&mut iter).last();
+        let buffer = iter.into_buffer();
+        assert_eq!(buffer.len(), a.len() % 4);
+        exact_size(buffer)
+    }
+}
+
+// with_position
+quickcheck! {
+    fn with_position_exact_size_1(a: Vec<u8>) -> bool {
+        exact_size_for_this(a.iter().with_position())
+    }
+    fn with_position_exact_size_2(a: Iter<u8, Exact>) -> bool {
+        exact_size_for_this(a.with_position())
+    }
+}
+
+quickcheck! {
+    fn correct_group_map_modulo_key(a: Vec<u8>, modulo: u8) -> () {
+        let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
+        let count = a.len();
+        let lookup = a.into_iter().map(|i| (i % modulo, i)).into_group_map();
+
+        assert_eq!(lookup.values().flat_map(|vals| vals.iter()).count(), count);
+
+        for (&key, vals) in lookup.iter() {
+            assert!(vals.iter().all(|&val| val % modulo == key));
+        }
+    }
+}
+
+/// A peculiar type: Equality compares both tuple items, but ordering only the
+/// first item.  This is so we can check the stability property easily.
+#[derive(Clone, Debug, PartialEq, Eq)]
+struct Val(u32, u32);
+
+impl PartialOrd<Val> for Val {
+    fn partial_cmp(&self, other: &Val) -> Option<Ordering> {
+        self.0.partial_cmp(&other.0)
+    }
+}
+
+impl Ord for Val {
+    fn cmp(&self, other: &Val) -> Ordering {
+        self.0.cmp(&other.0)
+    }
+}
+
+impl qc::Arbitrary for Val {
+    fn arbitrary<G: qc::Gen>(g: &mut G) -> Self {
+        let (x, y) = <(u32, u32)>::arbitrary(g);
+        Val(x, y)
+    }
+    fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
+        Box::new((self.0, self.1).shrink().map(|(x, y)| Val(x, y)))
+    }
+}
+
+quickcheck! {
+    fn minmax(a: Vec<Val>) -> bool {
+        use itertools::MinMaxResult;
+
+
+        let minmax = a.iter().minmax();
+        let expected = match a.len() {
+            0 => MinMaxResult::NoElements,
+            1 => MinMaxResult::OneElement(&a[0]),
+            _ => MinMaxResult::MinMax(a.iter().min().unwrap(),
+                                      a.iter().max().unwrap()),
+        };
+        minmax == expected
+    }
+}
+
+quickcheck! {
+    fn minmax_f64(a: Vec<f64>) -> TestResult {
+        use itertools::MinMaxResult;
+
+        if a.iter().any(|x| x.is_nan()) {
+            return TestResult::discard();
+        }
+
+        let min = cloned(&a).fold1(f64::min);
+        let max = cloned(&a).fold1(f64::max);
+
+        let minmax = cloned(&a).minmax();
+        let expected = match a.len() {
+            0 => MinMaxResult::NoElements,
+            1 => MinMaxResult::OneElement(min.unwrap()),
+            _ => MinMaxResult::MinMax(min.unwrap(), max.unwrap()),
+        };
+        TestResult::from_bool(minmax == expected)
+    }
+}
+
+quickcheck! {
+    #[allow(deprecated)]
+    fn tree_fold1_f64(mut a: Vec<f64>) -> TestResult {
+        fn collapse_adjacent<F>(x: Vec<f64>, mut f: F) -> Vec<f64>
+            where F: FnMut(f64, f64) -> f64
+        {
+            let mut out = Vec::new();
+            for i in (0..x.len()).step(2) {
+                if i == x.len()-1 {
+                    out.push(x[i])
+                } else {
+                    out.push(f(x[i], x[i+1]));
+                }
+            }
+            out
+        }
+
+        if a.iter().any(|x| x.is_nan()) {
+            return TestResult::discard();
+        }
+
+        let actual = a.iter().cloned().tree_fold1(f64::atan2);
+
+        while a.len() > 1 {
+            a = collapse_adjacent(a, f64::atan2);
+        }
+        let expected = a.pop();
+
+        TestResult::from_bool(actual == expected)
+    }
+}
+
+quickcheck! {
+    fn exactly_one_i32(a: Vec<i32>) -> TestResult {
+        let ret = a.iter().cloned().exactly_one();
+        match a.len() {
+            1 => TestResult::from_bool(ret.unwrap() == a[0]),
+            _ => TestResult::from_bool(ret.unwrap_err().eq(a.iter().cloned())),
+        }
+    }
+}
diff --git a/tests/specializations.rs b/tests/specializations.rs
new file mode 100644
index 0000000..ef51bbe
--- /dev/null
+++ b/tests/specializations.rs
@@ -0,0 +1,149 @@
+use itertools::{EitherOrBoth, Itertools};
+use std::fmt::Debug;
+use std::ops::BitXor;
+use quickcheck::quickcheck;
+
+struct Unspecialized<I>(I);
+impl<I> Iterator for Unspecialized<I>
+where
+    I: Iterator,
+{
+    type Item = I::Item;
+
+    #[inline(always)]
+    fn next(&mut self) -> Option<I::Item> {
+        self.0.next()
+    }
+
+    #[inline(always)]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.0.size_hint()
+    }
+}
+
+fn check_specialized<'a, V, IterItem, Iter, F>(iterator: &Iter, mapper: F)
+where
+    V: Eq + Debug,
+    IterItem: 'a,
+    Iter: Iterator<Item = IterItem> + Clone + 'a,
+    F: Fn(Box<dyn Iterator<Item = IterItem> + 'a>) -> V,
+{
+    assert_eq!(
+        mapper(Box::new(Unspecialized(iterator.clone()))),
+        mapper(Box::new(iterator.clone()))
+    )
+}
+
+fn check_specialized_count_last_nth_sizeh<'a, IterItem, Iter>(
+    it: &Iter,
+    known_expected_size: Option<usize>,
+) where
+    IterItem: 'a + Eq + Debug,
+    Iter: Iterator<Item = IterItem> + Clone + 'a,
+{
+    let size = it.clone().count();
+    if let Some(expected_size) = known_expected_size {
+        assert_eq!(size, expected_size);
+    }
+    check_specialized(it, |i| i.count());
+    check_specialized(it, |i| i.last());
+    for n in 0..size + 2 {
+        check_specialized(it, |mut i| i.nth(n));
+    }
+    let mut it_sh = it.clone();
+    for n in 0..size + 2 {
+        let len = it_sh.clone().count();
+        let (min, max) = it_sh.size_hint();
+        assert_eq!((size - n.min(size)), len);
+        assert!(min <= len);
+        if let Some(max) = max {
+            assert!(len <= max);
+        }
+        it_sh.next();
+    }
+}
+
+fn check_specialized_fold_xor<'a, IterItem, Iter>(it: &Iter)
+where
+    IterItem: 'a
+        + BitXor
+        + Eq
+        + Debug
+        + BitXor<<IterItem as BitXor>::Output, Output = <IterItem as BitXor>::Output>
+        + Clone,
+    <IterItem as BitXor>::Output:
+        BitXor<Output = <IterItem as BitXor>::Output> + Eq + Debug + Clone,
+    Iter: Iterator<Item = IterItem> + Clone + 'a,
+{
+    check_specialized(it, |mut i| {
+        let first = i.next().map(|f| f.clone() ^ (f.clone() ^ f));
+        i.fold(first, |acc, v: IterItem| acc.map(move |a| v ^ a))
+    });
+}
+
+fn put_back_test(test_vec: Vec<i32>, known_expected_size: Option<usize>) {
+    {
+        // Lexical lifetimes support
+        let pb = itertools::put_back(test_vec.iter());
+        check_specialized_count_last_nth_sizeh(&pb, known_expected_size);
+        check_specialized_fold_xor(&pb);
+    }
+
+    let mut pb = itertools::put_back(test_vec.into_iter());
+    pb.put_back(1);
+    check_specialized_count_last_nth_sizeh(&pb, known_expected_size.map(|x| x + 1));
+    check_specialized_fold_xor(&pb)
+}
+
+#[test]
+fn put_back() {
+    put_back_test(vec![7, 4, 1], Some(3));
+}
+
+quickcheck! {
+    fn put_back_qc(test_vec: Vec<i32>) -> () {
+        put_back_test(test_vec, None)
+    }
+}
+
+fn merge_join_by_test(i1: Vec<usize>, i2: Vec<usize>, known_expected_size: Option<usize>) {
+    let i1 = i1.into_iter();
+    let i2 = i2.into_iter();
+    let mjb = i1.clone().merge_join_by(i2.clone(), std::cmp::Ord::cmp);
+    check_specialized_count_last_nth_sizeh(&mjb, known_expected_size);
+    // Rust 1.24 compatibility:
+    fn eob_left_z(eob: EitherOrBoth<usize, usize>) -> usize {
+        eob.left().unwrap_or(0)
+    }
+    fn eob_right_z(eob: EitherOrBoth<usize, usize>) -> usize {
+        eob.left().unwrap_or(0)
+    }
+    fn eob_both_z(eob: EitherOrBoth<usize, usize>) -> usize {
+        let (a, b) = eob.both().unwrap_or((0, 0));
+        assert_eq!(a, b);
+        a
+    }
+    check_specialized_fold_xor(&mjb.clone().map(eob_left_z));
+    check_specialized_fold_xor(&mjb.clone().map(eob_right_z));
+    check_specialized_fold_xor(&mjb.clone().map(eob_both_z));
+
+    // And the other way around
+    let mjb = i2.merge_join_by(i1, std::cmp::Ord::cmp);
+    check_specialized_count_last_nth_sizeh(&mjb, known_expected_size);
+    check_specialized_fold_xor(&mjb.clone().map(eob_left_z));
+    check_specialized_fold_xor(&mjb.clone().map(eob_right_z));
+    check_specialized_fold_xor(&mjb.clone().map(eob_both_z));
+}
+
+#[test]
+fn merge_join_by() {
+    let i1 = vec![1, 3, 5, 7, 8, 9];
+    let i2 = vec![0, 3, 4, 5];
+    merge_join_by_test(i1, i2, Some(8));
+}
+
+quickcheck! {
+    fn merge_join_by_qc(i1: Vec<usize>, i2: Vec<usize>) -> () {
+        merge_join_by_test(i1, i2, None)
+    }
+}
diff --git a/tests/test_core.rs b/tests/test_core.rs
new file mode 100644
index 0000000..5861653
--- /dev/null
+++ b/tests/test_core.rs
@@ -0,0 +1,272 @@
+//! Licensed under the Apache License, Version 2.0
+//! http://www.apache.org/licenses/LICENSE-2.0 or the MIT license
+//! http://opensource.org/licenses/MIT, at your
+//! option. This file may not be copied, modified, or distributed
+//! except according to those terms.
+#![no_std]
+
+use core::iter;
+use itertools as it;
+use crate::it::Itertools;
+use crate::it::interleave;
+use crate::it::multizip;
+use crate::it::free::put_back;
+use crate::it::iproduct;
+use crate::it::izip;
+
+#[test]
+fn product2() {
+    let s = "αβ";
+
+    let mut prod = iproduct!(s.chars(), 0..2);
+    assert!(prod.next() == Some(('α', 0)));
+    assert!(prod.next() == Some(('α', 1)));
+    assert!(prod.next() == Some(('β', 0)));
+    assert!(prod.next() == Some(('β', 1)));
+    assert!(prod.next() == None);
+}
+
+#[test]
+fn product_temporary() {
+    for (_x, _y, _z) in iproduct!(
+        [0, 1, 2].iter().cloned(),
+        [0, 1, 2].iter().cloned(),
+        [0, 1, 2].iter().cloned())
+    {
+        // ok
+    }
+}
+
+
+#[test]
+fn izip_macro() {
+    let mut zip = izip!(2..3);
+    assert!(zip.next() == Some(2));
+    assert!(zip.next().is_none());
+
+    let mut zip = izip!(0..3, 0..2, 0..2i8);
+    for i in 0..2 {
+        assert!((i as usize, i, i as i8) == zip.next().unwrap());
+    }
+    assert!(zip.next().is_none());
+
+    let xs: [isize; 0] = [];
+    let mut zip = izip!(0..3, 0..2, 0..2i8, &xs);
+    assert!(zip.next().is_none());
+}
+
+#[test]
+fn izip2() {
+    let _zip1: iter::Zip<_, _> = izip!(1.., 2..);
+    let _zip2: iter::Zip<_, _> = izip!(1.., 2.., );
+}
+
+#[test]
+fn izip3() {
+    let mut zip: iter::Map<iter::Zip<_, _>, _> = izip!(0..3, 0..2, 0..2i8);
+    for i in 0..2 {
+        assert!((i as usize, i, i as i8) == zip.next().unwrap());
+    }
+    assert!(zip.next().is_none());
+}
+
+#[test]
+fn multizip3() {
+    let mut zip = multizip((0..3, 0..2, 0..2i8));
+    for i in 0..2 {
+        assert!((i as usize, i, i as i8) == zip.next().unwrap());
+    }
+    assert!(zip.next().is_none());
+
+    let xs: [isize; 0] = [];
+    let mut zip = multizip((0..3, 0..2, 0..2i8, xs.iter()));
+    assert!(zip.next().is_none());
+
+    for (_, _, _, _, _) in multizip((0..3, 0..2, xs.iter(), &xs, xs.to_vec())) {
+        /* test compiles */
+    }
+}
+
+#[test]
+fn write_to() {
+    let xs = [7, 9, 8];
+    let mut ys = [0; 5];
+    let cnt = ys.iter_mut().set_from(xs.iter().map(|x| *x));
+    assert!(cnt == xs.len());
+    assert!(ys == [7, 9, 8, 0, 0]);
+
+    let cnt = ys.iter_mut().set_from(0..10);
+    assert!(cnt == ys.len());
+    assert!(ys == [0, 1, 2, 3, 4]);
+}
+
+#[test]
+fn test_interleave() {
+    let xs: [u8; 0]  = [];
+    let ys = [7u8, 9, 8, 10];
+    let zs = [2u8, 77];
+    let it = interleave(xs.iter(), ys.iter());
+    it::assert_equal(it, ys.iter());
+
+    let rs = [7u8, 2, 9, 77, 8, 10];
+    let it = interleave(ys.iter(), zs.iter());
+    it::assert_equal(it, rs.iter());
+}
+
+#[allow(deprecated)]
+#[test]
+fn foreach() {
+    let xs = [1i32, 2, 3];
+    let mut sum = 0;
+    xs.iter().foreach(|elt| sum += *elt);
+    assert!(sum == 6);
+}
+
+#[test]
+fn dropping() {
+    let xs = [1, 2, 3];
+    let mut it = xs.iter().dropping(2);
+    assert_eq!(it.next(), Some(&3));
+    assert!(it.next().is_none());
+    let mut it = xs.iter().dropping(5);
+    assert!(it.next().is_none());
+}
+
+#[test]
+fn batching() {
+    let xs = [0, 1, 2, 1, 3];
+    let ys = [(0, 1), (2, 1)];
+
+    // An iterator that gathers elements up in pairs
+    let pit = xs.iter().cloned().batching(|it| {
+               match it.next() {
+                   None => None,
+                   Some(x) => match it.next() {
+                       None => None,
+                       Some(y) => Some((x, y)),
+                   }
+               }
+           });
+    it::assert_equal(pit, ys.iter().cloned());
+}
+
+#[test]
+fn test_put_back() {
+    let xs = [0, 1, 1, 1, 2, 1, 3, 3];
+    let mut pb = put_back(xs.iter().cloned());
+    pb.next();
+    pb.put_back(1);
+    pb.put_back(0);
+    it::assert_equal(pb, xs.iter().cloned());
+}
+
+#[allow(deprecated)]
+#[test]
+fn step() {
+    it::assert_equal((0..10).step(1), 0..10);
+    it::assert_equal((0..10).step(2), (0..10).filter(|x: &i32| *x % 2 == 0));
+    it::assert_equal((0..10).step(10), 0..1);
+}
+
+#[allow(deprecated)]
+#[test]
+fn merge() {
+    it::assert_equal((0..10).step(2).merge((1..10).step(2)), 0..10);
+}
+
+
+#[test]
+fn repeatn() {
+    let s = "α";
+    let mut it = it::repeat_n(s, 3);
+    assert_eq!(it.len(), 3);
+    assert_eq!(it.next(), Some(s));
+    assert_eq!(it.next(), Some(s));
+    assert_eq!(it.next(), Some(s));
+    assert_eq!(it.next(), None);
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn count_clones() {
+    // Check that RepeatN only clones N - 1 times.
+
+    use core::cell::Cell;
+    #[derive(PartialEq, Debug)]
+    struct Foo {
+        n: Cell<usize>
+    }
+
+    impl Clone for Foo
+    {
+        fn clone(&self) -> Self
+        {
+            let n = self.n.get();
+            self.n.set(n + 1);
+            Foo { n: Cell::new(n + 1) }
+        }
+    }
+
+
+    for n in 0..10 {
+        let f = Foo{n: Cell::new(0)};
+        let it = it::repeat_n(f, n);
+        // drain it
+        let last = it.last();
+        if n == 0 {
+            assert_eq!(last, None);
+        } else {
+            assert_eq!(last, Some(Foo{n: Cell::new(n - 1)}));
+        }
+    }
+}
+
+#[test]
+fn part() {
+    let mut data = [7, 1, 1, 9, 1, 1, 3];
+    let i = it::partition(&mut data, |elt| *elt >= 3);
+    assert_eq!(i, 3);
+    assert_eq!(data, [7, 3, 9, 1, 1, 1, 1]);
+
+    let i = it::partition(&mut data, |elt| *elt == 1);
+    assert_eq!(i, 4);
+    assert_eq!(data, [1, 1, 1, 1, 9, 3, 7]);
+
+    let mut data = [1, 2, 3, 4, 5, 6, 7, 8, 9];
+    let i = it::partition(&mut data, |elt| *elt % 3 == 0);
+    assert_eq!(i, 3);
+    assert_eq!(data, [9, 6, 3, 4, 5, 2, 7, 8, 1]);
+}
+
+#[test]
+fn tree_fold1() {
+    for i in 0..100 {
+        assert_eq!((0..i).tree_fold1(|x, y| x + y), (0..i).fold1(|x, y| x + y));
+    }
+}
+
+#[test]
+fn exactly_one() {
+    assert_eq!((0..10).filter(|&x| x == 2).exactly_one().unwrap(), 2);
+    assert!((0..10).filter(|&x| x > 1 && x < 4).exactly_one().unwrap_err().eq(2..4));
+    assert!((0..10).filter(|&x| x > 1 && x < 5).exactly_one().unwrap_err().eq(2..5));
+    assert!((0..10).filter(|&_| false).exactly_one().unwrap_err().eq(0..0));
+}
+
+#[test]
+fn sum1() {
+    let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+    assert_eq!(v[..0].iter().cloned().sum1::<i32>(), None);
+    assert_eq!(v[1..2].iter().cloned().sum1::<i32>(), Some(1));
+    assert_eq!(v[1..3].iter().cloned().sum1::<i32>(), Some(3));
+    assert_eq!(v.iter().cloned().sum1::<i32>(), Some(55));
+}
+
+#[test]
+fn product1() {
+    let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+    assert_eq!(v[..0].iter().cloned().product1::<i32>(), None);
+    assert_eq!(v[..1].iter().cloned().product1::<i32>(), Some(0));
+    assert_eq!(v[1..3].iter().cloned().product1::<i32>(), Some(2));
+    assert_eq!(v[1..5].iter().cloned().product1::<i32>(), Some(24));
+}
diff --git a/tests/test_std.rs b/tests/test_std.rs
new file mode 100644
index 0000000..ba07784
--- /dev/null
+++ b/tests/test_std.rs
@@ -0,0 +1,793 @@
+use permutohedron;
+use itertools as it;
+use crate::it::Itertools;
+use crate::it::multizip;
+use crate::it::multipeek;
+use crate::it::free::rciter;
+use crate::it::free::put_back_n;
+use crate::it::FoldWhile;
+use crate::it::cloned;
+use crate::it::iproduct;
+use crate::it::izip;
+
+#[test]
+fn product3() {
+    let prod = iproduct!(0..3, 0..2, 0..2);
+    assert_eq!(prod.size_hint(), (12, Some(12)));
+    let v = prod.collect_vec();
+    for i in 0..3 {
+        for j in 0..2 {
+            for k in 0..2 {
+                assert!((i, j, k) == v[(i * 2 * 2 + j * 2 + k) as usize]);
+            }
+        }
+    }
+    for (_, _, _, _) in iproduct!(0..3, 0..2, 0..2, 0..3) {
+        /* test compiles */
+    }
+}
+
+#[test]
+fn interleave_shortest() {
+    let v0: Vec<i32> = vec![0, 2, 4];
+    let v1: Vec<i32> = vec![1, 3, 5, 7];
+    let it = v0.into_iter().interleave_shortest(v1.into_iter());
+    assert_eq!(it.size_hint(), (6, Some(6)));
+    assert_eq!(it.collect_vec(), vec![0, 1, 2, 3, 4, 5]);
+
+    let v0: Vec<i32> = vec![0, 2, 4, 6, 8];
+    let v1: Vec<i32> = vec![1, 3, 5];
+    let it = v0.into_iter().interleave_shortest(v1.into_iter());
+    assert_eq!(it.size_hint(), (7, Some(7)));
+    assert_eq!(it.collect_vec(), vec![0, 1, 2, 3, 4, 5, 6]);
+
+    let i0 = ::std::iter::repeat(0);
+    let v1: Vec<_> = vec![1, 3, 5];
+    let it = i0.interleave_shortest(v1.into_iter());
+    assert_eq!(it.size_hint(), (7, Some(7)));
+
+    let v0: Vec<_> = vec![0, 2, 4];
+    let i1 = ::std::iter::repeat(1);
+    let it = v0.into_iter().interleave_shortest(i1);
+    assert_eq!(it.size_hint(), (6, Some(6)));
+}
+
+
+#[test]
+fn unique_by() {
+    let xs = ["aaa", "bbbbb", "aa", "ccc", "bbbb", "aaaaa", "cccc"];
+    let ys = ["aaa", "bbbbb", "ccc"];
+    it::assert_equal(ys.iter(), xs.iter().unique_by(|x| x[..2].to_string()));
+}
+
+#[test]
+fn unique() {
+    let xs = [0, 1, 2, 3, 2, 1, 3];
+    let ys = [0, 1, 2, 3];
+    it::assert_equal(ys.iter(), xs.iter().unique());
+    let xs = [0, 1];
+    let ys = [0, 1];
+    it::assert_equal(ys.iter(), xs.iter().unique());
+}
+
+#[test]
+fn intersperse() {
+    let xs = ["a", "", "b", "c"];
+    let v: Vec<&str> = xs.iter().map(|x| x.clone()).intersperse(", ").collect();
+    let text: String = v.concat();
+    assert_eq!(text, "a, , b, c".to_string());
+
+    let ys = [0, 1, 2, 3];
+    let mut it = ys[..0].iter().map(|x| *x).intersperse(1);
+    assert!(it.next() == None);
+}
+
+#[test]
+fn dedup() {
+    let xs = [0, 1, 1, 1, 2, 1, 3, 3];
+    let ys = [0, 1, 2, 1, 3];
+    it::assert_equal(ys.iter(), xs.iter().dedup());
+    let xs = [0, 0, 0, 0, 0];
+    let ys = [0];
+    it::assert_equal(ys.iter(), xs.iter().dedup());
+
+    let xs = [0, 1, 1, 1, 2, 1, 3, 3];
+    let ys = [0, 1, 2, 1, 3];
+    let mut xs_d = Vec::new();
+    xs.iter().dedup().fold((), |(), &elt| xs_d.push(elt));
+    assert_eq!(&xs_d, &ys);
+}
+
+#[test]
+fn dedup_by() {
+    let xs = [(0, 0), (0, 1), (1, 1), (2, 1), (0, 2), (3, 1), (0, 3), (1, 3)];
+    let ys = [(0, 0), (0, 1), (0, 2), (3, 1), (0, 3)];
+    it::assert_equal(ys.iter(), xs.iter().dedup_by(|x, y| x.1==y.1));
+    let xs = [(0, 1), (0, 2), (0, 3), (0, 4), (0, 5)];
+    let ys = [(0, 1)];
+    it::assert_equal(ys.iter(), xs.iter().dedup_by(|x, y| x.0==y.0));
+
+    let xs = [(0, 0), (0, 1), (1, 1), (2, 1), (0, 2), (3, 1), (0, 3), (1, 3)];
+    let ys = [(0, 0), (0, 1), (0, 2), (3, 1), (0, 3)];
+    let mut xs_d = Vec::new();
+    xs.iter().dedup_by(|x, y| x.1==y.1).fold((), |(), &elt| xs_d.push(elt));
+    assert_eq!(&xs_d, &ys);
+}
+
+#[test]
+fn all_equal() {
+    assert!("".chars().all_equal());
+    assert!("A".chars().all_equal());
+    assert!(!"AABBCCC".chars().all_equal());
+    assert!("AAAAAAA".chars().all_equal());
+    for (_key, mut sub) in &"AABBCCC".chars().group_by(|&x| x) {
+        assert!(sub.all_equal());
+    }
+}
+
+#[test]
+fn test_put_back_n() {
+    let xs = [0, 1, 1, 1, 2, 1, 3, 3];
+    let mut pb = put_back_n(xs.iter().cloned());
+    pb.next();
+    pb.next();
+    pb.put_back(1);
+    pb.put_back(0);
+    it::assert_equal(pb, xs.iter().cloned());
+}
+
+#[test]
+fn tee() {
+    let xs  = [0, 1, 2, 3];
+    let (mut t1, mut t2) = xs.iter().cloned().tee();
+    assert_eq!(t1.next(), Some(0));
+    assert_eq!(t2.next(), Some(0));
+    assert_eq!(t1.next(), Some(1));
+    assert_eq!(t1.next(), Some(2));
+    assert_eq!(t1.next(), Some(3));
+    assert_eq!(t1.next(), None);
+    assert_eq!(t2.next(), Some(1));
+    assert_eq!(t2.next(), Some(2));
+    assert_eq!(t1.next(), None);
+    assert_eq!(t2.next(), Some(3));
+    assert_eq!(t2.next(), None);
+    assert_eq!(t1.next(), None);
+    assert_eq!(t2.next(), None);
+
+    let (t1, t2) = xs.iter().cloned().tee();
+    it::assert_equal(t1, xs.iter().cloned());
+    it::assert_equal(t2, xs.iter().cloned());
+
+    let (t1, t2) = xs.iter().cloned().tee();
+    it::assert_equal(t1.zip(t2), xs.iter().cloned().zip(xs.iter().cloned()));
+}
+
+
+#[test]
+fn test_rciter() {
+    let xs = [0, 1, 1, 1, 2, 1, 3, 5, 6];
+
+    let mut r1 = rciter(xs.iter().cloned());
+    let mut r2 = r1.clone();
+    assert_eq!(r1.next(), Some(0));
+    assert_eq!(r2.next(), Some(1));
+    let mut z = r1.zip(r2);
+    assert_eq!(z.next(), Some((1, 1)));
+    assert_eq!(z.next(), Some((2, 1)));
+    assert_eq!(z.next(), Some((3, 5)));
+    assert_eq!(z.next(), None);
+
+    // test intoiterator
+    let r1 = rciter(0..5);
+    let mut z = izip!(&r1, r1);
+    assert_eq!(z.next(), Some((0, 1)));
+}
+
+#[allow(deprecated)]
+#[test]
+fn trait_pointers() {
+    struct ByRef<'r, I: ?Sized>(&'r mut I) ;
+
+    impl<'r, X, I: ?Sized> Iterator for ByRef<'r, I> where
+        I: 'r + Iterator<Item=X>
+    {
+        type Item = X;
+        fn next(&mut self) -> Option<X>
+        {
+            self.0.next()
+        }
+    }
+
+    let mut it = Box::new(0..10) as Box<dyn Iterator<Item=i32>>;
+    assert_eq!(it.next(), Some(0));
+
+    {
+        /* make sure foreach works on non-Sized */
+        let jt: &mut dyn Iterator<Item = i32> = &mut *it;
+        assert_eq!(jt.next(), Some(1));
+
+        {
+            let mut r = ByRef(jt);
+            assert_eq!(r.next(), Some(2));
+        }
+
+        assert_eq!(jt.find_position(|x| *x == 4), Some((1, 4)));
+        jt.foreach(|_| ());
+    }
+}
+
+#[test]
+fn merge_by() {
+    let odd : Vec<(u32, &str)> = vec![(1, "hello"), (3, "world"), (5, "!")];
+    let even = vec![(2, "foo"), (4, "bar"), (6, "baz")];
+    let expected = vec![(1, "hello"), (2, "foo"), (3, "world"), (4, "bar"), (5, "!"), (6, "baz")];
+    let results = odd.iter().merge_by(even.iter(), |a, b| a.0 <= b.0);
+    it::assert_equal(results, expected.iter());
+}
+
+#[test]
+fn merge_by_btree() {
+    use std::collections::BTreeMap;
+    let mut bt1 = BTreeMap::new();
+    bt1.insert("hello", 1);
+    bt1.insert("world", 3);
+    let mut bt2 = BTreeMap::new();
+    bt2.insert("foo", 2);
+    bt2.insert("bar", 4);
+    let results = bt1.into_iter().merge_by(bt2.into_iter(), |a, b| a.0 <= b.0 );
+    let expected = vec![("bar", 4), ("foo", 2), ("hello", 1), ("world", 3)];
+    it::assert_equal(results, expected.into_iter());
+}
+
+#[allow(deprecated)]
+#[test]
+fn kmerge() {
+    let its = (0..4).map(|s| (s..10).step(4));
+
+    it::assert_equal(its.kmerge(), 0..10);
+}
+
+#[allow(deprecated)]
+#[test]
+fn kmerge_2() {
+    let its = vec![3, 2, 1, 0].into_iter().map(|s| (s..10).step(4));
+
+    it::assert_equal(its.kmerge(), 0..10);
+}
+
+#[test]
+fn kmerge_empty() {
+    let its = (0..4).map(|_| 0..0);
+    assert_eq!(its.kmerge().next(), None);
+}
+
+#[test]
+fn kmerge_size_hint() {
+    let its = (0..5).map(|_| (0..10));
+    assert_eq!(its.kmerge().size_hint(), (50, Some(50)));
+}
+
+#[test]
+fn kmerge_empty_size_hint() {
+    let its = (0..5).map(|_| (0..0));
+    assert_eq!(its.kmerge().size_hint(), (0, Some(0)));
+}
+
+#[test]
+fn join() {
+    let many = [1, 2, 3];
+    let one  = [1];
+    let none: Vec<i32> = vec![];
+
+    assert_eq!(many.iter().join(", "), "1, 2, 3");
+    assert_eq!( one.iter().join(", "), "1");
+    assert_eq!(none.iter().join(", "), "");
+}
+
+#[test]
+fn sorted_by() {
+    let sc = [3, 4, 1, 2].iter().cloned().sorted_by(|&a, &b| {
+        a.cmp(&b)
+    });
+    it::assert_equal(sc, vec![1, 2, 3, 4]);
+
+    let v = (0..5).sorted_by(|&a, &b| a.cmp(&b).reverse());
+    it::assert_equal(v, vec![4, 3, 2, 1, 0]);
+}
+
+#[test]
+fn sorted_by_key() {
+    let sc = [3, 4, 1, 2].iter().cloned().sorted_by_key(|&x| x);
+    it::assert_equal(sc, vec![1, 2, 3, 4]);
+
+    let v = (0..5).sorted_by_key(|&x| -x);
+    it::assert_equal(v, vec![4, 3, 2, 1, 0]);
+}
+
+#[test]
+fn test_multipeek() {
+    let nums = vec![1u8,2,3,4,5];
+
+    let mp = multipeek(nums.iter().map(|&x| x));
+    assert_eq!(nums, mp.collect::<Vec<_>>());
+
+    let mut mp = multipeek(nums.iter().map(|&x| x));
+    assert_eq!(mp.peek(), Some(&1));
+    assert_eq!(mp.next(), Some(1));
+    assert_eq!(mp.peek(), Some(&2));
+    assert_eq!(mp.peek(), Some(&3));
+    assert_eq!(mp.next(), Some(2));
+    assert_eq!(mp.peek(), Some(&3));
+    assert_eq!(mp.peek(), Some(&4));
+    assert_eq!(mp.peek(), Some(&5));
+    assert_eq!(mp.peek(), None);
+    assert_eq!(mp.next(), Some(3));
+    assert_eq!(mp.next(), Some(4));
+    assert_eq!(mp.peek(), Some(&5));
+    assert_eq!(mp.peek(), None);
+    assert_eq!(mp.next(), Some(5));
+    assert_eq!(mp.next(), None);
+    assert_eq!(mp.peek(), None);
+
+}
+
+#[test]
+fn test_multipeek_reset() {
+    let data = [1, 2, 3, 4];
+
+    let mut mp = multipeek(cloned(&data));
+    assert_eq!(mp.peek(), Some(&1));
+    assert_eq!(mp.next(), Some(1));
+    assert_eq!(mp.peek(), Some(&2));
+    assert_eq!(mp.peek(), Some(&3));
+    mp.reset_peek();
+    assert_eq!(mp.peek(), Some(&2));
+    assert_eq!(mp.next(), Some(2));
+}
+
+#[test]
+fn test_multipeek_peeking_next() {
+    use crate::it::PeekingNext;
+    let nums = vec![1u8,2,3,4,5,6,7];
+
+    let mut mp = multipeek(nums.iter().map(|&x| x));
+    assert_eq!(mp.peeking_next(|&x| x != 0), Some(1));
+    assert_eq!(mp.next(), Some(2));
+    assert_eq!(mp.peek(), Some(&3));
+    assert_eq!(mp.peek(), Some(&4));
+    assert_eq!(mp.peeking_next(|&x| x == 3), Some(3));
+    assert_eq!(mp.peek(), Some(&4));
+    assert_eq!(mp.peeking_next(|&x| x != 4), None);
+    assert_eq!(mp.peeking_next(|&x| x == 4), Some(4));
+    assert_eq!(mp.peek(), Some(&5));
+    assert_eq!(mp.peek(), Some(&6));
+    assert_eq!(mp.peeking_next(|&x| x != 5), None);
+    assert_eq!(mp.peek(), Some(&7));
+    assert_eq!(mp.peeking_next(|&x| x == 5), Some(5));
+    assert_eq!(mp.peeking_next(|&x| x == 6), Some(6));
+    assert_eq!(mp.peek(), Some(&7));
+    assert_eq!(mp.peek(), None);
+    assert_eq!(mp.next(), Some(7));
+    assert_eq!(mp.peek(), None);
+}
+
+#[test]
+fn pad_using() {
+    it::assert_equal((0..0).pad_using(1, |_| 1), 1..2);
+
+    let v: Vec<usize> = vec![0, 1, 2];
+    let r = v.into_iter().pad_using(5, |n| n);
+    it::assert_equal(r, vec![0, 1, 2, 3, 4]);
+
+    let v: Vec<usize> = vec![0, 1, 2];
+    let r = v.into_iter().pad_using(1, |_| panic!());
+    it::assert_equal(r, vec![0, 1, 2]);
+}
+
+#[test]
+fn group_by() {
+    for (ch1, sub) in &"AABBCCC".chars().group_by(|&x| x) {
+        for ch2 in sub {
+            assert_eq!(ch1, ch2);
+        }
+    }
+
+    for (ch1, sub) in &"AAABBBCCCCDDDD".chars().group_by(|&x| x) {
+        for ch2 in sub {
+            assert_eq!(ch1, ch2);
+            if ch1 == 'C' {
+                break;
+            }
+        }
+    }
+
+    let toupper = |ch: &char| ch.to_uppercase().nth(0).unwrap();
+
+    // try all possible orderings
+    for indices in permutohedron::Heap::new(&mut [0, 1, 2, 3]) {
+        let groups = "AaaBbbccCcDDDD".chars().group_by(&toupper);
+        let mut subs = groups.into_iter().collect_vec();
+
+        for &idx in &indices[..] {
+            let (key, text) = match idx {
+                 0 => ('A', "Aaa".chars()),
+                 1 => ('B', "Bbb".chars()),
+                 2 => ('C', "ccCc".chars()),
+                 3 => ('D', "DDDD".chars()),
+                 _ => unreachable!(),
+            };
+            assert_eq!(key, subs[idx].0);
+            it::assert_equal(&mut subs[idx].1, text);
+        }
+    }
+
+    let groups = "AAABBBCCCCDDDD".chars().group_by(|&x| x);
+    let mut subs = groups.into_iter().map(|(_, g)| g).collect_vec();
+
+    let sd = subs.pop().unwrap();
+    let sc = subs.pop().unwrap();
+    let sb = subs.pop().unwrap();
+    let sa = subs.pop().unwrap();
+    for (a, b, c, d) in multizip((sa, sb, sc, sd)) {
+        assert_eq!(a, 'A');
+        assert_eq!(b, 'B');
+        assert_eq!(c, 'C');
+        assert_eq!(d, 'D');
+    }
+
+    // check that the key closure is called exactly n times
+    {
+        let mut ntimes = 0;
+        let text = "AABCCC";
+        for (_, sub) in &text.chars().group_by(|&x| { ntimes += 1; x}) {
+            for _ in sub {
+            }
+        }
+        assert_eq!(ntimes, text.len());
+    }
+
+    {
+        let mut ntimes = 0;
+        let text = "AABCCC";
+        for _ in &text.chars().group_by(|&x| { ntimes += 1; x}) {
+        }
+        assert_eq!(ntimes, text.len());
+    }
+
+    {
+        let text = "ABCCCDEEFGHIJJKK";
+        let gr = text.chars().group_by(|&x| x);
+        it::assert_equal(gr.into_iter().flat_map(|(_, sub)| sub), text.chars());
+    }
+}
+
+#[test]
+fn group_by_lazy_2() {
+    let data = vec![0, 1];
+    let groups = data.iter().group_by(|k| *k);
+    let gs = groups.into_iter().collect_vec();
+    it::assert_equal(data.iter(), gs.into_iter().flat_map(|(_k, g)| g));
+
+    let data = vec![0, 1, 1, 0, 0];
+    let groups = data.iter().group_by(|k| *k);
+    let mut gs = groups.into_iter().collect_vec();
+    gs[1..].reverse();
+    it::assert_equal(&[0, 0, 0, 1, 1], gs.into_iter().flat_map(|(_, g)| g));
+
+    let grouper = data.iter().group_by(|k| *k);
+    let mut groups = Vec::new();
+    for (k, group) in &grouper {
+        if *k == 1 {
+            groups.push(group);
+        }
+    }
+    it::assert_equal(&mut groups[0], &[1, 1]);
+
+    let data = vec![0, 0, 0, 1, 1, 0, 0, 2, 2, 3, 3];
+    let grouper = data.iter().group_by(|k| *k);
+    let mut groups = Vec::new();
+    for (i, (_, group)) in grouper.into_iter().enumerate() {
+        if i < 2 {
+            groups.push(group);
+        } else if i < 4 {
+            for _ in group {
+            }
+        } else {
+            groups.push(group);
+        }
+    }
+    it::assert_equal(&mut groups[0], &[0, 0, 0]);
+    it::assert_equal(&mut groups[1], &[1, 1]);
+    it::assert_equal(&mut groups[2], &[3, 3]);
+
+    // use groups as chunks
+    let data = vec![0, 0, 0, 1, 1, 0, 0, 2, 2, 3, 3];
+    let mut i = 0;
+    let grouper = data.iter().group_by(move |_| { let k = i / 3; i += 1; k });
+    for (i, group) in &grouper {
+        match i {
+            0 => it::assert_equal(group, &[0, 0, 0]),
+            1 => it::assert_equal(group, &[1, 1, 0]),
+            2 => it::assert_equal(group, &[0, 2, 2]),
+            3 => it::assert_equal(group, &[3, 3]),
+            _ => unreachable!(),
+        }
+    }
+}
+
+#[test]
+fn group_by_lazy_3() {
+    // test consuming each group on the lap after it was produced
+    let data = vec![0, 0, 0, 1, 1, 0, 0, 1, 1, 2, 2];
+    let grouper = data.iter().group_by(|elt| *elt);
+    let mut last = None;
+    for (key, group) in &grouper {
+        if let Some(gr) = last.take() {
+            for elt in gr {
+                assert!(elt != key && i32::abs(elt - key) == 1);
+            }
+        }
+        last = Some(group);
+    }
+}
+
+#[test]
+fn chunks() {
+    let data = vec![0, 0, 0, 1, 1, 0, 0, 2, 2, 3, 3];
+    let grouper = data.iter().chunks(3);
+    for (i, chunk) in grouper.into_iter().enumerate() {
+        match i {
+            0 => it::assert_equal(chunk, &[0, 0, 0]),
+            1 => it::assert_equal(chunk, &[1, 1, 0]),
+            2 => it::assert_equal(chunk, &[0, 2, 2]),
+            3 => it::assert_equal(chunk, &[3, 3]),
+            _ => unreachable!(),
+        }
+    }
+}
+
+#[test]
+fn concat_empty() {
+    let data: Vec<Vec<()>> = Vec::new();
+    assert_eq!(data.into_iter().concat(), Vec::new())
+}
+
+#[test]
+fn concat_non_empty() {
+    let data = vec![vec![1,2,3], vec![4,5,6], vec![7,8,9]];
+    assert_eq!(data.into_iter().concat(), vec![1,2,3,4,5,6,7,8,9])
+}
+
+#[test]
+fn combinations() {
+    assert!((1..3).combinations(5).next().is_none());
+
+    let it = (1..3).combinations(2);
+    it::assert_equal(it, vec![
+        vec![1, 2],
+        ]);
+
+    let it = (1..5).combinations(2);
+    it::assert_equal(it, vec![
+        vec![1, 2],
+        vec![1, 3],
+        vec![1, 4],
+        vec![2, 3],
+        vec![2, 4],
+        vec![3, 4],
+        ]);
+
+    it::assert_equal((0..0).tuple_combinations::<(_, _)>(), <Vec<_>>::new());
+    it::assert_equal((0..1).tuple_combinations::<(_, _)>(), <Vec<_>>::new());
+    it::assert_equal((0..2).tuple_combinations::<(_, _)>(), vec![(0, 1)]);
+
+    it::assert_equal((0..0).combinations(2), <Vec<Vec<_>>>::new());
+    it::assert_equal((0..1).combinations(1), vec![vec![0]]);
+    it::assert_equal((0..2).combinations(1), vec![vec![0], vec![1]]);
+    it::assert_equal((0..2).combinations(2), vec![vec![0, 1]]);
+}
+
+#[test]
+fn combinations_of_too_short() {
+    for i in 1..10 {
+        assert!((0..0).combinations(i).next().is_none());
+        assert!((0..i - 1).combinations(i).next().is_none());
+    }
+}
+
+
+#[test]
+fn combinations_zero() {
+    it::assert_equal((1..3).combinations(0), vec![vec![]]);
+    it::assert_equal((0..0).combinations(0), vec![vec![]]);
+}
+
+#[test]
+fn permutations_zero() {
+    it::assert_equal((1..3).permutations(0), vec![vec![]]);
+    it::assert_equal((0..0).permutations(0), vec![vec![]]);
+}
+
+#[test]
+fn combinations_with_replacement() {
+    // Pool smaller than n
+    it::assert_equal((0..1).combinations_with_replacement(2), vec![vec![0, 0]]);
+    // Pool larger than n
+    it::assert_equal(
+        (0..3).combinations_with_replacement(2),
+        vec![
+            vec![0, 0],
+            vec![0, 1],
+            vec![0, 2],
+            vec![1, 1],
+            vec![1, 2],
+            vec![2, 2],
+        ],
+    );
+    // Zero size
+    it::assert_equal(
+        (0..3).combinations_with_replacement(0),
+        vec![vec![]],
+    );
+    // Zero size on empty pool
+    it::assert_equal(
+        (0..0).combinations_with_replacement(0),
+        vec![vec![]],
+    );
+    // Empty pool
+    it::assert_equal(
+        (0..0).combinations_with_replacement(2),
+        <Vec<Vec<_>>>::new(),
+    );
+}
+
+#[test]
+fn diff_mismatch() {
+    let a = vec![1, 2, 3, 4];
+    let b = vec![1.0, 5.0, 3.0, 4.0];
+    let b_map = b.into_iter().map(|f| f as i32);
+    let diff = it::diff_with(a.iter(), b_map, |a, b| *a == b);
+
+    assert!(match diff {
+        Some(it::Diff::FirstMismatch(1, _, from_diff)) =>
+            from_diff.collect::<Vec<_>>() == vec![5, 3, 4],
+        _ => false,
+    });
+}
+
+#[test]
+fn diff_longer() {
+    let a = vec![1, 2, 3, 4];
+    let b = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0];
+    let b_map = b.into_iter().map(|f| f as i32);
+    let diff = it::diff_with(a.iter(), b_map, |a, b| *a == b);
+
+    assert!(match diff {
+        Some(it::Diff::Longer(_, remaining)) =>
+            remaining.collect::<Vec<_>>() == vec![5, 6],
+        _ => false,
+    });
+}
+
+#[test]
+fn diff_shorter() {
+    let a = vec![1, 2, 3, 4];
+    let b = vec![1.0, 2.0];
+    let b_map = b.into_iter().map(|f| f as i32);
+    let diff = it::diff_with(a.iter(), b_map, |a, b| *a == b);
+
+    assert!(match diff {
+        Some(it::Diff::Shorter(len, _)) => len == 2,
+        _ => false,
+    });
+}
+
+#[test]
+fn minmax() {
+    use std::cmp::Ordering;
+    use crate::it::MinMaxResult;
+
+    // A peculiar type: Equality compares both tuple items, but ordering only the
+    // first item.  This is so we can check the stability property easily.
+    #[derive(Clone, Debug, PartialEq, Eq)]
+    struct Val(u32, u32);
+
+    impl PartialOrd<Val> for Val {
+        fn partial_cmp(&self, other: &Val) -> Option<Ordering> {
+            self.0.partial_cmp(&other.0)
+        }
+    }
+
+    impl Ord for Val {
+        fn cmp(&self, other: &Val) -> Ordering {
+            self.0.cmp(&other.0)
+        }
+    }
+
+    assert_eq!(None::<Option<u32>>.iter().minmax(), MinMaxResult::NoElements);
+
+    assert_eq!(Some(1u32).iter().minmax(), MinMaxResult::OneElement(&1));
+
+    let data = vec![Val(0, 1), Val(2, 0), Val(0, 2), Val(1, 0), Val(2, 1)];
+
+    let minmax = data.iter().minmax();
+    assert_eq!(minmax, MinMaxResult::MinMax(&Val(0, 1), &Val(2, 1)));
+
+    let (min, max) = data.iter().minmax_by_key(|v| v.1).into_option().unwrap();
+    assert_eq!(min, &Val(2, 0));
+    assert_eq!(max, &Val(0, 2));
+
+    let (min, max) = data.iter().minmax_by(|x, y| x.1.cmp(&y.1)).into_option().unwrap();
+    assert_eq!(min, &Val(2, 0));
+    assert_eq!(max, &Val(0, 2));
+}
+
+#[test]
+fn format() {
+    let data = [0, 1, 2, 3];
+    let ans1 = "0, 1, 2, 3";
+    let ans2 = "0--1--2--3";
+
+    let t1 = format!("{}", data.iter().format(", "));
+    assert_eq!(t1, ans1);
+    let t2 = format!("{:?}", data.iter().format("--"));
+    assert_eq!(t2, ans2);
+
+    let dataf = [1.1, 2.71828, -22.];
+    let t3 = format!("{:.2e}", dataf.iter().format(", "));
+    assert_eq!(t3, "1.10e0, 2.72e0, -2.20e1");
+}
+
+#[test]
+fn while_some() {
+    let ns = (1..10).map(|x| if x % 5 != 0 { Some(x) } else { None })
+                    .while_some();
+    it::assert_equal(ns, vec![1, 2, 3, 4]);
+}
+
+#[allow(deprecated)]
+#[test]
+fn fold_while() {
+    let mut iterations = 0;
+    let vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+    let sum = vec.into_iter().fold_while(0, |acc, item| {
+        iterations += 1;
+        let new_sum = acc.clone() + item;
+        if new_sum <= 20 {
+            FoldWhile::Continue(new_sum)
+        } else {
+            FoldWhile::Done(acc)
+        }
+    }).into_inner();
+    assert_eq!(iterations, 6);
+    assert_eq!(sum, 15);
+}
+
+#[test]
+fn tree_fold1() {
+    let x = [
+        "",
+        "0",
+        "0 1 x",
+        "0 1 x 2 x",
+        "0 1 x 2 3 x x",
+        "0 1 x 2 3 x x 4 x",
+        "0 1 x 2 3 x x 4 5 x x",
+        "0 1 x 2 3 x x 4 5 x 6 x x",
+        "0 1 x 2 3 x x 4 5 x 6 7 x x x",
+        "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 x",
+        "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x x",
+        "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x 10 x x",
+        "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x 10 11 x x x",
+        "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x 10 11 x x 12 x x",
+        "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x 10 11 x x 12 13 x x x",
+        "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x 10 11 x x 12 13 x 14 x x x",
+        "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x 10 11 x x 12 13 x 14 15 x x x x",
+    ];
+    for (i, &s) in x.iter().enumerate() {
+        let expected = if s == "" { None } else { Some(s.to_string()) };
+        let num_strings = (0..i).map(|x| x.to_string());
+        let actual = num_strings.tree_fold1(|a, b| format!("{} {} x", a, b));
+        assert_eq!(actual, expected);
+    }
+}
diff --git a/tests/tuples.rs b/tests/tuples.rs
new file mode 100644
index 0000000..9fc8b3c
--- /dev/null
+++ b/tests/tuples.rs
@@ -0,0 +1,86 @@
+use itertools::Itertools;
+
+#[test]
+fn tuples() {
+    let v = [1, 2, 3, 4, 5];
+    let mut iter = v.iter().cloned().tuples();
+    assert_eq!(Some((1,)), iter.next());
+    assert_eq!(Some((2,)), iter.next());
+    assert_eq!(Some((3,)), iter.next());
+    assert_eq!(Some((4,)), iter.next());
+    assert_eq!(Some((5,)), iter.next());
+    assert_eq!(None, iter.next());
+    assert_eq!(None, iter.into_buffer().next());
+
+    let mut iter = v.iter().cloned().tuples();
+    assert_eq!(Some((1, 2)), iter.next());
+    assert_eq!(Some((3, 4)), iter.next());
+    assert_eq!(None, iter.next());
+    itertools::assert_equal(vec![5], iter.into_buffer());
+
+    let mut iter = v.iter().cloned().tuples();
+    assert_eq!(Some((1, 2, 3)), iter.next());
+    assert_eq!(None, iter.next());
+    itertools::assert_equal(vec![4, 5], iter.into_buffer());
+
+    let mut iter = v.iter().cloned().tuples();
+    assert_eq!(Some((1, 2, 3, 4)), iter.next());
+    assert_eq!(None, iter.next());
+    itertools::assert_equal(vec![5], iter.into_buffer());
+}
+
+#[test]
+fn tuple_windows() {
+    let v = [1, 2, 3, 4, 5];
+
+    let mut iter = v.iter().cloned().tuple_windows();
+    assert_eq!(Some((1,)), iter.next());
+    assert_eq!(Some((2,)), iter.next());
+    assert_eq!(Some((3,)), iter.next());
+
+    let mut iter = v.iter().cloned().tuple_windows();
+    assert_eq!(Some((1, 2)), iter.next());
+    assert_eq!(Some((2, 3)), iter.next());
+    assert_eq!(Some((3, 4)), iter.next());
+    assert_eq!(Some((4, 5)), iter.next());
+    assert_eq!(None, iter.next());
+
+    let mut iter = v.iter().cloned().tuple_windows();
+    assert_eq!(Some((1, 2, 3)), iter.next());
+    assert_eq!(Some((2, 3, 4)), iter.next());
+    assert_eq!(Some((3, 4, 5)), iter.next());
+    assert_eq!(None, iter.next());
+
+    let mut iter = v.iter().cloned().tuple_windows();
+    assert_eq!(Some((1, 2, 3, 4)), iter.next());
+    assert_eq!(Some((2, 3, 4, 5)), iter.next());
+    assert_eq!(None, iter.next());
+
+    let v = [1, 2, 3];
+    let mut iter = v.iter().cloned().tuple_windows::<(_, _, _, _)>();
+    assert_eq!(None, iter.next());
+}
+
+#[test]
+fn next_tuple() {
+    let v = [1, 2, 3, 4, 5];
+    let mut iter = v.iter();
+    assert_eq!(iter.next_tuple().map(|(&x, &y)| (x, y)), Some((1, 2)));
+    assert_eq!(iter.next_tuple().map(|(&x, &y)| (x, y)), Some((3, 4)));
+    assert_eq!(iter.next_tuple::<(_, _)>(), None);
+}
+
+#[test]
+fn collect_tuple() {
+    let v = [1, 2];
+    let iter = v.iter().cloned();
+    assert_eq!(iter.collect_tuple(), Some((1, 2)));
+
+    let v = [1];
+    let iter = v.iter().cloned();
+    assert_eq!(iter.collect_tuple::<(_, _)>(), None);
+
+    let v = [1, 2, 3];
+    let iter = v.iter().cloned();
+    assert_eq!(iter.collect_tuple::<(_, _)>(), None);
+}
diff --git a/tests/zip.rs b/tests/zip.rs
new file mode 100644
index 0000000..b1af52c
--- /dev/null
+++ b/tests/zip.rs
@@ -0,0 +1,63 @@
+use itertools::Itertools;
+use itertools::EitherOrBoth::{Both, Left, Right};
+use itertools::free::zip_eq;
+
+#[test]
+fn zip_longest_fused() {
+    let a = [Some(1), None, Some(3), Some(4)];
+    let b = [1, 2, 3];
+
+    let unfused = a.iter().batching(|it| *it.next().unwrap())
+        .zip_longest(b.iter().cloned());
+    itertools::assert_equal(unfused,
+                       vec![Both(1, 1), Right(2), Right(3)]);
+}
+
+#[test]
+fn test_zip_longest_size_hint() {
+    let c = (1..10).cycle();
+    let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+    let v2 = &[10, 11, 12];
+
+    assert_eq!(c.zip_longest(v.iter()).size_hint(), (std::usize::MAX, None));
+
+    assert_eq!(v.iter().zip_longest(v2.iter()).size_hint(), (10, Some(10)));
+}
+
+#[test]
+fn test_double_ended_zip_longest() {
+    let xs = [1, 2, 3, 4, 5, 6];
+    let ys = [1, 2, 3, 7];
+    let a = xs.iter().map(|&x| x);
+    let b = ys.iter().map(|&x| x);
+    let mut it = a.zip_longest(b);
+    assert_eq!(it.next(), Some(Both(1, 1)));
+    assert_eq!(it.next(), Some(Both(2, 2)));
+    assert_eq!(it.next_back(), Some(Left(6)));
+    assert_eq!(it.next_back(), Some(Left(5)));
+    assert_eq!(it.next_back(), Some(Both(4, 7)));
+    assert_eq!(it.next(), Some(Both(3, 3)));
+    assert_eq!(it.next(), None);
+}
+
+
+#[should_panic]
+#[test]
+fn zip_eq_panic1()
+{
+    let a = [1, 2];
+    let b = [1, 2, 3];
+
+    zip_eq(&a, &b).count();
+}
+
+#[should_panic]
+#[test]
+fn zip_eq_panic2()
+{
+    let a: [i32; 0] = [];
+    let b = [1, 2, 3];
+
+    zip_eq(&a, &b).count();
+}
+
