private CachedDocument GetDocument(string assemblyPath)
        {
            assemblyPath = Path.GetFullPath(assemblyPath);

            lock (cachedDocuments)
            {
                CachedDocument document;
                if (cachedDocuments.TryGetValue(assemblyPath, out document))
                {
                    return(document);
                }

                if (assemblyPath != null)
                {
                    string documentPath = Path.ChangeExtension(assemblyPath, @".xml");

                    if (File.Exists(documentPath))
                    {
                        document = CachedDocument.Load(documentPath);
                        cachedDocuments.Add(assemblyPath, document);
                        return(document);
                    }
                }

                cachedDocuments.Add(assemblyPath, null);
                return(null);
            }
        }
            public static CachedDocument Load(string documentPath)
            {
                // This is optimized somewhat to avoid reading in the XML document
                // as a big lump of objects.  We just need the contents; the structure
                // itself is irrelevant.

                CachedDocument document = new CachedDocument();

                XmlReaderSettings settings = new XmlReaderSettings();

                settings.IgnoreWhitespace             = false; // needed for whitespace normalization to work within comments
                settings.IgnoreProcessingInstructions = true;
                settings.IgnoreComments  = true;
                settings.ValidationType  = ValidationType.None;
                settings.ProhibitDtd     = true;
                settings.CheckCharacters = false;
                settings.CloseInput      = true;

                using (XmlReader reader = XmlReader.Create(documentPath, settings))
                {
                    for (; ;)
                    {
                        if (reader.NodeType == XmlNodeType.Element)
                        {
                            if (reader.Name == @"member")
                            {
                                string name    = reader.GetAttribute(@"name");
                                string content = NormalizeWhitespace(reader.ReadInnerXml());

                                // Note: The member name might not be unique if the XML file
                                //       is malformed.  So we keep the last occurrence only.
                                document.members[name] = content;
                                continue;
                            }
                            else if (reader.Name != @"doc" && reader.Name != @"members")
                            {
                                reader.Skip();
                                continue;
                            }
                        }

                        if (!reader.Read())
                        {
                            break;
                        }
                    }
                }

                return(document);
            }
        /// <inheritdoc />
        public string GetXmlDocumentation(string assemblyPath, string memberId)
        {
            if (assemblyPath == null)
            {
                throw new ArgumentNullException("assemblyPath");
            }
            if (memberId == null)
            {
                throw new ArgumentNullException("memberId");
            }

            CachedDocument document = GetDocument(assemblyPath);

            return(document != null?document.GetXmlDocumentation(memberId) : null);
        }
            public static CachedDocument Load(string documentPath)
            {
                // This is optimized somewhat to avoid reading in the XML document
                // as a big lump of objects.  We just need the contents; the structure
                // itself is irrelevant.

                CachedDocument document = new CachedDocument();

                XmlReaderSettings settings = new XmlReaderSettings();
                settings.IgnoreWhitespace = false; // needed for whitespace normalization to work within comments
                settings.IgnoreProcessingInstructions = true;
                settings.IgnoreComments = true;
                settings.ValidationType = ValidationType.None;
                settings.DtdProcessing = DtdProcessing.Prohibit;
                settings.CheckCharacters = false;
                settings.CloseInput = true;

                using (XmlReader reader = XmlReader.Create(documentPath, settings))
                {
                    for (; ; )
                    {
                        if (reader.NodeType == XmlNodeType.Element)
                        {
                            if (reader.Name == @"member")
                            {
                                string name = reader.GetAttribute(@"name");
                                string content = NormalizeWhitespace(reader.ReadInnerXml());

                                // Note: The member name might not be unique if the XML file
                                //       is malformed.  So we keep the last occurrence only.
                                document.members[name] = content;
                                continue;
                            }
                            else if (reader.Name != @"doc" && reader.Name != @"members")
                            {
                                reader.Skip();
                                continue;
                            }
                        }

                        if (!reader.Read())
                            break;
                    }
                }

                return document;
            }