public static boolean doPutOrCreate(LocalRegion rgn, EntryEventImpl ev, long lastMod) {
    try {
      boolean updated = false;
      boolean doUpdate = true; // start with assumption we have key and need value
      boolean invokeCallbacks = true;

      if (shouldDoRemoteCreate(rgn, ev)) {
        if (logger.isDebugEnabled()) {
          logger.debug("doPutOrCreate: attempting to update or create entry");
        }
        final long startPut = rgn.getCachePerfStats().getTime();
        final boolean isBucket = rgn.isUsedForPartitionedRegionBucket();
        if (isBucket) {
          BucketRegion br = (BucketRegion) rgn;
          br.getPartitionedRegion().getPrStats().startApplyReplication();
        }
        try {
          // if the oldValue is the DESTROYED token and overwrite is disallowed,
          // then basicPut will set the blockedDestroyed flag in the event
          boolean overwriteDestroyed = ev.getOperation().isCreate();
          try {
            boolean firstBasicUpdateSuccess =
                rgn.basicUpdate(ev, true, false, lastMod, overwriteDestroyed, true, true);
            if (firstBasicUpdateSuccess) {
              rgn.getCachePerfStats().endPut(startPut, ev.isOriginRemote());
              // we did a create, or replayed a create event
              doUpdate = false;
              updated = true;
            } else {
              // already exists. If it was blocked by the DESTROYED token, then
              // do no update.
              doUpdate = checkIfToUpdateAfterCreateFailed(rgn, ev);
            }
          } catch (ConcurrentCacheModificationException ex) {
            invokeCallbacks = false;
            doUpdate = checkIfToUpdateAfterCreateFailed(rgn, ev);
          }
        } finally {
          if (isBucket) {
            BucketRegion br = (BucketRegion) rgn;
            br.getPartitionedRegion().getPrStats().endApplyReplication(startPut);
          }
        }
      }

      // If we care about the region entry being updated, get its value
      // from this message.
      if (doUpdate) {
        if (!ev.isLocalInvalid()) {
          final long startPut = rgn.getCachePerfStats().getTime();
          boolean overwriteDestroyed = ev.getOperation().isCreate();
          final boolean isBucket = rgn.isUsedForPartitionedRegionBucket();
          if (isBucket) {
            BucketRegion br = (BucketRegion) rgn;
            br.getPartitionedRegion().getPrStats().startApplyReplication();
          }
          try {
            boolean secondBasicUpdateSuccess;
            try {
              secondBasicUpdateSuccess =
                  rgn.basicUpdate(ev, false, true, lastMod, overwriteDestroyed,
                      invokeCallbacks, true);
            } catch (ConcurrentCacheModificationException ex) {
              secondBasicUpdateSuccess = false;
              invokeCallbacks = false;
            }
            if (secondBasicUpdateSuccess) {
              rgn.getCachePerfStats().endPut(startPut, ev.isOriginRemote());
              if (logger.isTraceEnabled()) {
                logger.trace("Processing put key {} in region {}", ev.getKey(), rgn.getFullPath());
              }
            } else {
              // key not here, blocked by DESTROYED token or ConcurrentCacheModificationException
              // thrown during second update attempt
              if (rgn.isUsedForPartitionedRegionBucket()
                  || (rgn.getDataPolicy().withReplication() && rgn.getConcurrencyChecksEnabled())) {
                ev.makeCreate();
                boolean thirdBasicUpdateSuccess =
                    rgn.basicUpdate(ev, false, false, lastMod, true, invokeCallbacks, false);
                if (thirdBasicUpdateSuccess) {
                  rgn.getCachePerfStats().endPut(startPut, ev.isOriginRemote());
                }
              } else {
                if (rgn.getVersionVector() != null && ev.getVersionTag() != null) {
                  rgn.getVersionVector().recordVersion(
                      (InternalDistributedMember) ev.getDistributedMember(), ev.getVersionTag());
                }
                if (logger.isDebugEnabled()) {
                  logger.debug(
                      "While processing Update message, update not performed because this key is {}",
                      (ev.oldValueIsDestroyedToken() ? "blocked by DESTROYED/TOMBSTONE token"
                          : "not defined"));
                }
              }
            }
          } finally {
            if (isBucket) {
              BucketRegion br = (BucketRegion) rgn;
              br.getPartitionedRegion().getPrStats().endApplyReplication(startPut);
            }
          }
        } else { // supplied null, must be a create operation
          if (logger.isTraceEnabled()) {
            logger.trace("Processing create with null value provided, value not put");
          }
        }
      } else {
        if (rgn.getVersionVector() != null && ev.getVersionTag() != null
            && !ev.getVersionTag().isRecorded()) {
          rgn.getVersionVector().recordVersion(
              (InternalDistributedMember) ev.getDistributedMember(), ev.getVersionTag());
        }
        if (!updated) {
          if (logger.isDebugEnabled()) {
            logger.debug(
                "While processing Update message, update not performed because key was created but mirroring keys only and value not in update message, OR key was not new for sender and has been destroyed here");
          }
        }
      }
      return true;
    } catch (CacheWriterException e) {
      throw new Error("CacheWriter should not be called", e);
    } catch (TimeoutException e) {
      throw new Error(
          "DistributedLock should not be acquired",
          e);
    }
  }
Does a remote update (could be create or put). This code was factored into a static for
QueuedOperation.

@param rgn the region to do the update on
@param ev the event describing the operation
@param lastMod the modification timestamp for this op
@return true if the update was done.
@since GemFire 5.0
geode-core/src/main/java/org/apache/geode/internal/cache/AbstractUpdateOperation.java