Salome HOME
WIP
[modules/yacs.git] / src / engine / VisitorSaveSchema.cxx
index fd905b3ffffc0478437e2af5dac84aa5adc70405..85a30463cd9bb58df5d2a426f8a855f9b62420aa 100644 (file)
@@ -1,23 +1,45 @@
+// Copyright (C) 2006-2019  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
 
 #include "VisitorSaveSchema.hxx"
 
 #include "ElementaryNode.hxx"
 #include "InlineNode.hxx"
 #include "ServiceNode.hxx"
+#include "ServerNode.hxx"
 #include "ServiceInlineNode.hxx"
 #include "Bloc.hxx"
 #include "Proc.hxx"
 #include "ForEachLoop.hxx"
+#include "OptimizerLoop.hxx"
 #include "Loop.hxx"
 #include "ForLoop.hxx"
 #include "WhileLoop.hxx"
 #include "Switch.hxx"
 #include "InputPort.hxx"
 #include "TypeCode.hxx"
+#include "HomogeneousPoolContainer.hxx"
 #include "ComponentInstance.hxx"
 #include "InputDataStreamPort.hxx"
 #include "OutputDataStreamPort.hxx"
 #include "Container.hxx"
+#include "DataNode.hxx"
 
 #include <cassert>
 #include <iostream>
@@ -30,6 +52,12 @@ using namespace std;
 //#define _DEVDEBUG_
 #include "YacsTrace.hxx"
 
+/*! \class YACS::ENGINE::VisitorSaveSchema
+ *  \brief Base class for all visitors that save a schema.
+ *
+ *  Can be specialized in runtime.
+ */
+
 VisitorSaveSchema::VisitorSaveSchema(ComposedNode *root): _root(root), Visitor(root)
 {
 }
@@ -43,7 +71,7 @@ VisitorSaveSchema::~VisitorSaveSchema()
     }
 }
 
-void VisitorSaveSchema::openFileSchema(std::string xmlSchema) throw(Exception)
+void VisitorSaveSchema::openFileSchema(std::string xmlSchema) throw(YACS::Exception)
 {
   _out.open(xmlSchema.c_str(), ios::out);
   if (!_out)
@@ -51,8 +79,7 @@ void VisitorSaveSchema::openFileSchema(std::string xmlSchema) throw(Exception)
       string what = "Impossible to open file for writing: " + xmlSchema;
       throw Exception(what);
     }
-  _out << "<?xml version='1.0'?>" << endl;
-  _out << "<proc>" << endl;
+  _out << "<?xml version='1.0' encoding='iso-8859-1' ?>" << endl;
 }
 
 void VisitorSaveSchema::closeFileSchema()
@@ -72,6 +99,7 @@ void VisitorSaveSchema::visitBloc(Bloc *node)
     _out << " state=\"disabled\">" << endl;
   else
     _out << ">" << endl;
+  writeProperties(node);
   node->ComposedNode::accept(this);
   writeControls(node);
   writeSimpleDataLinks(node);
@@ -85,6 +113,7 @@ void VisitorSaveSchema::visitElementaryNode(ElementaryNode *node)
 {
   DEBTRACE("START visitElementaryNode " << _root->getChildName(node));
   beginCase(node);
+  writeProperties(node);
   writeInputPorts(node);
   writeInputDataStreamPorts(node);
   writeOutputPorts(node);
@@ -105,11 +134,13 @@ void VisitorSaveSchema::visitForEachLoop(ForEachLoop *node)
     _out << " state=\"disabled\"";
   if (!nbranch->isEmpty())
     _out << " nbranch=\"" << nbranch->getIntValue() << "\"";
+  _out << " loopWeight=\"" << node->getWeight()->getSimpleLoopWeight() << "\"";
   if (node->edGetSamplePort())
     _out << " type=\"" << node->edGetSamplePort()->edGetType()->name() << "\"";
   _out << ">" << endl;
   
-  node->ComposedNode::accept(this);
+  writeProperties(node);
+  node->DynParaLoop::accept(this);
   writeSimpleDataLinks(node);
   writeSimpleStreamLinks(node);
   _out << indent(depth) << "</foreach>" << endl;
@@ -117,6 +148,78 @@ void VisitorSaveSchema::visitForEachLoop(ForEachLoop *node)
   DEBTRACE("END visitForEachLoop " << _root->getChildName(node));
 }
 
