diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonBusinessObjectFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonBusinessObjectFactory.java
index 0d1b8706f5db33c664ba366fae380c36ca93afe2..2006f8c66417debcd70ea3d97def9d76d1afdb89 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonBusinessObjectFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonBusinessObjectFactory.java
@@ -87,6 +87,7 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.materiallister.Materi
 import ch.systemsx.cisd.openbis.generic.server.business.bo.samplelister.ISampleLister;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.samplelister.SampleLister;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.deletion.EntityHistoryCreator;
 import ch.systemsx.cisd.openbis.generic.server.jython.api.v1.impl.IMasterDataScriptRegistrationRunner;
 import ch.systemsx.cisd.openbis.generic.shared.IJythonEvaluatorPool;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
@@ -104,37 +105,41 @@ public final class CommonBusinessObjectFactory extends AbstractBusinessObjectFac
 
     private final IJythonEvaluatorPool jythonEvaluatorPool;
 
+    private EntityHistoryCreator historyCreator;
+
     public CommonBusinessObjectFactory(IDAOFactory daoFactory, IDataStoreServiceFactory dssFactory,
             IRelationshipService relationshipService,
             IEntityOperationChecker entityOperationChecker,
             IServiceConversationClientManagerLocal conversationClient,
             IManagedPropertyEvaluatorFactory managedPropertyEvaluatorFactory,
             IMultiplexer multiplexer,
-            IJythonEvaluatorPool jythonEvaluatorPool)
+            IJythonEvaluatorPool jythonEvaluatorPool,
+            EntityHistoryCreator historyCreator)
     {
         super(daoFactory, dssFactory, relationshipService, entityOperationChecker,
                 conversationClient, managedPropertyEvaluatorFactory, multiplexer);
         this.jythonEvaluatorPool = jythonEvaluatorPool;
+        this.historyCreator = historyCreator;
     }
 
     @Override
     public final IAttachmentBO createAttachmentBO(final Session session)
     {
-        return new AttachmentBO(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(), 
+        return new AttachmentBO(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker, relationshipService);
     }
 
     @Override
     public final ISpaceBO createSpaceBO(final Session session)
     {
-        return new SpaceBO(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(), 
+        return new SpaceBO(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker, relationshipService);
     }
 
     @Override
     public final IScriptBO createScriptBO(final Session session)
     {
-        return new ScriptBO(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(), 
+        return new ScriptBO(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker, relationshipService, jythonEvaluatorPool);
     }
 
@@ -142,7 +147,7 @@ public final class CommonBusinessObjectFactory extends AbstractBusinessObjectFac
     public final IRoleAssignmentTable createRoleAssignmentTable(final Session session)
     {
         return new RoleAssignmentTable(getDaoFactory(), session,
-                getManagedPropertyEvaluatorFactory(), dataSetTypeWithoutExperimentChecker, 
+                getManagedPropertyEvaluatorFactory(), dataSetTypeWithoutExperimentChecker,
                 relationshipService);
     }
 
@@ -191,7 +196,7 @@ public final class CommonBusinessObjectFactory extends AbstractBusinessObjectFac
     public final ISampleBO createSampleBO(final Session session)
     {
         return new SampleBO(getDaoFactory(), session, getRelationshipService(),
-                getEntityOperationChecker(), getManagedPropertyEvaluatorFactory(), 
+                getEntityOperationChecker(), getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker);
     }
 
@@ -199,7 +204,7 @@ public final class CommonBusinessObjectFactory extends AbstractBusinessObjectFac
     public IDataBO createDataBO(Session session)
     {
         return new DataBO(getDaoFactory(), session, getRelationshipService(),
-                getConversationClient(), getManagedPropertyEvaluatorFactory(), 
+                getConversationClient(), getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker);
     }
 
@@ -208,14 +213,14 @@ public final class CommonBusinessObjectFactory extends AbstractBusinessObjectFac
     {
         return new DataSetTable(getDaoFactory(), getDSSFactory(), session,
                 getRelationshipService(), getConversationClient(),
-                getManagedPropertyEvaluatorFactory(), getMultiplexer(), 
+                getManagedPropertyEvaluatorFactory(), getMultiplexer(),
                 dataSetTypeWithoutExperimentChecker);
     }
 
     @Override
     public ISearchDomainSearcher createSearchDomainSearcher(Session session)
     {
-        return new SearchDomainSearcher(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(), 
+        return new SearchDomainSearcher(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker, relationshipService, getDSSFactory());
     }
 
@@ -231,14 +236,14 @@ public final class CommonBusinessObjectFactory extends AbstractBusinessObjectFac
     public IExperimentTable createExperimentTable(final Session session)
     {
         return new ExperimentTable(getDaoFactory(), session, getRelationshipService(),
-                getManagedPropertyEvaluatorFactory(), 
+                getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker);
     }
 
     @Override
     public IMaterialTable createMaterialTable(final Session session)
     {
-        return new MaterialTable(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(), 
+        return new MaterialTable(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker, relationshipService);
     }
 
@@ -246,35 +251,35 @@ public final class CommonBusinessObjectFactory extends AbstractBusinessObjectFac
     public final IExperimentBO createExperimentBO(final Session session)
     {
         return new ExperimentBO(getDaoFactory(), session, getRelationshipService(),
-                getManagedPropertyEvaluatorFactory(), 
+                getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker);
     }
 
     @Override
     public final IPropertyTypeTable createPropertyTypeTable(final Session session)
     {
-        return new PropertyTypeTable(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(), 
+        return new PropertyTypeTable(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker, relationshipService);
     }
 
     @Override
     public final IPropertyTypeBO createPropertyTypeBO(final Session session)
     {
-        return new PropertyTypeBO(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(), 
+        return new PropertyTypeBO(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker, relationshipService);
     }
 
     @Override
     public final IVocabularyBO createVocabularyBO(Session session)
     {
-        return new VocabularyBO(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(), 
+        return new VocabularyBO(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker, relationshipService);
     }
 
     @Override
     public final IVocabularyTermBO createVocabularyTermBO(Session session)
     {
-        return new VocabularyTermBO(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(), 
+        return new VocabularyTermBO(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker, relationshipService);
     }
 
@@ -283,7 +288,7 @@ public final class CommonBusinessObjectFactory extends AbstractBusinessObjectFac
             EntityKind entityKind)
     {
         return new EntityTypePropertyTypeBO(getDaoFactory(), session, entityKind,
-                getManagedPropertyEvaluatorFactory(), 
+                getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker, relationshipService);
     }
 
@@ -291,29 +296,30 @@ public final class CommonBusinessObjectFactory extends AbstractBusinessObjectFac
     public IProjectBO createProjectBO(Session session)
     {
         return new ProjectBO(getDaoFactory(), session, getRelationshipService(),
-                getManagedPropertyEvaluatorFactory(), 
-                dataSetTypeWithoutExperimentChecker);
+                getManagedPropertyEvaluatorFactory(),
+                dataSetTypeWithoutExperimentChecker,
+                historyCreator);
     }
 
     @Override
     public IEntityTypeBO createEntityTypeBO(Session session)
     {
-        return new EntityTypeBO(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(), 
+        return new EntityTypeBO(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker, relationshipService);
     }
 
     @Override
     public IMaterialBO createMaterialBO(Session session)
     {
-        return new MaterialBO(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(), 
-                dataSetTypeWithoutExperimentChecker, relationshipService);
+        return new MaterialBO(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(),
+                dataSetTypeWithoutExperimentChecker, relationshipService, historyCreator);
     }
 
     @Override
     public IAuthorizationGroupBO createAuthorizationGroupBO(Session session)
     {
         return new AuthorizationGroupBO(getDaoFactory(), session,
-                getManagedPropertyEvaluatorFactory(), 
+                getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker, relationshipService);
     }
 
@@ -321,7 +327,7 @@ public final class CommonBusinessObjectFactory extends AbstractBusinessObjectFac
     public IGridCustomFilterOrColumnBO createGridCustomFilterBO(Session session)
     {
         return new GridCustomFilterBO(getDaoFactory(), session,
-                getManagedPropertyEvaluatorFactory(), 
+                getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker, relationshipService);
     }
 
@@ -329,21 +335,21 @@ public final class CommonBusinessObjectFactory extends AbstractBusinessObjectFac
     public IGridCustomFilterOrColumnBO createGridCustomColumnBO(Session session)
     {
         return new GridCustomColumnBO(getDaoFactory(), session,
-                getManagedPropertyEvaluatorFactory(), 
+                getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker, relationshipService);
     }
 
     @Override
     public ITrashBO createTrashBO(Session session)
     {
-        return new TrashBO(getDaoFactory(), this, session, getManagedPropertyEvaluatorFactory(), 
+        return new TrashBO(getDaoFactory(), this, session, getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker, relationshipService);
     }
 
     @Override
     public IDeletionTable createDeletionTable(Session session)
     {
-        return new DeletionTable(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(), 
+        return new DeletionTable(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker, relationshipService);
     }
 
@@ -352,7 +358,7 @@ public final class CommonBusinessObjectFactory extends AbstractBusinessObjectFac
             IMasterDataScriptRegistrationRunner masterDataScriptRunner)
     {
         return new CorePluginTable(getDaoFactory(), session, masterDataScriptRunner,
-                getManagedPropertyEvaluatorFactory(), 
+                getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker, relationshipService);
     }
 
@@ -367,7 +373,7 @@ public final class CommonBusinessObjectFactory extends AbstractBusinessObjectFac
     {
         return new MetaprojectBO(getDaoFactory(), createExperimentBO(session),
                 createSampleBO(session), createDataBO(session), createMaterialBO(session), session,
-                getManagedPropertyEvaluatorFactory(), 
+                getManagedPropertyEvaluatorFactory(),
                 dataSetTypeWithoutExperimentChecker, relationshipService);
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/MaterialBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/MaterialBO.java
index 742558549eed1151067ea614c2f5923f7b7723d9..18475d21bbd6c108860326fb819aa47c0cb4c850 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/MaterialBO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/MaterialBO.java
@@ -59,12 +59,15 @@ public final class MaterialBO extends AbstractMaterialBusinessObject implements
 
     private boolean dataChanged;
 
+    private EntityHistoryCreator historyCreator;
+
     public MaterialBO(final IDAOFactory daoFactory, final Session session,
             IManagedPropertyEvaluatorFactory managedPropertyEvaluatorFactory,
             DataSetTypeWithoutExperimentChecker dataSetTypeChecker,
-            IRelationshipService relationshipService)
+            IRelationshipService relationshipService, EntityHistoryCreator historyCreator)
     {
         super(daoFactory, session, managedPropertyEvaluatorFactory, dataSetTypeChecker, relationshipService);
+        this.historyCreator = historyCreator;
     }
 
     @Override
@@ -174,7 +177,7 @@ public final class MaterialBO extends AbstractMaterialBusinessObject implements
         try
         {
             String content =
-                    EntityHistoryCreator.apply(getSessionFactory().getCurrentSession(), Collections.singletonList(material.getId()),
+                    historyCreator.apply(getSessionFactory().getCurrentSession(), Collections.singletonList(material.getId()),
                             MaterialDAO.sqlPropertyHistory,
                             MaterialDAO.sqlRelationshipHistory);
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ProjectBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ProjectBO.java
index fc7f9d33ca23de0351b22f89873660e6f00979ef..40c3159ce9f26698da3d24a15005d8a16c64b488 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ProjectBO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ProjectBO.java
@@ -76,12 +76,15 @@ public final class ProjectBO extends AbstractBusinessObject implements IProjectB
 
     private final List<AttachmentPE> attachments = new ArrayList<AttachmentPE>();
 
+    private EntityHistoryCreator historyCreator;
+
     public ProjectBO(final IDAOFactory daoFactory, final Session session,
             IRelationshipService relationshipService,
             IManagedPropertyEvaluatorFactory managedPropertyEvaluatorFactory,
-            DataSetTypeWithoutExperimentChecker dataSetTypeChecker)
+            DataSetTypeWithoutExperimentChecker dataSetTypeChecker, EntityHistoryCreator historyCreator)
     {
         super(daoFactory, session, managedPropertyEvaluatorFactory, dataSetTypeChecker, relationshipService);
+        this.historyCreator = historyCreator;
     }
 
     private ProjectPE createProject(final ProjectIdentifier projectIdentifier, String description,
@@ -390,7 +393,7 @@ public final class ProjectBO extends AbstractBusinessObject implements IProjectB
             if (codes.isEmpty() && trashedCodes.isEmpty())
             {
                 String content =
-                        EntityHistoryCreator.apply(getSessionFactory().getCurrentSession(), Collections.singletonList(projectId.getId()),
+                        historyCreator.apply(getSessionFactory().getCurrentSession(), Collections.singletonList(projectId.getId()),
                                 propertyHistoryQuery,
                                 relationshipHistoryQuery);
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/AbstractGenericEntityWithPropertiesDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/AbstractGenericEntityWithPropertiesDAO.java
index dc8629ddc84f8d964df472867a905f7bb117bee8..d236b3b50566dbc2c5ef1bd8c7fd714f2e45dd2a 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/AbstractGenericEntityWithPropertiesDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/AbstractGenericEntityWithPropertiesDAO.java
@@ -71,11 +71,15 @@ public abstract class AbstractGenericEntityWithPropertiesDAO<T extends IEntityIn
 
     private final PersistencyResources persistencyResources;
 
+    protected EntityHistoryCreator historyCreator;
+
     protected AbstractGenericEntityWithPropertiesDAO(
-            final PersistencyResources persistencyResources, final Class<T> entityClass)
+            final PersistencyResources persistencyResources, final Class<T> entityClass,
+            final EntityHistoryCreator historyCreator)
     {
         super(persistencyResources.getSessionFactory(), entityClass);
         this.persistencyResources = persistencyResources;
+        this.historyCreator = historyCreator;
     }
 
     protected IFullTextIndexUpdateScheduler getIndexUpdateScheduler()
@@ -250,7 +254,7 @@ public abstract class AbstractGenericEntityWithPropertiesDAO<T extends IEntityIn
                     return null;
                 }
 
-                String content = EntityHistoryCreator.apply(session, entityIdsToDelete, sqlSelectPropertyHistory, sqlSelectRelationshipHistory);
+                String content = historyCreator.apply(session, entityIdsToDelete, sqlSelectPropertyHistory, sqlSelectRelationshipHistory);
 
                 deleteProperties(sqlQueryDeleteProperties, entityIdsToDelete);
                 deleteAttachmentsWithContents(sqlQuerySelectAttachmentContentIds,
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/AuthorizationDAOFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/AuthorizationDAOFactory.java
index fc571235ecfbe425d97ad9277b42ee4152d043ce..e15dab68f801e3a1dc15ba4362b021e3b47edf9f 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/AuthorizationDAOFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/AuthorizationDAOFactory.java
@@ -36,6 +36,7 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.IRoleAssignmentDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISampleDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISpaceDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.PersistencyResources;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.deletion.EntityHistoryCreator;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.search.IFullTextIndexUpdateScheduler;
 import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils;
 
@@ -78,7 +79,8 @@ public class AuthorizationDAOFactory implements IAuthorizationDAOFactory
     public AuthorizationDAOFactory(final DatabaseConfigurationContext context,
             final SessionFactory sessionFactory,
             final IFullTextIndexUpdateScheduler indexUpdateScheduler,
-            final IDynamicPropertyEvaluationScheduler dynamicPropertyEvaluationScheduler)
+            final IDynamicPropertyEvaluationScheduler dynamicPropertyEvaluationScheduler,
+            final EntityHistoryCreator historyCreator)
     {
         persistencyResources =
                 new PersistencyResources(context, sessionFactory, indexUpdateScheduler,
@@ -87,10 +89,10 @@ public class AuthorizationDAOFactory implements IAuthorizationDAOFactory
         groupDAO = new SpaceDAO(sessionFactory);
         roleAssignmentDAO = new RoleAssignmentDAO(sessionFactory);
         relationshipTypeDAO = new RelationshipTypeDAO(sessionFactory);
-        dataDAO = new DataDAO(persistencyResources, relationshipTypeDAO);
-        experimentDAO = new ExperimentDAO(persistencyResources);
+        dataDAO = new DataDAO(persistencyResources, relationshipTypeDAO, historyCreator);
+        experimentDAO = new ExperimentDAO(persistencyResources, historyCreator);
         projectDAO = new ProjectDAO(sessionFactory);
-        sampleDAO = new SampleDAO(persistencyResources);
+        sampleDAO = new SampleDAO(persistencyResources, historyCreator);
         gridCustomFilterDAO = new GridCustomFilterDAO(sessionFactory);
         gridCustomColumnDAO = new GridCustomColumnDAO(sessionFactory);
         queryDAO = new QueryDAO(sessionFactory);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DAOFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DAOFactory.java
index cddb6e71143115e851f5df903096947e159b8834..67fb180a09d763df6fbd3515753b2739a8c326f8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DAOFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DAOFactory.java
@@ -59,6 +59,7 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISampleTypeDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IScriptDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IVocabularyDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IVocabularyTermDAO;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.deletion.EntityHistoryCreator;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.search.HibernateSearchContext;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.search.IFullTextIndexUpdateScheduler;
 import ch.systemsx.cisd.openbis.generic.shared.Constants;
@@ -135,16 +136,20 @@ public final class DAOFactory extends AuthorizationDAOFactory implements IDAOFac
 
     private DatabaseConfigurationContext context;
 
+    private EntityHistoryCreator historyCreator;
+
     public DAOFactory(final DatabaseConfigurationContext context,
             final SessionFactory sessionFactory, HibernateSearchContext hibernateSearchContext,
             final IFullTextIndexUpdateScheduler fullTextIndexUpdateScheduler,
-            final IDynamicPropertyEvaluationScheduler dynamicPropertyEvaluationScheduler)
+            final IDynamicPropertyEvaluationScheduler dynamicPropertyEvaluationScheduler,
+            final EntityHistoryCreator historyCreator)
     {
         super(context, sessionFactory, fullTextIndexUpdateScheduler,
-                dynamicPropertyEvaluationScheduler);
+                dynamicPropertyEvaluationScheduler, historyCreator);
         this.context = context;
         this.dynamicPropertyEvaluationScheduler = dynamicPropertyEvaluationScheduler;
         this.fullTextIndexUpdateScheduler = fullTextIndexUpdateScheduler;
+        this.historyCreator = historyCreator;
         sampleTypeDAO = new SampleTypeDAO(sessionFactory);
         hibernateSearchDAO = new HibernateSearchDAO(sessionFactory, hibernateSearchContext);
         propertyTypeDAO = new PropertyTypeDAO(sessionFactory);
@@ -154,7 +159,7 @@ public final class DAOFactory extends AuthorizationDAOFactory implements IDAOFac
         dataSetTypeDAO = new DataSetTypeDAO(sessionFactory);
         fileFormatTypeDAO = new FileFormatTypeDAO(sessionFactory);
         locatorTypeDAO = new LocatorTypeDAO(sessionFactory);
-        materialDAO = new MaterialDAO(getPersistencyResources());
+        materialDAO = new MaterialDAO(getPersistencyResources(), historyCreator);
         codeSequenceDAO = new CodeSequenceDAO(sessionFactory);
         dataStoreDAO = new DataStoreDAO(sessionFactory);
         permIdDAO = new PermIdDAO(sessionFactory);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DataDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DataDAO.java
index dbfa751b71c832bd49af894108f2a629a92f6112..1060b04c19f327a3c204b12d807453b77cb2cb03 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DataDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DataDAO.java
@@ -105,9 +105,9 @@ final class DataDAO extends AbstractGenericEntityWithPropertiesDAO<DataPE>implem
 
     private IRelationshipTypeDAO relationshipTypeDAO;
 
-    DataDAO(final PersistencyResources persistencyResources, IRelationshipTypeDAO relationshipTypeDAO)
+    DataDAO(final PersistencyResources persistencyResources, IRelationshipTypeDAO relationshipTypeDAO, EntityHistoryCreator historyCreator)
     {
-        super(persistencyResources, ENTITY_CLASS);
+        super(persistencyResources, ENTITY_CLASS, historyCreator);
         this.relationshipTypeDAO = relationshipTypeDAO;
     }
 
@@ -1026,7 +1026,7 @@ final class DataDAO extends AbstractGenericEntityWithPropertiesDAO<DataPE>implem
                 final List<DeletedDataSetLocation> locations =
                         selectLocations(selectLocations, entityIdsToDelete);
 
-                String content = EntityHistoryCreator.apply(session, entityIdsToDelete, sqls.selectPropertyHistory, sqls.selectRelationshipHistory);
+                String content = historyCreator.apply(session, entityIdsToDelete, sqls.selectPropertyHistory, sqls.selectRelationshipHistory);
 
                 executeUpdate(deleteProperties, entityIdsToDelete);
                 executeUpdate(deleteExternalData, entityIdsToDelete);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/ExperimentDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/ExperimentDAO.java
index 78ab37a6c60a60711e539fcd2fda82ef6988df6e..714ab997794b668a167b408e0b7cb14e6b7d4dc5 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/ExperimentDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/ExperimentDAO.java
@@ -39,6 +39,7 @@ import ch.systemsx.cisd.openbis.generic.server.batch.BatchOperationExecutor;
 import ch.systemsx.cisd.openbis.generic.server.batch.IBatchOperation;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExperimentDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.PersistencyResources;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.deletion.EntityHistoryCreator;
 import ch.systemsx.cisd.openbis.generic.shared.basic.CodeConverter;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ColumnNames;
@@ -81,9 +82,9 @@ public class ExperimentDAO extends AbstractGenericEntityWithPropertiesDAO<Experi
 
     private final IExperimentSampleQuery experimentSampleQuery;
 
-    protected ExperimentDAO(final PersistencyResources persistencyResources)
+    protected ExperimentDAO(final PersistencyResources persistencyResources, EntityHistoryCreator historyCreator)
     {
-        super(persistencyResources, ExperimentPE.class);
+        super(persistencyResources, ExperimentPE.class, historyCreator);
         this.experimentSampleQuery = QueryTool.getManagedQuery(IExperimentSampleQuery.class);
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MaterialDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MaterialDAO.java
index 40a0fdb7e4014112eb4e8bcc8a427171a002dc2b..b74a65bd5d04a98f4a4dc14d80b455b8d09bb520 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MaterialDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MaterialDAO.java
@@ -79,9 +79,12 @@ public class MaterialDAO extends AbstractGenericEntityWithPropertiesDAO<Material
     private static final Pattern RELAXED_CODE_PATTERN = Pattern.compile("^[^\\s]+$",
             Pattern.CASE_INSENSITIVE);
 
-    protected MaterialDAO(final PersistencyResources persistencyResources)
+    private EntityHistoryCreator historyCreator;
+
+    protected MaterialDAO(final PersistencyResources persistencyResources, EntityHistoryCreator historyCreator)
     {
-        super(persistencyResources, ENTITY_CLASS);
+        super(persistencyResources, ENTITY_CLASS, historyCreator);
+        this.historyCreator = historyCreator;
     }
 
     @Override
@@ -303,7 +306,7 @@ public class MaterialDAO extends AbstractGenericEntityWithPropertiesDAO<Material
                             String materialTypeCode = (String) codeAndType[1];
                             String permId = MaterialPE.createPermId(materialCode, materialTypeCode);
 
-                            String content = EntityHistoryCreator.apply(session, Collections.singletonList(techId.getId()), sqlPropertyHistory,
+                            String content = historyCreator.apply(session, Collections.singletonList(techId.getId()), sqlPropertyHistory,
                                     sqlRelationshipHistory);
 
                             try
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SampleDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SampleDAO.java
index 1c259f10dbaa9d510f0b12d017b4e80dc161f4e1..fb231929c3e4bfb7f383b336347e2deace866617 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SampleDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SampleDAO.java
@@ -78,9 +78,9 @@ public class SampleDAO extends AbstractGenericEntityWithPropertiesDAO<SamplePE>i
     private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION,
             SampleDAO.class);
 
-    SampleDAO(final PersistencyResources persistencyResources)
+    SampleDAO(final PersistencyResources persistencyResources, EntityHistoryCreator historyCreator)
     {
-        super(persistencyResources, SamplePE.class);
+        super(persistencyResources, SamplePE.class, historyCreator);
     }
 
     // LockSampleModificationsInterceptor automatically obtains lock
@@ -554,7 +554,7 @@ public class SampleDAO extends AbstractGenericEntityWithPropertiesDAO<SamplePE>i
 
                     String permIds = permIdList.substring(2);
 
-                    String content = EntityHistoryCreator.apply(session, entityIdsToDelete, createQueryPropertyHistorySQL(),
+                    String content = historyCreator.apply(session, entityIdsToDelete, createQueryPropertyHistorySQL(),
                             createQueryRelationshipHistorySQL());
 
                     SQLQuery deleteProperties = session.createSQLQuery(properties);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/deletion/EntityHistoryCreator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/deletion/EntityHistoryCreator.java
index b8fe21dc93d44f05cabbbae30b6228edacc28f7a..ac1999c21677966b56671138168a0a2a95eb9889 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/deletion/EntityHistoryCreator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/deletion/EntityHistoryCreator.java
@@ -18,11 +18,29 @@ import com.fasterxml.jackson.databind.ObjectWriter;
 
 public class EntityHistoryCreator
 {
-    public static String apply(SharedSessionContract session,
+
+    private boolean enabled = false;
+
+    public void setEnabled(String s)
+    {
+        if (s != null && s.length() > 0 && s.equalsIgnoreCase("true"))
+        {
+            enabled = true;
+        } else
+        {
+            enabled = false;
+        }
+    }
+
+    public String apply(SharedSessionContract session,
             List<Long> entityIdsToDelete,
             String propertyHistoryQuery,
             String relationshipHistoryQuery)
     {
+        if (!enabled)
+        {
+            return "";
+        }
         Map<String, List<EntityModification>> histories = new HashMap<String, List<EntityModification>>();
 
         List<PropertyHistoryEntry> propertyHistory =
@@ -62,7 +80,7 @@ public class EntityHistoryCreator
         return content;
     }
 
-    private static void addToHistories(String permId, Map<String, List<EntityModification>> histories, EntityModification modification)
+    private void addToHistories(String permId, Map<String, List<EntityModification>> histories, EntityModification modification)
     {
         List<EntityModification> current = histories.get(permId);
         if (current == null)
@@ -72,7 +90,7 @@ public class EntityHistoryCreator
         histories.put(permId, addModification(current, modification));
     }
 
-    public static List<EntityModification> addModification(List<EntityModification> current, EntityModification modification)
+    private List<EntityModification> addModification(List<EntityModification> current, EntityModification modification)
     {
         List<EntityModification> list = new ArrayList<>(current);
         list.add(modification);
@@ -87,7 +105,7 @@ public class EntityHistoryCreator
         return Collections.unmodifiableList(list);
     }
 
-    private static List<PropertyHistoryEntry> selectHistoryPropertyEntries(
+    private List<PropertyHistoryEntry> selectHistoryPropertyEntries(
             final SQLQuery selectPropertyHistory, final List<Long> entityIds)
     {
         selectPropertyHistory.setParameterList("entityIds", entityIds);
@@ -121,7 +139,7 @@ public class EntityHistoryCreator
         return cast(selectPropertyHistory.list());
     }
 
-    private static List<RelationshipHistoryEntry> selectRelationshipHistoryEntries(final SQLQuery selectRelationshipHistory,
+    private List<RelationshipHistoryEntry> selectRelationshipHistoryEntries(final SQLQuery selectRelationshipHistory,
             final List<Long> entityIds)
     {
         selectRelationshipHistory.setParameterList("entityIds", entityIds);
@@ -154,7 +172,7 @@ public class EntityHistoryCreator
     }
 
     @SuppressWarnings("unchecked")
-    protected static final <T> List<T> cast(final List<?> list)
+    protected final <T> List<T> cast(final List<?> list)
     {
         return (List<T>) list;
     }
diff --git a/openbis/source/java/genericApplicationContext.xml b/openbis/source/java/genericApplicationContext.xml
index aa68cfc6ba60ab42e5acc507d15bc2be04462ea0..870bcbe558b7f3c63e2c3b1609cd0ad92f05a5f1 100644
--- a/openbis/source/java/genericApplicationContext.xml
+++ b/openbis/source/java/genericApplicationContext.xml
@@ -112,6 +112,7 @@
 		<constructor-arg ref="hibernate-search-context" />
 		<constructor-arg ref="full-text-index-updater" />
 		<constructor-arg ref="dynamic-property-scheduler" />
+		<constructor-arg ref="entity-history-creator" />
 	</bean>
 
 	<bean id="dss-factory"
@@ -158,6 +159,12 @@
 		<constructor-arg value="${accepted-remote-hosts-for-identity-change}" />
 	</bean>
 
+        
+    <bean id="entity-history-creator"
+        class="ch.systemsx.cisd.openbis.generic.server.dataaccess.db.deletion.EntityHistoryCreator">
+        <property name="enabled" value="${entity-history.enabled}"/>
+    </bean>
+
 	<bean id="common-business-object-factory"
 		class="ch.systemsx.cisd.openbis.generic.server.CommonBusinessObjectFactory">
 		<constructor-arg ref="dao-factory" />
@@ -168,6 +175,7 @@
 		<constructor-arg ref="managed-property-evaluator-factory" />
 		<constructor-arg ref="multiplexer" />
 		<constructor-arg ref="jython-evaluator-pool" />
+		<constructor-arg ref="entity-history-creator" />
 	</bean>
 
 	<bean id="last-modification-state"
diff --git a/openbis/source/java/service.properties b/openbis/source/java/service.properties
index 0df5811a82924ed7258168eb09dc61b5b6f186f4..8827f3a7dcc6087d204f0a9f3b4f48a3d135e841 100644
--- a/openbis/source/java/service.properties
+++ b/openbis/source/java/service.properties
@@ -167,3 +167,5 @@ demo.property_2 = some value 2
 
 # Name of the file that stores Web Client configuration
 web-client-configuration-file = etc/web-client.properties
+
+entity-history.enabled = true
\ No newline at end of file
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/Change.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/Change.java
similarity index 94%
rename from openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/Change.java
rename to openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/Change.java
index 6fde494579471428f809babb3cab5d14a7cdec20..ff66ef13b7151a0f1ed9da73150fc18f765a4a16 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/Change.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/Change.java
@@ -1,4 +1,4 @@
-package ch.ethz.sis.openbis.systemtest.asapi.v3;
+package ch.ethz.sis.openbis.systemtest.deletion;
 
 import java.util.Date;
 
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/DataSetDeletionTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/DataSetDeletionTest.java
similarity index 99%
rename from openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/DataSetDeletionTest.java
rename to openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/DataSetDeletionTest.java
index d16a6d8b0050ffe5720df832dd3645b23a8cc6ec..f51d74b0890584575a45c4bb2972b33a7bb461b4 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/DataSetDeletionTest.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/DataSetDeletionTest.java
@@ -1,4 +1,4 @@
-package ch.ethz.sis.openbis.systemtest.asapi.v3;
+package ch.ethz.sis.openbis.systemtest.deletion;
 
 import java.util.Arrays;
 
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/DeletionTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/DeletionTest.java
similarity index 99%
rename from openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/DeletionTest.java
rename to openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/DeletionTest.java
index 96da00d9082e2edbb50a23fde8112909bbc9ba2b..1cd9c80d0915c173a66e1a88225f379f0c119b1c 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/DeletionTest.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/DeletionTest.java
@@ -1,4 +1,4 @@
-package ch.ethz.sis.openbis.systemtest.asapi.v3;
+package ch.ethz.sis.openbis.systemtest.deletion;
 
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -61,6 +61,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.create.SpaceCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.delete.SpaceDeletionOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.ISpaceId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.SpacePermId;
+import ch.ethz.sis.openbis.systemtest.asapi.v3.AbstractTest;
 import ch.systemsx.cisd.openbis.generic.shared.dto.EventPE;
 
 public abstract class DeletionTest extends AbstractTest
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/ExperimentDeletionTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/ExperimentDeletionTest.java
similarity index 98%
rename from openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/ExperimentDeletionTest.java
rename to openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/ExperimentDeletionTest.java
index d72b91755421776019f537e10e8e7b0d2487c142..458b6e620e9c0b3e14cc5948f93e6649315452f6 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/ExperimentDeletionTest.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/ExperimentDeletionTest.java
@@ -1,4 +1,4 @@
-package ch.ethz.sis.openbis.systemtest.asapi.v3;
+package ch.ethz.sis.openbis.systemtest.deletion;
 
 import java.util.Arrays;
 
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/MaterialDeletionTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/MaterialDeletionTest.java
similarity index 95%
rename from openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/MaterialDeletionTest.java
rename to openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/MaterialDeletionTest.java
index 09f9c118110e23a180ce22cb45983479da001524..12a4f0d6069fec59219c7477cc0067cfdfb74588 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/MaterialDeletionTest.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/MaterialDeletionTest.java
@@ -1,4 +1,4 @@
-package ch.ethz.sis.openbis.systemtest.asapi.v3;
+package ch.ethz.sis.openbis.systemtest.deletion;
 
 import org.springframework.test.annotation.Rollback;
 import org.testng.annotations.Test;
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/ProjectDeletionTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/ProjectDeletionTest.java
similarity index 97%
rename from openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/ProjectDeletionTest.java
rename to openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/ProjectDeletionTest.java
index eab1422225b1b0d23c85c44a0b8a3a7377a5f547..b9029bad0f5edbf59578c1de9df15c3e44f5c140 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/ProjectDeletionTest.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/ProjectDeletionTest.java
@@ -1,4 +1,4 @@
-package ch.ethz.sis.openbis.systemtest.asapi.v3;
+package ch.ethz.sis.openbis.systemtest.deletion;
 
 import java.util.Arrays;
 
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/SampleDeletionTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/SampleDeletionTest.java
similarity index 99%
rename from openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/SampleDeletionTest.java
rename to openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/SampleDeletionTest.java
index 20224db99d5bc14104b431e9699d09f2fe41b5d4..aa2aef6c98ee50cbd6c8bea476e5befe2ef81d59 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/SampleDeletionTest.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/deletion/SampleDeletionTest.java
@@ -1,4 +1,4 @@
-package ch.ethz.sis.openbis.systemtest.asapi.v3;
+package ch.ethz.sis.openbis.systemtest.deletion;
 
 import java.util.Arrays;
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ProjectBOTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ProjectBOTest.java
index dea4a1aeaa9462e19222225ee193e06136447f7a..767d707786ed51ae8d3c3af3736b7503ca1b8160 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ProjectBOTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ProjectBOTest.java
@@ -31,6 +31,7 @@ import ch.rinn.restrictions.Friend;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.common.test.RecordingMatcher;
 import ch.systemsx.cisd.openbis.generic.server.business.ManagerTestTool;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.deletion.EntityHistoryCreator;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DeletedExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DeletionPE;
@@ -55,7 +56,7 @@ public final class ProjectBOTest extends AbstractBOTest
     private final ProjectBO createProjectBO()
     {
         return new ProjectBO(daoFactory, ManagerTestTool.EXAMPLE_SESSION, relationshipService,
-                managedPropertyEvaluatorFactory, null);
+                managedPropertyEvaluatorFactory, null, new EntityHistoryCreator());
     }
 
     @Test