/// <summary>
        /// Return the <see cref="IConfigurableCache"/> that uses this eviction
        /// policy.
        /// </summary>
        /// <remarks>
        /// If the <b>LocalCache</b> property has not been intialized, it is
        /// set to the <b>LocalCache</b> that raised the given event.
        /// </remarks>
        /// <param name="evt">
        /// The <see cref="CacheEventArgs"/> raised by the <b>LocalCache</b>
        /// that uses this eviction policy.
        /// </param>
        /// <returns>
        /// The <b>LocalCache</b> that uses this eviction policy.
        /// </returns>
        protected virtual IConfigurableCache EnsureCache(CacheEventArgs evt)
        {
            IConfigurableCache cache = m_cache;

            if (cache == null)
            {
                try
                {
                    cache = m_cache = (IConfigurableCache)evt.Cache;
                }
                catch (InvalidCastException)
                {
                    throw new InvalidCastException("Illegal cache type: " +
                                                   evt.Cache.GetType().Name);
                }
            }
            return(cache);
        }
        /// <summary>
        /// Return the cache entry associated with the given cache event.
        /// </summary>
        /// <param name="evt">
        /// A cache event raised by the <see cref="IConfigurableCache"/>
        /// that uses this eviction policy.
        /// </param>
        /// <returns>
        /// The cache entry associated with the given event.
        /// </returns>
        protected virtual IConfigurableCacheEntry GetEntry(CacheEventArgs evt)
        {
            IConfigurableCache cache = EnsureCache(evt);

            // if the IConfigurableCache.GetCacheEntry() implementation
            // causes an eviction or notifies the eviction policy that the
            // entry has been touched, we'll go into an infinite recursion
            try
            {
                return(cache.GetCacheEntry(evt.Key));
            }
            catch (StackOverflowException)
            {
                throw new StackOverflowException(cache.GetType().FullName
                                                 + "#GetCacheEntry() implementation causes an infinite"
                                                 + " recursion when used with " + GetType().FullName
                                                 + "#getEntry() implementation (inherited from "
                                                 + typeof(AbstractEvictionPolicy).FullName + ")");
            }
        }