Salome HOME
ready to test
[modules/yacs.git] / src / runtime / TypeConversions.cxx
index c51ca9ae26d1d3429933b4361e26ee94beae11a2..f75e20abf45c4bb71a8e53241a6e760b8cdf2510 100644 (file)
@@ -1,5 +1,24 @@
+// Copyright (C) 2006-2019  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
 
 //#define REFCNT
+//
 #ifdef REFCNT
 #define private public
 #define protected public
 #include "TypeConversions.hxx"
 #include "ConversionException.hxx"
 #include "RuntimeSALOME.hxx"
+#include "Salome_file_i.hxx"
 #include "TypeCode.hxx"
 #include "Cstr2d.hxx"
+#include "SALOME_GenericObj.hh"
 
 #include <iostream>
+#include <iomanip>
 #include <sstream>
 
+#ifdef WIN32
+#include <fcntl.h>
+#define _S_IREAD 256
+#define _S_IWRITE 128
+int mkstemp(char *tmpl)
+{
+  int ret=-1;
+  mktemp(tmpl); ret=open(tmpl,O_RDWR|O_BINARY|O_CREAT|O_EXCL|_O_SHORT_LIVED, _S_IREAD|_S_IWRITE);
+  return ret;
+}
+#endif
+
 //#define _DEVDEBUG_
 #include "YacsTrace.hxx"
 
@@ -25,6 +59,40 @@ namespace YACS
 {
   namespace ENGINE
   {
+    void printbin(const std::string& bin)
+      {
+        register char c;
+        for(int i=0;i<bin.length();i++)
+          {
+            c=bin[i];
+            if (c < ' ' || c >= 0x7f) 
+              {
+                fprintf(stderr,"\\x%02x",c & 0xff);
+              }
+            else
+              fprintf(stderr,"%c",c);
+          }
+        fprintf(stderr,"\n");
+      }
+
+    std::string getImplName(ImplType impl)
+      {
+         switch(impl)
+           {
+           case CORBAImpl:
+             return "CORBA";
+           case PYTHONImpl:
+             return "PYTHON";
+           case NEUTRALImpl:
+             return "NEUTRAL";
+           case XMLImpl:
+             return "XML";
+           case CPPImpl:
+             return "CPP";
+           default:
+             return "UNKNOWN";
+           }
+      }
     /*
      * Functions to return a CORBA TypeCode equivalent to a YACS TypeCode
      */
@@ -61,8 +129,14 @@ namespace YACS
 
     CORBA::TypeCode_ptr getCorbaTCObjref(const TypeCode *t)
     {
-      DEBTRACE( t->name() << " " << t->shortName());
-      CORBA::TypeCode_ptr tc= getSALOMERuntime()->getOrb()->create_interface_tc(t->id(),t->shortName());
+      DEBTRACE( t->name() << " " << t->shortName() << " " << t->id());
+      CORBA::TypeCode_ptr tc;
+      if(strncmp(t->id(),"python",6)==0 )
+        tc= CORBA::TypeCode::_duplicate(Engines::_tc_fileBlock);
+      else if(strncmp(t->id(),"json",4)==0)
+        tc= CORBA::TypeCode::_duplicate(CORBA::_tc_string);
+      else
+        tc= getSALOMERuntime()->getOrb()->create_interface_tc(t->id(),t->shortName());
 #ifdef REFCNT
       DEBTRACE("refcount CORBA tc Objref: " << ((omni::TypeCode_base*)tc)->pd_ref_count);
 #endif
@@ -183,6 +257,17 @@ namespace YACS
                 if( t1->isA(t2->id()) )
                   return 1;
               }
+            else if(t1->kind() == Sequence)
+              {
+                const TypeCodeSeq *t1c(dynamic_cast<const TypeCodeSeq *>(t1));
+                if(!t1c)
+                  return 0;
+                const TypeCode *t1cc(t1c->contentType());
+                if(t1cc==t2)
+                  return 1;
+                if(t1cc->kind() == Objref && std::string(t1cc->id())==std::string(t2->id()))
+                  return 1;
+              }
             return 0;
           }
       };
