]> SALOME platform Git repositories - modules/yacs.git/blobdiff - src/runtime/RuntimeSALOME.cxx
Salome HOME
copy tag mergefrom_BR_V0_1_CC_Salome_04oct07
[modules/yacs.git] / src / runtime / RuntimeSALOME.cxx
index 2980487b2c8a16645ec3fae9283be4aad8ae7c6f..b3755924d47995279f96caf6b73d6fad50656c75 100644 (file)
@@ -1,28 +1,99 @@
+//#define REFCNT
+#ifdef REFCNT
+#define private public
+#define protected public
+#include <omniORB4/CORBA.h>
+#include <omniORB4/internal/typecode.h>
+#include <omniORB4/internal/corbaOrb.h>
+#endif
 
+#include "yacsconfig.h"
 #include "RuntimeSALOME.hxx"
+#include "SALOMEDispatcher.hxx"
+#include "Proc.hxx"
+#include "WhileLoop.hxx"
+#include "ForLoop.hxx"
+#include "Bloc.hxx"
+#include "InputPort.hxx"
+#include "OutputPort.hxx"
+#include "InputDataStreamPort.hxx"
+#include "OutputDataStreamPort.hxx"
+#include "SalomeProc.hxx"
+//Components
+#include "CORBAComponent.hxx"
+#include "SalomeComponent.hxx"
+#include "SalomePythonComponent.hxx"
+#include "CppComponent.hxx"
+
+#include "SalomeContainer.hxx"
+#include "CppContainer.hxx"
+
+//Nodes
 #include "PythonNode.hxx"
 #include "CORBANode.hxx"
 #include "XMLNode.hxx"
 #include "CppNode.hxx"
 #include "TypeConversions.hxx"
+#include "SalomePythonNode.hxx"
+//CORBA proxy ports
 #include "CORBACORBAConv.hxx"
-#include "PythonCORBAConv.hxx"
 #include "CORBAPythonConv.hxx"
+#include "CORBAXMLConv.hxx"
+#include "CORBACppConv.hxx"
+#include "CORBANeutralConv.hxx"
+
+//Python proxy ports
+#include "PythonCORBAConv.hxx"
+#include "PythonXMLConv.hxx"
+#include "PythonCppConv.hxx"
+#include "PythonNeutralConv.hxx"
+
+//Neutral proxy ports
+#include "NeutralCORBAConv.hxx"
+#include "NeutralPythonConv.hxx"
+#include "NeutralXMLConv.hxx"
+#include "NeutralCppConv.hxx"
+
+//C++ proxy ports
+#include "CppCORBAConv.hxx"
+#include "CppPythonConv.hxx"
+#include "CppXMLConv.hxx"
+#include "CppCppConv.hxx"
+#include "CppNeutralConv.hxx"
+
+//XML proxy ports
 #include "XMLCORBAConv.hxx"
+#include "XMLPythonConv.hxx"
+#include "XMLCppConv.hxx"
+#include "XMLNeutralConv.hxx"
+
+//Calcium specific ports
+#include "CalStreamPort.hxx"
 
+#ifdef SALOME_KERNEL
+#include "SALOME_NamingService.hxx"
+#include "SALOME_LifeCycleCORBA.hxx"
+#endif
+  
+#include <libxml/parser.h>
 #include <omniORB4/CORBA.h>
 #include <iostream>
 #include <sstream>
 #include <cassert>
 
+//#define _DEVDEBUG_
+#include "YacsTrace.hxx"
+
 using namespace std;
 using namespace YACS::ENGINE;
 
-
-
-void RuntimeSALOME::setRuntime() // singleton creation (not thread safe!)
+void RuntimeSALOME::setRuntime(long flags) // singleton creation (not thread safe!)
 {
-  if (! Runtime::_singleton) Runtime::_singleton = new RuntimeSALOME();
+  if (! Runtime::_singleton)
+    {
+      Runtime::_singleton = new RuntimeSALOME(flags);
+    }
+  DEBTRACE("RuntimeSALOME::setRuntime() done !");
 }
 
 RuntimeSALOME* YACS::ENGINE::getSALOMERuntime()
@@ -37,118 +108,319 @@ RuntimeSALOME* YACS::ENGINE::getSALOMERuntime()
   
 RuntimeSALOME::RuntimeSALOME()
 {
-  _setOfImplementation.insert("Cpp");
-  _setOfImplementation.insert("Python");
-  _setOfImplementation.insert("CORBA");
-  init();
+  assert(0);
+}
+
+RuntimeSALOME::RuntimeSALOME(long flags)
+{
+  // If all flags (apart the IsPyExt flags) are unset, force them to true
+  if ((flags - flags & RuntimeSALOME::IsPyExt) == 0)
+    flags += RuntimeSALOME::UseCorba + RuntimeSALOME::UsePython
+          +  RuntimeSALOME::UseCpp + RuntimeSALOME::UseXml;
+
+  // Salome Nodes implies Corba Nodes
+  if (flags & RuntimeSALOME::UseSalome)
+    flags |= RuntimeSALOME::UseCorba;
+
+  // Corba Nodes implies Python Nodes
+  if (flags & RuntimeSALOME::UseCorba)
+    flags |= RuntimeSALOME::UsePython;
+
+  _useCorba = flags & RuntimeSALOME::UseCorba;
+  _usePython = flags & RuntimeSALOME::UsePython;
+  _useCpp = flags & RuntimeSALOME::UseCpp;
+  _useXml = flags & RuntimeSALOME::UseXml;
+
+  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);
+}
+
+RuntimeSALOME::~RuntimeSALOME()
+{
 }
 
+//! CORBA and Python initialization
+/*!
+ *  \param flags contains several bits
+ *            bit0 (ispyext) true when method is called from Python
+ *                           (Python initialization must not be done!)
+ *            bit1 (UsePython) true if python nodes are needed
+ *            bit1 (UseCorba)  true if CORBA nodes are needed
+ *            bit1 (UseXml)    true if python nodes are needed
+ *            bit1 (UseCpp)    true if C++ nodes are needed
+ *            bit1 (UseSalome) true if Salome nodes are needed
+ *
+ */
 
