Salome HOME
InitLoop and DoLoop parameters names
[modules/superv.git] / src / GraphExecutor / DataFlowExecutor_InNodeThreads.cxx
index b8a9eda24f26eb39c9800c8d1ac4de55d7b49285..42661e2dfda57ac0ed65c790919ea761d19edffc 100644 (file)
@@ -33,6 +33,19 @@ using namespace std;
 #include <unistd.h>
 #include <stdio.h>
 
+#if defined __GNUC__
+  #if __GNUC__ == 2
+    #define __GNUC_2__
+  #endif
+#endif
+
+#if defined __GNUC_2__
+// _CS_gbo_040604 include explicite pour l'utilisation de
+// std::transform dans UpperCase
+#include <cctype> // for toupper
+#include <algorithm> // for transform
+#endif
+
 #include "Python.h"
 
 #include "OpUtil.hxx"
@@ -41,14 +54,20 @@ using namespace std;
 #include CORBA_CLIENT_HEADER(SALOME_Component)
 #include "SALOME_LifeCycleCORBA.hxx"
 
-//#include "StreamGraph_Impl.hxx"
-
-#include "DataFlowExecutor_OutNode.hxx"
+#include "DataFlowExecutor_DataFlow.hxx"
+#include "DataFlowEditor_DataFlow.hxx"   // GraphEditor package must be built BEFORE
 
 
 static void UpperCase(std::string& rstr)
 {
-       std::transform(rstr.begin(), rstr.end(), rstr.begin(), towupper);
+#if defined __GNUC_2__
+  // _CS_gbo_040604 towupper n'existe pas. Utilisation de toupper. Par
+  // ailleurs, include explicite de cctype et algorithm pour toupper
+  // et transform respectivement. 
+  std::transform(rstr.begin(), rstr.end(), rstr.begin(),toupper);
+#else
+  std::transform(rstr.begin(), rstr.end(), rstr.begin(),towupper);
+#endif
 }
 
 
@@ -74,8 +93,8 @@ int GraphExecutor::InNode::SendEvent( const GraphExecutor::NodeEvent anEvent ) {
   }
 
 //  State( _NextState ) ;
-//  if ( _OldState == SUPERV::SuccessedExecutingState ||
-//       _OldState == SUPERV::ErroredExecutingState ) {
+//  if ( _OldState == GraphExecutor::SuccessedExecutingState ||
+//       _OldState == GraphExecutor::ErroredExecutingState ) {
 //    DoneAction() ;
 //  }
 
