/// <summary>
        /// Apply instructions to an image.
        /// A good point to extra configuration of Image Resizer
        /// </summary>
        /// <param name="inputStream">Input image stream</param>
        /// <param name="outputStream">Output stream to write the result</param>
        /// <param name="instructions">Instructions to apply</param>
        /// <returns>Result image as a stream. Caller have to care about the stream disposing.</returns>
        protected virtual ImageProcessingResult ProcessImage(Stream inputStream, Stream outputStream, Instructions instructions)
        {
            if (!inputStream.CanRead)
            {
                throw new ArgumentException("inputStream is nor readable");
            }
            if (!outputStream.CanWrite)
            {
                throw new ArgumentException("outputStream is nor writable");
            }

            var job = ImageBuilder.Current.Build(inputStream, outputStream, instructions);

            var res = new ImageProcessingResult();

            if (!string.IsNullOrEmpty(job.ResultFileExtension))
            {
                res.FileExt = job.ResultFileExtension;
            }
            if (!string.IsNullOrEmpty(job.ResultMimeType))
            {
                res.MediaType = job.ResultMimeType;
            }
            return(res);
        }
        /// <summary>
        /// Build file info object based on existing info & processing result. The result represents stored file but not the original one.
        /// For example if the original was a jpeg image, but after processing it's converted into png, file ext & mime type will be updated.
        /// </summary>
        /// <param name="fileInfo">Income file info</param>
        /// <param name="processingResult">Stored file info</param>
        /// <returns></returns>
        protected virtual IFileInfo BuildFileInfo(IFileInfo fileInfo, ImageProcessingResult processingResult)
        {
            var res = new IncomeFileInfo(fileInfo)
            {
                MimeType = processingResult.MediaType
            };

            if (processingResult.FileExt != null && !res.OriginalName.EndsWith(processingResult.FileExt, StringComparison.OrdinalIgnoreCase))
            {
                // Need to correct file ext
                var dotIndex = res.OriginalName.LastIndexOf('.');
                if (dotIndex > 0)
                {
                    res.OriginalName = res.OriginalName.Substring(0, dotIndex);
                }
                res.OriginalName += '.' + processingResult.FileExt;
            }
            return(res);
        }