diff -ru --exclude=CVS certi.orig/include/RTIambServices.hh certi.new/include/RTIambServices.hh
--- certi.orig/include/RTIambServices.hh	2007-06-14 15:00:21.000000000 +0200
+++ certi.new/include/RTIambServices.hh	2008-04-02 13:50:13.000000000 +0200
@@ -475,7 +475,7 @@
 Boolean tick2()
     throw (SpecifiedSaveLabelDoesNotExist, ConcurrentAccessAttempted, RTIinternalError);
 
-Boolean tick_kernel(bool)
+Boolean __tick_kernel(Boolean, TickTime, TickTime)
     throw (SpecifiedSaveLabelDoesNotExist, ConcurrentAccessAttempted, RTIinternalError);
 
 Boolean tick(TickTime, TickTime)
diff -ru --exclude=CVS certi.orig/libCERTI/Message.cc certi.new/libCERTI/Message.cc
--- certi.orig/libCERTI/Message.cc	2008-02-27 17:38:27.000000000 +0100
+++ certi.new/libCERTI/Message.cc	2008-04-02 13:48:42.000000000 +0200
@@ -194,6 +194,20 @@
 
 // ----------------------------------------------------------------------------
 void
+Message::setMinTickTime(RTI::TickTime time)
+{
+    minTickTime = time;
+}
+
+// ----------------------------------------------------------------------------
+void
+Message::setMaxTickTime(RTI::TickTime time)
+{
+    maxTickTime = time;
+}
+
+// ----------------------------------------------------------------------------
+void
 Message::setDimension(DimensionHandle handle)
 {
     dimension = handle ;
@@ -603,6 +617,8 @@
     dimension = msg.dimension ;
     // transportation = msg.transportation ;
     // ordering = msg.ordering ;
+    minTickTime = msg.minTickTime ;
+    maxTickTime = msg.maxTickTime ;
 
     strcpy(tag, msg.tag);
     strcpy(name, msg.name);
diff -ru --exclude=CVS certi.orig/libCERTI/Message.hh certi.new/libCERTI/Message.hh
--- certi.orig/libCERTI/Message.hh	2007-12-17 17:01:25.000000000 +0100
+++ certi.new/libCERTI/Message.hh	2008-04-02 13:47:45.000000000 +0200
@@ -310,6 +310,12 @@
     long getRegion() const { return region ; };
     void setRegion(long);
 
+    RTI::TickTime getMinTickTime() const { return minTickTime ; };
+    void setMinTickTime(RTI::TickTime);
+
+    RTI::TickTime getMaxTickTime() const { return maxTickTime ; };
+    void setMaxTickTime(RTI::TickTime);
+
     void setFederationTimeDelta(FederationTimeDelta);
     FederationTimeDelta getFederationTimeDelta() const
     { return lookahead ; };
@@ -415,6 +421,8 @@
     // OrderingHandle ordering ;
     unsigned long number ;
     long region ;
+    RTI::TickTime minTickTime;
+    RTI::TickTime maxTickTime;
 
 public:
     // used for both Attributes and Parameters arrays.
diff -ru --exclude=CVS certi.orig/libCERTI/Message_R.cc certi.new/libCERTI/Message_R.cc
--- certi.orig/libCERTI/Message_R.cc	2008-03-13 15:39:19.000000000 +0100
+++ certi.new/libCERTI/Message_R.cc	2008-04-02 13:52:15.000000000 +0200
@@ -441,8 +441,14 @@
           case DISABLE_TIME_REGULATION:
           case ENABLE_TIME_CONSTRAINED:
           case DISABLE_TIME_CONSTRAINED:
+            boolean = body.readLongInt();
+            break ;
+
+          // Body contains boolean, TickTime, TickTime
           case TICK_REQUEST:
             boolean = body.readLongInt();
+            body.readBlock((char *)&minTickTime, sizeof(minTickTime));
+            body.readBlock((char *)&maxTickTime, sizeof(maxTickTime));
             break ;
 
           // Body contains objectClass, handleArraySize,
diff -ru --exclude=CVS certi.orig/libCERTI/Message_W.cc certi.new/libCERTI/Message_W.cc
--- certi.orig/libCERTI/Message_W.cc	2008-03-13 15:39:19.000000000 +0100
+++ certi.new/libCERTI/Message_W.cc	2008-04-02 13:52:52.000000000 +0200
@@ -454,8 +454,14 @@
           case DISABLE_TIME_REGULATION:
           case ENABLE_TIME_CONSTRAINED:
           case DISABLE_TIME_CONSTRAINED:
+            body.writeLongInt(boolean);
+            break ;
+
+          // Body contains boolean, TickTime, TickTime
           case TICK_REQUEST:
             body.writeLongInt(boolean);
+            body.writeBlock((char *)&minTickTime, sizeof(minTickTime));
+            body.writeBlock((char *)&maxTickTime, sizeof(maxTickTime));
             break ;
 
           // Body contains objectClass, handleArray
diff -ru --exclude=CVS certi.orig/libRTI/RTIambassador.cc certi.new/libRTI/RTIambassador.cc
--- certi.orig/libRTI/RTIambassador.cc	2008-04-02 19:14:11.000000000 +0200
+++ certi.new/libRTI/RTIambassador.cc	2008-04-02 19:15:20.000000000 +0200
@@ -195,33 +195,46 @@
 }
 
 // ----------------------------------------------------------------------------