-void RuntimeSALOME::init()
+void RuntimeSALOME::init(long flags)
 {
-  int nbargs = 0; char **args = 0;
-  _orb = CORBA::ORB_init (nbargs, args);
-  CORBA::Object_var obj = _orb->resolve_initial_references("DynAnyFactory");
-  _dynFactory = DynamicAny::DynAnyFactory::_narrow(obj);
+  bool ispyext = flags & RuntimeSALOME::IsPyExt;
+  if (_useCorba)
+    {
+      int nbargs = 0; char **args = 0;
+      _orb = CORBA::ORB_init (nbargs, args);
+#ifdef REFCNT
+      DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
+#endif
+      CORBA::Object_var obj = _orb->resolve_initial_references("DynAnyFactory");
+      _dynFactory = DynamicAny::DynAnyFactory::_narrow(obj);
+    }
 
-  PyObject *mainmod ;
-  cerr << "RuntimeSALOME::init" << endl;
-  Py_Initialize();
+  if (_usePython)
+    {
+      DEBTRACE("RuntimeSALOME::init, is python extension = " << ispyext);
 
-  mainmod = PyImport_AddModule("__main__");
-  PyObject *globals;
-  globals = PyModule_GetDict(mainmod);
+      // Initialize Python interpreter in embedded mode
+      if (!Py_IsInitialized())
+        {
+          Py_InitializeEx(0); // do not install signal handlers
+          PyEval_InitThreads(); /* Create (and acquire) the interpreter lock (for threads)*/
+          PyEval_SaveThread(); /* Release the thread state */
+          //here we do not have the Global Interpreter Lock
+        }
 
-  /* globals is a borrowed reference */
-  Py_INCREF(globals);
-  /* globals is a new reference */
+      PyObject *mainmod,*pyapi,*res ;
+      PyObject *globals;
+      PyGILState_STATE gstate;
+      gstate = PyGILState_Ensure(); // acquire the Global Interpreter Lock
+    
+      mainmod = PyImport_AddModule("__main__");
+      globals = PyModule_GetDict(mainmod);
+      /* globals is a borrowed reference */
   
-  _bltins = PyEval_GetBuiltins();  /* borrowed ref */
+      if (PyDict_GetItemString(globals, "__builtins__") == NULL) 
+        {
+          PyObject *bimod = PyImport_ImportModule("__builtin__");
+          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 */
   
-  //init section
-  PyObject* omnipy = PyImport_ImportModule((char*)"_omnipy");
-  if (!omnipy)
-    {
-      PyErr_SetString(PyExc_ImportError, (char*)"Cannot import _omnipy");
-      return;
-    }
-  PyObject* pyapi = PyObject_GetAttrString(omnipy, (char*)"API");
-  _api = (omniORBpyAPI*)PyCObject_AsVoidPtr(pyapi);
-  Py_DECREF(pyapi);
-  PyObject *res=PyRun_String("\n"
-                            "import sys\n"
-                            "sys.path.insert(0,'.')\n"
-                            "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 );
-  if(res == NULL)
-    {
-      PyErr_Print();
-      return;
-    }
-  Py_DECREF(res);
-  _pyorb = PyDict_GetItemString(globals,"orb");
-  cerr << "refcnt: " << _pyorb->ob_refcnt << endl;
-  PyObject_Print(_pyorb,stdout,Py_PRINT_RAW);
-  cerr << endl;
-  /* pyorb is a borrowed reference */
-  //Py_INCREF(pyorb); pas nécessaire
-
-  PyObject *pyany;
-  pyany = PyDict_GetItemString(globals,"any");
-  cerr << "pyany refcnt: " << pyany->ob_refcnt << endl;
-  /* pyany is a borrowed reference */
-}
+      if (_useCorba)
+        {
+
+          //init section
+          PyObject* 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");
+          if (!pyapi)
+            {
+              goto out;
+            }
+          _api = (omniORBpyAPI*)PyCObject_AsVoidPtr(pyapi);
+          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 );
+          if(res == NULL)
+            {
+              PyErr_Print();
+              goto out;
+            }
+          Py_DECREF(res);
+
+          _pyorb = PyDict_GetItemString(globals,"orb");
+          /* PyDict_GetItemString returns a borrowed reference. There is no need to decref _pyorb */
 
+          PyObject *pyany;
+          pyany = PyDict_GetItemString(globals,"any");
+          /* PyDict_GetItemString returns a borrowed reference. There is no need to decref pyany */
+
+#ifdef REFCNT
+          DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
+#endif
+        }
+      out:
+        PyGILState_Release(gstate); // Release the Global Interpreter Lock
+    }
+}
 
 void RuntimeSALOME::fini()
 {
-  cerr << "RuntimeSALOME::fini" << endl;
-  Py_Finalize();
+  if (_usePython)
+    {
+      PyGILState_STATE gstate = PyGILState_Ensure();
+#ifdef REFCNT
+      DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
+#endif
+      PyObject *mainmod, *globals;
+      mainmod = PyImport_AddModule("__main__");
+      globals = PyModule_GetDict(mainmod);
+      if (_useCorba)
+        {
+          PyObject* res;
+          res=PyRun_String("orb.destroy()\n"
+                           "\n",
+                           Py_file_input,globals,globals );
+          if(res == NULL)
+            PyErr_Print();
+          else
+            Py_DECREF(res);
+        }
+      Py_Finalize();
+#ifdef REFCNT
+      DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
+#endif
+    }
+  else
+    {
+      if (_useCorba)
+        {
+#ifdef REFCNT
+          DEBTRACE("_orb refCount: " << ((omniOrbORB*)_orb.in())->pd_refCount);
+#endif
+          _orb->destroy();
+        }
+    }
 }
 
+Proc* RuntimeSALOME::createProc(const std::string& name)
+{
+  return new SalomeProc(name);
+}
+
+Bloc* RuntimeSALOME::createBloc(const std::string& name)
+{
+  return new Bloc(name);
+}
+
+WhileLoop* RuntimeSALOME::createWhileLoop(const std::string& name)
+{
+  return new WhileLoop(name);
+}
 
-ElementaryNode* RuntimeSALOME::createNode(string implementation,
-                                         string name) throw(Exception)
+ForLoop* RuntimeSALOME::createForLoop(const std::string& name)
 {
-  ElementaryNode* node = 0;
-  if (implementation == "Python")
-    node = new PythonNode(name);
-  else if (implementation == "CORBA")
-    node = new CORBANode(name);
-  else if (implementation == "XML")
-    node = new XmlNode(name);
-  else if (implementation == "Cpp")
-    node = new CppNode(name);
-  else 
+  return new ForLoop(name);
+}
+
+InlineFuncNode* RuntimeSALOME::createFuncNode(const std::string& kind,const std::string& name)
+{
+  InlineFuncNode* node;
+  if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
     {
-      string what ="RuntimeSALOME does not handle this implementation: " + implementation;
-      throw Exception(what);
+      node = new PyFuncNode(name);
+      return node;
     }
-  return node;
+  std::string msg="FuncNode kind ("+kind+") unknown";
+  throw Exception(msg);
 }
 
