Salome HOME
For future compatibility with python 3.9.
[modules/yacs.git] / src / runtime / RuntimeSALOME.cxx
index b3755924d47995279f96caf6b73d6fad50656c75..99f57715231a2a5b4b84e12db0a0226586217b13 100644 (file)
@@ -1,4 +1,24 @@
+// Copyright (C) 2006-2021  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
+//
+
 //#define REFCNT
+//
 #ifdef REFCNT
 #define private public
 #define protected public
 #endif
 
 #include "yacsconfig.h"
+#include "YACS_version.h"
 #include "RuntimeSALOME.hxx"
 #include "SALOMEDispatcher.hxx"
 #include "Proc.hxx"
+#include "TypeCode.hxx"
 #include "WhileLoop.hxx"
 #include "ForLoop.hxx"
+#include "ForEachLoop.hxx"
+#include "SalomeOptimizerLoop.hxx"
 #include "Bloc.hxx"
 #include "InputPort.hxx"
 #include "OutputPort.hxx"
+#include "PresetPorts.hxx"
 #include "InputDataStreamPort.hxx"
 #include "OutputDataStreamPort.hxx"
+#include "Switch.hxx"
 #include "SalomeProc.hxx"
+#include "PyStdout.hxx"
+//Catalog Loaders
+#include "SessionCataLoader.hxx"
+
 //Components
 #include "CORBAComponent.hxx"
 #include "SalomeComponent.hxx"
+#include "SalomeHPComponent.hxx"
 #include "SalomePythonComponent.hxx"
 #include "CppComponent.hxx"
 
 #include "SalomeContainer.hxx"
 #include "CppContainer.hxx"
+#include "SalomeHPContainer.hxx"
 
 //Nodes
 #include "PythonNode.hxx"
 #include "CORBANode.hxx"
 #include "XMLNode.hxx"
 #include "CppNode.hxx"
-#include "TypeConversions.hxx"
+#include "PresetNode.hxx"
+#include "OutNode.hxx"
+#include "StudyNodes.hxx"
 #include "SalomePythonNode.hxx"
+#include "DistributedPythonNode.hxx"
+
 //CORBA proxy ports
 #include "CORBACORBAConv.hxx"
 #include "CORBAPythonConv.hxx"
 #include "CORBACppConv.hxx"
 #include "CORBANeutralConv.hxx"
 
+#include "TypeConversions.hxx"
 //Python proxy ports
 #include "PythonCORBAConv.hxx"
 #include "PythonXMLConv.hxx"
 #include "PythonCppConv.hxx"
 #include "PythonNeutralConv.hxx"
+#include "PythonInitConv.hxx"
 
 //Neutral proxy ports
 #include "NeutralCORBAConv.hxx"
 #include "NeutralPythonConv.hxx"
 #include "NeutralXMLConv.hxx"
 #include "NeutralCppConv.hxx"
+#include "NeutralInitConv.hxx"
 
 //C++ proxy ports
 #include "CppCORBAConv.hxx"
 #ifdef SALOME_KERNEL
 #include "SALOME_NamingService.hxx"
 #include "SALOME_LifeCycleCORBA.hxx"
+#include "SALOME_NamingService.hxx"
+#include "SALOME_ResourcesManager.hxx"
+#include "SALOME_ContainerManager.hxx"
+#include "SALOMEconfig.h"
+#include CORBA_CLIENT_HEADER(SALOME_ContainerManager)
+
 #endif
   
 #include <libxml/parser.h>
 using namespace std;
 using namespace YACS::ENGINE;
 
-void RuntimeSALOME::setRuntime(long flags) // singleton creation (not thread safe!)
+void RuntimeSALOME::setRuntime(long flags, int argc, char* argv[]) // singleton creation (not thread safe!)
 {
   if (! Runtime::_singleton)
     {
-      Runtime::_singleton = new RuntimeSALOME(flags);
+      RuntimeSALOME* r=new RuntimeSALOME(flags, argc, argv);
+      Runtime::_singleton = r;
+      r->initBuiltins();
     }
   DEBTRACE("RuntimeSALOME::setRuntime() done !");
 }
 
 RuntimeSALOME* YACS::ENGINE::getSALOMERuntime()
 {
-  assert(Runtime::_singleton);
-  return dynamic_cast< RuntimeSALOME* >(Runtime::_singleton);
+  YASSERT(RuntimeSALOME::getSingleton());
+  return dynamic_cast< RuntimeSALOME* >(RuntimeSALOME::getSingleton());
 }
 
 /**
@@ -108,10 +155,54 @@ RuntimeSALOME* YACS::ENGINE::getSALOMERuntime()
   
 RuntimeSALOME::RuntimeSALOME()
 {
-  assert(0);
+  YASSERT(0);
+}
+
+void RuntimeSALOME::initBuiltins()
+{
+  //Fill the builtin catalog with nodes specific to the runtime
+  std::map<std::string,TypeCode*>& typeMap=_builtinCatalog->_typeMap;
+  std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
+  std::map<std::string,ComposedNode*>& composednodeMap=_builtinCatalog->_composednodeMap;
+  std::map<std::string,ComponentDefinition*>& componentMap=_builtinCatalog->_componentMap;
+  nodeMap["PyFunction"]=new PyFuncNode("PyFunction");
+  nodeMap["PyScript"]=new PythonNode("PyScript");
+  nodeMap["CORBANode"]=new CORBANode("CORBANode");
+  nodeMap["XmlNode"]=new XmlNode("XmlNode");
+  nodeMap["SalomeNode"]=new SalomeNode("SalomeNode");
+  nodeMap["CppNode"]=new CppNode("CppNode");
+  nodeMap["SalomePythonNode"]=new SalomePythonNode("SalomePythonNode");
+  nodeMap["PresetNode"]=new PresetNode("PresetNode");
+  nodeMap["OutNode"]=new OutNode("OutNode");
+  nodeMap["StudyInNode"]=new StudyInNode("StudyInNode");
+  nodeMap["StudyOutNode"]=new StudyOutNode("StudyOutNode");
+  composednodeMap["OptimizerLoop"]=createOptimizerLoop("OptimizerLoop","","",true);
+  typeMap["dblevec"]= createSequenceTc("dblevec","dblevec",_tc_double);
+  typeMap["intvec"]= createSequenceTc("intvec","intvec",_tc_int);
+  typeMap["stringvec"]= createSequenceTc("stringvec","stringvec",_tc_string);
+  typeMap["boolvec"]= createSequenceTc("boolvec","boolvec",_tc_bool);
+  typeMap["seqdblevec"]= createSequenceTc("seqdblevec","seqdblevec",typeMap["dblevec"]);
+  typeMap["seqintvec"]= createSequenceTc("seqintvec","seqintvec",typeMap["intvec"]);
+  typeMap["seqstringvec"]= createSequenceTc("seqstringvec","seqstringvec",typeMap["stringvec"]);
+  typeMap["seqboolvec"]= createSequenceTc("seqboolvec","seqboolvec",typeMap["boolvec"]);
+  std::list<TypeCodeObjref *> ltc;
+  typeMap["pyobj"]= createInterfaceTc("python:obj:1.0","pyobj",ltc);
+  typeMap["seqpyobj"]= createSequenceTc("seqpyobj","seqpyobj",typeMap["pyobj"]);
+  composednodeMap["Bloc"]=createBloc("Bloc");
+  composednodeMap["Switch"]=createSwitch("Switch");
+  composednodeMap["WhileLoop"]=createWhileLoop("WhileLoop");
+  composednodeMap["ForLoop"]=createForLoop("ForLoop");
+  composednodeMap["ForEachLoop_double"]=createForEachLoop("ForEachLoop_double",Runtime::_tc_double);
+  composednodeMap["ForEachLoop_string"]=createForEachLoop("ForEachLoop_string",Runtime::_tc_string);
+  composednodeMap["ForEachLoop_int"]=createForEachLoop("ForEachLoop_int",Runtime::_tc_int);
+  composednodeMap["ForEachLoop_bool"]=createForEachLoop("ForEachLoop_bool",Runtime::_tc_bool);
+  composednodeMap["ForEachLoop_pyobj"]=createForEachLoop("ForEachLoop_pyobj",typeMap["pyobj"]);;
+  ENGINE::TypeCodeStruct *t = createStructTc("","Engines/dataref");
+  t->addMember("ref",_tc_string);
+  typeMap["dataref"]= t;
 }
 
-RuntimeSALOME::RuntimeSALOME(long flags)
+RuntimeSALOME::RuntimeSALOME(long flags, int argc, char* argv[])
 {
   // If all flags (apart the IsPyExt flags) are unset, force them to true
   if ((flags - flags & RuntimeSALOME::IsPyExt) == 0)
@@ -131,15 +222,25 @@ RuntimeSALOME::RuntimeSALOME(long flags)
   _useCpp = flags & RuntimeSALOME::UseCpp;
   _useXml = flags & RuntimeSALOME::UseXml;
 
+  /* Init libxml */
+  xmlInitParser();
+
   if (_useCpp)    _setOfImplementation.insert(CppNode::IMPL_NAME);
   if (_usePython) _setOfImplementation.insert(PythonNode::IMPL_NAME);
   if (_useCorba)  _setOfImplementation.insert(CORBANode::IMPL_NAME);
   if (_useXml)    _setOfImplementation.insert(XmlNode::IMPL_NAME);
