Salome HOME
Join modifications from branch OCC_debug_for_3_2_0b1
[modules/superv.git] / src / Supervision / Graph_Impl.cxx
index bfb13ce8b5c27b5f29c58dee5d30c7d2b449cf96..5eb33e4115de4dc2c3dd4e85649985eaa880fba5 100644 (file)
 using namespace std;
 #include <stdio.h>
 #include <fstream>
-#include <strstream>
+//#include <sstream>
 #include <string>
 
-#include "utilities.h"
+//#include "utilities.h"
 
-#include "Graph_Impl.hxx"
+#include "SALOME_Container_i.hxx"
+
+#include "StreamGraph_Impl.hxx"
 
 #include "DataFlowEditor_DataFlow.hxx"
 
-Graph_Impl::Graph_Impl( CORBA::ORB_ptr orb ,
-                       PortableServer::POA_ptr poa ,
-                       PortableServer::ObjectId * contId , 
-                       const char *instanceName ,
-                        const char *interfaceName ,
-                        const char *aDataFlowName ) :
-  INode_Impl(orb, poa, contId, instanceName, interfaceName, aDataFlowName) {
-//  MESSAGE("Graph_Impl::Graph_Impl activate object instanceName("
-//          << instanceName << ") interfaceName(" << interfaceName << ") --> "
-//          << hex << (void *) this << dec )
-  beginService( "Graph_Impl::Graph_Impl" );
-  _thisObj = this ;
-  _id = _poa->activate_object(_thisObj);
-  _Orb = CORBA::ORB::_duplicate(orb);
-  _Poa = poa ;
-  _ContId = contId ;
-  _ExecNumber = 0 ;
+extern GraphExecutor::FiniteStateMachine * theAutomaton ;
 
-  string dbgfile = "/tmp/" ;
-  dbgfile += instanceName ;
-  dbgfile += "_" ;
+static void CreateEditor( CORBA::ORB_ptr orb ,
+                         const char *instanceName ,
+                          const char *aDataFlowName ,
+                          const SUPERV::KindOfNode aKindOfNode ,
+                          string & dbgfile ,
+                          GraphEditor::DataFlow **  aDataFlowEditor ) {
+  bool aXmlFile = false ;
   int lenname = strlen( aDataFlowName ) ;
   char * theDataFlowName = new char [ lenname+1 ] ;
   strcpy( theDataFlowName , aDataFlowName ) ;
@@ -66,36 +56,177 @@ Graph_Impl::Graph_Impl( CORBA::ORB_ptr orb ,
     if ( lenname > 4 && !strcmp( &aDataFlowName[ lenname - 4 ] , ".xml" ) ) {
       strncpy( theDataFlowName , &aDataFlowName[ 0 ] , lenname-4 ) ;
       theDataFlowName[ lenname-4 ] = '\0' ;
+      aXmlFile = true ;
       int i ;
       for ( i = lenname - 5 ; i >= 0 ; i-- ) {
         if ( aDataFlowName[ i ] == '/' ) {
           strncpy( theDataFlowName , &aDataFlowName[ i + 1 ] , lenname-5-i ) ;
           theDataFlowName[ lenname-5-i ] = '\0' ;
           break ;
-       }
+        }
       }
     }
     else {
       strcpy( theDataFlowName , &aDataFlowName[ 0 ] ) ;
     }
-    dbgfile += theDataFlowName ;
   }
-  dbgfile += ".log" ;
-  _DebugFileName = new char[ strlen( dbgfile.c_str() )+1 ] ;
-  strcpy( _DebugFileName , dbgfile.c_str() ) ;
+  
+  string theDataFlowInstanceName = theDataFlowName ;
+
+  // asv : 16.11.04 : creation of log file in /tmp/logs/$USER dir. 
+  // "/tmp/logs/$USER" was created by  runSalome.py -> orbmodule.py.
+  dbgfile = "/tmp/logs/" ;
+  dbgfile += getenv( "USER" ) ;
+  dbgfile += "/" ;
+  dbgfile += instanceName ;
+  dbgfile += "_" ;
+  dbgfile += theDataFlowInstanceName ;
+  dbgfile = dbgfile + "_" + theAutomaton->DbgFileNumber() + ".log" ;
+  FILE* f = fopen ( dbgfile.c_str(), "a" );
+  if ( f ) { // check if file can be opened for writing
+    fclose( f );
+  } 
+  else { // if file can't be opened - use a guaranteed temp file name
+    char* aTempNam = tempnam( NULL, NULL );
+    dbgfile = aTempNam;
+    free ( aTempNam );
+  }
+
+  SALOME_NamingService * NamingService = new SALOME_NamingService( orb ) ;
+  *aDataFlowEditor = new GraphEditor::DataFlow( orb , NamingService ,
+                                                theDataFlowInstanceName.c_str() , dbgfile.c_str() ,
+                                                aKindOfNode ) ;
+  MESSAGE( "CreateEditor " << theDataFlowName << " uniquely named " << theDataFlowInstanceName << " created with "
+           << dbgfile.c_str() ) ;
+
+  delete [] theDataFlowName ;
+}
+
+static void CreateExecutor( CORBA::ORB_ptr orb ,
+                         const char *instanceName ,
+                          const char *aDataFlowName ,
+                          const SUPERV::KindOfNode aKindOfNode ,
+                          string & dbgfile ,
+                          GraphExecutor::DataFlow **  aDataFlowExecutor ) {
+  int lenname = strlen( aDataFlowName ) ;
+  char * theDataFlowName = new char [ lenname+1 ] ;
+  strcpy( theDataFlowName , aDataFlowName ) ;
+  if ( aDataFlowName ) {
+    strcpy( theDataFlowName , &aDataFlowName[ 0 ] ) ;
+  }
+
+  string theDataFlowInstanceName = theDataFlowName ;
+
+  // asv : 16.11.04 : creation of log file in /tmp/logs/$USER dir. 
+  // "/tmp/logs/$USER" was created by  runSalome.py -> orbmodule.py.
+  dbgfile = "/tmp/logs/" ;
+  dbgfile += getenv( "USER" ) ;
+  dbgfile += "/" ;
+  dbgfile += instanceName ;
+  dbgfile += "_" ;
+  dbgfile += theDataFlowInstanceName ;
+  dbgfile = dbgfile + "_" + theAutomaton->DbgFileNumber() ;
+  ostringstream astr ;
+  astr << theAutomaton->ExecNumber() ;
+  dbgfile += astr.str() ;
+  dbgfile += string( "_Exec.log" ) ;
+  FILE* f = fopen ( dbgfile.c_str(), "a" );
+  if ( f ) { // check if file can be opened for writing
+    fclose( f );
+  } 
+  else { // if file can't be opened - use a guaranteed temp file name
+    char* aTempNam = tempnam( NULL, NULL );
+    dbgfile = aTempNam;
+    free ( aTempNam );
+  }
+
+  SALOME_NamingService * NamingService = new SALOME_NamingService( orb ) ;
+  *aDataFlowExecutor = new GraphExecutor::DataFlow( orb , NamingService ,
+                                                    theDataFlowInstanceName.c_str() , dbgfile.c_str() ,
+                                                    aKindOfNode ) ;
+
+  MESSAGE( "CreateExecutor " << theDataFlowName << " " << theDataFlowInstanceName << " created with "
+           << dbgfile.c_str() ) ;
 
-  _NamingService = new SALOME_NamingService(orb);
-//  _DataFlowEditor = new SALOME_DataFlowEditor_impl( NS ) ;
-  GraphEditor::DataFlow *  aDataFlowEditor = new GraphEditor::DataFlow(
-                                               _Orb , _NamingService ,
-                                               theDataFlowName ,
-                                               _DebugFileName ) ;
-  DataFlowEditor( aDataFlowEditor ) ;
-  DataFlowEditor()->SetObjImpl( this ) ;
-  _DataFlowExecutor = NULL ;
-//  _DataFlowDataNode = DataFlowEditor() ;
   delete [] theDataFlowName ;
-  endService( "Graph_Impl::Graph_Impl" );
+}
+
+Graph_Impl::Graph_Impl( CORBA::ORB_ptr orb ,
+                       PortableServer::POA_ptr poa ,
+                       PortableServer::ObjectId * contId , 
+                       const char *instanceName ,
+                        const char *interfaceName ,
+                        const char *aDataFlowName ,
+                        const SUPERV::KindOfNode aKindOfNode ) :
+  GNode_Impl( orb , poa , contId , instanceName , interfaceName , aDataFlowName , aKindOfNode ) {
+//  MESSAGE("Graph_Impl::Graph_Impl activate object instanceName("
+//          << instanceName << ") interfaceName(" << interfaceName << ") --> "
+//          << hex << (void *) this << dec )
+//  beginService( "Graph_Impl::Graph_Impl" );
+  _Orb = CORBA::ORB::_duplicate(orb);
+  _Poa = poa ;
+  _ContId = contId ;
+  _DebugFileName = NULL ;
+  if ( aKindOfNode == SUPERV::DataFlowGraph || aKindOfNode == SUPERV::MacroNode ) {
+//    MESSAGE( "Graph_Impl::Graph_Impl _poa->activate_object" );
+    _thisObj = this ;
+    _id = _poa->activate_object(_thisObj);
+  }
+  else {
+//    MESSAGE( "Graph_Impl::Graph_Impl NO _poa->activate_object " );
+  }
+
+  if ( aKindOfNode == SUPERV::DataFlowGraph || aKindOfNode == SUPERV::DataStreamGraph ) {
+    string dbgfile ;
+    GraphEditor::DataFlow * aDataFlowEditor ;
+    CreateEditor( orb , instanceName , aDataFlowName , aKindOfNode ,
+                  dbgfile , &aDataFlowEditor ) ;
+
+    if ( _DebugFileName ) {
+      delete [] _DebugFileName ;
+    }
+    _DebugFileName = new char[ strlen( dbgfile.c_str() )+1 ] ;
+    strcpy( _DebugFileName , dbgfile.c_str() ) ;
+
+    _NamingService = new SALOME_NamingService( orb ) ;
+    DataFlowEditor( aDataFlowEditor ) ;
+    DataFlowEditor()->Graph()->GraphEditor( aDataFlowEditor ) ;
+    DataFlowEditor()->Graph()->SetObjImpl( this ) ;
+  }
+  pthread_mutex_init( &_MutexExecutorWait , NULL ) ;
+//  DataFlowExecutor( NULL ) ;
+//  endService( "Graph_Impl::Graph_Impl" );
+}
+
+Graph_Impl::Graph_Impl( CORBA::ORB_ptr orb ,
+                       PortableServer::POA_ptr poa ,
+                       PortableServer::ObjectId * contId , 
+                       const char *instanceName ,
+                        const char *interfaceName ,
+                        GraphEditor::DataFlow * aDataFlowEditor ,
+                        GraphEditor::InNode * aDataFlowNode ) :
+  GNode_Impl( orb , poa , contId , instanceName , interfaceName , aDataFlowEditor , aDataFlowNode ) {
+//  beginService( "Graph_Impl::Graph_Impl" );
+//  MESSAGE( aDataFlowEditor->Graph()->Name() << " " );
+  if ( aDataFlowEditor->Graph()->IsDataFlowNode() ||
+       ( aDataFlowNode && aDataFlowNode->IsMacroNode() ) ) {
+//    MESSAGE( "Graph_Impl::Graph_Impl _poa->activate_object" );
+    _thisObj = this ;
+    _id = _poa->activate_object(_thisObj);
+  }
+  else {
+//    MESSAGE( "Graph_Impl::Graph_Impl NO _poa->activate_object " );
+  }
+  _Orb = CORBA::ORB::_duplicate(orb);
+  _Poa = poa ;
+  _ContId = contId ;
+  _DebugFileName = NULL ;
+  DataFlowEditor( aDataFlowEditor ) ;
+  DataFlowEditor()->Graph()->GraphEditor( aDataFlowEditor ) ;
+  DataFlowEditor()->Graph()->SetObjImpl( this ) ;
+  pthread_mutex_init( &_MutexExecutorWait , NULL ) ;
+//  DataFlowExecutor( NULL ) ;
+//  endService( "Graph_Impl::Graph_Impl" );  
 }
 
 Graph_Impl::Graph_Impl() {
@@ -108,15 +239,33 @@ Graph_Impl::~Graph_Impl() {
 
 void Graph_Impl::destroy() {
   beginService( "Graph_Impl::destroy" );
+  if ( DataFlowNode() && DataFlowNode()->ComputingNode()->IsMacroNode() ) {
+    SUPERV::Graph_var aGraph = DataFlowNode()->GOTONode()->MacroObject() ;
+    GNode_Impl::Delete() ;
+    if ( !CORBA::is_nil( aGraph ) ) {
+      aGraph->destroy() ;
+    }
+  }
+  else {
+    SUPERV::Graph_var aGraph = DataFlowEditor()->Graph()->MacroObject() ;
+    GNode_Impl::Delete() ;
+    if ( !CORBA::is_nil( aGraph ) ) {
+      aGraph->destroy() ;
+    }
+  }
   _poa->deactivate_object(*_id) ;
-  CORBA::release(_poa) ;
+//  CORBA::release(_poa) ;
   delete(_id) ;
-  _thisObj->_remove_ref();
+//  _thisObj->_remove_ref();
   endService( "Graph_Impl::destroy" );
 }
 
+
 char* Graph_Impl::getIOR() {
-  if (CORBA::is_nil(myServant)) {
+  if ( IsMacro() ) {
+    return CORBA::string_dup( NULLSTRING ) ;
+  }
+  else if ( CORBA::is_nil( myServant ) ) {
     PortableServer::ObjectId* id = getId();
     CORBA::Object_var obj;
     obj = _poa->id_to_reference(*id);
@@ -127,17 +276,18 @@ char* Graph_Impl::getIOR() {
 
 SUPERV::Graph_ptr Graph_Impl::Copy() {
   beginService( "Graph_Impl::Copy" );
-  Graph_Impl * myGraph ;
-  myGraph = new Graph_Impl( _Orb , _Poa, _ContId,
-                            instanceName() , interfaceName() ,
-                            Name() ) ;
-  PortableServer::ObjectId * id = myGraph->getId() ;
-  CORBA::Object_var obj = _poa->id_to_reference(*id);
-  SUPERV::Graph_var iobject ;
-  iobject = SUPERV::Graph::_narrow(obj) ;
-//  GraphBase::SGraph * aSGraph = aGraph->GetGraph() ;
-  GraphBase::SGraph * aSGraph = GetGraph() ;
-  myGraph->LoadGraph( aSGraph ) ;
+  SUPERV::Graph_var iobject = SUPERV::Graph::_nil() ;
+  if ( !IsMacro() ) {
+    Graph_Impl * myGraph ;
+    myGraph = new Graph_Impl( _Orb , _Poa, _ContId,
+                              instanceName() , interfaceName() ,
+                              DataFlowEditor()->Graph()->Name() , SUPERV::DataFlowGraph ) ;
+    PortableServer::ObjectId * id = myGraph->getId() ;
+    CORBA::Object_var obj = _poa->id_to_reference(*id);
+    iobject = SUPERV::Graph::_narrow(obj) ;
+    GraphBase::ListOfSGraphs * aListOfSGraphs = GetGraphs() ;
+    myGraph->LoadGraphs( aListOfSGraphs ) ;
+  }
   endService( "Graph_Impl::Copy" );
   return SUPERV::Graph::_duplicate(iobject) ;
 }
@@ -146,119 +296,96 @@ void Graph_Impl::ReadOnly() {
   DataFlowEditor()->ReadOnly() ;
 }
 
-SUPERV::INode_ptr Graph_Impl::GetNode() {
-//  beginService( "Graph_Impl::GetNode" );
+SUPERV::INode_ptr Graph_Impl::Node() {
+//  beginService( "Graph_Impl::Node" );
   PortableServer::ObjectId * id = getId() ;
   CORBA::Object_var obj = _poa->id_to_reference(*id);
   SUPERV::Graph_var iobject ;
   iobject = SUPERV::Graph::_narrow(obj) ;
-//  endService( "Graph_Impl::GetNode" );
+//  endService( "Graph_Impl::Node" );
   return SUPERV::Graph::_duplicate(iobject) ;
 }
 
-GraphBase::SGraph * Graph_Impl::GetGraph() {
-  return DataFlowEditor()->GetDataFlow() ;
-}
-
-#if 0
-char * Graph_Impl::DataFlowInfo() {
-  beginService( "Graph_Impl::DataFlowInfo" );
-  char * RetVal = DataFlowEditor()->DataFlowInfo() ;
-  endService( "Graph_Impl::DataFlowInfo" );
-  return CORBA::string_dup( RetVal ) ;
-}
-
-char * Graph_Impl::DataNodeInfo() {
-  beginService( "Graph_Impl::DataNodeInfo" );
-  char * RetVal = DataFlowEditor()->DataNodeInfo() ;
-  endService( "Graph_Impl::DataNodeInfo" );
-  return CORBA::string_dup( RetVal ) ;
-}
-
-char * Graph_Impl::NodeInfo( const char * aNodeName ) {
-  beginService( "Graph_Impl::NodeInfo" );
-  char * RetVal = DataFlowEditor()->NodeInfo( aNodeName ) ;
-  endService( "Graph_Impl::NodeInfo" );
-  return CORBA::string_dup( RetVal ) ;
+GraphBase::ListOfSGraphs * Graph_Impl::GetGraphs() {
+  return DataFlowEditor()->GetDataFlows() ;
 }
-#endif
 
-bool Graph_Impl::LoadGraph(const GraphBase::SGraph * aDataFlow ) {
-//  beginService( "Graph_Impl::LoadGraph" );
+bool Graph_Impl::LoadGraphs( GraphBase::ListOfSGraphs * aListOfDataFlows ) {
+  beginService( "Graph_Impl::LoadGraphs" );
   bool RetVal = false ;
   if ( DataFlowEditor()->IsEditing() ) {
-    RetVal = DataFlowEditor()->LoadDataFlow( aDataFlow ) ;
+//    RetVal = DataFlowEditor()->LoadDataFlows( aListOfDataFlows ) ;
+    if ( CORBA::is_nil( LoadDataFlows( DataFlowEditor() , aListOfDataFlows , 0 ) ) ) {
+      RetVal = false ;
+    }
   }
-//  endService( "Graph_Impl::LoadGraph" );
+  endService( "Graph_Impl::LoadGraphs" );
   return RetVal ;
 }
 
 bool Graph_Impl::Import(const char * aXmlFile ) {
-//  beginService( "Graph_Impl::Import" );
+  beginService( "Graph_Impl::Import" );
   bool RetVal = false ;
-  if ( DataFlowEditor()->IsEditing() ) {
-    RetVal = DataFlowEditor()->LoadXml( aXmlFile ) ;
+  if ( DataFlowEditor()->IsEditing() && !IsMacro() ) {
+    GraphBase::ListOfSGraphs aListOfDataFlows ;
+    RetVal = DataFlowEditor()->LoadXml( aXmlFile , aListOfDataFlows ) ;
+    if ( RetVal && aXmlFile != NULL ) {
+//      RetVal = DataFlowEditor()->LoadDataFlows( &aListOfDataFlows ) ;
+      if ( CORBA::is_nil( LoadDataFlows( DataFlowEditor() , &aListOfDataFlows , 0 ) ) ) {
+        RetVal = false ;
+      }
+    }
   }
-//  endService( "Graph_Impl::Import" );
+  endService( "Graph_Impl::Import" );
   return RetVal ;
 }
 
 bool Graph_Impl::Export(const char * anXmlFile ) {
-//  beginService( "Graph_Impl::Export" );
-  char * aFile = new char [ strlen( anXmlFile ) + 5 ] ;
-  strcpy( aFile , anXmlFile ) ;
-  int len = strlen( aFile ) ;
-  if ( !strcmp( &aFile[ len - 4 ] , ".xml" ) ) {
-  }
-  else if ( !strcmp( &aFile[ len - 3 ] , ".py" ) ) {
-    strcpy( &aFile[ len - 3 ] , ".xml" ) ;
-    len = strlen( aFile ) ;
-  }
-  else {
-    strcat( aFile , ".xml" ) ;
-    len = strlen( aFile ) ;
-  }
-  bool RetVal = DataFlowEditor()->SaveXml( aFile ) ;
-  if ( RetVal ) {
-    strcpy( &aFile[ len - 4 ] , ".py" ) ;
-    RetVal = DataFlowEditor()->SavePy( aFile ) ;
+  beginService( "Graph_Impl::Export" );
+  bool RetVal = false ;
+  if ( !IsMacro() ) {
+    char * aFile = new char [ strlen( anXmlFile ) + 5 ] ;
+    strcpy( aFile , anXmlFile ) ;
+    int len = strlen( aFile ) ;
+    if ( !strcmp( &aFile[ len - 4 ] , ".xml" ) ) {
+    }
+    else if ( !strcmp( &aFile[ len - 3 ] , ".py" ) ) {
+      strcpy( &aFile[ len - 3 ] , ".xml" ) ;
+      len = strlen( aFile ) ;
+    }
+    else {
+      strcat( aFile , ".xml" ) ;
+      len = strlen( aFile ) ;
+    }
+    RetVal = DataFlowEditor()->SaveXml( aFile ) ;
+    if ( RetVal ) {
+      strcpy( &aFile[ len - 4 ] , ".py" ) ;
+      RetVal = DataFlowEditor()->SavePy( aFile ) ;
+    }
+    delete [] aFile ;
   }
-  delete [] aFile ;
-//  endService( "Graph_Impl::Export" );
+  endService( "Graph_Impl::Export" );
   return RetVal ;
 }
 
-#if 0
-GraphBase::ListOfNodes * Graph_Impl::GetNodes() {
-//  beginService( "Graph_Impl::GetNodes" );
-  GraphBase::ListOfNodes * RetVal = DataFlowEditor()->GetNodes() ;
-//  endService( "Graph_Impl::GetNodes" );
-  return RetVal ;
-}
-GraphBase::ListOfLinks * Graph_Impl::GetLinks() {
-//  beginService( "Graph_Impl::GetLinks" );
-  GraphBase::ListOfLinks * RetVal = DataFlowEditor()->GetLinks() ;
-//  endService( "Graph_Impl::GetLinks" );
-  return RetVal ;
-}
-GraphBase::ListOfLinks * Graph_Impl::GetDatas() {
-//  beginService( "Graph_Impl::GetDatas" );
-  GraphBase::ListOfLinks * RetVal = DataFlowEditor()->GetDatas() ;
-//  endService( "Graph_Impl::GetDatas" );
-  return RetVal ;
+char *  Graph_Impl::SavePY( bool importSuperV ) {
+  beginService( "Graph_Impl::SavePY" );
+  ostringstream fstring ;
+  bool RetVal ;
+  RetVal = DataFlowEditor()->SavePY( fstring , importSuperV ) ;
+  fstring  << ends ;
+  endService( "Graph_Impl::SavePY" );
+  return CORBA::string_dup( fstring.str().c_str() );
 }
-#endif
-
-SUPERV::CNode_ptr Graph_Impl::CNode(
-                         const SALOME_ModuleCatalog::Service &NodeService ) {
+SUPERV::CNode_ptr Graph_Impl::CNode( const SALOME_ModuleCatalog::Service &NodeService ) {
   beginService( "Graph_Impl::CNode" );
   SUPERV::CNode_var iobject = SUPERV::CNode::_nil() ;
-  if ( DataFlowEditor()->IsEditing() && !DataFlowEditor()->IsReadOnly() ) {
+  if ( DataFlowEditor()->IsEditing() && !DataFlowEditor()->IsReadOnly() && !IsMacro() ) {
     CNode_Impl * myNode = new CNode_Impl( _Orb , _Poa , _ContId ,
                                           instanceName() , interfaceName() ,
                                           DataFlowEditor() ,
-                                          NodeService , (char * ) NULL ,
-                                          SUPERV::ComputingNode , (char * ) NULL ) ;
+                                          NodeService , NULLSTRING ,
+                                          SUPERV::ComputingNode , NULLSTRING ) ;
     if ( myNode->DataFlowNode() ) {
       PortableServer::ObjectId * id = myNode->getId() ;
       CORBA::Object_var obj = _poa->id_to_reference(*id);
@@ -266,23 +393,27 @@ SUPERV::CNode_ptr Graph_Impl::CNode(
       myNode->SetObjRef( SUPERV::CNode::_duplicate( iobject ) ) ;
     }
   }
+  DataFlowEditor()->UnValid() ;
   endService( "Graph_Impl::CNode" );
   return SUPERV::CNode::_duplicate( iobject ) ;
 }
 
-SUPERV::FNode_ptr Graph_Impl::FNode(
-                        const char * NodeComponentName ,
-                         const char * NodeInterfaceName ,
-                         const SALOME_ModuleCatalog::Service &NodeService ) {
-  beginService( "Graph_Impl::Node" );
+SUPERV::FNode_ptr Graph_Impl::FNode( const char * NodeComponentName ,
+                                     const char * NodeInterfaceName ,
+                                     const SALOME_ModuleCatalog::Service &NodeService ,
+                                    bool isCimpl ) {
+  beginService( "Graph_Impl::FNode" );
   SUPERV::FNode_var iobject = SUPERV::FNode::_nil() ;
-  if ( DataFlowEditor()->IsEditing() && !DataFlowEditor()->IsReadOnly() ) {
+  if ( DataFlowEditor()->IsEditing() && !DataFlowEditor()->IsReadOnly() && !IsMacro() ) {
     FNode_Impl * myNode = new FNode_Impl( _Orb , _Poa , _ContId ,
                                           instanceName() , interfaceName() ,
                                           DataFlowEditor() ,
                                           NodeService ,
                                           NodeComponentName ,
-                                          NodeInterfaceName ) ;
+                                          NodeInterfaceName ,
+                                         NULLSTRING ,
+                                         SUPERV::FactoryNode ,
+                                         isCimpl ) ;
     if ( myNode->DataFlowNode() ) {
       PortableServer::ObjectId * id = myNode->getId() ;
       CORBA::Object_var obj = _poa->id_to_reference(*id);
@@ -290,7 +421,8 @@ SUPERV::FNode_ptr Graph_Impl::FNode(
       myNode->SetObjRef( SUPERV::FNode::_duplicate( iobject ) ) ;
     }
   }
-  endService( "Graph_Impl::Node" );
+  DataFlowEditor()->UnValid() ;
+  endService( "Graph_Impl::FNode" );
   return SUPERV::FNode::_duplicate( iobject ) ;
 }
 
@@ -298,7 +430,7 @@ SUPERV::INode_ptr Graph_Impl::INode( const char * FuncName ,
                                      const SUPERV::ListOfStrings & PythonFuntion ) {
   beginService( "Graph_Impl::INode" );
   SUPERV::INode_var iobject = SUPERV::INode::_nil() ;
-  if ( DataFlowEditor()->IsEditing() && !DataFlowEditor()->IsReadOnly() ) {
+  if ( DataFlowEditor()->IsEditing() && !DataFlowEditor()->IsReadOnly() && !IsMacro() ) {
     INode_Impl * myNode = new INode_Impl( _Orb , _Poa , _ContId ,
                                           instanceName() , interfaceName() ,
                                           DataFlowEditor() ,
@@ -321,7 +453,7 @@ SUPERV::GNode_ptr Graph_Impl::GNode( const char * FuncName ,
                                      const char * anInLineNode ) {
   beginService( "Graph_Impl::GNode" );
   SUPERV::GNode_var iobject = SUPERV::GNode::_nil() ;
-  if ( DataFlowEditor()->IsEditing() && !DataFlowEditor()->IsReadOnly() ) {
+  if ( DataFlowEditor()->IsEditing() && !DataFlowEditor()->IsReadOnly() && !IsMacro() ) {
     GNode_Impl * myNode = new GNode_Impl( _Orb , _Poa , _ContId ,
                                           instanceName() , interfaceName() ,
                                           DataFlowEditor() ,
@@ -333,7 +465,7 @@ SUPERV::GNode_ptr Graph_Impl::GNode( const char * FuncName ,
       iobject = SUPERV::GNode::_narrow(obj) ;
       myNode->SetObjRef( SUPERV::GNode::_duplicate( iobject ) ) ;
       if ( strlen( anInLineNode ) ) {
-        GraphBase::InLineNode * CoupledINode = (GraphBase::InLineNode * ) DataFlowEditor()->GetGraphNode( anInLineNode ) ;
+        GraphBase::InLineNode * CoupledINode = (GraphBase::InLineNode * ) DataFlowEditor()->Graph()->GetGraphNode( anInLineNode ) ;
         if ( anInLineNode ) {
           myNode->SetCoupled( anInLineNode ) ;
           Link( myNode->Port( "OutGate" ) , CoupledINode->ObjRef()->Port( "InGate" ) ) ;
@@ -341,22 +473,22 @@ SUPERV::GNode_ptr Graph_Impl::GNode( const char * FuncName ,
       }
     }
   }
+  DataFlowEditor()->UnValid() ;
   endService( "Graph_Impl::GNode" );
   return SUPERV::GNode::_duplicate( iobject ) ;
 }
 
-SUPERV::LNode_ptr Graph_Impl::LNode(
-                          const char * InitName ,
-                          const SUPERV::ListOfStrings & InitFunction ,
-                          const char * MoreName ,
-                          const SUPERV::ListOfStrings & MoreFunction ,
-                          const char * NextName ,
-                          const SUPERV::ListOfStrings & NextFunction ,
-                          SUPERV::INode_out anEndOfLoop ) {
+SUPERV::LNode_ptr Graph_Impl::LNode( const char * InitName ,
+                                     const SUPERV::ListOfStrings & InitFunction ,
+                                     const char * MoreName ,
+                                     const SUPERV::ListOfStrings & MoreFunction ,
+                                     const char * NextName ,
+                                     const SUPERV::ListOfStrings & NextFunction ,
+                                     SUPERV::INode_out anEndOfLoop ) {
   beginService( "Graph_Impl::LNode" );
   SUPERV::LNode_var iobject = SUPERV::LNode::_nil() ;
   SUPERV::ELNode_var iendobject = SUPERV::ELNode::_nil() ;
-  if ( DataFlowEditor()->IsEditing() && !DataFlowEditor()->IsReadOnly() ) {
+  if ( DataFlowEditor()->IsEditing() && !DataFlowEditor()->IsReadOnly() && !IsMacro() ) {
     GraphBase::ListOfFuncName FuncNameList ;
     FuncNameList.resize(3) ;
     FuncNameList[0] = InitName ;
@@ -403,23 +535,25 @@ SUPERV::LNode_ptr Graph_Impl::LNode(
       myEndNode->SetObjRef( SUPERV::ELNode::_duplicate( iendobject ) ) ;
       myNode->SetCoupled( myEndNode->BaseNode()->Name() ) ;
       myEndNode->SetCoupled( myNode->BaseNode()->Name() ) ;
-      Link( myNode->Port( "DoLoop" ) , myEndNode->Port( "DoLoop" ) ) ;
-      Link( myEndNode->Port( "DoLoop" ) , myNode->Port( "InitLoop" ) ) ;
+//JR 25.01.2005  That links are already done in SetCoupled above ...
+//      Link( myNode->Port( "DoLoop" ) , myEndNode->Port( "DoLoop" ) ) ;
+//      Link( myEndNode->Port( "DoLoop" ) , myNode->Port( "InitLoop" ) ) ;
+//      Link( myEndNode->Port( "DoLoop" ) , myNode->Port( "DoLoop" ) ) ;
     }
   }
   anEndOfLoop = SUPERV::ELNode::_duplicate( iendobject ) ;
+  DataFlowEditor()->UnValid() ;
   endService( "Graph_Impl::LNode" );
   return SUPERV::LNode::_duplicate( iobject ) ;
 }
 
-SUPERV::SNode_ptr Graph_Impl::SNode(
-                          const char * FuncName ,
-                          const SUPERV::ListOfStrings & PythonFunction ,
-                          SUPERV::INode_out anEndOfSwitch ) {
+SUPERV::SNode_ptr Graph_Impl::SNode( const char * FuncName ,
+                                     const SUPERV::ListOfStrings & PythonFunction ,
+                                     SUPERV::INode_out anEndOfSwitch ) {
   beginService( "Graph_Impl::SNode" );
   SUPERV::SNode_var iobject = SUPERV::SNode::_nil() ;
   SUPERV::ESNode_var iendobject = SUPERV::ESNode::_nil() ;
-  if ( DataFlowEditor()->IsEditing() && !DataFlowEditor()->IsReadOnly() ) {
+  if ( DataFlowEditor()->IsEditing() && !DataFlowEditor()->IsReadOnly() && !IsMacro() ) {
     SNode_Impl * myNode = new SNode_Impl( _Orb , _Poa , _ContId ,
                                           instanceName() , interfaceName() ,
                                           DataFlowEditor() ,
@@ -438,17 +572,17 @@ SUPERV::SNode_ptr Graph_Impl::SNode(
       else {
         anEndName += "Switch" ;
       }
-      cout << "Graph_Impl::SNode anEndName " << (void *) FuncName << " " << FuncName
-           << " " << strlen(FuncName) << " " << (void *) anEndName.c_str() << " "
-           << anEndName.c_str() << endl ;
+//      cout << "Graph_Impl::SNode anEndName " << (void *) FuncName << " " << FuncName
+//           << " " << strlen(FuncName) << " " << (void *) anEndName.c_str() << " "
+//           << anEndName.c_str() << endl ;
       ESNode_Impl * myEndNode = new ESNode_Impl( _Orb , _Poa , _ContId ,
                                                instanceName() , interfaceName() ,
                                                DataFlowEditor() ,
                                                anEndName.c_str() ,
                                                SUPERV::EndSwitchNode ) ;
-      cout << "Graph_Impl::SNode returned anEndName " << (void *) FuncName << " "
-           << FuncName << " " << strlen(FuncName) << " " << (void *) anEndName.c_str()
-           << " " << anEndName.c_str() << endl ;
+//      cout << "Graph_Impl::SNode returned anEndName " << (void *) FuncName << " "
+//           << FuncName << " " << strlen(FuncName) << " " << (void *) anEndName.c_str()
+//           << " " << anEndName.c_str() << endl ;
       PortableServer::ObjectId * endid = myEndNode->getId() ;
       CORBA::Object_var endobj = _poa->id_to_reference(*endid);
       iendobject = SUPERV::ESNode::_narrow(endobj) ;
@@ -462,13 +596,526 @@ SUPERV::SNode_ptr Graph_Impl::SNode(
     }
   }
   anEndOfSwitch = SUPERV::ESNode::_duplicate( iendobject ) ;
+  DataFlowEditor()->UnValid() ;
   endService( "Graph_Impl::SNode" );
   return SUPERV::SNode::_duplicate( iobject ) ;
 }
 
+// WARNING : THIS IS COMPLICATED :
+SUPERV::Graph_var Graph_Impl::LoadDataFlows( GraphEditor::DataFlow * aDataFlowEditor ,
+                                             GraphBase::ListOfSGraphs * aListOfDataFlows ,
+                                             int index ) {
+  beginService( "Graph_Impl::EditorLoadDataFlows" ) ;
+  MESSAGE("Graph_Impl::LoadDataFlows index " << index << " " << (*aListOfDataFlows)[index].Info.theName.c_str() ) ;
+
+  SUPERV::Graph_var iobject = SUPERV::Graph::_nil() ;
+// That method is recursive :
+// At first we load the supergraph with index = 0 :
+// (After we load the graph corresponding to each MacroNode :)
+  if ( !aDataFlowEditor->LoadDataFlow( &(*aListOfDataFlows)[ index ] ) ) {
+    MESSAGE("Graph_Impl::LoadDataFlows failed " << (*aListOfDataFlows)[index].Info.theName.c_str() ) ;
+    return SUPERV::Graph::_duplicate( iobject ) ;
+  }
+// That graph is not a StreamGraph :
+  else if ( !aDataFlowEditor->Graph()->HasDataStream() ) {
+    aDataFlowEditor->Graph()->Kind( SUPERV::DataFlowGraph ) ;
+//    aDataFlowEditor->Graph()->SetGraphEditor( aDataFlowEditor ) ;
+    Graph_Impl * myGraph ;
+// We create a Graph ObjRef for that graph
+    myGraph = new Graph_Impl( _Orb , _Poa, _ContId,
+                              instanceName() , interfaceName() ,
+                              aDataFlowEditor , NULL ) ;
+    PortableServer::ObjectId * id = myGraph->getId() ;
+    CORBA::Object_var obj = _poa->id_to_reference(*id) ;
+    iobject = SUPERV::Graph::_narrow( obj ) ;
+    myGraph->SetObjRef( SUPERV::Graph::_duplicate( iobject ) ) ;
+    myGraph->SetObjImpl( (CNode_Impl * ) myGraph ) ;
+    GraphBase::Graph * aGraph = myGraph->DataFlowEditor()->Graph() ;
+    int i ;
+
+// asv: set Editor for the graph itself and for all its macro nodes
+    aGraph->GraphEditor( aDataFlowEditor );
+
+// For the supergraph or each graph of MacroNodes we search MacroNodes recursively :
+    for ( i = 0 ; i < aGraph->GraphNodesSize() ; i++ ) {
+      if ( aGraph->GraphNodes( i )->IsMacroNode() ) {
+        GraphBase::GOTONode * aMacroNode = (GraphBase::GOTONode * ) aGraph->GraphNodes( i ) ;
+
+       // asv : 05.11.04 : fix of bug - "insert file" into existing graph with MacroNodes worked incorrectly!
+       // aMacroNode is an "old" node, and here we must analize only "new" nodes, that
+       // came from aListOfDataFlows and were loaded by aDataFlowEditor->LoadDataFlow( &(*aListOfDataFlows)[ index ] )
+       // so here we check if the node is "new" or "old"
+       if ( aMacroNode->GraphEditor() && aMacroNode->CoupledNode() )
+         continue;
+
+       // asv: set Editor for the graph itself and for all its macro nodes
+       aMacroNode->GraphEditor( aDataFlowEditor );
+
+       // Creation of a GraphMacroNode ObjRef in the current editor
+        SUPERV::Graph_var macroiobject = SUPERV::Graph::_nil() ;
+        Graph_Impl * myMacroNode ;
+        myMacroNode = new Graph_Impl( _Orb , _Poa, _ContId,
+                                      instanceName() , interfaceName() ,
+                                      aMacroNode->Name() , SUPERV::MacroNode ) ;
+        id = myMacroNode->getId() ;
+        obj = _poa->id_to_reference(*id);
+        macroiobject = SUPERV::Graph::_narrow( obj ) ;
+        myMacroNode->DataFlowEditor( aDataFlowEditor ) ;
+        GraphEditor::InNode * aDataFlowNode = (GraphEditor::InNode * ) aMacroNode->GetInNode() ;
+        myMacroNode->DataFlowNode( aDataFlowNode ) ;
+        aDataFlowNode->SetObjRef( SUPERV::CNode::_duplicate( SUPERV::CNode::_narrow( obj ) ) ) ;
+        aDataFlowNode->SetObjImpl( myMacroNode ) ;
+
+        char * aCoupledNodeName = aMacroNode->CoupledNodeName() ;
+        MESSAGE( "LoadDataFlows MacroNode " << aMacroNode->Name() << " --> " << aCoupledNodeName
+                 << " to be searched among " << (*aListOfDataFlows).size() << " Graphs" ) ;
+        int index ;
+        bool found = false ;
+        for ( index = 0 ; index < (int ) (*aListOfDataFlows).size() ; index++ ) {
+          MESSAGE( "LoadDataFlows Graph" << index << " " << (*aListOfDataFlows)[index].Info.theName.c_str() ) ;
+          if ( !strcmp( aCoupledNodeName , (*aListOfDataFlows)[index].Info.theName.c_str() ) ) {
+            found = true ;
+            string dbgfile ;
+// At first create the editor and a StreamGraph
+            GraphEditor::DataFlow * aMacroGraphDataFlowEditor ;
+            CreateEditor( _Orb , instanceName() , aCoupledNodeName , SUPERV::DataStreamGraph ,
+                          dbgfile , &aMacroGraphDataFlowEditor ) ;
+
+            if ( _DebugFileName ) {
+              delete [] _DebugFileName ;
+            }
+            _DebugFileName = new char[ strlen( dbgfile.c_str() )+1 ] ;
+            strcpy( _DebugFileName , dbgfile.c_str() ) ;
+
+            MESSAGE( "RECURSIVE IMPORT OF GRAPHS OF MACRONODES :" << aCoupledNodeName ) ;
+            if ( CORBA::is_nil( LoadDataFlows( aMacroGraphDataFlowEditor , aListOfDataFlows , index ) ) ) {
+              MESSAGE("Graph_Impl::LoadDataFlows failed" ) ;
+              return SUPERV::Graph::_duplicate( iobject ) ;
+            }
+
+// That graph is not a StreamGraph :
+            else if ( !aMacroGraphDataFlowEditor->Graph()->HasDataStream() ) {
+              Graph_Impl * myMacroGraph ;
+// The Graph ObjRef for that graph was already created
+              myMacroGraph = (Graph_Impl * ) aMacroGraphDataFlowEditor->Graph()->ObjImpl() ;
+
+              GraphBase::Graph * aMacroGraph = myMacroGraph->DataFlowEditor()->Graph() ;
+             
+              aMacroGraph->GraphMacroLevel( aGraph->GraphMacroLevel() + 1 ) ;
+              aMacroGraph->CoupledNode( aMacroNode ) ;
+              aMacroGraph->MacroObject( SUPERV::Graph::_duplicate( macroiobject ) ) ;
+
+// Set the GraphMacroNode ObjRef in the MacroNode
+              aMacroNode->GraphMacroLevel( aGraph->GraphMacroLevel() + 1 ) ;
+              aMacroNode->CoupledNode( aMacroGraph ) ;
+              aMacroNode->MacroObject( SUPERV::Graph::_narrow( aMacroGraphDataFlowEditor->Graph()->ObjRef() ) ) ;
+              MESSAGE( "LoadDataFlows aMacroGraph " << aMacroGraph << " " << aMacroGraph->Name()
+                       << " coupled to " << aMacroGraph->CoupledNode() << " "
+                       << aMacroGraph->CoupledNode()->Name() << " Editor " << aMacroGraph->GraphEditor() ) ;
+              MESSAGE( "LoadDataFlows aMacroNode " << aMacroNode << " " << aMacroNode->Name()
+                       << " coupled to " << aMacroNode->CoupledNode() << " "
+                       << aMacroNode->CoupledNode()->Name() << " Editor " << aMacroNode->GraphEditor() ) ;
+              MESSAGE( "LoadDataFlows current Graph " << aGraph << " " << aGraph->Name()
+                       << " coupled to " << aGraph->CoupledNode()
+                       << " Editor " << aGraph->GraphEditor() << " " << aGraph->Name() ) ;
+           }
+            break ;
+         }
+       }
+        if ( !found ) {
+          return SUPERV::Graph::_duplicate( SUPERV::Graph::_nil() ) ;
+       }
+      }
+    }
+  }
+  else if ( (*aListOfDataFlows).size() == 1 ) {
+    StreamGraph_Impl * myStreamGraph ;
+// We create a Graph ObjRef for that graph
+    myStreamGraph = new StreamGraph_Impl( _Orb , _Poa, _ContId,
+                                          instanceName() , interfaceName() ,
+                                          aDataFlowEditor , NULL ) ;
+    PortableServer::ObjectId * id = myStreamGraph->getId() ;
+    CORBA::Object_var obj = _poa->id_to_reference(*id) ;
+    SUPERV::StreamGraph_var Streamiobject = SUPERV::StreamGraph::_nil() ;
+    Streamiobject = SUPERV::StreamGraph::_narrow( obj ) ;
+    myStreamGraph->SetObjRef( SUPERV::StreamGraph::_duplicate( Streamiobject ) ) ;
+    myStreamGraph->SetObjImpl( (CNode_Impl * ) myStreamGraph ) ;
+//    iobject = SUPERV::Graph::_narrow( obj ) ;
+    iobject = SUPERV::Graph::_narrow( Streamiobject ) ;
+  }
+  else {
+    MESSAGE( "Graph_Impl::LoadDataFlows StreamGraph with MacroNodes not yet implemented" ) ;
+  }
+
+  endService( "Graph_Impl::EditorLoadDataFlows" );
+  return SUPERV::Graph::_duplicate( iobject ) ;
+}
+
+SUPERV::Graph_var Graph_Impl::LoadDataFlows( GraphExecutor::DataFlow * aDataFlowExecutor ,
+                                             GraphBase::ListOfSGraphs * aListOfDataFlows ,
+                                             int index ) {
+  beginService( "Graph_Impl::ExecutorLoadDataFlows" ) ;
+  MESSAGE("Graph_Impl::LoadDataFlows(Executor) index " << index << " " << (*aListOfDataFlows)[index].Info.theName.c_str() << " aDataFlowExecutor " << aDataFlowExecutor ) ;
+
+  // That method is recursive :
+  // At first we load the supergraph with index = 0 :
+  // (After we load the graph corresponding to each MacroNode :)
+  if ( !aDataFlowExecutor->LoadDataFlow( &(*aListOfDataFlows)[ index ] ) ) {
+    MESSAGE("Graph_Impl::LoadDataFlows(Executor) failed, could not LoadDataFlow(supergraph)" ) ;
+    return SUPERV::Graph::_duplicate( SUPERV::Graph::_nil() ) ;
+  }
+
+  // That graph is not a StreamGraph :
+  else {
+    aDataFlowExecutor->Graph()->Kind( SUPERV::DataFlowGraph ) ;
+    GraphEditor::DataFlow * aDataFlowEditor ;
+    aDataFlowEditor = DataFlowEditor() ;
+    GraphBase::Graph * anEditorGraph = aDataFlowEditor->Graph() ;
+    GraphBase::Graph * anExecutorGraph = aDataFlowExecutor->Graph() ;
+    if ( aDataFlowEditor->Executor() ) {
+      delete aDataFlowEditor->Executor() ;
+      aDataFlowEditor->Executor( NULL ) ;
+      aDataFlowEditor->Editing() ;
+    }
+    aDataFlowEditor->Executor( aDataFlowExecutor ) ;
+    anExecutorGraph->GraphEditor( aDataFlowEditor ) ;
+
+    if ( !aDataFlowExecutor->Graph()->HasDataStream() ) {
+    // For the supergraph or each graph of MacroNodes we search MacroNodes recursively :
+      int i;
+      for ( i = 0 ; i < anExecutorGraph->GraphNodesSize() ; i++ ) {
+        if ( anExecutorGraph->GraphNodes( i )->IsMacroNode() ) {
+          GraphBase::GOTONode * aMacroNode = (GraphBase::GOTONode * ) anExecutorGraph->GraphNodes( i ) ;
+          aMacroNode->GraphEditor( aDataFlowEditor ) ;
+
+       // get the macro node's editor object
+          char * aMacroGraphName = aMacroNode->CoupledNodeName() ;
+          GraphBase::Graph* aMacroGraph =  (GraphBase::Graph*)((GraphBase::GOTONode *)anEditorGraph->GetGraphNode( aMacroNode->Name() ))->CoupledNode() ;
+       GraphEditor::DataFlow* aMacroGraphEditor = aMacroGraph->GraphEditor();
+
+          MESSAGE( "LoadDataFlows(Executor) MacroNode " << aMacroNode->Name() << " Coupled to " << aMacroGraphName
+                   << " to be searched among " << (*aListOfDataFlows).size() << " Graphs" << endl ) ;
+          int index;
+          bool found = false ;
+          for ( index = 0 ; index < (int ) (*aListOfDataFlows).size() && !found; index++ ) {
+            if ( !strcmp( aMacroGraphName , (*aListOfDataFlows)[index].Info.theName.c_str() ) )
+              found = true;
+         }
+         if ( !found ) {
+           MESSAGE("Graph_Impl::LoadDataFlows(Executor) failed, Macro node's coupled graph \"" << aMacroGraphName << "\" was not found" ) ;
+           return SUPERV::Graph::_duplicate( SUPERV::Graph::_nil() ) ;
+         }
+         index--; // it was incremented in "for ..." before last check ( !found ).
+       
+       // At first create the editor and a StreamGraph
+         string dbgfile ;
+         GraphExecutor::DataFlow * aMacroGraphExecutor ;
+         CreateExecutor( _Orb , instanceName() , aMacroGraphName , SUPERV::DataStreamGraph ,
+                       dbgfile , &aMacroGraphExecutor );
+
+       // set GraphMacroLevel for Executor's graph
+         GraphBase::Graph* aMacroGraphExe = aMacroGraphExecutor->Graph();
+            aMacroGraphExe->GraphMacroLevel( anExecutorGraph->GraphMacroLevel() + 1 );
+
+       // load data flows in MacroGraph's executor
+         Graph_Impl* aMacroGraphImpl = (Graph_Impl*) aMacroGraphEditor->Graph()->ObjImpl();
+         MESSAGE( "RECURSIVE IMPORT OF GRAPHS OF MACRONODES : " << aMacroGraphName ) ;
+         if ( CORBA::is_nil( aMacroGraphImpl->LoadDataFlows( aMacroGraphExecutor, aListOfDataFlows , index ) ) ) {
+           MESSAGE("Graph_Impl::LoadDataFlows(Executor) failed,  could not LoadDataFlow( MacroNodeGraph \"" <<aMacroGraphName << "\" )" ) ;
+           return SUPERV::Graph::_duplicate( SUPERV::Graph::_nil() ) ;
+         }
+         
+         // set coupled pair MacroNode <--> MacroGraph
+          aMacroGraphExe->CoupledNode( aMacroNode ) ;
+          aMacroNode->CoupledNode( aMacroGraphExe ) ;
+
+//JR 04.05.2005 Debug : InPorts values of MacroNodes are like for other nodes
+//                      InPorts values of MacroGraphs of MacroNodes are done in the Executor
+// It was probably to try to debug anything but it was a wrong debug and I do not know what bug
+// ===> folowing code is commented
+#if 0
+         // initialize MacroNode's InPorts with corresponding "external" values
+         int q ;
+         for ( q = 0 ; q < aMacroNode->GetNodeInPortsSize() ; q++ ) {
+           const GraphBase::InPort * anInPort = aMacroNode->GetNodeInPort( q ) ;
+           if ( anInPort->IsDataConnected() ) {
+             const char* aMacroGraphInPortName = aMacroGraph->GetNodeInPort( q )->PortName();
+//JR 30.03.2005              if ( !aMacroGraphExecutor->InputOfAny(  aMacroGraphInPortName, *anInPort->GetOutPort()->Value(),false ) ) {
+             if ( !aMacroGraphExecutor->InputOfAny(  aMacroGraphInPortName, anInPort->GetOutPort()->Value(),false ) ) {
+               return SUPERV::Graph::_duplicate( SUPERV::Graph::_nil() ) ;
+             }
+             else {
+               MESSAGE( "LoadDataFlows(Executor) " << aMacroGraph->Name() << "->InputOfAny( " 
+                         << aMacroGraphInPortName << " , Value )" ) ;
+             }
+           }
+         } // end of init MacroNode's InPorts
+#endif
+         aMacroGraphImpl->Run() ;
+
+        }
+      } // end of for( get nodes of the graph...)
+    }
+  } // end of setting initial graph's structure..
+
+  endService( "Graph_Impl::ExecutorLoadDataFlows" );
+
+  PortableServer::ObjectId * id = getId();
+  CORBA::Object_var obj = _poa->id_to_reference( *id );
+  SUPERV::Graph_var iobject = SUPERV::Graph::_narrow( obj ) ;
+  return SUPERV::Graph::_duplicate( iobject ) ;
+}
+
+SUPERV::Graph_ptr Graph_Impl::MNode( const char * aXmlFileName ) {
+  beginService( "Graph_Impl::MNode" );
+  SUPERV::Graph_var iobject = SUPERV::Graph::_nil() ;
+  MESSAGE( "Graph_Impl::MNode( " << aXmlFileName << " )" ) ;
+  if ( !IsMacro() ) {
+    GraphBase::ListOfSGraphs aListOfDataFlows ;
+    string dbgfile ;
+// At first create the editor and a StreamGraph with the xml file
+    GraphEditor::DataFlow * aDataFlowEditor ;
+    CreateEditor( _Orb , instanceName() , aXmlFileName , SUPERV::DataStreamGraph ,
+                  dbgfile , &aDataFlowEditor ) ;
+
+    if ( _DebugFileName ) {
+      delete [] _DebugFileName ;
+    }
+    _DebugFileName = new char[ strlen( dbgfile.c_str() )+1 ] ;
+    strcpy( _DebugFileName , dbgfile.c_str() ) ;
+
+    int lenname = strlen( aXmlFileName ) ;
+    bool loaded = false ;
+// Import of the xml file
+    if ( lenname > 4 && !strcmp( &aXmlFileName[ lenname - 4 ] , ".xml" ) ) {
+      loaded = aDataFlowEditor->LoadXml( aXmlFileName , aListOfDataFlows ) ;
+      if ( loaded ) {
+        iobject = MNode( aDataFlowEditor , &aListOfDataFlows ) ;
+      }
+    }
+  }
+  return iobject ;
+}
+
+// WARNING : THIS IS COMPLICATED :
+// I should have to remove duplicated code ...
+SUPERV::Graph_ptr Graph_Impl::MNode( GraphEditor::DataFlow * aMacroGraphDataFlowEditor ,
+                                     GraphBase::ListOfSGraphs * aListOfDataFlows ) {
+  beginService( "Graph_Impl::MNode" ) ;
+  SUPERV::Graph_var iobject = SUPERV::Graph::_nil() ;
+  SUPERV::Graph_var macroiobject = SUPERV::Graph::_nil() ;
+
+  if ( !IsMacro() ) {
+    MESSAGE( "Graph_Impl::MNode DataFlowEditor->LoadDataFlow" ) ;
+//    if ( !aMacroGraphDataFlowEditor->LoadDataFlow( &aListOfDataFlows[ 0 ] ) ) {
+    iobject = LoadDataFlows( aMacroGraphDataFlowEditor , aListOfDataFlows , 0 ) ;
+    if ( CORBA::is_nil( iobject ) ) {
+      MESSAGE("Graph_Impl::MNode LoadDataFlow failed" ) ;
+      return false ;
+    }
+
+// That graph is not a StreamGraph :
+    else if ( !aMacroGraphDataFlowEditor->Graph()->HasDataStream() ) {
+      aMacroGraphDataFlowEditor->Graph()->Kind( SUPERV::DataFlowGraph ) ;
+      aMacroGraphDataFlowEditor->Graph()->GraphEditor( aMacroGraphDataFlowEditor ) ;
+
+      Graph_Impl * myMacroGraph = (Graph_Impl * ) aMacroGraphDataFlowEditor->Graph()->ObjImpl() ;
+// Creation of a GraphMacroNode in the current editor
+      string aMacroNodeName = string( "Macro_" ) + string( myMacroGraph->Name() ) ;
+      Graph_Impl * myMacroNode ;
+      myMacroNode = new Graph_Impl( _Orb , _Poa, _ContId,
+                                    instanceName() , interfaceName() ,
+                                    aMacroNodeName.c_str() , SUPERV::MacroNode ) ;
+      PortableServer::ObjectId * id = myMacroNode->getId() ;
+      CORBA::Object_var obj = _poa->id_to_reference(*id);
+      macroiobject = SUPERV::Graph::_narrow( obj ) ;
+      myMacroNode->DataFlowEditor( DataFlowEditor() ) ;
+
+// Creation of the MacroNode itself in the current Graph
+      GraphBase::ListOfFuncName aFuncName ;
+      aFuncName.resize( 1 ) ;
+      aFuncName[0] = "" ;
+      SUPERV::ListOfStrings aListOfStrings ;
+      aListOfStrings.length( 1 ) ;
+      aListOfStrings[0] = "" ;
+      GraphBase::ListOfPythonFunctions aPythonFunction ;
+      aPythonFunction.resize( 1 ) ;
+      aPythonFunction[0] = &aListOfStrings ;
+      SALOME_ModuleCatalog::Service * aMacroNodeService = myMacroGraph->Service() ;
+      GraphEditor::InNode * aDataFlowNode = DataFlowEditor()->AddNode( *aMacroNodeService , "" , "" ,
+                                                                       aMacroNodeName.c_str() , SUPERV::MacroNode ,
+                                                                       aFuncName , aPythonFunction ) ;
+      aDataFlowNode->SetPythonFunction( "" , aListOfStrings ) ;
+      myMacroNode->DataFlowNode( aDataFlowNode ) ;
+      aDataFlowNode->ComputingNode()->SetService( *aMacroNodeService ) ;
+      aDataFlowNode->SetObjRef( SUPERV::CNode::_duplicate( SUPERV::CNode::_narrow( obj ) ) ) ;
+      aDataFlowNode->SetObjImpl( this ) ;
+
+      GraphBase::Graph * aGraph = myMacroGraph->DataFlowEditor()->Graph() ;
+      GraphBase::Graph * aGraphOfMacroGraph = myMacroNode->DataFlowEditor()->Graph() ;
+      GraphBase::Graph * aMacroGraph = myMacroNode->DataFlowNode()->GraphMacroNode() ;
+      aMacroGraph->Kind( SUPERV::MacroNode ) ;
+      aMacroGraph->GraphEditor( DataFlowEditor() ) ;
+// Creation of the Ports of the MacroNode from the ports of the GraphMacroNode
+      aMacroGraph->SetMacroPorts( aGraph ) ;
+// Valid ==> creation of Service and the ports of the current Graph
+      DataFlowEditor()->IsValid() ;
+// Set the Input Datas from the GraphMacroNode to the current Graph
+      aMacroGraph->SetMacroDatas( aGraph , aGraphOfMacroGraph ) ;
+      aMacroGraphDataFlowEditor->UnValid() ;
+// Set the MacroNode ObjRef in the GraphMacroNode
+      aGraph->CoupledNode( aMacroGraph ) ;
+      aGraph->MacroObject( SUPERV::Graph::_duplicate( macroiobject ) ) ;
+// Set the GraphMacroNode ObjRef in the MacroNode
+      aDataFlowNode->GraphMacroNode()->GraphMacroLevel( aGraphOfMacroGraph->GraphMacroLevel() + 1 ) ;
+      aMacroGraph->CoupledNode( aGraph ) ;
+//      aGraphOfMacroGraph->CoupledNode( aGraph ) ;
+      aMacroGraph->MacroObject( SUPERV::Graph::_duplicate( iobject ) ) ;
+//      aGraphOfMacroGraph->MacroObject( SUPERV::Graph::_duplicate( iobject ) ) ;
+//    aDataFlowNode->CoupledNode( aGraph ) ;
+//    aDataFlowNode->ComputingNode()->MacroObject( SUPERV::Graph::_duplicate( iobject ) ) ;
+// Set the MacroLevel of that graph
+      aGraph->GraphMacroLevel( aGraphOfMacroGraph->GraphMacroLevel() + 1 ) ;
+      aMacroGraph->Coordinates( 0 , 0 ) ;
+      MESSAGE( "DataFlowNode Graph " << this << " DataFlowEditor " << DataFlowEditor() << " aDataFlowNode "
+               << aDataFlowNode << " " << aDataFlowNode->Name() << " created" ) ;
+      MESSAGE( "MNode aGraph " << aGraph << " " << aGraph->Name()
+               << " coupled to " << aGraph->CoupledNode() << " "
+               << aGraph->CoupledNode()->Name() ) ;
+      MESSAGE( "MNode aMacroGraph " << aMacroGraph << " " << aMacroGraph->Name()
+               << " coupled to " << aMacroGraph->CoupledNode() << " "
+               << aMacroGraph->CoupledNode()->Name() ) ;
+      MESSAGE( "MNode aMacroGraph " << myMacroNode->DataFlowEditor()->Graph() << " "
+               << myMacroNode->DataFlowEditor()->Graph()->Name()
+               << " coupled to " << myMacroNode->DataFlowEditor()->Graph()->CoupledNode() ) ;
+    }
+    else {
+      delete aMacroGraphDataFlowEditor ;
+    }
+  }
+  endService( "Graph_Impl::MNode" );
+  return SUPERV::Graph::_duplicate( macroiobject ) ;
+}
+
+// For python supergraph
+SUPERV::Graph_ptr Graph_Impl::GraphMNode( SUPERV::Graph_ptr myMacroGraph ) {
+  SUPERV::Graph_var iobject = myMacroGraph ;
+  beginService( "Graph_Impl::GraphMNode" ) ;
+
+//  GraphBase::Graph * myMacroGraph = aGraph;
+  SUPERV::Graph_var macroiobject = SUPERV::StreamGraph::_nil() ;
+// Creation of a GraphMacroNode in the current editor
+  if ( !IsMacro() ) {
+    string aMacroNodeName = string( "Macro_" ) + string( myMacroGraph->Name() ) ;
+    //string aMacroNodeName = string( myMacroGraph->CoupledName() ) ;
+    MESSAGE( "GraphMNode( " << myMacroGraph->Name() << " )" ) ;
+    Graph_Impl * myMacroNode ;
+    myMacroNode = new Graph_Impl( _Orb , _Poa, _ContId,
+                                  instanceName() , interfaceName() ,
+                                  aMacroNodeName.c_str() , SUPERV::MacroNode ) ;
+    PortableServer::ObjectId * id = myMacroNode->getId() ;
+    CORBA::Object_var obj = _poa->id_to_reference(*id);
+    macroiobject = SUPERV::Graph::_narrow( obj ) ;
+    myMacroNode->DataFlowEditor( DataFlowEditor() ) ;
+
+// Creation of the MacroNode itself in the current Graph
+    GraphBase::ListOfFuncName aFuncName ;
+    aFuncName.resize( 1 ) ;
+    aFuncName[0] = "" ;
+    SUPERV::ListOfStrings aListOfStrings ;
+    aListOfStrings.length( 1 ) ;
+    aListOfStrings[0] = "" ;
+    GraphBase::ListOfPythonFunctions aPythonFunction ;
+    aPythonFunction.resize( 1 ) ;
+    aPythonFunction[0] = &aListOfStrings ;
+    SALOME_ModuleCatalog::Service * aMacroNodeService = myMacroGraph->Service() ;
+    GraphEditor::InNode * aDataFlowNode ;
+    aDataFlowNode = DataFlowEditor()->AddNode( *aMacroNodeService , "" , "" ,
+                                               aMacroNodeName.c_str() , SUPERV::MacroNode ,
+                                               aFuncName , aPythonFunction ) ;
+    aDataFlowNode->SetPythonFunction( "" , aListOfStrings ) ;
+    myMacroNode->DataFlowNode( aDataFlowNode ) ;
+    aDataFlowNode->ComputingNode()->SetService( *aMacroNodeService ) ;
+    aDataFlowNode->SetObjRef( SUPERV::CNode::_duplicate( SUPERV::CNode::_narrow( obj ) ) ) ;
+    aDataFlowNode->SetObjImpl( this ) ;
+
+    GraphBase::Graph * aSubGraph = NULL ;
+//    GraphBase::Graph * aGraph = DataFlowEditor()->Automaton()->MapGraph( myMacroGraph->Name() ) ;
+    //DataFlowEditor()->Automaton()->GraphBase( &aGraph ) ;
+//JR 20.09.2005 Debug SAB_data_1609_bugPAL.py from CEA (Anthony)
+//    Graph_Impl * aSubGraphImpl = dynamic_cast<Graph_Impl * >( _Poa->id_to_servant( *myMacroGraph->_Id ) ) ;
+    myMacroGraph->ping() ;
+    Graph_Impl * aSubGraphImpl = theAutomaton->GraphImpl() ;
+    aSubGraph = aSubGraphImpl->DataFlowEditor()->Graph() ;
+    myMacroGraph->Coupled() ;
+    GraphBase::Graph * aGraphOfMacroGraph = myMacroNode->DataFlowEditor()->Graph() ;
+    GraphBase::Graph * aMacroGraph = myMacroNode->DataFlowNode()->GraphMacroNode() ;
+    aMacroGraph->Kind( SUPERV::MacroNode ) ;
+    aMacroGraph->GraphEditor( DataFlowEditor() ) ;
+// Creation of the Ports of the MacroNode from the ports of the GraphMacroNode
+    aMacroGraph->SetMacroPorts( aSubGraph ) ;
+// Valid ==> creation of Service and the ports of the current Graph
+    DataFlowEditor()->IsValid() ;
+// Set the Input Datas from the GraphMacroNode to the current Graph
+    aMacroGraph->SetMacroDatas( aSubGraph , aGraphOfMacroGraph ) ;
+//    aMacroGraphDataFlowEditor->UnValid() ;
+    aSubGraph->GraphEditor()->UnValid() ;
+// Set the MacroNode ObjRef in the GraphMacroNode
+    aSubGraph->CoupledNode( aMacroGraph ) ;
+    aSubGraph->MacroObject( SUPERV::Graph::_duplicate( macroiobject ) ) ;
+// Set the GraphMacroNode ObjRef in the MacroNode
+    aDataFlowNode->GraphMacroNode()->GraphMacroLevel( aGraphOfMacroGraph->GraphMacroLevel() + 1 ) ;
+    aMacroGraph->CoupledNode( aSubGraph ) ;
+    aMacroGraph->MacroObject( SUPERV::Graph::_duplicate( iobject ) ) ;
+//    aDataFlowNode->CoupledNode( aSubGraph ) ;
+//    aDataFlowNode->ComputingNode()->MacroObject( SUPERV::Graph::_duplicate( iobject ) ) ;
+// Set the MacroLevel of that graph
+    aSubGraph->GraphMacroLevel( aGraphOfMacroGraph->GraphMacroLevel() + 1 ) ;
+    aMacroGraph->Coordinates( 0 , 0 ) ;
+    MESSAGE( aSubGraph->Name() << "->CoupledNode()->GraphEditor() : " << aSubGraph->CoupledNode()->GraphEditor() ) ;
+    MESSAGE( aMacroGraph->Name() << "->CoupledNode()->GraphEditor() : "
+             << aMacroGraph->CoupledNode()->GraphEditor() ) ;
+    MESSAGE( "DataFlowNode Graph " << this << " DataFlowEditor " << DataFlowEditor() << " aDataFlowNode "
+             << aDataFlowNode << " " << aDataFlowNode->Name() << " created" ) ;
+  }
+  endService( "Graph_Impl::GraphMNode" ) ;
+  return SUPERV::Graph::_duplicate( macroiobject ) ;
+}
+
+SUPERV::Graph_ptr Graph_Impl::FlowObjRef() {
+  beginService( "Graph_Impl::FlowObjRef" );
+  SUPERV::Graph_var iobject = SUPERV::Graph::_nil() ;
+  if ( IsMacro() ) {
+    iobject = SUPERV::Graph::_narrow( DataFlowNode()->GraphMacroNode()->MacroObject() ) ;
+  }
+  else if ( IsGraph() ) {
+    iobject = SUPERV::Graph::_narrow( DataFlowEditor()->Graph()->MacroObject() ) ;
+  }
+  if ( CORBA::is_nil( iobject ) ) {
+    MESSAGE( "Graph_Impl::FlowObjRef() returns a NIL Object" ) ;
+  }
+  endService( "Graph_Impl::FlowObjRef" );
+  return SUPERV::Graph::_duplicate( iobject ) ;
+}
+
+SUPERV::StreamGraph_ptr Graph_Impl::StreamObjRef() {
+  beginService( "Graph_Impl::StreamObjRef" );
+  SUPERV::StreamGraph_var iobject = SUPERV::StreamGraph::_nil() ;
+  if ( IsMacro() ) {
+    iobject = SUPERV::StreamGraph::_narrow( DataFlowNode()->GraphMacroNode()->MacroObject() ) ;
+  }
+  else if ( IsGraph() || IsStreamGraph() ) {
+    iobject = SUPERV::StreamGraph::_narrow( DataFlowEditor()->Graph()->MacroObject() ) ;
+  }
+  if ( CORBA::is_nil( iobject ) ) {
+    MESSAGE( "Graph_Impl::StreamObjRef() returns a NIL Object" ) ;
+  }
+  endService( "Graph_Impl::StreamObjRef" );
+  return SUPERV::StreamGraph::_duplicate( iobject ) ;
+}
 
-SUPERV::CNode_ptr Graph_Impl::GetNode(char const * aNodeName ) {
-//  beginService( "Graph_Impl::GetNode" );
+SUPERV::CNode_ptr Graph_Impl::Node(char const * aNodeName ) {
+//  beginService( "Graph_Impl::Node" );
   SUPERV::CNode_var iobject = SUPERV::CNode::_nil() ;
   /* JR : 13/06/03
      if ( CORBA::is_nil( DataFlowEditor()->GetNode( aNodeName )->ObjRef() ) ) {
@@ -484,81 +1131,214 @@ SUPERV::CNode_ptr Graph_Impl::GetNode(char const * aNodeName ) {
      else {
      iobject = DataFlowEditor()->GetNode( aNodeName )->ObjRef() ;
   */
-  GraphEditor::InNode * anInNode = DataFlowEditor()->GetNode( aNodeName ) ;
-  if ( anInNode ) {
-    if ( CORBA::is_nil( anInNode->ObjRef() ) ) {
-      CNode_Impl * myNode = new CNode_Impl( _Orb , _Poa , _ContId ,
-                                            instanceName() , interfaceName() ,
-                                            DataFlowEditor() ,
-                                            DataFlowEditor()->GetNode( aNodeName ) ) ;
-      PortableServer::ObjectId * id = myNode->getId() ;
-      CORBA::Object_var obj = _poa->id_to_reference(*id);
-      iobject = SUPERV::CNode::_narrow(obj) ;
-      myNode->SetObjRef( SUPERV::CNode::_duplicate( iobject ) ) ;
-    }
-    else {
-      iobject = DataFlowEditor()->GetNode( aNodeName )->ObjRef() ;
+  if ( !IsMacro() ) {
+    GraphEditor::InNode * anInNode = DataFlowEditor()->GetNode( aNodeName ) ;
+    if ( anInNode ) {
+      if ( CORBA::is_nil( anInNode->ObjRef() ) ) {
+        SetNodeObjRef( anInNode ) ;
+      }
+      iobject = anInNode->ObjRef() ;
     }
   }
-//  endService( "Graph_Impl::GetNode" );
+//  endService( "Graph_Impl::Node" );
   return SUPERV::CNode::_duplicate( iobject ) ;
 }
 
 SUPERV::Link_ptr Graph_Impl::Link( SUPERV::Port_ptr OutPort ,
                                    SUPERV::Port_ptr InPort ) {
-  beginService( "Graph_Impl::Link" );
+//  beginService( "Graph_Impl::Link" );
   SUPERV::Link_var iobject = SUPERV::Link::_nil() ;
-  if ( DataFlowEditor()->IsEditing() &&
-       !DataFlowEditor()->IsReadOnly() ) {
-    const char * DataFlowOutNodeName = OutPort->Node()->Name() ;
-    GraphEditor::InNode * DataFlowOutNode = DataFlowEditor()->GetNode( DataFlowOutNodeName ) ;
-    const char * DataFlowInNodeName = InPort->Node()->Name() ;
-    GraphEditor::InNode * DataFlowInNode = DataFlowEditor()->GetNode( DataFlowInNodeName ) ;
-    if ( DataFlowOutNode && DataFlowInNode ) {
-      Link_Impl * myLink = new Link_Impl( _Orb , _Poa , _ContId ,
-                                          instanceName() , interfaceName() ,
-                                          DataFlowEditor() ,
-                                          DataFlowInNode ,
-                                          InPort->Name() ,
-                                          DataFlowOutNode ,
-                                          OutPort->Name() ,
-                                          true ) ;
-      PortableServer::ObjectId * id = myLink->getId() ;
-      CORBA::Object_var obj = _poa->id_to_reference(*id);
-      iobject = SUPERV::Link::_narrow(obj) ;
-//      iobject = InPort->Link() ;
+  if ( DataFlowEditor()->IsEditing() && !DataFlowEditor()->IsReadOnly() &&
+       !OutPort->IsDataStream() && !InPort->IsDataStream() && !IsMacro() ) {
+    MESSAGE( "Graph_Impl::Link( " << OutPort->Node()->Name() << "( " << OutPort->Name() << " ) --> "
+             << InPort->Node()->Name() << "( " << InPort->Name() << " )" ) ;
+    GraphEditor::InNode * anInNode = DataFlowEditor()->GetNode( InPort->Node()->Name() ) ;
+    GraphEditor::InNode * anOutNode = DataFlowEditor()->GetNode( OutPort->Node()->Name() ) ;
+    if ( anInNode == NULL || anOutNode== NULL ) {
+      MESSAGE( "Graph_Impl::Link( " << OutPort->Node()->Name() << " " << anOutNode << " , "
+               << InPort->Node()->Name() << " " << anInNode << " ) Node(s) not found in " << Name() ) ;
+    }
+    else {
+      GraphBase::InPort * anInPort = anInNode->ComputingNode()->GetChangeInPort( InPort->Name() ) ;
+      GraphBase::OutPort * anOutPort = anOutNode->ComputingNode()->GetChangeOutPort( OutPort->Name() ) ;
+      if ( anInPort == NULL || anOutPort== NULL ) {
+        MESSAGE( "Graph_Impl::Link( " << OutPort->Name() << " " << anOutPort << " , "
+                 << InPort->Name() << " " << anInPort << " ) Port(s) not found" ) ;
+      }
+      else if ( CORBA::is_nil( anOutPort->InPortObjRef( anInPort ) ) ) {
+        const char * DataFlowOutNodeName = OutPort->Node()->Name() ;
+        GraphEditor::InNode * DataFlowOutNode = DataFlowEditor()->GetNode( DataFlowOutNodeName ) ;
+        const char * DataFlowInNodeName = InPort->Node()->Name() ;
+        GraphEditor::InNode * DataFlowInNode = DataFlowEditor()->GetNode( DataFlowInNodeName ) ;
+        if ( DataFlowOutNode && DataFlowInNode ) {
+          bool Success ;
+          Link_Impl * myLink = new Link_Impl( _Orb , _Poa , _ContId ,
+                                              instanceName() , interfaceName() ,
+                                              DataFlowEditor() ,
+                                              DataFlowInNode ,
+                                              InPort->Name() ,
+                                              DataFlowOutNode ,
+                                              OutPort->Name() ,
+                                              true , false , Success ) ;
+          if ( Success ) {
+            PortableServer::ObjectId * id = myLink->getId() ;
+            CORBA::Object_var obj = _poa->id_to_reference(*id);
+            iobject = SUPERV::Link::_narrow(obj) ;
+            anOutPort->AddInPortObjRef( anInPort , SUPERV::Link::_duplicate( iobject ) ) ;
+         }
+        }
+      }
+      else {
+        MESSAGE( "Graph_Impl::Link( " << OutPort->Name() << " " << anOutPort << " , "
+                 << InPort->Name() << " " << anInPort << " ) ObjRef already exists" ) ;
+        iobject = anOutPort->InPortObjRef( anInPort ) ;
+      }
     }
   }
-  endService( "Graph_Impl::Link" );
+  DataFlowEditor()->UnValid() ;
+//  endService( "Graph_Impl::Link" );
   return SUPERV::Link::_duplicate( iobject ) ;
 }
 
-SUPERV::ListOfNodes_var  Graph_Impl::SetNode( SUPERV::ListOfNodes_var RetVal ,
-                                              GraphBase::ComputingNode * aNode ) {
-  int index = 0 ;
-//   MESSAGE("Graph_Impl::SetNode " << aNode->Name() << " " << aNode->Kind() ) ;
-//  if ( _DataFlowExecutor ) {
-//    MESSAGE("Graph_Impl::SetNode " << aNode->Name() << " " << aNode->Kind() << " "
-//            << _DataFlowExecutor->StateName( _DataFlowExecutor->AutomatonState( aNode->Name() ) ) ) ;
-//  }
-//  else {
-//    MESSAGE("Graph_Impl::SetNode " << aNode->Name() << " " << aNode->Kind() ) ;
-//  }
-  if ( aNode->IsComputingNode() ) {
-    index = RetVal->CNodes.length() ;
-    RetVal->CNodes.length( index+1 );
+// Only to see MacroNodes with actual GUI ... :
+#define GOTOMacroNode 0
+
+void Graph_Impl::SetNodeObjRef( GraphEditor::InNode * anInNode ) {
+  MESSAGE("Graph_Impl::SetNodeObjRef " << anInNode->Name() << " " << anInNode->Kind() ) ;
+  CORBA::Object_var obj ;
+  if ( anInNode->IsComputingNode() ) {
+    CNode_Impl * myNode = new CNode_Impl( _Orb , _Poa , _ContId ,
+                                          instanceName() , interfaceName() ,
+                                          DataFlowEditor() ,
+                                          anInNode ) ;
+    PortableServer::ObjectId * id = myNode->getId() ;
+    obj = _poa->id_to_reference(*id);
+    SUPERV::CNode_var iobject = SUPERV::CNode::_narrow(obj) ;
+    myNode->SetObjRef( SUPERV::CNode::_duplicate( iobject ) ) ;
   }
-  else if ( aNode->IsFactoryNode() ) {
-    index = RetVal->FNodes.length() ;
-    RetVal->FNodes.length( index+1 );
+  else if ( anInNode->IsFactoryNode() ) {
+    FNode_Impl * myNode = new FNode_Impl( _Orb , _Poa , _ContId ,
+                                          instanceName() , interfaceName() ,
+                                          DataFlowEditor() ,
+                                          anInNode ) ;
+    PortableServer::ObjectId * id = myNode->getId() ;
+    obj = _poa->id_to_reference(*id);
+    SUPERV::FNode_var iobject = SUPERV::FNode::_narrow(obj) ;
+    myNode->SetObjRef( SUPERV::FNode::_duplicate( iobject ) ) ;
   }
-  else if ( aNode->IsInLineNode() ) {
-    index = RetVal->INodes.length() ;
-    RetVal->INodes.length( index+1 );
+  else if ( anInNode->IsInLineNode() ) {
+    INode_Impl * myNode = new INode_Impl( _Orb , _Poa , _ContId ,
+                                          instanceName() , interfaceName() ,
+                                          DataFlowEditor() ,
+                                          anInNode ) ;
+    PortableServer::ObjectId * id = myNode->getId() ;
+    obj = _poa->id_to_reference(*id);
+    SUPERV::INode_var iobject = SUPERV::INode::_narrow(obj) ;
+    myNode->SetObjRef( SUPERV::INode::_duplicate( iobject ) ) ;
   }
-  else if ( aNode->IsGOTONode() ) {
-    index = RetVal->GNodes.length() ;
-    RetVal->GNodes.length( index+1 );
+#if GOTOMacroNode
+  else if ( anInNode->IsGOTONode() || anInNode->IsMacroNode() ) {
+    if ( anInNode->IsMacroNode() ) {
+      anInNode->ComputingNode()->Kind( SUPERV::GOTONode ) ;
+    }
+#else
+  else if ( anInNode->IsGOTONode() ) {
+#endif
+    GNode_Impl * myNode = new GNode_Impl( _Orb , _Poa , _ContId ,
+                                          instanceName() , interfaceName() ,
+                                          DataFlowEditor() ,
+                                          anInNode ) ;
+    PortableServer::ObjectId * id = myNode->getId() ;
+    obj = _poa->id_to_reference(*id);
+    SUPERV::GNode_var iobject = SUPERV::GNode::_narrow(obj) ;
+    myNode->SetObjRef( SUPERV::GNode::_duplicate( iobject ) ) ;
+  }
+  else if ( anInNode->IsMacroNode() ) {
+    Graph_Impl * myNode = new Graph_Impl( _Orb , _Poa , _ContId ,
+                                          instanceName() , interfaceName() ,
+                                          DataFlowEditor() ,
+                                          anInNode ) ;
+    PortableServer::ObjectId * id = myNode->getId() ;
+    obj = _poa->id_to_reference(*id);
+    SUPERV::Graph_var iobject = SUPERV::Graph::_narrow(obj) ;
+    myNode->SetObjRef( SUPERV::Graph::_duplicate( iobject ) ) ;
+  }
+  else if ( anInNode->IsLoopNode() ) {
+    LNode_Impl * myNode = new LNode_Impl( _Orb , _Poa , _ContId ,
+                                          instanceName() , interfaceName() ,
+                                          DataFlowEditor() ,
+                                          anInNode ) ;
+    PortableServer::ObjectId * id = myNode->getId() ;
+    obj = _poa->id_to_reference(*id);
+    SUPERV::LNode_var iobject = SUPERV::LNode::_narrow(obj) ;
+    myNode->SetObjRef( SUPERV::LNode::_duplicate( iobject ) ) ;
+  }
+  else if ( anInNode->IsEndLoopNode() ) {
+    ELNode_Impl * myNode = new ELNode_Impl( _Orb , _Poa , _ContId ,
+                                            instanceName() , interfaceName() ,
+                                            DataFlowEditor() ,
+                                            anInNode ) ;
+    PortableServer::ObjectId * id = myNode->getId() ;
+    obj = _poa->id_to_reference(*id);
+    SUPERV::ELNode_var iobject = SUPERV::ELNode::_narrow(obj) ;
+    myNode->SetObjRef( SUPERV::ELNode::_duplicate( iobject ) ) ;
+  }
+  else if ( anInNode->IsSwitchNode() ) {
+    SNode_Impl * myNode = new SNode_Impl( _Orb , _Poa , _ContId ,
+                                          instanceName() , interfaceName() ,
+                                          DataFlowEditor() ,
+                                          anInNode ) ;
+    PortableServer::ObjectId * id = myNode->getId() ;
+    obj = _poa->id_to_reference(*id);
+    SUPERV::SNode_var iobject = SUPERV::SNode::_narrow(obj) ;
+    myNode->SetObjRef( SUPERV::SNode::_duplicate( iobject ) ) ;
+  }
+  else if ( anInNode->IsEndSwitchNode() ) {
+    ESNode_Impl * myNode = new ESNode_Impl( _Orb , _Poa , _ContId ,
+                                            instanceName() , interfaceName() ,
+                                            DataFlowEditor() ,
+                                            anInNode ) ;
+    PortableServer::ObjectId * id = myNode->getId() ;
+    obj = _poa->id_to_reference(*id);
+    SUPERV::ESNode_var iobject = SUPERV::ESNode::_narrow(obj) ;
+    myNode->SetObjRef( SUPERV::ESNode::_duplicate( iobject ) ) ;
+  }
+}
+
+SUPERV::ListOfNodes_var  Graph_Impl::SetNode( SUPERV::ListOfNodes_var RetVal ,
+                                              GraphBase::ComputingNode * aNode ) {
+  int index = 0 ;
+//  if ( _DataFlowExecutor ) {
+  if ( DataFlowExecutor() ) {
+    MESSAGE("Graph_Impl::SetNode " << aNode->Name() << " " << aNode->Kind() << " "
+            << DataFlowExecutor()->StateName( DataFlowExecutor()->AutomatonState( aNode->Name() ) ) ) ;
+  }
+  else {
+    MESSAGE("Graph_Impl::SetNode " << aNode->Name() << " " << aNode->Kind() ) ;
+  }
+  if ( aNode->IsComputingNode() ) {
+    index = RetVal->CNodes.length() ;
+    RetVal->CNodes.length( index+1 );
+  }
+  else if ( aNode->IsFactoryNode() ) {
+    index = RetVal->FNodes.length() ;
+    RetVal->FNodes.length( index+1 );
+  }
+  else if ( aNode->IsInLineNode() ) {
+    index = RetVal->INodes.length() ;
+    RetVal->INodes.length( index+1 );
+  }
+#if GOTOMacroNode
+  else if ( aNode->IsGOTONode() || aNode->IsMacroNode() ) {
+#else
+  else if ( aNode->IsGOTONode() ) {
+#endif
+    index = RetVal->GNodes.length() ;
+    RetVal->GNodes.length( index+1 );
+  }
+  else if ( aNode->IsMacroNode() ) {
+    index = RetVal->Graphs.length() ;
+    RetVal->Graphs.length( index+1 );
   }
   else if ( aNode->IsLoopNode() ) {
     index = RetVal->LNodes.length() ;
@@ -577,126 +1357,39 @@ SUPERV::ListOfNodes_var  Graph_Impl::SetNode( SUPERV::ListOfNodes_var RetVal ,
     RetVal->ESNodes.length( index+1 );
   }
   if ( CORBA::is_nil( aNode->ObjRef() ) ) {
-    if ( aNode->IsComputingNode() ) {
-      CNode_Impl * myNode = new CNode_Impl( _Orb , _Poa , _ContId ,
-                                  instanceName() , interfaceName() ,
-                                  DataFlowEditor() ,
-                                  (GraphEditor::InNode * ) aNode->GetInNode() ) ;
-      PortableServer::ObjectId * id = myNode->getId() ;
-      CORBA::Object_var obj = _poa->id_to_reference(*id);
-      SUPERV::CNode_var iobject ;
-      iobject = SUPERV::CNode::_narrow(obj) ;
-      myNode->SetObjRef( SUPERV::CNode::_duplicate( iobject ) ) ;
-      RetVal->CNodes[index] = SUPERV::CNode::_duplicate( iobject ) ;
-    }
-    else if ( aNode->IsFactoryNode() ) {
-      FNode_Impl * myNode = new FNode_Impl( _Orb , _Poa , _ContId ,
-                                            instanceName() , interfaceName() ,
-                                            DataFlowEditor() ,
-                                            (GraphEditor::InNode * ) aNode->GetInNode() ) ;
-      PortableServer::ObjectId * id = myNode->getId() ;
-      CORBA::Object_var obj = _poa->id_to_reference(*id);
-      SUPERV::FNode_var iobject ;
-      iobject = SUPERV::FNode::_narrow(obj) ;
-      myNode->SetObjRef( SUPERV::FNode::_duplicate( iobject ) ) ;
-      RetVal->FNodes[index] = SUPERV::FNode::_duplicate( iobject ) ;
-    }
-    else if ( aNode->IsInLineNode() ) {
-      INode_Impl * myNode = new INode_Impl( _Orb , _Poa , _ContId ,
-                                instanceName() , interfaceName() ,
-                                DataFlowEditor() ,
-                                (GraphEditor::InNode * ) aNode->GetInNode() ) ;
-      PortableServer::ObjectId * id = myNode->getId() ;
-      CORBA::Object_var obj = _poa->id_to_reference(*id);
-      SUPERV::INode_var iobject ;
-      iobject = SUPERV::INode::_narrow(obj) ;
-      myNode->SetObjRef( SUPERV::INode::_duplicate( iobject ) ) ;
-      RetVal->INodes[index] = SUPERV::INode::_duplicate( iobject ) ;
-    }
-    else if ( aNode->IsGOTONode() ) {
-      GNode_Impl * myNode = new GNode_Impl( _Orb , _Poa , _ContId ,
-                              instanceName() , interfaceName() ,
-                              DataFlowEditor() ,
-                              (GraphEditor::InNode * ) aNode->GetInNode() ) ;
-      PortableServer::ObjectId * id = myNode->getId() ;
-      CORBA::Object_var obj = _poa->id_to_reference(*id);
-      SUPERV::GNode_var iobject ;
-      iobject = SUPERV::GNode::_narrow(obj) ;
-      myNode->SetObjRef( SUPERV::GNode::_duplicate( iobject ) ) ;
-      RetVal->GNodes[index] = SUPERV::GNode::_duplicate( iobject ) ;
-    }
-    else if ( aNode->IsLoopNode() ) {
-      LNode_Impl * myNode = new LNode_Impl( _Orb , _Poa , _ContId ,
-                              instanceName() , interfaceName() ,
-                              DataFlowEditor() ,
-                              (GraphEditor::InNode * ) aNode->GetInNode() ) ;
-      PortableServer::ObjectId * id = myNode->getId() ;
-      CORBA::Object_var obj = _poa->id_to_reference(*id);
-      SUPERV::LNode_var iobject ;
-      iobject = SUPERV::LNode::_narrow(obj) ;
-      myNode->SetObjRef( SUPERV::LNode::_duplicate( iobject ) ) ;
-      RetVal->LNodes[index] = SUPERV::LNode::_duplicate( iobject ) ;
-    }
-    else if ( aNode->IsEndLoopNode() ) {
-      ELNode_Impl * myNode = new ELNode_Impl( _Orb , _Poa , _ContId ,
-                              instanceName() , interfaceName() ,
-                              DataFlowEditor() ,
-                              (GraphEditor::InNode * ) aNode->GetInNode() ) ;
-      PortableServer::ObjectId * id = myNode->getId() ;
-      CORBA::Object_var obj = _poa->id_to_reference(*id);
-      SUPERV::ELNode_var iobject ;
-      iobject = SUPERV::ELNode::_narrow(obj) ;
-      myNode->SetObjRef( SUPERV::ELNode::_duplicate( iobject ) ) ;
-      RetVal->ELNodes[index] = SUPERV::ELNode::_duplicate( iobject ) ;
-    }
-    else if ( aNode->IsSwitchNode() ) {
-      SNode_Impl * myNode = new SNode_Impl( _Orb , _Poa , _ContId ,
-                              instanceName() , interfaceName() ,
-                              DataFlowEditor() ,
-                              (GraphEditor::InNode * ) aNode->GetInNode() ) ;
-      PortableServer::ObjectId * id = myNode->getId() ;
-      CORBA::Object_var obj = _poa->id_to_reference(*id);
-      SUPERV::SNode_var iobject ;
-      iobject = SUPERV::SNode::_narrow(obj) ;
-      myNode->SetObjRef( SUPERV::SNode::_duplicate( iobject ) ) ;
-      RetVal->SNodes[index] = SUPERV::SNode::_duplicate( iobject ) ;
-    }
-    else if ( aNode->IsEndSwitchNode() ) {
-      ESNode_Impl * myNode = new ESNode_Impl( _Orb , _Poa , _ContId ,
-                              instanceName() , interfaceName() ,
-                              DataFlowEditor() ,
-                              (GraphEditor::InNode * ) aNode->GetInNode() ) ;
-      PortableServer::ObjectId * id = myNode->getId() ;
-      CORBA::Object_var obj = _poa->id_to_reference(*id);
-      SUPERV::ESNode_var iobject ;
-      iobject = SUPERV::ESNode::_narrow(obj) ;
-      myNode->SetObjRef( SUPERV::ESNode::_duplicate( iobject ) ) ;
-      RetVal->ESNodes[index] = SUPERV::ESNode::_duplicate( iobject ) ;
-    }
+    SetNodeObjRef( (GraphEditor::InNode * ) aNode->GetInNode() ) ;
   }
-  else if ( aNode->IsComputingNode() ) {
-    RetVal->CNodes[index] = SUPERV::CNode::_duplicate( aNode->ObjRef() ) ;
+  SUPERV::CNode_var aNodeObjRef = aNode->ObjRef() ;
+  if ( aNode->IsComputingNode() ) {
+    RetVal->CNodes[index] = SUPERV::CNode::_duplicate( aNodeObjRef ) ;
   }
   else if ( aNode->IsFactoryNode() ) {
-    RetVal->FNodes[index] = SUPERV::FNode::_duplicate( SUPERV::FNode::_narrow( aNode->ObjRef() ) ) ;
+    RetVal->FNodes[index] = SUPERV::FNode::_duplicate( SUPERV::FNode::_narrow( aNodeObjRef ) ) ;
   }
   else if ( aNode->IsInLineNode() ) {
-    RetVal->INodes[index] = SUPERV::INode::_duplicate( SUPERV::INode::_narrow( aNode->ObjRef() ) ) ;
+    RetVal->INodes[index] = SUPERV::INode::_duplicate( SUPERV::INode::_narrow( aNodeObjRef ) ) ;
   }
+#if GOTOMacroNode
+  else if ( aNode->IsGOTONode() || aNode->IsMacroNode() ) {
+#else
   else if ( aNode->IsGOTONode() ) {
-    RetVal->GNodes[index] = SUPERV::GNode::_duplicate( SUPERV::GNode::_narrow( aNode->ObjRef() ) ) ;
+#endif
+    RetVal->GNodes[index] = SUPERV::GNode::_duplicate( SUPERV::GNode::_narrow( aNodeObjRef ) ) ;
+  }
+  else if ( aNode->IsMacroNode() ) {
+    RetVal->Graphs[index] = SUPERV::Graph::_duplicate( SUPERV::Graph::_narrow( aNodeObjRef ) ) ;
   }
   else if ( aNode->IsLoopNode() ) {
-    RetVal->LNodes[index] = SUPERV::LNode::_duplicate( SUPERV::LNode::_narrow( aNode->ObjRef() ) ) ;
+    RetVal->LNodes[index] = SUPERV::LNode::_duplicate( SUPERV::LNode::_narrow( aNodeObjRef ) ) ;
   }
   else if ( aNode->IsEndLoopNode() ) {
-    RetVal->ELNodes[index] = SUPERV::ELNode::_duplicate( SUPERV::ELNode::_narrow( aNode->ObjRef() ) ) ;
+    RetVal->ELNodes[index] = SUPERV::ELNode::_duplicate( SUPERV::ELNode::_narrow( aNodeObjRef ) ) ;
   }
   else if ( aNode->IsSwitchNode() ) {
-    RetVal->SNodes[index] = SUPERV::SNode::_duplicate( SUPERV::SNode::_narrow( aNode->ObjRef() ) ) ;
+    RetVal->SNodes[index] = SUPERV::SNode::_duplicate( SUPERV::SNode::_narrow( aNodeObjRef ) ) ;
   }
    else if ( aNode->IsEndSwitchNode() ) {
-    RetVal->ESNodes[index] = SUPERV::ESNode::_duplicate( SUPERV::ESNode::_narrow( aNode->ObjRef() ) ) ;
+    RetVal->ESNodes[index] = SUPERV::ESNode::_duplicate( SUPERV::ESNode::_narrow( aNodeObjRef ) ) ;
   }
  return ( RetVal._retn() ) ;
 }
@@ -710,27 +1403,65 @@ SUPERV::ListOfNodes * Graph_Impl::Nodes() {
   RetVal->LNodes.length(0) ;
   RetVal->SNodes.length(0) ;
   RetVal->GNodes.length(0) ;
-  int i ;
-  for ( i = 0 ; i < DataFlowEditor()->GraphNodesSize() ; i++ ) {
-    GraphBase::ComputingNode * aNode = DataFlowEditor()->GraphNodes( i ) ;
-    RetVal = SetNode( RetVal , aNode ) ;
-  }
-  char * aStateG = "" ;
-  if ( _DataFlowExecutor ) {
-    aStateG = (char *) _DataFlowExecutor->StateName( _DataFlowExecutor->AutomatonState() ) ;
-  }
-//  MESSAGE("Graph_Impl::Nodes GraphState " << aStateG
-//          << " CNodes " << RetVal->CNodes.length()
-//          << " FNodes " << RetVal->FNodes.length()
-//          << " INodes " << RetVal->INodes.length()
-//          << " GNodes " << RetVal->GNodes.length()
-//          << " LNodes " << RetVal->LNodes.length()
-//          << " ELNodes " << RetVal->ELNodes.length()
-//          << " SNodes " << RetVal->SNodes.length()
-//          << " ESNodes " << RetVal->ESNodes.length() ) ;
-//  if ( _DataFlowExecutor ) {
-//    _DataFlowExecutor->EventList() ;
-//  }
+  RetVal->Graphs.length(0) ;
+  if ( !IsMacro() ) {
+    int i ;
+    MESSAGE( DataFlowEditor()->Graph()->GetGraphNodeSize() << " Nodes in the Map and "
+             << DataFlowEditor()->Graph()->GraphNodesSize() << " Nodes int the Vector" ) ;
+    for ( i = 0 ; i < DataFlowEditor()->Graph()->GraphNodesSize() ; i++ ) {
+      GraphBase::ComputingNode * aNode = DataFlowEditor()->Graph()->GraphNodes( i ) ;
+#if 1
+      MESSAGE( i << ". Vector : " << aNode->Name() << " Map : "
+               << DataFlowEditor()->Graph()->GetGraphNode( aNode->Name() )->Name() ) ;
+#endif
+      RetVal = SetNode( RetVal , aNode ) ;
+    }
+#if 0
+    char * aStateG = "" ;
+    if ( DataFlowExecutor() ) {
+      aStateG = (char *) DataFlowExecutor()->StateName( DataFlowExecutor()->AutomatonState() ) ;
+    }
+    MESSAGE("Graph_Impl::Nodes GraphState " << aStateG << " CNodes " << RetVal->CNodes.length() ) ;
+    for ( i = 0 ; i < RetVal->CNodes.length() ; i++ ) {
+      MESSAGE("           " << RetVal->CNodes[ i ] ->Name() ) ;
+    }
+    MESSAGE("FNodes " << RetVal->FNodes.length() ) ;
+    for ( i = 0 ; i < RetVal->FNodes.length() ; i++ ) {
+      MESSAGE("           " << RetVal->FNodes[ i ] ->Name() ) ;
+    }
+    MESSAGE("INodes " << RetVal->INodes.length() ) ;
+    for ( i = 0 ; i < RetVal->INodes.length() ; i++ ) {
+      MESSAGE("           " << RetVal->INodes[ i ] ->Name() ) ;
+    }
+    MESSAGE("GNodes " << RetVal->GNodes.length() ) ;
+    for ( i = 0 ; i < RetVal->GNodes.length() ; i++ ) {
+      MESSAGE("           " << RetVal->GNodes[ i ] ->Name() ) ;
+    }
+    MESSAGE("LNodes " << RetVal->LNodes.length() ) ;
+    for ( i = 0 ; i < RetVal->LNodes.length() ; i++ ) {
+      MESSAGE("           " << RetVal->LNodes[ i ] ->Name() ) ;
+    }
+    MESSAGE("ELNodes " << RetVal->ELNodes.length() ) ;
+    for ( i = 0 ; i < RetVal->ELNodes.length() ; i++ ) {
+      MESSAGE("           " << RetVal->ELNodes[ i ] ->Name() ) ;
+    }
+    MESSAGE("SNodes " << RetVal->SNodes.length() ) ;
+    for ( i = 0 ; i < RetVal->SNodes.length() ; i++ ) {
+      MESSAGE("           " << RetVal->SNodes[ i ] ->Name() ) ;
+    }
+    MESSAGE("ESNodes " << RetVal->ESNodes.length() ) ;
+    for ( i = 0 ; i < RetVal->ESNodes.length() ; i++ ) {
+      MESSAGE("           " << RetVal->ESNodes[ i ] ->Name() ) ;
+    }
+    MESSAGE("Graphs " << RetVal->Graphs.length() ) ;
+    for ( i = 0 ; i < RetVal->Graphs.length() ; i++ ) {
+      MESSAGE("           " << RetVal->Graphs[ i ] ->Name() ) ;
+    }
+    if ( DataFlowExecutor() ) {
+      DataFlowExecutor()->EventList() ;
+    }
+#endif
+  }
   endService( "Graph_Impl::Nodes" );
   return ( RetVal._retn() ) ;
 }
@@ -743,197 +1474,295 @@ SUPERV::ListOfLinks * Graph_Impl::Links( GraphBase::ComputingNode * theNode ,
                                          const char * anInputParam ) {
   bool begin = true ;
   SUPERV::ListOfLinks_var RetVal = new SUPERV::ListOfLinks ;
-  int i , j , countlink ;
-  countlink = 0 ;
-  for ( i = 0 ; i < DataFlowEditor()->GraphNodesSize() ; i++ ) {
-    GraphEditor::InNode * aNode = NULL ;
-    aNode = (GraphEditor::InNode * ) DataFlowEditor()->GraphNodes( i )->GetInNode() ;
-    bool ToProcess = false ;
-    if ( theNode == NULL ) {
-      ToProcess = true ;
-    }
-    else {
-      if ( !strcmp( theNode->Name() , aNode->Name() ) ) {
-        if ( !theNode->IsEndSwitchNode() ) {
-          ToProcess = true ;
-       }
-      }
-      else if ( theNode->IsEndSwitchNode() ) {
+  RetVal->length( 0 ) ;
+  if ( !IsMacro() ) {
+    int i , j , countlink ;
+    countlink = 0 ;
+    for ( i = 0 ; i < DataFlowEditor()->Graph()->GraphNodesSize() ; i++ ) {
+      GraphEditor::InNode * aNode = NULL ;
+      aNode = (GraphEditor::InNode * ) DataFlowEditor()->Graph()->GraphNodes( i )->GetInNode() ;
+      bool ToProcess = false ;
+      if ( theNode == NULL ) {
         ToProcess = true ;
       }
-    }
-    if ( ToProcess ) {
-      for ( j = 0 ; j < aNode->GetNodeInPortsSize() ; j++ ) {
-        GraphBase::InPort * anInPort = NULL ;
-        anInPort = aNode->GetChangeNodeInPort( j ) ;
-        if ( anInputParam == NULL ||
-             !strcmp( anInPort->PortName() , anInputParam ) ) {
-          if ( anInPort->GetOutPort() ) {
+      else {
+        if ( !strcmp( theNode->Name() , aNode->Name() ) ) {
+          if ( !theNode->IsEndSwitchNode() ) {
+            ToProcess = true ;
+         }
+        }
+        else if ( theNode->IsEndSwitchNode() ) {
+          ToProcess = true ;
+        }
+      }
+      if ( ToProcess ) {
+        for ( j = 0 ; j < aNode->GetNodeInPortsSize() ; j++ ) {
+          GraphBase::InPort * anInPort = NULL ;
+          anInPort = aNode->GetChangeNodeInPort( j ) ;
+          if ( anInputParam == NULL ||
+               !strcmp( anInPort->PortName() , anInputParam ) ) {
             GraphBase::OutPort * anOutPort = NULL ;
             anOutPort = anInPort->GetOutPort() ;
-            if ( strcmp( anOutPort->NodeName() , Name() ) ) {
-              MESSAGE("Graph_Impl::Links " << anOutPort->NodeName() << "("
-                      << anOutPort->PortName() << ") --> " << aNode->Name() << "("
-                      << anInPort->PortName() << ")" ) ;
-              if ( theNode == NULL ||
-                   ( theNode != NULL && theNode->IsEndSwitchNode() &&
-                     !strcmp( theNode->Name() , aNode->Name() ) ) ) {
-                if ( CORBA::is_nil( anOutPort->InPortObjRef( anInPort ) ) ) {
-                  if ( begin ) {
-                    beginService( "Graph_Impl::ListOfLinks" );
-                    begin = false ;
-                  }
-                  GraphEditor::InNode * anOutNode = NULL ;
-                  anOutNode = (GraphEditor::InNode * ) DataFlowEditor()->GetChangeGraphNode( anOutPort->NodeName() )->GetInNode() ;
-                  if ( anOutNode ) {
-                    Link_Impl * myLink = new Link_Impl( _Orb , _Poa , _ContId ,
-                                          instanceName() , interfaceName() ,
-                                          DataFlowEditor() ,
-                                          aNode ,
-                                          anInPort->PortName() ,
-                                          anOutNode ,
-                                          anOutPort->PortName() ,
-                                          false ) ;
-                    PortableServer::ObjectId * id = myLink->getId() ;
-                    CORBA::Object_var obj = _poa->id_to_reference(*id);
-                    SUPERV::Link_var iobject ;
-                    iobject = SUPERV::Link::_narrow(obj) ;
+            if ( anOutPort && !anOutPort->IsDataStream() ) {
+              if ( strcmp( anOutPort->NodeName() , Name() ) ) {
+//                MESSAGE("Graph_Impl::Links " << anOutPort->NodeName() << "("
+//                        << anOutPort->PortName() << ") --> " << aNode->Name() << "("
+//                        << anInPort->PortName() << ")" ) ;
+                if ( theNode == NULL ||
+//PAL8521
+//JR 14.02.2005 : Debug : we must see also that links !
+//                     ( theNode != NULL && !theNode->IsEndSwitchNode() &&
+                       !strcmp( theNode->Name() , aNode->Name() ) ) {
+                  if ( anInPort->IsLoop() || anOutPort->IsLoop() ||
+                       ( aNode->IsEndLoopNode() && !strcmp( aNode->CoupledNode()->Name() ,
+                                                            anOutPort->NodeName() ) ) ) {
+//                    MESSAGE( "Link " << anOutPort->NodeName() << "("
+//                            << anOutPort->PortName() << ") --> " << aNode->Name() << "("
+//                            << anInPort->PortName() << ")" << " ignored" ) ;
+                 }
+                  else if ( CORBA::is_nil( anOutPort->InPortObjRef( anInPort ) ) ) {
+                    if ( begin ) {
+                      beginService( "Graph_Impl::Links" );
+                      begin = false ;
+                    }
+                    GraphEditor::InNode * anOutNode = NULL ;
+                    anOutNode = (GraphEditor::InNode * ) DataFlowEditor()->Graph()->GetChangeGraphNode( anOutPort->NodeName() )->GetInNode() ;
+                    if ( anOutNode ) {
+                      bool Success ;
+                      Link_Impl * myLink = new Link_Impl( _Orb , _Poa , _ContId ,
+                                                          instanceName() , interfaceName() ,
+                                                          DataFlowEditor() ,
+                                                          aNode ,
+                                                          anInPort->PortName() ,
+                                                          anOutNode ,
+                                                          anOutPort->PortName() ,
+                                                          false , true , Success ) ;
+                      if ( Success ) {
+                        PortableServer::ObjectId * id = myLink->getId() ;
+                        CORBA::Object_var obj = _poa->id_to_reference(*id);
+                        SUPERV::Link_var iobject ;
+                        iobject = SUPERV::Link::_narrow(obj) ;
+                        RetVal->length( countlink + 1 ) ;
+                        RetVal[ countlink++ ] = SUPERV::Link::_duplicate( iobject ) ;
+                        anOutPort->AddInPortObjRef( anInPort , SUPERV::Link::_duplicate( iobject ) ) ;
+                     }
+                   }
+                 }
+                  else {
                     RetVal->length( countlink + 1 ) ;
-                    RetVal[ countlink++ ] = SUPERV::Link::_duplicate( iobject ) ;
-                    anOutPort->AddInPortObjRef( anInPort , SUPERV::Link::_duplicate( iobject ) ) ;
+                    RetVal[ countlink++ ] = SUPERV::Link::_duplicate( anOutPort->InPortObjRef( anInPort ) ) ;
                  }
+//                  MESSAGE( "Link " << anOutPort->NodeName() << "("
+//                           << anOutPort->PortName() << ") --> " << aNode->Name() << "("
+//                           << anInPort->PortName() << ")" << " selected" ) ;
                }
                 else {
-                  RetVal->length( countlink + 1 ) ;
-                  RetVal[ countlink++ ] = SUPERV::Link::_duplicate( anOutPort->InPortObjRef( anInPort ) ) ;
+//                  MESSAGE( "Link " << anOutPort->NodeName() << "("
+//                           << anOutPort->PortName() << ") --> " << aNode->Name() << "("
+//                           << anInPort->PortName() << ")" << " skipped" ) ;
                }
              }
-           }
-          }
-       }
+            }
+         }
+        }
       }
-    }
-    for ( j = 0 ; j < aNode->GetNodeOutPortsSize() ; j++ ) {
-      GraphBase::OutPort * anOutPort = aNode->GetChangeNodeOutPort( j ) ;
-      int k ;
-      for ( k = 0 ; k < anOutPort->InPortsSize() ; k++ ) {
-        GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( k ) ;
-        GraphEditor::InNode * toNode = (GraphEditor::InNode * ) DataFlowEditor()->GetChangeGraphNode( anInPort->NodeName() )->GetInNode() ;
-        if ( theNode == NULL ||
-             !strcmp( theNode->Name() , toNode->Name() ) ||
-             !strcmp( theNode->Name() , aNode->Name() ) ) {
-          if ( theNode || ( toNode->IsEndSwitchNode() && !aNode->IsSwitchNode() ) ) {
-            if ( anInputParam == NULL ||
-                 !strcmp( anInPort->PortName() , anInputParam ) ) {
-              if ( CORBA::is_nil( anOutPort->InPortObjRef( anInPort ) ) ) {
-                if ( begin ) {
-                  beginService( "Graph_Impl::ListOfLinks" );
-                  begin = false ;
-                }
-                Link_Impl * myLink = new Link_Impl( _Orb , _Poa , _ContId ,
-                                        instanceName() , interfaceName() ,
-                                        DataFlowEditor() ,
-                                        toNode ,
-                                        anInPort->PortName() ,
-                                        aNode ,
-                                        anOutPort->PortName() ,
-                                        false ) ;
-                PortableServer::ObjectId * id = myLink->getId() ;
-                CORBA::Object_var obj = _poa->id_to_reference(*id);
-                SUPERV::Link_var iobject ;
-                iobject = SUPERV::Link::_narrow(obj) ;
-                RetVal->length( countlink + 1 ) ;
-                RetVal[ countlink++ ] = SUPERV::Link::_duplicate( iobject ) ;
-                anOutPort->AddInPortObjRef( anInPort , SUPERV::Link::_duplicate( iobject ) ) ;
-             }
-              else {
-                RetVal->length( countlink + 1 ) ;
-                RetVal[ countlink++ ] = SUPERV::Link::_duplicate( anOutPort->InPortObjRef( anInPort ) ) ;
+      for ( j = 0 ; j < aNode->GetNodeOutPortsSize() ; j++ ) {
+        GraphBase::OutPort * anOutPort = aNode->GetChangeNodeOutPort( j ) ;
+//        MESSAGE( "Graph_Impl::Links " << aNode->Name() << " Out" << j << " " << anOutPort->PortName() << " "
+//                 << anOutPort->PortStatus() << " PortConnected to " << anOutPort->InPortsSize() << " InPorts" ) ;
+        int k ;
+        for ( k = 0 ; k < anOutPort->InPortsSize() ; k++ ) {
+          GraphBase::InPort * anInPort = anOutPort->ChangeInPorts( k ) ;
+//          MESSAGE( "              -->  In" << k << " " << anInPort->NodeName() << " " << anInPort->PortName()
+//                   << " " << anInPort->PortStatus() ) ;
+          if ( anInPort->IsPortConnected() ) {
+           GraphBase::ComputingNode * aComputingNode = DataFlowEditor()->Graph()->GetChangeGraphNode( anInPort->NodeName() ) ;
+            GraphEditor::InNode * toNode = (GraphEditor::InNode * ) aComputingNode->GetInNode() ;
+            if ( theNode == NULL ||
+                 !strcmp( theNode->Name() , aNode->Name() ) ) {
+              if ( !anInPort->IsDataStream() ) {
+//PAL8521
+//JR 14.02.2005 : Debug : we must see also that links !
+//                if ( theNode || ( toNode->IsEndSwitchNode() && !aNode->IsSwitchNode() ) ) {
+                  if ( anInputParam == NULL ||
+                       !strcmp( anInPort->PortName() , anInputParam ) ) {
+                    if ( anInPort->IsLoop() || anOutPort->IsLoop() ||
+                         ( toNode->IsEndLoopNode() && !strcmp( toNode->CoupledNode()->Name() ,
+                                                               anOutPort->NodeName() ) ) ) {
+//                      MESSAGE( "Link " << anOutPort->NodeName() << "("
+//                              << anOutPort->PortName() << ") --> " << toNode->Name() << "("
+//                              << anInPort->PortName() << ")" << " ignored" ) ;
+                   }
+                    else if ( CORBA::is_nil( anOutPort->InPortObjRef( anInPort ) ) ) {
+                      if ( begin ) {
+                        beginService( "Graph_Impl::Links" );
+                        begin = false ;
+                      }
+                      bool Success ;
+                      Link_Impl * myLink = new Link_Impl( _Orb , _Poa , _ContId ,
+                                                          instanceName() , interfaceName() ,
+                                                          DataFlowEditor() ,
+                                                          toNode ,
+                                                          anInPort->PortName() ,
+                                                          aNode ,
+                                                          anOutPort->PortName() ,
+                                                          false , true , Success ) ;
+                      if ( Success ) {
+                        PortableServer::ObjectId * id = myLink->getId() ;
+                        CORBA::Object_var obj = _poa->id_to_reference(*id);
+                        SUPERV::Link_var iobject ;
+                        iobject = SUPERV::Link::_narrow(obj) ;
+                        RetVal->length( countlink + 1 ) ;
+                        RetVal[ countlink++ ] = SUPERV::Link::_duplicate( iobject ) ;
+                        anOutPort->AddInPortObjRef( anInPort , SUPERV::Link::_duplicate( iobject ) ) ;
+                     }
+                   }
+                    else {
+                      RetVal->length( countlink + 1 ) ;
+                      RetVal[ countlink++ ] = SUPERV::Link::_duplicate( SUPERV::Link::_narrow( anOutPort->InPortObjRef( anInPort ) ) ) ;
+                   }
+//                    MESSAGE( "Link " << anOutPort->NodeName() << "("
+//                             << anOutPort->PortName() << ") --> " << toNode->Name() << "("
+//                             << anInPort->PortName() << ")" << " selected" ) ;
+                 }
+                  else {
+//                    MESSAGE( "Link " << anOutPort->NodeName() << "("
+//                             << anOutPort->PortName() << ") --> " << toNode->Name() << "("
+//                             << anInPort->PortName() << ")" << " skipped" ) ;
+                 }
+//             }
              }
            }
          }
        }
       }
     }
-  }
-  if ( !begin ) {
-    endService( "Graph_Impl::ListOfLinks" );
-  }
-  return ( RetVal._retn() ) ;
-}
 
-SUPERV::ListOfGraphs * Graph_Impl::Graphs() {
-//  beginService( "Graph_Impl::ListOfGraphs" );
-  SUPERV::ListOfGraphs_var RetVal = new SUPERV::ListOfGraphs ;
-  MESSAGE( "Graph_Impl::Graphs not yet implemented" );
-//  endService( "Graph_Impl::ListOfGraphs" );
+#if 0
+    const char * NodeName = "" ;
+    const char * InputParamName = "" ;
+    if ( theNode ) {
+      NodeName = theNode->Name() ;
+    }
+    if ( anInputParam ) {
+      InputParamName = anInputParam ;
+    }
+    MESSAGE( RetVal->length() << " Links of Node " << NodeName << " and of InPort " << InputParamName ) ;
+    for ( i = 0 ; i < (int ) RetVal->length() ; i++ ) {
+      MESSAGE( "Link " << RetVal[i]->OutPort()->Node()->Name() << "("
+               << RetVal[i]->OutPort()->Name() << ") --> "
+               << RetVal[i]->InPort()->Node()->Name() << "("
+               << RetVal[i]->InPort()->Name() << ")" ) ;
+    }
+#endif
+    if ( !begin ) {
+      endService( "Graph_Impl::Links" );
+    }
+  }
   return ( RetVal._retn() ) ;
 }
 
 Engines::Component_ptr Graph_Impl::ComponentRef( const char * aComputerContainer ,
                                                  const char * aComponentName ) {
-  Engines::Container_var myContainer ;
-  Engines::Component_var objComponent ;
-  DataFlowEditor()->StartComponent( 0 , aComputerContainer , aComponentName ,
-                                    myContainer , objComponent ) ;
+  Engines::Component_var objComponent = Engines::Component::_nil() ;
+  if ( !IsMacro() ) {
+    Engines::Container_var myContainer ;
+    DataFlowEditor()->Graph()->StartComponent( 0 , aComputerContainer , aComponentName ,
+                                               myContainer , objComponent ) ;
+  }
   return Engines::Component::_duplicate( objComponent ) ;
 }
 
+char * Graph_Impl::Messages() {
+  beginService( "Graph_Impl::Messages" );
+  string Messages  ;
+  MESSAGE( "Graph_Impl::Messages IsEditing " << DataFlowEditor()->IsEditing() ) ;
+  Messages = DataFlowEditor()->Graph()->Messages() ;
+  DataFlowEditor()->Graph()->ReSetMessages() ;
+  if ( DataFlowExecutor() ) {
+    Messages += DataFlowExecutor()->Graph()->Messages() ;
+    DataFlowExecutor()->Graph()->ReSetMessages() ;
+  }
+  endService( "Graph_Impl::Messages" );
+  return ( CORBA::string_dup( Messages.c_str() ) ) ;
+}
+
 bool Graph_Impl::IsValid() {
 //  beginService( "Graph_Impl::IsValid" );
-  bool RetVal = DataFlowEditor()->IsValid() ;
+  bool RetVal = false ;
+  if ( !IsMacro() ) {
+    RetVal = DataFlowEditor()->IsValid() ;
+  }
 //  endService( "Graph_Impl::IsValid" );
   return RetVal ;
 }
 bool Graph_Impl::IsExecutable() {
 //  beginService( "Graph_Impl::IsExecutable" );
-  bool RetVal = DataFlowEditor()->IsExecutable() ;
+  bool RetVal = false ;
+
+  // asv : 15.11.04 : added "&& GraphMacroLevel() == 0" -> 
+  // subgraphs are not executable by themselves, RetVal = false..
+  if ( !IsMacro() && DataFlowEditor()->Graph()->GraphMacroLevel() == 0 ) {
+    RetVal = DataFlowEditor()->IsExecutable() ;
+  }
 //  endService( "Graph_Impl::IsExecutable" );
   return RetVal ;
 }
-bool Graph_Impl::IsDataFlow() {
-//  beginService( "Graph_Impl::IsDataFlow" );
-  bool RetVal = false ; // = DataFlowEditor()->IsDataFlow() ;
-//  endService( "Graph_Impl::IsDataFlow" );
-  return RetVal ;
-}
 
 bool Graph_Impl::IsEditing() {
-//  beginService( "Graph_Impl::IsEditing" );
-  bool RetVal = DataFlowEditor()->IsEditing() ;
-//  endService( "Graph_Impl::IsEditing" );
+/*
+  bool RetVal = false ;
+  if ( !IsMacro() ) {
+    RetVal = DataFlowEditor()->IsEditing() ;
+  }
   return RetVal ;
+*/
+  if ( IsMacro() )
+    return false;
+  return !IsExecuting();
 }
+
 bool Graph_Impl::IsExecuting() {
-//  beginService( "Graph_Impl::IsExecuting" );
-  bool RetVal = !DataFlowEditor()->IsEditing() ;
-//  endService( "Graph_Impl::IsExecuting" );
+/*
+  bool RetVal = false ;
+  if ( !IsMacro() ) {
+    RetVal = !DataFlowEditor()->IsEditing() ;
+  }
   return RetVal ;
+*/
+  return CNode_Impl::IsExecuting();
 }
 
 bool Graph_Impl::IsReadOnly() {
 //  beginService( "Graph_Impl::IsExecuting" );
-  bool RetVal = DataFlowEditor()->IsReadOnly() ;
+  bool RetVal = false ;
+  if ( !IsMacro() ) {
+    RetVal = DataFlowEditor()->IsReadOnly() ;
+  }
 //  endService( "Graph_Impl::IsExecuting" );
   return RetVal ;
 }
 
-long Graph_Impl::LevelMax() {
+CORBA::Long Graph_Impl::LevelMax() {
 //  beginService( "Graph_Impl::LevelMax" );
-  long RetVal = DataFlowEditor()->LevelMax() ;
+  CORBA::Long RetVal = 0 ;
+  if ( !IsMacro() ) {
+    RetVal = DataFlowEditor()->LevelMax() ;
+  }
 //  endService( "Graph_Impl::LevelMax" );
   return RetVal ;
 }
-SUPERV::ListOfNodes * Graph_Impl::LevelNodes(long aLevel ) {
+SUPERV::ListOfNodes * Graph_Impl::LevelNodes(CORBA::Long aLevel ) {
 //  beginService( "Graph_Impl::LevelNodes" );
   SUPERV::ListOfNodes_var RetVal = new SUPERV::ListOfNodes;
-  int i ;
-  SUPERV::ListOfStrings_var Nodes = DataFlowEditor()->LevelNodes( aLevel ) ;
+  if ( !IsMacro() ) {
+    int i ;
+    SUPERV::ListOfStrings_var Nodes = DataFlowEditor()->LevelNodes( aLevel ) ;
 //  RetVal->length( Nodes->length() );
-  for ( i = 0 ; i < Nodes->length() ; i++ ) {
+    for ( i = 0 ; i < (int ) Nodes->length() ; i++ ) {
 //    char * aNode = Nodes[ i ] ;
-    GraphBase::ComputingNode * aNode = DataFlowEditor()->GetChangeGraphNode( Nodes[ i ] ) ;
-    RetVal = SetNode( RetVal , aNode ) ;
+      GraphBase::ComputingNode * aNode = DataFlowEditor()->Graph()->GetChangeGraphNode( Nodes[ i ] ) ;
+      RetVal = SetNode( RetVal , aNode ) ;
 //    cout << "Graph_Impl::LevelNodes( " << aLevel << " ) " << aNode->Name() << endl ;
 //    CNode_Impl * myNode = new CNode_Impl( _Orb , _Poa , _ContId ,
 //                               instanceName() , interfaceName() ,
@@ -944,99 +1773,136 @@ SUPERV::ListOfNodes * Graph_Impl::LevelNodes(long aLevel ) {
 //    SUPERV::CNode_var iobject ;
 //    iobject = SUPERV::CNode::_narrow(obj) ;
 //    RetVal[i] = SUPERV::CNode::_duplicate( iobject ) ;
+    }
   }
 //  endService( "Graph_Impl::LevelNodes" );
   return ( RetVal._retn() ) ;
 }
-long Graph_Impl::ThreadsMax() {
+CORBA::Long Graph_Impl::ThreadsMax() {
 //  beginService( "Graph_Impl::ThreadsMax" );
-  long RetVal =  DataFlowEditor()->ThreadsMax() ;
+  CORBA::Long RetVal = 0 ;
+  if ( !IsMacro() ) {
+    RetVal =  DataFlowEditor()->ThreadsMax() ;
+  }
 //  endService( "Graph_Impl::ThreadsMax" );
   return RetVal ;
 }
-long Graph_Impl::GraphsNumber() {
-//  beginService( "Graph_Impl::GraphsNumber" );
-  long RetVal =  DataFlowEditor()->GraphsNumber() ;
-//  endService( "Graph_Impl::GraphsNumber" );
-  return RetVal ;
-}
-long Graph_Impl::Threads() {
+CORBA::Long Graph_Impl::Threads() {
 //  beginService( "Node_Impl::Threads" );
-  long RetVal = _DataFlowExecutor->Threads() ;
+  CORBA::Long RetVal = false ;
+  if ( !IsMacro() ) {
+    RetVal = DataFlowExecutor()->Threads() ;
+  }
 //  endService( "Node_Impl::Threads" );
   return RetVal ;
 }
-long Graph_Impl::SuspendedThreads() {
+CORBA::Long Graph_Impl::SuspendedThreads() {
 //  beginService( "Node_Impl::SuspendedThreads" );
-  long RetVal = _DataFlowExecutor->SuspendedThreads() ;
+  CORBA::Long RetVal = false ;
+  if ( !IsMacro() ) {
+    RetVal = DataFlowExecutor()->SuspendedThreads() ;
+  }
 //  endService( "Node_Impl::SuspendedThreads" );
   return RetVal ;
 }
 
 bool Graph_Impl::Begin() {
   bool RetVal = false ;
+  // mkr : IPAL11408 : "Run()" method returns "0" after trying to start graph execution.
+  // If we call Run() method from Python script two times for one graph, we have to be sure,
+  // that first execution of this graph ended (i.e. GraphEditor::DataFlow::Editing() method was called).
+  // Otherwise, the second call of Run() method will return 0. Therefore, we have to waiting for
+  // the first execution finish. 
+  // NB! From GUI we cann't run dataflow if its previous execution not finished.
+  while ( !DataFlowEditor()->IsEditing() ) {} // waiting for the previous execution of this graph ended
   if ( DataFlowEditor()->IsEditing() ) {
-    if ( _DataFlowExecutor ) {
-      MESSAGE( "Graph_Impl::Begin " << _DataFlowExecutor->Threads() << " threads" )
-      if ( _DataFlowExecutor->Threads() ) {
-        _DataFlowExecutor->JoinedWait() ;
-      }
-      delete _DataFlowExecutor ;
-      _DataFlowExecutor = NULL ;
-      DataFlowEditor()->Executor( NULL ) ;
-    }
-    DataFlowEditor()->EditedAfterExecution( false ) ;
-    _ExecNumber += 1 ;
-    char ExecNumber[30] ;
-    sprintf( ExecNumber , "_%d" , _ExecNumber ) ;
-    int len = strlen( _DebugFileName ) ;
-    char * DebugFileName = new char [ len + strlen( ExecNumber ) + 6 ] ;
-    strncpy( DebugFileName , _DebugFileName , len - 4 ) ;
-    DebugFileName[ len - 4 ] = '\0' ;
-    strcat( DebugFileName , ExecNumber ) ;
-    strcat( DebugFileName , "_Exec.log" ) ;
-    GraphBase::SGraph * myGraph = DataFlowEditor()->GetDataFlow() ;
-    _DataFlowExecutor = new GraphExecutor::DataFlow( _Orb , _NamingService ,
-                                                     myGraph->Info.theName.c_str() ,
-                                                     DebugFileName ) ;
-    MESSAGE( "Graph_Impl::Begin : DataFlowExecutor created" );
-    RetVal = _DataFlowExecutor->LoadDataFlow( *myGraph ) ;
+    if ( pthread_mutex_lock( &_MutexExecutorWait ) ) {
+      perror("pthread_mutex_lock _MutexExecutorWait") ;
+      exit( 0 ) ;
+    }
+    DataFlowEditor()->Graph()->ReSetMessages() ; // ==> Only one set of errors messages ...
+    if ( DataFlowExecutor() ) {
+      MESSAGE( "Graph_Impl::Begin " << DataFlowExecutor()->Threads() << " threads" )
+      Editing(); // just in case it was not called before by GUI..
+    }
+    if ( DataFlowEditor()->IsExecutable() ) {
+      DataFlowEditor()->EditedAfterExecution( false ) ;
+      GraphBase::ListOfSGraphs * myListOfGraphs = DataFlowEditor()->GetDataFlows() ;
+
+      GraphExecutor::DataFlow * aDataFlowExecutor ;
+      string dbgfile ;
+      CreateExecutor( _Orb , instanceName() , (*myListOfGraphs)[ 0 ].Info.theName.c_str() , Kind() ,
+                      dbgfile , &aDataFlowExecutor ) ;
+
+      MESSAGE( "Graph_Impl::Begin : DataFlowExecutor created" );
+      if ( !CORBA::is_nil( LoadDataFlows( aDataFlowExecutor, myListOfGraphs , 0 ) ) ) 
+        RetVal = true ;
+  
+      if ( RetVal )
+        DataFlowExecutor()->Graph()->SetObjImpl( DataFlowEditor()->Graph()->ObjImpl() ) ;
+    
+    }
+    if ( pthread_mutex_unlock( &_MutexExecutorWait ) ) {
+      perror("pthread_mutex_unlock _MutexExecutorWait") ;
+      exit( 0 ) ;
+    }
+  }
+  return RetVal ;
+}
+
+/**
+ * run() : was created in order to reduce code dublication, Run() and Start() do the same thing
+ *         except for final call to Executor->Run( bool ) - Run() calls with AndSuspend=false
+ *         and Start() calls with AndSuspend=true flag.  The rest of the actions are the same:
+ *         1. if a MacroNode's coupled graph (MacroLevel>0) -> simply Run() it.
+ *         2. if a Supergraph -> create executor, load dataflow in it (done in Begin()), then - Run() it.
+ */
+bool Graph_Impl::run( const bool andSuspend ) {
+  bool RetVal = false ;
+
+  // if Editing or Finished state, and, naturally, 'this' is not a MacroNode. 
+  if ( ( DataFlowEditor()->IsEditing() || IsDone() ) && !IsMacro() ) {
+
+    if ( DataFlowEditor()->Graph()->GraphMacroLevel() ) {
+      // MacroGraph's Executor was created in recursive function LoadDataflows(Executor), called from
+      // Begin() of Supergraph.  See Begin() and LoadDataflows(Executor) for details.
+      RetVal = true ; 
+    }
+    else {
+      // Create Executor instance and its datamodel
+      RetVal = Begin() ;
+    }
     if ( RetVal ) {
-      DataFlowEditor()->Executor( _DataFlowExecutor ) ;
+      // Set Executing flag to avoid edition operations during execution, EditedAfterExecution=false
+      DataFlowEditor()->Executing() ;
+      DataFlowEditor()->EditedAfterExecution( false ); 
+
+      // THE MAIN RUN METHOD
+      RetVal = DataFlowExecutor()->Run( andSuspend );
     }
   }
   return RetVal ;
+
 }
+
+/**
+ * Run() - called on "Execute" command
+ */
 bool Graph_Impl::Run() {
   beginService( "Graph_Impl::Run" );
-  bool RetVal = false ;
-  if ( DataFlowEditor()->IsEditing() ) {
-    MESSAGE( "Graph_Impl::Run IsEditing" );
-    RetVal = Begin() ;
-    MESSAGE( "Graph_Impl::(Re)Run " );
-    RetVal = CNode_Impl::Run() ;
-  }
-  else {
-    MESSAGE( "Graph_Impl::(Re)Run " );
-    RetVal = CNode_Impl::ReRun() ;
-  }
+  bool RetVal = run( /*andSuspend=*/false ) ;
+  MESSAGE( "Graph_Impl::Run " << DataFlowEditor()->Graph()->Name() << " RetVal " << RetVal ) ;
   endService( "Graph_Impl::Run" );
   return RetVal ;
 }
+
+/**
+ * Run() - called on "Execute step-by-step" command
+ */
 bool Graph_Impl::Start() {
   beginService( "Graph_Impl::Start" );
-  bool RetVal = false ;
-  if ( DataFlowEditor()->IsEditing() ) {
-    MESSAGE( "Graph_Impl::Start IsEditing" );
-    RetVal = Begin() ;
-  }
-  else {
-    RetVal = true ;
-  }
-  if ( RetVal ) {
-    MESSAGE( "Graph_Impl::(Re)Start " );
-    RetVal = ReStart() ;
-  }
+  bool RetVal = run( /*andSuspend=*/true ) ;
+  MESSAGE( "Graph_Impl::Start " << DataFlowEditor()->Graph()->Name() << " RetVal " << RetVal ) ;
   endService( "Graph_Impl::Start" );
   return RetVal ;
 }
@@ -1048,20 +1914,33 @@ bool Graph_Impl::EventNoW( SUPERV::CNode_out aNode ,
   char * aNodeName = NULL ;
   SUPERV::GraphEvent theEvent = SUPERV::UndefinedEvent ;
   SUPERV::GraphState theState = SUPERV::UndefinedState ;
-  if ( !DataFlowEditor()->IsEditing() ) {
-    RetVal = _DataFlowExecutor->Event( & aNodeName , theEvent , theState , false ) ;
+  if ( pthread_mutex_lock( &_MutexExecutorWait ) ) {
+    perror("pthread_mutex_lock _MutexExecutorWait") ;
+    exit( 0 ) ;
+  }
+  if ( DataFlowExecutor() && !IsMacro() &&
+       ( DataFlowExecutor()->GetListSize() || !DataFlowEditor()->IsEditing() ) ) {
+    RetVal = DataFlowExecutor()->Event( & aNodeName , theEvent , theState , false ) ;
 //  endService( "Graph_Impl::Event" );
     if ( strlen( aNodeName ) ) {
       if ( strcmp( aNodeName , Name() ) ) {
-        aNode = GetNode( aNodeName ) ;
+        aNode = Node( aNodeName ) ;
       }
       else {
-        aNode = GetNode() ;
+        aNode = Node() ;
       }
     }
     else {
       aNode = SUPERV::Graph::_duplicate( SUPERV::Graph::_nil() ) ;
     }
+//    cout << "Graph_Impl::EventNoW " << aNode->Name() << " QSize " << DataFlowExecutor()->GetListSize() << endl ;
+  }
+  else {
+//    cout << "Graph_Impl::EventNoW NO DataFlowExecutor() or QSize=0 " << endl ;
+  }
+  if ( pthread_mutex_unlock( &_MutexExecutorWait ) ) {
+    perror("pthread_mutex_unlock _MutexExecutorWait") ;
+    exit( 0 ) ;
   }
   anEvent = theEvent ;
   aState = theState ;
@@ -1076,23 +1955,37 @@ bool Graph_Impl::Event( SUPERV::CNode_out aNode ,
   char * aNodeName = NULL ;
   SUPERV::GraphEvent theEvent = SUPERV::UndefinedEvent ;
   SUPERV::GraphState theState = SUPERV::UndefinedState ;
-  if ( !DataFlowEditor()->IsEditing() ) {
-    RetVal = _DataFlowExecutor->Event( & aNodeName , theEvent , theState ) ;
+  if ( pthread_mutex_lock( &_MutexExecutorWait ) ) {
+    perror("pthread_mutex_lock _MutexExecutorWait") ;
+    exit( 0 ) ;
+  }
+  if ( DataFlowExecutor() && !IsMacro() &&
+       ( DataFlowExecutor()->GetListSize() || !DataFlowEditor()->IsEditing() ) ){
+    RetVal = DataFlowExecutor()->Event( & aNodeName , theEvent , theState ) ;
 //  endService( "Graph_Impl::Event" );
     if ( strlen( aNodeName ) ) {
       if ( strcmp( aNodeName , Name() ) ) {
-        aNode = GetNode( aNodeName ) ;
+        aNode = Node( aNodeName ) ;
       }
       else {
-        aNode = GetNode() ;
+        aNode = Node() ;
       }
     }
     else {
       aNode = SUPERV::Graph::_duplicate( SUPERV::Graph::_nil() ) ;
     }
+//    cout << "Graph_Impl::Event " << aNode->Name() << " QSize " << DataFlowExecutor()->GetListSize() << endl ;
+  }
+  else {
+//    cout << "Graph_Impl::Event NO DataFlowExecutor() or QSize=0 " << endl ;
+  }
+  if ( pthread_mutex_unlock( &_MutexExecutorWait ) ) {
+    perror("pthread_mutex_unlock _MutexExecutorWait") ;
+    exit( 0 ) ;
   }
   anEvent = theEvent ;
   aState = theState ;
+
   return RetVal ;
 }
 
@@ -1104,61 +1997,173 @@ bool Graph_Impl::EventW( SUPERV::CNode_out aNode ,
   char * aNodeName = NULL ;
   SUPERV::GraphEvent theEvent = SUPERV::UndefinedEvent ;
   SUPERV::GraphState theState = SUPERV::UndefinedState ;
-  if ( !DataFlowEditor()->IsEditing() ) {
-    RetVal = _DataFlowExecutor->EventW( & aNodeName , theEvent , theState ) ;
+  if ( pthread_mutex_lock( &_MutexExecutorWait ) ) {
+    perror("pthread_mutex_lock _MutexExecutorWait") ;
+    exit( 0 ) ;
+  }
+  if ( DataFlowExecutor() && !IsMacro() &&
+       ( DataFlowExecutor()->GetListSize() || !DataFlowEditor()->IsEditing() ) ) {
+    RetVal = DataFlowExecutor()->EventW( & aNodeName , theEvent , theState ) ;
     if ( RetVal && strcmp( aNodeName , Name() ) ) {
-      aNode = GetNode( aNodeName ) ;
+      aNode = Node( aNodeName ) ;
     }
     else {
-      aNode = GetNode() ;
+      aNode = Node() ;
     }
   }
+  if ( pthread_mutex_unlock( &_MutexExecutorWait ) ) {
+    perror("pthread_mutex_unlock _MutexExecutorWait") ;
+    exit( 0 ) ;
+  }
   anEvent = theEvent ;
   aState = theState ;
 //  endService( "Graph_Impl::EventW" );
   return RetVal ;
 }
 
-long Graph_Impl::LastLevelDone() {
+CORBA::Long Graph_Impl::EventQSize() {
+//  beginService( "Graph_Impl::EventQSize" );
+  CORBA::Long QSize = -1 ;
+  if ( pthread_mutex_lock( &_MutexExecutorWait ) ) {
+    perror("pthread_mutex_lock _MutexExecutorWait") ;
+    exit( 0 ) ;
+  }
+  if ( DataFlowExecutor() && !IsMacro() ) {
+    QSize = DataFlowExecutor()->EventQSize() ;
+  }
+  if ( pthread_mutex_unlock( &_MutexExecutorWait ) ) {
+    perror("pthread_mutex_unlock _MutexExecutorWait") ;
+    exit( 0 ) ;
+  }
+//  endService( "Graph_Impl::EventQSize" );
+  return QSize ;
+}
+
+CORBA::Long Graph_Impl::LastLevelDone() {
 //  beginService( "Graph_Impl::LastLevelDone" );
-  long RetVal =  _DataFlowExecutor->LastLevelDone() ;
+  if ( pthread_mutex_lock( &_MutexExecutorWait ) ) {
+    perror("pthread_mutex_lock _MutexExecutorWait") ;
+    exit( 0 ) ;
+  }
+  CORBA::Long RetVal = 0 ;
+  if ( DataFlowExecutor() && !IsMacro() ) {
+    RetVal = DataFlowExecutor()->LastLevelDone() ;
+  }
+  if ( pthread_mutex_unlock( &_MutexExecutorWait ) ) {
+    perror("pthread_mutex_unlock _MutexExecutorWait") ;
+    exit( 0 ) ;
+  }
 //  endService( "Graph_Impl::LastLevelDone" );
   return RetVal ;
 }
 
+CORBA::Long Graph_Impl::SubGraphsNumber() {
+//  beginService( "Graph_Impl::SubGraphsNumber" );
+  CORBA::Long RetVal = 0 ;
+  if ( DataFlowEditor()->IsExecutable() && !IsMacro() ) {
+    RetVal = DataFlowEditor()->SubGraphsNumber() ;
+  }
+//  endService( "Graph_Impl::SubGraphsNumber" );
+  return RetVal ;
+}
+
+SUPERV::ListOfNodes * Graph_Impl::SubGraphsNodes( CORBA::Long aSubGraphNumber ) {
+  beginService( "Graph_Impl::SubGraphsNodes" );
+  SUPERV::ListOfNodes_var RetVal = new SUPERV::ListOfNodes ;
+  if ( DataFlowEditor()->IsEditing() && !IsMacro() ) {
+    SUPERV::ListOfNodes * aGraphNodes = Nodes() ;
+    int i ;
+// ComputingNodes
+    for ( i = 0 ; i < (int ) aGraphNodes->CNodes.length() ; i++ ) {
+      SUPERV::CNode_var aNode = (aGraphNodes->CNodes)[ i ] ;
+      if ( aNode->SubGraph() == aSubGraphNumber ) {
+        RetVal = SetNode( RetVal , DataFlowEditor()->Graph()->GetChangeGraphNode( aNode->Name() ) ) ;
+      }
+    }
+// FactoryNodes
+    for ( i = 0 ; i < (int ) aGraphNodes->FNodes.length() ; i++ ) {
+      SUPERV::FNode_var aNode = (aGraphNodes->FNodes)[ i ] ;
+      if ( aNode->SubGraph() == aSubGraphNumber ) {
+        RetVal = SetNode( RetVal , DataFlowEditor()->Graph()->GetChangeGraphNode( aNode->Name() ) ) ;
+      }
+    }
+// InLineNodes
+    for ( i = 0 ; i < (int ) aGraphNodes->INodes.length() ; i++ ) {
+      SUPERV::INode_var aNode = (aGraphNodes->INodes)[ i ] ;
+      if ( aNode->SubGraph() == aSubGraphNumber ) {
+        RetVal = SetNode( RetVal , DataFlowEditor()->Graph()->GetChangeGraphNode( aNode->Name() ) ) ;
+      }
+    }
+// GOTONodes
+    for ( i = 0 ; i < (int ) aGraphNodes->GNodes.length() ; i++ ) {
+      SUPERV::GNode_var aNode = (aGraphNodes->GNodes)[ i ] ;
+      if ( aNode->SubGraph() == aSubGraphNumber ) {
+        RetVal = SetNode( RetVal , DataFlowEditor()->Graph()->GetChangeGraphNode( aNode->Name() ) ) ;
+      }
+    }
+// LoopNodes
+    for ( i = 0 ; i < (int ) aGraphNodes->LNodes.length() ; i++ ) {
+      SUPERV::LNode_var aNode = (aGraphNodes->LNodes)[ i ] ;
+      if ( aNode->SubGraph() == aSubGraphNumber ) {
+        RetVal = SetNode( RetVal , DataFlowEditor()->Graph()->GetChangeGraphNode( aNode->Name() ) ) ;
+      }
+    }
+// EndLoopNodes
+    for ( i = 0 ; i < (int ) aGraphNodes->ELNodes.length() ; i++ ) {
+      SUPERV::ELNode_var aNode = (aGraphNodes->ELNodes)[ i ] ;
+      if ( aNode->SubGraph() == aSubGraphNumber ) {
+        RetVal = SetNode( RetVal , DataFlowEditor()->Graph()->GetChangeGraphNode( aNode->Name() ) ) ;
+      }
+    }
+// SwitchNodes
+    for ( i = 0 ; i < (int ) aGraphNodes->SNodes.length() ; i++ ) {
+      SUPERV::SNode_var aNode = (aGraphNodes->SNodes)[ i ] ;
+      if ( aNode->SubGraph() == aSubGraphNumber ) {
+        RetVal = SetNode( RetVal , DataFlowEditor()->Graph()->GetChangeGraphNode( aNode->Name() ) ) ;
+      }
+    }
+// EndSwitchNodes
+    for ( i = 0 ; i < (int ) aGraphNodes->ESNodes.length() ; i++ ) {
+      SUPERV::ESNode_var aNode = (aGraphNodes->ESNodes)[ i ] ;
+      if ( aNode->SubGraph() == aSubGraphNumber ) {
+        RetVal = SetNode( RetVal , DataFlowEditor()->Graph()->GetChangeGraphNode( aNode->Name() ) ) ;
+      }
+    }
+  }
+  endService( "Graph_Impl::SubGraphsNodes" );
+  return ( RetVal._retn() ) ;
+}
+
 bool Graph_Impl::Merge(const SUPERV::Graph_ptr aGraph ) {
 //  beginService( "Graph_Impl::Merge" );
-  bool RetVal = false ;
-  if ( DataFlowEditor()->IsEditing() ) {
-    SUPERV::ListOfNodes * aGraphNodes = aGraph->Nodes() ;
-    SUPERV::ListOfLinks * aGraphLinks = aGraph->Links() ;
-    SUPERV::ListOfPorts * aGraphPorts = aGraph->Ports() ;
+  bool RetVal = true ;
+  if ( !IsMacro() ) {
+    map< string , int > aMapOfNodes ;
+    RetVal = Merge( aGraph , aMapOfNodes ) ;
+  }
+//  endService( "Graph_Impl::Merge" );
+  return RetVal ;
+}
 
+bool Graph_Impl::Merge(const SUPERV::Graph_ptr aGraph , map< string , int > & aMapOfNodes ) {
+  beginService( "Graph_Impl::Merge" );
+  bool RetVal = true ;
+  if ( DataFlowEditor()->IsEditing() && !IsMacro() ) {
+    SUPERV::ListOfNodes * aGraphNodes = aGraph->Nodes() ;
     int i ;
-    map< string , int > aMapOfNodes ;
-    for ( i = 0 ; i < aGraphNodes->CNodes.length() ; i++ ) {
+    SUPERV::Port_ptr aPort ;
+//    SUPERV::StreamPort_ptr aStreamPort ;
+// ComputingNodes
+    for ( i = 0 ; i < (int ) aGraphNodes->CNodes.length() ; i++ ) {
       SUPERV::CNode_var aNode = (aGraphNodes->CNodes)[ i ] ;
-      GraphEditor::InNode * myNode ;
-      GraphBase::ListOfFuncName aFuncName = GraphBase::ListOfFuncName() ;
-      GraphBase::ListOfPythonFunctions aPythonFunction = GraphBase::ListOfPythonFunctions() ;
-      myNode = DataFlowEditor()->AddNode( *(aNode->Service()) ,
-                                          "" ,
-                                          "" ,
-                                          NULL ,
-                                          SUPERV::ComputingNode ,
-                                          aFuncName ,
-                                          aPythonFunction ,
-                                          aNode->CreationDate() ,
-                                          aNode->LastUpdateDate() ,
-                                          aNode->Version() ,
-                                          aNode->Author() ,
-                                          "" ,
-                                          aNode->Comment() ,
-                                          aNode->X() ,
-                                          aNode->Y() ) ;
-      if ( myNode ) {
+      SUPERV::CNode_ptr myNode = CNode( *(aNode->Service()) ) ;
+      if ( !CORBA::is_nil( myNode ) ) {
+        myNode->SetName( aNode->Name() ) ;
+        myNode->SetAuthor( aNode->Author() ) ;
+        myNode->SetComment( aNode->Comment() ) ;
+        myNode->Coords( aNode->X() , aNode->Y() ) ;
         string * aNodetheName = new string( aNode->Name() ) ;
-        aMapOfNodes[ *aNodetheName ] = DataFlowEditor()->GetGraphNodeIndex( myNode->Name() ) ;
+        aMapOfNodes[ *aNodetheName ] = DataFlowEditor()->Graph()->GetGraphNodeIndex( myNode->Name() ) ;
         delete aNodetheName ;
         RetVal = true ;
       }
@@ -1166,88 +2171,384 @@ bool Graph_Impl::Merge(const SUPERV::Graph_ptr aGraph ) {
         RetVal = false ;
         break ;
       }
+// The following informations are now in the service from SALOME_ModuleCatalog
+//      SUPERV::ListOfStreamPorts myStreamPorts = *(aNode->StreamPorts()) ;
+//      int j ;
+//      for ( j = 0 ; j < (int ) myStreamPorts.length() ; j++ ) {
+//        if ( myStreamPorts[ j ]->IsInput() && myStreamPorts[ j ]->IsDataStream() ) {
+//          aStreamPort = myNode->InStreamPort( myStreamPorts[ j ]->Name() , myStreamPorts[ j ]->Type() ) ;
+//        }
+//        else if ( myStreamPorts[ j ]->IsDataStream() ) {
+//          aStreamPort = myNode->OutStreamPort( myStreamPorts[ j ]->Name() , myStreamPorts[ j ]->Type() ) ;
+//        }
+//      }
     }
-    for ( i = 0 ; i < aGraphNodes->FNodes.length() ; i++ ) {
-      SUPERV::FNode_var aNode = (aGraphNodes->FNodes)[ i ] ;
-      GraphEditor::InNode * myNode ;
-      GraphBase::ListOfFuncName aFuncName = GraphBase::ListOfFuncName() ;
-      GraphBase::ListOfPythonFunctions aPythonFunction = GraphBase::ListOfPythonFunctions() ;
-      myNode = DataFlowEditor()->AddNode( *(aNode->Service()) ,
-                                         aNode->GetComponentName() ,
-                                         aNode->GetInterfaceName() ,
-                                         NULL ,
-                                         SUPERV::ComputingNode ,
-                                         aFuncName ,
-                                         aPythonFunction ,
-                                         aNode->CreationDate() ,
-                                         aNode->LastUpdateDate() ,
-                                         aNode->Version() ,
-                                         aNode->Author() ,
-                                         aNode->GetContainer() ,
-                                         aNode->Comment() ,
-                                         aNode->X() ,
-                                         aNode->Y() ) ;
-      if ( myNode ) {
-        string * aNodetheName = new string( aNode->Name() ) ;
-        aMapOfNodes[ *aNodetheName ] = DataFlowEditor()->GetGraphNodeIndex( myNode->Name() ) ;
-        delete aNodetheName ;
-        RetVal = true ;
+// FactoryNodes
+    if ( RetVal ) {
+      for ( i = 0 ; i < (int ) aGraphNodes->FNodes.length() ; i++ ) {
+        SUPERV::FNode_var aNode = (aGraphNodes->FNodes)[ i ] ;
+        SUPERV::FNode_ptr myNode = FNode( aNode->GetComponentName() ,
+                                          aNode->GetInterfaceName() ,
+                                          *(aNode->Service()) ,
+                                         aNode->IsCimpl() ) ; // mkr : PAL11273
+        if ( !CORBA::is_nil( myNode ) ) {
+          myNode->SetName( aNode->Name() ) ;
+          myNode->SetAuthor( aNode->Author() ) ;
+          myNode->SetComment( aNode->Comment() ) ;
+          myNode->Coords( aNode->X() , aNode->Y() ) ;
+          string * aNodetheName = new string( aNode->Name() ) ;
+          aMapOfNodes[ *aNodetheName ] = DataFlowEditor()->Graph()->GetGraphNodeIndex( myNode->Name() ) ;
+          delete aNodetheName ;
+          RetVal = true ;
+        }
+        else {
+          RetVal = false ;
+          break ;
+        }
+// The following informations are now in the service from SALOME_ModuleCatalog
+//        SUPERV::ListOfStreamPorts myStreamPorts = *(aNode->StreamPorts()) ;
+//        int j ;
+//        for ( j = 0 ; j < (int ) myStreamPorts.length() ; j++ ) {
+//          if ( myStreamPorts[ j ]->IsInput() && myStreamPorts[ j ]->IsDataStream() ) {
+//            aStreamPort = myNode->InStreamPort( myStreamPorts[ j ]->Name() , myStreamPorts[ j ]->Type() ) ;
+//          }
+//          else if ( myStreamPorts[ j ]->IsDataStream() ) {
+//            aStreamPort = myNode->OutStreamPort( myStreamPorts[ j ]->Name() , myStreamPorts[ j ]->Type() ) ;
+//          }
+//        }
       }
-      else {
-        RetVal = false ;
-        break ;
+    }
+// InLineNodes
+    if ( RetVal ) {
+      for ( i = 0 ; i < (int ) aGraphNodes->INodes.length() ; i++ ) {
+        SUPERV::INode_var aNode = (aGraphNodes->INodes)[ i ] ;
+        SUPERV::INode_ptr myNode = INode( aNode->PyFuncName() , *(aNode->PyFunction()) ) ;
+        if ( !CORBA::is_nil( myNode ) ) {
+          myNode->SetName( aNode->Name() ) ;
+          myNode->SetAuthor( aNode->Author() ) ;
+          myNode->SetComment( aNode->Comment() ) ;
+          myNode->Coords( aNode->X() , aNode->Y() ) ;
+          string * aNodetheName = new string( aNode->Name() ) ;
+          aMapOfNodes[ *aNodetheName ] = DataFlowEditor()->Graph()->GetGraphNodeIndex( myNode->Name() ) ;
+          delete aNodetheName ;
+          SUPERV::ListOfPorts myPorts = *(aNode->Ports()) ;
+          int j ;
+          for ( j = 0 ; j < (int ) myPorts.length() ; j++ ) {
+            if ( myPorts[ j ]->IsInput() ) {
+              aPort = myNode->InPort( myPorts[ j ]->Name() , myPorts[ j ]->Type() ) ;
+           }
+            else {
+              aPort = myNode->OutPort( myPorts[ j ]->Name() , myPorts[ j ]->Type() ) ;
+           }
+         }
+          if ( DataFlowEditor()->Graph()->IsDataStreamNode() ) {
+            SUPERV::ListOfStreamPorts myStreamPorts = *(aNode->StreamPorts()) ;
+            for ( j = 0 ; j < (int ) myStreamPorts.length() ; j++ ) {
+              if ( myStreamPorts[ j ]->IsInput() ) {
+                aPort = myNode->InStreamPort( myStreamPorts[ j ]->Name() , StringToDataStreamType( myStreamPorts[ j ]->Type() ) , myStreamPorts[ j ]->Dependency() ) ;
+             }
+              else {
+                aPort = myNode->OutStreamPort( myStreamPorts[ j ]->Name() , StringToDataStreamType( myStreamPorts[ j ]->Type() ) , myStreamPorts[ j ]->Dependency() ) ;
+             }
+           }
+         }
+          RetVal = true ;
+        }
+        else {
+          RetVal = false ;
+          break ;
+        }
+      }
+    }
+// GOTONodes
+    if ( RetVal ) {
+      for ( i = 0 ; i < (int ) aGraphNodes->GNodes.length() ; i++ ) {
+        SUPERV::GNode_var aNode = (aGraphNodes->GNodes)[ i ] ;
+        SUPERV::GNode_ptr myNode = GNode( aNode->PyFuncName() , *(aNode->PyFunction()) , aNode->Coupled()->Name() ) ;
+        if ( !CORBA::is_nil( myNode ) ) {
+          myNode->SetName( aNode->Name() ) ;
+          myNode->SetAuthor( aNode->Author() ) ;
+          myNode->SetComment( aNode->Comment() ) ;
+          myNode->Coords( aNode->X() , aNode->Y() ) ;
+          string * aNodetheName = new string( aNode->Name() ) ;
+          aMapOfNodes[ *aNodetheName ] = DataFlowEditor()->Graph()->GetGraphNodeIndex( myNode->Name() ) ;
+          delete aNodetheName ;
+          SUPERV::ListOfPorts myPorts = *(aNode->Ports()) ;
+          int j ;
+          for ( j = 0 ; j < (int ) myPorts.length() ; j++ ) {
+            if ( myPorts[ j ]->IsInput() ) {
+              aPort = myNode->InPort( myPorts[ j ]->Name() , myPorts[ j ]->Type() ) ;
+           }
+            else {
+              aPort = myNode->OutPort( myPorts[ j ]->Name() , myPorts[ j ]->Type() ) ;
+           }
+         }
+          if ( DataFlowEditor()->Graph()->IsDataStreamNode() ) {
+            SUPERV::ListOfStreamPorts myStreamPorts = *(aNode->StreamPorts()) ;
+            for ( j = 0 ; j < (int ) myStreamPorts.length() ; j++ ) {
+              if ( myStreamPorts[ j ]->IsInput() ) {
+                aPort = myNode->InStreamPort( myStreamPorts[ j ]->Name() , StringToDataStreamType( myStreamPorts[ j ]->Type() ) , myStreamPorts[ j ]->Dependency() ) ;
+             }
+              else {
+                aPort = myNode->OutStreamPort( myStreamPorts[ j ]->Name() , StringToDataStreamType( myStreamPorts[ j ]->Type() ) , myStreamPorts[ j ]->Dependency() ) ;
+             }
+           }
+         }
+          RetVal = true ;
+        }
+        else {
+          RetVal = false ;
+          break ;
+        }
+      }
+    }
+// LoopNodes
+    if ( RetVal ) {
+      for ( i = 0 ; i < (int ) aGraphNodes->LNodes.length() ; i++ ) {
+        SUPERV::LNode_var aNode = (aGraphNodes->LNodes)[ i ] ;
+        SUPERV::INode_ptr anEndOfLoop ;
+        SUPERV::LNode_ptr myNode = LNode( aNode->PyInitName() ,
+                                          *(aNode->PyInit()) ,
+                                          aNode->PyMoreName() ,
+                                          *(aNode->PyMore()) ,
+                                          aNode->PyNextName() ,
+                                          *(aNode->PyNext()) ,
+                                          anEndOfLoop ) ;
+        if ( !CORBA::is_nil( myNode ) ) {
+          myNode->SetName( aNode->Name() ) ;
+          myNode->SetAuthor( aNode->Author() ) ;
+          myNode->SetComment( aNode->Comment() ) ;
+          myNode->Coords( aNode->X() , aNode->Y() ) ;
+          string * aNodetheName = new string( aNode->Name() ) ;
+          aMapOfNodes[ *aNodetheName ] = DataFlowEditor()->Graph()->GetGraphNodeIndex( myNode->Name() ) ;
+          delete aNodetheName ;
+          SUPERV::ListOfPorts myPorts = *(aNode->Ports()) ;
+          int j ;
+          for ( j = 0 ; j < (int ) myPorts.length() ; j++ ) {
+            if ( myPorts[ j ]->IsInput() ) {
+              aPort = myNode->InPort( myPorts[ j ]->Name() , myPorts[ j ]->Type() ) ;
+           }
+            else {
+              aPort = myNode->OutPort( myPorts[ j ]->Name() , myPorts[ j ]->Type() ) ;
+           }
+         }
+          if ( DataFlowEditor()->Graph()->IsDataStreamNode() ) {
+            SUPERV::ListOfStreamPorts myStreamPorts = *(aNode->StreamPorts()) ;
+            for ( j = 0 ; j < (int ) myStreamPorts.length() ; j++ ) {
+              if ( myStreamPorts[ j ]->IsInput() ) {
+                aPort = myNode->InStreamPort( myStreamPorts[ j ]->Name() , StringToDataStreamType( myStreamPorts[ j ]->Type() ) , myStreamPorts[ j ]->Dependency() ) ;
+             }
+              else {
+                aPort = myNode->OutStreamPort( myStreamPorts[ j ]->Name() , StringToDataStreamType( myStreamPorts[ j ]->Type() ) , myStreamPorts[ j ]->Dependency() ) ;
+             }
+           }
+         }
+          SUPERV::INode_ptr myEndOfLoop = aNode->Coupled() ;
+          anEndOfLoop->SetName( myEndOfLoop->Name() ) ;
+          anEndOfLoop->SetAuthor( myEndOfLoop->Author() ) ;
+          anEndOfLoop->SetComment( myEndOfLoop->Comment() ) ;
+          anEndOfLoop->Coords( myEndOfLoop->X() , myEndOfLoop->Y() ) ;
+          anEndOfLoop->SetPyFunction( myEndOfLoop->PyFuncName() , *(myEndOfLoop->PyFunction()) ) ;
+          aNodetheName = new string( myEndOfLoop->Name() ) ;
+          aMapOfNodes[ *aNodetheName ] = DataFlowEditor()->Graph()->GetGraphNodeIndex( anEndOfLoop->Name() ) ;
+          if ( DataFlowEditor()->Graph()->IsDataStreamNode() ) {
+            SUPERV::ListOfStreamPorts myStreamLoopPorts = *(myEndOfLoop->StreamPorts()) ;
+            for ( j = 0 ; j < (int ) myStreamLoopPorts.length() ; j++ ) {
+              if ( myStreamLoopPorts[ j ]->IsInput() ) {
+                aPort = myNode->InStreamPort( myStreamLoopPorts[ j ]->Name() , StringToDataStreamType( myStreamLoopPorts[ j ]->Type() ) , myStreamLoopPorts[ j ]->Dependency() ) ;
+             }
+              else {
+                aPort = myNode->OutStreamPort( myStreamLoopPorts[ j ]->Name() , StringToDataStreamType( myStreamLoopPorts[ j ]->Type() ) , myStreamLoopPorts[ j ]->Dependency() ) ;
+             }
+           }
+         }
+          delete aNodetheName ;
+          RetVal = true ;
+        }
+        else {
+          RetVal = false ;
+          break ;
+        }
       }
     }
+// SwitchNodes
     if ( RetVal ) {
-      for ( i = 0 ; i < aGraphLinks->length() ; i++ ) {
+      for ( i = 0 ; i < (int ) aGraphNodes->SNodes.length() ; i++ ) {
+        SUPERV::SNode_var aNode = (aGraphNodes->SNodes)[ i ] ;
+        SUPERV::INode_ptr anEndOfSwitch ;
+        SUPERV::SNode_ptr myNode = SNode( aNode->PyFuncName() , *(aNode->PyFunction()) , anEndOfSwitch ) ;
+        if ( !CORBA::is_nil( myNode ) ) {
+          myNode->SetName( aNode->Name() ) ;
+          myNode->SetAuthor( aNode->Author() ) ;
+          myNode->SetComment( aNode->Comment() ) ;
+          myNode->Coords( aNode->X() , aNode->Y() ) ;
+          string * aNodetheName = new string( aNode->Name() ) ;
+          aMapOfNodes[ *aNodetheName ] = DataFlowEditor()->Graph()->GetGraphNodeIndex( myNode->Name() ) ;
+          delete aNodetheName ;
+          SUPERV::ListOfPorts myPorts = *(aNode->Ports()) ;
+          int j ;
+          for ( j = 0 ; j < (int ) myPorts.length() ; j++ ) {
+            if ( myPorts[ j ]->IsInput() ) {
+              aPort = myNode->InPort( myPorts[ j ]->Name() , myPorts[ j ]->Type() ) ;
+           }
+            else {
+              aPort = myNode->OutPort( myPorts[ j ]->Name() , myPorts[ j ]->Type() ) ;
+           }
+         }
+          if ( DataFlowEditor()->Graph()->IsDataStreamNode() ) {
+            SUPERV::ListOfStreamPorts myStreamPorts = *(aNode->StreamPorts()) ;
+            for ( j = 0 ; j < (int ) myStreamPorts.length() ; j++ ) {
+              if ( myStreamPorts[ j ]->IsInput() ) {
+                aPort = myNode->InStreamPort( myStreamPorts[ j ]->Name() , StringToDataStreamType( myStreamPorts[ j ]->Type() ) , myStreamPorts[ j ]->Dependency() ) ;
+             }
+              else {
+                aPort = myNode->OutStreamPort( myStreamPorts[ j ]->Name() , StringToDataStreamType( myStreamPorts[ j ]->Type() ) , myStreamPorts[ j ]->Dependency() ) ;
+             }
+           }
+         }
+          SUPERV::INode_ptr myEndOfSwitch = aNode->Coupled() ;
+          anEndOfSwitch->SetName( myEndOfSwitch->Name() ) ;
+          anEndOfSwitch->SetAuthor( myEndOfSwitch->Author() ) ;
+          anEndOfSwitch->SetComment( myEndOfSwitch->Comment() ) ;
+          anEndOfSwitch->Coords( myEndOfSwitch->X() , myEndOfSwitch->Y() ) ;
+          anEndOfSwitch->SetPyFunction( myEndOfSwitch->PyFuncName() , *(myEndOfSwitch->PyFunction()) ) ;
+          aNodetheName = new string( myEndOfSwitch->Name() ) ;
+          aMapOfNodes[ *aNodetheName ] = DataFlowEditor()->Graph()->GetGraphNodeIndex( anEndOfSwitch->Name() ) ;
+          delete aNodetheName ;
+          myPorts = *(myEndOfSwitch->Ports()) ;
+          for ( j = 0 ; j < (int ) myPorts.length() ; j++ ) {
+            if ( myPorts[ j ]->IsInput() ) {
+              aPort = anEndOfSwitch->InPort( myPorts[ j ]->Name() , myPorts[ j ]->Type() ) ; // mkr : IPAL11394 (add port to !EndSwitch! node)
+           }
+            else {
+              aPort = anEndOfSwitch->OutPort( myPorts[ j ]->Name() , myPorts[ j ]->Type() ) ; // mkr : IPAL11394 (add port to !EndSwitch! node)
+           }
+         }
+          if ( DataFlowEditor()->Graph()->IsDataStreamNode() ) {
+            SUPERV::ListOfStreamPorts myStreamSwitchPorts = *(myEndOfSwitch->StreamPorts()) ;
+            for ( j = 0 ; j < (int ) myStreamSwitchPorts.length() ; j++ ) {
+              if ( myStreamSwitchPorts[ j ]->IsInput() ) {
+                aPort = anEndOfSwitch->InStreamPort( myStreamSwitchPorts[ j ]->Name() , StringToDataStreamType( myStreamSwitchPorts[ j ]->Type() ) , myStreamSwitchPorts[ j ]->Dependency() ) ; // mkr : IPAL11394 (add port to !EndSwitch! node)
+             }
+              else {
+                aPort = anEndOfSwitch->OutStreamPort( myStreamSwitchPorts[ j ]->Name() , StringToDataStreamType( myStreamSwitchPorts[ j ]->Type() ) , myStreamSwitchPorts[ j ]->Dependency() ) ; // mkr : IPAL11394 (add port to !EndSwitch! node)
+             }
+           }
+         }
+          RetVal = true ;
+        }
+        else {
+          RetVal = false ;
+          break ;
+        }
+      }
+    }
+    if ( RetVal ) {
+      SUPERV::ListOfLinks * aGraphLinks = aGraph->GLinks() ;
+      SUPERV::ListOfPorts * aGraphPorts = aGraph->Ports() ;
+//      cout << "Graph_Impl::Merge " << aGraphLinks->length() << " links " << aGraphPorts->length() << " GraphPorts"
+//           << endl ;
+      for ( i = 0 ; i < (int ) aGraphLinks->length() ; i++ ) {
         SUPERV::Link_var aLink = (*aGraphLinks)[ i ] ;
         SUPERV::Port_var OutPort = aLink->OutPort() ;
         SUPERV::Port_var InPort = aLink->InPort() ;
         string * aLinkFromNodeName = new string( OutPort->Node()->Name() ) ;
         string * aLinkToNodeName = new string( InPort->Node()->Name() ) ;
-        RetVal = DataFlowEditor()->AddLink( DataFlowEditor()->GetGraphNode( aMapOfNodes[ aLinkFromNodeName->c_str() ] )->Name() ,
+        RetVal = DataFlowEditor()->AddLink( DataFlowEditor()->Graph()->GetGraphNode( aMapOfNodes[ aLinkFromNodeName->c_str() ] )->Name() ,
                                            OutPort->Name() ,
-                                           DataFlowEditor()->GetGraphNode( aMapOfNodes[ aLinkToNodeName->c_str() ] )->Name() ,
+                                           DataFlowEditor()->Graph()->GetGraphNode( aMapOfNodes[ aLinkToNodeName->c_str() ] )->Name() ,
                                            InPort->Name() ) ;
+        if ( RetVal ) {
+          CORBA::Long j ;
+          for ( j = 1 ; j <= aLink->CoordsSize() ; j++ ) {
+            CORBA::Long X , Y ;
+            RetVal = aLink->Coords( j , X , Y ) ;
+            if ( !RetVal )
+              break ;
+            RetVal = DataFlowEditor()->AddLinkCoord( DataFlowEditor()->Graph()->GetGraphNode( aMapOfNodes[ aLinkFromNodeName->c_str() ] )->Name() ,
+                                                     OutPort->Name() ,
+                                                     DataFlowEditor()->Graph()->GetGraphNode( aMapOfNodes[ aLinkToNodeName->c_str() ] )->Name() ,
+                                                     InPort->Name() ,
+                                                     j , X , Y ) ;
+            if ( !RetVal ) {
+              break ;
+           }
+         }
+       }
         delete aLinkFromNodeName ;
         delete aLinkToNodeName ;
-        if ( !RetVal )
+        if ( !RetVal ) {
           break ;
-        int j ;
-        for ( j = 1 ; j <= aLink->CoordsSize() ; j++ ) {
-          long X , Y ;
-          RetVal = aLink->Coords( j , X , Y ) ;
-          if ( !RetVal )
-            break ;
-          RetVal = DataFlowEditor()->AddLinkCoord( DataFlowEditor()->GetGraphNode( aMapOfNodes[ aLinkFromNodeName->c_str() ] )->Name() ,
-                                                  OutPort->Name() ,
-                                                  DataFlowEditor()->GetGraphNode( aMapOfNodes[ aLinkToNodeName->c_str() ] )->Name() ,
-                                                  InPort->Name() ,
-                                                  j , X , Y ) ;
-          if ( !RetVal )
-            break ;
        }
       }
       if ( RetVal ) {
-        for ( i = 0 ; i < aGraphPorts->length() ; i++ ) {
+        for ( i = 0 ; i < (int ) aGraphPorts->length() ; i++ ) {
           SUPERV::Port_var aPort = (*aGraphPorts)[ i ] ;
-          if ( aPort->HasInput() ) {
-            char * aNode = new char[ strlen( aPort->Name() + 1 ) ] ;
-            strcpy( aNode , aPort->Name() ) ;
-            char * thePort = strchr( aNode , '\\' ) ;
-            thePort[ 0 ] = '\0' ;
-            RetVal = DataFlowEditor()->AddInputData( DataFlowEditor()->GetGraphNode( aMapOfNodes[ aNode ] )->Name() ,
-                                                    thePort + 1 ,
-                                                    *(aPort->ToAny()) ) ;
-            delete aNode ;
-            if ( !RetVal )
+          if ( !aPort->IsGate() ) {
+            MESSAGE( "Graph_Impl::Merge " << i << ". " << aPort->Node()->Name() << " " << aPort->Name() ) ;
+            char * aPortName = aPort->Name() ;
+            char * aNodeName = new char[ strlen( aPortName ) + 1 ] ;
+            strcpy( aNodeName , aPortName ) ;
+//            char * thePortName = strchr( aNodeName , '\\' ) ;
+            char * thePortName = aNodeName ;
+            while ( ( thePortName = strchr( thePortName , '_' ) ) ) {
+              if ( thePortName[1] == '_' ) {
+                thePortName[ 0 ] = '\0' ;
+                break ;
+             }
+              else {
+                thePortName = &thePortName[2] ;
+             }
+           }
+            bool hasinput = aGraph->Node( aNodeName )->Port( thePortName + 2 )->HasInput() ;
+//            cout << "Graph_Impl::Merge " << " aNodeName " << aNodeName << " aPort " << thePortName + 1
+//                 << " HasInput " << hasinput << endl ;
+            if ( hasinput ) {
+              RetVal = DataFlowEditor()->AddInputData( DataFlowEditor()->Graph()->GetGraphNode( aMapOfNodes[ aNodeName ] )->Name() ,
+                                                       thePortName + 2 ,
+                                                       *(aPort->ToAny()) ) ;
+           }
+            delete [] aNodeName ;
+            if ( !RetVal ) {
               break ;
+           }
          }
        }
       }
     }
   }
-//  endService( "Graph_Impl::Merge" );
+  MESSAGE( "Graph_Impl::Merge returns " << RetVal ) ;
+  endService( "Graph_Impl::Merge" );
   return RetVal ;
 }
 
+SUPERV::StreamGraph_ptr Graph_Impl::ToStreamGraph() {
+  SUPERV::StreamGraph_var iobject = SUPERV::StreamGraph::_nil() ;
+  beginService( "Graph_Impl::ToStreamGraph" );
+  if ( IsStreamGraph() && !IsMacro() ) {
+//  StreamGraph_Impl * myStreamGraph = new StreamGraph_Impl( _Orb , _Poa , _ContId ,
+//                                          instanceName() , interfaceName() ) ;
+//  PortableServer::ObjectId * id = myStreamGraph->getId() ;
+//  CORBA::Object_var obj = _poa->id_to_reference(*id);
+    iobject = SUPERV::StreamGraph::_narrow( ObjRef() ) ;
+    if ( CORBA::is_nil( iobject ) ) {
+      MESSAGE( "ToStreamGraph of " << Name() << " (IsStreamGraph) --> nil reference" ) ;
+    }
+  }
+  else {
+    MESSAGE( "ToStreamGraph of " << Name() << " (IsNOTStreamGraph) --> nil reference" ) ;
+  }
+  endService( "Graph_Impl::ToStreamGraph" );
+  return SUPERV::StreamGraph::_duplicate( iobject ) ;
+}
+
+/**
+ * Destroy Executor and use only Editor and its data model
+ */
+void Graph_Impl::Editing() {
+  if ( DataFlowEditor() && DataFlowExecutor() ) {
+    delete DataFlowExecutor() ;
+    DataFlowEditor()->Executor( NULL );
+  }
+}
+