public function negotiate()
    {
        // This is a workaround for PHP5.5, @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/143#issuecomment-108148498
        $catchedException = null;

        try {
            $this->lock->acquire();
            $this->executeMigrations();
        } catch (LockingException $exc) {
            $this->logger->emergency($exc->getMessage());

            $catchedException = $exc;
        } catch (TopologyViolationException $exc) {
            $this->logger->emergency('The version to migrate to is older than the current one.');

            $catchedException = $exc;
        } catch (MigrationException $exc) {
            $this->logger->emergency('Migration of version ' . $exc->getCode() . ' failed.', array($exc->getMessage()));

            $catchedException = $exc;
        }

        $this->lock->release();

        if (!is_null($catchedException)) {
            throw $catchedException;
        }
    }