Salome HOME
Fix on [Bug PAL7750] Regression of UNDO in GEOM
[modules/yacs.git] / src / SALOMEDS / SALOMEDS_SObject_i.cxx
index f9c00984eded0c70bf0307679b2198716a5a5cd2..5f5ddded8977a4af4324f3905c2e1d3135c4516f 100644 (file)
 //  Module : SALOME
 //  $Header$
 
-using namespace std;
-#include "utilities.h"
+#include <TDF_Tool.hxx>
+#include <TDF_Attribute.hxx>
+#include <TDF_Reference.hxx>
+#include <Standard_GUID.hxx>
+#include <Standard_NoSuchObject.hxx>
+#include <TDataStd_Name.hxx>
+#include <TDataStd_Comment.hxx>
+#include <TDataStd_Integer.hxx>
+#include <TDataStd_Real.hxx>
+#include <TDataStd_TreeNode.hxx>
+#include <TDataStd_UAttribute.hxx>
+
+#include <TCollection_AsciiString.hxx>
+#include <TDF_AttributeIterator.hxx>
+
 #include "SALOMEDS_SObject_i.hxx"
+
 //SALOMEDS Headers
+#include "SALOMEDS_Study_i.hxx"
+#include "SALOMEDS_StudyManager_i.hxx"
 #include "SALOMEDS_SComponent_i.hxx"
-#include "SALOMEDS_IORAttribute.hxx"
-#include "SALOMEDS_PersRefAttribute.hxx"
-#include "SALOMEDS_SequenceOfRealAttribute.hxx"
-#include "SALOMEDS_SequenceOfIntegerAttribute.hxx"
-#include "SALOMEDS_TableOfRealAttribute.hxx"
-#include "SALOMEDS_TableOfIntegerAttribute.hxx"
-#include "SALOMEDS_IORAttribute.hxx"
-#include "SALOMEDS_PersRefAttribute.hxx"
-#include "SALOMEDS_StudyPropertiesAttribute.hxx"
-#include "SALOMEDS_PythonObjectAttribute.hxx"
+
+#include "SALOMEDS_AttributeComment_i.hxx"
+
+#include "SALOMEDS_AttributeTreeNode_i.hxx"
+#include "SALOMEDS_AttributeUserID_i.hxx"
+
 #include "SALOMEDS_AttributePersistentRef_i.hxx"
 #include "SALOMEDS_AttributeIOR_i.hxx"
-#include "SALOMEDS_AttributeComment_i.hxx"
+#include "SALOMEDS_AttributeExternalFileDef_i.hxx"
+#include "SALOMEDS_AttributeFileType_i.hxx"
 #include "SALOMEDS_AttributeName_i.hxx"
 #include "SALOMEDS_AttributeSequenceOfInteger_i.hxx"
 #include "SALOMEDS_AttributeSequenceOfReal_i.hxx"
+#include "SALOMEDS_AttributeTableOfInteger_i.hxx"
+#include "SALOMEDS_AttributeTableOfReal_i.hxx"
+#include "SALOMEDS_AttributeTableOfString_i.hxx"
 #include "SALOMEDS_AttributeInteger_i.hxx"
 #include "SALOMEDS_AttributeReal_i.hxx"
 #include "SALOMEDS_AttributeDrawable_i.hxx"
@@ -56,113 +72,257 @@ using namespace std;
 #include "SALOMEDS_AttributeTextColor_i.hxx"
 #include "SALOMEDS_AttributeTextHighlightColor_i.hxx"
 #include "SALOMEDS_AttributePixMap_i.hxx"
-#include "SALOMEDS_AttributeTreeNode_i.hxx"
-#include "SALOMEDS_AttributeLocalID_i.hxx"
-#include "SALOMEDS_AttributeUserID_i.hxx"
 #include "SALOMEDS_AttributeTarget_i.hxx"
-#include "SALOMEDS_AttributeTableOfInteger_i.hxx"
-#include "SALOMEDS_AttributeTableOfReal_i.hxx"
-#include "SALOMEDS_AttributeTableOfString_i.hxx"
+#include "SALOMEDS_AttributeLocalID_i.hxx"
 #include "SALOMEDS_AttributeStudyProperties_i.hxx"
 #include "SALOMEDS_AttributePythonObject_i.hxx"
-#include <TDF_AttributeIterator.hxx>
 
-//============================================================================
-/*! Function : ReturnGUIDForAttribute
- *  Purpose  : 
- */
-//============================================================================
+#include "SALOMEDS_AttributeGraphic_i.hxx"
+#include "SALOMEDS_AttributeFlags_i.hxx"
 
-Standard_GUID  
-SALOMEDS_SObject_i::ReturnGUIDForAttribute(const char* aTypeOfAttribute)
+#include "Utils_ExceptHandlers.hxx"
+UNEXPECT_CATCH(GALockProtection, SALOMEDS::GenericAttribute::LockProtection);
+
+#include "utilities.h"
+
+using namespace std;
+using namespace SALOMEDS;
+
+
+inline bool operator<(const Standard_GUID& theLeft, const Standard_GUID& theRight)
 {
-   Standard_GUID TypeID;
+  char aLeft[40] = "";
+  theLeft.ToCString(aLeft);
+
+  char aRight[40] = "";
+  theRight.ToCString(aRight);
   
-   if      (strcmp(aTypeOfAttribute, "AttributeReal") == 0 )               return TDataStd_Real::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributeInteger") == 0 )            return TDataStd_Integer::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributeSequenceOfReal") == 0 )     return SALOMEDS_SequenceOfRealAttribute::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributeSequenceOfInteger") == 0 )  return SALOMEDS_SequenceOfIntegerAttribute::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributeName") == 0 )               return TDataStd_Name::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributeComment") == 0 )            return TDataStd_Comment::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributeIOR") == 0 )                return SALOMEDS_IORAttribute::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributePersistentRef") == 0 )      return SALOMEDS_PersRefAttribute::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributeDrawable") == 0 )           return SALOMEDS_DrawableAttribute::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributeSelectable") == 0 )         return SALOMEDS_SelectableAttribute::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributeExpandable") == 0 )         return SALOMEDS_ExpandableAttribute::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributeOpened") == 0 )             return SALOMEDS_OpenedAttribute::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributeTextColor") == 0 )          return SALOMEDS_TextColorAttribute::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributeTextHighlightColor") == 0 ) return SALOMEDS_TextHighlightColorAttribute::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributePixMap") == 0 )             return SALOMEDS_PixMapAttribute::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributeTreeNode") == 0 )           return TDataStd_TreeNode::GetDefaultTreeID();
-   else if (strcmp(aTypeOfAttribute, "AttributeLocalID") == 0 )            return SALOMEDS_LocalIDAttribute::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributeTarget") == 0 )             return SALOMEDS_TargetAttribute::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributeTableOfInteger") == 0 )     return SALOMEDS_TableOfIntegerAttribute::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributeTableOfReal") == 0 )        return SALOMEDS_TableOfRealAttribute::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributeTableOfString") == 0 )      return SALOMEDS_TableOfStringAttribute::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributeStudyProperties") == 0 )    return SALOMEDS_StudyPropertiesAttribute::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributePythonObject") == 0 )       return SALOMEDS_PythonObjectAttribute::GetID();
-   else if (strcmp(aTypeOfAttribute, "AttributeUserID") == 0 )             return SALOMEDS_AttributeUserID_i::DefaultID();
-   else if (strncmp(aTypeOfAttribute,"AttributeTreeNodeGUID",21) == 0) {
-     char* aGUIDString = new char[40];
-     sprintf(aGUIDString, &(aTypeOfAttribute[21]));
-     Standard_GUID aGUID = Standard_GUID(aGUIDString); // create tree node GUID by name
-     delete(aGUIDString);
-     return aGUID;
-   }
-   else Standard_NoSuchObject::Raise("SALOMEDS_SObject_i::ReturnGUIDForAttribute");
+  return strcmp(aLeft,aRight) < 0;
 }
 
