@Override
	public void run() {
		script.status = "Sort tab";

		// extra for tab0
		// Categories then rest sorted alphabetically

		for (int i = 0; i < mappingList.size(); i++) {
			if (sorters == null) {
				sorters = new ItemSorter[mappingList.size()];
			}

			final IBank.BankTab tab = BANK_TABS[i];

			ItemSorter sorter = sorters[i];
			if (sorter == null) {
				sorter = sorters[i] = new ItemSorter(script.itemCategoriser, mappingList.get(i));
			}

			ArrayList<Item> current = new ArrayList<Item>();
			ctx.bank.getItemsInTab(tab).addTo(current);
			final Iterator<Item> iterator = current.iterator();
			for (final Item item : ctx.bank.getItemsInTab(tab).sort(sorter)) {
				//script.log.info(item.id() + " " + item.name());

				if (!iterator.hasNext()) {
					return;
				}

				final Item poll = iterator.next();
				if (poll.id() != item.id()) {
					//script.log.info(poll.id() + " != " + item.id());
					final Item destination = ctx.bank.getItemsInTab(tab).id(item.id()).select(new Filter<Item>() {
						@Override
						public boolean accept(Item i) {
							return i.component().index() > poll.component().index();
						}
					}).poll();

					if (!destination.valid()) {
						continue;
					}

					script.log.info("Swap: " + swap(poll, destination));

					return;
				}
			}
		}

		ctx.controller.stop();
	}