@SuppressWarnings("unchecked")
    public static <R> QueryResult<R> handleBasicQueries(
        final Query<R> query,
        final PositionBound positionBound,
        final QueryConfig config,
        final StateStore store,
        final Position position,
        final StateStoreContext context
    ) {

        final long start = config.isCollectExecutionInfo() ? System.nanoTime() : -1L;
        final QueryResult<R> result;

        final QueryHandler handler = QUERY_HANDLER_MAP.get(query.getClass());
        synchronized (position) {
            if (handler == null) {
                result = QueryResult.forUnknownQueryType(query, store);
            } else if (context == null || !isPermitted(position, positionBound, context.taskId().partition())) {
                result = QueryResult.notUpToBound(
                    position,
                    positionBound,
                    context == null ? null : context.taskId().partition()
                );
            } else {
                result = (QueryResult<R>) handler.apply(
                    query,
                    positionBound,
                    config,
                    store
                );
            }
            if (config.isCollectExecutionInfo()) {
                result.addExecutionInfo(
                    "Handled in " + store.getClass() + " in " + (System.nanoTime() - start) + "ns"
                );
            }
            result.setPosition(position.copy());
        }
        return result;
    }
@Test
    public void shouldReturnErrorOnBoundViolation() {
        @SuppressWarnings("unchecked") final KeyQuery<String, Integer> query =
            Mockito.mock(KeyQuery.class);
        @SuppressWarnings("unchecked") final KeyValueStore<String, Integer> store =
            Mockito.mock(KeyValueStore.class);
        final StateStoreContext context = Mockito.mock(StateStoreContext.class);
        Mockito.when(context.taskId()).thenReturn(new TaskId(0, 0));
        final QueryResult<Integer> queryResult = StoreQueryUtils.handleBasicQueries(
            query,
            PositionBound.at(Position.emptyPosition().withComponent("topic", 0, 1)),
            new QueryConfig(false),
            store,
            Position.emptyPosition().withComponent("topic", 0, 0),
            context
        );

        assertThat(queryResult.isFailure(), is(true));
        assertThat(queryResult.getFailureReason(), is(FailureReason.NOT_UP_TO_BOUND));
        assertThat(
            queryResult.getFailureMessage(),
            is("For store partition 0, the current position Position{position={topic={0=0}}}"
                   + " is not yet up to the bound"
                   + " PositionBound{position=Position{position={topic={0=1}}}}")
        );
    }