private void SaveGraph(IdentityMemberships identityMemberships, string outputFilePath)
        {
            var graph    = new VstsMembershipsDirectedGraph(identityMemberships, IdentityNamesToCollapse);
            var document = graph.CreateGraph();

            document.Save(outputFilePath);
        }
        public IdentityMemberships GetRootIdentityMemberships()
        {
            var rootIdentity = new IdentityMemberships
            {
                DisplayName      = $"{TFIdentityCategory.ProjectCollection}",
                Category         = TFIdentityCategory.ProjectCollection,
                NestedIdentities = GetRootNestedIdentities()
            };

            return(rootIdentity);
        }
        private Guid AddIdentityNodes(IdentityMemberships identity)
        {
            var parentNodeId = AddNode(identity);

            foreach (var childIdentity in identity.NestedIdentities)
            {
                var childNodeId = AddIdentityNodes(childIdentity);
                AddLink(parentNodeId, childNodeId);
            }
            return(parentNodeId);
        }
        private static IEnumerable <IdentityMemberships> GetTeamProjectsMemberships(
            IdentityMemberships root, string filter)
        {
            if (root.DisplayName.EndsWith(filter))
            {
                return new[] { root }
            }
            ;

            return(root
                   .NestedIdentities
                   .SelectMany(e => GetTeamProjectsMemberships(e, filter)));
        }
        private void SaveProjectsGraph(IdentityMemberships projectCollectionMemberships)
        {
            var projectFilterName      = @"\Project Valid Users";
            var teamProjectMemberships = GetTeamProjectsMemberships(projectCollectionMemberships, projectFilterName);

            foreach (var memberships in teamProjectMemberships)
            {
                var projectName = memberships.DisplayName
                                  .Replace(projectFilterName, string.Empty)
                                  .Replace("[", string.Empty)
                                  .Replace("]", string.Empty);

                var projectOutputFile = Path.Combine(DiagramOutputDir, $"{projectName}.dgml");
                SaveGraph(memberships, projectOutputFile);
            }
        }
        private Guid AddNode(IdentityMemberships identity)
        {
            var id             = Guid.NewGuid();
            var label          = identity.DisplayName;
            var seenBefore     = _nodes.Elements().Any(e => e.Attributes("Label").Any(a => a.Value == label));
            var shouldCollapse = seenBefore ||
                                 identity.NestedIdentities.Length == 0 ||
                                 _identitiesToCollapse.Contains(identity.DisplayName);

            var node = new XElement(DgmlNamespace + "Node",
                                    new XAttribute("Id", id),
                                    new XAttribute("Label", label),
                                    new XAttribute("Category", identity.Category),
                                    new XAttribute("Group", shouldCollapse ? "Collapsed" : "Expanded"));

            _nodes.Add(node);
            return(id);
        }
        public VstsMembershipsDirectedGraph(IdentityMemberships rootIdentity, string[] identitiesToCollapse)
        {
            _rootIdentity         = rootIdentity;
            _identitiesToCollapse = identitiesToCollapse;

            _graph = new XDocument(
                new XElement(DgmlNamespace + "DirectedGraph",
                             new XAttribute("GraphDirection", "TopToBottom"),
                             new XAttribute("Layout", "ForceDirected"),
                             new XElement(NodesXName),
                             new XElement(LinksXName),
                             new XElement(CategoriesXName),
                             new XElement(StylesXName)));

            if (_graph.Root == null)
            {
                throw new InvalidOperationException("Root of the XDocument is null.");
            }

            _nodes      = _graph.Root.Element(NodesXName);
            _links      = _graph.Root.Element(LinksXName);
            _categories = _graph.Root.Element(CategoriesXName);
            _styles     = _graph.Root.Element(StylesXName);
        }