returns the next candidate_it of the next preference expressed in the ticket
        for this bundle, and the next ticket_state after preferences are moved along
        if the vote exhausts, candidate_id will be None

def bundle_to_next_candidate(self, bundle):
        """
        returns the next candidate_it of the next preference expressed in the ticket
        for this bundle, and the next ticket_state after preferences are moved along
        if the vote exhausts, candidate_id will be None
        """
        ticket_state = bundle.ticket_state
        while True:
            ticket_state = TicketState(ticket_state.preferences, ticket_state.up_to + 1)
            candidate_id = get_preference(ticket_state)
            # if the preference passes through an elected or excluded candidate, we
            # skip over it
            if candidate_id in self.candidates_elected or candidate_id in self.candidates_excluded:
                continue
            return candidate_id, ticket_state