-InputPort * RuntimeSALOME::createInputPort(const string& name,
-                                          const string& impl,
-                                          Node * node,
-                                          TypeCode * type)
+InlineNode* RuntimeSALOME::createScriptNode(const std::string& kind,const std::string& name)
 {
-  if(impl == "CPP")
+  InlineNode* node;
+  if(kind == "" || kind == SalomeNode::KIND || kind == PythonNode::KIND)
     {
-      throw Exception("Cannot create InputCppPort ");
+      node = new PythonNode(name);
+      return node;
     }
-  else if(impl == "Python")
+  std::string msg="ScriptNode kind ("+kind+") unknown";
+  throw Exception(msg);
+}
+
+ServiceNode* RuntimeSALOME::createRefNode(const std::string& kind,const std::string& name)
+{
+  ServiceNode* node;
+  if(kind == "" || kind == SalomeNode::KIND || kind == CORBANode::KIND)
+    {
+      node = new CORBANode(name);
+      return node;
+    }
+  else if(kind == XmlNode::KIND)
+    {
+      node = new XmlNode(name);
+      return node;
+    }
+  std::string msg="RefNode kind ("+kind+") unknown";
+  throw Exception(msg);
+}
+
+ServiceNode* RuntimeSALOME::createCompoNode(const std::string& kind,const std::string& name)
+{
+  ServiceNode* node;
+  if(kind == "" || kind == SalomeNode::KIND )
+    {
+      node=new SalomeNode(name);
+      return node;
+    }
+  else if (kind == CppNode::KIND) 
+    {
+      node = new CppNode(name);
+      return node;
+    }
+  std::string msg="CompoNode kind ("+kind+") unknown";
+  throw Exception(msg);
+}
+
+ServiceInlineNode *RuntimeSALOME::createSInlineNode(const std::string& kind, const std::string& name)
+{
+  if(kind == "" || kind == SalomeNode::KIND )
+    return new SalomePythonNode(name);
+  std::string msg="CompoNode kind ("+kind+") unknown";
+  throw Exception(msg);
+}
+
+ComponentInstance* RuntimeSALOME::createComponentInstance(const std::string& name,
+                                                          const std::string& kind)
+{
+  ComponentInstance* compo;
+  if(kind == "" || kind == SalomeComponent::KIND) 
+    return new SalomeComponent(name);
+  else if(kind == CORBAComponent::KIND)
+    return new CORBAComponent(name);
+  else if(kind == SalomePythonComponent::KIND)
+    return new SalomePythonComponent(name);
+  else if (kind == CppComponent::KIND)
+    return new CppComponent(name);
+  std::string msg="Component Instance kind ("+kind+") unknown";
+  throw Exception(msg);
+}
+
+Container *RuntimeSALOME::createContainer(const std::string& kind)
+{
+  if(kind == "" || kind == SalomeComponent::KIND)
+    return new SalomeContainer;
+  else if (kind == CppComponent::KIND)
+    return new CppContainer;
+  std::string msg="Container kind ("+kind+") unknown";
+  throw Exception(msg);
+}
+
+InputPort * RuntimeSALOME::createInputPort(const std::string& name,
+                                           const std::string& impl,
+                                           Node * node,
+                                           TypeCode * type)
+{
+  if(impl == CppNode::IMPL_NAME)
+    {
+      return new InputCppPort(name, node, type);
+    }
+  else if(impl == PythonNode::IMPL_NAME)
     {
       return new InputPyPort(name, node, type);
     }
-  else if(impl == "CORBA")
+  else if(impl == CORBANode::IMPL_NAME)
     {
       return new InputCorbaPort(name, node, type);
     }
-  else if(impl == "XML")
+  else if(impl == XmlNode::IMPL_NAME)
     {
       return new InputXmlPort(name, node, type);
     }
@@ -161,24 +433,24 @@ InputPort * RuntimeSALOME::createInputPort(const string& name,
     }
 }
 
-OutputPort * RuntimeSALOME::createOutputPort(const string& name,
-                                            const string& impl,
-                                            Node * node,
-                                            TypeCode * type)
+OutputPort * RuntimeSALOME::createOutputPort(const std::string& name,
+                                             const std::string& impl,
+                                             Node * node,
+                                             TypeCode * type)
 {
-  if(impl == "CPP")
+  if(impl == CppNode::IMPL_NAME)
     {
-      throw Exception("Cannot create OutputCppPort ");
+      return new OutputCppPort(name, node, type);
     }
-  else if(impl == "Python")
+  else if(impl == PythonNode::IMPL_NAME)
     {
       return new OutputPyPort(name, node, type);
     }
-  else if(impl == "CORBA")
+  else if(impl == CORBANode::IMPL_NAME)
     {
       return new OutputCorbaPort(name, node, type);
     }
-  else if(impl == "XML")
+  else if(impl == XmlNode::IMPL_NAME)
     {
       return new OutputXmlPort(name, node, type);
     }
@@ -191,24 +463,67 @@ OutputPort * RuntimeSALOME::createOutputPort(const string& name,
     }
 }
 
