public void Execute(CommandParameters parameters)
        {
            var matches = MatchCommands(parameters);

            if (matches.Count() == 1) {
                var match = matches.Single();
                match.CommandHandlerFactory().Execute(match.Context);
            }
            else {
                var commandMatch = string.Join(" ", parameters.Arguments.ToArray());
                var commandList = string.Join(",", GetCommandDescriptors().Select(d => d.Name).ToArray());
                if (matches.Any()) {
                    throw new CoeveryCoreException(T("Multiple commands found matching arguments \"{0}\". Commands available: {1}.",
                                                             commandMatch, commandList));
                }
                throw new CoeveryCoreException(T("No command found matching arguments \"{0}\". Commands available: {1}.",
                                                 commandMatch, commandList));
            }
        }
        private static IEnumerable<Match> MatchCommands(CommandParameters parameters, int argCount, CommandHandlerDescriptor descriptor, Func<ICommandHandler> handlerFactory)
        {
            foreach (var commandDescriptor in descriptor.Commands) {
                var names = commandDescriptor.Name.Split(' ');
                if (!parameters.Arguments.Take(argCount).SequenceEqual(names, StringComparer.OrdinalIgnoreCase)) {
                    // leading arguments not equal to command name
                    continue;
                }

                yield return new Match {
                    Context = new CommandContext {
                        Arguments = parameters.Arguments.Skip(names.Count()),
                        Command = string.Join(" ", names),
                        CommandDescriptor = commandDescriptor,
                        Input = parameters.Input,
                        Output = parameters.Output,
                        Switches = parameters.Switches,
                    },
                    CommandHandlerFactory = handlerFactory
                };
            }
        }
        private IEnumerable<Match> MatchCommands(CommandParameters parameters)
        {
            // Command names are matched with as many arguments as possible, in decreasing order
            foreach (var argCount in Enumerable.Range(1, parameters.Arguments.Count()).Reverse()) {
                int count = argCount;
                var matches = _handlers.SelectMany(h => MatchCommands(parameters, count, GetDescriptor(h.Metadata), h.Value)).ToList();
                if (matches.Any())
                    return matches;
            }

            return Enumerable.Empty<Match>();
        }
        public CommandReturnCodes RunCommand(TextReader input, TextWriter output, string tenant, string[] args, Dictionary<string, string> switches)
        {
            try {
                tenant = tenant ?? ShellSettings.DefaultName;

                using (var env = CreateStandaloneEnvironment(tenant)) {
                    var commandManager = env.Resolve<ICommandManager>();

                    ITransactionManager transactionManager;
                    if (!env.TryResolve(out transactionManager))
                        transactionManager = null;

                    var parameters = new CommandParameters {
                        Arguments = args,
                        Switches = switches,
                        Input = input,
                        Output = output
                    };

                    try {
                        commandManager.Execute(parameters);
                    }
                    catch {
                        // any database changes in this using(env) scope are invalidated
                        if (transactionManager != null)
                            transactionManager.Cancel();

                        // exception handling performed below
                        throw;
                    }
                }

                // in effect "pump messages" see PostMessage circa 1980
                var processingEngine = _hostContainer.Resolve<IProcessingEngine>();
                while (processingEngine.AreTasksPending())
                    processingEngine.ExecuteNextTask();

                return CommandReturnCodes.Ok;
            }
            catch (CoeveryCommandHostRetryException e) {
                // Special "Retry" return code for our host
                output.WriteLine(T("{0} (Retrying...)", e.Message));
                return CommandReturnCodes.Retry;
            }
            catch (Exception e) {
                if (e is TargetInvocationException &&
                    e.InnerException != null) {
                    // If this is an exception coming from reflection and there is an innerexception which is the actual one, redirect
                    e = e.InnerException;
                }

                OutputException(output, T("Error executing command \"{0}\"", string.Join(" ", args)), e);
                return CommandReturnCodes.Fail;
            }
        }
 public void ManagerCanRunACompositeCommand()
 {
     var context = new CommandParameters { Arguments = ("Foo Bar Bleah").Split(' '), Output = new StringWriter() };
     _manager.Execute(context);
     Assert.That(context.Output.ToString(), Is.EqualTo("Bleah"));
 }
 public void ManagerCanRunACommand()
 {
     var context = new CommandParameters { Arguments = new string[] { "FooBar" }, Output = new StringWriter()};
     _manager.Execute(context);
     Assert.That(context.Output.ToString(), Is.EqualTo("success!"));
 }
        public CommandParameters ParseCommandParameters(string command)
        {
            var args = SplitArgs(command);
            var arguments = new List<string>();
            var result = new CommandParameters {
                Switches = new Dictionary<string, string>()
            };

            foreach (var arg in args) {
                // Switch?
                if (arg[0] == '/') {
                    int index = arg.IndexOf(':');
                    var switchName = (index < 0 ? arg.Substring(1) : arg.Substring(1, index - 1));
                    var switchValue = (index < 0 || index >= arg.Length ? string.Empty : arg.Substring(index + 1));

                    if (string.IsNullOrEmpty(switchName))
                    {
                        throw new ArgumentException(string.Format("Invalid switch syntax: \"{0}\". Valid syntax is /<switchName>[:<switchValue>].", arg));
                    }

                    result.Switches.Add(switchName, switchValue);
                }
                else {
                    arguments.Add(arg);
                }
            }

            result.Arguments = arguments;
            return result;
        }