Salome HOME
Join modifications from branch OCC_debug_for_3_2_0b1
[modules/superv.git] / src / Supervision / Graph_Impl.cxx
index abbebd9fb745f418bd52203b9187f8131f8b20a1..5eb33e4115de4dc2c3dd4e85649985eaa880fba5 100644 (file)
@@ -34,35 +34,21 @@ using namespace std;
 
 //#include "utilities.h"
 
-#include "Graph_Impl.hxx"
+#include "SALOME_Container_i.hxx"
+
+#include "StreamGraph_Impl.hxx"
 
 #include "DataFlowEditor_DataFlow.hxx"
 
 extern GraphExecutor::FiniteStateMachine * theAutomaton ;
 
-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 ) :
-  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" );
-  _Orb = CORBA::ORB::_duplicate(orb);
-  _Poa = poa ;
-  _ContId = contId ;
-  if ( aKindOfNode == SUPERV::DataFlowGraph ) {
-    _thisObj = this ;
-    _id = _poa->activate_object(_thisObj);
-  }
-
-  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 ) ;
@@ -70,35 +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() ) ;
+
+  delete [] theDataFlowName ;
+}
+
+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" );
+}
 
-  _NamingService = new SALOME_NamingService( orb ) ;
-  GraphEditor::DataFlow *  aDataFlowEditor ;
-  aDataFlowEditor = new GraphEditor::DataFlow( _Orb , _NamingService ,
-                                               theDataFlowName , _DebugFileName ,
-                                               aKindOfNode ) ;
+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 ;
-  delete [] theDataFlowName ;
-  endService( "Graph_Impl::Graph_Impl" );
+//  DataFlowExecutor( NULL ) ;
+//  endService( "Graph_Impl::Graph_Impl" );  
 }
 
 Graph_Impl::Graph_Impl() {
@@ -111,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();
-//  endService( "Graph_Impl::destroy" );
+//  _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);
@@ -130,16 +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() ,
-                            DataFlowEditor()->Graph()->Name() , SUPERV::DataFlowGraph ) ;
-  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 = 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) ;
 }
@@ -158,103 +306,81 @@ SUPERV::INode_ptr Graph_Impl::Node() {
   return SUPERV::Graph::_duplicate(iobject) ;
 }
 
-GraphBase::SGraph * Graph_Impl::GetGraph() {
-  return DataFlowEditor()->GetDataFlow() ;
+GraphBase::ListOfSGraphs * Graph_Impl::GetGraphs() {
+  return DataFlowEditor()->GetDataFlows() ;
 }
 
-#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 ) ;
-}
-#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 ) ;
+  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" );
   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 ) {
   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() ,
@@ -267,22 +393,27 @@ SUPERV::CNode_ptr Graph_Impl::CNode( const SALOME_ModuleCatalog::Service &NodeSe
       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 ) {
+                                     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,6 +421,7 @@ SUPERV::FNode_ptr Graph_Impl::FNode( const char * NodeComponentName ,
       myNode->SetObjRef( SUPERV::FNode::_duplicate( iobject ) ) ;
     }
   }
+  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() ,
@@ -341,6 +473,7 @@ SUPERV::GNode_ptr Graph_Impl::GNode( const char * FuncName ,
       }
     }
   }
+  DataFlowEditor()->UnValid() ;
   endService( "Graph_Impl::GNode" );
   return SUPERV::GNode::_duplicate( iobject ) ;
 }
@@ -355,7 +488,7 @@ SUPERV::LNode_ptr Graph_Impl::LNode( const char * InitName ,
   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 ;
@@ -402,11 +535,14 @@ SUPERV::LNode_ptr Graph_Impl::LNode( const char * InitName ,
       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 ) ;
 }
