Salome HOME
Add missing try/catch using SMESH_TryCatch.hxx
[modules/smesh.git] / src / SMESH_I / SMESH_Mesh_i.cxx
index 77edc2ffacce8bb0f781775eda82d37f177f89ba..e81c3a7e76592f6c572d4aae665ebaa2cc94656b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include "SMDS_ElemIterator.hxx"
 #include "SMDS_FacePosition.hxx"
 #include "SMDS_IteratorOnIterators.hxx"
+#include "SMDS_MeshGroup.hxx"
 #include "SMDS_SetIterator.hxx"
 #include "SMDS_VolumeTool.hxx"
 #include "SMESHDS_Command.hxx"
 #include "SMESHDS_CommandType.hxx"
+#include "SMESHDS_Group.hxx"
 #include "SMESHDS_GroupOnGeom.hxx"
 #include "SMESH_Filter_i.hxx"
 #include "SMESH_Gen_i.hxx"
 #include "SMESH_MEDMesh_i.hxx"
 #include "SMESH_MeshEditor.hxx"
 #include "SMESH_MeshEditor_i.hxx"
+#include "SMESH_MeshPartDS.hxx"
 #include "SMESH_MesherHelper.hxx"
+#include "SMESH_PreMeshInfo.hxx"
 #include "SMESH_PythonDump.hxx"
 #include "SMESH_subMesh_i.hxx"
 
 #include <OpUtil.hxx>
+#include <SALOMEDS_Attributes_wrap.hxx>
+#include <SALOMEDS_wrap.hxx>
 #include <SALOME_NamingService.hxx>
-#include <Utils_CorbaException.hxx>
 #include <Utils_ExceptHandlers.hxx>
 #include <Utils_SINGLETON.hxx>
 #include <utilities.h>
+
 #include <GEOMImpl_Types.hxx>
+#include <GEOM_GenericObjPtr.h>
 
 // OCCT Includes
 #include <BRep_Builder.hxx>
 #include <OSD_File.hxx>
 #include <OSD_Path.hxx>
 #include <OSD_Protection.hxx>
+#include <Standard_OutOfMemory.hxx>
 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
 #include <TColStd_MapOfInteger.hxx>
 #include <TColStd_SequenceOfInteger.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
-#include <TopoDS_Compound.hxx>
-#include <TopTools_MapOfShape.hxx>
 #include <TopTools_MapIteratorOfMapOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopoDS_Compound.hxx>
+
+#include "SMESH_TryCatch.hxx" // include after OCCT headers!
 
 // STL Includes
 #include <algorithm>
 #include <string>
 #include <iostream>
 #include <sstream>
+
 #include <sys/stat.h>
 
 #ifdef _DEBUG_
@@ -87,11 +98,7 @@ static int MYDEBUG = 0;
 using namespace std;
 using SMESH::TPythonDump;
 
-int SMESH_Mesh_i::myIdGenerator = 0;
-
-//To disable automatic genericobj management, the following line should be commented.
-//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
-#define WITHGENERICOBJ
+int SMESH_Mesh_i::_idGenerator = 0;
 
 //=============================================================================
 /*!
@@ -105,10 +112,11 @@ SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
 : SALOME::GenericObj_i( thePOA )
 {
   MESSAGE("SMESH_Mesh_i");
-  _impl = NULL;
-  _gen_i = gen_i;
-  _id = myIdGenerator++;
-  _studyId = studyId;
+  _impl        = NULL;
+  _gen_i       = gen_i;
+  _id          = _idGenerator++;
+  _studyId     = studyId;
+  _preMeshInfo = NULL;
 }
 
 //=============================================================================
@@ -121,48 +129,38 @@ SMESH_Mesh_i::~SMESH_Mesh_i()
 {
   MESSAGE("~SMESH_Mesh_i");
 
-#ifdef WITHGENERICOBJ
   // destroy groups
   map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
-  for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) {
-    if ( CORBA::is_nil( itGr->second ))
-      continue;
-    SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>(SMESH_Gen_i::GetServant(itGr->second).in());
-    if (aGroup) {
-      // this method is called from destructor of group (PAL6331)
+  for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
+    if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
+    {
+      // _impl->RemoveGroup() is called by ~SMESH_GroupBase_i() (PAL6331)
       //_impl->RemoveGroup( aGroup->GetLocalID() );
       aGroup->myMeshServant = 0;
       aGroup->UnRegister();
     }
-  }
   _mapGroups.clear();
 
   // destroy submeshes
   map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
-  for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) {
-    if ( CORBA::is_nil( itSM->second ))
-      continue;
-    SMESH_subMesh_i* aSubMesh = dynamic_cast<SMESH_subMesh_i*>(SMESH_Gen_i::GetServant(itSM->second).in());
-    if (aSubMesh) {
+  for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
+    if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
+    {
       aSubMesh->UnRegister();
     }
-  }
   _mapSubMeshIor.clear();
 
   // destroy hypotheses
   map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
-  for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
-    if ( CORBA::is_nil( itH->second ))
-      continue;
-    SMESH_Hypothesis_i* aHypo = dynamic_cast<SMESH_Hypothesis_i*>(SMESH_Gen_i::GetServant(itH->second).in());
-    if (aHypo) {
+  for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ )
+    if ( SMESH_Hypothesis_i* aHypo = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
+    {
       aHypo->UnRegister();
     }
-  }
   _mapHypo.clear();
-#endif
 
-  delete _impl;
+  delete _impl; _impl = NULL;
+  delete _preMeshInfo; _preMeshInfo = NULL;
 }
 
 //=============================================================================
@@ -230,6 +228,31 @@ GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
   return aShapeObj._retn();
 }
 
+//================================================================================
+/*!
+ * \brief Return false if the mesh is not yet fully loaded from the study file
+ */
+//================================================================================
+
+CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  return !_preMeshInfo;
+}
+
+//================================================================================
+/*!
+ * \brief Load full mesh data from the study file
+ */
+//================================================================================
+
+void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+}
+
 //================================================================================
 /*!
  * \brief Remove all nodes and elements
@@ -239,6 +262,9 @@ GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->ForgetAllData();
+
   try {
     _impl->Clear();
     CheckGeomGroupModif(); // issue 20145
@@ -246,6 +272,8 @@ void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
   catch(SALOME_Exception & S_ex) {
     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
   }
+  _impl->GetMeshDS()->Modified();
+
   TPythonDump() <<  _this() << ".Clear()";
 }
 
@@ -259,17 +287,23 @@ void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
   throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   try {
     _impl->ClearSubMesh( ShapeID );
   }
   catch(SALOME_Exception & S_ex) {
     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
   }
+  _impl->GetMeshDS()->Modified();
+
+  TPythonDump() <<  _this() << ".ClearSubMesh( " << ShapeID << " )";
 }
 
 //=============================================================================
 /*!
- *
+ * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
  */
 //=============================================================================
 
@@ -293,6 +327,30 @@ static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
   return res;
 }
 
+//=============================================================================
+/*!
+ * Convert ::SMESH_ComputeError to SMESH::ComputeError
+ */
+//=============================================================================
+
+static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
+{
+  SMESH::ComputeError_var errVar = new SMESH::ComputeError();
+  errVar->subShapeID = -1;
+  errVar->hasBadMesh = false;
+
+  if ( !errorPtr || errorPtr->IsOK() )
+  {
+    errVar->code = SMESH::COMPERR_OK;
+  }
+  else
+  {
+    errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
+    errVar->comment = errorPtr->myComment.c_str();
+  }
+  return errVar._retn();
+}
+
 //=============================================================================
 /*!
  *  ImportMEDFile
@@ -322,9 +380,9 @@ SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
   int major, minor, release;
   if( !MED::getMEDVersion( theFileName, major, minor, release ) )
     major = minor = release = -1;
-  myFileInfo           = new SALOME_MED::MedFileInfo();
-  myFileInfo->fileName = theFileName;
-  myFileInfo->fileSize = 0;
+  _medFileInfo           = new SALOME_MED::MedFileInfo();
+  _medFileInfo->fileName = theFileName;
+  _medFileInfo->fileSize = 0;
 #ifdef WIN32
   struct _stati64 d;
   if ( ::_stati64( theFileName, &d ) != -1 )
@@ -332,10 +390,10 @@ SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
   struct stat64 d;
   if ( ::stat64( theFileName, &d ) != -1 )
 #endif
-    myFileInfo->fileSize = d.st_size;
-  myFileInfo->major    = major;
-  myFileInfo->minor    = minor;
-  myFileInfo->release  = release;
+    _medFileInfo->fileSize = d.st_size;
+  _medFileInfo->major    = major;
+  _medFileInfo->minor    = minor;
+  _medFileInfo->release  = release;
 
   return ConvertDriverMEDReadStatus(status);
 }
@@ -392,11 +450,15 @@ char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nb
 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
   throw ( SALOME::SALOME_Exception )
 {
+  SMESH_TRY;
+
   // Read mesh with name = <theMeshName> into SMESH_Mesh
   _impl->UNVToMesh( theFileName );
 
   CreateGroupServants();
 
+  SMESH_CATCH( SMESH::throwCorbaException );
+
   return 1;
 }
 
@@ -410,28 +472,56 @@ int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
   throw ( SALOME::SALOME_Exception )
 {
+  SMESH_TRY;
+
   // Read mesh with name = <theMeshName> into SMESH_Mesh
   _impl->STLToMesh( theFileName );
 
+  SMESH_CATCH( SMESH::throwCorbaException );
+
   return 1;
 }
 
-//=============================================================================
+//================================================================================
 /*!
- *  importMEDFile
- *
- *  Imports mesh data from MED file
+ * \brief Function used in SMESH_CATCH by ImportGMFFile()
  */
-//=============================================================================
+//================================================================================
+
+namespace
+{
+  SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
+  {
+    return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Imports data from a GMF file and returns an error description
+ */
+//================================================================================
+
+SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
+                                                  bool        theMakeRequiredGroups )
+  throw (SALOME::SALOME_Exception)
+{
+  SMESH_ComputeErrorPtr error;
+
+#undef SMESH_CAUGHT
+#define SMESH_CAUGHT error =
+  SMESH_TRY;
+
+  error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
 
-// int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
-// {
-//   // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
-//   int status = _impl->MEDToMesh( theFileName, theMeshName );
-//   CreateGroupServants();
+  SMESH_CATCH( exceptionToComputeError );
+#undef SMESH_CAUGHT
+#define SMESH_CAUGHT
 
-//   return status;
-// }
+  CreateGroupServants();
+
+  return ConvertComputeError( error );
+}
 
 //=============================================================================
 /*!
@@ -474,11 +564,14 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
  */
 //=============================================================================
 
-SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
+SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr       aSubShapeObject,
                                                      SMESH::SMESH_Hypothesis_ptr anHyp)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->ForgetOrLoad();
+
   SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
 
   if ( !SMESH_Hypothesis::IsStatusFatal(status) )
@@ -534,9 +627,7 @@ SMESH_Hypothesis::Hypothesis_Status
     status = _impl->AddHypothesis(myLocSubShape, hypId);
     if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
       _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
-#ifdef WITHGENERICOBJ
       _mapHypo[hypId]->Register();
