public byte[] DownloadData(Uri uri, int fetchIntervalHrs, string userAgent)
        {
            if (fetchIntervalHrs == 0)
            {
                throw new ArgumentException("fetchIntervalHrs cannot be zero.", "fetchIntervalHrs");
            }

            System.DateTime?lastFetch = this.GetHTTPCacheLastUpdate(uri);

            if (lastFetch != null)
            {
                if (lastFetch.Value.AddHours(fetchIntervalHrs) > DateTime.Now)
                {
                    bool   requestSuccess = false;
                    byte[] cacheData      = this.GetHTTPCacheContent(uri, ref requestSuccess);

                    if (cacheData != null)
                    {
                        if (requestSuccess)
                        {
                            return(cacheData);
                        }
                        else
                        {
                            using (MemoryStream memoryStream = new MemoryStream(cacheData))
                            {
                                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();

                                // Deserialise the CacheWebException structure
                                CacheWebExpInfo cachedException = default(CacheWebExpInfo);
                                cachedException = (CacheWebExpInfo)binaryFormatter.Deserialize(memoryStream);

                                // Crete a new WebException with the cached data and throw it
                                throw new WebException(cachedException.Message, cachedException.InnerException, cachedException.Status, cachedException.Response);
                            }
                        }
                    }
                }
            }

            Debug.Print("CachedWebClient: Fetching " + uri.ToString());

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);

            request.UserAgent = userAgent;
            request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip");

            using (MemoryStream dataStream = new MemoryStream())
            {
                try
                {
                    HttpWebResponse response       = (HttpWebResponse)request.GetResponse();
                    Stream          responseStream = response.GetResponseStream();

                    if (response.ContentEncoding.ToUpperInvariant() == "GZIP")
                    {
                        // Decompress the gzipped response while it is being read into the memory stream
                        responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
                    }

                    // Read the response into a MemoryStream in chunks, ready for the byte array
                    byte[] buffer = new byte[10240];
                    int    readBytes;

                    while ((readBytes = responseStream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        dataStream.Write(buffer, 0, readBytes);
                    }

                    if (response.ContentEncoding.ToUpperInvariant() == "GZIP")
                    {
                        responseStream.Dispose();
                    }
                }
                catch (WebException webExp)
                {
                    if (webExp.Status != WebExceptionStatus.NameResolutionFailure && webExp.Status != WebExceptionStatus.Timeout)
                    {
                        // A WebException doesn't serialise well, as Response and Status get lost,
                        // so store the information in a structure and then recreate it later
                        CacheWebExpInfo cacheException = new CacheWebExpInfo();
                        cacheException.Message        = webExp.Message;
                        cacheException.InnerException = webExp.InnerException;
                        cacheException.Status         = webExp.Status;
                        cacheException.Response       = webExp.Response;

                        using (MemoryStream stream = new MemoryStream())
                        {
                            BinaryFormatter formatter = new BinaryFormatter();

                            // Serialise the CacheWebException and store it in the cache
                            formatter.Serialize(stream, cacheException);
                            this.AddToHTTPCache(uri, false, stream.ToArray());
                        }
                    }

                    // Re-throw the WebException
                    throw;
                }

                byte[] data = dataStream.ToArray();
                this.AddToHTTPCache(uri, true, data);

                return(data);
            }
        }
        public byte[] DownloadData(Uri uri, int fetchIntervalHrs, string userAgent)
        {
            if (fetchIntervalHrs == 0)
            {
                throw new ArgumentException("fetchIntervalHrs cannot be zero.", "fetchIntervalHrs");
            }

            System.DateTime? lastFetch = this.GetHTTPCacheLastUpdate(uri);

            if (lastFetch != null)
            {
                if (lastFetch.Value.AddHours(fetchIntervalHrs) > DateTime.Now)
                {
                    bool requestSuccess = false;
                    byte[] cacheData = this.GetHTTPCacheContent(uri, ref requestSuccess);

                    if (cacheData != null)
                    {
                        if (requestSuccess)
                        {
                            return cacheData;
                        }
                        else
                        {
                            using (MemoryStream memoryStream = new MemoryStream(cacheData))
                            {
                                System.Runtime.Serialization.Formatters.Binary.BinaryFormatter binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();

                                // Deserialise the CacheWebException structure
                                CacheWebExpInfo cachedException = default(CacheWebExpInfo);
                                cachedException = (CacheWebExpInfo)binaryFormatter.Deserialize(memoryStream);

                                // Crete a new WebException with the cached data and throw it
                                throw new WebException(cachedException.Message, cachedException.InnerException, cachedException.Status, cachedException.Response);
                            }
                        }
                    }
                }
            }

            Debug.Print("CachedWebClient: Fetching " + uri.ToString());

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
            request.UserAgent = userAgent;
            request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip");

            using (MemoryStream dataStream = new MemoryStream())
            {
                try
                {
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    Stream responseStream = response.GetResponseStream();

                    if (response.ContentEncoding.ToUpperInvariant() == "GZIP")
                    {
                        // Decompress the gzipped response while it is being read into the memory stream
                        responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
                    }

                    // Read the response into a MemoryStream in chunks, ready for the byte array
                    byte[] buffer = new byte[10240];
                    int readBytes;

                    while ((readBytes = responseStream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        dataStream.Write(buffer, 0, readBytes);
                    }

                    if (response.ContentEncoding.ToUpperInvariant() == "GZIP")
                    {
                        responseStream.Dispose();
                    }
                }
                catch (WebException webExp)
                {
                    if (webExp.Status != WebExceptionStatus.NameResolutionFailure && webExp.Status != WebExceptionStatus.Timeout)
                    {
                        // A WebException doesn't serialise well, as Response and Status get lost,
                        // so store the information in a structure and then recreate it later
                        CacheWebExpInfo cacheException = new CacheWebExpInfo();
                        cacheException.Message = webExp.Message;
                        cacheException.InnerException = webExp.InnerException;
                        cacheException.Status = webExp.Status;
                        cacheException.Response = webExp.Response;

                        using (MemoryStream stream = new MemoryStream())
                        {
                            BinaryFormatter formatter = new BinaryFormatter();

                            // Serialise the CacheWebException and store it in the cache
                            formatter.Serialize(stream, cacheException);
                            this.AddToHTTPCache(uri, false, stream.ToArray());
                        }
                    }

                    // Re-throw the WebException
                    throw;
                }

                byte[] data = dataStream.ToArray();
                this.AddToHTTPCache(uri, true, data);

                return data;
            }
        }