internal string CompareDirectoryDependencySummary(ConcurrentDictionary <string, DependencySummary <string> > otherDirectorySummary, string otherLogPath)
        {
            var directoriesNotInTwo = SummaryAnalyzer.GetDependencyDiff(m_analyzer.Summary.DirectorySummary, otherDirectorySummary).ToList();
            var directoriesNotInOne = SummaryAnalyzer.GetDependencyDiff(otherDirectorySummary, m_analyzer.Summary.DirectorySummary).ToList();

            // Directory dependencies in some PIPs are distinct.
            using (var output = new StringWriter(CultureInfo.InvariantCulture))
            {
                var hadOutput = false;
                int longest   = directoriesNotInOne.Select(s => s.Name.Length).Concat(new[] { 50 }).Max();
                longest = directoriesNotInTwo.Select(s => s.Name.Length).Concat(new[] { longest }).Max();

                // List the differences
                output.WriteLine("List differences between a summary of distinct directory dependencies");
                output.WriteLine("defined in process pips between execution log current and previous.");
                output.WriteLine("=====================================================================");
                string formatString = "{0,-" + longest + "} | {1,19} | {2, 15} | {3, 6} | {4, 6}";
                output.WriteLine("Top Directory Dependency Differences:");
                output.WriteLine("Current Execution Log = {0}", m_analyzer.ExecutionLogPath);
                output.WriteLine("Previous Execution Log = {0}", otherLogPath);
                output.WriteLine(formatString, "Directory Dependency", "Pip Reference count", "% Pip Reference", "Current", "Previous");

                foreach (var s in directoriesNotInTwo)
                {
                    var referencePercentage = m_analyzer.GetProcessPipCount() > 0
                        ? (int)((s.Count * 100) / m_analyzer.GetProcessPipCount())
                        : 0;
                    output.WriteLine(formatString, s.Name.ToLowerInvariant(), s.Count, referencePercentage, "yes", "no");
                    hadOutput = true;
                }

                foreach (var s in directoriesNotInOne)
                {
                    var referencePercentage = m_analyzer.GetProcessPipCount() > 0
                        ? (int)((s.Count * 100) / m_analyzer.GetProcessPipCount())
                        : 0;
                    output.WriteLine(formatString, s.Name.ToLowerInvariant(), s.Count, referencePercentage, "no", "yes");
                    hadOutput = true;
                }

                return(hadOutput ? output.ToString() : "Top Directory Dependency Differences: none");
            }
        }
        /// <summary>
        /// Writes the artifact reason for execution when comparing the two pips into the csv file.
        /// The pips comparared are the roots in order of longest critical path and only its difference is written. No transitive down pips are compared.
        /// </summary>
        private void PrintTransitiveDependenciesImpact(StreamWriter writer)
        {
            var summariesToReport = m_analyzer.GetDifferecesToReport();

            // keep track of distinct dependencies
            var fileArtifacts        = new HashSet <FileArtifactSummary>();
            var environmentVariables = new HashSet <DependencySummary <string> >();
            var observedInputs       = new HashSet <ObservedInputSummary>();

            foreach (var pipDiff in summariesToReport.OrderByDescending(a => a.pipSummary1.CriticalPath.Time))
            {
                var pipSummary      = pipDiff.pipSummary1;
                var otherPipSummary = pipDiff.pipSummary2;

                if (pipSummary.NewPip)
                {
                    continue;
                }

                // TODO: add removed dependencies in output
                if (!pipSummary.Fingerprint.Equals(otherPipSummary.Fingerprint))
                {
                    var filesDiff = SummaryAnalyzer.GetFileDependencyDiff(pipSummary.DependencySummary, otherPipSummary.DependencySummary).ToList();
                    foreach (var item in filesDiff)
                    {
                        if (item.CachedCount > 0)
                        {
                            // This was reported cached in other pips so it has not changed
                            continue;
                        }

                        if (item.OutputOrigin == PipOutputOrigin.Produced || fileArtifacts.Contains(item))
                        {
                            // Output file so not interesting or already written
                            continue;
                        }

                        PrintCsvArtifact(writer, pipSummary, item, "Input", item.GetHashName());
                        fileArtifacts.Add(item);
                    }

                    var environmentDiff = SummaryAnalyzer.GetDependencyDiff(pipSummary.EnvironmentSummary, otherPipSummary.EnvironmentSummary).ToList();
                    foreach (var item in environmentDiff)
                    {
                        if (!environmentVariables.Contains(item))
                        {
                            PrintCsvArtifact(writer, pipSummary, item, "EnvironmentVariable", string.Empty);
                            environmentVariables.Add(item);
                        }
                    }
                }

                var observedDiff = SummaryAnalyzer.GetFileDependencyDiff(pipSummary.ObservedInputSummary, otherPipSummary.ObservedInputSummary).ToList();
                foreach (var item in observedDiff)
                {
                    if (item.CachedCount > 0)
                    {
                        // This was reported cached in other pips so it has not changed
                        continue;
                    }

                    if (!observedInputs.Contains(item))
                    {
                        PrintCsvArtifact(writer, pipSummary, item, "ObservedInput", item.GetHashName());
                        observedInputs.Add(item);
                    }
                }
            }
        }