-#endif
       // assure there is a corresponding submesh
       if ( !_impl->IsMainShape( myLocSubShape )) {
         int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
@@ -563,6 +654,9 @@ SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aS
      throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->ForgetOrLoad();
+
   SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
 
   if ( !SMESH_Hypothesis::IsStatusFatal(status) )
@@ -737,7 +831,7 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShap
     if ( subMesh->_is_nil() )
       subMesh = createSubMesh( aSubShapeObject );
     if ( _gen_i->CanPublishInStudy( subMesh )) {
-      SALOMEDS::SObject_var aSO =
+      SALOMEDS::SObject_wrap aSO =
         _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
                                subMesh, aSubShapeObject, theName );
       if ( !aSO->_is_nil()) {
@@ -760,34 +854,43 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShap
 //=============================================================================
 
 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
-     throw (SALOME::SALOME_Exception)
+  throw (SALOME::SALOME_Exception)
 {
-  if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
+  SMESH_TRY;
+  
   if ( theSubMesh->_is_nil() )
     return;
 
   GEOM::GEOM_Object_var aSubShapeObject;
-  SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+  SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
   if ( !aStudy->_is_nil() )  {
     // Remove submesh's SObject
-    SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
+    SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
     if ( !anSO->_is_nil() ) {
       long aTag = SMESH_Gen_i::GetRefOnShapeTag();
-      SALOMEDS::SObject_var anObj, aRef;
-      if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
-        aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
-
-//       if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
-//         aSubShapeObject = theSubMesh->GetSubShape();
+      SALOMEDS::SObject_wrap anObj, aRef;
+      if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
+           anObj->ReferencedObject( aRef.inout() ))
+      {
+        CORBA::Object_var obj = aRef->GetObject();
+        aSubShapeObject = GEOM::GEOM_Object::_narrow( obj );
+      }
+      // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
+      //   aSubShapeObject = theSubMesh->GetSubShape();
 
-      aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
+      SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
+      builder->RemoveObjectWithChildren( anSO );
 
       // Update Python script
       TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
     }
   }
 
-  removeSubMesh( theSubMesh, aSubShapeObject.in() );
+  if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
+    if ( _preMeshInfo )
+      _preMeshInfo->ForgetOrLoad();
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=============================================================================
@@ -797,15 +900,18 @@ void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
 //=============================================================================
 
 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
-                                                 const char*         theName )
+                                                  const char*        theName )
      throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::SMESH_Group_var aNewGroup =
     SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
 
   if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
-    SALOMEDS::SObject_var aSO =
+    SALOMEDS::SObject_wrap aSO =
       _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
                            aNewGroup, GEOM::GEOM_Object::_nil(), theName);
     if ( !aSO->_is_nil()) {
@@ -830,6 +936,9 @@ SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType    theElemType,
      throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::SMESH_GroupOnGeom_var aNewGroup;
 
   TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
@@ -839,7 +948,7 @@ SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType    theElemType,
       ( createGroup( theElemType, theName, aShape ));
 
     if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
-      SALOMEDS::SObject_var aSO =
+      SALOMEDS::SObject_wrap aSO =
         _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
                              aNewGroup, theGeomObj, theName);
       if ( !aSO->_is_nil()) {
@@ -870,6 +979,8 @@ SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
     throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
 
   if ( CORBA::is_nil( theFilter ))
     THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
@@ -887,7 +998,7 @@ SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
 
   if ( _gen_i->CanPublishInStudy( aNewGroup ) )
   {
-    SALOMEDS::SObject_var aSO =
+    SALOMEDS::SObject_wrap aSO =
       _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), aNewGroup,
                            GEOM::GEOM_Object::_nil(), theName);
     if ( !aSO->_is_nil()) {
@@ -912,36 +1023,46 @@ void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
   if ( theGroup->_is_nil() )
     return;
 
+  SMESH_TRY;
+
   SMESH_GroupBase_i* aGroup =
     dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
   if ( !aGroup )
     return;
 
-  SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+  SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
   if ( !aStudy->_is_nil() )  {
-    SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
+    SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
 
     if ( !aGroupSO->_is_nil() ) {
       // Update Python script
       TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
 
       // Remove group's SObject
-      aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
+      SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
+      builder->RemoveObjectWithChildren( aGroupSO );
     }
   }
 
   // Remove the group from SMESH data structures
   removeGroup( aGroup->GetLocalID() );
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=============================================================================
-/*! RemoveGroupWithContents
+/*!
  *  Remove group with its contents
  */
 //=============================================================================
+
 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
   throw (SALOME::SALOME_Exception)
 {
+  SMESH_TRY;
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   if ( theGroup->_is_nil() )
     return;
 
@@ -961,11 +1082,13 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup
   else
     aMeshEditor->RemoveElements( anIds );
 
+  // Update Python script (theGroup must be alive for this)
+  pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
+
   // Remove group
   RemoveGroup( theGroup );
 
-  // Update Python script
-  pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //================================================================================
@@ -1034,60 +1157,58 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr the
                                                   const char* theName )
   throw (SALOME::SALOME_Exception)
 {
-  try
-  {
-    if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
-         theGroup1->GetType() != theGroup2->GetType() )
-      return SMESH::SMESH_Group::_nil();
+  SMESH::SMESH_Group_var aResGrp;
 
-    // Create Union
-    SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
-    if ( aResGrp->_is_nil() )
-      return SMESH::SMESH_Group::_nil();
+  SMESH_TRY;
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
 
-    SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
-    SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
+  if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
+       theGroup1->GetType() != theGroup2->GetType() )
+    return SMESH::SMESH_Group::_nil();
 
-    TColStd_MapOfInteger aResMap;
+  TPythonDump pyDump;
 
-    for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
-      aResMap.Add( anIds1[ i1 ] );
+  // Create Union
+  aResGrp = CreateGroup( theGroup1->GetType(), theName );
+  if ( aResGrp->_is_nil() )
+    return SMESH::SMESH_Group::_nil();
 
-    for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
-      aResMap.Add( anIds2[ i2 ] );
+  SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
+  SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
 
-    SMESH::long_array_var aResIds = new SMESH::long_array;
-    aResIds->length( aResMap.Extent() );
+  TColStd_MapOfInteger aResMap;
 
-    int resI = 0;
-    TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
-    for( ; anIter.More(); anIter.Next() )
-      aResIds[ resI++ ] = anIter.Key();
+  for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
+    aResMap.Add( anIds1[ i1 ] );
 
-    aResGrp->Add( aResIds );
+  for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
+    aResMap.Add( anIds2[ i2 ] );
 
-    // Clear python lines, created by CreateGroup() and Add()
-    SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
-    _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
-    _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
+  SMESH::long_array_var aResIds = new SMESH::long_array;
+  aResIds->length( aResMap.Extent() );
 
-    // Update Python script
-    TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
-                  << theGroup1 << ", " << theGroup2 << ", '"
-                  << theName << "' )";
+  int resI = 0;
+  TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
+  for( ; anIter.More(); anIter.Next() )
+    aResIds[ resI++ ] = anIter.Key();
 
-    return aResGrp._retn();
-  }
-  catch( ... )
-  {
-    return SMESH::SMESH_Group::_nil();
-  }
+  aResGrp->Add( aResIds );
+
+  // Update Python script
+  pyDump << aResGrp << " = " << _this() << ".UnionGroups( "
+         << theGroup1 << ", " << theGroup2 << ", '"
+         << theName << "' )";
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+
+  return aResGrp._retn();
 }
 
 //=============================================================================
 /*!
   \brief Union list of groups. New group is created. All mesh elements that are
-   present in initial groups are added to the new one.
+  present in initial groups are added to the new one.
   \param theGroups list of groups
   \param theName name of group to be created
   \return pointer on the group
@@ -1095,72 +1216,67 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr the
 //=============================================================================
 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
                                                        const char*                theName )
-throw (SALOME::SALOME_Exception)
+  throw (SALOME::SALOME_Exception)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   if ( !theName )
     return SMESH::SMESH_Group::_nil();
 
-  try
-  {
-    vector< int > anIds;
-    SMESH::ElementType aType = SMESH::ALL;
-    for ( int g = 0, n = theGroups.length(); g < n; g++ )
-    {
-      SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
-      if ( CORBA::is_nil( aGrp ) )
-        continue;
+  SMESH::SMESH_Group_var aResGrp;
 
-      // check type
-      SMESH::ElementType aCurrType = aGrp->GetType();
-      if ( aType == SMESH::ALL )
-        aType = aCurrType;
-      else 
-      {
-        if ( aType != aCurrType )
-          return SMESH::SMESH_Group::_nil();
-      }
+  SMESH_TRY;
 
-      // unite ids
-      SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
-      for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
-      {
-        int aCurrId = aCurrIds[ i ];
-        anIds.push_back( aCurrId );
-      }
-    }
+  vector< int > anIds;
+  SMESH::ElementType aType = SMESH::ALL;
+  for ( int g = 0, n = theGroups.length(); g < n; g++ )
+  {
+    SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
+    if ( CORBA::is_nil( aGrp ) )
+      continue;
 
-    // Create group
-    SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
-    if ( aResGrp->_is_nil() )
-      return SMESH::SMESH_Group::_nil();
-    
-    // Create array of identifiers
-    SMESH::long_array_var aResIds = new SMESH::long_array;
-    aResIds->length( anIds.size() );
-    
-    //NCollection_Map< int >::Iterator anIter( anIds );
-    for ( int i = 0; i<anIds.size(); i++ )
+    // check type
+    SMESH::ElementType aCurrType = aGrp->GetType();
+    if ( aType == SMESH::ALL )
+      aType = aCurrType;
+    else
     {
-      aResIds[ i ] = anIds[i];
+      if ( aType != aCurrType )
+        return SMESH::SMESH_Group::_nil();
     }
-    aResGrp->Add( aResIds );
 
-    // Clear python lines, created by CreateGroup() and Add()
-    SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
-    _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
-    _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
+    // unite ids
+    SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
+    for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
+    {
+      int aCurrId = aCurrIds[ i ];
+      anIds.push_back( aCurrId );
+    }
+  }
 
-    // Update Python script
-    
-    TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
-                  << &theGroups << ", '" << theName << "' )";
+  TPythonDump pyDump;
 
-    return aResGrp._retn();
-  }
-  catch( ... )
-  {
+  // Create group
+  aResGrp = CreateGroup( aType, theName );
+  if ( aResGrp->_is_nil() )
     return SMESH::SMESH_Group::_nil();
-  }
+
+  // Create array of identifiers
+  SMESH::long_array_var aResIds = new SMESH::long_array;
+  aResIds->length( anIds.size() );
+
+  for ( size_t i = 0; i<anIds.size(); i++ )
+    aResIds[ i ] = anIds[i];
+  aResGrp->Add( aResIds );
+
+  // Update Python script
+  pyDump << aResGrp << " = " << _this() << ".UnionListOfGroups( "
+         << &theGroups << ", '" << theName << "' )";
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+
+  return aResGrp._retn();
 }
 
 //=============================================================================
@@ -1171,15 +1287,23 @@ throw (SALOME::SALOME_Exception)
 //=============================================================================
 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
                                                       SMESH::SMESH_GroupBase_ptr theGroup2,
-                                                      const char* theName )
+                                                      const char*                theName )
   throw (SALOME::SALOME_Exception)
 {
+  SMESH::SMESH_Group_var aResGrp;
+
+  SMESH_TRY;
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
        theGroup1->GetType() != theGroup2->GetType() )
     return SMESH::SMESH_Group::_nil();
 
+  TPythonDump pyDump;
+
   // Create Intersection
-  SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
+  aResGrp = CreateGroup( theGroup1->GetType(), theName );
   if ( aResGrp->_is_nil() )
     return aResGrp;
 
@@ -1192,27 +1316,21 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr
     aMap1.Add( anIds1[ i1 ] );
 
   TColStd_SequenceOfInteger aSeq;
-
   for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
     if ( aMap1.Contains( anIds2[ i2 ] ) )
       aSeq.Append( anIds2[ i2 ] );
 
   SMESH::long_array_var aResIds = new SMESH::long_array;
   aResIds->length( aSeq.Length() );
-
-  for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
+  for ( size_t resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
     aResIds[ resI ] = aSeq( resI + 1 );
-
   aResGrp->Add( aResIds );
 
-  // Clear python lines, created by CreateGroup() and Add()
-  SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
-  _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
-  _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
-
   // Update Python script
-  TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
-                << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
+  pyDump << aResGrp << " = " << _this() << ".IntersectGroups( "
+         << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 
   return aResGrp._retn();
 }
@@ -1226,89 +1344,84 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr
   \return pointer on the group
 */
 //=============================================================================
-SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups( 
-  const SMESH::ListOfGroups& theGroups, const char* theName )
-throw (SALOME::SALOME_Exception)
+SMESH::SMESH_Group_ptr
+SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
+                                    const char*                theName )
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH::SMESH_Group_var aResGrp;
+
+  SMESH_TRY;
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   if ( !theName )
     return SMESH::SMESH_Group::_nil();
 
-  try
+  NCollection_DataMap< int, int > anIdToCount;
+  SMESH::ElementType aType = SMESH::ALL;
+  for ( int g = 0, n = theGroups.length(); g < n; g++ )
   {
-    NCollection_DataMap< int, int > anIdToCount;
-    SMESH::ElementType aType = SMESH::ALL;
-    for ( int g = 0, n = theGroups.length(); g < n; g++ )
-    {
-      SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
-      if ( CORBA::is_nil( aGrp ) )
-        continue;
-
-      // check type
-      SMESH::ElementType aCurrType = aGrp->GetType();
-      if ( aType == SMESH::ALL )
-        aType = aCurrType;
-      else 
-      {
-        if ( aType != aCurrType )
-          return SMESH::SMESH_Group::_nil();
-      }
+    SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
+    if ( CORBA::is_nil( aGrp ) )
+      continue;
 
-      // calculates number of occurance ids in groups
-      SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
-      for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
-      {
-        int aCurrId = aCurrIds[ i ];
-        if ( !anIdToCount.IsBound( aCurrId ) )
-          anIdToCount.Bind( aCurrId, 1 );
-        else 
-          anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
-      }
-    }
-    
-    // create map of ids
-    int nbGrp = theGroups.length();
-    vector< int > anIds;
-    NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
-    for ( ; anIter.More(); anIter.Next() )
+    // check type
+    SMESH::ElementType aCurrType = aGrp->GetType();
+    if ( aType == SMESH::ALL )
+      aType = aCurrType;
+    else
     {
-      int aCurrId = anIter.Key();
-      int aCurrNb = anIter.Value();
-      if ( aCurrNb == nbGrp )
-        anIds.push_back( aCurrId );
+      if ( aType != aCurrType )
+        return SMESH::SMESH_Group::_nil();
     }
 
-    // Create group
-    SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
-    if ( aResGrp->_is_nil() )
-      return SMESH::SMESH_Group::_nil();
-    
-    // Create array of identifiers
-    SMESH::long_array_var aResIds = new SMESH::long_array;
-    aResIds->length( anIds.size() );
-    
-    //NCollection_Map< int >::Iterator aListIter( anIds );
-    for ( int i = 0; i<anIds.size(); i++ )
+    // calculates number of occurance ids in groups
+    SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
+    for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
     {
-      aResIds[ i ] = anIds[i];
+      int aCurrId = aCurrIds[ i ];
+      if ( !anIdToCount.IsBound( aCurrId ) )
+        anIdToCount.Bind( aCurrId, 1 );
+      else
+        anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
     }
-    aResGrp->Add( aResIds );
+  }
 
-    // Clear python lines, created by CreateGroup() and Add()
-    SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
-    _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
-    _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
+  // create map of ids
+  int nbGrp = theGroups.length();
+  vector< int > anIds;
+  NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
+  for ( ; anIter.More(); anIter.Next() )
+  {
+    int aCurrId = anIter.Key();
+    int aCurrNb = anIter.Value();
+    if ( aCurrNb == nbGrp )
+      anIds.push_back( aCurrId );
+  }
 
-    // Update Python script
-    
-    TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
-                  << &theGroups << ", '" << theName << "' )";
+  TPythonDump pyDump;
 
-    return aResGrp._retn();
-  }
-  catch( ... )
-  {
+  // Create group
+  aResGrp = CreateGroup( aType, theName );
+  if ( aResGrp->_is_nil() )
     return SMESH::SMESH_Group::_nil();
-  }
+
+  // Create array of identifiers
+  SMESH::long_array_var aResIds = new SMESH::long_array;
+  aResIds->length( anIds.size() );
+
+  for ( size_t i = 0; i<anIds.size(); i++ )
+    aResIds[ i ] = anIds[i];
+  aResGrp->Add( aResIds );
+
+  // Update Python script
+  pyDump << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
+         << &theGroups << ", '" << theName << "' )";
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+
+  return aResGrp._retn();
 }
 
 //=============================================================================
@@ -1319,15 +1432,23 @@ throw (SALOME::SALOME_Exception)
 //=============================================================================
 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
                                                 SMESH::SMESH_GroupBase_ptr theGroup2,
-                                                const char* theName )
+                                                const char*                theName )
   throw (SALOME::SALOME_Exception)
 {
+  SMESH::SMESH_Group_var aResGrp;
+
+  SMESH_TRY;
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
        theGroup1->GetType() != theGroup2->GetType() )
     return SMESH::SMESH_Group::_nil();
 
+  TPythonDump pyDump;
+
   // Perform Cutting
-  SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
+  aResGrp = CreateGroup( theGroup1->GetType(), theName );
   if ( aResGrp->_is_nil() )
     return aResGrp;
 
@@ -1349,18 +1470,14 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGr
 
   for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
     aResIds[ resI ] = aSeq( resI + 1 );
-
   aResGrp->Add( aResIds );
 
-  // Clear python lines, created by CreateGroup() and Add()
-  SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
-  _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
-  _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
-
   // Update Python script
-  TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
-                << theGroup1 << ", " << theGroup2 << ", '"
-                << theName << "' )";
+  pyDump << aResGrp << " = " << _this() << ".CutGroups( "
+         << theGroup1 << ", " << theGroup2 << ", '"
+         << theName << "' )";
+
+  SMESH_CATCH( SMESH::throwCorbaException );
 
   return aResGrp._retn();
 }
@@ -1375,127 +1492,131 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGr
   \return pointer on the group
 */
 //=============================================================================
-SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups( 
-  const SMESH::ListOfGroups& theMainGroups, 
-  const SMESH::ListOfGroups& theToolGroups, 
-  const char* theName )
+SMESH::SMESH_Group_ptr
+SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups, 
+                              const SMESH::ListOfGroups& theToolGroups, 
+                              const char*                theName )
   throw (SALOME::SALOME_Exception)
 {
+  SMESH::SMESH_Group_var aResGrp;
+
+  SMESH_TRY;
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   if ( !theName )
     return SMESH::SMESH_Group::_nil();
 
-  try
+  set< int > aToolIds;
+  SMESH::ElementType aType = SMESH::ALL;
+  int g, n;
+  // iterate through tool groups
+  for ( g = 0, n = theToolGroups.length(); g < n; g++ )
   {
-    set< int > aToolIds;
-    SMESH::ElementType aType = SMESH::ALL;
-    int g, n;
-    // iterate through tool groups
-    for ( g = 0, n = theToolGroups.length(); g < n; g++ )
-    {
-      SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
-      if ( CORBA::is_nil( aGrp ) )
-        continue;
-
-      // check type
-      SMESH::ElementType aCurrType = aGrp->GetType();
-      if ( aType == SMESH::ALL )
-        aType = aCurrType;
-      else 
-      {
-        if ( aType != aCurrType )
-          return SMESH::SMESH_Group::_nil();
-      }
+    SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
+    if ( CORBA::is_nil( aGrp ) )
+      continue;
 
-      // unite tool ids
-      SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
-      for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
-      {
-        int aCurrId = aCurrIds[ i ];
-        aToolIds.insert( aCurrId );
-      }
+    // check type
+    SMESH::ElementType aCurrType = aGrp->GetType();
+    if ( aType == SMESH::ALL )
+      aType = aCurrType;
+    else
+    {
+      if ( aType != aCurrType )
+        return SMESH::SMESH_Group::_nil();
     }
 
-    vector< int > anIds; // result
-
-    // Iterate through main group 
-    for ( g = 0, n = theMainGroups.length(); g < n; g++ )
+    // unite tool ids
+    SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
+    for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
     {
-      SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
-      if ( CORBA::is_nil( aGrp ) )
-        continue;
+      int aCurrId = aCurrIds[ i ];
+      aToolIds.insert( aCurrId );
+    }
+  }
 
-      // check type
-      SMESH::ElementType aCurrType = aGrp->GetType();
-      if ( aType == SMESH::ALL )
-        aType = aCurrType;
-      else 
-      {
-        if ( aType != aCurrType )
-          return SMESH::SMESH_Group::_nil();
-      }
+  vector< int > anIds; // result
 
-      // unite tool ids
-      SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
-      for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
-      {
-        int aCurrId = aCurrIds[ i ];
-        if ( !aToolIds.count( aCurrId ) )
-          anIds.push_back( aCurrId );
-      }
-    }
+  // Iterate through main group 
+  for ( g = 0, n = theMainGroups.length(); g < n; g++ )
+  {
+    SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
+    if ( CORBA::is_nil( aGrp ) )
+      continue;
 
-    // Create group
-    SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
-    if ( aResGrp->_is_nil() )
-      return SMESH::SMESH_Group::_nil();
-    
-    // Create array of identifiers
-    SMESH::long_array_var aResIds = new SMESH::long_array;
-    aResIds->length( anIds.size() );
-    
-    for (int i=0; i<anIds.size(); i++ )
+    // check type
+    SMESH::ElementType aCurrType = aGrp->GetType();
+    if ( aType == SMESH::ALL )
+      aType = aCurrType;
+    else
     {
-      aResIds[ i ] = anIds[i];
+      if ( aType != aCurrType )
+        return SMESH::SMESH_Group::_nil();
     }
-    aResGrp->Add( aResIds );
 
-    // Clear python lines, created by CreateGroup() and Add()
-    SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
-    _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
-    _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
+    // unite tool ids
+    SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
+    for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
+    {
+      int aCurrId = aCurrIds[ i ];
+      if ( !aToolIds.count( aCurrId ) )
+        anIds.push_back( aCurrId );
+    }
+  }
 
-    // Update Python script
+  TPythonDump pyDump;
 
-    TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
-                  << &theMainGroups << ", " << &theToolGroups << ", '"
-                  << theName << "' )";
-    
-    return aResGrp._retn();
-  }
-  catch( ... )
-  {
+  // Create group
+  aResGrp = CreateGroup( aType, theName );
+  if ( aResGrp->_is_nil() )
     return SMESH::SMESH_Group::_nil();
-  }
+
+  // Create array of identifiers
+  SMESH::long_array_var aResIds = new SMESH::long_array;
+  aResIds->length( anIds.size() );
+
+  for (int i=0; i<anIds.size(); i++ )
+    aResIds[ i ] = anIds[i];
+  aResGrp->Add( aResIds );
+
+  // Update Python script
+  pyDump << aResGrp << " = " << _this() << ".CutListOfGroups( "
+         << &theMainGroups << ", " << &theToolGroups << ", '"
+         << theName << "' )";
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+
+  return aResGrp._retn();
 }
 
 //=============================================================================
 /*!
   \brief Create groups of entities from existing groups of superior dimensions 
-  System 
+  System
   1) extract all nodes from each group,
   2) combine all elements of specified dimension laying on these nodes.
   \param theGroups list of source groups 
   \param theElemType dimension of elements 
   \param theName name of new group
   \return pointer on new group
+  *
+  IMP 19939
 */
 //=============================================================================
-SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup( 
-  const SMESH::ListOfGroups& theGroups, 
-  SMESH::ElementType         theElemType, 
-  const char*                theName )
+
+SMESH::SMESH_Group_ptr
+SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups, 
+                             SMESH::ElementType         theElemType, 
+                             const char*                theName )
   throw (SALOME::SALOME_Exception)
 {
+  SMESH::SMESH_Group_var aResGrp;
+
+  SMESH_TRY;
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
 
   if ( !theName || !aMeshDS )
@@ -1503,145 +1624,73 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
 
   SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
 
-  try
-  {
-    // Create map of nodes from all groups 
+  // Create a group
 
-    set< int > aNodeMap;
-    
-    for ( int g = 0, n = theGroups.length(); g < n; g++ )
-    {
-      SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
-      if ( CORBA::is_nil( aGrp ) )
-        continue;
+  TPythonDump pyDump;
 
-      SMESH::ElementType aType = aGrp->GetType();
-      if ( aType == SMESH::ALL )
-        continue;
-      else if ( aType == SMESH::NODE )
-      {
-        SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
-        for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
-        {
-          int aCurrId = aCurrIds[ i ];
-          const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
-          if ( aNode )
-            aNodeMap.insert( aNode->GetID() );
-        }
-      }
-      else 
-      {
-        SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
-        for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
-        {
-          int aCurrId = aCurrIds[ i ];
-          const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
-          if ( !anElem )
-            continue;
-          SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
-          while( aNodeIter->more() )
-          {
-            const SMDS_MeshNode* aNode = 
-              dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
-            if ( aNode )
-              aNodeMap.insert( aNode->GetID() );
-          }
-        }
-      }
-    }
+  aResGrp = CreateGroup( theElemType, theName );
+  if ( aResGrp->_is_nil() )
+    return SMESH::SMESH_Group::_nil();
 
-    // Get result identifiers 
+  SMESHDS_GroupBase* groupBaseDS =
+    SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
+  SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
 
-    vector< int > aResultIds;
-    if ( theElemType == SMESH::NODE )
+  for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
+  {
+    SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
+    if ( CORBA::is_nil( aGrp ) )
+      continue;
+
+    groupBaseDS = SMESH::DownCast<SMESH_GroupBase_i*>( aGrp )->GetGroupDS();
+    SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements();
+
+    if ( theElemType == SMESH::NODE ) // get all nodes of elements
     {
-      //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
-      set<int>::iterator iter = aNodeMap.begin();
-      for ( ; iter != aNodeMap.end(); iter++ )
-        aResultIds.push_back( *iter);
+      while ( elIt->more() ) {
+        const SMDS_MeshElement* el = elIt->next();
+        SMDS_ElemIteratorPtr nIt = el->nodesIterator();
+        while ( nIt->more() )
+          resGroupCore.Add( nIt->next() );
+      }
     }
-    else
+    else // get elements of theElemType based on nodes of every element of group
     {
-      // Create list of elements of given dimension constructed on the nodes
-      vector< int > anElemList;
-      //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
-      //for ( ; aNodeIter.More(); aNodeIter.Next() )
-      set<int>::iterator iter = aNodeMap.begin();
-      for ( ; iter != aNodeMap.end(); iter++ )
+      while ( elIt->more() )
       {
-        const SMDS_MeshElement* aNode = 
-          dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( *iter ) );
-        if ( !aNode )
-          continue;
-
-         SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
-        while( anElemIter->more() )
-        {
-          const SMDS_MeshElement* anElem = 
-            dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
-          if ( anElem && anElem->GetType() == anElemType )
-            anElemList.push_back( anElem->GetID() );
-        }
-      }
-
-      // check whether all nodes of elements are present in nodes map
-      //NCollection_Map< int >::Iterator anIter( anElemList );
-      //for ( ; anIter.More(); anIter.Next() )
-      for (int i=0; i< anElemList.size(); i++)
-      {
-        const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] );
-        if ( !anElem )
-          continue;
-
-        bool isOk = true;
-        SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
-        while( aNodeIter->more() )
+        const SMDS_MeshElement* el = elIt->next(); // an element of group
+        TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
+        TIDSortedElemSet checkedElems;
+        SMDS_ElemIteratorPtr nIt = el->nodesIterator();
+        while ( nIt->more() )
         {
-          const SMDS_MeshNode* aNode = 
-            dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
-          if ( !aNode || !aNodeMap.count( aNode->GetID() ) )
+          const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
+          SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
+          // check nodes of elements of theElemType around el
+          while ( elOfTypeIt->more() )
           {
-            isOk = false;
-            break;
+            const SMDS_MeshElement* elOfType = elOfTypeIt->next();
+            if ( !checkedElems.insert( elOfType ).second ) continue;
+
+            SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
+            bool allNodesOK = true;
+            while ( nIt2->more() && allNodesOK )
+              allNodesOK = elNodes.count( nIt2->next() );
+            if ( allNodesOK )
+              resGroupCore.Add( elOfType );
           }
-        } 
-        if ( isOk )
-          aResultIds.push_back( anElem->GetID() );
+        }
       }
     }
+  }
 
-    // Create group
-
-    SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
-    if ( aResGrp->_is_nil() )
-      return SMESH::SMESH_Group::_nil();
-    
-    // Create array of identifiers
-    SMESH::long_array_var aResIds = new SMESH::long_array;
-    aResIds->length( aResultIds.size() );
-    
-    //NCollection_Map< int >::Iterator aResIter( aResultIds );
-    //for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
-    for (int i=0; i< aResultIds.size(); i++)
-      aResIds[ i ] = aResultIds[i];
-    aResGrp->Add( aResIds );
-
-    // Remove strings corresponding to group creation
-    SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
-    _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
-    _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
+  // Update Python script
+  pyDump << aResGrp << " = " << _this() << ".CreateDimGroup( "
+         << &theGroups << ", " << theElemType << ", '" << theName << "' )";
 
-    // Update Python script
-    
-    TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
-                  << &theGroups << ", " << theElemType << ", '" << theName << "' )";
+  SMESH_CATCH( SMESH::throwCorbaException );
 
-    return aResGrp._retn();
-  }
-  catch( ... )
-  {
-    return SMESH::SMESH_Group::_nil();
-  }
+  return aResGrp._retn();
 }
 
 //================================================================================
@@ -1656,13 +1705,13 @@ void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
   if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
     return;
   // group SO
-  SALOMEDS::Study_var   study  = _gen_i->GetCurrentStudy();
-  SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
+  SALOMEDS::Study_var   study   = _gen_i->GetCurrentStudy();
+  SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
   if ( groupSO->_is_nil() )
     return;
   // group indices
   GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
-  GEOM::GEOM_IGroupOperations_var groupOp =
+  GEOM::GEOM_IGroupOperations_wrap groupOp =
     geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
   GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
 
@@ -1710,7 +1759,7 @@ TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
   // get geom group
   SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
   if ( study->_is_nil() ) return newShape; // means "not changed"
-  SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
+  SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
   if ( !groupSO->_is_nil() )
   {
     CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
@@ -1720,9 +1769,9 @@ TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
     // get indices of group items
     set<int> curIndices;
     GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
-    GEOM::GEOM_IGroupOperations_var groupOp =
+    GEOM::GEOM_IGroupOperations_wrap groupOp =
       geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
-    GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
+    GEOM::ListOfLong_var   ids = groupOp->GetObjects( geomGroup );
     for ( int i = 0; i < ids->length(); ++i )
       curIndices.insert( ids[i] );
 
@@ -1737,7 +1786,7 @@ TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
     TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
     geomClient->RemoveShapeFromBuffer( groupIOR );
     newShape = _gen_i->GeomObjectToShape( geomGroup );
-  }    
+  }
 
   if ( newShape.IsNull() ) {
     // geom group becomes empty - return empty compound
@@ -1748,13 +1797,15 @@ TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
   return newShape;
 }
 
