public override bool TryParse(string[] rawArgs, out VfsCasConfiguration arguments) { var cli = new CommandLineUtilities(rawArgs); var config = new VfsCasConfiguration.Builder(); Dictionary <string, OptionHandler> handlers = new OptionHandler[] { new OptionHandler(new[] { "serverPort", "sp" }, opt => config.ServerGrpcPort = (int)ParseUInt32Option(opt, 0, ushort.MaxValue)), new OptionHandler(new[] { "backingPort", "bp" }, opt => config.BackingGrpcPort = (int)ParseUInt32Option(opt, 0, ushort.MaxValue)), new OptionHandler(new[] { "root" }, opt => config.RootPath = new AbsolutePath(ParsePathOption(opt))), new OptionHandler(new[] { "cacheName" }, opt => config.CacheName = ParseStringOption(opt)), new OptionHandler(new[] { "scenario" }, opt => config.Scenario = ParseStringOption(opt), required: false), new OptionHandler(new[] { "virtualizationMount", "vm" }, opt => { var kvp = ParseKeyValuePair(opt); config.VirtualizationMounts[kvp.Key] = new AbsolutePath(GetFullPath(kvp.Value, opt)); }, required: false), } .SelectMany(handler => handler.Names.Select(name => (name, handler))) .ToDictionary(t => t.name, t => t.handler, StringComparer.OrdinalIgnoreCase); foreach (var opt in cli.Options) { if (opt.Name == "?" || opt.Name == "help") { // TODO: Help text } if (handlers.TryGetValue(opt.Name, out var handler)) { handler.Handle(opt); handler.Occurrences++; } else { throw new InvalidArgumentException($"Unrecognized option {opt.Name}"); } } foreach (var handler in handlers.Values.Where(h => h.Occurrences == 0 && h.Required)) { throw new InvalidArgumentException($"Option '{handler.Names[0]}' is required."); } arguments = config.Build(); return(true); }