Salome HOME
Moved some functionality to VTKViewer_Utilities.h
[modules/kernel.git] / src / SALOMEDS / SALOMEDS_StudyManager_i.cxx
index 4d12d2379154387ca9d96bfcc4fb28102f85a030..588019be2d76bea0b75cc2640d8264fe267d4c69 100644 (file)
 //  Module : SALOME
 //  $Header$
 
-using namespace std;
-#include "utilities.h"
-#include "SALOMEDS_StudyManager_i.hxx"
-#include "SALOMEDS_Study_i.hxx"
-#include "SALOMEDS_SComponent_i.hxx"
+#include <memory>
+#include <sstream>
 
-#include "SALOMEDS_IORAttribute.hxx"
-#include "SALOMEDS_PersRefAttribute.hxx"
-#include "SALOMEDS_Tool.hxx"
+#include <OSD_Process.hxx>
+#include <Quantity_Date.hxx>
 
 #include <TDF_Label.hxx>
 #include <TDataStd_Name.hxx>
 #include <TDataStd_Comment.hxx>
+#include <TDataStd_Integer.hxx>
 #include <TDataStd_TreeNode.hxx>
 #include <TDataStd_UAttribute.hxx> 
+#include <TDF_ChildIterator.hxx>
 #include <TDF_Tool.hxx>
 #include <TDF_Reference.hxx>
 #include <TDF_Data.hxx>
 #include <TDF_RelocationTable.hxx>
 #include <TDF_AttributeIterator.hxx>
-//  #include <TDocStd_Owner.hxx>
-#include <TColStd_HArray1OfCharacter.hxx>
 #include <TCollection_ExtendedString.hxx>
-#include "HDFexplorer.hxx"
-#include "SALOMEDS_SequenceOfRealAttribute.hxx"
-#include "SALOMEDS_SequenceOfIntegerAttribute.hxx"
-#include <TColStd_HSequenceOfReal.hxx>
-#include <TColStd_HSequenceOfInteger.hxx>
-#include "SALOMEDS_PixMapAttribute.hxx"
-#include "SALOMEDS_DrawableAttribute.hxx"
-#include "SALOMEDS_SelectableAttribute.hxx"
-#include "SALOMEDS_ExpandableAttribute.hxx"
-#include "SALOMEDS_OpenedAttribute.hxx"
-#include "SALOMEDS_TextColorAttribute.hxx"
-#include "SALOMEDS_TextHighlightColorAttribute.hxx"
-#include "SALOMEDS_LocalIDAttribute.hxx"
+#include <TCollection_AsciiString.hxx>
+
+#include "SALOMEDS_StudyManager_i.hxx"
+#include "SALOME_LifeCycleCORBA.hxx"
+
+#include "SALOMEDS_Study_i.hxx"
+#include "SALOMEDS_SObject_i.hxx"
+#include "SALOMEDS_StudyBuilder_i.hxx"
+
+#include "SALOMEDS_IORAttribute.hxx"
+#include "SALOMEDS_PersRefAttribute.hxx"
 #include "SALOMEDS_TargetAttribute.hxx"
-#include "SALOMEDS_TableOfIntegerAttribute.hxx"
-#include "SALOMEDS_TableOfRealAttribute.hxx"
-#include "SALOMEDS_TableOfStringAttribute.hxx"
-#include "SALOMEDS_StudyPropertiesAttribute.hxx"
-#include "SALOMEDS_PythonObjectAttribute.hxx"
-#include <OSD_Process.hxx>
-#include <Quantity_Date.hxx>
 
+#include "SALOMEDS_Tool.hxx"
+#include "HDFexplorer.hxx"
+
+// IDL headers
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SALOMEDS_Attributes)
+
+#include "SALOME_GenericObj_i.hh"
 #include "Utils_CorbaException.hxx"
+#include "Utils_ExceptHandlers.hxx"
+
+UNEXPECT_CATCH(SalomeException,SALOME::SALOME_Exception);
+UNEXPECT_CATCH(LockProtection, SALOMEDS::StudyBuilder::LockProtection);
+
+#define USE_CASE_LABEL_ID             "0:2"
+#define AUTO_SAVE_GUID                "128268A3-71C9-4036-89B1-F81BD6A4FCF2"
+#define AUTO_SAVE_TAG                 "0:8"
+#define AUTO_SAVE_TIME_OUT_IN_SECONDS 1200
 
-#include <strstream>
+#include "utilities.h"
 
-#define USE_CASE_LABEL_ID            "0:2"
+using namespace std;
+
+//===========================================================================
+namespace SALOMEDS{
+
+  CORBA::Object_var 
+  GetObject(const TDF_Label& theLabel, CORBA::ORB_ptr theORB)
+  {
+    try {
+      Handle(SALOMEDS_IORAttribute) anAttr;
+      if(theLabel.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr))
+       return theORB->string_to_object(TCollection_AsciiString(anAttr->Get()).ToCString());
+    }catch(...){
+    }
+    return CORBA::Object::_nil();
+  }
+
+
+  PortableServer::ServantBase_var 
+  GetServant(CORBA::Object_ptr theObject, PortableServer::POA_ptr thePOA)
+  {
+    if(CORBA::is_nil(theObject))
+      return NULL;
+    try{
+      return thePOA->reference_to_servant(theObject);
+    }catch(...){
+      return NULL;
+    }
+  }
+
+}
 
 //===========================================================================
 //Function : LoadAttributes
 //===========================================================================
