diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/AuthorizationTestCase.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/AuthorizationTestCase.java
index 48dc10c4c1a801ed7630adcc356fd8e4a5c54d2f..eb17d5e8cad643efc90fa8f8ae20cd7e357ee388 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/AuthorizationTestCase.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/AuthorizationTestCase.java
@@ -17,6 +17,7 @@
 package ch.systemsx.cisd.openbis.generic.server.authorization;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -28,6 +29,7 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 
 import ch.rinn.restrictions.Friend;
+import ch.systemsx.cisd.common.exceptions.Status;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleLevel;
@@ -50,10 +52,26 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
 @Friend(toClasses = RoleWithIdentifier.class)
 public class AuthorizationTestCase extends AssertJUnit
 {
+
+    protected static final PersonPE PERSON = new PersonPE();
+
     protected static final String SPACE_CODE = "G1";
 
     protected static final String ANOTHER_SPACE_CODE = "G2";
 
+    protected static final SpacePE SPACE = new SpacePE();
+
+    protected static final SpacePE ANOTHER_SPACE = new SpacePE();
+
+    protected static final List<SpacePE> ALL_SPACES = Arrays.asList(SPACE, ANOTHER_SPACE);
+
+    static
+    {
+        PERSON.setUserId("test");
+        SPACE.setCode(SPACE_CODE);
+        ANOTHER_SPACE.setCode(ANOTHER_SPACE_CODE);
+    }
+
     protected Mockery context;
 
     protected IAuthorizationDataProvider provider;
@@ -62,9 +80,19 @@ public class AuthorizationTestCase extends AssertJUnit
      * Creates a role with level {@link RoleLevel#SPACE} with specified role code for specified space.
      */
     protected RoleWithIdentifier createSpaceRole(RoleCode roleCode, SpaceIdentifier spaceIdentifier)
+    {
+        return createSpaceRole(roleCode, spaceIdentifier.getSpaceCode());
+    }
+
+    protected RoleWithIdentifier createSpaceRole(RoleCode roleCode, SpacePE spacePE)
+    {
+        return createSpaceRole(roleCode, spacePE.getCode());
+    }
+
+    protected RoleWithIdentifier createSpaceRole(RoleCode roleCode, String spaceCode)
     {
         SpacePE groupPE = new SpacePE();
-        groupPE.setCode(spaceIdentifier.getSpaceCode());
+        groupPE.setCode(spaceCode);
         return new RoleWithIdentifier(RoleLevel.SPACE, roleCode, groupPE);
     }
 
@@ -314,6 +342,16 @@ public class AuthorizationTestCase extends AssertJUnit
             });
     }
 
