private void OnResolveRequestCache(object sender, EventArgs e)
        {
            bool cached = false;

            if (_app == null || _app.Context == null || !_app.Response.ContentType.Equals("text/html", StringComparison.InvariantCultureIgnoreCase) || _app.Context.Request.IsAuthenticated || _app.Context.Request.Browser.Crawler)
            {
                return;
            }

            if (IsInstallInProgress(_app))
            {
                return;
            }

            if (_app.Context.Request.RequestType == "POST" || !(_app.Context.Request.Url.LocalPath.EndsWith(Globals.glbDefaultPage, StringComparison.InvariantCultureIgnoreCase)))
            {
                return;
            }
            var portalSettings = (PortalSettings)(HttpContext.Current.Items["PortalSettings"]);
            int tabId          = portalSettings.ActiveTab.TabID;

            Hashtable tabSettings = TabController.Instance.GetTabSettings(tabId);

            if (tabSettings["CacheProvider"] == null || string.IsNullOrEmpty(tabSettings["CacheProvider"].ToString()))
            {
                return;
            }

            int    portalId = portalSettings.PortalId;
            string locale   = Localization.GetPageLocale(portalSettings).Name;

            IncludeExcludeType includeExclude = IncludeExcludeType.ExcludeByDefault;

            if (tabSettings["CacheIncludeExclude"] != null && !string.IsNullOrEmpty(tabSettings["CacheIncludeExclude"].ToString()))
            {
                if (tabSettings["CacheIncludeExclude"].ToString() == "0")
                {
                    includeExclude = IncludeExcludeType.ExcludeByDefault;
                }
                else
                {
                    includeExclude = IncludeExcludeType.IncludeByDefault;
                }
            }


            string tabOutputCacheProvider = tabSettings["CacheProvider"].ToString();

            _app.Context.Items[ContextKeyTabOutputCacheProvider] = tabOutputCacheProvider;
            int maxCachedVariationsForTab = 250; //by default, prevent DOS attacks

            if (tabSettings["MaxVaryByCount"] != null && !string.IsNullOrEmpty(tabSettings["MaxVaryByCount"].ToString()))
            {
                maxCachedVariationsForTab = Convert.ToInt32(tabSettings["MaxVaryByCount"].ToString());
            }

            var includeVaryByKeys = new StringCollection();

            includeVaryByKeys.Add("ctl");
            includeVaryByKeys.Add("returnurl");
            includeVaryByKeys.Add("tabid");
            includeVaryByKeys.Add("portalid");
            includeVaryByKeys.Add("locale");
            includeVaryByKeys.Add("alias");
            //make sure to always add keys in lowercase only

            if (includeExclude == IncludeExcludeType.ExcludeByDefault)
            {
                string includeVaryByKeysSettings = string.Empty;
                if (tabSettings["IncludeVaryBy"] != null)
                {
                    includeVaryByKeysSettings = tabSettings["IncludeVaryBy"].ToString();
                }

                if (!string.IsNullOrEmpty(includeVaryByKeysSettings))
                {
                    if (includeVaryByKeysSettings.Contains(","))
                    {
                        string[] keys = includeVaryByKeysSettings.Split(',');
                        foreach (string key in keys)
                        {
                            includeVaryByKeys.Add(key.Trim().ToLowerInvariant());
                        }
                    }
                    else
                    {
                        includeVaryByKeys.Add(includeVaryByKeysSettings.Trim().ToLowerInvariant());
                    }
                }
            }
            var excludeVaryByKeys = new StringCollection();

            if (includeExclude == IncludeExcludeType.IncludeByDefault)
            {
                string excludeVaryByKeysSettings = string.Empty;
                if (tabSettings["ExcludeVaryBy"] != null)
                {
                    excludeVaryByKeysSettings = tabSettings["ExcludeVaryBy"].ToString();
                }

                if (!string.IsNullOrEmpty(excludeVaryByKeysSettings))
                {
                    if (excludeVaryByKeysSettings.Contains(","))
                    {
                        string[] keys = excludeVaryByKeysSettings.Split(',');
                        foreach (string key in keys)
                        {
                            excludeVaryByKeys.Add(key.Trim().ToLowerInvariant());
                        }
                    }
                    else
                    {
                        excludeVaryByKeys.Add(excludeVaryByKeysSettings.Trim().ToLowerInvariant());
                    }
                }
            }

            var varyBy = new SortedDictionary <string, string>();

            foreach (string key in _app.Context.Request.QueryString)
            {
                if (key != null && _app.Context.Request.QueryString[key] != null)
                {
                    var varyKey = key.ToLowerInvariant();
                    varyBy.Add(varyKey, _app.Context.Request.QueryString[key]);

                    if (includeExclude == IncludeExcludeType.IncludeByDefault && !includeVaryByKeys.Contains(varyKey))
                    {
                        includeVaryByKeys.Add(varyKey);
                    }
                }
            }
            if (!(varyBy.ContainsKey("portalid")))
            {
                varyBy.Add("portalid", portalId.ToString());
            }
            if (!(varyBy.ContainsKey("tabid")))
            {
                varyBy.Add("tabid", tabId.ToString());
            }
            if (!(varyBy.ContainsKey("locale")))
            {
                varyBy.Add("locale", locale);
            }
            if (!(varyBy.ContainsKey("alias")))
            {
                varyBy.Add("alias", portalSettings.PortalAlias.HTTPAlias);
            }


            string cacheKey = OutputCachingProvider.Instance(tabOutputCacheProvider).GenerateCacheKey(tabId, includeVaryByKeys, excludeVaryByKeys, varyBy);

            bool returnedFromCache = OutputCachingProvider.Instance(tabOutputCacheProvider).StreamOutput(tabId, cacheKey, _app.Context);

            if (returnedFromCache)
            {
                //output the content type heade when read content from cache.
                _app.Context.Response.AddHeader("Content-Type", string.Format("{0}; charset={1}", _app.Response.ContentType, _app.Response.Charset));
                //This is to give a site owner the ability
                //to visually verify that a page was rendered via
                //the output cache.  Use FireFox FireBug or another
                //tool to view the response headers easily.
                _app.Context.Response.AddHeader("DNNOutputCache", "true");

                //Also add it ti the Context - the Headers are readonly unless using IIS in Integrated Pipleine mode
                //and we need to know if OutPut Caching is active in the compression module
                _app.Context.Items.Add("DNNOutputCache", "true");

                _app.Context.Response.End();
                cached = true;
            }

            _app.Context.Items[ContextKeyTabId] = tabId;

            if (cached != true)
            {
                if (tabSettings["CacheDuration"] != null && !string.IsNullOrEmpty(tabSettings["CacheDuration"].ToString()) && Convert.ToInt32(tabSettings["CacheDuration"].ToString()) > 0)
                {
                    int seconds  = Convert.ToInt32(tabSettings["CacheDuration"].ToString());
                    var duration = new TimeSpan(0, 0, seconds);

                    OutputCacheResponseFilter responseFilter = OutputCachingProvider.Instance(_app.Context.Items[ContextKeyTabOutputCacheProvider].ToString()).GetResponseFilter(Convert.ToInt32(_app.Context.Items[ContextKeyTabId]),
                                                                                                                                                                                 maxCachedVariationsForTab,
                                                                                                                                                                                 _app.Response.Filter,
                                                                                                                                                                                 cacheKey,
                                                                                                                                                                                 duration);
                    _app.Context.Items[ContextKeyResponseFilter] = responseFilter;
                    _app.Context.Response.Filter = responseFilter;
                }
            }
        }
        /*
         *      public void OnBeginRequest(object s, EventArgs e)
         *      {
         *          var app = (HttpApplication)s;
         *          var server = app.Server;
         *          var request = app.Request;
         *          var response = app.Response;
         *
         *
         *          //if (RewriterUtils.OmitFromRewriteProcessing(request.Url.LocalPath))
         *          //{
         *          //    return;
         *          //}
         *
         *
         *          //'Carry out first time initialization tasks
         *          //Initialize.Init(app);
         *
         *          if (request.Url.LocalPath.ToLower().EndsWith("/install/install.aspx")
         || request.Url.LocalPath.ToLower().EndsWith("/install/upgradewizard.aspx")
         || request.Url.LocalPath.ToLower().EndsWith("/install/installwizard.aspx")
         || request.Url.LocalPath.ToLower().EndsWith("captcha.aspx")
         || request.Url.LocalPath.ToLower().EndsWith("scriptresource.axd")
         || request.Url.LocalPath.ToLower().EndsWith("webresource.axd")
         || request.Url.LocalPath.ToLower().EndsWith(".ashx")
         ||             )
         ||         {
         ||             return;
         ||         }
         ||
         ||         var AbsoluteUri = app.Request.Url.AbsoluteUri;
         ||         string portalAlias;
         ||         PortalAliasInfo portal = GetPortalAlias(app, out portalAlias);
         ||         if (portal != null)
         ||         {
         ||             CacheController CacheCtrl = new CacheController(portal.PortalID);
         ||             var CacheItem = CacheCtrl.GetItem(AbsoluteUri);
         ||
         ||             if (CacheItem != null)
         ||             {
         ||                 if (IsCachable(app)){
         ||                     app.Context.Items["OpenOutputCache:CacheKey"] = CacheItem.CacheKey;
         ||                 }
         ||
         ||
         ||                 //string sendToUrl = "~/Portals/0/Cache/Output/55_65E28BECAA964E5BE8F2284FF6380489.data.html";
         ||                 //Satrabel.HttpModules.RewriterUtils.RewriteUrl(app.Context, sendToUrl);
         ||
         ||
         ||                 //var queryString = string.Empty;
         ||                 //string sendToUrlLessQString = sendToUrl;
         ||                 //if ((sendToUrl.IndexOf("?") > 0))
         ||                 //{
         ||                 //    sendToUrlLessQString = sendToUrl.Substring(0, sendToUrl.IndexOf("?"));
         ||                 //    queryString = sendToUrl.Substring(sendToUrl.IndexOf("?") + 1);
         ||                 //}
         ||
         ||                 //grab the file's physical path
         ||                 //string filePath = string.Empty;
         ||                 //filePath = app.Context.Server.MapPath(sendToUrlLessQString);
         ||
         ||                 //rewrite the path..
         ||                 //app.Context.RewritePath(sendToUrlLessQString, String.Empty, queryString);
         ||
         ||             }
         ||         }
         ||     }
         */
        private void OnResolveRequestCache(object sender, EventArgs e)
        {
            HttpApplication app = (HttpApplication)sender;

            if (!IsCachable(app))
            {
                return;
            }
            HttpContext context = app.Context;

            try
            {
                //string CacheKey = app.Context.Items["OpenOutputCache:CacheKey"];
                PortalSettings ps = PortalController.GetCurrentPortalSettings();
                if (ps == null || ps.ActiveTab == null || ps.ActiveTab.TabID == Null.NullInteger)
                {
                    return;
                }
                int       TabId         = ps.ActiveTab.TabID;
                var       tc            = new TabController();
                Hashtable tabSettings   = tc.GetTabSettings(TabId);
                string    CacheProvider = GetTabSettingAsString(tabSettings, "CacheProvider");
                if (string.IsNullOrEmpty(CacheProvider))
                {
                    return;
                }
                OutputCachingProvider provider = OutputCachingProvider.Instance(CacheProvider);
                //string CurrentCulture = Localization.GetPageLocale(ps).Name;
                StringCollection includeVaryByKeys;
                StringCollection excludeVaryByKeys;
                GetVarBy(tabSettings, out includeVaryByKeys, out excludeVaryByKeys, ps.PortalId);
                SortedDictionary <string, string> varyBy = new SortedDictionary <string, string>();
                bool VaryAll = includeVaryByKeys.Count == 0;
                foreach (string key in app.Context.Request.QueryString.Keys)
                {
                    try
                    {
                        // prevent error on invalid querystring eg http://domain.com/?p1=valeu1&value2
                        if (string.IsNullOrWhiteSpace(key))
                        {
                            string referrer = app.Context.Request.UrlReferrer == null ? "none" : app.Context.Request.UrlReferrer.AbsoluteUri;
                            Logger.Warn($"Invalid Querystring in url. Request: {app.Context.Request.Url.AbsoluteUri}.  Referrer: {referrer}");
                            continue;
                        }

                        string qs = app.Context.Request.QueryString[key];
                        // end bughunt
                        varyBy.Add(key.ToLower(), qs);
                        if (VaryAll)
                        {
                            includeVaryByKeys.Add(key.ToLower());
                        }
                        else
                        {
                            if (!includeVaryByKeys.Contains(key) && !excludeVaryByKeys.Contains(key))
                            {
                                return;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new Exception($"Error while processing QueryString. Request: {app.Context.Request.Url.AbsoluteUri}", ex);
                    }
                }
                if (PortalController.GetPortalSettingAsBoolean("OOC_VaryByBrowser", ps.PortalId, false))
                {
                    varyBy.Add("Browser", app.Context.Request.Browser.Browser);
                    includeVaryByKeys.Add("browser");
                }
                //excludeVaryByKeys.Add("returnurl");
                string CacheKey    = provider.GenerateCacheKey(TabId, includeVaryByKeys, excludeVaryByKeys, varyBy);
                string RawCacheKey = GetRawCacheKey(includeVaryByKeys, excludeVaryByKeys, varyBy);
                app.Context.Items["OpenOutputCache:RawCacheKey"] = RawCacheKey;
                app.Context.Items["OpenOutputCache:AbsoluteUri"] = app.Request.Url.AbsoluteUri;
                string CacheMode   = PortalController.GetPortalSetting("OOC_CacheMode", ps.PortalId, "ServerCache");
                int    ExpireDelay = PortalController.GetPortalSettingAsInteger("OOC_ExpireDelay", ps.PortalId, 60);
                if (provider.StreamOutput(TabId, CacheKey, app.Context))
                {
                    app.Context.Response.AddHeader("Content-Type", "text/html; charset=utf-8");
                    SetResponseCache(app.Context.Response, CacheKey, ExpireDelay, CacheMode);
                    app.CompleteRequest();
                }
                else
                {
                    int DefaultCacheDuration = PortalController.GetPortalSettingAsInteger("OOC_CacheDuration", ps.PortalId, 60);
                    int CacheDuration        = GetTabSettingAsInteger(tabSettings, "CacheDuration", DefaultCacheDuration);
                    if (CacheDuration > 0)
                    {
                        int DefaultMaxVaryByCount = PortalController.GetPortalSettingAsInteger("OOC_MaxVaryByCount", ps.PortalId, 0);
                        int MaxVaryByCount        = GetTabSettingAsInteger(tabSettings, "MaxVaryByCount", DefaultMaxVaryByCount);
                        int ItemCount             = 0;
                        if (MaxVaryByCount > 0)
                        {
                            ItemCount = OutputCachingProvider.Instance(CacheProvider).GetItemCount(TabId);
                        }
                        if (MaxVaryByCount <= 0 || ItemCount < MaxVaryByCount)
                        {
                            OutputCacheResponseFilter responseFilter = OutputCachingProvider.Instance(CacheProvider).GetResponseFilter(TabId, MaxVaryByCount, app.Response.Filter, CacheKey, TimeSpan.FromSeconds(CacheDuration));
                            app.Context.Response.Filter = responseFilter;
                            app.Context.Items["OpenOutputCache:Filter"]      = responseFilter;
                            app.Context.Items["OpenOutputCache:CacheMode"]   = CacheMode;
                            app.Context.Items["OpenOutputCache:ExpireDelay"] = ExpireDelay;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
            }
        }