diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateExperimentOfSampleTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateExperimentOfSampleTest.java
index f3d2967551736422bba595edaa4ea96565cc8383..3025198073aca3b83bc75ebbe7dc301963877347 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateExperimentOfSampleTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateExperimentOfSampleTest.java
@@ -16,6 +16,10 @@
 
 package ch.systemsx.cisd.openbis.systemtest;
 
+import static ch.systemsx.cisd.openbis.systemtest.base.auth.RuleBuilder.and;
+import static ch.systemsx.cisd.openbis.systemtest.base.auth.RuleBuilder.not;
+import static ch.systemsx.cisd.openbis.systemtest.base.auth.RuleBuilder.or;
+import static ch.systemsx.cisd.openbis.systemtest.base.auth.RuleBuilder.rule;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -30,10 +34,13 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleLevel;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Space;
 import ch.systemsx.cisd.openbis.systemtest.base.BaseTest;
-import ch.systemsx.cisd.openbis.systemtest.base.RolePermutator;
+import ch.systemsx.cisd.openbis.systemtest.base.auth.AuthorizationRule;
+import ch.systemsx.cisd.openbis.systemtest.base.auth.GuardedDomain;
+import ch.systemsx.cisd.openbis.systemtest.base.auth.RolePermutator;
 
 /**
  * @author anttil
@@ -149,20 +156,51 @@ public class UpdateExperimentOfSampleTest extends BaseTest
         sample = create(aSample().inExperiment(sourceExperiment));
     }
 
+    public static final GuardedDomain space1;
+
+    public static final GuardedDomain space2;
+
+    public static final GuardedDomain instance;
+
+    public static final AuthorizationRule assignSampleToExperimentRule;
+
+    static
+    {
+        space1 = new GuardedDomain("space1", RoleLevel.SPACE);
+        space2 = new GuardedDomain("space2", RoleLevel.SPACE);
+        instance = new GuardedDomain("instance", RoleLevel.INSTANCE);
+
+        // (space1 power and space2 power) or
+        // (space1 user and space2 user and instance1 etl_server) or
+        // instance_admin
+
+        AuthorizationRule powerUsers =
+                and(rule(space1, RoleWithHierarchy.SPACE_POWER_USER),
+                        rule(space2, RoleWithHierarchy.SPACE_POWER_USER));
+
+        AuthorizationRule users =
+                and(rule(space1, RoleWithHierarchy.SPACE_USER),
+                        rule(space2, RoleWithHierarchy.SPACE_USER), rule(instance,
+                                RoleWithHierarchy.INSTANCE_ETL_SERVER));
+
+        AuthorizationRule admins = rule(instance, RoleWithHierarchy.INSTANCE_ADMIN);
+
+        assignSampleToExperimentRule = or(powerUsers, users, admins);
+    }
+
     @DataProvider(name = "rolesAllowedToUpdateExperimentOfSample")
     public static Object[][] rolesAllowedToAssignSampleToExperiment()
     {
-        RolePermutator rp =
-                new RolePermutator(2, RoleWithHierarchy.SPACE_POWER_USER);
-        return rp.getAcceptedPermutations();
+        return RolePermutator.getAcceptedPermutations(assignSampleToExperimentRule, space1, space2,
+                instance);
     }
 
     @DataProvider(name = "rolesNotAllowedToUpdateExperimentOfSample")
     public static Object[][] rolesNotAllowedToAssignSampleToExperiment()
     {
-        RolePermutator rp =
-                new RolePermutator(2, RoleWithHierarchy.SPACE_POWER_USER);
-        return rp.getRejectedPermutations();
+        return RolePermutator.getAcceptedPermutations(not(assignSampleToExperimentRule), space1,
+                space2, instance);
+
     }
 
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/BaseTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/BaseTest.java
index 77ce0c981a2c9564edc13d2bc9e0202fb0f5ce33..46a65e300f7648fb25379199e92532402def74c2 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/BaseTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/BaseTest.java
@@ -57,6 +57,23 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.IGenericClientService;
 import ch.systemsx.cisd.openbis.plugin.generic.shared.IGenericServer;
+import ch.systemsx.cisd.openbis.systemtest.base.builder.Builder;
+import ch.systemsx.cisd.openbis.systemtest.base.builder.DataSetUpdateBuilder;
+import ch.systemsx.cisd.openbis.systemtest.base.builder.ExperimentBuilder;
+import ch.systemsx.cisd.openbis.systemtest.base.builder.ExperimentUpdateBuilder;
+import ch.systemsx.cisd.openbis.systemtest.base.builder.ExternalDataBuilder;
+import ch.systemsx.cisd.openbis.systemtest.base.builder.ProjectBuilder;
+import ch.systemsx.cisd.openbis.systemtest.base.builder.ProjectUpdateBuilder;
+import ch.systemsx.cisd.openbis.systemtest.base.builder.SampleBuilder;
+import ch.systemsx.cisd.openbis.systemtest.base.builder.SampleUpdateBuilder;
+import ch.systemsx.cisd.openbis.systemtest.base.builder.SessionBuilder;
+import ch.systemsx.cisd.openbis.systemtest.base.builder.SpaceBuilder;
+import ch.systemsx.cisd.openbis.systemtest.base.builder.UpdateBuilder;
+import ch.systemsx.cisd.openbis.systemtest.base.matcher.CollectionContainsExactlyMatcher;
+import ch.systemsx.cisd.openbis.systemtest.base.matcher.InExperimentMatcher;
+import ch.systemsx.cisd.openbis.systemtest.base.matcher.InProjectMatcher;
+import ch.systemsx.cisd.openbis.systemtest.base.matcher.InSampleMatcher;
+import ch.systemsx.cisd.openbis.systemtest.base.matcher.InSpaceMatcher;
 
 /**
  * @author anttil
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/RolePermutator.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/RolePermutator.java
deleted file mode 100644
index a3e49a2f3bed14a47fbf9fe06d34559fe717c9f5..0000000000000000000000000000000000000000
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/RolePermutator.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * 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.systemtest.base;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
-
-/**
- * @author anttil
- */
-public class RolePermutator
-{
-
-    public static Collection<RoleWithHierarchy> allInstanceRoles = new HashSet<RoleWithHierarchy>();
-
-    public static Collection<RoleWithHierarchy> allSpaceRoles = new HashSet<RoleWithHierarchy>();
-
-    private final int numSpaces;
-
-    private final RoleWithHierarchy[] limits;
-
-    {
-        allInstanceRoles.add(RoleWithHierarchy.INSTANCE_ADMIN);
-        allInstanceRoles.add(RoleWithHierarchy.INSTANCE_ETL_SERVER);
-        allInstanceRoles.add(RoleWithHierarchy.INSTANCE_OBSERVER);
-        allInstanceRoles.add(null);
-
-        allSpaceRoles.add(RoleWithHierarchy.SPACE_ADMIN);
-        allSpaceRoles.add(RoleWithHierarchy.SPACE_ETL_SERVER);
-        allSpaceRoles.add(RoleWithHierarchy.SPACE_POWER_USER);
-        allSpaceRoles.add(RoleWithHierarchy.SPACE_USER);
-        allSpaceRoles.add(RoleWithHierarchy.SPACE_OBSERVER);
-        allSpaceRoles.add(null);
-    }
-
-    public RolePermutator(int numSpaces, RoleWithHierarchy... limits)
-    {
-        this.numSpaces = numSpaces;
-        this.limits = limits;
-
-    }
-
-    public RoleWithHierarchy[][] getAcceptedPermutations()
-    {
-        return toNestedArray(acceptedRoles(numSpaces, limits));
-    }
-
-    public RoleWithHierarchy[][] getRejectedPermutations()
-    {
-        return toNestedArray(rejectedRoles(numSpaces, limits));
-    }
-
-    public static RoleWithHierarchy[][] toNestedArray(Collection<List<RoleWithHierarchy>> input)
-    {
-        RoleWithHierarchy[][] result = new RoleWithHierarchy[input.size()][];
-        int index = 0;
-        for (List<RoleWithHierarchy> roles : input)
-        {
-            result[index] = roles.toArray(new RoleWithHierarchy[0]);
-            index++;
-        }
-        return result;
-    }
-
-    public static Collection<List<RoleWithHierarchy>> acceptedRoles(int numSpaceRoles,
-            RoleWithHierarchy... limits)
-    {
-        Collection<RoleWithHierarchy> acceptedRoles = new HashSet<RoleWithHierarchy>();
-        for (RoleWithHierarchy limit : limits)
-        {
-            acceptedRoles.addAll(limit.getRoles());
-        }
-
-        Collection<List<RoleWithHierarchy>> results = new HashSet<List<RoleWithHierarchy>>();
-        for (RoleWithHierarchy instanceRole : allInstanceRoles)
-        {
-            for (List<RoleWithHierarchy> spaceRoles : getSpaceRoleCombinations(numSpaceRoles))
-            {
-                if (acceptedRoles.contains(instanceRole) || acceptedRoles.containsAll(spaceRoles))
-                {
-                    List<RoleWithHierarchy> result = new ArrayList<RoleWithHierarchy>();
-                    for (RoleWithHierarchy spaceRole : spaceRoles)
-                    {
-                        result.add(spaceRole);
-                    }
-                    result.add(instanceRole);
-                    results.add(result);
-                }
-            }
-        }
-        return results;
-    }
-
-    public static Collection<List<RoleWithHierarchy>> rejectedRoles(int numSpaceRoles,
-            RoleWithHierarchy... limits)
-    {
-        Collection<List<RoleWithHierarchy>> allCombinations = getAllRoleCombinations(numSpaceRoles);
-        Collection<List<RoleWithHierarchy>> acceptedCombinations =
-                acceptedRoles(numSpaceRoles, limits);
-        allCombinations.removeAll(acceptedCombinations);
-        return allCombinations;
-    }
-
-    public static Collection<List<RoleWithHierarchy>> getSpaceRoleCombinations(int num)
-    {
-        Collection<List<RoleWithHierarchy>> result = new HashSet<List<RoleWithHierarchy>>();
-        if (num == 0)
-        {
-            return result;
-        }
-
-        Collection<List<RoleWithHierarchy>> subLists = getSpaceRoleCombinations(num - 1);
-
-        for (RoleWithHierarchy role : allSpaceRoles)
-        {
-            if (subLists.size() == 0)
-            {
-                List<RoleWithHierarchy> list = new ArrayList<RoleWithHierarchy>();
-                list.add(role);
-                result.add(list);
-            } else
-            {
-                for (List<RoleWithHierarchy> subList : subLists)
-                {
-                    List<RoleWithHierarchy> list = new ArrayList<RoleWithHierarchy>();
-                    list.add(role);
-                    list.addAll(subList);
-                    result.add(list);
-                }
-            }
-        }
-        return result;
-    }
-
-    public static Collection<List<RoleWithHierarchy>> getAllRoleCombinations(int numSpaceRoles)
-    {
-        Collection<List<RoleWithHierarchy>> result = new HashSet<List<RoleWithHierarchy>>();
-
-        for (List<RoleWithHierarchy> spaceRoles : getSpaceRoleCombinations(numSpaceRoles))
-        {
-            for (RoleWithHierarchy instanceRole : allInstanceRoles)
-            {
-                List<RoleWithHierarchy> list = new ArrayList<RoleWithHierarchy>();
-                list.addAll(spaceRoles);
-                list.add(instanceRole);
-
-                if (containsOnlyNulls(list))
-                {
-                    continue;
-                }
-
-                result.add(list);
-            }
-        }
-        return result;
-    }
-
-    public static boolean containsOnlyNulls(Collection<?> collection)
-    {
-        for (Object o : collection)
-        {
-            if (o != null)
-            {
-                return false;
-            }
-        }
-        return true;
-    }
-
-}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/AndAuthorizationRule.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/AndAuthorizationRule.java
new file mode 100644
index 0000000000000000000000000000000000000000..a2a54a0dc4db375cff3eefc2b9ab2ee2267b3861
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/AndAuthorizationRule.java
@@ -0,0 +1,44 @@
+/*
+ * 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.systemtest.base.auth;
+
+import java.util.Map;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
+
+/**
+ * @author anttil
+ */
+public class AndAuthorizationRule implements AuthorizationRule
+{
+    private final AuthorizationRule rule1;
+
+    private final AuthorizationRule rule2;
+
+    public AndAuthorizationRule(AuthorizationRule rule1, AuthorizationRule rule2)
+    {
+        this.rule1 = rule1;
+        this.rule2 = rule2;
+    }
+
+    @Override
+    public boolean accepts(Map<GuardedDomain, RoleWithHierarchy> roles)
+    {
+        return this.rule1.accepts(roles) && this.rule2.accepts(roles);
+    }
+
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/AuthorizationRule.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/AuthorizationRule.java
new file mode 100644
index 0000000000000000000000000000000000000000..75002e1b2bb48ecf7b9f87bf8a770eb9da692abd
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/AuthorizationRule.java
@@ -0,0 +1,29 @@
+/*
+ * 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.systemtest.base.auth;
+
+import java.util.Map;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
+
+/**
+ * @author anttil
+ */
+public interface AuthorizationRule
+{
+    public boolean accepts(Map<GuardedDomain, RoleWithHierarchy> roles);
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/BasicAuthorizationRule.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/BasicAuthorizationRule.java
new file mode 100644
index 0000000000000000000000000000000000000000..397ae48937468ece97ee0eb6190ec32a4e644738
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/BasicAuthorizationRule.java
@@ -0,0 +1,67 @@
+/*
+ * 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.systemtest.base.auth;
+
+import java.util.Map;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
+
+/**
+ * @author anttil
+ */
+public class BasicAuthorizationRule implements AuthorizationRule
+{
+
+    private final RoleWithHierarchy limit;
+
+    private final GuardedDomain domain;
+
+    public BasicAuthorizationRule(GuardedDomain domain, RoleWithHierarchy limit)
+    {
+        switch (domain.getType())
+        {
+            case SPACE:
+                if (!limit.isSpaceLevel())
+                {
+                    throw new IllegalArgumentException("Invalid limit for space: " + limit);
+                }
+                break;
+            case INSTANCE:
+                if (!limit.isInstanceLevel())
+                {
+                    throw new IllegalArgumentException("Invalid limit for instance: " + limit);
+                }
+                break;
+            default:
+                throw new IllegalArgumentException("Unknown domain type " + domain.getType());
+        }
+        this.limit = limit;
+        this.domain = domain;
+    }
+
+    @Override
+    public boolean accepts(Map<GuardedDomain, RoleWithHierarchy> roles)
+    {
+        RoleWithHierarchy role = roles.get(this.domain);
+        if (role == null)
+        {
+            return false;
+        }
+
+        return this.limit.getRoles().contains(role);
+    }
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/GuardedDomain.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/GuardedDomain.java
new file mode 100644
index 0000000000000000000000000000000000000000..fbfbb4309ae5381c0f6563b12b1449c9a917244e
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/GuardedDomain.java
@@ -0,0 +1,74 @@
+/*
+ * 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.systemtest.base.auth;
+
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleLevel;
+
+/**
+ * @author anttil
+ */
+public class GuardedDomain
+{
+    private final String name;
+
+    private final RoleLevel type;
+
+    public GuardedDomain(String name, RoleLevel type)
+    {
+        this.name = name;
+        this.type = type;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public RoleLevel getType()
+    {
+        return type;
+    }
+
+    @Override
+    public boolean equals(Object o)
+    {
+        if (!(o instanceof GuardedDomain))
+        {
+            return false;
+        }
+
+        GuardedDomain domain = (GuardedDomain) o;
+        return domain.getName().equals(this.name) && domain.getType().equals(this.type);
+    }
+
+    @Override
+    public int hashCode()
+    {
+        HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(this.name);
+        builder.append(this.type);
+        return builder.toHashCode();
+    }
+
+    @Override
+    public String toString()
+    {
+        return this.name + " (" + this.type + ")";
+    }
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/NotAuthorizationRule.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/NotAuthorizationRule.java
new file mode 100644
index 0000000000000000000000000000000000000000..8eb27bc1a2e748d2a2e7b29ddb75392426bc9ff0
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/NotAuthorizationRule.java
@@ -0,0 +1,42 @@
+/*
+ * 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.systemtest.base.auth;
+
+import java.util.Map;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
+
+/**
+ * @author anttil
+ */
+public class NotAuthorizationRule implements AuthorizationRule
+{
+
+    private final AuthorizationRule rule;
+
+    public NotAuthorizationRule(AuthorizationRule rule)
+    {
+        this.rule = rule;
+    }
+
+    @Override
+    public boolean accepts(Map<GuardedDomain, RoleWithHierarchy> roles)
+    {
+        return !this.rule.accepts(roles);
+    }
+
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/OrAuthorizationRule.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/OrAuthorizationRule.java
new file mode 100644
index 0000000000000000000000000000000000000000..4962b5c51a0d5311f00a6c12a363b7c1eb842ef8
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/OrAuthorizationRule.java
@@ -0,0 +1,43 @@
+/*
+ * 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.systemtest.base.auth;
+
+import java.util.Map;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
+
+/**
+ * @author anttil
+ */
+public class OrAuthorizationRule implements AuthorizationRule
+{
+    private final AuthorizationRule rule1;
+
+    private final AuthorizationRule rule2;
+
+    public OrAuthorizationRule(AuthorizationRule rule1, AuthorizationRule rule2)
+    {
+        this.rule1 = rule1;
+        this.rule2 = rule2;
+    }
+
+    @Override
+    public boolean accepts(Map<GuardedDomain, RoleWithHierarchy> roles)
+    {
+        return this.rule1.accepts(roles) || this.rule2.accepts(roles);
+    }
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/RolePermutator.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/RolePermutator.java
new file mode 100644
index 0000000000000000000000000000000000000000..2e850062afc81c81282409bd3e48601c613f22aa
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/RolePermutator.java
@@ -0,0 +1,171 @@
+/*
+ * 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.systemtest.base.auth;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleLevel;
+
+/**
+ * @author anttil
+ */
+public class RolePermutator
+{
+
+    public static RoleWithHierarchy[][] getAcceptedPermutations(AuthorizationRule rule,
+            GuardedDomain... domains)
+    {
+        Collection<Map<GuardedDomain, RoleWithHierarchy>> accepted =
+                new HashSet<Map<GuardedDomain, RoleWithHierarchy>>();
+
+        for (Map<GuardedDomain, RoleWithHierarchy> permutation : getAllPermutations(Arrays
+                .asList(domains)))
+        {
+            if (rule.accepts(permutation) && !containsOnlyNulls(permutation.values()))
+            {
+                accepted.add(permutation);
+            }
+        }
+        return toNestedArray(accepted, domains);
+    }
+
+    public static Collection<Map<GuardedDomain, RoleWithHierarchy>> getAllPermutations(
+            List<GuardedDomain> domains)
+    {
+        Collection<Map<GuardedDomain, RoleWithHierarchy>> result =
+                new HashSet<Map<GuardedDomain, RoleWithHierarchy>>();
+        if (domains.size() == 0)
+        {
+            return result;
+        }
+
+        GuardedDomain domain = domains.get(0);
+        for (RoleWithHierarchy role : getAllRolesFor(domain.getType()))
+        {
+            Collection<Map<GuardedDomain, RoleWithHierarchy>> subpermutations =
+                    getAllPermutations(restOf(domains));
+            if (subpermutations.size() > 0)
+            {
+                for (Map<GuardedDomain, RoleWithHierarchy> rest : subpermutations)
+                {
+                    Map<GuardedDomain, RoleWithHierarchy> map =
+                            new HashMap<GuardedDomain, RoleWithHierarchy>();
+                    map.put(domain, role);
+                    map.putAll(rest);
+                    result.add(map);
+                }
+            } else
+            {
+                Map<GuardedDomain, RoleWithHierarchy> map =
+                        new HashMap<GuardedDomain, RoleWithHierarchy>();
+                map.put(domain, role);
+                result.add(map);
+            }
+        }
+        return result;
+    }
+
+    public static <T> List<T> restOf(List<T> list)
+    {
+        if (list.size() == 0)
+        {
+            throw new IllegalArgumentException("0");
+        }
+
+        if (list.size() == 1)
+        {
+            return new ArrayList<T>();
+        }
+
+        return list.subList(1, list.size());
+    }
+
+    public static Collection<RoleWithHierarchy> getAllRolesFor(RoleLevel level)
+    {
+        if (RoleLevel.SPACE.equals(level))
+        {
+            return allSpaceRoles;
+        } else if (RoleLevel.INSTANCE.equals(level))
+        {
+            return allInstanceRoles;
+        } else
+        {
+            throw new IllegalArgumentException(level.toString());
+        }
+    }
+
+    public static RoleWithHierarchy[][] toNestedArray(
+            Collection<Map<GuardedDomain, RoleWithHierarchy>> input, GuardedDomain[] order)
+    {
+        RoleWithHierarchy[][] result = new RoleWithHierarchy[input.size()][];
+        int index = 0;
+        for (Map<GuardedDomain, RoleWithHierarchy> permutation : input)
+        {
+            RoleWithHierarchy[] roles = new RoleWithHierarchy[permutation.size()];
+            int subIndex = 0;
+            for (GuardedDomain d : order)
+            {
+                roles[subIndex] = permutation.get(d);
+                subIndex++;
+            }
+            result[index] = roles;
+            index++;
+        }
+        return result;
+    }
+
+    public static boolean containsOnlyNulls(Collection<?> collection)
+    {
+        for (Object o : collection)
+        {
+            if (o != null)
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static final Collection<RoleWithHierarchy> allInstanceRoles;
+
+    public static final Collection<RoleWithHierarchy> allSpaceRoles;
+
+    static
+    {
+        allInstanceRoles = new HashSet<RoleWithHierarchy>();
+        allSpaceRoles = new HashSet<RoleWithHierarchy>();
+
+        allInstanceRoles.add(RoleWithHierarchy.INSTANCE_ADMIN);
+        allInstanceRoles.add(RoleWithHierarchy.INSTANCE_ETL_SERVER);
+        allInstanceRoles.add(RoleWithHierarchy.INSTANCE_OBSERVER);
+        allInstanceRoles.add(null);
+
+        allSpaceRoles.add(RoleWithHierarchy.SPACE_ADMIN);
+        allSpaceRoles.add(RoleWithHierarchy.SPACE_ETL_SERVER);
+        allSpaceRoles.add(RoleWithHierarchy.SPACE_POWER_USER);
+        allSpaceRoles.add(RoleWithHierarchy.SPACE_USER);
+        allSpaceRoles.add(RoleWithHierarchy.SPACE_OBSERVER);
+        allSpaceRoles.add(null);
+    }
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/RuleBuilder.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/RuleBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..13d4ef2ad43ba2bba596ca9e87f7280627427279
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/auth/RuleBuilder.java
@@ -0,0 +1,59 @@
+/*
+ * 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.systemtest.base.auth;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy;
+
+/**
+ * @author anttil
+ */
+public class RuleBuilder
+{
+
+    public static AuthorizationRule rule(GuardedDomain domain, RoleWithHierarchy role)
+    {
+        return new BasicAuthorizationRule(domain, role);
+    }
+
+    public static AuthorizationRule and(AuthorizationRule rule1, AuthorizationRule rule2,
+            AuthorizationRule... rest)
+    {
+        AuthorizationRule main = new AndAuthorizationRule(rule1, rule2);
+        for (AuthorizationRule rule : rest)
+        {
+            main = new AndAuthorizationRule(main, rule);
+        }
+        return main;
+    }
+
+    public static AuthorizationRule or(AuthorizationRule rule1, AuthorizationRule rule2,
+            AuthorizationRule... rest)
+    {
+        AuthorizationRule main = new OrAuthorizationRule(rule1, rule2);
+        for (AuthorizationRule rule : rest)
+        {
+            main = new OrAuthorizationRule(main, rule);
+        }
+        return main;
+    }
+
+    public static AuthorizationRule not(AuthorizationRule rule)
+    {
+        return new NotAuthorizationRule(rule);
+    }
+
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/Builder.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/Builder.java
similarity index 93%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/Builder.java
rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/Builder.java
index 1c0dfca29c2315fcb5bc6040756ed84c70cafc7c..ed56bd754881ce38797dd860737c44d242d387bc 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/Builder.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/Builder.java
@@ -14,11 +14,12 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.systemtest.base;
+package ch.systemsx.cisd.openbis.systemtest.base.builder;
 
 import ch.systemsx.cisd.openbis.generic.server.ICommonServerForInternalUse;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.plugin.generic.shared.IGenericServer;
+import ch.systemsx.cisd.openbis.systemtest.base.BaseTest;
 
 /**
  * @author anttil
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/DataSetUpdateBuilder.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/DataSetUpdateBuilder.java
similarity index 98%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/DataSetUpdateBuilder.java
rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/DataSetUpdateBuilder.java
index 7d12d2fc1ef679e969fac37cfe4801f077ae732f..aa67297b34ee73073f9db8cb70a37fee8039bb73 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/DataSetUpdateBuilder.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/DataSetUpdateBuilder.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.systemtest.base;
+package ch.systemsx.cisd.openbis.systemtest.base.builder;
 
 import static ch.systemsx.cisd.openbis.systemtest.base.BaseTest.id;
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/ExperimentBuilder.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/ExperimentBuilder.java
similarity index 98%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/ExperimentBuilder.java
rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/ExperimentBuilder.java
index 490fef9580b73763930ba3cf80b9fb79775db43d..0f140ccedac14f0cd2c37c4a1781696c96fef948 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/ExperimentBuilder.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/ExperimentBuilder.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.systemtest.base;
+package ch.systemsx.cisd.openbis.systemtest.base.builder;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/ExperimentUpdateBuilder.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/ExperimentUpdateBuilder.java
similarity index 98%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/ExperimentUpdateBuilder.java
rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/ExperimentUpdateBuilder.java
index e023f6547e048f9266b42db1b9a6e9dbecbd11cf..0401bafca95da3577796f30ce95052fd55b4ddcd 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/ExperimentUpdateBuilder.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/ExperimentUpdateBuilder.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.systemtest.base;
+package ch.systemsx.cisd.openbis.systemtest.base.builder;
 
 import java.util.ArrayList;
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/ExternalDataBuilder.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/ExternalDataBuilder.java
similarity index 98%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/ExternalDataBuilder.java
rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/ExternalDataBuilder.java
index 1078d7c6ab355503fc4b5729ac26b984d78e4a58..bc5e2015d1d7fef965a707511c8bfe9b76c2788d 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/ExternalDataBuilder.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/ExternalDataBuilder.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.systemtest.base;
+package ch.systemsx.cisd.openbis.systemtest.base.builder;
 
 import static ch.systemsx.cisd.openbis.systemtest.base.BaseTest.id;
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/ProjectBuilder.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/ProjectBuilder.java
similarity index 97%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/ProjectBuilder.java
rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/ProjectBuilder.java
index 14b476da7c84f06a2489814b45039d24b217cac3..dd47fc5dc5877ad83fea82a3bd4a1ab480525758 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/ProjectBuilder.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/ProjectBuilder.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.systemtest.base;
+package ch.systemsx.cisd.openbis.systemtest.base.builder;
 
 import java.util.ArrayList;
 import java.util.UUID;
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/ProjectUpdateBuilder.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/ProjectUpdateBuilder.java
similarity index 97%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/ProjectUpdateBuilder.java
rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/ProjectUpdateBuilder.java
index 9426fbdb2b3230c8052d33652e1e58e168ca6c62..3426148731ff5c0213a7203c6f608fcc33e0cc84 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/ProjectUpdateBuilder.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/ProjectUpdateBuilder.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.systemtest.base;
+package ch.systemsx.cisd.openbis.systemtest.base.builder;
 
 import java.util.ArrayList;
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/SampleBuilder.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/SampleBuilder.java
similarity index 98%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/SampleBuilder.java
rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/SampleBuilder.java
index 2aebd20615f2a8e2c24fa81b07df3672b7f16a60..a7186206a439c0a36825f0e3321f284b4f0f7d3e 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/SampleBuilder.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/SampleBuilder.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.systemtest.base;
+package ch.systemsx.cisd.openbis.systemtest.base.builder;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/SampleUpdateBuilder.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/SampleUpdateBuilder.java
similarity index 98%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/SampleUpdateBuilder.java
rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/SampleUpdateBuilder.java
index f5dc45038c4506aeee774786d2f5cde7978d697c..17a30347cb87f046c4f2b182bf11b8853f6abbf6 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/SampleUpdateBuilder.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/SampleUpdateBuilder.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.systemtest.base;
+package ch.systemsx.cisd.openbis.systemtest.base.builder;
 
 import static ch.systemsx.cisd.openbis.systemtest.base.BaseTest.id;
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/SessionBuilder.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/SessionBuilder.java
similarity index 98%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/SessionBuilder.java
rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/SessionBuilder.java
index ae35f8cb56b78be9ac3d9a01c95fd9f30f6ef71b..3d670c0b609eabf7fe53b5fe268aa41866c767ec 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/SessionBuilder.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/SessionBuilder.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.systemtest.base;
+package ch.systemsx.cisd.openbis.systemtest.base.builder;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/SpaceBuilder.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/SpaceBuilder.java
similarity index 97%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/SpaceBuilder.java
rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/SpaceBuilder.java
index 41ba10dd9169cabea77c8f463829c68813a4d4ed..6f7d7b220225202388aa9bc0988f3f26c4972c5e 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/SpaceBuilder.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/SpaceBuilder.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.systemtest.base;
+package ch.systemsx.cisd.openbis.systemtest.base.builder;
 
 import java.util.UUID;
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/UpdateBuilder.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/UpdateBuilder.java
similarity index 95%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/UpdateBuilder.java
rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/UpdateBuilder.java
index 27f4c9e9ad2c61218231419e8e1fbb951a98f4ef..f58d3e405f6b29edca8570bae98943b2cdadbe54 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/UpdateBuilder.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/builder/UpdateBuilder.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.systemtest.base;
+package ch.systemsx.cisd.openbis.systemtest.base.builder;
 
 import ch.systemsx.cisd.openbis.generic.server.ICommonServerForInternalUse;
 import ch.systemsx.cisd.openbis.plugin.generic.shared.IGenericServer;
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/CollectionContainsExactlyMatcher.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/matcher/CollectionContainsExactlyMatcher.java
similarity index 94%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/CollectionContainsExactlyMatcher.java
rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/matcher/CollectionContainsExactlyMatcher.java
index 745e87039a0de94635e3efe40ef2524130b768c5..a1891e4b6536895b9e0761d5a972c0c67832d27b 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/CollectionContainsExactlyMatcher.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/matcher/CollectionContainsExactlyMatcher.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.systemtest.base;
+package ch.systemsx.cisd.openbis.systemtest.base.matcher;
 
 import java.util.Collection;
 import java.util.HashSet;
@@ -22,6 +22,8 @@ import java.util.HashSet;
 import org.hamcrest.Description;
 import org.hamcrest.TypeSafeMatcher;
 
+import ch.systemsx.cisd.openbis.systemtest.base.EqualityChecker;
+
 public class CollectionContainsExactlyMatcher<T> extends TypeSafeMatcher<Collection<T>>
 {
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/InExperimentMatcher.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/matcher/InExperimentMatcher.java
similarity index 96%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/InExperimentMatcher.java
rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/matcher/InExperimentMatcher.java
index 591d280dd3dd42cbe50c8e881c837975acd3738f..302829512170696a30f47b2ec039dec03ca1af94 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/InExperimentMatcher.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/matcher/InExperimentMatcher.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.systemtest.base;
+package ch.systemsx.cisd.openbis.systemtest.base.matcher;
 
 import org.hamcrest.Description;
 import org.hamcrest.TypeSafeMatcher;
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/InProjectMatcher.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/matcher/InProjectMatcher.java
similarity index 95%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/InProjectMatcher.java
rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/matcher/InProjectMatcher.java
index 8fbd4f6e8bf00fb1e5c77827185f6985bab3e451..7d61c8f90a89e8bba1d70b7c61f9df7c24c411eb 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/InProjectMatcher.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/matcher/InProjectMatcher.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.systemtest.base;
+package ch.systemsx.cisd.openbis.systemtest.base.matcher;
 
 import org.hamcrest.Description;
 import org.hamcrest.TypeSafeMatcher;
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/InSampleMatcher.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/matcher/InSampleMatcher.java
similarity index 95%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/InSampleMatcher.java
rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/matcher/InSampleMatcher.java
index d9d7b0e0c0b43b557568dfbc29eaa7fbde87e643..7f62a9fb8d508428e6074d0bb0664ef095276534 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/InSampleMatcher.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/matcher/InSampleMatcher.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.systemtest.base;
+package ch.systemsx.cisd.openbis.systemtest.base.matcher;
 
 import org.hamcrest.Description;
 import org.hamcrest.TypeSafeMatcher;
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/InSpaceMatcher.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/matcher/InSpaceMatcher.java
similarity index 96%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/InSpaceMatcher.java
rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/matcher/InSpaceMatcher.java
index 1b1c5373b114125e56fe29862095dd76500034fd..062c7f2527169914fc2244265792b997b52fede2 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/InSpaceMatcher.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/matcher/InSpaceMatcher.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.systemtest.base;
+package ch.systemsx.cisd.openbis.systemtest.base.matcher;
 
 import org.hamcrest.Description;
 import org.hamcrest.TypeSafeMatcher;