@@ -417,7 +553,7 @@ SUPERV::SNode_ptr Graph_Impl::SNode( const char * FuncName ,
   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() ,
@@ -460,10 +596,523 @@ SUPERV::SNode_ptr Graph_Impl::SNode( const char * FuncName ,
     }
   }
   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::Node(char const * aNodeName ) {
 //  beginService( "Graph_Impl::Node" );
@@ -482,12 +1131,14 @@ SUPERV::CNode_ptr Graph_Impl::Node(char const * aNodeName ) {
      else {
      iobject = DataFlowEditor()->GetNode( aNodeName )->ObjRef() ;
   */
-  GraphEditor::InNode * anInNode = DataFlowEditor()->GetNode( aNodeName ) ;
-  if ( anInNode ) {
-    if ( CORBA::is_nil( anInNode->ObjRef() ) ) {
-      SetNodeObjRef( anInNode ) ;
+  if ( !IsMacro() ) {
+    GraphEditor::InNode * anInNode = DataFlowEditor()->GetNode( aNodeName ) ;
+    if ( anInNode ) {
+      if ( CORBA::is_nil( anInNode->ObjRef() ) ) {
+        SetNodeObjRef( anInNode ) ;
+      }
+      iobject = anInNode->ObjRef() ;
     }
-    iobject = anInNode->ObjRef() ;
   }
 //  endService( "Graph_Impl::Node" );
   return SUPERV::CNode::_duplicate( iobject ) ;
@@ -495,44 +1146,65 @@ SUPERV::CNode_ptr Graph_Impl::Node(char const * aNodeName ) {
 
 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() &&
-       !OutPort->IsDataStream() && !InPort->IsDataStream() ) {
-    GraphBase::InPort * anInPort = DataFlowEditor()->GetNode( InPort->Node()->Name() )->ComputingNode()->GetChangeInPort( InPort->Name() ) ;
-    GraphBase::OutPort * anOutPort = DataFlowEditor()->GetNode( OutPort->Node()->Name() )->ComputingNode()->GetChangeOutPort( OutPort->Name() ) ;
-    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 ) ) ;
-       }
-      }
+       !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 {
-      iobject = anOutPort->InPortObjRef( anInPort ) ;
+      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 ) ;
 }
 
+// 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 ,
@@ -564,7 +1236,14 @@ void Graph_Impl::SetNodeObjRef( GraphEditor::InNode * anInNode ) {
     SUPERV::INode_var iobject = SUPERV::INode::_narrow(obj) ;
     myNode->SetObjRef( SUPERV::INode::_duplicate( iobject ) ) ;
   }
+#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() ,
@@ -574,6 +1253,16 @@ void Graph_Impl::SetNodeObjRef( GraphEditor::InNode * anInNode ) {
     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() ,
@@ -619,9 +1308,10 @@ void Graph_Impl::SetNodeObjRef( GraphEditor::InNode * anInNode ) {
 SUPERV::ListOfNodes_var  Graph_Impl::SetNode( SUPERV::ListOfNodes_var RetVal ,
                                               GraphBase::ComputingNode * aNode ) {
   int index = 0 ;
-  if ( _DataFlowExecutor ) {
+//  if ( _DataFlowExecutor ) {
+  if ( DataFlowExecutor() ) {
     MESSAGE("Graph_Impl::SetNode " << aNode->Name() << " " << aNode->Kind() << " "
-            << _DataFlowExecutor->StateName( _DataFlowExecutor->AutomatonState( aNode->Name() ) ) ) ;
+            << DataFlowExecutor()->StateName( DataFlowExecutor()->AutomatonState( aNode->Name() ) ) ) ;
   }
   else {
     MESSAGE("Graph_Impl::SetNode " << aNode->Name() << " " << aNode->Kind() ) ;
@@ -638,10 +1328,18 @@ SUPERV::ListOfNodes_var  Graph_Impl::SetNode( SUPERV::ListOfNodes_var RetVal ,
     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() ;
     RetVal->LNodes.length( index+1 );
@@ -671,9 +1369,16 @@ SUPERV::ListOfNodes_var  Graph_Impl::SetNode( SUPERV::ListOfNodes_var RetVal ,
   else if ( aNode->IsInLineNode() ) {
     RetVal->INodes[index] = SUPERV::INode::_duplicate( SUPERV::INode::_narrow( aNodeObjRef ) ) ;
   }
+#if GOTOMacroNode
+  else if ( aNode->IsGOTONode() || aNode->IsMacroNode() ) {
+#else
   else if ( aNode->IsGOTONode() ) {
+#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( aNodeObjRef ) ) ;
   }
@@ -698,29 +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()->Graph()->GraphNodesSize() ; i++ ) {
-    GraphBase::ComputingNode * aNode = DataFlowEditor()->Graph()->GraphNodes( i ) ;
-    RetVal = SetNode( RetVal , aNode ) ;
-  }
+  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()
-          << " 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() ;
-  }
+    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() ) ;
 }
@@ -734,237 +1475,294 @@ SUPERV::ListOfLinks * Graph_Impl::Links( GraphBase::ComputingNode * theNode ,
   bool begin = true ;
   SUPERV::ListOfLinks_var RetVal = new SUPERV::ListOfLinks ;
   RetVal->length( 0 ) ;
-  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 ;
-    }
-    else {
-      if ( !strcmp( theNode->Name() , aNode->Name() ) ) {
-        if ( !theNode->IsEndSwitchNode() ) {
-          ToProcess = true ;
-       }
-      }
-      else if ( theNode->IsEndSwitchNode() ) {
+  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 ) ) {
-          GraphBase::OutPort * anOutPort = NULL ;
-          anOutPort = anInPort->GetOutPort() ;
-          if ( anOutPort && !anOutPort->IsDataStream() ) {
-            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 ( 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( anOutPort->InPortObjRef( anInPort ) ) ;
-               }
-//                MESSAGE( "Link " << anOutPort->NodeName() << "("
-//                         << anOutPort->PortName() << ") --> " << aNode->Name() << "("
-//                         << anInPort->PortName() << ")" << " selected" ) ;
-             }
-              else {
-//                MESSAGE( "Link " << anOutPort->NodeName() << "("
-//                         << anOutPort->PortName() << ") --> " << aNode->Name() << "("
-//                         << anInPort->PortName() << ")" << " skipped" ) ;
-             }
-           }
-          }
-       }
+      else {
+        if ( !strcmp( theNode->Name() , aNode->Name() ) ) {
+          if ( !theNode->IsEndSwitchNode() ) {
+            ToProcess = true ;
+         }
+        }
+        else if ( theNode->IsEndSwitchNode() ) {
+          ToProcess = true ;
+        }
       }
-    }
-    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()->Graph()->GetChangeGraphNode( anInPort->NodeName() )->GetInNode() ;
-        if ( theNode == NULL ||
-             !strcmp( theNode->Name() , aNode->Name() ) ) {
-          if ( !anInPort->IsDataStream() ) {
-            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 ) ) ;
+      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 ( 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( anOutPort->InPortObjRef( anInPort ) ) ;
+                 }
+//                  MESSAGE( "Link " << anOutPort->NodeName() << "("
+//                           << anOutPort->PortName() << ") --> " << aNode->Name() << "("
+//                           << anInPort->PortName() << ")" << " selected" ) ;
                }
                 else {
-                  RetVal->length( countlink + 1 ) ;
-                  RetVal[ countlink++ ] = SUPERV::Link::_duplicate( SUPERV::Link::_narrow( anOutPort->InPortObjRef( anInPort ) ) ) ;
+//                  MESSAGE( "Link " << anOutPort->NodeName() << "("
+//                           << anOutPort->PortName() << ") --> " << aNode->Name() << "("
+//                           << anInPort->PortName() << ")" << " skipped" ) ;
                }
