/// <summary>
        /// Returns the total number of unoptimized images in the Sitefinity album with the specified Id
        /// </summary>
        /// <param name="albumId">Id of the album</param>
        /// <returns></returns>
        public virtual int GetItemsCount(Guid albumId)
        {
            var optimizedImageIds = new HashSet <Guid>(OptimizationManager.GetImageOptimizationLogEntrys().Where(e => e.OptimizedFileId != Guid.Empty).Select(e => e.ImageId));
            var images            = LibManager.GetAlbum(albumId).Images()
                                    .Where(i => i.Status == ContentLifecycleStatus.Master && !optimizedImageIds.Contains(i.Id));

            return(images.Count());
        }
        /// <summary>
        /// Optimize all images in the Sitefinity album with the specified Id
        /// </summary>
        /// <param name="albumId">Id of the album to be optimized</param>
        public virtual void OptimizeAlbum(Guid albumId)
        {
            // Get all the unoptimized image items
            var optimizedImageIds = new HashSet <Guid>(OptimizationManager.GetImageOptimizationLogEntrys().Where(e => e.OptimizedFileId != Guid.Empty).Select(e => e.ImageId));
            var images            = LibManager.GetAlbum(albumId).Images()
                                    .Where(i => i.Status == ContentLifecycleStatus.Master && !optimizedImageIds.Contains(i.Id));

            foreach (Image image in images)
            {
                this.OptimizeImage(albumId, image.Id);
            }
        }
        /// <summary>
        /// Optimize a single Sitefinity image
        /// </summary>
        /// <param name="parentId">Id of the album that contains the image</param>
        /// <param name="imageId">Id of the master version of the image</param>
        public virtual void OptimizeImage(Guid albumId, Guid masterImageId)
        {
            Album album = LibManager.GetAlbum(albumId);

            // This saves us from having to care about BlobStorage later in the method
            var albumProvider = (LibrariesDataProvider)album.Provider;

            // This should exist!
            var image = album.Images().Where(i => i.Id == masterImageId && i.Status == ContentLifecycleStatus.Master).Single();

            // Pull the Stream of the image from the provider.
            Stream imageData = albumProvider.Download(image);

            using (MemoryStream ms = new MemoryStream())
            {
                // Can't trust the length of Stream. Copying to a MemoryStream
                imageData.CopyTo(ms);
                // Be kind...rewind
                ms.Seek(0, SeekOrigin.Begin);

                // Optimization methods may return the image in a different format than what was provided.
                // If that happens, we need to know about it.
                string optimizedExtension;
                Stream optimizedImage = this.CompressImageData(image, ms, out optimizedExtension);

                // There are different reasons why the optimizer would return null.
                // 1. An error occured (in which case the optimizer should throw or handle the exception)
                // 2. Some other mechanism is being used to handle the item updates (callbacks)
                if (optimizedImage != null)
                {
                    var oLogEntry = OptimizationManager.GetImageOptimizationLogEntrys().Where(e => e.ImageId == image.Id).FirstOrDefault();// .CreateImageOptimizationLogEntry();

                    //oLogEntry.ImageId = image.Id;
                    //oLogEntry.InitialFileExtension = image.Extension;
                    //oLogEntry.InitialTotalSize = image.TotalSize;

                    // Check out the master to get a temp version.
                    Image temp = LibManager.Lifecycle.CheckOut(image) as Image;

                    // Make the modifications to the temp version.
                    LibManager.Upload(temp, optimizedImage, optimizedExtension);

                    // Check in the temp version.
                    // After the check in the temp version is deleted.
                    LibManager.Lifecycle.CheckIn(temp);

                    oLogEntry.OptimizedFileId = image.FileId;

                    OptimizationManager.SaveChanges();

                    LibManager.SaveChanges();

                    // Check to see if this image is already published.
                    // If it is, we need to publish the "Master" to update "Live"
                    if (image.GetWorkflowState() == "Published")
                    {
                        var bag = new Dictionary <string, string>();
                        bag.Add("ContentType", typeof(Image).FullName);
                        WorkflowManager.MessageWorkflow(image.Id, typeof(Image), albumProvider.Name, "Publish", false, bag);
                    }
                }

                // Let concerned parties know that processing has completed for this item
                ImageOptimizedHandler tmp = OnImageOptimized;
                if (tmp != null)
                {
                    OnImageOptimized(this, EventArgs.Empty);
                }
            }
        }