@@ -216,7 +301,7 @@ namespace YACS
           {
             if(t1->kind() == Struct)
               {
-                if( t1->isA(t2->id()) )
+                if( t1->isA(t2) )
                   return 1;
               }
             return 0;
@@ -363,7 +448,7 @@ namespace YACS
     template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
     struct convertToYacsObjref
     {
-      static inline std::string convert(const TypeCode *t,TIN o,TIN2 aux)
+      static inline std::string convert(const TypeCode *t,TIN o,TIN2 aux,int protocol)
         {
           stringstream msg;
           msg << "Conversion not implemented: kind= " << t->kind() << " Implementation: " << IMPLIN << " to: " << IMPLOUT;
@@ -532,7 +617,12 @@ namespace YACS
     template <ImplType IMPLIN,class TIN,class TIN2,ImplType IMPLOUT, class TOUT>
     inline TOUT convertObjref(const TypeCode *t,TIN o,TIN2 aux)
     {
-      std::string d=convertToYacsObjref<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux);
+      int protocol=-1;
+      if(IMPLOUT==XMLImpl)
+        protocol=0;//to avoid presence of \0 into XML generated file
+      if(IMPLOUT==NEUTRALImpl)
+        protocol=4;
+      std::string d=convertToYacsObjref<IMPLIN,TIN,TIN2,IMPLOUT,TOUT>::convert(t,o,aux,protocol);
       DEBTRACE( d );
       TOUT r=convertFromYacsObjref<IMPLOUT,TOUT>::convert(t,d);
       return r;
@@ -607,15 +697,16 @@ namespace YACS
           double x;
           if (PyFloat_Check(o))
             x=PyFloat_AS_DOUBLE(o);
-          else if (PyInt_Check(o))
-            x=PyInt_AS_LONG(o);
           else if(PyLong_Check(o))
             x=PyLong_AsLong(o);
           else
             {
               stringstream msg;
-              msg << "Not a python double. kind=" << t->kind() ;
+              msg << "Not a python double. ";
+#ifdef _DEVDEBUG_
+              msg << "kind=" << t->kind() ;
               msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
+#endif
               throw YACS::ENGINE::ConversionException(msg.str());
             }
           return x;
@@ -627,15 +718,16 @@ namespace YACS
       static inline long convert(const TypeCode *t,PyObject* o,void*)
         {
           long l;
-          if (PyInt_Check(o))
-            l=PyInt_AS_LONG(o);
-          else if(PyLong_Check(o))
+          if(PyLong_Check(o))
             l=PyLong_AsLong(o);
           else
             {
               stringstream msg;
-              msg << "Not a python integer. kind=" << t->kind() ;
+              msg << "Not a python integer. ";
+#ifdef _DEVDEBUG_
+              msg << "kind=" << t->kind() ;
               msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
+#endif
               throw YACS::ENGINE::ConversionException(msg.str());
             }
           return l;
@@ -646,15 +738,26 @@ namespace YACS
     {
       static inline std::string convert(const TypeCode *t,PyObject* o,void*)
         {
-          if (PyString_Check(o))
-            return PyString_AS_STRING(o);
+          std::string s;
+          if (PyUnicode_Check(o))
+            {
+              Py_ssize_t size;
+              const char *ptr = PyUnicode_AsUTF8AndSize(o, &size);
+              if (!ptr)
+                throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed");
+              s.assign(ptr, size);
+            }
           else
             {
               stringstream msg;
-              msg << "Not a python string. kind=" << t->kind() ;
+              msg << "Not a python string. ";
+#ifdef _DEVDEBUG_
+              msg << "kind=" << t->kind() ;
               msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
+#endif
               throw YACS::ENGINE::ConversionException(msg.str());
             }
+          return s;
         }
     };
     template <ImplType IMPLOUT, class TOUT>
@@ -665,15 +768,16 @@ namespace YACS
           bool l;
           if (PyBool_Check(o))
               l=(o==Py_True);
-          else if (PyInt_Check(o))
-              l=(PyInt_AS_LONG(o)!=0);
           else if(PyLong_Check(o))
               l=(PyLong_AsLong(o)!=0);
           else
             {
               stringstream msg;
-              msg << "Problem in Python to xml conversion: kind= " << t->kind() ;
-              msg << " : " << __FILE__ << ":" << __LINE__;
+              msg << "Not a python boolean. ";
+#ifdef _DEVDEBUG_
+              msg << "kind=" << t->kind() ;
+              msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
+#endif
               throw YACS::ENGINE::ConversionException(msg.str());
             }
           return l;
@@ -682,17 +786,73 @@ namespace YACS
     template <ImplType IMPLOUT, class TOUT>
     struct convertToYacsObjref<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>
     {
-      static inline std::string convert(const TypeCode *t,PyObject* o,void*)
+      static inline std::string convert(const TypeCode *t,PyObject* o,void*,int protocol)
         {
-          if (PyString_Check(o))
+          if (PyUnicode_Check(o) && strncmp(t->id(),"python",6)!=0)
             {
               // the objref is used by Python as a string (prefix:value) keep it as a string
-              return PyString_AS_STRING(o);
+              Py_ssize_t size;
+              std::string s;
+              const char *ptr = PyUnicode_AsUTF8AndSize(o, &size);
+              if (!ptr)
+                throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed");
+              s.assign(ptr, size);
+              return s;
+            }
+          if(strncmp(t->id(),"python",6)==0)
+            {
+              // It's a native Python object pickle it
+              PyObject* mod=PyImport_ImportModule("pickle");
+              PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"Oi",o,protocol);
+              DEBTRACE(PyObject_Repr(pickled) );
+              Py_DECREF(mod);
+              if(pickled==NULL)
+                {
+                  PyErr_Print();
+                  throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl");
+                }
+              std::string mystr(PyBytes_AsString(pickled),PyBytes_Size(pickled));
+              Py_DECREF(pickled);
+              return mystr;
+            }
+          else if(strncmp(t->id(),"json",4)==0)
+            {
+              // It's a Python  object convert it to json 
+              PyObject* mod=PyImport_ImportModule("simplejson");
+              if(mod==NULL)
+                {
+                  PyErr_Print();
+                  throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl: no simplejson module");
+                }
+              PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"O",o);
+              Py_DECREF(mod);
+              if(pickled==NULL)
+                {
+                  PyErr_Print();
+                  throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl");
+                }
+              std::string mystr=PyBytes_AsString(pickled);
+              Py_DECREF(pickled);
+              return mystr;
+            }
+          else
+            {
+              // It should be a CORBA Object convert it to an IOR string
+              PyObject *pystring=PyObject_CallMethod(getSALOMERuntime()->getPyOrb(),(char *)"object_to_string",(char *)"O",o);
+              if(pystring==NULL)
+                {
+                  PyErr_Print();
+                  throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl");
+                }
+              Py_ssize_t size;
+              std::string mystr;
+              const char *ptr = PyUnicode_AsUTF8AndSize(pystring, &size);
+              if (!ptr)
+                throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed");
+              mystr.assign(ptr, size);
+              Py_DECREF(pystring);
+              return mystr;
             }
-          PyObject *pystring=PyObject_CallMethod(getSALOMERuntime()->getPyOrb(),"object_to_string","O",o);
-          std::string mystr=PyString_AsString(pystring);
-          Py_DECREF(pystring);
-          return mystr;
         }
     };
     template <ImplType IMPLOUT, class TOUT>
@@ -700,6 +860,15 @@ namespace YACS
     {
       static inline void convert(const TypeCode *t,PyObject* o,void*,std::vector<TOUT>& v)
         {
+          if(!PySequence_Check(o))
+            {
+              stringstream msg;
+              msg << "Problem in conversion: the python object is not a sequence " << std::endl;
+#ifdef _DEVDEBUG_
+              msg << " ( " << __FILE__ << ":" << __LINE__ << ")";
+#endif
+              throw YACS::ENGINE::ConversionException(msg.str());
+            }
           int length=PySequence_Size(o);
           DEBTRACE("length: " << length );
           v.resize(length);
@@ -712,9 +881,18 @@ namespace YACS
               std::cerr << std::endl;
 #endif
               DEBTRACE( "item refcnt: " << item->ob_refcnt );
-              TOUT ro=YacsConvertor<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>(t->contentType(),item,0);
-              v[i]=ro;
-              Py_DECREF(item);
+              try
+                {
+                  TOUT ro=YacsConvertor<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>(t->contentType(),item,0);
+                  v[i]=ro;
+                  Py_DECREF(item);
+                }
+              catch(ConversionException& ex)
+                {
+                  stringstream msg;
+                  msg << ex.what() << " for sequence element " << i;
+                  throw YACS::ENGINE::ConversionException(msg.str(),false);
+                }
             }
         }
     };
@@ -743,13 +921,20 @@ namespace YACS
                   std::cerr << std::endl;
 #endif
                   stringstream msg;
-                  msg << "Problem in conversion: member " << name << " not present " << endl;
-                  msg << " (" << __FILE__ << ":" << __LINE__ << ")";
+                  msg << "member " << name << " not present " ;
                   throw YACS::ENGINE::ConversionException(msg.str());
                 }
               DEBTRACE( "value refcnt: " << value->ob_refcnt );
-              TOUT ro=YacsConvertor<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>(tm,value,0);
-              m[name]=ro;
+              try
+                {
+                  TOUT ro=YacsConvertor<PYTHONImpl,PyObject*,void*,IMPLOUT,TOUT>(tm,value,0);
+                  m[name]=ro;
+                }
+              catch(ConversionException& ex)
+                {
+                  std::string s=" for struct member "+name;
+                  throw YACS::ENGINE::ConversionException(ex.what()+s,false);
+                }
             }
         }
     };
@@ -782,7 +967,7 @@ namespace YACS
     {
       static inline PyObject* convert(const TypeCode *t,std::string& o)
         {
-          return PyString_FromString(o.c_str());
+          return PyUnicode_FromString(o.c_str());
         }
     };
     template <>
