@Override
    protected Object processResponse(final @NotNull Message msg, final @NotNull Connection con)
        throws Exception {
      processAck(msg, con);
      if (prSingleHopEnabled) {
        Part part = msg.getPart(0);
        byte[] bytesReceived = part.getSerializedForm();
        if (bytesReceived[0] != ClientMetadataService.INITIAL_VERSION
            && bytesReceived.length == ClientMetadataService.SIZE_BYTES_ARRAY_RECEIVED) {
          if (region != null) {
            ClientMetadataService cms = region.getCache().getClientMetadataService();
            byte myVersion =
                cms.getMetaDataVersion(region, Operation.UPDATE, key, value, callbackArg);
            if (myVersion != bytesReceived[0] || isAllowDuplicateMetadataRefresh()) {
              cms.scheduleGetPRMetaData(region, false, bytesReceived[1]);
            }
          }
        }
      }
      if (msg.getMessageType() == MessageType.REPLY && msg.getNumberOfParts() > 1) {
        int flags = msg.getPart(1).getInt();
        int partIdx = 2;
        Object oldValue = null;
        if ((flags & HAS_OLD_VALUE_FLAG) != 0) {
          oldValue = msg.getPart(partIdx++).getObject();
          if ((flags & OLD_VALUE_IS_OBJECT_FLAG) != 0 && oldValue instanceof byte[]) {
            try (ByteArrayDataInput din = new ByteArrayDataInput((byte[]) oldValue)) {
              oldValue = DataSerializer.readObject(din);
            }
          }
        }
        // if the server has versioning we will attach it to the client's event
        // here so it can be applied to the cache
        if ((flags & HAS_VERSION_TAG) != 0) {
          VersionTag tag = (VersionTag) msg.getPart(partIdx).getObject();
          // we use the client's ID since we apparently don't track the server's ID in connections
          tag.replaceNullIDs((InternalDistributedMember) con.getEndpoint().getMemberId());
          checkForDeltaConflictAndSetVersionTag(tag, con);
        }
        return oldValue;
      }
      return null;
    }
the operation will have either a region or a regionName. Names seem to be used by unit tests
to exercise operations without creating a real region
geode-core/src/main/java/org/apache/geode/cache/client/internal/PutOp.java