private static int Main(string[] args)
        {
            List <string> packages = new List <string>();

            if (args.Length == 0)
            {
                DisplayHelp();
                return(0);
            }

            int?           topCount = null, comboCount = null, runCount = null;
            bool           combo = false;
            int?           seed = null, dumpMembers = null;
            string         packagePath = null, logPath = null, htmlLogPath = null, dirRun = null;
            DependencyType depType = DependencyType.Standard;
            bool           installMissingPackages = false, installAll = false, cleanup = true, lowAnalysis = false, wait = false;
            Dictionary <string, RunStats> stats = null;

            foreach (var arg in args)
            {
                if (arg == "/?" || arg == "--help")
                {
                    DisplayHelp();
                    return(0);
                }
                else if (arg == "/install_missing")
                {
                    installMissingPackages = true;
                }
                else if (arg == "/install_all")
                {
                    installAll = true;
                }
                else if (arg == "/low")
                {
                    lowAnalysis = true;
                }
                else if (arg == "/no_cleanup")
                {
                    cleanup = false;
                }
                else if (arg == "/wait")
                {
                    wait = true;
                }
                else if (arg.StartsWith("/package_list:"))
                {
                    string filename = arg.Substring("/package_list:".Length);
                    try {
                        packages.AddRange(File.ReadAllLines(filename));
                    } catch (Exception e) {
                        Console.WriteLine("Failed to read package list: {0}", filename);
                        Console.WriteLine(e.Message);
                        return(-1);
                    }
                }
                else if (arg.StartsWith("/package:"))
                {
                    string packageName = arg.Substring("/package:".Length);
                    if (String.IsNullOrWhiteSpace(packageName))
                    {
                        Console.WriteLine("Missing package name");
                        return(-3);
                    }
                    foreach (var name in packageName.Split(','))
                    {
                        packages.Add(name.Trim());
                    }
                }
                else if (arg.StartsWith("/dir:"))
                {
                    dirRun = arg.Substring("/dir:".Length);
                    if (String.IsNullOrWhiteSpace(dirRun))
                    {
                        Console.WriteLine("/dir: missing directory name");
                        return(-3);
                    }
                    else if (!Directory.Exists(dirRun))
                    {
                        Console.WriteLine("/dir: Directory does not exist");
                        return(-52);
                    }
                    cleanup = false;
                }
                else if (arg.StartsWith("/log:"))
                {
                    logPath = arg.Substring("/log:".Length);
                    if (String.IsNullOrWhiteSpace(logPath))
                    {
                        Console.WriteLine("Missing log file name");
                        return(-16);
                    }
                }
                else if (arg.StartsWith("/html:"))
                {
                    htmlLogPath = arg.Substring("/html:".Length);
                    if (String.IsNullOrWhiteSpace(htmlLogPath))
                    {
                        Console.WriteLine("Missing HTML log file name");
                        return(-25);
                    }
                }
                else if (arg.StartsWith("/package_path:"))
                {
                    packagePath = arg.Substring("/package_path:".Length);
                    if (String.IsNullOrWhiteSpace(packagePath))
                    {
                        Console.WriteLine("Missing package path");
                        return(-10);
                    }
                    if (!Directory.Exists(packagePath))
                    {
                        Console.WriteLine("Package path directory does not exist");
                        return(-11);
                    }
                }
                else if (arg.StartsWith("/seed:"))
                {
                    int seedInt;
                    if (!Int32.TryParse(arg.Substring("/seed:".Length), out seedInt))
                    {
                        Console.WriteLine("Bad seed value: {0}", arg.Substring("/seed:".Length));
                        return(-8);
                    }
                    seed = seedInt;
                }
                else if (arg.StartsWith("/combo:"))
                {
                    string comboArgs = arg.Substring("/combo:".Length);
                    if (String.IsNullOrWhiteSpace(comboArgs))
                    {
                        Console.WriteLine("Missing combo values");
                        return(-4);
                    }
                    var comboArgsArray = comboArgs.Split(',');
                    if (comboArgsArray.Length != 1 && comboArgsArray.Length != 2)
                    {
                        Console.WriteLine("Invalid number of arguments for combination run: {0}", comboArgs);
                        return(-6);
                    }
                    int comboArgValue;
                    if (!Int32.TryParse(comboArgsArray[0], out comboArgValue))
                    {
                        Console.WriteLine("Invalid package count for combination run: {0}", comboArgsArray[0]);
                        return(-5);
                    }
                    comboCount = comboArgValue;
                    if (comboArgsArray.Length > 1)
                    {
                        if (!Int32.TryParse(comboArgsArray[1], out comboArgValue))
                        {
                            Console.WriteLine("Invalid run count for combination run: {0}", comboArgsArray[1]);
                            return(-7);
                        }
                        runCount = comboArgValue;
                    }
                }
                else if (arg.StartsWith("/combo"))
                {
                    combo = true;
                }
                else if (arg.StartsWith("/devdependencies"))
                {
                    depType = DependencyType.Development;
                }
                else if (arg.StartsWith("/top:"))
                {
                    int topCountInt;
                    if (!Int32.TryParse(arg.Substring("/top:".Length), out topCountInt))
                    {
                        Console.WriteLine("Bad top count: {0}", arg.Substring("/top:".Length));
                        return(-2);
                    }
                    topCount = topCountInt;
                }
                else if (arg.StartsWith("/dump_members:"))
                {
                    int dumpMembersInt;
                    if (!Int32.TryParse(arg.Substring("/dump_members:".Length), out dumpMembersInt))
                    {
                        Console.WriteLine("Bad dump members count: {0}", arg.Substring("/dump_members:".Length));
                        return(-2);
                    }
                    dumpMembers = dumpMembersInt;
                }
                else if (arg.StartsWith("/dump_members"))
                {
                    dumpMembers = 1;
                }
                else if (arg.StartsWith("/baseline:"))
                {
                    stats = new Dictionary <string, RunStats>();
                    string baselinePath = arg.Substring("/baseline:".Length);
                    if (String.IsNullOrWhiteSpace(baselinePath) || !File.Exists(baselinePath))
                    {
                        Console.WriteLine("Bad baseline path: {0}", baselinePath);
                        return(-20);
                    }
                    var baselineEntries = File.ReadAllLines(baselinePath).Skip(1).ToArray();
                    foreach (var line in baselineEntries)
                    {
                        var kvp = RunStats.Parse(line);
                        if (kvp.Key != null)
                        {
                            stats.Add(kvp.Key, kvp.Value);
                        }
                    }
                }
                else
                {
                    Console.WriteLine("Unknown option: {0}", arg);
                    return(-15);
                }
            }


            if (packages.Count == 0)
            {
                Console.WriteLine("No packages were specified");
                return(-9);
            }

            if (topCount != null)
            {
                packages = new List <string>(packages.Where((value, index) => index < topCount.Value));
            }

            if (packagePath == null)
            {
                if (dirRun == null)
                {
                    packagePath = CreateTempDirectoryPath();
                    Console.WriteLine("Packages cached at {0}", packagePath);
                    installMissingPackages = true;
                }
                else
                {
                    packagePath = dirRun;
                }
            }

            Random random;

            if (seed == null)
            {
                seed = Environment.TickCount;
                if (comboCount != null)
                {
                    Console.WriteLine("Seed set to {0}", seed);
                }
            }

            random = new Random(seed.Value);
            TextWriter logger = null, htmlLogger = null;

            if (logPath != null)
            {
                logger = new StreamWriter(logPath);
            }

            if (htmlLogPath != null)
            {
                htmlLogger = new StreamWriter(htmlLogPath);
            }

            using (logger)
                using (htmlLogger)
                    using (var driver = new AnalysisDriver(
                               packages.ToArray(),
                               packagePath,
                               installMissingPackages,
                               installAll,
                               depType,
                               cleanup,
                               wait,
                               random,
                               logger,
                               htmlLogger,
                               dumpMembers,
                               lowAnalysis,
                               stats
                               )) {
                        if (combo)
                        {
                            comboCount = packages.Count;
                            runCount   = 1;
                        }
                        try {
                            if (dirRun != null)
                            {
                                driver.RunDirectory(
                                    dirRun,
                                    Path.GetFileName(dirRun),
                                    packages.ToArray(),
                                    1
                                    );
                            }
                            else if (comboCount == null)
                            {
                                driver.RunAll();
                            }
                            else
                            {
                                for (int i = 0; i < (runCount ?? 1); i++)
                                {
                                    driver.RunCombo(comboCount.Value, i + 1);
                                }
                            }
                        } catch (AssertFailedException e) {
                            Console.WriteLine("Run failed: {0}", e.Message);
                            return(-100);
                        } catch (Exception e) {
                            Console.WriteLine("Error during run: {0}\r\n{1}", e.Message, e.StackTrace);
                            return(-200);
                        }
                    }
            for (int i = 0; i < 3; i++)
            {
                GC.Collect(2);
                GC.WaitForPendingFinalizers();
            }
            //AnalysisValue.DumpStats();
            //VariableDef.DumpStats();
            return(0);
        }
        private static int Main(string[] args) {
            List<string> packages = new List<string>();
            if (args.Length == 0) {
                DisplayHelp();
                return 0;
            }

            int? topCount = null, comboCount = null, runCount = null;
            bool combo = false;
            int? seed = null, dumpMembers = null;
            string packagePath = null, logPath = null, htmlLogPath = null, dirRun = null;
            DependencyType depType = DependencyType.Standard;
            bool installMissingPackages = false, installAll = false, cleanup = true, lowAnalysis = false, wait = false;
            Dictionary<string, RunStats> stats = null;
            foreach (var arg in args) {
                if (arg == "/?" || arg == "--help") {
                    DisplayHelp();
                    return 0;
                } else if (arg == "/install_missing") {
                    installMissingPackages = true;
                } else if (arg == "/install_all") {
                    installAll = true;
                } else if (arg == "/low") {
                    lowAnalysis = true;
                } else if (arg == "/no_cleanup") {
                    cleanup = false;
                } else if (arg == "/wait") {
                    wait = true;
                } else if (arg.StartsWith("/package_list:")) {
                    string filename = arg.Substring("/package_list:".Length);
                    try {
                        packages.AddRange(File.ReadAllLines(filename));
                    } catch (Exception e) {
                        Console.WriteLine("Failed to read package list: {0}", filename);
                        Console.WriteLine(e.Message);
                        return -1;
                    }
                } else if (arg.StartsWith("/package:")) {
                    string packageName = arg.Substring("/package:".Length);
                    if (String.IsNullOrWhiteSpace(packageName)) {
                        Console.WriteLine("Missing package name");
                        return -3;
                    }
                    foreach (var name in packageName.Split(',')) {
                        packages.Add(name.Trim());
                    }
                } else if (arg.StartsWith("/dir:")) {
                    dirRun = arg.Substring("/dir:".Length);
                    if (String.IsNullOrWhiteSpace(dirRun)) {
                        Console.WriteLine("/dir: missing directory name");
                        return -3;
                    } else if (!Directory.Exists(dirRun)) {
                        Console.WriteLine("/dir: Directory does not exist");
                        return -52;
                    }
                    cleanup = false;
                } else if (arg.StartsWith("/log:")) {
                    logPath = arg.Substring("/log:".Length);
                    if (String.IsNullOrWhiteSpace(logPath)) {
                        Console.WriteLine("Missing log file name");
                        return -16;
                    }
                } else if (arg.StartsWith("/html:")) {
                    htmlLogPath = arg.Substring("/html:".Length);
                    if (String.IsNullOrWhiteSpace(htmlLogPath)) {
                        Console.WriteLine("Missing HTML log file name");
                        return -25;
                    }
                } else if (arg.StartsWith("/package_path:")) {
                    packagePath = arg.Substring("/package_path:".Length);
                    if (String.IsNullOrWhiteSpace(packagePath)) {
                        Console.WriteLine("Missing package path");
                        return -10;
                    }
                    if (!Directory.Exists(packagePath)) {
                        Console.WriteLine("Package path directory does not exist");
                        return -11;
                    }
                } else if (arg.StartsWith("/seed:")) {
                    int seedInt;
                    if (!Int32.TryParse(arg.Substring("/seed:".Length), out seedInt)) {
                        Console.WriteLine("Bad seed value: {0}", arg.Substring("/seed:".Length));
                        return -8;
                    }
                    seed = seedInt;
                } else if (arg.StartsWith("/combo:")) {
                    string comboArgs = arg.Substring("/combo:".Length);
                    if (String.IsNullOrWhiteSpace(comboArgs)) {
                        Console.WriteLine("Missing combo values");
                        return -4;
                    }
                    var comboArgsArray = comboArgs.Split(',');
                    if (comboArgsArray.Length != 1 && comboArgsArray.Length != 2) {
                        Console.WriteLine("Invalid number of arguments for combination run: {0}", comboArgs);
                        return -6;
                    }
                    int comboArgValue;
                    if (!Int32.TryParse(comboArgsArray[0], out comboArgValue)) {
                        Console.WriteLine("Invalid package count for combination run: {0}", comboArgsArray[0]);
                        return -5;
                    }
                    comboCount = comboArgValue;
                    if (comboArgsArray.Length > 1) {
                        if (!Int32.TryParse(comboArgsArray[1], out comboArgValue)) {
                            Console.WriteLine("Invalid run count for combination run: {0}", comboArgsArray[1]);
                            return -7;
                        }
                        runCount = comboArgValue;
                    }
                } else if (arg.StartsWith("/combo")) {
                    combo = true;
                } else if (arg.StartsWith("/devdependencies")) {
                    depType = DependencyType.Development;
                } else if (arg.StartsWith("/top:")) {
                    int topCountInt;
                    if (!Int32.TryParse(arg.Substring("/top:".Length), out topCountInt)) {
                        Console.WriteLine("Bad top count: {0}", arg.Substring("/top:".Length));
                        return -2;
                    }
                    topCount = topCountInt;
                } else if (arg.StartsWith("/dump_members:")) {
                    int dumpMembersInt;
                    if (!Int32.TryParse(arg.Substring("/dump_members:".Length), out dumpMembersInt)) {
                        Console.WriteLine("Bad dump members count: {0}", arg.Substring("/dump_members:".Length));
                        return -2;
                    }
                    dumpMembers = dumpMembersInt;
                } else if (arg.StartsWith("/dump_members")) {
                    dumpMembers = 1;
                } else if (arg.StartsWith("/baseline:")) {
                    stats = new Dictionary<string, RunStats>();
                    string baselinePath = arg.Substring("/baseline:".Length);
                    if (String.IsNullOrWhiteSpace(baselinePath) || !File.Exists(baselinePath)) {
                        Console.WriteLine("Bad baseline path: {0}", baselinePath);
                        return -20;
                    }
                    var baselineEntries = File.ReadAllLines(baselinePath).Skip(1).ToArray();
                    foreach (var line in baselineEntries) {
                        var kvp = RunStats.Parse(line);
                        if (kvp.Key != null) {
                            stats.Add(kvp.Key, kvp.Value);
                        }
                    }
                } else {
                    Console.WriteLine("Unknown option: {0}", arg);
                    return -15;
                }
            }


            if (packages.Count == 0) {
                Console.WriteLine("No packages were specified");
                return -9;
            }

            if (topCount != null) {
                packages = new List<string>(packages.Where((value, index) => index < topCount.Value));
            }

            if (packagePath == null) {
                if (dirRun == null) {
                    packagePath = CreateTempDirectoryPath();
                    Console.WriteLine("Packages cached at {0}", packagePath);
                    installMissingPackages = true;
                } else {
                    packagePath = dirRun;
                }
            }

            Random random;
            if (seed == null) {
                seed = Environment.TickCount;
                if (comboCount != null) {
                    Console.WriteLine("Seed set to {0}", seed);
                }
            }

            random = new Random(seed.Value);
            TextWriter logger = null, htmlLogger = null;
            if (logPath != null) {
                logger = new StreamWriter(logPath);
            }

            if (htmlLogPath != null) {
                htmlLogger = new StreamWriter(htmlLogPath);
            }

            using (logger)
            using (htmlLogger)
            using (var driver = new AnalysisDriver(
                    packages.ToArray(),
                    packagePath,
                    installMissingPackages,
                    installAll,
                    depType,
                    cleanup,
                    wait,
                    random,
                    logger,
                    htmlLogger,
                    dumpMembers,
                    lowAnalysis,
                    stats
                )) {
                if (combo) {
                    comboCount = packages.Count;
                    runCount = 1;
                }
                try {
                    if (dirRun != null) {
                        driver.RunDirectory(
                            dirRun,
                            Path.GetFileName(dirRun),
                            packages.ToArray(),
                            1
                        );
                    } else if (comboCount == null) {
                        driver.RunAll();
                    } else {
                        for (int i = 0; i < (runCount ?? 1); i++) {
                            driver.RunCombo(comboCount.Value, i + 1);
                        }
                    }
                } catch (AssertFailedException e) {
                    Console.WriteLine("Run failed: {0}", e.Message);
                    return -100;
                } catch (Exception e) {
                    Console.WriteLine("Error during run: {0}\r\n{1}", e.Message, e.StackTrace);
                    return -200;
                }
            }
            for (int i = 0; i < 3; i++) {
                GC.Collect(2);
                GC.WaitForPendingFinalizers();
            }
            //AnalysisValue.DumpStats();
            //VariableDef.DumpStats();
            return 0;
        }