+void VisitorSaveSchema::visitForEachLoopDyn(ForEachLoopDyn *node)
+{
+  DEBTRACE("START visitForEachLoopDyn " << _root->getChildName(node));
+  beginCase(node);
+  int depth = depthNode(node);
+
+  _out << indent(depth) << "<foreachdyn name=\"" << node->getName() << "\"";
+  if (node->getState() == YACS::DISABLED)
+    _out << " state=\"disabled\"";
+  _out << " loopWeight=\"" << node->getWeight()->getSimpleLoopWeight() << "\"";
+  if (node->edGetSamplePort())
+    _out << " type=\"" << node->edGetSamplePort()->edGetType()->name() << "\"";
+  _out << ">" << endl;
+  
+  writeProperties(node);
+  node->DynParaLoop::accept(this);
+  writeSimpleDataLinks(node);
+  writeSimpleStreamLinks(node);
+  _out << indent(depth) << "</foreachdyn>" << endl;
+  endCase(node);
+  DEBTRACE("END visitForEachLoopDyn " << _root->getChildName(node));
+}
+
+void VisitorSaveSchema::visitOptimizerLoop(OptimizerLoop *node)
+{
+  DEBTRACE("START visitOptimizerLoop " << _root->getChildName(node));
+  beginCase(node);
+  int depth = depthNode(node);
+
+  _out << indent(depth) << "<optimizer name=\"" << node->getName() << "\"";
+  AnyInputPort *nbranch = static_cast<AnyInputPort*>(node->edGetNbOfBranchesPort());
+  if (node->getState() == YACS::DISABLED)
+    _out << " state=\"disabled\"";
+  if (!nbranch->isEmpty())
+    _out << " nbranch=\"" << nbranch->getIntValue() << "\"";
+  _out << " loopWeight=\"" << node->getWeight()->getSimpleLoopWeight() << "\"";
+  _out << " lib=\"" << node->getAlgLib() << "\"";
+  _out << " entry=\"" << node->getSymbol() << "\"";
+  _out << ">" << endl;
+
+  writeProperties(node);
+  node->DynParaLoop::accept(this);
+  writeSimpleDataLinks(node);
+  writeSimpleStreamLinks(node);
+  _out << indent(depth) << "</optimizer>" << endl;
+  endCase(node);
+  DEBTRACE("END visitOptimizerLoop " << _root->getChildName(node));
+}
+
+void VisitorSaveSchema::visitDynParaLoop(DynParaLoop *node)
+{
+  DEBTRACE("START visitDynParaLoop " << _root->getChildName(node));
+  int depth = depthNode(node);
+  if (node->getInitNode() != NULL)
+    {
+      _out << indent(depth+1) << "<initnode>" << endl;
+      node->getInitNode()->accept(this);
+      _out << indent(depth+1) << "</initnode>" << endl;
+    }
+  if (node->getExecNode() != NULL)
+    {
+      node->getExecNode()->accept(this);
+    }
+  if (node->getFinalizeNode() != NULL)
+    {
+      _out << indent(depth+1) << "<finalizenode>" << endl;
+      node->getFinalizeNode()->accept(this);
+      _out << indent(depth+1) << "</finalizenode>" << endl;
+    }
+  DEBTRACE("END visitDynParaLoop " << _root->getChildName(node));
+}
+
 void VisitorSaveSchema::visitForLoop(ForLoop *node)
 {
   DEBTRACE("START visitForLoop " << _root->getChildName(node));
@@ -130,6 +233,7 @@ void VisitorSaveSchema::visitForLoop(ForLoop *node)
     _out << ">" << endl;
   else   
     _out << " nsteps=\"" << nsteps->getIntValue() << "\">" << endl;
+  writeProperties(node);
   node->ComposedNode::accept(this);
   writeSimpleDataLinks(node);
   writeSimpleStreamLinks(node);
@@ -143,7 +247,13 @@ void VisitorSaveSchema::visitInlineNode(InlineNode *node)
   DEBTRACE("START visitInlineNode " << _root->getChildName(node));
   beginCase(node);
   int depth = depthNode(node);
-  _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
+  if(node->getExecutionMode()==InlineNode::LOCAL_STR)
+    _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
+  else
+    {
+      _out << indent(depth) << "<remote name=\"" << node->getName() << "\"";
+      _out << " elementaryWeight=\"" << node->getWeight()->getElementaryWeight() << "\"";
+    }
   if (node->getState() == YACS::DISABLED)
     _out << " state=\"disabled\">" << endl;
   else
@@ -151,11 +261,23 @@ void VisitorSaveSchema::visitInlineNode(InlineNode *node)
   _out << indent(depth+1) << "<script><code><![CDATA[";
   _out << node->getScript();
   _out << "]]></code></script>" << endl;
+
+  //add load container if node is remote
+  Container *cont = node->getContainer();
+  if (cont)
+    _out << indent(depth+1) << "<load container=\"" << cont->getName() << "\"/>" << endl;
+
+  writeProperties(node);
   writeInputPorts(node);
   writeInputDataStreamPorts(node);
   writeOutputPorts(node);
   writeOutputDataStreamPorts(node);
-  _out << indent(depth) << "</inline>" << endl;
+
+  if(node->getExecutionMode()==InlineNode::LOCAL_STR)
+    _out << indent(depth) << "</inline>" << endl;
+  else
+    _out << indent(depth) << "</remote>" << endl;
+
   endCase(node);
   DEBTRACE("END visitInlineNode " << _root->getChildName(node));
 }
@@ -165,7 +287,13 @@ void VisitorSaveSchema::visitInlineFuncNode(InlineFuncNode *node)
   DEBTRACE("START visitInlineFuncNode " << _root->getChildName(node));
   beginCase(node);
   int depth = depthNode(node);
-  _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
+  if(node->getExecutionMode()==InlineNode::LOCAL_STR)
+    _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
+  else
+    {
+      _out << indent(depth) << "<remote name=\"" << node->getName() << "\"";
+      _out << " elementaryWeight=\"" << node->getWeight()->getElementaryWeight() << "\"";
+    }
   if (node->getState() == YACS::DISABLED)
     _out << " state=\"disabled\">" << endl;
   else
@@ -175,11 +303,23 @@ void VisitorSaveSchema::visitInlineFuncNode(InlineFuncNode *node)
   _out << node->getScript();
   _out << "]]></code>" << endl;
   _out << indent(depth+1) << "</function>" << endl;
+
+  //add load container if node is remote
+  Container *cont = node->getContainer();
+  if (cont)
+    _out << indent(depth+1) << "<load container=\"" << cont->getName() << "\"/>" << endl;
+
+  writeProperties(node);
   writeInputPorts(node);
   writeInputDataStreamPorts(node);
   writeOutputPorts(node);
   writeOutputDataStreamPorts(node);
