Salome HOME
Fix on [Bug PAL7750] Regression of UNDO in GEOM
[modules/kernel.git] / src / SALOMEDS / SALOMEDS_Study_i.cxx
index ae4a1f0768fa1f9cebb1f5044b27831fea7bcdbb..1f8e0aa75067bc52597819a1a6e0a3bb702dd13a 100644 (file)
-using namespace std;
-//  File      : SALOMEDS_Study_i.cxx
-//  Created   : Wed Nov 28 16:27:23 2001
-//  Author    : Yves FRICAUD
-
-//  Project   : SALOME
-//  Module    : SALOMEDS
-//  Copyright : Open CASCADE 2001
+//  SALOME SALOMEDS : data structure of SALOME and sources of Salome data server 
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SALOMEDS_Study_i.cxx
+//  Author : Yves FRICAUD
+//  Module : SALOME
 //  $Header$
 
-#include "utilities.h"
-#include "SALOMEDS_Study_i.hxx"
-
-#include "SALOMEDS_DataMapIteratorOfDataMapStringLabel.hxx"
-#include <TColStd_SequenceOfExtendedString.hxx>
-#include <TCollection_AsciiString.hxx>
-#include <TCollection_ExtendedString.hxx>
 #include <TDataStd_ChildNodeIterator.hxx>
 #include <TDocStd_Application.hxx>
 #include <TDocStd_Owner.hxx>
 #include <CDM_Document.hxx>
 #include <CDM_Application.hxx>
+#include <TDF_ChildIDIterator.hxx>
+
+#include <TColStd_SequenceOfExtendedString.hxx>
+#include <TCollection_ExtendedString.hxx>
+#include <TCollection_AsciiString.hxx>
+
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
+#include <TColStd_ListOfInteger.hxx>
+
+#include "SALOMEDS_Study_i.hxx"
+
+#include "SALOMEDS_StudyManager_i.hxx"
+#include "SALOMEDS_Callback_i.hxx"
+
+#include "SALOMEDS_SComponent_i.hxx"
+#include "SALOMEDS_SObject_i.hxx"
+
+#include "SALOMEDS_StudyBuilder_i.hxx"
+#include "SALOMEDS_ChildIterator_i.hxx"
+
+#include "SALOMEDS_UseCaseBuilder_i.hxx"
+#include "SALOMEDS_SComponentIterator_i.hxx"
+
+#include "SALOME_GenericObj_i.hh"
 #include "SALOMEDS_LocalIDAttribute.hxx"
-#include "SALOMEDS_UseCaseIterator_i.hxx"
+#include "SALOMEDS_PersRefAttribute.hxx"
+
+#include "SALOMEDS_StudyPropertiesAttribute.hxx"
+#include "SALOMEDS_DataMapIteratorOfDataMapStringLabel.hxx"
 
+#include "utilities.h"
 
-#define DIRECTORYID "DIRECTORY:"
+#define DIRECTORYID 16661
 #define FILEID "FILE: "
+#define FILELOCALID 26662 
+
+using namespace std;
+
+bool operator<(const TDF_Label& theLeft, const TDF_Label& theRight)
+{
+  TColStd_ListOfInteger aTagLeftList;
+  TDF_Tool::TagList(theLeft,aTagLeftList);
+  TColStd_ListIteratorOfListOfInteger anLeftIter(aTagLeftList);
+  
+  TColStd_ListOfInteger aTagRightList;
+  TDF_Tool::TagList(theRight,aTagRightList);
+  TColStd_ListIteratorOfListOfInteger anRightIter(aTagRightList);
+  
+  for(;;){
+    Standard_Boolean aLeftMore = anLeftIter.More();
+    Standard_Boolean aRightMore = anRightIter.More();
+    
+    if(!aLeftMore && !aRightMore)
+      return Standard_False;
+    
+    if(!aLeftMore)
+      return Standard_True;
+    
+    if(!aRightMore)
+      return Standard_False;
+    
+    Standard_Integer aLeftTag = anLeftIter.Value();
+    anLeftIter.Next();
+    
+    Standard_Integer aRightTag = anRightIter.Value();
+    anRightIter.Next();
+    
+    if(aLeftTag == aRightTag)
+      continue;
+    
+    return aLeftTag < aRightTag;
+  }
+  
+  return Standard_False;
+}
 
+  
 //============================================================================
 /*! Function : SALOMEDS_Study_i
  *  Purpose  : SALOMEDS_Study_i constructor
  */
 //============================================================================
-SALOMEDS_Study_i::SALOMEDS_Study_i(const Handle(TDocStd_Document) doc,
-                                  CORBA::ORB_ptr                 orb,
-                                  const char* study_name)
+SALOMEDS_Study_i::SALOMEDS_Study_i(SALOMEDS_StudyManager_i* theStudyManager,
+                                  const Handle(TDocStd_Document)& theDoc,
+                                  const char* theStudyName):
+  _StudyManager(theStudyManager),
+  _doc(theDoc),
+  _isSaved(false),
+  _URL(NULL),
+  _StudyId(-1),
+  _autoFill(true),
+  myNbUndos(0)
 {
-  _orb = CORBA::ORB::_duplicate(orb);
-  _doc = doc;
-  _name = new char[strlen(study_name) +1];
-  strcpy(_name,study_name);
-  _isSaved = false ;
-  _URL = NULL;
-  _StudyId = -1;
-  _autoFill = true;
+  _UseCaseBuilder = new SALOMEDS_UseCaseBuilder_i(this,_doc);
+  SALOMEDS::UseCaseBuilder_var aUseCaseBuilder = _UseCaseBuilder->_this();
+
+  _Builder = new SALOMEDS_StudyBuilder_i(this,_doc);
+  SALOMEDS::StudyBuilder_var aStudyBuilder = _Builder->_this(); 
+
+  SALOMEDS_Callback_i* aCallBackServant = new SALOMEDS_Callback_i(aUseCaseBuilder);
+  _callbackOnAdd = aCallBackServant->_this();
+  _callbackOnRemove = _callbackOnAdd;
+
+  _name = new char[strlen(theStudyName) +1];
+  strcpy(_name,theStudyName);
+  myNbPostponed.Append(0);
 }
   
 //============================================================================
