private void ShouldShowHelpWhenRequested(List<ConsoleCommand> commands, string[] consoleArguments)
        {
            var writer = new StringWriter();

            when("we call a command, asking for help", delegate
            {
                var commandC = new TestCommand()
                    .IsCommand("command-c", "one line description for C")
                    .HasAdditionalArguments(0, "<remaining> <args>")
                    .HasOption("o|option=", "option description", v => { });

                commands.Add(commandC);

                var exitCode = arrange(() => ConsoleCommandDispatcher.DispatchCommand(commands, consoleArguments, writer));

                then("the output contains a all help available for that command", delegate
                {
                    var output = writer.ToString();
                    Expect.That(output).ContainsInOrder(
                        commandC.Command,
                        commandC.OneLineDescription,
                        commandC.RemainingArgumentsHelpText,
                        "-o",
                        "--option",
                        "option description");
                });

                then("the process exit code is non-zero", () => expect(() => exitCode == -1));
            });
        }
        public override void Specify()
        {
            given("a no-op command that requires a parameter", delegate()
            {
                string result = null;
                var noopCommand = new TestCommand()
                    .IsCommand("required", "This command has a required parameter")
                    .HasOption("ignored=", "An extra option.", v => { })
                    .HasRequiredOption("f|foo=", "This foo to use.", v => result = v)
                    .SkipsCommandSummaryBeforeRunning();
                
                when_the_command_is_ran_without_the_parameter_then_the_console_gives_error_output(noopCommand, "foo");

                when("that command is ran with the parameter", delegate()
                {
                    StringWriter output = new StringWriter();

                    var exitCode = arrange(() => ConsoleCommandDispatcher.DispatchCommand(noopCommand, 
                        new[] { "required", "-foo", "bar" }, output));

                    then("the exit code indicates the call succeeded", delegate()
                    {
                        expect(() => exitCode == 0);
                    });

                    then("the option is actually received", delegate()
                    {
                        expect(() => result == "bar");
                    });
                });
            });

            given("a command that requires an integer parameter", () =>
            {
                int result = 0;
                var requiresInteger = arrange(() => new TestCommand()
                    .IsCommand("parse-int")
                    .HasRequiredOption<int>("value=", "The integer value", v => result = v));

                when("the command is passed an integer value", () =>
                {
                    StringWriter output = new StringWriter();

                    var exitCode = arrange(() => ConsoleCommandDispatcher.DispatchCommand(requiresInteger,
                        new[] { "parse-int", "-value", "42" }, output));

                    then("the command is told the parameter", ()=>
                    {
                        expect(() => result == 42);
                    });

                    then("the return value is success", () => expect(() => exitCode == 0));
                });

                when_the_command_is_ran_without_the_parameter_then_the_console_gives_error_output(requiresInteger, "value");
            });
        }
        public override void Specify()
        {
            given("we have some commands", delegate
            {
                var firstcommand = new TestCommand().IsCommand("command-a", "oneline description a");
                var secondCommand = new TestCommand().IsCommand("command-b", "oneline description b");

                var commands = new ConsoleCommand[]
                {
                    firstcommand,
                    secondCommand
                }.ToList();

                var writer = new StringWriter();

                when("we dispatch the commands with no arguments", delegate
                {
                    arrange(() => ConsoleCommandDispatcher.DispatchCommand(commands, new string[0], writer));

                    then("the output contains a list of available commands", delegate
                    {
                        var output = writer.ToString();

                        Expect.That(output).ContainsInOrder(
                            firstcommand.Command,
                            firstcommand.OneLineDescription,
                            secondCommand.Command,
                            secondCommand.OneLineDescription);
                    });
                });

                when("we call a command, asking for help", delegate
                {
                    var commandC = new TestCommand()
                        .IsCommand("command-c", "one line description for C")
                        .HasAdditionalArguments(0, "<remaining> <args>")
                        .HasOption("o|option=", "option description", v => { });

                    commands.Add(commandC);

                    arrange(() => ConsoleCommandDispatcher.DispatchCommand(commands, new string[] { commandC.Command, "/?" }, writer));

                    then("the output contains a all help available for that command", delegate
                    {
                        var output = writer.ToString();
                        Expect.That(output).ContainsInOrder(
                            commandC.Command,
                            commandC.OneLineDescription,
                            commandC.RemainingArgumentsHelpText,
                            "-o",
                            "--option",
                            "option description");
                    });
                });
            });
        }
        private void ShouldShowHelpWhenRequested(List<ConsoleCommand> commands, string[] consoleArguments)
        {
            var writer = new StringWriter();

            when("we call a command, asking for help", delegate
            {
                var commandC = new TestCommand()
                    .IsCommand("command-c", "one line description for C")
                    .HasLongDescription(
            @"Lorem ipsum dolor sit amet, consectetur adipiscing elit,
            sed do eiusmod tempor incididunt ut labore et dolore magna
            aliqua. Ut enim ad minim veniam, quis nostrud exercitation
            ullamco laboris nisi ut aliquip ex ea commodo consequat.
            Duis aute irure dolor in reprehenderit in voluptate velit
            esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
            occaecat cupidatat non proident, sunt in culpa qui officia
            deserunt mollit anim id est laborum.")
                    .HasAdditionalArguments(0, "<remaining> <args>")
                    .HasOption("o|option=", "option description", v => { });

                commands.Add(commandC);

                var exitCode = arrange(() => ConsoleCommandDispatcher.DispatchCommand(commands, consoleArguments, writer));

                then("the output contains a all help available for that command", delegate
                {
                    var output = writer.ToString();
                    Expect.That(output).ContainsInOrder(
                        commandC.Command,
                        commandC.OneLineDescription,
                        commandC.LongDescription,
                        commandC.RemainingArgumentsHelpText,
                        "-o",
                        "--option",
                        "option description");
                });

                then("the process exit code is non-zero", () => expect(() => exitCode == -1));
            });
        }
        public override void Specify()
        {
            given("we have some commands", delegate
            {
                var firstcommand = new TestCommand().IsCommand("command-a", "oneline description a");
                var secondCommand = new TestCommand().IsCommand("command-b", "oneline description b");

                var commands = new ConsoleCommand[]
                {
                    firstcommand,
                    secondCommand
                }.ToList();

                var writer = new StringWriter();

                WhenTheUserDoesNotSpecifyACommandThenShowAvailableCommands(commands, writer, firstcommand, secondCommand, new string[0]);
                WhenTheUserDoesNotSpecifyACommandThenShowAvailableCommands(commands, writer, firstcommand, secondCommand, new [] { "help"});

                ShouldShowHelpWhenRequested(commands, new string[] { "command-c", "/?" });
                ShouldShowHelpWhenRequested(commands, new string[] { "help", "command-c" });
            });
        }