+
+namespace SALOMEDS{
+
+  const char* Str(const TCollection_ExtendedString& theString)
+  {
+    return TCollection_AsciiString(theString).ToCString();
+  }
+
+  typedef std::string TAttributeID;
+
+  typedef Standard_GUID (*TGetGUID)();
+  typedef bool (*TIsCheckLockedStudy)();
+  typedef Handle(TDF_Attribute) (*TNewAttribute)();
+  typedef SALOMEDS_GenericAttribute_i* (*TNewInstance)(const Handle(TDF_Attribute)&, SALOMEDS_SObject_i*);
+  
+  struct TAttrFun{
+    TAttrFun(const TGetGUID& theGetGUID,
+            const TIsCheckLockedStudy& theIsCheckLockedStudy,
+            const TNewAttribute& theNewAttribute,
+            const TNewInstance& theNewInstance):
+      myGetGUID(theGetGUID),
+      myIsCheckLockedStudy(theIsCheckLockedStudy),
+      myNewAttribute(theNewAttribute),
+      myNewInstance(theNewInstance)
+    {
+    }
+
+    TGetGUID myGetGUID;
+    TIsCheckLockedStudy myIsCheckLockedStudy;
+    TNewAttribute myNewAttribute;
+    TNewInstance myNewInstance;
+  };
+  
+  typedef std::map<TAttributeID,TAttrFun> TAttrID2FunMap;
+  static TAttrID2FunMap __AttrID2FunMap__;
+  
+  
+  typedef std::map<Standard_GUID,TAttributeID> TGUID2AttrIDMap;
+  static TGUID2AttrIDMap __GUID2AttrIDMap__;
+  
+  bool Init()
+  {
+    
+#define ADD_ATTRID2FUNMAP_ITEM(theName) \
+    __AttrID2FunMap__.insert( \
+      TAttrID2FunMap::value_type(#theName,TAttrFun( \
+       &(SALOMEDS_##theName##_i::GetGUID), \
+       &(SALOMEDS_##theName##_i::IsCheckLockedStudy), \
+       &(SALOMEDS_##theName##_i::NewAttribute), \
+       &(SALOMEDS_##theName##_i::NewInstance) \
+    )))
+                                                      
+    ADD_ATTRID2FUNMAP_ITEM(AttributeName);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeComment); 
+    ADD_ATTRID2FUNMAP_ITEM(AttributeIOR);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeReal);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeInteger);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeSequenceOfInteger);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeSequenceOfReal);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeTableOfInteger);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeTableOfReal);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeTableOfString);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeLocalID);
+    ADD_ATTRID2FUNMAP_ITEM(AttributePythonObject);
+    
+    ADD_ATTRID2FUNMAP_ITEM(AttributeUserID);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeTreeNode);
+
+    ADD_ATTRID2FUNMAP_ITEM(AttributePersistentRef);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeDrawable);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeSelectable);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeExpandable);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeOpened);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeTextColor);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeTextHighlightColor);
+    ADD_ATTRID2FUNMAP_ITEM(AttributePixMap);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeTarget);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeStudyProperties);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeExternalFileDef);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeFileType);
+
+    ADD_ATTRID2FUNMAP_ITEM(AttributeGraphic);
+    ADD_ATTRID2FUNMAP_ITEM(AttributeFlags);
+
+    TAttrID2FunMap::const_iterator anIter = __AttrID2FunMap__.begin();
+    TAttrID2FunMap::const_iterator anEnd = __AttrID2FunMap__.end();
+    for(; anIter != anEnd; anIter++){
+      const TAttrID2FunMap::key_type& aKey = anIter->first;
+      const TAttrID2FunMap::data_type& aValue = anIter->second;
+      __GUID2AttrIDMap__[aValue.myGetGUID()] = aKey;
+    };
+
+#undef ADD_ATTRID2FUNMAP_ITEM
+    return true;
+  }
+  
+
+  static bool __IsInitilized__ = Init();
+
+
+  //============================================================================
+  bool GetAttrFun(const Standard_GUID& theGUID, TAttrFun& theAttrFun)
+  {
+    TGUID2AttrIDMap::const_iterator anIter = __GUID2AttrIDMap__.find(theGUID);
+    if(anIter != __GUID2AttrIDMap__.end())
+    {
+      const TAttributeID& anAttributeID = anIter->second;
+      TAttrID2FunMap::const_iterator anIter2 = __AttrID2FunMap__.find(anAttributeID);
+      if(anIter2 != __AttrID2FunMap__.end())
+      {
+       theAttrFun = anIter2->second;
+       return true;
+      }
+    }
+    return false;
+  }
+
+
+  //============================================================================
+  Standard_GUID GetGUID(const char* theType)
+  {
+    TAttrID2FunMap::const_iterator anIter = __AttrID2FunMap__.find(theType);
+    if(anIter != __AttrID2FunMap__.end()){
+      const TAttrID2FunMap::data_type& aValue = anIter->second;
+      return aValue.myGetGUID();
+    }
+    // create tree node GUID by name
+    if(strncmp(theType,"AttributeTreeNodeGUID",21) == 0){
+      char aGUIDString[40] = "";
+      sprintf(aGUIDString,&theType[21]);
+      return aGUIDString;
+    }
+    
+    return Standard_GUID();
+  }
+
+
+  //============================================================================
+  std::string GetType(const Handle(TDF_Attribute)& theAttr)
+  {
+    if(theAttr.IsNull())
+      return CORBA::string_dup("");
+    
+    Standard_GUID aGUID = theAttr->ID();
+    TGUID2AttrIDMap::const_iterator anIter = __GUID2AttrIDMap__.find(aGUID);
+    if(anIter != __GUID2AttrIDMap__.end())
+    {
+      const TAttributeID& anAttributeID = anIter->second;
+      return anAttributeID;
+    }
+    
+    char aType[60] = "";
+    {
+      Handle(TDataStd_TreeNode) anAttr = Handle(TDataStd_TreeNode)::DownCast(theAttr);
+      if (!anAttr.IsNull()) {
+       char aGUID[40] = "";
+       anAttr->ID().ToCString(aGUID);
+       sprintf(aType, "AttributeTreeNodeGUID%s",aGUID);
+       return aType;
+      }
+    }
+    {
+      Handle(TDataStd_UAttribute) anAttr = Handle(TDataStd_UAttribute)::DownCast(theAttr);
+      if (!anAttr.IsNull()) {
+       char aGUID[40] = "";
+       anAttr->ID().ToCString(aGUID);
+       sprintf(aType, "AttributeUserID_%s",aGUID); 
+       return aType;
+      }
+    }
+    return aType;
+  }
+  
+}  
+  
 //============================================================================
