From 8de54936c49b6e44cace55498918063fc77d2b83 Mon Sep 17 00:00:00 2001
From: felmer <felmer>
Date: Thu, 9 Dec 2010 13:10:51 +0000
Subject: [PATCH] LMS-1783 tests fixed concerning escaping permlink,
 SampleProvider creates complete table, all links supported in
 SampleBrowserGrid2

SVN: 19064
---
 .../web/client/ICommonClientService.java      |  15 ++
 .../web/client/ICommonClientServiceAsync.java |  12 +
 .../client/web/client/application/Dict.java   |   2 +
 .../framework/ComponentProvider.java          |   3 +-
 .../application/renderer/YesNoRenderer.java   |   2 +-
 .../AbstractColumnDefinitionKind.java         |   2 +-
 .../specific/CustomGridColumnColDefKind.java  |   2 +-
 .../specific/CustomGridFilterColDefKind.java  |   2 +-
 .../PropertyTypeAssignmentColDefKind.java     |   2 +-
 .../specific/VocabularyColDefKind.java        |   2 +-
 .../data/CommonExternalDataColDefKind.java    |   2 +-
 .../sample/CommonSampleColDefKind.java        |   2 +-
 .../specific/sample/SampleTypeColDefKind.java |   2 +-
 .../ui/sample/SampleBrowserGrid2.java         | 222 +++++++++++++++++-
 .../client/dto/ListSampleDisplayCriteria.java |   2 +-
 .../dto/ListSampleDisplayCriteria2.java       | 163 +++++++++++++
 .../web/client/dto/SampleGridColumnIDs.java   |  61 +++++
 .../web/server/CommonClientService.java       |  16 ++
 .../web/server/resultset/SampleProvider.java  | 161 +++++++++++++
 .../basic}/SimpleYesNoRenderer.java           |   2 +-
 .../generic/shared/util/DataTypeUtils.java    |   5 +
 .../ui/columns/QueryColDefKind.java           |   2 +-
 .../cisd/openbis/public/common-dictionary.js  |   2 +
 .../EntityTypePropertyTypeAssignmentTest.java |   2 +-
 .../ui/data/columns/DataSetRow.java           |   2 +-
 .../ui/experiment/columns/ExperimentRow.java  |   2 +-
 .../ui/sample/columns/SampleRow.java          |   2 +-
 .../plugin/generic/SampleDetailsTest.java     |   9 +-
 28 files changed, 678 insertions(+), 25 deletions(-)
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ListSampleDisplayCriteria2.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/SampleGridColumnIDs.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/SampleProvider.java
 rename openbis/source/java/ch/systemsx/cisd/openbis/generic/{client/web/client/application/ui/columns/framework/renderers => shared/basic}/SimpleYesNoRenderer.java (88%)

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
index 5dbb0a8e89b..8ee0a1a03d8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
@@ -29,6 +29,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListExperimentsCri
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListMaterialDisplayCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListPersonsCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListSampleDisplayCriteria;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListSampleDisplayCriteria2;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListScriptsCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.RelatedDataSetCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSet;
@@ -229,6 +230,12 @@ public interface ICommonClientService extends IClientService
     public ResultSetWithEntityTypes<Sample> listSamples(final ListSampleDisplayCriteria criteria)
             throws UserFailureException;
 
+    /**
+     * Returns a list of samples matching given criteria.
+     */
+    public TypedTableResultSet<Sample> listSamples2(final ListSampleDisplayCriteria2 criteria)
+            throws UserFailureException;
+    
     /**
      * Returns a key which can be used be the export servlet (and eventually
      * {@link #getExportTable(String, String)}) to reference the export criteria in an easy way.
@@ -236,6 +243,14 @@ public interface ICommonClientService extends IClientService
     public String prepareExportSamples(final TableExportCriteria<Sample> criteria)
             throws UserFailureException;
 
+    /**
+     * Returns a key which can be used be the export servlet (and eventually
+     * {@link #getExportTable(String, String)}) to reference the export criteria in an easy way.
+     */
+    public String prepareExportSamples2(
+            final TableExportCriteria<TableModelRowWithObject<Sample>> criteria)
+            throws UserFailureException;
+    
     /**
      * Returns a list of experiments.
      */
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
index b792034ef8c..86b0b7aa8c2 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
@@ -31,6 +31,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListExperimentsCri
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListMaterialDisplayCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListPersonsCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListSampleDisplayCriteria;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListSampleDisplayCriteria2;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListScriptsCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.RelatedDataSetCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSet;
@@ -190,12 +191,23 @@ public interface ICommonClientServiceAsync extends IClientServiceAsync
     public void listSamples(final ListSampleDisplayCriteria criteria,
             AsyncCallback<ResultSetWithEntityTypes<Sample>> asyncCallback);
 
+    /**
+     * @see ICommonClientService#listSamples2(ListSampleDisplayCriteria2)
+     */
+    public void listSamples2(final ListSampleDisplayCriteria2 criteria,
+            AsyncCallback<TypedTableResultSet<Sample>> asyncCallback);
+    
     /**
      * @see ICommonClientService#prepareExportSamples(TableExportCriteria)
      */
     public void prepareExportSamples(final TableExportCriteria<Sample> criteria,
             AsyncCallback<String> asyncCallback);
 
