/// <summary>
        /// Obtain an <see cref="INamedCache"/> interface that provides a view
        /// of resources shared among members of a cluster.
        /// </summary>
        /// <remarks>
        /// The view is identified by name within this ICacheService.
        /// Typically, repeated calls to this method with the same view name
        /// will result in the same view reference being returned.
        /// </remarks>
        /// <param name="name">
        /// The name, within this ICacheService, that uniquely identifies a
        /// view; <c>null</c> is legal, and may imply a default name.
        /// </param>
        /// <returns>
        /// An <b>INamedCache</b> interface which can be used to access the
        /// resources of the specified view.
        /// </returns>
        /// <exception cref="InvalidOperationException">
        /// If the service is not running.
        /// </exception>
        public virtual INamedCache EnsureCache(string name)
        {
            if (StringUtils.IsNullOrEmpty(name))
            {
                name = "Default";
            }

            ScopedReferenceStore storeCache = StoreRemoteNamedCache;
            RemoteNamedCache     cache      = storeCache.GetCache(name)
                                              as RemoteNamedCache;

            if (cache == null || !cache.IsActive)
            {
                lock (storeCache)
                {
                    cache = storeCache.GetCache(name) as RemoteNamedCache;
                    if (cache == null || !cache.IsActive)
                    {
                        cache = CreateRemoteNamedCache(name);
                        storeCache.PutCache(cache);
                    }
                }
            }

            return(cache);
        }
        /// <summary>
        /// Obtain an <see cref="INamedCache"/> interface that provides a view
        /// of resources shared among members of a cluster.
        /// </summary>
        /// <remarks>
        /// The view is identified by name within this ICacheService.
        /// Typically, repeated calls to this method with the same view name
        /// will result in the same view reference being returned.
        /// </remarks>
        /// <param name="name">
        /// The name, within this ICacheService, that uniquely identifies a
        /// view; <c>null</c> is legal, and may imply a default name.
        /// </param>
        /// <returns>
        /// An <b>INamedCache</b> interface which can be used to access the
        /// resources of the specified view.
        /// </returns>
        /// <exception cref="InvalidOperationException">
        /// If the service is not running.
        /// </exception>
        public INamedCache EnsureCache(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                name = "Default";
            }

            ScopedReferenceStore storeCache = StoreSafeNamedCache;
            SafeNamedCache       cacheSafe  = (SafeNamedCache)storeCache.GetCache(name);

            if (cacheSafe == null)
            {
                lock (storeCache)
                {
                    INamedCache cache = RunningCacheService.EnsureCache(name);

                    cacheSafe = new SafeNamedCache
                    {
                        SafeCacheService = this,
                        CacheName        = name,
                        NamedCache       = cache,
                        Principal        = Thread.CurrentPrincipal
                    };

                    storeCache.PutCache(cacheSafe);
                }
            }

            return(cacheSafe);
        }
        /// <summary>
        /// Removes <see cref="SafeNamedCache"/> from the
        /// <see cref="ScopedReferenceStore"/>.
        /// </summary>
        /// <param name="cacheSafe">
        /// <b>SafeNamedCache</b> to be removed.
        /// </param>
        protected virtual void RemoveCacheReference(SafeNamedCache cacheSafe)
        {
            cacheSafe.IsReleased = true;

            ScopedReferenceStore storeCache = StoreSafeNamedCache;

            lock (storeCache)
            {
                storeCache.ReleaseCache(cacheSafe);
            }
        }
        /// <summary>
        /// Cleanup used resources.
        /// </summary>
        protected override void Cleanup()
        {
            base.Cleanup();

            ScopedReferenceStore storeCache = StoreSafeNamedCache;

            lock (storeCache)
            {
                storeCache.Clear();
            }
        }
        /// <summary>
        /// Releases all the caches fetched from the store and then clears the store.
        /// </summary>
        public virtual void ReleaseCaches()
        {
            ScopedReferenceStore storeCache = StoreRemoteNamedCache;

            lock (storeCache)
            {
                for (IEnumerator iter = storeCache.GetAllCaches().GetEnumerator(); iter.MoveNext();)
                {
                    RemoteNamedCache cache = (RemoteNamedCache)iter.Current;
                    ReleaseRemoteNamedCache(cache as RemoteNamedCache);
                }
                storeCache.Clear();
            }
        }
        /// <summary>
        /// Release local resources associated with the specified instance of
        /// the cache.
        /// </summary>
        /// <remarks>
        /// <p>
        /// This invalidates a reference obtained by using the
        /// <see cref="ICacheService.EnsureCache"/> method.</p>
        /// <p>
        /// Releasing a reference to a cache makes the cache reference no
        /// longer usable, but does not affect the cache itself. In other
        /// words, all other references to the cache will still be valid, and
        /// the cache data is not affected by releasing the reference.</p>
        /// <p>
        /// The reference that is released using this method can no longer be
        /// used; any attempt to use the reference will result in an
        /// exception.</p>
        /// </remarks>
        /// <param name="cache">
        /// The cache object to be released.
        /// </param>
        public virtual void ReleaseCache(INamedCache cache)
        {
            if (!(cache is RemoteNamedCache))
            {
                throw new ArgumentException("illegal cache: " + cache);
            }

            ScopedReferenceStore storeCache = StoreRemoteNamedCache;

            lock (storeCache)
            {
                storeCache.ReleaseCache(cache);
            }
            ReleaseRemoteNamedCache(cache as RemoteNamedCache);
        }