-  _out << indent(depth) << "</inline>" << endl;
+
+  if(node->getExecutionMode()==InlineNode::LOCAL_STR)
+    _out << indent(depth) << "</inline>" << endl;
+  else
+    _out << indent(depth) << "</remote>" << endl;
+
   endCase(node);
   DEBTRACE("END visitInlineFuncNode " << _root->getChildName(node));
 }
@@ -189,6 +329,7 @@ void VisitorSaveSchema::visitLoop(Loop *node)
   DEBTRACE("START visitLoop " << _root->getChildName(node));
   beginCase(node);
   int depth = depthNode(node);
+  writeProperties(node);
   node->ComposedNode::accept(this);
   writeControls(node);
   writeSimpleDataLinks(node);
@@ -200,10 +341,12 @@ void VisitorSaveSchema::visitLoop(Loop *node)
 void VisitorSaveSchema::visitProc(Proc *node)
 {
   DEBTRACE("START visitProc " << node->getName());
+  _out << "<proc name=\""<< node->getName() << "\">" << endl;
   beginCase(node);
   writeProperties(node);
   writeTypeCodes(node);
   writeContainers(node);
+  writeComponentInstances(node);
   node->ComposedNode::accept(this);
   writeControls(node);
   writeSimpleDataLinks(node);
@@ -223,7 +366,7 @@ void VisitorSaveSchema::visitServiceNode(ServiceNode *node)
     _out << " state=\"disabled\">" << endl;
   else
     _out << ">" << endl;
-  if (node->getKind() == "XML")
+  if (node->getKind() == "xmlsh")
     {
       _out << indent(depth+1) << "<kind>xmlsh</kind>" << endl;
       _out << indent(depth+1) << "<ref>" << node->getRef() << "</ref>" << endl;
@@ -231,7 +374,11 @@ void VisitorSaveSchema::visitServiceNode(ServiceNode *node)
   else
     {
       ComponentInstance *compo = node->getComponent();
-      if (_componentInstanceMap.find(compo) == _componentInstanceMap.end())
+      if (compo && !compo->isAnonymous())
+        {
+          _out << indent(depth+1) << "<componentinstance>" << compo->getInstanceName() << "</componentinstance>" << endl;
+        }
+      else if (compo && (_componentInstanceMap.find(compo) == _componentInstanceMap.end()))
         {
           _out << indent(depth+1) << compo->getFileRepr() << endl;
           _componentInstanceMap[compo] = _root->getChildName(node);
@@ -247,13 +394,18 @@ void VisitorSaveSchema::visitServiceNode(ServiceNode *node)
                 _out << indent(depth+1) << "<load container=\"" << it->first << "\"/>" << endl;
             }
         }
-      else
+      else if(compo)
         {
           _out << indent(depth+1) << "<node>" << _componentInstanceMap[compo] << "</node>" << endl;
         }
+      else
+        {
+          _out << indent(depth+1) << "<component>" << "UNKNOWN" << "</component>" << endl;
+        }
     }
   _out << indent(depth+1) << "<method>" << node->getMethod() << "</method>" << endl;
 
+  writeProperties(node);
   writeInputPorts(node);
   writeInputDataStreamPorts(node);
   writeOutputPorts(node);
@@ -263,6 +415,43 @@ void VisitorSaveSchema::visitServiceNode(ServiceNode *node)
   DEBTRACE("END visitServiceNode " << _root->getChildName(node));
 }
 
+void VisitorSaveSchema::visitServerNode(ServerNode *node)
+{
+  DEBTRACE("START visitServerNode " << _root->getChildName(node));
+  beginCase(node);
+  int depth = depthNode(node);
+  _out << indent(depth) << "<server name=\"" << node->getName() << "\"";
+  if (node->getState() == YACS::DISABLED)
+    _out << " state=\"disabled\">" << endl;
+  else
+    _out << ">" << endl;
+  Container *cont = node->getContainer();
+  map<string, Container*>::const_iterator it;
+  for (it = _containerMap.begin(); it != _containerMap.end(); ++it)
+    {
+      if (it->second == cont) break;
+    }
+  if (it != _containerMap.end())
+    _out << indent(depth+1) << "<loadcontainer>" << it->first << "</loadcontainer>" << endl;
+  /*else
+    {
+      _out << indent(depth+1) << "<node>" << _contnentInstanceMap[cont] << "</node>" << endl;
+      }*/
+  _out << indent(depth+1) << "<method>" << node->getFname() << "</method>" << endl;
+  _out << indent(depth+2) << "<script><code><![CDATA[";
+  _out << node->getScript();
+  _out << "]]></code></script>" << endl;
+  //_out << indent(depth+1) << "</function>" << endl;
+  writeProperties(node);
+  writeInputPorts(node);
+  writeInputDataStreamPorts(node);
+  writeOutputPorts(node);
+  writeOutputDataStreamPorts(node);
+  _out << indent(depth) << "</server>" << endl;
+  endCase(node);
+  DEBTRACE("END visitServerNode " << _root->getChildName(node));
+}
+
 void VisitorSaveSchema::visitServiceInlineNode(ServiceInlineNode *node)
 {
   DEBTRACE("START visitServiceInlineNode " << _root->getChildName(node));
@@ -273,12 +462,17 @@ void VisitorSaveSchema::visitServiceInlineNode(ServiceInlineNode *node)
     _out << " state=\"disabled\">" << endl;
   else
     _out << ">" << endl;
-  _out << indent(depth+1) << node->getComponent()->getFileRepr() << endl;
+  
+  ComponentInstance *compo = node->getComponent();
+  if (compo)
+    _out << indent(depth+1) << compo->getFileRepr() << endl;
+
   _out << indent(depth+1) << "<function name=\"" << node->getMethod() << "\">" << endl;
   _out << indent(depth+2) << "<code><![CDATA[";
   _out << node->getScript();
   _out << "]]></code>" << endl;
   _out << indent(depth+1) << "</function>" << endl;
+  writeProperties(node);
   writeInputPorts(node);
   writeOutputPorts(node);
   _out << indent(depth) << "</serviceInline>" << endl;
@@ -286,6 +480,30 @@ void VisitorSaveSchema::visitServiceInlineNode(ServiceInlineNode *node)
   DEBTRACE("END visitServiceInlineNode " << _root->getChildName(node));
 }
 
