class SparqlThingQuery implements ThingQuery {

    @Override
    public List<Thing> filter(Collection<Thing> things) {
        if (things.isEmpty()) {
            return List.of();
        }

        // create rdf repository with all things
        SailRepository repository = new SailRepository(new MemoryStore());
        repository.init();

        Map<String, Thing> resourceToThings = new HashMap<>();
        for (Thing thing : things) {
            StringReader reader = new StringReader(thing.toJson());
            try {
                Model model = Rio.parse(reader, DEFAULT_BASE_IRI, FORMAT);
                RdfResource resource = new RdfResource(model);

                resourceToThings.put(resource.getIri().stringValue(), thing);

                Repositories.consume(repository, connection -> {
                    connection.add(resource.getMetadata());
                    connection.add(resource.getContent(), resource.getIri());
                });
            }
            catch (IOException e) {
                log.warn("Unable to create rdf resource for thing {}: {}", thing.getId(), e.getMessage());
            }
        }

        // apply query on repository
        Set<String> filteredIris = Repositories.tupleQuery(repository, "SELECT DISTINCT ?__id__ WHERE { GRAPH ?__id__ { " + query + " }}", result -> {
            Set<BindingSet> bindings = Iterations.asSet(result);
            return bindings.stream().map(b -> b.getValue("__id__").stringValue()).collect(Collectors.toSet());
        });

        // map returned iris to things
        List<Thing> filteredThings = filteredIris.stream()
                .map(resourceToThings::get).collect(Collectors.toList());

        repository.shutDown();

        return filteredThings;
    }

    public  SparqlThingQuery(String query);
      SparqlThingQuery();

}