def __handle_non_steady_cases(self) -> Iterator[Transition]:
        """Handle cases when set of transitions produced on previous run was interrupted.

        :yields: transitions as :class:`Transition` objects.
        """
        if self.sync < self.voters:
            logger.debug("Case 1: synchronous_standby_names %s is a subset of DCS state %s", self.sync, self.voters)
            # Case 1: voters is superset of sync nodes. In the middle of changing voters (quorum).
            # Evict  dead nodes from voters that are not being synced.
            remove_from_voters = self.voters - (self.sync | self.active)
            if remove_from_voters:
                yield from self.quorum_update(
                    quorum=len(self.voters) - len(remove_from_voters) - self.numsync,
                    voters=CaseInsensitiveSet(self.voters - remove_from_voters),
                    adjust_quorum=not (self.sync - self.active))
            # Start syncing to nodes that are in voters and alive
            add_to_sync = (self.voters & self.active) - self.sync
            if add_to_sync:
                yield from self.sync_update(self.numsync, CaseInsensitiveSet(self.sync | add_to_sync))
        elif self.sync > self.voters:
            logger.debug("Case 2: synchronous_standby_names %s is a superset of DCS state %s", self.sync, self.voters)
            # Case 2: sync is superset of voters nodes. In the middle of changing replication factor (sync).
            # Add to voters nodes that are already synced and active
            remove_from_sync = self.sync - self.active
            sync = CaseInsensitiveSet(self.sync - remove_from_sync)
            # If sync will not become empty after removing dead nodes - remove them.
            # However, do it carefully, between sync and voters should remain common nodes!
            if remove_from_sync and sync and (not self.voters or sync & self.voters):
                yield from self.sync_update(min(self.numsync, len(self.sync) - len(remove_from_sync)), sync)
            add_to_voters = (self.sync - self.voters) & self.active
            if add_to_voters:
                voters = CaseInsensitiveSet(self.voters | add_to_voters)
                yield from self.quorum_update(len(voters) - self.numsync, voters)
            # Remove from sync nodes that are dead
            remove_from_sync = self.sync - self.voters
            if remove_from_sync:
                yield from self.sync_update(
                    numsync=min(self.numsync, len(self.sync) - len(remove_from_sync)),
                    sync=CaseInsensitiveSet(self.sync - remove_from_sync))

        # After handling these two cases voters and sync must match.
        assert self.voters == self.sync

        safety_margin = self.quorum + min(self.numsync, self.numsync_confirmed) - len(self.voters | self.sync)
        if safety_margin > 0:  # In the middle of changing replication factor.
            if self.numsync > self.sync_wanted:
                numsync = max(self.sync_wanted, len(self.voters) - self.quorum)
                logger.debug('Case 3: replication factor %d is bigger than needed %d', self.numsync, numsync)
                yield from self.sync_update(numsync, self.sync)
            else:
                quorum = len(self.sync) - self.numsync
                logger.debug('Case 4: quorum %d is bigger than needed %d', self.quorum, quorum)
                yield from self.quorum_update(quorum, self.voters)
        else:
            safety_margin = self.quorum + self.numsync - len(self.voters | self.sync)
            if self.numsync == self.sync_wanted and safety_margin > 0 and self.numsync > self.numsync_confirmed:
                yield from self.quorum_update(len(self.sync) - self.numsync, self.voters)
Handle cases when set of transitions produced on previous run was interrupted.

        :yields: transitions as :class:`Transition` objects.
        
patroni/quorum.py