public ResignedState(
        Time time,
        int localId,
        int epoch,
        Set<Integer> voters,
        long electionTimeoutMs,
        List<ReplicaKey> preferredSuccessors,
        Endpoints endpoints,
        LogContext logContext
    ) {
        this.localId = localId;
        this.epoch = epoch;
        this.voters = voters;
        this.unackedVoters = new HashSet<>(voters);
        this.unackedVoters.remove(localId);
        this.electionTimeoutMs = electionTimeoutMs;
        this.electionTimer = time.timer(electionTimeoutMs);
        this.preferredSuccessors = preferredSuccessors;
        this.endpoints = endpoints;
        this.log = logContext.logger(ResignedState.class);
    }
@Test
    public void testResignedState() {
        int remoteId = 1;
        Set<Integer> voters = Utils.mkSet(localId, remoteId);

        ResignedState state = newResignedState(voters);

        assertEquals(ElectionState.withElectedLeader(epoch, localId, voters), state.election());
        assertEquals(epoch, state.epoch());

        assertEquals(Collections.singleton(remoteId), state.unackedVoters());
        state.acknowledgeResignation(remoteId);
        assertEquals(Collections.emptySet(), state.unackedVoters());

        assertEquals(electionTimeoutMs, state.remainingElectionTimeMs(time.milliseconds()));
        assertFalse(state.hasElectionTimeoutExpired(time.milliseconds()));
        time.sleep(electionTimeoutMs / 2);
        assertEquals(electionTimeoutMs / 2, state.remainingElectionTimeMs(time.milliseconds()));
        assertFalse(state.hasElectionTimeoutExpired(time.milliseconds()));
        time.sleep(electionTimeoutMs / 2);
        assertEquals(0, state.remainingElectionTimeMs(time.milliseconds()));
        assertTrue(state.hasElectionTimeoutExpired(time.milliseconds()));
    }