private Object replaceWithCallbackArgument(Object key, Object value, Object callbackArg) {
    long startPut = getStatisticsClock().getTime();

    checkIfConcurrentMapOpsAllowed();

    if (value == null) {
      throw new NullPointerException();
    }

    validateArguments(key, value, callbackArg);
    checkReadiness();
    checkForLimitedOrNoAccess();

    @Released
    EntryEventImpl event =
        entryEventFactory.create(this, Operation.REPLACE, key, value, callbackArg, false,
            getMyId());

    try {
      if (generateEventID()) {
        event.setNewEventId(cache.getDistributedSystem());
      }

      discoverJTA();

      if (!basicPut(event, false, true, null, true)) {
        return null;
      }
      if (!getDataView().isDeferredStats()) {
        getCachePerfStats().endPut(startPut, false);
      }
      return event.getOldValue(); // may be null if was invalid

    } catch (EntryNotFoundException ignore) {
      // put failed on server
      return null;
    } finally {
      event.release();
    }
  }
Same as {@link #replace(Object, Object)} except a callback argument is supplied to be passed on
to <tt>CacheListener</tt>s and/or <tt>CacheWriter</tt>s.
<p>
TODO: callbackArg is always null but this method is for callbacks??
geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java