private string GetDocumentation(string key, bool allowReload)
        {
            int hashcode = GetHashCode(key);
            var index    = this.index;          // read volatile field
            // index is sorted, so we can use binary search
            int m = Array.BinarySearch(index, new IndexEntry(hashcode, 0));

            if (m < 0)
            {
                return(null);
            }
            // correct hash code found.
            // possibly there are multiple items with the same hash, so go to the first.
            while (--m >= 0 && index[m].HashCode == hashcode)
            {
                ;
            }
            // m is now 1 before the first item with the correct hash

            XmlDocumentationCache cache = this.cache;

            lock (cache)
            {
                string val;
                if (!cache.TryGet(key, out val))
                {
                    try
                    {
                        // go through all items that have the correct hash
                        while (++m < index.Length && index[m].HashCode == hashcode)
                        {
                            val = LoadDocumentation(key, index[m].PositionInFile);
                            if (val != null)
                            {
                                break;
                            }
                        }
                        // cache the result (even if it is null)
                        cache.Add(key, val);
                    }
                    catch (IOException)
                    {
                        // may happen if the documentation file was deleted/is inaccessible/changed (EndOfStreamException)
                        return(allowReload ? ReloadAndGetDocumentation(key) : null);
                    }
                    catch (XmlException)
                    {
                        // may happen if the documentation file was changed so that the file position no longer starts on a valid XML element
                        return(allowReload ? ReloadAndGetDocumentation(key) : null);
                    }
                }
                return(val);
            }
        }
        /// <summary>
        /// Get the documentation for the member with the specified documentation key.
        /// </summary>
        public string GetDocumentation(string key)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            int hashcode = GetHashCode(key);
            // index is sorted, so we can use binary search
            int m = Array.BinarySearch(index, new IndexEntry(hashcode, 0));

            if (m < 0)
            {
                return(null);
            }
            // correct hash code found.
            // possibly there are multiple items with the same hash, so go to the first.
            while (--m >= 0 && index[m].HashCode == hashcode)
            {
                ;
            }
            // m is now 1 before the first item with the correct hash

            XmlDocumentationCache cache = this.cache;

            lock (cache) {
                string val;
                if (!cache.TryGet(key, out val))
                {
                    // go through all items that have the correct hash
                    while (++m < index.Length && index[m].HashCode == hashcode)
                    {
                        val = LoadDocumentation(key, index[m].PositionInFile);
                        if (val != null)
                        {
                            break;
                        }
                    }
                    // cache the result (even if it is null)
                    cache.Add(key, val);
                }
                return(val);
            }
        }
 public virtual void OnDeserialization(object sender)
 {
     cache = new XmlDocumentationCache();
 }