+void VisitorSaveSchema::visitPresetNode(DataNode *node)
+{
+  DEBTRACE("START visitPresetNode " << _root->getChildName(node));
+  DEBTRACE("END visitPresetNode " << _root->getChildName(node));
+}
+
+void VisitorSaveSchema::visitOutNode(DataNode *node)
+{
+  DEBTRACE("START visitOutNode " << _root->getChildName(node));
+  DEBTRACE("END visitOutNode " << _root->getChildName(node));
+}
+
+void VisitorSaveSchema::visitStudyInNode(DataNode *node)
+{
+  DEBTRACE("START visitStudyInNode " << _root->getChildName(node));
+  DEBTRACE("END visitStudyInNode " << _root->getChildName(node));
+}
+
+void VisitorSaveSchema::visitStudyOutNode(DataNode *node)
+{
+  DEBTRACE("START visitStudyOutNode " << _root->getChildName(node));
+  DEBTRACE("END visitStudyOutNode " << _root->getChildName(node));
+}
+
 
 void VisitorSaveSchema::visitSwitch(Switch *node)
 {
@@ -300,6 +518,7 @@ void VisitorSaveSchema::visitSwitch(Switch *node)
     _out << ">" << endl;
   else   
     _out << " select=\"" << condition->getIntValue() << "\">" << endl;
+  writeProperties(node);
   node->ComposedNode::accept(this);
   writeControls(node);
   writeSimpleDataLinks(node);
@@ -319,6 +538,7 @@ void VisitorSaveSchema::visitWhileLoop(WhileLoop *node)
     _out << " state=\"disabled\">" << endl;
   else
     _out << ">" << endl;
+  writeProperties(node);
   node->ComposedNode::accept(this);
   writeSimpleDataLinks(node);
   writeSimpleStreamLinks(node);
@@ -340,101 +560,164 @@ void VisitorSaveSchema::writeProperties(Node *node)
     }
 }
 