+    protected static void assertOK(Status status)
+    {
+        assertTrue(status.isOK());
+    }
+
+    protected static void assertError(Status status)
+    {
+        assertTrue(status.isError());
+    }
+
     @BeforeMethod
     public void setUp()
     {
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/NewProjectPredicateTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/NewProjectPredicateTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..688689bee123f3e6344997fc7201368ed93057c4
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/NewProjectPredicateTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2017 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.authorization.predicate;
+
+import java.util.Arrays;
+
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.exceptions.Status;
+import ch.systemsx.cisd.openbis.generic.server.authorization.AuthorizationTestCase;
+import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewProject;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode;
+
+/**
+ * @author pkupczyk
+ */
+public class NewProjectPredicateTest extends AuthorizationTestCase
+{
+
+    private static NewProject SPACE_PROJECT = new NewProject("/" + SPACE_CODE + "/PROJECT", "space project");
+
+    private static NewProject ANOTHER_SPACE_PROJECT = new NewProject("/" + ANOTHER_SPACE_CODE + "/PROJECT", "another space project");
+
+    @Test
+    public void testWithNonexistentSpaceForInstanceUser()
+    {
+        prepareProvider(Arrays.asList(SPACE));
+        assertOK(evaluate(ANOTHER_SPACE_PROJECT, createInstanceRole(RoleCode.ADMIN)));
+    }
+
+    @Test
+    public void testWithNonexistentSpaceForSpaceUser()
+    {
+        prepareProvider(Arrays.asList(SPACE));
+        assertOK(evaluate(ANOTHER_SPACE_PROJECT, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE)));
+    }
+
+    @Test
+    public void testWithNoAllowedRoles()
+    {
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(SPACE_PROJECT));
+    }
+
+    @Test
+    public void testWithMultipleAllowedRoles()
+    {
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE), createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithInstanceUser()
+    {
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT, createInstanceRole(RoleCode.ADMIN)));
+    }
+
+    @Test
+    public void testWithMatchingSpaceUser()
+    {
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT, createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithNonMatchingSpaceUser()
+    {
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(SPACE_PROJECT, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE)));
+    }
+
+    private Status evaluate(NewProject newProject, RoleWithIdentifier... roles)
+    {
+        NewProjectPredicate predicate = new NewProjectPredicate();
+        predicate.init(provider);
+        return predicate.evaluate(PERSON, Arrays.asList(roles), newProject);
+    }
+
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectAugmentedCodePredicateTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectAugmentedCodePredicateTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..7e43ff1cd22a37231a5b7c1f0695e3cdb7104197
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectAugmentedCodePredicateTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2017 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.authorization.predicate;
+
+import java.util.Arrays;
+
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.exceptions.Status;
+import ch.systemsx.cisd.openbis.generic.server.authorization.AuthorizationTestCase;
+import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode;
+
+/**
+ * @author pkupczyk
+ */
+public class ProjectAugmentedCodePredicateTest extends AuthorizationTestCase
+{
+
+    private static String SPACE_PROJECT = "/" + SPACE_CODE + "/PROJECT";
+
+    private static String ANOTHER_SPACE_PROJECT = "/" + ANOTHER_SPACE_CODE + "/PROJECT";
+
+    @Test
+    public void testWithNonexistentSpaceForInstanceUser()
+    {
+        prepareProvider(Arrays.asList(SPACE));
+        assertOK(evaluate(ANOTHER_SPACE_PROJECT, createInstanceRole(RoleCode.ADMIN)));
+    }
+
+    @Test
+    public void testWithNonexistentSpaceForSpaceUser()
+    {
+        prepareProvider(Arrays.asList(SPACE));
+        assertError(evaluate(ANOTHER_SPACE_PROJECT, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE)));
+    }
+
+    @Test
+    public void testWithNoAllowedRoles()
+    {
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(SPACE_PROJECT));
+    }
+
+    @Test
+    public void testWithMultipleAllowedRoles()
+    {
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE), createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithInstanceUser()
+    {
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT, createInstanceRole(RoleCode.ADMIN)));
+    }
+
+    @Test
+    public void testWithMatchingSpaceUser()
+    {
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT, createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithNonMatchingSpaceUser()
+    {
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(SPACE_PROJECT, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE)));
+    }
+
+    private Status evaluate(String projectIdentifier, RoleWithIdentifier... roles)
+    {
+        ProjectAugmentedCodePredicate predicate = new ProjectAugmentedCodePredicate();
+        predicate.init(provider);
+        return predicate.evaluate(PERSON, Arrays.asList(roles), projectIdentifier);
+    }
+
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectIdPredicateTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectIdPredicateTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..cadd4ecc0b6fb096abaccf6c9ebbc774f21d714c
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectIdPredicateTest.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright 2017 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.authorization.predicate;
+
+import java.util.Arrays;
+
+import org.jmock.Expectations;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.exceptions.Status;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.openbis.generic.server.authorization.AuthorizationTestCase;
+import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
+import ch.systemsx.cisd.openbis.generic.server.authorization.SpaceOwnerKind;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.project.IProjectId;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.project.ProjectIdentifierId;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.project.ProjectPermIdId;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.project.ProjectTechIdId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PermId;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
+
+/**
+ * @author pkupczyk
+ */
+public class ProjectIdPredicateTest extends AuthorizationTestCase
+{
+
+    private static final ProjectPE SPACE_PROJECT = new ProjectPE();
+
+    private static final ProjectPE ANOTHER_SPACE_PROJECT = new ProjectPE();
+
+    private static final ProjectIdentifierId SPACE_PROJECT_IDENTIFIER = new ProjectIdentifierId("/" + SPACE_CODE + "/PROJECT");
+
+    private static final ProjectPermIdId SPACE_PROJECT_PERM_ID = new ProjectPermIdId("spaceProjectPermId");
+
+    private static final ProjectTechIdId SPACE_PROJECT_TECH_ID = new ProjectTechIdId(123L);
+
+    static
+    {
+        SPACE_PROJECT.setSpace(SPACE);
+        ANOTHER_SPACE_PROJECT.setSpace(ANOTHER_SPACE);
+    }
+
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "No project id specified.")
+    public void testWithNonexistentProjectForInstanceUser()
+    {
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(null, createInstanceRole(RoleCode.ADMIN)));
+    }
+
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "No project id specified.")
+    public void testWithNonexistentProjectForSpaceUser()
+    {
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(null, createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithNoAllowedRolesWithIdentifier()
+    {
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(SPACE_PROJECT_IDENTIFIER));
+    }
+
+    @Test
+    public void testWithNoAllowedRolesWithPermId()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetProjectByPermId(new PermId(SPACE_PROJECT_PERM_ID.getPermId()));
+                    will(returnValue(SPACE_PROJECT));
+                }
+            });
+
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(SPACE_PROJECT_PERM_ID));
+    }
+
+    @Test
+    public void testWithNoAllowedRolesWithTechId()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetSpace(SpaceOwnerKind.PROJECT, new TechId(SPACE_PROJECT_TECH_ID.getTechId()));
+                    will(returnValue(SPACE));
+                }
+            });
+
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(SPACE_PROJECT_TECH_ID));
+    }
+
+    @Test
+    public void testWithMultipleAllowedRolesWithIdentifier()
+    {
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT_IDENTIFIER, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE), createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithMultipleAllowedRolesWithPermId()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetProjectByPermId(new PermId(SPACE_PROJECT_PERM_ID.getPermId()));
+                    will(returnValue(SPACE_PROJECT));
+                }
+            });
+
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT_PERM_ID, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE), createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithMultipleAllowedRolesWithTechId()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetSpace(SpaceOwnerKind.PROJECT, new TechId(SPACE_PROJECT_TECH_ID.getTechId()));
+                    will(returnValue(SPACE));
+                }
+            });
+
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT_TECH_ID, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE), createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithInstanceUserWithIdentifier()
+    {
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT_IDENTIFIER, createInstanceRole(RoleCode.ADMIN)));
+    }
+
+    @Test
+    public void testWithInstanceUserWithPermId()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetProjectByPermId(new PermId(SPACE_PROJECT_PERM_ID.getPermId()));
+                    will(returnValue(SPACE_PROJECT));
+                }
+            });
+
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT_PERM_ID, createInstanceRole(RoleCode.ADMIN)));
+    }
+
+    @Test
+    public void testWithInstanceUserWithTechId()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetSpace(SpaceOwnerKind.PROJECT, new TechId(SPACE_PROJECT_TECH_ID.getTechId()));
+                    will(returnValue(SPACE));
+                }
+            });
+
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT_TECH_ID, createInstanceRole(RoleCode.ADMIN)));
+    }
+
+    @Test
+    public void testWithMatchingSpaceUserWithIdentifier()
+    {
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT_IDENTIFIER, createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithMatchingSpaceUserWithPermId()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetProjectByPermId(new PermId(SPACE_PROJECT_PERM_ID.getPermId()));
+                    will(returnValue(SPACE_PROJECT));
+                }
+            });
+
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT_PERM_ID, createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithMatchingSpaceUserWithTechId()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetSpace(SpaceOwnerKind.PROJECT, new TechId(SPACE_PROJECT_TECH_ID.getTechId()));
+                    will(returnValue(SPACE));
+                }
+            });
+
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT_TECH_ID, createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithNonMatchingSpaceUserWithIdentifier()
+    {
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(SPACE_PROJECT_IDENTIFIER, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE)));
+    }
+
+    @Test
+    public void testWithNonMatchingSpaceUserWithPermId()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetProjectByPermId(new PermId(SPACE_PROJECT_PERM_ID.getPermId()));
+                    will(returnValue(SPACE_PROJECT));
+                }
+            });
+
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(SPACE_PROJECT_PERM_ID, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE)));
+    }
+
+    @Test
+    public void testWithNonMatchingSpaceUserWithTechId()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetSpace(SpaceOwnerKind.PROJECT, new TechId(SPACE_PROJECT_TECH_ID.getTechId()));
+                    will(returnValue(SPACE));
+                }
+            });
+
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(SPACE_PROJECT_TECH_ID, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE)));
+    }
+
+    private Status evaluate(IProjectId projectId, RoleWithIdentifier... roles)
+    {
+        ProjectIdPredicate predicate = new ProjectIdPredicate();
+        predicate.init(provider);
+        return predicate.evaluate(PERSON, Arrays.asList(roles), projectId);
+    }
+
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectPEPredicateTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectPEPredicateTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ba9d8a42e5db04dc8853517e825f4a9c7c920b83
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectPEPredicateTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2017 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.authorization.predicate;
+
+import java.util.Arrays;
+
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.exceptions.Status;
+import ch.systemsx.cisd.openbis.generic.server.authorization.AuthorizationTestCase;
+import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
+
+/**
+ * @author pkupczyk
+ */
+public class ProjectPEPredicateTest extends AuthorizationTestCase
+{
+
+    private static final ProjectPE SPACE_PROJECT = new ProjectPE();
+
+    private static final ProjectPE ANOTHER_SPACE_PROJECT = new ProjectPE();
+
+    static
+    {
+        SPACE_PROJECT.setSpace(SPACE);
+        ANOTHER_SPACE_PROJECT.setSpace(ANOTHER_SPACE);
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testWithNonexistentProjectForInstanceUser()
+    {
+        evaluate(null, createInstanceRole(RoleCode.ADMIN));
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testWithNonexistentProjectForSpaceUser()
+    {
+        evaluate(null, createSpaceRole(RoleCode.ADMIN, SPACE));
+    }
+
+    @Test
+    public void testWithNoAllowedRoles()
+    {
+        assertError(evaluate(SPACE_PROJECT));
+    }
+
+    @Test
+    public void testWithMultipleAllowedRoles()
+    {
+        assertOK(evaluate(SPACE_PROJECT, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE), createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithInstanceUser()
+    {
+        assertOK(evaluate(SPACE_PROJECT, createInstanceRole(RoleCode.ADMIN)));
+    }
+
+    @Test
+    public void testWithMatchingSpaceUser()
+    {
+        assertOK(evaluate(SPACE_PROJECT, createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithNonMatchingSpaceUser()
+    {
+        assertError(evaluate(SPACE_PROJECT, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE)));
+    }
+
+    private Status evaluate(ProjectPE project, RoleWithIdentifier... roles)
+    {
+        ProjectPEPredicate predicate = new ProjectPEPredicate();
+        predicate.init(provider);
+        return predicate.evaluate(PERSON, Arrays.asList(roles), project);
+    }
+
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectPermIdPredicateTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectPermIdPredicateTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..8cf369783cd32fd5c147a27c30c92ccd11f3d7fb
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectPermIdPredicateTest.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2017 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.authorization.predicate;
+
+import java.util.Arrays;
+
+import org.jmock.Expectations;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.exceptions.Status;
+import ch.systemsx.cisd.openbis.generic.server.authorization.AuthorizationTestCase;
+import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PermId;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
+
+/**
+ * @author pkupczyk
+ */
+public class ProjectPermIdPredicateTest extends AuthorizationTestCase
+{
+
+    private static final PermId SPACE_PROJECT_PERM_ID = new PermId("projectPermId");
+
+    private static final ProjectPE SPACE_PROJECT = new ProjectPE();
+
+    private static final ProjectPE ANOTHER_SPACE_PROJECT = new ProjectPE();
+
+    static
+    {
+        SPACE_PROJECT.setSpace(SPACE);
+        ANOTHER_SPACE_PROJECT.setSpace(ANOTHER_SPACE);
+    }
+
+    @Test
+    public void testWithNonexistentProjectForInstanceUser()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetProjectByPermId(SPACE_PROJECT_PERM_ID);
+                    will(returnValue(null));
+                }
+            });
+
+        assertOK(evaluate(SPACE_PROJECT_PERM_ID, createInstanceRole(RoleCode.ADMIN)));
+    }
+
+    @Test
+    public void testWithNonexistentProjectForSpaceUser()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetProjectByPermId(SPACE_PROJECT_PERM_ID);
+                    will(returnValue(null));
+                }
+            });
+
+        assertOK(evaluate(SPACE_PROJECT_PERM_ID, createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithNoAllowedRoles()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetProjectByPermId(SPACE_PROJECT_PERM_ID);
+                    will(returnValue(SPACE_PROJECT));
+                }
+            });
+
+        assertError(evaluate(SPACE_PROJECT_PERM_ID));
+    }
+
+    @Test
+    public void testWithMultipleAllowedRoles()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetProjectByPermId(SPACE_PROJECT_PERM_ID);
+                    will(returnValue(SPACE_PROJECT));
+                }
+            });
+
+        assertOK(evaluate(SPACE_PROJECT_PERM_ID, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE), createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithInstanceUser()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetProjectByPermId(SPACE_PROJECT_PERM_ID);
+                    will(returnValue(SPACE_PROJECT));
+                }
+            });
+
+        assertOK(evaluate(SPACE_PROJECT_PERM_ID, createInstanceRole(RoleCode.ADMIN)));
+    }
+
+    @Test
+    public void testWithMatchingSpaceUser()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetProjectByPermId(SPACE_PROJECT_PERM_ID);
+                    will(returnValue(SPACE_PROJECT));
+                }
+            });
+
+        assertOK(evaluate(SPACE_PROJECT_PERM_ID, createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithNonMatchingSpaceUser()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetProjectByPermId(SPACE_PROJECT_PERM_ID);
+                    will(returnValue(SPACE_PROJECT));
+                }
+            });
+
+        assertError(evaluate(SPACE_PROJECT_PERM_ID, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE)));
+    }
+
+    private Status evaluate(PermId permId, RoleWithIdentifier... roles)
+    {
+        ProjectPermIdPredicate predicate = new ProjectPermIdPredicate();
+        predicate.init(provider);
+        return predicate.evaluate(PERSON, Arrays.asList(roles), permId);
+    }
+
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectPredicateTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectPredicateTest.java
index d79182f9bf3ce3d1ccc032da42dde16912810516..eb572350450b612225afef9930685e0065a6ccfe 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectPredicateTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectPredicateTest.java
@@ -16,57 +16,78 @@
 
 package ch.systemsx.cisd.openbis.generic.server.authorization.predicate;
 
-import org.jmock.Expectations;
+import java.util.Arrays;
+
 import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.common.exceptions.Status;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.server.authorization.AuthorizationTestCase;
+import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Project;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode;
 
 /**
  * @author Pawel Glyzewski
  */
 public class ProjectPredicateTest extends AuthorizationTestCase
 {
-    @Test
-    public void testHaveAccessToProject()
+    private static final Project SPACE_PROJECT = new Project(SPACE.getCode(), "PROJECT");
+
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "No project specified.")
+    public void testWithNonexistentProjectForInstanceUser()
     {
-        ProjectPredicate predicate = new ProjectPredicate();
-        Project project = new Project(SPACE_CODE, "XXX");
+        prepareProvider(ALL_SPACES);
+        evaluate(null, createInstanceRole(RoleCode.ADMIN));
+    }
 
-        context.checking(new Expectations()
-            {
-                {
-                    allowing(provider).listSpaces();
-                    will(returnValue(createSpaces()));
-                }
-            });
-        predicate.init(provider);
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "No project specified.")
+    public void testWithNonexistentProjectForSpaceUser()
+    {
+        prepareProvider(ALL_SPACES);
+        evaluate(null, createSpaceRole(RoleCode.ADMIN, SPACE));
+    }
 
-        Status status = predicate.evaluate(createPerson(), createRoles(false), project);
+    @Test
+    public void testWithNoAllowedRoles()
+    {
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(SPACE_PROJECT));
+    }
 
-        assertEquals(false, status.isError());
-        context.assertIsSatisfied();
+    @Test
+    public void testWithMultipleAllowedRoles()
+    {
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE), createSpaceRole(RoleCode.ADMIN, SPACE)));
     }
 
     @Test
-    public void testHaveNoAccessToProject()
+    public void testWithInstanceUser()
     {
-        ProjectPredicate predicate = new ProjectPredicate();
-        Project project = new Project(ANOTHER_SPACE_CODE, "XXX");
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT, createInstanceRole(RoleCode.ADMIN)));
+    }
 
-        context.checking(new Expectations()
-            {
-                {
-                    allowing(provider).listSpaces();
-                    will(returnValue(createSpaces()));
-                }
-            });
-        predicate.init(provider);
+    @Test
+    public void testWithMatchingSpaceUser()
+    {
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT, createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
 
-        Status status = predicate.evaluate(createPerson(), createRoles(false), project);
+    @Test
+    public void testWithNonMatchingSpaceUser()
+    {
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(SPACE_PROJECT, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE)));
+    }
 
-        assertEquals(true, status.isError());
-        context.assertIsSatisfied();
+    private Status evaluate(Project project, RoleWithIdentifier... roles)
+    {
+        ProjectPredicate predicate = new ProjectPredicate();
+        predicate.init(provider);
+        return predicate.evaluate(PERSON, Arrays.asList(roles), project);
     }
