public function attach(EventDispatcher $eventDispatcher)
    {
        if (file_exists($this->databaseDirectory)) {
            throw new \RuntimeException(
                sprintf('Database directory: "%s" already exists', $this->databaseDirectory)
            );
        }

        mkdir($this->databaseDirectory, 0777, true);

        try {
            $db = new PDO($this->userDsn);
            $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (\PDOException $e) {
            rmdir($this->databaseDirectory);
            throw $e;
        }

        $eventDispatcher->listen('verify.start', function (Event $e) use ($db) {
            $e->getParameter('exercise')->seed($db);
            //make a copy - so solution can modify without effecting database user has access to
            copy($this->userDatabasePath, $this->solutionDatabasePath);
        });

        $eventDispatcher->listen('run.start', function (Event $e) use ($db) {
            $e->getParameter('exercise')->seed($db);
        });

        $eventDispatcher->listen('cli.verify.reference-execute.pre', function (CliExecuteEvent $e) {
            $e->prependArg($this->solutionDsn);
        });

        $eventDispatcher->listen(
            ['cli.verify.student-execute.pre', 'cli.run.student-execute.pre'],
            function (CliExecuteEvent $e) {
                $e->prependArg($this->userDsn);
            }
        );

        $eventDispatcher->insertVerifier('verify.finish', function (Event $e) use ($db) {
            $verifyResult = $e->getParameter('exercise')->verify($db);

            if (false === $verifyResult) {
                return Failure::fromNameAndReason($this->getName(), 'Database verification failed');
            }

            return new Success('Database Verification Check');
        });

        $eventDispatcher->listen(
            [
                'cli.verify.reference-execute.fail',
                'verify.finish',
                'run.finish'
            ],
            function (Event $e) use ($db) {
                unset($db);
                @unlink($this->userDatabasePath);
                @unlink($this->solutionDatabasePath);
                rmdir($this->databaseDirectory);
            }
        );
    }