Repository: kbknapp/clap-rs
Pull request #1157 (2018-01-31 04:50:29)

V3 dev


<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/kbknapp/clap-rs/1157)
<!-- Reviewable:end -->


mention-bot: @kbknapp, thanks for your PR! By analyzing the history of the files in this pull request, we identified @kbknapp to be a potential reviewer.

Patch:
diff --git a/Cargo.toml b/Cargo.toml
index 57eea397..7b926c37 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 
 name = "clap"
-version = "2.29.2"
+version = "3.0.0-alpha1"
 authors = ["Kevin K. <kbknapp@gmail.com>"]
 exclude = ["examples/*", "clap-test/*", "tests/*", "benches/*", "*.png", "clap-perf/*", "*.dot"]
 repository = "https://github.com/kbknapp/clap-rs"
diff --git a/benches/03_complex.rs b/benches/03_complex.rs
index 639d6829..65a747c2 100644
--- a/benches/03_complex.rs
+++ b/benches/03_complex.rs
@@ -4,7 +4,7 @@
 extern crate clap;
 extern crate test;
 
-use clap::{App, AppSettings, Arg, SubCommand};
+use clap::{App, AppSettings, Arg, SubCommand, ArgSettings};
 
 use test::Bencher;
 
@@ -21,7 +21,7 @@ macro_rules! create_app {
                 .author("Kevin K. <kbknapp@gmail.com>")
                 .args_from_usage(ARGS)
                 .arg(Arg::from_usage("-f --flag... 'tests flags'")
-                             .global(true))
+                             .setting(ArgSettings::Global))
                 .args(&[
                           Arg::from_usage("[flag2] -F 'tests flags with exclusions'").conflicts_with("flag").requires("option2"),
                           Arg::from_usage("--long-option-2 [option2] 'tests long options with exclusions'").conflicts_with("option").requires("positional2"),
@@ -57,8 +57,8 @@ fn create_app_builder(b: &mut Bencher) {
                     .help("tests options")
                     .short("o")
                     .long("option")
-                    .takes_value(true)
-                    .multiple(true),
+                    .setting(ArgSettings::MultipleValues)
+                    .setting(ArgSettings::MultipleOccurrences),
             )
             .arg(
                 Arg::with_name("positional")
@@ -70,8 +70,7 @@ fn create_app_builder(b: &mut Bencher) {
                     .short("f")
                     .help("tests flags")
                     .long("flag")
-                    .multiple(true)
-                    .global(true),
+                    .settings(&[ArgSettings::MultipleOccurrences, ArgSettings::Global]),
             )
             .arg(
                 Arg::with_name("flag2")
@@ -85,7 +84,7 @@ fn create_app_builder(b: &mut Bencher) {
                     .help("tests long options with exclusions")
                     .conflicts_with("option")
                     .requires("positional2")
-                    .takes_value(true)
+                    .setting(ArgSettings::TakesValue)
                     .long("long-option-2"),
             )
             .arg(
@@ -97,13 +96,14 @@ fn create_app_builder(b: &mut Bencher) {
                 Arg::with_name("option3")
                     .short("O")
                     .long("Option")
-                    .takes_value(true)
+                    .setting(ArgSettings::TakesValue)
                     .help("tests options with specific value sets")
                     .possible_values(&OPT3_VALS),
             )
             .arg(
                 Arg::with_name("positional3")
-                    .multiple(true)
+                    .setting(ArgSettings::MultipleValues)
+                    .setting(ArgSettings::MultipleOccurrences)
                     .help("tests positionals with specific values")
                     .index(4)
                     .possible_values(&POS3_VALS),
@@ -111,31 +111,30 @@ fn create_app_builder(b: &mut Bencher) {
             .arg(
                 Arg::with_name("multvals")
                     .long("multvals")
-                    .takes_value(true)
                     .help("Tests mutliple values, not mult occs")
                     .value_names(&["one", "two"]),
             )
             .arg(
                 Arg::with_name("multvalsmo")
                     .long("multvalsmo")
-                    .takes_value(true)
-                    .multiple(true)
+                    .setting(ArgSettings::MultipleValues)
+                    .setting(ArgSettings::MultipleOccurrences)
                     .help("Tests mutliple values, not mult occs")
                     .value_names(&["one", "two"]),
             )
             .arg(
                 Arg::with_name("minvals")
                     .long("minvals2")
-                    .multiple(true)
-                    .takes_value(true)
+                    .setting(ArgSettings::MultipleValues)
+                    .setting(ArgSettings::MultipleOccurrences)
                     .help("Tests 2 min vals")
                     .min_values(2),
             )
             .arg(
                 Arg::with_name("maxvals")
                     .long("maxvals3")
-                    .takes_value(true)
-                    .multiple(true)
+                    .setting(ArgSettings::MultipleValues)
+                    .setting(ArgSettings::MultipleOccurrences)
                     .help("Tests 3 max vals")
                     .max_values(3),
             )
@@ -148,8 +147,8 @@ fn create_app_builder(b: &mut Bencher) {
                         Arg::with_name("scoption")
                             .short("o")
                             .long("option")
-                            .multiple(true)
-                            .takes_value(true)
+                            .setting(ArgSettings::MultipleValues)
+                            .setting(ArgSettings::MultipleOccurrences)
                             .help("tests options"),
                     )
                     .arg(
diff --git a/benches/04_new_help.rs b/benches/04_new_help.rs
index f42f3717..89cceb0e 100644
--- a/benches/04_new_help.rs
+++ b/benches/04_new_help.rs
@@ -8,7 +8,7 @@ use test::Bencher;
 use std::io::Cursor;
 
 use clap::App;
-use clap::{Arg, SubCommand};
+use clap::{Arg, ArgSettings, SubCommand};
 
 fn build_help(app: &mut App) -> String {
     let mut buf = Cursor::new(Vec::with_capacity(50));
@@ -51,13 +51,13 @@ fn app_example3<'b, 'c>() -> App<'b, 'c> {
         .args(&[
             Arg::with_name("config")
                 .help("sets the config file to use")
-                .takes_value(true)
+                .setting(ArgSettings::TakesValue)
                 .short("c")
                 .long("config"),
             Arg::with_name("input")
                 .help("the input file to use")
                 .index(1)
-                .required(true),
+                .setting(ArgSettings::Required),
         ])
         .arg_from_usage("--license 'display the license file'")
         .args_from_usage(
@@ -87,7 +87,7 @@ fn app_example4<'b, 'c>() -> App<'b, 'c> {
             Arg::with_name("input")
                 .help("the input file to use")
                 .index(1)
-                .required(true),
+                .setting(ArgSettings::Required),
         )
 }
 
@@ -97,7 +97,7 @@ fn app_example5<'b, 'c>() -> App<'b, 'c> {
             .help("turns up the awesome")
             .short("a")
             .long("awesome")
-            .multiple(true)
+            .setting(ArgSettings::MultipleOccurrences)
             .requires("config")
             .conflicts_with("output"),
     )
@@ -111,7 +111,7 @@ fn app_example6<'b, 'c>() -> App<'b, 'c> {
                 .index(1)
                 .requires("config")
                 .conflicts_with("output")
-                .required(true),
+                .setting(ArgSettings::Required),
         )
         .arg(
             Arg::with_name("config")
@@ -127,11 +127,13 @@ fn app_example7<'b, 'c>() -> App<'b, 'c> {
         .arg(
             Arg::with_name("input")
                 .help("the input file to use")
-                .takes_value(true)
+                .settings(&[
+                    ArgSettings::MultipleValues,
+                    ArgSettings::MultipleOccurrences,
+                    ArgSettings::Required,
+                ])
                 .short("i")
                 .long("input")
-                .multiple(true)
-                .required(true)
                 .requires("config")
                 .conflicts_with("output"),
         )
@@ -144,11 +146,13 @@ fn app_example8<'b, 'c>() -> App<'b, 'c> {
         .arg(
             Arg::with_name("input")
                 .help("the input file to use")
-                .takes_value(true)
+                .settings(&[
+                    ArgSettings::MultipleValues,
+                    ArgSettings::MultipleOccurrences,
+                    ArgSettings::Required,
+                ])
                 .short("i")
                 .long("input")
-                .multiple(true)
-                .required(true)
                 .requires("config")
                 .conflicts_with("output"),
         )
@@ -159,7 +163,7 @@ fn app_example10<'b, 'c>() -> App<'b, 'c> {
         Arg::with_name("CONFIG")
             .help("The config file to use (default is \"config.json\")")
             .short("c")
-            .takes_value(true),
+            .setting(ArgSettings::TakesValue),
     )
 }
 
diff --git a/benches/05_ripgrep.rs b/benches/05_ripgrep.rs
index 11c5db1a..d41739c0 100644
--- a/benches/05_ripgrep.rs
+++ b/benches/05_ripgrep.rs
@@ -279,11 +279,7 @@ fn app<F>(next_line_help: bool, doc: F) -> App<'static, 'static>
 where
     F: Fn(&'static str) -> &'static str,
 {
-    let arg = |name| {
-        Arg::with_name(name)
-            .help(doc(name))
-            .next_line_help(next_line_help)
-    };
+    let arg = |name| Arg::with_name(name).help(doc(name));
     let flag = |name| arg(name).long(name);
 
     App::new("ripgrep")
@@ -292,8 +288,8 @@ where
         .about(ABOUT)
         .max_term_width(100)
         .setting(AppSettings::UnifiedHelpMessage)
-        .usage(USAGE)
-        .template(TEMPLATE)
+        .override_usage(USAGE)
+        .help_template(TEMPLATE)
         // Handle help/version manually to make their output formatting
         // consistent with short/long views.
         .arg(arg("help-short").short("h"))
@@ -305,10 +301,12 @@ where
                 "file", "files", "help-short", "help", "regexp", "type-list",
                 "version",
              ]))
-        .arg(arg("path").multiple(true))
+        .arg(arg("path").setting(ArgSettings::MultipleOccurrences))
         .arg(flag("regexp").short("e")
-             .takes_value(true).multiple(true).number_of_values(1)
-             .set(ArgSettings::AllowLeadingHyphen)
+             .settings(&[
+                  ArgSettings::AllowHyphenValues, 
+                  ArgSettings::MultipleOccurrences, 
+                  ArgSettings::TakesValue])
              .value_name("pattern"))
         .arg(flag("files")
              // This should also conflict with `pattern`, but the first file
@@ -321,46 +319,45 @@ where
         .arg(flag("count").short("c"))
         .arg(flag("color")
              .value_name("WHEN")
-             .takes_value(true)
-             .hide_possible_values(true)
+             .setting(ArgSettings::HidePossibleValues)
              .possible_values(&["never", "auto", "always", "ansi"]))
         .arg(flag("colors").value_name("SPEC")
-             .takes_value(true).multiple(true).number_of_values(1))
+             .settings(&[ArgSettings::MultipleOccurrences, ArgSettings::TakesValue]))
         .arg(flag("fixed-strings").short("F"))
         .arg(flag("glob").short("g")
-             .takes_value(true).multiple(true).number_of_values(1)
+             .settings(&[ArgSettings::MultipleOccurrences, ArgSettings::TakesValue])
              .value_name("GLOB"))
         .arg(flag("ignore-case").short("i"))
         .arg(flag("line-number").short("n"))
         .arg(flag("no-line-number").short("N"))
         .arg(flag("quiet").short("q"))
         .arg(flag("type").short("t")
-             .takes_value(true).multiple(true).number_of_values(1)
+             .settings(&[ArgSettings::MultipleOccurrences, ArgSettings::TakesValue])
              .value_name("TYPE"))
         .arg(flag("type-not").short("T")
-             .takes_value(true).multiple(true).number_of_values(1)
+             .settings(&[ArgSettings::MultipleOccurrences, ArgSettings::TakesValue])
              .value_name("TYPE"))
         .arg(flag("unrestricted").short("u")
-             .multiple(true))
+             .setting(ArgSettings::MultipleOccurrences))
         .arg(flag("invert-match").short("v"))
         .arg(flag("word-regexp").short("w"))
         // Third, set up less common flags.
         .arg(flag("after-context").short("A")
-             .value_name("NUM").takes_value(true)
+             .value_name("NUM")
              .validator(validate_number))
         .arg(flag("before-context").short("B")
-             .value_name("NUM").takes_value(true)
+             .value_name("NUM")
              .validator(validate_number))
         .arg(flag("context").short("C")
-             .value_name("NUM").takes_value(true)
+             .value_name("NUM")
              .validator(validate_number))
         .arg(flag("column"))
         .arg(flag("context-separator")
-             .value_name("SEPARATOR").takes_value(true))
+             .value_name("SEPARATOR"))
         .arg(flag("debug"))
         .arg(flag("file").short("f")
-             .value_name("FILE").takes_value(true)
-             .multiple(true).number_of_values(1))
+             .value_name("FILE")
+             .setting(ArgSettings::MultipleOccurrences))
         .arg(flag("files-with-matches").short("l"))
         .arg(flag("files-without-match"))
         .arg(flag("with-filename").short("H"))
@@ -369,14 +366,14 @@ where
         .arg(flag("no-heading").overrides_with("heading"))
         .arg(flag("hidden"))
         .arg(flag("ignore-file")
-             .value_name("FILE").takes_value(true)
-             .multiple(true).number_of_values(1))
+             .value_name("FILE")
+             .setting(ArgSettings::MultipleOccurrences))
         .arg(flag("follow").short("L"))
         .arg(flag("max-count")
-             .short("m").value_name("NUM").takes_value(true)
+             .short("m").value_name("NUM")
              .validator(validate_number))
         .arg(flag("maxdepth")
-             .value_name("NUM").takes_value(true)
+             .value_name("NUM")
              .validator(validate_number))
         .arg(flag("mmap"))
         .arg(flag("no-messages"))
@@ -385,22 +382,22 @@ where
         .arg(flag("no-ignore-parent"))
         .arg(flag("no-ignore-vcs"))
         .arg(flag("null"))
-        .arg(flag("path-separator").value_name("SEPARATOR").takes_value(true))
+        .arg(flag("path-separator").value_name("SEPARATOR"))
         .arg(flag("pretty").short("p"))
-        .arg(flag("replace").short("r").value_name("ARG").takes_value(true))
+        .arg(flag("replace").short("r").value_name("ARG"))
         .arg(flag("case-sensitive").short("s"))
         .arg(flag("smart-case").short("S"))
         .arg(flag("sort-files"))
         .arg(flag("threads")
-             .short("j").value_name("ARG").takes_value(true)
+             .short("j").value_name("ARG")
              .validator(validate_number))
         .arg(flag("vimgrep"))
         .arg(flag("type-add")
-             .value_name("TYPE").takes_value(true)
-             .multiple(true).number_of_values(1))
+             .value_name("TYPE")
+             .setting(ArgSettings::MultipleOccurrences))
         .arg(flag("type-clear")
-             .value_name("TYPE").takes_value(true)
-             .multiple(true).number_of_values(1))
+             .value_name("TYPE")
+             .setting(ArgSettings::MultipleOccurrences))
 }
 
 struct Usage {
diff --git a/benches/06_rustup.rs b/benches/06_rustup.rs
index d543ba90..9acebbe2 100644
--- a/benches/06_rustup.rs
+++ b/benches/06_rustup.rs
@@ -7,7 +7,7 @@
 extern crate clap;
 extern crate test;
 
-use clap::{App, AppSettings, Arg, ArgGroup, Shell, SubCommand};
+use clap::{App, AppSettings, Arg, ArgGroup, ArgSettings, Shell, SubCommand};
 
 use test::Bencher;
 
@@ -42,49 +42,47 @@ pub fn build_cli() -> App<'static, 'static> {
             .after_help(TOOLCHAIN_INSTALL_HELP)
             .setting(AppSettings::Hidden) // synonym for 'toolchain install'
             .arg(Arg::with_name("toolchain")
-                .required(true)))
+                .setting(ArgSettings::Required)))
         .subcommand(SubCommand::with_name("update")
             .about("Update Rust toolchains")
             .after_help(UPDATE_HELP)
-            .arg(Arg::with_name("toolchain").required(false))
+            .arg(Arg::with_name("toolchain").setting(ArgSettings::Required))
             .arg(Arg::with_name("no-self-update")
                 .help("Don't perform self update when running the `rustup` command")
                 .long("no-self-update")
-                .takes_value(false)
-                .hidden(true)))
+                .setting(ArgSettings::Hidden)))
         .subcommand(SubCommand::with_name("default")
             .about("Set the default toolchain")
             .after_help(DEFAULT_HELP)
-            .arg(Arg::with_name("toolchain").required(true)))
+            .arg(Arg::with_name("toolchain").setting(ArgSettings::Required)))
         .subcommand(SubCommand::with_name("toolchain")
             .about("Modify or query the installed toolchains")
             .after_help(TOOLCHAIN_HELP)
-            .setting(AppSettings::VersionlessSubcommands)
             .setting(AppSettings::DeriveDisplayOrder)
             // .setting(AppSettings::SubcommandRequiredElseHelp)
             .subcommand(SubCommand::with_name("list").about("List installed toolchains"))
             .subcommand(SubCommand::with_name("install")
                 .about("Install or update a given toolchain")
-                .arg(Arg::with_name("toolchain").required(true)))
+                .arg(Arg::with_name("toolchain").setting(ArgSettings::Required)))
             .subcommand(SubCommand::with_name("uninstall")
                 .about("Uninstall a toolchain")
-                .arg(Arg::with_name("toolchain").required(true)))
+                .arg(Arg::with_name("toolchain").setting(ArgSettings::Required)))
             .subcommand(SubCommand::with_name("link")
                 .about("Create a custom toolchain by symlinking to a directory")
-                .arg(Arg::with_name("toolchain").required(true))
-                .arg(Arg::with_name("path").required(true)))
+                .arg(Arg::with_name("toolchain").setting(ArgSettings::Required))
+                .arg(Arg::with_name("path").setting(ArgSettings::Required)))
             .subcommand(SubCommand::with_name("update")
                 .setting(AppSettings::Hidden) // synonym for 'install'
                 .arg(Arg::with_name("toolchain")
-                .required(true)))
+                .setting(ArgSettings::Required)))
             .subcommand(SubCommand::with_name("add")
                 .setting(AppSettings::Hidden) // synonym for 'install'
                 .arg(Arg::with_name("toolchain")
-                     .required(true)))
+                     .setting(ArgSettings::Required)))
             .subcommand(SubCommand::with_name("remove")
                 .setting(AppSettings::Hidden) // synonym for 'uninstall'
                 .arg(Arg::with_name("toolchain")
-                     .required(true))))
+                     .setting(ArgSettings::Required))))
         .subcommand(SubCommand::with_name("target")
             .about("Modify a toolchain's supported targets")
             .setting(AppSettings::VersionlessSubcommands)
@@ -94,33 +92,33 @@ pub fn build_cli() -> App<'static, 'static> {
                 .about("List installed and available targets")
                 .arg(Arg::with_name("toolchain")
                     .long("toolchain")
-                    .takes_value(true)))
+                    .setting(ArgSettings::TakesValue)))
             .subcommand(SubCommand::with_name("add")
                 .about("Add a target to a Rust toolchain")
-                .arg(Arg::with_name("target").required(true))
+                .arg(Arg::with_name("target").setting(ArgSettings::Required))
                 .arg(Arg::with_name("toolchain")
                     .long("toolchain")
-                    .takes_value(true)))
+                    .setting(ArgSettings::TakesValue)))
             .subcommand(SubCommand::with_name("remove")
                 .about("Remove a target  from a Rust toolchain")
-                .arg(Arg::with_name("target").required(true))
+                .arg(Arg::with_name("target").setting(ArgSettings::Required))
                 .arg(Arg::with_name("toolchain")
                     .long("toolchain")
-                    .takes_value(true)))
+                    .setting(ArgSettings::TakesValue)))
             .subcommand(SubCommand::with_name("install")
                 .setting(AppSettings::Hidden) // synonym for 'add'
                 .arg(Arg::with_name("target")
-                    .required(true))
+                    .setting(ArgSettings::Required))
                 .arg(Arg::with_name("toolchain")
                     .long("toolchain")
-                    .takes_value(true)))
+                    .setting(ArgSettings::TakesValue)))
             .subcommand(SubCommand::with_name("uninstall")
                 .setting(AppSettings::Hidden) // synonym for 'remove'
                 .arg(Arg::with_name("target")
-                    .required(true))
+                    .setting(ArgSettings::Required))
                 .arg(Arg::with_name("toolchain")
                     .long("toolchain")
-                    .takes_value(true))))
+                    .setting(ArgSettings::TakesValue))))
         .subcommand(SubCommand::with_name("component")
             .about("Modify a toolchain's installed components")
             .setting(AppSettings::VersionlessSubcommands)
@@ -130,25 +128,25 @@ pub fn build_cli() -> App<'static, 'static> {
                 .about("List installed and available components")
                 .arg(Arg::with_name("toolchain")
                     .long("toolchain")
-                    .takes_value(true)))
+                    .setting(ArgSettings::TakesValue)))
             .subcommand(SubCommand::with_name("add")
                 .about("Add a component to a Rust toolchain")
-                .arg(Arg::with_name("component").required(true))
+                .arg(Arg::with_name("component").setting(ArgSettings::Required))
                 .arg(Arg::with_name("toolchain")
                     .long("toolchain")
-                    .takes_value(true))
+                    .setting(ArgSettings::TakesValue))
                 .arg(Arg::with_name("target")
                     .long("target")
-                    .takes_value(true)))
+                    .setting(ArgSettings::TakesValue)))
             .subcommand(SubCommand::with_name("remove")
                 .about("Remove a component from a Rust toolchain")
-                .arg(Arg::with_name("component").required(true))
+                .arg(Arg::with_name("component").setting(ArgSettings::Required))
                 .arg(Arg::with_name("toolchain")
                     .long("toolchain")
-                    .takes_value(true))
+                    .setting(ArgSettings::TakesValue))
                 .arg(Arg::with_name("target")
                     .long("target")
-                    .takes_value(true))))
+                    .setting(ArgSettings::TakesValue))))
         .subcommand(SubCommand::with_name("override")
             .about("Modify directory toolchain overrides")
             .after_help(OVERRIDE_HELP)
@@ -158,44 +156,40 @@ pub fn build_cli() -> App<'static, 'static> {
             .subcommand(SubCommand::with_name("list").about("List directory toolchain overrides"))
             .subcommand(SubCommand::with_name("set")
                 .about("Set the override toolchain for a directory")
-                .arg(Arg::with_name("toolchain").required(true)))
+                .arg(Arg::with_name("toolchain").setting(ArgSettings::Required)))
             .subcommand(SubCommand::with_name("unset")
                 .about("Remove the override toolchain for a directory")
                 .after_help(OVERRIDE_UNSET_HELP)
                 .arg(Arg::with_name("path")
                     .long("path")
-                    .takes_value(true)
+                    .setting(ArgSettings::TakesValue)
                     .help("Path to the directory"))
                 .arg(Arg::with_name("nonexistent")
                     .long("nonexistent")
-                    .takes_value(false)
                     .help("Remove override toolchain for all nonexistent directories")))
             .subcommand(SubCommand::with_name("add")
                 .setting(AppSettings::Hidden) // synonym for 'set'
                 .arg(Arg::with_name("toolchain")
-                     .required(true)))
+                     .setting(ArgSettings::Required)))
             .subcommand(SubCommand::with_name("remove")
                 .setting(AppSettings::Hidden) // synonym for 'unset'
                 .about("Remove the override toolchain for a directory")
                 .arg(Arg::with_name("path")
                     .long("path")
-                    .takes_value(true))
+                    .setting(ArgSettings::TakesValue))
                 .arg(Arg::with_name("nonexistent")
                     .long("nonexistent")
-                    .takes_value(false)
                     .help("Remove override toolchain for all nonexistent directories"))))
         .subcommand(SubCommand::with_name("run")
             .about("Run a command with an environment configured for a given toolchain")
             .after_help(RUN_HELP)
             .setting(AppSettings::TrailingVarArg)
-            .arg(Arg::with_name("toolchain").required(true))
+            .arg(Arg::with_name("toolchain").setting(ArgSettings::Required))
             .arg(Arg::with_name("command")
-                .required(true)
-                .multiple(true)
-                .use_delimiter(false)))
+                .settings(&[ArgSettings::Required, ArgSettings::MultipleValues, ArgSettings::MutlipleOccurrences])))
         .subcommand(SubCommand::with_name("which")
             .about("Display which binary will be run for a given command")
-            .arg(Arg::with_name("command").required(true)))
+            .arg(Arg::with_name("command").setting(ArgSettings::Required)))
         .subcommand(SubCommand::with_name("doc")
             .about("Open the documentation for the current toolchain")
             .after_help(DOC_HELP)
@@ -208,15 +202,14 @@ pub fn build_cli() -> App<'static, 'static> {
             .group(ArgGroup::with_name("page").args(&["book", "std"])))
         .subcommand(SubCommand::with_name("man")
             .about("View the man page for a given command")
-            .arg(Arg::with_name("command").required(true))
+            .arg(Arg::with_name("command").setting(ArgSettings::Required))
             .arg(Arg::with_name("toolchain")
                 .long("toolchain")
-                .takes_value(true)))
+                .setting(ArgSettings::TakesValue)))
         .subcommand(SubCommand::with_name("self")
             .about("Modify the rustup installation")
             .setting(AppSettings::VersionlessSubcommands)
             .setting(AppSettings::DeriveDisplayOrder)
-            // .setting(AppSettings::SubcommandRequiredElseHelp)
             .subcommand(SubCommand::with_name("update")
                 .about("Download and install updates to rustup"))
             .subcommand(SubCommand::with_name("uninstall")
@@ -229,16 +222,14 @@ pub fn build_cli() -> App<'static, 'static> {
             .setting(AppSettings::Hidden)
             .setting(AppSettings::VersionlessSubcommands)
             .setting(AppSettings::DeriveDisplayOrder)
-            // .setting(AppSettings::SubcommandRequiredElseHelp)
             .subcommand(SubCommand::with_name("enable").about("Enable rustup telemetry"))
             .subcommand(SubCommand::with_name("disable").about("Disable rustup telemetry"))
             .subcommand(SubCommand::with_name("analyze").about("Analyze stored telemetry")))
         .subcommand(SubCommand::with_name("set")
             .about("Alter rustup settings")
-            // .setting(AppSettings::SubcommandRequiredElseHelp)
             .subcommand(SubCommand::with_name("default-host")
                 .about("The triple used to identify toolchains when not specified")
-                .arg(Arg::with_name("host_triple").required(true))))
+                .arg(Arg::with_name("host_triple").setting(ArgSettings::Required))))
         .subcommand(SubCommand::with_name("completions")
             .about("Generate completion scripts for your shell")
             .after_help(COMPLETIONS_HELP)
diff --git a/src/app/help.rs b/src/app/help.rs
index aed33303..df1d034c 100644
--- a/src/app/help.rs
+++ b/src/app/help.rs
@@ -296,6 +296,8 @@ impl<'w> Help<'w> {
     /// Writes argument's possible values to the wrapped stream.
     fn val<'b, 'c>(&mut self, arg: &Arg<'b, 'c>) -> Result<String, io::Error> {
         debugln!("Help::val: arg={}", arg.name);
+        let mult =
+            arg.is_set(ArgSettings::MultipleValues) || arg.is_set(ArgSettings::MultipleOccurrences);
         if arg.is_set(ArgSettings::TakesValue) {
             let delim = if arg.is_set(ArgSettings::RequireDelimiter) {
                 arg.val_delim.expect(INTERNAL_ERROR_MSG)
@@ -311,7 +313,7 @@ impl<'w> Help<'w> {
                     }
                 }
                 let num = vec.len();
-                if arg.is_set(ArgSettings::Multiple) && num == 1 {
+                if mult && num == 1 {
                     color!(self, "...", good)?;
                 }
             } else if let Some(num) = arg.num_vals {
@@ -322,12 +324,12 @@ impl<'w> Help<'w> {
                         write!(self.writer, "{}", delim)?;
                     }
                 }
-                if arg.is_set(ArgSettings::Multiple) && num == 1 {
+                if mult && num == 1 {
                     color!(self, "...", good)?;
                 }
             } else if arg.has_switch() {
                 color!(self, "<{}>", arg.name, good)?;
-                if arg.is_set(ArgSettings::Multiple) {
+                if mult {
                     color!(self, "...", good)?;
                 }
             } else {
diff --git a/src/app/mod.rs b/src/app/mod.rs
index b4647af7..9bbed4cc 100644
--- a/src/app/mod.rs
+++ b/src/app/mod.rs
@@ -1564,8 +1564,8 @@ impl<'a, 'b> App<'a, 'b> {
             assert!(
                 positionals!(self).fold(0, |acc, p| if p.index == Some(idx as u64){acc+1}else{acc}) < 2,
                 "Argument '{}' has the same index as another positional \
-                 argument\n\n\tUse Arg::multiple(true) to allow one positional argument \
-                 to take multiple values",
+                 argument\n\n\tUse Arg::setting(ArgSettings::MultipleValues) to allow one \
+                 positional argument to take multiple values",
                 a.name
             );
         }
diff --git a/src/app/parser.rs b/src/app/parser.rs
index f2d8e356..4b528b3c 100644
--- a/src/app/parser.rs
+++ b/src/app/parser.rs
@@ -128,7 +128,7 @@ where
 
         // Next we verify that only the highest index has a .multiple(true) (if any)
         if positionals!(self.app).any(|a| {
-            a.is_set(ArgSettings::Multiple) && (a.index.unwrap_or(0) != highest_idx as u64)
+            a.is_set(ArgSettings::MultipleValues) && (a.index.unwrap_or(0) != highest_idx as u64)
         }) {
             // First we make sure if there is a positional that allows multiple values
             // the one before it (second to last) has one of these:
@@ -157,7 +157,8 @@ where
             );
 
             // We make sure if the second to last is Multiple the last is ArgSettings::Last
-            let ok = second_to_last.is_set(ArgSettings::Multiple) || last.is_set(ArgSettings::Last);
+            let ok = second_to_last.is_set(ArgSettings::MultipleValues)
+                || last.is_set(ArgSettings::Last);
             assert!(
                 ok,
                 "Only the last positional argument, or second to last positional \
@@ -166,15 +167,15 @@ where
 
             // Next we check how many have both Multiple and not a specific number of values set
             let count = positionals!(self.app).fold(0, |acc, p| {
-                if p.settings.is_set(ArgSettings::Multiple) && p.num_vals.is_none() {
+                if p.settings.is_set(ArgSettings::MultipleValues) && p.num_vals.is_none() {
                     acc + 1
                 } else {
                     acc
                 }
             });
             let ok = count <= 1
-                || (last.is_set(ArgSettings::Last) && last.is_set(ArgSettings::Multiple)
-                    && second_to_last.is_set(ArgSettings::Multiple)
+                || (last.is_set(ArgSettings::Last) && last.is_set(ArgSettings::MultipleValues)
+                    && second_to_last.is_set(ArgSettings::MultipleValues)
                     && count == 2);
             assert!(
                 ok,
@@ -307,7 +308,7 @@ where
         debug_assert!(self._verify_positionals());
         // Set the LowIndexMultiple flag if required
         if positionals!(self.app).any(|a| {
-            a.is_set(ArgSettings::Multiple)
+            a.is_set(ArgSettings::MultipleValues)
                 && (a.index.unwrap_or(0) as usize != self.positionals.len())
         }) && self.positionals.values().last().map_or(false, |p_name| {
             !find!(self.app, p_name)
@@ -535,7 +536,7 @@ where
 
                 self.app.settings.set(AS::ValidArgFound);
                 // Only increment the positional counter if it doesn't allow multiples
-                if !p.settings.is_set(ArgSettings::Multiple) {
+                if !p.settings.is_set(ArgSettings::MultipleValues) {
                     pos_counter += 1;
                 }
                 self.app.settings.set(AS::ValidArgFound);
@@ -721,7 +722,7 @@ where
         if help_help {
             let mut pb = Arg::with_name("subcommand")
                 .index(1)
-                .set(ArgSettings::Multiple)
+                .setting(ArgSettings::MultipleValues)
                 .help("The subcommand whose help message to display");
             pb._build();
             parser.positionals.insert(1, pb.name);
@@ -754,11 +755,11 @@ where
         let arg_allows_tac = match needs_val_of {
             ParseResult::Opt(name) => {
                 let o = find!(self.app, &name).expect(INTERNAL_ERROR_MSG);
-                (o.is_set(ArgSettings::AllowLeadingHyphen) || app_wide_settings)
+                (o.is_set(ArgSettings::AllowHyphenValues) || app_wide_settings)
             }
             ParseResult::Pos(name) => {
                 let p = find!(self.app, &name).expect(INTERNAL_ERROR_MSG);
-                (p.is_set(ArgSettings::AllowLeadingHyphen) || app_wide_settings)
+                (p.is_set(ArgSettings::AllowHyphenValues) || app_wide_settings)
             }
             ParseResult::ValuesDone => return true,
             _ => false,
@@ -1061,7 +1062,7 @@ where
         debugln!("Parser::parse_opt; opt.settings={:?}", opt.settings);
         let mut has_eq = false;
         let no_val = val.is_none();
-        let empty_vals = opt.is_set(ArgSettings::EmptyValues);
+        let empty_vals = opt.is_set(ArgSettings::AllowEmptyValues);
         let min_vals_zero = opt.min_vals.unwrap_or(1) == 0;
         let needs_eq = opt.is_set(ArgSettings::RequireEquals);
 
@@ -1101,7 +1102,8 @@ where
             .and_then(|vec| Some(matcher.inc_occurrences_of(&*vec)));
 
         let needs_delim = opt.is_set(ArgSettings::RequireDelimiter);
-        let mult = opt.is_set(ArgSettings::Multiple);
+        let mult = opt.is_set(ArgSettings::MultipleValues);
+        // @TODO @soundness: if doesn't have an equal, but requires equal is ValuesDone?!
         if no_val && min_vals_zero && !has_eq && needs_eq {
             debugln!("Parser::parse_opt: More arg vals not required...");
             return Ok(ParseResult::ValuesDone);
diff --git a/src/app/usage.rs b/src/app/usage.rs
index 07a24ac4..c2f66ea5 100644
--- a/src/app/usage.rs
+++ b/src/app/usage.rs
@@ -96,7 +96,7 @@ impl<'a, 'b, 'c, 'z> Usage<'a, 'b, 'c, 'z> {
         let has_last = positionals!(self.0.app).any(|p| p.is_set(ArgSettings::Last));
         // places a '--' in the usage string if there are args and options
         // supporting multiple values
-        if opts!(self.0.app).any(|o| o.is_set(ArgSettings::Multiple))
+        if opts!(self.0.app).any(|o| o.is_set(ArgSettings::MultipleValues))
             && positionals!(self.0.app).any(|p| !p.is_set(ArgSettings::Required))
             && !(self.0.app.has_visible_subcommands()
                 || self.0.is_set(AS::AllowExternalSubcommands)) && !has_last
diff --git a/src/app/validator.rs b/src/app/validator.rs
index 40101d0b..0b897e56 100644
--- a/src/app/validator.rs
+++ b/src/app/validator.rs
@@ -95,7 +95,7 @@ impl<'a, 'b, 'c, 'z> Validator<'a, 'b, 'c, 'z> {
             if let Some(ref p_vals) = arg.possible_vals {
                 debugln!("Validator::validate_arg_values: possible_vals={:?}", p_vals);
                 let val_str = val.to_string_lossy();
-                let ok = if arg.is_set(ArgSettings::CaseInsensitive) {
+                let ok = if arg.is_set(ArgSettings::IgnoreCase) {
                     p_vals.iter().any(|pv| pv.eq_ignore_ascii_case(&*val_str))
                 } else {
                     p_vals.contains(&&*val_str)
@@ -110,7 +110,7 @@ impl<'a, 'b, 'c, 'z> Validator<'a, 'b, 'c, 'z> {
                     ));
                 }
             }
-            if !arg.is_set(ArgSettings::EmptyValues) && val.is_empty_()
+            if !arg.is_set(ArgSettings::AllowEmptyValues) && val.is_empty_()
                 && matcher.contains(&*arg.name)
             {
                 debugln!("Validator::validate_arg_values: illegal empty val found");
@@ -292,7 +292,7 @@ impl<'a, 'b, 'c, 'z> Validator<'a, 'b, 'c, 'z> {
         matcher: &ArgMatcher<'a>,
     ) -> ClapResult<()> {
         debugln!("Validator::validate_arg_num_occurs: a={};", a.name);
-        if ma.occurs > 1 && !a.is_set(ArgSettings::Multiple) {
+        if ma.occurs > 1 && !a.is_set(ArgSettings::MultipleOccurrences) {
             // Not the first time, and we don't allow multiples
             return Err(Error::unexpected_multiple_usage(
                 a,
@@ -312,7 +312,7 @@ impl<'a, 'b, 'c, 'z> Validator<'a, 'b, 'c, 'z> {
         debugln!("Validator::validate_arg_num_vals;");
         if let Some(num) = a.num_vals {
             debugln!("Validator::validate_arg_num_vals: num_vals set...{}", num);
-            let should_err = if a.is_set(ArgSettings::Multiple) {
+            let should_err = if a.is_set(ArgSettings::MultipleValues) {
                 ((ma.vals.len() as u64) % num) != 0
             } else {
                 num != (ma.vals.len() as u64)
@@ -322,13 +322,14 @@ impl<'a, 'b, 'c, 'z> Validator<'a, 'b, 'c, 'z> {
                 return Err(Error::wrong_number_of_values(
                     a,
                     num,
-                    if a.is_set(ArgSettings::Multiple) {
+                    if a.is_set(ArgSettings::MultipleValues) {
                         (ma.vals.len() % num as usize)
                     } else {
                         ma.vals.len()
                     },
                     if ma.vals.len() == 1
-                        || (a.is_set(ArgSettings::Multiple) && (ma.vals.len() % num as usize) == 1)
+                        || (a.is_set(ArgSettings::MultipleValues)
+                            && (ma.vals.len() % num as usize) == 1)
                     {
                         "as"
                     } else {
diff --git a/src/args/arg.rs b/src/args/arg.rs
index e016f226..506c6312 100644
--- a/src/args/arg.rs
+++ b/src/args/arg.rs
@@ -210,142 +210,6 @@ impl<'a, 'b> Arg<'a, 'b> {
         a
     }
 
-    /// Creates a new instance of [`Arg`] from a usage string. Allows creation of basic settings
-    /// for the [`Arg`]. The syntax is flexible, but there are some rules to follow.
-    ///
-    /// **NOTE**: Not all settings may be set using the usage string method. Some properties are
-    /// only available via the builder pattern.
-    ///
-    /// **NOTE**: Only ASCII values are officially supported in [`Arg::from_usage`] strings. Some
-    /// UTF-8 codepoints may work just fine, but this is not guaranteed.
-    ///
-    /// # Syntax
-    ///
-    /// Usage strings typically following the form:
-    ///
-    /// ```notrust
-    /// [explicit name] [short] [long] [value names] [help string]
-    /// ```
-    ///
-    /// This is not a hard rule as the attributes can appear in other orders. There are also
-    /// several additional sigils which denote additional settings. Below are the details of each
-    /// portion of the string.
-    ///
-    /// ### Explicit Name
-    ///
-    /// This is an optional field, if it's omitted the argument will use one of the additional
-    /// fields as the name using the following priority order:
-    ///
-    ///  * Explicit Name (This always takes precedence when present)
-    ///  * Long
-    ///  * Short
-    ///  * Value Name
-    ///
-    /// `clap` determines explicit names as the first string of characters between either `[]` or
-    /// `<>` where `[]` has the dual notation of meaning the argument is optional, and `<>` meaning
-    /// the argument is required.
-    ///
-    /// Explicit names may be followed by:
-    ///  * The multiple denotation `...`
-    ///
-    /// Example explicit names as follows (`ename` for an optional argument, and `rname` for a
-    /// required argument):
-    ///
-    /// ```notrust
-    /// [ename] -s, --long 'some flag'
-    /// <rname> -r, --longer 'some other flag'
-    /// ```
-    ///
-    /// ### Short
-    ///
-    /// This is set by placing a single character after a leading `-`.
-    ///
-    /// Shorts may be followed by
-    ///  * The multiple denotation `...`
-    ///  * An optional comma `,` which is cosmetic only
-    ///  * Value notation
-    ///
-    /// Example shorts are as follows (`-s`, and `-r`):
-    ///
-    /// ```notrust
-    /// -s, --long 'some flag'
-    /// <rname> -r [val], --longer 'some option'
-    /// ```
-    ///
-    /// ### Long
-    ///
-    /// This is set by placing a word (no spaces) after a leading `--`.
-    ///
-    /// Shorts may be followed by
-    ///  * The multiple denotation `...`
-    ///  * Value notation
-    ///
-    /// Example longs are as follows (`--some`, and `--rapid`):
-    ///
-    /// ```notrust
-    /// -s, --some 'some flag'
-    /// --rapid=[FILE] 'some option'
-    /// ```
-    ///
-    /// ### Values (Value Notation)
-    ///
-    /// This is set by placing a word(s) between `[]` or `<>` optionally after `=` (although this
-    /// is cosmetic only and does not affect functionality). If an explicit name has **not** been
-    /// set, using `<>` will denote a required argument, and `[]` will denote an optional argument
-    ///
-    /// Values may be followed by
-    ///  * The multiple denotation `...`
-    ///  * More Value notation
-    ///
-    /// More than one value will also implicitly set the arguments number of values, i.e. having
-    /// two values, `--option [val1] [val2]` specifies that in order for option to be satisified it
-    /// must receive exactly two values
-    ///
-    /// Example values are as follows (`FILE`, and `SPEED`):
-    ///
-    /// ```notrust
-    /// -s, --some [FILE] 'some option'
-    /// --rapid=<SPEED>... 'some required multiple option'
-    /// ```
-    ///
-    /// ### Help String
-    ///
-    /// The help string is denoted between a pair of single quotes `''` and may contain any
-    /// characters.
-    ///
-    /// Example help strings are as follows:
-    ///
-    /// ```notrust
-    /// -s, --some [FILE] 'some option'
-    /// --rapid=<SPEED>... 'some required multiple option'
-    /// ```
-    ///
-    /// ### Additional Sigils
-    ///
-    /// Multiple notation `...` (three consecutive dots/periods) specifies that this argument may
-    /// be used multiple times. Do not confuse multiple occurrences (`...`) with multiple values.
-    /// `--option val1 val2` is a single occurrence with multiple values. `--flag --flag` is
-    /// multiple occurrences (and then you can obviously have instances of both as well)
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// App::new("prog")
-    ///     .args(&[
-    ///         Arg::from_usage("--config <FILE> 'a required file for the configuration and no short'"),
-    ///         Arg::from_usage("-d, --debug... 'turns on debugging information and allows multiples'"),
-    ///         Arg::from_usage("[input] 'an optional input file to use'")
-    /// ])
-    /// # ;
-    /// ```
-    /// [`Arg`]: ./struct.Arg.html
-    /// [`Arg::from_usage`]: ./struct.Arg.html#method.from_usage
-    pub fn from_usage(u: &'a str) -> Self {
-        let parser = UsageParser::from_usage(u);
-        parser.parse()
-    }
-
     /// Sets the short version of the argument without the preceding `-`.
     ///
     /// By default `clap` automatically assigns `V` and `h` to the auto-generated `version` and
@@ -673,271 +537,6 @@ impl<'a, 'b> Arg<'a, 'b> {
         self
     }
 
-    /// Specifies that this arg is the last, or final, positional argument (i.e. has the highest
-    /// index) and is *only* able to be accessed via the `--` syntax (i.e. `$ prog args --
-    /// last_arg`). Even, if no other arguments are left to parse, if the user omits the `--` syntax
-    /// they will receive an [`UnknownArgument`] error. Setting an argument to `.last(true)` also
-    /// allows one to access this arg early using the `--` syntax. Accessing an arg early, even with
-    /// the `--` syntax is otherwise not possible.
-    ///
-    /// **NOTE:** This will change the usage string to look like `$ prog [FLAGS] [-- <ARG>]` if
-    /// `ARG` is marked as `.last(true)`.
-    ///
-    /// **NOTE:** This setting will imply [`AppSettings::DontCollapseArgsInUsage`] because failing
-    /// to set this can make the usage string very confusing.
-    ///
-    /// **NOTE**: This setting only applies to positional arguments, and has no affect on FLAGS /
-    /// OPTIONS
-    ///
-    /// **CAUTION:** Setting an argument to `.last(true)` *and* having child subcommands is not
-    /// recommended with the exception of *also* using [`AppSettings::ArgsNegateSubcommands`]
-    /// (or [`AppSettings::SubcommandsNegateReqs`] if the argument marked `.last(true)` is also
-    /// marked [`.required(true)`])
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// # use clap::Arg;
-    /// Arg::with_name("args")
-    ///     .last(true)
-    /// # ;
-    /// ```
-    ///
-    /// Setting [`Arg::last(true)`] ensures the arg has the highest [index] of all positional args
-    /// and requires that the `--` syntax be used to access it early.
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// let res = App::new("prog")
-    ///     .arg(Arg::with_name("first"))
-    ///     .arg(Arg::with_name("second"))
-    ///     .arg(Arg::with_name("third").last(true))
-    ///     .get_matches_from_safe(vec![
-    ///         "prog", "one", "--", "three"
-    ///     ]);
-    ///
-    /// assert!(res.is_ok());
-    /// let m = res.unwrap();
-    /// assert_eq!(m.value_of("third"), Some("three"));
-    /// assert!(m.value_of("second").is_none());
-    /// ```
-    ///
-    /// Even if the positional argument marked `.last(true)` is the only argument left to parse,
-    /// failing to use the `--` syntax results in an error.
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg, ErrorKind};
-    /// let res = App::new("prog")
-    ///     .arg(Arg::with_name("first"))
-    ///     .arg(Arg::with_name("second"))
-    ///     .arg(Arg::with_name("third").last(true))
-    ///     .get_matches_from_safe(vec![
-    ///         "prog", "one", "two", "three"
-    ///     ]);
-    ///
-    /// assert!(res.is_err());
-    /// assert_eq!(res.unwrap_err().kind, ErrorKind::UnknownArgument);
-    /// ```
-    /// [`Arg::last(true)`]: ./struct.Arg.html#method.last
-    /// [index]: ./struct.Arg.html#method.index
-    /// [`AppSettings::DontCollapseArgsInUsage`]: ./enum.AppSettings.html#variant.DontCollapseArgsInUsage
-    /// [`AppSettings::ArgsNegateSubcommands`]: ./enum.AppSettings.html#variant.ArgsNegateSubcommands
-    /// [`AppSettings::SubcommandsNegateReqs`]: ./enum.AppSettings.html#variant.SubcommandsNegateReqs
-    /// [`.required(true)`]: ./struct.Arg.html#method.required
-    /// [`UnknownArgument`]: ./enum.ErrorKind.html#variant.UnknownArgument
-    pub fn last(self, l: bool) -> Self {
-        if l {
-            self.set(ArgSettings::Last)
-        } else {
-            self.unset(ArgSettings::Last)
-        }
-    }
-
-    /// Sets whether or not the argument is required by default. Required by default means it is
-    /// required, when no other conflicting rules have been evaluated. Conflicting rules take
-    /// precedence over being required. **Default:** `false`
-    ///
-    /// **NOTE:** Flags (i.e. not positional, or arguments that take values) cannot be required by
-    /// default. This is simply because if a flag should be required, it should simply be implied
-    /// as no additional information is required from user. Flags by their very nature are simply
-    /// yes/no, or true/false.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// # use clap::Arg;
-    /// Arg::with_name("config")
-    ///     .required(true)
-    /// # ;
-    /// ```
-    ///
-    /// Setting [`Arg::required(true)`] requires that the argument be used at runtime.
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// let res = App::new("prog")
-    ///     .arg(Arg::with_name("cfg")
-    ///         .required(true)
-    ///         .takes_value(true)
-    ///         .long("config"))
-    ///     .get_matches_from_safe(vec![
-    ///         "prog", "--config", "file.conf"
-    ///     ]);
-    ///
-    /// assert!(res.is_ok());
-    /// ```
-    ///
-    /// Setting [`Arg::required(true)`] and *not* supplying that argument is an error.
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg, ErrorKind};
-    /// let res = App::new("prog")
-    ///     .arg(Arg::with_name("cfg")
-    ///         .required(true)
-    ///         .takes_value(true)
-    ///         .long("config"))
-    ///     .get_matches_from_safe(vec![
-    ///         "prog"
-    ///     ]);
-    ///
-    /// assert!(res.is_err());
-    /// assert_eq!(res.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
-    /// ```
-    /// [`Arg::required(true)`]: ./struct.Arg.html#method.required
-    pub fn required(self, r: bool) -> Self {
-        if r {
-            self.set(ArgSettings::Required)
-        } else {
-            self.unset(ArgSettings::Required)
-        }
-    }
-
-    /// Requires that options use the `--option=val` syntax (i.e. an equals between the option and
-    /// associated value) **Default:** `false`
-    ///
-    /// **NOTE:** This setting also removes the default of allowing empty values and implies
-    /// [`Arg::empty_values(false)`].
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// # use clap::Arg;
-    /// Arg::with_name("config")
-    ///     .long("config")
-    ///     .takes_value(true)
-    ///     .require_equals(true)
-    /// # ;
-    /// ```
-    ///
-    /// Setting [`Arg::require_equals(true)`] requires that the option have an equals sign between
-    /// it and the associated value.
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// let res = App::new("prog")
-    ///     .arg(Arg::with_name("cfg")
-    ///         .require_equals(true)
-    ///         .takes_value(true)
-    ///         .long("config"))
-    ///     .get_matches_from_safe(vec![
-    ///         "prog", "--config=file.conf"
-    ///     ]);
-    ///
-    /// assert!(res.is_ok());
-    /// ```
-    ///
-    /// Setting [`Arg::require_equals(true)`] and *not* supplying the equals will cause an error
-    /// unless [`Arg::empty_values(true)`] is set.
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg, ErrorKind};
-    /// let res = App::new("prog")
-    ///     .arg(Arg::with_name("cfg")
-    ///         .require_equals(true)
-    ///         .takes_value(true)
-    ///         .long("config"))
-    ///     .get_matches_from_safe(vec![
-    ///         "prog", "--config", "file.conf"
-    ///     ]);
-    ///
-    /// assert!(res.is_err());
-    /// assert_eq!(res.unwrap_err().kind, ErrorKind::EmptyValue);
-    /// ```
-    /// [`Arg::require_equals(true)`]: ./struct.Arg.html#method.require_equals
-    /// [`Arg::empty_values(true)`]: ./struct.Arg.html#method.empty_values
-    /// [`Arg::empty_values(false)`]: ./struct.Arg.html#method.empty_values
-    pub fn require_equals(mut self, r: bool) -> Self {
-        if r {
-            self.unsetb(ArgSettings::EmptyValues);
-            self.set(ArgSettings::RequireEquals)
-        } else {
-            self.unset(ArgSettings::RequireEquals)
-        }
-    }
-
-    /// Allows values which start with a leading hyphen (`-`)
-    ///
-    /// **WARNING**: Take caution when using this setting combined with [`Arg::multiple(true)`], as
-    /// this becomes ambiguous `$ prog --arg -- -- val`. All three `--, --, val` will be values
-    /// when the user may have thought the second `--` would constitute the normal, "Only
-    /// positional args follow" idiom. To fix this, consider using [`Arg::number_of_values(1)`]
-    ///
-    /// **WARNING**: When building your CLIs, consider the effects of allowing leading hyphens and
-    /// the user passing in a value that matches a valid short. For example `prog -opt -F` where
-    /// `-F` is supposed to be a value, yet `-F` is *also* a valid short for another arg. Care should
-    /// should be taken when designing these args. This is compounded by the ability to "stack"
-    /// short args. I.e. if `-val` is supposed to be a value, but `-v`, `-a`, and `-l` are all valid
-    /// shorts.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// # use clap::Arg;
-    /// Arg::with_name("pattern")
-    ///     .allow_hyphen_values(true)
-    /// # ;
-    /// ```
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// let m = App::new("prog")
-    ///     .arg(Arg::with_name("pat")
-    ///         .allow_hyphen_values(true)
-    ///         .takes_value(true)
-    ///         .long("pattern"))
-    ///     .get_matches_from(vec![
-    ///         "prog", "--pattern", "-file"
-    ///     ]);
-    ///
-    /// assert_eq!(m.value_of("pat"), Some("-file"));
-    /// ```
-    ///
-    /// Not setting [`Arg::allow_hyphen_values(true)`] and supplying a value which starts with a
-    /// hyphen is an error.
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg, ErrorKind};
-    /// let res = App::new("prog")
-    ///     .arg(Arg::with_name("pat")
-    ///         .takes_value(true)
-    ///         .long("pattern"))
-    ///     .get_matches_from_safe(vec![
-    ///         "prog", "--pattern", "-file"
-    ///     ]);
-    ///
-    /// assert!(res.is_err());
-    /// assert_eq!(res.unwrap_err().kind, ErrorKind::UnknownArgument);
-    /// ```
-    /// [`Arg::allow_hyphen_values(true)`]: ./struct.Arg.html#method.allow_hyphen_values
-    /// [`Arg::multiple(true)`]: ./struct.Arg.html#method.multiple
-    /// [`Arg::number_of_values(1)`]: ./struct.Arg.html#method.number_of_values
-    pub fn allow_hyphen_values(self, a: bool) -> Self {
-        if a {
-            self.set(ArgSettings::AllowLeadingHyphen)
-        } else {
-            self.unset(ArgSettings::AllowLeadingHyphen)
-        }
-    }
     /// Sets an arg that override this arg's required setting. (i.e. this arg will be required
     /// unless this other argument is present).
     ///
@@ -1768,25 +1367,30 @@ impl<'a, 'b> Arg<'a, 'b> {
         self
     }
 
-    /// Specifies that the argument takes a value at run time.
+    /// Specifies the index of a positional argument **starting at** 1.
     ///
-    /// **NOTE:** values for arguments may be specified in any of the following methods
+    /// **NOTE:** The index refers to position according to **other positional argument**. It does
+    /// not define position in the argument list as a whole.
+    ///
+    /// **NOTE:** If no [`Arg::short`], or [`Arg::long`] have been defined, you can optionally
+    /// leave off the `index` method, and the index will be assigned in order of evaluation.
+    /// Utilizing the `index` method allows for setting indexes out of order
+    ///
+    /// **NOTE:** When utilized with [`Arg::multiple(true)`], only the **last** positional argument
+    /// may be defined as multiple (i.e. with the highest index)
     ///
-    /// * Using a space such as `-o value` or `--option value`
-    /// * Using an equals and no space such as `-o=value` or `--option=value`
-    /// * Use a short and no space such as `-ovalue`
+    /// # Panics
     ///
-    /// **NOTE:** By default, args which allow [multiple values] are delimited by commas, meaning
-    /// `--option=val1,val2,val3` is three values for the `--option` argument. If you wish to
-    /// change the delimiter to another character you can use [`Arg::value_delimiter(char)`],
-    /// alternatively you can turn delimiting values **OFF** by using [`Arg::use_delimiter(false)`]
+    /// Although not in this method directly, [`App`] will [`panic!`] if indexes are skipped (such
+    /// as defining `index(1)` and `index(3)` but not `index(2)`, or a positional argument is
+    /// defined as multiple and is not the highest index
     ///
     /// # Examples
     ///
     /// ```rust
     /// # use clap::{App, Arg};
     /// Arg::with_name("config")
-    ///     .takes_value(true)
+    ///     .index(1)
     /// # ;
     /// ```
     ///
@@ -1794,137 +1398,16 @@ impl<'a, 'b> Arg<'a, 'b> {
     /// # use clap::{App, Arg};
     /// let m = App::new("prog")
     ///     .arg(Arg::with_name("mode")
-    ///         .long("mode")
-    ///         .takes_value(true))
+    ///         .index(1))
+    ///     .arg(Arg::with_name("debug")
+    ///         .long("debug"))
     ///     .get_matches_from(vec![
-    ///         "prog", "--mode", "fast"
+    ///         "prog", "--debug", "fast"
     ///     ]);
     ///
     /// assert!(m.is_present("mode"));
-    /// assert_eq!(m.value_of("mode"), Some("fast"));
-    /// ```
-    /// [`Arg::value_delimiter(char)`]: ./struct.Arg.html#method.value_delimiter
-    /// [`Arg::use_delimiter(false)`]: ./struct.Arg.html#method.use_delimiter
-    /// [multiple values]: ./struct.Arg.html#method.multiple
-    pub fn takes_value(self, tv: bool) -> Self {
-        if tv {
-            self.set(ArgSettings::TakesValue)
-        } else {
-            self.unset(ArgSettings::TakesValue)
-        }
-    }
-
-    /// Specifies if the possible values of an argument should be displayed in the help text or
-    /// not. Defaults to `false` (i.e. show possible values)
-    ///
-    /// This is useful for args with many values, or ones which are explained elsewhere in the
-    /// help text.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// Arg::with_name("config")
-    ///     .hide_possible_values(true)
-    /// # ;
-    /// ```
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// let m = App::new("prog")
-    ///     .arg(Arg::with_name("mode")
-    ///         .long("mode")
-    ///         .possible_values(&["fast", "slow"])
-    ///         .takes_value(true)
-    ///         .hide_possible_values(true));
-    ///
-    /// ```
-    ///
-    /// If we were to run the above program with `--help` the `[values: fast, slow]` portion of
-    /// the help text would be omitted.
-    pub fn hide_possible_values(self, hide: bool) -> Self {
-        if hide {
-            self.set(ArgSettings::HidePossibleValues)
-        } else {
-            self.unset(ArgSettings::HidePossibleValues)
-        }
-    }
-
-    /// Specifies if the default value of an argument should be displayed in the help text or
-    /// not. Defaults to `false` (i.e. show default value)
-    ///
-    /// This is useful when default behavior of an arg is explained elsewhere in the help text.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// Arg::with_name("config")
-    ///     .hide_default_value(true)
-    /// # ;
-    /// ```
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// let m = App::new("connect")
-    ///     .arg(Arg::with_name("host")
-    ///         .long("host")
-    ///         .default_value("localhost")
-    ///         .hide_default_value(true));
-    ///
-    /// ```
-    ///
-    /// If we were to run the above program with `--help` the `[default: localhost]` portion of
-    /// the help text would be omitted.
-    pub fn hide_default_value(self, hide: bool) -> Self {
-        if hide {
-            self.set(ArgSettings::HideDefaultValue)
-        } else {
-            self.unset(ArgSettings::HideDefaultValue)
-        }
-    }
-
-    /// Specifies the index of a positional argument **starting at** 1.
-    ///
-    /// **NOTE:** The index refers to position according to **other positional argument**. It does
-    /// not define position in the argument list as a whole.
-    ///
-    /// **NOTE:** If no [`Arg::short`], or [`Arg::long`] have been defined, you can optionally
-    /// leave off the `index` method, and the index will be assigned in order of evaluation.
-    /// Utilizing the `index` method allows for setting indexes out of order
-    ///
-    /// **NOTE:** When utilized with [`Arg::multiple(true)`], only the **last** positional argument
-    /// may be defined as multiple (i.e. with the highest index)
-    ///
-    /// # Panics
-    ///
-    /// Although not in this method directly, [`App`] will [`panic!`] if indexes are skipped (such
-    /// as defining `index(1)` and `index(3)` but not `index(2)`, or a positional argument is
-    /// defined as multiple and is not the highest index
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// Arg::with_name("config")
-    ///     .index(1)
-    /// # ;
-    /// ```
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// let m = App::new("prog")
-    ///     .arg(Arg::with_name("mode")
-    ///         .index(1))
-    ///     .arg(Arg::with_name("debug")
-    ///         .long("debug"))
-    ///     .get_matches_from(vec![
-    ///         "prog", "--debug", "fast"
-    ///     ]);
-    ///
-    /// assert!(m.is_present("mode"));
-    /// assert_eq!(m.value_of("mode"), Some("fast")); // notice index(1) means "first positional"
-    ///                                               // *not* first argument
+    /// assert_eq!(m.value_of("mode"), Some("fast")); // notice index(1) means "first positional"
+    ///                                               // *not* first argument
     /// ```
     /// [`Arg::short`]: ./struct.Arg.html#method.short
     /// [`Arg::long`]: ./struct.Arg.html#method.long
@@ -1936,204 +1419,6 @@ impl<'a, 'b> Arg<'a, 'b> {
         self
     }
 
-    /// Specifies that the argument may appear more than once. For flags, this results
-    /// in the number of occurrences of the flag being recorded. For example `-ddd` or `-d -d -d`
-    /// would count as three occurrences. For options there is a distinct difference in multiple
-    /// occurrences vs multiple values.
-    ///
-    /// For example, `--opt val1 val2` is one occurrence, but two values. Whereas
-    /// `--opt val1 --opt val2` is two occurrences.
-    ///
-    /// **WARNING:**
-    ///
-    /// Setting `multiple(true)` for an [option] with no other details, allows multiple values
-    /// **and** multiple occurrences because it isn't possible to have more occurrences than values
-    /// for options. Because multiple values are allowed, `--option val1 val2 val3` is perfectly
-    /// valid, be careful when designing a CLI where positional arguments are expected after a
-    /// option which accepts multiple values, as `clap` will continue parsing *values* until it
-    /// reaches the max or specific number of values defined, or another flag or option.
-    ///
-    /// **Pro Tip**:
-    ///
-    /// It's possible to define an option which allows multiple occurrences, but only one value per
-    /// occurrence. To do this use [`Arg::number_of_values(1)`] in coordination with
-    /// [`Arg::multiple(true)`].
-    ///
-    /// **WARNING:**
-    ///
-    /// When using args with `multiple(true)` on [options] or [positionals] (i.e. those args that
-    /// accept values) and [subcommands], one needs to consider the posibility of an argument value
-    /// being the same as a valid subcommand. By default `clap` will parse the argument in question
-    /// as a value *only if* a value is possible at that moment. Otherwise it will be parsed as a
-    /// subcommand. In effect, this means using `multiple(true)` with no additional parameters and
-    /// a possible value that coincides with a subcommand name, the subcommand cannot be called
-    /// unless another argument is passed first.
-    ///
-    /// As an example, consider a CLI with an option `--ui-paths=<paths>...` and subcommand `signer`
-    ///
-    /// The following would be parsed as values to `--ui-paths`.
-    ///
-    /// ```notrust
-    /// $ program --ui-paths path1 path2 signer
-    /// ```
-    ///
-    /// This is because `--ui-paths` accepts multiple values. `clap` will continue parsing values
-    /// until another argument is reached and it knows `--ui-paths` is done.
-    ///
-    /// By adding additional parameters to `--ui-paths` we can solve this issue. Consider adding
-    /// [`Arg::number_of_values(1)`] as discussed above. The following are all valid, and `signer`
-    /// is parsed as both a subcommand and a value in the second case.
-    ///
-    /// ```notrust
-    /// $ program --ui-paths path1 signer
-    /// $ program --ui-paths path1 --ui-paths signer signer
-    /// ```
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// Arg::with_name("debug")
-    ///     .short("d")
-    ///     .multiple(true)
-    /// # ;
-    /// ```
-    /// An example with flags
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// let m = App::new("prog")
-    ///     .arg(Arg::with_name("verbose")
-    ///         .multiple(true)
-    ///         .short("v"))
-    ///     .get_matches_from(vec![
-    ///         "prog", "-v", "-v", "-v"    // note, -vvv would have same result
-    ///     ]);
-    ///
-    /// assert!(m.is_present("verbose"));
-    /// assert_eq!(m.occurrences_of("verbose"), 3);
-    /// ```
-    ///
-    /// An example with options
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// let m = App::new("prog")
-    ///     .arg(Arg::with_name("file")
-    ///         .multiple(true)
-    ///         .takes_value(true)
-    ///         .short("F"))
-    ///     .get_matches_from(vec![
-    ///         "prog", "-F", "file1", "file2", "file3"
-    ///     ]);
-    ///
-    /// assert!(m.is_present("file"));
-    /// assert_eq!(m.occurrences_of("file"), 1); // notice only one occurrence
-    /// let files: Vec<_> = m.values_of("file").unwrap().collect();
-    /// assert_eq!(files, ["file1", "file2", "file3"]);
-    /// ```
-    /// This is functionally equivilant to the example above
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// let m = App::new("prog")
-    ///     .arg(Arg::with_name("file")
-    ///         .multiple(true)
-    ///         .takes_value(true)
-    ///         .short("F"))
-    ///     .get_matches_from(vec![
-    ///         "prog", "-F", "file1", "-F", "file2", "-F", "file3"
-    ///     ]);
-    /// let files: Vec<_> = m.values_of("file").unwrap().collect();
-    /// assert_eq!(files, ["file1", "file2", "file3"]);
-    ///
-    /// assert!(m.is_present("file"));
-    /// assert_eq!(m.occurrences_of("file"), 3); // Notice 3 occurrences
-    /// let files: Vec<_> = m.values_of("file").unwrap().collect();
-    /// assert_eq!(files, ["file1", "file2", "file3"]);
-    /// ```
-    ///
-    /// A common mistake is to define an option which allows multiples, and a positional argument
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// let m = App::new("prog")
-    ///     .arg(Arg::with_name("file")
-    ///         .multiple(true)
-    ///         .takes_value(true)
-    ///         .short("F"))
-    ///     .arg(Arg::with_name("word")
-    ///         .index(1))
-    ///     .get_matches_from(vec![
-    ///         "prog", "-F", "file1", "file2", "file3", "word"
-    ///     ]);
-    ///
-    /// assert!(m.is_present("file"));
-    /// let files: Vec<_> = m.values_of("file").unwrap().collect();
-    /// assert_eq!(files, ["file1", "file2", "file3", "word"]); // wait...what?!
-    /// assert!(!m.is_present("word")); // but we clearly used word!
-    /// ```
-    /// The problem is clap doesn't know when to stop parsing values for "files". This is further
-    /// compounded by if we'd said `word -F file1 file2` it would have worked fine, so it would
-    /// appear to only fail sometimes...not good!
-    ///
-    /// A solution for the example above is to specify that `-F` only accepts one value, but is
-    /// allowed to appear multiple times
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// let m = App::new("prog")
-    ///     .arg(Arg::with_name("file")
-    ///         .multiple(true)
-    ///         .takes_value(true)
-    ///         .number_of_values(1)
-    ///         .short("F"))
-    ///     .arg(Arg::with_name("word")
-    ///         .index(1))
-    ///     .get_matches_from(vec![
-    ///         "prog", "-F", "file1", "-F", "file2", "-F", "file3", "word"
-    ///     ]);
-    ///
-    /// assert!(m.is_present("file"));
-    /// let files: Vec<_> = m.values_of("file").unwrap().collect();
-    /// assert_eq!(files, ["file1", "file2", "file3"]);
-    /// assert!(m.is_present("word"));
-    /// assert_eq!(m.value_of("word"), Some("word"));
-    /// ```
-    /// As a final example, notice if we define [`Arg::number_of_values(1)`] and try to run the
-    /// problem example above, it would have been a runtime error with a pretty message to the
-    /// user :)
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg, ErrorKind};
-    /// let res = App::new("prog")
-    ///     .arg(Arg::with_name("file")
-    ///         .multiple(true)
-    ///         .takes_value(true)
-    ///         .number_of_values(1)
-    ///         .short("F"))
-    ///     .arg(Arg::with_name("word")
-    ///         .index(1))
-    ///     .get_matches_from_safe(vec![
-    ///         "prog", "-F", "file1", "file2", "file3", "word"
-    ///     ]);
-    ///
-    /// assert!(res.is_err());
-    /// assert_eq!(res.unwrap_err().kind, ErrorKind::UnknownArgument);
-    /// ```
-    /// [option]: ./struct.Arg.html#method.takes_value
-    /// [options]: ./struct.Arg.html#method.takes_value
-    /// [subcommands]: ./struct.SubCommand.html
-    /// [positionals]: ./struct.Arg.html#method.index
-    /// [`Arg::number_of_values(1)`]: ./struct.Arg.html#method.number_of_values
-    /// [`Arg::multiple(true)`]: ./struct.Arg.html#method.multiple
-    pub fn multiple(self, multi: bool) -> Self {
-        if multi {
-            self.set(ArgSettings::Multiple)
-        } else {
-            self.unset(ArgSettings::Multiple)
-        }
-    }
 
     /// Specifies a value that *stops* parsing multiple values of a give argument. By default when
     /// one sets [`multiple(true)`] on an argument, clap will continue parsing values for that
@@ -2186,146 +1471,6 @@ impl<'a, 'b> Arg<'a, 'b> {
         self
     }
 
-    /// Specifies that an argument can be matched to all child [`SubCommand`]s.
-    ///
-    /// **NOTE:** Global arguments *only* propagate down, **not** up (to parent commands), however
-    /// their values once a user uses them will be propagated back up to parents. In effect, this
-    /// means one should *define* all global arguments at the top level, however it doesn't matter
-    /// where the user *uses* the global argument.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// Arg::with_name("debug")
-    ///     .short("d")
-    ///     .global(true)
-    /// # ;
-    /// ```
-    ///
-    /// For example, assume an appliction with two subcommands, and you'd like to define a
-    /// `--verbose` flag that can be called on any of the subcommands and parent, but you don't
-    /// want to clutter the source with three duplicate [`Arg`] definitions.
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg, SubCommand};
-    /// let m = App::new("prog")
-    ///     .arg(Arg::with_name("verb")
-    ///         .long("verbose")
-    ///         .short("v")
-    ///         .global(true))
-    ///     .subcommand(SubCommand::with_name("test"))
-    ///     .subcommand(SubCommand::with_name("do-stuff"))
-    ///     .get_matches_from(vec![
-    ///         "prog", "do-stuff", "--verbose"
-    ///     ]);
-    ///
-    /// assert_eq!(m.subcommand_name(), Some("do-stuff"));
-    /// let sub_m = m.subcommand_matches("do-stuff").unwrap();
-    /// assert!(sub_m.is_present("verb"));
-    /// ```
-    /// [`SubCommand`]: ./struct.SubCommand.html
-    /// [required]: ./struct.Arg.html#method.required
-    /// [`ArgMatches`]: ./struct.ArgMatches.html
-    /// [`ArgMatches::is_present("flag")`]: ./struct.ArgMatches.html#method.is_present
-    /// [`Arg`]: ./struct.Arg.html
-    pub fn global(self, g: bool) -> Self {
-        if g {
-            self.set(ArgSettings::Global)
-        } else {
-            self.unset(ArgSettings::Global)
-        }
-    }
-
-    /// Allows an argument to accept explicitly empty values. An empty value must be specified at
-    /// the command line with an explicit `""`, or `''`
-    ///
-    /// **NOTE:** Defaults to `true` (Explicitly empty values are allowed)
-    ///
-    /// **NOTE:** Implicitly sets [`Arg::takes_value(true)`] when set to `false`
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// Arg::with_name("file")
-    ///     .long("file")
-    ///     .empty_values(false)
-    /// # ;
-    /// ```
-    /// The default is to allow empty values, such as `--option ""` would be an empty value. But
-    /// we can change to make empty values become an error.
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg, ErrorKind};
-    /// let res = App::new("prog")
-    ///     .arg(Arg::with_name("cfg")
-    ///         .long("config")
-    ///         .short("v")
-    ///         .empty_values(false))
-    ///     .get_matches_from_safe(vec![
-    ///         "prog", "--config="
-    ///     ]);
-    ///
-    /// assert!(res.is_err());
-    /// assert_eq!(res.unwrap_err().kind, ErrorKind::EmptyValue);
-    /// ```
-    /// [`Arg::takes_value(true)`]: ./struct.Arg.html#method.takes_value
-    pub fn empty_values(mut self, ev: bool) -> Self {
-        if ev {
-            self.set(ArgSettings::EmptyValues)
-        } else {
-            self = self.set(ArgSettings::TakesValue);
-            self.unset(ArgSettings::EmptyValues)
-        }
-    }
-
-    /// Hides an argument from help message output.
-    ///
-    /// **NOTE:** This does **not** hide the argument from usage strings on error
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// Arg::with_name("debug")
-    ///     .hidden(true)
-    /// # ;
-    /// ```
-    /// Setting `hidden(true)` will hide the argument when displaying help text
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// let m = App::new("prog")
-    ///     .arg(Arg::with_name("cfg")
-    ///         .long("config")
-    ///         .hidden(true)
-    ///         .help("Some help text describing the --config arg"))
-    ///     .get_matches_from(vec![
-    ///         "prog", "--help"
-    ///     ]);
-    /// ```
-    ///
-    /// The above example displays
-    ///
-    /// ```notrust
-    /// helptest
-    ///
-    /// USAGE:
-    ///    helptest [FLAGS]
-    ///
-    /// FLAGS:
-    /// -h, --help       Prints help information
-    /// -V, --version    Prints version information
-    /// ```
-    pub fn hidden(self, h: bool) -> Self {
-        if h {
-            self.set(ArgSettings::Hidden)
-        } else {
-            self.unset(ArgSettings::Hidden)
-        }
-    }
-
     /// Specifies a list of possible values for this argument. At runtime, `clap` verifies that
     /// only one of the specified values was used, or fails with an error message.
     ///
@@ -2374,6 +1519,7 @@ impl<'a, 'b> Arg<'a, 'b> {
     /// [options]: ./struct.Arg.html#method.takes_value
     /// [positional arguments]: ./struct.Arg.html#method.index
     pub fn possible_values(mut self, names: &[&'b str]) -> Self {
+        self.setb(ArgSettings::TakesValue);
         if let Some(ref mut vec) = self.possible_vals {
             for s in names {
                 vec.push(s);
@@ -2438,6 +1584,7 @@ impl<'a, 'b> Arg<'a, 'b> {
     /// [options]: ./struct.Arg.html#method.takes_value
     /// [positional arguments]: ./struct.Arg.html#method.index
     pub fn possible_value(mut self, name: &'b str) -> Self {
+        self.setb(ArgSettings::TakesValue);
         if let Some(ref mut vec) = self.possible_vals {
             vec.push(name);
         } else {
@@ -2446,59 +1593,6 @@ impl<'a, 'b> Arg<'a, 'b> {
         self
     }
 
-    /// When used with [`Arg::possible_values`] it allows the argument value to pass validation even if
-    /// the case differs from that of the specified `possible_value`.
-    ///
-    /// **Pro Tip:** Use this setting with [`arg_enum!`]
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// # use std::ascii::AsciiExt;
-    /// let m = App::new("pv")
-    ///     .arg(Arg::with_name("option")
-    ///         .long("--option")
-    ///         .takes_value(true)
-    ///         .possible_value("test123")
-    ///         .case_insensitive(true))
-    ///     .get_matches_from(vec![
-    ///         "pv", "--option", "TeSt123",
-    ///     ]);
-    ///
-    /// assert!(m.value_of("option").unwrap().eq_ignore_ascii_case("test123"));
-    /// ```
-    ///
-    /// This setting also works when multiple values can be defined:
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// let m = App::new("pv")
-    ///     .arg(Arg::with_name("option")
-    ///         .short("-o")
-    ///         .long("--option")
-    ///         .takes_value(true)
-    ///         .possible_value("test123")
-    ///         .possible_value("test321")
-    ///         .multiple(true)
-    ///         .case_insensitive(true))
-    ///     .get_matches_from(vec![
-    ///         "pv", "--option", "TeSt123", "teST123", "tESt321"
-    ///     ]);
-    ///
-    /// let matched_vals = m.values_of("option").unwrap().collect::<Vec<_>>();
-    /// assert_eq!(&*matched_vals, &["TeSt123", "teST123", "tESt321"]);
-    /// ```
-    /// [`Arg::case_insensitive(true)`]: ./struct.Arg.html#method.possible_values
-    /// [`arg_enum!`]: ./macro.arg_enum.html
-    pub fn case_insensitive(self, ci: bool) -> Self {
-        if ci {
-            self.set(ArgSettings::CaseInsensitive)
-        } else {
-            self.unset(ArgSettings::CaseInsensitive)
-        }
-    }
-
     /// Specifies the name of the [`ArgGroup`] the argument belongs to.
     ///
     /// # Examples
@@ -2753,225 +1847,80 @@ impl<'a, 'b> Arg<'a, 'b> {
     ///         .max_values(2)
     ///         .short("F"))
     ///     .get_matches_from_safe(vec![
-    ///         "prog", "-F", "file1", "file2", "file3"
-    ///     ]);
-    ///
-    /// assert!(res.is_err());
-    /// assert_eq!(res.unwrap_err().kind, ErrorKind::TooManyValues);
-    /// ```
-    /// [`Arg::multiple(true)`]: ./struct.Arg.html#method.multiple
-    pub fn max_values(mut self, qty: u64) -> Self {
-        self.setb(ArgSettings::TakesValue);
-        self.max_vals = Some(qty);
-        self
-    }
-
-    /// Specifies the *minimum* number of values for this argument. For example, if you had a
-    /// `-f <file>` argument where you wanted at least 2 'files' you would set
-    /// `.min_values(2)`, and this argument would be satisfied if the user provided, 2 or more
-    /// values.
-    ///
-    /// **NOTE:** This does not implicitly set [`Arg::multiple(true)`]. This is because
-    /// `-o val -o val` is multiple occurrences but a single value and `-o val1 val2` is a single
-    /// occurence with multiple values. For positional arguments this **does** set
-    /// [`Arg::multiple(true)`] because there is no way to determine the difference between multiple
-    /// occurences and multiple values.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// Arg::with_name("file")
-    ///     .short("f")
-    ///     .min_values(3)
-    /// # ;
-    /// ```
-    ///
-    /// Supplying more than the minimum number of values is allowed
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// let res = App::new("prog")
-    ///     .arg(Arg::with_name("file")
-    ///         .takes_value(true)
-    ///         .min_values(2)
-    ///         .short("F"))
-    ///     .get_matches_from_safe(vec![
-    ///         "prog", "-F", "file1", "file2", "file3"
-    ///     ]);
-    ///
-    /// assert!(res.is_ok());
-    /// let m = res.unwrap();
-    /// let files: Vec<_> = m.values_of("file").unwrap().collect();
-    /// assert_eq!(files, ["file1", "file2", "file3"]);
-    /// ```
-    ///
-    /// Supplying less than the minimum number of values is an error
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg, ErrorKind};
-    /// let res = App::new("prog")
-    ///     .arg(Arg::with_name("file")
-    ///         .takes_value(true)
-    ///         .min_values(2)
-    ///         .short("F"))
-    ///     .get_matches_from_safe(vec![
-    ///         "prog", "-F", "file1"
-    ///     ]);
-    ///
-    /// assert!(res.is_err());
-    /// assert_eq!(res.unwrap_err().kind, ErrorKind::TooFewValues);
-    /// ```
-    /// [`Arg::multiple(true)`]: ./struct.Arg.html#method.multiple
-    pub fn min_values(mut self, qty: u64) -> Self {
-        self.min_vals = Some(qty);
-        self.set(ArgSettings::TakesValue)
-    }
-
-    /// Specifies whether or not an argument should allow grouping of multiple values via a
-    /// delimiter. I.e. should `--option=val1,val2,val3` be parsed as three values (`val1`, `val2`,
-    /// and `val3`) or as a single value (`val1,val2,val3`). Defaults to using `,` (comma) as the
-    /// value delimiter for all arguments that accept values (options and positional arguments)
-    ///
-    /// **NOTE:** The default is `false`. When set to `true` the default [`Arg::value_delimiter`]
-    /// is the comma `,`.
-    ///
-    /// # Examples
-    ///
-    /// The following example shows the default behavior.
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// let delims = App::new("prog")
-    ///     .arg(Arg::with_name("option")
-    ///         .long("option")
-    ///         .use_delimiter(true)
-    ///         .takes_value(true))
-    ///     .get_matches_from(vec![
-    ///         "prog", "--option=val1,val2,val3",
-    ///     ]);
-    ///
-    /// assert!(delims.is_present("option"));
-    /// assert_eq!(delims.occurrences_of("option"), 1);
-    /// assert_eq!(delims.values_of("option").unwrap().collect::<Vec<_>>(), ["val1", "val2", "val3"]);
-    /// ```
-    /// The next example shows the difference when turning delimiters off. This is the default
-    /// behavior
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// let nodelims = App::new("prog")
-    ///     .arg(Arg::with_name("option")
-    ///         .long("option")
-    ///         .use_delimiter(false)
-    ///         .takes_value(true))
-    ///     .get_matches_from(vec![
-    ///         "prog", "--option=val1,val2,val3",
-    ///     ]);
-    ///
-    /// assert!(nodelims.is_present("option"));
-    /// assert_eq!(nodelims.occurrences_of("option"), 1);
-    /// assert_eq!(nodelims.value_of("option").unwrap(), "val1,val2,val3");
-    /// ```
-    /// [`Arg::value_delimiter`]: ./struct.Arg.html#method.value_delimiter
-    pub fn use_delimiter(mut self, d: bool) -> Self {
-        if d {
-            if self.val_delim.is_none() {
-                self.val_delim = Some(',');
-            }
-            self.setb(ArgSettings::TakesValue);
-            self.setb(ArgSettings::UseValueDelimiter);
-            self.unset(ArgSettings::ValueDelimiterNotSet)
-        } else {
-            self.val_delim = None;
-            self.unsetb(ArgSettings::UseValueDelimiter);
-            self.unset(ArgSettings::ValueDelimiterNotSet)
-        }
+    ///         "prog", "-F", "file1", "file2", "file3"
+    ///     ]);
+    ///
+    /// assert!(res.is_err());
+    /// assert_eq!(res.unwrap_err().kind, ErrorKind::TooManyValues);
+    /// ```
+    /// [`Arg::multiple(true)`]: ./struct.Arg.html#method.multiple
+    pub fn max_values(mut self, qty: u64) -> Self {
+        self.setb(ArgSettings::TakesValue);
+        self.setb(ArgSettings::MultipleValues);
+        self.max_vals = Some(qty);
+        self
     }
 
-    /// Specifies that *multiple values* may only be set using the delimiter. This means if an
-    /// if an option is encountered, and no delimiter is found, it automatically assumed that no
-    /// additional values for that option follow. This is unlike the default, where it is generally
-    /// assumed that more values will follow regardless of whether or not a delimiter is used.
-    ///
-    /// **NOTE:** The default is `false`.
-    ///
-    /// **NOTE:** Setting this to true implies [`Arg::use_delimiter(true)`]
+    /// Specifies the *minimum* number of values for this argument. For example, if you had a
+    /// `-f <file>` argument where you wanted at least 2 'files' you would set
+    /// `.min_values(2)`, and this argument would be satisfied if the user provided, 2 or more
+    /// values.
     ///
-    /// **NOTE:** It's a good idea to inform the user that use of a delimiter is required, either
-    /// through help text or other means.
+    /// **NOTE:** This does not implicitly set [`Arg::multiple(true)`]. This is because
+    /// `-o val -o val` is multiple occurrences but a single value and `-o val1 val2` is a single
+    /// occurence with multiple values. For positional arguments this **does** set
+    /// [`Arg::multiple(true)`] because there is no way to determine the difference between multiple
+    /// occurences and multiple values.
     ///
     /// # Examples
     ///
-    /// These examples demonstrate what happens when `require_delimiter(true)` is used. Notice
-    /// everything works in this first example, as we use a delimiter, as expected.
-    ///
     /// ```rust
     /// # use clap::{App, Arg};
-    /// let delims = App::new("prog")
-    ///     .arg(Arg::with_name("opt")
-    ///         .short("o")
-    ///         .takes_value(true)
-    ///         .multiple(true)
-    ///         .require_delimiter(true))
-    ///     .get_matches_from(vec![
-    ///         "prog", "-o", "val1,val2,val3",
-    ///     ]);
-    ///
-    /// assert!(delims.is_present("opt"));
-    /// assert_eq!(delims.values_of("opt").unwrap().collect::<Vec<_>>(), ["val1", "val2", "val3"]);
+    /// Arg::with_name("file")
+    ///     .short("f")
+    ///     .min_values(3)
+    /// # ;
     /// ```
-    /// In this next example, we will *not* use a delimiter. Notice it's now an error.
+    ///
+    /// Supplying more than the minimum number of values is allowed
     ///
     /// ```rust
-    /// # use clap::{App, Arg, ErrorKind};
+    /// # use clap::{App, Arg};
     /// let res = App::new("prog")
-    ///     .arg(Arg::with_name("opt")
-    ///         .short("o")
+    ///     .arg(Arg::with_name("file")
     ///         .takes_value(true)
-    ///         .multiple(true)
-    ///         .require_delimiter(true))
+    ///         .min_values(2)
+    ///         .short("F"))
     ///     .get_matches_from_safe(vec![
-    ///         "prog", "-o", "val1", "val2", "val3",
+    ///         "prog", "-F", "file1", "file2", "file3"
     ///     ]);
     ///
-    /// assert!(res.is_err());
-    /// let err = res.unwrap_err();
-    /// assert_eq!(err.kind, ErrorKind::UnknownArgument);
+    /// assert!(res.is_ok());
+    /// let m = res.unwrap();
+    /// let files: Vec<_> = m.values_of("file").unwrap().collect();
+    /// assert_eq!(files, ["file1", "file2", "file3"]);
     /// ```
-    /// What's happening is `-o` is getting `val1`, and because delimiters are required yet none
-    /// were present, it stops parsing `-o`. At this point it reaches `val2` and because no
-    /// positional arguments have been defined, it's an error of an unexpected argument.
     ///
-    /// In this final example, we contrast the above with `clap`'s default behavior where the above
-    /// is *not* an error.
+    /// Supplying less than the minimum number of values is an error
     ///
     /// ```rust
-    /// # use clap::{App, Arg};
-    /// let delims = App::new("prog")
-    ///     .arg(Arg::with_name("opt")
-    ///         .short("o")
+    /// # use clap::{App, Arg, ErrorKind};
+    /// let res = App::new("prog")
+    ///     .arg(Arg::with_name("file")
     ///         .takes_value(true)
-    ///         .multiple(true))
-    ///     .get_matches_from(vec![
-    ///         "prog", "-o", "val1", "val2", "val3",
+    ///         .min_values(2)
+    ///         .short("F"))
+    ///     .get_matches_from_safe(vec![
+    ///         "prog", "-F", "file1"
     ///     ]);
     ///
-    /// assert!(delims.is_present("opt"));
-    /// assert_eq!(delims.values_of("opt").unwrap().collect::<Vec<_>>(), ["val1", "val2", "val3"]);
+    /// assert!(res.is_err());
+    /// assert_eq!(res.unwrap_err().kind, ErrorKind::TooFewValues);
     /// ```
-    /// [`Arg::use_delimiter(true)`]: ./struct.Arg.html#method.use_delimiter
-    pub fn require_delimiter(mut self, d: bool) -> Self {
-        if d {
-            self = self.use_delimiter(true);
-            self.unsetb(ArgSettings::ValueDelimiterNotSet);
-            self.setb(ArgSettings::UseValueDelimiter);
-            self.set(ArgSettings::RequireDelimiter)
-        } else {
-            self = self.use_delimiter(false);
-            self.unsetb(ArgSettings::UseValueDelimiter);
-            self.unset(ArgSettings::RequireDelimiter)
-        }
+    /// [`Arg::multiple(true)`]: ./struct.Arg.html#method.multiple
+    pub fn min_values(mut self, qty: u64) -> Self {
+        self.min_vals = Some(qty);
+        self.setting(ArgSettings::TakesValue)
     }
 
     /// Specifies the separator to use when values are clumped together, defaults to `,` (comma).
@@ -3570,69 +2519,6 @@ impl<'a, 'b> Arg<'a, 'b> {
         self
     }
 
-    /// @TODO @p2 @docs @release: write docs
-    pub fn hide_env_values(self, hide: bool) -> Self {
-        if hide {
-            self.set(ArgSettings::HideEnvValues)
-        } else {
-            self.unset(ArgSettings::HideEnvValues)
-        }
-    }
-
-    /// When set to `true` the help string will be displayed on the line after the argument and
-    /// indented once. This can be helpful for arguments with very long or complex help messages.
-    /// This can also be helpful for arguments with very long flag names, or many/long value names.
-    ///
-    /// **NOTE:** To apply this setting to all arguments consider using
-    /// [`AppSettings::NextLineHelp`]
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// # use clap::{App, Arg};
-    /// let m = App::new("prog")
-    ///     .arg(Arg::with_name("opt")
-    ///         .long("long-option-flag")
-    ///         .short("o")
-    ///         .takes_value(true)
-    ///         .value_names(&["value1", "value2"])
-    ///         .help("Some really long help and complex\n\
-    ///                help that makes more sense to be\n\
-    ///                on a line after the option")
-    ///         .next_line_help(true))
-    ///     .get_matches_from(vec![
-    ///         "prog", "--help"
-    ///     ]);
-    /// ```
-    ///
-    /// The above example displays the following help message
-    ///
-    /// ```notrust
-    /// nlh
-    ///
-    /// USAGE:
-    ///     nlh [FLAGS] [OPTIONS]
-    ///
-    /// FLAGS:
-    ///     -h, --help       Prints help information
-    ///     -V, --version    Prints version information
-    ///
-    /// OPTIONS:
-    ///     -o, --long-option-flag <value1> <value2>
-    ///         Some really long help and complex
-    ///         help that makes more sense to be
-    ///         on a line after the option
-    /// ```
-    /// [`AppSettings::NextLineHelp`]: ./enum.AppSettings.html#variant.NextLineHelp
-    pub fn next_line_help(mut self, nlh: bool) -> Self {
-        if nlh {
-            self.setb(ArgSettings::NextLineHelp);
-        } else {
-            self.unsetb(ArgSettings::NextLineHelp);
-        }
-        self
-    }
-
     /// Allows custom ordering of args within the help message. Args with a lower value will be
     /// displayed first in the help message. This is helpful when one would like to emphasise
     /// frequently used args, or prioritize those towards the top of the list. Duplicate values
@@ -3693,31 +2579,47 @@ impl<'a, 'b> Arg<'a, 'b> {
         self
     }
 
-    /// Checks if one of the [`ArgSettings`] settings is set for the argument
+    // @TODO @docs @v3-beta: write better docs as ArgSettings is now critical
+    /// Checks if one of the [`ArgSettings`] is set for the argument
     /// [`ArgSettings`]: ./enum.ArgSettings.html
     pub fn is_set(&self, s: ArgSettings) -> bool { self.settings.is_set(s) }
 
     /// Sets one of the [`ArgSettings`] settings for the argument
     /// [`ArgSettings`]: ./enum.ArgSettings.html
-    pub fn set(mut self, s: ArgSettings) -> Self {
+    pub fn setting(mut self, s: ArgSettings) -> Self {
         self.setb(s);
         self
     }
 
-    /// Unsets one of the [`ArgSettings`] settings for the argument
+    // @TODO @docs @v3-beta: write better docs as ArgSettings is now critical
+    /// Sets multiple [`ArgSettings`] for the argument
     /// [`ArgSettings`]: ./enum.ArgSettings.html
-    pub fn unset(mut self, s: ArgSettings) -> Self {
+    pub fn settings(mut self, settings: &[ArgSettings]) -> Self {
+        for s in settings {
+            self.settings.set(*s);
+        }
+        self
+    }
+
+    /// Unsets one of the [`ArgSettings`] for the argument
+    /// [`ArgSettings`]: ./enum.ArgSettings.html
+    pub fn unset_setting(mut self, s: ArgSettings) -> Self {
         self.unsetb(s);
         self
     }
 
     #[doc(hidden)]
     pub fn _build(&mut self) {
+        if (self.is_set(ArgSettings::UseValueDelimiter) 
+            || self.is_set(ArgSettings::RequireDelimiter)) && self.val_delim.is_none() {
+            self.val_delim = Some(',');
+        }
         if self.index.is_some() || (self.short.is_none() && self.long.is_none()) {
             if self.max_vals.is_some() || self.min_vals.is_some()
                 || (self.num_vals.is_some() && self.num_vals.unwrap() > 1)
             {
-                self.setb(ArgSettings::Multiple);
+                self.setb(ArgSettings::MultipleValues);
+                self.setb(ArgSettings::MultipleOccurrences);
             }
         } else if self.is_set(ArgSettings::TakesValue) {
             if let Some(ref vec) = self.val_names {
@@ -3728,9 +2630,11 @@ impl<'a, 'b> Arg<'a, 'b> {
         }
     }
 
+    // @TODO @p6 @naming @internal: rename to set_mut
     #[doc(hidden)]
     pub fn setb(&mut self, s: ArgSettings) { self.settings.set(s); }
 
+    // @TODO @p6 @naming @internal: rename to unset_mut
     #[doc(hidden)]
     pub fn unsetb(&mut self, s: ArgSettings) { self.settings.unset(s); }
 
@@ -3748,7 +2652,8 @@ impl<'a, 'b> Arg<'a, 'b> {
         let mult_vals = self.val_names
             .as_ref()
             .map_or(true, |names| names.len() < 2);
-        if self.is_set(ArgSettings::Multiple) && mult_vals {
+        if (self.is_set(ArgSettings::MultipleValues) || self.is_set(ArgSettings::MultipleOccurrences)) 
+            && mult_vals {
             "..."
         } else {
             ""
@@ -3785,6 +2690,212 @@ impl<'a, 'b> Arg<'a, 'b> {
     }
 }
 
+// Deprecations
+// @TODO @v3-beta: remove
+impl<'a, 'b> Arg<'a, 'b> {
+
+    /// **Deprecated**
+    #[deprecated(since="2.30.0", note="Renamed to `Arg::setting`. Will be removed in v3.0-beta")]
+    pub fn set(mut self, s: ArgSettings) -> Self {
+        self.setb(s);
+        self
+    }
+
+    /// **Deprecated**
+    #[deprecated(since="2.30.0", note="Renamed to `Arg::unset_setting`. Will be removed in v3.0-beta")]
+    pub fn unset(mut self, s: ArgSettings) -> Self {
+        self.unsetb(s);
+        self
+    }
+
+
+    /// **Deprecated**
+    #[deprecated(since="2.30.0", note="Use `Arg::from` instead. Will be removed in v3.0-beta")]
+    pub fn from_usage(u: &'a str) -> Self {
+        let parser = UsageParser::from_usage(u);
+        parser.parse()
+    }
+
+    /// **Deprecated**
+    #[deprecated(since="2.30.0", note="Use `Arg::setting(ArgSettings::Last)` instead. Will be removed in v3.0-beta")]
+    pub fn last(self, l: bool) -> Self {
+        if l {
+            self.setting(ArgSettings::Last)
+        } else {
+            self.unset_setting(ArgSettings::Last)
+        }
+    }
+
+    /// **Deprecated**
+    #[deprecated(since="2.30.0", note="Use `Arg::setting(ArgSettings::Required)` instead. Will be removed in v3.0-beta")]
+    pub fn required(self, r: bool) -> Self {
+        if r {
+            self.setting(ArgSettings::Required)
+        } else {
+            self.unset_setting(ArgSettings::Required)
+        }
+    }
+
+    /// **Deprecated**
+    #[deprecated(since="2.30.0", note="Use `Arg::setting(ArgSettings::TakesValue)` instead. Will be removed in v3.0-beta")]
+    pub fn takes_value(self, tv: bool) -> Self {
+        if tv {
+            self.setting(ArgSettings::TakesValue)
+        } else {
+            self.unset_setting(ArgSettings::TakesValue)
+        }
+    }
+
+    /// **Deprecated**
+    #[deprecated(since="2.30.0", note="Use `Arg::setting(ArgSettings::AllowHyphenValues)` instead. Will be removed in v3.0-beta")]
+    pub fn allow_hyphen_values(self, a: bool) -> Self {
+        if a {
+            self.setting(ArgSettings::AllowHyphenValues)
+        } else {
+            self.unset_setting(ArgSettings::AllowHyphenValues)
+        }
+    }
+
+    /// **Deprecated**
+    #[deprecated(since="2.30.0", note="Use `Arg::setting(ArgSettings::RequireEquals)` instead. Will be removed in v3.0-beta")]
+    pub fn require_equals(mut self, r: bool) -> Self {
+        if r {
+            self.unsetb(ArgSettings::AllowEmptyValues);
+            self.setting(ArgSettings::RequireEquals)
+        } else {
+            self.unset_setting(ArgSettings::RequireEquals)
+        }
+    }
+
+    /// **Deprecated**
+    #[deprecated(since="2.30.0", note="Use `Arg::setting(ArgSettings::Global)` instead. Will be removed in v3.0-beta")]
+    pub fn global(self, g: bool) -> Self {
+        if g {
+            self.setting(ArgSettings::Global)
+        } else {
+            self.unset_setting(ArgSettings::Global)
+        }
+    }
+
+    /// **Deprecated**
+    #[deprecated(since="2.30.0", note="Use `Arg::setting(ArgSettings::RequireDelimiter)` instead. Will be removed in v3.0-beta")]
+    pub fn require_delimiter(mut self, d: bool) -> Self {
+        if d {
+            self.setb(ArgSettings::UseValueDelimiter);
+            self.unsetb(ArgSettings::ValueDelimiterNotSet);
+            self.setb(ArgSettings::UseValueDelimiter);
+            self.setting(ArgSettings::RequireDelimiter)
+        } else {
+            self.unsetb(ArgSettings::UseValueDelimiter);
+            self.unsetb(ArgSettings::UseValueDelimiter);
+            self.unset_setting(ArgSettings::RequireDelimiter)
+        }
+    }
+
+    /// **Deprecated**
+    #[deprecated(since="2.30.0", note="Use `Arg::setting(ArgSettings::HidePossibleValues)` instead. Will be removed in v3.0-beta")]
+    pub fn hide_possible_values(self, hide: bool) -> Self {
+        if hide {
+            self.setting(ArgSettings::HidePossibleValues)
+        } else {
+            self.unset_setting(ArgSettings::HidePossibleValues)
+        }
+    }
+
+    /// **Deprecated**
+    #[deprecated(since="2.30.0", note="Use `Arg::setting(ArgSettings::HideDefaultValue)` instead. Will be removed in v3.0-beta")]
+    pub fn hide_default_value(self, hide: bool) -> Self {
+        if hide {
+            self.setting(ArgSettings::HideDefaultValue)
+        } else {
+            self.unset_setting(ArgSettings::HideDefaultValue)
+        }
+    }
+
+    /// **Deprecated**
+    #[deprecated(since="2.30.0", note="Use `Arg::setting(ArgSettings::AllowEmptyValues)` instead. Will be removed in v3.0-beta")]
+    pub fn empty_values(mut self, ev: bool) -> Self {
+        if ev {
+            self.setting(ArgSettings::AllowEmptyValues)
+        } else {
+            self = self.setting(ArgSettings::TakesValue);
+            self.unset_setting(ArgSettings::AllowEmptyValues)
+        }
+    }
+
+    /// **Deprecated**
+    #[deprecated(since="2.30.0", note="Use `Arg::setting(ArgSettings::Hidden)` instead. Will be removed in v3.0-beta")]
+    pub fn hidden(self, h: bool) -> Self {
+        if h {
+            self.setting(ArgSettings::Hidden)
+        } else {
+            self.unset_setting(ArgSettings::Hidden)
+        }
+    }
+
+    /// **Deprecated**
+    #[deprecated(since="2.30.0", note="Use `Arg::setting(ArgSettings::IgnoreCase)` instead. Will be removed in v3.0-beta")]
+    pub fn case_insensitive(self, ci: bool) -> Self {
+        if ci {
+            self.setting(ArgSettings::IgnoreCase)
+        } else {
+            self.unset_setting(ArgSettings::IgnoreCase)
+        }
+    }
+
+    /// **Deprecated**
+    #[deprecated(since="2.30.0", note="Use `Arg::setting(ArgSettings::UseValueDelimiter)` instead. Will be removed in v3.0-beta")]
+    pub fn use_delimiter(mut self, d: bool) -> Self {
+        if d {
+            if self.val_delim.is_none() {
+                self.val_delim = Some(',');
+            }
+            self.setb(ArgSettings::TakesValue);
+            self.setb(ArgSettings::UseValueDelimiter);
+            self.unset_setting(ArgSettings::ValueDelimiterNotSet)
+        } else {
+            self.val_delim = None;
+            self.unsetb(ArgSettings::UseValueDelimiter);
+            self.unset_setting(ArgSettings::ValueDelimiterNotSet)
+        }
+    }
+
+    /// **Deprecated**
+    #[deprecated(since="2.30.0", note="Use `Arg::setting(ArgSettings::HideEnvValues)` instead. Will be removed in v3.0-beta")]
+    pub fn hide_env_values(self, hide: bool) -> Self {
+        if hide {
+            self.setting(ArgSettings::HideEnvValues)
+        } else {
+            self.unset_setting(ArgSettings::HideEnvValues)
+        }
+    }
+
+    /// **Deprecated**
+    #[deprecated(since="2.30.0", note="Use `Arg::setting(ArgSettings::NextLineHelp)` instead. Will be removed in v3.0-beta")]
+    pub fn next_line_help(mut self, nlh: bool) -> Self {
+        if nlh {
+            self.setb(ArgSettings::NextLineHelp);
+        } else {
+            self.unsetb(ArgSettings::NextLineHelp);
+        }
+        self
+    }
+
+    /// **Deprecated**
+    #[deprecated(since="2.30.0", note="Use `Arg::setting(ArgSettings::Multiple)` instead. Also note `ArgSettings::MultipleValues` and `ArgSettings::MultipleOccurrences` have been added which may be more appropriate. Will be removed in v3.0-beta")]
+    pub fn multiple(mut self, multi: bool) -> Self {
+        if multi {
+            self.setb(ArgSettings::MultipleOccurrences);
+            self.setting(ArgSettings::MultipleValues)
+        } else {
+            self.unsetb(ArgSettings::MultipleOccurrences);
+            self.unset_setting(ArgSettings::MultipleValues)
+        }
+    }
+
+
+}
+
 impl<'a, 'b, 'z> From<&'z Arg<'a, 'b>> for Arg<'a, 'b> {
     fn from(a: &'z Arg<'a, 'b>) -> Self { a.clone() }
 }
@@ -3816,7 +2927,7 @@ impl<'n, 'e> Display for Arg<'n, 'e> {
             } else {
                 write!(f, "<{}>", self.name)?;
             }
-            if self.settings.is_set(ArgSettings::Multiple)
+            if self.settings.is_set(ArgSettings::MultipleValues)
                 && (self.val_names.is_none() 
                     || (self.val_names.is_some() 
                         && self.val_names.as_ref().unwrap().len() == 1))
@@ -3861,7 +2972,7 @@ impl<'n, 'e> Display for Arg<'n, 'e> {
                 }
             }
             let num = vec.len();
-            if self.is_set(ArgSettings::Multiple) && num == 1 {
+            if self.is_set(ArgSettings::MultipleValues) && num == 1 {
                 write!(f, "...")?;
             }
         } else if let Some(num) = self.num_vals {
@@ -3872,7 +2983,7 @@ impl<'n, 'e> Display for Arg<'n, 'e> {
                     write!(f, "{}", delim)?;
                 }
             }
-            if self.is_set(ArgSettings::Multiple) && num == 1 {
+            if self.is_set(ArgSettings::MultipleValues) && num == 1 {
                 write!(f, "...")?;
             }
         } else {
@@ -3880,7 +2991,7 @@ impl<'n, 'e> Display for Arg<'n, 'e> {
                 f,
                 "<{}>{}",
                 self.name,
-                if self.is_set(ArgSettings::Multiple) {
+                if self.is_set(ArgSettings::MultipleOccurrences) {
                     "..."
                 } else {
                     ""
@@ -3956,7 +3067,7 @@ mod test {
     #[test]
     fn flag_display() {
         let mut f = Arg::with_name("flg");
-        f.settings.set(ArgSettings::Multiple);
+        f.settings.set(ArgSettings::MultipleOccurrences);
         f.long = Some("flag");
 
         assert_eq!(&*format!("{}", f), "--flag");
@@ -4046,7 +3157,7 @@ mod test {
     #[test]
     fn positiona_display_mult() {
         let mut p = Arg::with_name("pos").index(1);
-        p.settings.set(ArgSettings::Multiple);
+        p.setb(ArgSettings::MultipleValues);
 
         assert_eq!(&*format!("{}", p), "<pos>...");
     }
diff --git a/src/args/arg_matcher.rs b/src/args/arg_matcher.rs
index a189215f..a73205be 100644
--- a/src/args/arg_matcher.rs
+++ b/src/args/arg_matcher.rs
@@ -132,7 +132,7 @@ impl<'a> ArgMatcher<'a> {
         if let Some(ma) = self.get(o.name) {
             if let Some(num) = o.num_vals {
                 debugln!("ArgMatcher::needs_more_vals: num_vals...{}", num);
-                return if o.is_set(ArgSettings::Multiple) {
+                return if o.is_set(ArgSettings::MultipleValues) {
                     ((ma.vals.len() as u64) % num) != 0
                 } else {
                     num != (ma.vals.len() as u64)
@@ -144,7 +144,7 @@ impl<'a> ArgMatcher<'a> {
                 debugln!("ArgMatcher::needs_more_vals: min_vals...true");
                 return true;
             }
-            return o.is_set(ArgSettings::Multiple);
+            return o.is_set(ArgSettings::MultipleValues);
         }
         true
     }
diff --git a/src/args/arg_matches.rs b/src/args/arg_matches.rs
index 653cd170..074311e1 100644
--- a/src/args/arg_matches.rs
+++ b/src/args/arg_matches.rs
@@ -336,11 +336,11 @@ impl<'a> ArgMatches<'a> {
     /// # Examples
     ///
     /// ```rust
-    /// # use clap::{App, Arg};
+    /// # use clap::{App, Arg, ArgSettings};
     /// let m = App::new("myprog")
     ///     .arg(Arg::with_name("debug")
     ///         .short("d")
-    ///         .multiple(true))
+    ///         .setting(ArgSettings::MultipleOccurrences))
     ///     .get_matches_from(vec![
     ///         "myprog", "-d", "-d", "-d"
     ///     ]);
@@ -351,11 +351,11 @@ impl<'a> ArgMatches<'a> {
     /// This next example shows that counts actual uses of the argument, not just `-`'s
     ///
     /// ```rust
-    /// # use clap::{App, Arg};
+    /// # use clap::{App, Arg, ArgSettings};
     /// let m = App::new("myprog")
     ///     .arg(Arg::with_name("debug")
     ///         .short("d")
-    ///         .multiple(true))
+    ///         .setting(ArgSettings::MultipleOccurrences))
     ///     .arg(Arg::with_name("flag")
     ///         .short("f"))
     ///     .get_matches_from(vec![
diff --git a/src/args/settings.rs b/src/args/settings.rs
index 9de94d69..21806f71 100644
--- a/src/args/settings.rs
+++ b/src/args/settings.rs
@@ -6,23 +6,24 @@ use std::str::FromStr;
 bitflags! {
     struct Flags: u32 {
         const REQUIRED         = 1;
-        const MULTIPLE         = 1 << 1;
-        const EMPTY_VALS       = 1 << 2;
+        const MULTIPLE_OCC     = 1 << 1;
+        const EMPTY_VALS       = 1 << 2 | Self::TAKES_VAL.bits;
         const GLOBAL           = 1 << 3;
         const HIDDEN           = 1 << 4;
         const TAKES_VAL        = 1 << 5;
         const USE_DELIM        = 1 << 6;
         const NEXT_LINE_HELP   = 1 << 7;
         const R_UNLESS_ALL     = 1 << 8;
-        const REQ_DELIM        = 1 << 9;
+        const REQ_DELIM        = 1 << 9 | Self::TAKES_VAL.bits | Self::USE_DELIM.bits;
         const DELIM_NOT_SET    = 1 << 10;
-        const HIDE_POS_VALS    = 1 << 11;
-        const ALLOW_TAC_VALS   = 1 << 12;
-        const REQUIRE_EQUALS   = 1 << 13;
-        const LAST             = 1 << 14;
-        const HIDE_DEFAULT_VAL = 1 << 15;
+        const HIDE_POS_VALS    = 1 << 11 | Self::TAKES_VAL.bits;
+        const ALLOW_TAC_VALS   = 1 << 12 | Self::TAKES_VAL.bits;
+        const REQUIRE_EQUALS   = 1 << 13 | Self::TAKES_VAL.bits;
+        const LAST             = 1 << 14 | Self::TAKES_VAL.bits;
+        const HIDE_DEFAULT_VAL = 1 << 15 | Self::TAKES_VAL.bits;
         const CASE_INSENSITIVE = 1 << 16;
         const HIDE_ENV_VALS    = 1 << 17;
+        const MULTIPLE_VALS    = 1 << 18 | Self::TAKES_VAL.bits;
     }
 }
 
@@ -33,10 +34,12 @@ pub struct ArgFlags(Flags);
 impl ArgFlags {
     pub fn new() -> Self { ArgFlags::default() }
 
+    // @TODO @p6 @internal: Reorder alphabetically
     impl_settings!{ArgSettings,
         Required => Flags::REQUIRED,
-        Multiple => Flags::MULTIPLE,
-        EmptyValues => Flags::EMPTY_VALS,
+        MultipleOccurrences => Flags::MULTIPLE_OCC,
+        MultipleValues => Flags::MULTIPLE_VALS,
+        AllowEmptyValues => Flags::EMPTY_VALS,
         Global => Flags::GLOBAL,
         Hidden => Flags::HIDDEN,
         TakesValue => Flags::TAKES_VAL,
@@ -46,17 +49,17 @@ impl ArgFlags {
         RequireDelimiter => Flags::REQ_DELIM,
         ValueDelimiterNotSet => Flags::DELIM_NOT_SET,
         HidePossibleValues => Flags::HIDE_POS_VALS,
-        AllowLeadingHyphen => Flags::ALLOW_TAC_VALS,
+        AllowHyphenValues => Flags::ALLOW_TAC_VALS,
         RequireEquals => Flags::REQUIRE_EQUALS,
         Last => Flags::LAST,
-        CaseInsensitive => Flags::CASE_INSENSITIVE,
+        IgnoreCase => Flags::CASE_INSENSITIVE,
         HideEnvValues => Flags::HIDE_ENV_VALS,
         HideDefaultValue => Flags::HIDE_DEFAULT_VAL
     }
 }
 
 impl Default for ArgFlags {
-    fn default() -> Self { ArgFlags(Flags::EMPTY_VALS | Flags::DELIM_NOT_SET) }
+    fn default() -> Self { ArgFlags(Flags::DELIM_NOT_SET) }
 }
 
 /// Various settings that apply to arguments and may be set, unset, and checked via getter/setter
@@ -66,39 +69,951 @@ impl Default for ArgFlags {
 /// [`Arg::is_set`]: ./struct.Arg.html#method.is_set
 #[derive(Debug, PartialEq, Copy, Clone)]
 pub enum ArgSettings {
-    /// The argument must be used
+    /// Specifies that the argument is required by default. Required by default means it is
+    /// required, when no other conflicting rules or overrides have been evaluated. Conflicting
+    /// rules take precedence over being required.
+    ///
+    /// **Pro tip:** Flags (i.e. not positional, or arguments that take values) shouldn't be
+    /// required by default. This is because if a flag were to be required, it should simply be
+    /// implied. No additional information is required from user. Flags by their very nature are
+    /// simply boolean on/off switches. The only time a user *should* be required to use a flag
+    /// is if the operation is destructive in nature, and the user is essentially proving to you,
+    /// "Yes, I know what I'm doing."
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::{Arg, ArgSettings};
+    /// Arg::with_name("config")
+    ///     .setting(ArgSettings::Required)
+    /// # ;
+    /// ```
+    ///
+    /// Setting [`Required`] requires that the argument be used at runtime.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let res = App::new("prog")
+    ///     .arg(Arg::with_name("cfg")
+    ///         .settings(&[ArgSettings::Required, ArgSettings::TakesValue])
+    ///         .long("config"))
+    ///     .try_get_matches_from(vec![
+    ///         "prog", "--config", "file.conf"
+    ///     ]);
+    ///
+    /// assert!(res.is_ok());
+    /// ```
+    ///
+    /// Not setting [`Required`] and then *not* supplying that argument at runtime is an error.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings, ErrorKind};
+    /// let res = App::new("prog")
+    ///     .arg(Arg::with_name("cfg")
+    ///         .settings(&[ArgSettings::Required, ArgSettings::TakesValue])
+    ///         .long("config"))
+    ///     .try_get_matches_from(vec![
+    ///         "prog"
+    ///     ]);
+    ///
+    /// assert!(res.is_err());
+    /// assert_eq!(res.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
+    /// ```
+    /// [`Required`]: ./enum.ArgSettings.html#variant.Required
     Required,
-    /// The argument may be used multiple times such as `--flag --flag`
-    Multiple,
-    /// The argument allows empty values such as `--option ""`
-    EmptyValues,
-    /// The argument should be propagated down through all child [`SubCommands`]
-    /// [`SubCommand`]: ./struct.SubCommand.html
+    /// Specifies that the argument may have an unknown number of multiple values. Without any other
+    /// settings, this argument may appear only *once*.
+    ///
+    /// For example, `--opt val1 val2` is allowed, but `--opt val1 val2 --opt val3` is not.
+    ///
+    /// **NOTE:** Implicitly sets [`ArgSettings::TakesValue`]
+    ///
+    /// **WARNING:**
+    ///
+    /// Setting `MultipleValues` for an argument that takes a value, but with no other details can
+    /// be dangerous in some circumstances. Because multiple values are allowed,
+    /// `--option val1 val2 val3` is perfectly valid. Be careful when designing a CLI where
+    /// positional arguments are *also* expected as `clap` will continue parsing *values* until one
+    /// of the following happens:
+    ///
+    /// * It reaches the [maximum number of values]
+    /// * It reaches a [specific number of values]
+    /// * It finds another flag or option (i.e. something that starts with a `-`)
+    ///
+    /// **WARNING:**
+    ///
+    /// When using args with `MultipleValues` and [subcommands], one needs to consider the
+    /// posibility of an argument value being the same as a valid subcommand. By default `clap` will
+    /// parse the argument in question as a value *only if* a value is possible at that moment.
+    /// Otherwise it will be parsed as a subcommand. In effect, this means using `MultipleValues` with no
+    /// additional parameters and a value that coincides with a subcommand name, the subcommand
+    /// cannot be called unless another argument is passed between them.
+    ///
+    /// As an example, consider a CLI with an option `--ui-paths=<paths>...` and subcommand `signer`
+    ///
+    /// The following would be parsed as values to `--ui-paths`.
+    ///
+    /// ```notrust
+    /// $ program --ui-paths path1 path2 signer
+    /// ```
+    ///
+    /// This is because `--ui-paths` accepts multiple values. `clap` will continue parsing values
+    /// until another argument is reached and it knows `--ui-paths` is done parsing.
+    ///
+    /// By adding additional parameters to `--ui-paths` we can solve this issue. Consider adding
+    /// [`Arg::number_of_values(1)`] or using *only* [`MultipleOccurrences`]. The following are all
+    /// valid, and `signer` is parsed as a subcommand in the first case, but a value in the second
+    /// case.
+    ///
+    /// ```notrust
+    /// $ program --ui-paths path1 signer
+    /// $ program --ui-paths path1 --ui-paths signer signer
+    /// ```
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// Arg::with_name("debug")
+    ///     .short("d")
+    ///     .setting(ArgSettings::MultipleValues)
+    /// # ;
+    /// ```
+    /// An example with flags
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let m = App::new("prog")
+    ///     .arg(Arg::with_name("verbose")
+    ///         .setting(ArgSettings::MultipleOccurrences)
+    ///         .short("v"))
+    ///     .get_matches_from(vec![
+    ///         "prog", "-v", "-v", "-v"    // note, -vvv would have same result
+    ///     ]);
+    ///
+    /// assert!(m.is_present("verbose"));
+    /// assert_eq!(m.occurrences_of("verbose"), 3);
+    /// ```
+    ///
+    /// An example with options
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let m = App::new("prog")
+    ///     .arg(Arg::with_name("file")
+    ///         .setting(ArgSettings::MultipleValues) // implies TakesValue
+    ///         .short("F"))
+    ///     .get_matches_from(vec![
+    ///         "prog", "-F", "file1", "file2", "file3"
+    ///     ]);
+    ///
+    /// assert!(m.is_present("file"));
+    /// assert_eq!(m.occurrences_of("file"), 1); // notice only one occurrence
+    /// let files: Vec<_> = m.values_of("file").unwrap().collect();
+    /// assert_eq!(files, ["file1", "file2", "file3"]);
+    /// ```
+    /// Although `MultipleVlaues` has been specified, we cannot use the argument more than once.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ErrorKind, ArgSettings};
+    /// let res = App::new("prog")
+    ///     .arg(Arg::with_name("file")
+    ///         .setting(ArgSettings::MultipleValues) // implies TakesValue
+    ///         .short("F"))
+    ///     .try_get_matches_from(vec![
+    ///         "prog", "-F", "file1", "-F", "file2", "-F", "file3"
+    ///     ]);
+    /// assert!(res.is_err());
+    /// assert_eq!(res.unwrap_err().kind, ErrorKind::UnexpectedMultipleUsage)
+    /// ```
+    ///
+    /// A common mistake is to define an option which allows multiple values, and a positional
+    /// argument.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let m = App::new("prog")
+    ///     .arg(Arg::with_name("file")
+    ///         .setting(ArgSettings::MultipleValues) // implies TakesValue
+    ///         .short("F"))
+    ///     .arg(Arg::with_name("word")
+    ///         .index(1))
+    ///     .get_matches_from(vec![
+    ///         "prog", "-F", "file1", "file2", "file3", "word"
+    ///     ]);
+    ///
+    /// assert!(m.is_present("file"));
+    /// let files: Vec<_> = m.values_of("file").unwrap().collect();
+    /// assert_eq!(files, ["file1", "file2", "file3", "word"]); // wait...what?!
+    /// assert!(!m.is_present("word")); // but we clearly used word!
+    /// ```
+    /// The problem is `clap` doesn't know when to stop parsing values for "files". This is further
+    /// compounded by if we'd said `word -F file1 file2` it would have worked fine, so it would
+    /// appear to only fail sometimes...not good!
+    ///
+    /// A solution for the example above is to limit how many values with a [maxium], or [specific]
+    /// number, or to say [`MultipleOccurrences`] is ok, but multiple values is not.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let m = App::new("prog")
+    ///     .arg(Arg::with_name("file")
+    ///         .settings(&[ArgSettings::MultipleOccurrences, ArgSettings::TakesValue])
+    ///         .short("F"))
+    ///     .arg(Arg::with_name("word")
+    ///         .index(1))
+    ///     .get_matches_from(vec![
+    ///         "prog", "-F", "file1", "-F", "file2", "-F", "file3", "word"
+    ///     ]);
+    ///
+    /// assert!(m.is_present("file"));
+    /// let files: Vec<_> = m.values_of("file").unwrap().collect();
+    /// assert_eq!(files, ["file1", "file2", "file3"]);
+    /// assert!(m.is_present("word"));
+    /// assert_eq!(m.value_of("word"), Some("word"));
+    /// ```
+    /// As a final example, let's fix the above error and get a pretty message to the user :)
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ErrorKind, ArgSettings};
+    /// let res = App::new("prog")
+    ///     .arg(Arg::with_name("file")
+    ///         .settings(&[ArgSettings::MultipleOccurrences, ArgSettings::TakesValue])
+    ///         .short("F"))
+    ///     .arg(Arg::with_name("word")
+    ///         .index(1))
+    ///     .try_get_matches_from(vec![
+    ///         "prog", "-F", "file1", "file2", "file3", "word"
+    ///     ]);
+    ///
+    /// assert!(res.is_err());
+    /// assert_eq!(res.unwrap_err().kind, ErrorKind::UnknownArgument);
+    /// ```
+    /// [option]: ./enum.ArgSettings.html#variant.TakesValue
+    /// [options]: ./enum.ArgSettings.html#variant.TakesValue
+    /// [subcommands]: ./struct.App.html#method.subcommand
+    /// [positionals]: ./struct.Arg.html#method.index
+    /// [`Arg::number_of_values(1)`]: ./struct.Arg.html#method.number_of_values
+    /// [`MultipleOccurrences`]: ./enum.ArgSettings.html#variant.MultipleOccurrences
+    /// [`MultipleValues`]: ./enum.ArgSettings.html#variant.MultipleValues
+    /// [maximum number of values]: ./struct.Arg.html#method.max_values
+    /// [specific number of values]: ./struct.Arg.html#method.number_of_values
+    /// [maximum]: ./struct.Arg.html#method.max_values
+    /// [specific]: ./struct.Arg.html#method.number_of_values
+    MultipleValues,
+    /// Specifies that the argument may appear more than once.
+    /// For flags, this results
+    /// in the number of occurrences of the flag being recorded. For example `-ddd` or `-d -d -d`
+    /// would count as three occurrences. For options or arguments that take a value, this
+    /// *does not* affect how many values they can accept. (i.e. only one at a time is allowed)
+    ///
+    /// For example, `--opt val1 --opt val2` is allowed, but `--opt val1 val2` is not.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// Arg::with_name("debug")
+    ///     .short("d")
+    ///     .setting(ArgSettings::MultipleOccurrences)
+    /// # ;
+    /// ```
+    /// An example with flags
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let m = App::new("prog")
+    ///     .arg(Arg::with_name("verbose")
+    ///         .setting(ArgSettings::MultipleOccurrences)
+    ///         .short("v"))
+    ///     .get_matches_from(vec![
+    ///         "prog", "-v", "-v", "-v"    // note, -vvv would have same result
+    ///     ]);
+    ///
+    /// assert!(m.is_present("verbose"));
+    /// assert_eq!(m.occurrences_of("verbose"), 3);
+    /// ```
+    ///
+    /// An example with options
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let m = App::new("prog")
+    ///     .arg(Arg::with_name("file")
+    ///         .settings(&[ArgSettings::MultipleOccurrences, ArgSettings::TakesValue])
+    ///         .short("F"))
+    ///     .get_matches_from(vec![
+    ///         "prog", "-F", "file1", "-F", "file2", "-F", "file3"
+    ///     ]);
+    ///
+    /// assert!(m.is_present("file"));
+    /// assert_eq!(m.occurrences_of("file"), 3);
+    /// let files: Vec<_> = m.values_of("file").unwrap().collect();
+    /// assert_eq!(files, ["file1", "file2", "file3"]);
+    /// ```
+    /// [option]: ./enum.ArgSettings.html#variant.TakesValue
+    /// [options]: ./enum.ArgSettings.html#variant.TakesValue
+    /// [subcommands]: ./struct.App.html#method.subcommand
+    /// [positionals]: ./struct.Arg.html#method.index
+    /// [`Arg::number_of_values(1)`]: ./struct.Arg.html#method.number_of_values
+    /// [`MultipleOccurrences`]: ./enum.ArgSettings.html#variant.MultipleOccurrences
+    /// [`MultipleValues`]: ./enum.ArgSettings.html#variant.MultipleValues
+    /// [maximum number of values]: ./struct.Arg.html#method.max_values
+    /// [specific number of values]: ./struct.Arg.html#method.number_of_values
+    /// [maximum]: ./struct.Arg.html#method.max_values
+    /// [specific]: ./struct.Arg.html#method.number_of_values
+    MultipleOccurrences,
+    /// Allows an argument to accept explicitly empty values. An empty value must be specified at
+    /// the command line with an explicit `""`, `''`, or `--option=`
+    ///
+    /// **NOTE:** By default empty values are *not* allowed
+    ///
+    /// **NOTE:** Implicitly sets [`ArgSettings::TakesValue`]
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// Arg::with_name("file")
+    ///     .long("file")
+    ///     .setting(ArgSettings::AllowEmptyValues)
+    /// # ;
+    /// ```
+    /// The default is to *not* allow empty values.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ErrorKind, ArgSettings};
+    /// let res = App::new("prog")
+    ///     .arg(Arg::with_name("cfg")
+    ///         .long("config")
+    ///         .short("v")
+    ///         .setting(ArgSettings::TakesValue))
+    ///     .try_get_matches_from(vec![
+    ///         "prog", "--config="
+    ///     ]);
+    ///
+    /// assert!(res.is_err());
+    /// assert_eq!(res.unwrap_err().kind, ErrorKind::EmptyValue);
+    /// ```
+    /// By adding this setting, we can allow empty values
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let res = App::new("prog")
+    ///     .arg(Arg::with_name("cfg")
+    ///         .long("config")
+    ///         .short("v")
+    ///         .setting(ArgSettings::AllowEmptyValues)) // implies TakesValue
+    ///     .try_get_matches_from(vec![
+    ///         "prog", "--config="
+    ///     ]);
+    ///
+    /// assert!(res.is_ok());
+    /// assert_eq!(res.unwrap().value_of("config"), None);
+    /// ```
+    /// [`ArgSettings::TakesValue`]: ./enum.ArgSettings.html#variant.TakesValue
+    AllowEmptyValues,
+    /// Specifies that an argument can be matched to all child [`SubCommand`]s.
+    ///
+    /// **NOTE:** Global arguments *only* propagate down, **not** up (to parent commands), however
+    /// their values once a user uses them will be propagated back up to parents. In effect, this
+    /// means one should *define* all global arguments at the top level, however it doesn't matter
+    /// where the user *uses* the global argument.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// Arg::with_name("debug")
+    ///     .short("d")
+    ///     .setting(ArgSettings::Global)
+    /// # ;
+    /// ```
+    ///
+    /// For example, assume an appliction with two subcommands, and you'd like to define a
+    /// `--verbose` flag that can be called on any of the subcommands and parent, but you don't
+    /// want to clutter the source with three duplicate [`Arg`] definitions.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, SubCommand, ArgSettings};
+    /// let m = App::new("prog")
+    ///     .arg(Arg::with_name("verb")
+    ///         .long("verbose")
+    ///         .short("v")
+    ///         .setting(ArgSettings::Global))
+    ///     .subcommand(SubCommand::with_name("test"))
+    ///     .subcommand(SubCommand::with_name("do-stuff"))
+    ///     .get_matches_from(vec![
+    ///         "prog", "do-stuff", "--verbose"
+    ///     ]);
+    ///
+    /// assert_eq!(m.subcommand_name(), Some("do-stuff"));
+    /// let sub_m = m.subcommand_matches("do-stuff").unwrap();
+    /// assert!(sub_m.is_present("verb"));
+    /// ```
+    /// [`SubCommand`]: ./struct.App.html#method.subcommand
+    /// [required]: ./enum.ArgSettings.html#variant.Required
+    /// [`ArgMatches`]: ./struct.ArgMatches.html
+    /// [`ArgMatches::is_present("flag")`]: ./struct.ArgMatches.html#method.is_present
+    /// [`Arg`]: ./struct.Arg.html
     Global,
-    /// The argument should **not** be shown in help text
+    /// Hides an argument from help message output.
+    ///
+    /// **NOTE:** This does **not** hide the argument from usage strings on error
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// Arg::with_name("debug")
+    ///     .setting(ArgSettings::Hidden)
+    /// # ;
+    /// ```
+    /// Setting `Hidden` will hide the argument when displaying help text
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let m = App::new("prog")
+    ///     .arg(Arg::with_name("cfg")
+    ///         .long("config")
+    ///         .setting(ArgSettings::Hidden)
+    ///         .help("Some help text describing the --config arg"))
+    ///     .get_matches_from(vec![
+    ///         "prog", "--help"
+    ///     ]);
+    /// ```
+    ///
+    /// The above example displays
+    ///
+    /// ```notrust
+    /// helptest
+    ///
+    /// USAGE:
+    ///    helptest [FLAGS]
+    ///
+    /// FLAGS:
+    /// -h, --help       Prints help information
+    /// -V, --version    Prints version information
+    /// ```
     Hidden,
-    /// The argument accepts a value, such as `--option <value>`
+    /// Specifies that the argument takes a value at run time.
+    ///
+    /// **NOTE:** values for arguments may be specified in any of the following methods
+    ///
+    /// * Using a space such as `-o value` or `--option value`
+    /// * Using an equals and no space such as `-o=value` or `--option=value`
+    /// * Use a short and no space such as `-ovalue`
+    ///
+    /// **NOTE:** By default, args which allow [multiple values] are delimited by commas, meaning
+    /// `--option=val1,val2,val3` is three values for the `--option` argument. If you wish to
+    /// change the delimiter to another character you can use [`Arg::value_delimiter(char)`],
+    /// alternatively you can turn delimiting values **OFF** by using
+    /// [`Arg::unset_setting(ArgSettings::UseValueDelimiter`]
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// Arg::with_name("config")
+    ///     .setting(ArgSettings::TakesValue)
+    /// # ;
+    /// ```
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let m = App::new("prog")
+    ///     .arg(Arg::with_name("mode")
+    ///         .long("mode")
+    ///         .setting(ArgSettings::TakesValue))
+    ///     .get_matches_from(vec![
+    ///         "prog", "--mode", "fast"
+    ///     ]);
+    ///
+    /// assert!(m.is_present("mode"));
+    /// assert_eq!(m.value_of("mode"), Some("fast"));
+    /// ```
+    /// [`Arg::value_delimiter(char)`]: ./struct.Arg.html#method.value_delimiter
+    /// [`Arg::unset_setting(ArgSettings::UseValueDelimiter`]: ./enum.ArgSettings.html#variant.UseValueDelimiter
+    /// [multiple values]: ./enum.ArgSettings.html#variant.MultipleValues
     TakesValue,
-    /// Determines if the argument allows values to be grouped via a delimter
+    /// Specifies that an argument should allow grouping of multiple values via a
+    /// delimiter. I.e. should `--option=val1,val2,val3` be parsed as three values (`val1`, `val2`,
+    /// and `val3`) or as a single value (`val1,val2,val3`). Defaults to using `,` (comma) as the
+    /// value delimiter for all arguments that accept values (options and positional arguments)
+    ///
+    /// **NOTE:** When this setting is used, it will default [`Arg::value_delimiter`]
+    /// to the comma `,`.
+    ///
+    /// **NOTE:** Implicitly sets [`ArgSettings::TakesValue`]
+    ///
+    /// # Examples
+    ///
+    /// The following example shows the default behavior.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let delims = App::new("prog")
+    ///     .arg(Arg::with_name("option")
+    ///         .long("option")
+    ///         .setting(ArgSettings::UseValueDelimiter)
+    ///         .takes_value(true))
+    ///     .get_matches_from(vec![
+    ///         "prog", "--option=val1,val2,val3",
+    ///     ]);
+    ///
+    /// assert!(delims.is_present("option"));
+    /// assert_eq!(delims.occurrences_of("option"), 1);
+    /// assert_eq!(delims.values_of("option").unwrap().collect::<Vec<_>>(), ["val1", "val2", "val3"]);
+    /// ```
+    /// The next example shows the difference when turning delimiters off. This is the default
+    /// behavior
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let nodelims = App::new("prog")
+    ///     .arg(Arg::with_name("option")
+    ///         .long("option")
+    ///         .setting(ArgSettings::TakesValue))
+    ///     .get_matches_from(vec![
+    ///         "prog", "--option=val1,val2,val3",
+    ///     ]);
+    ///
+    /// assert!(nodelims.is_present("option"));
+    /// assert_eq!(nodelims.occurrences_of("option"), 1);
+    /// assert_eq!(nodelims.value_of("option").unwrap(), "val1,val2,val3");
+    /// ```
+    /// [`Arg::value_delimiter`]: ./struct.Arg.html#method.value_delimiter
     UseValueDelimiter,
-    /// Prints the help text on the line after the argument
+    /// When set to `true` the help string will be displayed on the line after the argument and
+    /// indented once. This can be helpful for arguments with very long or complex help messages.
+    /// This can also be helpful for arguments with very long flag names, or many/long value names.
+    ///
+    /// **NOTE:** To apply this setting to all arguments consider using
+    /// [`AppSettings::NextLineHelp`]
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let m = App::new("prog")
+    ///     .arg(Arg::with_name("opt")
+    ///         .long("long-option-flag")
+    ///         .short("o")
+    ///         .settings(&[ArgSettings::TakesValue, ArgSettings::NextLineHelp])
+    ///         .value_names(&["value1", "value2"])
+    ///         .help("Some really long help and complex\n\
+    ///                help that makes more sense to be\n\
+    ///                on a line after the option"))
+    ///     .get_matches_from(vec![
+    ///         "prog", "--help"
+    ///     ]);
+    /// ```
+    ///
+    /// The above example displays the following help message
+    ///
+    /// ```notrust
+    /// nlh
+    ///
+    /// USAGE:
+    ///     nlh [FLAGS] [OPTIONS]
+    ///
+    /// FLAGS:
+    ///     -h, --help       Prints help information
+    ///     -V, --version    Prints version information
+    ///
+    /// OPTIONS:
+    ///     -o, --long-option-flag <value1> <value2>
+    ///         Some really long help and complex
+    ///         help that makes more sense to be
+    ///         on a line after the option
+    /// ```
+    /// [`AppSettings::NextLineHelp`]: ./enum.AppSettings.html#variant.NextLineHelp
     NextLineHelp,
-    /// Requires the use of a value delimiter for all multiple values
+    /// Specifies that *multiple values* may only be set using the delimiter. This means if an
+    /// if an option is encountered, and no delimiter is found, it automatically assumed that no
+    /// additional values for that option follow. This is unlike the default, where it is generally
+    /// assumed that more values will follow regardless of whether or not a delimiter is used.
+    ///
+    /// **NOTE:** The default is `false`.
+    ///
+    /// **NOTE:** Setting this implies [`ArgSettings::UseValueDelimiter`] and
+    /// [`ArgSettings::TakesValue`]
+    ///
+    /// **NOTE:** It's a good idea to inform the user that use of a delimiter is required, either
+    /// through help text or other means.
+    ///
+    /// # Examples
+    ///
+    /// These examples demonstrate what happens when `require_delimiter(true)` is used. Notice
+    /// everything works in this first example, as we use a delimiter, as expected.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let delims = App::new("prog")
+    ///     .arg(Arg::with_name("opt")
+    ///         .short("o")
+    ///         .settings(&[ArgSettings::RequireDelimiter, ArgSettings::MultipleValues]))
+    ///     .get_matches_from(vec![
+    ///         "prog", "-o", "val1,val2,val3",
+    ///     ]);
+    ///
+    /// assert!(delims.is_present("opt"));
+    /// assert_eq!(delims.values_of("opt").unwrap().collect::<Vec<_>>(), ["val1", "val2", "val3"]);
+    /// ```
+    /// In this next example, we will *not* use a delimiter. Notice it's now an error.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ErrorKind, ArgSettings};
+    /// let res = App::new("prog")
+    ///     .arg(Arg::with_name("opt")
+    ///         .short("o")
+    ///         .setting(ArgSettings::RequireDelimiter))
+    ///     .try_get_matches_from(vec![
+    ///         "prog", "-o", "val1", "val2", "val3",
+    ///     ]);
+    ///
+    /// assert!(res.is_err());
+    /// let err = res.unwrap_err();
+    /// assert_eq!(err.kind, ErrorKind::UnknownArgument);
+    /// ```
+    /// What's happening is `-o` is getting `val1`, and because delimiters are required yet none
+    /// were present, it stops parsing `-o`. At this point it reaches `val2` and because no
+    /// positional arguments have been defined, it's an error of an unexpected argument.
+    ///
+    /// In this final example, we contrast the above with `clap`'s default behavior where the above
+    /// is *not* an error.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let delims = App::new("prog")
+    ///     .arg(Arg::with_name("opt")
+    ///         .short("o")
+    ///         .setting(ArgSettings::MultipleValues))
+    ///     .get_matches_from(vec![
+    ///         "prog", "-o", "val1", "val2", "val3",
+    ///     ]);
+    ///
+    /// assert!(delims.is_present("opt"));
+    /// assert_eq!(delims.values_of("opt").unwrap().collect::<Vec<_>>(), ["val1", "val2", "val3"]);
+    /// ```
+    /// [`ArgSettings::UseValueDelimiter`]: ./enum.ArgSettings.html#variant.UseValueDelimiter
+    /// [`ArgSettings::TakesValue`]: ./enum.ArgSettings.html#variant.TakesValue
     RequireDelimiter,
-    /// Hides the possible values from the help string
+    /// Specifies if the possible values of an argument should be displayed in the help text or
+    /// not. Defaults to `false` (i.e. show possible values)
+    ///
+    /// This is useful for args with many values, or ones which are explained elsewhere in the
+    /// help text.
+    ///
+    /// **NOTE:** Setting this implies [`ArgSettings::TakesValue`]
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// Arg::with_name("config")
+    ///     .setting(ArgSettings::HidePossibleValues)
+    /// # ;
+    /// ```
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let m = App::new("prog")
+    ///     .arg(Arg::with_name("mode")
+    ///         .long("mode")
+    ///         .possible_values(&["fast", "slow"])
+    ///         .setting(ArgSettings::HidePossibleValues));
+    /// ```
+    /// If we were to run the above program with `--help` the `[values: fast, slow]` portion of
+    /// the help text would be omitted.
     HidePossibleValues,
-    /// Allows vals that start with a '-'
-    AllowLeadingHyphen,
-    /// Require options use `--option=val` syntax
+    /// Allows values which start with a leading hyphen (`-`)
+    ///
+    /// **NOTE:** Setting this implies [`ArgSettings::TakesValue`]
+    ///
+    /// **WARNING**: Take caution when using this setting combined with
+    /// [`ArgSettings::MultipleValues`], as this becomes ambiguous `$ prog --arg -- -- val`. All
+    /// three `--, --, val` will be values when the user may have thought the second `--` would
+    /// constitute the normal, "Only positional args follow" idiom. To fix this, consider using
+    /// [`ArgSettings::MultipleOccurrences`] which only allows a single value at a time.
+    ///
+    /// **WARNING**: When building your CLIs, consider the effects of allowing leading hyphens and
+    /// the user passing in a value that matches a valid short. For example `prog -opt -F` where
+    /// `-F` is supposed to be a value, yet `-F` is *also* a valid short for another arg. Care should
+    /// should be taken when designing these args. This is compounded by the ability to "stack"
+    /// short args. I.e. if `-val` is supposed to be a value, but `-v`, `-a`, and `-l` are all valid
+    /// shorts.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::{Arg, ArgSettings};
+    /// Arg::with_name("pattern")
+    ///     .setting(ArgSettings::AllowHyphenValues)
+    /// # ;
+    /// ```
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let m = App::new("prog")
+    ///     .arg(Arg::with_name("pat")
+    ///         .setting(ArgSettings::AllowHyphenValues)
+    ///         .long("pattern"))
+    ///     .get_matches_from(vec![
+    ///         "prog", "--pattern", "-file"
+    ///     ]);
+    ///
+    /// assert_eq!(m.value_of("pat"), Some("-file"));
+    /// ```
+    ///
+    /// Not setting [`Arg::allow_hyphen_values(true)`] and supplying a value which starts with a
+    /// hyphen is an error.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ErrorKind, ArgSettings};
+    /// let res = App::new("prog")
+    ///     .arg(Arg::with_name("pat")
+    ///         .setting(ArgSettings::TakesValue)
+    ///         .long("pattern"))
+    ///     .try_get_matches_from(vec![
+    ///         "prog", "--pattern", "-file"
+    ///     ]);
+    ///
+    /// assert!(res.is_err());
+    /// assert_eq!(res.unwrap_err().kind, ErrorKind::UnknownArgument);
+    /// ```
+    /// [`ArgSettings::AllowHyphenValues`]: ./enum.ArgSettings.html#variant.AllowHyphenValues
+    /// [`ArgSettings::MultipleValues`]: ./enum.ArgSettings.html#variant.MultipleValues
+    /// [`ArgSettings::MultipleOccurrences`]: ./enum.ArgSettings.html#variant.MultipleOccurrences
+    /// [`Arg::number_of_values(1)`]: ./struct.Arg.html#method.number_of_values
+    AllowHyphenValues,
+    /// Requires that options use the `--option=val` syntax (i.e. an equals between the option and
+    /// associated value) **Default:** `false`
+    ///
+    /// **NOTE:** Setting this implies [`ArgSettings::TakesValue`]
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::{Arg, ArgSettings};
+    /// Arg::with_name("config")
+    ///     .long("config")
+    ///     .setting(ArgSettings::RequireEquals)
+    /// # ;
+    /// ```
+    ///
+    /// Setting [`RequireEquals`] requires that the option have an equals sign between
+    /// it and the associated value.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let res = App::new("prog")
+    ///     .arg(Arg::with_name("cfg")
+    ///         .setting(ArgSettings::RequireEquals)
+    ///         .long("config"))
+    ///     .try_get_matches_from(vec![
+    ///         "prog", "--config=file.conf"
+    ///     ]);
+    ///
+    /// assert!(res.is_ok());
+    /// ```
+    ///
+    /// Setting [`RequireEquals`] and *not* supplying the equals will cause an error
+    /// unless [`ArgSettings::EmptyValues`] is set.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ErrorKind, ArgSettings};
+    /// let res = App::new("prog")
+    ///     .arg(Arg::with_name("cfg")
+    ///         .setting(ArgSettings::RequireEquals)
+    ///         .long("config"))
+    ///     .try_get_matches_from(vec![
+    ///         "prog", "--config", "file.conf"
+    ///     ]);
+    ///
+    /// assert!(res.is_err());
+    /// assert_eq!(res.unwrap_err().kind, ErrorKind::EmptyValue);
+    /// ```
+    /// [`RequireEquals`]: ./enum.ArgSettings.html#variant.RequireEquals
+    /// [`ArgSettings::EmptyValues`]: ./enum.ArgSettings.html#variant.EmptyValues
+    /// [`ArgSettings::EmptyValues`]: ./enum.ArgSettings.html#variant.TakesValue
     RequireEquals,
-    /// Specifies that the arg is the last positional argument and may be accessed early via `--`
-    /// syntax
+    /// Specifies that this arg is the last, or final, positional argument (i.e. has the highest
+    /// index) and is *only* able to be accessed via the `--` syntax (i.e. `$ prog args --
+    /// last_arg`). Even, if no other arguments are left to parse, if the user omits the `--` syntax
+    /// they will receive an [`UnknownArgument`] error. Setting an argument to `.last(true)` also
+    /// allows one to access this arg early using the `--` syntax. Accessing an arg early, even with
+    /// the `--` syntax is otherwise not possible.
+    ///
+    /// **NOTE:** This will change the usage string to look like `$ prog [FLAGS] [-- <ARG>]` if
+    /// `ARG` is marked as `.last(true)`.
+    ///
+    /// **NOTE:** This setting will imply [`AppSettings::DontCollapseArgsInUsage`] because failing
+    /// to set this can make the usage string very confusing.
+    ///
+    /// **NOTE**: This setting only applies to positional arguments, and has no affect on FLAGS /
+    /// OPTIONS
+    ///
+    /// **NOTE:** Setting this implies [`ArgSettings::TakesValue`]
+    ///
+    /// **CAUTION:** Using this setting *and* having child subcommands is not
+    /// recommended with the exception of *also* using [`AppSettings::ArgsNegateSubcommands`]
+    /// (or [`AppSettings::SubcommandsNegateReqs`] if the argument marked `Last` is also
+    /// marked [`ArgSettings::Required`])
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::{Arg, ArgSettings};
+    /// Arg::with_name("args")
+    ///     .setting(ArgSettings::Last)
+    /// # ;
+    /// ```
+    ///
+    /// Setting [`Last`] ensures the arg has the highest [index] of all positional args
+    /// and requires that the `--` syntax be used to access it early.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let res = App::new("prog")
+    ///     .arg(Arg::with_name("first"))
+    ///     .arg(Arg::with_name("second"))
+    ///     .arg(Arg::with_name("third")
+    ///         .setting(ArgSettings::Last))
+    ///     .try_get_matches_from(vec![
+    ///         "prog", "one", "--", "three"
+    ///     ]);
+    ///
+    /// assert!(res.is_ok());
+    /// let m = res.unwrap();
+    /// assert_eq!(m.value_of("third"), Some("three"));
+    /// assert!(m.value_of("second").is_none());
+    /// ```
+    ///
+    /// Even if the positional argument marked `Last` is the only argument left to parse,
+    /// failing to use the `--` syntax results in an error.
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ErrorKind, ArgSettings};
+    /// let res = App::new("prog")
+    ///     .arg(Arg::with_name("first"))
+    ///     .arg(Arg::with_name("second"))
+    ///     .arg(Arg::with_name("third")
+    ///         .setting(ArgSettings::Last))
+    ///     .try_get_matches_from(vec![
+    ///         "prog", "one", "two", "three"
+    ///     ]);
+    ///
+    /// assert!(res.is_err());
+    /// assert_eq!(res.unwrap_err().kind, ErrorKind::UnknownArgument);
+    /// ```
+    /// [index]: ./struct.Arg.html#method.index
+    /// [`AppSettings::DontCollapseArgsInUsage`]: ./enum.AppSettings.html#variant.DontCollapseArgsInUsage
+    /// [`AppSettings::ArgsNegateSubcommands`]: ./enum.AppSettings.html#variant.ArgsNegateSubcommands
+    /// [`AppSettings::SubcommandsNegateReqs`]: ./enum.AppSettings.html#variant.SubcommandsNegateReqs
+    /// [`ArgSettings::Required`]: ./enum.ArgSetings.html#variant.Required
+    /// [`UnknownArgument`]: ./enum.ErrorKind.html#variant.UnknownArgument
     Last,
-    /// Hides the default value from the help string
+    /// Specifies that the default value of an argument should not be displayed in the help text.
+    ///
+    /// This is useful when default behavior of an arg is explained elsewhere in the help text.
+    ///
+    /// **NOTE:** Setting this implies [`ArgSettings::TakesValue`]
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// Arg::with_name("config")
+    ///     .setting(ArgSettings::HideDefaultValue)
+    /// # ;
+    /// ```
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let m = App::new("connect")
+    ///     .arg(Arg::with_name("host")
+    ///         .long("host")
+    ///         .default_value("localhost")
+    ///         .setting(ArgSettings::HideDefaultValue));
+    ///
+    /// ```
+    ///
+    /// If we were to run the above program with `--help` the `[default: localhost]` portion of
+    /// the help text would be omitted.
     HideDefaultValue,
-    /// Makes `Arg::possible_values` case insensitive
-    CaseInsensitive,
-    /// Hides ENV values in the help message
+    /// When used with [`Arg::possible_values`] it allows the argument value to pass validation even
+    /// if the case differs from that of the specified `possible_value`.
+    ///
+    /// **Pro Tip:** Use this setting with [`arg_enum!`]
+    ///
+    /// **NOTE:** Setting this implies [`ArgSettings::TakesValue`]
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// # use std::ascii::AsciiExt;
+    /// let m = App::new("pv")
+    ///     .arg(Arg::with_name("option")
+    ///         .long("--option")
+    ///         .setting(ArgSettings::IgnoreCase)
+    ///         .possible_value("test123"))
+    ///     .get_matches_from(vec![
+    ///         "pv", "--option", "TeSt123",
+    ///     ]);
+    ///
+    /// assert!(m.value_of("option").unwrap().eq_ignore_ascii_case("test123"));
+    /// ```
+    ///
+    /// This setting also works when multiple values can be defined:
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let m = App::new("pv")
+    ///     .arg(Arg::with_name("option")
+    ///         .short("-o")
+    ///         .long("--option")
+    ///         .settings(&[ArgSettings::IgnoreCase, ArgSettings::MultipleValues])
+    ///         .possible_value("test123")
+    ///         .possible_value("test321"))
+    ///     .get_matches_from(vec![
+    ///         "pv", "--option", "TeSt123", "teST123", "tESt321"
+    ///     ]);
+    ///
+    /// let matched_vals = m.values_of("option").unwrap().collect::<Vec<_>>();
+    /// assert_eq!(&*matched_vals, &["TeSt123", "teST123", "tESt321"]);
+    /// ```
+    /// [`arg_enum!`]: ./macro.arg_enum.html
+    IgnoreCase,
+    /// Specifies that any values inside the associated ENV variables of an argument should not be
+    /// displayed in the help text.
+    ///
+    /// This is useful when ENV vars contain sensitive values.
+    ///
+    /// **NOTE:** Setting this implies [`ArgSettings::TakesValue`]
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// Arg::with_name("config")
+    ///     .setting(ArgSettings::HideDefaultValue)
+    /// # ;
+    /// ```
+    ///
+    /// ```rust
+    /// # use clap::{App, Arg, ArgSettings};
+    /// let m = App::new("connect")
+    ///     .arg(Arg::with_name("host")
+    ///         .long("host")
+    ///         .env("CONNECT")
+    ///         .setting(ArgSettings::HideEnvValues));
+    ///
+    /// ```
+    ///
+    /// If we were to run the above program with `$ CONNECT=super_secret connect --help` the
+    /// `[default: CONNECT=super_secret]` portion of the help text would be omitted.
     HideEnvValues,
     #[doc(hidden)] RequiredUnlessAll,
     #[doc(hidden)] ValueDelimiterNotSet,
@@ -109,9 +1024,8 @@ impl FromStr for ArgSettings {
     fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
         match &*s.to_ascii_lowercase() {
             "required" => Ok(ArgSettings::Required),
-            "multiple" => Ok(ArgSettings::Multiple),
             "global" => Ok(ArgSettings::Global),
-            "emptyvalues" => Ok(ArgSettings::EmptyValues),
+            "allowemptyvalues" => Ok(ArgSettings::AllowEmptyValues),
             "hidden" => Ok(ArgSettings::Hidden),
             "takesvalue" => Ok(ArgSettings::TakesValue),
             "usevaluedelimiter" => Ok(ArgSettings::UseValueDelimiter),
@@ -120,11 +1034,11 @@ impl FromStr for ArgSettings {
             "requiredelimiter" => Ok(ArgSettings::RequireDelimiter),
             "valuedelimiternotset" => Ok(ArgSettings::ValueDelimiterNotSet),
             "hidepossiblevalues" => Ok(ArgSettings::HidePossibleValues),
-            "allowleadinghyphen" => Ok(ArgSettings::AllowLeadingHyphen),
+            "allowhyphenvalues" => Ok(ArgSettings::AllowHyphenValues),
             "requireequals" => Ok(ArgSettings::RequireEquals),
             "last" => Ok(ArgSettings::Last),
             "hidedefaultvalue" => Ok(ArgSettings::HideDefaultValue),
-            "caseinsensitive" => Ok(ArgSettings::CaseInsensitive),
+            "ignorecase" => Ok(ArgSettings::IgnoreCase),
             "hideenvvalues" => Ok(ArgSettings::HideEnvValues),
             _ => Err("unknown ArgSetting, cannot convert from str".to_owned()),
         }
@@ -138,12 +1052,12 @@ mod test {
     #[test]
     fn arg_settings_fromstr() {
         assert_eq!(
-            "allowleadinghyphen".parse::<ArgSettings>().unwrap(),
-            ArgSettings::AllowLeadingHyphen
+            "allowhyphenvalues".parse::<ArgSettings>().unwrap(),
+            ArgSettings::AllowHyphenValues
         );
         assert_eq!(
-            "emptyvalues".parse::<ArgSettings>().unwrap(),
-            ArgSettings::EmptyValues
+            "allowemptyvalues".parse::<ArgSettings>().unwrap(),
+            ArgSettings::AllowEmptyValues
         );
         assert_eq!(
             "global".parse::<ArgSettings>().unwrap(),
@@ -157,10 +1071,6 @@ mod test {
             "hidden".parse::<ArgSettings>().unwrap(),
             ArgSettings::Hidden
         );
-        assert_eq!(
-            "multiple".parse::<ArgSettings>().unwrap(),
-            ArgSettings::Multiple
-        );
         assert_eq!(
             "nextlinehelp".parse::<ArgSettings>().unwrap(),
             ArgSettings::NextLineHelp
@@ -199,8 +1109,8 @@ mod test {
             ArgSettings::HideDefaultValue
         );
         assert_eq!(
-            "caseinsensitive".parse::<ArgSettings>().unwrap(),
-            ArgSettings::CaseInsensitive
+            "ignorecase".parse::<ArgSettings>().unwrap(),
+            ArgSettings::IgnoreCase
         );
         assert_eq!(
             "hideenvvalues".parse::<ArgSettings>().unwrap(),
diff --git a/src/completions/bash.rs b/src/completions/bash.rs
index 6d83ac26..0eca9cf8 100644
--- a/src/completions/bash.rs
+++ b/src/completions/bash.rs
@@ -179,7 +179,9 @@ complete -F _{name} -o bashdefault -o default {name}
                 );
             }
             let num = vec.len();
-            if o.is_set(ArgSettings::Multiple) && num == 1 {
+            if (o.is_set(ArgSettings::MultipleValues) || o.is_set(ArgSettings::MultipleOccurrences))
+                && num == 1
+            {
                 ret = format!("{}...", ret);
             }
         } else if let Some(num) = o.num_vals {
@@ -192,12 +194,14 @@ complete -F _{name} -o bashdefault -o default {name}
                     if it.peek().is_some() { " " } else { "" }
                 );
             }
-            if o.is_set(ArgSettings::Multiple) && num == 1 {
+            if (o.is_set(ArgSettings::MultipleValues) || o.is_set(ArgSettings::MultipleOccurrences))
+                && num == 1
+            {
                 ret = format!("{}...", ret);
             }
         } else {
             ret = format!("<{}>", o.name);
-            if o.is_set(ArgSettings::Multiple) {
+            if o.is_set(ArgSettings::MultipleValues) || o.is_set(ArgSettings::MultipleOccurrences) {
                 ret = format!("{}...", ret);
             }
         }
diff --git a/src/completions/zsh.rs b/src/completions/zsh.rs
index a97f9760..89e13e1d 100644
--- a/src/completions/zsh.rs
+++ b/src/completions/zsh.rs
@@ -346,7 +346,11 @@ fn write_opts_of(p: &App) -> String {
             format!("({})", conflicts)
         };
 
-        let multiple = if o.is_set(ArgSettings::Multiple) {
+        // @TODO @soundness should probably be either multiple occurrences or multiple values and
+        // not both
+        let multiple = if o.is_set(ArgSettings::MultipleOccurrences)
+            || o.is_set(ArgSettings::MultipleValues)
+        {
             "*"
         } else {
             ""
@@ -407,7 +411,7 @@ fn write_flags_of(p: &App) -> String {
             format!("({})", conflicts)
         };
 
-        let multiple = if f.is_set(ArgSettings::Multiple) {
+        let multiple = if f.is_set(ArgSettings::MultipleOccurrences) {
             "*"
         } else {
             ""
diff --git a/src/errors.rs b/src/errors.rs
index 89c9dc23..51e14ea9 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -108,12 +108,12 @@ pub enum ErrorKind {
     /// # Examples
     ///
     /// ```rust
-    /// # use clap::{App, Arg, ErrorKind};
+    /// # use clap::{App, Arg, ErrorKind, ArgSettings};
     /// let res = App::new("prog")
     ///     .arg(Arg::with_name("color")
-    ///          .long("color")
-    ///          .empty_values(false))
-    ///     .get_matches_from_safe(vec!["prog", "--color="]);
+    ///          .setting(ArgSettings::TakesValue)
+    ///          .long("color"))
+    ///     .try_get_matches_from(vec!["prog", "--color="]);
     /// assert!(res.is_err());
     /// assert_eq!(res.unwrap_err().kind, ErrorKind::EmptyValue);
     /// ```
@@ -136,7 +136,7 @@ pub enum ErrorKind {
     /// let result = App::new("prog")
     ///     .arg(Arg::with_name("num")
     ///          .validator(is_numeric))
-    ///     .get_matches_from_safe(vec!["prog", "NotANumber"]);
+    ///     .try_get_matches_from(vec!["prog", "NotANumber"]);
     /// assert!(result.is_err());
     /// assert_eq!(result.unwrap_err().kind, ErrorKind::ValueValidation);
     /// ```
@@ -153,7 +153,7 @@ pub enum ErrorKind {
     ///     .arg(Arg::with_name("arg")
     ///         .multiple(true)
     ///         .max_values(2))
-    ///     .get_matches_from_safe(vec!["prog", "too", "many", "values"]);
+    ///     .try_get_matches_from(vec!["prog", "too", "many", "values"]);
     /// assert!(result.is_err());
     /// assert_eq!(result.unwrap_err().kind, ErrorKind::TooManyValues);
     /// ```
@@ -171,7 +171,7 @@ pub enum ErrorKind {
     ///     .arg(Arg::with_name("some_opt")
     ///         .long("opt")
     ///         .min_values(3))
-    ///     .get_matches_from_safe(vec!["prog", "--opt", "too", "few"]);
+    ///     .try_get_matches_from(vec!["prog", "--opt", "too", "few"]);
     /// assert!(result.is_err());
     /// assert_eq!(result.unwrap_err().kind, ErrorKind::TooFewValues);
     /// ```
@@ -191,7 +191,7 @@ pub enum ErrorKind {
     ///         .long("opt")
     ///         .takes_value(true)
     ///         .number_of_values(2))
-    ///     .get_matches_from_safe(vec!["prog", "--opt", "wrong"]);
+    ///     .try_get_matches_from(vec!["prog", "--opt", "wrong"]);
     /// assert!(result.is_err());
     /// assert_eq!(result.unwrap_err().kind, ErrorKind::WrongNumberOfValues);
     /// ```
@@ -213,7 +213,7 @@ pub enum ErrorKind {
     ///         .conflicts_with("color"))
     ///     .arg(Arg::with_name("color")
     ///         .long("color"))
-    ///     .get_matches_from_safe(vec!["prog", "--debug", "--color"]);
+    ///     .try_get_matches_from(vec!["prog", "--debug", "--color"]);
     /// assert!(result.is_err());
     /// assert_eq!(result.unwrap_err().kind, ErrorKind::ArgumentConflict);
     /// ```
diff --git a/src/lib.rs b/src/lib.rs
index ef340e66..88314ce5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -516,6 +516,8 @@
 #![doc(html_root_url = "https://docs.rs/clap/2.29.2")]
 #![deny(missing_docs, missing_debug_implementations, missing_copy_implementations, trivial_casts,
         unused_import_braces, unused_allocation)]
+// @TODO @v3-beta: remove me!
+#![allow(deprecated)]
 // Lints we'd like to deny but are currently failing for upstream crates
 //      unused_qualifications       (bitflags, clippy)
 //      trivial_numeric_casts       (bitflags)
diff --git a/src/usage_parser.rs b/src/usage_parser.rs
index 1f5dfd97..31e5958e 100644
--- a/src/usage_parser.rs
+++ b/src/usage_parser.rs
@@ -61,17 +61,14 @@ impl<'a> UsageParser<'a> {
                 break;
             }
         }
-        debug_assert!(
-            !arg.name.is_empty(),
-            format!(
-                "No name found for Arg when parsing usage string: {}",
-                self.usage
-            )
-        );
         arg.num_vals = match arg.val_names {
             Some(ref v) if v.len() >= 2 => Some(v.len() as u64),
             _ => None,
         };
+        if !arg.has_switch() && arg.is_set(ArgSettings::MultipleOccurrences) {
+            // We had a positional and need to set mult vals too
+            arg.setb(ArgSettings::MultipleValues);
+        }
         debugln!("UsageParser::parse: vals...{:?}", arg.val_names);
         arg
     }
@@ -177,14 +174,10 @@ impl<'a> UsageParser<'a> {
             self.pos += 1;
             if dot_counter == 3 {
                 debugln!("UsageParser::multiple: setting multiple");
-                arg.setb(ArgSettings::Multiple);
                 if arg.is_set(ArgSettings::TakesValue) {
-                    arg.setb(ArgSettings::UseValueDelimiter);
-                    arg.unsetb(ArgSettings::ValueDelimiterNotSet);
-                    if arg.val_delim.is_none() {
-                        arg.val_delim = Some(',');
-                    }
+                    arg.setb(ArgSettings::MultipleValues);
                 }
+                arg.setb(ArgSettings::MultipleOccurrences);
                 self.prev = UsageToken::Multiple;
                 self.pos += 1;
                 break;
@@ -233,111 +226,111 @@ mod test {
         assert_eq!(a.short.unwrap(), 'f');
         assert!(a.long.is_none());
         assert_eq!(a.help.unwrap(), "some help info");
-        assert!(!a.is_set(ArgSettings::Multiple));
+        assert!(!a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(a.val_names.is_none());
+        assert!(a.num_vals.is_none());
+
+        let a = Arg::from_usage("[flag] --flag 'some help info'");
+        assert_eq!(a.name, "flag");
+        assert_eq!(a.long.unwrap(), "flag");
+        assert!(a.short.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(!a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(a.val_names.is_none());
+        assert!(a.num_vals.is_none());
+
+        let a = Arg::from_usage("--flag 'some help info'");
+        assert_eq!(a.name, "flag");
+        assert_eq!(a.long.unwrap(), "flag");
+        assert!(a.short.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(!a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(a.val_names.is_none());
+        assert!(a.num_vals.is_none());
+
+        let a = Arg::from_usage("[flag] -f --flag 'some help info'");
+        assert_eq!(a.name, "flag");
+        assert_eq!(a.short.unwrap(), 'f');
+        assert_eq!(a.long.unwrap(), "flag");
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(!a.is_set(ArgSettings::MultipleOccurrences));
         assert!(a.val_names.is_none());
         assert!(a.num_vals.is_none());
 
-        let b = Arg::from_usage("[flag] --flag 'some help info'");
-        assert_eq!(b.name, "flag");
-        assert_eq!(b.long.unwrap(), "flag");
-        assert!(b.short.is_none());
-        assert_eq!(b.help.unwrap(), "some help info");
-        assert!(!b.is_set(ArgSettings::Multiple));
+        let a = Arg::from_usage("[flag] -f... 'some help info'");
+        assert_eq!(a.name, "flag");
+        assert_eq!(a.short.unwrap(), 'f');
+        assert!(a.long.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
         assert!(a.val_names.is_none());
         assert!(a.num_vals.is_none());
 
-        let b = Arg::from_usage("--flag 'some help info'");
-        assert_eq!(b.name, "flag");
-        assert_eq!(b.long.unwrap(), "flag");
-        assert!(b.short.is_none());
-        assert_eq!(b.help.unwrap(), "some help info");
-        assert!(!b.is_set(ArgSettings::Multiple));
-        assert!(b.val_names.is_none());
-        assert!(b.num_vals.is_none());
-
-        let c = Arg::from_usage("[flag] -f --flag 'some help info'");
-        assert_eq!(c.name, "flag");
-        assert_eq!(c.short.unwrap(), 'f');
-        assert_eq!(c.long.unwrap(), "flag");
-        assert_eq!(c.help.unwrap(), "some help info");
-        assert!(!c.is_set(ArgSettings::Multiple));
-        assert!(c.val_names.is_none());
-        assert!(c.num_vals.is_none());
-
-        let d = Arg::from_usage("[flag] -f... 'some help info'");
-        assert_eq!(d.name, "flag");
-        assert_eq!(d.short.unwrap(), 'f');
-        assert!(d.long.is_none());
-        assert_eq!(d.help.unwrap(), "some help info");
-        assert!(d.is_set(ArgSettings::Multiple));
-        assert!(d.val_names.is_none());
-        assert!(d.num_vals.is_none());
-
-        let e = Arg::from_usage("[flag] -f --flag... 'some help info'");
-        assert_eq!(e.name, "flag");
-        assert_eq!(e.long.unwrap(), "flag");
-        assert_eq!(e.short.unwrap(), 'f');
-        assert_eq!(e.help.unwrap(), "some help info");
-        assert!(e.is_set(ArgSettings::Multiple));
-        assert!(e.val_names.is_none());
-        assert!(e.num_vals.is_none());
-
-        let e = Arg::from_usage("-f --flag... 'some help info'");
-        assert_eq!(e.name, "flag");
-        assert_eq!(e.long.unwrap(), "flag");
-        assert_eq!(e.short.unwrap(), 'f');
-        assert_eq!(e.help.unwrap(), "some help info");
-        assert!(e.is_set(ArgSettings::Multiple));
-        assert!(e.val_names.is_none());
-        assert!(e.num_vals.is_none());
-
-        let e = Arg::from_usage("--flags");
-        assert_eq!(e.name, "flags");
-        assert_eq!(e.long.unwrap(), "flags");
-        assert!(e.val_names.is_none());
-        assert!(e.num_vals.is_none());
-
-        let e = Arg::from_usage("--flags...");
-        assert_eq!(e.name, "flags");
-        assert_eq!(e.long.unwrap(), "flags");
-        assert!(e.is_set(ArgSettings::Multiple));
-        assert!(e.val_names.is_none());
-        assert!(e.num_vals.is_none());
-
-        let e = Arg::from_usage("[flags] -f");
-        assert_eq!(e.name, "flags");
-        assert_eq!(e.short.unwrap(), 'f');
-        assert!(e.val_names.is_none());
-        assert!(e.num_vals.is_none());
-
-        let e = Arg::from_usage("[flags] -f...");
-        assert_eq!(e.name, "flags");
-        assert_eq!(e.short.unwrap(), 'f');
-        assert!(e.is_set(ArgSettings::Multiple));
-        assert!(e.val_names.is_none());
-        assert!(e.num_vals.is_none());
+        let a = Arg::from_usage("[flag] -f --flag... 'some help info'");
+        assert_eq!(a.name, "flag");
+        assert_eq!(a.long.unwrap(), "flag");
+        assert_eq!(a.short.unwrap(), 'f');
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(a.val_names.is_none());
+        assert!(a.num_vals.is_none());
+
+        let a = Arg::from_usage("-f --flag... 'some help info'");
+        assert_eq!(a.name, "flag");
+        assert_eq!(a.long.unwrap(), "flag");
+        assert_eq!(a.short.unwrap(), 'f');
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(a.val_names.is_none());
+        assert!(a.num_vals.is_none());
+
+        let a = Arg::from_usage("--flags");
+        assert_eq!(a.name, "flags");
+        assert_eq!(a.long.unwrap(), "flags");
+        assert!(a.val_names.is_none());
+        assert!(a.num_vals.is_none());
+
+        let a = Arg::from_usage("--flags...");
+        assert_eq!(a.name, "flags");
+        assert_eq!(a.long.unwrap(), "flags");
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(a.val_names.is_none());
+        assert!(a.num_vals.is_none());
+
+        let a = Arg::from_usage("[flags] -f");
+        assert_eq!(a.name, "flags");
+        assert_eq!(a.short.unwrap(), 'f');
+        assert!(a.val_names.is_none());
+        assert!(a.num_vals.is_none());
+
+        let a = Arg::from_usage("[flags] -f...");
+        assert_eq!(a.name, "flags");
+        assert_eq!(a.short.unwrap(), 'f');
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(a.val_names.is_none());
+        assert!(a.num_vals.is_none());
 
         let a = Arg::from_usage("-f 'some help info'");
         assert_eq!(a.name, "f");
         assert_eq!(a.short.unwrap(), 'f');
         assert!(a.long.is_none());
         assert_eq!(a.help.unwrap(), "some help info");
-        assert!(!a.is_set(ArgSettings::Multiple));
+        assert!(!a.is_set(ArgSettings::MultipleOccurrences));
         assert!(a.val_names.is_none());
         assert!(a.num_vals.is_none());
 
-        let e = Arg::from_usage("-f");
-        assert_eq!(e.name, "f");
-        assert_eq!(e.short.unwrap(), 'f');
-        assert!(e.val_names.is_none());
-        assert!(e.num_vals.is_none());
+        let a = Arg::from_usage("-f");
+        assert_eq!(a.name, "f");
+        assert_eq!(a.short.unwrap(), 'f');
+        assert!(a.val_names.is_none());
+        assert!(a.num_vals.is_none());
 
-        let e = Arg::from_usage("-f...");
-        assert_eq!(e.name, "f");
-        assert_eq!(e.short.unwrap(), 'f');
-        assert!(e.is_set(ArgSettings::Multiple));
-        assert!(e.val_names.is_none());
-        assert!(e.num_vals.is_none());
+        let a = Arg::from_usage("-f...");
+        assert_eq!(a.name, "f");
+        assert_eq!(a.short.unwrap(), 'f');
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(a.val_names.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
@@ -348,7 +341,8 @@ mod test {
         assert_eq!(a.short.unwrap(), 'o');
         assert!(a.long.is_none());
         assert_eq!(a.help.unwrap(), "some help info");
-        assert!(!a.is_set(ArgSettings::Multiple));
+        assert!(!a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(!a.is_set(ArgSettings::MultipleValues));
         assert!(a.is_set(ArgSettings::TakesValue));
         assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
@@ -357,44 +351,47 @@ mod test {
 
     #[test]
     fn create_option_usage1() {
-        let b = Arg::from_usage("-o [opt] 'some help info'");
-        assert_eq!(b.name, "o");
-        assert_eq!(b.short.unwrap(), 'o');
-        assert!(b.long.is_none());
-        assert_eq!(b.help.unwrap(), "some help info");
-        assert!(!b.is_set(ArgSettings::Multiple));
-        assert!(b.is_set(ArgSettings::TakesValue));
-        assert!(!b.is_set(ArgSettings::Required));
-        assert_eq!(b.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
-        assert!(b.num_vals.is_none());
+        let a = Arg::from_usage("-o [opt] 'some help info'");
+        assert_eq!(a.name, "o");
+        assert_eq!(a.short.unwrap(), 'o');
+        assert!(a.long.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(!a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(!a.is_set(ArgSettings::MultipleValues));
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(!a.is_set(ArgSettings::Required));
+        assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage2() {
-        let c = Arg::from_usage("<option> -o <opt> 'some help info'");
-        assert_eq!(c.name, "option");
-        assert_eq!(c.short.unwrap(), 'o');
-        assert!(c.long.is_none());
-        assert_eq!(c.help.unwrap(), "some help info");
-        assert!(!c.is_set(ArgSettings::Multiple));
-        assert!(c.is_set(ArgSettings::TakesValue));
-        assert!(c.is_set(ArgSettings::Required));
-        assert_eq!(c.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
-        assert!(c.num_vals.is_none());
+        let a = Arg::from_usage("<option> -o <opt> 'some help info'");
+        assert_eq!(a.name, "option");
+        assert_eq!(a.short.unwrap(), 'o');
+        assert!(a.long.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(!a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(!a.is_set(ArgSettings::MultipleValues));
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
+        assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage3() {
-        let d = Arg::from_usage("-o <opt> 'some help info'");
-        assert_eq!(d.name, "o");
-        assert_eq!(d.short.unwrap(), 'o');
-        assert!(d.long.is_none());
-        assert_eq!(d.help.unwrap(), "some help info");
-        assert!(!d.is_set(ArgSettings::Multiple));
-        assert!(d.is_set(ArgSettings::TakesValue));
-        assert!(d.is_set(ArgSettings::Required));
-        assert_eq!(d.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
-        assert!(d.num_vals.is_none());
+        let a = Arg::from_usage("-o <opt> 'some help info'");
+        assert_eq!(a.name, "o");
+        assert_eq!(a.short.unwrap(), 'o');
+        assert!(a.long.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(!a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(!a.is_set(ArgSettings::MultipleValues));
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
+        assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
@@ -404,7 +401,8 @@ mod test {
         assert_eq!(a.short.unwrap(), 'o');
         assert!(a.long.is_none());
         assert_eq!(a.help.unwrap(), "some help info");
-        assert!(a.is_set(ArgSettings::Multiple));
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(a.is_set(ArgSettings::MultipleValues));
         assert!(a.is_set(ArgSettings::TakesValue));
         assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
@@ -418,7 +416,7 @@ mod test {
         assert_eq!(a.short.unwrap(), 'o');
         assert!(a.long.is_none());
         assert_eq!(a.help.unwrap(), "some help info");
-        assert!(a.is_set(ArgSettings::Multiple));
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
         assert!(a.is_set(ArgSettings::TakesValue));
         assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
@@ -427,58 +425,61 @@ mod test {
 
     #[test]
     fn create_option_usage6() {
-        let b = Arg::from_usage("-o [opt]... 'some help info'");
-        assert_eq!(b.name, "o");
-        assert_eq!(b.short.unwrap(), 'o');
-        assert!(b.long.is_none());
-        assert_eq!(b.help.unwrap(), "some help info");
-        assert!(b.is_set(ArgSettings::Multiple));
-        assert!(b.is_set(ArgSettings::TakesValue));
-        assert!(!b.is_set(ArgSettings::Required));
-        assert_eq!(b.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
-        assert!(b.num_vals.is_none());
+        let a = Arg::from_usage("-o [opt]... 'some help info'");
+        assert_eq!(a.name, "o");
+        assert_eq!(a.short.unwrap(), 'o');
+        assert!(a.long.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(a.is_set(ArgSettings::MultipleValues));
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(!a.is_set(ArgSettings::Required));
+        assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage7() {
-        let c = Arg::from_usage("<option> -o <opt>... 'some help info'");
-        assert_eq!(c.name, "option");
-        assert_eq!(c.short.unwrap(), 'o');
-        assert!(c.long.is_none());
-        assert_eq!(c.help.unwrap(), "some help info");
-        assert!(c.is_set(ArgSettings::Multiple));
-        assert!(c.is_set(ArgSettings::TakesValue));
-        assert!(c.is_set(ArgSettings::Required));
-        assert_eq!(c.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
-        assert!(c.num_vals.is_none());
+        let a = Arg::from_usage("<option> -o <opt>... 'some help info'");
+        assert_eq!(a.name, "option");
+        assert_eq!(a.short.unwrap(), 'o');
+        assert!(a.long.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(a.is_set(ArgSettings::MultipleValues));
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
+        assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage8() {
-        let c = Arg::from_usage("<option>... -o <opt> 'some help info'");
-        assert_eq!(c.name, "option");
-        assert_eq!(c.short.unwrap(), 'o');
-        assert!(c.long.is_none());
-        assert_eq!(c.help.unwrap(), "some help info");
-        assert!(c.is_set(ArgSettings::Multiple));
-        assert!(c.is_set(ArgSettings::TakesValue));
-        assert!(c.is_set(ArgSettings::Required));
-        assert_eq!(c.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
-        assert!(c.num_vals.is_none());
+        let a = Arg::from_usage("<option>... -o <opt> 'some help info'");
+        assert_eq!(a.name, "option");
+        assert_eq!(a.short.unwrap(), 'o');
+        assert!(a.long.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
+        assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage9() {
-        let d = Arg::from_usage("-o <opt>... 'some help info'");
-        assert_eq!(d.name, "o");
-        assert_eq!(d.short.unwrap(), 'o');
-        assert!(d.long.is_none());
-        assert_eq!(d.help.unwrap(), "some help info");
-        assert!(d.is_set(ArgSettings::Multiple));
-        assert!(d.is_set(ArgSettings::TakesValue));
-        assert!(d.is_set(ArgSettings::Required));
-        assert_eq!(d.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
-        assert!(d.num_vals.is_none());
+        let a = Arg::from_usage("-o <opt>... 'some help info'");
+        assert_eq!(a.name, "o");
+        assert_eq!(a.short.unwrap(), 'o');
+        assert!(a.long.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(a.is_set(ArgSettings::MultipleValues));
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
+        assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
@@ -488,7 +489,8 @@ mod test {
         assert_eq!(a.long.unwrap(), "opt");
         assert!(a.short.is_none());
         assert_eq!(a.help.unwrap(), "some help info");
-        assert!(!a.is_set(ArgSettings::Multiple));
+        assert!(!a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(!a.is_set(ArgSettings::MultipleValues));
         assert!(a.is_set(ArgSettings::TakesValue));
         assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
@@ -497,50 +499,53 @@ mod test {
 
     #[test]
     fn create_option_usage_long2() {
-        let b = Arg::from_usage("--opt [option] 'some help info'");
-        assert_eq!(b.name, "opt");
-        assert_eq!(b.long.unwrap(), "opt");
-        assert!(b.short.is_none());
-        assert_eq!(b.help.unwrap(), "some help info");
-        assert!(!b.is_set(ArgSettings::Multiple));
-        assert!(b.is_set(ArgSettings::TakesValue));
-        assert!(!b.is_set(ArgSettings::Required));
+        let a = Arg::from_usage("--opt [option] 'some help info'");
+        assert_eq!(a.name, "opt");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert!(a.short.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(!a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(!a.is_set(ArgSettings::MultipleValues));
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(
-            b.val_names.unwrap().values().collect::<Vec<_>>(),
+            a.val_names.unwrap().values().collect::<Vec<_>>(),
             [&"option"]
         );
-        assert!(b.num_vals.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage_long3() {
-        let c = Arg::from_usage("<option> --opt <opt> 'some help info'");
-        assert_eq!(c.name, "option");
-        assert_eq!(c.long.unwrap(), "opt");
-        assert!(c.short.is_none());
-        assert_eq!(c.help.unwrap(), "some help info");
-        assert!(!c.is_set(ArgSettings::Multiple));
-        assert!(c.is_set(ArgSettings::TakesValue));
-        assert!(c.is_set(ArgSettings::Required));
-        assert_eq!(c.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
-        assert!(c.num_vals.is_none());
+        let a = Arg::from_usage("<option> --opt <opt> 'some help info'");
+        assert_eq!(a.name, "option");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert!(a.short.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(!a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(!a.is_set(ArgSettings::MultipleValues));
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
+        assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage_long4() {
-        let d = Arg::from_usage("--opt <option> 'some help info'");
-        assert_eq!(d.name, "opt");
-        assert_eq!(d.long.unwrap(), "opt");
-        assert!(d.short.is_none());
-        assert_eq!(d.help.unwrap(), "some help info");
-        assert!(!d.is_set(ArgSettings::Multiple));
-        assert!(d.is_set(ArgSettings::TakesValue));
-        assert!(d.is_set(ArgSettings::Required));
+        let a = Arg::from_usage("--opt <option> 'some help info'");
+        assert_eq!(a.name, "opt");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert!(a.short.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(!a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(!a.is_set(ArgSettings::MultipleValues));
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
         assert_eq!(
-            d.val_names.unwrap().values().collect::<Vec<_>>(),
+            a.val_names.unwrap().values().collect::<Vec<_>>(),
             [&"option"]
         );
-        assert!(d.num_vals.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
@@ -550,7 +555,8 @@ mod test {
         assert_eq!(a.long.unwrap(), "opt");
         assert!(a.short.is_none());
         assert_eq!(a.help.unwrap(), "some help info");
-        assert!(a.is_set(ArgSettings::Multiple));
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(a.is_set(ArgSettings::MultipleValues));
         assert!(a.is_set(ArgSettings::TakesValue));
         assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
@@ -564,7 +570,7 @@ mod test {
         assert_eq!(a.long.unwrap(), "opt");
         assert!(a.short.is_none());
         assert_eq!(a.help.unwrap(), "some help info");
-        assert!(a.is_set(ArgSettings::Multiple));
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
         assert!(a.is_set(ArgSettings::TakesValue));
         assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
@@ -573,64 +579,68 @@ mod test {
 
     #[test]
     fn create_option_usage_long7() {
-        let b = Arg::from_usage("--opt [option]... 'some help info'");
-        assert_eq!(b.name, "opt");
-        assert_eq!(b.long.unwrap(), "opt");
-        assert!(b.short.is_none());
-        assert_eq!(b.help.unwrap(), "some help info");
-        assert!(b.is_set(ArgSettings::Multiple));
-        assert!(b.is_set(ArgSettings::TakesValue));
-        assert!(!b.is_set(ArgSettings::Required));
+        let a = Arg::from_usage("--opt [option]... 'some help info'");
+        assert_eq!(a.name, "opt");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert!(a.short.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(a.is_set(ArgSettings::MultipleValues));
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(
-            b.val_names.unwrap().values().collect::<Vec<_>>(),
+            a.val_names.unwrap().values().collect::<Vec<_>>(),
             [&"option"]
         );
-        assert!(b.num_vals.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage_long8() {
-        let c = Arg::from_usage("<option> --opt <opt>... 'some help info'");
-        assert_eq!(c.name, "option");
-        assert_eq!(c.long.unwrap(), "opt");
-        assert!(c.short.is_none());
-        assert_eq!(c.help.unwrap(), "some help info");
-        assert!(c.is_set(ArgSettings::Multiple));
-        assert!(c.is_set(ArgSettings::TakesValue));
-        assert!(c.is_set(ArgSettings::Required));
-        assert_eq!(c.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
-        assert!(c.num_vals.is_none());
+        let a = Arg::from_usage("<option> --opt <opt>... 'some help info'");
+        assert_eq!(a.name, "option");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert!(a.short.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(a.is_set(ArgSettings::MultipleValues));
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
+        assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage_long9() {
-        let c = Arg::from_usage("<option>... --opt <opt> 'some help info'");
-        assert_eq!(c.name, "option");
-        assert_eq!(c.long.unwrap(), "opt");
-        assert!(c.short.is_none());
-        assert_eq!(c.help.unwrap(), "some help info");
-        assert!(c.is_set(ArgSettings::Multiple));
-        assert!(c.is_set(ArgSettings::TakesValue));
-        assert!(c.is_set(ArgSettings::Required));
-        assert_eq!(c.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
-        assert!(c.num_vals.is_none());
+        let a = Arg::from_usage("<option>... --opt <opt> 'some help info'");
+        assert_eq!(a.name, "option");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert!(a.short.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
+        assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage_long10() {
-        let d = Arg::from_usage("--opt <option>... 'some help info'");
-        assert_eq!(d.name, "opt");
-        assert_eq!(d.long.unwrap(), "opt");
-        assert!(d.short.is_none());
-        assert_eq!(d.help.unwrap(), "some help info");
-        assert!(d.is_set(ArgSettings::Multiple));
-        assert!(d.is_set(ArgSettings::TakesValue));
-        assert!(d.is_set(ArgSettings::Required));
+        let a = Arg::from_usage("--opt <option>... 'some help info'");
+        assert_eq!(a.name, "opt");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert!(a.short.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
         assert_eq!(
-            d.val_names.unwrap().values().collect::<Vec<_>>(),
+            a.val_names.unwrap().values().collect::<Vec<_>>(),
             [&"option"]
         );
-        assert!(d.num_vals.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
@@ -640,7 +650,9 @@ mod test {
         assert_eq!(a.long.unwrap(), "opt");
         assert!(a.short.is_none());
         assert_eq!(a.help.unwrap(), "some help info");
-        assert!(!a.is_set(ArgSettings::Multiple));
+        assert!(
+            !(a.is_set(ArgSettings::MultipleValues) || a.is_set(ArgSettings::MultipleOccurrences))
+        );
         assert!(a.is_set(ArgSettings::TakesValue));
         assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
@@ -649,50 +661,56 @@ mod test {
 
     #[test]
     fn create_option_usage_long_equals2() {
-        let b = Arg::from_usage("--opt=[option] 'some help info'");
-        assert_eq!(b.name, "opt");
-        assert_eq!(b.long.unwrap(), "opt");
-        assert!(b.short.is_none());
-        assert_eq!(b.help.unwrap(), "some help info");
-        assert!(!b.is_set(ArgSettings::Multiple));
-        assert!(b.is_set(ArgSettings::TakesValue));
-        assert!(!b.is_set(ArgSettings::Required));
+        let a = Arg::from_usage("--opt=[option] 'some help info'");
+        assert_eq!(a.name, "opt");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert!(a.short.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            !(a.is_set(ArgSettings::MultipleValues) || a.is_set(ArgSettings::MultipleOccurrences))
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(
-            b.val_names.unwrap().values().collect::<Vec<_>>(),
+            a.val_names.unwrap().values().collect::<Vec<_>>(),
             [&"option"]
         );
-        assert!(b.num_vals.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage_long_equals3() {
-        let c = Arg::from_usage("<option> --opt=<opt> 'some help info'");
-        assert_eq!(c.name, "option");
-        assert_eq!(c.long.unwrap(), "opt");
-        assert!(c.short.is_none());
-        assert_eq!(c.help.unwrap(), "some help info");
-        assert!(!c.is_set(ArgSettings::Multiple));
-        assert!(c.is_set(ArgSettings::TakesValue));
-        assert!(c.is_set(ArgSettings::Required));
-        assert_eq!(c.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
-        assert!(c.num_vals.is_none());
+        let a = Arg::from_usage("<option> --opt=<opt> 'some help info'");
+        assert_eq!(a.name, "option");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert!(a.short.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            !(a.is_set(ArgSettings::MultipleValues) || a.is_set(ArgSettings::MultipleOccurrences))
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
+        assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage_long_equals4() {
-        let d = Arg::from_usage("--opt=<option> 'some help info'");
-        assert_eq!(d.name, "opt");
-        assert_eq!(d.long.unwrap(), "opt");
-        assert!(d.short.is_none());
-        assert_eq!(d.help.unwrap(), "some help info");
-        assert!(!d.is_set(ArgSettings::Multiple));
-        assert!(d.is_set(ArgSettings::TakesValue));
-        assert!(d.is_set(ArgSettings::Required));
+        let a = Arg::from_usage("--opt=<option> 'some help info'");
+        assert_eq!(a.name, "opt");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert!(a.short.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            !(a.is_set(ArgSettings::MultipleValues) || a.is_set(ArgSettings::MultipleOccurrences))
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
         assert_eq!(
-            d.val_names.unwrap().values().collect::<Vec<_>>(),
+            a.val_names.unwrap().values().collect::<Vec<_>>(),
             [&"option"]
         );
-        assert!(d.num_vals.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
@@ -702,7 +720,9 @@ mod test {
         assert_eq!(a.long.unwrap(), "opt");
         assert!(a.short.is_none());
         assert_eq!(a.help.unwrap(), "some help info");
-        assert!(a.is_set(ArgSettings::Multiple));
+        assert!(
+            a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
+        );
         assert!(a.is_set(ArgSettings::TakesValue));
         assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
@@ -716,7 +736,7 @@ mod test {
         assert_eq!(a.long.unwrap(), "opt");
         assert!(a.short.is_none());
         assert_eq!(a.help.unwrap(), "some help info");
-        assert!(a.is_set(ArgSettings::Multiple));
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
         assert!(a.is_set(ArgSettings::TakesValue));
         assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
@@ -725,64 +745,70 @@ mod test {
 
     #[test]
     fn create_option_usage_long_equals7() {
-        let b = Arg::from_usage("--opt=[option]... 'some help info'");
-        assert_eq!(b.name, "opt");
-        assert_eq!(b.long.unwrap(), "opt");
-        assert!(b.short.is_none());
-        assert_eq!(b.help.unwrap(), "some help info");
-        assert!(b.is_set(ArgSettings::Multiple));
-        assert!(b.is_set(ArgSettings::TakesValue));
-        assert!(!b.is_set(ArgSettings::Required));
+        let a = Arg::from_usage("--opt=[option]... 'some help info'");
+        assert_eq!(a.name, "opt");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert!(a.short.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(
-            b.val_names.unwrap().values().collect::<Vec<_>>(),
+            a.val_names.unwrap().values().collect::<Vec<_>>(),
             [&"option"]
         );
-        assert!(b.num_vals.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage_long_equals8() {
-        let c = Arg::from_usage("<option> --opt=<opt>... 'some help info'");
-        assert_eq!(c.name, "option");
-        assert_eq!(c.long.unwrap(), "opt");
-        assert!(c.short.is_none());
-        assert_eq!(c.help.unwrap(), "some help info");
-        assert!(c.is_set(ArgSettings::Multiple));
-        assert!(c.is_set(ArgSettings::TakesValue));
-        assert!(c.is_set(ArgSettings::Required));
-        assert_eq!(c.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
-        assert!(c.num_vals.is_none());
+        let a = Arg::from_usage("<option> --opt=<opt>... 'some help info'");
+        assert_eq!(a.name, "option");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert!(a.short.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
+        assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage_long_equals9() {
-        let c = Arg::from_usage("<option>... --opt=<opt> 'some help info'");
-        assert_eq!(c.name, "option");
-        assert_eq!(c.long.unwrap(), "opt");
-        assert!(c.short.is_none());
-        assert_eq!(c.help.unwrap(), "some help info");
-        assert!(c.is_set(ArgSettings::Multiple));
-        assert!(c.is_set(ArgSettings::TakesValue));
-        assert!(c.is_set(ArgSettings::Required));
-        assert_eq!(c.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
-        assert!(c.num_vals.is_none());
+        let a = Arg::from_usage("<option>... --opt=<opt> 'some help info'");
+        assert_eq!(a.name, "option");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert!(a.short.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
+        assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage_long_equals10() {
-        let d = Arg::from_usage("--opt=<option>... 'some help info'");
-        assert_eq!(d.name, "opt");
-        assert_eq!(d.long.unwrap(), "opt");
-        assert!(d.short.is_none());
-        assert_eq!(d.help.unwrap(), "some help info");
-        assert!(d.is_set(ArgSettings::Multiple));
-        assert!(d.is_set(ArgSettings::TakesValue));
-        assert!(d.is_set(ArgSettings::Required));
+        let a = Arg::from_usage("--opt=<option>... 'some help info'");
+        assert_eq!(a.name, "opt");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert!(a.short.is_none());
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
         assert_eq!(
-            d.val_names.unwrap().values().collect::<Vec<_>>(),
+            a.val_names.unwrap().values().collect::<Vec<_>>(),
             [&"option"]
         );
-        assert!(d.num_vals.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
@@ -792,7 +818,9 @@ mod test {
         assert_eq!(a.long.unwrap(), "opt");
         assert_eq!(a.short.unwrap(), 'o');
         assert_eq!(a.help.unwrap(), "some help info");
-        assert!(!a.is_set(ArgSettings::Multiple));
+        assert!(
+            !(a.is_set(ArgSettings::MultipleValues) || a.is_set(ArgSettings::MultipleOccurrences))
+        );
         assert!(a.is_set(ArgSettings::TakesValue));
         assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(
@@ -804,50 +832,56 @@ mod test {
 
     #[test]
     fn create_option_usage_both2() {
-        let b = Arg::from_usage("-o --opt [option] 'some help info'");
-        assert_eq!(b.name, "opt");
-        assert_eq!(b.long.unwrap(), "opt");
-        assert_eq!(b.short.unwrap(), 'o');
-        assert_eq!(b.help.unwrap(), "some help info");
-        assert!(!b.is_set(ArgSettings::Multiple));
-        assert!(b.is_set(ArgSettings::TakesValue));
-        assert!(!b.is_set(ArgSettings::Required));
+        let a = Arg::from_usage("-o --opt [option] 'some help info'");
+        assert_eq!(a.name, "opt");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert_eq!(a.short.unwrap(), 'o');
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            !(a.is_set(ArgSettings::MultipleValues) || a.is_set(ArgSettings::MultipleOccurrences))
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(
-            b.val_names.unwrap().values().collect::<Vec<_>>(),
+            a.val_names.unwrap().values().collect::<Vec<_>>(),
             [&"option"]
         );
-        assert!(b.num_vals.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage_both3() {
-        let c = Arg::from_usage("<option> -o --opt <opt> 'some help info'");
-        assert_eq!(c.name, "option");
-        assert_eq!(c.long.unwrap(), "opt");
-        assert_eq!(c.short.unwrap(), 'o');
-        assert_eq!(c.help.unwrap(), "some help info");
-        assert!(!c.is_set(ArgSettings::Multiple));
-        assert!(c.is_set(ArgSettings::TakesValue));
-        assert!(c.is_set(ArgSettings::Required));
-        assert_eq!(c.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
-        assert!(c.num_vals.is_none());
+        let a = Arg::from_usage("<option> -o --opt <opt> 'some help info'");
+        assert_eq!(a.name, "option");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert_eq!(a.short.unwrap(), 'o');
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            !(a.is_set(ArgSettings::MultipleValues) || a.is_set(ArgSettings::MultipleOccurrences))
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
+        assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage_both4() {
-        let d = Arg::from_usage("-o --opt <option> 'some help info'");
-        assert_eq!(d.name, "opt");
-        assert_eq!(d.long.unwrap(), "opt");
-        assert_eq!(d.short.unwrap(), 'o');
-        assert_eq!(d.help.unwrap(), "some help info");
-        assert!(!d.is_set(ArgSettings::Multiple));
-        assert!(d.is_set(ArgSettings::TakesValue));
-        assert!(d.is_set(ArgSettings::Required));
+        let a = Arg::from_usage("-o --opt <option> 'some help info'");
+        assert_eq!(a.name, "opt");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert_eq!(a.short.unwrap(), 'o');
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            !(a.is_set(ArgSettings::MultipleValues) || a.is_set(ArgSettings::MultipleOccurrences))
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
         assert_eq!(
-            d.val_names.unwrap().values().collect::<Vec<_>>(),
+            a.val_names.unwrap().values().collect::<Vec<_>>(),
             [&"option"]
         );
-        assert!(d.num_vals.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
@@ -857,7 +891,7 @@ mod test {
         assert_eq!(a.long.unwrap(), "opt");
         assert_eq!(a.short.unwrap(), 'o');
         assert_eq!(a.help.unwrap(), "some help info");
-        assert!(a.is_set(ArgSettings::Multiple));
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
         assert!(a.is_set(ArgSettings::TakesValue));
         assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(
@@ -869,50 +903,54 @@ mod test {
 
     #[test]
     fn create_option_usage_both6() {
-        let b = Arg::from_usage("-o --opt [option]... 'some help info'");
-        assert_eq!(b.name, "opt");
-        assert_eq!(b.long.unwrap(), "opt");
-        assert_eq!(b.short.unwrap(), 'o');
-        assert_eq!(b.help.unwrap(), "some help info");
-        assert!(b.is_set(ArgSettings::Multiple));
-        assert!(b.is_set(ArgSettings::TakesValue));
-        assert!(!b.is_set(ArgSettings::Required));
+        let a = Arg::from_usage("-o --opt [option]... 'some help info'");
+        assert_eq!(a.name, "opt");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert_eq!(a.short.unwrap(), 'o');
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(
-            b.val_names.unwrap().values().collect::<Vec<_>>(),
+            a.val_names.unwrap().values().collect::<Vec<_>>(),
             [&"option"]
         );
-        assert!(b.num_vals.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage_both7() {
-        let c = Arg::from_usage("<option>... -o --opt <opt> 'some help info'");
-        assert_eq!(c.name, "option");
-        assert_eq!(c.long.unwrap(), "opt");
-        assert_eq!(c.short.unwrap(), 'o');
-        assert_eq!(c.help.unwrap(), "some help info");
-        assert!(c.is_set(ArgSettings::Multiple));
-        assert!(c.is_set(ArgSettings::TakesValue));
-        assert!(c.is_set(ArgSettings::Required));
-        assert_eq!(c.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
-        assert!(c.num_vals.is_none());
+        let a = Arg::from_usage("<option>... -o --opt <opt> 'some help info'");
+        assert_eq!(a.name, "option");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert_eq!(a.short.unwrap(), 'o');
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
+        assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage_both8() {
-        let d = Arg::from_usage("-o --opt <option>... 'some help info'");
-        assert_eq!(d.name, "opt");
-        assert_eq!(d.long.unwrap(), "opt");
-        assert_eq!(d.short.unwrap(), 'o');
-        assert_eq!(d.help.unwrap(), "some help info");
-        assert!(d.is_set(ArgSettings::Multiple));
-        assert!(d.is_set(ArgSettings::TakesValue));
-        assert!(d.is_set(ArgSettings::Required));
+        let a = Arg::from_usage("-o --opt <option>... 'some help info'");
+        assert_eq!(a.name, "opt");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert_eq!(a.short.unwrap(), 'o');
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
         assert_eq!(
-            d.val_names.unwrap().values().collect::<Vec<_>>(),
+            a.val_names.unwrap().values().collect::<Vec<_>>(),
             [&"option"]
         );
-        assert!(d.num_vals.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
@@ -922,7 +960,9 @@ mod test {
         assert_eq!(a.long.unwrap(), "opt");
         assert_eq!(a.short.unwrap(), 'o');
         assert_eq!(a.help.unwrap(), "some help info");
-        assert!(!a.is_set(ArgSettings::Multiple));
+        assert!(
+            !(a.is_set(ArgSettings::MultipleValues) || a.is_set(ArgSettings::MultipleOccurrences))
+        );
         assert!(a.is_set(ArgSettings::TakesValue));
         assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(
@@ -934,50 +974,56 @@ mod test {
 
     #[test]
     fn create_option_usage_both_equals2() {
-        let b = Arg::from_usage("-o --opt=[option] 'some help info'");
-        assert_eq!(b.name, "opt");
-        assert_eq!(b.long.unwrap(), "opt");
-        assert_eq!(b.short.unwrap(), 'o');
-        assert_eq!(b.help.unwrap(), "some help info");
-        assert!(!b.is_set(ArgSettings::Multiple));
-        assert!(b.is_set(ArgSettings::TakesValue));
-        assert!(!b.is_set(ArgSettings::Required));
+        let a = Arg::from_usage("-o --opt=[option] 'some help info'");
+        assert_eq!(a.name, "opt");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert_eq!(a.short.unwrap(), 'o');
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            !(a.is_set(ArgSettings::MultipleValues) || a.is_set(ArgSettings::MultipleOccurrences))
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(
-            b.val_names.unwrap().values().collect::<Vec<_>>(),
+            a.val_names.unwrap().values().collect::<Vec<_>>(),
             [&"option"]
         );
-        assert!(b.num_vals.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage_both_equals3() {
-        let c = Arg::from_usage("<option> -o --opt=<opt> 'some help info'");
-        assert_eq!(c.name, "option");
-        assert_eq!(c.long.unwrap(), "opt");
-        assert_eq!(c.short.unwrap(), 'o');
-        assert_eq!(c.help.unwrap(), "some help info");
-        assert!(!c.is_set(ArgSettings::Multiple));
-        assert!(c.is_set(ArgSettings::TakesValue));
-        assert!(c.is_set(ArgSettings::Required));
-        assert_eq!(c.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
-        assert!(c.num_vals.is_none());
+        let a = Arg::from_usage("<option> -o --opt=<opt> 'some help info'");
+        assert_eq!(a.name, "option");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert_eq!(a.short.unwrap(), 'o');
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            !(a.is_set(ArgSettings::MultipleValues) || a.is_set(ArgSettings::MultipleOccurrences))
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
+        assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage_both_equals4() {
-        let d = Arg::from_usage("-o --opt=<option> 'some help info'");
-        assert_eq!(d.name, "opt");
-        assert_eq!(d.long.unwrap(), "opt");
-        assert_eq!(d.short.unwrap(), 'o');
-        assert_eq!(d.help.unwrap(), "some help info");
-        assert!(!d.is_set(ArgSettings::Multiple));
-        assert!(d.is_set(ArgSettings::TakesValue));
-        assert!(d.is_set(ArgSettings::Required));
+        let a = Arg::from_usage("-o --opt=<option> 'some help info'");
+        assert_eq!(a.name, "opt");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert_eq!(a.short.unwrap(), 'o');
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            !(a.is_set(ArgSettings::MultipleValues) || a.is_set(ArgSettings::MultipleOccurrences))
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
         assert_eq!(
-            d.val_names.unwrap().values().collect::<Vec<_>>(),
+            a.val_names.unwrap().values().collect::<Vec<_>>(),
             [&"option"]
         );
-        assert!(d.num_vals.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
@@ -987,7 +1033,7 @@ mod test {
         assert_eq!(a.long.unwrap(), "opt");
         assert_eq!(a.short.unwrap(), 'o');
         assert_eq!(a.help.unwrap(), "some help info");
-        assert!(a.is_set(ArgSettings::Multiple));
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
         assert!(a.is_set(ArgSettings::TakesValue));
         assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(
@@ -999,131 +1045,145 @@ mod test {
 
     #[test]
     fn create_option_usage_both_equals6() {
-        let b = Arg::from_usage("-o --opt=[option]... 'some help info'");
-        assert_eq!(b.name, "opt");
-        assert_eq!(b.long.unwrap(), "opt");
-        assert_eq!(b.short.unwrap(), 'o');
-        assert_eq!(b.help.unwrap(), "some help info");
-        assert!(b.is_set(ArgSettings::Multiple));
-        assert!(b.is_set(ArgSettings::TakesValue));
-        assert!(!b.is_set(ArgSettings::Required));
+        let a = Arg::from_usage("-o --opt=[option]... 'some help info'");
+        assert_eq!(a.name, "opt");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert_eq!(a.short.unwrap(), 'o');
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(
-            b.val_names.unwrap().values().collect::<Vec<_>>(),
+            a.val_names.unwrap().values().collect::<Vec<_>>(),
             [&"option"]
         );
-        assert!(b.num_vals.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage_both_equals7() {
-        let c = Arg::from_usage("<option>... -o --opt=<opt> 'some help info'");
-        assert_eq!(c.name, "option");
-        assert_eq!(c.long.unwrap(), "opt");
-        assert_eq!(c.short.unwrap(), 'o');
-        assert_eq!(c.help.unwrap(), "some help info");
-        assert!(c.is_set(ArgSettings::Multiple));
-        assert!(c.is_set(ArgSettings::TakesValue));
-        assert!(c.is_set(ArgSettings::Required));
-        assert_eq!(c.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
-        assert!(c.num_vals.is_none());
+        let a = Arg::from_usage("<option>... -o --opt=<opt> 'some help info'");
+        assert_eq!(a.name, "option");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert_eq!(a.short.unwrap(), 'o');
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(a.is_set(ArgSettings::MultipleOccurrences));
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
+        assert_eq!(a.val_names.unwrap().values().collect::<Vec<_>>(), [&"opt"]);
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_usage_both_equals8() {
-        let d = Arg::from_usage("-o --opt=<option>... 'some help info'");
-        assert_eq!(d.name, "opt");
-        assert_eq!(d.long.unwrap(), "opt");
-        assert_eq!(d.short.unwrap(), 'o');
-        assert_eq!(d.help.unwrap(), "some help info");
-        assert!(d.is_set(ArgSettings::Multiple));
-        assert!(d.is_set(ArgSettings::TakesValue));
-        assert!(d.is_set(ArgSettings::Required));
+        let a = Arg::from_usage("-o --opt=<option>... 'some help info'");
+        assert_eq!(a.name, "opt");
+        assert_eq!(a.long.unwrap(), "opt");
+        assert_eq!(a.short.unwrap(), 'o');
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
         assert_eq!(
-            d.val_names.unwrap().values().collect::<Vec<_>>(),
+            a.val_names.unwrap().values().collect::<Vec<_>>(),
             [&"option"]
         );
-        assert!(d.num_vals.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn create_option_with_vals1() {
-        let d = Arg::from_usage("-o <file> <mode> 'some help info'");
-        assert_eq!(d.name, "o");
-        assert!(d.long.is_none());
-        assert_eq!(d.short.unwrap(), 'o');
-        assert_eq!(d.help.unwrap(), "some help info");
-        assert!(!d.is_set(ArgSettings::Multiple));
-        assert!(d.is_set(ArgSettings::TakesValue));
-        assert!(d.is_set(ArgSettings::Required));
+        let a = Arg::from_usage("-o <file> <mode> 'some help info'");
+        assert_eq!(a.name, "o");
+        assert!(a.long.is_none());
+        assert_eq!(a.short.unwrap(), 'o');
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            !(a.is_set(ArgSettings::MultipleValues) || a.is_set(ArgSettings::MultipleOccurrences))
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
         assert_eq!(
-            d.val_names.unwrap().values().collect::<Vec<_>>(),
+            a.val_names.unwrap().values().collect::<Vec<_>>(),
             [&"file", &"mode"]
         );
-        assert_eq!(d.num_vals.unwrap(), 2);
+        assert_eq!(a.num_vals.unwrap(), 2);
     }
 
     #[test]
     fn create_option_with_vals2() {
-        let d = Arg::from_usage("-o <file> <mode>... 'some help info'");
-        assert_eq!(d.name, "o");
-        assert!(d.long.is_none());
-        assert_eq!(d.short.unwrap(), 'o');
-        assert_eq!(d.help.unwrap(), "some help info");
-        assert!(d.is_set(ArgSettings::Multiple));
-        assert!(d.is_set(ArgSettings::TakesValue));
-        assert!(d.is_set(ArgSettings::Required));
+        let a = Arg::from_usage("-o <file> <mode>... 'some help info'");
+        assert_eq!(a.name, "o");
+        assert!(a.long.is_none());
+        assert_eq!(a.short.unwrap(), 'o');
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
         assert_eq!(
-            d.val_names.unwrap().values().collect::<Vec<_>>(),
+            a.val_names.unwrap().values().collect::<Vec<_>>(),
             [&"file", &"mode"]
         );
-        assert_eq!(d.num_vals.unwrap(), 2);
+        assert_eq!(a.num_vals.unwrap(), 2);
     }
 
     #[test]
     fn create_option_with_vals3() {
-        let d = Arg::from_usage("--opt <file> <mode>... 'some help info'");
-        assert_eq!(d.name, "opt");
-        assert!(d.short.is_none());
-        assert_eq!(d.long.unwrap(), "opt");
-        assert_eq!(d.help.unwrap(), "some help info");
-        assert!(d.is_set(ArgSettings::Multiple));
-        assert!(d.is_set(ArgSettings::TakesValue));
-        assert!(d.is_set(ArgSettings::Required));
+        let a = Arg::from_usage("--opt <file> <mode>... 'some help info'");
+        assert_eq!(a.name, "opt");
+        assert!(a.short.is_none());
+        assert_eq!(a.long.unwrap(), "opt");
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
         assert_eq!(
-            d.val_names.unwrap().values().collect::<Vec<_>>(),
+            a.val_names.unwrap().values().collect::<Vec<_>>(),
             [&"file", &"mode"]
         );
-        assert_eq!(d.num_vals.unwrap(), 2);
+        assert_eq!(a.num_vals.unwrap(), 2);
     }
 
     #[test]
     fn create_option_with_vals4() {
-        let d = Arg::from_usage("[myopt] --opt <file> <mode> 'some help info'");
-        assert_eq!(d.name, "myopt");
-        assert!(d.short.is_none());
-        assert_eq!(d.long.unwrap(), "opt");
-        assert_eq!(d.help.unwrap(), "some help info");
-        assert!(!d.is_set(ArgSettings::Multiple));
-        assert!(d.is_set(ArgSettings::TakesValue));
-        assert!(!d.is_set(ArgSettings::Required));
+        let a = Arg::from_usage("[myopt] --opt <file> <mode> 'some help info'");
+        assert_eq!(a.name, "myopt");
+        assert!(a.short.is_none());
+        assert_eq!(a.long.unwrap(), "opt");
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            !(a.is_set(ArgSettings::MultipleValues) || a.is_set(ArgSettings::MultipleOccurrences))
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(!a.is_set(ArgSettings::Required));
         assert_eq!(
-            d.val_names.unwrap().values().collect::<Vec<_>>(),
+            a.val_names.unwrap().values().collect::<Vec<_>>(),
             [&"file", &"mode"]
         );
-        assert_eq!(d.num_vals.unwrap(), 2);
+        assert_eq!(a.num_vals.unwrap(), 2);
     }
 
     #[test]
     fn create_option_with_vals5() {
-        let d = Arg::from_usage("--opt <file> <mode> 'some help info'");
-        assert_eq!(d.name, "opt");
-        assert!(d.short.is_none());
-        assert_eq!(d.long.unwrap(), "opt");
-        assert_eq!(d.help.unwrap(), "some help info");
-        assert!(!d.is_set(ArgSettings::Multiple));
-        assert!(d.is_set(ArgSettings::TakesValue));
-        assert!(d.is_set(ArgSettings::Required));
-        assert_eq!(d.num_vals.unwrap(), 2);
+        let a = Arg::from_usage("--opt <file> <mode> 'some help info'");
+        assert_eq!(a.name, "opt");
+        assert!(a.short.is_none());
+        assert_eq!(a.long.unwrap(), "opt");
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            !(a.is_set(ArgSettings::MultipleValues) || a.is_set(ArgSettings::MultipleOccurrences))
+        );
+        assert!(a.is_set(ArgSettings::TakesValue));
+        assert!(a.is_set(ArgSettings::Required));
+        assert_eq!(a.num_vals.unwrap(), 2);
     }
 
     #[test]
@@ -1131,7 +1191,9 @@ mod test {
         let a = Arg::from_usage("[pos] 'some help info'");
         assert_eq!(a.name, "pos");
         assert_eq!(a.help.unwrap(), "some help info");
-        assert!(!a.is_set(ArgSettings::Multiple));
+        assert!(
+            !(a.is_set(ArgSettings::MultipleValues) || a.is_set(ArgSettings::MultipleOccurrences))
+        );
         assert!(!a.is_set(ArgSettings::Required));
         assert!(a.val_names.is_none());
         assert!(a.num_vals.is_none());
@@ -1139,105 +1201,123 @@ mod test {
 
     #[test]
     fn create_positional_usage0() {
-        let b = Arg::from_usage("<pos> 'some help info'");
-        assert_eq!(b.name, "pos");
-        assert_eq!(b.help.unwrap(), "some help info");
-        assert!(!b.is_set(ArgSettings::Multiple));
-        assert!(b.is_set(ArgSettings::Required));
-        assert!(b.val_names.is_none());
-        assert!(b.num_vals.is_none());
+        let a = Arg::from_usage("<pos> 'some help info'");
+        assert_eq!(a.name, "pos");
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            !(a.is_set(ArgSettings::MultipleValues) || a.is_set(ArgSettings::MultipleOccurrences))
+        );
+        assert!(a.is_set(ArgSettings::Required));
+        assert!(a.val_names.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn pos_mult_help() {
-        let c = Arg::from_usage("[pos]... 'some help info'");
-        assert_eq!(c.name, "pos");
-        assert_eq!(c.help.unwrap(), "some help info");
-        assert!(c.is_set(ArgSettings::Multiple));
-        assert!(!c.is_set(ArgSettings::Required));
-        assert!(c.val_names.is_none());
-        assert!(c.num_vals.is_none());
+        let a = Arg::from_usage("[pos]... 'some help info'");
+        assert_eq!(a.name, "pos");
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
+        );
+        assert!(!a.is_set(ArgSettings::Required));
+        assert!(a.val_names.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn pos_help_lit_single_quote() {
-        let c = Arg::from_usage("[pos]... 'some help\' info'");
-        assert_eq!(c.name, "pos");
-        assert_eq!(c.help.unwrap(), "some help' info");
-        assert!(c.is_set(ArgSettings::Multiple));
-        assert!(!c.is_set(ArgSettings::Required));
-        assert!(c.val_names.is_none());
-        assert!(c.num_vals.is_none());
+        let a = Arg::from_usage("[pos]... 'some help\' info'");
+        assert_eq!(a.name, "pos");
+        assert_eq!(a.help.unwrap(), "some help' info");
+        assert!(
+            a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
+        );
+        assert!(!a.is_set(ArgSettings::Required));
+        assert!(a.val_names.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn pos_help_double_lit_single_quote() {
-        let c = Arg::from_usage("[pos]... 'some \'help\' info'");
-        assert_eq!(c.name, "pos");
-        assert_eq!(c.help.unwrap(), "some 'help' info");
-        assert!(c.is_set(ArgSettings::Multiple));
-        assert!(!c.is_set(ArgSettings::Required));
-        assert!(c.val_names.is_none());
-        assert!(c.num_vals.is_none());
+        let a = Arg::from_usage("[pos]... 'some \'help\' info'");
+        assert_eq!(a.name, "pos");
+        assert_eq!(a.help.unwrap(), "some 'help' info");
+        assert!(
+            a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
+        );
+        assert!(!a.is_set(ArgSettings::Required));
+        assert!(a.val_names.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn pos_help_newline() {
-        let c = Arg::from_usage(
+        let a = Arg::from_usage(
             "[pos]... 'some help{n}\
              info'",
         );
-        assert_eq!(c.name, "pos");
-        assert_eq!(c.help.unwrap(), "some help{n}info");
-        assert!(c.is_set(ArgSettings::Multiple));
-        assert!(!c.is_set(ArgSettings::Required));
-        assert!(c.val_names.is_none());
-        assert!(c.num_vals.is_none());
+        assert_eq!(a.name, "pos");
+        assert_eq!(a.help.unwrap(), "some help{n}info");
+        assert!(
+            a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
+        );
+        assert!(!a.is_set(ArgSettings::Required));
+        assert!(a.val_names.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn pos_help_newline_lit_sq() {
-        let c = Arg::from_usage(
+        let a = Arg::from_usage(
             "[pos]... 'some help\' stuff{n}\
              info'",
         );
-        assert_eq!(c.name, "pos");
-        assert_eq!(c.help.unwrap(), "some help' stuff{n}info");
-        assert!(c.is_set(ArgSettings::Multiple));
-        assert!(!c.is_set(ArgSettings::Required));
-        assert!(c.val_names.is_none());
-        assert!(c.num_vals.is_none());
+        assert_eq!(a.name, "pos");
+        assert_eq!(a.help.unwrap(), "some help' stuff{n}info");
+        assert!(
+            a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
+        );
+        assert!(!a.is_set(ArgSettings::Required));
+        assert!(a.val_names.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn pos_req_mult_help() {
-        let d = Arg::from_usage("<pos>... 'some help info'");
-        assert_eq!(d.name, "pos");
-        assert_eq!(d.help.unwrap(), "some help info");
-        assert!(d.is_set(ArgSettings::Multiple));
-        assert!(d.is_set(ArgSettings::Required));
-        assert!(d.val_names.is_none());
-        assert!(d.num_vals.is_none());
+        let a = Arg::from_usage("<pos>... 'some help info'");
+        assert_eq!(a.name, "pos");
+        assert_eq!(a.help.unwrap(), "some help info");
+        assert!(
+            a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
+        );
+        assert!(a.is_set(ArgSettings::Required));
+        assert!(a.val_names.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn pos_req() {
-        let b = Arg::from_usage("<pos>");
-        assert_eq!(b.name, "pos");
-        assert!(!b.is_set(ArgSettings::Multiple));
-        assert!(b.is_set(ArgSettings::Required));
-        assert!(b.val_names.is_none());
-        assert!(b.num_vals.is_none());
+        let a = Arg::from_usage("<pos>");
+        assert_eq!(a.name, "pos");
+        assert!(
+            !(a.is_set(ArgSettings::MultipleValues) || a.is_set(ArgSettings::MultipleOccurrences))
+        );
+        assert!(a.is_set(ArgSettings::Required));
+        assert!(a.val_names.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
     fn pos_mult() {
-        let c = Arg::from_usage("[pos]...");
-        assert_eq!(c.name, "pos");
-        assert!(c.is_set(ArgSettings::Multiple));
-        assert!(!c.is_set(ArgSettings::Required));
-        assert!(c.val_names.is_none());
-        assert!(c.num_vals.is_none());
+        let a = Arg::from_usage("[pos]...");
+        assert_eq!(a.name, "pos");
+        assert!(
+            a.is_set(ArgSettings::MultipleValues) && a.is_set(ArgSettings::MultipleOccurrences)
+        );
+        assert!(!a.is_set(ArgSettings::Required));
+        assert!(a.val_names.is_none());
+        assert!(a.num_vals.is_none());
     }
 
     #[test]
diff --git a/v3_changes.md b/v3_changes.md
new file mode 100644
index 00000000..f0ed204b
--- /dev/null
+++ b/v3_changes.md
@@ -0,0 +1,60 @@
+# Highlights
+
+* Lazy propagation
+* Lazy requirement validation
+* `App::write_help` takes `&mut self` now
+* `App::override_usage` No longer implies `\t` which allows multi lined usages
+* `Arg::setting` instead of `bool` methods
+* In usage parser, for options `[name]... --option [val]` results in `ArgSettings::MultipleOccurrences` but `--option [val]...` results in `ArgSettings::MultipleValues` *and* `ArgSettings::MultipleOccurrences`. Before both resulted in the same thing
+* Allow empty values no longer default
+* UseValueDelimiter no longer the default
+* Multpiple delima fixed (vals vs occurrences)
+
+# Deprecations
+
+## Simple Renames
+
+- `App::usage` -> `App::override_usage` 
+- `App::help` -> `App::override_help`
+- `App::template` -> `App::help_template`
+- `App::get_matches_safe` -> `App::try_get_matches` 
+- `App::get_matches_from_safe` -> `App::try_get_matches_from` 
+- `App::get_matches_safe_borrow` -> `App::try_get_matches_from_mut` 
+- `Arg::unset` -> `Arg::unset_setting` 
+- `Arg::set` -> `Arg::setting` 
+
+
+## Arg Bool Methods
+
+- `Arg::last` -> `ArgSettings::Last`
+- `Arg::required` -> `ArgSettings::Required`
+- `Arg::require_equals` -> `ArgSettings::RequireEquals`
+- `Arg::allow_hyphen_values` -> `ArgSettings::AllowHyphenValues`
+- `Arg::takes_value` -> `ArgSettings::TakesValue`
+- `Arg::hide_possible_values` -> `ArgSettings::HidePossibleValues`
+- `Arg::hide_default_value` -> `ArgSettings::HideDefaultValue`
+- `Arg::multiple` -> `ArgSettings::MultipleValues` 
+- `Arg::multiple` -> `ArgSettings::MultipleOccurrences` 
+- `Arg::multiple` -> `ArgSettings::Multiple` 
+- `Arg::global` -> `ArgSettings::Global`
+- `Arg::empty_values` -> `ArgSettings::AllowEmptyValues`
+- `Arg::hidden` -> `ArgSettings::Hidden`
+- `Arg::case_insensitive` -> `ArgSettings::IgnoreCase`
+- `Arg::use_delimiter` -> `ArgSettings::UseDelimiter`
+- `Arg::require_delimiter` -> `ArgSettings::RequireDelimiter`
+- `Arg::hide_env_values` -> `ArgSettings::HideEnvValues`
+- `Arg::next_line_help` -> `ArgSettings::NextLineHelp`
+
+- `App::version_message` -> `App::mut_arg`
+- `App::version_short` -> `App::mut_arg`
+- `App::help_message` -> `App::mut_arg`
+- `App::help_short` -> `App::mut_arg`
+- `App::args_from_usage` -> `App::args(&str)`
+- `App::arg_from_usage` -> `App::arg(Arg::from)`
+- `App::write_help` -> `&self` -> `&mut self` (#808)
+- `App::gen_completions` -> `clap_completions::generate`
+- `App::gen_completions_to` -> `clap_completions::generate_to`
+- `Arg::from_usage` -> `Arg::from(&str)` 
+
+# Additions
+


Test patch:
diff --git a/tests/delimiters.rs b/tests/delimiters.rs
index ac612c6d..eb709c92 100644
--- a/tests/delimiters.rs
+++ b/tests/delimiters.rs
@@ -1,12 +1,16 @@
 extern crate clap;
 
-use clap::{App, Arg};
+use clap::{App, Arg, ArgSettings};
 
 #[test]
 fn opt_default_no_delim() {
     let m = App::new("no_delim")
-        .arg(Arg::with_name("option").long("option").takes_value(true))
-        .get_matches_from_safe(vec!["", "--option", "val1,val2,val3"]);
+        .arg(
+            Arg::with_name("option")
+                .long("option")
+                .setting(ArgSettings::TakesValue),
+        )
+        .try_get_matches_from(vec!["", "--option", "val1,val2,val3"]);
 
     assert!(m.is_ok());
     let m = m.unwrap();
@@ -19,8 +23,12 @@ fn opt_default_no_delim() {
 #[test]
 fn opt_eq_no_delim() {
     let m = App::new("no_delim")
-        .arg(Arg::with_name("option").long("option").takes_value(true))
-        .get_matches_from_safe(vec!["", "--option=val1,val2,val3"]);
+        .arg(
+            Arg::with_name("option")
+                .long("option")
+                .setting(ArgSettings::TakesValue),
+        )
+        .try_get_matches_from(vec!["", "--option=val1,val2,val3"]);
 
     assert!(m.is_ok());
     let m = m.unwrap();
@@ -33,8 +41,12 @@ fn opt_eq_no_delim() {
 #[test]
 fn opt_s_eq_no_delim() {
     let m = App::new("no_delim")
-        .arg(Arg::with_name("option").short("o").takes_value(true))
-        .get_matches_from_safe(vec!["", "-o=val1,val2,val3"]);
+        .arg(
+            Arg::with_name("option")
+                .short("o")
+                .setting(ArgSettings::TakesValue),
+        )
+        .try_get_matches_from(vec!["", "-o=val1,val2,val3"]);
 
     assert!(m.is_ok(), "{:?}", m.unwrap_err());
     let m = m.unwrap();
@@ -47,8 +59,12 @@ fn opt_s_eq_no_delim() {
 #[test]
 fn opt_s_default_no_delim() {
     let m = App::new("no_delim")
-        .arg(Arg::with_name("option").short("o").takes_value(true))
-        .get_matches_from_safe(vec!["", "-o", "val1,val2,val3"]);
+        .arg(
+            Arg::with_name("option")
+                .short("o")
+                .setting(ArgSettings::TakesValue),
+        )
+        .try_get_matches_from(vec!["", "-o", "val1,val2,val3"]);
 
     assert!(m.is_ok(), "{:?}", m.unwrap_err());
     let m = m.unwrap();
@@ -61,8 +77,12 @@ fn opt_s_default_no_delim() {
 #[test]
 fn opt_s_no_space_no_delim() {
     let m = App::new("no_delim")
-        .arg(Arg::with_name("option").short("o").takes_value(true))
-        .get_matches_from_safe(vec!["", "-o", "val1,val2,val3"]);
+        .arg(
+            Arg::with_name("option")
+                .short("o")
+                .setting(ArgSettings::TakesValue),
+        )
+        .try_get_matches_from(vec!["", "-o", "val1,val2,val3"]);
 
     assert!(m.is_ok());
     let m = m.unwrap();
@@ -78,10 +98,9 @@ fn opt_s_no_space_mult_no_delim() {
         .arg(
             Arg::with_name("option")
                 .short("o")
-                .multiple(true)
-                .takes_value(true),
+                .setting(ArgSettings::MultipleValues),
         )
-        .get_matches_from_safe(vec!["", "-o", "val1,val2,val3"]);
+        .try_get_matches_from(vec!["", "-o", "val1,val2,val3"]);
 
     assert!(m.is_ok());
     let m = m.unwrap();
@@ -99,9 +118,9 @@ fn opt_eq_mult_def_delim() {
                 .long("opt")
                 .multiple(true)
                 .use_delimiter(true)
-                .takes_value(true),
+                .setting(ArgSettings::TakesValue),
         )
-        .get_matches_from_safe(vec!["", "--opt=val1,val2,val3"]);
+        .try_get_matches_from(vec!["", "--opt=val1,val2,val3"]);
 
     assert!(m.is_ok());
     let m = m.unwrap();
diff --git a/tests/flags.rs b/tests/flags.rs
index 3bd46d0c..8e4ec0c0 100644
--- a/tests/flags.rs
+++ b/tests/flags.rs
@@ -42,7 +42,7 @@ fn lots_o_flags_sep() {
             "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
             "-o", "-o", "-o",
         ]);
-    assert!(r.is_ok());
+    assert!(r.is_ok(), "{:?}", r.unwrap_err().kind);
     let m = r.unwrap();
     assert!(m.is_present("o"));
     assert_eq!(m.occurrences_of("o"), 297); // i.e. more than u8
@@ -60,7 +60,7 @@ fn lots_o_flags_combined() {
             "-oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
             "-ooooooooooooooooooooooooooooooooooooooooo",
         ]);
-    assert!(r.is_ok());
+    assert!(r.is_ok(), "{:?}", r.unwrap_err().kind);
     let m = r.unwrap();
     assert!(m.is_present("o"));
     assert_eq!(m.occurrences_of("o"), 297); // i.e. more than u8
@@ -120,7 +120,7 @@ fn short_flag_misspel() {
     assert_eq!(a.short.unwrap(), 'f');
     assert_eq!(a.long.unwrap(), "flag");
     assert_eq!(a.help.unwrap(), "some flag");
-    assert!(!a.is_set(ArgSettings::Multiple));
+    assert!(!a.is_set(ArgSettings::MultipleOccurrences));
     assert!(a.val_names.is_none());
     assert!(a.num_vals.is_none());
 }
@@ -132,7 +132,7 @@ fn short_flag_name_missing() {
     assert_eq!(a.short.unwrap(), 'f');
     assert!(a.long.is_none());
     assert_eq!(a.help.unwrap(), "some flag");
-    assert!(!a.is_set(ArgSettings::Multiple));
+    assert!(!a.is_set(ArgSettings::MultipleOccurrences));
     assert!(a.val_names.is_none());
     assert!(a.num_vals.is_none());
 }
diff --git a/tests/help.rs b/tests/help.rs
index acbc9572..10db0a65 100644
--- a/tests/help.rs
+++ b/tests/help.rs
@@ -4,7 +4,7 @@ extern crate regex;
 
 include!("../clap-test.rs");
 
-use clap::{App, AppSettings, Arg, ErrorKind, SubCommand};
+use clap::{App, AppSettings, Arg, ArgSettings, ErrorKind, SubCommand};
 
 static REQUIRE_DELIM_HELP: &'static str = "test 1.3
 Kevin K.
@@ -586,36 +586,36 @@ fn args_with_last_usage() {
                 .help("Prints out more stuff.")
                 .short("v")
                 .long("verbose")
-                .multiple(true),
+                .setting(ArgSettings::MultipleOccurrences),
         )
         .arg(
             Arg::with_name("timeout")
                 .help("Timeout in seconds.")
                 .short("t")
                 .long("timeout")
-                .value_name("SECONDS")
-                .takes_value(true),
+                .value_name("SECONDS"),
         )
         .arg(
             Arg::with_name("frequency")
                 .help("The sampling frequency.")
                 .short("f")
                 .long("frequency")
-                .value_name("HERTZ")
-                .takes_value(true),
+                .value_name("HERTZ"),
         )
         .arg(
             Arg::with_name("binary path")
                 .help("The path of the binary to be profiled. for a binary.")
-                .takes_value(true)
                 .value_name("BINFILE"),
         )
         .arg(
             Arg::with_name("pass through args")
                 .help("Any arguments you wish to pass to the being profiled.")
-                .value_name("ARGS")
-                .last(true)
-                .multiple(true),
+                .settings(&[
+                    ArgSettings::MultipleValues,
+                    ArgSettings::MultipleOccurrences,
+                    ArgSettings::Last,
+                ])
+                .value_name("ARGS"),
         );
     assert!(test::compare_output(
         app,
diff --git a/tests/multiple_occurrences.rs b/tests/multiple_occurrences.rs
index 4bbd1b28..c2e85931 100644
--- a/tests/multiple_occurrences.rs
+++ b/tests/multiple_occurrences.rs
@@ -1,11 +1,14 @@
 extern crate clap;
 
-use clap::{App, Arg};
+use clap::{App, Arg, ArgSettings};
 
 #[test]
 fn multiple_occurrences_of_flags_long() {
     let m = App::new("mo_flags_long")
-        .arg(Arg::from_usage("--multflag 'allowed multiple flag'").multiple(true))
+        .arg(
+            Arg::from_usage("--multflag 'allowed multiple flag'")
+                .setting(ArgSettings::MultipleOccurrences),
+        )
         .arg(Arg::from_usage("--flag 'disallowed multiple flag'"))
         .get_matches_from(vec!["", "--multflag", "--flag", "--multflag"]);
     assert!(m.is_present("multflag"));
@@ -17,7 +20,10 @@ fn multiple_occurrences_of_flags_long() {
 #[test]
 fn multiple_occurrences_of_flags_short() {
     let m = App::new("mo_flags_short")
-        .arg(Arg::from_usage("-m --multflag 'allowed multiple flag'").multiple(true))
+        .arg(
+            Arg::from_usage("-m --multflag 'allowed multiple flag'")
+                .setting(ArgSettings::MultipleOccurrences),
+        )
         .arg(Arg::from_usage("-f --flag 'disallowed multiple flag'"))
         .get_matches_from(vec!["", "-m", "-f", "-m"]);
     assert!(m.is_present("multflag"));
@@ -29,8 +35,14 @@ fn multiple_occurrences_of_flags_short() {
 #[test]
 fn multiple_occurrences_of_flags_mixed() {
     let m = App::new("mo_flags_mixed")
-        .arg(Arg::from_usage("-m, --multflag1 'allowed multiple flag'").multiple(true))
-        .arg(Arg::from_usage("-n, --multflag2 'another allowed multiple flag'").multiple(true))
+        .arg(
+            Arg::from_usage("-m, --multflag1 'allowed multiple flag'")
+                .setting(ArgSettings::MultipleOccurrences),
+        )
+        .arg(
+            Arg::from_usage("-n, --multflag2 'another allowed multiple flag'")
+                .setting(ArgSettings::MultipleOccurrences),
+        )
         .arg(Arg::from_usage("-f, --flag 'disallowed multiple flag'"))
         .get_matches_from(vec![
             "",
@@ -56,7 +68,10 @@ fn multiple_occurrences_of_flags_large_quantity() {
         .chain(vec!["-m"; 1024].into_iter())
         .collect();
     let m = App::new("mo_flags_larg_qty")
-        .arg(Arg::from_usage("-m --multflag 'allowed multiple flag'").multiple(true))
+        .arg(
+            Arg::from_usage("-m --multflag 'allowed multiple flag'")
+                .setting(ArgSettings::MultipleOccurrences),
+        )
         .get_matches_from(args);
     assert!(m.is_present("multflag"));
     assert_eq!(m.occurrences_of("multflag"), 1024);
diff --git a/tests/opts.rs b/tests/opts.rs
index df64ee74..c5c1bdab 100644
--- a/tests/opts.rs
+++ b/tests/opts.rs
@@ -3,7 +3,7 @@ extern crate regex;
 
 include!("../clap-test.rs");
 
-use clap::{App, Arg, ArgMatches, ErrorKind};
+use clap::{App, Arg, ArgMatches, ArgSettings, ErrorKind};
 
 #[cfg(feature = "suggestions")]
 static DYM: &'static str =
@@ -20,11 +20,11 @@ fn require_equals_fail() {
     let res = App::new("prog")
         .arg(
             Arg::with_name("cfg")
-                .require_equals(true)
-                .takes_value(true)
+                .setting(ArgSettings::RequireEquals)
+                .setting(ArgSettings::TakesValue)
                 .long("config"),
         )
-        .get_matches_from_safe(vec!["prog", "--config", "file.conf"]);
+        .try_get_matches_from(vec!["prog", "--config", "file.conf"]);
     assert!(res.is_err());
     assert_eq!(res.unwrap_err().kind, ErrorKind::EmptyValue);
 }
@@ -34,13 +34,12 @@ fn require_equals_min_values_zero() {
     let res = App::new("prog")
         .arg(
             Arg::with_name("cfg")
-                .require_equals(true)
-                .takes_value(true)
+                .setting(ArgSettings::RequireEquals)
                 .min_values(0)
                 .long("config"),
         )
         .arg(Arg::with_name("cmd"))
-        .get_matches_from_safe(vec!["prog", "--config", "cmd"]);
+        .try_get_matches_from(vec!["prog", "--config", "cmd"]);
     assert!(res.is_ok());
     let m = res.unwrap();
     assert!(m.is_present("cfg"));
@@ -52,11 +51,10 @@ fn double_hyphen_as_value() {
     let res = App::new("prog")
         .arg(
             Arg::with_name("cfg")
-                .takes_value(true)
-                .allow_hyphen_values(true)
+                .setting(ArgSettings::AllowHyphenValues)
                 .long("config"),
         )
-        .get_matches_from_safe(vec!["prog", "--config", "--"]);
+        .try_get_matches_from(vec!["prog", "--config", "--"]);
     assert!(res.is_ok(), "{:?}", res);
     assert_eq!(res.unwrap().value_of("cfg"), Some("--"));
 }
@@ -66,12 +64,11 @@ fn require_equals_no_empty_values_fail() {
     let res = App::new("prog")
         .arg(
             Arg::with_name("cfg")
-                .require_equals(true)
-                .takes_value(true)
+                .setting(ArgSettings::RequireEquals)
                 .long("config"),
         )
         .arg(Arg::with_name("some"))
-        .get_matches_from_safe(vec!["prog", "--config=", "file.conf"]);
+        .try_get_matches_from(vec!["prog", "--config=", "file.conf"]);
     assert!(res.is_err());
     assert_eq!(res.unwrap_err().kind, ErrorKind::EmptyValue);
 }
@@ -81,12 +78,11 @@ fn require_equals_empty_vals_pass() {
     let res = App::new("prog")
         .arg(
             Arg::with_name("cfg")
-                .require_equals(true)
-                .takes_value(true)
-                .empty_values(true)
+                .setting(ArgSettings::RequireEquals)
+                .setting(ArgSettings::AllowEmptyValues)
                 .long("config"),
         )
-        .get_matches_from_safe(vec!["prog", "--config="]);
+        .try_get_matches_from(vec!["prog", "--config="]);
     assert!(res.is_ok());
 }
 
@@ -95,11 +91,10 @@ fn require_equals_pass() {
     let res = App::new("prog")
         .arg(
             Arg::with_name("cfg")
-                .require_equals(true)
-                .takes_value(true)
+                .setting(ArgSettings::RequireEquals)
                 .long("config"),
         )
-        .get_matches_from_safe(vec!["prog", "--config=file.conf"]);
+        .try_get_matches_from(vec!["prog", "--config=file.conf"]);
     assert!(res.is_ok());
 }
 
@@ -107,7 +102,7 @@ fn require_equals_pass() {
 fn stdin_char() {
     let r = App::new("opts")
         .arg(Arg::from_usage("-f [flag] 'some flag'"))
-        .get_matches_from_safe(vec!["", "-f", "-"]);
+        .try_get_matches_from(vec!["", "-f", "-"]);
     assert!(r.is_ok());
     let m = r.unwrap();
     assert!(m.is_present("f"));
@@ -121,7 +116,7 @@ fn opts_using_short() {
             Arg::from_usage("-f [flag] 'some flag'"),
             Arg::from_usage("-c [color] 'some other flag'"),
         ])
-        .get_matches_from_safe(vec!["", "-f", "some", "-c", "other"]);
+        .try_get_matches_from(vec!["", "-f", "some", "-c", "other"]);
     assert!(r.is_ok());
     let m = r.unwrap();
     assert!(m.is_present("f"));
@@ -134,7 +129,7 @@ fn opts_using_short() {
 fn lots_o_vals() {
     let r = App::new("opts")
         .arg(Arg::from_usage("-o [opt]... 'some opt'"))
-        .get_matches_from_safe(vec![
+        .try_get_matches_from(vec![
             "", "-o", "some", "some", "some", "some", "some", "some", "some", "some", "some",
             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
             "some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
@@ -177,7 +172,7 @@ fn opts_using_long_space() {
             Arg::from_usage("--flag [flag] 'some flag'"),
             Arg::from_usage("--color [color] 'some other flag'"),
         ])
-        .get_matches_from_safe(vec!["", "--flag", "some", "--color", "other"]);
+        .try_get_matches_from(vec!["", "--flag", "some", "--color", "other"]);
     assert!(r.is_ok());
     let m = r.unwrap();
     assert!(m.is_present("flag"));
@@ -193,7 +188,7 @@ fn opts_using_long_equals() {
             Arg::from_usage("--flag [flag] 'some flag'"),
             Arg::from_usage("--color [color] 'some other flag'"),
         ])
-        .get_matches_from_safe(vec!["", "--flag=some", "--color=other"]);
+        .try_get_matches_from(vec!["", "--flag=some", "--color=other"]);
     assert!(r.is_ok());
     let m = r.unwrap();
     assert!(m.is_present("flag"));
@@ -209,7 +204,7 @@ fn opts_using_mixed() {
             Arg::from_usage("-f, --flag [flag] 'some flag'"),
             Arg::from_usage("-c, --color [color] 'some other flag'"),
         ])
-        .get_matches_from_safe(vec!["", "-f", "some", "--color", "other"]);
+        .try_get_matches_from(vec!["", "-f", "some", "--color", "other"]);
     assert!(r.is_ok());
     let m = r.unwrap();
     assert!(m.is_present("flag"));
@@ -225,7 +220,7 @@ fn opts_using_mixed2() {
             Arg::from_usage("-f, --flag [flag] 'some flag'"),
             Arg::from_usage("-c, --color [color] 'some other flag'"),
         ])
-        .get_matches_from_safe(vec!["", "--flag=some", "-c", "other"]);
+        .try_get_matches_from(vec!["", "--flag=some", "-c", "other"]);
     assert!(r.is_ok());
     let m = r.unwrap();
     assert!(m.is_present("flag"));
@@ -238,7 +233,7 @@ fn opts_using_mixed2() {
 fn default_values_user_value() {
     let r = App::new("df")
         .arg(Arg::from_usage("-o [opt] 'some opt'").default_value("default"))
-        .get_matches_from_safe(vec!["", "-o", "value"]);
+        .try_get_matches_from(vec!["", "-o", "value"]);
     assert!(r.is_ok());
     let m = r.unwrap();
     assert!(m.is_present("o"));
@@ -250,7 +245,7 @@ fn multiple_vals_pos_arg_equals() {
     let r = App::new("mvae")
         .arg(Arg::from_usage("-o [opt]... 'some opt'"))
         .arg(Arg::from_usage("[file] 'some file'"))
-        .get_matches_from_safe(vec!["", "-o=1", "some"]);
+        .try_get_matches_from(vec!["", "-o=1", "some"]);
     assert!(r.is_ok());
     let m = r.unwrap();
     assert!(m.is_present("o"));
@@ -262,9 +257,9 @@ fn multiple_vals_pos_arg_equals() {
 #[test]
 fn multiple_vals_pos_arg_delim() {
     let r = App::new("mvae")
-        .arg(Arg::from_usage("-o [opt]... 'some opt'"))
+        .arg(Arg::from_usage("-o [opt]... 'some opt'").setting(ArgSettings::UseValueDelimiter))
         .arg(Arg::from_usage("[file] 'some file'"))
-        .get_matches_from_safe(vec!["", "-o", "1,2", "some"]);
+        .try_get_matches_from(vec!["", "-o", "1,2", "some"]);
     assert!(r.is_ok());
     let m = r.unwrap();
     assert!(m.is_present("o"));
@@ -276,9 +271,9 @@ fn multiple_vals_pos_arg_delim() {
 #[test]
 fn require_delims_no_delim() {
     let r = App::new("mvae")
-        .arg(Arg::from_usage("-o [opt]... 'some opt'").require_delimiter(true))
+        .arg(Arg::from_usage("-o [opt]... 'some opt'").setting(ArgSettings::RequireDelimiter))
         .arg(Arg::from_usage("[file] 'some file'"))
-        .get_matches_from_safe(vec!["mvae", "-o", "1", "2", "some"]);
+        .try_get_matches_from(vec!["mvae", "-o", "1", "2", "some"]);
     assert!(r.is_err());
     let err = r.unwrap_err();
     assert_eq!(err.kind, ErrorKind::UnknownArgument);
@@ -287,9 +282,9 @@ fn require_delims_no_delim() {
 #[test]
 fn require_delims() {
     let r = App::new("mvae")
-        .arg(Arg::from_usage("-o [opt]... 'some opt'").require_delimiter(true))
+        .arg(Arg::from_usage("-o [opt]... 'some opt'").setting(ArgSettings::RequireDelimiter))
         .arg(Arg::from_usage("[file] 'some file'"))
-        .get_matches_from_safe(vec!["", "-o", "1,2", "some"]);
+        .try_get_matches_from(vec!["", "-o", "1,2", "some"]);
     assert!(r.is_ok());
     let m = r.unwrap();
     assert!(m.is_present("o"));
@@ -301,8 +296,8 @@ fn require_delims() {
 #[test]
 fn leading_hyphen_pass() {
     let r = App::new("mvae")
-        .arg(Arg::from_usage("-o [opt]... 'some opt'").allow_hyphen_values(true))
-        .get_matches_from_safe(vec!["", "-o", "-2", "3"]);
+        .arg(Arg::from_usage("-o [opt]... 'some opt'").setting(ArgSettings::AllowHyphenValues))
+        .try_get_matches_from(vec!["", "-o", "-2", "3"]);
     assert!(r.is_ok());
     let m = r.unwrap();
     assert!(m.is_present("o"));
@@ -313,7 +308,7 @@ fn leading_hyphen_pass() {
 fn leading_hyphen_fail() {
     let r = App::new("mvae")
         .arg(Arg::from_usage("-o [opt] 'some opt'"))
-        .get_matches_from_safe(vec!["", "-o", "-2"]);
+        .try_get_matches_from(vec!["", "-o", "-2"]);
     assert!(r.is_err());
     let m = r.unwrap_err();
     assert_eq!(m.kind, ErrorKind::UnknownArgument);
@@ -322,9 +317,9 @@ fn leading_hyphen_fail() {
 #[test]
 fn leading_hyphen_with_flag_after() {
     let r = App::new("mvae")
-        .arg(Arg::from_usage("-o [opt]... 'some opt'").allow_hyphen_values(true))
+        .arg(Arg::from_usage("-o [opt]... 'some opt'").setting(ArgSettings::AllowHyphenValues))
         .arg_from_usage("-f 'some flag'")
-        .get_matches_from_safe(vec!["", "-o", "-2", "-f"]);
+        .try_get_matches_from(vec!["", "-o", "-2", "-f"]);
     assert!(r.is_ok());
     let m = r.unwrap();
     assert!(m.is_present("o"));
@@ -335,9 +330,9 @@ fn leading_hyphen_with_flag_after() {
 #[test]
 fn leading_hyphen_with_flag_before() {
     let r = App::new("mvae")
-        .arg(Arg::from_usage("-o [opt]... 'some opt'").allow_hyphen_values(true))
+        .arg(Arg::from_usage("-o [opt]... 'some opt'").setting(ArgSettings::AllowHyphenValues))
         .arg_from_usage("-f 'some flag'")
-        .get_matches_from_safe(vec!["", "-f", "-o", "-2"]);
+        .try_get_matches_from(vec!["", "-f", "-o", "-2"]);
     assert!(r.is_ok());
     let m = r.unwrap();
     assert!(m.is_present("o"));
@@ -351,10 +346,10 @@ fn leading_hyphen_with_only_pos_follows() {
         .arg(
             Arg::from_usage("-o [opt]... 'some opt'")
                 .number_of_values(1)
-                .allow_hyphen_values(true),
+                .setting(ArgSettings::AllowHyphenValues),
         )
         .arg_from_usage("[arg] 'some arg'")
-        .get_matches_from_safe(vec!["", "-o", "-2", "--", "val"]);
+        .try_get_matches_from(vec!["", "-o", "-2", "--", "val"]);
     assert!(r.is_ok(), "{:?}", r);
     let m = r.unwrap();
     assert!(m.is_present("o"));
@@ -378,9 +373,8 @@ fn issue_665() {
     let res = App::new("tester")
         .arg_from_usage("-v, --reroll-count=[N] 'Mark the patch series as PATCH vN'")
         .arg(Arg::from_usage(
-"--subject-prefix [Subject-Prefix] 'Use [Subject-Prefix] instead of the standard [PATCH] prefix'")
-            .empty_values(false))
-        .get_matches_from_safe(vec!["test", "--subject-prefix", "-v", "2"]);
+"--subject-prefix [Subject-Prefix] 'Use [Subject-Prefix] instead of the standard [PATCH] prefix'") )
+        .try_get_matches_from(vec!["test", "--subject-prefix", "-v", "2"]);
 
     assert!(res.is_err());
     assert_eq!(res.unwrap_err().kind, ErrorKind::EmptyValue);
@@ -393,8 +387,7 @@ fn issue_1047_min_zero_vals_default_val() {
             Arg::with_name("del")
                 .short("d")
                 .long("del")
-                .takes_value(true)
-                .require_equals(true)
+                .setting(ArgSettings::RequireEquals)
                 .min_values(0)
                 .default_value("default"),
         )
@@ -405,9 +398,12 @@ fn issue_1047_min_zero_vals_default_val() {
 
 fn issue_1105_setup(argv: Vec<&'static str>) -> Result<ArgMatches<'static>, clap::Error> {
     App::new("opts")
-        .arg_from_usage("-o, --option [opt] 'some option'")
-        .arg_from_usage("--flag 'some flag'")
-        .get_matches_from_safe(argv)
+        .arg(
+            Arg::from_usage("-o, --option [opt] 'some option'")
+                .setting(ArgSettings::AllowEmptyValues),
+        )
+        .arg(Arg::from_usage("--flag 'some flag'"))
+        .try_get_matches_from(argv)
 }
 
 #[test]
diff --git a/tests/propagate_globals.rs b/tests/propagate_globals.rs
index 2f4ce1f8..f30cfd83 100644
--- a/tests/propagate_globals.rs
+++ b/tests/propagate_globals.rs
@@ -4,7 +4,7 @@ extern crate regex;
 #[cfg(test)]
 mod tests {
     include!("../clap-test.rs");
-    use clap::{App, Arg, ArgMatches, SubCommand};
+    use clap::{App, Arg, ArgMatches, ArgSettings, SubCommand};
 
     fn get_app() -> App<'static, 'static> {
         App::new("myprog")
@@ -12,16 +12,16 @@ mod tests {
                 Arg::with_name("GLOBAL_ARG")
                     .long("global-arg")
                     .help("Specifies something needed by the subcommands")
-                    .global(true)
-                    .takes_value(true)
+                    .setting(ArgSettings::Global)
+                    .setting(ArgSettings::TakesValue)
                     .default_value("default_value"),
             )
             .arg(
                 Arg::with_name("GLOBAL_FLAG")
                     .long("global-flag")
                     .help("Specifies something needed by the subcommands")
-                    .multiple(true)
-                    .global(true),
+                    .setting(ArgSettings::MultipleOccurrences)
+                    .setting(ArgSettings::Global),
             )
             .subcommand(SubCommand::with_name("outer").subcommand(SubCommand::with_name("inner")))
     }