-namespace {
+namespace
+{
   //=============================================================================
   /*!
    * \brief Storage of shape and index used in CheckGeomGroupModif()
    */
   //=============================================================================
-  struct TIndexedShape {
+  struct TIndexedShape
+  {
     int          _index;
     TopoDS_Shape _shape;
     TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
@@ -1796,6 +1847,9 @@ void SMESH_Mesh_i::CheckGeomGroupModif()
     if ( newShape.IsNull() )
       continue; // no changes
 
+    if ( _preMeshInfo )
+      _preMeshInfo->ForgetOrLoad();
+
     if ( processedGroup ) { // update group indices
       list<TGeomGroupData>::iterator data2 = data;
       for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
@@ -1957,10 +2011,10 @@ void SMESH_Mesh_i::CheckGeomGroupModif()
         if ( _mapGroups.find( oldID ) == _mapGroups.end() )
           continue;
         // get group name
-        SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
-        CORBA::String_var     name    = groupSO->GetName();
+        SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
+        CORBA::String_var      name    = groupSO->GetName();
         // update
-        SMESH_GroupBase_i* group_i    = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
+        SMESH_GroupBase_i*  group_i    = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
         int newID;
         if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
           group_i->changeLocalId( newID );
@@ -1974,10 +2028,10 @@ void SMESH_Mesh_i::CheckGeomGroupModif()
   // Update icons
 
   CORBA::Long newNbEntities = NbNodes() + NbElements();
-  list< SALOMEDS::SObject_var > soToUpdateIcons;
+  list< SALOMEDS::SObject_wrap > soToUpdateIcons;
   if ( newNbEntities != nbEntities )
   {
-    // Add all SObjects with icons
+    // Add all SObjects with icons to soToUpdateIcons
     soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
 
     for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
@@ -1989,7 +2043,7 @@ void SMESH_Mesh_i::CheckGeomGroupModif()
       soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
   }
 
-  list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
+  list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
   for ( ; so != soToUpdateIcons.end(); ++so )
     _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
 }
@@ -2001,13 +2055,18 @@ void SMESH_Mesh_i::CheckGeomGroupModif()
 //=============================================================================
 
 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
+  throw (SALOME::SALOME_Exception)
 {
   SMESH::SMESH_Group_var aGroup;
+
+  SMESH_TRY;
+
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   if ( theGroup->_is_nil() )
     return aGroup._retn();
 
-  Unexpect aCatch(SALOME_SalomeException);
-
   SMESH_GroupBase_i* aGroupToRem =
     dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
   if ( !aGroupToRem )
@@ -2026,15 +2085,15 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase
   _mapGroups.erase( anId );
 
   SALOMEDS::StudyBuilder_var builder;
-  SALOMEDS::SObject_var aGroupSO;
-  SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
-  if ( !aStudy->_is_nil() )  {
-    builder = aStudy->NewBuilder();
+  SALOMEDS::SObject_wrap      aGroupSO;
+  SALOMEDS::Study_var        aStudy = _gen_i->GetCurrentStudy();
+  if ( !aStudy->_is_nil() ) {
+    builder  = aStudy->NewBuilder();
     aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
-    if ( !aGroupSO->_is_nil() ) {
-
+    if ( !aGroupSO->_is_nil() )
+    {
       // remove reference to geometry
-      SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
+      SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
       for ( ; chItr->More(); chItr->Next() )
         // Remove group's child SObject
         builder->RemoveObject( chItr->Value() );
@@ -2050,28 +2109,26 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase
         const int isEmpty = ( elemTypes->length() == 0 );
         if ( !isEmpty )
         {
-          SALOMEDS::GenericAttribute_var anAttr =
+          SALOMEDS::GenericAttribute_wrap anAttr =
             builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
-          SALOMEDS::AttributePixMap_var pm = SALOMEDS::AttributePixMap::_narrow( anAttr );
+          SALOMEDS::AttributePixMap_wrap pm = anAttr;
           pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
         }
       }
     }
   }
 
-  // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
-  SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
-  aGroupImpl->Register();
-  // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
-
   // remember new group in own map
   aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
   _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
 
   // register CORBA object for persistence
-  /*int nextId =*/ _gen_i->RegisterObject( aGroup );
+  _gen_i->RegisterObject( aGroup );
+
+  CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
+  builder->SetIOR( aGroupSO, ior.in() );
 
-  builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
+  SMESH_CATCH( SMESH::throwCorbaException );
 
   return aGroup._retn();
 }
@@ -2128,12 +2185,12 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
  */
 //=============================================================================
 
-void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
+bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
                                   GEOM::GEOM_Object_ptr    theSubShapeObject )
 {
-  MESSAGE("SMESH_Mesh_i::removeSubMesh()");
+  bool isHypChanged = false;
   if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
-    return;
+    return isHypChanged;
 
   if ( theSubShapeObject->_is_nil() )  // not published shape (IPAL13617)
   {
@@ -2144,6 +2201,7 @@ void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
       if ( !S.IsNull() )
       {
         list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
+        isHypChanged = !hyps.empty();
         list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
         for ( ; hyp != hyps.end(); ++hyp )
           _impl->RemoveHypothesis(S, (*hyp)->GetID());
@@ -2154,6 +2212,7 @@ void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
   {
     try {
       SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
+      isHypChanged = ( aHypList->length() > 0 );
       for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
         removeHypothesis( theSubShapeObject, aHypList[i] );
       }
@@ -2168,7 +2227,8 @@ void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
   _mapSubMesh.erase(subMeshId);
   _mapSubMesh_i.erase(subMeshId);
   _mapSubMeshIor.erase(subMeshId);
-  if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
+
+  return isHypChanged;
 }
 
 //=============================================================================
@@ -2206,11 +2266,6 @@ SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType
     else
       aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
 
-    // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
-    SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
-    aGroupImpl->Register();
-    // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
-
     aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
     _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
 
@@ -2257,56 +2312,57 @@ void SMESH_Mesh_i::removeGroup( const int theId )
 //=============================================================================
 
 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
-throw(SALOME::SALOME_Exception)
+  throw(SALOME::SALOME_Exception)
 {
-  if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
-
   SMESH::log_array_var aLog;
-  try{
-    list < SMESHDS_Command * >logDS = _impl->GetLog();
-    aLog = new SMESH::log_array;
-    int indexLog = 0;
-    int lg = logDS.size();
-    SCRUTE(lg);
-    aLog->length(lg);
-    list < SMESHDS_Command * >::iterator its = logDS.begin();
-    while(its != logDS.end()){
-      SMESHDS_Command *com = *its;
-      int comType = com->GetType();
-      //SCRUTE(comType);
-      int lgcom = com->GetNumber();
-      //SCRUTE(lgcom);
-      const list < int >&intList = com->GetIndexes();
-      int inum = intList.size();
-      //SCRUTE(inum);
-      list < int >::const_iterator ii = intList.begin();
-      const list < double >&coordList = com->GetCoords();
-      int rnum = coordList.size();
-      //SCRUTE(rnum);
-      list < double >::const_iterator ir = coordList.begin();
-      aLog[indexLog].commandType = comType;
-      aLog[indexLog].number = lgcom;
-      aLog[indexLog].coords.length(rnum);
-      aLog[indexLog].indexes.length(inum);
-      for(int i = 0; i < rnum; i++){
-        aLog[indexLog].coords[i] = *ir;
-        //MESSAGE(" "<<i<<" "<<ir.Value());
-        ir++;
-      }
-      for(int i = 0; i < inum; i++){
-        aLog[indexLog].indexes[i] = *ii;
-        //MESSAGE(" "<<i<<" "<<ii.Value());
-        ii++;
-      }
-      indexLog++;
-      its++;
+
+  SMESH_TRY;
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
+  list < SMESHDS_Command * >logDS = _impl->GetLog();
+  aLog = new SMESH::log_array;
+  int indexLog = 0;
+  int lg = logDS.size();
+  SCRUTE(lg);
+  aLog->length(lg);
+  list < SMESHDS_Command * >::iterator its = logDS.begin();
+  while(its != logDS.end()){
+    SMESHDS_Command *com = *its;
+    int comType = com->GetType();
+    //SCRUTE(comType);
+    int lgcom = com->GetNumber();
+    //SCRUTE(lgcom);
+    const list < int >&intList = com->GetIndexes();
+    int inum = intList.size();
+    //SCRUTE(inum);
+    list < int >::const_iterator ii = intList.begin();
+    const list < double >&coordList = com->GetCoords();
+    int rnum = coordList.size();
+    //SCRUTE(rnum);
+    list < double >::const_iterator ir = coordList.begin();
+    aLog[indexLog].commandType = comType;
+    aLog[indexLog].number = lgcom;
+    aLog[indexLog].coords.length(rnum);
+    aLog[indexLog].indexes.length(inum);
+    for(int i = 0; i < rnum; i++){
+      aLog[indexLog].coords[i] = *ir;
+      //MESSAGE(" "<<i<<" "<<ir.Value());
+      ir++;
     }
-    if(clearAfterGet)
-      _impl->ClearLog();
-  }
-  catch(SALOME_Exception & S_ex){
-    THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+    for(int i = 0; i < inum; i++){
+      aLog[indexLog].indexes[i] = *ii;
+      //MESSAGE(" "<<i<<" "<<ii.Value());
+      ii++;
+    }
+    indexLog++;
+    its++;
   }
+  if(clearAfterGet)
+    _impl->ClearLog();
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+
   return aLog._retn();
 }
 
@@ -2319,8 +2375,9 @@ throw(SALOME::SALOME_Exception)
 
 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
 {
-  if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
+  SMESH_TRY;
   _impl->ClearLog();
+  SMESH_CATCH( SMESH::throwCorbaException );
 }
 
 //=============================================================================
@@ -2331,7 +2388,6 @@ void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
 
 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
 {
-  if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
   return _id;
 }
 
@@ -2349,16 +2405,31 @@ CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
 //=============================================================================
 namespace
 {
-  //!< implementation of struct used to call SMESH_Mesh_i::removeGroup() from
-  // SMESH_Mesh::RemoveGroup() (issue 0020918)
-  struct TRmGroupCallUp_i : public SMESH_Mesh::TRmGroupCallUp
+  //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
+  // issue 0020918: groups removal is caused by hyp modification
+  // issue 0021208: to forget not loaded mesh data at hyp modification
+  struct TCallUp_i : public SMESH_Mesh::TCallUp
   {
     SMESH_Mesh_i* _mesh;
-    TRmGroupCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
+    TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
     virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
+    virtual void HypothesisModified ()              { _mesh->onHypothesisModified(); }
+    virtual void Load ()                            { _mesh->Load(); }
   };
 }
 
+//================================================================================
+/*!
+ * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
+ */
+//================================================================================
+
+void SMESH_Mesh_i::onHypothesisModified()
+{
+  if ( _preMeshInfo )
+    _preMeshInfo->ForgetOrLoad();
+}
+
 //=============================================================================
 /*!
  *
@@ -2370,7 +2441,7 @@ void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
   if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
   _impl = impl;
   if ( _impl )
-    _impl->SetRemoveGroupCallUp( new TRmGroupCallUp_i(this));
+    _impl->SetCallUp( new TCallUp_i(this));
 }
 
 //=============================================================================
@@ -2392,15 +2463,24 @@ void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
 //=============================================================================
 
 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH::SMESH_MeshEditor_var aMeshEdVar;
+
+  SMESH_TRY;
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   // Create MeshEditor
   SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
-  SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
+  aMeshEdVar = aMeshEditor->_this();
 
   // Update Python script
   TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
 
-  return aMesh._retn();
+  SMESH_CATCH( SMESH::throwCorbaException );
+
+  return aMeshEdVar._retn();
 }
 
 //=============================================================================
@@ -2410,10 +2490,20 @@ SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
 //=============================================================================
 
 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH::SMESH_MeshEditor_var aMeshEdVar;
+
+  SMESH_TRY;
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
-  SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
-  return aMesh._retn();
+  aMeshEdVar = aMeshEditor->_this();
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+
+  return aMeshEdVar._retn();
 }
 
 //================================================================================
@@ -2429,6 +2519,12 @@ CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Ex
   return _impl->HasModificationsToDiscard();
 }
 
+//================================================================================
+/*!
+ * \brief Returns a random unique color
+ */
+//================================================================================
+
 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
 {
   const int MAX_ATTEMPTS = 100;
@@ -2461,9 +2557,10 @@ static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theRese
 
 //=============================================================================
 /*!
- *
+ * Sets auto-color mode. If it is on, groups get unique random colors
  */
 //=============================================================================
+
 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
@@ -2484,19 +2581,19 @@ void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOM
 
 //=============================================================================
 /*!
- *
+ * Returns true if auto-color mode is on
  */
 //=============================================================================
+
 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
   return _impl->GetAutoColor();
 }
 
-
 //=============================================================================
 /*!
- *  Export in different formats
+ *  Checks if there are groups with equal names
  */
 //=============================================================================
 
@@ -2505,6 +2602,12 @@ CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
   return _impl->HasDuplicatedGroupNamesMED();
 }
 
+//================================================================================
+/*!
+ * \brief Care of a file before exporting mesh into it
+ */
+//================================================================================
+
 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
 {
   TCollection_AsciiString aFullName ((char*)file);
@@ -2548,31 +2651,38 @@ void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
   }
 }
 
-string SMESH_Mesh_i::PrepareMeshNameAndGroups(const char* file,
+//================================================================================
+/*!
+ * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
+ *  \param file - file name
+ *  \param overwrite - to erase the file or not
+ *  \retval string - mesh name
+ */
+//================================================================================
+
+string SMESH_Mesh_i::prepareMeshNameAndGroups(const char*    file,
                                               CORBA::Boolean overwrite)
 {
   // Perform Export
   PrepareForWriting(file, overwrite);
   string aMeshName = "Mesh";
-  SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+  SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
   if ( !aStudy->_is_nil() ) {
-    SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
+    SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
     if ( !aMeshSO->_is_nil() ) {
       CORBA::String_var name = aMeshSO->GetName();
       aMeshName = name;
       // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
       if ( !aStudy->GetProperties()->IsLocked() )
       {
-        SALOMEDS::GenericAttribute_var anAttr;
+        SALOMEDS::GenericAttribute_wrap anAttr;
         SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
-        SALOMEDS::AttributeExternalFileDef_var aFileName;
         anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
-        aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
+        SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
         ASSERT(!aFileName->_is_nil());
         aFileName->SetValue(file);
-        SALOMEDS::AttributeFileType_var aFileType;
         anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
-        aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
+        SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
         ASSERT(!aFileType->_is_nil());
         aFileType->SetValue("FICHIERMED");
       }
@@ -2588,14 +2698,23 @@ string SMESH_Mesh_i::PrepareMeshNameAndGroups(const char* file,
   return aMeshName;
 }
 
-void SMESH_Mesh_i::ExportToMEDX (const char* file,
-                                 CORBA::Boolean auto_groups,
+//================================================================================
+/*!
+ * \brief Export to med file
+ */
+//================================================================================
+
+void SMESH_Mesh_i::ExportToMEDX (const char*        file,
+                                 CORBA::Boolean     auto_groups,
                                  SMESH::MED_VERSION theVersion,
-                                 CORBA::Boolean overwrite)
+                                 CORBA::Boolean     overwrite)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
-  string aMeshName = PrepareMeshNameAndGroups(file, overwrite);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
+  string aMeshName = prepareMeshNameAndGroups(file, overwrite);
   TPythonDump() << _this() << ".ExportToMEDX( r'"
                 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
 
@@ -2608,8 +2727,8 @@ void SMESH_Mesh_i::ExportToMEDX (const char* file,
  */
 //================================================================================
 
-void SMESH_Mesh_i::ExportToMED (const char* file,
-                                CORBA::Boolean auto_groups,
+void SMESH_Mesh_i::ExportToMED (const char*        file,
+                                CORBA::Boolean     auto_groups,
                                 SMESH::MED_VERSION theVersion)
   throw(SALOME::SALOME_Exception)
 {
@@ -2640,7 +2759,10 @@ void SMESH_Mesh_i::ExportSAUV (const char* file,
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
-  string aMeshName = PrepareMeshNameAndGroups(file, true);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
+  string aMeshName = prepareMeshNameAndGroups(file, true);
   TPythonDump() << _this() << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
   _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
 }
@@ -2656,6 +2778,8 @@ void SMESH_Mesh_i::ExportDAT (const char *file)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
 
   // Update Python script
   // check names of groups
@@ -2677,6 +2801,8 @@ void SMESH_Mesh_i::ExportUNV (const char *file)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
 
   // Update Python script
   // check names of groups
@@ -2698,6 +2824,8 @@ void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
 
   // Update Python script
   // check names of groups
@@ -2709,36 +2837,6 @@ void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
   _impl->ExportSTL(file, isascii);
 }
 
-//=============================================================================
-/*!
- * \brief Class providing SMESHDS_Mesh API to SMESH_IDSource. 
- *        It is used to export a part of mesh as a whole mesh.
- */
-class SMESH_MeshPartDS : public SMESHDS_Mesh
-{
-public:
-  SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart);
-
-  virtual SMDS_NodeIteratorPtr      nodesIterator     (bool idInceasingOrder=false) const;
-  virtual SMDS_0DElementIteratorPtr elements0dIterator(bool idInceasingOrder=false) const;
-  virtual SMDS_EdgeIteratorPtr      edgesIterator     (bool idInceasingOrder=false) const;
-  virtual SMDS_FaceIteratorPtr      facesIterator     (bool idInceasingOrder=false) const;
-  virtual SMDS_VolumeIteratorPtr    volumesIterator   (bool idInceasingOrder=false) const;
-
-  virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type=SMDSAbs_All) const;
-
-private:
-  TIDSortedElemSet _elements[ SMDSAbs_NbElementTypes ];
-  SMESHDS_Mesh*    _meshDS;
-  /*!
-   * \brief Class used to access to protected data of SMDS_MeshInfo
-   */
-  struct TMeshInfo : public SMDS_MeshInfo
-  {
-    void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
-  };
-};
-
 //================================================================================
 /*!
  * \brief Export a part of mesh to a med file
@@ -2753,13 +2851,15 @@ void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
   throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
 
   PrepareForWriting(file, overwrite);
 
   string aMeshName = "Mesh";
-  SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+  SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
   if ( !aStudy->_is_nil() ) {
-    SALOMEDS::SObject_var SO = _gen_i->ObjectToSObject( aStudy, meshPart );
+    SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
     if ( !SO->_is_nil() ) {
       CORBA::String_var name = SO->GetName();
       aMeshName = name;
@@ -2783,6 +2883,8 @@ void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
   throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
 
   PrepareForWriting(file);
 
@@ -2802,6 +2904,8 @@ void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
   throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
 
   PrepareForWriting(file);
 
@@ -2822,6 +2926,8 @@ void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
   throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
 
   PrepareForWriting(file);
 
@@ -2845,6 +2951,8 @@ void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
 {
 #ifdef WITH_CGNS
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
 
   PrepareForWriting(file,overwrite);
 
@@ -2858,61 +2966,93 @@ void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
 #endif
 }
 
+//================================================================================
+/*!
+ * \brief Export a part of mesh to a GMF file
+ */
+//================================================================================
+
+void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
+                             const char*                 file,
+                             bool                        withRequiredGroups)
+  throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
+  PrepareForWriting(file,/*overwrite=*/true);
+
+  SMESH_MeshPartDS partDS( meshPart );
+  _impl->ExportGMF(file, &partDS, withRequiredGroups);
+
+  TPythonDump() << _this() << ".ExportGMF( "
+                << meshPart<< ", r'"
+                << file << "', "
+                << withRequiredGroups << ")";
+}
+
 //=============================================================================
 /*!
- *
+ * Return implementation of SALOME_MED::MESH interfaces
  */
 //=============================================================================
 
 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
   SALOME_MED::MESH_var aMesh = aMedMesh->_this();
   return aMesh._retn();
 }
 
 //=============================================================================
-/*!
- *
- */
-//=============================================================================
+
 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbNodes();
+
   return _impl->NbNodes();
 }
 
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
-  return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbElements();
+
+  return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
 }
 
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->Nb0DElements();
+
   return _impl->Nb0DElements();
 }
 
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
+CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbBalls();
+
+  return _impl->NbBalls();
+}
+
 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbEdges();
+
   return _impl->NbEdges();
 }
 
@@ -2920,41 +3060,56 @@ CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
+
   return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
 }
 
 //=============================================================================
-/*!
- *
- */
-//=============================================================================
+
 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbFaces();
+
   return _impl->NbFaces();
 }
 
 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbTriangles();
+
   return _impl->NbTriangles();
 }
 
 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbQuadrangles();
