public async Task EmbedMessage(
            string fileInputLocation,
            string fileOutputLocation,
            string message,
            string password)
        {
            try
            {
                ConsoleLogger.LogMessage("Creating encoder instance...");
                ImageEncoder imageEncoder = new ImageEncoder(
                    format: ImageFormat.Png,
                    encryptionConfiguration: new EncryptionConfiguration(EncryptionType.Aes256, 20000),
                    compressionConfiguration: new CompressionConfiguration(CompressionType.Gzip, CompressionLevel.Standard),
                    embeddedImage: new EmbeddedImage(Image.FromFile(fileInputLocation), EmbeddedImage.PixelStorage.Auto)
                    );
                ConsoleLogger.LogMessage("Reading message bytes...");
                byte[] contentBytes    = Encoding.UTF8.GetBytes(message);
                string outputDirectory = Path.GetDirectoryName(fileOutputLocation);
                if (!Directory.Exists(outputDirectory))
                {
                    Directory.CreateDirectory(outputDirectory);
                }
                ConsoleLogger.LogMessage("Appending message bytes into a memory stream...");
                MemoryStream contentStream = new MemoryStream();
                await contentStream.WriteAsync(contentBytes, 0, contentBytes.Length);

                ConsoleLogger.LogMessage("Adding memory stream object into encoder...");
                imageEncoder.AddDirectory(new Input.Directory("\\", new[]
                {
                    new Input.File("__payload__.bin", contentStream)
                }));
                using (FileStream outputStream = new FileStream(fileOutputLocation, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                {
                    ConsoleLogger.LogMessage("Encoding data into target image...");
                    ConsoleLogger.LogMessage("Creating output image...");
                    await imageEncoder.SaveAsync(
                        outputStream : outputStream,
                        encodingConfiguration : new EncodingConfiguration
                        (
                            password: password,
                            tempStorageProvider: new MemoryStorageProvider(),
                            bufferSize: 81920,
                            fileGroupSize: 1024 * 1024
                        ));

                    ConsoleLogger.LogMessage($"Operation succeeded. File saved at {fileOutputLocation}");
                }
            }
            catch (Exception ex)
            {
                ConsoleLogger.ShowErrorMessage(ex.Message);
            }
        }
        public async Task EmbedFiles(
            string fileInputLocation,
            string fileOutputLocation,
            string[] fileAttachments,
            string password)
        {
            try
            {
                ConsoleLogger.LogMessage("Creating encoder instance...");
                ImageEncoder imageEncoder = new ImageEncoder(
                    format: ImageFormat.Png,
                    encryptionConfiguration: new EncryptionConfiguration(EncryptionType.Aes256, 20000),
                    compressionConfiguration: new CompressionConfiguration(CompressionType.Gzip, CompressionLevel.Standard),
                    embeddedImage: new EmbeddedImage(Image.FromFile(fileInputLocation), EmbeddedImage.PixelStorage.Auto)
                    );
                string outputDirectory = Path.GetDirectoryName(fileOutputLocation);
                if (!Directory.Exists(outputDirectory))
                {
                    Directory.CreateDirectory(outputDirectory);
                }

                string attachmentDirectory = Path.GetDirectoryName(fileAttachments.FirstOrDefault());

                ConsoleLogger.LogMessage("Adding file(s) into encoder instance...");
                List <Input.File> files = new List <Input.File>();
                foreach (string file in fileAttachments)
                {
                    files.Add(new Input.File(new System.IO.FileInfo(file)));
                }
                imageEncoder.AddDirectory(new Input.Directory("\\", files));

                using (FileStream outputStream = new FileStream(fileOutputLocation, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                {
                    ConsoleLogger.LogMessage("Encoding data into target image...");
                    ConsoleLogger.LogMessage("Creating output image...");
                    await imageEncoder.SaveAsync(
                        outputStream : outputStream,
                        encodingConfiguration : new EncodingConfiguration
                        (
                            password: password,
                            tempStorageProvider: new MemoryStorageProvider(),
                            bufferSize: 81920,
                            fileGroupSize: 1024 * 1024
                        ));

                    ConsoleLogger.LogMessage($"Operation succeeded. File saved at {fileOutputLocation}");
                }
            }
            catch (Exception ex)
            {
                ConsoleLogger.ShowErrorMessage(ex.ToString());
            }
        }
        private async Task CreateVersionCompatData(
            ImageFormat format,
            FileInfo inputZipFIle,
            EncryptionConfiguration encryption,
            CompressionConfiguration compression,
            EmbeddedImage embeddedImage)
        {
            var    inputFileName = Path.GetFileNameWithoutExtension(inputZipFIle.Name);
            string outputName    = inputFileName.Substring(0, Math.Min(inputFileName.Length, 10)) + "-" + Enum.GetName(typeof(ImageFormat), format);

            if (embeddedImage != null)
            {
                outputName += "-E";
            }

            if (encryption != null)
            {
                outputName += "-" + Enum.GetName(typeof(EncryptionType), encryption.Type).Substring(0, 3);
            }

            if (compression != null)
            {
                outputName += "-" + Enum.GetName(typeof(CompressionType), compression.Type).Substring(0, 3);
            }


            var tempInputDataDirectory = _ouputTempVersionDataDirectory.CreateSubdirectory(outputName + "_original_data");

            using (var zipFile = ZipFile.Read(inputZipFIle.FullName))
            {
                zipFile.ExtractAll(tempInputDataDirectory.FullName);
            }


            DirectoryInfo outputDirectory = _ouputTempVersionDataDirectory.CreateSubdirectory(outputName);
            var           encoder         = new ImageEncoder(format, encryption, compression, embeddedImage);

            using (Stream encodedImageFile = File.Create(Path.Combine(outputDirectory.FullName, inputFileName + "." + encoder.Extension)))
            {
                encoder.AddDirectory(tempInputDataDirectory);
                await encoder.SaveAsync(encodedImageFile, new EncodingConfiguration(
                                            password : "******",
                                            tempStorageProvider : new MemoryStorageProvider(),
                                            bufferSize : 4096,
                                            fileGroupSize : 1024 * 500));

                inputZipFIle.CopyTo(Path.Combine(outputDirectory.FullName, "Original_Data.zip"), true);
            }

            tempInputDataDirectory.Delete(true);
        }
        public async Task EncodingThenDecoding_ProducesEquivalentResults(
            ImageFormat format,
            FileInfo inputZipFile,
            EncryptionConfiguration encryption,
            CompressionConfiguration compression,
            EmbeddedImage embeddedImage,
            IDictionary <string, string> metadata)
        {
            DirectoryInfo inputDirectory  = null;
            DirectoryInfo outputDirectory = null;

            try
            {
                using (var storageStream = new MemoryStream())
                {
                    inputDirectory = _inputRootDirectory.CreateSubdirectory(Path.GetFileNameWithoutExtension(inputZipFile.Name));
                    using (var zipFile = ZipFile.Read(inputZipFile.FullName))
                    {
                        zipFile.ExtractAll(inputDirectory.FullName);
                    }

                    var encoder = new ImageEncoder(format, encryption, compression, embeddedImage);

                    encoder.Metadata = metadata;
                    encoder.AddDirectory(inputDirectory);
                    await encoder.SaveAsync(storageStream, ImageConfigurations.EncodingConfiguration);

                    storageStream.Position = 0;

                    var decoder = await ImageDecoder.LoadAsync(storageStream, ImageConfigurations.DecodingConfiguration);

                    outputDirectory = _ouputRootDirectory.CreateSubdirectory(inputDirectory.Name);
                    await decoder.DecodeAsync(outputDirectory);

                    AssertEx.AreEqualByJson(metadata, decoder.Metadata);
                    DirectoryAssert.AreEquivalent(inputDirectory, outputDirectory);
                }
            }
            finally
            {
                foreach (var directory in new[] { inputDirectory, outputDirectory })
                {
                    if (directory != null)
                    {
                        directory.Delete(true);
                    }
                }
            }
        }