public boolean basicPut(EntryEventImpl event, boolean ifNew, boolean originRemote)
      throws CacheWriterException, TimeoutException {
    byte putOp = OP_CREATE;
    boolean doingCreate = true;
    if (!ifNew) {
      if (existsLocally()) {
        putOp = OP_PUT;
        doingCreate = false;
      }
    }
    if (doingCreate) {
      event.makeCreate();
    } else {
      event.makeUpdate();
    }
    if (event.isNetSearch()) {
      putOp += (byte) (OP_SEARCH_PUT - OP_PUT);
    } else if (event.isLocalLoad()) {
      putOp += (byte) (OP_LLOAD_PUT - OP_PUT);
    } else if (event.isNetLoad()) {
      putOp += (byte) (OP_NLOAD_PUT - OP_PUT);
    }
    bulkOp = event.getOperation().isPutAll();
    byte advisedOp = adviseOp(putOp, event);

    InternalRegion internalRegion = event.getRegion();
    if (!event.isNetSearch()) {
      CacheWriter cWriter = internalRegion.basicGetWriter();
      boolean oldOriginRemote = event.isOriginRemote();
      if (event.hasClientOrigin() || originRemote) {
        event.setOriginRemote(true);
      }
      if (cWriter != null && event.isGenerateCallbacks() && !event.inhibitAllNotifications()) {
        if (doingCreate) {
          cWriter.beforeCreate(event);
        } else {
          cWriter.beforeUpdate(event);
        }
      }
      event.setOriginRemote(oldOriginRemote);
    }

    performOp(advisedOp, event);

    if (putOp == OP_CREATE) {
      fetchRemoteVersionTag(event);
    }
    return true;
  }
@param event the event object for this operation, with the exception that the oldValue
       parameter is not yet filled in. The oldValue will be filled in by this operation.

@param ifNew true if this operation must not overwrite an existing key
@param originRemote value for cacheWriter's isOriginRemote flag
@return true if put was done; otherwise returns false
geode-core/src/main/java/org/apache/geode/internal/cache/TXEntryState.java