@@ -798,15 +983,50 @@ namespace YACS
     {
       static inline PyObject* convert(const TypeCode *t,std::string& o)
         {
-          std::string::size_type pos=o.find_first_of(":");
-          std::string prefix=o.substr(0,pos);
-          DEBTRACE(prefix);
-          if(prefix == "file")
+          if(o=="")
+            {
+              Py_INCREF(Py_None);
+              return Py_None;
+            }
+          if(t->isA(Runtime::_tc_file))
             {
               //It's an objref file. Convert it specially
-              return PyString_FromString(o.c_str());
+              return PyUnicode_FromString(o.c_str());
+            }
+          if(strncmp(t->id(),"python",6)==0) //ex: "python:obj:1.0"
+            {
+              //It's a python pickled object, unpickled it
+              PyObject* mod=PyImport_ImportModule("pickle");
+              PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y#",o.c_str(),o.length());
+              DEBTRACE(PyObject_Repr(ob));
+              Py_DECREF(mod);
+              if(ob==NULL)
+                {
+                  PyErr_Print();
+                  throw YACS::ENGINE::ConversionException("Problem in convertFromYacsObjref<PYTHONImpl");
+                }
+              return ob;
             }
-          /* another way
+          if(strncmp(t->id(),"json",4)==0)
+            {
+              // It's a json object unpack it
+              PyObject* mod=PyImport_ImportModule("simplejson");
+              if(mod==NULL)
+                {
+                  PyErr_Print();
+                  throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl: no simplejson module");
+                }
+              PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y",o.c_str());
+              Py_DECREF(mod);
+              if(ob==NULL)
+                {
+                  PyErr_Print();
+                  throw YACS::ENGINE::ConversionException("Problem in convertFromYacsObjref<PYTHONImpl");
+                }
+              return ob;
+            }
+
+          /* another way to convert IOR string to CORBA PyObject 
           PyObject* ob= PyObject_CallMethod(getSALOMERuntime()->getPyOrb(),"string_to_object","s",o.c_str());
           DEBTRACE( "Objref python refcnt: " << ob->ob_refcnt );
           return ob;
@@ -827,6 +1047,11 @@ namespace YACS
               throw ConversionException("Can't get reference to object");
             }
 
+          if(obref->_non_existent())
+            {
+              throw ConversionException("non_existent object");
+            }
+
           if( CORBA::is_nil(obref) )
             {
               DEBTRACE( "Can't get reference to object (or it was nil)." );
@@ -841,12 +1066,46 @@ namespace YACS
               msg << " (" << __FILE__ << ":" << __LINE__ << ")";
               throw YACS::ENGINE::ConversionException(msg.str());
             }
-          //hold_lock is true: caller is supposed to hold the GIL.
-          //omniorb will not take the GIL
 #ifdef REFCNT
           DEBTRACE("obref refCount: " << obref->_PR_getobj()->pd_refCount);
 #endif
+#ifdef _DEVDEBUG_
+          std::cerr << "_PD_repoId: " << obref->_PD_repoId << std::endl;
+          std::cerr << "_mostDerivedRepoId: " << obref->_PR_getobj()->_mostDerivedRepoId()  << std::endl;
+#endif
+
+          //hold_lock is true: caller is supposed to hold the GIL.
+          //omniorb will not take the GIL
           PyObject* ob= getSALOMERuntime()->getApi()->cxxObjRefToPyObjRef(obref, 1);
+
+#ifdef _DEVDEBUG_
+          PyObject_Print(ob,stderr,Py_PRINT_RAW);
+          std::cerr << std::endl;
+          std::cerr << "obref is a generic: " << obref->_is_a("IDL:SALOME/GenericObj:1.0") << std::endl;
+          PyObject_Print(getSALOMERuntime()->get_omnipy(),stderr,Py_PRINT_RAW);
+          std::cerr << std::endl;
+#endif
+
+          //ob is a CORBA::Object. Try to convert it to more specific type SALOME/GenericObj
+          if(obref->_is_a("IDL:SALOME/GenericObj:1.0"))
+            {
+              PyObject *result = PyObject_CallMethod(getSALOMERuntime()->get_omnipy(), (char *)"narrow", (char *)"Osi",ob,"IDL:SALOME/GenericObj:1.0",1);
+              if(result==NULL)
+                PyErr_Clear();//Exception during narrow. Keep ob
+              else if(result==Py_None)
+                Py_DECREF(result); //Can't narrow. Keep ob
+              else
+                {
+                  //Can narrow. Keep result
+#ifdef _DEVDEBUG_
+                  PyObject_Print(result,stderr,Py_PRINT_RAW);
+                  std::cerr << std::endl;
+#endif
+                  Py_DECREF(ob);
+                  ob=result;
+                }
+            }
+
 #ifdef REFCNT
           DEBTRACE("obref refCount: " << obref->_PR_getobj()->pd_refCount);
 #endif
@@ -905,7 +1164,7 @@ namespace YACS
     {
       static inline double convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
         {
-          double d;
+          double d=0;
           cur = cur->xmlChildrenNode;
           while (cur != NULL)
             {
@@ -914,9 +1173,16 @@ namespace YACS
                   //wait a double, got a double
                   xmlChar * s = NULL;
                   s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
-                  DEBTRACE( "convertToYacsDouble " << (const char *)s );
-                  d=Cstr2d((const char *)s);
-                  xmlFree(s);
+                  if (s)
+                    {
+                      DEBTRACE( "convertToYacsDouble " << (const char *)s );
+                      d=Cstr2d((const char *)s);
+                      xmlFree(s);
+                    }
+                  else
+                    {
+                      DEBTRACE("############### workaround to improve...");
+                    }
                   return d;
                 }
               else if ((!xmlStrcmp(cur->name, (const xmlChar *)"int")))
@@ -924,16 +1190,23 @@ namespace YACS
                   //wait a double, got an int
                   xmlChar * s = NULL;
                   s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
-                  DEBTRACE( "convertToYacsDouble " << (const char *)s );
-                  d=Cstr2d((const char *)s);
-                  xmlFree(s);
+                  if (s)
+                    {
+                      DEBTRACE( "convertToYacsDouble " << (const char *)s );
+                      d=Cstr2d((const char *)s);
+                      xmlFree(s);
+                    }
+                  else
+                    {
+                      DEBTRACE("############### workaround to improve...");
+                    }
                   return d;
                 }
               cur = cur->next;
             }
           stringstream msg;
-          msg << "Problem in Xml to TOUT conversion: kind= " << t->kind() ;
-          msg << " : " << __FILE__ << ":" << __LINE__;
+          msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type:  " << t->id() ;
+          msg << " (" << __FILE__ << ":" << __LINE__ << ")";
           throw YACS::ENGINE::ConversionException(msg.str());
         }
     };
@@ -942,25 +1215,31 @@ namespace YACS
     {
       static inline long convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
         {
-          long d;
+          long d=0;
           cur = cur->xmlChildrenNode;
           while (cur != NULL)
             {
               if ((!xmlStrcmp(cur->name, (const xmlChar *)"int")))
                 {
-                  //wait a double, got an int
                   xmlChar * s = NULL;
                   s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
-                  DEBTRACE( "convertToYacsInt " << (const char *)s );
-                  d=atol((const char *)s);
-                  xmlFree(s);
+                  if (s)
+                    {
+                      DEBTRACE( "convertToYacsInt " << (const char *)s );
+                      d=atol((const char *)s);
+                      xmlFree(s);
+                    }
+                  else
+                    {
+                      DEBTRACE("############### workaround to improve...");
+                    }
                   return d;
                 }
               cur = cur->next;
             }
           stringstream msg;
-          msg << "Problem in Xml to TOUT conversion: kind= " << t->kind() ;
-          msg << " : " << __FILE__ << ":" << __LINE__;
+          msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type:  " << t->id() ;
+          msg << " (" << __FILE__ << ":" << __LINE__ << ")";
           throw YACS::ENGINE::ConversionException(msg.str());
         }
     };
@@ -986,8 +1265,8 @@ namespace YACS
               cur = cur->next;
             }
           stringstream msg;
-          msg << "Problem in Xml to TOUT conversion: kind= " << t->kind() ;
-          msg << " : " << __FILE__ << ":" << __LINE__;
+          msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type:  " << t->id() ;
+          msg << " (" << __FILE__ << ":" << __LINE__ << ")";
           throw YACS::ENGINE::ConversionException(msg.str());
         }
     };
@@ -1004,23 +1283,31 @@ namespace YACS
                   //wait a boolean, got a boolean
                   xmlChar * s = NULL;
                   s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
-                  DEBTRACE( "convertToYacsBool " << (const char *)s );
-                  bool ob=atoi((const char*)s)!=0;
-                  xmlFree(s);
+                  bool ob =false;
+                  if (s)
+                    {
+                      DEBTRACE( "convertToYacsBool " << (const char *)s );
+                      ob=atoi((const char*)s)!=0;
+                      xmlFree(s);
+                    }
+                  else
+                    {
+                      DEBTRACE("############### workaround to improve...");
+                    }
                   return ob;
                 }
               cur = cur->next;
             }
           stringstream msg;
-          msg << "Problem in Xml to TOUT conversion: kind= " << t->kind() ;
-          msg << " : " << __FILE__ << ":" << __LINE__;
+          msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type:  " << t->id() ;
+          msg << " (" << __FILE__ << ":" << __LINE__ << ")";
           throw YACS::ENGINE::ConversionException(msg.str());
         }
     };
     template <ImplType IMPLOUT, class TOUT>
     struct convertToYacsObjref<XMLImpl,xmlDocPtr,xmlNodePtr,IMPLOUT,TOUT>
     {
-      static inline std::string convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
+      static inline std::string convert(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur,int protocol)
         {
           cur = cur->xmlChildrenNode;
           while (cur != NULL)
@@ -1029,16 +1316,38 @@ namespace YACS
                 {
                   //we wait a objref, we have got a objref
                   xmlChar * s = NULL;
+                  std::string mystr = "";
+                  s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
+                  if (s)
+                    {
+                      DEBTRACE( "convertToYacsObjref " << (const char *)s );
+                      mystr = (const char *)s;
+                      xmlFree(s);
+                    }
+                  else
+                    {
+                      DEBTRACE("############### workaround to improve...");
+                    }
+                  if(strncmp(t->id(),"python",6)==0 )
+                    return FromBase64Safe(mystr);
+                  else
+                    return mystr;
+                }
+              else if ((!xmlStrcmp(cur->name, (const xmlChar *)"string")))// <- here case where pyobj value has been stored in XML. pyobj has kind==ObjRef. And the stored format is String ! EDF11027
+                {
+                  //wait a string, got a string
+                  xmlChar * s = NULL;
                   s = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
-                  DEBTRACE( "convertToYacsObjref " << (const char *)s );
-                  std::string mystr((const char *)s);
+                  if(s==0)return "";
+                  DEBTRACE( "convertToYacsString " << (const char *)s );
+                  std::string mystr=std::string((const char *)s);
                   xmlFree(s);
                   return mystr;
                 }
               cur = cur->next;
             }
           stringstream msg;
-          msg << "Problem in conversion: a objref is expected " ;
+          msg << "Problem in conversion from Xml to " << getImplName(IMPLOUT) << " with type:  " << t->id() ;
           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
           throw YACS::ENGINE::ConversionException(msg.str());
         }
@@ -1153,7 +1462,7 @@ namespace YACS
       static inline std::string convert(const TypeCode *t,double o)
         {
           stringstream msg ;
-          msg << "<value><double>" << o << "</double></value>\n";
+          msg << "<value><double>" << setprecision(16) << o << "</double></value>\n";
           return msg.str();
         }
     };
@@ -1191,7 +1500,12 @@ namespace YACS
     {
       static inline std::string convert(const TypeCode *t,std::string& o)
         {
-          return "<value><objref>" + o + "</objref></value>\n";
+          if(strncmp(t->id(),"python",6)==0 )
+            return "<value><objref><![CDATA[" + ToBase64(o) + "]]></objref></value>\n";
+          else if(strncmp(t->id(),"json",4)==0)
+            return "<value><objref><![CDATA[" + o + "]]></objref></value>\n";
+          else
+            return "<value><objref>" + o + "</objref></value>\n";
         }
     };
 
@@ -1261,7 +1575,12 @@ namespace YACS
     {
       static inline long convert(const TypeCode *t,YACS::ENGINE::Any* o,void*)
         {
-          return o->getIntValue();
+          if(o->getType()->kind()==Int)
+            return o->getIntValue();
+          stringstream msg;
+          msg << "Problem in conversion: a int is expected " ;
+          msg << " (" << __FILE__ << ":" << __LINE__ << ")";
+          throw YACS::ENGINE::ConversionException(msg.str());
         }
     };
     template <ImplType IMPLOUT, class TOUT>
@@ -1269,7 +1588,12 @@ namespace YACS
     {
       static inline std::string convert(const TypeCode *t,YACS::ENGINE::Any* o,void*)
         {
-          return o->getStringValue();
+          if(o->getType()->kind()==String)
+            return o->getStringValue();
+          stringstream msg;
+          msg << "Problem in conversion: a string is expected " ;
+          msg << " (" << __FILE__ << ":" << __LINE__ << ")";
+          throw YACS::ENGINE::ConversionException(msg.str());
         }
     };
     template <ImplType IMPLOUT, class TOUT>
@@ -1284,14 +1608,20 @@ namespace YACS
           stringstream msg;
           msg << "Problem in conversion: a bool or int is expected " ;
           msg << " (" << __FILE__ << ":" << __LINE__ << ")";
+          throw YACS::ENGINE::ConversionException(msg.str());
         }
     };
     template <ImplType IMPLOUT, class TOUT>
     struct convertToYacsObjref<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
     {
-      static inline std::string convert(const TypeCode *t,YACS::ENGINE::Any* o,void*)
+      static inline std::string convert(const TypeCode *t,YACS::ENGINE::Any* o,void*,int protocol)
         {
-          return o->getStringValue();
+          if(o->getType()->kind()==String || o->getType()->kind()==Objref)
+            return o->getStringValue();
+          stringstream msg;
+          msg << "Problem in conversion: a objref(string) is expected " ;
+          msg << " (" << __FILE__ << ":" << __LINE__ << ")";
+          throw YACS::ENGINE::ConversionException(msg.str());
         }
     };
     template <ImplType IMPLOUT, class TOUT>
@@ -1309,6 +1639,23 @@ namespace YACS
             }
         }
     };
+    template <ImplType IMPLOUT, class TOUT>
+    struct convertToYacsStruct<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>
+    {
+      static inline void convert(const TypeCode *t,YACS::ENGINE::Any* o,void*,std::map<std::string,TOUT>& m)
+        {
+          StructAny * sdata = dynamic_cast<StructAny *>(o);
+          YASSERT(sdata != NULL);
+          const TypeCodeStruct * tst = dynamic_cast<const TypeCodeStruct *>(t);
+          YASSERT(tst != NULL);
+          for (int i=0 ; i<tst->memberCount() ; i++)
+            {
+              string name = tst->memberName(i);
+              TOUT ro=YacsConvertor<NEUTRALImpl,YACS::ENGINE::Any*,void*,IMPLOUT,TOUT>(tst->memberType(i),(*sdata)[name.c_str()],0);
+              m[name]=ro;
+            }
+        }
+    };
     /* End of ToYacs Convertor for NEUTRALImpl */
 
     //! FromYacs Convertor for NEUTRALImpl
@@ -1353,7 +1700,43 @@ namespace YACS
     {
       static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::string& o)
         {
-          return YACS::ENGINE::AtomAny::New(o);
+          //Check if objref is a GenericObj and register it if it is the case (workaround for bad management of GenericObj)
+          if(o=="" || (t->isA(Runtime::_tc_file)) || (strncmp(t->id(),"python",6)==0) || (strncmp(t->id(),"json",4)==0))
+            return YACS::ENGINE::AtomAny::New(o, const_cast<TypeCode *>(t));
+
+          //Objref CORBA. prefix=IOR,corbaname,corbaloc
+          CORBA::Object_var obref;
+          try
+            {
+              obref = getSALOMERuntime()->getOrb()->string_to_object(o.c_str());
+            }
+          catch(CORBA::Exception& ex)
+            {
+              throw ConversionException("Can't get reference to object");
+            }
+          if(obref->_non_existent())
+            throw ConversionException("non_existent object");
+          if( CORBA::is_nil(obref) )
+            throw ConversionException("Can't get reference to object");
+          if(!obref->_is_a(t->id()))
+            {
+              stringstream msg;
+              msg << "Problem in conversion: an objref " << t->id() << " is expected " << endl;
+              msg << "An objref of type " << obref->_PD_repoId << " is given " << endl;
+              msg << " (" << __FILE__ << ":" << __LINE__ << ")";
+              throw YACS::ENGINE::ConversionException(msg.str());
+            }
+
+          SALOME::GenericObj_var gobj=SALOME::GenericObj::_narrow(obref);
+          if(!CORBA::is_nil(gobj))
+            {
+              DEBTRACE("It's a SALOME::GenericObj register it");
+              gobj->Register();
+            }
+          else
+              DEBTRACE("It's a CORBA::Object but not a SALOME::GenericObj");
+
+          return YACS::ENGINE::AtomAny::New(o, const_cast<TypeCode *>(t));
         }
     };
 
@@ -1375,6 +1758,22 @@ namespace YACS
           return any;
         }
     };