-  init(flags);
+  init(flags, argc, argv);
 }
 
 RuntimeSALOME::~RuntimeSALOME()
 {
+  DEBTRACE("RuntimeSALOME::~RuntimeSALOME");
+  // destroy catalog loader prototypes
+  std::map<std::string, CatalogLoader*>::const_iterator pt;
+  for(pt=_catalogLoaderFactoryMap.begin();pt!=_catalogLoaderFactoryMap.end();pt++)
+    {
+      delete (*pt).second;
+    }
 }
 
 //! CORBA and Python initialization
@@ -152,20 +253,30 @@ RuntimeSALOME::~RuntimeSALOME()
  *            bit1 (UseXml)    true if python nodes are needed
  *            bit1 (UseCpp)    true if C++ nodes are needed
  *            bit1 (UseSalome) true if Salome nodes are needed
+ *  \param argc number of command line arguments (used to initialize the Python interpreter)
+ *  \param argv command line arguments (used to initialize the Python interpreter)
  *
  */
 
-void RuntimeSALOME::init(long flags)
+void RuntimeSALOME::init(long flags, int argc, char* argv[])
 {
   bool ispyext = flags & RuntimeSALOME::IsPyExt;
   if (_useCorba)
     {
+      PortableServer::POA_var root_poa;
+      PortableServer::POAManager_var pman;
+      CORBA::Object_var obj;
       int nbargs = 0; char **args = 0;
       _orb = CORBA::ORB_init (nbargs, args);
+      obj = _orb->resolve_initial_references("RootPOA");
+      root_poa = PortableServer::POA::_narrow(obj);
+      pman = root_poa->the_POAManager();
+      pman->activate();
+
 #ifdef REFCNT
       DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
 #endif
-      CORBA::Object_var obj = _orb->resolve_initial_references("DynAnyFactory");
+      obj = _orb->resolve_initial_references("DynAnyFactory");
       _dynFactory = DynamicAny::DynAnyFactory::_narrow(obj);
     }
 
@@ -176,8 +287,36 @@ void RuntimeSALOME::init(long flags)
       // Initialize Python interpreter in embedded mode
       if (!Py_IsInitialized())
         {
+#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
+          Py_Initialize(); 
+#else
           Py_InitializeEx(0); // do not install signal handlers
+#endif
+          if (argc > 0 && argv != NULL)
+            {
+              wchar_t **changed_argv = new wchar_t*[argc];
+              for (int i = 0; i < argc; i++)
+              {
+                changed_argv[i] = Py_DecodeLocale(argv[i], NULL);
+              }
+              PySys_SetArgv(argc, changed_argv);
+            } 
+          else
+            {
+              int pyArgc = 1;
+              char* pyArgv[1];
+              char defaultName[] = "SALOME_YACS_RUNTIME";
+              wchar_t **changed_pyArgv = new wchar_t*[pyArgc];
+              pyArgv[0] = defaultName;
+              for (int i = 0; i < pyArgc; i++)
+              {
+                changed_pyArgv[i] = Py_DecodeLocale(pyArgv[i], NULL);
+              }
+              PySys_SetArgv(pyArgc, changed_pyArgv);
+            }
+#if PY_VERSION_HEX < 0x03070000
           PyEval_InitThreads(); /* Create (and acquire) the interpreter lock (for threads)*/
+#endif
           PyEval_SaveThread(); /* Release the thread state */
           //here we do not have the Global Interpreter Lock
         }
@@ -193,42 +332,47 @@ void RuntimeSALOME::init(long flags)
   
       if (PyDict_GetItemString(globals, "__builtins__") == NULL) 
         {
-          PyObject *bimod = PyImport_ImportModule("__builtin__");
+          PyObject *bimod = PyImport_ImportModule("builtins");
           if (bimod == NULL || PyDict_SetItemString(globals, "__builtins__", bimod) != 0)
             Py_FatalError("can't add __builtins__ to __main__");
           Py_DECREF(bimod);
         }
 
       _bltins = PyEval_GetBuiltins();  /* borrowed ref */
-  
+
       if (_useCorba)
         {
 
           //init section
-          PyObject* omnipy = PyImport_ImportModule((char*)"_omnipy");
-          if (!omnipy)
+          _omnipy = PyImport_ImportModule((char*)"_omnipy");
+          if (!_omnipy)
             {
               PyErr_Print();
               PyErr_SetString(PyExc_ImportError, (char*)"Cannot import _omnipy");
               goto out;
             }
-          pyapi = PyObject_GetAttrString(omnipy, (char*)"API");
+          pyapi = PyObject_GetAttrString(_omnipy, (char*)"API");
           if (!pyapi)
             {
               goto out;
             }
-          _api = (omniORBpyAPI*)PyCObject_AsVoidPtr(pyapi);
+          _api = (omniORBpyAPI*)PyCapsule_GetPointer(pyapi,"_omnipy.API");
           Py_DECREF(pyapi);
 
           res=PyRun_String("\n"
-                             "import sys\n"
-                             "sys.path.insert(0,'.')\n"
-                             "from omniORB import CORBA\n"
-                             "from omniORB import any\n"
-                             "orb = CORBA.ORB_init([], CORBA.ORB_ID)\n"
-                             "#print sys.getrefcount(orb)\n"
-                             "\n",
-                             Py_file_input,globals,globals );
+                           "from math import *\n"
+                           "import sys\n"
+                           "sys.path.insert(0,'.')\n"
+                           "from omniORB import CORBA\n"
+                           "from omniORB import any\n"
+                           "orb = CORBA.ORB_init([], CORBA.ORB_ID)\n"
+                           "#print(sys.getrefcount(orb))\n"
+                           "try:\n"
+                           "  import SALOME\n"
+                           "except:\n"
+                           "  pass\n"
+                           "\n",
+                           Py_file_input,globals,globals );
           if(res == NULL)
             {
               PyErr_Print();
@@ -250,6 +394,11 @@ void RuntimeSALOME::init(long flags)
       out:
         PyGILState_Release(gstate); // Release the Global Interpreter Lock
     }
+  if (_useCorba)
+    {
+      // initialize the catalogLoaderFactory map with the session one
+      _catalogLoaderFactoryMap["session"]=new SessionCataLoader;
+    }
 }
 
 void RuntimeSALOME::fini()
