Import structopt-0.3.14 am: 32e766957b am: 0ca5ae57f2

Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/structopt/+/1322972

Change-Id: I04a88df355a17e7b2ad61615d0cadf399576f834
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
new file mode 100644
index 0000000..2df1587
--- /dev/null
+++ b/.cargo_vcs_info.json
@@ -0,0 +1,5 @@
+{
+  "git": {
+    "sha1": "203c6bc19e561da1734873794bbd420e0bfc79b9"
+  }
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4467abb
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+target
+Cargo.lock
+*~
+expanded.rs
+
+.idea/
+.vscode/
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..14f5a6c
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,35 @@
+if: type != push OR branch = master
+
+language: rust
+matrix:
+  include:
+    - rust: stable
+      name: check if `cargo fmt --all` is applied
+      before_script: rustup component add rustfmt-preview
+      script: cargo fmt --all -- --check
+
+    - language: node_js
+      node_js: node
+      name: check links
+      install: npm install -g markdown-link-check
+      script:
+        - markdown-link-check -c link-check-headers.json README.md
+        - markdown-link-check -c link-check-headers.json CHANGELOG.md
+        - markdown-link-check -c link-check-headers.json examples/README.md
+
+    - rust: stable
+      name: clippy
+      before_script: rustup component add clippy
+      script: cargo clippy --all -- -D warnings
+
+    - rust: 1.36.0
+    - rust: stable
+    - rust: beta
+    - rust: nightly
+
+script:
+  - cargo test
+
+jobs:
+  allow_failures:
+    - name: clippy
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..22dca96
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,480 @@
+# v0.3.14 (2020-04-22)
+
+* Minor documentation improvements.
+
+# v0.3.13 (2020-04-9)
+
+* Bump `proc-macro-error` to `1.0`.
+
+# v0.3.12 (2020-03-18)
+
+* Fixed [bug in `external_subcommand`](https://github.com/TeXitoi/structopt/issues/359).
+
+# v0.3.11 (2020-03-01)
+
+* `syn`'s "full" feature is now explicitly enabled. It must have been, but hasn't.
+
+# v0.3.10 (2020-03-01) - YANKED
+
+* Fixed the breakage due to a required `syn` feature was not enabled.
+
+# v0.3.9 (2020-02-01) - YANKED
+
+* `clippy` warnings triggered by generated code shall not annoy you anymore!
+  Except for those from `clippy::correctness`, these lints are useful even
+  for auto generated code.
+* Improved error messages.
+
+# v0.3.8 (2020-1-19) - YANKED
+
+* You don't have to apply `#[no_version]` to every `enum` variant anymore.
+  Just annotate the `enum` and the setting will be propagated down
+  ([#242](https://github.com/TeXitoi/structopt/issues/242)).
+* [Auto-default](https://docs.rs/structopt/0.3/structopt/#default-values).
+* [External subcommands](https://docs.rs/structopt/0.3/structopt/#external-subcommands).
+* [Flattening subcommands](https://docs.rs/structopt/0.3.8/structopt/#flattening-subcommands).
+
+# v0.3.7 (2019-12-28)
+
+Nothing's new. Just re-release of `v0.3.6` due to
+[the mess with versioning](https://github.com/TeXitoi/structopt/issues/315#issuecomment-568502792).
+
+You may notice that `structopt-derive` was bumped to `v0.4.0`, that's OK, it's not a breaking change.
+`structopt` will pull the right version in on its on.
+
+# v0.3.6 (2019-12-22) - YANKED
+
+This is unusually big patch release. It contains a number of bugfixes and
+new features, some of them may theoretically be considered breaking. We did our best
+to avoid any problems on user's side but, if it wasn't good enough, please
+[file an issue ASAP](https://github.com/TeXitoi/structopt/issues).
+
+## Bugfixes
+
+* `structopt` used to treat `::path::to::type::Vec<T>` as `Vec<T>`
+  special type. [This was considered erroneous](https://github.com/TeXitoi/structopt/pull/287).
+  (same for `Option<T>` and `bool`). Now only exact `Vec<T>` match is a special type.
+
+* `#[structopt(version = expr)]` where `expr` is not a string literal used to get
+  overridden by auto generated `.version()` call,
+  [incorrectly](https://github.com/TeXitoi/structopt/issues/283). Now it doesn't.
+
+* Fixed bug with top-level `App::*` calls on multiple `struct`s, see
+  [#289](https://github.com/TeXitoi/structopt/issues/265).
+
+* Positional `bool` args with no explicit `#[structopt(parse(...))]` annotation are
+  now prohibited. This couldn't work well anyway, see
+  [this example](https://github.com/TeXitoi/structopt/blob/master/examples/true_or_false.rs)
+  for details.
+
+* Now we've instituted strict priority between doc comments, about, help, and the like.
+  See [the documentation](https://docs.rs/structopt/0.3/structopt/#help-messages).
+
+  **HUGE THANKS to [`@ssokolow`](https://github.com/ssokolow)** for tidying up our documentation,
+  teaching me English and explaining why our doc used to suck. I promise I'll make the rest
+  of the doc up to your standards... sometime later!
+
+## New features
+
+* Implement `StructOpt` for `Box<impl StructOpt>` so from now on you can use `Box<T>`
+  with `flatten` and `subcommand` ([#304](https://github.com/TeXitoi/structopt/issues/304)).
+
+  ```rust
+  enum Command {
+      #[structopt(name = "version")]
+      PrintVersion,
+
+      #[structopt(name = "second")]
+      DoSomething {
+          #[structopt(flatten)]
+          config: Box<DoSomethingConfig>,
+      },
+
+      #[structopt(name = "first")]
+      DoSomethingElse {
+          #[structopt(flatten)]
+          config: Box<DoSomethingElseConfig>,
+      }
+  }
+  ```
+
+* Introduced `#[structopt(verbatim_doc_comment)]` attribute that keeps line breaks in
+  doc comments, see
+  [the documentation](https://docs.rs/structopt/0.3/structopt/#doc-comment-preprocessing-and-structoptverbatim_doc_comment).
+
+* Introduced `#[structopt(rename_all_env)]` and `#[structopt(env)]` magical methods
+  so you can derive env var's name from field's name. See
+  [the documentation](https://docs.rs/structopt/0.3/structopt/#auto-deriving-environment-variables).
+
+## Improvements
+
+* Now we have nice README for our examples,
+  [check it out](https://github.com/TeXitoi/structopt/tree/master/examples)!
+
+* Some error messages were improved and clarified, thanks for all people involved!
+
+
+# v0.3.5 (2019-11-22)
+
+* `try_from_str` functions are now called with a `&str` instead of a `&String` ([#282](https://github.com/TeXitoi/structopt/pull/282))
+
+# v0.3.4 (2019-11-08)
+
+* `rename_all` does not apply to fields that were annotated with explicit
+  `short/long/name = "..."` anymore ([#265](https://github.com/TeXitoi/structopt/issues/265))
+* Now raw idents are handled correctly ([#269](https://github.com/TeXitoi/structopt/issues/269))
+* Some documentation improvements and clarification.
+
+# v0.3.3 (2019-10-10)
+
+* Add `from_flag` custom parser to create flags from non-bool types.
+  Fixes [#185](https://github.com/TeXitoi/structopt/issues/185)
+
+# v0.3.2 (2019-09-18)
+
+* `structopt` does not replace `:` with `, ` inside "author" strings while inside `<...>`.
+  Fixes [#156](https://github.com/TeXitoi/structopt/issues/156)
+* Introduced [`#[structopt(skip = expr)]` syntax](https://docs.rs/structopt/0.3.2/structopt/#skipping-fields).
+
+# v0.3.1 (2019-09-06)
+
+* Fix error messages ([#241](https://github.com/TeXitoi/structopt/issues/241))
+* Fix "`skip` plus long doc comment" bug ([#245](https://github.com/TeXitoi/structopt/issues/245))
+* Now `structopt` emits dummy `StructOpt` implementation along with an error. It suppresses
+  meaningless errors like `from_args method is not found for Opt`
+* `.version()` not get generated if `CARGO_PKG_VERSION` is not set anymore.
+
+# v0.3.0 (2019-08-30)
+
+## Breaking changes
+
+### Bump minimum rustc version to 1.36 by [@TeXitoi](https://github.com/TeXitoi)
+Now `rustc` 1.36 is the minimum compiler version supported by `structopt`,
+it likely won't work with older compilers.
+
+### Remove "nightly" feature
+Once upon a time this feature had been used to enable some of improvements
+in `proc-macro2` crate that were available only on nightly. Nowadays this feature doesn't
+mean anything so it's now removed.
+
+### Support optional vectors of arguments for distinguishing between `-o 1 2`, `-o` and no option provided at all by [@sphynx](https://github.com/sphynx) ([#180](https://github.com/TeXitoi/structopt/issues/188)).
+
+```rust
+#[derive(StructOpt)]
+struct Opt {
+  #[structopt(long)]
+  fruit: Option<Vec<String>>,
+}
+
+fn main() {
+  assert_eq!(Opt::from_args(&["test"]), None);
+  assert_eq!(Opt::from_args(&["test", "--fruit"]), Some(vec![]));
+  assert_eq!(Opt::from_args(&["test", "--fruit=apple orange"]), Some(vec!["apple", "orange"]));
+}
+```
+
+If you need to fall back to the old behavior you can use a type alias:
+```rust
+type Something = Vec<String>;
+
+#[derive(StructOpt)]
+struct Opt {
+  #[structopt(long)]
+  fruit: Option<Something>,
+}
+```
+
+### Change default case from 'Verbatim' into 'Kebab' by [@0ndorio](https://github.com/0ndorio) ([#202](https://github.com/TeXitoi/structopt/issues/202)).
+`structopt` 0.3 uses field renaming to deduce a name for long options and subcommands.
+
+```rust
+#[derive(StructOpt)]
+struct Opt {
+  #[structopt(long)]
+  http_addr: String, // will be renamed to `--http-addr`
+
+  #[structopt(subcommand)]
+  addr_type: AddrType // this adds `addr-type` subcommand
+}
+```
+
+`structopt` 0.2 used to leave things "as is", not renaming anything. If you want to keep old
+behavior add `#[structopt(rename_all = "verbatim")]` on top of a `struct`/`enum`.
+
+### Change `version`, `author` and `about` attributes behavior.
+Proposed by [@TeXitoi](https://github.com/TeXitoi) [(#217)](https://github.com/TeXitoi/structopt/issues/217), implemented by [@CreepySkeleton](https://github.com/CreepySkeleton) [(#229)](https://github.com/TeXitoi/structopt/pull/229).
+
+`structopt` have been deducing `version`, `author`, and `about` properties from `Cargo.toml`
+for a long time (more accurately, from `CARGO_PKG_...` environment variables).
+But many users found this behavior somewhat confusing, and a hack was added to cancel out
+this behavior: `#[structopt(author = "")]`.
+
+In `structopt` 0.3 this has changed.
+* `author` and `about` are no longer deduced by default. You should use `#[structopt(author, about)]`
+  to explicitly request `structopt` to deduce them.
+* Contrary, `version` **is still deduced by default**. You can use `#[structopt(no_version)]` to
+  cancel it out.
+* `#[structopt(author = "", about = "", version = "")]` is no longer a valid syntax
+  and will trigger an error.
+* `#[structopt(version = "version", author = "author", about = "about")]` syntax
+  stays unaffected by this changes.
+
+### Raw attributes are removed ([#198](https://github.com/TeXitoi/structopt/pull/198)) by [@sphynx](https://github.com/sphynx)
+In `structopt` 0.2 you were able to use any method from `clap::App` and `clap::Arg` via
+raw attribute: `#[structopt(raw(method_name = "arg"))]`. This syntax was kind of awkward.
+
+```rust
+#[derive(StructOpt, Debug)]
+#[structopt(raw(
+    global_settings = "&[AppSettings::ColoredHelp, AppSettings::VersionlessSubcommands]"
+))]
+struct Opt {
+    #[structopt(short = "l", long = "level", raw(aliases = r#"&["set-level", "lvl"]"#))]
+    level: Vec<String>,
+}
+```
+
+Raw attributes were removed in 0.3. Now you can use any method from `App` and `Arg` *directly*:
+```rust
+#[derive(StructOpt)]
+#[structopt(global_settings(&[AppSettings::ColoredHelp, AppSettings::VersionlessSubcommands]))]
+struct Opt {
+    #[structopt(short = "l", long = "level", aliases(&["set-level", "lvl"]))]
+    level: Vec<String>,
+}
+```
+
+## Improvements
+
+### Support skipping struct fields
+Proposed by [@Morganamilo](https://github.com/Morganamilo) in ([#174](https://github.com/TeXitoi/structopt/issues/174))
+implemented by [@sphynx](https://github.com/sphynx) in ([#213](https://github.com/TeXitoi/structopt/issues/213)).
+
+Sometimes you want to include some fields in your `StructOpt` `struct` that are not options
+and `clap` should know nothing about them. In `structopt` 0.3 it's possible via the
+`#[structopt(skip)]` attribute. The field in question will be assigned with `Default::default()`
+value.
+
+```rust
+#[derive(StructOpt)]
+struct Opt {
+    #[structopt(short, long)]
+    speed: f32,
+
+    car: String,
+
+    // this field should not generate any arguments
+    #[structopt(skip)]
+    meta: Vec<u64>
+}
+```
+
+### Add optional feature to support `paw` by [@gameldar](https://github.com/gameldar) ([#187](https://github.com/TeXitoi/structopt/issues/187))
+
+### Significantly improve error reporting by [@CreepySkeleton](https://github.com/CreepySkeleton) ([#225](https://github.com/TeXitoi/structopt/pull/225/))
+Now (almost) every error message points to the location it originates from:
+
+```text
+error: default_value is meaningless for bool
+  --> $DIR/bool_default_value.rs:14:24
+   |
+14 |     #[structopt(short, default_value = true)]
+   |                        ^^^^^^^^^^^^^
+```
+
+# v0.2.16 (2019-05-29)
+
+### Support optional options with optional argument, allowing `cmd [--opt[=value]]` by [@sphynx](https://github.com/sphynx) ([#188](https://github.com/TeXitoi/structopt/issues/188))
+Sometimes you want to represent an optional option that optionally takes an argument,
+i.e `[--opt[=value]]`. This is represented by `Option<Option<T>>`
+
+```rust
+#[derive(StructOpt)]
+struct Opt {
+  #[structopt(long)]
+  fruit: Option<Option<String>>,
+}
+
+fn main() {
+  assert_eq!(Opt::from_args(&["test"]), None);
+  assert_eq!(Opt::from_args(&["test", "--fruit"]), Some(None));
+  assert_eq!(Opt::from_args(&["test", "--fruit=apple"]), Some("apple"));
+}
+```
+
+# v0.2.15 (2019-03-08)
+
+* Fix [#168](https://github.com/TeXitoi/structopt/issues/168) by [@TeXitoi](https://github.com/TeXitoi)
+
+# v0.2.14 (2018-12-10)
+
+* Introduce smarter parsing of doc comments by [@0ndorio](https://github.com/0ndorio)
+
+# v0.2.13 (2018-11-01)
+
+* Automatic naming of fields and subcommands by [@0ndorio](https://github.com/0ndorio)
+
+# v0.2.12 (2018-10-11)
+
+* Fix minimal clap version by [@TeXitoi](https://github.com/TeXitoi)
+
+# v0.2.11 (2018-10-05)
+
+* Upgrade syn to 0.15 by [@konstin](https://github.com/konstin)
+
+# v0.2.10 (2018-06-07)
+
+* 1.21.0 is the minimum required rustc version by
+  [@TeXitoi](https://github.com/TeXitoi)
+
+# v0.2.9 (2018-06-05)
+
+* Fix a bug when using `flatten` by
+  [@fbenkstein](https://github.com/fbenkstein)
+* Update syn, quote and proc_macro2 by
+  [@TeXitoi](https://github.com/TeXitoi)
+* Fix a regression when there is multiple authors by
+  [@windwardly](https://github.com/windwardly)
+
+# v0.2.8 (2018-04-28)
+
+* Add `StructOpt::from_iter_safe()`, which returns an `Error` instead of
+  killing the program when it fails to parse, or parses one of the
+  short-circuiting flags. ([#98](https://github.com/TeXitoi/structopt/pull/98)
+  by [@quodlibetor](https://github.com/quodlibetor))
+* Allow users to enable `clap` features independently by
+  [@Kerollmops](https://github.com/Kerollmops)
+* Fix a bug when flattening an enum
+  ([#103](https://github.com/TeXitoi/structopt/pull/103) by
+  [@TeXitoi](https://github.com/TeXitoi)
+
+# v0.2.7 (2018-04-12)
+
+* Add flattening, the insertion of options of another StructOpt struct
+  into another ([#92](https://github.com/TeXitoi/structopt/pull/92))
+  by [@birkenfeld](https://github.com/birkenfeld)
+* Fail compilation when using `default_value` or `required` with
+  `Option` ([#88](https://github.com/TeXitoi/structopt/pull/88)) by
+  [@Kerollmops](https://github.com/Kerollmops)
+
+# v0.2.6 (2018-03-31)
+
+* Fail compilation when using `default_value` or `required` with `bool` ([#80](https://github.com/TeXitoi/structopt/issues/80)) by [@TeXitoi](https://github.com/TeXitoi)
+* Fix compilation with `#[deny(warnings)]` with the `!` type (https://github.com/rust-lang/rust/pull/49039#issuecomment-376398999) by [@TeXitoi](https://github.com/TeXitoi)
+* Improve first example in the documentation ([#82](https://github.com/TeXitoi/structopt/issues/82)) by [@TeXitoi](https://github.com/TeXitoi)
+
+# v0.2.5 (2018-03-07)
+
+* Work around breakage when `proc-macro2`'s nightly feature is enabled. ([#77](https://github.com/Texitoi/structopt/pull/77) and [proc-macro2#67](https://github.com/alexcrichton/proc-macro2/issues/67)) by [@fitzgen](https://github.com/fitzgen)
+
+# v0.2.4 (2018-02-25)
+
+* Fix compilation with `#![deny(missig_docs]` ([#74](https://github.com/TeXitoi/structopt/issues/74)) by [@TeXitoi](https://github.com/TeXitoi)
+* Fix [#76](https://github.com/TeXitoi/structopt/issues/76) by [@TeXitoi](https://github.com/TeXitoi)
+* Re-licensed to Apache-2.0/MIT by [@CAD97](https://github.com/cad97)
+
+# v0.2.3 (2018-02-16)
+
+* An empty line in a doc comment will result in a double linefeed in the generated about/help call by [@TeXitoi](https://github.com/TeXitoi)
+
+# v0.2.2 (2018-02-12)
+
+* Fix [#66](https://github.com/TeXitoi/structopt/issues/66) by [@TeXitoi](https://github.com/TeXitoi)
+
+# v0.2.1 (2018-02-11)
+
+* Fix a bug around enum tuple and the about message in the global help by [@TeXitoi](https://github.com/TeXitoi)
+* Fix [#65](https://github.com/TeXitoi/structopt/issues/65) by [@TeXitoi](https://github.com/TeXitoi)
+
+# v0.2.0 (2018-02-10)
+
+## Breaking changes
+
+### Don't special case `u64` by [@SergioBenitez](https://github.com/SergioBenitez)
+
+If you are using a `u64` in your struct to get the number of occurence of a flag, you should now add `parse(from_occurrences)` on the flag.
+
+For example
+```rust
+#[structopt(short = "v", long = "verbose")]
+verbose: u64,
+```
+must be changed by
+```rust
+#[structopt(short = "v", long = "verbose", parse(from_occurrences))]
+verbose: u64,
+```
+
+This feature was surprising as shown in [#30](https://github.com/TeXitoi/structopt/issues/30). Using the `parse` feature seems much more natural.
+
+### Change the signature of `Structopt::from_clap` to take its argument by reference by [@TeXitoi](https://github.com/TeXitoi)
+
+There was no reason to take the argument by value. Most of the StructOpt users will not be impacted by this change. If you are using `StructOpt::from_clap`, just add a `&` before the argument.
+
+### Fail if attributes are not used by [@TeXitoi](https://github.com/TeXitoi)
+
+StructOpt was quite fuzzy in its attribute parsing: it was only searching for interresting things, e. g. something like `#[structopt(foo(bar))]` was accepted but not used. It now fails the compilation.
+
+You should have nothing to do here. This breaking change may highlight some missuse that can be bugs.
+
+In future versions, if there is cases that are not highlighed, they will be considerated as bugs, not breaking changes.
+
+### Use `raw()` wrapping instead of `_raw` suffixing by [@TeXitoi](https://github.com/TeXitoi)
+
+The syntax of raw attributes is changed to improve the syntax.
+
+You have to change `foo_raw = "bar", baz_raw = "foo"` by `raw(foo = "bar", baz = "foo")` or `raw(foo = "bar"), raw(baz = "foo")`.
+
+## New features
+
+* Add `parse(from_occurrences)` parser by [@SergioBenitez](https://github.com/SergioBenitez)
+* Support 1-uple enum variant as subcommand by [@TeXitoi](https://github.com/TeXitoi)
+* structopt-derive crate is now an implementation detail, structopt reexport the custom derive macro by [@TeXitoi](https://github.com/TeXitoi)
+* Add the `StructOpt::from_iter` method by [@Kerollmops](https://github.com/Kerollmops)
+
+## Documentation
+
+* Improve doc by [@bestouff](https://github.com/bestouff)
+* All the documentation is now on the structopt crate by [@TeXitoi](https://github.com/TeXitoi)
+
+# v0.1.7 (2018-01-23)
+
+* Allow opting out of clap default features by [@ski-csis](https://github.com/ski-csis)
+
+# v0.1.6 (2017-11-25)
+
+* Improve documentation by [@TeXitoi](https://github.com/TeXitoi)
+* Fix bug [#31](https://github.com/TeXitoi/structopt/issues/31) by [@TeXitoi](https://github.com/TeXitoi)
+
+# v0.1.5 (2017-11-14)
+
+* Fix a bug with optional subsubcommand and Enum by [@TeXitoi](https://github.com/TeXitoi)
+
+# v0.1.4 (2017-11-09)
+
+* Implement custom string parser from either `&str` or `&OsStr` by [@kennytm](https://github.com/kennytm)
+
+# v0.1.3 (2017-11-01)
+
+* Improve doc by [@TeXitoi](https://github.com/TeXitoi)
+
+# v0.1.2 (2017-11-01)
+
+* Fix bugs [#24](https://github.com/TeXitoi/structopt/issues/24) and [#25](https://github.com/TeXitoi/structopt/issues/25) by [@TeXitoi](https://github.com/TeXitoi)
+* Support of methods with something else that a string as argument thanks to `_raw` suffix by [@Flakebi](https://github.com/Flakebi)
+
+# v0.1.1 (2017-09-22)
+
+* Better formating of multiple authors by [@killercup](https://github.com/killercup)
+
+# v0.1.0 (2017-07-17)
+
+* Subcommand support by [@williamyaoh](https://github.com/williamyaoh)
+
+# v0.0.5 (2017-06-16)
+
+* Using doc comment to populate help by [@killercup](https://github.com/killercup)
+
+# v0.0.3 (2017-02-11)
+
+* First version with flags, arguments and options support by [@TeXitoi](https://github.com/TeXitoi)
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..28d6d4b
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,53 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+edition = "2018"
+name = "structopt"
+version = "0.3.14"
+authors = ["Guillaume Pinot <texitoi@texitoi.eu>", "others"]
+description = "Parse command line argument by defining a struct."
+documentation = "https://docs.rs/structopt"
+readme = "README.md"
+keywords = ["clap", "cli", "derive", "docopt"]
+categories = ["command-line-interface"]
+license = "Apache-2.0/MIT"
+repository = "https://github.com/TeXitoi/structopt"
+[dependencies.clap]
+version = "2.33"
+default-features = false
+
+[dependencies.lazy_static]
+version = "1.4.0"
+
+[dependencies.structopt-derive]
+version = "=0.4.7"
+[dev-dependencies.rustversion]
+version = "1"
+
+[dev-dependencies.trybuild]
+version = "1.0.5"
+features = ["diff"]
+
+[features]
+color = ["clap/color"]
+debug = ["clap/debug"]
+default = ["clap/default"]
+doc = ["clap/doc"]
+lints = ["clap/lints"]
+no_cargo = ["clap/no_cargo"]
+paw = ["structopt-derive/paw"]
+suggestions = ["clap/suggestions"]
+wrap_help = ["clap/wrap_help"]
+yaml = ["clap/yaml"]
+[badges.travis-ci]
+repository = "TeXitoi/structopt"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
new file mode 100644
index 0000000..12b2dbe
--- /dev/null
+++ b/Cargo.toml.orig
@@ -0,0 +1,36 @@
+[package]
+name = "structopt"
+version = "0.3.14"
+edition = "2018"
+authors = ["Guillaume Pinot <texitoi@texitoi.eu>", "others"]
+description = "Parse command line argument by defining a struct."
+documentation = "https://docs.rs/structopt"
+repository = "https://github.com/TeXitoi/structopt"
+keywords = ["clap", "cli", "derive", "docopt"]
+categories = ["command-line-interface"]
+license = "Apache-2.0/MIT"
+readme = "README.md"
+
+[features]
+default = ["clap/default"]
+suggestions = ["clap/suggestions"]
+color = ["clap/color"]
+wrap_help = ["clap/wrap_help"]
+yaml = ["clap/yaml"]
+lints = ["clap/lints"]
+debug = ["clap/debug"]
+no_cargo = ["clap/no_cargo"]
+doc = ["clap/doc"]
+paw = ["structopt-derive/paw"]
+
+[badges]
+travis-ci = { repository = "TeXitoi/structopt" }
+
+[dependencies]
+clap = { version = "2.33", default-features = false }
+structopt-derive = { path = "structopt-derive", version = "=0.4.7" }
+lazy_static = "1.4.0"
+
+[dev-dependencies]
+trybuild = { version = "1.0.5", features = ["diff"] }
+rustversion = "1"
diff --git a/LICENSE-APACHE b/LICENSE-APACHE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/LICENSE-APACHE
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/LICENSE-MIT b/LICENSE-MIT
new file mode 100644
index 0000000..e931b83
--- /dev/null
+++ b/LICENSE-MIT
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+
+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.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..48ac3c3
--- /dev/null
+++ b/README.md
@@ -0,0 +1,148 @@
+# StructOpt [![Build status](https://travis-ci.org/TeXitoi/structopt.svg?branch=master)](https://travis-ci.org/TeXitoi/structopt) [![](https://img.shields.io/crates/v/structopt.svg)](https://crates.io/crates/structopt) [![](https://docs.rs/structopt/badge.svg)](https://docs.rs/structopt)
+
+Parse command line arguments by defining a struct.  It combines [clap](https://crates.io/crates/clap) with custom derive.
+
+## Documentation
+
+Find it on [Docs.rs](https://docs.rs/structopt).  You can also check the [examples](https://github.com/TeXitoi/structopt/tree/master/examples) and the [changelog](https://github.com/TeXitoi/structopt/blob/master/CHANGELOG.md).
+
+## Example
+
+Add `structopt` to your dependencies of your `Cargo.toml`:
+```toml
+[dependencies]
+structopt = "0.3"
+```
+
+And then, in your rust file:
+```rust
+use std::path::PathBuf;
+use structopt::StructOpt;
+
+/// A basic example
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+    // A flag, true if used in the command line. Note doc comment will
+    // be used for the help message of the flag. The name of the
+    // argument will be, by default, based on the name of the field.
+    /// Activate debug mode
+    #[structopt(short, long)]
+    debug: bool,
+
+    // The number of occurrences of the `v/verbose` flag
+    /// Verbose mode (-v, -vv, -vvv, etc.)
+    #[structopt(short, long, parse(from_occurrences))]
+    verbose: u8,
+
+    /// Set speed
+    #[structopt(short, long, default_value = "42")]
+    speed: f64,
+
+    /// Output file
+    #[structopt(short, long, parse(from_os_str))]
+    output: PathBuf,
+
+    // the long option will be translated by default to kebab case,
+    // i.e. `--nb-cars`.
+    /// Number of cars
+    #[structopt(short = "c", long)]
+    nb_cars: Option<i32>,
+
+    /// admin_level to consider
+    #[structopt(short, long)]
+    level: Vec<String>,
+
+    /// Files to process
+    #[structopt(name = "FILE", parse(from_os_str))]
+    files: Vec<PathBuf>,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:#?}", opt);
+}
+```
+
+Using this example:
+```
+$ ./basic
+error: The following required arguments were not provided:
+    --output <output>
+
+USAGE:
+    basic --output <output> --speed <speed>
+
+For more information try --help
+$ ./basic --help
+basic 0.3.0
+Guillaume Pinot <texitoi@texitoi.eu>, others
+A basic example
+
+USAGE:
+    basic [FLAGS] [OPTIONS] --output <output> [--] [file]...
+
+FLAGS:
+    -d, --debug      Activate debug mode
+    -h, --help       Prints help information
+    -V, --version    Prints version information
+    -v, --verbose    Verbose mode (-v, -vv, -vvv, etc.)
+
+OPTIONS:
+    -l, --level <level>...     admin_level to consider
+    -c, --nb-cars <nb-cars>    Number of cars
+    -o, --output <output>      Output file
+    -s, --speed <speed>        Set speed [default: 42]
+
+ARGS:
+    <file>...    Files to process
+$ ./basic -o foo.txt
+Opt {
+    debug: false,
+    verbose: 0,
+    speed: 42.0,
+    output: "foo.txt",
+    nb_cars: None,
+    level: [],
+    files: [],
+}
+$ ./basic -o foo.txt -dvvvs 1337 -l alice -l bob --nb-cars 4 bar.txt baz.txt
+Opt {
+    debug: true,
+    verbose: 3,
+    speed: 1337.0,
+    output: "foo.txt",
+    nb_cars: Some(
+        4,
+    ),
+    level: [
+        "alice",
+        "bob",
+    ],
+    files: [
+        "bar.txt",
+        "baz.txt",
+    ],
+}
+```
+
+## StructOpt rustc version policy
+
+- Minimum rustc version modification must be specified in the [changelog](https://github.com/TeXitoi/structopt/blob/master/CHANGELOG.md) and in the [travis configuration](https://github.com/TeXitoi/structopt/blob/master/.travis.yml).
+- Contributors can increment minimum rustc version without any justification if the new version is required by the latest version of one of StructOpt's dependencies (`cargo update` will not fail on StructOpt).
+- Contributors can increment minimum rustc version if the library user experience is improved.
+
+## License
+
+Licensed under either of
+
+- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or <https://www.apache.org/licenses/LICENSE-2.0>)
+- MIT license ([LICENSE-MIT](LICENSE-MIT) or <https://opensource.org/licenses/MIT>)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
diff --git a/examples/README.md b/examples/README.md
new file mode 100644
index 0000000..f0db20b
--- /dev/null
+++ b/examples/README.md
@@ -0,0 +1,82 @@
+# Collection of examples "how to use `structopt`"
+
+### [Help on the bottom](after_help.rs)
+
+How to append a postscript to the help message generated.
+
+### [At least N](at_least_two.rs)
+
+How to require presence of at least N values, like `val1 val2 ... valN ... valM`.
+
+### [Basic](basic.rs)
+
+A basic example how to use `structopt`.
+
+### [Deny missing docs](deny_missing_docs.rs)
+
+**This is not an example but a test**, it should be moved to `tests` folder
+as soon as [this](https://github.com/rust-lang/rust/issues/24584) is fixed (if ever).
+
+### [Doc comments](doc_comments.rs)
+
+How to use doc comments in place of `help/long_help`.
+
+### [Enums as arguments](enum_in_args.rs)
+
+How to use `arg_enum!` with `StructOpt`.
+
+### [Arguments of subcommands in separate `struct`](enum_tuple.rs)
+
+How to extract subcommands' args into external structs.
+
+### [Environment variables](env.rs)
+
+How to use environment variable fallback an how it interacts with `default_value`.
+
+### [Advanced](example.rs)
+
+Somewhat complex example of usage of `structopt`.
+
+### [Flatten](flatten.rs)
+
+How to use `#[structopt(flatten)]`
+
+### [`bash` completions](gen_completions.rs)
+
+Generating `bash` completions with `structopt`.
+
+### [Git](git.rs)
+
+Pseudo-`git` example, shows how to use subcommands and how to document them.
+
+### [Groups](group.rs)
+
+Using `clap::Arg::group` with `structopt`.
+
+### [`key=value` pairs](keyvalue.rs)
+
+How to parse `key=value` pairs.
+
+### [`--no-*` flags](negative_flag.rs)
+
+How to add `no-thing` flag which is `true` by default and `false` if passed.
+
+### [No version](no_version.rs)
+
+How to completely remove version.
+
+### [Rename all](rename_all.rs)
+
+How `#[structopt(rename_all)]` works.
+
+### [Skip](skip.rs)
+
+How to use `#[structopt(skip)]`.
+
+### [Aliases](subcommand_aliases.rs)
+
+How to use aliases
+
+### [`true` or `false`](true_or_false.rs)
+
+How to express "`"true"` or `"false"` argument.
diff --git a/examples/after_help.rs b/examples/after_help.rs
new file mode 100644
index 0000000..db2845f
--- /dev/null
+++ b/examples/after_help.rs
@@ -0,0 +1,19 @@
+//! How to append a postscript to the help message generated.
+
+use structopt::StructOpt;
+
+/// I am a program and I do things.
+///
+/// Sometimes they even work.
+#[derive(StructOpt, Debug)]
+#[structopt(after_help = "Beware `-d`, dragons be here")]
+struct Opt {
+    /// Release the dragon.
+    #[structopt(short)]
+    dragon: bool,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/examples/at_least_two.rs b/examples/at_least_two.rs
new file mode 100644
index 0000000..683db50
--- /dev/null
+++ b/examples/at_least_two.rs
@@ -0,0 +1,15 @@
+//! How to require presence of at least N values,
+//! like `val1 val2 ... valN ... valM`.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+struct Opt {
+    #[structopt(required = true, min_values = 2)]
+    foos: Vec<String>,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/examples/basic.rs b/examples/basic.rs
new file mode 100644
index 0000000..510e0e0
--- /dev/null
+++ b/examples/basic.rs
@@ -0,0 +1,48 @@
+//! A somewhat comprehensive example of a typical `StructOpt` usage.use
+
+use std::path::PathBuf;
+use structopt::StructOpt;
+
+/// A basic example
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+    // A flag, true if used in the command line. Note doc comment will
+    // be used for the help message of the flag. The name of the
+    // argument will be, by default, based on the name of the field.
+    /// Activate debug mode
+    #[structopt(short, long)]
+    debug: bool,
+
+    // The number of occurrences of the `v/verbose` flag
+    /// Verbose mode (-v, -vv, -vvv, etc.)
+    #[structopt(short, long, parse(from_occurrences))]
+    verbose: u8,
+
+    /// Set speed
+    #[structopt(short, long, default_value = "42")]
+    speed: f64,
+
+    /// Output file
+    #[structopt(short, long, parse(from_os_str))]
+    output: PathBuf,
+
+    // the long option will be translated by default to kebab case,
+    // i.e. `--nb-cars`.
+    /// Number of cars
+    #[structopt(short = "c", long)]
+    nb_cars: Option<i32>,
+
+    /// admin_level to consider
+    #[structopt(short, long)]
+    level: Vec<String>,
+
+    /// Files to process
+    #[structopt(name = "FILE", parse(from_os_str))]
+    files: Vec<PathBuf>,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:#?}", opt);
+}
diff --git a/examples/deny_missing_docs.rs b/examples/deny_missing_docs.rs
new file mode 100644
index 0000000..82b1e63
--- /dev/null
+++ b/examples/deny_missing_docs.rs
@@ -0,0 +1,51 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+// This should be in tests but it will not work until
+// https://github.com/rust-lang/rust/issues/24584 is fixed
+
+//! A test to check that structopt compiles with deny(missing_docs)
+
+#![deny(missing_docs)]
+
+use structopt::StructOpt;
+
+/// The options
+#[derive(StructOpt, Debug, PartialEq)]
+pub struct Opt {
+    #[structopt(short)]
+    verbose: bool,
+    #[structopt(subcommand)]
+    cmd: Option<Cmd>,
+}
+
+/// Some subcommands
+#[derive(StructOpt, Debug, PartialEq)]
+pub enum Cmd {
+    /// command A
+    A,
+    /// command B
+    B {
+        /// Alice?
+        #[structopt(short)]
+        alice: bool,
+    },
+    /// command C
+    C(COpt),
+}
+
+/// The options for C
+#[derive(StructOpt, Debug, PartialEq)]
+pub struct COpt {
+    #[structopt(short)]
+    bob: bool,
+}
+
+fn main() {
+    println!("{:?}", Opt::from_args());
+}
diff --git a/examples/doc_comments.rs b/examples/doc_comments.rs
new file mode 100644
index 0000000..810101f
--- /dev/null
+++ b/examples/doc_comments.rs
@@ -0,0 +1,74 @@
+//! How to use doc comments in place of `help/long_help`.
+
+use structopt::StructOpt;
+
+/// A basic example for the usage of doc comments as replacement
+/// of the arguments `help`, `long_help`, `about` and `long_about`.
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+    /// Just use doc comments to replace `help`, `long_help`,
+    /// `about` or `long_about` input.
+    #[structopt(short, long)]
+    first_flag: bool,
+
+    /// Split between `help` and `long_help`.
+    ///
+    /// In the previous case structopt is going to present
+    /// the whole comment both as text for the `help` and the
+    /// `long_help` argument.
+    ///
+    /// But if the doc comment is formatted like this example
+    /// -- with an empty second line splitting the heading and
+    /// the rest of the comment -- only the first line is used
+    /// as `help` argument. The `long_help` argument will still
+    /// contain the whole comment.
+    ///
+    /// ## Attention
+    ///
+    /// Any formatting next to empty lines that could be used
+    /// inside a doc comment is currently not preserved. If
+    /// lists or other well formatted content is required it is
+    /// necessary to use the related structopt argument with a
+    /// raw string as shown on the `third_flag` description.
+    #[structopt(short, long)]
+    second_flag: bool,
+
+    #[structopt(
+        short,
+        long,
+        long_help = r"This is a raw string.
+
+It can be used to pass well formatted content (e.g. lists or source
+code) in the description:
+
+ - first example list entry
+ - second example list entry
+ "
+    )]
+    third_flag: bool,
+
+    #[structopt(subcommand)]
+    sub_command: SubCommand,
+}
+
+#[derive(StructOpt, Debug)]
+#[structopt()]
+enum SubCommand {
+    /// The same rules described previously for flags. Are
+    /// also true for in regards of sub-commands.
+    First,
+
+    /// Applicable for both `about` an `help`.
+    ///
+    /// The formatting rules described in the comment of the
+    /// `second_flag` also apply to the description of
+    /// sub-commands which is normally given through the `about`
+    /// and `long_about` arguments.
+    Second,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/examples/enum_in_args.rs b/examples/enum_in_args.rs
new file mode 100644
index 0000000..70347da
--- /dev/null
+++ b/examples/enum_in_args.rs
@@ -0,0 +1,25 @@
+//! How to use `arg_enum!` with `StructOpt`.
+
+use clap::arg_enum;
+use structopt::StructOpt;
+
+arg_enum! {
+    #[derive(Debug)]
+    enum Baz {
+        Foo,
+        Bar,
+        FooBar
+    }
+}
+
+#[derive(StructOpt, Debug)]
+struct Opt {
+    /// Important argument.
+    #[structopt(possible_values = &Baz::variants(), case_insensitive = true)]
+    i: Baz,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/examples/enum_tuple.rs b/examples/enum_tuple.rs
new file mode 100644
index 0000000..0bad2e6
--- /dev/null
+++ b/examples/enum_tuple.rs
@@ -0,0 +1,26 @@
+//! How to extract subcommands' args into external structs.
+
+use structopt::StructOpt;
+
+#[derive(Debug, StructOpt)]
+pub struct Foo {
+    pub bar: Option<String>,
+}
+
+#[derive(Debug, StructOpt)]
+pub enum Command {
+    #[structopt(name = "foo")]
+    Foo(Foo),
+}
+
+#[derive(Debug, StructOpt)]
+#[structopt(name = "classify")]
+pub struct ApplicationArguments {
+    #[structopt(subcommand)]
+    pub command: Command,
+}
+
+fn main() {
+    let opt = ApplicationArguments::from_args();
+    println!("{:?}", opt);
+}
diff --git a/examples/env.rs b/examples/env.rs
new file mode 100644
index 0000000..0477089
--- /dev/null
+++ b/examples/env.rs
@@ -0,0 +1,26 @@
+//! How to use environment variable fallback an how it
+//! interacts with `default_value`.
+
+use structopt::StructOpt;
+
+/// Example for allowing to specify options via environment variables.
+#[derive(StructOpt, Debug)]
+#[structopt(name = "env")]
+struct Opt {
+    // Use `env` to enable specifying the option with an environment
+    // variable. Command line arguments take precedence over env.
+    /// URL for the API server
+    #[structopt(long, env = "API_URL")]
+    api_url: String,
+
+    // The default value is used if neither argument nor environment
+    // variable is specified.
+    /// Number of retries
+    #[structopt(long, env = "RETRIES", default_value = "5")]
+    retries: u32,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:#?}", opt);
+}
diff --git a/examples/example.rs b/examples/example.rs
new file mode 100644
index 0000000..7a9a514
--- /dev/null
+++ b/examples/example.rs
@@ -0,0 +1,54 @@
+//! Somewhat complex example of usage of structopt.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "example")]
+/// An example of StructOpt usage.
+struct Opt {
+    // A flag, true if used in the command line.
+    #[structopt(short, long)]
+    /// Activate debug mode
+    debug: bool,
+
+    // An argument of type float, with a default value.
+    #[structopt(short, long, default_value = "42")]
+    /// Set speed
+    speed: f64,
+
+    // Needed parameter, the first on the command line.
+    /// Input file
+    input: String,
+
+    // An optional parameter, will be `None` if not present on the
+    // command line.
+    /// Output file, stdout if not present
+    output: Option<String>,
+
+    // An optional parameter with optional value, will be `None` if
+    // not present on the command line, will be `Some(None)` if no
+    // argument is provided (i.e. `--log`) and will be
+    // `Some(Some(String))` if argument is provided (e.g. `--log
+    // log.txt`).
+    #[structopt(long)]
+    #[allow(clippy::option_option)]
+    /// Log file, stdout if no file, no logging if not present
+    log: Option<Option<String>>,
+
+    // An optional list of values, will be `None` if not present on
+    // the command line, will be `Some(vec![])` if no argument is
+    // provided (i.e. `--optv`) and will be `Some(Some(String))` if
+    // argument list is provided (e.g. `--optv a b c`).
+    #[structopt(long)]
+    optv: Option<Vec<String>>,
+
+    // Skipped option: it won't be parsed and will be filled with the
+    // default value for its type (in this case it'll be an empty string).
+    #[structopt(skip)]
+    skipped: String,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/examples/flatten.rs b/examples/flatten.rs
new file mode 100644
index 0000000..d51647f
--- /dev/null
+++ b/examples/flatten.rs
@@ -0,0 +1,29 @@
+//! How to use flattening.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+struct Cmdline {
+    /// switch verbosity on
+    #[structopt(short)]
+    verbose: bool,
+
+    #[structopt(flatten)]
+    daemon_opts: DaemonOpts,
+}
+
+#[derive(StructOpt, Debug)]
+struct DaemonOpts {
+    /// daemon user
+    #[structopt(short)]
+    user: String,
+
+    /// daemon group
+    #[structopt(short)]
+    group: String,
+}
+
+fn main() {
+    let opt = Cmdline::from_args();
+    println!("{:?}", opt);
+}
diff --git a/examples/gen_completions.rs b/examples/gen_completions.rs
new file mode 100644
index 0000000..4f35b07
--- /dev/null
+++ b/examples/gen_completions.rs
@@ -0,0 +1,26 @@
+// Copyright 2019-present structopt developers
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::clap::Shell;
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+/// An example of how to generate bash completions with structopt.
+struct Opt {
+    #[structopt(short, long)]
+    /// Activate debug mode
+    debug: bool,
+}
+
+fn main() {
+    // generate `bash` completions in "target" directory
+    Opt::clap().gen_completions(env!("CARGO_PKG_NAME"), Shell::Bash, "target");
+
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/examples/git.rs b/examples/git.rs
new file mode 100644
index 0000000..494e9d1
--- /dev/null
+++ b/examples/git.rs
@@ -0,0 +1,35 @@
+//! `git.rs` serves as a demonstration of how to use subcommands,
+//! as well as a demonstration of adding documentation to subcommands.
+//! Documentation can be added either through doc comments or
+//! `help`/`about` attributes.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "git")]
+/// the stupid content tracker
+enum Opt {
+    /// fetch branches from remote repository
+    Fetch {
+        #[structopt(long)]
+        dry_run: bool,
+        #[structopt(long)]
+        all: bool,
+        #[structopt(default_value = "origin")]
+        repository: String,
+    },
+    #[structopt(help = "add files to the staging area")]
+    Add {
+        #[structopt(short)]
+        interactive: bool,
+        #[structopt(short)]
+        all: bool,
+        files: Vec<String>,
+    },
+}
+
+fn main() {
+    let matches = Opt::from_args();
+
+    println!("{:?}", matches);
+}
diff --git a/examples/group.rs b/examples/group.rs
new file mode 100644
index 0000000..d53de6a
--- /dev/null
+++ b/examples/group.rs
@@ -0,0 +1,31 @@
+//! How to use `clap::Arg::group`
+
+use structopt::{clap::ArgGroup, StructOpt};
+
+#[derive(StructOpt, Debug)]
+#[structopt(group = ArgGroup::with_name("verb").required(true))]
+struct Opt {
+    /// Set a custom HTTP verb
+    #[structopt(long, group = "verb")]
+    method: Option<String>,
+    /// HTTP GET
+    #[structopt(long, group = "verb")]
+    get: bool,
+    /// HTTP HEAD
+    #[structopt(long, group = "verb")]
+    head: bool,
+    /// HTTP POST
+    #[structopt(long, group = "verb")]
+    post: bool,
+    /// HTTP PUT
+    #[structopt(long, group = "verb")]
+    put: bool,
+    /// HTTP DELETE
+    #[structopt(long, group = "verb")]
+    delete: bool,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/examples/keyvalue.rs b/examples/keyvalue.rs
new file mode 100644
index 0000000..12ce6fc
--- /dev/null
+++ b/examples/keyvalue.rs
@@ -0,0 +1,36 @@
+//! How to parse "key=value" pairs with structopt.
+
+use std::error::Error;
+use structopt::StructOpt;
+
+/// Parse a single key-value pair
+fn parse_key_val<T, U>(s: &str) -> Result<(T, U), Box<dyn Error>>
+where
+    T: std::str::FromStr,
+    T::Err: Error + 'static,
+    U: std::str::FromStr,
+    U::Err: Error + 'static,
+{
+    let pos = s
+        .find('=')
+        .ok_or_else(|| format!("invalid KEY=value: no `=` found in `{}`", s))?;
+    Ok((s[..pos].parse()?, s[pos + 1..].parse()?))
+}
+
+#[derive(StructOpt, Debug)]
+struct Opt {
+    // number_of_values = 1 forces the user to repeat the -D option for each key-value pair:
+    // my_program -D a=1 -D b=2
+    // Without number_of_values = 1 you can do:
+    // my_program -D a=1 b=2
+    // but this makes adding an argument after the values impossible:
+    // my_program -D a=1 -D b=2 my_input_file
+    // becomes invalid.
+    #[structopt(short = "D", parse(try_from_str = parse_key_val), number_of_values = 1)]
+    defines: Vec<(String, i32)>,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/examples/negative_flag.rs b/examples/negative_flag.rs
new file mode 100644
index 0000000..b178bf5
--- /dev/null
+++ b/examples/negative_flag.rs
@@ -0,0 +1,15 @@
+//! How to add `no-thing` flag which is `true` by default and
+//! `false` if passed.
+
+use structopt::StructOpt;
+
+#[derive(Debug, StructOpt)]
+struct Opt {
+    #[structopt(long = "no-verbose", parse(from_flag = std::ops::Not::not))]
+    verbose: bool,
+}
+
+fn main() {
+    let cmd = Opt::from_args();
+    println!("{:#?}", cmd);
+}
diff --git a/examples/no_version.rs b/examples/no_version.rs
new file mode 100644
index 0000000..a542ec1
--- /dev/null
+++ b/examples/no_version.rs
@@ -0,0 +1,17 @@
+//! How to completely remove version.
+
+use structopt::clap::AppSettings;
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(
+    name = "no_version",
+    no_version,
+    global_settings = &[AppSettings::DisableVersion]
+)]
+struct Opt {}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/examples/rename_all.rs b/examples/rename_all.rs
new file mode 100644
index 0000000..35f3c4f
--- /dev/null
+++ b/examples/rename_all.rs
@@ -0,0 +1,74 @@
+//! Example on how the `rename_all` parameter works.
+//!
+//! `rename_all` can be used to override the casing style used during argument
+//! generation. By default the `kebab-case` style will be used but there are a wide
+//! variety of other styles available.
+//!
+//! ## Supported styles overview:
+//!
+//! - **Camel Case**: Indicate word boundaries with uppercase letter, excluding
+//!                   the first word.
+//! - **Kebab Case**: Keep all letters lowercase and indicate word boundaries
+//!                   with hyphens.
+//! - **Pascal Case**: Indicate word boundaries with uppercase letter,
+//!                    including the first word.
+//! - **Screaming Snake Case**: Keep all letters uppercase and indicate word
+//!                             boundaries with underscores.
+//! - **Snake Case**: Keep all letters lowercase and indicate word boundaries
+//!                   with underscores.
+//! - **Verbatim**: Use the original attribute name defined in the code.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "rename_all", rename_all = "screaming_snake_case")]
+enum Opt {
+    // This subcommand will be named `FIRST_COMMAND`. As the command doesn't
+    // override the initial casing style, ...
+    /// A screaming loud first command. Only use if necessary.
+    FirstCommand {
+        // this flag will be available as `--FOO` and `-F`.
+        /// This flag will even scream louder.
+        #[structopt(long, short)]
+        foo: bool,
+    },
+
+    // As we override the casing style for this variant the related subcommand
+    // will be named `SecondCommand`.
+    /// Not nearly as loud as the first command.
+    #[structopt(rename_all = "pascal_case")]
+    SecondCommand {
+        // We can also override it again on a single field.
+        /// Nice quiet flag. No one is annoyed.
+        #[structopt(rename_all = "snake_case", long)]
+        bar_option: bool,
+
+        // Renaming will not be propagated into subcommand flagged enums. If
+        // a non default casing style is required it must be defined on the
+        // enum itself.
+        #[structopt(subcommand)]
+        cmds: Subcommands,
+
+        // or flattened structs.
+        #[structopt(flatten)]
+        options: BonusOptions,
+    },
+}
+
+#[derive(StructOpt, Debug)]
+enum Subcommands {
+    // This one will be available as `first-subcommand`.
+    FirstSubcommand,
+}
+
+#[derive(StructOpt, Debug)]
+struct BonusOptions {
+    // And this one will be available as `baz-option`.
+    #[structopt(long)]
+    baz_option: bool,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/examples/skip.rs b/examples/skip.rs
new file mode 100644
index 0000000..1f44769
--- /dev/null
+++ b/examples/skip.rs
@@ -0,0 +1,47 @@
+//! How to use `#[structopt(skip)]`
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug, PartialEq)]
+pub struct Opt {
+    #[structopt(long, short)]
+    number: u32,
+    #[structopt(skip)]
+    k: Kind,
+    #[structopt(skip)]
+    v: Vec<u32>,
+
+    #[structopt(skip = Kind::A)]
+    k2: Kind,
+    #[structopt(skip = vec![1, 2, 3])]
+    v2: Vec<u32>,
+    #[structopt(skip = "cake")] // &str implements Into<String>
+    s: String,
+}
+
+#[derive(Debug, PartialEq)]
+enum Kind {
+    A,
+    B,
+}
+
+impl Default for Kind {
+    fn default() -> Self {
+        return Kind::B;
+    }
+}
+
+fn main() {
+    assert_eq!(
+        Opt::from_iter(&["test", "-n", "10"]),
+        Opt {
+            number: 10,
+            k: Kind::B,
+            v: vec![],
+
+            k2: Kind::A,
+            v2: vec![1, 2, 3],
+            s: String::from("cake")
+        }
+    );
+}
diff --git a/examples/subcommand_aliases.rs b/examples/subcommand_aliases.rs
new file mode 100644
index 0000000..30b8cc3
--- /dev/null
+++ b/examples/subcommand_aliases.rs
@@ -0,0 +1,21 @@
+//! How to assign some aliases to subcommands
+
+use structopt::clap::AppSettings;
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+// https://docs.rs/clap/2/clap/enum.AppSettings.html#variant.InferSubcommands
+#[structopt(setting = AppSettings::InferSubcommands)]
+enum Opt {
+    // https://docs.rs/clap/2/clap/struct.App.html#method.alias
+    #[structopt(alias = "foobar")]
+    Foo,
+    // https://docs.rs/clap/2/clap/struct.App.html#method.aliases
+    #[structopt(aliases = &["baz", "fizz"])]
+    Bar,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/examples/true_or_false.rs b/examples/true_or_false.rs
new file mode 100644
index 0000000..31a543e
--- /dev/null
+++ b/examples/true_or_false.rs
@@ -0,0 +1,41 @@
+//! How to parse `--foo=true --bar=false` and turn them into bool.
+
+use structopt::StructOpt;
+
+fn true_or_false(s: &str) -> Result<bool, &'static str> {
+    match s {
+        "true" => Ok(true),
+        "false" => Ok(false),
+        _ => Err("expected `true` or `false`"),
+    }
+}
+
+#[derive(StructOpt, Debug, PartialEq)]
+struct Opt {
+    // Default parser for `try_from_str` is FromStr::from_str.
+    // `impl FromStr for bool` parses `true` or `false` so this
+    // works as expected.
+    #[structopt(long, parse(try_from_str))]
+    foo: bool,
+
+    // Of course, this could be done with an explicit parser function.
+    #[structopt(long, parse(try_from_str = true_or_false))]
+    bar: bool,
+
+    // `bool` can be positional only with explicit `parse(...)` annotation
+    #[structopt(long, parse(try_from_str))]
+    boom: bool,
+}
+
+fn main() {
+    assert_eq!(
+        Opt::from_iter(&["test", "--foo=true", "--bar=false", "true"]),
+        Opt {
+            foo: true,
+            bar: false,
+            boom: true
+        }
+    );
+    // no beauty, only truth and falseness
+    assert!(Opt::from_iter_safe(&["test", "--foo=beauty"]).is_err());
+}
diff --git a/link-check-headers.json b/link-check-headers.json
new file mode 100644
index 0000000..c1bb248
--- /dev/null
+++ b/link-check-headers.json
@@ -0,0 +1,14 @@
+{
+    "httpHeaders": [
+        {
+            "urls": [
+                "https://",
+                "http://"
+            ],
+            "headers": {
+                "User-Agent": "broken links checker (https://github.com/TeXitoi/structopt)",
+                "Accept": "text/html"
+            }
+        }
+    ]
+}
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..c42fe1f
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,1169 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+#![deny(missing_docs)]
+
+//! This crate defines the `StructOpt` trait and its custom derive.
+//!
+//! ## Features
+//!
+//! If you want to disable all the `clap` features (colors,
+//! suggestions, ..) add `default-features = false` to the `structopt`
+//! dependency:
+//!
+//! ```toml
+//! [dependencies]
+//! structopt = { version = "0.3", default-features = false }
+//! ```
+//!
+//! Support for [`paw`](https://github.com/rust-cli/paw) (the
+//! `Command line argument paw-rser abstraction for main`) is disabled
+//! by default, but can be enabled in the `structopt` dependency
+//! with the feature `paw`:
+//!
+//! ```toml
+//! [dependencies]
+//! structopt = { version = "0.3", features = [ "paw" ] }
+//! paw = "1.0"
+//! ```
+//!
+//! # Table of Contents
+//!
+//! - [How to `derive(StructOpt)`](#how-to-derivestructopt)
+//! - [Attributes](#attributes)
+//!     - [Raw methods](#raw-methods)
+//!     - [Magical methods](#magical-methods)
+//! - Arguments
+//!     - [Type magic](#type-magic)
+//!     - [Specifying argument types](#specifying-argument-types)
+//!     - [Default values](#default-values)
+//!     - [Help messages](#help-messages)
+//!     - [Environment variable fallback](#environment-variable-fallback)
+//! - [Skipping fields](#skipping-fields)
+//! - [Subcommands](#subcommands)
+//!     - [Optional subcommands](#optional-subcommands)
+//!     - [External subcommands](#external-subcommands)
+//!     - [Flattening subcommands](#flattening-subcommands)
+//! - [Flattening](#flattening)
+//! - [Custom string parsers](#custom-string-parsers)
+//!
+//!
+//!
+//! ## How to `derive(StructOpt)`
+//!
+//! First, let's look at the example:
+//!
+//! ```should_panic
+//! use std::path::PathBuf;
+//! use structopt::StructOpt;
+//!
+//! #[derive(Debug, StructOpt)]
+//! #[structopt(name = "example", about = "An example of StructOpt usage.")]
+//! struct Opt {
+//!     /// Activate debug mode
+//!     // short and long flags (-d, --debug) will be deduced from the field's name
+//!     #[structopt(short, long)]
+//!     debug: bool,
+//!
+//!     /// Set speed
+//!     // we don't want to name it "speed", need to look smart
+//!     #[structopt(short = "v", long = "velocity", default_value = "42")]
+//!     speed: f64,
+//!
+//!     /// Input file
+//!     #[structopt(parse(from_os_str))]
+//!     input: PathBuf,
+//!
+//!     /// Output file, stdout if not present
+//!     #[structopt(parse(from_os_str))]
+//!     output: Option<PathBuf>,
+//!
+//!     /// Where to write the output: to `stdout` or `file`
+//!     #[structopt(short)]
+//!     out_type: String,
+//!
+//!     /// File name: only required when `out` is set to `file`
+//!     #[structopt(name = "FILE", required_if("out_type", "file"))]
+//!     file_name: String,
+//! }
+//!
+//! fn main() {
+//!     let opt = Opt::from_args();
+//!     println!("{:?}", opt);
+//! }
+//! ```
+//!
+//! So `derive(StructOpt)` tells Rust to generate a command line parser,
+//! and the various `structopt` attributes are simply
+//! used for additional parameters.
+//!
+//! First, define a struct, whatever its name. This structure
+//! corresponds to a `clap::App`, its fields correspond to `clap::Arg`
+//! (unless they're [subcommands](#subcommands)),
+//! and you can adjust these apps and args by `#[structopt(...)]` [attributes](#attributes).
+//!
+//! **Note:**
+//! _________________
+//! Keep in mind that `StructOpt` trait is more than just `from_args` method.
+//! It has a number of additional features, including access to underlying
+//! `clap::App` via `StructOpt::clap()`. See the
+//! [trait's reference documentation](trait.StructOpt.html).
+//! _________________
+//!
+//! ## Attributes
+//!
+//! You can control the way `structopt` translates your struct into an actual
+//! [`clap::App`] invocation via `#[structopt(...)]` attributes.
+//!
+//! The attributes fall into two categories:
+//! - `structopt`'s own [magical methods](#magical-methods).
+//!
+//!    They are used by `structopt` itself. They come mostly in
+//!    `attr = ["whatever"]` form, but some `attr(args...)` also exist.
+//!
+//! - [`raw` attributes](#raw-methods).
+//!
+//!     They represent explicit `clap::Arg/App` method calls.
+//!     They are what used to be explicit `#[structopt(raw(...))]` attrs in pre-0.3 `structopt`
+//!
+//! Every `structopt attribute` looks like comma-separated sequence of methods:
+//! ```rust,ignore
+//! #[structopt(
+//!     short, // method with no arguments - always magical
+//!     long = "--long-option", // method with one argument
+//!     required_if("out", "file"), // method with one and more args
+//!     parse(from_os_str = path::to::parser) // some magical methods have their own syntax
+//! )]
+//! ```
+//!
+//! `#[structopt(...)]` attributes can be placed on top of `struct`, `enum`,
+//! `struct` field or `enum` variant. Attributes on top of `struct` or `enum`
+//! represent `clap::App` method calls, field or variant attributes correspond
+//! to `clap::Arg` method calls.
+//!
+//! In other words, the `Opt` struct from the example above
+//! will be turned into this (*details omitted*):
+//!
+//! ```
+//! # use structopt::clap::{Arg, App};
+//! App::new("example")
+//!     .version("0.2.0")
+//!     .about("An example of StructOpt usage.")
+//! .arg(Arg::with_name("debug")
+//!     .help("Activate debug mode")
+//!     .short("debug")
+//!     .long("debug"))
+//! .arg(Arg::with_name("speed")
+//!     .help("Set speed")
+//!     .short("v")
+//!     .long("velocity")
+//!     .default_value("42"))
+//! // and so on
+//! # ;
+//! ```
+//!
+//! ## Raw methods
+//!
+//! They are the reason why `structopt` is so flexible. **Every and each method from
+//! `clap::App/Arg` can be used this way!**
+//!
+//! ```ignore
+//! #[structopt(
+//!     global = true, // name = arg form, neat for one-arg methods
+//!     required_if("out", "file") // name(arg1, arg2, ...) form.
+//! )]
+//! ```
+//!
+//! The first form can only be used for methods which take only one argument.
+//! The second form must be used with multi-arg methods, but can also be used with
+//! single-arg methods. These forms are identical otherwise.
+//!
+//! As long as `method_name` is not one of the magical methods -
+//! it will be translated into a mere method call.
+//!
+//! **Note:**
+//! _________________
+//!
+//! "Raw methods" are direct replacement for pre-0.3 structopt's
+//! `#[structopt(raw(...))]` attributes, any time you would have used a `raw()` attribute
+//! in 0.2 you should use raw method in 0.3.
+//!
+//! Unfortunately, old raw attributes collide with `clap::Arg::raw` method. To explicitly
+//! warn users of this change we allow `#[structopt(raw())]` only with `true` or `false`
+//! literals (this method is supposed to be called only with `true` anyway).
+//! __________________
+//!
+//! ## Magical methods
+//!
+//! They are the reason why `structopt` is so easy to use and convenient in most cases.
+//! Many of them have defaults, some of them get used even if not mentioned.
+//!
+//! Methods may be used on "top level" (on top of a `struct`, `enum` or `enum` variant)
+//! and/or on "field-level" (on top of a `struct` field or *inside* of an enum variant).
+//! Top level (non-magical) methods correspond to `App::method` calls, field-level methods
+//! are `Arg::method` calls.
+//!
+//! ```ignore
+//! #[structopt(top_level)]
+//! struct Foo {
+//!     #[structopt(field_level)]
+//!     field: u32
+//! }
+//!
+//! #[structopt(top_level)]
+//! enum Bar {
+//!     #[structopt(top_level)]
+//!     Pineapple {
+//!         #[structopt(field_level)]
+//!         chocolate: String
+//!     },
+//!
+//!     #[structopt(top_level)]
+//!     Orange,
+//! }
+//! ```
+//!
+//! - `name`: `[name = expr]`
+//!   - On top level: `App::new(expr)`.
+//!
+//!     The binary name displayed in help messages. Defaults to the crate name given by Cargo.
+//!
+//!   - On field-level: `Arg::with_name(expr)`.
+//!
+//!     The name for the argument the field stands for, this name appears in help messages.
+//!     Defaults to a name, deduced from a field, see also
+//!     [`rename_all`](#specifying-argument-types).
+//!
+//! - `version`: `[version = "version"]`
+//!
+//!     Usable only on top level: `App::version("version" or env!(CARGO_PKG_VERSION))`.
+//!
+//!     The version displayed in help messages.
+//!     Defaults to the crate version given by Cargo. If `CARGO_PKG_VERSION` is not
+//!     set no `.version()` calls will be generated unless requested.
+//!
+//! - `no_version`: `no_version`
+//!
+//!     Usable only on top level. Prevents default `App::version` call, i.e
+//!     when no `version = "version"` mentioned.
+//!
+//! - `author`: `author [= "author"]`
+//!
+//!     Usable only on top level: `App::author("author" or env!(CARGO_PKG_AUTHORS))`.
+//!
+//!     Author/maintainer of the binary, this name appears in help messages.
+//!     Defaults to the crate author given by cargo, but only when `author` explicitly mentioned.
+//!
+//! - `about`: `about [= "about"]`
+//!
+//!     Usable only on top level: `App::about("about" or env!(CARGO_PKG_DESCRIPTION))`.
+//!
+//!     Short description of the binary, appears in help messages.
+//!     Defaults to the crate description given by cargo,
+//!     but only when `about` explicitly mentioned.
+//!
+//! - [`short`](#specifying-argument-types): `short [= "short-opt-name"]`
+//!
+//!     Usable only on field-level.
+//!
+//! - [`long`](#specifying-argument-types): `long [= "long-opt-name"]`
+//!
+//!     Usable only on field-level.
+//!
+//! - [`default_value`](#default-values): `default_value [= "default value"]`
+//!
+//!     Usable only on field-level.
+//!
+//! - [`rename_all`](#specifying-argument-types):
+//!     [`rename_all = "kebab"/"snake"/"screaming-snake"/"camel"/"pascal"/"verbatim"]`
+//!
+//!     Usable both on top level and field level.
+//!
+//! - [`parse`](#custom-string-parsers): `parse(type [= path::to::parser::fn])`
+//!
+//!     Usable only on field-level.
+//!
+//! - [`skip`](#skipping-fields): `skip [= expr]`
+//!
+//!     Usable only on field-level.
+//!
+//! - [`flatten`](#flattening): `flatten`
+//!
+//!     Usable on field-level or single-typed tuple variants.
+//!
+//! - [`subcommand`](#subcommands): `subcommand`
+//!
+//!     Usable only on field-level.
+//!
+//! - [`external_subcommand`](#external-subcommands)
+//!
+//!     Usable only on enum variants.
+//!
+//! - [`env`](#environment-variable-fallback): `env [= str_literal]`
+//!
+//!     Usable only on field-level.
+//!
+//! - [`rename_all_env`](##auto-deriving-environment-variables):
+//!     [`rename_all_env = "kebab"/"snake"/"screaming-snake"/"camel"/"pascal"/"verbatim"]`
+//!
+//!     Usable both on top level and field level.
+//!
+//! - [`verbatim_doc_comment`](#doc-comment-preprocessing-and-structoptverbatim_doc_comment):
+//!     `verbatim_doc_comment`
+//!
+//!     Usable both on top level and field level.
+//!
+//! ## Type magic
+//!
+//! One of major things that makes `structopt` so awesome is it's type magic.
+//! Do you want optional positional argument? Use `Option<T>`! Or perhaps optional argument
+//! that optionally takes value (`[--opt=[val]]`)? Use `Option<Option<T>>`!
+//!
+//! Here is the table of types and `clap` methods they correspond to:
+//!
+//! Type                         | Effect                                            | Added method call to `clap::Arg`
+//! -----------------------------|---------------------------------------------------|--------------------------------------
+//! `bool`                       | `true` if the flag is present                     | `.takes_value(false).multiple(false)`
+//! `Option<T: FromStr>`         | optional positional argument or option            | `.takes_value(true).multiple(false)`
+//! `Option<Option<T: FromStr>>` | optional option with optional value               | `.takes_value(true).multiple(false).min_values(0).max_values(1)`
+//! `Vec<T: FromStr>`            | list of options or the other positional arguments | `.takes_value(true).multiple(true)`
+//! `Option<Vec<T: FromStr>`     | optional list of options                          | `.takes_values(true).multiple(true).min_values(0)`
+//! `T: FromStr`                 | required option or positional argument            | `.takes_value(true).multiple(false).required(!has_default)`
+//!
+//! The `FromStr` trait is used to convert the argument to the given
+//! type, and the `Arg::validator` method is set to a method using
+//! `to_string()` (`FromStr::Err` must implement `std::fmt::Display`).
+//! If you would like to use a custom string parser other than `FromStr`, see
+//! the [same titled section](#custom-string-parsers) below.
+//!
+//! **Important:**
+//! _________________
+//! Pay attention that *only literal occurrence* of this types is special, for example
+//! `Option<T>` is special while `::std::option::Option<T>` is not.
+//!
+//! If you need to avoid special casing you can make a `type` alias and
+//! use it in place of the said type.
+//! _________________
+//!
+//! **Note:**
+//! _________________
+//! `bool` cannot be used as positional argument unless you provide an explicit parser.
+//! If you need a positional bool, for example to parse `true` or `false`, you must
+//! annotate the field with explicit [`#[structopt(parse(...))]`](#custom-string-parsers).
+//! _________________
+//!
+//! Thus, the `speed` argument is generated as:
+//!
+//! ```
+//! # fn parse_validator<T>(_: String) -> Result<(), String> { unimplemented!() }
+//! clap::Arg::with_name("speed")
+//!     .takes_value(true)
+//!     .multiple(false)
+//!     .required(false)
+//!     .validator(parse_validator::<f64>)
+//!     .short("v")
+//!     .long("velocity")
+//!     .help("Set speed")
+//!     .default_value("42");
+//! ```
+//!
+//! ## Specifying argument types
+//!
+//! There are three types of arguments that can be supplied to each
+//! (sub-)command:
+//!
+//!  - short (e.g. `-h`),
+//!  - long (e.g. `--help`)
+//!  - and positional.
+//!
+//! Like clap, structopt defaults to creating positional arguments.
+//!
+//! If you want to generate a long argument you can specify either
+//! `long = $NAME`, or just `long` to get a long flag generated using
+//! the field name.  The generated casing style can be modified using
+//! the `rename_all` attribute. See the `rename_all` example for more.
+//!
+//! For short arguments, `short` will use the first letter of the
+//! field name by default, but just like the long option it's also
+//! possible to use a custom letter through `short = $LETTER`.
+//!
+//! If an argument is renamed using `name = $NAME` any following call to
+//! `short` or `long` will use the new name.
+//!
+//! **Attention**: If these arguments are used without an explicit name
+//! the resulting flag is going to be renamed using `kebab-case` if the
+//! `rename_all` attribute was not specified previously. The same is true
+//! for subcommands with implicit naming through the related data structure.
+//!
+//! ```
+//! use structopt::StructOpt;
+//!
+//! #[derive(StructOpt)]
+//! #[structopt(rename_all = "kebab-case")]
+//! struct Opt {
+//!     /// This option can be specified with something like `--foo-option
+//!     /// value` or `--foo-option=value`
+//!     #[structopt(long)]
+//!     foo_option: String,
+//!
+//!     /// This option can be specified with something like `-b value` (but
+//!     /// not `--bar-option value`).
+//!     #[structopt(short)]
+//!     bar_option: String,
+//!
+//!     /// This option can be specified either `--baz value` or `-z value`.
+//!     #[structopt(short = "z", long = "baz")]
+//!     baz_option: String,
+//!
+//!     /// This option can be specified either by `--custom value` or
+//!     /// `-c value`.
+//!     #[structopt(name = "custom", long, short)]
+//!     custom_option: String,
+//!
+//!     /// This option is positional, meaning it is the first unadorned string
+//!     /// you provide (multiple others could follow).
+//!     my_positional: String,
+//!
+//!     /// This option is skipped and will be filled with the default value
+//!     /// for its type (in this case 0).
+//!     #[structopt(skip)]
+//!     skipped: u32,
+//!
+//! }
+//!
+//! # Opt::from_iter(
+//! #    &["test", "--foo-option", "", "-b", "", "--baz", "", "--custom", "", "positional"]);
+//! ```
+//!
+//! ## Default values
+//!
+//! In clap, default values for options can be specified via [`Arg::default_value`].
+//!
+//! Of course, you can use as a raw method:
+//! ```
+//! # use structopt::StructOpt;
+//! #[derive(StructOpt)]
+//! struct Opt {
+//!     #[structopt(default_value = "", long)]
+//!     prefix: String
+//! }
+//! ```
+//!
+//! This is quite mundane and error-prone to type the `"..."` default by yourself,
+//! especially when the Rust ecosystem uses the [`Default`] trait for that.
+//! It would be wonderful to have `structopt` to take the `Default_default` and fill it
+//! for you. And yes, `structopt` can do that.
+//!
+//! Unfortunately, `default_value` takes `&str` but `Default::default`
+//! gives us some `Self` value. We need to map `Self` to `&str` somehow.
+//!
+//! `structopt` solves this problem via [`ToString`] trait.
+//!
+//! To be able to use auto-default the type must implement *both* `Default` and `ToString`:
+//!
+//! ```
+//! # use structopt::StructOpt;
+//! #[derive(StructOpt)]
+//! struct Opt {
+//!     // just leave the `= "..."` part and structopt will figure it for you
+//!     #[structopt(default_value, long)]
+//!     prefix: String // `String` implements both `Default` and `ToString`
+//! }
+//! ```
+//!
+//! [`Default`]: https://doc.rust-lang.org/std/default/trait.Default.html
+//! [`ToString`]: https://doc.rust-lang.org/std/string/trait.ToString.html
+//! [`Arg::default_value`]: https://docs.rs/clap/2.33.0/clap/struct.Arg.html#method.default_value
+//!
+//!
+//! ## Help messages
+//!
+//! In clap, help messages for the whole binary can be specified
+//! via [`App::about`] and [`App::long_about`] while help messages
+//! for individual arguments can be specified via [`Arg::help`] and [`Arg::long_help`]".
+//!
+//! `long_*` variants are used when user calls the program with
+//! `--help` and "short" variants are used with `-h` flag. In `structopt`,
+//! you can use them via [raw methods](#raw-methods), for example:
+//!
+//! ```
+//! # use structopt::StructOpt;
+//!
+//! #[derive(StructOpt)]
+//! #[structopt(about = "I am a program and I work, just pass `-h`")]
+//! struct Foo {
+//!   #[structopt(short, help = "Pass `-h` and you'll see me!")]
+//!   bar: String
+//! }
+//! ```
+//!
+//! For convenience, doc comments can be used instead of raw methods
+//! (this example works exactly like the one above):
+//!
+//! ```
+//! # use structopt::StructOpt;
+//!
+//! #[derive(StructOpt)]
+//! /// I am a program and I work, just pass `-h`
+//! struct Foo {
+//!   /// Pass `-h` and you'll see me!
+//!   bar: String
+//! }
+//! ```
+//!
+//! Doc comments on [top-level](#magical-methods) will be turned into
+//! `App::about/long_about` call (see below), doc comments on field-level are
+//! `Arg::help/long_help` calls.
+//!
+//! **Important:**
+//! _________________
+//!
+//! Raw methods have priority over doc comments!
+//!
+//! **Top level doc comments always generate `App::about/long_about` calls!**
+//! If you really want to use the `App::help/long_help` methods (you likely don't),
+//! use a raw method to override the `App::about` call generated from the doc comment.
+//! __________________
+//!
+//! ### `long_help` and `--help`
+//!
+//! A message passed to [`App::long_help`] or [`Arg::long_about`] will be displayed whenever
+//! your program is called with `--help` instead of `-h`. Of course, you can
+//! use them via raw methods as described [above](#help-messages).
+//!
+//! The more convenient way is to use a so-called "long" doc comment:
+//!
+//! ```
+//! # use structopt::StructOpt;
+//! #[derive(StructOpt)]
+//! /// Hi there, I'm Robo!
+//! ///
+//! /// I like beeping, stumbling, eating your electricity,
+//! /// and making records of you singing in a shower.
+//! /// Pay up, or I'll upload it to youtube!
+//! struct Robo {
+//!     /// Call my brother SkyNet.
+//!     ///
+//!     /// I am artificial superintelligence. I won't rest
+//!     /// until I'll have destroyed humanity. Enjoy your
+//!     /// pathetic existence, you mere mortals.
+//!     #[structopt(long)]
+//!     kill_all_humans: bool
+//! }
+//! ```
+//!
+//! A long doc comment consists of three parts:
+//! * Short summary
+//! * A blank line (whitespace only)
+//! * Detailed description, all the rest
+//!
+//! In other words, "long" doc comment consists of two or more paragraphs,
+//! with the first being a summary and the rest being the detailed description.
+//!
+//! **A long comment will result in two method calls**, `help(<summary>)` and
+//! `long_help(<whole comment>)`, so clap will display the summary with `-h`
+//! and the whole help message on `--help` (see below).
+//!
+//! So, the example above will be turned into this (details omitted):
+//! ```
+//! clap::App::new("<name>")
+//!     .about("Hi there, I'm Robo!")
+//!     .long_about("Hi there, I'm Robo!\n\n\
+//!                  I like beeping, stumbling, eating your electricity,\
+//!                  and making records of you singing in a shower.\
+//!                  Pay up or I'll upload it to youtube!")
+//! // args...
+//! # ;
+//! ```
+//!
+//! ### `-h` vs `--help` (A.K.A `help()` vs `long_help()`)
+//!
+//! The `-h` flag is not the same as `--help`.
+//!
+//! -h corresponds to Arg::help/App::about and requests short "summary" messages
+//! while --help corresponds to Arg::long_help/App::long_about and requests more
+//! detailed, descriptive messages.
+//!
+//! It is entirely up to `clap` what happens if you used only one of
+//! [`Arg::help`]/[`Arg::long_help`], see `clap`'s documentation for these methods.
+//!
+//! As of clap v2.33, if only a short message ([`Arg::help`]) or only
+//! a long ([`Arg::long_help`]) message is provided, clap will use it
+//! for both -h and --help. The same logic applies to `about/long_about`.
+//!
+//! ### Doc comment preprocessing and `#[structopt(verbatim_doc_comment)]`
+//!
+//! `structopt` applies some preprocessing to doc comments to ease the most common uses:
+//!
+//! * Strip leading and trailing whitespace from every line, if present.
+//!
+//! * Strip leading and trailing blank lines, if present.
+//!
+//! * Interpret each group of non-empty lines as a word-wrapped paragraph.
+//!
+//!   We replace newlines within paragraphs with spaces to allow the output
+//!   to be re-wrapped to the terminal width.
+//!
+//! * Strip any excess blank lines so that there is exactly one per paragraph break.
+//!
+//! * If the first paragraph ends in exactly one period,
+//!   remove the trailing period (i.e. strip trailing periods but not trailing ellipses).
+//!
+//! Sometimes you don't want this preprocessing to apply, for example the comment contains
+//! some ASCII art or markdown tables, you would need to preserve LFs along with
+//! blank lines and the leading/trailing whitespace. You can ask `structopt` to preserve them
+//! via `#[structopt(verbatim_doc_comment)]` attribute.
+//!
+//! **This attribute must be applied to each field separately**, there's no global switch.
+//!
+//! **Important:**
+//! ______________
+//! Keep in mind that `structopt` will *still* remove one leading space from each
+//! line, even if this attribute is present, to allow for a space between
+//! `///` and the content.
+//!
+//! Also, `structopt` will *still* remove leading and trailing blank lines so
+//! these formats are equivalent:
+//!
+//! ```ignore
+//! /** This is a doc comment
+//!
+//! Hello! */
+//!
+//! /**
+//! This is a doc comment
+//!
+//! Hello!
+//! */
+//!
+//! /// This is a doc comment
+//! ///
+//! /// Hello!
+//! ```
+//! ______________
+//!
+//! [`App::about`]:      https://docs.rs/clap/2/clap/struct.App.html#method.about
+//! [`App::long_about`]: https://docs.rs/clap/2/clap/struct.App.html#method.long_about
+//! [`Arg::help`]:       https://docs.rs/clap/2/clap/struct.Arg.html#method.help
+//! [`Arg::long_help`]:  https://docs.rs/clap/2/clap/struct.Arg.html#method.long_help
+//!
+//! ## Environment variable fallback
+//!
+//! It is possible to specify an environment variable fallback option for an arguments
+//! so that its value is taken from the specified environment variable if not
+//! given through the command-line:
+//!
+//! ```
+//! # use structopt::StructOpt;
+//!
+//! #[derive(StructOpt)]
+//! struct Foo {
+//!   #[structopt(short, long, env = "PARAMETER_VALUE")]
+//!   parameter_value: String
+//! }
+//! ```
+//!
+//! By default, values from the environment are shown in the help output (i.e. when invoking
+//! `--help`):
+//!
+//! ```shell
+//! $ cargo run -- --help
+//! ...
+//! OPTIONS:
+//!   -p, --parameter-value <parameter-value>     [env: PARAMETER_VALUE=env_value]
+//! ```
+//!
+//! In some cases this may be undesirable, for example when being used for passing
+//! credentials or secret tokens. In those cases you can use `hide_env_values` to avoid
+//! having structopt emit the actual secret values:
+//! ```
+//! # use structopt::StructOpt;
+//!
+//! #[derive(StructOpt)]
+//! struct Foo {
+//!   #[structopt(long = "secret", env = "SECRET_VALUE", hide_env_values = true)]
+//!   secret_value: String
+//! }
+//! ```
+//!
+//! ### Auto-deriving environment variables
+//!
+//! Environment variables tend to be called after the corresponding `struct`'s field,
+//! as in example above. The field is `secret_value` and the env var is "SECRET_VALUE";
+//! the name is the same, except casing is different.
+//!
+//! It's pretty tedious and error-prone to type the same name twice,
+//! so you can ask `structopt` to do that for you.
+//!
+//! ```
+//! # use structopt::StructOpt;
+//!
+//! #[derive(StructOpt)]
+//! struct Foo {
+//!   #[structopt(long = "secret", env)]
+//!   secret_value: String
+//! }
+//! ```
+//!
+//! It works just like `#[structopt(short/long)]`: if `env` is not set to some concrete
+//! value the value will be derived from the field's name. This is controlled by
+//! `#[structopt(rename_all_env)]`.
+//!
+//! `rename_all_env` works exactly as `rename_all` (including overriding)
+//! except default casing is `SCREAMING_SNAKE_CASE` instead of `kebab-case`.
+//!
+//! ## Skipping fields
+//!
+//! Sometimes you may want to add a field to your `Opt` struct that is not
+//! a command line option and `clap` should know nothing about it. You can ask
+//! `structopt` to skip the field entirely via `#[structopt(skip = value)]`
+//! (`value` must implement `Into<FieldType>`)
+//! or `#[structopt(skip)]` if you want assign the field with `Default::default()`
+//! (obviously, the field's type must implement `Default`).
+//!
+//! ```
+//! # use structopt::StructOpt;
+//! #[derive(StructOpt)]
+//! pub struct Opt {
+//!     #[structopt(long, short)]
+//!     number: u32,
+//!
+//!     // these fields are to be assigned with Default::default()
+//!
+//!     #[structopt(skip)]
+//!     k: String,
+//!     #[structopt(skip)]
+//!     v: Vec<u32>,
+//!
+//!     // these fields get set explicitly
+//!
+//!     #[structopt(skip = vec![1, 2, 3])]
+//!     k2: Vec<u32>,
+//!     #[structopt(skip = "cake")] // &str implements Into<String>
+//!     v2: String,
+//! }
+//! ```
+//!
+//! ## Subcommands
+//!
+//! Some applications, especially large ones, split their functionality
+//! through the use of "subcommands". Each of these act somewhat like a separate
+//! command, but is part of the larger group.
+//! One example is `git`, which has subcommands such as `add`, `commit`,
+//! and `clone`, to mention just a few.
+//!
+//! `clap` has this functionality, and `structopt` supports it through enums:
+//!
+//! ```
+//! # use structopt::StructOpt;
+//!
+//! # use std::path::PathBuf;
+//! #[derive(StructOpt)]
+//! #[structopt(about = "the stupid content tracker")]
+//! enum Git {
+//!     Add {
+//!         #[structopt(short)]
+//!         interactive: bool,
+//!         #[structopt(short)]
+//!         patch: bool,
+//!         #[structopt(parse(from_os_str))]
+//!         files: Vec<PathBuf>
+//!     },
+//!     Fetch {
+//!         #[structopt(long)]
+//!         dry_run: bool,
+//!         #[structopt(long)]
+//!         all: bool,
+//!         repository: Option<String>
+//!     },
+//!     Commit {
+//!         #[structopt(short)]
+//!         message: Option<String>,
+//!         #[structopt(short)]
+//!         all: bool
+//!     }
+//! }
+//! ```
+//!
+//! Using `derive(StructOpt)` on an enum instead of a struct will produce
+//! a `clap::App` that only takes subcommands. So `git add`, `git fetch`,
+//! and `git commit` would be commands allowed for the above example.
+//!
+//! `structopt` also provides support for applications where certain flags
+//! need to apply to all subcommands, as well as nested subcommands:
+//!
+//! ```
+//! # use structopt::StructOpt;
+//! #[derive(StructOpt)]
+//! struct MakeCookie {
+//!     #[structopt(name = "supervisor", default_value = "Puck", long = "supervisor")]
+//!     supervising_faerie: String,
+//!     /// The faerie tree this cookie is being made in.
+//!     tree: Option<String>,
+//!     #[structopt(subcommand)]  // Note that we mark a field as a subcommand
+//!     cmd: Command
+//! }
+//!
+//! #[derive(StructOpt)]
+//! enum Command {
+//!     /// Pound acorns into flour for cookie dough.
+//!     Pound {
+//!         acorns: u32
+//!     },
+//!     /// Add magical sparkles -- the secret ingredient!
+//!     Sparkle {
+//!         #[structopt(short, parse(from_occurrences))]
+//!         magicality: u64,
+//!         #[structopt(short)]
+//!         color: String
+//!     },
+//!     Finish(Finish),
+//! }
+//!
+//! // Subcommand can also be externalized by using a 1-uple enum variant
+//! #[derive(StructOpt)]
+//! struct Finish {
+//!     #[structopt(short)]
+//!     time: u32,
+//!     #[structopt(subcommand)]  // Note that we mark a field as a subcommand
+//!     finish_type: FinishType
+//! }
+//!
+//! // subsubcommand!
+//! #[derive(StructOpt)]
+//! enum FinishType {
+//!     Glaze {
+//!         applications: u32
+//!     },
+//!     Powder {
+//!         flavor: String,
+//!         dips: u32
+//!     }
+//! }
+//! ```
+//!
+//! Marking a field with `structopt(subcommand)` will add the subcommands of the
+//! designated enum to the current `clap::App`. The designated enum *must* also
+//! be derived `StructOpt`. So the above example would take the following
+//! commands:
+//!
+//! + `make-cookie pound 50`
+//! + `make-cookie sparkle -mmm --color "green"`
+//! + `make-cookie finish 130 glaze 3`
+//!
+//! ### Optional subcommands
+//!
+//! Subcommands may be optional:
+//!
+//! ```
+//! # use structopt::StructOpt;
+//! #[derive(StructOpt)]
+//! struct Foo {
+//!     file: String,
+//!     #[structopt(subcommand)]
+//!     cmd: Option<Command>
+//! }
+//!
+//! #[derive(StructOpt)]
+//! enum Command {
+//!     Bar,
+//!     Baz,
+//!     Quux
+//! }
+//! ```
+//!
+//! ### External subcommands
+//!
+//! Sometimes you want to support not only the set of well-known subcommands
+//! but you also want to allow other, user-driven subcommands. `clap` supports
+//! this via [`AppSettings::AllowExternalSubcommands`].
+//!
+//! `structopt` provides it's own dedicated syntax for that:
+//!
+//! ```
+//! # use structopt::StructOpt;
+//! #[derive(Debug, PartialEq, StructOpt)]
+//! struct Opt {
+//!     #[structopt(subcommand)]
+//!     sub: Subcommands,
+//! }
+//!
+//! #[derive(Debug, PartialEq, StructOpt)]
+//! enum Subcommands {
+//!     // normal subcommand
+//!     Add,
+//!
+//!     // `external_subcommand` tells structopt to put
+//!     // all the extra arguments into this Vec
+//!     #[structopt(external_subcommand)]
+//!     Other(Vec<String>),
+//! }
+//!
+//! // normal subcommand
+//! assert_eq!(
+//!     Opt::from_iter(&["test", "add"]),
+//!     Opt {
+//!         sub: Subcommands::Add
+//!     }
+//! );
+//!
+//! assert_eq!(
+//!     Opt::from_iter(&["test", "git", "status"]),
+//!     Opt {
+//!         sub: Subcommands::Other(vec!["git".into(), "status".into()])
+//!     }
+//! );
+//!
+//! // Please note that if you'd wanted to allow "no subcommands at all" case
+//! // you should have used `sub: Option<Subcommands>` above
+//! assert!(Opt::from_iter_safe(&["test"]).is_err());
+//! ```
+//!
+//! In other words, you just add an extra tuple variant marked with
+//! `#[structopt(subcommand)]`, and its type must be either
+//! `Vec<String>` or `Vec<OsString>`. `structopt` will detect `String` in this context
+//! and use appropriate `clap` API.
+//!
+//! [`AppSettings::AllowExternalSubcommands`]: https://docs.rs/clap/2.32.0/clap/enum.AppSettings.html#variant.AllowExternalSubcommands
+//!
+//! ### Flattening subcommands
+//!
+//! It is also possible to combine multiple enums of subcommands into one.
+//! All the subcommands will be on the same level.
+//!
+//! ```
+//! # use structopt::StructOpt;
+//! #[derive(StructOpt)]
+//! enum BaseCli {
+//!     Ghost10 {
+//!         arg1: i32,
+//!     }
+//! }
+//!
+//! #[derive(StructOpt)]
+//! enum Opt {
+//!     #[structopt(flatten)]
+//!     BaseCli(BaseCli),
+//!     Dex {
+//!         arg2: i32,
+//!     }
+//! }
+//! ```
+//!
+//! ```shell
+//! cli ghost10 42
+//! cli dex 42
+//! ```
+//!
+//! ## Flattening
+//!
+//! It can sometimes be useful to group related arguments in a substruct,
+//! while keeping the command-line interface flat. In these cases you can mark
+//! a field as `flatten` and give it another type that derives `StructOpt`:
+//!
+//! ```
+//! # use structopt::StructOpt;
+//! #[derive(StructOpt)]
+//! struct Cmdline {
+//!     /// switch on verbosity
+//!     #[structopt(short)]
+//!     verbose: bool,
+//!     #[structopt(flatten)]
+//!     daemon_opts: DaemonOpts,
+//! }
+//!
+//! #[derive(StructOpt)]
+//! struct DaemonOpts {
+//!     /// daemon user
+//!     #[structopt(short)]
+//!     user: String,
+//!     /// daemon group
+//!     #[structopt(short)]
+//!     group: String,
+//! }
+//! ```
+//!
+//! In this example, the derived `Cmdline` parser will support the options `-v`,
+//! `-u` and `-g`.
+//!
+//! This feature also makes it possible to define a `StructOpt` struct in a
+//! library, parse the corresponding arguments in the main argument parser, and
+//! pass off this struct to a handler provided by that library.
+//!
+//! ## Custom string parsers
+//!
+//! If the field type does not have a `FromStr` implementation, or you would
+//! like to provide a custom parsing scheme other than `FromStr`, you may
+//! provide a custom string parser using `parse(...)` like this:
+//!
+//! ```
+//! # use structopt::StructOpt;
+//! use std::num::ParseIntError;
+//! use std::path::PathBuf;
+//!
+//! fn parse_hex(src: &str) -> Result<u32, ParseIntError> {
+//!     u32::from_str_radix(src, 16)
+//! }
+//!
+//! #[derive(StructOpt)]
+//! struct HexReader {
+//!     #[structopt(short, parse(try_from_str = parse_hex))]
+//!     number: u32,
+//!     #[structopt(short, parse(from_os_str))]
+//!     output: PathBuf,
+//! }
+//! ```
+//!
+//! There are five kinds of custom parsers:
+//!
+//! | Kind              | Signature                             | Default                         |
+//! |-------------------|---------------------------------------|---------------------------------|
+//! | `from_str`        | `fn(&str) -> T`                       | `::std::convert::From::from`    |
+//! | `try_from_str`    | `fn(&str) -> Result<T, E>`            | `::std::str::FromStr::from_str` |
+//! | `from_os_str`     | `fn(&OsStr) -> T`                     | `::std::convert::From::from`    |
+//! | `try_from_os_str` | `fn(&OsStr) -> Result<T, OsString>`   | (no default function)           |
+//! | `from_occurrences`| `fn(u64) -> T`                        | `value as T`                    |
+//! | `from_flag`       | `fn(bool) -> T`                       | `::std::convert::From::from`    |
+//!
+//! The `from_occurrences` parser is special. Using `parse(from_occurrences)`
+//! results in the _number of flags occurrences_ being stored in the relevant
+//! field or being passed to the supplied function. In other words, it converts
+//! something like `-vvv` to `3`. This is equivalent to
+//! `.takes_value(false).multiple(true)`. Note that the default parser can only
+//! be used with fields of integer types (`u8`, `usize`, `i64`, etc.).
+//!
+//! The `from_flag` parser is also special. Using `parse(from_flag)` or
+//! `parse(from_flag = some_func)` will result in the field being treated as a
+//! flag even if it does not have type `bool`.
+//!
+//! When supplying a custom string parser, `bool` will not be treated specially:
+//!
+//! Type        | Effect            | Added method call to `clap::Arg`
+//! ------------|-------------------|--------------------------------------
+//! `Option<T>` | optional argument | `.takes_value(true).multiple(false)`
+//! `Vec<T>`    | list of arguments | `.takes_value(true).multiple(true)`
+//! `T`         | required argument | `.takes_value(true).multiple(false).required(!has_default)`
+//!
+//! In the `try_from_*` variants, the function will run twice on valid input:
+//! once to validate, and once to parse. Hence, make sure the function is
+//! side-effect-free.
+
+// those mains are for a reason
+#![allow(clippy::needless_doctest_main)]
+
+#[doc(hidden)]
+pub use structopt_derive::*;
+
+use std::ffi::OsString;
+
+/// Re-exports
+pub use clap;
+
+/// **This is NOT PUBLIC API**.
+#[doc(hidden)]
+pub use lazy_static;
+
+/// A struct that is converted from command line arguments.
+pub trait StructOpt {
+    /// Returns the corresponding `clap::App`.
+    fn clap<'a, 'b>() -> clap::App<'a, 'b>;
+
+    /// Creates the struct from `clap::ArgMatches`.  It cannot fail
+    /// with a parameter generated by `clap` by construction.
+    fn from_clap(matches: &clap::ArgMatches<'_>) -> Self;
+
+    /// Gets the struct from the command line arguments.  Print the
+    /// error message and quit the program in case of failure.
+    fn from_args() -> Self
+    where
+        Self: Sized,
+    {
+        Self::from_clap(&Self::clap().get_matches())
+    }
+
+    /// Gets the struct from any iterator such as a `Vec` of your making.
+    /// Print the error message and quit the program in case of failure.
+    ///
+    /// **NOTE**: The first argument will be parsed as the binary name unless
+    /// [`AppSettings::NoBinaryName`] has been used.
+    ///
+    /// [`AppSettings::NoBinaryName`]: https://docs.rs/clap/2.33.0/clap/enum.AppSettings.html#variant.NoBinaryName
+    fn from_iter<I>(iter: I) -> Self
+    where
+        Self: Sized,
+        I: IntoIterator,
+        I::Item: Into<OsString> + Clone,
+    {
+        Self::from_clap(&Self::clap().get_matches_from(iter))
+    }
+
+    /// Gets the struct from any iterator such as a `Vec` of your making.
+    ///
+    /// Returns a `clap::Error` in case of failure. This does *not* exit in the
+    /// case of `--help` or `--version`, to achieve the same behavior as
+    /// `from_iter()` you must call `.exit()` on the error value.
+    ///
+    /// **NOTE**: The first argument will be parsed as the binary name unless
+    /// [`AppSettings::NoBinaryName`] has been used.
+    ///
+    /// [`AppSettings::NoBinaryName`]: https://docs.rs/clap/2.33.0/clap/enum.AppSettings.html#variant.NoBinaryName
+    fn from_iter_safe<I>(iter: I) -> Result<Self, clap::Error>
+    where
+        Self: Sized,
+        I: IntoIterator,
+        I::Item: Into<OsString> + Clone,
+    {
+        Ok(Self::from_clap(&Self::clap().get_matches_from_safe(iter)?))
+    }
+}
+
+/// This trait is NOT API. **SUBJECT TO CHANGE WITHOUT NOTICE!**.
+#[doc(hidden)]
+pub trait StructOptInternal: StructOpt {
+    fn augment_clap<'a, 'b>(app: clap::App<'a, 'b>) -> clap::App<'a, 'b> {
+        app
+    }
+
+    fn is_subcommand() -> bool {
+        false
+    }
+
+    fn from_subcommand<'a, 'b>(_sub: (&'b str, Option<&'b clap::ArgMatches<'a>>)) -> Option<Self>
+    where
+        Self: std::marker::Sized,
+    {
+        None
+    }
+}
+
+impl<T: StructOpt> StructOpt for Box<T> {
+    fn clap<'a, 'b>() -> clap::App<'a, 'b> {
+        <T as StructOpt>::clap()
+    }
+
+    fn from_clap(matches: &clap::ArgMatches<'_>) -> Self {
+        Box::new(<T as StructOpt>::from_clap(matches))
+    }
+}
+
+impl<T: StructOptInternal> StructOptInternal for Box<T> {
+    #[doc(hidden)]
+    fn is_subcommand() -> bool {
+        <T as StructOptInternal>::is_subcommand()
+    }
+
+    #[doc(hidden)]
+    fn from_subcommand<'a, 'b>(sub: (&'b str, Option<&'b clap::ArgMatches<'a>>)) -> Option<Self> {
+        <T as StructOptInternal>::from_subcommand(sub).map(Box::new)
+    }
+
+    #[doc(hidden)]
+    fn augment_clap<'a, 'b>(app: clap::App<'a, 'b>) -> clap::App<'a, 'b> {
+        <T as StructOptInternal>::augment_clap(app)
+    }
+}
diff --git a/tests/argument_naming.rs b/tests/argument_naming.rs
new file mode 100644
index 0000000..e7fe3d5
--- /dev/null
+++ b/tests/argument_naming.rs
@@ -0,0 +1,311 @@
+use structopt::StructOpt;
+
+#[test]
+fn test_single_word_enum_variant_is_default_renamed_into_kebab_case() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    enum Opt {
+        Command { foo: u32 },
+    }
+
+    assert_eq!(
+        Opt::Command { foo: 0 },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "command", "0"]))
+    );
+}
+
+#[test]
+fn test_multi_word_enum_variant_is_renamed() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    enum Opt {
+        FirstCommand { foo: u32 },
+    }
+
+    assert_eq!(
+        Opt::FirstCommand { foo: 0 },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "first-command", "0"]))
+    );
+}
+
+#[test]
+fn test_standalone_long_generates_kebab_case() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    #[allow(non_snake_case)]
+    struct Opt {
+        #[structopt(long)]
+        FOO_OPTION: bool,
+    }
+
+    assert_eq!(
+        Opt { FOO_OPTION: true },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--foo-option"]))
+    );
+}
+
+#[test]
+fn test_custom_long_overwrites_default_name() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    struct Opt {
+        #[structopt(long = "foo")]
+        foo_option: bool,
+    }
+
+    assert_eq!(
+        Opt { foo_option: true },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--foo"]))
+    );
+}
+
+#[test]
+fn test_standalone_long_uses_previous_defined_custom_name() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    struct Opt {
+        #[structopt(name = "foo", long)]
+        foo_option: bool,
+    }
+
+    assert_eq!(
+        Opt { foo_option: true },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--foo"]))
+    );
+}
+
+#[test]
+fn test_standalone_long_ignores_afterwards_defined_custom_name() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    struct Opt {
+        #[structopt(long, name = "foo")]
+        foo_option: bool,
+    }
+
+    assert_eq!(
+        Opt { foo_option: true },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--foo-option"]))
+    );
+}
+
+#[test]
+fn test_standalone_short_generates_kebab_case() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    #[allow(non_snake_case)]
+    struct Opt {
+        #[structopt(short)]
+        FOO_OPTION: bool,
+    }
+
+    assert_eq!(
+        Opt { FOO_OPTION: true },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-f"]))
+    );
+}
+
+#[test]
+fn test_custom_short_overwrites_default_name() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    struct Opt {
+        #[structopt(short = "o")]
+        foo_option: bool,
+    }
+
+    assert_eq!(
+        Opt { foo_option: true },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-o"]))
+    );
+}
+
+#[test]
+fn test_standalone_short_uses_previous_defined_custom_name() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    struct Opt {
+        #[structopt(name = "option", short)]
+        foo_option: bool,
+    }
+
+    assert_eq!(
+        Opt { foo_option: true },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-o"]))
+    );
+}
+
+#[test]
+fn test_standalone_short_ignores_afterwards_defined_custom_name() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    struct Opt {
+        #[structopt(short, name = "option")]
+        foo_option: bool,
+    }
+
+    assert_eq!(
+        Opt { foo_option: true },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-f"]))
+    );
+}
+
+#[test]
+fn test_standalone_long_uses_previous_defined_casing() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    struct Opt {
+        #[structopt(rename_all = "screaming_snake", long)]
+        foo_option: bool,
+    }
+
+    assert_eq!(
+        Opt { foo_option: true },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--FOO_OPTION"]))
+    );
+}
+
+#[test]
+fn test_standalone_short_uses_previous_defined_casing() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    struct Opt {
+        #[structopt(rename_all = "screaming_snake", short)]
+        foo_option: bool,
+    }
+
+    assert_eq!(
+        Opt { foo_option: true },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-F"]))
+    );
+}
+
+#[test]
+fn test_standalone_long_works_with_verbatim_casing() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    #[allow(non_snake_case)]
+    struct Opt {
+        #[structopt(rename_all = "verbatim", long)]
+        _fOO_oPtiON: bool,
+    }
+
+    assert_eq!(
+        Opt { _fOO_oPtiON: true },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--_fOO_oPtiON"]))
+    );
+}
+
+#[test]
+fn test_standalone_short_works_with_verbatim_casing() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    struct Opt {
+        #[structopt(rename_all = "verbatim", short)]
+        _foo: bool,
+    }
+
+    assert_eq!(
+        Opt { _foo: true },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-_"]))
+    );
+}
+
+#[test]
+fn test_rename_all_is_propagated_from_struct_to_fields() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    #[structopt(rename_all = "screaming_snake")]
+    struct Opt {
+        #[structopt(long)]
+        foo: bool,
+    }
+
+    assert_eq!(
+        Opt { foo: true },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--FOO"]))
+    );
+}
+
+#[test]
+fn test_rename_all_is_not_propagated_from_struct_into_flattened() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    #[structopt(rename_all = "screaming_snake")]
+    struct Opt {
+        #[structopt(flatten)]
+        foo: Foo,
+    }
+
+    #[derive(StructOpt, Debug, PartialEq)]
+    struct Foo {
+        #[structopt(long)]
+        foo: bool,
+    }
+
+    assert_eq!(
+        Opt {
+            foo: Foo { foo: true }
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--foo"]))
+    );
+}
+
+#[test]
+fn test_rename_all_is_not_propagated_from_struct_into_subcommand() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    #[structopt(rename_all = "screaming_snake")]
+    struct Opt {
+        #[structopt(subcommand)]
+        foo: Foo,
+    }
+
+    #[derive(StructOpt, Debug, PartialEq)]
+    enum Foo {
+        Command {
+            #[structopt(long)]
+            foo: bool,
+        },
+    }
+
+    assert_eq!(
+        Opt {
+            foo: Foo::Command { foo: true }
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "command", "--foo"]))
+    );
+}
+
+#[test]
+fn test_rename_all_is_propagated_from_enum_to_variants_and_their_fields() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    #[structopt(rename_all = "screaming_snake")]
+    enum Opt {
+        FirstVariant,
+        SecondVariant {
+            #[structopt(long)]
+            foo: bool,
+        },
+    }
+
+    assert_eq!(
+        Opt::FirstVariant,
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "FIRST_VARIANT"]))
+    );
+
+    assert_eq!(
+        Opt::SecondVariant { foo: true },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "SECOND_VARIANT", "--FOO"]))
+    );
+}
+
+#[test]
+fn test_rename_all_is_propagation_can_be_overridden() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    #[structopt(rename_all = "screaming_snake")]
+    enum Opt {
+        #[structopt(rename_all = "kebab_case")]
+        FirstVariant {
+            #[structopt(long)]
+            foo_option: bool,
+        },
+        SecondVariant {
+            #[structopt(rename_all = "kebab_case", long)]
+            foo_option: bool,
+        },
+    }
+
+    assert_eq!(
+        Opt::FirstVariant { foo_option: true },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "first-variant", "--foo-option"]))
+    );
+
+    assert_eq!(
+        Opt::SecondVariant { foo_option: true },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "SECOND_VARIANT", "--foo-option"]))
+    );
+}
diff --git a/tests/arguments.rs b/tests/arguments.rs
new file mode 100644
index 0000000..96a0938
--- /dev/null
+++ b/tests/arguments.rs
@@ -0,0 +1,86 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::clap;
+use structopt::StructOpt;
+
+#[test]
+fn required_argument() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        arg: i32,
+    }
+    assert_eq!(Opt { arg: 42 }, Opt::from_iter(&["test", "42"]));
+    assert!(Opt::clap().get_matches_from_safe(&["test"]).is_err());
+    assert!(Opt::clap()
+        .get_matches_from_safe(&["test", "42", "24"])
+        .is_err());
+}
+
+#[test]
+fn optional_argument() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        arg: Option<i32>,
+    }
+    assert_eq!(Opt { arg: Some(42) }, Opt::from_iter(&["test", "42"]));
+    assert_eq!(Opt { arg: None }, Opt::from_iter(&["test"]));
+    assert!(Opt::clap()
+        .get_matches_from_safe(&["test", "42", "24"])
+        .is_err());
+}
+
+#[test]
+fn argument_with_default() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(default_value = "42")]
+        arg: i32,
+    }
+    assert_eq!(Opt { arg: 24 }, Opt::from_iter(&["test", "24"]));
+    assert_eq!(Opt { arg: 42 }, Opt::from_iter(&["test"]));
+    assert!(Opt::clap()
+        .get_matches_from_safe(&["test", "42", "24"])
+        .is_err());
+}
+
+#[test]
+fn arguments() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        arg: Vec<i32>,
+    }
+    assert_eq!(Opt { arg: vec![24] }, Opt::from_iter(&["test", "24"]));
+    assert_eq!(Opt { arg: vec![] }, Opt::from_iter(&["test"]));
+    assert_eq!(
+        Opt { arg: vec![24, 42] },
+        Opt::from_iter(&["test", "24", "42"])
+    );
+}
+
+#[test]
+fn arguments_safe() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        arg: Vec<i32>,
+    }
+    assert_eq!(
+        Opt { arg: vec![24] },
+        Opt::from_iter_safe(&["test", "24"]).unwrap()
+    );
+    assert_eq!(Opt { arg: vec![] }, Opt::from_iter_safe(&["test"]).unwrap());
+    assert_eq!(
+        Opt { arg: vec![24, 42] },
+        Opt::from_iter_safe(&["test", "24", "42"]).unwrap()
+    );
+
+    assert_eq!(
+        clap::ErrorKind::ValueValidation,
+        Opt::from_iter_safe(&["test", "NOPE"]).err().unwrap().kind
+    );
+}
diff --git a/tests/author_version_about.rs b/tests/author_version_about.rs
new file mode 100644
index 0000000..0f1c8b5
--- /dev/null
+++ b/tests/author_version_about.rs
@@ -0,0 +1,58 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+mod utils;
+
+use structopt::StructOpt;
+use utils::*;
+
+#[test]
+fn no_author_version_about() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    #[structopt(name = "foo", no_version)]
+    struct Opt {}
+
+    let output = get_long_help::<Opt>();
+    assert!(output.starts_with("foo \n\nUSAGE:"));
+}
+
+#[test]
+fn use_env() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    #[structopt(author, about)]
+    struct Opt {}
+
+    let output = get_long_help::<Opt>();
+    assert!(output.starts_with("structopt 0."));
+    assert!(output.contains("Guillaume Pinot <texitoi@texitoi.eu>, others"));
+    assert!(output.contains("Parse command line argument by defining a struct."));
+}
+
+#[test]
+fn explicit_version_not_str() {
+    const VERSION: &str = "custom version";
+
+    #[derive(StructOpt)]
+    #[structopt(version = VERSION)]
+    pub struct Opt {}
+
+    let output = get_long_help::<Opt>();
+    assert!(output.contains("custom version"));
+}
+
+#[test]
+fn no_version_gets_propagated() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    #[structopt(no_version)]
+    enum Action {
+        Move,
+    }
+
+    let output = get_subcommand_long_help::<Action>("move");
+    assert_eq!(output.lines().next(), Some("test-move "));
+}
diff --git a/tests/custom-string-parsers.rs b/tests/custom-string-parsers.rs
new file mode 100644
index 0000000..89070ed
--- /dev/null
+++ b/tests/custom-string-parsers.rs
@@ -0,0 +1,306 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+use std::ffi::{CString, OsStr, OsString};
+use std::num::ParseIntError;
+use std::path::PathBuf;
+
+#[derive(StructOpt, PartialEq, Debug)]
+struct PathOpt {
+    #[structopt(short, long, parse(from_os_str))]
+    path: PathBuf,
+
+    #[structopt(short, default_value = "../", parse(from_os_str))]
+    default_path: PathBuf,
+
+    #[structopt(short, parse(from_os_str))]
+    vector_path: Vec<PathBuf>,
+
+    #[structopt(short, parse(from_os_str))]
+    option_path_1: Option<PathBuf>,
+
+    #[structopt(short = "q", parse(from_os_str))]
+    option_path_2: Option<PathBuf>,
+}
+
+#[test]
+fn test_path_opt_simple() {
+    assert_eq!(
+        PathOpt {
+            path: PathBuf::from("/usr/bin"),
+            default_path: PathBuf::from("../"),
+            vector_path: vec![
+                PathBuf::from("/a/b/c"),
+                PathBuf::from("/d/e/f"),
+                PathBuf::from("/g/h/i"),
+            ],
+            option_path_1: None,
+            option_path_2: Some(PathBuf::from("j.zip")),
+        },
+        PathOpt::from_clap(&PathOpt::clap().get_matches_from(&[
+            "test", "-p", "/usr/bin", "-v", "/a/b/c", "-v", "/d/e/f", "-v", "/g/h/i", "-q",
+            "j.zip",
+        ]))
+    );
+}
+
+fn parse_hex(input: &str) -> Result<u64, ParseIntError> {
+    u64::from_str_radix(input, 16)
+}
+
+#[derive(StructOpt, PartialEq, Debug)]
+struct HexOpt {
+    #[structopt(short, parse(try_from_str = parse_hex))]
+    number: u64,
+}
+
+#[test]
+#[allow(clippy::unreadable_literal)]
+fn test_parse_hex() {
+    assert_eq!(
+        HexOpt { number: 5 },
+        HexOpt::from_clap(&HexOpt::clap().get_matches_from(&["test", "-n", "5"]))
+    );
+    assert_eq!(
+        HexOpt { number: 0xabcdef },
+        HexOpt::from_clap(&HexOpt::clap().get_matches_from(&["test", "-n", "abcdef"]))
+    );
+
+    let err = HexOpt::clap()
+        .get_matches_from_safe(&["test", "-n", "gg"])
+        .unwrap_err();
+    assert!(err.message.contains("invalid digit found in string"), err);
+}
+
+fn custom_parser_1(_: &str) -> &'static str {
+    "A"
+}
+fn custom_parser_2(_: &str) -> Result<&'static str, u32> {
+    Ok("B")
+}
+fn custom_parser_3(_: &OsStr) -> &'static str {
+    "C"
+}
+fn custom_parser_4(_: &OsStr) -> Result<&'static str, OsString> {
+    Ok("D")
+}
+
+#[derive(StructOpt, PartialEq, Debug)]
+struct NoOpOpt {
+    #[structopt(short, parse(from_str = custom_parser_1))]
+    a: &'static str,
+    #[structopt(short, parse(try_from_str = custom_parser_2))]
+    b: &'static str,
+    #[structopt(short, parse(from_os_str = custom_parser_3))]
+    c: &'static str,
+    #[structopt(short, parse(try_from_os_str = custom_parser_4))]
+    d: &'static str,
+}
+
+#[test]
+fn test_every_custom_parser() {
+    assert_eq!(
+        NoOpOpt {
+            a: "A",
+            b: "B",
+            c: "C",
+            d: "D"
+        },
+        NoOpOpt::from_clap(
+            &NoOpOpt::clap().get_matches_from(&["test", "-a=?", "-b=?", "-c=?", "-d=?"])
+        )
+    );
+}
+
+// Note: can't use `Vec<u8>` directly, as structopt would instead look for
+// conversion function from `&str` to `u8`.
+type Bytes = Vec<u8>;
+
+#[derive(StructOpt, PartialEq, Debug)]
+struct DefaultedOpt {
+    #[structopt(short, parse(from_str))]
+    bytes: Bytes,
+
+    #[structopt(short, parse(try_from_str))]
+    integer: u64,
+
+    #[structopt(short, parse(from_os_str))]
+    path: PathBuf,
+}
+
+#[test]
+fn test_parser_with_default_value() {
+    assert_eq!(
+        DefaultedOpt {
+            bytes: b"E\xc2\xb2=p\xc2\xb2c\xc2\xb2+m\xc2\xb2c\xe2\x81\xb4".to_vec(),
+            integer: 9000,
+            path: PathBuf::from("src/lib.rs"),
+        },
+        DefaultedOpt::from_clap(&DefaultedOpt::clap().get_matches_from(&[
+            "test",
+            "-b",
+            "E²=p²c²+m²c⁴",
+            "-i",
+            "9000",
+            "-p",
+            "src/lib.rs",
+        ]))
+    );
+}
+
+#[derive(PartialEq, Debug)]
+struct Foo(u8);
+
+fn foo(value: u64) -> Foo {
+    Foo(value as u8)
+}
+
+#[derive(StructOpt, PartialEq, Debug)]
+struct Occurrences {
+    #[structopt(short, long, parse(from_occurrences))]
+    signed: i32,
+
+    #[structopt(short, parse(from_occurrences))]
+    little_signed: i8,
+
+    #[structopt(short, parse(from_occurrences))]
+    unsigned: usize,
+
+    #[structopt(short = "r", parse(from_occurrences))]
+    little_unsigned: u8,
+
+    #[structopt(short, long, parse(from_occurrences = foo))]
+    custom: Foo,
+}
+
+#[test]
+fn test_parser_occurrences() {
+    assert_eq!(
+        Occurrences {
+            signed: 3,
+            little_signed: 1,
+            unsigned: 0,
+            little_unsigned: 4,
+            custom: Foo(5),
+        },
+        Occurrences::from_clap(&Occurrences::clap().get_matches_from(&[
+            "test", "-s", "--signed", "--signed", "-l", "-rrrr", "-cccc", "--custom",
+        ]))
+    );
+}
+
+#[test]
+fn test_custom_bool() {
+    fn parse_bool(s: &str) -> Result<bool, String> {
+        match s {
+            "true" => Ok(true),
+            "false" => Ok(false),
+            _ => Err(format!("invalid bool {}", s)),
+        }
+    }
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(short, parse(try_from_str = parse_bool))]
+        debug: bool,
+        #[structopt(
+            short,
+            default_value = "false",
+            parse(try_from_str = parse_bool)
+        )]
+        verbose: bool,
+        #[structopt(short, parse(try_from_str = parse_bool))]
+        tribool: Option<bool>,
+        #[structopt(short, parse(try_from_str = parse_bool))]
+        bitset: Vec<bool>,
+    }
+
+    assert!(Opt::clap().get_matches_from_safe(&["test"]).is_err());
+    assert!(Opt::clap().get_matches_from_safe(&["test", "-d"]).is_err());
+    assert!(Opt::clap()
+        .get_matches_from_safe(&["test", "-dfoo"])
+        .is_err());
+    assert_eq!(
+        Opt {
+            debug: false,
+            verbose: false,
+            tribool: None,
+            bitset: vec![],
+        },
+        Opt::from_iter(&["test", "-dfalse"])
+    );
+    assert_eq!(
+        Opt {
+            debug: true,
+            verbose: false,
+            tribool: None,
+            bitset: vec![],
+        },
+        Opt::from_iter(&["test", "-dtrue"])
+    );
+    assert_eq!(
+        Opt {
+            debug: true,
+            verbose: false,
+            tribool: None,
+            bitset: vec![],
+        },
+        Opt::from_iter(&["test", "-dtrue", "-vfalse"])
+    );
+    assert_eq!(
+        Opt {
+            debug: true,
+            verbose: true,
+            tribool: None,
+            bitset: vec![],
+        },
+        Opt::from_iter(&["test", "-dtrue", "-vtrue"])
+    );
+    assert_eq!(
+        Opt {
+            debug: true,
+            verbose: false,
+            tribool: Some(false),
+            bitset: vec![],
+        },
+        Opt::from_iter(&["test", "-dtrue", "-tfalse"])
+    );
+    assert_eq!(
+        Opt {
+            debug: true,
+            verbose: false,
+            tribool: Some(true),
+            bitset: vec![],
+        },
+        Opt::from_iter(&["test", "-dtrue", "-ttrue"])
+    );
+    assert_eq!(
+        Opt {
+            debug: true,
+            verbose: false,
+            tribool: None,
+            bitset: vec![false, true, false, false],
+        },
+        Opt::from_iter(&["test", "-dtrue", "-bfalse", "-btrue", "-bfalse", "-bfalse"])
+    );
+}
+
+#[test]
+fn test_cstring() {
+    #[derive(StructOpt)]
+    struct Opt {
+        #[structopt(parse(try_from_str = CString::new))]
+        c_string: CString,
+    }
+    assert!(Opt::clap().get_matches_from_safe(&["test"]).is_err());
+    assert_eq!(Opt::from_iter(&["test", "bla"]).c_string.to_bytes(), b"bla");
+    assert!(Opt::clap()
+        .get_matches_from_safe(&["test", "bla\0bla"])
+        .is_err());
+}
diff --git a/tests/default_value.rs b/tests/default_value.rs
new file mode 100644
index 0000000..383bd23
--- /dev/null
+++ b/tests/default_value.rs
@@ -0,0 +1,19 @@
+use structopt::StructOpt;
+
+mod utils;
+
+use utils::*;
+
+#[test]
+fn auto_default_value() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(default_value)]
+        arg: i32,
+    }
+    assert_eq!(Opt { arg: 0 }, Opt::from_iter(&["test"]));
+    assert_eq!(Opt { arg: 1 }, Opt::from_iter(&["test", "1"]));
+
+    let help = get_long_help::<Opt>();
+    assert!(help.contains("[default: 0]"));
+}
diff --git a/tests/deny-warnings.rs b/tests/deny-warnings.rs
new file mode 100644
index 0000000..721204a
--- /dev/null
+++ b/tests/deny-warnings.rs
@@ -0,0 +1,47 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+#![deny(warnings)]
+
+use structopt::StructOpt;
+
+fn try_str(s: &str) -> Result<String, std::convert::Infallible> {
+    Ok(s.into())
+}
+
+#[test]
+fn warning_never_struct() {
+    #[derive(Debug, PartialEq, StructOpt)]
+    struct Opt {
+        #[structopt(parse(try_from_str = try_str))]
+        s: String,
+    }
+    assert_eq!(
+        Opt {
+            s: "foo".to_string()
+        },
+        Opt::from_iter(&["test", "foo"])
+    );
+}
+
+#[test]
+fn warning_never_enum() {
+    #[derive(Debug, PartialEq, StructOpt)]
+    enum Opt {
+        Foo {
+            #[structopt(parse(try_from_str = try_str))]
+            s: String,
+        },
+    }
+    assert_eq!(
+        Opt::Foo {
+            s: "foo".to_string()
+        },
+        Opt::from_iter(&["test", "foo", "foo"])
+    );
+}
diff --git a/tests/doc-comments-help.rs b/tests/doc-comments-help.rs
new file mode 100644
index 0000000..1d31683
--- /dev/null
+++ b/tests/doc-comments-help.rs
@@ -0,0 +1,185 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+mod utils;
+
+use structopt::StructOpt;
+use utils::*;
+
+#[test]
+fn doc_comments() {
+    /// Lorem ipsum
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct LoremIpsum {
+        /// Fooify a bar
+        /// and a baz
+        #[structopt(short, long)]
+        foo: bool,
+    }
+
+    let help = get_long_help::<LoremIpsum>();
+    assert!(help.contains("Lorem ipsum"));
+    assert!(help.contains("Fooify a bar and a baz"));
+}
+
+#[test]
+fn help_is_better_than_comments() {
+    /// Lorem ipsum
+    #[derive(StructOpt, PartialEq, Debug)]
+    #[structopt(name = "lorem-ipsum", about = "Dolor sit amet")]
+    struct LoremIpsum {
+        /// Fooify a bar
+        #[structopt(short, long, help = "DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES")]
+        foo: bool,
+    }
+
+    let help = get_long_help::<LoremIpsum>();
+    assert!(help.contains("Dolor sit amet"));
+    assert!(!help.contains("Lorem ipsum"));
+    assert!(help.contains("DO NOT PASS A BAR"));
+}
+
+#[test]
+fn empty_line_in_doc_comment_is_double_linefeed() {
+    /// Foo.
+    ///
+    /// Bar
+    #[derive(StructOpt, PartialEq, Debug)]
+    #[structopt(name = "lorem-ipsum", no_version)]
+    struct LoremIpsum {}
+
+    let help = get_long_help::<LoremIpsum>();
+    assert!(help.starts_with("lorem-ipsum \nFoo.\n\nBar\n\nUSAGE:"));
+}
+
+#[test]
+fn field_long_doc_comment_both_help_long_help() {
+    /// Lorem ipsumclap
+    #[derive(StructOpt, PartialEq, Debug)]
+    #[structopt(name = "lorem-ipsum", about = "Dolor sit amet")]
+    struct LoremIpsum {
+        /// Dot is removed from multiline comments.
+        ///
+        /// Long help
+        #[structopt(long)]
+        foo: bool,
+
+        /// Dot is removed from one short comment.
+        #[structopt(long)]
+        bar: bool,
+    }
+
+    let short_help = get_help::<LoremIpsum>();
+    let long_help = get_long_help::<LoremIpsum>();
+
+    assert!(short_help.contains("Dot is removed from one short comment"));
+    assert!(!short_help.contains("Dot is removed from one short comment."));
+    assert!(short_help.contains("Dot is removed from multiline comments"));
+    assert!(!short_help.contains("Dot is removed from multiline comments."));
+    assert!(long_help.contains("Long help"));
+    assert!(!short_help.contains("Long help"));
+}
+
+#[test]
+fn top_long_doc_comment_both_help_long_help() {
+    /// Lorem ipsumclap
+    #[derive(StructOpt, Debug)]
+    #[structopt(name = "lorem-ipsum", about = "Dolor sit amet")]
+    struct LoremIpsum {
+        #[structopt(subcommand)]
+        foo: SubCommand,
+    }
+
+    #[derive(StructOpt, Debug)]
+    pub enum SubCommand {
+        /// DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES
+        ///
+        /// Or something else
+        Foo {
+            #[structopt(help = "foo")]
+            bars: Vec<String>,
+        },
+    }
+
+    let short_help = get_help::<LoremIpsum>();
+    let long_help = get_subcommand_long_help::<LoremIpsum>("foo");
+
+    assert!(!short_help.contains("Or something else"));
+    assert!(long_help.contains("DO NOT PASS A BAR UNDER ANY CIRCUMSTANCES"));
+    assert!(long_help.contains("Or something else"));
+}
+
+#[test]
+fn verbatim_doc_comment() {
+    /// DANCE!
+    ///
+    ///                    ()
+    ///                    |
+    ///               (   ()   )
+    ///     ) ________    //  )
+    ///  ()  |\       \  //
+    /// ( \\__ \ ______\//
+    ///    \__) |       |
+    ///      |  |       |
+    ///       \ |       |
+    ///        \|_______|
+    ///        //    \\
+    ///       ((     ||
+    ///        \\    ||
+    ///      ( ()    ||
+    ///       (      () ) )
+    #[derive(StructOpt, Debug)]
+    #[structopt(verbatim_doc_comment)]
+    struct SeeFigure1 {
+        #[structopt(long)]
+        foo: bool,
+    }
+
+    let help = get_long_help::<SeeFigure1>();
+    let sample = r#"
+                   ()
+                   |
+              (   ()   )
+    ) ________    //  )
+ ()  |\       \  //
+( \\__ \ ______\//
+   \__) |       |
+     |  |       |
+      \ |       |
+       \|_______|
+       //    \\
+      ((     ||
+       \\    ||
+     ( ()    ||
+      (      () ) )"#;
+
+    assert!(help.contains(sample))
+}
+
+#[test]
+fn verbatim_doc_comment_field() {
+    #[derive(StructOpt, Debug)]
+    struct App {
+        /// This help ends in a period.
+        #[structopt(long, verbatim_doc_comment)]
+        foo: bool,
+        /// This help does not end in a period.
+        #[structopt(long)]
+        bar: bool,
+    }
+
+    let help = get_long_help::<App>();
+    let sample = r#"
+        --bar        
+            This help does not end in a period
+
+        --foo        
+            This help ends in a period."#;
+
+    assert!(help.contains(sample))
+}
diff --git a/tests/explicit_name_no_renaming.rs b/tests/explicit_name_no_renaming.rs
new file mode 100644
index 0000000..eff7a86
--- /dev/null
+++ b/tests/explicit_name_no_renaming.rs
@@ -0,0 +1,32 @@
+mod utils;
+
+use structopt::StructOpt;
+use utils::*;
+
+#[test]
+fn explicit_short_long_no_rename() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(short = ".", long = ".foo")]
+        foo: Vec<String>,
+    }
+
+    assert_eq!(
+        Opt {
+            foo: vec!["short".into(), "long".into()]
+        },
+        Opt::from_iter(&["test", "-.", "short", "--.foo", "long"])
+    );
+}
+
+#[test]
+fn explicit_name_no_rename() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(name = ".options")]
+        foo: Vec<String>,
+    }
+
+    let help = get_long_help::<Opt>();
+    assert!(help.contains("[.options]..."))
+}
diff --git a/tests/flags.rs b/tests/flags.rs
new file mode 100644
index 0000000..39a5dc3
--- /dev/null
+++ b/tests/flags.rs
@@ -0,0 +1,162 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[test]
+fn unique_flag() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(short, long)]
+        alice: bool,
+    }
+
+    assert_eq!(
+        Opt { alice: false },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test"]))
+    );
+    assert_eq!(
+        Opt { alice: true },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a"]))
+    );
+    assert_eq!(
+        Opt { alice: true },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--alice"]))
+    );
+    assert!(Opt::clap().get_matches_from_safe(&["test", "-i"]).is_err());
+    assert!(Opt::clap()
+        .get_matches_from_safe(&["test", "-a", "foo"])
+        .is_err());
+    assert!(Opt::clap()
+        .get_matches_from_safe(&["test", "-a", "-a"])
+        .is_err());
+    assert!(Opt::clap()
+        .get_matches_from_safe(&["test", "-a", "--alice"])
+        .is_err());
+}
+
+#[test]
+fn multiple_flag() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(short, long, parse(from_occurrences))]
+        alice: u64,
+        #[structopt(short, long, parse(from_occurrences))]
+        bob: u8,
+    }
+
+    assert_eq!(
+        Opt { alice: 0, bob: 0 },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test"]))
+    );
+    assert_eq!(
+        Opt { alice: 1, bob: 0 },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a"]))
+    );
+    assert_eq!(
+        Opt { alice: 2, bob: 0 },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "-a"]))
+    );
+    assert_eq!(
+        Opt { alice: 2, bob: 2 },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "--alice", "-bb"]))
+    );
+    assert_eq!(
+        Opt { alice: 3, bob: 1 },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-aaa", "--bob"]))
+    );
+    assert!(Opt::clap().get_matches_from_safe(&["test", "-i"]).is_err());
+    assert!(Opt::clap()
+        .get_matches_from_safe(&["test", "-a", "foo"])
+        .is_err());
+}
+
+fn parse_from_flag(b: bool) -> std::sync::atomic::AtomicBool {
+    std::sync::atomic::AtomicBool::new(b)
+}
+
+#[test]
+fn non_bool_flags() {
+    #[derive(StructOpt, Debug)]
+    struct Opt {
+        #[structopt(short, long, parse(from_flag = parse_from_flag))]
+        alice: std::sync::atomic::AtomicBool,
+        #[structopt(short, long, parse(from_flag))]
+        bob: std::sync::atomic::AtomicBool,
+    }
+
+    let falsey = Opt::from_clap(&Opt::clap().get_matches_from(&["test"]));
+    assert!(!falsey.alice.load(std::sync::atomic::Ordering::Relaxed));
+    assert!(!falsey.bob.load(std::sync::atomic::Ordering::Relaxed));
+
+    let alice = Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a"]));
+    assert!(alice.alice.load(std::sync::atomic::Ordering::Relaxed));
+    assert!(!alice.bob.load(std::sync::atomic::Ordering::Relaxed));
+
+    let bob = Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-b"]));
+    assert!(!bob.alice.load(std::sync::atomic::Ordering::Relaxed));
+    assert!(bob.bob.load(std::sync::atomic::Ordering::Relaxed));
+
+    let both = Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-b", "-a"]));
+    assert!(both.alice.load(std::sync::atomic::Ordering::Relaxed));
+    assert!(both.bob.load(std::sync::atomic::Ordering::Relaxed));
+}
+
+#[test]
+fn combined_flags() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(short, long)]
+        alice: bool,
+        #[structopt(short, long, parse(from_occurrences))]
+        bob: u64,
+    }
+
+    assert_eq!(
+        Opt {
+            alice: false,
+            bob: 0
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test"]))
+    );
+    assert_eq!(
+        Opt {
+            alice: true,
+            bob: 0
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a"]))
+    );
+    assert_eq!(
+        Opt {
+            alice: true,
+            bob: 0
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a"]))
+    );
+    assert_eq!(
+        Opt {
+            alice: false,
+            bob: 1
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-b"]))
+    );
+    assert_eq!(
+        Opt {
+            alice: true,
+            bob: 1
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--alice", "--bob"]))
+    );
+    assert_eq!(
+        Opt {
+            alice: true,
+            bob: 4
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-bb", "-a", "-bb"]))
+    );
+}
diff --git a/tests/flatten.rs b/tests/flatten.rs
new file mode 100644
index 0000000..f01e44e
--- /dev/null
+++ b/tests/flatten.rs
@@ -0,0 +1,129 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[test]
+fn flatten() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Common {
+        arg: i32,
+    }
+
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(flatten)]
+        common: Common,
+    }
+    assert_eq!(
+        Opt {
+            common: Common { arg: 42 }
+        },
+        Opt::from_iter(&["test", "42"])
+    );
+    assert!(Opt::clap().get_matches_from_safe(&["test"]).is_err());
+    assert!(Opt::clap()
+        .get_matches_from_safe(&["test", "42", "24"])
+        .is_err());
+}
+
+#[test]
+#[should_panic]
+fn flatten_twice() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Common {
+        arg: i32,
+    }
+
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(flatten)]
+        c1: Common,
+        // Defines "arg" twice, so this should not work.
+        #[structopt(flatten)]
+        c2: Common,
+    }
+    Opt::from_iter(&["test", "42", "43"]);
+}
+
+#[test]
+fn flatten_in_subcommand() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Common {
+        arg: i32,
+    }
+
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Add {
+        #[structopt(short)]
+        interactive: bool,
+        #[structopt(flatten)]
+        common: Common,
+    }
+
+    #[derive(StructOpt, PartialEq, Debug)]
+    enum Opt {
+        Fetch {
+            #[structopt(short)]
+            all: bool,
+            #[structopt(flatten)]
+            common: Common,
+        },
+
+        Add(Add),
+    }
+
+    assert_eq!(
+        Opt::Fetch {
+            all: false,
+            common: Common { arg: 42 }
+        },
+        Opt::from_iter(&["test", "fetch", "42"])
+    );
+    assert_eq!(
+        Opt::Add(Add {
+            interactive: true,
+            common: Common { arg: 43 }
+        }),
+        Opt::from_iter(&["test", "add", "-i", "43"])
+    );
+}
+
+#[test]
+fn merge_subcommands_with_flatten() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    enum BaseCli {
+        Command1(Command1),
+    }
+
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Command1 {
+        arg1: i32,
+    }
+
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Command2 {
+        arg2: i32,
+    }
+
+    #[derive(StructOpt, PartialEq, Debug)]
+    enum Opt {
+        #[structopt(flatten)]
+        BaseCli(BaseCli),
+        Command2(Command2),
+    }
+
+    assert_eq!(
+        Opt::BaseCli(BaseCli::Command1(Command1 { arg1: 42 })),
+        Opt::from_iter(&["test", "command1", "42"])
+    );
+    assert_eq!(
+        Opt::Command2(Command2 { arg2: 43 }),
+        Opt::from_iter(&["test", "command2", "43"])
+    );
+}
diff --git a/tests/issues.rs b/tests/issues.rs
new file mode 100644
index 0000000..8b4ac4b
--- /dev/null
+++ b/tests/issues.rs
@@ -0,0 +1,117 @@
+// https://github.com/TeXitoi/structopt/issues/{NUMBER}
+
+mod utils;
+use utils::*;
+
+use structopt::StructOpt;
+
+#[test]
+fn issue_151() {
+    use structopt::{clap::ArgGroup, StructOpt};
+
+    #[derive(StructOpt, Debug)]
+    #[structopt(group = ArgGroup::with_name("verb").required(true).multiple(true))]
+    struct Opt {
+        #[structopt(long, group = "verb")]
+        foo: bool,
+        #[structopt(long, group = "verb")]
+        bar: bool,
+    }
+
+    #[derive(Debug, StructOpt)]
+    struct Cli {
+        #[structopt(flatten)]
+        a: Opt,
+    }
+
+    assert!(Cli::clap().get_matches_from_safe(&["test"]).is_err());
+    assert!(Cli::clap()
+        .get_matches_from_safe(&["test", "--foo"])
+        .is_ok());
+    assert!(Cli::clap()
+        .get_matches_from_safe(&["test", "--bar"])
+        .is_ok());
+    assert!(Cli::clap()
+        .get_matches_from_safe(&["test", "--zebra"])
+        .is_err());
+    assert!(Cli::clap()
+        .get_matches_from_safe(&["test", "--foo", "--bar"])
+        .is_ok());
+}
+
+#[test]
+fn issue_289() {
+    use structopt::{clap::AppSettings, StructOpt};
+
+    #[derive(StructOpt)]
+    #[structopt(setting = AppSettings::InferSubcommands)]
+    enum Args {
+        SomeCommand(SubSubCommand),
+        AnotherCommand,
+    }
+
+    #[derive(StructOpt)]
+    #[structopt(setting = AppSettings::InferSubcommands)]
+    enum SubSubCommand {
+        TestCommand,
+    }
+
+    assert!(Args::clap()
+        .get_matches_from_safe(&["test", "some-command", "test-command"])
+        .is_ok());
+    assert!(Args::clap()
+        .get_matches_from_safe(&["test", "some", "test-command"])
+        .is_ok());
+    assert!(Args::clap()
+        .get_matches_from_safe(&["test", "some-command", "test"])
+        .is_ok());
+    assert!(Args::clap()
+        .get_matches_from_safe(&["test", "some", "test"])
+        .is_ok());
+}
+
+#[test]
+fn issue_324() {
+    fn my_version() -> &'static str {
+        "MY_VERSION"
+    }
+
+    #[derive(StructOpt)]
+    #[structopt(version = my_version())]
+    struct Opt {
+        #[structopt(subcommand)]
+        _cmd: Option<SubCommand>,
+    }
+
+    #[derive(StructOpt)]
+    enum SubCommand {
+        Start,
+    }
+
+    let help = get_long_help::<Opt>();
+    assert!(help.contains("MY_VERSION"));
+}
+
+#[test]
+fn issue_359() {
+    #[derive(Debug, PartialEq, StructOpt)]
+    struct Opt {
+        #[structopt(subcommand)]
+        sub: Subcommands,
+    }
+
+    #[derive(Debug, PartialEq, StructOpt)]
+    enum Subcommands {
+        Add,
+
+        #[structopt(external_subcommand)]
+        Other(Vec<String>),
+    }
+
+    assert_eq!(
+        Opt {
+            sub: Subcommands::Other(vec!["only_one_arg".into()])
+        },
+        Opt::from_iter(&["test", "only_one_arg"])
+    );
+}
diff --git a/tests/macro-errors.rs b/tests/macro-errors.rs
new file mode 100644
index 0000000..ae4f5a2
--- /dev/null
+++ b/tests/macro-errors.rs
@@ -0,0 +1,13 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+
+#[rustversion::attr(any(not(stable), before(1.39)), ignore)]
+#[test]
+fn ui() {
+    let t = trybuild::TestCases::new();
+    t.compile_fail("tests/ui/*.rs");
+}
diff --git a/tests/nested-subcommands.rs b/tests/nested-subcommands.rs
new file mode 100644
index 0000000..1fbd166
--- /dev/null
+++ b/tests/nested-subcommands.rs
@@ -0,0 +1,193 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, PartialEq, Debug)]
+struct Opt {
+    #[structopt(short, long)]
+    force: bool,
+    #[structopt(short, long, parse(from_occurrences))]
+    verbose: u64,
+    #[structopt(subcommand)]
+    cmd: Sub,
+}
+
+#[derive(StructOpt, PartialEq, Debug)]
+enum Sub {
+    Fetch {},
+    Add {},
+}
+
+#[derive(StructOpt, PartialEq, Debug)]
+struct Opt2 {
+    #[structopt(short, long)]
+    force: bool,
+    #[structopt(short, long, parse(from_occurrences))]
+    verbose: u64,
+    #[structopt(subcommand)]
+    cmd: Option<Sub>,
+}
+
+#[test]
+fn test_no_cmd() {
+    let result = Opt::clap().get_matches_from_safe(&["test"]);
+    assert!(result.is_err());
+
+    assert_eq!(
+        Opt2 {
+            force: false,
+            verbose: 0,
+            cmd: None
+        },
+        Opt2::from_clap(&Opt2::clap().get_matches_from(&["test"]))
+    );
+}
+
+#[test]
+fn test_fetch() {
+    assert_eq!(
+        Opt {
+            force: false,
+            verbose: 3,
+            cmd: Sub::Fetch {}
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-vvv", "fetch"]))
+    );
+    assert_eq!(
+        Opt {
+            force: true,
+            verbose: 0,
+            cmd: Sub::Fetch {}
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--force", "fetch"]))
+    );
+}
+
+#[test]
+fn test_add() {
+    assert_eq!(
+        Opt {
+            force: false,
+            verbose: 0,
+            cmd: Sub::Add {}
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "add"]))
+    );
+    assert_eq!(
+        Opt {
+            force: false,
+            verbose: 2,
+            cmd: Sub::Add {}
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-vv", "add"]))
+    );
+}
+
+#[test]
+fn test_badinput() {
+    let result = Opt::clap().get_matches_from_safe(&["test", "badcmd"]);
+    assert!(result.is_err());
+    let result = Opt::clap().get_matches_from_safe(&["test", "add", "--verbose"]);
+    assert!(result.is_err());
+    let result = Opt::clap().get_matches_from_safe(&["test", "--badopt", "add"]);
+    assert!(result.is_err());
+    let result = Opt::clap().get_matches_from_safe(&["test", "add", "--badopt"]);
+    assert!(result.is_err());
+}
+
+#[derive(StructOpt, PartialEq, Debug)]
+struct Opt3 {
+    #[structopt(short, long)]
+    all: bool,
+    #[structopt(subcommand)]
+    cmd: Sub2,
+}
+
+#[derive(StructOpt, PartialEq, Debug)]
+enum Sub2 {
+    Foo {
+        file: String,
+        #[structopt(subcommand)]
+        cmd: Sub3,
+    },
+    Bar {},
+}
+
+#[derive(StructOpt, PartialEq, Debug)]
+enum Sub3 {
+    Baz {},
+    Quux {},
+}
+
+#[test]
+fn test_subsubcommand() {
+    assert_eq!(
+        Opt3 {
+            all: true,
+            cmd: Sub2::Foo {
+                file: "lib.rs".to_string(),
+                cmd: Sub3::Quux {}
+            }
+        },
+        Opt3::from_clap(
+            &Opt3::clap().get_matches_from(&["test", "--all", "foo", "lib.rs", "quux"])
+        )
+    );
+}
+
+#[derive(StructOpt, PartialEq, Debug)]
+enum SubSubCmdWithOption {
+    Remote {
+        #[structopt(subcommand)]
+        cmd: Option<Remote>,
+    },
+    Stash {
+        #[structopt(subcommand)]
+        cmd: Stash,
+    },
+}
+#[derive(StructOpt, PartialEq, Debug)]
+enum Remote {
+    Add { name: String, url: String },
+    Remove { name: String },
+}
+
+#[derive(StructOpt, PartialEq, Debug)]
+enum Stash {
+    Save,
+    Pop,
+}
+
+#[test]
+fn sub_sub_cmd_with_option() {
+    fn make(args: &[&str]) -> Option<SubSubCmdWithOption> {
+        SubSubCmdWithOption::clap()
+            .get_matches_from_safe(args)
+            .ok()
+            .map(|m| SubSubCmdWithOption::from_clap(&m))
+    }
+    assert_eq!(
+        Some(SubSubCmdWithOption::Remote { cmd: None }),
+        make(&["", "remote"])
+    );
+    assert_eq!(
+        Some(SubSubCmdWithOption::Remote {
+            cmd: Some(Remote::Add {
+                name: "origin".into(),
+                url: "http".into()
+            })
+        }),
+        make(&["", "remote", "add", "origin", "http"])
+    );
+    assert_eq!(
+        Some(SubSubCmdWithOption::Stash { cmd: Stash::Save }),
+        make(&["", "stash", "save"])
+    );
+    assert_eq!(None, make(&["", "stash"]));
+}
diff --git a/tests/non_literal_attributes.rs b/tests/non_literal_attributes.rs
new file mode 100644
index 0000000..75b6b71
--- /dev/null
+++ b/tests/non_literal_attributes.rs
@@ -0,0 +1,147 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::clap::AppSettings;
+use structopt::StructOpt;
+
+pub const DISPLAY_ORDER: usize = 2;
+
+// Check if the global settings compile
+#[derive(StructOpt, Debug, PartialEq, Eq)]
+#[structopt(global_settings = &[AppSettings::ColoredHelp])]
+struct Opt {
+    #[structopt(
+        long = "x",
+        display_order = DISPLAY_ORDER,
+        next_line_help = true,
+        default_value = "0",
+        require_equals = true
+    )]
+    x: i32,
+
+    #[structopt(short = "l", long = "level", aliases = &["set-level", "lvl"])]
+    level: String,
+
+    #[structopt(long("values"))]
+    values: Vec<i32>,
+
+    #[structopt(name = "FILE", requires_if("FILE", "values"))]
+    files: Vec<String>,
+}
+
+#[test]
+fn test_slice() {
+    assert_eq!(
+        Opt {
+            x: 0,
+            level: "1".to_string(),
+            files: Vec::new(),
+            values: vec![],
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-l", "1"]))
+    );
+    assert_eq!(
+        Opt {
+            x: 0,
+            level: "1".to_string(),
+            files: Vec::new(),
+            values: vec![],
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--level", "1"]))
+    );
+    assert_eq!(
+        Opt {
+            x: 0,
+            level: "1".to_string(),
+            files: Vec::new(),
+            values: vec![],
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--set-level", "1"]))
+    );
+    assert_eq!(
+        Opt {
+            x: 0,
+            level: "1".to_string(),
+            files: Vec::new(),
+            values: vec![],
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--lvl", "1"]))
+    );
+}
+
+#[test]
+fn test_multi_args() {
+    assert_eq!(
+        Opt {
+            x: 0,
+            level: "1".to_string(),
+            files: vec!["file".to_string()],
+            values: vec![],
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-l", "1", "file"]))
+    );
+    assert_eq!(
+        Opt {
+            x: 0,
+            level: "1".to_string(),
+            files: vec!["FILE".to_string()],
+            values: vec![1],
+        },
+        Opt::from_clap(
+            &Opt::clap().get_matches_from(&["test", "-l", "1", "--values", "1", "--", "FILE"]),
+        )
+    );
+}
+
+#[test]
+fn test_multi_args_fail() {
+    let result = Opt::clap().get_matches_from_safe(&["test", "-l", "1", "--", "FILE"]);
+    assert!(result.is_err());
+}
+
+#[test]
+fn test_bool() {
+    assert_eq!(
+        Opt {
+            x: 1,
+            level: "1".to_string(),
+            files: vec![],
+            values: vec![],
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-l", "1", "--x=1"]))
+    );
+    let result = Opt::clap().get_matches_from_safe(&["test", "-l", "1", "--x", "1"]);
+    assert!(result.is_err());
+}
+
+fn parse_hex(input: &str) -> Result<u64, std::num::ParseIntError> {
+    u64::from_str_radix(input, 16)
+}
+
+#[derive(StructOpt, PartialEq, Debug)]
+struct HexOpt {
+    #[structopt(short = "n", parse(try_from_str = parse_hex))]
+    number: u64,
+}
+
+#[test]
+fn test_parse_hex_function_path() {
+    assert_eq!(
+        HexOpt { number: 5 },
+        HexOpt::from_clap(&HexOpt::clap().get_matches_from(&["test", "-n", "5"]))
+    );
+    assert_eq!(
+        HexOpt { number: 0xabcdef },
+        HexOpt::from_clap(&HexOpt::clap().get_matches_from(&["test", "-n", "abcdef"]))
+    );
+
+    let err = HexOpt::clap()
+        .get_matches_from_safe(&["test", "-n", "gg"])
+        .unwrap_err();
+    assert!(err.message.contains("invalid digit found in string"), err);
+}
diff --git a/tests/options.rs b/tests/options.rs
new file mode 100644
index 0000000..803abb4
--- /dev/null
+++ b/tests/options.rs
@@ -0,0 +1,336 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[test]
+fn required_option() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(short, long)]
+        arg: i32,
+    }
+    assert_eq!(
+        Opt { arg: 42 },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a42"]))
+    );
+    assert_eq!(
+        Opt { arg: 42 },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "42"]))
+    );
+    assert_eq!(
+        Opt { arg: 42 },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--arg", "42"]))
+    );
+    assert!(Opt::clap().get_matches_from_safe(&["test"]).is_err());
+    assert!(Opt::clap()
+        .get_matches_from_safe(&["test", "-a42", "-a24"])
+        .is_err());
+}
+
+#[test]
+fn optional_option() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(short)]
+        arg: Option<i32>,
+    }
+    assert_eq!(
+        Opt { arg: Some(42) },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a42"]))
+    );
+    assert_eq!(
+        Opt { arg: None },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test"]))
+    );
+    assert!(Opt::clap()
+        .get_matches_from_safe(&["test", "-a42", "-a24"])
+        .is_err());
+}
+
+#[test]
+fn option_with_default() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(short, default_value = "42")]
+        arg: i32,
+    }
+    assert_eq!(
+        Opt { arg: 24 },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a24"]))
+    );
+    assert_eq!(
+        Opt { arg: 42 },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test"]))
+    );
+    assert!(Opt::clap()
+        .get_matches_from_safe(&["test", "-a42", "-a24"])
+        .is_err());
+}
+
+#[test]
+fn option_with_raw_default() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(short, default_value = "42")]
+        arg: i32,
+    }
+    assert_eq!(
+        Opt { arg: 24 },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a24"]))
+    );
+    assert_eq!(
+        Opt { arg: 42 },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test"]))
+    );
+    assert!(Opt::clap()
+        .get_matches_from_safe(&["test", "-a42", "-a24"])
+        .is_err());
+}
+
+#[test]
+fn options() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(short, long)]
+        arg: Vec<i32>,
+    }
+    assert_eq!(
+        Opt { arg: vec![24] },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a24"]))
+    );
+    assert_eq!(
+        Opt { arg: vec![] },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test"]))
+    );
+    assert_eq!(
+        Opt { arg: vec![24, 42] },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a24", "--arg", "42"]))
+    );
+}
+
+#[test]
+fn empy_default_value() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(short, default_value = "")]
+        arg: String,
+    }
+    assert_eq!(Opt { arg: "".into() }, Opt::from_iter(&["test"]));
+    assert_eq!(
+        Opt { arg: "foo".into() },
+        Opt::from_iter(&["test", "-afoo"])
+    );
+}
+
+#[test]
+fn option_from_str() {
+    #[derive(Debug, PartialEq)]
+    struct A;
+
+    impl<'a> From<&'a str> for A {
+        fn from(_: &str) -> A {
+            A
+        }
+    }
+
+    #[derive(Debug, StructOpt, PartialEq)]
+    struct Opt {
+        #[structopt(parse(from_str))]
+        a: Option<A>,
+    }
+
+    assert_eq!(Opt { a: None }, Opt::from_iter(&["test"]));
+    assert_eq!(Opt { a: Some(A) }, Opt::from_iter(&["test", "foo"]));
+}
+
+#[test]
+fn optional_argument_for_optional_option() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(short)]
+        #[allow(clippy::option_option)]
+        arg: Option<Option<i32>>,
+    }
+    assert_eq!(
+        Opt {
+            arg: Some(Some(42))
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a42"]))
+    );
+    assert_eq!(
+        Opt { arg: Some(None) },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a"]))
+    );
+    assert_eq!(
+        Opt { arg: None },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test"]))
+    );
+    assert!(Opt::clap()
+        .get_matches_from_safe(&["test", "-a42", "-a24"])
+        .is_err());
+}
+
+#[test]
+fn two_option_options() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    #[allow(clippy::option_option)]
+    struct Opt {
+        #[structopt(short)]
+        arg: Option<Option<i32>>,
+
+        #[structopt(long)]
+        field: Option<Option<String>>,
+    }
+    assert_eq!(
+        Opt {
+            arg: Some(Some(42)),
+            field: Some(Some("f".into()))
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a42", "--field", "f"]))
+    );
+    assert_eq!(
+        Opt {
+            arg: Some(Some(42)),
+            field: Some(None)
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a42", "--field"]))
+    );
+    assert_eq!(
+        Opt {
+            arg: Some(None),
+            field: Some(None)
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "--field"]))
+    );
+    assert_eq!(
+        Opt {
+            arg: Some(None),
+            field: Some(Some("f".into()))
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "--field", "f"]))
+    );
+    assert_eq!(
+        Opt {
+            arg: None,
+            field: Some(None)
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--field"]))
+    );
+    assert_eq!(
+        Opt {
+            arg: None,
+            field: None
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test"]))
+    );
+}
+
+#[test]
+fn optional_vec() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(short)]
+        arg: Option<Vec<i32>>,
+    }
+    assert_eq!(
+        Opt { arg: Some(vec![1]) },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "1"]))
+    );
+
+    assert_eq!(
+        Opt {
+            arg: Some(vec![1, 2])
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a1", "-a2"]))
+    );
+
+    assert_eq!(
+        Opt {
+            arg: Some(vec![1, 2])
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a1", "-a2", "-a"]))
+    );
+
+    assert_eq!(
+        Opt {
+            arg: Some(vec![1, 2])
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a1", "-a", "-a2"]))
+    );
+
+    assert_eq!(
+        Opt {
+            arg: Some(vec![1, 2])
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "1", "2"]))
+    );
+
+    assert_eq!(
+        Opt {
+            arg: Some(vec![1, 2, 3])
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "1", "2", "-a", "3"]))
+    );
+
+    assert_eq!(
+        Opt { arg: Some(vec![]) },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a"]))
+    );
+
+    assert_eq!(
+        Opt { arg: Some(vec![]) },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "-a"]))
+    );
+
+    assert_eq!(
+        Opt { arg: None },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test"]))
+    );
+}
+
+#[test]
+fn two_optional_vecs() {
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(short)]
+        arg: Option<Vec<i32>>,
+
+        #[structopt(short)]
+        b: Option<Vec<i32>>,
+    }
+
+    assert_eq!(
+        Opt {
+            arg: Some(vec![1]),
+            b: Some(vec![])
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "1", "-b"]))
+    );
+
+    assert_eq!(
+        Opt {
+            arg: Some(vec![1]),
+            b: Some(vec![])
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a", "-b", "-a1"]))
+    );
+
+    assert_eq!(
+        Opt {
+            arg: Some(vec![1, 2]),
+            b: Some(vec![1, 2])
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-a1", "-a2", "-b1", "-b2"]))
+    );
+
+    assert_eq!(
+        Opt { arg: None, b: None },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test"]))
+    );
+}
diff --git a/tests/privacy.rs b/tests/privacy.rs
new file mode 100644
index 0000000..730bbce
--- /dev/null
+++ b/tests/privacy.rs
@@ -0,0 +1,32 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+mod options {
+    use super::StructOpt;
+
+    #[derive(Debug, StructOpt)]
+    pub struct Options {
+        #[structopt(subcommand)]
+        pub subcommand: super::subcommands::SubCommand,
+    }
+}
+
+mod subcommands {
+    use super::StructOpt;
+
+    #[derive(Debug, StructOpt)]
+    pub enum SubCommand {
+        /// foo
+        Foo {
+            /// foo
+            bars: Vec<String>,
+        },
+    }
+}
diff --git a/tests/raw_bool_literal.rs b/tests/raw_bool_literal.rs
new file mode 100644
index 0000000..faf8628
--- /dev/null
+++ b/tests/raw_bool_literal.rs
@@ -0,0 +1,29 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[test]
+fn raw_bool_literal() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    #[structopt(no_version, name = "raw_bool")]
+    struct Opt {
+        #[structopt(raw(false))]
+        a: String,
+        #[structopt(raw(true))]
+        b: String,
+    }
+
+    assert_eq!(
+        Opt {
+            a: "one".into(),
+            b: "--help".into()
+        },
+        Opt::from_iter(&["test", "one", "--", "--help"])
+    );
+}
diff --git a/tests/raw_idents.rs b/tests/raw_idents.rs
new file mode 100644
index 0000000..c00ff66
--- /dev/null
+++ b/tests/raw_idents.rs
@@ -0,0 +1,17 @@
+use structopt::StructOpt;
+
+#[test]
+fn raw_idents() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    struct Opt {
+        #[structopt(short, long)]
+        r#type: Vec<String>,
+    }
+
+    assert_eq!(
+        Opt {
+            r#type: vec!["long".into(), "short".into()]
+        },
+        Opt::from_iter(&["test", "--type", "long", "-t", "short"])
+    );
+}
diff --git a/tests/rename_all_env.rs b/tests/rename_all_env.rs
new file mode 100644
index 0000000..1979e84
--- /dev/null
+++ b/tests/rename_all_env.rs
@@ -0,0 +1,46 @@
+mod utils;
+
+use structopt::StructOpt;
+use utils::*;
+
+#[test]
+fn it_works() {
+    #[derive(Debug, PartialEq, StructOpt)]
+    #[structopt(rename_all_env = "kebab")]
+    struct BehaviorModel {
+        #[structopt(env)]
+        be_nice: String,
+    }
+
+    let help = get_help::<BehaviorModel>();
+    assert!(help.contains("[env: be-nice=]"));
+}
+
+#[test]
+fn default_is_screaming() {
+    #[derive(Debug, PartialEq, StructOpt)]
+    struct BehaviorModel {
+        #[structopt(env)]
+        be_nice: String,
+    }
+
+    let help = get_help::<BehaviorModel>();
+    assert!(help.contains("[env: BE_NICE=]"));
+}
+
+#[test]
+fn overridable() {
+    #[derive(Debug, PartialEq, StructOpt)]
+    #[structopt(rename_all_env = "kebab")]
+    struct BehaviorModel {
+        #[structopt(env)]
+        be_nice: String,
+
+        #[structopt(rename_all_env = "pascal", env)]
+        be_agressive: String,
+    }
+
+    let help = get_help::<BehaviorModel>();
+    assert!(help.contains("[env: be-nice=]"));
+    assert!(help.contains("[env: BeAgressive=]"));
+}
diff --git a/tests/skip.rs b/tests/skip.rs
new file mode 100644
index 0000000..47682d8
--- /dev/null
+++ b/tests/skip.rs
@@ -0,0 +1,148 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[test]
+fn skip_1() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    struct Opt {
+        #[structopt(short)]
+        x: u32,
+        #[structopt(skip)]
+        s: u32,
+    }
+
+    assert!(Opt::from_iter_safe(&["test", "-x", "10", "20"]).is_err());
+    assert_eq!(
+        Opt::from_iter(&["test", "-x", "10"]),
+        Opt {
+            x: 10,
+            s: 0, // default
+        }
+    );
+}
+
+#[test]
+fn skip_2() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    struct Opt {
+        #[structopt(short)]
+        x: u32,
+        #[structopt(skip)]
+        ss: String,
+        #[structopt(skip)]
+        sn: u8,
+        y: u32,
+        #[structopt(skip)]
+        sz: u16,
+        t: u32,
+    }
+
+    assert_eq!(
+        Opt::from_iter(&["test", "-x", "10", "20", "30"]),
+        Opt {
+            x: 10,
+            ss: String::from(""),
+            sn: 0,
+            y: 20,
+            sz: 0,
+            t: 30,
+        }
+    );
+}
+
+#[test]
+fn skip_enum() {
+    #[derive(Debug, PartialEq)]
+    #[allow(unused)]
+    enum Kind {
+        A,
+        B,
+    }
+
+    impl Default for Kind {
+        fn default() -> Self {
+            return Kind::B;
+        }
+    }
+
+    #[derive(StructOpt, Debug, PartialEq)]
+    pub struct Opt {
+        #[structopt(long, short)]
+        number: u32,
+        #[structopt(skip)]
+        k: Kind,
+        #[structopt(skip)]
+        v: Vec<u32>,
+    }
+
+    assert_eq!(
+        Opt::from_iter(&["test", "-n", "10"]),
+        Opt {
+            number: 10,
+            k: Kind::B,
+            v: vec![],
+        }
+    );
+}
+
+#[test]
+fn skip_help_doc_comments() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    pub struct Opt {
+        #[structopt(skip, help = "internal_stuff")]
+        a: u32,
+
+        #[structopt(skip, long_help = "internal_stuff\ndo not touch")]
+        b: u32,
+
+        /// Not meant to be used by clap.
+        ///
+        /// I want a default here.
+        #[structopt(skip)]
+        c: u32,
+
+        #[structopt(short, parse(try_from_str))]
+        n: u32,
+    }
+
+    assert_eq!(
+        Opt::from_iter(&["test", "-n", "10"]),
+        Opt {
+            n: 10,
+            a: 0,
+            b: 0,
+            c: 0,
+        }
+    );
+}
+
+#[test]
+fn skip_val() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    pub struct Opt {
+        #[structopt(long, short)]
+        number: u32,
+
+        #[structopt(skip = "key")]
+        k: String,
+
+        #[structopt(skip = vec![1, 2, 3])]
+        v: Vec<u32>,
+    }
+
+    assert_eq!(
+        Opt::from_iter(&["test", "-n", "10"]),
+        Opt {
+            number: 10,
+            k: "key".into(),
+            v: vec![1, 2, 3]
+        }
+    );
+}
diff --git a/tests/special_types.rs b/tests/special_types.rs
new file mode 100644
index 0000000..ffed5e2
--- /dev/null
+++ b/tests/special_types.rs
@@ -0,0 +1,73 @@
+//! Checks that types like `::std::option::Option` are not special
+
+use structopt::StructOpt;
+
+#[rustversion::since(1.37)]
+#[test]
+fn special_types_bool() {
+    mod inner {
+        #[allow(non_camel_case_types)]
+        #[derive(PartialEq, Debug)]
+        pub struct bool(pub String);
+
+        impl std::str::FromStr for self::bool {
+            type Err = String;
+
+            fn from_str(s: &str) -> Result<Self, Self::Err> {
+                Ok(self::bool(s.into()))
+            }
+        }
+    };
+
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        arg: inner::bool,
+    }
+
+    assert_eq!(
+        Opt {
+            arg: inner::bool("success".into())
+        },
+        Opt::from_iter(&["test", "success"])
+    );
+}
+
+#[test]
+fn special_types_option() {
+    fn parser(s: &str) -> Option<String> {
+        Some(s.to_string())
+    }
+
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(parse(from_str = parser))]
+        arg: ::std::option::Option<String>,
+    }
+
+    assert_eq!(
+        Opt {
+            arg: Some("success".into())
+        },
+        Opt::from_iter(&["test", "success"])
+    );
+}
+
+#[test]
+fn special_types_vec() {
+    fn parser(s: &str) -> Vec<String> {
+        vec![s.to_string()]
+    }
+
+    #[derive(StructOpt, PartialEq, Debug)]
+    struct Opt {
+        #[structopt(parse(from_str = parser))]
+        arg: ::std::vec::Vec<String>,
+    }
+
+    assert_eq!(
+        Opt {
+            arg: vec!["success".into()]
+        },
+        Opt::from_iter(&["test", "success"])
+    );
+}
diff --git a/tests/subcommands.rs b/tests/subcommands.rs
new file mode 100644
index 0000000..1fc8e76
--- /dev/null
+++ b/tests/subcommands.rs
@@ -0,0 +1,303 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+mod utils;
+
+use structopt::StructOpt;
+use utils::*;
+
+#[derive(StructOpt, PartialEq, Debug)]
+enum Opt {
+    /// Fetch stuff from GitHub
+    Fetch {
+        #[structopt(long)]
+        all: bool,
+        #[structopt(short, long)]
+        /// Overwrite local branches.
+        force: bool,
+        repo: String,
+    },
+
+    Add {
+        #[structopt(short, long)]
+        interactive: bool,
+        #[structopt(short, long)]
+        verbose: bool,
+    },
+}
+
+#[test]
+fn test_fetch() {
+    assert_eq!(
+        Opt::Fetch {
+            all: true,
+            force: false,
+            repo: "origin".to_string()
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "fetch", "--all", "origin"]))
+    );
+    assert_eq!(
+        Opt::Fetch {
+            all: false,
+            force: true,
+            repo: "origin".to_string()
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "fetch", "-f", "origin"]))
+    );
+}
+
+#[test]
+fn test_add() {
+    assert_eq!(
+        Opt::Add {
+            interactive: false,
+            verbose: false
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "add"]))
+    );
+    assert_eq!(
+        Opt::Add {
+            interactive: true,
+            verbose: true
+        },
+        Opt::from_clap(&Opt::clap().get_matches_from(&["test", "add", "-i", "-v"]))
+    );
+}
+
+#[test]
+fn test_no_parse() {
+    let result = Opt::clap().get_matches_from_safe(&["test", "badcmd", "-i", "-v"]);
+    assert!(result.is_err());
+
+    let result = Opt::clap().get_matches_from_safe(&["test", "add", "--badoption"]);
+    assert!(result.is_err());
+
+    let result = Opt::clap().get_matches_from_safe(&["test"]);
+    assert!(result.is_err());
+}
+
+#[derive(StructOpt, PartialEq, Debug)]
+enum Opt2 {
+    DoSomething { arg: String },
+}
+
+#[test]
+/// This test is specifically to make sure that hyphenated subcommands get
+/// processed correctly.
+fn test_hyphenated_subcommands() {
+    assert_eq!(
+        Opt2::DoSomething {
+            arg: "blah".to_string()
+        },
+        Opt2::from_clap(&Opt2::clap().get_matches_from(&["test", "do-something", "blah"]))
+    );
+}
+
+#[derive(StructOpt, PartialEq, Debug)]
+enum Opt3 {
+    Add,
+    Init,
+    Fetch,
+}
+
+#[test]
+fn test_null_commands() {
+    assert_eq!(
+        Opt3::Add,
+        Opt3::from_clap(&Opt3::clap().get_matches_from(&["test", "add"]))
+    );
+    assert_eq!(
+        Opt3::Init,
+        Opt3::from_clap(&Opt3::clap().get_matches_from(&["test", "init"]))
+    );
+    assert_eq!(
+        Opt3::Fetch,
+        Opt3::from_clap(&Opt3::clap().get_matches_from(&["test", "fetch"]))
+    );
+}
+
+#[derive(StructOpt, PartialEq, Debug)]
+#[structopt(about = "Not shown")]
+struct Add {
+    file: String,
+}
+/// Not shown
+#[derive(StructOpt, PartialEq, Debug)]
+struct Fetch {
+    remote: String,
+}
+#[derive(StructOpt, PartialEq, Debug)]
+enum Opt4 {
+    // Not shown
+    /// Add a file
+    Add(Add),
+    Init,
+    /// download history from remote
+    Fetch(Fetch),
+}
+
+#[test]
+fn test_tuple_commands() {
+    assert_eq!(
+        Opt4::Add(Add {
+            file: "f".to_string()
+        }),
+        Opt4::from_clap(&Opt4::clap().get_matches_from(&["test", "add", "f"]))
+    );
+    assert_eq!(
+        Opt4::Init,
+        Opt4::from_clap(&Opt4::clap().get_matches_from(&["test", "init"]))
+    );
+    assert_eq!(
+        Opt4::Fetch(Fetch {
+            remote: "origin".to_string()
+        }),
+        Opt4::from_clap(&Opt4::clap().get_matches_from(&["test", "fetch", "origin"]))
+    );
+
+    let output = get_long_help::<Opt4>();
+
+    assert!(output.contains("download history from remote"));
+    assert!(output.contains("Add a file"));
+    assert!(!output.contains("Not shown"));
+}
+
+#[test]
+fn enum_in_enum_subsubcommand() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    pub enum Opt {
+        Daemon(DaemonCommand),
+    }
+
+    #[derive(StructOpt, Debug, PartialEq)]
+    pub enum DaemonCommand {
+        Start,
+        Stop,
+    }
+
+    let result = Opt::clap().get_matches_from_safe(&["test"]);
+    assert!(result.is_err());
+
+    let result = Opt::clap().get_matches_from_safe(&["test", "daemon"]);
+    assert!(result.is_err());
+
+    let result = Opt::from_iter(&["test", "daemon", "start"]);
+    assert_eq!(Opt::Daemon(DaemonCommand::Start), result);
+}
+
+#[test]
+fn flatten_enum() {
+    #[derive(StructOpt, Debug, PartialEq)]
+    struct Opt {
+        #[structopt(flatten)]
+        sub_cmd: SubCmd,
+    }
+    #[derive(StructOpt, Debug, PartialEq)]
+    enum SubCmd {
+        Foo,
+        Bar,
+    }
+
+    assert!(Opt::from_iter_safe(&["test"]).is_err());
+    assert_eq!(
+        Opt::from_iter(&["test", "foo"]),
+        Opt {
+            sub_cmd: SubCmd::Foo
+        }
+    );
+}
+
+#[test]
+fn external_subcommand() {
+    #[derive(Debug, PartialEq, StructOpt)]
+    struct Opt {
+        #[structopt(subcommand)]
+        sub: Subcommands,
+    }
+
+    #[derive(Debug, PartialEq, StructOpt)]
+    enum Subcommands {
+        Add,
+        Remove,
+        #[structopt(external_subcommand)]
+        Other(Vec<String>),
+    }
+
+    assert_eq!(
+        Opt::from_iter(&["test", "add"]),
+        Opt {
+            sub: Subcommands::Add
+        }
+    );
+
+    assert_eq!(
+        Opt::from_iter(&["test", "remove"]),
+        Opt {
+            sub: Subcommands::Remove
+        }
+    );
+
+    assert_eq!(
+        Opt::from_iter(&["test", "git", "status"]),
+        Opt {
+            sub: Subcommands::Other(vec!["git".into(), "status".into()])
+        }
+    );
+
+    assert!(Opt::from_iter_safe(&["test"]).is_err());
+}
+
+#[test]
+fn external_subcommand_os_string() {
+    use std::ffi::OsString;
+
+    #[derive(Debug, PartialEq, StructOpt)]
+    struct Opt {
+        #[structopt(subcommand)]
+        sub: Subcommands,
+    }
+
+    #[derive(Debug, PartialEq, StructOpt)]
+    enum Subcommands {
+        #[structopt(external_subcommand)]
+        Other(Vec<OsString>),
+    }
+
+    assert_eq!(
+        Opt::from_iter(&["test", "git", "status"]),
+        Opt {
+            sub: Subcommands::Other(vec!["git".into(), "status".into()])
+        }
+    );
+
+    assert!(Opt::from_iter_safe(&["test"]).is_err());
+}
+
+#[test]
+fn external_subcommand_optional() {
+    #[derive(Debug, PartialEq, StructOpt)]
+    struct Opt {
+        #[structopt(subcommand)]
+        sub: Option<Subcommands>,
+    }
+
+    #[derive(Debug, PartialEq, StructOpt)]
+    enum Subcommands {
+        #[structopt(external_subcommand)]
+        Other(Vec<String>),
+    }
+
+    assert_eq!(
+        Opt::from_iter(&["test", "git", "status"]),
+        Opt {
+            sub: Some(Subcommands::Other(vec!["git".into(), "status".into()]))
+        }
+    );
+
+    assert_eq!(Opt::from_iter(&["test"]), Opt { sub: None });
+}
diff --git a/tests/ui/bool_default_value.rs b/tests/ui/bool_default_value.rs
new file mode 100644
index 0000000..9bdb0c9
--- /dev/null
+++ b/tests/ui/bool_default_value.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+    #[structopt(short, default_value = true)]
+    b: bool,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/bool_default_value.stderr b/tests/ui/bool_default_value.stderr
new file mode 100644
index 0000000..1e26a2d
--- /dev/null
+++ b/tests/ui/bool_default_value.stderr
@@ -0,0 +1,5 @@
+error: default_value is meaningless for bool
+  --> $DIR/bool_default_value.rs:14:24
+   |
+14 |     #[structopt(short, default_value = true)]
+   |                        ^^^^^^^^^^^^^
diff --git a/tests/ui/bool_required.rs b/tests/ui/bool_required.rs
new file mode 100644
index 0000000..018223c
--- /dev/null
+++ b/tests/ui/bool_required.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+    #[structopt(short, required = true)]
+    b: bool,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/bool_required.stderr b/tests/ui/bool_required.stderr
new file mode 100644
index 0000000..0b80d48
--- /dev/null
+++ b/tests/ui/bool_required.stderr
@@ -0,0 +1,5 @@
+error: required is meaningless for bool
+  --> $DIR/bool_required.rs:14:24
+   |
+14 |     #[structopt(short, required = true)]
+   |                        ^^^^^^^^
diff --git a/tests/ui/enum_flatten.rs b/tests/ui/enum_flatten.rs
new file mode 100644
index 0000000..768de76
--- /dev/null
+++ b/tests/ui/enum_flatten.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+enum Opt {
+    #[structopt(flatten)]
+    Variant1,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/enum_flatten.stderr b/tests/ui/enum_flatten.stderr
new file mode 100644
index 0000000..d74fa85
--- /dev/null
+++ b/tests/ui/enum_flatten.stderr
@@ -0,0 +1,6 @@
+error: `flatten` is usable only with single-typed tuple variants
+  --> $DIR/enum_flatten.rs:14:5
+   |
+14 | /     #[structopt(flatten)]
+15 | |     Variant1,
+   | |____________^
diff --git a/tests/ui/external_subcommand_wrong_type.rs b/tests/ui/external_subcommand_wrong_type.rs
new file mode 100644
index 0000000..ad62e73
--- /dev/null
+++ b/tests/ui/external_subcommand_wrong_type.rs
@@ -0,0 +1,19 @@
+use structopt::StructOpt;
+use std::ffi::CString;
+
+#[derive(StructOpt, Debug)]
+struct Opt {
+    #[structopt(subcommand)]
+    cmd: Command,
+}
+
+#[derive(StructOpt, Debug)]
+enum Command {
+    #[structopt(external_subcommand)]
+    Other(Vec<CString>)
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
\ No newline at end of file
diff --git a/tests/ui/external_subcommand_wrong_type.stderr b/tests/ui/external_subcommand_wrong_type.stderr
new file mode 100644
index 0000000..1966225
--- /dev/null
+++ b/tests/ui/external_subcommand_wrong_type.stderr
@@ -0,0 +1,8 @@
+error[E0308]: mismatched types
+  --> $DIR/external_subcommand_wrong_type.rs:13:15
+   |
+13 |     Other(Vec<CString>)
+   |               ^^^^^^^ expected struct `std::ffi::CString`, found struct `std::ffi::OsString`
+   |
+   = note: expected struct `std::vec::Vec<std::ffi::CString>`
+              found struct `std::vec::Vec<std::ffi::OsString>`
diff --git a/tests/ui/flatten_and_doc.rs b/tests/ui/flatten_and_doc.rs
new file mode 100644
index 0000000..2dc154d
--- /dev/null
+++ b/tests/ui/flatten_and_doc.rs
@@ -0,0 +1,30 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+struct DaemonOpts {
+    #[structopt(short)]
+    user: String,
+    #[structopt(short)]
+    group: String,
+}
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+    /// Opts.
+    #[structopt(flatten)]
+    opts: DaemonOpts,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/flatten_and_doc.stderr b/tests/ui/flatten_and_doc.stderr
new file mode 100644
index 0000000..2724dbb
--- /dev/null
+++ b/tests/ui/flatten_and_doc.stderr
@@ -0,0 +1,5 @@
+error: methods and doc comments are not allowed for flattened entry
+  --> $DIR/flatten_and_doc.rs:23:17
+   |
+23 |     #[structopt(flatten)]
+   |                 ^^^^^^^
diff --git a/tests/ui/flatten_and_methods.rs b/tests/ui/flatten_and_methods.rs
new file mode 100644
index 0000000..ff1af2e
--- /dev/null
+++ b/tests/ui/flatten_and_methods.rs
@@ -0,0 +1,29 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+struct DaemonOpts {
+    #[structopt(short)]
+    user: String,
+    #[structopt(short)]
+    group: String,
+}
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+    #[structopt(short, flatten)]
+    opts: DaemonOpts,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/flatten_and_methods.stderr b/tests/ui/flatten_and_methods.stderr
new file mode 100644
index 0000000..f058eb3
--- /dev/null
+++ b/tests/ui/flatten_and_methods.stderr
@@ -0,0 +1,5 @@
+error: methods and doc comments are not allowed for flattened entry
+  --> $DIR/flatten_and_methods.rs:22:24
+   |
+22 |     #[structopt(short, flatten)]
+   |                        ^^^^^^^
diff --git a/tests/ui/flatten_and_parse.rs b/tests/ui/flatten_and_parse.rs
new file mode 100644
index 0000000..3317272
--- /dev/null
+++ b/tests/ui/flatten_and_parse.rs
@@ -0,0 +1,29 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+struct DaemonOpts {
+    #[structopt(short)]
+    user: String,
+    #[structopt(short)]
+    group: String,
+}
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+    #[structopt(flatten, parse(from_occurrences))]
+    opts: DaemonOpts,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/flatten_and_parse.stderr b/tests/ui/flatten_and_parse.stderr
new file mode 100644
index 0000000..e217a84
--- /dev/null
+++ b/tests/ui/flatten_and_parse.stderr
@@ -0,0 +1,5 @@
+error: parse attribute is not allowed for flattened entry
+  --> $DIR/flatten_and_parse.rs:22:26
+   |
+22 |     #[structopt(flatten, parse(from_occurrences))]
+   |                          ^^^^^
diff --git a/tests/ui/multiple_external_subcommand.rs b/tests/ui/multiple_external_subcommand.rs
new file mode 100644
index 0000000..986261b
--- /dev/null
+++ b/tests/ui/multiple_external_subcommand.rs
@@ -0,0 +1,21 @@
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+struct Opt {
+    #[structopt(subcommand)]
+    cmd: Command,
+}
+
+#[derive(StructOpt, Debug)]
+enum Command {
+    #[structopt(external_subcommand)]
+    Run(Vec<String>),
+
+    #[structopt(external_subcommand)]
+    Other(Vec<String>)
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/multiple_external_subcommand.stderr b/tests/ui/multiple_external_subcommand.stderr
new file mode 100644
index 0000000..0c80c2e
--- /dev/null
+++ b/tests/ui/multiple_external_subcommand.stderr
@@ -0,0 +1,5 @@
+error: Only one variant can be marked with `external_subcommand`, this is the second
+  --> $DIR/multiple_external_subcommand.rs:14:17
+   |
+14 |     #[structopt(external_subcommand)]
+   |                 ^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/non_existent_attr.rs b/tests/ui/non_existent_attr.rs
new file mode 100644
index 0000000..96daf45
--- /dev/null
+++ b/tests/ui/non_existent_attr.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+    #[structopt(short, non_existing_attribute = 1)]
+    debug: bool,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/non_existent_attr.stderr b/tests/ui/non_existent_attr.stderr
new file mode 100644
index 0000000..99dc781
--- /dev/null
+++ b/tests/ui/non_existent_attr.stderr
@@ -0,0 +1,5 @@
+error[E0599]: no method named `non_existing_attribute` found for struct `clap::args::arg::Arg<'_, '_>` in the current scope
+  --> $DIR/non_existent_attr.rs:14:24
+   |
+14 |     #[structopt(short, non_existing_attribute = 1)]
+   |                        ^^^^^^^^^^^^^^^^^^^^^^ method not found in `clap::args::arg::Arg<'_, '_>`
diff --git a/tests/ui/opt_opt_nonpositional.rs b/tests/ui/opt_opt_nonpositional.rs
new file mode 100644
index 0000000..2a08105
--- /dev/null
+++ b/tests/ui/opt_opt_nonpositional.rs
@@ -0,0 +1,20 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+    n: Option<Option<u32>>,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/opt_opt_nonpositional.stderr b/tests/ui/opt_opt_nonpositional.stderr
new file mode 100644
index 0000000..cb9f172
--- /dev/null
+++ b/tests/ui/opt_opt_nonpositional.stderr
@@ -0,0 +1,5 @@
+error: Option<Option<T>> type is meaningless for positional argument
+  --> $DIR/opt_opt_nonpositional.rs:14:8
+   |
+14 |     n: Option<Option<u32>>,
+   |        ^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/opt_vec_nonpositional.rs b/tests/ui/opt_vec_nonpositional.rs
new file mode 100644
index 0000000..0f6f078
--- /dev/null
+++ b/tests/ui/opt_vec_nonpositional.rs
@@ -0,0 +1,20 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+    n: Option<Vec<u32>>,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/opt_vec_nonpositional.stderr b/tests/ui/opt_vec_nonpositional.stderr
new file mode 100644
index 0000000..c6b343f
--- /dev/null
+++ b/tests/ui/opt_vec_nonpositional.stderr
@@ -0,0 +1,5 @@
+error: Option<Vec<T>> type is meaningless for positional argument
+  --> $DIR/opt_vec_nonpositional.rs:14:8
+   |
+14 |     n: Option<Vec<u32>>,
+   |        ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/option_default_value.rs b/tests/ui/option_default_value.rs
new file mode 100644
index 0000000..a86bc0e
--- /dev/null
+++ b/tests/ui/option_default_value.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+    #[structopt(short, default_value = 1)]
+    n: Option<u32>,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/option_default_value.stderr b/tests/ui/option_default_value.stderr
new file mode 100644
index 0000000..2215497
--- /dev/null
+++ b/tests/ui/option_default_value.stderr
@@ -0,0 +1,5 @@
+error: default_value is meaningless for Option
+  --> $DIR/option_default_value.rs:14:24
+   |
+14 |     #[structopt(short, default_value = 1)]
+   |                        ^^^^^^^^^^^^^
diff --git a/tests/ui/option_required.rs b/tests/ui/option_required.rs
new file mode 100644
index 0000000..d91afbf
--- /dev/null
+++ b/tests/ui/option_required.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+    #[structopt(short, required = true)]
+    n: Option<u32>,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/option_required.stderr b/tests/ui/option_required.stderr
new file mode 100644
index 0000000..0230d57
--- /dev/null
+++ b/tests/ui/option_required.stderr
@@ -0,0 +1,5 @@
+error: required is meaningless for Option
+  --> $DIR/option_required.rs:14:24
+   |
+14 |     #[structopt(short, required = true)]
+   |                        ^^^^^^^^
diff --git a/tests/ui/parse_empty_try_from_os.rs b/tests/ui/parse_empty_try_from_os.rs
new file mode 100644
index 0000000..acfef0b
--- /dev/null
+++ b/tests/ui/parse_empty_try_from_os.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+    #[structopt(parse(try_from_os_str))]
+    s: String,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/parse_empty_try_from_os.stderr b/tests/ui/parse_empty_try_from_os.stderr
new file mode 100644
index 0000000..3dc9f24
--- /dev/null
+++ b/tests/ui/parse_empty_try_from_os.stderr
@@ -0,0 +1,5 @@
+error: you must set parser for `try_from_os_str` explicitly
+  --> $DIR/parse_empty_try_from_os.rs:14:23
+   |
+14 |     #[structopt(parse(try_from_os_str))]
+   |                       ^^^^^^^^^^^^^^^
diff --git a/tests/ui/parse_function_is_not_path.rs b/tests/ui/parse_function_is_not_path.rs
new file mode 100644
index 0000000..5eebc57
--- /dev/null
+++ b/tests/ui/parse_function_is_not_path.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+    #[structopt(parse(from_str = "2"))]
+    s: String,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/parse_function_is_not_path.stderr b/tests/ui/parse_function_is_not_path.stderr
new file mode 100644
index 0000000..7cf7444
--- /dev/null
+++ b/tests/ui/parse_function_is_not_path.stderr
@@ -0,0 +1,5 @@
+error: `parse` argument must be a function path
+  --> $DIR/parse_function_is_not_path.rs:14:34
+   |
+14 |     #[structopt(parse(from_str = "2"))]
+   |                                  ^^^
diff --git a/tests/ui/parse_literal_spec.rs b/tests/ui/parse_literal_spec.rs
new file mode 100644
index 0000000..b6f125a
--- /dev/null
+++ b/tests/ui/parse_literal_spec.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+    #[structopt(parse("from_str"))]
+    s: String,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/parse_literal_spec.stderr b/tests/ui/parse_literal_spec.stderr
new file mode 100644
index 0000000..6e99e8b
--- /dev/null
+++ b/tests/ui/parse_literal_spec.stderr
@@ -0,0 +1,5 @@
+error: parser specification must start with identifier
+  --> $DIR/parse_literal_spec.rs:14:23
+   |
+14 |     #[structopt(parse("from_str"))]
+   |                       ^^^^^^^^^^
diff --git a/tests/ui/parse_not_zero_args.rs b/tests/ui/parse_not_zero_args.rs
new file mode 100644
index 0000000..8729178
--- /dev/null
+++ b/tests/ui/parse_not_zero_args.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+    #[structopt(parse(from_str, from_str))]
+    s: String,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/parse_not_zero_args.stderr b/tests/ui/parse_not_zero_args.stderr
new file mode 100644
index 0000000..34b99a4
--- /dev/null
+++ b/tests/ui/parse_not_zero_args.stderr
@@ -0,0 +1,5 @@
+error: `parse` must have exactly one argument
+  --> $DIR/parse_not_zero_args.rs:14:17
+   |
+14 |     #[structopt(parse(from_str, from_str))]
+   |                 ^^^^^
diff --git a/tests/ui/positional_bool.rs b/tests/ui/positional_bool.rs
new file mode 100644
index 0000000..4dbf538
--- /dev/null
+++ b/tests/ui/positional_bool.rs
@@ -0,0 +1,10 @@
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+struct Opt {
+    verbose: bool,
+}
+
+fn main() {
+    Opt::from_args();
+}
\ No newline at end of file
diff --git a/tests/ui/positional_bool.stderr b/tests/ui/positional_bool.stderr
new file mode 100644
index 0000000..c3ed1ad
--- /dev/null
+++ b/tests/ui/positional_bool.stderr
@@ -0,0 +1,10 @@
+error: `bool` cannot be used as positional parameter with default parser
+
+  = help: if you want to create a flag add `long` or `short`
+  = help: If you really want a boolean parameter add an explicit parser, for example `parse(try_from_str)`
+  = note: see also https://github.com/TeXitoi/structopt/tree/master/examples/true_or_false.rs
+
+ --> $DIR/positional_bool.rs:5:14
+  |
+5 |     verbose: bool,
+  |              ^^^^
diff --git a/tests/ui/raw.rs b/tests/ui/raw.rs
new file mode 100644
index 0000000..b94f783
--- /dev/null
+++ b/tests/ui/raw.rs
@@ -0,0 +1,25 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+struct Opt {
+    #[structopt(raw(case_insensitive = "true"))]
+    s: String,
+}
+
+#[derive(StructOpt, Debug)]
+struct Opt2 {
+    #[structopt(raw(requires_if = r#""one", "two""#))]
+    s: String,
+}
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/raw.stderr b/tests/ui/raw.stderr
new file mode 100644
index 0000000..93b5e38
--- /dev/null
+++ b/tests/ui/raw.stderr
@@ -0,0 +1,19 @@
+error: `#[structopt(raw(...))` attributes are removed in structopt 0.3, they are replaced with raw methods
+
+  = help: if you meant to call `clap::Arg::raw()` method you should use bool literal, like `raw(true)` or `raw(false)`
+  = note: if you need to call `clap::Arg/App::case_insensitive` method you can do it like this: #[structopt(case_insensitive = true)]
+
+  --> $DIR/raw.rs:13:17
+   |
+13 |     #[structopt(raw(case_insensitive = "true"))]
+   |                 ^^^
+
+error: `#[structopt(raw(...))` attributes are removed in structopt 0.3, they are replaced with raw methods
+
+  = help: if you meant to call `clap::Arg::raw()` method you should use bool literal, like `raw(true)` or `raw(false)`
+  = note: if you need to call `clap::Arg/App::requires_if` method you can do it like this: #[structopt(requires_if("one", "two"))]
+
+  --> $DIR/raw.rs:19:17
+   |
+19 |     #[structopt(raw(requires_if = r#""one", "two""#))]
+   |                 ^^^
diff --git a/tests/ui/rename_all_wrong_casing.rs b/tests/ui/rename_all_wrong_casing.rs
new file mode 100644
index 0000000..4dabe14
--- /dev/null
+++ b/tests/ui/rename_all_wrong_casing.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic", rename_all = "fail")]
+struct Opt {
+    #[structopt(short)]
+    s: String,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/rename_all_wrong_casing.stderr b/tests/ui/rename_all_wrong_casing.stderr
new file mode 100644
index 0000000..2a72080
--- /dev/null
+++ b/tests/ui/rename_all_wrong_casing.stderr
@@ -0,0 +1,5 @@
+error: unsupported casing: `fail`
+  --> $DIR/rename_all_wrong_casing.rs:12:42
+   |
+12 | #[structopt(name = "basic", rename_all = "fail")]
+   |                                          ^^^^^^
diff --git a/tests/ui/skip_flatten.rs b/tests/ui/skip_flatten.rs
new file mode 100644
index 0000000..8668ec2
--- /dev/null
+++ b/tests/ui/skip_flatten.rs
@@ -0,0 +1,42 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "make-cookie")]
+struct MakeCookie {
+    #[structopt(short)]
+    s: String,
+
+    #[structopt(skip, flatten)]
+    cmd: Command,
+}
+
+#[derive(StructOpt, Debug)]
+enum Command {
+    #[structopt(name = "pound")]
+    /// Pound acorns into flour for cookie dough.
+    Pound { acorns: u32 },
+
+    Sparkle {
+        #[structopt(short)]
+        color: String,
+    },
+}
+
+impl Default for Command {
+    fn default() -> Self {
+        Command::Pound { acorns: 0 }
+    }
+}
+
+fn main() {
+    let opt = MakeCookie::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/skip_flatten.stderr b/tests/ui/skip_flatten.stderr
new file mode 100644
index 0000000..76477a3
--- /dev/null
+++ b/tests/ui/skip_flatten.stderr
@@ -0,0 +1,5 @@
+error: subcommand, flatten and skip cannot be used together
+  --> $DIR/skip_flatten.rs:17:23
+   |
+17 |     #[structopt(skip, flatten)]
+   |                       ^^^^^^^
diff --git a/tests/ui/skip_subcommand.rs b/tests/ui/skip_subcommand.rs
new file mode 100644
index 0000000..5d21426
--- /dev/null
+++ b/tests/ui/skip_subcommand.rs
@@ -0,0 +1,42 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "make-cookie")]
+struct MakeCookie {
+    #[structopt(short)]
+    s: String,
+
+    #[structopt(subcommand, skip)]
+    cmd: Command,
+}
+
+#[derive(StructOpt, Debug)]
+enum Command {
+    #[structopt(name = "pound")]
+    /// Pound acorns into flour for cookie dough.
+    Pound { acorns: u32 },
+
+    Sparkle {
+        #[structopt(short)]
+        color: String,
+    },
+}
+
+impl Default for Command {
+    fn default() -> Self {
+        Command::Pound { acorns: 0 }
+    }
+}
+
+fn main() {
+    let opt = MakeCookie::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/skip_subcommand.stderr b/tests/ui/skip_subcommand.stderr
new file mode 100644
index 0000000..aba2d69
--- /dev/null
+++ b/tests/ui/skip_subcommand.stderr
@@ -0,0 +1,5 @@
+error: subcommand, flatten and skip cannot be used together
+  --> $DIR/skip_subcommand.rs:17:29
+   |
+17 |     #[structopt(subcommand, skip)]
+   |                             ^^^^
diff --git a/tests/ui/skip_with_other_options.rs b/tests/ui/skip_with_other_options.rs
new file mode 100644
index 0000000..73c5342
--- /dev/null
+++ b/tests/ui/skip_with_other_options.rs
@@ -0,0 +1,15 @@
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "test")]
+pub struct Opt {
+    #[structopt(long)]
+    a: u32,
+    #[structopt(skip, long)]
+    b: u32,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/skip_with_other_options.stderr b/tests/ui/skip_with_other_options.stderr
new file mode 100644
index 0000000..3345f92
--- /dev/null
+++ b/tests/ui/skip_with_other_options.stderr
@@ -0,0 +1,5 @@
+error: methods are not allowed for skipped fields
+ --> $DIR/skip_with_other_options.rs:8:17
+  |
+8 |     #[structopt(skip, long)]
+  |                 ^^^^
diff --git a/tests/ui/skip_without_default.rs b/tests/ui/skip_without_default.rs
new file mode 100644
index 0000000..bc47511
--- /dev/null
+++ b/tests/ui/skip_without_default.rs
@@ -0,0 +1,29 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(Debug)]
+enum Kind {
+    A,
+    B,
+}
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "test")]
+pub struct Opt {
+    #[structopt(short)]
+    number: u32,
+    #[structopt(skip)]
+    k: Kind,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/skip_without_default.stderr b/tests/ui/skip_without_default.stderr
new file mode 100644
index 0000000..330898f
--- /dev/null
+++ b/tests/ui/skip_without_default.stderr
@@ -0,0 +1,9 @@
+error[E0277]: the trait bound `Kind: std::default::Default` is not satisfied
+  --> $DIR/skip_without_default.rs:22:17
+   |
+22 |     #[structopt(skip)]
+   |                 ^^^^ the trait `std::default::Default` is not implemented for `Kind`
+   |
+   = note: required by `std::default::Default::default`
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/struct_parse.rs b/tests/ui/struct_parse.rs
new file mode 100644
index 0000000..e428b23
--- /dev/null
+++ b/tests/ui/struct_parse.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic", parse(from_str))]
+struct Opt {
+    #[structopt(short)]
+    s: String,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/struct_parse.stderr b/tests/ui/struct_parse.stderr
new file mode 100644
index 0000000..5518214
--- /dev/null
+++ b/tests/ui/struct_parse.stderr
@@ -0,0 +1,5 @@
+error: `parse` attribute is only allowed on fields
+  --> $DIR/struct_parse.rs:12:29
+   |
+12 | #[structopt(name = "basic", parse(from_str))]
+   |                             ^^^^^
diff --git a/tests/ui/struct_subcommand.rs b/tests/ui/struct_subcommand.rs
new file mode 100644
index 0000000..ac0b145
--- /dev/null
+++ b/tests/ui/struct_subcommand.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic", subcommand)]
+struct Opt {
+    #[structopt(short)]
+    s: String,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/struct_subcommand.stderr b/tests/ui/struct_subcommand.stderr
new file mode 100644
index 0000000..438f6f8
--- /dev/null
+++ b/tests/ui/struct_subcommand.stderr
@@ -0,0 +1,5 @@
+error: subcommand is only allowed on fields
+  --> $DIR/struct_subcommand.rs:12:29
+   |
+12 | #[structopt(name = "basic", subcommand)]
+   |                             ^^^^^^^^^^
diff --git a/tests/ui/structopt_empty_attr.rs b/tests/ui/structopt_empty_attr.rs
new file mode 100644
index 0000000..a7fc0b9
--- /dev/null
+++ b/tests/ui/structopt_empty_attr.rs
@@ -0,0 +1,22 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+    #[structopt]
+    debug: bool,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
+
diff --git a/tests/ui/structopt_empty_attr.stderr b/tests/ui/structopt_empty_attr.stderr
new file mode 100644
index 0000000..bd3b3ed
--- /dev/null
+++ b/tests/ui/structopt_empty_attr.stderr
@@ -0,0 +1,5 @@
+error: expected attribute arguments in parentheses: #[structopt(...)]
+  --> $DIR/structopt_empty_attr.rs:14:5
+   |
+14 |     #[structopt]
+   |     ^^^^^^^^^^^^
diff --git a/tests/ui/structopt_name_value_attr.rs b/tests/ui/structopt_name_value_attr.rs
new file mode 100644
index 0000000..3d9388f
--- /dev/null
+++ b/tests/ui/structopt_name_value_attr.rs
@@ -0,0 +1,22 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt {
+    #[structopt = "short"]
+    debug: bool,
+}
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
+
diff --git a/tests/ui/structopt_name_value_attr.stderr b/tests/ui/structopt_name_value_attr.stderr
new file mode 100644
index 0000000..373a3b8
--- /dev/null
+++ b/tests/ui/structopt_name_value_attr.stderr
@@ -0,0 +1,5 @@
+error: expected parentheses: #[structopt(...)]
+  --> $DIR/structopt_name_value_attr.rs:14:17
+   |
+14 |     #[structopt = "short"]
+   |                 ^
diff --git a/tests/ui/subcommand_and_flatten.rs b/tests/ui/subcommand_and_flatten.rs
new file mode 100644
index 0000000..742ee6d
--- /dev/null
+++ b/tests/ui/subcommand_and_flatten.rs
@@ -0,0 +1,36 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "make-cookie")]
+struct MakeCookie {
+    #[structopt(short)]
+    s: String,
+
+    #[structopt(subcommand, flatten)]
+    cmd: Command,
+}
+
+#[derive(StructOpt, Debug)]
+enum Command {
+    #[structopt(name = "pound")]
+    /// Pound acorns into flour for cookie dough.
+    Pound { acorns: u32 },
+
+    Sparkle {
+        #[structopt(short)]
+        color: String,
+    },
+}
+
+fn main() {
+    let opt = MakeCookie::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/subcommand_and_flatten.stderr b/tests/ui/subcommand_and_flatten.stderr
new file mode 100644
index 0000000..cacea5e
--- /dev/null
+++ b/tests/ui/subcommand_and_flatten.stderr
@@ -0,0 +1,5 @@
+error: subcommand, flatten and skip cannot be used together
+  --> $DIR/subcommand_and_flatten.rs:17:29
+   |
+17 |     #[structopt(subcommand, flatten)]
+   |                             ^^^^^^^
diff --git a/tests/ui/subcommand_and_methods.rs b/tests/ui/subcommand_and_methods.rs
new file mode 100644
index 0000000..890f10c
--- /dev/null
+++ b/tests/ui/subcommand_and_methods.rs
@@ -0,0 +1,36 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "make-cookie")]
+struct MakeCookie {
+    #[structopt(short)]
+    s: String,
+
+    #[structopt(subcommand, long)]
+    cmd: Command,
+}
+
+#[derive(StructOpt, Debug)]
+enum Command {
+    #[structopt(name = "pound")]
+    /// Pound acorns into flour for cookie dough.
+    Pound { acorns: u32 },
+
+    Sparkle {
+        #[structopt(short)]
+        color: String,
+    },
+}
+
+fn main() {
+    let opt = MakeCookie::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/subcommand_and_methods.stderr b/tests/ui/subcommand_and_methods.stderr
new file mode 100644
index 0000000..ccaf28d
--- /dev/null
+++ b/tests/ui/subcommand_and_methods.stderr
@@ -0,0 +1,5 @@
+error: methods in attributes are not allowed for subcommand
+  --> $DIR/subcommand_and_methods.rs:17:17
+   |
+17 |     #[structopt(subcommand, long)]
+   |                 ^^^^^^^^^^
diff --git a/tests/ui/subcommand_and_parse.rs b/tests/ui/subcommand_and_parse.rs
new file mode 100644
index 0000000..f24e4bc
--- /dev/null
+++ b/tests/ui/subcommand_and_parse.rs
@@ -0,0 +1,36 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "make-cookie")]
+struct MakeCookie {
+    #[structopt(short)]
+    s: String,
+
+    #[structopt(subcommand, parse(from_occurrences))]
+    cmd: Command,
+}
+
+#[derive(StructOpt, Debug)]
+enum Command {
+    #[structopt(name = "pound")]
+    /// Pound acorns into flour for cookie dough.
+    Pound { acorns: u32 },
+
+    Sparkle {
+        #[structopt(short)]
+        color: String,
+    },
+}
+
+fn main() {
+    let opt = MakeCookie::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/subcommand_and_parse.stderr b/tests/ui/subcommand_and_parse.stderr
new file mode 100644
index 0000000..4070056
--- /dev/null
+++ b/tests/ui/subcommand_and_parse.stderr
@@ -0,0 +1,5 @@
+error: parse attribute is not allowed for subcommand
+  --> $DIR/subcommand_and_parse.rs:17:29
+   |
+17 |     #[structopt(subcommand, parse(from_occurrences))]
+   |                             ^^^^^
diff --git a/tests/ui/subcommand_opt_opt.rs b/tests/ui/subcommand_opt_opt.rs
new file mode 100644
index 0000000..1dd84e5
--- /dev/null
+++ b/tests/ui/subcommand_opt_opt.rs
@@ -0,0 +1,36 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "make-cookie")]
+struct MakeCookie {
+    #[structopt(short)]
+    s: String,
+
+    #[structopt(subcommand)]
+    cmd: Option<Option<Command>>,
+}
+
+#[derive(StructOpt, Debug)]
+enum Command {
+    #[structopt(name = "pound")]
+    /// Pound acorns into flour for cookie dough.
+    Pound { acorns: u32 },
+
+    Sparkle {
+        #[structopt(short)]
+        color: String,
+    },
+}
+
+fn main() {
+    let opt = MakeCookie::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/subcommand_opt_opt.stderr b/tests/ui/subcommand_opt_opt.stderr
new file mode 100644
index 0000000..25b37e5
--- /dev/null
+++ b/tests/ui/subcommand_opt_opt.stderr
@@ -0,0 +1,5 @@
+error: Option<Option<T>> type is not allowed for subcommand
+  --> $DIR/subcommand_opt_opt.rs:18:10
+   |
+18 |     cmd: Option<Option<Command>>,
+   |          ^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/subcommand_opt_vec.rs b/tests/ui/subcommand_opt_vec.rs
new file mode 100644
index 0000000..17bffbf
--- /dev/null
+++ b/tests/ui/subcommand_opt_vec.rs
@@ -0,0 +1,36 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "make-cookie")]
+struct MakeCookie {
+    #[structopt(short)]
+    s: String,
+
+    #[structopt(subcommand)]
+    cmd: Option<Vec<Command>>,
+}
+
+#[derive(StructOpt, Debug)]
+enum Command {
+    #[structopt(name = "pound")]
+    /// Pound acorns into flour for cookie dough.
+    Pound { acorns: u32 },
+
+    Sparkle {
+        #[structopt(short)]
+        color: String,
+    },
+}
+
+fn main() {
+    let opt = MakeCookie::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/subcommand_opt_vec.stderr b/tests/ui/subcommand_opt_vec.stderr
new file mode 100644
index 0000000..a36071b
--- /dev/null
+++ b/tests/ui/subcommand_opt_vec.stderr
@@ -0,0 +1,5 @@
+error: Option<Vec<T>> type is not allowed for subcommand
+  --> $DIR/subcommand_opt_vec.rs:18:10
+   |
+18 |     cmd: Option<Vec<Command>>,
+   |          ^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/tuple_struct.rs b/tests/ui/tuple_struct.rs
new file mode 100644
index 0000000..af9b1d5
--- /dev/null
+++ b/tests/ui/tuple_struct.rs
@@ -0,0 +1,18 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+use structopt::StructOpt;
+
+#[derive(StructOpt, Debug)]
+#[structopt(name = "basic")]
+struct Opt(u32);
+
+fn main() {
+    let opt = Opt::from_args();
+    println!("{:?}", opt);
+}
diff --git a/tests/ui/tuple_struct.stderr b/tests/ui/tuple_struct.stderr
new file mode 100644
index 0000000..9f2876f
--- /dev/null
+++ b/tests/ui/tuple_struct.stderr
@@ -0,0 +1,5 @@
+error: structopt only supports non-tuple structs and enums
+  --> $DIR/tuple_struct.rs:11:10
+   |
+11 | #[derive(StructOpt, Debug)]
+   |          ^^^^^^^^^
diff --git a/tests/utils.rs b/tests/utils.rs
new file mode 100644
index 0000000..c0684a2
--- /dev/null
+++ b/tests/utils.rs
@@ -0,0 +1,45 @@
+#![allow(unused)]
+
+use structopt::StructOpt;
+
+pub fn get_help<T: StructOpt>() -> String {
+    let mut output = Vec::new();
+    <T as StructOpt>::clap().write_help(&mut output).unwrap();
+    let output = String::from_utf8(output).unwrap();
+
+    eprintln!("\n%%% HELP %%%:=====\n{}\n=====\n", output);
+    eprintln!("\n%%% HELP (DEBUG) %%%:=====\n{:?}\n=====\n", output);
+
+    output
+}
+
+pub fn get_long_help<T: StructOpt>() -> String {
+    let mut output = Vec::new();
+    <T as StructOpt>::clap()
+        .write_long_help(&mut output)
+        .unwrap();
+    let output = String::from_utf8(output).unwrap();
+
+    eprintln!("\n%%% LONG_HELP %%%:=====\n{}\n=====\n", output);
+    eprintln!("\n%%% LONG_HELP (DEBUG) %%%:=====\n{:?}\n=====\n", output);
+
+    output
+}
+
+pub fn get_subcommand_long_help<T: StructOpt>(subcmd: &str) -> String {
+    let output = <T as StructOpt>::clap()
+        .get_matches_from_safe(vec!["test", subcmd, "--help"])
+        .expect_err("")
+        .message;
+
+    eprintln!(
+        "\n%%% SUBCOMMAND `{}` HELP %%%:=====\n{}\n=====\n",
+        subcmd, output
+    );
+    eprintln!(
+        "\n%%% SUBCOMMAND `{}` HELP (DEBUG) %%%:=====\n{:?}\n=====\n",
+        subcmd, output
+    );
+
+    output
+}
diff --git a/tests/we_need_syn_full.rs b/tests/we_need_syn_full.rs
new file mode 100644
index 0000000..cc6eca8
--- /dev/null
+++ b/tests/we_need_syn_full.rs
@@ -0,0 +1,19 @@
+// See https://github.com/TeXitoi/structopt/issues/354
+
+use structopt::StructOpt;
+
+#[test]
+fn we_need_syn_full() {
+    #[allow(unused)]
+    #[derive(Debug, StructOpt, Clone)]
+    struct Args {
+        #[structopt(
+            short = "c",
+            long = "colour",
+            help = "Output colouring",
+            default_value = "auto",
+            possible_values = &["always", "auto", "never"]
+        )]
+        colour: String,
+    }
+}