Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/superv.git] / src / GraphEditor / DataFlowEditor_OutNode.cxx
index cd7876c0a84ae17328c6d2fbc2be163ee8181abf..8e60fccc48552d39238eca0a69fa888cbba18770 100644 (file)
@@ -17,7 +17,7 @@
 //  License along with this library; if not, write to the Free Software 
 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
 // 
-//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 //
 //
 using namespace std;
 #include <sstream>
 #include <iostream>
+#include "DataFlowEditor_DataFlow.hxx"
 #include "DataFlowEditor_OutNode.hxx"
 #include "DataFlowBase_EndOfLoopNode.hxx"
 #include "DataFlowBase_EndOfSwitchNode.hxx"
 
+//map< string , GraphBase::Graph * > GraphEditor::OutNode::_MapOfGraphs;
+map< string , int > _MapOfGraphNames;
+
+string GraphInstanceName( const char * aGraphName ) {
+  // mkr : PAL8004 -->
+  // For Macro nodes : names of subgraphs must be unique and differ from the main dataflow
+  // name (i.e. the dataflow with MacroLevel = 0).
+  // It is neccessary for reqursive call of LoadDataFlows(...) method for MacroNodes execution.
+  int GraphInstanceNumber = _MapOfGraphNames[ aGraphName ] ;
+  string theGraphInstanceName = string( aGraphName ) ;
+  if ( GraphInstanceNumber ) {
+    theGraphInstanceName += "_" ;
+    ostringstream astr ;
+    astr << GraphInstanceNumber ;
+    theGraphInstanceName += astr.str() ;
+  }
+  if ( theGraphInstanceName != string( aGraphName ) )
+    _MapOfGraphNames[ theGraphInstanceName ] = GraphInstanceNumber ;
+  _MapOfGraphNames[ aGraphName ] = GraphInstanceNumber + 1 ;
+  // mkr : PAL8004 <--
+  return theGraphInstanceName ;
+}
+
+
 // Implementation de la classe GraphEditor::Graph
 