-void VisitorSaveSchema::writeTypeCodes(Proc *proc)
+void VisitorSaveSchema::dumpTypeCode(TypeCode* type, std::set<std::string>& typeNames,std::map<std::string, TypeCode*>& typeMap,int depth)
 {
-  int depth = depthNode(proc)+1;
-  map<string, TypeCode*> typeMap = getTypeCodeMap(proc);
-  map<string, TypeCode*>::const_iterator it;
-  set<string> typeNames;
-
-  // --- force definition of simple types first
-
-  _out << indent(depth) << "<type name=\"Bool\" kind=\"bool\"/>" << endl;
-  _out << indent(depth) << "<type name=\"Double\" kind=\"double\"/>" << endl;
-  _out << indent(depth) << "<type name=\"Int\" kind=\"int\"/>" << endl;
-  _out << indent(depth) << "<type name=\"String\" kind=\"string\"/>" << endl;
-  typeNames.insert("Bool");
-  typeNames.insert("Double");
-  typeNames.insert("Int");
-  typeNames.insert("String");
-
-  for (it = typeMap.begin(); it != typeMap.end(); it++)
+  DynType kind = type->kind();
+  string typeName = type->name();
+  if (typeNames.find(typeName) != typeNames.end())
+    return;
+  switch(kind)
     {
-      DynType kind = (it->second)->kind();
-      string typeId = (it->second)->id();
-      switch(kind)
-        {
-        case YACS::ENGINE::Double:
+    case YACS::ENGINE::Double:
+      {
+        typeNames.insert(typeName);
+        _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"double\"/>" << endl;
+        break;
+      }
+    case YACS::ENGINE::Int:
+      {
+        typeNames.insert(typeName);
+        _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"int\"/>" << endl;
+        break;
+      }
+    case YACS::ENGINE::String:
+      {
+        typeNames.insert(typeName);
+        _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"string\"/>" << endl;
+        break;
+      }
+    case YACS::ENGINE::Bool:
+      {
+        typeNames.insert(typeName);
+        _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"bool\"/>" << endl;
+        break;
+      }
+    case YACS::ENGINE::Objref:
+      {
+        TypeCodeObjref *objref = dynamic_cast<TypeCodeObjref*>(type);
+        std::list<TypeCodeObjref*> listOfBases = getListOfBases(objref);
+        //try to dump base classes
+        for(std::list<TypeCodeObjref*>::iterator il=listOfBases.begin(); il != listOfBases.end(); ++il)
           {
-            if (typeNames.find(typeId) == typeNames.end())
-              {
-                typeNames.insert(typeId);
-                _out << indent(depth) << "<type name=\"" << typeId << "\" kind=\"double\"/>" << endl;
-              }
-            break;
+            if (typeNames.find((*il)->name()) == typeNames.end())
+              dumpTypeCode((*il),typeNames,typeMap,depth);
           }
-        case YACS::ENGINE::Int:
+        //effective dump
+        typeNames.insert(typeName);
+        _out << indent(depth) << "<objref name=\"" << typeName << "\" id=\""
+             << objref->id() << "\"";
+        if (listOfBases.empty())
+          _out << "/>" << endl;
+        else
           {
-            if (typeNames.find(typeId) == typeNames.end())
+            _out << ">" << endl;
+            for(std::list<TypeCodeObjref*>::iterator il=listOfBases.begin(); il != listOfBases.end(); ++il)
               {
-                typeNames.insert(typeId);
-                _out << indent(depth) << "<type name=\"" << typeId << "\" kind=\"int\"/>" << endl;
+                _out << indent(depth+1) << "<base>";
+                _out << (*il)->name();
+                _out << "</base>" << endl;
               }
-            break;
+            _out << indent(depth) << "</objref>" << endl;
           }
-        case YACS::ENGINE::String:
+        break;
+      }
+    case YACS::ENGINE::Sequence:
+      {
+        TypeCode* content = (TypeCode*)type->contentType();
+        if (typeNames.find(content->name()) == typeNames.end())
           {
-            if (typeNames.find(typeId) == typeNames.end())
-              {
-                typeNames.insert(typeId);
-                _out << indent(depth) << "<type name=\"" << typeId << "\" kind=\"string\"/>" << endl;
-              }
-            break;
+            //content type not dumped
+            dumpTypeCode(content,typeNames,typeMap,depth);
           }
-        case YACS::ENGINE::Bool:
+        typeNames.insert(typeName);
+        _out << indent(depth) << "<sequence name=\"" << typeName << "\" content=\""
+             << content->name() <<  "\"/>" << endl;
+        break;
+      }
+    case YACS::ENGINE::Array:
+      {
+        TypeCode* content = (TypeCode*)type->contentType();
+        if (typeNames.find(content->name()) == typeNames.end())
           {
-            if (typeNames.find(typeId) == typeNames.end())
-              {
-                typeNames.insert(typeId);
-                _out << indent(depth) << "<type name=\"" << typeId << "\" kind=\"bool\"/>" << endl;
-              }
-            break;
+            //content type not dumped
+            dumpTypeCode(content,typeNames,typeMap,depth);
           }
-        case YACS::ENGINE::Objref:
+        typeNames.insert(typeName);
+        _out << indent(depth) << "<array name=\"" << typeName << "\" content=\""
+             << content->name() <<  "\"/>" << endl;
+        break;
+      }
+    case YACS::ENGINE::Struct:
+      {
+        TypeCodeStruct* tcStruct = dynamic_cast<TypeCodeStruct*>(type);
+        YASSERT(tcStruct);
+        int mbCnt = tcStruct->memberCount();
+        for (int i=0; i<mbCnt; i++)
           {
-            TypeCodeObjref *objref = dynamic_cast<TypeCodeObjref*>(it->second);
-            assert(objref);
-            std::list<TypeCodeObjref*> listOfBases = getListOfBases(objref);
-            _out << indent(depth) << "<objref name=\"" << it->first << "\" id=\""
-                 << objref->id() << "\"";
-            if (listOfBases.empty())
-              _out << "/>" << endl;
-            else
+            TypeCode* member = tcStruct->memberType(i);
+            if (typeNames.find(member->name()) == typeNames.end())
               {
-                _out << ">" << endl;
-                for(std::list<TypeCodeObjref*>::iterator il=listOfBases.begin(); il != listOfBases.end(); ++il)
-                  {
-                    _out << indent(depth+1) << "<base>";
-                    _out << (*il)->name();
-                    _out << "</base>" << endl;
-                  }
-                _out << indent(depth) << "</objref>" << endl;
-              }
-            break;
+                //content type not dumped
+                dumpTypeCode(member,typeNames,typeMap,depth);
+              }            
           }
-        case YACS::ENGINE::Sequence:
+        typeNames.insert(typeName);
+        _out << indent(depth) << "<struct name=\"" << typeName << "\">" << endl;
+        for (int i=0; i<mbCnt; i++)
           {
-            const TypeCode* content = (it->second)->contentType();
-
-            _out << indent(depth) << "<sequence name=\"" << it->first << "\" content=\""
-                 << content->name() <<  "\"/>" << endl;
-            break;
-          }
-        default:
-          {
-            string what = "wrong TypeCode: "; 
-            throw Exception(what);
+            TypeCode* member = tcStruct->memberType(i);
+            _out << indent(depth+1) << "<member name=\"" <<tcStruct->memberName(i) << "\" type=\"" << member->name() << "\"/>" << endl;
           }
+        _out << indent(depth) << "</struct>" << endl;
+        break;
+      }
+    default:
+      {
+        string what = "wrong TypeCode: "; 
+        throw Exception(what);
+      }
+    }
+}
+
+void VisitorSaveSchema::writeTypeCodes(Proc *proc)
+{
+  int depth = depthNode(proc)+1;
+  map<string, TypeCode*> typeMap = getTypeCodeMap(proc);
+  map<string, TypeCode*>::const_iterator it;
+  set<string> typeNames;
+
+  // --- force definition of simple types first
+
+  for (it = typeMap.begin(); it != typeMap.end(); it++)
+    {
+      dumpTypeCode(it->second,typeNames,typeMap,depth);
+    }
+}
+
+void VisitorSaveSchema::writeComponentInstances(Proc *proc)
+{
+  int depth = depthNode(proc)+1;
+  std::map<std::string, ComponentInstance*>::const_iterator it;
+  for (it = proc->componentInstanceMap.begin(); it != proc->componentInstanceMap.end(); it++)
+    {
+      string name = it->first;
+      ComponentInstance* inst=it->second;
+      if(!inst->isAnonymous())
+        {
+          _out << indent(depth) << "<componentinstance name=\"" << inst->getInstanceName() << "\">" << endl;
+          _out << indent(depth+1) << "<component>" << inst->getCompoName() << "</component>" << endl;
+
+          Container *cont = inst->getContainer();
+          if (cont)
+            _out << indent(depth+1) << "<load container=\"" << cont->getName() << "\"/>" << endl;
+
+          std::map<std::string, std::string> properties = inst->getProperties();
+          std::map<std::string, std::string>::const_iterator itm;
+          for(itm = properties.begin(); itm != properties.end(); ++itm)
+            _out << indent(depth+1) << "<property name=\"" << (*itm).first
+                 << "\" value=\"" << (*itm).second << "\"/>" << endl;
+
+          _out << indent(depth) << "</componentinstance>" << endl;
         }
     }
 }