-/*! Function : AttributeIDToType
- *  Purpose  : 
- */
-//============================================================================
-char* SALOMEDS_SObject_i::AttributeIDToType(Standard_GUID ID)
+SALOMEDS_Study_i::TSObjectHolder
+SALOMEDS_SObject_i::New(SALOMEDS_Study_i* theStudy,
+                       const TDF_Label& theLabel)
+{
+  SALOMEDS_Study_i::TSObjectHolder aSObjectHolder;
+  SALOMEDS_Study_i::TSObjectMap& anSObjectMap = theStudy->GetSObjectMap();
+  SALOMEDS_Study_i::TSObjectMap::const_iterator anIter = anSObjectMap.find(theLabel);
+  if(anIter != anSObjectMap.end())
+    aSObjectHolder = anIter->second;
+  else{
+    SALOMEDS_SObject_i* aSObject = new SALOMEDS_SObject_i(theStudy,theLabel);
+    aSObjectHolder.first = aSObject;
+    aSObjectHolder.second = aSObject->_this();
+    anSObjectMap[theLabel] = aSObjectHolder;
+
+    //TCollection_AsciiString anEntry;
+    //TDF_Tool::Entry(theLabel,anEntry);
+    //cout<<"APO - SALOMEDS_SObject_i::New - anEntry = "<<anEntry.ToCString()<<endl;
+  }
+  return aSObjectHolder;
+}
+
+SALOMEDS_SObject_i*
+SALOMEDS_SObject_i::NewPtr(SALOMEDS_Study_i* theStudy,
+                          const TDF_Label& theLabel)
 {
-  if      (ID == TDataStd_Name::GetID())                        return "AttributeName";
-  else if (ID == TDataStd_Comment::GetID())                     return "AttributeComment";
-  else if (ID == SALOMEDS_IORAttribute::GetID())                return "AttributeIOR"; 
-  else if (ID == SALOMEDS_PersRefAttribute::GetID())            return "AttributePersistentRef";
-  else if (ID == TDataStd_Real::GetID())                        return "AttributeReal";
-  else if (ID == TDataStd_Integer::GetID())                     return "AttributeInteger";
-  else if (ID == SALOMEDS_SequenceOfRealAttribute::GetID())     return "AttributeSequenceOfReal";
-  else if (ID == SALOMEDS_SequenceOfIntegerAttribute::GetID())  return "AttributeSequenceOfInteger";
-  else if (ID == SALOMEDS_DrawableAttribute::GetID())           return "AttributeDrawable";
-  else if (ID == SALOMEDS_SelectableAttribute::GetID())         return "AttributeSelectable";
-  else if (ID == SALOMEDS_ExpandableAttribute::GetID())         return "AttributeExpandable";
-  else if (ID == SALOMEDS_OpenedAttribute::GetID())             return "AttributeOpened";
-  else if (ID == SALOMEDS_TextColorAttribute::GetID())          return "AttributeTextColor";
-  else if (ID == SALOMEDS_TextHighlightColorAttribute::GetID()) return "AttributeTextHighlightColor";
-  else if (ID == SALOMEDS_PixMapAttribute::GetID())             return "AttributePixMap";
-  else if (ID == TDataStd_TreeNode::GetDefaultTreeID())         return "AttributeTreeNode";
-  else if (ID == SALOMEDS_LocalIDAttribute::GetID())            return "AttributeLocalID";
-  else if (ID == SALOMEDS_TargetAttribute::GetID())             return "AttributeTarget";
-  else if (ID == SALOMEDS_TableOfIntegerAttribute::GetID())     return "AttributeTableOfInteger";
-  else if (ID == SALOMEDS_TableOfRealAttribute::GetID())        return "AttributeTableOfReal";
-  else if (ID == SALOMEDS_TableOfStringAttribute::GetID())      return "AttributeTableOfString";
-  else if (ID == SALOMEDS_StudyPropertiesAttribute::GetID())    return "AttributeStudyProperties";
-  else if (ID == SALOMEDS_PythonObjectAttribute::GetID())       return "AttributePythonObject";
-  else if (ID == SALOMEDS_AttributeUserID_i::DefaultID())       return "AttributeUserID";
-  // 08.01.2003 mpv: this method must be called only for attributes with constant GUID
-  else Standard_NoSuchObject::Raise("SALOMEDS_SObject_i::AttributeIDToType");
+  return New(theStudy,theLabel).first;
 }
 
+SALOMEDS::SObject_var
+SALOMEDS_SObject_i::NewRef(SALOMEDS_Study_i* theStudy,
+                          const TDF_Label& theLabel)
+{
+  return New(theStudy,theLabel).second;
+}
 
 //============================================================================
 /*! Function : constructor
  *  Purpose  : 
  */
 //============================================================================