@@ -57,6 +150,96 @@ SALOMEDS_Study_i::~SALOMEDS_Study_i()
   delete [] _URL ;
 }  
 
+//============================================================================
+CORBA::ORB_var SALOMEDS_Study_i::GetORB() const
+{
+  return _StudyManager->GetORB();
+}
+
+//============================================================================
+PortableServer::POA_var SALOMEDS_Study_i::GetPOA() const
+{
+  return _StudyManager->GetPOA();
+}
+
+
+SALOMEDS_SObject_i* 
+SALOMEDS_Study_i::DownCast(SALOMEDS::SObject_ptr theSObject) const
+{
+  if(!CORBA::is_nil(theSObject)){
+    PortableServer::POA_var aPOA = GetPOA();
+    PortableServer::ServantBase_var aServant = SALOMEDS::GetServant(theSObject,aPOA);
+    if(aServant.in())
+      return dynamic_cast<SALOMEDS_SObject_i*>(aServant.in());
+  }
+  return NULL;
+}
+
+//============================================================================
+/*! Function : SetOnAddSObject
+ *  Purpose  : 
+ */
+//============================================================================
+SALOMEDS::Callback_ptr SALOMEDS_Study_i::SetOnAddSObject(SALOMEDS::Callback_ptr theCallback)
+{
+  SALOMEDS::Callback_var aRet = _callbackOnAdd;
+  _callbackOnAdd = SALOMEDS::Callback::_duplicate(theCallback);
+  return aRet._retn();
+}
+
+//============================================================================
+/*! Function : SetOnNewSObject
+ *  Purpose  : 
+ */
+//============================================================================
+SALOMEDS::Callback_ptr SALOMEDS_Study_i::SetOnRemoveSObject(SALOMEDS::Callback_ptr theCallback)
+{
+  SALOMEDS::Callback_var aRet = _callbackOnRemove;
+  _callbackOnAdd = SALOMEDS::Callback::_duplicate(theCallback);
+  return aRet._retn();
+}
+
+//============================================================================
+void SALOMEDS_Study_i::OnAddSObject(SALOMEDS::SObject_ptr theObject)
+{
+  if(!CORBA::is_nil(_callbackOnAdd.in()))
+    _callbackOnAdd->OnAddSObject(theObject);
+}
+
+//============================================================================
+void SALOMEDS_Study_i::OnRemoveSObject(SALOMEDS::SObject_ptr theObject)
+{
+  if(!CORBA::is_nil(_callbackOnRemove.in()))
+    _callbackOnRemove->OnRemoveSObject(theObject);
+}
+
+//============================================================================
+void SALOMEDS_Study_i::CheckLocked()
+{
+  if(_doc->HasOpenCommand()) 
+    return;
+
+  Handle(SALOMEDS_StudyPropertiesAttribute) anAttr;
+  if(_doc->Main().FindAttribute(SALOMEDS_StudyPropertiesAttribute::GetID(),anAttr))
+    if(anAttr->IsLocked())
+      throw SALOMEDS::StudyBuilder::LockProtection();
+}
+
+
+//============================================================================
+char* SALOMEDS_Study_i::ConvertObjectToIOR(CORBA::Object_ptr theObject)
+{
+  return GetORB()->object_to_string(theObject); 
+}
+
+
+//============================================================================
+CORBA::Object_ptr SALOMEDS_Study_i::ConvertIORToObject(const char* theIOR) 
+{ 
+  return GetORB()->string_to_object(theIOR); 
+}
+
+
 //============================================================================
 /*! Function : GetPersistentReference
  *  Purpose  : Get persistent reference of study (idem URL())
@@ -103,27 +286,21 @@ CORBA::Boolean SALOMEDS_Study_i::IsEmpty()
  *  Purpose  : Find a Component with ComponentDataType = aComponentName
  */
 //============================================================================
