@Override
  @SuppressWarnings("unchecked")
  public Collection values(Predicate predicate) {
    checkTransactionState();
    checkNotNull(predicate, "Predicate can not be null!");
    checkNotInstanceOf(
        PagingPredicate.class, predicate, "Paging is not supported for Transactional queries");

    MapService service = getService();
    MapServiceContext mapServiceContext = service.getMapServiceContext();
    MapQueryEngine queryEngine = mapServiceContext.getMapQueryEngine(name);
    SerializationService serializationService = getNodeEngine().getSerializationService();

    QueryResult result = queryEngine.invokeQueryAllPartitions(name, predicate, IterationType.ENTRY);
    QueryResultCollection<Map.Entry> queryResult =
        new QueryResultCollection<Map.Entry>(
            serializationService, IterationType.ENTRY, false, true, result);

    // TODO: Can't we just use the original set?
    List<Object> valueSet = new ArrayList<Object>();
    Set<Object> keyWontBeIncluded = new HashSet<Object>();

    // iterate over the txMap and see if the values are updated or removed
    for (Map.Entry<Data, TxnValueWrapper> entry : txMap.entrySet()) {
      boolean isRemoved = TxnValueWrapper.Type.REMOVED.equals(entry.getValue().type);
      boolean isUpdated = TxnValueWrapper.Type.UPDATED.equals(entry.getValue().type);

      Object keyObject = serializationService.toObject(entry.getKey());
      if (isRemoved) {
        keyWontBeIncluded.add(keyObject);
      } else {
        if (isUpdated) {
          keyWontBeIncluded.add(keyObject);
        }
        Object entryValue = entry.getValue().value;
        QueryableEntry queryEntry =
            new CachedQueryEntry(serializationService, entry.getKey(), entryValue);
        if (predicate.apply(queryEntry)) {
          valueSet.add(queryEntry.getValue());
        }
      }
    }
    removeFromResultSet(queryResult, valueSet, keyWontBeIncluded);
    return valueSet;
  }
  @Override
  @SuppressWarnings("unchecked")
  public Set keySet(Predicate predicate) {
    checkTransactionState();
    checkNotNull(predicate, "Predicate should not be null!");
    checkNotInstanceOf(
        PagingPredicate.class, predicate, "Paging is not supported for Transactional queries!");

    MapService service = getService();
    MapServiceContext mapServiceContext = service.getMapServiceContext();
    MapQueryEngine queryEngine = mapServiceContext.getMapQueryEngine(name);
    SerializationService serializationService = getNodeEngine().getSerializationService();

    QueryResult result = queryEngine.invokeQueryAllPartitions(name, predicate, IterationType.KEY);
    Set<Object> queryResult =
        new QueryResultCollection(serializationService, IterationType.KEY, false, true, result);

    // TODO: Can't we just use the original set?
    Set<Object> keySet = new HashSet<Object>(queryResult);
    for (Map.Entry<Data, TxnValueWrapper> entry : txMap.entrySet()) {
      Data keyData = entry.getKey();
      if (!TxnValueWrapper.Type.REMOVED.equals(entry.getValue().type)) {
        Object value =
            (entry.getValue().value instanceof Data)
                ? mapServiceContext.toObject(entry.getValue().value)
                : entry.getValue().value;

        QueryableEntry queryEntry = new CachedQueryEntry(serializationService, keyData, value);
        // apply predicate on txMap
        if (predicate.apply(queryEntry)) {
          Object keyObject = serializationService.toObject(keyData);
          keySet.add(keyObject);
        }
      } else {
        // meanwhile remove keys which are not in txMap
        Object keyObject = serializationService.toObject(keyData);
        keySet.remove(keyObject);
      }
    }
    return keySet;
  }