Salome HOME
PR: synchro V6_main tag mergeto_V7_main_11Feb13
[modules/smesh.git] / src / SMESH_I / SMESH_Gen_i.cxx
index 47e0fad99c6b3408bb26a257707cc5cd3bebdc29..8fb303ad35ce421875c92c6f75190fc78a4ae206 100644 (file)
@@ -1,30 +1,28 @@
-//  Copyright (C) 2007-2010  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
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-
-//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //  File   : SMESH_Gen_i.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
-//
+
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <OSD.hxx>
 
-#include "Utils_CorbaException.hxx"
-
-#include "utilities.h"
-#include <fstream>
-#include <stdio.h>
-
 #ifdef WNT
  #include <windows.h>
  #include <process.h>
  #define UnLoadLib( handle ) dlclose( handle );
 #endif
 
-#include <HDFOI.hxx>
-
 #include "SMESH_Gen_i.hxx"
-#include "SMESH_Mesh_i.hxx"
-#include "SMESH_Hypothesis_i.hxx"
-#include "SMESH_Algo_i.hxx"
-#include "SMESH_Group_i.hxx"
-#include "SMESH_PythonDump.hxx"
+#include "SMESH_version.h"
 
+#include "SMDS_EdgePosition.hxx"
+#include "SMDS_FacePosition.hxx"
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMDS_SetIterator.hxx"
+#include "SMDS_SpacePosition.hxx"
+#include "SMDS_VertexPosition.hxx"
 #include "SMESHDS_Document.hxx"
 #include "SMESHDS_Group.hxx"
 #include "SMESHDS_GroupOnGeom.hxx"
-#include "SMESH_Mesh.hxx"
-#include "SMESH_Hypothesis.hxx"
+#include "SMESH_Algo_i.hxx"
+#include "SMESH_File.hxx"
 #include "SMESH_Group.hxx"
+#include "SMESH_Group_i.hxx"
+#include "SMESH_Hypothesis.hxx"
+#include "SMESH_Hypothesis_i.hxx"
+#include "SMESH_Mesh.hxx"
 #include "SMESH_MeshEditor.hxx"
-
-#include "SMDS_EdgePosition.hxx"
-#include "SMDS_FacePosition.hxx"
-#include "SMDS_VertexPosition.hxx"
-#include "SMDS_SpacePosition.hxx"
-#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMESH_Mesh_i.hxx"
+#include "SMESH_PreMeshInfo.hxx"
+#include "SMESH_PythonDump.hxx"
 
 #include CORBA_SERVER_HEADER(SMESH_Group)
 #include CORBA_SERVER_HEADER(SMESH_Filter)
 
 #include "DriverMED_W_SMESHDS_Mesh.h"
 #include "DriverMED_R_SMESHDS_Mesh.h"
+#ifdef WITH_CGNS
+#include "DriverCGNS_Read.hxx"
+#endif
+#include "memoire.h"
 
-#include "SALOMEDS_Tool.hxx"
-#include "SALOME_NamingService.hxx"
-#include "SALOME_LifeCycleCORBA.hxx"
-#include "Utils_SINGLETON.hxx"
-#include "OpUtil.hxx"
+#include <GEOM_Client.hxx>
+
+#include <Basics_Utils.hxx>
+#include <HDFOI.hxx>
+#include <OpUtil.hxx>
+#include <SALOMEDS_Tool.hxx>
+#include <SALOME_Container_i.hxx>
+#include <SALOME_LifeCycleCORBA.hxx>
+#include <SALOME_NamingService.hxx>
+#include <Utils_CorbaException.hxx>
+#include <Utils_ExceptHandlers.hxx>
+#include <Utils_SINGLETON.hxx>
+#include <utilities.h>
 
 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
 #include CORBA_CLIENT_HEADER(SALOME_Session)
 
-#include "GEOM_Client.hxx"
-#include "Utils_ExceptHandlers.hxx"
-#include "memoire.h"
-#include "Basics_Utils.hxx"
+// helpers about SALOME::GenericObj
+#include <SALOMEDS_wrap.hxx>
+#include <SALOMEDS_Attributes_wrap.hxx>
+#include <GEOM_wrap.hxx>
 
 #include <map>
+#include <fstream>
+#include <cstdio>
+#include <stdlib.h>
 
 using namespace std;
 using SMESH::TPythonDump;
+using SMESH::TVar;
 
 #define NUM_TMP_FILES 2
 
@@ -155,9 +164,9 @@ PortableServer::ServantBase_var SMESH_Gen_i::GetServant( CORBA::Object_ptr theOb
   try {
     PortableServer::Servant aServant = GetPOA()->reference_to_servant( theObject );
     return aServant;
-  } 
+  }
   catch (...) {
-    INFOS( "GetServant - Unknown exception was caught!!!" ); 
+    INFOS( "GetServant - Unknown exception was caught!!!" );
     return NULL;
   }
 }
