From 75b66a13b09935dba9b30cecb58e9c77d3aea80b Mon Sep 17 00:00:00 2001
From: anttil <anttil>
Date: Mon, 1 Oct 2012 14:31:38 +0000
Subject: [PATCH] SWE-2 / SP-314 : Working towards tab browsing

SVN: 26897
---
 .../application/DummyApplicationRunner.java   | 156 ++++++++++++++++++
 .../application/GuiApplicationRunner.java     | 104 +++++++++++-
 .../PublicApiApplicationRunner.java           |  24 ---
 .../uitest/infra/dsl/DslSampleBrowser.java    |  50 ++++++
 ...ntMatcher.java => CellContentMatcher.java} |  46 +++---
 ...er.java => CollectionContainsMatcher.java} |  18 +-
 ...laysMatcher.java => RowExistsMatcher.java} |  17 +-
 .../infra/uid/DictionaryUidGenerator.java     |   4 +-
 .../page/tab/AssignSamplePropertyType.java    |   2 +-
 .../cisd/openbis/uitest/page/tab/Browser.java |  53 +++++-
 .../openbis/uitest/page/tab/BrowserRow.java   |  12 ++
 .../uitest/page/tab/DataSetTypeBrowser.java   |  74 +++++++++
 .../uitest/page/tab/ExperimentBrowser.java    |  34 ++--
 .../page/tab/ExperimentTypeBrowser.java       |  32 ++--
 .../uitest/page/tab/ProjectBrowser.java       |  31 ++--
 .../tab/PropertyTypeAssignmentBrowser.java    |  31 ++--
 .../uitest/page/tab/PropertyTypeBrowser.java  |  31 ++--
 .../page/tab/RoleAssignmentBrowser.java       |  42 +++--
 .../uitest/page/tab/SampleBrowser.java        |  43 ++---
 .../uitest/page/tab/SampleTypeBrowser.java    |  32 ++--
 .../openbis/uitest/page/tab/SpaceBrowser.java |  32 ++--
 .../uitest/page/tab/VocabularyBrowser.java    |  31 ++--
 .../openbis/uitest/suite/ExperimentTest.java  |   4 +-
 .../uitest/suite/ExperimentTypeTest.java      |   2 +-
 .../openbis/uitest/suite/ProjectTest.java     |   2 +-
 .../suite/PropertyTypeAssignmentTest.java     |   6 +-
 .../uitest/suite/PropertyTypeTest.java        |   2 +-
 .../cisd/openbis/uitest/suite/SampleTest.java |   8 +-
 .../openbis/uitest/suite/SampleTypeTest.java  |   6 +-
 .../openbis/uitest/suite/SeleniumTest.java    | 129 +++------------
 .../cisd/openbis/uitest/suite/SpaceTest.java  |   5 +-
 .../cisd/openbis/uitest/suite/SprintTest.java |  23 ++-
 .../openbis/uitest/suite/VocabularyTest.java  |   2 +-
 .../cisd/openbis/uitest/type/Browsable.java   |  10 +-
 .../cisd/openbis/uitest/type/DataSet.java     |  27 ++-
 .../cisd/openbis/uitest/type/DataSetType.java |  45 ++++-
 .../cisd/openbis/uitest/type/Experiment.java  |  44 ++++-
 .../openbis/uitest/type/ExperimentType.java   |  45 ++++-
 .../cisd/openbis/uitest/type/Project.java     |  45 ++++-
 .../openbis/uitest/type/PropertyType.java     |  71 ++++----
 .../uitest/type/PropertyTypeAssignment.java   |  69 +++++---
 .../type/PropertyTypeAssignmentBuilder.java   |   4 +-
 .../cisd/openbis/uitest/type/Sample.java      |  58 +++++--
 .../openbis/uitest/type/SampleBuilder.java    |   2 +-
 .../cisd/openbis/uitest/type/SampleType.java  |  40 ++++-
 .../cisd/openbis/uitest/type/Space.java       |  49 ++++--
 .../cisd/openbis/uitest/type/Vocabulary.java  |  50 ++++--
 .../cisd/openbis/uitest/widget/Grid.java      |  28 ++++
 .../openbis/uitest/widget/SettingsDialog.java |   6 +
 .../cisd/openbis/uitest/widget/TreeGrid.java  |   4 -
 50 files changed, 1149 insertions(+), 536 deletions(-)
 create mode 100644 ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/application/DummyApplicationRunner.java
 create mode 100644 ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/dsl/DslSampleBrowser.java
 rename ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/{BrowserListsElementMatcher.java => CellContentMatcher.java} (54%)
 rename ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/{CellLinksToMatcher.java => CollectionContainsMatcher.java} (68%)
 rename ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/{CellDisplaysMatcher.java => RowExistsMatcher.java} (66%)
 create mode 100644 ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/DataSetTypeBrowser.java

diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/application/DummyApplicationRunner.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/application/DummyApplicationRunner.java
new file mode 100644
index 00000000000..49dcff7114a
--- /dev/null
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/application/DummyApplicationRunner.java
@@ -0,0 +1,156 @@
+/*
+ * 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.uitest.infra.application;
+
+import java.util.UUID;
+
+import ch.systemsx.cisd.openbis.uitest.type.DataSet;
+import ch.systemsx.cisd.openbis.uitest.type.DataSetType;
+import ch.systemsx.cisd.openbis.uitest.type.Experiment;
+import ch.systemsx.cisd.openbis.uitest.type.ExperimentType;
+import ch.systemsx.cisd.openbis.uitest.type.Project;
+import ch.systemsx.cisd.openbis.uitest.type.PropertyType;
+import ch.systemsx.cisd.openbis.uitest.type.PropertyTypeAssignment;
+import ch.systemsx.cisd.openbis.uitest.type.Sample;
+import ch.systemsx.cisd.openbis.uitest.type.SampleType;
+import ch.systemsx.cisd.openbis.uitest.type.Space;
+import ch.systemsx.cisd.openbis.uitest.type.Vocabulary;
+
+/**
+ * @author anttil
+ */
+public class DummyApplicationRunner implements ApplicationRunner
+{
+
+    @Override
+    public String uid()
+    {
+        return UUID.randomUUID().toString();
+    }
+
+    @Override
+    public void login(String userName, String password)
+    {
+    }
+
+    @Override
+    public void logout()
+    {
+    }
+
+    @Override
+    public Space create(Space space)
+    {
+        return null;
+    }
+
+    @Override
+    public void delete(Space space)
+    {
+    }
+
+    @Override
+    public Project create(Project project)
+    {
+        return null;
+    }
+
+    @Override
+    public void delete(Project project)
+    {
+    }
+
+    @Override
+    public SampleType create(SampleType sampleType)
+    {
+        return null;
+    }
+
+    @Override
+    public void update(SampleType sampleType)
+    {
+    }
+
+    @Override
+    public void delete(SampleType sampleType)
+    {
+    }
+
+    @Override
+    public ExperimentType create(ExperimentType experimentType)
+    {
+        return null;
+    }
+
+    @Override
+    public void delete(ExperimentType experimentType)
+    {
+
+    }
+
+    @Override
+    public PropertyType create(PropertyType propertyType)
+    {
+        return null;
+    }
+
+    @Override
+    public void delete(PropertyType propertyType)
+    {
+    }
+
+    @Override
+    public Vocabulary create(Vocabulary vocabulary)
+    {
+        return null;
+    }
+
+    @Override
+    public void delete(Vocabulary vocabulary)
+    {
+    }
+
+    @Override
+    public Sample create(Sample sample)
+    {
+        return null;
+    }
+
+    @Override
+    public Experiment create(Experiment experiment)
+    {
+        return null;
+    }
+
+    @Override
+    public PropertyTypeAssignment create(PropertyTypeAssignment assignment)
+    {
+        return null;
+    }
+
+    @Override
+    public DataSetType create(DataSetType type)
+    {
+        return null;
+    }
+
+    @Override
+    public DataSet create(DataSet dataSet)
+    {
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/application/GuiApplicationRunner.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/application/GuiApplicationRunner.java
index 27951ced46c..4b683a14f97 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/application/GuiApplicationRunner.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/application/GuiApplicationRunner.java
@@ -16,6 +16,8 @@
 
 package ch.systemsx.cisd.openbis.uitest.infra.application;
 
+import java.util.List;
+
 import ch.systemsx.cisd.openbis.uitest.infra.uid.UidGenerator;
 import ch.systemsx.cisd.openbis.uitest.infra.webdriver.PageProxy;
 import ch.systemsx.cisd.openbis.uitest.page.dialog.AddExperimentTypeDialog;
@@ -35,6 +37,7 @@ import ch.systemsx.cisd.openbis.uitest.page.tab.AddPropertyType;
 import ch.systemsx.cisd.openbis.uitest.page.tab.AssignSamplePropertyType;
 import ch.systemsx.cisd.openbis.uitest.page.tab.Browser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserRow;
+import ch.systemsx.cisd.openbis.uitest.page.tab.DataSetTypeBrowser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.ExperimentBrowser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.ExperimentTypeBrowser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.LoginPage;
@@ -50,6 +53,7 @@ import ch.systemsx.cisd.openbis.uitest.page.tab.SampleTypeBrowser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.SpaceBrowser;
 import ch.systemsx.cisd.openbis.uitest.page.tab.Trash;
 import ch.systemsx.cisd.openbis.uitest.page.tab.VocabularyBrowser;
+import ch.systemsx.cisd.openbis.uitest.type.Browsable;
 import ch.systemsx.cisd.openbis.uitest.type.DataSet;
 import ch.systemsx.cisd.openbis.uitest.type.DataSetType;
 import ch.systemsx.cisd.openbis.uitest.type.Experiment;
@@ -97,7 +101,7 @@ public class GuiApplicationRunner implements ApplicationRunner
     public void delete(Space space)
     {
         SpaceBrowser browser = browseToSpaceBrowser();
-        browser.filter(space);
+        browser.filterTo(space);
         BrowserRow row = browser.select(space);
         if (row.exists())
         {
@@ -118,7 +122,7 @@ public class GuiApplicationRunner implements ApplicationRunner
     public void delete(Project project)
     {
         ProjectBrowser browser = browseToProjectBrowser();
-        browser.filter(project);
+        browser.filterTo(project);
         BrowserRow row = browser.select(project);
         if (row.exists())
         {
@@ -130,7 +134,7 @@ public class GuiApplicationRunner implements ApplicationRunner
     public void delete(SampleType sampleType)
     {
         SampleTypeBrowser browser = browseToSampleTypeBrowser();
-        browser.filter(sampleType);
+        browser.filterTo(sampleType);
         BrowserRow row = browser.select(sampleType);
         if (row.exists())
         {
@@ -142,7 +146,7 @@ public class GuiApplicationRunner implements ApplicationRunner
     public void delete(ExperimentType experimentType)
     {
         ExperimentTypeBrowser browser = browseToExperimentTypeBrowser();
-        browser.filter(experimentType);
+        browser.filterTo(experimentType);
         BrowserRow row = browser.select(experimentType);
         if (row.exists())
         {
@@ -154,7 +158,7 @@ public class GuiApplicationRunner implements ApplicationRunner
     public void delete(PropertyType propertyType)
     {
         PropertyTypeBrowser browser = browseToPropertyTypeBrowser();
-        browser.filter(propertyType);
+        browser.filterTo(propertyType);
         BrowserRow row = browser.select(propertyType);
         if (row.exists())
         {
@@ -167,7 +171,7 @@ public class GuiApplicationRunner implements ApplicationRunner
     public void delete(Vocabulary vocabulary)
     {
         VocabularyBrowser browser = browseToVocabularyBrowser();
-        browser.filter(vocabulary);
+        browser.filterTo(vocabulary);
         BrowserRow row = browser.select(vocabulary);
         if (row.exists())
         {
@@ -253,7 +257,7 @@ public class GuiApplicationRunner implements ApplicationRunner
     public void update(SampleType sampleType)
     {
         SampleTypeBrowser browser = browseToSampleTypeBrowser();
-        browser.filter(sampleType);
+        browser.filterTo(sampleType);
         browser.select(sampleType);
         browser.edit();
         EditSampleTypeDialog dialog = proxy.get(EditSampleTypeDialog.class);
@@ -275,6 +279,84 @@ public class GuiApplicationRunner implements ApplicationRunner
         load(UserMenu.class).logout();
     }
 
+    public BrowserRow browseTo(Sample sample)
+    {
+        browseToSampleBrowser();
+        return getRow(SampleBrowser.class, sample);
+    }
+
+    public BrowserRow browseTo(SampleType type)
+    {
+        browseToSampleTypeBrowser();
+        return getRow(SampleTypeBrowser.class, type);
+    }
+
+    public BrowserRow browseTo(Vocabulary vocabulary)
+    {
+        browseToVocabularyBrowser();
+        return getRow(VocabularyBrowser.class, vocabulary);
+    }
+
+    public BrowserRow browseTo(Experiment experiment)
+    {
+        browseToExperimentBrowser();
+        return getRow(ExperimentBrowser.class, experiment);
+    }
+
+    public BrowserRow browseTo(ExperimentType type)
+    {
+        browseToExperimentTypeBrowser();
+        return getRow(ExperimentTypeBrowser.class, type);
+    }
+
+    public BrowserRow browseTo(Project project)
+    {
+        browseToProjectBrowser();
+        return getRow(ProjectBrowser.class, project);
+    }
+
+    public BrowserRow browseTo(PropertyTypeAssignment assignment)
+    {
+        browseToPropertyTypeAssignmentBrowser();
+        return getRow(PropertyTypeAssignmentBrowser.class, assignment);
+    }
+
+    public BrowserRow browseTo(PropertyType type)
+    {
+        browseToPropertyTypeBrowser();
+        return getRow(PropertyTypeBrowser.class, type);
+    }
+
+    public BrowserRow browseTo(Space space)
+    {
+        browseToSpaceBrowser();
+        return getRow(SpaceBrowser.class, space);
+    }
+
+    public BrowserRow browseTo(DataSetType type)
+    {
+        browseToDataSetTypeBrowser();
+        return getRow(DataSetTypeBrowser.class, type);
+    }
+
+    private <T extends Browsable> BrowserRow getRow(Class<? extends Browser<T>> browserClass,
+            T browsable)
+    {
+        load(browserClass).showColumnsOf(browsable);
+        load(browserClass).filterTo(browsable);
+        List<BrowserRow> rows = load(browserClass).getData();
+        if (rows.size() == 0)
+        {
+            return new BrowserRow();
+        } else if (rows.size() == 1)
+        {
+            return rows.get(0);
+        } else
+        {
+            throw new IllegalStateException("multiple rows found:\n" + rows);
+        }
+    }
+
     public SampleTypeBrowser browseToSampleTypeBrowser()
     {
         getMenus().admin();
@@ -291,6 +373,14 @@ public class GuiApplicationRunner implements ApplicationRunner
         return getBrowser(ExperimentTypeBrowser.class);
     }
 
+    public DataSetTypeBrowser browseToDataSetTypeBrowser()
+    {
+        getMenus().admin();
+        load(AdminMenu.class).types();
+        load(TypesMenu.class).experimentTypes();
+        return getBrowser(DataSetTypeBrowser.class);
+    }
+
     public Trash browseToTrash()
     {
         getMenus().trash();
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/application/PublicApiApplicationRunner.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/application/PublicApiApplicationRunner.java
index 41981634504..b2a21a1b3aa 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/application/PublicApiApplicationRunner.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/application/PublicApiApplicationRunner.java
@@ -84,99 +84,77 @@ public class PublicApiApplicationRunner implements ApplicationRunner
     @Override
     public void logout()
     {
-        // TODO Auto-generated method stub
-
     }
 
     @Override
     public Space create(Space space)
     {
-        // TODO Auto-generated method stub
         return null;
     }
 
     @Override
     public void delete(Space space)
     {
-        // TODO Auto-generated method stub
-
     }
 
     @Override
     public Project create(Project project)
     {
-        // TODO Auto-generated method stub
         return null;
     }
 
     @Override
     public void delete(Project project)
     {
-        // TODO Auto-generated method stub
-
     }
 
     @Override
     public SampleType create(SampleType sampleType)
     {
-        // TODO Auto-generated method stub
         return null;
     }
 
     @Override
     public void update(SampleType sampleType)
     {
-        // TODO Auto-generated method stub
-
     }
 
     @Override
     public void delete(SampleType sampleType)
     {
-        // TODO Auto-generated method stub
-
     }
 
     @Override
     public ExperimentType create(ExperimentType experimentType)
     {
-        // TODO Auto-generated method stub
         return null;
     }
 
     @Override
     public void delete(ExperimentType experimentType)
     {
-        // TODO Auto-generated method stub
-
     }
 
     @Override
     public PropertyType create(PropertyType propertyType)
     {
-        // TODO Auto-generated method stub
         return null;
     }
 
     @Override
     public void delete(PropertyType propertyType)
     {
-        // TODO Auto-generated method stub
-
     }
 
     @Override
     public Vocabulary create(Vocabulary vocabulary)
     {
-        // TODO Auto-generated method stub
         return null;
     }
 
     @Override
     public void delete(Vocabulary vocabulary)
     {
-        // TODO Auto-generated method stub
-
     }
 
     @Override
@@ -189,14 +167,12 @@ public class PublicApiApplicationRunner implements ApplicationRunner
     @Override
     public Experiment create(Experiment experiment)
     {
-        // TODO Auto-generated method stub
         return null;
     }
 
     @Override
     public PropertyTypeAssignment create(PropertyTypeAssignment assignment)
     {
-        // TODO Auto-generated method stub
         return null;
     }
 
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/dsl/DslSampleBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/dsl/DslSampleBrowser.java
new file mode 100644
index 00000000000..26812e88009
--- /dev/null
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/dsl/DslSampleBrowser.java
@@ -0,0 +1,50 @@
+/*
+ * 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.uitest.infra.dsl;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import ch.systemsx.cisd.openbis.uitest.infra.application.DummyApplicationRunner;
+import ch.systemsx.cisd.openbis.uitest.page.tab.SampleBrowser;
+import ch.systemsx.cisd.openbis.uitest.type.SampleType;
+import ch.systemsx.cisd.openbis.uitest.type.SampleTypeBuilder;
+
+/**
+ * @author anttil
+ */
+public class DslSampleBrowser
+{
+    private final SampleBrowser sampleBrowser;
+
+    public DslSampleBrowser(SampleBrowser sampleBrowser)
+    {
+        this.sampleBrowser = sampleBrowser;
+    }
+
+    public Collection<SampleType> availableSampleTypes()
+    {
+        Set<SampleType> types = new HashSet<SampleType>();
+
+        for (String code : sampleBrowser.getSampleTypes())
+        {
+            types.add(new SampleTypeBuilder(new DummyApplicationRunner()).withCode(code).build());
+        }
+        return types;
+    }
+}
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/BrowserListsElementMatcher.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/CellContentMatcher.java
similarity index 54%
rename from ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/BrowserListsElementMatcher.java
rename to ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/CellContentMatcher.java
index 71fe6a2ff76..f3bcac82f60 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/BrowserListsElementMatcher.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/CellContentMatcher.java
@@ -19,47 +19,49 @@ package ch.systemsx.cisd.openbis.uitest.infra.matcher;
 import org.hamcrest.Description;
 import org.hamcrest.TypeSafeMatcher;
 
-import ch.systemsx.cisd.openbis.uitest.page.tab.Browser;
+import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserCell;
 import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserRow;
-import ch.systemsx.cisd.openbis.uitest.type.Browsable;
 
 /**
  * @author anttil
  */
-public class BrowserListsElementMatcher<T extends Browsable, U extends Browser<T>>
-        extends TypeSafeMatcher<U>
+public class CellContentMatcher extends TypeSafeMatcher<BrowserRow>
 {
-    private T expected;
 
-    public BrowserListsElementMatcher(T expected)
+    private String column;
+
+    private String expected;
+
+    private boolean link;
+
+    public CellContentMatcher(String column, String value, boolean link)
     {
-        this.expected = expected;
+        this.column = column;
+        this.expected = value;
+        this.link = link;
     }
 
     @Override
     public void describeTo(Description description)
     {
-        description.appendText("Browser that contains element " + this.expected);
+        description.appendText(
+                "A cell in column " + column + (link ? " linking to " : " displaying ") + expected);
     }
 
     @Override
-    public boolean matchesSafely(U browser)
+    public boolean matchesSafely(BrowserRow row)
     {
-        browser.filter(expected);
-        try
+        if (row.exists() == false)
         {
-            BrowserRow row = browser.select(expected);
+            return false;
+        }
 
-            if (row.exists())
-            {
-                return expected.isRepresentedBy(row);
-            } else
-            {
-                return false;
-            }
-        } finally
+        BrowserCell actual = row.get(column);
+        if (actual == null)
         {
-            browser.resetFilters();
+            return false;
         }
+
+        return expected.equalsIgnoreCase(link ? actual.getUrl() : actual.getText());
     }
-}
\ No newline at end of file
+}
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/CellLinksToMatcher.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/CollectionContainsMatcher.java
similarity index 68%
rename from ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/CellLinksToMatcher.java
rename to ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/CollectionContainsMatcher.java
index e5a76c0f30d..ac6b9a2ba27 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/CellLinksToMatcher.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/CollectionContainsMatcher.java
@@ -16,34 +16,34 @@
 
 package ch.systemsx.cisd.openbis.uitest.infra.matcher;
 
+import java.util.Collection;
+
 import org.hamcrest.Description;
 import org.hamcrest.TypeSafeMatcher;
 
-import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserCell;
-
 /**
  * @author anttil
  */
-public class CellLinksToMatcher extends TypeSafeMatcher<BrowserCell>
+public class CollectionContainsMatcher<T> extends TypeSafeMatcher<Collection<T>>
 {
 
-    private String expected;
+    private T expected;
 
-    public CellLinksToMatcher(String url)
+    public CollectionContainsMatcher(T expected)
     {
-        expected = url;
+        this.expected = expected;
     }
 
     @Override
     public void describeTo(Description description)
     {
-        description.appendText("A cell linking to " + this.expected);
+        description.appendText("A collection containing item " + expected.toString());
     }
 
     @Override
-    public boolean matchesSafely(BrowserCell actual)
+    public boolean matchesSafely(Collection<T> collection)
     {
-        return expected.equals(actual.getUrl());
+        return collection.contains(expected);
     }
 
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/CellDisplaysMatcher.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/RowExistsMatcher.java
similarity index 66%
rename from ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/CellDisplaysMatcher.java
rename to ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/RowExistsMatcher.java
index 1bfaa35a081..27a64e9e463 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/CellDisplaysMatcher.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/matcher/RowExistsMatcher.java
@@ -19,31 +19,24 @@ package ch.systemsx.cisd.openbis.uitest.infra.matcher;
 import org.hamcrest.Description;
 import org.hamcrest.TypeSafeMatcher;
 
-import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserCell;
+import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserRow;
 
 /**
  * @author anttil
  */
-public class CellDisplaysMatcher extends TypeSafeMatcher<BrowserCell>
+public class RowExistsMatcher extends TypeSafeMatcher<BrowserRow>
 {
 
-    private String expected;
-
-    public CellDisplaysMatcher(String string)
-    {
-        expected = string;
-    }
-
     @Override
     public void describeTo(Description description)
     {
-        description.appendText("A cell displaying  text'" + this.expected + "'");
+        description.appendText("A browser row that exists");
     }
 
     @Override
-    public boolean matchesSafely(BrowserCell actual)
+    public boolean matchesSafely(BrowserRow row)
     {
-        return expected.equalsIgnoreCase(actual.getText());
+        return row.exists();
     }
 
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/uid/DictionaryUidGenerator.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/uid/DictionaryUidGenerator.java
index 794156b1853..a6ca90c9398 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/uid/DictionaryUidGenerator.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/infra/uid/DictionaryUidGenerator.java
@@ -46,7 +46,9 @@ public class DictionaryUidGenerator implements UidGenerator
     @Override
     public String uid()
     {
-        return tokens.get((int) (Math.random() * tokens.size())) + "-" + UUID.randomUUID();
+        String uid = tokens.get((int) (Math.random() * tokens.size())) + "-" + UUID.randomUUID();
+        uid = uid.toUpperCase();
+        return uid;
     }
 
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/AssignSamplePropertyType.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/AssignSamplePropertyType.java
index 1e33b68393d..e5d07959729 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/AssignSamplePropertyType.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/AssignSamplePropertyType.java
@@ -48,7 +48,7 @@ public class AssignSamplePropertyType
     public void fillWith(PropertyTypeAssignment assignment)
     {
         propertyType.select(assignment.getPropertyType().getLabel());
-        sampleType.select(assignment.getSampleType().getCode());
+        sampleType.select(assignment.getEntityType().getCode());
         mandatory.set(assignment.isMandatory());
 
         if (assignment.getInitialValue() != null && assignment.getInitialValue().length() > 0)
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/Browser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/Browser.java
index 8936b32b87c..72f7267ee6c 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/Browser.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/Browser.java
@@ -16,18 +16,61 @@
 
 package ch.systemsx.cisd.openbis.uitest.page.tab;
 
+import java.util.List;
+
 import ch.systemsx.cisd.openbis.uitest.type.Browsable;
+import ch.systemsx.cisd.openbis.uitest.widget.FilterToolBar;
+import ch.systemsx.cisd.openbis.uitest.widget.Grid;
+import ch.systemsx.cisd.openbis.uitest.widget.PagingToolBar;
+import ch.systemsx.cisd.openbis.uitest.widget.SettingsDialog;
 
 /**
  * @author anttil
  */
-public interface Browser<T extends Browsable>
+public abstract class Browser<T extends Browsable>
 {
-    public BrowserRow select(T browsable);
 
-    public BrowserCell cell(T browsable, String column);
+    public abstract Grid getGrid();
+
+    public abstract PagingToolBar getPaging();
+
+    public abstract FilterToolBar getFilters();
+
+    public abstract SettingsDialog getSettings();
+
+    public final BrowserRow select(T browsable)
+    {
+        return getGrid().select("Code", browsable.getCode());
+    }
+
+    public final void filterTo(T browsable)
+    {
+        getPaging().filters();
+        getFilters().setCode(browsable.getCode(), getPaging());
+    }
+
+    public final void resetFilters()
+    {
+        getPaging().filters();
+        getFilters().reset();
+    }
+
+    public final void showColumnsOf(T browsable)
+    {
+        getPaging().settings();
+        getSettings().showColumnsOf(browsable);
+    }
+
+    public final List<BrowserRow> getData()
+    {
+        return getGrid().getData();
+    }
 
-    public void filter(T browsable);
+    @Override
+    public String toString()
+    {
+        String s = getClass().getSimpleName() + "\n==========\n";
+        return s + getGrid().toString();
+    }
 
-    public void resetFilters();
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/BrowserRow.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/BrowserRow.java
index 19bc62cbc3a..8b1c10c55cb 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/BrowserRow.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/BrowserRow.java
@@ -51,4 +51,16 @@ public class BrowserRow
         return this.row.get(columnName);
     }
 
+    @Override
+    public String toString()
+    {
+        if (exists)
+        {
+            return "A browser row with the following data: " + row;
+        } else
+        {
+            return "A row that does not exist";
+        }
+    }
+
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/DataSetTypeBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/DataSetTypeBrowser.java
new file mode 100644
index 00000000000..8421b236d5d
--- /dev/null
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/DataSetTypeBrowser.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.uitest.page.tab;
+
+import ch.systemsx.cisd.openbis.uitest.infra.webdriver.Lazy;
+import ch.systemsx.cisd.openbis.uitest.infra.webdriver.Locate;
+import ch.systemsx.cisd.openbis.uitest.type.DataSetType;
+import ch.systemsx.cisd.openbis.uitest.widget.FilterToolBar;
+import ch.systemsx.cisd.openbis.uitest.widget.Grid;
+import ch.systemsx.cisd.openbis.uitest.widget.PagingToolBar;
+import ch.systemsx.cisd.openbis.uitest.widget.SettingsDialog;
+
+public class DataSetTypeBrowser extends Browser<DataSetType>
+{
+
+    @Locate("openbis_data-set-type-browser-grid")
+    private Grid grid;
+
+    @Locate("openbis_data-set-type-browser-grid-paging-toolbar")
+    private PagingToolBar paging;
+
+    @Lazy
+    @Locate("openbis_data-set-type-browser-grid-filter-toolbar")
+    private FilterToolBar filters;
+
+    @Lazy
+    @Locate("openbis_tab-paneltype-browser-grid-DATA_SET")
+    private SettingsDialog settings;
+
+    @Override
+    public Grid getGrid()
+    {
+        return grid;
+    }
+
+    @Override
+    public PagingToolBar getPaging()
+    {
+        return paging;
+    }
+
+    @Override
+    public FilterToolBar getFilters()
+    {
+        return filters;
+    }
+
+    @Override
+    public String toString()
+    {
+        String s = "DataSetTypeBrowser\n==========\n";
+        return s + grid.toString();
+    }
+
+    @Override
+    public SettingsDialog getSettings()
+    {
+        return settings;
+    }
+}
\ No newline at end of file
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/ExperimentBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/ExperimentBrowser.java
index b2741cd5002..ebf3f606825 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/ExperimentBrowser.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/ExperimentBrowser.java
@@ -24,16 +24,17 @@ import ch.systemsx.cisd.openbis.uitest.type.Experiment;
 import ch.systemsx.cisd.openbis.uitest.type.Project;
 import ch.systemsx.cisd.openbis.uitest.widget.Button;
 import ch.systemsx.cisd.openbis.uitest.widget.DeletionConfirmationBox;
+import ch.systemsx.cisd.openbis.uitest.widget.FilterToolBar;
 import ch.systemsx.cisd.openbis.uitest.widget.Grid;
 import ch.systemsx.cisd.openbis.uitest.widget.PagingToolBar;
+import ch.systemsx.cisd.openbis.uitest.widget.SettingsDialog;
 import ch.systemsx.cisd.openbis.uitest.widget.TreeGrid;
 
-public class ExperimentBrowser implements Browser<Experiment>
+public class ExperimentBrowser extends Browser<Experiment>
 {
     @Locate("openbis_select-project")
     private TreeGrid projectTree;
 
-    @SuppressWarnings("unused")
     @Locate("openbis_experiment-browser-grid-grid")
     private Grid grid;
 
@@ -44,10 +45,17 @@ public class ExperimentBrowser implements Browser<Experiment>
     @Locate("deletion-confirmation-dialog")
     private DeletionConfirmationBox deletionDialog;
 
-    @Lazy
     @Locate("openbis_experiment-browser-grid-grid-paging-toolbar")
     private PagingToolBar paging;
 
+    @Lazy
+    @Locate("openbis_experiment-browser-grid-grid-filter-toolbar")
+    private FilterToolBar filters;
+
+    @Lazy
+    @Locate("openbis_tab-panelentity-browser-grid")
+    private SettingsDialog settings;
+
     public boolean selectProject(final Project project)
     {
         return new WaitForRefreshOf<Boolean>(paging).after(new Action<Boolean>()
@@ -73,31 +81,27 @@ public class ExperimentBrowser implements Browser<Experiment>
     }
 
     @Override
-    public BrowserRow select(Experiment browsable)
+    public Grid getGrid()
     {
-        // TODO Auto-generated method stub
-        return null;
+        return grid;
     }
 
     @Override
-    public BrowserCell cell(Experiment browsable, String column)
+    public PagingToolBar getPaging()
     {
-        // TODO Auto-generated method stub
-        return null;
+        return paging;
     }
 
     @Override
-    public void filter(Experiment browsable)
+    public FilterToolBar getFilters()
     {
-        // TODO Auto-generated method stub
-
+        return filters;
     }
 
     @Override
-    public void resetFilters()
+    public SettingsDialog getSettings()
     {
-        // TODO Auto-generated method stub
-
+        return settings;
     }
 
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/ExperimentTypeBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/ExperimentTypeBrowser.java
index 42567b18bba..6b1c70bd9c2 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/ExperimentTypeBrowser.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/ExperimentTypeBrowser.java
@@ -24,8 +24,9 @@ import ch.systemsx.cisd.openbis.uitest.widget.DeletionConfirmationBox;
 import ch.systemsx.cisd.openbis.uitest.widget.FilterToolBar;
 import ch.systemsx.cisd.openbis.uitest.widget.Grid;
 import ch.systemsx.cisd.openbis.uitest.widget.PagingToolBar;
+import ch.systemsx.cisd.openbis.uitest.widget.SettingsDialog;
 
-public class ExperimentTypeBrowser implements Browser<ExperimentType>
+public class ExperimentTypeBrowser extends Browser<ExperimentType>
 {
 
     @Locate("add-entity-type-EXPERIMENT")
@@ -52,6 +53,10 @@ public class ExperimentTypeBrowser implements Browser<ExperimentType>
     @Locate("deletion-confirmation-dialog")
     private DeletionConfirmationBox confimDeletion;
 
+    @Lazy
+    @Locate("openbis_tab-paneltype-browser-grid-EXPERIMENT")
+    private SettingsDialog settings;
+
     public void add()
     {
         add.click();
@@ -64,29 +69,21 @@ public class ExperimentTypeBrowser implements Browser<ExperimentType>
     }
 
     @Override
-    public BrowserRow select(ExperimentType experimentType)
+    public Grid getGrid()
     {
-        return grid.select("Code", experimentType.getCode());
+        return grid;
     }
 
     @Override
-    public BrowserCell cell(ExperimentType experimentType, String column)
+    public PagingToolBar getPaging()
     {
-        return select(experimentType).get(column);
+        return paging;
     }
 
     @Override
-    public void filter(final ExperimentType type)
+    public FilterToolBar getFilters()
     {
-        paging.filters();
-        filters.setCode(type.getCode(), paging);
-    }
-
-    @Override
-    public void resetFilters()
-    {
-        paging.filters();
-        filters.reset();
+        return filters;
     }
 
     @Override
@@ -96,4 +93,9 @@ public class ExperimentTypeBrowser implements Browser<ExperimentType>
         return s + grid.toString();
     }
 
+    @Override
+    public SettingsDialog getSettings()
+    {
+        return settings;
+    }
 }
\ No newline at end of file
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/ProjectBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/ProjectBrowser.java
index 8934149b4bd..65c7f9666ef 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/ProjectBrowser.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/ProjectBrowser.java
@@ -24,8 +24,9 @@ import ch.systemsx.cisd.openbis.uitest.widget.DeletionConfirmationBox;
 import ch.systemsx.cisd.openbis.uitest.widget.FilterToolBar;
 import ch.systemsx.cisd.openbis.uitest.widget.Grid;
 import ch.systemsx.cisd.openbis.uitest.widget.PagingToolBar;
+import ch.systemsx.cisd.openbis.uitest.widget.SettingsDialog;
 
-public class ProjectBrowser implements Browser<Project>
+public class ProjectBrowser extends Browser<Project>
 {
 
     @Locate("openbis_project-browser-grid")
@@ -45,6 +46,10 @@ public class ProjectBrowser implements Browser<Project>
     @Locate("deletion-confirmation-dialog")
     private DeletionConfirmationBox confimDeletion;
 
+    @Lazy
+    @Locate("openbis_tab-panelproject-browser-grid")
+    private SettingsDialog settings;
+
     public void delete()
     {
         delete.click();
@@ -52,35 +57,27 @@ public class ProjectBrowser implements Browser<Project>
     }
 
     @Override
-    public BrowserRow select(Project project)
+    public Grid getGrid()
     {
-        return grid.select("Code", project.getCode());
+        return grid;
     }
 
     @Override
-    public BrowserCell cell(Project project, String column)
+    public PagingToolBar getPaging()
     {
-        return select(project).get(column);
+        return paging;
     }
 
     @Override
-    public void filter(Project project)
+    public FilterToolBar getFilters()
     {
-        paging.filters();
-        filters.setCode(project.getCode(), paging);
+        return filters;
     }
 
     @Override
-    public void resetFilters()
+    public SettingsDialog getSettings()
     {
-        paging.filters();
-        filters.reset();
+        return settings;
     }
 
-    @Override
-    public String toString()
-    {
-        String s = "ProjectBrowser\n==========\n";
-        return s + grid.toString();
-    }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/PropertyTypeAssignmentBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/PropertyTypeAssignmentBrowser.java
index f772e3f64b8..3468ea26578 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/PropertyTypeAssignmentBrowser.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/PropertyTypeAssignmentBrowser.java
@@ -23,8 +23,9 @@ import ch.systemsx.cisd.openbis.uitest.widget.Button;
 import ch.systemsx.cisd.openbis.uitest.widget.FilterToolBar;
 import ch.systemsx.cisd.openbis.uitest.widget.Grid;
 import ch.systemsx.cisd.openbis.uitest.widget.PagingToolBar;
+import ch.systemsx.cisd.openbis.uitest.widget.SettingsDialog;
 
-public class PropertyTypeAssignmentBrowser implements Browser<PropertyTypeAssignment>
+public class PropertyTypeAssignmentBrowser extends Browser<PropertyTypeAssignment>
 {
     @Locate("openbis_property-type-assignment-browser-grid")
     private Grid grid;
@@ -44,36 +45,32 @@ public class PropertyTypeAssignmentBrowser implements Browser<PropertyTypeAssign
     @Locate("openbis_property-type-assignment-browser-grid-filter-toolbar")
     private FilterToolBar filters;
 
-    @Override
-    public BrowserRow select(PropertyTypeAssignment assignment)
-    {
-        return grid.select("Property Type Code", assignment.getPropertyType().getCode());
-    }
+    @Lazy
+    @Locate("openbis_tab-panelproperty-type-assignment-browser-grid")
+    private SettingsDialog settings;
 
     @Override
-    public BrowserCell cell(PropertyTypeAssignment assignment, String column)
+    public Grid getGrid()
     {
-        return select(assignment).get(column);
+        return grid;
     }
 
     @Override
-    public void filter(PropertyTypeAssignment assignment)
+    public PagingToolBar getPaging()
     {
-        paging.filters();
-        filters.setCode(assignment.getPropertyType().getCode(), paging);
+        return paging;
     }
 
     @Override
-    public void resetFilters()
+    public FilterToolBar getFilters()
     {
-        paging.filters();
-        filters.reset();
+        return filters;
     }
 
     @Override
-    public String toString()
+    public SettingsDialog getSettings()
     {
-        String s = "PropertyTypeAssignmentBrowser\n==========\n";
-        return s + grid.toString();
+        return settings;
     }
+
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/PropertyTypeBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/PropertyTypeBrowser.java
index 0a21dec36a8..522b5ad901f 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/PropertyTypeBrowser.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/PropertyTypeBrowser.java
@@ -24,8 +24,9 @@ import ch.systemsx.cisd.openbis.uitest.widget.DeletionConfirmationBox;
 import ch.systemsx.cisd.openbis.uitest.widget.FilterToolBar;
 import ch.systemsx.cisd.openbis.uitest.widget.Grid;
 import ch.systemsx.cisd.openbis.uitest.widget.PagingToolBar;
+import ch.systemsx.cisd.openbis.uitest.widget.SettingsDialog;
 
-public class PropertyTypeBrowser implements Browser<PropertyType>
+public class PropertyTypeBrowser extends Browser<PropertyType>
 {
 
     @Locate("openbis_property-type-browser-grid")
@@ -49,6 +50,10 @@ public class PropertyTypeBrowser implements Browser<PropertyType>
     @Locate("deletion-confirmation-dialog")
     private DeletionConfirmationBox confimDeletion;
 
+    @Lazy
+    @Locate("openbis_tab-panelproperty-type-browser-grid")
+    private SettingsDialog settings;
+
     public void delete()
     {
         delete.click();
@@ -56,35 +61,27 @@ public class PropertyTypeBrowser implements Browser<PropertyType>
     }
 
     @Override
-    public BrowserRow select(PropertyType type)
+    public Grid getGrid()
     {
-        return grid.select("Code", type.getCode());
+        return grid;
     }
 
     @Override
-    public BrowserCell cell(PropertyType type, String column)
+    public PagingToolBar getPaging()
     {
-        return select(type).get(column);
+        return paging;
     }
 
     @Override
-    public void filter(PropertyType propertyType)
+    public FilterToolBar getFilters()
     {
-        paging.filters();
-        filters.setCode(propertyType.getCode(), paging);
+        return filters;
     }
 
     @Override
-    public void resetFilters()
+    public SettingsDialog getSettings()
     {
-        paging.filters();
-        filters.reset();
+        return settings;
     }
 
-    @Override
-    public String toString()
-    {
-        String s = "PropertyTypeBrowser\n==========\n";
-        return s + grid.toString();
-    }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/RoleAssignmentBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/RoleAssignmentBrowser.java
index b611fadabaf..4bc1c15a2dd 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/RoleAssignmentBrowser.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/RoleAssignmentBrowser.java
@@ -16,43 +16,57 @@
 
 package ch.systemsx.cisd.openbis.uitest.page.tab;
 
+import ch.systemsx.cisd.openbis.uitest.infra.webdriver.Lazy;
 import ch.systemsx.cisd.openbis.uitest.infra.webdriver.Locate;
 import ch.systemsx.cisd.openbis.uitest.type.Experiment;
 import ch.systemsx.cisd.openbis.uitest.widget.Button;
+import ch.systemsx.cisd.openbis.uitest.widget.FilterToolBar;
+import ch.systemsx.cisd.openbis.uitest.widget.Grid;
+import ch.systemsx.cisd.openbis.uitest.widget.PagingToolBar;
+import ch.systemsx.cisd.openbis.uitest.widget.SettingsDialog;
 
-public class RoleAssignmentBrowser implements Browser<Experiment>
+public class RoleAssignmentBrowser extends Browser<Experiment>
 {
 
     @SuppressWarnings("unused")
     @Locate("openbis_role-browser_assign-button")
     private Button assignRoleButton;
 
+    @Locate("openbis_role-browser-grid")
+    private Grid grid;
+
+    @Locate("openbis_role-browser-grid-paging-toolbar")
+    private PagingToolBar paging;
+
+    @Lazy
+    @Locate("openbis_role-browser-grid-filter-toolbar")
+    private FilterToolBar filters;
+
+    @Lazy
+    @Locate("openbis_tab-panelrole-assignment-browser-grid")
+    private SettingsDialog settings;
+
     @Override
-    public BrowserRow select(Experiment browsable)
+    public Grid getGrid()
     {
-        // TODO Auto-generated method stub
-        return null;
+        return grid;
     }
 
     @Override
-    public BrowserCell cell(Experiment browsable, String column)
+    public PagingToolBar getPaging()
     {
-        // TODO Auto-generated method stub
-        return null;
+        return paging;
     }
 
     @Override
-    public void filter(Experiment browsable)
+    public FilterToolBar getFilters()
     {
-        // TODO Auto-generated method stub
-
+        return filters;
     }
 
     @Override
-    public void resetFilters()
+    public SettingsDialog getSettings()
     {
-        // TODO Auto-generated method stub
-
+        return settings;
     }
-
 }
\ No newline at end of file
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SampleBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SampleBrowser.java
index 1dd20b1a94d..19d9db592f7 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SampleBrowser.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SampleBrowser.java
@@ -29,7 +29,7 @@ import ch.systemsx.cisd.openbis.uitest.widget.Grid;
 import ch.systemsx.cisd.openbis.uitest.widget.PagingToolBar;
 import ch.systemsx.cisd.openbis.uitest.widget.SettingsDialog;
 
-public class SampleBrowser implements Browser<Sample>
+public class SampleBrowser extends Browser<Sample>
 {
 
     @Locate("openbis_sample-browser_main-grid")
@@ -76,53 +76,32 @@ public class SampleBrowser implements Browser<Sample>
     }
 
     @Override
-    public BrowserRow select(Sample sample)
+    public Grid getGrid()
     {
-        return grid.select("Code", sample.getCode());
+        return grid;
     }
 
     @Override
-    public BrowserCell cell(Sample sample, String column)
+    public PagingToolBar getPaging()
     {
-        BrowserCell c = select(sample).get(column);
-        if (c == null)
-        {
-            paging.settings();
-            settings.showColumns("Code", column);
-            try
-            {
-                Thread.sleep(5000);
-            } catch (InterruptedException ex)
-            {
-                // TODO Auto-generated catch block
-                ex.printStackTrace();
-            }
-            return select(sample).get(column);
-        } else
-        {
-            return c;
-        }
+        return paging;
     }
 
     @Override
-    public void filter(Sample sample)
+    public FilterToolBar getFilters()
     {
-        paging.filters();
-        filters.setCode(sample.getCode(), paging);
+        return filters;
     }
 
     @Override
-    public void resetFilters()
+    public String toString()
     {
-        paging.filters();
-        filters.reset();
+        return super.toString() + "\nSample Type Choices: " + sampleTypeList.getChoices() + "\n";
     }
 
     @Override
-    public String toString()
+    public SettingsDialog getSettings()
     {
-        String s = "SampleBrowser\n==========\n";
-        s += "Sample Type Choices: " + sampleTypeList.getChoices() + "\n";
-        return s + grid.toString();
+        return settings;
     }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SampleTypeBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SampleTypeBrowser.java
index 1ec48ce5584..192340d8080 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SampleTypeBrowser.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SampleTypeBrowser.java
@@ -24,8 +24,9 @@ import ch.systemsx.cisd.openbis.uitest.widget.DeletionConfirmationBox;
 import ch.systemsx.cisd.openbis.uitest.widget.FilterToolBar;
 import ch.systemsx.cisd.openbis.uitest.widget.Grid;
 import ch.systemsx.cisd.openbis.uitest.widget.PagingToolBar;
+import ch.systemsx.cisd.openbis.uitest.widget.SettingsDialog;
 
-public class SampleTypeBrowser implements Browser<SampleType>
+public class SampleTypeBrowser extends Browser<SampleType>
 {
     @Locate("add-entity-type-SAMPLE")
     private Button add;
@@ -50,6 +51,10 @@ public class SampleTypeBrowser implements Browser<SampleType>
     @Locate("deletion-confirmation-dialog")
     private DeletionConfirmationBox confimDeletion;
 
+    @Lazy
+    @Locate("openbis_tab-paneltype-browser-grid-SAMPLE")
+    private SettingsDialog settings;
+
     public void add()
     {
         add.click();
@@ -67,36 +72,27 @@ public class SampleTypeBrowser implements Browser<SampleType>
     }
 
     @Override
-    public BrowserRow select(SampleType type)
-    {
-        return grid.select("Code", type.getCode());
-    }
-
-    @Override
-    public BrowserCell cell(SampleType type, String column)
+    public Grid getGrid()
     {
-        return select(type).get(column);
+        return grid;
     }
 
     @Override
-    public void filter(SampleType type)
+    public PagingToolBar getPaging()
     {
-        paging.filters();
-        filters.setCode(type.getCode(), paging);
+        return paging;
     }
 
     @Override
-    public void resetFilters()
+    public FilterToolBar getFilters()
     {
-        paging.filters();
-        filters.reset();
+        return filters;
     }
 
     @Override
-    public String toString()
+    public SettingsDialog getSettings()
     {
-        String s = "SampleTypeBrowser\n==========\n";
-        return s + grid.toString();
+        return settings;
     }
 
 }
\ No newline at end of file
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SpaceBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SpaceBrowser.java
index 58528761d92..aabcc2d4bfd 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SpaceBrowser.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/SpaceBrowser.java
@@ -24,8 +24,9 @@ import ch.systemsx.cisd.openbis.uitest.widget.DeletionConfirmationBox;
 import ch.systemsx.cisd.openbis.uitest.widget.FilterToolBar;
 import ch.systemsx.cisd.openbis.uitest.widget.Grid;
 import ch.systemsx.cisd.openbis.uitest.widget.PagingToolBar;
+import ch.systemsx.cisd.openbis.uitest.widget.SettingsDialog;
 
-public class SpaceBrowser implements Browser<Space>
+public class SpaceBrowser extends Browser<Space>
 {
 
     @Locate("openbis_space-browser-grid")
@@ -48,17 +49,15 @@ public class SpaceBrowser implements Browser<Space>
     @Locate("deletion-confirmation-dialog")
     private DeletionConfirmationBox confimDeletion;
 
+    @Lazy
+    @Locate("openbis_tab-panelspace-browser-grid")
+    private SettingsDialog settings;
+
     public void addSpace()
     {
         addSpace.click();
     }
 
-    @Override
-    public BrowserRow select(Space space)
-    {
-        return grid.select("Code", space.getCode());
-    }
-
     public void delete()
     {
         delete.click();
@@ -66,29 +65,26 @@ public class SpaceBrowser implements Browser<Space>
     }
 
     @Override
-    public BrowserCell cell(Space space, String column)
+    public Grid getGrid()
     {
-        return select(space).get(column);
+        return grid;
     }
 
     @Override
-    public void filter(final Space space)
+    public PagingToolBar getPaging()
     {
-        paging.filters();
-        filters.setCode(space.getCode(), paging);
+        return paging;
     }
 
     @Override
-    public void resetFilters()
+    public FilterToolBar getFilters()
     {
-        paging.filters();
-        filters.reset();
+        return filters;
     }
 
     @Override
-    public String toString()
+    public SettingsDialog getSettings()
     {
-        String s = "SpaceBrowser\n==========\n";
-        return s + grid.toString();
+        return settings;
     }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/VocabularyBrowser.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/VocabularyBrowser.java
index 8526a710a39..3d3958ab8e2 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/VocabularyBrowser.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/page/tab/VocabularyBrowser.java
@@ -24,8 +24,9 @@ import ch.systemsx.cisd.openbis.uitest.widget.DeletionConfirmationBox;
 import ch.systemsx.cisd.openbis.uitest.widget.FilterToolBar;
 import ch.systemsx.cisd.openbis.uitest.widget.Grid;
 import ch.systemsx.cisd.openbis.uitest.widget.PagingToolBar;
+import ch.systemsx.cisd.openbis.uitest.widget.SettingsDialog;
 
-public class VocabularyBrowser implements Browser<Vocabulary>
+public class VocabularyBrowser extends Browser<Vocabulary>
 {
     @Locate("openbis_vocabulary-browser-grid")
     private Grid grid;
@@ -47,6 +48,10 @@ public class VocabularyBrowser implements Browser<Vocabulary>
     @Locate("deletion-confirmation-dialog")
     private DeletionConfirmationBox confimDeletion;
 
+    @Lazy
+    @Locate("openbis_tab-panelvocabulary-browser-grid")
+    private SettingsDialog settings;
+
     public void add()
     {
         add.click();
@@ -59,35 +64,27 @@ public class VocabularyBrowser implements Browser<Vocabulary>
     }
 
     @Override
-    public BrowserRow select(Vocabulary vocabulary)
+    public Grid getGrid()
     {
-        return grid.select("Code", vocabulary.getCode());
+        return grid;
     }
 
     @Override
-    public BrowserCell cell(Vocabulary vocabulary, String column)
+    public PagingToolBar getPaging()
     {
-        return select(vocabulary).get(column);
+        return paging;
     }
 
     @Override
-    public void filter(Vocabulary vocabulary)
+    public FilterToolBar getFilters()
     {
-        paging.filters();
-        filters.setCode(vocabulary.getCode(), paging);
+        return filters;
     }
 
     @Override
-    public void resetFilters()
+    public SettingsDialog getSettings()
     {
-        paging.filters();
-        filters.reset();
+        return settings;
     }
 
-    @Override
-    public String toString()
-    {
-        String s = "VocabularyBrowser\n==========\n";
-        return s + grid.toString();
-    }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/ExperimentTest.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/ExperimentTest.java
index f6f71dcac8e..8bd43edf472 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/ExperimentTest.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/ExperimentTest.java
@@ -42,7 +42,7 @@ public class ExperimentTest extends SeleniumTest
 
         Experiment experiment = create(anExperiment().in(project).withSamples(sample));
 
-        assertThat(cell(sample, "Experiment").of(sampleBrowser()), displays(experiment.getCode()));
-        assertThat(cell(sample, "Project").of(sampleBrowser()), displays(project.getCode()));
+        assertThat(browserEntryOf(sample), containsValue("Experiment", experiment.getCode()));
+        assertThat(browserEntryOf(sample), containsValue("Project", project.getCode()));
     }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/ExperimentTypeTest.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/ExperimentTypeTest.java
index 834129c0668..492f1116360 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/ExperimentTypeTest.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/ExperimentTypeTest.java
@@ -16,7 +16,7 @@ public class ExperimentTypeTest extends SeleniumTest
     {
         ExperimentType type = create(anExperimentType());
 
-        assertThat(experimentTypeBrowser(), lists(type));
+        assertThat(browserEntryOf(type), exists());
     }
 
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/ProjectTest.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/ProjectTest.java
index 8a2ac44cc00..81e57ad8d45 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/ProjectTest.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/ProjectTest.java
@@ -16,7 +16,7 @@ public class ProjectTest extends SeleniumTest
     {
         Project project = create(aProject());
 
-        assertThat(projectBrowser(), lists(project));
+        assertThat(browserEntryOf(project), exists());
     }
 
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/PropertyTypeAssignmentTest.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/PropertyTypeAssignmentTest.java
index 239551cbc65..d6e4338c6bb 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/PropertyTypeAssignmentTest.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/PropertyTypeAssignmentTest.java
@@ -37,7 +37,7 @@ public class PropertyTypeAssignmentTest extends SeleniumTest
     {
         PropertyTypeAssignment assignment = create(aSamplePropertyTypeAssignment());
 
-        assertThat(propertyTypeAssignmentBrowser(), lists(assignment));
+        assertThat(browserEntryOf(assignment), exists());
     }
 
     @Test
@@ -55,7 +55,7 @@ public class PropertyTypeAssignmentTest extends SeleniumTest
                 .thatIsMandatory()
                 .havingInitialValueOf("Test Initial Value"));
 
-        assertThat(cell(sample, propertyType.getLabel()).of(sampleBrowser()),
-                displays("Test Initial Value"));
+        assertThat(browserEntryOf(sample), containsValue(propertyType.getLabel(),
+                "Test Initial Value"));
     }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/PropertyTypeTest.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/PropertyTypeTest.java
index fc55a6d9701..722f3034225 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/PropertyTypeTest.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/PropertyTypeTest.java
@@ -34,6 +34,6 @@ public class PropertyTypeTest extends SeleniumTest
     {
         PropertyType propertyType = create(aBooleanPropertyType());
 
-        assertThat(propertyTypeBrowser(), lists(propertyType));
+        assertThat(browserEntryOf(propertyType), exists());
     }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/SampleTest.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/SampleTest.java
index 0df8c3f36c9..e3fab77404c 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/SampleTest.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/SampleTest.java
@@ -37,7 +37,7 @@ public class SampleTest extends SeleniumTest
     {
         Sample sample = create(aSample());
 
-        assertThat(sampleBrowser(), lists(sample));
+        assertThat(browserEntryOf(sample), exists());
     }
 
     @Test
@@ -76,9 +76,9 @@ public class SampleTest extends SeleniumTest
         Sample sample =
                 create(aSample().ofType(sampleType).withProperty(vocabularyType, "mouse"));
 
-        assertThat(cell(sample, vocabularyType.getLabel()).of(sampleBrowser()), displays("mouse"));
-        assertThat(cell(sample, vocabularyType.getLabel()).of(sampleBrowser()),
-                linksTo("http://www.ask.com/web?q=MOUSE"));
+        assertThat(browserEntryOf(sample), containsValue(vocabularyType.getLabel(), "mouse"));
+        assertThat(browserEntryOf(sample), containsLink(vocabularyType.getLabel(),
+                "http://www.ask.com/web?q=MOUSE"));
     }
 
     @Test(enabled = false)
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/SampleTypeTest.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/SampleTypeTest.java
index 0a1cae21676..090232542b8 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/SampleTypeTest.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/SampleTypeTest.java
@@ -46,7 +46,7 @@ public class SampleTypeTest extends SeleniumTest
     {
         SampleType sampleType = create(aSampleType());
 
-        assertThat(sampleTypeBrowser(), lists(sampleType));
+        assertThat(browserEntryOf(sampleType), exists());
     }
 
     @Test
@@ -54,7 +54,7 @@ public class SampleTypeTest extends SeleniumTest
     {
         SampleType sampleType = create(aSampleType().thatIsNotListable());
 
-        assertThat(sampleBrowser(), doesNotShowInToolBar(sampleType));
+        assertThat(sampleBrowser().availableSampleTypes(), doesNotContain(sampleType));
     }
 
     @Test
@@ -64,7 +64,7 @@ public class SampleTypeTest extends SeleniumTest
 
         perform(anUpdateOf(sampleType).settingItListable());
 
-        assertThat(sampleBrowser(), showsInToolBar(sampleType));
+        assertThat(sampleBrowser().availableSampleTypes(), contains(sampleType));
     }
 
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/SeleniumTest.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/SeleniumTest.java
index 29efef8e139..0f82114a6a3 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/SeleniumTest.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/SeleniumTest.java
@@ -22,6 +22,7 @@ import java.awt.Toolkit;
 import java.io.File;
 import java.io.IOException;
 import java.lang.reflect.Method;
+import java.util.Collection;
 import java.util.concurrent.TimeUnit;
 
 import org.hamcrest.Matcher;
@@ -39,31 +40,20 @@ import org.testng.annotations.BeforeSuite;
 import ch.systemsx.cisd.openbis.uitest.infra.application.ApplicationRunner;
 import ch.systemsx.cisd.openbis.uitest.infra.application.GuiApplicationRunner;
 import ch.systemsx.cisd.openbis.uitest.infra.application.PublicApiApplicationRunner;
-import ch.systemsx.cisd.openbis.uitest.infra.matcher.BrowserListsElementMatcher;
-import ch.systemsx.cisd.openbis.uitest.infra.matcher.CellDisplaysMatcher;
-import ch.systemsx.cisd.openbis.uitest.infra.matcher.CellLinksToMatcher;
+import ch.systemsx.cisd.openbis.uitest.infra.dsl.DslSampleBrowser;
+import ch.systemsx.cisd.openbis.uitest.infra.matcher.CellContentMatcher;
+import ch.systemsx.cisd.openbis.uitest.infra.matcher.CollectionContainsMatcher;
 import ch.systemsx.cisd.openbis.uitest.infra.matcher.PageMatcher;
 import ch.systemsx.cisd.openbis.uitest.infra.matcher.RegisterSampleFormContainsInputsForPropertiesMatcher;
-import ch.systemsx.cisd.openbis.uitest.infra.matcher.SampleBrowserSampleTypeDropDownMenuMatcher;
+import ch.systemsx.cisd.openbis.uitest.infra.matcher.RowExistsMatcher;
 import ch.systemsx.cisd.openbis.uitest.infra.matcher.SampleHasDataSetsMatcher;
 import ch.systemsx.cisd.openbis.uitest.infra.screenshot.FileScreenShotter;
 import ch.systemsx.cisd.openbis.uitest.infra.screenshot.ScreenShotter;
 import ch.systemsx.cisd.openbis.uitest.infra.uid.DictionaryUidGenerator;
 import ch.systemsx.cisd.openbis.uitest.infra.uid.UidGenerator;
 import ch.systemsx.cisd.openbis.uitest.infra.webdriver.PageProxy;
-import ch.systemsx.cisd.openbis.uitest.page.tab.Browser;
-import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserCell;
-import ch.systemsx.cisd.openbis.uitest.page.tab.ExperimentBrowser;
-import ch.systemsx.cisd.openbis.uitest.page.tab.ExperimentTypeBrowser;
-import ch.systemsx.cisd.openbis.uitest.page.tab.ProjectBrowser;
-import ch.systemsx.cisd.openbis.uitest.page.tab.PropertyTypeAssignmentBrowser;
-import ch.systemsx.cisd.openbis.uitest.page.tab.PropertyTypeBrowser;
+import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserRow;
 import ch.systemsx.cisd.openbis.uitest.page.tab.RegisterSample;
-import ch.systemsx.cisd.openbis.uitest.page.tab.SampleBrowser;
-import ch.systemsx.cisd.openbis.uitest.page.tab.SampleTypeBrowser;
-import ch.systemsx.cisd.openbis.uitest.page.tab.SpaceBrowser;
-import ch.systemsx.cisd.openbis.uitest.page.tab.Trash;
-import ch.systemsx.cisd.openbis.uitest.page.tab.VocabularyBrowser;
 import ch.systemsx.cisd.openbis.uitest.type.Browsable;
 import ch.systemsx.cisd.openbis.uitest.type.Builder;
 import ch.systemsx.cisd.openbis.uitest.type.DataSet;
@@ -187,7 +177,7 @@ public abstract class SeleniumTest
             }), uid);
         openbis.login(ADMIN_USER, ADMIN_PASSWORD);
         // this is because of BIS-184
-        sampleBrowser();
+        openbis.browseToSampleBrowser();
 
         openbisApi.login(ADMIN_USER, ADMIN_PASSWORD);
     }
@@ -241,49 +231,19 @@ public abstract class SeleniumTest
         f.delete();
     }
 
-    protected SampleBrowser sampleBrowser()
+    protected DslSampleBrowser sampleBrowser()
     {
-        return openbis.browseToSampleBrowser();
+        return new DslSampleBrowser(openbis.browseToSampleBrowser());
     }
 
-    protected ExperimentBrowser experimentBrowser()
+    protected <T extends Browsable> BrowserRow browserEntryOf(T browsable)
     {
-        return openbis.browseToExperimentBrowser();
+        return browsable.getBrowserContent(openbis);
     }
 
-    protected Trash trash()
+    protected void emptyTrash()
     {
-        return openbis.browseToTrash();
-    }
-
-    protected SampleTypeBrowser sampleTypeBrowser()
-    {
-        return openbis.browseToSampleTypeBrowser();
-    }
-
-    protected ExperimentTypeBrowser experimentTypeBrowser()
-    {
-        return openbis.browseToExperimentTypeBrowser();
-    }
-
-    protected VocabularyBrowser vocabularyBrowser()
-    {
-        return openbis.browseToVocabularyBrowser();
-    }
-
-    protected PropertyTypeBrowser propertyTypeBrowser()
-    {
-        return openbis.browseToPropertyTypeBrowser();
-    }
-
-    protected SpaceBrowser spaceBrowser()
-    {
-        return openbis.browseToSpaceBrowser();
-    }
-
-    protected ProjectBrowser projectBrowser()
-    {
-        return openbis.browseToProjectBrowser();
+        openbis.browseToTrash().empty();
     }
 
     protected RegisterSample sampleRegistrationPageFor(SampleType type)
@@ -292,11 +252,6 @@ public abstract class SeleniumTest
         return pageProxy.get(RegisterSample.class);
     }
 
-    protected PropertyTypeAssignmentBrowser propertyTypeAssignmentBrowser()
-    {
-        return openbis.browseToPropertyTypeAssignmentBrowser();
-    }
-
     protected Matcher<Sample> hasDataSets(DataSet... datasets)
     {
         return new SampleHasDataSetsMatcher(openbis, datasets);
@@ -307,69 +262,39 @@ public abstract class SeleniumTest
         return new PageMatcher(pageClass, pageProxy);
     }
 
-    protected Matcher<SampleBrowser> showsInToolBar(SampleType sampleType)
-    {
-        return new SampleBrowserSampleTypeDropDownMenuMatcher(sampleType);
-    }
-
-    protected Matcher<SampleBrowser> doesNotShowInToolBar(SampleType sampleType)
-    {
-        return not(new SampleBrowserSampleTypeDropDownMenuMatcher(sampleType));
-    }
-
-    protected <T extends Browsable, U extends Browser<T>> Matcher<U> lists(T browsable)
+    protected Matcher<RegisterSample> hasInputsForProperties(PropertyType... fields)
     {
-        return new BrowserListsElementMatcher<T, U>(browsable);
+        return new RegisterSampleFormContainsInputsForPropertiesMatcher(fields);
     }
 
-    protected <T extends Browsable, U extends Browser<T>> Matcher<U> doesNotList(T browsable)
+    protected Matcher<BrowserRow> containsValue(String column, String value)
     {
-        return not(new BrowserListsElementMatcher<T, U>(browsable));
+        return new CellContentMatcher(column, value, false);
     }
 
-    protected Matcher<RegisterSample> hasInputsForProperties(PropertyType... fields)
+    protected Matcher<BrowserRow> exists()
     {
-        return new RegisterSampleFormContainsInputsForPropertiesMatcher(fields);
+        return new RowExistsMatcher();
     }
 
-    protected <T extends Browsable> CellExtractor<T> cell(T browsable, String column)
+    protected Matcher<BrowserRow> doesNotExist()
     {
-        return new CellExtractor<T>(browsable, column);
+        return not(new RowExistsMatcher());
     }
 
-    protected class CellExtractor<T extends Browsable>
+    protected Matcher<BrowserRow> containsLink(String column, String value)
     {
-        private final T browsable;
-
-        private final String column;
-
-        public CellExtractor(T browsable, String column)
-        {
-            this.browsable = browsable;
-            this.column = column;
-        }
-
-        public BrowserCell of(Browser<T> browser)
-        {
-            browser.filter(browsable);
-            try
-            {
-                return browser.cell(browsable, column);
-            } finally
-            {
-                browser.resetFilters();
-            }
-        }
+        return new CellContentMatcher(column, value, true);
     }
 
-    protected Matcher<BrowserCell> linksTo(String url)
+    protected <T> Matcher<Collection<T>> contains(T t)
     {
-        return new CellLinksToMatcher(url);
+        return new CollectionContainsMatcher<T>(t);
     }
 
-    protected Matcher<BrowserCell> displays(String text)
+    protected <T> Matcher<Collection<T>> doesNotContain(T t)
     {
-        return new CellDisplaysMatcher(text);
+        return not(new CollectionContainsMatcher<T>(t));
     }
 
     protected <T> T create(Builder<T> builder)
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/SpaceTest.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/SpaceTest.java
index 72c01ace581..8a510a4abe5 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/SpaceTest.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/SpaceTest.java
@@ -16,7 +16,7 @@ public class SpaceTest extends SeleniumTest
     {
         Space space = create(aSpace());
 
-        assertThat(spaceBrowser(), lists(space));
+        assertThat(browserEntryOf(space), exists());
     }
 
     @Test
@@ -26,7 +26,6 @@ public class SpaceTest extends SeleniumTest
 
         delete(space);
 
-        assertThat(spaceBrowser(), doesNotList(space));
+        assertThat(browserEntryOf(space), doesNotExist());
     }
-
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/SprintTest.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/SprintTest.java
index 2b989e517d2..89b3a74b46d 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/SprintTest.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/SprintTest.java
@@ -54,7 +54,7 @@ public class SprintTest extends SeleniumTest
                 assume(aVocabularyPropertyType(oldVocabulary).withCode("sprint-test.animal"));
 
         deleteExperimentsFrom(oldProject);
-        trash().empty();
+        emptyTrash();
         delete(oldProject);
         delete(oldSpace);
         delete(oldSampleType);
@@ -70,7 +70,7 @@ public class SprintTest extends SeleniumTest
 
         // 2) Space
         Space space = create(aSpace().withCode("sprint-test"));
-        assertThat(spaceBrowser(), lists(space));
+        assertThat(browserEntryOf(space), exists());
 
         // 3) Sample types and properties
         create(aSampleType().withCode("sprint test"));
@@ -83,11 +83,11 @@ public class SprintTest extends SeleniumTest
                         .thatIsNotListable()
                         .thatShowsContainer()
                         .thatShowsParents());
-        assertThat(sampleTypeBrowser(), lists(sampleType));
-        assertThat(sampleBrowser(), doesNotShowInToolBar(sampleType));
+        assertThat(browserEntryOf(sampleType), exists());
+        assertThat(sampleBrowser().availableSampleTypes(), doesNotContain(sampleType));
 
         perform(anUpdateOf(sampleType).settingItListable());
-        assertThat(sampleBrowser(), showsInToolBar(sampleType));
+        assertThat(sampleBrowser().availableSampleTypes(), contains(sampleType));
 
         Vocabulary vocabulary =
                 create(aVocabulary()
@@ -131,11 +131,10 @@ public class SprintTest extends SeleniumTest
                         .withProperty(varcharPropertyType, "some text")
                         .withProperty(animalPropertyType, "mouse"));
 
-        assertThat(sampleBrowser(), lists(sample));
-        assertThat(cell(sample, animalPropertyType.getLabel()).of(sampleBrowser()),
-                displays("mouse"));
-        assertThat(cell(sample, animalPropertyType.getLabel()).of(sampleBrowser()),
-                linksTo("http://www.ask.com/web?q=MOUSE"));
+        assertThat(browserEntryOf(sample), exists());
+        assertThat(browserEntryOf(sample), containsValue(animalPropertyType.getLabel(), "mouse"));
+        assertThat(browserEntryOf(sample), containsLink(animalPropertyType.getLabel(),
+                "http://www.ask.com/web?q=MOUSE"));
 
         // 5) Project and experiment
         Project project = create(aProject().withCode("P1").in(space));
@@ -144,7 +143,7 @@ public class SprintTest extends SeleniumTest
         Experiment experiment =
                 create(anExperiment().ofType(experimentType).in(project).withCode("exp1")
                         .withSamples(sample));
-        assertThat(cell(sample, "Experiment").of(sampleBrowser()), displays(experiment.getCode()));
-        assertThat(cell(sample, "Project").of(sampleBrowser()), displays(project.getCode()));
+        assertThat(browserEntryOf(sample), containsValue("Experiment", experiment.getCode()));
+        assertThat(browserEntryOf(sample), containsValue("Project", project.getCode()));
     }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/VocabularyTest.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/VocabularyTest.java
index 6e70c53322e..bdbce6eb4ab 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/VocabularyTest.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/suite/VocabularyTest.java
@@ -16,7 +16,7 @@ public class VocabularyTest extends SeleniumTest
     {
         Vocabulary vocabulary = create(aVocabulary());
 
-        assertThat(vocabularyBrowser(), lists(vocabulary));
+        assertThat(browserEntryOf(vocabulary), exists());
     }
 
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Browsable.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Browsable.java
index 390cc6aa821..0ab772e434e 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Browsable.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Browsable.java
@@ -16,13 +16,19 @@
 
 package ch.systemsx.cisd.openbis.uitest.type;
 
-import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserRow;
+import java.util.Collection;
 
+import ch.systemsx.cisd.openbis.uitest.infra.application.GuiApplicationRunner;
+import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserRow;
 
 /**
  * @author anttil
  */
 public interface Browsable
 {
-    public boolean isRepresentedBy(BrowserRow row);
+    public BrowserRow getBrowserContent(GuiApplicationRunner openbis);
+
+    public Collection<String> getColumns();
+
+    public String getCode();
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/DataSet.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/DataSet.java
index ace461ee654..0c6600956bd 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/DataSet.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/DataSet.java
@@ -36,12 +36,6 @@ public class DataSet
         this.experiment = experiment;
     }
 
-    @Override
-    public String toString()
-    {
-        return "DataSet " + this.code;
-    }
-
     public String getCode()
     {
         return code;
@@ -82,4 +76,25 @@ public class DataSet
         this.experiment = experiment;
     }
 
+    @Override
+    public int hashCode()
+    {
+        return code.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o)
+    {
+        if (o instanceof DataSet)
+        {
+            return ((DataSet) o).getCode().equals(code);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString()
+    {
+        return "DataSet " + this.code;
+    }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/DataSetType.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/DataSetType.java
index e6392f7eff6..5c30d2ebf46 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/DataSetType.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/DataSetType.java
@@ -16,7 +16,10 @@
 
 package ch.systemsx.cisd.openbis.uitest.type;
 
-import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserCell;
+import java.util.Arrays;
+import java.util.Collection;
+
+import ch.systemsx.cisd.openbis.uitest.infra.application.GuiApplicationRunner;
 import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserRow;
 
 /**
@@ -35,12 +38,6 @@ public class DataSetType implements Browsable
     }
 
     @Override
-    public boolean isRepresentedBy(BrowserRow row)
-    {
-        BrowserCell codeCell = row.get("Code");
-        return codeCell != null && codeCell.getText().equalsIgnoreCase(this.code);
-    }
-
     public String getCode()
     {
         return code;
@@ -55,4 +52,38 @@ public class DataSetType implements Browsable
     {
         this.description = description;
     }
+
+    @Override
+    public BrowserRow getBrowserContent(GuiApplicationRunner openbis)
+    {
+        return openbis.browseTo(this);
+    }
+
+    @Override
+    public Collection<String> getColumns()
+    {
+        return Arrays.asList("Code", "Description");
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return code.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o)
+    {
+        if (o instanceof DataSetType)
+        {
+            return ((DataSetType) o).getCode().equals(code);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString()
+    {
+        return "DataSetType " + this.code;
+    }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Experiment.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Experiment.java
index f5a31971898..362bcde59e1 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Experiment.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Experiment.java
@@ -16,9 +16,10 @@
 
 package ch.systemsx.cisd.openbis.uitest.type;
 
+import java.util.Arrays;
 import java.util.Collection;
 
-import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserCell;
+import ch.systemsx.cisd.openbis.uitest.infra.application.GuiApplicationRunner;
 import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserRow;
 
 /**
@@ -42,13 +43,6 @@ public class Experiment implements EntityType, Browsable
         this.samples = samples;
     }
 
-    @Override
-    public boolean isRepresentedBy(BrowserRow row)
-    {
-        BrowserCell codeCell = row.get("Code");
-        return codeCell != null && codeCell.getText().equalsIgnoreCase(this.code);
-    }
-
     @Override
     public String getCode()
     {
@@ -84,4 +78,38 @@ public class Experiment implements EntityType, Browsable
     {
         this.samples = samples;
     }
+
+    @Override
+    public BrowserRow getBrowserContent(GuiApplicationRunner openbis)
+    {
+        return openbis.browseTo(this);
+    }
+
+    @Override
+    public Collection<String> getColumns()
+    {
+        return Arrays.asList("Code", "Project", "Experiment Type");
+    }
+
+    @Override
+    public boolean equals(Object o)
+    {
+        if (o instanceof Experiment)
+        {
+            return ((Experiment) o).getCode().equals(code);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return code.hashCode();
+    }
+
+    @Override
+    public String toString()
+    {
+        return "Experiment " + code;
+    }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/ExperimentType.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/ExperimentType.java
index 80c64a25e46..fc42e424200 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/ExperimentType.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/ExperimentType.java
@@ -16,7 +16,10 @@
 
 package ch.systemsx.cisd.openbis.uitest.type;
 
-import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserCell;
+import java.util.Arrays;
+import java.util.Collection;
+
+import ch.systemsx.cisd.openbis.uitest.infra.application.GuiApplicationRunner;
 import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserRow;
 
 /**
@@ -35,12 +38,6 @@ public class ExperimentType implements Browsable
     }
 
     @Override
-    public boolean isRepresentedBy(BrowserRow row)
-    {
-        BrowserCell codeCell = row.get("Code");
-        return codeCell != null && codeCell.getText().equalsIgnoreCase(this.code);
-    }
-
     public String getCode()
     {
         return code;
@@ -55,4 +52,38 @@ public class ExperimentType implements Browsable
     {
         this.description = description;
     }
+
+    @Override
+    public BrowserRow getBrowserContent(GuiApplicationRunner openbis)
+    {
+        return openbis.browseTo(this);
+    }
+
+    @Override
+    public Collection<String> getColumns()
+    {
+        return Arrays.asList("Code", "Description");
+    }
+
+    @Override
+    public boolean equals(Object o)
+    {
+        if (o instanceof ExperimentType)
+        {
+            return ((ExperimentType) o).getCode().equals(code);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return code.hashCode();
+    }
+
+    @Override
+    public String toString()
+    {
+        return "ExperimentType " + code;
+    }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Project.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Project.java
index 21c06f4fd69..faca3131276 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Project.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Project.java
@@ -16,7 +16,10 @@
 
 package ch.systemsx.cisd.openbis.uitest.type;
 
-import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserCell;
+import java.util.Arrays;
+import java.util.Collection;
+
+import ch.systemsx.cisd.openbis.uitest.infra.application.GuiApplicationRunner;
 import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserRow;
 
 /**
@@ -38,12 +41,6 @@ public class Project implements Browsable
     }
 
     @Override
-    public boolean isRepresentedBy(BrowserRow row)
-    {
-        BrowserCell codeCell = row.get("Code");
-        return codeCell != null && codeCell.getText().equalsIgnoreCase(this.code);
-    }
-
     public String getCode()
     {
         return code;
@@ -69,4 +66,38 @@ public class Project implements Browsable
         this.description = description;
     }
 
+    @Override
+    public BrowserRow getBrowserContent(GuiApplicationRunner openbis)
+    {
+        return openbis.browseTo(this);
+    }
+
+    @Override
+    public Collection<String> getColumns()
+    {
+        return Arrays.asList("Code", "Description", "Space");
+    }
+
+    @Override
+    public boolean equals(Object o)
+    {
+        if (o instanceof Project)
+        {
+            return ((Project) o).getCode().equals(code);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return code.hashCode();
+    }
+
+    @Override
+    public String toString()
+    {
+        return "Project " + code;
+    }
+
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/PropertyType.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/PropertyType.java
index ab196564d32..99484d02e2c 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/PropertyType.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/PropertyType.java
@@ -16,7 +16,10 @@
 
 package ch.systemsx.cisd.openbis.uitest.type;
 
-import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserCell;
+import java.util.Arrays;
+import java.util.Collection;
+
+import ch.systemsx.cisd.openbis.uitest.infra.application.GuiApplicationRunner;
 import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserRow;
 
 /**
@@ -24,7 +27,6 @@ import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserRow;
  */
 public class PropertyType implements Browsable
 {
-
     private final String code;
 
     private String label;
@@ -46,36 +48,6 @@ public class PropertyType implements Browsable
     }
 
     @Override
-    public boolean isRepresentedBy(BrowserRow row)
-    {
-        BrowserCell codeCell = row.get("Code");
-        return codeCell != null && codeCell.getText().equalsIgnoreCase(this.code);
-    }
-
-    @Override
-    public boolean equals(Object o)
-    {
-        if (!(o instanceof PropertyType))
-        {
-            return false;
-        }
-
-        PropertyType type = (PropertyType) o;
-        return type.getCode().equals(this.code);
-    }
-
-    @Override
-    public int hashCode()
-    {
-        return this.getCode().hashCode();
-    }
-
-    @Override
-    public String toString()
-    {
-        return "PropertyType " + code + " of type " + dataType;
-    }
-
     public String getCode()
     {
         return code;
@@ -121,4 +93,39 @@ public class PropertyType implements Browsable
         this.vocabulary = vocabulary;
     }
 
+    @Override
+    public BrowserRow getBrowserContent(GuiApplicationRunner openbis)
+    {
+        return openbis.browseTo(this);
+    }
+
+    @Override
+    public Collection<String> getColumns()
+    {
+        return Arrays.asList("Code", "Data Type", "Label", "Description", "Vocabulary");
+    }
+
+    @Override
+    public boolean equals(Object o)
+    {
+        if (!(o instanceof PropertyType))
+        {
+            return false;
+        }
+
+        PropertyType type = (PropertyType) o;
+        return type.getCode().equals(this.code);
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return this.getCode().hashCode();
+    }
+
+    @Override
+    public String toString()
+    {
+        return "PropertyType " + code + " of type " + dataType;
+    }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/PropertyTypeAssignment.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/PropertyTypeAssignment.java
index 193bba21521..b9994019056 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/PropertyTypeAssignment.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/PropertyTypeAssignment.java
@@ -16,7 +16,10 @@
 
 package ch.systemsx.cisd.openbis.uitest.type;
 
-import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserCell;
+import java.util.Arrays;
+import java.util.Collection;
+
+import ch.systemsx.cisd.openbis.uitest.infra.application.GuiApplicationRunner;
 import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserRow;
 
 /**
@@ -42,41 +45,69 @@ public class PropertyTypeAssignment implements Browsable
         this.initialValue = initialValue;
     }
 
-    @Override
-    public boolean isRepresentedBy(BrowserRow row)
+    public PropertyType getPropertyType()
     {
-        BrowserCell propertyTypeCode = row.get("Property Type Code");
-        BrowserCell entityTypeCode = row.get("Entity Type");
+        return propertyType;
+    }
 
-        return propertyTypeCode != null &&
-                entityTypeCode != null &&
-                propertyTypeCode.getText().equalsIgnoreCase(propertyType.getCode()) &&
-                entityTypeCode.getText().equalsIgnoreCase(entityType.getCode());
+    public EntityType getEntityType()
+    {
+        return entityType;
+    }
+
+    public boolean isMandatory()
+    {
+        return mandatory;
+    }
+
+    public String getInitialValue()
+    {
+        return initialValue;
     }
 
     @Override
-    public String toString()
+    public BrowserRow getBrowserContent(GuiApplicationRunner openbis)
     {
-        return "PropertyTypeAssignment [" + this.propertyType + ", " + this.entityType + "]";
+        return openbis.browseTo(this);
     }
 
-    public PropertyType getPropertyType()
+    @Override
+    public Collection<String> getColumns()
     {
-        return propertyType;
+        return Arrays.asList("Property Type Code", "Entity Type", "Mandatory?");
     }
 
-    public EntityType getSampleType()
+    @Override
+    public String getCode()
     {
-        return entityType;
+        return propertyType.getCode();
     }
 
-    public boolean isMandatory()
+    @Override
+    public int hashCode()
     {
-        return mandatory;
+        int result = 17;
+        result = 31 * result + propertyType.getCode().hashCode();
+        result = 31 * result + entityType.getCode().hashCode();
+        return result;
     }
 
-    public String getInitialValue()
+    @Override
+    public boolean equals(Object o)
     {
-        return initialValue;
+        if (o instanceof PropertyTypeAssignment)
+        {
+            PropertyTypeAssignment assignment = (PropertyTypeAssignment) o;
+            return assignment.getPropertyType().getCode().equals(propertyType.getCode()) &&
+                    assignment.getEntityType().getCode().equals(entityType.getCode());
+        }
+        return false;
     }
+
+    @Override
+    public String toString()
+    {
+        return "PropertyTypeAssignment [" + this.propertyType + ", " + this.entityType + "]";
+    }
+
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/PropertyTypeAssignmentBuilder.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/PropertyTypeAssignmentBuilder.java
index b8b08e45466..fa772c7e78b 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/PropertyTypeAssignmentBuilder.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/PropertyTypeAssignmentBuilder.java
@@ -81,7 +81,9 @@ public class PropertyTypeAssignmentBuilder implements Builder<PropertyTypeAssign
             entityType = new SampleTypeBuilder(openbis).create();
         }
 
-        return openbis.create(build());
+        PropertyTypeAssignment assignment = openbis.create(build());
+        entityType.getPropertyTypeAssignments().add(assignment);
+        return assignment;
     }
 
     @Override
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Sample.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Sample.java
index 841e9b72fa0..4b3af31d681 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Sample.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Sample.java
@@ -16,10 +16,12 @@
 
 package ch.systemsx.cisd.openbis.uitest.type;
 
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.Map;
 
-import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserCell;
+import ch.systemsx.cisd.openbis.uitest.infra.application.GuiApplicationRunner;
 import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserRow;
 
 /**
@@ -27,7 +29,6 @@ import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserRow;
  */
 public class Sample implements EntityType, Browsable
 {
-
     private SampleType type;
 
     private final String code;
@@ -51,19 +52,6 @@ public class Sample implements EntityType, Browsable
         this.properties = properties;
     }
 
-    @Override
-    public boolean isRepresentedBy(BrowserRow row)
-    {
-        BrowserCell codeCell = row.get("Code");
-        return codeCell != null && codeCell.getText().equalsIgnoreCase(this.code);
-    }
-
-    @Override
-    public String toString()
-    {
-        return "Sample " + this.code;
-    }
-
     @Override
     public String getCode()
     {
@@ -120,4 +108,44 @@ public class Sample implements EntityType, Browsable
         this.properties = properties;
     }
 
+    @Override
+    public BrowserRow getBrowserContent(GuiApplicationRunner openbis)
+    {
+        return openbis.browseTo(this);
+    }
+
+    @Override
+    public Collection<String> getColumns()
+    {
+        Collection<String> columns = new HashSet<String>();
+        columns.addAll(Arrays.asList("Code", "Experiment", "Parents", "Space", "Sample Type",
+                "Project"));
+        for (PropertyTypeAssignment propertyTypeAssignment : type.getPropertyTypeAssignments())
+        {
+            columns.add(propertyTypeAssignment.getPropertyType().getLabel());
+        }
+        return columns;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return code.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o)
+    {
+        if (o instanceof Sample)
+        {
+            return ((Sample) o).getCode().equals(code);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString()
+    {
+        return "Sample " + this.code;
+    }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/SampleBuilder.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/SampleBuilder.java
index f476fb55531..1c6dcefbab5 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/SampleBuilder.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/SampleBuilder.java
@@ -101,7 +101,7 @@ public class SampleBuilder implements Builder<Sample>
         for (PropertyTypeAssignment assignment : type.getPropertyTypeAssignments())
         {
             if (assignment.isMandatory()
-                    && properties.get(assignment.getPropertyType().getLabel()) == null)
+                    && properties.get(assignment.getPropertyType()) == null)
             {
                 throw new IllegalStateException("missing property");
             }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/SampleType.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/SampleType.java
index 80aa3cfcf3a..db1a205cda5 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/SampleType.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/SampleType.java
@@ -16,9 +16,10 @@
 
 package ch.systemsx.cisd.openbis.uitest.type;
 
+import java.util.Arrays;
 import java.util.Collection;
 
-import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserCell;
+import ch.systemsx.cisd.openbis.uitest.infra.application.GuiApplicationRunner;
 import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserRow;
 
 /**
@@ -64,13 +65,6 @@ public class SampleType implements Browsable, EntityType
         this.propertyTypeAssignments = propertyTypeAssignments;
     }
 
-    @Override
-    public boolean isRepresentedBy(BrowserRow row)
-    {
-        BrowserCell codeCell = row.get("Code");
-        return codeCell != null && codeCell.getText().equalsIgnoreCase(this.code);
-    }
-
     @Override
     public String toString()
     {
@@ -172,4 +166,34 @@ public class SampleType implements Browsable, EntityType
     {
         this.propertyTypeAssignments = propertyTypeAssignments;
     }
+
+    @Override
+    public BrowserRow getBrowserContent(GuiApplicationRunner openbis)
+    {
+        return openbis.browseTo(this);
+    }
+
+    @Override
+    public Collection<String> getColumns()
+    {
+        return Arrays.asList("Code", "Description", "Database Instance", "Validation Script",
+                "Listable?", "Show Container?", "Show Parents?", "Unique Subcodes",
+                "Generate Codes Automatically", "Show Parent Metadata?", "Generated Code Prefix");
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return code.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o)
+    {
+        if (!(o instanceof SampleType))
+        {
+            return false;
+        }
+        return code.equals(((SampleType) o).getCode());
+    }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Space.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Space.java
index aa6e151a0f0..974e1568f27 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Space.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Space.java
@@ -16,7 +16,10 @@
 
 package ch.systemsx.cisd.openbis.uitest.type;
 
-import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserCell;
+import java.util.Arrays;
+import java.util.Collection;
+
+import ch.systemsx.cisd.openbis.uitest.infra.application.GuiApplicationRunner;
 import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserRow;
 
 /**
@@ -35,30 +38,52 @@ public class Space implements Browsable
     }
 
     @Override
-    public boolean isRepresentedBy(BrowserRow row)
+    public String getCode()
+    {
+        return code;
+    }
+
+    public String getDescription()
     {
-        BrowserCell codeCell = row.get("Code");
-        return codeCell != null && codeCell.getText().equalsIgnoreCase(this.code);
+        return description;
+    }
+
+    void setDescription(String description)
+    {
+        this.description = description;
     }
 
     @Override
-    public String toString()
+    public BrowserRow getBrowserContent(GuiApplicationRunner openbis)
     {
-        return "Space " + this.code;
+        return openbis.browseTo(this);
     }
 
-    public String getCode()
+    @Override
+    public Collection<String> getColumns()
     {
-        return code;
+        return Arrays.asList("Code", "Description");
     }
 
-    public String getDescription()
+    @Override
+    public int hashCode()
     {
-        return description;
+        return code.hashCode();
     }
 
-    void setDescription(String description)
+    @Override
+    public boolean equals(Object o)
     {
-        this.description = description;
+        if (o instanceof Space)
+        {
+            return ((Space) o).getCode().equals(code);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString()
+    {
+        return "Space " + this.code;
     }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Vocabulary.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Vocabulary.java
index 59abd08b031..91a7f396917 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Vocabulary.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/type/Vocabulary.java
@@ -16,9 +16,11 @@
 
 package ch.systemsx.cisd.openbis.uitest.type;
 
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Set;
 
-import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserCell;
+import ch.systemsx.cisd.openbis.uitest.infra.application.GuiApplicationRunner;
 import ch.systemsx.cisd.openbis.uitest.page.tab.BrowserRow;
 
 /**
@@ -43,18 +45,6 @@ public class Vocabulary implements Browsable
     }
 
     @Override
-    public boolean isRepresentedBy(BrowserRow row)
-    {
-        BrowserCell codeCell = row.get("Code");
-        return codeCell != null && codeCell.getText().equalsIgnoreCase(this.code);
-    }
-
-    @Override
-    public String toString()
-    {
-        return "Vocabulary " + this.code + ": " + this.terms;
-    }
-
     public String getCode()
     {
         return code;
@@ -89,4 +79,38 @@ public class Vocabulary implements Browsable
     {
         this.url = url;
     }
+
+    @Override
+    public BrowserRow getBrowserContent(GuiApplicationRunner openbis)
+    {
+        return openbis.browseTo(this);
+    }
+
+    @Override
+    public Collection<String> getColumns()
+    {
+        return Arrays.asList("Code", "Description", "URL Template");
+    }
+
+    @Override
+    public String toString()
+    {
+        return "Vocabulary " + this.code + ": " + this.terms;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return code.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o)
+    {
+        if (o instanceof Vocabulary)
+        {
+            return ((Vocabulary) o).getCode().equals(code);
+        }
+        return false;
+    }
 }
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/widget/Grid.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/widget/Grid.java
index bb94d5e18ec..95195dbc30d 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/widget/Grid.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/widget/Grid.java
@@ -16,6 +16,7 @@
 
 package ch.systemsx.cisd.openbis.uitest.widget;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -90,6 +91,33 @@ public class Grid implements Widget
         return new BrowserRow(m);
     }
 
+    public List<BrowserRow> getData()
+    {
+        List<String> columns = new ArrayList<String>();
+        for (WebElement column : getColumns())
+        {
+            columns.add(column.getText());
+        }
+
+        List<BrowserRow> result = new ArrayList<BrowserRow>();
+        Map<String, BrowserCell> map = new HashMap<String, BrowserCell>();
+        int index = 0;
+        for (WebElement element : getCells())
+        {
+            map.put(columns.get(index), new BrowserCell(element.getText(), element
+                    .getAttribute("href")));
+            index++;
+            if (index % columns.size() == 0)
+            {
+                result.add(new BrowserRow(map));
+                map = new HashMap<String, BrowserCell>();
+                index = 0;
+            }
+        }
+
+        return result;
+    }
+
     private List<WebElement> getColumns()
     {
         return context
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/widget/SettingsDialog.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/widget/SettingsDialog.java
index 7f41bb57ea8..cb3532b4c4b 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/widget/SettingsDialog.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/widget/SettingsDialog.java
@@ -21,6 +21,7 @@ import java.util.List;
 import org.openqa.selenium.WebElement;
 
 import ch.systemsx.cisd.openbis.uitest.infra.webdriver.WidgetContext;
+import ch.systemsx.cisd.openbis.uitest.type.Browsable;
 
 /**
  * @author anttil
@@ -50,6 +51,11 @@ public class SettingsDialog implements Widget
         context.find("//*[@class='x-window-bl']//button[text()='OK']").click();
     }
 
+    public void showColumnsOf(Browsable browsable)
+    {
+        showColumns(browsable.getColumns().toArray(new String[0]));
+    }
+
     @Override
     public void setContext(WidgetContext context)
     {
diff --git a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/widget/TreeGrid.java b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/widget/TreeGrid.java
index 6ab6e341b09..b384f2f4dd8 100644
--- a/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/widget/TreeGrid.java
+++ b/ui-test/source/java/ch/systemsx/cisd/openbis/uitest/widget/TreeGrid.java
@@ -50,10 +50,6 @@ public class TreeGrid implements Widget
         }
 
         return false;
-        /*        
-         * throw new IllegalArgumentException("Selection " + label + " not found - these were found: "
-                        + found);
-                        */
     }
 
     @Override
-- 
GitLab