-InputPort* RuntimeSALOME::adapt(const string& imp_source,
-                               InputPort* source,
-                               const string& impl,
-                               TypeCode * type) throw (ConversionException)
+InputDataStreamPort* RuntimeSALOME::createInputDataStreamPort(const std::string& name,
+                                                              Node *node,TypeCode *type)
+{
+  DEBTRACE("createInputDataStreamPort: " << name << " " << type->shortName());
+  if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
+    {
+      return new InputCalStreamPort(name,node,type);
+    }
+  else
+    {
+      return new InputDataStreamPort(name,node,type);
+    }
+}
+
+OutputDataStreamPort* RuntimeSALOME::createOutputDataStreamPort(const std::string& name,
+                                                                Node *node,TypeCode *type)
 {
-  cerr<<"RuntimeSALOME::adapt(InputPort* source" << endl;
-  if(imp_source == "Python")
+  DEBTRACE("createOutputDataStreamPort: " << name << " " << type->shortName());
+  if(type->kind() == Objref && std::string(type->shortName(),7) == "CALCIUM")
+    {
+      return new OutputCalStreamPort(name,node,type);
+    }
+  else
+    {
+      return new OutputDataStreamPort(name,node,type);
+    }
+}
+
+//! Main adapter function : adapt an InputPort to be able to connect it to an OutputPort with a possible different implementation 
+/*!
+ *  \param source : InputPort to be adapted
+ *  \param impl : new implementation (C++, python, CORBA, XML, Neutral)
+ *  \param type : data type provided by the InputPort
+ * 
+ * \return : adapted InputPort
+ */
+InputPort* RuntimeSALOME::adapt(InputPort* source,
+                                const std::string& impl,
+                                TypeCode * type) throw (ConversionException)
+{
+  string imp_source=source->getNode()->getImplementation();
+  if(imp_source == PythonNode::IMPL_NAME)
     {
       return adapt((InputPyPort*)source,impl,type);
     }
-  else if(imp_source == "CORBA")
+  else if(imp_source == CppNode::IMPL_NAME)
+    {
+      return adapt((InputCppPort*)source,impl,type);
+    }
+  else if(imp_source == CORBANode::IMPL_NAME)
     {
       return adapt((InputCorbaPort*)source,impl,type);
     }
-  else if(imp_source == "XML")
+  else if(imp_source == XmlNode::IMPL_NAME)
     {
       return adapt((InputXmlPort*)source,impl,type);
     }
+  else if(imp_source == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
+    {
+      return adaptNeutral(source,impl,type);
+    }
   else
     {
       stringstream msg;
@@ -218,348 +533,895 @@ InputPort* RuntimeSALOME::adapt(const string& imp_source,
     }
 }
 
-//! Retourne un adaptateur d'un port entrant Xml pour un port sortant dont l'implémentation est donnée par impl
+//! Adapt a Neutral input port to a Corba output port
 /*!
- *   \param source : input port to adapt to implementation impl and type type
- *   \param impl : output port implementation (C++, Python or Corba)
- *   \param type : le type supporté par le port sortant
- *   \return input port adapté à l'implémentation
+ *   \param inport : Neutral input port to adapt to Corba type type
+ *   \param type : output port type
+ *   \return an adaptated input port of type InputCorbaPort
  */
+InputPort* RuntimeSALOME::adaptNeutralToCorba(InputPort* inport,
+                      TypeCode * type) throw (ConversionException)
+{
+  // BEWARE : using the generic check
+  if(inport->edGetType()->isAdaptable(type))
+    {
+      //the output data is convertible to inport type
+      return new CorbaNeutral(inport);
+    }
+  //non convertible type
+  stringstream msg;
+  msg << "Cannot connect Neutral InputPort to OutputCorbaPort : " ;
+  msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+  throw ConversionException(msg.str());
+}
 
-InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
-                               const string& impl,
-                               TypeCode * type) throw (ConversionException)
+//! Adapt a Neutral input port to a Python output port
+/*!
+ *   \param inport : input port to adapt to Python type type
+ *   \param type : output port type
+ *   \return an adaptated input port of type InputPyPort
+ */
+InputPort* RuntimeSALOME::adaptNeutralToPython(InputPort* inport,
+                      TypeCode * type) throw (ConversionException)
 {
-  cerr<<"RuntimeSALOME::adapt(InputXmlPort* source" << endl;
-  if(impl == "CORBA")
+  // BEWARE : using the generic check
+  if(inport->edGetType()->isAdaptable(type))
     {
-      return adaptXmlToCorba(source,type);
+      //convertible type
+      return new PyNeutral(inport);
     }
-  else
+  //non convertible type
+  stringstream msg;
+  msg << "Cannot connect Neutral InputPort to OutputPyPort : " ;
+  msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+  throw ConversionException(msg.str());
+}
+
+//! Adapt a Neutral input port to a Xml output port 
+/*!
+ *   \param inport : input port to adapt to Xml type type
+ *   \param type : output port type
+ *   \return an input port of type InputXmlPort
+ */
+InputPort* RuntimeSALOME::adaptNeutralToXml(InputPort* inport,
+                      TypeCode * type) throw (ConversionException)
+{
+  // BEWARE : using the generic check
+  if(inport->edGetType()->isAdaptable(type))
     {
-      stringstream msg;
-      msg << "Cannot connect InputXmlPort to " << impl << " implementation";
-      msg << " ("__FILE__ << ":" << __LINE__ << ")";
-      throw ConversionException(msg.str());
+      //convertible type
+      return new XmlNeutral(inport);
+    }
+  //non convertible type
+  stringstream msg;
+  msg << "Cannot connect Neutral InputPort to OutputXmlPort : " ;
+  msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+  throw ConversionException(msg.str());
+}
+
+//! Adapt a Neutral input port to a C++ output port 
+/*!
+ *   \param inport : input port to adapt to C++ type type
+ *   \param type : output port type
+ *   \return an input port of type InputCppPort
+ */
+InputPort* RuntimeSALOME::adaptNeutralToCpp(InputPort* inport,
+                      TypeCode * type) throw (ConversionException)
+{
+  DEBTRACE("RuntimeSALOME::adaptNeutralToCpp(InputPort* inport" );
+  if(isAdaptableNeutralCpp(type,inport->edGetType()))
+    {
+      //convertible type
+      return new CppNeutral(inport);
+    }
+  //non convertible type
+  stringstream msg;
+  msg << "Cannot connect Neutral " << inport->edGetType()->getKindRepr() 
+      << " InputPort to " << type->getKindRepr() << " OutputCppPort : " ;
+  msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+  throw ConversionException(msg.str());
+}
+
+//! Adapt a Neutral input port to connect it to an output port with a given implementation
+/*!
+ *   \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
+ *   \return       the adaptated port
+ */
+InputPort* RuntimeSALOME::adaptNeutral(InputPort* source,
+                                       const std::string& impl,
+                                       TypeCode * type) throw (ConversionException)
+{
+  if(impl == CppNode::IMPL_NAME)
+    {
+      return adaptNeutralToCpp(source,type);
+    }
+  else if(impl == PythonNode::IMPL_NAME)
+    {
+      return adaptNeutralToPython(source,type);
+    }
+  else if(impl == CORBANode::IMPL_NAME)
+    {
+      return adaptNeutralToCorba(source,type);
+    }
+  else if(impl == XmlNode::IMPL_NAME)
+    {
+      return adaptNeutralToXml(source,type);
     }
+  else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
+    {
+      return new ProxyPort(source);
+    }
+  stringstream msg;
+  msg << "Cannot connect InputPort : unknown implementation " << impl;
+  msg << " (" <<__FILE__ << ":" <<__LINE__ << ")";
+  throw ConversionException(msg.str());
 }
 
-//! Retourne un adaptateur d'un port entrant XML pour un port sortant CORBA
+//! Adapt a XML input port to connect it to a CORBA output port 
 /*!
  *   \param inport : input port to adapt to CORBA type type
- *   \param type : le type supporté par le port sortant
- *   \return a InputCorbaPort port
+ *   \param type : type supported by output port
+ *   \return an adaptator port of type InputCorbaPort 
  */
 
 InputPort* RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport,
-                                         TypeCode * type) throw (ConversionException)
+                                          TypeCode * type) throw (ConversionException)
 {
-  cerr <<"RuntimeSALOME::adaptXmlToCorba(InputXmlPort* inport" << endl;
-  if(isAdaptableXmlCorba(type,inport->type()))
+  if(isAdaptableXmlCorba(type,inport->edGetType()))
     {
-      //les types sont convertibles
+      //output type is convertible to input type
       return new CorbaXml(inport);
     }
-  //les types sont non convertibles
+  //output type is not convertible
   stringstream msg;
   msg << "Cannot connect InputXmlPort to Corba output port " ;
-  msg << type->id() << " != " << inport->type()->id();
+  msg << type->id() << " != " << inport->edGetType()->id();
   msg << " ("__FILE__ << ":" << __LINE__ << ")";
   throw ConversionException(msg.str());
 }
 
-//! Retourne un adaptateur d'un port entrant CORBA pour un port sortant Xml
+//! Adapt a XML input port to a Python output port
 /*!
- *   \param inport : input port to adapt to Xml type type
- *   \param type : le type supporté par le port sortant
- *   \return an input port of Python type InputXmlPort
+ *   \param inport : input port to adapt to Python type type
+ *   \param type : output port type
+ *   \return an adaptated input port of type InputPyPort
  */
+InputPort* RuntimeSALOME::adaptXmlToPython(InputXmlPort* inport,
+                      TypeCode * type) throw (ConversionException)
+{
+  if(inport->edGetType()->isAdaptable(type))
+    {
+      //the output data is convertible to inport type
+      return new PyXml(inport);
+    }
+  //non convertible type
+  stringstream msg;
+  msg << "Cannot connect Xml InputPort to OutputPyPort : " ;
+  msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+  throw ConversionException(msg.str());
+}
 
-InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport,
-                                         TypeCode * type) throw (ConversionException)
+//! Adapt a XML input port to a C++ output port
+/*!
+ *   \param inport : input port to adapt to C++ type type
+ *   \param type : output port type
+ *   \return an adaptated input port of type InputPyPort
+ */
+InputPort* RuntimeSALOME::adaptXmlToCpp(InputXmlPort* inport,
+                      TypeCode * type) throw (ConversionException)
 {
-  //ATTENTION : on utilise isAdaptableCorbaPyObject (meme fonction)
-  cerr << "RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport" << endl;
-  if(isAdaptableCorbaPyObject(type,inport->type()))
+  DEBTRACE("RuntimeSALOME::adaptXmlToCpp(InputPort* inport" );
+  DEBTRACE(type->kind() << "   " << inport->edGetType()->kind() );
+  if(type->isAdaptable(inport->edGetType()))
     {
-      //les types sont convertibles
-      return new XmlCorba(inport);
+      //the output data is convertible to inport type
+      return new CppXml(inport);
     }
-  //les types sont non convertibles
+  //non convertible type
   stringstream msg;
-  msg << "Cannot connect InputCorbaPort with OutputXmlPort : " ;
-  msg << __FILE__ << ":" <<__LINE__;
+  msg << "Cannot connect Xml InputPort to OutputCppPort : " ;
+  msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
   throw ConversionException(msg.str());
 }
 
