@Override
 public CompletableFuture<Void> visitGetKeysInGroupCommand(
     final InvocationContext ctx, GetKeysInGroupCommand command) throws Throwable {
   final String groupName = command.getGroupName();
   if (!command.isGroupOwner()) {
     return ctx.continueInvocation();
   }
   final KeyFilter<Object> keyFilter =
       new CompositeKeyFilter<>(
           new GroupFilter<>(groupName, groupManager),
           new CollectionKeyFilter<>(ctx.getLookedUpEntries().keySet()));
   dataContainer.executeTask(
       keyFilter,
       (o, internalCacheEntry) -> {
         synchronized (ctx) {
           // the process can be made in multiple threads, so we need to synchronize in the
           // context.
           entryFactory.wrapExternalEntry(
               ctx,
               internalCacheEntry.getKey(),
               internalCacheEntry,
               EntryFactory.Wrap.STORE,
               false);
         }
       });
   return ctx.continueInvocation();
 }
  protected final void commitContextEntries(
      InvocationContext ctx, FlagAffectedCommand command, Metadata metadata) {
    final Flag stateTransferFlag = extractStateTransferFlag(ctx, command);

    if (stateTransferFlag == null) {
      // it is a normal operation
      stopStateTransferIfNeeded(command);
    }

    if (ctx instanceof SingleKeyNonTxInvocationContext) {
      SingleKeyNonTxInvocationContext singleKeyCtx = (SingleKeyNonTxInvocationContext) ctx;
      commitEntryIfNeeded(ctx, command, singleKeyCtx.getCacheEntry(), stateTransferFlag, metadata);
    } else {
      Set<Map.Entry<Object, CacheEntry>> entries = ctx.getLookedUpEntries().entrySet();
      Iterator<Map.Entry<Object, CacheEntry>> it = entries.iterator();
      final Log log = getLog();
      while (it.hasNext()) {
        Map.Entry<Object, CacheEntry> e = it.next();
        CacheEntry entry = e.getValue();
        if (!commitEntryIfNeeded(ctx, command, entry, stateTransferFlag, metadata)) {
          if (trace) {
            if (entry == null)
              log.tracef("Entry for key %s is null : not calling commitUpdate", toStr(e.getKey()));
            else
              log.tracef(
                  "Entry for key %s is not changed(%s): not calling commitUpdate",
                  toStr(e.getKey()), entry);
          }
        }
      }
    }
  }
  public void testWriteLockIsAcquired() throws Exception {
    advancedCache.put("k", "v");
    assertNotLocked(advancedCache, "k");
    tm.begin();
    advancedCache.withFlags(Flag.FORCE_WRITE_LOCK).get("k");

    InvocationContext ic = advancedCache.getInvocationContextContainer().getInvocationContext(true);
    CacheEntry cacheEntry = ic.getLookedUpEntries().get("k");
    assert (cacheEntry instanceof ReadCommittedEntry && cacheEntry.isChanged());

    assertLocked(advancedCache, "k");
    tm.commit();
    assertNotLocked(advancedCache, "k");
  }