public String disassemble(ScriptDefinition script) throws IOException
	{
		int[] instructions = script.getInstructions();
		int[] iops = script.getIntOperands();
		String[] sops = script.getStringOperands();
		Map<Integer, Integer>[] switches = script.getSwitches();

		assert iops.length == instructions.length;
		assert sops.length == instructions.length;

		boolean[] jumps = needLabel(script);

		StringBuilder writer = new StringBuilder();
		writerHeader(writer, script);

		for (int i = 0; i < instructions.length; ++i)
		{
			int opcode = instructions[i];
			int iop = iops[i];
			String sop = sops[i];

			Instruction ins = this.instructions.find(opcode);
			if (ins == null)
			{
				logger.warn("Unknown instruction {} in script {}", opcode, script.getId());
			}

			if (jumps[i])
			{
				// something jumps here
				writer.append("LABEL").append(i).append(":\n");
			}

			String name;
			if (ins != null && ins.getName() != null)
			{
				name = ins.getName();
			}
			else
			{
				name = String.format("%03d", opcode);
			}

			writer.append(String.format("   %-22s", name));

			if (shouldWriteIntOperand(opcode, iop))
			{
				if (isJump(opcode))
				{
					writer.append(" LABEL").append(i + iop + 1);
				}
				else
				{
					writer.append(" ").append(iop);
				}
			}

			if (sop != null)
			{
				writer.append(" \"").append(ESCAPER.escape(sop)).append("\"");
			}

			if (opcode == Opcodes.SWITCH)
			{
				Map<Integer, Integer> switchMap = switches[iop];

				for (Entry<Integer, Integer> entry : switchMap.entrySet())
				{
					int value = entry.getKey();
					int jump = entry.getValue();

					writer.append("\n");
					writer.append("      ").append(value).append(": LABEL").append(i + jump + 1);
				}
			}

			writer.append("\n");
		}

		return writer.toString();
	}
@Test
	public void test() throws IOException
	{
		File outDir = folder.newFolder();
		int count = 0;

		try (Store store = new Store(StoreLocation.LOCATION))
		{
			store.load();

			Storage storage = store.getStorage();
			Index index = store.getIndex(IndexType.CLIENTSCRIPT);
			ScriptLoader loader = new ScriptLoader();

			for (Archive archive : index.getArchives())
			{
				byte[] contents = archive.decompress(storage.loadArchive(archive));

				if (contents == null)
				{
					continue;
				}

				ScriptDefinition script = loader.load(archive.getArchiveId(), contents);

				File outFile = new File(outDir, archive.getArchiveId() + ".rs2asm");

				Disassembler disassembler = new Disassembler();
				String out = disassembler.disassemble(script);

				Files.write(out.getBytes(StandardCharsets.UTF_8), outFile);

				++count;
			}
		}

		logger.info("Dumped {} scripts to {}", count, outDir);
	}