+//! Adapt a XML input port to a Neutral output port
+/*!
+ *   \param inport : input port to adapt to Neutral type type
+ *   \param type : output port type
+ *   \return an adaptated input port of type Neutralxxxx
+ */
+InputPort* RuntimeSALOME::adaptXmlToNeutral(InputXmlPort* inport,
+                      TypeCode * type) throw (ConversionException)
+{
+  if(inport->edGetType()->isAdaptable(type))
+    {
+      //the output data is convertible to inport type
+      return new NeutralXml(inport);
+    }
+  //non convertible type
+  stringstream msg;
+  msg << "Cannot connect Xml InputPort to OutputNeutralPort : " ;
+  msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+  throw ConversionException(msg.str());
+}
 
-//! Retourne un adaptateur d'un port entrant CORBA pour un port sortant CORBA
+//! Adapt an Xml input port to an output port which implementation is given by impl
 /*!
- *   \param inport : input port to adapt to CORBA type type
- *   \param type : le type supporté par le port sortant
+ *   \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
+ *   \return       the adaptated port
  */
 
+InputPort* RuntimeSALOME::adapt(InputXmlPort* source,
+                                const std::string& impl,
+                                TypeCode * type) throw (ConversionException)
+{
+  if(impl == CORBANode::IMPL_NAME)
+    {
+      return adaptXmlToCorba(source,type);
+    }
+  else if(impl == PythonNode::IMPL_NAME)
+    {
+      return adaptXmlToPython(source,type);
+    }
+  else if(impl == CppNode::IMPL_NAME)
+    {
+      return adaptXmlToCpp(source,type);
+    }
+  else if(impl == XmlNode::IMPL_NAME)
+    {
+      return new ProxyPort(source);
+    }
+  else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
+    {
+      return adaptXmlToNeutral(source,type);
+    }
+  else
+    {
+      stringstream msg;
+      msg << "Cannot connect InputXmlPort to " << impl << " implementation";
+      msg << " ("__FILE__ << ":" << __LINE__ << ")";
+      throw ConversionException(msg.str());
+    }
+}
+
+
+//! Adapt a CORBA input port to a CORBA output port 
+/*!
+ *   \param inport : input port to adapt to CORBA outport data type
+ *   \param type : outport data type 
+ *   \return an adaptator port of type InputCORBAPort 
+ */
 InputPort* RuntimeSALOME::adaptCorbaToCorba(InputCorbaPort* inport,
-                                           TypeCode * type) throw (ConversionException)
+                                            TypeCode * type) throw (ConversionException)
 {
-  if(type->is_a(inport->type()))
+  if(type->isA(inport->edGetType()))
     {
-      //les types sont compatibles : pas de conversion
-      return inport;
+      //types are compatible : no conversion 
+      //outport data type is more specific than inport required type
+      //so the inport can be used safely 
+      return new ProxyPort(inport);
     }
-  else if(isAdaptableCorbaCorba(type,inport->type()))
+  else if(isAdaptableCorbaCorba(type,inport->edGetType()))
     {
-      //les types sont convertibles
+      //ouport data can be converted to inport data type
       return new CorbaCorba(inport);
     }
-  //les types sont non convertibles
+  //outport data can not be converted
   stringstream msg;
   msg << "Cannot connect 2 CorbaPort with non convertible types: " ;
-  msg << type->id() << " != " << inport->type()->id();
+  msg << type->id() << " != " << inport->edGetType()->id();
   throw ConversionException(msg.str());
 }
 