+
   return _impl->NbQuadrangles();
 }
 
 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbBiQuadQuadrangles();
+
   return _impl->NbBiQuadQuadrangles();
 }
 
 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbPolygons();
+
   return _impl->NbPolygons();
 }
 
@@ -2962,6 +3117,9 @@ CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
+
   return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
 }
 
@@ -2969,6 +3127,9 @@ CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
+
   return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
 }
 
@@ -2976,59 +3137,83 @@ CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
+
   return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
 }
 
 //=============================================================================
-/*!
- *
- */
-//=============================================================================
+
 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbVolumes();
+
   return _impl->NbVolumes();
 }
 
 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbTetras();
+
   return _impl->NbTetras();
 }
 
 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbHexas();
+
   return _impl->NbHexas();
 }
 
 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbTriQuadHexas();
+
   return _impl->NbTriQuadraticHexas();
 }
 
 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbPyramids();
+
   return _impl->NbPyramids();
 }
 
 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbPrisms();
+
   return _impl->NbPrisms();
 }
 
 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbHexPrisms();
+
   return _impl->NbHexagonalPrisms();
 }
 
 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbPolyhedrons();
+
   return _impl->NbPolyhedrons();
 }
 
@@ -3036,6 +3221,9 @@ CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
+
   return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
 }
 
@@ -3043,6 +3231,9 @@ CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
+
   return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
 }
 
@@ -3050,6 +3241,9 @@ CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
+
   return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
 }
 
@@ -3057,6 +3251,9 @@ CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
+
   return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
 }
 
@@ -3064,14 +3261,18 @@ CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
   throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
+  if ( _preMeshInfo )
+    return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
+
   return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
 }
 
 //=============================================================================
 /*!
- *
+ * Returns nb of published sub-meshes
  */
 //=============================================================================
+
 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
@@ -3080,9 +3281,10 @@ CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
 
 //=============================================================================
 /*!
- *
+ * Dumps mesh into a string
  */
 //=============================================================================
+
 char* SMESH_Mesh_i::Dump()
 {
   ostringstream os;
@@ -3092,29 +3294,18 @@ char* SMESH_Mesh_i::Dump()
 
 //=============================================================================
 /*!
- *
+ * Method of SMESH_IDSource interface
  */
 //=============================================================================
+
 SMESH::long_array* SMESH_Mesh_i::GetIDs()
 {
-//   SMESH::long_array_var aResult = new SMESH::long_array();
-//   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
-//   int aMinId = aSMESHDS_Mesh->MinElementID();
-//   int aMaxId =  aSMESHDS_Mesh->MaxElementID();
-
-//   aResult->length(aMaxId - aMinId + 1);
-
-//   for (int i = 0, id = aMinId; id <= aMaxId; id++  )
-//     aResult[i++] = id;
-
-//   return aResult._retn();
-  // PAL12398
   return GetElementsId();
 }
 
 //=============================================================================
 /*!
- *
+ * Returns ids of all elements
  */
 //=============================================================================
 
@@ -3122,7 +3313,9 @@ SMESH::long_array* SMESH_Mesh_i::GetElementsId()
      throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
-  MESSAGE("SMESH_Mesh_i::GetElementsId");
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::long_array_var aResult = new SMESH::long_array();
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
 
@@ -3141,7 +3334,7 @@ SMESH::long_array* SMESH_Mesh_i::GetElementsId()
 
 //=============================================================================
 /*!
- *
+ * Returns ids of all elements of given type
  */
 //=============================================================================
 
@@ -3149,7 +3342,9 @@ SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemTy
     throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
-  MESSAGE("SMESH_subMesh_i::GetElementsByType");
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::long_array_var aResult = new SMESH::long_array();
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
 
@@ -3182,7 +3377,7 @@ SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemTy
 
 //=============================================================================
 /*!
- *
+ * Returns ids of all nodes
  */
 //=============================================================================
 
@@ -3190,7 +3385,9 @@ SMESH::long_array* SMESH_Mesh_i::GetNodesId()
   throw (SALOME::SALOME_Exception)
 {
   Unexpect aCatch(SALOME_SalomeException);
-  MESSAGE("SMESH_subMesh_i::GetNodesId");
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::long_array_var aResult = new SMESH::long_array();
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
 
@@ -3215,7 +3412,17 @@ SMESH::long_array* SMESH_Mesh_i::GetNodesId()
 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
   throw (SALOME::SALOME_Exception)
 {
-  return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
+  SMESH::ElementType type;
+  SMESH_TRY;
+
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
+  type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+
+  return type;
 }
 
 //=============================================================================
@@ -3227,6 +3434,9 @@ SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const boo
 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
   throw (SALOME::SALOME_Exception)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
   if ( !e )
     THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
@@ -3244,6 +3454,10 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
 {
   SMESH::long_array_var aResult = new SMESH::long_array();
 
+  SMESH_TRY;
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
   if(!SM) return aResult._retn();
 
@@ -3258,6 +3472,8 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
     aResult[i++] = eIt->next()->GetID();
   }
 
+  SMESH_CATCH( SMESH::throwCorbaException );
+
   return aResult._retn();
 }
 
@@ -3269,11 +3485,16 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
  * returns only nodes on shapes.
  */
 //=============================================================================
-SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
-     throw (SALOME::SALOME_Exception)
+SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
+                                                   CORBA::Boolean    all)
+  throw (SALOME::SALOME_Exception)
 {
   SMESH::long_array_var aResult = new SMESH::long_array();
 
+  SMESH_TRY;
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
   if(!SM) return aResult._retn();
 
@@ -3306,18 +3527,26 @@ SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CO
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
     aResult[i++] = *itElem;
 
+  SMESH_CATCH( SMESH::throwCorbaException );
+
   return aResult._retn();
 }
   
-
 //=============================================================================
 /*!
  * Returns type of elements for given submesh
  */
 //=============================================================================
+
 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
-     throw (SALOME::SALOME_Exception)
+  throw (SALOME::SALOME_Exception)
 {
+  SMESH::ElementType type;
+
+  SMESH_TRY;
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
   if(!SM) return SMESH::ALL;
 
@@ -3329,18 +3558,26 @@ SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID
 
   SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
   const SMDS_MeshElement* anElem = eIt->next();
-  return ( SMESH::ElementType ) anElem->GetType();
+
+  type = ( SMESH::ElementType ) anElem->GetType();
+
+  SMESH_CATCH( SMESH::throwCorbaException );
+
+  return type; 
 }
   
 
 //=============================================================================
 /*!
- *
+ * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
  */
 //=============================================================================
 
 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   CORBA::LongLong pointeur = CORBA::LongLong(_impl);
   if ( MYDEBUG )
     MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
