@Override
  public Collection<V> values(Predicate predicate) {
    PagingPredicate pagingPredicate = null;
    if (predicate instanceof PagingPredicate) {
      pagingPredicate = (PagingPredicate) predicate;
      pagingPredicate.setIterationType(IterationType.VALUE);

      if (pagingPredicate.getPage() > 0 && pagingPredicate.getAnchor() == null) {
        pagingPredicate.previousPage();
        values(pagingPredicate);
        pagingPredicate.nextPage();
      }
    }
    MapQueryRequest request = new MapQueryRequest(name, predicate, IterationType.VALUE);
    QueryResultSet result = invoke(request);

    if (pagingPredicate == null) {
      final ArrayList<V> values = new ArrayList<V>(result.size());
      for (Object data : result) {
        V value = toObject(data);
        values.add(value);
      }
      return values;
    }

    List<Entry<Object, V>> valueEntryList = new ArrayList<Entry<Object, V>>(result.size());
    final Iterator<Entry> iterator = result.rawIterator();
    while (iterator.hasNext()) {
      final Entry entry = iterator.next();
      K key = toObject(entry.getKey());
      V value = toObject(entry.getValue());
      valueEntryList.add(new AbstractMap.SimpleImmutableEntry<Object, V>(key, value));
    }

    Collections.sort(
        valueEntryList,
        SortingUtil.newComparator(pagingPredicate.getComparator(), IterationType.VALUE));
    if (valueEntryList.size() > pagingPredicate.getPageSize()) {
      valueEntryList = valueEntryList.subList(0, pagingPredicate.getPageSize());
    }
    Entry anchor = null;
    if (valueEntryList.size() != 0) {
      anchor = valueEntryList.get(valueEntryList.size() - 1);
    }
    PagingPredicateAccessor.setPagingPredicateAnchor(pagingPredicate, anchor);

    final ArrayList<V> values = new ArrayList<V>(valueEntryList.size());
    for (Entry<Object, V> objectVEntry : valueEntryList) {
      values.add(objectVEntry.getValue());
    }
    return values;
  }
  @Override
  public Set<K> keySet(Predicate predicate) {
    PagingPredicate pagingPredicate = null;
    if (predicate instanceof PagingPredicate) {
      pagingPredicate = (PagingPredicate) predicate;
      pagingPredicate.setIterationType(IterationType.KEY);

      if (pagingPredicate.getPage() > 0 && pagingPredicate.getAnchor() == null) {
        pagingPredicate.previousPage();
        keySet(pagingPredicate);
        pagingPredicate.nextPage();
      }
    }
    MapQueryRequest request = new MapQueryRequest(name, predicate, IterationType.KEY);
    QueryResultSet result = invoke(request);
    if (pagingPredicate == null) {
      final HashSet<K> keySet = new HashSet<K>();
      for (Object o : result) {
        final K key = toObject(o);
        keySet.add(key);
      }
      return keySet;
    }

    final Comparator<Entry> comparator =
        SortingUtil.newComparator(pagingPredicate.getComparator(), IterationType.KEY);
    final SortedQueryResultSet sortedResult =
        new SortedQueryResultSet(comparator, IterationType.KEY, pagingPredicate.getPageSize());

    final Iterator<Entry> iterator = result.rawIterator();
    while (iterator.hasNext()) {
      final Entry entry = iterator.next();
      final K key = toObject(entry.getKey());
      final V value = toObject(entry.getValue());
      sortedResult.add(new AbstractMap.SimpleImmutableEntry<K, V>(key, value));
    }

    PagingPredicateAccessor.setPagingPredicateAnchor(pagingPredicate, sortedResult.last());

    return (Set<K>) sortedResult;
  }
  @Override
  public Set<Entry<K, V>> entrySet(Predicate predicate) {
    PagingPredicate pagingPredicate = null;
    if (predicate instanceof PagingPredicate) {
      pagingPredicate = (PagingPredicate) predicate;
      pagingPredicate.setIterationType(IterationType.ENTRY);

      if (pagingPredicate.getPage() > 0 && pagingPredicate.getAnchor() == null) {
        pagingPredicate.previousPage();
        entrySet(pagingPredicate);
        pagingPredicate.nextPage();
      }
    }

    MapQueryRequest request = new MapQueryRequest(name, predicate, IterationType.ENTRY);
    QueryResultSet result = invoke(request);
    Set entrySet;
    if (pagingPredicate == null) {
      entrySet = new HashSet<Entry<K, V>>(result.size());
    } else {
      entrySet =
          new SortedQueryResultSet(
              pagingPredicate.getComparator(), IterationType.ENTRY, pagingPredicate.getPageSize());
    }
    for (Object data : result) {
      AbstractMap.SimpleImmutableEntry<Data, Data> dataEntry =
          (AbstractMap.SimpleImmutableEntry<Data, Data>) data;
      K key = toObject(dataEntry.getKey());
      V value = toObject(dataEntry.getValue());
      entrySet.add(new AbstractMap.SimpleEntry<K, V>(key, value));
    }
    if (pagingPredicate != null) {
      PagingPredicateAccessor.setPagingPredicateAnchor(
          pagingPredicate, ((SortedQueryResultSet) entrySet).last());
    }
    return entrySet;
  }