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 23b4a08239eeb1a0d8a80c138bb6e5209b9a1367..df290b3c73e441fb08fdce36daace60f68b381ba 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
@@ -80,6 +80,7 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.samplelister.ISampleL
 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.jython.api.v1.impl.IMasterDataScriptRegistrationRunner;
+import ch.systemsx.cisd.openbis.generic.shared.IRelationshipService;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
 import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
 
@@ -92,9 +93,13 @@ public final class CommonBusinessObjectFactory extends AbstractBusinessObjectFac
         ICommonBusinessObjectFactory
 {
 
-    public CommonBusinessObjectFactory(IDAOFactory daoFactory, IDataStoreServiceFactory dssFactory)
+    private IRelationshipService relationshipService;
+
+    public CommonBusinessObjectFactory(IDAOFactory daoFactory, IDataStoreServiceFactory dssFactory,
+            IRelationshipService relationshipService)
     {
         super(daoFactory, dssFactory);
+        this.relationshipService = relationshipService;
     }
 
     @Override
@@ -172,7 +177,7 @@ public final class CommonBusinessObjectFactory extends AbstractBusinessObjectFac
     @Override
     public IExperimentTable createExperimentTable(final Session session)
     {
-        return new ExperimentTable(getDaoFactory(), session);
+        return new ExperimentTable(getDaoFactory(), session, relationshipService);
     }
 
     @Override
@@ -184,7 +189,7 @@ public final class CommonBusinessObjectFactory extends AbstractBusinessObjectFac
     @Override
     public final IExperimentBO createExperimentBO(final Session session)
     {
-        return new ExperimentBO(getDaoFactory(), session);
+        return new ExperimentBO(getDaoFactory(), session, relationshipService);
     }
 
     @Override
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/RelationshipService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/RelationshipService.java
new file mode 100644
index 0000000000000000000000000000000000000000..b04ec072d8e15ebbf4a3203661fc97504059a4ef
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/RelationshipService.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.server;
+
+import org.hibernate.Criteria;
+import org.hibernate.criterion.Restrictions;
+
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.util.SampleUtils;
+import ch.systemsx.cisd.openbis.generic.shared.IRelationshipService;
+import ch.systemsx.cisd.openbis.generic.shared.basic.CodeConverter;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.IAuthSession;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier;
+
+/**
+ * The unique {@link IRelationshipService} implementation.
+ * 
+ * @author anttil
+ */
+public class RelationshipService implements IRelationshipService
+{
+    private static final String ERR_PROJECT_NOT_FOUND =
+            "No project for experiment '%s' could be found in the database.";
+
+    private org.hibernate.SessionFactory sessionFactory;
+
+    @Override
+    public void reassignProject(IAuthSession session, ProjectIdentifier projectId,
+            ExperimentIdentifier experimentId)
+    {
+        ProjectPE project = findProject(projectId);
+        ExperimentPE experiment = findExperiment(experimentId);
+        ProjectPE previousProject = experiment.getProject();
+        if (project.equals(previousProject))
+        {
+            return;
+        }
+        // if the group has changes, move all samples to that group
+        if (project.getSpace().equals(previousProject.getSpace()) == false)
+        {
+            SampleUtils.setSamplesGroup(experiment, project.getSpace());
+        }
+        experiment.setProject(project);
+    }
+
+    private ProjectPE findProject(ProjectIdentifier id)
+    {
+
+        final Criteria criteria =
+                this.sessionFactory.getCurrentSession().createCriteria(ProjectPE.class);
+        criteria.add(Restrictions.eq("code", CodeConverter.tryToDatabase(id.getProjectCode())));
+        final Criteria spaceCriteria = criteria.createCriteria("space");
+        spaceCriteria.add(Restrictions.eq("code", CodeConverter.tryToDatabase(id.getSpaceCode())));
+
+        ProjectPE project = (ProjectPE) criteria.uniqueResult();
+        if (project == null)
+        {
+            throw UserFailureException.fromTemplate(ERR_PROJECT_NOT_FOUND, id);
+        }
+        return project;
+    }
+
+    private ExperimentPE findExperiment(ExperimentIdentifier id)
+    {
+        final Criteria criteria =
+                this.sessionFactory.getCurrentSession().createCriteria(ExperimentPE.class);
+        criteria.add(Restrictions.eq("code", CodeConverter.tryToDatabase(id.getExperimentCode())));
+        return (ExperimentPE) criteria.uniqueResult();
+    }
+
+    public void setSessionFactory(org.hibernate.SessionFactory sessionFactory)
+    {
+        this.sessionFactory = sessionFactory;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentBO.java
index 052b7caf0718db623d9a765548a02af2c4289709..f4fddf977c2810ff09818b550d4c405e57f8f6d0 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentBO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentBO.java
@@ -32,6 +32,7 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.util.SampleUtils;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAttachmentDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISampleDAO;
+import ch.systemsx.cisd.openbis.generic.shared.IRelationshipService;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Code;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
@@ -81,9 +82,13 @@ public final class ExperimentBO extends AbstractBusinessObject implements IExper
 
     private final List<AttachmentPE> attachments = new ArrayList<AttachmentPE>();
 
-    public ExperimentBO(final IDAOFactory daoFactory, final Session session)
+    private IRelationshipService relationshipService;
+
+    public ExperimentBO(final IDAOFactory daoFactory, final Session session,
+            IRelationshipService relationshipService)
     {
         super(daoFactory, session, EntityKind.EXPERIMENT);
+        this.relationshipService = relationshipService;
     }
 
     ExperimentBO(final IDAOFactory daoFactory, final Session session,
@@ -416,7 +421,15 @@ public final class ExperimentBO extends AbstractBusinessObject implements IExper
             throwModifiedEntityException("Experiment");
         }
         updateProperties(updates.getProperties());
-        updateProject(updates.getProjectIdentifier());
+
+        if (updates.getProjectIdentifier().getProjectCode().equals(
+                experiment.getProject().getCode()) == false)
+        {
+            relationshipService.reassignProject(session, updates.getProjectIdentifier(),
+                    new ExperimentIdentifier(updates.getProjectIdentifier(), experiment
+                            .getCode()));
+        }
+
         for (NewAttachment attachment : updates.getAttachments())
         {
             addAttachment(AttachmentTranslator.translate(attachment));
@@ -548,9 +561,6 @@ public final class ExperimentBO extends AbstractBusinessObject implements IExper
         return new HashSet<String>(Arrays.asList(objects));
     }
 
-    /**
-     * See also {@link ExperimentTable#updateProject}.
-     */
     @Private
     void updateProject(ProjectIdentifier newProjectIdentifier)
     {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentTable.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentTable.java
index 96012618fad60b466278b5e6a47df2b73be220d1..d6c2125d0fa72f4249c0649e8dbbacc70ea30050 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentTable.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentTable.java
@@ -27,9 +27,9 @@ import java.util.Set;
 import org.springframework.dao.DataAccessException;
 
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.util.SampleUtils;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExperimentDAO;
+import ch.systemsx.cisd.openbis.generic.shared.IRelationshipService;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentBatchUpdateDetails;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
@@ -61,15 +61,19 @@ public final class ExperimentTable extends AbstractBusinessObject implements IEx
 
     private boolean dataChanged = false;
 
+    private IRelationshipService relationshipService;
+
     ExperimentTable(final IDAOFactory daoFactory, final Session session,
             IEntityPropertiesConverter converter)
     {
         super(daoFactory, session, converter);
     }
 
-    public ExperimentTable(final IDAOFactory daoFactory, final Session session)
+    public ExperimentTable(final IDAOFactory daoFactory, final Session session,
+            IRelationshipService relationshipService)
     {
         super(daoFactory, session, EntityKind.EXPERIMENT);
+        this.relationshipService = relationshipService;
     }
 
     //
@@ -245,39 +249,11 @@ public final class ExperimentTable extends AbstractBusinessObject implements IEx
 
         if (updates.isProjectUpdateRequested())
         {
-            updateProject(experiment, updates);
-        }
-    }
-
-    /**
-     * Modeled after {@link ExperimentBO#updateProject(SpaceIdentifier)}
-     */
-    private void updateProject(ExperimentPE experiment, ExperimentBatchUpdatesDTO updates)
-    {
-        ProjectPE project = findProject(updates.getProjectIdentifier());
-        ProjectPE previousProject = experiment.getProject();
-        if (project.equals(previousProject))
-        {
-            return; // nothing to change
-        }
-        // if the group has changes, move all samples to that group
-        if (project.getSpace().equals(previousProject.getSpace()) == false)
-        {
-            SampleUtils.setSamplesGroup(experiment, project.getSpace());
-        }
-        experiment.setProject(project);
-    }
-
-    private ProjectPE findProject(ProjectIdentifier newProjectIdentifier)
-    {
-        ProjectPE project =
-                getProjectDAO().tryFindProject(newProjectIdentifier.getDatabaseInstanceCode(),
-                        newProjectIdentifier.getSpaceCode(), newProjectIdentifier.getProjectCode());
-        if (project == null)
-        {
-            throw UserFailureException.fromTemplate(ERR_PROJECT_NOT_FOUND, newProjectIdentifier);
+            relationshipService
+                    .reassignProject(session, updates.getProjectIdentifier(),
+                            new ExperimentIdentifier(updates.getProjectIdentifier(), experiment
+                                    .getCode()));
         }
-        return project;
     }
 
     private void batchUpdateProperties(ExperimentPE experiment, List<IEntityProperty> properties,
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IRelationshipService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IRelationshipService.java
new file mode 100644
index 0000000000000000000000000000000000000000..e708b377061869f4a5a667cdd8823de91c72e75c
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IRelationshipService.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared;
+
+import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.Capability;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.RolesAllowed;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
+import ch.systemsx.cisd.openbis.generic.shared.dto.IAuthSession;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier;
+
+/**
+ * Definition of an internal service through which entity relationships can be changed and deleted.
+ * All the methods of this service require authorization,
+ * 
+ * @author anttil
+ */
+public interface IRelationshipService
+{
+    @RolesAllowed(RoleWithHierarchy.SPACE_ADMIN)
+    @Capability("REASSIGN_PROJECT")
+    public void reassignProject(IAuthSession session, ProjectIdentifier project,
+            ExperimentIdentifier experiment);
+
+}
diff --git a/openbis/source/java/genericApplicationContext.xml b/openbis/source/java/genericApplicationContext.xml
index 50efc3aa84674af5e70b9ff28e03d750b2c3023b..964d9af14118052a7efaa3d136c2c01f260915ec 100644
--- a/openbis/source/java/genericApplicationContext.xml
+++ b/openbis/source/java/genericApplicationContext.xml
@@ -22,6 +22,11 @@
         <property name="sessionFactory" ref="hibernate-session-factory" />
         <property name="jdbcExceptionTranslator" ref="exception-translator" />
     </bean>
+    
+    <bean id="relationship-service"
+        class="ch.systemsx.cisd.openbis.generic.server.RelationshipService">
+        <property name="sessionFactory" ref="hibernate-session-factory" />
+    </bean>
 
     <bean id="sql-script-provider" class="ch.systemsx.cisd.dbmigration.DBMigrationEngine"
         factory-method="createOrMigrateDatabaseAndGetScriptProvider">
@@ -76,6 +81,7 @@
         class="ch.systemsx.cisd.openbis.generic.server.CommonBusinessObjectFactory">
         <constructor-arg ref="dao-factory" />
         <constructor-arg ref="dss-factory" />
+        <constructor-arg ref="relationship-service" />
     </bean>
 
     <bean id="last-modification-state"
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBOTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBOTest.java
index 8d5fbee324383957eddd83abd68b83bb20af8124..173aa4f45d9f7b6c10fce94465575941a80dfbd0 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBOTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBOTest.java
@@ -53,6 +53,7 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISpaceDAO;
 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.IPermIdDAO;
+import ch.systemsx.cisd.openbis.generic.shared.IRelationshipService;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
 
 /**
@@ -123,6 +124,8 @@ public abstract class AbstractBOTest extends AssertJUnit
 
     protected ICorePluginDAO corePluginDAO;
 
+    protected IRelationshipService relationshipService;
+
     @BeforeMethod
     public void beforeMethod()
     {
@@ -156,6 +159,7 @@ public abstract class AbstractBOTest extends AssertJUnit
         scriptDAO = context.mock(IScriptDAO.class);
         deletionDAO = context.mock(IDeletionDAO.class);
         corePluginDAO = context.mock(ICorePluginDAO.class);
+        relationshipService = context.mock(IRelationshipService.class);
         context.checking(new Expectations()
             {
                 {
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentBOTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentBOTest.java
index 974055313a6e8cdad5fae8b5880352302b07f3bd..3c8fe8aa30075060d99430f8dfa86bf72fd0d5be 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentBOTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ExperimentBOTest.java
@@ -81,7 +81,7 @@ public final class ExperimentBOTest extends AbstractBOTest
 
     private final ExperimentBO createExperimentBO()
     {
-        return new ExperimentBO(daoFactory, ManagerTestTool.EXAMPLE_SESSION);
+        return new ExperimentBO(daoFactory, ManagerTestTool.EXAMPLE_SESSION, relationshipService);
     }
 
     @Test
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/RelationshipServiceTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/RelationshipServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..af042b5754353ffc96ac876033629d5ebb056fa8
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/RelationshipServiceTest.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2009 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.systemtest;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.util.ArrayList;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Grantee;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAttachment;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSamplesWithTypes;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentUpdatesDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SessionContextDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
+
+/**
+ * @author anttil
+ */
+@Test(groups = "system test")
+public class RelationshipServiceTest extends SystemTestCase
+{
+    @BeforeMethod
+    public void createUsers()
+    {
+        SessionContextDTO systemUser = commonServer.tryToAuthenticateAsSystem();
+        commonServer.registerPerson(systemUser.getSessionToken(), "basic");
+        commonServer.registerSpaceRole(systemUser.getSessionToken(), RoleCode.USER,
+                new SpaceIdentifier("CISD", "CISD"), Grantee.createPerson("basic"));
+
+        commonServer.registerPerson(systemUser.getSessionToken(), "power");
+        commonServer.registerSpaceRole(systemUser.getSessionToken(), RoleCode.POWER_USER,
+                new SpaceIdentifier("CISD", "CISD"), Grantee.createPerson("power"));
+
+        commonServer.registerPerson(systemUser.getSessionToken(), "admin");
+        commonServer.registerSpaceRole(systemUser.getSessionToken(), RoleCode.ADMIN,
+                new SpaceIdentifier("CISD", "CISD"), Grantee.createPerson("admin"));
+
+        commonServer.registerPerson(systemUser.getSessionToken(), "instance_admin");
+        commonServer.registerInstanceRole(systemUser.getSessionToken(), RoleCode.ADMIN, Grantee
+                .createPerson("instance_admin"));
+
+    }
+
+    @Test(expectedExceptions =
+        { AuthorizationFailureException.class })
+    public void basicUserIsNotAllowedToUpdateExperienceProjectRelationship()
+    {
+        SessionContextDTO basicUser = commonServer.tryToAuthenticate("basic", "password");
+        ExperimentUpdatesDTO updates = getProjectUpdate(basicUser);
+        commonServer.updateExperiment(basicUser.getSessionToken(), updates);
+    }
+
+    @Test(expectedExceptions =
+        { AuthorizationFailureException.class })
+    public void powerUserIsNotAllowedToUpdateExperienceProjectRelationship()
+    {
+        SessionContextDTO powerUser = commonServer.tryToAuthenticate("power", "password");
+        ExperimentUpdatesDTO updates = getProjectUpdate(powerUser);
+        commonServer.updateExperiment(powerUser.getSessionToken(), updates);
+    }
+
+    @Test
+    public void spaceAdminIsAllowedToUpdateExperienceProjectRelationship()
+    {
+        SessionContextDTO adminUser = commonServer.tryToAuthenticate("admin", "password");
+        ExperimentUpdatesDTO updates = getProjectUpdate(adminUser);
+        commonServer.updateExperiment(adminUser.getSessionToken(), updates);
+
+        Experiment experiment =
+                commonServer.getExperimentInfo(adminUser.getSessionToken(),
+                        new ExperimentIdentifier(
+                                "CISD", "CISD", "DEFAULT", "EXP1"));
+        assertThat(experiment.getProject().getCode(), is("DEFAULT"));
+    }
+
+    @Test
+    public void instanceAdminIsAllowedToUpdateExperienceProjectRelationship()
+    {
+        SessionContextDTO instanceAdminUser =
+                commonServer.tryToAuthenticate("instance_admin", "password");
+        ExperimentUpdatesDTO updates = getProjectUpdate(instanceAdminUser);
+        commonServer.updateExperiment(instanceAdminUser.getSessionToken(), updates);
+
+        Experiment experiment =
+                commonServer.getExperimentInfo(instanceAdminUser.getSessionToken(),
+                        new ExperimentIdentifier(
+                                "CISD", "CISD", "DEFAULT", "EXP1"));
+        assertThat(experiment.getProject().getCode(), is("DEFAULT"));
+    }
+
+    private ExperimentUpdatesDTO getProjectUpdate(SessionContextDTO session)
+    {
+        ExperimentUpdatesDTO updates = new ExperimentUpdatesDTO();
+        Experiment experiment =
+                commonServer.getExperimentInfo(session.getSessionToken(), new ExperimentIdentifier(
+                        "CISD", "CISD", "NEMO", "EXP1"));
+
+        updates.setExperimentId(new TechId(experiment));
+        updates.setVersion(experiment.getModificationDate());
+        updates.setProjectIdentifier(new ProjectIdentifier("CISD", "CISD", "DEFAULT"));
+        updates.setProperties(experiment.getProperties());
+        updates.setAttachments(new ArrayList<NewAttachment>());
+        updates.setNewSamples(new ArrayList<NewSamplesWithTypes>());
+        return updates;
+    }
+}