private XmlDocumentation GetXmlDocumentation(IAssemblySymbol assembly, string preferredCultureName = null)
        {
            if (!_xmlDocumentations.TryGetValue(assembly, out XmlDocumentation xmlDocumentation))
            {
                if (Assemblies.Contains(assembly))
                {
                    Compilation compilation = FindCompilation(assembly);

                    MetadataReference metadataReference = compilation.GetMetadataReference(assembly);

                    if (metadataReference is PortableExecutableReference portableExecutableReference)
                    {
                        string path = portableExecutableReference.FilePath;

                        if (preferredCultureName != null)
                        {
                            path = Path.GetDirectoryName(path);

                            path = Path.Combine(path, preferredCultureName);

                            if (Directory.Exists(path))
                            {
                                string fileName = Path.ChangeExtension(Path.GetFileNameWithoutExtension(path), "xml");

                                path = Path.Combine(path, fileName);

                                if (File.Exists(path))
                                {
                                    xmlDocumentation = XmlDocumentation.Load(path);
                                }
                            }
                        }

                        if (xmlDocumentation == null)
                        {
                            path = Path.ChangeExtension(path, "xml");

                            if (File.Exists(path))
                            {
                                xmlDocumentation = XmlDocumentation.Load(path);
                            }
                        }
                    }
                }

                _xmlDocumentations[assembly] = xmlDocumentation;
            }

            return(xmlDocumentation);
        }
        public SymbolXmlDocumentation GetXmlDocumentation(ISymbol symbol, string preferredCultureName = null)
        {
            if (_symbolData.TryGetValue(symbol, out SymbolDocumentationData data) &&
                data.XmlDocumentation != null)
            {
                if (object.ReferenceEquals(data.XmlDocumentation, SymbolXmlDocumentation.Default))
                {
                    return(null);
                }

                return(data.XmlDocumentation);
            }

            IAssemblySymbol assembly = FindAssembly();

            if (assembly != null)
            {
                SymbolXmlDocumentation xmlDocumentation = GetXmlDocumentation(assembly, preferredCultureName)?.GetXmlDocumentation(symbol);

                if (xmlDocumentation != null)
                {
                    _symbolData[symbol] = data.WithXmlDocumentation(xmlDocumentation);
                    return(xmlDocumentation);
                }

                CultureInfo preferredCulture = null;

                if (preferredCultureName != null &&
                    !_cultures.TryGetValue(preferredCultureName, out preferredCulture))
                {
                    preferredCulture = ImmutableInterlocked.GetOrAdd(ref _cultures, preferredCultureName, f => new CultureInfo(f));
                }

                string xml = symbol.GetDocumentationCommentXml(preferredCulture: preferredCulture, expandIncludes: true);

                if (!string.IsNullOrEmpty(xml))
                {
                    xml = XmlDocumentation.Unindent(xml);

                    XElement element = XElement.Parse(xml, LoadOptions.PreserveWhitespace);

                    xmlDocumentation = new SymbolXmlDocumentation(symbol, element);

                    _symbolData[symbol] = data.WithXmlDocumentation(xmlDocumentation);
                    return(xmlDocumentation);
                }
            }

            if (!_additionalXmlDocumentationPaths.IsDefault)
            {
                if (_additionalXmlDocumentations.IsDefault)
                {
                    _additionalXmlDocumentations = _additionalXmlDocumentationPaths
                                                   .Select(f => XmlDocumentation.Load(f))
                                                   .ToImmutableArray();
                }

                string commentId = symbol.GetDocumentationCommentId();

                foreach (XmlDocumentation xmlDocumentation in _additionalXmlDocumentations)
                {
                    SymbolXmlDocumentation documentation = xmlDocumentation.GetXmlDocumentation(symbol, commentId);

                    if (documentation != null)
                    {
                        _symbolData[symbol] = data.WithXmlDocumentation(documentation);
                        return(documentation);
                    }
                }
            }

            _symbolData[symbol] = data.WithXmlDocumentation(SymbolXmlDocumentation.Default);
            return(null);

            IAssemblySymbol FindAssembly()
            {
                foreach (IAssemblySymbol a in Assemblies)
                {
                    if (symbol.ContainingAssembly == a)
                    {
                        return(a);
                    }
                }

                return(null);
            }
        }
        public SymbolXmlDocumentation GetXmlDocumentation(ISymbol symbol, string preferredCultureName = null)
        {
            if (_symbolData.TryGetValue(symbol, out SymbolDocumentationData data) &&
                data.XmlDocumentation != null)
            {
                if (object.ReferenceEquals(data.XmlDocumentation, SymbolXmlDocumentation.Default))
                {
                    return(null);
                }

                return(data.XmlDocumentation);
            }

            IAssemblySymbol assembly = FindAssembly();

            if (assembly != null)
            {
                SymbolXmlDocumentation xmlDocumentation = GetXmlDocumentation(assembly, preferredCultureName)?.GetXmlDocumentation(symbol);

                if (xmlDocumentation != null)
                {
                    _symbolData[symbol] = data.WithXmlDocumentation(xmlDocumentation);
                    return(xmlDocumentation);
                }
            }

            if (!_additionalXmlDocumentationPaths.IsDefault)
            {
                if (_additionalXmlDocumentations.IsDefault)
                {
                    _additionalXmlDocumentations = _additionalXmlDocumentationPaths
                                                   .Select(f => XmlDocumentation.Load(f))
                                                   .ToImmutableArray();
                }

                string commentId = symbol.GetDocumentationCommentId();

                foreach (XmlDocumentation xmlDocumentation in _additionalXmlDocumentations)
                {
                    SymbolXmlDocumentation documentation = xmlDocumentation.GetXmlDocumentation(symbol, commentId);

                    if (documentation != null)
                    {
                        _symbolData[symbol] = data.WithXmlDocumentation(documentation);
                        return(documentation);
                    }
                }
            }

            _symbolData[symbol] = data.WithXmlDocumentation(SymbolXmlDocumentation.Default);
            return(null);

            IAssemblySymbol FindAssembly()
            {
                foreach (IAssemblySymbol a in Assemblies)
                {
                    if (symbol.ContainingAssembly == a)
                    {
                        return(a);
                    }
                }

                return(null);
            }
        }