+
+    template <>
+    struct convertFromYacsStruct<NEUTRALImpl,YACS::ENGINE::Any*>
+    {
+      static inline YACS::ENGINE::Any* convert(const TypeCode *t,std::map<std::string,YACS::ENGINE::Any*>& m)
+        {
+          StructAny * any = StructAny::New((TypeCodeStruct *)t);
+          std::map<std::string,YACS::ENGINE::Any*>::const_iterator it;
+          for (it=m.begin() ; it!=m.end() ; it++)
+            {
+              any->setEltAtRank(it->first.c_str(), it->second);
+              it->second->decrRef();
+            }
+          return any;
+        }
+    };
     /* End of FromYacs Convertor for NEUTRALImpl */
 
     //! ToYacs Convertor for CORBAImpl
@@ -1412,8 +1811,12 @@ namespace YACS
       static inline long convert(const TypeCode *t,CORBA::Any* o,void*)
         {
           CORBA::Long d;
-          *o >>= d;
-          return d;
+          if(*o >>= d)
+            return d;
+          stringstream msg;
+          msg << "Problem in CORBA to TOUT conversion: kind= " << t->kind() ;
+          msg << " : " << __FILE__ << ":" << __LINE__;
+          throw YACS::ENGINE::ConversionException(msg.str());
         }
     };
     template <ImplType IMPLOUT, class TOUT>
