private static void GenerateTargetContainers(DGMLManager dgml, IList <FrameworkName> targets)
 {
     for (int i = 0; i < targets.Count; i++)
     {
         string targetFramework = targets[i].FullName;
         Guid   nodeGuid        = dgml.GetOrCreateGuid(targetFramework);
         dgml.AddNode(nodeGuid, targetFramework, "Target", null, group: "Expanded");
     }
 }
        public Task WriteStreamAsync(Stream stream, AnalyzeResponse response)
        {
            // Create a new dgml every time write to a new stream.
            var dgml = new DGMLManager();
            var rg   = ReferenceGraph.CreateGraph(response);

            var analysisResult = response.ReportingResult;
            var targets        = analysisResult.Targets;

            GenerateTargetContainers(dgml, targets);
            dgml.SetTitle(response.ApplicationName);

            // For each target, let's generate the assemblies
            foreach (var node in rg.Nodes.Keys)
            {
                for (int i = 0; i < targets.Count; i++)
                {
                    double portabilityIndex = 0, portabilityIndexRefs = 0;
                    string missingTypes = null;
                    if (node.UsageData != null)
                    {
                        TargetUsageInfo usageInfo = node.UsageData[i];
                        portabilityIndex     = node.GetPortabilityIndex(i);
                        portabilityIndexRefs = node.GetPortabilityIndexForReferences(i);

                        missingTypes = GenerateMissingTypes(node.Assembly, analysisResult, i);
                    }

                    // generate the node
                    string tfm          = targets[i].FullName;
                    Guid   nodeGuid     = dgml.GetOrCreateGuid($"{node.Assembly},TFM:{tfm}");
                    string nodeTitle    = $"{node.SimpleName}: {Math.Round(portabilityIndex * 100, 2)}%, References: {Math.Round(portabilityIndexRefs * 100, 2)}%";
                    string nodeCategory = node.IsMissing ? "Unresolved" : GetCategory(Math.Round(portabilityIndex * portabilityIndexRefs * 100, 2));

                    dgml.AddNode(nodeGuid, nodeTitle,
                                 nodeCategory,
                                 portabilityIndex,
                                 group: string.IsNullOrEmpty(missingTypes) ? null : "Collapsed");

                    if (dgml.TryGetId(tfm, out Guid frameworkGuid))
                    {
                        dgml.AddLink(frameworkGuid, nodeGuid, "Contains");
                    }

                    if (!string.IsNullOrEmpty(missingTypes))
                    {
                        Guid commentGuid = Guid.NewGuid();
                        dgml.AddNode(commentGuid, missingTypes, "Comment");
                        dgml.AddLink(nodeGuid, commentGuid, "Contains");
                    }
                }
            }

            // generate the references.
            foreach (var node in rg.Nodes.Keys)
            {
                for (int i = 0; i < targets.Count; i++)
                {
                    // generate the node
                    string tfm      = targets[i].FullName;
                    Guid   nodeGuid = dgml.GetOrCreateGuid($"{node.Assembly},TFM:{tfm}");

                    foreach (var refNode in node.Nodes)
                    {
                        Guid refNodeGuid = dgml.GetOrCreateGuid($"{refNode.Assembly},TFM:{tfm}");
                        dgml.AddLink(nodeGuid, refNodeGuid);
                    }
                }
            }

            dgml.Save(stream);

            return(Task.CompletedTask);
        }