-// Tick
+//! Evoke callback (HLA1.3).
+/*! Non-blocking callback evocation, returns immediately with or without 1 callback.
+ *  @return Always returns false.
+ */
 RTI::Boolean
 RTI::RTIambassador::tick()
     throw (SpecifiedSaveLabelDoesNotExist,
            ConcurrentAccessAttempted,
            RTIinternalError)
 {
-   // non-blocking tick, returns immediately with or without 1 callback
-   return tick_kernel (false);
+   __tick_kernel(RTI_FALSE, 0.0, 0.0);
+   return RTI_FALSE;
 }
 
 // ----------------------------------------------------------------------------
-// Tick
+//! Evoke callback (CERTI extension).
+/*! Blocks until a callback delivery and then evokes a single callback.
+ *  Waits until a callback delivery, be careful.
+ *  @return true if additional callbacks pending, false otherwise
+ *  @warning This is a non-standard extension of the HLA 1.3 API.
+ */
 RTI::Boolean
 RTI::RTIambassador::tick2()
     throw (SpecifiedSaveLabelDoesNotExist,
            ConcurrentAccessAttempted,
            RTIinternalError)
 {
-   // blocking tick, waits until a callback delivery, be careful
-   return tick_kernel (true);
+   __tick_kernel(RTI_FALSE, std::numeric_limits<double>::infinity(), 0.0);
+   return RTI_FALSE;
 }
 
 // ----------------------------------------------------------------------------
-// Tick_kernel
+//! Generic callback evocation (CERTI extension).
+/*! Blocks up to "minimum" seconds until a callback delivery and then evokes a
+ *  single callback.
+ *  @return true if additional callbacks pending, false otherwise
+ *  @warning This is a non-standard extension of the HLA 1.3 API.
+ */
 RTI::Boolean
-RTI::RTIambassador::tick_kernel(bool locked)
+RTI::RTIambassador::__tick_kernel(RTI::Boolean multiple, TickTime minimum, TickTime maximum)
     throw (SpecifiedSaveLabelDoesNotExist,
            ConcurrentAccessAttempted,
            RTIinternalError)
@@ -230,10 +243,9 @@
 
     // Prevenir le RTI
     vers_RTI.type = Message::TICK_REQUEST ;
-    if (locked)
-       vers_RTI.setBoolean(true);
-    else
-       vers_RTI.setBoolean(false);
+    vers_RTI.setBoolean(multiple);
+    vers_RTI.setMinTickTime(minimum);
+    vers_RTI.setMaxTickTime(maximum);
 
     try {
         vers_RTI.write(privateRefs->socketUn);
@@ -245,285 +257,288 @@
         throw RTIinternalError("RTI::RTIambassador::tick_kernel (tick1) : NetworkError-->RTIinternalError");
     }
 
