public function run(Deployment $deployment)
    {
        parent::run($deployment);

        $applications = $deployment->getApplications();
        if (count($applications) === 0) {
            throw InvalidConfigurationException::createNoApplicationConfigured();
        }

        $nodes = $deployment->getNodes();
        if (count($nodes) === 0) {
            throw InvalidConfigurationException::createNoNodesConfigured();
        }

        foreach ($this->stages as $stage) {
            $deployment->getLogger()->notice('Stage ' . $stage);
            foreach ($nodes as $node) {
                $deployment->getLogger()->debug('Node ' . $node->getName());
                foreach ($applications as $application) {
                    if (! $application->hasNode($node)) {
                        continue;
                    }

                    $deployment->getLogger()->debug('Application ' . $application->getName());

                    try {
                        $this->executeStage($stage, $node, $application, $deployment);
                    } catch (DeploymentLockedException $exception) {
                        $deployment->setStatus(Deployment::STATUS_CANCELLED);
                        $deployment->getLogger()->info($exception->getMessage());
                        if ($this->enableRollback) {
                            $this->taskManager->rollback();
                        }

                        return;
                    } catch (Exception $exception) {
                        $deployment->setStatus(Deployment::STATUS_FAILED);
                        if ($this->enableRollback) {
                            if (array_search($stage, $this->stages, false) <= array_search('switch', $this->stages, false)) {
                                $deployment->getLogger()->error('Got exception "' . $exception->getMessage() . '" rolling back.');
                                $this->taskManager->rollback();
                            } else {
                                $deployment->getLogger()->error('Got exception "' . $exception->getMessage() . '" but after switch stage, no rollback necessary.');
                                $this->taskManager->reset();
                            }
                        } else {
                            $deployment->getLogger()->error('Got exception "' . $exception->getMessage() . '" but rollback disabled. Stopping.');
                        }

                        return;
                    }
                }
            }
        }
        if ($deployment->getStatus() === Deployment::STATUS_UNKNOWN) {
            $deployment->setStatus(Deployment::STATUS_SUCCESS);
        }
    }