/// <summary>
        /// Creates a <see cref="Page"/> which is a sliced view of
        /// the data source. This method first looks for the datasource
        /// in the <see cref="System.Web.Caching.Cache"/> and if not found,
        /// it invokes the <c>dataObtentionCallback</c> and caches the result
        /// using the specifed <c>cacheKey</c>
        /// </summary>
        /// <param name="cacheKey">Cache key used to query/store the datasource</param>
        /// <param name="pageSize">Page size</param>
        /// <param name="dataObtentionCallback">Callback to be used to populate the cache</param>
        /// <returns>A <see cref="Page"/> instance</returns>
        public static Page CreateCachedPagination(String cacheKey, int pageSize, DataObtentionDelegate dataObtentionCallback)
        {
            IList datasource = (IList)CurrentContext.Cache[cacheKey];

            if (datasource == null)
            {
                datasource = dataObtentionCallback();

                CurrentContext.Cache.Insert(
                    cacheKey, datasource, null,
                    DateTime.MaxValue, TimeSpan.FromSeconds(10));
            }

            return(CreatePagination(datasource, pageSize));
        }
        /// <summary>
        /// Creates a <see cref="Page"/> which is a sliced view of
        /// the data source. This method first looks for the datasource
        /// in the <see cref="System.Web.Caching.Cache"/> and if not found,
        /// it invokes the <c>dataObtentionCallback</c> and caches the result
        /// using the specifed <c>cacheKey</c>
        /// </summary>
        /// <param name="engineContext">The engine context.</param>
        /// <param name="cacheKey">Cache key used to query/store the datasource</param>
        /// <param name="pageSize">Page size</param>
        /// <param name="dataObtentionCallback">Callback to be used to populate the cache</param>
        /// <returns>A <see cref="Page"/> instance</returns>
        /// <remarks>
        /// CreateCachedPagination is quite dangerous exactly because the cache is
        /// shared. If the results vary per logged user, then the programmer must
        /// rather pay a lot of attention when generating the cache key.
        /// It is preferable to have caching happen at a lower level of the stack, for example the NHibernate query cache.
        /// </remarks>
        public static IPaginatedPage CreateCachedPagination(IEngineContext engineContext, String cacheKey, int pageSize,
                                                            DataObtentionDelegate dataObtentionCallback)
        {
            var cacheProvider = engineContext.Services.CacheProvider;
            var datasource    = (IList)cacheProvider.Get(cacheKey);

            if (datasource == null)
            {
                datasource = dataObtentionCallback();

                cacheProvider.Store(cacheKey, datasource);
            }

            return(CreatePagination(engineContext, datasource, pageSize));
        }