protected static CommandLineConfig Parse(params String[] args) { var frames = new StackTrace().GetFrames().Select(f => { var m = f.GetMethod(); var decl = m.DeclaringType; while (decl != null && decl.IsCompilerGenerated()) decl = decl.DeclaringType; return decl; }).ToReadOnly(); frames = frames.SkipWhile(decl => decl == null || decl == typeof(CommandLineConfig)).ToReadOnly(); frames = frames.SkipWhile(decl => decl == null || decl == typeof(Func)).ToReadOnly(); frames = frames.SkipWhile(decl => decl == null || decl == typeof(CommandLineConfig)).ToReadOnly(); var t = frames.AssertFirst(decl => decl != null && decl != typeof(CommandLineConfig)); try { var ctor = t.GetConstructors(BF.All).Single(ci => ci.Params().SingleOrDefault2() == typeof(String[])); return (CommandLineConfig)ctor.Invoke(args.MkArray()); } catch (TargetInvocationException tie) { var cex = tie.InnerException as ConfigException; if (cex != null) { var error = Logger.Get(t).Error; if (cex.Message != null) { if (args.Last() != "/verbose") { var asm_name = t.Assembly.GetName().Name; var cfg_name = t.Attr<ConfigAttribute>().Name; error.WriteLine("Command line was: {0} {1}", cfg_name ?? asm_name, args.StringJoin(" ")); } error.WriteLine(cex.Message); } error.EnsureBlankLine(); Banners.Help(); return null; } else { throw; } } }