Repository: Geal/nom
Pull request #361 (2016-11-06 15:23:55)

Improve documentation for `alt!` and `alt_complete!`
I'm trying to improve the documentation a little and started with the `alt!` and `alt_complete!` combinators. Here is what I changed:

- Made the short description, shorter and easier to read.
  In my opinion, things like `alt!(I -> IResult<I,O> | I -> IResult<I,O> | ... | I -> IResult<I,O> ) => I -> IResult<I, O>` are too long to be in the short description. When all the combinators are listed on the front page of the docs it's easier to have a one line overview of what that combinator does, instead of a full type description.
- Added titles to differentiate between different sections of the page (e.g. example, manipulate results, ...).
- Changed the examples to be a little more readable by adding spaces, comments and making it a little more realistic.

I am not sure if you will like the changes, if not, feel free to close this PR. :smiley: 




Patch:
diff --git a/.travis.yml b/.travis.yml
index 40beb66..9bfdcb8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -33,11 +33,6 @@ script:
 after_success:
   - travis-cargo bench
   - travis-cargo coveralls --no-sudo
-  - ./kcov/build/src/kcov --verify --coveralls-id=$TRAVIS_JOB_ID --exclude-pattern=/.cargo target/kcov target/debug/nom-*
-  - ./kcov/build/src/kcov --verify --coveralls-id=$TRAVIS_JOB_ID --exclude-pattern=/.cargo target/kcov target/debug/arithmetic*
-  - ./kcov/build/src/kcov --verify --coveralls-id=$TRAVIS_JOB_ID --exclude-pattern=/.cargo target/kcov target/debug/ini*
-  - ./kcov/build/src/kcov --verify --coveralls-id=$TRAVIS_JOB_ID --exclude-pattern=/.cargo target/kcov target/debug/mp4*
-  - ./kcov/build/src/kcov --verify --coveralls-id=$TRAVIS_JOB_ID --exclude-pattern=/.cargo target/kcov target/debug/json*
   - if [ "$TRAVIS_RUST_VERSION" == "nightly" ]; then
       cargo bench;
     fi
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8b27d3f..f1c3315 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,81 +4,6 @@
 
 ### Changed
 