@@ -172,16 +181,16 @@ PortableServer::ServantBase_var SMESH_Gen_i::GetServant( CORBA::Object_ptr theOb
 
 CORBA::Object_var SMESH_Gen_i::SObjectToObject( SALOMEDS::SObject_ptr theSObject )
 {
-  SALOMEDS::GenericAttribute_var anAttr;
+  SALOMEDS::GenericAttribute_wrap anAttr;
   CORBA::Object_var anObj;
   if ( !theSObject->_is_nil() ) {
     try {
-      if( theSObject->FindAttribute( anAttr, "AttributeIOR" ) ) {
-        SALOMEDS::AttributeIOR_var anIOR  = SALOMEDS::AttributeIOR::_narrow( anAttr );
+      if( theSObject->FindAttribute( anAttr.inout(), "AttributeIOR" ) ) {
+        SALOMEDS::AttributeIOR_wrap anIOR  = anAttr;
         CORBA::String_var aValue = anIOR->Value();
         if( strcmp( aValue, "" ) != 0 )
           anObj = GetORB()->string_to_object( aValue );
-        }
+      }
     }
     catch( ... ) {
       INFOS( "SObjectToObject - Unknown exception was caught!!!" );
@@ -194,7 +203,7 @@ CORBA::Object_var SMESH_Gen_i::SObjectToObject( SALOMEDS::SObject_ptr theSObject
 /*!
  *  GetNS [ static ]
  *
- *  Get SALOME_NamingService object 
+ *  Get SALOME_NamingService object
  */
 //=============================================================================
 
@@ -214,7 +223,7 @@ SALOME_NamingService* SMESH_Gen_i::GetNS()
  *
  *  Get SALOME_LifeCycleCORBA object
  */
-//=============================================================================     
+//=============================================================================
 SALOME_LifeCycleCORBA*  SMESH_Gen_i::GetLCC() {
   if ( myLCC == NULL ) {
     myLCC = new SALOME_LifeCycleCORBA( GetNS() );
@@ -229,14 +238,14 @@ SALOME_LifeCycleCORBA*  SMESH_Gen_i::GetLCC() {
  *
  *  Get GEOM::GEOM_Gen reference
  */
-//=============================================================================     
-GEOM::GEOM_Gen_ptr SMESH_Gen_i::GetGeomEngine() {
+//=============================================================================
+GEOM::GEOM_Gen_var SMESH_Gen_i::GetGeomEngine() {
   //CCRT GEOM::GEOM_Gen_var aGeomEngine =
   //CCRT   GEOM::GEOM_Gen::_narrow( GetLCC()->FindOrLoad_Component("FactoryServer","GEOM") );
   //CCRT return aGeomEngine._retn();
   if(CORBA::is_nil(myGeomGen))
   {
-    Engines::Component_ptr temp=GetLCC()->FindOrLoad_Component("FactoryServer","GEOM");
+    Engines::EngineComponent_ptr temp=GetLCC()->FindOrLoad_Component("FactoryServer","GEOM");
     myGeomGen=GEOM::GEOM_Gen::_narrow(temp);
   }
   return myGeomGen;
@@ -257,7 +266,7 @@ SMESH_Gen_i::SMESH_Gen_i()
 
 //=============================================================================
 /*!
- *  SMESH_Gen_i::SMESH_Gen_i 
+ *  SMESH_Gen_i::SMESH_Gen_i
  *
  *  Standard constructor, used with Container
  */
@@ -265,8 +274,8 @@ SMESH_Gen_i::SMESH_Gen_i()
 
 SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr            orb,
                           PortableServer::POA_ptr   poa,
-                          PortableServer::ObjectId* contId, 
-                          const char*               instanceName, 
+                          PortableServer::ObjectId* contId,
+                          const char*               instanceName,
                           const char*               interfaceName )
      : Engines_Component_i( orb, poa, contId, instanceName, interfaceName )
 {
@@ -274,13 +283,15 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr            orb,
 
   myOrb = CORBA::ORB::_duplicate(orb);
   myPoa = PortableServer::POA::_duplicate(poa);
-  
+
   _thisObj = this ;
   _id = myPoa->activate_object( _thisObj );
-  
+
   myIsEmbeddedMode = false;
   myShapeReader = NULL;  // shape reader
   mySMESHGen = this;
+  myIsHistoricalPythonDump = true;
+  myToForgetMeshDataOnHypModif = false;
 
   // set it in standalone mode only
   //OSD::SetSignal( true );
@@ -295,7 +306,7 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr            orb,
     SALOME::Session_var session = SALOME::Session::_narrow( obj ) ;
     if ( !session->_is_nil() )
     {
-      CORBA::String_var s_host = session->getHostname();
+      CORBA::String_var str_host = session->getHostname();
       CORBA::Long        s_pid = session->getPID();
       string my_host = Kernel_Utils::GetHostname();
 #ifdef WNT
@@ -303,7 +314,7 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr            orb,
 #else
       long    my_pid = (long) getpid();
 #endif
-      SetEmbeddedMode( s_pid == my_pid && my_host == s_host.in() );
+      SetEmbeddedMode( s_pid == my_pid && my_host == str_host.in() );
     }
   }
 }
@@ -318,7 +329,7 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr            orb,
 
 SMESH_Gen_i::~SMESH_Gen_i()
 {
-  INFOS( "SMESH_Gen_i::~SMESH_Gen_i" );
+  MESSAGE( "SMESH_Gen_i::~SMESH_Gen_i" );
 
   // delete hypothesis creators
   map<string, GenericHypothesisCreator_i*>::iterator itHyp;
@@ -335,10 +346,10 @@ SMESH_Gen_i::~SMESH_Gen_i()
   }
   myStudyContextMap.clear();
   // delete shape reader
-  if ( !myShapeReader ) 
+  if ( myShapeReader )
     delete myShapeReader;
 }
-  
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::createHypothesis
@@ -376,7 +387,7 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName
     }
     else
     {
-      //try to use new format 
+      //try to use new format
 #ifdef WNT
       aPlatformLibName = new char[ libNameLen + 5 ];
       aPlatformLibName[0] = '\0';
@@ -462,7 +473,7 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::createHypothesis(const char* theHypName
   // activate the CORBA servant of hypothesis
   hypothesis_i = SMESH::SMESH_Hypothesis::_narrow( myHypothesis_i->_this() );
   int nextId = RegisterObject( hypothesis_i );
-  if(MYDEBUG) MESSAGE( "Add hypo to map with id = "<< nextId );  
+  if(MYDEBUG) MESSAGE( "Add hypo to map with id = "<< nextId );
 
   return hypothesis_i._retn();
 }
@@ -510,7 +521,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh()
 GEOM_Client* SMESH_Gen_i::GetShapeReader()
 {
   // create shape reader if necessary
-  if ( !myShapeReader ) 
+  if ( !myShapeReader )
     myShapeReader = new GEOM_Client(GetContainerRef());
   ASSERT( myShapeReader );
   return myShapeReader;
@@ -587,34 +598,38 @@ CORBA::Boolean SMESH_Gen_i::IsEmbeddedMode()
 //=============================================================================
 
 void SMESH_Gen_i::SetCurrentStudy( SALOMEDS::Study_ptr theStudy )
+{
+  setCurrentStudy( theStudy );
+}
+
+void SMESH_Gen_i::setCurrentStudy( SALOMEDS::Study_ptr theStudy,
+                                   bool                theStudyIsBeingClosed)
 {
   int curStudyId = GetCurrentStudyID();
   myCurrentStudy = SALOMEDS::Study::_duplicate( theStudy );
   // create study context, if it doesn't exist and set current study
   int studyId = GetCurrentStudyID();
-  if ( myStudyContextMap.find( studyId ) == myStudyContextMap.end() ) {
-    myStudyContextMap[ studyId ] = new StudyContext;      
-  }
+  if ( myStudyContextMap.find( studyId ) == myStudyContextMap.end() )
+    myStudyContextMap[ studyId ] = new StudyContext;
 
   // myCurrentStudy may be nil
-  if ( !CORBA::is_nil( myCurrentStudy ) ) {
-    SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); 
-    if( !myCurrentStudy->FindComponent( "GEOM" )->_is_nil() )
-      aStudyBuilder->LoadWith( myCurrentStudy->FindComponent( "GEOM" ), GetGeomEngine() );
-
+  if ( !theStudyIsBeingClosed && !CORBA::is_nil( myCurrentStudy ) ) {
+    SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
+    SALOMEDS::SComponent_wrap GEOM_var = myCurrentStudy->FindComponent( "GEOM" );
+    if( !GEOM_var->_is_nil() )
+      aStudyBuilder->LoadWith( GEOM_var, GetGeomEngine() );
     // NPAL16168, issue 0020210
     // Let meshes update their data depending on GEOM groups that could change
     if ( curStudyId != studyId )
     {
-      //SALOMEDS::SComponent_var me =  PublishComponent( myCurrentStudy );
-      SALOMEDS::SComponent_var me = SALOMEDS::SComponent::_narrow
-        ( myCurrentStudy->FindComponent( ComponentDataType() ) );
+      CORBA::String_var compDataType = ComponentDataType();
+      SALOMEDS::SComponent_wrap me = myCurrentStudy->FindComponent( compDataType.in() );
       if ( !me->_is_nil() ) {
-        SALOMEDS::ChildIterator_var anIter = myCurrentStudy->NewChildIterator( me );
+        SALOMEDS::ChildIterator_wrap anIter = myCurrentStudy->NewChildIterator( me );
         for ( ; anIter->More(); anIter->Next() ) {
-          SALOMEDS::SObject_var so = anIter->Value();
-          CORBA::Object_var    ior = SObjectToObject( so );
-          if ( SMESH_Mesh_i*  mesh = SMESH::DownCast<SMESH_Mesh_i*>( ior ))
+          SALOMEDS::SObject_wrap so = anIter->Value();
+          CORBA::Object_var     ior = SObjectToObject( so );
+          if ( SMESH_Mesh_i*   mesh = SMESH::DownCast<SMESH_Mesh_i*>( ior ))
             mesh->CheckGeomGroupModif();
         }
       }
@@ -638,7 +653,7 @@ SALOMEDS::Study_ptr SMESH_Gen_i::GetCurrentStudy()
 
 //=============================================================================
 /*!
- *  SMESH_Gen_i::GetCurrentStudyContext 
+ *  SMESH_Gen_i::GetCurrentStudyContext
  *
  *  Get current study context
  */
@@ -654,7 +669,7 @@ StudyContext* SMESH_Gen_i::GetCurrentStudyContext()
 
 //=============================================================================
 /*!
- *  SMESH_Gen_i::CreateHypothesis 
+ *  SMESH_Gen_i::CreateHypothesis
  *
  *  Create hypothesis/algorothm of given type and publish it in the study
  */
@@ -670,7 +685,7 @@ SMESH::SMESH_Hypothesis_ptr SMESH_Gen_i::CreateHypothesis( const char* theHypNam
 
   // Publish hypothesis/algorithm in the study
   if ( CanPublishInStudy( hyp ) ) {
-    SALOMEDS::SObject_var aSO = PublishHypothesis( myCurrentStudy, hyp );
+    SALOMEDS::SObject_wrap aSO = PublishHypothesis( myCurrentStudy, hyp );
     if ( !aSO->_is_nil() ) {
       // Update Python script
       TPythonDump() << aSO << " = " << this << ".CreateHypothesis('"
@@ -734,9 +749,11 @@ SMESH_Gen_i::GetHypothesisParameterValues (const char*           theHypType,
       // check local shape
       SMESH::ListOfHypothesis_var aHypList = theMesh->GetHypothesisList( theGeom );
       int nbLocalHyps = aHypList->length();
-      for ( int i = 0; i < nbLocalHyps; i++ )
-        if ( strcmp( theHypType, aHypList[i]->GetName() ) == 0 ) // FOUND local!
+      for ( int i = 0; i < nbLocalHyps; i++ ) {
+        CORBA::String_var hypName = aHypList[i]->GetName();
+        if ( strcmp( theHypType, hypName.in() ) == 0 ) // FOUND local!
           return SMESH::SMESH_Hypothesis::_duplicate( aHypList[i] );
+      }
       // check super shapes
       TopTools_ListIteratorOfListOfShape itShape( mesh->GetAncestors( shape ));
       while ( nbLocalHyps == 0 && itShape.More() ) {
@@ -752,7 +769,7 @@ SMESH_Gen_i::GetHypothesisParameterValues (const char*           theHypType,
       }
     }
 
-    // let the temporary hypothesis find out some how parameter values by mesh
+    // let the temporary hypothesis find out somehow parameter values by mesh
     if ( hyp->SetParametersByMesh( mesh, shape ))
       return SMESH::SMESH_Hypothesis::_duplicate( tmpHyp );
   }
@@ -765,6 +782,7 @@ SMESH_Gen_i::GetHypothesisParameterValues (const char*           theHypType,
     ::SMESH_Hypothesis::TDefaults dflts;
     dflts._elemLength = diagonal / myGen.GetBoundaryBoxSegmentation();
     dflts._nbSegments = myGen.GetDefaultNbSegments();
+    dflts._shape      = &shape;
     // let the temporary hypothesis initialize it's values
     if ( hyp->SetParametersByDefaults( dflts, mesh ))
       return SMESH::SMESH_Hypothesis::_duplicate( tmpHyp );
@@ -802,6 +820,63 @@ void SMESH_Gen_i::SetDefaultNbSegments(CORBA::Long theNbSegments)
     THROW_SALOME_CORBA_EXCEPTION( "non-positive number of segments", SALOME::BAD_PARAM );
 }
 
+//=============================================================================
+/*!
+  Set an option value
+*/
+//=============================================================================
+
+void SMESH_Gen_i::SetOption(const char* name, const char* value)
+{
+  if ( name && value && strlen( value ) > 0 )
+  {
+    string msgToGUI; 
+    if ( strcmp(name, "historical_python_dump") == 0 )
+    {
+      myIsHistoricalPythonDump = ( value[0] == '1' || toupper(value[0]) == 'T' ); // 1 || true
+      msgToGUI = "preferences/SMESH/historical_python_dump/";
+      msgToGUI += myIsHistoricalPythonDump ? "true" : "false";
+    }
+    else if ( strcmp(name, "forget_mesh_on_hyp_modif") == 0 )
+    {
+      myToForgetMeshDataOnHypModif = ( value[0] == '1' || toupper(value[0]) == 'T' ); // 1 || true
+      msgToGUI = "preferences/SMESH/forget_mesh_on_hyp_modif/";
+      msgToGUI += myToForgetMeshDataOnHypModif ? "true" : "false";
+    }
+
+    // update preferences in case if SetOption() is invoked from python console
+    if ( !msgToGUI.empty() )
+    {
+      CORBA::Object_var obj = SMESH_Gen_i::GetNS()->Resolve( "/Kernel/Session" );
+      SALOME::Session_var session = SALOME::Session::_narrow( obj );
+      if ( !CORBA::is_nil( session ) )
+        session->emitMessageOneWay(msgToGUI.c_str());
+    }
+  }
+}
+
+//=============================================================================
+/*!
+  Return an option value
+*/
+//=============================================================================
+
+char* SMESH_Gen_i::GetOption(const char* name)
+{
+  if ( name )
+  {
+    if ( strcmp(name, "historical_python_dump") == 0 )
+    {
+      return CORBA::string_dup( myIsHistoricalPythonDump ? "true" : "false" );
+    }
+    if ( strcmp(name, "forget_mesh_on_hyp_modif") == 0 )
+    {
+      return CORBA::string_dup( myToForgetMeshDataOnHypModif ? "true" : "false" );
+    }
+  }
+  return CORBA::string_dup( "" );
+}
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::CreateMesh
@@ -826,7 +901,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMesh( GEOM::GEOM_Object_ptr theShapeObj
   if ( CanPublishInStudy( mesh ) ) {
     SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
     aStudyBuilder->NewCommand();  // There is a transaction
-    SALOMEDS::SObject_var aSO = PublishMesh( myCurrentStudy, mesh.in() );
+    SALOMEDS::SObject_wrap aSO = PublishMesh( myCurrentStudy, mesh.in() );
     aStudyBuilder->CommitCommand();
     if ( !aSO->_is_nil() ) {
       // Update Python script
@@ -857,7 +932,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateEmptyMesh()
   if ( CanPublishInStudy( mesh ) ) {
     SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
     aStudyBuilder->NewCommand();  // There is a transaction
-    SALOMEDS::SObject_var aSO = PublishMesh( myCurrentStudy, mesh.in() );
+    SALOMEDS::SObject_wrap aSO = PublishMesh( myCurrentStudy, mesh.in() );
     aStudyBuilder->CommitCommand();
     if ( !aSO->_is_nil() ) {
       // Update Python script
@@ -888,11 +963,11 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName
   if ( CanPublishInStudy( aMesh ) ) {
     SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
     aStudyBuilder->NewCommand();  // There is a transaction
-    SALOMEDS::SObject_var aSO = PublishMesh( myCurrentStudy, aMesh.in(), aFileName.c_str() );
+    SALOMEDS::SObject_wrap aSO = PublishMesh( myCurrentStudy, aMesh.in(), aFileName.c_str() );
     aStudyBuilder->CommitCommand();
     if ( !aSO->_is_nil() ) {
       // Update Python script
-      TPythonDump() << aSO << " = smeshgen.CreateMeshesFromUNV(r'" << theFileName << "')";
+      TPythonDump() << aSO << " = " << this << ".CreateMeshesFromUNV(r'" << theFileName << "')";
     }
   }
 
@@ -901,7 +976,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName
   aServant->ImportUNVFile( theFileName );
 
   // Dump creation of groups
-  aServant->GetGroups();
+  SMESH::ListOfGroups_var groups = aServant->GetGroups();
 
   aServant->GetImpl().GetMeshDS()->Modified();
   return aMesh._retn();
@@ -915,13 +990,18 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName
  */
 //=============================================================================
 
-SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
-                                                     SMESH::DriverMED_ReadStatus& theStatus)
-     throw ( SALOME::SALOME_Exception )
+SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMEDorSAUV( const char* theFileName,
+                                                           SMESH::DriverMED_ReadStatus& theStatus,
+                                                           const char* theCommandNameForPython,
+                                                           const char* theFileNameForPython)
 {
-  Unexpect aCatch(SALOME_SalomeException);
-  if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshFromMED" );
-
+#ifdef WIN32
+  char bname[ _MAX_FNAME ];
+  _splitpath( theFileNameForPython, NULL, NULL, bname, NULL );
+  string aFileName = bname;
+#else
+  string aFileName = basename( theFileNameForPython );
+#endif
   // Retrieve mesh names from the file
   DriverMED_R_SMESHDS_Mesh myReader;
   myReader.SetFile( theFileName );
@@ -942,7 +1022,7 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
     aStudyBuilder->NewCommand();  // There is a transaction
     aResult->length( aNames.size() );
     int i = 0;
-    
+
     // Iterate through all meshes and create mesh objects
     for ( list<string>::iterator it = aNames.begin(); it != aNames.end(); it++ ) {
       // Python Dump
@@ -950,11 +1030,14 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
 
       // create mesh
       SMESH::SMESH_Mesh_var mesh = createMesh();
-      
+
       // publish mesh in the study
-      SALOMEDS::SObject_var aSO;
+      SALOMEDS::SObject_wrap aSO;
       if ( CanPublishInStudy( mesh ) )
-        aSO = PublishMesh( myCurrentStudy, mesh.in(), (*it).c_str() );
+        // little trick: for MED file theFileName and theFileNameForPython are the same, but they are different for SAUV
+        // - as names of meshes are stored in MED file, we use them for data publishing
+        // - as mesh name is not stored in UNV file, we use file name as name of mesh when publishing data
+        aSO = PublishMesh( myCurrentStudy, mesh.in(), ( theFileName == theFileNameForPython ) ? (*it).c_str() : aFileName.c_str() );
       if ( !aSO->_is_nil() ) {
         // Python Dump
         aPythonDump << aSO;
@@ -978,15 +1061,65 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
   }
 
   // Update Python script
-  aPythonDump << "], status) = " << this << ".CreateMeshesFromMED(r'" << theFileName << "')";
+  aPythonDump << "], status) = " << this << "." << theCommandNameForPython << "(r'" << theFileNameForPython << "')";
   }
   // Dump creation of groups
   for ( int i = 0; i < aResult->length(); ++i )
-    aResult[ i ]->GetGroups();
+    SMESH::ListOfGroups_var groups = aResult[ i ]->GetGroups();
 
   return aResult._retn();
 }
 
+SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
+                                                     SMESH::DriverMED_ReadStatus& theStatus)
+     throw ( SALOME::SALOME_Exception )
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshFromMED" );
+  SMESH::mesh_array* result = CreateMeshesFromMEDorSAUV(theFileName, theStatus, "CreateMeshesFromMED", theFileName);
+  return result;
+}
+
+//=============================================================================
+/*!
+ *  SMESH_Gen_i::CreateMeshFromSAUV
+ *
+ *  Create mesh and import data from SAUV file
+ */
+//=============================================================================
+
+SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromSAUV( const char* theFileName,
+                                                      SMESH::DriverMED_ReadStatus& theStatus)
+     throw ( SALOME::SALOME_Exception )
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshFromSAUV" );
+  std::string sauvfilename(theFileName);
+  std::string medfilename(theFileName);
+  medfilename += ".med";
+  std::string cmd;
+#ifdef WNT
+  cmd = "%PYTHONBIN% ";
+#else
+  cmd = "python ";
+#endif
+  cmd += "-c \"";
+  cmd += "from medutilities import convert ; convert(r'" + sauvfilename + "', 'GIBI', 'MED', 1, r'" + medfilename + "')";
+  cmd += "\"";
+  system(cmd.c_str());
+  SMESH::mesh_array* result = CreateMeshesFromMEDorSAUV(medfilename.c_str(), theStatus, "CreateMeshesFromSAUV", sauvfilename.c_str());
+#ifdef WNT
+  cmd = "%PYTHONBIN% ";
+#else
+  cmd = "python ";
+#endif
+  cmd += "-c \"";
+  cmd += "from medutilities import my_remove ; my_remove(r'" + medfilename + "')";
+  cmd += "\"";
+  system(cmd.c_str());
+  return result;
+}
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::CreateMeshFromSTL
@@ -1002,12 +1135,19 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::CreateMeshesFromSTL" );
 
   SMESH::SMESH_Mesh_var aMesh = createMesh();
-  string aFileName;
+  //string aFileName;
+#ifdef WIN32
+  char bname[ _MAX_FNAME ];
+  _splitpath( theFileName, NULL, NULL, bname, NULL );
+  string aFileName = bname;
+#else
+  string aFileName = basename( theFileName );
+#endif
   // publish mesh in the study
   if ( CanPublishInStudy( aMesh ) ) {
     SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
     aStudyBuilder->NewCommand();  // There is a transaction
-    SALOMEDS::SObject_var aSO = PublishInStudy
+    SALOMEDS::SObject_wrap aSO = PublishInStudy
       ( myCurrentStudy, SALOMEDS::SObject::_nil(), aMesh.in(), aFileName.c_str() );
     aStudyBuilder->CommitCommand();
     if ( !aSO->_is_nil() ) {
@@ -1023,6 +1163,135 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName
   return aMesh._retn();
 }
 
+//================================================================================
+/*!
+ * \brief Create meshes and import data from the CGSN file
+ */
+//================================================================================
+
+SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromCGNS( const char* theFileName,
+                                                      SMESH::DriverMED_ReadStatus& theStatus)
+  throw ( SALOME::SALOME_Exception )
+{
+  Unexpect aCatch(SALOME_SalomeException);
+
+  SMESH::mesh_array_var aResult = new SMESH::mesh_array();
+
+#ifdef WITH_CGNS
+  // Retrieve nb meshes from the file
+  DriverCGNS_Read myReader;
+  myReader.SetFile( theFileName );
+  Driver_Mesh::Status aStatus;
+  int nbMeshes = myReader.GetNbMeshes(aStatus);
+  theStatus = (SMESH::DriverMED_ReadStatus)aStatus;
+
+  aResult->length( nbMeshes );
+
+  { // open a new scope to make aPythonDump die before PythonDump in SMESH_Mesh::GetGroups()
+
+    // Python Dump
+    TPythonDump aPythonDump;
+    aPythonDump << "([";
+
+    if (theStatus == SMESH::DRS_OK)
+    {
+      SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
+      aStudyBuilder->NewCommand();  // There is a transaction
+
+      int i = 0;
+
+      // Iterate through all meshes and create mesh objects
+      for ( ; i < nbMeshes; ++i )
+      {
+        // Python Dump
+        if (i > 0) aPythonDump << ", ";
+
+        // create mesh
+        SMESH::SMESH_Mesh_var mesh = createMesh();
+        aResult[i] = SMESH::SMESH_Mesh::_duplicate( mesh );
+
+        // Read mesh data (groups are published automatically by ImportMEDFile())
+        SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( mesh ).in() );
+        ASSERT( meshServant );
+        string meshName;
+        SMESH::DriverMED_ReadStatus status1 =
+          meshServant->ImportCGNSFile( theFileName, i, meshName );
+        if (status1 > theStatus)
+          theStatus = status1;
+
+        meshServant->GetImpl().GetMeshDS()->Modified();
+        // publish mesh in the study
+        SALOMEDS::SObject_wrap aSO;
+        if ( CanPublishInStudy( mesh ) )
+          aSO = PublishMesh( myCurrentStudy, mesh.in(), meshName.c_str() );
+
+        // Python Dump
+        if ( !aSO->_is_nil() ) {
+          aPythonDump << aSO;
+        }
+        else {
+          aPythonDump << "mesh_" << i;
+        }
+      }
+      aStudyBuilder->CommitCommand();
+    }
+
+    aPythonDump << "], status) = " << this << ".CreateMeshesFromCGNS(r'" << theFileName << "')";
+  }
+  // Dump creation of groups
+  for ( int i = 0; i < aResult->length(); ++i )
+    SMESH::ListOfGroups_var groups = aResult[ i ]->GetGroups();
+#else
+  THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
+#endif
+
+  return aResult._retn();
+}
+
+//================================================================================
+/*!
+ * \brief Create a mesh and import data from a GMF file
+ */
+//================================================================================
+
+SMESH::SMESH_Mesh_ptr
+SMESH_Gen_i::CreateMeshesFromGMF( const char*             theFileName,
+                                  CORBA::Boolean          theMakeRequiredGroups,
+                                  SMESH::ComputeError_out theError)
+    throw ( SALOME::SALOME_Exception )
+{
+  Unexpect aCatch(SALOME_SalomeException);
+
+  SMESH::SMESH_Mesh_var aMesh = createMesh();
+#ifdef WIN32
+  char bname[ _MAX_FNAME ];
+  _splitpath( theFileName, NULL, NULL, bname, NULL );
+  string aFileName = bname;
+#else
+  string aFileName = basename( theFileName );
+#endif
+  // publish mesh in the study
+  if ( CanPublishInStudy( aMesh ) ) {
+    SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder();
+    aStudyBuilder->NewCommand();  // There is a transaction
+    SALOMEDS::SObject_wrap aSO = PublishInStudy
+      ( myCurrentStudy, SALOMEDS::SObject::_nil(), aMesh.in(), aFileName.c_str() );
+    aStudyBuilder->CommitCommand();
+    if ( !aSO->_is_nil() ) {
+      // Update Python script
+      TPythonDump() << "("<< aSO << ", error) = " << this << ".CreateMeshesFromGMF(r'"
+                    << theFileName << "', "
+                    << theMakeRequiredGroups << " )";
+    }
+  }
+  SMESH_Mesh_i* aServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( aMesh ).in() );
+  ASSERT( aServant );
+  theError = aServant->ImportGMFFile( theFileName, theMakeRequiredGroups );
+  aServant->GetImpl().GetMeshDS()->Modified();
+  return aMesh._retn();
+}
+
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::IsReadyToCompute
@@ -1039,7 +1308,7 @@ CORBA::Boolean SMESH_Gen_i::IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh,
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::IsReadyToCompute" );
 
   if ( CORBA::is_nil( theShapeObject ) )
-    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", 
+    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
                                   SALOME::BAD_PARAM );
 
   if ( CORBA::is_nil( theMesh ) )
@@ -1075,16 +1344,16 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::GetAlgoSO(const ::SMESH_Algo* algo)
   if ( algo ) {
     if ( !myCurrentStudy->_is_nil() ) {
       // find algo in the study
-      SALOMEDS::SComponent_var father = SALOMEDS::SComponent::_narrow
-        ( myCurrentStudy->FindComponent( ComponentDataType() ) );
+      CORBA::String_var compDataType  = ComponentDataType();
+      SALOMEDS::SComponent_wrap father = myCurrentStudy->FindComponent( compDataType.in() );
       if ( !father->_is_nil() ) {
-        SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( father );
+        SALOMEDS::ChildIterator_wrap itBig = myCurrentStudy->NewChildIterator( father );
         for ( ; itBig->More(); itBig->Next() ) {
-          SALOMEDS::SObject_var gotBranch = itBig->Value();
+          SALOMEDS::SObject_wrap gotBranch = itBig->Value();
           if ( gotBranch->Tag() == GetAlgorithmsRootTag() ) {
-            SALOMEDS::ChildIterator_var algoIt = myCurrentStudy->NewChildIterator( gotBranch );
+            SALOMEDS::ChildIterator_wrap algoIt = myCurrentStudy->NewChildIterator( gotBranch );
             for ( ; algoIt->More(); algoIt->Next() ) {
-              SALOMEDS::SObject_var algoSO = algoIt->Value();
+              SALOMEDS::SObject_wrap algoSO = algoIt->Value();
               CORBA::Object_var     algoIOR = SObjectToObject( algoSO );
               if ( !CORBA::is_nil( algoIOR )) {
                 SMESH_Hypothesis_i* impl = SMESH::DownCast<SMESH_Hypothesis_i*>( algoIOR );
@@ -1107,7 +1376,7 @@ SALOMEDS::SObject_ptr SMESH_Gen_i::GetAlgoSO(const ::SMESH_Algo* algo)
  */
 //================================================================================
 
-SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr theMesh, 
+SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr theMesh,
                                                            GEOM::GEOM_Object_ptr theSubObject )
   throw ( SALOME::SALOME_Exception )
 {
@@ -1129,7 +1398,7 @@ SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr
         shape = GeomObjectToShape( theSubObject );
       else
         shape = SMESH_Mesh::PseudoShape();
-      
+
       ::SMESH_Mesh& mesh = meshServant->GetImpl();
 
       error_array->length( mesh.GetMeshDS()->MaxShapeIndex() );
@@ -1142,8 +1411,8 @@ SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr
       while ( smIt->more() )
       {
         sm = smIt->next();
-        if ( sm->GetSubShape().ShapeType() == TopAbs_VERTEX )
-          break;
+        // if ( sm->GetSubShape().ShapeType() == TopAbs_VERTEX )
+        //   break;
         SMESH_ComputeErrorPtr error = sm->GetComputeError();
         if ( error && !error->IsOK() && error->myAlgo )
         {
@@ -1151,11 +1420,14 @@ SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr
           errStruct.code       = -( error->myName < 0 ? error->myName + 1: error->myName ); // -1 -> 0
           errStruct.comment    = error->myComment.c_str();
           errStruct.subShapeID = sm->GetId();
-          SALOMEDS::SObject_var algoSO = GetAlgoSO( error->myAlgo );
-          if ( !algoSO->_is_nil() )
-            errStruct.algoName = algoSO->GetName();
-          else
+          SALOMEDS::SObject_wrap algoSO = GetAlgoSO( error->myAlgo );
+          if ( !algoSO->_is_nil() ) {
+            CORBA::String_var algoName = algoSO->GetName();
+            errStruct.algoName = algoName;
+          }
+          else {
             errStruct.algoName = error->myAlgo->GetName();
+          }
           errStruct.hasBadMesh = !error->myBadElements.empty();
         }
       }
@@ -1169,7 +1441,7 @@ SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr
   return error_array._retn();
 }
 
-// 
+//
 //================================================================================
 /*!
  * \brief Return mesh elements preventing computation of a subshape
@@ -1264,7 +1536,7 @@ SMESH_Gen_i::GetBadInputElements( SMESH::SMESH_Mesh_ptr theMesh,
  */
 //================================================================================
 
-SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh, 
+SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMesh,
                                                     GEOM::GEOM_Object_ptr theSubObject )
       throw ( SALOME::SALOME_Exception )
 {
@@ -1287,7 +1559,7 @@ SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMes
         myLocShape = GeomObjectToShape( theSubObject );
       else
         myLocShape = SMESH_Mesh::PseudoShape();
-      
+
       ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
       list< ::SMESH_Gen::TAlgoStateError > error_list;
       list< ::SMESH_Gen::TAlgoStateError >::iterator error;
@@ -1303,9 +1575,11 @@ SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMes
         errStruct.algoDim      = error->_algoDim;
         errStruct.isGlobalAlgo = error->_isGlobalAlgo;
         errStruct.algoName     = "";
-        SALOMEDS::SObject_var algoSO = GetAlgoSO( error->_algo );
-        if ( !algoSO->_is_nil() )
-          errStruct.algoName   = algoSO->GetName();
+        SALOMEDS::SObject_wrap algoSO = GetAlgoSO( error->_algo );
+        if ( !algoSO->_is_nil() ) {
+          CORBA::String_var algoName = algoSO->GetName();
+          errStruct.algoName = algoName.in();
+        }
       }
     }
   }
@@ -1340,7 +1614,7 @@ SMESH::long_array* SMESH_Gen_i::GetSubShapesId( GEOM::GEOM_Object_ptr theMainSha
   try
     {
       TopoDS_Shape myMainShape = GeomObjectToShape(theMainShapeObject);
-      TopTools_IndexedMapOfShape myIndexToShape;      
+      TopTools_IndexedMapOfShape myIndexToShape;
       TopExp::MapShapes(myMainShape,myIndexToShape);
 
       for ( int i = 0; i < theListOfSubShapeObject.length(); i++ )
@@ -1407,7 +1681,7 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Compute" );
 
   if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh())
-    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", 
+    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
                                   SALOME::BAD_PARAM );
 
   if ( CORBA::is_nil( theMesh ) )
@@ -1421,6 +1695,7 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
   try {
     // get mesh servant
     SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
+    meshServant->Load();
     ASSERT( meshServant );
     if ( meshServant ) {
       // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
@@ -1433,6 +1708,9 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
         myLocShape = SMESH_Mesh::PseudoShape();
       // call implementation compute
       ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+      myGen.PrepareCompute( myLocMesh, myLocShape);
+#endif
       bool ok = myGen.Compute( myLocMesh, myLocShape);
       meshServant->CreateGroupServants(); // algos can create groups (issue 0020918)
       myLocMesh.GetMeshDS()->Modified();
@@ -1451,6 +1729,29 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
   return false;
 }
 
+//=============================================================================
+/*!
+ *  SMESH_Gen_i::CancelCompute
+ *
+ *  Cancel Compute mesh on a shape
+ */
+//=============================================================================
+
+void SMESH_Gen_i::CancelCompute( SMESH::SMESH_Mesh_ptr theMesh,
+                                 GEOM::GEOM_Object_ptr theShapeObject )
+{
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+  SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
+  ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
+  TopoDS_Shape myLocShape;
+  if(theMesh->HasShapeToMesh())
+    myLocShape = GeomObjectToShape( theShapeObject );
+  else
+    myLocShape = SMESH_Mesh::PseudoShape();
+  myGen.CancelCompute( myLocMesh, myLocShape);
+#endif
+}
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::Precompute
@@ -1469,7 +1770,7 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Precompute" );
 
   if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh())
-    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", 
+    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
                                   SALOME::BAD_PARAM );
 
   if ( CORBA::is_nil( theMesh ) )
@@ -1480,6 +1781,7 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh
   try {
     // get mesh servant
     SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( theMesh ).in() );
+    meshServant->Load();
     ASSERT( meshServant );
     if ( meshServant ) {
       // NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation"
@@ -1519,7 +1821,7 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh
           SMESH_subMesh* sm = myLocMesh.GetSubMeshContaining(*idIt);
           if ( !sm || !sm->IsMeshComputed() )
             continue;
-          
+
           const TopoDS_Shape& aSh = sm->GetSubShape();
           const int shDim = myGen.GetShapeDim( aSh );
           if ( shDim < 1 || shDim > theDimension )
@@ -1656,7 +1958,7 @@ SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Evaluate" );
 
   if ( CORBA::is_nil( theShapeObject ) && theMesh->HasShapeToMesh())
-    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", 
+    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference",
                                   SALOME::BAD_PARAM );
 
   if ( CORBA::is_nil( theMesh ) )
@@ -1700,7 +2002,7 @@ SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
             SMESH_subMesh* sm = anIt->first;
             SMESH_ComputeErrorPtr& error = sm->GetComputeError();
             const SMESH_Algo* algo = myGen.GetAlgo( myLocMesh, sm->GetSubShape());
-            if ( algo && !error.get() || error->IsOK() )
+            if ( (algo && !error.get()) || error->IsOK() )
               error.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED,"Failed to evaluate",algo));
           }
           else
@@ -1731,7 +2033,7 @@ SMESH::long_array* SMESH_Gen_i::Evaluate(SMESH::SMESH_Mesh_ptr theMesh,
  *  \param theMesh - the mesh the element is in
  *  \param theElementID - the element ID
  *  \param theGeomName - the name of the result geom object if it is not yet published
- *  \retval GEOM::GEOM_Object_ptr - the found or just published geom object
+ *  \retval GEOM::GEOM_Object_ptr - the found or just published geom object (no need to UnRegister())
  */
 //================================================================================
 
@@ -1742,32 +2044,35 @@ SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
   throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
-  GEOM::GEOM_Object_var geom = FindGeometryByMeshElement(theMesh, theElementID);
+
+  GEOM::GEOM_Object_wrap geom = FindGeometryByMeshElement(theMesh, theElementID);
   if ( !geom->_is_nil() ) {
     GEOM::GEOM_Object_var mainShape = theMesh->GetShapeToMesh();
     GEOM::GEOM_Gen_ptr    geomGen   = GetGeomEngine();
 
     // try to find the corresponding SObject
-    SALOMEDS::SObject_var SObj = ObjectToSObject( myCurrentStudy, geom.in() );
+    SALOMEDS::SObject_wrap SObj = ObjectToSObject( myCurrentStudy, geom.in() );
     if ( SObj->_is_nil() ) // submesh can be not found even if published
     {
       // try to find published submesh
       GEOM::ListOfLong_var list = geom->GetSubShapeIndices();
       if ( !geom->IsMainShape() && list->length() == 1 ) {
-        SALOMEDS::SObject_var mainSO = ObjectToSObject( myCurrentStudy, mainShape );
-        SALOMEDS::ChildIterator_var it;
-        if ( !mainSO->_is_nil() )
+        SALOMEDS::SObject_wrap mainSO = ObjectToSObject( myCurrentStudy, mainShape );
+        SALOMEDS::ChildIterator_wrap it;
+        if ( !mainSO->_is_nil() ) {
           it = myCurrentStudy->NewChildIterator( mainSO );
+        }
         if ( !it->_is_nil() ) {
-          for ( it->InitEx(true); SObj->_is_nil() && it->More(); it->Next() ) {
-            GEOM::GEOM_Object_var subGeom =
-              GEOM::GEOM_Object::_narrow( SObjectToObject( it->Value() ));
+          for ( it->InitEx(true); it->More(); it->Next() ) {
+            SALOMEDS::SObject_wrap      so = it->Value();
+            CORBA::Object_var         obj = SObjectToObject( so );
+            GEOM::GEOM_Object_var subGeom = GEOM::GEOM_Object::_narrow( obj );
             if ( !subGeom->_is_nil() ) {
               GEOM::ListOfLong_var subList = subGeom->GetSubShapeIndices();
               if ( subList->length() == 1 && list[0] == subList[0] ) {
-                SObj = it->Value();
+                SObj = so;
                 geom = subGeom;
+                break;
               }
             }
           }
@@ -1778,8 +2083,12 @@ SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
       SObj = geomGen->AddInStudy( myCurrentStudy, geom, theGeomName, mainShape );
 
     // return only published geometry
-    if ( !SObj->_is_nil() )
-      return geom._retn();
+    if ( !SObj->_is_nil() ) {
+      //return geom._retn(); -- servant of geom must be UnRegister()ed;
+      CORBA::Object_var    obj = SObjectToObject( SObj );
+      GEOM::GEOM_Object_var go = GEOM::GEOM_Object::_narrow( obj );
+      return go._retn();
+    }
   }
   return GEOM::GEOM_Object::_nil();
 }
@@ -1789,7 +2098,7 @@ SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
  * \brief Return geometrical object the given element is built on.
  *  \param theMesh - the mesh the element is in
  *  \param theElementID - the element ID
- *  \retval GEOM::GEOM_Object_ptr - the found geom object
+ *  \retval GEOM::GEOM_Object_ptr - the found or created (UnRegister()!) geom object
  */
 //================================================================================
 
@@ -1819,14 +2128,16 @@ SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
         GEOM::GEOM_Object_var geom = ShapeToGeomObject( meshDS->IndexToShape( shapeID ));
         if ( geom->_is_nil() ) {
           // try to find a published sub-shape
-          SALOMEDS::SObject_var mainSO = ObjectToSObject( myCurrentStudy, mainShape );
-          SALOMEDS::ChildIterator_var it;
-          if ( !mainSO->_is_nil() )
+          SALOMEDS::SObject_wrap mainSO = ObjectToSObject( myCurrentStudy, mainShape );
+          SALOMEDS::ChildIterator_wrap it;
+          if ( !mainSO->_is_nil() ) {
             it = myCurrentStudy->NewChildIterator( mainSO );
+          }
           if ( !it->_is_nil() ) {
             for ( it->InitEx(true); it->More(); it->Next() ) {
-              GEOM::GEOM_Object_var subGeom =
-                GEOM::GEOM_Object::_narrow( SObjectToObject( it->Value() ));
+              SALOMEDS::SObject_wrap      so = it->Value();
+              CORBA::Object_var         obj = SObjectToObject( so );
+              GEOM::GEOM_Object_var subGeom = GEOM::GEOM_Object::_narrow( obj );
               if ( !subGeom->_is_nil() ) {
                 GEOM::ListOfLong_var subList = subGeom->GetSubShapeIndices();
                 if ( subList->length() == 1 && shapeID == subList[0] ) {
@@ -1839,11 +2150,14 @@ SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
         }
         if ( geom->_is_nil() ) {
           // explode
-          GEOM::GEOM_IShapesOperations_var op =
+          GEOM::GEOM_IShapesOperations_wrap op =
             geomGen->GetIShapesOperations( GetCurrentStudyID() );
           if ( !op->_is_nil() )
             geom = op->GetSubShape( mainShape, shapeID );
         }
+        else {
+          geom->Register();
+        }
         if ( !geom->_is_nil() ) {
           GeomObjectToShape( geom ); // let geom client remember the found shape
           return geom._retn();
@@ -1863,8 +2177,8 @@ SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
 //================================================================================
 
 SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Concatenate(const SMESH::mesh_array& theMeshesArray,
-                                               CORBA::Boolean           theUniteIdenticalGroups, 
-                                               CORBA::Boolean           theMergeNodesAndElements, 
+                                               CORBA::Boolean           theUniteIdenticalGroups,
+                                               CORBA::Boolean           theMergeNodesAndElements,
                                                CORBA::Double            theMergeTolerance)
   throw ( SALOME::SALOME_Exception )
 {
@@ -1886,8 +2200,8 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Concatenate(const SMESH::mesh_array& theMeshe
 
 SMESH::SMESH_Mesh_ptr
 SMESH_Gen_i::ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray,
-                                   CORBA::Boolean           theUniteIdenticalGroups, 
-                                   CORBA::Boolean           theMergeNodesAndElements, 
+                                   CORBA::Boolean           theUniteIdenticalGroups,
+                                   CORBA::Boolean           theMergeNodesAndElements,
                                    CORBA::Double            theMergeTolerance)
   throw ( SALOME::SALOME_Exception )
 {
@@ -1908,8 +2222,8 @@ SMESH_Gen_i::ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray,
 
 SMESH::SMESH_Mesh_ptr
 SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
-                               CORBA::Boolean           theUniteIdenticalGroups, 
-                               CORBA::Boolean           theMergeNodesAndElements, 
+                               CORBA::Boolean           theUniteIdenticalGroups,
+                               CORBA::Boolean           theMergeNodesAndElements,
                                CORBA::Double            theMergeTolerance,
                                CORBA::Boolean           theCommonGroups)
   throw ( SALOME::SALOME_Exception )
@@ -1924,7 +2238,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
 
   // create mesh
   SMESH::SMESH_Mesh_var aNewMesh = CreateEmptyMesh();
-  
+
   SMESHDS_Mesh* aNewMeshDS = 0;
   if ( !aNewMesh->_is_nil() ) {
     SMESH_Mesh_i* aNewImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( aNewMesh ).in() );
@@ -1944,6 +2258,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
           SMESH_Mesh_i* anInitImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( anInitMesh ).in() );
           if ( anInitImpl ) {
             ::SMESH_Mesh& aInitLocMesh = anInitImpl->GetImpl();
+            aInitLocMesh.Load();
             SMESHDS_Mesh* anInitMeshDS = aInitLocMesh.GetMeshDS();
 
             TIDsMap nodesMap;
@@ -1959,17 +2274,20 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
             int anNbEdges   = 0;
             int anNbFaces   = 0;
             int anNbVolumes = 0;
+            int aNbBalls    = 0;
 
             SMESH::long_array_var anIDsNodes   = new SMESH::long_array();
             SMESH::long_array_var anIDsEdges   = new SMESH::long_array();
             SMESH::long_array_var anIDsFaces   = new SMESH::long_array();
             SMESH::long_array_var anIDsVolumes = new SMESH::long_array();
+            SMESH::long_array_var anIDsBalls   = new SMESH::long_array();
 
             if( theCommonGroups ) {
               anIDsNodes->length(   anInitMeshDS->NbNodes()   );
               anIDsEdges->length(   anInitMeshDS->NbEdges()   );
               anIDsFaces->length(   anInitMeshDS->NbFaces()   );
               anIDsVolumes->length( anInitMeshDS->NbVolumes() );
+              anIDsBalls->length(   anInitMeshDS->NbBalls() );
             }
 
             for ( int j = 0; itElems->more(); j++) {
@@ -1997,35 +2315,64 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
               }//nodes loop
 
               // creates a corresponding element on existent nodes in new mesh
-              if ( anElem->IsPoly() && anElemType == SMDSAbs_Volume )
+              switch ( anElem->GetEntityType() ) {
+              case SMDSEntity_Polyhedra:
+                if ( const SMDS_VtkVolume* aVolume =
+                     dynamic_cast<const SMDS_VtkVolume*> (anElem))
                 {
-                  const SMDS_VtkVolume* aVolume =
-                    dynamic_cast<const SMDS_VtkVolume*> (anElem);
-                  if ( aVolume ) {
-                    aNewElem = aNewMeshDS->AddPolyhedralVolume(aNodesArray, 
-                                                               aVolume->GetQuantities());
-                    elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
-                    if( theCommonGroups )
+                  aNewElem = aNewMeshDS->AddPolyhedralVolume(aNodesArray,
+                                                             aVolume->GetQuantities());
+                  elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
+                  if( theCommonGroups )
+                    anIDsVolumes[anNbVolumes++] = aNewElem->GetID();
+                }
+                break;
+              case SMDSEntity_Ball:
+                if ( const SMDS_BallElement* aBall =
+                     dynamic_cast<const SMDS_BallElement*> (anElem))
+                {
+                  aNewElem = aNewEditor.AddElement(aNodesArray, SMDSAbs_Ball,
+                                                   /*isPoly=*/false, /*id=*/0,
+                                                   aBall->GetDiameter() );
+                  elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
+                  if( theCommonGroups )
+                    anIDsBalls[aNbBalls++] = aNewElem->GetID();
+                }
+                break;
+              default:
+                {
+                  aNewElem = aNewEditor.AddElement(aNodesArray,
+                                                   anElemType,
+                                                   anElem->IsPoly());
+                  elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
+                  if( theCommonGroups ) {
+                    if( anElemType == SMDSAbs_Edge )
+                      anIDsEdges[anNbEdges++] = aNewElem->GetID();
+                    else if( anElemType == SMDSAbs_Face )
+                      anIDsFaces[anNbFaces++] = aNewElem->GetID();
+                    else if( anElemType == SMDSAbs_Volume )
                       anIDsVolumes[anNbVolumes++] = aNewElem->GetID();
                   }
                 }
-              else {
-                
-                aNewElem = aNewEditor.AddElement(aNodesArray,
-                                                 anElemType,
-                                                 anElem->IsPoly());
-                elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
-                if( theCommonGroups ) {
-                  if( anElemType == SMDSAbs_Edge )
-                    anIDsEdges[anNbEdges++] = aNewElem->GetID();
-                  else if( anElemType == SMDSAbs_Face )
-                    anIDsFaces[anNbFaces++] = aNewElem->GetID();
-                  else if( anElemType == SMDSAbs_Volume )
-                    anIDsVolumes[anNbVolumes++] = aNewElem->GetID();
-                }
-              } 
-            }//elems loop
-            
+              }
+            } //elems loop
+
+            // copy orphan nodes
+            SMDS_NodeIteratorPtr  itNodes = anInitMeshDS->nodesIterator();
+            while ( itNodes->more() )
+            {
+              const SMDS_MeshNode* aNode = itNodes->next();
+              if ( aNode->NbInverseElements() == 0 )
+              {
+                const SMDS_MeshNode* aNewNode =
+                  aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z());
+                nodesMap.insert( make_pair(aNode->GetID(), aNewNode->GetID()) );
+                if( theCommonGroups )
+                  anIDsNodes[anNbNodes++] = aNewNode->GetID();
+              }
+            }
+
+
             aListOfGroups = anInitImpl->GetGroups();
             SMESH::SMESH_GroupBase_ptr aGroup;
 
@@ -2037,9 +2384,9 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
             SMESH::ElementType aGroupType;
             CORBA::String_var aGroupName;
             if ( theCommonGroups ) {
-              for(aGroupType=SMESH::NODE;aGroupType<=SMESH::VOLUME;aGroupType=(SMESH::ElementType)(aGroupType+1)) {
+              for(aGroupType=SMESH::NODE;aGroupType<=SMESH::BALL;aGroupType=(SMESH::ElementType)(aGroupType+1)) {
                 string str = "Gr";
-                SALOMEDS::SObject_var aMeshSObj = ObjectToSObject( myCurrentStudy, anInitMesh );
+                SALOMEDS::SObject_wrap aMeshSObj = ObjectToSObject( myCurrentStudy, anInitMesh );
                 if(aMeshSObj)
                   str += aMeshSObj->GetName();
                 str += "_";
@@ -2067,6 +2414,11 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
                   anIDsVolumes->length(anNbVolumes);
                   anLen = anNbVolumes;
                   break;
+                case SMESH::BALL:
+                  str += "Balls";
+                  anIDsBalls->length(aNbBalls);
+                  anLen = aNbBalls;
+                  break;
                 default:
                   break;
                 }
@@ -2090,10 +2442,13 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
                   case SMESH::VOLUME:
                     aNewGroup->Add( anIDsVolumes );
                     break;
+                  case SMESH::BALL:
+                    aNewGroup->Add( anIDsBalls );
+                    break;
                   default:
                     break;
                   }
-                
+
                   aListOfNewGroups.clear();
                   aListOfNewGroups.push_back(aNewGroup);
                   aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups ));
@@ -2102,8 +2457,8 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
             }
 
             // check that current group name and type don't have identical ones in union mesh
-            for (int i = 0; i < aListOfGroups->length(); i++) {
-              aGroup = aListOfGroups[i];
+            for (int iG = 0; iG < aListOfGroups->length(); iG++) {
+              aGroup = aListOfGroups[iG];
               aListOfNewGroups.clear();
               aGroupType = aGroup->GetType();
               aGroupName = aGroup->GetName();
@@ -2121,14 +2476,14 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
                 for (int j = 0; j < anInitIDs->length(); j++) {
                   anNewIDs[j] = elemsMap.find(anInitIDs[j])->second;
                 }
-              
+
               // check that current group name and type don't have identical ones in union mesh
               if ( anIter == aGroupsMap.end() ) {
                 // add a new group in the mesh
                 aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
                 // add elements into new group
                 aNewGroup->Add( anNewIDs );
-                
+
                 aListOfNewGroups.push_back(aNewGroup);
                 aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups ));
               }
@@ -2143,7 +2498,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
                 // rename identical groups
                 aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
                 aNewGroup->Add( anNewIDs );
-                
+
                 TListOfNewGroups& aNewGroups = anIter->second;
                 string aNewGroupName;
                 if (aNewGroups.size() == 1) {
@@ -2172,7 +2527,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
       }
     }
   }
-  
+
   // Update Python script
   aPythonDump << aNewMesh << " = " << this;
   if( !theCommonGroups )
@@ -2187,7 +2542,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
   aPythonDump << "], ";
   aPythonDump << theUniteIdenticalGroups << ", "
               << theMergeNodesAndElements << ", "
-              << theMergeTolerance << ")";
+              << TVar( theMergeTolerance ) << ")";
 
   delete pPythonDump; // enable python dump from GetGroups()
 
@@ -2198,19 +2553,254 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
   }
 
   // IPAL21468 Change icon of compound because it need not be computed.
-  SALOMEDS::SObject_var aMeshSObj = ObjectToSObject( myCurrentStudy, aNewMesh );
-  if( !aMeshSObj->_is_nil() ) {
-    SALOMEDS::GenericAttribute_var anAttr;
-    SALOMEDS::StudyBuilder_var aBuilder = myCurrentStudy->NewBuilder();
-    anAttr = aBuilder->FindOrCreateAttribute( aMeshSObj,"AttributePixMap" );
-    SALOMEDS::AttributePixMap_var aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
-    aPixmap->SetPixMap("ICON_SMESH_TREE_MESH");
-  }
+  SALOMEDS::SObject_wrap aMeshSObj = ObjectToSObject( myCurrentStudy, aNewMesh );
+  SetPixMap( aMeshSObj, "ICON_SMESH_TREE_MESH" );
+
   if (aNewMeshDS)
     aNewMeshDS->Modified();
   return aNewMesh._retn();
 }
 
+//================================================================================
+/*!
+ * \brief Create a mesh by copying a part of another mesh
+ *  \param meshPart - a part of mesh to copy
+ *  \param toCopyGroups - to create in the new mesh groups
+ *                        the copied elements belongs to
+ *  \param toKeepIDs - to preserve IDs of the copied elements or not
+ *  \retval SMESH::SMESH_Mesh_ptr - the new mesh
+ */
+//================================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
+                                            const char*               meshName,
+                                            CORBA::Boolean            toCopyGroups,
+                                            CORBA::Boolean            toKeepIDs)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+
+  TPythonDump* pyDump = new TPythonDump; // prevent dump from CreateMesh()
+
+  // 1. Get source mesh
+
+  if ( CORBA::is_nil( meshPart ))
+    THROW_SALOME_CORBA_EXCEPTION( "bad IDSource", SALOME::BAD_PARAM );
+
+  SMESH::SMESH_Mesh_var srcMesh = meshPart->GetMesh();
+  SMESH_Mesh_i*       srcMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( srcMesh );
+  if ( !srcMesh_i )
+    THROW_SALOME_CORBA_EXCEPTION( "bad mesh of IDSource", SALOME::BAD_PARAM );
+
+  SMESHDS_Mesh* srcMeshDS = srcMesh_i->GetImpl().GetMeshDS();
+
+  // 2. Make a new mesh
+
+  SMESH::SMESH_Mesh_var newMesh = CreateMesh(GEOM::GEOM_Object::_nil());
+  SMESH_Mesh_i*       newMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( newMesh );
+  if ( !newMesh_i )
+    THROW_SALOME_CORBA_EXCEPTION( "can't create a mesh", SALOME::INTERNAL_ERROR );
+  SALOMEDS::SObject_wrap meshSO = ObjectToSObject(myCurrentStudy, newMesh );
+  if ( !meshSO->_is_nil() )
+  {
+    SetName( meshSO, meshName, "Mesh" );
+    SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
+  }
+  SMESHDS_Mesh* newMeshDS = newMesh_i->GetImpl().GetMeshDS();
+  ::SMESH_MeshEditor editor( &newMesh_i->GetImpl() );
+
+  // 3. Get elements to copy
+
+  SMDS_ElemIteratorPtr srcElemIt; SMDS_NodeIteratorPtr srcNodeIt;
+  TIDSortedElemSet srcElems;
+  SMESH::array_of_ElementType_var srcElemTypes = meshPart->GetTypes();
+  if ( SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
+  {
+    srcElemIt = srcMeshDS->elementsIterator();
+    srcNodeIt = srcMeshDS->nodesIterator();
+  }
+  else
+  {
+    SMESH::long_array_var ids = meshPart->GetIDs();
+    if ( srcElemTypes->length() == 1 && srcElemTypes[0] == SMESH::NODE ) // group of nodes
+    {
+      for (int i=0; i < ids->length(); i++)
+        if ( const SMDS_MeshElement * elem = srcMeshDS->FindNode( ids[i] ))
+          srcElems.insert( elem );
+    }
+    else
+    {
+      for (int i=0; i < ids->length(); i++)
+        if ( const SMDS_MeshElement * elem = srcMeshDS->FindElement( ids[i] ))
+          srcElems.insert( elem );
+    }
+    if ( srcElems.empty() )
+      return newMesh._retn();
+
+    typedef SMDS_SetIterator< SMDS_pElement, TIDSortedElemSet::const_iterator > ElIter;
+    srcElemIt = SMDS_ElemIteratorPtr( new ElIter( srcElems.begin(), srcElems.end() ));
+  }
+
+  // 4. Copy elements
+
+  typedef map<SMDS_pElement, SMDS_pElement, TIDCompare> TE2EMap;
+  TE2EMap e2eMapByType[ SMDSAbs_NbElementTypes ];
+  TE2EMap& n2nMap = e2eMapByType[ SMDSAbs_Node ];
+  int iN;
+  const SMDS_MeshNode *nSrc, *nTgt;
+  vector< const SMDS_MeshNode* > nodes;
+  while ( srcElemIt->more() )
+  {
+    const SMDS_MeshElement * elem = srcElemIt->next();
+    // find / add nodes
+    nodes.resize( elem->NbNodes());
+    SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
+    if ( toKeepIDs ) {
+      for ( iN = 0; nIt->more(); ++iN )
+      {
+        nSrc = static_cast<const SMDS_MeshNode*>( nIt->next() );
+        nTgt = newMeshDS->FindNode( nSrc->GetID());
+        if ( !nTgt )
+          nTgt = newMeshDS->AddNodeWithID( nSrc->X(), nSrc->Y(), nSrc->Z(), nSrc->GetID());
+        nodes[ iN ] = nTgt;
+      }
+    }
+    else {
+      for ( iN = 0; nIt->more(); ++iN )
+      {
+        nSrc = static_cast<const SMDS_MeshNode*>( nIt->next() );
+        TE2EMap::iterator n2n = n2nMap.insert( make_pair( nSrc, SMDS_pNode(0) )).first;
+        if ( !n2n->second )
+          n2n->second = newMeshDS->AddNode( nSrc->X(), nSrc->Y(), nSrc->Z() );
+        nodes[ iN ] = (const SMDS_MeshNode*) n2n->second;
+      }
+    }
+    // add elements
+    if ( elem->GetType() != SMDSAbs_Node )
+    {
+      int ID = toKeepIDs ? elem->GetID() : 0;
+      const SMDS_MeshElement * newElem;
+      switch ( elem->GetEntityType() ) {
+      case SMDSEntity_Polyhedra:
+        newElem = editor.GetMeshDS()->
+          AddPolyhedralVolumeWithID( nodes,
+                                     static_cast<const SMDS_VtkVolume*>(elem)->GetQuantities(),
+                                     ID);
+        break;
+      case SMDSEntity_Ball:
+        newElem = editor.AddElement( nodes, SMDSAbs_Ball, false, ID,
+                                     static_cast<const SMDS_BallElement*>(elem)->GetDiameter());
+        break;
+      default:
+        newElem = editor.AddElement( nodes,elem->GetType(),elem->IsPoly(),ID);
+
+      if ( toCopyGroups && !toKeepIDs )
+        e2eMapByType[ elem->GetType() ].insert( make_pair( elem, newElem ));
+      }
+    }
+  } // while ( srcElemIt->more() )
+
+  // 4(b). Copy free nodes
+
+  if ( srcNodeIt && srcMeshDS->NbNodes() != newMeshDS->NbNodes() )
+  {
+    while ( srcNodeIt->more() )
+    {
+      nSrc = srcNodeIt->next();
+      if ( nSrc->NbInverseElements() == 0 )
+      {
+        if ( toKeepIDs )
+          nTgt = newMeshDS->AddNodeWithID( nSrc->X(), nSrc->Y(), nSrc->Z(), nSrc->GetID());
+        else
+          n2nMap[ nSrc ] = newMeshDS->AddNode( nSrc->X(), nSrc->Y(), nSrc->Z() );
+      }
+    }
+  }
+
+  // 5. Copy groups
+
+  int nbNewGroups = 0;
+  if ( toCopyGroups )
+  {
+    SMESH_Mesh::GroupIteratorPtr gIt = srcMesh_i->GetImpl().GetGroups();
+    while ( gIt->more() )
+    {
+      SMESH_Group* group = gIt->next();
+      const SMESHDS_GroupBase* groupDS = group->GetGroupDS();
+
+      // Check group type. We copy nodal groups containing nodes of copied element
+      SMDSAbs_ElementType groupType = groupDS->GetType();
+      if ( groupType != SMDSAbs_Node &&
+           newMeshDS->GetMeshInfo().NbElements( groupType ) == 0 )
+        continue; // group type differs from types of meshPart
+
+      // Find copied elements in the group
+      vector< const SMDS_MeshElement* > groupElems;
+      SMDS_ElemIteratorPtr eIt = groupDS->GetElements();
+      if ( toKeepIDs )
+      {
+        const SMDS_MeshElement* foundElem;
+        if ( groupType == SMDSAbs_Node )
+        {
+          while ( eIt->more() )
+            if (( foundElem = newMeshDS->FindNode( eIt->next()->GetID() )))
+              groupElems.push_back( foundElem );
+        }
+        else
+        {
+          while ( eIt->more() )
+            if (( foundElem = newMeshDS->FindElement( eIt->next()->GetID() )))
+              groupElems.push_back( foundElem );
+        }
+      }
+      else
+      {
+        TE2EMap & e2eMap = e2eMapByType[ groupDS->GetType() ];
+        if ( e2eMap.empty() ) continue;
+        int minID = e2eMap.begin()->first->GetID();
+        int maxID = e2eMap.rbegin()->first->GetID();
+        TE2EMap::iterator e2e;
+        while ( eIt->more() && groupElems.size() < e2eMap.size())
+        {
+          const SMDS_MeshElement* e = eIt->next();
+          if ( e->GetID() < minID || e->GetID() > maxID ) continue;
+          if ((e2e = e2eMap.find( e )) != e2eMap.end())
+            groupElems.push_back( e2e->second );
+        }
+      }
+      // Make a new group
+      if ( !groupElems.empty() )
+      {
+        SMESH::SMESH_Group_var newGroupObj =
+          newMesh->CreateGroup( SMESH::ElementType(groupType), group->GetName() );
+        if ( SMESH_GroupBase_i* newGroup_i = SMESH::DownCast<SMESH_GroupBase_i*>( newGroupObj))
+        {
+          SMESHDS_GroupBase * newGroupDS = newGroup_i->GetGroupDS();
+          SMDS_MeshGroup& smdsGroup = ((SMESHDS_Group*)newGroupDS)->SMDSGroup();
+          for ( unsigned i = 0; i < groupElems.size(); ++i )
+            smdsGroup.Add( groupElems[i] );
+
+          nbNewGroups++;
+        }
+      }
+    }
+  }
+
+  newMeshDS->Modified();
+
+  *pyDump << newMesh << " = " << this
+          << ".CopyMesh( " << meshPart << ", "
+          << "'" << meshName << "', "
+          << toCopyGroups << ", "
+          << toKeepIDs << ")";
+
+  delete pyDump; pyDump = 0; // allow dump in GetGroups()
+
+  if ( nbNewGroups > 0 ) // dump created groups
+    SMESH::ListOfGroups_var groups = newMesh->GetGroups();
+
+  return newMesh._retn();
+}
+
 //================================================================================
 /*!
  *  SMESH_Gen_i::GetMEDVersion
@@ -2270,7 +2860,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
   //  ASSERT( theComponent->GetStudy()->StudyId() == myCurrentStudy->StudyId() )
   // san -- in case <myCurrentStudy> differs from theComponent's study,
   // use that of the component
-  if ( myCurrentStudy->_is_nil() || 
+  if ( myCurrentStudy->_is_nil() ||
     theComponent->GetStudy()->StudyId() != myCurrentStudy->StudyId() )
     SetCurrentStudy( theComponent->GetStudy() );
 
@@ -2291,7 +2881,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
   aFileSeq->length( NUM_TMP_FILES );
 
   TCollection_AsciiString aStudyName( "" );
-  if ( isMultiFile ) 
+  if ( isMultiFile )
     aStudyName = ( (char*)SALOMEDS_Tool::GetNameFromPath( myCurrentStudy->URL() ).c_str() );
 
   // Set names of temporary files
@@ -2334,15 +2924,18 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
   // SetStoreName() to groups before storing hypotheses to let them refer to
   // groups using "store name", which is "Group <group_persistent_id>"
   {
-    SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( theComponent );
+    SALOMEDS::ChildIterator_wrap itBig = myCurrentStudy->NewChildIterator( theComponent );
     for ( ; itBig->More(); itBig->Next() ) {
-      SALOMEDS::SObject_var gotBranch = itBig->Value();
+      SALOMEDS::SObject_wrap gotBranch = itBig->Value();
       if ( gotBranch->Tag() > GetAlgorithmsRootTag() ) {
         CORBA::Object_var anObject = SObjectToObject( gotBranch );
         if ( !CORBA::is_nil( anObject ) ) {
           SMESH::SMESH_Mesh_var myMesh = SMESH::SMESH_Mesh::_narrow( anObject ) ;
           if ( !myMesh->_is_nil() ) {
+            myMesh->Load(); // load from study file if not yet done
+            TPythonDump pd; // not to dump GetGroups()
             SMESH::ListOfGroups_var groups = myMesh->GetGroups();
+            pd << ""; // to avoid optimizing pd out
             for ( int i = 0; i < groups->length(); ++i )
             {
               SMESH_GroupBase_i* grImpl = SMESH::DownCast<SMESH_GroupBase_i*>( groups[i]);
@@ -2368,9 +2961,9 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
   aFile->CreateOnDisk();
 
   // --> iterator for top-level objects
-  SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( theComponent );
+  SALOMEDS::ChildIterator_wrap itBig = myCurrentStudy->NewChildIterator( theComponent );
   for ( ; itBig->More(); itBig->Next() ) {
-    SALOMEDS::SObject_var gotBranch = itBig->Value();
+    SALOMEDS::SObject_wrap gotBranch = itBig->Value();
 
     // --> hypotheses root branch (only one for the study)
     if ( gotBranch->Tag() == GetHypothesisRootTag() ) {
@@ -2379,9 +2972,9 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
       aTopGroup->CreateOnDisk();
 
       // iterator for all hypotheses
-      SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( gotBranch );
+      SALOMEDS::ChildIterator_wrap it = myCurrentStudy->NewChildIterator( gotBranch );
       for ( ; it->More(); it->Next() ) {
-        SALOMEDS::SObject_var mySObject = it->Value();
+        SALOMEDS::SObject_wrap mySObject = it->Value();
         CORBA::Object_var anObject = SObjectToObject( mySObject );
         if ( !CORBA::is_nil( anObject ) ) {
           SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow( anObject );
@@ -2448,9 +3041,9 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
       aTopGroup->CreateOnDisk();
 
       // iterator for all algorithms
-      SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( gotBranch );
+      SALOMEDS::ChildIterator_wrap it = myCurrentStudy->NewChildIterator( gotBranch );
       for ( ; it->More(); it->Next() ) {
-        SALOMEDS::SObject_var mySObject = it->Value();
+        SALOMEDS::SObject_wrap mySObject = it->Value();
         CORBA::Object_var anObject = SObjectToObject( mySObject );
         if ( !CORBA::is_nil( anObject ) ) {
           SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow( anObject );
@@ -2574,12 +3167,12 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
             aDataset->CloseOnDisk();
 
             // write reference on a shape if exists
-            SALOMEDS::SObject_var myRef;
+            SALOMEDS::SObject_wrap myRef;
             bool shapeRefFound = false;
-            bool found = gotBranch->FindSubObject( GetRefOnShapeTag(), myRef );
+            bool found = gotBranch->FindSubObject( GetRefOnShapeTag(), myRef.inout() );
             if ( found ) {
-              SALOMEDS::SObject_var myShape;
-              bool ok = myRef->ReferencedObject( myShape );
+              SALOMEDS::SObject_wrap myShape;
+              bool ok = myRef->ReferencedObject( myShape.inout() );
               if ( ok ) {
                 shapeRefFound = (! CORBA::is_nil( myShape->GetObject() ));
                 string myRefOnObject = myShape->GetID();
@@ -2594,8 +3187,8 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
             }
 
             // write applied hypotheses if exist
-            SALOMEDS::SObject_var myHypBranch;
-            found = gotBranch->FindSubObject( GetRefOnAppliedHypothesisTag(), myHypBranch );
+            SALOMEDS::SObject_wrap myHypBranch;
+            found = gotBranch->FindSubObject( GetRefOnAppliedHypothesisTag(), myHypBranch.inout() );
             if ( found && !shapeRefFound && hasShape) { // remove applied hyps
               myCurrentStudy->NewBuilder()->RemoveObjectWithChildren( myHypBranch );
             }
@@ -2603,16 +3196,16 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
               aGroup = new HDFgroup( "Applied Hypotheses", aTopGroup );
               aGroup->CreateOnDisk();
 
-              SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myHypBranch );
+              SALOMEDS::ChildIterator_wrap it = myCurrentStudy->NewChildIterator( myHypBranch );
               int hypNb = 0;
               for ( ; it->More(); it->Next() ) {
-                SALOMEDS::SObject_var mySObject = it->Value();
-                SALOMEDS::SObject_var myRefOnHyp;
-                bool ok = mySObject->ReferencedObject( myRefOnHyp );
+                SALOMEDS::SObject_wrap mySObject = it->Value();
+                SALOMEDS::SObject_wrap myRefOnHyp;
+                bool ok = mySObject->ReferencedObject( myRefOnHyp.inout() );
                 if ( ok ) {
                   // san - it is impossible to recover applied hypotheses
                   //       using their entries within Load() method,
-                  // for there are no AttributeIORs in the study when Load() is working. 
+                  // for there are no AttributeIORs in the study when Load() is working.
                   // Hence, it is better to store persistent IDs of hypotheses as references to them
 
                   //string myRefOnObject = myRefOnHyp->GetID();
@@ -2637,8 +3230,9 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
             }
 
             // write applied algorithms if exist
-            SALOMEDS::SObject_var myAlgoBranch;
-            found = gotBranch->FindSubObject( GetRefOnAppliedAlgorithmsTag(), myAlgoBranch );
+            SALOMEDS::SObject_wrap myAlgoBranch;
+            found = gotBranch->FindSubObject( GetRefOnAppliedAlgorithmsTag(),
+                                              myAlgoBranch.inout() );
             if ( found && !shapeRefFound && hasShape) { // remove applied algos
               myCurrentStudy->NewBuilder()->RemoveObjectWithChildren( myAlgoBranch );
             }
@@ -2646,16 +3240,16 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
               aGroup = new HDFgroup( "Applied Algorithms", aTopGroup );
               aGroup->CreateOnDisk();
 
-              SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myAlgoBranch );
+              SALOMEDS::ChildIterator_wrap it = myCurrentStudy->NewChildIterator( myAlgoBranch );
               int algoNb = 0;
               for ( ; it->More(); it->Next() ) {
-                SALOMEDS::SObject_var mySObject = it->Value();
-                SALOMEDS::SObject_var myRefOnAlgo;
-                bool ok = mySObject->ReferencedObject( myRefOnAlgo );
+                SALOMEDS::SObject_wrap mySObject = it->Value();
+                SALOMEDS::SObject_wrap myRefOnAlgo;
+                bool ok = mySObject->ReferencedObject( myRefOnAlgo.inout() );
                 if ( ok ) {
                   // san - it is impossible to recover applied algorithms
                   //       using their entries within Load() method,
-                  // for there are no AttributeIORs in the study when Load() is working. 
+                  // for there are no AttributeIORs in the study when Load() is working.
                   // Hence, it is better to store persistent IDs of algorithms as references to them
 
                   //string myRefOnObject = myRefOnAlgo->GetID();
@@ -2682,18 +3276,18 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
             // --> submesh objects sub-branches
 
             for ( int i = GetSubMeshOnVertexTag(); i <= GetSubMeshOnCompoundTag(); i++ ) {
-              SALOMEDS::SObject_var mySubmeshBranch;
-              found = gotBranch->FindSubObject( i, mySubmeshBranch );
+              SALOMEDS::SObject_wrap mySubmeshBranch;
+              found = gotBranch->FindSubObject( i, mySubmeshBranch.inout() );
 
               if ( found ) // check if there is shape reference in submeshes
               {
                 bool hasShapeRef = false;
-                SALOMEDS::ChildIterator_var itSM =
+                SALOMEDS::ChildIterator_wrap itSM =
                   myCurrentStudy->NewChildIterator( mySubmeshBranch );
                 for ( ; itSM->More(); itSM->Next() ) {
-                  SALOMEDS::SObject_var mySubRef, myShape, mySObject = itSM->Value();
-                  if ( mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ))
-                    mySubRef->ReferencedObject( myShape );
+                  SALOMEDS::SObject_wrap mySubRef, myShape, mySObject = itSM->Value();
+                  if ( mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef.inout() ))
+                    mySubRef->ReferencedObject( myShape.inout() );
                   if ( !CORBA::is_nil( myShape ) && !CORBA::is_nil( myShape->GetObject() ))
                     hasShapeRef = true;
                   else
@@ -2744,9 +3338,9 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                 aGroup->CreateOnDisk();
 
                 // iterator for all submeshes of given type
-                SALOMEDS::ChildIterator_var itSM = myCurrentStudy->NewChildIterator( mySubmeshBranch );
+                SALOMEDS::ChildIterator_wrap itSM = myCurrentStudy->NewChildIterator( mySubmeshBranch );
                 for ( ; itSM->More(); itSM->Next() ) {
-                  SALOMEDS::SObject_var mySObject = itSM->Value();
+                  SALOMEDS::SObject_wrap mySObject = itSM->Value();
                   CORBA::Object_var anSubObject = SObjectToObject( mySObject );
                   if ( !CORBA::is_nil( anSubObject ))
                   {
@@ -2761,9 +3355,9 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                     aSubGroup->CreateOnDisk();
 
                     // write reference on a shape, already checked if it exists
-                    SALOMEDS::SObject_var mySubRef, myShape;
-                    if ( mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ))
-                      mySubRef->ReferencedObject( myShape );
+                    SALOMEDS::SObject_wrap mySubRef, myShape;
+                    if ( mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef.inout() ))
+                      mySubRef->ReferencedObject( myShape.inout() );
                     string myRefOnObject = myShape->GetID();
                     if ( myRefOnObject.length() > 0 ) {
                       aSize[ 0 ] = myRefOnObject.length() + 1;
@@ -2774,18 +3368,19 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                     }
 
                     // write applied hypotheses if exist
-                    SALOMEDS::SObject_var mySubHypBranch;
-                    found = mySObject->FindSubObject( GetRefOnAppliedHypothesisTag(), mySubHypBranch );
+                    SALOMEDS::SObject_wrap mySubHypBranch;
+                    found = mySObject->FindSubObject( GetRefOnAppliedHypothesisTag(),
+                                                      mySubHypBranch.inout() );
                     if ( found ) {
                       aSubSubGroup = new HDFgroup( "Applied Hypotheses", aSubGroup );
                       aSubSubGroup->CreateOnDisk();
 
-                      SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( mySubHypBranch );
+                      SALOMEDS::ChildIterator_wrap it = myCurrentStudy->NewChildIterator( mySubHypBranch );
                       int hypNb = 0;
                       for ( ; it->More(); it->Next() ) {
-                        SALOMEDS::SObject_var mySubSObject = it->Value();
-                        SALOMEDS::SObject_var myRefOnHyp;
-                        bool ok = mySubSObject->ReferencedObject( myRefOnHyp );
+                        SALOMEDS::SObject_wrap mySubSObject = it->Value();
+                        SALOMEDS::SObject_wrap myRefOnHyp;
+                        bool ok = mySubSObject->ReferencedObject( myRefOnHyp.inout() );
                         if ( ok ) {
                           //string myRefOnObject = myRefOnHyp->GetID();
                           CORBA::Object_var anObject = SObjectToObject( myRefOnHyp );
@@ -2809,18 +3404,20 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                     }
 
                     // write applied algorithms if exist
-                    SALOMEDS::SObject_var mySubAlgoBranch;
-                    found = mySObject->FindSubObject( GetRefOnAppliedAlgorithmsTag(), mySubAlgoBranch );
+                    SALOMEDS::SObject_wrap mySubAlgoBranch;
+                    found = mySObject->FindSubObject( GetRefOnAppliedAlgorithmsTag(),
+                                                      mySubAlgoBranch.inout() );
                     if ( found ) {
                       aSubSubGroup = new HDFgroup( "Applied Algorithms", aSubGroup );
                       aSubSubGroup->CreateOnDisk();
 
-                      SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( mySubAlgoBranch );
+                      SALOMEDS::ChildIterator_wrap it =
+                        myCurrentStudy->NewChildIterator( mySubAlgoBranch );
                       int algoNb = 0;
                       for ( ; it->More(); it->Next() ) {
-                        SALOMEDS::SObject_var mySubSObject = it->Value();
-                        SALOMEDS::SObject_var myRefOnAlgo;
-                        bool ok = mySubSObject->ReferencedObject( myRefOnAlgo );
+                        SALOMEDS::SObject_wrap mySubSObject = it->Value();
+                        SALOMEDS::SObject_wrap myRefOnAlgo;
+                        bool ok = mySubSObject->ReferencedObject( myRefOnAlgo.inout() );
                         if ( ok ) {
                           //string myRefOnObject = myRefOnAlgo->GetID();
                           CORBA::Object_var anObject = SObjectToObject( myRefOnAlgo );
@@ -2890,9 +3487,9 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
             }
 
             // groups root sub-branch
-            SALOMEDS::SObject_var myGroupsBranch;
-            for ( int i = GetNodeGroupsTag(); i <= GetVolumeGroupsTag(); i++ ) {
-              found = gotBranch->FindSubObject( i, myGroupsBranch );
+            SALOMEDS::SObject_wrap myGroupsBranch;
+            for ( int i = GetNodeGroupsTag(); i <= GetBallElementsGroupsTag(); i++ ) {
+              found = gotBranch->FindSubObject( i, myGroupsBranch.inout() );
               if ( found ) {
                 char name_group[ 30 ];
                 if ( i == GetNodeGroupsTag() )
@@ -2903,13 +3500,17 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                   strcpy( name_group, "Groups of Faces" );
                 else if ( i == GetVolumeGroupsTag() )
                   strcpy( name_group, "Groups of Volumes" );
+                else if ( i == Get0DElementsGroupsTag() )
+                  strcpy( name_group, "Groups of 0D Elements" );
+                else if ( i == GetBallElementsGroupsTag() )
+                  strcpy( name_group, "Groups of Balls" );
 
                 aGroup = new HDFgroup( name_group, aTopGroup );
                 aGroup->CreateOnDisk();
 
-                SALOMEDS::ChildIterator_var it = myCurrentStudy->NewChildIterator( myGroupsBranch );
+                SALOMEDS::ChildIterator_wrap it = myCurrentStudy->NewChildIterator( myGroupsBranch );
                 for ( ; it->More(); it->Next() ) {
-                  SALOMEDS::SObject_var mySObject = it->Value();
+                  SALOMEDS::SObject_wrap mySObject = it->Value();
                   CORBA::Object_var aSubObject = SObjectToObject( mySObject );
                   if ( !CORBA::is_nil( aSubObject ) ) {
                     SMESH_GroupBase_i* myGroupImpl =
@@ -2919,7 +3520,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                     SMESHDS_GroupBase* aGrpBaseDS = myGroupImpl->GetGroupDS();
                     if ( !aGrpBaseDS )
                       continue;
-                    
+
                     CORBA::String_var objStr = GetORB()->object_to_string( aSubObject );
                     int anId = myStudyContext->findId( string( objStr.in() ) );
 
@@ -2950,7 +3551,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                     aDataset->WriteOnDisk( anRGB );
                     aDataset->CloseOnDisk();
 
-                    // Pass SMESHDS_Group to MED writer 
+                    // Pass SMESHDS_Group to MED writer
                     SMESHDS_Group* aGrpDS = dynamic_cast<SMESHDS_Group*>( aGrpBaseDS );
                     if ( aGrpDS )
                       myWriter.AddGroup( aGrpDS );
@@ -2959,9 +3560,9 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                     SMESHDS_GroupOnGeom* aGeomGrp =
                       dynamic_cast<SMESHDS_GroupOnGeom*>( aGrpBaseDS );
                     if ( aGeomGrp ) {
-                      SALOMEDS::SObject_var mySubRef, myShape;
-                      if (mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ) &&
-                          mySubRef->ReferencedObject( myShape ) &&
+                      SALOMEDS::SObject_wrap mySubRef, myShape;
+                      if (mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef.inout() ) &&
+                          mySubRef->ReferencedObject( myShape.inout() ) &&
                           !CORBA::is_nil( myShape->GetObject() ))
                       {
                         string myRefOnObject = myShape->GetID();
@@ -2981,33 +3582,47 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                         myWriter.AddGroup( aGeomGrp );
                       }
                     }
+                    else if ( SMESH_GroupOnFilter_i* aFilterGrp_i = 
+                              dynamic_cast<SMESH_GroupOnFilter_i*>( myGroupImpl ))
+                    {
+                      std::string str = aFilterGrp_i->FilterToString();
+                      std::string hdfGrpName = "Filter " + SMESH_Comment(anId);
+                      aSize[ 0 ] = str.length() + 1;
+                      aDataset = new HDFdataset( hdfGrpName.c_str(), aGroup, HDF_STRING, aSize, 1);
+                      aDataset->CreateOnDisk();
+                      aDataset->WriteOnDisk( ( char* )( str.c_str() ) );
+                      aDataset->CloseOnDisk();
+                    }
                   }
                 }
                 aGroup->CloseOnDisk();
               }
-            } // loop on groups 
-            
+            } // loop on groups
+
             if ( strcmp( strHasData.c_str(), "1" ) == 0 )
             {
               // Flush current mesh information into MED file
               myWriter.Perform();
-              
+
+              // save info on nb of elements
+              SMESH_PreMeshInfo::SaveToFile( myImpl, id, aFile );
+
               // maybe a shape was deleted in the study
               if ( !shapeRefFound && !mySMESHDSMesh->ShapeToMesh().IsNull() && hasShape) {
                 TopoDS_Shape nullShape;
                 myLocMesh.ShapeToMesh( nullShape ); // remove shape referring data
               }
-              
+
               if ( !mySMESHDSMesh->SubMeshes().empty() )
               {
                 // Store submeshes
                 // ----------------
                 aGroup = new HDFgroup( "Submeshes", aTopGroup );
                 aGroup->CreateOnDisk();
-                
+
                 // each element belongs to one or none submesh,
                 // so for each node/element, we store a submesh ID
-                
+
                 // Make maps of submesh IDs of elements sorted by element IDs
                 typedef int TElemID;
                 typedef int TSubMID;
@@ -3032,7 +3647,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                   for ( itElem = aSubMesh->GetElements(); itElem->more(); ++hint)
                     hint = eId2smId.insert( hint, make_pair( itElem->next()->GetID(), aSubMeID ));
                 }
-                
+
                 // Care of elements that are not on submeshes
                 if ( mySMESHDSMesh->NbNodes() != nId2smId.size() ) {
                   for ( itNode = mySMESHDSMesh->nodesIterator(); itNode->more(); )
@@ -3046,7 +3661,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                   for ( itElem = mySMESHDSMesh->elementsIterator(); itElem->more(); )
                     eId2smId.insert( make_pair( itElem->next()->GetID(), 0 ));
                 }
-                
+
                 // Store submesh IDs
                 for ( int isNode = 0; isNode < 2; ++isNode )
                 {
@@ -3067,20 +3682,22 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                   //
                   delete[] smIDs;
                 }
-                
+
+                aGroup->CloseOnDisk();
+
                 // Store node positions on sub-shapes (SMDS_Position):
                 // ----------------------------------------------------
-                
+
                 aGroup = new HDFgroup( "Node Positions", aTopGroup );
                 aGroup->CreateOnDisk();
-                
+
                 // in aGroup, create 5 datasets to contain:
                 // "Nodes on Edges" - ID of node on edge
                 // "Edge positions" - U parameter on node on edge
                 // "Nodes on Faces" - ID of node on face
                 // "Face U positions" - U parameter of node on face
                 // "Face V positions" - V parameter of node on face
-                
+
                 // Find out nb of nodes on edges and faces
                 // Collect corresponing sub-meshes
                 int nbEdgeNodes = 0, nbFaceNodes = 0;
@@ -3093,7 +3710,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                     continue; // submesh containing other submeshs
                   int nbNodes = aSubMesh->NbNodes();
                   if ( nbNodes == 0 ) continue;
-                  
+
                   int aShapeID = (*itSubM).first;
                   if ( aShapeID < 1 || aShapeID > mySMESHDSMesh->MaxShapeIndex() )
                     continue;
@@ -3121,7 +3738,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                   int* aNodeIDs = new int [ nbNodes ];
                   double* aUPos = new double [ nbNodes ];
                   double* aVPos = ( onFace ? new double[ nbNodes ] : 0 );
-                  
+
                   // Fill arrays
                   // loop on sub-meshes
                   list<SMESHDS_SubMesh*> * pListSM = ( onFace ? &aFaceSM : &aEdgeSM );
@@ -3129,7 +3746,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                   for ( ; itSM != pListSM->end(); itSM++ )
                   {
                     SMESHDS_SubMesh* aSubMesh = (*itSM);
-                    
+
                     SMDS_NodeIteratorPtr itNode = aSubMesh->GetNodes();
                     // loop on nodes in aSubMesh
                     while ( itNode->more() )
@@ -3137,7 +3754,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                       //node ID
                       const SMDS_MeshNode* node = itNode->next();
                       aNodeIDs [ iNode ] = node->GetID();
-                      
+
                       // Position
                       const SMDS_PositionPtr pos = node->GetPosition();
                       if ( onFace ) { // on FACE
@@ -3163,7 +3780,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                       }
                     } // loop on nodes in aSubMesh
                   } // loop on sub-meshes
-                  
+
                   // Write datasets
                   if ( nbNodes )
                   {
@@ -3174,7 +3791,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                     aDataset->CreateOnDisk();
                     aDataset->WriteOnDisk( aNodeIDs );
                     aDataset->CloseOnDisk();
-                
+
                     // U Positions
                     aDSName = ( onFace ? "Face U positions" : "Edge positions");
                     aDataset = new HDFdataset( (char*)aDSName.c_str(), aGroup, HDF_FLOAT64, aSize, 1);
@@ -3192,15 +3809,15 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                   delete [] aNodeIDs;
                   delete [] aUPos;
                   if ( aVPos ) delete [] aVPos;
-                  
+
                 } // treat positions on edges or faces
-                
+
                 // close "Node Positions" group
-                aGroup->CloseOnDisk(); 
-                
+                aGroup->CloseOnDisk();
+
               } // if ( there are submeshes in SMESHDS_Mesh )
             } // if ( hasData )
-            
+
             // close mesh HDF group
             aTopGroup->CloseOnDisk();
           }
@@ -3208,7 +3825,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
       }
     }
   }
-  
+
   // close HDF file
   aFile->CloseOnDisk();
   delete aFile;
@@ -3217,7 +3834,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
   aStreamFile = SALOMEDS_Tool::PutFilesToStream( tmpDir.ToCString(), aFileSeq.in(), isMultiFile );
 
   // Remove temporary files and directory
-  if ( !isMultiFile ) 
+  if ( !isMultiFile )
     SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true );
 
   INFOS( "SMESH_Gen_i::Save() completed" );
@@ -3244,12 +3861,12 @@ SALOMEDS::TMPFile* SMESH_Gen_i::SaveASCII( SALOMEDS::SComponent_ptr theComponent
   int size = aStreamFile.in().length();
   _CORBA_Octet* buffer = new _CORBA_Octet[size*3+1];
   for ( int i = 0; i < size; i++ )
-    sprintf( (char*)&(buffer[i*3]), "|%02x", (char*)(aStreamFile[i]) );
+    sprintf( (char*)&(buffer[i*3]), "|%02x", aStreamFile[i] );
 
   buffer[size * 3] = '\0';
 
   SALOMEDS::TMPFile_var anAsciiStreamFile = new SALOMEDS::TMPFile(size*3, size*3, buffer, 1);
-  
+
   return anAsciiStreamFile._retn();
 }
 
@@ -3270,36 +3887,9 @@ void SMESH_Gen_i::loadGeomData( SALOMEDS::SComponent_ptr theCompRoot )
   if ( aStudy->_is_nil() )
     return;
 
-  SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder(); 
+  SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
   aStudyBuilder->LoadWith( theCompRoot, GetGeomEngine() );
 }
-//=============================================================================
-/*!
- * \brief Creates SMDS_Position according to shape type
- */
-//=============================================================================
-
-class PositionCreator {
-public:
-  SMDS_PositionPtr MakePosition(const TopAbs_ShapeEnum type) {
-    return (this->*myFuncTable[ type ])();
-  }
-  PositionCreator() {
-    myFuncTable.resize( (size_t) TopAbs_SHAPE, & PositionCreator::defaultPosition );
-    myFuncTable[ TopAbs_SOLID  ] = & PositionCreator::volumePosition;
-    myFuncTable[ TopAbs_FACE   ] = & PositionCreator::facePosition;
-    myFuncTable[ TopAbs_EDGE   ] = & PositionCreator::edgePosition;
-    myFuncTable[ TopAbs_VERTEX ] = & PositionCreator::vertexPosition;
-  }
-private:
-  SMDS_PositionPtr edgePosition()    const { return SMDS_PositionPtr( new SMDS_EdgePosition  ); }
-  SMDS_PositionPtr facePosition()    const { return SMDS_PositionPtr( new SMDS_FacePosition  ); }
-  SMDS_PositionPtr volumePosition()  const { return SMDS_PositionPtr( new SMDS_SpacePosition ); }
-  SMDS_PositionPtr vertexPosition()  const { return SMDS_PositionPtr( new SMDS_VertexPosition); }
-  SMDS_PositionPtr defaultPosition() const { return SMDS_SpacePosition::originSpacePosition();  }
-  typedef SMDS_PositionPtr (PositionCreator:: * FmakePos)() const;
-  vector<FmakePos> myFuncTable;
-};
 
 //=============================================================================
 /*!
@@ -3316,7 +3906,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
 {
   INFOS( "SMESH_Gen_i::Load" );
 
-  if ( myCurrentStudy->_is_nil() || 
+  if ( myCurrentStudy->_is_nil() ||
        theComponent->GetStudy()->StudyId() != myCurrentStudy->StudyId() )
     SetCurrentStudy( theComponent->GetStudy() );
 
@@ -3332,18 +3922,18 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
   // Get temporary files location
   TCollection_AsciiString tmpDir =
     isMultiFile ? TCollection_AsciiString( ( char* )theURL ) : ( char* )SALOMEDS_Tool::GetTmpDir().c_str();
-    
-    INFOS( "THE URL++++++++++++++" )
-    INFOS( theURL );
-    INFOS( "THE TMP PATH+++++++++" );
-    INFOS( tmpDir );
+
+  INFOS( "THE URL++++++++++++++" );
+  INFOS( theURL );
+  INFOS( "THE TMP PATH+++++++++" );
+  INFOS( tmpDir );
 
   // Convert the stream into sequence of files to process
   SALOMEDS::ListOfFileNames_var aFileSeq = SALOMEDS_Tool::PutStreamToFiles( theStream,
                                                                             tmpDir.ToCString(),
                                                                             isMultiFile );
   TCollection_AsciiString aStudyName( "" );
-  if ( isMultiFile ) 
+  if ( isMultiFile )
     aStudyName = ( (char*)SALOMEDS_Tool::GetNameFromPath( myCurrentStudy->URL() ).c_str() );
 
   // Set names of temporary files
@@ -3369,8 +3959,10 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
     return false;
   }
 
-  DriverMED_R_SMESHDS_Mesh myReader;
-  myReader.SetFile( meshfile.ToCString() );
+  TPythonDump pd; // prevent dump during loading
+
+  // DriverMED_R_SMESHDS_Mesh myReader;
+  // myReader.SetFile( meshfile.ToCString() );
 
   // For PAL13473 ("Repetitive mesh") implementation.
   // New dependencies between SMESH objects are established:
@@ -3386,16 +3978,16 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
   list< pair< SMESH_Mesh_i*,       HDFgroup* > > meshGroupList;
 
   // get total number of top-level groups
-  int aNbGroups = aFile->nInternalObjects(); 
+  int aNbGroups = aFile->nInternalObjects();
   if ( aNbGroups > 0 ) {
     // --> in first turn we should read&create hypotheses
     if ( aFile->ExistInternalObject( "Hypotheses" ) ) {
       // open hypotheses root HDF group
-      aTopGroup = new HDFgroup( "Hypotheses", aFile ); 
+      aTopGroup = new HDFgroup( "Hypotheses", aFile );
       aTopGroup->OpenOnDisk();
 
       // get number of hypotheses
-      int aNbObjects = aTopGroup->nInternalObjects(); 
+      int aNbObjects = aTopGroup->nInternalObjects();
       for ( int j = 0; j < aNbObjects; j++ ) {
         // try to identify hypothesis
         char hypGrpName[ HDF_NAME_MAX_LEN+1 ];
@@ -3403,7 +3995,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
 
         if ( string( hypGrpName ).substr( 0, 10 ) == string( "Hypothesis" ) ) {
           // open hypothesis group
-          aGroup = new HDFgroup( hypGrpName, aTopGroup ); 
+          aGroup = new HDFgroup( hypGrpName, aTopGroup );
           aGroup->OpenOnDisk();
 
           // --> get hypothesis id
@@ -3473,8 +4065,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             if ( myImpl ) {
               // myImpl->LoadFrom( hypdata.c_str() );
               hypDataList.push_back( make_pair( myImpl, hypdata ));
-              string iorString = GetORB()->object_to_string( myHyp );
-              int newId = myStudyContext->findId( iorString );
+              CORBA::String_var iorString = GetORB()->object_to_string( myHyp );
+              int newId = myStudyContext->findId( iorString.in() );
               myStudyContext->mapOldToNew( id, newId );
             }
             else
@@ -3490,11 +4082,11 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
     // --> then we should read&create algorithms
     if ( aFile->ExistInternalObject( "Algorithms" ) ) {
       // open algorithms root HDF group
-      aTopGroup = new HDFgroup( "Algorithms", aFile ); 
+      aTopGroup = new HDFgroup( "Algorithms", aFile );
       aTopGroup->OpenOnDisk();
 
       // get number of algorithms
-      int aNbObjects = aTopGroup->nInternalObjects(); 
+      int aNbObjects = aTopGroup->nInternalObjects();
       for ( int j = 0; j < aNbObjects; j++ ) {
         // try to identify algorithm
         char hypGrpName[ HDF_NAME_MAX_LEN+1 ];
@@ -3502,7 +4094,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
 
         if ( string( hypGrpName ).substr( 0, 9 ) == string( "Algorithm" ) ) {
           // open algorithm group
-          aGroup = new HDFgroup( hypGrpName, aTopGroup ); 
+          aGroup = new HDFgroup( hypGrpName, aTopGroup );
           aGroup->OpenOnDisk();
 
           // --> get algorithm id
@@ -3573,8 +4165,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             if ( myImpl ) {
               //myImpl->LoadFrom( hypdata.c_str() );
               hypDataList.push_back( make_pair( myImpl, hypdata ));
-              string iorString = GetORB()->object_to_string( myHyp );
-              int newId = myStudyContext->findId( iorString );
+              CORBA::String_var iorString = GetORB()->object_to_string( myHyp );
+              int newId = myStudyContext->findId( iorString.in() );
               myStudyContext->mapOldToNew( id, newId );
             }
             else
@@ -3600,11 +4192,11 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
           continue;
 
         // open mesh HDF group
-        aTopGroup = new HDFgroup( meshName, aFile ); 
+        aTopGroup = new HDFgroup( meshName, aFile );
         aTopGroup->OpenOnDisk();
 
         // get number of child HDF objects
-        int aNbObjects = aTopGroup->nInternalObjects(); 
+        int aNbObjects = aTopGroup->nInternalObjects();
         if ( aNbObjects > 0 ) {
           // create mesh
           if(MYDEBUG) MESSAGE( "VSR - load mesh : id = " << id );
@@ -3614,8 +4206,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             continue;
           meshGroupList.push_back( make_pair( myNewMeshImpl, aTopGroup ));
 
-          string iorString = GetORB()->object_to_string( myNewMesh );
-          int newId = myStudyContext->findId( iorString );
+          CORBA::String_var iorString = GetORB()->object_to_string( myNewMesh );
+          int newId = myStudyContext->findId( iorString.in() );
           myStudyContext->mapOldToNew( id, newId );
 
           // ouv : NPAL12872
@@ -3630,7 +4222,8 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             int* anAutoColor = new int[ size ];
             aDataset->ReadFromDisk( anAutoColor );
             aDataset->CloseOnDisk();
-            myNewMeshImpl->SetAutoColor( (bool)anAutoColor[0] );
+            myNewMeshImpl->GetImpl().SetAutoColor( (bool)anAutoColor[0] );
+            delete [] anAutoColor;
           }
 
           // try to read and set reference to shape
@@ -3644,7 +4237,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             aDataset->ReadFromDisk( refFromFile );
             aDataset->CloseOnDisk();
             if ( strlen( refFromFile ) > 0 ) {
-              SALOMEDS::SObject_var shapeSO = myCurrentStudy->FindObjectID( refFromFile );
+              SALOMEDS::SObject_wrap shapeSO = myCurrentStudy->FindObjectID( refFromFile );
 
               // Make sure GEOM data are loaded first
               //loadGeomData( shapeSO->GetFatherComponent() );
@@ -3656,18 +4249,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                   myNewMeshImpl->SetShape( aShapeObject );
               }
             }
-          }
-
-          // issue 0020693. Restore _isModified flag
-          if( aTopGroup->ExistInternalObject( "_isModified" ) )
-          {
-            aDataset = new HDFdataset( "_isModified", aTopGroup );
-            aDataset->OpenOnDisk();
-            size = aDataset->GetSize();
-            int* isModified = new int[ size ];
-            aDataset->ReadFromDisk( isModified );
-            aDataset->CloseOnDisk();
-            myNewMeshImpl->GetImpl().SetIsModified( bool(*isModified));
+            delete [] refFromFile;
           }
 
           // issue 20918. Restore Persistent Id of SMESHDS_Mesh
@@ -3680,10 +4262,11 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             aDataset->ReadFromDisk( meshPersistentId );
             aDataset->CloseOnDisk();
             myNewMeshImpl->GetImpl().GetMeshDS()->SetPersistentId( *meshPersistentId );
+            delete [] meshPersistentId;
           }
         }
       }
-    }
+    } // reading MESHes
 
     // As all object that can be referred by hypothesis are created,
     // we can restore hypothesis data
@@ -3703,15 +4286,15 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
     {
       aTopGroup                   = meshi_group->second;
       SMESH_Mesh_i* myNewMeshImpl = meshi_group->first;
-      ::SMESH_Mesh& myLocMesh     = myNewMeshImpl->GetImpl();
-      SMESHDS_Mesh* mySMESHDSMesh = myLocMesh.GetMeshDS();
+      //::SMESH_Mesh& myLocMesh     = myNewMeshImpl->GetImpl();
+      //SMESHDS_Mesh* mySMESHDSMesh = myLocMesh.GetMeshDS();
 
       GEOM::GEOM_Object_var aShapeObject = myNewMeshImpl->GetShapeToMesh();
       bool hasData = false;
 
       // get mesh old id
-      string iorString = GetORB()->object_to_string( myNewMeshImpl->_this() );
-      int newId = myStudyContext->findId( iorString );
+      CORBA::String_var iorString = GetORB()->object_to_string( myNewMeshImpl->_this() );
+      int newId = myStudyContext->findId( iorString.in() );
       int id = myStudyContext->getOldId( newId );
 
       // try to find mesh data dataset
@@ -3725,19 +4308,21 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
         aDataset->CloseOnDisk();
         if ( strcmp( strHasData, "1") == 0 ) {
           // read mesh data from MED file
-          myReader.SetMesh( mySMESHDSMesh );
-          myReader.SetMeshId( id );
-          myReader.Perform();
+          // myReader.SetMesh( mySMESHDSMesh );
+          // myReader.SetMeshId( id );
+          // myReader.Perform();
           hasData = true;
         }
+        delete [] strHasData;
       }
 
-      // try to get applied algorithms
+      // Try to get applied ALGORITHMS (mesh is not cleared by algo addition because
+      // nodes and elements are not yet put into sub-meshes)
       if ( aTopGroup->ExistInternalObject( "Applied Algorithms" ) ) {
         aGroup = new HDFgroup( "Applied Algorithms", aTopGroup );
         aGroup->OpenOnDisk();
         // get number of applied algorithms
-        int aNbSubObjects = aGroup->nInternalObjects(); 
+        int aNbSubObjects = aGroup->nInternalObjects();
         if(MYDEBUG) MESSAGE( "VSR - number of applied algos " << aNbSubObjects );
         for ( int j = 0; j < aNbSubObjects; j++ ) {
           char name_dataset[ HDF_NAME_MAX_LEN+1 ];
@@ -3750,12 +4335,11 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             char* refFromFile = new char[ size ];
             aDataset->ReadFromDisk( refFromFile );
             aDataset->CloseOnDisk();
-
             // san - it is impossible to recover applied algorithms using their entries within Load() method
-
-            //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile );
+            //SALOMEDS::SObject_wrap hypSO = myCurrentStudy->FindObjectID( refFromFile );
             //CORBA::Object_var hypObject = SObjectToObject( hypSO );
             int id = atoi( refFromFile );
+            delete [] refFromFile;
             string anIOR = myStudyContext->getIORbyOldId( id );
             if ( !anIOR.empty() ) {
               CORBA::Object_var hypObject = GetORB()->string_to_object( anIOR.c_str() );
@@ -3776,7 +4360,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
         aGroup = new HDFgroup( "Applied Hypotheses", aTopGroup );
         aGroup->OpenOnDisk();
         // get number of applied hypotheses
-        int aNbSubObjects = aGroup->nInternalObjects(); 
+        int aNbSubObjects = aGroup->nInternalObjects();
         for ( int j = 0; j < aNbSubObjects; j++ ) {
           char name_dataset[ HDF_NAME_MAX_LEN+1 ];
           aGroup->InternalObjectIndentify( j, name_dataset );
@@ -3788,12 +4372,11 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             char* refFromFile = new char[ size ];
             aDataset->ReadFromDisk( refFromFile );
             aDataset->CloseOnDisk();
-
             // san - it is impossible to recover applied hypotheses using their entries within Load() method
-
-            //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile );
+            //SALOMEDS::SObject_wrap hypSO = myCurrentStudy->FindObjectID( refFromFile );
             //CORBA::Object_var hypObject = SObjectToObject( hypSO );
             int id = atoi( refFromFile );
+            delete [] refFromFile;
             string anIOR = myStudyContext->getIORbyOldId( id );
             if ( !anIOR.empty() ) {
               CORBA::Object_var hypObject = GetORB()->string_to_object( anIOR.c_str() );
@@ -3809,7 +4392,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
         aGroup->CloseOnDisk();
       }
 
-      // --> try to find submeshes containers for each type of submesh
+      // --> try to find SUB-MESHES containers for each type of submesh
       for ( int j = GetSubMeshOnVertexTag(); j <= GetSubMeshOnCompoundTag(); j++ ) {
         char name_meshgroup[ 30 ];
         if ( j == GetSubMeshOnVertexTag() )
@@ -3834,7 +4417,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
           aGroup->OpenOnDisk();
 
           // get number of submeshes
-          int aNbSubMeshes = aGroup->nInternalObjects(); 
+          int aNbSubMeshes = aGroup->nInternalObjects();
           for ( int k = 0; k < aNbSubMeshes; k++ ) {
             // identify submesh
             char name_submeshgroup[ HDF_NAME_MAX_LEN+1 ];
@@ -3861,7 +4444,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                 aDataset->ReadFromDisk( refFromFile );
                 aDataset->CloseOnDisk();
                 if ( strlen( refFromFile ) > 0 ) {
-                  SALOMEDS::SObject_var subShapeSO = myCurrentStudy->FindObjectID( refFromFile );
+                  SALOMEDS::SObject_wrap subShapeSO = myCurrentStudy->FindObjectID( refFromFile );
                   CORBA::Object_var subShapeObject = SObjectToObject( subShapeSO );
                   if ( !CORBA::is_nil( subShapeObject ) ) {
                     aSubShapeObject = GEOM::GEOM_Object::_narrow( subShapeObject );
@@ -3880,28 +4463,13 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
               if ( aSubMesh->_is_nil() )
                 continue;
 
-              // VSR: Get submesh data from MED convertor
-              //                  int anInternalSubmeshId = aSubMesh->GetId(); // this is not a persistent ID, it's an internal one computed from sub-shape
-              //                  if (myNewMeshImpl->_mapSubMesh.find(anInternalSubmeshId) != myNewMeshImpl->_mapSubMesh.end()) {
-              //                    if(MYDEBUG) MESSAGE("VSR - SMESH_Gen_i::Load(): loading from MED file submesh with ID = " <<
-              //                            subid << " for subshape # " << anInternalSubmeshId);
-              //                    SMESHDS_SubMesh* aSubMeshDS =
-              //                      myNewMeshImpl->_mapSubMesh[anInternalSubmeshId]->CreateSubMeshDS();
-              //                    if ( !aSubMeshDS ) {
-              //                      if(MYDEBUG) MESSAGE("VSR - SMESH_Gen_i::Load(): FAILED to create a submesh for subshape # " <<
-              //                              anInternalSubmeshId << " in current mesh!");
-              //                    }
-              //                    else
-              //                      myReader.GetSubMesh( aSubMeshDS, subid );
-              //                  }
-
               // try to get applied algorithms
               if ( aSubGroup->ExistInternalObject( "Applied Algorithms" ) ) {
                 // open "applied algorithms" HDF group
                 aSubSubGroup = new HDFgroup( "Applied Algorithms", aSubGroup );
                 aSubSubGroup->OpenOnDisk();
                 // get number of applied algorithms
-                int aNbSubObjects = aSubSubGroup->nInternalObjects(); 
+                int aNbSubObjects = aSubSubGroup->nInternalObjects();
                 for ( int l = 0; l < aNbSubObjects; l++ ) {
                   char name_dataset[ HDF_NAME_MAX_LEN+1 ];
                   aSubSubGroup->InternalObjectIndentify( l, name_dataset );
@@ -3914,8 +4482,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                     aDataset->ReadFromDisk( refFromFile );
                     aDataset->CloseOnDisk();
 
-                    //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile );
-                    //CORBA::Object_var hypObject = SObjectToObject( hypSO );
                     int id = atoi( refFromFile );
                     string anIOR = myStudyContext->getIORbyOldId( id );
                     if ( !anIOR.empty() ) {
@@ -3938,7 +4504,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                 aSubSubGroup = new HDFgroup( "Applied Hypotheses", aSubGroup );
                 aSubSubGroup->OpenOnDisk();
                 // get number of applied hypotheses
-                int aNbSubObjects = aSubSubGroup->nInternalObjects(); 
+                int aNbSubObjects = aSubSubGroup->nInternalObjects();
                 for ( int l = 0; l < aNbSubObjects; l++ ) {
                   char name_dataset[ HDF_NAME_MAX_LEN+1 ];
                   aSubSubGroup->InternalObjectIndentify( l, name_dataset );
@@ -3951,8 +4517,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                     aDataset->ReadFromDisk( refFromFile );
                     aDataset->CloseOnDisk();
 
-                    //SALOMEDS::SObject_var hypSO = myCurrentStudy->FindObjectID( refFromFile );
-                    //CORBA::Object_var hypObject = SObjectToObject( hypSO );
                     int id = atoi( refFromFile );
                     string anIOR = myStudyContext->getIORbyOldId( id );
                     if ( !anIOR.empty() ) {
@@ -3965,225 +4529,21 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                     }
                   }
                 }
-                // close "applied hypotheses" HDF group
+                // close "APPLIED HYPOTHESES" hdf group
                 aSubSubGroup->CloseOnDisk();
               }
 
-              // close submesh HDF group
+              // close SUB-MESH hdf group
               aSubGroup->CloseOnDisk();
             }
           }
-          // close submeshes containers HDF group
+          // close SUB-MESHES containers hdf group
           aGroup->CloseOnDisk();
         }
       }
 
-      if(hasData) {
-
-        // Read sub-meshes from MED
-        // -------------------------
-        if(MYDEBUG) MESSAGE("Create all sub-meshes");
-        bool submeshesInFamilies = ( ! aTopGroup->ExistInternalObject( "Submeshes" ));
-        if ( submeshesInFamilies )
-        {
-          // old way working before fix of PAL 12992
-          myReader.CreateAllSubMeshes();
-        }
-        else
-        {
-          // open a group
-          aGroup = new HDFgroup( "Submeshes", aTopGroup ); 
-          aGroup->OpenOnDisk();
-
-          int maxID = Max( mySMESHDSMesh->MaxSubMeshIndex(), mySMESHDSMesh->MaxShapeIndex() );
-          vector< SMESHDS_SubMesh * > subMeshes( maxID + 1, (SMESHDS_SubMesh*) 0 );
-          vector< TopAbs_ShapeEnum  > smType   ( maxID + 1, TopAbs_SHAPE ); 
-
-          PositionCreator aPositionCreator;
-
-          SMDS_NodeIteratorPtr nIt = mySMESHDSMesh->nodesIterator();
-          SMDS_ElemIteratorPtr eIt = mySMESHDSMesh->elementsIterator();
-          for ( int isNode = 0; isNode < 2; ++isNode )
-          {
-            string aDSName( isNode ? "Node Submeshes" : "Element Submeshes");
-            if ( aGroup->ExistInternalObject( (char*) aDSName.c_str() ))
-            {
-              aDataset = new HDFdataset( (char*) aDSName.c_str(), aGroup );
-              aDataset->OpenOnDisk();
-              // read submesh IDs for all elements sorted by ID
-              int nbElems = aDataset->GetSize();
-              int* smIDs = new int [ nbElems ];
-              aDataset->ReadFromDisk( smIDs );
-              aDataset->CloseOnDisk();
-
-              // get elements sorted by ID
-              TIDSortedElemSet elemSet;
-              if ( isNode )
-                while ( nIt->more() ) elemSet.insert( nIt->next() );
-              else
-                while ( eIt->more() ) elemSet.insert( eIt->next() );
-              //ASSERT( elemSet.size() == nbElems ); -- issue 20182
-              // -- Most probably a bad study was saved when there were
-              // not fixed bugs in SMDS_MeshInfo
-              if ( elemSet.size() < nbElems ) {
-#ifdef _DEBUG_
-                cout << "SMESH_Gen_i::Load(), warning: Node position data is invalid" << endl;
-#endif
-                nbElems = elemSet.size();
-              }
-              // add elements to submeshes
-              TIDSortedElemSet::iterator iE = elemSet.begin();
-              for ( int i = 0; i < nbElems; ++i, ++iE )
-              {
-                int smID = smIDs[ i ];
-                if ( smID == 0 ) continue;
-                const SMDS_MeshElement* elem = *iE;
-                if( smID > maxID ) {
-                  // corresponding subshape no longer exists: maybe geom group has been edited
-                  if ( myNewMeshImpl->HasShapeToMesh() )
-                    mySMESHDSMesh->RemoveElement( elem );
-                  continue;
-                }
-                // get or create submesh
-                SMESHDS_SubMesh* & sm = subMeshes[ smID ];
-                if ( ! sm ) {
-                  sm = mySMESHDSMesh->NewSubMesh( smID );
-                  smType[ smID ] = mySMESHDSMesh->IndexToShape( smID ).ShapeType();
-                }
-                // add
-                if ( isNode ) {
-                  SMDS_PositionPtr pos = aPositionCreator.MakePosition( smType[ smID ]);
-                  SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( static_cast<const SMDS_MeshNode*>( elem ));
-                  node->SetPosition( pos );
-                  sm->AddNode( node );
-                } else {
-                  sm->AddElement( elem );
-                }
-              }
-              delete [] smIDs;
-            }
-          }
-        } // end reading submeshes
-
-        // Read node positions on sub-shapes (SMDS_Position)
-
-        if ( aTopGroup->ExistInternalObject( "Node Positions" ))
-        {
-          // There are 5 datasets to read:
-          // "Nodes on Edges" - ID of node on edge
-          // "Edge positions" - U parameter on node on edge
-          // "Nodes on Faces" - ID of node on face
-          // "Face U positions" - U parameter of node on face
-          // "Face V positions" - V parameter of node on face
-          const char* aEid_DSName = "Nodes on Edges";
-          const char* aEu_DSName  = "Edge positions";
-          const char* aFu_DSName  = "Face U positions";
-          //char* aFid_DSName = "Nodes on Faces";
-          //char* aFv_DSName  = "Face V positions";
-
-          // data to retrieve
-          int nbEids = 0, nbFids = 0;
-          int *aEids = 0, *aFids  = 0;
-          double *aEpos = 0, *aFupos = 0, *aFvpos = 0;
-
-          // open a group
-          aGroup = new HDFgroup( "Node Positions", aTopGroup ); 
-          aGroup->OpenOnDisk();
-
-          // loop on 5 data sets
-          int aNbObjects = aGroup->nInternalObjects();
-          for ( int i = 0; i < aNbObjects; i++ )
-          {
-            // identify dataset
-            char aDSName[ HDF_NAME_MAX_LEN+1 ];
-            aGroup->InternalObjectIndentify( i, aDSName );
-            // read data
-            aDataset = new HDFdataset( aDSName, aGroup );
-            aDataset->OpenOnDisk();
-            if ( aDataset->GetType() == HDF_FLOAT64 ) // Positions
-            {
-              double* pos = new double [ aDataset->GetSize() ];
-              aDataset->ReadFromDisk( pos );
-              // which one?
-              if ( strncmp( aDSName, aEu_DSName, strlen( aEu_DSName )) == 0 )
-                aEpos = pos;
-              else if ( strncmp( aDSName, aFu_DSName, strlen( aFu_DSName )) == 0 )
-                aFupos = pos;
-              else
-                aFvpos = pos;
-            }
-            else // NODE IDS
-            {
-              int aSize = aDataset->GetSize();
-
-              // for reading files, created from 18.07.2005 till 10.10.2005
-              if (aDataset->GetType() == HDF_STRING)
-                aSize /= sizeof(int);
-
-              int* ids = new int [aSize];
-              aDataset->ReadFromDisk( ids );
-              // on face or nodes?
-              if ( strncmp( aDSName, aEid_DSName, strlen( aEid_DSName )) == 0 ) {
-                aEids = ids;
-                nbEids = aSize;
-              }
-              else {
-                aFids = ids;
-                nbFids = aSize;
-              }
-            }
-            aDataset->CloseOnDisk();
-          } // loop on 5 datasets
-
-          // Set node positions on edges or faces
-          for ( int onFace = 0; onFace < 2; onFace++ )
-          {
-            int nbNodes = ( onFace ? nbFids : nbEids );
-            if ( nbNodes == 0 ) continue;
-            int* aNodeIDs = ( onFace ? aFids : aEids );
-            double* aUPos = ( onFace ? aFupos : aEpos );
-            double* aVPos = ( onFace ? aFvpos : 0 );
-            // loop on node IDs
-            for ( int iNode = 0; iNode < nbNodes; iNode++ )
-            {
-              const SMDS_MeshNode* node = mySMESHDSMesh->FindNode( aNodeIDs[ iNode ]);
-              if ( !node ) continue; // maybe removed while Loading() if geometry changed
-              SMDS_PositionPtr aPos = node->GetPosition();
-              ASSERT( aPos );
-              if ( onFace ) {
-                // ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_FACE );-- issue 20182
-                // -- Most probably a bad study was saved when there were
-                // not fixed bugs in SMDS_MeshInfo
-                if ( aPos->GetTypeOfPosition() == SMDS_TOP_FACE ) {
-                  SMDS_FacePosition* fPos = const_cast<SMDS_FacePosition*>
-                    ( static_cast<const SMDS_FacePosition*>( aPos ));
-                  fPos->SetUParameter( aUPos[ iNode ]);
-                  fPos->SetVParameter( aVPos[ iNode ]);
-                }
-              }
-              else {
-                // ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE );-- issue 20182
-                if ( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE ) {
-                  SMDS_EdgePosition* fPos = const_cast<SMDS_EdgePosition*>
-                    ( static_cast<const SMDS_EdgePosition*>( aPos ));
-                  fPos->SetUParameter( aUPos[ iNode ]);
-                }
-              }
-            }
-          }
-          if ( aEids ) delete [] aEids;
-          if ( aFids ) delete [] aFids;
-          if ( aEpos ) delete [] aEpos;
-          if ( aFupos ) delete [] aFupos;
-          if ( aFvpos ) delete [] aFvpos;
-
-          aGroup->CloseOnDisk();
-
-        } // if ( aTopGroup->ExistInternalObject( "Node Positions" ) )
-      } // if ( hasData )
-
-      // try to get groups
-      for ( int ii = GetNodeGroupsTag(); ii <= GetVolumeGroupsTag(); ii++ ) {
+      // try to get GROUPS
+      for ( int ii = GetNodeGroupsTag(); ii <= GetBallElementsGroupsTag(); ii++ ) {
         char name_group[ 30 ];
         if ( ii == GetNodeGroupsTag() )
           strcpy( name_group, "Groups of Nodes" );
@@ -4193,12 +4553,16 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
           strcpy( name_group, "Groups of Faces" );
         else if ( ii == GetVolumeGroupsTag() )
           strcpy( name_group, "Groups of Volumes" );
+        else if ( ii == Get0DElementsGroupsTag() )
+          strcpy( name_group, "Groups of 0D Elements" );
+        else if ( ii == GetBallElementsGroupsTag() )
+          strcpy( name_group, "Groups of Balls" );
 
         if ( aTopGroup->ExistInternalObject( name_group ) ) {
           aGroup = new HDFgroup( name_group, aTopGroup );
           aGroup->OpenOnDisk();
           // get number of groups
-          int aNbSubObjects = aGroup->nInternalObjects(); 
+          int aNbSubObjects = aGroup->nInternalObjects();
           for ( int j = 0; j < aNbSubObjects; j++ ) {
             char name_dataset[ HDF_NAME_MAX_LEN+1 ];
             aGroup->InternalObjectIndentify( j, name_dataset );
@@ -4230,7 +4594,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                 aDataset->ReadFromDisk( refFromFile );
                 aDataset->CloseOnDisk();
                 if ( strlen( refFromFile ) > 0 ) {
-                  SALOMEDS::SObject_var shapeSO = myCurrentStudy->FindObjectID( refFromFile );
+                  SALOMEDS::SObject_wrap shapeSO = myCurrentStudy->FindObjectID( refFromFile );
                   CORBA::Object_var shapeObject = SObjectToObject( shapeSO );
                   if ( !CORBA::is_nil( shapeObject ) ) {
                     aShapeObject = GEOM::GEOM_Object::_narrow( shapeObject );
@@ -4239,28 +4603,48 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                   }
                 }
               }
+              // Try to read a filter of SMESH_GroupOnFilter
+              SMESH::Filter_var filter;
+              SMESH_PredicatePtr predicate;
+              std::string hdfGrpName = "Filter " + SMESH_Comment(subid);
+              if ( aGroup->ExistInternalObject( hdfGrpName.c_str() ))
+              {
+                aDataset = new HDFdataset( hdfGrpName.c_str(), aGroup );
+                aDataset->OpenOnDisk();
+                size = aDataset->GetSize();
+                char* persistStr = new char[ size ];
+                aDataset->ReadFromDisk( persistStr );
+                aDataset->CloseOnDisk();
+                if ( strlen( persistStr ) > 0 ) {
+                  filter = SMESH_GroupOnFilter_i::StringToFilter( persistStr );
+                  predicate = SMESH_GroupOnFilter_i::GetPredicate( filter );
+                }
+              }
+
               // Create group servant
               SMESH::ElementType type = (SMESH::ElementType)(ii - GetNodeGroupsTag() + 1);
               SMESH::SMESH_GroupBase_var aNewGroup = SMESH::SMESH_GroupBase::_duplicate
-                ( myNewMeshImpl->createGroup( type, nameFromFile, aShape ) );
-              // Obtain a SMESHDS_Group object 
+                ( myNewMeshImpl->createGroup( type, nameFromFile, aShape, predicate ) );
+              // Obtain a SMESHDS_Group object
               if ( aNewGroup->_is_nil() )
                 continue;
 
               string iorSubString = GetORB()->object_to_string( aNewGroup );
-              int newSubId = myStudyContext->findId( iorSubString );
+              int        newSubId = myStudyContext->findId( iorSubString );
               myStudyContext->mapOldToNew( subid, newSubId );
 
-              SMESH_GroupBase_i* aGroupImpl =
-                dynamic_cast<SMESH_GroupBase_i*>( GetServant( aNewGroup ).in() );
+              SMESH_GroupBase_i* aGroupImpl = SMESH::DownCast< SMESH_GroupBase_i*>( aNewGroup );
               if ( !aGroupImpl )
                 continue;
 
-              SMESH_Group* aLocalGroup  = myLocMesh.GetGroup( aGroupImpl->GetLocalID() );
-              if ( !aLocalGroup )
+              if ( SMESH_GroupOnFilter_i* aFilterGroup =
+                   dynamic_cast< SMESH_GroupOnFilter_i*>( aGroupImpl ))
+                aFilterGroup->SetFilter( filter );
+
+              SMESHDS_GroupBase* aGroupBaseDS = aGroupImpl->GetGroupDS();
+              if ( !aGroupBaseDS )
                 continue;
 
-              SMESHDS_GroupBase* aGroupBaseDS = aLocalGroup->GetGroupDS();
               aGroupBaseDS->SetStoreName( name_dataset );
 
               // ouv : NPAL12872
@@ -4280,16 +4664,25 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
               }
 
               // Fill group with contents from MED file
-              SMESHDS_Group* aGrp = dynamic_cast<SMESHDS_Group*>( aGroupBaseDS );
-              if ( aGrp )
-                myReader.GetGroup( aGrp );
+              // SMESHDS_Group* aGrp = dynamic_cast<SMESHDS_Group*>( aGroupBaseDS );
+              // if ( aGrp )
+              //   myReader.GetGroup( aGrp );
             }
           }
           aGroup->CloseOnDisk();
         }
+      } // reading GROUPs
+
+      // instead of reading mesh data, we read only brief information of all
+      // objects: mesh, groups, sub-meshes (issue 0021208 )
+      if ( hasData )
+      {
+        SMESH_PreMeshInfo::LoadFromFile( myNewMeshImpl, id,
+                                         meshfile.ToCString(), filename.ToCString(),
+                                         !isMultiFile );
       }
 
-      // read submeh order if any
+      // read Sub-Mesh ORDER if any
       if( aTopGroup->ExistInternalObject( "Mesh Order" ) ) {
         aDataset = new HDFdataset( "Mesh Order", aTopGroup );
         aDataset->OpenOnDisk();
@@ -4304,12 +4697,19 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
             anOrderIds.push_back( TListOfInt() );
           else
             anOrderIds.back().push_back(smIDs[ i ]);
-        
+
         myNewMeshImpl->GetImpl().SetMeshOrder( anOrderIds );
       }
     } // loop on meshes
 
-    // notify algos on completed restoration
+    // update hyps needing full mesh data restored (issue 20918)
+    for ( hyp_data = hypDataList.begin(); hyp_data != hypDataList.end(); ++hyp_data )
+    {
+      SMESH_Hypothesis_i* hyp  = hyp_data->first;
+      hyp->UpdateAsMeshesRestored();
+    }
+
+    // notify algos on completed restoration to set sub-mesh event listeners
     for ( meshi_group = meshGroupList.begin(); meshi_group != meshGroupList.end(); ++meshi_group )
     {
       SMESH_Mesh_i* myNewMeshImpl = meshi_group->first;
@@ -4320,28 +4720,39 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
         myLocShape = myLocMesh.GetShapeToMesh();
       else
         myLocShape = SMESH_Mesh::PseudoShape();
-        
+
       myLocMesh.GetSubMesh(myLocShape)->
         ComputeStateEngine (SMESH_subMesh::SUBMESH_RESTORED);
     }
 
-    for ( hyp_data = hypDataList.begin(); hyp_data != hypDataList.end(); ++hyp_data )
-    {
-      SMESH_Hypothesis_i* hyp  = hyp_data->first;
-      hyp->UpdateAsMeshesRestored(); // for hyps needing full mesh data restored (issue 20918)
-    }
-
     // close mesh group
     if(aTopGroup)
-      aTopGroup->CloseOnDisk();   
+      aTopGroup->CloseOnDisk();
   }
   // close HDF file
   aFile->CloseOnDisk();
   delete aFile;
 
   // Remove temporary files created from the stream
-  if ( !isMultiFile ) 
-    SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true );
+  if ( !isMultiFile )
+  {
+    SMESH_File meshFile( meshfile.ToCString() );
+    if ( !meshFile ) // no meshfile exists
+    {
+      SALOMEDS_Tool::RemoveTemporaryFiles( tmpDir.ToCString(), aFileSeq.in(), true );
+    }
+    else
+    {
+      Engines::Container_var container = GetContainerRef();
+      if ( Engines_Container_i* container_i = SMESH::DownCast<Engines_Container_i*>( container ))
+      {
+        container_i->registerTemporaryFile( filename.ToCString() );
+        container_i->registerTemporaryFile( meshfile.ToCString() );
+        container_i->registerTemporaryFile( tmpDir.ToCString() );
+      }
+    }
+  }
+  pd << ""; // prevent optimizing pd out
 
   INFOS( "SMESH_Gen_i::Load completed" );
   return true;
@@ -4382,7 +4793,7 @@ bool SMESH_Gen_i::LoadASCII( SALOMEDS::SComponent_ptr theComponent,
   }
 
   SALOMEDS::TMPFile_var aRealStreamFile = new SALOMEDS::TMPFile(real_size, real_size, buffer, 1);
-  
+
   return Load( theComponent, *(aRealStreamFile._retn()), theURL, isMultiFile );
 }
 
@@ -4399,8 +4810,9 @@ void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent )
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Close" );
 
   // set correct current study
-  if (theComponent->GetStudy()->StudyId() != GetCurrentStudyID())
-    SetCurrentStudy(theComponent->GetStudy());
+  SALOMEDS::Study_var study = theComponent->GetStudy();
+  if ( study->StudyId() != GetCurrentStudyID())
+    setCurrentStudy( study, /*IsBeingClosed=*/true );
 
   // Clear study contexts data
   int studyId = GetCurrentStudyID();
@@ -4409,24 +4821,9 @@ void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent )
     myStudyContextMap.erase( studyId );
   }
 
-  // delete SMESH_Mesh's
-//   See bug IPAL19437.
-//
-//   StudyContextStruct* context = myGen.GetStudyContext( studyId );
-//   map< int, SMESH_Mesh* >::iterator i_mesh = context->mapMesh.begin();
-//   for ( ; i_mesh != context->mapMesh.end(); ++i_mesh ) {
-//     printf( "--------------------------- SMESH_Gen_i::Close, delete aGroup = %p \n", i_mesh->second );
-//     delete i_mesh->second;
-//   }
-  
-
-  // delete SMESHDS_Mesh's
-  // it's too long on big meshes
-//   if ( context->myDocument ) {
-//     delete context->myDocument;
-//     context->myDocument = 0;
-//   }
-  
+  // remove the tmp files meshes are loaded from
+  SMESH_PreMeshInfo::RemoveStudyFiles_TMP_METHOD( theComponent );
+
   myCurrentStudy = SALOMEDS::Study::_nil();
   return;
 }
@@ -4434,7 +4831,7 @@ void SMESH_Gen_i::Close( SALOMEDS::SComponent_ptr theComponent )
 //=============================================================================
 /*!
  *  SMESH_Gen_i::ComponentDataType
- * 
+ *
  *  Get component data type
  */
 //=============================================================================
@@ -4445,11 +4842,11 @@ char* SMESH_Gen_i::ComponentDataType()
   return CORBA::string_dup( "SMESH" );
 }
 
-    
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::IORToLocalPersistentID
- *  
+ *
  *  Transform data from transient form to persistent
  */
 //=============================================================================
@@ -4461,7 +4858,7 @@ char* SMESH_Gen_i::IORToLocalPersistentID( SALOMEDS::SObject_ptr /*theSObject*/,
 {
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::IORToLocalPersistentID" );
   StudyContext* myStudyContext = GetCurrentStudyContext();
-  
+
   if ( myStudyContext && strcmp( IORString, "" ) != 0 ) {
     int anId = myStudyContext->findId( IORString );
     if ( anId ) {
@@ -4499,7 +4896,7 @@ char* SMESH_Gen_i::LocalPersistentIDToIOR( SALOMEDS::SObject_ptr /*theSObject*/,
 
 //=======================================================================
 //function : RegisterObject
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 int SMESH_Gen_i::RegisterObject(CORBA::Object_ptr theObject)
@@ -4542,7 +4939,7 @@ void SMESH_Gen_i::SetName(const char* theIOR,
 {
   if ( theIOR && strcmp( theIOR, "" ) ) {
     CORBA::Object_var anObject = GetORB()->string_to_object( theIOR );
-    SALOMEDS::SObject_var aSO = ObjectToSObject( myCurrentStudy, anObject );
+    SALOMEDS::SObject_wrap aSO = ObjectToSObject( myCurrentStudy, anObject );
     if ( !aSO->_is_nil() ) {
       SetName( aSO, theName );
     }
@@ -4553,21 +4950,31 @@ int SMESH_Gen_i::GetCurrentStudyID()
 {
   return myCurrentStudy->_is_nil() || myCurrentStudy->_non_existent() ? -1 : myCurrentStudy->StudyId();
 }
-    
+
+// Version information
+char* SMESH_Gen_i::getVersion()
+{
+#if SMESH_DEVELOPMENT
+  return CORBA::string_dup(SMESH_VERSION_STR"dev");
+#else
+  return CORBA::string_dup(SMESH_VERSION_STR);
+#endif
+}
+
 //=============================================================================
-/*! 
+/*!
  *  SMESHEngine_factory
  *
- *  C factory, accessible with dlsym, after dlopen  
+ *  C factory, accessible with dlsym, after dlopen
  */
 //=============================================================================
 
 extern "C"
 { SMESH_I_EXPORT
   PortableServer::ObjectId* SMESHEngine_factory( CORBA::ORB_ptr            orb,
-                                                 PortableServer::POA_ptr   poa, 
+                                                 PortableServer::POA_ptr   poa,
                                                  PortableServer::ObjectId* contId,
-                                                 const char*               instanceName, 
+                                                 const char*               instanceName,
                                                  const char*               interfaceName )
   {
     if(MYDEBUG) MESSAGE( "PortableServer::ObjectId* SMESHEngine_factory()" );