public function execute()
    {
        // Update the build in the database, ping any external services.
        $this->build->setStatus(Build::STATUS_RUNNING);
        $this->build->setStarted(new \DateTime());
        $this->store->save($this->build);
        $this->build->sendStatusPostback();
        $success = true;

        $previous_build = $this->build->getProject()->getPreviousBuild($this->build->getBranch());

        $previous_state = Build::STATUS_NEW;

        if ($previous_build) {
            $previous_state = $previous_build->getStatus();
        }

        try {
            // Set up the build:
            $this->setupBuild();

            // Run the core plugin stages:
            foreach (array('setup', 'test') as $stage) {
                $success &= $this->pluginExecutor->executePlugins($this->config, $stage);
            }

            // Set the status so this can be used by complete, success and failure
            // stages.
            if ($success) {
                $this->build->setStatus(Build::STATUS_SUCCESS);
            } else {
                $this->build->setStatus(Build::STATUS_FAILED);
            }


            if ($success) {
                $this->pluginExecutor->executePlugins($this->config, 'success');

                if ($previous_state == Build::STATUS_FAILED) {
                    $this->pluginExecutor->executePlugins($this->config, 'fixed');
                }

                $this->buildLogger->logSuccess(Lang::get('build_success'));
            } else {
                $this->pluginExecutor->executePlugins($this->config, 'failure');

                if ($previous_state == Build::STATUS_SUCCESS || $previous_state == Build::STATUS_NEW) {
                    $this->pluginExecutor->executePlugins($this->config, 'broken');
                }

                $this->buildLogger->logFailure(Lang::get('build_failed'));
            }
        } catch (\Exception $ex) {
            $this->build->setStatus(Build::STATUS_FAILED);
            $this->buildLogger->logFailure(Lang::get('exception') . $ex->getMessage());
        }finally{
            // Complete stage plugins are always run
            $this->pluginExecutor->executePlugins($this->config, 'complete');
        }


        // Update the build in the database, ping any external services, etc.
        $this->build->sendStatusPostback();
        $this->build->setFinished(new \DateTime());

        // Clean up:
        $this->buildLogger->log(Lang::get('removing_build'));
        $this->build->removeBuildDirectory();

        $this->store->save($this->build);
    }