-## 2.0.1 - 2016-12-10
-
-Bugfix release
-
-*Warning*: there is a small breaking change, `add_error!` is renamed to `add_return_error!`. This was planned for the 2.0 release but was forgotten. This is a small change in a feature that not many people use, for a release that is not yet widely in use, so there will be no 3.0 release for that change.
-
-### Thanks
-
-- @nickbabcock for catching and fixing the `add_error!` mixup
-- @lucab for documentation fixes
-- @jtdowney for noticing that `tag_no_case!` was not working at all for byte slices
-
-### Fixed
-
-- `add_error!` has been renamed to `add_return_error!`
-- the `not!` combinator now accepts functions
-- `tag_no_case!` is now working as accepted (before, it accepted everything)
-
-
-## 2.0 - 2016-11-25
-
-The 2.0 release is one of the biggest yet. It was a good opportunity to clean up some badly named combinators and fix invalid behaviours.
-
-Since this version introduces a few breaking changes, an [upgrade documentation](https://github.com/Geal/nom/blob/master/doc/upgrading_to_nom_2.md) is available, detailing the steps to fix the most common migration issues. After testing on a set of 30 crates, most of them will build directly, a large part will just need to activate the "verbose-errors" compilation feature. The remaining fixes are documented.
-
-This version also adds a lot of interesting features, like the permutation combinator or whitespace separated formats support.
-
-### Thanks
-
-- @lu-zero for license help
-- @adamgreig for type inference fixes
-- @keruspe for documentation and example fixes, for the `IResult => Result` conversion work, making `AsChar`'s method more consistent, and adding `many_till!`
-- @jdeeny for implementing `Offset` on `&str`
-- @vickenty for documentation fixes and his refactoring of `length_value!` and `length_bytes!`
-- @overdrivenpotato for refactoring some combinators
-- @taralx for documentation fixes
-- @keeperofdakeys for fixing eol behaviour, writing documentation and adding `named_attr!`
-- @jturner314 for writing documentation
-- @bozaro for fixing compilation errors
-- @uniphil for adding a `crates.io` badge
-- @badboy for documentation fixes
-- @jugglerchris for fixing `take_s!`
-- @AndyShiue for implementing `Error` and `Display` on `ErrorKind` and detecting incorrect UTF-8 string indexing
-
-### Added
-
-- the "simple" error management system does not accumulates errors when backtracking. This is a big perf gain, and is activated by default in nom 2.0
-- nom can now work on any type that implement the traits defined in `src/traits.rs`: `InputLength`, `InputIter`, `InputTake`, `Compare`, `FindToken`, `FindSubstring`, `Slice`
-- the documentation from Github's wiki has been moved to the `doc/` directory. They are markdown files that you can build with [cargo-external-doc](https://crates.io/crates/cargo-external-doc)
-- whitespace separated format support: with the `ws!` combinator, you can automatically introduce whitespace parsers between all parsers and combinators
-- the `permutation!` combinator applies its child parsers in any order, as long as they all succeed once, and return a tuple of the results
-- `do_parse!` is a simpler alternative to `chain!`, which is now deprecated
-- you can now transform an `IResult` in a `std::result::Result`
-- `length_data!` parses a length, and returns a subslice of that length
-- `tag_no_case!` provides case independent comparison. It works nicely, without any allocation, for ASCII strings, but for UTF-8 strings, it defaults to an unsatisfying (and incorrect) comparison by lowercasing both strings
-- `named_attr!` creates functions like `named!` but can add attributes like documentation
-- `many_till!` applies repeatedly its first child parser until the second succeeds
-
-### Changed
-
-- the "verbose" error management that was available in previous versions is now activated by the "verbose-errors" compilation feature
-- code reorganization: most of the parsers were moved in separate files to make the source easier to navigate
-- most of the combinators are now independent from the input type
-- the `eof` function was replaced with the `eof!` macro
-- `error!` and `add_error!` were replaced with `return_error!` and `add_return_error!` to fix the name conflict with the log crate
-- the `offset()` method is now in the `Offset` trait
-- `length_value!` has been renamed to `length_count!`. The new `length_value!` selects a slice and applies the second parser once on that slice
-- `AsChar::is_0_to_9` is now `AsChar::is_dec_digit`
-- the combinators with configurable endianness now take an enum instead of a boolean as parameter
-
-### Fixed
-- the `count!`, `count_fixed!` and `length_*!` combinator calculate incomplete data needs correctly
-- `eol`, `line_ending` and `not_line_ending` now have a consistent behaviour that works correctly with incomplete data
-- `take_s!` didn't correctly handle the case when the slice is exactly the right length
-
 ## 1.2.4 - 2016-07-20
 
 ### Thanks
@@ -104,14 +29,14 @@ This version also adds a lot of interesting features, like the permutation combi
 - `take_bits!` is now more precise
 - `many1` inccorectly used the `len` function instead of `input_len`
 - the INI parser is simpler
-- `recognize!` had an early `return` that is removed now
+- `recognize!` had an early `return` taht is removed now
 
 ## 1.2.3 - 2016-05-10
 
 ### Thanks
 - @lu-zero for the contribution guidelines
 - @GuillaumeGomez for fixes on `length_bytes` and some documentation
-- @Hywan for documentation and test fixes
+- @Hywan for ducomentation and test fixes
 - @Xirdus for correct trait import issues
 - @mspiegel for the new AST example
 - @cholcombe973 for adding the `cond_with_error!` combinator
@@ -138,7 +63,7 @@ This version also adds a lot of interesting features, like the permutation combi
 ## 1.2.2 - 2016-03-09
 
 ### Thanks
-- @conradev for fixing `take_until_s!`
+- @conradev for fixing take_until_s!`
 - @GuillaumeGomez for some documentation fixes
 - @frewsxcv for some documentation fixes
 - @tstorch for some test refactorings
@@ -196,7 +121,7 @@ This version also adds a lot of interesting features, like the permutation combi
 - there were type inference issues in a few combinators. They will now be easier to compile
 - `peek!` compilation with bare functions
 - `&str` parsers were splitting data at the byte level, not at the char level, which can result in inconsistencies in parsing UTF-8 characters. They now use character indexes
-- some method implementations were missing on `IResult<I,O,E>` (with specified error type instead of implicit)
+- some method implementations were missing on `ÌResult<I,O,E>` (with specified error type instead of implicit)
 
 ## 1.1.0 - 2016-01-01
 
@@ -212,11 +137,11 @@ There are also a few performance improvements and documentation fixes.
 - @meh for fixing `Option` and `Vec` imports
 - @hoodie for a documentation fix
 - @joelself for some documentation fixes
-- @vberger for his traits magic making nom functions more generic
+- @vberger for his traits magic making `nom functions more generic
 
 ### Added
 
-- string related parsers: `tag_s!`, `take_s!`, `is_a_s!`, `is_not_s!`, `take_while_s!`, `take_while1_s!`, `take_till_s!`
+- string related parsers: `tag_s!`, `take_s!`, `is_a_s!`, `is_not_s!`, `take_while_s!`, `take_while1_s!`, `take_till_s!
 - `value!` is a combinator that always returns the same value. If a child parser is passed as second argument, that value is returned when the child parser succeeds
 
 ### Changed
@@ -596,10 +521,8 @@ Considering the number of changes since the last release, this version can conta
 
 ## Compare code
 
-* [unreleased]: https://github.com/Geal/nom/compare/2.0.1...HEAD
-* [2.0.1]: https://github.com/Geal/nom/compare/2.0.0...2.0.1
-* [2.0.0]: https://github.com/Geal/nom/compare/1.2.4...2.0.0
-* [1.2.4]: https://github.com/Geal/nom/compare/1.2.3...1.2.4
+* [unreleased]: https://github.com/Geal/nom/compare/1.2.4...HEAD
+* [1.2.3]: https://github.com/Geal/nom/compare/1.2.3...1.2.4
 * [1.2.3]: https://github.com/Geal/nom/compare/1.2.2...1.2.3
 * [1.2.2]: https://github.com/Geal/nom/compare/1.2.1...1.2.2
 * [1.2.1]: https://github.com/Geal/nom/compare/1.2.0...1.2.1
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index d88a7b7..dfa4779 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -43,10 +43,6 @@ get to full coverage is pretty welcome.
 Help in making sure the code does not have performance regression, by improving the benchmark suite or just by
 running it weekly, is welcome as well.
 
-### Documentation
-
-To preview changes to the documentation: use `cargo doc` with [`cargo
-external-doc`](https://github.com/Geal/cargo-external-doc)
 
 ## Style
 
diff --git a/Cargo.toml b/Cargo.toml
index 57db293..65f035d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 
 name = "nom"
-version = "2.0.1"
+version = "1.2.4"
 authors = [ "contact@geoffroycouprie.com" ]
 description = "A byte-oriented, zero-copy, parser combinators library"
 license = "MIT"
@@ -9,7 +9,6 @@ repository = "https://github.com/Geal/nom"
 readme = "README.md"
 documentation = "http://rust.unhandledexpression.com/nom/"
 keywords = ["parser", "parser-combinators", "parsing", "streaming", "bit"]
-categories = ["parsing"]
 
 include = [
   "CHANGELOG.md",
@@ -31,16 +30,13 @@ stream = []
 verbose-errors = []
 
 [dependencies.regex]
-version = "^0.2"
+version = "^0.1.56"
 optional = true
 
 [dependencies.lazy_static]
-version = "^0.2.2"
+version = "^0.2.1"
 optional = true
 
-#[dev-dependencies.bytes]
-#git = "https://github.com/carllerche/bytes"
-#rev = "a7d38e29"
-
-[badges]
-travis-ci = { repository = "Geal/nom" }
+[dev-dependencies.bytes]
+git = "https://github.com/carllerche/bytes"
+rev = "a7d38e29"
diff --git a/LICENSE b/LICENSE
index a885458..0bd6a1c 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2015-2016 Geoffroy Couprie
+Copyright (c) 2015 Geoffroy Couprie
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
diff --git a/README.md b/README.md
index 07cbd95..49475f4 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,6 @@
 [![Join the chat at https://gitter.im/Geal/nom](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Geal/nom?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
 [![Build Status](https://travis-ci.org/Geal/nom.svg?branch=master)](https://travis-ci.org/Geal/nom)
 [![Coverage Status](https://coveralls.io/repos/Geal/nom/badge.svg?branch=master)](https://coveralls.io/r/Geal/nom?branch=master)
-[![Crates.io Version](https://img.shields.io/crates/v/nom.svg)](https://crates.io/crates/nom)
 
 nom is a parser combinators library written in Rust. Its goal is to provide tools to build safe parsers without compromising the speed or memory consumption. To that end, it uses extensively Rust's *strong typing*, *zero copy* parsing, *push streaming*, *pull streaming*, and provides macros and traits to abstract most of the error prone plumbing.
 
@@ -14,7 +13,7 @@ If you need any help developing your parsers, please ping `geal` on IRC (mozilla
 
 Reference documentation is available [here](http://rust.unhandledexpression.com/nom/).
 
-Various design documents and tutorials can be found in the [doc directory](https://github.com/Geal/nom/tree/master/doc).
+Various design documents and tutorials can be found in the [docs directory](https://github.com/Geal/nom/tree/master/docs).
 
 ## Features
 
@@ -43,7 +42,7 @@ nom is available on [crates.io](https://crates.io/crates/nom) and can be include
 
 ```toml
 [dependencies]
-nom = "^2.0"
+nom = "^1.2.4"
 ```
 
 Then include it in your code like this:
@@ -53,20 +52,20 @@ Then include it in your code like this:
 extern crate nom;
 ```
 
-**NOTE: if you have existing code using nom below the 2.0 version, please take a look at the [upgrade documentation](https://github.com/Geal/nom/blob/master/doc/upgrading_to_nom_2.md) to handle the breaking changes.**
+**NOTE: if you have existing code using nom below the 1.0 version, please take a look at the [upgrading documentation](https://github.com/Geal/nom/wiki/Upgrading-to-nom-1.0) to
+handle the breaking changes.**
 
 There are a few compilation features:
 
 * `core`: enables `no_std` builds
 * `regexp`: enables regular expression parsers with the `regex` crate
 * `regexp_macros`: enables regular expression parsers with the `regex` and `regex_macros` crates. Regular expressions can be defined at compile time, but it requires a nightly version of rustc
-* `verbose-errors`: accumulate error codes and input positions as you backtrack through the parser tree. This gives you precise information about which part of the parser was affected by which part of the input
 
 You can activate those features like this:
 
 ```toml
 [dependencies.nom]
-version = "^2.0"
+version = "^1.2.3"
 features = ["regexp"]
 ```
 
@@ -170,7 +169,7 @@ There is already a large list of basic parsers available, like:
 - **be_f32**, **be_f64** to parse big endian floating point numbers
 - **eof**: a parser that is successful only if the input is over. In any other case, it returns an error.
 
-Please refer to the [documentation](http://rust.unhandledexpression.com/nom/) for an exhaustive list of parsers.
+Please refer to the documentation for an exhaustive list of parsers.
 
 #### Making new parsers with macros
 
@@ -271,7 +270,7 @@ Here are some basic combining macros available:
 
 Please refer to the documentation for an exhaustive list of combinators.
 
-There are more complex (and more useful) parsers like `do_parse!` and `tuple!`, which are used to apply a series of parsers then assemble their results.
+There are more complex (and more useful) parsers like `chain!` and `tuple!`, which are used to apply a series of parsers then assemble their results.
 
 Example with `tuple!`:
 
@@ -296,7 +295,7 @@ let input = &b"abcdejk"[..];
 assert_eq!(tpl(input), Error(Position(ErrorKind::Tag, &input[5..])));
 ```
 
-Example with `do_parse!`:
+Example with `chain!`:
 
 ```rust
 #[derive(Debug, PartialEq)]
@@ -309,15 +308,15 @@ fn ret_int1(i:&[u8]) -> IResult<&[u8], u8> { Done(i,1) }
 fn ret_int2(i:&[u8]) -> IResult<&[u8], u8> { Done(i,2) }
 
 named!(f<&[u8],A>,
-  do_parse!(    // the parser takes a byte array as input, and returns an A struct
-    tag!("abcd")       >>      // begins with "abcd"
-    opt!(tag!("abcd")) >>      // this is an optional parser
-    aa: ret_int1       >>      // the return value of ret_int1, if it does not fail, will be stored in aa
-    tag!("efgh")       >>
-    bb: ret_int2       >>
-    tag!("efgh")       >>
-
-    (A{a: aa, b: bb})          // the final tuple will be able to use the variable defined previously
+  chain!(    // the parser takes a byte array as input, and returns an A struct
+    tag!("abcd")  ~      // begins with "abcd"
+    tag!("abcd")? ~      // the question mark indicates an optional parser
+    aa: ret_int1  ~      // the return value of ret_int1, if it does not fail, will be stored in aa
+    tag!("efgh")  ~
+    bb: ret_int2  ~
+    tag!("efgh")  ,      // end the chain with a comma
+
+    ||{A{a: aa, b: bb}} // the final closure will be able to use the variable defined previously
   )
 );
 
@@ -328,7 +327,7 @@ let r2 = f(b"abcdefghefghX");
 assert_eq!(r2, Done(&b"X"[..], A{a: 1, b: 2}));
 ```
 
-The double right arrow `>>` is used as separator between every parser in the sequence, and the last closure can see the variables storing the result of parsers.
+The tilde `~` is used as separator between every parser in the sequence, the comma `,` indicates the parser chain ended, and the last closure can see the variables storing the result of parsers.
 
 More examples of chain and tuple usage can be found in the [INI file parser example](tests/ini.rs).
 
@@ -350,15 +349,12 @@ Here is a list of known projects using nom:
  * [Thrift](https://github.com/thehydroimpulse/thrust)
 - Audio, video and image formats:
  * [GIF](https://github.com/Geal/gif.rs)
- * [MagicaVoxel .vox](https://github.com/davidedmonds/dot_vox)
- * [midi](https://github.com/derekdreery/nom-midi-rs)
 - Document formats:
  * [TAR](https://github.com/Keruspe/tar-parser.rs)
  * [torrent files](https://github.com/jag426/bittorrent)
 - Database formats:
  * [Redis database files](https://github.com/badboy/rdb-rs)
 - Network protocol formats:
- * [Bencode](https://github.com/jbaum98/bencode.rs)
  * [IRC](https://github.com/Detegr/RBot-parser)
  * [Pcap-NG](https://github.com/richo/pcapng-rs)
  * [NTP](https://github.com/rusticata/ntp-parser)
diff --git a/benches/http.rs b/benches/http.rs
index 207dc7a..6be649d 100644
--- a/benches/http.rs
+++ b/benches/http.rs
@@ -65,53 +65,53 @@ fn is_version(c: u8) -> bool {
 named!(line_ending, alt!(tag!("\r\n") | tag!("\n")));
 
 fn request_line<'a>(input: &'a [u8]) -> IResult<&'a[u8], Request<'a>> {
-  do_parse!(input,
-    method: take_while1!(is_token)     >>
-            take_while1!(is_space)     >>
-    url:    take_while1!(is_not_space) >>
-            take_while1!(is_space)     >>
-    version: http_version              >>
-    line_ending                        >>
-
-    (Request {
+  chain!(input,
+    method: take_while1!(is_token)     ~
+            take_while1!(is_space)     ~
+    url:    take_while1!(is_not_space) ~
+            take_while1!(is_space)     ~
+    version: http_version              ~
+    line_ending,
+
+    || Request {
         method: method,
         uri:    url,
         version: version,
-    }))
+    })
 }
 
-named!(http_version, do_parse!(
-    tag!("HTTP/")                     >>
-    version: take_while1!(is_version) >>
-
-    (version)));
-
-named!(message_header_value, do_parse!(
-          take_while1!(is_horizontal_space) >>
-    data: take_while1!(not_line_ending)     >>
-    line_ending                             >>
+named!(http_version, chain!(
+    tag!("HTTP/")                    ~
+    version: take_while1!(is_version),
+    
+    || version));
 
-    (data)));
+named!(message_header_value, chain!(
+          take_while1!(is_horizontal_space) ~
+    data: take_while1!(not_line_ending)     ~
+    line_ending,
+    
+    || data));
 
 fn message_header<'a>(input: &'a [u8]) -> IResult<&'a[u8], Header<'a>> {
-  do_parse!(input,
-    name:   take_while1!(is_token)       >>
-            char!(':')                   >>
-    values: many1!(message_header_value) >>
+  chain!(input,
+    name:   take_while1!(is_token) ~
+            char!(':') ~
+    values: many1!(message_header_value),
 
-    (Header {
+    || Header {
         name: name,
         value: values,
-    }))
+    })
 }
 
 fn request<'a>(input: &'a [u8]) -> IResult<&'a[u8], (Request<'a>, Vec<Header<'a>>)> {
-  do_parse!(input,
-    req: request_line           >>
-    h:   many1!(message_header) >>
-         line_ending            >>
+  chain!(input,
+    req: request_line           ~
+    h:   many1!(message_header) ~
+         line_ending,
 
-    (req, h))
+    || (req, h))
 }
 
 
@@ -130,7 +130,7 @@ fn parse(data:&[u8]) -> Option<Vec<(Request, Vec<Header>)>> {
           break;
         }
       },
-      IResult::Error(_) => return None/*panic!("{:?}", e)*/,
+      IResult::Error(e) => return None/*panic!("{:?}", e)*/,
       IResult::Incomplete(_) => return None/*panic!("Incomplete!")*/,
     }
   }
@@ -183,7 +183,7 @@ fn main() {
         let _ = file.read_to_end(&mut contents).unwrap();
     }
     
-    let buf = &contents[..];
+    let mut buf = &contents[..];
     loop { parse(buf); }
 }
 
diff --git a/benches/json.rs b/benches/json.rs
deleted file mode 100644
index 404d122..0000000
--- a/benches/json.rs
+++ /dev/null
@@ -1,122 +0,0 @@
-//#![feature(trace_macros)]
-#![feature(test)]
-extern crate test;
-
-#[macro_use]
-extern crate nom;
-
-use nom::{digit, alphanumeric};
-
-use test::Bencher;
-
-use std::str::{self,FromStr};
-use std::collections::HashMap;
-
-#[derive(Debug,PartialEq)]
-pub enum JsonValue {
-  Str(String),
-  Num(f32),
-  Array(Vec<JsonValue>),
-  Object(HashMap<String,JsonValue>)
-}
-
-// FIXME: since we already parsed a serie of digits and dots,
-// we know it is correct UTF-8. no need to use from_utf8 to
-// verify it is correct
-// FIXME: use alt_complete (implement ws for alt_complete)
-named!(unsigned_float <f32>, map_res!(
-  map_res!(
-    recognize!(
-      alt_complete!(
-        delimited!(digit, tag!("."), opt!(complete!(digit))) |
-        delimited!(opt!(digit), tag!("."), digit)            |
-        digit
-      )
-    ),
-    str::from_utf8
-  ),
-  FromStr::from_str
-));
-named!(float<f32>, map!(
-  pair!(
-    opt!(alt!(tag!("+") | tag!("-"))),
-    unsigned_float
-  ),
-  |(sign, value): (Option<&[u8]>, f32)| {
-    sign.and_then(|s| if s[0] == ('-' as u8) { Some(-1f32) } else { None }).unwrap_or(1f32) * value
-  }
-));
-
-//FIXME: verify how json strings are formatted
-named!(string<&str>,
-  delimited!(
-    tag!("\""),
-    map_res!(escaped!(call!(alphanumeric), '\\', is_a!("\"n\\")), str::from_utf8),
-    tag!("\"")
-  )
-);
-
-named!(array < Vec<JsonValue> >,
-  ws!(
-    delimited!(
-      tag!("["),
-      separated_list!(tag!(","), value),
-      tag!("]")
-    )
-  )
-);
-
-named!(key_value<(&str,JsonValue)>,
-  ws!(
-    separated_pair!(
-      string,
-      tag!(":"),
-      value
-    )
-  )
-);
-
-named!(hash< HashMap<String,JsonValue> >,
-  ws!(
-    map!(
-      delimited!(
-        tag!("{"),
-        separated_list!(tag!(","), key_value),
-        tag!("}")
-        ),
-      |tuple_vec| {
-        let mut h: HashMap<String, JsonValue> = HashMap::new();
-        for (k, v) in tuple_vec {
-          h.insert(String::from(k), v);
-        }
-        h
-      }
-    )
-  )
-);
-
-named!(value<JsonValue>,
-  ws!(
-    alt!(
-      hash   => { |h|   JsonValue::Object(h)            } |
-      array  => { |v|   JsonValue::Array(v)             } |
-      string => { |s|   JsonValue::Str(String::from(s)) } |
-      float  => { |num| JsonValue::Num(num)             }
-    )
-  )
-);
-
-#[bench]
-fn json_bench(b: &mut Bencher) {
-  let data = &b"  { \"a\"\t: 42,
-  \"b\": [ \"x\", \"y\", 12 ] ,
-  \"c\": { \"hello\" : \"world\" 
-  }
-  }  ";
-
-  //println!("data:\n{:?}", value(&data[..]));
-  b.iter(||{
-    value(&data[..])
-  });
-}
-
diff --git a/doc/upgrading_to_nom_2.md b/doc/upgrading_to_nom_2.md
deleted file mode 100644
index 0eb2abc..0000000
--- a/doc/upgrading_to_nom_2.md
+++ /dev/null
@@ -1,182 +0,0 @@
-% Upgrading to nom 2.0
-
-# Upgrading to nom 2.0
-
-The 2.0 release of nom adds a lot of new features, but it was also time for a big cleanup of badly named functions and macros, awkwardly written features and redundant functionality. So this release has some breaking changes, but most of them are harmless.
-
-## Simple VS verbose errors
-
-The error management system of nom 1.0 is powerful: it allows you to aggregate errors as you backtrack in the parser tree, and gives you clear indications about which combinators worked on which part of the input. Unfortunately, this slowed down the parsers a bit, since a lot of code was generated to drop the error list when it was not used.
-
-Not everybody uses that feature, so it was moved behind a compilation feature called "verbose-errors". For projects that do not use the `Err` enum and do not try to make their own custom error codes, it should build correctly out of the box. You can get between 30% and 50% perf gains on some parsers by updating to 2.0.
-
-For the parsers using it, you will probably get something like the following compilation error:
-
-```ignore
-error: no associated item named `Code` found for type `nom::ErrorKind<_>` in the current scope
-   --> src/metadata/parser.rs:309:31
-    |
-309 |     _       => IResult::Error(Err::Code(
-    |                               ^^^^^^^^^
-
-error: no associated item named `Code` found for type `nom::ErrorKind<_>` in the current scope
-   --> src/metadata/parser.rs:388:41
-    |
-388 |     let result_invalid = IResult::Error(Err::Code(nom::ErrorKind::Custom(
-    |                                         ^^^^^^^^^
-
-error: no associated item named `Position` found for type `nom::ErrorKind<_>` in the current scope
-  --> src/utility/macros.rs:16:41
-   |
-16 |             $crate::nom::IResult::Error($crate::nom::Err::Position(
-   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-  ::: src/metadata/parser.rs
-   |
-178|     bytes: skip_bytes!(14, 2) ~
-   |                      - in this macro invocation
-
-error: no associated item named `Position` found for type `nom::ErrorKind<_>` in the current scope
-   --> src/utility/macros.rs:16:41
-    |
-16  |             $crate::nom::IResult::Error($crate::nom::Err::Position(
-    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^
-    |
-   ::: src/metadata/parser.rs
-    |
-201 |     skip_bytes!(3),
-    |               - in this macro invocation
-```
-
-It is rather easy to fix, just activate the "verbose-errors" feature:
-
-```diff
--nom             = "^1.0.0"
-nom             = { version = "^2.0.0", features = ["verbose-errors"] }
-```
-
-If you only use `Err::Code` to make your custom error codes, you could switch to the simple errors, since it replaces the `Err<Input,E=u32>` enum, which contained an `ErrorKind<E=u32>`, with the `ErrorKind<E=u32>` type directly.
-
-## the eof function was removed
-
-The eof implementation was linked too much to the input type. This is now a macro combinator, called `eof!()`.
-
-If you see the following error, remove the `eof` import and replace all `eof` calls by `eof!()`.
-```ìgnore
-error[E0432]: unresolved import `nom::eof`
- --> src/parser.rs:1:20
-  |
-1 | use nom::{IResult, eof, line_ending, not_line_ending, space};
-  |                    ^^^ no `eof` in `nom`. Did you mean to use `eol`?
-```
-
-## parsers returning `Incomplete` instead of an error on empty input
-
-`alpha`, `digit`, `alphanumeric`, `hex_digit`, `oct_digit`, `space`, `multispace`, `sized_buffer` will now return `Incomplete` if they get an empty input. If you get the following error message, you can wrap those calls with `complete!`, a combinator that transforms `Incomplete` to `Error`.
-
-```
----- rules::literals::tests::case_invalid_hexadecimal_no_number stdout ----
-        thread 'rules::literals::tests::case_invalid_hexadecimal_no_number' panicked at 'assertion failed: `(left == right)` (left: `Incomplete(Unknown)`, right: `Error(Position(HexDigit, []))`)', source/rules/literals.rs:726
-```
-
-This change was implemented to make these basic parsers more consistent. Please note that parsing the basic elements of a format, like the alphabet of a token, is always very specific to that format, and those functions may not always fit your needs. In that case, you can easily make your own with [`take_while`](take_while.m.html) and a function that test for the characters or bytes you need.
-
-## `take_till!` iterates on bytes or chars, not on references to them
-
-The input types must now conform to a trait which requires changes to `take_till!`. If you get the following error:
-
-```ignore
-error[E0308]: mismatched types
-  --> src/linux/parser.rs:32:1
-   |
-32 | named!(parse_c_string, take_till!(is_nul_byte));
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected &u8, found u8
-   |
-   = note: expected type `&u8`
-   = note:    found type `u8`
-   = note: this error originates in a macro outside of the current crate
-```
-
-you can fix it with:
-
-```diff
--fn is_nul_byte(c: &u8) -> bool {
--    *c == 0x0
-+fn is_nul_byte(c: u8) -> bool {
-+    c == 0x0
-```
-
-## length_value, length_bytes refactoring
-
-The "length-value" pattern usually indicates that we get a length from the input, then take a slice of that size from the input, and convert that to a value of the type we need. The `length_value!` macro was using the length parameter to apply the value parser a specific number of times.
-
-- the `length_value!` macro was replaced by `length_count!`
-- the new `length_value!` macros takes a slice of the size obtained by the first child parser, then applies the second child parser on this slice. If the second parser returns incomplete, the parser fails
-- `length_data!` gets a length from its child parser, then returns a subslice of that length
-
-```ignore
-error[E0308]: mismatched types
-   --> src/tls.rs:378:37
-    |
-378 |                         cert_types: cert_types,
-    |                                     ^^^^^^^^^^ expected struct `std::vec::Vec`, found u8
-    |
-    = note: expected type `std::vec::Vec<u8>`
-    = note:    found type `u8`
-```
-
-```diff
- fn parse_tls_handshake_msg_certificaterequest( i:&[u8] ) -> IResult<&[u8], TlsMessageHandshake> {
-     chain!(i,
--        cert_types: length_value!(be_u8,be_u8) ~
-+        cert_types: length_count!(be_u8,be_u8) ~
-         sig_hash_algs_len: be_u16 ~
-```
-
-## error! does not exist anymore
-
-The `error!` macro, that was used to return a parsing error without backtracking through the parser tree, is now called `return_error!`. This change was done because the "log" crate also uses an `error!` macro, and they complained about the name conflict to nom instead of complaining to log, much to my dismay.
-
-The `add_error!` macro has also been renamed to `add_return_error!`.
-
-The compilation error you could get would be:
-
-```
-error: macro undefined: 'error!'
-   --> src/parser.rs:205:10
-    |
-205 |     error!(Custom(ParseError::InvalidData),
-    |          ^
-```
-
-It is fixed by:
-
-```diff
- named!(repeat<&str, u8, ParseError>,
--       error!(Custom(ParseError::RepeatNotNumeric), fix!(
-+       return_error!(Custom(ParseError::RepeatNotNumeric), fix!(
-        map_res!(flat_map!(take_s!(1), digit), FromStr::from_str))));
-```
-
-## the `offset()` method was moved to the `Offset` trait
-
-There is now an implementation of `Offset` for `&str`. The `HexDisplay` trait is now reserved for `&[u8]`.
-
-## `AsChar::is_0_to_9` is now `AsChar::is_dec_digit`
-
-This makes the method naming more consistent.
-
-## the number parsing macros with configurable endianness now take an enum as argument instead of a boolean
-
-Using a boolean to specify endianness was confusing, there is now the `nom::Endianness` enum:
-
-```diff
--    named!(be_tst32<u32>, u32!(true));
--    named!(le_tst32<u32>, u32!(false));
-+    named!(be_tst32<u32>, u32!(Endianness::Big));
-+    named!(le_tst32<u32>, u32!(Endianness::Little));
-```
-
-## end of line parsing
-
-There were different, incompatible ways to parse line endings. Now, the `eol`, `line_ending` and `not_line_ending` all have the same behaviour. First, test for '\n', then if it is not the right character, test for "\r\n". This fixes the length issues.
diff --git a/doc/FAQ.md b/docs/FAQ.md
similarity index 98%
rename from doc/FAQ.md
rename to docs/FAQ.md
index 409ba4b..fe4b934 100644
--- a/doc/FAQ.md
+++ b/docs/FAQ.md
@@ -1,8 +1,6 @@
-% FAQ
-
 ### The compiler indicates `error: expected an item keyword` then points to the function's return type in `named!`:
 
-```ignore
+```
 error: expected an item keyword
 named!(multi<Vec<&str>>, many0!( map_res!(tag!( "abcd" ), str::from_utf8) ) );
              ^~~
@@ -14,7 +12,7 @@ This happens because the macro processor mistakes `>>` for an operator. It will
 
 Typically, the error would look like this:
 
-```ignore
+```
 src/stream.rs:74:44: 74:64 error: the parameter type `E` may not live long enough [E0309]
 src/stream.rs:74     if let &ConsumerState::Done(_,ref o) = self.apply(consumer) {
                                                             ^~~~~~~~~~~~~~~~~~~~
diff --git a/doc/error_management.md b/docs/error_management.md
similarity index 71%
rename from doc/error_management.md
rename to docs/error_management.md
index 6c69040..668ca5f 100644
--- a/doc/error_management.md
+++ b/docs/error_management.md
@@ -1,5 +1,3 @@
-% Error management
-
 # Error management
 
 Parser combinators are useful tools to build parsers, but they are notoriously bad at error reporting. This happens because a tree of parser acts as a single parser, and the only error you get will come from the root parser.
@@ -27,8 +25,8 @@ fn main() {
 
 Result:
 
-```ignore
-Error(Position(0, [101, 102, 103, 104])) at l.5 by " tag ! ( "abcd" ) "
+```
+Error(Position(0, [101, 102, 103, 104])) at l.5 by ' tag ! ( "abcd" ) '
 ```
 
 The result sent by `dbg_dmp!` is slightly different:
@@ -46,8 +44,8 @@ fn main() {
 
 It will print, along with the result and the parser, a hexdump of the input buffer passed to the parser.
 
-```ignore
-Error(Position(0, [101, 102, 103, 104, 105, 106, 107, 108])) at l.5 by " tag ! ( "abcd" ) "
+```
+Error(Position(0, [101, 102, 103, 104, 105, 106, 107, 108])) at l.5 by ' tag ! ( "abcd" ) '
 00000000        65 66 67 68 69 6a 6b 6c         efghijkl
 ```
 
@@ -55,7 +53,7 @@ Error(Position(0, [101, 102, 103, 104, 105, 106, 107, 108])) at l.5 by " tag ! (
 
 As a reminder, here are the basic types of nom:
 
-```ignore
+```rust
 #[derive(Debug,PartialEq,Eq,Clone)]
 pub enum Err<P,E=u32>{
   Code(ErrorKind<E>),
@@ -84,67 +82,57 @@ An error in nom can be either:
 - an `ErrorKind<E>` error code, an input slice and a pointer to the next error
 
 `E` is the custom error type you can provide. Otherwise, it is an `u32` by default.
-If you need more information on the errors, or want to act on them in the calling code you can use the `return_error!` combinator. It takes an `ErrorKind<E>` error code and a parser as argument. If the child parser returns an error, it will wrap it in another error (a `NodePosition`) with its own error code, and return it directly.
+If you need more information on the errors, or want to act on them in the calling code you can use the `error!` combinator. It takes an `ErrorKind<E>` error code and a parser as argument. If the child parser returns an error, it will wrap it in another error (a `NodePosition`) with its own error code, and return it directly.
 
 ### Adding an error
 
-Sometimes, you want to provide an error code at a specific point in the parser tree. The `add_return_error!` macro can be used for this:
+Sometimes, you want to provide an error code at a specific point in the parser tree. The `add_error!` macro can be used for this:
 
-```ignore
-# #[macro_use] extern crate nom;
-# use nom::ErrorKind;
-# use nom::Err::*;
-# use nom::IResult::Error;
-named!(err_test,
-  preceded!(tag!("efgh"), add_return_error!(ErrorKind::Custom(42),
-      do_parse!(
-             tag!("ijkl")                                     >>
-        res: add_return_error!(ErrorKind::Custom(128), tag!("mnop")) >>
-        (res)
-      )
-    )
-));
-
-# fn main() {
-let a = &b"efghblah"[..];
-let blah = &b"blah"[..];
-
-let res_a = err_test(a);
-assert_eq!(res_a, Error(NodePosition(ErrorKind::Custom(42), blah, Box::new(Position(ErrorKind::Tag, blah)))));
-# }
+```rust
+    named!(err_test,
+      preceded!(tag!("efgh"), add_error!(ErrorKind::Custom(42),
+          do_parse!(
+                 tag!("ijkl")                                     >>
+            res: add_error!(ErrorKind::Custom(128), tag!("mnop")) >>
+            (res)
+          )    
+        )    
+    ));  
+    let a = &b"efghblah"[..];
+    let blah = &b"blah"[..];
+
+    let res_a = err_test(a);
+    assert_eq!(res_a, Error(NodePosition(ErrorKind::Custom(42), blah, Box::new(Position(ErrorKind::Tag, blah)))));
 ```
 
-If the child parser returns an error, `add_return_error!` will add its own at the head of the error chain.
+If the child parser returns an error, `add_error!` will add its own at the head of the error chain.
 
 ### Early returns
 
 This macro does an **early return**: it will not pass the error to the parent parser like other combinators, but will directly do a `return`, thus exiting the function. It works a bit like the "cut" operator in Prolog, in that there is no backtracking.
 
-If another `return_error!` call is present in the parent parsing chain, it will intercept the previously returned error, and wrap it with its own error code.
+If another `error!` call is present in the parent parsing chain, it will intercept the previously returned error, and wrap it with its own error code.
 
 Here is how it works in practice:
 
-```ignore
-# #[macro_use] extern crate nom;
-# use nom::ErrorKind;
-# use nom::IResult::Error;
-# use nom::Err::*;
+```rust
+use std::collections;
+
 named!(err_test, alt!(
   tag!("abcd") |
   preceded!(
     tag!("efgh"),
-    return_error!(
-      ErrorKind::Custom(42),
+    error!(
+      42,
       do_parse!(
              tag!("ijkl")              >>
-        res: return_error!(ErrorKind::Custom(128), tag!("mnop")) >>
+        res: error!(128, tag!("mnop")) >>
         (res)
       )
     )
   )
 ));
 
-# fn main() {
 let a = &b"efghblah"[..];
 let b = &b"efghijklblah"[..];
 
@@ -154,18 +142,17 @@ let blah = &b"blah"[..];
 let res_a = err_test(a);
 let res_b = err_test(b);
 
-assert_eq!(res_a, Error(NodePosition(ErrorKind::Custom(42), blah, Box::new(Position(ErrorKind::Custom(0), blah)))));
+assert_eq!(res_a, Error(NodePosition(42, blah, Box::new(Position(0, blah)))));
 assert_eq!(res_b, Error(
-  NodePosition(ErrorKind::Custom(42), &b"ijklblah"[..],
-    Box::new(NodePosition(ErrorKind::Custom(128), blah,
-      Box::new(Position(ErrorKind::Custom(0), blah))
+  NodePosition(42, &b"ijklblah"[..],
+    Box::new(NodePosition(128, blah,
+      Box::new(Position(0, blah))
     ))
   )
 ));
-# }
 ```
 
-With this mechanism, you get a chain of error codes and the corresponding positions in the input slice. If the `return_error!`calls are strategically placed, they can give a lot of information about what happened during parsing.
+With this mechanism, you get a chain of error codes and the corresponding positions in the input slice. If the `error!`calls are strategically placed, they can give a lot of information about what happened during parsing.
 
 ## Error pattern matching
 
@@ -175,54 +162,45 @@ Once you get a chain of errors with easily identifying codes, you probably want
 
 The `error_to_list` function can gather all of the error codes in a vector. This vector is essentially a signature of the parsing path and will let you distinguish between the different parsing errors.
 
-```ignore
-# #[macro_use] extern crate nom;
-use nom::{Err,ErrorKind,error_to_list};
+```rust
+use nom::util::error_to_list;
 
-fn error_to_string<P>(e: &Err<P>) -> &'static str {
-  let v:Vec<ErrorKind> = error_to_list(e);
+fn error_to_string<P>(e: Err<P>) -> &str {
+  let v:Vec<u32> = error_to_list(e);
   if &v[..] == [ErrorKind::Custom(42),ErrorKind::Tag] {
     "missing `ijkl` tag"
-  } else if &v[..] == [ErrorKind::Custom(42), ErrorKind::Custom(128), ErrorKind::Tag] {
+  } else if &v[..] == [ErrorKind::Custom(42), ErrorKind::Custom(128), ErrorKind::Tag] { 
     "missing `mnop` tag after `ijkl`"
   } else {
     "unrecognized error"
-  }
+  }    
 }
-
-# fn main() {}
 ```
 
 ### With slice patterns
 
 If you can use the *slice patterns* feature, you can easily match on errors this way:
 
-```ignore
+```rust
 #![feature(slice_patterns)]
-# #[macro_use] extern crate nom;
-use nom::{Err,ErrorKind,error_to_list};
+use nom::util::error_to_list;
 
-fn error_to_string<P>(e: &Err<P>) -> &'static str {
-  let v:Vec<ErrorKind> = error_to_list(e);
+fn error_to_string<P>(e: Err<P>) -> &str {
+  let v:Vec<u32> = error_to_list(e);
   match &v[..] {
     [ErrorKind::Custom(42),ErrorKind::Tag]       => "missing `ijkl` tag",
     [ErrorKind::Custom(42), ErrorKind::Custom(128), ErrorKind::Tag] => "missing `mnop` tag after `ijkl`",
     _            => "unrecognized error"
   }
 }
-# fn main() {}
 ```
 
 ### With box patterns
 
 If you can use box patterns, you can match directly on the error instead of filtering with `error_to_list`.
 
-```ignore
+```rust
 #![feature(box_patterns)]
-# #[macro_use] extern crate nom;
-# use nom::{add_error_pattern, error_to_list};
-# use nom::Err::*;
-# use nom::ErrorKind;
 
 use std::str;
 fn error_to_string<P>(e:Err<P>) -> String
@@ -244,7 +222,7 @@ This error reporting approach comes from the [Merr](https://github.com/pippijn/m
 
 To do this in nom, you use the `add_error_pattern` function:
 
-```ignore
+```rust
 fn add_error_pattern<'a,I,O>(h: &mut HashMap<Vec<ErrorKind>, &'a str>, res: IResult<I,O>, message: &'a str) -> bool
 ```
 
@@ -252,19 +230,16 @@ It takes as argument a mutable hashmap that will contain the correspondance betw
 
 To use it, you fill up the hashmap, before parsing, with know bad inputs (if you work with binary data, the `include_bytes!` macro might help you there). Then you can just get the error by passing the result of `error_to_list!` as key of the hashmap. 
 
-```ignore
-# #[macro_use] extern crate nom;
-use nom::{add_error_pattern, error_to_list};
-use nom::IResult;
+```rust
+use nom::util::{add_error_pattern, error_to_list};
 
-# fn main() {
 let mut err_map = collections::HashMap::new();
 add_error_pattern(
   &mut err_map,
   err_test(&b"efghpouet"[..]),
   "missing `ijkl` tag"
 );
-
+    
 add_error_pattern(
   &mut err_map,
   err_test(&b"efghijklpouet"[..]),
@@ -278,36 +253,34 @@ if let IResult::Error(e) = err_test(&b"efghblah"[..]) {
 if let IResult::Error(e) = err_test(&b"efghijklblah"[..]) {
   assert_eq!(err_map.get(&error_to_list(e)), Some(&"missing `mnop` tag after `ijkl`"));
 };
-# }
+
 ```
 
 ## Colored hexdump
 
 To help in format discovery, visual tools can sometimes help. The error chain system gives a correspondence between codes and positions in the input, so displaying what input has been handled by which parser is possible.
 
-Let's take a parser with a few more `return_error!` calls:
+Let's take a parser with a few more `error!` calls:
 
-```ignore
-# #[macro_use] extern crate nom;
+```rust
 named!(err_test, alt!(
   tag!("abcd") |
-  return_error!(ErrorKind::Custom(12),
-    preceded!(tag!("efgh"), return_error!(ErrorKind::Custom(42),
+  error!(12,
+    preceded!(tag!("efgh"), error!(42,
         do_parse!(
-               tag!("ijk")                      >>
-          res: return_error!(ErrorKind::Custom(128), tag!("mnop")) >>
+               tag!("ijk")               >>
+          res: error!(128, tag!("mnop")) >>
           (res)
         )
       )
     )
   )
 ));
-# fn main() {}
 ```
 
 We can then define the function `display_error` as follows:
 
-```ignore
+```rust
 use nom::util::{generate_colors,prepare_errors,print_codes,print_offsets};
 
 pub fn display_error<I,O>(input: &[u8], res: IResult<I,O>) {
@@ -331,7 +304,7 @@ The `nom::util::print_offsets` will print the input data in hexadecimal format,
 
 As an example, for this call:
 
-```ignore
+```rust
   let input = &b"efghijklblahblah"[..];
 
   display_error(input, err_test(input));
diff --git a/doc/home.md b/docs/home.md
similarity index 65%
rename from doc/home.md
rename to docs/home.md
index aba6163..c6bbe35 100644
--- a/doc/home.md
+++ b/docs/home.md
@@ -1,5 +1,3 @@
-% Home
-
 # Nom is an awesome parser combinators library in Rust
 
 To get started using nom, you can include it in your Rust projects from
@@ -9,7 +7,7 @@ To get started using nom, you can include it in your Rust projects from
 * [Gitter chat room](https://gitter.im/Geal/nom). You can also go to the #nom IRC
 channel on irc.mozilla.org, or ping 'geal' on Mozilla, Freenode, Geeknode or oftc IRC
 * [Tutorial about parsing ISO8601 dates](https://fnordig.de/2015/07/16/omnomnom-parsing-iso8601-dates-using-nom/)
-* [Making a new parser from scratch](making_a_new_parser_from_scratch.html)
+* [Making a new parser from scratch](https://github.com/Geal/nom/blob/master/docs/making_a_new_parser_from_scratch.md)
 (general tips on writing a parser and code architecture)
-* [How to handle parser errors](error_management.html)
-* [How nom's macro combinators work](how_nom_macros_work.html)
+* [How to handle parser errors](https://github.com/Geal/nom/blob/master/docs/error_management.md)
+* [How nom's macro combinators work](https://github.com/Geal/nom/blob/master/docs/how_nom_macros_work.md)
diff --git a/doc/how_nom_macros_work.md b/docs/how_nom_macros_work.md
similarity index 88%
rename from doc/how_nom_macros_work.md
rename to docs/how_nom_macros_work.md
index 7bbbd78..3147d1a 100644
--- a/doc/how_nom_macros_work.md
+++ b/docs/how_nom_macros_work.md
@@ -1,5 +1,3 @@
-% How nom macros work
-
 nom uses Rust macros heavily to provide a nice syntax and generate parsing code. This has multiple advantages:
 
 * it gives the apparence of combining functions without the runtime cost of closures
@@ -11,20 +9,12 @@ nom uses Rust macros heavily to provide a nice syntax and generate parsing code.
 Let's take the `opt!` macro as example: `opt!` returns `IResult<I,Option<O>>`, producing a `Some(o)` if the child parser succeeded, and None otherwise. Here is how you could use it:
 
 ```rust
-# #[macro_use] extern crate nom;
-# use nom::{IResult,digit};
-# fn main() {
-# }
 named!(opt_tag<Option<&[u8]>>, opt!(digit));
 ```
 
 And here is how it is defined:
 
 ```rust
-# #[macro_use] extern crate nom;
-# use nom::IResult;
-# fn main() {
-# }
 #[macro_export]
 macro_rules! opt(
   ($i:expr, $submac:ident!( $($args:tt)* )) => (
@@ -44,7 +34,7 @@ macro_rules! opt(
 
 To define a Rust macro, you indicate the name of the macro, then each pattern it is meant to apply to:
 
-```ignore
+```rust
 macro_rules! my_macro (
   (<pattern1>) => ( <generated code for pattern1> );
   (<pattern2>) => ( <generated code for pattern2> );
@@ -55,33 +45,25 @@ macro_rules! my_macro (
 
 The first thing you can see in `opt!` is that the pattern have an additional parameter that you do not use:
 
-```ignore
+```rust
 ($i:expr, $f:expr)
 ```
 
 while you call:
 
-```ignore
+```rust
 opt!(digit)
 ```
 
 This is the first trick of nom macros: the first parameter, usually `$i` or `$input`, is the input data, passed by the parent parser. The expression using `named!` will translate like this:
 
 ```rust
-# #[macro_use] extern crate nom;
-# use nom::digit;
-# fn main() {
-# }
 named!(opt_tag<Option<&[u8]>>, opt!(digit));
 ```
 
 to
 
 ```rust
-# #[macro_use] extern crate nom;
-# use nom::{IResult,digit};
-# fn main() {
-# }
 fn opt_tag(input:&[u8]) -> IResult<&[u8], Option<&[u8]>> {
   opt!(input, digit)
 }
@@ -92,10 +74,6 @@ This is how combinators hide all the plumbing: they receive the input automatica
 When you have multiple submacros, such as this example, the input is always passed to the first, top level combinator:
 
 ```rust
-# #[macro_use] extern crate nom;
-# use nom::IResult;
-# fn main() {
-# }
 macro_rules! multispaced (
     ($i:expr, $submac:ident!( $($args:tt)* )) => (
         delimited!($i, opt!(multispace), $submac!($($args)*), opt!(multispace));
@@ -112,7 +90,7 @@ Here, `delimited!` will apply `opt!(multispace)` on the input, and if successful
 
 The second trick you can see is the two patterns:
 
-```ignore
+```rust
 #[macro_export]
 macro_rules! opt(
   ($i:expr, $submac:ident!( $($args:tt)* )) => (
@@ -126,19 +104,19 @@ macro_rules! opt(
 
 The first pattern is used to receive a macro as child parser, like this:
 
-```ignore
+```rust
 opt!(tag!("abcd"))
 ```
 
 The second pattern can receive a function, and transforms it in a macro, then calls itself again. This is done to avoid repeating code. Applying `opt!` with `digit` as argument would be transformed from this:
 
-```ignore
+```rust
 opt!(digit)
 ```
 
 transformed with the second pattern:
 
-```ignore
+```rust
 opt!(call!(digit))
 ```
 
@@ -148,7 +126,7 @@ The `call!` macro transforms `call!(input, f)` into `f(i)`. If you need to pass
 
 The macro argument is decomposed into `$submac:ident!`, the macro's name and a bang, and `( $($args:tt)* )`, the tokens contained between the parenthesis of the macro call.
 
-```ignore
+```rust
 ($i:expr, $submac:ident!( $($args:tt)* )) => (
     {
       match $submac!($i, $($args)*) {
@@ -164,23 +142,23 @@ The macro is called with the input we got, as first argument, then we pattern ma
 
 As an example, see how the `preceded!` macro works:
 
-```ignore
-($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
-    {
+```rust
+($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => ( 
+    {    
       match $submac!($i, $($args)*) {
         $crate::IResult::Error(a)      => $crate::IResult::Error(a),
         $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
-        $crate::IResult::Done(i1,_)    => {
+        $crate::IResult::Done(i1,_)    => { 
           match $submac2!(i1, $($args2)*) {
             $crate::IResult::Error(a)      => $crate::IResult::Error(a),
             $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
-            $crate::IResult::Done(i2,o2)   => {
+            $crate::IResult::Done(i2,o2)   => { 
               $crate::IResult::Done(i2, o2)
-            }
-          }
-        },
-      }
-    }
+            }    
+          }    
+        },   
+      }    
+    }    
   );
 ```
 
diff --git a/doc/making_a_new_parser_from_scratch.md b/docs/making_a_new_parser_from_scratch.md
similarity index 93%
rename from doc/making_a_new_parser_from_scratch.md
rename to docs/making_a_new_parser_from_scratch.md
index fc7d90f..557c7e0 100644
--- a/doc/making_a_new_parser_from_scratch.md
+++ b/docs/making_a_new_parser_from_scratch.md
@@ -1,5 +1,3 @@
-% Making a new parser from scratch
-
 Writing a parser is a very fun, interactive process, but sometimes a daunting task. How do you test it? How to  see ambiguities in specifications?
 
 nom is designed to abstract data manipulation (counting array offsets, converting to structures, etc) while providing a safe, composable API. It also takes care of making the code easy to test and read, but it can be confusing at first, if you are not familiar with parser combinators, or if you are not used to Rust macros.
@@ -18,31 +16,17 @@ While it is tempting to insert the parsing code right inside the rest of the log
 
 Usually, you can separate the parsing functions in their own module, so you could have a `src/lib.rs`file containing this:
 
-
 ```rust
-# #[macro_use] extern crate nom;
-# use nom::IResult;
-# fn main() {
-  fn take_wrapper(input: &[u8], i: u8) -> IResult<&[u8],&[u8]> { take!(input, i * 10) }
-
-// will make a parser taking 20 bytes
-  named!(parser, apply!(take_wrapper, 2));
-# }
-
-```
-
-```ignore
 #[macro_use]
 extern crate nom;
+
 pub mod parser;
 ```
 
 And use the methods and structure from `parser` there. The `src/parser.rs` would then import nom functions and structures if needed:
 
 ```rust
-# #[macro_use] extern crate nom;
 use nom::{be_u16, be_u32};
-# fn main() {}
 ```
 
 # Writing a first parser
@@ -51,16 +35,13 @@ Let's parse a simple expression like `(12345)`. nom parsers are functions that u
 
 The `IResult` type depends on the input and output types, and an optional custom error type. This enum can either contain `Done(i,o)` containing the remaining input and the output value, an error, or an indication that more data is needed.
 
-```ignore
-# #[macro_use] extern crate nom;
-# use nom::{Err,Needed};
+```rust
 #[derive(Debug,PartialEq,Eq,Clone)]
 pub enum IResult<I,O,E=u32> {
   Done(I,O),
   Error(Err<I,E>),
   Incomplete(Needed)
 }
-# fn main() {}
 ```
 
 nom uses this type everywhere. Every combination of parsers will pattern match on this to know if it must return a value, an error, consume more data, etc. But this is done behind the scenes most of the time.
@@ -68,21 +49,16 @@ nom uses this type everywhere. Every combination of parsers will pattern match o
 nom provides a macro for function definition, called `named!`:
 
 ```rust
-# #[macro_use] extern crate nom;
-# fn main() {}
 named!(my_function( &[u8] ) -> &[u8], tag!("abcd"));
 
-named!(my_function2<&[u8], &[u8]>, tag!("abcd"));
+named!(my_function<&[u8], &[u8]>, tag!("abcd"));
 
-named!(my_function3, tag!("abcd"));
+named!(my_function, tag!("abcd"));
 ```
 
 But you could as easily define the function yourself like this:
 
 ```rust
-# #[macro_use] extern crate nom;
-# fn main() {}
-# use nom::IResult;
 fn my_function(input: &[u8]) -> IResult<&[u8], &[u8]> {
   tag!(input, "abcd")
 }
@@ -91,16 +67,12 @@ fn my_function(input: &[u8]) -> IResult<&[u8], &[u8]> {
 Note that we pass the input to the first parser in the manual definition, while we do not when we use `named!`. This is a macro trick specific to nom: every parser takes the input as first parameter, and the macros take care of giving the remaining input to the next parser. As an example, take a simple parser like the following one, which recognizes the word "hello" then takes the next 5 bytes:
 
 ```rust
-# #[macro_use] extern crate nom;
-# fn main() {}
 named!(prefixed, preceded!(tag!("hello"), take!(5)));
 ```
 
 Once the macros have expanded, this would correspond to:
 
-```ignore
-# #[macro_use] extern crate nom;
-# fn main() {}
+```rust
 fn prefixed(i: &[u8]) -> ::nom::IResult<&[u8], &[u8]> {
     {
         match {
@@ -179,7 +151,7 @@ Regular expression related macros are in [src/regexp.rs](https://github.com/Geal
 
 Once you have a parser function, a good trick is to test it on a lot of the samples you gathered, and integrate this to your unit tests. To that end, put all of the test files in a folder like `assets` and refer to test files like this:
 
-```ignore
+```rust
   #[test]
   fn header_test() {
     let data = include_bytes!("../assets/axolotl-piano.gif");
@@ -191,7 +163,7 @@ The `include_bytes!` macro (provided by Rust's standard library) will integrate
 
 If your parser handles textual data, you can just use a lot of strings directly in the test, like this:
 
-```ignore
+```rust
 #[test]
 fn factor_test() {
   assert_eq!(factor(&b"3"[..]),       IResult::Done(&b""[..], 3));
@@ -207,7 +179,7 @@ The more samples and test cases you get, the more you can experiment with your p
 
 While Rust macros are really useful to get a simpler syntax, they can sometimes give cryptic errors. As an example, `named!(manytag, many0!(take!(5)));` would result in the following error:
 
-```ignore
+```
 <nom macros>:6:38: 6:41 error: mismatched types:
  expected `&[u8]`,
     found `collections::vec::Vec<&[u8]>`
@@ -229,15 +201,15 @@ There are a few tools you can use to debug how code is generated.
 
 The `trace_macros` feature show how macros are applied. To use it, add `#![feature(trace_macros)]` at the top of your file (you need Rust nightly for this), then apply it like this:
 
-```ignore
+```rust
 trace_macros!(true);
-named!(manytag< Vec<&[u8]> >, many0!(take!(5)));
+named!(manytag, many0!(take!(5)));
 trace_macros!(false);
 ```
 
 It will result in the following output during compilation:
 
-```ignore
+```
 named! { manytag , many0 ! ( take ! ( 5 ) ) }
 many0! { i , take ! ( 5 ) }
 take! { input , 5 }
@@ -250,9 +222,7 @@ rustc can show how code is expanded with the option `--pretty=expanded`. If you
 It will print the `manytag` function like this:
 
 ```rust
-# #[macro_use] extern crate nom;
-# fn main() {}
-fn manytag(i: &[u8]) -> ::nom::IResult<&[u8], Vec<&[u8]>> {
+fn manytag(i: &[u8]) -> ::nom::IResult<&[u8], &[u8]> {
     {
         let mut res = Vec::new();
         let mut input = i;
diff --git a/doc/upgrading_to_nom_1.md b/docs/upgrading_to_nom_1.md
similarity index 97%
rename from doc/upgrading_to_nom_1.md
rename to docs/upgrading_to_nom_1.md
index 2c3a201..02a56aa 100644
--- a/doc/upgrading_to_nom_1.md
+++ b/docs/upgrading_to_nom_1.md
@@ -1,5 +1,3 @@
-% Upgrading to nom 1.0
-
 The 1.0 release of nom is one of the biggest since the beginning of the project. Its goal was to rework some core parts to be more flexible, and clean code that was awkward or unclear. This resulted in breaking changes, that I hope will not happen again in the future (but hey, we are Rust developers, breaking changes are FUN for us!).
 
 Here are a few tips to update your code to run with nom 1.0:
@@ -8,7 +6,7 @@ Here are a few tips to update your code to run with nom 1.0:
 
 `nom::Err` now depends on two generic types, the position `P` and the error type `E`:
 
-```ignore
+```rust
 pub enum Err<P,E=u32>{
   Code(ErrorKind<E>),
   Node(ErrorKind<E>, Box<Err<P,E>>),
@@ -19,7 +17,7 @@ pub enum Err<P,E=u32>{
 
 The default error type is `u32` to keep some compatibility with older code. To update your code, the first step is to **replace all usages of `nom::ErrorCode` by `nom::ErrorKind`**. `ErrorKind` is now an enum that contains the same instances as the previous `ErrorCode`, with an additional generic parameter:
 
-```ignore
+```rust
 pub enum ErrorKind<E=u32> {
   Custom(E),
   Tag,
@@ -32,7 +30,7 @@ pub enum ErrorKind<E=u32> {
 
 `ErrorKind::Custom` is where you will store your custom error type. Note that default nom parsers like `alphabetic` use `u32` as custom type, so you may need to translate the error types coming from those parsers like this:
 
-```ignore
+```rust
 fix_error!(CustomErrorType, alphabetic)
 ```
 
@@ -42,7 +40,7 @@ Since the error type is now an enum instead of a `u32`, you can now **replace an
 
 The error type is now completely generic over the input type, so the lifetime that appeared in `IResult` is not necessary anymore. It changes function declarations like this:
 
-```ignore
+```rust
 fn parse_status<'a>(i: &'a [u8]) -> IResult<'a, &'a [u8], Status>
 
 // To this:
diff --git a/src/branch.rs b/src/branch.rs
index 4e1d7d7..4028099 100644
--- a/src/branch.rs
+++ b/src/branch.rs
@@ -1,48 +1,98 @@
-/// `alt!(I -> IResult<I,O> | I -> IResult<I,O> | ... | I -> IResult<I,O> ) => I -> IResult<I, O>`
-/// try a list of parsers, return the result of the first successful one
+/// Try a list of parsers and return the result of the first successful one
 ///
-/// If one of the parser returns Incomplete, alt will return Incomplete, to retry
+/// ```rust,ignore
+/// alt!(I -> IResult<I,O> | I -> IResult<I,O> | ... | I -> IResult<I,O> ) => I -> IResult<I, O>
+/// ```
+/// All the parsers must have the same return type.
+///
+/// If one of the parsers returns `Incomplete`, `alt!` will return `Incomplete`, to retry
 /// once you get more input. Note that it is better for performance to know the
-/// minimum size of data you need before you get into alt.
+/// minimum size of data you need before you get into `alt!`.
+///
+/// The `alt!` combinator is used in the following way:
+///
+/// ```rust,ignore
+/// alt!(parser_1 | parser_2 | ... | parser_n)
+/// ```
+///
+/// # Basic example
 ///
 /// ```
 /// # #[macro_use] extern crate nom;
-/// # use nom::IResult::Done;
 /// # fn main() {
-///  named!( test, alt!( tag!( "abcd" ) | tag!( "efgh" ) ) );
-///  let r1 = test(b"abcdefgh");
-///  assert_eq!(r1, Done(&b"efgh"[..], &b"abcd"[..]));
-///  let r2 = test(&b"efghijkl"[..]);
-///  assert_eq!(r2, Done(&b"ijkl"[..], &b"efgh"[..]));
+///  // Create a parser that will match either "dragon" or "beast"
+///  named!( dragon_or_beast, alt!( tag!( "dragon" ) | tag!( "beast" ) ) );
+///
+///  // Given the input "dragon slayer", the parser will match "dragon"
+///  // and the rest will be " slayer"
+///  let (rest, result) = dragon_or_beast(b"dragon slayer").unwrap();
+///  assert_eq!(result, b"dragon");
+///  assert_eq!(rest, b" slayer");
+///
+///  // Given the input "beast of Gevaudan", the parser will match "beast"
+///  // and the rest will be " of Gevaudan"
+///  let (rest, result) = dragon_or_beast(&b"beast of Gevaudan"[..]).unwrap();
+///  assert_eq!(result, b"beast");
+///  assert_eq!(rest, b" of Gevaudan");
 ///  # }
 /// ```
 ///
-/// There is another syntax for alt allowing a block to manipulate the result:
+/// # Manipulate results
+///
+/// There exists another syntax for `alt!` that gives you the ability to
+/// manipulate the result from each parser:
 ///
 /// ```
 /// # #[macro_use] extern crate nom;
 /// # use nom::IResult::Done;
 /// # fn main() {
-///     #[derive(Debug,PartialEq,Eq)]
-///     enum Tagged {
-///       Abcd,
-///       Efgh,
-///       Took(usize)
-///     }
-///     named!(test<Tagged>, alt!(
-///         tag!("abcd") => { |_|          Tagged::Abcd }
-///       | tag!("efgh") => { |_|          Tagged::Efgh }
-///       | take!(5)     => { |res: &[u8]| Tagged::Took(res.len()) } // the closure takes the result as argument if the parser is successful
-///     ));
-///     let r1 = test(b"abcdefgh");
-///     assert_eq!(r1, Done(&b"efgh"[..], Tagged::Abcd));
-///     let r2 = test(&b"efghijkl"[..]);
-///     assert_eq!(r2, Done(&b"ijkl"[..], Tagged::Efgh));
-///     let r3 = test(&b"mnopqrst"[..]);
-///     assert_eq!(r3, Done(&b"rst"[..],  Tagged::Took(5)));
+/// #
+/// // We create an enum to represent our creatures
+/// #[derive(Debug,PartialEq,Eq)]
+/// enum Creature {
+///     Dragon,
+///     Beast,
+///     Unknown(usize)
+/// }
+///
+/// // Let's make a helper function that returns true when not a space
+/// // we are required to do this because the `take_while!` macro is limited
+/// // to idents, so we can't negate `ìs_space` at the call site
+/// fn is_not_space(c: u8) -> bool { ! nom::is_space(c) }
+///
+/// // Our parser will return the `Dragon` variant when matching "dragon",
+/// // the `Beast` variant when matching "beast" and otherwise it will consume
+/// // the input until a space is found and return an `Unknown` creature with
+/// // the size of it's name.
+/// named!(creature<Creature>, alt!(
+///     tag!("dragon")            => { |_| Creature::Dragon } |
+///     tag!("beast")             => { |_| Creature::Beast }  |
+///     take_while!(is_not_space) => { |r: &[u8]| Creature::Unknown(r.len()) }
+///     // the closure takes the result as argument if the parser is successful
+/// ));
+///
+/// // Given the input "dragon slayer" the parser will return `Creature::Dragon`
+/// // and the rest will be " slayer"
+/// let (rest, result) = creature(b"dragon slayer").unwrap();
+/// assert_eq!(result, Creature::Dragon);
+/// assert_eq!(rest, b" slayer");
+///
+/// // Given the input "beast of Gevaudan" the parser will return `Creature::Beast`
+/// // and the rest will be " of Gevaudan"
+/// let (rest, result) = creature(b"beast of Gevaudan").unwrap();
+/// assert_eq!(result, Creature::Beast);
+/// assert_eq!(rest, b" of Gevaudan");
+///
+/// // Given the input "demon hunter" the parser will return `Creature::Unkown(5)`
+/// // and the rest will be " hunter"
+/// let (rest, result) = creature(b"demon hunter").unwrap();
+/// assert_eq!(result, Creature::Unknown(5));
+/// assert_eq!(rest, b" hunter");
 /// # }
 /// ```
 ///
+/// # Behaviour of `alt!`
+///
 /// **BE CAREFUL** there is a case where the behaviour of `alt!` can be confusing:
 ///
 /// when the alternatives have different lengths, like this case:
@@ -104,7 +154,7 @@
 ///        tag!("ab"),
 ///        alt!(
 ///          tag!( "cd" ) |
-///          eof!()
+///          eof
 ///        )
 ///      )
 ///    | tag!( "ef" )
@@ -192,11 +242,26 @@ macro_rules! alt (
   );
 );
 
-/// This is a combination of the `alt!` and `complete!` combinators. Rather
-/// than returning `Incomplete` on partial input, `alt_complete!` will try the
-/// next alternative in the chain. You should use this only if you know you
+/// Is equivalent to the `alt!` combinator, except that it will not return `Incomplete`
+/// when one of the constituting parsers returns `Incomplete`. Instead, it will try the
+/// next alternative in the chain.
+///
+/// You should use this combinator only if you know you
 /// will not receive partial input for the rules you're trying to match (this
 /// is almost always the case for parsing programming languages).
+///
+/// ```rust,ignore
+/// alt_complete!(I -> IResult<I,O> | I -> IResult<I,O> | ... | I -> IResult<I,O> ) => I -> IResult<I, O>
+/// ```
+/// All the parsers must have the same return type.
+///
+/// If one of the parsers return `Incomplete`, `alt_complete!` will try the next alternative.
+/// If there is no other parser left to try, an `Error` will be returned.
+///
+/// ```rust,ignore
+/// alt_complete!(parser_1 | parser_2 | ... | parser_n)
+/// ```
+/// **For more in depth examples, refer to the documentation of `alt!`**
 #[macro_export]
 macro_rules! alt_complete (
   // Recursive rules (must include `complete!` around the head)
@@ -454,18 +519,6 @@ macro_rules! succ (
   (5, $submac:ident ! ($($rest:tt)*)) => ($submac!(6, $($rest)*));
   (6, $submac:ident ! ($($rest:tt)*)) => ($submac!(7, $($rest)*));
   (7, $submac:ident ! ($($rest:tt)*)) => ($submac!(8, $($rest)*));
-  (8, $submac:ident ! ($($rest:tt)*)) => ($submac!(9, $($rest)*));
-  (9, $submac:ident ! ($($rest:tt)*)) => ($submac!(10, $($rest)*));
-  (10, $submac:ident ! ($($rest:tt)*)) => ($submac!(11, $($rest)*));
-  (11, $submac:ident ! ($($rest:tt)*)) => ($submac!(12, $($rest)*));
-  (12, $submac:ident ! ($($rest:tt)*)) => ($submac!(13, $($rest)*));
-  (13, $submac:ident ! ($($rest:tt)*)) => ($submac!(14, $($rest)*));
-  (14, $submac:ident ! ($($rest:tt)*)) => ($submac!(15, $($rest)*));
-  (15, $submac:ident ! ($($rest:tt)*)) => ($submac!(16, $($rest)*));
-  (16, $submac:ident ! ($($rest:tt)*)) => ($submac!(17, $($rest)*));
-  (17, $submac:ident ! ($($rest:tt)*)) => ($submac!(18, $($rest)*));
-  (18, $submac:ident ! ($($rest:tt)*)) => ($submac!(19, $($rest)*));
-  (19, $submac:ident ! ($($rest:tt)*)) => ($submac!(20, $($rest)*));
 );
 
 // HACK: for some reason, Rust 1.11 does not accept $res.$it in
@@ -482,19 +535,6 @@ macro_rules! acc (
   (5, $tup:expr) => ($tup.5);
   (6, $tup:expr) => ($tup.6);
   (7, $tup:expr) => ($tup.7);
-  (8, $tup:expr) => ($tup.8);
-  (9, $tup:expr) => ($tup.9);
-  (10, $tup:expr) => ($tup.10);
-  (11, $tup:expr) => ($tup.11);
-  (12, $tup:expr) => ($tup.12);
-  (13, $tup:expr) => ($tup.13);
-  (14, $tup:expr) => ($tup.14);
-  (15, $tup:expr) => ($tup.15);
-  (16, $tup:expr) => ($tup.16);
-  (17, $tup:expr) => ($tup.17);
-  (18, $tup:expr) => ($tup.18);
-  (19, $tup:expr) => ($tup.19);
-  (20, $tup:expr) => ($tup.20);
 );
 
 #[doc(hidden)]
diff --git a/src/bytes.rs b/src/bytes.rs
index 3ab8a97..9e2acbf 100644
--- a/src/bytes.rs
+++ b/src/bytes.rs
@@ -94,7 +94,7 @@ macro_rules! is_not(
   ($input:expr, $arr:expr) => (
     {
       use $crate::InputLength;
-      use $crate::InputIter;
+      use $crate::IterIndices;
       use $crate::FindToken;
       use $crate::Slice;
 
@@ -136,7 +136,7 @@ macro_rules! is_a (
   ($input:expr, $arr:expr) => (
     {
       use $crate::InputLength;
-      use $crate::InputIter;
+      use $crate::IterIndices;
       use $crate::FindToken;
       use $crate::Slice;
 
@@ -168,7 +168,7 @@ macro_rules! is_a (
 /// # use nom::IResult::Done;
 /// # use nom::alpha;
 /// # fn main() {
-///  named!(esc, escaped!(call!(alpha), '\\', one_of!("\"n\\")));
+///  named!(esc, escaped!(call!(alpha), '\\', is_a!("\"n\\")));
 ///  assert_eq!(esc(&b"abcd"[..]), Done(&b""[..], &b"abcd"[..]));
 ///  assert_eq!(esc(&b"ab\\\"cd"[..]), Done(&b""[..], &b"ab\\\"cd"[..]));
 /// # }
@@ -180,43 +180,40 @@ macro_rules! escaped (
     {
       use $crate::InputLength;
       use $crate::Slice;
-      let cl = || -> $crate::IResult<_,_,_> {
+      let cl = || {
         use $crate::Offset;
         let mut index  = 0;
 
         while index < $i.input_len() {
-          match $normal!($i.slice(index..), $($args)*) {
-            $crate::IResult::Done(i, _) => {
-              if i.is_empty() {
-                return $crate::IResult::Done($i.slice($i.input_len()..), $i)
-              } else {
-                index = $i.offset(i);
-              }
-            },
-            $crate::IResult::Incomplete(i) => {
-              return $crate::IResult::Incomplete(i)
-            },
-            $crate::IResult::Error(e) => {
-              if $i[index] == $control_char as u8 {
-                if index + 1 >= $i.input_len() {
-                  return $crate::IResult::Error(error_node_position!($crate::ErrorKind::Escaped, $i.slice(index..), e));
-                } else {
-                  match $escapable!($i.slice(index+1..), $($args2)*) {
-                    $crate::IResult::Done(i,_) => {
-                      if i.is_empty() {
-                        return $crate::IResult::Done($i.slice($i.input_len()..), $i)
-                      } else {
-                        index = $i.offset(i);
-                      }
-                    },
-                    $crate::IResult::Incomplete(i) => return $crate::IResult::Incomplete(i),
-                    $crate::IResult::Error(e2)     => return $crate::IResult::Error(e2)
+          if let $crate::IResult::Done(i,_) = $normal!($i.slice(index..), $($args)*) {
+            if i.is_empty() {
+              return $crate::IResult::Done($i.slice($i.input_len()..), $i)
+            } else {
+              index = $i.offset(i);
+            }
+            //FIXME: should use index() from IterIndices?
+          } else if $i[index] == $control_char as u8 {
+            if index + 1 >= $i.input_len() {
+              return $crate::IResult::Error(error_position!($crate::ErrorKind::Escaped,$i.slice(index..)));
+            } else {
+              match $escapable!($i.slice(index+1..), $($args2)*) {
+                $crate::IResult::Done(i,_) => {
+                  if i.is_empty() {
+                    return $crate::IResult::Done($i.slice($i.input_len()..), $i)
+                  } else {
+                    index = $i.offset(i);
                   }
-                }
-              } else {
-                return $crate::IResult::Done($i.slice(index..), $i.slice(..index));
+                },
+                $crate::IResult::Incomplete(i) => return $crate::IResult::Incomplete(i),
+                $crate::IResult::Error(e)      => return $crate::IResult::Error(e)
               }
             }
+          } else {
+            if index == 0 {
+              return $crate::IResult::Error(error_position!($crate::ErrorKind::Escaped,$i.slice(index..)))
+            } else {
+              return $crate::IResult::Done($i.slice(index..), $i.slice(..index))
+            }
           }
         }
         $crate::IResult::Done(&$i[index..], &$i[..index])
@@ -257,7 +254,7 @@ macro_rules! escaped (
 /// matches a byte string with escaped characters.
 ///
 /// The first argument matches the normal characters (it must not match the control character), the second argument is the control character (like `\` in most languages),
-/// the third argument matches the escaped characters and transforms them.
+/// the third argument matches the escaped characters and trnasforms them.
 ///
 /// As an example, the chain `abc\tdef` could be `abc    def` (it also consumes the control character)
 ///
@@ -386,7 +383,7 @@ macro_rules! escaped_transform (
 macro_rules! take_while (
   ($input:expr, $submac:ident!( $($args:tt)* )) => (
     {
-      use $crate::{InputLength,InputIter,Slice};
+      use $crate::{InputLength,IterIndices,Slice};
       let input = $input;
 
       match input.position(|c| !$submac!(c, $($args)*)) {
@@ -416,7 +413,7 @@ macro_rules! take_while1 (
       let input = $input;
 
       use $crate::InputLength;
-      use $crate::InputIter;
+      use $crate::IterIndices;
       use $crate::Slice;
       if input.input_len() == 0 {
         $crate::IResult::Error(error_position!($crate::ErrorKind::TakeWhile1,input))
@@ -449,7 +446,7 @@ macro_rules! take_till (
       let input = $input;
 
       use $crate::InputLength;
-      use $crate::InputIter;
+      use $crate::IterIndices;
       use $crate::Slice;
       match input.position(|c| $submac!(c, $($args)*)) {
         Some(n) => $crate::IResult::Done(input.slice(n..), input.slice(..n)),
@@ -481,15 +478,15 @@ macro_rules! take_till (
 macro_rules! take (
   ($i:expr, $count:expr) => (
     {
-      use $crate::InputIter;
+      use $crate::IterIndices;
       use $crate::Slice;
       let input = $i;
 
       let cnt = $count as usize;
 
-      let res: $crate::IResult<_,_> = match input.slice_index(cnt) {
+      let res: $crate::IResult<_,_> = match input.index(cnt) {
         None        => $crate::IResult::Incomplete($crate::Needed::Size(cnt)),
-        //FIXME: use the InputTake trait
+        //FIXME: use the IterTake trait
         Some(index) => $crate::IResult::Done(input.slice(index..), input.slice(..index))
       };
       res
@@ -571,7 +568,7 @@ macro_rules! take_until_either_and_consume (
   ($input:expr, $arr:expr) => (
     {
       use $crate::InputLength;
-      use $crate::InputIter;
+      use $crate::IterIndices;
       use $crate::FindToken;
       use $crate::Slice;
 
@@ -602,7 +599,7 @@ macro_rules! take_until_either (
   ($input:expr, $arr:expr) => (
     {
       use $crate::InputLength;
-      use $crate::InputIter;
+      use $crate::IterIndices;
       use $crate::FindToken;
       use $crate::Slice;
 
@@ -627,8 +624,8 @@ macro_rules! take_until_either (
   );
 );
 
-/// `length_bytes!(&[T] -> IResult<&[T], nb>) => &[T] -> IResult<&[T], &[T]>`
-/// Gets a number from the first parser, then extracts that many bytes from the
+/// `length_bytes!(&[T] -> IResult<&[T], nb>) => &[T] -> IResult<&[T], &[T]>
+/// gets a number from the first parser, then extracts that many bytes from the
 /// remaining stream
 #[macro_export]
 macro_rules! length_bytes(
@@ -664,50 +661,6 @@ mod tests {
   use util::ErrorKind;
   use nom::{alpha, digit, hex_digit, oct_digit, alphanumeric, space, multispace};
 
-  macro_rules! one_of (
-    ($i:expr, $inp: expr) => (
-      {
-        if $i.is_empty() {
-          $crate::IResult::Incomplete::<_, _>($crate::Needed::Size(1))
-        } else {
-          #[inline(always)]
-          fn as_bytes<T: $crate::AsBytes>(b: &T) -> &[u8] {
-            b.as_bytes()
-          }
-
-          let expected = $inp;
-          let bytes = as_bytes(&expected);
-          one_of_bytes!($i, bytes)
-        }
-      }
-    );
-  );
-
-  macro_rules! one_of_bytes (
-    ($i:expr, $bytes: expr) => (
-      {
-        if $i.is_empty() {
-          $crate::IResult::Incomplete::<_, _>($crate::Needed::Size(1))
-        } else {
-          let mut found = false;
-
-          for &i in $bytes {
-            if i == $i[0] {
-              found = true;
-              break;
-            }
-          }
-
-          if found {
-            $crate::IResult::Done(&$i[1..], $i[0] as char)
-          } else {
-            $crate::IResult::Error(error_position!($crate::ErrorKind::OneOf, $i))
-          }
-        }
-      }
-    );
-  );
-
   #[test]
   fn is_a() {
     named!(a_or_b, is_a!(&b"ab"[..]));
@@ -751,7 +704,7 @@ mod tests {
   #[allow(unused_variables)]
   #[test]
   fn escaping() {
-    named!(esc, escaped!(call!(alpha), '\\', one_of!("\"n\\")));
+    named!(esc, escaped!(call!(alpha), '\\', is_a!("\"n\\")));
     assert_eq!(esc(&b"abcd"[..]), Done(&b""[..], &b"abcd"[..]));
     assert_eq!(esc(&b"ab\\\"cd"[..]), Done(&b""[..], &b"ab\\\"cd"[..]));
     assert_eq!(esc(&b"\\\"abcd"[..]), Done(&b""[..], &b"\\\"abcd"[..]));
@@ -761,9 +714,6 @@ mod tests {
       error_position!(ErrorKind::Escaped, &b"\\"[..]))));
     assert_eq!(esc(&b"AB\\A"[..]), Error(error_node_position!(ErrorKind::Escaped, &b"AB\\A"[..],
       error_position!(ErrorKind::IsA, &b"A"[..]))));
-
-    named!(esc2, escaped!(call!(digit), '\\', one_of!("\"n\\")));
-    assert_eq!(esc2(&b"12\\nnn34"[..]), Done(&b"nn34"[..], &b"12\\n"[..]));
   }
 
   #[cfg(feature = "verbose-errors")]
@@ -998,25 +948,10 @@ mod tests {
     assert_eq!(test(&b"aBCdefgh"[..]), Done(&b"efgh"[..], &b"aBCd"[..]));
     assert_eq!(test(&b"abcdefgh"[..]), Done(&b"efgh"[..], &b"abcd"[..]));
     assert_eq!(test(&b"ABCDefgh"[..]), Done(&b"efgh"[..], &b"ABCD"[..]));
-    assert_eq!(test(&b"ab"[..]), Incomplete(Needed::Size(4)));
-    assert_eq!(test(&b"Hello"[..]), Error(error_code!(ErrorKind::Tag)));
-    assert_eq!(test(&b"Hel"[..]), Error(error_code!(ErrorKind::Tag)));
-
-    named!(test2<&str, &str>, tag_no_case!("ABcd"));
-    assert_eq!(test2("aBCdefgh"), Done("efgh", "aBCd"));
-    assert_eq!(test2("abcdefgh"), Done("efgh", "abcd"));
-    assert_eq!(test2("ABCDefgh"), Done("efgh", "ABCD"));
-    assert_eq!(test2("ab"), Incomplete(Needed::Size(4)));
-    assert_eq!(test2("Hello"), Error(error_code!(ErrorKind::Tag)));
-    assert_eq!(test2("Hel"), Error(error_code!(ErrorKind::Tag)));
-  }
 
-  #[test]
-  fn tag_fixed_size_array() {
-    named!(test, tag!([0x42]));
-    named!(test2, tag!(&[0x42]));
-    let input = vec!(0x42, 0x00);
-    assert_eq!(test(&input), Done(&b"\x00"[..], &b"\x42"[..]));
-    assert_eq!(test2(&input), Done(&b"\x00"[..], &b"\x42"[..]));
+    named!(test2, tag_no_case!("ABcd"));
+    assert_eq!(test2(&b"aBCdefgh"[..]), Done(&b"efgh"[..], &b"aBCd"[..]));
+    assert_eq!(test2(&b"abcdefgh"[..]), Done(&b"efgh"[..], &b"abcd"[..]));
+    assert_eq!(test2(&b"ABCDefgh"[..]), Done(&b"efgh"[..], &b"ABCD"[..]));
   }
 }
diff --git a/src/internal.rs b/src/internal.rs
index 04b2f87..f8c837d 100644
--- a/src/internal.rs
+++ b/src/internal.rs
@@ -228,35 +228,60 @@ impl<'a,I,E> GetOutput<&'a str> for IResult<I,&'a str,E> {
   }
 }
 
+#[cfg(not(feature = "core"))]
+#[cfg(feature = "verbose-errors")]
+use std::any::Any;
+#[cfg(not(feature = "core"))]
+#[cfg(feature = "verbose-errors")]
+use std::{error,fmt};
+#[cfg(not(feature = "core"))]
+#[cfg(feature = "verbose-errors")]
+use std::fmt::Debug;
+#[cfg(not(feature = "core"))]
+#[cfg(feature = "verbose-errors")]
+impl<P:Debug+Any,E:Debug+Any> error::Error for Err<P,E> {
+  fn description(&self) -> &str {
+    let kind = match *self {
+      Err::Code(ref e) | Err::Node(ref e, _) | Err::Position(ref e, _) | Err::NodePosition(ref e, _, _) => e
+    };
+    kind.description()
+  }
+}
+
+#[cfg(not(feature = "core"))]
+#[cfg(feature = "verbose-errors")]
+impl<P:fmt::Debug,E:fmt::Debug> fmt::Display for Err<P,E> {
+  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    match *self {
+      Err::Code(ref e) | Err::Node(ref e, _) => {
+        write!(f, "{:?}", e)
+      },
+      Err::Position(ref e, ref p) | Err::NodePosition(ref e, ref p, _) => {
+        write!(f, "{:?}:{:?}", p, e)
+      }
+    }
+  }
+}
+
 #[cfg(feature = "verbose-errors")]
-/// creates a parse error from a `nom::ErrorKind`
 #[macro_export]
 macro_rules! error_code(
   ($code:expr) => ($crate::Err::Code($code));
 );
 
 #[cfg(not(feature = "verbose-errors"))]
-/// creates a parse error from a `nom::ErrorKind`
 #[macro_export]
 macro_rules! error_code(
   ($code:expr) => ($code);
 );
 
 #[cfg(feature = "verbose-errors")]
-/// creates a parse error from a `nom::ErrorKind`
-/// and the next error in the parsing tree.
-/// if "verbose-errors" is not activated,
-/// it default to only the error code
 #[macro_export]
 macro_rules! error_node(
   ($code:expr, $next:expr) => ($crate::Err::Node($code, ::std::boxed::Box::new($next)));
 );
 
 #[cfg(not(feature = "verbose-errors"))]
-/// creates a parse error from a `nom::ErrorKind`
-/// and the next error in the parsing tree.
-/// if "verbose-errors" is not activated,
-/// it default to only the error code
 #[allow(unused_variables)]
 #[macro_export]
 macro_rules! error_node(
@@ -264,20 +289,12 @@ macro_rules! error_node(
 );
 
 #[cfg(feature = "verbose-errors")]
-/// creates a parse error from a `nom::ErrorKind`
-/// and the position in the input
-/// if "verbose-errors" is not activated,
-/// it default to only the error code
 #[macro_export]
 macro_rules! error_position(
   ($code:expr, $input:expr) => ($crate::Err::Position($code, $input));
 );
 
 #[cfg(not(feature = "verbose-errors"))]
-/// creates a parse error from a `nom::ErrorKind`
-/// and the position in the input
-/// if "verbose-errors" is not activated,
-/// it default to only the error code
 #[allow(unused_variables)]
 #[macro_export]
 macro_rules! error_position(
@@ -285,22 +302,12 @@ macro_rules! error_position(
 );
 
 #[cfg(feature = "verbose-errors")]
-/// creates a parse error from a `nom::ErrorKind`,
-/// the position in the input and the next error in
-/// the parsing tree.
-/// if "verbose-errors" is not activated,
-/// it default to only the error code
 #[macro_export]
 macro_rules! error_node_position(
   ($code:expr, $input:expr, $next:expr) => ($crate::Err::NodePosition($code, $input, ::std::boxed::Box::new($next)));
 );
 
 #[cfg(not(feature = "verbose-errors"))]
-/// creates a parse error from a `nom::ErrorKind`,
-/// the position in the input and the next error in
-/// the parsing tree.
-/// if "verbose-errors" is not activated,
-/// it default to only the error code
 #[allow(unused_variables)]
 #[macro_export]
 macro_rules! error_node_position(
diff --git a/src/lib.rs b/src/lib.rs
index 94fd1c6..7a23016 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -5,16 +5,6 @@
 //!
 //! The code is available on [Github](https://github.com/Geal/nom)
 //!
-//! There are a few [guides](home.html) with more details
-//! about [the design of nom](how_nom_macros_work.html),
-//! [how to write parsers](making_a_new_parser_from_scratch.html),
-//! or the [error management system](error_management.html).
-//!
-//! If you are upgrading to nom 2.0, please read the
-//! [migration document](upgrading_to_nom_2.html).
-//!
-//! See also the [FAQ](FAQ.html).
-//!
 //! # Example
 //!
 //! ```
@@ -22,57 +12,65 @@
 //! extern crate nom;
 //!
 //! use nom::{IResult,digit};
+//! use nom::IResult::*;
 //!
 //! // Parser definition
 //!
 //! use std::str;
 //! use std::str::FromStr;
 //!
-//! // We parse any expr surrounded by parens, ignoring all whitespaces around those
-//! named!(parens<i64>, ws!(delimited!( tag!("("), expr, tag!(")") )) );
+//! named!(parens<i64>, delimited!(
+//!     char!('('),
+//!     expr,
+//!     char!(')')
+//!   )
+//! );
 //!
-//! // We transform an integer string into a i64, ignoring surrounding whitespaces
-//! // We look for a digit suite, and try to convert it.
-//! // If either str::from_utf8 or FromStr::from_str fail,
-//! // we fallback to the parens parser defined above
-//! named!(factor<i64>, alt!(
+//! named!(i64_digit<i64>,
+//!   map_res!(
 //!     map_res!(
-//!       map_res!(
-//!         ws!(digit),
-//!         str::from_utf8
-//!       ),
-//!       FromStr::from_str
-//!     )
+//!       digit,
+//!       str::from_utf8
+//!     ),
+//!     FromStr::from_str
+//!   )
+//! );
+//!
+//! // We transform an integer string into a i64
+//! // we look for a digit suite, and try to convert it.
+//! // if either str::from_utf8 or FromStr::from_str fail,
+//! // the parser will fail
+//! named!(factor<i64>,
+//!   alt!(
+//!     i64_digit
 //!   | parens
 //!   )
 //! );
 //!
-//! // We read an initial factor and for each time we find
-//! // a * or / operator followed by another factor, we do
-//! // the math by folding everything
-//! named!(term <i64>, do_parse!(
-//!     init: factor >>
-//!     res:  fold_many0!(
-//!         pair!(alt!(tag!("*") | tag!("/")), factor),
-//!         init,
-//!         |acc, (op, val): (&[u8], i64)| {
-//!             if (op[0] as char) == '*' { acc * val } else { acc / val }
-//!         }
-//!     ) >>
-//!     (res)
+//! // we define acc as mutable to update its value whenever a new term is found
+//! named!(term <i64>,
+//!   chain!(
+//!     mut acc: factor  ~
+//!              many0!(
+//!                alt!(
+//!                  tap!(mul: preceded!(tag!("*"), factor) => acc = acc * mul) |
+//!                  tap!(div: preceded!(tag!("/"), factor) => acc = acc / div)
+//!                )
+//!              ),
+//!     || { return acc }
 //!   )
 //! );
 //!
-//! named!(expr <i64>, do_parse!(
-//!     init: term >>
-//!     res:  fold_many0!(
-//!         pair!(alt!(tag!("+") | tag!("-")), term),
-//!         init,
-//!         |acc, (op, val): (&[u8], i64)| {
-//!             if (op[0] as char) == '+' { acc + val } else { acc - val }
-//!         }
-//!     ) >>
-//!     (res)
+//! named!(expr <i64>,
+//!   chain!(
+//!     mut acc: term  ~
+//!              many0!(
+//!                alt!(
+//!                  tap!(add: preceded!(tag!("+"), term) => acc = acc + add) |
+//!                  tap!(sub: preceded!(tag!("-"), term) => acc = acc - sub)
+//!                )
+//!              ),
+//!     || { return acc }
 //!   )
 //! );
 //!
@@ -91,7 +89,6 @@
 #![cfg_attr(feature = "core", no_std)]
 #![cfg_attr(feature = "nightly", feature(test))]
 #![cfg_attr(feature = "nightly", feature(const_fn))]
-//#![warn(missing_docs)]
 
 #[cfg(feature = "core")]
 extern crate collections;
@@ -149,9 +146,9 @@ pub use self::str::*;
 #[macro_use] mod util;
 mod traits;
 
-#[cfg(feature = "verbose-errors")] #[macro_use] pub mod verbose_errors;
+#[cfg(feature = "verbose-errors")] #[macro_use] mod verbose_errors;
 
-#[cfg(not(feature = "verbose-errors"))] #[macro_use] pub mod simple_errors;
+#[cfg(not(feature = "verbose-errors"))] #[macro_use] mod simple_errors;
 
 #[macro_use] mod internal;
 #[macro_use] mod macros;
diff --git a/src/macros.rs b/src/macros.rs
index 3c9c28d..0f43b8d 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -98,92 +98,57 @@ macro_rules! named (
         named_attr!(#$($args)*);
     );
     ($name:ident( $i:ty ) -> $o:ty, $submac:ident!( $($args:tt)* )) => (
-        #[allow(unused_variables)]
         fn $name( i: $i ) -> $crate::IResult<$i,$o,u32> {
             $submac!(i, $($args)*)
         }
     );
     ($name:ident<$i:ty,$o:ty,$e:ty>, $submac:ident!( $($args:tt)* )) => (
-        #[allow(unused_variables)]
         fn $name( i: $i ) -> $crate::IResult<$i, $o, $e> {
             $submac!(i, $($args)*)
         }
     );
     ($name:ident<$i:ty,$o:ty>, $submac:ident!( $($args:tt)* )) => (
-        #[allow(unused_variables)]
         fn $name( i: $i ) -> $crate::IResult<$i, $o, u32> {
             $submac!(i, $($args)*)
         }
     );
     ($name:ident<$o:ty>, $submac:ident!( $($args:tt)* )) => (
-        #[allow(unused_variables)]
         fn $name<'a>( i: &'a[u8] ) -> $crate::IResult<&'a [u8], $o, u32> {
             $submac!(i, $($args)*)
         }
     );
     ($name:ident, $submac:ident!( $($args:tt)* )) => (
-        #[allow(unused_variables)]
         fn $name( i: &[u8] ) -> $crate::IResult<&[u8], &[u8], u32> {
             $submac!(i, $($args)*)
         }
     );
     (pub $name:ident( $i:ty ) -> $o:ty, $submac:ident!( $($args:tt)* )) => (
-        #[allow(unused_variables)]
         pub fn $name( i: $i ) -> $crate::IResult<$i,$o, u32> {
             $submac!(i, $($args)*)
         }
     );
     (pub $name:ident<$i:ty,$o:ty,$e:ty>, $submac:ident!( $($args:tt)* )) => (
-        #[allow(unused_variables)]
         pub fn $name( i: $i ) -> $crate::IResult<$i, $o, $e> {
             $submac!(i, $($args)*)
         }
     );
     (pub $name:ident<$i:ty,$o:ty>, $submac:ident!( $($args:tt)* )) => (
-        #[allow(unused_variables)]
         pub fn $name( i: $i ) -> $crate::IResult<$i, $o, u32> {
             $submac!(i, $($args)*)
         }
     );
     (pub $name:ident<$o:ty>, $submac:ident!( $($args:tt)* )) => (
-        #[allow(unused_variables)]
         pub fn $name( i: &[u8] ) -> $crate::IResult<&[u8], $o, u32> {
             $submac!(i, $($args)*)
         }
     );
     (pub $name:ident, $submac:ident!( $($args:tt)* )) => (
-        #[allow(unused_variables)]
         pub fn $name<'a>( i: &'a [u8] ) -> $crate::IResult<&[u8], &[u8], u32> {
             $submac!(i, $($args)*)
         }
     );
 );
 
-/// Makes a function from a parser combination with arguments.
-#[macro_export]
-macro_rules! named_args {
-    (pub $func_name:ident ( $( $arg:ident : $typ:ty ),* ) < $return_type:ty > , $submac:ident!( $($args:tt)* ) ) => {
-        pub fn $func_name(input: &[u8], $( $arg : $typ ),*) -> IResult<&[u8], $return_type> {
-            $submac!(input, $($args)*)
-        }
-    };
-    (pub $func_name:ident < 'a > ( $( $arg:ident : $typ:ty ),* ) < $return_type:ty > , $submac:ident!( $($args:tt)* ) ) => {
-        pub fn $func_name<'a>(input: &'a [u8], $( $arg : $typ ),*) -> IResult<&'a [u8], $return_type> {
-            $submac!(input, $($args)*)
-        }
-    };
-    ($func_name:ident ( $( $arg:ident : $typ:ty ),* ) < $return_type:ty > , $submac:ident!( $($args:tt)* ) ) => {
-        fn $func_name(input: &[u8], $( $arg : $typ ),*) -> IResult<&[u8], $return_type> {
-            $submac!(input, $($args)*)
-        }
-    };
-    ($func_name:ident < 'a > ( $( $arg:ident : $typ:ty ),* ) < $return_type:ty > , $submac:ident!( $($args:tt)* ) ) => {
-        fn $func_name<'a>(input: &'a [u8], $( $arg : $typ ),*) -> IResult<&'a [u8], $return_type> {
-            $submac!(input, $($args)*)
-        }
-    };
-}
-
 /// Makes a function from a parser combination, with attributes
 ///
 /// The usage of this macro is almost identical to `named!`, except that
@@ -271,7 +236,7 @@ macro_rules! named_attr (
 ///   fn take_wrapper(input: &[u8], i: u8) -> IResult<&[u8],&[u8]> { take!(input, i * 10) }
 ///
 ///   // will make a parser taking 20 bytes
-///   named!(parser, call!(take_wrapper, 2));
+///   named!(parser, apply!(take_wrapper, 2));
 /// # }
 /// ```
 #[macro_export]
@@ -373,7 +338,7 @@ macro_rules! return_error (
 /// Add an error if the child parser fails
 ///
 /// While error! does an early return and avoids backtracking,
-/// add_return_error! backtracks normally. It just provides more context
+/// add_error! backtracks normally. It just provides more context
 /// for an error
 ///
 /// ```
@@ -384,7 +349,7 @@ macro_rules! return_error (
 /// # use nom::Err::{Position,NodePosition};
 /// # use nom::ErrorKind;
 /// # fn main() {
-///     named!(err_test, add_return_error!(ErrorKind::Custom(42), tag!("abcd")));
+///     named!(err_test, add_error!(ErrorKind::Custom(42), tag!("abcd")));
 ///
 ///     let a = &b"efghblah"[..];
 ///     let res_a = err_test(a);
@@ -393,7 +358,7 @@ macro_rules! return_error (
 /// ```
 ///
 #[macro_export]
-macro_rules! add_return_error (
+macro_rules! add_error (
   ($i:expr, $code:expr, $submac:ident!( $($args:tt)* )) => (
     {
       match $submac!($i, $($args)*) {
@@ -406,7 +371,7 @@ macro_rules! add_return_error (
     }
   );
   ($i:expr, $code:expr, $f:expr) => (
-    add_return_error!($i, $code, call!($f));
+    add_error!($i, $code, call!($f));
   );
 );
 
@@ -582,67 +547,6 @@ macro_rules! map_opt (
   );
 );
 
-/// `parse_to!(O) => I -> IResult<I, O>`
-/// uses the `parse` method from `std::str::FromStr` to convert the current
-/// input to the specified type
-///
-/// this will completely consume the input
-#[macro_export]
-macro_rules! parse_to (
-  ($i:expr, $t:ty ) => (
-    {
-      use $crate::ParseTo;
-      use $crate::InputLength;
-      match ($i).parse_to() {
-        ::std::option::Option::Some(output) => $crate::IResult::Done($i.slice(..$i.input_len()), output),
-        ::std::option::Option::None         => $crate::IResult::Error(error_position!($crate::ErrorKind::MapOpt, $i))
-      }
-    }
-  );
-);
-
-/// `verify!(I -> IResult<I,O>, O -> bool) => I -> IResult<I, O>`
-/// returns the result of the child parser if it satisfies a verifcation function
-///
-/// ```
-/// # #[macro_use] extern crate nom;
-/// # use nom::IResult::Done;
-/// # use nom::be_u32;
-/// # fn main() {
-///  named!(check<u32>, verify!(be_u32, |val:u32| val >= 0 && val < 3));
-/// # }
-/// ```
-#[macro_export]
-macro_rules! verify (
-  // Internal parser, do not use directly
-  (__impl $i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
-    {
-      match $submac!($i, $($args)*) {
-        $crate::IResult::Error(e)                            => $crate::IResult::Error(e),
-        $crate::IResult::Incomplete($crate::Needed::Unknown) => $crate::IResult::Incomplete($crate::Needed::Unknown),
-        $crate::IResult::Incomplete($crate::Needed::Size(i)) => $crate::IResult::Incomplete($crate::Needed::Size(i)),
-        $crate::IResult::Done(i, o)                          => if $submac2!(o, $($args2)*) {
-          $crate::IResult::Done(i, o)
-        } else {
-          $crate::IResult::Error(error_position!($crate::ErrorKind::Verify, $i))
-        }
-      }
-    }
-  );
-  ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
-    verify!(__impl $i, $submac!($($args)*), call!($g));
-  );
-  ($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
-    verify!(__impl $i, $submac!($($args)*), $submac2!($($args2)*));
-  );
-  ($i:expr, $f:expr, $g:expr) => (
-    verify!(__impl $i, call!($f), call!($g));
-  );
-  ($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
-    verify!(__impl $i, call!($f), $submac!($($args)*));
-  );
-);
-
 /// `value!(T, R -> IResult<R, S> ) => R -> IResult<R, T>`
 ///
 /// or `value!(T) => R -> IResult<R, T>`
@@ -1038,9 +942,6 @@ macro_rules! not(
       }
     }
   );
-  ($i:expr, $f:expr) => (
-    not!($i, call!($f));
-  );
 );
 
 /// `tap!(name: I -> IResult<I,O> => { block }) => I -> IResult<I, O>`
@@ -1077,11 +978,7 @@ macro_rules! tap (
   );
 );
 
-/// `eof!(i)` returns `i` if it is at the end of input data
-///
-/// please note that for now, eof only means there's no more
-/// data available, it does not work yet with smarter input
-/// types
+//FIXME: needs tests and docs
 #[macro_export]
 macro_rules! eof (
   ($i:expr,) => (
@@ -1305,11 +1202,4 @@ mod tests {
     assert_eq!(not_aaa(&b"abcd"[..]), Done(&b"abcd"[..], &b""[..]));
   }
 
-  #[test]
-  fn verify() {
-    named!(test, verify!(take!(5), |slice: &[u8]| slice[0] == 'a' as u8));
-    assert_eq!(test(&b"bcd"[..]), Incomplete(Needed::Size(5)));
-    assert_eq!(test(&b"bcdefg"[..]), Error(error_position!(ErrorKind::Verify, &b"bcdefg"[..])));
-    assert_eq!(test(&b"abcdefg"[..]), Done(&b"fg"[..], &b"abcde"[..]));
-  }
 }
diff --git a/src/methods.rs b/src/methods.rs
index d09ec85..1be1655 100644
--- a/src/methods.rs
+++ b/src/methods.rs
@@ -107,35 +107,30 @@
 macro_rules! method (
   // Non-public immutable self
   ($name:ident<$a:ty>( $i:ty ) -> $o:ty, $self_:ident, $submac:ident!( $($args:tt)* )) => (
-      #[allow(unused_variables)]
       fn $name( $self_: $a, i: $i ) -> ($a, $crate::IResult<$i,$o,u32>) {
         let result = $submac!(i, $($args)*);
         ($self_, result)
       }
   );
   ($name:ident<$a:ty,$i:ty,$o:ty,$e:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => (
-    #[allow(unused_variables)]
     fn $name( $self_: $a, i: $i ) -> ($a, $crate::IResult<$i, $o, $e>) {
       let result = $submac!(i, $($args)*);
       ($self_, result)
     }
   );
   ($name:ident<$a:ty,$i:ty,$o:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => (
-    #[allow(unused_variables)]
     fn $name( $self_: $a, i: $i ) -> ($a, $crate::IResult<$i,$o,u32>)  {
       let result = $submac!(i, $($args)*);
       ($self_, result)
     }
   );
   ($name:ident<$a:ty,$o:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => (
-      #[allow(unused_variables)]
       fn $name<'a>( $self_: $a, i: &'a[u8] ) -> ($a, $crate::IResult<&'a [u8], $o, u32>) {
         let result = $submac!(i, $($args)*);
         ($self_, result)
       }
   );
   ($name:ident<$a:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => (
-      #[allow(unused_variables)]
       fn $name( $self_: $a, i: &[u8] ) -> ($a, $crate::IResult<&[u8], &[u8], u32>) {
         let result = $submac!(i, $($args)*);
         ($self_, result)
@@ -143,35 +138,30 @@ macro_rules! method (
   );
   // Public immutable self
   (pub $name:ident<$a:ty>( $i:ty ) -> $o:ty, $self_:ident, $submac:ident!( $($args:tt)* )) => (
-      #[allow(unused_variables)]
       pub fn $name( $self_: $a, i: $i ) -> ($a, $crate::IResult<$i,$o,u32>) {
         let result = $submac!(i, $($args)*);
         ($self_, result)
       }
   );
   (pub $name:ident<$a:ty,$i:ty,$o:ty,$e:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => (
-      #[allow(unused_variables)]
       fn $name( $self_: $a, i: $i ) -> ($a, $crate::IResult<$i, $o, $e>) {
         let result = $submac!(i, $($args)*);
         ($self_, result)
       }
   );
   (pub $name:ident<$a:ty,$i:ty,$o:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => (
-    #[allow(unused_variables)]
     pub fn $name( $self_: $a,i: $i ) -> ($a, $crate::IResult<$i,$o,u32>)  {
       let result = $submac!(i, $($args)*);
       ($self_, result)
     }
   );
   (pub $name:ident<$a:ty,$o:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => (
-    #[allow(unused_variables)]
     pub fn $name<'a>( $self_: $a, i: &'a[u8] ) -> ($a, $crate::IResult<&'a [u8], $o, u32>) {
       let result = $submac!(i, $($args)*);
       ($self_, result)
     }
   );
   (pub $name:ident<$a:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => (
-    #[allow(unused_variables)]
     pub fn $name( $self_: $a, i: &[u8] ) -> ($a, $crate::IResult<&[u8], &[u8], u32>) {
       let result = $submac!(i, $($args)*);
       ($self_, result)
@@ -179,35 +169,30 @@ macro_rules! method (
   );
   // Non-public mutable self
   ($name:ident<$a:ty>( $i:ty ) -> $o:ty, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
-      #[allow(unused_variables)]
       fn $name( mut $self_: $a, i: $i ) -> ($a, $crate::IResult<$i,$o,u32>) {
         let result = $submac!(i, $($args)*);
         ($self_, result)
       }
   );
   ($name:ident<$a:ty,$i:ty,$o:ty,$e:ty>, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
-      #[allow(unused_variables)]
       fn $name( mut $self_: $a, i: $i ) -> ($a, $crate::IResult<$i, $o, $e>) {
       let result = $submac!(i, $($args)*);
       ($self_, result)
       }
   );
   ($name:ident<$a:ty,$i:ty,$o:ty>, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
-    #[allow(unused_variables)]
     fn $name( mut $self_: $a, i: $i ) -> ($a, $crate::IResult<$i,$o,u32>)  {
       let result = $submac!(i, $($args)*);
       ($self_, result)
     }
   );
   ($name:ident<$a:ty,$o:ty>, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
-      #[allow(unused_variables)]
       fn $name<'a>( mut $self_: $a, i: &'a[u8] ) -> ($a, $crate::IResult<&'a [u8], $o, u32>) {
         let result = $submac!(i, $($args)*);
         ($self_, result)
       }
   );
   ($name:ident<$a:ty>, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
-      #[allow(unused_variables)]
       fn $name( mut $self_: $a, i: &[u8] ) -> ($a, $crate::IResult<&[u8], &[u8], u32>) {
         let result = $submac!(i, $($args)*);
         ($self_, result)
@@ -215,35 +200,30 @@ macro_rules! method (
   );
   // Public mutable self
   (pub $name:ident<$a:ty>( $i:ty ) -> $o:ty, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
-      #[allow(unused_variables)]
       pub fn $name( mut $self_: $a, i: $i ) -> ($a, $crate::IResult<$i,$o,u32>) {
         let result = $submac!(i, $($args)*);
         ($self_, result)
       }
   );
   (pub $name:ident<$a:ty,$i:ty,$o:ty,$e:ty>, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
-      #[allow(unused_variables)]
       fn $name( mut $self_: $a, i: $i ) -> ($a, $crate::IResult<$i, $o, $e>) {
         let result = $submac!(i, $($args)*);
         ($self_, result)
       }
   );
   (pub $name:ident<$a:ty,$i:ty,$o:ty>, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
-    #[allow(unused_variables)]
     pub fn $name( mut $self_: $a,i: $i ) -> ($a, $crate::IResult<$i,$o,u32>)  {
       let result = $submac!(i, $($args)*);
       ($self_, result)
     }
   );
   (pub $name:ident<$a:ty,$o:ty>, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
-    #[allow(unused_variables)]
     pub fn $name<'a>( mut $self_: $a, i: &'a[u8] ) -> ($a, $crate::IResult<&'a [u8], $o, u32>) {
       let result = $submac!(i, $($args)*);
       ($self_, result)
     }
   );
   (pub $name:ident<$a:ty>, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
-    #[allow(unused_variables)]
     pub fn $name( mut $self_: $a, i: &[u8] ) -> ($a, $crate::IResult<&[u8], &[u8], u32>) {
       let result = $submac!(i, $($args)*);
       ($self_, result)
@@ -271,8 +251,8 @@ macro_rules! call_m (
 );
 
 
-/// emulate function currying for method calls on structs
-/// `apply_m!(self.my_function, arg1, arg2, ...)` becomes `self.my_function(input, arg1, arg2, ...)`
+/// emulate function currying for method calls on structs 
+/// `apply!(self.my_function, arg1, arg2, ...)` becomes `self.my_function(input, arg1, arg2, ...)`
 ///
 /// Supports up to 6 arguments
 #[macro_export]
diff --git a/src/multi.rs b/src/multi.rs
index a602d3c..6a50177 100644
--- a/src/multi.rs
+++ b/src/multi.rs
@@ -275,10 +275,10 @@ macro_rules! many1(
 );
 
 /// `many_till!(I -> IResult<I,O>, I -> IResult<I,P>) => I -> IResult<I, (Vec<O>, P)>`
-/// Applies the first parser until the second applies. Returns a tuple containing the list
+/// Applies the first parser until the second applies returns a tuple containong the list
 /// of results from the first in a Vec and the result of the second.
 ///
-/// The first embedded parser may return Incomplete
+/// the first embedded parser may return Incomplete
 ///
 /// ```
 /// # #[macro_use] extern crate nom;
@@ -490,16 +490,10 @@ macro_rules! count(
             ret = $crate::IResult::Error(error_position!($crate::ErrorKind::Count,$i));
             break;
           },
-          $crate::IResult::Incomplete($crate::Needed::Unknown) => {
+          $crate::IResult::Incomplete(_) => {
             ret = $crate::IResult::Incomplete($crate::Needed::Unknown);
             break;
           }
-          $crate::IResult::Incomplete($crate::Needed::Size(sz)) => {
-            ret = $crate::IResult::Incomplete($crate::Needed::Size(
-              sz + $crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&input)
-            ));
-            break;
-          }
         }
       }
 
@@ -560,139 +554,78 @@ macro_rules! count_fixed (
             ret = $crate::IResult::Error(error_position!($crate::ErrorKind::Count,$i));
             break;
           },
-          $crate::IResult::Incomplete($crate::Needed::Unknown) => {
+          $crate::IResult::Incomplete(_) => {
             ret = $crate::IResult::Incomplete($crate::Needed::Unknown);
             break;
           }
-          $crate::IResult::Incomplete($crate::Needed::Size(sz)) => {
-            ret = $crate::IResult::Incomplete($crate::Needed::Size(
-              sz + $crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&input)
-            ));
-            break;
-          }
         }
       }
 
       ret
     }
-);
+  );
   ($i:expr, $typ: ty, $f:ident, $count: expr) => (
     count_fixed!($i, $typ, call!($f), $count);
   );
 );
-
-/// `length_count!(I -> IResult<I, nb>, I -> IResult<I,O>) => I -> IResult<I, Vec<O>>`
-/// gets a number from the first parser, then applies the second parser that many times
 #[macro_export]
-macro_rules! length_count(
-  ($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
+#[doc(hidden)]
+macro_rules! length_value_impl(
+  ($i:expr, $f:expr, $g:ident!( $($args:tt)* ), $lenpat:pat, $lenexpr:expr) => (
     {
-      match $submac!($i, $($args)*) {
-        $crate::IResult::Error(e)      => $crate::IResult::Error(e),
-        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
-        $crate::IResult::Done(i, o)    => {
-          match count!(i, $submac2!($($args2)*), o as usize) {
-            $crate::IResult::Error(e)                            => $crate::IResult::Error(e),
-            $crate::IResult::Incomplete($crate::Needed::Unknown) => $crate::IResult::Incomplete($crate::Needed::Unknown),
-            $crate::IResult::Incomplete($crate::Needed::Size(n)) => {
-              $crate::IResult::Incomplete($crate::Needed::Size(
-                n + $crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&i)
-              ))
-            },
-            $crate::IResult::Done(i2, o2)  =>  $crate::IResult::Done(i2, o2)
-          }
-        }
-      }
-    }
-  );
-
-  ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
-    length_count!($i, $submac!($($args)*), call!($g));
-  );
-
-  ($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
-    length_count!($i, call!($f), $submac!($($args)*));
-  );
+      use $crate::InputLength;
+      match $f($i) {
+        $crate::IResult::Error(a)      => $crate::IResult::Error(a),
+        $crate::IResult::Incomplete(x) => $crate::IResult::Incomplete(x),
+        $crate::IResult::Done(inum, onum)   => {
+          let ret;
+          let length_token = $i.input_len() - inum.input_len();
+          let mut input    = inum;
+          let mut res      = ::std::vec::Vec::new();
+
+          loop {
+            if res.len() == onum as usize {
+              ret = $crate::IResult::Done(input, res); break;
+            }
 
-  ($i:expr, $f:expr, $g:expr) => (
-    length_count!($i, call!($f), call!($g));
-  );
-);
+            match $g!(input, $($args)*) {
+              $crate::IResult::Done(iparse, oparse) => {
+                res.push(oparse);
+                input = iparse;
+              },
+              $crate::IResult::Error(_)      => {
+                ret = $crate::IResult::Error(error_position!($crate::ErrorKind::LengthValue,$i));
+                break;
+              },
+              $crate::IResult::Incomplete(a) => {
+                ret = match a {
+                  $crate::Needed::Unknown => $crate::IResult::Incomplete(
+                    $crate::Needed::Unknown
+                  ),
+                  $crate::Needed::Size($lenpat) => $crate::IResult::Incomplete(
+                    $crate::Needed::Size(length_token + onum as usize * $lenexpr)
+                  )
+                };
+                break;
+              }
+            }
+          }
 
-/// `length_data!(I -> IResult<I, nb>) => O`
-///
-/// `length_data` gets a number from the first parser, than takes a subslice of the input
-/// of that size, and returns that subslice
-#[macro_export]
-macro_rules! length_data(
-  ($i:expr, $submac:ident!( $($args:tt)* )) => (
-    match $submac!($i, $($args)*) {
-      $crate::IResult::Error(e)      => $crate::IResult::Error(e),
-      $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
-      $crate::IResult::Done(i, o)    => {
-        match take!(i, o as usize) {
-          $crate::IResult::Error(e)                            => $crate::IResult::Error(e),
-          $crate::IResult::Incomplete($crate::Needed::Unknown) => $crate::IResult::Incomplete($crate::Needed::Unknown),
-          $crate::IResult::Incomplete($crate::Needed::Size(n)) => {
-            $crate::IResult::Incomplete($crate::Needed::Size(
-              n +$crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&i)
-            ))
-          },
-          $crate::IResult::Done(i2, o2)  =>  $crate::IResult::Done(i2, o2)
+          ret
         }
       }
     }
   );
-
-  ($i:expr, $f:expr) => (
-    length_data!($i, call!($f));
-  );
 );
 
 /// `length_value!(I -> IResult<I, nb>, I -> IResult<I,O>) => I -> IResult<I, Vec<O>>`
-/// gets a number from the first parser, takes a subslice of the input of that size,
-/// then applies the second parser on that subslice. If the second parser returns
-/// `Incomplete`, `length_value` will return an error
+/// gets a number from the first parser, then applies the second parser that many times
 #[macro_export]
 macro_rules! length_value(
-  ($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
-    {
-      match $submac!($i, $($args)*) {
-        $crate::IResult::Error(e)      => $crate::IResult::Error(e),
-        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
-        $crate::IResult::Done(i, o)    => {
-          match take!(i, o as usize) {
-            $crate::IResult::Error(e)                            => $crate::IResult::Error(e),
-            $crate::IResult::Incomplete($crate::Needed::Unknown) => $crate::IResult::Incomplete($crate::Needed::Unknown),
-            $crate::IResult::Incomplete($crate::Needed::Size(n)) => {
-              $crate::IResult::Incomplete($crate::Needed::Size(
-                n +$crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&i)
-              ))
-            },
-            $crate::IResult::Done(i2, o2)  => {
-              match complete!(o2, $submac2!($($args2)*)) {
-                $crate::IResult::Error(e)      => $crate::IResult::Error(e),
-                $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
-                $crate::IResult::Done(_, o3)   => $crate::IResult::Done(i2, o3)
-              }
-            }
-          }
-        }
-      }
-    }
-  );
-
-  ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
-    length_value!($i, $submac!($($args)*), call!($g));
-  );
-
-  ($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
-    length_value!($i, call!($f), $submac!($($args)*));
-  );
-
-  ($i:expr, $f:expr, $g:expr) => (
-    length_value!($i, call!($f), call!($g));
-  );
+  ($i:expr, $f:expr, $g:ident!( $($args:tt)* )) => (length_value_impl!($i, $f, $g!($($args)*), length, length));
+  ($i:expr, $f:expr, $g:ident!( $($args:tt)* ), $length:expr) => (length_value_impl!($i, $f, $g!($($args)*), _, $length));
+  ($i:expr, $f:expr, $g:expr) => (length_value_impl!($i, $f, call!($g), length, length));
+  ($i:expr, $f:expr, $g:expr, $length:expr) => (length_value_impl!($i, $f, call!($g), _, $length));
 );
 
 /// `fold_many0!(I -> IResult<I,O>, R, Fn(R, O) -> R) => I -> IResult<I, R>`
@@ -961,8 +894,7 @@ mod tests {
 
   use internal::IResult::*;
   use util::ErrorKind;
-  use nom::{be_u8,be_u16,le_u16,digit};
-  use std::str::{self,FromStr};
+  use nom::{be_u8,be_u16,le_u16};
 
   // reproduce the tag and take macros, because of module import order
   macro_rules! tag (
@@ -1162,8 +1094,8 @@ mod tests {
     named!( cnt_2<&[u8], Vec<&[u8]> >, count!(tag_abc, TIMES ) );
 
     assert_eq!(cnt_2(&b"abcabcabcdef"[..]), Done(&b"abcdef"[..], vec![&b"abc"[..], &b"abc"[..]]));
-    assert_eq!(cnt_2(&b"ab"[..]), Incomplete(Needed::Size(3)));
-    assert_eq!(cnt_2(&b"abcab"[..]), Incomplete(Needed::Size(6)));
+    assert_eq!(cnt_2(&b"ab"[..]), Incomplete(Needed::Unknown));
+    assert_eq!(cnt_2(&b"abcab"[..]), Incomplete(Needed::Unknown));
     assert_eq!(cnt_2(&b"xxx"[..]), Error(error_position!(ErrorKind::Count, &b"xxx"[..])));
     assert_eq!(cnt_2(&b"xxxabcabcdef"[..]), Error(error_position!(ErrorKind::Count, &b"xxxabcabcdef"[..])));
     assert_eq!(cnt_2(&b"abcxxxabcdef"[..]), Error(error_position!(ErrorKind::Count, &b"abcxxxabcdef"[..])));
@@ -1207,8 +1139,8 @@ mod tests {
     named!( cnt_2<&[u8], [&[u8]; TIMES] >, count_fixed!(&[u8], tag_abc, TIMES ) );
 
     assert_eq!(cnt_2(&b"abcabcabcdef"[..]), Done(&b"abcdef"[..], [&b"abc"[..], &b"abc"[..]]));
-    assert_eq!(cnt_2(&b"ab"[..]), Incomplete(Needed::Size(3)));
-    assert_eq!(cnt_2(&b"abcab"[..]), Incomplete(Needed::Size(6)));
+    assert_eq!(cnt_2(&b"ab"[..]), Incomplete(Needed::Unknown));
+    assert_eq!(cnt_2(&b"abcab"[..]), Incomplete(Needed::Unknown));
     assert_eq!(cnt_2(&b"xxx"[..]), Error(error_position!(ErrorKind::Count, &b"xxx"[..])));
     assert_eq!(cnt_2(&b"xxxabcabcdef"[..]), Error(error_position!(ErrorKind::Count, &b"xxxabcabcdef"[..])));
     assert_eq!(cnt_2(&b"abcxxxabcdef"[..]), Error(error_position!(ErrorKind::Count, &b"abcxxxabcdef"[..])));
@@ -1243,63 +1175,49 @@ mod tests {
     let error_2_remain = &b"abcxxxabcdef"[..];
 
     assert_eq!(counter_2(done), Done(rest, parsed_main));
-    assert_eq!(counter_2(incomplete_1), Incomplete(Needed::Size(3)));
-    assert_eq!(counter_2(incomplete_2), Incomplete(Needed::Size(6)));
+    assert_eq!(counter_2(incomplete_1), Incomplete(Needed::Unknown));
+    assert_eq!(counter_2(incomplete_2), Incomplete(Needed::Unknown));
     assert_eq!(counter_2(error), Error(error_position!(ErrorKind::Count, error)));
     assert_eq!(counter_2(error_1), Error(error_position!(ErrorKind::Count, error_1_remain)));
     assert_eq!(counter_2(error_2), Error(error_position!(ErrorKind::Count, error_2_remain)));
   }
 
-  named!(pub number<u32>, map_res!(
-    map_res!(
-      digit,
-      str::from_utf8
-    ),
-    FromStr::from_str
-  ));
-
-  #[test]
-  fn length_count() {
-    named!(tag_abc, tag!(&b"abc"[..]) );
-    named!( cnt<&[u8], Vec<&[u8]> >, length_count!(number, tag_abc) );
-
-    assert_eq!(cnt(&b"2abcabcabcdef"[..]), Done(&b"abcdef"[..], vec![&b"abc"[..], &b"abc"[..]]));
-    assert_eq!(cnt(&b"2ab"[..]), Incomplete(Needed::Size(4)));
-    assert_eq!(cnt(&b"3abcab"[..]), Incomplete(Needed::Size(7)));
-    assert_eq!(cnt(&b"xxx"[..]), Error(error_position!(ErrorKind::Digit, &b"xxx"[..])));
-    assert_eq!(cnt(&b"2abcxxx"[..]), Error(error_position!(ErrorKind::Count, &b"xxx"[..])));
-  }
-
-  #[test]
-  fn length_data() {
-    named!( take<&[u8], &[u8]>, length_data!(number) );
-
-    assert_eq!(take(&b"6abcabcabcdef"[..]), Done(&b"abcdef"[..], &b"abcabc"[..]));
-    assert_eq!(take(&b"3ab"[..]), Incomplete(Needed::Size(4)));
-    assert_eq!(take(&b"xxx"[..]), Error(error_position!(ErrorKind::Digit, &b"xxx"[..])));
-    assert_eq!(take(&b"2abcxxx"[..]), Done(&b"cxxx"[..], &b"ab"[..]));
-  }
-
   #[test]
   fn length_value_test() {
-    named!(length_value_1<&[u8], u16 >, length_value!(be_u8, be_u16));
-    named!(length_value_2<&[u8], (u8, u8) >, length_value!(be_u8, tuple!(be_u8, be_u8)));
+    named!(length_value_1<&[u8], Vec<u16> >, length_value!(be_u8, be_u16));
+    named!(length_value_2<&[u8], Vec<u16> >, length_value!(be_u8, be_u16, 2));
+    named!(length_value_3<&[u8], Vec<(u8, u8)> >, length_value!(be_u8, tuple!(be_u8, be_u8)));
+    named!(length_value_4<&[u8], Vec<(u8, u8)> >, length_value!(be_u8, tuple!(be_u8, be_u8), 2));
 
     let i1 = vec![0, 5, 6];
-    assert_eq!(length_value_1(&i1), IResult::Error(error_position!(ErrorKind::Complete, &b""[..])));
-    assert_eq!(length_value_2(&i1), IResult::Error(error_position!(ErrorKind::Complete, &b""[..])));
+    assert_eq!(length_value_1(&i1), IResult::Done(&i1[1..], vec![]));
+    assert_eq!(length_value_2(&i1), IResult::Done(&i1[1..], vec![]));
+    assert_eq!(length_value_3(&i1), IResult::Done(&i1[1..], vec![]));
+    assert_eq!(length_value_4(&i1), IResult::Done(&i1[1..], vec![]));
 
     let i2 = vec![1, 5, 6, 3];
-    assert_eq!(length_value_1(&i2), IResult::Error(error_position!(ErrorKind::Complete, &i2[1..])));
-    assert_eq!(length_value_2(&i2), IResult::Error(error_position!(ErrorKind::Complete, &i2[1..])));
+    assert_eq!(length_value_1(&i2), IResult::Done(&i2[3..], vec![1286]));
+    assert_eq!(length_value_2(&i2), IResult::Done(&i2[3..], vec![1286]));
+    assert_eq!(length_value_3(&i2), IResult::Done(&i2[3..], vec![(5, 6)]));
+    assert_eq!(length_value_4(&i2), IResult::Done(&i2[3..], vec![(5, 6)]));
 
     let i3 = vec![2, 5, 6, 3, 4, 5, 7];
-    assert_eq!(length_value_1(&i3), IResult::Done(&i3[3..], 1286));
-    assert_eq!(length_value_2(&i3), IResult::Done(&i3[3..], (5, 6)));
-
-    let i4 = vec![3, 5, 6, 3, 4, 5];
-    assert_eq!(length_value_1(&i4), IResult::Done(&i4[4..], 1286));
-    assert_eq!(length_value_2(&i4), IResult::Done(&i4[4..], (5, 6)));
+    assert_eq!(length_value_1(&i3), IResult::Done(&i3[5..], vec![1286, 772]));
+    assert_eq!(length_value_2(&i3), IResult::Done(&i3[5..], vec![1286, 772]));
+    assert_eq!(length_value_3(&i3), IResult::Done(&i3[5..], vec![(5, 6), (3, 4)]));
+    assert_eq!(length_value_4(&i3), IResult::Done(&i3[5..], vec![(5, 6), (3, 4)]));
+
+    let i4 = vec![2, 5, 6, 3];
+    assert_eq!(length_value_1(&i4), IResult::Incomplete(Needed::Size(5)));
+    assert_eq!(length_value_2(&i4), IResult::Incomplete(Needed::Size(5)));
+    assert_eq!(length_value_3(&i4), IResult::Incomplete(Needed::Size(5)));
+    assert_eq!(length_value_4(&i4), IResult::Incomplete(Needed::Size(5)));
+
+    let i5 = vec![3, 5, 6, 3, 4, 5];
+    assert_eq!(length_value_1(&i5), IResult::Incomplete(Needed::Size(7)));
+    assert_eq!(length_value_2(&i5), IResult::Incomplete(Needed::Size(7)));
+    assert_eq!(length_value_3(&i5), IResult::Incomplete(Needed::Size(7)));
+    assert_eq!(length_value_4(&i5), IResult::Incomplete(Needed::Size(7)));
   }
 
   #[test]
diff --git a/src/nom.rs b/src/nom.rs
index 2887bb6..3741440 100644
--- a/src/nom.rs
+++ b/src/nom.rs
@@ -14,7 +14,7 @@ use std::fmt::Debug;
 use internal::*;
 use internal::IResult::*;
 use util::ErrorKind;
-use traits::{AsChar,InputLength,InputIter};
+use traits::{AsChar,InputLength,IterIndices};
 use std::mem::transmute;
 use std::ops::{Range,RangeFrom,RangeTo};
 use traits::{Compare,CompareResult,Slice};
@@ -44,7 +44,7 @@ pub fn begin(input: &[u8]) -> IResult<(), &[u8]> {
 
 pub fn crlf<T>(input:T) -> IResult<T,T> where
   T:Slice<Range<usize>>+Slice<RangeFrom<usize>>+Slice<RangeTo<usize>>,
-  T: InputIter,
+  T: IterIndices,
   T: Compare<&'static str> {
     match input.compare("\r\n") {
       //FIXME: is this the right index?
@@ -60,7 +60,7 @@ pub fn crlf<T>(input:T) -> IResult<T,T> where
 // public methods
 pub fn not_line_ending<T>(input:T) -> IResult<T,T> where
     T:Slice<Range<usize>>+Slice<RangeFrom<usize>>+Slice<RangeTo<usize>>,
-    T: InputIter+InputLength,
+    T: IterIndices+InputLength,
     T: Compare<&'static str> {
       match input.iter_elements().position(|item| {
         let c = item.as_char();
@@ -86,10 +86,10 @@ pub fn not_line_ending<T>(input:T) -> IResult<T,T> where
       }
 }
 
-/// Recognizes an end of line (both '\n' and '\r\n')
+/// Recognizes lowercase and uppercase alphabetic characters: a-zA-Z
 pub fn line_ending<T>(input:T) -> IResult<T, T> where
     T: Slice<Range<usize>>+Slice<RangeFrom<usize>>+Slice<RangeTo<usize>>,
-    T: InputIter+InputLength,
+    T: IterIndices+InputLength,
     T: Compare<&'static str> {
 
   match input.compare("\n") {
@@ -106,7 +106,7 @@ pub fn line_ending<T>(input:T) -> IResult<T, T> where
 
 pub fn eol<T>(input:T) -> IResult<T,T> where
     T: Slice<Range<usize>>+Slice<RangeFrom<usize>>+Slice<RangeTo<usize>>,
-    T: InputIter+InputLength,
+    T: IterIndices+InputLength,
     T: Compare<&'static str> {
   line_ending(input)
 }
@@ -159,7 +159,7 @@ pub fn is_space(chr:u8) -> bool {
 /// Recognizes lowercase and uppercase alphabetic characters: a-zA-Z
 pub fn alpha<T>(input:T) -> IResult<T, T> where
     T: Slice<Range<usize>>+Slice<RangeFrom<usize>>+Slice<RangeTo<usize>>,
-    T: InputIter+InputLength {
+    T: IterIndices+InputLength {
   let input_length = input.input_len();
   if input_length == 0 {
     return Incomplete(Needed::Unknown);
@@ -180,7 +180,7 @@ pub fn alpha<T>(input:T) -> IResult<T, T> where
 /// Recognizes numerical characters: 0-9
 pub fn digit<T>(input:T) -> IResult<T, T> where
     T: Slice<Range<usize>>+Slice<RangeFrom<usize>>+Slice<RangeTo<usize>>,
-    T: InputIter+InputLength {
+    T: IterIndices+InputLength {
   let input_length = input.input_len();
   if input_length == 0 {
     return Incomplete(Needed::Unknown);
@@ -201,7 +201,7 @@ pub fn digit<T>(input:T) -> IResult<T, T> where
 /// Recognizes hexadecimal numerical characters: 0-9, A-F, a-f
 pub fn hex_digit<T>(input:T) -> IResult<T,T> where
     T: Slice<Range<usize>>+Slice<RangeFrom<usize>>+Slice<RangeTo<usize>>,
-    T: InputIter+InputLength {
+    T: IterIndices+InputLength {
   let input_length = input.input_len();
   if input_length == 0 {
     return Incomplete(Needed::Unknown);
@@ -222,7 +222,7 @@ pub fn hex_digit<T>(input:T) -> IResult<T,T> where
 /// Recognizes octal characters: 0-7
 pub fn oct_digit<T>(input:T) -> IResult<T,T> where
     T: Slice<Range<usize>>+Slice<RangeFrom<usize>>+Slice<RangeTo<usize>>,
-    T: InputIter+InputLength {
+    T: IterIndices+InputLength {
   let input_length = input.input_len();
   if input_length == 0 {
     return Incomplete(Needed::Unknown);
@@ -243,7 +243,7 @@ pub fn oct_digit<T>(input:T) -> IResult<T,T> where
 /// Recognizes numerical and alphabetic characters: 0-9a-zA-Z
 pub fn alphanumeric<T>(input:T) -> IResult<T,T> where
     T: Slice<Range<usize>>+Slice<RangeFrom<usize>>+Slice<RangeTo<usize>>,
-    T: InputIter+InputLength {
+    T: IterIndices+InputLength {
   let input_length = input.input_len();
   if input_length == 0 {
     return Incomplete(Needed::Unknown);
@@ -264,7 +264,7 @@ pub fn alphanumeric<T>(input:T) -> IResult<T,T> where
 /// Recognizes spaces and tabs
 pub fn space<T>(input:T) -> IResult<T,T> where
     T: Slice<Range<usize>>+Slice<RangeFrom<usize>>+Slice<RangeTo<usize>>,
-    T: InputIter+InputLength {
+    T: IterIndices+InputLength {
   let input_length = input.input_len();
   if input_length == 0 {
     return Incomplete(Needed::Unknown);
@@ -286,7 +286,7 @@ pub fn space<T>(input:T) -> IResult<T,T> where
 /// Recognizes spaces, tabs, carriage returns and line feeds
 pub fn multispace<T>(input:T) -> IResult<T,T> where
     T: Slice<Range<usize>>+Slice<RangeFrom<usize>>+Slice<RangeTo<usize>>,
-    T: InputIter+InputLength {
+    T: IterIndices+InputLength {
   let input_length = input.input_len();
   if input_length == 0 {
     return Incomplete(Needed::Unknown);
@@ -319,6 +319,20 @@ pub fn sized_buffer(input:&[u8]) -> IResult<&[u8], &[u8]> {
   }
 }
 
+pub fn length_value(input:&[u8]) -> IResult<&[u8], &[u8]> {
+  let input_len = input.len();
+  if input_len == 0 {
+    return Incomplete(Needed::Unknown);
+  }
+
+  let len = input[0] as usize;
+  if input_len - 1 >= len {
+    IResult::Done(&input[len+1..], &input[1..len+1])
+  } else {
+    IResult::Incomplete(Needed::Size(1+len))
+  }
+}
+
 /// Recognizes an unsigned 1 byte integer (equivalent to take!(1)
 #[inline]
 pub fn be_u8(i: &[u8]) -> IResult<&[u8], u8> {
@@ -595,94 +609,6 @@ pub fn rest_s(input: &str) -> IResult<&str, &str> {
     IResult::Done(&input[input.len()..], input)
 }
 
-/// Recognizes floating point number in a byte string and returs a f32
-pub fn float(input: &[u8]) -> IResult<&[u8],f32> {
-  flat_map!(input,
-    recognize!(
-      tuple!(
-        opt!(alt!(tag!("+") | tag!("-"))),
-        alt!(
-          delimited!(digit, tag!("."), opt!(digit))
-          | delimited!(opt!(digit), tag!("."), digit)
-        ),
-        opt!(complete!(tuple!(
-          alt!(tag!("e") | tag!("E")),
-          opt!(alt!(tag!("+") | tag!("-"))),
-          digit
-          )
-        ))
-      )
-    ),
-    parse_to!(f32)
-  )
-}
-
-/// Recognizes floating point number in a string and returs a f32
-pub fn float_s(input: &str) -> IResult<&str,f32> {
-  flat_map!(input,
-    recognize!(
-      tuple!(
-        opt!(alt!(tag!("+") | tag!("-"))),
-        alt!(
-          delimited!(digit, tag!("."), opt!(digit))
-          | delimited!(opt!(digit), tag!("."), digit)
-        ),
-        opt!(complete!(tuple!(
-          alt!(tag!("e") | tag!("E")),
-          opt!(alt!(tag!("+") | tag!("-"))),
-          digit
-          )
-        ))
-      )
-    ),
-    parse_to!(f32)
-  )
-}
-
-/// Recognizes floating point number in a byte string and returs a f64
-pub fn double(input: &[u8]) -> IResult<&[u8],f64> {
-  flat_map!(input,
-    recognize!(
-      tuple!(
-        opt!(alt!(tag!("+") | tag!("-"))),
-        alt!(
-          delimited!(digit, tag!("."), opt!(digit))
-          | delimited!(opt!(digit), tag!("."), digit)
-        ),
-        opt!(complete!(tuple!(
-          alt!(tag!("e") | tag!("E")),
-          opt!(alt!(tag!("+") | tag!("-"))),
-          digit
-          )
-        ))
-      )
-    ),
-    parse_to!(f64)
-  )
-}
-
-/// Recognizes floating point number in a string and returs a f64
-pub fn double_s(input: &str) -> IResult<&str,f64> {
-  flat_map!(input,
-    recognize!(
-      tuple!(
-        opt!(alt!(tag!("+") | tag!("-"))),
-        alt!(
-          delimited!(digit, tag!("."), opt!(digit))
-          | delimited!(opt!(digit), tag!("."), digit)
-        ),
-        opt!(complete!(tuple!(
-          alt!(tag!("e") | tag!("E")),
-          opt!(alt!(tag!("+") | tag!("-"))),
-          digit
-          )
-        ))
-      )
-    ),
-    parse_to!(f64)
-  )
-}
-
 #[cfg(test)]
 mod tests {
   use super::*;
@@ -864,6 +790,26 @@ mod tests {
     assert_eq!(res, Done(&v2[..], ()));
   }*/
 
+  #[test]
+  fn length_value_test() {
+    let i1 = vec![7,8];
+    let o1 = vec![4, 5, 6];
+    let arr1:[u8; 6usize] = [3, 4, 5, 6, 7, 8];
+    let res1 = length_value(&arr1);
+    assert_eq!(Done(&i1[..], &o1[..]), res1);
+
+    let i2:Vec<u8> = vec![4,5,6,7,8];
+    let o2: &[u8] = b"";
+    let arr2:[u8; 6usize] = [0, 4, 5, 6, 7, 8];
+    let res2 = length_value(&arr2);
+    assert_eq!(Done(&i2[..], o2), res2);
+
+    let arr3:[u8; 7usize] = [8, 4, 5, 6, 7, 8, 9];
+    let res3 = length_value(&arr3);
+    //FIXME: should be incomplete
+    assert_eq!(Incomplete(Needed::Size(9)), res3);
+  }
+
   #[test]
   fn i8_tests() {
     assert_eq!(be_i8(&[0x00]), Done(&b""[..], 0));
@@ -1130,17 +1076,4 @@ mod tests {
     assert_eq!(eol("\r"),    Incomplete(Needed::Size(2)));
     assert_eq!(eol("\ra"),   Error(error_position!(ErrorKind::CrLf, "\ra")));
   }
-
-  #[test]
-  fn float_test() {
-    assert_eq!(float(&b"+3.14"[..]),   Done(&b""[..], 3.14));
-    assert_eq!(float_s(&"3.14"[..]),   Done(&""[..], 3.14));
-    assert_eq!(double(&b"3.14"[..]),   Done(&b""[..], 3.14));
-    assert_eq!(double_s(&"3.14"[..]),   Done(&""[..], 3.14));
-
-    assert_eq!(float(&b"-1.234E-12"[..]),   Done(&b""[..], -1.234E-12));
-    assert_eq!(float_s(&"-1.234E-12"[..]),   Done(&""[..], -1.234E-12));
-    assert_eq!(double(&b"-1.234E-12"[..]),   Done(&b""[..], -1.234E-12));
-    assert_eq!(double_s(&"-1.234E-12"[..]),   Done(&""[..], -1.234E-12));
-  }
 }
diff --git a/src/regexp.rs b/src/regexp.rs
index 87ac566..d312524 100644
--- a/src/regexp.rs
+++ b/src/regexp.rs
@@ -23,18 +23,6 @@ macro_rules! regex_bytes (
 /// Returns the whole input if a match is found
 ///
 /// requires the `regexp` feature
-///
-/// ```
-/// # #[macro_use] extern crate nom;
-/// # use nom::IResult::{Done,Error};
-/// # fn main() {
-/// named!(rm< &str,Vec<&str> >, re_matches_static!(r"\d{4}-\d{2}-\d{2}"));
-/// assert_eq!(rm("2015-09-07"), Done("", vec!["2015-09-07"]));
-/// assert_eq!(rm("blah"), Error(error_code!(ErrorKind::RegexpMatches)));
-/// assert_eq!(rm("aaa2015-09-07blah2015-09-09pouet"), Done("pouet", vec!["2015-09-07", "2015-09-09"]));
-/// # }
-/// ```
-///
 #[macro_export]
 macro_rules! re_match (
   ($i:expr, $re:expr) => (
diff --git a/src/sequence.rs b/src/sequence.rs
index f566da6..b4b8369 100644
--- a/src/sequence.rs
+++ b/src/sequence.rs
@@ -1,15 +1,6 @@
-/// [DEPRECATED] `chain!(I->IResult<I,A> ~ I->IResult<I,B> ~ ... I->IResult<I,X> , || { return O } ) => I -> IResult<I, O>`
+/// `chain!(I->IResult<I,A> ~ I->IResult<I,B> ~ ... I->IResult<I,X> , || { return O } ) => I -> IResult<I, O>`
 /// chains parsers and assemble the results through a closure
 ///
-/// this parser is deprecated and will be removed in nom 3.0. You can
-/// now replace it with `do_parse!`. The `?` syntax to make a parser
-/// optional can be done with the `opt!` combinator.
-///
-/// There are also combinators available for specific patterns like
-/// `pair!`, `tuple!`, `preceded!`, `terminated!`, `delimited!`, etc.
-///
-/// In lots of cases, there are better solutions than using `chain!`.
-///
 /// The input type `I` must implement `nom::InputLength`.
 ///
 /// This combinator will count how much data is consumed by every child parser
@@ -1024,10 +1015,10 @@ mod tests {
   #[test]
   fn add_err() {
     named!(err_test,
-      preceded!(tag!("efgh"), add_return_error!(ErrorKind::Custom(42),
+      preceded!(tag!("efgh"), add_error!(ErrorKind::Custom(42),
           do_parse!(
                  tag!("ijkl")                                     >>
-            res: add_return_error!(ErrorKind::Custom(128), tag!("mnop")) >>
+            res: add_error!(ErrorKind::Custom(128), tag!("mnop")) >>
             (res)
           )
         )
diff --git a/src/simple_errors.rs b/src/simple_errors.rs
index f95d24c..7386acb 100644
--- a/src/simple_errors.rs
+++ b/src/simple_errors.rs
@@ -1,20 +1,3 @@
-//! Error management
-//!
-//! there are two ways to handle errors in nom. The first one,
-//! activated by default, uses the `nom::ErrorKind<E=u32>` enum
-//! in the error branch of `IResult`. This enum can hold either
-//! a parser specific error code, or a custom error type you
-//! specify.
-//!
-//! If you need more advanced error management, you can activate
-//! the "verbose-errors" compilation feature, which will give you
-//! the error system available in nom 1.0. The verbose errors
-//! accumulate error codes and positions as you backtrack through
-//! the parser tree. From there, you can precisely identify which
-//! parts of the input triggered the error case.
-//!
-//! Please note that the verbose error management is a bit slower
-//! than the simple one.
 use util::ErrorKind;
 use internal::{IResult, IError};
 use internal::IResult::*;
@@ -54,7 +37,7 @@ impl<I,O,E> IResult<I,O,E> {
     }
   }
 
-  /// Convert the IResult to a std::result::Result, or panic if the `IResult` is `Incomplete`
+  /// Convert the IResult to a std::result::Result
   pub fn to_result(self) -> Result<O, Err<E>> {
     match self {
       Done(_, o)    => Ok(o),
@@ -64,24 +47,6 @@ impl<I,O,E> IResult<I,O,E> {
   }
 }
 
-#[cfg(not(feature = "core"))]
-use std::any::Any;
-#[cfg(not(feature = "core"))]
-use std::{error,fmt};
-#[cfg(not(feature = "core"))]
-impl<E: fmt::Debug+Any> error::Error for Err<E> {
-  fn description(&self) -> &str {
-    self.description()
-  }
-}
-
-#[cfg(not(feature = "core"))]
-impl<E: fmt::Debug> fmt::Display for Err<E> {
-  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-    write!(f, "{}", self.description())
-  }
-}
-
 /// translate parser result from IResult<I,O,u32> to IResult<I,O,E> with a custom type
 ///
 /// ```
@@ -91,9 +56,9 @@ impl<E: fmt::Debug> fmt::Display for Err<E> {
 /// # use nom::ErrorKind;
 /// # fn main() {
 ///     // will add a Custom(42) error to the error chain
-///     named!(err_test, add_return_error!(ErrorKind::Custom(42), tag!("abcd")));
+///     named!(err_test, add_error!(ErrorKind::Custom(42), tag!("abcd")));
 ///     // Convert to IREsult<&[u8], &[u8], &str>
-///     named!(parser<&[u8], &[u8], &str>, add_return_error!(ErrorKind::Custom("custom error message"), fix_error!(&str, err_test)));
+///     named!(parser<&[u8], &[u8], &str>, add_error!(ErrorKind::Custom("custom error message"), fix_error!(&str, err_test)));
 ///
 ///     let a = &b"efghblah"[..];
 ///     let res_a = parser(a);
diff --git a/src/str.rs b/src/str.rs
index 7485ea7..8f7eeb6 100644
--- a/src/str.rs
+++ b/src/str.rs
@@ -64,10 +64,6 @@ macro_rules! tag_no_case_s (
 ///  let a = "abcdefgh";
 ///
 ///  assert_eq!(take5(a), Done("fgh", "abcde"));
-///
-///  let b = "12345";
-///
-///  assert_eq!(take5(b), Done("", "12345"));
 /// # }
 /// ```
 #[macro_export]
@@ -616,15 +612,6 @@ mod test {
 
     }
 
-    #[test]
-    fn utf8_indexing() {
-      named!(dot(&str) -> &str,
-        tag_s!(".")
-      );
-
-      dot("點");
-    }
-
   #[test]
   fn case_insensitive() {
     named!(test<&str,&str>, tag_no_case!("ABcd"));
diff --git a/src/traits.rs b/src/traits.rs
index a728f08..3789e5b 100644
--- a/src/traits.rs
+++ b/src/traits.rs
@@ -1,22 +1,11 @@
 //! Traits input types have to implement to work with nom combinators
 //!
 use std::ops::{Range,RangeTo,RangeFrom,RangeFull};
-use std::iter::Enumerate;
 
 #[cfg(not(feature = "core"))]
 use std::str::Chars;
-#[cfg(not(feature = "core"))]
-use std::str::CharIndices;
-#[cfg(not(feature = "core"))]
-use std::str::FromStr;
-#[cfg(not(feature = "core"))]
-use std::str::from_utf8;
 
-
-/// abstract method to calculate the input length
 pub trait InputLength {
-  /// calculates the input length, as indicated by its name,
-  /// and the name of the trait itself
   #[inline]
   fn input_len(&self) -> usize;
 }
@@ -46,30 +35,21 @@ impl<'a> InputLength for (&'a [u8], usize) {
   }
 }
 
-/// transforms common types to a char for basic token parsing
+use std::iter::Enumerate;
+#[cfg(not(feature = "core"))]
+use std::str::CharIndices;
+
 pub trait AsChar {
-    /// makes a char from self
     #[inline]
     fn as_char(self)      -> char;
-
-    /// tests that self is an alphabetic character
-    ///
-    /// warning: for `&str` it recognizes alphabetic
-    /// characters outside of the 52 ASCII letters
     #[inline]
     fn is_alpha(self)     -> bool;
-
-    /// tests that self is an alphabetic character
-    /// or a decimal digit
     #[inline]
     fn is_alphanum(self)  -> bool;
-    /// tests that self is a decimal digit
     #[inline]
     fn is_dec_digit(self) -> bool;
-    /// tests that self is an hex digit
     #[inline]
     fn is_hex_digit(self) -> bool;
-    /// tests that self is an octal digit
     #[inline]
     fn is_oct_digit(self) -> bool;
 }
@@ -138,40 +118,27 @@ impl AsChar for char {
     fn is_oct_digit(self) -> bool { self.is_digit(8) }
 }
 
-/// abstracts common iteration operations on the input type
-///
-/// it needs a distinction between `Item` and `RawItem` because
-/// `&[T]` iterates on references
-pub trait InputIter {
+pub trait IterIndices {
     type Item     : AsChar;
     type RawItem  : AsChar;
     type Iter     : Iterator<Item=(usize, Self::Item)>;
     type IterElem : Iterator<Item=Self::Item>;
-
-    /// returns an iterator over the elements and their byte offsets
     fn iter_indices(&self)  -> Self::Iter;
-    /// returns an iterator over the elements
     fn iter_elements(&self) -> Self::IterElem;
-    /// finds the byte position of the element
     fn position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::RawItem) -> bool;
-    /// get the byte offset from the element's position in the stream
-    fn slice_index(&self, count:usize) -> Option<usize>;
+    fn index(&self, count:usize) -> Option<usize>;
 }
 
-/// abstracts slicing operations
-pub trait InputTake {
-    /// returns a slice of `count` bytes
+pub trait IterTake {
     fn take<P>(&self, count: usize)  -> Option<&Self>;
-    /// split the stream at the `count` byte offset
     fn take_split<P>(&self, count: usize) -> Option<(&Self,&Self)>;
 }
 
-impl<'a> InputIter for &'a [u8] {
+impl<'a> IterIndices for &'a [u8] {
     type Item     = &'a u8;
     type RawItem  = u8;
     type Iter     = Enumerate<::std::slice::Iter<'a, u8>>;
     type IterElem = ::std::slice::Iter<'a, u8>;
-
     #[inline]
     fn iter_indices(&self) -> Enumerate<::std::slice::Iter<'a, u8>> {
         self.iter().enumerate()
@@ -185,7 +152,7 @@ impl<'a> InputIter for &'a [u8] {
       self.iter().position(|b| predicate(*b))
     }
     #[inline]
-    fn slice_index(&self, count:usize) -> Option<usize> {
+    fn index(&self, count:usize) -> Option<usize> {
       if self.len() >= count {
         Some(count)
       } else {
@@ -194,7 +161,7 @@ impl<'a> InputIter for &'a [u8] {
     }
 }
 
-impl InputTake for [u8] {
+impl IterTake for [u8] {
     #[inline]
     fn take<P>(&self, count: usize) -> Option<&Self> {
       if self.len() >= count {
@@ -214,7 +181,7 @@ impl InputTake for [u8] {
 }
 
 #[cfg(not(feature = "core"))]
-impl<'a> InputIter for &'a str {
+impl<'a> IterIndices for &'a str {
     type Item     = char;
     type RawItem  = char;
     type Iter     = CharIndices<'a>;
@@ -236,7 +203,7 @@ impl<'a> InputIter for &'a str {
       None
     }
     #[inline]
-    fn slice_index(&self, count:usize) -> Option<usize> {
+    fn index(&self, count:usize) -> Option<usize> {
       let mut cnt    = 0;
       for (index, _) in self.char_indices() {
         if cnt == count {
@@ -244,15 +211,12 @@ impl<'a> InputIter for &'a str {
         }
         cnt += 1;
       }
-      if cnt == count {
-        return Some(self.len())
-      }
       None
     }
 }
 
 #[cfg(not(feature = "core"))]
-impl InputTake for str {
+impl IterTake for str {
     #[inline]
     fn take<P>(&self, count: usize) -> Option<&Self> {
       let mut cnt    = 0;
@@ -279,8 +243,6 @@ impl InputTake for str {
     }
 }
 
-/// indicates wether a comparison was successful, an error, or
-/// if more data was needed
 #[derive(Debug,PartialEq)]
 pub enum CompareResult {
   Ok,
@@ -288,17 +250,8 @@ pub enum CompareResult {
   Error
 }
 
-/// abstracts comparison operations
 pub trait Compare<T> {
-  /// compares self to another value for equality
   fn compare(&self, t:T)         -> CompareResult;
-  /// compares self to another value for equality
-  /// independently of the case.
-  ///
-  /// warning: for `&str`, the comparison is done
-  /// by lowercasing both strings and comparing
-  /// the result. This is a temporary solution until
-  /// a better one appears
   fn compare_no_case(&self, t:T) -> CompareResult;
 }
 
@@ -332,7 +285,7 @@ impl<'a,'b> Compare<&'b[u8]> for &'a [u8] {
       match (*a,*b) {
         (0...64, 0...64) | (91...96, 91...96) | (123...255, 123...255) => a == b,
         (65...90, 65...90) | (97...122, 97...122) | (65...90, 97...122 ) |(97...122, 65...90) => {
-          *a | 0b00100000 == *b | 0b00100000
+          *a & 0b01000000 == *b & 0b01000000
         }
         _ => false
       }
@@ -362,42 +315,48 @@ impl<'a,'b> Compare<&'b str> for &'a [u8] {
 impl<'a,'b> Compare<&'b str> for &'a str {
   #[inline(always)]
   fn compare(&self, t: &'b str) -> CompareResult {
-    let pos = self.chars().zip(t.chars()).position(|(a,b)| a != b);
+    let len     = self.len();
+    let blen    = t.len();
+    let m       = if len < blen { len } else { blen };
+    let reduced = &self[..m];
+    let b       = &t[..m];
 
-    match pos {
-      Some(_) => CompareResult::Error,
-      None    => if self.len() >= t.len() {
-        CompareResult::Ok
-      } else {
-        CompareResult::Incomplete
-      }
+    if reduced != b {
+      CompareResult::Error
+    } else if m < blen {
+      CompareResult::Incomplete
+    } else {
+      CompareResult::Ok
     }
   }
 
   //FIXME: this version is too simple and does not use the current locale
   #[inline(always)]
   fn compare_no_case(&self, t: &'b str) -> CompareResult {
-    let pos = self.to_lowercase().chars().zip(t.to_lowercase().chars()).position(|(a,b)| a != b);
+    let len     = self.len();
+    let blen    = t.len();
+    let m       = if len < blen { len } else { blen };
+    let reduced = &self[..m];
+    let b       = &t[..m];
 
-    match pos {
-      Some(_) => CompareResult::Error,
-      None    => if self.len() >= t.len() {
-        CompareResult::Ok
-      } else {
-        CompareResult::Incomplete
-      }
+    //println!("compare_no_case({}, {}) => {} / {}", self, t, reduced.to_lowercase(), b.to_lowercase());
+    if !(reduced.to_lowercase() == b.to_lowercase()) {
+      CompareResult::Error
+    } else if m < blen {
+      CompareResult::Incomplete
+    } else {
+      CompareResult::Ok
     }
   }
 }
 
-/// look for self in the given input stream
 pub trait FindToken<T> {
-  fn find_token(&self, input: T) -> bool;
+  fn find_token(&self, list: T) -> bool;
 }
 
 impl<'a> FindToken<&'a[u8]> for u8 {
-  fn find_token(&self, input: &[u8]) -> bool {
-    for &i in input.iter() {
+  fn find_token(&self, list: &[u8]) -> bool {
+    for &i in list.iter() {
       if *self == i { return true }
     }
     false
@@ -406,22 +365,21 @@ impl<'a> FindToken<&'a[u8]> for u8 {
 
 #[cfg(not(feature = "core"))]
 impl<'a> FindToken<&'a str> for u8 {
-  fn find_token(&self, input: &str) -> bool {
-    self.find_token(str::as_bytes(input))
+  fn find_token(&self, list: &str) -> bool {
+    self.find_token(str::as_bytes(list))
   }
 }
 
 #[cfg(not(feature = "core"))]
 impl<'a> FindToken<&'a str> for char {
-  fn find_token(&self, input: &str) -> bool {
-    for i in input.chars() {
+  fn find_token(&self, list: &str) -> bool {
+    for i in list.chars() {
       if *self == i { return true }
     }
     false
   }
 }
 
-/// look for a substring in self
 pub trait FindSubstring<T> {
   fn find_substring(&self, substr: T) -> Option<usize>;
 }
@@ -452,124 +410,55 @@ impl<'a,'b> FindSubstring<&'b str> for &'a str {
   }
 }
 
-/// abstract method to calculate the input length
-#[cfg(not(feature = "core"))]
-pub trait ParseTo<R> {
-  fn parse_to(&self) -> Option<R>;
+pub trait Slice<R> {
+  #[inline(always)]
+  fn slice(&self, range: R) -> Self;
 }
 
-#[cfg(not(feature = "core"))]
-impl<'a,R: FromStr> ParseTo<R> for &'a[u8] {
-  fn parse_to(&self) -> Option<R> {
-    from_utf8(self).ok().and_then(|s| s.parse().ok())
+impl<'a,T> Slice<Range<usize>> for &'a [T] {
+  fn slice(&self, range:Range<usize>) -> Self {
+    &self[range]
   }
 }
 
-#[cfg(not(feature = "core"))]
-impl<'a,R:FromStr> ParseTo<R> for &'a str {
-  fn parse_to(&self) -> Option<R> {
-    self.parse().ok()
+impl<'a,T> Slice<RangeTo<usize>> for &'a [T] {
+  fn slice(&self, range:RangeTo<usize>) -> Self {
+    &self[range]
   }
 }
 
-/// slicing operations using ranges
-///
-/// this trait is loosely based on
-/// `Index`, but can actually return
-/// something else than a `&[T]` or `&str`
-pub trait Slice<R> {
-  #[inline(always)]
-  fn slice(&self, range: R) -> Self;
+impl<'a,T> Slice<RangeFrom<usize>> for &'a [T] {
+  fn slice(&self, range:RangeFrom<usize>) -> Self {
+    &self[range]
+  }
 }
 
-macro_rules! impl_fn_slice {
-    ( $ty:ty ) => {
-        fn slice(&self, range:$ty) -> Self {
-            &self[range]
-        }
-    }
+impl<'a,T> Slice<RangeFull> for &'a [T] {
+  fn slice(&self, range:RangeFull) -> Self {
+    &self[range]
+  }
 }
 
-macro_rules! slice_range_impl {
-    ( [ $for_type:ident ], $ty:ty ) => {
-        impl<'a, $for_type> Slice<$ty> for &'a [$for_type] {
-            impl_fn_slice!( $ty );
-        }
-    };
-    ( $for_type:ty, $ty:ty ) => {
-        impl<'a> Slice<$ty> for &'a $for_type {
-            impl_fn_slice!( $ty );
-        }
-    }
+impl<'a> Slice<Range<usize>> for &'a str {
+  fn slice(&self, range:Range<usize>) -> Self {
+    &self[range]
+  }
 }
 
-macro_rules! slice_ranges_impl {
-    ( [ $for_type:ident ] ) => {
-        slice_range_impl! {[$for_type], Range<usize>}
-        slice_range_impl! {[$for_type], RangeTo<usize>}
-        slice_range_impl! {[$for_type], RangeFrom<usize>}
-        slice_range_impl! {[$for_type], RangeFull}
-    };
-    ( $for_type:ty ) => {
-        slice_range_impl! {$for_type, Range<usize>}
-        slice_range_impl! {$for_type, RangeTo<usize>}
-        slice_range_impl! {$for_type, RangeFrom<usize>}
-        slice_range_impl! {$for_type, RangeFull}
-    }
+impl<'a> Slice<RangeTo<usize>> for &'a str {
+  fn slice(&self, range:RangeTo<usize>) -> Self {
+    &self[range]
+  }
 }
 
-slice_ranges_impl! {str}
-slice_ranges_impl! {[T]}
-
-
-macro_rules! array_impls {
-  ($($N:expr)+) => {
-    $(
-      impl InputLength for [u8; $N] {
-        #[inline]
-        fn input_len(&self) -> usize {
-          self.len()
-        }
-      }
-
-      impl<'a> InputLength for &'a [u8; $N] {
-        #[inline]
-        fn input_len(&self) -> usize {
-          self.len()
-        }
-      }
-
-      impl<'a> Compare<[u8; $N]> for &'a [u8] {
-        #[inline(always)]
-        fn compare(&self, t: [u8; $N]) -> CompareResult {
-          self.compare(&t[..])
-        }
-
-        #[inline(always)]
-        fn compare_no_case(&self, t: [u8;$N]) -> CompareResult {
-          self.compare_no_case(&t[..])
-        }
-      }
-
-      impl<'a,'b> Compare<&'b [u8; $N]> for &'a [u8] {
-        #[inline(always)]
-        fn compare(&self, t: &'b [u8; $N]) -> CompareResult {
-          self.compare(&t[..])
-        }
-
-        #[inline(always)]
-        fn compare_no_case(&self, t: &'b [u8;$N]) -> CompareResult {
-          self.compare_no_case(&t[..])
-        }
-      }
-    )+
-  };
+impl<'a> Slice<RangeFrom<usize>> for &'a str {
+  fn slice(&self, range:RangeFrom<usize>) -> Self {
+    &self[range]
+  }
 }
 
-
-array_impls! {
-     0  1  2  3  4  5  6  7  8  9
-    10 11 12 13 14 15 16 17 18 19
-    20 21 22 23 24 25 26 27 28 29
-    30 31 32
+impl<'a> Slice<RangeFull> for &'a str {
+  fn slice(&self, range:RangeFull) -> Self {
+    &self[range]
+  }
 }
diff --git a/src/util.rs b/src/util.rs
index cc00257..fd63388 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -562,7 +562,6 @@ pub enum ErrorKind<E=u32> {
   TakeUntilStr,
   Not,
   Permutation,
-  Verify,
 }
 
 pub fn error_to_u32<E>(e: &ErrorKind<E>) -> u32 {
@@ -624,7 +623,6 @@ pub fn error_to_u32<E>(e: &ErrorKind<E>) -> u32 {
     ErrorKind::Not                       => 63,
     ErrorKind::Permutation               => 64,
     ErrorKind::ManyTill                  => 65,
-    ErrorKind::Verify                    => 66,
   }
 }
 
@@ -688,7 +686,6 @@ pub fn error_to_u32<E>(e: &ErrorKind<E>) -> u32 {
         ErrorKind::Not                       => "Negation",
         ErrorKind::Permutation               => "Permutation",
         ErrorKind::ManyTill                  => "ManyTill",
-        ErrorKind::Verify                    => "predicate verification",
       }
 
     }
diff --git a/src/verbose_errors.rs b/src/verbose_errors.rs
index 0389ce7..fe4165d 100644
--- a/src/verbose_errors.rs
+++ b/src/verbose_errors.rs
@@ -1,20 +1,3 @@
-//! Error management
-//!
-//! there are two ways to handle errors in nom. The first one,
-//! activated by default, uses the `nom::ErrorKind<E=u32>` enum
-//! in the error branch of `IResult`. This enum can hold either
-//! a parser specific error code, or a custom error type you
-//! specify.
-//!
-//! If you need more advanced error management, you can activate
-//! the "verbose-errors" compilation feature, which will give you
-//! the error system available in nom 1.0. The verbose errors
-//! accumulate error codes and positions as you backtrack through
-//! the parser tree. From there, you can precisely identify which
-//! parts of the input triggered the error case.
-//!
-//! Please note that the verbose error management is a bit slower
-//! than the simple one.
 use util::ErrorKind;
 use internal::{IResult, IError};
 use internal::IResult::*;
@@ -23,7 +6,7 @@ use std::boxed::Box;
 /// Contains the error that a parser can return
 ///
 /// If you use the `verbose-errors` compilation feature,
-/// `nom::Err` will be the enum defined here,
+/// the error type will be the enum defined here,
 /// otherwise, it will amount to a `ErrorKind<E=u32>`.
 ///
 /// It can represent a linked list of errors, indicating the path taken in the parsing tree, with corresponding position in the input data.
@@ -83,37 +66,6 @@ impl<I,O,E> IResult<I,O,E> {
   }
 }
 
-#[cfg(not(feature = "core"))]
-use std::any::Any;
-#[cfg(not(feature = "core"))]
-use std::{error,fmt};
-#[cfg(not(feature = "core"))]
-use std::fmt::Debug;
-#[cfg(not(feature = "core"))]
-impl<P:Debug+Any,E:Debug+Any> error::Error for Err<P,E> {
-  fn description(&self) -> &str {
-    let kind = match *self {
-      Err::Code(ref e) | Err::Node(ref e, _) | Err::Position(ref e, _) | Err::NodePosition(ref e, _, _) => e
-    };
-    kind.description()
-  }
-}
-
-#[cfg(not(feature = "core"))]
-impl<P:fmt::Debug,E:fmt::Debug> fmt::Display for Err<P,E> {
-  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-    match *self {
-      Err::Code(ref e) | Err::Node(ref e, _) => {
-        write!(f, "{:?}", e)
-      },
-      Err::Position(ref e, ref p) | Err::NodePosition(ref e, ref p, _) => {
-        write!(f, "{:?}:{:?}", p, e)
-      }
-    }
-  }
-}
-
-
 /// translate parser result from IResult<I,O,u32> to IResult<I,O,E> with a custom type
 ///
 /// ```
@@ -125,9 +77,9 @@ impl<P:fmt::Debug,E:fmt::Debug> fmt::Display for Err<P,E> {
 /// # use std::boxed::Box;
 /// # fn main() {
 ///     // will add a Custom(42) error to the error chain
-///     named!(err_test, add_return_error!(ErrorKind::Custom(42), tag!("abcd")));
+///     named!(err_test, add_error!(ErrorKind::Custom(42), tag!("abcd")));
 ///     // Convert to IREsult<&[u8], &[u8], &str>
-///     named!(parser<&[u8], &[u8], &str>, add_return_error!(ErrorKind::Custom("custom error message"), fix_error!(&str, err_test)));
+///     named!(parser<&[u8], &[u8], &str>, add_error!(ErrorKind::Custom("custom error message"), fix_error!(&str, err_test)));
 ///
 ///     let a = &b"efghblah"[..];
 ///     let res_a = parser(a);
diff --git a/src/whitespace.rs b/src/whitespace.rs
index 450ed3c..abd60ad 100644
--- a/src/whitespace.rs
+++ b/src/whitespace.rs
@@ -112,7 +112,6 @@ macro_rules! wrap_sep (
   );
 );
 
-#[doc(hidden)]
 #[macro_export]
 macro_rules! pair_sep (
   ($i:expr, $separator:ident, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
@@ -133,7 +132,6 @@ macro_rules! pair_sep (
   );
 );
 
-#[doc(hidden)]
 #[macro_export]
 macro_rules! delimited_sep (
   ($i:expr, $separator:ident, $submac1:ident!( $($args1:tt)* ), $($rest:tt)+) => (
@@ -150,7 +148,6 @@ macro_rules! delimited_sep (
   );
 );
 
-#[doc(hidden)]
 #[macro_export]
 macro_rules! separated_pair_sep (
   ($i:expr, $separator:ident, $submac1:ident!( $($args1:tt)* ), $($rest:tt)+) => (
@@ -167,7 +164,6 @@ macro_rules! separated_pair_sep (
   );
 );
 
-#[doc(hidden)]
 #[macro_export]
 macro_rules! preceded_sep (
   ($i:expr, $separator:ident, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
@@ -190,7 +186,6 @@ macro_rules! preceded_sep (
   );
 );
 
-#[doc(hidden)]
 #[macro_export]
 macro_rules! terminated_sep (
   ($i:expr, $separator:ident, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
@@ -203,7 +198,7 @@ macro_rules! terminated_sep (
     }
   );
   ($i:expr, $separator:ident, $submac:ident!( $($args:tt)* ), $g:expr) => (
-    terminated_sep!($i, $separator, $submac!($($args)*), call!($g));
+    terminated_wrap!($i, $separator, $submac!($($args)*), call!($g));
   );
   ($i:expr, $separator:ident, $f:expr, $submac:ident!( $($args:tt)* )) => (
     terminated_sep!($i, $separator, call!($f), $submac!($($args)*));
@@ -278,7 +273,6 @@ macro_rules! tuple_sep (
   );
 );
 
-#[doc(hidden)]
 #[macro_export]
 macro_rules! do_parse_sep (
   (__impl $i:expr, $separator:ident, $consumed:expr, ( $($rest:expr),* )) => (
@@ -370,7 +364,6 @@ macro_rules! do_parse_sep (
   );
 );
 
-#[doc(hidden)]
 #[macro_export]
 macro_rules! permutation_sep (
   ($i:expr, $separator:ident, $($rest:tt)*) => (
@@ -462,7 +455,6 @@ macro_rules! permutation_iterator_sep (
   };
 );
 
-#[doc(hidden)]
 #[macro_export]
 macro_rules! alt_sep (
   (__impl $i:expr, $separator:ident, $e:ident | $($rest:tt)*) => (
@@ -539,7 +531,6 @@ macro_rules! alt_sep (
   );
 );
 
-#[doc(hidden)]
 #[macro_export]
 macro_rules! alt_complete_sep (
   ($i:expr, $separator:ident, $e:ident | $($rest:tt)*) => (
@@ -588,7 +579,6 @@ macro_rules! alt_complete_sep (
   );
 );
 
-#[doc(hidden)]
 #[macro_export]
 macro_rules! switch_sep (
   (__impl $i:expr, $separator:ident, $submac:ident!( $($args:tt)* ), $($p:pat => $subrule:ident!( $($args2:tt)* ))|* ) => (
@@ -624,7 +614,6 @@ macro_rules! switch_sep (
   );
 );
 
-#[doc(hidden)]
 #[macro_export]
 macro_rules! separated_list_sep (
   ($i:expr, $separator:ident, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
@@ -645,19 +634,11 @@ macro_rules! separated_list_sep (
   );
 );
 
-/// helper macros to build a separator parser
-///
-/// ```
-/// # #[macro_use] extern crate nom;
-/// # use nom::IResult::Done;
-/// named!(pub space, eat_separator!(&b" \t"[..]));
-/// # fn main() {}
-/// ```
 #[macro_export]
 macro_rules! eat_separator (
   ($i:expr, $arr:expr) => (
     {
-      use $crate::{InputLength,InputIter,Slice};
+      use $crate::{InputLength,IterIndices,Slice};
       if ($i).input_len() == 0 {
         $crate::IResult::Done($i, ($i).slice(0..0))
       } else {
@@ -679,22 +660,6 @@ macro_rules! eat_separator (
   );
 );
 
-/// sep is the parser rewriting macro for whitespace separated formats
-///
-/// it takes as argument a space eating function and a parser tree,
-/// and will intersperse the space parser everywhere
-///
-/// ```ignore
-/// #[macro_export]
-/// macro_rules! ws (
-///   ($i:expr, $($args:tt)*) => (
-///     {
-///       use $crate::sp;
-///       sep!($i, sp, $($args)*)
-///     }
-///   )
-/// );
-/// ```
 #[macro_export]
 macro_rules! sep (
   ($i:expr,  $separator:ident, tuple ! ($($rest:tt)*) ) => {


Test patch:
diff --git a/tests/arithmetic.rs b/tests/arithmetic.rs
index 40ffc8c..6f3d788 100644
--- a/tests/arithmetic.rs
+++ b/tests/arithmetic.rs
@@ -3,18 +3,11 @@ extern crate nom;
 
 use nom::{IResult,digit};
 
-// Parser definition
-
 use std::str;
 use std::str::FromStr;
 
-// We parse any expr surrounded by parens, ignoring all whitespaces around those
 named!(parens<i64>, ws!(delimited!( tag!("("), expr, tag!(")") )) );
 
-// We transform an integer string into a i64, ignoring surrounding whitespaces
-// We look for a digit suite, and try to convert it.
-// If either str::from_utf8 or FromStr::from_str fail,
-// we fallback to the parens parser defined above
 named!(factor<i64>, alt!(
     map_res!(
       map_res!(
@@ -27,32 +20,27 @@ named!(factor<i64>, alt!(
   )
 );
 
-// We read an initial factor and for each time we find
-// a * or / operator followed by another factor, we do
-// the math by folding everything
-named!(term <i64>, do_parse!(
-    init: factor >>
-    res:  fold_many0!(
-        pair!(alt!(tag!("*") | tag!("/")), factor),
-        init,
-        |acc, (op, val): (&[u8], i64)| {
-            if (op[0] as char) == '*' { acc * val } else { acc / val }
-        }
-    ) >>
-    (res)
+named!(term <i64>, chain!(
+    mut acc: factor  ~
+             many0!(
+               alt!(
+                 tap!(mul: preceded!(tag!("*"), factor) => acc = acc * mul) |
+                 tap!(div: preceded!(tag!("/"), factor) => acc = acc / div)
+               )
+             ),
+    || { return acc }
   )
 );
 
-named!(expr <i64>, do_parse!(
-    init: term >>
-    res:  fold_many0!(
-        pair!(alt!(tag!("+") | tag!("-")), term),
-        init,
-        |acc, (op, val): (&[u8], i64)| {
-            if (op[0] as char) == '+' { acc + val } else { acc - val }
-        }
-    ) >>
-    (res)
+named!(expr <i64>, chain!(
+    mut acc: term  ~
+             many0!(
+               alt!(
+                 tap!(add: preceded!(tag!("+"), term) => acc = acc + add) |
+                 tap!(sub: preceded!(tag!("-"), term) => acc = acc - sub)
+               )
+             ),
+    || { return acc }
   )
 );
 
diff --git a/tests/blockbuf-arithmetic.rs b/tests/blockbuf-arithmetic.rs
index a412db0..6773b59 100644
--- a/tests/blockbuf-arithmetic.rs
+++ b/tests/blockbuf-arithmetic.rs
@@ -1,9 +1,9 @@
 #[macro_use]
 extern crate nom;
-/*
+
 extern crate bytes;
 
-use nom::{Compare,CompareResult,InputLength,InputIter,Slice,HexDisplay};
+use nom::{Compare,CompareResult,InputLength,IterIndices,Slice,HexDisplay};
 
 use std::str;
 use std::str::FromStr;
@@ -80,7 +80,7 @@ impl<'a> Slice<RangeFull> for BlockSlice<'a> {
 }
 
 
-impl<'a> InputIter for BlockSlice<'a> {
+impl<'a> IterIndices for BlockSlice<'a> {
     type Item     = u8;
     type RawItem  = u8;
     type Iter     = Enumerate<WrapCursor<'a>>;
@@ -95,7 +95,7 @@ impl<'a> InputIter for BlockSlice<'a> {
     fn position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::RawItem) -> bool {
       self.cursor().position(|b| predicate(b))
     }
-    fn slice_index(&self, count:usize) -> Option<usize> {
+    fn index(&self, count:usize) -> Option<usize> {
       if self.end - self.start >= count {
         Some(count)
       } else {
@@ -191,7 +191,7 @@ impl<'a> Iterator for WrapCursor<'a> {
 macro_rules! block_eat_separator (
   ($i:expr, $arr:expr) => (
     {
-      use nom::{InputLength,InputIter,Slice};
+      use nom::{InputLength,IterIndices,Slice};
       if ($i).input_len() == 0 {
         nom::IResult::Done($i, ($i).slice(0..0))
       } else {
@@ -251,29 +251,27 @@ block_named!(factor<i64>, alt!(
   )
 );
 
-block_named!(term <i64>, do_parse!(
-    init: factor >>
-    res:  fold_many0!(
-        pair!(alt!(tag!("*") | tag!("/")), factor),
-        init,
-        |acc, (op, val): (BlockSlice, i64)| {
-            if (op.cursor().next().unwrap() as char) == '*' { acc * val } else { acc / val }
-        }
-    ) >>
-    (res)
+block_named!(term <i64>, chain!(
+    mut acc: factor  ~
+             many0!(
+               alt!(
+                 tap!(mul: preceded!(tag!("*"), factor) => acc = acc * mul) |
+                 tap!(div: preceded!(tag!("/"), factor) => acc = acc / div)
+               )
+             ),
+    || { return acc }
   )
 );
 
-block_named!(expr <i64>, do_parse!(
-    init: term >>
-    res:  fold_many0!(
-        pair!(alt!(tag!("+") | tag!("-")), term),
-        init,
-        |acc, (op, val): (BlockSlice, i64)| {
-            if (op.cursor().next().unwrap() as char) == '+' { acc + val } else { acc - val }
-        }
-    ) >>
-    (res)
+block_named!(expr <i64>, chain!(
+    mut acc: term  ~
+             many0!(
+               alt!(
+                 tap!(add: preceded!(tag!("+"), term) => acc = acc + add) |
+                 tap!(sub: preceded!(tag!("-"), term) => acc = acc - sub)
+               )
+             ),
+    || { return acc }
   )
 );
 
@@ -294,8 +292,10 @@ fn sl<'a>(input: &'a BlockBuf) -> BlockSlice<'a> {
 }
 
 fn to_i64<'a>(input: BlockSlice<'a>) -> Result<i64, ()> {
+  //println!("got input: {:?}", input);
   let v: Vec<u8> = input.cursor().collect();
 
+  //println!("collected: {}", &v.to_hex(16));
   match str::from_utf8(&v) {
     Err(_) => Err(()),
     Ok(s) => match FromStr::from_str(s) {
@@ -307,15 +307,40 @@ fn to_i64<'a>(input: BlockSlice<'a>) -> Result<i64, ()> {
 
 #[test]
 fn factor_test() {
+  //assert_eq!(factor(&b" 12"[..]), IResult::Done(&b""[..], 12));
+  //assert_eq!(factor(&b"537  "[..]), IResult::Done(&b""[..], 537));
+  //assert_eq!(factor(&b"  24   "[..]), IResult::Done(&b""[..], 24));
+
   let a = blockbuf_from(&b"3"[..]);
+  //let empty = blockbuf_from(&b""[..]);
   println!("calculated: {:?}", factor(sl(&a)));
+  //assert_eq!(factor(sl(&a)), IResult::Done(sl(&empty),3));
+}
+
+/*
+#[test]
+fn term_test() {
+  assert_eq!(term(&b" 12 *2 /  3"[..]), IResult::Done(&b""[..], 8));
+  assert_eq!(term(&b" 2* 3  *2 *2 /  3"[..]), IResult::Done(&b""[..], 8));
+  assert_eq!(term(&b" 48 /  3/2"[..]), IResult::Done(&b""[..], 8));
 }
 
+#[test]
+fn expr_test() {
+  assert_eq!(expr(&b" 1 +  2 "[..]), IResult::Done(&b""[..], 3));
+  assert_eq!(expr(&b" 12 + 6 - 4+  3"[..]), IResult::Done(&b""[..], 17));
+  assert_eq!(expr(&b" 1 + 2*3 + 4"[..]), IResult::Done(&b""[..], 11));
+}
+*/
 #[test]
 fn parens_test() {
+  //assert_eq!(expr(&b" (  2 )"[..]), IResult::Done(&b""[..], 2));
+  //assert_eq!(expr(&b" 2* (  3 + 4 ) "[..]), IResult::Done(&b""[..], 14));
   let input1 = blockbuf_from(&b" 2* (  3 + 4 ) "[..]);
   println!("calculated 1: {:?}", expr(sl(&input1)));
   let input2 = blockbuf_from(&b"  2*2 / ( 5 - 1) + 3"[..]);
+  //let empty = blockbuf_from(&b""[..]);
   println!("calculated 2: {:?}", expr(sl(&input2)));
+  //assert_eq!(expr(sl(&input2)), IResult::Done(sl(&empty), 4));
 }
-*/
+
diff --git a/tests/json.rs b/tests/json.rs
index b036916..c42bd7d 100644
--- a/tests/json.rs
+++ b/tests/json.rs
@@ -3,7 +3,7 @@
 #[macro_use]
 extern crate nom;
 
-use nom::{digit, alphanumeric};
+use nom::{IResult, digit, alphanumeric};
 
 use std::str::{self,FromStr};
 use std::collections::HashMap;
diff --git a/tests/named_args.rs b/tests/named_args.rs
deleted file mode 100644
index e998a08..0000000
--- a/tests/named_args.rs
+++ /dev/null
@@ -1,108 +0,0 @@
-#[macro_use]
-extern crate nom;
-
-use nom::{IResult,digit};
-
-// Parser definition
-
-use std::str;
-use std::str::FromStr;
-
-use self::Operator::*;
-
-enum Operator {
-    Slash,
-    Star,
-}
-
-impl Operator {
-    fn to_str(&self) -> &'static str {
-        match *self {
-            Slash => "/",
-            Star => "*",
-        }
-    }
-}
-
-// Parse the specified `Operator`.
-named_args!(operator(op: Operator) <&[u8]>,
-    tag!(op.to_str())
-);
-
-// We parse any expr surrounded by the tags `open_tag` and `close_tag`, ignoring all whitespaces around those
-named_args!(brackets<'a>(open_tag: &str, close_tag: &str) <i64>, ws!(delimited!( tag!(open_tag), expr, tag!(close_tag) )) );
-
-// We transform an integer string into a i64, ignoring surrounding whitespaces
-// We look for a digit suite, and try to convert it.
-// If either str::from_utf8 or FromStr::from_str fail,
-// we fallback to the brackets parser defined above
-named!(factor<i64>, alt!(
-    map_res!(
-      map_res!(
-        ws!(digit),
-        str::from_utf8
-      ),
-      FromStr::from_str
-    )
-  | call!(brackets, "(", ")")
-  )
-);
-
-// We read an initial factor and for each time we find
-// a * or / operator followed by another factor, we do
-// the math by folding everything
-named!(term <i64>, do_parse!(
-    init: factor >>
-    res:  fold_many0!(
-        pair!(alt!(call!(operator, Star) | call!(operator, Slash)), factor),
-        init,
-        |acc, (op, val): (&[u8], i64)| {
-            if (op[0] as char) == '*' { acc * val } else { acc / val }
-        }
-    ) >>
-    (res)
-  )
-);
-
-named!(expr <i64>, do_parse!(
-    init: term >>
-    res:  fold_many0!(
-        pair!(alt!(tag!("+") | tag!("-")), term),
-        init,
-        |acc, (op, val): (&[u8], i64)| {
-            if (op[0] as char) == '+' { acc + val } else { acc - val }
-        }
-    ) >>
-    (res)
-  )
-);
-
-#[test]
-fn factor_test() {
-  assert_eq!(factor(&b"3"[..]), IResult::Done(&b""[..], 3));
-  assert_eq!(factor(&b" 12"[..]), IResult::Done(&b""[..], 12));
-  assert_eq!(factor(&b"537  "[..]), IResult::Done(&b""[..], 537));
-  assert_eq!(factor(&b"  24   "[..]), IResult::Done(&b""[..], 24));
-}
-
-
-#[test]
-fn term_test() {
-  assert_eq!(term(&b" 12 *2 /  3"[..]), IResult::Done(&b""[..], 8));
-  assert_eq!(term(&b" 2* 3  *2 *2 /  3"[..]), IResult::Done(&b""[..], 8));
-  assert_eq!(term(&b" 48 /  3/2"[..]), IResult::Done(&b""[..], 8));
-}
-
-#[test]
-fn expr_test() {
-  assert_eq!(expr(&b" 1 +  2 "[..]), IResult::Done(&b""[..], 3));
-  assert_eq!(expr(&b" 12 + 6 - 4+  3"[..]), IResult::Done(&b""[..], 17));
-  assert_eq!(expr(&b" 1 + 2*3 + 4"[..]), IResult::Done(&b""[..], 11));
-}
-
-#[test]
-fn parens_test() {
-  assert_eq!(expr(&b" (  2 )"[..]), IResult::Done(&b""[..], 2));
-  assert_eq!(expr(&b" 2* (  3 + 4 ) "[..]), IResult::Done(&b""[..], 14));
-  assert_eq!(expr(&b"  2*2 / ( 5 - 1) + 3"[..]), IResult::Done(&b""[..], 4));
-}