diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/IDataSetRegistrationTransaction.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/IDataSetRegistrationTransaction.java
index c6bfe9300c0584a6968a973811f9708ec697788b..34e9361a187834927da707f2580da9ba90abfb5f 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/IDataSetRegistrationTransaction.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/IDataSetRegistrationTransaction.java
@@ -127,6 +127,13 @@ public interface IDataSetRegistrationTransaction
      */
     IExperimentUpdatable getExperimentForUpdate(String experimentIdentifierString);
 
+    /**
+     * Given an immutable experiment, make it mutable.
+     * 
+     * @return An experiment
+     */
+    IExperimentUpdatable makeExperimentMutable(IExperimentImmutable experiment);
+
     /**
      * Create a new experiment to register with the openBIS AS. The experiment will have a permId.
      * 
@@ -180,6 +187,13 @@ public interface IDataSetRegistrationTransaction
      */
     IMaterial getMaterialForUpdate(String materialCode, String materialType);
 
+    /**
+     * Given an immutable material, make it mutable.
+     * 
+     * @return A material
+     */
+    IMaterial makeMaterialMutable(IMaterialImmutable material);
+
     /**
      * Create a new material to register with the openBIS AS.
      * 
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AbstractTransactionState.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AbstractTransactionState.java
index 298aa16be4a53d28fe1fb4c5b74c5f01adaec112..783a49a5c1ea2c2458f15e51dcb86f80b639c305 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AbstractTransactionState.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AbstractTransactionState.java
@@ -50,6 +50,7 @@ import ch.systemsx.cisd.etlserver.registrator.api.v1.impl.RollbackStack.IRollbac
 import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.IDataSetImmutable;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.IExperimentImmutable;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.IMaterialImmutable;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.ISampleImmutable;
 import ch.systemsx.cisd.openbis.dss.generic.shared.dto.AtomicEntityOperationDetails;
 import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation;
@@ -565,6 +566,42 @@ public abstract class AbstractTransactionState<T extends DataSetInformation>
             return result;
         }
 
+        public IExperimentUpdatable makeExperimentMutable(IExperimentImmutable experiment)
+        {
+            if (experiment == null)
+            {
+                return null;
+            }
+            // Check if we already have an updatable experiment for this one
+            ExperimentUpdatable result = findExperimentLocally(experiment);
+            if (result != null)
+            {
+                return result;
+            }
+
+            if (experiment instanceof ExperimentImmutable)
+            {
+                result =
+                        new ExperimentUpdatable(((ExperimentImmutable) experiment).getExperiment());
+                experimentsToBeUpdated.add(result);
+                return result;
+            }
+
+            return null;
+        }
+
+        private ExperimentUpdatable findExperimentLocally(IExperimentImmutable experimentToFind)
+        {
+            for (ExperimentUpdatable experiment : experimentsToBeUpdated)
+            {
+                if (experiment.equals(experimentToFind))
+                {
+                    return experiment;
+                }
+            }
+            return null;
+        }
+
         public IExperiment createNewExperiment(String experimentIdentifierString,
                 String experimentTypeCode)
         {
@@ -614,6 +651,41 @@ public abstract class AbstractTransactionState<T extends DataSetInformation>
             return result;
         }
 
+        public IMaterial makeMaterialMutable(IMaterialImmutable material)
+        {
+            if (material == null)
+            {
+                return null;
+            }
+            // Check if we already have an updatable material for this one
+            Material result = findMaterialLocally(material);
+            if (result != null)
+            {
+                return result;
+            }
+
+            if (material instanceof MaterialImmutable)
+            {
+                result = new Material(((MaterialImmutable) material).getMaterial());
+                materialsToBeUpdated.add(result);
+                return result;
+            }
+
+            return null;
+        }
+
+        private Material findMaterialLocally(IMaterialImmutable materialToFind)
+        {
+            for (Material material : materialsToBeUpdated)
+            {
+                if (material.equals(materialToFind))
+                {
+                    return material;
+                }
+            }
+            return null;
+        }
+
         public String moveFile(String src, IDataSet dst)
         {
             File srcFile = new File(src);
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransaction.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransaction.java
index 790be226001ad868a38110152e81e773ad9cfea3..1cfa30c57d9ddcb9c0d305221fb4df9fc70f82d4 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransaction.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransaction.java
@@ -318,6 +318,12 @@ public class DataSetRegistrationTransaction<T extends DataSetInformation> implem
         return getStateAsLiveState().getExperimentForUpdate(experimentIdentifierString);
     }
 
+    @Override
+    public IExperimentUpdatable makeExperimentMutable(IExperimentImmutable experiment)
+    {
+        return getStateAsLiveState().makeExperimentMutable(experiment);
+    }
+
     @Override
     public ISample createNewSample(String sampleIdentifierString, String sampleTypeCode)
     {
@@ -388,6 +394,12 @@ public class DataSetRegistrationTransaction<T extends DataSetInformation> implem
         return getStateAsLiveState().getMaterialForUpdate(materialCode, materialType);
     }
 
+    @Override
+    public IMaterial makeMaterialMutable(IMaterialImmutable material)
+    {
+        return getStateAsLiveState().makeMaterialMutable(material);
+    }
+
     @Override
     public IMaterial createNewMaterial(String materialCode, String materialType)
     {
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/DataSetRegistrationTransactionV2Delegate.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/DataSetRegistrationTransactionV2Delegate.java
index 0513d8e6d5a3fbc773a3e2da856478388cae61e5..004ea32cf2f5641b75f05900aa3154dbb15c91f0 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/DataSetRegistrationTransactionV2Delegate.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/DataSetRegistrationTransactionV2Delegate.java
@@ -125,6 +125,12 @@ public class DataSetRegistrationTransactionV2Delegate implements IDataSetRegistr
         return transaction.getExperimentForUpdate(experimentIdentifierString);
     }
 
+    @Override
+    public IExperimentUpdatable makeExperimentMutable(IExperimentImmutable experiment)
+    {
+        return transaction.makeExperimentMutable(experiment);
+    }
+
     @Override
     public IExperiment createNewExperiment(String experimentIdentifierString,
             String experimentTypeCode)
@@ -168,6 +174,12 @@ public class DataSetRegistrationTransactionV2Delegate implements IDataSetRegistr
         return transaction.getMaterialForUpdate(materialCode, materialType);
     }
 
+    @Override
+    public IMaterial makeMaterialMutable(IMaterialImmutable material)
+    {
+        return transaction.makeMaterialMutable(material);
+    }
+
     @Override
     public IMaterial createNewMaterial(String materialCode, String materialType)
     {
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/IDataSetRegistrationTransactionV2.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/IDataSetRegistrationTransactionV2.java
index 129d065abffe39bbb390792f71bd178a5966befd..3607b9be1676021c9539134988c5fa2350639bfd 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/IDataSetRegistrationTransactionV2.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/IDataSetRegistrationTransactionV2.java
@@ -124,6 +124,13 @@ public interface IDataSetRegistrationTransactionV2
      */
     IExperimentUpdatable getExperimentForUpdate(String experimentIdentifierString);
 
+    /**
+     * Given an immutable experiment, make it mutable.
+     * 
+     * @return An experiment
+     */
+    IExperimentUpdatable makeExperimentMutable(IExperimentImmutable experiment);
+
     /**
      * Create a new experiment to register with the openBIS AS. The experiment will have a permId.
      * 
@@ -176,6 +183,13 @@ public interface IDataSetRegistrationTransactionV2
      */
     IMaterial getMaterialForUpdate(String materialCode, String materialType);
 
+    /**
+     * Given an immutable material, make it mutable.
+     * 
+     * @return A material
+     */
+    IMaterial makeMaterialMutable(IMaterialImmutable material);
+
     /**
      * Create a new material to register with the openBIS AS.
      *