@@ -90,7 +109,7 @@ int GraphExecutor::InNode::SendEvent( const GraphExecutor::NodeEvent anEvent ) {
          << " _RewindStack " << _RewindStack  << endl ;
 
 #if 0
-  cout << pthread_self() << "/" << ThreadNo() << " SendedEvent Node " << Name()
+  //cout << pthread_self() << "/" << ThreadNo() << " SendedEvent Node " << Name()
        << endl << " ControlState : "
        << Automaton()->ControlStateName( ControlState() ) << endl
        << " OldState : " << Automaton()->StateName( _OldState ) << endl
@@ -138,6 +157,7 @@ void GraphExecutor::InNode::RunningAction() {
   cdebug << pthread_self() << "/" << ThreadNo()
          << "RunningAction pthread_cond_broadcast _RunningWait "
          << Name() << endl ;
+// That activate the pthread_cond_wait for RunninWait
   if ( pthread_cond_broadcast( &_RunningWait ) ) {
     perror("Running pthread_cond_broadcast ") ;
   }
@@ -430,17 +450,20 @@ void GraphExecutor::InNode::ThreadStartedAction() {
     exit( 0 ) ;
   }
   if ( !_ThreadStartedSync ) {
-    cdebug << "pthread_cond " << Name() << " ThreadStarted pthread_cond_wait"
+    cdebug << pthread_self() << "/" << ThreadNo()
+           << "pthread_cond " << Name() << " ThreadStarted pthread_cond_wait"
            << endl ;
     _ThreadStartedSync = true ;
     if ( pthread_cond_wait( &_ThreadStartedWait , &_MutexWait ) ) {
       perror("ThreadStarted pthread_cond_wait ") ;
     }
-    cdebug << "pthread_cond " << Name() << " ThreadStarted pthread_cond_waited"
+    cdebug << pthread_self() << "/" << ThreadNo()
+           << "pthread_cond " << Name() << " ThreadStarted pthread_cond_waited"
            << endl ;
   }
   else {
-    cdebug << "pthread_cond " << Name() << " NO ThreadStarted pthread_cond_wait"
+    cdebug << pthread_self() << "/" << ThreadNo()
+           << "pthread_cond " << Name() << " NO ThreadStarted pthread_cond_wait"
            << endl ;
 //Debug :
     _ThreadStartedSync = false ;  
@@ -448,7 +471,8 @@ void GraphExecutor::InNode::ThreadStartedAction() {
       perror("ThreadStart pthread_cond_signal ") ;
     }
 //Debug
-    cdebug << "pthread_cond " << Name() << " NO ThreadStarted pthread_cond_signaled"
+    cdebug << pthread_self() << "/" << ThreadNo()
+           << "pthread_cond " << Name() << " NO ThreadStarted pthread_cond_signaled"
            << endl ;
   }
   if ( pthread_mutex_unlock( &_MutexWait ) ) {
@@ -463,17 +487,20 @@ void GraphExecutor::InNode::ThreadStartAction() {
     exit( 0 ) ;
   }
   if ( _ThreadStartedSync ) {
-    cdebug << "pthread_cond " << Name() << " ThreadStart pthread_cond_signal"
+    cdebug << pthread_self() << "/" << ThreadNo()
+           << "pthread_cond " << Name() << " ThreadStart pthread_cond_signal"
            << endl ;
     _ThreadStartedSync = false ;  
     if ( pthread_cond_signal( &_ThreadStartedWait ) ) {
       perror("ThreadStart pthread_cond_broadcast ") ;
     }
-    cdebug << "pthread_cond " << Name() << " ThreadStart pthread_cond_signaled"
+    cdebug << pthread_self() << "/" << ThreadNo()
+           << "pthread_cond " << Name() << " ThreadStart pthread_cond_signaled"
            << endl ;
   }
   else {
-    cdebug << "pthread_cond " << Name() << " NO ThreadStart pthread_cond_signal"
+    cdebug << pthread_self() << "/" << ThreadNo()
+           << "pthread_cond " << Name() << " NO ThreadStart pthread_cond_signal"
            << endl ;
     _ThreadStartedSync = true ;
 //Debug :
@@ -481,7 +508,8 @@ void GraphExecutor::InNode::ThreadStartAction() {
       perror("ThreadStarted pthread_cond_wait ") ;
     }
 //Debug
-    cdebug << "pthread_cond " << Name() << " NO ThreadStart pthread_cond_waited"
+    cdebug << pthread_self() << "/" << ThreadNo()
+           << "pthread_cond " << Name() << " NO ThreadStart pthread_cond_waited"
            << endl ;
   }
   if ( pthread_mutex_unlock( &_MutexWait ) ) {
@@ -512,7 +540,7 @@ int GraphExecutor::InNode::executeAction() {
       pthread_t T;
       int pthread_sts = 1 ;
 //      _OutNode->PushEvent( NULL , GraphExecutor::NewThreadEvent ,
-//                           SUPERV::ExecutingState ) ; 
+//                           GraphExecutor::ExecutingState ) ; 
       while ( (pthread_sts = pthread_create(&T, NULL, run_function, this )) ) {
         char * msg = "Cannot pthread_create " ;
         perror( msg ) ;
@@ -543,7 +571,7 @@ int GraphExecutor::InNode::executeAction() {
              << Automaton()->StateName( State() ) << " "
              << Automaton()->ActionName( _NextAction ) << "(" << Name()
              << ") ReStartAction ==>" << endl;
-      State( SUPERV::SuspendedSuccessedState ) ;
+      State( GraphExecutor::SuspendedSuccessedState ) ;
       if ( !ReStartAction( this , GraphExecutor::ReStartEvent ) ) {
         cdebug << pthread_self() << "/" << ThreadNo()
                << " executeAction STATE & CALLED "
@@ -570,7 +598,7 @@ int GraphExecutor::InNode::executeAction() {
 }
 
 void GraphExecutor::InNode::coutbegin() {
-  cdebug << ThreadNo() << " " << pthread_self() << " run_function begin"
+  cdebug << pthread_self() << "/" << ThreadNo() << " run_function begin"
          << " " << Name() << " " << Automaton()->StateName( State() ) << endl ;
 }
 void GraphExecutor::InNode::coutexit() {
@@ -590,6 +618,8 @@ void * run_function(void *p) {
     exit(0) ;
   }
   aNode->ThreadStartAction() ;
+//  cout << "run_function " << aNode->Name() << "->ExecuteAction() Coupled : " << aNode->CoupledNode()
+//       << endl ;
   aNode->ExecuteAction() ;
   char * msg = new char[40] ;
   sprintf( msg , "%d" , (int ) aNode->ThreadNo() ) ;
@@ -605,12 +635,12 @@ void * run_function(void *p) {
 int GraphExecutor::InNode::ExecuteAction() {
   int sts ;
 
-//  const char * nextactionname = Automaton()->ActionName( _NextAction ) ;
-//  const char * statename = Automaton()->StateName( State() ) ;
-//  const char * nextstatename = Automaton()->StateName( _NextState ) ;
-//  cdebug << pthread_self() << "/" << ThreadNo() << " --> ExecuteAction "
-//         << nextactionname << " "  << statename << " NextState "
-//         << nextstatename << endl ;
+  const char * nextactionname = Automaton()->ActionName( _NextAction ) ;
+  const char * statename = Automaton()->StateName( State() ) ;
+  const char * nextstatename = Automaton()->StateName( _NextState ) ;
+  cdebug_in << pthread_self() << "/" << ThreadNo() << " --> ExecuteAction "
+            << nextactionname << " "  << statename << " NextState "
+            << nextstatename << endl ;
 
   State( _NextState ) ;
   switch ( _NextAction ) {
@@ -741,8 +771,8 @@ int GraphExecutor::InNode::ExecuteAction() {
     return 0 ;
   }
   }
-//  cdebug << pthread_self() << "/" << ThreadNo() << "<-- ExecuteAction "
-//         << Automaton()->ActionName( nextaction ) << endl ;
+  cdebug_out << pthread_self() << "/" << ThreadNo() << "<-- ExecuteAction "
+             << nextactionname << endl ;
   return sts ;
 }
 
@@ -765,16 +795,16 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
   unsigned int k;
   int InReady = 0 ;
   int res = 1;
-  bool LoopFinished = false ;
   bool LoopBeginning = false ;
+  bool LoopFinished = false ;
   bool SwitchFinished = false ;
 
-  if ( IsEndLoopNode() && !GetChangeNodeInLoop()->GetOutPort()->BoolValue() ) {
-    LoopFinished = true ; // End of Loop
-  }
   if ( IsLoopNode() && GetChangeNodeInLoop()->GetOutPort()->BoolValue() ) {
     LoopBeginning = true ; // Beginning of Loop
   }
+  if ( IsEndLoopNode() && !GetChangeNodeInLoop()->GetOutPort()->BoolValue() ) {
+    LoopFinished = true ; // End of Loop
+  }
   if ( IsEndSwitchNode() && !GetChangeNodeInGate()->GetOutPort()->BoolValue() ) {
     SwitchFinished = true ; // End of Switch
   }
@@ -783,20 +813,21 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
   for ( k = 0 ; k < (unsigned int ) GetNodeInPortsSize() ; k++ ) {
     GraphBase::InPort * anInPort = GetChangeNodeInPort(k) ;
     GraphBase::OutPort * anOutPort = anInPort->GetOutPort() ;
-    cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " InPort " << anInPort->PortName() << endl ;
+    cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " InPort " << anInPort->PortName() << " " << anInPort->State() << " " << anInPort->PortStatus() << endl ;
     if ( anInPort->IsGate() && anOutPort == NULL ) {
       InReady += 1 ;
       anInPort->State( SUPERV::ReadyState ) ;
       cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
              << anInPort->PortName() << " ControlPort inactive." << endl ;
     }
+// That InPort get its value from an other node
     else if ( strcmp( DataFromNode() , anOutPort->NodeName() ) ) {
       if ( anInPort->State() == SUPERV::ReadyState ) {
         InReady += 1 ;
         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
-               << anInPort->PortName() << " Was Done from "
-               << anOutPort->NodeName() << " " << anOutPort->PortName()
-               << " ReadyState " ;
+               << anInPort->PortName() << " Was Done from Node "
+               << anOutPort->NodeName() << "( " << anOutPort->PortName()
+               << ") ReadyState " ;
 #ifdef _DEBUG_
         if ( GraphBase::Base::_prof_debug ) {
           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
@@ -808,9 +839,9 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
         anInPort->State( SUPERV::ReadyState ) ;
         InReady += 1 ;
         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
-               << anInPort->PortName() << " Was Done from "
-               << anOutPort->NodeName() << " " << anOutPort->PortName()
-               << " LoopBeginning " << LoopBeginning ;
+               << anInPort->PortName() << " Was Done from Node "
+               << anOutPort->NodeName() << "( " << anOutPort->PortName()
+               << ") LoopBeginning " << LoopBeginning ;
 #ifdef _DEBUG_
         if ( GraphBase::Base::_prof_debug ) {
           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
@@ -822,9 +853,9 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
         anInPort->State( SUPERV::ReadyState ) ;
         InReady += 1 ;
         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
-               << anInPort->PortName() << " Was Done from "
-               << anOutPort->NodeName() << " " << anOutPort->PortName()
-               << " LoopFinished" ;
+               << anInPort->PortName() << " Was Done from Node "
+               << anOutPort->NodeName() << "( " << anOutPort->PortName()
+               << ") LoopFinished" ;
 #ifdef _DEBUG_
         if ( GraphBase::Base::_prof_debug ) {
           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
@@ -836,9 +867,9 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
         anInPort->State( SUPERV::ReadyState ) ;
         InReady += 1 ;
         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
-               << anInPort->PortName() << " Was Done from "
-               << anOutPort->NodeName() << " " << anOutPort->PortName()
-               << " SwitchFinished" ;
+               << anInPort->PortName() << " Was Done from Node "
+               << anOutPort->NodeName() << "( " << anOutPort->PortName()
+               << ") SwitchFinished" ;
 #ifdef _DEBUG_
         if ( GraphBase::Base::_prof_debug ) {
           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
@@ -848,13 +879,14 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
       }
       else {
         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
-               << anInPort->PortName() << " Was NOT Done from "
-               << anOutPort->NodeName() << " " << anOutPort->PortName() << " "
+               << anInPort->PortName() << " Was NOT Done from Node "
+               << anOutPort->NodeName() << "( " << anOutPort->PortName() << ") "
                << " " << Automaton()->StateName( State() ) << " DataConnected "
                << anInPort->IsDataConnected() << " LoopBeginning "
                << LoopBeginning << endl ;
       }
     }
+// That InPort get its value from the sending node
     else if ( anInPort->IsGate() ) {
       const CORBA::Any * theValue = anOutPort->Value() ;
       long GateOpened ;
@@ -863,9 +895,9 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
         InReady += 1 ;
         anInPort->State( SUPERV::ReadyState ) ;
         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
-               << anInPort->PortName() << " Gate is Opened from "
-               << anOutPort->NodeName() << " " << anOutPort->PortName()
-               << " " ;
+               << anInPort->PortName() << " Gate is Opened from Node "
+               << anOutPort->NodeName() << "( " << anOutPort->PortName()
+               << ") " ;
 #ifdef _DEBUG_
         if ( GraphBase::Base::_prof_debug ) {
           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
@@ -876,9 +908,9 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
       else if ( LoopFinished ) {
         anInPort->State( SUPERV::ReadyState ) ;
         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
-               << anInPort->PortName() << " GATE IS CLOSED from "
-               << anOutPort->NodeName() << " " << anOutPort->PortName()
-               << " LoopFinished" ;
+               << anInPort->PortName() << " GATE IS CLOSED from Node "
+               << anOutPort->NodeName() << "( " << anOutPort->PortName()
+               << ") LoopFinished" ;
 #ifdef _DEBUG_
         if ( GraphBase::Base::_prof_debug ) {
           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
@@ -888,9 +920,9 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
       }
       else {
         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
-               << anInPort->PortName() << " GATE IS CLOSED from "
-               << anOutPort->NodeName() << " " << anOutPort->PortName()
-               << " " ;
+               << anInPort->PortName() << " GATE IS CLOSED from Node "
+               << anOutPort->NodeName() << "( " << anOutPort->PortName()
+               << ") " ;
 #ifdef _DEBUG_
         if ( GraphBase::Base::_prof_debug ) {
           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
@@ -899,21 +931,39 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
         cdebug << endl ;
       }
     }
-    else {
+    else if ( anOutPort->Done() ) {
       InReady += 1 ;
       anInPort->State( SUPERV::ReadyState ) ;
       cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
-             << anInPort->PortName() << " is Done from "
-             << anOutPort->NodeName() << " " << anOutPort->PortName() << " " ;
+             << anInPort->PortName() << " " << anInPort->PortStatus() << " is Done from Node "
+             << anOutPort->NodeName() << "( " << anOutPort->PortName() << ") "
+             << anOutPort->PortStatus() << " " ;
 #ifdef _DEBUG_
-        if ( GraphBase::Base::_prof_debug ) {
-          anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
-       }
+      if ( GraphBase::Base::_prof_debug ) {
+        anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
+      }
 #endif
-        cdebug << endl ;
+      cdebug << endl ;
+// MacroNode : give immediately the value to the corresponding graph
+      if ( IsMacroNode() ) {
+        cout << "SomeDataReadyAction " << GraphMacroNode() << " " << GraphMacroNode()->Name()
+             << " coupled to " << GraphMacroNode()->CoupledNode() << endl ;
+        GraphExecutor::DataFlow * aMacroGraph = GraphMacroNode()->CoupledNode()->GraphEditor()->Executor() ;
+        cdebug << "SomeDataReadyAction MacroNode " << aMacroGraph->Graph()->Name() << " --> InputOfAny "
+               << InReady << "/" << GetNodeInPortsSize() << " InPorts are Ready" << endl ;
+//        GraphMacroNode()->MacroObject()->InputOfAny( anInPort->PortName() , *anOutPort->Value() ) ;
+        aMacroGraph->InputOfAny( anInPort->PortName() , *anOutPort->Value() ) ;
+      }
+    }
+    else {
+      cdebug << pthread_self() << "/" << ThreadNo() << " Node " << Name() << "( "
+             << anInPort->PortName() << ") " << anInPort->PortStatus()
+             << " is NOT Done from Node "
+             << anOutPort->NodeName() << "( " << anOutPort->PortName() << ") "
+             << anOutPort->PortStatus() << " " ;
     }
   }
-  
+
   if ( InReady == GetNodeInPortsSize() ) { // All Flags != 0 :
     res = SendEvent( GraphExecutor::AllDataReadyEvent ); // ==> Ready to execute
   }
@@ -940,7 +990,7 @@ int GraphExecutor::InNode::DataUndef_AllDataReadyAction() {
 //         << " CreateNewThreadIf " << CreateNewThreadIf() << " IsLockedDataWait "
 //         << IsLockedDataWait() ;
   if ( IsLockedDataWait() ) {
-//    cdebug << " WOULD DEAD-LOCK" << endl ;
+    cdebug << "DataUndef_AllDataReadyAction() WOULD DEAD-LOCK" << endl ;
     return 0 ; // ==> DataUndef_AllDataReadyAction() after UnLockDataWait()
   }
 //  cdebug << endl ;
@@ -950,7 +1000,7 @@ int GraphExecutor::InNode::DataUndef_AllDataReadyAction() {
     ThreadNo( pthread_self() ) ;
   }
   _OutNode->PushEvent( this , GraphExecutor::AllDataReadyEvent ,
-                       SUPERV::DataReadyState ) ; 
+                       GraphExecutor::DataReadyState ) ; 
   ReadyAction() ;
   SUPERV::ControlState aControl = ControlState() ;
   switch ( aControl ) {
@@ -1000,7 +1050,7 @@ int GraphExecutor::InNode::DataReady_SuspendAction() {
          << " Threads " << _OutNode->Threads() << " SuspendedThreads "
          << _OutNode->SuspendedThreads() << endl;
   _OutNode->PushEvent( this , GraphExecutor::SuspendedReadyEvent ,
-                       SUPERV::SuspendedReadyState ) ;
+                       GraphExecutor::SuspendedReadyState ) ;
   GraphExecutor::InNode * aReStartNode = SuspendAction() ;
   cdebug << pthread_self() << "/" << ThreadNo()
          << "DataReady_SuspendAction Resumed " << Name() << endl;
@@ -1019,13 +1069,13 @@ int GraphExecutor::InNode::SuspendedReady_ResumeAction() {
          << Name() << endl;
 //  ResumeAction() ;
   _OutNode->PushEvent( this , GraphExecutor::ResumedReadyEvent ,
-                       SUPERV::ResumedReadyState ) ; 
+                       GraphExecutor::ResumedReadyState ) ; 
   return 1 ;
 }
 
 int GraphExecutor::InNode::DataReady_KillAction() {
   _OutNode->PushEvent( this , GraphExecutor::KilledReadyEvent ,
-                       SUPERV::KilledReadyState ) ;
+                       GraphExecutor::KilledReadyState ) ;
   KillAction() ;
   cdebug << pthread_self() << "/" << ThreadNo() << "DataReady_KillAction " << Name()
          << " will pthread_exit()" << endl;
@@ -1034,7 +1084,7 @@ int GraphExecutor::InNode::DataReady_KillAction() {
 
 int GraphExecutor::InNode::DataReady_StopAction() {
   _OutNode->PushEvent( this , GraphExecutor::StoppedReadyEvent ,
-                       SUPERV::StoppedReadyState ) ; 
+                       GraphExecutor::StoppedReadyState ) ; 
   StopAction() ;
   cdebug << pthread_self() << "/" << ThreadNo() << "DataReady_StopAction " << Name()
          << " will pthread_exit()" << endl;
@@ -1049,74 +1099,89 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
 //  cdebug << pthread_self() << "/" << ThreadNo() << " --> DataReady_ExecuteAction "
 //         << Name() << endl;
   _OutNode->PushEvent( this , GraphExecutor::ExecuteEvent ,
-                       SUPERV::ExecutingState ) ; 
+                       GraphExecutor::ExecutingState ) ; 
 
   RunningAction() ;
+
+  bool Err = false ;
+
   SUPERV::GraphState PortState = SUPERV::ReadyState ;
-  SUPERV::AutomatonState NewState = SUPERV::DataUndefState ;
+  GraphExecutor::AutomatonState NewState = GraphExecutor::DataUndefState ;
   GraphExecutor::NodeEvent NewEvent = GraphExecutor::UndefinedEvent ;
 
-  bool Err = false ;
+  int nInParams ;
+  ServicesAnyData * InParametersList ;
+  int nOutParams ;
+  ServicesAnyData * OutParametersList ;
 
-  int nInParams = GetNodeInPortsSize()  ;
-  ServicesAnyData * InParametersList = new ServicesAnyData[nInParams];
+  nInParams = GetNodeInPortsSize()  ;
+  InParametersList = new ServicesAnyData[nInParams];
   InParametersSet( Err , nInParams , InParametersList ) ;
 
-  Engines::Container_var myContainer ;
-  Engines::Component_var myObjComponent ;
-  if ( !IsFactoryNode() ) {
-//    cdebug << ThreadNo() << "No Component : NO StartComponent & No Ping" << endl ;
-    if ( IsComputingNode() ) {
-      ObjInterface( true ) ;
-      CORBA::Object_ptr obj ;
-      InParametersList[0].Value >>= obj ;
-      CORBA::Object_var objvar = CORBA::Object_var( obj ) ;
-      myObjComponent = Engines::Component::_narrow( objvar ) ;
+  nOutParams = GetNodeOutPortsSize() ;
+  OutParametersList = new ServicesAnyData[nOutParams];
+  InOutParametersSet( nOutParams , OutParametersList ) ;
+
+  if ( !IsMacroNode() ) {
+
+    Engines::Container_var myContainer ;
+    Engines::Component_var myObjComponent ;
+    if ( !IsFactoryNode() ) {
+//      cdebug << ThreadNo() << "No Component : NO StartComponent & No Ping" << endl ;
+      if ( IsComputingNode() ) {
+        ObjInterface( true ) ;
+        CORBA::Object_ptr obj ;
+        InParametersList[0].Value >>= obj ;
+        CORBA::Object_var objvar = CORBA::Object_var( obj ) ;
+        myObjComponent = Engines::Component::_narrow( objvar ) ;
+      }
+      else {
+      }
     }
-    else {
+    else if ( CORBA::is_nil( Component() ) ) {
+//      ostringstream astr ;
+//      astr << "Graph " << _OutNode->Graph()->Name() << " Node " << Name()
+//           << " : load of component " << ComponentName() << " in container "
+//           << Computer() ;
+//      _OutNode->Graph()->ObjImpl()->sendMessage( NOTIF_STEP, astr.str().c_str() ) ;
+      Err = !_OutNode->Graph()->StartComponent( ThreadNo() , Computer() ,
+                                                my_strdup( ComponentName() ) ,
+                                                myContainer , myObjComponent ) ;
+      ObjInterface( false ) ;
+      SetContainer( myContainer ) ;
+      SetComponent( myObjComponent ) ;
     }
-  }
-  else if ( CORBA::is_nil( Component() ) ) {
-    ostringstream astr ;
-    astr << "Graph " << _OutNode->Graph()->Name() << " Node " << Name()
-         << " : load of component " << ComponentName() << " in container "
-         << Computer() ;
-//    _OutNode->Graph()->ObjImpl()->sendMessage( NOTIF_STEP, astr.str().c_str() ) ;
-    Err = !_OutNode->Graph()->StartComponent( ThreadNo() , Computer() ,
-                                              my_strdup( ComponentName() ) ,
-                                              myContainer , myObjComponent ) ;
-    ObjInterface( false ) ;
-    SetContainer( myContainer ) ;
-    SetComponent( myObjComponent ) ;
-  }
-  else {
-    myContainer = Container() ;
-    myObjComponent = Component() ;
-//    cdebug << ThreadNo() << "Component known : NO StartComponent & Ping"
-//           << endl ;
-    try {
-      myObjComponent->ping() ;
-    }
-    catch( ... ) {
-      cdebug << "ping() catched" << endl ;
-      Err = true ;
+    else {
+      myContainer = Container() ;
+      myObjComponent = Component() ;
+//      cdebug << ThreadNo() << "Component known : NO StartComponent & Ping"
+//             << endl ;
+      try {
+        myObjComponent->ping() ;
+      }
+      catch( ... ) {
+        cdebug << "ping() catched" << endl ;
+        Err = true ;
+      }
     }
-  }
-
-  int nOutParams = GetNodeOutPortsSize()  ;
-  ServicesAnyData * OutParametersList = new ServicesAnyData[nOutParams];
-  InOutParametersSet( nOutParams , OutParametersList ) ;
 
     if ( Err || ControlState() == SUPERV::ToKillState ||
                 ControlState() == SUPERV::ToKillDoneState ||
                 ControlState() == SUPERV::ToStopState ) {
       cdebug << ThreadNo() << "StartComponent Error or ToKillState" << endl ;
+      MESSAGE(pthread_self() << "Executor::InNode::DataReady_ExecuteAction of " << Name()
+              << " ControlState " << Automaton()->ControlStateName( ControlState() )
+              << " BEFORE execution ThreadNo " << ThreadNo() ) ;
       Err = true ;
     }
     else {
+      if ( ControlState() == SUPERV::ToSuspendState ) {
+        cdebug << ThreadNo() << "ToSuspendState before running." << endl ;
+        MESSAGE(ThreadNo() << "ToSuspendState before running.") ;
+      }
       if ( !Err ) {
-        ostringstream astr ;
-        astr << "Graph " << _OutNode->Graph()->Name() << " Run of Node " << Name() ;
+//        ostringstream astr ;
+//        astr << "Graph " << _OutNode->Graph()->Name() << " Run of Node " << Name() ;
 //        _OutNode->Graph()->ObjImpl()->sendMessage( NOTIF_STEP, astr.str().c_str() ) ;
         cdebug << ThreadNo() << " Run( '" << ServiceName() << "'" ;
         for ( i = 0 ; i < (int ) ServiceInParameter().length() ; i++ ) {
@@ -1129,7 +1194,8 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
         }
         if ( IsOneOfInLineNodes() ) {
           cdebug << " , PyFuncName '" << InLineNode()->PyFuncName() << "' PyRunMethod "
-                 << InLineNode()->PyRunMethod() << " length " << (*InLineNode()->PythonFunction()).length() ;
+                 << InLineNode()->PyRunMethod() << " length "
+                 << (*InLineNode()->PythonFunction()).length() ;
        }
         cdebug << ")" << endl ;
 
@@ -1139,107 +1205,146 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
           SetPyCpuUsed() ;
           try {
 //            if ( IsInLineNode() && (*InLineNode()->PythonFunction()).length() &&
+            bool ItIsaLoop = false ;
             bool CopyInOut = false ;
            if ( IsInLineNode() && /*InLineNode()->PyRunMethod() &&*/
                  strlen( InLineNode()->PyFuncName() ) ) {
-//              cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
-//                     << InLineNode()->PyFuncName()
-//                     << "' IsInLineNode PyDynInvoke"  << endl ;
+              cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
+                     << InLineNode()->PyFuncName()
+                     << "' IsInLineNode PyDynInvoke"  << endl ;
               StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
                                             InLineNode()->PyFuncName() ,
                                             &InParametersList[0] , ServiceInParameter().length() ,
                                             &OutParametersList[0] , ServiceOutParameter().length() ) ;
-           }
+              if ( !StsPyDynInvoke ) {
+                RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
+             }     }
             else if ( IsLoopNode() ) {
+              ItIsaLoop = true ;
               bool CopyOutIn = false ;
-              if ( GetNodeInLoop()->GetOutPort()->BoolValue() && /*InLineNode()->PyRunMethod() &&*/
-                   strlen( InLineNode()->PyFuncName() ) ) { // InLoop Port
-//                cdebug << ThreadNo() << " !ObjInterface " << Name()
-//                       << " IsLoopNode PyDynInvoke '" << InLineNode()->PyFuncName()
-//                       << "'" << endl ;
-                StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
-                                              InLineNode()->PyFuncName() ,
-                                              &InParametersList[1] , ServiceInParameter().length() ,
-                                              &OutParametersList[1] , ServiceOutParameter().length() ) ;
-                CopyOutIn = true ;
+// Switch between Init() and Next()
+// if InLoop port is true and does not come from EndLoop ==> execute Init
+// if InLoop port is false or come from EndLoop ==> execute Next
+//              GraphExecutor::InNode * anEndLoopNode = (GraphExecutor::InNode * ) CoupledNode()->GetInNode() ;
+//              if ( GetNodeInLoop()->GetOutPort()->BoolValue() &&
+              if ( _InitLoop ) {
+                if ( strlen( InLineNode()->PyFuncName() ) ) { // InLoop Port = true ==> Init()
+                  cdebug << ThreadNo() << " !ObjInterface " << Name()
+                         << " IsLoopNode PyDynInvoke '" << InLineNode()->PyFuncName()
+                         << "' InitLoop " << LoopNode()->PyRunMethod() << endl ;
+                  StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
+                                                InLineNode()->PyFuncName() ,
+                                                &InParametersList[1] , ServiceInParameter().length() ,
+                                                &OutParametersList[1] , ServiceOutParameter().length() ) ;
+                if ( !StsPyDynInvoke ) {
+                  RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
+               }
+                  CopyOutIn = true ;
+               }
+                else {
+                  cdebug << ThreadNo() << " !ObjInterface " << Name()
+                         << " IsLoopNode NO PyDynInvoke Void PyFuncName InitLoop" << endl ;
+               }
+                cdebug << ThreadNo() << " !ObjInterface " << Name()
+                       << " IsLoopNode _InitLoop Reset after Init() Python Function" << endl ;
+                _InitLoop = false ;
              }
               else if ( LoopNode()->PyNextMethod() &&
-                        strlen( LoopNode()->PyNextName() ) ){
-//                cdebug << ThreadNo() << " !ObjInterface " << Name()
-//                       << " IsLoopNode PyDynInvoke '" << LoopNode()->PyNextName()
-//                       << "'" << endl ;
+                        strlen( LoopNode()->PyNextName() ) ){ // InLoop Port = false ==> Next()
+                cdebug << ThreadNo() << " !ObjInterface " << Name()
+                       << " IsLoopNode PyDynInvoke '" << LoopNode()->PyNextName()
+                       << "' " << LoopNode()->PyNextMethod() << endl ;
                 StsPyDynInvoke = PyDynInvoke( LoopNode()->PyNextMethod() ,
                                               LoopNode()->PyNextName() ,
                                               &InParametersList[1] , ServiceInParameter().length() ,
                                               &OutParametersList[1] , ServiceOutParameter().length() ) ;
+                if ( !StsPyDynInvoke ) {
+                  RemovePyDynInvoke( LoopNode()->PyNextName() ) ;
+               }
                 CopyOutIn = true ;
              }
-              if ( StsPyDynInvoke && CopyOutIn ) {
-//                cdebug << ThreadNo() << " !ObjInterface " << Name()
-//                       << " IsLoopNode PyDynInvoke '" << LoopNode()->PyMoreName()
-//                       << "' Copy of " << ServiceInParameter().length()
-//                       << " OutParameters" << endl ;
-                int i ;
-                for ( i = 1 ; i <= (int ) ServiceInParameter().length() ; i++ ) {
-                  InParametersList[i].Value = OutParametersList[i].Value ;
-                  InParametersList[i].Name = OutParametersList[i].Name ;
+              else {
+                cdebug << ThreadNo() << " !ObjInterface " << Name()
+                       << " IsLoopNode NO PyDynInvoke Void PyFuncName NextLoop" << endl ;
+             }
+              if ( StsPyDynInvoke ) {
+                if ( CopyOutIn ) {
+                  cdebug << ThreadNo() << " !ObjInterface " << Name()
+                         << " IsLoopNode PyDynInvoke '" << LoopNode()->PyMoreName()
+                         << "' Copy of " << ServiceInParameter().length()
+                         << " OutParameters" << endl ;
+                  int i ;
+// Start at 1 : Do not copy InLoop ( InLoop == true <==> Init ; InLoop == false <==> Next )
+                  for ( i = 1 ; i <= (int ) ServiceInParameter().length() ; i++ ) {
+                    InParametersList[i].Value = OutParametersList[i].Value ;
+                    InParametersList[i].Name = OutParametersList[i].Name ;
 //#if 0
-                  switch ( InParametersList[i].Value.type()->kind() ) {
-                  case CORBA::tk_string :
-                    char * t;
-                    InParametersList[i].Value >>= t ;
-                    cdebug << "ArgOut->In" << i << " : "
-                           << InParametersList[i].Name.c_str()
-                           << " Value(string) " << t << endl ;
-                    break ;
-                  case CORBA::tk_double :
-                    double d;
-                    InParametersList[i].Value >>= d;
-                    cdebug << "ArgOut->In" << i << " : "
-                           << InParametersList[i].Name.c_str()
-                           << " Value(double) " << d << endl ;
-                    break ;
-                  case CORBA::tk_long :
-                    long l;
-                    InParametersList[i].Value >>= l;
-                    cdebug << "ArgOut->In" << i << " : "
-                           << InParametersList[i].Name.c_str()
-                           << " Value(long) " << l << endl ;
-                    break ;
-                  case CORBA::tk_objref :
-                    CORBA::Object_ptr obj ;
-                    char * retstr ;
-                    try {
-                      InParametersList[i].Value >>= obj ;
-                      retstr = ObjectToString( obj );
+                    switch ( InParametersList[i].Value.type()->kind() ) {
+                    case CORBA::tk_string :
+                      char * t;
+                      InParametersList[i].Value >>= t ;
                       cdebug << "ArgOut->In" << i << " : "
                              << InParametersList[i].Name.c_str()
-                             << " Value(object reference) " << retstr << endl ;
-                    }
-                    catch ( ... ) {
+                             << " Value(string) " << t << endl ;
+                      break ;
+                    case CORBA::tk_double :
+                      double d;
+                      InParametersList[i].Value >>= d;
                       cdebug << "ArgOut->In" << i << " : "
                              << InParametersList[i].Name.c_str()
-                             << " Value(object reference) Catched ERROR" << endl ;
-                   }
-                    break ;
-                  default :
-                    cdebug << "ArgOut->In" << i << " : "
-                           << InParametersList[i].Name.c_str()
-                           << " Value(other) ERROR" << endl ;
-                 }
+                             << " Value(double) " << d << endl ;
+                      break ;
+                    case CORBA::tk_long :
+                      long l;
+                      InParametersList[i].Value >>= l;
+                      cdebug << "ArgOut->In" << i << " : "
+                             << InParametersList[i].Name.c_str()
+                             << " Value(long) " << l << endl ;
+                      break ;
+                    case CORBA::tk_objref :
+                      CORBA::Object_ptr obj ;
+                      char * retstr ;
+                      try {
+                        InParametersList[i].Value >>= obj ;
+                        retstr = ObjectToString( obj );
+                        cdebug << "ArgOut->In" << i << " : "
+                               << InParametersList[i].Name.c_str()
+                               << " Value(object reference) " << retstr << endl ;
+                      }
+                      catch ( ... ) {
+                        cdebug << "ArgOut->In" << i << " : "
+                               << InParametersList[i].Name.c_str()
+                               << " Value(object reference) Catched ERROR" << endl ;
+                     }
+                      break ;
+                    default :
+                      cdebug << "ArgOut->In" << i << " : "
+                             << InParametersList[i].Name.c_str()
+                             << " Value(other) ERROR" << endl ;
+                   }
 //#endif
+                 }
                }
                 if ( LoopNode()->PyMoreMethod() && strlen( LoopNode()->PyMoreName() ) ) {
+                  cdebug << ThreadNo() << " !ObjInterface " << Name()
+                         << " IsLoopNode PyDynInvoke '" << LoopNode()->PyMoreName()
+                         << "' " << LoopNode()->PyMoreMethod() << endl ;
                   StsPyDynInvoke = PyDynInvoke( LoopNode()->PyMoreMethod() ,
                                                 LoopNode()->PyMoreName() ,
                                                 &InParametersList[1] , ServiceInParameter().length() ,
                                                 &OutParametersList[0] , ServiceOutParameter().length()+1 ) ;
+                  if ( !StsPyDynInvoke ) {
+                    RemovePyDynInvoke( LoopNode()->PyMoreName() ) ;
+                 }
                }
                 else {
+                  cdebug << ThreadNo() << " !ObjInterface " << Name()
+                         << " IsLoopNode PyDynInvoke '" << LoopNode()->PyMoreName()
+                         << "' No MoreMethod" << endl ;
                   CopyInOut = true ;
                }
              }
-              else  if ( !StsPyDynInvoke ) {
+              else {
                 Err = true ;
                 cdebug << ThreadNo() << " InLineNode " << Name() << " "
                        << InLineNode()->PyFuncName() << "/" << LoopNode()->PyNextName()
@@ -1256,6 +1361,9 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
                                             InLineNode()->PyFuncName() ,
                                             &InParametersList[0] , ServiceInParameter().length() ,
                                             &OutParametersList[0] , ServiceOutParameter().length() ) ;
+              if ( !StsPyDynInvoke ) {
+                RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
+             }
            }
 //            else if ( IsGOTONode() && (*GOTONode()->PythonFunction()).length() &&
             else if ( IsGOTONode() && /*InLineNode()->PyRunMethod() &&*/
@@ -1267,6 +1375,9 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
                                             InLineNode()->PyFuncName() ,
                                             &InParametersList[0] , ServiceInParameter().length() ,
                                             &OutParametersList[0] , ServiceOutParameter().length() ) ;
+              if ( !StsPyDynInvoke ) {
+                RemovePyDynInvoke( GOTONode()->PyFuncName() ) ;
+             }
            }
 //            else if ( IsEndSwitchNode() && (*InLineNode()->PythonFunction()).length() &&
             else if ( ( IsEndSwitchNode() ) &&
@@ -1278,20 +1389,28 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
                                             InLineNode()->PyFuncName() ,
                                             &InParametersList[0] , ServiceInParameter().length() ,
                                             &OutParametersList[0] , ServiceOutParameter().length() ) ;
+              if ( !StsPyDynInvoke ) {
+                RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
+             }
            }
             else if ( ( IsEndLoopNode() ) &&
                       InLineNode()->PyRunMethod() && strlen( InLineNode()->PyFuncName() ) ) {
-//              cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
-//                     << InLineNode()->PyFuncName()
-//                     << "' IsSwitchNode PyDynInvoke"  << endl ;
+              cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
+                     << InLineNode()->PyFuncName()
+                     << "' IsSwitchNode PyDynInvoke"  << endl ;
               StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
                                             InLineNode()->PyFuncName() ,
                                             &InParametersList[0] , ServiceInParameter().length() + 1 ,
                                             &OutParametersList[0] , ServiceOutParameter().length() + 1 ) ;
+              if ( !StsPyDynInvoke ) {
+                RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
+             }
            }
+
 //            else if ( (*InLineNode()->PythonFunction()).length() == 0 ||
-            if ( InLineNode()->PyRunMethod() == NULL ||
-                 strlen( InLineNode()->PyFuncName() ) == 0 || CopyInOut ) {
+            if ( (!ItIsaLoop && ( InLineNode()->PyRunMethod() == NULL ||
+                                  strlen( InLineNode()->PyFuncName() ) == 0 ) ) || CopyInOut ) {
+// This is a void Python Function : without code (No PyFuncName)
 //              cdebug << ThreadNo() << " !ObjInterface " << Name()
 //                     << " Copy of " << ServiceInParameter().length()
 //                     << " OutParameters" << endl ;
@@ -1301,8 +1420,12 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
               if ( IsLoopNode() || IsEndLoopNode() ) {
                 argout0 = 1 ;
                 argin0 = 1 ; // after DoLoop
-                if ( IsLoopNode() ) {
-                  OutParametersList[0].Value = InParametersList[0].Value ; // DoLoop
+                if ( IsLoopNode() ) { // More() is void
+//                  OutParametersList[0].Value = InParametersList[0].Value ; // DoLoop
+                  cdebug << Name() << " Not Beginning of loop and non void EndLoop : DoLoop = EndLoop(DoLoop)"
+                         << endl ;
+                  GraphExecutor::InNode * anEndLoopNode = (GraphExecutor::InNode * ) CoupledNode()->GetInNode() ;
+                  OutParametersList[0].Value = *anEndLoopNode->GetNodeOutLoop()->Value() ; // DoLoop = EndLoop(DoLoop)
                }
              }
               for ( i = 0 ; i < (int ) ServiceInParameter().length() ; i++ ) {
@@ -1397,7 +1520,7 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
               }
               catch( ... ) {
                 cdebug << "DynInvoke setProperties catched ERROR" << endl ;
-                Err = true ;
+               Err = true;
              }
            }
             if ( !Err && IsComputingNode() ) {
@@ -1405,16 +1528,18 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
                      << " IsComputingNode DynInvoke"  << endl ;
               cdebug << ServiceInParameter().length()-1 << " input parameters and "
                      << ServiceOutParameter().length() << " output parameters" << endl ;
+              IsLoading( false ) ;
               DynInvoke( myObjComponent,
                          ServiceName() ,
                          &InParametersList[1] , ServiceInParameter().length()-1 ,
                          &OutParametersList[0] , ServiceOutParameter().length() ) ;
            }
-            else if ( !Err &&IsFactoryNode() ) {
+            else if ( !Err && IsFactoryNode() ) {
               cdebug << ThreadNo() << " !ObjInterface " << Name()
                      << " IsFactoryNode DynInvoke"  << endl ;
               cdebug << ServiceInParameter().length() << " input parameters and "
                      << ServiceOutParameter().length() << " output parameters" << endl ;
+              IsLoading( false ) ;
               DynInvoke( myObjComponent,
                          ServiceName() ,
                          &InParametersList[0] , ServiceInParameter().length() ,
@@ -1428,50 +1553,95 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
             cdebug << ThreadNo() << " !ObjInterface " << Name()
                    << " Node(Component) Dynamic Call Exception catched ERROR"
                    << endl ;
+//Reset of _ThreadId in the Container ...
+            try {
+              myObjComponent->Kill_impl() ;
+           }
+            catch( ... ) {
+           }
          }
         }
       }
     }
-//  }
-//  else {
-//    sleep( 1 ) ;
-//  }
+  }
 
-  ostringstream astr ;
-  astr << "Graph " << _OutNode->Graph()->Name() << " Node " << Name() << " is done : "
-       << Automaton()->StateName( State() ) ;
+//  ostringstream astr ;
+//  astr << "Graph " << _OutNode->Graph()->Name() << " Node " << Name() << " is done : "
+//       << Automaton()->StateName( State() ) ;
 //  _OutNode->Graph()->ObjImpl()->sendMessage( NOTIF_STEP, astr.str().c_str() ) ;
+
   if ( Err ) {
+    
+    // if exception or something else - IsLoading( false ) may not NOT has been called
+    if ( IsLoading() )
+      IsLoading( false );
+
     if ( ControlState() == SUPERV::ToKillState ||
          ControlState() == SUPERV::ToKillDoneState ||
          ControlState() == SUPERV::ToStopState ) {
       PortState = SUPERV::ErrorState ;
-      NewState = SUPERV::KilledState ;
+      NewState = GraphExecutor::KilledState ;
       NewEvent = GraphExecutor::KillEvent ;
     }
     else {
       PortState = SUPERV::ErrorState ;
-      NewState = SUPERV::ErroredState ;
+      NewState = GraphExecutor::ErroredState ;
       NewEvent = GraphExecutor::ErrorEvent ;
     }
   }
   else {
     PortState = SUPERV::ReadyState ;
-    NewState = SUPERV::DataReadyState ;
+    NewState = GraphExecutor::DataReadyState ;
     NewEvent = GraphExecutor::SuccessEvent ;
   }
 
-  bool ErrOut = OutParametersSet( Err , PortState , nOutParams , OutParametersList ) ;
-              
-  if ( !ErrOut ) {
-    NewEvent = GraphExecutor::ErrorEvent ;
+  if ( !IsMacroNode() ) {
+    bool ErrOut = OutParametersSet( Err , PortState , nOutParams , OutParametersList ) ;
+    if ( !ErrOut ) {
+      NewEvent = GraphExecutor::ErrorEvent ;
+    }
+    delete [] InParametersList ;
+    delete [] OutParametersList ;
   }
          
-  delete [] InParametersList ;
-  delete [] OutParametersList ;
-
-              
-  SendEvent( NewEvent );
+  if ( !IsMacroNode() ) {              
+    SendEvent( NewEvent ) ;
+  }
+  else {
+    GraphExecutor::DataFlow * aMacroGraph = GraphMacroNode()->CoupledNode()->GraphEditor()->Executor() ;
+    cdebug << ThreadNo() << " DataReady_ExecuteAction " << aMacroGraph << " "
+           << aMacroGraph->Graph()->Name() << " ->DoneWait()"
+           << " State " << aMacroGraph->State() << endl;
+    aMacroGraph->DoneWait() ;
+    cdebug << ThreadNo() << " DataReady_ExecuteAction " << Name() << " State " << aMacroGraph->State() << endl;
+    if ( aMacroGraph->State() == SUPERV::DoneState ) {
+      PortState = SUPERV::ReadyState ;
+      NewState = GraphExecutor::DataReadyState ;
+      NewEvent = GraphExecutor::SuccessEvent ;
+    }
+    else {
+      Err = true ;
+      if ( ControlState() == SUPERV::ToKillState ||
+           ControlState() == SUPERV::ToKillDoneState ||
+           ControlState() == SUPERV::ToStopState ) {
+        PortState = SUPERV::ErrorState ;
+        NewState = GraphExecutor::KilledState ;
+        NewEvent = GraphExecutor::KillEvent ;
+      }
+      else {
+        PortState = SUPERV::ErrorState ;
+        NewState = GraphExecutor::ErroredState ;
+        NewEvent = GraphExecutor::ErrorEvent ;
+      }
+    }
+    bool ErrOut = OutParametersSet( Err , PortState , nOutParams , OutParametersList ) ;
+    if ( !ErrOut ) {
+      NewEvent = GraphExecutor::ErrorEvent ;
+    }
+    delete [] InParametersList ;
+    delete [] OutParametersList ;
+    SendEvent( NewEvent ) ;
+  }
 
 //  cdebug << ThreadNo() << " <-- DataReady_ExecuteAction " << Name() << endl;
   return 1 ;
@@ -1479,14 +1649,14 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
 
 int GraphExecutor::InNode::Executing_SuspendAction() {
   _OutNode->PushEvent( this , GraphExecutor::SuspendedExecutingEvent ,
-                       SUPERV::SuspendedExecutingState ) ; 
+                       GraphExecutor::SuspendedExecutingState ) ; 
   cdebug << ThreadNo() << " Executing_SuspendAction " << Name() << endl;
   return 1 ;
 }
 
 int GraphExecutor::InNode::SuspendedExecuting_ResumeAction() {
   cdebug << ThreadNo() << " SuspendedExecuting_ResumeAction " << Name() << endl;
-  SUPERV::AutomatonState next_state ;
+  GraphExecutor::AutomatonState next_state ;
   next_state = Automaton()->NextState( State() , GraphExecutor::ExecutingEvent ) ;
   _OutNode->NewThread() ; // Only for Threads count
   _OutNode->PushEvent( this , GraphExecutor::ResumedExecutingEvent ,
@@ -1496,42 +1666,42 @@ int GraphExecutor::InNode::SuspendedExecuting_ResumeAction() {
 }
 
 int GraphExecutor::InNode::Executing_KillAction() {
-  cdebug << ThreadNo() << " Executing_KillAction " << Name() << endl;
+  cdebug << ThreadNo() << " Executing_KillAction " << Name() << " Thread " << ThreadNo()<< endl;
   int RetVal = 0 ;
   if ( pthread_self() == ThreadNo() ) {
     cdebug << "Executing_KillAction would pthread_canceled itself" << endl ;
     KillAction() ;
     _OutNode->PushEvent( this , GraphExecutor::KilledExecutingEvent ,
-                         SUPERV::KilledExecutingState ) ; 
+                         GraphExecutor::KilledExecutingState ) ; 
     RetVal = 1 ;
   }
   else if ( pthread_cancel( ThreadNo() ) ) {
     perror("Executing_KillAction pthread_cancel error") ;
   }
   else {
-    cdebug << "Executing_KillAction : ThreadId " << ThreadNo()
+    cdebug << pthread_self() << " Executing_KillAction : ThreadId " << ThreadNo()
            << " pthread_canceled" << endl ;
     KillAction() ;
-    _OutNode->ExitThread() ;
+    _OutNode->ExitThread( ThreadNo() ) ;
     _OutNode->PushEvent( this , GraphExecutor::KilledExecutingEvent ,
-                         SUPERV::KilledExecutingState ) ; 
+                         GraphExecutor::KilledExecutingState ) ; 
   }
   return RetVal ;
 }
 
 int GraphExecutor::InNode::Executing_StopAction() {
-  cdebug << ThreadNo() << " Executing_StopAction " << Name() << endl;
+  cdebug << ThreadNo() << " Executing_StopAction " << Name() << " Thread " << ThreadNo() << endl;
   int RetVal = 0 ;
   if ( pthread_cancel( ThreadNo() ) ) {
     perror("Executing_KillAction pthread_cancel error") ;
   }
   else {
-    cdebug << "Executing_KillAction : ThreadId " << ThreadNo()
+    cdebug << pthread_self() << " Executing_KillAction : ThreadId " << ThreadNo()
            << " pthread_canceled" << endl ;
     StopAction() ;
-    _OutNode->ExitThread() ;
+    _OutNode->ExitThread( ThreadNo() ) ;
     _OutNode->PushEvent( this , GraphExecutor::StoppedExecutingEvent ,
-                         SUPERV::StoppedExecutingState ) ; 
+                         GraphExecutor::StoppedExecutingState ) ; 
   }
   return RetVal ;
 }
@@ -1539,7 +1709,10 @@ int GraphExecutor::InNode::Executing_StopAction() {
 int GraphExecutor::InNode::Executing_SuccessAction() {
 //  cdebug << ThreadNo() << " --> Executing_SuccessAction " << Name() << endl;
   _OutNode->PushEvent( this , GraphExecutor::SuccessedExecutingEvent ,
-                       SUPERV::SuccessedState ) ; 
+                       GraphExecutor::SuccessedState ) ; 
+  MESSAGE(pthread_self() << "Executor::InNode::Executing_SuccessAction of " << Name()
+          << " ControlState " << Automaton()->ControlStateName( ControlState() )
+          << " AFTER execution ThreadNo " << ThreadNo() ) ;
   SUPERV::ControlState aControl = ControlState() ;
   switch ( aControl ) {
   case SUPERV::VoidState : {
@@ -1580,7 +1753,7 @@ int GraphExecutor::InNode::Executing_SuccessAction() {
 int GraphExecutor::InNode::Executing_ErrorAction() {
   cdebug << ThreadNo() << " --> Executing_ErrorAction " << Name() << endl;
   _OutNode->PushEvent( this , GraphExecutor::ErroredExecutingEvent ,
-                       SUPERV::ErroredState ) ; 
+                       GraphExecutor::ErroredState ) ; 
 
   SUPERV::ControlState aControl = ControlState() ;
   switch ( aControl ) {
@@ -1624,42 +1797,61 @@ void GraphExecutor::InNode::SetWaitingStates(GraphExecutor::InNode * EndNode ) {
   int i ;
   int j ;
   bool docdebug = false ;
-  State( SUPERV::DataWaitingState ) ;
+  State( GraphExecutor::DataWaitingState ) ;
   for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
     GraphBase::InPort * anInPort = GetChangeNodeInPort( i ) ;
-    if ( anInPort->IsGate() ) { // Loop : Open the doors
+    cdebug << "SetWaitingStates InPort " << Name() << "( " << anInPort->PortName() << " ) "
+           << anInPort->PortStatus() << " " << anInPort->State() << endl ;
+// JR Debug 07.01.2005 : Close the Gates instead of open !!!
+    if ( anInPort->IsGate() ) { // Loop : Close the doors
       GraphBase::OutPort * anOutPort = anInPort->GetOutPort() ;
       if ( anOutPort ) {
         CORBA::Any * anAny = new CORBA::Any() ;
-        *anAny <<= (long ) 1 ;
+//        *anAny <<= (long ) 1 ;
+        *anAny <<= (long ) 0 ;
         anOutPort->Value( anAny ) ;
-        anInPort->State( SUPERV::ReadyState ) ;
+        anInPort->State( SUPERV::WaitingState ) ;
       }
     }
-    else if ( anInPort->State() != SUPERV::WaitingState ) {
+    else if ( anInPort->State() != SUPERV::WaitingState &&
+              !anInPort->IsDataConnected() ) {
       if ( !docdebug ) {
-//        cdebug << ThreadNo()
-//               << " --> GraphExecutor::InNodeThreads::SetWaitingStates " << Name() << endl;
+        cdebug << ThreadNo()
+               << " --> GraphExecutor::InNodeThreads::SetWaitingStates " << Name() << endl;
         docdebug = true ;
       }
       if ( !anInPort->IsDataStream() ) {
         anInPort->State( SUPERV::WaitingState ) ;
       }
     }
+    cdebug << "               --> " << Name() << "( " << anInPort->PortName() << " ) "
+           << anInPort->PortStatus() << " " << anInPort->State() << endl ;
   }
   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
     GraphBase::OutPort * anOutPort = GetChangeNodeOutPort( i ) ;
     for ( j = 0 ; j < anOutPort->InPortsSize() ; j++ ) {
       if ( !( IsGOTONode() && anOutPort->IsGate() ) &&
-           !( IsEndLoopNode() && ( anOutPort->IsGate() ||
-              anOutPort->IsLoop() ) ) &&
+           !( IsEndLoopNode() && ( anOutPort->IsGate() || anOutPort->IsLoop() ) ) &&
            !anOutPort->IsDataStream() &&
-           !anOutPort->ChangeInPorts( j )->IsDataStream() ) {
-//        cdebug << ThreadNo()
-//               << " GraphExecutor::InNodeThreads::SetWaitingStates "
-//               << Name() << "( " << anOutPort->PortName() << " ) --> InPort "
-//               << anOutPort->ChangeInPorts( j )->PortName() << " from Node "
-//               << anOutPort->ChangeInPorts( j )->NodeName() << endl;
+           !anOutPort->ChangeInPorts( j )->IsDataStream() &&
+           !anOutPort->ChangeInPorts( j )->IsExternConnected() ) {
+        cdebug << ThreadNo()
+               << " InNodeThreads::SetWaitingStates OutPort "
+               << Name() << "/" << anOutPort->ChangeInPorts( j )->NodeName() << "( "
+               << anOutPort->PortName() << " " << anOutPort->PortStatus() << " ) --> InPort "
+               << anOutPort->ChangeInPorts( j )->NodeName() << "( "
+               << anOutPort->ChangeInPorts( j )->PortName() << " "
+               << anOutPort->ChangeInPorts( j )->PortStatus() << " )" << endl;
+        if ( strcmp( anOutPort->ChangeInPorts( j )->GetOutPort()->NodeName() , Name() ) ) {
+// After EndLoopNode or GOTONode the Input Ports of LoopNode or LabelNode have their values from
+// EndLoopNode or GOTONode. But if there is several nested loops we should re-establish.
+          cdebug << ThreadNo()
+                 << " InNodeThreads::SetWaitingStates OutPort->ChangeInPorts( j )->OutPort()->NodeName "
+                 << anOutPort->ChangeInPorts( j )->GetOutPort()->NodeName() << " != "
+                 << Name() << " : Restored to " << anOutPort->NodeName() << "( "
+                 << anOutPort->PortName() << " )" << endl ;
+          anOutPort->ChangeInPorts( j )->ChangeOutPort( anOutPort ) ;
+        }
         GraphExecutor::InNode * aNode = (GraphExecutor::InNode * ) _OutNode->Graph()->GetChangeGraphNode( anOutPort->ChangeInPorts( j )->NodeName() )->GetInNode() ;
         if ( aNode != EndNode ) {
           aNode->SetWaitingStates( EndNode ) ;
@@ -1670,7 +1862,7 @@ void GraphExecutor::InNode::SetWaitingStates(GraphExecutor::InNode * EndNode ) {
 }
 
 int GraphExecutor::InNode::Successed_SuccessAction() {
-//  cdebug << ThreadNo() << " --> Successed_SuccessAction "  << Name() << endl;
+  cdebug << ThreadNo() << " --> Successed_SuccessAction "  << Name() << endl;
   int res = 1;
   int linkednodesnumber = LinkedNodesSize() ;
   GraphExecutor::InNode *firstzeroNode = NULL ;
@@ -1682,6 +1874,12 @@ int GraphExecutor::InNode::Successed_SuccessAction() {
 
   DoneAction() ;
 
+  if ( IsMacroNode() ) {
+      cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " LinkedNodes->SomeDataReady already done"
+             << endl ;
+    return 1;
+  }
+
   if ( IsGOTONode() ||
        ( IsEndLoopNode() && GetNodeInLoop()->GetOutPort()->BoolValue() ) ) {
     cdebug << ThreadNo() << " Successed_SuccessAction " << Name()
@@ -1693,18 +1891,31 @@ int GraphExecutor::InNode::Successed_SuccessAction() {
     else {
       aGateOutPort = GetNodeOutLoop() ;
     }
+    if ( aGateOutPort->InPortsSize() != 1 ) {
+      cdebug << ThreadNo() << " Successed_SuccessAction aGateOutPort->InPortsSize "
+             << aGateOutPort->InPortsSize() << " != 1 ERROR " << Name() << endl ;
+    }
+    GraphExecutor::InNode * aLabelNode = NULL ;
     for ( i = 0 ; i < aGateOutPort->InPortsSize() ; i++ ) {
       const GraphBase::InPort * anInPort = aGateOutPort->InPorts( i ) ;
-      GraphExecutor::InNode * aLabelNode = (GraphExecutor::InNode *) _OutNode->Graph()->GetChangeGraphNode( anInPort->NodeName() )->GetInNode() ;
-//      cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " will Loop to HeadNode "
-//             << aLabelNode->Name() << " from port " << anInPort->PortName() << endl ;
+      aLabelNode = (GraphExecutor::InNode *) _OutNode->Graph()->GetChangeGraphNode( anInPort->NodeName() )->GetInNode() ;
+      cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " will Loop to HeadNode "
+             << aLabelNode->Name() << " from port " << anInPort->PortName() << endl ;
       aLabelNode->SetWaitingStates( this ) ;
+// JR 07.01.2005 Debug : Open the Gate of the coupledNode closed by SetWaitingStates
+      GraphBase::OutPort * anOutPort = aLabelNode->GetChangeNodeInGate()->GetOutPort() ;
+      if ( anOutPort ) {
+        CORBA::Any * anAny = new CORBA::Any() ;
+        *anAny <<= (long ) 1 ;
+        anOutPort->Value( anAny ) ;
+        aLabelNode->GetChangeNodeInGate()->State( SUPERV::ReadyState ) ;
+      }
       for ( j = 0 ; j < aLabelNode->GetNodeInPortsSize() ; j++ ) {
         const GraphBase::InPort * anInPort = aLabelNode->GetNodeInPort( j ) ;
         if ( anInPort->GetOutPort() ) {
-//          cdebug << aLabelNode->Name() << "(" << anInPort->PortName() << ") value : "
-//                 << anInPort->GetOutPort()->NodeName() << "(" << anInPort->GetOutPort()->PortName() << ")"
-//                 << endl ;
+          cdebug << aLabelNode->Name() << "(" << anInPort->PortName() << ") value : "
+                 << anInPort->GetOutPort()->NodeName() << "(" << anInPort->GetOutPort()->PortName() << ")"
+                 << endl ;
        }
       }
       for ( j = 0 ; j < GetNodeOutPortsSize() ; j++ ) {
@@ -1712,58 +1923,49 @@ int GraphExecutor::InNode::Successed_SuccessAction() {
         if ( !aBusParamOutPort->IsGate() ) {
           GraphBase::InPort * aBusParamChangeInPort = NULL ;
           if ( aBusParamOutPort->IsLoop() ) {
-            aBusParamChangeInPort = aLabelNode->GetChangeNodeInLoop() ;
+// For EndLoop do not copy EndLoop(DoLoop) in Loop(InLoop)
+//            aBusParamChangeInPort = aLabelNode->GetChangeNodeInLoop() ;
          }
           else {
             aBusParamChangeInPort = aLabelNode->GetChangeInPort( aBusParamOutPort->PortName() ) ;
          }
           if ( aBusParamChangeInPort ) {
             aBusParamChangeInPort->ChangeOutPort( aBusParamOutPort ) ;
-//            cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " ChangeOutPort to HeadNode "
-//                   << aLabelNode->Name() << "(" << aBusParamChangeInPort->PortName() << ") from port "
-//                   << aBusParamOutPort->PortName() << endl ;
-            if ( !aLabelNode->IsLockedDataWait() ) {
-              res = aLabelNode->SendSomeDataReady( Name() ) ;
-              if ( res ) {
-                if ( firsttoNode == NULL &&
-                     aLabelNode->ThreadNo() == pthread_self() ) {
-                  firsttoNode = aLabelNode ;
-//                  cdebug << ThreadNo() << " Successed_SuccessAction firsttoNode "
-//                         << aLabelNode->Name() << endl ;
-                }
-                else if ( firstzeroNode == NULL &&
-                          aLabelNode->ThreadNo() == 0 ) {
-                  firstzeroNode = aLabelNode ;
-               }
-                else {
-                  SomeDataNodes.push_back( aLabelNode ) ;
-//                  cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " push "
-//                         << aLabelNode->Name() << " " << SomeDataNodes.size() 
-//                         << endl ;
-               }
-             }
-           }
-            else {
-//              cdebug << ThreadNo()
-//                     << " Successed_SuccessAction Loop to HeadNode "
-//                     << aLabelNode->Name() << " with datas from " << Name() << "("
-//                     << aBusParamOutPort->PortName() << ") to port "
-//                     << aBusParamChangeInPort->PortName() << endl;
-           }
-         }
-          else {
-//            cdebug << ThreadNo() << " ERROR in Successed_SuccessAction of " << Name()
-//                   << " NO port " << aBusParamOutPort->PortName() << " in "
-//                   << aLabelNode->Name() << endl;
+            cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " ChangeOutPort to HeadNode "
+                   << aLabelNode->Name() << "(" << aBusParamChangeInPort->PortName() << ") from port "
+                   << aBusParamOutPort->PortName() << endl ;
          }
+       }
+      }
+    }
+
+    if ( aLabelNode && !aLabelNode->IsLockedDataWait() ) {
+      res = aLabelNode->SendSomeDataReady( Name() ) ;
+      if ( res ) {
+        if ( firsttoNode == NULL &&
+             aLabelNode->ThreadNo() == pthread_self() ) {
+          firsttoNode = aLabelNode ;
+          cdebug << ThreadNo() << " Successed_SuccessAction firsttoNode "
+                 << aLabelNode->Name() << endl ;
         }
+        else if ( firstzeroNode == NULL &&
+                  aLabelNode->ThreadNo() == 0 ) {
+          firstzeroNode = aLabelNode ;
+        }
+        else {
+          SomeDataNodes.push_back( aLabelNode ) ;
+          cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " push "
+                 << aLabelNode->Name() << " " << SomeDataNodes.size() 
+                 << endl ;
+       }
       }
+
       for ( j = 0 ; j < aLabelNode->GetNodeInPortsSize() ; j++ ) {
         const GraphBase::InPort * anInPort = aLabelNode->GetNodeInPort( j ) ;
         if ( anInPort->GetOutPort() ) {
-//          cdebug << aLabelNode->Name() << "(" << anInPort->PortName() << ") value : "
-//                 << anInPort->GetOutPort()->NodeName() << "(" << anInPort->GetOutPort()->PortName() << ")"
-//                 << endl ;
+          cdebug << aLabelNode->Name() << "(" << anInPort->PortName() << ") value : "
+                 << anInPort->GetOutPort()->NodeName() << "(" << anInPort->GetOutPort()->PortName() << ")"
+                 << endl ;
        }
       }
       const GraphBase::InPort * aGateInPort = aLabelNode->GetNodeInGate() ;
@@ -1777,8 +1979,8 @@ int GraphExecutor::InNode::Successed_SuccessAction() {
             if ( firsttoNode == NULL &&
                  aLabelNode->ThreadNo() == pthread_self() ) {
               firsttoNode = aLabelNode ;
-//              cdebug << ThreadNo() << " Successed_SuccessAction firsttoNode "
-//                     << aLabelNode->Name() << endl ;
+              cdebug << ThreadNo() << " Successed_SuccessAction firsttoNode "
+                     << aLabelNode->Name() << endl ;
             }
             else if ( firstzeroNode == NULL &&
                       aLabelNode->ThreadNo() == 0 ) {
@@ -1786,9 +1988,9 @@ int GraphExecutor::InNode::Successed_SuccessAction() {
            }
             else {
               SomeDataNodes.push_back( aLabelNode ) ;
-//              cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " push "
-//                     << aLabelNode->Name() << " " << SomeDataNodes.size()
-//                     << endl ;
+              cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " push "
+                     << aLabelNode->Name() << " " << SomeDataNodes.size()
+                     << endl ;
            }
          }
        }
@@ -1802,22 +2004,26 @@ int GraphExecutor::InNode::Successed_SuccessAction() {
   }
 
   else {
-//    cdebug << ThreadNo() << " Successed_SuccessAction of " << Name()
-//           << " with " << LinkedNodesSize() << " linked nodes :" ;
+    cdebug << ThreadNo() << " Successed_SuccessAction of " << Name()
+           << " with " << LinkedNodesSize() << " linked nodes :" ;
     for ( i = 0 ; i < LinkedNodesSize() ; i++ ) {
       if ( LinkedNodes( i )->IsDataFlowNode() ) {
         linkednodesnumber -= 1 ;
       }
-//      cdebug << " " << LinkedNodes( i )->Name() ;
+      cdebug << " " << LinkedNodes( i )->Name() ;
     }
-//    cdebug << endl;
+    cdebug << endl;
     for ( i = 0 ; i < LinkedNodesSize() ; i++ ) {
       bool IgnoreForEndLoop = false ;
       GraphBase::ComputingNode * aComputingNode ;
       aComputingNode = (GraphBase::ComputingNode * ) LinkedNodes( i ) ;
       toNode = (GraphExecutor::InNode *) aComputingNode->GetInNode() ;
-//      cdebug << ThreadNo() << " Successed_SuccessAction of " << Name()
-//             << " [" << i << "] " << LinkedNodes( i )->Name() << endl ;
+      cdebug << ThreadNo() << " Successed_SuccessAction of " << Name()
+             << " [" << i << "] " << LinkedNodes( i )->Name() << " toNode " << toNode << " IgnoreForEndLoop "
+             << IgnoreForEndLoop ;
+      if ( toNode ) {
+        cdebug << " " << toNode->Kind() << endl ;
+      }
       if ( toNode && !toNode->IsDataFlowNode() ) {
         if ( IsComputingNode() && toNode->IsInLineNode() ) {
           GraphBase::InPort * toGateInPort = toNode->GetChangeNodeInGate() ;
@@ -1861,7 +2067,7 @@ int GraphExecutor::InNode::Successed_SuccessAction() {
           LoopOutPort->PortStatus( DataConnected );
           LoopOutPort->State( SUPERV::ReadyState ) ;
           LoopOutPort->Done( true ) ;
-          CORBA::Any * anAny = new CORBA::Any() ;
+          CORBA::Any * anAny = new CORBA::Any() ; // InitLoop
           *anAny <<= (long ) 1 ;
           LoopOutPort->Value( anAny ) ;
           int j ;
@@ -1869,13 +2075,15 @@ int GraphExecutor::InNode::Successed_SuccessAction() {
             toNode->GetChangeNodeInPort( j )->InitialOutPort() ;
          }
         }
+        cdebug << ThreadNo() << " Successed_SuccessAction " << toNode->Name() << "->SendSomeDataReady( "
+               << Name() << " )" << endl ;
         res = toNode->SendSomeDataReady( Name() ) ;
         if ( res ) {
           if ( firsttoNode == NULL &&
                toNode->ThreadNo() == pthread_self() ) {
             firsttoNode = toNode ;
-//            cdebug << ThreadNo() << " Successed_SuccessAction firsttoNode "
-//                   << toNode->Name() << endl ;
+            cdebug << ThreadNo() << " Successed_SuccessAction firsttoNode "
+                   << toNode->Name() << endl ;
           }
           else if ( firstzeroNode == NULL &&
                     toNode->ThreadNo() == 0 ) {
@@ -1883,8 +2091,8 @@ int GraphExecutor::InNode::Successed_SuccessAction() {
          }
           else {
             SomeDataNodes.push_back( toNode ) ;
-//            cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " push "
-//                   << toNode->Name() << " " << SomeDataNodes.size() << endl ;
+            cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " push "
+                   << toNode->Name() << " " << SomeDataNodes.size() << endl ;
          }
        }
       }
@@ -1893,14 +2101,18 @@ int GraphExecutor::InNode::Successed_SuccessAction() {
 
   if ( firsttoNode == NULL && firstzeroNode ) {
     firsttoNode = firstzeroNode ;
-//    cdebug << ThreadNo()
-//           << " Successed_SuccessAction firsttoNode = firstzeroNode "
-//           << endl ;
+    cdebug << ThreadNo()
+           << " Successed_SuccessAction firsttoNode = firstzeroNode "
+           << endl ;
   }
   else if ( firsttoNode && firstzeroNode ) {
     SomeDataNodes.push_back( firstzeroNode ) ;
-//    cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " push firstzeroNode "
-//           << firstzeroNode->Name() << " " << SomeDataNodes.size() << endl ;
+    cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " push firstzeroNode "
+           << firstzeroNode->Name() << " " << SomeDataNodes.size() << endl ;
+  }
+  else {
+    cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " firsttoNode " << firsttoNode
+           << " firstzeroNode " << firstzeroNode << endl ;
   }
 
   while ( SomeDataNodes.size() ) {
@@ -1909,7 +2121,7 @@ int GraphExecutor::InNode::Successed_SuccessAction() {
 //    cdebug << pthread_self() << "/" << ThreadNo()
 //           << " Successed_SuccessAction pop "
 //           << SomeDataNodes.size() << " " << aNode->Name() << endl ;
-    if ( aNode->State() == SUPERV::DataReadyState ) {
+    if ( aNode->State() == GraphExecutor::DataReadyState ) {
       aNode->CreateNewThreadIf( true ) ;
       aNode->UnLockDataWait() ;
       res = aNode->DataUndef_AllDataReadyAction() ;
@@ -1927,13 +2139,13 @@ int GraphExecutor::InNode::Successed_SuccessAction() {
 //           << SomeDataNodes.size() << " " << firsttoNode->Name() << endl ;
     firsttoNode->CreateNewThreadIf( false ) ;
     firsttoNode->RewindStack( RewindStack() ) ;
-    if ( firsttoNode->State() == SUPERV::SuccessedState ) {
+    if ( firsttoNode->State() == GraphExecutor::SuccessedState ) {
 //      cdebug << pthread_self() << "/" << ThreadNo() << " " << Name()
 //             << " : " << firsttoNode->Name() << " "
 //             << Automaton()->StateName( firsttoNode->State() )
 //             << " --> DataWaitingState for Thread "
 //             << firsttoNode->ThreadNo() << endl ;
-      firsttoNode->State( SUPERV::DataWaitingState ) ;
+      firsttoNode->State( GraphExecutor::DataWaitingState ) ;
     }
 //    pthread_t OldT = firsttoNode->ThreadNo() ;
     firsttoNode->ThreadNo( pthread_self() ) ;
@@ -1947,7 +2159,7 @@ int GraphExecutor::InNode::Successed_SuccessAction() {
 //           << " !firsttoNode->CreateNewThreadIf() "
 //           << !firsttoNode->CreateNewThreadIf()
 //           << " " << Automaton()->StateName( firsttoNode->State() ) ;
-    if ( firsttoNode->State() == SUPERV::DataReadyState ) {
+    if ( firsttoNode->State() == GraphExecutor::DataReadyState ) {
       cdebug << endl ;
       firsttoNode->UnLockDataWait() ;
       res = firsttoNode->DataUndef_AllDataReadyAction() ;
@@ -1977,8 +2189,8 @@ int GraphExecutor::InNode::Successed_SuccessAction() {
 bool GraphExecutor::InNode::SendSomeDataReady( char * FromNodeName ) {
   bool RetVal = false ;
   if ( IsDataFlowNode() ) {
-//    cdebug << ThreadNo() << " ----> " << Name()
-//         << " send Result to graph " << Name() << endl;
+    cdebug << ThreadNo() << "InNode::SendSomeDataReady ----> " << Name()
+         << " send Result to graph " << Name() << endl;
   }
   else {
 //    cdebug << pthread_self() << "/" << ThreadNo() << " ----> " << FromNodeName
@@ -1987,20 +2199,26 @@ bool GraphExecutor::InNode::SendSomeDataReady( char * FromNodeName ) {
 //           << " CreateNewThreadIf() " << CreateNewThreadIf()
 //           << " LockedDataWait " << IsLockedDataWait() << endl;
 #if 0
-    cout << pthread_self() << "/" << ThreadNo() << " ----> " << FromNodeName
+  //cout << pthread_self() << "/" << ThreadNo() << " ----> " << FromNodeName
          << " send SomeDataReady to " << Name() << " "
          << Automaton()->StateName( State() ) 
          << " CreateNewThreadIf() " << CreateNewThreadIf()
          << " LockedDataWait " << IsLockedDataWait() << endl;
 #endif
-    if ( State() == SUPERV::SuccessedState ||
-         State() == SUPERV::SuspendedSuccessedState ||
-         State() == SUPERV::SuspendedSuccessedToReStartState ) {
+    if ( State() == GraphExecutor::SuccessedState ||
+         State() == GraphExecutor::SuspendedSuccessedState ||
+         State() == GraphExecutor::SuspendedSuccessedToReStartState ) {
 //      cdebug << ThreadNo() << " " << FromNodeName
 //             << " : " << Name() << " " << Automaton()->StateName( State() )
 //             << " --> DataWaitingState for Thread "
 //             << ThreadNo() << " " << endl ;
-      State( SUPERV::DataWaitingState ) ;
+      State( GraphExecutor::DataWaitingState ) ;
+    }
+// We begin that LoopNode if SendSomeDataReady does not come from the corresponding EndLoopNode
+    if ( IsLoopNode() && strcmp( LoopNode()->CoupledNodeName() , FromNodeName ) ) {
+      cdebug << ThreadNo() << "InNode::SendSomeDataReady " << Name() << " Set _InitLoop from "
+             << FromNodeName << endl ;
+      _InitLoop = true ;
     }
     LockDataWait() ;
     DataFromNode( FromNodeName ) ;
@@ -2024,7 +2242,7 @@ int GraphExecutor::InNode::Successed_SuspendAction() {
          << " Threads " << _OutNode->Threads() << " SuspendedThreads "
          << _OutNode->SuspendedThreads() << endl;
   _OutNode->PushEvent( this , GraphExecutor::SuspendedSuccessedEvent ,
-                       SUPERV::SuspendedSuccessedState ) ; 
+                       GraphExecutor::SuspendedSuccessedState ) ; 
   DoneAction() ;
   GraphExecutor::InNode * aReStartNode = SuspendAction() ;
   cdebug << ThreadNo() << " Successed_SuspendAction Resumed " << Name() ;
@@ -2045,7 +2263,7 @@ int GraphExecutor::InNode::Errored_SuspendAction() {
          << " Threads " << _OutNode->Threads() << " SuspendedThreads "
          << _OutNode->SuspendedThreads() << endl;
   _OutNode->PushEvent( this , GraphExecutor::SuspendedErroredEvent ,
-                       SUPERV::SuspendedErroredState ) ; 
+                       GraphExecutor::SuspendedErroredState ) ; 
   DoneAction() ;
   GraphExecutor::InNode * aReStartNode = SuspendAction() ;
   cdebug << ThreadNo() << " Errored_SuspendAction Resumed " << Name()
@@ -2064,7 +2282,7 @@ int GraphExecutor::InNode::SuspendedSuccessed_ResumeAction() {
   cdebug << ThreadNo() << " SuspendedSuccessed_ResumeAction " << Name() << endl;
 //  ResumeAction() ;
   _OutNode->PushEvent( this , GraphExecutor::ResumedSuccessedEvent ,
-                       SUPERV::ResumedSuccessedState ) ; 
+                       GraphExecutor::ResumedSuccessedState ) ; 
   SendEvent( ResumedSuccessedEvent ) ;
   return 1 ;
 }
@@ -2073,7 +2291,7 @@ int GraphExecutor::InNode::SuspendedErrored_ResumeAction() {
   cdebug << ThreadNo() << " SuspendedErrored_ResumeAction " << Name() << endl;
 //  ResumeAction() ;
   _OutNode->PushEvent( this , GraphExecutor::ResumedErroredEvent ,
-                       SUPERV::ResumedErroredState ) ; 
+                       GraphExecutor::ResumedErroredState ) ; 
   SendEvent( ResumedErroredEvent ) ;
   return 1 ;
 }
@@ -2081,7 +2299,7 @@ int GraphExecutor::InNode::SuspendedErrored_ResumeAction() {
 int GraphExecutor::InNode::Successed_KillAction() {
   KillAction() ;
   _OutNode->PushEvent( this , GraphExecutor::KilledEvent ,
-                       SUPERV::KilledSuccessedState ) ; 
+                       GraphExecutor::KilledSuccessedState ) ; 
   cdebug << ThreadNo() << " Successed_KillAction " << Name() << endl;
   return 1 ;
 }
@@ -2089,7 +2307,7 @@ int GraphExecutor::InNode::Successed_KillAction() {
 int GraphExecutor::InNode::Errored_KillAction() {
   KillAction() ;
   _OutNode->PushEvent( this , GraphExecutor::KilledEvent ,
-                       SUPERV::KilledErroredState ) ; 
+                       GraphExecutor::KilledErroredState ) ; 
   cdebug << ThreadNo() << " Errored_KillAction " << Name() << endl;
   return 1 ;
 }
@@ -2097,7 +2315,7 @@ int GraphExecutor::InNode::Errored_KillAction() {
 int GraphExecutor::InNode::Successed_StopAction() {
   StopAction() ;
   _OutNode->PushEvent( this , GraphExecutor::StoppedEvent ,
-                       SUPERV::StoppedSuccessedState ) ; 
+                       GraphExecutor::StoppedSuccessedState ) ; 
   cdebug << ThreadNo() << " Successed_StopAction " << Name() << endl;
   return 1 ;
 }
@@ -2105,7 +2323,7 @@ int GraphExecutor::InNode::Successed_StopAction() {
 int GraphExecutor::InNode::Errored_StopAction() {
   StopAction() ;
   _OutNode->PushEvent( this , GraphExecutor::StoppedEvent ,
-                       SUPERV::StoppedErroredState ) ; 
+                       GraphExecutor::StoppedErroredState ) ; 
   cdebug << ThreadNo() << " Errored_StopAction " << Name() << endl;
   return 1 ;
 }
@@ -2113,7 +2331,7 @@ int GraphExecutor::InNode::Errored_StopAction() {
 int GraphExecutor::InNode::SuspendedSuccessed_ReStartAction() {
   cdebug << ThreadNo() << " SuspendedSuccessed_ReStartAction " << Name() << endl;
   _OutNode->PushEvent( this , GraphExecutor::ReStartedEvent ,
-                       SUPERV::ReStartedState ) ;
+                       GraphExecutor::ReStartedState ) ;
   int i ;
   for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
     GetChangeNodeInPort( i )->State( SUPERV::ReadyState ) ;
@@ -2126,7 +2344,7 @@ int GraphExecutor::InNode::SuspendedSuccessed_ReStartAction() {
 int GraphExecutor::InNode::SuspendedErrored_ReStartAction() {
   cdebug << ThreadNo() << " SuspendedErrored_ReStartAction " << Name() << endl;
   _OutNode->PushEvent( this , GraphExecutor::ReStartedEvent ,
-                       SUPERV::ReStartedState ) ; 
+                       GraphExecutor::ReStartedState ) ; 
   int i ;
   for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
     GetChangeNodeInPort( i )->State( SUPERV::ReadyState ) ;
@@ -2140,8 +2358,8 @@ int GraphExecutor::InNode::SuspendedSuccessed_ReStartAndSuspendAction() {
   cdebug << ThreadNo() << " SuspendedSuccessed_ReStartAndSuspendAction " << Name()
          << endl;
   _OutNode->PushEvent( this , GraphExecutor::ReStartedAndSuspendEvent ,
-                       SUPERV::ReStartedState ) ; 
-  State( SUPERV::DataWaitingState ) ;
+                       GraphExecutor::ReStartedState ) ; 
+  State( GraphExecutor::DataWaitingState ) ;
   if ( !Suspend() ) {
     cdebug << "InNode::Suspend() Node " << Name() << endl ;
     return false ;
@@ -2160,8 +2378,8 @@ int GraphExecutor::InNode::SuspendedErrored_ReStartAndSuspendAction() {
   cdebug << ThreadNo() << " SuspendedErrored_ReStartAndSuspendAction " << Name()
          << endl;
   _OutNode->PushEvent( this , GraphExecutor::ReStartedAndSuspendEvent ,
-                       SUPERV::ReStartedState ) ; 
-  State( SUPERV::DataWaitingState ) ;
+                       GraphExecutor::ReStartedState ) ; 
+  State( GraphExecutor::DataWaitingState ) ;
   if ( !Suspend() ) {
     cdebug << "InNode::Suspend() Node " << Name() << endl ;
     return false ;
@@ -2180,6 +2398,7 @@ void GraphExecutor::InNode::InParametersSet( bool & Err ,
                                              int  nInParams ,
                                              ServicesAnyData * InParametersList ) {
   int i ;
+  cdebug << ThreadNo() << " InParametersSet " << Name() << endl ;
   for ( i = 0 ; i < nInParams ; i++ ) {
     ServicesAnyData D = InParametersList[i];
     GraphBase::InPort * anInPort = GetChangeNodeInPort(i) ;
@@ -2195,11 +2414,13 @@ void GraphExecutor::InNode::InParametersSet( bool & Err ,
         *anAny <<= (long ) 0 ;
         theOutPort->Value( anAny ) ;
       }
-      if ( !anInPort->IsDataStream() ) {
+      if ( !anInPort->IsDataStream() &&
+           !anInPort->IsDataConnected() ) {
         anInPort->State( SUPERV::WaitingState ) ;
       }
       D.Name = CORBA::string_dup( anInPort->GetServicesParameter().Parametername ) ;
-      cdebug << ThreadNo() << " ArgIn" << i << " " << anInPort->Kind() ;
+      cdebug << ThreadNo() << " ArgIn" << i << " " << anInPort->Kind()
+             << " " << anInPort->State() ;
       cdebug << "      " << D.Name << " " << anInPort->GetServicesParameter().Parametertype << " : " ;
       D.Value = *theOutPort->Value() ; // CORBA::Any
       string _Type = CORBA::string_dup( anInPort->GetServicesParameter().Parametertype ) ;
@@ -2571,7 +2792,9 @@ bool GraphExecutor::InNode::OutParametersSet( bool Err ,
   int i ;
   GraphBase::OutPort * aGateOutPort = NULL ;
   bool OrSwitch = false ;
-  if ( nOutParams ) {
+  cdebug << "OutParametersSet " << Name() << " nOutParams " << nOutParams << " NewState " << NewState << endl ;
+//  cout << "OutParametersSet " << Name() << " nOutParams " << nOutParams << " NewState " << NewState << endl ;
+  if ( nOutParams && !IsMacroNode() ) {
     GraphBase::OutPort * anOutPort ;
     for ( i = 0 ; i < nOutParams ; i++ ) {
       anOutPort = GetChangeNodeOutPort(i) ;
@@ -2690,30 +2913,47 @@ bool GraphExecutor::InNode::OutParametersSet( bool Err ,
         int j ;
         for ( j = 0 ; j < anOutPort->InPortsSize() ; j++ ) {
           bool fromGOTO = false ;
-          GraphBase::OutPort * aGOTOPort = _OutNode->Graph()->GetChangeGraphNode( anOutPort->ChangeInPorts( j )->NodeName() )->GetChangeNodeInGate()->GetOutPort() ;
-          if ( aGOTOPort ) {
-            fromGOTO = aGOTOPort->IsGOTO() ;
-         }
-          if ( anOutPort->ChangeInPorts( j )->IsEndSwitch() || fromGOTO ) {
-            cdebug << anOutPort->ChangeInPorts( j )->NodeName() << "("
-                   << anOutPort->ChangeInPorts( j )->PortName() << ","
-                   << anOutPort->ChangeInPorts( j )->Kind() << ") WILL BE changed from "
-                   << anOutPort->ChangeInPorts( j )->GetOutPort()->NodeName()
-                   << "("
-                   << anOutPort->ChangeInPorts( j )->GetOutPort()->PortName()
-                   << ") to " << anOutPort->NodeName() << "("
-                   << anOutPort->PortName() << ")" << endl ;
-            anOutPort->ChangeInPorts( j )->ChangeOutPort( anOutPort ) ;
-         }
+          const char * ToNodeName = anOutPort->ChangeInPorts( j )->NodeName() ;
+          if ( !strcmp( ToNodeName , _OutNode->Graph()->Name() ) && _OutNode->Graph()->GraphMacroLevel() != 0 ) {
+            cdebug << "OutParametersSet ToNodeName " << _OutNode->Graph()->Name() << " CoupledNode "
+                   << _OutNode->Graph()->CoupledNodeName() << _OutNode->Graph()->CoupledNode()
+                   << endl ;
+            cdebug << " GraphExecutor " << _OutNode->Graph()->CoupledNode()->GraphEditor()->Executor() << endl ;
+            _OutNode->Graph()->CoupledNode()->GraphEditor()->Executor()->OutputOfAny( _OutNode->Graph()->CoupledNodeName() ,
+                                                                            anOutPort->ChangeInPorts( j )->PortName() ,
+                                                                            *anOutPort->Value() ) ;
+         }
           else {
-            cdebug << anOutPort->ChangeInPorts( j )->NodeName() << "("
-                   << anOutPort->ChangeInPorts( j )->PortName() << ","
-                   << anOutPort->ChangeInPorts( j )->Kind() << ") NOT changed from "
-                   << anOutPort->ChangeInPorts( j )->GetOutPort()->NodeName()
-                   << "("
-                   << anOutPort->ChangeInPorts( j )->GetOutPort()->PortName()
-                   << ") to " << anOutPort->NodeName() << "("
-                   << anOutPort->PortName() << ")" << endl ;
+           GraphBase::ComputingNode * ToNode = _OutNode->Graph()->GetChangeGraphNode( ToNodeName ) ;
+            if ( ToNode ) {
+//              cout << "OutParametersSet ToNodeName " << ToNodeName << endl ;
+              cdebug << "OutParametersSet ToNodeName " << ToNodeName << " " << ToNode->Name() << endl ;
+              GraphBase::OutPort * aGOTOPort = ToNode->GetChangeNodeInGate()->GetOutPort() ;
+              if ( aGOTOPort ) {
+                fromGOTO = aGOTOPort->IsGOTO() ;
+             }
+              if ( anOutPort->ChangeInPorts( j )->IsEndSwitch() || fromGOTO ) {
+                cdebug << anOutPort->ChangeInPorts( j )->NodeName() << "("
+                       << anOutPort->ChangeInPorts( j )->PortName() << ","
+                       << anOutPort->ChangeInPorts( j )->Kind() << ") WILL BE changed from "
+                       << anOutPort->ChangeInPorts( j )->GetOutPort()->NodeName()
+                       << "("
+                       << anOutPort->ChangeInPorts( j )->GetOutPort()->PortName()
+                       << ") to " << anOutPort->NodeName() << "("
+                       << anOutPort->PortName() << ")" << endl ;
+                anOutPort->ChangeInPorts( j )->ChangeOutPort( anOutPort ) ;
+             }
+              else {
+                cdebug << anOutPort->ChangeInPorts( j )->NodeName() << "("
+                       << anOutPort->ChangeInPorts( j )->PortName() << ","
+                       << anOutPort->ChangeInPorts( j )->Kind() << ") NOT changed from "
+                       << anOutPort->ChangeInPorts( j )->GetOutPort()->NodeName()
+                       << "("
+                       << anOutPort->ChangeInPorts( j )->GetOutPort()->PortName()
+                       << ") to " << anOutPort->NodeName() << "("
+                       << anOutPort->PortName() << ")" << endl ;
+             }
+           }
          }
         }
 //#if 0