@@ -1422,8 +1825,12 @@ namespace YACS
       static inline std::string convert(const TypeCode *t,CORBA::Any* o,void*)
         {
           const char *s;
-          *o >>=s;
-          return s;
+          if(*o >>=s)
+            return s;
+          stringstream msg;
+          msg << "Problem in CORBA to TOUT conversion: kind= " << t->kind() ;
+          msg << " : " << __FILE__ << ":" << __LINE__;
+          throw YACS::ENGINE::ConversionException(msg.str());
         }
     };
     template <ImplType IMPLOUT, class TOUT>
@@ -1443,12 +1850,72 @@ namespace YACS
     template <ImplType IMPLOUT, class TOUT>
     struct convertToYacsObjref<CORBAImpl,CORBA::Any*,void*,IMPLOUT,TOUT>
     {
-      static inline std::string convert(const TypeCode *t,CORBA::Any* o,void*)
+      static inline std::string convert(const TypeCode *t,CORBA::Any* o,void*,int protocol)
         {
-          CORBA::Object_var ObjRef ;
-          *o >>= (CORBA::Any::to_object ) ObjRef ;
-          CORBA::String_var objref = getSALOMERuntime()->getOrb()->object_to_string(ObjRef);
-          return (char *)objref;
+          char file[]="/tmp/XXXXXX";
+          if(t->isA(Runtime::_tc_file))
+            {
+              Engines::Salome_file_ptr sf;
+              *o >>= sf;
+              Salome_file_i* f=new Salome_file_i();
+              mkstemp(file);
+              f->setDistributedFile(file);
+              f->connect(sf);
+              f->recvFiles();
+              delete f;
+              return file;
+            }
+          else if(strncmp(t->id(),"python",6)==0)
+            {
+              const char *s;
+              Engines::fileBlock * buffer;
+              if(*o >>=buffer)
+                {
+                  s=(const char*)buffer->get_buffer();
+
+                  if(protocol !=4)
+                    {
+                      std::string mystr(s,buffer->length());
+                      return mystr;
+                    }
+
+                  PyGILState_STATE gstate = PyGILState_Ensure(); 
+                  PyObject* mod=PyImport_ImportModule("pickle");
+                  PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y#",s,buffer->length());
+                  PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"Oi",ob,protocol);
+                  DEBTRACE(PyObject_Repr(pickled));
+                  std::string mystr=PyBytes_AsString(pickled);
+                  Py_DECREF(mod);
+                  Py_DECREF(ob);
+                  Py_DECREF(pickled);
+                  PyGILState_Release(gstate);
+
+                  return mystr;
+                }
+              stringstream msg;
+              msg << "Problem in CORBA (protocol python) to TOUT conversion: kind= " << t->kind() ;
+              msg << " : " << __FILE__ << ":" << __LINE__;
+              throw YACS::ENGINE::ConversionException(msg.str());
+            }
+          else if(strncmp(t->id(),"json",4)==0)
+            {
+              const char *s;
+              if(*o >>=s)
+                {
+                  return s;
+                }
+              stringstream msg;
+              msg << "Problem in CORBA (protocol json) to TOUT conversion: kind= " << t->kind() ;
+              msg << " : " << __FILE__ << ":" << __LINE__;
+              throw YACS::ENGINE::ConversionException(msg.str());
+            }
+          else
+            {
+              CORBA::Object_var ObjRef ;
+              *o >>= CORBA::Any::to_object(ObjRef) ;
+              CORBA::String_var objref = getSALOMERuntime()->getOrb()->object_to_string(ObjRef);
+              return (char *)objref;
+            }
         }
     };
     template <ImplType IMPLOUT, class TOUT>