-//! Retourne un adaptateur d'un port entrant CORBA pour un port sortant Python
+//! Adapt a CORBA input port to a Python output port 
 /*!
  *   \param inport : input port to adapt to Python type type
- *   \param type : le type supporté par le port sortant
- *   \return an input port of Python type InputPyPort
+ *   \param type : outport data type 
+ *   \return an adaptator port of type InputPyPort 
  */
 
 InputPort* RuntimeSALOME::adaptCorbaToPython(InputCorbaPort* inport,
-                                            TypeCode * type) throw (ConversionException)
+                                             TypeCode * type) throw (ConversionException)
 {
-  if(inport->type()->kind() == Double)
+  if(inport->edGetType()->kind() == Double)
     {
-      if(isAdaptableCorbaPyObject(type,inport->type()))return new PyCorbaDouble(inport);
+      if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaDouble(inport);
     }
-  else if(inport->type()->kind() == Int)
+  else if(inport->edGetType()->kind() == Int)
     {
-      if(isAdaptableCorbaPyObject(type,inport->type()))return new PyCorbaInt(inport);
+      if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaInt(inport);
     }
-  else if(inport->type()->kind() == String)
+  else if(inport->edGetType()->kind() == String)
     {
-      if(isAdaptableCorbaPyObject(type,inport->type()))return new PyCorbaString(inport);
+      if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaString(inport);
+    }
+  else if(inport->edGetType()->kind() == Bool)
+    {
+      if(isAdaptableCorbaPyObject(type,inport->edGetType()))return new PyCorbaBool(inport);
+    }
+  else if(inport->edGetType()->kind() == Objref )
+    {
+      if(isAdaptableCorbaPyObject(type,inport->edGetType()))
+        {
+          return new PyCorbaObjref(inport);
+        }
+      else
+        {
+          stringstream msg;
+          msg << "Cannot connect InputPyPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id();
+          msg << " " << __FILE__ << ":" <<__LINE__;
+          throw ConversionException(msg.str());
+        }
     }
-  else if(inport->type()->kind() == Objref )
+  else if(inport->edGetType()->kind() == Sequence)
     {
-      if(isAdaptableCorbaPyObject(type,inport->type()))
-       {
-         return new PyCorbaObjref(inport);
+      if(isAdaptableCorbaPyObject(type,inport->edGetType()))
+        {
+          return new PyCorbaSequence(inport);
         }
       else
-       {
-         stringstream msg;
-         msg << "Cannot connect InputPyPort : incompatible objref types ";
-         msg << __FILE__ << ":" <<__LINE__;
-         throw ConversionException(msg.str());
+        {
+          stringstream msg;
+          msg << "Cannot convert this sequence type " ;
+          msg << __FILE__ << ":" <<__LINE__;
+          throw ConversionException(msg.str());
         }
     }
-  else if(inport->type()->kind() == Sequence)
+  else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
     {
-      if(isAdaptableCorbaPyObject(type,inport->type()))
-       {
-         return new PyCorbaSequence(inport);
+      if(isAdaptableCorbaPyObject(type,inport->edGetType()))
+        {
+          return new PyCorbaStruct(inport);
         }
       else
-       {
-         stringstream msg;
-         msg << "Cannot convert this sequence type " ;
-         msg << __FILE__ << ":" <<__LINE__;
-         throw ConversionException(msg.str());
+        {
+          stringstream msg;
+          msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
+          msg << __FILE__ << ":" <<__LINE__;
+          throw ConversionException(msg.str());
         }
     }
-  // Adaptation not found
+  // Adaptation not possible
   stringstream msg;
   msg << "Cannot connect InputCorbaPort to Python output " ;
   msg << __FILE__ << ":" <<__LINE__;
   throw ConversionException(msg.str());
 }
 
-//! Retourne un adaptateur d'un port entrant CORBA pour un port sortant C++
+//! Adapt a CORBA input port to connect it to a XML output port 
+/*!
+ *   \param inport : input port to adapt to Xml type type
+ *   \param type : type supported by output port
+ *   \return an adaptator port of type InputXmlPort 
+ */
+
+InputPort* RuntimeSALOME::adaptCorbaToXml(InputCorbaPort* inport,
+                                          TypeCode * type) throw (ConversionException)
+{
+  // BEWARE : using the generic check
+  if(inport->edGetType()->isAdaptable(type))
+    {
+      //output type is convertible to input type
+      return new XmlCorba(inport);
+    }
+  //output type is not convertible
+  stringstream msg;
+  msg << "Cannot connect InputCorbaPort with OutputXmlPort : " ;
+  msg << __FILE__ << ":" <<__LINE__;
+  throw ConversionException(msg.str());
+}
+
+//! Adapt a CORBA input port to a C++ output port 
 /*!
  *   \param inport : input port to adapt to C++ type type
- *   \param type : le type supporté par le port sortant
+ *   \param type : outport data type 
+ *   \return an adaptator port of type InputCPPPort 
  */
 
 InputPort* RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport,
-                                         TypeCode * type) throw (ConversionException)
+                                          TypeCode * type) throw (ConversionException)
 {
-  throw ConversionException("Cannot connect InputCorbaPort to C++ ");
+  DEBTRACE("RuntimeSALOME::adaptCorbaToCpp(InputCorbaPort* inport" );
+  if(isAdaptableCorbaCpp(type,inport->edGetType()))
+    {
+      //output type is convertible to input type
+      return new CppCorba(inport);
+    }
+  //output type is not convertible
+  stringstream msg;
+  msg << "Cannot connect InputCorbaPort with OutputCppPort : " ;
+  msg << __FILE__ << ":" <<__LINE__;
+  throw ConversionException(msg.str());
 }
 
-//! Retourne un adaptateur d'un port entrant CORBA pour un port sortant dont l'implémentation est donnée par impl
+//! Adapt a CORBA input port to a neutral data 
+/*!
+ *   \param inport : InputPort to adapt to Neutral type type
+ *   \param type : outport data type 
+ *   \return an adaptator port of type Neutralxxxx
+ */
+
+InputPort* RuntimeSALOME::adaptCorbaToNeutral(InputCorbaPort* inport,
+                                              TypeCode * type) throw (ConversionException)
+{
+  if(inport->edGetType()->kind() == Double)
+    {
+      if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaDouble(inport);
+    }
+  else if(inport->edGetType()->kind() == Int)
+    {
+      if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaInt(inport);
+    }
+  else if(inport->edGetType()->kind() == String)
+    {
+      if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaString(inport);
+    }
+  else if(inport->edGetType()->kind() == Bool)
+    {
+      if(isAdaptableCorbaNeutral(type,inport->edGetType()))return new NeutralCorbaBool(inport);
+    }
+  else if(inport->edGetType()->kind() == Objref)
+    {
+      if(isAdaptableCorbaNeutral(type,inport->edGetType())) return new NeutralCorbaObjref(inport);
+    }
+  else if(inport->edGetType()->kind() == Sequence)
+    {
+      if(isAdaptableCorbaNeutral(type,inport->edGetType()))
+        return new NeutralCorbaSequence(inport);
+      else
+        {
+          stringstream msg;
+          msg << "Cannot convert this sequence type " ;
+          msg << __FILE__ << ":" <<__LINE__;
+          throw ConversionException(msg.str());
+        }
+    }
+
+  // Adaptation not possible
+  stringstream msg;
+  msg << "Cannot connect InputCorbaPort to Neutral output " ;
+  msg << __FILE__ << ":" <<__LINE__;
+  throw ConversionException(msg.str());
+}
+
+//! Adapt a CORBA input port to an output which implementation and type are given by impl and type
 /*!
  *   \param source : input port to adapt to implementation impl and type type
  *   \param impl : output port implementation (C++, Python or Corba)
- *   \param type : le type supporté par le port sortant
+ *   \param type : outport data type 
+ *   \return an adaptator port which type depends on impl
  */
 
 InputPort* RuntimeSALOME::adapt(InputCorbaPort* source,
-                               const string& impl,
-                               TypeCode * type) throw (ConversionException)
+                                const std::string& impl,
+                                TypeCode * type) throw (ConversionException)
 {
-  cerr<<"RuntimeSALOME::adapt(InputPyPort* source" << endl;
-  if(impl == "CPP")
+  if(impl == CppNode::IMPL_NAME)
     {
       return adaptCorbaToCpp(source,type);
     }
-  else if(impl == "Python")
+  else if(impl == PythonNode::IMPL_NAME)
     {
       return adaptCorbaToPython(source,type);
     }
-  else if(impl == "CORBA")
+  else if(impl == CORBANode::IMPL_NAME)
     {
       return adaptCorbaToCorba(source,type);
     }
-  else if(impl == "XML")
+  else if(impl == XmlNode::IMPL_NAME)
     {
       return adaptCorbaToXml(source,type);
     }
-   else
+  else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
+    {
+      return adaptCorbaToNeutral(source,type);
+    }
+  else
     {
       stringstream msg;
       msg << "Cannot connect InputCorbaPort : unknown implementation " ;
       msg << __FILE__ << ":" <<__LINE__;
       throw ConversionException(msg.str());
     }
-  return source;
 }
 
-//! Retourne un adaptateur d'un port entrant Python pour un port sortant Python
+//! Adapt a Python input port to a Python output port
 /*!
- * Dans ce cas, on ne fait pas de conversion ni de cast (int->double, par ex).
- * On vérifie simplement que la connexion est autorisée.
+ * No need to make conversion or cast. 
+ * Only check, it's possible.
  *   \param inport : InputPort to adapt to Python type type
- *   \param type : le TypeCode supporté par le port sortant
- *   \return       InputPort de type Python (InputPyPort)
+ *   \param type : outport data type 
+ *   \return an adaptator port of type InputPyPort 
  */
 
 InputPort* RuntimeSALOME::adaptPythonToPython(InputPyPort* inport,
-                                             TypeCode * type) throw (ConversionException)
+                                              TypeCode * type) throw (ConversionException)
 {
-  if(isAdaptablePyObjectPyObject(type,inport->type()))
+  if(isAdaptablePyObjectPyObject(type,inport->edGetType()))
     {
-      //les types sont convertibles
-      //En Python, il n'est pas nécessaire de convertir. La conversion
-      //sera faite à la volée dans l'interpréteur
-      return inport;
+      //output data is convertible to input type
+      //With python, no need to convert. Conversion will be done automatically
+      //by the interpreter
+      return new ProxyPort(inport);
     }
-  //les types sont non convertibles
+  //output data is not convertible to input type
   stringstream msg;
   msg << "Cannot connect 2 Python Port with non convertible types: " ;
-  msg << type->id() << " != " << inport->type()->id();
+  msg << type->id() << " != " << inport->edGetType()->id();
+  msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
   throw ConversionException(msg.str());
 }
 
