class SimpleStateManager implements StateManager {

    @Override
    public Map<Resource, Model> getStates(@Nullable String username, @Nullable String applicationId,
                                          Set<Resource> subjects) {
        Map<Resource, Model> states = new HashMap<>();
        try (RepositoryConnection conn = repository.getConnection()) {
            TupleQuery statesQuery;
            if (applicationId != null && !applicationId.isEmpty()) {
                Application app = applicationManager.getApplication(applicationId).orElseThrow(() ->
                        new IllegalArgumentException("Application not found"));
                statesQuery = conn.prepareTupleQuery(GET_APPLICATION_STATES_QUERY);
                statesQuery.setBinding(APPLICATION_BINDING, app.getResource());
            } else {
                statesQuery = conn.prepareTupleQuery(GET_STATES_QUERY);
            }
            if (username != null && !username.isEmpty()) {
                User user = engineManager.retrieveUser(username).orElseThrow(() ->
                        new IllegalArgumentException("User not found"));
                statesQuery.setBinding(USER_BINDING, user.getResource());
            }
            TupleQueryResult results = statesQuery.evaluate();

            BindingSet bindings;
            while (results.hasNext() && (bindings = results.next()).getBindingNames().contains(STATE_ID_BINDING)) {
                Resource stateId = Bindings.requiredResource(bindings, STATE_ID_BINDING);
                bindings.getBinding(RESOURCES_BINDING).ifPresent(binding -> {
                    Set<Resource> resources = Arrays.stream(StringUtils.split(binding.getValue().stringValue(), ","))
                            .map(factory::createIRI)
                            .collect(Collectors.toSet());

                    if (subjects.isEmpty() || resources.containsAll(subjects)) {
                        Model stateModel = modelFactory.createModel();
                        resources.forEach(resource -> conn.getStatements(resource, null, null)
                                .forEach(stateModel::add));
                        states.put(stateId, stateModel);
                    }
                });
            }
            return states;
        }
    }

}