-static void ReadAttributes(Handle(TDF_Data)& DF,
-                          TDF_Label& Lab, 
-                          HDFdataset* hdf_dataset)
+static 
+void 
+ReadAttributes(SALOMEDS_Study_i* theStudy,
+              SALOMEDS::SObject_ptr aSO,
+              HDFdataset* hdf_dataset)
 {
   hdf_dataset->OpenOnDisk();
-  
-  if (hdf_dataset->GetType() == HDF_STRING) {
-
-    if (!strncmp(hdf_dataset->GetName(),"AttributeTreeNode",17)) {
-      MESSAGE("Create a Attribute :     AttributeTreeNode");
-      char current_strings[5][hdf_dataset->GetSize()/5];
-      hdf_dataset->ReadFromDisk(current_strings);
-
-      MESSAGE("Create an Attribute :     AttributeTreeNode"); 
-      Standard_GUID aGUID(current_strings[4]);
-      Handle(TDataStd_TreeNode) aNewNode = TDataStd_TreeNode::Set(Lab,aGUID);
-      TDF_Label aLabel;
-      Handle(TDataStd_TreeNode) aNode;
-      if (current_strings[0][0]) {
-        TDF_Tool::Label(DF,current_strings[0],aLabel,1);
-        if (!aLabel.FindAttribute(aGUID,aNode)) aNode = TDataStd_TreeNode::Set(aLabel,aGUID);
-        aNewNode->SetFather(aNode);
-      }
-      if (current_strings[1][0]) {
-        TDF_Tool::Label(DF,current_strings[1],aLabel,1);
-       if (!aLabel.FindAttribute(aGUID,aNode)) aNode = TDataStd_TreeNode::Set(aLabel,aGUID);
-        aNewNode->SetPrevious(aNode);
-      }
-      if (current_strings[2][0]) {
-        TDF_Tool::Label(DF,current_strings[2],aLabel,1);
-        if (!aLabel.FindAttribute(aGUID,aNode)) aNode = TDataStd_TreeNode::Set(aLabel,aGUID);
-        aNewNode->SetNext(aNode);
-      }
-      if (current_strings[3][0]) {
-        TDF_Tool::Label(DF,current_strings[3],aLabel,1);
-        if (!aLabel.FindAttribute(aGUID,aNode)) aNode = TDataStd_TreeNode::Set(aLabel,aGUID);
-        aNewNode->SetFirst(aNode);
-      }
-    } else {
 
-      int size =  hdf_dataset->GetSize();
-      char* current_string = new char[size];
-      hdf_dataset->ReadFromDisk(current_string);
+  SALOMEDS::GenericAttribute_var anAttr;
 
-      if (!strcmp(hdf_dataset->GetName(),"COMPONENTDATATYPE")) {      
-        MESSAGE("Create a OCAF Attribute :    COMPONENTDATATYPE");
-        TDataStd_Comment::Set         (Lab,current_string); 
-      }
-      else if (!strcmp(hdf_dataset->GetName(),"AttributeComment")) {
-        MESSAGE("Create an Attribute :     AttributeComment"); 
-        TDataStd_Comment::Set         (Lab,current_string); 
-      }
-      else if (!strcmp(hdf_dataset->GetName(),"AttributeName")) {
-        MESSAGE("Create an  Attribute :     AttributeName");       
-        TDataStd_Name::Set            (Lab,current_string);
-      }
-      else if (!strcmp(hdf_dataset->GetName(),"AttributePersistentRef")) { 
-        MESSAGE("Create an Attribute :     AttributePersistentRef"); 
-        SALOMEDS_PersRefAttribute::Set(Lab,current_string);
-      }
-      else if (!strcmp(hdf_dataset->GetName(),"Reference")) {
-        MESSAGE("Create a OCAF Attribute :     Reference"); 
-        TDF_Label RefLab;
-        TDF_Tool::Label(DF,current_string,RefLab,1);
-        TDF_Reference::Set(Lab,RefLab);
-       SALOMEDS_TargetAttribute::Set(RefLab)->Append(Lab);
-      }
-      else if (!strcmp(hdf_dataset->GetName(),"AttributeReal")) {
-        MESSAGE("Create a Attribute :     AttributeReal");
-        char * err = NULL;
-        CORBA::Double r =  strtod(current_string, &err);
-        SCRUTE(r);
-        if (err == current_string) {
-         MESSAGE("AtttributeReal : conversion impossible");
-        }
-        else TDataStd_Real::Set (Lab,r);
-      }
-      else if (!strcmp(hdf_dataset->GetName(),"AttributeInteger")) {
-        MESSAGE("Create a Attribute :     AttributeInteger");
-        CORBA::Long r =  atol(current_string);
-        SCRUTE(r);
-        TDataStd_Integer::Set (Lab,r);
-      }
-      else if (!strcmp(hdf_dataset->GetName(),"AttributePixMap")) {
-        MESSAGE("Create an  Attribute :     AttributePixMap");       
-        SALOMEDS_PixMapAttribute::Set (Lab,current_string);
-      }
-      else if (!strcmp(hdf_dataset->GetName(),"AttributeDrawable")) {
-        MESSAGE("Create a Attribute :     DrawableAttribute");
-        CORBA::Long r =  atol(current_string);
-        SCRUTE(r);
-        SALOMEDS_DrawableAttribute::Set (Lab,r);
-      }
-      else if (!strcmp(hdf_dataset->GetName(),"AttributeSelectable")) {
-        MESSAGE("Create a Attribute :     AttributeSelectable");
-        CORBA::Long r =  atol(current_string);
-        SCRUTE(r);
-        SALOMEDS_SelectableAttribute::Set (Lab,r);
-      }
-      else if (!strcmp(hdf_dataset->GetName(),"AttributeExpandable")) {
-        MESSAGE("Create a Attribute :     AttributeExpandable");
-        CORBA::Long r =  atol(current_string);
-        SCRUTE(r);
-        SALOMEDS_ExpandableAttribute::Set (Lab,r);
-      }
-      else if (!strcmp(hdf_dataset->GetName(),"AttributeOpened")) {
-        MESSAGE("Create a Attribute :     AttributeOpened");
-        CORBA::Long r =  atol(current_string);
-        SCRUTE(r);
-        SALOMEDS_OpenedAttribute::Set (Lab,r);
-      }
-      else if (!strcmp(hdf_dataset->GetName(),"AttributeLocalID")) {
-        MESSAGE("Create a Attribute :     AttributeLocalID");
-        CORBA::Long r =  atol(current_string);
-        SCRUTE(r);
-        SALOMEDS_LocalIDAttribute::Set (Lab,r);
-      }
-      else if (!strncmp(hdf_dataset->GetName(),"AttributeUserID",15)) {
-        MESSAGE("Create an  Attribute :     AttributeUserID");       
-        TDataStd_UAttribute::Set       (Lab,Standard_GUID(current_string));
-      }
-      else if (!strcmp(hdf_dataset->GetName(),"AttributeTableOfInteger")) {
-       MESSAGE("Create a Attribute :     AttributeTableOfInteger");
-       int size = hdf_dataset->GetSize();
-       Handle(SALOMEDS_TableOfIntegerAttribute) Attr = SALOMEDS_TableOfIntegerAttribute::Set(Lab);
-       unsigned char* aBuffer = new unsigned char[size];
-       if(aBuffer == NULL) throw HDFexception("Unable to open dataset AttributeTableOfInteger");
-       hdf_dataset->ReadFromDisk(aBuffer);
-       SALOMEDS::TMPFile_var aTMPFile = new SALOMEDS::TMPFile(size, size, aBuffer, 1);
-       istrstream aStream((char*)&aTMPFile[0], aTMPFile->length());
-       Attr->RestoreFromString(aStream);
-      }
-      else if (!strcmp(hdf_dataset->GetName(),"AttributeTableOfReal")) {
-       MESSAGE("Create a Attribute :     AttributeTableOfReal");
-       int size = hdf_dataset->GetSize();
-       Handle(SALOMEDS_TableOfRealAttribute) Attr = SALOMEDS_TableOfRealAttribute::Set(Lab);
-       unsigned char* aBuffer = new unsigned char[size];
-       if(aBuffer == NULL) throw HDFexception("Unable to open dataset AttributeTableOfReal");
-       hdf_dataset->ReadFromDisk(aBuffer);
-       SALOMEDS::TMPFile_var aTMPFile = new SALOMEDS::TMPFile(size, size, aBuffer, 1);
-       istrstream aStream((char*)&aTMPFile[0], aTMPFile->length());
-       Attr->RestoreFromString(aStream);
-      }
-      else if (!strcmp(hdf_dataset->GetName(),"AttributeTableOfString")) {
-       MESSAGE("Create a Attribute :     AttributeTableOfString");
-       int size = hdf_dataset->GetSize();
-       Handle(SALOMEDS_TableOfStringAttribute) Attr = SALOMEDS_TableOfStringAttribute::Set(Lab);
-       unsigned char* aBuffer = new unsigned char[size];
-       if(aBuffer == NULL) throw HDFexception("Unable to open dataset AttributeTableOfString");
-       hdf_dataset->ReadFromDisk(aBuffer);
-       SALOMEDS::TMPFile_var aTMPFile = new SALOMEDS::TMPFile(size, size, aBuffer, 1);
-       istrstream aStream((char*)&aTMPFile[0], aTMPFile->length());
-       Attr->RestoreFromString(aStream);
-      }
-      else if (!strcmp(hdf_dataset->GetName(),"AttributeStudyProperties")) {
-        MESSAGE("Create an  Attribute :     AttributeStudyProperties");     
-//     MESSAGE("current string :"<<current_string);
-        Handle(SALOMEDS_StudyPropertiesAttribute) aProp = SALOMEDS_StudyPropertiesAttribute::Set (Lab);
-       switch (current_string[0]) {
-       case 'f': aProp->SetCreationMode(1);break;
-       case 'c': aProp->SetCreationMode(2);break;
-       }
+  char* current_string = new char[hdf_dataset->GetSize()];
+  hdf_dataset->ReadFromDisk(current_string);
 
-       int anIndex;
-       for(anIndex = 2; anIndex + 2 < size ;) {
-         char str[10];
-         Standard_Integer aMinute, aHour, aDay, aMonth, aYear;
-         str[0] = current_string[anIndex++];
-         str[1] = current_string[anIndex++];
-         str[2] = 0;
-         aMinute = atoi(str);
-         str[0] = current_string[anIndex++];
-         str[1] = current_string[anIndex++];
-         aHour =  atoi(str);
-         str[0] = current_string[anIndex++];
-         str[1] = current_string[anIndex++];
-         aDay =  atoi(str);
-         str[0] = current_string[anIndex++];
-         str[1] = current_string[anIndex++];
-         aMonth =  atoi(str);
-         str[0] = current_string[anIndex++];
-         str[1] = current_string[anIndex++];
-         str[2] = current_string[anIndex++];
-         str[3] = current_string[anIndex++];
-         str[4] = 0;
-         aYear = atoi(str);
-         aProp->SetModificationDate(aMinute,aHour,aDay,aMonth,aYear);
-
-         int aNameSize;
-         for(aNameSize = 0; current_string[anIndex+aNameSize]!=1; aNameSize++);
-         char *aName = new char[aNameSize+1];
-         strncpy(aName, &(current_string[anIndex]), aNameSize);
-         aName[aNameSize] = 0;
-         aProp->SetUserName(TCollection_ExtendedString(aName));
-         delete(aName);
-         anIndex += aNameSize + 1;
-         if (current_string[1] == 'l') {
-           aProp->SetLocked(Standard_True);
-           aProp->IsLockChanged(true);
-         }
-         aProp->SetModified(0);
-       }
-      }
-      else if (!strcmp(hdf_dataset->GetName(),"AttributePythonObject")) {
-        MESSAGE("Create an  Attribute :     AttributePythonObject");       
-       Handle(SALOMEDS_PythonObjectAttribute) anObj = SALOMEDS_PythonObjectAttribute::Set(Lab);
-       Standard_Boolean aScript = (current_string[0] == 's')?Standard_True:Standard_False;
-       anObj->SetObject((char *)(current_string+1), aScript);
-      }
-      else {
-        MESSAGE(hdf_dataset->GetName());
-        MESSAGE("LoadAttributes: unknown types");
-      }
-    }
-  }
-  if (hdf_dataset->GetType() == HDF_FLOAT64) {
-    if (!strcmp(hdf_dataset->GetName(),"AttributeSequenceOfReal")) {
-      MESSAGE("Create a Attribute :     AttributeSequenceOfReal");
-      int size = hdf_dataset->GetSize();
-      hdf_float64* val = new hdf_float64[size];
-      hdf_dataset->ReadFromDisk(val);
-      Handle(TColStd_HSequenceOfReal) SeqReal = new TColStd_HSequenceOfReal;
-      for (Standard_Integer i = 0; i < size; i++) {
-        SeqReal->Append(val[i]);
-//          MESSAGE( val[i] << " restored"   );
-      }
-      SALOMEDS_SequenceOfRealAttribute::Set (Lab);
-      Handle(SALOMEDS_SequenceOfRealAttribute) Attr;
-      Handle(TDF_Attribute) Att;
-      Lab.FindAttribute(SALOMEDS_SequenceOfRealAttribute::GetID(),Att);
-      Attr = Handle(SALOMEDS_SequenceOfRealAttribute)::DownCast(Att);
-      Attr->Assign(SeqReal);
-    } else
-    if (!strcmp(hdf_dataset->GetName(),"AttributeTextColor")) {
-      MESSAGE("Create a Attribute :     AttributeTextColor");
-      hdf_float64 val[3];
-      hdf_dataset->ReadFromDisk(val);
-      Handle(SALOMEDS_TextColorAttribute) TC = new SALOMEDS_TextColorAttribute;
-      Lab.AddAttribute(TC); 
-      TC->SetValue(1, val[0]);
-      TC->SetValue(2, val[1]);
-      TC->SetValue(3, val[2]);
-    } else
-    if (!strcmp(hdf_dataset->GetName(),"AttributeTextHighlightColor")) {
-      MESSAGE("Create a Attribute :     AttributeTextHighlightColor");
-      hdf_float64 val[3];
-      hdf_dataset->ReadFromDisk(val);
-      Handle(SALOMEDS_TextHighlightColorAttribute) TC = new SALOMEDS_TextHighlightColorAttribute;
-      Lab.AddAttribute(TC); 
-      TC->SetValue(1, val[0]);
-      TC->SetValue(2, val[1]);
-      TC->SetValue(3, val[2]);
-    }else {
-      MESSAGE(hdf_dataset->GetName());
-      MESSAGE("LoadAttributes: unknown types");
-    }
+  if (!strcmp(hdf_dataset->GetName(),"COMPONENTDATATYPE")) {
+    anAttr = theStudy->GetBuilder()->FindOrCreateAttribute(aSO, "AttributeComment");
+  } else if (!strcmp(hdf_dataset->GetName(),"Reference")) {
+    theStudy->GetBuilder()->Addreference(aSO, theStudy->CreateObjectID(current_string));
+    delete(current_string);
+    hdf_dataset->CloseOnDisk();
+    return;
+  } else {
+    MESSAGE("Read attribute "<<hdf_dataset->GetName())
+    anAttr = theStudy->GetBuilder()->FindOrCreateAttribute(aSO, hdf_dataset->GetName());
   }
-  if (hdf_dataset->GetType() == HDF_INT32) {
-    if (!strcmp(hdf_dataset->GetName(),"AttributeSequenceOfInteger")) {
-      MESSAGE("Create a OCAF Attribute :     AttributeSequenceOfInteger");
-      int size = hdf_dataset->GetSize();
-      hdf_int32* val = new hdf_int32[size];
-      hdf_dataset->ReadFromDisk(val);
-      Handle(TColStd_HSequenceOfInteger) SeqInt = new TColStd_HSequenceOfInteger;
-      for (Standard_Integer i = 0; i < size; i++) {
-        SeqInt->Append(val[i]);
-//          MESSAGE( val[i] << " restored"   );
-      }
-      SALOMEDS_SequenceOfIntegerAttribute::Set (Lab);
-      Handle(SALOMEDS_SequenceOfIntegerAttribute) Attr;
-      Handle(TDF_Attribute) Att;
-      Lab.FindAttribute(SALOMEDS_SequenceOfIntegerAttribute::GetID(),Att);
-      Attr = Handle(SALOMEDS_SequenceOfIntegerAttribute)::DownCast(Att);
-      Attr->Assign(SeqInt);
-    } 
-    else {
-      MESSAGE(hdf_dataset->GetName());
-      MESSAGE("LoadAttributes: unknown types");
-    }
+
+  if (!CORBA::is_nil(anAttr)) {
+    anAttr->Restore(current_string);
+    MESSAGE("Restoring attribute "<<hdf_dataset->GetName()<<" by string '"<<current_string<<"' done")
+  } else {
+    MESSAGE(hdf_dataset->GetName());
+    MESSAGE("LoadAttributes: unknown types");
   }
+  delete(current_string);
   hdf_dataset->CloseOnDisk();
 }
 
 //============================================================================
 //Function : Translate_IOR_to_persistentID
 //============================================================================
-static void Translate_IOR_to_persistentID (SALOMEDS::Study_ptr        study,
-                                          SALOMEDS::StudyBuilder_ptr SB,
-                                          SALOMEDS::SObject_ptr      so,
-                                          SALOMEDS::Driver_ptr       engine,
-                                          CORBA::Boolean             isMultiFile,
-                                          CORBA::Boolean             isASCII)
+static void Translate_IOR_to_persistentID(SALOMEDS_Study_i* theStudy,
+                                         SALOMEDS_StudyBuilder_i* theBuilder,
+                                         SALOMEDS::SObject_ptr theSObject,
+                                         SALOMEDS::Driver_ptr theEngine,
+                                         CORBA::Boolean theIsMultiFile,
+                                         CORBA::Boolean theIsASCII)
 {
   MESSAGE("In Translate_IOR_to_persistentID");
-  SALOMEDS::ChildIterator_var itchild = study->NewChildIterator(so);
-  CORBA::String_var ior_string;
-  char* persistent_string = 0;
-  char *curid=0;
-
-  for (; itchild->More(); itchild->Next()) {
-    SALOMEDS::SObject_var current = itchild->Value();
-    SCRUTE(current->GetID());
-    SALOMEDS::GenericAttribute_var SObj;
-    if (current->FindAttribute(SObj, "AttributeIOR")) {
-      SALOMEDS::AttributeIOR_var IOR = SALOMEDS::AttributeIOR::_narrow(SObj);
-      ior_string = IOR->Value();
-      SCRUTE(ior_string);
-      
-      persistent_string = engine->IORToLocalPersistentID (current,ior_string,isMultiFile, isASCII);
-      
-//       SB->AddAttribute (current, SALOMEDS::PersistentRef,persistent_string);
-      SALOMEDS::AttributePersistentRef_var Pers = SALOMEDS::AttributePersistentRef::_narrow(SB->FindOrCreateAttribute (current, "AttributePersistentRef"));
-      Pers->SetValue(persistent_string);
-      SCRUTE(persistent_string);
-      curid = current->GetID();
-      MESSAGE("Translate " << curid <<
-             " to Persistent string "<<persistent_string);
-      persistent_string = 0;
-      curid = 0;
+  SALOMEDS_ChildIterator_i anIter = theStudy->GetChildIterator(theSObject);
+  for(; anIter.More(); anIter.Next()){
+    SALOMEDS::GenericAttribute_var anAttr;
+    SALOMEDS::SObject_var aSObject = anIter.Value();
+    if(aSObject->FindAttribute(anAttr,"AttributeIOR")){
+      SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
+      CORBA::String_var aString = anIOR->Value();
+      CORBA::String_var aPersistentID = 
+       theEngine->IORToLocalPersistentID(aSObject,aString,theIsMultiFile,theIsASCII);
+      anAttr = theBuilder->FindOrCreateAttribute(aSObject,"AttributePersistentRef");
+      SALOMEDS::AttributePersistentRef_var aPersistentRef = SALOMEDS::AttributePersistentRef::_narrow(anAttr);
+      aPersistentRef->SetValue(aPersistentID);
+      aString = aSObject->GetID();
     }
-    Translate_IOR_to_persistentID (study,SB,current,engine,isMultiFile, isASCII);
+    Translate_IOR_to_persistentID(theStudy,theBuilder,aSObject,theEngine,theIsMultiFile,theIsASCII);
   }
-  CORBA::string_free(persistent_string);
-  CORBA::string_free(curid);
 }
 
 //============================================================================
 //Function : BuildlTree
 //============================================================================
-static void BuildTree  (Handle(TDF_Data)& DF,HDFgroup* hdf_current_group)
+static 
+void 
+BuildTree(SALOMEDS_Study_i* theStudy, HDFgroup* hdf_current_group)
 {
   hdf_current_group->OpenOnDisk();
   
-  TDF_Label Lab;
-  Standard_CString Entry = hdf_current_group->GetName();
+  SALOMEDS::SObject_var aSO;
+  char* Entry = hdf_current_group->GetName();
   if (strcmp(Entry,"STUDY_STRUCTURE") == 0) {
     MESSAGE("find the root of the document");
-    Lab =  DF->Root().FindChild(1,Standard_True);
+    aSO = theStudy->CreateObjectID("0:1");
   }
   else {
-    TDF_Tool::Label  (DF,Entry,Lab,1);
+    aSO = theStudy->CreateObjectID(Entry);
     MESSAGE("BuildTree : Create a new label"<<Entry);
   }
   char name[HDF_NAME_MAX_LEN+1];
@@ -434,14 +209,14 @@ static void BuildTree  (Handle(TDF_Data)& DF,HDFgroup* hdf_current_group)
     if  (type == HDF_DATASET) {
       MESSAGE("--> Dataset: Internal Object Name : " << name);
       HDFdataset* new_dataset = new HDFdataset(name,hdf_current_group);
-      ReadAttributes   (DF,Lab,new_dataset);      
+      ReadAttributes(theStudy,aSO,new_dataset);      
       new_dataset = 0; // will be deleted by father destructor
 
     }
     else if (type == HDF_GROUP)   {
       MESSAGE( "--> Group: Internal Object Name : " << name);
       HDFgroup* new_group = new HDFgroup(name,hdf_current_group);
-      BuildTree (DF,new_group);
+      BuildTree(theStudy, new_group);
       new_group = 0; // will be deleted by father destructor
     }
   }
@@ -454,14 +229,16 @@ static void BuildTree  (Handle(TDF_Data)& DF,HDFgroup* hdf_current_group)
  *  Purpose  : SALOMEDS_StudyManager_i constructor 
  */
 //============================================================================
-SALOMEDS_StudyManager_i::SALOMEDS_StudyManager_i(CORBA::ORB_ptr orb) 
+SALOMEDS_StudyManager_i::SALOMEDS_StudyManager_i(CORBA::ORB_ptr theORB, 
+                                                PortableServer::POA_ptr thePOA):
+  _orb(CORBA::ORB::_duplicate(theORB)),
+  _poa(PortableServer::POA::_duplicate(thePOA)),
+  _OCAFApp(new SALOMEDS_OCAFApplication()),
+  _name_service(theORB)
 { 
-  _orb = CORBA::ORB::_duplicate(orb);
-  _OCAFApp = new SALOMEDS_OCAFApplication();  
-  _name_service = new SALOME_NamingService(_orb);
   // Study directory creation in the naming service : to register all
   // open studies in the session
-  _name_service->Create_Directory("/Study");
+  _name_service.Create_Directory("/Study");
   _IDcounter = 0;
 }
 
@@ -473,9 +250,19 @@ SALOMEDS_StudyManager_i::SALOMEDS_StudyManager_i(CORBA::ORB_ptr orb)
 SALOMEDS_StudyManager_i::~SALOMEDS_StudyManager_i()
 {
   // Destroy directory to register open studies
-  _name_service->Destroy_Directory("/Study");
-  // Destroy OCAF document
-  delete &_OCAFApp;
+  _name_service.Destroy_Directory("/Study");
+}
+
+SALOMEDS_Study_i* 
+SALOMEDS_StudyManager_i::DownCast(SALOMEDS::Study_ptr theStudy) const
+{
+  if(!CORBA::is_nil(theStudy)){
+    PortableServer::POA_var aPOA = GetPOA();
+    PortableServer::ServantBase_var aServant = SALOMEDS::GetServant(theStudy,aPOA);
+    if(aServant.in())
+      return dynamic_cast<SALOMEDS_Study_i*>(aServant.in());
+  }
+  return NULL;
 }
 
 //============================================================================
@@ -484,9 +271,9 @@ SALOMEDS_StudyManager_i::~SALOMEDS_StudyManager_i()
  *             context name
  */
 //============================================================================
-void SALOMEDS_StudyManager_i::register_name(char * name) {
-  SALOMEDS::StudyManager_ptr g = SALOMEDS::StudyManager::_narrow(_this());
-  _name_service->Register(g, name);
+void SALOMEDS_StudyManager_i::register_name(char * theName) {
+  SALOMEDS::StudyManager_var aManager(_this());
+  _name_service.Register(aManager.in(),theName);
 }
 
 
@@ -495,40 +282,45 @@ void SALOMEDS_StudyManager_i::register_name(char * name) {
  *  Purpose  : Create a New Study of name study_name
  */
 //============================================================================
-SALOMEDS::Study_ptr SALOMEDS_StudyManager_i::NewStudy(const char* study_name) 
+SALOMEDS::Study_ptr SALOMEDS_StudyManager_i::NewStudy(const char* theStudyName) 
 {
-  Handle(TDocStd_Document) Doc;
-  _OCAFApp->NewDocument("SALOME_STUDY",Doc); 
+  Handle(TDocStd_Document) aDocument;
+  _OCAFApp->NewDocument("SALOME_STUDY",aDocument); 
 
   MESSAGE("NewStudy : Creating the CORBA servant holding it... ");
-  SALOMEDS_Study_i *Study_servant = new SALOMEDS_Study_i(Doc,_orb,study_name); 
-  SALOMEDS::Study_var Study = SALOMEDS::Study::_narrow(Study_servant->_this());
+  SALOMEDS_Study_i* aStudyServant = new SALOMEDS_Study_i(this,aDocument,theStudyName); 
+  SALOMEDS::Study_var aStudy = aStudyServant->_this();
 
   //Study->StudyId( _OCAFApp->NbDocuments() ); 
   _IDcounter++;
-  Study->StudyId( _IDcounter );
+  aStudyServant->StudyId( _IDcounter );
 
   // Register study in the naming service
   // Path to acces the study
-  if(!_name_service->Change_Directory("/Study")) 
-      MESSAGE( "Unable to access the study directory" )
-  else
-      _name_service->Register(Study, study_name);
-
+  if(!_name_service.Change_Directory("/Study")){
+    MESSAGE( "Unable to access the study directory" );
+  }else
+    _name_service.Register(aStudy, theStudyName);
+                                                  
   // Assign the value of the IOR in the study->root
-  const char*  IORStudy = _orb->object_to_string(Study);
-  SALOMEDS_IORAttribute::Set(Doc->Main().Root(),TCollection_ExtendedString(strdup(IORStudy)),_orb);
+  CORBA::String_var anIOR = _orb->object_to_string(aStudy);
+  SALOMEDS_IORAttribute::Set(aDocument->Main().Root(),
+                            const_cast<char*>(anIOR.in()),
+                            aStudyServant);
 
   // set Study properties
-  SALOMEDS::AttributeStudyProperties_ptr aProp = Study->GetProperties();
+  SALOMEDS::AttributeStudyProperties_var aProp = aStudyServant->GetProperties();
   OSD_Process aProcess;
   Quantity_Date aDate = aProcess.SystemDate();
-  aProp->SetCreationDate(CORBA::Long(aDate.Minute()), CORBA::Long(aDate.Hour()), CORBA::Long(aDate.Day()),
-                        CORBA::Long(aDate.Month()), CORBA::Long(aDate.Year()));
+  aProp->SetCreationDate(CORBA::Long(aDate.Minute()), 
+                        CORBA::Long(aDate.Hour()), 
+                        CORBA::Long(aDate.Day()),
+                        CORBA::Long(aDate.Month()), 
+                        CORBA::Long(aDate.Year()));
   aProp->SetCreationMode("from scratch");
   aProp->SetUserName(aProcess.UserName().ToCString());
 
-  return Study;
+  return aStudy._retn();
 }
 
 //============================================================================
@@ -536,119 +328,98 @@ SALOMEDS::Study_ptr SALOMEDS_StudyManager_i::NewStudy(const char* study_name)
  *  Purpose  : Open a Study from it's persistent reference
  */
 //============================================================================
-SALOMEDS::Study_ptr  SALOMEDS_StudyManager_i::Open(const char* aUrl)
+SALOMEDS::Study_ptr  SALOMEDS_StudyManager_i::Open(const char* theURL)
      throw(SALOME::SALOME_Exception)
 {
+  Unexpect aCatch(SalomeException);
   MESSAGE("Begin of SALOMEDS_StudyManager_i::Open");
-  // open the HDFFile 
-  HDFfile *hdf_file =0;         
-  HDFgroup *hdf_group_study_structure =0;
 
-  char* aHDFUrl;
   bool isASCII = false;
-  if (HDFascii::isASCII(aUrl)) {
+  std::ostringstream anURLStream;
+  if (HDFascii::isASCII(theURL)) {
     isASCII = true;
-    char* aResultPath = HDFascii::ConvertFromASCIIToHDF(aUrl);
-    aHDFUrl = new char[strlen(aResultPath) + 19];
-    sprintf(aHDFUrl, "%shdf_from_ascii.hdf", aResultPath);
-    delete(aResultPath);
+    auto_ptr<char> aResultPath(HDFascii::ConvertFromASCIIToHDF(theURL));
+    anURLStream<<aResultPath.get()<<"hdf_from_ascii.hdf";
   } else {
-    aHDFUrl = strdup(aUrl);
+    anURLStream<<theURL;
   }
+  std::string aHDFUrl = anURLStream.str();
+
+  // open the HDFFile (all related hdf objects will be deleted     )
+  auto_ptr<HDFfile> hdf_file(new HDFfile(const_cast<char*>(aHDFUrl.c_str())));
 
-  hdf_file = new HDFfile(aHDFUrl);
   try {
     hdf_file->OpenOnDisk(HDF_RDONLY);// mpv: was RDWR, but opened file can be write-protected too
-  }
-  catch (HDFexception)
-    {
-//        MESSAGE( "HDFexception ! " );
-//        cerr << "HDFexception ! " << endl;
-      delete aHDFUrl;
-      char eStr[strlen(aUrl)+17];
-      sprintf(eStr,"Can't open file %s",aUrl);
-      THROW_SALOME_CORBA_EXCEPTION(CORBA::string_dup(eStr),SALOME::BAD_PARAM);
-      
-    } 
+  }catch(HDFexception){
+    std::ostringstream aStream;
+    aStream<<"Can't open file "<<theURL;
+    std::string eStr = aStream.str();
+    THROW_SALOME_CORBA_EXCEPTION(eStr.c_str(),SALOME::BAD_PARAM);
+  } 
   MESSAGE("Open : Creating the CORBA servant holding it... ");
 
   // Temporary aStudyUrl in place of study name
   Handle(TDocStd_Document) Doc;
   _OCAFApp->NewDocument("SALOME_STUDY",Doc); 
 
-  SALOMEDS_Study_i * Study_servant = new SALOMEDS_Study_i(Doc, _orb, aUrl);  
-  SALOMEDS::Study_var Study = SALOMEDS::Study::_narrow(Study_servant->_this()); 
+  SALOMEDS_Study_i* aStudyServant = new SALOMEDS_Study_i(this,Doc,theURL);  
+  SALOMEDS::Study_var aStudy = aStudyServant->_this(); 
 
-  //  Study->StudyId( _OCAFApp->NbDocuments() ); 
+  //  aStudy->StudyId( _OCAFApp->NbDocuments() ); 
   _IDcounter++;
-  Study->StudyId( _IDcounter );
+  aStudy->StudyId( _IDcounter );
 
-  // Register study in the naming service
-  // Path to acces the study
-  if(!_name_service->Change_Directory("/Study")) 
-      MESSAGE( "Unable to access the study directory" )
-  else
-    {
-      char* aPath = CORBA::string_dup(aUrl);
-      char *aName = NULL;
-      char *adr = strtok(aPath, "/");
-      while (adr)
-       {
-         aName = adr;
-         adr = strtok(NULL, "/");
-       }
-      adr = aName;
-      aName = strtok(adr, ".");
-      SCRUTE(aName);
-      _name_service->Register(Study, CORBA::string_dup(aName));
-      CORBA::string_free(aPath);
-    }
+  // Assign the value of the URL in the study object
+  aStudyServant->URL(theURL);
+  SCRUTE(theURL);
 
   // Assign the value of the IOR in the study->root
-  CORBA::String_var IORStudy = _orb->object_to_string(Study);
+  CORBA::String_var anIOR = _orb->object_to_string(aStudy);
   SALOMEDS_IORAttribute::Set(Doc->Main().Root(),
-                            TCollection_ExtendedString(CORBA::string_dup(IORStudy)),_orb);
+                            const_cast<char*>(anIOR.in()),
+                            aStudyServant);
 
-  // Assign the value of the URL in the study object
-  Study->URL (aUrl);
-  SCRUTE(aUrl);
-  SALOMEDS_PersRefAttribute::Set(Doc->Main(),strdup(aUrl)); 
+  SALOMEDS_PersRefAttribute::Set(Doc->Main(),const_cast<char*>(theURL)); 
 
   if (!hdf_file->ExistInternalObject("STUDY_STRUCTURE")) {
-    delete aHDFUrl;
     MESSAGE("SALOMEDS_StudyManager::Open : the study is empty");
-    return Study;
+    return aStudy._retn();
   }
 
   //Create  the Structure of the OCAF Document
-  hdf_group_study_structure = new HDFgroup("STUDY_STRUCTURE",hdf_file);
+  HDFgroup *hdf_group_study_structure = new HDFgroup("STUDY_STRUCTURE",hdf_file.get());
 
   Handle(TDF_Data) DF = Doc->GetData();
 
-  try {
-    BuildTree (DF,hdf_group_study_structure);
-  }
-  catch (HDFexception)
-    {
-//        MESSAGE( "HDFexception ! " );
-//        cerr << "HDFexception ! " << endl;
-      delete aHDFUrl;
-      char eStr[strlen(aUrl)+17];
-      sprintf(eStr,"Can't open file %s",aUrl);
-      THROW_SALOME_CORBA_EXCEPTION(CORBA::string_dup(eStr),SALOME::BAD_PARAM);
-    } 
+  try{
+    BuildTree(aStudyServant,hdf_group_study_structure);
+  }catch(HDFexception){
+    std::ostringstream aStream;
+    aStream<<"Can't open file "<<theURL;
+    std::string eStr = aStream.str();
+    THROW_SALOME_CORBA_EXCEPTION(eStr.c_str(),SALOME::BAD_PARAM);
+  } 
   
   hdf_file->CloseOnDisk();
 
+  // Register study in the naming service
+  // Path to acces the study
+  if(!_name_service.Change_Directory("/Study")){
+    MESSAGE( "Unable to access the study directory" );
+  }else{
+    CORBA::String_var aString(aStudyServant->Name());
+    _name_service.Register(aStudy,aString.in());
+  }
+
   if (isASCII) {
     SALOMEDS::ListOfFileNames_var aFilesToRemove = new SALOMEDS::ListOfFileNames;
     aFilesToRemove->length(1);
-    aFilesToRemove[0] = strdup(&(aHDFUrl[strlen(SALOMEDS_Tool::GetDirFromPath(aHDFUrl))]));
-    SALOMEDS_Tool::RemoveTemporaryFiles(SALOMEDS_Tool::GetDirFromPath(aHDFUrl), aFilesToRemove, true);
+    std::string aDir = SALOMEDS_Tool::GetDirFromPath(aHDFUrl);
+    aFilesToRemove[0] = CORBA::string_dup(&aHDFUrl[strlen(aDir.c_str())]);
+    SALOMEDS_Tool::RemoveTemporaryFiles(aDir,aFilesToRemove,true);
   }
-  delete aHDFUrl;
-  delete hdf_file; // all related hdf objects will be deleted
-  return Study;
+
+  return aStudy._retn();
 }
 
 
@@ -663,11 +434,15 @@ SALOMEDS::Study_ptr  SALOMEDS_StudyManager_i::Open(const char* aUrl)
 void  SALOMEDS_StudyManager_i::Close(SALOMEDS::Study_ptr aStudy)
 {
   if(aStudy->_is_nil()) return;
-    
-  // Destroy study name in the naming service
-  if(_name_service->Change_Directory("/Study")) 
-    _name_service->Destroy_Name(aStudy->Name());
   
+  aStudy->RemovePostponed(-1);
+  
+  // Destroy study name in the naming service
+  if(_name_service.Change_Directory("/Study")){
+    CORBA::String_var aString(aStudy->Name());
+    _name_service.Destroy_Name(aString.in());
+  }
+
   aStudy->Close();
 }
 
@@ -676,26 +451,24 @@ void  SALOMEDS_StudyManager_i::Close(SALOMEDS::Study_ptr aStudy)
  *  Purpose  : Save a Study to it's persistent reference
  */
 //============================================================================
-void SALOMEDS_StudyManager_i::Save(SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
+void SALOMEDS_StudyManager_i::Save(SALOMEDS::Study_ptr theStudy, CORBA::Boolean theMultiFile)
 {
-  CORBA::String_var url = aStudy->URL();
-  if (url==NULL)
-    MESSAGE( "No path specified to save the study. Nothing done")
-  else
-    {
-      _SaveAs(url,aStudy, theMultiFile, false);
-    }
+  CORBA::String_var anURL = theStudy->URL();
+  if(strcmp(anURL.in(),"") == 0){
+    MESSAGE( "No path specified to save the study. Nothing done");
+  }else{
+    _SaveAs(anURL,theStudy,theMultiFile,false);
+  }
 }
 
-void SALOMEDS_StudyManager_i::SaveASCII(SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
+void SALOMEDS_StudyManager_i::SaveASCII(SALOMEDS::Study_ptr theStudy, CORBA::Boolean theMultiFile)
 {
-  CORBA::String_var url = aStudy->URL();
-  if (url==NULL)
-    MESSAGE( "No path specified to save the study. Nothing done")
-  else
-    {
-      _SaveAs(url,aStudy, theMultiFile, true);
-    }
+  CORBA::String_var anURL = theStudy->URL();
+  if(strcmp(anURL.in(),"") == 0){
+    MESSAGE( "No path specified to save the study. Nothing done");
+  }else{
+    _SaveAs(anURL,theStudy,theMultiFile,true);
+  }
 }
 
 //=============================================================================
@@ -703,21 +476,15 @@ void SALOMEDS_StudyManager_i::SaveASCII(SALOMEDS::Study_ptr aStudy, CORBA::Boole
  *  Purpose  : Save a study to the persistent reference aUrl
  */
 //============================================================================
-void SALOMEDS_StudyManager_i::SaveAs(const char* aUrl, SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
+void SALOMEDS_StudyManager_i::SaveAs(const char* aUrl, SALOMEDS::Study_ptr theStudy, CORBA::Boolean theMultiFile)
 {
-  // Save the URL of the Study => to be used with the function "Save"
-  aStudy->URL(aUrl);
-  
-  _SaveAs(aUrl,aStudy,theMultiFile, false);
+  _SaveAs(aUrl,theStudy,theMultiFile, false);
 
 }
 
-void SALOMEDS_StudyManager_i::SaveAsASCII(const char* aUrl, SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
+void SALOMEDS_StudyManager_i::SaveAsASCII(const char* aUrl, SALOMEDS::Study_ptr theStudy, CORBA::Boolean theMultiFile)
 {
-  // Save the URL of the Study => to be used with the function "Save"
-  aStudy->URL(aUrl);
-  
-  _SaveAs(aUrl,aStudy,theMultiFile, true);
+  _SaveAs(aUrl,theStudy,theMultiFile, true);
 }
 
 //============================================================================
@@ -728,25 +495,20 @@ void SALOMEDS_StudyManager_i::SaveAsASCII(const char* aUrl, SALOMEDS::Study_ptr
 SALOMEDS::ListOfOpenStudies*  SALOMEDS_StudyManager_i::GetOpenStudies()
 {
   // MESSAGE("Begin of GetOpenStudies");
-  SALOMEDS::ListOfOpenStudies_var _list_open_studies = new SALOMEDS::ListOfOpenStudies;
-  _list_open_studies->length(0);
-  vector<string> _list ;
-
-  if(!_name_service->Change_Directory("/Study"))
-    {
-      MESSAGE("No active study in this session");
-    }
-  else
-    {
-      _list = _name_service->list_directory();
-      _list_open_studies->length(_list.size());
-      for (unsigned int ind=0; ind < _list.size();ind++)
-       {
-         _list_open_studies[ind]=CORBA::string_dup(_list[ind].c_str());
-         SCRUTE(_list_open_studies[ind]) ;
-       }
+  SALOMEDS::ListOfOpenStudies_var aStudyList = new SALOMEDS::ListOfOpenStudies;
+
+  if(!_name_service.Change_Directory("/Study")){
+    MESSAGE("No active study in this session");
+  }else{
+    vector<string> aList = _name_service.list_directory();
+    aStudyList->length(aList.size());
+    for(unsigned int ind = 0; ind < aList.size(); ind++){
+      aStudyList[ind] = CORBA::string_dup(aList[ind].c_str());
+      SCRUTE(aStudyList[ind]) ;
     }
-  return _list_open_studies._retn();
+  }
+
+  return aStudyList._retn();
 }
 
 //============================================================================
@@ -755,33 +517,25 @@ SALOMEDS::ListOfOpenStudies*  SALOMEDS_StudyManager_i::GetOpenStudies()
  */
 //============================================================================
 SALOMEDS::Study_ptr  
-SALOMEDS_StudyManager_i::GetStudyByName(const char* aStudyName) 
+SALOMEDS_StudyManager_i::GetStudyByName(const char* theStudyName) 
 {
-  SALOMEDS::Study_var Study;
+  SALOMEDS::Study_var aStudy;
 
   // Go to study directory and look for aStudyName
-  if(!_name_service->Change_Directory("/Study"))
-    {
-      MESSAGE("No active study in this session");
-      ASSERT(false); // Stop here...
-    }
+  if(!_name_service.Change_Directory("/Study")){
+    MESSAGE("No active study in this session");
+    ASSERT(false); // Stop here...
+  }
   
-//   const char *theStudyName = this->_SubstituteSlash(aStudyName);
-  const char* theStudyName = CORBA::string_dup(aStudyName);
-
-  if(_name_service->Find(theStudyName)>0)
-    {
+  if(_name_service.Find(theStudyName) > 0){
     // Study found
-    CORBA::Object_ptr obj= _name_service->Resolve(theStudyName) ;
-    Study = SALOMEDS::Study::_narrow(obj);
+    CORBA::Object_ptr anObj = _name_service.Resolve(theStudyName) ;
+    aStudy = SALOMEDS::Study::_narrow(anObj);
     MESSAGE("Study " << theStudyName << " found in the naming service");
-    }
-  else  
-    {
-      Study = SALOMEDS::Study::_narrow( CORBA::Object::_nil()); 
-      MESSAGE("Study " << theStudyName << " not found in the naming service");
-    }
-  return Study;
+  }else{
+    MESSAGE("Study " << theStudyName << " not found in the naming service");
+  }
+  return aStudy._retn();
 }
 
 //============================================================================
@@ -792,39 +546,30 @@ SALOMEDS_StudyManager_i::GetStudyByName(const char* aStudyName)
 SALOMEDS::Study_ptr  
 SALOMEDS_StudyManager_i::GetStudyByID(CORBA::Short aStudyID) 
 {
-  SALOMEDS::Study_var Study;
-  vector<string> _list ;
-
-  if(!_name_service->Change_Directory("/Study"))
-    {
-      MESSAGE("No active study in this session");
-    }
-  else
-    {
-      _list = _name_service->list_directory();
-      for (unsigned int ind=0; ind < _list.size();ind++)
-       {
-         const char* theStudyName = CORBA::string_dup(_list[ind].c_str());
-         MESSAGE ( "GetStudyByID = " << theStudyName )
-
-         if(_name_service->Find(theStudyName)>0) {
-           CORBA::Object_ptr obj= _name_service->Resolve(theStudyName) ;
-           Study = SALOMEDS::Study::_narrow(obj);
-
-           MESSAGE ( " aStudyID : " << aStudyID << "-" << Study->StudyId() )
-
-           if ( aStudyID == Study->StudyId() ) {
-             MESSAGE("Study with studyID = " << aStudyID << " found in the naming service");
-             return Study;
-           }
-         } else {
-           Study = SALOMEDS::Study::_narrow( CORBA::Object::_nil()); 
-           MESSAGE("Study " << theStudyName << " not found in the naming service");
-         }
+  SALOMEDS::Study_var aStudy;
+
+  if(!_name_service.Change_Directory("/Study")){
+    MESSAGE("No active study in this session");
+  }else{
+    vector<string> aList = _name_service.list_directory();
+    for(unsigned int ind = 0; ind < aList.size(); ind++){
+      const char* aStudyName = aList[ind].c_str();
+      MESSAGE( "GetStudyByID = " << aStudyName );
+      if(_name_service.Find(aStudyName) > 0){
+       CORBA::Object_ptr anObj = _name_service.Resolve(aStudyName) ;
+       aStudy = SALOMEDS::Study::_narrow(anObj);
+       MESSAGE( " aStudyID : " << aStudyID << "-" << aStudy->StudyId() );
+       if(aStudyID == aStudy->StudyId()){
+         MESSAGE("Study with studyID = " << aStudyID << " found in the naming service");
+         return aStudy._retn();
        }
-      Study = SALOMEDS::Study::_narrow( CORBA::Object::_nil()); 
+      }else{
+       MESSAGE("Study " << aStudyName << " not found in the naming service");
+      }
     }
-  return Study;
+  }
+  
+  return aStudy._retn();
 }
 //============================================================================
 /*! Function : SaveAttributes
@@ -832,369 +577,33 @@ SALOMEDS_StudyManager_i::GetStudyByID(CORBA::Short aStudyID)
  */
 //============================================================================
 static void SaveAttributes(SALOMEDS::SObject_ptr SO, HDFgroup *hdf_group_sobject) {
-  HDFdataset *hdf_dataset = 0;
+  int a;
   hdf_size size[1];
-  hdf_int32 name_len = 0;
-  SALOMEDS::GenericAttribute_var SObj;
-  if(SO->FindAttribute(SObj, "AttributeComment"))
-    {
-      SALOMEDS::AttributeComment_var Comment = SALOMEDS::AttributeComment::_narrow(SObj);
-        CORBA::String_var Val = Comment->Value();
-        name_len = (hdf_int32) strlen(Val);
-        size[0] = name_len +1 ; 
-        hdf_dataset = new HDFdataset("AttributeComment",hdf_group_sobject,HDF_STRING,size,1);
-        hdf_dataset->CreateOnDisk();
-        hdf_dataset->WriteOnDisk(Val);
-        MESSAGE("attribute comment " <<  Val << " wrote on file");
-        hdf_dataset->CloseOnDisk();
-        hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-      }
-  // Attribute  SALOMEDS::PersistentRef
-  if(SO->FindAttribute(SObj, "AttributePersistentRef"))
-    {
-      SALOMEDS::AttributePersistentRef_var PersRef = SALOMEDS::AttributePersistentRef::_narrow(SObj);
-        CORBA::String_var Val = PersRef->Value();
-        name_len = (hdf_int32) strlen(Val);
-        size[0] = name_len +1 ; 
-        hdf_dataset = new HDFdataset("AttributePersistentRef",hdf_group_sobject,HDF_STRING,size,1);
-        hdf_dataset->CreateOnDisk();
-        hdf_dataset->WriteOnDisk(Val);
-        MESSAGE("attribute persistentref " <<  Val << " wrote on file");
-        hdf_dataset->CloseOnDisk();
-        hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-      }
-  // Attribute  SALOMEDS::Name
-  if(SO->FindAttribute(SObj, "AttributeName"))
-    {
-      SALOMEDS::AttributeName_var NameRef = SALOMEDS::AttributeName::_narrow(SObj);
-        CORBA::String_var Val = NameRef->Value();
-        name_len = (hdf_int32) strlen(Val);
-        size[0] = name_len +1 ; 
-        hdf_dataset = new HDFdataset("AttributeName",hdf_group_sobject,HDF_STRING,size,1);
-        hdf_dataset->CreateOnDisk();
-        hdf_dataset->WriteOnDisk(Val);
-        MESSAGE("attribute name " <<  Val << " wrote on file");
-        hdf_dataset->CloseOnDisk();
-        hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-      }
-  if(SO->FindAttribute(SObj, "AttributeReal"))
-    {
-      char RealVal[25];
-      SALOMEDS::AttributeReal_var RealRef = SALOMEDS::AttributeReal::_narrow(SObj);
-      sprintf(RealVal, "%f", RealRef->Value());
-      name_len = (hdf_int32) strlen(RealVal);
-      size[0] = name_len +1 ; 
-      hdf_dataset = new HDFdataset("AttributeReal",hdf_group_sobject,HDF_STRING,size,1);
-      hdf_dataset->CreateOnDisk();
-      hdf_dataset->WriteOnDisk(RealVal);
-      MESSAGE("attribute Real " <<  RealVal << " wrote on file");
-      hdf_dataset->CloseOnDisk();
-      hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-    }
-  if(SO->FindAttribute(SObj, "AttributeInteger"))
-    {
-      char IntVal[25];
-      SALOMEDS::AttributeInteger_var IntRef = SALOMEDS::AttributeInteger::_narrow(SObj);
-      sprintf(IntVal, "%d", IntRef->Value());
-      name_len = (hdf_int32) strlen(IntVal);
-      size[0] = name_len +1 ; 
-      hdf_dataset = new HDFdataset("AttributeInteger",hdf_group_sobject,HDF_STRING,size,1);
-      hdf_dataset->CreateOnDisk();
-      hdf_dataset->WriteOnDisk(IntVal);
-      MESSAGE("attribute Real " <<  IntVal << " wrote on file");
-      hdf_dataset->CloseOnDisk();
-      hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-    }    
-  
-  if(SO->FindAttribute(SObj, "AttributeSequenceOfReal"))
-    {
-      SALOMEDS::AttributeSequenceOfReal_var RealSeq = SALOMEDS::AttributeSequenceOfReal::_narrow(SObj);
-        size[0] = RealSeq->Length();
-        SALOMEDS::DoubleSeq_var DS = RealSeq->CorbaSequence();
-        hdf_dataset = new HDFdataset("AttributeSequenceOfReal",hdf_group_sobject,HDF_FLOAT64,size,1);
-        hdf_dataset->CreateOnDisk();
-        hdf_float64 *data = new hdf_float64[RealSeq->Length()];
-        for (Standard_Integer i = 0; i < RealSeq->Length(); i++) {
-          MESSAGE("Value =  " << i << " = " << DS[i]  << " wrote on file");
-          data[i] = DS[i];
-        }
-        hdf_dataset->WriteOnDisk(data);
-        //               delete data;
-        hdf_dataset->CloseOnDisk();
-        hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-      }
-  if(SO->FindAttribute(SObj, "AttributeSequenceOfInteger"))
-    {
-      SALOMEDS::AttributeSequenceOfInteger_var IntSeq = SALOMEDS::AttributeSequenceOfInteger::_narrow(SObj);
-        size[0] = IntSeq->Length();
-        SALOMEDS::LongSeq_var LS = IntSeq->CorbaSequence();
-        hdf_dataset = new HDFdataset("AttributeSequenceOfInteger",hdf_group_sobject,HDF_INT32,size,1);
-        hdf_dataset->CreateOnDisk();
-        hdf_int32 *data = new hdf_int32[IntSeq->Length()];
-        for (Standard_Integer i = 0; i < IntSeq->Length(); i++) {
-          MESSAGE("Value =  " << i << " = " << LS[i]  << " wrote on file");
-          data[i] = LS[i];
-        }
-        hdf_dataset->WriteOnDisk(data);
-        hdf_dataset->CloseOnDisk();
-        //               delete data;
-        hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-      }
-    if(SO->FindAttribute(SObj, "AttributeDrawable"))
-    {
-      char IntVal[25];
-      SALOMEDS::AttributeDrawable_var DrRef = SALOMEDS::AttributeDrawable::_narrow(SObj);
-      sprintf(IntVal, "%d", DrRef->IsDrawable());
-      name_len = (hdf_int32) strlen(IntVal);
-      size[0] = name_len +1 ; 
-      hdf_dataset = new HDFdataset("AttributeDrawable",hdf_group_sobject,HDF_STRING,size,1);
-      hdf_dataset->CreateOnDisk();
-      hdf_dataset->WriteOnDisk(IntVal);
-      MESSAGE("attribute Drawable " <<  IntVal << " wrote on file");
-      hdf_dataset->CloseOnDisk();
-      hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-    }    
-  if(SO->FindAttribute(SObj, "AttributeSelectable"))
-    {
-      char IntVal[25];
-      SALOMEDS::AttributeSelectable_var SelRef = SALOMEDS::AttributeSelectable::_narrow(SObj);
-      sprintf(IntVal, "%d", SelRef->IsSelectable());
-      name_len = (hdf_int32) strlen(IntVal);
-      size[0] = name_len +1 ; 
-      hdf_dataset = new HDFdataset("AttributeSelectable",hdf_group_sobject,HDF_STRING,size,1);
-      hdf_dataset->CreateOnDisk();
-      hdf_dataset->WriteOnDisk(IntVal);
-      MESSAGE("attribute Selectable " <<  IntVal << " wrote on file");
-      hdf_dataset->CloseOnDisk();
-      hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-    }    
-  if(SO->FindAttribute(SObj, "AttributeExpandable"))
-    {
-      char IntVal[25];
-      SALOMEDS::AttributeExpandable_var ExRef = SALOMEDS::AttributeExpandable::_narrow(SObj);
-      sprintf(IntVal, "%d", ExRef->IsExpandable());
-      name_len = (hdf_int32) strlen(IntVal);
-      size[0] = name_len +1 ; 
-      hdf_dataset = new HDFdataset("AttributeExpandable",hdf_group_sobject,HDF_STRING,size,1);
-      hdf_dataset->CreateOnDisk();
-      hdf_dataset->WriteOnDisk(IntVal);
-      MESSAGE("attribute Expandable " <<  IntVal << " wrote on file");
-      hdf_dataset->CloseOnDisk();
-      hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-    }    
-  if(SO->FindAttribute(SObj, "AttributeOpened"))
-    {
-      char IntVal[25];
-      SALOMEDS::AttributeOpened_var OpRef = SALOMEDS::AttributeOpened::_narrow(SObj);
-      sprintf(IntVal, "%d", OpRef->IsOpened());
-      name_len = (hdf_int32) strlen(IntVal);
-      size[0] = name_len +1 ; 
-      hdf_dataset = new HDFdataset("AttributeOpened",hdf_group_sobject,HDF_STRING,size,1);
-      hdf_dataset->CreateOnDisk();
-      hdf_dataset->WriteOnDisk(IntVal);
-      MESSAGE("attribute Opened " <<  IntVal << " wrote on file");
-      hdf_dataset->CloseOnDisk();
-      hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-    }    
-  if(SO->FindAttribute(SObj, "AttributeTextColor"))
-    {
-      SALOMEDS::AttributeTextColor_var TextRef = SALOMEDS::AttributeTextColor::_narrow(SObj);
-      size[0] = 3;
-      hdf_float64 data[3];
-      SALOMEDS::Color C = TextRef->TextColor();
-      data[0] = C.R;
-      data[1] = C.G;
-      data[2] = C.B;
-      hdf_dataset = new HDFdataset("AttributeTextColor",hdf_group_sobject,HDF_FLOAT64,size,1);
-      hdf_dataset->CreateOnDisk();
-      hdf_dataset->WriteOnDisk(data);
-      MESSAGE("attribute  AttributeTextColor wrote on file");
-      hdf_dataset->CloseOnDisk();
-      hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-    }    
-    if(SO->FindAttribute(SObj, "AttributeTextHighlightColor"))
-    {
-      SALOMEDS::AttributeTextHighlightColor_var TextRef = SALOMEDS::AttributeTextHighlightColor::_narrow(SObj);
-      size[0] = 3;
-      hdf_float64 data[3];
-      SALOMEDS::Color C = TextRef->TextHighlightColor();
-      data[0] = C.R;
-      data[1] = C.G;
-      data[2] = C.B;
-      hdf_dataset = new HDFdataset("AttributeTextHighlightColor",hdf_group_sobject,HDF_FLOAT64,size,1);
-      hdf_dataset->CreateOnDisk();
-      hdf_dataset->WriteOnDisk(data);
-      MESSAGE("attribute  AttributeTextHighlightColor wrote on file");
-      hdf_dataset->CloseOnDisk();
-      hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-    }    
-  if(SO->FindAttribute(SObj, "AttributePixMap"))
-    {
-      SALOMEDS::AttributePixMap_var PMRef = SALOMEDS::AttributePixMap::_narrow(SObj);
-      if (PMRef->HasPixMap()) {
-       CORBA::String_var Val = PMRef->GetPixMap();
-       name_len = (hdf_int32) strlen(Val);
-       size[0] = name_len +1 ; 
-       hdf_dataset = new HDFdataset("AttributePixMap",hdf_group_sobject,HDF_STRING,size,1);
-       hdf_dataset->CreateOnDisk();
-       hdf_dataset->WriteOnDisk(Val);
-          MESSAGE("attribute PixMap " <<  Val << " wrote on file");
-       hdf_dataset->CloseOnDisk();
-       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-      }
-    }
-  if(SO->FindAttribute(SObj, "AttributeLocalID"))
-    {
-      char IntVal[25];
-      SALOMEDS::AttributeLocalID_var LIDRef = SALOMEDS::AttributeLocalID::_narrow(SObj);
-      sprintf(IntVal, "%d", LIDRef->Value());
-      name_len = (hdf_int32) strlen(IntVal);
-      size[0] = name_len +1 ; 
-      hdf_dataset = new HDFdataset("AttributeLocalID",hdf_group_sobject,HDF_STRING,size,1);
-      hdf_dataset->CreateOnDisk();
-      hdf_dataset->WriteOnDisk(IntVal);
-      hdf_dataset->CloseOnDisk();
-      hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-      MESSAGE("attribute  AttributeLocalID wrote on file");
-    }    
-  if(SO->FindAttribute(SObj, "AttributeTableOfInteger"))
-    {
-      SALOMEDS::AttributeTableOfInteger_var IntTab = SALOMEDS::AttributeTableOfInteger::_narrow(SObj);
-      SALOMEDS::TMPFile_var aStream = IntTab->SaveToFile();
-      
-      hdf_size aHDFSize[1];
-      aHDFSize[0] = aStream->length();
-      
-      HDFdataset *hdf_dataset = new HDFdataset("AttributeTableOfInteger",hdf_group_sobject, HDF_STRING, aHDFSize, 1);
-      hdf_dataset->CreateOnDisk();
-      hdf_dataset->WriteOnDisk((unsigned char*) &aStream[0]);  //Save the stream in the HDF file
-      hdf_dataset->CloseOnDisk();
-      hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-      
-      MESSAGE("attribute  AttributeTableOfInteger wrote on file");
-    }
-  if(SO->FindAttribute(SObj, "AttributeTableOfReal"))
-    {
-      SALOMEDS::AttributeTableOfReal_var RealTab = SALOMEDS::AttributeTableOfReal::_narrow(SObj);
-      SALOMEDS::TMPFile_var aStream = RealTab->SaveToFile();
-      
-      hdf_size aHDFSize[1];
-      aHDFSize[0] = aStream->length();
-      
-      HDFdataset *hdf_dataset = new HDFdataset("AttributeTableOfReal",hdf_group_sobject, HDF_STRING, aHDFSize, 1);
-      hdf_dataset->CreateOnDisk();
-      hdf_dataset->WriteOnDisk((unsigned char*) &aStream[0]);  //Save the stream in the HDF file
-      hdf_dataset->CloseOnDisk();
-      hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-
-      MESSAGE("attribute  AttributeTableOfReal wrote on file")
-    }
-  if(SO->FindAttribute(SObj, "AttributeTableOfString"))
-    {
-      SALOMEDS::AttributeTableOfString_var StrTab = SALOMEDS::AttributeTableOfString::_narrow(SObj);
-      SALOMEDS::TMPFile_var aStream = StrTab->SaveToFile();
-      
-      hdf_size aHDFSize[1];
-      aHDFSize[0] = aStream->length();
-      
-      HDFdataset *hdf_dataset = new HDFdataset("AttributeTableOfString",hdf_group_sobject, HDF_STRING, aHDFSize, 1);
-      hdf_dataset->CreateOnDisk();
-      hdf_dataset->WriteOnDisk((unsigned char*) &aStream[0]);  //Save the stream in the HDF file
-      hdf_dataset->CloseOnDisk();
-      hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-
-      MESSAGE("attribute  AttributeTableOfString wrote on file")
-    }
-  if(SO->FindAttribute(SObj, "AttributePythonObject"))
-    {
-      SALOMEDS::AttributePythonObject_var anObj = SALOMEDS::AttributePythonObject::_narrow(SObj);
-      char* aSeq = CORBA::string_dup(anObj->GetObject());
-      int aLen = strlen(aSeq);
-      char* aString = new char[aLen+2];
-      aString[0] = anObj->IsScript()?'s':'n';
-      for(int i = 0; i < aLen; i++) aString[i+1] = aSeq[i];
-      aString[aLen+1] = 0;
-      size[0] = aLen+2 ; 
-      hdf_dataset = new HDFdataset("AttributePythonObject",hdf_group_sobject,HDF_STRING,size,1);
-      hdf_dataset->CreateOnDisk();
-      hdf_dataset->WriteOnDisk(aString);
-      hdf_dataset->CloseOnDisk();
-      hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-      MESSAGE("attribute  AttributePythonObject wrote on file");
-    }    
-
-// Reference
-  SALOMEDS::SObject_var RefSO;
-  if(SO->ReferencedObject(RefSO))
-    {
-      CORBA::String_var attribute_reference = strdup(RefSO->GetID());
-      name_len = (hdf_int32) strlen(attribute_reference);
-      size[0] = name_len +1 ; 
-      hdf_dataset = new HDFdataset("Reference",hdf_group_sobject,HDF_STRING,size,1);
-      hdf_dataset->CreateOnDisk();
-      hdf_dataset->WriteOnDisk(attribute_reference);
-      MESSAGE("attribute reference " <<  attribute_reference << " wrote on file");
-      hdf_dataset->CloseOnDisk();
-      hdf_dataset =0; // will be deleted by father hdf object destructor
-    }
-
-// TreeNodeAttributes with not constant GUID
   SALOMEDS::ListOfAttributes_var anAttrList = SO->GetAllAttributes();
-  int anIndex, aLength = anAttrList->length();
-  for(anIndex = 0; anIndex<aLength; anIndex++) {
-    SALOMEDS::AttributeUserID_var UAttr = SALOMEDS::AttributeUserID::_narrow(anAttrList[anIndex]);
-    if (!UAttr->_is_nil()) {
-      char* Val = UAttr->Value();
-      name_len = (hdf_int32) strlen(Val);
-      size[0] = name_len + 1;
-      char* aDataSetName = new char[60];
-      sprintf(aDataSetName, "AttributeUserID_%s",Val);
-      hdf_dataset = new HDFdataset(aDataSetName,hdf_group_sobject,HDF_STRING,size,1);
-      hdf_dataset->CreateOnDisk();
-      hdf_dataset->WriteOnDisk(Val);
-      MESSAGE("attribute UesrID " <<  Val << " wrote on file");
-      hdf_dataset->CloseOnDisk();
-      hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-      delete(aDataSetName);
-      continue;
-    }
+  for(a = anAttrList->length() - 1; a >= 0; a--) {
+    if (strcmp(anAttrList[a]->Type(), "AttributeIOR") == 0) continue; // never write AttributeIOR to file
+    if (strcmp(anAttrList[a]->Type(), "AttributeExternalFileDef") == 0) continue; // never write ExternalFileDef to file
+    if (strcmp(anAttrList[a]->Type(), "AttributeFileType") == 0) continue; // never write FileType to file
+    CORBA::String_var aSaveStr(anAttrList[a]->Store());
+    size[0] = (hdf_int32) strlen(aSaveStr.in()) + 1;
+    HDFdataset *hdf_dataset = new HDFdataset(anAttrList[a]->Type(),hdf_group_sobject,HDF_STRING,size,1);
+    hdf_dataset->CreateOnDisk();
+    hdf_dataset->WriteOnDisk(aSaveStr);
+    hdf_dataset->CloseOnDisk();
+    //cout<<"********** Write Attribute "<<anAttrList[a]->Type()<<" : "<<aSaveStr<<" done"<<endl;
+    hdf_dataset = 0; //will be deleted by hdf_sco_group destructor
+  }
 
-    SALOMEDS::AttributeTreeNode_var TNRef = SALOMEDS::AttributeTreeNode::_narrow(anAttrList[anIndex]);
-    if (!TNRef->_is_nil()) {
-      hdf_size TNsize[2];
-      int maxSize,index;
-      CORBA::String_var Val[5];
-      
-      if (TNRef->HasFather()) Val[0] = TNRef->GetFather()->Label(); else Val[0] = "\0";
-      maxSize = strlen(Val[0]);
-      if (TNRef->HasPrevious()) Val[1] = TNRef->GetPrevious()->Label(); else Val[1] = "\0";
-      maxSize = Max(maxSize,strlen(Val[1]));
-      if (TNRef->HasNext()) Val[2] = TNRef->GetNext()->Label(); else Val[2] = "\0";
-      maxSize = Max(maxSize,strlen(Val[2]));
-      if (TNRef->HasFirst()) Val[3] = TNRef->GetFirst()->Label(); else Val[3] = "\0";
-      maxSize = Max(maxSize,strlen(Val[3]));
-      Val[4] = TNRef->GetTreeID();
-      maxSize = Max(maxSize,strlen(Val[4]));
-      
-      TNsize[0]=5;
-      TNsize[1]=maxSize+1;
-      char Data[5][maxSize+1];
-      for(index=0;index<5;index++) {
-       strcpy(Data[index],Val[index]);
-       for(int a = strlen(Data[index]) + 1; a < maxSize; a++) Data[index][a] = ' '; // mpv: for ASCII format
-      }
-      
-      char* aDataSetName = new char[60];
-      sprintf(aDataSetName, "AttributeTreeNodeGUID%s",TNRef->GetTreeID());
-      hdf_dataset = new HDFdataset(aDataSetName,hdf_group_sobject,HDF_STRING,TNsize,2);
-      hdf_dataset->CreateOnDisk();
-      hdf_dataset->WriteOnDisk(Data);
-      hdf_dataset->CloseOnDisk();
-      hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-      MESSAGE("attribute AttributeTreeNode with various GUID wrote on file:");
-      MESSAGE(aDataSetName);
-      delete(aDataSetName);
-    }
+  // Reference attribute has no CORBA attribute representation, so, GetAllAttributes can not return this attribute
+  SALOMEDS::SObject_var RefSO;
+  if(SO->ReferencedObject(RefSO)) {
+    CORBA::String_var attribute_reference(RefSO->GetID());
+    size[0] = strlen(attribute_reference) + 1 ; 
+    HDFdataset *hdf_dataset = new HDFdataset("Reference",hdf_group_sobject,HDF_STRING,size,1);
+    hdf_dataset->CreateOnDisk();
+    hdf_dataset->WriteOnDisk(attribute_reference);
+    hdf_dataset->CloseOnDisk();
+    hdf_dataset = 0; // will be deleted by father hdf object destructor
   }
 }
 
@@ -1203,64 +612,51 @@ static void SaveAttributes(SALOMEDS::SObject_ptr SO, HDFgroup *hdf_group_sobject
  *  Purpose  : save the study properties in HDF file
  */
 //============================================================================
-void SALOMEDS_StudyManager_i::_SaveProperties(SALOMEDS::Study_ptr aStudy, HDFgroup *hdf_group) {
-  HDFdataset *hdf_dataset = 0;
-  hdf_size size[1];
-  hdf_int32 name_len;
-
+void SALOMEDS_StudyManager_i::_SaveProperties(SALOMEDS_Study_i* theStudy, HDFgroup *hdf_group) 
+{
   // add modifications list (user and date of save)
-  SALOMEDS::AttributeStudyProperties_ptr aProp = aStudy->GetProperties();
-  SALOMEDS::StudyBuilder_var SB= aStudy->NewBuilder();
-//    SB->NewCommand();
+  SALOMEDS::AttributeStudyProperties_ptr aProp = theStudy->GetProperties();
   int aLocked = aProp->IsLocked();
-  if (aLocked) aProp->SetLocked(Standard_False);
+  if (aLocked) 
+    aProp->SetLocked(Standard_False);
   OSD_Process aProcess;
   Quantity_Date aDate = aProcess.SystemDate();
   aProp->SetModification(aProcess.UserName().ToCString(),
-                        CORBA::Long(aDate.Minute()), CORBA::Long(aDate.Hour()), CORBA::Long(aDate.Day()),
-                        CORBA::Long(aDate.Month()), CORBA::Long(aDate.Year()));
-  if (aLocked) aProp->SetLocked(Standard_True);
-//    SB->CommitCommand();
-  
+                        CORBA::Long(aDate.Minute()), 
+                        CORBA::Long(aDate.Hour()), 
+                        CORBA::Long(aDate.Day()),
+                        CORBA::Long(aDate.Month()), 
+                        CORBA::Long(aDate.Year()));
+  if(aLocked) 
+    aProp->SetLocked(Standard_True);
 
   SALOMEDS::StringSeq_var aNames;
   SALOMEDS::LongSeq_var aMinutes, aHours, aDays, aMonths, aYears;
-  aProp->GetModificationsList(aNames , aMinutes ,aHours, aDays, aMonths, aYears, true);
-  int aLength, anIndex;
-  for(aLength = 0, anIndex = aNames->length() - 1; anIndex >= 0; anIndex--) aLength += strlen(aNames[anIndex]) + 1;
-
-  // string length: 1 byte = locked flag, 1 byte = modified flag, (12 + name length + 1) for each name and date, "zero" byte
-  char* aProperty = new char[3 + aLength + 12 * aNames->length()];
-
-  sprintf(aProperty,"%c%c",
-         (strlen(aProp->GetCreationMode()) != 0)?aProp->GetCreationMode()[0]:'0',
-         (aProp->IsLocked())?'l':'u');
-
-  aLength = aNames->length();
-  int a = 2;
-  for(anIndex = 0; anIndex  < aLength; anIndex++) {
-    sprintf(&(aProperty[a]),"%2d%2d%2d%2d%4d%s",
-           (int)(aMinutes[anIndex]),
-           (int)(aHours[anIndex]),
-           (int)(aDays[anIndex]),
-           (int)(aMonths[anIndex]),
-           (int)(aYears[anIndex]),
-           (char*)aNames[anIndex]);
-    a = strlen(aProperty);
-    aProperty[a++] = 1;
+  aProp->GetModificationsList(aNames,aMinutes,aHours,aDays,aMonths,aYears,true);
+
+  std::ostringstream aPropertyList;
+  aPropertyList<<(strlen(aProp->GetCreationMode()) != 0? aProp->GetCreationMode()[0] : '0');
+  aPropertyList<<(aProp->IsLocked()? 'l': 'u');
+
+  int aLength = aNames->length();
+  for(int anIndex = 0; anIndex  < aLength; anIndex++) {
+    aPropertyList<<std::setw(2)<<aMinutes[anIndex];
+    aPropertyList<<std::setw(2)<<aHours[anIndex];
+    aPropertyList<<std::setw(2)<<aDays[anIndex];
+    aPropertyList<<std::setw(2)<<aMonths[anIndex];
+    aPropertyList<<std::setw(4)<<aYears[anIndex];
+    aPropertyList<<aNames[anIndex];
+    aPropertyList<<char(0x1);
   }
-  aProperty[a] = 0;
+  std::string aProperty = aPropertyList.str();
 
-  name_len = (hdf_int32) a;
-//    MESSAGE("*** Property: "<<aProperty);
-  size[0] = name_len + 1 ; 
-  hdf_dataset = new HDFdataset("AttributeStudyProperties",hdf_group,HDF_STRING,size,1);
+  hdf_size size[] = {aProperty.size() + 1};
+  HDFdataset *hdf_dataset = new HDFdataset("AttributeStudyProperties",hdf_group,HDF_STRING,size,1);
   hdf_dataset->CreateOnDisk();
-  hdf_dataset->WriteOnDisk(aProperty);
+  hdf_dataset->WriteOnDisk(const_cast<char*>(aProperty.c_str()));
   MESSAGE("attribute StudyProperties " <<  aProperty << " wrote on file");
   hdf_dataset->CloseOnDisk();
-  hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-  delete(aProperty);
+  hdf_dataset = 0; //will be deleted by hdf_sco_group destructor
   aProp->SetModified(0);
 }
 
@@ -1270,7 +666,7 @@ void SALOMEDS_StudyManager_i::_SaveProperties(SALOMEDS::Study_ptr aStudy, HDFgro
  */
 //============================================================================
 void SALOMEDS_StudyManager_i::_SaveAs(const char* aUrl, 
-                                     SALOMEDS::Study_ptr aStudy,
+                                     SALOMEDS::Study_ptr theStudy,
                                      CORBA::Boolean theMultiFile,
                                      CORBA::Boolean theASCII)
 {
@@ -1280,31 +676,70 @@ void SALOMEDS_StudyManager_i::_SaveAs(const char* aUrl,
   // * Study Structure -> Exactly what is contained in OCAF document
   //   Informations in data group hdf_group_study_structure
 
-  HDFfile *hdf_file=0;         
-  HDFgroup *hdf_group_study_structure =0;
-  HDFgroup *hdf_sco_group =0;
-  HDFgroup *hdf_sco_group2 =0;
-
-  HDFgroup *hdf_group_datacomponent =0;
-  HDFdataset *hdf_dataset =0;
-  HDFattribute *hdf_attribute=0;
-  hdf_size size[1];
-  hdf_int32 name_len = 0;
-  char *component_name = 0;
-  char *attribute_name = 0;
-  char *attribute_comment = 0;
-  char *attribute_persistentref = 0;
-
-  int aLocked = aStudy->GetProperties()->IsLocked();
-  if (aLocked) aStudy->GetProperties()->SetLocked(false);
+  if(SALOMEDS_Study_i* aStudy = DownCast(theStudy)){
+    HDFfile *hdf_file=0;         
+    HDFgroup *hdf_group_study_structure =0;
+    HDFgroup *hdf_sco_group =0;
+    HDFgroup *hdf_sco_group2 =0;
 
-  SALOMEDS::StudyBuilder_var SB= aStudy->NewBuilder();
+    HDFgroup *hdf_group_datacomponent =0;
+    HDFdataset *hdf_dataset =0;
+    hdf_size size[1];
+    hdf_int32 name_len = 0;
+  
+    int aLocked = aStudy->GetProperties()->IsLocked();
+    if(aLocked) 
+      aStudy->GetProperties()->SetLocked(false);
+
+    SALOMEDS_StudyBuilder_i* SB= aStudy->GetBuilder();
+    try{
+      // mpv 15.12.2003: for saving components we have to load all data from all modules
+      SALOMEDS_SComponentIterator_i aComponentIter = aStudy->GetComponentIterator();
+      for(; aComponentIter.More(); aComponentIter.Next()){
+       SALOMEDS::SComponent_var sco = aComponentIter.Value();
+       // if there is an associated Engine call its method for saving
+       CORBA::String_var IOREngine;
+       try{
+         if(!sco->ComponentIOR(IOREngine)){
+           SALOMEDS::GenericAttribute_var aGeneric;
+           SALOMEDS::AttributeName_var aName;
+           if(sco->FindAttribute(aGeneric, "AttributeName"))
+             aName = SALOMEDS::AttributeName::_narrow(aGeneric);
+           
+           if(!aName->_is_nil()){
+             CORBA::String_var aCompType = aName->Value();
+
+             CORBA::String_var aFactoryType;
+             if(strcmp(aCompType, "SUPERV") == 0) 
+               aFactoryType = "SuperVisionContainer";
+             else
+               aFactoryType = "FactoryServer";
+             
+             Engines::Component_var aComp =
+               SALOME_LifeCycleCORBA(&_name_service).FindOrLoad_Component(aFactoryType, aCompType);
+               
+             if(aComp->_is_nil()){
+               Engines::Component_var aComp =
+                 SALOME_LifeCycleCORBA(&_name_service).FindOrLoad_Component("FactoryServerPy", aCompType);
+             }
+               
+             if(!aComp->_is_nil()){
+               SALOMEDS::Driver_var aDriver = SALOMEDS::Driver::_narrow(aComp);
+               if (!CORBA::is_nil(aDriver)) {
+                 SB->LoadWith(sco, aDriver);
+               }
+             }
+           }
+         }
+       }catch(...){
+         MESSAGE("Can not restore information to resave it");
+         return;
+       }
+      }
 
-  aStudy->URL(aUrl);
+      CORBA::String_var anOldName = aStudy->Name();
+      aStudy->URL(aUrl);
 
-  ASSERT(!CORBA::is_nil(aStudy));
-  try
-    {
       // To change for Save 
       // Do not have to do a new file but just a Open??? Rewrite all informations after erasing evrything??
       hdf_file = new HDFfile((char *)aUrl);
@@ -1317,76 +752,112 @@ void SALOMEDS_StudyManager_i::_SaveAs(const char* aUrl,
       hdf_group_datacomponent = new HDFgroup("DATACOMPONENT",hdf_file);
       hdf_group_datacomponent->CreateOnDisk();
 
-      SALOMEDS::SComponentIterator_var itcomponent = aStudy->NewComponentIterator();
+      //SRN: Added 17 Nov, 2003
+      SALOMEDS::SObject_var anAutoSaveSO = aStudy->FindObjectID(AUTO_SAVE_TAG);
+      //SRN: End
 
-      for (; itcomponent->More(); itcomponent->Next())
-       {
-         SALOMEDS::SComponent_var sco = itcomponent->Value();
+      aComponentIter.Init();
+      for(; aComponentIter.More(); aComponentIter.Next()){
+       SALOMEDS::SComponent_var sco = aComponentIter.Value();
          
-         CORBA::String_var scoid = sco->GetID();
-         hdf_sco_group = new HDFgroup(scoid,hdf_group_datacomponent);
-         hdf_sco_group->CreateOnDisk();
-
-         CORBA::String_var componentDataType = sco->ComponentDataType();
-         MESSAGE ( "Look for  an engine for data type :"<< componentDataType);
-         // if there is an associated Engine call its method for saving
-         CORBA::String_var IOREngine;
-         if (sco->ComponentIOR(IOREngine))
-           {
-             // we have found the associated engine to write the data 
-             MESSAGE ( "We have found an engine for data type :"<< componentDataType);
-             CORBA::Object_var obj = _orb->string_to_object(IOREngine);
-             SALOMEDS::Driver_var Engine = SALOMEDS::Driver::_narrow(obj) ;
+       CORBA::String_var scoid = sco->GetID();
+       hdf_sco_group = new HDFgroup(scoid,hdf_group_datacomponent);
+       hdf_sco_group->CreateOnDisk();
+       
+       CORBA::String_var componentDataType = sco->ComponentDataType();
+       MESSAGE ( "Look for  an engine for data type :"<< componentDataType);
+       
+       //SRN: Added 17 Nov 2003: If there is a specified attribute, the component peforms a special save         
+       if(!CORBA::is_nil(anAutoSaveSO) && SB->IsGUID(sco, AUTO_SAVE_GUID)){        
+         SALOMEDS::GenericAttribute_var aGeneric;
+         SALOMEDS::AttributeTableOfString_var aTable;
+         if(anAutoSaveSO->FindAttribute(aGeneric, "AttributeTableOfString")){
+           aTable = SALOMEDS::AttributeTableOfString::_narrow(aGeneric);
+           Standard_Integer nbRows = aTable->GetNbRows(), k, aTimeOut = 0;
+           if(nbRows > 0 && aTable->GetNbColumns() > 1) {      
+             SALOMEDS::StringSeq_var aRow;
+             for(k=1; k<=nbRows; k++){
+               aRow = aTable->GetRow(k);
+               if(strcmp(aRow[0], componentDataType) == 0){
+                 CORBA::String_var anEntry = CORBA::string_dup(aRow[1]);
+                 SALOMEDS::SObject_var aCompSpecificSO = aStudy->FindObjectID(anEntry);
+                 if(!CORBA::is_nil(aCompSpecificSO)) {
+                   SALOMEDS::AttributeInteger_var anInteger;
+                   if(aCompSpecificSO->FindAttribute(aGeneric, "AttributeInteger")) {
+                     anInteger = SALOMEDS::AttributeInteger::_narrow(aGeneric);
+                     anInteger->SetValue(-1);
+                     while(anInteger->Value() < 0) { sleep(2); if(++aTimeOut > AUTO_SAVE_TIME_OUT_IN_SECONDS) break; }
+                   }  // if(aCompSpecificSO->FindAttribute(anInteger, "AttributeInteger"))
+                 }  // if(!CORBA::is_nil(aCompSpecificSO)) 
+               }  // if (strcmp(aRow[0], componentDataType) == 0)
+             }  // for
              
-             if (!CORBA::is_nil(Engine))
-               {
-                 MESSAGE ( "Save the data of type:"<< componentDataType);
-                 MESSAGE("Engine :"<<Engine->ComponentDataType());
-
-                 SALOMEDS::TMPFile_var aStream;
-                  if (theASCII) aStream = Engine->SaveASCII(sco,SALOMEDS_Tool::GetDirFromPath(aUrl),theMultiFile);
-                 else aStream = Engine->Save(sco,SALOMEDS_Tool::GetDirFromPath(aUrl),theMultiFile);
-
-                 HDFdataset *hdf_dataset;
-                 hdf_size aHDFSize[1];
-                 if(aStream->length() > 0) {  //The component saved some auxiliary files, then put them into HDF file 
-
-                   aHDFSize[0] = aStream->length();
-                     
-                   HDFdataset *hdf_dataset = new HDFdataset("FILE_STREAM", hdf_sco_group, HDF_STRING, aHDFSize, 1);
-                   hdf_dataset->CreateOnDisk();
-                   hdf_dataset->WriteOnDisk((unsigned char*) &aStream[0]);  //Save the stream in the HDF file
-                   hdf_dataset->CloseOnDisk();
-                 }
-                 // store multifile state
-                 aHDFSize[0] = 2;
-                 hdf_dataset = new HDFdataset("MULTIFILE_STATE", hdf_sco_group, HDF_STRING, aHDFSize, 1);
-                 hdf_dataset->CreateOnDisk();
-                 hdf_dataset->WriteOnDisk((void*)(theMultiFile?"M":"S")); // save: multi or single
-                 hdf_dataset->CloseOnDisk();
-                 hdf_dataset=0; //will be deleted by hdf_sco_AuxFiles destructor                
-
-                 // store ASCII state
-                 aHDFSize[0] = 2;
-                 hdf_dataset = new HDFdataset("ASCII_STATE", hdf_sco_group, HDF_STRING, aHDFSize, 1);
-                 hdf_dataset->CreateOnDisk();
-                 hdf_dataset->WriteOnDisk((void*)(theASCII?"A":"B")); // save: ASCII or BINARY
-                 hdf_dataset->CloseOnDisk();
-                 hdf_dataset=0; //will be deleted by hdf_sco_AuxFiles destructor                
-
-                 Translate_IOR_to_persistentID (aStudy,SB,sco,Engine,theMultiFile, theASCII);
-                 MESSAGE("After Translate_IOR_to_persistentID");
-                 
-                 // Creation of the persistance reference  attribute
-               }
+           }  // if(nbRows > 0 && aTable->GetNbColumns() > 1)
+           
+         }  // if(anAutoSaveSO->FindAttribute(aTable, "AttributeTableOfString")
+         
+       }  // if(SB->IsGUID(AUTO_SAVE_GUID)
+       
+       //SRN: End
+       
+       CORBA::String_var IOREngine;
+       if(sco->ComponentIOR(IOREngine)){
+         // we have found the associated engine to write the data 
+         MESSAGE ( "We have found an engine for data type :"<< componentDataType);
+         CORBA::Object_var obj = _orb->string_to_object(IOREngine);
+         SALOMEDS::Driver_var Engine = SALOMEDS::Driver::_narrow(obj) ;
+         
+         if(!CORBA::is_nil(Engine)){
+           MESSAGE ( "Save the data of type:"<< componentDataType);
+           MESSAGE("Engine :"<<Engine->ComponentDataType());
+           
+           SALOMEDS::TMPFile_var aStream;
+           
+           if(theASCII) 
+             aStream = Engine->SaveASCII(sco,SALOMEDS_Tool::GetDirFromPath(aUrl).c_str(),theMultiFile);
+           else
+             aStream = Engine->Save(sco,SALOMEDS_Tool::GetDirFromPath(aUrl).c_str(),theMultiFile);
+
+           HDFdataset *hdf_dataset;
+           hdf_size aHDFSize[1];
+           if(aStream->length() > 0){  //The component saved some auxiliary files, then put them into HDF file 
+             
+             aHDFSize[0] = aStream->length();
+             
+             HDFdataset *hdf_dataset = new HDFdataset("FILE_STREAM", hdf_sco_group, HDF_STRING, aHDFSize, 1);
+             hdf_dataset->CreateOnDisk();
+             hdf_dataset->WriteOnDisk((unsigned char*) &aStream[0]);  //Save the stream in the HDF file
+             hdf_dataset->CloseOnDisk();
            }
-         hdf_sco_group->CloseOnDisk();
-         hdf_sco_group=0; // will be deleted by hdf_group_datacomponent destructor
+           // store multifile state
+           aHDFSize[0] = 2;
+           hdf_dataset = new HDFdataset("MULTIFILE_STATE", hdf_sco_group, HDF_STRING, aHDFSize, 1);
+           hdf_dataset->CreateOnDisk();
+           hdf_dataset->WriteOnDisk((void*)(theMultiFile?"M":"S")); // save: multi or single
+           hdf_dataset->CloseOnDisk();
+           hdf_dataset=0; //will be deleted by hdf_sco_AuxFiles destructor              
+           
+           // store ASCII state
+           aHDFSize[0] = 2;
+           hdf_dataset = new HDFdataset("ASCII_STATE", hdf_sco_group, HDF_STRING, aHDFSize, 1);
+           hdf_dataset->CreateOnDisk();
+           hdf_dataset->WriteOnDisk((void*)(theASCII?"A":"B")); // save: ASCII or BINARY
+           hdf_dataset->CloseOnDisk();
+           hdf_dataset=0; //will be deleted by hdf_sco_AuxFiles destructor              
+           
+           Translate_IOR_to_persistentID(aStudy,SB,sco,Engine,theMultiFile, theASCII);
+           MESSAGE("After Translate_IOR_to_persistentID");
+                 
+           // Creation of the persistance reference  attribute
+         }
        }
+       hdf_sco_group->CloseOnDisk();
+       hdf_sco_group=0; // will be deleted by hdf_group_datacomponent destructor
+      }
       hdf_group_datacomponent->CloseOnDisk();
       hdf_group_datacomponent =0;  // will be deleted by hdf_file destructor
-
-
+      
+      
       //-----------------------------------------------------------------------
       //3 - Write the Study Structure
       //-----------------------------------------------------------------------
@@ -1394,37 +865,35 @@ void SALOMEDS_StudyManager_i::_SaveAs(const char* aUrl,
       hdf_group_study_structure->CreateOnDisk();
 
       // save component attributes
-      SALOMEDS::SComponentIterator_var itcomp = aStudy->NewComponentIterator();
-      for (; itcomp->More(); itcomp->Next()) 
-       {
-         SALOMEDS::SComponent_var SC = itcomp->Value();
-         
-         CORBA::String_var scid = SC->GetID();
-         hdf_sco_group2 = new HDFgroup(scid,hdf_group_study_structure);
-         hdf_sco_group2->CreateOnDisk();
-          SaveAttributes(SC, hdf_sco_group2);
-         // ComponentDataType treatment
-         component_name = SC->ComponentDataType();
-         MESSAGE("Component data type " << component_name << " treated");
-         
-         name_len = (hdf_int32) strlen(component_name);
-         size[0] = name_len +1 ; 
-         hdf_dataset = new HDFdataset("COMPONENTDATATYPE",hdf_sco_group2,HDF_STRING,size,1);
-         hdf_dataset->CreateOnDisk();
-         hdf_dataset->WriteOnDisk(component_name);
-         MESSAGE("component name " <<  component_name << " wrote on file");
-         hdf_dataset->CloseOnDisk();
-         hdf_dataset=0; //will be deleted by hdf_sco_group destructor
-         _SaveObject(aStudy, SC, hdf_sco_group2);
-         hdf_sco_group2->CloseOnDisk();
-         hdf_sco_group2=0; // will be deleted by hdf_group_study_structure destructor
-         CORBA::string_free(component_name);       
-       }
+      aComponentIter.Init();
+      for(; aComponentIter.More(); aComponentIter.Next()){
+       SALOMEDS::SComponent_var SC = aComponentIter.Value();
+       
+       CORBA::String_var scid = SC->GetID();
+       hdf_sco_group2 = new HDFgroup(scid,hdf_group_study_structure);
+       hdf_sco_group2->CreateOnDisk();
+       SaveAttributes(SC, hdf_sco_group2);
+       // ComponentDataType treatment
+       CORBA::String_var component_name = SC->ComponentDataType();
+       MESSAGE("Component data type " << component_name << " treated");
+       
+       name_len = (hdf_int32) strlen(component_name.in());
+       size[0] = name_len +1 ; 
+       hdf_dataset = new HDFdataset("COMPONENTDATATYPE",hdf_sco_group2,HDF_STRING,size,1);
+       hdf_dataset->CreateOnDisk();
+       hdf_dataset->WriteOnDisk(const_cast<char*>(component_name.in()));
+       MESSAGE("component name " <<  component_name << " wrote on file");
+       hdf_dataset->CloseOnDisk();
+       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
+       _SaveObject(aStudy, SC, hdf_sco_group2);
+       hdf_sco_group2->CloseOnDisk();
+       hdf_sco_group2=0; // will be deleted by hdf_group_study_structure destructor
+      }
       //-----------------------------------------------------------------------
       //4 - Write the Study UseCases Structure
       //-----------------------------------------------------------------------
       SALOMEDS::SObject_var aSO = aStudy->FindObjectID(USE_CASE_LABEL_ID);
-      if (!aSO->_is_nil()) {
+      if(!aSO->_is_nil()){
        HDFgroup *hdf_soo_group = new HDFgroup(USE_CASE_LABEL_ID,hdf_group_study_structure);
        hdf_soo_group->CreateOnDisk();
        SaveAttributes(aSO, hdf_soo_group);
@@ -1434,7 +903,8 @@ void SALOMEDS_StudyManager_i::_SaveAs(const char* aUrl,
        hdf_soo_group=0; // will be deleted by hdf_group_study_structure destructor
       }
 
-      if (aLocked) aStudy->GetProperties()->SetLocked(true);
+      if (aLocked) 
+       aStudy->GetProperties()->SetLocked(true);
       //-----------------------------------------------------------------------
       //5 - Write the Study Properties
       //-----------------------------------------------------------------------
@@ -1452,16 +922,20 @@ void SALOMEDS_StudyManager_i::_SaveAs(const char* aUrl,
 
       hdf_group_study_structure->CloseOnDisk();
       hdf_file->CloseOnDisk();
+
+      _name_service.Change_Directory("/Study");
+      _name_service.Destroy_Name(anOldName);
+      _name_service.Register(theStudy, aStudy->Name());
+
       aStudy->IsSaved(true);
       hdf_group_study_structure =0; // will be deleted by hdf_file destructor
       delete hdf_file; // recursively deletes all hdf objects...
+    }catch(HDFexception){
+      MESSAGE( "HDFexception ! " );
     }
-  catch (HDFexception)
-    {
-      MESSAGE( "HDFexception ! " )
+    if(theASCII){ // save file in ASCII format
+      HDFascii::ConvertFromHDFToASCII(aUrl, true);
     }
-  if (theASCII) { // save file in ASCII format
-    HDFascii::ConvertFromHDFToASCII(aUrl, true);
   }
 }
 
@@ -1470,47 +944,46 @@ void SALOMEDS_StudyManager_i::_SaveAs(const char* aUrl,
  *  Purpose  :
  */
 //============================================================================
-void SALOMEDS_StudyManager_i::_SaveObject(SALOMEDS::Study_ptr aStudy, 
-                                         SALOMEDS::SObject_ptr SC
+void SALOMEDS_StudyManager_i::_SaveObject(SALOMEDS_Study_i* theStudy, 
+                                         SALOMEDS::SObject_ptr theSObject
                                          HDFgroup *hdf_group_datatype)
 {
   // Write in group hdf_group_datatype all informations of SObject SC
   // Iterative function to parse all SObjects under a SComponent
   SALOMEDS::SObject_var RefSO;
   HDFgroup *hdf_group_sobject = 0;
-  HDFdataset *hdf_dataset = 0;
-  hdf_size size[1];
-  hdf_int32 name_len = 0;
-
-  SALOMEDS::ChildIterator_var itchild = aStudy->NewChildIterator(SC);
-  for (; itchild->More(); itchild->Next()) 
-    {
-      SALOMEDS::SObject_var SO = itchild->Value();
-
-      // mpv: don't save empty labels
-      if (SO->GetAllAttributes()->length() == 0) {
-       SALOMEDS::ChildIterator_var subchild = aStudy->NewChildIterator(SC);
-       if (!subchild->More()) {
-         continue;
-       }
-       subchild->InitEx(true);
-       bool anEmpty = true;
-       for (; subchild->More() && anEmpty; subchild->Next()) 
-         if (subchild->Value()->GetAllAttributes()->length() != 0) anEmpty = false;
-       if (anEmpty) {
-         continue;
-       }
-      }
-
-      CORBA::String_var scoid = strdup(SO->GetID());
-      hdf_group_sobject = new HDFgroup(scoid,hdf_group_datatype);
-      hdf_group_sobject->CreateOnDisk();
-      SaveAttributes(SO, hdf_group_sobject);
-      _SaveObject(aStudy,SO, hdf_group_sobject);
-      hdf_group_sobject->CloseOnDisk();
-      hdf_group_sobject =0; // will be deleted by father hdf object destructor
 
+  SALOMEDS_ChildIterator_i aChildIter = theStudy->GetChildIterator(theSObject);
+  for(; aChildIter.More(); aChildIter.Next()){
+    SALOMEDS::SObject_var aSObject = aChildIter.Value();
+    SALOMEDS::ListOfAttributes_var anAllAttributes = aSObject->GetAllAttributes();
+    
+    // mpv: don't save empty labels
+    if(anAllAttributes->length() == 0 && !aSObject->ReferencedObject(RefSO)){
+      SALOMEDS_ChildIterator_i aSubChildIter = theStudy->GetChildIterator(theSObject);
+      if(!aSubChildIter.More())
+       continue;
+
+      aSubChildIter.InitEx(true);
+      bool anEmpty = true;
+      for(; aSubChildIter.More() && anEmpty; aSubChildIter.Next()){
+       SALOMEDS::SObject_var aSObj = aSubChildIter.Value();
+       SALOMEDS::ListOfAttributes_var anAllAttr = aSObj->GetAllAttributes();
+       if(anAllAttr->length() != 0 || aSObj->ReferencedObject(RefSO)) 
+         anEmpty = false;
+      }
+      if(anEmpty)
+       continue;
     }
+
+    CORBA::String_var scoid(aSObject->GetID());
+    hdf_group_sobject = new HDFgroup(scoid,hdf_group_datatype);
+    hdf_group_sobject->CreateOnDisk();
+    SaveAttributes(aSObject, hdf_group_sobject);
+    _SaveObject(theStudy,aSObject, hdf_group_sobject);
+    hdf_group_sobject->CloseOnDisk();
+    hdf_group_sobject =0; // will be deleted by father hdf object destructor
+  }
 }
 
 //============================================================================
@@ -1519,15 +992,13 @@ void SALOMEDS_StudyManager_i::_SaveObject(SALOMEDS::Study_ptr aStudy,
  */
 //============================================================================
 
-const char *SALOMEDS_StudyManager_i::_SubstituteSlash(const char *aUrl)
+std::string SALOMEDS_StudyManager_i::_SubstituteSlash(const char *theUrl)
 {
   ASSERT(1==0);
-  TCollection_ExtendedString theUrl(CORBA::string_dup(aUrl));
-  Standard_ExtCharacter val1 = ToExtCharacter('/');
-  Standard_ExtCharacter val2 = ToExtCharacter(':');
-  theUrl.ChangeAll(val1,val2);
-  TCollection_AsciiString ch(theUrl);
-  return strdup(ch.ToCString());
+  TCollection_ExtendedString aUrl(const_cast<char*>(theUrl));
+  aUrl.ChangeAll(ToExtCharacter('/'),ToExtCharacter(':'));
+  TCollection_AsciiString ch(aUrl);
+  return ch.ToCString();
 }
 
 //============================================================================
@@ -1537,40 +1008,23 @@ const char *SALOMEDS_StudyManager_i::_SubstituteSlash(const char *aUrl)
 //============================================================================
 CORBA::Boolean SALOMEDS_StudyManager_i::CanCopy(SALOMEDS::SObject_ptr theObject) {
   SALOMEDS::SComponent_var aComponent = theObject->GetFatherComponent();
-  if (aComponent->_is_nil()) return false;
-  if (aComponent == theObject) return false;
+
+  if(aComponent->_is_nil()) 
+    return false;
+
+  if(aComponent == theObject) 
+    return false;
 
   CORBA::String_var IOREngine;
-  if (!aComponent->ComponentIOR(IOREngine)) return false;
+  if(!aComponent->ComponentIOR(IOREngine)) 
+    return false;
 
   CORBA::Object_var obj = _orb->string_to_object(IOREngine);
   SALOMEDS::Driver_var Engine = SALOMEDS::Driver::_narrow(obj) ;
-  if (CORBA::is_nil(Engine)) return false;
-  return Engine->CanCopy(theObject);
-}
-
-//============================================================================
-/*! Function : GetDocumentOfStudy
- *  Purpose  : 
- */
-//============================================================================
-Handle(TDocStd_Document) SALOMEDS_StudyManager_i::GetDocumentOfStudy(SALOMEDS::Study_ptr theStudy) {
-  int a;
-  int aNbDocs = _OCAFApp->NbDocuments(); 
-  Handle(TDocStd_Document) aDocument;  
-  for(a = 1; a <= aNbDocs ; a++) {
-    _OCAFApp->GetDocument(a, aDocument);
-    if (!aDocument.IsNull()) {
-      SALOMEDS_SObject_i *  aSOServant = new SALOMEDS_SObject_i (aDocument->Main(),_orb);
-      SALOMEDS::SObject_var aSO = SALOMEDS::SObject::_narrow(aSOServant->_this()); 
-      SALOMEDS::Study_var aStudy = aSO->GetStudy();
-      if(CORBA::is_nil(aStudy)) continue;  //The clipboard document ( hopefully :) )
-      if (aStudy->StudyId() == theStudy->StudyId()) break;
-      aDocument.Nullify();
-    }
-  }
+  if (CORBA::is_nil(Engine)) 
+    return false;
 
-  return aDocument;
+  return Engine->CanCopy(theObject);
 }
 
 //============================================================================
@@ -1578,11 +1032,12 @@ Handle(TDocStd_Document) SALOMEDS_StudyManager_i::GetDocumentOfStudy(SALOMEDS::S
  *  Purpose  : 
  */
 //============================================================================
-void SALOMEDS_StudyManager_i::CopyLabel(const SALOMEDS::Study_ptr theSourceStudy,
+void SALOMEDS_StudyManager_i::CopyLabel(SALOMEDS_Study_i* theSourceStudy,
                                        const SALOMEDS::Driver_ptr theEngine,
                                        const Standard_Integer theSourceStartDepth,
                                        const TDF_Label& theSource,
-                                       const TDF_Label& theDestinationMain) {
+                                       const TDF_Label& theDestinationMain) 
+{
   int a;
   TDF_Label aTargetLabel = theDestinationMain;
   TDF_Label aAuxTargetLabel = theDestinationMain.Father().FindChild(2);
@@ -1617,19 +1072,16 @@ void SALOMEDS_StudyManager_i::CopyLabel(const SALOMEDS::Study_ptr theSourceStudy
     if (!Handle(SALOMEDS_IORAttribute)::DownCast(anAttr).IsNull()) { // IOR => ID and TMPFile of Engine
       TCollection_AsciiString anEntry;
       TDF_Tool::Entry(theSource, anEntry);
-      SALOMEDS::SObject_var aSO = theSourceStudy->FindObjectID(strdup(anEntry.ToCString()));
-//        if (theEngine->CanCopy(aSO)) {
-       CORBA::Long anObjID;
-//     TCollection_ExtendedString aResStr(strdup((char*)(theEngine->CopyFrom(aSO, anObjID))));
-          SALOMEDS::TMPFile_var aStream = theEngine->CopyFrom(aSO, anObjID);
-          int aLen = aStream->length();
-         TCollection_ExtendedString aResStr("");
-         for(a = 0; a < aLen; a++) {
-           aResStr += TCollection_ExtendedString(ToExtCharacter((Standard_Character)aStream[a]));
-         }
-         TDataStd_Integer::Set(aAuxTargetLabel, anObjID);
-         TDataStd_Name::Set(aAuxTargetLabel, aResStr);
-//        }
+      SALOMEDS::SObject_var aSO = theSourceStudy->FindObjectID(anEntry.ToCString());
+      CORBA::Long anObjID;
+      SALOMEDS::TMPFile_var aStream = theEngine->CopyFrom(aSO, anObjID);
+      int aLen = aStream->length();
+      TCollection_ExtendedString aResStr("");
+      for(a = 0; a < aLen; a++) {
+       aResStr += TCollection_ExtendedString(ToExtCharacter((Standard_Character)aStream[a]));
+      }
+      TDataStd_Integer::Set(aAuxTargetLabel, anObjID);
+      TDataStd_Name::Set(aAuxTargetLabel, aResStr);
       continue;
     }
     Handle(TDF_Attribute) aNewAttribute = anAttr->NewEmpty();
@@ -1646,49 +1098,58 @@ void SALOMEDS_StudyManager_i::CopyLabel(const SALOMEDS::Study_ptr theSourceStudy
 //============================================================================
 CORBA::Boolean SALOMEDS_StudyManager_i::Copy(SALOMEDS::SObject_ptr theObject) {
   // adoptation for alliances datamodel copy: without IOR attributes !!!
-  bool aStructureOnly; // copy only SObjects and attributes without component help
+  // copy only SObjects and attributes without component help
   SALOMEDS::GenericAttribute_var anAttribute;
-  aStructureOnly = !theObject->FindAttribute(anAttribute, "AttributeIOR");
+  bool aStructureOnly = !theObject->FindAttribute(anAttribute, "AttributeIOR");
 
-  // get component-engine
-  SALOMEDS::Study_var aStudy = theObject->GetStudy();
+  PortableServer::ServantBase_var aServant = GetServant(theObject,_poa);
+  SALOMEDS_SObject_i* aSObject = dynamic_cast<SALOMEDS_SObject_i*>(aServant.in());
+  if(aSObject == NULL) 
+    return false;
 
-  SALOMEDS::Driver_var Engine;
+  SALOMEDS_Study_i* aStudy = aSObject->GetStudyServant();
+  SALOMEDS::Driver_var anEngine;
+  CORBA::String_var aString;
   if (!aStructureOnly) {
     SALOMEDS::SComponent_var aComponent = theObject->GetFatherComponent();
-    CORBA::String_var IOREngine;
-    if (!aComponent->ComponentIOR(IOREngine)) return false;
+    if(!aComponent->ComponentIOR(aString)) 
+      return false;
 
-    CORBA::Object_var obj = _orb->string_to_object(IOREngine);
-    Engine = SALOMEDS::Driver::_narrow(obj) ;
+    CORBA::Object_var anObj = _orb->string_to_object(aString);
+    anEngine = SALOMEDS::Driver::_narrow(anObj) ;
   }
+
   // CAF document of current study usage
-  Handle(TDocStd_Document) aDocument = GetDocumentOfStudy(aStudy);
-  if (aDocument.IsNull()) return false;
+  Handle(TDocStd_Document) aDocument = aStudy->GetDocument();
+  if(aDocument.IsNull()) 
+    return false;
+
   // create new document for clipboard
   Handle(TDocStd_Document) aTargetDocument;
   _OCAFApp->NewDocument("SALOME_STUDY", aTargetDocument);
   // set component data type to the name attribute of root label
-  if (!aStructureOnly) {
-    TDataStd_Comment::Set(aTargetDocument->Main().Root(),
-                         TCollection_ExtendedString(strdup(Engine->ComponentDataType())));
+  if(!aStructureOnly){
+    aString = anEngine->ComponentDataType();
+    TDataStd_Comment::Set(aTargetDocument->Main().Root(),const_cast<char*>(aString.in()));
   }
   // set to the Root label integer attribute: study id
-  TDataStd_Integer::Set(aTargetDocument->Main().Root(), aStudy->StudyId());
+  TDataStd_Integer::Set(aTargetDocument->Main().Root(),aStudy->StudyId());
+
   // iterate all theObject's label children
   TDF_Label aStartLabel;
-  char* aStartID = strdup(theObject->GetID());
-  TDF_Tool::Label(aDocument->GetData(), aStartID, aStartLabel);
+  aString = theObject->GetID();
+  TDF_Tool::Label(aDocument->GetData(),const_cast<char*>(aString.in()),aStartLabel);
   Standard_Integer aSourceStartDepth = aStartLabel.Depth();
   
   // copy main source label
-  CopyLabel(aStudy, Engine, aSourceStartDepth, aStartLabel, aTargetDocument->Main());
+  CopyLabel(aStudy,anEngine,aSourceStartDepth,aStartLabel,aTargetDocument->Main());
 
   // copy all subchildren of the main source label (all levels)
-  TDF_ChildIterator anIterator(aStartLabel, Standard_True);
-  for(; anIterator.More(); anIterator.Next()) {
-    CopyLabel(aStudy, Engine, aSourceStartDepth, anIterator.Value(), aTargetDocument->Main());
+  TDF_ChildIterator anIterator(aStartLabel,Standard_True);
+  for(; anIterator.More(); anIterator.Next()){
+    CopyLabel(aStudy,anEngine,aSourceStartDepth,anIterator.Value(),aTargetDocument->Main());
   }
+
   // done: free old clipboard document and 
   if (!_clipboard.IsNull()) {
 //      Handle(TDocStd_Owner) anOwner;
@@ -1698,6 +1159,7 @@ CORBA::Boolean SALOMEDS_StudyManager_i::Copy(SALOMEDS::SObject_ptr theObject) {
 //      }
     _OCAFApp->Close(_clipboard);
   }
+
   _clipboard = aTargetDocument;
 
   return true;
@@ -1717,27 +1179,32 @@ CORBA::Boolean SALOMEDS_StudyManager_i::CanPaste(SALOMEDS::SObject_ptr theObject
     return false;
 
   SALOMEDS::SComponent_var aComponent = theObject->GetFatherComponent();
-  if (aComponent->_is_nil()) return false;
+  if(aComponent->_is_nil()) 
+    return false;
   
   CORBA::String_var IOREngine;
-  if (!aComponent->ComponentIOR(IOREngine)) return false;
+  if(!aComponent->ComponentIOR(IOREngine)) 
+    return false;
   
   CORBA::Object_var obj = _orb->string_to_object(IOREngine);
   SALOMEDS::Driver_var Engine = SALOMEDS::Driver::_narrow(obj) ;
-  if (CORBA::is_nil(Engine)) return false;
-  return Engine->CanPaste(strdup(TCollection_AsciiString(aCompName->Get()).ToCString()), anObjID->Get());
+  if (CORBA::is_nil(Engine)) 
+    return false;
+
+  return Engine->CanPaste(TCollection_AsciiString(aCompName->Get()).ToCString(),anObjID->Get());
 }
 //============================================================================
 /*! Function : PasteLabel
  *  Purpose  :
  */
 //============================================================================
-TDF_Label SALOMEDS_StudyManager_i::PasteLabel(const SALOMEDS::Study_ptr theDestinationStudy,
+TDF_Label SALOMEDS_StudyManager_i::PasteLabel(SALOMEDS_Study_i* theDestinationStudy,
                                              const SALOMEDS::Driver_ptr theEngine,
                                              const TDF_Label& theSource,
                                              const TDF_Label& theDestinationStart,
                                              const int theCopiedStudyID,
-                                             const bool isFirstElement) {
+                                             const bool isFirstElement) 
+{
 
   // get corresponding source, target and auxiliary labels
   TDF_Label aTargetLabel = theDestinationStart;
@@ -1746,7 +1213,8 @@ TDF_Label SALOMEDS_StudyManager_i::PasteLabel(const SALOMEDS::Study_ptr theDesti
   if (!isFirstElement) {
     for(a = theSource.Depth() - 1; a > 0 ; a--) {
       TDF_Label aSourceLabel = theSource;
-      for(int aNbFather = 1; aNbFather < a; aNbFather++) aSourceLabel = aSourceLabel.Father();
+      for(int aNbFather = 1; aNbFather < a; aNbFather++)
+       aSourceLabel = aSourceLabel.Father();
       aTargetLabel = aTargetLabel.FindChild(aSourceLabel.Tag());
       aAuxSourceLabel = aAuxSourceLabel.FindChild(aSourceLabel.Tag());
     }
@@ -1760,9 +1228,8 @@ TDF_Label SALOMEDS_StudyManager_i::PasteLabel(const SALOMEDS::Study_ptr theDesti
     aAuxSourceLabel.FindAttribute(TDataStd_Integer::GetID(), anObjID);
     Handle(TDataStd_Comment) aComponentName;
     theSource.Root().FindAttribute(TDataStd_Comment::GetID(), aComponentName);
-    CORBA::String_var aCompName = strdup(TCollection_AsciiString(aComponentName->Get()).ToCString());
-
-    if (theEngine->CanPaste(aCompName, anObjID->Get())) {
+    std::string aCompName = TCollection_AsciiString(aComponentName->Get()).ToCString();
+    if (theEngine->CanPaste(aCompName.c_str(),anObjID->Get())) {
       SALOMEDS::TMPFile_var aTMPFil = new SALOMEDS::TMPFile();
       TCollection_ExtendedString aTMPStr = aNameAttribute->Get();
       int aLen = aTMPStr.Length();
@@ -1770,20 +1237,17 @@ TDF_Label SALOMEDS_StudyManager_i::PasteLabel(const SALOMEDS::Study_ptr theDesti
       for(a = 0; a < aLen; a++) {
        aTMPFil[a] = ToCharacter(aTMPStr.Value(a+1));
       }
-//        char* aTMPStr = strdup(TCollection_AsciiString(aNameAttribute->Get()).ToCString());
-//        int aLen = strlen(aTMPStr);
-//        SALOMEDS::TMPFile aTMPFil(aLen, aLen, (CORBA::Octet*)aTMPStr, 1);
-      
       TCollection_AsciiString anEntry;
       TDF_Tool::Entry(aTargetLabel, anEntry);
-      SALOMEDS::SObject_var aPastedSO = theDestinationStudy->FindObjectID(strdup(anEntry.ToCString()));
-      if (isFirstElement) {
+      SALOMEDS::SObject_var aPastedSO = theDestinationStudy->FindObjectID(anEntry.ToCString());
+      if(isFirstElement){
        SALOMEDS::SObject_var aDestSO =
          theEngine->PasteInto(aTMPFil.in(),
                               anObjID->Get(),
                               aPastedSO->GetFatherComponent());
        TDF_Tool::Label(theDestinationStart.Data(), aDestSO->GetID(), aTargetLabel);
-      } else theEngine->PasteInto(aTMPFil.in(),anObjID->Get(),aPastedSO);
+      }else 
+       theEngine->PasteInto(aTMPFil.in(),anObjID->Get(),aPastedSO);
     }
   }
 
@@ -1804,23 +1268,25 @@ TDF_Label SALOMEDS_StudyManager_i::PasteLabel(const SALOMEDS::Study_ptr theDesti
   // check auxiliary label for Comment => reference or name attribute of the referenced object
   Handle(TDataStd_Comment) aCommentAttribute;
   if (aAuxSourceLabel.FindAttribute(TDataStd_Comment::GetID(), aCommentAttribute)) {
-    char * anEntry = new char[aCommentAttribute->Get().Length() + 1];
-    strcpy(anEntry, TCollection_AsciiString(aCommentAttribute->Get()).ToCString());
-    char* aNameStart = strchr(anEntry, ' ');
-    if (aNameStart) {
-      *aNameStart = '\0';
-      aNameStart++;
+    std::string anEntry(TCollection_AsciiString(aCommentAttribute->Get()).ToCString());
+    std::size_t aNameStart = anEntry.find(' ');
+    std::string aName;
+    if(aNameStart != std::string::npos){
+      aName = anEntry.substr(aNameStart+1);
+      anEntry = anEntry.substr(0,aNameStart);
     }
     if (theCopiedStudyID == theDestinationStudy->StudyId()) { // if copy to the same study, reanimate reference
       TDF_Label aRefLabel;
-      TDF_Tool::Label(aTargetLabel.Data(), anEntry, aRefLabel);
+      TDF_Tool::Label(aTargetLabel.Data(),&anEntry[0],aRefLabel);
       TDF_Reference::Set(aTargetLabel, aRefLabel);
       SALOMEDS_TargetAttribute::Set(aRefLabel)->Append(aTargetLabel); // target attributes structure support
     } else {
-      if (aNameStart) TDataStd_Name::Set(aTargetLabel, aNameStart);
-      else TDataStd_Name::Set(aTargetLabel, TCollection_ExtendedString("Reference to:")+anEntry);
+      if(aNameStart != std::string::npos)
+       TDataStd_Name::Set(aTargetLabel, &aName[0]);
+      else
+       TDataStd_Name::Set(aTargetLabel, 
+                          TCollection_ExtendedString("Reference to:") + &anEntry[0]);
     }
-    delete(anEntry);
   }
 
   return aTargetLabel;
@@ -1833,7 +1299,14 @@ TDF_Label SALOMEDS_StudyManager_i::PasteLabel(const SALOMEDS::Study_ptr theDesti
 SALOMEDS::SObject_ptr SALOMEDS_StudyManager_i::Paste(SALOMEDS::SObject_ptr theObject)
      throw(SALOMEDS::StudyBuilder::LockProtection)
 {
-  SALOMEDS::Study_var aStudy = theObject->GetStudy();
+  Unexpect aCatch(LockProtection);
+
+  PortableServer::ServantBase_var aServant = GetServant(theObject,_poa);
+  SALOMEDS_SObject_i* aSObject = dynamic_cast<SALOMEDS_SObject_i*>(aServant.in());
+  if(aSObject == NULL) 
+    return false;
+
+  SALOMEDS_Study_i* aStudy = aSObject->GetStudyServant();
 
   // if study is locked, then paste can't be done
   if (aStudy->GetProperties()->IsLocked())
@@ -1847,42 +1320,35 @@ SALOMEDS::SObject_ptr SALOMEDS_StudyManager_i::Paste(SALOMEDS::SObject_ptr theOb
   Handle(TDataStd_Integer) aStudyIDAttribute;
   if (!_clipboard->Main().Root().FindAttribute(TDataStd_Integer::GetID(), aStudyIDAttribute))
     return SALOMEDS::SObject::_nil();
-  int aCStudyID = aStudyIDAttribute->Get();
 
   // get component-engine
-  SALOMEDS::Driver_var Engine;
   SALOMEDS::SComponent_var aComponent;
+  SALOMEDS::Driver_var anEngine;
+  CORBA::String_var aString;
   if (!aStructureOnly) {
     aComponent = theObject->GetFatherComponent();
-    CORBA::String_var IOREngine;
-    if (!aComponent->ComponentIOR(IOREngine)) return SALOMEDS::SObject::_nil();
-    CORBA::Object_var obj = _orb->string_to_object(IOREngine);
-    Engine = SALOMEDS::Driver::_narrow(obj) ;
+    if(!aComponent->ComponentIOR(aString)) 
+      return SALOMEDS::SObject::_nil();
+
+    CORBA::Object_var anObj = _orb->string_to_object(aString);
+    anEngine = SALOMEDS::Driver::_narrow(anObj) ;
   }
 
   // CAF document of current study usage
-  Handle(TDocStd_Document) aDocument = GetDocumentOfStudy(aStudy);
-  if (aDocument.IsNull()) return SALOMEDS::SObject::_nil();
+  Handle(TDocStd_Document) aDocument = aStudy->GetDocument();
+  if (aDocument.IsNull()) 
+    return SALOMEDS::SObject::_nil();
+
   // fill root inserted SObject
-  TDF_Label aStartLabel;
-  if (aStructureOnly) {
-    TDF_Label anObjectLabel;
-    TDF_Tool::Label(aDocument->GetData(), theObject->GetID(), anObjectLabel);
-    aStartLabel = PasteLabel(aStudy, Engine, _clipboard->Main(), anObjectLabel, aCStudyID, false);
-  } else {
-    TDF_Label aComponentLabel;
-    TDF_Tool::Label(aDocument->GetData(), aComponent->GetID(), aComponentLabel);
-    aStartLabel = PasteLabel(aStudy, Engine, _clipboard->Main(), aComponentLabel, aCStudyID, true);
-  }
+  int aCStudyID = aStudyIDAttribute->Get();
+  TDF_Label aLabel = aStructureOnly? aSObject->GetLabel(): aSObject->GetFatherComponentLabel();
+  TDF_Label aStartLabel = PasteLabel(aStudy,anEngine,_clipboard->Main(),aLabel,aCStudyID,true);
 
   // paste all sublebels
-  TDF_ChildIterator anIterator(_clipboard->Main(), Standard_True);
+  TDF_ChildIterator anIterator(_clipboard->Main(),Standard_True);
   for(; anIterator.More(); anIterator.Next()) {
-    PasteLabel(aStudy, Engine, anIterator.Value(), aStartLabel, aCStudyID, false);
+    PasteLabel(aStudy,anEngine,anIterator.Value(),aStartLabel,aCStudyID,false);
   }
 
-  SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (aStartLabel, _orb);
-  SALOMEDS::SObject_var so = SALOMEDS::SObject::_narrow(so_servant->_this()); 
-
-  return so._retn();
+  return SALOMEDS_SObject_i::NewRef(aStudy,aStartLabel)._retn();
 }