Bug 1341102 - Update vendored clap to get more consistent bitflags on a CLOSED TREE.
authorXidorn Quan <me@upsuper.org>
Thu, 01 Jun 2017 09:52:00 +1000
changeset 361690 f11d37b8446bdb8e81d5a510142c68526c978a98
parent 361689 ed1a152dba74778327420a572576d68a47821469
child 361691 5ecd65c9136b6b3c924f91679f89b9e3577c3dbc
push id31939
push usercbook@mozilla.com
push dateThu, 01 Jun 2017 11:49:28 +0000
treeherdermozilla-central@d96110d76619 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1341102
milestone55.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 1341102 - Update vendored clap to get more consistent bitflags on a CLOSED TREE. MozReview-Commit-ID: 3Km7H7yEh39
testing/geckodriver/Cargo.lock
third_party/rust/atty/.cargo-checksum.json
third_party/rust/atty/.cargo-ok
third_party/rust/atty/.gitignore
third_party/rust/atty/.travis.yml
third_party/rust/atty/CHANGELOG.md
third_party/rust/atty/Cargo.toml
third_party/rust/atty/LICENSE
third_party/rust/atty/README.md
third_party/rust/atty/appveyor.yml
third_party/rust/atty/examples/atty.rs
third_party/rust/atty/src/lib.rs
third_party/rust/bitflags/.cargo-checksum.json
third_party/rust/bitflags/.travis.yml
third_party/rust/bitflags/Cargo.toml
third_party/rust/bitflags/README.md
third_party/rust/bitflags/src/lib.rs
third_party/rust/bitflags/tests/i128_bitflags.rs
third_party/rust/clap/.cargo-checksum.json
third_party/rust/clap/CHANGELOG.md
third_party/rust/clap/CONTRIBUTORS.md
third_party/rust/clap/Cargo.toml
third_party/rust/clap/README.md
third_party/rust/clap/clap-test.rs
third_party/rust/clap/justfile
third_party/rust/clap/src/app/help.rs
third_party/rust/clap/src/app/macros.rs
third_party/rust/clap/src/app/meta.rs
third_party/rust/clap/src/app/mod.rs
third_party/rust/clap/src/app/parser.rs
third_party/rust/clap/src/app/settings.rs
third_party/rust/clap/src/app/usage.rs
third_party/rust/clap/src/app/validator.rs
third_party/rust/clap/src/args/any_arg.rs
third_party/rust/clap/src/args/arg.rs
third_party/rust/clap/src/args/arg_builder/base.rs
third_party/rust/clap/src/args/arg_builder/flag.rs
third_party/rust/clap/src/args/arg_builder/option.rs
third_party/rust/clap/src/args/arg_builder/positional.rs
third_party/rust/clap/src/args/arg_builder/switched.rs
third_party/rust/clap/src/args/arg_builder/valued.rs
third_party/rust/clap/src/args/arg_matcher.rs
third_party/rust/clap/src/args/arg_matches.rs
third_party/rust/clap/src/args/group.rs
third_party/rust/clap/src/args/matched_arg.rs
third_party/rust/clap/src/args/mod.rs
third_party/rust/clap/src/args/settings.rs
third_party/rust/clap/src/completions/bash.rs
third_party/rust/clap/src/completions/fish.rs
third_party/rust/clap/src/completions/powershell.rs
third_party/rust/clap/src/errors.rs
third_party/rust/clap/src/fmt.rs
third_party/rust/clap/src/lib.rs
third_party/rust/clap/src/macros.rs
third_party/rust/clap/src/osstringext.rs
third_party/rust/clap/src/suggestions.rs
third_party/rust/clap/src/usage_parser.rs
third_party/rust/term_size/.cargo-checksum.json
third_party/rust/term_size/CHANGELOG.md
third_party/rust/term_size/Cargo.toml
third_party/rust/term_size/README.md
third_party/rust/term_size/rustfmt.toml
third_party/rust/term_size/src/lib.rs
third_party/rust/vec_map/.cargo-checksum.json
third_party/rust/vec_map/Cargo.toml
third_party/rust/vec_map/src/lib.rs
toolkit/library/gtest/rust/Cargo.lock
toolkit/library/rust/Cargo.lock
--- a/testing/geckodriver/Cargo.lock
+++ b/testing/geckodriver/Cargo.lock
@@ -1,14 +1,14 @@
 [root]
 name = "geckodriver"
 version = "0.16.1"
 dependencies = [
  "chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "hyper 0.10.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "mozprofile 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "mozrunner 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "mozversion 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -66,17 +66,17 @@ name = "base64"
 version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "bitflags"
-version = "0.7.0"
+version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "byteorder"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -108,26 +108,25 @@ version = "0.2.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "num 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "clap"
-version = "2.20.5"
+version = "2.24.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "vec_map 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cookie"
 version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -512,17 +511,17 @@ name = "tempdir"
 version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "term_size"
-version = "0.2.3"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -623,17 +622,17 @@ version = "0.1.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "vec_map"
-version = "0.6.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "void"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -686,23 +685,23 @@ dependencies = [
 ]
 
 [metadata]
 "checksum advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "307c92332867e586720c0222ee9d890bbe8431711efed8a1b06bc5b40fc66bd7"
 "checksum aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0638fd549427caa90c499814196d1b9e3725eb4d15d7339d6de073a680ed0ca2"
 "checksum backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72f9b4182546f4b04ebc4ab7f84948953a118bd6021a1b6a6c909e3e94f6be76"
 "checksum backtrace-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d192fd129132fbc97497c1f2ec2c2c5174e376b95f535199ef4fe0a293d33842"
 "checksum base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30e93c03064e7590d0466209155251b90c22e37fab1daf2771582598b5827557"
-"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
+"checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"
 "checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8"
 "checksum bzip2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3eafc42c44e0d827de6b1c131175098fe7fb53b8ce8a47e65cb3ea94688be24"
 "checksum bzip2-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "98ce3fff84d4e90011f464bbdf48e3428f04270439f703868fd489d2aaedfc30"
 "checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
 "checksum chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9213f7cd7c27e95c2b57c49f0e69b1ea65b27138da84a170133fd21b07659c00"
-"checksum clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7db281b0520e97fbd15cd615dcd8f8bcad0c26f5f7d5effe705f090f39e9a758"
+"checksum clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b8f69e518f967224e628896b54e41ff6acfb4dcfefc5076325c36525dac900f"
 "checksum cookie 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30b3493e12a550c2f96be785088d1da8d93189e7237c8a8d0d871bc9070334c3"
 "checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97"
 "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
 "checksum flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)" = "36df0166e856739905cd3d7e0b210fe818592211a008862599845e012d8d304c"
 "checksum gcc 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "291055c78f59ca3d84c99026c9501c469413d386bb46be1e1cf1d285cd1db3b0"
 "checksum httparse 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77f756bed9ee3a83ce98774f4155b42a31b787029013f3a7d83eca714e500e21"
 "checksum hyper 0.10.10 (registry+https://github.com/rust-lang/crates.io-index)" = "36e108e0b1fa2d17491cbaac4bc460dc0956029d10ccf83c913dd0e5db3e7f07"
 "checksum idna 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2233d4940b1f19f0418c158509cd7396b8d70a5db5705ce410914dc8fa603b37"
@@ -743,30 +742,30 @@ dependencies = [
 "checksum slog 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bab9d589681f7d6b9ca4ed5cc861779a392bca7beaae2f69f2341617415a78dc"
 "checksum slog-atomic 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d6f5a4e4908d6818fe553b6126ba5377801556ab885c65ebf960b722a6778864"
 "checksum slog-extra 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "511581f4dd1dc90e4eca99b60be8a692d9c975e8757558aa774f16007d27492a"
 "checksum slog-stdlog 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "56cc08f40c45e0ab41dcfde0a19a22c5b7176d3827fc7d078450ebfdc080a37c"
 "checksum slog-stream 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3fac4af71007ddb7338f771e059a46051f18d1454d8ac556f234a0573e719daa"
 "checksum slog-term 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb53c0bae0745898fd5a7b75b1c389507333470ac4c645ae431890c0f828b6ca"
 "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
 "checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6"
-"checksum term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "07b6c1ac5b3fffd75073276bca1ceed01f67a28537097a2a9539e116e50fb21a"
+"checksum term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2b6b55df3198cc93372e85dd2ed817f0e38ce8cc0f22eb32391bfad9c4bf209"
 "checksum thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4437c97558c70d129e40629a5b385b3fb1ffac301e63941335e4d354081ec14a"
 "checksum thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c85048c6260d17cf486ceae3282d9fb6b90be220bf5b28c400f5485ffc29f0c7"
 "checksum time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "211b63c112206356ef1ff9b19355f43740fc3f85960c598a93d3a3d3ba7beade"
 "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
 "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
 "checksum unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a5906ca2b98c799f4b1ab4557b76367ebd6ae5ef14930ec841c74aed5f3764"
 "checksum unicode-bidi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a6a2c4e3710edd365cd7e78383153ed739fa31af19f9172f72d3575060f5a43a"
 "checksum unicode-normalization 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e28fa37426fceeb5cf8f41ee273faa7c82c47dc8fba5853402841e665fcd86ff"
 "checksum unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18127285758f0e2c6cf325bb3f3d138a12fee27de4f23e146cd6a179f26c2cf3"
 "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
 "checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91"
 "checksum url 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2ba3456fbe5c0098cb877cf08b92b76c3e18e0be9e47c35b487220d377d24e"
 "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
 "checksum uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "78c590b5bd79ed10aad8fb75f078a59d8db445af6c743e55c4a53227fc01c13f"
-"checksum vec_map 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cac5efe5cb0fa14ec2f84f83c701c562ee63f6dcc680861b21d65c682adfb05f"
+"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
 "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
 "checksum webdriver 0.25.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d161bc62ed766ddc0838af89f1b339ed3c8b5c3dbe8776b59731dfae7b1a6c7"
 "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
 "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
 "checksum winreg 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e63857fb213f619b4c4fff86b158285c76766aac7e7474967e92fb6dbbfeefe9"
 "checksum zip 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "c0deac03fc7d43abcf19f2c2db6bd9289f9ea3d31f350e26eb0ed8b4117983c1"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/atty/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"7a3d49ec6b768c90a70ae9c97fdcda96f90849b3e38164db8d3239f79a53c3e4",".travis.yml":"4752c993a36dc8b271f25998b2c0b34af65f82fb61f7d71d0e34612a8a7cd5b0","CHANGELOG.md":"a182831141a059342664a8aaf40b9fd7828e8004094fb42e1b17129a090899ec","Cargo.toml":"5fa1586ac82ee945f057b87c81acae6e588de2303536445b4a766028633347e0","LICENSE":"235760c32039b0a6b23207918b71c1aa5d8318ee651c0f245d290ba1f47631cf","README.md":"b23f66e15c8311e11cbc3b10bfc87a7cb10bc4d758c6a352b155127b48b970d7","appveyor.yml":"dfe3d3eddd762a3cc76174e03ea91c93f544ce7fa05fbca4975f1624757d65e4","examples/atty.rs":"1551387a71474d9ac1b5153231f884e9e05213badcfaa3494ad2cb7ea958374a","src/lib.rs":"4530fe39e123b042eb023e4cf98a81d5184d06c938d3604b002f418101beb524"},"package":"d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"}
\ No newline at end of file
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/third_party/rust/atty/.gitignore
@@ -0,0 +1,3 @@
+target
+Cargo.lock
+*.bk
new file mode 100644
--- /dev/null
+++ b/third_party/rust/atty/.travis.yml
@@ -0,0 +1,44 @@
+sudo: false
+language: rust
+matrix:
+  fast_finish: true
+  include:
+    - rust: nightly
+    - rust: beta
+    - rust: stable
+    - rust: 1.8.0
+os:
+ - linux
+ - osx
+script:
+  - cargo build
+  - cargo test
+cache:
+  apt: true
+  directories:
+  - target/debug/deps
+  - target/debug/build
+addons:
+  apt:
+    packages:
+    - libcurl4-openssl-dev
+    - libelf-dev
+    - libdw-dev
+    - binutils-dev # required for `kcov --verify`
+    - libbfd-dev # required for `kcov --verify`
+after_success: |
+  [ $TRAVIS_RUST_VERSION = stable ] &&
+  wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
+  tar xzf master.tar.gz && mkdir kcov-master/build && cd kcov-master/build && cmake .. && make && make install DESTDIR=../tmp && cd ../.. &&
+  ls target/debug &&
+  ./kcov-master/tmp/usr/local/bin/kcov --verify --coveralls-id=$TRAVIS_JOB_ID --exclude-pattern=/.cargo target/kcov target/debug/atty-* &&
+  [ $TRAVIS_BRANCH = master ] &&
+  [ $TRAVIS_PULL_REQUEST = false ] &&
+  cargo doc --no-deps &&
+  echo "<meta http-equiv=refresh content=0;url=`echo $TRAVIS_REPO_SLUG | cut -d '/' -f 2`/index.html>" > target/doc/index.html &&
+  pip install --user ghp-import &&
+  /home/travis/.local/bin/ghp-import -n target/doc &&
+  git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
+env:
+  global:
+    secure: acjXoBFG4yFklz/iW4q9PLaMmTgug0c8hOov4uiaXYjDkVGhnEePBozGc8ctKuFv2BVlwBSzvE1neE9dHcCS6il0x+G79sVTekfVN5dERja3UpwrC0/QodJuDmErIUpb6zylupPnUGq5pzZabRPNKyAnsFS5wYhLMSLxGPu4pfYdW0Eu8CEPIgPYsI6o2pfKgNpXbeizdHRLMeZCN4cbEPohO1odc+Z6WJvgKn2xEkpAcfhAuaroqGGxRtmDiJZ/JaBijAKY/O9Q3Xq1GSGOPT5lmwJSp3Fxw5dgmeX6LmN0ZODASdnEoYfoqUDUFzkCON3Sk4a7hugxlkZ7cx1tfqXxMg+0BgYIUdGQNloDJnuusWvXPBFdB2jxMsfcbrCjNsrJ8kjN6uBsW9yy0kqN7a8eOJckwh5fYRWfNta0R+BrveNXWmGp4u4aBq/85jEiHi30XKTzaEUbF0Y3cIONweWeWwBOcAvPBhO63Y07TRRe+SSk1NYm7QHGW9RsHhz89OSbaIXqn+r/o+6DZcw5XaO73DtZ62Kx48NErej9kVqcIJ6HnyvCJ/fJoT7h1ixSRI/WmS30l2S/q33Q2G4C/IZ4ZZRD/1thSltAxeA6OAUnr8ITZyW47CqOmyL1IUptrdAb9OLEedYV/QrOhcg2RJLXyP66xnItOwMp014bEp4=
new file mode 100644
--- /dev/null
+++ b/third_party/rust/atty/CHANGELOG.md
@@ -0,0 +1,25 @@
+# 0.2.2
+
+* use target specific dependencies [#11](https://github.com/softprops/atty/pull/11)
+* Add tty detection for MSYS terminals [#12](https://github.com/softprops/atty/pull/12)
+
+# 0.2.1
+
+* fix windows bug
+
+# 0.2.0
+
+* support for various stream types
+
+# 0.1.2
+
+* windows support (with automated testing)
+* automated code coverage
+
+# 0.1.1
+
+* bumped libc dep from `0.1` to `0.2`
+
+# 0.1.0
+
+* initial release
new file mode 100644
--- /dev/null
+++ b/third_party/rust/atty/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "atty"
+version = "0.2.2"
+authors = ["softprops <d.tangren@gmail.com>"]
+description = "A simple interface for querying atty"
+documentation = "http://softprops.github.io/atty"
+homepage = "https://github.com/softprops/atty"
+repository = "https://github.com/softprops/atty"
+keywords = ["terminal", "tty"]
+license = "MIT"
+
+[target.'cfg(not(windows))'.dependencies]
+libc = "0.2"
+
+[target.'cfg(windows)'.dependencies]
+kernel32-sys = "0.2"
+winapi = "0.2"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/atty/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2015-2016 Doug Tangren
+
+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.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/atty/README.md
@@ -0,0 +1,78 @@
+# atty
+
+[![Build Status](https://travis-ci.org/softprops/atty.svg?branch=master)](https://travis-ci.org/softprops/atty) [![Build status](https://ci.appveyor.com/api/projects/status/geggrsnsjsuse8cv?svg=true)](https://ci.appveyor.com/project/softprops/atty) [![Coverage Status](https://coveralls.io/repos/softprops/atty/badge.svg?branch=master&service=github)](https://coveralls.io/github/softprops/atty?branch=master) [![crates.io](http://meritbadge.herokuapp.com/atty)](https://crates.io/crates/atty)
+
+> are you or are you not a tty?
+
+
+[Api documentation](http://softprops.github.io/atty)
+
+## usage
+
+```rust
+extern crate atty;
+
+use atty::Stream;
+
+fn main() {
+  if atty::is(Stream::Stdout) {
+    println!("I'm a terminal");
+  } else {
+    println!("I'm not");
+  }
+}
+```
+
+## install
+
+Add the following to your `Cargo.toml`
+
+```toml
+[dependencies]
+atty = "0.2"
+```
+
+## testing
+
+This library has been unit tested on both unix and windows platforms (via appveyor).
+
+
+A simple example program is provided in this repo to test various tty's. By default.
+
+It prints
+
+```bash
+$ cargo run --example atty
+stdout? true
+stderr? true
+stdin? true
+```
+
+To test std in, pipe some text to the program
+
+```bash
+$ echo "test" | cargo run --example atty
+stdout? true
+stderr? true
+stdin? false
+```
+
+To test std out, pipe the program to something
+
+```bash
+$ cargo run --example atty | grep std
+stdout? false
+stderr? true
+stdin? true
+```
+
+To test std err, pipe the program to something redirecting std err
+
+```bash
+$ cargo run --example atty 2>&1 | grep std
+stdout? false
+stderr? false
+stdin? true
+```
+
+Doug Tangren (softprops) 2015
new file mode 100644
--- /dev/null
+++ b/third_party/rust/atty/appveyor.yml
@@ -0,0 +1,17 @@
+environment:
+  matrix:
+  - TARGET: nightly-x86_64-pc-windows-msvc
+  - TARGET: nightly-i686-pc-windows-msvc
+  - TARGET: nightly-x86_64-pc-windows-gnu
+  - TARGET: nightly-i686-pc-windows-gnu
+  - TARGET: 1.8.0-x86_64-pc-windows-gnu
+install:
+  - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-${env:TARGET}.exe" -FileName "rust-install.exe"
+  - ps: .\rust-install.exe /VERYSILENT /NORESTART /DIR="C:\rust" | Out-Null
+  - ps: $env:PATH="$env:PATH;C:\rust\bin"
+  - call "%VCVARS%" || ver>nul
+  - rustc -vV
+  - cargo -vV
+build: false
+test_script:
+  - cargo test --verbose
new file mode 100644
--- /dev/null
+++ b/third_party/rust/atty/examples/atty.rs
@@ -0,0 +1,9 @@
+extern crate atty;
+
+use atty::{is, Stream};
+
+fn main() {
+    println!("stdout? {}", is(Stream::Stdout));
+    println!("stderr? {}", is(Stream::Stderr));
+    println!("stdin? {}", is(Stream::Stdin));
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/atty/src/lib.rs
@@ -0,0 +1,183 @@
+//! atty is a simple utility that answers one question
+//! > is this a tty?
+//!
+//! usage is just as simple
+//!
+//! ```
+//! if atty::is(atty::Stream::Stdout) {
+//!   println!("i'm a tty")
+//! }
+//! ```
+//!
+//! ```
+//! if atty::isnt(atty::Stream::Stdout) {
+//!   println!("i'm not a tty")
+//! }
+//! ```
+
+#[cfg(windows)]
+extern crate kernel32;
+#[cfg(not(windows))]
+extern crate libc;
+#[cfg(windows)]
+extern crate winapi;
+
+#[cfg(windows)]
+use winapi::minwindef::DWORD;
+
+/// possible stream sources
+#[derive(Clone, Copy, Debug)]
+pub enum Stream {
+    Stdout,
+    Stderr,
+    Stdin,
+}
+
+/// returns true if this is a tty
+#[cfg(unix)]
+pub fn is(stream: Stream) -> bool {
+    extern crate libc;
+
+    let fd = match stream {
+        Stream::Stdout => libc::STDOUT_FILENO,
+        Stream::Stderr => libc::STDERR_FILENO,
+        Stream::Stdin => libc::STDIN_FILENO,
+    };
+    unsafe { libc::isatty(fd) != 0 }
+}
+
+/// returns true if this is a tty
+#[cfg(windows)]
+pub fn is(stream: Stream) -> bool {
+    use winapi::{
+        STD_INPUT_HANDLE as STD_INPUT,
+        STD_ERROR_HANDLE as STD_ERROR,
+        STD_OUTPUT_HANDLE as STD_OUTPUT
+    };
+
+    let (fd, others) = match stream {
+        Stream::Stdin => (STD_INPUT, [STD_ERROR, STD_OUTPUT]),
+        Stream::Stderr => (STD_ERROR, [STD_INPUT, STD_OUTPUT]),
+        Stream::Stdout => (STD_OUTPUT, [STD_INPUT, STD_ERROR]),
+    };
+    if unsafe { console_on_any(&[fd]) } {
+        // False positives aren't possible. If we got a console then
+        // we definitely have a tty on stdin.
+        return true;
+    }
+
+    // At this point, we *could* have a false negative. We can determine that
+    // this is true negative if we can detect the presence of a console on
+    // any of the other streams. If another stream has a console, then we know
+    // we're in a Windows console and can therefore trust the negative.
+    if unsafe { console_on_any(&others) } {
+        return false;
+    }
+
+    // Otherwise, we fall back to a very strange msys hack to see if we can
+    // sneakily detect the presence of a tty.
+    unsafe { msys_tty_on(fd) }
+}
+
+/// returns true if this is _not_ a tty
+pub fn isnt(stream: Stream) -> bool {
+    !is(stream)
+}
+
+/// Returns true if any of the given fds are on a console.
+#[cfg(windows)]
+unsafe fn console_on_any(fds: &[DWORD]) -> bool {
+    for &fd in fds {
+        let mut out = 0;
+        let handle = kernel32::GetStdHandle(fd);
+        if kernel32::GetConsoleMode(handle, &mut out) != 0 {
+            return true;
+        }
+    }
+    false
+}
+
+/// Returns true if there is an MSYS tty on the given handle.
+#[cfg(windows)]
+unsafe fn msys_tty_on(fd: DWORD) -> bool {
+    use std::ffi::OsString;
+    use std::mem;
+    use std::os::raw::c_void;
+    use std::os::windows::ffi::OsStringExt;
+    use std::slice;
+
+    use kernel32::GetFileInformationByHandleEx;
+    use winapi::fileapi::FILE_NAME_INFO;
+    use winapi::minwinbase::FileNameInfo;
+    use winapi::minwindef::MAX_PATH;
+
+    let size = mem::size_of::<FILE_NAME_INFO>();
+    let mut name_info_bytes = vec![0u8; size + MAX_PATH];
+    let res = GetFileInformationByHandleEx(
+        kernel32::GetStdHandle(fd),
+        FileNameInfo,
+        &mut *name_info_bytes as *mut _ as *mut c_void,
+        name_info_bytes.len() as u32);
+    if res == 0 {
+        return true;
+    }
+    let name_info: FILE_NAME_INFO =
+        *(name_info_bytes[0..size].as_ptr() as *const FILE_NAME_INFO);
+    let name_bytes =
+        &name_info_bytes[size..size + name_info.FileNameLength as usize];
+    let name_u16 = slice::from_raw_parts(
+        name_bytes.as_ptr() as *const u16, name_bytes.len() / 2);
+    let name = OsString::from_wide(name_u16)
+        .as_os_str().to_string_lossy().into_owned();
+    name.contains("msys-") || name.contains("-pty")
+}
+
+#[cfg(test)]
+mod tests {
+    use super::{is, Stream};
+
+    #[test]
+    #[cfg(windows)]
+    fn is_err() {
+        // appveyor pipes its output
+        assert!(!is(Stream::Stderr))
+    }
+
+    #[test]
+    #[cfg(windows)]
+    fn is_out() {
+        // appveyor pipes its output
+        assert!(!is(Stream::Stdout))
+    }
+
+    #[test]
+    #[cfg(windows)]
+    fn is_in() {
+        assert!(is(Stream::Stdin))
+    }
+
+    #[test]
+    #[cfg(unix)]
+    fn is_err() {
+        assert!(is(Stream::Stderr))
+    }
+
+    #[test]
+    #[cfg(unix)]
+    fn is_out() {
+        assert!(is(Stream::Stdout))
+    }
+
+    #[test]
+    #[cfg(target_os = "macos")]
+    fn is_in() {
+        // macos on travis seems to pipe its input
+        assert!(!is(Stream::Stdin))
+    }
+
+    #[test]
+    #[cfg(all(not(target_os = "macos"), unix))]
+    fn is_in() {
+        assert!(is(Stream::Stdin))
+    }
+}
--- a/third_party/rust/bitflags/.cargo-checksum.json
+++ b/third_party/rust/bitflags/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"c1e953ee360e77de57f7b02f1b7880bd6a3dc22d1a69e953c2ac2c52cc52d247",".travis.yml":"2b615144d3f4b2e63ba6ec435cc18df7d76354aa07c2a02d6c707028cc448784","Cargo.toml":"db8c2e9ea912c5f3d2d89cf4cf936c448300e356b0fb533db8875923cb135256","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"8cfbc986af45867d9e620188af2392320fe6e0d9536753ba415c94ab522f5fb5","src/lib.rs":"618ce383bb219725363fba174fc66beb4874d9682e5da953f9e3e9cb3f786d5f","tests/external.rs":"546e549ec831876a5dc272bd0537adc9e9886c6da54656c825e7bffc079e2c74","tests/external_no_std.rs":"48929f5109aabc156442d5ae2ab07b4bce5d648488bf49dba725f6ab23bcb48a"},"package":"aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"c1e953ee360e77de57f7b02f1b7880bd6a3dc22d1a69e953c2ac2c52cc52d247",".travis.yml":"793de473e858941a0d41e0c4e114373bca6b822737cdcf5ff8f36238a9b51837","Cargo.toml":"98d1298b1d79ccc587957062cf1c56712f68ee2796bed5f39c8d334133d9c562","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"1cce1c9c1fe2cf40ec1c6a0384f8cc2f0c5c40ece4acfedd64330ed95ef74e44","src/lib.rs":"006a631d800f713e2ffc74e33f65fd47505eec1b047c109e180905a9dcb7e973","tests/external.rs":"546e549ec831876a5dc272bd0537adc9e9886c6da54656c825e7bffc079e2c74","tests/external_no_std.rs":"48929f5109aabc156442d5ae2ab07b4bce5d648488bf49dba725f6ab23bcb48a","tests/i128_bitflags.rs":"fb1bf9e01f528478539c52de94e82a96b2639dc271ea242fea6ebb32dcb0f99e"},"package":"1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"}
\ No newline at end of file
--- a/third_party/rust/bitflags/.travis.yml
+++ b/third_party/rust/bitflags/.travis.yml
@@ -1,24 +1,24 @@
 language: rust
 rust:
   - stable
   - beta
   - nightly
 sudo: false
+before_script:
+  - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
 script:
   - cargo build --verbose
   - cargo test --verbose
-  - cargo doc
-after_success: |
-  [ $TRAVIS_BRANCH = master ] &&
-  [ $TRAVIS_PULL_REQUEST = false ] &&
-  [ $TRAVIS_RUST_VERSION = nightly ] &&
-  echo '<meta http-equiv=refresh content=0;url=bitflags/index.html>' > target/doc/index.html &&
-  pip install ghp-import --user $USER &&
-  $HOME/.local/bin/ghp-import -n target/doc &&
-  git push -qf https://${TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
+  - travis-cargo --only nightly test
+  - cargo doc --no-deps
+after_success:
+  - travis-cargo --only nightly doc-upload
 env:
   global:
-    secure: d+l63TtlF6cfFVDGauYRexgx4lBww4ORqqK4Vt75nWbiCbjZYsKXbcTUdhAr193nIVGiNW50A8SekM01F3EngHwHwr6u5kFleOggm+HA0kkBVeX+k2A4WCVVfYI+gth+zk99WaF8h46MA0evhx6FYDoqeyl9oqmVifI4kaqhMwc=
+    secure: "DoZ8g8iPs+X3xEEucke0Ae02JbkQ1qd1SSv/L2aQqxULmREtRcbzRauhiT+ToQO5Ft1Lul8uck14nPfs4gMr/O3jFFBhEBVpSlbkJx7eNL3kwUdp95UNroA8I43xPN/nccJaHDN6TMTD3+uajTQTje2SyzOQP+1gvdKg17kguvE="
+
+
+
 notifications:
   email:
     on_success: never
--- a/third_party/rust/bitflags/Cargo.toml
+++ b/third_party/rust/bitflags/Cargo.toml
@@ -1,13 +1,17 @@
 [package]
 
 name = "bitflags"
-version = "0.7.0"
+version = "0.8.2"
 authors = ["The Rust Project Developers"]
 license = "MIT/Apache-2.0"
 readme = "README.md"
 repository = "https://github.com/rust-lang/bitflags"
 homepage = "https://github.com/rust-lang/bitflags"
 documentation = "https://doc.rust-lang.org/bitflags"
 description = """
 A macro to generate structures which behave like bitflags.
 """
+
+[features]
+i128 = []
+unstable = ["i128"]
--- a/third_party/rust/bitflags/README.md
+++ b/third_party/rust/bitflags/README.md
@@ -8,17 +8,36 @@ A Rust macro to generate structures whic
 [Documentation](https://doc.rust-lang.org/bitflags)
 
 ## Usage
 
 Add this to your `Cargo.toml`:
 
 ```toml
 [dependencies]
-bitflags = "0.6"
+bitflags = "0.7"
 ```
 
 and this to your crate root:
 
 ```rust
 #[macro_use]
 extern crate bitflags;
 ```
+
+## 128-bit integer bitflags (nightly only)
+
+Add this to your `Cargo.toml`:
+
+```toml
+[dependencies.bitflags]
+version = "0.7"
+features = ["i128"]
+```
+
+and this to your crate root:
+
+```rust
+#![feature(i128_type)]
+
+#[macro_use]
+extern crate bitflags;
+```
--- a/third_party/rust/bitflags/src/lib.rs
+++ b/third_party/rust/bitflags/src/lib.rs
@@ -7,26 +7,38 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
 //! A typesafe bitmask flag generator.
 
 #![no_std]
 
+#![cfg_attr(feature = "i128", feature(i128_type))]
+
+// When compiled for the rustc compiler itself we want to make sure that this is
+// an unstable crate.
+#![cfg_attr(rustbuild, feature(staged_api))]
+#![cfg_attr(rustbuild, unstable(feature = "rustc_private", issue = "27812"))]
+
 #[cfg(test)]
 #[macro_use]
 extern crate std;
 
 // Re-export libstd/libcore using an alias so that the macros can work in no_std
 // crates while remaining compatible with normal crates.
 #[allow(private_in_public)]
 #[doc(hidden)]
 pub use core as __core;
 
+#[cfg(feature = "i128")]
+pub type __BitFlagsWidth = u128;
+#[cfg(not(feature = "i128"))]
+pub type __BitFlagsWidth = u64;
+
 /// The `bitflags!` macro generates a `struct` that holds a set of C-style
 /// bitmask flags. It is useful for creating typesafe wrappers for C APIs.
 ///
 /// The flags should only be defined for integer types, otherwise unexpected
 /// type errors may occur at compile time.
 ///
 /// # Example
 ///
@@ -226,52 +238,53 @@ macro_rules! bitflags {
                 // bit value of 0.
                 #[allow(dead_code)]
                 #[allow(unused_assignments)]
                 mod dummy {
                     // We can't use the real $BitFlags struct because it may be
                     // private, which prevents us from using it to define
                     // public constants.
                     pub struct $BitFlags {
-                        bits: u64,
+                        bits: $crate::__BitFlagsWidth,
                     }
                     mod real_flags {
                         use super::$BitFlags;
                         $($(#[$Flag_attr])* pub const $Flag: $BitFlags = $BitFlags {
-                            bits: super::super::$Flag.bits as u64
+                            bits: super::super::$Flag.bits as $crate::__BitFlagsWidth
                         };)+
                     }
                     // Now we define the "undefined" versions of the flags.
                     // This way, all the names exist, even if some are #[cfg]ed
                     // out.
                     $(const $Flag: $BitFlags = $BitFlags { bits: 0 };)+
 
                     #[inline]
-                    pub fn fmt(self_: u64,
+                    pub fn fmt(self_: $crate::__BitFlagsWidth,
                                f: &mut $crate::__core::fmt::Formatter)
                                -> $crate::__core::fmt::Result {
                         // Now we import the real values for the flags.
                         // Only ones that are #[cfg]ed out will be 0.
                         use self::real_flags::*;
 
                         let mut first = true;
                         $(
                             // $Flag.bits == 0 means that $Flag doesn't exist
-                            if $Flag.bits != 0 && self_ & $Flag.bits as u64 == $Flag.bits as u64 {
+                            if $Flag.bits != 0 && self_ & $Flag.bits as $crate::__BitFlagsWidth ==
+                                $Flag.bits as $crate::__BitFlagsWidth {
                                 if !first {
                                     try!(f.write_str(" | "));
                                 }
                                 first = false;
                                 try!(f.write_str(stringify!($Flag)));
                             }
                         )+
                         Ok(())
                     }
                 }
-                dummy::fmt(self.bits as u64, f)
+                dummy::fmt(self.bits as $crate::__BitFlagsWidth, f)
             }
         }
 
         #[allow(dead_code)]
         impl $BitFlags {
             /// Returns an empty set of flags.
             #[inline]
             pub fn empty() -> $BitFlags {
@@ -280,28 +293,28 @@ macro_rules! bitflags {
 
             /// Returns the set containing all flags.
             #[inline]
             pub fn all() -> $BitFlags {
                 // See above `dummy` module for why this approach is taken.
                 #[allow(dead_code)]
                 mod dummy {
                     pub struct $BitFlags {
-                        bits: u64,
+                        bits: $crate::__BitFlagsWidth,
                     }
                     mod real_flags {
                         use super::$BitFlags;
                         $($(#[$Flag_attr])* pub const $Flag: $BitFlags = $BitFlags {
-                            bits: super::super::$Flag.bits as u64
+                            bits: super::super::$Flag.bits as $crate::__BitFlagsWidth
                         };)+
                     }
                     $(const $Flag: $BitFlags = $BitFlags { bits: 0 };)+
 
                     #[inline]
-                    pub fn all() -> u64 {
+                    pub fn all() -> $crate::__BitFlagsWidth {
                         use self::real_flags::*;
                         $($Flag.bits)|+
                     }
                 }
                 $BitFlags { bits: dummy::all() as $T }
             }
 
             /// Returns the raw value of the flags currently stored.
@@ -364,16 +377,26 @@ macro_rules! bitflags {
                 self.bits &= !other.bits;
             }
 
             /// Toggles the specified flags in-place.
             #[inline]
             pub fn toggle(&mut self, other: $BitFlags) {
                 self.bits ^= other.bits;
             }
+
+            /// Inserts or removes the specified flags depending on the passed value.
+            #[inline]
+            pub fn set(&mut self, other: $BitFlags, value: bool) {
+                if value {
+                    self.insert(other);
+                } else {
+                    self.remove(other);
+                }
+            }
         }
 
         impl $crate::__core::ops::BitOr for $BitFlags {
             type Output = $BitFlags;
 
             /// Returns the union of the two sets of flags.
             #[inline]
             fn bitor(self, other: $BitFlags) -> $BitFlags {
@@ -666,16 +689,25 @@ mod tests {
         assert_eq!(e3, FlagA | FlagB);
 
         let mut m4 = AnotherSetOfFlags::empty();
         m4.toggle(AnotherSetOfFlags::empty());
         assert_eq!(m4, AnotherSetOfFlags::empty());
     }
 
     #[test]
+    fn test_set() {
+        let mut e1 = FlagA | FlagC;
+        e1.set(FlagB, true);
+        e1.set(FlagC, false);
+
+        assert_eq!(e1, FlagA | FlagB);
+    }
+
+    #[test]
     fn test_assignment_operators() {
         let mut m1 = Flags::empty();
         let e1 = FlagA | FlagC;
         // union
         m1 |= FlagA;
         assert_eq!(m1, FlagA);
         // intersection
         m1 &= e1;
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bitflags/tests/i128_bitflags.rs
@@ -0,0 +1,30 @@
+#![allow(dead_code, unused_imports)]
+#![cfg_attr(feature = "i128", feature(i128_type))]
+
+#[macro_use]
+extern crate bitflags;
+
+#[cfg(feature = "i128")]
+bitflags! {
+    /// baz
+    flags Flags128: u128 {
+        const A       = 0x0000_0000_0000_0000_0000_0000_0000_0001,
+        const B       = 0x0000_0000_0000_1000_0000_0000_0000_0000,
+        const C       = 0x8000_0000_0000_0000_0000_0000_0000_0000,
+        const ABC     = A.bits | B.bits | C.bits,
+    }
+}
+
+#[cfg(feature = "i128")]
+#[test]
+fn test_i128_bitflags() {
+    assert_eq!(ABC, A | B | C);
+    assert_eq!(A.bits, 0x0000_0000_0000_0000_0000_0000_0000_0001);
+    assert_eq!(B.bits, 0x0000_0000_0000_1000_0000_0000_0000_0000);
+    assert_eq!(C.bits, 0x8000_0000_0000_0000_0000_0000_0000_0000);
+    assert_eq!(ABC.bits, 0x8000_0000_0000_1000_0000_0000_0000_0001);
+    assert_eq!(format!("{:?}", A), "A");
+    assert_eq!(format!("{:?}", B), "B");
+    assert_eq!(format!("{:?}", C), "C");
+    assert_eq!(format!("{:?}", ABC), "A | B | C | ABC");
+}
--- a/third_party/rust/clap/.cargo-checksum.json
+++ b/third_party/rust/clap/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".clog.toml":"f691701bd51b5f311931d0d8f05fa3d78c00dda8d60f3313e21011309c736ff1",".github/CONTRIBUTING.md":"f7eff737f3aa25294802fefb233e3758a64b248781dbbf3262532d693f340a87",".github/ISSUE_TEMPLATE.md":"681afbd64b3603e3e82789ceb6841d851eaa7333caec5769173462bab1b5d82b",".gitignore":"57b1cc6deeaf68d35909201e4bb863c7dbec899ceaa17edde7b9fe64ece8c3e9",".travis.yml":"2975b3159624d4ecc4dd29577f378e9d4fa27f1991bfd5042ac3c267fb2cdd38","CHANGELOG.md":"a1e86059e19fe5dd7c674d1165d31b77d1ec71d0db2aaa43c2442c3d65301ddd","CONTRIBUTORS.md":"62c5e9edb670a0b9315970b1a635a368928cf74b1240bbf1a0dab68d8ca6d598","Cargo.toml":"166690f9a21d1ea2f0492f10b8974d5ad5238eddea9b35cd3507059abb42ba66","LICENSE-MIT":"6725d1437fc6c77301f2ff0e7d52914cf4f9509213e1078dc77d9356dbe6eac5","README.md":"229557cb90d19e7632ec23820271b4aedad872544190b2477b9b43001c937e13","appveyor.yml":"303c64c2cc84c24b3c9ac0b4cd66b98d6bb25dec7d030ed53e5cb6ab3f13ebd1","clap-test.rs":"1021e44ea7981166f988268e619410f8329db8874018f4bc880a4f74b0b8ae76","index.html":"36f9ce4465266f3af9a259444b01c4239200473cabfc848f789f75b322a3ea8f","justfile":"82c20f705bc096a391f4b7232dbf712a0d3f00f9a2229aaa674f035ad0d9650e","rustfmt.toml":"8fd2d63119df515fd5f44e530c709b19d66b09fbc2e22a640bf4b64c57e7d6b3","src/app/help.rs":"f48bfb67331df1ff72da5d404b68a6e2049203ba1a091f701dc212ab0450461b","src/app/macros.rs":"8a8e8fe466da78588affeeadacf5c2a28d00299d387fdb8081ab9314a1d0b4eb","src/app/meta.rs":"81414fb8bfb32fa809eb470f3f3deee6610bfe54205240095371708c3d037933","src/app/mod.rs":"b36db7c4a404d04e58be00d3a720b87ed071f9234937cac5e77b938ac29d4f3f","src/app/parser.rs":"7aa95d1ddaf2941329668d5bd92c4a0b96ab00b8525207a0fa630e5d633d05e5","src/app/settings.rs":"52d5482b96e9832af1f06d15f5055cfe4cfb1edca0e2bf8f7c3ac7f72e982ec9","src/args/any_arg.rs":"6b1b480083ae2d31805a7d89ffaac8f452378fa19f0ef13bfc5a198707540f82","src/args/arg.rs":"77f8fd843928b7b963d332657ccaee21258fa9831565d225973579718d010ccc","src/args/arg_builder/base.rs":"70a9882495e2bcec53f5c9a370e5e2ae5d3b06559ef7ebda24c8a842c089df67","src/args/arg_builder/flag.rs":"2c20a751707fa0c5cc24afca3d3f3528eb68d9805ff69830bde66699bbcdd889","src/args/arg_builder/mod.rs":"7a32c8fd85b48f7b60e5f2c13dc70fa9100aa65cd933ba419300d28d682bf722","src/args/arg_builder/option.rs":"1a9473b10e94d09a7345c8c1c845a0380cd5234433ef01e0e62dabc28fa57470","src/args/arg_builder/positional.rs":"a60431c4619333ba0ed6e01cabd2d91f412c51f829c05656cf0f1bbf9b03c7da","src/args/arg_builder/switched.rs":"43b4da391b51a475a8a9bd3a396f507c2ae21bbd5a5a923bb8b1fd6d7829f228","src/args/arg_builder/valued.rs":"bdaa6943254e79c332d45af2e623baf2a99f6418a0d47240d7f666940af33e97","src/args/arg_matcher.rs":"16c4c68c253fa5660586dfa09bfa0f5dbae9cb8cb6de5e5f791ba41839ccc2e5","src/args/arg_matches.rs":"5b948efdc025fc9c39c93a84fbda1c8916c400e3557ae09a422aa29091072414","src/args/group.rs":"93797d3b8ca690d9bd23730ede9c490d49678220c70f8a90bf68914ea9eb8e22","src/args/macros.rs":"0dd7ae4c6e26ed78044c3ef90e21259816e544f724dcb09e6a0d92d4fcbc4b1a","src/args/matched_arg.rs":"ce480cff445964707663886ebbdc7c7bc168ac079ea1dafe928305d387ca07f7","src/args/mod.rs":"e15fc06bd63c3ef09c13c38c801b70c3318350456a3171d0110816eb92e0a0e2","src/args/settings.rs":"f1cdaa80def5760c72efdfddb3c509fa6ebbd83defb746dfc8fbfd57bcd080e3","src/args/subcommand.rs":"e1ad9638c33785f1301675de1795b0a4f4b079452aa11f7526d263c2a1179432","src/completions/bash.rs":"d323396378a5770ea09062fe22a6cade8c5ace74f26678dc992d86268a91c270","src/completions/fish.rs":"737084dc358bc3477477ecb18c0ec00e3ddf1bb8c238374ef017aed9f95d0bed","src/completions/macros.rs":"ebad5037e6e63401b1a54498e09d3bd93d1a3a06f045c2990902d47eb9a73774","src/completions/mod.rs":"5d4a734df6a21e6c1e0831a2f7be50a45d2e7bdaf7475589ea78b978643229cd","src/completions/powershell.rs":"e442d7ee240fb8430ed3ffd8abf7abb69f1523452f8dbe960b4b05047b3523c9","src/completions/shell.rs":"c7995ca229fd0d8671761da0aca0513c4f740165f02d06cd97aa0ae881c22cd4","src/completions/zsh.rs":"8ac4576e1cb3b1403dbb35ce146159aa8b29864e1d8201776200d999052b422d","src/errors.rs":"4da870f2002486b107b6b4b3dc8a5c81525b8416cef9aa1efb6bef495e431c09","src/fmt.rs":"284d4fc8463779241341b779b0a69d24368a21d4798862268036855fd331e18a","src/lib.rs":"78ae21e3fcfa8ffd1b9b2e5a846bd083f03b30b23a9bebc7d24249e3b0599d79","src/macros.rs":"50bf5bb36a4ca5511d3e1959aedb8d234bd84ff3d4eef0918fe9a269ef050a35","src/osstringext.rs":"680869e35af8f4f4b7f57bb7121b6274a9781cc6f7de6ba4c95683d1a71bd848","src/strext.rs":"d4418d396069e9c05804f92c042ba7192a4244e46059e2edc98670b45cd2daee","src/suggestions.rs":"ca35c332646fe9d3f93c6263830eaef77c87522f71794bfc986f90fc34229dec","src/usage_parser.rs":"ac23fdbff8a92eb02d0716685513f765dafe04a3d4ec0f4daf7cf40ed37149f7"},"package":"7db281b0520e97fbd15cd615dcd8f8bcad0c26f5f7d5effe705f090f39e9a758"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".clog.toml":"f691701bd51b5f311931d0d8f05fa3d78c00dda8d60f3313e21011309c736ff1",".github/CONTRIBUTING.md":"f7eff737f3aa25294802fefb233e3758a64b248781dbbf3262532d693f340a87",".github/ISSUE_TEMPLATE.md":"681afbd64b3603e3e82789ceb6841d851eaa7333caec5769173462bab1b5d82b",".gitignore":"57b1cc6deeaf68d35909201e4bb863c7dbec899ceaa17edde7b9fe64ece8c3e9",".travis.yml":"2975b3159624d4ecc4dd29577f378e9d4fa27f1991bfd5042ac3c267fb2cdd38","CHANGELOG.md":"82b23419a6964c8f80993b399c9dded5b7fd809ba51f5f806c2a139d3c6270a4","CONTRIBUTORS.md":"5d7dbafaff6879bbfbb01b22cca299953ec163872d8d624bbf99e20851ca0165","Cargo.toml":"94e3789815bfd001abf96cb0d10fa95a4b4576bc679539e79a531d0010e2ccdd","LICENSE-MIT":"6725d1437fc6c77301f2ff0e7d52914cf4f9509213e1078dc77d9356dbe6eac5","README.md":"031031971829f165ed7ffd8375c2249ce96336a9ed7f207d4722df05563d2d7e","appveyor.yml":"303c64c2cc84c24b3c9ac0b4cd66b98d6bb25dec7d030ed53e5cb6ab3f13ebd1","clap-test.rs":"a0b0d9ca9106a52bf9dc41cf52b0b87c98209dca3490caa6ec1452bd1fec5c4c","index.html":"36f9ce4465266f3af9a259444b01c4239200473cabfc848f789f75b322a3ea8f","justfile":"811b2dec57aec46e570aeeb9945018cf87fe65f6d5b27cdb9ffca79d906910f6","rustfmt.toml":"8fd2d63119df515fd5f44e530c709b19d66b09fbc2e22a640bf4b64c57e7d6b3","src/app/help.rs":"da53217886fb1ea289b9057d4b5e94dce74ce81a7b7006d216370aad709bff77","src/app/macros.rs":"0205c461041d917aecb4a15212f89908e72902b961f47014a645f2b061de5998","src/app/meta.rs":"a56d28bb466a8ba68155b3f2883e85228b4b74cf25658f62fc050e07cff2dc85","src/app/mod.rs":"d0e1843ae1f77c1da4179cebdd8fb1ea55803002fb1ae96087de3a8cdcedf6fc","src/app/parser.rs":"66b08057b7bc19f6c2c94671de7fc20ec623368e04f92d2a6775991d37430fc2","src/app/settings.rs":"cf9f4a1a9d3799ac30d1d98cf23987cc884435ad912a0dfd853b101ce86c97cc","src/app/usage.rs":"ecaeab6c7980544e9a2d35cc41f2797df8bc9c09f5da67e96286631a116c0ccc","src/app/validator.rs":"f19d876ac673019ed5fdd4b9f76ba598fa790aa5e64d482696ca1e45dce5f28b","src/args/any_arg.rs":"b082385eeff2505ced7b747bd44d20a3fb6fd9d4bd14be9e99870699c43ea072","src/args/arg.rs":"673de3f1957eccb1b116255bac9638fe24c0da54ccb358d958446c8ed54c9621","src/args/arg_builder/base.rs":"8b99a9ab811df3e0bdcfba8c0994042b0bcd06d8ddf794ab559baaf9a490ba59","src/args/arg_builder/flag.rs":"4007a950869789b1f4d5f953107aee228477e2d5fe82515d3b895286c65522c6","src/args/arg_builder/mod.rs":"7a32c8fd85b48f7b60e5f2c13dc70fa9100aa65cd933ba419300d28d682bf722","src/args/arg_builder/option.rs":"d5e5243e3a72d2c820c8fad4e1efc4b985881c6f60f3a72757b33a9054a87e99","src/args/arg_builder/positional.rs":"39615d22b586e744a0bdeb8490dbe43df7df66ed793abf8f50ed2037ec0fb90c","src/args/arg_builder/switched.rs":"61f5121b0ec746461215a47e1b7a4d699a37a3f181172820e0615f68d5f6f0ef","src/args/arg_builder/valued.rs":"19368a03e046d6b63451c3d04dff6e51d49f140ed45330f82879539c6d1b28dd","src/args/arg_matcher.rs":"27829739ae12ac7800a26109e751ce9f8c3d26e262d41de161a38baf5c421167","src/args/arg_matches.rs":"9d72a388053ef0c31fe2516df9ea791a4d0f6c0b5e9758eb61886f1ac8df89ab","src/args/group.rs":"3f72a6ecc6ff71c96dd9cd8098e4fb6f7c4e6207e9bd0b67a50b104f5dfdb23d","src/args/macros.rs":"0dd7ae4c6e26ed78044c3ef90e21259816e544f724dcb09e6a0d92d4fcbc4b1a","src/args/matched_arg.rs":"1ed8d338869ecc3b5fa426ef4cf42f4c9c3b1dd538cdea1fe0489169345536f7","src/args/mod.rs":"c155cd989fa4ca1f8de6a79115afbf5086f092adcb854ff9698b9100f45fc323","src/args/settings.rs":"e6bbfb49c2e38fcedb67481bcbf0eb887ee510031639be8134411121a9363f7e","src/args/subcommand.rs":"e1ad9638c33785f1301675de1795b0a4f4b079452aa11f7526d263c2a1179432","src/completions/bash.rs":"116c6830ee2b6310f299a69924f5b1e39b05ebec2b5f7b0ffe3b6938b7fa5514","src/completions/fish.rs":"63975f8beea9af6bef66c7dd7938bfa61c6f871995a74dbc1545daa9fbc1f2d0","src/completions/macros.rs":"ebad5037e6e63401b1a54498e09d3bd93d1a3a06f045c2990902d47eb9a73774","src/completions/mod.rs":"5d4a734df6a21e6c1e0831a2f7be50a45d2e7bdaf7475589ea78b978643229cd","src/completions/powershell.rs":"4267818aaa60583c055d7a276a7535309e5162c94467f3003799b6a8a7f6d6b0","src/completions/shell.rs":"c7995ca229fd0d8671761da0aca0513c4f740165f02d06cd97aa0ae881c22cd4","src/completions/zsh.rs":"8ac4576e1cb3b1403dbb35ce146159aa8b29864e1d8201776200d999052b422d","src/errors.rs":"5d0ab536ea62614a6cf88d175a5b5e9c2777a35958e1d4598ac1ec4a6f451593","src/fmt.rs":"42459e7f42f5495c005d2de3eaf8d7b5619bf4b8d245ecb76e583f08ecaa3869","src/lib.rs":"3471c5b046df081afecb4e541d4e55dc7afa34bf7fe8f369f301f6471887e930","src/macros.rs":"c1d40220947c62b0364eedd2c40ca2c414daccc334a1e04e029a884e782bf2b0","src/osstringext.rs":"a87a5a0685dd8310f6329d5f8e8f54c0fac68eb75595a835aeb1c36208efd5f9","src/strext.rs":"d4418d396069e9c05804f92c042ba7192a4244e46059e2edc98670b45cd2daee","src/suggestions.rs":"ca352c62cdcc1b6071c50e39f39e8f5f6cd11c318229cc6cf16511dfde43c5c7","src/usage_parser.rs":"a04143bba42a6506746091a3f898c38e2c7409bacefed21fa8194c90961ca390"},"package":"6b8f69e518f967224e628896b54e41ff6acfb4dcfefc5076325c36525dac900f"}
\ No newline at end of file
--- a/third_party/rust/clap/CHANGELOG.md
+++ b/third_party/rust/clap/CHANGELOG.md
@@ -1,8 +1,214 @@
+<a name="v2.24.2"></a>
+### v2.24.2 (2017-05-15)
+
+
+#### Bug Fixes
+
+*   adds a debug assertion to ensure all args added to groups actually exist ([14f6b8f3](https://github.com/kbknapp/clap-rs/commit/14f6b8f3a2f6df73aeeec9c54a54909b1acfc158), closes [#917](https://github.com/kbknapp/clap-rs/issues/917))
+*   fixes a bug where args that allow values to start with a hyphen couldnt contain a double hyphen -- as a value ([ebf73a09](https://github.com/kbknapp/clap-rs/commit/ebf73a09db6f3c03c19cdd76b1ba6113930e1643), closes [#960](https://github.com/kbknapp/clap-rs/issues/960))
+*   fixes a bug where positional argument help text is misaligned ([54c16836](https://github.com/kbknapp/clap-rs/commit/54c16836dea4651806a2cfad53146a83fa3abf21))
+
+#### Documentation
+
+* **App::template:**  adds details about the necessity to use AppSettings::UnifiedHelpMessage when using {unified} tags in the help template ([cf569438](https://github.com/kbknapp/clap-rs/commit/cf569438f309c199800bb8e46c9f140187de69d7), closes [#949](https://github.com/kbknapp/clap-rs/issues/949))
+* **Arg::allow_hyphen_values:**  updates the docs to include warnings for allow_hyphen_values and multiple(true) used together ([ded5a2f1](https://github.com/kbknapp/clap-rs/commit/ded5a2f15474d4a5bd46a67b130ccb8b6781bd01))
+* **clap_app!:**  adds using the @group specifier to the macro docs ([fe85fcb1](https://github.com/kbknapp/clap-rs/commit/fe85fcb1772b61f13b20b7ea5290e2437a76190c), closes [#932](https://github.com/kbknapp/clap-rs/issues/932))
+
+
+
+<a name="v2.24.0"></a>
+### v2.24.0 (2017-05-07)
+
+
+#### Bug Fixes
+
+*   fixes a bug where args with last(true) and required(true) set were not being printed in the usage string ([3ac533fe](https://github.com/kbknapp/clap-rs/commit/3ac533fedabf713943eedf006f830a5a486bbe80), closes [#944](https://github.com/kbknapp/clap-rs/issues/944))
+*   fixes a bug that was printing the arg name, instead of value name when Arg::last(true) was used ([e1fe8ac3](https://github.com/kbknapp/clap-rs/commit/e1fe8ac3bc1f9cf4e36df0d881f8419755f1787b), closes [#940](https://github.com/kbknapp/clap-rs/issues/940))
+*   fixes a bug where flags were parsed as flags AND positional values when specific combinations of settings were used ([20f83292](https://github.com/kbknapp/clap-rs/commit/20f83292d070038b8cee2a6b47e91f6b0a2f7871), closes [#946](https://github.com/kbknapp/clap-rs/issues/946))
+
+
+
+<a name="v2.24.0"></a>
+## v2.24.0 (2017-05-05)
+
+
+#### Documentation
+
+* **README.md:**  fix some typos ([fa34deac](https://github.com/kbknapp/clap-rs/commit/fa34deac079f334c3af97bb7fb151880ba8887f8))
+
+#### API Additions
+
+* **Arg:**  add `default_value_os` ([d5ef8955](https://github.com/kbknapp/clap-rs/commit/d5ef8955414b1587060f7218385256105b639c88))
+* **arg_matches.rs:**  Added a Default implementation for Values and OsValues iterators. ([0a4384e3](https://github.com/kbknapp/clap-rs/commit/0a4384e350eed74c2a4dc8964c203f21ac64897f))
+
+
+<a name="v2.23.2"></a>
+### v2.23.2 (2017-04-19)
+
+
+#### Bug Fixes
+
+* **PowerShell Completions:**  fixes a bug where powershells completions cant be used if no subcommands are defined ([a8bce558](https://github.com/kbknapp/clap-rs/commit/a8bce55837dc4e0fb187dc93180884a40ae09c6f), closes [#931](https://github.com/kbknapp/clap-rs/issues/931))
+
+#### Improvements
+
+*   bumps term_size to take advantage of better terminal dimension handling ([e05100b7](https://github.com/kbknapp/clap-rs/commit/e05100b73d74066a90876bf38f952adf5e8ee422))
+* **PowerShell Completions:**  massively dedups subcommand names in the generate script to make smaller scripts that are still functionally equiv ([85b0e1cc](https://github.com/kbknapp/clap-rs/commit/85b0e1cc4b9755dda75a93d898d79bc38631552b))
+
+#### Documentation
+
+*   Fix a typo the minimum rust version required ([71dabba3](https://github.com/kbknapp/clap-rs/commit/71dabba3ea0a17c88b0e2199c9d99f0acbf3bc17))
+
+<a name="v2.23.1"></a>
+### v2.23.1 (2017-04-05)
+
+
+#### Bug Fixes
+
+*   fixes a missing newline character in the autogenerated help and version messages in some instances ([5ae9007d](https://github.com/kbknapp/clap-rs/commit/5ae9007d984ae94ae2752df51bcbaeb0ec89bc15))
+
+
+<a name="v2.23.0"></a>
+## v2.23.0 (2017-04-05)
+
+
+#### API Additions
+
+* `App::long_about`
+* `App::long_version`
+* `App::print_long_help`
+* `App::write_long_help`
+* `App::print_long_version`
+* `App::write_long_version`
+* `Arg::long_help`
+
+#### Features
+
+*   allows distinguishing between short and long version messages (-V/short or --version/long) ([59272b06](https://github.com/kbknapp/clap-rs/commit/59272b06cc213289dc604dbc694cb95d383a5d68))
+*   allows distinguishing between short and long help with subcommands in the same manner as args ([6b371891](https://github.com/kbknapp/clap-rs/commit/6b371891a1702173a849d1e95f9fecb168bf6fc4))
+*   allows specifying a short help vs a long help (i.e. varying levels of detail depending on if -h or --help was used) ([ef1b24c3](https://github.com/kbknapp/clap-rs/commit/ef1b24c3a0dff2f58c5e2e90880fbc2b69df20ee))
+* **clap_app!:**  adds support for arg names with hyphens similar to longs with hyphens ([f7a88779](https://github.com/kbknapp/clap-rs/commit/f7a8877978c8f90e6543d4f0d9600c086cf92cd7), closes [#869](https://github.com/kbknapp/clap-rs/issues/869))
+
+#### Bug Fixes
+
+*   fixes a bug that wasn't allowing help and version to be properly overridden ([8b2ceb83](https://github.com/kbknapp/clap-rs/commit/8b2ceb8368bcb70689fadf1c7f4b9549184926c1), closes [#922](https://github.com/kbknapp/clap-rs/issues/922))
+
+#### Documentation
+
+* **clap_app!:**  documents the `--("some-arg")` method for using args with hyphens inside them ([bc08ef3e](https://github.com/kbknapp/clap-rs/commit/bc08ef3e185393073d969d301989b6319c616c1f), closes [#919](https://github.com/kbknapp/clap-rs/issues/919))
+
+
+
+<a name="v2.22.2"></a>
+### v2.22.2 (2017-03-30)
+
+
+#### Bug Fixes
+
+* **Custom Usage Strings:**  fixes the usage string regression when using help templates ([0e4fd96d](https://github.com/kbknapp/clap-rs/commit/0e4fd96d74280d306d09e60ac44f938a82321769))
+
+
+
+<a name="v2.22.1"></a>
+### v2.22.1 (2017-03-24)
+
+
+#### Bug Fixes
+
+* **usage:**  fixes a big regression with custom usage strings ([2c41caba](https://github.com/kbknapp/clap-rs/commit/2c41caba3c7d723a2894e315d04da796b0e97759))
+
+<a name="v2.22.0"></a>
+## v2.22.0 (2017-03-23)
+
+#### API Additions
+
+* **App::name:**  adds the ability to change the name of the App instance after creation ([d49e8292](https://github.com/kbknapp/clap-rs/commit/d49e8292b026b06e2b70447cd9f08299f4fcba76), closes [#908](https://github.com/kbknapp/clap-rs/issues/908))
+* **Arg::hide_default_value:**  adds ability to hide the default value of an argument from the help string ([89e6ea86](https://github.com/kbknapp/clap-rs/commit/89e6ea861e16a1ad56757ca12f6b32d02253e44a), closes [#902](https://github.com/kbknapp/clap-rs/issues/902))
+
+
+<a name="v2.21.3"></a>
+### v2.21.3 (2017-03-23)
+
+#### Bug Fixes
+
+* **yaml:**  adds support for loading author info from yaml ([e04c390c](https://github.com/kbknapp/clap-rs/commit/e04c390c597a55fa27e724050342f16c42f1c5c9))
+
+
+<a name="v2.21.2"></a>
+### v2.21.2 (2017-03-17)
+
+
+#### Improvements
+
+*   add fish subcommand help support ([f8f68cf8](https://github.com/kbknapp/clap-rs/commit/f8f68cf8251669aef4539a25a7c1166f0ac81ea6))
+*   options that use `require_equals(true)` now display the equals sign in help messages, usage strings, and errors" ([c8eb0384](https://github.com/kbknapp/clap-rs/commit/c8eb0384d394d2900ccdc1593099c97808a3fa05), closes [#903](https://github.com/kbknapp/clap-rs/issues/903))
+
+
+#### Bug Fixes
+
+*  setting the max term width now correctly propagates down through child subcommands
+
+
+
+<a name="v2.21.1"></a>
+### v2.21.1 (2017-03-12)
+
+
+#### Bug Fixes
+
+* **ArgRequiredElseHelp:**  fixes the precedence of this error to prioritize over other error messages ([74b751ff](https://github.com/kbknapp/clap-rs/commit/74b751ff2e3631e337b7946347c1119829a41c53), closes [#895](https://github.com/kbknapp/clap-rs/issues/895))
+* **Positionals:**  fixes some regression bugs resulting from old asserts in debug mode. ([9a3bc98e](https://github.com/kbknapp/clap-rs/commit/9a3bc98e9b55e7514b74b73374c5ac8b6e5e0508), closes [#896](https://github.com/kbknapp/clap-rs/issues/896))
+
+
+
+<a name="v2.21.0"></a>
+## v2.21.0 (2017-03-09)
+
+#### Performance
+
+*   doesn't run `arg_post_processing` on multiple values anymore ([ec516182](https://github.com/kbknapp/clap-rs/commit/ec5161828729f6a53f0fccec8648f71697f01f78))
+*   changes internal use of `VecMap` to `Vec` for matched values of `Arg`s ([22bf137a](https://github.com/kbknapp/clap-rs/commit/22bf137ac581684c6ed460d2c3c640c503d62621))
+*   vastly reduces the amount of cloning when adding non-global args minus when they're added from `App::args` which is forced to clone ([8da0303b](https://github.com/kbknapp/clap-rs/commit/8da0303bc02db5fe047cfc0631a9da41d9dc60f7))
+*   refactor to remove unneeded vectors and allocations and checks for significant performance increases ([0efa4119](https://github.com/kbknapp/clap-rs/commit/0efa4119632f134fc5b8b9695b007dd94b76735d))
+
+#### Documentation
+
+*   Fix examples link in CONTRIBUTING.md ([60cf875d](https://github.com/kbknapp/clap-rs/commit/60cf875d67a252e19bb85054be57696fac2c57a1))
+
+#### Improvements
+
+*   when `AppSettings::SubcommandsNegateReqs` and `ArgsNegateSubcommands` are used, a new more accurate double line usage string is shown ([50f02300](https://github.com/kbknapp/clap-rs/commit/50f02300d81788817acefef0697e157e01b6ca32), closes [#871](https://github.com/kbknapp/clap-rs/issues/871))
+
+#### API Additions
+
+* **Arg::last:**  adds the ability to mark a positional argument as 'last' which means it should be used with `--` syntax and can be accessed early ([6a7aea90](https://github.com/kbknapp/clap-rs/commit/6a7aea9043b83badd9ab038b4ecc4c787716147e), closes [#888](https://github.com/kbknapp/clap-rs/issues/888))
+*   provides `default_value_os` and `default_value_if[s]_os` ([0f2a3782](https://github.com/kbknapp/clap-rs/commit/0f2a378219a6930748d178ba350fe5925be5dad5), closes [#849](https://github.com/kbknapp/clap-rs/issues/849))
+*   provides `App::help_message` and `App::version_message` which allows one to override the auto-generated help/version flag associated help ([389c413](https://github.com/kbknapp/clap-rs/commit/389c413b7023dccab8c76aa00577ea1d048e7a99), closes [#889](https://github.com/kbknapp/clap-rs/issues/889))
+
+#### New Settings
+
+* **InferSubcommands:**  adds a setting to allow one to infer shortened subcommands or aliases (i.e. for subcommmand "test", "t", "te", or "tes" would be allowed assuming no other ambiguities) ([11602032](https://github.com/kbknapp/clap-rs/commit/11602032f6ff05881e3adf130356e37d5e66e8f9), closes [#863](https://github.com/kbknapp/clap-rs/issues/863))
+
+#### Bug Fixes
+
+*   doesn't print the argument sections in the help message if all args in that section are hidden ([ce5ee5f5](https://github.com/kbknapp/clap-rs/commit/ce5ee5f5a76f838104aeddd01c8ec956dd347f50))
+*   doesn't include the various [ARGS] [FLAGS] or [OPTIONS] if the only ones available are hidden ([7b4000af](https://github.com/kbknapp/clap-rs/commit/7b4000af97637703645c5fb2ac8bb65bd546b95b), closes [#882](https://github.com/kbknapp/clap-rs/issues/882))
+*   now correctly shows subcommand as required in the usage string when AppSettings::SubcommandRequiredElseHelp is used ([8f0884c1](https://github.com/kbknapp/clap-rs/commit/8f0884c1764983a49b45de52a1eddf8d721564d8))
+*   fixes some memory leaks when an error is detected and clap exits ([8c2dd287](https://github.com/kbknapp/clap-rs/commit/8c2dd28718262ace4ae0db98563809548e02a86b))
+*   fixes a trait that's marked private accidentlly, but should be crate internal public ([1ae21108](https://github.com/kbknapp/clap-rs/commit/1ae21108015cea87e5360402e1747025116c7878))
+* **Completions:**   fixes a bug that tried to propogate global args multiple times when generating multiple completion scripts ([5e9b9cf4](https://github.com/kbknapp/clap-rs/commit/5e9b9cf4dd80fa66a624374fd04e6545635c1f94), closes [#846](https://github.com/kbknapp/clap-rs/issues/846))
+
+#### Features
+
+* **Options:**  adds the ability to require the equals syntax with options --opt=val ([f002693d](https://github.com/kbknapp/clap-rs/commit/f002693dec6a6959c4e9590cb7b7bfffd6d6e5bc), closes [#833](https://github.com/kbknapp/clap-rs/issues/833))
+
+
+
 <a name="v2.20.5"></a>
 ### v2.20.5 (2017-02-18)
 
 
 #### Bug Fixes
 
 * **clap_app!:**   fixes a critical bug of a missing fragment specifier when using `!property` style tags. ([5635c1f94](https://github.com/kbknapp/clap-rs/commit/5e9b9cf4dd80fa66a624374fd04e6545635c1f94))
 
--- a/third_party/rust/clap/CONTRIBUTORS.md
+++ b/third_party/rust/clap/CONTRIBUTORS.md
@@ -1,56 +1,67 @@
-The following is a list of contributors in alphabetical order:
+the following is a list of contributors:
 
 
-[<img alt="afiune" src="https://avatars.githubusercontent.com/u/5712253?v=3&s=117" width="117">](https://github.com/afiune) |[<img alt="alex-gulyas" src="https://avatars.githubusercontent.com/u/8698329?v=3&s=117" width="117">](https://github.com/alex-gulyas) |[<img alt="alexbool" src="https://avatars.githubusercontent.com/u/1283792?v=3&s=117" width="117">](https://github.com/alexbool) |[<img alt="AluisioASG" src="https://avatars.githubusercontent.com/u/1904165?v=3&s=117" width="117">](https://github.com/AluisioASG) |[<img alt="archer884" src="https://avatars.githubusercontent.com/u/679494?v=3&s=117" width="117">](https://github.com/archer884) |[<img alt="Arnavion" src="https://avatars.githubusercontent.com/u/1096010?v=3&s=117" width="117">](https://github.com/Arnavion) |
+[<img alt="kbknapp" src="https://avatars2.githubusercontent.com/u/6942134?v=3&s=117" width="117">](https://github.com/kbknapp) |[<img alt="homu" src="https://avatars2.githubusercontent.com/u/10212162?v=3&s=117" width="117">](https://github.com/homu) |[<img alt="Vinatorul" src="https://avatars2.githubusercontent.com/u/6770624?v=3&s=117" width="117">](https://github.com/Vinatorul) |[<img alt="tormol" src="https://avatars0.githubusercontent.com/u/10460821?v=3&s=117" width="117">](https://github.com/tormol) |[<img alt="sru" src="https://avatars0.githubusercontent.com/u/2485892?v=3&s=117" width="117">](https://github.com/sru) |[<img alt="nabijaczleweli" src="https://avatars0.githubusercontent.com/u/6709544?v=3&s=117" width="117">](https://github.com/nabijaczleweli) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[afiune](https://github.com/afiune) |[alex-gulyas](https://github.com/alex-gulyas) |[alexbool](https://github.com/alexbool) |[AluisioASG](https://github.com/AluisioASG) |[archer884](https://github.com/archer884) |[Arnavion](https://github.com/Arnavion) |
+[kbknapp](https://github.com/kbknapp) |[homu](https://github.com/homu) |[Vinatorul](https://github.com/Vinatorul) |[tormol](https://github.com/tormol) |[sru](https://github.com/sru) |[nabijaczleweli](https://github.com/nabijaczleweli) |
 
-[<img alt="Bilalh" src="https://avatars.githubusercontent.com/u/171602?v=3&s=117" width="117">](https://github.com/Bilalh) |[<img alt="birkenfeld" src="https://avatars.githubusercontent.com/u/144359?v=3&s=117" width="117">](https://github.com/birkenfeld) |[<img alt="bradurani" src="https://avatars.githubusercontent.com/u/4195952?v=3&s=117" width="117">](https://github.com/bradurani) |[<img alt="brennie" src="https://avatars.githubusercontent.com/u/156585?v=3&s=117" width="117">](https://github.com/brennie) |[<img alt="brianp" src="https://avatars.githubusercontent.com/u/179134?v=3&s=117" width="117">](https://github.com/brianp) |[<img alt="BurntSushi" src="https://avatars.githubusercontent.com/u/456674?v=3&s=117" width="117">](https://github.com/BurntSushi) |
+[<img alt="Byron" src="https://avatars1.githubusercontent.com/u/63622?v=3&s=117" width="117">](https://github.com/Byron) |[<img alt="hgrecco" src="https://avatars3.githubusercontent.com/u/278566?v=3&s=117" width="117">](https://github.com/hgrecco) |[<img alt="james-darkfox" src="https://avatars0.githubusercontent.com/u/637155?v=3&s=117" width="117">](https://github.com/james-darkfox) |[<img alt="rtaycher" src="https://avatars3.githubusercontent.com/u/324733?v=3&s=117" width="117">](https://github.com/rtaycher) |[<img alt="glowing-chemist" src="https://avatars3.githubusercontent.com/u/17074682?v=3&s=117" width="117">](https://github.com/glowing-chemist) |[<img alt="Arnavion" src="https://avatars1.githubusercontent.com/u/1096010?v=3&s=117" width="117">](https://github.com/Arnavion) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[Bilalh](https://github.com/Bilalh) |[birkenfeld](https://github.com/birkenfeld) |[bradurani](https://github.com/bradurani) |[brennie](https://github.com/brennie) |[brianp](https://github.com/brianp) |[BurntSushi](https://github.com/BurntSushi) |
+[Byron](https://github.com/Byron) |[hgrecco](https://github.com/hgrecco) |[james-darkfox](https://github.com/james-darkfox) |[rtaycher](https://github.com/rtaycher) |[glowing-chemist](https://github.com/glowing-chemist) |[Arnavion](https://github.com/Arnavion) |
 
-[<img alt="Byron" src="https://avatars.githubusercontent.com/u/63622?v=3&s=117" width="117">](https://github.com/Byron) |[<img alt="casey" src="https://avatars.githubusercontent.com/u/1945?v=3&s=117" width="117">](https://github.com/casey) |[<img alt="cite-reader" src="https://avatars.githubusercontent.com/u/4196987?v=3&s=117" width="117">](https://github.com/cite-reader) |[<img alt="cstorey" src="https://avatars.githubusercontent.com/u/743059?v=3&s=117" width="117">](https://github.com/cstorey) |[<img alt="daboross" src="https://avatars.githubusercontent.com/u/1152146?v=3&s=117" width="117">](https://github.com/daboross) |[<img alt="davidszotten" src="https://avatars.githubusercontent.com/u/412005?v=3&s=117" width="117">](https://github.com/davidszotten) |
+[<img alt="mgeisler" src="https://avatars3.githubusercontent.com/u/89623?v=3&s=117" width="117">](https://github.com/mgeisler) |[<img alt="afiune" src="https://avatars3.githubusercontent.com/u/5712253?v=3&s=117" width="117">](https://github.com/afiune) |[<img alt="crazymerlyn" src="https://avatars2.githubusercontent.com/u/6919679?v=3&s=117" width="117">](https://github.com/crazymerlyn) |[<img alt="SuperFluffy" src="https://avatars3.githubusercontent.com/u/701177?v=3&s=117" width="117">](https://github.com/SuperFluffy) |[<img alt="untitaker" src="https://avatars3.githubusercontent.com/u/837573?v=3&s=117" width="117">](https://github.com/untitaker) |[<img alt="japaric" src="https://avatars0.githubusercontent.com/u/5018213?v=3&s=117" width="117">](https://github.com/japaric) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[Byron](https://github.com/Byron) |[casey](https://github.com/casey) |[cite-reader](https://github.com/cite-reader) |[cstorey](https://github.com/cstorey) |[daboross](https://github.com/daboross) |[davidszotten](https://github.com/davidszotten) |
+[mgeisler](https://github.com/mgeisler) |[afiune](https://github.com/afiune) |[crazymerlyn](https://github.com/crazymerlyn) |[SuperFluffy](https://github.com/SuperFluffy) |[untitaker](https://github.com/untitaker) |[japaric](https://github.com/japaric) |
 
-[<img alt="Deedasmi" src="https://avatars.githubusercontent.com/u/5093293?v=3&s=117" width="117">](https://github.com/Deedasmi) |[<img alt="dguo" src="https://avatars.githubusercontent.com/u/2763135?v=3&s=117" width="117">](https://github.com/dguo) |[<img alt="dotdash" src="https://avatars.githubusercontent.com/u/230962?v=3&s=117" width="117">](https://github.com/dotdash) |[<img alt="flying-sheep" src="https://avatars.githubusercontent.com/u/291575?v=3&s=117" width="117">](https://github.com/flying-sheep) |[<img alt="Geogi" src="https://avatars.githubusercontent.com/u/1818316?v=3&s=117" width="117">](https://github.com/Geogi) |[<img alt="glowing-chemist" src="https://avatars.githubusercontent.com/u/17074682?v=3&s=117" width="117">](https://github.com/glowing-chemist) |
+[<img alt="matthiasbeyer" src="https://avatars3.githubusercontent.com/u/427866?v=3&s=117" width="117">](https://github.com/matthiasbeyer) |[<img alt="SShrike" src="https://avatars2.githubusercontent.com/u/4061736?v=3&s=117" width="117">](https://github.com/SShrike) |[<img alt="gohyda" src="https://avatars0.githubusercontent.com/u/10263838?v=3&s=117" width="117">](https://github.com/gohyda) |[<img alt="jimmycuadra" src="https://avatars1.githubusercontent.com/u/122457?v=3&s=117" width="117">](https://github.com/jimmycuadra) |[<img alt="Nemo157" src="https://avatars2.githubusercontent.com/u/81079?v=3&s=117" width="117">](https://github.com/Nemo157) |[<img alt="tshepang" src="https://avatars3.githubusercontent.com/u/588486?v=3&s=117" width="117">](https://github.com/tshepang) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[Deedasmi](https://github.com/Deedasmi) |[dguo](https://github.com/dguo) |[dotdash](https://github.com/dotdash) |[flying-sheep](https://github.com/flying-sheep) |[Geogi](https://github.com/Geogi) |[glowing-chemist](https://github.com/glowing-chemist) |
+[matthiasbeyer](https://github.com/matthiasbeyer) |[SShrike](https://github.com/SShrike) |[gohyda](https://github.com/gohyda) |[jimmycuadra](https://github.com/jimmycuadra) |[Nemo157](https://github.com/Nemo157) |[tshepang](https://github.com/tshepang) |
 
-[<img alt="gohyda" src="https://avatars.githubusercontent.com/u/10263838?v=3&s=117" width="117">](https://github.com/gohyda) |[<img alt="GrappigPanda" src="https://avatars.githubusercontent.com/u/2055372?v=3&s=117" width="117">](https://github.com/GrappigPanda) |[<img alt="grossws" src="https://avatars.githubusercontent.com/u/171284?v=3&s=117" width="117">](https://github.com/grossws) |[<img alt="hexjelly" src="https://avatars.githubusercontent.com/u/435283?v=3&s=117" width="117">](https://github.com/hexjelly) |[<img alt="hgrecco" src="https://avatars.githubusercontent.com/u/278566?v=3&s=117" width="117">](https://github.com/hgrecco) |[<img alt="homu" src="https://avatars.githubusercontent.com/u/10212162?v=3&s=117" width="117">](https://github.com/homu) |
+[<img alt="porglezomp" src="https://avatars2.githubusercontent.com/u/1690225?v=3&s=117" width="117">](https://github.com/porglezomp) |[<img alt="wdv4758h" src="https://avatars2.githubusercontent.com/u/2716047?v=3&s=117" width="117">](https://github.com/wdv4758h) |[<img alt="frewsxcv" src="https://avatars1.githubusercontent.com/u/416575?v=3&s=117" width="117">](https://github.com/frewsxcv) |[<img alt="hoodie" src="https://avatars2.githubusercontent.com/u/260370?v=3&s=117" width="117">](https://github.com/hoodie) |[<img alt="huonw" src="https://avatars2.githubusercontent.com/u/1203825?v=3&s=117" width="117">](https://github.com/huonw) |[<img alt="GrappigPanda" src="https://avatars3.githubusercontent.com/u/2055372?v=3&s=117" width="117">](https://github.com/GrappigPanda) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[gohyda](https://github.com/gohyda) |[GrappigPanda](https://github.com/GrappigPanda) |[grossws](https://github.com/grossws) |[hexjelly](https://github.com/hexjelly) |[hgrecco](https://github.com/hgrecco) |[homu](https://github.com/homu) |
+[porglezomp](https://github.com/porglezomp) |[wdv4758h](https://github.com/wdv4758h) |[frewsxcv](https://github.com/frewsxcv) |[hoodie](https://github.com/hoodie) |[huonw](https://github.com/huonw) |[GrappigPanda](https://github.com/GrappigPanda) |
 
-[<img alt="hoodie" src="https://avatars.githubusercontent.com/u/260370?v=3&s=117" width="117">](https://github.com/hoodie) |[<img alt="huonw" src="https://avatars.githubusercontent.com/u/1203825?v=3&s=117" width="117">](https://github.com/huonw) |[<img alt="idmit" src="https://avatars.githubusercontent.com/u/2546728?v=3&s=117" width="117">](https://github.com/idmit) |[<img alt="iliekturtles" src="https://avatars.githubusercontent.com/u/5081378?v=3&s=117" width="117">](https://github.com/iliekturtles) |[<img alt="james-darkfox" src="https://avatars.githubusercontent.com/u/637155?v=3&s=117" width="117">](https://github.com/james-darkfox) |[<img alt="japaric" src="https://avatars.githubusercontent.com/u/5018213?v=3&s=117" width="117">](https://github.com/japaric) |
+[<img alt="ignatenkobrain" src="https://avatars2.githubusercontent.com/u/2866862?v=3&s=117" width="117">](https://github.com/ignatenkobrain) |[<img alt="cstorey" src="https://avatars0.githubusercontent.com/u/743059?v=3&s=117" width="117">](https://github.com/cstorey) |[<img alt="musoke" src="https://avatars3.githubusercontent.com/u/16665084?v=3&s=117" width="117">](https://github.com/musoke) |[<img alt="nelsonjchen" src="https://avatars2.githubusercontent.com/u/5363?v=3&s=117" width="117">](https://github.com/nelsonjchen) |[<img alt="pkgw" src="https://avatars3.githubusercontent.com/u/59598?v=3&s=117" width="117">](https://github.com/pkgw) |[<img alt="Deedasmi" src="https://avatars3.githubusercontent.com/u/5093293?v=3&s=117" width="117">](https://github.com/Deedasmi) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[hoodie](https://github.com/hoodie) |[huonw](https://github.com/huonw) |[idmit](https://github.com/idmit) |[iliekturtles](https://github.com/iliekturtles) |[james-darkfox](https://github.com/james-darkfox) |[japaric](https://github.com/japaric) |
+[ignatenkobrain](https://github.com/ignatenkobrain) |[cstorey](https://github.com/cstorey) |[musoke](https://github.com/musoke) |[nelsonjchen](https://github.com/nelsonjchen) |[pkgw](https://github.com/pkgw) |[Deedasmi](https://github.com/Deedasmi) |
 
-[<img alt="jespino" src="https://avatars.githubusercontent.com/u/290303?v=3&s=117" width="117">](https://github.com/jespino) |[<img alt="jimmycuadra" src="https://avatars.githubusercontent.com/u/122457?v=3&s=117" width="117">](https://github.com/jimmycuadra) |[<img alt="joshtriplett" src="https://avatars.githubusercontent.com/u/162737?v=3&s=117" width="117">](https://github.com/joshtriplett) |[<img alt="jtdowney" src="https://avatars.githubusercontent.com/u/44654?v=3&s=117" width="117">](https://github.com/jtdowney) |[<img alt="kbknapp" src="https://avatars.githubusercontent.com/u/6942134?v=3&s=117" width="117">](https://github.com/kbknapp) |[<img alt="Keats" src="https://avatars.githubusercontent.com/u/680355?v=3&s=117" width="117">](https://github.com/Keats) |
+[<img alt="N-006" src="https://avatars3.githubusercontent.com/u/399312?v=3&s=117" width="117">](https://github.com/N-006) |[<img alt="Keats" src="https://avatars1.githubusercontent.com/u/680355?v=3&s=117" width="117">](https://github.com/Keats) |[<img alt="starkat99" src="https://avatars2.githubusercontent.com/u/8295111?v=3&s=117" width="117">](https://github.com/starkat99) |[<img alt="alex-gulyas" src="https://avatars3.githubusercontent.com/u/8698329?v=3&s=117" width="117">](https://github.com/alex-gulyas) |[<img alt="cite-reader" src="https://avatars2.githubusercontent.com/u/4196987?v=3&s=117" width="117">](https://github.com/cite-reader) |[<img alt="alexbool" src="https://avatars0.githubusercontent.com/u/1283792?v=3&s=117" width="117">](https://github.com/alexbool) |
+:---: |:---: |:---: |:---: |:---: |:---: |
+[N-006](https://github.com/N-006) |[Keats](https://github.com/Keats) |[starkat99](https://github.com/starkat99) |[alex-gulyas](https://github.com/alex-gulyas) |[cite-reader](https://github.com/cite-reader) |[alexbool](https://github.com/alexbool) |
+
+[<img alt="AluisioASG" src="https://avatars1.githubusercontent.com/u/1904165?v=3&s=117" width="117">](https://github.com/AluisioASG) |[<img alt="BurntSushi" src="https://avatars0.githubusercontent.com/u/456674?v=3&s=117" width="117">](https://github.com/BurntSushi) |[<img alt="nox" src="https://avatars3.githubusercontent.com/u/123095?v=3&s=117" width="117">](https://github.com/nox) |[<img alt="pixelistik" src="https://avatars2.githubusercontent.com/u/170929?v=3&s=117" width="117">](https://github.com/pixelistik) |[<img alt="brennie" src="https://avatars0.githubusercontent.com/u/156585?v=3&s=117" width="117">](https://github.com/brennie) |[<img alt="ogham" src="https://avatars0.githubusercontent.com/u/503760?v=3&s=117" width="117">](https://github.com/ogham) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[jespino](https://github.com/jespino) |[jimmycuadra](https://github.com/jimmycuadra) |[joshtriplett](https://github.com/joshtriplett) |[jtdowney](https://github.com/jtdowney) |[kbknapp](https://github.com/kbknapp) |[Keats](https://github.com/Keats) |
+[AluisioASG](https://github.com/AluisioASG) |[BurntSushi](https://github.com/BurntSushi) |[nox](https://github.com/nox) |[pixelistik](https://github.com/pixelistik) |[brennie](https://github.com/brennie) |[ogham](https://github.com/ogham) |
 
-[<img alt="matthiasbeyer" src="https://avatars.githubusercontent.com/u/427866?v=3&s=117" width="117">](https://github.com/matthiasbeyer) |[<img alt="mernen" src="https://avatars.githubusercontent.com/u/6412?v=3&s=117" width="117">](https://github.com/mernen) |[<img alt="messense" src="https://avatars.githubusercontent.com/u/1556054?v=3&s=117" width="117">](https://github.com/messense) |[<img alt="mgeisler" src="https://avatars.githubusercontent.com/u/89623?v=3&s=117" width="117">](https://github.com/mgeisler) |[<img alt="mineo" src="https://avatars.githubusercontent.com/u/78236?v=3&s=117" width="117">](https://github.com/mineo) |[<img alt="musoke" src="https://avatars.githubusercontent.com/u/16665084?v=3&s=117" width="117">](https://github.com/musoke) |
+[<img alt="Bilalh" src="https://avatars3.githubusercontent.com/u/171602?v=3&s=117" width="117">](https://github.com/Bilalh) |[<img alt="dotdash" src="https://avatars2.githubusercontent.com/u/230962?v=3&s=117" width="117">](https://github.com/dotdash) |[<img alt="bradurani" src="https://avatars3.githubusercontent.com/u/4195952?v=3&s=117" width="117">](https://github.com/bradurani) |[<img alt="Seeker14491" src="https://avatars1.githubusercontent.com/u/6490497?v=3&s=117" width="117">](https://github.com/Seeker14491) |[<img alt="brianp" src="https://avatars2.githubusercontent.com/u/179134?v=3&s=117" width="117">](https://github.com/brianp) |[<img alt="casey" src="https://avatars1.githubusercontent.com/u/1945?v=3&s=117" width="117">](https://github.com/casey) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[matthiasbeyer](https://github.com/matthiasbeyer) |[mernen](https://github.com/mernen) |[messense](https://github.com/messense) |[mgeisler](https://github.com/mgeisler) |[mineo](https://github.com/mineo) |[musoke](https://github.com/musoke) |
+[Bilalh](https://github.com/Bilalh) |[dotdash](https://github.com/dotdash) |[bradurani](https://github.com/bradurani) |[Seeker14491](https://github.com/Seeker14491) |[brianp](https://github.com/brianp) |[casey](https://github.com/casey) |
 
-[<img alt="mvaude" src="https://avatars.githubusercontent.com/u/9532611?v=3&s=117" width="117">](https://github.com/mvaude) |[<img alt="N-006" src="https://avatars.githubusercontent.com/u/399312?v=3&s=117" width="117">](https://github.com/N-006) |[<img alt="nabijaczleweli" src="https://avatars.githubusercontent.com/u/6709544?v=3&s=117" width="117">](https://github.com/nabijaczleweli) |[<img alt="nelsonjchen" src="https://avatars.githubusercontent.com/u/5363?v=3&s=117" width="117">](https://github.com/nelsonjchen) |[<img alt="Nemo157" src="https://avatars.githubusercontent.com/u/81079?v=3&s=117" width="117">](https://github.com/Nemo157) |[<img alt="nicompte" src="https://avatars.githubusercontent.com/u/439369?v=3&s=117" width="117">](https://github.com/nicompte) |
+[<img alt="volks73" src="https://avatars2.githubusercontent.com/u/1915469?v=3&s=117" width="117">](https://github.com/volks73) |[<img alt="daboross" src="https://avatars2.githubusercontent.com/u/1152146?v=3&s=117" width="117">](https://github.com/daboross) |[<img alt="mernen" src="https://avatars3.githubusercontent.com/u/6412?v=3&s=117" width="117">](https://github.com/mernen) |[<img alt="dguo" src="https://avatars3.githubusercontent.com/u/2763135?v=3&s=117" width="117">](https://github.com/dguo) |[<img alt="davidszotten" src="https://avatars0.githubusercontent.com/u/412005?v=3&s=117" width="117">](https://github.com/davidszotten) |[<img alt="eddyb" src="https://avatars1.githubusercontent.com/u/77424?v=3&s=117" width="117">](https://github.com/eddyb) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[mvaude](https://github.com/mvaude) |[N-006](https://github.com/N-006) |[nabijaczleweli](https://github.com/nabijaczleweli) |[nelsonjchen](https://github.com/nelsonjchen) |[Nemo157](https://github.com/Nemo157) |[nicompte](https://github.com/nicompte) |
+[volks73](https://github.com/volks73) |[daboross](https://github.com/daboross) |[mernen](https://github.com/mernen) |[dguo](https://github.com/dguo) |[davidszotten](https://github.com/davidszotten) |[eddyb](https://github.com/eddyb) |
 
-[<img alt="nvzqz" src="https://avatars.githubusercontent.com/u/10367662?v=3&s=117" width="117">](https://github.com/nvzqz) |[<img alt="ogham" src="https://avatars.githubusercontent.com/u/503760?v=3&s=117" width="117">](https://github.com/ogham) |[<img alt="panicbit" src="https://avatars.githubusercontent.com/u/628445?v=3&s=117" width="117">](https://github.com/panicbit) |[<img alt="pixelistik" src="https://avatars.githubusercontent.com/u/170929?v=3&s=117" width="117">](https://github.com/pixelistik) |[<img alt="rnelson" src="https://avatars.githubusercontent.com/u/118361?v=3&s=117" width="117">](https://github.com/rnelson) |[<img alt="rtaycher" src="https://avatars.githubusercontent.com/u/324733?v=3&s=117" width="117">](https://github.com/rtaycher) |
+[<img alt="birkenfeld" src="https://avatars3.githubusercontent.com/u/144359?v=3&s=117" width="117">](https://github.com/birkenfeld) |[<img alt="tanakh" src="https://avatars1.githubusercontent.com/u/109069?v=3&s=117" width="117">](https://github.com/tanakh) |[<img alt="SirVer" src="https://avatars3.githubusercontent.com/u/140115?v=3&s=117" width="117">](https://github.com/SirVer) |[<img alt="idmit" src="https://avatars2.githubusercontent.com/u/2546728?v=3&s=117" width="117">](https://github.com/idmit) |[<img alt="archer884" src="https://avatars2.githubusercontent.com/u/679494?v=3&s=117" width="117">](https://github.com/archer884) |[<img alt="shepmaster" src="https://avatars3.githubusercontent.com/u/174509?v=3&s=117" width="117">](https://github.com/shepmaster) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[nvzqz](https://github.com/nvzqz) |[ogham](https://github.com/ogham) |[panicbit](https://github.com/panicbit) |[pixelistik](https://github.com/pixelistik) |[rnelson](https://github.com/rnelson) |[rtaycher](https://github.com/rtaycher) |
+[birkenfeld](https://github.com/birkenfeld) |[tanakh](https://github.com/tanakh) |[SirVer](https://github.com/SirVer) |[idmit](https://github.com/idmit) |[archer884](https://github.com/archer884) |[shepmaster](https://github.com/shepmaster) |
 
-[<img alt="Seeker14491" src="https://avatars.githubusercontent.com/u/6490497?v=3&s=117" width="117">](https://github.com/Seeker14491) |[<img alt="shepmaster" src="https://avatars.githubusercontent.com/u/174509?v=3&s=117" width="117">](https://github.com/shepmaster) |[<img alt="SirVer" src="https://avatars.githubusercontent.com/u/140115?v=3&s=117" width="117">](https://github.com/SirVer) |[<img alt="sru" src="https://avatars.githubusercontent.com/u/2485892?v=3&s=117" width="117">](https://github.com/sru) |[<img alt="SShrike" src="https://avatars.githubusercontent.com/u/4061736?v=3&s=117" width="117">](https://github.com/SShrike) |[<img alt="starkat99" src="https://avatars.githubusercontent.com/u/8295111?v=3&s=117" width="117">](https://github.com/starkat99) |
+[<img alt="jespino" src="https://avatars3.githubusercontent.com/u/290303?v=3&s=117" width="117">](https://github.com/jespino) |[<img alt="jtdowney" src="https://avatars2.githubusercontent.com/u/44654?v=3&s=117" width="117">](https://github.com/jtdowney) |[<img alt="andete" src="https://avatars1.githubusercontent.com/u/689017?v=3&s=117" width="117">](https://github.com/andete) |[<img alt="joshtriplett" src="https://avatars1.githubusercontent.com/u/162737?v=3&s=117" width="117">](https://github.com/joshtriplett) |[<img alt="malbarbo" src="https://avatars0.githubusercontent.com/u/1678126?v=3&s=117" width="117">](https://github.com/malbarbo) |[<img alt="iliekturtles" src="https://avatars0.githubusercontent.com/u/5081378?v=3&s=117" width="117">](https://github.com/iliekturtles) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[Seeker14491](https://github.com/Seeker14491) |[shepmaster](https://github.com/shepmaster) |[SirVer](https://github.com/SirVer) |[sru](https://github.com/sru) |[SShrike](https://github.com/SShrike) |[starkat99](https://github.com/starkat99) |
+[jespino](https://github.com/jespino) |[jtdowney](https://github.com/jtdowney) |[andete](https://github.com/andete) |[joshtriplett](https://github.com/joshtriplett) |[malbarbo](https://github.com/malbarbo) |[iliekturtles](https://github.com/iliekturtles) |
 
-[<img alt="SuperFluffy" src="https://avatars.githubusercontent.com/u/701177?v=3&s=117" width="117">](https://github.com/SuperFluffy) |[<img alt="swatteau" src="https://avatars.githubusercontent.com/u/5521255?v=3&s=117" width="117">](https://github.com/swatteau) |[<img alt="tanakh" src="https://avatars.githubusercontent.com/u/109069?v=3&s=117" width="117">](https://github.com/tanakh) |[<img alt="th4t" src="https://avatars.githubusercontent.com/u/2801030?v=3&s=117" width="117">](https://github.com/th4t) |[<img alt="tormol" src="https://avatars.githubusercontent.com/u/10460821?v=3&s=117" width="117">](https://github.com/tormol) |[<img alt="tshepang" src="https://avatars.githubusercontent.com/u/588486?v=3&s=117" width="117">](https://github.com/tshepang) |
+[<img alt="nicompte" src="https://avatars1.githubusercontent.com/u/439369?v=3&s=117" width="117">](https://github.com/nicompte) |[<img alt="NickeZ" src="https://avatars1.githubusercontent.com/u/492753?v=3&s=117" width="117">](https://github.com/NickeZ) |[<img alt="nvzqz" src="https://avatars3.githubusercontent.com/u/10367662?v=3&s=117" width="117">](https://github.com/nvzqz) |[<img alt="Geogi" src="https://avatars2.githubusercontent.com/u/1818316?v=3&s=117" width="117">](https://github.com/Geogi) |[<img alt="flying-sheep" src="https://avatars3.githubusercontent.com/u/291575?v=3&s=117" width="117">](https://github.com/flying-sheep) |[<img alt="peppsac" src="https://avatars0.githubusercontent.com/u/2198295?v=3&s=117" width="117">](https://github.com/peppsac) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[SuperFluffy](https://github.com/SuperFluffy) |[swatteau](https://github.com/swatteau) |[tanakh](https://github.com/tanakh) |[th4t](https://github.com/th4t) |[tormol](https://github.com/tormol) |[tshepang](https://github.com/tshepang) |
+[nicompte](https://github.com/nicompte) |[NickeZ](https://github.com/NickeZ) |[nvzqz](https://github.com/nvzqz) |[Geogi](https://github.com/Geogi) |[flying-sheep](https://github.com/flying-sheep) |[peppsac](https://github.com/peppsac) |
 
-[<img alt="tspiteri" src="https://avatars.githubusercontent.com/u/18604588?v=3&s=117" width="117">](https://github.com/tspiteri) |[<img alt="untitaker" src="https://avatars.githubusercontent.com/u/837573?v=3&s=117" width="117">](https://github.com/untitaker) |[<img alt="Vinatorul" src="https://avatars.githubusercontent.com/u/6770624?v=3&s=117" width="117">](https://github.com/Vinatorul) |[<img alt="vks" src="https://avatars.githubusercontent.com/u/33460?v=3&s=117" width="117">](https://github.com/vks) |[<img alt="volks73" src="https://avatars.githubusercontent.com/u/1915469?v=3&s=117" width="117">](https://github.com/volks73) |[<img alt="wdv4758h" src="https://avatars.githubusercontent.com/u/2716047?v=3&s=117" width="117">](https://github.com/wdv4758h) |
+[<img alt="hexjelly" src="https://avatars3.githubusercontent.com/u/435283?v=3&s=117" width="117">](https://github.com/hexjelly) |[<img alt="rnelson" src="https://avatars0.githubusercontent.com/u/118361?v=3&s=117" width="117">](https://github.com/rnelson) |[<img alt="swatteau" src="https://avatars0.githubusercontent.com/u/5521255?v=3&s=117" width="117">](https://github.com/swatteau) |[<img alt="tspiteri" src="https://avatars3.githubusercontent.com/u/18604588?v=3&s=117" width="117">](https://github.com/tspiteri) |[<img alt="vks" src="https://avatars1.githubusercontent.com/u/33460?v=3&s=117" width="117">](https://github.com/vks) |[<img alt="th4t" src="https://avatars1.githubusercontent.com/u/2801030?v=3&s=117" width="117">](https://github.com/th4t) |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[tspiteri](https://github.com/tspiteri) |[untitaker](https://github.com/untitaker) |[Vinatorul](https://github.com/Vinatorul) |[vks](https://github.com/vks) |[volks73](https://github.com/volks73) |[wdv4758h](https://github.com/wdv4758h) |
+[hexjelly](https://github.com/hexjelly) |[rnelson](https://github.com/rnelson) |[swatteau](https://github.com/swatteau) |[tspiteri](https://github.com/tspiteri) |[vks](https://github.com/vks) |[th4t](https://github.com/th4t) |
+
+[<img alt="mineo" src="https://avatars2.githubusercontent.com/u/78236?v=3&s=117" width="117">](https://github.com/mineo) |[<img alt="grossws" src="https://avatars1.githubusercontent.com/u/171284?v=3&s=117" width="117">](https://github.com/grossws) |[<img alt="messense" src="https://avatars3.githubusercontent.com/u/1556054?v=3&s=117" width="117">](https://github.com/messense) |[<img alt="mvaude" src="https://avatars2.githubusercontent.com/u/9532611?v=3&s=117" width="117">](https://github.com/mvaude) |[<img alt="panicbit" src="https://avatars1.githubusercontent.com/u/628445?v=3&s=117" width="117">](https://github.com/panicbit) |[<img alt="mitsuhiko" src="https://avatars2.githubusercontent.com/u/7396?v=3&s=117" width="117">](https://github.com/mitsuhiko) |
+:---: |:---: |:---: |:---: |:---: |:---: |
+[mineo](https://github.com/mineo) |[grossws](https://github.com/grossws) |[messense](https://github.com/messense) |[mvaude](https://github.com/mvaude) |[panicbit](https://github.com/panicbit) |[mitsuhiko](https://github.com/mitsuhiko) |
 
 
+
+
+This list was generated by [mgechev/github-contributors-list](https://github.com/mgechev/github-contributors-list)
--- a/third_party/rust/clap/Cargo.toml
+++ b/third_party/rust/clap/Cargo.toml
@@ -1,45 +1,46 @@
 [package]
 
 name = "clap"
-version = "2.20.5"
+version = "2.24.2"
 authors = ["Kevin K. <kbknapp@gmail.com>"]
 exclude = ["examples/*", "clap-test/*", "tests/*", "benches/*", "*.png", "clap-perf/*", "*.dot"]
 repository = "https://github.com/kbknapp/clap-rs.git"
 documentation = "https://docs.rs/clap/"
 homepage = "https://clap.rs/"
 readme = "README.md"
 license = "MIT"
 keywords = ["argument", "command", "arg", "parser", "parse"]
 categories = ["command-line-interface"]
 description = """
 A simple to use, efficient, and full featured  Command Line Argument Parser
 """
 
 [dependencies]
-bitflags              = "0.7.0"
-vec_map               = "0.6.0"
+bitflags              = "0.8.0"
+vec_map               = "0.8"
 unicode-width         = "0.1.4"
 unicode-segmentation  = "1.0.1"
 strsim    = { version = "0.6.0",  optional = true }
 ansi_term = { version = "0.9.0",  optional = true }
-term_size = { version = "0.2.2",  optional = true }
-libc      = { version = "0.2.20",  optional = true }
+term_size = { version = "0.3.0",  optional = true }
 yaml-rust = { version = "0.3.5",  optional = true }
-clippy    = { version = "~0.0.112", optional = true }
+clippy    = { version = "~0.0.131", optional = true }
+atty      = { version = "0.2.2",  optional = true }
 
 [dev-dependencies]
-regex = "~0.1.80"
+regex = "0.2"
+lazy_static = "0.2"
 
 [features]
 default     = ["suggestions", "color", "wrap_help"]
 suggestions = ["strsim"]
-color       = ["ansi_term", "libc"]
-wrap_help   = ["libc", "term_size"]
+color       = ["ansi_term", "atty"]
+wrap_help   = ["term_size"]
 yaml        = ["yaml-rust"]
 unstable    = [] # for building with unstable clap features (doesn't require nightly Rust) (currently none)
 nightly     = [] # for building with unstable Rust features (currently none)
 lints       = ["clippy"] # Requires nightly Rust
 debug       = [] # Enables debug messages
 no_cargo    = [] # Enable if you're not using Cargo, disables Cargo-env-var-dependent macros
 
 [profile.release]
@@ -59,17 +60,17 @@ debug-assertions = true
 codegen-units = 4
 
 [profile.test]
 opt-level = 1
 debug = true
 rpath = false
 lto = false
 debug-assertions = true
-codegen-units = 2
+codegen-units = 4
 
 [profile.bench]
 opt-level = 3
 debug = false
 rpath = false
 lto = true
 debug-assertions = false
 
--- a/third_party/rust/clap/README.md
+++ b/third_party/rust/clap/README.md
@@ -40,141 +40,74 @@ Table of Contents
 * [License](#license)
 * [Recent Breaking Changes](#recent-breaking-changes)
   * [Deprecations](#deprecations)
 
 Created by [gh-md-toc](https://github.com/ekalinin/github-markdown-toc)
 
 ## What's New
 
-Here's the highlights for v2.20.5
+Here's the highlights for v2.24.2
 
-* Fixes a critical bug in the `clap_app!` macro of a missing fragment specifier when using `!property` style tags.
+* fixes a bug where args that allow values to start with a hyphen couldnt contain a double hyphen -- as a value 
+* fixes a bug where positional argument help text is misaligned 
+* **App::template docs:**  adds details about the necessity to use AppSettings::UnifiedHelpMessage when using {unified} tags in the help template 
+* **Arg::allow_hyphen_values docs:**  updates the docs to include warnings for allow_hyphen_values and multiple(true) used together 
+* **clap_app! docs:**  adds using the @group specifier to the macro docs 
+* adds a debug assertion to ensure all args added to groups actually exist 
+
+Here's the highlights for v2.21.0 to v2.24.1
 
-
-Here's the highlights from v2.0.0 to v2.20.4
-
-* Fixes a bug that tried to propogate global args multiple times when generating multiple completion scripts
+* fixes a bug where args with last(true) and required(true) set were not being printed in the usage string 
+* fixes a bug that was printing the arg name, instead of value name when Arg::last(true) was used 
+* fixes a bug where flags were parsed as flags AND positional values when specific combinations of settings were used 
+* **README.md:**  fix some typos 
+* **Arg:**  add `default_value_os` 
+* **arg_matches.rs:**  Added a Default implementation for Values and OsValues iterators. 
+* **PowerShell Completions:**
+  * fixes a bug where powershells completions cant be used if no subcommands are defined
+  * massively dedups subcommand names in the generate script to make smaller scripts that are still functionally equiv
+* allows specifying a short help vs a long help (i.e. varying levels of detail depending on if -h or --help was used)
+* **clap_app!:**  adds support for arg names with hyphens similar to longs with hyphens
+* fixes a bug that wasn't allowing help and version to be properly overridden
+  * This may break code that was relying on this bug! If you add a flag with a long of `help` manually *and* rely on the help message to be printed automatically your code could break. Please see the commit link in the full CHANGELOG.md
+* `App::long_about`
+* `App::long_version`
+* `App::print_long_help`
+* `App::write_long_help`
+* `App::print_long_version`
+* `App::write_long_version`
+* `Arg::long_help`
+* **clap_app!:**  documents the `--("some-arg")` method for using args with hyphens inside them
+* fixes the usage string regression when using help templates
+* fixes a big regression with custom usage strings
+* adds the ability to change the name of the App instance after creation
+* adds ability to hide the default value of an argument from the help string
+* fixes support for loading author info from yaml
+* adds fish subcommand help support
+* options that use `require_equals(true)` now display the equals sign in help messages, usage strings, and errors
+* setting the max term width now correctly propagates down through child subcommands
+* fixes the precedence of this error to prioritize over other error messages
+* fixes some regression bugs resulting from old asserts in debug mode.
+* adds the ability to mark a positional argument as 'last' which means it should be used with `--` syntax and can be accessed early to effectivly skip other positional args
+* Some performance improvements by reducing the ammount of duplicate work, cloning, and allocations in all cases.
+* Some massive performance gains when using many args (i.e. things like shell glob expansions)
+* adds a setting to allow one to infer shortened subcommands or aliases (i.e. for subcommmand "test", "t", "te", or "tes" would be allowed assuming no other ambiguities)
+* when `AppSettings::SubcommandsNegateReqs` and `ArgsNegateSubcommands` are used, a new more accurate double line usage string is shown
+* provides `default_value_os` and `default_value_if[s]_os`
+* provides `App::help_message` and `App::version_message` which allows one to override the auto-generated help/version flag associated help
+* adds the ability to require the equals syntax with options `--opt=val`
+* doesn't print the argument sections in the help message if all args in that section are hidden
+* doesn't include the various `[ARGS]` `[FLAGS]` or `[OPTIONS]` if the only ones available are hidden
+* now correctly shows subcommand as required in the usage string when AppSettings::SubcommandRequiredElseHelp is used
+* fixes some "memory leaks" when an error is detected and clap exits
+* fixes a trait that's marked private accidentlly, but should be crate internal public
+* fixes a bug that tried to propogate global args multiple times when generating multiple completion scripts
+* Fixes a critical bug in the `clap_app!` macro of a missing fragment specifier when using `!property` style tags.
 * Fix examples link in CONTRIBUTING.md
-* **Completions**: fixes bash completions for commands that have an underscore in the name
-* **Completions**: fixes a bug where ZSH completions would panic if the binary name had an underscore in it
-* allow final word to be wrapped in wrap_help
-* **Completions**: fixes a bug where global args weren't included in the generated completion scripts
-* **Macros Documentation:**  adds a warning about changing values in Cargo.toml not triggering a rebuild automatically
-* Fixes a critical bug where subcommand settings were being propogated too far
-* Adds ArgGroup::multiple to the supported YAML fields for building ArgGroups from YAML
-* Fixes a bug where the final word wasn't wrapped in help messages
-* Fixes finding required arguments in group arguments
-* **ArgsNegateSubcommands:**  disables args being allowed between subcommands
-* **DontCollapseArgsInUsage:** disables the collapsing of positional args into `[ARGS]` in the usage string
-* **DisableHelpSubcommand:**  disables building the `help` subcommand
-* **AllowMissingPositional:**  allows one to implement `$ prog [optional] <required>` style CLIs where the second postional argument is required, but the first is optional
-* **PropagateGlobalValuesDown:**  automatically propagats global arg's values down through *used* subcommands
-* **Arg::value_terminator:**  adds the ability to terminate multiple values with a given string or char
-* **Arg::default_value_if[s]:**  adds new methods for *conditional* default values (such as a particular value from another argument was used)
-* **Arg::requires_if[s]:**  adds the ability to *conditionally* require additional args (such as if a particular value was used)
-* **Arg::required_if[s]:**  adds the ability for an arg to be *conditionally* required (i.e. "arg X is only required if arg Y was used with value Z")
-* **Arg::validator_os:**  adds ability to validate values which may contain invalid UTF-8
-* **crate_description!:** Uses the `Cargo.toml` description field to fill in the `App::about` method at compile time
-* **crate_name!:** Uses the `Cargo.toml` name field to fill in the `App::new` method at compile time
-* **app_from_crate!:** Combines `crate_version!`, `crate_name!`, `crate_description!`, and `crate_authors!` into a single macro call to build a default `App` instance from the `Cargo.toml` fields
-* **no_cargo:**  adds a `no_cargo` feature to disable Cargo-env-var-dependent macros for those *not* using `cargo` to build their crates
-* **Options:**  fixes a critical bug where options weren't forced to have a value
-*   fixes a bug where calling the help of a subcommand wasn't ignoring required args of parent commands
-* **Help Subcommand:**  fixes a bug where the help subcommand couldn't be overriden
-* **Low Index Multiples:**  fixes a bug which caused combinations of LowIndexMultiples and `Arg::allow_hyphen_values` to fail parsing
-* **Default Values:**  improves the error message when default values are involved
-* **YAML:**  adds conditional requirements and conditional default values to YAML
-*  Support `--("some-arg-name")` syntax for defining long arg names when using `clap_app!` macro
-*  Support `("some app name")` syntax for defining app names when using `clap_app!` macro
-* **Help Wrapping:**  long app names (with spaces), authors, and descriptions are now wrapped appropriately
-* **Conditional Default Values:**  fixes the failing doc tests of Arg::default_value_ifs
-* **Conditional Requirements:**  adds docs for Arg::requires_ifs
-* Fixes a bug where calling the help of a subcommand wasn't ignoring required args of parent commands
-* Fixes a bug by escaping square brackets in ZSH completions which were causing conflicts and errors.
-* **Bash Completion:**  allows bash completion to fall back to traidtional bash completion upon no matching completing function
-* **Arg Setting**: Allows specifying an `AllowLeadingHyphen` style setting for values only for specific args, vice command wide
-* **Validators:**  improves the error messages for validators
-* **Required Unless:**  fixes a bug where having required_unless set doesn't work when conflicts are also set
-* **ZSH Completions:**  fixes an issue where zsh completions caused panics if there were no subcommands
-* **Completions:**  Adds completion support for Microsoft PowerShell! (Thanks to @Arnavion)
-* Allows specifying the second to last positional argument as `multiple(true)` (i.e. things such as `mv <files>... <target>`)
-* Adds an `App::get_name` and `App::get_bin_name`
-* Conflicting argument errors are now symetrical, meaning more consistent and better usage suggestions
-* **Completions:**  adds automatic ZSH completion script generation support! :tada: :tada:
-* **AppSettings:**  adds new setting `AppSettings::AllowNegativeNumbers` which functions like `AllowLeadingHyphen` except only allows undefined negative numbers to pass parsing.
-* Stabilize `clap_app!` macro (i.e. no longer need to use `unstable` feature)
-* Deprecate `App::with_defaults`
-* One can now alias arguments either visibly (which appears in the help text) or invisibly just like subcommands!
-* The `from_usage` parser now correctly handles non-ascii names / options and help!
-* **Value Delimiters:**  fixes the confusion around implicitly setting value delimiters. (The default is to *not* use a delimiter unless explicitly set)
-* Changes the default value delimiter rules (i.e. the default is `use_delimiter(false)` *unless* a setting/method that implies multiple values was used) **[Bugfix that *may* "break" code]**
- * If code breaks, simply add `Arg::use_delimiter(true)` to the affected args
-* Adds ability to hide the possible values from the help text on a per argument basis, instead of command wide
-* Allows for limiting detected terminal width (i.e. wrap at `x` length, unless the terminal width is *smaller*)
-* `clap` now ignores hard newlines in help messages and properly re-aligns text, but still wraps if the term width is too small
-* Adds support for the setting `Arg::require_delimiter` from YAML
-* `clap` no longer requires one to use `{n}` inside help text to insert a newline that is properly aligned. One can now use the normal `\n`.
-* `clap` now ignores hard newlines in help messages and properly re-aligns text, but still wraps if the term width is too small
-* Errors can now have custom description
-* Uses `term_size` instead of home-grown solution on Windows
-* Adds the ability to wrap help text intelligently on Windows!
-* Moves docs to [docs.rs!](https://docs.rs/clap/)!
-* Automatically moves help text to the next line and wraps when term width is determined to be too small, or help text is too long
-* Vastly improves *development* error messages when using YAML
-* Adds a shorthand way to ignore help text wrapping and use source formatting (i.e. `App::set_term_width(0)`)
-* **Help Subcommand:**  fixes misleading usage string when using multi-level subcommmands such as `myprog help subcmd1 subcmd2`
-* **YAML:**  allows using lists or single values with certain arg declarations for increased ergonomics
-* **Fish Shell Completions:**  one can generate a basic fish completions script at compile time!
-* Adds the ability to generate completions to an `io::Write` object
-* Adds an `App::unset_setting` and `App::unset_settings`
-* **Completions:**  one can now [generate a bash completions](https://docs.rs/clap/2.9.0/clap/struct.App.html#method.gen_completions) script at compile time! These completions work with options using [possible values](https://docs.rs/clap/2.9.0/clap/struct.Arg.html#method.possible_values), [subcommand aliases](https://docs.rs/clap/2.9.0/clap/struct.App.html#method.aliases), and even multiple levels of subcommands
-* **Arg:**  adds new optional setting [`Arg::require_delimiter`](https://docs.rs/clap/2.8.0/clap/struct.Arg.html#method.require_delimiter) which requires val delimiter to parse multiple values
-* The terminal sizing portion has been factored out into a separate crate, [term_size](https://crates.io/crates/term_size)
-* Options using multiple values and delimiters no longer parse additional values after a trailing space (i.e. `prog -o 1,2 file.txt` parses as `1,2` for `-o` and `file.txt` for a positional arg)
-* Using options using multiple values and with an `=` no longer parse args after the trailing space as values (i.e. `prog -o=1 file.txt` parses as `1` for `-o` and `file.txt` for a positional arg)
-* **Usage Strings:**  `[FLAGS]` and `[ARGS]` are no longer blindly added to usage strings, instead only when applicable
-* `arg_enum!`:  allows using more than one meta item, or things like `#[repr(C)]` with `arg_enum!`s
-* `App::print_help`: now prints the same as would have been printed by `--help` or the like
-* Prevents invoking `<cmd> help help` and displaying incorrect help message
-* Subcommand help messages requested via `<cmd> help <sub>` now correctly match `<cmd> <sub> --help`
-* One can now specify groups which require AT LEAST one of the args
-* Allows adding multiple ArgGroups per Arg
-* **Global Settings:** One can now set an `AppSetting` which is propogated down through child subcommands
-* **Terminal Wrapping:**  Allows wrapping at specified term width (Even on Windows!) (can now set an absolute width to "smart" wrap at)
-* **SubCommands/Aliases:**  adds support for visible aliases for subcommands (i.e. aliases that are dipslayed in the help message)
-* **Subcommands/Aliases:**  when viewing the help of an alias, it now display help of the aliased subcommand
-* Adds new setting to stop delimiting values with `--` or `AppSettings::TrailingVarArg`
-* Subcommands now support aliases - think of them as hidden subcommands that dispatch to said subcommand automatically
-* Fixed times when `ArgGroup`s are duplicated in usage strings
-* **Before Help:**  adds support for displaying info before help message
-* **Required Unless:**  adds support for allowing args that are required unless certain other args are present
-* **New Help Template Engine!**: Now you have full control over the layout of your help message. Major thanks to @hgrecco
-* **Pull crate Authors from Cargo.toml**: One can now use the `crate_authors!` macro to automatically pull the crate authors from their Cargo.toml file
-* **Colored Help Messages**: Help messages can now be optionally colored (See the `AppSettings::ColoredHelp` setting). Screenshot below.
-* **Help text auto wraps and aligns at for subcommands too!** - Long help strings of subcommands will now properly wrap and align to term width on Linux and OS X. This can be turned off as well.
-* **Help text auto wraps and aligns at term width!** - Long help strings will now properly wrap and align to term width on Linux and OS X (and presumably Unix too). This can be turned off as well.
-* **Can customize the order of opts, flags, and subcommands in help messages**  - Instead of using the default alphabetical order, you can now re-arrange the order of your args and subcommands in help message. This helps to emphasize more popular or important options.
-* **Can auto-derive the order from declaration order** - Have a bunch of args or subcommmands to re-order? You can now just derive the order from the declaration order!
-* **Help subcommand now accepts other subcommands as arguments!** - Similar to other CLI precedents, the `help` subcommand can now accept other subcommands as arguments to display their help message. i.e. `$ myprog help mysubcmd` (*Note* these can even be nested heavily such as `$ myprog help subcmd1 subcmd2 subcmd3` etc.)
-* **Default Values**: Args can now specify default values
-* **Next Line Help**: Args can have help strings on the line following the argument (useful for long arguments, or those with many values). This can be set command-wide or for individual args
-
-Here's a gif of them in action!
-
-![zsh-comppletions](http://i.imgur.com/rwlMbAv.gif)
-
-An example of the help text wrapping at term width:
-
-![screenshot](http://i.imgur.com/PAJzJJG.png)
-
-An example of the optional colored help:
-
-![screenshot](http://i.imgur.com/7fs2h5j.png)
-
 
 For full details, see [CHANGELOG.md](https://github.com/kbknapp/clap-rs/blob/master/CHANGELOG.md)
 
 ## About
 
 `clap` is used to parse *and validate* the string of command line arguments provided by the user at runtime. You provide the list of valid possibilities, and `clap` handles the rest. This means you focus on your *applications* functionality, and less on the parsing and validating of arguments.
 
 `clap` also provides the traditional version and help switches (or flags) 'for free' meaning automatically with no configuration. It does this by checking list of valid possibilities you supplied and adding only the ones you haven't already defined. If you are using subcommands, `clap` will also auto-generate a `help` subcommand for you in addition to the traditional flags.
@@ -534,18 +467,18 @@ Define a list of valid arguments for you
 
 Then run `cargo build` or `cargo update && cargo build` for your project.
 
 ### Optional Dependencies / Features
 
 #### Features enabled by default
 
 * **"suggestions"**: Turns on the `Did you mean '--myoption'?` feature for when users make typos. (builds dependency `strsim`)
-* **"color"**: Turns on colored error messages. This feature only works on non-Windows OSs. (builds dependency `ansi-term` and `libc`)
-* **"wrap_help"**: Wraps the help at the actual terminal width when available, instead of 120 chracters. (builds dependency `term_size`, and `libc`)
+* **"color"**: Turns on colored error messages. This feature only works on non-Windows OSs. (builds dependency `ansi-term`)
+* **"wrap_help"**: Wraps the help at the actual terminal width when available, instead of 120 characters. (builds dependency `term_size`)
 
 To disable these, add this to your `Cargo.toml`:
 
 ```toml
 [dependencies.clap]
 version = "2.19"
 default-features = false
 ```
@@ -594,24 +527,24 @@ Contributions are always welcome! And th
 
 Another really great way to help is if you find an interesting, or helpful way in which to use `clap`. You can either add it to the [examples/](examples) directory, or file an issue and tell me. I'm all about giving credit where credit is due :)
 
 Please read [CONTRIBUTING.md](.github/CONTRIBUTING.md) before you start contributing.
 
 
 ### Testing Code
 
-To test with all features both enabled and disabled, you can run theese commands:
+To test with all features both enabled and disabled, you can run these commands:
 
 ```sh
 $ cargo test --no-default-features
 $ cargo test --features "yaml unstable"
 ```
 
-Alternatively, if you have [`just`](https://github.com/casey/just) installed you can run the prebuilt recipies. *Not* using `just` is prfeclty fine as well, it simply bundles commands automatically.
+Alternatively, if you have [`just`](https://github.com/casey/just) installed you can run the prebuilt recipes. *Not* using `just` is perfectly fine as well, it simply bundles commands automatically.
 
 For example, to test the code, as above simply run:
 
 ```sh
 $ just run-tests
 ```
 
 From here on, I will list the appropriate `cargo` command as well as the `just` command.
@@ -671,17 +604,17 @@ There are a few goals of `clap` that I'd
 * `panic!` on *developer* error, exit gracefully on *end-user* error
 
 ### Compatibility Policy
 
 Because `clap` takes SemVer and compatibility seriously, this is the official policy regarding breaking changes and minimum required versions of Rust.
 
 `clap` will pin the minimum required version of Rust to the CI builds. Bumping the minimum version of Rust is considered a minor breaking change, meaning *at a minimum* the minor version of `clap` will be bumped.
 
-In order to keep from being suprised of breaking changes, it is **highly** recommended to use the `~major.minor.patch` style in your `Cargo.toml` only if you wish to target a version of Rust that is *older* than current stable minus two releases:
+In order to keep from being surprised of breaking changes, it is **highly** recommended to use the `~major.minor.patch` style in your `Cargo.toml` only if you wish to target a version of Rust that is *older* than current stable minus two releases:
 
 ```toml
 [dependencies]
 clap = "~2.19.0"
 ```
 
 This will cause *only* the patch version to be updated upon a `cargo update` call, and therefore cannot break due to new features, or bumped minimum versions of Rust.
 
@@ -689,17 +622,17 @@ This will cause *only* the patch version
 
 `clap` will officially support current stable Rust, minus two releases, but may work with prior releases as well. For example, current stable Rust at the time of this writing is 1.13.0, meaning `clap` is guaranteed to compile with 1.11.0 and beyond.
 At the 1.14.0 release, `clap` will be guaranteed to compile with 1.12.0 and beyond, etc.
 
 Upon bumping the minimum version of Rust (assuming it's within the stable-2 range), it *must* be clearly annotated in the `CHANGELOG.md`
 
 #### Breaking Changes
 
-`clap` takes a similar policy to Rust and will bump the major veresion number upon breaking changes with only the following exceptions:
+`clap` takes a similar policy to Rust and will bump the major version number upon breaking changes with only the following exceptions:
 
  * The breaking change is to fix a security concern
  * The breaking change is to be fixing a bug (i.e. relying on a bug as a feature)
  * The breaking change is a feature isn't used in the wild, or all users of said feature have given approval *prior* to the change
 
 ## License
 
 `clap` is licensed under the MIT license. Please read the [LICENSE-MIT](LICENSE-MIT) file in this repository for more information.
--- a/third_party/rust/clap/clap-test.rs
+++ b/third_party/rust/clap/clap-test.rs
@@ -4,21 +4,24 @@ mod test {
     use std::io::{Cursor, Write};
 
     use regex::Regex;
 
     use clap::{App, Arg, SubCommand, ArgGroup};
 
     fn compare<S, S2>(l: S, r: S2) -> bool
         where S: AsRef<str>,
-              S2: AsRef<str> {
+              S2: AsRef<str>
+    {
         let re = Regex::new("\x1b[^m]*m").unwrap();
         // Strip out any mismatching \r character on windows that might sneak in on either side
-        let left = re.replace_all(&l.as_ref().trim().replace("\r", "")[..], "");
-        let right = re.replace_all(&r.as_ref().trim().replace("\r", "")[..], "");
+        let ls = l.as_ref().trim().replace("\r", "");
+        let rs = r.as_ref().trim().replace("\r", "");
+        let left = re.replace_all(&*ls, "");
+        let right = re.replace_all(&*rs, "");
         let b = left == right;
         if !b {
             println!("");
             println!("--> left");
             println!("{}", left);
             println!("--> right");
             println!("{}", right);
             println!("--")
@@ -64,9 +67,9 @@ mod test {
             ])
             .subcommand(SubCommand::with_name("subcmd")
                                     .about("tests subcommands")
                                     .version("0.1")
                                     .author("Kevin K. <kbknapp@gmail.com>")
                                     .arg_from_usage("-o --option [scoption]... 'tests options'")
                                     .arg_from_usage("[scpositional] 'tests positionals'"))
     }
-}
\ No newline at end of file
+}
--- a/third_party/rust/clap/justfile
+++ b/third_party/rust/clap/justfile
@@ -1,16 +1,19 @@
 @update-contributors:
 	echo 'Removing old CONTRIBUTORS.md'
 	mv CONTRIBUTORS.md CONTRIBUTORS.md.bak
 	echo 'Downloading a list of new contributors'
-	echo "The following is a list of contributors in alphabetical order:" > CONTRIBUTORS.md
+	echo "the following is a list of contributors:" > CONTRIBUTORS.md
 	echo "" >> CONTRIBUTORS.md
 	echo "" >> CONTRIBUTORS.md
-	githubcontrib --owner kbknapp --repo clap-rs --sha master --cols 6 --format md --showlogin true --sortBy login >> CONTRIBUTORS.md
+	githubcontrib --owner kbknapp --repo clap-rs --sha master --cols 6 --format md --showlogin true --sortBy contributions --sortOrder desc >> CONTRIBUTORS.md
+	echo "" >> CONTRIBUTORS.md
+	echo "" >> CONTRIBUTORS.md
+	echo "This list was generated by [mgechev/github-contributors-list](https://github.com/mgechev/github-contributors-list)" >> CONTRIBUTORS.md
 	rm CONTRIBUTORS.md.bak
 
 run-test TEST:
 	cargo test --test {{TEST}}
 
 debug TEST:
 	cargo test --test {{TEST}} --features debug
 
--- a/third_party/rust/clap/src/app/help.rs
+++ b/third_party/rust/clap/src/app/help.rs
@@ -6,16 +6,17 @@ use std::io::{self, Cursor, Read, Write}
 use std::usize;
 
 // Internal
 use app::{App, AppSettings};
 use app::parser::Parser;
 use args::{AnyArg, ArgSettings, DispOrder};
 use errors::{Error, Result as ClapResult};
 use fmt::{Format, Colorizer};
+use app::usage;
 
 // Third Party
 use unicode_width::UnicodeWidthStr;
 #[cfg(feature = "wrap_help")]
 use term_size;
 use unicode_segmentation::UnicodeSegmentation;
 use vec_map::VecMap;
 
@@ -83,28 +84,30 @@ pub struct Help<'a> {
     writer: &'a mut Write,
     next_line_help: bool,
     hide_pv: bool,
     term_w: usize,
     color: bool,
     cizer: Colorizer,
     longest: usize,
     force_next_line: bool,
+    use_long: bool,
 }
 
 // Public Functions
 impl<'a> Help<'a> {
     /// Create a new `Help` instance.
     pub fn new(w: &'a mut Write,
                next_line_help: bool,
                hide_pv: bool,
                color: bool,
                cizer: Colorizer,
                term_w: Option<usize>,
-               max_w: Option<usize>)
+               max_w: Option<usize>,
+               use_long: bool)
                -> Self {
         debugln!("Help::new;");
         Help {
             writer: w,
             next_line_help: next_line_help,
             hide_pv: hide_pv,
             term_w: match term_w {
                 Some(width) => if width == 0 { usize::MAX } else { width },
@@ -115,59 +118,61 @@ impl<'a> Help<'a> {
                                  Some(mw) => mw,
                              })
                 }
             },
             color: color,
             cizer: cizer,
             longest: 0,
             force_next_line: false,
+            use_long: use_long,
         }
     }
 
     /// Reads help settings from an App
     /// and write its help to the wrapped stream.
-    pub fn write_app_help(w: &'a mut Write, app: &App) -> ClapResult<()> {
+    pub fn write_app_help(w: &'a mut Write, app: &App, use_long: bool) -> ClapResult<()> {
         debugln!("Help::write_app_help;");
-        Self::write_parser_help(w, &app.p)
+        Self::write_parser_help(w, &app.p, use_long)
     }
 
     /// Reads help settings from a Parser
     /// and write its help to the wrapped stream.
-    pub fn write_parser_help(w: &'a mut Write, parser: &Parser) -> ClapResult<()> {
+    pub fn write_parser_help(w: &'a mut Write, parser: &Parser, use_long: bool) -> ClapResult<()> {
         debugln!("Help::write_parser_help;");
-        Self::_write_parser_help(w, parser, false)
+        Self::_write_parser_help(w, parser, false, use_long)
     }
 
     /// Reads help settings from a Parser
     /// and write its help to the wrapped stream which will be stderr. This method prevents
     /// formatting when required.
     pub fn write_parser_help_to_stderr(w: &'a mut Write, parser: &Parser) -> ClapResult<()> {
         debugln!("Help::write_parser_help;");
-        Self::_write_parser_help(w, parser, true)
+        Self::_write_parser_help(w, parser, true, false)
     }
 
     #[doc(hidden)]
-    pub fn _write_parser_help(w: &'a mut Write, parser: &Parser, stderr: bool) -> ClapResult<()> {
+    pub fn _write_parser_help(w: &'a mut Write, parser: &Parser, stderr: bool, use_long: bool) -> ClapResult<()> {
         debugln!("Help::write_parser_help;");
         let nlh = parser.is_set(AppSettings::NextLineHelp);
         let hide_v = parser.is_set(AppSettings::HidePossibleValuesInHelp);
         let color = parser.is_set(AppSettings::ColoredHelp);
         let cizer = Colorizer {
             use_stderr: stderr,
             when: parser.color(),
         };
         Self::new(w,
                   nlh,
                   hide_v,
                   color,
                   cizer,
                   parser.meta.term_w,
-                  parser.meta.max_w)
-            .write_help(parser)
+                  parser.meta.max_w,
+                  use_long)
+                .write_help(parser)
     }
 
     /// Writes the parser help to the wrapped stream.
     pub fn write_help(&mut self, parser: &Parser) -> ClapResult<()> {
         debugln!("Help::write_help;");
         if let Some(h) = parser.meta.help_str {
             try!(write!(self.writer, "{}", h).map_err(Error::from));
         } else if let Some(tmpl) = parser.meta.template {
@@ -185,24 +190,23 @@ impl<'a> Help<'a> {
     fn write_args_unsorted<'b: 'd, 'c: 'd, 'd, I: 'd>(&mut self, args: I) -> io::Result<()>
         where I: Iterator<Item = &'d ArgWithOrder<'b, 'c>>
     {
         debugln!("Help::write_args_unsorted;");
         // The shortest an arg can legally be is 2 (i.e. '-x')
         self.longest = 2;
         let mut arg_v = Vec::with_capacity(10);
         for arg in args.filter(|arg| {
-            !(arg.is_set(ArgSettings::Hidden)) || arg.is_set(ArgSettings::NextLineHelp)
-        }) {
+                                   !(arg.is_set(ArgSettings::Hidden)) ||
+                                   arg.is_set(ArgSettings::NextLineHelp)
+                               }) {
             if arg.longest_filter() {
                 self.longest = cmp::max(self.longest, arg.to_string().len());
             }
-            if !arg.is_set(ArgSettings::Hidden) {
-                arg_v.push(arg)
-            }
+            arg_v.push(arg)
         }
         let mut first = true;
         for arg in arg_v {
             if first {
                 first = false;
             } else {
                 try!(self.writer.write_all(b"\n"));
             }
@@ -279,17 +283,23 @@ impl<'a> Help<'a> {
         }
         if arg.takes_value() {
             if let Some(l) = arg.long() {
                 if arg.short().is_some() {
                     try!(write!(self.writer, ", "));
                 }
                 try!(color!(self, "--{}", l, good))
             }
-            try!(write!(self.writer, " "));
+
+            let sep = if arg.is_set(ArgSettings::RequireEquals) {
+                "="
+            } else {
+                " "
+            };
+            try!(write!(self.writer, "{}", sep));
         } else if let Some(l) = arg.long() {
             if arg.short().is_some() {
                 try!(write!(self.writer, ", "));
             }
             try!(color!(self, "--{}", l, good));
         }
         Ok(())
     }
@@ -379,28 +389,31 @@ impl<'a> Help<'a> {
         }
         Ok(spec_vals)
     }
 
     fn write_before_after_help(&mut self, h: &str) -> io::Result<()> {
         debugln!("Help::write_before_after_help;");
         let mut help = String::new();
         // determine if our help fits or needs to wrap
-        debugln!("Help::write_before_after_help: Term width...{}", self.term_w);
+        debugln!("Help::write_before_after_help: Term width...{}",
+                 self.term_w);
         let too_long = str_width(h) >= self.term_w;
 
         debug!("Help::write_before_after_help: Too long...");
         if too_long || h.contains("{n}") {
             sdebugln!("Yes");
             help.push_str(h);
             debugln!("Help::write_before_after_help: help: {}", help);
-            debugln!("Help::write_before_after_help: help width: {}", str_width(&*help));
+            debugln!("Help::write_before_after_help: help width: {}",
+                     str_width(&*help));
             // Determine how many newlines we need to insert
-            debugln!("Help::write_before_after_help: Usable space: {}", self.term_w);
-            let longest_w = find_longest!(help);            
+            debugln!("Help::write_before_after_help: Usable space: {}",
+                     self.term_w);
+            let longest_w = find_longest!(help);
             help = help.replace("{n}", "\n");
             wrap_help(&mut help, longest_w, self.term_w);
         } else {
             sdebugln!("No");
         }
         let help = if !help.is_empty() {
             &*help
         } else {
@@ -419,18 +432,22 @@ impl<'a> Help<'a> {
         }
         Ok(())
     }
 
     /// Writes argument's help to the wrapped stream.
     fn help<'b, 'c>(&mut self, arg: &ArgWithDisplay<'b, 'c>, spec_vals: &str) -> io::Result<()> {
         debugln!("Help::help;");
         let mut help = String::new();
-        let h = arg.help().unwrap_or("");
-        let nlh = self.next_line_help || arg.is_set(ArgSettings::NextLineHelp);
+        let h = if self.use_long {
+            arg.long_help().unwrap_or(arg.help().unwrap_or(""))
+        } else {
+            arg.help().unwrap_or(arg.long_help().unwrap_or(""))
+        };
+        let nlh = self.next_line_help || arg.is_set(ArgSettings::NextLineHelp) || self.use_long;
         debugln!("Help::help: Next Line...{:?}", nlh);
 
         let spcs = if nlh || self.force_next_line {
             12 // "tab" * 3
         } else {
             self.longest + 12
         };
 
@@ -446,17 +463,17 @@ impl<'a> Help<'a> {
             sdebugln!("Yes");
             help.push_str(h);
             help.push_str(&*spec_vals);
             debugln!("Help::help: help...{}", help);
             debugln!("Help::help: help width...{}", str_width(&*help));
             // Determine how many newlines we need to insert
             let avail_chars = self.term_w - spcs;
             debugln!("Help::help: Usable space...{}", avail_chars);
-            let longest_w = find_longest!(help);            
+            let longest_w = find_longest!(help);
             help = help.replace("{n}", "\n");
             wrap_help(&mut help, longest_w, avail_chars);
         } else {
             sdebugln!("No");
         }
         let help = if !help.is_empty() {
             &*help
         } else if spec_vals.is_empty() {
@@ -476,93 +493,102 @@ impl<'a> Help<'a> {
                     try!(write!(self.writer, "{}{}{}", TAB, TAB, TAB));
                 } else if arg.has_switch() {
                     write_nspaces!(self.writer, self.longest + 12);
                 } else {
                     write_nspaces!(self.writer, self.longest + 8);
                 }
                 try!(write!(self.writer, "{}", part));
             }
+        } else if nlh || self.force_next_line {
+            try!(write!(self.writer, "{}", help));
+            try!(write!(self.writer, "\n"));
         } else {
             try!(write!(self.writer, "{}", help));
         }
         Ok(())
     }
 
     fn spec_vals(&self, a: &ArgWithDisplay) -> String {
         debugln!("Help::spec_vals: a={}", a);
         let mut spec_vals = vec![];
-        if let Some(pv) = a.default_val() {
-            debugln!("Help::spec_vals: Found default value...[{}]", pv);
-            spec_vals.push(format!(" [default: {}]",
-                                   if self.color {
-                                       self.cizer.good(pv)
-                                   } else {
-                                       Format::None(pv)
-                                   }));
+        if !a.is_set(ArgSettings::HideDefaultValue) {
+            if let Some(pv) = a.default_val() {
+                debugln!("Help::spec_vals: Found default value...[{:?}]", pv);
+                spec_vals.push(format!(" [default: {}]",
+                                       if self.color {
+                                           self.cizer.good(pv.to_string_lossy())
+                                       } else {
+                                           Format::None(pv.to_string_lossy())
+                                       }));
+            }
         }
         if let Some(ref aliases) = a.aliases() {
             debugln!("Help::spec_vals: Found aliases...{:?}", aliases);
             spec_vals.push(format!(" [aliases: {}]",
                                    if self.color {
-                                       aliases.iter()
+                                       aliases
+                                           .iter()
                                            .map(|v| format!("{}", self.cizer.good(v)))
                                            .collect::<Vec<_>>()
                                            .join(", ")
                                    } else {
                                        aliases.join(", ")
                                    }));
         }
         if !self.hide_pv && !a.is_set(ArgSettings::HidePossibleValues) {
             if let Some(pv) = a.possible_vals() {
                 debugln!("Help::spec_vals: Found possible vals...{:?}", pv);
                 spec_vals.push(if self.color {
-                    format!(" [values: {}]",
-                            pv.iter()
-                                .map(|v| format!("{}", self.cizer.good(v)))
-                                .collect::<Vec<_>>()
-                                .join(", "))
-                } else {
-                    format!(" [values: {}]", pv.join(", "))
-                });
+                                   format!(" [values: {}]",
+                                           pv.iter()
+                                               .map(|v| format!("{}", self.cizer.good(v)))
+                                               .collect::<Vec<_>>()
+                                               .join(", "))
+                               } else {
+                                   format!(" [values: {}]", pv.join(", "))
+                               });
             }
         }
         spec_vals.join(" ")
     }
 }
 
 
 // Methods to write Parser help.
 impl<'a> Help<'a> {
     /// Writes help for all arguments (options, flags, args, subcommands)
     /// including titles of a Parser Object to the wrapped stream.
     #[cfg_attr(feature = "lints", allow(useless_let_if_seq))]
     pub fn write_all_args(&mut self, parser: &Parser) -> ClapResult<()> {
         debugln!("Help::write_all_args;");
         let flags = parser.has_flags();
-        let pos = parser.has_positionals();
+        let pos = parser
+            .positionals()
+            .filter(|arg| !arg.is_set(ArgSettings::Hidden))
+            .count() > 0;
         let opts = parser.has_opts();
         let subcmds = parser.has_subcommands();
 
         let unified_help = parser.is_set(AppSettings::UnifiedHelpMessage);
 
         let mut first = true;
 
         if unified_help && (flags || opts) {
-            let opts_flags = parser.flags()
+            let opts_flags = parser
+                .flags()
                 .map(as_arg_trait)
                 .chain(parser.opts().map(as_arg_trait));
             try!(color!(self, "OPTIONS:\n", warning));
             try!(self.write_args(opts_flags));
             first = false;
         } else {
             if flags {
                 try!(color!(self, "FLAGS:\n", warning));
-                try!(self.write_args(parser.flags()
-                    .map(as_arg_trait)));
+                try!(self.write_args(parser.flags().map(as_arg_trait)));
                 first = false;
             }
             if opts {
                 if !first {
                     try!(self.writer.write_all(b"\n\n"));
                 }
                 try!(color!(self, "OPTIONS:\n", warning));
                 try!(self.write_args(parser.opts().map(as_arg_trait)));
@@ -591,18 +617,23 @@ impl<'a> Help<'a> {
     }
 
     /// Writes help for subcommands of a Parser Object to the wrapped stream.
     fn write_subcommands(&mut self, parser: &Parser) -> io::Result<()> {
         debugln!("Help::write_subcommands;");
         // The shortest an arg can legally be is 2 (i.e. '-x')
         self.longest = 2;
         let mut ord_m = VecMap::new();
-        for sc in parser.subcommands.iter().filter(|s| !s.p.is_set(AppSettings::Hidden)) {
-            let btm = ord_m.entry(sc.p.meta.disp_ord).or_insert(BTreeMap::new());
+        for sc in parser
+                .subcommands
+                .iter()
+                .filter(|s| !s.p.is_set(AppSettings::Hidden)) {
+            let btm = ord_m
+                .entry(sc.p.meta.disp_ord)
+                .or_insert(BTreeMap::new());
             self.longest = cmp::max(self.longest, sc.p.meta.name.len());
             btm.insert(sc.p.meta.name.clone(), sc.clone());
         }
 
         let mut first = true;
         for btm in ord_m.values() {
             for sc in btm.values() {
                 if first {
@@ -676,17 +707,17 @@ impl<'a> Help<'a> {
         if let Some(about) = parser.meta.about {
             write_thing!(about)
         }
 
         try!(color!(self, "\nUSAGE:", warning));
         try!(write!(self.writer,
                     "\n{}{}\n\n",
                     TAB,
-                    parser.create_usage_no_title(&[])));
+                    usage::create_usage_no_title(parser, &[])));
 
         let flags = parser.has_flags();
         let pos = parser.has_positionals();
         let opts = parser.has_opts();
         let subcmds = parser.has_subcommands();
 
         if flags || opts || pos || subcmds {
             try!(self.write_all_args(&parser));
@@ -846,19 +877,19 @@ impl<'a> Help<'a> {
                 None => return Ok(()),
                 Some(Err(e)) => return Err(Error::from(e)),
                 Some(Ok(val)) if val > 0 => val,
                 _ => continue,
             };
 
             debugln!("Help::write_template_help:iter: tag_buf={};", unsafe {
                 String::from_utf8_unchecked(tag_buf.get_ref()[0..tag_length]
-                    .iter()
-                    .map(|&i| i)
-                    .collect::<Vec<_>>())
+                                                .iter()
+                                                .map(|&i| i)
+                                                .collect::<Vec<_>>())
             });
             match &tag_buf.get_ref()[0..tag_length] {
                 b"?" => {
                     try!(self.writer.write_all(b"Could not decode tag name"));
                 }
                 b"bin" => {
                     try!(self.write_bin_name(&parser));
                 }
@@ -873,38 +904,36 @@ impl<'a> Help<'a> {
                                 parser.meta.author.unwrap_or("unknown author")));
                 }
                 b"about" => {
                     try!(write!(self.writer,
                                 "{}",
                                 parser.meta.about.unwrap_or("unknown about")));
                 }
                 b"usage" => {
-                    try!(write!(self.writer, "{}", parser.create_usage_no_title(&[])));
+                    try!(write!(self.writer, "{}", usage::create_usage_no_title(parser, &[])));
                 }
                 b"all-args" => {
                     try!(self.write_all_args(&parser));
                 }
                 b"unified" => {
-                    let opts_flags = parser.flags()
+                    let opts_flags = parser
+                        .flags()
                         .map(as_arg_trait)
                         .chain(parser.opts().map(as_arg_trait));
                     try!(self.write_args(opts_flags));
                 }
                 b"flags" => {
-                    try!(self.write_args(parser.flags()
-                        .map(as_arg_trait)));
+                    try!(self.write_args(parser.flags().map(as_arg_trait)));
                 }
                 b"options" => {
-                    try!(self.write_args(parser.opts()
-                        .map(as_arg_trait)));
+                    try!(self.write_args(parser.opts().map(as_arg_trait)));
                 }
                 b"positionals" => {
-                    try!(self.write_args(parser.positionals()
-                        .map(as_arg_trait)));
+                    try!(self.write_args(parser.positionals().map(as_arg_trait)));
                 }
                 b"subcommands" => {
                     try!(self.write_subcommands(&parser));
                 }
                 b"after-help" => {
                     try!(write!(self.writer,
                                 "{}",
                                 parser.meta.more_help.unwrap_or("unknown after-help")));
@@ -933,17 +962,18 @@ fn wrap_help(help: &mut String, longest_
     if longest_w < avail_chars {
         sdebugln!("Yes");
         let mut prev_space = 0;
         let mut j = 0;
         for (idx, g) in (&*help.clone()).grapheme_indices(true) {
             debugln!("Help::wrap_help:iter: idx={}, g={}", idx, g);
             if g == "\n" {
                 debugln!("Help::wrap_help:iter: Newline found...");
-                debugln!("Help::wrap_help:iter: Still space...{:?}", str_width(&help[j..idx]) < avail_chars);
+                debugln!("Help::wrap_help:iter: Still space...{:?}",
+                         str_width(&help[j..idx]) < avail_chars);
                 if str_width(&help[j..idx]) < avail_chars {
                     j = idx;
                     continue;
                 }
             } else if g != " " {
                 if idx != help.len() - 1 || str_width(&help[j..idx]) < avail_chars {
                     continue;
                 }
@@ -952,17 +982,17 @@ fn wrap_help(help: &mut String, longest_
                 debugln!("Help::wrap_help:iter: Space found with room...");
                 prev_space = idx;
                 continue;
             }
             debugln!("Help::wrap_help:iter: Adding Newline...");
             j = prev_space;
             debugln!("Help::wrap_help:iter: prev_space={}, j={}", prev_space, j);
             debugln!("Help::wrap_help:iter: Removing...{}", j);
-            debugln!("Help::wrap_help:iter: Char at {}: {:?}", j, &help[j..j+1]);
+            debugln!("Help::wrap_help:iter: Char at {}: {:?}", j, &help[j..j + 1]);
             help.remove(j);
             help.insert(j, '\n');
             prev_space = idx;
         }
     } else {
         sdebugln!("No");
     }
 }
--- a/third_party/rust/clap/src/app/macros.rs
+++ b/third_party/rust/clap/src/app/macros.rs
@@ -14,21 +14,24 @@ macro_rules! remove_overriden {
     };
     (@arg $_self:ident, $arg:ident) => {
         remove_overriden!(@remove_requires $_self.required, $arg.requires);
         remove_overriden!(@remove $_self.blacklist, $arg.blacklist);
         remove_overriden!(@remove $_self.overrides, $arg.overrides);
     };
     ($_self:ident, $name:expr) => {
         debugln!("remove_overriden!;");
-        if let Some(ref o) = $_self.opts.iter().filter(|o| o.b.name == *$name).next() {
+        if let Some(o) = $_self.opts.iter() .find(|o| o.b.name == *$name) {
             remove_overriden!(@arg $_self, o);
-        } else if let Some(ref f) = $_self.flags.iter().filter(|f| f.b.name == *$name).next() {
+        } else if let Some(f) = $_self.flags.iter() .find(|f| f.b.name == *$name) {
             remove_overriden!(@arg $_self, f);
-        } else if let Some(p) = $_self.positionals.values().filter(|p| p.b.name == *$name).next() {
+        } else {
+            let p = $_self.positionals.values()
+                                      .find(|p| p.b.name == *$name)
+                                      .expect(INTERNAL_ERROR_MSG);
             remove_overriden!(@arg $_self, p);
         }
     };
 }
 
 macro_rules! arg_post_processing {
     ($me:ident, $arg:ident, $matcher:ident) => {
         debugln!("arg_post_processing!;");
@@ -51,59 +54,58 @@ macro_rules! arg_post_processing {
             $me.overrides.extend(or);
             vec_remove_all!($me.required, or.iter());
         } else { sdebugln!("No"); }
 
         // Handle conflicts
         debug!("arg_post_processing!: Does '{}' have conflicts...", $arg.to_string());
         if let Some(bl) = $arg.blacklist() {
             sdebugln!("Yes");
-            
+
             for c in bl {
                 // Inject two-way conflicts
                 debug!("arg_post_processing!: Has '{}' already been matched...", c);
                 if $matcher.contains(c) {
                     sdebugln!("Yes");
                     // find who blacklisted us...
                     $me.blacklist.push(&$arg.b.name);
                 } else {
                     sdebugln!("No");
                 }
             }
 
-            $me.blacklist.extend(bl);
+            $me.blacklist.extend_from_slice(bl);
             vec_remove_all!($me.overrides, bl.iter());
-            vec_remove_all!($me.required, bl.iter());
+            // vec_remove_all!($me.required, bl.iter());
         } else { sdebugln!("No"); }
 
         // Add all required args which aren't already found in matcher to the master
         // list
         debug!("arg_post_processing!: Does '{}' have requirements...", $arg.to_string());
         if let Some(reqs) = $arg.requires() {
-            for n in reqs.iter().filter(|&&(val, _)| val.is_none()).map(|&(_, name)| name) {
-                if $matcher.contains(&n) {
-                    sdebugln!("\tYes '{}' but it's already met", n);
-                    continue;
-                } else { sdebugln!("\tYes '{}'", n); }
-
+            for n in reqs.iter()
+                .filter(|&&(val, _)| val.is_none())
+                .filter(|&&(_, req)| !$matcher.contains(&req))
+                .map(|&(_, name)| name) {
+                    
                 $me.required.push(n);
             }
         } else { sdebugln!("No"); }
 
         _handle_group_reqs!($me, $arg);
     };
 }
 
 macro_rules! _handle_group_reqs{
     ($me:ident, $arg:ident) => ({
         use args::AnyArg;
         debugln!("_handle_group_reqs!;");
-        for grp in $me.groups.values() {
+        for grp in $me.groups.iter() {
             let found = if grp.args.contains(&$arg.name()) {
-                vec_remove!($me.required, &$arg.name());
+                // vec_remove!($me.required, &$arg.name());
                 if let Some(ref reqs) = grp.requires {
                     debugln!("_handle_group_reqs!: Adding {:?} to the required list", reqs);
                     $me.required.extend(reqs);
                 }
                 if let Some(ref bl) = grp.conflicts {
                     $me.blacklist.extend(bl);
                 }
                 true // What if arg is in more than one group with different reqs?
@@ -121,134 +123,40 @@ macro_rules! _handle_group_reqs{
                     $me.blacklist.extend(&grp.args);
                     vec_remove!($me.blacklist, &$arg.name());
                 }
             }
         }
     })
 }
 
-macro_rules! validate_multiples {
-    ($_self:ident, $a:ident, $m:ident) => {
-        debugln!("validate_multiples!;");
-        if $m.contains(&$a.b.name) && !$a.b.settings.is_set(ArgSettings::Multiple) {
-            // Not the first time, and we don't allow multiples
-            return Err(Error::unexpected_multiple_usage($a,
-                &*$_self.create_current_usage($m, None),
-                $_self.color()))
-        }
-    };
-}
-
 macro_rules! parse_positional {
     (
         $_self:ident,
         $p:ident,
         $arg_os:ident,
         $pos_counter:ident,
         $matcher:ident
     ) => {
         debugln!("parse_positional!;");
-        validate_multiples!($_self, $p, $matcher);
 
-        if !$_self.trailing_vals &&
-           ($_self.settings.is_set(AppSettings::TrailingVarArg) &&
+        if !$_self.is_set(AS::TrailingValues) &&
+           ($_self.is_set(AS::TrailingVarArg) &&
             $pos_counter == $_self.positionals.len()) {
-            $_self.trailing_vals = true;
+            $_self.settings.set(AS::TrailingValues);
         }
         let _ = try!($_self.add_val_to_arg($p, &$arg_os, $matcher));
 
         $matcher.inc_occurrence_of($p.b.name);
         let _ = $_self.groups_for_arg($p.b.name)
                       .and_then(|vec| Some($matcher.inc_occurrences_of(&*vec)));
-        arg_post_processing!($_self, $p, $matcher);
+        if $_self.cache.map_or(true, |name| name != $p.b.name) {
+            arg_post_processing!($_self, $p, $matcher);
+            $_self.cache = Some($p.b.name);
+        }
+
+        $_self.settings.set(AS::ValidArgFound);
         // Only increment the positional counter if it doesn't allow multiples
         if !$p.b.settings.is_set(ArgSettings::Multiple) {
             $pos_counter += 1;
         }
     };
 }
-
-macro_rules! find_from {
-    ($_self:ident, $arg_name:expr, $from:ident, $matcher:expr) => {{
-        let mut ret = None;
-        for k in $matcher.arg_names() {
-            if let Some(f) = find_by_name!($_self, &k, flags, iter) {
-                if let Some(ref v) = f.$from() {
-                    if v.contains($arg_name) {
-                        ret = Some(f.to_string());
-                    }
-                }
-            }
-            if let Some(o) = find_by_name!($_self, &k, opts, iter) {
-                if let Some(ref v) = o.$from() {
-                    if v.contains(&$arg_name) {
-                        ret = Some(o.to_string());
-                    }
-                }
-            }
-            if let Some(pos) = find_by_name!($_self, &k, positionals, values) {
-                if let Some(ref v) = pos.$from() {
-                    if v.contains($arg_name) {
-                        ret = Some(pos.b.name.to_owned());
-                    }
-                }
-            }
-        }
-        ret
-    }};
-}
-
-macro_rules! find_name_from {
-    ($_self:ident, $arg_name:expr, $from:ident, $matcher:expr) => {{
-        let mut ret = None;
-        for k in $matcher.arg_names() {
-            if let Some(f) = find_by_name!($_self, &k, flags, iter) {
-                if let Some(ref v) = f.$from() {
-                    if v.contains($arg_name) {
-                        ret = Some(f.b.name);
-                    }
-                }
-            }
-            if let Some(o) = find_by_name!($_self, &k, opts, iter) {
-                if let Some(ref v) = o.$from() {
-                    if v.contains(&$arg_name) {
-                        ret = Some(o.b.name);
-                    }
-                }
-            }
-            if let Some(pos) = find_by_name!($_self, &k, positionals, values) {
-                if let Some(ref v) = pos.$from() {
-                    if v.contains($arg_name) {
-                        ret = Some(pos.b.name);
-                    }
-                }
-            }
-        }
-        ret
-    }};
-}
-
-// Finds an arg by name
-macro_rules! find_by_name {
-    ($_self:ident, $name:expr, $what:ident, $how:ident) => {
-        $_self.$what.$how().find(|o| &o.b.name == $name)
-    }
-}
-
-// Finds an option including if it's aliasesed
-macro_rules! find_by_long {
-    ($_self:ident, $long:expr, $what:ident) => {
-        $_self.$what
-            .iter()
-            .filter(|o| o.s.long.is_some())
-            .find(|o| {
-                &&o.s.long.unwrap() == &$long ||
-                (o.s.aliases.is_some() &&
-                 o.s
-                    .aliases
-                    .as_ref()
-                    .unwrap()
-                    .iter()
-                    .any(|&(alias, _)| &&alias == &$long))
-            })
-    }
-}
--- a/third_party/rust/clap/src/app/meta.rs
+++ b/third_party/rust/clap/src/app/meta.rs
@@ -1,68 +1,27 @@
 #[doc(hidden)]
 #[allow(missing_debug_implementations)]
+#[derive(Default, Clone)]
 pub struct AppMeta<'b> {
     pub name: String,
     pub bin_name: Option<String>,
     pub author: Option<&'b str>,
     pub version: Option<&'b str>,
+    pub long_version: Option<&'b str>,
     pub about: Option<&'b str>,
+    pub long_about: Option<&'b str>,
     pub more_help: Option<&'b str>,
     pub pre_help: Option<&'b str>,
     pub aliases: Option<Vec<(&'b str, bool)>>, // (name, visible)
     pub usage_str: Option<&'b str>,
     pub usage: Option<String>,
     pub help_str: Option<&'b str>,
     pub disp_ord: usize,
     pub term_w: Option<usize>,
     pub max_w: Option<usize>,
     pub template: Option<&'b str>,
 }
 
-impl<'b> Default for AppMeta<'b> {
-    fn default() -> Self {
-        AppMeta {
-            name: String::new(),
-            author: None,
-            about: None,
-            more_help: None,
-            pre_help: None,
-            version: None,
-            usage_str: None,
-            usage: None,
-            bin_name: None,
-            help_str: None,
-            disp_ord: 999,
-            template: None,
-            aliases: None,
-            term_w: None,
-            max_w: None,
-        }
-    }
-}
-
 impl<'b> AppMeta<'b> {
     pub fn new() -> Self { Default::default() }
-    pub fn with_name(s: String) -> Self { AppMeta { name: s, ..Default::default() } }
-}
-
-impl<'b> Clone for AppMeta<'b> {
-    fn clone(&self) -> Self {
-        AppMeta {
-            name: self.name.clone(),
-            author: self.author,
-            about: self.about,
-            more_help: self.more_help,
-            pre_help: self.pre_help,
-            version: self.version,
-            usage_str: self.usage_str,
-            usage: self.usage.clone(),
-            bin_name: self.bin_name.clone(),
-            help_str: self.help_str,
-            disp_ord: self.disp_ord,
-            template: self.template,
-            aliases: self.aliases.clone(),
-            term_w: self.term_w,
-            max_w: self.max_w,
-        }
-    }
-}
+    pub fn with_name(s: String) -> Self { AppMeta { name: s, disp_ord: 999, ..Default::default() } }
+}
\ No newline at end of file
--- a/third_party/rust/clap/src/app/mod.rs
+++ b/third_party/rust/clap/src/app/mod.rs
@@ -1,17 +1,18 @@
 mod settings;
 #[macro_use]
 mod macros;
 pub mod parser;
 mod meta;
 mod help;
+mod validator;
+mod usage;
 
 // Std
-use std::borrow::Borrow;
 use std::env;
 use std::ffi::{OsStr, OsString};
 use std::fmt;
 use std::io::{self, BufRead, BufWriter, Write};
 use std::path::Path;
 use std::process;
 use std::rc::Rc;
 use std::result::Result as StdResult;
@@ -19,18 +20,17 @@ use std::result::Result as StdResult;
 // Third Party
 use vec_map::{self, VecMap};
 #[cfg(feature = "yaml")]
 use yaml_rust::Yaml;
 
 // Internal
 use app::help::Help;
 use app::parser::Parser;
-use args::{ArgKind, AnyArg, Arg, ArgGroup, ArgMatcher, ArgMatches, ArgSettings};
-use errors::Error;
+use args::{AnyArg, Arg, ArgGroup, ArgMatcher, ArgMatches, ArgSettings};
 use errors::Result as ClapResult;
 pub use self::settings::AppSettings;
 use completions::Shell;
 
 /// Used to create a representation of a command line program and all possible command line
 /// arguments. Application settings are set using the "builder pattern" with the
 /// [`App::get_matches`] family of methods being the terminal methods that starts the
 /// runtime-parsing process. These methods then return information about the user supplied
@@ -195,31 +195,91 @@ impl<'a, 'b> App<'a, 'b> {
     /// ```
     /// [`SubCommand`]: ./struct.SubCommand.html
     pub fn bin_name<S: Into<String>>(mut self, name: S) -> Self {
         self.p.meta.bin_name = Some(name.into());
         self
     }
 
     /// Sets a string describing what the program does. This will be displayed when displaying help
-    /// information.
+    /// information with `-h`.
+    ///
+    /// **NOTE:** If only `about` is provided, and not [`App::long_about`] but the user requests
+    /// `--help` clap will still display the contents of `about` appropriately
+    ///
+    /// **NOTE:** Only [`App::about`] is used in completion script generation in order to be
+    /// concise
     ///
     /// # Examples
     ///
     /// ```no_run
     /// # use clap::{App, Arg};
     /// App::new("myprog")
     ///     .about("Does really amazing things to great people")
     /// # ;
     /// ```
+    /// [`App::long_about`]: ./struct.App.html#method.long_about
     pub fn about<S: Into<&'b str>>(mut self, about: S) -> Self {
         self.p.meta.about = Some(about.into());
         self
     }
 
+    /// Sets a string describing what the program does. This will be displayed when displaying help
+    /// information.
+    ///
+    /// **NOTE:** If only `long_about` is provided, and not [`App::about`] but the user requests
+    /// `-h` clap will still display the contents of `long_about` appropriately
+    ///
+    /// **NOTE:** Only [`App::about`] is used in completion script generation in order to be
+    /// concise
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// # use clap::{App, Arg};
+    /// App::new("myprog")
+    ///     .long_about(
+    /// "Does really amazing things to great people. Now let's talk a little
+    ///  more in depth about how this subcommand really works. It may take about
+    ///  a few lines of text, but that's ok!")
+    /// # ;
+    /// ```
+    /// [`App::about`]: ./struct.App.html#method.about
+    pub fn long_about<S: Into<&'b str>>(mut self, about: S) -> Self {
+        self.p.meta.long_about = Some(about.into());
+        self
+    }
+
+    /// Sets the program's name. This will be displayed when displaying help information.
+    ///
+    /// **Pro-top:** This function is particularly useful when configuring a program via
+    /// [`App::from_yaml`] in conjunction with the [`crate_name!`] macro to derive the program's
+    /// name from its `Cargo.toml`.
+    ///
+    /// # Examples
+    /// ```ignore
+    /// # #[macro_use]
+    /// # extern crate clap;
+    /// # use clap::App;
+    /// # fn main() {
+    /// let yml = load_yaml!("app.yml");
+    /// let app = App::from_yaml(yml)
+    ///     .name(crate_name!());
+    ///
+    /// // continued logic goes here, such as `app.get_matches()` etc.
+    /// # }
+    /// ```
+    ///
+    /// [`App::from_yaml`]: ./struct.App.html#method.from_yaml
+    /// [`crate_name!`]: ./macro.crate_name.html
+    pub fn name<S: Into<String>>(mut self, name: S) -> Self {
+        self.p.meta.name = name.into();
+        self
+    }
+
     /// Adds additional help information to be displayed in addition to auto-generated help. This
     /// information is displayed **after** the auto-generated help information. This is often used
     /// to describe how to use the arguments, or caveats to be noted.
     ///
     /// # Examples
     ///
     /// ```no_run
     /// # use clap::App;
@@ -245,37 +305,72 @@ impl<'a, 'b> App<'a, 'b> {
     /// # ;
     /// ```
     pub fn before_help<S: Into<&'b str>>(mut self, help: S) -> Self {
         self.p.meta.pre_help = Some(help.into());
         self
     }
 
     /// Sets a string of the version number to be displayed when displaying version or help
-    /// information.
+    /// information with `-V`. 
+    ///
+    /// **NOTE:** If only `version` is provided, and not [`App::long_version`] but the user
+    /// requests `--version` clap will still display the contents of `version` appropriately
     ///
     /// **Pro-tip:** Use `clap`s convenience macro [`crate_version!`] to automatically set your
     /// application's version to the same thing as your crate at compile time. See the [`examples/`]
     /// directory for more information
     ///
     /// # Examples
     ///
     /// ```no_run
     /// # use clap::{App, Arg};
     /// App::new("myprog")
     ///     .version("v0.1.24")
     /// # ;
     /// ```
     /// [`crate_version!`]: ./macro.crate_version!.html
     /// [`examples/`]: https://github.com/kbknapp/clap-rs/tree/master/examples
+    /// [`App::long_version`]: ./struct.App.html#method.long_version
     pub fn version<S: Into<&'b str>>(mut self, ver: S) -> Self {
         self.p.meta.version = Some(ver.into());
         self
     }
 
+    /// Sets a string of the version number to be displayed when displaying version or help
+    /// information with `--version`.
+    ///
+    /// **NOTE:** If only `long_version` is provided, and not [`App::version`] but the user
+    /// requests `-V` clap will still display the contents of `long_version` appropriately
+    ///
+    /// **Pro-tip:** Use `clap`s convenience macro [`crate_version!`] to automatically set your
+    /// application's version to the same thing as your crate at compile time. See the [`examples/`]
+    /// directory for more information
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// # use clap::{App, Arg};
+    /// App::new("myprog")
+    ///     .long_version(
+    /// "v0.1.24
+    ///  commit: abcdef89726d
+    ///  revision: 123
+    ///  release: 2
+    ///  binary: myprog")
+    /// # ;
+    /// ```
+    /// [`crate_version!`]: ./macro.crate_version!.html
+    /// [`examples/`]: https://github.com/kbknapp/clap-rs/tree/master/examples
+    /// [`App::version`]: ./struct.App.html#method.version
+    pub fn long_version<S: Into<&'b str>>(mut self, ver: S) -> Self {
+        self.p.meta.long_version = Some(ver.into());
+        self
+    }
+
     /// Sets a custom usage string to override the auto-generated usage string.
     ///
     /// This will be displayed to the user when errors are found in argument parsing, or when you
     /// call [`ArgMatches::usage`]
     ///
     /// **CAUTION:** Using this setting disables `clap`s "context-aware" usage strings. After this
     /// setting is set, this will be the only usage string displayed to the user!
     ///
@@ -386,30 +481,70 @@ impl<'a, 'b> App<'a, 'b> {
     /// # ;
     /// ```
     /// [`short`]: ./struct.Arg.html#method.short
     pub fn version_short<S: AsRef<str>>(mut self, s: S) -> Self {
         self.p.version_short(s.as_ref());
         self
     }
 
+    /// Sets the help text for the auto-generated `help` argument.
+    ///
+    /// By default `clap` sets this to `"Prints help information"`, but if you're using a
+    /// different convention for your help messages and would prefer a different phrasing you can
+    /// override it.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// # use clap::{App, Arg};
+    /// App::new("myprog")
+    ///     .help_message("Print help information") // Perhaps you want imperative help messages
+    ///
+    /// # ;
+    /// ```
+    pub fn help_message<S: Into<&'a str>>(mut self, s: S) -> Self {
+        self.p.help_message = Some(s.into());
+        self
+    }
+
+    /// Sets the help text for the auto-generated `version` argument.
+    ///
+    /// By default `clap` sets this to `"Prints version information"`, but if you're using a
+    /// different convention for your help messages and would prefer a different phrasing then you
+    /// can change it.
+    ///
+    /// # Examples
+    /// ```no_run
+    /// # use clap::{App, Arg};
+    /// App::new("myprog")
+    ///     .version_message("Print version information") // Perhaps you want imperative help messages
+    /// # ;
+    /// ```
+    pub fn version_message<S: Into<&'a str>>(mut self, s: S) -> Self {
+        self.p.version_message = Some(s.into());
+        self
+    }
+
     /// Sets the help template to be used, overriding the default format.
     ///
     /// Tags arg given inside curly brackets.
     ///
     /// Valid tags are:
     ///
     ///   * `{bin}`         - Binary name.
     ///   * `{version}`     - Version number.
     ///   * `{author}`      - Author information.
     ///   * `{about}`       - General description (from [`App::about`])
     ///   * `{usage}`       - Automatically generated or given usage string.
     ///   * `{all-args}`    - Help for all arguments (options, flags, positionals arguments,
     ///                       and subcommands) including titles.
-    ///   * `{unified}`     - Unified help for options and flags.
+    ///   * `{unified}`     - Unified help for options and flags. Note, you must *also* set 
+    ///                       [`AppSettings::UnifiedHelpMessage`] to fully merge both options and 
+    ///                       flags, otherwise the ordering is "best effort"
     ///   * `{flags}`       - Help for flags.
     ///   * `{options}`     - Help for options.
     ///   * `{positionals}` - Help for positionals arguments.
     ///   * `{subcommands}` - Help for subcommands.
     ///   * `{after-help}`  - Help from [`App::after_help`]
     ///   * `{before-help}`  - Help from [`App::before_help`]
     ///
     /// # Examples
@@ -421,16 +556,17 @@ impl<'a, 'b> App<'a, 'b> {
     ///     .template("{bin} ({version}) - {usage}")
     /// # ;
     /// ```
     /// **NOTE:**The template system is, on purpose, very simple. Therefore the tags have to writen
     /// in the lowercase and without spacing.
     /// [`App::about`]: ./struct.App.html#method.about
     /// [`App::after_help`]: ./struct.App.html#method.after_help
     /// [`App::before_help`]: ./struct.App.html#method.before_help
+    /// [`AppSettings::UnifiedHelpMessage`]: ./enum.AppSettings.html#variant.UnifiedHelpMessage
     pub fn template<S: Into<&'b str>>(mut self, s: S) -> Self {
         self.p.meta.template = Some(s.into());
         self
     }
 
     /// Enables a single command, or [`SubCommand`], level settings.
     ///
     /// See [`AppSettings`] for a full list of possibilities and examples.
@@ -635,18 +771,18 @@ impl<'a, 'b> App<'a, 'b> {
     ///     // Adding a single "option" argument with a short, a long, and help text using the less
     ///     // verbose Arg::from_usage()
     ///     .arg(
     ///         Arg::from_usage("-c --config=[CONFIG] 'Optionally sets a config file to use'")
     ///     )
     /// # ;
     /// ```
     /// [argument]: ./struct.Arg.html
-    pub fn arg<A: Borrow<Arg<'a, 'b>> + 'a>(mut self, a: A) -> Self {
-        self.p.add_arg(a.borrow());
+    pub fn arg<A: Into<Arg<'a, 'b>>>(mut self, a: A) -> Self {
+        self.p.add_arg(a.into());
         self
     }
 
     /// Adds multiple [arguments] to the list of valid possibilties
     ///
     /// # Examples
     ///
     /// ```no_run
@@ -656,17 +792,17 @@ impl<'a, 'b> App<'a, 'b> {
     ///         &[Arg::from_usage("[debug] -d 'turns on debugging info'"),
     ///          Arg::with_name("input").index(1).help("the input file to use")]
     ///     )
     /// # ;
     /// ```
     /// [arguments]: ./struct.Arg.html
     pub fn args(mut self, args: &[Arg<'a, 'b>]) -> Self {
         for arg in args {
-            self.p.add_arg(arg);
+            self.p.add_arg_ref(arg);
         }
         self
     }
 
     /// A convenience method for adding a single [argument] from a usage type string. The string
     /// used follows the same rules and syntax as [`Arg::from_usage`]
     ///
     /// **NOTE:** The downside to using this method is that you can not set any additional
@@ -679,17 +815,17 @@ impl<'a, 'b> App<'a, 'b> {
     /// App::new("myprog")
     ///     .arg_from_usage("-c --config=<FILE> 'Sets a configuration file to use'")
     /// # ;
     /// ```
     /// [arguments]: ./struct.Arg.html
     /// [`Arg`]: ./struct.Arg.html
     /// [`Arg::from_usage`]: ./struct.Arg.html#method.from_usage
     pub fn arg_from_usage(mut self, usage: &'a str) -> Self {
-        self.p.add_arg(&Arg::from_usage(usage));
+        self.p.add_arg(Arg::from_usage(usage));
         self
     }
 
     /// Adds multiple [arguments] at once from a usage string, one per line. See
     /// [`Arg::from_usage`] for details on the syntax and rules supported.
     ///
     /// **NOTE:** Like [`App::arg_from_usage`] the downside is you only set properties for the
     /// [`Arg`]s which [`Arg::from_usage`] supports.
@@ -711,17 +847,17 @@ impl<'a, 'b> App<'a, 'b> {
     /// [`App::arg_from_usage`]: ./struct.App.html#method.arg_from_usage
     /// [`Arg`]: ./struct.Arg.html
     pub fn args_from_usage(mut self, usage: &'a str) -> Self {
         for line in usage.lines() {
             let l = line.trim();
             if l.is_empty() {
                 continue;
             }
-            self.p.add_arg(&Arg::from_usage(l));
+            self.p.add_arg(Arg::from_usage(l));
         }
         self
     }
 
     /// Allows adding a [`SubCommand`] alias, which function as "hidden" subcommands that
     /// automatically dispatch as if this subcommand was used. This is more efficient, and easier
     /// than creating multiple hidden subcommands as one only needs to check for the existence of
     /// this command, and not all variants.
@@ -992,81 +1128,179 @@ impl<'a, 'b> App<'a, 'b> {
     ///     alpha   Some help and text
     /// ```
     /// [`SubCommand`]: ./struct.SubCommand.html
     pub fn display_order(mut self, ord: usize) -> Self {
         self.p.meta.disp_ord = ord;
         self
     }
 
-    /// Prints the full help message to [`io::stdout()`] using a [`BufWriter`]
+    /// Prints the full help message to [`io::stdout()`] using a [`BufWriter`] using the same
+    /// method as if someone ran `-h` to request the help message
+    ///
+    /// **NOTE:** clap has the ability to distinguish between "short" and "long" help messages
+    /// depending on if the user ran [`-h` (short)] or [`--help` (long)]
     ///
     /// # Examples
     ///
     /// ```rust
     /// # use clap::App;
     /// let mut app = App::new("myprog");
     /// app.print_help();
     /// ```
     /// [`io::stdout()`]: https://doc.rust-lang.org/std/io/fn.stdout.html
     /// [`BufWriter`]: https://doc.rust-lang.org/std/io/struct.BufWriter.html
+    /// [`-h` (short)]: ./struct.Arg.html#method.help
+    /// [`--help` (long)]: ./struct.Arg.html#method.long_help
     pub fn print_help(&mut self) -> ClapResult<()> {
         // If there are global arguments, or settings we need to propgate them down to subcommands
         // before parsing incase we run into a subcommand
         self.p.propogate_globals();
         self.p.propogate_settings();
         self.p.derive_display_order();
 
         self.p.create_help_and_version();
         let out = io::stdout();
         let mut buf_w = BufWriter::new(out.lock());
         self.write_help(&mut buf_w)
     }
 
-    /// Writes the full help message to the user to a [`io::Write`] object
+    /// Prints the full help message to [`io::stdout()`] using a [`BufWriter`] using the same
+    /// method as if someone ran `-h` to request the help message
+    ///
+    /// **NOTE:** clap has the ability to distinguish between "short" and "long" help messages
+    /// depending on if the user ran [`-h` (short)] or [`--help` (long)]
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::App;
+    /// let mut app = App::new("myprog");
+    /// app.print_long_help();
+    /// ```
+    /// [`io::stdout()`]: https://doc.rust-lang.org/std/io/fn.stdout.html
+    /// [`BufWriter`]: https://doc.rust-lang.org/std/io/struct.BufWriter.html
+    /// [`-h` (short)]: ./struct.Arg.html#method.help
+    /// [`--help` (long)]: ./struct.Arg.html#method.long_help
+    pub fn print_long_help(&mut self) -> ClapResult<()> {
+        // If there are global arguments, or settings we need to propgate them down to subcommands
+        // before parsing incase we run into a subcommand
+        self.p.propogate_globals();
+        self.p.propogate_settings();
+        self.p.derive_display_order();
+
+        self.p.create_help_and_version();
+        let out = io::stdout();
+        let mut buf_w = BufWriter::new(out.lock());
+        self.write_long_help(&mut buf_w)
+    }
+
+    /// Writes the full help message to the user to a [`io::Write`] object in the same method as if
+    /// the user ran `-h`
+    ///
+    /// **NOTE:** clap has the ability to distinguish between "short" and "long" help messages
+    /// depending on if the user ran [`-h` (short)] or [`--help` (long)]
+    ///
+    /// **NOTE:** There is a known bug where this method does not write propogated global arguments
+    /// or autogenerated arguments (i.e. the default help/version args). Prefer
+    /// [`App::write_long_help`] instead if possibe!
     ///
     /// # Examples
     ///
     /// ```rust
     /// # use clap::App;
     /// use std::io;
     /// let mut app = App::new("myprog");
     /// let mut out = io::stdout();
     /// app.write_help(&mut out).expect("failed to write to stdout");
     /// ```
     /// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
+    /// [`-h` (short)]: ./struct.Arg.html#method.help
+    /// [`--help` (long)]: ./struct.Arg.html#method.long_help
     pub fn write_help<W: Write>(&self, w: &mut W) -> ClapResult<()> {
         // PENDING ISSUE: 808
         //      https://github.com/kbknapp/clap-rs/issues/808
         // If there are global arguments, or settings we need to propgate them down to subcommands
         // before parsing incase we run into a subcommand
         // self.p.propogate_globals();
         // self.p.propogate_settings();
         // self.p.derive_display_order();
         // self.p.create_help_and_version();
 
-        Help::write_app_help(w, self)
+        Help::write_app_help(w, self, false)
     }
 
-    /// Writes the version message to the user to a [`io::Write`] object
+    /// Writes the full help message to the user to a [`io::Write`] object in the same method as if
+    /// the user ran `--help`
+    ///
+    /// **NOTE:** clap has the ability to distinguish between "short" and "long" help messages
+    /// depending on if the user ran [`-h` (short)] or [`--help` (long)]
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::App;
+    /// use std::io;
+    /// let mut app = App::new("myprog");
+    /// let mut out = io::stdout();
+    /// app.write_long_help(&mut out).expect("failed to write to stdout");
+    /// ```
+    /// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
+    /// [`-h` (short)]: ./struct.Arg.html#method.help
+    /// [`--help` (long)]: ./struct.Arg.html#method.long_help
+    pub fn write_long_help<W: Write>(&mut self, w: &mut W) -> ClapResult<()> {
+        self.p.propogate_globals();
+        self.p.propogate_settings();
+        self.p.derive_display_order();
+        self.p.create_help_and_version();
+
+        Help::write_app_help(w, self, true)
+    }
+
+    /// Writes the version message to the user to a [`io::Write`] object as if the user ran `-V`.
+    ///
+    /// **NOTE:** clap has the ability to distinguish between "short" and "long" version messages
+    /// depending on if the user ran [`-V` (short)] or [`--version` (long)]
     ///
     /// # Examples
     ///
     /// ```rust
     /// # use clap::App;
     /// use std::io;
     /// let mut app = App::new("myprog");
     /// let mut out = io::stdout();
     /// app.write_version(&mut out).expect("failed to write to stdout");
     /// ```
     /// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
+    /// [`-V` (short)]: ./struct.App.html#method.version
+    /// [`--version` (long)]: ./struct.App.html#method.long_version
     pub fn write_version<W: Write>(&self, w: &mut W) -> ClapResult<()> {
-        self.p.write_version(w).map_err(From::from)
+        self.p.write_version(w, false).map_err(From::from)
     }
 
+    /// Writes the version message to the user to a [`io::Write`] object
+    ///
+    /// **NOTE:** clap has the ability to distinguish between "short" and "long" version messages
+    /// depending on if the user ran [`-V` (short)] or [`--version` (long)]
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::App;
+    /// use std::io;
+    /// let mut app = App::new("myprog");
+    /// let mut out = io::stdout();
+    /// app.write_long_version(&mut out).expect("failed to write to stdout");
+    /// ```
+    /// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
+    /// [`-V` (short)]: ./struct.App.html#method.version
+    /// [`--version` (long)]: ./struct.App.html#method.long_version
+    pub fn write_long_version<W: Write>(&self, w: &mut W) -> ClapResult<()> {
+        self.p.write_version(w, true).map_err(From::from)
+    }
 
     /// Generate a completions file for a specified shell at compile time.
     ///
     /// **NOTE:** to generate the this file at compile time you must use a `build.rs` "Build Script"
     ///
     /// # Examples
     ///
     /// The following example generates a bash completion script via a `build.rs` script. In this
@@ -1113,17 +1347,17 @@ impl<'a, 'b> App<'a, 'b> {
     ///
     /// Next, we set up our `Cargo.toml` to use a `build.rs` build script.
     ///
     /// ```toml
     /// # Cargo.toml
     /// build = "build.rs"
     ///
     /// [build-dependencies]
-    /// clap = "2.9"
+    /// clap = "2.23"
     /// ```
     ///
     /// Next, we place a `build.rs` in our project root.
     ///
     /// ```ignore
     /// extern crate clap;
     ///
     /// use clap::Shell;
@@ -1263,17 +1497,31 @@ impl<'a, 'b> App<'a, 'b> {
     /// [`Vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html
     /// [`AppSettings::NoBinaryName`]: ./enum.AppSettings.html#variant.NoBinaryName
     pub fn get_matches_from<I, T>(mut self, itr: I) -> ArgMatches<'a>
         where I: IntoIterator<Item = T>,
               T: Into<OsString> + Clone
     {
         self.get_matches_from_safe_borrow(itr).unwrap_or_else(|e| {
             // Otherwise, write to stderr and exit
-            self.maybe_wait_for_exit(e);
+            if e.use_stderr() {
+                wlnerr!("{}", e.message);
+                if self.p.is_set(AppSettings::WaitOnError) {
+                    wlnerr!("\nPress [ENTER] / [RETURN] to continue...");
+                    let mut s = String::new();
+                    let i = io::stdin();
+                    i.lock().read_line(&mut s).unwrap();
+                }
+                drop(self);
+                drop(e);
+                process::exit(1);
+            }
+
+            drop(self);
+            e.exit()
         })
     }
 
     /// Starts the parsing process. A combination of [`App::get_matches_from`], and
     /// [`App::get_matches_safe`]
     ///
     /// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are
     /// used. It will return a [`clap::Error`], where the [`kind`] is a [`ErrorKind::HelpDisplayed`]
@@ -1368,39 +1616,22 @@ impl<'a, 'b> App<'a, 'b> {
 
         // do the real parsing
         if let Err(e) = self.p.get_matches_with(&mut matcher, &mut it.peekable()) {
             return Err(e);
         }
 
         if self.p.is_set(AppSettings::PropagateGlobalValuesDown) {
             for a in &self.p.global_args {
-                matcher.propagate(a.name);
+                matcher.propagate(a.b.name);
             }
         }
 
         Ok(matcher.into())
     }
-
-    // Re-implements ClapError::exit except it checks if we should wait for input before exiting
-    // since ClapError doesn't have that info and the error message must be printed before exiting
-    fn maybe_wait_for_exit(&self, e: Error) -> ! {
-        if e.use_stderr() {
-            wlnerr!("{}", e.message);
-            if self.p.is_set(AppSettings::WaitOnError) {
-                wlnerr!("\nPress [ENTER] / [RETURN] to continue...");
-                let mut s = String::new();
-                let i = io::stdin();
-                i.lock().read_line(&mut s).unwrap();
-            }
-            process::exit(1);
-        }
-
-        e.exit()
-    }
 }
 
 #[cfg(feature = "yaml")]
 impl<'a> From<&'a Yaml> for App<'a, 'a> {
     fn from(mut yaml: &'a Yaml) -> Self {
         use args::SubCommand;
         // We WANT this to panic on error...so expect() is good.
         let mut is_sc = None;
@@ -1420,25 +1651,28 @@ impl<'a> From<&'a Yaml> for App<'a, 'a> 
                     $a = $a.$i(v);
                 } else if $y[stringify!($i)] != Yaml::BadValue {
                     panic!("Failed to convert YAML value {:?} to a string", $y[stringify!($i)]);
                 }
             };
         }
 
         yaml_str!(a, yaml, version);
+        yaml_str!(a, yaml, author);
         yaml_str!(a, yaml, bin_name);
         yaml_str!(a, yaml, about);
         yaml_str!(a, yaml, before_help);
         yaml_str!(a, yaml, after_help);
         yaml_str!(a, yaml, template);
         yaml_str!(a, yaml, usage);
         yaml_str!(a, yaml, help);
         yaml_str!(a, yaml, help_short);
         yaml_str!(a, yaml, version_short);
+        yaml_str!(a, yaml, help_message);
+        yaml_str!(a, yaml, version_message);
         yaml_str!(a, yaml, alias);
         yaml_str!(a, yaml, visible_alias);
 
         if let Some(v) = yaml["display_order"].as_i64() {
             a = a.display_order(v as usize);
         } else if yaml["display_order"] != Yaml::BadValue {
             panic!("Failed to convert YAML value {:?} to a u64",
                    yaml["display_order"]);
@@ -1530,42 +1764,43 @@ impl<'a> From<&'a Yaml> for App<'a, 'a> 
 impl<'a, 'b> Clone for App<'a, 'b> {
     fn clone(&self) -> Self { App { p: self.p.clone() } }
 }
 
 impl<'n, 'e> AnyArg<'n, 'e> for App<'n, 'e> {
     fn name(&self) -> &'n str {
         unreachable!("App struct does not support AnyArg::name, this is a bug!")
     }
-    fn id(&self) -> usize { self.p.id }
-    fn kind(&self) -> ArgKind { ArgKind::Subcmd }
     fn overrides(&self) -> Option<&[&'e str]> { None }
     fn requires(&self) -> Option<&[(Option<&'e str>, &'n str)]> { None }
     fn blacklist(&self) -> Option<&[&'e str]> { None }
     fn required_unless(&self) -> Option<&[&'e str]> { None }
     fn val_names(&self) -> Option<&VecMap<&'e str>> { None }
     fn is_set(&self, _: ArgSettings) -> bool { false }
-    fn val_terminator(&self) -> Option<&'e str> {None}
+    fn val_terminator(&self) -> Option<&'e str> { None }
     fn set(&mut self, _: ArgSettings) {
         unreachable!("App struct does not support AnyArg::set, this is a bug!")
     }
     fn has_switch(&self) -> bool { false }
     fn max_vals(&self) -> Option<u64> { None }
     fn num_vals(&self) -> Option<u64> { None }
     fn possible_vals(&self) -> Option<&[&'e str]> { None }
     fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> { None }
     fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>> { None }
     fn min_vals(&self) -> Option<u64> { None }
     fn short(&self) -> Option<char> { None }
     fn long(&self) -> Option<&'e str> { None }
     fn val_delim(&self) -> Option<char> { None }
     fn takes_value(&self) -> bool { true }
     fn help(&self) -> Option<&'e str> { self.p.meta.about }
-    fn default_val(&self) -> Option<&'n str> { None }
-    fn default_vals_ifs(&self) -> Option<vec_map::Values<(&'n str, Option<&'e str>, &'e str)>> {None}
+    fn long_help(&self) -> Option<&'e str> { self.p.meta.long_about }
+    fn default_val(&self) -> Option<&'e OsStr> { None }
+    fn default_vals_ifs(&self) -> Option<vec_map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
+        None
+    }
     fn longest_filter(&self) -> bool { true }
     fn aliases(&self) -> Option<Vec<&'e str>> {
         if let Some(ref aliases) = self.p.meta.aliases {
             let vis_aliases: Vec<_> =
                 aliases.iter().filter_map(|&(n, v)| if v { Some(n) } else { None }).collect();
             if vis_aliases.is_empty() {
                 None
             } else {
--- a/third_party/rust/clap/src/app/parser.rs
+++ b/third_party/rust/clap/src/app/parser.rs
@@ -1,10 +1,9 @@
 // Std
-use std::collections::{BTreeMap, HashMap, VecDeque};
 use std::ffi::{OsStr, OsString};
 use std::fmt::Display;
 use std::fs::File;
 use std::io::{self, BufWriter, Write};
 #[cfg(feature = "debug")]
 use std::os::unix::ffi::OsStrExt;
 use std::path::PathBuf;
 use std::slice::Iter;
@@ -15,118 +14,101 @@ use vec_map::{self, VecMap};
 
 // Internal
 use INTERNAL_ERROR_MSG;
 use INVALID_UTF8;
 use SubCommand;
 use app::App;
 use app::help::Help;
 use app::meta::AppMeta;
-use app::settings::{AppFlags, AppSettings};
+use app::settings::AppFlags;
 use args::{AnyArg, ArgMatcher, Base, Switched, Arg, ArgGroup, FlagBuilder, OptBuilder, PosBuilder};
-use args::MatchedArg;
 use args::settings::ArgSettings;
 use completions::ComplGen;
 use errors::{Error, ErrorKind};
 use errors::Result as ClapResult;
-use fmt::{Colorizer, ColorWhen};
+use fmt::ColorWhen;
 use osstringext::OsStrExt2;
 use completions::Shell;
 use suggestions;
+use app::settings::AppSettings as AS;
+use app::validator::Validator;
+use app::usage;
+
+#[derive(Debug, PartialEq, Copy, Clone)]
+#[doc(hidden)]
+pub enum ParseResult<'a> {
+    Flag,
+    Opt(&'a str),
+    Pos(&'a str),
+    MaybeHyphenValue,
+    MaybeNegNum,
+    NotFound,
+    ValuesDone,
+}
 
 #[allow(missing_debug_implementations)]
 #[doc(hidden)]
+#[derive(Clone, Default)]
 pub struct Parser<'a, 'b>
     where 'a: 'b
 {
-    propogated: bool,
-    required: Vec<&'a str>,
-    r_ifs: Vec<(&'a str, &'b str, &'a str)>,
-    pub short_list: Vec<char>,
-    pub long_list: Vec<&'b str>,
-    blacklist: Vec<&'b str>,
-    // A list of possible flags
-    pub flags: Vec<FlagBuilder<'a, 'b>>,
-    // A list of possible options
-    pub opts: Vec<OptBuilder<'a, 'b>>,
-    // A list of positional arguments
-    pub positionals: VecMap<PosBuilder<'a, 'b>>,
-    // A list of subcommands
-    #[doc(hidden)]
-    pub subcommands: Vec<App<'a, 'b>>,
-    groups: HashMap<&'a str, ArgGroup<'a>>,
-    pub global_args: Vec<Arg<'a, 'b>>,
-    overrides: Vec<&'b str>,
-    help_short: Option<char>,
-    version_short: Option<char>,
+    pub meta: AppMeta<'b>,
     settings: AppFlags,
     pub g_settings: AppFlags,
-    pub meta: AppMeta<'b>,
-    pub id: usize,
-    trailing_vals: bool,
-    valid_neg_num: bool,
-    // have we found a valid arg yet
-    valid_arg: bool,
-}
-
-impl<'a, 'b> Default for Parser<'a, 'b> {
-    fn default() -> Self {
-        Parser {
-            propogated: false,
-            flags: vec![],
-            opts: vec![],
-            positionals: VecMap::new(),
-            subcommands: vec![],
-            help_short: None,
-            version_short: None,
-            required: vec![],
-            r_ifs: vec![],
-            short_list: vec![],
-            long_list: vec![],
-            blacklist: vec![],
-            groups: HashMap::new(),
-            global_args: vec![],
-            overrides: vec![],
-            g_settings: AppFlags::new(),
-            settings: AppFlags::new(),
-            meta: AppMeta::new(),
-            trailing_vals: false,
-            id: 0,
-            valid_neg_num: false,
-            valid_arg: false,
-        }
-    }
+    pub flags: Vec<FlagBuilder<'a, 'b>>,
+    pub opts: Vec<OptBuilder<'a, 'b>>,
+    pub positionals: VecMap<PosBuilder<'a, 'b>>,
+    pub subcommands: Vec<App<'a, 'b>>,
+    pub groups: Vec<ArgGroup<'a>>,
+    pub global_args: Vec<Arg<'a, 'b>>,
+    pub required: Vec<&'a str>,
+    pub r_ifs: Vec<(&'a str, &'b str, &'a str)>,
+    pub blacklist: Vec<&'b str>,
+    pub overrides: Vec<&'b str>,
+    help_short: Option<char>,
+    version_short: Option<char>,
+    cache: Option<&'a str>,
+    pub help_message: Option<&'a str>,
+    pub version_message: Option<&'a str>,
 }
 
 impl<'a, 'b> Parser<'a, 'b>
     where 'a: 'b
 {
     pub fn with_name(n: String) -> Self {
-        Parser { meta: AppMeta::with_name(n), ..Default::default() }
+        Parser {
+            meta: AppMeta::with_name(n),
+            ..Default::default()
+        }
     }
 
     pub fn help_short(&mut self, s: &str) {
-        self.help_short = s.trim_left_matches(|c| c == '-')
+        let c = s.trim_left_matches(|c| c == '-')
             .chars()
-            .nth(0);
+            .nth(0)
+            .unwrap_or('h');
+        self.help_short = Some(c);
     }
 
     pub fn version_short(&mut self, s: &str) {
-        self.version_short = s.trim_left_matches(|c| c == '-')
+        let c = s.trim_left_matches(|c| c == '-')
             .chars()
-            .nth(0);
+            .nth(0)
+            .unwrap_or('V');
+        self.version_short = Some(c);
     }
 
     pub fn gen_completions_to<W: Write>(&mut self, for_shell: Shell, buf: &mut W) {
-        if !self.propogated {
+        if !self.is_set(AS::Propogated) {
             self.propogate_help_version();
             self.build_bin_names();
             self.propogate_globals();
             self.propogate_settings();
-            self.propogated = true;
+            self.set(AS::Propogated);
         }
 
         ComplGen::new(self).generate(for_shell, buf)
     }
 
     pub fn gen_completions(&mut self, for_shell: Shell, od: OsString) {
         use std::error::Error;
 
@@ -141,530 +123,561 @@ impl<'a, 'b> Parser<'a, 'b>
 
         let mut file = match File::create(out_dir.join(file_name)) {
             Err(why) => panic!("couldn't create completion file: {}", why.description()),
             Ok(file) => file,
         };
         self.gen_completions_to(for_shell, &mut file)
     }
 
-    // actually adds the arguments
-    pub fn add_arg(&mut self, a: &Arg<'a, 'b>) {
-        debug_assert!(!(self.flags.iter().any(|f| &f.b.name == &a.name) ||
-                        self.opts.iter().any(|o| o.b.name == a.name) ||
-                        self.positionals.values().any(|p| p.b.name == a.name)),
-                      format!("Non-unique argument name: {} is already in use", a.name));
+    #[inline]
+    fn app_debug_asserts(&mut self) -> bool {
+        assert!(self.verify_positionals());
+        let should_err = self.groups
+            .iter()
+            .all(|g| {
+                g.args
+                    .iter()
+                    .all(|arg| {
+                             (self.flags.iter().any(|f| &f.b.name == arg) ||
+                              self.opts.iter().any(|o| &o.b.name == arg) ||
+                              self.positionals.values().any(|p| &p.b.name == arg) ||
+                              self.groups.iter().any(|g| &g.name == arg))
+                         })
+            });
+        let g = self.groups
+            .iter()
+            .find(|g| {
+                g.args
+                    .iter()
+                    .any(|arg| {
+                             !(self.flags.iter().any(|f| &f.b.name == arg) ||
+                               self.opts.iter().any(|o| &o.b.name == arg) ||
+                               self.positionals.values().any(|p| &p.b.name == arg) ||
+                               self.groups.iter().any(|g| &g.name == arg))
+                         })
+            });
+        assert!(should_err,
+                "The group '{}' contains the arg '{}' that doesn't actually exist.",
+                g.unwrap().name,
+                g.unwrap()
+                    .args
+                    .iter()
+                    .find(|arg| {
+                              !(self.flags.iter().any(|f| &&f.b.name == arg) ||
+                                self.opts.iter().any(|o| &&o.b.name == arg) ||
+                                self.positionals.values().any(|p| &&p.b.name == arg) ||
+                                self.groups.iter().any(|g| &&g.name == arg))
+                          })
+                    .unwrap());
+        true
+    }
+
+    #[inline]
+    fn debug_asserts(&self, a: &Arg) -> bool {
+        assert!(!arg_names!(self).any(|name| name == a.b.name),
+                format!("Non-unique argument name: {} is already in use", a.b.name));
+        if let Some(l) = a.s.long {
+            assert!(!self.contains_long(l),
+                    "Argument long must be unique\n\n\t--{} is already in use",
+                    l);
+        }
+        if let Some(s) = a.s.short {
+            assert!(!self.contains_short(s),
+                    "Argument short must be unique\n\n\t-{} is already in use",
+                    s);
+        }
+        let i = if a.index.is_none() {
+            (self.positionals.len() + 1)
+        } else {
+            a.index.unwrap() as usize
+        };
+        assert!(!self.positionals.contains_key(i),
+                "Argument \"{}\" has the same index as another positional \
+                    argument\n\n\tPerhaps try .multiple(true) to allow one positional argument \
+                    to take multiple values",
+                a.b.name);
+        assert!(!(a.is_set(ArgSettings::Required) && a.is_set(ArgSettings::Global)),
+                "Global arguments cannot be required.\n\n\t'{}' is marked as \
+                          global and required",
+                a.b.name);
+        if a.b.is_set(ArgSettings::Last) {
+            assert!(!self.positionals
+                         .values()
+                         .any(|p| p.b.is_set(ArgSettings::Last)),
+                    "Only one positional argument may have last(true) set. Found two.");
+            assert!(a.s.long.is_none(),
+                    "Flags or Options may not have last(true) set. {} has both a long and last(true) set.",
+                    a.b.name);
+            assert!(a.s.short.is_none(),
+                    "Flags or Options may not have last(true) set. {} has both a short and last(true) set.",
+                    a.b.name);
+        }
+        true
+    }
+
+    #[inline]
+    fn add_conditional_reqs(&mut self, a: &Arg<'a, 'b>) {
         if let Some(ref r_ifs) = a.r_ifs {
             for &(arg, val) in r_ifs {
-                self.r_ifs.push((arg, val, a.name));
-            }
-        }
-        if let Some(ref grps) = a.groups {
-            for g in grps {
-                let ag = self.groups.entry(g).or_insert_with(|| ArgGroup::with_name(g));
-                ag.args.push(a.name);
+                self.r_ifs.push((arg, val, a.b.name));
             }
         }
-        if let Some(s) = a.short {
-            debug_assert!(!self.short_list.contains(&s),
-                          format!("Argument short must be unique\n\n\t-{} is already in use",
-                                  s));
-            self.short_list.push(s);
-        }
-        if let Some(l) = a.long {
-            debug_assert!(!self.long_list.contains(&l),
-                          format!("Argument long must be unique\n\n\t--{} is already in use",
-                                  l));
-            self.long_list.push(l);
-            if l == "help" {
-                self.unset(AppSettings::NeedsLongHelp);
-            } else if l == "version" {
-                self.unset(AppSettings::NeedsLongVersion);
+    }
+
+    #[inline]
+    fn add_arg_groups(&mut self, a: &Arg<'a, 'b>) {
+        if let Some(ref grps) = a.b.groups {
+            for g in grps {
+                let mut found = false;
+                if let Some(ref mut ag) = self.groups.iter_mut().find(|grp| &grp.name == g) {
+                    ag.args.push(a.b.name);
+                    found = true;
+                }
+                if !found {
+                    let mut ag = ArgGroup::with_name(g);
+                    ag.args.push(a.b.name);
+                    self.groups.push(ag);
+                }
             }
         }
+    }
+
+    #[inline]
+    fn add_reqs(&mut self, a: &Arg<'a, 'b>) {
         if a.is_set(ArgSettings::Required) {
-            self.required.push(a.name);
+            // If the arg is required, add all it's requirements to master required list
+            if let Some(ref areqs) = a.b.requires {
+                for name in areqs
+                        .iter()
+                        .filter(|&&(val, _)| val.is_none())
+                        .map(|&(_, name)| name) {
+                    self.required.push(name);
+                }
+            }
+            self.required.push(a.b.name);
+        }
+    }
+
+    #[inline]
+    fn implied_settings(&mut self, a: &Arg<'a, 'b>) {
+        if a.is_set(ArgSettings::Last) {
+            // if an arg has `Last` set, we need to imply DontCollapseArgsInUsage so that args
+            // in the usage string don't get confused or left out.
+            self.set(AS::DontCollapseArgsInUsage);
+            self.set(AS::ContainsLast);
         }
-        if a.index.is_some() || (a.short.is_none() && a.long.is_none()) {
+        if let Some(l) = a.s.long {
+            if l == "version" {
+                self.unset(AS::NeedsLongVersion);
+            } else if l == "help" {
+                self.unset(AS::NeedsLongHelp);
+            }
+        }
+    }
+
+    // actually adds the arguments
+    pub fn add_arg(&mut self, a: Arg<'a, 'b>) {
+        // if it's global we have to clone anyways
+        if a.is_set(ArgSettings::Global) {
+            return self.add_arg_ref(&a);
+        }
+        debug_assert!(self.debug_asserts(&a));
+        self.add_conditional_reqs(&a);
+        self.add_arg_groups(&a);
+        self.add_reqs(&a);
+        self.implied_settings(&a);
+        if a.index.is_some() || (a.s.short.is_none() && a.s.long.is_none()) {
             let i = if a.index.is_none() {
                 (self.positionals.len() + 1)
             } else {
                 a.index.unwrap() as usize
             };
-            debug_assert!(!self.positionals.contains_key(i),
-                          format!("Argument \"{}\" has the same index as another positional \
-                    argument\n\n\tPerhaps try .multiple(true) to allow one positional argument \
-                    to take multiple values",
-                                  a.name));
-            let pb = PosBuilder::from_arg(a, i as u64, &mut self.required);
+            self.positionals
+                .insert(i, PosBuilder::from_arg(a, i as u64));
+        } else if a.is_set(ArgSettings::TakesValue) {
+            let mut ob = OptBuilder::from(a);
+            ob.s.unified_ord = self.flags.len() + self.opts.len();
+            self.opts.push(ob);
+        } else {
+            let mut fb = FlagBuilder::from(a);
+            fb.s.unified_ord = self.flags.len() + self.opts.len();
+            self.flags.push(fb);
+        }
+    }
+    // actually adds the arguments but from a borrow (which means we have to do some clonine)
+    pub fn add_arg_ref(&mut self, a: &Arg<'a, 'b>) {
+        debug_assert!(self.debug_asserts(&a));
+        self.add_conditional_reqs(a);
+        self.add_arg_groups(a);
+        self.add_reqs(a);
+        self.implied_settings(&a);
+        if a.index.is_some() || (a.s.short.is_none() && a.s.long.is_none()) {
+            let i = if a.index.is_none() {
+                (self.positionals.len() + 1)
+            } else {
+                a.index.unwrap() as usize
+            };
+            let pb = PosBuilder::from_arg_ref(a, i as u64);
             self.positionals.insert(i, pb);
         } else if a.is_set(ArgSettings::TakesValue) {
-            let mut ob = OptBuilder::from_arg(a, &mut self.required);
-            let id = self.opts.len();
-            ob.b.id = id;
+            let mut ob = OptBuilder::from(a);
             ob.s.unified_ord = self.flags.len() + self.opts.len();
-            self.opts.insert(id, ob);
+            self.opts.push(ob);
         } else {
             let mut fb = FlagBuilder::from(a);
-            let id = self.flags.len();
-            fb.b.id = id;
             fb.s.unified_ord = self.flags.len() + self.opts.len();
-            self.flags.insert(id, fb);
+            self.flags.push(fb);
         }
         if a.is_set(ArgSettings::Global) {
-            debug_assert!(!a.is_set(ArgSettings::Required),
-                          format!("Global arguments cannot be required.\n\n\t'{}' is marked as \
-                          global and required",
-                                  a.name));
             self.global_args.push(a.into());
         }
     }
 
     pub fn add_group(&mut self, group: ArgGroup<'a>) {
         if group.required {
-            self.required.push(group.name.into());
+            self.required.push(group.name);
             if let Some(ref reqs) = group.requires {
                 self.required.extend_from_slice(reqs);
             }
             if let Some(ref bl) = group.conflicts {
                 self.blacklist.extend_from_slice(bl);
             }
         }
-        let mut found = false;
-        if let Some(ref mut grp) = self.groups.get_mut(&group.name) {
+        if self.groups.iter().any(|g| g.name == group.name) {
+            let grp = self.groups
+                .iter_mut()
+                .find(|g| g.name == group.name)
+                .expect(INTERNAL_ERROR_MSG);
             grp.args.extend_from_slice(&group.args);
             grp.requires = group.requires.clone();
             grp.conflicts = group.conflicts.clone();
             grp.required = group.required;
-            found = true;
-        }
-        if !found {
-            self.groups.insert(group.name.into(), group);
+        } else {
+            self.groups.push(group);
         }
     }
 
     pub fn add_subcommand(&mut self, mut subcmd: App<'a, 'b>) {
         debugln!("Parser::add_subcommand: term_w={:?}, name={}",
-                 self.meta.term_w, subcmd.p.meta.name);
+                 self.meta.term_w,
+                 subcmd.p.meta.name);
         subcmd.p.meta.term_w = self.meta.term_w;
         if subcmd.p.meta.name == "help" {
-            self.settings.unset(AppSettings::NeedsSubcommandHelp);
+            self.unset(AS::NeedsSubcommandHelp);
         }
 
         self.subcommands.push(subcmd);
     }
 
     pub fn propogate_settings(&mut self) {
-        debugln!("Parser::propogate_settings: self={}, g_settings={:#?}", 
-            self.meta.name, self.g_settings);
+        debugln!("Parser::propogate_settings: self={}, g_settings={:#?}",
+                 self.meta.name,
+                 self.g_settings);
         for sc in &mut self.subcommands {
-            debugln!("Parser::propogate_settings: sc={}, settings={:#?}, g_settings={:#?}", 
-                sc.p.meta.name, sc.p.settings, sc.p.g_settings);
+            debugln!("Parser::propogate_settings: sc={}, settings={:#?}, g_settings={:#?}",
+                     sc.p.meta.name,
+                     sc.p.settings,
+                     sc.p.g_settings);
             // We have to create a new scope in order to tell rustc the borrow of `sc` is
             // done and to recursively call this method
             {
-                let vsc = self.settings.is_set(AppSettings::VersionlessSubcommands);
-                let gv = self.settings.is_set(AppSettings::GlobalVersion);
+                let vsc = self.settings.is_set(AS::VersionlessSubcommands);
+                let gv = self.settings.is_set(AS::GlobalVersion);
 
                 if vsc {
-                    sc.p.settings.set(AppSettings::DisableVersion);
+                    sc.p.set(AS::DisableVersion);
                 }
                 if gv && sc.p.meta.version.is_none() && self.meta.version.is_some() {
-                    sc.p.set(AppSettings::GlobalVersion);
+                    sc.p.set(AS::GlobalVersion);
                     sc.p.meta.version = Some(self.meta.version.unwrap());
                 }
                 sc.p.settings = sc.p.settings | self.g_settings;
                 sc.p.g_settings = sc.p.g_settings | self.g_settings;
+                sc.p.meta.term_w = self.meta.term_w;
+                sc.p.meta.max_w = self.meta.max_w;
             }
             sc.p.propogate_settings();
         }
     }
 
     #[cfg_attr(feature = "lints", allow(needless_borrow))]
     pub fn derive_display_order(&mut self) {
-        if self.settings.is_set(AppSettings::DeriveDisplayOrder) {
-            let unified = self.settings.is_set(AppSettings::UnifiedHelpMessage);
+        if self.is_set(AS::DeriveDisplayOrder) {
+            let unified = self.is_set(AS::UnifiedHelpMessage);
             for (i, o) in self.opts
-                .iter_mut()
-                .enumerate()
-                .filter(|&(_, ref o)| o.s.disp_ord == 999) {
+                    .iter_mut()
+                    .enumerate()
+                    .filter(|&(_, ref o)| o.s.disp_ord == 999) {
                 o.s.disp_ord = if unified { o.s.unified_ord } else { i };
             }
             for (i, f) in self.flags
-                .iter_mut()
-                .enumerate()
-                .filter(|&(_, ref f)| f.s.disp_ord == 999) {
+                    .iter_mut()
+                    .enumerate()
+                    .filter(|&(_, ref f)| f.s.disp_ord == 999) {
                 f.s.disp_ord = if unified { f.s.unified_ord } else { i };
             }
             for (i, sc) in &mut self.subcommands
-                .iter_mut()
-                .enumerate()
-                .filter(|&(_, ref sc)| sc.p.meta.disp_ord == 999) {
+                                    .iter_mut()
+                                    .enumerate()
+                                    .filter(|&(_, ref sc)| sc.p.meta.disp_ord == 999) {
                 sc.p.meta.disp_ord = i;
             }
         }
         for sc in &mut self.subcommands {
             sc.p.derive_display_order();
         }
     }
 
     pub fn required(&self) -> Iter<&str> { self.required.iter() }
 
-    pub fn get_required_from(&self,
-                             reqs: &[&'a str],
-                             matcher: Option<&ArgMatcher<'a>>,
-                             extra: Option<&str>)
-                             -> VecDeque<String> {
-        debugln!("Parser::get_required_from: reqs={:?}, extra={:?}", reqs, extra);
-        let mut c_flags: Vec<&str> = vec![];
-        let mut c_pos: Vec<&str> = vec![];
-        let mut c_opt: Vec<&str> = vec![];
-        let mut grps: Vec<&str> = vec![];
-        macro_rules! categorize {
-            ($_self:ident, $name:ident, $c_flags:ident, $c_pos:ident, $c_opt:ident, $grps:ident) => {
-                if $_self.flags.iter().any(|f| &f.b.name == $name) {
-                    $c_flags.push($name);
-                } else if self.opts.iter().any(|o| &o.b.name == $name) {
-                    $c_opt.push($name);
-                } else if self.groups.contains_key($name) {
-                    $grps.push($name);
-                } else {
-                    $c_pos.push($name);
-                }
-            }
-        };
-        for name in reqs {
-            categorize!(self, name, c_flags, c_pos, c_opt, grps);
-        }
-        if let Some(ref name) = extra {
-            categorize!(self, name, c_flags, c_pos, c_opt, grps);
-        }
-        macro_rules! fill_vecs {
-            ($_self:ident {
-                $t1:ident => $v1:ident => $i1:ident,
-                $t2:ident => $v2:ident => $i2:ident,
-                $t3:ident => $v3:ident => $i3:ident,
-                $gv:ident, $tmp:ident
-            }) => {
-                for a in &$v1 {
-                    if let Some(a) = self.$t1.$i1().filter(|arg| &arg.b.name == a).next() {
-                        if let Some(ref rl) = a.b.requires {
-                            for &(_, r) in rl.iter() {
-                                if !reqs.contains(&r) {
-                                    if $_self.$t1.$i1().any(|t| &t.b.name == &r) {
-                                        $tmp.push(r);
-                                    } else if $_self.$t2.$i2().any(|t| &t.b.name == &r) {
-                                        $v2.push(r);
-                                    } else if $_self.$t3.$i3().any(|t| &t.b.name == &r) {
-                                        $v3.push(r);
-                                    } else if $_self.groups.contains_key(r) {
-                                        $gv.push(r);
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-                $v1.extend(&$tmp);
-            };
-        }
-
-        let mut tmp = vec![];
-        fill_vecs!(self {
-            flags       => c_flags => iter,
-            opts        => c_opt   => iter,
-            positionals => c_pos   => values,
-            grps, tmp
-        });
-        tmp.clear();
-        fill_vecs!(self {
-            opts        => c_opt   => iter,
-            flags       => c_flags => iter,
-            positionals => c_pos   => values,
-            grps, tmp
-        });
-        tmp.clear();
-        fill_vecs!(self {
-            positionals => c_pos   => values,
-            opts        => c_opt   => iter,
-            flags       => c_flags => iter,
-            grps, tmp
-        });
-        let mut ret_val = VecDeque::new();
-        c_pos.dedup();
-        c_flags.dedup();
-        c_opt.dedup();
-        grps.dedup();
-        let args_in_groups = grps.iter()
-            .flat_map(|g| self.arg_names_in_group(g))
-            .collect::<Vec<_>>();
-
-        let pmap = c_pos.into_iter()
-            .filter(|&p| matcher.is_none() || !matcher.as_ref().unwrap().contains(p))
-            .filter_map(|p| self.positionals.values().find(|x| x.b.name == p))
-            .filter(|p| !args_in_groups.contains(&p.b.name))
-            .map(|p| (p.index, p))
-            .collect::<BTreeMap<u64, &PosBuilder>>();// sort by index
-        debugln!("Parser::get_required_from: args_in_groups={:?}", args_in_groups);
-        for &p in pmap.values() {
-            let s = p.to_string();
-            if args_in_groups.is_empty() || !args_in_groups.contains(&&*s) {
-                ret_val.push_back(s);
-            }
-        }
-        macro_rules! write_arg {
-            ($i:expr, $m:ident, $v:ident, $r:ident, $aig:ident) => {
-                for f in $v {
-                    if $m.is_some() && $m.as_ref().unwrap().contains(f) || $aig.contains(&f) {
-                        continue;
-                    }
-                    $r.push_back($i.filter(|flg| &flg.b.name == &f).next().unwrap().to_string());
-                }
-            }
-        }
-        write_arg!(self.flags.iter(), matcher, c_flags, ret_val, args_in_groups);
-        write_arg!(self.opts.iter(), matcher, c_opt, ret_val, args_in_groups);
-        let mut g_vec = vec![];
-        for g in grps {
-            let g_string = self.args_in_group(g)
-                .join("|");
-            g_vec.push(format!("<{}>", &g_string[..g_string.len()]));
-        }
-        g_vec.dedup();
-        for g in g_vec {
-            ret_val.push_back(g);
-        }
-
-        ret_val
-    }
-
-    // Gets the `[ARGS]` tag for the usage string
-    pub fn get_args_tag(&self) -> Option<String> {
-        debugln!("Parser::get_args_tag;");
-        let mut count = 0;
-        'outer: for p in self.positionals.values().filter(|p| !p.is_set(ArgSettings::Required)) {
-            debugln!("Parser::get_args_tag:iter:iter: p={};", p.b.name);
-            if let Some(g_vec) = self.groups_for_arg(p.b.name) {
-                for grp_s in &g_vec {
-                    debugln!("Parser::get_args_tag:iter:iter: grp_s={};", grp_s);
-                    if let Some(grp) = self.groups.get(grp_s) {
-                        debug!("Parser::get_args_tag:iter:iter: Is group required...{:?}", grp.required);
-                        if grp.required {
-                            // if it's part of a required group we don't want to count it
-                            continue 'outer;
-                        }
-                    }
-                }
-            }
-            count += 1;
-            debugln!("Parser::get_args_tag:iter: {} Args not required", count);
-        }
-        if !self.is_set(AppSettings::DontCollapseArgsInUsage) &&
-           (count > 1 || self.positionals.len() > 1) {
-            return None; // [ARGS]
-        } else if count == 1 {
-            let p = self.positionals
-                .values()
-                .find(|p| !p.is_set(ArgSettings::Required))
-                .expect(INTERNAL_ERROR_MSG);
-            return Some(format!(" [{}]{}", p.name_no_brackets(), p.multiple_str()));
-        } else if self.is_set(AppSettings::DontCollapseArgsInUsage) &&
-                  !self.positionals.is_empty() {
-            return Some(self.positionals
-                .values()
-                .filter(|p| !p.is_set(ArgSettings::Required))
-                .map(|p| format!(" [{}]{}", p.name_no_brackets(), p.multiple_str()))
-                .collect::<Vec<_>>()
-                .join(""));
-        }
-        Some("".into())
-    }
-
-    // Determines if we need the `[FLAGS]` tag in the usage string
-    pub fn needs_flags_tag(&self) -> bool {
-        debugln!("Parser::needs_flags_tag;");
-        'outer: for f in &self.flags {
-            debugln!("Parser::needs_flags_tag:iter: f={};", f.b.name);
-            if let Some(l) = f.s.long {
-                if l == "help" || l == "version" {
-                    // Don't print `[FLAGS]` just for help or version
-                    continue;
-                }
-            }
-            if let Some(g_vec) = self.groups_for_arg(f.b.name) {
-                for grp_s in &g_vec {
-                    debugln!("Parser::needs_flags_tag:iter:iter: grp_s={};", grp_s);
-                    if let Some(grp) = self.groups.get(grp_s) {
-                        debug!("Parser::needs_flags_tag:iter:iter: Is group required...{:?}", grp.required);
-                        if grp.required {
-                            continue 'outer;
-                        }
-                    }
-                }
-            }
-            debugln!("Parser::needs_flags_tag:iter: [FLAGS] required");
-            return true;
-        }
-
-        debugln!("Parser::needs_flags_tag: [FLAGS] not required");
-        false
+    #[cfg_attr(feature = "lints", allow(needless_borrow))]
+    #[inline]
+    pub fn has_args(&self) -> bool {
+        !(self.flags.is_empty() && self.opts.is_empty() && self.positionals.is_empty())
     }
 
     #[inline]
     pub fn has_opts(&self) -> bool { !self.opts.is_empty() }
 
     #[inline]
     pub fn has_flags(&self) -> bool { !self.flags.is_empty() }
 
     #[inline]
     pub fn has_positionals(&self) -> bool { !self.positionals.is_empty() }
 
     #[inline]
     pub fn has_subcommands(&self) -> bool { !self.subcommands.is_empty() }
 
     #[inline]
-    pub fn is_set(&self, s: AppSettings) -> bool { self.settings.is_set(s) }
+    pub fn has_visible_opts(&self) -> bool {
+        if self.opts.is_empty() {
+            return false;
+        }
+        self.opts.iter().any(|o| !o.is_set(ArgSettings::Hidden))
+    }
+
+    #[inline]
+    pub fn has_visible_flags(&self) -> bool {
+        if self.flags.is_empty() {
+            return false;
+        }
+        self.flags.iter().any(|f| !f.is_set(ArgSettings::Hidden))
+    }
 
     #[inline]
-    pub fn set(&mut self, s: AppSettings) { self.settings.set(s) }
+    pub fn has_visible_positionals(&self) -> bool {
+        if self.positionals.is_empty() {
+            return false;
+        }
+        self.positionals
+            .values()
+            .any(|p| !p.is_set(ArgSettings::Hidden))
+    }
 
     #[inline]
-    pub fn unset(&mut self, s: AppSettings) { self.settings.unset(s) }
+    pub fn has_visible_subcommands(&self) -> bool {
+        if self.subcommands.is_empty() {
+            return false;
+        }
+        self.subcommands.iter().any(|s| !s.p.is_set(AS::Hidden))
+    }
+
+    #[inline]
+    pub fn is_set(&self, s: AS) -> bool { self.settings.is_set(s) }
+
+    #[inline]
+    pub fn set(&mut self, s: AS) { self.settings.set(s) }
+
+    #[inline]
+    pub fn unset(&mut self, s: AS) { self.settings.unset(s) }
 
     #[cfg_attr(feature = "lints", allow(block_in_if_condition_stmt))]
-    pub fn verify_positionals(&mut self) {
+    pub fn verify_positionals(&mut self) -> bool {
         // Because you must wait until all arguments have been supplied, this is the first chance
         // to make assertions on positional argument indexes
         //
         // Firt we verify that the index highest supplied index, is equal to the number of
         // positional arguments to verify there are no gaps (i.e. supplying an index of 1 and 3
         // but no 2)
         if let Some((idx, p)) = self.positionals.iter().rev().next() {
-            debug_assert!(!(idx != self.positionals.len()),
-                    format!("Found positional argument \"{}\" who's index is {} but there are \
-                    only {} positional arguments defined",
-                            p.b.name,
-                            idx,
-                            self.positionals.len()));
+            assert!(!(idx != self.positionals.len()),
+                    "Found positional argument \"{}\" who's index is {} but there \
+                          are only {} positional arguments defined",
+                    p.b.name,
+                    idx,
+                    self.positionals.len());
         }
 
         // Next we verify that only the highest index has a .multiple(true) (if any)
         if self.positionals
-            .values()
-            .any(|a| {
-                a.b.settings.is_set(ArgSettings::Multiple) &&
-                (a.index as usize != self.positionals.len())
-            }) {
+               .values()
+               .any(|a| {
+                        a.b.is_set(ArgSettings::Multiple) &&
+                        (a.index as usize != self.positionals.len())
+                    }) {
+            let mut it = self.positionals.values().rev();
+            let last = it.next().unwrap();
+            let second_to_last = it.next().unwrap();
+            // Either the final positional is required
+            // Or the second to last has a terminator or .last(true) set
+            let ok = last.is_set(ArgSettings::Required) ||
+                     (second_to_last.v.terminator.is_some() ||
+                      second_to_last.b.is_set(ArgSettings::Last)) ||
+                     last.is_set(ArgSettings::Last);
+            assert!(ok,
+                    "When using a positional argument with .multiple(true) that is *not the \
+                          last* positional argument, the last positional argument (i.e the one \
+                          with the highest index) *must* have .required(true) or .last(true) set.");
+            let ok = second_to_last.is_set(ArgSettings::Multiple) || last.is_set(ArgSettings::Last);
+            assert!(ok,
+                    "Only the last positional argument, or second to last positional \
+                          argument may be set to .multiple(true)");
 
-            debug_assert!({
-                    let mut it = self.positionals.values().rev();
-                    // Either the final positional is required
-                    it.next().unwrap().is_set(ArgSettings::Required)
-                    // Or the second to last has a terminator set
-                    || it.next().unwrap().v.terminator.is_some()
-                },
-                "When using a positional argument with .multiple(true) that is *not the last* \
-                positional argument, the last positional argument (i.e the one with the highest \
-                index) *must* have .required(true) set."
-            );
-
-            debug_assert!({
-                let num = self.positionals.len() - 1;
-                self.positionals.get(num).unwrap().is_set(ArgSettings::Multiple)
-            },
-            "Only the last positional argument, or second to last positional argument may be set to .multiple(true)");
-
-            self.set(AppSettings::LowIndexMultiplePositional);
+            let count = self.positionals
+                .values()
+                .filter(|p| p.b.settings.is_set(ArgSettings::Multiple) && p.v.num_vals.is_none())
+                .count();
+            let ok = count <= 1 ||
+                     (last.is_set(ArgSettings::Last) && last.is_set(ArgSettings::Multiple) &&
+                      second_to_last.is_set(ArgSettings::Multiple) &&
+                      count == 2);
+            assert!(ok,
+                    "Only one positional argument with .multiple(true) set is allowed per \
+                        command, unless the second one also has .last(true) set");
         }
 
-        debug_assert!(self.positionals.values()
-            .filter(|p| p.b.settings.is_set(ArgSettings::Multiple)
-                && p.v.num_vals.is_none())
-            .map(|_| 1)
-            .sum::<u64>() <= 1,
-            "Only one positional argument with .multiple(true) set is allowed per command");
 
-        // If it's required we also need to ensure all previous positionals are
-        // required too
-        if self.is_set(AppSettings::AllowMissingPositional) {
+        if self.is_set(AS::AllowMissingPositional) {
+            // Check that if a required positional argument is found, all positions with a lower
+            // index are also required.
             let mut found = false;
             let mut foundx2 = false;
             for p in self.positionals.values().rev() {
                 if foundx2 && !p.b.settings.is_set(ArgSettings::Required) {
-                    // [arg1] <arg2> is Ok
-                    // [arg1] <arg2> <arg3> Is not
-                    debug_assert!(p.b.settings.is_set(ArgSettings::Required),
-                                "Found positional argument which is not required with a lower index \
-                                than a required positional argument by two or more: {:?} index {}",
-                                p.b.name,
-                                p.index);
-                } else if p.b.settings.is_set(ArgSettings::Required) {
+                    assert!(p.b.is_set(ArgSettings::Required),
+                            "Found positional argument which is not required with a lower \
+                                  index than a required positional argument by two or more: {:?} \
+                                  index {}",
+                            p.b.name,
+                            p.index);
+                } else if p.b.is_set(ArgSettings::Required) && !p.b.is_set(ArgSettings::Last) {
+                    // Args that .last(true) don't count since they can be required and have
+                    // positionals with a lower index that aren't required
+                    // Imagine: prog <req1> [opt1] -- <req2>
+                    // Both of these are valid invocations:
+                    //      $ prog r1 -- r2
+                    //      $ prog r1 o1 -- r2
                     if found {
                         foundx2 = true;
                         continue;
                     }
                     found = true;
                     continue;
                 } else {
                     found = false;
                 }
             }
         } else {
+            // Check that if a required positional argument is found, all positions with a lower
+            // index are also required
             let mut found = false;
             for p in self.positionals.values().rev() {
                 if found {
-                    debug_assert!(p.b.settings.is_set(ArgSettings::Required),
-                                "Found positional argument which is not required with a lower index \
-                                than a required positional argument: {:?} index {}",
-                                p.b.name,
-                                p.index);
-                } else if p.b.settings.is_set(ArgSettings::Required) {
+                    assert!(p.b.is_set(ArgSettings::Required),
+                            "Found positional argument which is not required with a lower \
+                                  index than a required positional argument: {:?} index {}",
+                            p.b.name,
+                            p.index);
+                } else if p.b.is_set(ArgSettings::Required) && !p.b.is_set(ArgSettings::Last) {
+                    // Args that .last(true) don't count since they can be required and have
+                    // positionals with a lower index that aren't required
+                    // Imagine: prog <req1> [opt1] -- <req2>
+                    // Both of these are valid invocations:
+                    //      $ prog r1 -- r2
+                    //      $ prog r1 o1 -- r2
                     found = true;
                     continue;
                 }
             }
         }
+        if self.positionals
+               .values()
+               .any(|p| {
+                        p.b.is_set(ArgSettings::Last) && p.b.is_set(ArgSettings::Required)
+                    }) && self.has_subcommands() &&
+           !self.is_set(AS::SubcommandsNegateReqs) {
+            panic!("Having a required positional argument with .last(true) set *and* child \
+            subcommands without setting SubcommandsNegateReqs isn't compatible.");
+        }
+
+        true
     }
 
     pub fn propogate_globals(&mut self) {
         for sc in &mut self.subcommands {
             // We have to create a new scope in order to tell rustc the borrow of `sc` is
             // done and to recursively call this method
             {
                 for a in &self.global_args {
-                    sc.p.add_arg(a);
+                    sc.p.add_arg_ref(a);
                 }
             }
             sc.p.propogate_globals();
         }
     }
 
     // Checks if the arg matches a subcommand name, or any of it's aliases (if defined)
-    #[inline]
-    fn possible_subcommand(&self, arg_os: &OsStr) -> bool {
+    fn possible_subcommand(&self, arg_os: &OsStr) -> (bool, Option<&str>) {
         debugln!("Parser::possible_subcommand: arg={:?}", arg_os);
-        if self.is_set(AppSettings::ArgsNegateSubcommands) && self.valid_arg {
-            return false;
+        fn starts(h: &str, n: &OsStr) -> bool {
+            #[cfg(not(target_os = "windows"))]
+            use std::os::unix::ffi::OsStrExt;
+            #[cfg(target_os = "windows")]
+            use osstringext::OsStrExt3;
+
+            let n_bytes = n.as_bytes();
+            let h_bytes = OsStr::new(h).as_bytes();
+
+            h_bytes.starts_with(n_bytes)
+        }
+
+        if self.is_set(AS::ArgsNegateSubcommands) && self.is_set(AS::ValidArgFound) {
+            return (false, None);
         }
-        self.subcommands
-            .iter()
-            .any(|s| {
-                &s.p.meta.name[..] == &*arg_os ||
-                (s.p.meta.aliases.is_some() &&
-                 s.p
-                    .meta
-                    .aliases
-                    .as_ref()
-                    .unwrap()
-                    .iter()
-                    .any(|&(a, _)| a == &*arg_os))
-            })
+        if !self.is_set(AS::InferSubcommands) {
+            if let Some(sc) = find_subcmd!(self, arg_os) {
+                return (true, Some(&sc.p.meta.name));
+            }
+        } else {
+            let v = self.subcommands
+                .iter()
+                .filter(|s| {
+                    starts(&s.p.meta.name[..], &*arg_os) ||
+                    (s.p.meta.aliases.is_some() &&
+                     s.p
+                         .meta
+                         .aliases
+                         .as_ref()
+                         .unwrap()
+                         .iter()
+                         .filter(|&&(a, _)| starts(a, &*arg_os))
+                         .count() == 1)
+                })
+                .map(|sc| &sc.p.meta.name)
+                .collect::<Vec<_>>();
+
+            if v.len() == 1 {
+                return (true, Some(v[0]));
+            }
+        }
+        (false, None)
     }
 
-    fn parse_help_subcommand<I, T>(&self, it: &mut I) -> ClapResult<()>
+    fn parse_help_subcommand<I, T>(&self, it: &mut I) -> ClapResult<ParseResult<'a>>
         where I: Iterator<Item = T>,
               T: Into<OsString>
     {
         debugln!("Parser::parse_help_subcommand;");
         let cmds: Vec<OsString> = it.map(|c| c.into()).collect();
         let mut help_help = false;
         let mut bin_name = self.meta
             .bin_name
@@ -674,1461 +687,1092 @@ impl<'a, 'b> Parser<'a, 'b>
         let mut sc = {
             let mut sc: &Parser = self;
             for (i, cmd) in cmds.iter().enumerate() {
                 if &*cmd.to_string_lossy() == "help" {
                     // cmd help help
                     help_help = true;
                 }
                 if let Some(c) = sc.subcommands
-                    .iter()
-                    .find(|s| &*s.p.meta.name == cmd)
-                    .map(|sc| &sc.p) {
+                       .iter()
+                       .find(|s| &*s.p.meta.name == cmd)
+                       .map(|sc| &sc.p) {
                     sc = c;
                     if i == cmds.len() - 1 {
                         break;
                     }
                 } else if let Some(c) = sc.subcommands
-                    .iter()
-                    .find(|s| if let Some(ref als) = s.p
-                        .meta
-                        .aliases {
-                        als.iter()
-                            .any(|&(a, _)| &a == &&*cmd.to_string_lossy())
-                    } else {
-                        false
-                    })
-                    .map(|sc| &sc.p) {
+                              .iter()
+                              .find(|s| if let Some(ref als) = s.p.meta.aliases {
+                                        als.iter().any(|&(a, _)| &a == &&*cmd.to_string_lossy())
+                                    } else {
+                                        false
+                                    })
+                              .map(|sc| &sc.p) {
                     sc = c;
                     if i == cmds.len() - 1 {
                         break;
                     }
                 } else {
                     return Err(Error::unrecognized_subcommand(cmd.to_string_lossy().into_owned(),
                                                               self.meta
                                                                   .bin_name
                                                                   .as_ref()
                                                                   .unwrap_or(&self.meta.name),
                                                               self.color()));
                 }
-                bin_name = format!("{} {}",
-                    bin_name,
-                    &*sc.meta.name);
+                bin_name = format!("{} {}", bin_name, &*sc.meta.name);
             }
             sc.clone()
         };
         if help_help {
             let mut pb = PosBuilder::new("subcommand", 1);
             pb.b.help = Some("The subcommand whose help message to display");
             pb.set(ArgSettings::Multiple);
             sc.positionals.insert(1, pb);
             sc.settings = sc.settings | self.g_settings;
         } else {
             sc.create_help_and_version();
         }
         if sc.meta.bin_name != self.meta.bin_name {
             sc.meta.bin_name = Some(format!("{} {}", bin_name, sc.meta.name));
         }
-        sc._help()
+        Err(sc._help(false))
     }
 
     // allow wrong self convention due to self.valid_neg_num = true and it's a private method
     #[cfg_attr(feature = "lints", allow(wrong_self_convention))]
-    #[inline]
-    fn is_new_arg(&mut self, arg_os: &OsStr, needs_val_of: Option<&'a str>) -> bool {
-        debugln!("Parser::is_new_arg: arg={:?}, Needs Val of={:?}", arg_os, needs_val_of);
-        let app_wide_settings = if self.is_set(AppSettings::AllowLeadingHyphen) {
+    fn is_new_arg(&mut self, arg_os: &OsStr, needs_val_of: ParseResult<'a>) -> bool {
+        debugln!("Parser::is_new_arg: arg={:?}, Needs Val of={:?}",
+                 arg_os,
+                 needs_val_of);
+        let app_wide_settings = if self.is_set(AS::AllowLeadingHyphen) {
             true
-        } else if self.is_set(AppSettings::AllowNegativeNumbers) {
+        } else if self.is_set(AS::AllowNegativeNumbers) {
             let a = arg_os.to_string_lossy();
             if a.parse::<i64>().is_ok() || a.parse::<f64>().is_ok() {
-                self.valid_neg_num = true;
+                self.set(AS::ValidNegNumFound);
                 true
             } else {
                 false
             }
         } else {
             false
         };
-        let arg_allows_tac = if let Some(name) = needs_val_of {
-            if let Some(o) = find_by_name!(self, &name, opts, iter) {
+        let arg_allows_tac = match needs_val_of {
+            ParseResult::Opt(name) => {
+                let o = self.opts
+                    .iter()
+                    .find(|o| o.b.name == name)
+                    .expect(INTERNAL_ERROR_MSG);
                 (o.is_set(ArgSettings::AllowLeadingHyphen) || app_wide_settings)
-            } else if let Some(p) = find_by_name!(self, &name, positionals, values) {
+            }
+            ParseResult::Pos(name) => {
+                let p = self.positionals
+                    .values()
+                    .find(|p| p.b.name == name)
+                    .expect(INTERNAL_ERROR_MSG);
                 (p.is_set(ArgSettings::AllowLeadingHyphen) || app_wide_settings)
-            } else {
-                false
             }
-        } else {
-            false
+            _ => false,
         };
-        debugln!("Parser::is_new_arg: Does arg allow leading hyphen...{:?}", arg_allows_tac);
+        debugln!("Parser::is_new_arg: Arg::allow_leading_hyphen({:?})",
+                 arg_allows_tac);
 
         // Is this a new argument, or values from a previous option?
-        debug!("Parser::is_new_arg: Starts new arg...");
         let mut ret = if arg_os.starts_with(b"--") {
-            sdebugln!("--");
-            if arg_os.len_() == 2 {
+            debugln!("Parser::is_new_arg: -- found");
+            if arg_os.len_() == 2 && !arg_allows_tac {
                 return true; // We have to return true so override everything else
+            } else if arg_allows_tac {
+                return false;
             }
             true
         } else if arg_os.starts_with(b"-") {
-            sdebugln!("-");
+            debugln!("Parser::is_new_arg: - found");
             // a singe '-' by itself is a value and typically means "stdin" on unix systems
             !(arg_os.len_() == 1)
         } else {
-            sdebugln!("Probable value");
+            debugln!("Parser::is_new_arg: probably value");
             false
         };
 
         ret = ret && !arg_allows_tac;
 
-        debugln!("Parser::is_new_arg: Starts new arg...{:?}", ret);
+        debugln!("Parser::is_new_arg: starts_new_arg={:?}", ret);
         ret
     }
 
     // The actual parsing function
     #[cfg_attr(feature = "lints", allow(while_let_on_iterator, collapsible_if))]
     pub fn get_matches_with<I, T>(&mut self,
                                   matcher: &mut ArgMatcher<'a>,
                                   it: &mut Peekable<I>)
                                   -> ClapResult<()>
         where I: Iterator<Item = T>,
               T: Into<OsString> + Clone
     {
         debugln!("Parser::get_matches_with;");
         // Verify all positional assertions pass
-        self.verify_positionals();
+        debug_assert!(self.app_debug_asserts());
+        if self.positionals
+               .values()
+               .any(|a| {
+                        a.b.is_set(ArgSettings::Multiple) &&
+                        (a.index as usize != self.positionals.len())
+                    }) &&
+           self.positionals
+               .values()
+               .last()
+               .map_or(false, |p| !p.is_set(ArgSettings::Last)) {
+            self.settings.set(AS::LowIndexMultiplePositional);
+        }
+        let has_args = self.has_args();
 
         // Next we create the `--help` and `--version` arguments and add them if
         // necessary
         self.create_help_and_version();
 
         let mut subcmd_name: Option<String> = None;
-        let mut needs_val_of: Option<&'a str> = None;
+        let mut needs_val_of: ParseResult<'a> = ParseResult::NotFound;
         let mut pos_counter = 1;
         while let Some(arg) = it.next() {
             let arg_os = arg.into();
-            debugln!("Parser::get_matches_with: Begin parsing '{:?}' ({:?})", arg_os, &*arg_os.as_bytes());
+            debugln!("Parser::get_matches_with: Begin parsing '{:?}' ({:?})",
+                     arg_os,
+                     &*arg_os.as_bytes());
 
-            self.valid_neg_num = false;
+            self.unset(AS::ValidNegNumFound);
             // Is this a new argument, or values from a previous option?
             let starts_new_arg = self.is_new_arg(&arg_os, needs_val_of);
+            if arg_os.starts_with(b"--") && arg_os.len_() == 2 && starts_new_arg {
+                debugln!("Parser::get_matches_with: setting TrailingVals=true");
+                self.set(AS::TrailingValues);
+                continue;
+            }
 
             // Has the user already passed '--'? Meaning only positional args follow
-            if !self.trailing_vals {
+            if !self.is_set(AS::TrailingValues) {
                 // Does the arg match a subcommand name, or any of it's aliases (if defined)
-                if self.possible_subcommand(&arg_os) {
-                    if &*arg_os == "help" && self.is_set(AppSettings::NeedsSubcommandHelp) {
-                        try!(self.parse_help_subcommand(it));
+                {
+                    let (is_match, sc_name) = self.possible_subcommand(&arg_os);
+                    debugln!("Parser::get_matches_with: possible_sc={:?}, sc={:?}",
+                             is_match,
+                             sc_name);
+                    if is_match {
+                        let sc_name = sc_name.expect(INTERNAL_ERROR_MSG);
+                        if sc_name == "help" && self.is_set(AS::NeedsSubcommandHelp) {
+                            try!(self.parse_help_subcommand(it));
+                        }
+                        subcmd_name = Some(sc_name.to_owned());
+                        break;
                     }
-                    subcmd_name = Some(arg_os.to_str().expect(INVALID_UTF8).to_owned());
-                    break;
                 }
 
                 if !starts_new_arg {
-                    if let Some(name) = needs_val_of {
-                        // Check to see if parsing a value from a previous arg
-                        if let Some(arg) = find_by_name!(self, &name, opts, iter) {
-                        // get the OptBuilder so we can check the settings
-                            needs_val_of = try!(self.add_val_to_arg(&*arg, &arg_os, matcher));
+                    match needs_val_of {
+                        ParseResult::Opt(name) => {
+                            // Check to see if parsing a value from a previous arg
+                            let arg = self.opts
+                                .iter()
+                                .find(|o| o.b.name == name)
+                                .expect(INTERNAL_ERROR_MSG);
+                            // get the OptBuilder so we can check the settings
+                            needs_val_of = try!(self.add_val_to_arg(arg, &arg_os, matcher));
                             // get the next value from the iterator
                             continue;
                         }
+                        _ => (),
                     }
                 } else {
                     if arg_os.starts_with(b"--") {
-                        if arg_os.len_() == 2 {
-                            // The user has passed '--' which means only positional args follow no
-                            // matter what they start with
-                            self.trailing_vals = true;
-                            continue;
-                        }
-
                         needs_val_of = try!(self.parse_long_arg(matcher, &arg_os));
-                        if !(needs_val_of.is_none() && self.is_set(AppSettings::AllowLeadingHyphen)) {
-                            continue;
+                        debugln!("Parser:get_matches_with: After parse_long_arg {:?}",
+                                 needs_val_of);
+                        match needs_val_of {
+                            ParseResult::Flag |
+                            ParseResult::Opt(..) |
+                            ParseResult::ValuesDone => continue,
+                            _ => (),
                         }
                     } else if arg_os.starts_with(b"-") && arg_os.len_() != 1 {
                         // Try to parse short args like normal, if AllowLeadingHyphen or
                         // AllowNegativeNumbers is set, parse_short_arg will *not* throw
                         // an error, and instead return Ok(None)
                         needs_val_of = try!(self.parse_short_arg(matcher, &arg_os));
                         // If it's None, we then check if one of those two AppSettings was set
-                        if needs_val_of.is_none() {
-                            if self.is_set(AppSettings::AllowNegativeNumbers) {
+                        debugln!("Parser:get_matches_with: After parse_short_arg {:?}",
+                                 needs_val_of);
+                        match needs_val_of {
+                            ParseResult::MaybeNegNum => {
                                 if !(arg_os.to_string_lossy().parse::<i64>().is_ok() ||
-                                    arg_os.to_string_lossy().parse::<f64>().is_ok()) {
+                                     arg_os.to_string_lossy().parse::<f64>().is_ok()) {
                                     return Err(Error::unknown_argument(&*arg_os.to_string_lossy(),
-                                                                "",
-                                                                &*self.create_current_usage(matcher, None),
-                                                                self.color()));
+                                        "",
+                                        &*usage::create_error_usage(self, matcher, None),
+                                        self.color()));
                                 }
-                            } else if !self.is_set(AppSettings::AllowLeadingHyphen) {
-                                continue;
                             }
-                        } else {
-                            continue;
+                            ParseResult::Opt(..) |
+                            ParseResult::Flag |
+                            ParseResult::ValuesDone => continue,
+                            _ => (),
                         }
                     }
                 }
 
-                if !self.is_set(AppSettings::ArgsNegateSubcommands) {
-                    if let Some(cdate) =
-                    suggestions::did_you_mean(&*arg_os.to_string_lossy(),
-                                              self.subcommands
-                                                  .iter()
-                                                  .map(|s| &s.p.meta.name)) {
-                        return Err(Error::invalid_subcommand(arg_os.to_string_lossy().into_owned(),
-                                                            cdate,
-                                                            self.meta
-                                                                .bin_name
-                                                                .as_ref()
-                                                                .unwrap_or(&self.meta.name),
-                                                            &*self.create_current_usage(matcher, None),
-                                                            self.color()));
+                if !(self.is_set(AS::ArgsNegateSubcommands) && self.is_set(AS::ValidArgFound)) &&
+                   !self.is_set(AS::InferSubcommands) {
+                    if let Some(cdate) = suggestions::did_you_mean(&*arg_os.to_string_lossy(),
+                                                                   sc_names!(self)) {
+                        return Err(Error::invalid_subcommand(arg_os
+                                                                 .to_string_lossy()
+                                                                 .into_owned(),
+                                                             cdate,
+                                                             self.meta
+                                                                 .bin_name
+                                                                 .as_ref()
+                                                                 .unwrap_or(&self.meta.name),
+                                                             &*usage::create_error_usage(self,
+                                                                                         matcher,
+                                                                                         None),
+                                                             self.color()));
                     }
                 }
             }
 
-            let low_index_mults = self.is_set(AppSettings::LowIndexMultiplePositional) &&
-                                  !self.positionals.is_empty() &&
+            let low_index_mults = self.is_set(AS::LowIndexMultiplePositional) &&
                                   pos_counter == (self.positionals.len() - 1);
-            let missing_pos = self.is_set(AppSettings::AllowMissingPositional) &&
-                                  !self.positionals.is_empty() &&
-                                  pos_counter == (self.positionals.len() - 1);
-            debugln!("Parser::get_matches_with: Low index multiples...{:?}", low_index_mults);
-            debugln!("Parser::get_matches_with: Positional counter...{}", pos_counter);
+            let missing_pos = self.is_set(AS::AllowMissingPositional) &&
+                              pos_counter == (self.positionals.len() - 1);
+            debugln!("Parser::get_matches_with: Positional counter...{}",
+                     pos_counter);
+            debugln!("Parser::get_matches_with: Low index multiples...{:?}",
+                     low_index_mults);
             if low_index_mults || missing_pos {
                 if let Some(na) = it.peek() {
                     let n = (*na).clone().into();
-                    needs_val_of = if needs_val_of.is_none() {
+                    needs_val_of = if needs_val_of != ParseResult::ValuesDone {
                         if let Some(p) = self.positionals.get(pos_counter) {
-                            Some(p.b.name)
+                            ParseResult::Pos(p.b.name)
                         } else {
-                            None
+                            ParseResult::ValuesDone
                         }
                     } else {
-                        None
+                        ParseResult::ValuesDone
                     };
-                    if self.is_new_arg(&n, needs_val_of) || self.possible_subcommand(&n) ||
-                       suggestions::did_you_mean(&n.to_string_lossy(),
-                                                 self.subcommands
-                                                     .iter()
-                                                     .map(|s| &s.p.meta.name))
-                        .is_some() {
+                    let sc_match = {
+                        self.possible_subcommand(&n).0
+                    };
+                    if self.is_new_arg(&n, needs_val_of) || sc_match ||
+                       suggestions::did_you_mean(&n.to_string_lossy(), sc_names!(self)).is_some() {
                         debugln!("Parser::get_matches_with: Bumping the positional counter...");
                         pos_counter += 1;
                     }
                 } else {
                     debugln!("Parser::get_matches_with: Bumping the positional counter...");
                     pos_counter += 1;
                 }
+            } else if self.is_set(AS::ContainsLast) && self.is_set(AS::TrailingValues) {
+                // Came to -- and one postional has .last(true) set, so we go immediately
+                // to the last (highest index) positional
+                debugln!("Parser::get_matches_with: .last(true) and --, setting last pos");
+                pos_counter = self.positionals.len();
             }
             if let Some(p) = self.positionals.get(pos_counter) {
+                if p.is_set(ArgSettings::Last) && !self.is_set(AS::TrailingValues) {
+                    return Err(Error::unknown_argument(&*arg_os.to_string_lossy(),
+                                                       "",
+                                                       &*usage::create_error_usage(self,
+                                                                                   matcher,
+                                                                                   None),
+                                                       self.color()));
+                }
                 parse_positional!(self, p, arg_os, pos_counter, matcher);
-                self.valid_arg = true;
-            } else if self.settings.is_set(AppSettings::AllowExternalSubcommands) {
+                self.settings.set(AS::ValidArgFound);
+            } else if self.is_set(AS::AllowExternalSubcommands) {
                 // Get external subcommand name
                 let sc_name = match arg_os.to_str() {
                     Some(s) => s.to_string(),
                     None => {
-                        if !self.settings.is_set(AppSettings::StrictUtf8) {
-                            return Err(Error::invalid_utf8(&*self.create_current_usage(matcher, None),
+                        if !self.is_set(AS::StrictUtf8) {
+                            return Err(Error::invalid_utf8(&*usage::create_error_usage(self,
+                                                                                       matcher,
+                                                                                       None),
                                                            self.color()));
                         }
                         arg_os.to_string_lossy().into_owned()
                     }
                 };
 
                 // Collect the external subcommand args
                 let mut sc_m = ArgMatcher::new();
                 while let Some(v) = it.next() {
                     let a = v.into();
-                    if a.to_str().is_none() && !self.settings.is_set(AppSettings::StrictUtf8) {
-                        return Err(Error::invalid_utf8(&*self.create_current_usage(matcher, None),
+                    if a.to_str().is_none() && !self.is_set(AS::StrictUtf8) {
+                        return Err(Error::invalid_utf8(&*usage::create_error_usage(self,
+                                                                                   matcher,
+                                                                                   None),
                                                        self.color()));
                     }
                     sc_m.add_val_to("", &a);
                 }
 
                 matcher.subcommand(SubCommand {
-                    name: sc_name,
-                    matches: sc_m.into(),
-                });
-            } else if !(self.is_set(AppSettings::AllowLeadingHyphen) ||
-                        self.is_set(AppSettings::AllowNegativeNumbers)) {
+                                       name: sc_name,
+                                       matches: sc_m.into(),
+                                   });
+            } else if !(self.is_set(AS::AllowLeadingHyphen) ||
+                        self.is_set(AS::AllowNegativeNumbers)) &&
+                      !self.is_set(AS::InferSubcommands) {
                 return Err(Error::unknown_argument(&*arg_os.to_string_lossy(),
                                                    "",
-                                                   &*self.create_current_usage(matcher, None),
+                                                   &*usage::create_error_usage(self,
+                                                                               matcher,
+                                                                               None),
                                                    self.color()));
+            } else if !has_args || self.is_set(AS::InferSubcommands) && self.has_subcommands() {
+                if let Some(cdate) = suggestions::did_you_mean(&*arg_os.to_string_lossy(),
+                                                               sc_names!(self)) {
+                    return Err(Error::invalid_subcommand(arg_os.to_string_lossy().into_owned(),
+                                                         cdate,
+                                                         self.meta
+                                                             .bin_name
+                                                             .as_ref()
+                                                             .unwrap_or(&self.meta.name),
+                                                         &*usage::create_error_usage(self,
+                                                                                     matcher,
+                                                                                     None),
+                                                         self.color()));
+                } else {
+                    return Err(Error::unrecognized_subcommand(arg_os
+                                                                  .to_string_lossy()
+                                                                  .into_owned(),
+                                                              self.meta
+                                                                  .bin_name
+                                                                  .as_ref()
+                                                                  .unwrap_or(&self.meta.name),
+                                                              self.color()));
+                }
             }
         }
 
         if let Some(ref pos_sc_name) = subcmd_name {
-            // is this is a real subcommand, or an alias
-            if self.subcommands.iter().any(|sc| &sc.p.meta.name == pos_sc_name) {
-                try!(self.parse_subcommand(&*pos_sc_name, matcher, it));
-            } else {
-                let sc_name = &*self.subcommands
-                    .iter()
-                    .filter(|sc| sc.p.meta.aliases.is_some())
-                    .filter(|sc| {
-                        sc.p
-                            .meta
-                            .aliases
-                            .as_ref()
-                            .expect(INTERNAL_ERROR_MSG)
-                            .iter()
-                            .any(|&(a, _)| &a == &&*pos_sc_name)
-                    })
-                    .map(|sc| sc.p.meta.name.clone())
-                    .next()
-                    .expect(INTERNAL_ERROR_MSG);
-                try!(self.parse_subcommand(sc_name, matcher, it));
-            }
-        } else if self.is_set(AppSettings::SubcommandRequired) {
+            let sc_name = {
+                find_subcmd!(self, pos_sc_name)
+                    .expect(INTERNAL_ERROR_MSG)
+                    .p
+                    .meta
+                    .name
+                    .clone()
+            };
+            try!(self.parse_subcommand(&*sc_name, matcher, it));
+        } else if self.is_set(AS::SubcommandRequired) {
             let bn = self.meta.bin_name.as_ref().unwrap_or(&self.meta.name);
             return Err(Error::missing_subcommand(bn,
-                                                 &self.create_current_usage(matcher, None),
+                                                 &usage::create_error_usage(self, matcher, None),
                                                  self.color()));
-        } else if self.is_set(AppSettings::SubcommandRequiredElseHelp) {
-            debugln!("parser::get_matches_with: SubcommandRequiredElseHelp=true");
+        } else if self.is_set(AS::SubcommandRequiredElseHelp) {
+            debugln!("Parser::get_matches_with: SubcommandRequiredElseHelp=true");
             let mut out = vec![];
             try!(self.write_help_err(&mut out));
             return Err(Error {
-                message: String::from_utf8_lossy(&*out).into_owned(),
-                kind: ErrorKind::MissingArgumentOrSubcommand,
-                info: None,
-            });
+                           message: String::from_utf8_lossy(&*out).into_owned(),
+                           kind: ErrorKind::MissingArgumentOrSubcommand,
+                           info: None,
+                       });
         }
 
-        self.validate(needs_val_of, subcmd_name, matcher)
+        Validator::new(self).validate(needs_val_of, subcmd_name, matcher)
     }
 
-    fn validate(&mut self,
-                needs_val_of: Option<&'a str>,
-                subcmd_name: Option<String>,
-                matcher: &mut ArgMatcher<'a>)
-                -> ClapResult<()> {
-        debugln!("Parser::validate;");
-        let mut reqs_validated = false;
-        try!(self.add_defaults(matcher));
-        if let Some(a) = needs_val_of {
-            debugln!("Parser::validate: needs_val_of={:?}", a);
-            if let Some(o) = find_by_name!(self, &a, opts, iter) {
-                try!(self.validate_required(matcher));
-                reqs_validated = true;
-                let should_err = if let Some(v) = matcher.0.args.get(&*o.b.name) {
-                    v.vals.is_empty() && !(o.v.min_vals.is_some() && o.v.min_vals.unwrap() == 0)
-                } else {
-                    true
-                };
-                if should_err {
-                    return Err(Error::empty_value(o,
-                                                &*self.create_current_usage(matcher, None),
-                                                self.color()));
-                }
-            }
-        }
-
-        try!(self.validate_blacklist(matcher));
-        if !(self.settings.is_set(AppSettings::SubcommandsNegateReqs) && subcmd_name.is_some()) &&
-           !reqs_validated {
-            try!(self.validate_required(matcher));
-        }
-        try!(self.validate_matched_args(matcher));
-        matcher.usage(self.create_usage(&[]));
-
-        if matcher.is_empty() && matcher.subcommand_name().is_none() &&
-           self.is_set(AppSettings::ArgRequiredElseHelp) {
-            let mut out = vec![];
-            try!(self.write_help_err(&mut out));
-            return Err(Error {
-                message: String::from_utf8_lossy(&*out).into_owned(),
-                kind: ErrorKind::MissingArgumentOrSubcommand,
-                info: None,
-            });
-        }
-        Ok(())
-    }
 
     fn propogate_help_version(&mut self) {
         debugln!("Parser::propogate_help_version;");
         self.create_help_and_version();
         for sc in &mut self.subcommands {
             sc.p.propogate_help_version();
         }
     }
 
     fn build_bin_names(&mut self) {
         debugln!("Parser::build_bin_names;");
         for sc in &mut self.subcommands {
             debug!("Parser::build_bin_names:iter: bin_name set...");
             if sc.p.meta.bin_name.is_none() {
                 sdebugln!("No");
                 let bin_name = format!("{}{}{}",
-                                      self.meta
-                                          .bin_name
-                                          .as_ref()
-                                          .unwrap_or(&self.meta.name.clone()),
-                                      if self.meta.bin_name.is_some() {
-                                          " "
-                                      } else {
-                                          ""
-                                      },
-                                      &*sc.p.meta.name);
-                debugln!("Parser::build_bin_names:iter: Setting bin_name of {} to {}", self.meta.name, bin_name);
+                                       self.meta
+                                           .bin_name
+                                           .as_ref()
+                                           .unwrap_or(&self.meta.name.clone()),
+                                       if self.meta.bin_name.is_some() {
+                                           " "
+                                       } else {
+                                           ""
+                                       },
+                                       &*sc.p.meta.name);
+                debugln!("Parser::build_bin_names:iter: Setting bin_name of {} to {}",
+                         self.meta.name,
+                         bin_name);
                 sc.p.meta.bin_name = Some(bin_name);
             } else {
                 sdebugln!("yes ({:?})", sc.p.meta.bin_name);
             }
-            debugln!("Parser::build_bin_names:iter: Calling build_bin_names from...{}", sc.p.meta.name);
+            debugln!("Parser::build_bin_names:iter: Calling build_bin_names from...{}",
+                     sc.p.meta.name);
             sc.p.build_bin_names();
         }
     }
 
     fn parse_subcommand<I, T>(&mut self,
                               sc_name: &str,
                               matcher: &mut ArgMatcher<'a>,
                               it: &mut Peekable<I>)
                               -> ClapResult<()>
         where I: Iterator<Item = T>,
               T: Into<OsString> + Clone
     {
         use std::fmt::Write;
         debugln!("Parser::parse_subcommand;");
         let mut mid_string = String::new();
-        if !self.settings.is_set(AppSettings::SubcommandsNegateReqs) {
+        if !self.is_set(AS::SubcommandsNegateReqs) {
             let mut hs: Vec<&str> = self.required.iter().map(|n| &**n).collect();
             for k in matcher.arg_names() {
                 hs.push(k);
             }
-            let reqs = self.get_required_from(&hs, Some(matcher), None);
+            let reqs = usage::get_required_usage_from(self, &hs, Some(matcher), None, false);
 
             for s in &reqs {
                 write!(&mut mid_string, " {}", s).expect(INTERNAL_ERROR_MSG);
             }
         }
         mid_string.push_str(" ");
         if let Some(ref mut sc) = self.subcommands
-            .iter_mut()
-            .find(|s| &s.p.meta.name == &sc_name) {
+               .iter_mut()
+               .find(|s| &s.p.meta.name == &sc_name) {
             let mut sc_matcher = ArgMatcher::new();
             // bin_name should be parent's bin_name + [<reqs>] + the sc's name separated by
             // a space
             sc.p.meta.usage = Some(format!("{}{}{}",
                                            self.meta.bin_name.as_ref().unwrap_or(&String::new()),
                                            if self.meta.bin_name.is_some() {
                                                &*mid_string
                                            } else {
                                                ""
                                            },
                                            &*sc.p.meta.name));
-            sc.p.meta.bin_name = Some(format!("{}{}{}",
-                                              self.meta
-                                                  .bin_name
-                                                  .as_ref()
-                                                  .unwrap_or(&String::new()),
-                                              if self.meta.bin_name.is_some() {
-                                                  " "
-                                              } else {
-                                                  ""
-                                              },
-                                              &*sc.p.meta.name));
-            debugln!("Parser::parse_subcommand: About to parse sc={}", sc.p.meta.name);
+            sc.p.meta.bin_name =
+                Some(format!("{}{}{}",
+                             self.meta.bin_name.as_ref().unwrap_or(&String::new()),
+                             if self.meta.bin_name.is_some() {
+                                 " "
+                             } else {
+                                 ""
+                             },
+                             &*sc.p.meta.name));
+            debugln!("Parser::parse_subcommand: About to parse sc={}",
+                     sc.p.meta.name);
             debugln!("Parser::parse_subcommand: sc settings={:#?}", sc.p.settings);
             try!(sc.p.get_matches_with(&mut sc_matcher, it));
             matcher.subcommand(SubCommand {
-                name: sc.p.meta.name.clone(),
-                matches: sc_matcher.into(),
-            });
+                                   name: sc.p.meta.name.clone(),
+                                   matches: sc_matcher.into(),
+                               });
         }
         Ok(())
     }
 
-
-    fn groups_for_arg(&self, name: &str) -> Option<Vec<&'a str>> {
+    pub fn groups_for_arg(&self, name: &str) -> Option<Vec<&'a str>> {
         debugln!("Parser::groups_for_arg: name={}", name);
 
         if self.groups.is_empty() {
             debugln!("Parser::groups_for_arg: No groups defined");
             return None;
         }
         let mut res = vec![];
         debugln!("Parser::groups_for_arg: Searching through groups...");
-        for (gn, grp) in &self.groups {
+        for grp in &self.groups {
             for a in &grp.args {
                 if a == &name {
-                    sdebugln!("\tFound '{}'", gn);
-                    res.push(*gn);
+                    sdebugln!("\tFound '{}'", grp.name);
+                    res.push(&*grp.name);
                 }
             }
         }
         if res.is_empty() {
             return None;
         }
 
         Some(res)
     }
 
-    fn args_in_group(&self, group: &str) -> Vec<String> {
+    pub fn args_in_group(&self, group: &str) -> Vec<String> {
         let mut g_vec = vec![];
         let mut args = vec![];
 
-        for n in &self.groups[group].args {
+        for n in &self.groups
+                      .iter()
+                      .find(|g| g.name == group)
+                      .expect(INTERNAL_ERROR_MSG)
+                      .args {
             if let Some(f) = self.flags.iter().find(|f| &f.b.name == n) {
                 args.push(f.to_string());
             } else if let Some(f) = self.opts.iter().find(|o| &o.b.name == n) {
                 args.push(f.to_string());
-            } else if self.groups.contains_key(&**n) {
+            } else if let Some(p) = self.positionals.values().find(|p| &p.b.name == n) {
+                args.push(p.b.name.to_owned());
+            } else {
                 g_vec.push(*n);
-            } else if let Some(p) = self.positionals
-                .values()
-                .find(|p| &p.b.name == n) {
-                args.push(p.b.name.to_owned());
             }
         }
 
         for av in g_vec.iter().map(|g| self.args_in_group(g)) {
             args.extend(av);
         }
         args.dedup();
         args.iter().map(ToOwned::to_owned).collect()
     }
 
-    fn arg_names_in_group(&self, group: &str) -> Vec<&'a str> {
+    pub fn arg_names_in_group(&self, group: &str) -> Vec<&'a str> {
         let mut g_vec = vec![];
         let mut args = vec![];
 
-        for n in &self.groups[group].args {
-            if self.groups.contains_key(&*n) {
+        for n in &self.groups
+                      .iter()
+                      .find(|g| g.name == group)
+                      .expect(INTERNAL_ERROR_MSG)
+                      .args {
+            if self.groups.iter().any(|g| &g.name == &*n) {
+                args.extend(self.arg_names_in_group(n));
                 g_vec.push(*n);
             } else {
-                args.push(*n);
+                if !args.contains(n) {
+                    args.push(*n);
+                }
             }
         }
 
-        for av in g_vec.iter().map(|g| self.arg_names_in_group(g)) {
-            args.extend(av);
-        }
-        args.dedup();
         args.iter().map(|s| *s).collect()
     }
 
     pub fn create_help_and_version(&mut self) {
         debugln!("Parser::create_help_and_version;");
         // name is "hclap_help" because flags are sorted by name
-        if self.is_set(AppSettings::NeedsLongHelp) {
+        if !self.contains_long("help") {
             debugln!("Parser::create_help_and_version: Building --help");
-            if self.help_short.is_none() && !self.short_list.contains(&'h') {
+            if self.help_short.is_none() && !self.contains_short('h') {
                 self.help_short = Some('h');
             }
-            let id = self.flags.len();
             let arg = FlagBuilder {
                 b: Base {
                     name: "hclap_help",
-                    help: Some("Prints help information"),
-                    id: id,
+                    help: self.help_message.or(Some("Prints help information")),
                     ..Default::default()
                 },
                 s: Switched {
                     short: self.help_short,
                     long: Some("help"),
                     ..Default::default()
                 },
             };
-            if let Some(h) = self.help_short {
-                self.short_list.push(h);
-            }
-            self.long_list.push("help");
-            self.flags.insert(id, arg);
+            self.flags.push(arg);
         }
-        if !self.settings.is_set(AppSettings::DisableVersion) &&
-           self.is_set(AppSettings::NeedsLongVersion) {
+        if !self.is_set(AS::DisableVersion) && !self.contains_long("version") {
             debugln!("Parser::create_help_and_version: Building --version");
-            if self.version_short.is_none() && !self.short_list.contains(&'V') {
+            if self.version_short.is_none() && !self.contains_short('V') {
                 self.version_short = Some('V');
             }
-            let id = self.flags.len();
             // name is "vclap_version" because flags are sorted by name
             let arg = FlagBuilder {
                 b: Base {
                     name: "vclap_version",
-                    help: Some("Prints version information"),
-                    id: id,
+                    help: self.version_message.or(Some("Prints version information")),
                     ..Default::default()
                 },
                 s: Switched {
                     short: self.version_short,
                     long: Some("version"),
                     ..Default::default()
                 },
             };
-            if let Some(v) = self.version_short {
-                self.short_list.push(v);
-            }
-            self.long_list.push("version");
-            self.flags.insert(id, arg);
+            self.flags.push(arg);
         }
-        if !self.subcommands.is_empty() && !self.is_set(AppSettings::DisableHelpSubcommand) &&
-           self.is_set(AppSettings::NeedsSubcommandHelp) {
+        if !self.subcommands.is_empty() && !self.is_set(AS::DisableHelpSubcommand) &&
+           self.is_set(AS::NeedsSubcommandHelp) {
             debugln!("Parser::create_help_and_version: Building help");
             self.subcommands
                 .push(App::new("help")
-                    .about("Prints this message or the help of the given subcommand(s)"));
+                          .about("Prints this message or the help of the given subcommand(s)"));
         }
     }
 
     // Retrieves the names of all args the user has supplied thus far, except required ones
     // because those will be listed in self.required
-    pub fn create_current_usage(&self, matcher: &'b ArgMatcher<'a>, extra: Option<&str>) -> String {
-        let mut args: Vec<_> = matcher.arg_names()
-            .iter()
-            .filter(|n| {
-                if let Some(o) = find_by_name!(self, *n, opts, iter) {
-                    !o.b.settings.is_set(ArgSettings::Required)
-                } else if let Some(p) = find_by_name!(self, *n, positionals, values) {
-                    !p.b.settings.is_set(ArgSettings::Required)
-                } else {
-                    true // flags can't be required, so they're always true
-                }
-            })
-            .map(|&n| n)
-            .collect();
-        if let Some(r) = extra {
-            args.push(r);
-        }
-        self.create_usage(&*args)
-    }
-
     fn check_for_help_and_version_str(&self, arg: &OsStr) -> ClapResult<()> {
         debugln!("Parser::check_for_help_and_version_str;");
         debug!("Parser::check_for_help_and_version_str: Checking if --{} is help or version...",
                arg.to_str().unwrap());
-        if arg == "help" && self.settings.is_set(AppSettings::NeedsLongHelp) {
+        if arg == "help" && self.is_set(AS::NeedsLongHelp) {
             sdebugln!("Help");
-            try!(self._help());
+            return Err(self._help(true));
         }
-        if arg == "version" && self.settings.is_set(AppSettings::NeedsLongVersion) {
+        if arg == "version" && self.is_set(AS::NeedsLongVersion) {
             sdebugln!("Version");
-            try!(self._version());
+            return Err(self._version(true));
         }
         sdebugln!("Neither");
 
         Ok(())
     }
 
     fn check_for_help_and_version_char(&self, arg: char) -> ClapResult<()> {
         debugln!("Parser::check_for_help_and_version_char;");
-        debug!("Parser::check_for_help_and_version_char: Checking if -{} is help or version...", arg);
+        debug!("Parser::check_for_help_and_version_char: Checking if -{} is help or version...",
+               arg);
         if let Some(h) = self.help_short {
-            if arg == h && self.settings.is_set(AppSettings::NeedsLongHelp) {
+            if arg == h && self.is_set(AS::NeedsLongHelp) {
                 sdebugln!("Help");
-                try!(self._help());
+                return Err(self._help(false));
             }
         }
         if let Some(v) = self.version_short {
-            if arg == v && self.settings.is_set(AppSettings::NeedsLongVersion) {
+            if arg == v && self.is_set(AS::NeedsLongVersion) {
                 sdebugln!("Version");
-                try!(self._version());
+                return Err(self._version(false));
             }
         }
         sdebugln!("Neither");
         Ok(())
     }
 
-    fn _help(&self) -> ClapResult<()> {
+    fn use_long_help(&self) -> bool {
+        let ul = self.flags.iter().any(|f| f.b.long_help.is_some()) ||
+                 self.opts.iter().any(|o| o.b.long_help.is_some()) ||
+                 self.positionals.values().any(|p| p.b.long_help.is_some()) ||
+                 self.subcommands
+                     .iter()
+                     .any(|s| s.p.meta.long_about.is_some());
+        debugln!("Parser::use_long_help: ret={:?}", ul);
+        ul
+    }
+
+    fn _help(&self, mut use_long: bool) -> Error {
+        debugln!("Parser::_help: use_long={:?}", use_long);
+        use_long = use_long && self.use_long_help();
         let mut buf = vec![];
-        try!(Help::write_parser_help(&mut buf, self));
-        Err(Error {
+        match Help::write_parser_help(&mut buf, self, use_long) {
+            Err(e) => return e,
+            _ => (),
+        }
+        Error {
             message: unsafe { String::from_utf8_unchecked(buf) },
             kind: ErrorKind::HelpDisplayed,
             info: None,
-        })
+        }
     }
 
-    fn _version(&self) -> ClapResult<()> {
+    fn _version(&self, use_long: bool) -> Error {
+        debugln!("Parser::_version: ");
         let out = io::stdout();
         let mut buf_w = BufWriter::new(out.lock());
-        try!(self.print_version(&mut buf_w));
-        Err(Error {
+        match self.print_version(&mut buf_w, use_long) {
+            Err(e) => return e,
+            _ => (),
+        }
+        Error {
             message: String::new(),
             kind: ErrorKind::VersionDisplayed,
             info: None,
-        })
+        }
     }
 
     fn parse_long_arg(&mut self,
                       matcher: &mut ArgMatcher<'a>,
                       full_arg: &OsStr)
-                      -> ClapResult<Option<&'a str>> {
+                      -> ClapResult<ParseResult<'a>> {
         // maybe here lifetime should be 'a
         debugln!("Parser::parse_long_arg;");
         let mut val = None;
         debug!("Parser::parse_long_arg: Does it contain '='...");
         let arg = if full_arg.contains_byte(b'=') {
             let (p0, p1) = full_arg.trim_left_matches(b'-').split_at_byte(b'=');
             sdebugln!("Yes '{:?}'", p1);
             val = Some(p1);
             p0
         } else {
             sdebugln!("No");
             full_arg.trim_left_matches(b'-')
         };
 
-        if let Some(opt) = find_by_long!(self, &arg, opts) {
-            debugln!("Parser::parse_long_arg: Found valid opt '{}'", opt.to_string());
-            self.valid_arg = true;
-            let ret = try!(self.parse_opt(val, opt, matcher));
-            arg_post_processing!(self, opt, matcher);
+        if let Some(opt) = find_opt_by_long!(@os self, &arg) {
+            debugln!("Parser::parse_long_arg: Found valid opt '{}'",
+                     opt.to_string());
+            self.settings.set(AS::ValidArgFound);
+            let ret = try!(self.parse_opt(val, opt, val.is_some(), matcher));
+            if self.cache.map_or(true, |name| name != opt.b.name) {
+                arg_post_processing!(self, opt, matcher);
+                self.cache = Some(opt.b.name);
+            }
 
             return Ok(ret);
-        } else if let Some(flag) = find_by_long!(self, &arg, flags) {
-            debugln!("Parser::parse_long_arg: Found valid flag '{}'", flag.to_string());
-            self.valid_arg = true;
+        } else if let Some(flag) = find_flag_by_long!(@os self, &arg) {
+            debugln!("Parser::parse_long_arg: Found valid flag '{}'",
+                     flag.to_string());
+            self.settings.set(AS::ValidArgFound);
             // Only flags could be help or version, and we need to check the raw long
             // so this is the first point to check
             try!(self.check_for_help_and_version_str(arg));
 
             try!(self.parse_flag(flag, matcher));
 
             // Handle conflicts, requirements, etc.
+            // if self.cache.map_or(true, |name| name != flag.b.name) {
             arg_post_processing!(self, flag, matcher);
+            // self.cache = Some(flag.b.name);
+            // }
 
-            return Ok(None);
-        } else if self.is_set(AppSettings::AllowLeadingHyphen) {
-            return Ok(None);
-        } else if self.valid_neg_num {
-            return Ok(None);
+            return Ok(ParseResult::Flag);
+        } else if self.is_set(AS::AllowLeadingHyphen) {
+            return Ok(ParseResult::MaybeHyphenValue);
+        } else if self.is_set(AS::ValidNegNumFound) {
+            return Ok(ParseResult::MaybeNegNum);
         }
 
         debugln!("Parser::parse_long_arg: Didn't match anything");
-        self.did_you_mean_error(arg.to_str().expect(INVALID_UTF8), matcher).map(|_| None)
+        self.did_you_mean_error(arg.to_str().expect(INVALID_UTF8), matcher)
+            .map(|_| ParseResult::NotFound)
     }
 
+    #[cfg_attr(feature = "lints", allow(len_zero))]
     fn parse_short_arg(&mut self,
                        matcher: &mut ArgMatcher<'a>,
                        full_arg: &OsStr)
-                       -> ClapResult<Option<&'a str>> {
-        debugln!("Parser::parse_short_arg;");
-        // let mut utf8 = true;
+                       -> ClapResult<ParseResult<'a>> {
+        debugln!("Parser::parse_short_arg: full_arg={:?}", full_arg);
         let arg_os = full_arg.trim_left_matches(b'-');
         let arg = arg_os.to_string_lossy();
 
-        // If AllowLeadingHyphen is set, we want to ensure `-val` gets parsed as `-val` and not `-v` `-a` `-l` assuming
-        // `v` `a` and `l` are all, or mostly, valid shorts.
-        if self.is_set(AppSettings::AllowLeadingHyphen) {
-            let mut good = true;
-            for c in arg.chars() {
-                good = self.short_list.contains(&c);
+        // If AllowLeadingHyphen is set, we want to ensure `-val` gets parsed as `-val` and not
+        // `-v` `-a` `-l` assuming `v` `a` and `l` are all, or mostly, valid shorts.
+        if self.is_set(AS::AllowLeadingHyphen) {
+            if arg.chars().any(|c| !self.contains_short(c)) {
+                debugln!("Parser::parse_short_arg: LeadingHyphenAllowed yet -{} isn't valid",
+                         arg);
+                return Ok(ParseResult::MaybeHyphenValue);
             }
-            if !good {
-                return Ok(None);
-            }
-        } else if self.valid_neg_num {
+        } else if self.is_set(AS::ValidNegNumFound) {
             // TODO: Add docs about having AllowNegativeNumbers and `-2` as a valid short
             // May be better to move this to *after* not finding a valid flag/opt?
             debugln!("Parser::parse_short_arg: Valid negative num...");
-            return Ok(None);
+            return Ok(ParseResult::MaybeNegNum);
         }
 
+        let mut ret = ParseResult::NotFound;
         for c in arg.chars() {
-            debugln!("Parser::parse_short_arg:iter: short={}", c);
+            debugln!("Parser::parse_short_arg:iter:{}", c);
             // Check for matching short options, and return the name if there is no trailing
             // concatenated value: -oval
             // Option: -o
             // Value: val
-            if let Some(opt) = self.opts
-                .iter()
-                .find(|&o| o.s.short.is_some() && o.s.short.unwrap() == c) {
-                debugln!("Parser::parse_short_arg:iter: Found valid short opt -{} in '{}'", c, arg);
-                self.valid_arg = true;
+            if let Some(opt) = find_opt_by_short!(self, c) {
+                debugln!("Parser::parse_short_arg:iter:{}: Found valid opt", c);
+                self.settings.set(AS::ValidArgFound);
                 // Check for trailing concatenated value
                 let p: Vec<_> = arg.splitn(2, c).collect();
-                debugln!("Parser::parse_short_arg:iter: arg: {:?}, arg_os: {:?}, full_arg: {:?}",
-                         arg,
-                         arg_os,
-                         full_arg);
-                debugln!("Parser::parse_short_arg:iter: p[0]: {:?}, p[1]: {:?}", p[0].as_bytes(), p[1].as_bytes());
+                debugln!("Parser::parse_short_arg:iter:{}: p[0]={:?}, p[1]={:?}",
+                         c,
+                         p[0].as_bytes(),
+                         p[1].as_bytes());
                 let i = p[0].as_bytes().len() + 1;
                 let val = if p[1].as_bytes().len() > 0 {
-                    debugln!("Parser::parse_short_arg:iter: setting val: {:?} (bytes), {:?} (ascii)",
+                    debugln!("Parser::parse_short_arg:iter:{}: val={:?} (bytes), val={:?} (ascii)",
+                             c,
                              arg_os.split_at(i).1.as_bytes(),
                              arg_os.split_at(i).1);
                     Some(arg_os.split_at(i).1)
                 } else {
                     None
                 };
 
                 // Default to "we're expecting a value later"
-                let ret = try!(self.parse_opt(val, opt, matcher));
+                let ret = try!(self.parse_opt(val, opt, false, matcher));
 
-                arg_post_processing!(self, opt, matcher);
+                if self.cache.map_or(true, |name| name != opt.b.name) {
+                    arg_post_processing!(self, opt, matcher);
+                    self.cache = Some(opt.b.name);
+                }
 
                 return Ok(ret);
-            } else if let Some(flag) = self.flags
-                .iter()
-                .find(|&f| f.s.short.is_some() && f.s.short.unwrap() == c) {
-                debugln!("Parser::parse_short_arg:iter: Found valid short flag -{}", c);
-                self.valid_arg = true;
+            } else if let Some(flag) = find_flag_by_short!(self, c) {
+                debugln!("Parser::parse_short_arg:iter:{}: Found valid flag", c);
+                self.settings.set(AS::ValidArgFound);
                 // Only flags can be help or version
                 try!(self.check_for_help_and_version_char(c));
-                try!(self.parse_flag(flag, matcher));
+                ret = try!(self.parse_flag(flag, matcher));
+
                 // Handle conflicts, requirements, overrides, etc.
                 // Must be called here due to mutablilty
-                arg_post_processing!(self, flag, matcher);
+                if self.cache.map_or(true, |name| name != flag.b.name) {
+                    arg_post_processing!(self, flag, matcher);
+                    self.cache = Some(flag.b.name);
+                }
             } else {
-                let mut arg = String::new();
-                arg.push('-');
-                arg.push(c);
+                let arg = format!("-{}", c);
                 return Err(Error::unknown_argument(&*arg,
                                                    "",
-                                                   &*self.create_current_usage(matcher, None),
+                                                   &*usage::create_error_usage(self,
+                                                                               matcher,
+                                                                               None),
                                                    self.color()));
             }
         }
-        Ok(None)
+        Ok(ret)
     }
 
     fn parse_opt(&self,
                  val: Option<&OsStr>,
                  opt: &OptBuilder<'a, 'b>,
+                 had_eq: bool,
                  matcher: &mut ArgMatcher<'a>)
-                 -> ClapResult<Option<&'a str>> {
-        debugln!("Parser::parse_opt;");
-        validate_multiples!(self, opt, matcher);
+                 -> ClapResult<ParseResult<'a>> {
+        debugln!("Parser::parse_opt; opt={}, val={:?}", opt.b.name, val);
+        debugln!("Parser::parse_opt; opt.settings={:?}", opt.b.settings);
         let mut has_eq = false;
 
-        debug!("Parser::parse_optChecking for val...");
+        debug!("Parser::parse_opt; Checking for val...");
         if let Some(fv) = val {
-            has_eq = fv.starts_with(&[b'=']);
+            has_eq = fv.starts_with(&[b'=']) || had_eq;
             let v = fv.trim_left_matches(b'=');
-            if !opt.is_set(ArgSettings::EmptyValues) && v.len_() == 0 {
+            if !opt.is_set(ArgSettings::EmptyValues) &&
+               (v.len_() == 0 || (opt.is_set(ArgSettings::RequireEquals) && !has_eq)) {
                 sdebugln!("Found Empty - Error");
                 return Err(Error::empty_value(opt,
-                                              &*self.create_current_usage(matcher, None),
+                                              &*usage::create_error_usage(self, matcher, None),
                                               self.color()));
             }
             sdebugln!("Found - {:?}, len: {}", v, v.len_());
-            debugln!("Parser::parse_opt: {:?} contains '='...{:?}", fv, fv.starts_with(&[b'=']));
+            debugln!("Parser::parse_opt: {:?} contains '='...{:?}",
+                     fv,
+                     fv.starts_with(&[b'=']));
             try!(self.add_val_to_arg(opt, v, matcher));
+        } else if opt.is_set(ArgSettings::RequireEquals) && !opt.is_set(ArgSettings::EmptyValues) {
+            sdebugln!("None, but requires equals...Error");
+            return Err(Error::empty_value(opt,
+                                          &*usage::create_error_usage(self, matcher, None),
+                                          self.color()));
+
         } else {
             sdebugln!("None");
         }
 
         matcher.inc_occurrence_of(opt.b.name);
         // Increment or create the group "args"
-        self.groups_for_arg(opt.b.name).and_then(|vec| Some(matcher.inc_occurrences_of(&*vec)));
+        self.groups_for_arg(opt.b.name)
+            .and_then(|vec| Some(matcher.inc_occurrences_of(&*vec)));
 
         if val.is_none() ||
            !has_eq &&
            (opt.is_set(ArgSettings::Multiple) && !opt.is_set(ArgSettings::RequireDelimiter) &&
             matcher.needs_more_vals(opt)) {
             debugln!("Parser::parse_opt: More arg vals required...");
-            return Ok(Some(opt.b.name));
+            return Ok(ParseResult::Opt(opt.b.name));
         }
         debugln!("Parser::parse_opt: More arg vals not required...");
-        Ok(None)
+        Ok(ParseResult::ValuesDone)
     }
 
     fn add_val_to_arg<A>(&self,
                          arg: &A,
                          val: &OsStr,
                          matcher: &mut ArgMatcher<'a>)
-                         -> ClapResult<Option<&'a str>>
+                         -> ClapResult<ParseResult<'a>>
         where A: AnyArg<'a, 'b> + Display
     {
-        debugln!("Parser::add_val_to_arg;");
-        let mut ret = None;
-        if !(self.trailing_vals && self.is_set(AppSettings::DontDelimitTrailingValues)) {
+        debugln!("Parser::add_val_to_arg; arg={}, val={:?}", arg.name(), val);
+        let ret;
+        debugln!("Parser::add_val_to_arg; trailing_vals={:?}, DontDelimTrailingVals={:?}",
+                 self.is_set(AS::TrailingValues),
+                 self.is_set(AS::DontDelimitTrailingValues));
+        if !(self.is_set(AS::TrailingValues) && self.is_set(AS::DontDelimitTrailingValues)) {
             if let Some(delim) = arg.val_delim() {
+                let mut iret = ParseResult::ValuesDone;
                 if val.is_empty_() {
-                    ret = try!(self.add_single_val_to_arg(arg, val, matcher));
+                    iret = try!(self.add_single_val_to_arg(arg, val, matcher));
                 } else {
                     for v in val.split(delim as u32 as u8) {
-                        ret = try!(self.add_single_val_to_arg(arg, v, matcher));
+                        iret = try!(self.add_single_val_to_arg(arg, v, matcher));
                     }
                     // If there was a delimiter used, we're not looking for more values
                     if val.contains_byte(delim as u32 as u8) ||
                        arg.is_set(ArgSettings::RequireDelimiter) {
-                        ret = None;
+                        iret = ParseResult::ValuesDone;
                     }
                 }
+                ret = Ok(iret);
             } else {
-                ret = try!(self.add_single_val_to_arg(arg, val, matcher));
+                ret = self.add_single_val_to_arg(arg, val, matcher);
             }
         } else {
-            ret = try!(self.add_single_val_to_arg(arg, val, matcher));
+            ret = self.add_single_val_to_arg(arg, val, matcher);
         }
-        Ok(ret)
+        ret
     }
 
     fn add_single_val_to_arg<A>(&self,
                                 arg: &A,
                                 v: &OsStr,
                                 matcher: &mut ArgMatcher<'a>)
-                                -> ClapResult<Option<&'a str>>
+                                -> ClapResult<ParseResult<'a>>
         where A: AnyArg<'a, 'b> + Display
     {
         debugln!("Parser::add_single_val_to_arg;");
         debugln!("Parser::add_single_val_to_arg: adding val...{:?}", v);
         if let Some(t) = arg.val_terminator() {
             if t == v {
-                return Ok(None);
+                return Ok(ParseResult::ValuesDone);
             }
         }
         matcher.add_val_to(arg.name(), v);
 
         // Increment or create the group "args"
         if let Some(grps) = self.groups_for_arg(arg.name()) {
             for grp in grps {
                 matcher.add_val_to(&*grp, v);
             }
         }
 
-        // The validation must come AFTER inserting into 'matcher' or the usage string
-        // can't be built
-        self.validate_value(arg, v, matcher)
+        if matcher.needs_more_vals(arg) {
+            return Ok(ParseResult::Opt(arg.name()));
+        }
+        Ok(ParseResult::ValuesDone)
     }
 
-    fn validate_value<A>(&self,
-                         arg: &A,
-                         val: &OsStr,
-                         matcher: &ArgMatcher<'a>)
-                         -> ClapResult<Option<&'a str>>
-        where A: AnyArg<'a, 'b> + Display
-    {
-        debugln!("Parser::validate_value: val={:?}", val);
-        if self.is_set(AppSettings::StrictUtf8) && val.to_str().is_none() {
-            return Err(Error::invalid_utf8(&*self.create_current_usage(matcher, None), self.color()));
-        }
-        if let Some(p_vals) = arg.possible_vals() {
-            let val_str = val.to_string_lossy();
-            if !p_vals.contains(&&*val_str) {
-                return Err(Error::invalid_value(val_str,
-                                                p_vals,
-                                                arg,
-                                                &*self.create_current_usage(matcher, None),
-                                                self.color()));
-            }
-        }
-        if !arg.is_set(ArgSettings::EmptyValues) && val.is_empty_() &&
-           matcher.contains(&*arg.name()) {
-            return Err(Error::empty_value(arg, &*self.create_current_usage(matcher, None), self.color()));
-        }
-        if let Some(vtor) = arg.validator() {
-            if let Err(e) = vtor(val.to_string_lossy().into_owned()) {
-                return Err(Error::value_validation(Some(arg), e, self.color()));
-            }
-        }
-        if let Some(vtor) = arg.validator_os() {
-            if let Err(e) = vtor(val) {
-                return Err(Error::value_validation(Some(arg),
-                                                   (*e).to_string_lossy().to_string(),
-                                                   self.color()));
-            }
-        }
-        if matcher.needs_more_vals(arg) {
-            return Ok(Some(arg.name()));
-        }
-        Ok(None)
-    }
 
     fn parse_flag(&self,
                   flag: &FlagBuilder<'a, 'b>,
                   matcher: &mut ArgMatcher<'a>)
-                  -> ClapResult<()> {
+                  -> ClapResult<ParseResult<'a>> {
         debugln!("Parser::parse_flag;");
-        validate_multiples!(self, flag, matcher);
 
         matcher.inc_occurrence_of(flag.b.name);
         // Increment or create the group "args"
-        self.groups_for_arg(flag.b.name).and_then(|vec| Some(matcher.inc_occurrences_of(&*vec)));
-
-        Ok(())
-    }
-
-    fn validate_blacklist(&self, matcher: &mut ArgMatcher) -> ClapResult<()> {
-        debugln!("Parser::validate_blacklist: blacklist={:?}", self.blacklist);
-        macro_rules! build_err {
-            ($me:ident, $name:expr, $matcher:ident) => ({
-                debugln!("build_err!: name={}", $name);
-                let mut c_with = find_from!($me, $name, blacklist, &$matcher);
-                c_with = c_with.or(
-                    $me.find_any_arg($name).map_or(None, |aa| aa.blacklist())
-                                           .map_or(None, |bl| bl.iter().find(|arg| $matcher.contains(arg)))
-                                           .map_or(None, |an| $me.find_any_arg(an))
-                                           .map_or(None, |aa| Some(format!("{}", aa)))
-                );
-                debugln!("build_err!: '{:?}' conflicts with '{}'", c_with, $name);
-                $matcher.remove($name);
-                let usg = $me.create_current_usage($matcher, None);
-                if let Some(f) = find_by_name!($me, $name, flags, iter) {
-                    debugln!("build_err!: It was a flag...");
-                    Error::argument_conflict(f, c_with, &*usg, self.color())
-                } else if let Some(o) = find_by_name!($me, $name, opts, iter) {
-                   debugln!("build_err!: It was an option...");
-                    Error::argument_conflict(o, c_with, &*usg, self.color())
-                } else {
-                    match find_by_name!($me, $name, positionals, values) {
-                        Some(p) => {
-                            debugln!("build_err!: It was a positional...");
-                            Error::argument_conflict(p, c_with, &*usg, self.color())
-                        },
-                        None    => panic!(INTERNAL_ERROR_MSG)
-                    }
-                }
-            });
-        }
-
-        for name in &self.blacklist {
-            debugln!("Parser::validate_blacklist:iter: Checking blacklisted name: {}", name);
-            if self.groups.contains_key(name) {
-                debugln!("Parser::validate_blacklist:iter: groups contains it...");
-                for n in self.arg_names_in_group(name) {
-                    debugln!("Parser::validate_blacklist:iter:iter: Checking arg '{}' in group...", n);
-                    if matcher.contains(n) {
-                        debugln!("Parser::validate_blacklist:iter:iter: matcher contains it...");
-                        return Err(build_err!(self, &n, matcher));
-                    }
-                }
-            } else if matcher.contains(name) {
-                debugln!("Parser::validate_blacklist:iter: matcher contains it...");
-                return Err(build_err!(self, name, matcher));
-            }
-        }
-        Ok(())
-    }
-
-    fn validate_matched_args(&self, matcher: &mut ArgMatcher) -> ClapResult<()> {
-        debugln!("Parser::validate_matched_args;");
-        for (name, ma) in matcher.iter() {
-            debugln!("Parser::validate_matched_args:iter: name={}", name);
-            if let Some(opt) = find_by_name!(self, name, opts, iter) {
-                try!(self.validate_arg_num_vals(opt, ma, matcher));
-                try!(self.validate_arg_requires(opt, ma, matcher));
-            } else if let Some(flag) = find_by_name!(self, name, flags, iter) {
-                // Only requires
-                try!(self.validate_arg_requires(flag, ma, matcher));
-            } else if let Some(pos) = find_by_name!(self, name, positionals, values) {
-                try!(self.validate_arg_num_vals(pos, ma, matcher));
-                try!(self.validate_arg_requires(pos, ma, matcher));
-            } else if let Some(grp) = self.groups.get(name) {
-                if let Some(ref g_reqs) = grp.requires {
-                    if g_reqs.iter().any(|&n| !matcher.contains(n)) {
-                        return self.missing_required_error(matcher, None);
-                    }
-                }
-            }
-        }
-        Ok(())
-    }
+        self.groups_for_arg(flag.b.name)
+            .and_then(|vec| Some(matcher.inc_occurrences_of(&*vec)));
 
-    fn validate_arg_num_vals<A>(&self,
-                                a: &A,
-                                ma: &MatchedArg,
-                                matcher: &ArgMatcher)
-                                -> ClapResult<()>
-        where A: AnyArg<'a, 'b> + Display
-    {
-        debugln!("Parser::validate_arg_num_vals;");
-        if let Some(num) = a.num_vals() {
-            debugln!("Parser::validate_arg_num_vals: num_vals set...{}", num);
-            let should_err = if a.is_set(ArgSettings::Multiple) {
-                ((ma.vals.len() as u64) % num) != 0
-            } else {
-                num != (ma.vals.len() as u64)
-            };
-            if should_err {
-                debugln!("Parser::validate_arg_num_vals: Sending error WrongNumberOfValues");
-                return Err(Error::wrong_number_of_values(a,
-                                                         num,
-                                                         if a.is_set(ArgSettings::Multiple) {
-                                                             (ma.vals.len() % num as usize)
-                                                         } else {
-                                                             ma.vals.len()
-                                                         },
-                                                         if ma.vals.len() == 1 ||
-                                                            (a.is_set(ArgSettings::Multiple) &&
-                                                             (ma.vals.len() % num as usize) ==
-                                                             1) {
-                                                             "as"
-                                                         } else {
-                                                             "ere"
-                                                         },
-                                                         &*self.create_current_usage(matcher, None),
-                                                         self.color()));
-            }
-        }
-        if let Some(num) = a.max_vals() {
-            debugln!("Parser::validate_arg_num_vals: max_vals set...{}", num);
-            if (ma.vals.len() as u64) > num {
-                debugln!("Parser::validate_arg_num_vals: Sending error TooManyValues");
-                return Err(Error::too_many_values(ma.vals
-                                                      .get(ma.vals
-                                                          .keys()
-                                                          .last()
-                                                          .expect(INTERNAL_ERROR_MSG))
-                                                      .expect(INTERNAL_ERROR_MSG)
-                                                      .to_str()
-                                                      .expect(INVALID_UTF8),
-                                                  a,
-                                                  &*self.create_current_usage(matcher, None),
-                                                  self.color()));
-            }
-        }
-        if let Some(num) = a.min_vals() {
-            debugln!("Parser::validate_arg_num_vals: min_vals set: {}", num);
-            if (ma.vals.len() as u64) < num {
-                debugln!("Parser::validate_arg_num_vals: Sending error TooFewValues");
-                return Err(Error::too_few_values(a,
-                                                 num,
-                                                 ma.vals.len(),
-                                                 &*self.create_current_usage(matcher, None),
-                                                 self.color()));
-            }
-        }
-        // Issue 665 (https://github.com/kbknapp/clap-rs/issues/665)
-        if a.takes_value() && !a.is_set(ArgSettings::EmptyValues) && ma.vals.is_empty() {
-            return Err(Error::empty_value(a, &*self.create_current_usage(matcher, None), self.color()));
-        }
-        Ok(())
-    }
-
-    fn validate_arg_requires<A>(&self,
-                                a: &A,
-                                ma: &MatchedArg,
-                                matcher: &ArgMatcher)
-                                -> ClapResult<()>
-        where A: AnyArg<'a, 'b> + Display
-    {
-        debugln!("Parser::validate_arg_requires;");
-        if let Some(a_reqs) = a.requires() {
-            for &(val, name) in a_reqs.iter().filter(|&&(val, _)| val.is_some()) {
-                if ma.vals
-                    .values()
-                    .any(|v| v == val.expect(INTERNAL_ERROR_MSG) && !matcher.contains(name)) {
-                    return self.missing_required_error(matcher, None);
-                }
-            }
-        }
-        Ok(())
-    }
-
-    #[inline]
-    fn missing_required_error(&self, matcher: &ArgMatcher, extra: Option<&str>) -> ClapResult<()> {
-        debugln!("Parser::missing_required_error: extra={:?}", extra);
-        let c = Colorizer {
-            use_stderr: true,
-            when: self.color(),
-        };
-        let mut reqs = self.required.iter().map(|&r| &*r).collect::<Vec<_>>();
-        if let Some(r) = extra {
-            reqs.push(r);
-        }
-        reqs.retain(|n| !matcher.contains(n));
-        reqs.dedup();
-        debugln!("Parser::missing_required_error: reqs={:#?}", reqs);
-        Err(Error::missing_required_argument(&*self.get_required_from(&reqs[..],
-                                                                    Some(matcher),
-                                                                    extra)
-                                                 .iter()
-                                                 .fold(String::new(), |acc, s| {
-                                                     acc + &format!("\n    {}", c.error(s))[..]
-                                                 }),
-                                             &*self.create_current_usage(matcher, extra),
-                                             self.color()))
-    }
-
-    fn validate_required(&self, matcher: &ArgMatcher) -> ClapResult<()> {
-        debugln!("Parser::validate_required: required={:?};", self.required);
-        'outer: for name in &self.required {
-            debugln!("Parser::validate_required:iter: name={}", name);
-            if matcher.contains(name) {
-                continue 'outer;
-            }
-            if let Some(grp) = self.groups.get(name) {
-                for arg in &grp.args {
-                    if matcher.contains(arg) {
-                        continue 'outer;
-                    }
-                }
-            }
-            if self.groups.values().any(|g| g.args.contains(name)) {
-                continue 'outer;
-            }
-            if let Some(a) = find_by_name!(self, name, flags, iter) {
-                if self.is_missing_required_ok(a, matcher) {
-                    continue 'outer;
-                }
-            } else if let Some(a) = find_by_name!(self, name, opts, iter) {
-                if self.is_missing_required_ok(a, matcher) {
-                    continue 'outer;
-                }
-            } else if let Some(a) = find_by_name!(self, name, positionals, values) {
-                if self.is_missing_required_ok(a, matcher) {
-                    continue 'outer;
-                }
-            }
-            return self.missing_required_error(matcher, None);
-        }
-
-        // Validate the conditionally required args
-        for &(a, v, r) in &self.r_ifs {
-            if let Some(ma) = matcher.get(a) {
-                for val in ma.vals.values() {
-                    if v == val && matcher.get(r).is_none() {
-                        return self.missing_required_error(matcher, Some(r));
-                    }
-                }
-            }
-        }
-        Ok(())
-    }
-
-    fn is_missing_required_ok<A>(&self, a: &A, matcher: &ArgMatcher) -> bool
-        where A: AnyArg<'a, 'b>
-    {
-        debugln!("Parser::is_missing_required_ok: a={}", a.name());
-        if let Some(bl) = a.blacklist() {
-            debugln!("Parser::is_missing_required_ok: Conflicts found...{:?}", bl);
-            for n in bl.iter() {
-                debugln!("Parser::is_missing_required_ok:iter: conflict={}", n);
-                if matcher.contains(n) ||
-                   self.groups
-                    .get(n)
-                    .map_or(false, |g| g.args.iter().any(|an| matcher.contains(an))) {
-                    return true;
-                }
-            }
-        }
-        if let Some(ru) = a.required_unless() {
-            debugln!("Parser::is_missing_required_ok: Required unless found...{:?}", ru);
-            let mut found_any = false;
-            for n in ru.iter() {
-                debugln!("Parser::is_missing_required_ok:iter: ru={}", n);
-                if matcher.contains(n) ||
-                   self.groups
-                    .get(n)
-                    .map_or(false, |g| g.args.iter().any(|an| matcher.contains(an))) {
-                    if !a.is_set(ArgSettings::RequiredUnlessAll) {
-                        debugln!("Parser::is_missing_required_ok:iter: Doesn't require all...returning true");
-                        return true;
-                    }
-                    debugln!("Parser::is_missing_required_ok:iter: Requires all...next");
-                    found_any = true;
-                } else if a.is_set(ArgSettings::RequiredUnlessAll) {
-                    debugln!("Parser::is_missing_required_ok:iter: Not in matcher, or group and requires all...returning false");
-                    return false;
-                }
-            }
-            return found_any;
-        }
-        false
+        Ok(ParseResult::Flag)
     }
 
     fn did_you_mean_error(&self, arg: &str, matcher: &mut ArgMatcher<'a>) -> ClapResult<()> {
         // Didn't match a flag or option...maybe it was a typo and close to one
         let suffix =
             suggestions::did_you_mean_suffix(arg,
-                                             self.long_list.iter(),
+                                             longs!(self),
                                              suggestions::DidYouMeanMessageStyle::LongFlag);
 
         // Add the arg to the matches to build a proper usage string
         if let Some(name) = suffix.1 {
-            if let Some(opt) = find_by_long!(self, &name, opts) {
+            if let Some(opt) = find_opt_by_long!(self, &name) {
                 self.groups_for_arg(&*opt.b.name)
                     .and_then(|grps| Some(matcher.inc_occurrences_of(&*grps)));
                 matcher.insert(&*opt.b.name);
-            } else if let Some(flg) = find_by_long!(self, &name, flags) {
+            } else if let Some(flg) = find_flag_by_long!(self, &name) {
                 self.groups_for_arg(&*flg.b.name)
                     .and_then(|grps| Some(matcher.inc_occurrences_of(&*grps)));
                 matcher.insert(&*flg.b.name);
             }
         }
 
         let used_arg = format!("--{}", arg);
         Err(Error::unknown_argument(&*used_arg,
                                     &*suffix.0,
-                                    &*self.create_current_usage(matcher, None),
+                                    &*usage::create_error_usage(self, matcher, None),
                                     self.color()))
     }
 
-    // Creates a usage string if one was not provided by the user manually. This happens just
-    // after all arguments were parsed, but before any subcommands have been parsed
-    // (so as to give subcommands their own usage recursively)
-    pub fn create_usage(&self, used: &[&str]) -> String {
-        debugln!("Parser::create_usage;");
-        let mut usage = String::with_capacity(75);
-        usage.push_str("USAGE:\n    ");
-        usage.push_str(&self.create_usage_no_title(used));
-        usage
-    }
-
-    // Creates a usage string (*without title*) if one was not provided by the user
-    // manually. This happens just
-    // after all arguments were parsed, but before any subcommands have been parsed
-    // (so as to give subcommands their own usage recursively)
-    pub fn create_usage_no_title(&self, used: &[&str]) -> String {
-        debugln!("Parser::create_usage_no_title;");
-        let mut usage = String::with_capacity(75);
-        if let Some(u) = self.meta.usage_str {
-            usage.push_str(&*u);
-        } else if used.is_empty() {
-            usage.push_str(&*self.meta
-                .usage
-                .as_ref()
-                .unwrap_or_else(|| self.meta
-                    .bin_name
-                    .as_ref()
-                    .unwrap_or(&self.meta.name)));
-            let mut reqs: Vec<&str> = self.required().map(|r| &**r).collect();
-            reqs.dedup();
-            let req_string = self.get_required_from(&reqs, None, None)
-                .iter()
-                .fold(String::new(), |a, s| a + &format!(" {}", s)[..]);
-
-            let flags = self.needs_flags_tag();
-            if flags && !self.is_set(AppSettings::UnifiedHelpMessage) {
-                usage.push_str(" [FLAGS]");
-            } else if flags {
-                usage.push_str(" [OPTIONS]");
-            }
-            if !self.is_set(AppSettings::UnifiedHelpMessage) && self.has_opts() &&
-               self.opts.iter().any(|o| !o.b.settings.is_set(ArgSettings::Required)) {
-                usage.push_str(" [OPTIONS]");
-            }
-
-            usage.push_str(&req_string[..]);
-
-            // places a '--' in the usage string if there are args and options
-            // supporting multiple values
-            if self.has_positionals() &&
-               self.opts.iter().any(|o| o.b.settings.is_set(ArgSettings::Multiple)) &&
-               self.positionals.values().any(|p| !p.b.settings.is_set(ArgSettings::Required)) &&
-               !self.has_subcommands() {
-                usage.push_str(" [--]")
-            }
-            if self.has_positionals() &&
-               self.positionals.values().any(|p| !p.b.settings.is_set(ArgSettings::Required)) {
-                if let Some(args_tag) = self.get_args_tag() {
-                    usage.push_str(&*args_tag);
-                } else {
-                    usage.push_str(" [ARGS]");
-                }
-            }
-
-
-            if self.has_subcommands() && !self.is_set(AppSettings::SubcommandRequired) {
-                usage.push_str(" [SUBCOMMAND]");
-            } else if self.is_set(AppSettings::SubcommandRequired) && self.has_subcommands() {
-                usage.push_str(" <SUBCOMMAND>");
-            }
-        } else {
-            self.smart_usage(&mut usage, used);
-        }
-
-        usage.shrink_to_fit();
-        usage
-    }
-
-    // Creates a context aware usage string, or "smart usage" from currently used
-    // args, and requirements
-    fn smart_usage(&self, usage: &mut String, used: &[&str]) {
-        debugln!("Parser::smart_usage;");
-        let mut hs: Vec<&str> = self.required().map(|s| &**s).collect();
-        hs.extend_from_slice(used);
-
-        let r_string = self.get_required_from(&hs, None, None)
-            .iter()
-            .fold(String::new(), |acc, s| acc + &format!(" {}", s)[..]);
-
-        usage.push_str(&self.meta
-            .usage
-            .as_ref()
-            .unwrap_or_else(|| self.meta
-                .bin_name
-                .as_ref()
-                .unwrap_or(&self.meta
-                    .name))[..]);
-        usage.push_str(&*r_string);
-        if self.is_set(AppSettings::SubcommandRequired) {
-            usage.push_str(" <SUBCOMMAND>");
-        }
-    }
-
     // Prints the version to the user and exits if quit=true
-    fn print_version<W: Write>(&self, w: &mut W) -> ClapResult<()> {
-        try!(self.write_version(w));
+    fn print_version<W: Write>(&self, w: &mut W, use_long: bool) -> ClapResult<()> {
+        try!(self.write_version(w, use_long));
         w.flush().map_err(Error::from)
     }
 
-    pub fn write_version<W: Write>(&self, w: &mut W) -> io::Result<()> {
+    pub fn write_version<W: Write>(&self, w: &mut W, use_long: bool) -> io::Result<()> {
+        let ver = if use_long {
+            self.meta
+                .long_version
+                .unwrap_or(self.meta.version.unwrap_or("".into()))
+        } else {
+            self.meta
+                .version
+                .unwrap_or(self.meta.long_version.unwrap_or("".into()))
+        };
         if let Some(bn) = self.meta.bin_name.as_ref() {
             if bn.contains(' ') {
                 // Incase we're dealing with subcommands i.e. git mv is translated to git-mv
-                write!(w,
-                         "{} {}",
-                         bn.replace(" ", "-"),
-                         self.meta.version.unwrap_or("".into()))
+                write!(w, "{} {}", bn.replace(" ", "-"), ver)
             } else {
-                write!(w,
-                         "{} {}",
-                         &self.meta.name[..],
-                         self.meta.version.unwrap_or("".into()))
+                write!(w, "{} {}", &self.meta.name[..], ver)
             }
         } else {
-            write!(w,
-                     "{} {}",
-                     &self.meta.name[..],
-                     self.meta.version.unwrap_or("".into()))
+            write!(w, "{} {}", &self.meta.name[..], ver)
         }
     }
 
     pub fn print_help(&self) -> ClapResult<()> {
         let out = io::stdout();
         let mut buf_w = BufWriter::new(out.lock());
         self.write_help(&mut buf_w)
     }
 
     pub fn write_help<W: Write>(&self, w: &mut W) -> ClapResult<()> {
-        Help::write_parser_help(w, self)
+        Help::write_parser_help(w, self, false)
+    }
+
+    pub fn write_long_help<W: Write>(&self, w: &mut W) -> ClapResult<()> {
+        Help::write_parser_help(w, self, true)
     }
 
     pub fn write_help_err<W: Write>(&self, w: &mut W) -> ClapResult<()> {
         Help::write_parser_help_to_stderr(w, self)
     }
 
-    fn add_defaults(&mut self, matcher: &mut ArgMatcher<'a>) -> ClapResult<()> {
+    pub fn add_defaults(&mut self, matcher: &mut ArgMatcher<'a>) -> ClapResult<()> {
         macro_rules! add_val {
             (@default $_self:ident, $a:ident, $m:ident) => {
                 if let Some(ref val) = $a.v.default_val {
                     if $m.get($a.b.name).is_none() {
                         try!($_self.add_val_to_arg($a, OsStr::new(val), $m));
-                        arg_post_processing!($_self, $a, $m);
+
+                        if $_self.cache.map_or(true, |name| name != $a.name()) {
+                            arg_post_processing!($_self, $a, $m);
+                            $_self.cache = Some($a.name());
+                        }
                     }
                 }
             };
             ($_self:ident, $a:ident, $m:ident) => {
                 if let Some(ref vm) = $a.v.default_vals_ifs {
                     let mut done = false;
                     if $m.get($a.b.name).is_none() {
                         for &(arg, val, default) in vm.values() {
                             let add = if let Some(a) = $m.get(arg) {
                                 if let Some(v) = val {
-                                    a.vals.values().any(|value| v == value)
+                                    a.vals.iter().any(|value| v == value)
                                 } else {
                                     true
                                 }
                             } else {
                                 false
                             };
                             if add {
                                 try!($_self.add_val_to_arg($a, OsStr::new(default), $m));
-                                arg_post_processing!($_self, $a, $m);
+                                if $_self.cache.map_or(true, |name| name != $a.name()) {
+                                    arg_post_processing!($_self, $a, $m);
+                                    $_self.cache = Some($a.name());
+                                }
                                 done = true;
                                 break;
                             }
                         }
                     }
 
                     if done {
                         continue; // outer loop (outside macro)
@@ -2155,20 +1799,20 @@ impl<'a, 'b> Parser<'a, 'b>
 
     pub fn subcommands(&self) -> Iter<App> { self.subcommands.iter() }
 
     // Should we color the output? None=determined by output location, true=yes, false=no
     #[doc(hidden)]
     pub fn color(&self) -> ColorWhen {
         debugln!("Parser::color;");
         debug!("Parser::color: Color setting...");
-        if self.is_set(AppSettings::ColorNever) {
+        if self.is_set(AS::ColorNever) {
             sdebugln!("Never");
             ColorWhen::Never
-        } else if self.is_set(AppSettings::ColorAlways) {
+        } else if self.is_set(AS::ColorAlways) {
             sdebugln!("Always");
             ColorWhen::Always
         } else {
             sdebugln!("Auto");
             ColorWhen::Auto
         }
     }
 
@@ -2180,62 +1824,41 @@ impl<'a, 'b> Parser<'a, 'b>
             return Some(o);
         }
         if let Some(p) = find_by_name!(self, &name, positionals, values) {
             return Some(p);
         }
         None
     }
 
-    #[cfg_attr(feature = "lints", allow(explicit_iter_loop))]
+    // Only used for completion scripts due to bin_name messiness
+    #[cfg_attr(feature = "lints", allow(block_in_if_condition_stmt))]
     pub fn find_subcommand(&'b self, sc: &str) -> Option<&'b App<'a, 'b>> {
         debugln!("Parser::find_subcommand: sc={}", sc);
-        debugln!("Parser::find_subcommand: Currently in Parser...{}", self.meta.bin_name.as_ref().unwrap());
+        debugln!("Parser::find_subcommand: Currently in Parser...{}",
+                 self.meta.bin_name.as_ref().unwrap());
         for s in self.subcommands.iter() {
             if s.p.meta.bin_name.as_ref().unwrap_or(&String::new()) == sc ||
                (s.p.meta.aliases.is_some() &&
                 s.p
-                .meta
-                .aliases
-                .as_ref()
-                .unwrap()
-                .iter()
-                .any(|&(s, _)| s == sc.split(' ').rev().next().expect(INTERNAL_ERROR_MSG))) {
+                    .meta
+                    .aliases
+                    .as_ref()
+                    .unwrap()
+                    .iter()
+                    .any(|&(s, _)| {
+                             s == sc.split(' ').rev().next().expect(INTERNAL_ERROR_MSG)
+                         })) {
                 return Some(s);
             }
             if let Some(app) = s.p.find_subcommand(sc) {
                 return Some(app);
             }
         }
         None
     }
-}
+
+    #[inline]
+    fn contains_long(&self, l: &str) -> bool { longs!(self).any(|al| al == &l) }
 
-impl<'a, 'b> Clone for Parser<'a, 'b>
-    where 'a: 'b
-{
-    fn clone(&self) -> Self {
-        Parser {
-            propogated: self.propogated,
-            required: self.required.clone(),
-            short_list: self.short_list.clone(),
-            long_list: self.long_list.clone(),
-            blacklist: self.blacklist.clone(),
-            flags: self.flags.clone(),
-            opts: self.opts.clone(),
-            positionals: self.positionals.clone(),
-            subcommands: self.subcommands.clone(),
-            groups: self.groups.clone(),
-            global_args: self.global_args.clone(),
-            overrides: self.overrides.clone(),
-            help_short: self.help_short,
-            version_short: self.version_short,
-            settings: self.settings,
-            g_settings: self.g_settings,
-            meta: self.meta.clone(),
-            trailing_vals: self.trailing_vals,
-            id: self.id,
-            valid_neg_num: self.valid_neg_num,
-            r_ifs: self.r_ifs.clone(),
-            valid_arg: self.valid_arg,
-        }
-    }
+    #[inline]
+    fn contains_short(&self, s: char) -> bool { shorts!(self).any(|arg_s| arg_s == &s) }
 }
--- a/third_party/rust/clap/src/app/settings.rs
+++ b/third_party/rust/clap/src/app/settings.rs
@@ -1,61 +1,65 @@
 // Std
 use std::ascii::AsciiExt;
 use std::str::FromStr;
 use std::ops::BitOr;
 
 bitflags! {
     flags Flags: u64 {
-        const SC_NEGATE_REQS       = 0b0000000000000000000000000000000001,
-        const SC_REQUIRED          = 0b0000000000000000000000000000000010,
-        const A_REQUIRED_ELSE_HELP = 0b0000000000000000000000000000000100,
-        const GLOBAL_VERSION       = 0b0000000000000000000000000000001000,
-        const VERSIONLESS_SC       = 0b0000000000000000000000000000010000,
-        const UNIFIED_HELP         = 0b0000000000000000000000000000100000,
-        const WAIT_ON_ERROR        = 0b0000000000000000000000000001000000,
-        const SC_REQUIRED_ELSE_HELP= 0b0000000000000000000000000010000000,
-        const NEEDS_LONG_HELP      = 0b0000000000000000000000000100000000,
-        const NEEDS_LONG_VERSION   = 0b0000000000000000000000001000000000,
-        const NEEDS_SC_HELP        = 0b0000000000000000000000010000000000,
-        const DISABLE_VERSION      = 0b0000000000000000000000100000000000,
-        const HIDDEN               = 0b0000000000000000000001000000000000,
-        const TRAILING_VARARG      = 0b0000000000000000000010000000000000,
-        const NO_BIN_NAME          = 0b0000000000000000000100000000000000,
-        const ALLOW_UNK_SC         = 0b0000000000000000001000000000000000,
-        const UTF8_STRICT          = 0b0000000000000000010000000000000000,
-        const UTF8_NONE            = 0b0000000000000000100000000000000000,
-        const LEADING_HYPHEN       = 0b0000000000000001000000000000000000,
-        const NO_POS_VALUES        = 0b0000000000000010000000000000000000,
-        const NEXT_LINE_HELP       = 0b0000000000000100000000000000000000,
-        const DERIVE_DISP_ORDER    = 0b0000000000001000000000000000000000,
-        const COLORED_HELP         = 0b0000000000010000000000000000000000,
-        const COLOR_ALWAYS         = 0b0000000000100000000000000000000000,
-        const COLOR_AUTO           = 0b0000000001000000000000000000000000,
-        const COLOR_NEVER          = 0b0000000010000000000000000000000000,
-        const DONT_DELIM_TRAIL     = 0b0000000100000000000000000000000000,
-        const ALLOW_NEG_NUMS       = 0b0000001000000000000000000000000000,
-        const LOW_INDEX_MUL_POS    = 0b0000010000000000000000000000000000,
-        const DISABLE_HELP_SC      = 0b0000100000000000000000000000000000,
-        const DONT_COLLAPSE_ARGS   = 0b0001000000000000000000000000000000,
-        const ARGS_NEGATE_SCS      = 0b0010000000000000000000000000000000,
-        const PROPAGATE_VALS_DOWN  = 0b0100000000000000000000000000000000,
-        const ALLOW_MISSING_POS    = 0b1000000000000000000000000000000000,
+        const SC_NEGATE_REQS       = 1 << 0,
+        const SC_REQUIRED          = 1 << 1,
+        const A_REQUIRED_ELSE_HELP = 1 << 2,
+        const GLOBAL_VERSION       = 1 << 3,
+        const VERSIONLESS_SC       = 1 << 4,
+        const UNIFIED_HELP         = 1 << 5,
+        const WAIT_ON_ERROR        = 1 << 6,
+        const SC_REQUIRED_ELSE_HELP= 1 << 7,
+        const NEEDS_LONG_HELP      = 1 << 8,
+        const NEEDS_LONG_VERSION   = 1 << 9,
+        const NEEDS_SC_HELP        = 1 << 10,
+        const DISABLE_VERSION      = 1 << 11,
+        const HIDDEN               = 1 << 12,
+        const TRAILING_VARARG      = 1 << 13,
+        const NO_BIN_NAME          = 1 << 14,
+        const ALLOW_UNK_SC         = 1 << 15,
+        const UTF8_STRICT          = 1 << 16,
+        const UTF8_NONE            = 1 << 17,
+        const LEADING_HYPHEN       = 1 << 18,
+        const NO_POS_VALUES        = 1 << 19,
+        const NEXT_LINE_HELP       = 1 << 20,
+        const DERIVE_DISP_ORDER    = 1 << 21,
+        const COLORED_HELP         = 1 << 22,
+        const COLOR_ALWAYS         = 1 << 23,
+        const COLOR_AUTO           = 1 << 24,
+        const COLOR_NEVER          = 1 << 25,
+        const DONT_DELIM_TRAIL     = 1 << 26,
+        const ALLOW_NEG_NUMS       = 1 << 27,
+        const LOW_INDEX_MUL_POS    = 1 << 28,
+        const DISABLE_HELP_SC      = 1 << 29,
+        const DONT_COLLAPSE_ARGS   = 1 << 30,
+        const ARGS_NEGATE_SCS      = 1 << 31, 
+        const PROPAGATE_VALS_DOWN  = 1 << 32,
+        const ALLOW_MISSING_POS    = 1 << 33,
+        const TRAILING_VALUES      = 1 << 34,
+        const VALID_NEG_NUM_FOUND  = 1 << 35,
+        const PROPOGATED           = 1 << 36,
+        const VALID_ARG_FOUND      = 1 << 37,
+        const INFER_SUBCOMMANDS    = 1 << 38,
+        const CONTAINS_LAST        = 1 << 39,
     }
 }
 
 #[doc(hidden)]
 #[derive(Debug, Copy, Clone, PartialEq)]
 pub struct AppFlags(Flags);
 
 impl BitOr for AppFlags {
     type Output = Self;
-    fn bitor(self, rhs: Self) -> Self {
-        AppFlags(self.0 | rhs.0)
-    }
+    fn bitor(self, rhs: Self) -> Self { AppFlags(self.0 | rhs.0) }
 }
 
 impl Default for AppFlags {
     fn default() -> Self {
         AppFlags(NEEDS_LONG_VERSION | NEEDS_LONG_HELP | NEEDS_SC_HELP | UTF8_NONE | COLOR_AUTO)
     }
 }
 
@@ -91,17 +95,23 @@ impl AppFlags {
         StrictUtf8 => UTF8_STRICT,
         SubcommandsNegateReqs => SC_NEGATE_REQS,
         SubcommandRequired => SC_REQUIRED,
         SubcommandRequiredElseHelp => SC_REQUIRED_ELSE_HELP,
         TrailingVarArg => TRAILING_VARARG,
         UnifiedHelpMessage => UNIFIED_HELP,
         NextLineHelp => NEXT_LINE_HELP,
         VersionlessSubcommands => VERSIONLESS_SC,
-        WaitOnError => WAIT_ON_ERROR
+        WaitOnError => WAIT_ON_ERROR,
+        TrailingValues => TRAILING_VALUES,
+        ValidNegNumFound => VALID_NEG_NUM_FOUND,
+        Propogated => PROPOGATED,
+        ValidArgFound => VALID_ARG_FOUND,
+        InferSubcommands => INFER_SUBCOMMANDS,
+        ContainsLast => CONTAINS_LAST
     }
 }
 
 /// Application level settings, which affect how [`App`] operates
 ///
 /// **NOTE:** When these settings are used, they apply only to current command, and are *not*
 /// propagated down or up through child or parent subcommands
 ///
@@ -147,37 +157,36 @@ pub enum AppSettings {
     /// [`ArgMatches::os_values_of`]: ./struct.ArgMatches.html#method.os_values_of
     /// [`ArgMatches::lossy_value_of`]: ./struct.ArgMatches.html#method.lossy_value_of
     /// [`ArgMatches::lossy_values_of`]: ./struct.ArgMatches.html#method.lossy_values_of
     AllowInvalidUtf8,
 
     /// Specifies that leading hyphens are allowed in argument *values*, such as negative numbers
     /// like `-10`. (which would otherwise be parsed as another flag or option)
     ///
-    /// **NOTE:** This can only be set application wide and not on a per argument basis.
-    ///
     /// **NOTE:** Use this setting with caution as it silences certain circumstances which would
     /// otherwise be an error (such as accidentally forgetting to specify a value for leading
-    /// option)
+    /// option). It is preferred to set this on a per argument basis, via [`Arg::allow_hyphen_values`]
     ///
     /// # Examples
     ///
     /// ```rust
     /// # use clap::{Arg, App, AppSettings};
     /// // Imagine you needed to represent negative numbers as well, such as -10
     /// let m = App::new("nums")
     ///     .setting(AppSettings::AllowLeadingHyphen)
     ///     .arg(Arg::with_name("neg").index(1))
     ///     .get_matches_from(vec![
     ///         "nums", "-20"
     ///     ]);
     ///
     /// assert_eq!(m.value_of("neg"), Some("-20"));
     /// # ;
     /// ```
+    /// [`Arg::allow_hyphen_values`]: ./struct.Arg.html#method.allow_hyphen_values
     AllowLeadingHyphen,
 
     /// Allows negative numbers to pass as values. This is similar to
     /// `AllowLeadingHyphen` except that it only allows numbers, all
     /// other undefined leading hyphens will fail to parse.
     ///
     /// # Examples
     ///
@@ -201,17 +210,17 @@ pub enum AppSettings {
     /// the final positional argument is required. Such as `$ prog [optional] <required>` where one
     /// of the two following usages is allowed:
     ///
     /// * `$ prog [optional] <required>`
     /// * `$ prog <required>`
     ///
     /// This would otherwise not be allowed. This is useful when `[optional]` has a default value.
     ///
-    /// **Note:** In addition to using this setting, the second positional argument *must* be 
+    /// **Note:** In addition to using this setting, the second positional argument *must* be
     /// [required]
     ///
     /// # Examples
     ///
     /// ```rust
     /// # use clap::{App, Arg, AppSettings};
     /// // Assume there is an external subcommand named "subcmd"
     /// let m = App::new("myprog")
@@ -262,19 +271,19 @@ pub enum AppSettings {
     /// }
     /// ```
     /// [`ErrorKind::UnknownArgument`]: ./enum.ErrorKind.html#variant.UnknownArgument
     /// [`SubCommand`]: ./struct.SubCommand.html
     /// [`ArgMatches`]: ./struct.ArgMatches.html
     AllowExternalSubcommands,
 
     /// Specifies that use of a valid [argument] negates [subcomands] being used after. By default
-    /// `clap` allows arguments between subcommands such as 
-    /// `<cmd> [cmd_args] <cmd2> [cmd2_args] <cmd3> [cmd3_args]`. This setting disables that 
-    /// functionality and says that arguments can only follow the *final* subcommand. For instance 
+    /// `clap` allows arguments between subcommands such as
+    /// `<cmd> [cmd_args] <cmd2> [cmd2_args] <cmd3> [cmd3_args]`. This setting disables that
+    /// functionality and says that arguments can only follow the *final* subcommand. For instance
     /// using this setting makes only the following invocations possible:
     ///
     /// * `<cmd> <cmd2> <cmd3> [cmd3_args]`
     /// * `<cmd> <cmd2> [cmd2_args]`
     /// * `<cmd> [cmd_args]`
     ///
     /// # Examples
     ///
@@ -289,17 +298,17 @@ pub enum AppSettings {
     ArgsNegateSubcommands,
 
     /// Specifies that the help text should be displayed (and then exit gracefully),
     /// if no arguments are present at runtime (i.e. an empty run such as, `$ myprog`.
     ///
     /// **NOTE:** [`SubCommand`]s count as arguments
     ///
     /// **NOTE:** Setting [`Arg::default_value`] effectively disables this option as it will
-    /// ensure that some argument is always present. 
+    /// ensure that some argument is always present.
     ///
     /// # Examples
     ///
     /// ```rust
     /// # use clap::{App, AppSettings};
     /// App::new("myprog")
     ///     .setting(AppSettings::ArgRequiredElseHelp)
     /// # ;
@@ -408,28 +417,28 @@ pub enum AppSettings {
     /// App::new("myprog")
     ///     .setting(AppSettings::DontDelimitTrailingValues)
     ///     .get_matches();
     /// ```
     /// [`AppSettings::TrailingVarArg`]: ./enum.AppSettings.html#variant.TrailingVarArg
     /// [`Arg::use_delimiter(false)`]: ./struct.Arg.html#method.use_delimiter
     DontDelimitTrailingValues,
 
-    /// Disables the `help` subcommand 
+    /// Disables the `help` subcommand
     ///
     /// # Examples
     ///
     /// ```rust
     /// # use clap::{App, AppSettings, ErrorKind, SubCommand};
     /// let res = App::new("myprog")
     ///     .version("v1.1")
     ///     .setting(AppSettings::DisableHelpSubcommand)
     ///     // Normally, creating a subcommand causes a `help` subcommand to automaticaly
     ///     // be generated as well
-    ///     .subcommand(SubCommand::with_name("test")) 
+    ///     .subcommand(SubCommand::with_name("test"))
     ///     .get_matches_from_safe(vec![
     ///         "myprog", "help"
     ///     ]);
     /// assert!(res.is_err());
     /// assert_eq!(res.unwrap_err().kind, ErrorKind::UnknownArgument);
     /// ```
     /// [`SubCommand`]: ./struct.SubCommand.html
     DisableHelpSubcommand,
@@ -514,16 +523,46 @@ pub enum AppSettings {
     /// ```
     /// [`SubCommand`]: ./struct.SubCommand.html
     Hidden,
 
     /// Tells `clap` *not* to print possible values when displaying help information.
     /// This can be useful if there are many values, or they are explained elsewhere.
     HidePossibleValuesInHelp,
 
+    /// Tries to match unknown args to partial [`subcommands`] or their [aliases]. For example to 
+    /// match a subcommand named `test`, one could use `t`, `te`, `tes`, and `test`.
+    ///
+    /// **NOTE:** The match *must not* be ambiguous at all in order to succeed. i.e. to match `te`
+    /// to `test` there could not also be a subcommand or alias `temp` because both start with `te`
+    ///
+    /// **CAUTION:** This setting can interfere with [positional/free arguments], take care when
+    /// designing CLIs which allow inferred subcommands and have potential positional/free
+    /// arguments who's values could start with the same characters as subcommands. If this is the
+    /// case, it's recommended to use settings such as [`AppSeettings::ArgsNegateSubcommands`] in
+    /// conjuction with this setting.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// # use clap::{App, Arg, SubCommand, AppSettings};
+    /// let m = App::new("prog")
+    ///     .setting(AppSettings::InferSubcommands)
+    ///     .subcommand(SubCommand::with_name("test"))
+    ///     .get_matches_from(vec![
+    ///         "prog", "te"
+    ///     ]);
+    /// assert_eq!(m.subcommand_name(), Some("test"));
+    /// ```
+    /// [`subcommands`]: ./struct.SubCommand.html
+    /// [positional/free arguments]: ./struct.Arg.html#method.index
+    /// [aliases]: ./struct.App.html#method.alias
+    /// [`AppSeettings::ArgsNegateSubcommands`]: ./enum.AppSettings.html#variant.ArgsNegateSubcommands
+    InferSubcommands,
+
     /// Specifies that the parser should not assume the first argument passed is the binary name.
     /// This is normally the case when using a "daemon" style mode, or an interactive CLI where one
     /// one would not normally type the binary or program name for each command.
     ///
     /// # Examples
     ///
     /// ```rust
     /// # use clap::{App, Arg, AppSettings};
@@ -568,21 +607,23 @@ pub enum AppSettings {
     ///
     /// assert_eq!(m.value_of("cmd"), Some("set"));
     ///
     /// let sub_m = m.subcommand_matches("foo").unwrap();
     /// assert_eq!(sub_m.value_of("cmd"), Some("set"));
     /// ```
     /// Now doing the same thing, but *not* using any subcommands will result in the value not being
     /// propagated down.
+    ///
     /// ```rust
-    /// # use clap::{App, Arg, AppSettings};
+    /// # use clap::{App, Arg, AppSettings, SubCommand};
     /// let m = App::new("myprog")
     ///     .setting(AppSettings::PropagateGlobalValuesDown)
-    ///     .global_arg(Arg::from_usage("<cmd> 'command to run'"))
+    ///     .arg(Arg::from_usage("[cmd] 'command to run'")
+    ///         .global(true))
     ///     .subcommand(SubCommand::with_name("foo"))
     ///     .get_matches_from(vec!["myprog", "set"]);
     ///
     /// assert_eq!(m.value_of("cmd"), Some("set"));
     ///
     /// assert!(m.subcommand_matches("foo").is_none());
     /// ```
     PropagateGlobalValuesDown,
@@ -802,16 +843,31 @@ pub enum AppSettings {
     #[doc(hidden)]
     NeedsLongHelp,
 
     #[doc(hidden)]
     NeedsSubcommandHelp,
 
     #[doc(hidden)]
     LowIndexMultiplePositional,
+
+    #[doc(hidden)]
+    TrailingValues,
+
+    #[doc(hidden)]
+    ValidNegNumFound,
+
+    #[doc(hidden)]
+    Propogated,
+
+    #[doc(hidden)]
+    ValidArgFound,
+
+    #[doc(hidden)]
+    ContainsLast,
 }
 
 impl FromStr for AppSettings {
     type Err = String;
     fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
         match &*s.to_ascii_lowercase() {
             "argrequiredelsehelp" => Ok(AppSettings::ArgRequiredElseHelp),
             "argsnegatesubcommands" => Ok(AppSettings::ArgsNegateSubcommands),
@@ -826,27 +882,32 @@ impl FromStr for AppSettings {
             "derivedisplayorder" => Ok(AppSettings::DeriveDisplayOrder),
             "dontcollapseargsinusage" => Ok(AppSettings::DontCollapseArgsInUsage),
             "dontdelimittrailingvalues" => Ok(AppSettings::DontDelimitTrailingValues),
             "disablehelpsubcommand" => Ok(AppSettings::DisableHelpSubcommand),
             "disableversion" => Ok(AppSettings::DisableVersion),
             "globalversion" => Ok(AppSettings::GlobalVersion),
             "hidden" => Ok(AppSettings::Hidden),
             "hidepossiblevaluesinhelp" => Ok(AppSettings::HidePossibleValuesInHelp),
+            "infersubcommands" => Ok(AppSettings::InferSubcommands),
             "lowindexmultiplepositional" => Ok(AppSettings::LowIndexMultiplePositional),
             "nobinaryname" => Ok(AppSettings::NoBinaryName),
             "nextlinehelp" => Ok(AppSettings::NextLineHelp),
             "strictutf8" => Ok(AppSettings::StrictUtf8),
             "subcommandsnegatereqs" => Ok(AppSettings::SubcommandsNegateReqs),
             "subcommandrequired" => Ok(AppSettings::SubcommandRequired),
             "subcommandrequiredelsehelp" => Ok(AppSettings::SubcommandRequiredElseHelp),
             "trailingvararg" => Ok(AppSettings::TrailingVarArg),
             "unifiedhelpmessage" => Ok(AppSettings::UnifiedHelpMessage),
             "versionlesssubcommands" => Ok(AppSettings::VersionlessSubcommands),
             "waitonerror" => Ok(AppSettings::WaitOnError),
+            "validnegnumfound" => Ok(AppSettings::ValidNegNumFound),
+            "validargfound" => Ok(AppSettings::ValidArgFound),
+            "propogated" => Ok(AppSettings::Propogated),
+            "trailingvalues" => Ok(AppSettings::TrailingValues),
             _ => Err("unknown AppSetting, cannot convert from str".to_owned()),
         }
     }
 }
 
 #[cfg(test)]
 mod test {
     use super::AppSettings;
@@ -906,11 +967,21 @@ mod test {
         assert_eq!("trailingvararg".parse::<AppSettings>().unwrap(),
                    AppSettings::TrailingVarArg);
         assert_eq!("unifiedhelpmessage".parse::<AppSettings>().unwrap(),
                    AppSettings::UnifiedHelpMessage);
         assert_eq!("versionlesssubcommands".parse::<AppSettings>().unwrap(),
                    AppSettings::VersionlessSubcommands);
         assert_eq!("waitonerror".parse::<AppSettings>().unwrap(),
                    AppSettings::WaitOnError);
+        assert_eq!("validnegnumfound".parse::<AppSettings>().unwrap(),
+                   AppSettings::ValidNegNumFound);
+        assert_eq!("validargfound".parse::<AppSettings>().unwrap(),
+                   AppSettings::ValidArgFound);
+        assert_eq!("propogated".parse::<AppSettings>().unwrap(),
+                   AppSettings::Propogated);
+        assert_eq!("trailingvalues".parse::<AppSettings>().unwrap(),
+                   AppSettings::TrailingValues);
+        assert_eq!("infersubcommands".parse::<AppSettings>().unwrap(),
+                   AppSettings::InferSubcommands);
         assert!("hahahaha".parse::<AppSettings>().is_err());
     }
 }
new file mode 100644
--- /dev/null
+++ b/third_party/rust/clap/src/app/usage.rs
@@ -0,0 +1,439 @@
+// std
+use std::collections::{BTreeMap, VecDeque};
+
+// Internal
+use INTERNAL_ERROR_MSG;
+use args::{AnyArg, ArgMatcher, PosBuilder};
+use args::settings::ArgSettings;
+use app::settings::AppSettings as AS;
+use app::parser::Parser;
+
+// Creates a usage string for display. This happens just after all arguments were parsed, but before
+// any subcommands have been parsed (so as to give subcommands their own usage recursively)
+pub fn create_usage_with_title(p: &Parser, used: &[&str]) -> String {
+    debugln!("usage::create_usage_with_title;");
+    let mut usage = String::with_capacity(75);
+    usage.push_str("USAGE:\n    ");
+    usage.push_str(&*create_usage_no_title(p, used));
+    usage
+}
+
+// Creates a usage string to be used in error message (i.e. one with currently used args)
+pub fn create_error_usage<'a, 'b>(p: &Parser<'a, 'b>,
+                                  matcher: &'b ArgMatcher<'a>,
+                                  extra: Option<&str>)
+                                  -> String {
+    let mut args: Vec<_> = matcher.arg_names()
+        .iter()
+        .filter(|n| {
+            if let Some(o) = find_by_name!(p, *n, opts, iter) {
+                !o.b.is_set(ArgSettings::Required) && !o.b.is_set(ArgSettings::Hidden)
+            } else if let Some(p) = find_by_name!(p, *n, positionals, values) {
+                !p.b.is_set(ArgSettings::Required) && p.b.is_set(ArgSettings::Hidden)
+            } else {
+                true // flags can't be required, so they're always true
+            }
+        })
+        .map(|&n| n)
+        .collect();
+    if let Some(r) = extra {
+        args.push(r);
+    }
+    create_usage_with_title(p, &*args)
+}
+
+// Creates a usage string (*without title*) if one was not provided by the user manually.
+pub fn create_usage_no_title(p: &Parser, used: &[&str]) -> String {
+    debugln!("usage::create_usage_no_title;");
+    if let Some(u) = p.meta.usage_str {
+        String::from(&*u)
+    } else if used.is_empty() {
+        create_help_usage(p, true)
+    } else {
+        create_smart_usage(p, used)
+    }
+}
+
+// Creates a usage string for display in help messages (i.e. not for errors)
+pub fn create_help_usage(p: &Parser, incl_reqs: bool) -> String {
+    let mut usage = String::with_capacity(75);
+    let name = p.meta
+        .usage
+        .as_ref()
+        .unwrap_or_else(|| {
+                            p.meta
+                                .bin_name
+                                .as_ref()
+                                .unwrap_or(&p.meta.name)
+                        });
+    usage.push_str(&*name);
+    let req_string = if incl_reqs {
+        let mut reqs: Vec<&str> = p.required().map(|r| &**r).collect();
+        reqs.sort();
+        reqs.dedup();
+        get_required_usage_from(p, &reqs, None, None, false).iter().fold(String::new(), |a, s| {
+            a + &format!(" {}", s)[..]
+        })
+    } else {
+        String::new()
+    };
+
+    let flags = needs_flags_tag(p);
+    if flags && !p.is_set(AS::UnifiedHelpMessage) {
+        usage.push_str(" [FLAGS]");
+    } else if flags {
+        usage.push_str(" [OPTIONS]");
+    }
+    if !p.is_set(AS::UnifiedHelpMessage) &&
+       p.opts.iter().any(|o| !o.is_set(ArgSettings::Required) && !o.is_set(ArgSettings::Hidden)) {
+        usage.push_str(" [OPTIONS]");
+    }
+
+    usage.push_str(&req_string[..]);
+
+    let has_last = p.positionals.values().any(|p| p.is_set(ArgSettings::Last));
+    // places a '--' in the usage string if there are args and options
+    // supporting multiple values
+    if p.opts.iter().any(|o| o.is_set(ArgSettings::Multiple)) &&
+       p.positionals.values().any(|p| !p.is_set(ArgSettings::Required)) &&
+       !p.has_visible_subcommands() && !has_last {
+        usage.push_str(" [--]");
+    }
+    let not_req_or_hidden =
+        |p: &PosBuilder| (!p.is_set(ArgSettings::Required) || p.is_set(ArgSettings::Last)) && !p.is_set(ArgSettings::Hidden);
+    if p.has_positionals() && p.positionals.values().any(not_req_or_hidden) {
+        if let Some(args_tag) = get_args_tag(p, incl_reqs) {
+            usage.push_str(&*args_tag);
+        } else {
+            usage.push_str(" [ARGS]");
+        }
+        if has_last && incl_reqs {
+            let pos = p.positionals
+                .values()
+                .find(|p| p.b.is_set(ArgSettings::Last))
+                .expect(INTERNAL_ERROR_MSG);
+            debugln!("usage::create_help_usage: '{}' has .last(true)", pos.name());
+            let req = pos.is_set(ArgSettings::Required);
+            if req && p.positionals.values().any(|p| !p.is_set(ArgSettings::Required)) {
+                usage.push_str(" -- <");
+            } else if req {
+                usage.push_str(" [--] <");
+            } else {
+                usage.push_str(" [-- <");
+            }
+            usage.push_str(&*pos.name_no_brackets());
+            usage.push_str(">");
+            usage.push_str(pos.multiple_str());
+            if !req {
+                usage.push_str("]");
+            }
+        }
+    }
+
+    // incl_reqs is only false when this function is called recursively
+    if p.has_visible_subcommands() && incl_reqs {
+        if p.is_set(AS::SubcommandsNegateReqs) || p.is_set(AS::ArgsNegateSubcommands) {
+            if !p.is_set(AS::ArgsNegateSubcommands) {
+                usage.push_str("\n    ");
+                usage.push_str(&*create_help_usage(p, false));
+                usage.push_str(" <SUBCOMMAND>");
+            } else {
+                usage.push_str("\n    ");
+                usage.push_str(&*name);
+                usage.push_str(" <SUBCOMMAND>");
+            }
+        } else if p.is_set(AS::SubcommandRequired) || p.is_set(AS::SubcommandRequiredElseHelp) {
+            usage.push_str(" <SUBCOMMAND>");
+        } else {
+            usage.push_str(" [SUBCOMMAND]");
+        }
+    }
+    usage.shrink_to_fit();
+    debugln!("usage::create_help_usage: usage={}", usage);
+    usage
+}
+
+// Creates a context aware usage string, or "smart usage" from currently used
+// args, and requirements
+fn create_smart_usage(p: &Parser, used: &[&str]) -> String {
+    debugln!("usage::smart_usage;");
+    let mut usage = String::with_capacity(75);
+    let mut hs: Vec<&str> = p.required().map(|s| &**s).collect();
+    hs.extend_from_slice(used);
+
+    let r_string =
+        get_required_usage_from(p, &hs, None, None, false).iter().fold(String::new(), |acc, s| {
+            acc + &format!(" {}", s)[..]
+        });
+
+    usage.push_str(&p.meta
+                        .usage
+                        .as_ref()
+                        .unwrap_or_else(|| {
+                                            p.meta
+                                                .bin_name
+                                                .as_ref()
+                                                .unwrap_or(&p.meta.name)
+                                        })
+                        [..]);
+    usage.push_str(&*r_string);
+    if p.is_set(AS::SubcommandRequired) {
+        usage.push_str(" <SUBCOMMAND>");
+    }
+    usage.shrink_to_fit();
+    usage
+}
+
+// Gets the `[ARGS]` tag for the usage string
+fn get_args_tag(p: &Parser, incl_reqs: bool) -> Option<String> {
+    debugln!("usage::get_args_tag;");
+    let mut count = 0;
+    'outer: for pos in p.positionals
+                    .values()
+                    .filter(|pos| !pos.is_set(ArgSettings::Required))
+                    .filter(|pos| !pos.is_set(ArgSettings::Hidden))
+                    .filter(|pos| !pos.is_set(ArgSettings::Last)) {
+        debugln!("usage::get_args_tag:iter:{}:", pos.b.name);
+        if let Some(g_vec) = p.groups_for_arg(pos.b.name) {
+            for grp_s in &g_vec {
+                debugln!("usage::get_args_tag:iter:{}:iter:{};", pos.b.name, grp_s);
+                // if it's part of a required group we don't want to count it
+                if p.groups.iter().any(|g| g.required && (&g.name == grp_s)) {
+                    continue 'outer;
+                }
+            }
+        }
+        count += 1;
+        debugln!("usage::get_args_tag:iter: {} Args not required or hidden",
+                 count);
+    }
+    if !p.is_set(AS::DontCollapseArgsInUsage) && count > 1 {
+        debugln!("usage::get_args_tag:iter: More than one, returning [ARGS]");
+        return None; // [ARGS]
+    } else if count == 1 && incl_reqs {
+        let pos = p.positionals
+            .values()
+            .find(|pos| {
+                      !pos.is_set(ArgSettings::Required) && !pos.is_set(ArgSettings::Hidden) &&
+                      !pos.is_set(ArgSettings::Last)
+                  })
+            .expect(INTERNAL_ERROR_MSG);
+        debugln!("usage::get_args_tag:iter: Exactly one, returning '{}'",
+                 pos.name());
+        return Some(format!(" [{}]{}", pos.name_no_brackets(), pos.multiple_str()));
+    } else if p.is_set(AS::DontCollapseArgsInUsage) && !p.positionals.is_empty() && incl_reqs {
+        debugln!("usage::get_args_tag:iter: Don't collapse returning all");
+        return Some(p.positionals
+                        .values()
+                        .filter(|pos| !pos.is_set(ArgSettings::Required))
+                        .filter(|pos| !pos.is_set(ArgSettings::Hidden))
+                        .filter(|pos| !pos.is_set(ArgSettings::Last))
+                        .map(|pos| {
+                                 format!(" [{}]{}", pos.name_no_brackets(), pos.multiple_str())
+                             })
+                        .collect::<Vec<_>>()
+                        .join(""));
+    } else if !incl_reqs {
+        debugln!("usage::get_args_tag:iter: incl_reqs=false, building secondary usage string");
+        let highest_req_pos = p.positionals
+            .iter()
+            .filter_map(|(idx, pos)| if pos.b.is_set(ArgSettings::Required) &&
+                                        !pos.b.is_set(ArgSettings::Last) {
+                            Some(idx)
+                        } else {
+                            None
+                        })
+            .max()
+            .unwrap_or(p.positionals.len());
+        return Some(p.positionals
+                        .iter()
+                        .filter_map(|(idx, pos)| if idx <= highest_req_pos {
+                                        Some(pos)
+                                    } else {
+                                        None
+                                    })
+                        .filter(|pos| !pos.is_set(ArgSettings::Required))
+                        .filter(|pos| !pos.is_set(ArgSettings::Hidden))
+                        .filter(|pos| !pos.is_set(ArgSettings::Last))
+                        .map(|pos| {
+                                 format!(" [{}]{}", pos.name_no_brackets(), pos.multiple_str())
+                             })
+                        .collect::<Vec<_>>()
+                        .join(""));
+    }
+    Some("".into())
+}
+
+// Determines if we need the `[FLAGS]` tag in the usage string
+fn needs_flags_tag(p: &Parser) -> bool {
+    debugln!("usage::needs_flags_tag;");
+    'outer: for f in &p.flags {
+        debugln!("usage::needs_flags_tag:iter: f={};", f.b.name);
+        if let Some(l) = f.s.long {
+            if l == "help" || l == "version" {
+                // Don't print `[FLAGS]` just for help or version
+                continue;
+            }
+        }
+        if let Some(g_vec) = p.groups_for_arg(f.b.name) {
+            for grp_s in &g_vec {
+                debugln!("usage::needs_flags_tag:iter:iter: grp_s={};", grp_s);
+                if p.groups.iter().any(|g| &g.name == grp_s && g.required) {
+                    debugln!("usage::needs_flags_tag:iter:iter: Group is required");
+                    continue 'outer;
+                }
+            }
+        }
+        if f.is_set(ArgSettings::Hidden) {
+            continue;
+        }
+        debugln!("usage::needs_flags_tag:iter: [FLAGS] required");
+        return true;
+    }
+
+    debugln!("usage::needs_flags_tag: [FLAGS] not required");
+    false
+}
+
+// Returns the required args in usage string form by fully unrolling all groups
+pub fn get_required_usage_from<'a, 'b>(p: &Parser<'a, 'b>,
+                                       reqs: &[&'a str],
+                                       matcher: Option<&ArgMatcher<'a>>,
+                                       extra: Option<&str>,
+                                       incl_last: bool)
+                                       -> VecDeque<String> {
+    debugln!("usage::get_required_usage_from: reqs={:?}, extra={:?}",
+             reqs,
+             extra);
+    let mut desc_reqs: Vec<&str> = vec![];
+    desc_reqs.extend(extra);
+    let mut new_reqs: Vec<&str> = vec![];
+    macro_rules! get_requires {
+        (@group $a: ident, $v:ident, $p:ident) => {{
+            if let Some(rl) = p.groups.iter()
+                                            .filter(|g| g.requires.is_some())
+                                            .find(|g| &g.name == $a)
+                                            .map(|g| g.requires.as_ref().unwrap()) {
+                for r in rl {
+                    if !$p.contains(&r) {
+                        debugln!("usage::get_required_usage_from:iter:{}: adding group req={:?}",
+                            $a, r);
+                        $v.push(r);
+                    }
+                }
+            }
+        }};
+        ($a:ident, $what:ident, $how:ident, $v:ident, $p:ident) => {{
+            if let Some(rl) = p.$what.$how()
+                                        .filter(|a| a.b.requires.is_some())
+                                        .find(|arg| &arg.b.name == $a)
+                                        .map(|a| a.b.requires.as_ref().unwrap()) {
+                for &(_, r) in rl.iter() {
+                    if !$p.contains(&r) {
+                        debugln!("usage::get_required_usage_from:iter:{}: adding arg req={:?}",
+                            $a, r);
+                        $v.push(r);
+                    }
+                }
+            }
+        }};
+    }
+    // initialize new_reqs
+    for a in reqs {
+        get_requires!(a, flags, iter, new_reqs, reqs);
+        get_requires!(a, opts, iter, new_reqs, reqs);
+        get_requires!(a, positionals, values, new_reqs, reqs);
+        get_requires!(@group a, new_reqs, reqs);
+    }
+    desc_reqs.extend_from_slice(&*new_reqs);
+    debugln!("usage::get_required_usage_from: after init desc_reqs={:?}",
+             desc_reqs);
+    loop {
+        let mut tmp = vec![];
+        for a in &new_reqs {
+            get_requires!(a, flags, iter, tmp, desc_reqs);
+            get_requires!(a, opts, iter, tmp, desc_reqs);
+            get_requires!(a, positionals, values, tmp, desc_reqs);
+            get_requires!(@group a, tmp, desc_reqs);
+        }
+        if tmp.is_empty() {
+            debugln!("usage::get_required_usage_from: no more children");
+            break;
+        } else {
+            debugln!("usage::get_required_usage_from: after iter tmp={:?}", tmp);
+            debugln!("usage::get_required_usage_from: after iter new_reqs={:?}",
+                     new_reqs);
+            desc_reqs.extend_from_slice(&*new_reqs);
+            new_reqs.clear();
+            new_reqs.extend_from_slice(&*tmp);
+            debugln!("usage::get_required_usage_from: after iter desc_reqs={:?}",
+                     desc_reqs);
+        }
+    }
+    desc_reqs.extend_from_slice(reqs);
+    desc_reqs.sort();
+    desc_reqs.dedup();
+    debugln!("usage::get_required_usage_from: final desc_reqs={:?}",
+             desc_reqs);
+    let mut ret_val = VecDeque::new();
+    let args_in_groups = p.groups
+        .iter()
+        .filter(|gn| desc_reqs.contains(&gn.name))
+        .flat_map(|g| p.arg_names_in_group(&g.name))
+        .collect::<Vec<_>>();
+
+    let pmap = if let Some(ref m) = matcher {
+        desc_reqs.iter()
+            .filter(|a| p.positionals.values().any(|p| &&p.b.name == a))
+            .filter(|&pos| !m.contains(pos))
+            .filter_map(|pos| p.positionals.values().find(|x| &x.b.name == pos))
+            .filter(|&pos| incl_last || !pos.is_set(ArgSettings::Last))
+            .filter(|pos| !args_in_groups.contains(&pos.b.name))
+            .map(|pos| (pos.index, pos))
+            .collect::<BTreeMap<u64, &PosBuilder>>() // sort by index
+    } else {
+        desc_reqs.iter()
+            .filter(|a| p.positionals.values().any(|pos| &&pos.b.name == a))
+            .filter_map(|pos| p.positionals.values().find(|x| &x.b.name == pos))
+            .filter(|&pos| incl_last || !pos.is_set(ArgSettings::Last))
+            .filter(|pos| !args_in_groups.contains(&pos.b.name))
+            .map(|pos| (pos.index, pos))
+            .collect::<BTreeMap<u64, &PosBuilder>>() // sort by index
+    };
+    debugln!("usage::get_required_usage_from: args_in_groups={:?}",
+             args_in_groups);
+    for &p in pmap.values() {
+        let s = p.to_string();
+        if args_in_groups.is_empty() || !args_in_groups.contains(&&*s) {
+            ret_val.push_back(s);
+        }
+    }
+    for a in desc_reqs.iter()
+            .filter(|name| !p.positionals.values().any(|p| &&p.b.name == name))
+            .filter(|name| !p.groups.iter().any(|g| &&g.name == name))
+            .filter(|name| !args_in_groups.contains(name))
+            .filter(|name| !(matcher.is_some() && matcher.as_ref().unwrap().contains(name))) {
+        debugln!("usage::get_required_usage_from:iter:{}:", a);
+        let arg = find_by_name!(p, a, flags, iter)
+            .map(|f| f.to_string())
+            .unwrap_or_else(|| {
+                                find_by_name!(p, a, opts, iter)
+                                    .map(|o| o.to_string())
+                                    .expect(INTERNAL_ERROR_MSG)
+                            });
+        ret_val.push_back(arg);
+    }
+    let mut g_vec: Vec<String> = vec![];
+    for g in desc_reqs.iter().filter(|n| p.groups.iter().any(|g| &&g.name == n)) {
+        let g_string = p.args_in_group(g).join("|");
+        let elem = format!("<{}>", &g_string[..g_string.len()]);
+        if !g_vec.contains(&elem) {
+            g_vec.push(elem);
+        }
+    }
+    for g in g_vec {
+        ret_val.push_back(g);
+    }
+
+    ret_val
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/clap/src/app/validator.rs
@@ -0,0 +1,456 @@
+// std
+use std::fmt::Display;
+
+// Internal
+use INTERNAL_ERROR_MSG;
+use INVALID_UTF8;
+use args::{AnyArg, ArgMatcher, MatchedArg};
+use args::settings::ArgSettings;
+use errors::{Error, ErrorKind};
+use errors::Result as ClapResult;
+use osstringext::OsStrExt2;
+use app::settings::AppSettings as AS;
+use app::parser::{Parser, ParseResult};
+use fmt::Colorizer;
+use app::usage;
+
+pub struct Validator<'a, 'b, 'z>(&'z mut Parser<'a, 'b>)
+    where 'a: 'b,
+          'b: 'z;
+
+impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
+    pub fn new(p: &'z mut Parser<'a, 'b>) -> Self { Validator(p) }
+
+    pub fn validate(&mut self,
+                    needs_val_of: ParseResult<'a>,
+                    subcmd_name: Option<String>,
+                    matcher: &mut ArgMatcher<'a>)
+                    -> ClapResult<()> {
+        debugln!("Validator::validate;");
+        let mut reqs_validated = false;
+        try!(self.0.add_defaults(matcher));
+        if let ParseResult::Opt(a) = needs_val_of {
+            debugln!("Validator::validate: needs_val_of={:?}", a);
+            let o = self.0
+                .opts
+                .iter()
+                .find(|o| o.b.name == a)
+                .expect(INTERNAL_ERROR_MSG);
+            try!(self.validate_required(matcher));
+            reqs_validated = true;
+            let should_err = if let Some(v) = matcher.0.args.get(&*o.b.name) {
+                v.vals.is_empty() && !(o.v.min_vals.is_some() && o.v.min_vals.unwrap() == 0)
+            } else {
+                true
+            };
+            if should_err {
+                return Err(Error::empty_value(o,
+                                              &*usage::create_error_usage(self.0, matcher, None),
+                                              self.0.color()));
+            }
+        }
+
+        if matcher.is_empty() && matcher.subcommand_name().is_none() &&
+           self.0.is_set(AS::ArgRequiredElseHelp) {
+            let mut out = vec![];
+            try!(self.0.write_help_err(&mut out));
+            return Err(Error {
+                           message: String::from_utf8_lossy(&*out).into_owned(),
+                           kind: ErrorKind::MissingArgumentOrSubcommand,
+                           info: None,
+                       });
+        }
+        try!(self.validate_blacklist(matcher));
+        if !(self.0.is_set(AS::SubcommandsNegateReqs) && subcmd_name.is_some()) && !reqs_validated {
+            try!(self.validate_required(matcher));
+        }
+        try!(self.validate_matched_args(matcher));
+        matcher.usage(usage::create_usage_with_title(self.0, &[]));
+
+        Ok(())
+    }
+
+    fn validate_values<A>(&self,
+                          arg: &A,
+                          ma: &MatchedArg,
+                          matcher: &ArgMatcher<'a>)
+                          -> ClapResult<()>
+        where A: AnyArg<'a, 'b> + Display
+    {
+        debugln!("Validator::validate_values: arg={:?}", arg.name());
+        for val in &ma.vals {
+            if self.0.is_set(AS::StrictUtf8) && val.to_str().is_none() {
+                debugln!("Validator::validate_values: invalid UTF-8 found in val {:?}",
+                         val);
+                return Err(Error::invalid_utf8(&*usage::create_error_usage(self.0, matcher, None),
+                                               self.0.color()));
+            }
+            if let Some(p_vals) = arg.possible_vals() {
+                debugln!("Validator::validate_values: possible_vals={:?}", p_vals);
+                let val_str = val.to_string_lossy();
+                if !p_vals.contains(&&*val_str) {
+                    return Err(Error::invalid_value(val_str,
+                                                    p_vals,
+                                                    arg,
+                                                    &*usage::create_error_usage(self.0,
+                                                                                matcher,
+                                                                                None),
+                                                    self.0.color()));
+                }
+            }
+            if !arg.is_set(ArgSettings::EmptyValues) && val.is_empty_() &&
+               matcher.contains(&*arg.name()) {
+                debugln!("Validator::validate_values: illegal empty val found");
+                return Err(Error::empty_value(arg,
+                                              &*usage::create_error_usage(self.0, matcher, None),
+                                              self.0.color()));
+            }
+            if let Some(vtor) = arg.validator() {
+                debug!("Validator::validate_values: checking validator...");
+                if let Err(e) = vtor(val.to_string_lossy().into_owned()) {
+                    sdebugln!("error");
+                    return Err(Error::value_validation(Some(arg), e, self.0.color()));
+                } else {
+                    sdebugln!("good");
+                }
+            }
+            if let Some(vtor) = arg.validator_os() {
+                debug!("Validator::validate_values: checking validator_os...");
+                if let Err(e) = vtor(val) {
+                    sdebugln!("error");
+                    return Err(Error::value_validation(Some(arg),
+                                                       (*e).to_string_lossy().to_string(),
+                                                       self.0.color()));
+                } else {
+                    sdebugln!("good");
+                }
+            }
+        }
+        Ok(())
+    }
+
+    fn validate_blacklist(&self, matcher: &mut ArgMatcher) -> ClapResult<()> {
+        debugln!("Validator::validate_blacklist: blacklist={:?}",
+                 self.0.blacklist);
+        macro_rules! build_err {
+            ($p:expr, $name:expr, $matcher:ident) => ({
+                debugln!("build_err!: name={}", $name);
+                let mut c_with = find_from!($p, $name, blacklist, &$matcher);
+                c_with = c_with.or(
+                    $p.find_any_arg($name).map_or(None, |aa| aa.blacklist())
+                                           .map_or(None, 
+                                                |bl| bl.iter().find(|arg| $matcher.contains(arg)))
+                                           .map_or(None, |an| $p.find_any_arg(an))
+                                           .map_or(None, |aa| Some(format!("{}", aa)))
+                );
+                debugln!("build_err!: '{:?}' conflicts with '{}'", c_with, $name);
+                $matcher.remove($name);
+                let usg = usage::create_error_usage($p, $matcher, None);
+                if let Some(f) = find_by_name!($p, $name, flags, iter) {
+                    debugln!("build_err!: It was a flag...");
+                    Error::argument_conflict(f, c_with, &*usg, self.0.color())
+                } else if let Some(o) = find_by_name!($p, $name, opts, iter) {
+                   debugln!("build_err!: It was an option...");
+                    Error::argument_conflict(o, c_with, &*usg, self.0.color())
+                } else {
+                    match find_by_name!($p, $name, positionals, values) {
+                        Some(p) => {
+                            debugln!("build_err!: It was a positional...");
+                            Error::argument_conflict(p, c_with, &*usg, self.0.color())
+                        },
+                        None    => panic!(INTERNAL_ERROR_MSG)
+                    }
+                }
+            });
+        }
+
+        for name in &self.0.blacklist {
+            debugln!("Validator::validate_blacklist:iter: Checking blacklisted name: {}",
+                     name);
+            if self.0.groups.iter().any(|g| &g.name == name) {
+                debugln!("Validator::validate_blacklist:iter: groups contains it...");
+                for n in self.0.arg_names_in_group(name) {
+                    debugln!("Validator::validate_blacklist:iter:iter: Checking arg '{}' in group...",
+                             n);
+                    if matcher.contains(n) {
+                        debugln!("Validator::validate_blacklist:iter:iter: matcher contains it...");
+                        return Err(build_err!(self.0, &n, matcher));
+                    }
+                }
+            } else if matcher.contains(name) {
+                debugln!("Validator::validate_blacklist:iter: matcher contains it...");
+                return Err(build_err!(self.0, name, matcher));
+            }
+        }
+        Ok(())
+    }
+
+    fn validate_matched_args(&self, matcher: &mut ArgMatcher<'a>) -> ClapResult<()> {
+        debugln!("Validator::validate_matched_args;");
+        for (name, ma) in matcher.iter() {
+            debugln!("Validator::validate_matched_args:iter:{}: vals={:#?}",
+                     name,
+                     ma.vals);
+            if let Some(opt) = find_by_name!(self.0, name, opts, iter) {
+                try!(self.validate_arg_num_vals(opt, ma, matcher));
+                try!(self.validate_values(opt, ma, matcher));
+                try!(self.validate_arg_requires(opt, ma, matcher));
+                try!(self.validate_arg_num_occurs(opt, ma, matcher));
+            } else if let Some(flag) = find_by_name!(self.0, name, flags, iter) {
+                try!(self.validate_arg_requires(flag, ma, matcher));
+                try!(self.validate_arg_num_occurs(flag, ma, matcher));
+            } else if let Some(pos) = find_by_name!(self.0, name, positionals, values) {
+                try!(self.validate_arg_num_vals(pos, ma, matcher));
+                try!(self.validate_arg_num_occurs(pos, ma, matcher));
+                try!(self.validate_values(pos, ma, matcher));
+                try!(self.validate_arg_requires(pos, ma, matcher));
+            } else {
+                let grp = self.0
+                    .groups
+                    .iter()
+                    .find(|g| &g.name == name)
+                    .expect(INTERNAL_ERROR_MSG);
+                if let Some(ref g_reqs) = grp.requires {
+                    if g_reqs.iter().any(|&n| !matcher.contains(n)) {
+                        return self.missing_required_error(matcher, None);
+                    }
+                }
+            }
+        }
+        Ok(())
+    }
+
+    fn validate_arg_num_occurs<A>(&self,
+                                  a: &A,
+                                  ma: &MatchedArg,
+                                  matcher: &ArgMatcher)
+                                  -> ClapResult<()>
+        where A: AnyArg<'a, 'b> + Display
+    {
+        debugln!("Validator::validate_arg_num_occurs: a={};", a.name());
+        if ma.occurs > 1 && !a.is_set(ArgSettings::Multiple) {
+            // Not the first time, and we don't allow multiples
+            return Err(Error::unexpected_multiple_usage(a,
+                                                        &*usage::create_error_usage(self.0,
+                                                                                    matcher,
+                                                                                    None),
+                                                        self.0.color()));
+        }
+        Ok(())
+    }
+
+    fn validate_arg_num_vals<A>(&self,
+                                a: &A,
+                                ma: &MatchedArg,
+                                matcher: &ArgMatcher)
+                                -> ClapResult<()>
+        where A: AnyArg<'a, 'b> + Display
+    {
+        debugln!("Validator::validate_arg_num_vals;");
+        if let Some(num) = a.num_vals() {
+            debugln!("Validator::validate_arg_num_vals: num_vals set...{}", num);
+            let should_err = if a.is_set(ArgSettings::Multiple) {
+                ((ma.vals.len() as u64) % num) != 0
+            } else {
+                num != (ma.vals.len() as u64)
+            };
+            if should_err {
+                debugln!("Validator::validate_arg_num_vals: Sending error WrongNumberOfValues");
+                return Err(Error::wrong_number_of_values(a,
+                                                         num,
+                                                         if a.is_set(ArgSettings::Multiple) {
+                                                             (ma.vals.len() % num as usize)
+                                                         } else {
+                                                             ma.vals.len()
+                                                         },
+                                                         if ma.vals.len() == 1 ||
+                                                            (a.is_set(ArgSettings::Multiple) &&
+                                                             (ma.vals.len() % num as usize) ==
+                                                             1) {
+                                                             "as"
+                                                         } else {
+                                                             "ere"
+                                                         },
+                                                         &*usage::create_error_usage(self.0,
+                                                                                     matcher,
+                                                                                     None),
+                                                         self.0.color()));
+            }
+        }
+        if let Some(num) = a.max_vals() {
+            debugln!("Validator::validate_arg_num_vals: max_vals set...{}", num);
+            if (ma.vals.len() as u64) > num {
+                debugln!("Validator::validate_arg_num_vals: Sending error TooManyValues");
+                return Err(Error::too_many_values(ma.vals
+                                                      .iter()
+                                                      .last()
+                                                      .expect(INTERNAL_ERROR_MSG)
+                                                      .to_str()
+                                                      .expect(INVALID_UTF8),
+                                                  a,
+                                                  &*usage::create_error_usage(self.0,
+                                                                              matcher,
+                                                                              None),
+                                                  self.0.color()));
+            }
+        }
+        if let Some(num) = a.min_vals() {
+            debugln!("Validator::validate_arg_num_vals: min_vals set: {}", num);
+            if (ma.vals.len() as u64) < num {
+                debugln!("Validator::validate_arg_num_vals: Sending error TooFewValues");
+                return Err(Error::too_few_values(a,
+                                                 num,
+                                                 ma.vals.len(),
+                                                 &*usage::create_error_usage(self.0,
+                                                                             matcher,
+                                                                             None),
+                                                 self.0.color()));
+            }
+        }
+        // Issue 665 (https://github.com/kbknapp/clap-rs/issues/665)
+        if a.takes_value() && !a.is_set(ArgSettings::EmptyValues) && ma.vals.is_empty() {
+            return Err(Error::empty_value(a,
+                                          &*usage::create_error_usage(self.0, matcher, None),
+                                          self.0.color()));
+        }
+        Ok(())
+    }
+
+    fn validate_arg_requires<A>(&self,
+                                a: &A,
+                                ma: &MatchedArg,
+                                matcher: &ArgMatcher)
+                                -> ClapResult<()>
+        where A: AnyArg<'a, 'b> + Display
+    {
+        debugln!("Validator::validate_arg_requires;");
+        if let Some(a_reqs) = a.requires() {
+            for &(val, name) in a_reqs.iter().filter(|&&(val, _)| val.is_some()) {
+                let missing_req =
+                    |v| v == val.expect(INTERNAL_ERROR_MSG) && !matcher.contains(name);
+                if ma.vals.iter().any(missing_req) {
+                    return self.missing_required_error(matcher, None);
+                }
+            }
+        }
+        Ok(())
+    }
+
+    fn validate_required(&self, matcher: &ArgMatcher) -> ClapResult<()> {
+        debugln!("Validator::validate_required: required={:?};",
+                 self.0.required);
+        'outer: for name in &self.0.required {
+            debugln!("Validator::validate_required:iter:{}:", name);
+            if matcher.contains(name) {
+                continue 'outer;
+            }
+            if let Some(a) = find_by_name!(self.0, name, flags, iter) {
+                if self.is_missing_required_ok(a, matcher) {
+                    continue 'outer;
+                }
+            } else if let Some(a) = find_by_name!(self.0, name, opts, iter) {
+                if self.is_missing_required_ok(a, matcher) {
+                    continue 'outer;
+                }
+            } else if let Some(a) = find_by_name!(self.0, name, positionals, values) {
+                if self.is_missing_required_ok(a, matcher) {
+                    continue 'outer;
+                }
+            }
+            return self.missing_required_error(matcher, None);
+        }
+
+        // Validate the conditionally required args
+        for &(a, v, r) in &self.0.r_ifs {
+            if let Some(ma) = matcher.get(a) {
+                if matcher.get(r).is_none() && ma.vals.iter().any(|val| val == v) {
+                    return self.missing_required_error(matcher, Some(r));
+                }
+            }
+        }
+        Ok(())
+    }
+
+    fn validate_conflicts<A>(&self, a: &A, matcher: &ArgMatcher) -> Option<bool>
+        where A: AnyArg<'a, 'b>
+    {
+        debugln!("Validator::validate_conflicts: a={:?};", a.name());
+        a.blacklist()
+            .map(|bl| {
+                bl.iter()
+                    .any(|conf| {
+                        matcher.contains(conf) ||
+                        self.0
+                            .groups
+                            .iter()
+                            .find(|g| &g.name == conf)
+                            .map_or(false, |g| g.args.iter().any(|arg| matcher.contains(arg)))
+                    })
+            })
+    }
+
+    fn validate_required_unless<A>(&self, a: &A, matcher: &ArgMatcher) -> Option<bool>
+        where A: AnyArg<'a, 'b>
+    {
+        debugln!("Validator::validate_required_unless: a={:?};", a.name());
+        macro_rules! check {
+            ($how:ident, $_self:expr, $a:ident, $m:ident) => {{
+                $a.required_unless().map(|ru| {
+                    ru.iter().$how(|n| {
+                        $m.contains(n) || {
+                            if let Some(grp) = $_self.groups.iter().find(|g| &g.name == n) {
+                                     grp.args.iter().any(|arg| $m.contains(arg))
+                            } else {
+                                false
+                            }
+                        }
+                    })
+                })
+            }}; 
+        }
+        if a.is_set(ArgSettings::RequiredUnlessAll) {
+            check!(all, self.0, a, matcher)
+        } else {
+            check!(any, self.0, a, matcher)
+        }
+    }
+
+    fn missing_required_error(&self, matcher: &ArgMatcher, extra: Option<&str>) -> ClapResult<()> {
+        debugln!("Validator::missing_required_error: extra={:?}", extra);
+        let c = Colorizer {
+            use_stderr: true,
+            when: self.0.color(),
+        };
+        let mut reqs = self.0
+            .required
+            .iter()
+            .map(|&r| &*r)
+            .collect::<Vec<_>>();
+        if let Some(r) = extra {
+            reqs.push(r);
+        }
+        reqs.retain(|n| !matcher.contains(n));
+        reqs.dedup();
+        debugln!("Validator::missing_required_error: reqs={:#?}", reqs);
+        let req_args =
+            usage::get_required_usage_from(self.0, &reqs[..], Some(matcher), extra, true)
+                .iter()
+                .fold(String::new(),
+                      |acc, s| acc + &format!("\n    {}", c.error(s))[..]);
+        debugln!("Validator::missing_required_error: req_args={:#?}",
+                 req_args);
+        Err(Error::missing_required_argument(&*req_args,
+                                             &*usage::create_error_usage(self.0, matcher, extra),
+                                             self.0.color()))
+    }
+
+    #[inline]
+    fn is_missing_required_ok<A>(&self, a: &A, matcher: &ArgMatcher) -> bool
+        where A: AnyArg<'a, 'b>
+    {
+        debugln!("Validator::is_missing_required_ok: a={}", a.name());
+        self.validate_conflicts(a, matcher).unwrap_or(false) ||
+        self.validate_required_unless(a, matcher)
+            .unwrap_or(false)
+    }
+}
\ No newline at end of file
--- a/third_party/rust/clap/src/args/any_arg.rs
+++ b/third_party/rust/clap/src/args/any_arg.rs
@@ -3,22 +3,20 @@ use std::rc::Rc;
 use std::fmt as std_fmt;
 use std::ffi::{OsStr, OsString};
 
 // Third Party
 use vec_map::{self, VecMap};
 
 // Internal
 use args::settings::ArgSettings;
-use args::ArgKind;
 
 #[doc(hidden)]
 pub trait AnyArg<'n, 'e>: std_fmt::Display {
     fn name(&self) -> &'n str;
-    fn id(&self) -> usize;
     fn overrides(&self) -> Option<&[&'e str]>;
     fn aliases(&self) -> Option<Vec<&'e str>>;
     fn requires(&self) -> Option<&[(Option<&'e str>, &'n str)]>;
     fn blacklist(&self) -> Option<&[&'e str]>;
     fn required_unless(&self) -> Option<&[&'e str]>;
     fn is_set(&self, ArgSettings) -> bool;
     fn set(&mut self, ArgSettings);
     fn has_switch(&self) -> bool;
@@ -29,18 +27,18 @@ pub trait AnyArg<'n, 'e>: std_fmt::Displ
     fn validator(&self) -> Option<&Rc<Fn(String) -> Result<(), String>>>;
     fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> Result<(), OsString>>>;
     fn short(&self) -> Option<char>;
     fn long(&self) -> Option<&'e str>;
     fn val_delim(&self) -> Option<char>;
     fn takes_value(&self) -> bool;
     fn val_names(&self) -> Option<&VecMap<&'e str>>;
     fn help(&self) -> Option<&'e str>;
-    fn default_val(&self) -> Option<&'n str>;
-    fn default_vals_ifs(&self) -> Option<vec_map::Values<(&'n str, Option<&'e str>, &'e str)>>;
+    fn long_help(&self) -> Option<&'e str>;
+    fn default_val(&self) -> Option<&'e OsStr>;
+    fn default_vals_ifs(&self) -> Option<vec_map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>>;
     fn longest_filter(&self) -> bool;
-    fn kind(&self) -> ArgKind;
     fn val_terminator(&self) -> Option<&'e str>;
 }
 
 pub trait DispOrder {
     fn disp_ord(&self) -> usize;
 }
--- a/third_party/rust/clap/src/args/arg.rs
+++ b/third_party/rust/clap/src/args/arg.rs
@@ -1,19 +1,25 @@
 #[cfg(feature = "yaml")]
 use std::collections::BTreeMap;
 use std::rc::Rc;
 use std::ffi::{OsString, OsStr};
+#[cfg(target_os="windows")]
+use osstringext::OsStrExt3;
+#[cfg(not(target_os="windows"))]
+use std::os::unix::ffi::OsStrExt;
+
 
 #[cfg(feature = "yaml")]
 use yaml_rust::Yaml;
 use vec_map::VecMap;
 
 use usage_parser::UsageParser;
-use args::settings::{ArgFlags, ArgSettings};
+use args::settings::ArgSettings;
+use args::arg_builder::{Base, Valued, Switched};
 
 /// The abstract representation of a command line argument. Used to set all the options and
 /// relationships that define a valid argument for the program.
 ///
 /// There are two methods for constructing [`Arg`]s, using the builder pattern and setting options
 /// manually, or using a usage string which is far less verbose but has fewer options. You can also
 /// use a combination of the two methods to achieve the best of both worlds.
 ///
@@ -28,104 +34,32 @@ use args::settings::{ArgFlags, ArgSettin
 ///       .takes_value(true)
 ///       .value_name("FILE")
 ///       .help("Provides a config file to myprog");
 /// // Using a usage string (setting a similar argument to the one above)
 /// let input = Arg::from_usage("-i, --input=[FILE] 'Provides an input file to the program'");
 /// ```
 /// [`Arg`]: ./struct.Arg.html
 #[allow(missing_debug_implementations)]
+#[derive(Default, Clone)]
 pub struct Arg<'a, 'b>
     where 'a: 'b
 {
     #[doc(hidden)]
-    pub name: &'a str,
-    #[doc(hidden)]
-    pub short: Option<char>,
+    pub b: Base<'a, 'b>,
     #[doc(hidden)]
-    pub long: Option<&'b str>,
+    pub s: Switched<'b>,
     #[doc(hidden)]
-    pub aliases: Option<Vec<(&'b str, bool)>>, // (name, visible)
-    #[doc(hidden)]
-    pub help: Option<&'b str>,
+    pub v: Valued<'a, 'b>,
     #[doc(hidden)]
     pub index: Option<u64>,
     #[doc(hidden)]
-    pub blacklist: Option<Vec<&'a str>>,
-    #[doc(hidden)]
-    pub possible_vals: Option<Vec<&'b str>>,
-    #[doc(hidden)]
-    pub requires: Option<Vec<(Option<&'b str>, &'a str)>>,
-    #[doc(hidden)]
-    pub groups: Option<Vec<&'a str>>,
-    #[doc(hidden)]
-    pub val_names: Option<VecMap<&'b str>>,
-    #[doc(hidden)]
-    pub num_vals: Option<u64>,
-    #[doc(hidden)]
-    pub max_vals: Option<u64>,
-    #[doc(hidden)]
-    pub min_vals: Option<u64>,
-    #[doc(hidden)]
-    pub validator: Option<Rc<Fn(String) -> Result<(), String>>>,
-    #[doc(hidden)]
-    pub validator_os: Option<Rc<Fn(&OsStr) -> Result<(), OsString>>>,
-    #[doc(hidden)]
-    pub overrides: Option<Vec<&'a str>>,
-    #[doc(hidden)]
-    pub settings: ArgFlags,
-    #[doc(hidden)]
-    pub val_delim: Option<char>,
-    #[doc(hidden)]
-    pub default_val: Option<&'a str>,
-    #[doc(hidden)]
-    pub default_vals_ifs: Option<VecMap<(&'a str, Option<&'b str>, &'b str)>>,
-    #[doc(hidden)]
-    pub disp_ord: usize,
-    #[doc(hidden)]
-    pub r_unless: Option<Vec<&'a str>>,
-    #[doc(hidden)]
     pub r_ifs: Option<Vec<(&'a str, &'b str)>>,
-    #[doc(hidden)]
-    pub val_terminator: Option<&'b str>,
 }
 
-impl<'a, 'b> Default for Arg<'a, 'b> {
-    fn default() -> Self {
-        Arg {
-            name: "".as_ref(),
-            short: None,
-            long: None,
-            aliases: None,
-            help: None,
-            index: None,
-            blacklist: None,
-            possible_vals: None,
-            requires: None,
-            groups: None,
-            val_names: None,
-            num_vals: None,
-            max_vals: None,
-            min_vals: None,
-            validator: None,
-            validator_os: None,
-            overrides: None,
-            settings: ArgFlags::new(),
-            val_delim: None,
-            default_val: None,
-            default_vals_ifs: None,
-            disp_ord: 999,
-            r_unless: None,
-            r_ifs: None,
-            val_terminator: None,
-        }
-    }
-}
-
-
 impl<'a, 'b> Arg<'a, 'b> {
     /// Creates a new instance of [`Arg`] using a unique string name. The name will be used to get
     /// information about whether or not the argument was used at runtime, get values, set
     /// relationships with other args, etc..
     ///
     /// **NOTE:** In the case of arguments that take values (i.e. [`Arg::takes_value(true)`])
     /// and positional arguments (i.e. those without a preceding `-` or `--`) the name will also
     /// be displayed when the user prints the usage/help information of the program.
@@ -134,17 +68,17 @@ impl<'a, 'b> Arg<'a, 'b> {
     ///
     /// ```rust
     /// # use clap::{App, Arg};
     /// Arg::with_name("config")
     /// # ;
     /// ```
     /// [`Arg::takes_value(true)`]: ./struct.Arg.html#method.takes_value
     /// [`Arg`]: ./struct.Arg.html
-    pub fn with_name(n: &'a str) -> Self { Arg { name: n, ..Default::default() } }
+    pub fn with_name(n: &'a str) -> Self { Arg { b: Base::new(n), ..Default::default() } }
 
     /// Creates a new instance of [`Arg`] from a .yml (YAML) file.
     ///
     /// # Examples
     ///
     /// ```ignore
     /// # #[macro_use]
     /// # extern crate clap;
@@ -164,16 +98,17 @@ impl<'a, 'b> Arg<'a, 'b> {
         let arg_settings = y.get(name_yml).unwrap().as_hash().unwrap();
 
         for (k, v) in arg_settings.iter() {
             a = match k.as_str().unwrap() {
                 "short" => yaml_to_str!(a, v, short),
                 "long" => yaml_to_str!(a, v, long),
                 "aliases" => yaml_vec_or_str!(v, a, alias),
                 "help" => yaml_to_str!(a, v, help),
+                "long_help" => yaml_to_str!(a, v, long_help),
                 "required" => yaml_to_bool!(a, v, required),
                 "required_if" => yaml_tuple2!(a, v, required_if),
                 "required_ifs" => yaml_tuple2!(a, v, required_if),
                 "takes_value" => yaml_to_bool!(a, v, takes_value),
                 "index" => yaml_to_u64!(a, v, index),
                 "global" => yaml_to_bool!(a, v, global),
                 "multiple" => yaml_to_bool!(a, v, multiple),
                 "hidden" => yaml_to_bool!(a, v, hidden),
@@ -334,17 +269,17 @@ impl<'a, 'b> Arg<'a, 'b> {
     /// be used multiple times. Do not confuse multiple occurrences (`...`) with multiple values.
     /// `--option val1 val2` is a single occurrence with multiple values. `--flag --flag` is
     /// multiple occurrences (and then you can obviously have instances of both as well)
     ///
     /// # Examples
     ///
     /// ```rust
     /// # use clap::{App, Arg};
-    /// App::new("myprog")
+    /// App::new("prog")
     ///     .args(&[
     ///         Arg::from_usage("--config <FILE> 'a required file for the configuration and no short'"),
     ///         Arg::from_usage("-d, --debug... 'turns on debugging information and allows multiples'"),
     ///         Arg::from_usage("[input] 'an optional input file to use'")
     /// ])
     /// # ;
     /// ```
     /// [`Arg`]: ./struct.Arg.html
@@ -375,28 +310,28 @@ impl<'a, 'b> Arg<'a, 'b> {
     ///     .short("c")
     /// # ;
     /// ```
     ///
     /// Setting [`short`] allows using the argument via a single hyphen (`-`) such as `-c`
     ///
     /// ```rust
     /// # use clap::{App, Arg};
-    /// let m = App::new("shorttest")
+    /// let m = App::new("prog")
     ///     .arg(Arg::with_name("config")
     ///         .short("c"))
     ///     .get_matches_from(vec![
-    ///         "shorttest", "-c"
+    ///         "prog", "-c"
     ///     ]);
     ///
     /// assert!(m.is_present("config"));
     /// ```
     /// [`short`]: ./struct.Arg.html#method.short
     pub fn short<S: AsRef<str>>(mut self, s: S) -> Self {
-        self.short = s.as_ref().trim_left_matches(|c| c == '-').chars().nth(0);
+        self.s.short = s.as_ref().trim_left_matches(|c| c == '-').chars().nth(0);
         self
     }
 
     /// Sets the long version of the argument without the preceding `--`.
     ///
     /// By default `clap` automatically assigns `version` and `help` to the auto-generated
     /// `version` and `help` arguments respectively. You may use the word `version` or `help` for
     /// the long form of your own arguments, in which case `clap` simply will not assign those to
@@ -416,144 +351,158 @@ impl<'a, 'b> Arg<'a, 'b> {
     ///     .long("config")
     /// # ;
     /// ```
     ///
     /// Setting `long` allows using the argument via a double hyphen (`--`) such as `--config`
     ///
     /// ```rust
     /// # use clap::{App, Arg};
-    /// let m = App::new("longtest")
+    /// let m = App::new("prog")
     ///     .arg(Arg::with_name("cfg")
     ///         .long("config"))
     ///     .get_matches_from(vec![
-    ///         "longtest", "--config"
+    ///         "prog", "--config"
     ///     ]);
     ///
     /// assert!(m.is_present("cfg"));
     /// ```
     pub fn long(mut self, l: &'b str) -> Self {
-        self.long = Some(l.trim_left_matches(|c| c == '-'));
+        self.s.long = Some(l.trim_left_matches(|c| c == '-'));
         self
     }
 
     /// Allows adding a [`Arg`] alias, which function as "hidden" arguments that
     /// automatically dispatch as if this argument was used. This is more efficient, and easier
     /// than creating multiple hidden arguments as one only needs to check for the existence of
     /// this command, and not all variants.
     ///
     /// # Examples
     ///
     /// ```rust
     /// # use clap::{App, Arg};
-    /// let m = App::new("myprog")
+    /// let m = App::new("prog")
     ///             .arg(Arg::with_name("test")
     ///             .long("test")
     ///             .alias("alias")
     ///             .takes_value(true))
-    ///        .get_matches_from(vec!["myprog", "--alias", "cool"]);
+    ///        .get_matches_from(vec![
+    ///             "prog", "--alias", "cool"
+    ///         ]);
     /// assert!(m.is_present("test"));
     /// assert_eq!(m.value_of("test"), Some("cool"));
     /// ```
     /// [`Arg`]: ./struct.Arg.html
     pub fn alias<S: Into<&'b str>>(mut self, name: S) -> Self {
-        if let Some(ref mut als) = self.aliases {
+        if let Some(ref mut als) = self.s.aliases {
             als.push((name.into(), false));
         } else {
-            self.aliases = Some(vec![(name.into(), false)]);
+            self.s.aliases = Some(vec![(name.into(), false)]);
         }
         self
     }
 
     /// Allows adding [`Arg`] aliases, which function as "hidden" arguments that
     /// automatically dispatch as if this argument was used. This is more efficient, and easier
     /// than creating multiple hidden subcommands as one only needs to check for the existence of
     /// this command, and not all variants.
     ///
     /// # Examples
     ///
     /// ```rust
     /// # use clap::{App, Arg};
-    /// let m = App::new("myprog")
+    /// let m = App::new("prog")
     ///             .arg(Arg::with_name("test")
     ///                     .long("test")
     ///                     .aliases(&["do-stuff", "do-tests", "tests"])
     ///                     .help("the file to add")
     ///                     .required(false))
-    ///             .get_matches_from(vec!["myprog", "--do-tests"]);
+    ///             .get_matches_from(vec![
+    ///                 "prog", "--do-tests"
+    ///             ]);
     /// assert!(m.is_present("test"));
     /// ```
     /// [`Arg`]: ./struct.Arg.html
     pub fn aliases(mut self, names: &[&'b str]) -> Self {
-        if let Some(ref mut als) = self.aliases {
+        if let Some(ref mut als) = self.s.aliases {
             for n in names {
                 als.push((n, false));
             }
         } else {
-            self.aliases = Some(names.iter().map(|n| (*n, false)).collect::<Vec<_>>());
+            self.s.aliases = Some(names.iter().map(|n| (*n, false)).collect::<Vec<_>>());
         }
         self
     }
 
     /// Allows adding a [`Arg`] alias that functions exactly like those defined with
     /// [`Arg::alias`], except that they are visible inside the help message.
     ///
     /// # Examples
     ///
     /// ```rust
     /// # use clap::{App, Arg};
-    /// let m = App::new("myprog")
+    /// let m = App::new("prog")
     ///             .arg(Arg::with_name("test")
     ///                 .visible_alias("something-awesome")
     ///                 .long("test")
     ///                 .takes_value(true))
-    ///        .get_matches_from(vec!["myprog", "--something-awesome", "coffee"]);
+    ///        .get_matches_from(vec![
+    ///             "prog", "--something-awesome", "coffee"
+    ///         ]);
     /// assert!(m.is_present("test"));
     /// assert_eq!(m.value_of("test"), Some("coffee"));
     /// ```
     /// [`Arg`]: ./struct.Arg.html
     /// [`App::alias`]: ./struct.Arg.html#method.alias
     pub fn visible_alias<S: Into<&'b str>>(mut self, name: S) -> Self {
-        if let Some(ref mut als) = self.aliases {
+        if let Some(ref mut als) = self.s.aliases {
             als.push((name.into(), true));
         } else {
-            self.aliases = Some(vec![(name.into(), true)]);
+            self.s.aliases = Some(vec![(name.into(), true)]);
         }
         self
     }
 
     /// Allows adding multiple [`Arg`] aliases that functions exactly like those defined
     /// with [`Arg::aliases`], except that they are visible inside the help message.
     ///
     /// # Examples
     ///
     /// ```rust
     /// # use clap::{App, Arg};
-    /// let m = App::new("myprog")
+    /// let m = App::new("prog")
     ///             .arg(Arg::with_name("test")
     ///                 .long("test")
     ///                 .visible_aliases(&["something", "awesome", "cool"]))
-    ///        .get_matches_from(vec!["myprog", "--awesome"]);
+    ///        .get_matches_from(vec![
+    ///             "prog", "--awesome"
+    ///         ]);
     /// assert!(m.is_present("test"));
     /// ```
     /// [`Arg`]: ./struct.Arg.html
     /// [`App::aliases`]: ./struct.Arg.html#method.aliases
     pub fn visible_aliases(mut self, names: &[&'b str]) -> Self {
-        if let Some(ref mut als) = self.aliases {
+        if let Some(ref mut als) = self.s.aliases {
             for n in names {
                 als.push((n, true));
             }
         } else {
-            self.aliases = Some(names.iter().map(|n| (*n, true)).collect::<Vec<_>>());
+            self.s.aliases = Some(names.iter().map(|n| (*n, true)).collect::<Vec<_>>());
         }
         self
     }
 
-    /// Sets the help text of the argument that will be displayed to the user when they print the
-    /// usage/help information.
+    /// Sets the short help text of the argument that will be displayed to the user when they print
+    /// the help information with `-h`. Typically, this is a short (one line) description of the
+    /// arg.
+    ///
+    /// **NOTE:** If only `Arg::help` is provided, and not [`Arg::long_help`] but the user requests
+    /// `--help` clap will still display the contents of `help` appropriately
+    ///
+    /// **NOTE:** Only `Arg::help` is used in completion script generation in order to be concise
     ///
     /// # Examples
     ///
     /// Any valid UTF-8 is allowed in the help text. The one exception is when one wishes to
     /// include a newline in the help text and have the following text be properly aligned with all
     /// the other help text.
     ///
     /// ```rust
@@ -563,43 +512,195 @@ impl<'a, 'b> Arg<'a, 'b> {
     /// # ;
     /// ```
     ///
     /// Setting `help` displays a short message to the side of the argument when the user passes
     /// `-h` or `--help` (by default).
     ///
     /// ```rust
     /// # use clap::{App, Arg};
-    /// let m = App::new("helptest")
+    /// let m = App::new("prog")
     ///     .arg(Arg::with_name("cfg")
     ///         .long("config")
     ///         .help("Some help text describing the --config arg"))
     ///     .get_matches_from(vec![
-    ///         "shorttest", "--help"
+    ///         "prog", "--help"
     ///     ]);
     /// ```
     ///
     /// The above example displays
     ///
     /// ```notrust
     /// helptest
     ///
     /// USAGE:
     ///    helptest [FLAGS]
     ///
     /// FLAGS:
     ///     --config     Some help text describing the --config arg
     /// -h, --help       Prints help information
     /// -V, --version    Prints version information
     /// ```
+    /// [`Arg::long_help`]: ./struct.Arg.html#method.long_help
     pub fn help(mut self, h: &'b str) -> Self {
-        self.help = Some(h);
+        self.b.help = Some(h);
+        self
+    }
+
+    /// Sets the long help text of the argument that will be displayed to the user when they print
+    /// the help information with `--help`. Typically this a more detailed (multi-line) message
+    /// that describes the arg.
+    ///
+    /// **NOTE:** If only `long_help` is provided, and not [`Arg::help`] but the user requests `-h`
+    /// clap will still display the contents of `long_help` appropriately
+    ///
+    /// **NOTE:** Only [`Arg::help`] is used in completion script generation in order to be concise
+    ///
+    /// # Examples
+    ///
+    /// Any valid UTF-8 is allowed in the help text. The one exception is when one wishes to
+    /// include a newline in the help text and have the following text be properly aligned with all
+    /// the other help text.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg};
+    /// Arg::with_name("config")
+    ///     .long_help(
+    /// "The config file used by the myprog must be in JSON format
+    /// with only valid keys and may not contain other nonsense
+    /// that cannot be read by this program. Obviously I'm going on
+    /// and on, so I'll stop now.")
+    /// # ;
+    /// ```
+    ///
+    /// Setting `help` displays a short message to the side of the argument when the user passes
+    /// `-h` or `--help` (by default).
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg};
+    /// let m = App::new("prog")
+    ///     .arg(Arg::with_name("cfg")
+    ///         .long("config")
+    ///         .long_help(
+    /// "The config file used by the myprog must be in JSON format
+    /// with only valid keys and may not contain other nonsense
+    /// that cannot be read by this program. Obviously I'm going on
+    /// and on, so I'll stop now."))
+    ///     .get_matches_from(vec![
+    ///         "prog", "--help"
+    ///     ]);
+    /// ```
+    ///
+    /// The above example displays
+    ///
+    /// ```notrust
+    /// helptest
+    ///
+    /// USAGE:
+    ///    helptest [FLAGS]
+    ///
+    /// FLAGS:
+    ///    --config
+    ///         The config file used by the myprog must be in JSON format
+    ///         with only valid keys and may not contain other nonsense
+    ///         that cannot be read by this program. Obviously I'm going on
+    ///         and on, so I'll stop now.
+    ///
+    /// -h, --help       
+    ///         Prints help information
+    ///
+    /// -V, --version    
+    ///         Prints version information
+    /// ```
+    /// [`Arg::help`]: ./struct.Arg.html#method.help
+    pub fn long_help(mut self, h: &'b str) -> Self {
+        self.b.long_help = Some(h);
         self
     }
 
+    /// Specifies that this arg is the last, or final, positional argument (i.e. has the highest
+    /// index) and is *only* able to be accessed via the `--` syntax (i.e. `$ prog args --
+    /// last_arg`). Even, if no other arguments are left to parse, if the user omits the `--` syntax
+    /// they will receive an [`UnknownArgument`] error. Setting an argument to `.last(true)` also
+    /// allows one to access this arg early using the `--` syntax. Accessing an arg early, even with
+    /// the `--` syntax is otherwise not possible.
+    ///
+    /// **NOTE:** This will change the usage string to look like `$ prog [FLAGS] [-- <ARG>]` if 
+    /// `ARG` is marked as `.last(true)`.
+    ///
+    /// **NOTE:** This setting will imply [`AppSettings::DontCollapseArgsInUsage`] because failing
+    /// to set this can make the usage string very confusing.
+    ///
+    /// **NOTE**: This setting only applies to positional arguments, and has no affect on FLAGS / 
+    /// OPTIONS
+    ///
+    /// **CAUTION:** Setting an argument to `.last(true)` *and* having child subcommands is not
+    /// recommended with the exception of *also* using [`AppSettings::ArgsNegateSubcommands`]
+    /// (or [`AppSettings::SubcommandsNegateReqs`] if the argument marked `.last(true)` is also
+    /// marked [`.required(true)`])
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::Arg;
+    /// Arg::with_name("args")
+    ///     .last(true)
+    /// # ;
+    /// ```
+    ///
+    /// Setting [`Arg::last(true)`] ensures the arg has the highest [index] of all positional args
+    /// and requires that the `--` syntax be used to access it early.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg};
+    /// let res = App::new("prog")
+    ///     .arg(Arg::with_name("first"))
+    ///     .arg(Arg::with_name("second"))
+    ///     .arg(Arg::with_name("third").last(true))
+    ///     .get_matches_from_safe(vec![
+    ///         "prog", "one", "--", "three"
+    ///     ]);
+    ///
+    /// assert!(res.is_ok());
+    /// let m = res.unwrap();
+    /// assert_eq!(m.value_of("third"), Some("three"));
+    /// assert!(m.value_of("second").is_none());
+    /// ```
+    ///
+    /// Even if the positional argument marked `.last(true)` is the only argument left to parse,
+    /// failing to use the `--` syntax results in an error.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ErrorKind};
+    /// let res = App::new("prog")
+    ///     .arg(Arg::with_name("first"))
+    ///     .arg(Arg::with_name("second"))
+    ///     .arg(Arg::with_name("third").last(true))
+    ///     .get_matches_from_safe(vec![
+    ///         "prog", "one", "two", "three"
+    ///     ]);
+    ///
+    /// assert!(res.is_err());
+    /// assert_eq!(res.unwrap_err().kind, ErrorKind::UnknownArgument);
+    /// ```
+    /// [`Arg::last(true)`]: ./struct.Arg.html#method.last
+    /// [index]: ./struct.Arg.html#method.index
+    /// [`AppSettings::DontCollapseArgsInUsage`]: ./enum.AppSettings.html#variant.DontCollapseArgsInUsage
+    /// [`AppSettings::ArgsNegateSubcommands`]: ./enum.AppSettings.html#variant.ArgsNegateSubcommands
+    /// [`AppSettings::SubcommandsNegateReqs`]: ./enum.AppSettings.html#variant.SubcommandsNegateReqs
+    /// [`.required(true)`]: ./struct.Arg.html#method.required
+    /// [`UnknownArgument`]: ./enum.ErrorKind.html#variant.UnknownArgument
+    pub fn last(self, l: bool) -> Self {
+        if l {
+            self.set(ArgSettings::Last)
+        } else {
+            self.unset(ArgSettings::Last)
+        }
+    }
+
     /// Sets whether or not the argument is required by default. Required by default means it is
     /// required, when no other conflicting rules have been evaluated. Conflicting rules take
     /// precedence over being required. **Default:** `false`
     ///
     /// **NOTE:** Flags (i.e. not positional, or arguments that take values) cannot be required by
     /// default. This is simply because if a flag should be required, it should simply be implied
     /// as no additional information is required from user. Flags by their very nature are simply
     /// yes/no, or true/false.
@@ -612,55 +713,123 @@ impl<'a, 'b> Arg<'a, 'b> {
     ///     .required(true)
     /// # ;
     /// ```
     ///
     /// Setting [`Arg::required(true)`] requires that the argument be used at runtime.
     ///
     /// ```rust
     /// # use clap::{App, Arg};
-    /// let res = App::new("longtest")
+    /// let res = App::new("prog")
     ///     .arg(Arg::with_name("cfg")
     ///         .required(true)
     ///         .takes_value(true)
     ///         .long("config"))
     ///     .get_matches_from_safe(vec![
-    ///         "shorttest", "--config", "file.conf"
+    ///         "prog", "--config", "file.conf"
     ///     ]);
     ///
     /// assert!(res.is_ok());
     /// ```
     ///
     /// Setting [`Arg::required(true)`] and *not* supplying that argument is an error.
     ///
     /// ```rust
     /// # use clap::{App, Arg, ErrorKind};
-    /// let res = App::new("longtest")
+    /// let res = App::new("prog")
     ///     .arg(Arg::with_name("cfg")
     ///         .required(true)
     ///         .takes_value(true)
     ///         .long("config"))
     ///     .get_matches_from_safe(vec![
-    ///         "shorttest"
+    ///         "prog"
     ///     ]);
     ///
     /// assert!(res.is_err());
     /// assert_eq!(res.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
     /// ```
     /// [`Arg::required(true)`]: ./struct.Arg.html#method.required
     pub fn required(self, r: bool) -> Self {
         if r {
             self.set(ArgSettings::Required)
         } else {
             self.unset(ArgSettings::Required)
         }
     }
 
+    /// Requires that options use the `--option=val` syntax (i.e. an equals between the option and
+    /// associated value) **Default:** `false`
+    ///
+    /// **NOTE:** This setting also removes the default of allowing empty values and implies
+    /// [`Arg::empty_values(false)`].
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::Arg;
+    /// Arg::with_name("config")
+    ///     .long("config")
+    ///     .takes_value(true)
+    ///     .require_equals(true)
+    /// # ;
+    /// ```
+    ///
+    /// Setting [`Arg::require_equals(true)`] requires that the option have an equals sign between
+    /// it and the associated value.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg};
+    /// let res = App::new("prog")
+    ///     .arg(Arg::with_name("cfg")
+    ///         .require_equals(true)
+    ///         .takes_value(true)
+    ///         .long("config"))
+    ///     .get_matches_from_safe(vec![
+    ///         "prog", "--config=file.conf"
+    ///     ]);
+    ///
+    /// assert!(res.is_ok());
+    /// ```
+    ///
+    /// Setting [`Arg::require_equals(true)`] and *not* supplying the equals will cause an error
+    /// unless [`Arg::empty_values(true)`] is set.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ErrorKind};
+    /// let res = App::new("prog")
+    ///     .arg(Arg::with_name("cfg")
+    ///         .require_equals(true)
+    ///         .takes_value(true)
+    ///         .long("config"))
+    ///     .get_matches_from_safe(vec![
+    ///         "prog", "--config", "file.conf"
+    ///     ]);
+    ///
+    /// assert!(res.is_err());
+    /// assert_eq!(res.unwrap_err().kind, ErrorKind::EmptyValue);
+    /// ```
+    /// [`Arg::require_equals(true)`]: ./struct.Arg.html#method.require_equals
+    /// [`Arg::empty_values(true)`]: ./struct.Arg.html#method.empty_values
+    /// [`Arg::empty_values(false)`]: ./struct.Arg.html#method.empty_values
+    pub fn require_equals(mut self, r: bool) -> Self {
+        if r {
+            self.unsetb(ArgSettings::EmptyValues);
+            self.set(ArgSettings::RequireEquals