@@ -3357,6 +3594,9 @@ CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
 
 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::double_array_var aResult = new SMESH::double_array();
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL )
@@ -3385,6 +3625,9 @@ SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
 
 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::long_array_var aResult = new SMESH::long_array();
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL )
@@ -3420,6 +3663,9 @@ SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
 
 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
   aNodePosition->shapeID = 0;
   aNodePosition->shapeType = GEOM::SHAPE;
@@ -3472,6 +3718,9 @@ SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
 
 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL )
     return -1;
@@ -3496,6 +3745,9 @@ CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
 
 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL )
     return -1;
@@ -3505,7 +3757,6 @@ CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
   if(!elem)
     return -1;
 
-  //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
   ::SMESH_MeshEditor aMeshEditor(_impl);
   int index = aMeshEditor.FindShape( elem );
   if(index>0)
@@ -3524,6 +3775,9 @@ CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
 
 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL ) return -1;
   // try to find element
@@ -3543,6 +3797,9 @@ CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
 
 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL ) return -1;
   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
@@ -3559,6 +3816,9 @@ CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long in
 
 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::long_array_var aResult = new SMESH::long_array();
   if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
   {
@@ -3581,6 +3841,9 @@ SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
 
 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL ) return false;
   // try to find node
@@ -3604,6 +3867,9 @@ CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Lo
 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
                                                    SMESH::ElementType theElemType)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL ) return false;
 
@@ -3631,6 +3897,9 @@ CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
 
 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL ) return -1;
   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
@@ -3647,6 +3916,9 @@ CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
 
 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL ) return -1;
   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
