public function run()
    {
        $this->logger->notice('Starting to run an election');
        $this->logger->notice(sprintf('There are %d candidates, %d ballots and to be %d winners', $this->election->getCandidateCount(), $this->validBallots, $this->election->getWinnersCount()));

        // Reject invalid ballots, then calculate the quota based on remaining valid ballots
        // p. 46(3) and p 47
        $this->rejectInvalidBallots();
        $this->setQuota();

        // First step of standard allocation of ballots
        // p. 46(1) and 46(2)
        $this->firstStep();

        $candidates = $this->election->getActiveCandidates();

        // All the re-allocation rounds until we have filled all seats or
        // have the same number of seats left to fill and candidates remaining
        // (then elect them).
        $this->processReallocationRounds($candidates);
        // p. 53
        $this->reallocateRemainingVotes($candidates);

        $this->logger->notice('Election complete');

        return $this->election->getElectedCandidates();
    }