@@ -274,6 +423,14 @@ void RuntimeSALOME::fini()
           else
             Py_DECREF(res);
         }
+      std::map<std::string,Node*>& nodeMap=_builtinCatalog->_nodeMap;
+      delete nodeMap["PyFunction"];
+      delete nodeMap["PyScript"];
+      delete nodeMap["SalomePythonNode"];
+      nodeMap.erase("PyFunction");
+      nodeMap.erase("PyScript");
+      nodeMap.erase("SalomePythonNode");
+
       Py_Finalize();
 #ifdef REFCNT
       DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
@@ -291,11 +448,102 @@ void RuntimeSALOME::fini()
     }
 }
 
+std::vector< std::pair<std::string,int> > RuntimeSALOME::getCatalogOfComputeNodes() const
+{
+  CORBA::ORB_ptr orb(getOrb());
+  SALOME_NamingService namingService;
+  try
+  {
+    namingService.init_orb(orb);
+  }
+  catch(SALOME_Exception& e)
+  {
+    throw Exception("RuntimeSALOME::getCatalogOfComputeNodes : Unable to contact the SALOME Naming Service");
+  }
+  CORBA::Object_var obj(namingService.Resolve(SALOME_ResourcesManager::_ResourcesManagerNameInNS));
+  if(CORBA::is_nil(obj))
+    throw Exception("RuntimeSALOME::getCatalogOfComputeNodes : Unable to access to the resource manager !");
+  Engines::ResourcesManager_var resManager(Engines::ResourcesManager::_narrow(obj));
+  if(CORBA::is_nil(resManager))
+    throw Exception("RuntimeSALOME::getCatalogOfComputeNodes : Internal error ! The entry attached to the res manager in NS does not have right type !");
+  std::vector< std::pair<std::string,int> > ret;
+  Engines::ResourceParameters params;
+  params.name = "";
+  params.hostname = "";
+  params.OS = "";
+  params.nb_proc = 0;
+  params.mem_mb = 0;
+  params.cpu_clock = 0;
+  params.nb_node = 0;
+  params.nb_proc_per_node = 0;
+  params.policy = "";
+  params.can_launch_batch_jobs = false;
+  params.can_run_containers = true;
+  params.componentList.length(0);
+  try
+  {
+    Engines::ResourceList_var resourceList;
+    resourceList = resManager->GetFittingResources(params);
+    ret.reserve(resourceList->length());
+    for(int i = 0; i<resourceList->length(); i++)
+    {
+      const char* resource_name = resourceList[i];
+      std::string std_resource_name = resource_name;
+      Engines::ResourceDefinition_var resource_definition
+                              = resManager->GetResourceDefinition(resource_name);
+      int nb_cores = resource_definition->nb_node *
+                     resource_definition->nb_proc_per_node;
+      ret.push_back(std::pair<std::string,int>(resource_name, nb_cores));
+    }
+  }
+  catch(SALOME::SALOME_Exception& e)
+  {
+    std::string message;
+    message=e.details.text.in();
+    throw Exception(message);
+  }
+
+  return ret;
+}
+
+std::string RuntimeSALOME::getVersion() const
+{
+#ifdef YACS_DEVELOPMENT
+  return CORBA::string_dup(YACS_VERSION_STR"dev");
+#else
+  return CORBA::string_dup(YACS_VERSION_STR);
+#endif
+}
+
 Proc* RuntimeSALOME::createProc(const std::string& name)
 {
   return new SalomeProc(name);
 }
 
+TypeCode * RuntimeSALOME::createInterfaceTc(const std::string& id, const std::string& name,
+                                            std::list<TypeCodeObjref *> ltc)
+{
+  std::string myName;
+  if(id == "") myName = "IDL:" + name + ":1.0";
+  else myName = id;
+  return TypeCode::interfaceTc(myName.c_str(),name.c_str(),ltc);
+}
+
+TypeCode * RuntimeSALOME::createSequenceTc(const std::string& id,
+                                           const std::string& name,
+                                           TypeCode *content)
+{
+  return TypeCode::sequenceTc(id.c_str(),name.c_str(),content);
+};
+
+TypeCodeStruct * RuntimeSALOME::createStructTc(const std::string& id, const std::string& name)
+{
+  std::string myName;
+  if(id == "") myName = "IDL:" + name + ":1.0";
+  else myName = id;
+  return (TypeCodeStruct *)TypeCode::structTc(myName.c_str(),name.c_str());
+}
+
 Bloc* RuntimeSALOME::createBloc(const std::string& name)
 {
   return new Bloc(name);
@@ -311,6 +559,46 @@ ForLoop* RuntimeSALOME::createForLoop(const std::string& name)
   return new ForLoop(name);
 }
 
+OptimizerLoop* RuntimeSALOME::createOptimizerLoop(const std::string& name,const std::string& algLib,const std::string& factoryName,
+                                                  bool algInitOnFile, const std::string& kind, Proc * procForTypes)
+{
+  OptimizerLoop * ol = (kind == "base") ? new OptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes) :
+                                          new SalomeOptimizerLoop(name,algLib,factoryName,algInitOnFile, true, procForTypes);
+  ol->edGetNbOfBranchesPort()->edInit(1);
+  return ol;
+}
+
+DataNode* RuntimeSALOME::createInDataNode(const std::string& kind,const std::string& name)
+{
+  DataNode* node;
+  if(kind == "" )
+    {
+      node = new PresetNode(name);
+      return node;
+    }
+  else if(kind == "study" )
+    {
+      return new StudyInNode(name);
+    }
+  std::string msg="DataNode kind ("+kind+") unknown";
+  throw Exception(msg);
+}
+
+DataNode* RuntimeSALOME::createOutDataNode(const std::string& kind,const std::string& name)
+{
+  if(kind == "" )
+    {
+      return new OutNode(name);
+    }
+  else if(kind == "study" )
+    {
+      return new StudyOutNode(name);
+    }
+
+  std::string msg="OutDataNode kind ("+kind+") unknown";
+  throw Exception(msg);
+}
+
 InlineFuncNode* RuntimeSALOME::createFuncNode(const std::string& kind,const std::string& name)
 {
   InlineFuncNode* node;
@@ -319,6 +607,8 @@ InlineFuncNode* RuntimeSALOME::createFuncNode(const std::string& kind,const std:
       node = new PyFuncNode(name);
       return node;
     }
+  if(kind == DistributedPythonNode::KIND)
+    return new DistributedPythonNode(name);
   std::string msg="FuncNode kind ("+kind+") unknown";
   throw Exception(msg);
 }
