void GraphNode(FragmentNode fragmentNode)
        {
            SvgEditor   e             = new SvgEditor();
            SENodeGroup parentsGroup  = new SENodeGroup("parents", false);
            SENodeGroup focusGroup    = new SENodeGroup("focus", false);
            SENodeGroup childrenGroup = new SENodeGroup("children", false);

            parentsGroup.AppendChild(focusGroup);
            focusGroup.AppendChild(childrenGroup);

            {
                SENode node = this.CreateNode(fragmentNode.Focus, Color.Green, false);
                focusGroup.AppendNode(node);
            }

            foreach (ResourceMap.Node childNode in fragmentNode.Children)
            {
                SENode node = this.CreateNode(childNode, Color.LightBlue, true);
                childrenGroup.AppendNode(node);
            }

            foreach (ResourceMap.Node parentNode in fragmentNode.Parents)
            {
                SENode node = this.CreateNode(parentNode, Color.LightCyan, true);
                parentsGroup.AppendNode(node);
            }

            e.Render(parentsGroup, true);
            String svgName       = FragmentMapName(fragmentNode.Focus);
            String outputSvgPath = Path.Combine(this.graphicsDir, svgName);

            this.fc?.Mark(outputSvgPath);
            e.Save(outputSvgPath);

            this.fragmentsBlock
            .AppendLine($"<p>")
            .AppendLine($"Fragment Diagram {fragmentNode.Focus.Name}")
            .AppendLine($"</p>")
            .AppendLine($"<object data=\"{svgName}\" type=\"image/svg+xml\">")
            .AppendLine($"    <img src=\"{svgName}\" alt=\"{fragmentNode.Focus.Name}\"/>")
            .AppendLine($"</object>");
            ;
        }
        void GraphNode(ResourceMap.Node focusNode)
        {
            if (focusNode.Name.Contains("Fragment", new StringComparison()) == true)
            {
                return;
            }
            //Debug.Assert(focusNode.Name != "SectionFindingsLeftBreast");

            SvgEditor   e             = new SvgEditor();
            SENodeGroup parentsGroup  = new SENodeGroup("parents", true);
            SENodeGroup focusGroup    = new SENodeGroup("focus", true);
            SENodeGroup childrenGroup = new SENodeGroup("children", true);

            parentsGroup.AppendChild(focusGroup);
            focusGroup.AppendChild(childrenGroup);
            {
                SENode node = this.CreateResourceNode(focusNode, Color.White, null, false);
                focusGroup.AppendNode(node);
            }
            {
                HashSet <String> alreadyLinkedResources = new HashSet <string>();

                void AddParent(dynamic link,
                               List <SENode> parents)
                {
                    String linkSource = link.LinkSource.ToObject <String>();

                    if (this.map.TryGetNode(linkSource, out ResourceMap.Node parentNode) == false)
                    {
                        throw new Exception($"Parent extension {linkSource} not found in map");
                    }
                    if (alreadyLinkedResources.Contains(parentNode.ResourceUrl) == true)
                    {
                        return;
                    }

                    if (this.map.TryGetNode(parentNode.ResourceUrl, out ResourceMap.Node parentMapNode) == false)
                    {
                        throw new Exception($"Resource '{parentNode.ResourceUrl}' not found!");
                    }

                    alreadyLinkedResources.Add(parentNode.ResourceUrl);
                    SENode node = this.CreateResourceNode(parentNode, this.ReferenceColor(parentMapNode),
                                                          new String[] { null, link.CardinalityLeft?.ToString() },
                                                          true);

                    parents.Add(node);
                }

                List <SENode> componentParents = new List <SENode>();
                List <SENode> extensionParents = new List <SENode>();
                List <SENode> valueSetParents  = new List <SENode>();
                List <SENode> targetParents    = new List <SENode>();

                foreach (dynamic link in this.map.TargetOrReferenceLinks(focusNode.ResourceUrl))
                {
                    switch (link.LinkType.ToObject <String>())
                    {
                    case "fragment":
                        break;

                    default:
                        AddParent(link, componentParents);
                        break;
                    }
                }

                parentsGroup.AppendNodes(targetParents);
                parentsGroup.AppendNodes(componentParents);
                parentsGroup.AppendNodes(valueSetParents);
                parentsGroup.AppendNodes(extensionParents);
            }
            {
                SENodeGroup targetChildren    = new SENodeGroup("A.Targets", true);
                SENodeGroup componentChildren = new SENodeGroup("B.Components", true);
                SENodeGroup extensionChildren = new SENodeGroup("C.Extensions", true);
                SENodeGroup valueSetChildren  = new SENodeGroup("D.ValueSets", true);

                childrenGroup.AppendChild(targetChildren);
                childrenGroup.AppendChild(componentChildren);
                childrenGroup.AppendChild(valueSetChildren);
                childrenGroup.AppendChild(extensionChildren);

                foreach (dynamic link in this.map.SourceLinks(focusNode.ResourceUrl))
                {
                    switch (link.LinkType.ToObject <String>())
                    {
                    case "fragment":
                        break;

                    case SVGGlobal.ComponentType:
                        MakeComponent(link, componentChildren);
                        break;

                    case SVGGlobal.ExtensionType:
                    {
                        String linkSource    = link.LinkSource.ToObject <String>();
                        String componentHRef = link.ComponentHRef.ToObject <String>()
                                               .Replace("{SDName}", linkSource.LastUriPart());

                        SENode node = new SENode(0,
                                                 LinkTypeColor(link),
                                                 new String[] { link.CardinalityLeft?.ToString() },
                                                 componentHRef);
                        node.AddTextLine(link.LocalName.ToObject <String>(), componentHRef);
                        node.AddTextLine("extension", componentHRef);

                        SENodeGroup nodeGroup = new SENodeGroup(node.AllText(), true);
                        extensionChildren.AppendChild(nodeGroup);
                        nodeGroup.AppendNode(node);

                        {
                            SENodeGroup extGroup = new SENodeGroup("extension", true);
                            nodeGroup.AppendChild(extGroup);
                            SENode extNode;
                            String extUrl = link.LinkTarget.ToObject <String>().Trim();
                            if (extUrl.ToLower().StartsWith(Global.BreastRadBaseUrl))
                            {
                                if (this.map.TryGetNode(extUrl, out ResourceMap.Node targetNode) == false)
                                {
                                    throw new Exception($"Component resource '{extUrl}' not found!");
                                }
                                extNode = this.CreateResourceNode(targetNode, this.ReferenceColor(targetNode),
                                                                  new String[] { link.CardinalityLeft?.ToString() },
                                                                  true);
                            }
                            else
                            {
                                String name = extUrl.LastUriPart()
                                              .TrimStart("StructureDefinition-")
                                              .TrimStart("ValueSet-")
                                              .TrimEnd(".html")
                                ;
                                extNode = new SENode(0,
                                                     this.fhirColor,
                                                     new String[] { link.CardinalityLeft?.ToString() },
                                                     extUrl);
                                extNode.AddTextLine(name, extUrl);
                            }

                            extGroup.AppendNode(extNode);
                        }
                    }
                    break;

                    case SVGGlobal.ValueSetType:
                    {
                        if (this.map.TryGetNode(link.LinkTarget.ToObject <String>().ToObject <String>(),
                                                out ResourceMap.Node childNode) == true)
                        {
                            SENode      node      = this.CreateResourceNode(childNode, link, true);
                            SENodeGroup nodeGroup = new SENodeGroup(node.AllText(), false);
                            valueSetChildren.AppendChild(nodeGroup);
                            nodeGroup.AppendNode(node);
                        }
                    }
                    break;

                    case SVGGlobal.TargetType:
                    {
                        if (this.map.TryGetNode(link.LinkTarget.ToObject <String>(),
                                                out ResourceMap.Node childNode) == false)
                        {
                            throw new Exception(
                                      $"Child target {link.LinkTarget.ToObject<String>()} not found in map");
                        }
                        SENode      node      = this.CreateResourceNode(childNode, link, true);
                        SENodeGroup nodeGroup = new SENodeGroup(node.AllText(), true);
                        targetChildren.AppendChild(nodeGroup);
                        nodeGroup.AppendNode(node);
                    }
                    break;

                    default:
                        throw new NotImplementedException($"Unknown link type {link.LinkType.ToObject<String>()}");
                    }
                }
            }

            //parentsGroup.Sort();
            e.Render(parentsGroup, true);
            String outputPath = Path.Combine(this.graphicsDir, FocusMapName(focusNode));

            this.fc?.Mark(outputPath);
            e.Save(outputPath);
        }