def group_files(files_to_sort, reader=None, time_threshold=10,
                group_keys=None, ppp_config_dir=None, reader_kwargs=None):
    if reader is None:
        raise ValueError("'reader' keyword argument is required.")
    elif not isinstance(reader, (list, tuple)):
        reader = [reader]
    reader = reader[0]
    reader_configs = list(configs_for_reader(reader, ppp_config_dir))[0]
    reader_kwargs = reader_kwargs or {}
    try:
        reader_instance = load_reader(reader_configs, **reader_kwargs)
    except (KeyError, IOError, yaml.YAMLError) as err:
        LOG.info('Cannot use %s', str(reader_configs))
        LOG.debug(str(err))
        raise
    if group_keys is None:
        group_keys = reader_instance.info.get('group_keys', ('start_time',))
    file_keys = []
    for filetype, filetype_info in reader_instance.sorted_filetype_items():
        for f, file_info in reader_instance.filename_items_for_filetype(files_to_sort, filetype_info):
            group_key = tuple(file_info.get(k) for k in group_keys)
            file_keys.append((group_key, f))
    prev_key = None
    threshold = timedelta(seconds=time_threshold)
    file_groups = {}
    for gk, f in sorted(file_keys):
        if prev_key is None:
            is_new_group = True
            prev_key = gk
        elif isinstance(gk[0], datetime):
            is_new_group = (gk[0] - prev_key[0]) > threshold
        else:
            is_new_group = gk[0] != prev_key[0]
        vals_not_equal = (this_val != prev_val for this_val, prev_val in zip(gk[1:], prev_key[1:])
                          if this_val is not None and prev_val is not None)
        if is_new_group or any(vals_not_equal):
            file_groups[gk] = [f]
            prev_key = gk
        else:
            file_groups[prev_key].append(f)
    sorted_group_keys = sorted(file_groups)
    return [{reader: file_groups[group_key]} for group_key in sorted_group_keys]