public void write(Bundle bundle, Progress progress) throws IOException {
        this.bundle = bundle;

        // add offset placeholders
        levelOffsetMap.clear();
        bundle.entries().stream()
            .filter(entry -> {
                if (bundle.entries().size() == 1) {
                    return true;
                }
                String name = entry.name();
                return name.equals("mainData") || name.startsWith("level");
            })
            .forEach(entry -> levelOffsetMap.put(entry, new MutablePair<>(0L, 0L)));

        BundleHeader header = bundle.header();
        header.levelByteEnd().clear();
        header.levelByteEnd().addAll(levelOffsetMap.values());
        header.numberOfLevelsToDownload(levelOffsetMap.size());

        // write header
        out.writeStruct(header);
        header.headerSize((int) out.position());

        // write bundle data
        if (header.compressed()) {
            // write data to temporary file
            try (DataWriter outData = DataWriters.forFile(dataFile,
                        CREATE, WRITE, TRUNCATE_EXISTING)) {
                writeData(outData, progress);
            }

            // configure LZMA encoder
            LzmaEncoderProps props = new LzmaEncoderProps();
            props.setDictionarySize(1 << 23); // 8 MiB
            props.setNumFastBytes(273); // maximum
            props.setUncompressedSize(Files.size(dataFile));
            props.setEndMarkerMode(true);

            // stream the temporary bundle data compressed into the bundle file
            try (OutputStream os = new LzmaOutputStream(new BufferedOutputStream(out.stream()), props)) {
                Files.copy(dataFile, os);
            }

            for (MutablePair<Long, Long> levelOffset : levelOffsetMap.values()) {
                levelOffset.setLeft(out.size());
            }
        } else {
            // write data directly to file
            writeData(out, progress);
        }

        // update header
        int fileSize = (int) out.size();
        header.completeFileSize(fileSize);
        header.minimumStreamedBytes(fileSize);

        out.position(0);
        out.writeStruct(header);
    }
@author Nico Bergemann <barracuda415 at yahoo.de>
disunity-core/src/main/java/info/ata4/junity/bundle/BundleWriter.java