diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/TypedTableAssertions.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/TypedTableAssertions.java
new file mode 100644
index 0000000000000000000000000000000000000000..ba2e7b294b2efd4af044d3efe0bc34f6f389ec6e
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/TypedTableAssertions.java
@@ -0,0 +1,261 @@
+package ch.systemsx.cisd.openbis.systemtest;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.testng.AssertJUnit;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.TypedTableGrid;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.GridRowModels;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TypedTableResultSet;
+import ch.systemsx.cisd.openbis.generic.shared.basic.GridRowModel;
+import ch.systemsx.cisd.openbis.generic.shared.basic.ISerializable;
+import ch.systemsx.cisd.openbis.generic.shared.basic.Row;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ISerializableComparable;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelColumnHeader;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelRowWithObject;
+
+/**
+ * A utility class that can be used to simplify assertions in {@link TypedTableGrid}-related
+ * headless system tests.
+ * 
+ * @author Kaloyan Enimanev
+ */
+public class TypedTableAssertions<T extends ISerializable> extends AssertJUnit
+{
+
+    /**
+     * a convenience method, that can be used as a static import to achieve a fluent-API like
+     * programming style.
+     */
+    public static <S extends ISerializable> TypedTableAssertions<S> assertTable(
+            TypedTableResultSet<S> tableResultSet)
+    {
+        return new TypedTableAssertions<S>(tableResultSet);
+    }
+
+    /**
+     * a convenience method, that can be used as a static import to achieve a fluent-API like
+     * programming style.
+     */
+    public static <S extends ISerializable> TypedTableAssertions<S>.ColumnAssertions assertColumn(
+            TypedTableResultSet<S> tableResultSet,
+            String columnName)
+    {
+        return new TypedTableAssertions<S>(tableResultSet).hasColumn(columnName);
+    }
+
+
+    private TypedTableResultSet<T> tableResultSet;
+
+    private Map<String, TableModelColumnHeader> headers;
+
+    /**
+     * the constructor is tentatively marked as "private" for now. We could make it public in the
+     * future if we decide it will suite our tests better.
+     * 
+     * @param tableResultSet the typed-table result set
+     */
+    private TypedTableAssertions(TypedTableResultSet<T> tableResultSet)
+    {
+        this.tableResultSet = tableResultSet;
+        initializeHeaders();
+    }
+
+    /**
+     * assertion for the total rows number of a table.
+     */
+    public TypedTableAssertions<T> hasNumberOfRows(int rowsNumber)
+    {
+        assertEquals(rowsNumber, tableResultSet.getResultSet().getTotalLength());
+        return this;
+    }
+
+    /**
+     * asserts that the table contains a specified row.
+     */
+    public TypedTableAssertions<T> containsRow(Row row)
+    {
+        Map<String, Object> rowValues = row.getColumnIDValuesMap();
+        // check all specified column names exist in the table
+        for (String columnName : rowValues.keySet())
+        {
+            hasColumn(columnName);
+        }
+        
+        boolean rowFound = false;
+        GridRowModels<TableModelRowWithObject<T>> list = tableResultSet.getResultSet().getList();
+        for (GridRowModel<TableModelRowWithObject<T>> rowModel : list)
+        {
+            if (rowsEqual(rowValues, rowModel))
+            {
+                rowFound = true;
+                break;
+            }
+        }
+
+        if (false == rowFound)
+        {
+            String errMessage =
+                    String.format("Row with cells %s was not discovered in the "
+                            + "table. Its contents were %s", rowValues, getTableContents());
+            fail(errMessage);
+        }
+
+        return this;
+    }
+
+
+    public ColumnAssertions hasColumn(String columnId)
+    {
+        return new ColumnAssertions(columnId);
+    }
+
+    private void initializeHeaders()
+    {
+        headers = new HashMap<String, TableModelColumnHeader>();
+        GridRowModels<TableModelRowWithObject<T>> list = tableResultSet.getResultSet().getList();
+
+        for (TableModelColumnHeader tmch : list.getColumnHeaders())
+        {
+            headers.put(tmch.getId(), tmch);
+        }
+    }
+
+    private boolean rowsEqual(Map<String, Object> rowValues,
+            GridRowModel<TableModelRowWithObject<T>> rowModel)
+    {
+        List<ISerializableComparable> modelValues = rowModel.getOriginalObject().getValues();
+        boolean rowsEqual = true;
+        for (Entry<String, Object> rowCell : rowValues.entrySet())
+        {
+            int valueIndex = headers.get(rowCell.getKey()).getIndex();
+            ISerializableComparable modelValue = modelValues.get(valueIndex);
+            // the modelValue.toString() invocation here is tricky. We do it, since in most of
+            // test cases we match the table contents with Strings. However, if someone wishes
+            // to compare real ISerializableComparable objects we'll need to change the
+            // way we compare our expectations with the model.
+            if (false == rowCell.getValue().equals(modelValue.toString()))
+            {
+                rowsEqual = false;
+                break;
+            }
+        }
+        return rowsEqual;
+    }
+
+    private Collection<String> getHeaderNames()
+    {
+        return headers.keySet();
+    }
+
+    private List<List<String>> getTableContents()
+    {
+        GridRowModels<TableModelRowWithObject<T>> list = tableResultSet.getResultSet().getList();
+        List<List<String>> result = new ArrayList<List<String>>();
+        for (GridRowModel<TableModelRowWithObject<T>> rowModel : list)
+        {
+            List<String> rowContents = new ArrayList<String>();
+            for (Object value : rowModel.getOriginalObject().getValues())
+            {
+                rowContents.add(value.toString());
+            }
+            result.add(rowContents);
+        }
+        return result;
+    }
+
+    /**
+     * column-related assertions.
+     */
+    public class ColumnAssertions
+    {
+        private TableModelColumnHeader header = null;
+
+        private ColumnAssertions(String columnId)
+        {
+            initTableHeader(columnId);
+        }
+
+        /**
+         * prepares the column header for subsequent assertions.
+         */
+        private void initTableHeader(String columnId)
+        {
+            GridRowModels<TableModelRowWithObject<T>> list =
+                    tableResultSet.getResultSet().getList();
+            for (TableModelColumnHeader tmch : list.getColumnHeaders())
+            {
+                if (tmch.getId().equalsIgnoreCase(columnId))
+                {
+                    header = tmch;
+                    return;
+                }
+            }
+
+            String errMessage =
+                    String.format(
+                            "Table header with id '%s' was not discovered in the headers list: %s",
+                            columnId, getHeaderNames());
+            assertNotNull(errMessage, header);
+        }
+
+        /**
+         * just a convenience method redirecting to the {@link #containsValue(String)} with a single
+         * parameter.
+         */
+        public void containsValues(String... values)
+        {
+            for (String value : values)
+            {
+                containsValue(value);
+            }
+        }
+
+        /**
+         * asserts that the column contains a specified value.
+         * 
+         * @param value a value to be searched for
+         */
+        public void containsValue(String value)
+        {
+            GridRowModels<TableModelRowWithObject<T>> list =
+                    tableResultSet.getResultSet().getList();
+            for (GridRowModel<TableModelRowWithObject<T>> rowModel : list)
+            {
+                List<ISerializableComparable> rowValues = rowModel.getOriginalObject().getValues();
+                String cellValue = rowValues.get(header.getIndex()).toString();
+                if (value.equals(cellValue))
+                {
+                    // the expected value has been found
+                    return;
+                }
+            }
+            String errMessage =
+                    String.format(
+                            "The value '%s' was not discovered in column %s. Its contents were : %s",
+                            value, header.getId(), getColumnContents());
+            fail(errMessage);
+
+        }
+
+        private List<String> getColumnContents()
+        {
+            GridRowModels<TableModelRowWithObject<T>> list =
+                    tableResultSet.getResultSet().getList();
+            List<String> result = new ArrayList<String>();
+            for (GridRowModel<TableModelRowWithObject<T>> rowModel : list)
+            {
+                List<ISerializableComparable> rowValues = rowModel.getOriginalObject().getValues();
+                String cellValue = rowValues.get(header.getIndex()).toString();
+                result.add(cellValue);
+            }
+            return result;
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/TypedTableColumnAssertions.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/TypedTableColumnAssertions.java
deleted file mode 100644
index e24fffe1167dd2d872207196e43c92bdc1237f58..0000000000000000000000000000000000000000
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/TypedTableColumnAssertions.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package ch.systemsx.cisd.openbis.systemtest;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.testng.AssertJUnit;
-
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.TypedTableGrid;
-import ch.systemsx.cisd.openbis.generic.client.web.client.dto.GridRowModels;
-import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TypedTableResultSet;
-import ch.systemsx.cisd.openbis.generic.shared.basic.ISerializable;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ISerializableComparable;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelColumnHeader;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelRowWithObject;
-
-/**
- * A utility class that can be used to simplify assertions in {@link TypedTableGrid}-related
- * headless system tests.
- * 
- * @author Kaloyan Enimanev
- */
-public class TypedTableColumnAssertions<T extends ISerializable> extends AssertJUnit
-{
-    /**
-     * a convenience method, that can be used as a static import to achieve a fluent-API like
-     * programming style.
-     */
-    public static <S extends ISerializable> TypedTableColumnAssertions<S> assertColumn(
-            TypedTableResultSet<S> tableResultSet,
-            String columnName)
-    {
-        return new TypedTableColumnAssertions<S>(tableResultSet, columnName);
-    }
-
-    private TypedTableResultSet<T> tableResultSet;
-
-    private TableModelColumnHeader header = null;
-
-    private TypedTableColumnAssertions(TypedTableResultSet<T> tableResultSet, String columnId)
-    {
-        this.tableResultSet = tableResultSet;
-        initTableHeader(columnId);
-    }
-
-    /**
-     * prepares the column header for subsequent assertions.
-     */
-    private void initTableHeader(String columnId)
-    {
-        GridRowModels<TableModelRowWithObject<T>> list =
-                tableResultSet.getResultSet().getList();
-        List<String> headerIds = new ArrayList<String>();
-
-        for (TableModelColumnHeader tmch : list.getColumnHeaders())
-        {
-            String headerId = tmch.getId();
-            headerIds.add(headerId);
-            if (headerId.equalsIgnoreCase(columnId))
-            {
-                header = tmch;
-                return;
-            }
-        }
-
-        String errMessage =
-                String.format(
-                        "Table header with id '%s' was not discovered in the headers list: %s",
-                        columnId, headerIds.toString());
-        assertNotNull(errMessage, header);
-    }
-
-    /**
-     * just a convenience method redirecting to the {@link #containsValue(String)} with a single
-     * parameter.
-     */
-    public void containsValues(String... values)
-    {
-        for (String value : values)
-        {
-            containsValue(value);
-        }
-    }
-
-    /**
-     * asserts that the column contains a specified value.
-     * 
-     * @param value a value to be searched for
-     */
-    public void containsValue(String value)
-    {
-        GridRowModels<TableModelRowWithObject<T>> list =
-            tableResultSet.getResultSet().getList();
-        List<String> presentValues = new ArrayList<String>();
-        for (int i = 0; i < tableResultSet.getResultSet().getTotalLength(); i++)
-        {
-            List<ISerializableComparable> rowValues =
-                    list.get(i).getOriginalObject().getValues();
-            String cellValue = rowValues.get(header.getIndex()).toString();
-            presentValues.add(cellValue);
-            if (value.equals(cellValue))
-            {
-                // the expected value has been found
-                return;
-            }
-        }
-        String errMessage =
-                String.format(
-                        "The value '%s' was not discovered in column %s. Its contents were : %s",
-                        value, header.getId(), presentValues.toString());
-        fail(errMessage);
-
-    }
-}
\ No newline at end of file
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/plugin/generic/FileFormatTypeGridHeadlessTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/plugin/generic/FileFormatTypeHeadlessTest.java
similarity index 79%
rename from openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/plugin/generic/FileFormatTypeGridHeadlessTest.java
rename to openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/plugin/generic/FileFormatTypeHeadlessTest.java
index 130e1f40318dfdcdff094194dea26565327d4467..92c3c3f8afa5c2fce7ba4a622f7aa4c2382f383b 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/plugin/generic/FileFormatTypeGridHeadlessTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/plugin/generic/FileFormatTypeHeadlessTest.java
@@ -16,8 +16,8 @@
 
 package ch.systemsx.cisd.openbis.systemtest.plugin.generic;
 
-import static ch.systemsx.cisd.openbis.systemtest.TypedTableColumnAssertions.assertColumn;
-import static org.testng.AssertJUnit.assertEquals;
+import static ch.systemsx.cisd.openbis.systemtest.TypedTableAssertions.assertColumn;
+import static ch.systemsx.cisd.openbis.systemtest.TypedTableAssertions.assertTable;
 
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -25,6 +25,7 @@ import org.testng.annotations.Test;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.FileFormatTypeGridTest;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DefaultResultSetConfig;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TypedTableResultSet;
+import ch.systemsx.cisd.openbis.generic.shared.basic.Row;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.FileFormatType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelRowWithObject;
 
@@ -34,7 +35,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelRowWithObject
  * @author Kaloyan Enimanev
  */
 @Test(groups = "system test")
-public class FileFormatTypeGridHeadlessTest extends GenericSystemTestCase
+public class FileFormatTypeHeadlessTest extends GenericSystemTestCase
 {
 
     @BeforeMethod
@@ -51,7 +52,7 @@ public class FileFormatTypeGridHeadlessTest extends GenericSystemTestCase
         TypedTableResultSet<FileFormatType> tableResultSet =
                 commonClientService.listFileTypes(criteria);
 
-        assertEquals(8, tableResultSet.getResultSet().getTotalLength());
+        assertTable(tableResultSet).hasNumberOfRows(8);
         assertColumn(tableResultSet, "CODE").containsValues("TIFF", "XML", "HDF5");
     }
 
@@ -70,9 +71,13 @@ public class FileFormatTypeGridHeadlessTest extends GenericSystemTestCase
         TypedTableResultSet<FileFormatType> tableResultSet =
                 commonClientService.listFileTypes(criteria);
 
-        assertEquals(9, tableResultSet.getResultSet().getTotalLength());
-        assertColumn(tableResultSet, "CODE").containsValues(fft.getCode());
-        assertColumn(tableResultSet, "DESCRIPTION").containsValues(fft.getDescription());
+
+        Row expectedRow =
+                new Row().withCell("CODE", fft.getCode()).withCell("DESCRIPTION",
+                        fft.getDescription());
+
+        assertTable(tableResultSet).hasNumberOfRows(9);
+        assertTable(tableResultSet).containsRow(expectedRow);
 
     }