class TaskAssignor {

    public static <C, T extends Comparable<T>> Map<C, ClientState<T>> assign(Map<C, ClientState<T>> states, Set<T> tasks, int numStandbyReplicas) {
        long seed = 0L;
        for (C client : states.keySet()) {
            seed += client.hashCode();
        }

        TaskAssignor<C, T> assignor = new TaskAssignor<>(states, tasks, seed);
        log.info("Assigning tasks to clients: {}, prevAssignmentBalanced: {}, " +
            "prevClientsUnchangeed: {}, tasks: {}, replicas: {}",
            states, assignor.prevAssignmentBalanced, assignor.prevClientsUnchanged,
            tasks, numStandbyReplicas);

        assignor.assignTasks();
        if (numStandbyReplicas > 0)
            assignor.assignStandbyTasks(numStandbyReplicas);

        log.info("Assigned with: " + assignor.states);
        return assignor.states;
    }

    private  TaskAssignor(Map<C, ClientState<T>> states, Set<T> tasks, long randomSeed);

}