@@ -448,6 +731,25 @@ void VisitorSaveSchema::writeContainers(Proc *proc)
     {
       string name = it->first;
       _out << indent(depth) << "<container name=\"" << name << "\">" << endl;
+      _out << indent(depth+1) << "<property name=\"" << Container::KIND_ENTRY << "\" value=\"" << it->second->getKind() << "\"/>" << endl;
+      _out << indent(depth+1) << "<property name=\"" << Container::AOC_ENTRY << "\" value=\"" << (int)it->second->isAttachedOnCloning() << "\"/>" << endl;
+      map<string, string> properties = (it->second)->getProperties();
+      map<string, string>::iterator itm;
+      for(itm = properties.begin(); itm != properties.end(); ++itm)
+        {
+          if((*itm).first==Container::KIND_ENTRY)
+            continue;
+          if((*itm).first==Container::AOC_ENTRY)
+            continue;
+          if((*itm).first!=HomogeneousPoolContainer::INITIALIZE_SCRIPT_KEY)
+            {
+              _out << indent(depth+1) << "<property name=\"" << (*itm).first << "\" value=\"" << (*itm).second << "\"/>" << endl;
+            }
+          else
+            {
+              _out << indent(depth+1) << "<initializescriptkey><code><![CDATA[" << (*itm).second << "]]></code></initializescriptkey>" << endl;
+            }
+        }
       _out << indent(depth) << "</container>"  << endl;
     }
 }
@@ -470,19 +772,19 @@ void VisitorSaveSchema::writeInputDataStreamPorts(Node *node)
   list<InputDataStreamPort*> listOfInputPorts = node->getSetOfInputDataStreamPort();
   for (list<InputDataStreamPort*>::iterator it = listOfInputPorts.begin(); it != listOfInputPorts.end(); ++it)
     {
-      std::map<std::string,std::string> aPropMap = (*it)->getPropertyMap();
+      std::map<std::string,std::string> aPropMap = (*it)->getProperties();
       if ( aPropMap.empty() )
-       _out << indent(depth) << "<instream name=\"" << (*it)->getName() << "\" type=\"" 
-            << (*it)->edGetType()->name() << "\"/>" << endl;
+        _out << indent(depth) << "<instream name=\"" << (*it)->getName() << "\" type=\"" 
+             << (*it)->edGetType()->name() << "\"/>" << endl;
       else
-       {
-         _out << indent(depth) << "<instream name=\"" << (*it)->getName() << "\" type=\"" 
-              << (*it)->edGetType()->name() << "\">" << endl;
-         for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
-           _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\"" 
-                << (*itP).second << "\"/>" << endl;
-         _out << indent(depth) << "</instream>" << endl;
-       }
+        {
+          _out << indent(depth) << "<instream name=\"" << (*it)->getName() << "\" type=\"" 
+               << (*it)->edGetType()->name() << "\">" << endl;
+          for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
+            _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\"" 
+                 << (*itP).second << "\"/>" << endl;
+          _out << indent(depth) << "</instream>" << endl;
+        }
     }
 }
 