@@ -389,15 +679,19 @@ ComponentInstance* RuntimeSALOME::createComponentInstance(const std::string& nam
     return new SalomePythonComponent(name);
   else if (kind == CppComponent::KIND)
     return new CppComponent(name);
+  else if (kind == SalomeHPComponent::KIND)
+    return new SalomeHPComponent(name);
   std::string msg="Component Instance kind ("+kind+") unknown";
   throw Exception(msg);
 }
 
 Container *RuntimeSALOME::createContainer(const std::string& kind)
 {
-  if(kind == "" || kind == SalomeComponent::KIND)
+  if(kind == "" || kind == SalomeContainer::KIND)
     return new SalomeContainer;
-  else if (kind == CppComponent::KIND)
+  if(kind==SalomeHPContainer::KIND)
+    return new SalomeHPContainer;
+  else if (kind == CppContainer::KIND)
     return new CppContainer;
   std::string msg="Container kind ("+kind+") unknown";
   throw Exception(msg);
@@ -428,7 +722,7 @@ InputPort * RuntimeSALOME::createInputPort(const std::string& name,
     {
       stringstream msg;
       msg << "Cannot create " << impl << " InputPort" ;
-      msg << " ("__FILE__ << ":" << __LINE__ << ")";
+      msg << " (" << __FILE__ << ":" << __LINE__ << ")";
       throw Exception(msg.str());
     }
 }
@@ -458,7 +752,7 @@ OutputPort * RuntimeSALOME::createOutputPort(const std::string& name,
     {
       stringstream msg;
       msg << "Cannot create " << impl << " OutputPort" ;
-      msg << " ("__FILE__ << ":" << __LINE__ << ")";
+      msg << " (" << __FILE__ << ":" << __LINE__ << ")";
       throw Exception(msg.str());
     }
 }
@@ -496,43 +790,60 @@ OutputDataStreamPort* RuntimeSALOME::createOutputDataStreamPort(const std::strin
  *  \param source : InputPort to be adapted
  *  \param impl : new implementation (C++, python, CORBA, XML, Neutral)
  *  \param type : data type provided by the InputPort
+ *  \param init : indicates if the adapted InputPort will be used for initialization (value true) or not (value false)
  * 
  * \return : adapted InputPort
  */
 InputPort* RuntimeSALOME::adapt(InputPort* source,
                                 const std::string& impl,
-                                TypeCode * type) throw (ConversionException)
+                                TypeCode * type,bool init)
 {
   string imp_source=source->getNode()->getImplementation();
   if(imp_source == PythonNode::IMPL_NAME)
     {
-      return adapt((InputPyPort*)source,impl,type);
+      return adapt((InputPyPort*)source,impl,type,init);
     }
   else if(imp_source == CppNode::IMPL_NAME)
     {
-      return adapt((InputCppPort*)source,impl,type);
+      return adapt((InputCppPort*)source,impl,type,init);
     }
   else if(imp_source == CORBANode::IMPL_NAME)
     {
-      return adapt((InputCorbaPort*)source,impl,type);
+      return adapt((InputCorbaPort*)source,impl,type,init);
     }
   else if(imp_source == XmlNode::IMPL_NAME)
     {
-      return adapt((InputXmlPort*)source,impl,type);
+      return adapt((InputXmlPort*)source,impl,type,init);
     }
   else if(imp_source == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
     {
-      return adaptNeutral(source,impl,type);
+      return adaptNeutral(source,impl,type,init);
     }
   else
     {
       stringstream msg;
       msg << "Cannot adapt " << imp_source << " InputPort to " << impl;
-      msg << " ("__FILE__ << ":" << __LINE__ << ")";
+      msg << " (" << __FILE__ << ":" << __LINE__ << ")";
       throw ConversionException(msg.str());
     }
 }
 
+//! Adapter function for InPropertyPort
+/*!
+ *  \param source : InPropertyPort to be adapted
+ *  \param impl : new implementation (C++, python, CORBA, XML, Neutral)
+ *  \param type : data type provided by the InPropertyPort
+ *  \param init : indicates if the adapted InPropertyPort will be used for initialization (value true) or not (value false)
+ * 
+ * \return : adapted InputPort
+ */
+InputPort* RuntimeSALOME::adapt(InPropertyPort* source,
+                                const std::string& impl,
+                                TypeCode * type,bool init)
+{
+  return adaptNeutral((InputPort *)source,impl,type,init);
+}
+
 //! Adapt a Neutral input port to a Corba output port
 /*!
  *   \param inport : Neutral input port to adapt to Corba type type
@@ -540,7 +851,7 @@ InputPort* RuntimeSALOME::adapt(InputPort* source,
  *   \return an adaptated input port of type InputCorbaPort
  */
 InputPort* RuntimeSALOME::adaptNeutralToCorba(InputPort* inport,
-                      TypeCode * type) throw (ConversionException)
+                      TypeCode * type)
 {
   // BEWARE : using the generic check
   if(inport->edGetType()->isAdaptable(type))
@@ -550,8 +861,11 @@ InputPort* RuntimeSALOME::adaptNeutralToCorba(InputPort* inport,
     }
   //non convertible type
   stringstream msg;
-  msg << "Cannot connect Neutral InputPort to OutputCorbaPort : " ;
-  msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+  msg << "Cannot connect Corba output port with type: " << type->id() ;
+  msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
   throw ConversionException(msg.str());
 }
 
@@ -562,7 +876,7 @@ InputPort* RuntimeSALOME::adaptNeutralToCorba(InputPort* inport,
  *   \return an adaptated input port of type InputPyPort
  */
 InputPort* RuntimeSALOME::adaptNeutralToPython(InputPort* inport,
-                      TypeCode * type) throw (ConversionException)
+                      TypeCode * type)
 {
   // BEWARE : using the generic check
   if(inport->edGetType()->isAdaptable(type))
@@ -570,10 +884,18 @@ InputPort* RuntimeSALOME::adaptNeutralToPython(InputPort* inport,
       //convertible type
       return new PyNeutral(inport);
     }
+  //last chance : an py output that is seq[objref] can be connected to a neutral input objref (P13268)
+  else if(type->kind()==Sequence && type->contentType()->kind()==Objref && inport->edGetType()->kind()==Objref)
+    {
+      return new PyNeutral(inport);
+    }
   //non convertible type
   stringstream msg;
-  msg << "Cannot connect Neutral InputPort to OutputPyPort : " ;
-  msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+  msg << "Cannot connect Python output port with type: " << type->id() ;
+  msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
   throw ConversionException(msg.str());
 }
 
@@ -584,7 +906,7 @@ InputPort* RuntimeSALOME::adaptNeutralToPython(InputPort* inport,
  *   \return an input port of type InputXmlPort
  */
 InputPort* RuntimeSALOME::adaptNeutralToXml(InputPort* inport,
-                      TypeCode * type) throw (ConversionException)
+                      TypeCode * type)
 {
   // BEWARE : using the generic check
   if(inport->edGetType()->isAdaptable(type))
@@ -594,8 +916,11 @@ InputPort* RuntimeSALOME::adaptNeutralToXml(InputPort* inport,
     }
   //non convertible type
   stringstream msg;
-  msg << "Cannot connect Neutral InputPort to OutputXmlPort : " ;
-  msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+  msg << "Cannot connect Xml output port with type: " << type->id() ;
+  msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
   throw ConversionException(msg.str());
 }
 
@@ -606,7 +931,7 @@ InputPort* RuntimeSALOME::adaptNeutralToXml(InputPort* inport,
  *   \return an input port of type InputCppPort
  */
 InputPort* RuntimeSALOME::adaptNeutralToCpp(InputPort* inport,
-                      TypeCode * type) throw (ConversionException)
+                      TypeCode * type)
 {
   DEBTRACE("RuntimeSALOME::adaptNeutralToCpp(InputPort* inport" );
   if(isAdaptableNeutralCpp(type,inport->edGetType()))
@@ -616,9 +941,11 @@ InputPort* RuntimeSALOME::adaptNeutralToCpp(InputPort* inport,
     }
   //non convertible type
   stringstream msg;
-  msg << "Cannot connect Neutral " << inport->edGetType()->getKindRepr() 
-      << " InputPort to " << type->getKindRepr() << " OutputCppPort : " ;
-  msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+  msg << "Cannot connect Cpp output port with type: " << type->id() ;
+  msg << " to Neutral input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
   throw ConversionException(msg.str());
 }
 
@@ -627,11 +954,12 @@ InputPort* RuntimeSALOME::adaptNeutralToCpp(InputPort* inport,
  *   \param source : Neutral input port to adapt to implementation impl and type type
  *   \param impl : output port implementation (C++, Python, Corba, Xml or Neutral)
  *   \param type : output port supported type
+ *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
  *   \return       the adaptated port
  */
 InputPort* RuntimeSALOME::adaptNeutral(InputPort* source,
                                        const std::string& impl,
-                                       TypeCode * type) throw (ConversionException)
+                                       TypeCode * type,bool init)
 {
   if(impl == CppNode::IMPL_NAME)
     {
@@ -645,13 +973,16 @@ InputPort* RuntimeSALOME::adaptNeutral(InputPort* source,
     {
       return adaptNeutralToCorba(source,type);
     }
-  else if(impl == XmlNode::IMPL_NAME)
+  else if(impl == XmlNode::IMPL_NAME )
     {
       return adaptNeutralToXml(source,type);
     }
   else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
     {
-      return new ProxyPort(source);
+      if(init)
+        return new NeutralInit(source);
+      else
+        return new ProxyPort(source);
     }
   stringstream msg;
   msg << "Cannot connect InputPort : unknown implementation " << impl;
@@ -667,7 +998,7 @@ InputPort* RuntimeSALOME::adaptNeutral(InputPort* source,
  */
 
 InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport,
-                                          TypeCode * type) throw (ConversionException)
+                                          TypeCode * type)
 {
   if(isAdaptableXmlCorba(type,inport->edGetType()))
     {
@@ -676,9 +1007,11 @@ InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport,
     }
   //output type is not convertible
   stringstream msg;
-  msg << "Cannot connect InputXmlPort to Corba output port " ;
-  msg << type->id() << " != " << inport->edGetType()->id();
-  msg << " ("__FILE__ << ":" << __LINE__ << ")";
+  msg << "Cannot connect Corba output port with type: " << type->id() ;
+  msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
   throw ConversionException(msg.str());
 }
 
@@ -689,7 +1022,7 @@ InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport,
  *   \return an adaptated input port of type InputPyPort
  */
 InputPort* RuntimeSALOME::adaptXmlToPython(InputXmlPort* inport,
-                      TypeCode * type) throw (ConversionException)
+                      TypeCode * type)
 {
   if(inport->edGetType()->isAdaptable(type))
     {
@@ -698,8 +1031,11 @@ InputPort* RuntimeSALOME::adaptXmlToPython(InputXmlPort* inport,
     }
   //non convertible type
   stringstream msg;
-  msg << "Cannot connect Xml InputPort to OutputPyPort : " ;
-  msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+  msg << "Cannot connect Python output port with type: " << type->id() ;
+  msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
   throw ConversionException(msg.str());
 }
 
@@ -710,7 +1046,7 @@ InputPort* RuntimeSALOME::adaptXmlToPython(InputXmlPort* inport,
  *   \return an adaptated input port of type InputPyPort
  */
 InputPort* RuntimeSALOME::adaptXmlToCpp(InputXmlPort* inport,
-                      TypeCode * type) throw (ConversionException)
+                      TypeCode * type)
 {
   DEBTRACE("RuntimeSALOME::adaptXmlToCpp(InputPort* inport" );
   DEBTRACE(type->kind() << "   " << inport->edGetType()->kind() );
@@ -721,8 +1057,11 @@ InputPort* RuntimeSALOME::adaptXmlToCpp(InputXmlPort* inport,
     }
   //non convertible type
   stringstream msg;
-  msg << "Cannot connect Xml InputPort to OutputCppPort : " ;
-  msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+  msg << "Cannot connect Cpp output port with type: " << type->id() ;
+  msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
   throw ConversionException(msg.str());
 }
 
@@ -733,7 +1072,7 @@ InputPort* RuntimeSALOME::adaptXmlToCpp(InputXmlPort* inport,
  *   \return an adaptated input port of type Neutralxxxx
  */
 InputPort* RuntimeSALOME::adaptXmlToNeutral(InputXmlPort* inport,
-                      TypeCode * type) throw (ConversionException)
+                      TypeCode * type)
 {
   if(inport->edGetType()->isAdaptable(type))
     {
@@ -747,17 +1086,43 @@ InputPort* RuntimeSALOME::adaptXmlToNeutral(InputXmlPort* inport,
   throw ConversionException(msg.str());
 }
 
+//! Adapt a XML input port to a Xml output port
+/*!
+ *   \param inport : input port to adapt to Xml type type
+ *   \param type : output port type
+ *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
+ *   \return an adaptated input port of type Xmlxxxx
+ */
+InputPort* RuntimeSALOME::adaptXmlToXml(InputXmlPort* inport,
+                      TypeCode * type,bool init)
+{
+  if(init)
+    return new ProxyPort(inport);
+
+  if(inport->edGetType()->isAdaptable(type))
+    return new ProxyPort(inport);
+
+  stringstream msg;
+  msg << "Cannot connect Xml output port with type: " << type->id() ;
+  msg << " to Xml input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
+  throw ConversionException(msg.str());
+}
+
 //! Adapt an Xml input port to an output port which implementation is given by impl
 /*!
  *   \param source : input port to adapt to implementation impl and type type
  *   \param impl : output port implementation (C++, Python or Corba)
  *   \param type : output port supported type
+ *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
  *   \return       the adaptated port
  */
 
 InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
                                 const std::string& impl,
-                                TypeCode * type) throw (ConversionException)
+                                TypeCode * type,bool init)
 {
   if(impl == CORBANode::IMPL_NAME)
     {
@@ -771,9 +1136,9 @@ InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
     {
       return adaptXmlToCpp(source,type);
     }
-  else if(impl == XmlNode::IMPL_NAME)
+  else if(impl == XmlNode::IMPL_NAME )
     {
-      return new ProxyPort(source);
+      return adaptXmlToXml(source,type,init);
     }
   else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
     {
@@ -783,7 +1148,7 @@ InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
     {
       stringstream msg;
       msg << "Cannot connect InputXmlPort to " << impl << " implementation";
-      msg << " ("__FILE__ << ":" << __LINE__ << ")";
+      msg << " (" << __FILE__ << ":" << __LINE__ << ")";
       throw ConversionException(msg.str());
     }
 }
@@ -796,7 +1161,7 @@ InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
  *   \return an adaptator port of type InputCORBAPort 
  */
 InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport,
-                                            TypeCode * type) throw (ConversionException)
+                                            TypeCode * type)
 {
   if(type->isA(inport->edGetType()))
     {
@@ -812,8 +1177,11 @@ InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport,
     }
   //outport data can not be converted
   stringstream msg;
-  msg << "Cannot connect 2 CorbaPort with non convertible types: " ;
-  msg << type->id() << " != " << inport->edGetType()->id();
+  msg << "Cannot connect Corba output port with type: " << type->id() ;
+  msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
   throw ConversionException(msg.str());
 }
 
@@ -825,7 +1193,7 @@ InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport,
  */
 
 InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport,
-                                             TypeCode * type) throw (ConversionException)
+                                             TypeCode * type)
 {
   if(inport->edGetType()->kind() == Double)
     {
@@ -852,8 +1220,9 @@ InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport,
       else
         {
           stringstream msg;
-          msg << "Cannot connect InputPyPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id();
-          msg << " " << __FILE__ << ":" <<__LINE__;
+          msg << "Cannot connect Python output port with type: " << type->id() ;
+          msg << " to CORBA input port " << inport->getName() << " with incompatible objref type: " << inport->edGetType()->id();
+          msg << " (" << __FILE__ << ":" <<__LINE__ << ")";
           throw ConversionException(msg.str());
         }
     }
@@ -887,8 +1256,11 @@ InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport,
     }
   // Adaptation not possible
   stringstream msg;
-  msg << "Cannot connect InputCorbaPort to Python output " ;
-  msg << __FILE__ << ":" <<__LINE__;
+  msg << "Cannot connect Python output port with type: " << type->id() ;
+  msg << " to CORBA input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
   throw ConversionException(msg.str());
 }
 
