class RestUtils {

    public static <T extends Thing> Response createPaginatedThingResponse(UriInfo uriInfo, Set<T> things,
                                                                          IRI sortIRI, int offset, int limit,
                                                                          boolean asc,
                                                                          Function<T, Boolean> filterFunction,
                                                                          String type, SesameTransformer transformer,
                                                                          BNodeService bNodeService) {
        long start = System.currentTimeMillis();
        try {
            if (offset > things.size()) {
                throw ErrorUtils.sendError("Offset exceeds total size", Response.Status.BAD_REQUEST);
            }
            Comparator<T> comparator = Comparator.comparing(dist -> dist.getProperty(sortIRI).get().stringValue());

            Stream<T> stream = things.stream();

            if (!asc) {
                comparator = comparator.reversed();
            }

            if (filterFunction != null) {
                stream = stream.filter(filterFunction::apply);
            }

            List<T> filteredThings = stream.collect(Collectors.toList());
            List<T> result = filteredThings.stream()
                    .sorted(comparator)
                    .skip(offset)
                    .limit(limit)
                    .collect(Collectors.toList());

            return createPaginatedResponse(uriInfo, result, filteredThings.size(), limit, offset, type, transformer,
                    bNodeService);
        } finally {
            LOG.trace("createPaginatedThingResponse took {}ms", System.currentTimeMillis() - start);
        }
    }

}