-GraphEditor::OutNode::OutNode() :
-             Graph() {
+GraphEditor::OutNode::OutNode() {
+//             Graph() {
   cdebug_in << "GraphEditor::OutNode::OutNode()" << endl;
 
+  _Graph = NULL ;
   _Imported = false ;
   _Valid = false ;
   _Executable = false ;
@@ -47,14 +73,29 @@ GraphEditor::OutNode::OutNode() :
 GraphEditor::OutNode::OutNode( CORBA::ORB_ptr ORB ,
                                SALOME_NamingService * ptrNamingService ,
                                const char * DataFlowName ,
-                               const char * DebugFileName ) :
-             Graph( ORB , ptrNamingService , DataFlowName , DebugFileName ) {
+                               const char * DebugFileName ,
+                               const SUPERV::KindOfNode aKindOfNode ) {
+//             Graph( ORB , ptrNamingService , DataFlowName , DebugFileName ) {
+  _Graph = NULL ;
+  Set_prof_debug( ORB , DebugFileName ) ;
   cdebug_in << "GraphEditor::OutNode::OutNode(" ;
   if ( DataFlowName ) {
     cdebug << DataFlowName ;
   }
   cdebug << ")" << endl;
 
+  if ( aKindOfNode == SUPERV::DataFlowGraph ) {
+    _StreamGraph = NULL ;
+    _Graph = new GraphBase::Graph( ORB , ptrNamingService , DataFlowName , aKindOfNode ,
+                                   _prof_debug , _fdebug ) ; 
+//    MapGraph( _Graph , _Graph->Name() ) ;
+  }
+  else if ( aKindOfNode == SUPERV::DataStreamGraph ) {
+    _StreamGraph = new GraphBase::StreamGraph( ORB , ptrNamingService , DataFlowName , aKindOfNode ,
+                                               _prof_debug , _fdebug ) ;
+    _Graph = _StreamGraph ;
+//    MapGraph( _Graph , _Graph->Name() ) ;
+  }
   _Orb = CORBA::ORB::_duplicate( ORB ) ;
   _Imported = false ;
   _Valid = false ;
@@ -77,13 +118,30 @@ GraphEditor::OutNode::OutNode(
                      const char * DataFlowAuthor ,
                      const char * DataFlowComputer ,
                      const char * DataFlowComment ,
-                     const char * DebugFileName ) :
-             Graph( ORB , ptrNamingService , DataFlowService , DataFlowComponentName ,
-                    DataFlowInterfaceName , DataFlowName , DataFlowkind ,
-                    DataFlowFirstCreation , DataFlowLastModification  ,
-                    DataFlowEditorRelease , DataFlowAuthor ,
-                    DataFlowComputer , DataFlowComment , DebugFileName ) {
-
+                     const char * DebugFileName ) {
+  _Graph = NULL ;
+  Set_prof_debug( ORB , DebugFileName ) ;
+
+  if ( DataFlowkind == SUPERV::DataFlowGraph ) {
+    _StreamGraph = NULL ;
+    _Graph = new GraphBase::Graph( ORB , ptrNamingService , DataFlowService , DataFlowComponentName ,
+                                   DataFlowInterfaceName , DataFlowName , DataFlowkind ,
+                                   DataFlowFirstCreation , DataFlowLastModification  ,
+                                   DataFlowEditorRelease , DataFlowAuthor ,
+                                   DataFlowComputer , DataFlowComment ,
+                                   _prof_debug , _fdebug ) ;
+//    MapGraph( _Graph , _Graph->Name() ) ;
+  }
+  else if ( DataFlowkind == SUPERV::DataStreamGraph ) {
+    _StreamGraph = new GraphBase::StreamGraph( ORB , ptrNamingService , DataFlowService , DataFlowComponentName ,
+                                               DataFlowInterfaceName , DataFlowName , DataFlowkind ,
+                                               DataFlowFirstCreation , DataFlowLastModification  ,
+                                               DataFlowEditorRelease , DataFlowAuthor ,
+                                               DataFlowComputer , DataFlowComment ,
+                                               _prof_debug , _fdebug ) ;
+    _Graph = _StreamGraph ;
+//    MapGraph( _Graph , _Graph->Name() ) ;
+  }
   _Orb = CORBA::ORB::_duplicate( ORB ) ;
   _Imported = false ;
   _Valid = false ;
@@ -92,90 +150,194 @@ GraphEditor::OutNode::OutNode(
 } ;
 
 GraphEditor::OutNode::~OutNode() {
+//  EraseGraph( Graph->Name() ) ;
 //  delete _DataFlowNode ;
 //  delete _DataFlowDatas ;
 //  delete _GT ;
 }
 
-bool GraphEditor::OutNode::LoadDataFlow( const GraphBase::SGraph *aDataFlow ) {
+bool GraphEditor::OutNode::Name( const char * aName ) {
   bool RetVal = false ;
-  cdebug_in << "GraphEditor::OutNode::LoadDataFlow() " << aDataFlow->Info.theName.c_str()
-            << endl;
+//  if ( !GraphName( aName ) ) {
+//    char * aGraphName = Graph()->Name() ;
+    RetVal = Graph()->Name( aName ) ;
+//    if ( RetVal ) {
+//      EraseGraph( aGraphName ) ;
+//      MapGraph( Graph() , aName ) ;
+//    }
+//  }
+  return RetVal ;
+}
+
+void GraphEditor::OutNode::Set_prof_debug( CORBA::ORB_ptr ORB ,
+                                           const char * DebugFileName ) {
+  _Graph_prof_debug = 0 ;
+  _prof_debug = 0 ;
+  if ( DebugFileName ) {
+    _fdebug = new ofstream( DebugFileName );
+    SetDebug( ORB , &_Graph_prof_debug , _fdebug ) ;
+    MESSAGE( endl << "Trace redirected to file " << DebugFileName << endl)
+  }
+}
+
+bool GraphEditor::OutNode::LoadDataFlow( const GraphBase::SGraph * aDataFlow ) {
+  bool RetVal = false ;
+  cdebug_in << "GraphEditor::OutNode::LoadDataFlow() " << (*aDataFlow).Info.theName.c_str()
+            << " GraphNodesSize " << Graph()->GraphNodesSize() << endl;
   if ( !_Imported ) {
-    RetVal = LoadInfo( aDataFlow->Info ) ;
+    RetVal = LoadInfo( (*aDataFlow).Info ) ;
     _Imported = true ;
   }
-  else {
+  else if ( Graph()->IsDataStreamNode() || (*aDataFlow).Info.theKind == SUPERV::DataFlowGraph ) {
     RetVal = true ;
   }
+  cdebug << "GraphEditor::OutNode::LoadDataFlow() _Imported " << _Imported << " RetVal " << RetVal << endl;
 
   map< string , int > aMapOfNodes ;
-  if ( RetVal )
-    RetVal = LoadNodes( aMapOfNodes , aDataFlow->Nodes ) ;
-  if ( RetVal )
-    RetVal = LoadLinks( aMapOfNodes , aDataFlow->Links ) ;
+  if ( RetVal ) {
+    cdebug << "GraphEditor::OutNode::LoadDataFlow() LoadNodes GraphNodesSize " << Graph()->GraphNodesSize() << endl;
+    RetVal = LoadNodes( aMapOfNodes , (*aDataFlow).Nodes ) ;
+  }
+  if ( RetVal ) {
+    cdebug << "GraphEditor::OutNode::LoadDataFlow() LoadLinks GraphNodesSize " << Graph()->GraphNodesSize() << endl;
+    RetVal = LoadLinks( aMapOfNodes , (*aDataFlow).Links ) ;
+  }
   if ( RetVal ) {
     Valid() ;
-    RetVal = LoadDatas( aMapOfNodes , aDataFlow->Datas ) ;
+    cdebug << "GraphEditor::OutNode::LoadDataFlow() LoadDatas GraphNodesSize " << Graph()->GraphNodesSize() << endl;
+    RetVal = LoadDatas( aMapOfNodes , (*aDataFlow).Datas ) ;
   }
-  cdebug_out << "GraphEditor::OutNode::LoadDataFlow" << endl;
+  cdebug_out << "GraphEditor::OutNode::LoadDataFlow done GraphNodesSize " << Graph()->GraphNodesSize()
+             << " _Valid " << _Valid << " _Executable " << _Executable << " RetVal " << RetVal << endl;
   return RetVal ;
 }
 
+bool GraphEditor::OutNode::LoadXml( const char* myFileName , GraphBase::ListOfSGraphs & aListOfDataFlows ) {
+  bool RetVal = false ;
+//  GraphBase::ListOfSGraphs aListOfDataFlows ;
+  if ( myFileName == NULL ) {
+    cdebug << "GraphEditor::OutNode::LoadXml() No file" << endl;
+    _Imported = true ;
+    char * aDataFlowName = Graph()->Name() ;
+//  Name( Graph()->Name() ) ;
+    Name( GraphInstanceName( Graph()->Name() ).c_str() ) ;
+//    MapGraph( Graph() , Graph()->Name() ) ;
+    cdebug << "GraphEditor::OutNode::LoadXml() " << aDataFlowName << " --> " << Graph()->Name() << endl;
+    RetVal = true ;
+  }
+  else {
+    cdebug_in << "GraphEditor::OutNode::LoadXml() " << myFileName << endl;
+    RetVal = Graph()->LoadXml( _Orb , myFileName , aListOfDataFlows ) ;
+//    RetVal = LoadDataFlows( &aListOfDataFlows ) ;
+    cdebug_out << "GraphEditor::OutNode::LoadXml " << RetVal << " " << aListOfDataFlows.size()
+               << " Graphs" << endl;
+  }
+  return RetVal ;
+} 
+
+#if 0
 bool GraphEditor::OutNode::LoadXml( const char* myFileName ) {
   bool RetVal = false ;
-  GraphBase::SGraph aDataFlow ;
+  GraphBase::ListOfSGraphs aListOfDataFlows ;
   if ( myFileName == NULL ) {
     cdebug << "GraphEditor::OutNode::LoadXml() No file" << endl;
     _Imported = true ;
     RetVal = true ;
   }
-  else if ( GraphBase::Graph::LoadXml( _Orb , myFileName , aDataFlow ) ) {
-    cdebug_in << "GraphEditor::OutNode::LoadXml() " << endl;
-    RetVal = LoadDataFlow( &aDataFlow ) ;
+  else if ( Graph()->LoadXml( _Orb , myFileName , aListOfDataFlows ) ) {
+    cdebug_in << "GraphEditor::OutNode::LoadXml() " << myFileName << endl;
+    RetVal = LoadDataFlows( &aListOfDataFlows ) ;
     cdebug_out << "GraphEditor::OutNode::LoadXml " << RetVal << endl;
   }
   return RetVal ;
-} 
+}
+#endif
 
 bool GraphEditor::OutNode::LoadInfo(const GraphBase::SNode &aDataFlowInfo ) {
+  bool RetVal = false ;
   cdebug_in << "GraphEditor::OutNode::LoadInfo " << aDataFlowInfo.theName.c_str()
             << endl ;
-//  MESSAGE( "GraphEditor::OutNode::LoadDataFlow" );
+//  MESSAGE( "GraphEditor::OutNode::LoadInfo" );
 //  ComponentName( aDataFlowInfo.theComponentName.c_str() ) ;
 //  InterfaceName( aDataFlowInfo.theInterfaceName.c_str() ) ;
-  Name( aDataFlowInfo.theName.c_str() ) ;
-  Kind( aDataFlowInfo.theKind ) ;
-  Service( aDataFlowInfo.theService ) ;
-  FirstCreation( aDataFlowInfo.theFirstCreation ) ;
-  LastModification( aDataFlowInfo.theLastModification ) ;
-  EditorRelease( aDataFlowInfo.theEditorRelease.c_str() ) ;
-  Author( aDataFlowInfo.theAuthor.c_str()  ) ;
-//  Computer( aDataFlowInfo.theContainer.c_str() ) ;
-  Comment( aDataFlowInfo.theComment.c_str() ) ;
+  if ( Graph()->IsDataStreamNode() || aDataFlowInfo.theKind == SUPERV::DataFlowGraph ) {
+    char * aDataFlowName = Graph()->Name() ;
+//    Graph()->Name( aDataFlowInfo.theName.c_str() ) ;
+    Graph()->Name( GraphInstanceName( aDataFlowInfo.theName.c_str() ).c_str() ) ;
+//    MapGraph( Graph() , Graph()->Name() ) ;
+    cdebug << "GraphEditor::OutNode::LoadInfo " << aDataFlowName << " --> " << Graph()->Name()
+           << " aDataFlowInfo.Kind " << aDataFlowInfo.theKind << " Kind() " << Graph()->Kind() << endl ;
+    if ( Graph()->IsDataStreamNode() ) {
+      Graph()->Kind( SUPERV::DataStreamGraph ) ;
+      StreamGraph()->SetStreamParams( aDataFlowInfo.theTimeout , aDataFlowInfo.theDataStreamTrace , aDataFlowInfo.theDeltaTime ) ;
+    }
+    else {
+      Graph()->Kind( SUPERV::DataFlowGraph ) ;
+    }
+    Graph()->SetService( aDataFlowInfo.theService ) ;
+    Graph()->FirstCreation( aDataFlowInfo.theFirstCreation ) ;
+    Graph()->LastModification( aDataFlowInfo.theLastModification ) ;
+    Graph()->EditorRelease( aDataFlowInfo.theEditorRelease.c_str() ) ;
+    Graph()->Author( aDataFlowInfo.theAuthor.c_str()  ) ;
+//    Graph()->Computer( aDataFlowInfo.theContainer.c_str() ) ;
+    Graph()->Comment( aDataFlowInfo.theComment.c_str() ) ;
 // Not in OutNode/DataFlow but in InNode/DataFlow_in_an_other_DataFlow
-//  Coordinates( aDataFlowInfo.theX , aDataFlowInfo.theY ) ;
-  cdebug_out << "GraphEditor::OutNode::LoadInfo" << endl ;
-  return true ;
+//    Graph()->Coordinates( aDataFlowInfo.theX , aDataFlowInfo.theY ) ;
+    RetVal = true ;
+  }
+  else {
+    Graph()->Kind( aDataFlowInfo.theKind ) ;
+    cdebug << "GraphEditor::OutNode::LoadInfo aDataFlowInfo.Kind " << aDataFlowInfo.theKind
+           << " != IsDataStreamNode() " << Graph()->IsDataStreamNode() << endl ;
+  }
+  cdebug_out << "GraphEditor::OutNode::LoadInfo " << RetVal << endl ;
+  return RetVal ;
 }
 
 bool GraphEditor::OutNode::LoadNodes(map< string , int > & aMapOfNodes ,
-                                     const GraphBase::ListOfNodes &aListOfNodes ) {
+                                     const GraphBase::ListOfSNodes &aListOfNodes ) {
   GraphEditor::InNode * anInNode ;
-  cdebug_in << "GraphEditor::OutNode::LoadNodes" << endl ;
+  cdebug_in << "GraphEditor::OutNode::LoadNodes " << endl ;
   int i ;
   for ( i = 0 ; i < (int ) aListOfNodes.size() ; i++ ) {
     GraphBase::SNode aNode = aListOfNodes[ i ] ;
     const char * aNodeName = aNode.theName.c_str() ;
+//    cout << "GraphEditor::OutNode::LoadNodes " << aNodeName << " "
+//         << aNode.theService.ServiceinParameter.length() << " InParameters "
+//         << aNode.theService.ServiceoutParameter.length() << " OutParameters "
+//         << aNode.theListOfInDataStreams.size() << " InDataStreams "
+//         << aNode.theListOfOutDataStreams.size() << " OutDataStreams "
+//         << " _prof_debug " << _prof_debug << endl ;
+    cdebug << "GraphEditor::OutNode::LoadNodes " << aNodeName << " "
+           << aNode.theService.ServiceinParameter.length() << " InParameters "
+           << aNode.theService.ServiceoutParameter.length() << " OutParameters "
+           << aNode.theListOfInDataStreams.size() << " InDataStreams "
+           << aNode.theListOfOutDataStreams.size() << " OutDataStreams "
+           << endl ;
     if ( aNode.theListOfFuncName.size() == 0 ) {
       aNode.theListOfFuncName.resize( 1 ) ;
       aNode.theListOfFuncName[ 0 ] = "" ;
       aNode.theListOfPythonFunctions.resize( 1 ) ;
       aNode.theListOfPythonFunctions[ 0 ] = new SUPERV::ListOfStrings() ;
     }
-    if ( GetGraphNode( aNode.theName.c_str() ) ) {
-      aNodeName = NULL ;
+    if ( Graph()->GetGraphNode( aNode.theName.c_str() ) ) {
+      aNodeName = NULLSTRING ;
+    }
+
+    aNode.theService.ServiceinDataStreamParameter.length( aNode.theListOfInDataStreams.size() ) ;
+    aNode.theService.ServiceoutDataStreamParameter.length( aNode.theListOfOutDataStreams.size() ) ;
+    unsigned int j ;
+    for ( j = 0 ; j < aNode.theListOfInDataStreams.size() ; j++ ) {
+      aNode.theService.ServiceinDataStreamParameter[ j ].Parametername = aNode.theListOfInDataStreams[ j ].theDataStreamParameter.Parametername ,
+      aNode.theService.ServiceinDataStreamParameter[ j ].Parametertype = aNode.theListOfInDataStreams[ j ].theDataStreamParameter.Parametertype ,
+      aNode.theService.ServiceinDataStreamParameter[ j ].Parameterdependency = aNode.theListOfInDataStreams[ j ].theDataStreamParameter.Parameterdependency ;
+    }
+    for ( j = 0 ; j < aNode.theListOfOutDataStreams.size() ; j++ ) {
+      aNode.theService.ServiceoutDataStreamParameter[ j ].Parametername = aNode.theListOfOutDataStreams[ j ].theDataStreamParameter.Parametername ,
+      aNode.theService.ServiceoutDataStreamParameter[ j ].Parametertype = aNode.theListOfOutDataStreams[ j ].theDataStreamParameter.Parametertype ,
+      aNode.theService.ServiceoutDataStreamParameter[ j ].Parameterdependency = aNode.theListOfOutDataStreams[ j ].theDataStreamParameter.Parameterdependency ;
     }
+
     anInNode = AddNode( aNode.theService ,
                         aNode.theListOfFuncName ,
                         aNode.theListOfPythonFunctions ,
@@ -187,13 +349,17 @@ bool GraphEditor::OutNode::LoadNodes(map< string , int > & aMapOfNodes ,
                         aNode.theAuthor.c_str() , aNode.theContainer.c_str() ,
                         aNode.theComment.c_str() ,
                         aNode.theCoords.theX , aNode.theCoords.theY ) ;
+
+    // insert container into < ComponentName, Container > map for corresponding component
+    Graph()->InsertToMapOfComponentNameContainer( aNode.theComponentName.c_str(), aNode.theContainer.c_str() ) ; // mkr : PAL13947
+
     string * aNodetheName = new string( aNode.theName ) ;
-    aMapOfNodes[ *aNodetheName ] = GetGraphNodeIndex( anInNode->Name() ) ;
-    if ( anInNode->IsOneOfInLineNodes() ) {
+    aMapOfNodes[ *aNodetheName ] = Graph()->GetGraphNodeIndex( anInNode->Name() ) ;
+    if ( anInNode->IsOneOfInLineNodes() || anInNode->IsMacroNode() ) {
       anInNode->GraphEditor::InNode::InLineNode()->DefPortsOfNode(
                 _Orb , aNode.theService , anInNode->NamePtr() ,
                 anInNode->Kind() ,
-                  Graph_prof_debug() , Graph_fdebug() ) ;
+                _prof_debug , _fdebug ) ;
       GraphBase::InLineNode * aINode = anInNode->InLineNode() ;
       GraphBase::LoopNode * aLNode = NULL ;
       if ( aINode->IsLoopNode() ) {
@@ -205,26 +371,77 @@ bool GraphEditor::OutNode::LoadNodes(map< string , int > & aMapOfNodes ,
         aLNode->SetNextPythonFunction( aNode.theListOfFuncName[ 2 ].c_str() ,
                                        *aNode.theListOfPythonFunctions[ 2 ] ) ;
       }
-      else if ( aINode->IsInLineNode() || aINode->IsGOTONode() ||
+      else if ( aINode->IsMacroNode() || aINode->IsInLineNode() || aINode->IsGOTONode() ||
                 aINode->IsSwitchNode() || aINode->IsEndSwitchNode() ) {
         aINode->SetPythonFunction( aNode.theListOfFuncName[ 0 ].c_str() ,
                                    *aNode.theListOfPythonFunctions[ 0 ] ) ;
       }
     }
+
+    for ( j = 0 ; j < aNode.theListOfInDataStreams.size() ; j++ ) {
+      GraphBase::InPort * anInPort ;
+      if ( anInNode->IsOneOfInLineNodes() ) {
+        anInPort = anInNode->ComputingNode()->AddInDataStreamPort( aNode.theListOfInDataStreams[ j ].theDataStreamParameter.Parametername ,
+                                                                   aNode.theListOfInDataStreams[ j ].theDataStreamParameter.Parametertype ,
+                                                                   aNode.theListOfInDataStreams[ j ].theDataStreamParameter.Parameterdependency ,
+                                                                   SUPERV::DataStreamParameter ) ;
+      }
+      else {
+        anInPort = anInNode->ComputingNode()->GetChangeInPort( aNode.theListOfInDataStreams[ j ].theDataStreamParameter.Parametername ) ;
+      }
+      ((GraphBase::InDataStreamPort * ) anInPort)->SetParams( aNode.theListOfInDataStreams[ j ].theKindOfSchema ,
+                                                              aNode.theListOfInDataStreams[ j ].theKindOfInterpolation ,
+                                                              aNode.theListOfInDataStreams[ j ].theKindOfExtrapolation ) ;
+    }
+    for ( j = 0 ; j < aNode.theListOfOutDataStreams.size() ; j++ ) {
+      GraphBase::OutPort * anOutPort ;
+      if ( anInNode->IsOneOfInLineNodes() ) {
+        anOutPort = anInNode->ComputingNode()->AddOutDataStreamPort( aNode.theListOfOutDataStreams[ j ].theDataStreamParameter.Parametername ,
+                                                                     aNode.theListOfOutDataStreams[ j ].theDataStreamParameter.Parametertype ,
+                                                                     aNode.theListOfOutDataStreams[ j ].theDataStreamParameter.Parameterdependency ,
+                                                                     SUPERV::DataStreamParameter ) ;
+      }
+      else {
+        anOutPort = anInNode->ComputingNode()->GetChangeOutPort( aNode.theListOfOutDataStreams[ j ].theDataStreamParameter.Parametername ) ;
+      }
+      ((GraphBase::OutDataStreamPort * ) anOutPort)->NumberOfValues( aNode.theListOfOutDataStreams[ j ].theNumberOfValues ) ;
+    }
     delete aNodetheName ;
     if ( !anInNode ) {
       return false ;
     }
   }
+
+  // setting coupled pairs of nodes: Loop-EndLoop, Switch-EndSwitch, InLine-GOTO, MacroNode-Graph
   for ( i = 0 ; i < (int ) aListOfNodes.size() ; i++ ) {
     GraphBase::SNode aNode = aListOfNodes[ i ] ;
     cdebug << "GraphEditor::OutNode::LoadNodes " << aNode.theName.c_str() << " Coupled to "
            << aNode.theCoupledNode.c_str() << endl ;
-    anInNode = (GraphEditor::InNode * ) GetChangeGraphNode( aNode.theName.c_str() )->GetInNode() ;
+    anInNode = (GraphEditor::InNode * ) Graph()->GetChangeGraphNode( aMapOfNodes[ aNode.theName.c_str() ] )->GetInNode() ;
+
     if ( anInNode->IsOneOfGOTONodes() && strlen( aNode.theCoupledNode.c_str() ) ) {
-      GraphBase::GOTONode * aCoupledNode ;
-      aCoupledNode = (GraphBase::GOTONode * ) GetGraphNode( aNode.theName.c_str() ) ;
-      aCoupledNode->CoupledNode( (GraphBase::GOTONode * ) GetChangeGraphNode( aNode.theCoupledNode.c_str() ) ) ; 
+      GraphBase::GOTONode * aGOTONode;
+      aGOTONode = (GraphBase::GOTONode * ) anInNode->ComputingNode() ;
+
+      // asv : 25.10.04 : if aNode is a MacroNode, then its coupled node (another Graph) is NOT in aMapOfNodes 
+      //                  and we must couple MacroNode only with name to its subgraph
+      if ( aGOTONode->IsMacroNode() ) {
+        cdebug << "GraphEditor::OutNode::LoadNodes MacroNode " << aNode.theName.c_str()
+              << " is Coupled ONLY WITH NAME to its subgraph " << aNode.theCoupledNode.c_str() << endl;
+        aGOTONode->CoupledNodeName( aNode.theCoupledNode.c_str() ) ;
+      }
+      else { // coupling Loop-EndLoop, Switch-EndSwitch, InLine-GOTO
+       // asv : fix for 6822 : using map because if aNode's name is the same as some existing node's name
+       // aMap will give the correct index any way (aMap has already a different name for aNode, SNode still has old name)
+       int aCoupledNodeIndex = aMapOfNodes[ aNode.theCoupledNode.c_str() ] ;
+       cdebug << "GraphEditor::OutNode::LoadNodes " << aNode.theCoupledNode.c_str()
+              << " index " << aCoupledNodeIndex << endl ;
+        GraphBase::GOTONode * aCoupledNode ;
+        aCoupledNode = (GraphBase::GOTONode * ) Graph()->GetChangeGraphNode( aCoupledNodeIndex ) ;
+        cdebug << "GraphEditor::OutNode::LoadNodes " << aNode.theName.c_str()
+               << " is now Coupled to " << aNode.theCoupledNode.c_str() << endl ;
+        aGOTONode->CoupledNode( aCoupledNode ) ;
+      }
     }
   }
   cdebug_out << "GraphEditor::OutNode::LoadNodes" << endl ;
@@ -232,8 +449,9 @@ bool GraphEditor::OutNode::LoadNodes(map< string , int > & aMapOfNodes ,
 }
 
 bool GraphEditor::OutNode::LoadLinks(map< string , int > & aMapOfNodes ,
-                                     const GraphBase::ListOfLinks &aListOfLinks ) {
+                                     const GraphBase::ListOfSLinks &aListOfLinks ) {
   bool RetVal = true ;
+  bool RetAddLink ;
   cdebug_in << "GraphEditor::OutNode::LoadLinks" << endl ;
 //  MESSAGE( "GraphEditor::OutNode::LoadLinks" );
   int i , j ;
@@ -244,30 +462,27 @@ bool GraphEditor::OutNode::LoadLinks(map< string , int > & aMapOfNodes ,
     cdebug << "LoadLinks " << aLinkFromNodeName->c_str() << "( "
            << aLink.FromServiceParameterName.c_str() << " ) --> "
            << aLinkToNodeName->c_str() << "( "
-           << aLink.FromServiceParameterName.c_str() << " )" << endl ;
-    if ( GetGraphNode( aMapOfNodes[ aLinkFromNodeName->c_str() ] ) &&
-         GetGraphNode( aMapOfNodes[ aLinkToNodeName->c_str() ] ) ) {
-      RetVal = AddLink( GetGraphNode( aMapOfNodes[ aLinkFromNodeName->c_str() ] )->Name() ,
-                        aLink.FromServiceParameterName.c_str() ,
-                        GetGraphNode( aMapOfNodes[ aLinkToNodeName->c_str() ] )->Name() ,
-                        aLink.ToServiceParameterName.c_str() ,
-                        *((GraphBase::ComputingNode *) GetGraphNode( aMapOfNodes[ aLinkFromNodeName->c_str() ] ))->GetOutPort( aLink.FromServiceParameterName.c_str() )->Value() ) ;
+           << aLink.ToServiceParameterName.c_str() << " )" << endl ;
+    if ( Graph()->GetGraphNode( aMapOfNodes[ aLinkFromNodeName->c_str() ] ) &&
+         Graph()->GetGraphNode( aMapOfNodes[ aLinkToNodeName->c_str() ] ) ) {
+//JR 08.02.2005 : Rule of CEA : a bad graph may be stored in a xml
+      RetAddLink = AddLink( Graph()->GetGraphNode( aMapOfNodes[ aLinkFromNodeName->c_str() ] )->Name() ,
+                            aLink.FromServiceParameterName.c_str() ,
+                            Graph()->GetGraphNode( aMapOfNodes[ aLinkToNodeName->c_str() ] )->Name() ,
+                            aLink.ToServiceParameterName.c_str() ) ;
     }
     else {
       RetVal = false ;
     }
-//                      aLink.aLinkValue ) ;
-    if ( !RetVal )
-      break ;
-    else {
+    if ( RetVal && RetAddLink ) {
       for ( j = 0 ; j < (int ) aLink.aListOfCoords.size() ; j++ ) {
-        RetVal = AddLinkCoord( GetGraphNode( aMapOfNodes[ aLinkFromNodeName->c_str() ] )->Name() ,
-                               aLink.FromServiceParameterName.c_str() ,
-                               GetGraphNode( aMapOfNodes[ aLink.ToNodeName.c_str() ] )->Name() ,
-                               aLink.ToServiceParameterName.c_str() ,
-                               j + 1 ,
-                               aLink.aListOfCoords[j].theX ,
-                               aLink.aListOfCoords[j].theY ) ;
+        RetVal = AddLinkCoord( Graph()->GetGraphNode( aMapOfNodes[ aLinkFromNodeName->c_str() ] )->Name() ,
+                                        aLink.FromServiceParameterName.c_str() ,
+                                        Graph()->GetGraphNode( aMapOfNodes[ aLink.ToNodeName.c_str() ] )->Name() ,
+                                        aLink.ToServiceParameterName.c_str() ,
+                                       j + 1 ,
+                                       aLink.aListOfCoords[j].theX ,
+                                       aLink.aListOfCoords[j].theY ) ;
         if ( !RetVal )
           break ;
       }
@@ -275,39 +490,37 @@ bool GraphEditor::OutNode::LoadLinks(map< string , int > & aMapOfNodes ,
     delete aLinkFromNodeName ;
     delete aLinkToNodeName ;
   }
-  cdebug_out << "GraphEditor::OutNode::LoadLinks" << endl ;
+  cdebug_out << "GraphEditor::OutNode::LoadLinks " << RetVal << endl ;
   return RetVal ;
 }
 
 bool GraphEditor::OutNode::LoadDatas(map< string , int > & aMapOfNodes ,
-                                     const GraphBase::ListOfLinks &aListOfDatas ) {
+                                     const GraphBase::ListOfSLinks &aListOfDatas ) {
   bool RetVal = true ;
+  bool RetAddLink ;
   cdebug_in << "GraphEditor::OutNode::LoadDatas" << endl ;
 //  MESSAGE( "GraphEditor::OutNode::LoadDatas" );
   int i ;
   for ( i = 0 ; i < (int ) aListOfDatas.size() ; i++ ) {
     GraphBase::SLink aLink = aListOfDatas[ i ] ;
-    if ( !strcmp( aLink.FromNodeName.c_str() , Name() ) ) {
-      cdebug << "GraphEditor::OutNode::LoadDatas Warning "
-             << aLink.FromNodeName.c_str()
-             << " and " << aLink.ToNodeName.c_str() << " differents from " << Name()
-             << endl ;
-    }
+    cdebug << "OutNode::LoadDatas " << i << aLink.FromNodeName.c_str() << "(" << aLink.FromServiceParameterName
+           << ") --> " << aLink.ToNodeName.c_str() << "(" << aLink.ToServiceParameterName << ") CORBA::tk_xxx "
+           << aLink.aLinkValue.type()->kind() << endl ;
     string * aLinkFromNodeName = new string( aLink.FromNodeName.c_str() ) ;
     string * aLinkToNodeName = new string( aLink.ToNodeName.c_str() ) ;
 //      cout << "LoadDatas " << aLink.FromNodeName.c_str() << " "
 //           << aMapOfNodes[ aLinkFromNodeName->c_str() ] << endl ;
 //      cout << "          " << aLink.ToNodeName.c_str() << " "
 //           << aMapOfNodes[ aLinkToNodeName->c_str() ] << endl ;
-    RetVal = GraphBase::Graph::AddInputData( GetGraphNode( aMapOfNodes[ aLinkToNodeName->c_str() ] )->Name() ,
-                                             aLink.ToServiceParameterName.c_str() ,
-                                             aLink.aLinkValue ) ;
+    RetAddLink = Graph()->AddInputData( Graph()->GetGraphNode( aMapOfNodes[ aLinkToNodeName->c_str() ] )->Name() ,
+                                        aLink.ToServiceParameterName.c_str() ,
+                                        aLink.aLinkValue ) ;
     delete aLinkFromNodeName ;
     delete aLinkToNodeName ;
     if ( !RetVal )
       break ;
   }
-  cdebug_out << "GraphEditor::OutNode::LoadDatas" << endl ;
+  cdebug_out << "GraphEditor::OutNode::LoadDatas " << RetVal << endl ;
   return RetVal ;
 }
 
@@ -316,15 +529,21 @@ bool GraphEditor::OutNode::SaveXml(const char* filename) {
   cdebug_in << "GraphEditor::OutNode::SaveXml(" << filename << ")" << endl;
   ofstream f(filename);
   IsValid() ;
-//  test = SaveXML( f );
-  QDomDocument Graph ;
-  test = SaveXML( Graph );
-  if ( test ) {
-    QString xml = Graph.toString() ;
+  QDomDocument DomGraph ;
+  QDomElement Domsupergraph ;
+  cdebug << "OutNode::SaveXML("<< filename << ") ---> OutNode::SaveXML( ostream & f , QDomDocument & , true "
+         << " , QDomElement & ) " << Graph()->Name() << endl ;
+  test = SaveXML( f , DomGraph , true , Domsupergraph );
+  QString xml = DomGraph.toString() ;
+  f << xml << endl ;
+
+  cdebug << "OutNode::SaveXML("<< filename << ") done" << endl ;
+//  if ( test ) {
+//    QString xml = Graph.toString() ;
 //    cout << "GraphEditor::OutNode::SaveXML " << xml << endl ;
-    f << xml << endl ;
-  }
-  cdebug_out << "GraphEditor::OutNode::SaveXml" << endl;
+//    f << xml << endl ;
+//  }
+  cdebug_out << "GraphEditor::OutNode::SaveXml " << test << endl;
   return test;
 }
 
@@ -334,18 +553,39 @@ bool GraphEditor::OutNode::SavePy( const char* filename ) {
   cdebug_in << "GraphEditor::OutNode::SavePy(" << filename << ")" << endl;
   ofstream f( filename ) ;
   IsValid() ;
-  test = SavePY( f );
-  cdebug_out << "GraphEditor::OutNode::SavePy" << endl;
+  test = SavePY( f , true );
+  f << endl << Graph()->Name() << " = Def" << Graph()->Name() << "()" << endl ;
+  cdebug_out << "GraphEditor::OutNode::SavePy " << test << endl;
   return test;
 }
 
-GraphBase::SGraph * GraphEditor::OutNode::GetDataFlow() {
-  GraphBase::SGraph * aDataFlow = new GraphBase::SGraph;
-  aDataFlow->Info = *GetInfo() ;
-  aDataFlow->Nodes = *GetNodes() ;
-  aDataFlow->Links = *GetLinks( true ) ;
-  aDataFlow->Datas = *GetDatas() ;
-  return aDataFlow ;
+GraphBase::ListOfSGraphs * GraphEditor::OutNode::GetDataFlows( GraphBase::ListOfSGraphs * aListOfDataFlows ) {
+//  GraphBase::ListOfSGraphs * aListOfDataFlows = new GraphBase::ListOfSGraphs;
+  int index = aListOfDataFlows->size() ;
+  aListOfDataFlows->resize( index + 1 ) ;
+  if ( Graph()->IsDataFlowNode() ) {
+    (*aListOfDataFlows)[ index ].Info = *Graph()->GetInfo() ;
+    (*aListOfDataFlows)[ index ].Nodes = *Graph()->GetNodes() ;
+    (*aListOfDataFlows)[ index ].Links = *Graph()->GetLinks( true ) ;
+    (*aListOfDataFlows)[ index ].Datas = *Graph()->GetDatas() ;
+  }
+  else {
+    (*aListOfDataFlows)[ index ].Info = *StreamGraph()->GetInfo() ;
+    (*aListOfDataFlows)[ index ].Nodes = *StreamGraph()->GetNodes() ;
+    (*aListOfDataFlows)[ index ].Links = *StreamGraph()->GetLinks( true ) ;
+    (*aListOfDataFlows)[ index ].Datas = *StreamGraph()->GetDatas() ;
+  }
+  int i ;
+  for ( i = 0 ; i < (int ) (*aListOfDataFlows)[ index ].Nodes.size() ; i++ ) {
+    const GraphBase::ComputingNode * aNode = Graph()->GetGraphNode( (*aListOfDataFlows)[ index ].Nodes[i].theName.c_str() ) ;
+    if ( aNode->IsMacroNode() ) {
+//      string aCoupledNodeName = (*aListOfDataFlows)[ index ].Nodes[i].theCoupledNode ;
+      GraphBase::Graph * aGraph = (GraphBase::Graph * ) ((GraphBase::GOTONode * ) aNode )->CoupledNode() ;
+//      GraphBase::Graph * aGraph = MapGraph( aCoupledNodeName.c_str() ) ;
+      aGraph->GraphEditor()->GraphEditor::OutNode::GetDataFlows( aListOfDataFlows ) ;
+    }
+  }
+  return aListOfDataFlows ;
 }
 
 void GraphEditor::OutNode::DateModification() {
@@ -359,21 +599,21 @@ void GraphEditor::OutNode::DateModification() {
   aLastModificationDate.Day    = Tm->tm_mday;
   aLastModificationDate.Month  = Tm->tm_mon + 1;
   aLastModificationDate.Year   = Tm->tm_year + 1900;
-  LastModification( aLastModificationDate ) ;
+  Graph()->LastModification( aLastModificationDate ) ;
 }
 
 void GraphEditor::OutNode::Coordinates( const char* NodeName ,
                                         const int X ,
                                         const int Y ) {
-  ((GraphEditor::InNode * ) GetChangeGraphNode( NodeName ))->Coordinates( X , Y ) ;
+  ((GraphEditor::InNode * ) Graph()->GetChangeGraphNode( NodeName ))->Coordinates( X , Y ) ;
 }
 
 const int GraphEditor::OutNode::XCoordinate( const char* NodeName ) {
-  return ((GraphEditor::InNode * ) GetChangeGraphNode( NodeName ))->XCoordinate() ;
+  return ((GraphEditor::InNode * ) Graph()->GetChangeGraphNode( NodeName ))->XCoordinate() ;
 }
 
 const int GraphEditor::OutNode::YCoordinate( const char* NodeName ) {
-  return ((GraphEditor::InNode * ) GetChangeGraphNode( NodeName ))->YCoordinate() ;
+  return ((GraphEditor::InNode * ) Graph()->GetChangeGraphNode( NodeName ))->YCoordinate() ;
 }
 
 GraphEditor::InNode * GraphEditor::OutNode::AddNode(
@@ -394,21 +634,30 @@ GraphEditor::InNode * GraphEditor::OutNode::AddNode(
                       const int NodeY ) {
   cdebug_in << "GraphEditor::OutNode::AddNode( " ;
   if ( NodeComponentName != NULLSTRING && strlen( NodeComponentName ) ) {
-    cdebug << NodeComponentName << " , " ;
+    cdebug << "Component('" << NodeComponentName << "') , Node('" ;
   }
   else {
     cdebug << "NodeComponentName[NULL] )" << endl;
   }
+  if ( theNodeName == NULL ) {
+    theNodeName = NULLSTRING ;
+  }
   if ( theNodeName != NULLSTRING && strlen( theNodeName ) ) {
-    cdebug << theNodeName << " )" << endl;
+    cdebug << theNodeName << "' )" ;
   }
   else {
-    cdebug << "NodeName[NULL] )" << endl;
+    cdebug << "NodeName[NULLSTRING]' )" ;
   }
+  cdebug << " " << NodeKindOfNode << endl ;
   char * RetVal = NULLSTRING ;
   GraphEditor::InNode *Nd = NULL ;
-  char * aNodeName = NULL ;
+  char * aNodeName = NULLSTRING ;
   bool   GeneratedName = false ;
+//PAL9048 JR Debug : a node may not have the same name as the graph
+  bool GraphNodeSameName = false ;
+  if ( theNodeName && !strcmp( Graph()->Name() , theNodeName ) ) {
+    GraphNodeSameName = true ;
+  }
   if ( NodeKindOfNode == SUPERV::InLineNode ||
        NodeKindOfNode == SUPERV::LoopNode ||
        NodeKindOfNode == SUPERV::EndLoopNode ||
@@ -440,36 +689,50 @@ GraphEditor::InNode * GraphEditor::OutNode::AddNode(
     }
     theNodeName = NULLSTRING ;
   }
-  if ( theNodeName == NULLSTRING || strlen( theNodeName ) == 0 ) {
+//PAL9048 JR Debug : a node may not have the same name as the graph
+//  if ( theNodeName == NULLSTRING || strlen( theNodeName ) == 0 || Graph()->GetGraphNode( theNodeName ) ) {
+  if ( theNodeName == NULLSTRING || strlen( theNodeName ) == 0 ||
+       Graph()->GetGraphNode( theNodeName ) || GraphNodeSameName ) {
+    cdebug << "OutNode::AddNode : '" << theNodeName << "' GraphNodeSameName "
+           << GraphNodeSameName << endl;
     aNodeName = new char[ strlen( NodeService.ServiceName )+1 ] ;
     strcpy( aNodeName , NodeService.ServiceName ) ;
-    if ( GetGraphNode( NodeService.ServiceName ) ) {
+//    if ( Graph()->GetGraphNode( NodeService.ServiceName ) ) {
+    if ( Graph()->GetGraphNode( NodeService.ServiceName ) || GraphNodeSameName ) {
       GeneratedName = true ;
-      while ( GetGraphNode( aNodeName ) ) {
+      while ( Graph()->GetGraphNode( aNodeName ) || GraphNodeSameName ) {
+        cdebug << "OutNode::AddNode : '" << aNodeName << "' exists or GraphNodeSameName "
+               << GraphNodeSameName << endl;
         if ( aNodeName ) {
           delete [] aNodeName ;
        }
-        int num = GetServiceNameNumber( NodeService.ServiceName ) ;
+//JR 09.08.2005 Debug : folowing line does not run with OMNIORB4
+//        char * aServiceName = (CORBA::String_member ) NodeService.ServiceName ;
+        int num = Graph()->GetNewServiceInstanceNumber( (CORBA::String_member ) NodeService.ServiceName ) ;
         ostringstream astr ;
         astr << num << ends ;
-        const char * n_instance = astr.str().c_str() ;
+//        const char * n_instance = astr.str().c_str() ;
         int lname = strlen( NodeService.ServiceName ) + 1 +
-                    strlen( n_instance ) + 1 ;
+                    strlen( astr.str().c_str() ) + 1 ;
         aNodeName = new char[lname] ;
         strcpy( aNodeName , NodeService.ServiceName ) ;
         strcat( aNodeName , "_" ) ;
-        strcat( aNodeName , n_instance ) ;
+        strcat( aNodeName , astr.str().c_str() ) ;
+        GraphNodeSameName = !strcmp( Graph()->Name() , aNodeName ) ;
       }
     }
   }
   else {
-    if ( GetGraphNode( theNodeName ) == NULL ) {
+    if ( Graph()->GetGraphNode( theNodeName ) == NULL ) {
       aNodeName = new char[ strlen( theNodeName )+1 ] ;
       strcpy( aNodeName , theNodeName ) ;
     }
+    else {
+      aNodeName = NULLSTRING ;
+    }
   }
   if ( aNodeName != NULLSTRING ) {
-    Nd = new GraphEditor::InNode( _Orb , NamingService() ,
+    Nd = new GraphEditor::InNode( _Orb , Graph()->NamingService() ,
                                   aFuncName , aPythonFunction , NodeService ,
                                   NodeComponentName , NodeInterfaceName ,
                                   aNodeName , NodeKindOfNode ,
@@ -477,10 +740,35 @@ GraphEditor::InNode * GraphEditor::OutNode::AddNode(
                                   NodeEditorRelease , NodeAuthor ,
                                   NodeComputer , NodeComment , GeneratedName ,
                                   NodeX , NodeY ,
-                                  Graph_prof_debug() , Graph_fdebug() ) ;
-//    MESSAGE( "GraphEditor::OutNode::AddNode " << hex << (void *) Nd << dec );
-//    if ( GraphBase::Graph::AddNode( Nd ) ) {
-    if ( GraphBase::Graph::AddNode( Nd->ComputingNode() ) ) {
+                                  _prof_debug , _fdebug ) ;
+    
+    // asv: 28.09.04 fix for 6621
+    //if ( Nd->IsMacroNode() )
+    //  MapGraph( Nd->GraphMacroNode(), aNodeName );
+
+    if ( Graph()->IsDataStreamNode() && ( Nd->IsComputingNode() || Nd->IsFactoryNode() ) ) {
+      unsigned int i ;
+      for ( i = 0 ; i < NodeService.ServiceinDataStreamParameter.length() ; i++ ) {
+        GraphBase::InDataStreamPort * aDataStreamPort ;
+        aDataStreamPort = Nd->ComputingNode()->AddInDataStreamPort(
+//JR 17.02.2005 Memory Leak                                         my_strdup( NodeService.ServiceinDataStreamParameter[i].Parametername ) ,
+                                         NodeService.ServiceinDataStreamParameter[i].Parametername ,
+                                         NodeService.ServiceinDataStreamParameter[i].Parametertype ,
+                                         NodeService.ServiceinDataStreamParameter[i].Parameterdependency ,
+                                        SUPERV::DataStreamParameter ) ;
+      }
+      for ( i = 0 ; i < NodeService.ServiceoutDataStreamParameter.length() ; i++ ) {
+        GraphBase::OutDataStreamPort * aDataStreamPort ;
+        aDataStreamPort = Nd->ComputingNode()->AddOutDataStreamPort(
+//JR 17.02.2005 Memory Leak                                         my_strdup( NodeService.ServiceoutDataStreamParameter[i].Parametername ) ,
+                                         NodeService.ServiceoutDataStreamParameter[i].Parametername ,
+                                         NodeService.ServiceoutDataStreamParameter[i].Parametertype ,
+                                         NodeService.ServiceoutDataStreamParameter[i].Parameterdependency ,
+                                        SUPERV::DataStreamParameter ) ;
+      }
+    }
+
+    if ( Graph()->AddNode( Nd->ComputingNode() ) ) {
       DateModification() ;
       RetVal = Nd->Name() ;
     }
@@ -489,11 +777,16 @@ GraphEditor::InNode * GraphEditor::OutNode::AddNode(
     }
   }
   else {
-    cdebug << "NodeName is NULL or already exists." << endl ;
+    cdebug << "ERROR NodeName is NULL or already exists." << endl ;
   }
 //  delete [] aNodeName ;
-  cdebug_out << "GraphEditor::OutNode::AddNode" << endl;
   _Valid = false ;
+  if ( Nd == NULL ) {
+    cdebug_out << "GraphEditor::OutNode::AddNode : NULL" << endl;
+  }
+  else {
+    cdebug_out << "GraphEditor::OutNode::AddNode : " << Nd << " " << Nd->Name() << endl;
+  }
   return Nd ;
 }
 
@@ -504,15 +797,15 @@ bool GraphEditor::OutNode::AddLinkCoord( const char* FromNodeName ,
                                          const int nXY ,
                                          const int* X ,
                                          const int* Y ) {
-  GraphBase::InPort * anInPort = GraphBase::Graph::GetChangeInPort( ToNodeName ,
-                                                                    ToServiceParameterName ) ;
+  GraphBase::InPort * anInPort = Graph()->GetChangeInPort( ToNodeName ,
+                                                           ToServiceParameterName ) ;
 //  cdebug << "GraphEditor::OutNode::AddLinkCoord " << ToNodeName << "( " << ToServiceParameterName
 //         << " ) " << anInPort << " IsEndSwitch " << anInPort->IsEndSwitch() << endl ;
   if ( anInPort ) {
     if ( anInPort->IsEndSwitch() ) {
 //      cdebug << "GraphEditor::OutNode::AddLinkCoord " << FromNodeName << "( " << FromServiceParameterName
 //             << " )" << endl ;
-      return GraphBase::Graph::GetChangeOutPort( FromNodeName , FromServiceParameterName )->AddCoord( nXY , X , Y ) ;
+      return Graph()->GetChangeOutPort( FromNodeName , FromServiceParameterName )->AddCoord( nXY , X , Y ) ;
     }
     else {
       return anInPort->AddCoord( nXY , X , Y ) ;
@@ -528,15 +821,15 @@ bool GraphEditor::OutNode::AddLinkCoord( const char* FromNodeName ,
                                          const int index ,
                                          const int X ,
                                          const int Y ) {
-  GraphBase::InPort * anInPort = GraphBase::Graph::GetChangeInPort( ToNodeName ,
-                                                                    ToServiceParameterName ) ;
+  GraphBase::InPort * anInPort = Graph()->GetChangeInPort( ToNodeName ,
+                                                           ToServiceParameterName ) ;
 //  cdebug << "GraphEditor::OutNode::AddLinkCoord " << ToNodeName << "( " << ToServiceParameterName
 //         << " ) " << anInPort << " IsEndSwitch " << anInPort->IsEndSwitch() << endl ;
   if ( anInPort ) {
     if ( anInPort->IsEndSwitch() ) {
 //      cdebug << "GraphEditor::OutNode::AddLinkCoord " << FromNodeName << "( " << FromServiceParameterName
 //             << " )" << endl ;
-      return GraphBase::Graph::GetChangeOutPort( FromNodeName , FromServiceParameterName )->AddCoord( index , X , Y ) ;
+      return Graph()->GetChangeOutPort( FromNodeName , FromServiceParameterName )->AddCoord( index , X , Y ) ;
     }
     else {
       return anInPort->AddCoord( index , X , Y ) ;
@@ -552,15 +845,15 @@ bool GraphEditor::OutNode::ChangeLinkCoord( const char* FromNodeName ,
                                             const int index ,
                                             const int X ,
                                             const int Y ) {
-  GraphBase::InPort * anInPort = GraphBase::Graph::GetChangeInPort( ToNodeName ,
-                                               ToServiceParameterName ) ;
+  GraphBase::InPort * anInPort = Graph()->GetChangeInPort( ToNodeName ,
+                                                           ToServiceParameterName ) ;
 //  cdebug << "GraphEditor::OutNode::ChangeLinkCoord " << ToNodeName << "( " << ToServiceParameterName
 //         << " ) " << anInPort << " IsEndSwitch " << anInPort->IsEndSwitch() << endl ;
   if ( anInPort ) {
     if ( anInPort->IsEndSwitch() ) {
 //      cdebug << "GraphEditor::OutNode::ChangeLinkCoord " << FromNodeName << "( " << FromServiceParameterName
 //             << " )" << endl ;
-      return GraphBase::Graph::GetChangeOutPort( FromNodeName , FromServiceParameterName )->ChangeCoord( index , X , Y ) ;
+      return Graph()->GetChangeOutPort( FromNodeName , FromServiceParameterName )->ChangeCoord( index , X , Y ) ;
     }
     else {
       return anInPort->ChangeCoord( index , X , Y ) ;
@@ -574,15 +867,15 @@ bool GraphEditor::OutNode::RemoveLinkCoord( const char* FromNodeName ,
                                             const char* ToNodeName ,
                                             const char* ToServiceParameterName ,
                                             const int index ) {
-  GraphBase::InPort * anInPort = GraphBase::Graph::GetChangeInPort( ToNodeName ,
-                                                                    ToServiceParameterName ) ;
+  GraphBase::InPort * anInPort = Graph()->GetChangeInPort( ToNodeName ,
+                                                           ToServiceParameterName ) ;
 //  cdebug << "GraphEditor::OutNode::RemoveLinkCoord " << ToNodeName << "( " << ToServiceParameterName
 //         << " ) " << anInPort << " IsEndSwitch " << anInPort->IsEndSwitch() << endl ;
   if ( anInPort ) {
     if ( anInPort->IsEndSwitch() ) {
 //      cdebug << "GraphEditor::OutNode::RemoveLinkCoord " << FromNodeName << "( " << FromServiceParameterName
 //             << " )" << endl ;
-      return GraphBase::Graph::GetChangeOutPort( FromNodeName , FromServiceParameterName )->RemoveCoord( index ) ;
+      return Graph()->GetChangeOutPort( FromNodeName , FromServiceParameterName )->RemoveCoord( index ) ;
     }
     else {
       return anInPort->RemoveCoord( index ) ;
@@ -595,14 +888,14 @@ int GraphEditor::OutNode::GetLinkCoordSize( const char* FromNodeName ,
                                             const char* FromServiceParameterName ,
                                             const char* ToNodeName ,
                                             const char* ToServiceParameterName ) {
-  const GraphBase::InPort * anInPort = GraphBase::Graph::GetInPort( ToNodeName , ToServiceParameterName ) ;
+  const GraphBase::InPort * anInPort = Graph()->GetInPort( ToNodeName , ToServiceParameterName ) ;
 //  cdebug << "GraphEditor::OutNode::GetLinkCoordSize " << ToNodeName << "( " << ToServiceParameterName
 //         << " ) " << anInPort << " IsEndSwitch " << anInPort->IsEndSwitch() << endl ;
   if ( anInPort ) {
     if ( anInPort->IsEndSwitch() ) {
 //      cdebug << "GraphEditor::OutNode::GetLinkCoordSize " << FromNodeName << "( " << FromServiceParameterName
 //             << " )" << endl ;
-      return GraphBase::Graph::GetChangeOutPort( FromNodeName , FromServiceParameterName )->GetCoord() ;
+      return Graph()->GetChangeOutPort( FromNodeName , FromServiceParameterName )->GetCoord() ;
     }
     else {
       return anInPort->GetCoord() ;
@@ -616,14 +909,14 @@ bool GraphEditor::OutNode::GetLinkCoord( const char* FromNodeName ,
                                          const char* ToNodeName ,
                                          const char* ToServiceParameterName ,
                                          int *X , int *Y ) {
-  const GraphBase::InPort * anInPort = GraphBase::Graph::GetInPort( ToNodeName , ToServiceParameterName ) ;
+  const GraphBase::InPort * anInPort = Graph()->GetInPort( ToNodeName , ToServiceParameterName ) ;
 //  cdebug << "GraphEditor::OutNode::GetLinkCoord " << ToNodeName << "( " << ToServiceParameterName
 //         << " ) " << anInPort << " IsEndSwitch " << anInPort->IsEndSwitch() << endl ;
   if ( anInPort ) {
     if ( anInPort->IsEndSwitch() ) {
 //      cdebug << "GraphEditor::OutNode::GetLinkCoord " << FromNodeName << "( " << FromServiceParameterName
 //             << " )" << endl ;
-      return GraphBase::Graph::GetChangeOutPort( FromNodeName , FromServiceParameterName )->GetCoord( X , Y ) ;
+      return Graph()->GetChangeOutPort( FromNodeName , FromServiceParameterName )->GetCoord( X , Y ) ;
     }
     else {
       return anInPort->GetCoord( X , Y ) ;
@@ -636,16 +929,16 @@ bool GraphEditor::OutNode::GetLinkCoord( const char* FromNodeName ,
                                          const char* FromServiceParameterName ,
                                          const char* ToNodeName ,
                                          const char* ToServiceParameterName ,
-                                         const int index , long &X , long &Y ) {
-  GraphBase::InPort * anInPort = GraphBase::Graph::GetChangeInPort( ToNodeName ,
-                                                                    ToServiceParameterName ) ;
+                                         const int index , CORBA::Long &X , CORBA::Long &Y ) {
+  GraphBase::InPort * anInPort = Graph()->GetChangeInPort( ToNodeName ,
+                                                           ToServiceParameterName ) ;
 //  cdebug << "GraphEditor::OutNode::GetLinkCoord " << ToNodeName << "( " << ToServiceParameterName
 //         << " ) " << anInPort << " IsEndSwitch " << anInPort->IsEndSwitch() << endl ;
   if ( anInPort ) {
     if ( anInPort->IsEndSwitch() ) {
 //      cdebug << "GraphEditor::OutNode::GetLinkCoord " << FromNodeName << "( " << FromServiceParameterName
 //             << " )" << endl ;
-      return GraphBase::Graph::GetChangeOutPort( FromNodeName , FromServiceParameterName )->GetCoord( index , X , Y ) ;
+      return Graph()->GetChangeOutPort( FromNodeName , FromServiceParameterName )->GetCoord( index , X , Y ) ;
     }
     else {
       return anInPort->GetCoord( index , X , Y ) ;
@@ -654,92 +947,191 @@ bool GraphEditor::OutNode::GetLinkCoord( const char* FromNodeName ,
   return false ;
 }
 
-bool GraphEditor::OutNode::AddInputData( const char* ToNodeName1 ,
-                                         const char* ToParameterName1 ,
-                                         const char* ToNodeName2 ,
-                                         const char* ToParameterName2 ) {
-  cdebug_in << "GraphEditor::OutNode::AddInputData" << endl;
-  bool RetVal = GraphBase::Graph::AddInputData( ToNodeName1 ,
-                                                ToParameterName1 ,
-                                                ToNodeName2 ,
-                                                ToParameterName2 ) ;
-  cdebug_out << "GraphEditor::OutNode::AddInputData" << endl;
+bool GraphEditor::OutNode::UnValid() {
+  bool RetVal = _Valid ;
   _Valid = false ;
+  if ( Graph()->GraphMacroLevel() != 0 ) {
+    cdebug << "GraphEditor::OutNode::UnValid() GraphMacroLevel " << Graph()->GraphMacroLevel() << endl ;
+    RetVal = Valid() ;
+  }
   return RetVal ;
 }
 
+//JR Optional parameter kLoopSwitch (default = true) :
+//In some cases we do not need to check the validity of loops and switchs
+//JR 07.07.2005 PAL9342 : that code is now in Executable() method instead of Valid() method
+//bool GraphEditor::OutNode::Valid(bool kLoopSwitch ) {
 bool GraphEditor::OutNode::Valid() {
-  if ( _Valid )
-    return true ;
-
+  bool RetVal = true ;
   cdebug_in << "GraphEditor::OutNode::Valid" << endl;
+//  if ( _Valid )
+//    return true ;
+
   _Executable = false ;
 
-  CreateService() ;
-  
-  if ( !Sort() ) {
-    cdebug << "This DataFlow is not valid." << endl ;
-    return false ;
+  if ( !Graph()->CreateService() ) {
+    cdebug << "GraphEditor::OutNode::Valid ERROR _Valid " << _Valid << endl;
+    RetVal = false ;
   }
   
-  
-//  CreateService() ;
+  if ( Graph()->GraphMacroLevel() != 0 ) {
+    cdebug << "CoupledNode " << Graph()->CoupledNode() << endl ;
+    cdebug << "GraphEditor " << Graph()->CoupledNode()->GraphEditor() << endl ;
+    cdebug << "Graph " << Graph()->CoupledNode()->GraphEditor()->Graph() << endl ;
+    cdebug << "Name " << Graph()->CoupledNode()->GraphEditor()->Graph()->Name() << endl ;
+    cdebug << "Valid --> UpdateMacroPorts of " << Graph()->CoupledNodeName() << " of "
+           << Graph()->CoupledNode()->GraphEditor()->Graph()->Name() << endl ;
+    cdebug << Graph()->CoupledNode() << endl ;
+    Graph()->CoupledNode()->UpdateMacroPorts( Graph() ) ;
+    cdebug << Graph()->CoupledNode()->Name() << " Valid --> UnValid of graph "
+           << Graph()->CoupledNode()->GraphEditor()->Graph()->Name()
+           << " GraphMacroLevel " << Graph()->CoupledNode()->GraphEditor()->Graph()->GraphMacroLevel()  << endl ;
+    Graph()->CoupledNode()->GraphEditor()->UnValid() ;
+  }
+
+  Graph()->InLineServices() ;
 
-  InLineServices() ;
+//JR 07.07.2005 PAL9342 : that code is now in Executable() method instead of Valid() method
+#if 0
+  int SubStreamGraphsNumber = 0 ;
+  if ( !Graph()->Sort( SubStreamGraphsNumber ) ) {
+    cdebug_out << "This DataFlow is not valid." << endl ;
+    RetVal = false ;
+  }
+  if ( Graph()->IsDataStreamNode() ) {
+    StreamGraph()->SubStreamGraphsNumber( SubStreamGraphsNumber ) ;
+  }
+
+//JR Debug 24.08.2005 : InLineServices is needed for Export ==> it is executed above
+//  Graph()->InLineServices() ;
 
-  ComputingNodes() ;
+  if ( kLoopSwitch ) {
+    if ( !Graph()->ValidLoops() ) {
+      cdebug_out << "This DataFlow have not valid Loops." << endl ;
+      RetVal = false ;
+    }
+    if ( !Graph()->ValidSwitchs() ) {
+      cdebug_out << "This DataFlow have not valid Switchs." << endl ;
+      RetVal = false ;
+    }
+  }
+  
+  Graph()->ComputingNodes() ;
+#endif
 
-  _Valid = true ;
+  if ( !Graph()->ValidGOTO() ) { // mkr : PAL12575
+    cdebug << "Editor::OutNode::Valid This DataFlow have not valid GOTO(ValidGOTO)." << endl ;
+    RetVal = false ;
+  }
 
-  cdebug_out << "GraphEditor::OutNode::Valid" << endl;
-  return _Valid ;
+  if ( RetVal ) {
+    _Valid = true ;
+  }
+
+  cdebug_out << "GraphEditor::OutNode::Valid " << _Valid << " RetVal " << RetVal << endl;
+  return RetVal ;
 }
 
 bool GraphEditor::OutNode::Executable() {
   cdebug_in << "GraphEditor::OutNode::Executable" << endl;
+  bool RetVal = true ;
   bool NewLink ;
-  if ( LinkLoopNodes( NewLink ) ) {
+// LinkLoopNodes manage input values of LoopNodes and EndLoopNodes
+  if ( Graph()->LinkLoopNodes( NewLink ) ) {
     if ( NewLink ) {
       _Valid = false ;
+      RetVal = false ;
     }
   }
   else {
-    cdebug << "This DataFlow is not executable." << endl ;
+    cdebug << "Editor::OutNode::Executable This DataFlow is not executable(LinkLoopNodes)." << endl ;
     _Executable = false ;
+    RetVal = false ;
   }
   if ( !IsValid() ) {
     Valid() ;
   }
   if ( !IsValid() ) {
-    return false ;
+    RetVal = false ;
+  }
+
+//JR 07.07.2005 PAL9342 : that code is now in Executable() method instead of Valid() method
+  bool IsValid = true;
+  int SubStreamGraphsNumber = 0 ;
+  if ( !Graph()->Sort( SubStreamGraphsNumber ) ) {
+    cdebug << "Editor::OutNode::Executable This DataFlow is not valid(Sort)." << endl ;
+    RetVal = false ;
+    //mkr : 28.09.2005 : if dataflow is not valid => it is not executable
+    IsValid = false ;
   }
-  if ( DataServerNodes() )
+  if ( Graph()->IsDataStreamNode() )
+    StreamGraph()->SubStreamGraphsNumber( SubStreamGraphsNumber ) ;
+
+  Graph()->InLineServices() ;
+  
+//  if ( kLoopSwitch ) {
+    if ( !Graph()->ValidLoops() ) {
+      cdebug << "Editor::OutNode::Executable This DataFlow have not valid Loops(ValidLoops)." << endl ;
+      RetVal = false ;
+      //mkr : 28.09.2005 : if dataflow is not valid => it is not executable
+      IsValid = false ;
+    }
+    if ( !Graph()->ValidSwitchs() ) {
+      cdebug << "Editor::OutNode::Executable This DataFlow have not valid Switchs(ValidSwitchs)." << endl ;
+      RetVal = false ;
+      //mkr : 28.09.2005 : if dataflow is not valid => it is not executable
+      IsValid = false ;
+    }
+//  }
+  
+  Graph()->ComputingNodes() ;
+
+  if ( Graph()->DataServerNodes() )
     _Executable = true ;
   else {
-    cdebug << "This DataFlow is not executable." << endl ;
+    cdebug << "Editor::OutNode::Executable This DataFlow is not executable(DataServerNodes)." << endl ;
     _Executable = false ;
+    RetVal = false ;
+  }
+
+  if ( _Executable && Graph()->IsDataStreamNode() ) {
+    StreamGraph()->CreateStreamTopology( "/tmp/" ) ;
   }
 
-  cdebug_out << "GraphEditor::OutNode::Executable" << endl;
-  return _Executable ;
+  // asv : 13.12.04 : introducing check for compatibility of linked ports' types.
+  if ( !IsLinksCompatible() ) {
+    _Executable = false;
+    RetVal = false ;
+  }    
+
+  //mkr : 28.09.2005 : if dataflow is not valid => it is not executable
+  if ( !IsValid ) _Executable = false ;
+
+  cdebug_out << "GraphEditor::OutNode::Executable _Executable " << _Executable << " RetVal " << RetVal
+             << endl;
+  return RetVal ;
 }
 
-const CORBA::Any *GraphEditor::OutNode::GetInData(
+//JR 30.03.2005const CORBA::Any *GraphEditor::OutNode::GetInData(
+const CORBA::Any GraphEditor::OutNode::GetInData(
                               const char * ToNodeName ,
                               const char * ToParameterName ) {
 //  cdebug_in << "GraphEditor::OutNode::GetInData " << ToNodeName
 //            << " " << ToParameterName << endl ;
-  const CORBA::Any * retdata = PortInData( ToNodeName , ToParameterName ) ;
+//JR 30.03.2005  const CORBA::Any * retdata = Graph()->PortInData( ToNodeName , ToParameterName ) ;
+  const CORBA::Any retdata = Graph()->PortInData( ToNodeName , ToParameterName ) ;
 //  cdebug_out << "GraphEditor::OutNode::GetInData" << endl ;
   return retdata ;
 }
 
-const CORBA::Any *GraphEditor::OutNode::GetOutData(
+//JR 30.03.2005const CORBA::Any *GraphEditor::OutNode::GetOutData(
+const CORBA::Any GraphEditor::OutNode::GetOutData(
                               const char * FromNodeName ,
                               const char * FromParameterName ) {
 //  cdebug_in << "GraphEditor::OutNode::GetOutData " << FromNodeName
 //            << " " << FromParameterName << endl ;
-  const CORBA::Any * retdata = PortOutData( FromNodeName , FromParameterName ) ;
+//JR 30.03.2005  const CORBA::Any * retdata = Graph()->PortOutData( FromNodeName , FromParameterName ) ;
+  const CORBA::Any retdata = Graph()->PortOutData( FromNodeName , FromParameterName ) ;
 //  cdebug_out << "GraphEditor::OutNode::GetOutData" << endl ;
   return retdata ;
 }
@@ -748,6 +1140,9 @@ const CORBA::Any *GraphEditor::OutNode::GetOutData(
 bool GraphEditor::OutNode::LinkSaveXML( QDomDocument & Graph , QDomElement & link ,
                                         GraphBase::SLink aLink ,
                                         bool wdata ) const {
+  cdebug_in << "GraphEditor::OutNode::LinkSaveXML " << aLink.FromNodeName
+            << "(" << aLink.FromServiceParameterName << ") --> "
+            << aLink.ToNodeName << "(" << aLink.ToServiceParameterName << ")" << endl ;
   QDomElement fromnodename = Graph.createElement( "fromnode-name" ) ;
   QDomText aField ;
   if ( strlen( aLink.FromNodeName.c_str() ) ) {
@@ -805,18 +1200,33 @@ bool GraphEditor::OutNode::LinkSaveXML( QDomDocument & Graph , QDomElement & lin
     valuetype.appendChild( aField ) ;
     switch (aLink.aLinkValue.type()->kind()) {
       case CORBA::tk_string: {
-        char* retstr ;
+        const char* retstr ;
         aLink.aLinkValue >>= retstr;
 //        f << Tabs << "       <value>" << retstr << "</value>" << endl ;
         QDomElement value = Graph.createElement( "value" ) ;
-        aField = Graph.createTextNode( retstr ) ;
+//PAL9133 Debug JR : accept void strings
+        QDomCDATASection aCDATA ;
+        int i ;
+        for ( i = 0 ; i < (int ) strlen( retstr ) ; i++ ) {
+          if ( retstr[ i ] != ' ' ) {
+            break ;
+         }
+        }
+        if ( i == (int ) strlen( retstr ) ) {
+          aCDATA = Graph.createCDATASection( "?" ) ;
+        }
+        else {
+          aCDATA = Graph.createCDATASection( retstr ) ;
+       }
+//        aField = Graph.createTextNode( retstr ) ;
         datavalue.appendChild( value ) ;
-        value.appendChild( aField ) ;
+//        datavalue.appendChild( value ) ;
+        value.appendChild( aCDATA ) ;
 //        MESSAGE( "ToString( string ) " << retstr );
         break ;
       }
       case CORBA::tk_double: {
-        double d;
+        CORBA::Double d;
         aLink.aLinkValue >>= d;
 //        f << Tabs << "       <value>" << d << "</value>" << endl ;
         QDomElement value = Graph.createElement( "value" ) ;
@@ -829,7 +1239,7 @@ bool GraphEditor::OutNode::LinkSaveXML( QDomDocument & Graph , QDomElement & lin
         break ;
       }
       case CORBA::tk_long: {
-        long l;
+        CORBA::Long l;
         aLink.aLinkValue >>= l;
 //        f << Tabs << "       <value>" << l << "</value>" << endl ;
         QDomElement value = Graph.createElement( "value" ) ;
@@ -838,13 +1248,17 @@ bool GraphEditor::OutNode::LinkSaveXML( QDomDocument & Graph , QDomElement & lin
         aField = Graph.createTextNode( aKind ) ;
         datavalue.appendChild( value ) ;
         value.appendChild( aField ) ;
-//        MESSAGE( "ToString( long ) " << l );
+//        MESSAGE( "ToString( CORBA::Long ) " << l );
         break ;
       }
       case CORBA::tk_objref: {
         char* retstr ;
         CORBA::Object_ptr obj ;
-        aLink.aLinkValue >>= obj ;
+#if OMNIORB_VERSION >= 4
+        aLink.aLinkValue >>= (CORBA::Any::to_object)obj;
+#else
+       aLink.aLinkValue >>= obj;
+#endif 
         retstr = _Orb->object_to_string(obj );
 //        f << Tabs << "       <value>" << retstr << "</value>" << endl ;
         QDomElement value = Graph.createElement( "value" ) ;
@@ -892,45 +1306,62 @@ bool GraphEditor::OutNode::LinkSaveXML( QDomDocument & Graph , QDomElement & lin
 //    f << Tabs << "   </coord>" << endl ;
   }
 //  f << Tabs << "</coord-list>" << endl ;
+  cdebug_out << "GraphEditor::OutNode::LinkSaveXML " << aLink.FromNodeName
+             << "(" << aLink.FromServiceParameterName << ") --> "
+             << aLink.ToNodeName << "(" << aLink.ToServiceParameterName << ")"
+             << endl ;
   return true ;
 }
 
 bool GraphEditor::OutNode::LinkSavePY( ostream &f , const char * aGraphName ,
                                        GraphBase::SLink aLink ,
-                                       bool intervar , bool wdata ) const {
+                                       bool fromparam , bool toparam ,
+                                       bool wdata ) const {
   if ( !wdata ) {
-    if ( intervar ) {
-      f << aLink.FromNodeName.c_str() << aLink.FromServiceParameterName.c_str()
-        << " = "
-        << aLink.FromNodeName.c_str() << ".Port( '"
-        << aLink.FromServiceParameterName.c_str()
-        << "' )" << endl ;
+//    if ( intervar ) {
+//      f << "O" << aLink.FromNodeName.c_str() << aLink.FromServiceParameterName.c_str()
+//        << " = "
+//        << aLink.FromNodeName.c_str() << ".GetOutPort( '"
+//        << aLink.FromServiceParameterName.c_str()
+//        << "' )" << endl ;
+//    }
+    f << "    " << "L" << aLink.FromNodeName.c_str() << aLink.FromServiceParameterName.c_str()
+      << aLink.ToNodeName.c_str() << aLink.ToServiceParameterName.c_str() ;
+    if ( ((GraphBase::Graph *) Graph())->GetChangeGraphNode( aLink.FromNodeName.c_str() )->GetChangeOutPort( aLink.FromServiceParameterName.c_str() )->IsDataStream() ) {
+      f << " = " << aGraphName << ".StreamLink( " ;
+    }
+    else {
+      f << " = " << aGraphName << ".Link( " ;
     }
-    f << aLink.ToNodeName.c_str() << aLink.ToServiceParameterName.c_str()
-      << " = " << aGraphName << ".Link( " << aLink.FromNodeName.c_str()
-      << aLink.FromServiceParameterName.c_str() << " , "
-      << aLink.ToNodeName.c_str() << ".Port( '"
-      << aLink.ToServiceParameterName.c_str() << "' ) )" << endl ;
+//    if ( !fromparam ) {
+      f << "O" ;
+//    }
+    f << aLink.FromNodeName.c_str() << aLink.FromServiceParameterName.c_str() << " , " ;
+//    if ( !toparam ) {
+      f << "I" ;
+//    }
+    f << aLink.ToNodeName.c_str() << aLink.ToServiceParameterName.c_str() << " )" << endl ;
   }
   else {
-    f << aLink.ToNodeName.c_str() << aLink.ToServiceParameterName.c_str()
-      << " = " << aLink.ToNodeName.c_str() << ".Input( '"
-      << aLink.ToServiceParameterName.c_str() << "' , " ;
+    f << "    " << "I"<< aLink.ToNodeName.c_str() << aLink.ToServiceParameterName.c_str()
+//      << " = " << aLink.ToNodeName.c_str() << ".Input( '"
+//      << aLink.ToServiceParameterName.c_str() << "' , " ;
+      << ".Input( " ;
     switch (aLink.aLinkValue.type()->kind()) {
       case CORBA::tk_string: {
-        char* retstr ;
+        const char* retstr ;
         aLink.aLinkValue >>= retstr;
         f << "'" << retstr << "'" ;
         break ;
       }
       case CORBA::tk_double: {
-        double d;
+        CORBA::Double d;
         aLink.aLinkValue >>= d;
         f << d ;
         break ;
       }
       case CORBA::tk_long: {
-        long l;
+        CORBA::Long l;
         aLink.aLinkValue >>= l;
         f << l ;
         break ;
@@ -938,7 +1369,11 @@ bool GraphEditor::OutNode::LinkSavePY( ostream &f , const char * aGraphName ,
       case CORBA::tk_objref: {
         char* retstr ;
         CORBA::Object_ptr obj ;
-        aLink.aLinkValue >>= obj ;
+#if OMNIORB_VERSION >= 4
+        aLink.aLinkValue >>= (CORBA::Any::to_object)obj;
+#else
+       aLink.aLinkValue >>= obj;
+#endif 
         retstr = _Orb->object_to_string(obj );
         f << "'" << retstr << "'" ;
         break ;
@@ -949,12 +1384,12 @@ bool GraphEditor::OutNode::LinkSavePY( ostream &f , const char * aGraphName ,
         break ;
       }
     }
-    f << ")" << endl ;
+    f << " )" << endl ;
   }
   int i ;
   for ( i = 0 ; i < (int ) aLink.aListOfCoords.size() ; i++ ) {
-    f << aLink.ToNodeName.c_str()
-      << aLink.ToServiceParameterName.c_str() << ".AddCoord( " << i+1 << " , "
+    f << "    " << "L" << aLink.FromNodeName.c_str() << aLink.FromServiceParameterName.c_str()
+      << aLink.ToNodeName.c_str() << aLink.ToServiceParameterName.c_str() << ".AddCoord( " << i+1 << " , "
       << aLink.aListOfCoords[ i ].theX << " , "
       << aLink.aListOfCoords[ i ].theY << " )" << endl ;
   }
@@ -962,89 +1397,102 @@ bool GraphEditor::OutNode::LinkSavePY( ostream &f , const char * aGraphName ,
 }
 
 //bool GraphEditor::OutNode::SaveXML(ostream & f ) {
-bool GraphEditor::OutNode::SaveXML(QDomDocument & Graph ) {
+bool GraphEditor::OutNode::SaveXML( ostream & f , QDomDocument & GraphQDom ,
+                                    bool aSuperGraph , QDomElement & supergraph ) {
+  cdebug_in << "OutNode::SaveXML( ostream & f , QDomDocument & , " << aSuperGraph << " , QDomElement & ) "
+            << Graph()->Name() << endl ;
   int i ;
-//  f << "<?xml version='1.0' encoding='us-ascii' ?>" << endl << endl ;
-//  f << "<!-- XML Dataflow -->" << endl << endl ;
-//  f << "<!-- Dataflow information -->" << endl ;
-  QString Dataflow("Dataflow") ;
-  Graph = QDomDocument(Dataflow) ;
-//  f << "<dataflow>" << endl ;
-  QDomElement dataflow = Graph.createElement( "dataflow" ) ;
-  Graph.appendChild( dataflow ) ;
-//  f << "     <info-list>" << endl ;
-  QDomElement info = Graph.createElement( "info-list" ) ;
-  dataflow.appendChild( info ) ;
 
-//  f << "             <node>" << endl ;
+  QDomElement dataflow ;
+  if ( aSuperGraph ) {
+    QString SuperGraph("SuperGraph") ;
+    GraphQDom = QDomDocument(SuperGraph) ;
 
-//  GraphBase::DataNode::SaveXML( f , "                        " , 0 , 0 ) ;
-  GraphBase::DataNode::SaveXML( Graph , info , 0 , 0 ) ;
+    supergraph = GraphQDom.createElement( "supergraph" ) ;
+    GraphQDom.appendChild( supergraph ) ;
 
-//  f << "             </node>" << endl ;
+    dataflow = GraphQDom.createElement( "dataflow" ) ;
+    supergraph.appendChild( dataflow ) ;
+  }
+  else {
+//    QString Dataflow("Dataflow") ;
+//    GraphQDom = QDomDocument(Dataflow) ;
 
-//  f << "     </info-list>" << endl << endl ;
+    dataflow = GraphQDom.createElement( "dataflow" ) ;
+    supergraph.appendChild( dataflow ) ;
+  }
 
-//  f << "     <node-list>" << endl ;
-  QDomElement nodelist = Graph.createElement( "node-list" ) ;
+  QDomElement info = GraphQDom.createElement( "info-list" ) ;
+  dataflow.appendChild( info ) ;
+
+  Graph()->SaveXML( GraphQDom , info , 0 , 0 ) ;
+
+  QDomElement nodelist = GraphQDom.createElement( "node-list" ) ;
   dataflow.appendChild( nodelist ) ;
-  for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
+  for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
 //      f << "         <node>" << endl ;
-      if ( GraphNodes( i )->IsComputingNode() ) {
+      if ( Graph()->GraphNodes( i )->IsComputingNode() ) {
 //        ((GraphBase::ComputingNode *)GraphNodes( i ))->SaveXML( f ,
 //                    "                        " ,
-        ((GraphBase::ComputingNode *)GraphNodes( i ))->SaveXML( Graph , nodelist ,
-                    GraphNodes( i )->XCoordinate() ,
-                    GraphNodes( i )->YCoordinate() ) ;
+        ((GraphBase::ComputingNode *) Graph()->GraphNodes( i ))->SaveXML( GraphQDom , nodelist ,
+                    Graph()->GraphNodes( i )->XCoordinate() ,
+                    Graph()->GraphNodes( i )->YCoordinate() ) ;
       }
-      else if ( GraphNodes( i )->IsFactoryNode() ) {
+      else if ( Graph()->GraphNodes( i )->IsFactoryNode() ) {
 //        ((GraphBase::FactoryNode * ) GraphNodes( i ))->SaveXML( f ,
 //                    "                        " ,
-        ((GraphBase::FactoryNode * ) GraphNodes( i ))->SaveXML( Graph , nodelist ,
-                    GraphNodes( i )->XCoordinate() ,
-                    GraphNodes( i )->YCoordinate() ) ;
+        ((GraphBase::FactoryNode * ) Graph()->GraphNodes( i ))->SaveXML( GraphQDom , nodelist ,
+                    Graph()->GraphNodes( i )->XCoordinate() ,
+                    Graph()->GraphNodes( i )->YCoordinate() ) ;
+      }
+      else if ( Graph()->GraphNodes( i )->IsInLineNode()  ) {
+//        ((GraphBase::InLineNode * ) GraphNodes( i ))->SaveXML( f ,
+//                    "                        " ,
+        ((GraphBase::InLineNode * ) Graph()->GraphNodes( i ))->SaveXML( GraphQDom , nodelist ,
+                    Graph()->GraphNodes( i )->XCoordinate() ,
+                    Graph()->GraphNodes( i )->YCoordinate() ) ;
       }
-      else if ( GraphNodes( i )->IsInLineNode() ) {
+      else if ( Graph()->GraphNodes( i )->IsMacroNode() ) {
 //        ((GraphBase::InLineNode * ) GraphNodes( i ))->SaveXML( f ,
 //                    "                        " ,
-        ((GraphBase::InLineNode * ) GraphNodes( i ))->SaveXML( Graph , nodelist ,
-                    GraphNodes( i )->XCoordinate() ,
-                    GraphNodes( i )->YCoordinate() ) ;
+        ((GraphBase::GOTONode * ) Graph()->GraphNodes( i ))->SaveXML( GraphQDom , nodelist ,
+                    Graph()->GraphNodes( i )->XCoordinate() ,
+                    Graph()->GraphNodes( i )->YCoordinate() ) ;
       }
-      else if ( GraphNodes( i )->IsGOTONode() ) {
+      else if ( Graph()->GraphNodes( i )->IsGOTONode() ) {
 //        ((GraphBase::GOTONode * ) GraphNodes( i ))->SaveXML( f ,
 //                    "                        " ,
-        ((GraphBase::GOTONode * ) GraphNodes( i ))->SaveXML( Graph , nodelist ,
-                    GraphNodes( i )->XCoordinate() ,
-                    GraphNodes( i )->YCoordinate() ) ;
+        ((GraphBase::GOTONode * ) Graph()->GraphNodes( i ))->SaveXML( GraphQDom , nodelist ,
+                    Graph()->GraphNodes( i )->XCoordinate() ,
+                    Graph()->GraphNodes( i )->YCoordinate() ) ;
       }
-      else if ( GraphNodes( i )->IsLoopNode() ) {
+      else if ( Graph()->GraphNodes( i )->IsLoopNode() ) {
 //        ((GraphBase::LoopNode * ) GraphNodes( i ))->SaveXML( f ,
 //                    "                        " ,
-        ((GraphBase::LoopNode * ) GraphNodes( i ))->SaveXML( Graph , nodelist ,
-                    GraphNodes( i )->XCoordinate() ,
-                    GraphNodes( i )->YCoordinate() ) ;
+        ((GraphBase::LoopNode * ) Graph()->GraphNodes( i ))->SaveXML( GraphQDom , nodelist ,
+                    Graph()->GraphNodes( i )->XCoordinate() ,
+                    Graph()->GraphNodes( i )->YCoordinate() ) ;
       }
-      else if ( GraphNodes( i )->IsEndLoopNode() ) {
+      else if ( Graph()->GraphNodes( i )->IsEndLoopNode() ) {
 //        ((GraphBase::EndOfLoopNode * ) GraphNodes( i ))->SaveXML( f ,
 //                    "                        " ,
-        ((GraphBase::EndOfLoopNode * ) GraphNodes( i ))->SaveXML( Graph , nodelist ,
-                    GraphNodes( i )->XCoordinate() ,
-                    GraphNodes( i )->YCoordinate() ) ;
+        ((GraphBase::EndOfLoopNode * ) Graph()->GraphNodes( i ))->SaveXML( GraphQDom , nodelist ,
+                    Graph()->GraphNodes( i )->XCoordinate() ,
+                    Graph()->GraphNodes( i )->YCoordinate() ) ;
       }
-      else if ( GraphNodes( i )->IsSwitchNode() ) {
+      else if ( Graph()->GraphNodes( i )->IsSwitchNode() ) {
 //        ((GraphBase::SwitchNode * ) GraphNodes( i ))->SaveXML( f ,
 //                    "                        " ,
-        ((GraphBase::SwitchNode * ) GraphNodes( i ))->SaveXML( Graph , nodelist ,
-                    GraphNodes( i )->XCoordinate() ,
-                    GraphNodes( i )->YCoordinate() ) ;
+        ((GraphBase::SwitchNode * ) Graph()->GraphNodes( i ))->SaveXML( GraphQDom , nodelist ,
+                    Graph()->GraphNodes( i )->XCoordinate() ,
+                    Graph()->GraphNodes( i )->YCoordinate() ) ;
       }
-      else if ( GraphNodes( i )->IsEndSwitchNode() ) {
+      else if ( Graph()->GraphNodes( i )->IsEndSwitchNode() ) {
 //        ((GraphBase::EndOfSwitchNode * ) GraphNodes( i ))->SaveXML( f ,
 //                    "                        " ,
-        ((GraphBase::EndOfSwitchNode * ) GraphNodes( i ))->SaveXML( Graph , nodelist ,
-                    GraphNodes( i )->XCoordinate() ,
-                    GraphNodes( i )->YCoordinate() ) ;
+        ((GraphBase::EndOfSwitchNode * ) Graph()->GraphNodes( i ))->SaveXML( GraphQDom , nodelist ,
+                    Graph()->GraphNodes( i )->XCoordinate() ,
+                    Graph()->GraphNodes( i )->YCoordinate() ) ;
       }
 //      f << "         </node>" << endl ;
 //    }
@@ -1052,263 +1500,230 @@ bool GraphEditor::OutNode::SaveXML(QDomDocument & Graph ) {
 //  f << "     </node-list>" << endl << endl ;
 
 //  f << "     <link-list>" << endl ;
-  QDomElement linklist = Graph.createElement( "link-list" ) ;
+  QDomElement linklist = GraphQDom.createElement( "link-list" ) ;
   dataflow.appendChild( linklist ) ;
-  const GraphBase::ListOfLinks * Links = GetLinks( true ) ;
+  const GraphBase::ListOfSLinks * Links = Graph()->GetLinks( true ) ;
   for ( i = 0 ; i < (int ) Links->size() ; i++ ) {
 //    f << "           <link>" << endl ;
-    QDomElement link = Graph.createElement( "link" ) ;
+    QDomElement link = GraphQDom.createElement( "link" ) ;
     linklist.appendChild( link ) ;
 //    LinkSaveXML( f , "                       " , (*Links)[ i ] , false ) ;
-    LinkSaveXML( Graph , link , (*Links)[ i ] , false ) ;
+    LinkSaveXML( GraphQDom , link , (*Links)[ i ] , false ) ;
 //    f << "           </link>" << endl ;
   }
 //  f << "     </link-list>" << endl << endl ;
 
 //  f << "     <data-list>" << endl ;
-  QDomElement datalist = Graph.createElement( "data-list" ) ;
+  QDomElement datalist = GraphQDom.createElement( "data-list" ) ;
   dataflow.appendChild( datalist ) ;
-  const GraphBase::ListOfLinks * Datas = GetDatas() ;
-  for ( i = 0 ; i < (int ) Datas->size() ; i++ ) {
+  if ( Graph()->GraphMacroLevel() == 0 ) {
+    const GraphBase::ListOfSLinks * Datas = Graph()->GetDatas() ;
+    for ( i = 0 ; i < (int ) Datas->size() ; i++ ) {
 //    f << "           <data>" << endl ;
-    QDomElement data = Graph.createElement( "data" ) ;
-    datalist.appendChild( data ) ;
+      QDomElement data = GraphQDom.createElement( "data" ) ;
+      datalist.appendChild( data ) ;
 //    LinkSaveXML( f , "                       " , (*Datas)[ i ] , true ) ;
-    LinkSaveXML( Graph , data , (*Datas)[ i ] , true ) ;
+      LinkSaveXML( GraphQDom , data , (*Datas)[ i ] , true ) ;
 //    f << "           </data>" << endl ;
+    }
   }
-//#if 0
-//  const GraphEditor::OutNode * aDataNode = (GraphEditor::OutNode *) this ;
-//  if ( aDataNode ) {
-//    int i ;
-//    for ( i = 0 ; i < aDataNode->GetNodeOutPortsSize() ; i++ ) {
-//      const GraphBase::InPort *aLink = aDataNode->GetNodeOutPort(i)->GetLink() ;
-//      if ( aLink ) {
-//        f << "               <data>" << endl ;
-//        aLink->SaveXML( f , "                        " ) ;
-//        f << "               </data>" << endl ;
-//      }
-//    }
-//    for ( i = 0 ; i < aDataNode->GetNodeInPortsSize() ; i++ ) {
-//      const GraphBase::InPort *aLink = aDataNode->GetNodeInPort(i)->GetLink() ;
-//      if ( aLink ) {
-//        f << "               <data>" << endl ;
-//        aLink->SaveXML( f , "                        " ) ;
-//        f << "               </data>" << endl ;
-//      }
-//    }
-//  }
-//#endif
 
-#if 0
-  f << "       </data-list>" << endl << endl ;
-  f << "</dataflow>" << endl ;
-#endif
+  for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
+    if ( Graph()->GraphNodes( i )->IsMacroNode() ) {
+      GraphBase::GOTONode * aMacroNode = (GraphBase::GOTONode * ) Graph()->GraphNodes( i ) ;
+      GraphBase::Graph * aMacroGraph = (GraphBase::Graph * ) aMacroNode->CoupledNode() ;
+      cdebug << "OutNode::SaveXML ---> OutNode::SaveXML( ostream & f , QDomDocument & , false "
+             << " , QDomElement & ) MacroGraph " << aMacroGraph->Name() << endl ;
+      if ( !aMacroGraph->GraphEditor()->SaveXML( f , GraphQDom , false , supergraph ) ) {
+        return false ;
+      cdebug << "OutNode::SaveXML MacroGraph "<< aMacroGraph->Name() << " done" << endl ;
+      }
+    }
+  }
+
+  cdebug_out << "OutNode::SaveXML( ostream & f , QDomDocument & , " << aSuperGraph << " , QDomElement & ) "
+             << Graph()->Name() << endl ;
 
   return true ;
 }
 
-bool GraphEditor::OutNode::SavePY( ostream & f ) {
+bool GraphEditor::OutNode::SavePY( ostream & f , bool importSuperV ) {
   int i ;
   int j ;
-  f << endl << "# Generated python file of Graph " << Name() << endl << endl ;
-
-  f << "from SuperV import *" << endl ;
+  const GraphBase::ListOfSLinks * Links ;
+  if ( importSuperV ) {
+    f << endl << "# Generated python file of Graph " << Graph()->Name() << endl << endl ;
 
-  f << "# Graph creation " << endl ;
-  GraphBase::DataNode::SavePY( f , Name() , 0 , 0 ) ;
+    f << "from SuperV import *" << endl << endl ;
+  }
 
-  f << endl << "# Creation of Factory Nodes" << endl ;
-  for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
-    if ( GraphNodes( i )->IsFactoryNode() ) {
-      f << endl ;
-      ((GraphBase::FactoryNode * ) GraphNodes( i ))->SavePY( f , Name() ,
-                GraphNodes( i )->XCoordinate() ,
-                GraphNodes( i )->YCoordinate() ) ;
+  f << "# Graph creation of " << Graph()->Name() << endl ;
+  f << "def Def" << Graph()->Name() << "() :" << endl ;
+  Graph()->SavePY( f , Graph()->Name() , 0 , 0 ) ;
+
+  f << "    " << endl << "    " << "# Creation of Factory Nodes" << endl ;
+  for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
+    if ( Graph()->GraphNodes( i )->IsFactoryNode() ) {
+      f << "    " << endl ;
+      ((GraphBase::FactoryNode * ) Graph()->GraphNodes( i ))->SavePY( f , Graph()->Name() ,
+                                                                      Graph()->GraphNodes( i )->XCoordinate() ,
+                                                                      Graph()->GraphNodes( i )->YCoordinate() ) ;
     }
   }
 
   bool first = true ;
-  for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
-    if ( GraphNodes( i )->IsComputingNode() ) {
+  for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
+    if ( Graph()->GraphNodes( i )->IsComputingNode() ) {
       if ( first ) {
-        f << endl << "# Creation of Computing Nodes" << endl ;
+        f << "    " << endl << "    " << "# Creation of Computing Nodes" << endl ;
         first = false ;
       }
       else {
-        f << endl ;
+        f << "    " << endl ;
       }
-      ((GraphBase::ComputingNode * ) GraphNodes( i ))->SavePY( f , Name() ,
-                GraphNodes( i )->XCoordinate() ,
-                GraphNodes( i )->YCoordinate() ) ;
+      ((GraphBase::ComputingNode * ) Graph()->GraphNodes( i ))->SavePY( f , Graph()->Name() ,
+                                                                        Graph()->GraphNodes( i )->XCoordinate() ,
+                                                                        Graph()->GraphNodes( i )->YCoordinate() ) ;
     }
   }
 
   first = true ;
-  for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
-    if ( GraphNodes( i )->IsInLineNode() ) {
+  for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
+    if ( Graph()->GraphNodes( i )->IsInLineNode() ) {
       if ( first ) {
-        f << endl << "# Creation of InLine Nodes" << endl ;
+        f << "    " << endl << "    " << "# Creation of InLine Nodes" << endl ;
         first = false ;
       }
       else {
-        f << endl ;
+        f << "    " << endl ;
       }
-      ((GraphBase::InLineNode * ) GraphNodes( i ))->SavePY( f , Name() ,
-                GraphNodes( i )->XCoordinate() ,
-                GraphNodes( i )->YCoordinate() ) ;
+      ((GraphBase::InLineNode * ) Graph()->GraphNodes( i ))->SavePY( f , Graph()->Name() ,
+                                                                     Graph()->GraphNodes( i )->XCoordinate() ,
+                                                                     Graph()->GraphNodes( i )->YCoordinate() ) ;
     }
   }
 
   first = true ;
-  for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
-    if ( GraphNodes( i )->IsLoopNode() ) {
+  for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
+    if ( Graph()->GraphNodes( i )->IsLoopNode() ) {
       if ( first ) {
-        f << endl << "# Creation of Loop Nodes" << endl ;
+        f << "    " << endl << "    " << "# Creation of Loop Nodes" << endl ;
         first = false ;
       }
       else {
-        f << endl ;
+        f << "    " << endl ;
       }
-      ((GraphBase::LoopNode * ) GraphNodes( i ))->SavePY( f , Name() ,
-                GraphNodes( i )->XCoordinate() ,
-                GraphNodes( i )->YCoordinate() ) ;
+      ((GraphBase::LoopNode * ) Graph()->GraphNodes( i ))->SavePY( f , Graph()->Name() ,
+                                                                   Graph()->GraphNodes( i )->XCoordinate() ,
+                                                                   Graph()->GraphNodes( i )->YCoordinate() ) ;
     }
   }
 
   first = true ;
-  for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
-    if ( GraphNodes( i )->IsSwitchNode() ) {
+  for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
+    if ( Graph()->GraphNodes( i )->IsSwitchNode() ) {
       if ( first ) {
-        f << endl << "# Creation of Switch Nodes" << endl ;
+        f << "    " << endl << "    " << "# Creation of Switch Nodes" << endl ;
         first = false ;
       }
       else {
-        f << endl ;
+        f << "    " << endl ;
       }
-      ((GraphBase::SwitchNode * ) GraphNodes( i ))->SavePY( f , Name() ,
-                GraphNodes( i )->XCoordinate() ,
-                GraphNodes( i )->YCoordinate() ) ;
+      ((GraphBase::SwitchNode * ) Graph()->GraphNodes( i ))->SavePY( f , Graph()->Name() ,
+                                                                     Graph()->GraphNodes( i )->XCoordinate() ,
+                                                                     Graph()->GraphNodes( i )->YCoordinate() ) ;
     }
   }
 
   first = true ;
-  for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
-    if ( GraphNodes( i )->IsGOTONode() ) {
+  for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
+    if ( Graph()->GraphNodes( i )->IsGOTONode() ) {
       if ( first ) {
-        f << endl << "# Creation of GOTO Nodes" << endl ;
+        f << "    " << endl << "    " << "# Creation of GOTO Nodes" << endl ;
         first = false ;
       }
       else {
-        f << endl ;
+        f << "    " << endl ;
       }
-      ((GraphBase::GOTONode * ) GraphNodes( i ))->SavePY( f , Name() ,
-                GraphNodes( i )->XCoordinate() ,
-                GraphNodes( i )->YCoordinate() ) ;
+      ((GraphBase::GOTONode * ) Graph()->GraphNodes( i ))->SavePY( f , Graph()->Name() ,
+                                                                   Graph()->GraphNodes( i )->XCoordinate() ,
+                                                                   Graph()->GraphNodes( i )->YCoordinate() ) ;
     }
   }
 
-  const GraphBase::ListOfLinks * Links = GetLinks() ;
-  bool intervar ;
-  map< string , int > aMapOfOutPorts ;
   first = true ;
-  for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
+  for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
+    if ( Graph()->GraphNodes( i )->IsMacroNode() ) {
+      if ( first ) {
+        f << "    " << endl << "    " << "# Creation of Macro Nodes" << endl ;
+        first = false ;
+      }
+      else {
+        f << "    " << endl ;
+      }
+      ((GraphBase::GOTONode * ) Graph()->GraphNodes( i ))->SavePY( f , Graph()->Name() ,
+                                                                   Graph()->GraphNodes( i )->XCoordinate() ,
+                                                                   Graph()->GraphNodes( i )->YCoordinate() ) ;
+    }
+  }
+
+  Links = Graph()->GetLinks() ;
+//  bool intervar ;
+//  map< string , int > aMapOfOutPorts ;
+  first = true ;
+  for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
     for ( j = 0 ; j < (int ) Links->size() ; j++ ) {
-      if ( !strcmp( GraphNodes( i )->Name() , (*Links)[ j ].FromNodeName.c_str() ) ) {
+      if ( !strcmp( Graph()->GraphNodes( i )->Name() , (*Links)[ j ].FromNodeName.c_str() ) ) {
         if ( first ) {
-          f << endl
-            << "# Creation of Links"
+          f << "    " << endl
+            << "    " << "# Creation of Links"
             << endl ;
           first = false ;
         }
         else {
-          f << endl ;
-        }
-        char * NodePort = new char [ strlen( (*Links)[ j ].FromNodeName.c_str() ) +
-                                     strlen( (*Links)[ j ].FromServiceParameterName.c_str() ) + 1 ] ;
-        strcpy( NodePort , (*Links)[ j ].FromNodeName.c_str() ) ;
-        strcat( NodePort , (*Links)[ j ].FromServiceParameterName.c_str() ) ;
-        if ( aMapOfOutPorts[ NodePort ] == 0 ) {
-          aMapOfOutPorts[ NodePort ] = j + 1 ;
-          intervar = true ;
-        }
-        else {
-          intervar = false ;
+          f << "    " << endl ;
         }
-        LinkSavePY( f , Name() , (*Links)[ j ] , intervar , false ) ;
-        delete [] NodePort ;
+//        char * NodePort = new char [ strlen( (*Links)[ j ].FromNodeName.c_str() ) +
+//                                     strlen( (*Links)[ j ].FromServiceParameterName.c_str() ) + 1 ] ;
+//        strcpy( NodePort , (*Links)[ j ].FromNodeName.c_str() ) ;
+//        strcat( NodePort , (*Links)[ j ].FromServiceParameterName.c_str() ) ;
+//        if ( aMapOfOutPorts[ NodePort ] == 0 ) {
+//          aMapOfOutPorts[ NodePort ] = j + 1 ;
+//          intervar = true ;
+//        }
+//        else {
+//          intervar = false ;
+//        }
+        bool fromparam = false ;
+        if ( Graph()->GraphNodes( i )->GetOutPort( (*Links)[ j ].FromServiceParameterName.c_str() )->IsParam() ) {
+          fromparam = true ;
+       }
+        bool toparam = false ;
+        if ( Graph()->GetChangeGraphNode( (*Links)[ j ].ToNodeName.c_str() )->GetInPort( (*Links)[ j ].ToServiceParameterName.c_str() )->IsParam() ) {
+          toparam = true ;
+       }
+        LinkSavePY( f , Graph()->Name() , (*Links)[ j ] , fromparam , toparam , false ) ;
+//        delete [] NodePort ;
       }
     }
   }
 
-#if 0
-  first = true ;
-  for ( i = 0 ; i < Links->size() ; i++ ) {
-    if ( GetGraphNode( (*Links)[ i ].FromNodeName.c_str() )->IsSwitchNode() ||
-         GetGraphNode( (*Links)[ i ].ToNodeName.c_str() )->IsSwitchNode() ||
-         GetGraphNode( (*Links)[ i ].FromNodeName.c_str() )->IsEndSwitchNode() ||
-         GetGraphNode( (*Links)[ i ].ToNodeName.c_str() )->IsEndSwitchNode() ) {
+  if ( Graph()->GraphMacroLevel() == 0 ) {
+    const GraphBase::ListOfSLinks * Datas = Graph()->GetDatas() ;
+    first = true ;
+    for ( i = 0 ; i < (int ) Datas->size() ; i++ ) {
       if ( first ) {
-        f << endl
-          << "# Creation of Switch Links"
-          << endl ;
+        f << "    " << endl << "    " << "# Input datas" << endl ;
         first = false ;
       }
-      char * NodePort = new char [ strlen( (*Links)[ i ].FromNodeName.c_str() ) +
-                                   strlen( (*Links)[ i ].FromServiceParameterName.c_str() ) + 1 ] ;
-      strcpy( NodePort , (*Links)[ i ].FromNodeName.c_str() ) ;
-      strcat( NodePort , (*Links)[ i ].FromServiceParameterName.c_str() ) ;
-      if ( aMapOfOutPorts[ NodePort ] == 0 ) {
-        aMapOfOutPorts[ NodePort ] = i + 1 ;
-        intervar = true ;
-      }
-      else {
-        intervar = false ;
-      }
-      LinkSavePY( f , Name() , (*Links)[ i ] , intervar , false ) ;
-      delete [] NodePort ;
+      bool fromparam = true ;
+      bool toparam = true ;
+      LinkSavePY( f , Graph()->Name() , (*Datas)[ i ] , fromparam , toparam , true ) ;
     }
   }
 
   first = true ;
-  for ( i = 0 ; i < Links->size() ; i++ ) {
-    if ( GetGraphNode( (*Links)[ i ].FromNodeName.c_str() )->IsGOTONode() &&
-         GetGraphNode( (*Links)[ i ].ToNodeName.c_str() )->IsInLineNode() ) {
-      if ( first ) {
-        f << endl
-          << "# Creation of intermediate Output variables and of Loop Links"
-          << endl ;
-        first = false ;
-      }
-      char * NodePort = new char [ strlen( (*Links)[ i ].FromNodeName.c_str() ) +
-                                   strlen( (*Links)[ i ].FromServiceParameterName.c_str() ) + 1 ] ;
-      strcpy( NodePort , (*Links)[ i ].FromNodeName.c_str() ) ;
-      strcat( NodePort , (*Links)[ i ].FromServiceParameterName.c_str() ) ;
-      if ( aMapOfOutPorts[ NodePort ] == 0 ) {
-        aMapOfOutPorts[ NodePort ] = i + 1 ;
-        intervar = true ;
-      }
-      else {
-        intervar = false ;
-      }
-      LinkSavePY( f , Name() , (*Links)[ i ] , intervar , false ) ;
-      delete [] NodePort ;
-    }
-  }
-#endif
-
-  const GraphBase::ListOfLinks * Datas = GetDatas() ;
-  first = true ;
-  for ( i = 0 ; i < (int ) Datas->size() ; i++ ) {
-    if ( first ) {
-      f << endl << "# Creation of Input datas" << endl ;
-      first = false ;
-    }
-    LinkSavePY( f , Name() , (*Datas)[ i ] , false , true ) ;
-  }
-
-  first = true ;
-  const SALOME_ModuleCatalog::ListOfServicesParameter ListOfInParam = ServiceInParameter() ;
+  const SALOME_ModuleCatalog::ListOfServicesParameter ListOfInParam = Graph()->ServiceInParameter() ;
   for ( i = 0 ; i < (int ) ListOfInParam.length() ; i++ ) {
     string _aParam = CORBA::string_dup(ListOfInParam[ i ].Parametername) ;
     const char * aParam = _aParam.c_str() ;
@@ -1316,29 +1731,31 @@ bool GraphEditor::OutNode::SavePY( ostream & f ) {
     char * aPortName ;
     int j ;
     for ( j = 0 ; j < (int ) strlen( aParam ) ; j++ ) {
-      if ( aParam[ j ] == '\\' ) {
+//      if ( aParam[ j ] == '\\' ) {
+      if ( aParam[ j ] == '_' && aParam[ j+1 ] == '_' ) {
         aNodeName = new char[ j+1 ] ;
         strncpy( aNodeName , aParam , j ) ;
         aNodeName[ j ] = '\0' ;
-        aPortName = new char[ strlen( aParam ) - j ] ;
-        strncpy( aPortName , &aParam[ j+1 ] , strlen( aParam ) - j ) ;
+        aPortName = new char[ strlen( aParam ) - j-1 ] ;
+        strncpy( aPortName , &aParam[ j+2 ] , strlen( aParam ) - j-1 ) ;
         break ;
       }
     }
-    if ( !GetChangeGraphNode( aNodeName )->GetInPort( aPortName )->IsDataConnected() ) {
+    const GraphBase::InPort * anInPort = Graph()->GetChangeGraphNode( aNodeName )->GetInPort( aPortName ) ;
+    if ( !anInPort->IsDataConnected() ) {
       if ( first ) {
-        f << endl << "# Missing Input datas" << endl ;
+        f << "    " << endl << "    " << "# Input Ports of the graph" << endl ;
         first = false ;
       }
-      f << aNodeName << aPortName << " = " << aNodeName << ".Port( '"
+      f << "    " << "#I" << aNodeName << aPortName << " = " << aNodeName << ".GetInPort( '"
         << aPortName << "' )" << endl ;
     }
     delete [] aNodeName ;
     delete [] aPortName ;
   }
 
-  f << endl << "# Creation of Output variables" << endl ;
-  const SALOME_ModuleCatalog::ListOfServicesParameter ListOfOutParam = ServiceOutParameter() ;
+  f << "    " << endl << "    # Output Ports of the graph" << endl ;
+  const SALOME_ModuleCatalog::ListOfServicesParameter ListOfOutParam = Graph()->ServiceOutParameter() ;
   for ( i = 0 ; i < (int ) ListOfOutParam.length() ; i++ ) {
     string _aParam = CORBA::string_dup(ListOfOutParam[ i ].Parametername) ;
     const char * aParam = _aParam.c_str() ;
@@ -1346,48 +1763,143 @@ bool GraphEditor::OutNode::SavePY( ostream & f ) {
     char * aPortName ;
     int j ;
     for ( j = 0 ; j < (int ) strlen( aParam ) ; j++ ) {
-      if ( aParam[ j ] == '\\' ) {
+//      if ( aParam[ j ] == '\\' ) {
+      if ( aParam[ j ] == '_' && aParam[ j+1 ] == '_' ) {
         aNodeName = new char[ j+1 ] ;
         strncpy( aNodeName , aParam , j ) ;
         aNodeName[ j ] = '\0' ;
-        aPortName = new char[ strlen( aParam ) - j ] ;
-        strncpy( aPortName , &aParam[ j+1 ] , strlen( aParam ) - j ) ;
+        aPortName = new char[ strlen( aParam ) - j-1 ] ;
+        strncpy( aPortName , &aParam[ j+2 ] , strlen( aParam ) - j-1 ) ;
         break ;
       }
     }
-    f << aNodeName << aPortName << " = " << aNodeName << ".Port( '"
+    f << "    " << "#O" << aNodeName << aPortName << " = " << aNodeName << ".GetOutPort( '"
       << aPortName << "' )" << endl ;
     delete [] aNodeName ;
     delete [] aPortName ;
   }
+
+  f << "    " << "return " << Graph()->Name() << endl << endl ;
+
+// RECURSIVE CREATION OF GRAPHS OF MACRONODES
+  for ( i = 0 ; i < Graph()->GraphNodesSize() ; i++ ) {
+    if ( Graph()->GraphNodes( i )->IsMacroNode() ) {
+      GraphBase::GOTONode * aMacroNode = (GraphBase::GOTONode * ) Graph()->GraphNodes( i ) ;
+      GraphBase::Graph * aMacroGraph = (GraphBase::Graph * ) aMacroNode->CoupledNode() ;
+      cdebug << "OutNode::SavePY ---> OutNode::SavePY( ostream & f ) MacroGraph " << aMacroGraph->Name() << endl ;
+      GraphEditor::DataFlow * aDataFlow = aMacroGraph->GraphEditor() ;
+      cdebug << "SavePY of the Graph " << aDataFlow->Graph() << " of the MacroNode "
+             << aMacroGraph->Name() << endl ;
+      if ( !aDataFlow->SavePY( f , false ) ) {
+        return false ;
+      }
+    }
+  }
+
+//  f << Graph()->Name() << " = " << Graph()->Name() << "()" << endl ;
+
   return true ;
 }
 
+/** Iterate through ALL links (OutPort-InPort pairs) and check if their types are 
+ *  compatible - call GraphEditor::DataFlow::IsCompatible(type1, type2).
+ *  Returns true if all are compatible.
+ */
+bool GraphEditor::OutNode::IsLinksCompatible() {
+  cdebug_in << "Editor::OutNode::IsLinksCompatible()" << endl ;
+  bool RetVal = true;
+  bool b ;
+  const GraphBase::ListOfSLinks * Links = Graph()->GetLinks( true ) ;
+  cdebug_in << "Editor::OutNode::IsLinksCompatible() " << Links->size() << " Links" << endl ;
+//  for ( int i = 0 ; i < (int ) Links->size() && b ; i++ ) {
+  for ( int i = 0 ; i < (int ) Links->size() ; i++ ) {
+    GraphBase::SLink aLink = (*Links)[i];
+    GraphBase::ComputingNode* anOutNode = Graph()->GetChangeGraphNode( aLink.FromNodeName.c_str() );
+    GraphBase::ComputingNode* anInNode = Graph()->GetChangeGraphNode( aLink.ToNodeName.c_str() );
+    const GraphBase::OutPort* anOutPort = anOutNode->GetOutPort( aLink.FromServiceParameterName.c_str() );
+    const GraphBase::InPort* anInPort = anInNode->GetInPort( aLink.ToServiceParameterName.c_str() );    
+    b = IsCompatible( anOutPort->PortType(), anInPort->PortType() );
+    cdebug << "GraphEditor::OutNode::IsLinksCompatible:  " << aLink.FromNodeName << "( "
+           << aLink.FromServiceParameterName << " " << anOutPort->PortType()
+           << " )  -->  " << aLink.ToNodeName <<"( " << aLink.ToServiceParameterName << " "
+           << anInPort->PortType() << " ) = " << (b ? "OK" : "Not compatible (ERROR)") << endl;
+    if ( !b ) {
+      RetVal = false ;
+      MESSAGE( "Graph structure ERROR: type of port \"" << aLink.FromServiceParameterName
+               << "\" of node \"" << aLink.FromNodeName
+               << "\" is not compatible with type of linked port \""
+              << aLink.ToServiceParameterName << "\" of node \"" << aLink.ToNodeName<<"\"" ) ; 
+      ostringstream aTypeOutPortstr ;
+      aTypeOutPortstr << anOutPort->PortType() ;
+      ostringstream aTypeInPortstr ;
+      aTypeInPortstr << anInPort->PortType() ;
+      string anErrorMessage = string( "PortTypes of " ) + string( aLink.FromNodeName ) +
+                              string( "( " ) + aLink.FromServiceParameterName +
+                              string( " ) " ) + aTypeOutPortstr.str() + string( " and " ) +
+                              string( aLink.ToNodeName ) + string( "( " ) +
+                              string( aLink.ToServiceParameterName ) + 
+                              string( " ) " ) + aTypeInPortstr.str() +
+                              string( " are not compatibles.\n" ) ;
+      Graph()->SetMessages( anErrorMessage ) ;
+    }
+  }
+  cdebug_out << "Editor::OutNode::IsLinksCompatible() RetVal " << RetVal << endl ;
+  return RetVal ;
+}
+
+static const char* gSimpleTypes[] = 
+  {"boolean", "char", "short", "int", "long", "float", "double"};
+bool isSimpleType( string type ) {
+  for ( int i = 0; i < 7; i++ )
+    if ( type == gSimpleTypes[i] )
+      return true;
+  return false;
+}
 
+/**Returns true if an out-port of type "OutPortType" can be bound with in-port of type "InPortType". 
+ * Types: {"string", "boolean", "char", "short", "int", "long", "float", "double", "objref"};
+ * Currently considered compatible ALL types except for objref - they must match exactly
+ */
+bool GraphEditor::OutNode::IsCompatible( const char* OutPortType, const char* InPortType ) const {
+  bool ret = true;
+  string t1 = OutPortType;
+  string t2 = InPortType;
+  // if ANY is a string - the link is OK
+  if ( t1 == "string" || t2 == "string" )
+    ret = true;
+
+  // the next check prohibits linkage of "objref" to any simple type (int, char, etc.)
+  // it is still possible to link "objref" to some UNKNOWN type (probably objref, too,
+  // which interface name came from Cataloge
+  else if ( ( t1 == "objref" && isSimpleType( t2 ) ) ||  
+           ( t2 == "objref" && isSimpleType( t1 ) ) )
+    ret = false; 
+  return ret;
+}
 
 ostream & operator<< (ostream & f,const GraphEditor::OutNode & G) {
-  f << (GraphBase::ComputingNode ) G ;
+  f << (GraphBase::ComputingNode ) *(G.Graph()) ;
   f << endl ;
 
-  f << "  Nodes : " << G.GraphNodesSize() << " node" 
-    << (G.GraphNodesSize() > 1 ? "s" : "") << endl;
+  f << "  Nodes : " << (G.Graph())->GraphNodesSize() << " node" 
+    << ((G.Graph())->GraphNodesSize() > 1 ? "s" : "") << endl;
   
   int i ;
-  for ( i = 0 ; i < G.GraphNodesSize() ; i++ ) {
+  for ( i = 0 ; i < (G.Graph())->GraphNodesSize() ; i++ ) {
     f
-//      << hex << (void *) G.GraphNodes( i ) << dec << " "
-      << *G.GraphNodes( i ) << endl;
+//      << hex << (void *) G.Graph().GraphNodes( i ) << dec << " "
+      << (G.Graph())->GraphNodes( i ) << endl;
   }
 
   f << "  Links : " << endl ;
-  for ( i = 0 ; i < G.GraphNodesSize() ; i++ ) {
-    G.GraphNodes( i )->ListLinks( f ) ;
+  for ( i = 0 ; i < (G.Graph())->GraphNodesSize() ; i++ ) {
+    (G.Graph())->GraphNodes( i )->ListLinks( f ) ;
   }
 
   f << "  Datas : " << endl ;
-  G.ListDatas( f ) ;
+  (G.Graph())->ListDatas( f ) ;
 
-  f << "DataFlow " << G.Name() << " is " ;
+  f << "DataFlow " << (G.Graph())->Name() << " is " ;
   if ( G.IsNotValid() )
     f << "not " ;
   f << "valid and is " ;
@@ -1415,10 +1927,27 @@ ostream & operator<< (ostream &fOut,const SUPERV::SDate &D)
   return fOut;
 }
 
+/*
+GraphBase::Graph * GraphEditor::OutNode::MapGraph( const char * aGraphName ) {
+  GraphBase::Graph * aGraph = _MapOfGraphs[ aGraphName ] ;
+  return aGraph ;
+}
 
+bool GraphEditor::OutNode::MapGraph( GraphBase::Graph * aGraph , const char * aGraphName ) {
+  if ( MapGraph( aGraphName ) ) {
+    return false ;
+  }
+  _MapOfGraphs[ aGraphName ] = aGraph ;
+  return true ;
+}
 
+void GraphEditor::OutNode::EraseGraph( const char * aGraphName ) {
+  _MapOfGraphs.erase( aGraphName ) ;
+}
 
-
-
+bool GraphEditor::OutNode::GraphName( const char * aGraphName ) {
+  return  _MapOfGraphNames[ aGraphName ] ;
+}
+*/