@@ -1535,7 +2002,7 @@ namespace YACS
       static inline CORBA::Any* convert(const TypeCode *t,double o)
         {
           CORBA::Any *any = new CORBA::Any();
-          *any <<= o;
+          *any <<= (CORBA::Double)o;
           return any;
         }
     };
@@ -1545,7 +2012,7 @@ namespace YACS
       static inline CORBA::Any* convert(const TypeCode *t,long o)
         {
           CORBA::Any *any = new CORBA::Any();
-          *any <<= o;
+          *any <<= (CORBA::Long)o;
           return any;
         }
     };
@@ -1574,17 +2041,57 @@ namespace YACS
     {
       static inline CORBA::Any* convert(const TypeCode *t,std::string& o)
         {
-          /*
-          std::string::size_type pos=o.find_first_of(":");
-          std::string prefix=o.substr(0,pos);
-          DEBTRACE(prefix);
-          if(prefix == "file")
+          CORBA::Object_var obref;
+
+          if(t->isA(Runtime::_tc_file))
             {
               //It's an objref file. Convert it specially
+              Salome_file_i* aSalome_file = new Salome_file_i();
+              try
+                {
+                  aSalome_file->setLocalFile(o.c_str());
+                  obref = aSalome_file->_this();
+                  aSalome_file->_remove_ref();
+                }
+              catch (const SALOME::SALOME_Exception& e)
+                {
+                  stringstream msg;
+                  msg << e.details.text;
+                  msg << " : " << __FILE__ << ":" << __LINE__;
+                  throw YACS::ENGINE::ConversionException(msg.str());
+                }
+            }
+          else if(strncmp(t->id(),"python",6)==0 )
+            {
+              CORBA::Any *any = new CORBA::Any();
+              Engines::fileBlock * buffer=new Engines::fileBlock();
+              buffer->length(o.length());
+              CORBA::Octet *buf=buffer->get_buffer();
+              memcpy(buf,o.c_str(),o.length());
+              *any <<= buffer;
+              return any;
+            }
+          else if(strncmp(t->id(),"json",4)==0)
+            {
+              CORBA::Any *any = new CORBA::Any();
+              *any <<= o.c_str();
+              return any;
+            }
+          else
+            {
+              try
+                {
+                  obref=getSALOMERuntime()->getOrb()->string_to_object(o.c_str());
+                }
+              catch(CORBA::Exception& ex)
+                {
+                  throw ConversionException("Can't get reference to object");
+                }
+              if( CORBA::is_nil(obref) )
+                {
+                  throw ConversionException("Can't get reference to object");
+                }
             }
-            */
-          CORBA::Object_var obref =
-            getSALOMERuntime()->getOrb()->string_to_object(o.c_str());
 #ifdef REFCNT
           DEBTRACE("ObjRef refCount: " << obref->_PR_getobj()->pd_refCount);
 #endif
@@ -1602,52 +2109,41 @@ namespace YACS
     {
       static inline CORBA::Any* convert(const TypeCode *t,std::vector<CORBA::Any*>& v)
         {
-          CORBA::Any *any;
-          CORBA::TypeCode_ptr seqTC;
+          CORBA::ORB_ptr orb=getSALOMERuntime()->getOrb();
+          std::vector<CORBA::Any*>::const_iterator iter;
 
-          //the equivalent CORBA TypeCode
-          seqTC=getCorbaTC(t);
-#ifdef REFCNT
-          DEBTRACE("refcount CORBA seqTC: " << ((omni::TypeCode_base*)seqTC)->pd_ref_count);
-#endif
-          DynamicAny::DynAny_ptr dynany =
-            getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(seqTC);
-          CORBA::release(seqTC);
-          DynamicAny::DynSequence_ptr ds =
-            DynamicAny::DynSequence::_narrow(dynany);
-          CORBA::release(dynany);
+          // Build an Any from vector v
+          int isObjref=0;
+          if(t->contentType()->kind() == Objref)
+            isObjref=1;
+
+          CORBA::TypeCode_var tc=getCorbaTC(t);
+
+          DynamicAny::DynAny_var dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(tc);
+          DynamicAny::DynSequence_var ds = DynamicAny::DynSequence::_narrow(dynany);
+          ds->set_length(v.size());
 
-          std::vector<CORBA::Any*>::const_iterator iter;
-          DynamicAny::AnySeq as ;
-          as.length(v.size());
-          int i=0;
           for(iter=v.begin();iter!=v.end();iter++)
             {
-              //Can we avoid making a copy ?
+              DynamicAny::DynAny_var temp=ds->current_component();
               CORBA::Any* a=*iter;
-              as[i]=*a;
-              i++;
+              //It seems that from_any does not support inherited objref: convert to CORBA::Object and insert reference
+              if(isObjref)
+                {
+                  CORBA::Object_var zzobj ;
+                  *a >>= CORBA::Any::to_object(zzobj) ;
+                  temp->insert_reference(zzobj);
+                }
+              else
+                temp->from_any(*a);
+
               //delete intermediate any
               delete a;
+              ds->next();
             }
-          try
-            {
-              ds->set_elements(as);
-            }
-          catch(DynamicAny::DynAny::TypeMismatch& ex)
-            {
-              throw YACS::ENGINE::ConversionException("type mismatch");
-            }
-          catch(DynamicAny::DynAny::InvalidValue& ex)
-            {
-              throw YACS::ENGINE::ConversionException("invalid value");
-            }
-          any=ds->to_any();
+
+          CORBA::Any *any=ds->to_any();
           ds->destroy();
-          CORBA::release(ds);
-#ifdef REFCNT
-          DEBTRACE("refcount CORBA seqTC: " << ((omni::TypeCode_base*)seqTC)->pd_ref_count);
-#endif
           return any;
         }
     };
@@ -1656,69 +2152,43 @@ namespace YACS
     {
       static inline CORBA::Any* convert(const TypeCode *t,std::map<std::string,CORBA::Any*>& m)
         {
-          CORBA::Any *any;
-          CORBA::TypeCode_ptr structTC;
+          CORBA::ORB_ptr orb=getSALOMERuntime()->getOrb();
 
-          //the equivalent CORBA TypeCode
-          structTC=getCorbaTC(t);
-#ifdef REFCNT
-          DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count);
-          DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count);
-#endif
           YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
           int nMember=tst->memberCount();
           DEBTRACE("nMember="<<nMember);
-          DynamicAny::DynAny_ptr da=
-            getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(structTC);
-#ifdef REFCNT
-          DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count);
-          DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count);
-#endif
-          CORBA::release(structTC);
-#ifdef REFCNT
-          DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count);
-          DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count);
-#endif
-          DynamicAny::DynStruct_ptr ds=DynamicAny::DynStruct::_narrow(da);
-          CORBA::release(da);
-#ifdef REFCNT
-          DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count);
-          DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count);
-#endif
-          DynamicAny::NameValuePairSeq members;
-          members.length(nMember);
+
+          CORBA::TypeCode_var tc=getCorbaTC(t);
+          DynamicAny::DynAny_var dynany=getSALOMERuntime()->getDynFactory()->create_dyn_any_from_type_code(tc);
+          DynamicAny::DynStruct_var ds = DynamicAny::DynStruct::_narrow(dynany);
+
           for(int i=0;i<nMember;i++)
             {
+              DynamicAny::DynAny_var temp=ds->current_component();
               const char * name=tst->memberName(i);
               DEBTRACE("Member name="<<name);
-              //TypeCode* tm=tst->memberType(i);
               //do not test member presence : test has been done in ToYacs convertor
               CORBA::Any* a=m[name];
-              members[i].id=CORBA::string_dup(name);
-              members[i].value=*a;
+              //It seems that from_any does not support inherited objref: convert to CORBA::Object and insert reference
+              CORBA::TypeCode_var atc = tc->member_type(i);
+              if(atc->kind()==CORBA::tk_objref)
+                {
+                  //special treatment for objref
+                  CORBA::Object_var zzobj ;
+                  *a >>= CORBA::Any::to_object(zzobj) ;
+                  temp->insert_reference(zzobj);
+                }
+              else
+                {
+                  temp->from_any(*a);
+                }
               //delete intermediate any
               delete a;
+              ds->next();
             }