-SALOMEDS_SObject_i::SALOMEDS_SObject_i(const TDF_Label lab, CORBA::ORB_ptr orb)
-  :_lab(lab)
+SALOMEDS_SObject_i::SALOMEDS_SObject_i(SALOMEDS_Study_i* theStudy,
+                                      const TDF_Label& theLabel):
+  _lab(theLabel),
+  _study(theStudy)
 {
-  _orb = CORBA::ORB::_duplicate(orb);
-  _value = NULL;
-  _type = NULL;
-  _name = NULL;
-  _liste_ba_type.resize(0);
 }
-  
 
 //============================================================================
 /*! Function : destructor
@@ -171,12 +331,23 @@ SALOMEDS_SObject_i::SALOMEDS_SObject_i(const TDF_Label lab, CORBA::ORB_ptr orb)
 //============================================================================
 SALOMEDS_SObject_i::~SALOMEDS_SObject_i()
 {
-  CORBA::string_free(_value);
-  CORBA::string_free(_type);
-  CORBA::string_free(_name);
 }
   
-  
+
+//============================================================================
+CORBA::ORB_var SALOMEDS_SObject_i::GetORB() const
+{
+  return _study->GetORB();
+}
+
+
+//============================================================================
+PortableServer::POA_var SALOMEDS_SObject_i::GetPOA() const
+{
+  return _study->GetPOA();
+}
+
+
 //============================================================================
 /*! Function :
  *  Purpose  : 
@@ -185,7 +356,7 @@ SALOMEDS_SObject_i::~SALOMEDS_SObject_i()
 char* SALOMEDS_SObject_i::GetID()
 {
   TCollection_AsciiString anEntry;
-  TDF_Tool::Entry (_lab,anEntry);
+  TDF_Tool::Entry(_lab,anEntry);
   return CORBA::string_dup(anEntry.ToCString());
 }
   
@@ -196,14 +367,11 @@ char* SALOMEDS_SObject_i::GetID()
 //============================================================================
 SALOMEDS::SComponent_ptr SALOMEDS_SObject_i::GetFatherComponent()
 {
-  TDF_Label LF = _lab;
-  while (!SALOMEDS_SComponent_i::IsA(LF) && !LF.IsRoot()) {
-    LF = LF.Father();
+  TDF_Label aSCompLabel = _lab;
+  while(!SALOMEDS_SComponent_i::IsA(aSCompLabel) && !aSCompLabel.IsRoot()){
+    aSCompLabel = aSCompLabel.Father();
   }
-  SALOMEDS_SComponent_i *  so_servant = new SALOMEDS_SComponent_i (LF,_orb);
-  SALOMEDS::SComponent_var so;
-  so= SALOMEDS::SComponent::_narrow(so_servant->SComponent::_this()); 
-  return so;
+  return SALOMEDS_SComponent_i::NewRef(_study,aSCompLabel)._retn();
 }
   
 //============================================================================
@@ -213,11 +381,7 @@ SALOMEDS::SComponent_ptr SALOMEDS_SObject_i::GetFatherComponent()
 //============================================================================
 SALOMEDS::SObject_ptr SALOMEDS_SObject_i::GetFather()
 {
-  TDF_Label LF = _lab.Father();
-
-  SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (LF,_orb);
-  SALOMEDS::SObject_var so = SALOMEDS::SObject::_narrow(so_servant->_this()); 
-  return so;
+  return SALOMEDS_SObject_i::NewRef(_study,_lab.Father())._retn();
 }
 
 //============================================================================
@@ -227,296 +391,21 @@ SALOMEDS::SObject_ptr SALOMEDS_SObject_i::GetFather()
 //============================================================================
 SALOMEDS::Study_ptr SALOMEDS_SObject_i::GetStudy()
 {
-  TDF_Label Root = _lab.Root();
-  Handle(SALOMEDS_IORAttribute) Att;
-  char* IOR;
-  if (Root.FindAttribute(SALOMEDS_IORAttribute::GetID(),Att)){
-    TCollection_AsciiString ch(Att->Get());
-    IOR = CORBA::string_dup(ch.ToCString());
-    CORBA::Object_var obj = _orb->string_to_object(IOR);
-    SALOMEDS::Study_var Study = SALOMEDS::Study::_narrow(obj) ;
-    ASSERT(!CORBA::is_nil(Study));
-    return SALOMEDS::Study::_duplicate(Study); //return Study = abort...
-  }
-  INFOS("Problem GetStudy");
-  return SALOMEDS::Study::_nil();
-}
-
-//============================================================================
-/*! Function : FindAttribute
- *  Purpose  : Find attribute of given type on this SObject
- */
-//============================================================================
-CORBA::Boolean SALOMEDS_SObject_i::FindAttribute (SALOMEDS::GenericAttribute_out anAttribute, 
-                                                 const char* aTypeOfAttribute)
-{
-  Handle(TDF_Attribute) anAttr;
-  Standard_Boolean found = _lab.FindAttribute(SALOMEDS_SObject_i::ReturnGUIDForAttribute(aTypeOfAttribute), anAttr);
-  if (found) {
-    if (strcmp(aTypeOfAttribute, "AttributeReal") == 0 )  {
-      SALOMEDS_AttributeReal_i* Attr = new SALOMEDS_AttributeReal_i(Handle(TDataStd_Real)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeReal::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributeInteger") == 0 )  {
-      SALOMEDS_AttributeInteger_i* Attr = new SALOMEDS_AttributeInteger_i(Handle(TDataStd_Integer)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeInteger::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributeSequenceOfReal") == 0 )  {
-      SALOMEDS_AttributeSequenceOfReal_i* Attr = new SALOMEDS_AttributeSequenceOfReal_i(Handle(SALOMEDS_SequenceOfRealAttribute)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeSequenceOfReal::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributeSequenceOfInteger") == 0 )  {
-      SALOMEDS_AttributeSequenceOfInteger_i* Attr = new SALOMEDS_AttributeSequenceOfInteger_i(Handle(SALOMEDS_SequenceOfIntegerAttribute)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeSequenceOfInteger::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributeName") == 0 ) {
-      SALOMEDS_AttributeName_i* Attr = new SALOMEDS_AttributeName_i(Handle(TDataStd_Name)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeName::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributeComment") == 0 ) {
-      SALOMEDS_AttributeComment_i* Attr = new SALOMEDS_AttributeComment_i(Handle(TDataStd_Comment)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeComment::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributeIOR") == 0 ) {
-      SALOMEDS_AttributeIOR_i* Attr = new SALOMEDS_AttributeIOR_i(Handle(SALOMEDS_IORAttribute)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeIOR::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributePersistentRef") == 0 )  {
-      SALOMEDS_AttributePersistentRef_i* Attr = new SALOMEDS_AttributePersistentRef_i(Handle(SALOMEDS_PersRefAttribute)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributePersistentRef::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributeDrawable") == 0 )  {
-      SALOMEDS_AttributeDrawable_i* Attr = new SALOMEDS_AttributeDrawable_i(Handle(SALOMEDS_DrawableAttribute)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeDrawable::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributeSelectable") == 0 )  {
-      SALOMEDS_AttributeSelectable_i* Attr= new SALOMEDS_AttributeSelectable_i(Handle(SALOMEDS_SelectableAttribute)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeSelectable::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributeExpandable") == 0 )  {
-      SALOMEDS_AttributeExpandable_i* Attr = new SALOMEDS_AttributeExpandable_i(Handle(SALOMEDS_ExpandableAttribute)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeExpandable::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributeOpened") == 0 )  {
-      SALOMEDS_AttributeOpened_i* Attr= new SALOMEDS_AttributeOpened_i(Handle(SALOMEDS_OpenedAttribute)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeOpened::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributeTextColor") == 0 )  {
-      SALOMEDS_AttributeTextColor_i* Attr= new SALOMEDS_AttributeTextColor_i(Handle(SALOMEDS_TextColorAttribute)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeTextColor::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributeTextHighlightColor") == 0 )  {
-      SALOMEDS_AttributeTextHighlightColor_i* Attr= new SALOMEDS_AttributeTextHighlightColor_i(Handle(SALOMEDS_TextHighlightColorAttribute)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeTextHighlightColor::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributePixMap") == 0 )  {
-      SALOMEDS_AttributePixMap_i* Attr= new SALOMEDS_AttributePixMap_i(Handle(SALOMEDS_PixMapAttribute)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributePixMap::_this();
-      return Standard_True;
-    }
-    else if (strncmp(aTypeOfAttribute, "AttributeTreeNode",17) == 0 )  {
-      SALOMEDS_AttributeTreeNode_i* Attr= new SALOMEDS_AttributeTreeNode_i(Handle(TDataStd_TreeNode)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeTreeNode::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributeLocalID") == 0 )  {
-      SALOMEDS_AttributeLocalID_i* Attr= new SALOMEDS_AttributeLocalID_i(Handle(SALOMEDS_LocalIDAttribute)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeLocalID::_this();
-      return Standard_True;
-    }
-    else if (strncmp(aTypeOfAttribute, "AttributeUserID",15) == 0 )  {
-      SALOMEDS_AttributeUserID_i* Attr= new SALOMEDS_AttributeUserID_i(Handle(TDataStd_UAttribute)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeUserID::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributeTarget") == 0 )  {
-      SALOMEDS_AttributeTarget_i* Attr= new SALOMEDS_AttributeTarget_i(Handle(SALOMEDS_TargetAttribute)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeTarget::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributeTableOfInteger") == 0 )  {
-      SALOMEDS_AttributeTableOfInteger_i* Attr = new SALOMEDS_AttributeTableOfInteger_i(Handle(SALOMEDS_TableOfIntegerAttribute)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeTableOfInteger::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributeTableOfReal") == 0 )  {
-      SALOMEDS_AttributeTableOfReal_i* Attr = new SALOMEDS_AttributeTableOfReal_i(Handle(SALOMEDS_TableOfRealAttribute)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeTableOfReal::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributeTableOfString") == 0 )  {
-      SALOMEDS_AttributeTableOfString_i* Attr = new SALOMEDS_AttributeTableOfString_i(Handle(SALOMEDS_TableOfStringAttribute)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeTableOfString::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributeStudyProperties") == 0 )  {
-      SALOMEDS_AttributeStudyProperties_i* Attr = new SALOMEDS_AttributeStudyProperties_i(Handle(SALOMEDS_StudyPropertiesAttribute)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributeStudyProperties::_this();
-      return Standard_True;
-    }
-    else if (strcmp(aTypeOfAttribute, "AttributePythonObject") == 0 )  {
-      SALOMEDS_AttributePythonObject_i* Attr = new SALOMEDS_AttributePythonObject_i(Handle(SALOMEDS_PythonObjectAttribute)::DownCast(anAttr), _orb);
-      anAttribute = Attr->AttributePythonObject::_this();
-      return Standard_True;
-    }
-  } else return Standard_False;
+  return _study->_this();
 }
 
-//============================================================================
-/*! Function : GetAllAttributes
- *  Purpose  : Returns list of all attributes for this sobject
- */
-//============================================================================
-
-SALOMEDS::ListOfAttributes* SALOMEDS_SObject_i::GetAllAttributes()
-{
-  Standard_Integer NumAttr = _lab.NbAttributes();
-  SALOMEDS::ListOfAttributes_var SeqOfAttr = new SALOMEDS::ListOfAttributes;
-  SeqOfAttr->length(NumAttr);
-  if (NumAttr != 0) {
-    Standard_Integer i = 0;
-    for(TDF_AttributeIterator iter(_lab);iter.More();iter.Next()) {
-      Handle(TDF_Attribute) anAttr = iter.Value();
-      SALOMEDS::GenericAttribute_var anAttribute;
-      if (ReturnGUIDForAttribute("AttributeReal") == anAttr->ID()) {
-        SALOMEDS_AttributeReal_i* Attr= new SALOMEDS_AttributeReal_i(Handle(TDataStd_Real)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeReal::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributeInteger") == anAttr->ID()) {
-        SALOMEDS_AttributeInteger_i* Attr= new SALOMEDS_AttributeInteger_i(Handle(TDataStd_Integer)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeInteger::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributeSequenceOfReal") == anAttr->ID()) {
-        SALOMEDS_AttributeSequenceOfReal_i* Attr= new SALOMEDS_AttributeSequenceOfReal_i(Handle(SALOMEDS_SequenceOfRealAttribute)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeSequenceOfReal::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributeSequenceOfInteger") == anAttr->ID()) {
-        SALOMEDS_AttributeSequenceOfInteger_i* Attr= new SALOMEDS_AttributeSequenceOfInteger_i(Handle(SALOMEDS_SequenceOfIntegerAttribute)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeSequenceOfInteger::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributeName") == anAttr->ID()) {
-        SALOMEDS_AttributeName_i* Attr= new SALOMEDS_AttributeName_i(Handle(TDataStd_Name)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeName::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributeComment") == anAttr->ID()) {
-        SALOMEDS_AttributeComment_i* Attr= new SALOMEDS_AttributeComment_i(Handle(TDataStd_Comment)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeComment::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributeIOR") == anAttr->ID()) {
-        SALOMEDS_AttributeIOR_i* Attr= new SALOMEDS_AttributeIOR_i(Handle(SALOMEDS_IORAttribute)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeIOR::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributePersistentRef") == anAttr->ID()) {
-        SALOMEDS_AttributePersistentRef_i* Attr= new SALOMEDS_AttributePersistentRef_i(Handle(SALOMEDS_PersRefAttribute)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributePersistentRef::_this();
-      }
-      else if (ReturnGUIDForAttribute("AttributeDrawable") == anAttr->ID()) {
-        SALOMEDS_AttributeDrawable_i* Attr= new SALOMEDS_AttributeDrawable_i(Handle(SALOMEDS_DrawableAttribute)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeDrawable::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributeSelectable") == anAttr->ID()) {
-        SALOMEDS_AttributeSelectable_i* Attr= new SALOMEDS_AttributeSelectable_i(Handle(SALOMEDS_SelectableAttribute)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeSelectable::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributeExpandable") == anAttr->ID()) {
-        SALOMEDS_AttributeExpandable_i* Attr= new SALOMEDS_AttributeExpandable_i(Handle(SALOMEDS_ExpandableAttribute)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeExpandable::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributeOpened") == anAttr->ID()) {
-        SALOMEDS_AttributeOpened_i* Attr= new SALOMEDS_AttributeOpened_i(Handle(SALOMEDS_OpenedAttribute)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeOpened::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributeTextColor") == anAttr->ID()) {
-        SALOMEDS_AttributeTextColor_i* Attr= new SALOMEDS_AttributeTextColor_i(Handle(SALOMEDS_TextColorAttribute)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeTextColor::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributeTextHighlightColor") == anAttr->ID()) {
-        SALOMEDS_AttributeTextHighlightColor_i* Attr= new SALOMEDS_AttributeTextHighlightColor_i(Handle(SALOMEDS_TextHighlightColorAttribute)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeTextHighlightColor::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributePixMap") == anAttr->ID()) {
-        SALOMEDS_AttributePixMap_i* Attr= new SALOMEDS_AttributePixMap_i(Handle(SALOMEDS_PixMapAttribute)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributePixMap::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributeTreeNode") == anAttr->ID()) {
-        SALOMEDS_AttributeTreeNode_i* Attr= new SALOMEDS_AttributeTreeNode_i(Handle(TDataStd_TreeNode)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeTreeNode::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributeLocalID") == anAttr->ID()) {
-        SALOMEDS_AttributeLocalID_i* Attr= new SALOMEDS_AttributeLocalID_i(Handle(SALOMEDS_LocalIDAttribute)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeLocalID::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributeTarget") == anAttr->ID()) {
-        SALOMEDS_AttributeTarget_i* Attr= new SALOMEDS_AttributeTarget_i(Handle(SALOMEDS_TargetAttribute)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeTarget::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributeTableOfInteger") == anAttr->ID()) {
-        SALOMEDS_AttributeTableOfInteger_i* Attr= new SALOMEDS_AttributeTableOfInteger_i(Handle(SALOMEDS_TableOfIntegerAttribute)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeTableOfInteger::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributeTableOfReal") == anAttr->ID()) {
-        SALOMEDS_AttributeTableOfReal_i* Attr= new SALOMEDS_AttributeTableOfReal_i(Handle(SALOMEDS_TableOfRealAttribute)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeTableOfReal::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributeTableOfString") == anAttr->ID()) {
-        SALOMEDS_AttributeTableOfString_i* Attr= new SALOMEDS_AttributeTableOfString_i(Handle(SALOMEDS_TableOfStringAttribute)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeTableOfString::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributeStudyProperties") == anAttr->ID()) {
-        SALOMEDS_AttributeStudyProperties_i* Attr= new SALOMEDS_AttributeStudyProperties_i(Handle(SALOMEDS_StudyPropertiesAttribute)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeStudyProperties::_this();
-      } 
-      else if (ReturnGUIDForAttribute("AttributePythonObject") == anAttr->ID()) {
-        SALOMEDS_AttributePythonObject_i* Attr= new SALOMEDS_AttributePythonObject_i(Handle(SALOMEDS_PythonObjectAttribute)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributePythonObject::_this();
-      } 
-      else if (!Handle(TDataStd_UAttribute)::DownCast(anAttr).IsNull()) {
-        SALOMEDS_AttributeUserID_i* Attr= new SALOMEDS_AttributeUserID_i(Handle(TDataStd_UAttribute)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeUserID::_this();
-      } 
-      else if (!Handle(TDataStd_TreeNode)::DownCast(anAttr).IsNull()) {
-        SALOMEDS_AttributeTreeNode_i* Attr= new SALOMEDS_AttributeTreeNode_i(Handle(TDataStd_TreeNode)::DownCast(anAttr), _orb);
-        anAttribute = Attr->AttributeTreeNode::_this();
-      } else {
-       // references attributes, for an example, never returns
-       continue;
-      }
-
-      SeqOfAttr[i] =  anAttribute;
-      i++;
-    }
-  }
-  return SeqOfAttr._retn();
-}
-
-
 //============================================================================
 /*! Function : ReferencedObject
  *  Purpose  : 
  */
 //============================================================================
-CORBA::Boolean SALOMEDS_SObject_i::ReferencedObject(SALOMEDS::SObject_out obj)
+CORBA::Boolean SALOMEDS_SObject_i::ReferencedObject(SALOMEDS::SObject_out theSObject)
 {
-  Handle(TDF_Reference) Ref;
-  if (!_lab.FindAttribute(TDF_Reference::GetID(),Ref))
+  Handle(TDF_Reference) aRef;
+  if (!_lab.FindAttribute(TDF_Reference::GetID(),aRef))
     return false;
   
-  SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (Ref->Get(),_orb);
-  obj  = SALOMEDS::SObject::_narrow(so_servant->_this()); 
+  theSObject = SALOMEDS_SObject_i::NewRef(_study,aRef->Get())._retn(); 
   return true;
 }
 
@@ -525,15 +414,14 @@ CORBA::Boolean SALOMEDS_SObject_i::ReferencedObject(SALOMEDS::SObject_out obj)
  *  Purpose  : 
  */
 //============================================================================
-CORBA::Boolean SALOMEDS_SObject_i::FindSubObject(long atag, SALOMEDS::SObject_out obj)
+CORBA::Boolean SALOMEDS_SObject_i::FindSubObject(CORBA::Long theTag, SALOMEDS::SObject_out theSObject)
 {
-  TDF_Label L = _lab.FindChild(atag,false);
-  if (L.IsNull()) return false;
+  TDF_Label aLabel = _lab.FindChild(theTag,false);
+  if(aLabel.IsNull()) 
+    return false;
   
-  SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (L,_orb);
-  obj  = SALOMEDS::SObject::_narrow(so_servant->_this()); 
+  theSObject = SALOMEDS_SObject_i::NewRef(_study,aLabel)._retn(); 
   return true;
-    
 }  
 
 //============================================================================
@@ -543,7 +431,7 @@ CORBA::Boolean SALOMEDS_SObject_i::FindSubObject(long atag, SALOMEDS::SObject_ou
 //============================================================================
 char* SALOMEDS_SObject_i::Name()
 {
-  return CORBA::string_dup(_name);
+  return CORBA::string_dup(_name.c_str());
 }
   
 //============================================================================
@@ -551,9 +439,9 @@ char* SALOMEDS_SObject_i::Name()
  *  Purpose  : 
  */
 //============================================================================
-void  SALOMEDS_SObject_i::Name(const char* name)
+void  SALOMEDS_SObject_i::Name(const char* theName)
 {
-  _name = CORBA::string_dup(name);
+  _name = theName;
 }
   
 //============================================================================
@@ -565,3 +453,320 @@ CORBA::Short SALOMEDS_SObject_i::Tag()
 {
   return _lab.Tag();
 }
+
+//============================================================================
+/*! Function :
+ *  Purpose  : 
+ */
+//============================================================================
+CORBA::Short SALOMEDS_SObject_i::Depth()
+{
+  return _lab.Depth();
+}
+
+//============================================================================
+/*! Function :
+ *  Purpose  : 
+ */
+//============================================================================
+CORBA::Object_ptr SALOMEDS_SObject_i::GetObject()
+{
+  try {
+    Handle(SALOMEDS_IORAttribute) anAttr;
+    if(_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr)){
+      CORBA::ORB_var anORB = _study->GetStudyManager()->GetORB();
+      return anORB->string_to_object(Str(anAttr->Get()));
+    }
+  }catch(...){
+  }
+  return CORBA::Object::_nil();
+}
+
+//============================================================================
+/*! Function :
+ *  Purpose  : 
+ */
+//============================================================================
+char* SALOMEDS_SObject_i::GetName() {
+  Handle(TDataStd_Name) anAttr;
+  if(_lab.FindAttribute(TDataStd_Name::GetID(),anAttr))
+    return CORBA::string_dup(Str(anAttr->Get()));
+
+  return CORBA::string_dup("");
+}
+
+//============================================================================
+/*! Function :
+ *  Purpose  : 
+ */
+//============================================================================
+char* SALOMEDS_SObject_i::GetComment() {
+  Handle(TDataStd_Comment) anAttr;
+  if(_lab.FindAttribute(TDataStd_Comment::GetID(), anAttr))
+    return CORBA::string_dup(Str(anAttr->Get()));
+
+  return CORBA::string_dup("");
+}
+
+//============================================================================
+/*! Function :
+ *  Purpose  : 
+ */
+//============================================================================
+char* SALOMEDS_SObject_i::GetIOR() {
+  Handle(SALOMEDS_IORAttribute) anAttr;
+  if(_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr))
+    return CORBA::string_dup(Str(anAttr->Get()));
+
+  return CORBA::string_dup("");
+}
+
+
+//============================================================================
+/*! Function : GetAllAttributes
+ *  Purpose  : Returns list of all attributes for this sobject
+ */
+//============================================================================
+SALOMEDS_SObject_i::TAttrHolder 
+SALOMEDS_SObject_i::_FindGenAttribute(const Handle(TDF_Attribute)& theAttr)
+{
+  TAttrHolder anGenAttr;
+
+  Standard_GUID aGUID = theAttr->ID();
+
+  TGUID2AttrIDMap::const_iterator anIter = __GUID2AttrIDMap__.find(aGUID);
+  if(anIter != __GUID2AttrIDMap__.end()){
+    const TAttributeID& anAttributeID = anIter->second;
+    anGenAttr = _FindGenAttribute(anAttributeID.c_str());
+  }
+
+  return anGenAttr;
+}
+
+
+SALOMEDS::ListOfAttributes* SALOMEDS_SObject_i::GetAllAttributes()
+{
+  SALOMEDS::ListOfAttributes_var aSeqOfAttr = new SALOMEDS::ListOfAttributes;
+  if(_lab.NbAttributes() > 0){
+    Standard_Integer i = 0;
+    for(TDF_AttributeIterator iter(_lab); iter.More(); iter.Next()) {
+      Handle(TDF_Attribute) anAttr = iter.Value();
+      TAttrHolder anAttrHolder = _FindGenAttribute(anAttr);
+      SALOMEDS::GenericAttribute_var anGenAttr = anAttrHolder.second;
+      if(!anGenAttr->_is_nil())
+      {
+       aSeqOfAttr->length(++i);
+       aSeqOfAttr[i-1] = anGenAttr._retn();
+      }
+    }
+  }
+
+  return aSeqOfAttr._retn();
+}
+
+
+//============================================================================
+/*! Function : FindAttribute
+ *  Purpose  : Find attribute of given type on this SObject
+ */
+//============================================================================
+SALOMEDS_SObject_i::TAttrHolder 
+SALOMEDS_SObject_i::_CreateGenAttribute(const Handle(TDF_Attribute)& theAttr,
+                                       const char* theType) 
+{
+  SALOMEDS_GenericAttribute_i* anAttr;
+  TAttrID2FunMap::const_iterator anIter = __AttrID2FunMap__.find(theType);
+  if(anIter != __AttrID2FunMap__.end()){
+    const TAttrID2FunMap::data_type& aValue = anIter->second;
+    
+    if(aValue.myIsCheckLockedStudy())
+      _study->CheckLocked();
+    
+    anAttr = aValue.myNewInstance(theAttr,this);
+    return TAttrHolder(anAttr,anAttr->_this());
+  }
+  
+  if(strncmp(theType,"AttributeTreeNode",17) == 0){
+    anAttr = new SALOMEDS_AttributeTreeNode_i(theAttr,this);
+    return TAttrHolder(anAttr,anAttr->_this());
+  }
+  
+  if(strncmp(theType,"AttributeUserID",15) == 0){
+    anAttr =  new SALOMEDS_AttributeUserID_i(theAttr,this);
+    return TAttrHolder(anAttr,anAttr->_this());
+  }
+  
+  return TAttrHolder();
+}
+
+
+SALOMEDS_SObject_i::TAttrHolder 
+SALOMEDS_SObject_i::_FindGenAttribute(const char* theType)
+{
+  TAttrHolder anAttrHolder;
+  TAttrMap::const_iterator anIter = myAttrMap.find(theType);
+  if(anIter != myAttrMap.end())
+    anAttrHolder = anIter->second;
+
+  Standard_GUID aGUID = ::GetGUID(theType);
+  Handle(TDF_Attribute) anAttr;
+
+  if(_lab.FindAttribute(aGUID,anAttr)){
+    SALOMEDS_GenericAttribute_i* aGenAttr = anAttrHolder.first;
+    if(aGenAttr != NULL){
+      if(aGenAttr->GetAttribute() != anAttr)
+       aGenAttr->SetAttribute(anAttr);
+    }else{
+      anAttrHolder = _CreateGenAttribute(anAttr,theType);
+    }
+    aGenAttr = anAttrHolder.first;
+    if(aGenAttr != NULL)
+      myAttrMap[theType] = anAttrHolder;
+  }else{
+    //myAttrMap.erase(theType);
+    //if(anGenAttr != NULL)
+    //  anGenAttr->Destroy();
+    return TAttrHolder();
+  }
+
+  return anAttrHolder;
+}
+
+
+SALOMEDS::GenericAttribute_ptr 
+SALOMEDS_SObject_i::_FindCORBAAttribute(const char* theType)
+{
+  TAttrHolder anAttr = _FindGenAttribute(theType);
+  SALOMEDS::GenericAttribute_var anGenAttr = anAttr.second;
+  if(!CORBA::is_nil(anGenAttr)){
+    return anGenAttr._retn();
+  }
+
+  return SALOMEDS::GenericAttribute::_nil();
+}
+
+
+CORBA::Boolean 
+SALOMEDS_SObject_i::FindAttribute(SALOMEDS::GenericAttribute_out theAttribute, 
+                                 const char* theType)
+{
+  theAttribute = _FindCORBAAttribute(theType);
+  return !CORBA::is_nil(theAttribute);
+}
+
+
+//============================================================================
+/*! Function : FindAttribute
+ *  Purpose  : Find attribute of given type on this SObject
+ */
+//============================================================================
+Handle(TDF_Attribute) 
+  SALOMEDS_SObject_i::_AddAttribute(const char* theType) 
+{
+  Handle(TDF_Attribute) anAttr;
+  TAttrID2FunMap::const_iterator anIter = __AttrID2FunMap__.find(theType);
+  if(anIter != __AttrID2FunMap__.end()){
+    const TAttrID2FunMap::data_type& aValue = anIter->second;
+    
+    if(aValue.myIsCheckLockedStudy())
+      _study->CheckLocked();
+    
+    anAttr = aValue.myNewAttribute();
+    _lab.AddAttribute(anAttr);
+    return anAttr;
+  }
+  
+  if(strncmp(theType, "AttributeTreeNode",17) == 0){
+    Standard_GUID aGUID;
+    if(strcmp(theType, "AttributeTreeNode") == 0){
+      aGUID = TDataStd_TreeNode::GetDefaultTreeID();
+    }else{
+      char aString[40] = "";
+      sprintf(aString, &theType[21]);
+      aGUID = Standard_GUID(aString); // create tree node GUID by name
+    }
+    if(!_lab.FindAttribute(aGUID,anAttr)){
+      _study->CheckLocked();
+      anAttr = TDataStd_TreeNode::Set(_lab,aGUID);
+      _lab.AddAttribute(anAttr);
+      return anAttr;
+    }
+  }
+  
+  if(strncmp(theType, "AttributeUserID",15) == 0){
+    Standard_GUID aGUID = SALOMEDS_AttributeUserID_i::GetGUID();
+    if(!_lab.FindAttribute(aGUID,anAttr)){
+      _study->CheckLocked();
+      anAttr = TDataStd_UAttribute::Set(_lab,aGUID);
+      _lab.AddAttribute(anAttr);
+      return anAttr;
+    }
+  }
+  
+  
+  return anAttr;
+}
+
+
+SALOMEDS::GenericAttribute_ptr 
+SALOMEDS_SObject_i::FindOrCreateAttribute(const char* theType)
+{
+  TAttrHolder anAttrHolder = _FindGenAttribute(theType);
+  SALOMEDS::GenericAttribute_var anGenAttr = anAttrHolder.second;
+  if(!anGenAttr->_is_nil())
+    return anGenAttr._retn();
+
+  Handle(TDF_Attribute) anAttr = _AddAttribute(theType);
+  if(!anAttr.IsNull()){
+    anAttrHolder = _CreateGenAttribute(anAttr,theType);
+    anGenAttr = anAttrHolder.second;
+    if(!anGenAttr->_is_nil())
+      return anGenAttr._retn();
+  }
+
+  return SALOMEDS::GenericAttribute::_nil();
+}
+
+
+//============================================================================
+/*! Function : FindAttribute
+ *  Purpose  : Find attribute of given type on this SObject
+ */
+//============================================================================
+void SALOMEDS_SObject_i::RemoveAttribute(const char* theType)
+{
+  _study->CheckLocked();
+  if(strcmp(theType, "AttributeIOR") == 0) { // postponed removing of CORBA objects
+    Handle(SALOMEDS_IORAttribute) anAttr;
+    if(_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(), anAttr))
+      _study->AddPostponed(Str(anAttr->Get()));
+    else 
+      return;
+  }
+  TAttrMap::iterator anIter = myAttrMap.find(theType);
+  if(anIter != myAttrMap.end()){
+    //myAttrMap.erase(anIter);
+  }
+  _lab.ForgetAttribute(::GetGUID(theType));
+}
+
+
+void SALOMEDS_SObject_i::OnRemove()
+{
+  Handle(TDF_Reference) aReference;
+  if(_lab.FindAttribute(TDF_Reference::GetID(),aReference)){
+    Handle(SALOMEDS_TargetAttribute) aTarget;
+    if(aReference->Get().FindAttribute(SALOMEDS_TargetAttribute::GetID(),aTarget))
+      aTarget->Remove(_lab);
+  }
+
+  Handle(SALOMEDS_IORAttribute) anAttr; // postponed removing of CORBA objects
+  if(_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr)){
+    _study->AddPostponed(TCollection_AsciiString(anAttr->Get()).ToCString());
+  }
+
+  //myAttrMap.clear();
+
+  //SALOMEDS_Study_i::TSObjectMap& anSObjectMap = _study->GetSObjectMap();
+  //anSObjectMap.erase(_lab);
+}