/// <summary>
        /// Adds a virtual item to the cache.
        /// </summary>
        /// <param name="guid">The guid representing this item.</param>
        /// <param name="adaptor">The adaptor for this item.</param>
        /// <param name="key">The key of this item.</param>
        /// <param name="thumbSize">Requested thumbnail size.</param>
        /// <param name="thumb">Thumbnail image to add to cache.</param>
        /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param>
        /// <param name="autoRotate">AutoRotate property of the owner control.</param>
        /// <param name="useWIC">Whether to use WIC.</param>
        public void Add(Guid guid, ImageListView.ImageListViewItemAdaptor adaptor, object key, Size thumbSize, Image thumb, UseEmbeddedThumbnails useEmbeddedThumbnails, bool autoRotate, bool useWIC)
        {
            // Already cached?
            CacheItem item = null;

            if (thumbCache.TryGetValue(guid, out item))
            {
                if (item.Size == thumbSize && item.UseEmbeddedThumbnails == useEmbeddedThumbnails)
                {
                    return;
                }
            }

            // Resize
            thumb = ThumbnailExtractor.FromImage(thumb, thumbSize, useEmbeddedThumbnails, autoRotate, useWIC);

            // Add to cache
            thumbCache.Add(guid, new CacheItem(guid, thumbSize, thumb, CacheState.Cached, useEmbeddedThumbnails, autoRotate, useWIC));

            // Add to disk cache
            using (MemoryStream stream = new MemoryStream())
            {
                string diskCacheKey = adaptor.GetUniqueIdentifier(key, thumbSize, useEmbeddedThumbnails, autoRotate, useWIC);
                thumb.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
                diskCache.Write(diskCacheKey, stream);
            }

            // Raise the cache events
            if (mImageListView != null)
            {
                mImageListView.OnThumbnailCachedInternal(guid, thumb, thumbSize, true);
                mImageListView.Refresh();
            }
        }
        /// <summary>
        /// Gets the image from the thumbnail cache. If the image is not cached,
        /// null will be returned.
        /// </summary>
        /// <param name="guid">The guid representing this item.</param>
        /// <param name="adaptor">The adaptor of this item.</param>
        /// <param name="key">The key of this item.</param>
        /// <param name="thumbSize">Requested thumbnail size.</param>
        /// <param name="useEmbeddedThumbnails">UseEmbeddedThumbnails property of the owner control.</param>
        /// <param name="autoRotate">AutoRotate property of the owner control.</param>
        /// <param name="useWIC">Whether to use WIC.</param>
        /// <param name="clone">true to return a clone of the cached image; otherwise false.</param>
        public Image GetImage(Guid guid, ImageListView.ImageListViewItemAdaptor adaptor, object key, Size thumbSize, UseEmbeddedThumbnails useEmbeddedThumbnails, bool autoRotate, bool useWIC, bool clone)
        {
            CacheItem item = null;

            if (thumbCache.TryGetValue(guid, out item) && item != null && item.Image != null && item.Size == thumbSize && item.UseEmbeddedThumbnails == useEmbeddedThumbnails && item.AutoRotate == autoRotate && item.UseWIC == useWIC)
            {
                return(clone ? (Image)item.Image.Clone() : item.Image);
            }
            else
            {
                string diskCacheKey = adaptor.GetUniqueIdentifier(key, thumbSize, useEmbeddedThumbnails, autoRotate, useWIC);

                // Check the disk cache
                using (Stream stream = diskCache.Read(diskCacheKey))
                {
                    if (stream.Length > 0)
                    {
                        return(new Bitmap(stream));
                    }
                }
                return(null);
            }
        }