/**
  * Internal message delivery method.
  *
  * @pre threads > 0
  */
 private void sendUpdate(
     Address<? extends Receiver> receiver, Direction direction, Tuple updateElement) {
   ReteContainer affectedContainer = receiver.getContainer();
   synchronized (globalTerminationCriteria) {
     long newCriterion =
         affectedContainer.sendUpdateToLocalAddress(receiver, direction, updateElement);
     terminationCriterion(affectedContainer, newCriterion);
   }
 }
 /**
  * Sends multiple update messages atomically to the receiver node, indicating a newly found or
  * lost partial matching. The node may reside in any of the containers associated with this
  * network. To be called from a user thread during construction.
  *
  * @pre: structuralChangeLock MUST be grabbed by the sequence (but not necessarily this thread, as
  *     the sequence may span through network calls, that's why it's not enforced here )
  * @return the value of the target container's clock at the time when the message was accepted
  *     into its message queue
  */
 public void sendConstructionUpdates(
     Address<? extends Receiver> receiver, Direction direction, Collection<Tuple> updateElements) {
   // structuralChangeLock.lock();
   if (threads > 0) sendUpdates(receiver, direction, updateElements);
   else
     receiver
         .getContainer()
         .sendUpdatesToLocalAddressSingleThreaded(receiver, direction, updateElements);
   // structuralChangeLock.unlock();
 }
 /**
  * Internal message delivery method.
  *
  * @pre threads > 0
  */
 private void sendUpdates(
     Address<? extends Receiver> receiver, Direction direction, Collection<Tuple> updateElements) {
   if (updateElements.isEmpty()) return;
   ReteContainer affectedContainer = receiver.getContainer();
   synchronized (globalTerminationCriteria) {
     long newCriterion =
         affectedContainer.sendUpdatesToLocalAddress(receiver, direction, updateElements);
     terminationCriterion(affectedContainer, newCriterion);
   }
 }
 /**
  * Severs connection between a supplier and a receiver node, regardless which container they are
  * in. Not to be called remotely, because this method enforces the structural lock.
  *
  * @param supplier
  * @param receiver
  * @param desynchronise indicates whether the current contents of the supplier should be
  *     subtracted from the receiver
  */
 public void disconnectRemoteNodes(
     Address<? extends Supplier> supplier,
     Address<? extends Receiver> receiver,
     boolean desynchronise) {
   try {
     if (threads > 0) structuralChangeLock.lock();
     receiver.getContainer().disconnectRemoteNodes(supplier, receiver, desynchronise);
   } finally {
     if (threads > 0) structuralChangeLock.unlock();
   }
 }
 /**
  * Internal message delivery method for single-threaded operation
  *
  * @pre threads == 0
  */
 private void sendUpdateSingleThreaded(
     Address<? extends Receiver> receiver, Direction direction, Tuple updateElement) {
   ReteContainer affectedContainer = receiver.getContainer();
   affectedContainer.sendUpdateToLocalAddressSingleThreaded(receiver, direction, updateElement);
 }