-//! Retourne un adaptateur d'un port entrant Python pour un port sortant C++
+//! Adapt a Python input port to a C++ output port
 /*!
- * Pas encore implémenté
  *   \param inport : InputPort to adapt to C++ type type
- *   \param type : le TypeCode supporté par le port sortant
- *   \return       InputPort de type C++ (InputCppPort)
+ *   \param type : outport data type 
+ *   \return an adaptator port of C++ type (InputCppPort)
  */
 
 InputPort* RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport,
-                                          TypeCode * type) throw (ConversionException)
+                                           TypeCode * type) throw (ConversionException)
 {
-  throw ConversionException("Cannot connect InputPyPort to C++ ");
+  DEBTRACE("RuntimeSALOME::adaptPythonToCpp(InputPyPort* inport" );
+  if(isAdaptablePyObjectCpp(type,inport->edGetType()))
+    {
+      //output type is convertible to input type
+      return new CppPy(inport);
+    }
+  //output type is not convertible
+  stringstream msg;
+  msg << "Cannot connect InputPythonPort with OutputCppPort : " ;
+  msg << __FILE__ << ":" <<__LINE__;
+  throw ConversionException(msg.str());
 }
 
-//! Retourne un adaptateur d'un port entrant Python pour un port sortant Corba
+//! Adapt a Python input port to a Neutral data port
 /*!
- * On convertit dans tous les cas
+ *   \param inport : InputPort to adapt to Neutral type type
+ *   \param type : outport data type 
+ *   \return an adaptator port of Neutral type (Neutralxxxx)
+ */
+
+InputPort* RuntimeSALOME::adaptPythonToNeutral(InputPyPort* inport,
+                                               TypeCode * type) throw (ConversionException)
+{
+  if(inport->edGetType()->kind() == Double)
+    {
+      if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyDouble(inport);
+    }
+  else if(inport->edGetType()->kind() == Int)
+    {
+      if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyInt(inport);
+    }
+  else if(inport->edGetType()->kind() == String)
+    {
+      if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyString(inport);
+    }
+  else if(inport->edGetType()->kind() == Bool)
+    {
+      if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyBool(inport);
+    }
+  else if(inport->edGetType()->kind() == Objref)
+    {
+      if(isAdaptablePyObjectNeutral(type,inport->edGetType()))return new NeutralPyObjref(inport);
+    }
+  else if(inport->edGetType()->kind() == Sequence)
+    {
+      if(isAdaptablePyObjectNeutral(type,inport->edGetType()))
+        return new NeutralPySequence(inport);
+      else
+        {
+          stringstream msg;
+          msg << "Cannot convert this sequence type " ;
+          msg << __FILE__ << ":" <<__LINE__;
+          throw ConversionException(msg.str());
+        }
+    }
+  // 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__ << ")";
+  throw ConversionException(msg.str());
+}
+
+//! Adapt a Python input port to a Corba output port
+/*!
+ * Always convert the data
  *   \param inport : InputPort to adapt to Corba type type
- *   \param type : le TypeCode supporté par le port sortant
- *   \return       InputPort de type Corba (InputCorbaPort)
+ *   \param type : outport data type 
+ *   \return an adaptator port of Corba type (InputCorbaPort)
  */
 
 InputPort* RuntimeSALOME::adaptPythonToCorba(InputPyPort* inport,
-                                            TypeCode * type) throw (ConversionException)
+                                             TypeCode * type) throw (ConversionException)
 {
-  cerr << "RuntimeSALOME::adaptPythonToCorba:" ;
-  cerr << inport->type()->kind() << ":" << type->kind()<< endl;
-
-  if(inport->type()->kind() == Double)
+  if(inport->edGetType()->kind() == Double)
     {
-      if(isAdaptablePyObjectCorba(type,inport->type()))return new CorbaPyDouble(inport);
+      if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyDouble(inport);
     }
-  else if(inport->type()->kind() == Int)
+  else if(inport->edGetType()->kind() == Int)
     {
-      if(isAdaptablePyObjectCorba(type,inport->type()))return new CorbaPyInt(inport);
+      if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyInt(inport);
     }
-  else if(inport->type()->kind() == String)
+  else if(inport->edGetType()->kind() == String)
     {
-      if(isAdaptablePyObjectCorba(type,inport->type()))return new CorbaPyString(inport);
+      if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyString(inport);
     }
-  else if(inport->type()->kind() == Objref)
+  else if(inport->edGetType()->kind() == Bool)
     {
-      if(isAdaptablePyObjectCorba(type,inport->type()))
-       {
-         return new CorbaPyObjref(inport);
+      if(isAdaptablePyObjectCorba(type,inport->edGetType()))return new CorbaPyBool(inport);
+    }
+  else if(inport->edGetType()->kind() == Objref)
+    {
+      if(isAdaptablePyObjectCorba(type,inport->edGetType()))
+        {
+          return new CorbaPyObjref(inport);
         }
       else
-       {
-         stringstream msg;
-         msg << "Cannot connect InputCorbaPort : incompatible objref types ";
-         msg << __FILE__ << ":" <<__LINE__;
-         throw ConversionException(msg.str());
+        {
+          stringstream msg;
+          msg << "Cannot connect InputCorbaPort : incompatible objref types " << type->id() << " " << inport->edGetType()->id();
+          msg << " " << __FILE__ << ":" <<__LINE__;
+          throw ConversionException(msg.str());
         }
     }
-  else if(inport->type()->kind() == Sequence)
+  else if(inport->edGetType()->kind() == Sequence)
     {
-      if(isAdaptablePyObjectCorba(type,inport->type()))
-       {
-         return new CorbaPySequence(inport);
+      if(isAdaptablePyObjectCorba(type,inport->edGetType()))
+        {
+          return new CorbaPySequence(inport);
         }
       else
-       {
-         stringstream msg;
-         msg << "Cannot convert this sequence type " ;
-         msg << __FILE__ << ":" <<__LINE__;
-         throw ConversionException(msg.str());
+        {
+          stringstream msg;
+          msg << "Cannot convert this sequence type " ;
+          msg << __FILE__ << ":" <<__LINE__;
+          throw ConversionException(msg.str());
         }
     }
-  // Adaptation not found
+  else if(inport->edGetType()->kind() == YACS::ENGINE::Struct)
+    {
+      if(isAdaptablePyObjectCorba(type,inport->edGetType()))
+        {
+          return new CorbaPyStruct(inport);
+        }
+      else
+        {
+          stringstream msg;
+          msg << "Cannot convert this struct type " << type->id() << " to " << inport->edGetType()->id();
+          msg << " " << __FILE__ << ":" <<__LINE__;
+          throw ConversionException(msg.str());
+        }
+    }
+  // Adaptation not possible
   stringstream msg;
   msg << "Cannot connect InputPyPort to Corba output " ;
   msg <<  __FILE__ << ":" << __LINE__;
   throw ConversionException(msg.str());
 }
 
-//! Retourne un adaptateur d'un port entrant Python pour un port sortant dont l'implémentation est donnée par impl
+//! Adapt a Python input port to a Xml output port 
+/*!
+ *   \param inport : input port to adapt to Xml type type
+ *   \param type : output port type
+ *   \return an input port of type InputXmlPort
+ */
+
+InputPort* RuntimeSALOME::adaptPythonToXml(InputPyPort* inport,
+                                          TypeCode * type) throw (ConversionException)
+{
+  // BEWARE : using the generic check
+  if(inport->edGetType()->isAdaptable(type))
+    {
+      //convertible type
+      return new XmlPython(inport);
+    }
+  //non convertible type
+  stringstream msg;
+  msg << "Cannot connect InputPyPort with OutputXmlPort : " ;
+  msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+  throw ConversionException(msg.str());
+}
+
+//! Adapt a Python input port to an output port with a given implementation
 /*!
  *   \param source : input port to adapt to implementation impl and type type
  *   \param impl : output port implementation (C++, Python or Corba)
- *   \param type : le type supporté par le port sortant
- *   \return input port adapté à l'implémentation
+ *   \param type : output port type
+ *   \return     adaptated input port
  */
 
 InputPort* RuntimeSALOME::adapt(InputPyPort* source,
-                               const string& impl,
-                               TypeCode * type) throw (ConversionException)
+                                const std::string& impl,
+                                TypeCode * type) throw (ConversionException)
 {
-  cerr<<"RuntimeSALOME::adapt(InputPyPort* source" << endl;
-  if(impl == "CPP")
+  if(impl == CppNode::IMPL_NAME)
     {
       return adaptPythonToCpp(source,type);
     }
-  else if(impl == "Python")
+  else if(impl == PythonNode::IMPL_NAME)
     {
       return adaptPythonToPython(source,type);
     }
-  else if(impl == "CORBA")
+  else if(impl == CORBANode::IMPL_NAME)
     {
       return adaptPythonToCorba(source,type);
     }
+  else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
+    {
+      return adaptPythonToNeutral(source,type);
+    }
+  else if(impl == XmlNode::IMPL_NAME)
+    {
+      return adaptPythonToXml(source,type);
+    }
+  else
+    {
+      stringstream msg;
+      msg << "Cannot connect InputPyPort : unknown implementation " << impl;
+      msg <<  " ("<<__FILE__ << ":" << __LINE__<<")";
+      throw ConversionException(msg.str());
+    }
+}
+
+
+//! Adapt a C++ input port to connect it to a CORBA output port
+/*!
+ *   \param inport : input port to adapt to CORBA type type
+ *   \param type : type supported by output port
+ *   \return an adaptator port of type InputCorbaPort
+ */
+
+InputPort* RuntimeSALOME::adaptCppToCorba(InputCppPort* inport,
+                                          TypeCode * type) throw (ConversionException)
+{
+  DEBTRACE("RuntimeSALOME::adaptCppToCorba(InputCppPort* inport)");
+  if(isAdaptableCppCorba(type,inport->edGetType()))
+    {
+      //output type is convertible to input type
+      return new CorbaCpp(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__ << ")";
+  throw ConversionException(msg.str());
+}
+
+//! Adapt a C++ input port to a Python output port
+/*!
+ *   \param inport : input port to adapt to Python type type
+ *   \param type : output port type
+ *   \return an adaptated input port of type InputPyPort
+ */
+InputPort* RuntimeSALOME::adaptCppToPython(InputCppPort* inport,
+                      TypeCode * type) throw (ConversionException)
+{
+  DEBTRACE("RuntimeSALOME::adaptCppToPython(InputCppPort* inport)");
+  if(isAdaptableCppPyObject(type,inport->edGetType()))
+    {
+      //output type is convertible to input type
+      return new PyCpp(inport);
+    }
+  //output type is not convertible
+  stringstream msg;
+  msg << "Cannot connect InputCppPort with OutputPythonPort : " ;
+  msg << __FILE__ << ":" <<__LINE__;
+  throw ConversionException(msg.str());
+}
+
+//! Adapt a C++ input port to a C++ output port
+/*!
+ *   \param inport : input port to adapt to C++ type type
+ *   \param type : output port type
+ *   \return an adaptated input port of type InputPyPort
+ */
+InputPort* RuntimeSALOME::adaptCppToCpp(InputCppPort* inport,
+                      TypeCode * type) throw (ConversionException)
+{
+  DEBTRACE("RuntimeSALOME::adaptCppToCpp(InputPort* inport" );
+  DEBTRACE(type->kind() << "   " << inport->edGetType()->kind() );
+  if(type->isAdaptable(inport->edGetType()))
+    {
+      //the output data is convertible to inport type
+      return new CppCpp(inport);
+    }
+  //non convertible type
+  stringstream msg;
+  msg << "Cannot connect Cpp InputPort to OutputCppPort : " ;
+  msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+  throw ConversionException(msg.str());
+}
+
+//! Adapt a C++ input port to a Neutral output port
+/*!
+ *   \param inport : input port to adapt to C++ type type
+ *   \param type : output port type
+ *   \return an adaptated input port of type InputPyPort
+ */
+InputPort* RuntimeSALOME::adaptCppToNeutral(InputCppPort* inport,
+                      TypeCode * type) throw (ConversionException)
+{
+  DEBTRACE("RuntimeSALOME::adaptCppToNeutral(InputPort* inport" );
+  DEBTRACE(type->kind() << "   " << inport->edGetType()->kind() );
+  if(type->isAdaptable(inport->edGetType()))
+    {
+      //the output data is convertible to inport type
+      return new NeutralCpp(inport);
+    }
+  //non convertible type
+  stringstream msg;
+  msg << "Cannot connect Cpp InputPort to OutputNeutralPort : " ;
+  msg << "(" <<__FILE__ << ":" <<__LINE__<< ")";
+  throw ConversionException(msg.str());
+}
+
+InputPort* RuntimeSALOME::adaptCppToXml(InputCppPort* inport,
+                      TypeCode * type) throw (ConversionException)
+{
+   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__<< ")";
+   throw ConversionException(msg.str());
+}
+
+//! Adapt a C++ input port to connect it to an output port with a given implementation
+/*!
+ *   \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
+ *   \return       the adaptated port
+ */
+
+InputPort* RuntimeSALOME::adapt(InputCppPort* source,
+                                const std::string& impl,
+                                TypeCode * type) throw (ConversionException)
+{
+  DEBTRACE("RuntimeSALOME::adapt(InputCppPort* source)");
+  if(impl == CORBANode::IMPL_NAME)
+    {
+      return adaptCppToCorba(source,type);
+    }
+  else if(impl == PythonNode::IMPL_NAME)
+    {
+      return adaptCppToPython(source,type);
+    }
+  else if(impl == XmlNode::IMPL_NAME)
+    {
+      return adaptCppToXml(source,type);
+    }
+  else if(impl == CppNode::IMPL_NAME)
+    {
+      return adaptCppToCpp(source, type);
+    }
+  else if(impl == Runtime::RUNTIME_ENGINE_INTERACTION_IMPL_NAME)
+    {
+      return adaptCppToNeutral(source, type);
+    }
   else
     {
-      throw ConversionException("Cannot connect InputPyPort : unknown implementation  ");
+      stringstream msg;
+      msg << "Cannot connect InputCppPort to " << impl << " implementation";
+      msg << " ("__FILE__ << ":" << __LINE__ << ")";
+      throw ConversionException(msg.str());
     }
 }
 
 // bool RuntimeSALOME::isCompatible(const OutputPort* outputPort, 
-//                              const InputPort*  inputPort)
+//                               const InputPort*  inputPort)
 // {
 //   bool result=true;
 //   return result;