@@ -503,31 +805,31 @@ void VisitorSaveSchema::writeOutputDataStreamPorts(Node *node)
   list<OutputDataStreamPort*> listOfOutputPorts = node->getSetOfOutputDataStreamPort();
   for (list<OutputDataStreamPort*>::iterator it = listOfOutputPorts.begin(); it != listOfOutputPorts.end(); ++it)
     {
-      std::map<std::string,std::string> aPropMap = (*it)->getPropertyMap();
+      std::map<std::string,std::string> aPropMap = (*it)->getProperties();
       if ( aPropMap.empty() )
-       _out << indent(depth) << "<outstream name=\"" << (*it)->getName() << "\" type=\"" 
-            << (*it)->edGetType()->name() << "\"/>" << endl;
+        _out << indent(depth) << "<outstream name=\"" << (*it)->getName() << "\" type=\"" 
+             << (*it)->edGetType()->name() << "\"/>" << endl;
       else
-       {
-         _out << indent(depth) << "<outstream name=\"" << (*it)->getName() << "\" type=\"" 
-              << (*it)->edGetType()->name() << "\">" << endl;
-         for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
-           _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\"" 
-                << (*itP).second << "\"/>" << endl;
-         _out << indent(depth) << "</outstream>" << endl;
-       }
+        {
+          _out << indent(depth) << "<outstream name=\"" << (*it)->getName() << "\" type=\"" 
+               << (*it)->edGetType()->name() << "\">" << endl;
+          for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
+            _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\"" 
+                 << (*itP).second << "\"/>" << endl;
+          _out << indent(depth) << "</outstream>" << endl;
+        }
     }
 }
 
 void VisitorSaveSchema::writeControls(ComposedNode *node)
 {
   int depth = depthNode(node)+1;
-  set<Node*> setOfChildren =  node->edGetDirectDescendants();
-  for (set<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
+  list<Node*> setOfChildren =  node->edGetDirectDescendants();
+  for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
     {
       // --- Control links from direct descendant to nodes inside the bloc
-      set<InGate*> setOfInGates = (*ic)->getOutGate()->edSetInGate();
-      for (set<InGate*>::iterator ig = setOfInGates.begin(); ig != setOfInGates.end(); ++ig)
+      list<InGate*> setOfInGates = (*ic)->getOutGate()->edSetInGate();
+      for (list<InGate*>::iterator ig = setOfInGates.begin(); ig != setOfInGates.end(); ++ig)
         {
           Node *to = (*ig)->getNode();
           if (node->isInMyDescendance(to))
@@ -563,18 +865,22 @@ void VisitorSaveSchema::writeControls(ComposedNode *node)
 void VisitorSaveSchema::writeSimpleDataLinks(ComposedNode *node)
 {
   int depth = depthNode(node)+1;
-  set<Node*> setOfChildren =  node->edGetDirectDescendants();
+  list<Node*> setOfChildren =  node->edGetDirectDescendants();
 
-  set<Node*> setOfChildrenPlusSplitters = setOfChildren;
+  list<Node*> setOfChildrenPlusSplitters = setOfChildren;
 
-  for (set<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
+  for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
     // add "splitter" node of ForEachLoop nodes to the set of children
-    if ( dynamic_cast<ForEachLoop*>( *ic ) )
-      setOfChildrenPlusSplitters.insert( (*ic)->getChildByName(ForEachLoop::NAME_OF_SPLITTERNODE) );
+    if ( dynamic_cast<ForEachLoopGen*>( *ic ) )
+      {
+        Node *nodeToInsert=(*ic)->getChildByName(ForEachLoop::NAME_OF_SPLITTERNODE);
+        if(find(setOfChildrenPlusSplitters.begin(),setOfChildrenPlusSplitters.end(),nodeToInsert)==setOfChildrenPlusSplitters.end())
+          setOfChildrenPlusSplitters.push_back(nodeToInsert);
+      }
   
   // --- first pass,  write links where the input port is inside the node scope. Keep in memory others.
   
-  for (set<Node*>::iterator ic = setOfChildrenPlusSplitters.begin(); ic != setOfChildrenPlusSplitters.end(); ++ic)
+  for (list<Node*>::iterator ic = setOfChildrenPlusSplitters.begin(); ic != setOfChildrenPlusSplitters.end(); ++ic)
     {
       Node* from = *ic;
       list<OutputPort*> listOP = from->getLocalOutputPorts();
@@ -586,25 +892,25 @@ void VisitorSaveSchema::writeSimpleDataLinks(ComposedNode *node)
             {
               InPort *anIP = *iip;
               Node* to = anIP->getNode();
-              cerr << "from " << from->getName() << " outputPort " << anOP->getName()
-                   << " to " << to->getName() << " inputPort " << anIP->getName() << endl;
+              DEBTRACE("from " << from->getName() << " outputPort " << anOP->getName()
+                       << " to " << to->getName() << " inputPort " << anIP->getName() );
               Node* child = node->isInMyDescendance(to);
               if (child && (child->getNumId() != node->getNumId())
                   && (from->getNumId() != to->getNumId()))
                 {
-                  cerr << "BINGO!" << endl;
-
-                 string fromName;
-                 if ( dynamic_cast<SplitterNode*>(from) && dynamic_cast<ForEachLoop*>(from->getFather()) )
-                   fromName = from->getFather()->getName();
-                 else
-                   fromName = node->getChildName(from);
-
-                 string childName;
-                 if ( dynamic_cast<SplitterNode*>(to) && dynamic_cast<ForEachLoop*>(to->getFather()) )
-                   childName = node->getChildName(to->getFather());
-                 else
-                   childName = node->getChildName(to);
+                  DEBTRACE( "BINGO!" );
+
+                  string fromName;
+                  if ( dynamic_cast<SplitterNode*>(from) && dynamic_cast<ForEachLoopGen*>(from->getFather()) )
+                    fromName = from->getFather()->getName();
+                  else
+                    fromName = node->getChildName(from);
+
+                  string childName;
+                  if ( dynamic_cast<SplitterNode*>(to) && dynamic_cast<ForEachLoopGen*>(to->getFather()) )
+                    childName = node->getChildName(to->getFather());
+                  else
+                    childName = node->getChildName(to);
                   _out << indent(depth) << "<datalink control=\"false\">" << endl;
                   _out << indent(depth+1) << "<fromnode>" << fromName << "</fromnode> ";
                   _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
@@ -614,7 +920,7 @@ void VisitorSaveSchema::writeSimpleDataLinks(ComposedNode *node)
                 }
               else
                 { // --- store info to create the link later, given the input port
-                  cerr << "For later" << endl;
+                  DEBTRACE( "For later" );
                   struct DataLinkInfo aLink = { from, to, anOP, anIP, false };
                   _mapOfDLtoCreate.insert(make_pair(anIP->getNumId(), aLink));
                 }
@@ -668,11 +974,11 @@ void VisitorSaveSchema::writeSimpleDataLinks(ComposedNode *node)
 void VisitorSaveSchema::writeSimpleStreamLinks(ComposedNode *node)
 {
   int depth = depthNode(node)+1;
-  set<Node*> setOfChildren =  node->edGetDirectDescendants();
+  list<Node*> setOfChildren =  node->edGetDirectDescendants();
 
   // --- first pass,  write links where the input port is inside the node scope. Keep in memory others.
 
-  for (set<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
+  for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
     {
       Node* from = *ic;
       if ( dynamic_cast<ComposedNode*>(from) ) continue;
@@ -685,13 +991,13 @@ void VisitorSaveSchema::writeSimpleStreamLinks(ComposedNode *node)
             {
               InPort *anIP = *iip;
               Node* to = anIP->getNode();
-              cerr << "from " << from->getName() << " outputPort " << anOP->getName()
-                   << " to " << to->getName() << " inputPort " << anIP->getName() << endl;
+              DEBTRACE("from " << from->getName() << " outputPort " << anOP->getName()
+                       << " to " << to->getName() << " inputPort " << anIP->getName() );
               Node* child = node->isInMyDescendance(to);
               if (child && (child->getNumId() != node->getNumId())
                   && (from->getNumId() != to->getNumId()))
                 {
-                  cerr << "BINGO!" << endl;
+                  DEBTRACE( "BINGO!" );
                   string childName = node->getChildName(to);
                   _out << indent(depth) << "<stream>" << endl;
                   _out << indent(depth+1) << "<fromnode>" << node->getChildName(from) << "</fromnode> ";
@@ -699,21 +1005,24 @@ void VisitorSaveSchema::writeSimpleStreamLinks(ComposedNode *node)
                   _out << indent(depth+1) << "<tonode>" << childName << "</tonode> ";
                   _out << "<toport>" << anIP->getName() << "</toport>" << endl;
 
-                 std::map<std::string,std::string> aPropMap = anOP->getPropertyMap();
-                 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
-                   _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\"" 
-                        << (*itP).second << "\"/>" << endl;
-
+                  std::map<std::string,std::string> aPropMap = dynamic_cast<InputDataStreamPort*>(anIP)->getProperties();
+                  for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
+                    {
+                      string notAlinkProperty = "DependencyType";
+                      if (notAlinkProperty != (*itP).first)
+                        _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\"" 
+                             << (*itP).second << "\"/>" << endl;
+                    }
                   _out << indent(depth) << "</stream>" << endl;
-               }
+                }
               else
                 { // --- store info to create the link later, given the input port
-                  cerr << "For later" << endl;
+                  DEBTRACE("For later" );
                   struct StreamLinkInfo aLink = { from, to, anOP, anIP, false };
                   _mapOfSLtoCreate.insert(make_pair(anIP->getNumId(), aLink));
                 }
             }
-       }
+        }
     }
 
   // --- second pass, retreive links where the output port is inside the scope.
@@ -743,10 +1052,10 @@ void VisitorSaveSchema::writeSimpleStreamLinks(ComposedNode *node)
                     _out << indent(depth+1) << "<tonode>" << node->getChildName(to) << "</tonode> ";
                     _out << "<toport>" << anIP->getName() << "</toport>" << endl;
 
-                   std::map<std::string,std::string> aPropMap = anOP->getPropertyMap();
-                   for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
-                     _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\"" 
-                          << (*itP).second << "\"/>" << endl;
+                    std::map<std::string,std::string> aPropMap = dynamic_cast<InputDataStreamPort*>(anIP)->getProperties();
+                    for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
+                      _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\"" 
+                           << (*itP).second << "\"/>" << endl;
 
                     _out << indent(depth) << "</stream>" << endl;
                   }
@@ -768,8 +1077,8 @@ void VisitorSaveSchema::writeSimpleStreamLinks(ComposedNode *node)
 std::set<Node*> VisitorSaveSchema::getAllNodes(ComposedNode *node)
 {
   set<Node *> ret;
-  set<Node *> setOfNode = node->edGetDirectDescendants();
-  for(set<Node *>::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
+  list< Node *> setOfNode = node->edGetDirectDescendants();
+  for(list<Node *>::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
     {
       if ( dynamic_cast<ComposedNode*> (*iter) )
         {
@@ -779,12 +1088,12 @@ std::set<Node*> VisitorSaveSchema::getAllNodes(ComposedNode *node)
         }
       else
         {
-          set<ElementaryNode *> myCurrentSet=(*iter)->getRecursiveConstituents();
+          list<ElementaryNode *> myCurrentSet=(*iter)->getRecursiveConstituents();
           ret.insert(myCurrentSet.begin(),myCurrentSet.end());
           ret.insert(*iter);
         }
     }
-   return ret;
+  return ret;
 }
 
 void VisitorSaveSchema::writeParameters(Proc *proc)
@@ -793,9 +1102,9 @@ void VisitorSaveSchema::writeParameters(Proc *proc)
   set<Node*> nodeSet = getAllNodes(proc);
   for (set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter)
     {
-//       ElementaryNode *node = dynamic_cast<ElementaryNode*>(*iter);
-//       if (node)
-//         writeParametersNode(proc,node);
+      //       ElementaryNode *node = dynamic_cast<ElementaryNode*>(*iter);
+      //       if (node)
+      //         writeParametersNode(proc,node);
       writeParametersNode(proc,(*iter));
     }
 }
@@ -804,11 +1113,6 @@ void VisitorSaveSchema::writeParametersNode(ComposedNode *proc, Node *node)
 {
   int depth = 1;
   list<InputPort *> setOfInputPort = node->getLocalInputPorts();
-  if (ForEachLoop* foreach = dynamic_cast<ForEachLoop*>(node))
-    {
-      DEBTRACE("writeParametersNode foreach");
-      setOfInputPort.push_back( foreach->edGetSeqOfSamplesPort());
-    }
   list<InputPort *>::iterator iter;
   for(iter = setOfInputPort.begin(); iter != setOfInputPort.end(); ++iter)
     {
@@ -874,7 +1178,7 @@ int VisitorSaveSchema::depthNode(Node* node)
 
 SchemaSave::SchemaSave(Proc* proc): _p(proc)
 {
-  assert(_p);
+  YASSERT(_p);
 }
 
 void SchemaSave::save(std::string xmlSchemaFile)