@@ -900,7 +1272,7 @@ InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport,
  */
 
 InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport,
-                                          TypeCode * type) throw (ConversionException)
+                                          TypeCode * type)
 {
   // BEWARE : using the generic check
   if(inport->edGetType()->isAdaptable(type))
@@ -910,8 +1282,11 @@ InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport,
     }
   //output type is not convertible
   stringstream msg;
-  msg << "Cannot connect InputCorbaPort with OutputXmlPort : " ;
-  msg << __FILE__ << ":" <<__LINE__;
+  msg << "Cannot connect Xml output port with type: " << type->id() ;
+  msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
   throw ConversionException(msg.str());
 }
 
@@ -923,7 +1298,7 @@ InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport,
  */
 
 InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport,
-                                          TypeCode * type) throw (ConversionException)
+                                          TypeCode * type)
 {
   DEBTRACE("RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport" );
   if(isAdaptableCorbaCpp(type,inport->edGetType()))
@@ -933,8 +1308,11 @@ InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport,
     }
   //output type is not convertible
   stringstream msg;
-  msg << "Cannot connect InputCorbaPort with OutputCppPort : " ;
-  msg << __FILE__ << ":" <<__LINE__;
+  msg << "Cannot connect Cpp output port with type: " << type->id() ;
+  msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
   throw ConversionException(msg.str());
 }
 
