class HKXWriter {

	public void write(final HKXFile file) throws IOException, UnsupportedVersionError
	{
		// Connect to the file.
		HKXWriterConnector connector = new HKXWriterConnector(outputBB);

		// Create the header.
		HeaderData header = new HKXHeaderFactory().create(file);

		// Create the file's section data.
		HKXSectionHandler sectionHandler = new HKXSectionHandler(header);
		SectionData classnames = new SectionData();
		SectionData types = new SectionData();
		SectionData data = new SectionData();
		sectionHandler.init(HKXSectionHandler.CLASSNAME, classnames);

		// Create the ClassNames data.
		HKXClassnamesHandler cnameHandler = new HKXClassnamesHandler();
		ClassnamesData cnameData = cnameHandler.getClassnames(file);

		// Write ClassNames data to the file.
		long classnamesEnd = connector.writeClassnames(classnames, cnameData);
		sectionHandler.fillCName(classnames, classnamesEnd);
		connector.writeHeader(header);
		connector.writeSection(header, HKXSectionHandler.CLASSNAME, classnames);

		// Update things to prepare for Data writing.
		sectionHandler.init(HKXSectionHandler.TYPES, types);
		connector.writeSection(header, HKXSectionHandler.TYPES, types);
		sectionHandler.init(HKXSectionHandler.DATA, data);

		// Write data in the file and store data1/data2/data3 values.
		PointerResolver resolver = new PointerResolver();
		HKXDataHandler dataHandler = new HKXDataHandler(outputBB, cnameData, enumResolver);
		try
		{
			long endData = dataHandler.fillFile(data, file, resolver) - data.offset;
			data.data1 = endData % 0x10 == 0 ? endData : (1 + endData / 0x10) * 0x10;
			dataHandler.fillPointers(data, resolver);
			
			// Flips the ByteBuffer now, to set its limit to the end of the file.
			outputBB.flip();
			
			// Write the data section to the file.
			connector.writeSection(header, HKXSectionHandler.DATA, data);
		}
		catch (ClassCastException e)
		{
			LoggerUtil.add(new WrongInputCastException(String.format(SBundle.getString("error.hkx.write.cast")), e));
		}
		
		// Prepare the output ByteBuffer for use.
		outputBB.position(0);
		
		// If needed, write the output ByteBuffer back to the file.
		if (outputFile.isPresent())
		{
			try (RandomAccessFile out = new RandomAccessFile(outputFile.get(), "rw"))
			{
				byte[] bytes = new byte[outputBB.limit()];
				outputBB.get(bytes);
				out.write(bytes);
				out.close();
			}
		}
	}

	public  HKXWriter(final File outputFile, final HKXEnumResolver enumResolver);
	public  HKXWriter(final File outputFile, final HKXEnumResolver enumResolver, final int bufferCapacity);
	public  HKXWriter(final ByteBuffer outputBB, final HKXEnumResolver enumResolver);

}