-#ifdef REFCNT
-          DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count);
-          DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count);
-#endif
-          ds->set_members(members);
-#ifdef REFCNT
-          DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count);
-          DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count);
-#endif
-          any=ds->to_any();
-#ifdef REFCNT
-          DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count);
-          DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count);
-#endif
+          CORBA::Any *any=ds->to_any();
           ds->destroy();
-          CORBA::release(ds);
-#ifdef REFCNT
-          DEBTRACE("refcount CORBA structTC: " << ((omni::TypeCode_base*)structTC)->pd_ref_count);
-          DEBTRACE("refcount CORBA tc_double: " << ((omni::TypeCode_base*)CORBA::_tc_double)->pd_ref_count);
-#endif
+
           return any;
         }
     };
@@ -1827,6 +2297,30 @@ namespace YACS
       {
         return YacsConvertor<PYTHONImpl,PyObject*,void*,CORBAImpl,CORBA::Any*>(t,data,0);
       }
+    PyObject* convertPyObjectPyObject(const TypeCode *t,PyObject *data)
+      {
+        return YacsConvertor<PYTHONImpl,PyObject*,void*,PYTHONImpl,PyObject*>(t,data,0);
+      }
+
+    std::string convertPyObjectToString(PyObject* ob)
+    {
+      PyObject *s;
+      PyGILState_STATE gstate = PyGILState_Ensure(); 
+      // TODO: separate treatment for string (maybe with bad encoding?) and other types of PyObject ?
+      // Do we need str() or repr() and what are the possible causes of failure of str() ?
+      // not clear, needs more analysis.
+      s=PyObject_Str(ob);
+      if (s == NULL) // for instance string with bad encoding, non utf-8
+      {
+       s=PyObject_ASCII(ob); // escape non ASCII characters and like repr(), which is not the same as str()...
+      }
+      Py_ssize_t size;
+      const char* characters =  PyUnicode_AsUTF8AndSize(s, &size);
+      std::string ss( characters, size);
+      Py_DECREF(s);
+      PyGILState_Release(gstate);
+      return ss;
+    }
 
     //XML conversions
     PyObject* convertXmlPyObject(const TypeCode *t,xmlDocPtr doc,xmlNodePtr cur)
@@ -1841,6 +2335,47 @@ namespace YACS
       {
         return YacsConvertor<XMLImpl,xmlDocPtr,xmlNodePtr,CORBAImpl,CORBA::Any*>(t,doc,cur);
       }