+    /** @see ICommonClientService#prepareExportSamples2(TableExportCriteria) */
+    public void prepareExportSamples2(
+            TableExportCriteria<TableModelRowWithObject<Sample>> exportCriteria,
+            AsyncCallback<String> callback);
+
     /** @see ICommonClientService#listPropertyTypeAssignments(DefaultResultSetConfig) */
     public void listPropertyTypeAssignments(
             DefaultResultSetConfig<String, EntityTypePropertyType<?>> criteria,
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java
index 62fd1f6f0ba..d7b4c5835c0 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java
@@ -217,6 +217,8 @@ public abstract class Dict
     public static final String IS_INVALID = "is_invalid";
 
     public static final String GROUP = "group";
+    
+    public static final String SPACE = "space";
 
     public static final String GROUPS = "groups";
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java
index d1f76d65980..4ace3d1310b 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java
@@ -51,6 +51,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.propert
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.property_type.PropertyTypeRegistrationForm;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.SampleBatchRegisterUpdatePanel;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.SampleBrowserGrid;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.SampleBrowserGrid2;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.SampleRegistrationPanel;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.SampleSearchHitGrid;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.SampleTypeGrid;
@@ -116,7 +117,7 @@ public final class ComponentProvider
                 public ITabItem create()
                 {
                     IDisposableComponent browser =
-                            SampleBrowserGrid.create(viewContext, initialGroupOrNull,
+                            SampleBrowserGrid2.create(viewContext, initialGroupOrNull,
                                     initialSampleTypeOrNull);
                     return createTab(getTabTitle(), browser);
                 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/renderer/YesNoRenderer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/renderer/YesNoRenderer.java
index 8abc2d4589d..6637289941a 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/renderer/YesNoRenderer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/renderer/YesNoRenderer.java
@@ -6,7 +6,7 @@ import com.extjs.gxt.ui.client.widget.grid.ColumnData;
 import com.extjs.gxt.ui.client.widget.grid.Grid;
 import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
 
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.renderers.SimpleYesNoRenderer;
+import ch.systemsx.cisd.openbis.generic.shared.basic.SimpleYesNoRenderer;
 
 /**
  * Renderer of {@link Boolean} value. Render <code>true</code> to <code>yes</code> and
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/framework/AbstractColumnDefinitionKind.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/framework/AbstractColumnDefinitionKind.java
index def54d72fcc..abd8a21cdba 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/framework/AbstractColumnDefinitionKind.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/framework/AbstractColumnDefinitionKind.java
@@ -16,11 +16,11 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework;
 
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.renderers.SimpleYesNoRenderer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.GridRowModel;
 import ch.systemsx.cisd.openbis.generic.shared.basic.IInvalidationProvider;
 import ch.systemsx.cisd.openbis.generic.shared.basic.SimpleDateRenderer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.SimplePersonRenderer;
+import ch.systemsx.cisd.openbis.generic.shared.basic.SimpleYesNoRenderer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractRegistrationHolder;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Person;
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/CustomGridColumnColDefKind.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/CustomGridColumnColDefKind.java
index 4c370ff11b0..12eab1723fc 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/CustomGridColumnColDefKind.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/CustomGridColumnColDefKind.java
@@ -19,7 +19,7 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.column
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.AbstractColumnDefinitionKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.IColumnDefinitionKind;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.renderers.SimpleYesNoRenderer;
+import ch.systemsx.cisd.openbis.generic.shared.basic.SimpleYesNoRenderer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.GridCustomColumn;
 
 /**
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/CustomGridFilterColDefKind.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/CustomGridFilterColDefKind.java
index ffd2ad95264..df782c92734 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/CustomGridFilterColDefKind.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/CustomGridFilterColDefKind.java
@@ -19,7 +19,7 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.column
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.AbstractColumnDefinitionKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.IColumnDefinitionKind;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.renderers.SimpleYesNoRenderer;
+import ch.systemsx.cisd.openbis.generic.shared.basic.SimpleYesNoRenderer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.GridCustomFilter;
 
 /**
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/PropertyTypeAssignmentColDefKind.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/PropertyTypeAssignmentColDefKind.java
index 07ec2159758..1ecdb3e564a 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/PropertyTypeAssignmentColDefKind.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/PropertyTypeAssignmentColDefKind.java
@@ -19,7 +19,7 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.column
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.AbstractColumnDefinitionKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.IColumnDefinitionKind;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.renderers.SimpleYesNoRenderer;
+import ch.systemsx.cisd.openbis.generic.shared.basic.SimpleYesNoRenderer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityTypePropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Script;
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/VocabularyColDefKind.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/VocabularyColDefKind.java
index 5e48a64d9e5..4720ff6c704 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/VocabularyColDefKind.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/VocabularyColDefKind.java
@@ -19,7 +19,7 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.column
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.AbstractColumnDefinitionKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.IColumnDefinitionKind;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.renderers.SimpleYesNoRenderer;
+import ch.systemsx.cisd.openbis.generic.shared.basic.SimpleYesNoRenderer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
 
 /**
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/data/CommonExternalDataColDefKind.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/data/CommonExternalDataColDefKind.java
index 945a05c839c..829ab25a278 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/data/CommonExternalDataColDefKind.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/data/CommonExternalDataColDefKind.java
@@ -20,8 +20,8 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.AbstractColumnDefinitionKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.IColumnDefinitionKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.LinkExtractor;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.renderers.SimpleYesNoRenderer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.SimpleDateRenderer;
+import ch.systemsx.cisd.openbis.generic.shared.basic.SimpleYesNoRenderer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.FileFormatType;
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/sample/CommonSampleColDefKind.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/sample/CommonSampleColDefKind.java
index 3e2ff2c60e5..2cafe198083 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/sample/CommonSampleColDefKind.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/sample/CommonSampleColDefKind.java
@@ -20,7 +20,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.AbstractColumnDefinitionKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.IColumnDefinitionKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.LinkExtractor;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.renderers.SimpleYesNoRenderer;
+import ch.systemsx.cisd.openbis.generic.shared.basic.SimpleYesNoRenderer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/sample/SampleTypeColDefKind.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/sample/SampleTypeColDefKind.java
index fa737d6a061..8e15e72ee1c 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/sample/SampleTypeColDefKind.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/sample/SampleTypeColDefKind.java
@@ -21,7 +21,7 @@ import static ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.AbstractColumnDefinitionKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.IColumnDefinitionKind;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.renderers.SimpleYesNoRenderer;
+import ch.systemsx.cisd.openbis.generic.shared.basic.SimpleYesNoRenderer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
 
 /**
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowserGrid2.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowserGrid2.java
index 158e33a6ba0..2ae67de1548 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowserGrid2.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowserGrid2.java
@@ -16,6 +16,11 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample;
 
+import static ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.createOrDelete;
+import static ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.edit;
+
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -24,6 +29,7 @@ import com.extjs.gxt.ui.client.event.ButtonEvent;
 import com.extjs.gxt.ui.client.event.SelectionListener;
 import com.extjs.gxt.ui.client.widget.Dialog;
 import com.extjs.gxt.ui.client.widget.button.Button;
+import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
 import com.google.gwt.user.client.rpc.AsyncCallback;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
@@ -37,29 +43,43 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DisplayTypeIDGenerator;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.IDisplayTypeIDGenerator;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.SampleTypeDisplayID;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.BaseEntityModel;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.renderer.LinkRenderer;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.renderer.PersonRenderer;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.DisplayedAndSelectedEntities;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.TypedTableGrid;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.LinkExtractor;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.AbstractEntityBrowserGrid.ICriteriaProvider;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.ColumnDefsAndConfigs;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.DisposableEntityChooser;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IBrowserGridActionInvoker;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.ICellListenerAndLinkGenerator;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IDisposableComponent;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.entity.PropertyTypesCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.entity.PropertyTypesCriteriaProvider;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.entity.PropertyTypesFilterUtil;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.listener.OpenEntityDetailsTabAction;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.listener.OpenEntityDetailsTabHelper;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.IDataRefreshCallback;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IDelegatedAction;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IDelegatedActionWithResult;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.SetUtils;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DefaultResultSetConfig;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListEntityDisplayCriteriaKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListSampleDisplayCriteria;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListSampleDisplayCriteria2;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableExportCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TypedTableResultSet;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.BasicEntityType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.ObjectKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ISerializableComparable;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListSampleCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
@@ -309,15 +329,181 @@ public class SampleBrowserGrid2 extends TypedTableGrid<Sample>
     {
         super(viewContext, browserId, displayTypeIDGenerator);
         propertyTypesAndCriteriaProvider = criteriaProvider;
+        linkSample();
+        linkExperiment();
+        linkProject();
+        linkParent();
+        linkContainer();
+    }
+
+    private void linkSample()
+    {
+        ICellListenerAndLinkGenerator<Sample> listenerLinkGenerator =
+                new ICellListenerAndLinkGenerator<Sample>()
+                    {
+                        public void handle(TableModelRowWithObject<Sample> rowItem,
+                                boolean specialKeyPressed)
+                        {
+                            showEntityViewer(rowItem.getObjectOrNull(), false, specialKeyPressed);
+                        }
+
+                        public String tryGetLink(Sample entity,
+                                ISerializableComparable comparableValue)
+                        {
+                            return LinkExtractor.tryExtract(entity);
+                        }
+                    };
+        registerListenerAndLinkGenerator(SampleGridColumnIDs.CODE, listenerLinkGenerator);
+        registerListenerAndLinkGenerator(SampleGridColumnIDs.SUBCODE, listenerLinkGenerator);
+        registerListenerAndLinkGenerator(SampleGridColumnIDs.SAMPLE_IDENTIFIER,
+                listenerLinkGenerator);
+    }
+
+    private void linkExperiment()
+    {
+        ICellListenerAndLinkGenerator<Sample> listenerLinkGenerator =
+                new ICellListenerAndLinkGenerator<Sample>()
+                    {
+                        public void handle(TableModelRowWithObject<Sample> rowItem,
+                                boolean specialKeyPressed)
+                        {
+                            Experiment experiment = rowItem.getObjectOrNull().getExperiment();
+                            new OpenEntityDetailsTabAction(experiment, viewContext,
+                                    specialKeyPressed).execute();
+                        }
+
+                        public String tryGetLink(Sample entity,
+                                ISerializableComparable comparableValue)
+                        {
+                            return LinkExtractor.tryExtract(entity.getExperiment());
+                        }
+                    };
+        registerListenerAndLinkGenerator(SampleGridColumnIDs.EXPERIMENT, listenerLinkGenerator);
+        registerListenerAndLinkGenerator(SampleGridColumnIDs.EXPERIMENT_IDENTFIER,
+                listenerLinkGenerator);
     }
     
+    private void linkProject()
+    {
+        registerListenerAndLinkGenerator(SampleGridColumnIDs.PROJECT,
+                new ICellListenerAndLinkGenerator<Sample>()
+                    {
+                        public void handle(TableModelRowWithObject<Sample> rowItem,
+                                boolean specialKeyPressed)
+                        {
+                            final Project project =
+                                    rowItem.getObjectOrNull().getExperiment().getProject();
+                            final String href = LinkExtractor.tryExtract(project);
+                            OpenEntityDetailsTabHelper.open(viewContext, project,
+                                    specialKeyPressed, href);
+                        }
+
+                        public String tryGetLink(Sample entity,
+                                ISerializableComparable comparableValue)
+                        {
+                            final Experiment exp = entity.getExperiment();
+                            return exp == null ? null : LinkExtractor.tryExtract(exp.getProject());
+                        }
+                    });
+    }
+
+    private void linkParent()
+    {
+        registerListenerAndLinkGenerator(SampleGridColumnIDs.PARENTS,
+                new ICellListenerAndLinkGenerator<Sample>()
+                    {
+                        public void handle(TableModelRowWithObject<Sample> rowItem,
+                                boolean specialKeyPressed)
+                        {
+                            showEntityViewer(rowItem.getObjectOrNull().getGeneratedFrom(), false,
+                                    specialKeyPressed);
+                        }
+
+                        public String tryGetLink(Sample entity,
+                                ISerializableComparable comparableValue)
+                        {
+                            Sample parent = entity.getGeneratedFrom();
+                            if (parent == null)
+                            {
+                                return null;
+                            }
+                            return LinkExtractor.tryExtract(parent);
+                        }
+                    });
+    }
+
+    private void linkContainer()
+    {
+        registerListenerAndLinkGenerator(SampleGridColumnIDs.CONTAINER_SAMPLE,
+                new ICellListenerAndLinkGenerator<Sample>()
+                    {
+                        public void handle(TableModelRowWithObject<Sample> rowItem,
+                                boolean specialKeyPressed)
+                        {
+                            showEntityViewer(rowItem.getObjectOrNull().getContainer(), false,
+                                    specialKeyPressed);
+                        }
+
+                        public String tryGetLink(Sample entity,
+                                ISerializableComparable comparableValue)
+                        {
+                            Sample container = entity.getContainer();
+                            if (container == null)
+                            {
+                                return null;
+                            }
+                            return LinkExtractor.tryExtract(container);
+                        }
+                    });
+    }
+
+    @Override
+    protected String translateColumnIdToDictionaryKey(String columnID)
+    {
+        return columnID.toLowerCase();
+    }
+
+    @Override
+    protected ColumnDefsAndConfigs<TableModelRowWithObject<Sample>> createColumnsDefinition()
+    {
+        ColumnDefsAndConfigs<TableModelRowWithObject<Sample>> definitions =
+                super.createColumnsDefinition();
+        definitions.setGridCellRendererFor(SampleGridColumnIDs.REGISTRATOR,
+                PersonRenderer.REGISTRATOR_RENDERER);
+        definitions.setGridCellRendererFor(SampleGridColumnIDs.SHOW_DETAILS_LINK_COLUMN_NAME,
+                createShowDetailsLinkCellRenderer());
+        return definitions;
+    }
+
+    protected final GridCellRenderer<BaseEntityModel<?>> createShowDetailsLinkCellRenderer()
+    {
+        return LinkRenderer.createExternalLinkRenderer(viewContext
+                .getMessage(Dict.SHOW_DETAILS_LINK_TEXT_VALUE));
+
+    }
+
+    @Override
+    protected List<String> getColumnIdsOfFilters()
+    {
+        return Arrays.asList(SampleGridColumnIDs.CODE, SampleGridColumnIDs.EXPERIMENT, SampleGridColumnIDs.PROJECT);
+    }
+
     @Override
     protected void listTableRows(
             DefaultResultSetConfig<String, TableModelRowWithObject<Sample>> resultSetConfig,
             AsyncCallback<TypedTableResultSet<Sample>> callback)
     {
-        // TODO Auto-generated method stub
-        
+        ListSampleDisplayCriteria c1 = getCriteriaProvider().tryGetCriteria();
+        ListSampleDisplayCriteria2 criteria;
+        if (c1.getCriteriaKind() == ListEntityDisplayCriteriaKind.BROWSE)
+        {
+            criteria = new ListSampleDisplayCriteria2(c1.getBrowseCriteria());
+        } else
+        {
+            criteria = new ListSampleDisplayCriteria2(c1.getSearchCriteria());
+        }
+        criteria.copyPagingConfig(resultSetConfig);
+        viewContext.getService().listSamples2(criteria, callback);
     }
 
     @Override
@@ -325,8 +511,36 @@ public class SampleBrowserGrid2 extends TypedTableGrid<Sample>
             TableExportCriteria<TableModelRowWithObject<Sample>> exportCriteria,
             AbstractAsyncCallback<String> callback)
     {
-        // TODO Auto-generated method stub
-        
+        viewContext.getService().prepareExportSamples2(exportCriteria, callback);
+    }
+
+    @Override
+    public DatabaseModificationKind[] getRelevantModifications()
+    {
+        List<DatabaseModificationKind> relevantModifications =
+                new ArrayList<DatabaseModificationKind>();
+        SetUtils.addAll(relevantModifications, getCriteriaProvider().getRelevantModifications());
+        relevantModifications.addAll(getGridRelevantModifications());
+        return relevantModifications.toArray(DatabaseModificationKind.EMPTY_ARRAY);
+    }
+
+    protected Set<DatabaseModificationKind> getGridRelevantModifications()
+    {
+        Set<DatabaseModificationKind> result = getGridRelevantModifications(ObjectKind.SAMPLE);
+        result.add(edit(ObjectKind.PROJECT));
+        return result;
+    }
+
+    protected final static Set<DatabaseModificationKind> getGridRelevantModifications(
+            ObjectKind entity)
+    {
+        Set<DatabaseModificationKind> result = new HashSet<DatabaseModificationKind>();
+        result.add(createOrDelete(entity));
+        result.add(edit(entity));
+        result.add(createOrDelete(ObjectKind.PROPERTY_TYPE_ASSIGNMENT));
+        result.add(edit(ObjectKind.PROPERTY_TYPE_ASSIGNMENT));
+        result.add(edit(ObjectKind.VOCABULARY_TERM));
+        return result;
     }
 
     /**
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ListSampleDisplayCriteria.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ListSampleDisplayCriteria.java
index 849cb3b9485..220f8ae5942 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ListSampleDisplayCriteria.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ListSampleDisplayCriteria.java
@@ -77,7 +77,7 @@ public class ListSampleDisplayCriteria extends DefaultResultSetConfig<String, Sa
 
     private ListSampleCriteria listCriteriaOrNull;
 
-    private ListSampleDisplayCriteria(final DetailedSearchCriteria searchCriteria)
+     ListSampleDisplayCriteria(final DetailedSearchCriteria searchCriteria)
     {
         assert searchCriteria != null : "search criteria not set";
         this.criteriaKind = ListEntityDisplayCriteriaKind.SEARCH;
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ListSampleDisplayCriteria2.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ListSampleDisplayCriteria2.java
new file mode 100644
index 00000000000..0e45e6114ba
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ListSampleDisplayCriteria2.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2009 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.client.web.client.dto;
+
+import com.google.gwt.user.client.rpc.IsSerializable;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListSampleCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelRowWithObject;
+
+/**
+ * Criteria for listing <i>samples</i> and displaying them in the grid.<br>
+ * <br>
+ * Used either for browsing or for searching.
+ * 
+ * @author Tomasz Pylak
+ * @author Piotr Buczek
+ */
+public class ListSampleDisplayCriteria2 extends DefaultResultSetConfig<String, TableModelRowWithObject<Sample>> implements
+        IsSerializable
+{
+    public static ListSampleDisplayCriteria2 createForContainer(final TechId containerSampleId)
+    {
+        return new ListSampleDisplayCriteria2(ListSampleCriteria
+                .createForContainer(containerSampleId));
+    }
+
+    public static ListSampleDisplayCriteria2 createForParent(final TechId parentSampleId)
+    {
+        return new ListSampleDisplayCriteria2(ListSampleCriteria.createForParent(parentSampleId));
+    }
+
+    public static ListSampleDisplayCriteria2 createForChild(final TechId childSampleId)
+    {
+        return new ListSampleDisplayCriteria2(ListSampleCriteria.createForChild(childSampleId));
+    }
+
+    public static ListSampleDisplayCriteria2 createForExperiment(final TechId experimentId)
+    {
+        return new ListSampleDisplayCriteria2(ListSampleCriteria.createForExperiment(experimentId));
+    }
+
+    public static ListSampleDisplayCriteria2 createForSearch()
+    {
+        return createForSearch(new DetailedSearchCriteria());
+    }
+
+    private static ListSampleDisplayCriteria2 createForSearch(
+            final DetailedSearchCriteria searchCriteria)
+    {
+        return new ListSampleDisplayCriteria2(searchCriteria);
+    }
+
+    private ListEntityDisplayCriteriaKind criteriaKind;
+
+    // artificial 'all' SampleType
+    private SampleType allSampleTypeOrNull;
+
+    // either search criteria or list criteria is set
+    private DetailedSearchCriteria searchCriteriaOrNull;
+
+    private ListSampleCriteria listCriteriaOrNull;
+
+    public ListSampleDisplayCriteria2(final DetailedSearchCriteria searchCriteria)
+    {
+        assert searchCriteria != null : "search criteria not set";
+        this.criteriaKind = ListEntityDisplayCriteriaKind.SEARCH;
+        this.setSearchCriteriaOrNull(searchCriteria);
+    }
+
+    public ListSampleDisplayCriteria2(final ListSampleCriteria listCriteria)
+    {
+        assert listCriteria != null : "list criteria not set";
+        this.criteriaKind = ListEntityDisplayCriteriaKind.BROWSE;
+        this.setListCriteriaOrNull(listCriteria);
+    }
+
+    public ListEntityDisplayCriteriaKind getCriteriaKind()
+    {
+        return criteriaKind;
+    }
+
+    public ListSampleCriteria getBrowseCriteria()
+    {
+        assert getCriteriaKind() == ListEntityDisplayCriteriaKind.BROWSE : "not a browse criteria";
+        return getListCriteriaOrNull();
+    }
+
+    public DetailedSearchCriteria getSearchCriteria()
+    {
+        assert getCriteriaKind() == ListEntityDisplayCriteriaKind.SEARCH : "not a search criteria";
+        return getSearchCriteriaOrNull();
+    }
+
+    public void updateSearchCriteria(final DetailedSearchCriteria newSearchCriteria)
+    {
+        assert getCriteriaKind() == ListEntityDisplayCriteriaKind.SEARCH : "not a search criteria";
+        assert newSearchCriteria != null : "new search criteria not set";
+        setSearchCriteriaOrNull(newSearchCriteria);
+    }
+
+    private ListSampleCriteria getListCriteriaOrNull()
+    {
+        return listCriteriaOrNull;
+    }
+
+    private void setListCriteriaOrNull(ListSampleCriteria listCriteriaOrNull)
+    {
+        this.listCriteriaOrNull = listCriteriaOrNull;
+    }
+
+    private DetailedSearchCriteria getSearchCriteriaOrNull()
+    {
+        return searchCriteriaOrNull;
+    }
+
+    private void setSearchCriteriaOrNull(DetailedSearchCriteria searchCriteriaOrNull)
+    {
+        this.searchCriteriaOrNull = searchCriteriaOrNull;
+    }
+
+    public void setAllSampleType(SampleType sampleType)
+    {
+        this.allSampleTypeOrNull = sampleType;
+    }
+
+    public SampleType tryGetSampleType()
+    {
+        if (allSampleTypeOrNull != null)
+        {
+            return allSampleTypeOrNull;
+        } else
+        {
+            return listCriteriaOrNull != null ? listCriteriaOrNull.getSampleType() : null;
+        }
+    }
+
+    //
+    // GWT only
+    //
+    @SuppressWarnings("unused")
+    private ListSampleDisplayCriteria2()
+    {
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/SampleGridColumnIDs.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/SampleGridColumnIDs.java
new file mode 100644
index 00000000000..8d7cc6facdf
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/SampleGridColumnIDs.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2010 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.client.web.client.dto;
+
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class SampleGridColumnIDs
+{
+    public static final String CODE = "CODE";
+    
+    public static final String SUBCODE = "SUBCODE";
+
+    public static final String SPACE = "SPACE";
+    
+    public static final String REGISTRATOR = "REGISTRATOR";
+
+    public static final String REGISTRATION_DATE = "REGISTRATION_DATE";
+
+    public static final String SAMPLE_TYPE = "SAMPLE_TYPE";
+
+    public static final String DATABASE_INSTANCE = "DATABASE_INSTANCE";
+
+    public static final String SAMPLE_IDENTIFIER = "SAMPLE_IDENTIFIER";
+    
+    public static final String IS_INSTANCE_SAMPLE = "IS_INSTANCE_SAMPLE";
+    
+    public static final String IS_IVALID = "IS_INVALID";
+    
+    public static final String EXPERIMENT = "EXPERIMENT";
+    
+    public static final String EXPERIMENT_IDENTFIER = "EXPERIMENT_IDENTIFIER";
+    
+    public static final String PROJECT = "PROJECT";
+    
+    public static final String PERM_ID = "PERM_ID";
+    
+    public static final String SHOW_DETAILS_LINK_COLUMN_NAME = "SHOW_DETAILS_LINK_COLUMN_NAME";
+    
+    public static final String PARENTS = "PARENTS";
+    
+    public static final String CONTAINER_SAMPLE = "CONTAINER_SAMPLE";
+}
+
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
index f7c8d84432c..b53383b07f6 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
@@ -53,6 +53,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListExperimentsCri
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListMaterialDisplayCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListPersonsCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListSampleDisplayCriteria;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListSampleDisplayCriteria2;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListScriptsCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.RelatedDataSetCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSet;
@@ -68,6 +69,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.CacheManager
 import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.DataProviderAdapter;
 import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.IOriginalDataProvider;
 import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.IResultSet;
+import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.SampleProvider;
 import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.SpacesProvider;
 import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.TableDataProviderFactory;
 import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.VocabularyTermsProvider;
@@ -416,6 +418,12 @@ public final class CommonClientService extends AbstractClientService implements
         return prepareExportEntities(criteria);
     }
 
+    public String prepareExportSamples2(
+            TableExportCriteria<TableModelRowWithObject<Sample>> criteria)
+    {
+        return prepareExportEntities(criteria);
+    }
+
     public final String prepareExportExperiments(final TableExportCriteria<Experiment> criteria)
     {
         return prepareExportEntities(criteria);
@@ -514,6 +522,14 @@ public final class CommonClientService extends AbstractClientService implements
                 commonServer, sessionToken, listCriteria));
     }
 
+    public TypedTableResultSet<Sample> listSamples2(ListSampleDisplayCriteria2 criteria)
+    {
+        SampleProvider provider = new SampleProvider(commonServer, getSessionToken(), criteria);
+        DataProviderAdapter<Sample> dataProvider = new DataProviderAdapter<Sample>(provider);
+        ResultSet<TableModelRowWithObject<Sample>> resultSet = listEntities(criteria, dataProvider);
+        return new TypedTableResultSet<Sample>(resultSet);
+    }
+
     public ResultSetWithEntityTypes<ExternalData> searchForDataSets(
             DetailedSearchCriteria criteria,
             final IResultSetConfig<String, ExternalData> resultSetConfig)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/SampleProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/SampleProvider.java
new file mode 100644
index 00000000000..cfe07894692
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/resultset/SampleProvider.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2010 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.client.web.server.resultset;
+
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.CODE;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.CONTAINER_SAMPLE;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.DATABASE_INSTANCE;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.EXPERIMENT;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.EXPERIMENT_IDENTFIER;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.IS_INSTANCE_SAMPLE;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.IS_IVALID;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.PARENTS;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.PERM_ID;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.PROJECT;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.REGISTRATION_DATE;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.REGISTRATOR;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.SAMPLE_IDENTIFIER;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.SAMPLE_TYPE;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.SHOW_DETAILS_LINK_COLUMN_NAME;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.SPACE;
+import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridColumnIDs.SUBCODE;
+
+import java.util.List;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListSampleDisplayCriteria2;
+import ch.systemsx.cisd.openbis.generic.shared.ICommonServer;
+import ch.systemsx.cisd.openbis.generic.shared.basic.SimpleYesNoRenderer;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TypedTableModel;
+import ch.systemsx.cisd.openbis.generic.shared.util.TypedTableModelBuilder;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class SampleProvider extends AbstractCommonTableModelProvider<Sample>
+{
+    private final ListSampleDisplayCriteria2 criteria;
+
+    public SampleProvider(ICommonServer commonServer, String sessionToken, ListSampleDisplayCriteria2 criteria)
+    {
+        super(commonServer, sessionToken);
+        this.criteria = criteria;
+    }
+
+    @Override
+    protected TypedTableModel<Sample> createTableModel()
+    {
+        List<Sample> samples = getSamples();
+        TypedTableModelBuilder<Sample> builder = new TypedTableModelBuilder<Sample>();
+        builder.addColumn(CODE);
+        builder.addColumn(SUBCODE).hideByDefault();
+        builder.addColumn(DATABASE_INSTANCE).hideByDefault();
+        builder.addColumn(SPACE).hideByDefault();
+        builder.addColumn(SAMPLE_IDENTIFIER).withDefaultWidth(150).hideByDefault();
+        builder.addColumn(SAMPLE_TYPE).withDefaultWidth(150).hideByDefault();
+        builder.addColumn(IS_INSTANCE_SAMPLE).hideByDefault();
+        builder.addColumn(IS_IVALID).hideByDefault();
+        builder.addColumn(REGISTRATOR).withDefaultWidth(200);
+        builder.addColumn(REGISTRATION_DATE).withDefaultWidth(300).hideByDefault();
+        builder.addColumn(EXPERIMENT);
+        builder.addColumn(EXPERIMENT_IDENTFIER).withDefaultWidth(200).hideByDefault();
+        builder.addColumn(PROJECT);
+        builder.addColumn(PERM_ID).hideByDefault();
+        builder.addColumn(SHOW_DETAILS_LINK_COLUMN_NAME).hideByDefault();
+        builder.addColumn(PARENTS);
+        builder.addColumn(CONTAINER_SAMPLE);
+        for (Sample sample : samples)
+        {
+            builder.addRow(sample);
+            builder.column(CODE).addString(sample.getCode());
+            builder.column(SUBCODE).addString(sample.getSubCode());
+            builder.column(DATABASE_INSTANCE).addString(getDatabaseInstance(sample).getCode());
+            builder.column(SPACE).addString(sample.getSpace() == null ? "" : sample.getSpace().getCode());
+            builder.column(SAMPLE_IDENTIFIER).addString(sample.getIdentifier());
+            builder.column(SAMPLE_TYPE).addString(sample.getSampleType().getCode());
+            builder.column(IS_INSTANCE_SAMPLE).addString(SimpleYesNoRenderer.render(sample.getDatabaseInstance() != null));
+            builder.column(IS_IVALID).addString(SimpleYesNoRenderer.render(sample.getInvalidation() != null));
+            builder.column(REGISTRATOR).addPerson(sample.getRegistrator());
+            builder.column(REGISTRATION_DATE).addDate(sample.getRegistrationDate());
+            builder.column(EXPERIMENT).addString(getExperimentCode(sample));
+            builder.column(EXPERIMENT_IDENTFIER).addString(getExperimentIdentifier(sample));
+            builder.column(PROJECT).addString(getProjectCode(sample));
+            builder.column(PERM_ID).addString(sample.getPermId());
+            builder.column(SHOW_DETAILS_LINK_COLUMN_NAME).addString(sample.getPermlink());
+            builder.column(PARENTS).addString(getParents(sample));
+            builder.column(CONTAINER_SAMPLE).addString(getContainer(sample));
+            builder.columnGroup("property-").addProperties(sample.getProperties());
+        }
+        return builder.getModel();
+    }
+
+    private String getParents(Sample sample)
+    {
+        Sample generatedFrom = sample.getGeneratedFrom();
+        return generatedFrom == null ? "" : generatedFrom.getIdentifier();
+    }
+
+    private String getContainer(Sample sample)
+    {
+        Sample container = sample.getContainer();
+        return container == null ? "" : container.getIdentifier();
+    }
+    
+    private String getProjectCode(Sample sample)
+    {
+        Experiment experiment = sample.getExperiment();
+        return experiment == null ? "" : experiment.getProject().getCode();
+    }
+
+    private String getExperimentCode(Sample sample)
+    {
+        Experiment experiment = sample.getExperiment();
+        return experiment == null ? "" : experiment.getCode();
+    }
+    
+    private String getExperimentIdentifier(Sample sample)
+    {
+        Experiment experiment = sample.getExperiment();
+        return experiment == null ? "" : experiment.getIdentifier();
+    }
+    
+    private DatabaseInstance getDatabaseInstance(Sample sample)
+    {
+        DatabaseInstance databaseInstance = sample.getDatabaseInstance();
+        if (databaseInstance == null)
+        {
+            databaseInstance = sample.getSpace().getInstance();
+        }
+        return databaseInstance;
+    }
+
+    private final List<Sample> getSamples()
+    {
+        switch (criteria.getCriteriaKind())
+        {
+            case BROWSE:
+                return commonServer.listSamples(sessionToken, criteria.getBrowseCriteria());
+            case SEARCH:
+                return commonServer.searchForSamples(sessionToken, criteria.getSearchCriteria());
+        }
+        return null; // not possible
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/framework/renderers/SimpleYesNoRenderer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/SimpleYesNoRenderer.java
similarity index 88%
rename from openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/framework/renderers/SimpleYesNoRenderer.java
rename to openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/SimpleYesNoRenderer.java
index cf73bc86517..4a68610896e 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/framework/renderers/SimpleYesNoRenderer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/SimpleYesNoRenderer.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.renderers;
+package ch.systemsx.cisd.openbis.generic.shared.basic;
 
 /**
  * @author Tomasz Pylak
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/DataTypeUtils.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/DataTypeUtils.java
index 5000b9754cf..744d6354068 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/DataTypeUtils.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/DataTypeUtils.java
@@ -24,6 +24,7 @@ import org.apache.commons.lang.StringUtils;
 
 import com.google.gwt.user.client.rpc.IsSerializable;
 
+import ch.systemsx.cisd.openbis.generic.shared.basic.BasicConstant;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DoubleTableCell;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ISerializableComparable;
@@ -134,6 +135,10 @@ public class DataTypeUtils
             {
                 return EMPTY_CELL;
             }
+            if (value.startsWith(BasicConstant.ERROR_PROPERTY_PREFIX))
+            {
+                return new StringTableCell(value.substring(1));
+            }
             return doConversion(value);
         }
         
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/web/client/application/ui/columns/QueryColDefKind.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/web/client/application/ui/columns/QueryColDefKind.java
index 51f78ecbc84..41dce361cab 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/web/client/application/ui/columns/QueryColDefKind.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/web/client/application/ui/columns/QueryColDefKind.java
@@ -19,7 +19,7 @@ package ch.systemsx.cisd.openbis.plugin.query.client.web.client.application.ui.c
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.AbstractColumnDefinitionKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.IColumnDefinitionKind;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.renderers.SimpleYesNoRenderer;
+import ch.systemsx.cisd.openbis.generic.shared.basic.SimpleYesNoRenderer;
 import ch.systemsx.cisd.openbis.plugin.query.shared.basic.dto.QueryExpression;
 
 /**
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js
index 7290158bc4d..f8dd329acc3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js
@@ -169,12 +169,14 @@ var common = {
   is_instance_sample: "Shared?",
   is_invalid: "Invalid?",
   group: "Space",
+  space: "Space",
   groups: "Spaces",
   project: "Project",
   experiment: "Experiment",
   experiment_identifier: "Experiment Identifier",
   generated_from: "Parent {0}",
   part_of: "Container",
+  container_sample: "Container",
   invalidation: "Invalidation",
   invalidation_template: "Invalidated by: {0}<br>Invalidation Date: {1}<br>Invalidation Reason: {2}",
   
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/EntityTypePropertyTypeAssignmentTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/EntityTypePropertyTypeAssignmentTest.java
index 0a0decfd302..894a9f4d4f1 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/EntityTypePropertyTypeAssignmentTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/EntityTypePropertyTypeAssignmentTest.java
@@ -18,7 +18,6 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.menu.TopMenu.ActionMenuKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.InvokeActionMenu;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.renderers.SimpleYesNoRenderer;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.specific.PropertyTypeAssignmentColDefKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.property_type.CheckPropertyTypeAssignmentTable;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.property_type.FillPropertyTypeAssignmentForm;
@@ -27,6 +26,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.columns.SampleRow;
 import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.AbstractGWTTestCase;
 import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.Row;
+import ch.systemsx.cisd.openbis.generic.shared.basic.SimpleYesNoRenderer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 
 /**
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/columns/DataSetRow.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/columns/DataSetRow.java
index e1705a27196..1077447c91d 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/columns/DataSetRow.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/columns/DataSetRow.java
@@ -16,9 +16,9 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.data.columns;
 
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.renderers.SimpleYesNoRenderer;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.specific.data.CommonExternalDataColDefKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.Row;
+import ch.systemsx.cisd.openbis.generic.shared.basic.SimpleYesNoRenderer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SourceType;
 
 /**
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/columns/ExperimentRow.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/columns/ExperimentRow.java
index af4d75351b7..b5fb96fc461 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/columns/ExperimentRow.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/columns/ExperimentRow.java
@@ -16,9 +16,9 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.experiment.columns;
 
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.renderers.SimpleYesNoRenderer;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.specific.experiment.CommonExperimentColDefKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.RowWithProperties;
+import ch.systemsx.cisd.openbis.generic.shared.basic.SimpleYesNoRenderer;
 
 /**
  * Allows to define experiment table row expectations.
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/columns/SampleRow.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/columns/SampleRow.java
index 28191328af8..2239cae0f33 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/columns/SampleRow.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/columns/SampleRow.java
@@ -16,11 +16,11 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.columns;
 
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.renderers.SimpleYesNoRenderer;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.specific.sample.CommonSampleColDefKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.specific.sample.ParentContainerSampleColDef;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.specific.sample.ParentGeneratedFromSampleColDef;
 import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.RowWithProperties;
+import ch.systemsx.cisd.openbis.generic.shared.basic.SimpleYesNoRenderer;
 
 /**
  * @author Franz-Josef Elmer
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/plugin/generic/SampleDetailsTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/plugin/generic/SampleDetailsTest.java
index dfe8336a186..83c013d1f32 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/plugin/generic/SampleDetailsTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/plugin/generic/SampleDetailsTest.java
@@ -22,6 +22,7 @@ import static org.testng.AssertJUnit.fail;
 
 import java.util.List;
 
+import org.apache.commons.lang.StringEscapeUtils;
 import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.SampleBrowserTest;
@@ -74,11 +75,11 @@ public class SampleDetailsTest extends GenericSystemTestCase
 
     private static final String CELL_PLATE_EXAMPLE_PERM_ID = "200811050946559-983";
 
-    private static final String CONTROL_LAYOUT_EXAMPLE_PERMLINK = String.format(PERMLINK_TEMPLATE,
-            CONTROL_LAYOUT_EXAMPLE_PERM_ID);
+    private static final String CONTROL_LAYOUT_EXAMPLE_PERMLINK = StringEscapeUtils
+            .escapeHtml(String.format(PERMLINK_TEMPLATE, CONTROL_LAYOUT_EXAMPLE_PERM_ID));
 
-    private static final String CELL_PLATE_EXAMPLE_PERMLINK = String.format(PERMLINK_TEMPLATE,
-            CELL_PLATE_EXAMPLE_PERM_ID);
+    private static final String CELL_PLATE_EXAMPLE_PERMLINK = StringEscapeUtils.escapeHtml(String
+            .format(PERMLINK_TEMPLATE, CELL_PLATE_EXAMPLE_PERM_ID));
 
     private static final String DIRECTLY_CONNECTED_DATA_SET_CODE = "20081105092158673-1";
 
-- 
GitLab