protected boolean putObject(Conflatable event, long sequenceID)
        throws CacheException, InterruptedException {
      Long oldPosition = null;
      final boolean isDebugEnabled_BS = logger.isTraceEnabled(LogMarker.BRIDGE_SERVER_VERBOSE);
      if (isDebugEnabled_BS && lastSequenceIDPut >= sequenceID
          && !owningQueue.puttingGIIDataInQueue.get()) {
        logger.trace(LogMarker.BRIDGE_SERVER_VERBOSE,
            "HARegionQueue::DACE:putObject: Given sequence ID is already present ({}).\nThis may be a recovered operation via P2P or a GetInitialImage.\nlastSequenceIDPut = {} ; event = {};\n",
            sequenceID, lastSequenceIDPut, event);
      }

      boolean rejected = false;
      Conflatable eventInHARegion = null;

      synchronized (this) {
        if (sequenceID > lastSequenceIDPut) {
          if (logger.isTraceEnabled()) {
            logger.trace("HARegionQueue.putObject: adding {}", event);
          }
          lastSequenceIDPut = sequenceID;
        } else if (!owningQueue.puttingGIIDataInQueue.get()) {
          if (isDebugEnabled_BS) {
            logger.trace(LogMarker.BRIDGE_SERVER_VERBOSE,
                "{} eliding event with ID {}, because it is not greater than the last sequence ID ({}). The rejected event has key <{}> and value <{}>",
                this, event.getEventId(), lastSequenceIDPut, event.getKeyToConflate(),
                event.getValueToConflate());
          }
          owningQueue.stats.incNumSequenceViolated();

          // increase take side put permits instead of increasing put side permits
          owningQueue.incrementTakeSidePutPermits();// WithoutNotify();
          CacheClientNotifier ccn = CacheClientNotifier.getInstance();
          if (ccn != null) {
            ccn.getClientProxy(owningQueue.clientProxyID).getStatistics().incMessagesFailedQueued();
          }
          return true;
        }

        if (lastDispatchedSequenceId == TOKEN_DESTROYED) {
          return false;
        }

        if (sequenceID > lastDispatchedSequenceId || owningQueue.puttingGIIDataInQueue.get()) {
          // Insert the object into the Region
          Long position = owningQueue.tailKey.incrementAndGet();

          eventInHARegion = owningQueue.putEventInHARegion(event, position);

          // Add the position counter to the LinkedHashSet
          if (counters == null) {
            counters = new LinkedHashMap<>();
          }
          counters.put(position, null);

          // Check if the event is conflatable
          if (owningQueue.shouldBeConflated(eventInHARegion)) {
            // Add to the conflation map & get the position of the
            // old conflatable entry. The old entry may have inserted by the
            // same
            // ThreadIdentifier or different one.
            oldPosition = owningQueue.addToConflationMap(eventInHARegion, position);
          }

          // Take the size lock & add to the list of availabelIds
          // TODO: Asif : To implement blocking peek & take , ideally notify
          // should be issued
          // from this block & hence this function should be appropriately
          // overridden
          owningQueue.publish(position);
        } else {
          rejected = true;
        }
      }
      if (rejected) {
        owningQueue.incrementTakeSidePutPermits();// WithoutNotify();
        CacheClientNotifier ccn = CacheClientNotifier.getInstance();
        if (ccn != null) {
          ccn.getClientProxy(owningQueue.clientProxyID).getStatistics().incMessagesFailedQueued();
        }
      } else {
        owningQueue.entryEnqueued(eventInHARegion);
      }
      // Remove the old conflated position
      if (oldPosition != null) {
        // Obtain the DispatchedAndCurrentEvents object
        Conflatable old = (Conflatable) owningQueue.region.get(oldPosition);
        if (old != null) {
          ThreadIdentifier oldTi = HARegionQueue.getThreadIdentifier(old.getEventId());
          DispatchedAndCurrentEvents oldDace =
              (DispatchedAndCurrentEvents) owningQueue.eventsMap.get(oldTi);
          if (oldDace != null) {
            oldDace.removeOldConflatedEntry(oldPosition);
          }
        }
      }
      return true;
    }
This method adds to the conflation map & counters set if the add operation has not yet been
dispatched. Also it is the responsibility of this method to remove the old conflated entry.
As such we can assume only one thread can enter this function at a time because this DACE
object gets created for every ThreadIdentifier . And a given thread ( corresponding to this
thread identifier) is doing operation in sequence & a new add operation in DACE cannot happen
till the old one is done.

@param event Object to be added to the queue
@param sequenceID Sequence ID of the event originating from a unqiue thread identified by its
       ThreadIdentifier
geode-core/src/main/java/org/apache/geode/internal/cache/ha/HARegionQueue.java