Bug 1468349 - Vendor in new freebsd deps for u2f-hid-rs r=mgoodwin
authorJ.C. Jones <jjones@mozilla.com>
Tue, 12 Jun 2018 11:03:01 -0700
changeset 476793 ee93e9e7bcfd3cda3e5ef807ecc9d1db74fbf04a
parent 476792 8ebf45b0854ace6848090c02d6c4935bc515fe0a
child 476794 035cac21d2b1194053fc90861159cbcb6181216b
push id9374
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:43:20 +0000
treeherdermozilla-beta@160e085dfb0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmgoodwin
bugs1468349
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1468349 - Vendor in new freebsd deps for u2f-hid-rs r=mgoodwin MozReview-Commit-ID: 26E21CeZiLj
Cargo.lock
third_party/rust/devd-rs/.cargo-checksum.json
third_party/rust/devd-rs/.rustfmt.toml
third_party/rust/devd-rs/CODE_OF_CONDUCT.md
third_party/rust/devd-rs/Cargo.toml
third_party/rust/devd-rs/README.md
third_party/rust/devd-rs/UNLICENSE
third_party/rust/devd-rs/examples/main.rs
third_party/rust/devd-rs/src/data.rs
third_party/rust/devd-rs/src/lib.rs
third_party/rust/devd-rs/src/parser.rs
third_party/rust/devd-rs/src/result.rs
third_party/rust/nom-1.2.4/.cargo-checksum.json
third_party/rust/nom-1.2.4/.travis.yml
third_party/rust/nom-1.2.4/CHANGELOG.md
third_party/rust/nom-1.2.4/Cargo.toml
third_party/rust/nom-1.2.4/LICENSE
third_party/rust/nom-1.2.4/nom/.cargo-checksum.json
third_party/rust/nom-1.2.4/nom/.travis.yml
third_party/rust/nom-1.2.4/nom/CHANGELOG.md
third_party/rust/nom-1.2.4/nom/Cargo.toml
third_party/rust/nom-1.2.4/nom/LICENSE
third_party/rust/nom-1.2.4/nom/src/bits.rs
third_party/rust/nom-1.2.4/nom/src/bytes.rs
third_party/rust/nom-1.2.4/nom/src/character.rs
third_party/rust/nom-1.2.4/nom/src/internal.rs
third_party/rust/nom-1.2.4/nom/src/lib.rs
third_party/rust/nom-1.2.4/nom/src/macros.rs
third_party/rust/nom-1.2.4/nom/src/methods.rs
third_party/rust/nom-1.2.4/nom/src/nom.rs
third_party/rust/nom-1.2.4/nom/src/regexp.rs
third_party/rust/nom-1.2.4/nom/src/str.rs
third_party/rust/nom-1.2.4/nom/src/stream.rs
third_party/rust/nom-1.2.4/nom/src/util.rs
third_party/rust/nom-1.2.4/nom/tests/arithmetic.rs
third_party/rust/nom-1.2.4/nom/tests/arithmetic_ast.rs
third_party/rust/nom-1.2.4/nom/tests/cross_function_backtracking.rs
third_party/rust/nom-1.2.4/nom/tests/ini.rs
third_party/rust/nom-1.2.4/nom/tests/ini_str.rs
third_party/rust/nom-1.2.4/nom/tests/issues.rs
third_party/rust/nom-1.2.4/nom/tests/mp4.rs
third_party/rust/nom-1.2.4/nom/tests/omnom.rs
third_party/rust/nom-1.2.4/nom/tests/test1.rs
third_party/rust/nom-1.2.4/src/bits.rs
third_party/rust/nom-1.2.4/src/bytes.rs
third_party/rust/nom-1.2.4/src/character.rs
third_party/rust/nom-1.2.4/src/internal.rs
third_party/rust/nom-1.2.4/src/lib.rs
third_party/rust/nom-1.2.4/src/macros.rs
third_party/rust/nom-1.2.4/src/methods.rs
third_party/rust/nom-1.2.4/src/nom.rs
third_party/rust/nom-1.2.4/src/regexp.rs
third_party/rust/nom-1.2.4/src/str.rs
third_party/rust/nom-1.2.4/src/stream.rs
third_party/rust/nom-1.2.4/src/util.rs
third_party/rust/nom-1.2.4/tests/arithmetic.rs
third_party/rust/nom-1.2.4/tests/arithmetic_ast.rs
third_party/rust/nom-1.2.4/tests/cross_function_backtracking.rs
third_party/rust/nom-1.2.4/tests/ini.rs
third_party/rust/nom-1.2.4/tests/ini_str.rs
third_party/rust/nom-1.2.4/tests/issues.rs
third_party/rust/nom-1.2.4/tests/mp4.rs
third_party/rust/nom-1.2.4/tests/omnom.rs
third_party/rust/nom-1.2.4/tests/test1.rs
third_party/rust/nom/.cargo-checksum.json
third_party/rust/nom/.travis.yml
third_party/rust/nom/CHANGELOG.md
third_party/rust/nom/Cargo.toml
third_party/rust/nom/LICENSE
third_party/rust/nom/src/bits.rs
third_party/rust/nom/src/branch.rs
third_party/rust/nom/src/bytes.rs
third_party/rust/nom/src/character.rs
third_party/rust/nom/src/internal.rs
third_party/rust/nom/src/lib.rs
third_party/rust/nom/src/macros.rs
third_party/rust/nom/src/methods.rs
third_party/rust/nom/src/multi.rs
third_party/rust/nom/src/nom.rs
third_party/rust/nom/src/regexp.rs
third_party/rust/nom/src/sequence.rs
third_party/rust/nom/src/simple_errors.rs
third_party/rust/nom/src/str.rs
third_party/rust/nom/src/stream.rs
third_party/rust/nom/src/traits.rs
third_party/rust/nom/src/util.rs
third_party/rust/nom/src/verbose_errors.rs
third_party/rust/nom/src/whitespace.rs
third_party/rust/nom/tests/arithmetic.rs
third_party/rust/nom/tests/arithmetic_ast.rs
third_party/rust/nom/tests/blockbuf-arithmetic.rs
third_party/rust/nom/tests/cross_function_backtracking.rs
third_party/rust/nom/tests/float.rs
third_party/rust/nom/tests/ini.rs
third_party/rust/nom/tests/ini_str.rs
third_party/rust/nom/tests/issues.rs
third_party/rust/nom/tests/json.rs
third_party/rust/nom/tests/mp4.rs
third_party/rust/nom/tests/multiline.rs
third_party/rust/nom/tests/named_args.rs
third_party/rust/nom/tests/omnom.rs
third_party/rust/nom/tests/overflow.rs
third_party/rust/nom/tests/reborrow_fold.rs
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -554,16 +554,25 @@ version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "darling_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "devd-rs"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "diff"
 version = "0.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "docopt"
 version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -838,17 +847,17 @@ dependencies = [
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "mozurl 0.0.1",
  "mp4parse_capi 0.10.1",
  "netwerk_helper 0.0.1",
  "nserror 0.1.0",
  "nsstring 0.1.0",
  "prefs_parser 0.0.1",
  "rsdparsa_capi 0.1.0",
- "u2fhid 0.1.0",
+ "u2fhid 0.2.0",
  "webrender_bindings 0.1.0",
  "xpcom 0.1.0",
 ]
 
 [[package]]
 name = "gl_generator"
 version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1378,16 +1387,24 @@ version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "nom"
 version = "1.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "nom"
+version = "3.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "nserror"
 version = "0.1.0"
 dependencies = [
  "nsstring 0.1.0",
 ]
 
 [[package]]
 name = "nsstring"
@@ -2148,22 +2165,23 @@ source = "registry+https://github.com/ru
 
 [[package]]
 name = "typeable"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "u2fhid"
-version = "0.1.0"
+version = "0.2.0"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "boxfnonce 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "devd-rs 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
  "libudev 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "runloop 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2540,16 +2558,17 @@ dependencies = [
 "checksum cstr-macros 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f9f316203d1ea36f4f18316822806f6999aa3dc5ed1adf51e35b77e3b3933d78"
 "checksum cubeb 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8a3502aafa1bf95c524f65d2ba46d8741700c6a8a9543ea52c6da3d8b69a2896"
 "checksum cubeb-backend 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcac95519416d9ec814db2dc40e6293e7da25b906023d93f48b87f0587ab138"
 "checksum cubeb-core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37f7b20f757a4e4b6aa28863236551bff77682dc6db192eba15af615492b5445"
 "checksum cubeb-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "653b9e245d35dbe2a2da7c4586275cee75ff656ddeb02d4a73b4afdfa6d67502"
 "checksum darling 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d3effd06d4057f275cb7858889f4952920bab78dd8ff0f6e7dfe0c8d2e67ed89"
 "checksum darling_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "167dd3e235c2f1da16a635c282630452cdf49191eb05711de1bcd1d3d5068c00"
 "checksum darling_macro 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c53edaba455f6073a10c27c72440860eb3f60444f8c8660a391032eeae744d82"
+"checksum devd-rs 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e7c9ac481c38baf400d3b732e4a06850dfaa491d1b6379a249d9d40d14c2434c"
 "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a"
 "checksum docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d8acd393692c503b168471874953a2531df0e9ab77d0b6bbc582395743300a4a"
 "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
 "checksum dtoa-short 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "068d4026697c1a18f0b0bb8cfcad1b0c151b90d8edb9bf4c235ad68128920d1d"
 "checksum dwrote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b26e30aaa6bf31ec830db15fec14ed04f0f2ecfcc486ecfce88c55d3389b237f"
 "checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a"
 "checksum ena 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cabe5a5078ac8c506d3e4430763b1ba9b609b1286913e7d08e581d1c2de9b7e5"
 "checksum encoding_c 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "769ecb8b33323998e482b218c0d13cd64c267609023b4b7ec3ee740714c318ee"
@@ -2613,16 +2632,17 @@ dependencies = [
 "checksum moz_cbor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20c82a57087fd5990d7122dbff1607c3b20c3d2958e9d9ad9765aab415e2c91c"
 "checksum mp4parse_fallible 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6626c2aef76eb8f984eef02e475883d3fe9112e114720446c5810fc5f045cd30"
 "checksum msdos_time 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "65ba9d75bcea84e07812618fedf284a64776c2f2ea0cad6bca7f69739695a958"
 "checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09"
 "checksum new-ordered-float 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8ccbebba6fb53a6d2bdcfaf79cb339bc136dee3bfff54dc337a334bafe36476a"
 "checksum new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4"
 "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
 "checksum nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b8c256fd9471521bcb84c3cdba98921497f1a331cbc15b8030fc63b82050ce"
+"checksum nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05aec50c70fd288702bcd93284a8444607f3292dbdf2a30de5ea5dcdbe72287b"
 "checksum num 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "a311b77ebdc5dd4cf6449d81e4135d9f0e3b153839ac90e648a8ef538f923525"
 "checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba"
 "checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01"
 "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
 "checksum num-traits 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e7de20f146db9d920c45ee8ed8f71681fd9ade71909b48c3acbd766aa504cf10"
 "checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d"
 "checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
 "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/devd-rs/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".rustfmt.toml":"2af0439152afb5f592e67eb815db1a2711e3951d94d6ec2a3343ccf17cf7eb53","CODE_OF_CONDUCT.md":"62f073941a34756006851cef8d5d081f6332a986063e87deafeb621f3f6ff554","Cargo.toml":"82c3a9280afb5f4ac916fbca17ca4913b9f66f90c28eb48be1b66f5efe363e87","README.md":"27a78f684d46d92d64bdda18e8b55f132960836347a654d4024ede000e980bec","UNLICENSE":"7e12e5df4bae12cb21581ba157ced20e1986a0508dd10d0e8a4ab9a4cf94e85c","examples/main.rs":"734a87846b61d09d2aaca444c69dc61765f66df34602f3a4acf1255f95404226","src/data.rs":"677b52a636deb1f0ffc623dbdc5ed7acd78d915117825ced7031c6fa6f0c861e","src/lib.rs":"5e1539f2e197214f90cdcb5835c9b082773b0cd18f6c18e03067ebe04f18a6b7","src/parser.rs":"8459eed676eb9190f592b159d099d542bbcc447d6fb19b46f7a61c60a1ef8a8e","src/result.rs":"4088fc879652c115a13d8a6e6a71fab8571a7982e740af6a91115f3a82aef236"},"package":"e7c9ac481c38baf400d3b732e4a06850dfaa491d1b6379a249d9d40d14c2434c"}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/devd-rs/.rustfmt.toml
@@ -0,0 +1,9 @@
+max_width = 256
+fn_call_width = 96
+struct_lit_width = 64
+struct_variant_width = 96
+array_width = 256
+newline_style = "Native"
+use_try_shorthand = true
+match_block_trailing_comma = true
+fn_call_style = "Block"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/devd-rs/CODE_OF_CONDUCT.md
@@ -0,0 +1,74 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, gender identity and expression, level of experience,
+nationality, personal appearance, race, religion, or sexual identity and
+orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+  address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+  professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the project owner at greg@unrelenting.technology. All
+complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. The project owner is
+obligated to maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good
+faith may face temporary or permanent repercussions as determined by other
+members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
+available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
new file mode 100644
--- /dev/null
+++ b/third_party/rust/devd-rs/Cargo.toml
@@ -0,0 +1,28 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g. crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+name = "devd-rs"
+version = "0.2.1"
+authors = ["Greg V <greg@unrelenting.technology>"]
+description = "An interface to devd, the device hotplug daemon on FreeBSD and DragonFlyBSD"
+homepage = "https://github.com/myfreeweb/devd-rs"
+readme = "README.md"
+keywords = ["System", "FreeBSD", "DragonFlyBSD", "devd", "hotplug"]
+categories = ["os::unix-apis"]
+license = "Unlicense/MIT"
+repository = "https://github.com/myfreeweb/devd-rs"
+[dependencies.libc]
+version = "0"
+
+[dependencies.nom]
+version = "3.2"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/devd-rs/README.md
@@ -0,0 +1,25 @@
+[![crates.io](https://img.shields.io/crates/v/systemstat.svg)](https://crates.io/crates/systemstat)
+[![unlicense](https://img.shields.io/badge/un-license-green.svg?style=flat)](http://unlicense.org)
+
+# devd-rs
+
+A Rust library for listening to FreeBSD (also DragonFlyBSD) [devd](https://www.freebsd.org/cgi/man.cgi?devd)'s device attach-detach notifications.
+
+Listens on `/var/run/devd.seqpacket.pipe` and parses messages using [nom](https://github.com/Geal/nom).
+
+## Usage
+
+See [examples/main.rs](https://github.com/myfreeweb/devd-rs/blob/master/examples/main.rs).
+
+## Contributing
+
+Please feel free to submit pull requests!
+
+By participating in this project you agree to follow the [Contributor Code of Conduct](http://contributor-covenant.org/version/1/4/).
+
+[The list of contributors is available on GitHub](https://github.com/myfreeweb/devd-rs/graphs/contributors).
+
+## License
+
+This is free and unencumbered software released into the public domain.  
+For more information, please refer to the `UNLICENSE` file or [unlicense.org](http://unlicense.org).
new file mode 100644
--- /dev/null
+++ b/third_party/rust/devd-rs/UNLICENSE
@@ -0,0 +1,24 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <http://unlicense.org/>
new file mode 100644
--- /dev/null
+++ b/third_party/rust/devd-rs/examples/main.rs
@@ -0,0 +1,12 @@
+extern crate devd_rs;
+
+use devd_rs::*;
+
+fn main() {
+    let mut ctx = Context::new().unwrap();
+    loop {
+        if let Ok(ev) = ctx.wait_for_event(1000) {
+            println!("{:?}", ev);
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/devd-rs/src/data.rs
@@ -0,0 +1,9 @@
+pub use std::collections::BTreeMap;
+
+#[derive(Debug, Clone, PartialEq)]
+pub enum Event {
+    Notify { system: String, subsystem: String, kind: String, data: BTreeMap<String, String> },
+    Attach { dev: String, parent: BTreeMap<String, String>, location: String },
+    Detach { dev: String, parent: BTreeMap<String, String>, location: String },
+    Nomatch { parent: BTreeMap<String, String>, location: String },
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/devd-rs/src/lib.rs
@@ -0,0 +1,98 @@
+extern crate libc;
+#[macro_use]
+extern crate nom;
+
+pub mod result;
+pub mod data;
+pub mod parser;
+
+use libc::{
+    c_int, nfds_t,
+    poll, pollfd, POLLIN,
+    socket, connect, sockaddr_un, AF_UNIX, SOCK_SEQPACKET
+};
+use std::os::unix::io::{FromRawFd, RawFd};
+use std::os::unix::net::UnixStream;
+use std::{io, mem, ptr};
+use io::{BufRead, BufReader};
+
+pub use result::*;
+pub use data::*;
+
+const SOCKET_PATH: &'static str = "/var/run/devd.seqpacket.pipe";
+
+pub fn parse_devd_event(e: String) -> Result<Event> {
+    match parser::event(e.as_bytes()) {
+        parser::IResult::Done(_, x) => Ok(x),
+        _ => Err(Error::Parse),
+    }
+}
+
+#[derive(Debug)]
+pub struct Context {
+    sock: BufReader<UnixStream>,
+    sockfd: RawFd,
+}
+
+impl Context {
+    pub fn new() -> Result<Context> {
+        unsafe {
+            let sockfd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+            if sockfd < 0 {
+                return Err(io::Error::last_os_error().into());
+            }
+            let mut sockaddr = sockaddr_un {
+                sun_family: AF_UNIX as _,
+                .. mem::zeroed()
+            };
+            ptr::copy_nonoverlapping(
+                SOCKET_PATH.as_ptr(),
+                sockaddr.sun_path.as_mut_ptr() as *mut u8,
+                SOCKET_PATH.len());
+            if connect(
+                sockfd,
+                &sockaddr as *const sockaddr_un as *const _,
+                (mem::size_of_val(&AF_UNIX) + SOCKET_PATH.len()) as _) < 0 {
+                return Err(io::Error::last_os_error().into());
+            }
+            Ok(Context {
+                sock: BufReader::new(UnixStream::from_raw_fd(sockfd)),
+                sockfd: sockfd,
+            })
+        }
+    }
+
+    /// Waits for an event using poll(), reads it but does not parse
+    pub fn wait_for_event_raw(&mut self, timeout_ms: usize) -> Result<String> {
+        let mut fds = vec![pollfd { fd: self.sockfd, events: POLLIN, revents: 0 }];
+        let x = unsafe { poll((&mut fds).as_mut_ptr(), fds.len() as nfds_t, timeout_ms as c_int) };
+        if x < 0 {
+            Err(io::Error::last_os_error().into())
+        } else if x == 0 {
+            Err(Error::Timeout)
+        } else {
+            let mut s = String::new();
+            let _ = self.sock.read_line(&mut s);
+            Ok(s)
+        }
+    }
+
+    /// Waits for an event using poll(), reads and parses it
+    pub fn wait_for_event<'a>(&mut self, timeout_ms: usize) -> Result<Event> {
+        self.wait_for_event_raw(timeout_ms)
+            .and_then(parse_devd_event)
+    }
+
+    /// Returns the devd socket file descriptor in case you want to select/poll on it together with
+    /// other file descriptors
+    pub fn fd(&self) -> RawFd {
+        self.sockfd
+    }
+
+    /// Reads an event and parses it. Use when polling on the raw fd by yourself
+    pub fn read_event(&mut self) -> Result<Event> {
+        let mut s = String::new();
+        let _ = self.sock.read_line(&mut s);
+        parse_devd_event(s)
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/devd-rs/src/parser.rs
@@ -0,0 +1,164 @@
+use std::str;
+use nom::{alphanumeric, multispace};
+pub use nom::IResult;
+use data::*;
+
+named!(key<&str>, map_res!(alphanumeric, str::from_utf8));
+
+named!(
+    val<&str>,
+    alt!(delimited!(char!('"'), map_res!(take_while!(call!(|c| c != '"' as u8)), str::from_utf8), char!('"')) | map_res!(take_while!(call!(|c| c != '\n' as u8 && c != ' ' as u8)), str::from_utf8))
+);
+
+named!(keyval <&[u8], (String, String)>,
+   do_parse!(
+           key: key
+        >> char!('=')
+        >> val: val
+        >> (key.to_owned(), val.to_owned())
+        )
+    );
+
+named!(keyvals <&[u8], BTreeMap<String, String> >,
+       map!(
+           many0!(terminated!(keyval, opt!(multispace))),
+           |vec: Vec<_>| vec.into_iter().collect()
+       )
+      );
+
+named!(pub event <&[u8], Event>,
+       alt!(
+       do_parse!(
+           tag!("!") >>
+           tag!("system=") >>
+           sys: val >>
+           multispace >>
+           tag!("subsystem=") >>
+           subsys: val >>
+           multispace >>
+           tag!("type=") >>
+           kind: val >>
+           multispace >>
+           data: keyvals >>
+           (Event::Notify { system: sys.to_owned(), subsystem: subsys.to_owned(), kind: kind.to_owned(), data: data })
+       ) |
+    do_parse!(
+        tag!("+") >>
+        dev: key >>
+        multispace >>
+        tag!("at") >>
+        multispace >>
+        parent: keyvals >>
+        tag!("on") >>
+        multispace >>
+        loc: val >>
+        (Event::Attach { dev: dev.to_owned(), parent: parent, location: loc.to_owned() })
+    ) |
+    do_parse!(
+        tag!("-") >>
+        dev: key >>
+        multispace >>
+        tag!("at") >>
+        multispace >>
+        parent: keyvals >>
+        tag!("on") >>
+        multispace >>
+        loc: val >>
+        (Event::Detach { dev: dev.to_owned(), parent: parent, location: loc.to_owned() })
+    ) |
+    do_parse!(
+        tag!("?") >>
+        multispace >>
+        tag!("at") >>
+        multispace >>
+        parent: keyvals >>
+        tag!("on") >>
+        multispace >>
+        loc: val >>
+        (Event::Nomatch { parent: parent, location: loc.to_owned() })
+    )
+
+
+
+
+       )
+      );
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_notify() {
+        let txt = b"!system=USB subsystem=INTERFACE type=ATTACH ugen=ugen0.2 vendor=0x1050 sernum=\"\" mode=host\n";
+        let res = event(txt);
+        let mut data = BTreeMap::new();
+        data.insert("ugen".to_owned(), "ugen0.2".to_owned());
+        data.insert("vendor".to_owned(), "0x1050".to_owned());
+        data.insert("sernum".to_owned(), "".to_owned());
+        data.insert("mode".to_owned(), "host".to_owned());
+        assert_eq!(
+            res,
+            IResult::Done(
+                &b""[..],
+                Event::Notify {
+                    system: "USB".to_owned(),
+                    subsystem: "INTERFACE".to_owned(),
+                    kind: "ATTACH".to_owned(),
+                    data: data,
+                }
+            )
+        )
+    }
+
+    #[test]
+    fn test_attach() {
+        let txt = b"+uhid1 at bus=0 sernum=\"\" on uhub1";
+        let res = event(txt);
+        let mut data = BTreeMap::new();
+        data.insert("bus".to_owned(), "0".to_owned());
+        data.insert("sernum".to_owned(), "".to_owned());
+        assert_eq!(
+            res,
+            IResult::Done(
+                &b""[..],
+                Event::Attach {
+                    dev: "uhid1".to_owned(),
+                    parent: data,
+                    location: "uhub1".to_owned(),
+                }
+            )
+        )
+    }
+
+    #[test]
+    fn test_detach() {
+        let txt = b"-uhid1 at  on uhub1";
+        let res = event(txt);
+        let data = BTreeMap::new();
+        assert_eq!(
+            res,
+            IResult::Done(
+                &b""[..],
+                Event::Detach {
+                    dev: "uhid1".to_owned(),
+                    parent: data.to_owned(),
+                    location: "uhub1".to_owned(),
+                }
+            )
+        )
+    }
+
+    #[test]
+    fn test_nomatch() {
+        let txt = b"? at bus=0 on uhub1";
+        let res = event(txt);
+        let mut data = BTreeMap::new();
+        data.insert("bus".to_owned(), "0".to_owned());
+        assert_eq!(
+            res,
+            IResult::Done(&b""[..], Event::Nomatch { parent: data, location: "uhub1".to_owned() })
+        )
+    }
+
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/devd-rs/src/result.rs
@@ -0,0 +1,26 @@
+use std::{io, result};
+
+#[derive(Debug)]
+pub enum Error {
+    IoError(io::Error),
+    Timeout,
+    Parse,
+}
+
+impl Into<io::Error> for Error {
+    fn into(self) -> io::Error {
+        match self {
+            Error::IoError(e) => e,
+            Error::Timeout => io::Error::new(io::ErrorKind::Other, "devd poll timeout"),
+            Error::Parse => io::Error::new(io::ErrorKind::Other, "devd parse error"),
+        }
+    }
+}
+
+impl From<io::Error> for Error {
+    fn from(err: io::Error) -> Error {
+        Error::IoError(err)
+    }
+}
+
+pub type Result<T> = result::Result<T, Error>;
new file mode 100644
--- /dev/null
+++ b/third_party/rust/nom-1.2.4/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".travis.yml":"6d4e81838b10c5e330749857c72c2f2b1a2e575e71abcd11c094f3b612347b2a","CHANGELOG.md":"d4722e028b2a5b88c466b0d759e463b90bdcfa1b79181a1c76cd313b0a27c615","Cargo.toml":"aebcb999933c3425db85012bea19f9ce78da8e7834dbab54d4a2966e8bc62149","LICENSE":"de730187d5563a81342a3c011d968f78dff37c934fac9b3701e8c762b6118a55","src/bits.rs":"97c9148f63e175489bb6199d039c594ddc56bdf0b7491b9f38b8d74e898bca80","src/bytes.rs":"8f29b976a5e8e6500eb618a9dead7f212688ba9eb06c7066a4016e2db99fed00","src/character.rs":"9ee081f56b508212231ff70d7455b1b85ae44722a39aa60223e8cd95c6570859","src/internal.rs":"ada499b9c178be2a7f9b56319ffb10a778f25fafcda39c78d26b364d89debd72","src/lib.rs":"34efb051214acfde2053e93a7ba718a4fd41b6e0d9edd65a1737605d99b994ab","src/macros.rs":"d39ce3a2cd2b1cb9dd57ce90c06a1ca84720a2dc75e6332cffebba6086cb75d3","src/methods.rs":"24bdbcb0e3570c8bf3fa270dd8d79dd6dfcb982276c82180a89a1e73c5e38019","src/nom.rs":"b0a9c7ce0d09388179bce8f8e23bf57df76b504d925815583c249ec3fc04baab","src/regexp.rs":"8fdae52b761dbad90179e6be87e0e66357fefa34d76af541fb0fcf550fd6ec08","src/str.rs":"198fa15d45c3636289d92c0a592002a07e5a04a431e8cfdf724266e44d484be2","src/stream.rs":"c1bd5b8e7a2061ff66eb2c954033146001f1d65a26d12efa06af8cf93ffa53e4","src/util.rs":"da40ebac865d3176567d3a37b01170234398a03e938553720ce30aa1f6005b6d","tests/arithmetic.rs":"b98936b7fa0228835ca022f6db5342b72a9c01cc3f16a4e05263bbe6424ba3e9","tests/arithmetic_ast.rs":"b18b9a46ba573ae13c40a31217425f6e8cf8fade09a75cdbbfa7146ec668f0b2","tests/cross_function_backtracking.rs":"b071d13031c1f12195473186e3775943991496b10f4590db3f36d511e9f98a1c","tests/ini.rs":"776f681542028564899e55f71533b3bcda5ed1bbb971f24b5b1b9578111ba0cb","tests/ini_str.rs":"315046d9b6dc38d6d306d3562d7ac6518c9ecce9aabcc58fb80c07577ad99789","tests/issues.rs":"2193c219397b7a417cc009b72c13adc42471e7a4917a2a4009aa0fca23c6ea8c","tests/mp4.rs":"b4bf0514fd645160851cc4da9ad6bf81d571cd14865bf134837c19578caaf6e6","tests/omnom.rs":"409d2349fa24f3503bd02e0079c1554a58ce3d40dd7eb0e5d4bb63b588afdae4","tests/test1.rs":"3e0c187bad91d822ebc113eb5cf30fc6585e53a961728304ac24e05ab2123d10"},"package":"a5b8c256fd9471521bcb84c3cdba98921497f1a331cbc15b8030fc63b82050ce"}
\ No newline at end of file
rename from third_party/rust/nom/.travis.yml
rename to third_party/rust/nom-1.2.4/.travis.yml
new file mode 100644
--- /dev/null
+++ b/third_party/rust/nom-1.2.4/CHANGELOG.md
@@ -0,0 +1,555 @@
+# Change Log
+
+## [Unreleased][unreleased]
+
+### Changed
+
+## 1.2.4 - 2016-07-20
+
+### Thanks
+- @Phlosioneer for documentation fixes
+- @sourrust for fixing offsets in `take_bits!`
+- @ChrisMacNaughton for the XFS crate
+- @pwoolcoc for `rest_s`
+- @fitzgen for more `IResult` methods
+- @gtors for the negative lookahead feature
+- @frk1 and @jeandudey for little endian float parsing
+- @jethrogb for fixing input usage in `many1`
+- @acatton for beating me at nom golf :D
+
+### Added
+- the `rest_s` method on `IResult` returns the remaining `&str` input
+- `unwrap_err` and `unwrap_inc` methods on `IResult`
+- `not!` will peek at the input and return `Done` if the underlying parser returned `Error` or `Incomplete`, without consuming the input
+- `le_f32` and `le_f64` parse little endian floating point numbers (IEEE 754)
+-
+
+### Fixed
+- documentation fixes
+- `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` 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 ducomentation and test fixes
+- @Xirdus for correct trait import issues
+- @mspiegel for the new AST example
+- @cholcombe973 for adding the `cond_with_error!` combinator
+- @tstorch for refactoring `many0!`
+- @panicbit for the folding combinators
+- @evestera for `separated_list!` fixes
+- @DanielKeep for correcting some enum imports
+
+### Added
+- Regular expression combinators starting with `re_bytes_` work on byte slices
+- example parsing arithmetic expressions to an AST
+- `cond_with_error!` works like `cond!` but will return `None` if the condition is false, and `Some(value)` if the underlying parser succeeded
+- `fold_many0!`, `fold_many1!` and `fold_many_m_n!` will take a parser, an initial value and a combining function, and fold over the successful applications of the parser
+
+### Fixed
+- `length_bytes!` converts the result of its child parser to usize
+- `take_till!` now imports `InputLength` instead of assuming it's in scope
+- `separated_list!` and `separated_nonempty_list!` will not consume the separator if there's no following successfully parsed value
+- no more warnings on build
+
+### Changed
+- simpler implementation of `many0!`
+
+## 1.2.2 - 2016-03-09
+
+### Thanks
+- @conradev for fixing take_until_s!`
+- @GuillaumeGomez for some documentation fixes
+- @frewsxcv for some documentation fixes
+- @tstorch for some test refactorings
+
+### Added
+- `nom::Err` now implements `std::error::Error`
+
+### Fixed
+- `hex_u32` does not parses more than 8 chars now
+- `take_while!` and `take_while1!` will not perturb the behaviour of `recognize!` anymore
+
+## 1.2.1 - 2016-02-23
+
+### Thanks
+- @sourrust for adding methods to `IResult`
+- @tstorch for the test refactoring, and for adding methods to `IResult` and `Needed`
+- @joelself for fixing the method system
+
+### Added
+
+- mapping methods over `IResult` and `Needed`
+
+### Changed
+
+- `apply_rf` is renamed to `apply_m`. This will not warrant a major version, since it is part missing from the methods feture added in the 1.2.0 release
+- the `regexp_macros` feature that used `regex!` to precompile regular expressions has been replaced by the normal regex engine combined with `lazy_static`
+
+### Fixed
+
+- when a parser or combinator was returning an empty buffer as remaining part, it was generating one from a static empty string. This was messing with buffer offset calculation. Now, that empty slice is taken like this: `&input[input.len()..]`.
+- The `regexp_macros` and `no_std` feature build again and are now tested with Travis CI
+
+## 1.2.0 - 2016-02-08
+
+### Thanks
+- @zentner-kyle for type inference fixes
+- @joelself for his work on `&str` parsing and method parsers
+- @GuillaumeGomez for implementing methods on `IResult`
+- @dirk for the `alt_complete!` combinator
+- @tstorch for a lot of refactoring work and unit tests additions
+- @jansegre for the hex digit parsers
+- @belgum for some documentation fixes
+- @lwandrebeck for some documentation fixes and code fixes in `hex_digit`
+
+### Added
+- `take_until_and_consume_s!` for consumption of string data until a tag
+- more function patterns in `named!`. The error type can now be specified
+- `alt_complete!` works like the `alt!` combinator, but tries the next branch if the current one returned `Incomplete`, instead of returning directly
+- more unit tests for a lot of combinators
+- hexadecimal digit parsers
+- the `tuple!` combinator takes a list of parsers as argument, and applies them serially on the input. If all of them are successful, it willr eturn a tuple accumulating all the values. This combinator will (hopefully) replace most uses of `chain!`
+- parsers can now be implemented as a method for a struct thanks to the `method!`, `call_m!` and `apply_rf!` combinators
+
+### Fixed
+- 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 `ÌResult<I,O,E>` (with specified error type instead of implicit)
+
+## 1.1.0 - 2016-01-01
+
+This release adds a lot of features related to `&str` parsing. The previous versions
+were focused on `&[u8]` and bit streams parsing, but there's a need for more text
+parsing with nom. The parsing functions like `alpha`, `digit` and others will now
+accept either a `&[u8]` or a `&str`, so there is no breaking change on that part.
+
+There are also a few performance improvements and documentation fixes.
+
+### Thanks
+- @Binero for pushing the work on `&str` parsing
+- @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
+
+### Added
+
+- 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
+
+- `tag!` will now compare even on partial input. If it expects "abcd" but receives "ef", it will now return an `Error` instead of `Incomplete`
+- `many0!` and others will preallocate a larger vector to avoid some copies and reallocations
+- `alpha`, `digit`, `alphanumeric`, `space` and `multispace` now accept as input a `&[u8]` or a `&str`. Additionally, they return an error if they receive an empty input
+- `take_while!`, `take_while1!`, `take_while_s!`, `take_while1_s!` wilreturn an error on empty input
+
+### Fixed
+
+- if the child parser of `many0!` or `many1!` returns `Incomplete`, it will return `Incomplete` too, possibly updating the needed size
+- `Option,` `Some`, `None` and `Vec` are now used with full path imports
+
+## 1.0.1 - 2015-11-22
+
+This releases makes the 1.0 version compatible with Rust 1.2 and 1.3
+
+### Thanks
+- @steveklabnik for fixing lifetime issues in Producers and Consumers
+
+## 1.0.0 - 2015-11-16
+
+Stable release for nom. A lot of new features, a few breaking changes
+
+### Thanks
+- @ahenry for macro fixes
+- @bluss for fixing documentation
+- @sourrust for cleaning code and debugging the new streaming utilities
+- @meh for inline optimizations
+- @ccmtaylor for fixing function imports
+- @soro for improvements to the streaming utilities
+- @breard-r for catching my typos
+- @nelsonjchen for catching my typos too
+- @divarvel for hex string parsers
+- @mrordinaire for the `length_bytes!` combinator
+
+### Breaking changes
+- `IResult::Error` can now use custom error types, and is generic over the input type
+- Producers and consumers have been replaced. The new implementation uses less memory and integrates more with parsers
+- `nom::ErrorCode` is now `nom::ErrorKind`
+- `filter!` has been renamed to `take_while!`
+- `chain!` will count how much data is consumed and use that number to calculate how much data is needed if a parser returned `Incomplete`
+- `alt!` returns `Incomplete` if a child parser returned `Incomplete`, instead of skipping to the next parser
+- `IResult` does not require a lifetime tag anymore, yay!
+
+### Added
+
+- `complete!` will return an error if the child parser returned `Incomplete`
+- `add_error!` will wrap an error, but allow backtracking
+- `hex_u32` parser
+
+### Fixed
+- the behaviour around `Incomplete` is better for most parsers now
+
+## 0.5.0 - 2015-10-16
+
+This release fixes a few issues and stabilizes the code.
+
+### Thanks
+- @nox for documentation fixes
+- @daboross for linting fixes
+- @ahenry for fixing `tap!` and extending `dbg!` and `dbg_dmp!`
+- @bluss for tracking down and fixing issues with unsafe code
+- @meh for inlining parser functions
+- @ccmtaylor for fixing import of `str::from_utf8`
+
+### Fixed
+- `tap!`, `dbg!` and `dbg_dmp!` now accept function parameters
+
+### Changed
+- the type used in `count_fixed!` must be `Copy`
+- `chain!` calculates how much data is needed if one of the parsers returns `Incomplete
+- optional parsers in `chain!` can return `Incomplete`
+
+## 0.4.0 - 2015-09-08
+
+Considering the number of changes since the last release, this version can contain breaking changes, so the version number becomes 0.4.0. A lot of new features and performance improvements!
+
+### Thanks
+- @frewsxcv for documentation fixes
+- @ngrewe for his work on producers and consumers
+- @meh for fixes on `chain!` and for the `rest` parser
+- @daboross for refactoring `many0!` and `many1!`
+- @aleksander for the `switch!` combinator idea
+- @TechnoMancer for his help with bit level parsing
+- @sxeraverx for pointing out a bug in `is_a!`
+
+### Fixed
+- `count_fixed!` must take an explicit type as argument to generate the fixed-size array
+- optional parsing behaviour in `chain!`
+- `count!` can take 0 elements
+- `is_a!` and `is_not!` can now consume the whole input
+
+### Added
+- it is now possible to seek to the end of a `MemProducer`
+- `opt!` returns `Done(input, None)` if `the child parser returned `Incomplete`
+- `rest` will return the remaining input
+- consumers can now seek to and from the end of input
+- `switch!` applies a first parser then matches on its result to choose the next parser
+- bit-level parsers
+- character-level parsers
+- regular expression parsers
+- implementation of `take_till!`, `take_while!` and `take_while1!`
+
+### Changed
+- `alt!` can return `Incomplete`
+- the error analysis functions will now take references to functions instead of moving them
+- performance improvements on producers
+- performance improvement for `filter!`
+- performance improvement for `count!`: a `Vec` of the right size is directly allocated
+
+## 0.3.11 - 2015-08-04
+
+### Thanks
+- @bluss for remarking that the crate included random junk lying non commited in my local repository
+
+### Fixed
+- cleanup of my local repository will ship less files in the crates, resulting in a smaller download
+
+## 0.3.10 - 2015-08-03
+
+### Added
+
+- `bits!` for bit level parsing. It indicates that all child parsers will take a `(&[u8], usize)`as input, with the second parameter indicating the bit offset in the first byte. This allows viewing a byte slice as a bit stream. Most combinators can be used directly under `bits!`
+- `take_bits!` takes an integer type and a number of bits, consumes that number of bits and updates the offset, possibly by crossing byte boundaries
+- bit level parsers are all written in `src/bits.rs`
+
+### Changed
+
+- Parsers that specifically handle bytes have been moved to src/bytes.rs`. This applies to `tag!`, `is_not!`, `is_a!`, `filter!`, `take!`, `take_str!`, `take_until_and_consume!`, `take_until!`, `take_until_either_and_consume!`, `take_until_either!`
+
+## 0.3.9 - 2015-07-20
+
+### Thanks
+- @badboy for fixing `filter!`
+- @idmit for some documentation fixes
+
+### Added
+- `opt_res!` applies a parser and transform its result in a Result. This parser never fails
+- `cond_reduce!` takes an expression as parameter, applies the parser if the expression is true, and returns an error if the expression is false
+- `tap!` pass the result of a parser to a block to manipulate it, but do not affect the parser's result
+- `AccReader` is a Read+BufRead that supports data accumulation and partial consumption. The `consume` method must be called afterwardsto indicate how much was consumed
+- Arithmetic expression evaluation and parsing example
+- `u16!`, `u32!`, `u64!`, `i16!`, `i32!`, `i64!` take an expression as parameter, if the expression is true, apply the big endian integer parser, if false, the little endian version
+- type information for combinators. This will make the documentation a bit easier to navigate
+
+### Fixed
+- `map_opt!` and `map_res!` had issues with argument order due to bad macros
+- `delimited!` did not compile for certain combinations of arguments
+- `filter!` did not return a byte slice but a fixed array
+
+## 0.3.8 - 2015-07-03
+
+### Added
+- code coverage is now calculated automatically on Travis CI
+- `Stepper`: wrap a `Producer`, and call the method `step` with a parser. This method will buffer data if there is not enough, apply the parser if there is, and keep the rest of the input in memory for the next call
+- `ReadProducer`: takes something implementing `Read`, and makes a `Producer` out of it
+
+### Fixed
+- the combinators `separated_pair!` and `delimited!` did not work because an implementation macro was not exported
+- if a `MemProducer` reached its end, it should always return `Eof`
+- `map!` had issues with argument matching
+
+## 0.3.7 - 2015-06-24
+
+### Added
+- `expr_res!` and `expr_opt!` evaluate an expression returning a Result or Opt and convert it to IResult
+- `AsBytes` is implemented for fixed size arrays. This allows `tag!([41u8, 42u8])`
+
+### Fixed
+- `count_fixed!` argument parsing works again
+
+## 0.3.6 - 2015-06-15
+
+### Added
+- documentation for a few functions
+- the consumer trait now requires the `failed(&self, error_code)` method in case of parsing error
+- `named!` now handles thge alternative `named!(pub fun_name<OutputType>, ...)`
+
+### Fixed
+- `filter!` now returns the whole input if the filter function never returned false
+- `take!` casts its argument as usize, so it can accepts any integer type now
+
+## 0.3.5 - 2015-06-10
+
+### Thanks
+- @cmr for some documentation fixes
+
+### Added
+- `count_fixed!` returns a fixed array
+
+### Fixed
+- `count!` is back to the previous behaviour, returning a `Vec` for sizes known at runtime
+
+### Changed
+- functions and traits exported from `nom::util` are now directly in `nom::`
+
+## 0.3.4 - 2015-06-09
+
+### Thanks
+- @andrew-d for fixes on `cond!`
+- @keruspe for features in `chain!`
+
+### Added
+- `chain!` can now have mutable fields
+
+### Fixed
+- `cond!` had an infinite macro recursion
+
+### Changed
+- `chain!` generates less code now. No apprent compilation time improvement
+
+## 0.3.3 - 2015-06-09
+
+### Thanks
+- @andrew-d for the little endian signed integer parsers
+- @keruspe for fixes on `count!`
+
+### Added
+- `le_i8`, `le_i16`, `le_i32`, `le_i64`: little endian signed integer parsers
+
+### Changed
+- the `alt!` parser compiles much faster, even with more than 8 branches
+- `count!` can now return a fixed size array instead of a growable vector
+
+## 0.3.2 - 2015-05-31
+
+### Thanks
+- @keruspe for the `take_str` parser and the function application combinator
+
+### Added
+- `take_str!`: takes the specified number of bytes and return a UTF-8 string
+- `apply!`: do partial application on the parameters of a function
+
+### Changed
+- `Needed::Size` now contains a `usize` instead of a `u32`
+
+## 0.3.1 - 2015-05-21
+
+### Thanks
+- @divarvel for the big endian signed integer parsers
+
+### Added
+- `be_i8`, `be_i16`, `be_i32`, `be_i64`: big endian signed integer parsers
+- the `core` feature can be passed to cargo to build with `no_std`
+- colored hexdump can be generated from error chains
+
+## 0.3.0 - 2015-05-07
+
+### Thanks
+- @filipegoncalves for some documentation and the new eof parser
+- @CrimsonVoid for putting fully qualified types in the macros
+- @lu_zero for some documentation fixes
+
+### Added
+- new error types that can contain an error code, an input slice, and a list of following errors
+- `error!` will cut backtracking and return directly from the parser, with a specified error code
+- `eof` parser, successful if there is no more input
+- specific error codes for the parsers provided by nom
+
+### Changed
+- fully qualified types in macros. A lot of imports are not needed anymore
+
+### Removed
+- `FlatMap`, `FlatpMapOpt` and `Functor` traits (replaced by `map!`, `map_opt!` and `map_res!`)
+
+## 0.2.2 - 2015-04-12
+
+### Thanks
+- @filipegoncalves and @thehydroimpulse for debugging an infinite loop in many0 and many1
+- @thehydroimpulse for suggesting public named parsers
+- @skade for removing the dependency on the collections gate
+
+### Added
+- `named!` can now declare public functions like this: `named!(pub tst, tag!("abcd"));`
+- `pair!(X,Y)` returns a tuple `(x, y)`
+- `separated_pair!(X, sep, Y)` returns a tuple `(x, y)`
+- `preceded!(opening, X)` returns `x`
+- `terminated!(X, closing)` returns `x`
+- `delimited(opening, X, closing)` returns `x`
+- `separated_list(sep, X)` returns a `Vec<X>`
+- `separated_nonempty_list(sep, X)` returns a `Vec<X>` of at list one element
+
+### Changed
+- `many0!` and `many1!` forbid parsers that do not consume input
+- `is_a!`, `is_not!`, `alpha`, `digit`, `space`, `multispace` will now return an error if they do not consume at least one byte
+
+## 0.2.1 - 2015-04-04
+
+### Thanks
+- @mtsr for catching the remaining debug println!
+- @jag426 who killed a lot of warnings
+- @skade for removing the dependency on the core feature gate
+
+
+### Added
+- little endian unsigned int parsers le_u8, le_u16, le_u32, le_u64
+- `count!` to apply a parser a specified number of times
+- `cond!` applies a parser if the condition is met
+- more parser development tools in `util::*`
+
+### Fixed
+- in one case, `opt!` would not compile
+
+### Removed
+- most of the feature gates are now removed. The only one still needed is `collections`
+
+## 0.2.0 - 2015-03-24
+*works with `rustc 1.0.0-dev (81e2396c7 2015-03-19) (built 2015-03-19)`*
+
+### Thanks
+- Ryman for the AsBytes implementation
+- jag426 and jaredly for documentation fixes
+- eternaleye on #rust IRC for his help on the new macro syntax
+
+### Changed
+- the AsBytes trait improves readability, no more b"...", but "..." instead
+- Incomplete will now hold either Needed;;Unknown, or Needed::Size(u32). Matching on Incomplete without caring for the value is done with `Incomplete(_)`, but if more granularity is mandatory, `Needed` can be matched too
+- `alt!` can pass the result of the parser to a closure
+- the `take_*` macros changed behaviour, the default case is now not to consume the separator. The macros have been renamed as follows: `take_until!` -> `take_until_and_consume!`, `take_until_and_leave!` -> `take_until!`, `take_until_either_and_leave!` -> `take_until_either!`, `take_until_either!` -> `take_until_either_and_consume!`
+
+### Added
+- `peek!` macro: matches the future input but does not consume it
+- `length_value!` macro: the first argument is a parser returning a `n` that can cast to usize, then applies the second parser `n` times. The macro has a variant with a third argument indicating the expected input size for the second parser
+- benchmarks are available at https://github.com/Geal/nom_benchmarks
+- more documentation
+- **Unnamed parser syntax**: warning, this is a breaking change. With this new syntax, the macro combinators do not generate functions anymore, they create blocks. That way, they can be nested, for better readability. The `named!` macro is provided to create functions from parsers. Please be aware that nesting parsers comes with a small cost of compilation time, negligible in most cases, but can quickly get to the minutes scale if not careful. If this happens, separate your parsers in multiple subfunctions.
+- `named!`, `closure!` and `call!` macros used to support the unnamed syntax
+- `map!`, `map_opt!` and `map_res!` to combine a parser with a normal function, transforming the input directly, or returning an `Option` or `Result`
+
+### Fixed
+- `is_a!` is now working properly
+
+### Removed
+- the `o!` macro does less than `chain!`, so it has been removed
+- the `fold0!` and `fold1!` macros were too complex and awkward to use, the `many*` combinators will be useful for most uses for now
+
+## 0.1.6 - 2015-02-24
+### Changed
+- consumers must have an end method that will be called after parsing
+
+### Added
+- big endian unsigned int and float parsers: be_u8, be_u16, be_u32, be_u64, be_f32, be_f64
+- producers can seek
+- function and macros documentation
+- README documentation
+### Fixed
+- lifetime declarations
+- tag! can return Incomplete
+
+## 0.1.5 - 2015-02-17
+### Changed
+- traits were renamed: FlatMapper -> FlatMap, Mapper -> FlatMapOpt, Mapper2 -> Functor
+
+### Fixed
+- woeks with rustc f1bb6c2f4
+
+## 0.1.4 - 2015-02-17
+### Changed
+- the chaining macro can take optional arguments with '?'
+
+## 0.1.3 - 2015-02-16
+### Changed
+- the chaining macro now takes the closure at the end of the argument list
+
+## 0.1.2 - 2015-02-16
+### Added
+- flat_map implementation for <&[u8], &[u8]>
+- chaining macro
+- partial MP4 parser example
+
+
+## 0.1.1 - 2015-02-06
+### Fixed
+- closure syntax change
+
+## Compare code
+
+* [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
+* [1.2.0]: https://github.com/Geal/nom/compare/1.1.0...1.2.0
+* [1.1.0]: https://github.com/Geal/nom/compare/1.0.1...1.1.0
+* [1.0.1]: https://github.com/Geal/nom/compare/1.0.0...1.0.1
+* [1.0.0]: https://github.com/Geal/nom/compare/0.5.0...1.0.0
+* [0.5.0]: https://github.com/geal/nom/compare/0.4.0...0.5.0
+* [0.4.0]: https://github.com/geal/nom/compare/0.3.11...0.4.0
+* [0.3.11]: https://github.com/geal/nom/compare/0.3.10...0.3.11
+* [0.3.10]: https://github.com/geal/nom/compare/0.3.9...0.3.10
+* [0.3.9]: https://github.com/geal/nom/compare/0.3.8...0.3.9
+* [0.3.8]: https://github.com/Geal/nom/compare/0.3.7...0.3.8
+* [0.3.7]: https://github.com/Geal/nom/compare/0.3.6...0.3.7
+* [0.3.6]: https://github.com/Geal/nom/compare/0.3.5...0.3.6
+* [0.3.5]: https://github.com/Geal/nom/compare/0.3.4...0.3.5
+* [0.3.4]: https://github.com/Geal/nom/compare/0.3.3...0.3.4
+* [0.3.3]: https://github.com/Geal/nom/compare/0.3.2...0.3.3
+* [0.3.2]: https://github.com/Geal/nom/compare/0.3.1...0.3.2
+* [0.3.1]: https://github.com/Geal/nom/compare/0.3.0...0.3.1
+* [0.3.0]: https://github.com/Geal/nom/compare/0.2.2...0.3.0
+* [0.2.2]: https://github.com/Geal/nom/compare/0.2.1...0.2.2
+* [0.2.1]: https://github.com/Geal/nom/compare/0.2.0...0.2.1
+* [0.2.0]: https://github.com/Geal/nom/compare/0.1.6...0.2.0
+* [0.1.6]: https://github.com/Geal/nom/compare/0.1.5...0.1.6
+* [0.1.5]: https://github.com/Geal/nom/compare/0.1.4...0.1.5
+* [0.1.4]: https://github.com/Geal/nom/compare/0.1.3...0.1.4
+* [0.1.3]: https://github.com/Geal/nom/compare/0.1.2...0.1.3
+* [0.1.2]: https://github.com/Geal/nom/compare/0.1.1...0.1.2
+* [0.1.1]: https://github.com/Geal/nom/compare/0.1.0...0.1.1
new file mode 100644
--- /dev/null
+++ b/third_party/rust/nom-1.2.4/Cargo.toml
@@ -0,0 +1,38 @@
+[package]
+
+name = "nom"
+version = "1.2.4"
+authors = [ "contact@geoffroycouprie.com" ]
+description = "A byte-oriented, zero-copy, parser combinators library"
+license = "MIT"
+repository = "https://github.com/Geal/nom"
+readme = "README.md"
+documentation = "http://rust.unhandledexpression.com/nom/"
+keywords = ["parser", "parser-combinators", "parsing", "streaming", "bit"]
+
+include = [
+  "CHANGELOG.md",
+  "LICENSE",
+  ".gitignore",
+  ".travis.yml",
+  "Cargo.toml",
+  "src/*.rs",
+  "tests/*.rs"
+]
+
+[features]
+core = []
+nightly = []
+default = ["stream"]
+regexp = ["regex"]
+regexp_macros = ["regexp", "lazy_static"]
+stream = []
+
+[dependencies.regex]
+version = "^0.1.56"
+optional = true
+
+[dependencies.lazy_static]
+version = "^0.2.1"
+optional = true
+
new file mode 100644
--- /dev/null
+++ b/third_party/rust/nom-1.2.4/LICENSE
@@ -0,0 +1,20 @@
+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
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
copy from third_party/rust/nom/.cargo-checksum.json
copy to third_party/rust/nom-1.2.4/nom/.cargo-checksum.json
copy from third_party/rust/nom/.travis.yml
copy to third_party/rust/nom-1.2.4/nom/.travis.yml
copy from third_party/rust/nom/CHANGELOG.md
copy to third_party/rust/nom-1.2.4/nom/CHANGELOG.md
copy from third_party/rust/nom/Cargo.toml
copy to third_party/rust/nom-1.2.4/nom/Cargo.toml
copy from third_party/rust/nom/LICENSE
copy to third_party/rust/nom-1.2.4/nom/LICENSE
copy from third_party/rust/nom/src/bits.rs
copy to third_party/rust/nom-1.2.4/nom/src/bits.rs
copy from third_party/rust/nom/src/bytes.rs
copy to third_party/rust/nom-1.2.4/nom/src/bytes.rs
copy from third_party/rust/nom/src/character.rs
copy to third_party/rust/nom-1.2.4/nom/src/character.rs
copy from third_party/rust/nom/src/internal.rs
copy to third_party/rust/nom-1.2.4/nom/src/internal.rs
copy from third_party/rust/nom/src/lib.rs
copy to third_party/rust/nom-1.2.4/nom/src/lib.rs
copy from third_party/rust/nom/src/macros.rs
copy to third_party/rust/nom-1.2.4/nom/src/macros.rs
copy from third_party/rust/nom/src/methods.rs
copy to third_party/rust/nom-1.2.4/nom/src/methods.rs
copy from third_party/rust/nom/src/nom.rs
copy to third_party/rust/nom-1.2.4/nom/src/nom.rs
copy from third_party/rust/nom/src/regexp.rs
copy to third_party/rust/nom-1.2.4/nom/src/regexp.rs
copy from third_party/rust/nom/src/str.rs
copy to third_party/rust/nom-1.2.4/nom/src/str.rs
copy from third_party/rust/nom/src/stream.rs
copy to third_party/rust/nom-1.2.4/nom/src/stream.rs
copy from third_party/rust/nom/src/util.rs
copy to third_party/rust/nom-1.2.4/nom/src/util.rs
copy from third_party/rust/nom/tests/arithmetic.rs
copy to third_party/rust/nom-1.2.4/nom/tests/arithmetic.rs
copy from third_party/rust/nom/tests/arithmetic_ast.rs
copy to third_party/rust/nom-1.2.4/nom/tests/arithmetic_ast.rs
copy from third_party/rust/nom/tests/cross_function_backtracking.rs
copy to third_party/rust/nom-1.2.4/nom/tests/cross_function_backtracking.rs
copy from third_party/rust/nom/tests/ini.rs
copy to third_party/rust/nom-1.2.4/nom/tests/ini.rs
copy from third_party/rust/nom/tests/ini_str.rs
copy to third_party/rust/nom-1.2.4/nom/tests/ini_str.rs
copy from third_party/rust/nom/tests/issues.rs
copy to third_party/rust/nom-1.2.4/nom/tests/issues.rs
copy from third_party/rust/nom/tests/mp4.rs
copy to third_party/rust/nom-1.2.4/nom/tests/mp4.rs
copy from third_party/rust/nom/tests/omnom.rs
copy to third_party/rust/nom-1.2.4/nom/tests/omnom.rs
copy from third_party/rust/nom/tests/test1.rs
copy to third_party/rust/nom-1.2.4/nom/tests/test1.rs
new file mode 100644
--- /dev/null
+++ b/third_party/rust/nom-1.2.4/src/bits.rs
@@ -0,0 +1,220 @@
+//! Bit level parsers and combinators
+//!
+//! Bit parsing is handled by tweaking the input in most macros.
+//! In byte level parsing, the input is generally a `&[u8]` passed from combinator
+//! to combinator until the slices are manipulated.
+//!
+//! Bit parsers take a `(&[u8], usize)` as input. The first part of the tuple is an byte slice,
+//! the second part is a bit offset in the first byte of the slice.
+//!
+//! By passing a pair like this, we can leverage most of the combinators, and avoid
+//! transforming the whole slice to a vector of booleans. This should make it easy
+//! to see a byte slice as a bit stream, and parse code points of arbitrary bit length.
+
+
+/// `bits!( parser ) => ( &[u8], (&[u8], usize) -> IResult<(&[u8], usize), T> ) -> IResult<&[u8], T>`
+/// transforms its byte slice input into a bit stream for the underlying parsers
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::Done;
+/// # fn main() {
+///  named!( take_3_bits<u8>, bits!( take_bits!( u8, 3 ) ) );
+///
+///  let input = vec![0b10101010, 0b11110000, 0b00110011];
+///  let sl    = &input[..];
+///
+///  assert_eq!(take_3_bits( sl ), Done(&sl[1..], 5) );
+/// # }
+#[macro_export]
+macro_rules! bits (
+  ($i:expr, $submac:ident!( $($args:tt)* )) => (
+    bits_impl!($i, $submac!($($args)*));
+  );
+  ($i:expr, $f:expr) => (
+    bits_impl!($i, call!($f));
+  );
+);
+
+/// Internal parser, do not use directly
+#[doc(hidden)]
+#[macro_export]
+macro_rules! bits_impl (
+  ($i:expr, $submac:ident!( $($args:tt)* )) => (
+    {
+      let input = ($i, 0usize);
+      match $submac!(input, $($args)*) {
+        $crate::IResult::Error(e)                            => {
+          let err = match e {
+            $crate::Err::Code(k) | $crate::Err::Node(k, _) => $crate::Err::Code(k),
+            $crate::Err::Position(k, (i,b)) | $crate::Err::NodePosition(k, (i,b), _) => {
+              $crate::Err::Position(k, &i[b/8..])
+            }
+          };
+          $crate::IResult::Error(err)
+        }
+        $crate::IResult::Incomplete($crate::Needed::Unknown) => $crate::IResult::Incomplete($crate::Needed::Unknown),
+        $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+          //println!("bits parser returned Needed::Size({})", i);
+          $crate::IResult::Incomplete($crate::Needed::Size(i / 8 + 1))
+        },
+        $crate::IResult::Done((i, bit_index), o)             => {
+          let byte_index = bit_index / 8 + if bit_index % 8 == 0 { 0 } else { 1 } ;
+          //println!("bit index=={} => byte index=={}", bit_index, byte_index);
+          $crate::IResult::Done(&i[byte_index..], o)
+        }
+      }
+    }
+  );
+);
+
+/// `take_bits!(type, nb) => ( (&[T], usize), U, usize) -> IResult<(&[T], usize), U>`
+/// generates a parser consuming the specified number of bits.
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::Done;
+/// # fn main() {
+///  named!( take_pair<(u8, u8)>, bits!( pair!( take_bits!( u8, 3 ), take_bits!(u8, 5) ) ) );
+///
+///  let input = vec![0b10101010, 0b11110000, 0b00110011];
+///  let sl    = &input[..];
+///
+///  assert_eq!(take_pair( sl ),       Done(&sl[1..], (5, 10)) );
+///  assert_eq!(take_pair( &sl[1..] ), Done(&sl[2..], (7, 16)) );
+/// # }
+/// ```
+#[macro_export]
+macro_rules! take_bits (
+  ($i:expr, $t:ty, $count:expr) => (
+    {
+      use std::ops::Div;
+      //println!("taking {} bits from {:?}", $count, $i);
+      let (input, bit_offset) = $i;
+      let res : $crate::IResult<(&[u8],usize), $t> = if $count == 0 {
+        $crate::IResult::Done( (input, bit_offset), 0)
+      } else {
+        let cnt = ($count as usize + bit_offset).div(8);
+        if input.len() * 8 < $count as usize + bit_offset {
+          //println!("returning incomplete: {}", $count as usize + bit_offset);
+          $crate::IResult::Incomplete($crate::Needed::Size($count as usize))
+        } else {
+          let mut acc:$t            = 0;
+          let mut offset: usize     = bit_offset;
+          let mut remaining: usize  = $count;
+          let mut end_offset: usize = 0;
+
+          for byte in input.iter().take(cnt + 1) {
+            if remaining == 0 {
+              break;
+            }
+            let val: $t = if offset == 0 {
+              *byte as $t
+            } else {
+              ((*byte << offset) as u8 >> offset) as $t
+            };
+
+            if remaining < 8 - offset {
+              acc += val >> (8 - offset - remaining);
+              end_offset = remaining + offset;
+              break;
+            } else {
+              acc += val << (remaining - (8 - offset));
+              remaining -= 8 - offset;
+              offset = 0;
+            }
+          }
+          $crate::IResult::Done( (&input[cnt..], end_offset) , acc)
+        }
+      };
+      res
+    }
+  );
+);
+
+/// matches an integer pattern to a bitstream. The number of bits of the input to compare must be specified
+#[macro_export]
+macro_rules! tag_bits (
+  ($i:expr, $t:ty, $count:expr, $p: pat) => (
+    {
+      match take_bits!($i, $t, $count) {
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
+        $crate::IResult::Done(i, o)    => {
+          if let $p = o {
+            let res: $crate::IResult<(&[u8],usize),$t> = $crate::IResult::Done(i, o);
+            res
+          } else {
+            $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::TagBits, $i))
+          }
+        },
+        _                              => {
+          $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::TagBits, $i))
+        }
+      }
+    }
+  )
+);
+
+#[cfg(test)]
+mod tests {
+  use internal::{IResult,Needed,Err};
+  use ErrorKind;
+
+  #[test]
+  fn take_bits() {
+    let input = vec![0b10101010, 0b11110000, 0b00110011];
+    let sl    = &input[..];
+
+    assert_eq!(take_bits!( (sl, 0), u8,   0 ), IResult::Done((sl, 0), 0));
+    assert_eq!(take_bits!( (sl, 0), u8,   8 ), IResult::Done((&sl[1..], 0), 170));
+    assert_eq!(take_bits!( (sl, 0), u8,   3 ), IResult::Done((&sl[0..], 3), 5));
+    assert_eq!(take_bits!( (sl, 0), u8,   6 ), IResult::Done((&sl[0..], 6), 42));
+    assert_eq!(take_bits!( (sl, 1), u8,   1 ), IResult::Done((&sl[0..], 2), 0));
+    assert_eq!(take_bits!( (sl, 1), u8,   2 ), IResult::Done((&sl[0..], 3), 1));
+    assert_eq!(take_bits!( (sl, 1), u8,   3 ), IResult::Done((&sl[0..], 4), 2));
+    assert_eq!(take_bits!( (sl, 6), u8,   3 ), IResult::Done((&sl[1..], 1), 5));
+    assert_eq!(take_bits!( (sl, 0), u16, 10 ), IResult::Done((&sl[1..], 2), 683));
+    assert_eq!(take_bits!( (sl, 0), u16,  8 ), IResult::Done((&sl[1..], 0), 170));
+    assert_eq!(take_bits!( (sl, 6), u16, 10 ), IResult::Done((&sl[2..], 0), 752));
+    assert_eq!(take_bits!( (sl, 6), u16, 11 ), IResult::Done((&sl[2..], 1), 1504));
+    assert_eq!(take_bits!( (sl, 0), u32, 20 ), IResult::Done((&sl[2..], 4), 700163));
+    assert_eq!(take_bits!( (sl, 4), u32, 20 ), IResult::Done((&sl[3..], 0), 716851));
+    assert_eq!(take_bits!( (sl, 4), u32, 22 ), IResult::Incomplete(Needed::Size(22)));
+  }
+
+  #[test]
+  fn tag_bits() {
+    let input = vec![0b10101010, 0b11110000, 0b00110011];
+    let sl    = &input[..];
+
+    assert_eq!(tag_bits!( (sl, 0), u8,   3, 0b101), IResult::Done((&sl[0..], 3), 5));
+    assert_eq!(tag_bits!( (sl, 0), u8,   4, 0b1010), IResult::Done((&sl[0..], 4), 10));
+  }
+
+  named!(ch<(&[u8],usize),(u8,u8)>,
+    chain!(
+      tag_bits!(u8, 3, 0b101) ~
+      x: take_bits!(u8, 4)    ~
+      y: take_bits!(u8, 5)    ,
+      || { (x,y) }
+    )
+  );
+
+  #[test]
+  fn chain_bits() {
+    let input = vec![0b10101010, 0b11110000, 0b00110011];
+    let sl    = &input[..];
+    assert_eq!(ch((&input[..],0)), IResult::Done((&sl[1..], 4), (5,15)));
+    assert_eq!(ch((&input[..],4)), IResult::Done((&sl[2..], 0), (7,16)));
+    assert_eq!(ch((&input[..1],0)), IResult::Incomplete(Needed::Size(12)));
+  }
+
+  named!(ch_bytes<(u8,u8)>, bits!(ch));
+  #[test]
+  fn bits_to_bytes() {
+    let input = vec![0b10101010, 0b11110000, 0b00110011];
+    assert_eq!(ch_bytes(&input[..]), IResult::Done(&input[2..], (5,15)));
+    assert_eq!(ch_bytes(&input[..1]), IResult::Incomplete(Needed::Size(2)));
+    assert_eq!(ch_bytes(&input[1..]), IResult::Error(Err::Position(ErrorKind::TagBits, &input[1..])));
+  }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/nom-1.2.4/src/bytes.rs
@@ -0,0 +1,1027 @@
+//! Byte level parsers and combinators
+//!
+
+/// `recognize!(&[T] -> IResult<&[T], O> ) => &[T] -> IResult<&[T], &[T]>`
+/// if the child parser was successful, return the consumed input as produced value
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::Done;
+/// # fn main() {
+///  named!(x, recognize!(delimited!(tag!("<!--"), take!(5), tag!("-->"))));
+///  let r = x(&b"<!-- abc --> aaa"[..]);
+///  assert_eq!(r, Done(&b" aaa"[..], &b"<!-- abc -->"[..]));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! recognize (
+  ($i:expr, $submac:ident!( $($args:tt)* )) => (
+    {
+      use $crate::HexDisplay;
+      match $submac!($i, $($args)*) {
+        $crate::IResult::Done(i,_)     => {
+          let index = ($i).offset(i);
+          $crate::IResult::Done(i, &($i)[..index])
+        },
+        $crate::IResult::Error(e)      => $crate::IResult::Error(e),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i)
+      }
+    }
+  );
+  ($i:expr, $f:expr) => (
+    recognize!($i, call!($f))
+  );
+);
+
+/// `tag!(&[T]: nom::AsBytes) => &[T] -> IResult<&[T], &[T]>`
+/// declares a byte array as a suite to recognize
+///
+/// consumes the recognized characters
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::Done;
+/// # fn main() {
+///  named!(x, tag!("abcd"));
+///  let r = x(&b"abcdefgh"[..]);
+///  assert_eq!(r, Done(&b"efgh"[..], &b"abcd"[..]));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! tag (
+  ($i:expr, $inp: expr) => (
+    {
+      #[inline(always)]
+      fn as_bytes<T: $crate::AsBytes>(b: &T) -> &[u8] {
+        b.as_bytes()
+      }
+
+      let expected = $inp;
+      let bytes    = as_bytes(&expected);
+
+      tag_bytes!($i,bytes)
+    }
+  );
+);
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! tag_bytes (
+  ($i:expr, $bytes: expr) => (
+    {
+      let len = $i.len();
+      let blen = $bytes.len();
+      let m   = if len < blen { len } else { blen };
+      let reduced = &$i[..m];
+      let b       = &$bytes[..m];
+
+      let res: $crate::IResult<_,_> = if reduced != b {
+        $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::Tag, $i))
+      } else if m < blen {
+        $crate::IResult::Incomplete($crate::Needed::Size(blen))
+      } else {
+        $crate::IResult::Done(&$i[blen..], reduced)
+      };
+      res
+    }
+  );
+);
+
+/// `is_not!(&[T:AsBytes]) => &[T] -> IResult<&[T], &[T]>`
+/// returns the longest list of bytes that do not appear in the provided array
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::Done;
+/// # fn main() {
+///  named!( not_space, is_not!( " \t\r\n" ) );
+///
+///  let r = not_space(&b"abcdefgh\nijkl"[..]);
+///  assert_eq!(r, Done(&b"\nijkl"[..], &b"abcdefgh"[..]));
+///  # }
+/// ```
+#[macro_export]
+macro_rules! is_not(
+  ($input:expr, $arr:expr) => (
+    {
+      #[inline(always)]
+      fn as_bytes<T: $crate::AsBytes>(b: &T) -> &[u8] {
+        b.as_bytes()
+      }
+
+      let expected   = $arr;
+      let bytes      = as_bytes(&expected);
+
+      is_not_bytes!($input, bytes)
+    }
+  );
+);
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! is_not_bytes (
+  ($input:expr, $bytes:expr) => (
+    {
+      use $crate::InputLength;
+      let res: $crate::IResult<_,_> = match $input.iter().position(|c| {
+        for &i in $bytes.iter() {
+          if *c == i { return true }
+        }
+        false
+      }) {
+        Some(0) => $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::IsNot,$input)),
+        Some(n) => {
+          let res = $crate::IResult::Done(&$input[n..], &$input[..n]);
+          res
+        },
+        None    => {
+          $crate::IResult::Done(&$input[$input.input_len()..], $input)
+        }
+      };
+      res
+    }
+  );
+);
+
+/// `is_a!(&[T]) => &[T] -> IResult<&[T], &[T]>`
+/// returns the longest list of bytes that appear in the provided array
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::Done;
+/// # fn main() {
+///  named!(abcd, is_a!( "abcd" ));
+///
+///  let r1 = abcd(&b"aaaaefgh"[..]);
+///  assert_eq!(r1, Done(&b"efgh"[..], &b"aaaa"[..]));
+///
+///  let r2 = abcd(&b"dcbaefgh"[..]);
+///  assert_eq!(r2, Done(&b"efgh"[..], &b"dcba"[..]));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! is_a (
+  ($input:expr, $arr:expr) => (
+    {
+      #[inline(always)]
+      fn as_bytes<T: $crate::AsBytes>(b: &T) -> &[u8] {
+        b.as_bytes()
+      }
+
+      let expected  = $arr;
+      let bytes     = as_bytes(&expected);
+
+      is_a_bytes!($input, bytes)
+    }
+  );
+);
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! is_a_bytes (
+  ($input:expr, $bytes:expr) => (
+    {
+      use $crate::InputLength;
+      let res: $crate::IResult<_,_> = match $input.iter().position(|c| {
+        for &i in $bytes.iter() {
+          if *c == i { return false }
+        }
+        true
+      }) {
+        Some(0) => $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::IsA,$input)),
+        Some(n) => {
+          let res: $crate::IResult<_,_> = $crate::IResult::Done(&$input[n..], &$input[..n]);
+          res
+        },
+        None    => {
+          $crate::IResult::Done(&$input[($input).input_len()..], $input)
+        }
+      };
+      res
+    }
+  );
+);
+
+/// `escaped!(&[T] -> IResult<&[T], &[T]>, T, &[T] -> IResult<&[T], &[T]>) => &[T] -> IResult<&[T], &[T]>`
+/// matches a byte string with escaped characters.
+///
+/// The first argument matches the normal characters (it must not accept the control character), the second argument is the control character (like `\` in most languages),
+/// the third argument matches the escaped characters
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::Done;
+/// # use nom::alpha;
+/// # fn main() {
+///  named!(esc, escaped!(call!(alpha), '\\', is_a_bytes!(&b"\"n\\"[..])));
+///  assert_eq!(esc(&b"abcd"[..]), Done(&b""[..], &b"abcd"[..]));
+///  assert_eq!(esc(&b"ab\\\"cd"[..]), Done(&b""[..], &b"ab\\\"cd"[..]));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! escaped (
+  ($i:expr, $submac:ident!( $($args:tt)* ), $control_char: expr, $($rest:tt)+) => (
+    {
+      escaped1!($i, $submac!($($args)*), $control_char, $($rest)*)
+    }
+  );
+
+  ($i:expr, $f:expr, $control_char: expr, $($rest:tt)+) => (
+    escaped1!($i, call!($f), $control_char, $($rest)*)
+  );
+);
+
+/// Internal parser, do not use directly
+#[doc(hidden)]
+#[macro_export]
+macro_rules! escaped1 (
+  ($i:expr, $submac1:ident!( $($args:tt)* ), $control_char: expr, $submac2:ident!( $($args2:tt)*) ) => (
+    {
+     escaped_impl!($i, $submac1!($($args)*), $control_char,  $submac2!($($args2)*))
+    }
+  );
+  ($i:expr, $submac1:ident!( $($args:tt)* ), $control_char: expr, $g:expr) => (
+     escaped_impl!($i, $submac1!($($args)*), $control_char, call!($g))
+  );
+);
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! escaped_impl (
+  ($i: expr, $normal:ident!(  $($args:tt)* ), $control_char: expr, $escapable:ident!(  $($args2:tt)* )) => (
+    {
+      use $crate::InputLength;
+      let cl = || {
+        use $crate::HexDisplay;
+        let mut index  = 0;
+
+        while index < $i.len() {
+          if let $crate::IResult::Done(i,_) = $normal!(&$i[index..], $($args)*) {
+            if i.is_empty() {
+              return $crate::IResult::Done(&$i[$i.input_len()..], $i)
+            } else {
+              index = $i.offset(i);
+            }
+          } else if $i[index] == $control_char as u8 {
+            if index + 1 >= $i.len() {
+              return $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::Escaped,&$i[index..]));
+            } else {
+              match $escapable!(&$i[index+1..], $($args2)*) {
+                $crate::IResult::Done(i,_) => {
+                  if i.is_empty() {
+                    return $crate::IResult::Done(&$i[$i.input_len()..], $i)
+                  } else {
+                    index = $i.offset(i);
+                  }
+                },
+                $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($crate::Err::Position($crate::ErrorKind::Escaped,&$i[index..]))
+            } else {
+              return $crate::IResult::Done(&$i[index..], &$i[..index])
+            }
+          }
+        }
+        $crate::IResult::Done(&$i[index..], &$i[..index])
+      };
+      match cl() {
+        $crate::IResult::Incomplete(x) => $crate::IResult::Incomplete(x),
+        $crate::IResult::Done(i, o)    => $crate::IResult::Done(i, o),
+        $crate::IResult::Error(e)      => {
+          return $crate::IResult::Error($crate::Err::NodePosition($crate::ErrorKind::Escaped, $i, Box::new(e)))
+        }
+      }
+    }
+  );
+);
+
+/// `escaped_transform!(&[T] -> IResult<&[T], &[T]>, T, &[T] -> IResult<&[T], &[T]>) => &[T] -> IResult<&[T], Vec<T>>`
+/// 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 trnasforms them.
+///
+/// As an example, the chain `abc\tdef` could be `abc    def` (it also consumes the control character)
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::Done;
+/// # use nom::alpha;
+/// # use std::str::from_utf8;
+/// # fn main() {
+/// fn to_s(i:Vec<u8>) -> String {
+///   String::from_utf8_lossy(&i).into_owned()
+/// }
+
+///  named!(transform < String >,
+///    map!(
+///      escaped_transform!(call!(alpha), '\\',
+///        alt!(
+///            tag!("\\")       => { |_| &b"\\"[..] }
+///          | tag!("\"")       => { |_| &b"\""[..] }
+///          | tag!("n")        => { |_| &b"\n"[..] }
+///        )
+///      ), to_s
+///    )
+///  );
+///  assert_eq!(transform(&b"ab\\\"cd"[..]), Done(&b""[..], String::from("ab\"cd")));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! escaped_transform (
+  ($i:expr, $submac:ident!( $($args:tt)* ), $control_char: expr, $($rest:tt)+) => (
+    {
+      escaped_transform1!($i, $submac!($($args)*), $control_char, $($rest)*)
+    }
+  );
+
+  ($i:expr, $f:expr, $control_char: expr, $($rest:tt)+) => (
+    escaped_transform1!($i, call!($f), $control_char, $($rest)*)
+  );
+);
+
+/// Internal parser, do not use directly
+#[doc(hidden)]
+#[macro_export]
+macro_rules! escaped_transform1 (
+  ($i:expr, $submac1:ident!( $($args:tt)* ), $control_char: expr, $submac2:ident!( $($args2:tt)*) ) => (
+    {
+     escaped_transform_impl!($i, $submac1!($($args)*), $control_char,  $submac2!($($args2)*))
+    }
+  );
+  ($i:expr, $submac1:ident!( $($args:tt)* ), $control_char: expr, $g:expr) => (
+     escaped_transform_impl!($i, $submac1!($($args)*), $control_char, call!($g))
+  );
+);
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! escaped_transform_impl (
+  ($i: expr, $normal:ident!(  $($args:tt)* ), $control_char: expr, $transform:ident!(  $($args2:tt)* )) => (
+    {
+      use $crate::InputLength;
+      let cl = || {
+        use $crate::HexDisplay;
+        let mut index  = 0;
+        let mut res = Vec::new();
+
+        while index < $i.len() {
+          if let $crate::IResult::Done(i,o) = $normal!(&$i[index..], $($args)*) {
+            res.extend(o.iter().cloned());
+            if i.is_empty() {
+              return $crate::IResult::Done(&$i[$i.input_len()..], res)
+            } else {
+              index = $i.offset(i);
+            }
+          } else if $i[index] == $control_char as u8 {
+            if index + 1 >= $i.len() {
+              return $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::EscapedTransform,&$i[index..]));
+            } else {
+              match $transform!(&$i[index+1..], $($args2)*) {
+                $crate::IResult::Done(i,o) => {
+                  res.extend(o.iter().cloned());
+                  if i.is_empty() {
+                    return $crate::IResult::Done(&$i[$i.input_len()..], res)
+                  } else {
+                    index = $i.offset(i);
+                  }
+                },
+                $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($crate::Err::Position($crate::ErrorKind::EscapedTransform,&$i[index..]))
+            } else {
+              return $crate::IResult::Done(&$i[index..], res)
+            }
+          }
+        }
+        $crate::IResult::Done(&$i[index..], res)
+      };
+      match cl() {
+        $crate::IResult::Incomplete(x) => $crate::IResult::Incomplete(x),
+        $crate::IResult::Done(i, o)    => $crate::IResult::Done(i, o),
+        $crate::IResult::Error(e)      => {
+          return $crate::IResult::Error($crate::Err::NodePosition($crate::ErrorKind::EscapedTransform, $i, Box::new(e)))
+        }
+      }
+    }
+  )
+);
+
+/// `take_while!(T -> bool) => &[T] -> IResult<&[T], &[T]>`
+/// returns the longest list of bytes until the provided function fails.
+///
+/// The argument is either a function `T -> bool` or a macro returning a `bool`.
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::Done;
+/// # use nom::is_alphanumeric;
+/// # fn main() {
+///  named!( alpha, take_while!( is_alphanumeric ) );
+///
+///  let r = alpha(&b"abcd\nefgh"[..]);
+///  assert_eq!(r, Done(&b"\nefgh"[..], &b"abcd"[..]));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! take_while (
+  ($input:expr, $submac:ident!( $($args:tt)* )) => (
+    {
+      match $input.iter().position(|c| !$submac!(*c, $($args)*)) {
+        Some(n) => {
+          let res:$crate::IResult<_,_> = $crate::IResult::Done(&$input[n..], &$input[..n]);
+          res
+        },
+        None    => {
+          $crate::IResult::Done(&$input[($input).len()..], $input)
+        }
+      }
+    }
+  );
+  ($input:expr, $f:expr) => (
+    take_while!($input, call!($f));
+  );
+);
+
+/// `take_while1!(&[T] -> bool) => &[T] -> IResult<&[T], &[T]>`
+/// returns the longest (non empty) list of bytes until the provided function fails.
+///
+/// The argument is either a function `&[T] -> bool` or a macro returning a `bool
+#[macro_export]
+macro_rules! take_while1 (
+  ($input:expr, $submac:ident!( $($args:tt)* )) => (
+    {
+      use $crate::InputLength;
+      if ($input).input_len() == 0 {
+        $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::TakeWhile1,$input))
+      } else {
+        match $input.iter().position(|c| !$submac!(*c, $($args)*)) {
+          Some(0) => $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::TakeWhile1,$input)),
+          Some(n) => {
+            $crate::IResult::Done(&$input[n..], &$input[..n])
+          },
+          None    => {
+            $crate::IResult::Done(&$input[($input).len()..], $input)
+          }
+        }
+      }
+    }
+  );
+  ($input:expr, $f:expr) => (
+    take_while1!($input, call!($f));
+  );
+);
+
+/// `take_till!(T -> bool) => &[T] -> IResult<&[T], &[T]>`
+/// returns the longest list of bytes until the provided function succeeds
+///
+/// The argument is either a function `&[T] -> bool` or a macro returning a `bool
+#[macro_export]
+macro_rules! take_till (
+  ($input:expr, $submac:ident!( $($args:tt)* )) => (
+    {
+      use $crate::InputLength;
+      match $input.iter().position(|c| $submac!(c, $($args)*)) {
+        Some(n) => $crate::IResult::Done(&$input[n..], &$input[..n]),
+        None    => $crate::IResult::Done(&$input[($input).input_len()..], $input)
+      }
+    }
+  );
+  ($input:expr, $f:expr) => (
+    take_till!($input, call!($f));
+  );
+);
+
+/// `take!(nb) => &[T] -> IResult<&[T], &[T]>`
+/// generates a parser consuming the specified number of bytes
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::Done;
+/// # fn main() {
+///  // Desmond parser
+///  named!(take5, take!( 5 ) );
+///
+///  let a = b"abcdefgh";
+///
+///  assert_eq!(take5(&a[..]), Done(&b"fgh"[..], &b"abcde"[..]));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! take (
+  ($i:expr, $count:expr) => (
+    {
+      let cnt = $count as usize;
+      let res: $crate::IResult<_,_> = if $i.len() < cnt {
+        $crate::IResult::Incomplete($crate::Needed::Size(cnt))
+      } else {
+        $crate::IResult::Done(&$i[cnt..],&$i[0..cnt])
+      };
+      res
+    }
+  );
+);
+
+/// `take!(nb) => &[T] -> IResult<&[T], &str>`
+/// same as take! but returning a &str
+#[macro_export]
+macro_rules! take_str (
+ ( $i:expr, $size:expr ) => ( map_res!($i, take!($size), ::std::str::from_utf8) );
+);
+
+/// `take_until_and_consume!(tag) => &[T] -> IResult<&[T], &[T]>`
+/// generates a parser consuming bytes until the specified byte sequence is found, and consumes it
+#[macro_export]
+macro_rules! take_until_and_consume(
+  ($i:expr, $inp:expr) => (
+    {
+      #[inline(always)]
+      fn as_bytes<T: $crate::AsBytes>(b: &T) -> &[u8] {
+        b.as_bytes()
+      }
+
+      let expected   = $inp;
+      let bytes      = as_bytes(&expected);
+      take_until_and_consume_bytes!($i, bytes)
+    }
+  );
+);
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! take_until_and_consume_bytes (
+  ($i:expr, $bytes:expr) => (
+    {
+      let res: $crate::IResult<_,_> = if $bytes.len() > $i.len() {
+        $crate::IResult::Incomplete($crate::Needed::Size($bytes.len()))
+      } else {
+        let mut index  = 0;
+        let mut parsed = false;
+
+        for idx in 0..$i.len() {
+          if idx + $bytes.len() > $i.len() {
+            index = idx;
+            break;
+          }
+          if &$i[idx..idx + $bytes.len()] == $bytes {
+            parsed = true;
+            index = idx;
+            break;
+          }
+        }
+
+        if parsed {
+          $crate::IResult::Done(&$i[(index + $bytes.len())..], &$i[0..index])
+        } else {
+          $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::TakeUntilAndConsume,$i))
+        }
+      };
+      res
+    }
+  );
+);
+
+/// `take_until!(tag) => &[T] -> IResult<&[T], &[T]>`
+/// consumes data until it finds the specified tag
+#[macro_export]
+macro_rules! take_until(
+  ($i:expr, $inp:expr) => (
+    {
+      #[inline(always)]
+      fn as_bytes<T: $crate::AsBytes>(b: &T) -> &[u8] {
+        b.as_bytes()
+      }
+
+      let expected   = $inp;
+      let bytes      = as_bytes(&expected);
+      take_until_bytes!($i, bytes)
+    }
+  );
+);
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! take_until_bytes(
+  ($i:expr, $bytes:expr) => (
+    {
+      let res: $crate::IResult<_,_> = if $bytes.len() > $i.len() {
+        $crate::IResult::Incomplete($crate::Needed::Size($bytes.len()))
+      } else {
+        let mut index  = 0;
+        let mut parsed = false;
+
+        for idx in 0..$i.len() {
+          if idx + $bytes.len() > $i.len() {
+            index = idx;
+            break;
+          }
+          if &$i[idx..idx+$bytes.len()] == $bytes {
+            parsed = true;
+            index  = idx;
+            break;
+          }
+        }
+
+        if parsed {
+          $crate::IResult::Done(&$i[index..], &$i[0..index])
+        } else {
+          $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::TakeUntil,$i))
+        }
+      };
+      res
+    }
+  );
+);
+
+/// `take_until_either_and_consume!(tag) => &[T] -> IResult<&[T], &[T]>`
+/// consumes data until it finds any of the specified characters, and consume it
+#[macro_export]
+macro_rules! take_until_either_and_consume(
+  ($i:expr, $inp:expr) => (
+    {
+      #[inline(always)]
+      fn as_bytes<T: $crate::AsBytes>(b: &T) -> &[u8] {
+        b.as_bytes()
+      }
+
+      let expected   = $inp;
+      let bytes      = as_bytes(&expected);
+      take_until_either_and_consume_bytes!($i, bytes)
+    }
+  );
+);
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! take_until_either_and_consume_bytes(
+  ($i:expr, $bytes:expr) => (
+    {
+      let res: $crate::IResult<_,_> = if 1 > $i.len() {
+        $crate::IResult::Incomplete($crate::Needed::Size(1))
+      } else {
+        let mut index  = 0;
+        let mut parsed = false;
+
+        for idx in 0..$i.len() {
+          if idx + 1 > $i.len() {
+            index = idx;
+            break;
+          }
+          for &t in $bytes.iter() {
+            if $i[idx] == t {
+              parsed = true;
+              index = idx;
+              break;
+            }
+          }
+          if parsed { break; }
+        }
+
+        if parsed {
+          $crate::IResult::Done(&$i[(index+1)..], &$i[0..index])
+        } else {
+          $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::TakeUntilEitherAndConsume,$i))
+        }
+      };
+      res
+    }
+  );
+);
+
+/// `take_until_either!(tag) => &[T] -> IResult<&[T], &[T]>`
+#[macro_export]
+macro_rules! take_until_either(
+  ($i:expr, $inp:expr) => (
+    {
+      #[inline(always)]
+      fn as_bytes<T: $crate::AsBytes>(b: &T) -> &[u8] {
+        b.as_bytes()
+      }
+
+      let expected   = $inp;
+      let bytes      = as_bytes(&expected);
+      take_until_either_bytes!($i, bytes)
+    }
+  );
+);
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! take_until_either_bytes(
+  ($i:expr, $bytes:expr) => (
+    {
+      let res: $crate::IResult<_,_> = if 1 > $i.len() {
+        $crate::IResult::Incomplete($crate::Needed::Size(1))
+      } else {
+        let mut index  = 0;
+        let mut parsed = false;
+
+        for idx in 0..$i.len() {
+          if idx + 1 > $i.len() {
+            index = idx;
+            break;
+          }
+          for &t in $bytes.iter() {
+            if $i[idx] == t {
+              parsed = true;
+              index = idx;
+              break;
+            }
+          }
+          if parsed { break; }
+        }
+
+        if parsed {
+          $crate::IResult::Done(&$i[index..], &$i[0..index])
+        } else {
+          $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::TakeUntilEither,$i))
+        }
+      };
+      res
+    }
+  );
+);
+
+/// `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(
+  ($i:expr, $submac:ident!( $($args: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,nb)   => {
+          let nb = nb as usize;
+          let length_remaining = i1.len();
+          if length_remaining < nb {
+            $crate::IResult::Incomplete($crate::Needed::Size(nb - length_remaining))
+          } else {
+            $crate::IResult::Done(&i1[nb..], &i1[..nb])
+          }
+        }
+      }
+    }
+  );
+  ($i:expr, $f:expr) => (
+    length_bytes!($i, call!($f))
+  )
+);
+
+#[cfg(test)]
+mod tests {
+  use internal::Needed;
+  use internal::IResult::*;
+  use internal::Err::*;
+  use util::ErrorKind;
+  use nom::{alpha, digit, hex_digit, oct_digit, alphanumeric, space, multispace};
+
+  #[test]
+  fn is_a() {
+    named!(a_or_b, is_a!(&b"ab"[..]));
+
+    let a = &b"abcd"[..];
+    assert_eq!(a_or_b(a), Done(&b"cd"[..], &b"ab"[..]));
+
+    let b = &b"bcde"[..];
+    assert_eq!(a_or_b(b), Done(&b"cde"[..], &b"b"[..]));
+
+    let c = &b"cdef"[..];
+    assert_eq!(a_or_b(c), Error(Position(ErrorKind::IsA,c)));
+
+    let d = &b"bacdef"[..];
+    assert_eq!(a_or_b(d), Done(&b"cdef"[..], &b"ba"[..]));
+  }
+
+  #[test]
+  fn is_not() {
+    named!(a_or_b, is_not!(&b"ab"[..]));
+
+    let a = &b"cdab"[..];
+    assert_eq!(a_or_b(a), Done(&b"ab"[..], &b"cd"[..]));
+
+    let b = &b"cbde"[..];
+    assert_eq!(a_or_b(b), Done(&b"bde"[..], &b"c"[..]));
+
+    let c = &b"abab"[..];
+    assert_eq!(a_or_b(c), Error(Position(ErrorKind::IsNot,c)));
+
+    let d = &b"cdefba"[..];
+    assert_eq!(a_or_b(d), Done(&b"ba"[..], &b"cdef"[..]));
+
+    let e = &b"e"[..];
+    assert_eq!(a_or_b(e), Done(&b""[..], &b"e"[..]));
+
+    let f = &b"fghi"[..];
+    assert_eq!(a_or_b(f), Done(&b""[..], &b"fghi"[..]));
+  }
+
+  #[test]
+  fn escaping() {
+    named!(esc, escaped!(call!(alpha), '\\', is_a_bytes!(&b"\"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"[..]));
+    assert_eq!(esc(&b"\\n"[..]), Done(&b""[..], &b"\\n"[..]));
+    assert_eq!(esc(&b"ab\\\"12"[..]), Done(&b"12"[..], &b"ab\\\""[..]));
+    assert_eq!(esc(&b"AB\\"[..]), Error(NodePosition(ErrorKind::Escaped, &b"AB\\"[..], Box::new(Position(ErrorKind::Escaped, &b"\\"[..])))));
+    assert_eq!(esc(&b"AB\\A"[..]), Error(NodePosition(ErrorKind::Escaped, &b"AB\\A"[..], Box::new(Position(ErrorKind::IsA, &b"A"[..])))));
+  }
+
+  fn to_s(i:Vec<u8>) -> String {
+    String::from_utf8_lossy(&i).into_owned()
+  }
+
+  #[test]
+  fn escape_transform() {
+    use std::str;
+
+    named!(esc< String >, map!(escaped_transform!(alpha, '\\',
+      alt!(
+          tag!("\\")       => { |_| &b"\\"[..] }
+        | tag!("\"")       => { |_| &b"\""[..] }
+        | tag!("n")        => { |_| &b"\n"[..] }
+      )), to_s)
+    );
+
+    assert_eq!(esc(&b"abcd"[..]), Done(&b""[..], String::from("abcd")));
+    assert_eq!(esc(&b"ab\\\"cd"[..]), Done(&b""[..], String::from("ab\"cd")));
+    assert_eq!(esc(&b"\\\"abcd"[..]), Done(&b""[..], String::from("\"abcd")));
+    assert_eq!(esc(&b"\\n"[..]), Done(&b""[..], String::from("\n")));
+    assert_eq!(esc(&b"ab\\\"12"[..]), Done(&b"12"[..], String::from("ab\"")));
+    assert_eq!(esc(&b"AB\\"[..]), Error(NodePosition(ErrorKind::EscapedTransform, &b"AB\\"[..], Box::new(Position(ErrorKind::EscapedTransform, &b"\\"[..])))));
+    assert_eq!(esc(&b"AB\\A"[..]), Error(NodePosition(ErrorKind::EscapedTransform, &b"AB\\A"[..], Box::new(Position(ErrorKind::Alt, &b"A"[..])))));
+
+    let e = "è";
+    let a = "à";
+    println!("è: {:?} | à: {:?}", str::as_bytes(e), str::as_bytes(a));
+    named!(esc2< String >, map!(escaped_transform!(call!(alpha), '&',
+      alt!(
+          tag!("egrave;") => { |_| str::as_bytes("è") }
+        | tag!("agrave;") => { |_| str::as_bytes("à") }
+      )), to_s)
+    );
+    assert_eq!(esc2(&b"ab&egrave;DEF"[..]), Done(&b""[..], String::from("abèDEF")));
+    assert_eq!(esc2(&b"ab&egrave;D&agrave;EF"[..]), Done(&b""[..], String::from("abèDàEF")));
+  }
+
+  #[test]
+  fn issue_84() {
+    let r0 = is_a!(&b"aaaaefgh"[..], "abcd");
+    assert_eq!(r0, Done(&b"efgh"[..], &b"aaaa"[..]));
+    let r1 = is_a!(&b"aaaa"[..], "abcd");
+    assert_eq!(r1, Done(&b""[..], &b"aaaa"[..]));
+    let r2 = is_a!(&b"1"[..], "123456789");
+    assert_eq!(r2, Done(&b""[..], &b"1"[..]));
+  }
+
+  #[test]
+  fn take_str_test() {
+    let a = b"omnomnom";
+
+    assert_eq!(take_str!(&a[..], 5), Done(&b"nom"[..], "omnom"));
+    assert_eq!(take_str!(&a[..], 9), Incomplete(Needed::Size(9)));
+  }
+
+  #[test]
+  fn take_until_test() {
+    named!(x, take_until_and_consume!("efgh"));
+    let r = x(&b"abcdabcdefghijkl"[..]);
+    assert_eq!(r, Done(&b"ijkl"[..], &b"abcdabcd"[..]));
+
+    println!("Done 1\n");
+
+    let r2 = x(&b"abcdabcdefgh"[..]);
+    assert_eq!(r2, Done(&b""[..], &b"abcdabcd"[..]));
+
+    println!("Done 2\n");
+    let r3 = x(&b"abcefg"[..]);
+    assert_eq!(r3,  Error(Position(ErrorKind::TakeUntilAndConsume, &b"abcefg"[..])));
+
+    assert_eq!(
+      x(&b"ab"[..]),
+      Incomplete(Needed::Size(4))
+    );
+  }
+
+  #[test]
+  fn take_until_either_incomplete() {
+    named!(x, take_until_either!("!."));
+    assert_eq!(
+      x(&b"123"[..]),
+      Error(Position(ErrorKind::TakeUntilEither, &b"123"[..]))
+    );
+  }
+
+  #[test]
+  fn take_until_incomplete() {
+    named!(y, take_until!("end"));
+    assert_eq!(
+      y(&b"nd"[..]),
+      Incomplete(Needed::Size(3))
+    );
+    assert_eq!(
+      y(&b"123"[..]),
+      Error(Position(ErrorKind::TakeUntil, &b"123"[..]))
+    );
+  }
+
+  #[test]
+  fn recognize() {
+    named!(x, recognize!(delimited!(tag!("<!--"), take!(5), tag!("-->"))));
+    let r = x(&b"<!-- abc --> aaa"[..]);
+    assert_eq!(r, Done(&b" aaa"[..], &b"<!-- abc -->"[..]));
+
+    let empty = &b""[..];
+
+    named!(ya, recognize!(alpha));
+    let ra = ya(&b"abc"[..]);
+    assert_eq!(ra, Done(empty, &b"abc"[..]));
+
+    named!(yd, recognize!(digit));
+    let rd = yd(&b"123"[..]);
+    assert_eq!(rd, Done(empty, &b"123"[..]));
+
+    named!(yhd, recognize!(hex_digit));
+    let rhd = yhd(&b"123abcDEF"[..]);
+    assert_eq!(rhd, Done(empty, &b"123abcDEF"[..]));
+
+    named!(yod, recognize!(oct_digit));
+    let rod = yod(&b"1234567"[..]);
+    assert_eq!(rod, Done(empty, &b"1234567"[..]));
+
+    named!(yan, recognize!(alphanumeric));
+    let ran = yan(&b"123abc"[..]);
+    assert_eq!(ran, Done(empty, &b"123abc"[..]));
+
+    named!(ys, recognize!(space));
+    let rs = ys(&b" \t"[..]);
+    assert_eq!(rs, Done(empty, &b" \t"[..]));
+
+    named!(yms, recognize!(multispace));
+    let rms = yms(&b" \t\r\n"[..]);
+    assert_eq!(rms, Done(empty, &b" \t\r\n"[..]));
+  }
+
+  #[test]
+  fn take_while() {
+    use nom::is_alphabetic;
+    named!(f, take_while!(is_alphabetic));
+    let a = b"";
+    let b = b"abcd";
+    let c = b"abcd123";
+    let d = b"123";
+
+    assert_eq!(f(&a[..]), Done(&a[..], &a[..]));
+    assert_eq!(f(&b[..]), Done(&a[..], &b[..]));
+    assert_eq!(f(&c[..]), Done(&d[..], &b[..]));
+    assert_eq!(f(&d[..]), Done(&d[..], &a[..]));
+  }
+
+  #[test]
+  fn take_while1() {
+    use nom::is_alphabetic;
+    named!(f, take_while1!(is_alphabetic));
+    let a = b"";
+    let b = b"abcd";
+    let c = b"abcd123";
+    let d = b"123";
+
+    assert_eq!(f(&a[..]), Error(Position(ErrorKind::TakeWhile1, &b""[..])));
+    assert_eq!(f(&b[..]), Done(&a[..], &b[..]));
+    assert_eq!(f(&c[..]), Done(&b"123"[..], &b[..]));
+    assert_eq!(f(&d[..]), Error(Position(ErrorKind::TakeWhile1, &d[..])));
+  }
+
+  #[cfg(feature = "nightly")]
+  use test::Bencher;
+
+  #[cfg(feature = "nightly")]
+  #[bench]
+  fn take_while_bench(b: &mut Bencher) {
+    use nom::is_alphabetic;
+    named!(f, take_while!(is_alphabetic));
+    b.iter(|| {
+      f(&b"abcdefghijklABCDEejfrfrjgro12aa"[..])
+    });
+  }
+
+  #[test]
+  fn recognize_take_while() {
+    use nom::is_alphanumeric;
+    named!(x, take_while!(is_alphanumeric));
+    named!(y, recognize!(x));
+    assert_eq!(x(&b"ab"[..]), Done(&[][..], &b"ab"[..]));
+    println!("X: {:?}", x(&b"ab"[..]));
+    assert_eq!(y(&b"ab"[..]), Done(&[][..], &b"ab"[..]));
+  }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/nom-1.2.4/src/character.rs
@@ -0,0 +1,184 @@
+/// Character level parsers
+
+use internal::{IResult,Needed,Err};
+use util::ErrorKind;
+
+/// matches one of the provided characters
+#[macro_export]
+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)
+      }
+    }
+  );
+);
+
+#[doc(hidden)]
+#[macro_export]
+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($crate::Err::Position($crate::ErrorKind::OneOf, $i))
+        }
+      }
+    }
+  );
+);
+
+/// matches anything but the provided characters
+#[macro_export]
+macro_rules! none_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);
+        none_of_bytes!($i, bytes)
+      }
+    }
+  );
+);
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! none_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($crate::Err::Position($crate::ErrorKind::NoneOf, $i))
+        }
+      }
+    }
+  );
+);
+
+/// matches one character: `char!(char) => &[u8] -> IResult<&[u8], char>
+#[macro_export]
+macro_rules! char (
+  ($i:expr, $c: expr) => (
+    {
+      if $i.is_empty() {
+        let res: $crate::IResult<&[u8], char> = $crate::IResult::Incomplete($crate::Needed::Size(1));
+        res
+      } else {
+        if $i[0] == $c as u8 {
+          $crate::IResult::Done(&$i[1..], $i[0] as char)
+        } else {
+          $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::Char, $i))
+        }
+      }
+    }
+  );
+);
+
+named!(pub newline<char>, char!('\n'));
+
+pub fn crlf(input:&[u8]) -> IResult<&[u8], char> {
+  if input.len() < 2 {
+    IResult::Incomplete(Needed::Size(2))
+  } else {
+    if &input[0..2] == &b"\r\n"[..] {
+      IResult::Done(&input[2..], '\n')
+    } else {
+      IResult::Error(Err::Position(ErrorKind::CrLf, input))
+    }
+  }
+}
+
+named!(pub eol<char>, alt!(crlf | newline));
+named!(pub tab<char>, char!('\t'));
+
+pub fn anychar(input:&[u8]) -> IResult<&[u8], char> {
+  if input.is_empty() {
+    IResult::Incomplete(Needed::Size(1))
+  } else {
+    IResult::Done(&input[1..], input[0] as char)
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use internal::IResult::*;
+  use internal::Err::*;
+  use util::ErrorKind;
+
+  #[test]
+  fn one_of() {
+    named!(f<char>, one_of!("ab"));
+
+    let a = &b"abcd"[..];
+    assert_eq!(f(a), Done(&b"bcd"[..], 'a'));
+
+    let b = &b"cde"[..];
+    assert_eq!(f(b), Error(Position(ErrorKind::OneOf, b)));
+  }
+
+  #[test]
+  fn none_of() {
+    named!(f<char>, none_of!("ab"));
+
+    let a = &b"abcd"[..];
+    assert_eq!(f(a), Error(Position(ErrorKind::NoneOf, a)));
+
+    let b = &b"cde"[..];
+    assert_eq!(f(b), Done(&b"de"[..], 'c'));
+  }
+
+  #[test]
+  fn char() {
+    named!(f<char>, char!('c'));
+
+    let a = &b"abcd"[..];
+    assert_eq!(f(a), Error(Position(ErrorKind::Char, a)));
+
+    let b = &b"cde"[..];
+    assert_eq!(f(b), Done(&b"de"[..], 'c'));
+  }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/nom-1.2.4/src/internal.rs
@@ -0,0 +1,347 @@
+//! Basic types to build the parsers
+
+use self::IResult::*;
+use self::Needed::*;
+use util::ErrorKind;
+
+#[cfg(feature = "core")]
+use std::prelude::v1::*;
+use std::boxed::Box;
+
+/// Contains the error that a parser can return
+///
+/// It can represent a linked list of errors, indicating the path taken in the parsing tree, with corresponding position in the input data.
+/// It depends on P, the input position (for a &[u8] parser, it would be a &[u8]), and E, the custom error type (by default, u32)
+#[derive(Debug,PartialEq,Eq,Clone)]
+pub enum Err<P,E=u32>{
+  /// An error code, represented by an ErrorKind, which can contain a custom error code represented by E
+  Code(ErrorKind<E>),
+  /// An error code, and the next error
+  Node(ErrorKind<E>, Box<Err<P,E>>),
+  /// An error code, and the input position
+  Position(ErrorKind<E>, P),
+  /// An error code, the input position and the next error
+  NodePosition(ErrorKind<E>, P, Box<Err<P,E>>)
+}
+
+/// Contains information on needed data if a parser returned `Incomplete`
+#[derive(Debug,PartialEq,Eq,Clone,Copy)]
+pub enum Needed {
+  /// needs more data, but we do not know how much
+  Unknown,
+  /// contains the required data size
+  Size(usize)
+}
+
+impl Needed {
+  pub fn is_known(&self) -> bool {
+    *self != Unknown
+  }
+
+  /// Maps a `Needed` to `Needed` by appling a function to a contained `Size` value.
+  #[inline]
+  pub fn map<F: FnOnce(usize) -> usize>(self, f: F) -> Needed {
+    match self {
+      Unknown => Unknown,
+      Size(n) => Size(f(n)),
+    }
+  }
+}
+
+/// Holds the result of parsing functions
+///
+/// It depends on I, the input type, O, the output type, and E, the error type (by default u32)
+///
+#[derive(Debug,PartialEq,Eq,Clone)]
+pub enum IResult<I,O,E=u32> {
+   /// indicates a correct parsing, the first field containing the rest of the unparsed data, the second field contains the parsed data
+  Done(I,O),
+  /// contains a Err, an enum that can indicate an error code, a position in the input, and a pointer to another error, making a list of errors in the parsing tree
+  Error(Err<I,E>),
+  /// Incomplete contains a Needed, an enum than can represent a known quantity of input data, or unknown
+  Incomplete(Needed)
+}
+
+impl<I,O,E> IResult<I,O,E> {
+  pub fn is_done(&self) -> bool {
+    match *self {
+      Done(_,_) => true,
+      _         => false
+    }
+  }
+
+  pub fn is_err(&self) -> bool {
+    match *self {
+      Error(_) => true,
+      _        => false
+    }
+  }
+
+  pub fn is_incomplete(&self) -> bool {
+    match *self {
+      Incomplete(_) => true,
+      _             => false
+    }
+  }
+
+  /// Maps a `IResult<I, O, E>` to `IResult<I, N, E>` by appling a function
+  /// to a contained `Done` value, leaving `Error` and `Incomplete` value
+  /// untouched.
+  #[inline]
+  pub fn map<N, F: FnOnce(O) -> N>(self, f: F) -> IResult<I, N, E> {
+    match self {
+      Done(i, o)    => Done(i, f(o)),
+      Error(e)      => Error(e),
+      Incomplete(n) => Incomplete(n),
+    }
+  }
+
+  /// Maps a `IResult<I, O, E>` to `IResult<I, O, E>` by appling a function
+  /// to a contained `Incomplete` value, leaving `Done` and `Error` value
+  /// untouched.
+  #[inline]
+  pub fn map_inc<F>(self, f: F) -> IResult<I, O, E>
+   where F: FnOnce(Needed) -> Needed {
+    match self {
+      Error(e)      => Error(e),
+      Incomplete(n) => Incomplete(f(n)),
+      Done(i, o)    => Done(i, o),
+    }
+  }
+
+  /// Maps a `IResult<I, O, E>` to `IResult<I, O, N>` by appling a function
+  /// to a contained `Error` value, leaving `Done` and `Incomplete` value
+  /// untouched.
+  #[inline]
+  pub fn map_err<N, F>(self, f: F) -> IResult<I, O, N>
+   where F: FnOnce(Err<I, E>) -> Err<I, N> {
+    match self {
+      Error(e)      => Error(f(e)),
+      Incomplete(n) => Incomplete(n),
+      Done(i, o)    => Done(i, o),
+    }
+  }
+
+  /// Unwrap the contained `Done(I, O)` value, or panic if the `IResult` is not
+  /// `Done`.
+  pub fn unwrap(self) -> (I, O) {
+    match self {
+      Done(i, o)    => (i, o),
+      Incomplete(_) => panic!("unwrap() called on an IResult that is Incomplete"),
+      Error(_)      => panic!("unwrap() called on an IResult that is Error")
+    }
+  }
+
+  /// Unwrap the contained `Done(I, O)` value, or panic if the `IResult` is not
+  /// `Done`.
+  pub fn unwrap_inc(self) -> Needed {
+    match self {
+      Incomplete(n) => n,
+      Done(_, _)    => panic!("unwrap_inc() called on an IResult that is Done"),
+      Error(_)      => panic!("unwrap_inc() called on an IResult that is Error")
+    }
+  }
+
+  /// Unwrap the contained `Done(I, O)` value, or panic if the `IResult` is not
+  /// `Done`.
+  pub fn unwrap_err(self) -> Err<I, E> {
+    match self {
+      Error(e)      => e,
+      Done(_, _)    => panic!("unwrap_err() called on an IResult that is Done"),
+      Incomplete(_) => panic!("unwrap_err() called on an IResult that is Incomplete"),
+    }
+  }
+}
+
+pub trait GetInput<I> {
+  fn remaining_input(&self) -> Option<I>;
+}
+
+pub trait GetOutput<O> {
+  fn output(&self) -> Option<O>;
+}
+
+impl<'a,I,O,E> GetInput<&'a[I]> for IResult<&'a[I],O,E> {
+  fn remaining_input(&self) -> Option<&'a[I]> {
+    match *self {
+      Done(ref i,_) => Some(*i),
+      _             => None
+    }
+  }
+}
+
+impl<O,E> GetInput<()> for IResult<(),O,E> {
+  fn remaining_input(&self) -> Option<()> {
+    match *self {
+      Done((),_) => Some(()),
+      _          => None
+    }
+  }
+}
+
+impl<'a,O,E> GetInput<&'a str> for IResult<&'a str,O,E> {
+  fn remaining_input(&self) -> Option<&'a str> {
+    match *self {
+      Done(ref i,_) => Some(*i),
+      _          => None
+    }
+  }
+}
+
+impl<'a,I,O,E> GetOutput<&'a[O]> for IResult<I,&'a[O],E> {
+  fn output(&self) -> Option<&'a[O]> {
+    match *self {
+      Done(_, ref o) => Some(*o),
+      _              => None
+    }
+  }
+}
+
+impl<I,E> GetOutput<()> for IResult<I,(),E> {
+  fn output(&self) -> Option<()> {
+    match *self {
+      Done(_,()) => Some(()),
+      _          => None
+    }
+  }
+}
+
+impl<'a,I,E> GetOutput<&'a str> for IResult<I,&'a str,E> {
+  fn output(&self) -> Option<&'a str> {
+    match *self {
+      Done(_,ref o) => Some(*o),
+      _          => None
+    }
+  }
+}
+
+#[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)
+      }
+    }
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use super::*;
+  use util::ErrorKind;
+
+  const REST: [u8; 0] = [];
+  const DONE: IResult<&'static [u8], u32> = IResult::Done(&REST, 5);
+  const ERROR: IResult<&'static [u8], u32> = IResult::Error(Err::Code(ErrorKind::Tag));
+  const INCOMPLETE: IResult<&'static [u8], u32> = IResult::Incomplete(Needed::Unknown);
+
+  #[test]
+  fn needed_map() {
+    let unknown = Needed::Unknown;
+    let size = Needed::Size(5);
+
+    assert_eq!(size.map(|x| x * 2), Needed::Size(10));
+    assert_eq!(unknown.map(|x| x * 2), Needed::Unknown);
+  }
+
+  #[test]
+  fn iresult_map() {
+    assert_eq!(DONE.map(|x| x * 2), IResult::Done(&b""[..], 10));
+    assert_eq!(ERROR.map(|x| x * 2), IResult::Error(Err::Code(ErrorKind::Tag)));
+    assert_eq!(INCOMPLETE.map(|x| x * 2), IResult::Incomplete(Needed::Unknown));
+  }
+
+  #[test]
+  fn iresult_map_inc() {
+    let inc_unknown: IResult<&[u8], u32> = IResult::Incomplete(Needed::Unknown);
+    let inc_size: IResult<&[u8], u32> = IResult::Incomplete(Needed::Size(5));
+
+    assert_eq!(DONE.map_inc(|n| if let Needed::Size(i) = n {Needed::Size(i+1)} else {n}), IResult::Done(&b""[..], 5));
+    assert_eq!(ERROR.map_inc(|n| if let Needed::Size(i) = n {Needed::Size(i+1)} else {n}), IResult::Error(Err::Code(ErrorKind::Tag)));
+    assert_eq!(inc_unknown.map_inc(|n| if let Needed::Size(i) = n {Needed::Size(i+1)} else {n}), IResult::Incomplete(Needed::Unknown));
+    assert_eq!(inc_size.map_inc(|n| if let Needed::Size(i) = n {Needed::Size(i+1)} else {n}), IResult::Incomplete(Needed::Size(6)));
+  }
+
+  #[test]
+  fn iresult_map_err() {
+    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
+    struct Error(u32);
+
+    let error_kind = Err::Code(ErrorKind::Custom(Error(5)));
+
+    assert_eq!(DONE.map_err(|_| error_kind.clone()), IResult::Done(&b""[..], 5));
+    assert_eq!(ERROR.map_err(|x| {println!("err: {:?}", x); error_kind.clone()}), IResult::Error(error_kind.clone()));
+    assert_eq!(INCOMPLETE.map_err(|x| {println!("err: {:?}", x); error_kind.clone()}), IResult::Incomplete(Needed::Unknown));
+  }
+
+  #[test]
+  fn iresult_unwrap_on_done() {
+    assert_eq!(DONE.unwrap(), (&b""[..], 5));
+  }
+
+  #[test]
+  #[should_panic]
+  fn iresult_unwrap_on_err() {
+    ERROR.unwrap();
+  }
+
+  #[test]
+  #[should_panic]
+  fn iresult_unwrap_on_inc() {
+    INCOMPLETE.unwrap();
+  }
+
+  #[test]
+  #[should_panic]
+  fn iresult_unwrap_err_on_done() {
+    DONE.unwrap_err();
+  }
+
+  #[test]
+  fn iresult_unwrap_err_on_err() {
+    assert_eq!(ERROR.unwrap_err(), Err::Code(ErrorKind::Tag));
+  }
+
+  #[test]
+  #[should_panic]
+  fn iresult_unwrap_err_on_inc() {
+    INCOMPLETE.unwrap_err();
+  }
+
+  #[test]
+  #[should_panic]
+  fn iresult_unwrap_inc_on_done() {
+    DONE.unwrap_inc();
+  }
+
+  #[test]
+  #[should_panic]
+  fn iresult_unwrap_inc_on_err() {
+    ERROR.unwrap_inc();
+  }
+
+  #[test]
+  fn iresult_unwrap_inc_on_inc() {
+    assert_eq!(INCOMPLETE.unwrap_inc(), Needed::Unknown);
+  }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/nom-1.2.4/src/lib.rs
@@ -0,0 +1,151 @@
+//! nom, eating data byte by byte
+//!
+//! nom is a parser combinator library with a focus on safe parsing,
+//! streaming patterns, and as much as possible zero copy.
+//!
+//! The code is available on [Github](https://github.com/Geal/nom)
+//!
+//! # Example
+//!
+//! ```
+//! #[macro_use]
+//! extern crate nom;
+//!
+//! use nom::{IResult,digit};
+//! use nom::IResult::*;
+//!
+//! // Parser definition
+//!
+//! use std::str;
+//! use std::str::FromStr;
+//!
+//! named!(parens<i64>, delimited!(
+//!     char!('('),
+//!     expr,
+//!     char!(')')
+//!   )
+//! );
+//!
+//! named!(i64_digit<i64>,
+//!   map_res!(
+//!     map_res!(
+//!       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 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>,
+//!   chain!(
+//!     mut acc: term  ~
+//!              many0!(
+//!                alt!(
+//!                  tap!(add: preceded!(tag!("+"), term) => acc = acc + add) |
+//!                  tap!(sub: preceded!(tag!("-"), term) => acc = acc - sub)
+//!                )
+//!              ),
+//!     || { return acc }
+//!   )
+//! );
+//!
+//! fn main() {
+//!   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));
+//!
+//!   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));
+//! }
+//! ```
+#![cfg_attr(feature = "core", feature(no_std))]
+#![cfg_attr(feature = "core", feature(collections))]
+#![cfg_attr(feature = "core", no_std)]
+#![cfg_attr(feature = "nightly", feature(test))]
+#![cfg_attr(feature = "nightly", feature(const_fn))]
+
+#[cfg(feature = "core")]
+extern crate collections;
+#[cfg(feature = "regexp")]
+extern crate regex;
+#[cfg(feature = "regexp_macros")]
+#[macro_use] extern crate lazy_static;
+#[cfg(feature = "nightly")]
+extern crate test;
+
+#[cfg(feature = "core")]
+mod std {
+#[macro_use]
+  pub use core::{fmt, iter, option, ops, slice, mem};
+  pub use collections::{boxed, vec, string};
+  pub mod prelude {
+    pub use core::prelude as v1;
+  }
+}
+
+pub use self::util::*;
+pub use self::internal::*;
+pub use self::macros::*;
+pub use self::methods::*;
+pub use self::bytes::*;
+pub use self::bits::*;
+
+pub use self::nom::*;
+pub use self::character::*;
+
+#[cfg(feature = "regexp")]
+pub use self::regexp::*;
+
+#[cfg(not(feature = "core"))]
+#[cfg(feature = "stream")]
+pub use self::stream::*;
+
+#[cfg(not(feature = "core"))]
+pub use self::str::*;
+
+#[macro_use] mod util;
+mod internal;
+#[macro_use] mod macros;
+#[macro_use] mod methods;
+#[macro_use] mod bytes;
+#[macro_use] mod bits;
+
+#[macro_use] mod nom;
+#[macro_use] mod character;
+
+#[cfg(feature = "regexp")]
+#[macro_use] mod regexp;
+
+#[macro_use]
+#[cfg(not(feature = "core"))]
+#[cfg(feature = "stream")]
+mod stream;
+
+#[cfg(not(feature = "core"))]
+mod str;
new file mode 100644
--- /dev/null
+++ b/third_party/rust/nom-1.2.4/src/macros.rs
@@ -0,0 +1,3561 @@
+//! Macro combinators
+//!
+//! Macros are used to make combination easier,
+//! since they often do not depend on the type
+//! of the data they manipulate or return.
+//!
+//! There is a trick to make them easier to assemble,
+//! combinators are defined like this:
+//!
+//! ```ignore
+//! macro_rules! tag (
+//!   ($i:expr, $inp: expr) => (
+//!     {
+//!       ...
+//!     }
+//!   );
+//! );
+//! ```
+//!
+//! But when used in other combinators, are Used
+//! like this:
+//!
+//! ```ignore
+//! named!(my_function, tag!("abcd"));
+//! ```
+//!
+//! Internally, other combinators will rewrite
+//! that call to pass the input as first argument:
+//!
+//! ```ignore
+//! macro_rules! named (
+//!   ($name:ident, $submac:ident!( $($args:tt)* )) => (
+//!     fn $name<'a>( i: &'a [u8] ) -> $crate::IResult<'a,&[u8], &[u8]> {
+//!       $submac!(i, $($args)*)
+//!     }
+//!   );
+//! );
+//! ```
+//!
+//! If you want to call a combinator directly, you can
+//! do it like this:
+//!
+//! ```ignore
+//! let res = { tag!(input, "abcd"); }
+//! ```
+//!
+//! Combinators must have a specific variant for
+//! non-macro arguments. Example: passing a function
+//! to take_while! instead of another combinator.
+//!
+//! ```ignore
+//! macro_rules! take_while(
+//!   ($input:expr, $submac:ident!( $($args:tt)* )) => (
+//!     {
+//!       ...
+//!     }
+//!   );
+//!
+//!   // wrap the function in a macro to pass it to the main implementation
+//!   ($input:expr, $f:expr) => (
+//!     take_while!($input, call!($f));
+//!   );
+//! );
+//!
+
+/// Wraps a parser in a closure
+#[macro_export]
+macro_rules! closure (
+    ($ty:ty, $submac:ident!( $($args:tt)* )) => (
+        |i: $ty| { $submac!(i, $($args)*) }
+    );
+    ($submac:ident!( $($args:tt)* )) => (
+        |i| { $submac!(i, $($args)*) }
+    );
+);
+
+/// Makes a function from a parser combination
+///
+/// The type can be set up if the compiler needs
+/// more information
+///
+/// ```ignore
+/// named!(my_function( &[u8] ) -> &[u8], tag!("abcd"));
+/// // first type parameter is input, second is output
+/// named!(my_function<&[u8], &[u8]>,     tag!("abcd"));
+/// // will have &[u8] as input type, &[u8] as output type
+/// named!(my_function,                   tag!("abcd"));
+/// // will use &[u8] as input type (use this if the compiler
+/// // complains about lifetime issues
+/// named!(my_function<&[u8]>,            tag!("abcd"));
+/// //prefix them with 'pub' to make the functions public
+/// named!(pub my_function,               tag!("abcd"));
+/// ```
+#[macro_export]
+macro_rules! named (
+    ($name:ident( $i:ty ) -> $o:ty, $submac:ident!( $($args:tt)* )) => (
+        fn $name( i: $i ) -> $crate::IResult<$i,$o,u32> {
+            $submac!(i, $($args)*)
+        }
+    );
+    ($name:ident<$i:ty,$o:ty,$e:ty>, $submac:ident!( $($args:tt)* )) => (
+        fn $name( i: $i ) -> $crate::IResult<$i, $o, $e> {
+            $submac!(i, $($args)*)
+        }
+    );
+    ($name:ident<$i:ty,$o:ty>, $submac:ident!( $($args:tt)* )) => (
+        fn $name( i: $i ) -> $crate::IResult<$i, $o, u32> {
+            $submac!(i, $($args)*)
+        }
+    );
+    ($name:ident<$o:ty>, $submac:ident!( $($args:tt)* )) => (
+        fn $name<'a>( i: &'a[u8] ) -> $crate::IResult<&'a [u8], $o, u32> {
+            $submac!(i, $($args)*)
+        }
+    );
+    ($name:ident, $submac:ident!( $($args:tt)* )) => (
+        fn $name( i: &[u8] ) -> $crate::IResult<&[u8], &[u8], u32> {
+            $submac!(i, $($args)*)
+        }
+    );
+    (pub $name:ident( $i:ty ) -> $o:ty, $submac:ident!( $($args:tt)* )) => (
+        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)* )) => (
+        pub fn $name( i: $i ) -> $crate::IResult<$i, $o, $e> {
+            $submac!(i, $($args)*)
+        }
+    );
+    (pub $name:ident<$i:ty,$o:ty>, $submac:ident!( $($args:tt)* )) => (
+        pub fn $name( i: $i ) -> $crate::IResult<$i, $o, u32> {
+            $submac!(i, $($args)*)
+        }
+    );
+    (pub $name:ident<$o:ty>, $submac:ident!( $($args:tt)* )) => (
+        pub fn $name( i: &[u8] ) -> $crate::IResult<&[u8], $o, u32> {
+            $submac!(i, $($args)*)
+        }
+    );
+    (pub $name:ident, $submac:ident!( $($args:tt)* )) => (
+        pub fn $name<'a>( i: &'a [u8] ) -> $crate::IResult<&[u8], &[u8], u32> {
+            $submac!(i, $($args)*)
+        }
+    );
+);
+
+/// Used to wrap common expressions and function as macros
+///
+/// ```
+/// # #[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));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! call (
+  ($i:expr, $fun:expr) => ( $fun( $i ) );
+  ($i:expr, $fun:expr, $($args:expr),* ) => ( $fun( $i, $($args),* ) );
+);
+
+/// emulate function currying: `apply!(my_function, arg1, arg2, ...)` becomes `my_function(input, arg1, arg2, ...)`
+///
+/// ```
+/// # #[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));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! apply (
+  ($i:expr, $fun:expr, $($args:expr),* ) => ( $fun( $i, $($args),* ) );
+);
+
+/// Prevents backtracking if the child parser fails
+///
+/// This parser will do an early return instead of sending
+/// its result to the parent parser.
+///
+/// If another `error!` combinator is present in the parent
+/// chain, the error will be wrapped and another early
+/// return will be made.
+///
+/// This makes it easy to build report on which parser failed,
+/// where it failed in the input, and the chain of parsers
+/// that led it there.
+///
+/// Additionally, the error chain contains number identifiers
+/// that can be matched to provide useful error messages.
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use std::collections;
+/// # use nom::IResult::Error;
+/// # use nom::Err::{Position,NodePosition};
+/// # use nom::ErrorKind;
+/// # fn main() {
+///     named!(err_test, alt!(
+///       tag!("abcd") |
+///       preceded!(tag!("efgh"), error!(ErrorKind::Custom(42),
+///           chain!(
+///                  tag!("ijkl")              ~
+///             res: error!(ErrorKind::Custom(128), tag!("mnop")) ,
+///             || { res }
+///           )
+///         )
+///       )
+///     ));
+///     let a = &b"efghblah"[..];
+///     let b = &b"efghijklblah"[..];
+///     let c = &b"efghijklmnop"[..];
+///
+///     let blah = &b"blah"[..];
+///
+///     let res_a = err_test(a);
+///     let res_b = err_test(b);
+///     let res_c = err_test(c);
+///     assert_eq!(res_a, Error(NodePosition(ErrorKind::Custom(42), blah, Box::new(Position(ErrorKind::Tag, blah)))));
+///     assert_eq!(res_b, Error(NodePosition(ErrorKind::Custom(42), &b"ijklblah"[..],
+///       Box::new(NodePosition(ErrorKind::Custom(128), blah, Box::new(Position(ErrorKind::Tag, blah))))))
+///     );
+/// # }
+/// ```
+///
+#[macro_export]
+macro_rules! error (
+  ($i:expr, $code:expr, $submac:ident!( $($args:tt)* )) => (
+    {
+      let cl = || {
+        $submac!($i, $($args)*)
+      };
+
+      match cl() {
+        $crate::IResult::Incomplete(x) => $crate::IResult::Incomplete(x),
+        $crate::IResult::Done(i, o)    => $crate::IResult::Done(i, o),
+        $crate::IResult::Error(e)      => {
+          return $crate::IResult::Error($crate::Err::NodePosition($code, $i, Box::new(e)))
+        }
+      }
+    }
+  );
+  ($i:expr, $code:expr, $f:expr) => (
+    error!($i, $code, call!($f));
+  );
+);
+
+/// Add an error if the child parser fails
+///
+/// While error! does an early return and avoids backtracking,
+/// add_error! backtracks normally. It just provides more context
+/// for an error
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use std::collections;
+/// # use nom::IResult::Error;
+/// # use nom::Err::{Position,NodePosition};
+/// # use nom::ErrorKind;
+/// # fn main() {
+///     named!(err_test, add_error!(ErrorKind::Custom(42), tag!("abcd")));
+///
+///     let a = &b"efghblah"[..];
+///     let res_a = err_test(a);
+///     assert_eq!(res_a, Error(NodePosition(ErrorKind::Custom(42), a, Box::new(Position(ErrorKind::Tag, a)))));
+/// # }
+/// ```
+///
+#[macro_export]
+macro_rules! add_error (
+  ($i:expr, $code:expr, $submac:ident!( $($args:tt)* )) => (
+    {
+      match $submac!($i, $($args)*) {
+        $crate::IResult::Incomplete(x) => $crate::IResult::Incomplete(x),
+        $crate::IResult::Done(i, o)    => $crate::IResult::Done(i, o),
+        $crate::IResult::Error(e)      => {
+          $crate::IResult::Error($crate::Err::NodePosition($code, $i, Box::new(e)))
+        }
+      }
+    }
+  );
+  ($i:expr, $code:expr, $f:expr) => (
+    add_error!($i, $code, call!($f));
+  );
+);
+
+
+/// translate parser result from IResult<I,O,u32> to IResult<I,O,E> with a custom type
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use std::collections;
+/// # use nom::IResult::Error;
+/// # use nom::Err::{Position,NodePosition};
+/// # use nom::ErrorKind;
+/// # fn main() {
+///     // will add a Custom(42) error to the error chain
+///     named!(err_test, add_error!(ErrorKind::Custom(42), tag!("abcd")));
+///     // Convert to IREsult<&[u8], &[u8], &str>
+///     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);
+///     assert_eq!(res_a,  Error(NodePosition( ErrorKind::Custom("custom error message"), a, Box::new(Position(ErrorKind::Fix, a)))));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! fix_error (
+  ($i:expr, $t:ty, $submac:ident!( $($args:tt)* )) => (
+    {
+      match $submac!($i, $($args)*) {
+        $crate::IResult::Incomplete(x) => $crate::IResult::Incomplete(x),
+        $crate::IResult::Done(i, o)    => $crate::IResult::Done(i, o),
+        $crate::IResult::Error(e) => {
+          let err = match e {
+            $crate::Err::Code($crate::ErrorKind::Custom(_)) |
+              $crate::Err::Node($crate::ErrorKind::Custom(_), _) => {
+              let e: $crate::ErrorKind<$t> = $crate::ErrorKind::Fix;
+              $crate::Err::Code(e)
+            },
+            $crate::Err::Position($crate::ErrorKind::Custom(_), p) |
+              $crate::Err::NodePosition($crate::ErrorKind::Custom(_), p, _) => {
+              let e: $crate::ErrorKind<$t> = $crate::ErrorKind::Fix;
+              $crate::Err::Position(e, p)
+            },
+            $crate::Err::Code(_) |
+              $crate::Err::Node(_, _) => {
+              let e: $crate::ErrorKind<$t> = $crate::ErrorKind::Fix;
+              $crate::Err::Code(e)
+            },
+            $crate::Err::Position(_, p) |
+              $crate::Err::NodePosition(_, p, _) => {
+              let e: $crate::ErrorKind<$t> = $crate::ErrorKind::Fix;
+              $crate::Err::Position(e, p)
+            },
+          };
+          $crate::IResult::Error(err)
+        }
+      }
+    }
+  );
+  ($i:expr, $t:ty, $f:expr) => (
+    fix_error!($i, $t, call!($f));
+  );
+);
+
+/// replaces a `Incomplete` returned by the child parser
+/// with an `Error`
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use std::collections;
+/// # use nom::IResult::Error;
+/// # use nom::Err::{Position,NodePosition};
+/// # use nom::ErrorKind;
+/// # fn main() {
+///     named!(take_5, complete!(take!(5)));
+///
+///     let a = &b"abcd"[..];
+///     let res_a = take_5(a);
+///     assert_eq!(res_a,  Error(Position(ErrorKind::Complete, a)));
+/// # }
+/// ```
+///
+#[macro_export]
+macro_rules! complete (
+  ($i:expr, $submac:ident!( $($args:tt)* )) => (
+    {
+      match $submac!($i, $($args)*) {
+        $crate::IResult::Done(i, o)    => $crate::IResult::Done(i, o),
+        $crate::IResult::Error(e)      => $crate::IResult::Error(e),
+        $crate::IResult::Incomplete(_) =>  {
+          $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::Complete, $i))
+        },
+      }
+    }
+  );
+  ($i:expr, $f:expr) => (
+    complete!($i, call!($f));
+  );
+);
+
+/// A bit like `std::try!`, this macro will return the remaining input and parsed value if the child parser returned `Done`,
+/// and will do an early return for `Error` and `Incomplete`
+/// this can provide more flexibility than `chain!` if needed
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::{self, Done, Error};
+/// # use nom::Err::Position;
+/// # use nom::{be_u8,ErrorKind};
+///
+///  fn take_add(input:&[u8], size: u8) -> IResult<&[u8],&[u8]> {
+///    let (i1, sz)     = try_parse!(input, be_u8);
+///    let (i2, length) = try_parse!(i1, expr_opt!(size.checked_add(sz)));
+///    let (i3, data)   = try_parse!(i2, take!(length));
+///    return Done(i3, data);
+///  }
+/// # fn main() {
+/// let arr1 = [1, 2, 3, 4, 5];
+/// let r1 = take_add(&arr1[..], 1);
+/// assert_eq!(r1, Done(&[4,5][..], &[2,3][..]));
+///
+/// let arr2 = [0xFE, 2, 3, 4, 5];
+/// // size is overflowing
+/// let r1 = take_add(&arr2[..], 42);
+/// assert_eq!(r1, Error(Position(ErrorKind::ExprOpt,&[2,3,4,5][..])));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! try_parse (
+  ($i:expr, $submac:ident!( $($args:tt)* )) => (
+    match $submac!($i, $($args)*) {
+      $crate::IResult::Done(i,o)     => (i,o),
+      $crate::IResult::Error(e)      => return $crate::IResult::Error(e),
+      $crate::IResult::Incomplete(i) => return $crate::IResult::Incomplete(i)
+    }
+  );
+  ($i:expr, $f:expr) => (
+    try_parse!($i, call!($f))
+  );
+);
+
+/// `flat_map!(R -> IResult<R,S>, S -> IResult<S,T>) => R -> IResult<R, T>`
+///
+/// combines a parser R -> IResult<R,S> and
+/// a parser S -> IResult<S,T> to return another
+/// parser R -> IResult<R,T>
+#[macro_export]
+macro_rules! flat_map(
+  ($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)                          => match $submac2!(o, $($args2)*) {
+          $crate::IResult::Error(e)                                 => {
+            let err = match e {
+              $crate::Err::Code(k) | $crate::Err::Node(k, _) | $crate::Err::Position(k, _) | $crate::Err::NodePosition(k, _, _) => {
+                $crate::Err::Position(k, $i)
+              }
+            };
+            $crate::IResult::Error(err)
+          },
+          $crate::IResult::Incomplete($crate::Needed::Unknown)      => $crate::IResult::Incomplete($crate::Needed::Unknown),
+          $crate::IResult::Incomplete($crate::Needed::Size(ref i2)) => $crate::IResult::Incomplete($crate::Needed::Size(*i2)),
+          $crate::IResult::Done(_, o2)                              => $crate::IResult::Done(i, o2)
+        }
+      }
+    }
+  );
+  ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
+    flat_map!($i, $submac!($($args)*), call!($g));
+  );
+  ($i:expr, $f:expr, $g:expr) => (
+    flat_map!($i, call!($f), call!($g));
+  );
+  ($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
+    flat_map!($i, call!($f), $submac!($($args)*));
+  );
+);
+
+/// `map!(I -> IResult<I,O>, O -> P) => I -> IResult<I, P>`
+/// maps a function on the result of a parser
+#[macro_export]
+macro_rules! map(
+  ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
+    map_impl!($i, $submac!($($args)*), call!($g));
+  );
+  ($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
+    map_impl!($i, $submac!($($args)*), $submac2!($($args2)*));
+  );
+  ($i:expr, $f:expr, $g:expr) => (
+    map_impl!($i, call!($f), call!($g));
+  );
+  ($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
+    map_impl!($i, call!($f), $submac!($($args)*));
+  );
+);
+
+/// Internal parser, do not use directly
+#[doc(hidden)]
+#[macro_export]
+macro_rules! map_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)                          => $crate::IResult::Done(i, $submac2!(o, $($args2)*))
+      }
+    }
+  );
+);
+
+/// `map_res!(I -> IResult<I,O>, O -> Result<P>) => I -> IResult<I, P>`
+/// maps a function returning a Result on the output of a parser
+#[macro_export]
+macro_rules! map_res (
+  ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
+    map_res_impl!($i, $submac!($($args)*), call!($g));
+  );
+  ($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
+    map_res_impl!($i, $submac!($($args)*), $submac2!($($args2)*));
+  );
+  ($i:expr, $f:expr, $g:expr) => (
+    map_res_impl!($i, call!($f), call!($g));
+  );
+  ($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
+    map_res_impl!($i, call!($f), $submac!($($args)*));
+  );
+);
+
+/// Internal parser, do not use directly
+#[doc(hidden)]
+#[macro_export]
+macro_rules! map_res_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)                          => match $submac2!(o, $($args2)*) {
+          Ok(output) => $crate::IResult::Done(i, output),
+          Err(_)     => $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::MapRes, $i))
+        }
+      }
+    }
+  );
+);
+
+
+/// `map_opt!(I -> IResult<I,O>, O -> Option<P>) => I -> IResult<I, P>`
+/// maps a function returning an Option on the output of a parser
+#[macro_export]
+macro_rules! map_opt (
+  ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
+    map_opt_impl!($i, $submac!($($args)*), call!($g));
+  );
+  ($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
+    map_opt_impl!($i, $submac!($($args)*), $submac2!($($args2)*));
+  );
+  ($i:expr, $f:expr, $g:expr) => (
+    map_opt_impl!($i, call!($f), call!($g));
+  );
+  ($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
+    map_opt_impl!($i, call!($f), $submac!($($args)*));
+  );
+);
+
+/// Internal parser, do not use directly
+#[doc(hidden)]
+#[macro_export]
+macro_rules! map_opt_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)                          => match $submac2!(o, $($args2)*) {
+          ::std::option::Option::Some(output) => $crate::IResult::Done(i, output),
+          ::std::option::Option::None         => $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::MapOpt, $i))
+        }
+      }
+    }
+  );
+);
+
+/// `value!(T, R -> IResult<R, S> ) => R -> IResult<R, T>`
+///
+/// or `value!(T) => R -> IResult<R, T>`
+///
+/// If the child parser was successful, return the value.
+/// If no child parser is provided, always return the value
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::Done;
+/// # fn main() {
+///  named!(x<u8>, value!(42, delimited!(tag!("<!--"), take!(5), tag!("-->"))));
+///  named!(y<u8>, delimited!(tag!("<!--"), value!(42), tag!("-->")));
+///  let r = x(&b"<!-- abc --> aaa"[..]);
+///  assert_eq!(r, Done(&b" aaa"[..], 42));
+///
+///  let r2 = y(&b"<!----> aaa"[..]);
+///  assert_eq!(r2, Done(&b" aaa"[..], 42));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! value (
+  ($i:expr, $res:expr, $submac:ident!( $($args:tt)* )) => (
+    {
+      match $submac!($i, $($args)*) {
+        $crate::IResult::Done(i,_)     => {
+          $crate::IResult::Done(i, $res)
+        },
+        $crate::IResult::Error(e)      => $crate::IResult::Error(e),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i)
+      }
+    }
+  );
+  ($i:expr, $res:expr, $f:expr) => (
+    value!($i, $res, call!($f))
+  );
+  ($i:expr, $res:expr) => (
+    $crate::IResult::Done($i, $res)
+  );
+);
+
+/// `expr_res!(Result<E,O>) => I -> IResult<I, O>`
+/// evaluate an expression that returns a Result<T,E> and returns a IResult::Done(I,T) if Ok
+///
+/// See expr_opt for an example
+#[macro_export]
+macro_rules! expr_res (
+  ($i:expr, $e:expr) => (
+    {
+      match $e {
+        Ok(output) => $crate::IResult::Done($i, output),
+        Err(_)     => $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::ExprRes, $i))
+      }
+    }
+  );
+);
+
+/// `expr_opt!(Option<O>) => I -> IResult<I, O>`
+/// evaluate an expression that returns a Option<T> and returns a IResult::Done(I,T) if Some
+///
+/// Useful when doing computations in a chain
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::{self, Done, Error};
+/// # use nom::Err::Position;
+/// # use nom::{be_u8,ErrorKind};
+///
+///  fn take_add(input:&[u8], size: u8) -> IResult<&[u8],&[u8]> {
+///    chain!(input,
+///      sz:     be_u8                             ~
+///      length: expr_opt!(size.checked_add(sz))   ~ // checking for integer overflow (returns an Option)
+///      data:   take!(length)                     ,
+///      ||{ data }
+///    )
+///  }
+/// # fn main() {
+/// let arr1 = [1, 2, 3, 4, 5];
+/// let r1 = take_add(&arr1[..], 1);
+/// assert_eq!(r1, Done(&[4,5][..], &[2,3][..]));
+///
+/// let arr2 = [0xFE, 2, 3, 4, 5];
+/// // size is overflowing
+/// let r1 = take_add(&arr2[..], 42);
+/// assert_eq!(r1, Error(Position(ErrorKind::ExprOpt,&[2,3,4,5][..])));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! expr_opt (
+  ($i:expr, $e:expr) => (
+    {
+      match $e {
+        ::std::option::Option::Some(output) => $crate::IResult::Done($i, output),
+        ::std::option::Option::None         => $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::ExprOpt, $i))
+      }
+    }
+  );
+);
+
+/// `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
+///
+/// The input type `I` must implement `nom::InputLength`.
+///
+/// This combinator will count how much data is consumed by every child parser and take it into account if
+/// there is not enough data
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::{self, Done, Error};
+/// # use nom::Err::Position;
+/// # use nom::ErrorKind;
+/// #[derive(PartialEq,Eq,Debug)]
+/// struct B {
+///   a: u8,
+///   b: Option<u8>
+/// }
+///
+/// named!(y, tag!("efgh"));
+///
+/// fn ret_int(i:&[u8]) -> IResult<&[u8], u8> { Done(i, 1) }
+/// named!(ret_y<&[u8], u8>, map!(y, |_| 1)); // return 1 if the "efgh" tag is found
+///
+///  named!(z<&[u8], B>,
+///    chain!(
+///      tag!("abcd")  ~     // the '~' character is used as separator
+///      aa: ret_int   ~     // the result of that parser will be used in the closure
+///      tag!("abcd")? ~     // this parser is optional
+///      bb: ret_y?    ,     // the result of that parser is an option
+///                          // the last parser in the chain is followed by a ','
+///      ||{B{a: aa, b: bb}}
+///    )
+///  );
+///
+/// # fn main() {
+/// // the first "abcd" tag is not present, we have an error
+/// let r1 = z(&b"efgh"[..]);
+/// assert_eq!(r1, Error(Position(ErrorKind::Tag,&b"efgh"[..])));
+///
+/// // everything is present, everything is parsed
+/// let r2 = z(&b"abcdabcdefgh"[..]);
+/// assert_eq!(r2, Done(&b""[..], B{a: 1, b: Some(1)}));
+///
+/// // the second "abcd" tag is optional
+/// let r3 = z(&b"abcdefgh"[..]);
+/// assert_eq!(r3, Done(&b""[..], B{a: 1, b: Some(1)}));
+///
+/// // the result of ret_y is optional, as seen in the B structure
+/// let r4 = z(&b"abcdabcdwxyz"[..]);
+/// assert_eq!(r4, Done(&b"wxyz"[..], B{a: 1, b: None}));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! chain (
+  ($i:expr, $($rest:tt)*) => (
+    {
+      chaining_parser!($i, 0usize, $($rest)*)
+    }
+  );
+);
+
+/// Internal parser, do not use directly
+#[doc(hidden)]
+#[macro_export]
+macro_rules! chaining_parser (
+  ($i:expr, $consumed:expr, $e:ident ~ $($rest:tt)*) => (
+    chaining_parser!($i, $consumed, call!($e) ~ $($rest)*);
+  );
+  ($i:expr, $consumed:expr, $submac:ident!( $($args:tt)* ) ~ $($rest: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($consumed + i)),
+        $crate::IResult::Done(i,_)     => {
+          chaining_parser!(i, $consumed + ($crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&i)), $($rest)*)
+        }
+      }
+    }
+);
+
+  ($i:expr, $consumed:expr, $e:ident ? ~ $($rest:tt)*) => (
+    chaining_parser!($i, $consumed, call!($e) ? ~ $($rest)*);
+  );
+
+  ($i:expr, $consumed:expr, $submac:ident!( $($args:tt)* ) ? ~ $($rest:tt)*) => (
+    {
+      let res = $submac!($i, $($args)*);
+      if let $crate::IResult::Incomplete(inc) = res {
+        match inc {
+          $crate::Needed::Unknown => $crate::IResult::Incomplete($crate::Needed::Unknown),
+          $crate::Needed::Size(i) => $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+        }
+      } else {
+        let input = if let $crate::IResult::Done(i,_) = res {
+          i
+        } else {
+          $i
+        };
+        chaining_parser!(input, $consumed + ($crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&input)), $($rest)*)
+      }
+    }
+  );
+
+  ($i:expr, $consumed:expr, $field:ident : $e:ident ~ $($rest:tt)*) => (
+    chaining_parser!($i, $consumed, $field: call!($e) ~ $($rest)*);
+  );
+
+  ($i:expr, $consumed:expr, $field:ident : $submac:ident!( $($args:tt)* ) ~ $($rest: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($consumed + i)),
+        $crate::IResult::Done(i,o)     => {
+          let $field = o;
+          chaining_parser!(i, $consumed + ($crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&i)), $($rest)*)
+        }
+      }
+    }
+  );
+
+  ($i:expr, $consumed:expr, mut $field:ident : $e:ident ~ $($rest:tt)*) => (
+    chaining_parser!($i, $consumed, mut $field: call!($e) ~ $($rest)*);
+  );
+
+  ($i:expr, $consumed:expr, mut $field:ident : $submac:ident!( $($args:tt)* ) ~ $($rest: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($consumed + i)),
+        $crate::IResult::Done(i,o)     => {
+          let mut $field = o;
+          chaining_parser!(i, $consumed + $crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&i), $($rest)*)
+        }
+      }
+    }
+  );
+
+  ($i:expr, $consumed:expr, $field:ident : $e:ident ? ~ $($rest:tt)*) => (
+    chaining_parser!($i, $consumed, $field : call!($e) ? ~ $($rest)*);
+  );
+
+  ($i:expr, $consumed:expr, $field:ident : $submac:ident!( $($args:tt)* ) ? ~ $($rest:tt)*) => (
+    {
+      let res = $submac!($i, $($args)*);
+      if let $crate::IResult::Incomplete(inc) = res {
+        match inc {
+          $crate::Needed::Unknown => $crate::IResult::Incomplete($crate::Needed::Unknown),
+          $crate::Needed::Size(i) => $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+        }
+      } else {
+        let ($field,input) = if let $crate::IResult::Done(i,o) = res {
+          (::std::option::Option::Some(o),i)
+        } else {
+          (::std::option::Option::None,$i)
+        };
+        chaining_parser!(input, $consumed + $crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&input), $($rest)*)
+      }
+    }
+  );
+
+  ($i:expr, $consumed:expr, mut $field:ident : $e:ident ? ~ $($rest:tt)*) => (
+    chaining_parser!($i, $consumed, mut $field : call!($e) ? ~ $($rest)*);
+  );
+
+  ($i:expr, $consumed:expr, mut $field:ident : $submac:ident!( $($args:tt)* ) ? ~ $($rest:tt)*) => (
+    {
+      let res = $submac!($i, $($args)*);
+      if let $crate::IResult::Incomplete(inc) = res {
+        match inc {
+          $crate::Needed::Unknown => $crate::IResult::Incomplete($crate::Needed::Unknown),
+          $crate::Needed::Size(i) => $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+        }
+      } else {
+        let (mut $field,input) = if let $crate::IResult::Done(i,o) = res {
+          (::std::option::Option::Some(o),i)
+        } else {
+          (::std::option::Option::None,$i)
+        };
+        chaining_parser!(input, $consumed + $crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&input), $($rest)*)
+      }
+    }
+  );
+
+  // ending the chain
+  ($i:expr, $consumed:expr, $e:ident, $assemble:expr) => (
+    chaining_parser!($i, $consumed, call!($e), $assemble);
+  );
+
+  ($i:expr, $consumed:expr, $submac:ident!( $($args:tt)* ), $assemble:expr) => (
+    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($consumed + i)),
+      $crate::IResult::Done(i,_)     => {
+        $crate::IResult::Done(i, $assemble())
+      }
+    }
+  );
+
+  ($i:expr, $consumed:expr, $e:ident ?, $assemble:expr) => (
+    chaining_parser!($i, $consumed, call!($e) ?, $assemble);
+  );
+
+  ($i:expr, $consumed:expr, $submac:ident!( $($args:tt)* ) ?, $assemble:expr) => ({
+    let res = $submac!($i, $($args)*);
+    if let $crate::IResult::Incomplete(inc) = res {
+      match inc {
+        $crate::Needed::Unknown => $crate::IResult::Incomplete($crate::Needed::Unknown),
+        $crate::Needed::Size(i) => $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+      }
+    } else {
+      let input = if let $crate::IResult::Done(i,_) = res {
+        i
+      } else {
+        $i
+      };
+      $crate::IResult::Done(input, $assemble())
+    }
+  });
+
+  ($i:expr, $consumed:expr, $field:ident : $e:ident, $assemble:expr) => (
+    chaining_parser!($i, $consumed, $field: call!($e), $assemble);
+  );
+
+  ($i:expr, $consumed:expr, $field:ident : $submac:ident!( $($args:tt)* ), $assemble:expr) => (
+    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($consumed + i)),
+      $crate::IResult::Done(i,o)     => {
+        let $field = o;
+        $crate::IResult::Done(i, $assemble())
+      }
+    }
+  );
+
+  ($i:expr, $consumed:expr, mut $field:ident : $e:ident, $assemble:expr) => (
+    chaining_parser!($i, $consumed, mut $field: call!($e), $assemble);
+  );
+
+  ($i:expr, $consumed:expr, mut $field:ident : $submac:ident!( $($args:tt)* ), $assemble:expr) => (
+    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($consumed + i)),
+      $crate::IResult::Done(i,o)     => {
+        let mut $field = o;
+        $crate::IResult::Done(i, $assemble())
+      }
+    }
+  );
+
+  ($i:expr, $consumed:expr, $field:ident : $e:ident ? , $assemble:expr) => (
+    chaining_parser!($i, $consumed, $field : call!($e) ? , $assemble);
+  );
+
+  ($i:expr, $consumed:expr, $field:ident : $submac:ident!( $($args:tt)* ) ? , $assemble:expr) => ({
+    let res = $submac!($i, $($args)*);
+    if let $crate::IResult::Incomplete(inc) = res {
+      match inc {
+        $crate::Needed::Unknown => $crate::IResult::Incomplete($crate::Needed::Unknown),
+        $crate::Needed::Size(i) => $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+      }
+    } else {
+      let ($field,input) = if let $crate::IResult::Done(i,o) = res {
+        (::std::option::Option::Some(o), i)
+      } else {
+        (::std::option::Option::None, $i)
+      };
+      $crate::IResult::Done(input, $assemble())
+    }
+  });
+
+  ($i:expr, $consumed:expr, mut $field:ident : $e:ident ? , $assemble:expr) => (
+    chaining_parser!($i, $consumed, $field : call!($e) ? , $assemble);
+  );
+
+  ($i:expr, $consumed:expr, mut $field:ident : $submac:ident!( $($args:tt)* ) ? , $assemble:expr) => ({
+    let res = $submac!($i, $($args)*);
+    if let $crate::IResult::Incomplete(inc) = res {
+      match inc {
+        $crate::Needed::Unknown => $crate::IResult::Incomplete($crate::Needed::Unknown),
+        $crate::Needed::Size(i) => $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+      }
+    } else {
+      let (mut $field,input) = if let $crate::IResult::Done(i,o) = res {
+        (::std::option::Option::Some(o), i)
+      } else {
+        (::std::option::Option::None, $i)
+      };
+      $crate::IResult::Done(input, $assemble())
+    }
+  });
+
+  ($i:expr, $consumed:expr, $assemble:expr) => (
+    $crate::IResult::Done($i, $assemble())
+  )
+);
+
+
+/// `tuple!(I->IResult<I,A>, I->IResult<I,B>, ... I->IResult<I,X>) => I -> IResult<I, (A, B, ..., X)>`
+/// chains parsers and assemble the sub results in a tuple.
+///
+/// The input type `I` must implement `nom::InputLength`.
+///
+/// This combinator will count how much data is consumed by every child parser and take it into account if
+/// there is not enough data
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::{self, Done, Error};
+/// # use nom::Err::Position;
+/// # use nom::ErrorKind;
+/// # use nom::be_u16;
+/// // the return type depends of the children parsers
+/// named!(parser<&[u8], (u16, &[u8], &[u8]) >,
+///   tuple!(
+///     be_u16 ,
+///     take!(3),
+///     tag!("fg")
+///   )
+/// );
+///
+/// # fn main() {
+/// assert_eq!(
+///   parser(&b"abcdefgh"[..]),
+///   Done(
+///     &b"h"[..],
+///     (0x6162u16, &b"cde"[..], &b"fg"[..])
+///   )
+/// );
+/// # }
+/// ```
+#[macro_export]
+macro_rules! tuple (
+  ($i:expr, $($rest:tt)*) => (
+    {
+      tuple_parser!($i, 0usize, (), $($rest)*)
+    }
+  );
+);
+
+/// Internal parser, do not use directly
+#[doc(hidden)]
+#[macro_export]
+macro_rules! tuple_parser (
+  ($i:expr, $consumed:expr, ($($parsed:tt),*), $e:ident, $($rest:tt)*) => (
+    tuple_parser!($i, $consumed, ($($parsed),*), call!($e), $($rest)*);
+  );
+  ($i:expr, $consumed:expr, (), $submac:ident!( $($args:tt)* ), $($rest: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($consumed + i)),
+        $crate::IResult::Done(i,o)     => {
+          tuple_parser!(i, $consumed + ($crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&i)), (o), $($rest)*)
+        }
+      }
+    }
+  );
+  ($i:expr, $consumed:expr, ($($parsed:tt)*), $submac:ident!( $($args:tt)* ), $($rest: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($consumed + i)),
+        $crate::IResult::Done(i,o)     => {
+          tuple_parser!(i, $consumed + ($crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&i)), ($($parsed)* , o), $($rest)*)
+        }
+      }
+    }
+  );
+  ($i:expr, $consumed:expr, ($($parsed:tt),*), $e:ident) => (
+    tuple_parser!($i, $consumed, ($($parsed),*), call!($e));
+  );
+  ($i:expr, $consumed:expr, (), $submac:ident!( $($args: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($consumed + i)),
+        $crate::IResult::Done(i,o)     => {
+          $crate::IResult::Done(i, (o))
+        }
+      }
+    }
+  );
+  ($i:expr, $consumed:expr, ($($parsed:expr),*), $submac:ident!( $($args: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($consumed + i)),
+        $crate::IResult::Done(i,o)     => {
+          $crate::IResult::Done(i, ($($parsed),* , o))
+        }
+      }
+    }
+  );
+  ($i:expr, $consumed:expr, ($($parsed:expr),*)) => (
+    {
+      $crate::IResult::Done($i, ($($parsed),*))
+    }
+  );
+);
+/// `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
+///
+/// If one of the parser 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.
+///
+/// ```
+/// # #[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"[..]));
+///  # }
+/// ```
+///
+/// There is another syntax for alt allowing a block to manipulate the result:
+///
+/// ```
+/// # #[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)));
+/// # }
+/// ```
+///
+/// **BE CAREFUL** there is a case where the behaviour of `alt!` can be confusing:
+///
+/// when the alternatives have different lengths, like this case:
+///
+/// ```ignore
+///  named!( test, alt!( tag!( "abcd" ) | tag!( "ef" ) | tag!( "ghi" ) | tag!( "kl" ) ) );
+/// ```
+///
+/// With this parser, if you pass `"abcd"` as input, the first alternative parses it correctly,
+/// but if you pass `"efg"`, the first alternative will return `Incomplete`, since it needs an input
+/// of 4 bytes. This behaviour of `alt!` is expected: if you get a partial input that isn't matched
+/// by the first alternative, but would match if the input was complete, you want `alt!` to indicate
+/// that it cannot decide with limited information.
+///
+/// There are two ways to fix this behaviour. The first one consists in ordering the alternatives
+/// by size, like this:
+///
+/// ```ignore
+///  named!( test, alt!( tag!( "ef" ) | tag!( "kl") | tag!( "ghi" ) | tag!( "abcd" ) ) );
+/// ```
+///
+/// With this solution, the largest alternative will be tested last.
+///
+/// The other solution uses the `complete!` combinator, which transforms an `Incomplete` in an
+/// `Error`. If one of the alternatives returns `Incomplete` but is wrapped by `complete!`,
+/// `alt!` will try the next alternative. This is useful when you know that
+/// you will not get partial input:
+///
+/// ```ignore
+///  named!( test,
+///    alt!(
+///      complete!( tag!( "abcd" ) ) |
+///      complete!( tag!( "ef"   ) ) |
+///      complete!( tag!( "ghi"  ) ) |
+///      complete!( tag!( "kl"   ) )
+///    )
+///  );
+/// ```
+///
+/// If you want the `complete!` combinator to be applied to all rules then use the convenience
+/// `alt_complete!` macro (see below).
+///
+/// This behaviour of `alt!` can get especially confusing if multiple alternatives have different
+/// sizes but a common prefix, like this:
+///
+/// ```ignore
+///  named!( test, alt!( tag!( "abcd" ) | tag!( "ab" ) | tag!( "ef" ) ) );
+/// ```
+///
+/// in that case, if you order by size, passing `"abcd"` as input will always be matched by the
+/// smallest parser, so the solution using `complete!` is better suited.
+///
+/// You can also nest multiple `alt!`, like this:
+///
+/// ```ignore
+///  named!( test,
+///    alt!(
+///      preceded!(
+///        tag!("ab"),
+///        alt!(
+///          tag!( "cd" ) |
+///          eof
+///        )
+///      )
+///    | tag!( "ef" )
+///    )
+///  );
+/// ```
+///
+///  `preceded!` will first parse `"ab"` then, if successful, try the alternatives "cd",
+///  or empty input (End Of File). If none of them work, `preceded!` will fail and
+///  "ef" will be tested.
+///
+#[macro_export]
+macro_rules! alt (
+  ($i:expr, $($rest:tt)*) => (
+    {
+      alt_parser!($i, $($rest)*)
+    }
+  );
+);
+
+/// Internal parser, do not use directly
+#[doc(hidden)]
+#[macro_export]
+macro_rules! alt_parser (
+  ($i:expr, $e:ident | $($rest:tt)*) => (
+    alt_parser!($i, call!($e) | $($rest)*);
+  );
+
+  ($i:expr, $subrule:ident!( $($args:tt)*) | $($rest:tt)*) => (
+    {
+      let res = $subrule!($i, $($args)*);
+      match res {
+        $crate::IResult::Done(_,_)     => res,
+        $crate::IResult::Incomplete(_) => res,
+        _                              => alt_parser!($i, $($rest)*)
+      }
+    }
+  );
+
+  ($i:expr, $subrule:ident!( $($args:tt)* ) => { $gen:expr } | $($rest:tt)+) => (
+    {
+      match $subrule!( $i, $($args)* ) {
+        $crate::IResult::Done(i,o)     => $crate::IResult::Done(i,$gen(o)),
+        $crate::IResult::Incomplete(x) => $crate::IResult::Incomplete(x),
+        $crate::IResult::Error(_)      => {
+          alt_parser!($i, $($rest)*)
+        }
+      }
+    }
+  );
+
+  ($i:expr, $e:ident => { $gen:expr } | $($rest:tt)*) => (
+    alt_parser!($i, call!($e) => { $gen } | $($rest)*);
+  );
+
+  ($i:expr, $e:ident => { $gen:expr }) => (
+    alt_parser!($i, call!($e) => { $gen });
+  );
+
+  ($i:expr, $subrule:ident!( $($args:tt)* ) => { $gen:expr }) => (
+    {
+      match $subrule!( $i, $($args)* ) {
+        $crate::IResult::Done(i,o)     => $crate::IResult::Done(i,$gen(o)),
+        $crate::IResult::Incomplete(x) => $crate::IResult::Incomplete(x),
+        $crate::IResult::Error(_)      => {
+          alt_parser!($i)
+        }
+      }
+    }
+  );
+
+  ($i:expr, $e:ident) => (
+    alt_parser!($i, call!($e));
+  );
+
+  ($i:expr, $subrule:ident!( $($args:tt)*)) => (
+    {
+      match $subrule!( $i, $($args)* ) {
+        $crate::IResult::Done(i,o)     => $crate::IResult::Done(i,o),
+        $crate::IResult::Incomplete(x) => $crate::IResult::Incomplete(x),
+        $crate::IResult::Error(_)      => {
+          alt_parser!($i)
+        }
+      }
+    }
+  );
+
+  ($i:expr) => (
+    $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::Alt,$i))
+  );
+);
+
+/// 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
+/// will not receive partial input for the rules you're trying to match (this
+/// is almost always the case for parsing programming languages).
+#[macro_export]
+macro_rules! alt_complete (
+  // Recursive rules (must include `complete!` around the head)
+
+  ($i:expr, $e:ident | $($rest:tt)*) => (
+    alt_complete!($i, complete!(call!($e)) | $($rest)*);
+  );
+
+  ($i:expr, $subrule:ident!( $($args:tt)*) | $($rest:tt)*) => (
+    {
+      let res = complete!($i, $subrule!($($args)*));
+      match res {
+        $crate::IResult::Done(_,_) => res,
+        _ => alt_complete!($i, $($rest)*),
+      }
+    }
+  );
+
+  ($i:expr, $subrule:ident!( $($args:tt)* ) => { $gen:expr } | $($rest:tt)+) => (
+    {
+      match complete!($i, $subrule!($($args)*)) {
+        $crate::IResult::Done(i,o) => $crate::IResult::Done(i,$gen(o)),
+        _ => alt_complete!($i, $($rest)*),
+      }
+    }
+  );
+
+  ($i:expr, $e:ident => { $gen:expr } | $($rest:tt)*) => (
+    alt_complete!($i, complete!(call!($e)) => { $gen } | $($rest)*);
+  );
+
+  // Tail (non-recursive) rules
+
+  ($i:expr, $e:ident => { $gen:expr }) => (
+    alt_complete!($i, call!($e) => { $gen });
+  );
+
+  ($i:expr, $subrule:ident!( $($args:tt)* ) => { $gen:expr }) => (
+    alt_parser!($i, $subrule!($($args)*) => { $gen })
+  );
+
+  ($i:expr, $e:ident) => (
+    alt_complete!($i, call!($e));
+  );
+
+  ($i:expr, $subrule:ident!( $($args:tt)*)) => (
+    alt_parser!($i, $subrule!($($args)*))
+  );
+);
+
+/// `switch!(I -> IResult<I,P>, P => I -> IResult<I,O> | ... | P => I -> IResult<I,O> ) => I -> IResult<I, O>`
+/// choose the next parser depending on the result of the first one, if successful,
+/// and returns the result of the second parser
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::{Done,Error};
+/// # use nom::Err::{Position, NodePosition};
+/// # use nom::ErrorKind;
+/// # fn main() {
+///  named!(sw,
+///    switch!(take!(4),
+///      b"abcd" => tag!("XYZ") |
+///      b"efgh" => tag!("123")
+///    )
+///  );
+///
+///  let a = b"abcdXYZ123";
+///  let b = b"abcdef";
+///  let c = b"efgh123";
+///  let d = b"blah";
+///
+///  assert_eq!(sw(&a[..]), Done(&b"123"[..], &b"XYZ"[..]));
+///  assert_eq!(sw(&b[..]), Error(NodePosition(ErrorKind::Switch, &b"abcdef"[..], Box::new(Position(ErrorKind::Tag, &b"ef"[..])))));
+///  assert_eq!(sw(&c[..]), Done(&b""[..], &b"123"[..]));
+///  assert_eq!(sw(&d[..]), Error(Position(ErrorKind::Switch, &b"blah"[..])));
+///  # }
+/// ```
+///
+/// Due to limitations in Rust macros, it is not possible to have simple functions on the right hand
+/// side of pattern, like this:
+///
+/// ```ignore
+///  named!(sw,
+///    switch!(take!(4),
+///      b"abcd" => tag!("XYZ") |
+///      b"efgh" => tag!("123")
+///    )
+///  );
+/// ```
+///
+/// If you want to pass your own functions instead, you can use the `call!` combinator as follows:
+///
+/// ```ignore
+///  named!(xyz, tag!("XYZ"));
+///  named!(num, tag!("123"));
+///  named!(sw,
+///    switch!(take!(4),
+///      b"abcd" => call!(xyz) |
+///      b"efgh" => call!(num)
+///    )
+///  );
+/// ```
+///
+#[macro_export]
+macro_rules! switch (
+  ($i:expr, $submac:ident!( $($args:tt)*), $($rest:tt)*) => (
+    {
+      switch_impl!($i, $submac!($($args)*), $($rest)*)
+    }
+  );
+  ($i:expr, $e:ident, $($rest:tt)*) => (
+    {
+      switch_impl!($i, call!($e), $($rest)*)
+    }
+  );
+);
+
+/// Internal parser, do not use directly
+#[doc(hidden)]
+#[macro_export]
+macro_rules! switch_impl (
+  ($i:expr, $submac:ident!( $($args:tt)* ), $($p:pat => $subrule:ident!( $($args2:tt)* ))|* ) => (
+    {
+      match $submac!($i, $($args)*) {
+        $crate::IResult::Error(e)      => $crate::IResult::Error($crate::Err::NodePosition(
+            $crate::ErrorKind::Switch, $i, ::std::boxed::Box::new(e)
+        )),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
+        $crate::IResult::Done(i, o)    => {
+          match o {
+            $($p => match $subrule!(i, $($args2)*) {
+              $crate::IResult::Error(e) => $crate::IResult::Error($crate::Err::NodePosition(
+                  $crate::ErrorKind::Switch, $i, ::std::boxed::Box::new(e)
+              )),
+              a => a,
+            }),*,
+            _    => $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::Switch,$i))
+          }
+        }
+      }
+    }
+  );
+);
+/// `opt!(I -> IResult<I,O>) => I -> IResult<I, Option<O>>`
+/// make the underlying parser optional
+///
+/// returns an Option of the returned type. This parser returns `Some(result)` if the child parser
+/// succeeds,`None` if it fails, and `Incomplete` if it did not have enough data to decide
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::Done;
+/// # fn main() {
+///  named!( o<&[u8], Option<&[u8]> >, opt!( tag!( "abcd" ) ) );
+///
+///  let a = b"abcdef";
+///  let b = b"bcdefg";
+///  assert_eq!(o(&a[..]), Done(&b"ef"[..], Some(&b"abcd"[..])));
+///  assert_eq!(o(&b[..]), Done(&b"bcdefg"[..], None));
+///  # }
+/// ```
+#[macro_export]
+macro_rules! opt(
+  ($i:expr, $submac:ident!( $($args:tt)* )) => (
+    {
+      match $submac!($i, $($args)*) {
+        $crate::IResult::Done(i,o)     => $crate::IResult::Done(i, ::std::option::Option::Some(o)),
+        $crate::IResult::Error(_)      => $crate::IResult::Done($i, ::std::option::Option::None),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i)
+      }
+    }
+  );
+  ($i:expr, $f:expr) => (
+    opt!($i, call!($f));
+  );
+);
+
+/// `opt_res!(I -> IResult<I,O>) => I -> IResult<I, Result<nom::Err,O>>`
+/// make the underlying parser optional
+///
+/// returns a Result, with Err containing the parsing error
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::Done;
+/// # use nom::Err::Position;
+/// # use nom::ErrorKind;
+/// # fn main() {
+///  named!( o<&[u8], Result<&[u8], nom::Err<&[u8]> > >, opt_res!( tag!( "abcd" ) ) );
+///
+///  let a = b"abcdef";
+///  let b = b"bcdefg";
+///  assert_eq!(o(&a[..]), Done(&b"ef"[..], Ok(&b"abcd"[..])));
+///  assert_eq!(o(&b[..]), Done(&b"bcdefg"[..], Err(Position(ErrorKind::Tag, &b[..]))));
+///  # }
+/// ```
+#[macro_export]
+macro_rules! opt_res (
+  ($i:expr, $submac:ident!( $($args:tt)* )) => (
+    {
+      match $submac!($i, $($args)*) {
+        $crate::IResult::Done(i,o)     => $crate::IResult::Done(i,  Ok(o)),
+        $crate::IResult::Error(e)      => $crate::IResult::Done($i, Err(e)),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i)
+      }
+    }
+  );
+  ($i:expr, $f:expr) => (
+    opt_res!($i, call!($f));
+  );
+);
+
+/// `cond_with_error!(bool, I -> IResult<I,O>) => I -> IResult<I, Option<O>>`
+/// Conditional combinator
+///
+/// Wraps another parser and calls it if the
+/// condition is met. This combinator returns
+/// an Option of the return type of the child
+/// parser.
+///
+/// This is especially useful if a parser depends
+/// on the value return by a preceding parser in
+/// a `chain!`.
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::Done;
+/// # use nom::IResult;
+/// # fn main() {
+///  let b = true;
+///  let f: Box<Fn(&'static [u8]) -> IResult<&[u8],Option<&[u8]>>> = Box::new(closure!(&'static[u8],
+///    cond!( b, tag!("abcd") ))
+///  );
+///
+///  let a = b"abcdef";
+///  assert_eq!(f(&a[..]), Done(&b"ef"[..], Some(&b"abcd"[..])));
+///
+///  let b2 = false;
+///  let f2:Box<Fn(&'static [u8]) -> IResult<&[u8],Option<&[u8]>>> = Box::new(closure!(&'static[u8],
+///    cond!( b2, tag!("abcd") ))
+///  );
+///  assert_eq!(f2(&a[..]), Done(&b"abcdef"[..], None));
+///  # }
+/// ```
+///
+#[macro_export]
+macro_rules! cond_with_error(
+  ($i:expr, $cond:expr, $submac:ident!( $($args:tt)* )) => (
+    {
+      if $cond {
+        match $submac!($i, $($args)*) {
+          $crate::IResult::Done(i,o)     => $crate::IResult::Done(i, ::std::option::Option::Some(o)),
+          $crate::IResult::Error(e)      => $crate::IResult::Error(e),
+          $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i)
+        }
+      } else {
+        $crate::IResult::Done($i, ::std::option::Option::None)
+      }
+    }
+  );
+  ($i:expr, $cond:expr, $f:expr) => (
+    cond!($i, $cond, call!($f));
+  );
+);
+
+/// `cond!(bool, I -> IResult<I,O>) => I -> IResult<I, Option<O>>`
+/// Conditional combinator
+///
+/// Wraps another parser and calls it if the
+/// condition is met. This combinator returns
+/// an Option of the return type of the child
+/// parser.
+///
+/// This is especially useful if a parser depends
+/// on the value return by a preceding parser in
+/// a `chain!`.
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::Done;
+/// # use nom::IResult;
+/// # fn main() {
+///  let b = true;
+///  let f: Box<Fn(&'static [u8]) -> IResult<&[u8],Option<&[u8]>>> = Box::new(closure!(&'static[u8],
+///    cond!( b, tag!("abcd") ))
+///  );
+///
+///  let a = b"abcdef";
+///  assert_eq!(f(&a[..]), Done(&b"ef"[..], Some(&b"abcd"[..])));
+///
+///  let b2 = false;
+///  let f2:Box<Fn(&'static [u8]) -> IResult<&[u8],Option<&[u8]>>> = Box::new(closure!(&'static[u8],
+///    cond!( b2, tag!("abcd") ))
+///  );
+///  assert_eq!(f2(&a[..]), Done(&b"abcdef"[..], None));
+///  # }
+/// ```
+///
+#[macro_export]
+macro_rules! cond(
+  ($i:expr, $cond:expr, $submac:ident!( $($args:tt)* )) => (
+    {
+      if $cond {
+        match $submac!($i, $($args)*) {
+          $crate::IResult::Done(i,o)     => $crate::IResult::Done(i, ::std::option::Option::Some(o)),
+          $crate::IResult::Error(_)      => $crate::IResult::Done($i, ::std::option::Option::None),
+          $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i)
+        }
+      } else {
+        $crate::IResult::Done($i, ::std::option::Option::None)
+      }
+    }
+  );
+  ($i:expr, $cond:expr, $f:expr) => (
+    cond!($i, $cond, call!($f));
+  );
+);
+
+/// `cond_reduce!(bool, I -> IResult<I,O>) => I -> IResult<I, O>`
+/// Conditional combinator with error
+///
+/// Wraps another parser and calls it if the
+/// condition is met. This combinator returns
+/// an error if the condition is false
+///
+/// This is especially useful if a parser depends
+/// on the value return by a preceding parser in
+/// a `chain!`.
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::{Done,Error};
+/// # use nom::{Err,ErrorKind};
+/// # fn main() {
+///  let b = true;
+///  let f = closure!(&'static[u8],
+///    cond_reduce!( b, tag!("abcd") )
+///  );
+///
+///  let a = b"abcdef";
+///  assert_eq!(f(&a[..]), Done(&b"ef"[..], &b"abcd"[..]));
+///
+///  let b2 = false;
+///  let f2 = closure!(&'static[u8],
+///    cond_reduce!( b2, tag!("abcd") )
+///  );
+///  assert_eq!(f2(&a[..]), Error(Err::Position(ErrorKind::CondReduce, &a[..])));
+///  # }
+/// ```
+///
+#[macro_export]
+macro_rules! cond_reduce(
+  ($i:expr, $cond:expr, $submac:ident!( $($args:tt)* )) => (
+    {
+      if $cond {
+        match $submac!($i, $($args)*) {
+          $crate::IResult::Done(i,o)     => $crate::IResult::Done(i, o),
+          $crate::IResult::Error(e)      => $crate::IResult::Error(e),
+          $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i)
+        }
+      } else {
+        $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::CondReduce, $i))
+      }
+    }
+  );
+  ($i:expr, $cond:expr, $f:expr) => (
+    cond_reduce!($i, $cond, call!($f));
+  );
+);
+
+/// `peek!(I -> IResult<I,O>) => I -> IResult<I, O>`
+/// returns a result without consuming the input
+///
+/// the embedded parser may return Incomplete
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::Done;
+/// # fn main() {
+///  named!(ptag, peek!( tag!( "abcd" ) ) );
+///
+///  let r = ptag(&b"abcdefgh"[..]);
+///  assert_eq!(r, Done(&b"abcdefgh"[..], &b"abcd"[..]));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! peek(
+  ($i:expr, $submac:ident!( $($args:tt)* )) => (
+    {
+      match $submac!($i, $($args)*) {
+        $crate::IResult::Done(_,o)     => $crate::IResult::Done($i, o),
+        $crate::IResult::Error(a)      => $crate::IResult::Error(a),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i)
+      }
+    }
+  );
+  ($i:expr, $f:expr) => (
+    peek!($i, call!($f));
+  );
+);
+
+/// `not!(I -> IResult<I,0>) => I -> IResult<I, O>`
+/// returns a result only if the embedded parser returns Error or Incomplete
+/// does not consume the input
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::{Done, Error};
+/// # use nom::Err::{Position};
+/// # use nom::ErrorKind;
+/// # fn main() {
+/// named!(not_e, chain!(
+///     res: tag!("abc") ~ 
+///          not!(char!('e')),
+///     || { res }));
+///
+/// let r = not_e(&b"abcd"[..]); 
+/// assert_eq!(r, Done(&b"d"[..], &b"abc"[..]));
+///
+/// let r2 = not_e(&b"abce"[..]);
+/// assert_eq!(r2, Error(Position(ErrorKind::Not, &b"e"[..])));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! not(
+  ($i:expr, $submac:ident!( $($args:tt)* )) => (
+    {
+      match $submac!($i, $($args)*) {
+        $crate::IResult::Done(_, _)    => $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::Not, $i)),
+        $crate::IResult::Error(_)      => $crate::IResult::Done($i, &($i)[..0]),
+        $crate::IResult::Incomplete(_) => $crate::IResult::Done($i, &($i)[..0])
+      }
+    }
+  );
+);
+
+/// `tap!(name: I -> IResult<I,O> => { block }) => I -> IResult<I, O>`
+/// allows access to the parser's result without affecting it
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::Done;
+/// # use std::str;
+/// # fn main() {
+///  named!(ptag, tap!(res: tag!( "abcd" ) => { println!("recognized {}", str::from_utf8(res).unwrap()) } ) );
+///
+///  let r = ptag(&b"abcdefgh"[..]);
+///  assert_eq!(r, Done(&b"efgh"[..], &b"abcd"[..]));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! tap (
+  ($i:expr, $name:ident : $submac:ident!( $($args:tt)* ) => $e:expr) => (
+    {
+      match $submac!($i, $($args)*) {
+        $crate::IResult::Done(i,o)     => {
+          let $name = o;
+          $e;
+          $crate::IResult::Done(i, $name)
+        },
+        $crate::IResult::Error(a)      => $crate::IResult::Error(a),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i)
+      }
+    }
+  );
+  ($i:expr, $name: ident: $f:expr => $e:expr) => (
+    tap!($i, $name: call!($f) => $e);
+  );
+);
+
+/// `pair!(I -> IResult<I,O>, I -> IResult<I,P>) => I -> IResult<I, (O,P)>`
+/// pair(X,Y), returns (x,y)
+///
+#[macro_export]
+macro_rules! pair(
+  ($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
+    {
+      tuple!($i, $submac!($($args)*), $submac2!($($args2)*))
+    }
+  );
+
+  ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
+    pair!($i, $submac!($($args)*), call!($g));
+  );
+
+  ($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
+    pair!($i, call!($f), $submac!($($args)*));
+  );
+
+  ($i:expr, $f:expr, $g:expr) => (
+    pair!($i, call!($f), call!($g));
+  );
+);
+
+/// `separated_pair!(I -> IResult<I,O>, I -> IResult<I, T>, I -> IResult<I,P>) => I -> IResult<I, (O,P)>`
+/// separated_pair(X,sep,Y) returns (x,y)
+#[macro_export]
+macro_rules! separated_pair(
+  ($i:expr, $submac:ident!( $($args:tt)* ), $($rest:tt)+) => (
+    {
+      match tuple_parser!($i, 0usize, (), $submac!($($args)*), $($rest)*) {
+        $crate::IResult::Error(a)      => $crate::IResult::Error(a),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
+        $crate::IResult::Done(i1, (o1, _, o2))   => {
+          $crate::IResult::Done(i1, (o1, o2))
+        }
+      }
+    }
+  );
+
+  ($i:expr, $f:expr, $($rest:tt)+) => (
+    separated_pair!($i, call!($f), $($rest)*);
+  );
+);
+
+/// `preceded!(I -> IResult<I,T>, I -> IResult<I,O>) => I -> IResult<I, O>`
+/// preceded(opening, X) returns X
+#[macro_export]
+macro_rules! preceded(
+  ($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
+    {
+      match tuple!($i, $submac!($($args)*), $submac2!($($args2)*)) {
+        $crate::IResult::Error(a)      => $crate::IResult::Error(a),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
+        $crate::IResult::Done(remaining, (_,o))    => {
+          $crate::IResult::Done(remaining, o)
+        }
+      }
+    }
+  );
+
+  ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
+    preceded!($i, $submac!($($args)*), call!($g));
+  );
+
+  ($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
+    preceded!($i, call!($f), $submac!($($args)*));
+  );
+
+  ($i:expr, $f:expr, $g:expr) => (
+    preceded!($i, call!($f), call!($g));
+  );
+);
+
+/// `terminated!(I -> IResult<I,O>, I -> IResult<I,T>) => I -> IResult<I, O>`
+/// terminated(X, closing) returns X
+#[macro_export]
+macro_rules! terminated(
+  ($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
+    {
+      match tuple!($i, $submac!($($args)*), $submac2!($($args2)*)) {
+        $crate::IResult::Error(a)      => $crate::IResult::Error(a),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
+        $crate::IResult::Done(remaining, (o,_))    => {
+          $crate::IResult::Done(remaining, o)
+        }
+      }
+    }
+  );
+
+  ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
+    terminated!($i, $submac!($($args)*), call!($g));
+  );
+
+  ($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
+    terminated!($i, call!($f), $submac!($($args)*));
+  );
+
+  ($i:expr, $f:expr, $g:expr) => (
+    terminated!($i, call!($f), call!($g));
+  );
+);
+
+/// `delimited!(I -> IResult<I,T>, I -> IResult<I,O>, I -> IResult<I,U>) => I -> IResult<I, O>`
+/// delimited(opening, X, closing) returns X
+#[macro_export]
+macro_rules! delimited(
+  ($i:expr, $submac:ident!( $($args:tt)* ), $($rest:tt)+) => (
+    {
+      match tuple_parser!($i, 0usize, (), $submac!($($args)*), $($rest)*) {
+        $crate::IResult::Error(a)      => $crate::IResult::Error(a),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
+        $crate::IResult::Done(i1, (_, o, _))   => {
+          $crate::IResult::Done(i1, o)
+        }
+      }
+    }
+  );
+
+  ($i:expr, $f:expr, $($rest:tt)+) => (
+    delimited!($i, call!($f), $($rest)*);
+  );
+);
+
+/// `separated_list!(I -> IResult<I,T>, I -> IResult<I,O>) => I -> IResult<I, Vec<O>>`
+/// separated_list(sep, X) returns Vec<X>
+#[macro_export]
+macro_rules! separated_list(
+  ($i:expr, $sep:ident!( $($args:tt)* ), $submac:ident!( $($args2:tt)* )) => (
+    {
+      let mut res   = ::std::vec::Vec::new();
+      let mut input = $i;
+
+      // get the first element
+      match $submac!(input, $($args2)*) {
+        $crate::IResult::Error(_)      => $crate::IResult::Done(input, ::std::vec::Vec::new()),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
+        $crate::IResult::Done(i,o)     => {
+          if i.len() == input.len() {
+            $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::SeparatedList,input))
+          } else {
+            res.push(o);
+            input = i;
+
+            loop {
+              // get the separator first
+              if let $crate::IResult::Done(i2,_) = $sep!(input, $($args)*) {
+                if i2.len() == input.len() {
+                  break;
+                }
+
+                // get the element next
+                if let $crate::IResult::Done(i3,o3) = $submac!(i2, $($args2)*) {
+                  if i3.len() == i2.len() {
+                    break;
+                  }
+                  res.push(o3);
+                  input = i3;
+                } else {
+                  break;
+                }
+              } else {
+                break;
+              }
+            }
+            $crate::IResult::Done(input, res)
+          }
+        },
+      }
+    }
+  );
+  ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
+    separated_list!($i, $submac!($($args)*), call!($g));
+  );
+  ($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
+    separated_list!($i, call!($f), $submac!($($args)*));
+  );
+  ($i:expr, $f:expr, $g:expr) => (
+    separated_list!($i, call!($f), call!($g));
+  );
+);
+
+/// `separated_nonempty_list!(I -> IResult<I,T>, I -> IResult<I,O>) => I -> IResult<I, Vec<O>>`
+/// separated_nonempty_list(sep, X) returns Vec<X>
+#[macro_export]
+macro_rules! separated_nonempty_list(
+  ($i:expr, $sep:ident!( $($args:tt)* ), $submac:ident!( $($args2:tt)* )) => (
+    {
+      let mut res   = ::std::vec::Vec::new();
+      let mut input = $i;
+
+      // get the first element
+      match $submac!(input, $($args2)*) {
+        $crate::IResult::Error(a)      => $crate::IResult::Error(a),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
+        $crate::IResult::Done(i,o)     => {
+          if i.len() == input.len() {
+            $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::SeparatedNonEmptyList,input))
+          } else {
+            res.push(o);
+            input = i;
+
+            loop {
+              if let $crate::IResult::Done(i2,_) = $sep!(input, $($args)*) {
+                if i2.len() == input.len() {
+                  break;
+                }
+
+                if let $crate::IResult::Done(i3,o3) = $submac!(i2, $($args2)*) {
+                  if i3.len() == i2.len() {
+                    break;
+                  }
+                  res.push(o3);
+                  input = i3;
+                } else {
+                  break;
+                }
+              } else {
+                break;
+              }
+            }
+            $crate::IResult::Done(input, res)
+          }
+        },
+      }
+    }
+  );
+  ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
+    separated_nonempty_list!($i, $submac!($($args)*), call!($g));
+  );
+  ($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
+    separated_nonempty_list!($i, call!($f), $submac!($($args)*));
+  );
+  ($i:expr, $f:expr, $g:expr) => (
+    separated_nonempty_list!($i, call!($f), call!($g));
+  );
+);
+
+/// `many0!(I -> IResult<I,O>) => I -> IResult<I, Vec<O>>`
+/// Applies the parser 0 or more times and returns the list of results in a Vec
+///
+/// the embedded parser may return Incomplete
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::Done;
+/// # fn main() {
+///  named!(multi<&[u8], Vec<&[u8]> >, many0!( tag!( "abcd" ) ) );
+///
+///  let a = b"abcdabcdefgh";
+///  let b = b"azerty";
+///
+///  let res = vec![&b"abcd"[..], &b"abcd"[..]];
+///  assert_eq!(multi(&a[..]), Done(&b"efgh"[..], res));
+///  assert_eq!(multi(&b[..]), Done(&b"azerty"[..], Vec::new()));
+/// # }
+/// ```
+/// 0 or more
+#[macro_export]
+macro_rules! many0(
+  ($i:expr, $submac:ident!( $($args:tt)* )) => (
+    {
+      use $crate::InputLength;
+
+      let ret;
+      let mut res   = ::std::vec::Vec::new();
+      let mut input = $i;
+
+      loop {
+        if input.input_len() == 0 {
+          ret = $crate::IResult::Done(input, res); break;
+        }
+
+        match $submac!(input, $($args)*) {
+          $crate::IResult::Error(_)                            => {
+            ret = $crate::IResult::Done(input, res); break;
+          },
+          $crate::IResult::Incomplete($crate::Needed::Unknown) => {
+            ret = $crate::IResult::Incomplete($crate::Needed::Unknown); break;
+          },
+          $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+            let size = i + ($i).input_len() - input.input_len();
+            ret = $crate::IResult::Incomplete($crate::Needed::Size(size)); break;
+          },
+          $crate::IResult::Done(i, o)                          => {
+            // loop trip must always consume (otherwise infinite loops)
+            if i == input {
+              ret = $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::Many0,input)); break;
+            }
+
+            res.push(o);
+            input = i;
+          }
+        }
+      }
+
+      ret
+    }
+  );
+  ($i:expr, $f:expr) => (
+    many0!($i, call!($f));
+  );
+);
+
+/// `many1!(I -> IResult<I,O>) => I -> IResult<I, Vec<O>>`
+/// Applies the parser 1 or more times and returns the list of results in a Vec
+///
+/// the embedded parser may return Incomplete
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::{Done, Error};
+/// # use nom::Err::Position;
+/// # use nom::ErrorKind;
+/// # fn main() {
+///  named!(multi<&[u8], Vec<&[u8]> >, many1!( tag!( "abcd" ) ) );
+///
+///  let a = b"abcdabcdefgh";
+///  let b = b"azerty";
+///
+///  let res = vec![&b"abcd"[..], &b"abcd"[..]];
+///  assert_eq!(multi(&a[..]), Done(&b"efgh"[..], res));
+///  assert_eq!(multi(&b[..]), Error(Position(ErrorKind::Many1,&b[..])));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! many1(
+  ($i:expr, $submac:ident!( $($args:tt)* )) => (
+    {
+      use $crate::InputLength;
+      match $submac!($i, $($args)*) {
+        $crate::IResult::Error(_)      => $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::Many1,$i)),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
+        $crate::IResult::Done(i1,o1)   => {
+          if i1.input_len() == 0 {
+            $crate::IResult::Done(i1,vec![o1])
+          } else {
+
+            let mut res    = ::std::vec::Vec::with_capacity(4);
+            res.push(o1);
+            let mut input  = i1;
+            let mut incomplete: ::std::option::Option<$crate::Needed> = ::std::option::Option::None;
+            loop {
+              if input.input_len() == 0 {
+                break;
+              }
+              match $submac!(input, $($args)*) {
+                $crate::IResult::Error(_)                    => {
+                  break;
+                },
+                $crate::IResult::Incomplete($crate::Needed::Unknown) => {
+                  incomplete = ::std::option::Option::Some($crate::Needed::Unknown);
+                  break;
+                },
+                $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+                  incomplete = ::std::option::Option::Some($crate::Needed::Size(i + ($i).input_len() - input.input_len()));
+                  break;
+                },
+                $crate::IResult::Done(i, o) => {
+                  if i.input_len() == input.input_len() {
+                    break;
+                  }
+                  res.push(o);
+                  input = i;
+                }
+              }
+            }
+
+            match incomplete {
+              ::std::option::Option::Some(i) => $crate::IResult::Incomplete(i),
+              ::std::option::Option::None    => $crate::IResult::Done(input, res)
+            }
+          }
+        }
+      }
+    }
+  );
+  ($i:expr, $f:expr) => (
+    many1!($i, call!($f));
+  );
+);
+
+/// `many_m_n!(usize, usize, I -> IResult<I,O>) => I -> IResult<I, Vec<O>>`
+/// Applies the parser between m and n times (n included) and returns the list of results in a Vec
+///
+/// the embedded parser may return Incomplete
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::{Done, Error};
+/// # use nom::Err::Position;
+/// # use nom::ErrorKind;
+/// # fn main() {
+///  named!(multi<&[u8], Vec<&[u8]> >, many_m_n!(2, 4, tag!( "abcd" ) ) );
+///
+///  let a = b"abcdefgh";
+///  let b = b"abcdabcdefgh";
+///  let c = b"abcdabcdabcdabcdabcdefgh";
+///
+///  assert_eq!(multi(&a[..]),Error(Position(ErrorKind::ManyMN,&a[..])));
+///  let res = vec![&b"abcd"[..], &b"abcd"[..]];
+///  assert_eq!(multi(&b[..]), Done(&b"efgh"[..], res));
+///  let res2 = vec![&b"abcd"[..], &b"abcd"[..], &b"abcd"[..], &b"abcd"[..]];
+///  assert_eq!(multi(&c[..]), Done(&b"abcdefgh"[..], res2));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! many_m_n(
+  ($i:expr, $m:expr, $n: expr, $submac:ident!( $($args:tt)* )) => (
+    {
+      use $crate::InputLength;
+      let mut res          = ::std::vec::Vec::with_capacity($m);
+      let mut input        = $i;
+      let mut count: usize = 0;
+      let mut err          = false;
+      let mut incomplete: ::std::option::Option<$crate::Needed> = ::std::option::Option::None;
+      loop {
+        if count == $n { break }
+        match $submac!(input, $($args)*) {
+          $crate::IResult::Done(i, o) => {
+            // do not allow parsers that do not consume input (causes infinite loops)
+            if i.input_len() == input.input_len() {
+              break;
+            }
+            res.push(o);
+            input  = i;
+            count += 1;
+          }
+          $crate::IResult::Error(_)                    => {
+            err = true;
+            break;
+          },
+          $crate::IResult::Incomplete($crate::Needed::Unknown) => {
+            incomplete = ::std::option::Option::Some($crate::Needed::Unknown);
+            break;
+          },
+          $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+            incomplete = ::std::option::Option::Some($crate::Needed::Size(i + ($i).input_len() - input.input_len()));
+            break;
+          },
+        }
+        if input.input_len() == 0 {
+          break;
+        }
+      }
+
+      if count < $m {
+        if err {
+          $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::ManyMN,$i))
+        } else {
+          match incomplete {
+            ::std::option::Option::Some(i) => $crate::IResult::Incomplete(i),
+            ::std::option::Option::None    => $crate::IResult::Incomplete($crate::Needed::Unknown)
+          }
+        }
+      } else {
+        match incomplete {
+          ::std::option::Option::Some(i) => $crate::IResult::Incomplete(i),
+          ::std::option::Option::None    => $crate::IResult::Done(input, res)
+        }
+      }
+    }
+  );
+  ($i:expr, $m:expr, $n: expr, $f:expr) => (
+    many_m_n!($i, $m, $n, call!($f));
+  );
+);
+
+/// `count!(I -> IResult<I,O>, nb) => I -> IResult<I, Vec<O>>`
+/// Applies the child parser a specified number of times
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::{Done,Error};
+/// # use nom::Err::Position;
+/// # use nom::ErrorKind;
+/// # fn main() {
+///  named!(counter< Vec<&[u8]> >, count!( tag!( "abcd" ), 2 ) );
+///
+///  let a = b"abcdabcdabcdef";
+///  let b = b"abcdefgh";
+///  let res = vec![&b"abcd"[..], &b"abcd"[..]];
+///
+///  assert_eq!(counter(&a[..]), Done(&b"abcdef"[..], res));
+///  assert_eq!(counter(&b[..]), Error(Position(ErrorKind::Count, &b[..])));
+/// # }
+/// ```
+///
+#[macro_export]
+macro_rules! count(
+  ($i:expr, $submac:ident!( $($args:tt)* ), $count: expr) => (
+    {
+      let ret;
+      let mut input = $i;
+      let mut res   = ::std::vec::Vec::with_capacity($count);
+
+      loop {
+        if res.len() == $count {
+          ret = $crate::IResult::Done(input, res); break;
+        }
+
+        match $submac!(input, $($args)*) {
+          $crate::IResult::Done(i,o) => {
+            res.push(o);
+            input = i;
+          },
+          $crate::IResult::Error(_)  => {
+            ret = $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::Count,$i)); break;
+          },
+          $crate::IResult::Incomplete(_) => {
+            ret = $crate::IResult::Incomplete($crate::Needed::Unknown); break;
+          }
+        }
+      }
+
+      ret
+    }
+  );
+  ($i:expr, $f:expr, $count: expr) => (
+    count!($i, call!($f), $count);
+  );
+);
+
+/// `count_fixed!(O, I -> IResult<I,O>, nb) => I -> IResult<I, [O; nb]>`
+/// Applies the child parser a fixed number of times and returns a fixed size array
+/// The type must be specified and it must be `Copy`
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::{Done,Error};
+/// # use nom::Err::Position;
+/// # use nom::ErrorKind;
+/// # fn main() {
+///  named!(counter< [&[u8]; 2] >, count_fixed!( &[u8], tag!( "abcd" ), 2 ) );
+///  // can omit the type specifier if returning slices
+///  // named!(counter< [&[u8]; 2] >, count_fixed!( tag!( "abcd" ), 2 ) );
+///
+///  let a = b"abcdabcdabcdef";
+///  let b = b"abcdefgh";
+///  let res = [&b"abcd"[..], &b"abcd"[..]];
+///
+///  assert_eq!(counter(&a[..]), Done(&b"abcdef"[..], res));
+///  assert_eq!(counter(&b[..]), Error(Position(ErrorKind::Count, &b[..])));
+/// # }
+/// ```
+///
+#[macro_export]
+macro_rules! count_fixed (
+  ($i:expr, $typ:ty, $submac:ident!( $($args:tt)* ), $count: expr) => (
+    {
+      let ret;
+      let mut input = $i;
+      // `$typ` must be Copy, and thus having no destructor, this is panic safe
+      let mut res: [$typ; $count] = unsafe{[::std::mem::uninitialized(); $count as usize]};
+      let mut cnt: usize = 0;
+
+      loop {
+        if cnt == $count {
+          ret = $crate::IResult::Done(input, res); break;
+        }
+
+        match $submac!(input, $($args)*) {
+          $crate::IResult::Done(i,o) => {
+            res[cnt] = o;
+            cnt += 1;
+            input = i;
+          },
+          $crate::IResult::Error(_)  => {
+            ret = $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::Count,$i)); break;
+          },
+          $crate::IResult::Incomplete(_) => {
+            ret = $crate::IResult::Incomplete($crate::Needed::Unknown); break;
+          }
+        }
+      }
+
+      ret
+    }
+  );
+  ($i:expr, $typ: ty, $f:ident, $count: expr) => (
+    count_fixed!($i, $typ, call!($f), $count);
+  );
+);
+
+/// `length_value!(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_value(
+  ($i:expr, $f:expr, $g:expr) => (
+    {
+      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.len() - inum.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;
+            }
+
+            match $g(input) {
+              $crate::IResult::Done(iparse, oparse) => {
+                res.push(oparse);
+                input = iparse;
+              },
+              $crate::IResult::Error(_)      => {
+                ret = $crate::IResult::Error($crate::Err::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(length) => $crate::IResult::Incomplete($crate::Needed::Size(length_token + onum as usize * length))
+                };
+                break;
+              }
+            }
+          }
+
+          ret
+        }
+      }
+    }
+  );
+  ($i:expr, $f:expr, $g:expr, $length:expr) => (
+    {
+      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.len() - inum.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;
+            }
+
+            match $g(input) {
+              $crate::IResult::Done(iparse, oparse) => {
+                res.push(oparse);
+                input = iparse;
+              },
+              $crate::IResult::Error(_)      => {
+                ret = $crate::IResult::Error($crate::Err::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(_) => $crate::IResult::Incomplete($crate::Needed::Size(length_token + onum as usize * $length))
+                };
+                break;
+              }
+            }
+          }
+
+          ret
+        }
+      }
+    }
+  );
+);
+
+/// `fold_many0!(I -> IResult<I,O>, R, Fn(R, O) -> R) => I -> IResult<I, R>`
+/// Applies the parser 0 or more times and folds the list of return values
+///
+/// the embedded parser may return Incomplete
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::Done;
+/// # fn main() {
+///  named!(multi<&[u8], Vec<&[u8]> >, fold_many0!( tag!( "abcd" ), Vec::new(), |mut acc: Vec<_>, item| {
+///      acc.push(item);
+///      acc
+///  }));
+///
+///  let a = b"abcdabcdefgh";
+///  let b = b"azerty";
+///
+///  let res = vec![&b"abcd"[..], &b"abcd"[..]];
+///  assert_eq!(multi(&a[..]), Done(&b"efgh"[..], res));
+///  assert_eq!(multi(&b[..]), Done(&b"azerty"[..], Vec::new()));
+/// # }
+/// ```
+/// 0 or more
+#[macro_export]
+macro_rules! fold_many0(
+  ($i:expr, $submac:ident!( $($args:tt)* ), $init:expr, $f:expr) => (
+    {
+      use $crate::InputLength;
+      let ret;
+      let f         = $f;
+      let mut res   = $init;
+      let mut input = $i;
+
+      loop {
+        if input.input_len() == 0 {
+          ret = $crate::IResult::Done(input, res); break;
+        }
+
+        match $submac!(input, $($args)*) {
+          $crate::IResult::Error(_)                            => {
+            ret = $crate::IResult::Done(input, res); break;
+          },
+          $crate::IResult::Incomplete($crate::Needed::Unknown) => {
+            ret = $crate::IResult::Incomplete($crate::Needed::Unknown); break;
+          },
+          $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+            let size = i + ($i).input_len() - input.input_len();
+            ret = $crate::IResult::Incomplete($crate::Needed::Size(size)); break;
+          },
+          $crate::IResult::Done(i, o)                          => {
+            // loop trip must always consume (otherwise infinite loops)
+            if i == input {
+              ret = $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::Many0,input)); break;
+            }
+
+            res = f(res, o);
+            input = i;
+          }
+        }
+      }
+
+      ret
+    }
+  );
+  ($i:expr, $f:expr, $init:expr, $fold_f:expr) => (
+    fold_many0!($i, call!($f), $init, $fold_f);
+  );
+);
+
+/// `fold_many1!(I -> IResult<I,O>, R, Fn(R, O) -> R) => I -> IResult<I, R>`
+/// Applies the parser 1 or more times and folds the list of return values
+///
+/// the embedded parser may return Incomplete
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::{Done, Error};
+/// # use nom::Err::Position;
+/// # use nom::ErrorKind;
+/// # fn main() {
+///  named!(multi<&[u8], Vec<&[u8]> >, fold_many1!( tag!( "abcd" ), Vec::new(), |mut acc: Vec<_>, item| {
+///      acc.push(item);
+///      acc
+///  }));
+///
+///  let a = b"abcdabcdefgh";
+///  let b = b"azerty";
+///
+///  let res = vec![&b"abcd"[..], &b"abcd"[..]];
+///  assert_eq!(multi(&a[..]), Done(&b"efgh"[..], res));
+///  assert_eq!(multi(&b[..]), Error(Position(ErrorKind::Many1,&b[..])));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! fold_many1(
+  ($i:expr, $submac:ident!( $($args:tt)* ), $init:expr, $f:expr) => (
+    {
+      use $crate::InputLength;
+      match $submac!($i, $($args)*) {
+        $crate::IResult::Error(_)      => $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::Many1,$i)),
+        $crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
+        $crate::IResult::Done(i1,o1)   => {
+          let acc = $init;
+          let f = $f;
+          if i1.len() == 0 {
+            let acc = f(acc, o1);
+            $crate::IResult::Done(i1,acc)
+          } else {
+            let mut acc = f(acc, o1);
+            let mut input  = i1;
+            let mut incomplete: ::std::option::Option<$crate::Needed> = ::std::option::Option::None;
+            loop {
+              if input.input_len() == 0 {
+                break;
+              }
+              match $submac!(input, $($args)*) {
+                $crate::IResult::Error(_)                    => {
+                  break;
+                },
+                $crate::IResult::Incomplete($crate::Needed::Unknown) => {
+                  incomplete = ::std::option::Option::Some($crate::Needed::Unknown);
+                  break;
+                },
+                $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+                  incomplete = ::std::option::Option::Some($crate::Needed::Size(i + ($i).input_len() - input.input_len()));
+                  break;
+                },
+                $crate::IResult::Done(i, o) => {
+                  if i.input_len() == input.input_len() {
+                    break;
+                  }
+                  acc = f(acc, o);
+                  input = i;
+                }
+              }
+            }
+
+            match incomplete {
+              ::std::option::Option::Some(i) => $crate::IResult::Incomplete(i),
+              ::std::option::Option::None    => $crate::IResult::Done(input, acc)
+            }
+          }
+        }
+      }
+    }
+  );
+  ($i:expr, $f:expr, $init:expr, $fold_f:expr) => (
+    fold_many1!($i, call!($f), $init, $fold_f);
+  );
+);
+
+/// `fold_many_m_n!(usize, usize, I -> IResult<I,O>, R, Fn(R, O) -> R) => I -> IResult<I, R>`
+/// Applies the parser between m and n times (n included) and folds the list of return value
+///
+/// the embedded parser may return Incomplete
+///
+/// ```
+/// # #[macro_use] extern crate nom;
+/// # use nom::IResult::{Done, Error};
+/// # use nom::Err::Position;
+/// # use nom::ErrorKind;
+/// # fn main() {
+///  named!(multi<&[u8], Vec<&[u8]> >, fold_many_m_n!(2, 4, tag!( "abcd" ), Vec::new(), |mut acc: Vec<_>, item| {
+///      acc.push(item);
+///      acc
+///  }));
+///
+///  let a = b"abcdefgh";
+///  let b = b"abcdabcdefgh";
+///  let c = b"abcdabcdabcdabcdabcdefgh";
+///
+///  assert_eq!(multi(&a[..]),Error(Position(ErrorKind::ManyMN,&a[..])));
+///  let res = vec![&b"abcd"[..], &b"abcd"[..]];
+///  assert_eq!(multi(&b[..]), Done(&b"efgh"[..], res));
+///  let res2 = vec![&b"abcd"[..], &b"abcd"[..], &b"abcd"[..], &b"abcd"[..]];
+///  assert_eq!(multi(&c[..]), Done(&b"abcdefgh"[..], res2));
+/// # }
+/// ```
+#[macro_export]
+macro_rules! fold_many_m_n(
+  ($i:expr, $m:expr, $n: expr, $submac:ident!( $($args:tt)* ), $init:expr, $f:expr) => (
+    {
+      use $crate::InputLength;
+      let mut acc          = $init;
+      let     f            = $f;
+      let mut input        = $i;
+      let mut count: usize = 0;
+      let mut err          = false;
+      let mut incomplete: ::std::option::Option<$crate::Needed> = ::std::option::Option::None;
+      loop {
+        if count == $n { break }
+        match $submac!(input, $($args)*) {
+          $crate::IResult::Done(i, o) => {
+            // do not allow parsers that do not consume input (causes infinite loops)
+            if i.input_len() == input.input_len() {
+              break;
+            }
+            acc = f(acc, o);
+            input  = i;
+            count += 1;
+          }
+          $crate::IResult::Error(_)                    => {
+            err = true;
+            break;
+          },
+          $crate::IResult::Incomplete($crate::Needed::Unknown) => {
+            incomplete = ::std::option::Option::Some($crate::Needed::Unknown);
+            break;
+          },
+          $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+            incomplete = ::std::option::Option::Some($crate::Needed::Size(i + ($i).input_len() - input.input_len()));
+            break;
+          },
+        }
+        if input.input_len() == 0 {
+          break;
+        }
+      }
+
+      if count < $m {
+        if err {
+          $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::ManyMN,$i))
+        } else {
+          match incomplete {
+            ::std::option::Option::Some(i) => $crate::IResult::Incomplete(i),
+            ::std::option::Option::None    => $crate::IResult::Incomplete($crate::Needed::Unknown)
+          }
+        }
+      } else {
+        match incomplete {
+          ::std::option::Option::Some(i) => $crate::IResult::Incomplete(i),
+          ::std::option::Option::None    => $crate::IResult::Done(input, acc)
+        }
+      }
+    }
+  );
+  ($i:expr, $m:expr, $n: expr, $f:expr, $init:expr, $fold_f:expr) => (
+    fold_many_m_n!($i, $m, $n, call!($f), $init, $fold_f);
+  );
+);
+
+#[cfg(test)]
+mod tests {
+  use internal::{Needed,IResult,Err};
+  use internal::IResult::*;
+  use internal::Err::*;
+  use util::ErrorKind;
+
+  // reproduce the tag and take macros, because of module import order
+  macro_rules! tag (
+    ($i:expr, $inp: expr) => (
+      {
+        #[inline(always)]
+        fn as_bytes<T: $crate::AsBytes>(b: &T) -> &[u8] {
+          b.as_bytes()
+        }
+
+        let expected = $inp;
+        let bytes    = as_bytes(&expected);
+
+        tag_bytes!($i,bytes)
+      }
+    );
+  );
+
+  macro_rules! tag_bytes (
+    ($i:expr, $bytes: expr) => (
+      {
+        use std::cmp::min;
+        let len = $i.len();
+        let blen = $bytes.len();
+        let m   = min(len, blen);
+        let reduced = &$i[..m];
+        let b       = &$bytes[..m];
+
+        let res: $crate::IResult<_,_> = if reduced != b {
+          $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::Tag, $i))
+        } else if m < blen {
+          $crate::IResult::Incomplete($crate::Needed::Size(blen))
+        } else {
+          $crate::IResult::Done(&$i[blen..], reduced)
+        };
+        res
+      }
+    );
+  );
+
+  macro_rules! take(
+    ($i:expr, $count:expr) => (
+      {
+        let cnt = $count as usize;
+        let res:$crate::IResult<&[u8],&[u8]> = if $i.len() < cnt {
+          $crate::IResult::Incomplete($crate::Needed::Size(cnt))
+        } else {
+          $crate::IResult::Done(&$i[cnt..],&$i[0..cnt])
+        };
+        res
+      }
+    );
+  );
+
+
+  mod pub_named_mod {
+    named!(pub tst, tag!("abcd"));
+  }
+
+  #[test]
+  fn pub_named_test() {
+    let a = &b"abcd"[..];
+    let res = pub_named_mod::tst(a);
+    assert_eq!(res, Done(&b""[..], a));
+  }
+
+  #[test]
+  fn apply_test() {
+    fn sum2(a:u8, b:u8)       -> u8 { a + b }
+    fn sum3(a:u8, b:u8, c:u8) -> u8 { a + b + c }
+    let a = apply!(1, sum2, 2);
+    let b = apply!(1, sum3, 2, 3);
+
+    assert_eq!(a, 3);
+    assert_eq!(b, 6);
+  }
+
+  #[derive(PartialEq,Eq,Debug)]
+  struct B {
+    a: u8,
+    b: u8
+  }
+
+  #[test]
+  fn chain2() {
+    fn ret_int1(i:&[u8]) -> IResult<&[u8], u8> { Done(i,1) };
+    fn ret_int2(i:&[u8]) -> IResult<&[u8], u8> { Done(i,2) };
+
+    named!(chain_parser<&[u8],B>,
+      chain!(
+        tag!("abcd")   ~
+        tag!("abcd")?  ~
+        aa: ret_int1   ~
+        tag!("efgh")   ~
+        bb: ret_int2   ~
+        tag!("efgh")   ,
+        ||{B{a: aa, b: bb}}
+      )
+    );
+
+    assert_eq!(chain_parser(&b"abcdabcdefghefghX"[..]), Done(&b"X"[..], B{a: 1, b: 2}));
+    assert_eq!(chain_parser(&b"abcdefghefghX"[..]), Done(&b"X"[..], B{a: 1, b: 2}));
+    assert_eq!(chain_parser(&b"abcdab"[..]), Incomplete(Needed::Size(8)));
+    assert_eq!(chain_parser(&b"abcdefghef"[..]), Incomplete(Needed::Size(12)));
+  }
+
+  #[test]
+  fn nested_chain() {
+    fn ret_int1(i:&[u8]) -> IResult<&[u8], u8> { Done(i,1) };
+    fn ret_int2(i:&[u8]) -> IResult<&[u8], u8> { Done(i,2) };
+
+    named!(chain_parser<&[u8],B>,
+      chain!(
+        chain!(
+          tag!("abcd")   ~
+          tag!("abcd")?  ,
+          || {}
+        )              ~
+        aa: ret_int1   ~
+        tag!("efgh")   ~
+        bb: ret_int2   ~
+        tag!("efgh")   ,
+        ||{B{a: aa, b: bb}}
+      )
+    );
+
+    assert_eq!(chain_parser(&b"abcdabcdefghefghX"[..]), Done(&b"X"[..], B{a: 1, b: 2}));
+    assert_eq!(chain_parser(&b"abcdefghefghX"[..]), Done(&b"X"[..], B{a: 1, b: 2}));
+    assert_eq!(chain_parser(&b"abcdab"[..]), Incomplete(Needed::Size(8)));
+    assert_eq!(chain_parser(&b"abcdefghef"[..]), Incomplete(Needed::Size(12)));
+  }
+
+  #[derive(PartialEq,Eq,Debug)]
+  struct C {
+    a: u8,
+    b: Option<u8>
+  }
+
+  #[test]
+  fn chain_mut() {
+    fn ret_b1_2(i:&[u8]) -> IResult<&[u8], B> { Done(i,B{a:1,b:2}) };
+    named!(f<&[u8],B>,
+      chain!(
+        tag!("abcd")     ~
+        tag!("abcd")?    ~
+        tag!("efgh")     ~
+        mut bb: ret_b1_2 ~
+        tag!("efgh")   ,
+        ||{
+          bb.b = 3;
+          bb
+        }
+      )
+    );
+
+    let r = f(&b"abcdabcdefghefghX"[..]);
+    assert_eq!(r, Done(&b"X"[..], B{a: 1, b: 3}));
+  }
+
+  #[test]
+  fn chain_opt() {
+    named!(y, tag!("efgh"));
+    fn ret_int1(i:&[u8]) -> IResult<&[u8], u8> { Done(i,1) };
+    named!(ret_y<&[u8], u8>, map!(y, |_| 2));
+
+    named!(chain_parser<&[u8],C>,
+      chain!(
+        tag!("abcd") ~
+        aa: ret_int1 ~
+        bb: ret_y?   ,
+        ||{C{a: aa, b: bb}}
+      )
+    );
+
+    assert_eq!(chain_parser(&b"abcdefghX"[..]), Done(&b"X"[..], C{a: 1, b: Some(2)}));
+    assert_eq!(chain_parser(&b"abcdWXYZ"[..]), Done(&b"WXYZ"[..], C{a: 1, b: None}));
+    assert_eq!(chain_parser(&b"abcdX"[..]), Done(&b"X"[..], C{ a: 1, b: None }));
+    assert_eq!(chain_parser(&b"abcdef"[..]), Incomplete(Needed::Size(8)));
+  }
+
+  use util::{error_to_list, add_error_pattern, print_error};
+
+  fn error_to_string<P>(e: &Err<P>) -> &'static str {
+    let v:Vec<ErrorKind> = error_to_list(e);
+    // do it this way if you can use slice patterns
+    /*
+    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"
+    }
+    */
+    if &v[..] == [ErrorKind::Custom(42),ErrorKind::Tag] {
+      "missing `ijkl` tag"
+    } else if &v[..] == [ErrorKind::Custom(42), ErrorKind::Custom(128), ErrorKind::Tag] {
+      "missing `mnop` tag after `ijkl`"
+    } else {
+      "unrecognized error"
+    }
+  }
+
+  // do it this way if you can use box patterns
+  /*use std::str;
+  fn error_to_string(e:Err) -> String
+    match e {
+      NodePosition(ErrorKind::Custom(42), i1, box Position(ErrorKind::Tag, i2)) => {
+        format!("missing `ijkl` tag, found '{}' instead", str::from_utf8(i2).unwrap())
+      },
+      NodePosition(ErrorKind::Custom(42), i1, box NodePosition(ErrorKind::Custom(128), i2,  box Position(ErrorKind::Tag, i3))) => {
+        format!("missing `mnop` tag after `ijkl`, found '{}' instead", str::from_utf8(i3).unwrap())
+      },
+      _ => "unrecognized error".to_string()
+    }
+  }*/
+  use std::collections;
+  #[test]
+  fn err() {
+    named!(err_test, alt!(
+      tag!("abcd") |
+      preceded!(tag!("efgh"), error!(ErrorKind::Custom(42),
+          chain!(
+                 tag!("ijkl")              ~
+            res: error!(ErrorKind::Custom(128), tag!("mnop")) ,
+            || { res }
+          )
+        )
+      )
+    ));
+    let a = &b"efghblah"[..];
+    let b = &b"efghijklblah"[..];
+    let c = &b"efghijklmnop"[..];
+
+    let blah = &b"blah"[..];
+
+    let res_a = err_test(a);
+    let res_b = err_test(b);
+    let res_c = err_test(c);
+    assert_eq!(res_a, Error(NodePosition(ErrorKind::Custom(42), blah, Box::new(Position(ErrorKind::Tag, blah)))));
+    assert_eq!(res_b, Error(NodePosition(ErrorKind::Custom(42), &b"ijklblah"[..], Box::new(NodePosition(ErrorKind::Custom(128), blah, Box::new(Position(ErrorKind::Tag, blah)))))));
+    assert_eq!(res_c, Done(&b""[..], &b"mnop"[..]));
+
+    // Merr-like error matching
+    let mut err_map = collections::HashMap::new();
+    assert!(add_error_pattern(&mut err_map, err_test(&b"efghpouet"[..]), "missing `ijkl` tag"));
+    assert!(add_error_pattern(&mut err_map, err_test(&b"efghijklpouet"[..]), "missing `mnop` tag after `ijkl`"));
+
+    let res_a2 = res_a.clone();
+    match res_a {
+      Error(e) => {
+        assert_eq!(error_to_list(&e), [ErrorKind::Custom(42), ErrorKind::Tag]);
+        assert_eq!(error_to_string(&e), "missing `ijkl` tag");
+        assert_eq!(err_map.get(&error_to_list(&e)), Some(&"missing `ijkl` tag"));
+      },
+      _ => panic!()
+    };
+
+    let res_b2 = res_b.clone();
+    match res_b {
+      Error(e) => {
+        assert_eq!(error_to_list(&e), [ErrorKind::Custom(42), ErrorKind::Custom(128), ErrorKind::Tag]);
+        assert_eq!(error_to_string(&e), "missing `mnop` tag after `ijkl`");
+        assert_eq!(err_map.get(&error_to_list(&e)), Some(&"missing `mnop` tag after `ijkl`"));
+      },
+      _ => panic!()
+    };
+
+    print_error(a, res_a2);
+    print_error(b, res_b2);
+  }
+
+  #[test]
+  fn add_err() {
+    named!(err_test,
+      preceded!(tag!("efgh"), add_error!(ErrorKind::Custom(42),
+          chain!(
+                 tag!("ijkl")              ~
+            res: add_error!(ErrorKind::Custom(128), tag!("mnop")) ,
+            || { res }
+          )
+        )
+    ));
+    let a = &b"efghblah"[..];
+    let b = &b"efghijklblah"[..];
+    let c = &b"efghijklmnop"[..];
+
+    let blah = &b"blah"[..];
+
+    let res_a = err_test(a);
+    let res_b = err_test(b);
+    let res_c = err_test(c);
+    assert_eq!(res_a, Error(NodePosition(ErrorKind::Custom(42), blah, Box::new(Position(ErrorKind::Tag, blah)))));
+    assert_eq!(res_b, Error(NodePosition(ErrorKind::Custom(42), &b"ijklblah"[..], Box::new(NodePosition(ErrorKind::Custom(128), blah, Box::new(Position(ErrorKind::Tag, blah)))))));
+    assert_eq!(res_c, Done(&b""[..], &b"mnop"[..]));
+  }
+
+  #[test]
+  fn complete() {
+    named!(err_test,
+      chain!(
+             tag!("ijkl")              ~
+        res: complete!(tag!("mnop")) ,
+        || { res }
+      )
+    );
+    let a = &b"ijklmn"[..];
+
+    let res_a = err_test(a);
+    assert_eq!(res_a, Error(Position(ErrorKind::Complete, &b"mn"[..])));
+  }
+  #[test]
+  fn alt() {
+    fn work(input: &[u8]) -> IResult<&[u8],&[u8], &'static str> {
+      Done(&b""[..], input)
+    }
+
+    #[allow(unused_variables)]
+    fn dont_work(input: &[u8]) -> IResult<&[u8],&[u8],&'static str> {
+      Error(Code(ErrorKind::Custom("abcd")))
+    }
+
+    fn work2(input: &[u8]) -> IResult<&[u8],&[u8], &'static str> {
+      Done(input, &b""[..])
+    }
+
+    fn alt1(i:&[u8]) ->  IResult<&[u8],&[u8], &'static str> {
+      alt!(i, dont_work | dont_work)
+    }
+    fn alt2(i:&[u8]) ->  IResult<&[u8],&[u8], &'static str> {
+      alt!(i, dont_work | work)
+    }
+    fn alt3(i:&[u8]) ->  IResult<&[u8],&[u8], &'static str> {
+      alt!(i, dont_work | dont_work | work2 | dont_work)
+    }
+    //named!(alt1, alt!(dont_work | dont_work));
+    //named!(alt2, alt!(dont_work | work));
+    //named!(alt3, alt!(dont_work | dont_work | work2 | dont_work));
+
+    let a = &b"abcd"[..];
+    assert_eq!(alt1(a), Error(Position(ErrorKind::Alt, a)));
+    assert_eq!(alt2(a), Done(&b""[..], a));
+    assert_eq!(alt3(a), Done(a, &b""[..]));
+
+    named!(alt4, alt!(tag!("abcd") | tag!("efgh")));
+    let b = &b"efgh"[..];
+    assert_eq!(alt4(a), Done(&b""[..], a));
+    assert_eq!(alt4(b), Done(&b""[..], b));
+
+    // test the alternative syntax
+    named!(alt5<bool>, alt!(tag!("abcd") => { |_| false } | tag!("efgh") => { |_| true }));
+    assert_eq!(alt5(a), Done(&b""[..], false));
+    assert_eq!(alt5(b), Done(&b""[..], true));
+
+  }
+
+  #[test]
+  fn alt_incomplete() {
+    named!(alt1, alt!(tag!("a") | tag!("bc") | tag!("def")));
+
+    let a = &b""[..];
+    assert_eq!(alt1(a), Incomplete(Needed::Size(1)));
+    let a = &b"b"[..];
+    assert_eq!(alt1(a), Incomplete(Needed::Size(2)));
+    let a = &b"bcd"[..];
+    assert_eq!(alt1(a), Done(&b"d"[..], &b"bc"[..]));
+    let a = &b"cde"[..];
+    assert_eq!(alt1(a), Error(Position(ErrorKind::Alt, a)));
+    let a = &b"de"[..];
+    assert_eq!(alt1(a), Incomplete(Needed::Size(3)));
+    let a = &b"defg"[..];
+    assert_eq!(alt1(a), Done(&b"g"[..], &b"def"[..]));
+  }
+
+  #[test]
+  fn alt_complete() {
+    named!(ac<&[u8], &[u8]>,
+      alt_complete!(tag!("abcd") | tag!("ef") | tag!("ghi") | tag!("kl"))
+    );
+
+    let a = &b""[..];
+    assert_eq!(ac(a), Incomplete(Needed::Size(2)));
+    let a = &b"ef"[..];
+    assert_eq!(ac(a), Done(&b""[..], &b"ef"[..]));
+    let a = &b"cde"[..];
+    assert_eq!(ac(a), Error(Position(ErrorKind::Alt, a)));
+  }
+
+  #[test]
+  fn switch() {
+    named!(sw,
+      switch!(take!(4),
+        b"abcd" => take!(2) |
+        b"efgh" => take!(4)
+      )
+    );
+
+    let a = &b"abcdefgh"[..];
+    assert_eq!(sw(a), Done(&b"gh"[..], &b"ef"[..]));
+
+    let b = &b"efghijkl"[..];
+    assert_eq!(sw(b), Done(&b""[..], &b"ijkl"[..]));
+    let c = &b"afghijkl"[..];
+    assert_eq!(sw(c), Error(Position(ErrorKind::Switch, &b"afghijkl"[..])));
+  }
+
+  #[test]
+  fn opt() {
+    named!(opt_abcd<&[u8],Option<&[u8]> >, opt!(tag!("abcd")));
+
+    let a = &b"abcdef"[..];
+    let b = &b"bcdefg"[..];
+    let c = &b"ab"[..];
+    assert_eq!(opt_abcd(a), Done(&b"ef"[..], Some(&b"abcd"[..])));
+    assert_eq!(opt_abcd(b), Done(&b"bcdefg"[..], None));
+    assert_eq!(opt_abcd(c), Incomplete(Needed::Size(4)));
+  }
+
+  #[test]
+  fn opt_res() {
+    named!(opt_res_abcd<&[u8], Result<&[u8], Err<&[u8]>> >, opt_res!(tag!("abcd")));
+
+    let a = &b"abcdef"[..];
+    let b = &b"bcdefg"[..];
+    let c = &b"ab"[..];
+    assert_eq!(opt_res_abcd(a), Done(&b"ef"[..], Ok(&b"abcd"[..])));
+    assert_eq!(opt_res_abcd(b), Done(&b"bcdefg"[..], Err(Position(ErrorKind::Tag, b))));
+    assert_eq!(opt_res_abcd(c), Incomplete(Needed::Size(4)));
+  }
+
+  #[test]
+  fn cond() {
+    let f_true: Box<Fn(&'static [u8]) -> IResult<&[u8],Option<&[u8]>, &str>> = Box::new(closure!(&'static [u8], cond!( true, tag!("abcd") ) ));
+    let f_false: Box<Fn(&'static [u8]) -> IResult<&[u8],Option<&[u8]>, &str>> = Box::new(closure!(&'static [u8], cond!( false, tag!("abcd") ) ));
+    //let f_false = closure!(&'static [u8], cond!( false, tag!("abcd") ) );
+
+    assert_eq!(f_true(&b"abcdef"[..]), Done(&b"ef"[..], Some(&b"abcd"[..])));
+    assert_eq!(f_true(&b"ab"[..]), Incomplete(Needed::Size(4)));
+    assert_eq!(f_true(&b"xxx"[..]), Done(&b"xxx"[..], None));
+
+    assert_eq!(f_false(&b"abcdef"[..]), Done(&b"abcdef"[..], None));
+    assert_eq!(f_false(&b"ab"[..]), Done(&b"ab"[..], None));
+    assert_eq!(f_false(&b"xxx"[..]), Done(&b"xxx"[..], None));
+  }
+
+  #[test]
+  fn cond_wrapping() {
+    // Test that cond!() will wrap a given identifier in the call!() macro.
+    named!( tag_abcd, tag!("abcd") );
+    let f_true: Box<Fn(&'static [u8]) -> IResult<&[u8],Option<&[u8]>, &str>> = Box::new(closure!(&'static [u8], cond!( true, tag_abcd ) ));
+    let f_false: Box<Fn(&'static [u8]) -> IResult<&[u8],Option<&[u8]>, &str>> = Box::new(closure!(&'static [u8], cond!( false, tag_abcd ) ));
+    //let f_false = closure!(&'static [u8], cond!( b2, tag!("abcd") ) );
+
+    assert_eq!(f_true(&b"abcdef"[..]), Done(&b"ef"[..], Some(&b"abcd"[..])));
+    assert_eq!(f_true(&b"ab"[..]), Incomplete(Needed::Size(4)));
+    assert_eq!(f_true(&b"xxx"[..]), Done(&b"xxx"[..], None));
+
+    assert_eq!(f_false(&b"abcdef"[..]), Done(&b"abcdef"[..], None));
+    assert_eq!(f_false(&b"ab"[..]), Done(&b"ab"[..], None));
+    assert_eq!(f_false(&b"xxx"[..]), Done(&b"xxx"[..], None));
+  }
+
+  #[test]
+  fn peek() {
+    named!(peek_tag<&[u8],&[u8]>, peek!(tag!("abcd")));
+
+    assert_eq!(peek_tag(&b"abcdef"[..]), Done(&b"abcdef"[..], &b"abcd"[..]));
+    assert_eq!(peek_tag(&b"ab"[..]), Incomplete(Needed::Size(4)));
+    assert_eq!(peek_tag(&b"xxx"[..]), Error(Position(ErrorKind::Tag, &b"xxx"[..])));
+  }
+
+  #[test]
+  fn pair() {
+    named!( tag_abc, tag!("abc") );
+    named!( tag_def, tag!("def") );
+    named!( pair_abc_def<&[u8],(&[u8], &[u8])>, pair!(tag_abc, tag_def) );
+
+    assert_eq!(pair_abc_def(&b"abcdefghijkl"[..]), Done(&b"ghijkl"[..], (&b"abc"[..], &b"def"[..])));
+    assert_eq!(pair_abc_def(&b"ab"[..]), Incomplete(Needed::Size(3)));
+    assert_eq!(pair_abc_def(&b"abcd"[..]), Incomplete(Needed::Size(6)));
+    assert_eq!(pair_abc_def(&b"xxx"[..]), Error(Position(ErrorKind::Tag, &b"xxx"[..])));
+    assert_eq!(pair_abc_def(&b"xxxdef"[..]), Error(Position(ErrorKind::Tag, &b"xxxdef"[..])));
+    assert_eq!(pair_abc_def(&b"abcxxx"[..]), Error(Position(ErrorKind::Tag, &b"xxx"[..])));
+  }
+
+  #[test]
+  fn separated_pair() {
+    named!( tag_abc, tag!("abc") );
+    named!( tag_def, tag!("def") );
+    named!( tag_separator, tag!(",") );
+    named!( sep_pair_abc_def<&[u8],(&[u8], &[u8])>, separated_pair!(tag_abc, tag_separator, tag_def) );
+
+    assert_eq!(sep_pair_abc_def(&b"abc,defghijkl"[..]), Done(&b"ghijkl"[..], (&b"abc"[..], &b"def"[..])));
+    assert_eq!(sep_pair_abc_def(&b"ab"[..]), Incomplete(Needed::Size(3)));
+    assert_eq!(sep_pair_abc_def(&b"abc,d"[..]), Incomplete(Needed::Size(7)));
+    assert_eq!(sep_pair_abc_def(&b"xxx"[..]), Error(Position(ErrorKind::Tag, &b"xxx"[..])));
+    assert_eq!(sep_pair_abc_def(&b"xxx,def"[..]), Error(Position(ErrorKind::Tag, &b"xxx,def"[..])));
+    assert_eq!(sep_pair_abc_def(&b"abc,xxx"[..]), Error(Position(ErrorKind::Tag, &b"xxx"[..])));
+  }
+
+  #[test]
+  fn preceded() {
+    named!( tag_abcd, tag!("abcd") );
+    named!( tag_efgh, tag!("efgh") );
+    named!( preceded_abcd_efgh<&[u8], &[u8]>, preceded!(tag_abcd, tag_efgh) );
+
+    assert_eq!(preceded_abcd_efgh(&b"abcdefghijkl"[..]), Done(&b"ijkl"[..], &b"efgh"[..]));
+    assert_eq!(preceded_abcd_efgh(&b"ab"[..]), Incomplete(Needed::Size(4)));
+    assert_eq!(preceded_abcd_efgh(&b"abcde"[..]), Incomplete(Needed::Size(8)));
+    assert_eq!(preceded_abcd_efgh(&b"xxx"[..]), Error(Position(ErrorKind::Tag, &b"xxx"[..])));
+    assert_eq!(preceded_abcd_efgh(&b"xxxxdef"[..]), Error(Position(ErrorKind::Tag, &b"xxxxdef"[..])));
+    assert_eq!(preceded_abcd_efgh(&b"abcdxxx"[..]), Error(Position(ErrorKind::Tag, &b"xxx"[..])));
+  }
+
+  #[test]
+  fn terminated() {
+    named!( tag_abcd, tag!("abcd") );
+    named!( tag_efgh, tag!("efgh") );
+    named!( terminated_abcd_efgh<&[u8], &[u8]>, terminated!(tag_abcd, tag_efgh) );
+
+    assert_eq!(terminated_abcd_efgh(&b"abcdefghijkl"[..]), Done(&b"ijkl"[..], &b"abcd"[..]));
+    assert_eq!(terminated_abcd_efgh(&b"ab"[..]), Incomplete(Needed::Size(4)));
+    assert_eq!(terminated_abcd_efgh(&b"abcde"[..]), Incomplete(Needed::Size(8)));
+    assert_eq!(terminated_abcd_efgh(&b"xxx"[..]), Error(Position(ErrorKind::Tag, &b"xxx"[..])));
+    assert_eq!(terminated_abcd_efgh(&b"xxxxdef"[..]), Error(Position(ErrorKind::Tag, &b"xxxxdef"[..])));
+    assert_eq!(terminated_abcd_efgh(&b"abcdxxxx"[..]), Error(Position(ErrorKind::Tag, &b"xxxx"[..])));
+  }
+
+  #[test]
+  fn delimited() {
+    named!( tag_abc, tag!("abc") );
+    named!( tag_def, tag!("def") );
+    named!( tag_ghi, tag!("ghi") );
+    named!( delimited_abc_def_ghi<&[u8], &[u8]>, delimited!(tag_abc, tag_def, tag_ghi) );
+
+    assert_eq!(delimited_abc_def_ghi(&b"abcdefghijkl"[..]), Done(&b"jkl"[..], &b"def"[..]));
+    assert_eq!(delimited_abc_def_ghi(&b"ab"[..]), Incomplete(Needed::Size(3)));
+    assert_eq!(delimited_abc_def_ghi(&b"abcde"[..]), Incomplete(Needed::Size(6)));
+    assert_eq!(delimited_abc_def_ghi(&b"abcdefgh"[..]), Incomplete(Needed::Size(9)));
+    assert_eq!(delimited_abc_def_ghi(&b"xxx"[..]), Error(Position(ErrorKind::Tag, &b"xxx"[..])));
+    assert_eq!(delimited_abc_def_ghi(&b"xxxdefghi"[..]), Error(Position(ErrorKind::Tag, &b"xxxdefghi"[..])));
+    assert_eq!(delimited_abc_def_ghi(&b"abcxxxghi"[..]), Error(Position(ErrorKind::Tag, &b"xxxghi"[..])));
+    assert_eq!(delimited_abc_def_ghi(&b"abcdefxxx"[..]), Error(Position(ErrorKind::Tag, &b"xxx"[..])));
+  }
+
+  #[test]
+  fn separated_list() {
+    named!(multi<&[u8],Vec<&[u8]> >, separated_list!(tag!(","), tag!("abcd")));
+    named!(multi_empty<&[u8],Vec<&[u8]> >, separated_list!(tag!(","), tag!("")));
+
+    let a = &b"abcdef"[..];
+    let b = &b"abcd,abcdef"[..];
+    let c = &b"azerty"[..];
+    let d = &b",,abc"[..];
+    let e = &b"abcd,abcd,ef"[..];
+
+    let res1 = vec![&b"abcd"[..]];
+    assert_eq!(multi(a), Done(&b"ef"[..], res1));
+    let res2 = vec![&b"abcd"[..], &b"abcd"[..]];
+    assert_eq!(multi(b), Done(&b"ef"[..], res2));
+    assert_eq!(multi(c), Done(&b"azerty"[..], Vec::new()));
+    assert_eq!(multi_empty(d), Error(Position(ErrorKind::SeparatedList, d)));
+    //let res3 = vec![&b""[..], &b""[..], &b""[..]];
+    //assert_eq!(multi_empty(d), Done(&b"abc"[..], res3));
+    let res4 = vec![&b"abcd"[..], &b"abcd"[..]];
+    assert_eq!(multi(e), Done(&b",ef"[..], res4));
+  }
+
+  #[test]
+  fn separated_nonempty_list() {
+    named!(multi<&[u8],Vec<&[u8]> >, separated_nonempty_list!(tag!(","), tag!("abcd")));
+
+    let a = &b"abcdef"[..];
+    let b = &b"abcd,abcdef"[..];
+    let c = &b"azerty"[..];
+    let d = &b"abcd,abcd,ef"[..];
+
+    let res1 = vec![&b"abcd"[..]];
+    assert_eq!(multi(a), Done(&b"ef"[..], res1));
+    let res2 = vec![&b"abcd"[..], &b"abcd"[..]];
+    assert_eq!(multi(b), Done(&b"ef"[..], res2));
+    assert_eq!(multi(c), Error(Position(ErrorKind::Tag,c)));
+    let res3 = vec![&b"abcd"[..], &b"abcd"[..]];
+    assert_eq!(multi(d), Done(&b",ef"[..], res3));
+  }
+
+  #[test]
+  fn many0() {
+    named!( tag_abcd, tag!("abcd") );
+    named!( tag_empty, tag!("") );
+    named!( multi<&[u8],Vec<&[u8]> >, many0!(tag_abcd) );
+    named!( multi_empty<&[u8],Vec<&[u8]> >, many0!(tag_empty) );
+
+    assert_eq!(multi(&b"abcdef"[..]), Done(&b"ef"[..], vec![&b"abcd"[..]]));
+    assert_eq!(multi(&b"abcdabcdefgh"[..]), Done(&b"efgh"[..], vec![&b"abcd"[..], &b"abcd"[..]]));
+    assert_eq!(multi(&b"azerty"[..]), Done(&b"azerty"[..], Vec::new()));
+    assert_eq!(multi(&b"abcdab"[..]), Incomplete(Needed::Size(8)));
+    assert_eq!(multi(&b"abcd"[..]), Done(&b""[..], vec![&b"abcd"[..]]));
+    assert_eq!(multi(&b""[..]), Done(&b""[..], Vec::new()));
+    assert_eq!(multi_empty(&b"abcdef"[..]), Error(Position(ErrorKind::Many0, &b"abcdef"[..])));
+  }
+
+  #[cfg(feature = "nightly")]
+  use test::Bencher;
+
+  #[cfg(feature = "nightly")]
+  #[bench]
+  fn many0_bench(b: &mut Bencher) {
+    named!(multi<&[u8],Vec<&[u8]> >, many0!(tag!("abcd")));
+    b.iter(|| {
+      multi(&b"abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"[..])
+    });
+  }
+
+  #[test]
+  fn many1() {
+    named!(multi<&[u8],Vec<&[u8]> >, many1!(tag!("abcd")));
+
+    let a = &b"abcdef"[..];
+    let b = &b"abcdabcdefgh"[..];
+    let c = &b"azerty"[..];
+    let d = &b"abcdab"[..];
+
+    let res1 = vec![&b"abcd"[..]];
+    assert_eq!(multi(a), Done(&b"ef"[..], res1));
+    let res2 = vec![&b"abcd"[..], &b"abcd"[..]];
+    assert_eq!(multi(b), Done(&b"efgh"[..], res2));
+    assert_eq!(multi(c), Error(Position(ErrorKind::Many1,c)));
+    assert_eq!(multi(d), Incomplete(Needed::Size(8)));
+  }
+
+  #[test]
+  fn infinite_many() {
+    fn tst(input: &[u8]) -> IResult<&[u8], &[u8]> {
+      println!("input: {:?}", input);
+      Error(Position(ErrorKind::Custom(0),input))
+    }
+
+    // should not go into an infinite loop
+    named!(multi0<&[u8],Vec<&[u8]> >, many0!(tst));
+    let a = &b"abcdef"[..];
+    assert_eq!(multi0(a), Done(a, Vec::new()));
+
+    named!(multi1<&[u8],Vec<&[u8]> >, many1!(tst));
+    let a = &b"abcdef"[..];
+    assert_eq!(multi1(a), Error(Position(ErrorKind::Many1,a)));
+  }
+
+  #[test]
+  fn many_m_n() {
+    named!(multi<&[u8],Vec<&[u8]> >, many_m_n!(2, 4, tag!("Abcd")));
+
+    let a = &b"Abcdef"[..];
+    let b = &b"AbcdAbcdefgh"[..];
+    let c = &b"AbcdAbcdAbcdAbcdefgh"[..];
+    let d = &b"AbcdAbcdAbcdAbcdAbcdefgh"[..];
+    let e = &b"AbcdAb"[..];
+
+    assert_eq!(multi(a), Error(Err::Position(ErrorKind::ManyMN,a)));
+    let res1 = vec![&b"Abcd"[..], &b"Abcd"[..]];
+    assert_eq!(multi(b), Done(&b"efgh"[..], res1));
+    let res2 = vec![&b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..]];
+    assert_eq!(multi(c), Done(&b"efgh"[..], res2));
+    let res3 = vec![&b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..]];
+    assert_eq!(multi(d), Done(&b"Abcdefgh"[..], res3));
+    assert_eq!(multi(e), Incomplete(Needed::Size(8)));
+  }
+
+  #[test]
+  fn count() {
+    const TIMES: usize = 2;
+    named!( tag_abc, tag!("abc") );
+    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::Unknown));
+    assert_eq!(cnt_2(&b"abcab"[..]), Incomplete(Needed::Unknown));
+    assert_eq!(cnt_2(&b"xxx"[..]), Error(Position(ErrorKind::Count, &b"xxx"[..])));
+    assert_eq!(cnt_2(&b"xxxabcabcdef"[..]), Error(Position(ErrorKind::Count, &b"xxxabcabcdef"[..])));
+    assert_eq!(cnt_2(&b"abcxxxabcdef"[..]), Error(Position(ErrorKind::Count, &b"abcxxxabcdef"[..])));
+  }
+
+  #[test]
+  fn count_zero() {
+    const TIMES: usize = 0;
+    named!( tag_abc, tag!("abc") );
+    named!( counter_2<&[u8], Vec<&[u8]> >, count!(tag_abc, TIMES ) );
+
+    let done = &b"abcabcabcdef"[..];
+    let parsed_done = Vec::new();
+    let rest = done;
+    let incomplete_1 = &b"ab"[..];
+    let parsed_incompl_1 = Vec::new();
+    let incomplete_2 = &b"abcab"[..];
+    let parsed_incompl_2 = Vec::new();
+    let error = &b"xxx"[..];
+    let error_remain = &b"xxx"[..];
+    let parsed_err = Vec::new();
+    let error_1 = &b"xxxabcabcdef"[..];
+    let parsed_err_1 = Vec::new();
+    let error_1_remain = &b"xxxabcabcdef"[..];
+    let error_2 = &b"abcxxxabcdef"[..];
+    let parsed_err_2 = Vec::new();
+    let error_2_remain = &b"abcxxxabcdef"[..];
+
+    assert_eq!(counter_2(done), Done(rest, parsed_done));
+    assert_eq!(counter_2(incomplete_1), Done(incomplete_1, parsed_incompl_1));
+    assert_eq!(counter_2(incomplete_2), Done(incomplete_2, parsed_incompl_2));
+    assert_eq!(counter_2(error), Done(error_remain, parsed_err));
+    assert_eq!(counter_2(error_1), Done(error_1_remain, parsed_err_1));
+    assert_eq!(counter_2(error_2), Done(error_2_remain, parsed_err_2));
+  }
+
+  #[test]
+  fn count_fixed() {
+    const TIMES: usize = 2;
+    named!( tag_abc, tag!("abc") );
+    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::Unknown));
+    assert_eq!(cnt_2(&b"abcab"[..]), Incomplete(Needed::Unknown));
+    assert_eq!(cnt_2(&b"xxx"[..]), Error(Position(ErrorKind::Count, &b"xxx"[..])));
+    assert_eq!(cnt_2(&b"xxxabcabcdef"[..]), Error(Position(ErrorKind::Count, &b"xxxabcabcdef"[..])));
+    assert_eq!(cnt_2(&b"abcxxxabcdef"[..]), Error(Position(ErrorKind::Count, &b"abcxxxabcdef"[..])));
+  }
+
+  use nom::{le_u16,eof};
+  #[allow(dead_code)]
+  pub fn compile_count_fixed(input: &[u8]) -> IResult<&[u8], ()> {
+    chain!(input,
+      tag!("abcd")                   ~
+      count_fixed!( u16, le_u16, 4 ) ~
+      eof                            ,
+      || { () }
+    )
+  }
+
+  #[test]
+  fn count_fixed_no_type() {
+    const TIMES: usize = 2;
+    named!( tag_abc, tag!("abc") );
+    named!( counter_2<&[u8], [&[u8]; TIMES], () >, count_fixed!(&[u8], tag_abc, TIMES ) );
+
+    let done = &b"abcabcabcdef"[..];
+    let parsed_main = [&b"abc"[..], &b"abc"[..]];
+    let rest = &b"abcdef"[..];
+    let incomplete_1 = &b"ab"[..];
+    let incomplete_2 = &b"abcab"[..];
+    let error = &b"xxx"[..];
+    let error_1 = &b"xxxabcabcdef"[..];
+    let error_1_remain = &b"xxxabcabcdef"[..];
+    let error_2 = &b"abcxxxabcdef"[..];
+    let error_2_remain = &b"abcxxxabcdef"[..];
+
+    assert_eq!(counter_2(done), Done(rest, parsed_main));
+    assert_eq!(counter_2(incomplete_1), Incomplete(Needed::Unknown));
+    assert_eq!(counter_2(incomplete_2), Incomplete(Needed::Unknown));
+    assert_eq!(counter_2(error), Error(Position(ErrorKind::Count, error)));
+    assert_eq!(counter_2(error_1), Error(Position(ErrorKind::Count, error_1_remain)));
+    assert_eq!(counter_2(error_2), Error(Position(ErrorKind::Count, error_2_remain)));
+  }
+
+  use nom::{be_u8,be_u16};
+  #[test]
+  fn length_value_test() {
+    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));
+
+    let i1 = vec![0, 5, 6];
+    assert_eq!(length_value_1(&i1), IResult::Done(&i1[1..], vec![]));
+    assert_eq!(length_value_2(&i1), IResult::Done(&i1[1..], vec![]));
+
+    let i2 = vec![1, 5, 6, 3];
+    assert_eq!(length_value_1(&i2), IResult::Done(&i2[3..], vec![1286]));
+    assert_eq!(length_value_2(&i2), IResult::Done(&i2[3..], vec![1286]));
+
+    let i3 = vec![2, 5, 6, 3, 4, 5, 7];
+    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]));
+
+    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)));
+
+    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)));
+  }
+
+  #[test]
+  fn fold_many0() {
+    fn fold_into_vec<T>(mut acc: Vec<T>, item: T) -> Vec<T> {
+      acc.push(item);
+      acc
+    };
+    named!( tag_abcd, tag!("abcd") );
+    named!( tag_empty, tag!("") );
+    named!( multi<&[u8],Vec<&[u8]> >, fold_many0!(tag_abcd, Vec::new(), fold_into_vec) );
+    named!( multi_empty<&[u8],Vec<&[u8]> >, fold_many0!(tag_empty, Vec::new(), fold_into_vec) );
+
+    assert_eq!(multi(&b"abcdef"[..]), Done(&b"ef"[..], vec![&b"abcd"[..]]));
+    assert_eq!(multi(&b"abcdabcdefgh"[..]), Done(&b"efgh"[..], vec![&b"abcd"[..], &b"abcd"[..]]));
+    assert_eq!(multi(&b"azerty"[..]), Done(&b"azerty"[..], Vec::new()));
+    assert_eq!(multi(&b"abcdab"[..]), Incomplete(Needed::Size(8)));
+    assert_eq!(multi(&b"abcd"[..]), Done(&b""[..], vec![&b"abcd"[..]]));
+    assert_eq!(multi(&b""[..]), Done(&b""[..], Vec::new()));
+    assert_eq!(multi_empty(&b"abcdef"[..]), Error(Position(ErrorKind::Many0, &b"abcdef"[..])));
+  }
+
+  #[test]
+  fn fold_many1() {
+    fn fold_into_vec<T>(mut acc: Vec<T>, item: T) -> Vec<T> {
+      acc.push(item);
+      acc
+    };
+    named!(multi<&[u8],Vec<&[u8]> >, fold_many1!(tag!("abcd"), Vec::new(), fold_into_vec));
+
+    let a = &b"abcdef"[..];
+    let b = &b"abcdabcdefgh"[..];
+    let c = &b"azerty"[..];
+    let d = &b"abcdab"[..];
+
+    let res1 = vec![&b"abcd"[..]];
+    assert_eq!(multi(a), Done(&b"ef"[..], res1));
+    let res2 = vec![&b"abcd"[..], &b"abcd"[..]];
+    assert_eq!(multi(b), Done(&b"efgh"[..], res2));
+    assert_eq!(multi(c), Error(Position(ErrorKind::Many1,c)));
+    assert_eq!(multi(d), Incomplete(Needed::Size(8)));
+  }
+
+  #[test]
+  fn fold_many_m_n() {
+    fn fold_into_vec<T>(mut acc: Vec<T>, item: T) -> Vec<T> {
+      acc.push(item);
+      acc
+    };
+    named!(multi<&[u8],Vec<&[u8]> >, fold_many_m_n!(2, 4, tag!("Abcd"), Vec::new(), fold_into_vec));
+
+    let a = &b"Abcdef"[..];
+    let b = &b"AbcdAbcdefgh"[..];
+    let c = &b"AbcdAbcdAbcdAbcdefgh"[..];
+    let d = &b"AbcdAbcdAbcdAbcdAbcdefgh"[..];
+    let e = &b"AbcdAb"[..];
+
+    assert_eq!(multi(a), Error(Err::Position(ErrorKind::ManyMN,a)));
+    let res1 = vec![&b"Abcd"[..], &b"Abcd"[..]];
+    assert_eq!(multi(b), Done(&b"efgh"[..], res1));
+    let res2 = vec![&b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..]];
+    assert_eq!(multi(c), Done(&b"efgh"[..], res2));
+    let res3 = vec![&b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..], &b"Abcd"[..]];
+    assert_eq!(multi(d), Done(&b"Abcdefgh"[..], res3));
+    assert_eq!(multi(e), Incomplete(Needed::Size(8)));
+  }
+
+  #[test]
+  fn chain_incomplete() {
+    let res = chain!(&b"abcdefgh"[..],
+      a: take!(4) ~
+      b: take!(8),
+      ||{(a,b )}
+    );
+
+    assert_eq!(res, IResult::Incomplete(Needed::Size(12)));
+  }
+
+  #[test]
+  fn tuple_test() {
+    named!(tuple_3<&[u8], (u16, &[u8], &[u8]) >,
+    tuple!( be_u16 , take!(3), tag!("fg") ) );
+
+    assert_eq!(tuple_3(&b"abcdefgh"[..]), Done(&b"h"[..], (0x6162u16, &b"cde"[..], &b"fg"[..])));
+    assert_eq!(tuple_3(&b"abcd"[..]), Incomplete(Needed::Size(5)));
+    assert_eq!(tuple_3(&b"abcde"[..]), Incomplete(Needed::Size(7)));
+    assert_eq!(tuple_3(&b"abcdejk"[..]), Error(Position(ErrorKind::Tag, &b"jk"[..])));
+  }
+  
+  #[test]
+  fn not() {
+    named!(not_aaa, not!(tag!("aaa")));
+    assert_eq!(not_aaa(&b"aaa"[..]), Error(Position(ErrorKind::Not, &b"aaa"[..])));
+    assert_eq!(not_aaa(&b"aa"[..]), Done(&b"aa"[..], &b""[..]));
+    assert_eq!(not_aaa(&b"abcd"[..]), Done(&b"abcd"[..], &b""[..]));
+  }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/nom-1.2.4/src/methods.rs
@@ -0,0 +1,480 @@
+//! Method macro combinators
+//!
+//! These macros make parsers as methods of structs
+//! and that can take methods of structs to call
+//! as parsers.
+//!
+//! There is a trick to make them easier to assemble,
+//! combinators are defined like this:
+//!
+//! ```ignore
+//! macro_rules! tag (
+//!   ($i:expr, $inp: expr) => (
+//!     {
+//!       ...
+//!     }
+//!   );
+//! );
+//! ```
+//!
+//! But when used as methods in other combinators, are used
+//! like this:
+//!
+//! ```ignore
+//! method!(my_function<Parser<'a> >, self, tag!("abcd"));
+//! ```
+//!
+//! Internally, other combinators will rewrite
+//! that call to pass the input as second argument:
+//!
+//! ```ignore
+//! macro_rules! method (
+//!   ($name:ident<$a:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => (
+//!     fn $name( $self_: $a, i: &[u8] ) -> $crate::IResult<&[u8], &[u8]> {
+//!       $submac!(i, $($args)*)
+//!     }
+//!   );
+//! );
+//! ```
+//! 
+//! The `method!` macro is similar to the `named!` macro in the macros module.
+//! While `named!` will create a parser function, `method!` will create a parser
+//! method on the struct it is defined in.
+//!
+//! Compared to the `named!` macro there are a few differences in how they are
+//! invoked. A `method!` invocation always has to have the type of `self`
+//! declared and it can't be a reference due to Rust's borrow lifetime
+//! restrictions:
+//! ```ignore
+//! //                  -`self`'s type-
+//! method!(method_name<  Parser<'a> >, ...);
+//! ```
+//! `self`'s type always comes first.
+//! The next difference is you have to input the self struct. Due to Rust's
+//! macro hygiene the macro can't declare it on it's own.
+//! ```ignore
+//! //                                                 -self-
+//! method!(method_name<Parser<'a>, &'a str, &'a str>, self, ...);
+//! ```
+//! When making a parsing struct with parsing methods, due to the static borrow
+//! checker,calling any parsing methods on self (or any other parsing struct)
+//! will cause self to be moved for the rest of the method.To get around this
+//! restriction all self is moved into the called method and then the called
+//! method will return self to the caller.
+//! 
+//! To call a method on self you need to use the `call_m!` macro. For example:
+//! ```ignore
+//! struct<'a> Parser<'a> {
+//!   parsed: &'a str,
+//! }
+//! impl<'a> Parser<'a> {
+//!   // Constructor omitted for brevity
+//!   method!(take4<Parser<'a>, &'a str, &'a str>, self, take!(4));
+//!   method!(caller<Parser<'a>, &'a str, &'a str>, self, call_m!(self.take4));
+//! }
+//! ```
+//! More complicated combinations still mostly look the same as their `named!`
+//! counterparts:
+//! ```ignore
+//!    method!(pub simple_chain<&mut Parser<'a>, &'a str, &'a str>, self,
+//!      chain!(
+//!             call_m!(self.tag_abc)      ~
+//!             call_m!(self.tag_def)      ~
+//!             call_m!(self.tag_ghi)      ~
+//!       last: call_m!(self.simple_peek)  ,
+//!        ||{sb.parsed = last; last}
+//!      )
+//!    );
+//! ```
+//! The three additions to method definitions to remember are:
+//! 1. Specify `self`'s type
+//! 2. Pass `self` to the macro
+//! 4. Call parser methods using the `call_m!` macro.
+
+/// Makes a method from a parser combination
+///
+/// The must be set up because the compiler needs
+/// the information
+///
+/// ```ignore
+/// method!(my_function<Parser<'a> >( &[u8] ) -> &[u8], tag!("abcd"));
+/// // first type parameter is `self`'s type, second is input, third is output
+/// method!(my_function<Parser<'a>, &[u8], &[u8]>,     tag!("abcd"));
+/// //prefix them with 'pub' to make the methods public
+/// method!(pub my_function<Parser<'a>,&[u8], &[u8]>, tag!("abcd"));
+/// ```
+#[macro_export]
+macro_rules! method (
+  // Non-public immutable self
+  ($name:ident<$a:ty>( $i:ty ) -> $o:ty, $self_:ident, $submac:ident!( $($args:tt)* )) => (
+      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)* )) => (
+    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)* )) => (
+    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)* )) => (
+      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)* )) => (
+      fn $name( $self_: $a, i: &[u8] ) -> ($a, $crate::IResult<&[u8], &[u8], u32>) {
+        let result = $submac!(i, $($args)*);
+        ($self_, result)
+      }
+  );
+  // Public immutable self
+  (pub $name:ident<$a:ty>( $i:ty ) -> $o:ty, $self_:ident, $submac:ident!( $($args:tt)* )) => (
+      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)* )) => (
+      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)* )) => (
+    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)* )) => (
+    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)* )) => (
+    pub fn $name( $self_: $a, i: &[u8] ) -> ($a, $crate::IResult<&[u8], &[u8], u32>) {
+      let result = $submac!(i, $($args)*);
+      ($self_, result)
+    }
+  );
+  // Non-public mutable self
+  ($name:ident<$a:ty>( $i:ty ) -> $o:ty, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
+      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)* )) => (
+      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)* )) => (
+    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)* )) => (
+      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)* )) => (
+      fn $name( mut $self_: $a, i: &[u8] ) -> ($a, $crate::IResult<&[u8], &[u8], u32>) {
+        let result = $submac!(i, $($args)*);
+        ($self_, result)
+      }
+  );
+  // Public mutable self
+  (pub $name:ident<$a:ty>( $i:ty ) -> $o:ty, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
+      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)* )) => (
+      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)* )) => (
+    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)* )) => (
+    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)* )) => (
+    pub fn $name( mut $self_: $a, i: &[u8] ) -> ($a, $crate::IResult<&[u8], &[u8], u32>) {
+      let result = $submac!(i, $($args)*);
+      ($self_, result)
+    }
+  );
+);
+
+/// Used to called methods then move self back into self
+#[macro_export]
+macro_rules! call_m (
+  ($i:expr, $self_:ident.$method:ident) => (
+    {
+      let (tmp, res) = $self_.$method($i);
+      $self_ = tmp;
+      res
+    }
+  );
+  ($i:expr, $self_:ident.$method:ident, $($args:expr),* ) => (
+    {
+      let (tmp, res) = $self_.$method($i, $($args),*);
+      $self_ = tmp;
+      res
+    }
+  );
+);
+
+
+/// 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]
+macro_rules! apply_m (
+  ($i:expr, $self_:ident.$method:ident, $($args:expr),* ) => ( { let (tmp, res) = $self_.$method( $i, $($args),* ); $self_ = tmp; res } );
+);
+
+#[cfg(test)]
+mod tests {
+  use internal::IResult::*;
+
+  // reproduce the tag_s and take_s macros, because of module import order
+  macro_rules! tag_s (
+    ($i:expr, $tag: expr) => (
+      {
+        let res: $crate::IResult<_,_> = if $tag.len() > $i.len() {
+          $crate::IResult::Incomplete($crate::Needed::Size($tag.len()))
+        //} else if &$i[0..$tag.len()] == $tag {
+        } else if ($i).starts_with($tag) {
+          $crate::IResult::Done(&$i[$tag.len()..], &$i[0..$tag.len()])
+        } else {
+          $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::TagStr, $i))
+        };
+        res
+      }
+    );
+  );
+
+  macro_rules! take_s (
+    ($i:expr, $count:expr) => (
+      {
+        let cnt = $count as usize;
+        let res: $crate::IResult<_,_> = if $i.chars().count() < cnt {
+          $crate::IResult::Incomplete($crate::Needed::Size(cnt))
+        } else {
+          let mut offset = $i.len();
+          let mut count = 0;
+          for (o, _) in $i.char_indices() {
+            if count == cnt {
+              offset = o;
+              break;
+            }
+            count += 1;
+          }
+          $crate::IResult::Done(&$i[offset..], &$i[..offset])
+        };
+        res
+      }
+    );
+  );
+
+  struct Parser<'a> {
+    bcd: &'a str,
+  }
+
+  impl<'a> Parser<'a> {
+    pub fn new() -> Parser<'a> {
+      Parser{bcd: ""}
+    }
+
+    method!(tag_abc<Parser<'a>, &'a str, &'a str>, self, tag_s!("áβç"));
+    method!(tag_bcd<Parser<'a> >(&'a str) -> &'a str, self, tag_s!("βçδ"));
+    method!(pub tag_hij<Parser<'a> >(&'a str) -> &'a str, self, tag_s!("λïJ"));
+    method!(pub tag_ijk<Parser<'a>, &'a str, &'a str>, self, tag_s!("ïJƙ"));
+    method!(take3<Parser<'a>, &'a str, &'a str>, self, take_s!(3));
+    method!(pub simple_call<Parser<'a>, &'a str, &'a str>, mut self,
+      call_m!(self.tag_abc)
+    );
+    method!(pub simple_peek<Parser<'a>, &'a str, &'a str>, mut self,
+      peek!(call_m!(self.take3))
+    );
+    method!(pub simple_chain<Parser<'a>, &'a str, &'a str>, mut self,
+      chain!(
+         bcd:  call_m!(self.tag_bcd)      ~
+         last: call_m!(self.simple_peek)  ,
+         ||{self.bcd = bcd; last}
+      )
+    );
+    fn tag_stuff(mut self: Parser<'a>, input: &'a str, something: &'a str) -> (Parser<'a>, ::IResult<&'a str, &'a str>) {
+      self.bcd = something;
+      let(tmp, res) = self.tag_abc(input);
+      self = tmp;
+      (self, res)
+    }
+    method!(use_apply<Parser<'a>, &'a str, &'a str>, mut self, apply_m!(self.tag_stuff, "βçδ"));
+  }
+
+  #[test]
+  fn test_method_call_abc() {
+    let p = Parser::new();
+    let input: &str = "áβçδèƒϱλïJƙ";
+    let consumed: &str = "áβç";
+    let leftover: &str = "δèƒϱλïJƙ";
+    let(_, res) = p.tag_abc(input);
+    match res {
+      Done(extra, output) => { assert!(extra == leftover, "`Parser.tag_abc` consumed leftover input. leftover: {}", extra);
+                               assert!(output == consumed, "`Parser.tag_abc` doesnt return the string it consumed \
+                                on success. Expected `{}`, got `{}`.", consumed, output);
+                             },
+      other => panic!("`Parser.tag_abc` didn't succeed when it should have. \
+                             Got `{:?}`.", other),
+    }
+  }
+
+  #[test]
+  fn test_method_call_bcd() {
+    let p = Parser::new();
+    let input: &str = "βçδèƒϱλïJƙ";
+    let consumed: &str = "βçδ";
+    let leftover: &str = "èƒϱλïJƙ";
+    let(_, res) = p.tag_bcd(input);
+    match res {
+      Done(extra, output) => { assert!(extra == leftover, "`Parser.tag_bcd` consumed leftover input. leftover: {}", extra);
+                               assert!(output == consumed, "`Parser.tag_bcd` doesn't return the string it consumed \
+                                on success. Expected `{}`, got `{}`.", consumed, output);
+                             },
+      other => panic!("`Parser.tag_bcd` didn't succeed when it should have. \
+                             Got `{:?}`.", other),
+    }
+  }
+
+  #[test]
+  fn test_method_call_hij() {
+    let p = Parser::new();
+    let input: &str = "λïJƙℓ₥ñôƥ9řƨ";
+    let consumed: &str = "λïJ";
+    let leftover: &str = "ƙℓ₥ñôƥ9řƨ";
+    let(_, res) = p.tag_hij(input);
+    match res {
+      Done(extra, output) => { assert!(extra == leftover, "`Parser.tag_hij` consumed leftover input. leftover: {}", extra);
+                               assert!(output == consumed, "`Parser.tag_hij` doesn't return the string it consumed \
+                                on success. Expected `{}`, got `{}`.", consumed, output);
+                             },
+      other => panic!("`Parser.tag_hij` didn't succeed when it should have. \
+                             Got `{:?}`.", other),
+    }
+  }
+
+  #[test]
+  fn test_method_call_ijk() {
+    let p = Parser::new();
+    let input: &str = "ïJƙℓ₥ñôƥ9řƨ";
+    let consumed: &str = "ïJƙ";
+    let leftover: &str = "ℓ₥ñôƥ9řƨ";
+    let(_, res) = p.tag_ijk(input);
+    match res {
+      Done(extra, output) => { assert!(extra == leftover, "`Parser.tag_ijk` consumed leftover input. leftover: {}", extra);
+                               assert!(output == consumed, "`Parser.tag_ijk` doesn't return the string it consumed \
+                                on success. Expected `{}`, got `{}`.", consumed, output);
+                             },
+      other => panic!("`Parser.tag_ijk` didn't succeed when it should have. \
+                             Got `{:?}`.", other),
+    }
+  }
+  #[test]
+  fn test_method_simple_call() {
+    let p = Parser::new();
+    let input: &str = "áβçδèƒϱλïJƙ";
+    let consumed: &str = "áβç";
+    let leftover: &str = "δèƒϱλïJƙ";
+    let(_, res) = p.simple_call(input);
+    match res {
+      Done(extra, output) => { assert!(extra == leftover, "`Parser.simple_call` consumed leftover input. leftover: {}", extra);
+                               assert!(output == consumed, "`Parser.simple_call` doesn't return the string it consumed \
+                                on success. Expected `{}`, got `{}`.", consumed, output);
+                             },
+      other => panic!("`Parser.simple_call` didn't succeed when it should have. \
+                             Got `{:?}`.", other),
+    }
+  }
+
+  #[test]
+  fn test_apply_m() {
+    let mut p = Parser::new();
+    let input: &str = "áβçδèƒϱλïJƙ";
+    let consumed: &str = "áβç";
+    let leftover: &str = "δèƒϱλïJƙ";
+    let(tmp, res) = p.use_apply(input);
+    p = tmp;
+    match res {
+      Done(extra, output) => { assert!(extra == leftover, "`Parser.use_apply` consumed leftover input. leftover: {}", extra);
+                               assert!(output == consumed, "`Parser.use_apply` doesn't return the string it was supposed to \
+                                on success. Expected `{}`, got `{}`.", leftover, output);
+                               assert!(p.bcd == "βçδ", "Parser.use_apply didn't modify the parser field correctly: {}", p.bcd);
+                             },
+      other => panic!("`Parser.use_apply` didn't succeed when it should have. \
+                             Got `{:?}`.", other),
+    }
+  } 
+
+  #[test]
+  fn test_method_call_peek() {
+    let p = Parser::new();
+    let input: &str = "ж¥ƺáβçδèƒϱλïJƙ";
+    let consumed: &str = "ж¥ƺ";
+    let(_, res) = p.simple_peek(input);
+    match res {
+      Done(extra, output) => { assert!(extra == input, "`Parser.simple_peek` consumed leftover input. leftover: {}", extra);
+                               assert!(output == consumed, "`Parser.simple_peek` doesn't return the string it consumed \
+                                on success. Expected `{}`, got `{}`.", consumed, output);
+                             },
+      other => panic!("`Parser.simple_peek` didn't succeed when it should have. \
+                             Got `{:?}`.", other),
+    }
+  }
+
+  #[test]
+  fn test_method_call_chain() {
+    let mut p = Parser::new();
+    let input : &str = "βçδδèƒϱλïJƙℓ";
+    let leftover : &str = "δèƒϱλïJƙℓ";
+    let output : &str = "늟";
+    let(tmp, res) = p.simple_chain(input);
+    p = tmp;
+    match res {
+      Done(extra, out) => { assert!(extra == leftover, "`Parser.simple_chain` consumed leftover input. leftover: {}", extra);
+                               assert!(out == output, "`Parser.simple_chain` doesn't return the string it was supposed to \
+                                on success. Expected `{}`, got `{}`.", output, out);
+                               assert!(p.bcd == "βçδ", "Parser.simple_chain didn't modify the parser field correctly: {}", p.bcd);
+                             },
+      other => panic!("`Parser.simple_chain` didn't succeed when it should have. \
+                             Got `{:?}`.", other),
+    }
+  }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/nom-1.2.4/src/nom.rs
@@ -0,0 +1,950 @@
+//! Useful parser combinators
+//!
+//! A number of useful parser combinators have already been implemented.
+//! Some of them use macros, other are implemented through functions.
+//! Hopefully, the syntax will converge to onely one way in the future,
+//! but the macros system makes no promises.
+//!
+
+#[cfg(feature = "core")]
+use std::prelude::v1::*;
+use std::boxed::Box;
+
+use std::fmt::Debug;
+use internal::*;
+use internal::IResult::*;
+use internal::Err::*;
+use util::{ErrorKind,IterIndices,AsChar,InputLength};
+use std::mem::transmute;
+
+#[inline]
+pub fn tag_cl<'a,'b>(rec:&'a[u8]) ->  Box<Fn(&'b[u8]) -> IResult<&'b[u8], &'b[u8]> + 'a> {
+  Box::new(move |i: &'b[u8]| -> IResult<&'b[u8], &'b[u8]> {
+    if i.len() >= rec.len() && &i[0..rec.len()] == rec {
+      Done(&i[rec.len()..], &i[0..rec.len()])
+    } else {
+      Error(Position(ErrorKind::TagClosure, i))
+    }
+  })
+}
+
+#[cfg(not(feature = "core"))]
+#[inline]
+pub fn print<T: Debug>(input: T) -> IResult<T, ()> {
+  println!("{:?}", input);
+  Done(input, ())
+}
+
+#[inline]
+pub fn begin(input: &[u8]) -> IResult<(), &[u8]> {
+  Done((), input)
+}
+
+// FIXME: when rust-lang/rust#17436 is fixed, macros will be able to export
+// public methods
+//pub is_not!(line_ending b"\r\n")
+pub fn not_line_ending(input:&[u8]) -> IResult<&[u8], &[u8]> {
+  for (idx, item) in input.iter().enumerate() {
+    for &i in b"\r\n".iter() {
+      if *item == i {
+        return Done(&input[idx..], &input[0..idx])
+      }
+    }
+  }
+  Done(&input[input.len()..], input)
+}
+
+named!(tag_ln, tag!("\n"));
+
+/// Recognizes a line feed
+#[inline]
+pub fn line_ending(input:&[u8]) -> IResult<&[u8], &[u8]> {
+  tag_ln(input)
+}
+
+#[inline]
+pub fn is_alphabetic(chr:u8) -> bool {
+  (chr >= 0x41 && chr <= 0x5A) || (chr >= 0x61 && chr <= 0x7A)
+}
+
+#[inline]
+pub fn is_digit(chr: u8) -> bool {
+  chr >= 0x30 && chr <= 0x39
+}
+
+#[inline]
+pub fn is_hex_digit(chr: u8) -> bool {
+  (chr >= 0x30 && chr <= 0x39) ||
+  (chr >= 0x41 && chr <= 0x46) ||
+  (chr >= 0x61 && chr <= 0x66)
+}
+
+#[inline]
+pub fn is_oct_digit(chr: u8) -> bool {
+  chr >= 0x30 && chr <= 0x37
+}
+
+#[inline]
+pub fn is_alphanumeric(chr: u8) -> bool {
+  is_alphabetic(chr) || is_digit(chr)
+}
+
+#[inline]
+pub fn is_space(chr:u8) -> bool {
+  chr == ' ' as u8 || chr == '\t' as u8
+}
+
+// FIXME: when rust-lang/rust#17436 is fixed, macros will be able to export
+//pub filter!(alpha is_alphabetic)
+//pub filter!(digit is_digit)
+//pub filter!(hex_digit is_hex_digit)
+//pub filter!(oct_digit is_oct_digit)
+//pub filter!(alphanumeric is_alphanumeric)
+
+use std::ops::{Index,Range,RangeFrom};
+/// Recognizes lowercase and uppercase alphabetic characters: a-zA-Z
+pub fn alpha<'a, T: ?Sized>(input:&'a T) -> IResult<&'a T, &'a T> where
+    T:Index<Range<usize>, Output=T>+Index<RangeFrom<usize>, Output=T>,
+    &'a T: IterIndices+InputLength {
+  let input_length = input.input_len();
+  if input_length == 0 {
+    return Error(Position(ErrorKind::Alpha, input))
+  }
+
+  for (idx, item) in input.iter_indices() {
+    if ! item.is_alpha() {
+      if idx == 0 {
+        return Error(Position(ErrorKind::Alpha, input))
+      } else {
+        return Done(&input[idx..], &input[0..idx])
+      }
+    }
+  }
+  Done(&input[input_length..], input)
+}
+
+/// Recognizes numerical characters: 0-9
+pub fn digit<'a, T: ?Sized>(input:&'a T) -> IResult<&'a T, &'a T> where
+    T:Index<Range<usize>, Output=T>+Index<RangeFrom<usize>, Output=T>,
+    &'a T: IterIndices+InputLength {
+  let input_length = input.input_len();
+  if input_length == 0 {
+    return Error(Position(ErrorKind::Digit, input))
+  }
+
+  for (idx, item) in input.iter_indices() {
+    if ! item.is_0_to_9() {
+      if idx == 0 {
+        return Error(Position(ErrorKind::Digit, input))
+      } else {
+        return Done(&input[idx..], &input[0..idx])
+      }
+    }
+  }
+  Done(&input[input_length..], input)
+}
+
+/// Recognizes hexadecimal numerical characters: 0-9, A-F, a-f
+pub fn hex_digit<'a, T: ?Sized>(input:&'a T) -> IResult<&'a T, &'a T> where
+    T:Index<Range<usize>, Output=T>+Index<RangeFrom<usize>, Output=T>,
+    &'a T: IterIndices+InputLength {
+  let input_length = input.input_len();
+  if input_length == 0 {
+    return Error(Position(ErrorKind::HexDigit, input))
+  }
+
+  for (idx, item) in input.iter_indices() {
+    if ! item.is_hex_digit() {
+      if idx == 0 {
+        return Error(Position(ErrorKind::HexDigit, input))
+      } else {
+        return Done(&input[idx..], &input[0..idx])
+      }
+    }
+  }
+  Done(&input[input_length..], input)
+}
+
+/// Recognizes octal characters: 0-7
+pub fn oct_digit<'a, T: ?Sized>(input:&'a T) -> IResult<&'a T, &'a T> where
+    T:Index<Range<usize>, Output=T>+Index<RangeFrom<usize>, Output=T>,
+    &'a T: IterIndices+InputLength {
+  let input_length = input.input_len();
+  if input_length == 0 {
+    return Error(Position(ErrorKind::OctDigit, input))
+  }
+
+  for (idx, item) in input.iter_indices() {
+    if ! item.is_oct_digit() {
+      if idx == 0 {
+        return Error(Position(ErrorKind::OctDigit, input))
+      } else {
+        return Done(&input[idx..], &input[0..idx])
+      }
+    }
+  }
+  Done(&input[input_length..], input)
+}
+
+/// Recognizes numerical and alphabetic characters: 0-9a-zA-Z
+pub fn alphanumeric<'a, T: ?Sized>(input:&'a T) -> IResult<&'a T, &'a T> where
+    T:Index<Range<usize>, Output=T>+Index<RangeFrom<usize>, Output=T>,
+    &'a T: IterIndices+InputLength {
+  let input_length = input.input_len();
+  if input_length == 0 {
+    return Error(Position(ErrorKind::AlphaNumeric, input));
+  }
+
+  for (idx, item) in input.iter_indices() {
+    if ! item.is_alphanum() {
+      if idx == 0 {
+        return Error(Position(ErrorKind::AlphaNumeric, input))
+      } else {
+        return Done(&input[idx..], &input[0..idx])
+      }
+    }
+  }
+  Done(&input[input_length..], input)
+}
+
+/// Recognizes spaces and tabs
+pub fn space<'a, T: ?Sized>(input:&'a T) -> IResult<&'a T, &'a T> where
+    T:Index<Range<usize>, Output=T>+Index<RangeFrom<usize>, Output=T>,
+    &'a T: IterIndices+InputLength {
+  let input_length = input.input_len();
+  if input_length == 0 {
+    return Error(Position(ErrorKind::Space, input));
+  }
+
+  for (idx, item) in input.iter_indices() {
+    let chr = item.as_char();
+    if ! (chr == ' ' || chr == '\t')  {
+      if idx == 0 {
+        return Error(Position(ErrorKind::Space, input))
+      } else {
+        return Done(&input[idx..], &input[0..idx])
+      }
+    }
+  }
+  Done(&input[input_length..], input)
+}
+
+/// Recognizes spaces, tabs, carriage returns and line feeds
+pub fn multispace<'a, T: ?Sized>(input:&'a T) -> IResult<&'a T, &'a T> where
+    T:Index<Range<usize>, Output=T>+Index<RangeFrom<usize>, Output=T>,
+    &'a T: IterIndices+InputLength {
+  let input_length = input.input_len();
+  if input_length == 0 {
+    return Error(Position(ErrorKind::MultiSpace, input));
+  }
+
+  for (idx, item) in input.iter_indices() {
+    let chr = item.as_char();
+    if ! (chr == ' ' || chr == '\t' || chr == '\r' || chr == '\n')  {
+      if idx == 0 {
+        return Error(Position(ErrorKind::MultiSpace, input))
+      } else {
+        return Done(&input[idx..], &input[0..idx])
+      }
+    }
+  }
+  Done(&input[input_length..], input)
+}
+
+pub fn sized_buffer(input:&[u8]) -> IResult<&[u8], &[u8]> {
+  if input.is_empty() {
+    return Incomplete(Needed::Unknown)
+  }
+
+  let len = input[0] as usize;
+
+  if input.len() >= len + 1 {
+    Done(&input[len+1..], &input[1..len+1])
+  } else {
+    Incomplete(Needed::Size(1 + len))
+  }
+}
+
+pub fn length_value(input:&[u8]) -> IResult<&[u8], &[u8]> {
+  let input_len = input.len();
+  if input_len == 0 {
+    return Error(Position(ErrorKind::LengthValueFn, input))
+  }
+
+  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> {
+  if i.len() < 1 {
+    Incomplete(Needed::Size(1))
+  } else {
+    Done(&i[1..], i[0])
+  }
+}
+
+/// Recognizes big endian unsigned 2 bytes integer
+#[inline]
+pub fn be_u16(i: &[u8]) -> IResult<&[u8], u16> {
+  if i.len() < 2 {
+    Incomplete(Needed::Size(2))
+  } else {
+    let res = ((i[0] as u16) << 8) + i[1] as u16;
+    Done(&i[2..], res)
+  }
+}
+
+/// Recognizes big endian unsigned 4 bytes integer
+#[inline]
+pub fn be_u32(i: &[u8]) -> IResult<&[u8], u32> {
+  if i.len() < 4 {
+    Incomplete(Needed::Size(4))
+  } else {
+    let res = ((i[0] as u32) << 24) + ((i[1] as u32) << 16) + ((i[2] as u32) << 8) + i[3] as u32;
+    Done(&i[4..], res)
+  }
+}
+
+/// Recognizes big endian unsigned 8 bytes integer
+#[inline]
+pub fn be_u64(i: &[u8]) -> IResult<&[u8], u64> {
+  if i.len() < 8 {
+    Incomplete(Needed::Size(8))
+  } else {
+    let res = ((i[0] as u64) << 56) + ((i[1] as u64) << 48) + ((i[2] as u64) << 40) + ((i[3] as u64) << 32) +
+      ((i[4] as u64) << 24) + ((i[5] as u64) << 16) + ((i[6] as u64) << 8) + i[7] as u64;
+    Done(&i[8..], res)
+  }
+}
+
+/// Recognizes a signed 1 byte integer (equivalent to take!(1)
+#[inline]
+pub fn be_i8(i:&[u8]) -> IResult<&[u8], i8> {
+  map!(i, be_u8, | x | { x as i8 })
+}
+
+/// Recognizes big endian signed 2 bytes integer
+#[inline]
+pub fn be_i16(i:&[u8]) -> IResult<&[u8], i16> {
+  map!(i, be_u16, | x | { x as i16 })
+}
+
+/// Recognizes big endian signed 4 bytes integer
+#[inline]
+pub fn be_i32(i:&[u8]) -> IResult<&[u8], i32> {
+  map!(i, be_u32, | x | { x as i32 })
+}
+
+/// Recognizes big endian signed 8 bytes integer
+#[inline]
+pub fn be_i64(i:&[u8]) -> IResult<&[u8], i64> {
+  map!(i, be_u64, | x | { x as i64 })
+}
+
+/// Recognizes an unsigned 1 byte integer (equivalent to take!(1)
+#[inline]
+pub fn le_u8(i: &[u8]) -> IResult<&[u8], u8> {
+  if i.len() < 1 {
+    Incomplete(Needed::Size(1))
+  } else {
+    Done(&i[1..], i[0])
+  }
+}
+
+/// Recognizes little endian unsigned 2 bytes integer
+#[inline]
+pub fn le_u16(i: &[u8]) -> IResult<&[u8], u16> {
+  if i.len() < 2 {
+    Incomplete(Needed::Size(2))
+  } else {
+    let res = ((i[1] as u16) << 8) + i[0] as u16;
+    Done(&i[2..], res)
+  }
+}
+
+/// Recognizes little endian unsigned 4 bytes integer
+#[inline]
+pub fn le_u32(i: &[u8]) -> IResult<&[u8], u32> {
+  if i.len() < 4 {
+    Incomplete(Needed::Size(4))
+  } else {
+    let res = ((i[3] as u32) << 24) + ((i[2] as u32) << 16) + ((i[1] as u32) << 8) + i[0] as u32;
+    Done(&i[4..], res)
+  }
+}
+
+/// Recognizes little endian unsigned 8 bytes integer
+#[inline]
+pub fn le_u64(i: &[u8]) -> IResult<&[u8], u64> {
+  if i.len() < 8 {
+    Incomplete(Needed::Size(8))
+  } else {
+    let res = ((i[7] as u64) << 56) + ((i[6] as u64) << 48) + ((i[5] as u64) << 40) + ((i[4] as u64) << 32) +
+      ((i[3] as u64) << 24) + ((i[2] as u64) << 16) + ((i[1] as u64) << 8) + i[0] as u64;
+    Done(&i[8..], res)
+  }
+}
+
+/// Recognizes a signed 1 byte integer (equivalent to take!(1)
+#[inline]
+pub fn le_i8(i:&[u8]) -> IResult<&[u8], i8> {
+  map!(i, le_u8, | x | { x as i8 })
+}
+
+/// Recognizes little endian signed 2 bytes integer
+#[inline]
+pub fn le_i16(i:&[u8]) -> IResult<&[u8], i16> {
+  map!(i, le_u16, | x | { x as i16 })
+}
+
+/// Recognizes little endian signed 4 bytes integer
+#[inline]
+pub fn le_i32(i:&[u8]) -> IResult<&[u8], i32> {
+  map!(i, le_u32, | x | { x as i32 })
+}
+
+/// Recognizes little endian signed 8 bytes integer
+#[inline]
+pub fn le_i64(i:&[u8]) -> IResult<&[u8], i64> {
+  map!(i, le_u64, | x | { x as i64 })
+}
+
+/// if parameter is true, parse a big endian u16 integer,
+/// otherwise a little endian u16 integer
+#[macro_export]
+macro_rules! u16 ( ($i:expr, $e:expr) => ( {if $e { $crate::be_u16($i) } else { $crate::le_u16($i) } } ););
+/// if parameter is true, parse a big endian u32 integer,
+/// otherwise a little endian u32 integer
+#[macro_export]
+macro_rules! u32 ( ($i:expr, $e:expr) => ( {if $e { $crate::be_u32($i) } else { $crate::le_u32($i) } } ););
+/// if parameter is true, parse a big endian u64 integer,
+/// otherwise a little endian u64 integer
+#[macro_export]
+macro_rules! u64 ( ($i:expr, $e:expr) => ( {if $e { $crate::be_u64($i) } else { $crate::le_u64($i) } } ););
+
+/// if parameter is true, parse a big endian i16 integer,
+/// otherwise a little endian i16 integer
+#[macro_export]
+macro_rules! i16 ( ($i:expr, $e:expr) => ( {if $e { $crate::be_i16($i) } else { $crate::le_i16($i) } } ););
+/// if parameter is true, parse a big endian i32 integer,
+/// otherwise a little endian i32 integer
+#[macro_export]
+macro_rules! i32 ( ($i:expr, $e:expr) => ( {if $e { $crate::be_i32($i) } else { $crate::le_i32($i) } } ););
+/// if parameter is true, parse a big endian i64 integer,
+/// otherwise a little endian i64 integer
+#[macro_export]
+macro_rules! i64 ( ($i:expr, $e:expr) => ( {if $e { $crate::be_i64($i) } else { $crate::le_i64($i) } } ););
+
+/// Recognizes big endian 4 bytes floating point number
+#[inline]
+pub fn be_f32(input: &[u8]) -> IResult<&[u8], f32> {
+  match be_u32(input) {
+    Error(e)      => Error(e),
+    Incomplete(e) => Incomplete(e),
+    Done(i,o) => {
+      unsafe {
+        Done(i, transmute::<u32, f32>(o))
+      }
+    }
+  }
+}
+
+/// Recognizes big endian 8 bytes floating point number
+#[inline]
+pub fn be_f64(input: &[u8]) -> IResult<&[u8], f64> {
+  match be_u64(input) {
+    Error(e)      => Error(e),
+    Incomplete(e) => Incomplete(e),
+    Done(i,o) => {
+      unsafe {
+        Done(i, transmute::<u64, f64>(o))
+      }
+    }
+  }
+}
+
+/// Recognizes little endian 4 bytes floating point number
+#[inline]
+pub fn le_f32(input: &[u8]) -> IResult<&[u8], f32> {
+  match le_u32(input) {
+    Error(e)      => Error(e),
+    Incomplete(e) => Incomplete(e),
+    Done(i,o) => {
+      unsafe {
+        Done(i, transmute::<u32, f32>(o))
+      }
+    }
+  }
+}
+
+/// Recognizes little endian 8 bytes floating point number
+#[inline]
+pub fn le_f64(input: &[u8]) -> IResult<&[u8], f64> {
+  match le_u64(input) {
+    Error(e)      => Error(e),
+    Incomplete(e) => Incomplete(e),
+    Done(i,o) => {
+      unsafe {
+        Done(i, transmute::<u64, f64>(o))
+      }
+    }
+  }
+}
+
+/// Recognizes a hex-encoded integer
+#[inline]
+pub fn hex_u32(input: &[u8]) -> IResult<&[u8], u32> {
+  match is_a!(input, &b"0123456789abcdef"[..]) {
+    Error(e)    => Error(e),
+    Incomplete(e) => Incomplete(e),
+    Done(i,o) => {
+      let mut res = 0u32;
+
+      // Do not parse more than 8 characters for a u32
+      let mut remaining = i;
+      let mut parsed    = o;
+      if o.len() > 8 {
+        remaining = &input[8..];
+        parsed    = &input[..8];
+      }
+
+      for &e in parsed {
+        let digit = e as char;
+        let value = digit.to_digit(16).unwrap_or(0);
+        res = value + (res << 4);
+      }
+      Done(remaining, res)
+    }
+  }
+}
+
+/// Recognizes empty input buffers
+///
+/// useful to verify that the previous parsers used all of the input
+#[inline]
+//pub fn eof(input:&[u8]) -> IResult<&[u8], &[u8]> {
+pub fn eof<'a, T:?Sized>(input: &'a T) -> IResult<&'a T,&'a T> where
+    T:Index<Range<usize>, Output=T>+Index<RangeFrom<usize>, Output=T>,
+    &'a T: InputLength {
+  if input.input_len() == 0 {
+      Done(input, input)
+  } else {
+      Error(Position(ErrorKind::Eof, input))
+  }
+}
+
+/// Recognizes non empty buffers
+#[inline]
+pub fn non_empty<'a, T:?Sized>(input: &'a T) -> IResult<&'a T,&'a T> where
+    T:Index<Range<usize>, Output=T>+Index<RangeFrom<usize>, Output=T>,
+    &'a T: InputLength {
+  if input.input_len() == 0 {
+    Error(Position(ErrorKind::NonEmpty, input))
+  } else {
+    Done(&input[input.input_len()..], input)
+  }
+}
+
+/// Return the remaining input.
+#[inline]
+pub fn rest(input: &[u8]) -> IResult<&[u8], &[u8]> {
+    IResult::Done(&input[input.len()..], input)
+}
+
+/// Return the remaining input, for strings.
+#[inline]
+pub fn rest_s(input: &str) -> IResult<&str, &str> {
+    IResult::Done(&input[input.len()..], input)
+}
+
+#[cfg(test)]
+mod tests {
+  use super::*;
+  use internal::{Needed,IResult};
+  use internal::IResult::*;
+  use internal::Err::*;
+  use util::ErrorKind;
+
+  #[test]
+  fn tag_closure() {
+    let x = tag_cl(&b"abcd"[..]);
+    let r = x(&b"abcdabcdefgh"[..]);
+    assert_eq!(r, Done(&b"abcdefgh"[..], &b"abcd"[..]));
+
+    let r2 = x(&b"abcefgh"[..]);
+    assert_eq!(r2, Error(Position(ErrorKind::TagClosure, &b"abcefgh"[..])));
+  }
+
+  #[test]
+  fn character() {
+    let empty: &[u8] = b"";
+    let a: &[u8] = b"abcd";
+    let b: &[u8] = b"1234";
+    let c: &[u8] = b"a123";
+    let d: &[u8] = "azé12".as_bytes();
+    let e: &[u8] = b" ";
+    assert_eq!(alpha(a), Done(empty, a));
+    assert_eq!(alpha(b), Error(Position(ErrorKind::Alpha,b)));
+    assert_eq!(alpha(c), Done(&c[1..], &b"a"[..]));
+    assert_eq!(alpha(d), Done("é12".as_bytes(), &b"az"[..]));
+    assert_eq!(digit(a), Error(Position(ErrorKind::Digit,a)));
+    assert_eq!(digit(b), Done(empty, b));
+    assert_eq!(digit(c), Error(Position(ErrorKind::Digit,c)));
+    assert_eq!(digit(d), Error(Position(ErrorKind::Digit,d)));
+    assert_eq!(hex_digit(a), Done(empty, a));
+    assert_eq!(hex_digit(b), Done(empty, b));
+    assert_eq!(hex_digit(c), Done(empty, c));
+    assert_eq!(hex_digit(d), Done("zé12".as_bytes(), &b"a"[..]));
+    assert_eq!(hex_digit(e), Error(Position(ErrorKind::HexDigit,e)));
+    assert_eq!(oct_digit(a), Error(Position(ErrorKind::OctDigit,a)));
+    assert_eq!(oct_digit(b), Done(empty, b));
+    assert_eq!(oct_digit(c), Error(Position(ErrorKind::OctDigit,c)));
+    assert_eq!(oct_digit(d), Error(Position(ErrorKind::OctDigit,d)));
+    assert_eq!(alphanumeric(a), Done(empty, a));
+    assert_eq!(fix_error!(b,(), alphanumeric), Done(empty, b));
+    assert_eq!(alphanumeric(c), Done(empty, c));
+    assert_eq!(alphanumeric(d), Done("é12".as_bytes(), &b"az"[..]));
+    assert_eq!(space(e), Done(&b""[..], &b" "[..]));
+  }
+
+  #[test]
+  fn character_s() {
+    let empty = "";
+    let a     = "abcd";
+    let b     = "1234";
+    let c     = "a123";
+    let d     = "azé12";
+    let e     = " ";
+    assert_eq!(alpha(a), Done(empty, a));
+    assert_eq!(alpha(b), Error(Position(ErrorKind::Alpha,b)));
+    assert_eq!(alpha(c), Done(&c[1..], &"a"[..]));
+    assert_eq!(alpha(d), Done("12", &"azé"[..]));
+    assert_eq!(digit(a), Error(Position(ErrorKind::Digit,a)));
+    assert_eq!(digit(b), Done(empty, b));
+    assert_eq!(digit(c), Error(Position(ErrorKind::Digit,c)));
+    assert_eq!(digit(d), Error(Position(ErrorKind::Digit,d)));
+    assert_eq!(hex_digit(a), Done(empty, a));
+    assert_eq!(hex_digit(b), Done(empty, b));
+    assert_eq!(hex_digit(c), Done(empty, c));
+    assert_eq!(hex_digit(d), Done("zé12", &"a"[..]));
+    assert_eq!(hex_digit(e), Error(Position(ErrorKind::HexDigit,e)));
+    assert_eq!(oct_digit(a), Error(Position(ErrorKind::OctDigit,a)));
+    assert_eq!(oct_digit(b), Done(empty, b));
+    assert_eq!(oct_digit(c), Error(Position(ErrorKind::OctDigit,c)));
+    assert_eq!(oct_digit(d), Error(Position(ErrorKind::OctDigit,d)));
+    assert_eq!(alphanumeric(a), Done(empty, a));
+    assert_eq!(fix_error!(b,(), alphanumeric), Done(empty, b));
+    assert_eq!(alphanumeric(c), Done(empty, c));
+    assert_eq!(alphanumeric(d), Done("", &"azé12"[..]));
+    assert_eq!(space(e), Done(&""[..], &" "[..]));
+  }
+
+  use util::HexDisplay;
+  #[test]
+  fn offset() {
+    let a = &b"abcd"[..];
+    let b = &b"1234"[..];
+    let c = &b"a123"[..];
+    let d = &b" \t"[..];
+    let e = &b" \t\r\n"[..];
+    let f = &b"123abcDEF"[..];
+
+    match alpha(a) {
+        Done(i, _)  => { assert_eq!(a.offset(i) + i.len(), a.len()); }
+        _           => { panic!("wrong return type in offset test for alpha") }
+    }
+    match digit(b) {
+        Done(i, _)  => { assert_eq!(b.offset(i) + i.len(), b.len()); }
+        _           => { panic!("wrong return type in offset test for digit") }
+    }
+    match alphanumeric(c) {
+        Done(i, _)  => { assert_eq!(c.offset(i) + i.len(), c.len()); }
+        _           => { panic!("wrong return type in offset test for alphanumeric") }
+    }
+    match space(d) {
+        Done(i, _)  => { assert_eq!(d.offset(i) + i.len(), d.len()); }
+        _           => { panic!("wrong return type in offset test for space") }
+    }
+    match multispace(e) {
+        Done(i, _)  => { assert_eq!(e.offset(i) + i.len(), e.len()); }
+        _           => { panic!("wrong return type in offset test for multispace") }
+    }
+    match hex_digit(f) {
+        Done(i, _)  => { assert_eq!(f.offset(i) + i.len(), f.len()); }
+        _           => { panic!("wrong return type in offset test for hex_digit") }
+    }
+    match oct_digit(f) {
+        Done(i, _)  => { assert_eq!(f.offset(i) + i.len(), f.len()); }
+        _           => { panic!("wrong return type in offset test for oct_digit") }
+    }
+  }
+
+  #[test]
+  fn is_not() {
+    let a: &[u8] = b"ab12cd\nefgh";
+    assert_eq!(not_line_ending(a), Done(&b"\nefgh"[..], &b"ab12cd"[..]));
+
+    let b: &[u8] = b"ab12cd\nefgh\nijkl";
+    assert_eq!(not_line_ending(b), Done(&b"\nefgh\nijkl"[..], &b"ab12cd"[..]));
+
+    let c: &[u8] = b"ab12cd";
+    assert_eq!(not_line_ending(c), Done(&b""[..], c));
+  }
+
+  #[test]
+  fn buffer_with_size() {
+    let i:Vec<u8> = vec![7,8];
+    let o:Vec<u8> = vec![4,5,6];
+    //let arr:[u8; 6usize] = [3, 4, 5, 6, 7, 8];
+    let arr:[u8; 6usize] = [3, 4, 5, 6, 7, 8];
+    let res = sized_buffer(&arr[..]);
+    assert_eq!(res, Done(&i[..], &o[..]))
+  }
+
+  /*#[test]
+  fn t1() {
+    let v1:Vec<u8> = vec![1,2,3];
+    let v2:Vec<u8> = vec![4,5,6];
+    let d = Done(&v1[..], &v2[..]);
+    let res = d.flat_map(print);
+    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));
+    assert_eq!(be_i8(&[0x7f]), Done(&b""[..], 127));
+    assert_eq!(be_i8(&[0xff]), Done(&b""[..], -1));
+    assert_eq!(be_i8(&[0x80]), Done(&b""[..], -128));
+  }
+
+  #[test]
+  fn i16_tests() {
+    assert_eq!(be_i16(&[0x00, 0x00]), Done(&b""[..], 0));
+    assert_eq!(be_i16(&[0x7f, 0xff]), Done(&b""[..], 32767_i16));
+    assert_eq!(be_i16(&[0xff, 0xff]), Done(&b""[..], -1));
+    assert_eq!(be_i16(&[0x80, 0x00]), Done(&b""[..], -32768_i16));
+  }
+
+  #[test]
+  fn i32_tests() {
+    assert_eq!(be_i32(&[0x00, 0x00, 0x00, 0x00]), Done(&b""[..], 0));
+    assert_eq!(be_i32(&[0x7f, 0xff, 0xff, 0xff]), Done(&b""[..], 2147483647_i32));
+    assert_eq!(be_i32(&[0xff, 0xff, 0xff, 0xff]), Done(&b""[..], -1));
+    assert_eq!(be_i32(&[0x80, 0x00, 0x00, 0x00]), Done(&b""[..], -2147483648_i32));
+  }
+
+  #[test]
+  fn i64_tests() {
+    assert_eq!(be_i64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), Done(&b""[..], 0));
+    assert_eq!(be_i64(&[0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]), Done(&b""[..], 9223372036854775807_i64));
+    assert_eq!(be_i64(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]), Done(&b""[..], -1));
+    assert_eq!(be_i64(&[0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), Done(&b""[..], -9223372036854775808_i64));
+  }
+
+  #[test]
+  fn le_i8_tests() {
+    assert_eq!(le_i8(&[0x00]), Done(&b""[..], 0));
+    assert_eq!(le_i8(&[0x7f]), Done(&b""[..], 127));
+    assert_eq!(le_i8(&[0xff]), Done(&b""[..], -1));
+    assert_eq!(le_i8(&[0x80]), Done(&b""[..], -128));
+  }
+
+  #[test]
+  fn le_i16_tests() {
+    assert_eq!(le_i16(&[0x00, 0x00]), Done(&b""[..], 0));
+    assert_eq!(le_i16(&[0xff, 0x7f]), Done(&b""[..], 32767_i16));
+    assert_eq!(le_i16(&[0xff, 0xff]), Done(&b""[..], -1));
+    assert_eq!(le_i16(&[0x00, 0x80]), Done(&b""[..], -32768_i16));
+  }
+
+  #[test]
+  fn le_i32_tests() {
+    assert_eq!(le_i32(&[0x00, 0x00, 0x00, 0x00]), Done(&b""[..], 0));
+    assert_eq!(le_i32(&[0xff, 0xff, 0xff, 0x7f]), Done(&b""[..], 2147483647_i32));
+    assert_eq!(le_i32(&[0xff, 0xff, 0xff, 0xff]), Done(&b""[..], -1));
+    assert_eq!(le_i32(&[0x00, 0x00, 0x00, 0x80]), Done(&b""[..], -2147483648_i32));
+  }
+
+  #[test]
+  fn le_i64_tests() {
+    assert_eq!(le_i64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), Done(&b""[..], 0));
+    assert_eq!(le_i64(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f]), Done(&b""[..], 9223372036854775807_i64));
+    assert_eq!(le_i64(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]), Done(&b""[..], -1));
+    assert_eq!(le_i64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80]), Done(&b""[..], -9223372036854775808_i64));
+  }
+
+  #[test]
+  fn be_f32_tests() {
+    assert_eq!(be_f32(&[0x00, 0x00, 0x00, 0x00]), Done(&b""[..], 0_f32));
+    assert_eq!(be_f32(&[0x4d, 0x31, 0x1f, 0xd8]), Done(&b""[..], 185728392_f32));
+  }
+
+  #[test]
+  fn be_f64_tests() {
+    assert_eq!(be_f64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), Done(&b""[..], 0_f64));
+    assert_eq!(be_f64(&[0x41, 0xa6, 0x23, 0xfb, 0x10, 0x00, 0x00, 0x00]), Done(&b""[..], 185728392_f64));
+  }
+
+  #[test]
+  fn le_f32_tests() {
+    assert_eq!(le_f32(&[0x00, 0x00, 0x00, 0x00]), Done(&b""[..], 0_f32));
+    assert_eq!(le_f32(&[0xd8, 0x1f, 0x31, 0x4d]), Done(&b""[..], 185728392_f32));
+  }
+
+  #[test]
+  fn le_f64_tests() {
+    assert_eq!(le_f64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), Done(&b""[..], 0_f64));
+    assert_eq!(le_f64(&[0x00, 0x00, 0x00, 0x10, 0xfb, 0x23, 0xa6, 0x41]), Done(&b""[..], 185728392_f64));
+  }
+
+  #[test]
+  fn hex_u32_tests() {
+    assert_eq!(hex_u32(&b""[..]), Done(&b""[..], 0));
+    assert_eq!(hex_u32(&b"ff"[..]), Done(&b""[..], 255));
+    assert_eq!(hex_u32(&b"1be2"[..]), Done(&b""[..], 7138));
+    assert_eq!(hex_u32(&b"c5a31be2"[..]), Done(&b""[..], 3315801058));
+    assert_eq!(hex_u32(&b"00c5a31be2"[..]), Done(&b"e2"[..], 12952347));
+    assert_eq!(hex_u32(&b"c5a31be201"[..]), Done(&b"01"[..], 3315801058));
+    assert_eq!(hex_u32(&b"ffffffff"[..]), Done(&b""[..], 4294967295));
+    assert_eq!(hex_u32(&b"0x1be2"[..]), Done(&b"x1be2"[..], 0));
+  }
+
+    #[test]
+    fn end_of_input() {
+        let not_over = &b"Hello, world!"[..];
+        let is_over = &b""[..];
+
+        let res_not_over = eof(not_over);
+        assert_eq!(res_not_over, Error(Position(ErrorKind::Eof, not_over)));
+
+        let res_over = eof(is_over);
+        assert_eq!(res_over, Done(is_over, is_over));
+    }
+
+  #[test]
+  fn configurable_endianness() {
+    named!(be_tst16<u16>, u16!(true));
+    named!(le_tst16<u16>, u16!(false));
+    assert_eq!(be_tst16(&[0x80, 0x00]), Done(&b""[..], 32768_u16));
+    assert_eq!(le_tst16(&[0x80, 0x00]), Done(&b""[..], 128_u16));
+
+    named!(be_tst32<u32>, u32!(true));
+    named!(le_tst32<u32>, u32!(false));
+    assert_eq!(be_tst32(&[0x12, 0x00, 0x60, 0x00]), Done(&b""[..], 302014464_u32));
+    assert_eq!(le_tst32(&[0x12, 0x00, 0x60, 0x00]), Done(&b""[..], 6291474_u32));
+
+    named!(be_tst64<u64>, u64!(true));
+    named!(le_tst64<u64>, u64!(false));
+    assert_eq!(be_tst64(&[0x12, 0x00, 0x60, 0x00, 0x12, 0x00, 0x80, 0x00]), Done(&b""[..], 1297142246100992000_u64));
+    assert_eq!(le_tst64(&[0x12, 0x00, 0x60, 0x00, 0x12, 0x00, 0x80, 0x00]), Done(&b""[..], 36028874334666770_u64));
+
+    named!(be_tsti16<i16>, i16!(true));
+    named!(le_tsti16<i16>, i16!(false));
+    assert_eq!(be_tsti16(&[0x00, 0x80]), Done(&b""[..], 128_i16));
+    assert_eq!(le_tsti16(&[0x00, 0x80]), Done(&b""[..], -32768_i16));
+
+    named!(be_tsti32<i32>, i32!(true));
+    named!(le_tsti32<i32>, i32!(false));
+    assert_eq!(be_tsti32(&[0x00, 0x12, 0x60, 0x00]), Done(&b""[..], 1204224_i32));
+    assert_eq!(le_tsti32(&[0x00, 0x12, 0x60, 0x00]), Done(&b""[..], 6296064_i32));
+
+    named!(be_tsti64<i64>, i64!(true));
+    named!(le_tsti64<i64>, i64!(false));
+    assert_eq!(be_tsti64(&[0x00, 0xFF, 0x60, 0x00, 0x12, 0x00, 0x80, 0x00]), Done(&b""[..], 71881672479506432_i64));
+    assert_eq!(le_tsti64(&[0x00, 0xFF, 0x60, 0x00, 0x12, 0x00, 0x80, 0x00]), Done(&b""[..], 36028874334732032_i64));
+
+  }
+
+  #[test]
+  fn manual_configurable_endianness_test() {
+    let x = 1;
+    let int_parse: Box<Fn(&[u8]) -> IResult<&[u8], u16> > = if x == 2 {
+      Box::new(be_u16)
+    } else {
+      Box::new(le_u16)
+    };
+    println!("{:?}", int_parse(&b"3"[..]));
+    assert_eq!(int_parse(&[0x80, 0x00]), Done(&b""[..], 128_u16));
+  }
+
+  #[allow(dead_code)]
+  fn custom_error(input: &[u8]) -> IResult<&[u8], &[u8], ()> {
+    fix_error!(input, (), alphanumeric)
+  }
+
+  #[test]
+  fn hex_digit_test() {
+    let empty = &b""[..];
+
+    let i = &b"0123456789abcdefABCDEF"[..];
+    assert_eq!(hex_digit(i), Done(empty, i));
+
+    let i = &b"g"[..];
+    assert_eq!(hex_digit(i), Error(Position(ErrorKind::HexDigit,i)));
+
+    let i = &b"G"[..];
+    assert_eq!(hex_digit(i), Error(Position(ErrorKind::HexDigit,i)));
+
+    assert!(is_hex_digit(b'0'));
+    assert!(is_hex_digit(b'9'));
+    assert!(is_hex_digit(b'a'));
+    assert!(is_hex_digit(b'f'));
+    assert!(is_hex_digit(b'A'));
+    assert!(is_hex_digit(b'F'));
+    assert!(!is_hex_digit(b'g'));
+    assert!(!is_hex_digit(b'G'));
+    assert!(!is_hex_digit(b'/'));
+    assert!(!is_hex_digit(b':'));
+    assert!(!is_hex_digit(b'@'));
+    assert!(!is_hex_digit(b'\x60'));
+  }
+
+  #[test]
+  fn oct_digit_test() {
+    let empty = &b""[..];
+
+    let i = &b"01234567"[..];
+    assert_eq!(oct_digit(i), Done(empty, i));
+
+    let i = &b"8"[..];
+    assert_eq!(oct_digit(i), Error(Position(ErrorKind::OctDigit,i)));
+
+    assert!(is_oct_digit(b'0'));
+    assert!(is_oct_digit(b'7'));
+    assert!(!is_oct_digit(b'8'));
+    assert!(!is_oct_digit(b'9'));
+    assert!(!is_oct_digit(b'a'));
+    assert!(!is_oct_digit(b'A'));
+    assert!(!is_oct_digit(b'/'));
+    assert!(!is_oct_digit(b':'));
+    assert!(!is_oct_digit(b'@'));
+    assert!(!is_oct_digit(b'\x60'));
+  }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/nom-1.2.4/src/regexp.rs
@@ -0,0 +1,644 @@
+#[doc(hidden)]
+#[macro_export]
+macro_rules! regex (
+  ($re: ident, $s:expr) => (
+    lazy_static! {
+      static ref $re: ::regex::Regex = ::regex::Regex::new($s).unwrap();
+    }
+  );
+);
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! regex_bytes (
+  ($re: ident, $s:expr) => (
+    lazy_static! {
+      static ref $re: ::regex::bytes::Regex = ::regex::bytes::Regex::new($s).unwrap();
+    }
+  );
+);
+
+
+/// `re_match!(regexp) => &[T] -> IResult<&[T], &[T]>`
+/// Returns the whole input if a match is found
+///
+/// requires the `regexp` feature
+#[macro_export]
+macro_rules! re_match (
+  ($i:expr, $re:expr) => (
+    {
+      use $crate::InputLength;
+      let re = ::regex::Regex::new($re).unwrap();
+      if re.is_match($i) {
+        $crate::IResult::Done(&$i[$i.input_len()..], $i)
+      } else {
+        $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpMatch))
+      }
+    }
+  )
+);
+
+#[cfg(feature = "regexp_macros")]
+/// `re_match_static!(regexp) => &[T] -> IResult<&[T], &[T]>`
+/// Returns the whole input if a match is found. Regular expression calculated at compile time
+///
+/// requires the `regexp_macros` feature
+#[macro_export]
+macro_rules! re_match_static (
+  ($i:expr, $re:expr) => (
+    {
+      use $crate::InputLength;
+      regex!(RE, $re);
+      if RE.is_match($i) {
+        $crate::IResult::Done(&$i[$i.input_len()..], $i)
+      } else {
+        $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpMatch))
+      }
+    }
+  )
+);
+
+/// `re_bytes_match!(regexp) => &[T] -> IResult<&[T], &[T]>`
+/// Returns the whole input if a match is found
+///
+/// requires the `regexp` feature
+#[macro_export]
+macro_rules! re_bytes_match (
+  ($i:expr, $re:expr) => (
+    {
+      use $crate::InputLength;
+      let re = ::regex::bytes::Regex::new($re).unwrap();
+      if re.is_match($i) {
+        $crate::IResult::Done(&$i[$i.input_len()..], $i)
+      } else {
+        $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpMatch))
+      }
+    }
+  )
+);
+
+#[cfg(feature = "regexp_macros")]
+/// `re_bytes_match_static!(regexp) => &[T] -> IResult<&[T], &[T]>`
+/// Returns the whole input if a match is found. Regular expression calculated at compile time
+///
+/// requires the `regexp_macros` feature
+#[macro_export]
+macro_rules! re_bytes_match_static (
+  ($i:expr, $re:expr) => (
+    {
+      use $crate::InputLength;
+      regex_bytes!(RE, $re);
+      if RE.is_match($i) {
+        $crate::IResult::Done(&$i[$i.input_len()..], $i)
+      } else {
+        $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpMatch))
+      }
+    }
+  )
+);
+
+/// `re_find!(regexp) => &[T] -> IResult<&[T], &[T]>`
+/// Returns the first match
+///
+/// requires the `regexp` feature
+#[macro_export]
+macro_rules! re_find (
+  ($i:expr, $re:expr) => (
+    {
+      let re = ::regex::Regex::new($re).unwrap();
+      if let Some((begin, end)) = re.find($i) {
+        $crate::IResult::Done(&$i[end..], &$i[begin..end])
+      } else {
+        $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpFind))
+      }
+    }
+  )
+);
+
+#[cfg(feature = "regexp_macros")]
+/// `re_find_static!(regexp) => &[T] -> IResult<&[T], &[T]>`
+/// Returns the first match. Regular expression calculated at compile time
+///
+/// requires the `regexp_macros` feature
+#[macro_export]
+macro_rules! re_find_static (
+  ($i:expr, $re:expr) => (
+    {
+      regex!(RE, $re);
+      if let Some((begin, end)) = RE.find($i) {
+        $crate::IResult::Done(&$i[end..], &$i[begin..end])
+      } else {
+        $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpFind))
+      }
+    }
+
+  )
+);
+
+/// `re_bytes_find!(regexp) => &[T] -> IResult<&[T], &[T]>`
+/// Returns the first match
+///
+/// requires the `regexp` feature
+#[macro_export]
+macro_rules! re_bytes_find (
+  ($i:expr, $re:expr) => (
+    {
+      let re = ::regex::bytes::Regex::new($re).unwrap();
+      if let Some((begin, end)) = re.find($i) {
+        $crate::IResult::Done(&$i[end..], &$i[begin..end])
+      } else {
+        $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpFind))
+      }
+    }
+  )
+);
+
+#[cfg(feature = "regexp_macros")]
+/// `re_bytes_find!(regexp) => &[T] -> IResult<&[T], &[T]>`
+/// Returns the first match. Regular expression calculated at compile time
+///
+/// requires the `regexp_macros` feature
+#[macro_export]
+macro_rules! re_bytes_find_static (
+  ($i:expr, $re:expr) => (
+    {
+      regex_bytes!(RE, $re);
+      if let Some((begin, end)) = RE.find($i) {
+        $crate::IResult::Done(&$i[end..], &$i[begin..end])
+      } else {
+        $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpFind))
+      }
+    }
+
+  )
+);
+
+/// `re_matches!(regexp) => &[T] -> IResult<&[T], Vec<&[T]>>`
+/// Returns all the matched parts
+///
+/// requires the `regexp` feature
+#[macro_export]
+macro_rules! re_matches (
+  ($i:expr, $re:expr) => (
+    {
+      let re = ::regex::Regex::new($re).unwrap();
+      let v: Vec<&str> = re.find_iter($i).map(|(begin,end)| &$i[begin..end]).collect();
+      if v.len() != 0 {
+        let offset = {
+          let end = v.last().unwrap();
+          end.as_ptr() as usize + end.len() - $i.as_ptr() as usize
+        };
+        $crate::IResult::Done(&$i[offset..], v)
+      } else {
+        $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpMatches))
+      }
+    }
+  )
+);
+
+#[cfg(feature = "regexp_macros")]
+/// `re_matches_static!(regexp) => &[T] -> IResult<&[T], Vec<&[T]>>`
+/// Returns all the matched parts. Regular expression calculated at compile time
+///
+/// requires the `regexp_macros` feature
+#[macro_export]
+macro_rules! re_matches_static (
+  ($i:expr, $re:expr) => (
+    {
+      regex!(RE, $re);
+      let v: Vec<&str> = RE.find_iter($i).map(|(begin,end)| &$i[begin..end]).collect();
+      if v.len() != 0 {
+        let offset = {
+          let end = v.last().unwrap();
+          end.as_ptr() as usize + end.len() - $i.as_ptr() as usize
+        };
+        $crate::IResult::Done(&$i[offset..], v)
+      } else {
+        $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpMatches))
+      }
+    }
+  )
+);
+
+/// `re_bytes_matches!(regexp) => &[T] -> IResult<&[T], Vec<&[T]>>`
+/// Returns all the matched parts
+///
+/// requires the `regexp` feature
+#[macro_export]
+macro_rules! re_bytes_matches (
+  ($i:expr, $re:expr) => (
+    {
+      let re = ::regex::bytes::Regex::new($re).unwrap();
+      let v: Vec<&[u8]> = re.find_iter($i).map(|(begin,end)| &$i[begin..end]).collect();
+      if v.len() != 0 {
+        let offset = {
+          let end = v.last().unwrap();
+          end.as_ptr() as usize + end.len() - $i.as_ptr() as usize
+        };
+        $crate::IResult::Done(&$i[offset..], v)
+      } else {
+        $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpMatches))
+      }
+    }
+  )
+);
+
+#[cfg(feature = "regexp_macros")]
+/// `re_bytes_matches_static!(regexp) => &[T] -> IResult<&[T], Vec<&[T]>>`
+/// Returns all the matched parts. Regular expression calculated at compile time
+///
+/// requires the `regexp_macros` feature
+#[macro_export]
+macro_rules! re_bytes_matches_static (
+  ($i:expr, $re:expr) => (
+    {
+      regex_bytes!(RE, $re);
+      let v: Vec<&[u8]> = RE.find_iter($i).map(|(begin,end)| &$i[begin..end]).collect();
+      if v.len() != 0 {
+        let offset = {
+          let end = v.last().unwrap();
+          end.as_ptr() as usize + end.len() - $i.as_ptr() as usize
+        };
+        $crate::IResult::Done(&$i[offset..], v)
+      } else {
+        $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpMatches))
+      }
+    }
+  )
+);
+
+/// `re_capture!(regexp) => &[T] -> IResult<&[T], Vec<&[T]>>`
+/// Returns the first capture group
+///
+/// requires the `regexp` feature
+#[macro_export]
+macro_rules! re_capture (
+  ($i:expr, $re:expr) => (
+    {
+      let re = ::regex::Regex::new($re).unwrap();
+      if let Some(c) = re.captures($i) {
+        let v:Vec<&str> = c.iter_pos().filter(|el| el.is_some()).map(|el| el.unwrap()).map(|(begin,end)| &$i[begin..end]).collect();
+        let offset = {
+          let end = v.last().unwrap();
+          end.as_ptr() as usize + end.len() - $i.as_ptr() as usize
+        };
+        $crate::IResult::Done(&$i[offset..], v)
+      } else {
+        $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpCapture))
+      }
+    }
+  )
+);
+
+#[cfg(feature = "regexp_macros")]
+/// `re_capture_static!(regexp) => &[T] -> IResult<&[T], Vec<&[T]>>`
+/// Returns the first capture group. Regular expression calculated at compile time
+///
+/// requires the `regexp_macros` feature
+#[macro_export]
+macro_rules! re_capture_static (
+  ($i:expr, $re:expr) => (
+    {
+      regex!(RE, $re);
+      if let Some(c) = RE.captures($i) {
+        let v:Vec<&str> = c.iter_pos().filter(|el| el.is_some()).map(|el| el.unwrap()).map(|(begin,end)| &$i[begin..end]).collect();
+        let offset = {
+          let end = v.last().unwrap();
+          end.as_ptr() as usize + end.len() - $i.as_ptr() as usize
+        };
+        $crate::IResult::Done(&$i[offset..], v)
+      } else {
+        $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpCapture))
+      }
+    }
+  )
+);
+
+/// `re_bytes_capture!(regexp) => &[T] -> IResult<&[T], Vec<&[T]>>`
+/// Returns the first capture group
+///
+/// requires the `regexp` feature
+#[macro_export]
+macro_rules! re_bytes_capture (
+  ($i:expr, $re:expr) => (
+    {
+      let re = ::regex::bytes::Regex::new($re).unwrap();
+      if let Some(c) = re.captures($i) {
+        let v:Vec<&[u8]> = c.iter_pos().filter(|el| el.is_some()).map(|el| el.unwrap()).map(|(begin,end)| &$i[begin..end]).collect();
+        let offset = {
+          let end = v.last().unwrap();
+          end.as_ptr() as usize + end.len() - $i.as_ptr() as usize
+        };
+        $crate::IResult::Done(&$i[offset..], v)
+      } else {
+        $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpCapture))
+      }
+    }
+  )
+);
+
+#[cfg(feature = "regexp_macros")]
+/// `re_bytes_capture_static!(regexp) => &[T] -> IResult<&[T], Vec<&[T]>>`
+/// Returns the first capture group. Regular expression calculated at compile time
+///
+/// requires the `regexp_macros` feature
+#[macro_export]
+macro_rules! re_bytes_capture_static (
+  ($i:expr, $re:expr) => (
+    {
+      regex_bytes!(RE, $re);
+      if let Some(c) = RE.captures($i) {
+        let v:Vec<&[u8]> = c.iter_pos().filter(|el| el.is_some()).map(|el| el.unwrap()).map(|(begin,end)| &$i[begin..end]).collect();
+        let offset = {
+          let end = v.last().unwrap();
+          end.as_ptr() as usize + end.len() - $i.as_ptr() as usize
+        };
+        $crate::IResult::Done(&$i[offset..], v)
+      } else {
+        $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpCapture))
+      }
+    }
+  )
+);
+
+/// `re_captures!(regexp) => &[T] -> IResult<&[T], Vec<Vec<&[T]>>>`
+/// Returns all the capture groups
+///
+/// requires the `regexp` feature
+#[macro_export]
+macro_rules! re_captures (
+  ($i:expr, $re:expr) => (
+    {
+      let re = ::regex::Regex::new($re).unwrap();
+      let v:Vec<Vec<&str>> = re.captures_iter($i).map(|c| c.iter_pos().filter(|el| el.is_some()).map(|el| el.unwrap()).map(|(begin,end)| &$i[begin..end]).collect()).collect();
+      if v.len() != 0 {
+        let offset = {
+          let end = v.last().unwrap().last().unwrap();
+          end.as_ptr() as usize + end.len() - $i.as_ptr() as usize
+        };
+        $crate::IResult::Done(&$i[offset..], v)
+      } else {
+        $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpCapture))
+      }
+    }
+  )
+);
+
+#[cfg(feature = "regexp_macros")]
+/// `re_captures_static!(regexp) => &[T] -> IResult<&[T], Vec<Vec<&[T]>>>`
+/// Returns all the capture groups. Regular expression calculated at compile time
+///
+/// requires the `regexp_macros` feature
+#[macro_export]
+macro_rules! re_captures_static (
+  ($i:expr, $re:expr) => (
+    {
+      regex!(RE, $re);
+      let v:Vec<Vec<&str>> = RE.captures_iter($i).map(|c| c.iter_pos().filter(|el| el.is_some()).map(|el| el.unwrap()).map(|(begin,end)| &$i[begin..end]).collect()).collect();
+      if v.len() != 0 {
+        let offset = {
+          let end = v.last().unwrap().last().unwrap();
+          end.as_ptr() as usize + end.len() - $i.as_ptr() as usize
+        };
+        $crate::IResult::Done(&$i[offset..], v)
+      } else {
+        $crate::IResult::Error($crate::Err::Code($crate::ErrorKind::RegexpCapture))
+      }
+    }
+  )
+);
+
+/// `re_bytes_captures!(regexp) => &[T] -> IResult<&[T], Vec<Vec<&[T]>>>`
+/// Returns all the capture groups
+///
+/// requires the `regexp` feature
+#[macro_export]
+macro_rules! re_bytes_captures (
+  ($i:expr, $re:expr) => (
+    {
+      let re = ::regex::bytes::Regex::new($re).unwrap();