@@ -946,7 +1324,7 @@ InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport,
  */
 
 InputPort* RuntimeSALOME::adaptCorbaToNeutral(InputCorbaPort* inport,
-                                              TypeCode * type) throw (ConversionException)
+                                              TypeCode * type)
 {
   if(inport->edGetType()->kind() == Double)
     {
@@ -980,11 +1358,18 @@ InputPort* RuntimeSALOME::adaptCorbaToNeutral(InputCorbaPort* inport,
           throw ConversionException(msg.str());
         }
     }
+  else if(inport->edGetType()->kind() == Struct)
+    {
+      if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaStruct(inport);
+    }
 
   // Adaptation not possible
   stringstream msg;
-  msg << "Cannot connect InputCorbaPort to Neutral output " ;
-  msg << __FILE__ << ":" <<__LINE__;
+  msg << "Cannot connect Neutral output port with type: " << type->id() ;
+  msg << " to Corba input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
   throw ConversionException(msg.str());
 }
 
@@ -993,12 +1378,13 @@ InputPort* RuntimeSALOME::adaptCorbaToNeutral(InputCorbaPort* inport,
  *   \param source : input port to adapt to implementation impl and type type
  *   \param impl : output port implementation (C++, Python or Corba)
  *   \param type : outport data type 
+ *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
  *   \return an adaptator port which type depends on impl
  */
 
 InputPort* RuntimeSALOME::adapt(InputCorbaPort* source,
                                 const std::string& impl,
-                                TypeCode * type) throw (ConversionException)
+                                TypeCode * type,bool init)
 {
   if(impl == CppNode::IMPL_NAME)
     {
@@ -1010,9 +1396,12 @@ InputPort* RuntimeSALOME::adapt(InputCorbaPort* source,
     }
   else if(impl == CORBANode::IMPL_NAME)
     {
-      return adaptCorbaToCorba(source,type);
+      if(init)
+        return adaptCorbaToCorba(source,type);
+      else
+        return adaptCorbaToCorba(source,type);
     }
-  else if(impl == XmlNode::IMPL_NAME)
+  else if(impl == XmlNode::IMPL_NAME )
     {
       return adaptCorbaToXml(source,type);
     }
@@ -1035,12 +1424,16 @@ InputPort* RuntimeSALOME::adapt(InputCorbaPort* source,
  * Only check, it's possible.
  *   \param inport : InputPort to adapt to Python type type
  *   \param type : outport data type 
+ *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
  *   \return an adaptator port of type InputPyPort 
  */
 
 InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport,
-                                              TypeCode * type) throw (ConversionException)
+                                              TypeCode * type,bool init)
 {
+  if(init)
+    return new PyInit(inport);
+
   if(isAdaptablePyObjectPyObject(type,inport->edGetType()))
     {
       //output data is convertible to input type
@@ -1050,9 +1443,11 @@ InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport,
     }
   //output data is not convertible to input type
   stringstream msg;
-  msg << "Cannot connect 2 Python Port with non convertible types: " ;
-  msg << type->id() << " != " << inport->edGetType()->id();
+  msg << "Cannot connect Python output port with type: " << type->id() ;
+  msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
   msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
   throw ConversionException(msg.str());
 }
 
@@ -1064,7 +1459,7 @@ InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport,
  */
 
 InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport,
-                                           TypeCode * type) throw (ConversionException)
+                                           TypeCode * type)
 {
   DEBTRACE("RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport" );
   if(isAdaptablePyObjectCpp(type,inport->edGetType()))
@@ -1074,8 +1469,11 @@ InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport,
     }
   //output type is not convertible
   stringstream msg;