+    PyObject* convertXmlStrPyObject(const TypeCode *t,std::string data)
+      {
+        xmlDocPtr doc;
+        xmlNodePtr cur;
+        PyObject *ob=NULL;
+        doc = xmlParseMemory(data.c_str(), strlen(data.c_str()));
+        if (doc == NULL )
+        {
+          std::stringstream msg;
+          msg << "Problem in conversion: XML Document not parsed successfully ";
+          msg << " (" << __FILE__ << ":" << __LINE__ << ")";
+          throw YACS::ENGINE::ConversionException(msg.str());
+        }
+        cur = xmlDocGetRootElement(doc);
+        if (cur == NULL)
+        {
+          xmlFreeDoc(doc);
+          std::stringstream msg;
+          msg << "Problem in conversion: empty XML Document";
+          msg << " (" << __FILE__ << ":" << __LINE__ << ")";
+          throw YACS::ENGINE::ConversionException(msg.str());
+        }
+        while (cur != NULL)
+        {
+          if ((!xmlStrcmp(cur->name, (const xmlChar *)"value")))
+          {
+            ob=convertXmlPyObject(t,doc,cur);
+            break;
+          }
+          cur = cur->next;
+        }
+        xmlFreeDoc(doc);
+        if(ob==NULL)
+        {
+          std::stringstream msg;
+          msg << "Problem in conversion: incorrect XML value";
+          msg << " (" << __FILE__ << ":" << __LINE__ << ")";
+          throw YACS::ENGINE::ConversionException(msg.str());
+        }
+        return ob;
+      }
     //NEUTRAL conversions
     PyObject* convertNeutralPyObject(const TypeCode *t,YACS::ENGINE::Any* data)
       {
@@ -1877,5 +2412,244 @@ namespace YACS
       {
         return YacsConvertor<CORBAImpl,CORBA::Any*,void*,CORBAImpl,CORBA::Any*>(t,data,0);
       }
+
+    //! Basic template checker from type TIN 
+    /*!
+     * This checker does nothing : throws exception
+     * It must be partially specialize for a specific type (TIN)
+     */
+    template <ImplType IMPLIN,class TIN,class TIN2>
+    static inline bool checkDouble(const TypeCode *t,TIN o,TIN2 aux)
+        {
+          stringstream msg;
+          msg << "Check not implemented for Implementation: " << IMPLIN ;
+          msg << " : " << __FILE__ << ":" << __LINE__;
+          throw YACS::ENGINE::ConversionException(msg.str());
+        }
+    template <ImplType IMPLIN,class TIN,class TIN2>
+    static inline bool checkInt(const TypeCode *t,TIN o,TIN2 aux)
+        {
+          stringstream msg;
+          msg << "Check not implemented for Implementation: " << IMPLIN ;
+          msg << " : " << __FILE__ << ":" << __LINE__;
+          throw YACS::ENGINE::ConversionException(msg.str());
+        }
+    template <ImplType IMPLIN,class TIN,class TIN2>
+    static inline bool checkBool(const TypeCode *t,TIN o,TIN2 aux)
+        {
+          stringstream msg;
+          msg << "Check not implemented for Implementation: " << IMPLIN ;
+          msg << " : " << __FILE__ << ":" << __LINE__;
+          throw YACS::ENGINE::ConversionException(msg.str());
+        }
+    template <ImplType IMPLIN,class TIN,class TIN2>
+    static inline bool checkString(const TypeCode *t,TIN o,TIN2 aux)
+        {
+          stringstream msg;
+          msg << "Check not implemented for Implementation: " << IMPLIN ;
+          msg << " : " << __FILE__ << ":" << __LINE__;
+          throw YACS::ENGINE::ConversionException(msg.str());
+        }
+    template <ImplType IMPLIN,class TIN,class TIN2>
+    static inline bool checkObjref(const TypeCode *t,TIN o,TIN2 aux)
+        {
+          stringstream msg;
+          msg << "Check not implemented for Implementation: " << IMPLIN ;
+          msg << " : " << __FILE__ << ":" << __LINE__;
+          throw YACS::ENGINE::ConversionException(msg.str());
+        }
+    template <ImplType IMPLIN,class TIN,class TIN2>
+    static inline bool checkSequence(const TypeCode *t,TIN o,TIN2 aux)
+        {
+          stringstream msg;
+          msg << "Check not implemented for Implementation: " << IMPLIN ;
+          msg << " : " << __FILE__ << ":" << __LINE__;
+          throw YACS::ENGINE::ConversionException(msg.str());
+        }
+    template <ImplType IMPLIN,class TIN,class TIN2>
+    static inline bool checkStruct(const TypeCode *t,TIN o,TIN2 aux)
+        {
+          stringstream msg;
+          msg << "Check not implemented for Implementation: " << IMPLIN ;
+          msg << " : " << __FILE__ << ":" << __LINE__;
+          throw YACS::ENGINE::ConversionException(msg.str());
+        }
+    template <ImplType IMPLIN,class TIN,class TIN2>
+    static inline bool checkArray(const TypeCode *t,TIN o,TIN2 aux)
+        {
+          stringstream msg;
+          msg << "Check not implemented for Implementation: " << IMPLIN ;
+          msg << " : " << __FILE__ << ":" << __LINE__;
+          throw YACS::ENGINE::ConversionException(msg.str());
+        }
+
+    template <ImplType IMPLIN,class TIN,class TIN2>
+    inline bool YacsChecker(const TypeCode *t,TIN o,TIN2 aux)
+      {
+         int tk=t->kind();
+         switch(t->kind())
+           {
+           case Double:
+             return checkDouble<IMPLIN,TIN,TIN2>(t,o,aux);
+           case Int:
+             return checkInt<IMPLIN,TIN,TIN2>(t,o,aux);
+           case String:
+             return checkString<IMPLIN,TIN,TIN2>(t,o,aux);
+           case Bool:
+             return checkBool<IMPLIN,TIN,TIN2>(t,o,aux);
+           case Objref:
+             return checkObjref<IMPLIN,TIN,TIN2>(t,o,aux);
+           case Sequence:
+             return checkSequence<IMPLIN,TIN,TIN2>(t,o,aux);
+           case Array:
+             return checkArray<IMPLIN,TIN,TIN2>(t,o,aux);
+           case Struct:
+             return checkStruct<IMPLIN,TIN,TIN2>(t,o,aux);
+           default:
+             break;
+           }
+         stringstream msg;
+         msg << "Check not implemented for kind= " << tk ;
+         msg << " : " << __FILE__ << ":" << __LINE__;
+         throw YACS::ENGINE::ConversionException(msg.str());
+      }
+    template<>
+    inline bool checkDouble<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
+      {
+        if (PyFloat_Check(o))
+          return true;
+        else if(PyLong_Check(o))
+          return true;
+        else
+          {
+            stringstream msg;
+            msg << "Not a python double ";
+            throw YACS::ENGINE::ConversionException(msg.str());
+          }
+      }
+    template<>
+    inline bool checkInt<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
+      {
+          if (PyLong_Check(o))
+            return true;
+          else
+            {
+              stringstream msg;
+              msg << "Not a python integer ";
+              throw YACS::ENGINE::ConversionException(msg.str());
+            }
+      }
+    template<>
+    inline bool checkBool<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
+      {
+          if (PyBool_Check(o))
+              return true;
+          else if(PyLong_Check(o))
+              return true;
+          else
+            {
+              stringstream msg;
+              msg << "Not a python boolean " ;
+              throw YACS::ENGINE::ConversionException(msg.str());
+            }
+
+      }
+    template<>
+    inline bool checkString<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
+      {
+          if (PyUnicode_Check(o))
+            return true;
+          else
+            {
+              stringstream msg;
+              msg << "Not a python string " ;
+              throw YACS::ENGINE::ConversionException(msg.str());
+            }
+      }
+    template<>
+    inline bool checkObjref<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
+      {
+          if (PyUnicode_Check(o))
+            return true;
+          if(strncmp(t->id(),"python",6)==0) // a Python object is expected (it's always true)
+            return true;
+          else if(strncmp(t->id(),"json",4)==0) // The python object must be json pickable
+            {
+               // The python object should be json compliant (to improve)
+               return true;
+            }
+          else
+            {
+              // The python object should be a CORBA obj (to improve)
+               return true;
+            }
+      }
+    template<>
+    inline bool checkSequence<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
+      {
+        if(!PySequence_Check(o))
+          {
+            stringstream msg;
+            msg << "python object is not a sequence " ;
+            throw YACS::ENGINE::ConversionException(msg.str());
+          }
+        int length=PySequence_Size(o);
+        for(int i=0;i<length;i++)
+          {
+            PyObject *item=PySequence_ITEM(o,i);
+            try
+              {
+                YacsChecker<PYTHONImpl,PyObject*,void*>(t->contentType(),item,0);
+              }
+            catch(ConversionException& ex)
+              {
+                stringstream msg;
+                msg << ex.what() << " for sequence element " << i;
+                throw YACS::ENGINE::ConversionException(msg.str(),false);
+              }
+            Py_DECREF(item);
+          }
+        return true;
+      }
+    template<>
+    inline bool checkStruct<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
+      {
+        PyObject *value;
+        if(!PyDict_Check(o))
+          {
+            stringstream msg;
+            msg << "python object is not a dict " ;
+            throw YACS::ENGINE::ConversionException(msg.str());
+          }
+        YACS::ENGINE::TypeCodeStruct* tst=(YACS::ENGINE::TypeCodeStruct*)t;
+        int nMember=tst->memberCount();
+        for(int i=0;i<nMember;i++)
+          {
+            std::string name=tst->memberName(i);
+            TypeCode* tm=tst->memberType(i);
+            value=PyDict_GetItemString(o, name.c_str());
+            if(value==NULL)
+              {
+                stringstream msg;
+                msg << "member " << name << " not present " ;
+                throw YACS::ENGINE::ConversionException(msg.str());
+              }
+            try
+              {
+                YacsChecker<PYTHONImpl,PyObject*,void*>(tm,value,0);
+              }
+            catch(ConversionException& ex)
+              {
+                std::string s=" for struct member "+name;
+                throw YACS::ENGINE::ConversionException(ex.what()+s,false);
+              }
+          }
+        return true;
+      }
+
+    bool checkPyObject(const TypeCode *t,PyObject* ob)
+      {
+        return YacsChecker<PYTHONImpl,PyObject*,void*>(t,ob,0);
+      }
   }
 }