protected async override Task ExecuteEncodeAsync(ImageConfiguration configuration, Stream output) { var chunkLayoutBuilder = new ChunkLayoutBuilder(); var chunkWriter = new ChunkWriter(EncodingConfiguration); chunkLayoutBuilder.Append( GenerateChunk(StructureType.Metadata, configuration, new Metadata(configuration.Metadata)), chunkWriter, new MetadataSerializer()); IList <IList <File> > groupedFiles = _fileGroupingService.GroupFiles(configuration.Files, EncodingConfiguration.FileGroupSize); IDictionary <File, Output.File> mappedFiles = MapFiles(configuration.Files); ICollection <Directory> mappedDirectories = MapDirectories(mappedFiles, configuration.Directories).Values; var fileGroupSerializer = new FileGroupContentsSerializer(EncodingConfiguration); var fileGroups = new List <FileGroup>(); var fileStreams = new List <Stream>(); foreach (var group in groupedFiles) { fileGroups.Add(new FileGroup(group.Select(file => mappedFiles[file]))); var fileGroupStreams = group.Select(file => file.GetStream()).ToList(); fileStreams.AddRange(fileGroupStreams); chunkLayoutBuilder.Append(GenerateChunk( StructureType.FileGroupContents, configuration, new FileGroupContents(new CombinedStream(fileGroupStreams))), chunkWriter, fileGroupSerializer); } chunkLayoutBuilder.Prepend( GenerateChunk(StructureType.FileLayout, configuration, new FileLayout(mappedDirectories, fileGroups)), chunkWriter, new FileLayoutSerializer()); ChunkLayout chunkLayout = await chunkLayoutBuilder.BuildAsync(); var chunkLayoutBytes = await new ChunkLayoutSerializer().SerializeToBytesAsync(chunkLayout); long totalLength = CalculateTotalLength(chunkLayoutBytes, chunkLayout) + 1; //Plus one to force room for padding using (Stream imageStream = await CreateImageWriterStreamAsync(configuration, output, totalLength)) { await WriteBodyData(imageStream, chunkLayoutBytes, chunkLayoutBuilder); } fileStreams.ForEach(stream => stream.Close()); }