class UpgradeService {

    public void upgradeVersion() {

        LOG.info("Global upgrade process starting");

        int alreadyApplied = 0;
        int numberOfTasksApplied = 0;
        for (UpgradeTask task : tasks) {

            final UpgradeTaskId taskId = task.getId();

            // skip non version upgrade task
            if (task.getTarget() != VERSION) {
                LOG.debug("{} does not target version", taskId);
                continue;
            }

            final String targetId = VERSION.name() + '-' + taskId.getVersion();

            if (repository.isAlreadyApplied(targetId, taskId)) {
                LOG.debug("{} already applied, let's skip it", taskId);
                alreadyApplied++;
            } else {
                LOG.debug("apply upgrade {}", taskId);
                try {
                    task.run();
                } catch (Exception exception) {
                    LOG.error("Failed to apply upgrade {}", taskId, exception);
                    break;
                }
                repository.applied(targetId, taskId);
                numberOfTasksApplied++;
            }
        }
        LOG.info("Global upgrade process finished, {}/{} upgrade(s) performed ({} already applied).",
                numberOfTasksApplied, tasks.size(), alreadyApplied);
    }

}