-SALOMEDS::SComponent_ptr SALOMEDS_Study_i::FindComponent (const char* aComponentName)
+SALOMEDS::SComponent_ptr 
+SALOMEDS_Study_i::FindComponent(const char* theComponentName)
 {
-  bool _find = false;
-  Standard_CString name;
-  SALOMEDS::SComponentIterator_var itcomp = NewComponentIterator();
-  SALOMEDS::SComponent_var compo;
-
-  for (; itcomp->More(); itcomp->Next()) {
-    SALOMEDS::SComponent_var SC = itcomp->Value();
-    name = SC->ComponentDataType();
-    //ED if ( TCollection_AsciiString(name).IsEqual(TCollection_AsciiString(strdup(aComponentName))) ) {
-    if(strcmp(aComponentName,name) == 0){
-      _find = true;
-      return SALOMEDS::SComponent::_narrow(SC); 
+  bool anIsFound = false;
+  SALOMEDS::SComponent_var aSComponent;
+  SALOMEDS_SComponentIterator_i aComponentIter(this,_doc);
+  for(; aComponentIter.More() && !anIsFound; aComponentIter.Next()){
+    SALOMEDS::SComponent_var aSComp = aComponentIter.Value();
+    CORBA::String_var aName = aSComp->ComponentDataType();
+    if(strcmp(theComponentName,aName.in()) == 0){
+      aSComponent = aSComp;
+      anIsFound = true;
     }
   }
-  if(!_find)
-    {
-      return SALOMEDS::SComponent::_nil();
-    }
-  return compo;
+  return aSComponent._retn();
 }
 
 //============================================================================
@@ -139,9 +316,9 @@ SALOMEDS::SComponent_ptr SALOMEDS_Study_i::FindComponentID(const char* aComponen
   char *ID;
   SALOMEDS::SComponent_ptr compo;
 
-  SALOMEDS::SComponentIterator_var itcomp = NewComponentIterator();
-  for (; itcomp->More(); itcomp->Next()) {
-    SALOMEDS::SComponent_var SC = itcomp->Value();
+  SALOMEDS_SComponentIterator_i itcomp(this,_doc);
+  for (; itcomp.More(); itcomp.Next()) {
+    SALOMEDS::SComponent_var SC = itcomp.Value();
     ID = SC->GetID();
     if(strcmp(aComponentID,ID)==0)
       {
@@ -162,34 +339,29 @@ SALOMEDS::SComponent_ptr SALOMEDS_Study_i::FindComponentID(const char* aComponen
  *  Purpose  : Find an Object with SALOMEDS::Name = anObjectName
  */
 //============================================================================
-SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObject(const char* anObjectName)
+SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObject(const char* theObjectName)
 {
   // Iterate to all components defined in the study
   // After testing the component name, iterate in all objects defined under
   // components (function _FindObject)
-  bool _find = false;
-  SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
-
-  SALOMEDS::SComponentIterator_var it = NewComponentIterator();
-  for (; it->More();it->Next()){
-    if(!_find)
-      {
-       SALOMEDS::SComponent_var SC = it->Value();
-       SALOMEDS::GenericAttribute_var anAttr;
-       if (SC->FindAttribute(anAttr,"AttributeName")) 
-       {
-         SALOMEDS::AttributeName_var Name = SALOMEDS::AttributeName::_narrow(anAttr);
-         CORBA::String_var Val = Name->Value();
-         if (strcmp(Val, anObjectName) == 0)
-           {
-             _find = true;
-             RefSO = SALOMEDS::SObject::_narrow(SC);
-           }
-       }
-       if (!_find) RefSO =  _FindObject(SC,anObjectName, _find);
+  bool aIsFound = false;
+  SALOMEDS::SObject_var aRefSO;
+  SALOMEDS_SComponentIterator_i aComponentIter(this,_doc);
+  for(; aComponentIter.More() && !aIsFound; aComponentIter.Next()){
+    TDF_Label aLab = aComponentIter.GetValue();
+    Handle(TDataStd_Name) anAttr;
+    if(aLab.FindAttribute(TDataStd_Name::GetID(),anAttr)){
+      TCollection_AsciiString aString(anAttr->Get());
+      if(strcmp(aString.ToCString(),theObjectName) == 0){
+       aRefSO = SALOMEDS_SComponent_i::NewRef(this,aLab)._retn();
+       aIsFound = true;
       }
+    }
+    if(!aIsFound) 
+      aRefSO = _FindObject(aLab,theObjectName,aIsFound);
   }
-  return RefSO;
+
+  return aRefSO._retn();
 }
 
 //============================================================================
@@ -201,69 +373,76 @@ SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectID(const char* anObjectID)
 {
   // Convert aSO->GetID in TDF_Label.
   TDF_Label Lab;
-  TDF_Tool::Label(_doc->GetData(), strdup(anObjectID), Lab);
+  TDF_Tool::Label(_doc->GetData(), (char*)anObjectID, Lab);
   
-  if (Lab.IsNull()) return SALOMEDS::SObject::_nil();
-  SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (Lab,_orb);
-  SALOMEDS::SObject_var so = SALOMEDS::SObject::_narrow(so_servant->_this()); 
-  return so;
+  if (Lab.IsNull()) 
+    return SALOMEDS::SObject::_nil();
+
+  return SALOMEDS_SObject_i::NewRef(this,Lab)._retn();
 
 }
 
+//============================================================================
+/*! Function : CreateObjectID
+ *  Purpose  : Creates an Object with ID = anObjectID
+ */
+//============================================================================
+SALOMEDS::SObject_ptr SALOMEDS_Study_i::CreateObjectID(const char* anObjectID)
+{
+  // Convert aSO->GetID in TDF_Label.
+  TDF_Label Lab;
+  TDF_Tool::Label(_doc->GetData(), (char*)anObjectID, Lab, Standard_True);
+  
+  if (Lab.IsNull()) 
+    return SALOMEDS::SObject::_nil();
+
+  return SALOMEDS_SObject_i::NewRef(this,Lab)._retn();
+}
+
 //============================================================================
 /*! Function : FindObjectByName
  *  Purpose  : Find Objects with SALOMEDS::Name = anObjectName in a Component
  *           : with ComponentDataType = aComponentName
  */
 //============================================================================
-SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindObjectByName( const char* anObjectName,
-                                                                   const char* aComponentName )
+SALOMEDS::Study::ListOfSObject* 
+SALOMEDS_Study_i::FindObjectByName(const char* theObjectName,
+                                  const char* theComponentName)
 {
-  SALOMEDS::Study::ListOfSObject_var listSO = new SALOMEDS::Study::ListOfSObject ;
-  listSO->length(0);
-  
-  SALOMEDS::SComponent_ptr compo = FindComponent(aComponentName) ;
-  if ( compo->_is_nil() ) {
-    MESSAGE ("In FindObjectByName() :  Component named " << aComponentName << " not found ");
-    return listSO._retn();
+  SALOMEDS::Study::ListOfSObject_var aListOfSObj = new SALOMEDS::Study::ListOfSObject ;
+  aListOfSObj->length(0);
+
+  SALOMEDS::SComponent_ptr aSComponent = FindComponent(theComponentName) ;
+  if(aSComponent->_is_nil()){
+    MESSAGE ("In FindObjectByName() :  Component named " << theComponentName << " not found ");
+    return aListOfSObj._retn();
   }
 
   // Iterate on each object and subobject of the component
   // If objectName is found add it to the list of SObjects 
-  char *name;
-  char *childName ;
-  SALOMEDS::SObject_ptr addSO = SALOMEDS::SObject::_nil();
-
-  CORBA::String_var compoId = compo->GetID();
-  SALOMEDS::ChildIterator_var it = NewChildIterator(compo);
-  int length = 0 ;
-  for ( ; it->More();it->Next() ) {
-    
-    SALOMEDS::SObject_var CSO = it->Value();
-    SALOMEDS::GenericAttribute_var anAttr;
-    SALOMEDS::AttributeName_var    aName;
-    if ( CSO->FindAttribute(anAttr, "AttributeName") ) {
-      aName = SALOMEDS::AttributeName::_narrow(anAttr);
-      name = aName->Value();
-      if ( strcmp( name, anObjectName ) == 0) {
-       addSO = SALOMEDS::SObject::_narrow(CSO);
+  TDF_Label aLabel;
+  CORBA::String_var anEntry = aSComponent->GetID();
+  TDF_Tool::Label(_doc->GetData(),const_cast<char*>(anEntry.in()),aLabel);
+  
+  int aLength = 0 ;
+  SALOMEDS::SObject_var aRefSO;
+  TDF_ChildIterator aChildIter(aLabel,true);
+  for(; aChildIter.More(); aChildIter.Next()){
+    TDF_Label aLab = aChildIter.Value();
+    Handle(TDataStd_Name) anAttr;
+    if(aLab.FindAttribute(TDataStd_Name::GetID(),anAttr)){
+      TCollection_AsciiString aString(anAttr->Get());
+      if(strcmp(aString.ToCString(),theObjectName) == 0){
+       aRefSO = SALOMEDS_SObject_i::NewRef(this,aLab)._retn();
        /* add to list */
-       length++ ;
-       listSO->length(length);
-       listSO[length-1] = addSO ;
-      }
-      
-      /* looks also for eventual children */
-      bool found = false ;
-      addSO = _FindObject( CSO, anObjectName, found ) ;
-      if( found) {
-       length++ ;
-       listSO->length(length);
-       listSO[length-1] = addSO ;
+       aLength++ ;
+       aListOfSObj->length(aLength);
+       aListOfSObj[aLength-1] = aRefSO;
       }
     }
   }
-  return listSO._retn() ;
+
+  return aListOfSObj._retn() ;
 }
 
 
@@ -273,47 +452,48 @@ SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindObjectByName( const char*
  *  Purpose  : Find an Object with IOR = anObjectIOR
  */
 //============================================================================
-SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectIOR(const char* anObjectIOR)
+SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectIOR(const char* theObjectIOR)
 {
   // firstly searching in the datamap for optimization
-  CORBA::String_var anIOR = CORBA::string_dup(anObjectIOR);
-  if (myIORLabels.IsBound(TCollection_ExtendedString(anIOR))) {
-    SALOMEDS_SObject_i* aResult = new SALOMEDS_SObject_i(myIORLabels.Find(TCollection_ExtendedString(anIOR)),_orb);
+  char* anIOR = const_cast<char*>(theObjectIOR);
+  if(myIORLabels.IsBound(anIOR)){
+    TDF_Label aLabel = myIORLabels.Find(anIOR);
+    TSObjectHolder aSObjectHolder = SALOMEDS_SObject_i::New(this,aLabel);
+    SALOMEDS_SObject_i* aSObjectPtr = aSObjectHolder.first;
+    SALOMEDS::SObject_var aSObject = aSObjectHolder.second;
     // 11 oct 2002: forbidden attributes must be checked here
     SALOMEDS::GenericAttribute_var anAttr;
-    if (!aResult->FindAttribute(anAttr,"AttributeIOR")) {
-      myIORLabels.UnBind(TCollection_ExtendedString(anIOR));
-    } else return aResult->_this();
+    if(!aSObjectPtr->FindAttribute(anAttr,"AttributeIOR")){
+      myIORLabels.UnBind(anIOR);
+    }else{
+      return aSObject._retn();
+    }
   }
+
   // Iterate to all components defined in the study
   // After testing the component name, iterate in all objects defined under
   // components (function _FindObject)
-  bool _find = false;
-  SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
-
-  SALOMEDS::SComponentIterator_var it = NewComponentIterator();
-  for (; it->More();it->Next()){
-    if(!_find)
-      {
-       SALOMEDS::SComponent_var SC = it->Value();
-       SALOMEDS::GenericAttribute_var anAttr;
-       if (SC->FindAttribute(anAttr,"AttributeIOR")) 
-       {
-         SALOMEDS::AttributeIOR_var IOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
-          CORBA::String_var Val = IOR->Value();
-         if (strcmp(Val, anObjectIOR) == 0)
-           {
-             _find = true;
-             RefSO = SALOMEDS::SObject::_narrow(SC);
-           }
-       }
-       if (!_find) 
-         RefSO =  _FindObjectIOR(SC,anObjectIOR, _find);
+  bool aIsFound = false;
+  SALOMEDS::SObject_var aRefSO;
+  SALOMEDS_SComponentIterator_i aComponentIter(this,_doc);
+  for(; aComponentIter.More() && !aIsFound; aComponentIter.Next()){
+    TDF_Label aLab = aComponentIter.GetValue();
+    Handle(SALOMEDS_IORAttribute) anAttr;
+    if(aLab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr)){
+      TCollection_AsciiString aString(anAttr->Get());
+      if(strcmp(aString.ToCString(),theObjectIOR) == 0){
+       aRefSO = SALOMEDS_SComponent_i::NewRef(this,aLab);
+       aIsFound = true;
       }
+    }
+    if(!aIsFound) 
+      aRefSO = _FindObjectIOR(aLab,theObjectIOR,aIsFound);
   }
-  if (!RefSO->_is_nil()) INFOS("SALOMEDS_Study_i::FindObjectIOR: found label with old methods");
 
-  return RefSO;
+  if(!aRefSO->_is_nil()) 
+    MESSAGE("SALOMEDS_Study_i::FindObjectIOR: found label with old methods");
+
+  return aRefSO._retn();
 }
 
 //============================================================================
@@ -329,9 +509,7 @@ SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectByPath(const char* thePath)
   bool isRelative = false;
 
   if(aLength == 0) {  //Empty path - return the current context
-    SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (_current, _orb);
-    aSO = SALOMEDS::SObject::_narrow(so_servant->_this()); 
-    return aSO._retn();
+    return SALOMEDS_SObject_i::NewRef(this,_current)._retn();
   }
 
   if(aPath.Value(1) != '/')  //Relative path 
@@ -347,9 +525,7 @@ SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectByPath(const char* thePath)
   }
   else {
     if(aPath.Length() == 1 && aPath.Value(1) == '/') {    //Root
-      SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (_doc->Main(), _orb);
-      aSO = SALOMEDS::SObject::_narrow(so_servant->_this());
-      return aSO._retn();
+      return SALOMEDS_SObject_i::NewRef(this,_doc->Main())._retn();
     }
     anIterator.Initialize(_doc->Main(), Standard_False);
   }
@@ -365,9 +541,7 @@ SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectByPath(const char* thePath)
        if(anAttr->Get() == aToken) {
          aToken = aPath.Token("/", i+1); //Check if it was the last part of the path
          if(aToken.Length() == 0) {  //The searched label is found (no part of the path is left)
-             SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (aLabel, _orb);
-             aSO = SALOMEDS::SObject::_narrow(so_servant->_this()); 
-             return aSO._retn();
+           return SALOMEDS_SObject_i::NewRef(this,aLabel)._retn();
          }
 
          anIterator.Initialize(aLabel, Standard_False);
@@ -390,18 +564,22 @@ SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectByPath(const char* thePath)
 char* SALOMEDS_Study_i::GetObjectPath(CORBA::Object_ptr theObject)
 {
   TCollection_AsciiString aPath("");
-  if(CORBA::is_nil(theObject)) return CORBA::string_dup(aPath.ToCString());
+  if(CORBA::is_nil(theObject)) 
+    return CORBA::string_dup(aPath.ToCString());
 
   SALOMEDS::SObject_var anObject = SALOMEDS::SObject::_narrow(theObject);
   if(anObject->_is_nil()) {
-    anObject = FindObjectIOR(_orb->object_to_string(theObject));
-    if(anObject->_is_nil()) return CORBA::string_dup(aPath.ToCString());
+    CORBA::String_var anIOR = GetORB()->object_to_string(theObject);
+    anObject = FindObjectIOR(anIOR);
+    if(anObject->_is_nil()) 
+      return CORBA::string_dup(aPath.ToCString());
   }
 
   SALOMEDS::GenericAttribute_var anAttr;
   if(anObject->FindAttribute(anAttr, "AttributeName")) {
     SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
-    if(anAttr->_is_nil()) return CORBA::string_dup(aPath.ToCString());
+    if(anAttr->_is_nil()) 
+      return CORBA::string_dup(aPath.ToCString());
     TCollection_AsciiString aValue(aName->Value());
     aValue.Prepend("/");
     aValue += aPath;
@@ -431,7 +609,7 @@ void SALOMEDS_Study_i::SetContext(const char* thePath)
 {
   if(thePath == NULL || strlen(thePath) == 0) throw SALOMEDS::Study::StudyInvalidDirectory();
   TCollection_AsciiString aPath(CORBA::string_dup(thePath)), aContext("");
-  bool isInvalid = false, isFound = false;
+  bool isInvalid = false;
   SALOMEDS::SObject_var aSO;
   
   if(aPath.Value(1) != '/') { //Relative path 
@@ -466,10 +644,11 @@ void SALOMEDS_Study_i::SetContext(const char* thePath)
 //============================================================================
 char* SALOMEDS_Study_i::GetContext() 
 {
-  if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();   
-  SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (_current, _orb);
-  SALOMEDS::SObject_var aSO = SALOMEDS::SObject::_narrow(so_servant->_this()); 
-  return GetObjectPath(aSO._retn());
+  if(_current.IsNull()) 
+    throw SALOMEDS::Study::StudyInvalidContext();   
+
+  SALOMEDS::SObject_var aSObject = SALOMEDS_SObject_i::NewRef(this,_current);
+  return GetObjectPath(aSObject);
 }
 
 //============================================================================
@@ -530,19 +709,15 @@ SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetDirectoryNames(const char* theCont
   TDF_ChildIterator anIter(aLabel, Standard_False); // iterate first-level children at all sublevels
   for(; anIter.More(); anIter.Next()) {
     TDF_Label aLabel = anIter.Value();
-//      Handle(TDF_Attribute) anAttribute;
-//      if (!aLabel.FindAttribute(SALOMEDS_IORAttribute::GetID(), anAttribute) &&
-//     !aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anAttribute)) {
-    Handle(SALOMEDS_PersRefAttribute) anID;
-    if (aLabel.FindAttribute(SALOMEDS_PersRefAttribute::GetID(), anID)) {
-      if (anID->Get().Search(TCollection_ExtendedString(DIRECTORYID)) == 1) {
+    Handle(SALOMEDS_LocalIDAttribute) anID;
+    if (aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anID)) {
+      if (anID->Get() == DIRECTORYID) {
        Handle(TDataStd_Name) aName;
        if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) {
          aResultSeq.Append(aName->Get());
        }
       }
     }
-//      }
   }
   // fill the result table
   int anIndex, aLength = aResultSeq.Length();
@@ -574,13 +749,15 @@ SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetFileNames(const char* theContext)
   TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
   for(; anIter.More(); anIter.Next()) {
     TDF_Label aLabel = anIter.Value();
-//      Handle(TDF_Attribute) anAttribute;
-//      if (aLabel.FindAttribute(SALOMEDS_IORAttribute::GetID(), anAttribute) ||
-//     aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anAttribute)) {
-    Handle(SALOMEDS_PersRefAttribute) aName;
-    if (aLabel.FindAttribute(SALOMEDS_PersRefAttribute::GetID(), aName)) {
-      if (aName->Get().Search(TCollection_ExtendedString(FILEID)) == 1) {
-       aResultSeq.Append(aName->Get().Split(strlen(FILEID)));
+    Handle(SALOMEDS_LocalIDAttribute) anID;
+    if (aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anID)) {
+      if (anID->Get() == FILELOCALID) {
+       Handle(SALOMEDS_PersRefAttribute) aName;
+       if(aLabel.FindAttribute(SALOMEDS_PersRefAttribute::GetID(), aName)) {
+         TCollection_ExtendedString aFileName = aName->Get();
+         if(aFileName.Length() > 0)
+           aResultSeq.Append(aFileName.Split(strlen(FILEID)));
+       }
       }
     }
 //      }
@@ -622,53 +799,66 @@ SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetComponentNames(const char* theCont
  *  Purpose  : Create a ChildIterator from an SObject
  */
 //============================================================================
-SALOMEDS::ChildIterator_ptr SALOMEDS_Study_i::NewChildIterator(SALOMEDS::SObject_ptr aSO)
+SALOMEDS::ChildIterator_ptr 
+SALOMEDS_Study_i::NewChildIterator(SALOMEDS::SObject_ptr theSObject)
 {
-  //Convert aSO->GetID in TDF_Label.
-  TDF_Label Lab;
-  TDF_Tool::Label(_doc->GetData(), strdup(aSO->GetID()), Lab);
-
-  //Create iterator
-  SALOMEDS_ChildIterator_i* it_servant = new SALOMEDS_ChildIterator_i(Lab,_orb);
-  SALOMEDS::ChildIterator_var it = SALOMEDS::ChildIterator::_narrow(it_servant->_this()); 
+  SALOMEDS_ChildIterator_i* aServant = 
+    new SALOMEDS_ChildIterator_i(GetChildIterator(theSObject));
 
-  return it;
+  return aServant->_this();
 }
 
+SALOMEDS_ChildIterator_i 
+SALOMEDS_Study_i::GetChildIterator(SALOMEDS::SObject_ptr theSObject)
+{
+  TDF_Label aLab;
+  TDF_Tool::Label(_doc->GetData(),theSObject->GetID(),aLab);
+  return SALOMEDS_ChildIterator_i(this,aLab);
+}
 
 //============================================================================
 /*! Function : NewComponentIterator
  *  Purpose  : Create a SComponentIterator
  */
 //============================================================================
-SALOMEDS::SComponentIterator_ptr SALOMEDS_Study_i::NewComponentIterator()
+SALOMEDS::SComponentIterator_ptr 
+SALOMEDS_Study_i::NewComponentIterator()
+{
+  SALOMEDS_SComponentIterator_i* aServant = 
+    new SALOMEDS_SComponentIterator_i(GetComponentIterator());
+
+  return aServant->_this();
+}
+
+SALOMEDS_SComponentIterator_i 
+SALOMEDS_Study_i::GetComponentIterator()
 {
-  SALOMEDS_SComponentIterator_i* it_servant = new SALOMEDS_SComponentIterator_i(_doc,_orb);
-  SALOMEDS::SComponentIterator_var it = SALOMEDS::SComponentIterator::_narrow(it_servant->_this()); 
-  return it;
+  return SALOMEDS_SComponentIterator_i(this,_doc);
 }
 
+//============================================================================
+/*! Function : GetUseCaseBuilder
+ *  Purpose  : Returns a UseCase builder
+ */
+//============================================================================
+SALOMEDS::UseCaseBuilder_ptr SALOMEDS_Study_i::GetUseCaseBuilder() 
+{
+  return _UseCaseBuilder->_this();
+}
 
 //============================================================================
 /*! Function : NewBuilder
  *  Purpose  : Create a StudyBuilder
  */
 //============================================================================
+SALOMEDS_StudyBuilder_i* SALOMEDS_Study_i::GetBuilder()
+{
+  return _Builder;
+}
 SALOMEDS::StudyBuilder_ptr SALOMEDS_Study_i::NewBuilder()
 {
-  SALOMEDS_StudyBuilder_i* it_servant = new SALOMEDS_StudyBuilder_i(_doc,_orb);
-  SALOMEDS::StudyBuilder_var it = SALOMEDS::StudyBuilder::_narrow(it_servant->_this()); 
-
-  if(_autoFill) {
-    SALOMEDS_Callback_i* callback = new SALOMEDS_Callback_i(GetUseCaseBuilder(), _orb);
-    SALOMEDS::Callback_var cb = SALOMEDS::Callback::_narrow(callback->_this()); 
-
-    it->SetOnAddSObject(cb);
-    it->SetOnRemoveSObject(cb);
-  }
-
-  return it;
-
+  return GetBuilder()->_this();
 }
  
 //============================================================================
@@ -733,6 +923,10 @@ CORBA::Boolean  SALOMEDS_Study_i::IsModified()
 //============================================================================
 char* SALOMEDS_Study_i::URL()
 {
+  if(!_URL) {
+    _URL = new char[1];
+    _URL[0] = (char)0;
+  }
   return CORBA::string_dup(_URL);
 }
 
@@ -743,9 +937,20 @@ char* SALOMEDS_Study_i::URL()
 //============================================================================
 void SALOMEDS_Study_i::URL(const char* url)
 {
+  if (_URL) delete [] _URL;
   _URL = new char[strlen(url) +1];
   strcpy(_URL,url);
   SCRUTE(_URL);
+
+  char *aName = _URL;
+  char *adr = strtok(aName, "/");
+  while (adr)
+    {
+      aName = adr;
+      adr = strtok(NULL, "/");
+    }
+  strcpy(_URL,url);
+  Name(aName);
 }
 
 
@@ -754,35 +959,28 @@ void SALOMEDS_Study_i::URL(const char* url)
  *  Purpose  : Find an Object with SALOMEDS::Name = anObjectName
  */
 //============================================================================
-SALOMEDS::SObject_ptr SALOMEDS_Study_i::_FindObject(SALOMEDS::SObject_ptr SO,
-                                                   const char* anObjectName, 
-                                                   bool& _find)
+SALOMEDS::SObject_ptr 
+SALOMEDS_Study_i::_FindObject(TDF_Label theLabel,
+                             const char* theObjectName, 
+                             bool& theIsFound)
 {
+  theIsFound = false;
   // Iterate on each objects and subobjects of the component
   // If objectName find, stop the loop and get the object reference
-  SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
-
-  CORBA::String_var soid = SO->GetID();
-  SALOMEDS::ChildIterator_var it = NewChildIterator(SO);
-  for (; it->More();it->Next()){
-    if(!_find)
-      {
-       SALOMEDS::SObject_var CSO = it->Value();
-       SALOMEDS::GenericAttribute_var anAttr;
-       if (CSO->FindAttribute(anAttr,"AttributeName")) 
-       {
-         SALOMEDS::AttributeName_var Name = SALOMEDS::AttributeName::_narrow(anAttr);
-          CORBA::String_var Val = Name->Value();
-         if (strcmp(Val, anObjectName) == 0)
-           {
-             RefSO = SALOMEDS::SObject::_narrow(CSO);
-             _find = true;
-           }
-       }
-       if (!_find) RefSO =  _FindObject(CSO, anObjectName, _find);
+  SALOMEDS::SObject_var aRefSO;
+  TDF_ChildIterator aChildIter(theLabel,true);
+  for(; aChildIter.More() && !theIsFound; aChildIter.Next()){
+    TDF_Label aLab = aChildIter.Value();
+    Handle(TDataStd_Name) anAttr;
+    if(aLab.FindAttribute(TDataStd_Name::GetID(),anAttr)){
+      TCollection_AsciiString aString(anAttr->Get());
+      if(strcmp(aString.ToCString(),theObjectName) == 0){
+       aRefSO = SALOMEDS_SObject_i::NewRef(this,aLab);
+       theIsFound = true;
       }
+    }
   }
-  return RefSO;
+  return aRefSO._retn();
 }
 
 //============================================================================
@@ -791,34 +989,26 @@ SALOMEDS::SObject_ptr SALOMEDS_Study_i::_FindObject(SALOMEDS::SObject_ptr SO,
  */
 //============================================================================
 SALOMEDS::SObject_ptr 
-SALOMEDS_Study_i::_FindObjectIOR(SALOMEDS::SObject_ptr SO,
-                             const char* anObjectIOR, 
-                             bool& _find)
+SALOMEDS_Study_i::_FindObjectIOR(TDF_Label theLabel,
+                                const char* theObjectIOR, 
+                                bool& theIsFound)
 {
   // Iterate on each objects and subobjects of the component
   // If objectName find, stop the loop and get the object reference
-  SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
-
-  SALOMEDS::ChildIterator_var it = NewChildIterator(SO);
-  for (; it->More();it->Next()){
-    if(!_find)
-      {
-       SALOMEDS::SObject_var CSO = it->Value();
-       SALOMEDS::GenericAttribute_var anAttr;
-       if (CSO->FindAttribute(anAttr,"AttributeIOR")) 
-       {
-         SALOMEDS::AttributeIOR_var IOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
-          CORBA::String_var Val = IOR->Value();
-         if (strcmp(Val, anObjectIOR) == 0)
-           {
-             RefSO = SALOMEDS::SObject::_narrow(CSO);
-             _find = true;
-           }
-       }
-       if (!_find) RefSO =  _FindObjectIOR(CSO, anObjectIOR, _find);
+  SALOMEDS::SObject_var aRefSO;
+  TDF_ChildIterator aChildIter(theLabel,true);
+  for(; aChildIter.More() && !theIsFound; aChildIter.Next()){
+    TDF_Label aLab = aChildIter.Value();
+    Handle(SALOMEDS_IORAttribute) anAttr;
+    if(aLab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr)){
+      TCollection_AsciiString aString(anAttr->Get());
+      if(strcmp(aString.ToCString(),theObjectIOR) == 0){
+       aRefSO = SALOMEDS_SObject_i::NewRef(this,aLab);
+       theIsFound = true;
       }
+    }
   }
-  return RefSO;
+  return aRefSO._retn();
 }
 
 CORBA::Short SALOMEDS_Study_i::StudyId()
@@ -840,22 +1030,11 @@ void SALOMEDS_Study_i::UpdateIORLabelMap(const char* anIOR,const char* anEntry)
   myIORLabels.Bind(TCollection_ExtendedString(IOR), aLabel);
 }
 
-void SALOMEDS_Study_i::IORUpdated(const Handle(SALOMEDS_IORAttribute) theAttribute, CORBA::ORB_ptr orb) {
-  // get accorded study first
-  Handle(SALOMEDS_IORAttribute) Att;
-  if (theAttribute->Label().Root().FindAttribute(SALOMEDS_IORAttribute::GetID(),Att)){
-    TCollection_AsciiString ch(Att->Get());
-    char* IOR = CORBA::string_dup(ch.ToCString());
-    CORBA::Object_var obj = orb->string_to_object(IOR);
-    SALOMEDS::Study_ptr aStudy = SALOMEDS::Study::_narrow(obj) ;
-    ASSERT(!CORBA::is_nil(aStudy));
-    TCollection_AsciiString aString;
-    TDF_Tool::Entry(theAttribute->Label(),aString);
-    aStudy->UpdateIORLabelMap(TCollection_AsciiString(theAttribute->Get()).ToCString(), aString.ToCString());
-  } else {
-    INFOS("IORUpdated: Problem to get study");
-    return;
-  }
+void SALOMEDS_Study_i::IORUpdated(const Handle(SALOMEDS_IORAttribute) theAttribute) {
+  TCollection_AsciiString aString;
+  TDF_Tool::Entry(theAttribute->Label(),aString);
+  TCollection_AsciiString aValue(theAttribute->Get());
+  UpdateIORLabelMap(aValue.ToCString(),aString.ToCString());
 }
 
 SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindDependances(SALOMEDS::SObject_ptr anObject) {
@@ -869,9 +1048,12 @@ SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindDependances(SALOMEDS::SObj
 }
 
 
-SALOMEDS::AttributeStudyProperties_ptr SALOMEDS_Study_i::GetProperties() {
-  SALOMEDS::GenericAttribute_ptr anAttr =  NewBuilder()->FindOrCreateAttribute(FindObjectID("0:1"),
-                                                                              "AttributeStudyProperties");
+SALOMEDS::AttributeStudyProperties_ptr SALOMEDS_Study_i::GetProperties(){
+  SALOMEDS::SObject_var aSObject = FindObjectID("0:1");
+
+  SALOMEDS::GenericAttribute_var anAttr =  
+    GetBuilder()->FindOrCreateAttribute(aSObject,"AttributeStudyProperties");
+
   return SALOMEDS::AttributeStudyProperties::_narrow(anAttr);
 }
 
@@ -909,19 +1091,6 @@ SALOMEDS::ListOfDates* SALOMEDS_Study_i::GetModificationsDate() {
 
 
 
-//============================================================================
-/*! Function : GetUseCaseBuilder
- *  Purpose  : Returns a UseCase builder
- */
-//============================================================================
-SALOMEDS::UseCaseBuilder_ptr SALOMEDS_Study_i::GetUseCaseBuilder() 
-{
-  SALOMEDS_UseCaseBuilder_i* _caseBuilder = new SALOMEDS_UseCaseBuilder_i(_doc, _orb);
-  SALOMEDS::UseCaseBuilder_var aBuilder = SALOMEDS::UseCaseBuilder::_narrow(_caseBuilder->_this());
-  return aBuilder._retn();
-}
-
-
 //============================================================================
 /*! Function : Close
  *  Purpose  : 
@@ -929,10 +1098,11 @@ SALOMEDS::UseCaseBuilder_ptr SALOMEDS_Study_i::GetUseCaseBuilder()
 //============================================================================
 void SALOMEDS_Study_i::Close()
 {
-  SALOMEDS::SComponentIterator_var itcomponent = NewComponentIterator();
+  SALOMEDS_SComponentIterator_i itcomponent(this,_doc);
 
-  for (; itcomponent->More(); itcomponent->Next()) {
-    SALOMEDS::SComponent_var sco = itcomponent->Value();
+  const CORBA::ORB_var& anORB = GetORB();
+  for (; itcomponent.More(); itcomponent.Next()) {
+    SALOMEDS::SComponent_var sco = itcomponent.Value();
          
     MESSAGE ( "Look for an engine for data type :"<< sco->ComponentDataType());
     // if there is an associated Engine call its method for closing
@@ -940,11 +1110,13 @@ void SALOMEDS_Study_i::Close()
     if (sco->ComponentIOR(IOREngine)) {
       // we have found the associated engine to write the data 
       MESSAGE ( "We have found an engine for data type :"<< sco->ComponentDataType());
-      CORBA::Object_var obj = _orb->string_to_object(IOREngine);
-      SALOMEDS::Driver_var anEngine = SALOMEDS::Driver::_narrow(obj) ;
-             
-      if (!anEngine->_is_nil())  
-       anEngine->Close(sco);
+      CORBA::Object_var obj = anORB->string_to_object(IOREngine);
+      if (!CORBA::is_nil(obj)) {
+       SALOMEDS::Driver_var anEngine = SALOMEDS::Driver::_narrow(obj) ;
+       
+       if (!anEngine->_is_nil())  
+         anEngine->Close(sco);
+      }
     }
   }
 
@@ -957,3 +1129,116 @@ void SALOMEDS_Study_i::Close()
   if(!anApp.IsNull()) anApp->Close(_doc);
   _doc.Nullify();
 }
+
+//============================================================================
+/*! Function : AddPostponed
+ *  Purpose  : 
+ */
+ //============================================================================
+void SALOMEDS_Study_i::AddPostponed(const char* theIOR) {
+  if (!GetBuilder()->HasOpenCommand()) return;
+  try {
+    CORBA::Object_var obj = GetORB()->string_to_object(theIOR);
+    if (!CORBA::is_nil(obj)) {
+      SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj) ;
+      if (!CORBA::is_nil(aGeneric)) {
+       TCollection_AsciiString anIOR(const_cast<char*>(theIOR));
+       anIOR.Prepend("d");
+       myPostponedIORs.Append(anIOR); // add prefix: deleted
+       myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
+      }
+    }
+  } catch(...) {}
+}
+
+void SALOMEDS_Study_i::AddCreatedPostponed(const char* theIOR) {
+  if (!GetBuilder()->HasOpenCommand()) return;
+  try {
+    CORBA::Object_var obj = GetORB()->string_to_object(theIOR);
+    if (!CORBA::is_nil(obj)) {
+      SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj) ;
+      if (!CORBA::is_nil(aGeneric)) {
+       TCollection_AsciiString anIOR(const_cast<char*>(theIOR));
+       anIOR.Prepend("c");
+       myPostponedIORs.Append(anIOR); // add prefix: created
+       myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
+      }
+    }
+  } catch(...) {}
+}
+
+//============================================================================
+/*! Function : RemovePostponed
+ *  Purpose  : 
+ */
+//============================================================================
+void SALOMEDS_Study_i::RemovePostponed(const CORBA::Long theUndoLimit) {
+  int anIndex;
+  int anOld;
+
+  int aUndoLimit = theUndoLimit;
+  if (theUndoLimit < 0) aUndoLimit = 0;
+
+  const CORBA::ORB_var& anORB = GetORB();
+  if (myNbUndos > 0) { // remove undone
+    anOld = 0;
+    for(anIndex = 1; anIndex < myNbPostponed.Length() - myNbUndos; anIndex++)
+      anOld += myNbPostponed(anIndex);
+    int aNew = myPostponedIORs.Length() - myNbPostponed.Last();
+
+    for(anIndex = anOld + 1; anIndex <= aNew; anIndex++) {
+      TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
+      if (anIOR.Value(1) == 'c') {
+       CORBA::Object_var obj = anORB->string_to_object(anIOR.Split(1).ToCString());
+       SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
+       if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
+      }
+    }
+    if (anOld < aNew) myPostponedIORs.Remove(anOld + 1, aNew);
+    if (myNbPostponed.Length() > 0) myNbPostponed.Remove(myNbPostponed.Length() - myNbUndos, myNbPostponed.Length() - 1);
+
+    myNbUndos = 0;
+  }
+
+  if (myNbPostponed.Length() > aUndoLimit) { // remove objects, that can not be undone
+    anOld = 0;
+    for(anIndex = myNbPostponed.Length() - aUndoLimit; anIndex >= 1; anIndex--)
+      anOld += myNbPostponed(anIndex);
+    for(anIndex = 1; anIndex <= anOld; anIndex++) {
+      TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
+      if (anIOR.Value(1) == 'd') {
+       CORBA::Object_var obj = anORB->string_to_object(anIOR.Split(1).ToCString());
+       SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
+       if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
+      }
+    }
+    if (anOld > 0) myPostponedIORs.Remove(1, anOld);
+    myNbPostponed.Remove(1, myNbPostponed.Length() - aUndoLimit);
+  }
+
+  if (theUndoLimit == -1) { // remove all IORs from the study on the study close
+    TDF_ChildIDIterator anIter(_doc->GetData()->Root(), SALOMEDS_IORAttribute::GetID(), Standard_True);
+    for(; anIter.More(); anIter.Next()) {
+      Handle(SALOMEDS_IORAttribute) anAttr = Handle(SALOMEDS_IORAttribute)::DownCast(anIter.Value());
+      CORBA::String_var anIOR = CORBA::string_dup(TCollection_AsciiString(anAttr->Get()).ToCString());
+      try {
+       CORBA::Object_var obj = anORB->string_to_object(anIOR);
+       SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
+       if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
+      } catch (...) {}
+    }
+  } else myNbPostponed.Append(0);
+}
+
+//============================================================================
+/*! Function : UndoPostponed
+ *  Purpose  : 
+ */
+//============================================================================
+void SALOMEDS_Study_i::UndoPostponed(const CORBA::Long theWay) {
+  myNbUndos += theWay;
+  // remove current postponed
+  if (myNbPostponed.Last() > 0)
+    myPostponedIORs.Remove(myPostponedIORs.Length() - myNbPostponed.Last() + 1, myPostponedIORs.Length());
+  myNbPostponed(myNbPostponed.Length()) = 0;
+}