-    // Lire la reponse du RTIA local
-    try {
-        vers_Fed.read(privateRefs->socketUn);
-    }
-    catch (NetworkError) {
-        cout << "tick 2." << endl ;
-        cout << "LibRTI:: Catched NetworkError, throw RTIinternalError."
-             << endl ;
-        throw RTIinternalError("RTI::RTIambassador::tick_kernel (tick2) : NetworkError-->RTIinternalError");
-    }
+    // Read response(s) from the local RTIA until Message::TICK_REQUEST is received.
+    while (1) {
+        try {
+            vers_Fed.read(privateRefs->socketUn);
+        }
+        catch (NetworkError) {
+            cout << "tick 2." << endl ;
+            cout << "LibRTI:: Catched NetworkError, throw RTIinternalError."
+                 << endl ;
+            throw RTIinternalError("RTI::RTIambassador::tick_kernel (tick2) : NetworkError-->RTIinternalError");
+        }
 
-    // Si c'est de type TICK_REQUEST, il n'y a qu'a traiter l'exception.
-    if (vers_Fed.type == Message::TICK_REQUEST) {
-        privateRefs->processException(&vers_Fed);
-        return RTI::Boolean(vers_Fed.getBoolean());
-    }
+        vers_RTI.setException(e_NO_EXCEPTION);
+
+        try {		
+            //D.Mes( pdMessage, 'M', vers_Fed.type);
+            vers_Fed.trace("RTI::RTIambassador::tick ");
+                
+            switch (vers_Fed.type) {
+
+              // If the type is TICK_REQUEST, the __tick_kernel() has terminated.
+
+              case Message::TICK_REQUEST:
+                if (vers_Fed.getExceptionType() != e_NO_EXCEPTION)
+                    privateRefs->processException(&vers_Fed);
+                return RTI::Boolean(vers_Fed.getBoolean());
+
+              // Otherwise, the RTI calls a FederateAmbassador service.
+
+              case Message::SYNCHRONIZATION_POINT_REGISTRATION_SUCCEEDED:
+                privateRefs->fed_amb->synchronizationPointRegistrationSucceeded(vers_Fed.getLabel());
+                break ;
+
+              case Message::ANNOUNCE_SYNCHRONIZATION_POINT:
+                privateRefs->fed_amb->announceSynchronizationPoint(vers_Fed.getLabel(),vers_Fed.getTag());
+                break ;
+
+              case Message::FEDERATION_SYNCHRONIZED:
+                privateRefs->fed_amb->federationSynchronized(vers_Fed.getLabel());
+                break ;
+
+              case Message::INITIATE_FEDERATE_SAVE:
+                privateRefs->fed_amb->initiateFederateSave(vers_Fed.getLabel());
+                break ;
+
+              case Message::FEDERATION_SAVED:
+                privateRefs->fed_amb->federationSaved();
+                break ;
+
+              case Message::REQUEST_FEDERATION_RESTORE_SUCCEEDED:
+                privateRefs->fed_amb->requestFederationRestoreSucceeded(
+                    vers_Fed.getLabel());
+                break ;
+
+              case Message::REQUEST_FEDERATION_RESTORE_FAILED:
+                privateRefs->fed_amb->requestFederationRestoreFailed(vers_Fed.getLabel(),
+                                                        vers_Fed.getTag());
+                break ;
+
+              case Message::FEDERATION_RESTORE_BEGUN:
+                privateRefs->fed_amb->federationRestoreBegun();
+                break ;
+
+              case Message::INITIATE_FEDERATE_RESTORE:
+                privateRefs->fed_amb->initiateFederateRestore(vers_Fed.getLabel(),
+                                                 vers_Fed.getFederate());
+                break ;
+
+              case Message::FEDERATION_RESTORED:
+                privateRefs->fed_amb->federationRestored();
+                break ;
+
+              case Message::FEDERATION_NOT_RESTORED:
+                privateRefs->fed_amb->federationNotRestored();
+                break ;
+
+              case Message::START_REGISTRATION_FOR_OBJECT_CLASS: {
+                  privateRefs->fed_amb->startRegistrationForObjectClass(
+                     vers_Fed.getObjectClass());
+              } break ;
+
+              case Message::STOP_REGISTRATION_FOR_OBJECT_CLASS: {
+                  privateRefs->fed_amb->
+                      stopRegistrationForObjectClass(vers_Fed.getObjectClass());
+              } break ;
+
+              case Message::TURN_INTERACTIONS_ON: {
+                  privateRefs->fed_amb->turnInteractionsOn(vers_Fed.getInteractionClass());
+              } break ;
+
+              case Message::TURN_INTERACTIONS_OFF: {
+                  privateRefs->fed_amb->turnInteractionsOff(vers_Fed.getInteractionClass());
+              } break ;
+
+              case Message::DISCOVER_OBJECT_INSTANCE: {
+                  privateRefs->fed_amb->
+                      discoverObjectInstance(vers_Fed.getObject(),
+                                             vers_Fed.getObjectClass(),
+                                             vers_Fed.getName());
+              } break ;
+
+              case Message::REFLECT_ATTRIBUTE_VALUES: {
+                  G.Out(pdGendoc,"          tick_kernel call to reflectAttributeValues");
+                  AttributeHandleValuePairSet *attributes = vers_Fed.getAHVPS();
+                  if (vers_Fed.getBoolean())
+                     privateRefs->fed_amb->
+                         reflectAttributeValues(vers_Fed.getObject(),
+                                                *attributes,
+                                                vers_Fed.getFedTime(),
+                                                vers_Fed.getTag(),
+                                                vers_Fed.getEventRetraction());
+                  else
+                     privateRefs->fed_amb->
+                         reflectAttributeValues(vers_Fed.getObject(),
+                                                *attributes,
+                                                vers_Fed.getTag());
+                  delete attributes ;
+              } break ;
+
+              case Message::RECEIVE_INTERACTION:
+                  {
+                  ParameterHandleValuePairSet *parameters = vers_Fed.getPHVPS();
+                  if (vers_Fed.getBoolean())
+                      privateRefs->fed_amb->receiveInteraction(
+                                              vers_Fed.getInteractionClass(),
+                                              *parameters,
+                                              vers_Fed.getFedTime(),
+                                              vers_Fed.getTag(),
+                                              vers_Fed.getEventRetraction());
+                  else
+                      privateRefs->fed_amb->receiveInteraction(
+                                              vers_Fed.getInteractionClass(),
+                                              *parameters,
+                                              vers_Fed.getTag());
+
+                  delete parameters ;
+                  } break ;
+
+              case Message::REMOVE_OBJECT_INSTANCE: {
+                  if (vers_Fed.getBoolean()) {
+                      privateRefs->fed_amb->removeObjectInstance(
+                                                vers_Fed.getObject(),
+                                                vers_Fed.getFedTime(),
+                                                vers_Fed.getTag(),
+                                                vers_Fed.getEventRetraction());
+                   }
+              else {
+                      privateRefs->fed_amb->removeObjectInstance(
+                                                vers_Fed.getObject(),
+                                                vers_Fed.getTag());
+                   }
+              } break ;
 
-    // Sinon, le RTI nous demande un service, donc on appele une methode
-    // du FederateAmbassador.
+              case Message::PROVIDE_ATTRIBUTE_VALUE_UPDATE: {
+                  AttributeHandleSet *attributeSet = vers_Fed.getAHS();
 
-    vers_RTI.setException(e_NO_EXCEPTION);
+                  privateRefs->fed_amb->provideAttributeValueUpdate(vers_Fed.getObject(),*attributeSet);
+                  delete attributeSet ;
+              } break ;
+
+              case Message::REQUEST_RETRACTION: {
 
+              } break ;
 
-    try {		
-        //D.Mes( pdMessage, 'M', vers_Fed.type);
-        vers_Fed.trace("RTI::RTIambassador::tick ");
-				
-        switch (vers_Fed.type) {
-
-          case Message::SYNCHRONIZATION_POINT_REGISTRATION_SUCCEEDED:
-            privateRefs->fed_amb->synchronizationPointRegistrationSucceeded(vers_Fed.getLabel());
-            break ;
-
-          case Message::ANNOUNCE_SYNCHRONIZATION_POINT:
-            privateRefs->fed_amb->announceSynchronizationPoint(vers_Fed.getLabel(),vers_Fed.getTag());
-            break ;
-
-          case Message::FEDERATION_SYNCHRONIZED:
-            privateRefs->fed_amb->federationSynchronized(vers_Fed.getLabel());
-            break ;
-
-          case Message::INITIATE_FEDERATE_SAVE:
-            privateRefs->fed_amb->initiateFederateSave(vers_Fed.getLabel());
-            break ;
-
-          case Message::FEDERATION_SAVED:
-            privateRefs->fed_amb->federationSaved();
-            break ;
-
-          case Message::REQUEST_FEDERATION_RESTORE_SUCCEEDED:
-            privateRefs->fed_amb->requestFederationRestoreSucceeded(
-                vers_Fed.getLabel());
-            break ;
-
-          case Message::REQUEST_FEDERATION_RESTORE_FAILED:
-            privateRefs->fed_amb->requestFederationRestoreFailed(vers_Fed.getLabel(),
-                                                    vers_Fed.getTag());
-            break ;
-
-          case Message::FEDERATION_RESTORE_BEGUN:
-            privateRefs->fed_amb->federationRestoreBegun();
-            break ;
-
-          case Message::INITIATE_FEDERATE_RESTORE:
-            privateRefs->fed_amb->initiateFederateRestore(vers_Fed.getLabel(),
-                                             vers_Fed.getFederate());
-            break ;
-
-          case Message::FEDERATION_RESTORED:
-            privateRefs->fed_amb->federationRestored();
-            break ;
-
-          case Message::FEDERATION_NOT_RESTORED:
-            privateRefs->fed_amb->federationNotRestored();
-            break ;
-
-          case Message::START_REGISTRATION_FOR_OBJECT_CLASS: {
-              privateRefs->fed_amb->startRegistrationForObjectClass(
-	              vers_Fed.getObjectClass());
-          } break ;
-
-          case Message::STOP_REGISTRATION_FOR_OBJECT_CLASS: {
-              privateRefs->fed_amb->
-                  stopRegistrationForObjectClass(vers_Fed.getObjectClass());
-          } break ;
-
-          case Message::TURN_INTERACTIONS_ON: {
-              privateRefs->fed_amb->turnInteractionsOn(vers_Fed.getInteractionClass());
-          } break ;
-
-          case Message::TURN_INTERACTIONS_OFF: {
-              privateRefs->fed_amb->turnInteractionsOff(vers_Fed.getInteractionClass());
-          } break ;
-
-          case Message::DISCOVER_OBJECT_INSTANCE: {
-              privateRefs->fed_amb->
-                  discoverObjectInstance(vers_Fed.getObject(),
-                                         vers_Fed.getObjectClass(),
-                                         vers_Fed.getName());
-          } break ;
-
-          case Message::REFLECT_ATTRIBUTE_VALUES: {
-              G.Out(pdGendoc,"          tick_kernel call to reflectAttributeValues");
-              AttributeHandleValuePairSet *attributes = vers_Fed.getAHVPS();
-              if (vers_Fed.getBoolean())
-                 privateRefs->fed_amb->
-                     reflectAttributeValues(vers_Fed.getObject(),
-                                            *attributes,
-                                            vers_Fed.getFedTime(),
-                                            vers_Fed.getTag(),
-                                            vers_Fed.getEventRetraction());
-              else
-                 privateRefs->fed_amb->
-                     reflectAttributeValues(vers_Fed.getObject(),
-                                            *attributes,
-                                            vers_Fed.getTag());
-              delete attributes ;
-          } break ;
-
-          case Message::RECEIVE_INTERACTION:
-              {
-              ParameterHandleValuePairSet *parameters = vers_Fed.getPHVPS();
-              if (vers_Fed.getBoolean())
-                  privateRefs->fed_amb->receiveInteraction(
-                                          vers_Fed.getInteractionClass(),
-                                          *parameters,
-                                          vers_Fed.getFedTime(),
-                                          vers_Fed.getTag(),
-                                          vers_Fed.getEventRetraction());
-              else
-                  privateRefs->fed_amb->receiveInteraction(
-                                          vers_Fed.getInteractionClass(),
-                                          *parameters,
-                                          vers_Fed.getTag());
+              case Message::REQUEST_ATTRIBUTE_OWNERSHIP_ASSUMPTION: {
+                  AttributeHandleSet *attributeSet = vers_Fed.getAHS();
 
-              delete parameters ;
+                  privateRefs->fed_amb->
+                      requestAttributeOwnershipAssumption(vers_Fed.getObject(),
+                                                          *attributeSet,
+                                                          vers_Fed.getTag());
+                  delete attributeSet ;
               } break ;
 
-          case Message::REMOVE_OBJECT_INSTANCE: {
-              if (vers_Fed.getBoolean()) {
-                  privateRefs->fed_amb->removeObjectInstance(
-                                            vers_Fed.getObject(),
-                                            vers_Fed.getFedTime(),
-                                            vers_Fed.getTag(),
-                                            vers_Fed.getEventRetraction());
-               }
-	       else {
-                  privateRefs->fed_amb->removeObjectInstance(
-                                            vers_Fed.getObject(),
-                                            vers_Fed.getTag());
-               }
-          } break ;
-
-          case Message::PROVIDE_ATTRIBUTE_VALUE_UPDATE: {
-              AttributeHandleSet *attributeSet = vers_Fed.getAHS();
-
-              privateRefs->fed_amb->provideAttributeValueUpdate(vers_Fed.getObject(),*attributeSet);
-              delete attributeSet ;
-          } break ;
-
-          case Message::REQUEST_RETRACTION: {
-
-          } break ;
-
-          case Message::REQUEST_ATTRIBUTE_OWNERSHIP_ASSUMPTION: {
-              AttributeHandleSet *attributeSet = vers_Fed.getAHS();
-
-              privateRefs->fed_amb->
-                  requestAttributeOwnershipAssumption(vers_Fed.getObject(),
-                                                      *attributeSet,
-                                                      vers_Fed.getTag());
-              delete attributeSet ;
-          } break ;
-
-          case Message::REQUEST_ATTRIBUTE_OWNERSHIP_RELEASE: {
-              AttributeHandleSet *attributeSet = vers_Fed.getAHS();
-
-              privateRefs->fed_amb->requestAttributeOwnershipRelease(
-		      vers_Fed.getObject(),
-		      *attributeSet,
-		      vers_Fed.getTag());
-
-              delete attributeSet ;
-          } break ;
-
-          case Message::ATTRIBUTE_OWNERSHIP_UNAVAILABLE: {
-              AttributeHandleSet *attributeSet = vers_Fed.getAHS();
-
-              privateRefs->fed_amb->attributeOwnershipUnavailable(vers_Fed.getObject(),
-                                                         *attributeSet);
-
-              delete attributeSet ;
-          } break ;
-
-          case Message::ATTRIBUTE_OWNERSHIP_ACQUISITION_NOTIFICATION: {
-              AttributeHandleSet *attributeSet = vers_Fed.getAHS();
-
-              privateRefs->fed_amb->attributeOwnershipAcquisitionNotification(
-		      vers_Fed.getObject(),
-		      *attributeSet);
-
-              delete attributeSet ;
-          } break ;
-
-          case Message::ATTRIBUTE_OWNERSHIP_DIVESTITURE_NOTIFICATION: {
-              AttributeHandleSet *attributeSet = vers_Fed.getAHS();
-
-              privateRefs->fed_amb->attributeOwnershipDivestitureNotification(
-		      vers_Fed.getObject(),
-		      *attributeSet);
-
-              delete attributeSet ;
-          } break ;
-
-          case Message::CONFIRM_ATTRIBUTE_OWNERSHIP_ACQUISITION_CANCELLATION: {
-              AttributeHandleSet *attributeSet = vers_Fed.getAHS();
-
-              privateRefs->fed_amb->
-                      confirmAttributeOwnershipAcquisitionCancellation
-                      (vers_Fed.getObject(), *attributeSet);
-
-              delete attributeSet ;
-          } break ;
-
-           case Message::INFORM_ATTRIBUTE_OWNERSHIP: {
-              privateRefs->fed_amb->
-                  informAttributeOwnership(vers_Fed.getObject(),
-                                               vers_Fed.getAttribute(),
-                                               vers_Fed.getFederate());
-          } break ;
-
-          case Message::ATTRIBUTE_IS_NOT_OWNED: {
-              privateRefs->fed_amb->attributeIsNotOwned(vers_Fed.getObject(),
-                                               vers_Fed.getAttribute());
-          } break ;
-
-          case Message::TIME_ADVANCE_GRANT: {
-              privateRefs->fed_amb->timeAdvanceGrant(vers_Fed.getFedTime());
-          } break ;
-
-          default: {
-              privateRefs->leave("RTI service requested by RTI is unknown.");
-          }
+              case Message::REQUEST_ATTRIBUTE_OWNERSHIP_RELEASE: {
+                  AttributeHandleSet *attributeSet = vers_Fed.getAHS();
+
+                  privateRefs->fed_amb->requestAttributeOwnershipRelease(
+                vers_Fed.getObject(),
+                *attributeSet,
+                vers_Fed.getTag());
+
+                  delete attributeSet ;
+              } break ;
+
+              case Message::ATTRIBUTE_OWNERSHIP_UNAVAILABLE: {
+                  AttributeHandleSet *attributeSet = vers_Fed.getAHS();
+
+                  privateRefs->fed_amb->attributeOwnershipUnavailable(vers_Fed.getObject(),
+                                                             *attributeSet);
+
+                  delete attributeSet ;
+              } break ;
+
+              case Message::ATTRIBUTE_OWNERSHIP_ACQUISITION_NOTIFICATION: {
+                  AttributeHandleSet *attributeSet = vers_Fed.getAHS();
+
+                  privateRefs->fed_amb->attributeOwnershipAcquisitionNotification(
+                vers_Fed.getObject(),
+                *attributeSet);
+
+                  delete attributeSet ;
+              } break ;
+
+              case Message::ATTRIBUTE_OWNERSHIP_DIVESTITURE_NOTIFICATION: {
+                  AttributeHandleSet *attributeSet = vers_Fed.getAHS();
+
+                  privateRefs->fed_amb->attributeOwnershipDivestitureNotification(
+                vers_Fed.getObject(),
+                *attributeSet);
+
+                  delete attributeSet ;
+              } break ;
+
+              case Message::CONFIRM_ATTRIBUTE_OWNERSHIP_ACQUISITION_CANCELLATION: {
+                  AttributeHandleSet *attributeSet = vers_Fed.getAHS();
+
+                  privateRefs->fed_amb->
+                          confirmAttributeOwnershipAcquisitionCancellation
+                          (vers_Fed.getObject(), *attributeSet);
+
+                  delete attributeSet ;
+              } break ;
+
+               case Message::INFORM_ATTRIBUTE_OWNERSHIP: {
+                  privateRefs->fed_amb->
+                      informAttributeOwnership(vers_Fed.getObject(),
+                                                   vers_Fed.getAttribute(),
+                                                   vers_Fed.getFederate());
+              } break ;
+
+              case Message::ATTRIBUTE_IS_NOT_OWNED: {
+                  privateRefs->fed_amb->attributeIsNotOwned(vers_Fed.getObject(),
+                                                   vers_Fed.getAttribute());
+              } break ;
+
+              case Message::TIME_ADVANCE_GRANT: {
+                  privateRefs->fed_amb->timeAdvanceGrant(vers_Fed.getFedTime());
+              } break ;
+
+              default: {
+                  privateRefs->leave("RTI service requested by RTI is unknown.");
+              }
+            }
+        }
+        catch (InvalidFederationTime &e) {
+            vers_RTI.setException(e_InvalidFederationTime, e._reason);
+            throw ;
+        }
+        catch (TimeAdvanceWasNotInProgress &e) {
+            vers_RTI.setException(e_TimeAdvanceWasNotInProgress, e._reason);
+            throw ;
+        }
+        catch (FederationTimeAlreadyPassed &e) {
+            vers_RTI.setException(e_FederationTimeAlreadyPassed, e._reason);
+        }
+        catch (FederateInternalError &e) {
+            vers_RTI.setException(e_FederateInternalError, e._reason);
+            throw ;
+        }
+        catch (Exception &e) {
+            vers_RTI.setException(e_RTIinternalError, e._reason);
+            throw ;
         }
     }
-    catch (InvalidFederationTime &e) {
-        vers_RTI.setException(e_InvalidFederationTime, e._reason);
-        throw ;
-    }
-    catch (TimeAdvanceWasNotInProgress &e) {
-        vers_RTI.setException(e_TimeAdvanceWasNotInProgress, e._reason);
-        throw ;
-    }
-    catch (FederationTimeAlreadyPassed &e) {
-        vers_RTI.setException(e_FederationTimeAlreadyPassed, e._reason);
-    }
-    catch (FederateInternalError &e) {
-        vers_RTI.setException(e_FederateInternalError, e._reason);
-        throw ;
-    }
-    catch (Exception &e) {
-        vers_RTI.setException(e_RTIinternalError, e._reason);
-        throw ;
-    }
-    
-    return RTI::Boolean(true);
-          
 }
 
 // ----------------------------------------------------------------------------
+//! Evoke multiple callbacks (HLA1.3).
+/*! Blocks up to "minimum" seconds until a callback delivery, then envokes
+ *  multiple callbacks until no callback is pending, or until "maximum"
+ *  duration is reached.
+ *  @return true if additional callbacks pending, false otherwise
+ */
 RTI::Boolean
-RTI::RTIambassador::tick(TickTime, TickTime)
+RTI::RTIambassador::tick(TickTime minimum, TickTime maximum)
     throw (SpecifiedSaveLabelDoesNotExist, ConcurrentAccessAttempted,
            RTIinternalError)
 {
-    return tick();
+    return __tick_kernel(RTI_TRUE, minimum, maximum);
 }
 
-
 // ----------------------------------------------------------------------------
 // Create Federation Execution.
 /** Realization of the Create Federation Execution federation management service
diff -ru --exclude=CVS certi.orig/libRTI/RTIambPrivateRefs.cc certi.new/libRTI/RTIambPrivateRefs.cc
--- certi.orig/libRTI/RTIambPrivateRefs.cc	2008-02-18 14:37:30.000000000 +0100
+++ certi.new/libRTI/RTIambPrivateRefs.cc	2008-04-02 13:17:01.000000000 +0200
@@ -84,12 +84,11 @@
 
     D.Out(pdDebug, "RTIA reply received.");
 
-    if (req->type != Message::TICK_REQUEST) {
-       if (rep->type != req->type) {
-           std::cout << "LibRTI: Assertion failed: rep->type != req->type" << std::endl ;
-           throw RTIinternalError("RTIambPrivateRefs::executeService: "
-                                  "rep->type != req->type");
-       }
+
+    if (rep->type != req->type) {
+        std::cout << "LibRTI: Assertion failed: rep->type != req->type" << std::endl ;
+        throw RTIinternalError("RTIambPrivateRefs::executeService: "
+                               "rep->type != req->type");
     }
 
     D.Out(pdDebug, "processing returned exception (from reply).");
diff -ru --exclude=CVS certi.orig/RTIA/Communications.cc certi.new/RTIA/Communications.cc
--- certi.orig/RTIA/Communications.cc	2008-02-22 12:34:30.000000000 +0100
+++ certi.new/RTIA/Communications.cc	2008-04-01 17:22:45.000000000 +0200
@@ -180,7 +180,8 @@
   Returns the actual source in the 1st parameter (RTIG=>1 federate=>2)
 */
 void
-Communications::readMessage(int &n, NetworkMessage *msg_reseau, Message *msg)
+Communications::readMessage(int &n, NetworkMessage *msg_reseau, Message *msg,
+                            struct timeval *timeout)
 {
     const int tcp_fd(SecureTCPSocket::returnSocket());
     const int udp_fd(SocketUDP::returnSocket());
@@ -241,7 +242,7 @@
     else {
         // waitingList is empty and no data in TCP buffer.
         // Wait a message (coming from federate or network).
-        if (select(max_fd, &fdset, NULL, NULL, NULL) < 0) {
+        if (select(max_fd, &fdset, NULL, NULL, timeout) < 0) {
 			#ifdef _WIN32
 				 if(WSAGetLastError() == WSAEINTR)
 			#else
@@ -275,12 +276,16 @@
             msg_reseau->read((SocketUDP *) this);
             n = 1 ;
         }
-        else {
+        else if (FD_ISSET(_socket_un, &fdset)) {
             // Read a message coming from the federate.
-            assert(FD_ISSET(_socket_un, &fdset));
             receiveUN(msg);
             n = 2 ;
         }
+        else
+        {
+            // select() timeout occured
+            n = 3;
+        }
     }
 }
 
diff -ru --exclude=CVS certi.orig/RTIA/Communications.hh certi.new/RTIA/Communications.hh
--- certi.orig/RTIA/Communications.hh	2008-02-22 12:34:30.000000000 +0100
+++ certi.new/RTIA/Communications.hh	2008-04-01 15:39:54.000000000 +0200
@@ -54,7 +54,7 @@
     void sendMessage(NetworkMessage *Msg);
     void sendUN(Message *Msg);
     void receiveUN(Message *Msg);
-    void readMessage(int&, NetworkMessage *, Message *);
+    void readMessage(int&, NetworkMessage *, Message *, struct timeval *);
     void requestFederateService(Message *req);
     unsigned long getAddress();
     unsigned int getPort();
diff -ru --exclude=CVS certi.orig/RTIA/RTIA.cc certi.new/RTIA/RTIA.cc
--- certi.orig/RTIA/RTIA.cc	2008-04-02 19:14:10.000000000 +0200
+++ certi.new/RTIA/RTIA.cc	2008-04-02 21:07:05.000000000 +0200
@@ -25,6 +25,7 @@
 #include "RTIA.hh"
 
 #include <assert.h>
+#include <math.h>
 
 namespace certi {
 namespace rtia {
@@ -119,7 +120,7 @@
         msg_un = new Message ;
 
         try {
-            comm->readMessage(n, msg_tcp_udp, msg_un);
+            comm->readMessage(n, msg_tcp_udp, msg_un, NULL);
         }
         catch (NetworkSignal) {
             fm->_fin_execution = true ;
@@ -130,6 +131,8 @@
 
         switch (n) {
           case 0:
+            delete msg_un ;
+            delete msg_tcp_udp ;
             break ;
           case 1:
             processNetworkMessage(msg_tcp_udp);
@@ -139,20 +142,34 @@
             processFederateRequest(msg_un);
             delete msg_tcp_udp ;
             break ;
+          case 3: // timeout
+            delete msg_un ;
+            delete msg_tcp_udp ;
+            break ;
           default:
             assert(false);
         }
 
-        // special case, blocking tick (tick2)
-        while (!fm->_fin_execution && tm->_ongoing_tick) {
+        // special case, blocking tick
+        while (!fm->_fin_execution && tm->_blocking_tick) {
 	    // read a message from the rtig
             // same code is reused, but only the case 1 should match
-
             msg_tcp_udp = new NetworkMessage ;
             msg_un = new Message ;
 
             try {
-                comm->readMessage(n, msg_tcp_udp, msg_un);
+                if (isfinite(tm->_tick_timeout) && tm->_tick_timeout < LONG_MAX)
+                {
+                    struct timeval timev;
+                    timev.tv_sec = int(tm->_tick_timeout);
+                    timev.tv_usec = int((tm->_tick_timeout-timev.tv_sec)*1000000.0);
+
+                    comm->readMessage(n, msg_tcp_udp, msg_un, &timev);
+                }
+                else
+                    comm->readMessage(n, msg_tcp_udp, msg_un, NULL);
+
+                /* timev is undefined after select() */
             }
             catch (NetworkSignal) {
                 fm->_fin_execution = true ;
@@ -163,14 +180,24 @@
 
             switch (n) {
               case 0:
+                delete msg_un;
+                delete msg_tcp_udp;
                 break ;
               case 1:
                 processNetworkMessage(msg_tcp_udp) ;  // could authorize a callbak
-                msg_un->type = Message::TICK_REQUEST ;
-                msg_un->setBoolean(true) ;
-                processFederateRequest(msg_un);  //could reset _ongoing_tick                
+                delete msg_un ;
+                // may have reset tm->_blocking_tick
+                processOngoingTick();
                 break ;
               case 2:
+                assert(false);
+              case 3: // timeout
+                delete msg_un;
+                delete msg_tcp_udp;
+                // stop the ongoing tick() operation
+                tm->_blocking_tick = false;
+                processOngoingTick();
+                break ;
               default:
                 assert(false);
             }
diff -ru --exclude=CVS certi.orig/RTIA/RTIA_federate.cc certi.new/RTIA/RTIA_federate.cc
--- certi.orig/RTIA/RTIA_federate.cc	2008-04-02 19:14:10.000000000 +0200
+++ certi.new/RTIA/RTIA_federate.cc	2008-04-02 20:49:46.000000000 +0200
@@ -39,6 +39,22 @@
 static PrettyDebug G("GENDOC",__FILE__) ;
 
 // ----------------------------------------------------------------------------
+static RTI::TickTime currentTickTime()
+{
+    RTI::TickTime result;
+#ifdef _WIN32 
+    _timeb timev;
+    _ftime(&timev);
+    result = timev.time + timev.millitm/1000;
+#else 
+    struct timeval timev;
+    gettimeofday(&timev, NULL);
+    result = timev.tv_sec + timev.tv_usec/1000000;
+#endif 
+    return result;
+}
+
+// ----------------------------------------------------------------------------
 //! Verify that federate is not in saving or restoring state.
 void
 RTIA::saveAndRestoreStatus(Message::Type type)
@@ -942,18 +958,19 @@
         break ;
 
       case Message::TICK_REQUEST:
-        tm->_tick_request_ack = true ;
-        if (req->getBoolean()) {
-           tm->_ongoing_tick = true ;
-           D.Out(pdDebug, "Receiving Message from Federate, type TickRequest2.");
-           
-        }
-        else {
-           D.Out(pdDebug, "Receiving Message from Federate, type TickRequest.");
-           
+        tm->_tick_multiple = req->getBoolean();
+
+	if (req->getMinTickTime() > 0.0)
+	{
+            tm->_tick_timeout = req->getMinTickTime();
+            tm->_tick_stop_time = currentTickTime() + req->getMaxTickTime();
+
+            tm->_blocking_tick = true ;
         }
-        rep.setBoolean(tm->tick(e));
+        else
+            tm->_blocking_tick = false ;
 
+        processOngoingTick();
         break ;
 
       default:
@@ -966,6 +983,43 @@
 }
 
 // ----------------------------------------------------------------------------
+//! RTIA processes the TICK_REQUEST
+void
+RTIA::processOngoingTick()
+{
+    TypeException exc = e_NO_EXCEPTION;
+    bool pending;
+
+    do {
+        // send a single callback to federate (if any)
+	pending = tm->tick(exc);
+
+	// processing a callback may have reset tm->_blocking_tick
+
+        if (!tm->_tick_multiple)
+    	    break;
+
+	if (currentTickTime() > tm->_tick_stop_time)
+	{
+            tm->_blocking_tick = false;
+            break;
+	}
+    }
+    while (pending);
+
+    if (!tm->_blocking_tick)
+    {
+        Message msg_ack;
+        if ( exc != e_RTIinternalError )
+    	    msg_ack.setException(exc);
+        // terminate __tick() call in the federate
+        msg_ack.type = Message::TICK_REQUEST;
+        msg_ack.setBoolean(pending);
+        comm->requestFederateService(&msg_ack);
+    }
+}
+
+// ----------------------------------------------------------------------------
 //! RTIA processes a service request coming from federate.
 void
 RTIA::processFederateRequest(Message *req)
@@ -1312,18 +1366,9 @@
 
     delete req ;;
 
-     
-    if (rep.type == Message::TICK_REQUEST)
-       if ((!tm->_ongoing_tick) && tm->_tick_request_ack) {
-           // acknowledgment of an empty tick
-           comm->sendUN(&rep);
-           D.Out(pdDebug, "Reply send to Unix socket.");
-        }
-        else {
-           // no answer in the case of a successful tick
-        }
-    else {
+    if (rep.type != Message::TICK_REQUEST) {
        // generic federate service acknowledgment
+       // the TICK_REQUEST confirmation is generated in processOngoingTick()
        comm->sendUN(&rep);
        D.Out(pdDebug, "Reply send to Unix socket.");
     }
diff -ru --exclude=CVS certi.orig/RTIA/RTIA.hh certi.new/RTIA/RTIA.hh
--- certi.orig/RTIA/RTIA.hh	2008-03-14 15:52:23.000000000 +0100
+++ certi.new/RTIA/RTIA.hh	2008-04-02 15:16:00.000000000 +0200
@@ -67,6 +67,7 @@
     void chooseFederateProcessing(Message *, Message &, TypeException &)
        throw (CouldNotOpenFED,FederationExecutionAlreadyExists,ErrorReadingFED,
               FederateAlreadyExecutionMember);
+    void processOngoingTick();
 };
 
 }} // namespace certi
diff -ru --exclude=CVS certi.orig/RTIA/TimeManagement.cc certi.new/RTIA/TimeManagement.cc
--- certi.orig/RTIA/TimeManagement.cc	2008-03-13 15:39:19.000000000 +0100
+++ certi.new/RTIA/TimeManagement.cc	2008-04-02 15:26:15.000000000 +0200
@@ -82,7 +82,7 @@
     lastNullMessageDate = 0.0 ;
 
     _avancee_en_cours = PAS_D_AVANCEE ;
-    _ongoing_tick          = false ;
+    _blocking_tick         = false ;
     _asynchronous_delivery = false ;
 
     _heure_courante = 0.0 ;
@@ -125,8 +125,7 @@
 
   msg.trace("TimeManagement::executeFederateService ");
 
-  _ongoing_tick = false ;  // end of the blocking tick, a message is delivered
-  _tick_request_ack = false ;  // the callback message serves as the ack
+    _blocking_tick = false;  // indicate a callback was processed
 
     switch (msg.type) {
 
@@ -822,8 +821,7 @@
     if (_lookahead_courant == epsilon)
        _lookahead_courant = 0.0 ;
 
-    _ongoing_tick = false ;  // end of the blocking tick, a message is delivered
-    _tick_request_ack = false ;
+    _blocking_tick = false;  // indicate a callback was processed
 
     comm->requestFederateService(&req);
 
diff -ru --exclude=CVS certi.orig/RTIA/TimeManagement.hh certi.new/RTIA/TimeManagement.hh
--- certi.orig/RTIA/TimeManagement.hh	2008-03-13 15:39:19.000000000 +0100
+++ certi.new/RTIA/TimeManagement.hh	2008-04-02 15:24:40.000000000 +0200
@@ -105,8 +105,10 @@
     bool requestRegulateurState() { return _est_regulateur ; };
 
     // Attribute
-    bool _ongoing_tick;  // tick2 processing
-    bool _tick_request_ack;  // do we have to acknowledge the tick request
+    bool _blocking_tick;  // processing the tick
+    bool _tick_multiple;  // process multiple callbacks
+    RTI::TickTime _tick_timeout;
+    RTI::TickTime _tick_stop_time;
     bool _asynchronous_delivery ;
 
 private:
