def construct_entries_response(query_registry, tree, route, path, offset, limit, fields, filters, sort, base_url):
    path_parts = [segment for segment in path.split('/') if segment]
    if (not isinstance(tree, DuckTree)):
        raise WrongTypeForRoute('This is not a Tree.')
    queries = defaultdict(dict)
    for (key, value) in filters.items():
        if (value is None):
            continue
        (name, field) = _FILTER_PARAM_PATTERN.match(key).groups()
        queries[name][field] = value
    sorting = []
    if (sort is not None):
        for item in sort.split(','):
            if item:
                if item.startswith('-'):
                    sorting.append((item[1:], (- 1)))
                else:
                    sorting.append((item, 1))
    if sorting:
        if (not hasattr(tree, 'sort')):
            raise HTTPException(status_code=400, detail='This Tree does not support sorting.')
        tree = tree.sort(sorting)
    key_lookups = []
    for (query_name, parameters_dict_of_lists) in queries.items():
        for i in itertools.count(0):
            try:
                parameters = {field_name: parameters_list[i] for (field_name, parameters_list) in parameters_dict_of_lists.items()}
            except IndexError:
                break
            query_class = query_registry.name_to_query_type[query_name]
            for field in dataclasses.fields(query_class):
                if (getattr(field.type, '__origin__', None) is list):
                    (inner_type,) = field.type.__args__
                    parameters[field.name] = [inner_type(item) for item in parameters[field.name].split(',')]
            try:
                query = query_class(**parameters)
                if isinstance(query, KeyLookup):
                    key_lookups.append(query.key)
                    continue
                tree = tree.search(query)
            except QueryValueError as err:
                raise HTTPException(status_code=400, detail=err.args[0])
    if key_lookups:
        unique_key_lookups = set(key_lookups)
        (key_lookup, *others) = unique_key_lookups
        if others:
            tree = TreeInMemory({})
        else:
            try:
                tree = TreeInMemory({key_lookup: tree[key_lookup]}, must_revalidate=False)
            except KeyError:
                tree = TreeInMemory({})
    count = len_or_approx(tree)
    links = pagination_links(route, path_parts, offset, limit, count)
    data = []
    if (fields != [models.EntryFields.none]):
        items = tree.items_indexer[offset:(offset + limit)]
    else:
        items = ((key, None) for key in tree.keys_indexer[offset:(offset + limit)])
    metadata_stale_at = (datetime.utcnow() + timedelta(days=1000000))
    must_revalidate = getattr(tree, 'must_revalidate', True)
    for (key, entry) in items:
        resource = construct_resource(base_url, (path_parts + [key]), entry, fields)
        data.append(resource)
        if (metadata_stale_at is not None):
            if (getattr(entry, 'metadata_stale_at', None) is None):
                metadata_stale_at = None
            else:
                metadata_stale_at = min(metadata_stale_at, entry.metadata_stale_at)
    return (models.Response(data=data, links=links, meta={'count': count}), metadata_stale_at, must_revalidate)
def construct_entries_response(query_registry, tree, route, path, offset, limit, fields, filters, sort, base_url):
    path_parts = [segment for segment in path.split('/') if segment]
    if (not isinstance(tree, DuckTree)):
        raise WrongTypeForRoute('This is not a Tree.')
    queries = defaultdict(dict)
    for (key, value) in filters.items():
        if (value is None):
            continue
        (name, field) = _FILTER_PARAM_PATTERN.match(key).groups()
        queries[name][field] = value
    sorting = []
    if (sort is not None):
        for item in sort.split(','):
            if item:
                if item.startswith('-'):
                    sorting.append((item[1:], (- 1)))
                else:
                    sorting.append((item, 1))
    if sorting:
        if (not hasattr(tree, 'sort')):
            raise HTTPException(status_code=400, detail='This Tree does not support sorting.')
        tree = tree.sort(sorting)
    key_lookups = []
    for (query_name, parameters_dict_of_lists) in queries.items():
        for i in itertools.count(0):
            try:
                parameters = {field_name: parameters_list[i] for (field_name, parameters_list) in parameters_dict_of_lists.items()}
            except IndexError:
                break
            query_class = query_registry.name_to_query_type[query_name]
            for field in dataclasses.fields(query_class):
                if (getattr(field.type, '__origin__', None) is list):
                    (inner_type,) = field.type.__args__
                    parameters[field.name] = [inner_type(item) for item in parameters[field.name].split(',')]
            try:
                query = query_class(**parameters)
                if isinstance(query, KeyLookup):
                    key_lookups.append(query.key)
                    continue
                tree = tree.search(query)
            except QueryValueError as err:
                raise HTTPException(status_code=400, detail=err.args[0])
    if key_lookups:
        unique_key_lookups = set(key_lookups)
        (key_lookup, *others) = unique_key_lookups
        if others:
            tree = TreeInMemory({})
        else:
            try:
                tree = TreeInMemory({key_lookup: tree[key_lookup]}, must_revalidate=False)
            except KeyError:
                tree = TreeInMemory({})
    count = len_or_approx(tree)
    links = pagination_links(route, path_parts, offset, limit, count)
    data = []
    if (fields != [models.EntryFields.none]):
        items = tree.items_indexer[offset:(offset + limit)]
    else:
        items = ((key, None) for key in tree.keys_indexer[offset:(offset + limit)])
    metadata_stale_at = (datetime.utcnow() + timedelta(days=1000000))
    must_revalidate = getattr(tree, 'must_revalidate', True)
    for (key, entry) in items:
        resource = construct_resource(base_url, (path_parts + [key]), entry, fields)
        data.append(resource)
        if (metadata_stale_at is not None):
            if (getattr(entry, 'metadata_stale_at', None) is None):
                metadata_stale_at = None
            else:
                metadata_stale_at = min(metadata_stale_at, entry.metadata_stale_at)
    return (models.Response(data=data, links=links, meta={'count': count}), metadata_stale_at, must_revalidate)