public CommandLineManagerImplementation(string[] commandLineArgs)
        {
            runFromCommandLine        = false;
            coverageResultsPath       = string.Empty;
            coverageHistoryPath       = string.Empty;
            sourcePaths               = string.Empty;
            generateAdditionalMetrics = false;
            generateHTMLReportHistory = false;
            generateHTMLReport        = false;
            generateBadgeReport       = false;
            useProjectSettings        = false;
            assemblyFiltersSpecified  = false;
            pathFiltersSpecified      = false;
            pathStrippingSpecified    = false;
            sourcePathsSpecified      = false;
            assemblyFiltering         = new AssemblyFiltering();
            pathFiltering             = new PathFiltering();
            pathStripping             = new PathStripping();
            runTests      = false;
            batchmode     = false;
            burstDisabled = false;

            m_CoverageOptionsArg    = string.Empty;
            m_CoverageOptions       = new string[] { };
            m_IncludeAssemblies     = string.Empty;
            m_ExcludeAssemblies     = string.Empty;
            m_IncludePaths          = string.Empty;
            m_ExcludePaths          = string.Empty;
            m_PathStrippingPatterns = string.Empty;

            CommandLineOptionSet optionSet = new CommandLineOptionSet(
                new CommandLineOption("enableCodeCoverage", () => { runFromCommandLine = true; }),
                new CommandLineOption("coverageResultsPath", filePathArg => { SetCoverageResultsPath(filePathArg); }),
                new CommandLineOption("coverageHistoryPath", filePathArg => { SetCoverageHistoryPath(filePathArg); }),
                new CommandLineOption("coverageOptions", optionsArg => { AddCoverageOptions(optionsArg); }),
                new CommandLineOption("runTests", () => { runTests = true; }),
                new CommandLineOption("batchmode", () => { batchmode = true; }),
                new CommandLineOption("burst-disable-compilation", () => { burstDisabled = true; })
                );

            optionSet.Parse(commandLineArgs);

            ValidateCoverageResultsPath();
            ValidateCoverageHistoryPath();

            if (runFromCommandLine)
            {
                ParseCoverageOptions();
            }
        }
        protected override TreeViewItem BuildRoot()
        {
            string[] includeAssemblyFilters = m_AssembliesToInclude.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

            Regex[] includeAssemblies = includeAssemblyFilters
                                        .Select(f => AssemblyFiltering.CreateFilterRegex(f))
                                        .ToArray();

            TreeViewItem root = new TreeViewItem(-1, -1);

            Assembly[] assemblies = CompilationPipeline.GetAssemblies();
            Array.Sort(assemblies, (x, y) => String.Compare(x.name, y.name));

            int assembliesLength = assemblies.Length;

            GUIContent textContent = new GUIContent();

            for (int i = 0; i < assembliesLength; ++i)
            {
                Assembly assembly = assemblies[i];
                bool     enabled  = includeAssemblies.Any(f => f.IsMatch(assembly.name.ToLowerInvariant()));
                root.AddChild(new AssembliesTreeViewItem()
                {
                    id = i + 1, displayName = assembly.name, Enabled = enabled
                });

                textContent.text = assembly.name;
                float itemWidth = TreeView.DefaultStyles.label.CalcSize(textContent).x + kCheckBoxWidth;
                if (Width < itemWidth)
                {
                    Width = itemWidth;
                }
            }

            return(root);
        }
        private void ParseCoverageOptions()
        {
            m_CoverageOptions = m_CoverageOptionsArg.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

            foreach (string optionArgsStr in m_CoverageOptions)
            {
                if (optionArgsStr.Length == 0)
                {
                    continue;
                }

                string optionName = optionArgsStr;
                string optionArgs = string.Empty;

                int indexOfColon = optionArgsStr.IndexOf(':');
                if (indexOfColon > 0)
                {
                    optionName = optionArgsStr.Substring(0, indexOfColon);
                    optionArgs = optionArgsStr.Substring(indexOfColon + 1);
                }

                switch (optionName.ToUpperInvariant())
                {
                case "GENERATEADDITIONALMETRICS":
                    generateAdditionalMetrics = true;
                    break;

                case "GENERATEHTMLREPORTHISTORY":
                    generateHTMLReportHistory = true;
                    break;

                case "GENERATEHTMLREPORT":
                    generateHTMLReport = true;
                    break;

                case "GENERATEBADGEREPORT":
                    generateBadgeReport = true;
                    break;

                case "USEPROJECTSETTINGS":
                    if (batchmode)
                    {
                        useProjectSettings = true;
                    }
                    else
                    {
                        ResultsLogger.Log(ResultID.Warning_UseProjectSettingsNonBatchmode);
                    }
                    break;

                case "VERBOSITY":
                    if (optionArgs.Length > 0)
                    {
                        switch (optionArgs.ToUpperInvariant())
                        {
                        case "VERBOSE":
                            ResultsLogger.VerbosityLevel = LogVerbosityLevel.Verbose;
                            break;

                        case "INFO":
                            ResultsLogger.VerbosityLevel = LogVerbosityLevel.Info;
                            break;

                        case "WARNING":
                            ResultsLogger.VerbosityLevel = LogVerbosityLevel.Warning;
                            break;

                        case "ERROR":
                            ResultsLogger.VerbosityLevel = LogVerbosityLevel.Error;
                            break;

                        case "OFF":
                            ResultsLogger.VerbosityLevel = LogVerbosityLevel.Off;
                            break;
                        }
                    }
                    break;

                case "ASSEMBLYFILTERS":
                    if (optionArgs.Length > 0)
                    {
                        assemblyFiltersSpecified = true;

                        string[] assemblyFilters = optionArgs.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                        for (int i = 0; i < assemblyFilters.Length; ++i)
                        {
                            string filter     = assemblyFilters[i];
                            string filterBody = filter.Length > 1 ? filter.Substring(1) : string.Empty;

                            if (filter.StartsWith("+", StringComparison.OrdinalIgnoreCase))
                            {
                                if (m_IncludeAssemblies.Length > 0)
                                {
                                    m_IncludeAssemblies += ",";
                                }

                                if (filterBody.StartsWith("<", StringComparison.OrdinalIgnoreCase))
                                {
                                    if (string.Equals(filterBody, AssemblyFiltering.kUserAlias, StringComparison.OrdinalIgnoreCase))
                                    {
                                        m_IncludeAssemblies += AssemblyFiltering.GetUserOnlyAssembliesString();
                                    }
                                    else if (string.Equals(filterBody, AssemblyFiltering.kProjectAlias, StringComparison.OrdinalIgnoreCase))
                                    {
                                        m_IncludeAssemblies += AssemblyFiltering.GetAllProjectAssembliesString();
                                    }
                                    else if (string.Equals(filterBody, AssemblyFiltering.kPackagesAlias, StringComparison.OrdinalIgnoreCase))
                                    {
                                        m_IncludeAssemblies += AssemblyFiltering.GetPackagesOnlyAssembliesString();
                                    }
                                    else if (string.Equals(filterBody, AssemblyFiltering.kAllAlias, StringComparison.OrdinalIgnoreCase))
                                    {
                                        m_IncludeAssemblies += "*";
                                    }
                                }
                                else
                                {
                                    m_IncludeAssemblies += filterBody;
                                }
                            }
                            else if (filter.StartsWith("-", StringComparison.OrdinalIgnoreCase))
                            {
                                if (m_ExcludeAssemblies.Length > 0)
                                {
                                    m_ExcludeAssemblies += ",";
                                }

                                if (filterBody.StartsWith("<", StringComparison.OrdinalIgnoreCase))
                                {
                                    if (string.Equals(filterBody, AssemblyFiltering.kUserAlias, StringComparison.OrdinalIgnoreCase))
                                    {
                                        m_ExcludeAssemblies += AssemblyFiltering.GetUserOnlyAssembliesString();
                                    }
                                    else if (string.Equals(filterBody, AssemblyFiltering.kProjectAlias, StringComparison.OrdinalIgnoreCase))
                                    {
                                        m_ExcludeAssemblies += AssemblyFiltering.GetAllProjectAssembliesString();
                                    }
                                    else if (string.Equals(filterBody, AssemblyFiltering.kPackagesAlias, StringComparison.OrdinalIgnoreCase))
                                    {
                                        m_ExcludeAssemblies += AssemblyFiltering.GetPackagesOnlyAssembliesString();
                                    }
                                    else if (string.Equals(filterBody, AssemblyFiltering.kAllAlias, StringComparison.OrdinalIgnoreCase))
                                    {
                                        m_ExcludeAssemblies += "*";
                                    }
                                }
                                else
                                {
                                    m_ExcludeAssemblies += filterBody;
                                }
                            }
                            else
                            {
                                ResultsLogger.Log(ResultID.Warning_AssemblyFiltersNotPrefixed, filter);
                            }
                        }
                    }
                    break;

                case "PATHFILTERS":
                    if (optionArgs.Length > 0)
                    {
                        pathFiltersSpecified = true;

                        string[] pathFilters = optionArgs.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                        for (int i = 0; i < pathFilters.Length; ++i)
                        {
                            string filter     = pathFilters[i];
                            string filterBody = filter.Length > 1 ? filter.Substring(1) : string.Empty;

                            if (filter.StartsWith("+", StringComparison.OrdinalIgnoreCase))
                            {
                                if (m_IncludePaths.Length > 0)
                                {
                                    m_IncludePaths += ",";
                                }
                                m_IncludePaths += filterBody;
                            }
                            else if (filter.StartsWith("-", StringComparison.OrdinalIgnoreCase))
                            {
                                if (m_ExcludePaths.Length > 0)
                                {
                                    m_ExcludePaths += ",";
                                }
                                m_ExcludePaths += filterBody;
                            }
                            else
                            {
                                ResultsLogger.Log(ResultID.Warning_PathFiltersNotPrefixed, filter);
                            }
                        }
                    }
                    break;

                case "PATHSTRIPPINGPATTERNS":
                    if (optionArgs.Length > 0)
                    {
                        pathStrippingSpecified  = true;
                        m_PathStrippingPatterns = optionArgs;
                    }
                    break;

                case "SOURCEPATHS":
                    if (optionArgs.Length > 0)
                    {
                        sourcePathsSpecified = true;

                        string[] rawSourcePaths = optionArgs.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                        for (int i = 0; i < rawSourcePaths.Length; ++i)
                        {
                            if (sourcePaths.Length > 0)
                            {
                                sourcePaths += ",";
                            }
                            sourcePaths += CoverageUtils.NormaliseFolderSeparators(rawSourcePaths[i]);
                        }
                    }
                    break;
                }
            }

            if (m_IncludeAssemblies.Length == 0)
            {
                // If there are no inlcudedAssemblies specified but there are includedPaths specified
                // then include all project assemblies so path filtering can take precedence over assembly filtering,
                // othewise if there are no includedPaths specified neither then inlcude just the user assemblies (found under the Assets folder)

                if (m_IncludePaths.Length > 0)
                {
                    m_IncludeAssemblies = AssemblyFiltering.GetAllProjectAssembliesString();
                }
                else
                {
                    m_IncludeAssemblies = AssemblyFiltering.GetUserOnlyAssembliesString();
                }
            }

            if (m_ExcludeAssemblies.Length > 0)
            {
                m_ExcludeAssemblies += ",";
            }

            m_ExcludeAssemblies += AssemblyFiltering.kDefaultExcludedAssemblies;

            assemblyFiltering.Parse(m_IncludeAssemblies, m_ExcludeAssemblies);
            pathFiltering.Parse(m_IncludePaths, m_ExcludePaths);
            pathStripping.Parse(m_PathStrippingPatterns);
        }
        public void Generate(CoverageSettings coverageSettings)
        {
            CoverageRunData.instance.ReportGenerationStart();

            if (coverageSettings == null)
            {
                EditorUtility.ClearProgressBar();
                ResultsLogger.Log(ResultID.Warning_FailedReportNullCoverageSettings);
                CoverageRunData.instance.ReportGenerationEnd(false);
                return;
            }

            string includeAssemblies = string.Empty;

            if (CommandLineManager.instance.batchmode && !CommandLineManager.instance.useProjectSettings)
            {
                includeAssemblies = CommandLineManager.instance.assemblyFiltering.includedAssemblies;
            }
            else
            {
                includeAssemblies = CommandLineManager.instance.assemblyFiltersSpecified ?
                                    CommandLineManager.instance.assemblyFiltering.includedAssemblies :
                                    CoveragePreferences.instance.GetString("IncludeAssemblies", AssemblyFiltering.GetUserOnlyAssembliesString());
            }

            // If override for include assemblies is set in coverageSettings, use overrideIncludeAssemblies instead
            if (!String.IsNullOrEmpty(coverageSettings.overrideIncludeAssemblies))
            {
                includeAssemblies = coverageSettings.overrideIncludeAssemblies;
            }

            string[] includeAssembliesArray = includeAssemblies.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < includeAssembliesArray.Length; i++)
            {
                includeAssembliesArray[i] = "+" + includeAssembliesArray[i];
            }
            string assemblies = string.Join(",", includeAssembliesArray);

            string[] assemblyFilters = assemblies.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

            if (assemblyFilters.Length == 0)
            {
                EditorUtility.ClearProgressBar();
                ResultsLogger.Log(ResultID.Error_FailedReportNoAssemblies);
                CoverageRunData.instance.ReportGenerationEnd(false);
                return;
            }

            string rootFolderPath = coverageSettings.rootFolderPath;

            if (!CoverageUtils.DoesFolderExistAndNotEmpty(rootFolderPath) || CoverageUtils.GetNumberOfFilesInFolder(rootFolderPath, "*.xml", SearchOption.AllDirectories) == 0)
            {
                EditorUtility.ClearProgressBar();
                ResultsLogger.Log(ResultID.Error_FailedReportNoTests);
                CoverageRunData.instance.ReportGenerationEnd(false);
                return;
            }

            // Only include xml files with the correct filename format
            string sourceXmlPath           = CoverageUtils.JoinPaths(rootFolderPath, "**");
            string testResultsXmlPath      = CoverageUtils.JoinPaths(sourceXmlPath, "TestCoverageResults_????.xml");
            string recordingResultsXmlPath = CoverageUtils.JoinPaths(sourceXmlPath, "RecordingCoverageResults_????.xml");

            string[] reportFilePatterns = new string[] { testResultsXmlPath, recordingResultsXmlPath };

            bool includeHistoryInReport = CommandLineManager.instance.batchmode && !CommandLineManager.instance.useProjectSettings ?
                                          CommandLineManager.instance.generateHTMLReportHistory :
                                          CommandLineManager.instance.generateHTMLReportHistory || CoveragePreferences.instance.GetBool("IncludeHistoryInReport", true);

            string historyDirectory = includeHistoryInReport ? coverageSettings.historyFolderPath : null;

            string targetDirectory = CoverageUtils.JoinPaths(rootFolderPath, CoverageSettings.ReportFolderName);

            string[] sourceDirectories = CommandLineManager.instance.sourcePathsSpecified ? CommandLineManager.instance.sourcePaths.Split(',') : new string[] { };

            bool generateHTMLReport = CommandLineManager.instance.batchmode && !CommandLineManager.instance.useProjectSettings ?
                                      CommandLineManager.instance.generateHTMLReport :
                                      CommandLineManager.instance.generateHTMLReport || CoveragePreferences.instance.GetBool("GenerateHTMLReport", true);

            if (coverageSettings.overrideGenerateReport)
            {
                generateHTMLReport = true;
            }

            bool generateBadge = CommandLineManager.instance.batchmode && !CommandLineManager.instance.useProjectSettings ?
                                 CommandLineManager.instance.generateBadgeReport :
                                 CommandLineManager.instance.generateBadgeReport || CoveragePreferences.instance.GetBool("GenerateBadge", true);

            string reportTypesString = "xmlSummary,";

            if (generateHTMLReport)
            {
                reportTypesString += "Html,";
            }
            if (generateBadge)
            {
                reportTypesString += "Badges,";
            }

            string[] reportTypes = reportTypesString.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            string[] plugins     = new string[] { };

            bool includeAdditionalMetrics = CommandLineManager.instance.batchmode && !CommandLineManager.instance.useProjectSettings ?
                                            CommandLineManager.instance.generateAdditionalMetrics :
                                            CommandLineManager.instance.generateAdditionalMetrics || CoveragePreferences.instance.GetBool("GenerateAdditionalMetrics", false);

            string[] classFilters   = new string[] { };
            string[] fileFilters    = new string[] { };
            string   verbosityLevel = null;
            string   tag            = null;

            ReportConfiguration config = new ReportConfiguration(
                reportFilePatterns,
                targetDirectory,
                sourceDirectories,
                historyDirectory,
                reportTypes,
                plugins,
                assemblyFilters,
                classFilters,
                fileFilters,
                verbosityLevel,
                tag);

            DebugFactory loggerFactory = new DebugFactory();

            LoggerFactory.Configure(loggerFactory);

            try
            {
                if (!CommandLineManager.instance.batchmode)
                {
                    EditorUtility.DisplayProgressBar(ReportGeneratorStyles.ProgressTitle.text, ReportGeneratorStyles.ProgressInfo.text, 0.4f);
                }

                if (Directory.Exists(targetDirectory))
                {
                    Directory.Delete(targetDirectory, true);
                }

                Generator generator = new Generator();
                if (generator.GenerateReport(config, new Settings()
                {
                    DisableRiskHotspots = !includeAdditionalMetrics
                }, new RiskHotspotsAnalysisThresholds()))
                {
                    ResultsLogger.Log(ResultID.Log_ReportSaved, targetDirectory);

                    CoverageRunData.instance.ReportGenerationEnd(true);

                    // Send Analytics event (Report Only / Data & Report)
                    CoverageAnalytics.instance.SendCoverageEvent(true);

                    if (!CommandLineManager.instance.batchmode &&
                        coverageSettings.revealReportInFinder)
                    {
                        string indexHtm = CoverageUtils.JoinPaths(targetDirectory, "index.htm");
                        if (File.Exists(indexHtm))
                        {
                            EditorUtility.RevealInFinder(indexHtm);
                        }
                        else
                        {
                            EditorUtility.RevealInFinder(targetDirectory);
                        }
                    }
                }
                else
                {
                    ResultsLogger.Log(ResultID.Error_FailedReport);

                    CoverageRunData.instance.ReportGenerationEnd(false);
                }
            }
            finally
            {
                EditorUtility.ClearProgressBar();
            }
        }