-//                MESSAGE( "Link " << anOutPort->NodeName() << "("
-//                         << anOutPort->PortName() << ") --> " << toNode->Name() << "("
-//                         << anInPort->PortName() << ")" << " selected" ) ;
              }
-              else {
-//                MESSAGE( "Link " << anOutPort->NodeName() << "("
-//                         << anOutPort->PortName() << ") --> " << toNode->Name() << "("
-//                         << anInPort->PortName() << ")" << " skipped" ) ;
+            }
+         }
+        }
+      }
+      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 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() << ")" ) ;
-  }
+    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" );
+    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()->Graph()->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::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 < (int ) Nodes->length() ; i++ ) {
+    for ( i = 0 ; i < (int ) Nodes->length() ; i++ ) {
 //    char * aNode = Nodes[ i ] ;
-    GraphBase::ComputingNode * aNode = DataFlowEditor()->Graph()->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() ,
@@ -975,64 +1773,74 @@ 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::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 ( pthread_mutex_lock( &_MutexExecutorWait ) ) {
       perror("pthread_mutex_lock _MutexExecutorWait") ;
       exit( 0 ) ;
     }
-    if ( _DataFlowExecutor ) {
-      MESSAGE( "Graph_Impl::Begin " << _DataFlowExecutor->Threads() << " threads" )
-      if ( _DataFlowExecutor->Threads() ) {
-        _DataFlowExecutor->JoinedWait() ;
-      }
-      delete _DataFlowExecutor ;
-      _DataFlowExecutor = NULL ;
-      DataFlowEditor()->Executor( NULL ) ;
-    }
-    DataFlowEditor()->EditedAfterExecution( false ) ;
-    int _ExecNumber = theAutomaton->ExecNumber() ;
-    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 , Kind() ) ;
-    MESSAGE( "Graph_Impl::Begin : DataFlowExecutor created" );
-    RetVal = _DataFlowExecutor->LoadDataFlow( *myGraph ) ;
-    if ( RetVal ) {
-      _DataFlowExecutor->Graph()->SetObjImpl( DataFlowEditor()->Graph()->ObjImpl() ) ;
-      DataFlowEditor()->Executor( _DataFlowExecutor ) ;
+    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") ;
@@ -1041,38 +1849,60 @@ bool Graph_Impl::Begin() {
   }
   return RetVal ;
 }
-bool Graph_Impl::Run() {
-  beginService( "Graph_Impl::Run" );
+
+/**
+ * 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 ( DataFlowEditor()->IsEditing() ) {
-    MESSAGE( "Graph_Impl::Run IsEditing" );
-    RetVal = Begin() ;
+
+  // 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 ) {
-      MESSAGE( "Graph_Impl::(Re)Run " );
-      RetVal = CNode_Impl::Run() ;
+      // Set Executing flag to avoid edition operations during execution, EditedAfterExecution=false
+      DataFlowEditor()->Executing() ;
+      DataFlowEditor()->EditedAfterExecution( false ); 
+
+      // THE MAIN RUN METHOD
+      RetVal = DataFlowExecutor()->Run( andSuspend );
     }
   }
-  else {
-    MESSAGE( "Graph_Impl::(Re)Run " );
-    RetVal = CNode_Impl::ReRun() ;
-  }
+  return RetVal ;
+
+}
+
+/**
+ * Run() - called on "Execute" command
+ */
+bool Graph_Impl::Run() {
+  beginService( "Graph_Impl::Run" );
+  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 ;
 }
@@ -1088,9 +1918,9 @@ bool Graph_Impl::EventNoW( SUPERV::CNode_out aNode ,
     perror("pthread_mutex_lock _MutexExecutorWait") ;
     exit( 0 ) ;
   }
-  if ( _DataFlowExecutor &&
-       ( _DataFlowExecutor->GetListSize() || !DataFlowEditor()->IsEditing() ) ) {
-    RetVal = _DataFlowExecutor->Event( & aNodeName , theEvent , theState , false ) ;
+  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() ) ) {
@@ -1103,10 +1933,10 @@ bool Graph_Impl::EventNoW( SUPERV::CNode_out aNode ,
     else {
       aNode = SUPERV::Graph::_duplicate( SUPERV::Graph::_nil() ) ;
     }
-//    cout << "Graph_Impl::EventNoW " << aNode->Name() << " QSize " << _DataFlowExecutor->GetListSize() << endl ;
+//    cout << "Graph_Impl::EventNoW " << aNode->Name() << " QSize " << DataFlowExecutor()->GetListSize() << endl ;
   }
   else {
-//    cout << "Graph_Impl::EventNoW NO DataFlowExecutor or QSize=0 " << endl ;
+//    cout << "Graph_Impl::EventNoW NO DataFlowExecutor() or QSize=0 " << endl ;
   }
   if ( pthread_mutex_unlock( &_MutexExecutorWait ) ) {
     perror("pthread_mutex_unlock _MutexExecutorWait") ;
@@ -1129,9 +1959,9 @@ bool Graph_Impl::Event( SUPERV::CNode_out aNode ,
     perror("pthread_mutex_lock _MutexExecutorWait") ;
     exit( 0 ) ;
   }
-  if ( _DataFlowExecutor &&
-       ( _DataFlowExecutor->GetListSize() || !DataFlowEditor()->IsEditing() ) ){
-    RetVal = _DataFlowExecutor->Event( & aNodeName , theEvent , theState ) ;
+  if ( DataFlowExecutor() && !IsMacro() &&
+       ( DataFlowExecutor()->GetListSize() || !DataFlowEditor()->IsEditing() ) ){
+    RetVal = DataFlowExecutor()->Event( & aNodeName , theEvent , theState ) ;
 //  endService( "Graph_Impl::Event" );
     if ( strlen( aNodeName ) ) {
       if ( strcmp( aNodeName , Name() ) ) {
@@ -1144,10 +1974,10 @@ bool Graph_Impl::Event( SUPERV::CNode_out aNode ,
     else {
       aNode = SUPERV::Graph::_duplicate( SUPERV::Graph::_nil() ) ;
     }
-//    cout << "Graph_Impl::Event " << aNode->Name() << " QSize " << _DataFlowExecutor->GetListSize() << endl ;
+//    cout << "Graph_Impl::Event " << aNode->Name() << " QSize " << DataFlowExecutor()->GetListSize() << endl ;
   }
   else {
-//    cout << "Graph_Impl::Event NO DataFlowExecutor or QSize=0 " << endl ;
+//    cout << "Graph_Impl::Event NO DataFlowExecutor() or QSize=0 " << endl ;
   }
   if ( pthread_mutex_unlock( &_MutexExecutorWait ) ) {
     perror("pthread_mutex_unlock _MutexExecutorWait") ;
@@ -1155,6 +1985,7 @@ bool Graph_Impl::Event( SUPERV::CNode_out aNode ,
   }
   anEvent = theEvent ;
   aState = theState ;
+
   return RetVal ;
 }
 
@@ -1170,9 +2001,9 @@ bool Graph_Impl::EventW( SUPERV::CNode_out aNode ,
     perror("pthread_mutex_lock _MutexExecutorWait") ;
     exit( 0 ) ;
   }
-  if ( _DataFlowExecutor &&
-       ( _DataFlowExecutor->GetListSize() || !DataFlowEditor()->IsEditing() ) ) {
-    RetVal = _DataFlowExecutor->EventW( & aNodeName , theEvent , theState ) ;
+  if ( DataFlowExecutor() && !IsMacro() &&
+       ( DataFlowExecutor()->GetListSize() || !DataFlowEditor()->IsEditing() ) ) {
+    RetVal = DataFlowExecutor()->EventW( & aNodeName , theEvent , theState ) ;
     if ( RetVal && strcmp( aNodeName , Name() ) ) {
       aNode = Node( aNodeName ) ;
     }
@@ -1190,15 +2021,15 @@ bool Graph_Impl::EventW( SUPERV::CNode_out aNode ,
   return RetVal ;
 }
 
-long Graph_Impl::EventQSize() {
+CORBA::Long Graph_Impl::EventQSize() {
 //  beginService( "Graph_Impl::EventQSize" );
-  long QSize = -1 ;
+  CORBA::Long QSize = -1 ;
   if ( pthread_mutex_lock( &_MutexExecutorWait ) ) {
     perror("pthread_mutex_lock _MutexExecutorWait") ;
     exit( 0 ) ;
   }
-  if ( _DataFlowExecutor ) {
-    QSize = _DataFlowExecutor->EventQSize() ;
+  if ( DataFlowExecutor() && !IsMacro() ) {
+    QSize = DataFlowExecutor()->EventQSize() ;
   }
   if ( pthread_mutex_unlock( &_MutexExecutorWait ) ) {
     perror("pthread_mutex_unlock _MutexExecutorWait") ;
@@ -1208,15 +2039,15 @@ long Graph_Impl::EventQSize() {
   return QSize ;
 }
 
-long Graph_Impl::LastLevelDone() {
+CORBA::Long Graph_Impl::LastLevelDone() {
 //  beginService( "Graph_Impl::LastLevelDone" );
   if ( pthread_mutex_lock( &_MutexExecutorWait ) ) {
     perror("pthread_mutex_lock _MutexExecutorWait") ;
     exit( 0 ) ;
   }
-  long RetVal = 0 ;
-  if ( _DataFlowExecutor ) {
-    RetVal = _DataFlowExecutor->LastLevelDone() ;
+  CORBA::Long RetVal = 0 ;
+  if ( DataFlowExecutor() && !IsMacro() ) {
+    RetVal = DataFlowExecutor()->LastLevelDone() ;
   }
   if ( pthread_mutex_unlock( &_MutexExecutorWait ) ) {
     perror("pthread_mutex_unlock _MutexExecutorWait") ;
@@ -1226,20 +2057,20 @@ long Graph_Impl::LastLevelDone() {
   return RetVal ;
 }
 
-long Graph_Impl::SubGraphsNumber() {
+CORBA::Long Graph_Impl::SubGraphsNumber() {
 //  beginService( "Graph_Impl::SubGraphsNumber" );
-  long RetVal = 0 ;
-  if ( DataFlowEditor()->IsExecutable() ) {
+  CORBA::Long RetVal = 0 ;
+  if ( DataFlowEditor()->IsExecutable() && !IsMacro() ) {
     RetVal = DataFlowEditor()->SubGraphsNumber() ;
   }
 //  endService( "Graph_Impl::SubGraphsNumber" );
   return RetVal ;
 }
 
-SUPERV::ListOfNodes * Graph_Impl::SubGraphsNodes( const long aSubGraphNumber ) {
+SUPERV::ListOfNodes * Graph_Impl::SubGraphsNodes( CORBA::Long aSubGraphNumber ) {
   beginService( "Graph_Impl::SubGraphsNodes" );
   SUPERV::ListOfNodes_var RetVal = new SUPERV::ListOfNodes ;
-  if ( DataFlowEditor()->IsEditing() ) {
+  if ( DataFlowEditor()->IsEditing() && !IsMacro() ) {
     SUPERV::ListOfNodes * aGraphNodes = Nodes() ;
     int i ;
 // ComputingNodes
@@ -1306,8 +2137,10 @@ SUPERV::ListOfNodes * Graph_Impl::SubGraphsNodes( const long aSubGraphNumber ) {
 bool Graph_Impl::Merge(const SUPERV::Graph_ptr aGraph ) {
 //  beginService( "Graph_Impl::Merge" );
   bool RetVal = true ;
-  map< string , int > aMapOfNodes ;
-  RetVal = Merge( aGraph , aMapOfNodes ) ;
+  if ( !IsMacro() ) {
+    map< string , int > aMapOfNodes ;
+    RetVal = Merge( aGraph , aMapOfNodes ) ;
+  }
 //  endService( "Graph_Impl::Merge" );
   return RetVal ;
 }
@@ -1315,7 +2148,7 @@ bool Graph_Impl::Merge(const SUPERV::Graph_ptr aGraph ) {
 bool Graph_Impl::Merge(const SUPERV::Graph_ptr aGraph , map< string , int > & aMapOfNodes ) {
   beginService( "Graph_Impl::Merge" );
   bool RetVal = true ;
-  if ( DataFlowEditor()->IsEditing() ) {
+  if ( DataFlowEditor()->IsEditing() && !IsMacro() ) {
     SUPERV::ListOfNodes * aGraphNodes = aGraph->Nodes() ;
     int i ;
     SUPERV::Port_ptr aPort ;
@@ -1356,7 +2189,8 @@ bool Graph_Impl::Merge(const SUPERV::Graph_ptr aGraph , map< string , int > & aM
         SUPERV::FNode_var aNode = (aGraphNodes->FNodes)[ i ] ;
         SUPERV::FNode_ptr myNode = FNode( aNode->GetComponentName() ,
                                           aNode->GetInterfaceName() ,
-                                          *(aNode->Service()) ) ;
+                                          *(aNode->Service()) ,
+                                         aNode->IsCimpl() ) ; // mkr : PAL11273
         if ( !CORBA::is_nil( myNode ) ) {
           myNode->SetName( aNode->Name() ) ;
           myNode->SetAuthor( aNode->Author() ) ;
@@ -1584,20 +2418,20 @@ bool Graph_Impl::Merge(const SUPERV::Graph_ptr aGraph , map< string , int > & aM
           myPorts = *(myEndOfSwitch->Ports()) ;
           for ( j = 0 ; j < (int ) myPorts.length() ; j++ ) {
             if ( myPorts[ j ]->IsInput() ) {
-              aPort = myNode->InPort( myPorts[ j ]->Name() , myPorts[ j ]->Type() ) ;
+              aPort = anEndOfSwitch->InPort( myPorts[ j ]->Name() , myPorts[ j ]->Type() ) ; // mkr : IPAL11394 (add port to !EndSwitch! node)
            }
             else {
-              aPort = myNode->OutPort( myPorts[ j ]->Name() , myPorts[ j ]->Type() ) ;
+              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 = myNode->InStreamPort( myStreamSwitchPorts[ j ]->Name() , StringToDataStreamType( myStreamSwitchPorts[ j ]->Type() ) , myStreamSwitchPorts[ j ]->Dependency() ) ;
+                aPort = anEndOfSwitch->InStreamPort( myStreamSwitchPorts[ j ]->Name() , StringToDataStreamType( myStreamSwitchPorts[ j ]->Type() ) , myStreamSwitchPorts[ j ]->Dependency() ) ; // mkr : IPAL11394 (add port to !EndSwitch! node)
              }
               else {
-                aPort = myNode->OutStreamPort( myStreamSwitchPorts[ j ]->Name() , StringToDataStreamType( myStreamSwitchPorts[ j ]->Type() ) , myStreamSwitchPorts[ j ]->Dependency() ) ;
+                aPort = anEndOfSwitch->OutStreamPort( myStreamSwitchPorts[ j ]->Name() , StringToDataStreamType( myStreamSwitchPorts[ j ]->Type() ) , myStreamSwitchPorts[ j ]->Dependency() ) ; // mkr : IPAL11394 (add port to !EndSwitch! node)
              }
            }
          }
@@ -1625,9 +2459,9 @@ bool Graph_Impl::Merge(const SUPERV::Graph_ptr aGraph , map< string , int > & aM
                                            DataFlowEditor()->Graph()->GetGraphNode( aMapOfNodes[ aLinkToNodeName->c_str() ] )->Name() ,
                                            InPort->Name() ) ;
         if ( RetVal ) {
-          int j ;
+          CORBA::Long j ;
           for ( j = 1 ; j <= aLink->CoordsSize() ; j++ ) {
-            long X , Y ;
+            CORBA::Long X , Y ;
             RetVal = aLink->Coords( j , X , Y ) ;
             if ( !RetVal )
               break ;
@@ -1655,14 +2489,23 @@ bool Graph_Impl::Merge(const SUPERV::Graph_ptr aGraph , map< string , int > & aM
             char * aPortName = aPort->Name() ;
             char * aNodeName = new char[ strlen( aPortName ) + 1 ] ;
             strcpy( aNodeName , aPortName ) ;
-            char * thePortName = strchr( aNodeName , '\\' ) ;
-            thePortName[ 0 ] = '\0' ;
-            bool hasinput = aGraph->Node( aNodeName )->Port( thePortName + 1 )->HasInput() ;
+//            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 + 1 ,
+                                                       thePortName + 2 ,
                                                        *(aPort->ToAny()) ) ;
            }
             delete [] aNodeName ;
@@ -1682,7 +2525,7 @@ bool Graph_Impl::Merge(const SUPERV::Graph_ptr aGraph , map< string , int > & aM
 SUPERV::StreamGraph_ptr Graph_Impl::ToStreamGraph() {
   SUPERV::StreamGraph_var iobject = SUPERV::StreamGraph::_nil() ;
   beginService( "Graph_Impl::ToStreamGraph" );
-  if ( IsStreamGraph() ) {
+  if ( IsStreamGraph() && !IsMacro() ) {
 //  StreamGraph_Impl * myStreamGraph = new StreamGraph_Impl( _Orb , _Poa , _ContId ,
 //                                          instanceName() , interfaceName() ) ;
 //  PortableServer::ObjectId * id = myStreamGraph->getId() ;
@@ -1699,4 +2542,13 @@ SUPERV::StreamGraph_ptr 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 );
+  }
+}