/** {@inheritDoc} */
  @SuppressWarnings("ConstantConditions")
  @Override
  protected boolean onFieldsPageReady(
      boolean loc,
      GridCacheQueryInfo qryInfo,
      @Nullable List<GridQueryFieldMetadata> metadata,
      @Nullable Collection<?> entities,
      @Nullable Collection<?> data,
      boolean finished,
      @Nullable Throwable e) {
    assert qryInfo != null;

    if (e != null) {
      if (loc) {
        GridCacheLocalFieldsQueryFuture fut =
            (GridCacheLocalFieldsQueryFuture) qryInfo.localQueryFuture();

        fut.onPage(null, null, null, e, true);
      } else
        sendQueryResponse(
            qryInfo.senderId(),
            new GridCacheQueryResponse(cctx.cacheId(), qryInfo.requestId(), e),
            qryInfo.query().timeout());

      return true;
    }

    if (loc) {
      GridCacheLocalFieldsQueryFuture fut =
          (GridCacheLocalFieldsQueryFuture) qryInfo.localQueryFuture();

      fut.onPage(null, metadata, data, null, finished);
    } else {
      GridCacheQueryResponse res =
          new GridCacheQueryResponse(
              cctx.cacheId(), qryInfo.requestId(), finished, qryInfo.reducer() == null);

      res.metadata(metadata);
      res.data(entities != null ? entities : data);

      if (!sendQueryResponse(qryInfo.senderId(), res, qryInfo.query().timeout())) return false;
    }

    return true;
  }
  /** {@inheritDoc} */
  @Override
  public CacheQueryFuture<?> queryFieldsLocal(GridCacheQueryBean qry) {
    assert cctx.config().getCacheMode() != LOCAL;

    if (log.isDebugEnabled()) log.debug("Executing query on local node: " + qry);

    GridCacheLocalFieldsQueryFuture fut = new GridCacheLocalFieldsQueryFuture(cctx, qry);

    try {
      qry.query().validate();

      fut.execute();
    } catch (IgniteCheckedException e) {
      fut.onDone(e);
    }

    return fut;
  }