-  msg << "Cannot connect InputPythonPort with OutputCppPort : " ;
-  msg << __FILE__ << ":" <<__LINE__;
+  msg << "Cannot connect Cpp output port with type: " << type->id() ;
+  msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
   throw ConversionException(msg.str());
 }
 
@@ -1087,7 +1485,7 @@ InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport,
  */
 
 InputPort* RuntimeSALOME::adaptPythonToNeutral(InputPyPort* inport,
-                                               TypeCode * type) throw (ConversionException)
+                                               TypeCode * type)
 {
   if(inport->edGetType()->kind() == Double)
     {
@@ -1121,11 +1519,18 @@ InputPort* RuntimeSALOME::adaptPythonToNeutral(InputPyPort* inport,
           throw ConversionException(msg.str());
         }
     }
+  else if(inport->edGetType()->kind() == Struct)
+    {
+      if(isAdaptablePyObjectNeutral(type,inport->edGetType())) return new NeutralPyStruct(inport);
+    }
+
   // Adaptation not possible
   stringstream msg;
-  msg << "Cannot connect InputPyPort to Neutral output " ;
-  msg << "Output typeid: " << type->id() << " Input typeid: " << inport->edGetType()->id();
-  msg << " ("__FILE__ << ":" << __LINE__ << ")";
+  msg << "Cannot connect Neutral output port with type: " << type->id() ;
+  msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
   throw ConversionException(msg.str());
 }
 
@@ -1138,7 +1543,7 @@ InputPort* RuntimeSALOME::adaptPythonToNeutral(InputPyPort* inport,
  */
 
 InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport,
-                                             TypeCode * type) throw (ConversionException)
+                                             TypeCode * type)
 {
   if(inport->edGetType()->kind() == Double)
     {
@@ -1200,8 +1605,11 @@ InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport,
     }
   // Adaptation not possible
   stringstream msg;
-  msg << "Cannot connect InputPyPort to Corba output " ;
-  msg <<  __FILE__ << ":" << __LINE__;
+  msg << "Cannot connect Corba output port with type: " << type->id() ;
+  msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg << " ("__FILE__ << ":" << __LINE__ << ")";
+#endif
   throw ConversionException(msg.str());
 }
 
@@ -1213,7 +1621,7 @@ InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport,
  */
 
 InputPort* RuntimeSALOME::adaptPythonToXml(InputPyPort* inport,
-                                          TypeCode * type) throw (ConversionException)
+                                          TypeCode * type)
 {
   // BEWARE : using the generic check
   if(inport->edGetType()->isAdaptable(type))
@@ -1223,8 +1631,11 @@ InputPort* RuntimeSALOME::adaptPythonToXml(InputPyPort* inport,
     }
   //non convertible type
   stringstream msg;
-  msg << "Cannot connect InputPyPort with OutputXmlPort : " ;
-  msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+  msg << "Cannot connect Xml output port with type: " << type->id() ;
+  msg << " to Python input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
   throw ConversionException(msg.str());
 }
 
