void FiddlerApplication_BeforeRequest(FiddlerSession rpSession)
        {
            var rStopwatch = Stopwatch.StartNew();

            if (EnableUpstreamProxy)
                rpSession["x-OverrideGateway"] = UpstreamProxy;

            var rRequest = rpSession.oRequest;
            var rPath = rpSession.PathAndQuery;
            var rIsGame = rPath.StartsWith("/kcs");
            var rIsResource = rPath.StartsWith("/kcs/") && !rPath.StartsWith("/kcs/mainD2.swf");

            if (rPath.Contains("/kcs/mainD2.swf"))
                GameToken(rpSession.fullUrl);

            Session rSession;
            if (!rIsGame)
                rSession = new Session(rpSession.fullUrl);
            else if (rIsResource)
            {
                var rResourceSession = new ResourceSession(rpSession.fullUrl, rpSession.PathAndQuery.Substring(1));
                rSession = rResourceSession;

                LoadFromCache(rpSession, rResourceSession);
            }
            else
            {
                var rUrl = rpSession.PathAndQuery;
                var rPosition = rUrl.IndexOf("/kcsapi/");
                if (rPosition != -1)
                    rUrl = rUrl.Substring(rPosition + 8);
                rSession = new ApiSession(rpSession.fullUrl, rUrl) { RequestBody = Uri.UnescapeDataString(rpSession.GetRequestBodyAsString()) };
            }

            rpSession.Tag = rSession;

            rSession.Stopwatch = rStopwatch;
            if (rSession.Status != SessionStatus.LoadedFromCache)
                rSession.Status = SessionStatus.Request;

            NewSession(rSession);

            Debug.WriteLine("Request - " + rpSession.fullUrl);
        }
        static void LoadFromCacheCore(FiddlerSession rpSession, ResourceSession rpResourceSession, string rpPath)
        {
            rpSession.utilCreateResponseAndBypassServer();
            rpSession.ResponseBody = File.ReadAllBytes(rpPath);

            rpResourceSession.LoadedBytes = rpSession.ResponseBody.Length;
            rpResourceSession.Status = SessionStatus.LoadedFromCache;
        }
        static void LoadFromCache(FiddlerSession rpSession, ResourceSession rpResourceSession)
        {
            if (!ResourceCache.IsEnabled) return;

            var rPath = rpResourceSession.OriginalCachePath;
            var rExtension = Path.GetExtension(rpResourceSession.CachePath);

            var rForcePath = Path.Combine(ResourceCache.CacheFolder, rpResourceSession.FileNameWithoutVersion + ".hack" + rExtension);
            if (File.Exists(rForcePath))
                LoadFromCacheCore(rpSession, rpResourceSession, rForcePath);
            else if (File.Exists(rpResourceSession.CachePath))
            {
                if (File.Exists(rPath) && File.GetLastWriteTime(rPath) > File.GetLastWriteTime(rpResourceSession.CachePath))
                {
                    File.Delete(rpResourceSession.CachePath);
                    File.Move(rPath, rpResourceSession.CachePath);
                }

                LoadFromCacheCore(rpSession, rpResourceSession, rpResourceSession.CachePath);
            }
            else if (File.Exists(rPath))
            {
                File.Move(rPath, rpResourceSession.CachePath);
                LoadFromCacheCore(rpSession, rpResourceSession, rpResourceSession.CachePath);
            }
        }