@@ -3662,6 +3934,9 @@ CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long  elemId,
                                                   CORBA::Short faceIndex)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::long_array_var aResult = new SMESH::long_array();
   if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
   {
@@ -3687,6 +3962,9 @@ SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long  elemId,
 
 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   CORBA::Long elemID(0);
   if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
   {
@@ -3696,8 +3974,8 @@ CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
         return elemID;
 
     const SMDS_MeshElement* elem = mesh->FindElement( nn );
-    if ( !elem && ( _impl->NbEdges( ORDER_QUADRATIC ) ||
-                    _impl->NbFaces( ORDER_QUADRATIC ) ||
+    if ( !elem && ( _impl->NbEdges  ( ORDER_QUADRATIC ) ||
+                    _impl->NbFaces  ( ORDER_QUADRATIC ) ||
                     _impl->NbVolumes( ORDER_QUADRATIC )))
       elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
 
@@ -3714,6 +3992,9 @@ CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
 
 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL ) return false;
   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
@@ -3730,6 +4011,9 @@ CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
 
 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL ) return false;
   const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
@@ -3737,6 +4021,23 @@ CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
   return elem->IsQuadratic();
 }
 
+//=============================================================================
+/*!
+ * Returns diameter of ball discrete element or zero in case of an invalid \a id
+ */
+//=============================================================================
+
+CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
+{
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
+  if ( const SMDS_BallElement* ball =
+       dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
+    return ball->GetDiameter();
+
+  return 0;
+}
 
 //=============================================================================
 /*!
@@ -3746,6 +4047,9 @@ CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
 
 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->FullLoadFromFile();
+
   SMESH::double_array_var aResult = new SMESH::double_array();
   SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
   if ( aSMESHDS_Mesh == NULL )
@@ -3793,9 +4097,9 @@ SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
  */
 //=============================================================================
 
-void SMESH_Mesh_i::CreateGroupServants() 
+void SMESH_Mesh_i::CreateGroupServants()
 {
-  SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+  SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
 
   set<int> addedIDs;
   ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
@@ -3821,10 +4125,6 @@ void SMESH_Mesh_i::CreateGroupServants()
       aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
     }
 
-    // To ensure correct mapping of servant and correct reference counting in GenericObj_i
-    SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
-    aGroupImpl->Register();
-
     SMESH::SMESH_GroupBase_var groupVar =
       SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
     _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
@@ -3883,7 +4183,7 @@ SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
 
 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
 {
-  SALOME_MED::MedFileInfo_var res( myFileInfo );
+  SALOME_MED::MedFileInfo_var res( _medFileInfo );
   if ( !res.operator->() ) {
     res = new SALOME_MED::MedFileInfo;
     res->fileName = "";
@@ -3894,7 +4194,7 @@ SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
 
 //=============================================================================
 /*!
- * \brief Check and correct names of mesh groups
+ * \brief Pass names of mesh groups from study to mesh DS
  */
 //=============================================================================
 
@@ -3904,7 +4204,7 @@ void SMESH_Mesh_i::checkGroupNames()
   if ( !nbGrp )
     return;
 
-  SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
+  SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
   if ( aStudy->_is_nil() )
     return; // nothing to do
   
@@ -3920,7 +4220,7 @@ void SMESH_Mesh_i::checkGroupNames()
     SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
     if ( !aGrp )
       continue;
-    SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
+    SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
     if ( aGrpSO->_is_nil() )
       continue;
     // correct name of the mesh group if necessary
@@ -3937,8 +4237,9 @@ void SMESH_Mesh_i::checkGroupNames()
 //=============================================================================
 void SMESH_Mesh_i::SetParameters(const char* theParameters)
 {
-  SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
-                                               CORBA::string_dup(theParameters));
+  // SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
+  //                                              CORBA::string_dup(theParameters));
+  SMESH_Gen_i::GetSMESHGen()->UpdateParameters(theParameters);
 }
 
 //=============================================================================
@@ -3963,7 +4264,7 @@ SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
   SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
   if(gen) {
     char *aParameters = GetParameters();
-    SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
+    SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
     if(!aStudy->_is_nil()) {
       SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters); 
       if(aSections->length() > 0) {
@@ -3984,18 +4285,18 @@ SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
 
 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
 {
+  if ( _preMeshInfo )
+    return _preMeshInfo->GetTypes();
+
   SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
 
-  types->length( 4 );
+  types->length( 5 );
   int nbTypes = 0;
-  if (_impl->NbEdges())
-    types[nbTypes++] = SMESH::EDGE;
-  if (_impl->NbFaces())
-    types[nbTypes++] = SMESH::FACE;
-  if (_impl->NbVolumes())
-    types[nbTypes++] = SMESH::VOLUME;
-  if (_impl->Nb0DElements())
-    types[nbTypes++] = SMESH::ELEM0D;
+  if (_impl->NbEdges())      types[nbTypes++] = SMESH::EDGE;
+  if (_impl->NbFaces())      types[nbTypes++] = SMESH::FACE;
+  if (_impl->NbVolumes())    types[nbTypes++] = SMESH::VOLUME;
+  if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
+  if (_impl->NbBalls())      types[nbTypes++] = SMESH::BALL;
   types->length( nbTypes );
 
   return types._retn();
@@ -4011,13 +4312,28 @@ SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
   return SMESH::SMESH_Mesh::_duplicate( _this() );
 }
 
+//=======================================================================
+//function : IsMeshInfoCorrect
+//purpose  : * Returns false if GetMeshInfo() returns incorrect information that may
+//           * happen if mesh data is not yet fully loaded from the file of study.
+//=======================================================================
+
+bool SMESH_Mesh_i::IsMeshInfoCorrect()
+{
+  return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
+}
+
 //=============================================================================
 /*!
  * \brief Returns statistic of mesh elements
  */
 //=============================================================================
+
 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
 {
+  if ( _preMeshInfo )
+    return _preMeshInfo->GetMeshInfo();
+
   SMESH::long_array_var aRes = new SMESH::long_array();
   aRes->length(SMESH::Entity_Last);
   for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
@@ -4036,6 +4352,7 @@ SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
  * \brief Collect statistic of mesh elements given by iterator
  */
 //=============================================================================
+
 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
                                    SMESH::long_array&         theInfo)
 {
@@ -4045,11 +4362,14 @@ void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
 }
 
 //=============================================================================
+namespace // Finding concurrent hypotheses
+//=============================================================================
+{
+
 /*!
  * \brief mapping of mesh dimension into shape type
  */
-//=============================================================================
-static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
+TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
 {
   TopAbs_ShapeEnum aType = TopAbs_SOLID;
   switch ( theDim ) {
@@ -4062,7 +4382,7 @@ static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
   return aType;
 }
 
-//=============================================================================
+//-----------------------------------------------------------------------------
 /*!
  * \brief Internal structure used to find concurent submeshes
  *
@@ -4071,8 +4391,6 @@ static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
  *  with another submesh. In other words, it is dimension of a hypothesis assigned
  *  to submesh.
  */
-//=============================================================================
-
 class SMESH_DimHyp
 {
  public:
@@ -4081,8 +4399,14 @@ class SMESH_DimHyp
   int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
   TopTools_MapOfShape _shapeMap;
   SMESH_subMesh*      _subMesh;
-  list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
+  list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
+
+  //-----------------------------------------------------------------------------
+  // Return the algorithm
+  const SMESH_Algo* GetAlgo() const
+  { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
 
+  //-----------------------------------------------------------------------------
   //! Constructors
   SMESH_DimHyp(const SMESH_subMesh*  theSubMesh,
                const int             theDim,
@@ -4092,8 +4416,9 @@ class SMESH_DimHyp
     SetShape( theDim, theShape );
   }
 
+  //-----------------------------------------------------------------------------
   //! set shape
-  void SetShape(const int theDim,
+  void SetShape(const int           theDim,
                 const TopoDS_Shape& theShape)
   {
     _dim = theDim;
@@ -4107,6 +4432,7 @@ class SMESH_DimHyp
     }
   }
 
+  //-----------------------------------------------------------------------------
   //! Check sharing of sub-shapes
   static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
                                const TopTools_MapOfShape& theToFind,
@@ -4114,7 +4440,8 @@ class SMESH_DimHyp
   {
     bool isShared = false;
     TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
-    for (; !isShared && anItr.More(); anItr.Next() ) {
+    for (; !isShared && anItr.More(); anItr.Next() )
+    {
       const TopoDS_Shape aSubSh = anItr.Key();
       // check for case when concurrent dimensions are same
       isShared = theToFind.Contains( aSubSh );
@@ -4126,11 +4453,13 @@ class SMESH_DimHyp
     return isShared;
   }
   
+  //-----------------------------------------------------------------------------
   //! check algorithms
   static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
                         const SMESHDS_Hypothesis* theA2)
   {
-    if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
+    if ( !theA1 || !theA2 ||
+         theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
          theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
       return false; // one of the hypothesis is not algorithm
     // check algorithm names (should be equal)
@@ -4138,6 +4467,7 @@ class SMESH_DimHyp
   }
 
   
+  //-----------------------------------------------------------------------------
   //! Check if sub-shape hypotheses are concurrent
   bool IsConcurrent(const SMESH_DimHyp* theOther) const
   {
@@ -4147,8 +4477,10 @@ class SMESH_DimHyp
     // if ( <own dim of either of submeshes> == <concurrent dim> &&
     //      any of the two submeshes is not on COMPOUND shape )
     //  -> no concurrency
-    bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
-    bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
+    bool meIsCompound    = (_subMesh->GetSubMeshDS() &&
+                            _subMesh->GetSubMeshDS()->IsComplexSubmesh());
+    bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
+                            theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
     if ( (_ownDim == _dim  || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
       return false;
 
@@ -4160,65 +4492,102 @@ class SMESH_DimHyp
         return false;
 
     // check algorithms to be same
-    if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
-      return true; // different algorithms
-    
+    if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
+      return true; // different algorithms -> concurrency !
+
     // check hypothesises for concurrence (skip first as algorithm)
     int nbSame = 0;
-    // pointers should be same, becase it is referenes from mesh hypothesis partition
-    list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
-    list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
-    for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
-      if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
+    // pointers should be same, because it is referened from mesh hypothesis partition
+    list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
+    list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
+    for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
+      if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
         nbSame++;
     // the submeshes are concurrent if their algorithms has different parameters
-    return nbSame != theOther->_hypothesises.size() - 1;
+    return nbSame != theOther->_hypotheses.size() - 1;
+  }
+
+  // Return true if algorithm of this SMESH_DimHyp is used if no
+  // sub-mesh order is imposed by the user
+  bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
+  {
+    // NeedDiscreteBoundary() algo has a higher priority
+    if ( this    ->GetAlgo()->NeedDiscreteBoundary() !=
+         theOther->GetAlgo()->NeedDiscreteBoundary() )
+      return !this->GetAlgo()->NeedDiscreteBoundary();
+
+    return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
   }
   
 }; // end of SMESH_DimHyp
+//-----------------------------------------------------------------------------
+
+typedef list<const SMESH_DimHyp*> TDimHypList;
 
-typedef list<SMESH_DimHyp*> TDimHypList;
+//-----------------------------------------------------------------------------
 
-static void addDimHypInstance(const int               theDim, 
-                              const TopoDS_Shape&     theShape,
-                              const SMESH_Algo*       theAlgo,
-                              const SMESH_subMesh*    theSubMesh,
-                              const list <const SMESHDS_Hypothesis*>& theHypList,
-                              TDimHypList*            theDimHypListArr )
+void addDimHypInstance(const int                               theDim, 
+                       const TopoDS_Shape&                     theShape,
+                       const SMESH_Algo*                       theAlgo,
+                       const SMESH_subMesh*                    theSubMesh,
+                       const list <const SMESHDS_Hypothesis*>& theHypList,
+                       TDimHypList*                            theDimHypListArr )
 {
   TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
   if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
     SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
+    dimHyp->_hypotheses.push_front(theAlgo);
     listOfdimHyp.push_back( dimHyp );
   }
   
-  SMESH_DimHyp* dimHyp = listOfdimHyp.back();
-  dimHyp->_hypothesises.push_front(theAlgo);
-  list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
-  for( ; hypIt != theHypList.end(); hypIt++ )
-    dimHyp->_hypothesises.push_back( *hypIt );
+  SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
+  dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
+                              theHypList.begin(), theHypList.end() );
+}
+
+//-----------------------------------------------------------------------------
+void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
+                           TDimHypList&        theListOfConcurr)
+{
+  if ( theListOfConcurr.empty() )
+  {
+    theListOfConcurr.push_back( theDimHyp );
+  }
+  else
+  {
+    TDimHypList::iterator hypIt = theListOfConcurr.begin();
+    while ( hypIt != theListOfConcurr.end() &&
+            !theDimHyp->IsHigherPriorityThan( *hypIt ))
+      ++hypIt;
+    theListOfConcurr.insert( hypIt, theDimHyp );
+  }
 }
 
-static void findConcurrents(const SMESH_DimHyp* theDimHyp,
-                            const TDimHypList&  theListOfDimHyp,
-                            TListOfInt&         theListOfConcurr )
+//-----------------------------------------------------------------------------
+void findConcurrents(const SMESH_DimHyp* theDimHyp,
+                     const TDimHypList&  theListOfDimHyp,
+                     TDimHypList&        theListOfConcurrHyp,
+                     set<int>&           theSetOfConcurrId )
 {
   TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
-  for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
+  for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
+  {
     const SMESH_DimHyp* curDimHyp = *rIt;
     if ( curDimHyp == theDimHyp )
       break; // meet own dimHyp pointer in same dimension
-    else if ( theDimHyp->IsConcurrent( curDimHyp ) )
-      if ( find( theListOfConcurr.begin(),
-                 theListOfConcurr.end(),
-                 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
-        theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
+
+    if ( theDimHyp->IsConcurrent( curDimHyp ) &&
+         theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
+    {
+      addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
+    }
   }
 }
 
-static void unionLists(TListOfInt&       theListOfId,
-                       TListOfListOfInt& theListOfListOfId,
-                       const int         theIndx )
+//-----------------------------------------------------------------------------
+void unionLists(TListOfInt&       theListOfId,
+                TListOfListOfInt& theListOfListOfId,
+                const int         theIndx )
 {
   TListOfListOfInt::iterator it = theListOfListOfId.begin();
   for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
@@ -4240,9 +4609,10 @@ static void unionLists(TListOfInt&       theListOfId,
     otherListOfId.clear();
   }
 }
+//-----------------------------------------------------------------------------
 
 //! free memory allocated for dimension-hypothesis objects
-static void removeDimHyps( TDimHypList* theArrOfList )
+void removeDimHyps( TDimHypList* theArrOfList )
 {
   for (int i = 0; i < 4; i++ ) {
     TDimHypList& listOfdimHyp = theArrOfList[i];
@@ -4252,6 +4622,28 @@ static void removeDimHyps( TDimHypList* theArrOfList )
   }
 }
 
+//-----------------------------------------------------------------------------
+/*!
+ * \brief find common submeshes with given submesh
+ * \param theSubMeshList list of already collected submesh to check
+ * \param theSubMesh given submesh to intersect with other
+ * \param theCommonSubMeshes collected common submeshes
+ */
+void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
+                        const SMESH_subMesh*        theSubMesh,
+                        set<const SMESH_subMesh*>&  theCommon )
+{
+  if ( !theSubMesh )
+    return;
+  list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
+  for ( ; it != theSubMeshList.end(); it++ )
+    theSubMesh->FindIntersection( *it, theCommon );
+  theSubMeshList.push_back( theSubMesh );
+  //theCommon.insert( theSubMesh );
+}
+
+} // namespace
+
 //=============================================================================
 /*!
  * \brief Return submesh objects list in meshing order
@@ -4270,7 +4662,7 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
   TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
   if ( !anOrder.size() ) {
 
-    // collect submeshes detecting concurrent algorithms and hypothesises
+    // collect submeshes and detect concurrent algorithms and hypothesises
     TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
     
     map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
@@ -4278,7 +4670,7 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
       ::SMESH_subMesh* sm = (*i_sm).second;
       // shape of submesh
       const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
-      
+
       // list of assigned hypothesises
       const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
       // Find out dimensions where the submesh can be concurrent.
@@ -4297,7 +4689,7 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
             anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
         }
         if (!anAlgo)
-          continue; // no assigned algorithm to current submesh
+          continue; // no algorithm assigned to a current submesh
 
         int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
         // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
@@ -4310,20 +4702,25 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
     
     // iterate on created dimension-hypotheses and check for concurrents
     for ( int i = 0; i < 4; i++ ) {
-      const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
+      const TDimHypList& listOfDimHyp = dimHypListArr[i];
       // check for concurrents in own and other dimensions (step-by-step)
       TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
       for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
         const SMESH_DimHyp* dimHyp = *dhIt;
-        TListOfInt listOfConcurr;
+        TDimHypList listOfConcurr;
+        set<int>    setOfConcurrIds;
         // looking for concurrents and collect into own list
         for ( int j = i; j < 4; j++ )
-          findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
+          findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
         // check if any concurrents found
         if ( listOfConcurr.size() > 0 ) {
           // add own submesh to list of concurrent
-          listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
-          anOrder.push_back( listOfConcurr );
+          addInOrderOfPriority( dimHyp, listOfConcurr );
+          list<int> listOfConcurrIds;
+          TDimHypList::iterator hypIt = listOfConcurr.begin();
+          for ( ; hypIt != listOfConcurr.end(); ++hypIt )
+            listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
+          anOrder.push_back( listOfConcurrIds );
         }
       }
     }
@@ -4346,28 +4743,6 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
   return aResult._retn();
 }
 
-//=============================================================================
-/*!
- * \brief find common submeshes with given submesh
- * \param theSubMeshList list of already collected submesh to check
- * \param theSubMesh given submesh to intersect with other
- * \param theCommonSubMeshes collected common submeshes
- */
-//=============================================================================
-
-static void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
-                               const SMESH_subMesh*        theSubMesh,
-                               set<const SMESH_subMesh*>&  theCommon )
-{
-  if ( !theSubMesh )
-    return;
-  list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
-  for ( ; it != theSubMeshList.end(); it++ )
-    theSubMesh->FindIntersection( *it, theCommon );
-  theSubMeshList.push_back( theSubMesh );
-  //theCommon.insert( theSubMesh );
-}
-
 //=============================================================================
 /*!
  * \brief Set submesh object order
@@ -4377,6 +4752,9 @@ static void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
 
 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
 {
+  if ( _preMeshInfo )
+    _preMeshInfo->ForgetOrLoad();
+
   bool res = false;
   ::SMESH_Mesh& mesh = GetImpl();
 
@@ -4410,12 +4788,9 @@ static void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
 
     // clear collected submeshes
     set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
-    for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
-      SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
-        if ( sm )
-          sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
-        // ClearSubMesh( *clrIt );
-      }
+    for ( ; clrIt != subMeshToClear.end(); clrIt++ )
+      if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
+        sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
   }
   aPythonDump << " ])";
 
@@ -4485,7 +4860,7 @@ void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt&     theIdsOrder,
 // Implementation of SMESH_MeshPartDS
 //
 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
-  SMESHDS_Mesh( /*theMeshID=*/-1, /*theIsEmbeddedMode=*/true)
+  SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
 {
   SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
   SMESH_Mesh_i*       mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
@@ -4535,6 +4910,64 @@ SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
     _meshDS = 0; // to enforce iteration on _elements and _nodes
   }
 }
+// -------------------------------------------------------------------------------------
+SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
+  SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
+{
+  TMeshInfo tmpInfo;
+  list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
+  for ( ; partIt != meshPart.end(); ++partIt )
+    if ( const SMDS_MeshElement * e = *partIt )
+      if ( _elements[ e->GetType() ].insert( e ).second )
+      {
+        tmpInfo.Add( e );
+        SMDS_ElemIteratorPtr nIt = e->nodesIterator();
+        while ( nIt->more() )
+        {
+          const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
+          if ( _elements[ SMDSAbs_Node ].insert( n ).second )
+            tmpInfo.Add( n );
+        }
+      }
+  myInfo = tmpInfo;
+}
+// -------------------------------------------------------------------------------------
+SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
+{
+  if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
+
+  typedef SMDS_SetIterator
+    <const SMDS_MeshElement*,
+    TIDSortedElemSet::const_iterator,
+    SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
+    SMDS_MeshElement::GeomFilter
+    > TIter;
+
+  SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
+
+  return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
+                                          _elements[type].end(),
+                                          SMDS_MeshElement::GeomFilter( geomType )));
+}
+// -------------------------------------------------------------------------------------
+SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
+{
+  if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
+
+  typedef SMDS_SetIterator
+    <const SMDS_MeshElement*,
+    TIDSortedElemSet::const_iterator,
+    SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
+    SMDS_MeshElement::EntityFilter
+    > TIter;
+
+  SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
+
+  return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
+                                          _elements[type].end(),
+                                          SMDS_MeshElement::EntityFilter( entity )));
+}
+// -------------------------------------------------------------------------------------
 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
 {
   typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
@@ -4553,6 +4986,7 @@ SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type
   return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
       ( new TIter( _elements[type].begin(), _elements[type].end() ));
 }
+// -------------------------------------------------------------------------------------
 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType)                       \
   iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const                 \
   {                                                                                 \
@@ -4560,8 +4994,8 @@ SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type
     return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType                 \
       ( new TIter( _elements[elemType].begin(), _elements[elemType].end() ));       \
   }
+// -------------------------------------------------------------------------------------
 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
-_GET_ITER_DEFINE( SMDS_0DElementIteratorPtr, elements0dIterator, SMDS_Mesh0DElement, SMDSAbs_0DElement)
 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
@@ -4570,3 +5004,5 @@ _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDS
 // END Implementation of SMESH_MeshPartDS
 //
 //================================================================================
+
+