class Camflake {

    public long next() {

        // elapsedTime
        long elapsed = getElapsedTime();
        // sequence
        int sequence = getSequence(elapsed);
        log.debug("sequence id: {}", sequence);
        // If sequence ID exceeded maximum value, it retries once to generate unique ID 2 milliseconds later.
        if (sequence > SEQUENCE_MAX) {
            sleep(TimeUnit.MILLISECONDS.toMillis(2L));

            elapsed = getElapsedTime();
            sequence = getSequence(elapsed);
            if (sequence > SEQUENCE_MAX) {
                throw new CamflakeException("Failed to issue sequence id.");
            }
        }

        long id = (elapsed << 22) | (sequence << 16) | machineId;
        log.debug("unique id: {}", id);

        return id;
    }

    public  Camflake(MachineId machineId, Instant baseTime);
    public  Camflake(MachineId machineId);
    public  Camflake();

}