+
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectTechIdCollectionPredicateTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectTechIdCollectionPredicateTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..8a7b350b4908ab80dc514a7a158f34312e490c24
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectTechIdCollectionPredicateTest.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2017 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.authorization.predicate;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+
+import org.jmock.Expectations;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.exceptions.Status;
+import ch.systemsx.cisd.openbis.generic.server.authorization.AuthorizationTestCase;
+import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
+import ch.systemsx.cisd.openbis.generic.server.authorization.SpaceOwnerKind;
+import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.AbstractTechIdCollectionPredicate.ProjectTechIdCollectionPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
+
+/**
+ * @author pkupczyk
+ */
+public class ProjectTechIdCollectionPredicateTest extends AuthorizationTestCase
+{
+
+    private static TechId PROJECT_ID = new TechId(123L);
+
+    private static TechId PROJECT_ID_2 = new TechId(234L);
+
+    @Test
+    public void testWithNonexistentProjectForInstanceUser()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).getDistinctSpacesByEntityIds(SpaceOwnerKind.PROJECT, Arrays.asList(PROJECT_ID));
+                    will(returnValue(Collections.emptySet()));
+                }
+            });
+
+        assertOK(evaluate(Arrays.asList(PROJECT_ID), createInstanceRole(RoleCode.ADMIN)));
+    }
+
+    @Test
+    public void testWithNonexistentProjectForSpaceUser()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).getDistinctSpacesByEntityIds(SpaceOwnerKind.PROJECT, Arrays.asList(PROJECT_ID));
+                    will(returnValue(Collections.emptySet()));
+                }
+            });
+
+        assertOK(evaluate(Arrays.asList(PROJECT_ID), createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithNoAllowedRoles()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).getDistinctSpacesByEntityIds(SpaceOwnerKind.PROJECT, Arrays.asList(PROJECT_ID));
+                    will(returnValue(Collections.singleton(SPACE)));
+                }
+            });
+
+        assertError(evaluate(Arrays.asList(PROJECT_ID)));
+    }
+
+    @Test
+    public void testWithMultipleAllowedRoles()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).getDistinctSpacesByEntityIds(SpaceOwnerKind.PROJECT, Arrays.asList(PROJECT_ID));
+                    will(returnValue(Collections.singleton(SPACE)));
+                }
+            });
+
+        assertOK(evaluate(Arrays.asList(PROJECT_ID), createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE), createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithInstanceUser()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).getDistinctSpacesByEntityIds(SpaceOwnerKind.PROJECT, Arrays.asList(PROJECT_ID));
+                    will(returnValue(Collections.singleton(SPACE)));
+                }
+            });
+
+        assertOK(evaluate(Arrays.asList(PROJECT_ID), createInstanceRole(RoleCode.ADMIN)));
+    }
+
+    @Test
+    public void testWithMatchingSpaceUser()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).getDistinctSpacesByEntityIds(SpaceOwnerKind.PROJECT, Arrays.asList(PROJECT_ID));
+                    will(returnValue(Collections.singleton(SPACE)));
+                }
+            });
+
+        assertOK(evaluate(Arrays.asList(PROJECT_ID), createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithNonMatchingSpaceUser()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).getDistinctSpacesByEntityIds(SpaceOwnerKind.PROJECT, Arrays.asList(PROJECT_ID));
+                    will(returnValue(Collections.singleton(SPACE)));
+                }
+            });
+
+        assertError(evaluate(Arrays.asList(PROJECT_ID), createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE)));
+    }
+
+    @Test
+    public void testWithMultipleTechIdsWithAccessToOnlyOne()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).getDistinctSpacesByEntityIds(SpaceOwnerKind.PROJECT, Arrays.asList(PROJECT_ID, PROJECT_ID_2));
+                    will(returnValue(new HashSet<SpacePE>(Arrays.asList(SPACE, ANOTHER_SPACE))));
+                }
+            });
+
+        assertError(evaluate(Arrays.asList(PROJECT_ID, PROJECT_ID_2), createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithMultipleTechIdsWithAccessToAll()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).getDistinctSpacesByEntityIds(SpaceOwnerKind.PROJECT, Arrays.asList(PROJECT_ID, PROJECT_ID_2));
+                    will(returnValue(new HashSet<SpacePE>(Arrays.asList(SPACE, ANOTHER_SPACE))));
+                }
+            });
+
+        assertOK(evaluate(Arrays.asList(PROJECT_ID, PROJECT_ID_2), createSpaceRole(RoleCode.ADMIN, SPACE),
+                createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE)));
+    }
+
+    private Status evaluate(List<TechId> techIds, RoleWithIdentifier... roles)
+    {
+        ProjectTechIdCollectionPredicate predicate = new ProjectTechIdCollectionPredicate();
+        predicate.init(provider);
+        return predicate.evaluate(PERSON, Arrays.asList(roles), techIds);
+    }
+
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectTechIdPredicateTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectTechIdPredicateTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..46d5e6b978702ce155aecfcb8e7c902e0745e300
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectTechIdPredicateTest.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2017 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.authorization.predicate;
+
+import java.util.Arrays;
+
+import org.jmock.Expectations;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.exceptions.Status;
+import ch.systemsx.cisd.openbis.generic.server.authorization.AuthorizationTestCase;
+import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
+import ch.systemsx.cisd.openbis.generic.server.authorization.SpaceOwnerKind;
+import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.AbstractTechIdPredicate.ProjectTechIdPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode;
+
+/**
+ * @author pkupczyk
+ */
+public class ProjectTechIdPredicateTest extends AuthorizationTestCase
+{
+
+    private static Long PROJECT_ID = 123L;
+
+    @Test
+    public void testWithNonexistentProjectForInstanceUser()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetSpace(SpaceOwnerKind.PROJECT, new TechId(PROJECT_ID));
+                    will(returnValue(null));
+                }
+            });
+
+        assertError(evaluate(PROJECT_ID, createInstanceRole(RoleCode.ADMIN)));
+    }
+
+    @Test
+    public void testWithNonexistentProjectForSpaceUser()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetSpace(SpaceOwnerKind.PROJECT, new TechId(PROJECT_ID));
+                    will(returnValue(null));
+                }
+            });
+
+        assertError(evaluate(PROJECT_ID, createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithNoAllowedRoles()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetSpace(SpaceOwnerKind.PROJECT, new TechId(PROJECT_ID));
+                    will(returnValue(SPACE));
+                }
+            });
+
+        assertError(evaluate(PROJECT_ID));
+    }
+
+    @Test
+    public void testWithMultipleAllowedRoles()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetSpace(SpaceOwnerKind.PROJECT, new TechId(PROJECT_ID));
+                    will(returnValue(SPACE));
+                }
+            });
+
+        assertOK(evaluate(PROJECT_ID, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE), createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithInstanceUser()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetSpace(SpaceOwnerKind.PROJECT, new TechId(PROJECT_ID));
+                    will(returnValue(SPACE));
+                }
+            });
+
+        assertOK(evaluate(PROJECT_ID, createInstanceRole(RoleCode.ADMIN)));
+    }
+
+    @Test
+    public void testWithMatchingSpaceUser()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetSpace(SpaceOwnerKind.PROJECT, new TechId(PROJECT_ID));
+                    will(returnValue(SPACE));
+                }
+            });
+
+        assertOK(evaluate(PROJECT_ID, createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithNonMatchingSpaceUser()
+    {
+        prepareProvider(ALL_SPACES);
+
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetSpace(SpaceOwnerKind.PROJECT, new TechId(PROJECT_ID));
+                    will(returnValue(SPACE));
+                }
+            });
+
+        assertError(evaluate(PROJECT_ID, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE)));
+    }
+
+    private Status evaluate(long techId, RoleWithIdentifier... roles)
+    {
+        ProjectTechIdPredicate predicate = new ProjectTechIdPredicate();
+        predicate.init(provider);
+        return predicate.evaluate(PERSON, Arrays.asList(roles), new TechId(123L));
+    }
+
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectUpdatesPredicateTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectUpdatesPredicateTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..fedaaf8ef1d2f9e2a9d4e59a6e27e04cd39d5851
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ProjectUpdatesPredicateTest.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2017 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.authorization.predicate;
+
+import java.util.Arrays;
+
+import org.jmock.Expectations;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.exceptions.Status;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.openbis.generic.server.authorization.AuthorizationTestCase;
+import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
+import ch.systemsx.cisd.openbis.generic.server.authorization.SpaceOwnerKind;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PermId;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectUpdatesDTO;
+
+/**
+ * @author pkupczyk
+ */
+public class ProjectUpdatesPredicateTest extends AuthorizationTestCase
+{
+
+    private static final ProjectPE SPACE_PROJECT = new ProjectPE();
+
+    private static final ProjectPE ANOTHER_SPACE_PROJECT = new ProjectPE();
+
+    private static final ProjectUpdatesDTO SPACE_PROJECT_WITH_TECH_ID = new ProjectUpdatesDTO();
+
+    private static final ProjectUpdatesDTO ANOTHER_SPACE_PROJECT_WITH_TECH_ID = new ProjectUpdatesDTO();
+
+    private static final ProjectUpdatesDTO SPACE_PROJECT_WITH_PERM_ID = new ProjectUpdatesDTO();
+
+    private static final ProjectUpdatesDTO ANOTHER_SPACE_PROJECT_WITH_PERM_ID = new ProjectUpdatesDTO();
+
+    private static final ProjectUpdatesDTO SPACE_PROJECT_WITH_IDENTIFIER = new ProjectUpdatesDTO();
+
+    private static final ProjectUpdatesDTO ANOTHER_SPACE_PROJECT_WITH_IDENTIFIER = new ProjectUpdatesDTO();
+
+    static
+    {
+        SPACE_PROJECT.setSpace(SPACE);
+        ANOTHER_SPACE_PROJECT.setSpace(ANOTHER_SPACE);
+
+        SPACE_PROJECT_WITH_TECH_ID.setTechId(new TechId(123L));
+        ANOTHER_SPACE_PROJECT_WITH_TECH_ID.setTechId(new TechId(234L));
+
+        SPACE_PROJECT_WITH_PERM_ID.setPermId("spaceProjectPermId");
+        ANOTHER_SPACE_PROJECT_WITH_PERM_ID.setPermId("anotherSpaceProjectPermId");
+
+        SPACE_PROJECT_WITH_IDENTIFIER.setIdentifier("/" + SPACE_CODE + "/PROJECT");
+        ANOTHER_SPACE_PROJECT_WITH_IDENTIFIER.setIdentifier("/" + ANOTHER_SPACE_CODE + "/PROJECT");
+    }
+
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "No project updates specified.")
+    public void testWithNonexistentProjectForInstanceUser()
+    {
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(null, createInstanceRole(RoleCode.ADMIN)));
+    }
+
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = "No project updates specified.")
+    public void testWithNonexistentProjectForSpaceUser()
+    {
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(null, createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithNoAllowedRolesWithIdentifier()
+    {
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(SPACE_PROJECT_WITH_IDENTIFIER));
+    }
+
+    @Test
+    public void testWithNoAllowedRolesWithPermId()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetProjectByPermId(new PermId(SPACE_PROJECT_WITH_PERM_ID.getPermId()));
+                    will(returnValue(SPACE_PROJECT));
+                }
+            });
+
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(SPACE_PROJECT_WITH_PERM_ID));
+    }
+
+    @Test
+    public void testWithNoAllowedRolesWithTechId()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetSpace(SpaceOwnerKind.PROJECT, SPACE_PROJECT_WITH_TECH_ID.getTechId());
+                    will(returnValue(SPACE));
+                }
+            });
+
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(SPACE_PROJECT_WITH_TECH_ID));
+    }
+
+    @Test
+    public void testWithMultipleAllowedRolesWithIdentifier()
+    {
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT_WITH_IDENTIFIER, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE), createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithMultipleAllowedRolesWithPermId()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetProjectByPermId(new PermId(SPACE_PROJECT_WITH_PERM_ID.getPermId()));
+                    will(returnValue(SPACE_PROJECT));
+                }
+            });
+
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT_WITH_PERM_ID, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE), createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithMultipleAllowedRolesWithTechId()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetSpace(SpaceOwnerKind.PROJECT, SPACE_PROJECT_WITH_TECH_ID.getTechId());
+                    will(returnValue(SPACE));
+                }
+            });
+
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT_WITH_TECH_ID, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE), createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithInstanceUserWithIdentifier()
+    {
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT_WITH_IDENTIFIER, createInstanceRole(RoleCode.ADMIN)));
+    }
+
+    @Test
+    public void testWithInstanceUserWithPermId()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetProjectByPermId(new PermId(SPACE_PROJECT_WITH_PERM_ID.getPermId()));
+                    will(returnValue(SPACE_PROJECT));
+                }
+            });
+
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT_WITH_PERM_ID, createInstanceRole(RoleCode.ADMIN)));
+    }
+
+    @Test
+    public void testWithInstanceUserWithTechId()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetSpace(SpaceOwnerKind.PROJECT, SPACE_PROJECT_WITH_TECH_ID.getTechId());
+                    will(returnValue(SPACE));
+                }
+            });
+
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT_WITH_TECH_ID, createInstanceRole(RoleCode.ADMIN)));
+    }
+
+    @Test
+    public void testWithMatchingSpaceUserWithIdentifier()
+    {
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT_WITH_IDENTIFIER, createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithMatchingSpaceUserWithPermId()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetProjectByPermId(new PermId(SPACE_PROJECT_WITH_PERM_ID.getPermId()));
+                    will(returnValue(SPACE_PROJECT));
+                }
+            });
+
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT_WITH_PERM_ID, createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithMatchingSpaceUserWithTechId()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetSpace(SpaceOwnerKind.PROJECT, SPACE_PROJECT_WITH_TECH_ID.getTechId());
+                    will(returnValue(SPACE));
+                }
+            });
+
+        prepareProvider(ALL_SPACES);
+        assertOK(evaluate(SPACE_PROJECT_WITH_TECH_ID, createSpaceRole(RoleCode.ADMIN, SPACE)));
+    }
+
+    @Test
+    public void testWithNonMatchingSpaceUserWithIdentifier()
+    {
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(SPACE_PROJECT_WITH_IDENTIFIER, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE)));
+    }
+
+    @Test
+    public void testWithNonMatchingSpaceUserWithPermId()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetProjectByPermId(new PermId(SPACE_PROJECT_WITH_PERM_ID.getPermId()));
+                    will(returnValue(SPACE_PROJECT));
+                }
+            });
+
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(SPACE_PROJECT_WITH_PERM_ID, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE)));
+    }
+
+    @Test
+    public void testWithNonMatchingSpaceUserWithTechId()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(provider).tryGetSpace(SpaceOwnerKind.PROJECT, SPACE_PROJECT_WITH_TECH_ID.getTechId());
+                    will(returnValue(SPACE));
+                }
+            });
+
+        prepareProvider(ALL_SPACES);
+        assertError(evaluate(SPACE_PROJECT_WITH_TECH_ID, createSpaceRole(RoleCode.ADMIN, ANOTHER_SPACE)));
+    }
+
+    private Status evaluate(ProjectUpdatesDTO updates, RoleWithIdentifier... roles)
+    {
+        ProjectUpdatesPredicate predicate = new ProjectUpdatesPredicate();
+        predicate.init(provider);
+        return predicate.evaluate(PERSON, Arrays.asList(roles), updates);
+    }
+
+}
diff --git a/openbis/sourceTest/java/tests_project_authorization.xml b/openbis/sourceTest/java/tests_project_authorization.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4c2b9baad0022d044761ea8f9ed275ab3c08a4f5
--- /dev/null
+++ b/openbis/sourceTest/java/tests_project_authorization.xml
@@ -0,0 +1,8 @@
+<suite name="projectAuthorization" verbose="2">
+	<test name="unit" annotations="JDK">
+		<packages>
+			<package
+				name="ch.systemsx.cisd.openbis.generic.server.authorization.predicate.*" />
+		</packages>
+	</test>
+</suite>