'Dynamically selects block_ids indicating which of the possible children are displayed to the current user.
Arguments:
selected - list of (block_type, block_id) tuples assigned to this student
children - children of this block
max_count - number of components to display to each student
mode - how content is drawn from the library
Returns:
A dict containing the following keys:
\'selected\' (set) of (block_type, block_id) tuples assigned to this student
\'invalid\' (set) of dropped (block_type, block_id) tuples that are no longer valid
\'overlimit\' (set) of dropped (block_type, block_id) tuples that were previously selected
\'added\' (set) of newly added (block_type, block_id) tuples'

@classmethod
def make_selection(cls, selected, children, max_count, mode):

    selected = set((tuple(k) for k in selected))
    valid_block_keys = set([(c.block_type, c.block_id) for c in children])
    invalid_block_keys = (selected - valid_block_keys)
    if invalid_block_keys:
        selected -= invalid_block_keys
    overlimit_block_keys = set()
    while (len(selected) > max_count):
        overlimit_block_keys.add(selected.pop())
    num_to_add = (max_count - len(selected))
    added_block_keys = None
    if (num_to_add > 0):
        pool = (valid_block_keys - selected)
        if (mode == 'random'):
            num_to_add = min(len(pool), num_to_add)
            added_block_keys = set(random.sample(pool, num_to_add))
        else:
            raise NotImplementedError('Unsupported    mode.')
        selected |= added_block_keys
    return {'selected': selected, 'invalid': invalid_block_keys, 'overlimit': overlimit_block_keys, 'added': added_block_keys}
