public void AddProcessType(Type processType,
                                   string registeredName        = null,
                                   string registeredDescription = null)
        {
            string key = string.Format("T{0:000}", 1 + _processTypes.Count);

            var candidate = new IncludedProcessType(processType, key, registeredName,
                                                    registeredDescription);

            if (!IncludeObsolete && candidate.Obsolete)
            {
                return;
            }

            _processTypes.Add(candidate);
        }
        private static void WriteEntryTitleRow(XmlWriter writer,
                                               IncludedProcessType processType)
        {
            writer.WriteStartElement("tr");

            writer.WriteStartElement("td");
            writer.WriteAttributeString("colspan", "3");
            writer.WriteAttributeString("class",
                                        processType.Obsolete ? "obsoleteTitle" : "entryTitle");

            writer.WriteValue(processType.Name);

            if (!string.IsNullOrEmpty(processType.Key))
            {
                writer.WriteStartElement("a");
                writer.WriteAttributeString("id", processType.Key);
                writer.WriteEndElement();                 // a
            }

            writer.WriteEndElement();             // td

            writer.WriteEndElement();             // tr
        }
        private void WriteIndex(XmlWriter writer)
        {
            WriteSectionTitleRow(writer, "Index");

            if (_processTypes.Count < 1)
            {
                return;
            }

            var list = new List <IncludedProcessType>(_processTypes);

            list.Sort(delegate(IncludedProcessType a, IncludedProcessType b)
            {
                int order = string.Compare(a.Name, b.Name,
                                           StringComparison.CurrentCultureIgnoreCase);
                return(order == 0
                                               ? string.CompareOrdinal(a.Key, b.Key)
                                               : order);
            });

            // <tr><td colspan=3><b>Process Types:</b><br/> t1, t2, etc.</td></tr>);
            writer.WriteStartElement("tr");
            writer.WriteStartElement("td");
            writer.WriteAttributeString("colspan", "3");

            writer.WriteElementString("b", "Process Types:");
            writer.WriteStartElement("br");
            writer.WriteEndElement();             // br - does this create an empty <br/>?

            string lastTypeName = null;

            for (var i = 0; i < list.Count; i++)
            {
                IncludedProcessType processType = list[i];

                if (i > 0)
                {
                    writer.WriteString(", ");
                    writer.WriteString(Environment.NewLine);
                }

                if (string.Equals(processType.Name, lastTypeName))
                {
                    // (<a href="#key">other instance</a>)
                    writer.WriteString("(");
                    writer.WriteStartElement("a");
                    writer.WriteAttributeString("href", string.Concat("#", processType.Key));
                    writer.WriteValue("another instance");
                    writer.WriteEndElement();                     // a
                    writer.WriteString(")");
                }
                else
                {
                    // <a href="#key" title="desc">name</a>
                    writer.WriteStartElement("a");
                    writer.WriteAttributeString("href", string.Concat("#", processType.Key));
                    if (!string.IsNullOrEmpty(processType.Description))
                    {
                        writer.WriteAttributeString("title", processType.Description);
                    }

                    writer.WriteValue(processType.Name);
                    writer.WriteEndElement();                     // a
                }

                lastTypeName = processType.Name;
            }

            writer.WriteEndElement();             // td
            writer.WriteEndElement();             // tr

            // Part 2: the "Registered As" index

            list.Sort(delegate(IncludedProcessType a, IncludedProcessType b)
            {
                int order = string.Compare(a.RegisteredName, b.RegisteredName,
                                           StringComparison.CurrentCultureIgnoreCase);
                return(order == 0
                                               ? string.CompareOrdinal(a.Key, b.Key)
                                               : order);
            });

            if (string.IsNullOrEmpty(list[0].RegisteredName))
            {
                return;
            }

            // <tr><td colspan=3><b>Registered As:</b><br/> t1, t2, etc.</td></tr>);
            writer.WriteStartElement("tr");
            writer.WriteStartElement("td");
            writer.WriteAttributeString("colspan", "3");

            writer.WriteElementString("b", "Registered As:");
            writer.WriteStartElement("br");
            writer.WriteEndElement();             // br - does this create an empty <br/>?
            string lastRegisteredName = null;

            for (var i = 0; i < list.Count; i++)
            {
                IncludedProcessType processType = list[i];

                if (i > 0)
                {
                    writer.WriteString(", ");
                    writer.WriteString(Environment.NewLine);
                }

                if (string.Equals(processType.RegisteredName, lastRegisteredName))
                {
                    // (<a href="#key">duplicate</a>)
                    writer.WriteString("(");
                    writer.WriteStartElement("a");
                    writer.WriteAttributeString("href", string.Concat("#", processType.Key));
                    writer.WriteValue("duplicate");
                    writer.WriteEndElement();                     // a
                    writer.WriteString(")");
                }
                else
                {
                    // <a href="#key" title="reg.desc">reg.name</a>
                    writer.WriteStartElement("a");
                    writer.WriteAttributeString("href", string.Concat("#", processType.Key));
                    if (!string.IsNullOrEmpty(processType.RegisteredDescription))
                    {
                        writer.WriteAttributeString("title", processType.RegisteredDescription);
                    }

                    writer.WriteValue(Assert.NotNull(processType.RegisteredName));
                    writer.WriteEndElement();                     // a
                }

                lastRegisteredName = processType.RegisteredName;
            }

            writer.WriteEndElement();             // td
            writer.WriteEndElement();             // tr
        }