@@ -1233,12 +1644,13 @@ InputPort* RuntimeSALOME::adaptPythonToXml(InputPyPort* inport,
  *   \param source : input port to adapt to implementation impl and type type
  *   \param impl : output port implementation (C++, Python or Corba)
  *   \param type : output port type
+ *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
  *   \return     adaptated input port
  */
 
 InputPort* RuntimeSALOME::adapt(InputPyPort* source,
                                 const std::string& impl,
-                                TypeCode * type) throw (ConversionException)
+                                TypeCode * type,bool init)
 {
   if(impl == CppNode::IMPL_NAME)
     {
@@ -1246,7 +1658,7 @@ InputPort* RuntimeSALOME::adapt(InputPyPort* source,
     }
   else if(impl == PythonNode::IMPL_NAME)
     {
-      return adaptPythonToPython(source,type);
+      return adaptPythonToPython(source,type,init);
     }
   else if(impl == CORBANode::IMPL_NAME)
     {
@@ -1278,7 +1690,7 @@ InputPort* RuntimeSALOME::adapt(InputPyPort* source,
  */
 
 InputPort* RuntimeSALOME::adaptCppToCorba(InputCppPort* inport,
-                                          TypeCode * type) throw (ConversionException)
+                                          TypeCode * type)
 {
   DEBTRACE("RuntimeSALOME::adaptCppToCorba(InputCppPort* inport)");
   if(isAdaptableCppCorba(type,inport->edGetType()))
@@ -1288,9 +1700,11 @@ InputPort* RuntimeSALOME::adaptCppToCorba(InputCppPort* inport,
     }
   //output type is not convertible
   stringstream msg;
-  msg << "Cannot connect InputCppPort to Corba output port " ;
-  msg << type->id() << " != " << inport->edGetType()->id();
-  msg << " ("__FILE__ << ":" << __LINE__ << ")";
+  msg << "Cannot connect Corba output port with type: " << type->id() ;
+  msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
   throw ConversionException(msg.str());
 }
 
@@ -1301,7 +1715,7 @@ InputPort* RuntimeSALOME::adaptCppToCorba(InputCppPort* inport,
  *   \return an adaptated input port of type InputPyPort
  */
 InputPort* RuntimeSALOME::adaptCppToPython(InputCppPort* inport,
-                      TypeCode * type) throw (ConversionException)
+                      TypeCode * type)
 {
   DEBTRACE("RuntimeSALOME::adaptCppToPython(InputCppPort* inport)");
   if(isAdaptableCppPyObject(type,inport->edGetType()))
@@ -1311,8 +1725,11 @@ InputPort* RuntimeSALOME::adaptCppToPython(InputCppPort* inport,
     }
   //output type is not convertible
   stringstream msg;
-  msg << "Cannot connect InputCppPort with OutputPythonPort : " ;
-  msg << __FILE__ << ":" <<__LINE__;
+  msg << "Cannot connect Python output port with type: " << type->id() ;
+  msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
   throw ConversionException(msg.str());
 }
 
@@ -1323,7 +1740,7 @@ InputPort* RuntimeSALOME::adaptCppToPython(InputCppPort* inport,
  *   \return an adaptated input port of type InputPyPort
  */
 InputPort* RuntimeSALOME::adaptCppToCpp(InputCppPort* inport,
-                      TypeCode * type) throw (ConversionException)
+                      TypeCode * type)
 {
   DEBTRACE("RuntimeSALOME::adaptCppToCpp(InputPort* inport" );
   DEBTRACE(type->kind() << "   " << inport->edGetType()->kind() );
@@ -1334,8 +1751,11 @@ InputPort* RuntimeSALOME::adaptCppToCpp(InputCppPort* inport,
     }
   //non convertible type
   stringstream msg;
-  msg << "Cannot connect Cpp InputPort to OutputCppPort : " ;
-  msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+  msg << "Cannot connect Cpp output port with type: " << type->id() ;
+  msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
   throw ConversionException(msg.str());
 }
 
@@ -1346,7 +1766,7 @@ InputPort* RuntimeSALOME::adaptCppToCpp(InputCppPort* inport,
  *   \return an adaptated input port of type InputPyPort
  */
 InputPort* RuntimeSALOME::adaptCppToNeutral(InputCppPort* inport,
-                      TypeCode * type) throw (ConversionException)
+                      TypeCode * type)
 {
   DEBTRACE("RuntimeSALOME::adaptCppToNeutral(InputPort* inport" );
   DEBTRACE(type->kind() << "   " << inport->edGetType()->kind() );
@@ -1357,24 +1777,30 @@ InputPort* RuntimeSALOME::adaptCppToNeutral(InputCppPort* inport,
     }
   //non convertible type
   stringstream msg;
-  msg << "Cannot connect Cpp InputPort to OutputNeutralPort : " ;
-  msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+  msg << "Cannot connect Neutral output port with type: " << type->id() ;
+  msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
   throw ConversionException(msg.str());
 }
 
 InputPort* RuntimeSALOME::adaptCppToXml(InputCppPort* inport,
-                      TypeCode * type) throw (ConversionException)
+                      TypeCode * type)
 {
-   DEBTRACE("RuntimeSALOME::adaptCppToXml(InputCppPort* inport" );
-   if(isAdaptableCppXml(type,inport->edGetType()))
-   {
+  DEBTRACE("RuntimeSALOME::adaptCppToXml(InputCppPort* inport" );
+  if(isAdaptableCppXml(type,inport->edGetType()))
+    {
       //convertible type
       return new XmlCpp(inport);
-   }
-   //non convertible type
-   stringstream msg;
-   msg << "Cannot connect InputCppPort with OutputXmlPort : " ;
-   msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+    }
+  //non convertible type
+  stringstream msg;
+  msg << "Cannot connect Xml output port with type: " << type->id() ;
+  msg << " to Cpp input port " << inport->getName() << " with type: " << inport->edGetType()->id();
+#ifdef _DEVDEBUG_
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+#endif
    throw ConversionException(msg.str());
 }
 
@@ -1383,12 +1809,13 @@ InputPort* RuntimeSALOME::adaptCppToXml(InputCppPort* inport,
  *   \param source : input port to adapt to implementation impl and type type
  *   \param impl : output port implementation (C++, Python or Corba)
  *   \param type : output port supported type
+ *   \param init : if init is true the proxy port will be used in initialization of input port (needs value check)
  *   \return       the adaptated port
  */
 
 InputPort* RuntimeSALOME::adapt(InputCppPort* source,
                                 const std::string& impl,
-                                TypeCode * type) throw (ConversionException)
+                                TypeCode * type,bool init)
 {
   DEBTRACE("RuntimeSALOME::adapt(InputCppPort* source)");
   if(impl == CORBANode::IMPL_NAME)
@@ -1415,7 +1842,7 @@ InputPort* RuntimeSALOME::adapt(InputCppPort* source,
     {
       stringstream msg;
       msg << "Cannot connect InputCppPort to " << impl << " implementation";
-      msg << " ("__FILE__ << ":" << __LINE__ << ")";
+      msg << " (" << __FILE__ << ":" << __LINE__ << ")";
       throw ConversionException(msg.str());
     }
 }
@@ -1427,28 +1854,104 @@ InputPort* RuntimeSALOME::adapt(InputCppPort* source,
 //   return result;
 // }
 
-CORBA::ORB_ptr RuntimeSALOME::getOrb()
+CORBA::ORB_ptr RuntimeSALOME::getOrb() const
 {
   return _orb;
 }
 
-PyObject * RuntimeSALOME::getPyOrb()
+PyObject * RuntimeSALOME::getPyOrb() const
 {
   return _pyorb;
 }
 
-PyObject * RuntimeSALOME::getBuiltins()
+PyObject * RuntimeSALOME::getBuiltins() const
 {
   return _bltins;
 }
 
-DynamicAny::DynAnyFactory_ptr RuntimeSALOME::getDynFactory()
+DynamicAny::DynAnyFactory_ptr RuntimeSALOME::getDynFactory() const
 {
   return _dynFactory;
 }
 
+PyObject * RuntimeSALOME::get_omnipy()
+{
+  return _omnipy;
+}
+
 omniORBpyAPI* RuntimeSALOME::getApi()
 {
   return _api;
 }
 
+void* RuntimeSALOME::convertNeutral(TypeCode * type, Any *data)
+{
+  if(data)
+    return (void *)convertNeutralPyObject(type,data);
+  else
+    {
+      Py_INCREF(Py_None);
+      return (void *)Py_None;
+    }
+}
+
+std::string RuntimeSALOME::convertNeutralAsString(TypeCode * type, Any *data)
+{
+  PyObject* ob;
+  if(data)
+    {
+      // The call to PyGILState_Ensure was moved here because there was also
+      // a crash when calling convertNeutralPyObject with a sequence of pyobj.
+      // see also the comment below.
+      PyGILState_STATE gstate = PyGILState_Ensure();
+      ob=convertNeutralPyObject(type,data);
+      std::string s=convertPyObjectToString(ob);
+
+      // Note (Renaud Barate, 8 jan 2013): With Python 2.7, this call to Py_DECREF causes a crash
+      // (SIGSEGV) when ob is a sequence and the call is not protected with the global interpreter
+      // lock. I thus added the call to PyGILState_Ensure / PyGILState_Release. It worked fine in
+      // Python 2.6 without this call. If anyone finds the real reason of this bug and another fix,
+      // feel free to change this code.
+      //PyGILState_STATE gstate = PyGILState_Ensure();
+      Py_DECREF(ob);
+      PyGILState_Release(gstate);
+      return s;
+    }
+  else
+    {
+      return "None";
+    }
+}
+
+std::string RuntimeSALOME::convertPyObjectToString(PyObject* ob)
+{
+  return YACS::ENGINE::convertPyObjectToString(ob);
+}
+
+PyObject* RuntimeSALOME::convertStringToPyObject(const std::string& s)
+{
+  PyObject *mainmod;
+  PyObject *globals;
+  PyObject* ob;
+  PyGILState_STATE gstate = PyGILState_Ensure();
+  mainmod = PyImport_AddModule("__main__");
+  globals = PyModule_GetDict(mainmod);
+  PyObject* d = PyDict_New();
+  //PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
+  ob= PyRun_String( s.c_str(), Py_eval_input, globals, d);
+  Py_DECREF(d);
+  if(ob==NULL)
+    {
+      //exception
+      std::string error;
+      PyObject* new_stderr = newPyStdOut(error);
+      PySys_SetObject((char *)"stderr", new_stderr);
+      PyErr_Print();
+      PySys_SetObject((char *)"stderr", PySys_GetObject((char *)"__stderr__"));
+      Py_DECREF(new_stderr);
+      PyGILState_Release(gstate);
+      throw Exception(error);
+    }
+  PyGILState_Release(gstate);
+  return ob;
+}