/// <summary>
        /// Requests a new image and return it via the callback. If the image is in the cache, it is
        /// returned from there. Otherwise we queue up the request and spin up a thread to retrieve the
        /// image and invoke the callback from there.
        /// </summary>
        /// <param name="imageURL">The URL of the image</param>
        /// <param name="maxWidth">The maximum width of the requested image</param>
        /// <param name="maxHeight">The maximum height of the requested image</param>
        /// <param name="callback">The callback</param>
        /// <param name="callbackParameter">A user specified parameter for the callback</param>
        /// <returns>An Image object that represents the specified image or null if it is not yet available</returns>
        public Image NewRequest(string imageURL, int maxWidth, int maxHeight, ImageRetrieved callback, object callbackParameter)
        {
            if (_imageCache.ContainsKey(imageURL))
            {
                LogFile.WriteLine("Image {0} retrieved from cache", imageURL);

                return((_imageCache[imageURL].Image != null) ? ScaleImage(_imageCache[imageURL].Image, maxWidth, maxHeight) : null);
            }

            // Spin up a new thread to obtain any images
            Thread t = new Thread(() =>
            {
                try
                {
                    LogFile.WriteLine("Requesting image {0}", imageURL);

                    // Convert Dropbox share URLs into raw links
                    string realImageURL = imageURL;
                    if (realImageURL.StartsWith("https://www.dropbox.com", StringComparison.Ordinal))
                    {
                        realImageURL += "?raw=1";
                    }

                    HttpWebRequest webRequest            = (HttpWebRequest)WebRequest.Create(realImageURL);
                    webRequest.AllowWriteStreamBuffering = true;
                    webRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)";

                    using (WebResponse _WebResponse = webRequest.GetResponse())
                    {
                        Stream stream = _WebResponse.GetResponseStream();
                        if (stream != null)
                        {
                            Image _tmpImage       = Image.FromStream(stream);
                            _imageCache[imageURL] = new ImageCacheEntry {
                                Image = _tmpImage, Timestamp = DateTime.Now
                            };

                            Image image = ScaleImage(_tmpImage, maxWidth, maxHeight);
                            callback(image, callbackParameter);

                            LogFile.WriteLine("Image {0} retrieved from server and cached", imageURL);
                        }
                    }
                }
                catch (Exception e)
                {
                    LogFile.WriteLine("Failed to load {0}: {1}", imageURL, e.Message);

                    // Don't try and request this image again for a while.
                    _imageCache[imageURL] = new ImageCacheEntry {
                        Image = null, Timestamp = DateTime.Now
                    };
                }
            });

            t.Start();
            return(null);
        }
        /// <summary>
        /// Requests a new image and return it via the callback. If the image is in the cache, it is
        /// returned from there. Otherwise we queue up the request and spin up a thread to retrieve the
        /// image and invoke the callback from there.
        /// </summary>
        /// <param name="imageURL">The URL of the image</param>
        /// <param name="maxWidth">The maximum width of the requested image</param>
        /// <param name="maxHeight">The maximum height of the requested image</param>
        /// <param name="callback">The callback</param>
        /// <param name="callbackParameter">A user specified parameter for the callback</param>
        /// <returns>An Image object that represents the specified image or null if it is not yet available</returns>
        public Image NewRequest(string imageURL, int maxWidth, int maxHeight, ImageRetrieved callback, object callbackParameter)
        {
            if (_imageCache.ContainsKey(imageURL))
            {
                LogFile.WriteLine("Image {0} retrieved from cache", imageURL);

                return (_imageCache[imageURL].Image != null) ? ScaleImage(_imageCache[imageURL].Image, maxWidth, maxHeight) : null;
            }

            // Spin up a new thread to obtain any images
            Thread t = new Thread(() =>
            {
                try
                {
                    LogFile.WriteLine("Requesting image {0}", imageURL);

                    // Convert Dropbox share URLs into raw links
                    string realImageURL = imageURL;
                    if (realImageURL.StartsWith("https://www.dropbox.com", StringComparison.Ordinal))
                    {
                        realImageURL += "?raw=1";
                    }

                    HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(realImageURL);
                    webRequest.AllowWriteStreamBuffering = true;
                    webRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)";

                    using (WebResponse _WebResponse = webRequest.GetResponse())
                    {
                        Stream stream = _WebResponse.GetResponseStream();
                        if (stream != null)
                        {
                            Image _tmpImage = Image.FromStream(stream);
                            _imageCache[imageURL] = new ImageCacheEntry { Image = _tmpImage, Timestamp = DateTime.Now };

                            Image image = ScaleImage(_tmpImage, maxWidth, maxHeight);
                            callback(image, callbackParameter);

                            LogFile.WriteLine("Image {0} retrieved from server and cached", imageURL);
                        }
                    }
                }
                catch (Exception e)
                {
                    LogFile.WriteLine("Failed to load {0}: {1}", imageURL, e.Message);

                    // Don't try and request this image again for a while.
                    _imageCache[imageURL] = new ImageCacheEntry { Image = null, Timestamp = DateTime.Now };
                }
            });
            t.Start();
            return null;
        }