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);
