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 8f417674089b96f249a9ff16de74345e7f41e39b..7280afed7042b96ad86e79ecefc835a339e3a31f 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
@@ -120,6 +120,13 @@ public interface ICommonClientService extends IClientService
     public String prepareExportExperiments(final TableExportCriteria<Experiment> criteria)
             throws UserFailureException;
 
+    /**
+     * Returns a key which can be used be the export servlet (and eventually
+     * {@link #getExportTable(String)}) to reference the export criteria in an easy way.
+     */
+    public String prepareExportMatchingEntities(final TableExportCriteria<MatchingEntity> criteria)
+            throws UserFailureException;
+
     /**
      * Assumes that preparation of the export ({@link #prepareExportSamples(TableExportCriteria)}
      * or {@link #prepareExportExperiments(TableExportCriteria)} has been invoked before and
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 f24b0136ac00f3c73f4711a5faac51a7538fe122..d00f050bd664e20ede8101b486557c1f110b0e9e 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
@@ -101,6 +101,10 @@ public interface ICommonClientServiceAsync extends IClientServiceAsync
     public void prepareExportExperiments(TableExportCriteria<Experiment> exportCriteria,
             AsyncCallback<String> callback);
 
+    /** @see ICommonClientService#prepareExportMatchingEntities(TableExportCriteria) */
+    public void prepareExportMatchingEntities(TableExportCriteria<MatchingEntity> exportCriteria,
+            AsyncCallback<String> callback);
+
     /**
      * @see ICommonClientService#getExportTable(String)
      */
@@ -124,7 +128,7 @@ public interface ICommonClientServiceAsync extends IClientServiceAsync
      */
     public void listExternalDataForExperiment(String experimentIdentifier,
             AsyncCallback<List<ExternalData>> asyncCallback);
-    
+
     /**
      * @see ICommonClientService#listSearchableEntities()
      */
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/MatchingEntitiesPanel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/MatchingEntitiesPanel.java
index 438ce7adbd86532c284dd4b41a1ecbf21fef2705..a51a45218eac3ab74e21fec08adddb538ade6984 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/MatchingEntitiesPanel.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/MatchingEntitiesPanel.java
@@ -16,299 +16,93 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.application;
 
-import java.util.ArrayList;
 import java.util.List;
 
-import com.extjs.gxt.ui.client.Events;
 import com.extjs.gxt.ui.client.XDOM;
-import com.extjs.gxt.ui.client.Style.SelectionMode;
-import com.extjs.gxt.ui.client.data.BasePagingLoadResult;
-import com.extjs.gxt.ui.client.data.BasePagingLoader;
-import com.extjs.gxt.ui.client.data.PagingLoadConfig;
-import com.extjs.gxt.ui.client.data.PagingLoadResult;
-import com.extjs.gxt.ui.client.data.PagingLoader;
-import com.extjs.gxt.ui.client.data.RpcProxy;
-import com.extjs.gxt.ui.client.event.GridEvent;
-import com.extjs.gxt.ui.client.event.Listener;
-import com.extjs.gxt.ui.client.event.TabPanelEvent;
-import com.extjs.gxt.ui.client.store.ListStore;
-import com.extjs.gxt.ui.client.widget.ContentPanel;
 import com.extjs.gxt.ui.client.widget.LayoutContainer;
-import com.extjs.gxt.ui.client.widget.PagingToolBar;
-import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
-import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
-import com.extjs.gxt.ui.client.widget.grid.Grid;
-import com.extjs.gxt.ui.client.widget.layout.FitLayout;
-import com.google.gwt.user.client.rpc.AsyncCallback;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DispatcherHelper;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.ITabItemFactory;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.MatchingEntityModel;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.ColumnConfigFactory;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.PagingToolBarWithoutRefresh;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.GWTUtils;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.GxtTranslator;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.AbstractBrowserGrid;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IColumnDefinitionUI;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.columns.ColumnDefsAndConfigs;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DefaultResultSetConfig;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.EntityKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.MatchingEntity;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSet;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.SearchableEntity;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableExportCriteria;
 
 /**
  * A {@link LayoutContainer} extension which displays the matching entities.
  * 
  * @author Christian Ribeaud
  */
-final class MatchingEntitiesPanel extends ContentPanel implements Listener<TabPanelEvent>
+final class MatchingEntitiesPanel extends AbstractBrowserGrid<MatchingEntity, MatchingEntityModel>
 {
-    static final int PAGE_SIZE = 50;
-
     static final String PREFIX = GenericConstants.ID_PREFIX + "matching-entities-panel_";
 
     static final String GRID_ID = PREFIX + "grid";
 
-    private final IViewContext<ICommonClientServiceAsync> viewContext;
-
-    private final PagingLoader<PagingLoadConfig> matchingEntitiesLoader;
-
     private final SearchableEntity searchableEntity;
 
     private final String queryText;
 
-    private String resultSetKey;
-
-    private ResultSet<MatchingEntity> firstResultSet;
-
     MatchingEntitiesPanel(final IViewContext<ICommonClientServiceAsync> viewContext,
             final SearchableEntity searchableEntity, final String queryText)
     {
-        this.viewContext = viewContext;
+        super(viewContext, GRID_ID);
         this.searchableEntity = searchableEntity;
         this.queryText = queryText;
-        matchingEntitiesLoader = createMatchingEntitiesLoader();
         setId(PREFIX + XDOM.getUniqueId());
-        setLayout(new FitLayout());
-        add(createGrid());
-        final PagingToolBar toolBar = createPagingToolBar();
-        toolBar.bind(matchingEntitiesLoader);
-        setHeaderVisible(false);
-        setBottomComponent(toolBar);
-    }
-
-    private final PagingLoader<PagingLoadConfig> createMatchingEntitiesLoader()
-    {
-        final RpcProxy<PagingLoadConfig, PagingLoadResult<MatchingEntityModel>> proxy =
-                createRpcProxy();
-        final BasePagingLoader<PagingLoadConfig, PagingLoadResult<MatchingEntityModel>> pagingLoader =
-                new BasePagingLoader<PagingLoadConfig, PagingLoadResult<MatchingEntityModel>>(proxy);
-        pagingLoader.setRemoteSort(true);
-        return pagingLoader;
-    }
-
-    private final RpcProxy<PagingLoadConfig, PagingLoadResult<MatchingEntityModel>> createRpcProxy()
-    {
-        return new RpcProxy<PagingLoadConfig, PagingLoadResult<MatchingEntityModel>>()
-            {
-
-                //
-                // RpcProxy
-                //
-
-                @Override
-                public final void load(final PagingLoadConfig loadConfig,
-                        final AsyncCallback<PagingLoadResult<MatchingEntityModel>> callback)
-                {
-                    final int offset = loadConfig.getOffset();
-                    final ListMatchingEntitiesCallback listMatchingEntitiesCallback =
-                            new ListMatchingEntitiesCallback(viewContext, callback, offset);
-                    if (firstResultSet != null)
-                    {
-                        listMatchingEntitiesCallback.onSuccess(firstResultSet);
-                        firstResultSet = null;
-                        return;
-                    }
-                    final DefaultResultSetConfig<String> resultSetConfig =
-                            new DefaultResultSetConfig<String>();
-                    resultSetConfig.setOffset(offset);
-                    resultSetConfig.setLimit(loadConfig.getLimit());
-                    resultSetConfig.setSortInfo(GxtTranslator.translate(loadConfig.getSortInfo()));
-                    resultSetConfig.setResultSetKey(resultSetKey);
-                    viewContext.getService().listMatchingEntities(searchableEntity, queryText,
-                            resultSetConfig, listMatchingEntitiesCallback);
-                }
-
-            };
     }
 
-    private final Grid<MatchingEntityModel> createGrid()
+    public final void refresh(final IDataRefreshCallback newRefreshCallback)
     {
-        final ColumnModel columnModel = createColumnModel();
-
-        final Grid<MatchingEntityModel> grid =
-                new Grid<MatchingEntityModel>(new ListStore<MatchingEntityModel>(
-                        matchingEntitiesLoader), columnModel);
-        grid.setId(GRID_ID);
-        grid.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
-        grid.setLoadMask(true);
-        grid.addListener(Events.CellDoubleClick, new Listener<GridEvent>()
-            {
-
-                //
-                // Listener
-                //
-
-                public final void handleEvent(final GridEvent be)
-                {
-                    final MatchingEntityModel matchingEntityModel =
-                            (MatchingEntityModel) be.grid.getStore().getAt(be.rowIndex);
-                    final MatchingEntity matchingEntity =
-                            (MatchingEntity) matchingEntityModel.get(ModelDataPropertyNames.OBJECT);
-                    final EntityKind entityKind = matchingEntity.getEntityKind();
-                    final ITabItemFactory tabView =
-                            viewContext.getClientPluginFactoryProvider().getClientPluginFactory(
-                                    entityKind, matchingEntity.getEntityType()).createClientPlugin(
-                                    entityKind).createEntityViewer(matchingEntity);
-                    DispatcherHelper.dispatchNaviEvent(tabView);
-                }
-            });
-        GWTUtils.setAutoExpandOnLastVisibleColumn(grid);
-        return grid;
+        super.refresh(newRefreshCallback, null, true);
     }
 
-    private final ColumnModel createColumnModel()
+    @Override
+    protected void showEntityViewer(MatchingEntityModel matchingEntityModel)
     {
-        final List<ColumnConfig> configs = new ArrayList<ColumnConfig>();
-        configs.add(createEntityKindColumnConfig());
-        configs.add(createEntityTypeColumnConfig());
-        configs.add(createIdentifierColumnConfig());
-        configs.add(ColumnConfigFactory.createRegistratorColumnConfig(viewContext));
-        configs.add(createMatchedFieldColumnConfig());
-        configs.add(createMatchedTextColumnConfig());
-        final ColumnModel columnModel = new ColumnModel(configs);
-        return columnModel;
+        final MatchingEntity matchingEntity = matchingEntityModel.getBaseObject();
+        final EntityKind entityKind = matchingEntity.getEntityKind();
+        final ITabItemFactory tabView =
+                viewContext.getClientPluginFactoryProvider().getClientPluginFactory(entityKind,
+                        matchingEntity.getEntityType()).createClientPlugin(entityKind)
+                        .createEntityViewer(matchingEntity);
+        DispatcherHelper.dispatchNaviEvent(tabView);
     }
 
-    private final ColumnConfig createMatchedTextColumnConfig()
+    @Override
+    protected ColumnDefsAndConfigs<MatchingEntity> createColumnsDefinition()
     {
-        ColumnConfig config =
-                createColumnConfig(Dict.MATCHING_TEXT, ModelDataPropertyNames.MATCHING_TEXT);
-        config.setWidth(200);
-        return config;
+        List<IColumnDefinitionUI<MatchingEntity>> list =
+                MatchingEntityModel.createColumnsSchema(viewContext);
+        return ColumnDefsAndConfigs.create(list, true);
     }
 
-    private final ColumnConfig createMatchedFieldColumnConfig()
+    @Override
+    protected List<MatchingEntityModel> createModels(List<MatchingEntity> entities)
     {
-        ColumnConfig config =
-                createColumnConfig(Dict.MATCHING_FIELD, ModelDataPropertyNames.MATCHING_FIELD);
-        config.setWidth(140);
-        return config;
+        return MatchingEntityModel.convert(entities);
     }
 
-    private final ColumnConfig createEntityKindColumnConfig()
+    @Override
+    protected void listEntities(DefaultResultSetConfig<String> resultSetConfig,
+            AbstractAsyncCallback<ResultSet<MatchingEntity>> callback)
     {
-        return createColumnConfig(Dict.ENTITY_KIND, ModelDataPropertyNames.ENTITY_KIND);
+        viewContext.getService().listMatchingEntities(searchableEntity, queryText, resultSetConfig,
+                callback);
     }
 
-    private final ColumnConfig createIdentifierColumnConfig()
+    @Override
+    protected void prepareExportEntities(TableExportCriteria<MatchingEntity> exportCriteria,
+            AbstractAsyncCallback<String> callback)
     {
-        final ColumnConfig columnConfig =
-                createColumnConfig(Dict.IDENTIFIER, ModelDataPropertyNames.IDENTIFIER);
-        columnConfig.setWidth(140);
-        return columnConfig;
-    }
-
-    private final ColumnConfig createEntityTypeColumnConfig()
-    {
-        return createColumnConfig(Dict.ENTITY_TYPE, ModelDataPropertyNames.ENTITY_TYPE);
-    }
-
-    private final ColumnConfig createColumnConfig(String headerMsgKey, String colId)
-    {
-        return ColumnConfigFactory.createDefaultColumnConfig(viewContext.getMessage(headerMsgKey),
-                colId);
-    }
-
-    private final static PagingToolBar createPagingToolBar()
-    {
-        return new PagingToolBarWithoutRefresh(PAGE_SIZE);
-    }
-
-    /**
-     * Sets the first result set loaded.
-     */
-    final void setFirstResulSet(final ResultSet<MatchingEntity> resultSet)
-    {
-        firstResultSet = resultSet;
-        matchingEntitiesLoader.load(0, PAGE_SIZE);
-    }
-
-    //
-    // Listener
-    //
-
-    public final void handleEvent(final TabPanelEvent be)
-    {
-        if (be.type == Events.Close && resultSetKey != null)
-        {
-            viewContext.getService().removeResultSet(resultSetKey,
-                    new VoidAsyncCallback<Void>(viewContext));
-        }
-    }
-
-    //
-    // Helper classes
-    //
-
-    private final class ListMatchingEntitiesCallback extends
-            AbstractAsyncCallback<ResultSet<MatchingEntity>>
-    {
-        private final AsyncCallback<PagingLoadResult<MatchingEntityModel>> delegate;
-
-        private final int offset;
-
-        ListMatchingEntitiesCallback(final IViewContext<ICommonClientServiceAsync> viewContext,
-                final AsyncCallback<PagingLoadResult<MatchingEntityModel>> delegate,
-                final int offset)
-        {
-            super(viewContext);
-            this.delegate = delegate;
-            this.offset = offset;
-        }
-
-        private void setResultSetKey(final String resultSetKey)
-        {
-            if (MatchingEntitiesPanel.this.resultSetKey == null)
-            {
-                MatchingEntitiesPanel.this.resultSetKey = resultSetKey;
-            } else
-            {
-                assert MatchingEntitiesPanel.this.resultSetKey.equals(resultSetKey) : "Result set keys not the same.";
-            }
-        }
-
-        //
-        // AbstractAsyncCallback
-        //
-
-        @Override
-        protected final void finishOnFailure(final Throwable caught)
-        {
-            delegate.onFailure(caught);
-        }
-
-        @Override
-        protected final void process(final ResultSet<MatchingEntity> result)
-        {
-            setResultSetKey(result.getResultSetKey());
-            final List<MatchingEntityModel> matchingEntities =
-                    MatchingEntityModel.convert(result.getList());
-            final PagingLoadResult<MatchingEntityModel> loadResult =
-                    new BasePagingLoadResult<MatchingEntityModel>(matchingEntities, offset, result
-                            .getTotalLength());
-            delegate.onSuccess(loadResult);
-        }
+        viewContext.getService().prepareExportMatchingEntities(exportCriteria, callback);
     }
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/SearchWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/SearchWidget.java
index 4a2ef451deb41a6e5f3f2a1bb31599709e975de7..a295e0d1ce03f8ead29c7be56bc2fb7b2cad02cf 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/SearchWidget.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/SearchWidget.java
@@ -16,8 +16,9 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.application;
 
-import java.util.List;
-
+import com.extjs.gxt.ui.client.Events;
+import com.extjs.gxt.ui.client.event.Listener;
+import com.extjs.gxt.ui.client.event.TabPanelEvent;
 import com.extjs.gxt.ui.client.widget.LayoutContainer;
 import com.extjs.gxt.ui.client.widget.MessageBox;
 import com.extjs.gxt.ui.client.widget.form.TextField;
@@ -30,11 +31,9 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.ITabItemFactory;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.EnterKeyListener;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.AbstractBrowserGrid.IDataRefreshCallback;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.ButtonWithLoadingMask;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.StringUtils;
-import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DefaultResultSetConfig;
-import ch.systemsx.cisd.openbis.generic.client.web.client.dto.MatchingEntity;
-import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSet;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.SearchableEntity;
 
 /**
@@ -137,42 +136,94 @@ final class SearchWidget extends LayoutContainer
         {
             return;
         }
-        final SearchableEntity selectedSearchableEntityOrNull =
-                entityChooser.getSelectedSearchableEntity();
         final String queryText = textField.getValue();
-        if (StringUtils.isBlank(queryText) == false)
+        if (StringUtils.isBlank(queryText))
+        {
+            return;
+        }
+        if (hasOnlyWildcards(queryText))
         {
-            boolean onlyWildcard = true;
-            for (final char c : queryText.toCharArray())
+            MessageBox.alert(viewContext.getMessage(Dict.MESSAGEBOX_WARNING), viewContext
+                    .getMessage(Dict.TOO_GENERIC, queryText), null);
+            return;
+        }
+        enableSearch(false);
+        final SearchableEntity selectedSearchableEntityOrNull =
+                entityChooser.getSelectedSearchableEntity();
+        final MatchingEntitiesPanel matchingEntitiesGrid =
+                new MatchingEntitiesPanel(viewContext, selectedSearchableEntityOrNull, queryText);
+        String title = createTabTitle(queryText);
+        final ITabItemFactory tabFactory = createTabFactory(matchingEntitiesGrid, title);
+
+        matchingEntitiesGrid.refresh(new IDataRefreshCallback()
             {
-                if (c != '*' && c != '?')
+                public void postRefresh(boolean wasSuccessful)
                 {
-                    onlyWildcard = false;
-                    break;
+                    enableSearch(true);
+                    if (wasSuccessful == false)
+                    {
+                        return;
+                    }
+                    if (matchingEntitiesGrid.getRowNumber() == 0)
+                    {
+                        MessageBox.alert(viewContext.getMessage(Dict.MESSAGEBOX_WARNING),
+                                viewContext.getMessage(Dict.NO_MATCH, queryText), null);
+                        return;
+                    } else
+                    {
+                        textField.reset();
+                        DispatcherHelper.dispatchNaviEvent(tabFactory);
+                    }
                 }
-            }
-            if (onlyWildcard)
+            });
+    }
+
+    private String createTabTitle(final String queryText)
+    {
+        final String selectedText =
+                entityChooser.getValue().get(ModelDataPropertyNames.DESCRIPTION);
+        return viewContext.getMessage(Dict.GLOBAL_SEARCH, selectedText, queryText);
+    }
+
+    private static ITabItemFactory createTabFactory(
+            final MatchingEntitiesPanel matchingEntitiesPanel, String title)
+    {
+        final DefaultTabItem tab =
+                new DefaultTabItem(title, matchingEntitiesPanel,
+                        createTabPanelEventListener(matchingEntitiesPanel));
+        // this tab cannot be opened for the second time, so we can create it outside of the
+        // factory
+        return new ITabItemFactory()
             {
-                MessageBox.alert(viewContext.getMessage(Dict.MESSAGEBOX_WARNING), viewContext
-                        .getMessage(Dict.TOO_GENERIC, queryText), null);
-                return;
-            }
-            enableSearch(false);
-            viewContext.getService()
-                    .listMatchingEntities(
-                            selectedSearchableEntityOrNull,
-                            queryText,
-                            createResultSetConfig(),
-                            new SearchResultCallback(viewContext, selectedSearchableEntityOrNull,
-                                    queryText));
-        }
+                public ITabItem create()
+                {
+                    return tab;
+                }
+
+                public String getId()
+                {
+                    return matchingEntitiesPanel.getId();
+                }
+
+                public boolean isCloseConfirmationNeeded()
+                {
+                    return false;
+                }
+            };
     }
 
-    private final static DefaultResultSetConfig<String> createResultSetConfig()
+    private static boolean hasOnlyWildcards(final String queryText)
     {
-        final DefaultResultSetConfig<String> resultSetConfig = new DefaultResultSetConfig<String>();
-        resultSetConfig.setLimit(MatchingEntitiesPanel.PAGE_SIZE);
-        return resultSetConfig;
+        boolean onlyWildcard = true;
+        for (final char c : queryText.toCharArray())
+        {
+            if (c != '*' && c != '?')
+            {
+                onlyWildcard = false;
+                break;
+            }
+        }
+        return onlyWildcard;
     }
 
     private final ButtonWithLoadingMask createSearchButton()
@@ -194,83 +245,19 @@ final class SearchWidget extends LayoutContainer
         return button;
     }
 
-    //
-    // Helper classes
-    //
-
-    public final class SearchResultCallback extends
-            AbstractAsyncCallback<ResultSet<MatchingEntity>>
+    private static Listener<TabPanelEvent> createTabPanelEventListener(
+            final MatchingEntitiesPanel matchingEntitiesPanel)
     {
-        private final SearchableEntity searchableEntityOrNull;
-
-        private final String queryText;
-
-        SearchResultCallback(final IViewContext<ICommonClientServiceAsync> viewContext,
-                final SearchableEntity searchableEntityOrNull, final String queryText)
-        {
-            super(viewContext);
-            this.searchableEntityOrNull = searchableEntityOrNull;
-            this.queryText = queryText;
-        }
-
-        @SuppressWarnings("unchecked")
-        private final IViewContext<ICommonClientServiceAsync> castViewContext()
-        {
-            return (IViewContext<ICommonClientServiceAsync>) viewContext;
-        }
-
-        //
-        // AbstractAsyncCallback
-        //
-
-        @Override
-        protected final void finishOnFailure(final Throwable caught)
-        {
-            enableSearch(true);
-        }
-
-        @Override
-        protected final void process(final ResultSet<MatchingEntity> result)
-        {
-            enableSearch(true);
-            final List<MatchingEntity> entities = result.getList();
-            if (entities.size() == 0)
+        return new Listener<TabPanelEvent>()
             {
-                MessageBox.alert(viewContext.getMessage(Dict.MESSAGEBOX_WARNING), viewContext
-                        .getMessage(Dict.NO_MATCH, queryText), null);
-                return;
-            }
-            textField.reset();
-
-            final String selectedText =
-                    entityChooser.getValue().get(ModelDataPropertyNames.DESCRIPTION);
-            final MatchingEntitiesPanel matchingEntitiesPanel =
-                    new MatchingEntitiesPanel(castViewContext(), searchableEntityOrNull, queryText);
-            matchingEntitiesPanel.setFirstResulSet(result);
-
-            String title = viewContext.getMessage(Dict.GLOBAL_SEARCH, selectedText, queryText);
-            final DefaultTabItem tab =
-                    new DefaultTabItem(title, matchingEntitiesPanel, matchingEntitiesPanel);
-            // this tab cannot be opened for the second time, so we can create it outside of the
-            // factory
-            DispatcherHelper.dispatchNaviEvent(new ITabItemFactory()
+                public void handleEvent(TabPanelEvent be)
                 {
-                    public ITabItem create()
-                    {
-                        return tab;
-                    }
-
-                    public String getId()
-                    {
-                        return matchingEntitiesPanel.getId();
-                    }
-
-                    public boolean isCloseConfirmationNeeded()
+                    if (be.type == Events.Close)
                     {
-                        return false;
+                        matchingEntitiesPanel.disposeCache();
                     }
-                });
-        }
+                }
+            };
     }
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/AbstractEntityModel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/AbstractEntityModel.java
index a5c02911811a08034b26e3d383d08b92b7e21cf2..5aa3f71a38026ff2058f50b5e38dc8c468dbef58 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/AbstractEntityModel.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/AbstractEntityModel.java
@@ -16,6 +16,9 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.model;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import com.extjs.gxt.ui.client.data.BaseModelData;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
@@ -23,19 +26,37 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.renderer.I
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.renderer.PersonRenderer;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.CommonColumnDefinition;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IColumnDefinitionKind;
-import ch.systemsx.cisd.openbis.generic.client.web.client.dto.CodeWithRegistration;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IColumnDefinitionUI;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IMessageProvider;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.AbstractRegistrationHolder;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.IColumnDefinition;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.IInvalidationProvider;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Person;
 
 /**
- * 
- *
  * @author Franz-Josef Elmer
  */
-public class AbstractEntityModel<T extends CodeWithRegistration<T>> extends BaseModelData
+public class AbstractEntityModel<T> extends BaseModelData
 {
     private static final long serialVersionUID = 1L;
 
+    protected AbstractEntityModel(final T entity, List<? extends IColumnDefinition<T>> columnsSchema)
+    {
+        set(ModelDataPropertyNames.OBJECT, entity);
+
+        for (IColumnDefinition<T> column : columnsSchema)
+        {
+            String value = renderColumnValue(entity, column);
+            set(column.getIdentifier(), value);
+        }
+    }
+
+    public final T getBaseObject()
+    {
+        return get(ModelDataPropertyNames.OBJECT);
+    }
+
+    // ugly, ugly, ugly!
     protected String renderColumnValue(final T entity, IColumnDefinition<T> column)
     {
         String value = column.getValue(entity);
@@ -44,9 +65,11 @@ public class AbstractEntityModel<T extends CodeWithRegistration<T>> extends Base
             IColumnDefinitionKind<?> columnKind =
                     ((CommonColumnDefinition<?>) column).getColumnDefinitionKind();
             String headerMsgKey = columnKind.getHeaderMsgKey();
-            if (headerMsgKey.equals(Dict.REGISTRATOR))
+            if (headerMsgKey.equals(Dict.REGISTRATOR)
+                    && entity instanceof AbstractRegistrationHolder)
             {
-                value = PersonRenderer.createPersonAnchor(entity.getRegistrator(), value);
+                Person registrator = ((AbstractRegistrationHolder) entity).getRegistrator();
+                value = PersonRenderer.createPersonAnchor(registrator, value);
             } else if (headerMsgKey.equals(Dict.CODE) && entity instanceof IInvalidationProvider)
             {
                 value = InvalidableWithCodeRenderer.render((IInvalidationProvider) entity, value);
@@ -55,5 +78,26 @@ public class AbstractEntityModel<T extends CodeWithRegistration<T>> extends Base
         return value;
     }
 
+    protected static <T> List<IColumnDefinitionUI<T>> createColumnsSchemaFrom(
+            IColumnDefinitionKind<T>[] columnKinds, IMessageProvider msgProviderOrNull)
+    {
+        List<IColumnDefinitionUI<T>> list = new ArrayList<IColumnDefinitionUI<T>>();
+        for (IColumnDefinitionKind<T> columnKind : columnKinds)
+        {
+            list.add(createColumn(columnKind, msgProviderOrNull));
+        }
+        return list;
+    }
+
+    private static <T> IColumnDefinitionUI<T> createColumn(IColumnDefinitionKind<T> columnKind,
+            IMessageProvider messageProviderOrNull)
+    {
+        String headerText = null;
+        if (messageProviderOrNull != null)
+        {
+            headerText = messageProviderOrNull.getMessage(columnKind.getHeaderMsgKey());
+        }
+        return new CommonColumnDefinition<T>(columnKind, headerText);
+    }
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/ExperimentModel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/ExperimentModel.java
index bbed6c2be1a5848c39b631ecdbe3414208c3d896..810770e57d560fa7e9b54e3045c2528a0481ac10 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/ExperimentModel.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/ExperimentModel.java
@@ -27,12 +27,10 @@ import ch.systemsx.cisd.openbis.generic.client.shared.ExperimentTypePropertyType
 import ch.systemsx.cisd.openbis.generic.client.shared.PropertyType;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.experiment.columns.CommonExperimentColDefKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.experiment.columns.PropertyExperimentColDef;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.CommonColumnDefinition;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IColumnDefinitionUI;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.columns.ColumnDefsAndConfigs;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IMessageProvider;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Experiment;
-import ch.systemsx.cisd.openbis.generic.client.web.client.dto.IColumnDefinition;
 
 /**
  * {@link ModelData} for {@link Experiment}
@@ -50,16 +48,9 @@ public final class ExperimentModel extends AbstractEntityModel<Experiment>
         return PROPERTY_PREFIX + propertyType.isInternalNamespace() + propertyType.getCode();
     }
 
-    public ExperimentModel(final Experiment experiment)
+    public ExperimentModel(final Experiment entity)
     {
-        set(ModelDataPropertyNames.OBJECT, experiment);
-
-        List<IColumnDefinitionUI<Experiment>> columnsSchema = createColumnsSchema(experiment);
-        for (IColumnDefinition<Experiment> column : columnsSchema)
-        {
-            String value = renderColumnValue(experiment, column);
-            set(column.getIdentifier(), value);
-        }
+        super(entity, createColumnsSchema(entity));
     }
 
     // here we create the columns definition having just one table row. We need them only to render
@@ -116,33 +107,11 @@ public final class ExperimentModel extends AbstractEntityModel<Experiment>
     private static List<IColumnDefinitionUI<Experiment>> createCommonColumnsSchema(
             IMessageProvider msgProviderOrNull)
     {
-        List<IColumnDefinitionUI<Experiment>> list = createColDefList();
-        for (CommonExperimentColDefKind columnKind : CommonExperimentColDefKind.values())
-        {
-            list.add(createColumn(columnKind, msgProviderOrNull));
-        }
-        return list;
+        return createColumnsSchemaFrom(CommonExperimentColDefKind.values(), msgProviderOrNull);
     }
 
     private static ArrayList<IColumnDefinitionUI<Experiment>> createColDefList()
     {
         return new ArrayList<IColumnDefinitionUI<Experiment>>();
     }
-
-    private static CommonColumnDefinition<Experiment> createColumn(CommonExperimentColDefKind columnKind,
-            IMessageProvider messageProviderOrNull)
-    {
-        String headerText = null;
-        if (messageProviderOrNull != null)
-        {
-            headerText = messageProviderOrNull.getMessage(columnKind.getHeaderMsgKey());
-        }
-        return new CommonColumnDefinition<Experiment>(columnKind, headerText);
-    }
-
-    public Experiment getBaseObject()
-    {
-        return get(ModelDataPropertyNames.OBJECT);
-    }
-
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/ExternalDataModel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/ExternalDataModel.java
index 9a53d0e42b566d9c7bb056c8a601916884ce2131..24b91f870e18631feeac958fdcbb634d5c9c6260 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/ExternalDataModel.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/ExternalDataModel.java
@@ -19,28 +19,40 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.model;
 import java.util.ArrayList;
 import java.util.List;
 
-import com.extjs.gxt.ui.client.data.BaseModelData;
 import com.extjs.gxt.ui.client.data.ModelData;
 
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.data.columns.CommonExternalDataColDefKind;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IColumnDefinitionUI;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IMessageProvider;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExternalData;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.IColumnDefinition;
 
 /**
  * {@link ModelData} for {@link ExternalData}.
  * 
  * @author Christian Ribeaud
  */
-public final class ExternalDataModel extends BaseModelData
+public final class ExternalDataModel extends AbstractEntityModel<ExternalData>
 {
 
     private static final long serialVersionUID = 1L;
 
     public ExternalDataModel(final ExternalData externalData)
     {
+        // TODO 2009-01-19, Tomasz Pylak: define column schema
+        // super(externalData, createColumnsSchema(null));
+        super(externalData, new ArrayList<IColumnDefinition<ExternalData>>());
         set(ModelDataPropertyNames.CODE, externalData.getCode());
         set(ModelDataPropertyNames.LOCATION, externalData.getLocation());
         set(ModelDataPropertyNames.FILE_FORMAT_TYPE, externalData.getFileFormatType().getCode());
     }
 
+    public static List<IColumnDefinitionUI<ExternalData>> createColumnsSchema(
+            IMessageProvider msgProviderOrNull)
+    {
+        return createColumnsSchemaFrom(CommonExternalDataColDefKind.values(), msgProviderOrNull);
+    }
+
     public final static List<ExternalDataModel> asExternalDataModels(final List<ExternalData> result)
     {
         final List<ExternalDataModel> models = new ArrayList<ExternalDataModel>(result.size());
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/MatchingEntityModel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/MatchingEntityModel.java
index aeb18bf37cc4e16f89e56c0f7e74a54b802a47e0..223dfe7ded808e0d5f88c9133f141a30da0de1bc 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/MatchingEntityModel.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/MatchingEntityModel.java
@@ -19,10 +19,14 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.model;
 import java.util.ArrayList;
 import java.util.List;
 
-import com.extjs.gxt.ui.client.data.BaseModelData;
 import com.extjs.gxt.ui.client.data.ModelData;
 
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.renderer.PersonRenderer;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.AbstractColumnDefinitionKind;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IColumnDefinitionKind;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IColumnDefinitionUI;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IMessageProvider;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.MatchingEntity;
 
 /**
@@ -30,24 +34,23 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.MatchingEntity;
  * 
  * @author Christian Ribeaud
  */
-public final class MatchingEntityModel extends BaseModelData
+public final class MatchingEntityModel extends AbstractEntityModel<MatchingEntity>
 {
     private static final long serialVersionUID = 1L;
 
-    public MatchingEntityModel()
+    public MatchingEntityModel(final MatchingEntity entity)
     {
+        super(entity, createColumnsSchema(null));
+
+        // override registrator column adding a link
+        set(MatchingEntityColumnKind.REGISTRATOR.id(), PersonRenderer.createPersonAnchor(entity
+                .getRegistrator()));
     }
 
-    public MatchingEntityModel(final MatchingEntity matchingEntity)
+    public static List<IColumnDefinitionUI<MatchingEntity>> createColumnsSchema(
+            IMessageProvider msgProviderOrNull)
     {
-        set(ModelDataPropertyNames.OBJECT, matchingEntity);
-        set(ModelDataPropertyNames.IDENTIFIER, matchingEntity.getIdentifier());
-        set(ModelDataPropertyNames.ENTITY_KIND, matchingEntity.getEntityKind().getDescription());
-        set(ModelDataPropertyNames.ENTITY_TYPE, matchingEntity.getEntityType().getCode());
-        set(ModelDataPropertyNames.MATCHING_FIELD, matchingEntity.getFieldDescription());
-        set(ModelDataPropertyNames.MATCHING_TEXT, matchingEntity.getTextFragment());
-        set(ModelDataPropertyNames.REGISTRATOR, PersonRenderer.createPersonAnchor(matchingEntity
-                .getRegistrator()));
+        return createColumnsSchemaFrom(MatchingEntityColumnKind.values(), msgProviderOrNull);
     }
 
     public final static List<MatchingEntityModel> convert(
@@ -60,4 +63,94 @@ public final class MatchingEntityModel extends BaseModelData
         }
         return list;
     }
+
+    public enum MatchingEntityColumnKind implements IColumnDefinitionKind<MatchingEntity>
+    {
+        ENTITY_KIND(new AbstractColumnDefinitionKind<MatchingEntity>(
+                ModelDataPropertyNames.ENTITY_KIND, Dict.ENTITY_KIND)
+            {
+                public String tryGetValue(MatchingEntity entity)
+                {
+                    return entity.getEntityKind().getDescription();
+                }
+            }),
+
+        ENTITY_TYPE(new AbstractColumnDefinitionKind<MatchingEntity>(
+                ModelDataPropertyNames.ENTITY_TYPE, Dict.ENTITY_TYPE)
+            {
+                public String tryGetValue(MatchingEntity entity)
+                {
+                    return entity.getEntityType().getCode();
+                }
+            }),
+
+        IDENTIFIER(new AbstractColumnDefinitionKind<MatchingEntity>(
+                ModelDataPropertyNames.IDENTIFIER, Dict.IDENTIFIER, 140, false)
+            {
+                public String tryGetValue(MatchingEntity entity)
+                {
+                    return entity.getIdentifier();
+                }
+            }),
+
+        REGISTRATOR(new AbstractColumnDefinitionKind<MatchingEntity>(
+                ModelDataPropertyNames.REGISTRATOR, Dict.REGISTRATOR)
+            {
+                public String tryGetValue(MatchingEntity entity)
+                {
+                    return renderRegistrator(entity.getRegistrator());
+                }
+            }),
+
+        MATCHING_FIELD(new AbstractColumnDefinitionKind<MatchingEntity>(
+                ModelDataPropertyNames.MATCHING_FIELD, Dict.MATCHING_FIELD, 140, false)
+            {
+                public String tryGetValue(MatchingEntity entity)
+                {
+                    return entity.getFieldDescription();
+                }
+            }),
+
+        MATCHING_TEXT(new AbstractColumnDefinitionKind<MatchingEntity>(
+                ModelDataPropertyNames.MATCHING_TEXT, Dict.MATCHING_TEXT, 200, false)
+            {
+                public String tryGetValue(MatchingEntity entity)
+                {
+                    return entity.getTextFragment();
+                }
+            });
+
+        private final IColumnDefinitionKind<MatchingEntity> columnDefinitionKind;
+
+        private MatchingEntityColumnKind(IColumnDefinitionKind<MatchingEntity> columnDefinitionKind)
+        {
+            this.columnDefinitionKind = columnDefinitionKind;
+        }
+
+        public String getHeaderMsgKey()
+        {
+            return columnDefinitionKind.getHeaderMsgKey();
+        }
+
+        public int getWidth()
+        {
+            return columnDefinitionKind.getWidth();
+        }
+
+        public String id()
+        {
+            return columnDefinitionKind.id();
+        }
+
+        public boolean isHidden()
+        {
+            return columnDefinitionKind.isHidden();
+        }
+
+        public String tryGetValue(MatchingEntity entity)
+        {
+            return columnDefinitionKind.tryGetValue(entity);
+        }
+    }
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/ExternalDataGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/ExternalDataGrid.java
index 1773d4995fe3b5112fb5fcb3c62393dbf58b2f19..d59484de912a68d2820fcdbbe0f9204cb303f302 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/ExternalDataGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/ExternalDataGrid.java
@@ -16,28 +16,21 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.data;
 
-import java.util.ArrayList;
 import java.util.List;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ExternalDataModel;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.data.columns.CommonExternalDataColDefKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.AbstractBrowserGrid;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.CommonColumnDefinition;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IColumnDefinitionKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IColumnDefinitionUI;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.columns.ColumnDefsAndConfigs;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IMessageProvider;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DefaultResultSetConfig;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExternalData;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSet;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableExportCriteria;
 
 /**
- * 
- *
  * @author Franz-Josef Elmer
  */
 public class ExternalDataGrid extends AbstractBrowserGrid<ExternalData, ExternalDataModel>
@@ -50,26 +43,9 @@ public class ExternalDataGrid extends AbstractBrowserGrid<ExternalData, External
     @Override
     protected ColumnDefsAndConfigs<ExternalData> createColumnsDefinition()
     {
-        ColumnDefsAndConfigs<ExternalData> columns = new ColumnDefsAndConfigs<ExternalData>();
         List<IColumnDefinitionUI<ExternalData>> list =
-                new ArrayList<IColumnDefinitionUI<ExternalData>>();
-        for (CommonExternalDataColDefKind columnKind : CommonExternalDataColDefKind.values())
-        {
-            list.add(createColumn(columnKind, viewContext));
-        }
-        columns.addColumns(list, true);
-        return columns;
-    }
-
-    private CommonColumnDefinition<ExternalData> createColumn(
-            IColumnDefinitionKind<ExternalData> columnKind, IMessageProvider messageProviderOrNull)
-    {
-        String headerText = null;
-        if (messageProviderOrNull != null)
-        {
-            headerText = messageProviderOrNull.getMessage(columnKind.getHeaderMsgKey());
-        }
-        return new CommonColumnDefinition<ExternalData>(columnKind, headerText);
+                ExternalDataModel.createColumnsSchema(viewContext);
+        return ColumnDefsAndConfigs.create(list, true);
     }
 
     @Override
@@ -83,7 +59,7 @@ public class ExternalDataGrid extends AbstractBrowserGrid<ExternalData, External
             AbstractAsyncCallback<ResultSet<ExternalData>> callback)
     {
         // TODO Auto-generated method stub
-        
+
     }
 
     @Override
@@ -91,7 +67,7 @@ public class ExternalDataGrid extends AbstractBrowserGrid<ExternalData, External
             AbstractAsyncCallback<String> callback)
     {
         // TODO Auto-generated method stub
-        
+
     }
 
     @Override
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserToolbar.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserToolbar.java
index 1bf9f8b0c33ed2f787cdf4bc18ccdeaeda7b39d1..d7decdfc9239ae5fea629719a34145af9f50277c 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserToolbar.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserToolbar.java
@@ -193,9 +193,12 @@ class ExperimentBrowserToolbar extends ToolBar
     {
         return new IDataRefreshCallback()
             {
-                public void postRefresh()
+                public void postRefresh(boolean wasSuccessful)
                 {
-                    exportButton.setEnabled(true);
+                    if (wasSuccessful)
+                    {
+                        exportButton.setEnabled(true);
+                    }
                 }
             };
     }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java
index ae8db3d65dcb816f7510f3251b82ad750f430cab..84444e004a6686ba1630325e09c436e68bd43950 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java
@@ -102,13 +102,16 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex
 
     public interface IDataRefreshCallback
     {
-        // called after the grid is refreshed with new data
-        void postRefresh();
+        /**
+         * called after the grid is refreshed with new data
+         * 
+         * @param wasSuccessful false if the call ended with a failure
+         */
+        void postRefresh(boolean wasSuccessful);
     }
 
     protected AbstractBrowserGrid(final IViewContext<ICommonClientServiceAsync> viewContext,
-
-    String gridId)
+            String gridId)
     {
         this.viewContext = viewContext;
         this.pagingLoader = createPagingLoader();
@@ -157,6 +160,12 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex
         return resultSetConfig;
     }
 
+    /** @return number of rows in the grid */
+    public int getRowNumber()
+    {
+        return grid.getStore().getCount();
+    }
+
     // @Private
     public final class ListEntitiesCallback extends AbstractAsyncCallback<ResultSet<T>>
     {
@@ -181,6 +190,7 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex
         @Override
         protected final void finishOnFailure(final Throwable caught)
         {
+            refreshCallback.postRefresh(false);
             delegate.onFailure(caught);
         }
 
@@ -198,7 +208,7 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex
                             .getTotalLength());
             delegate.onSuccess(loadResult);
             // notify that the refresh is done
-            refreshCallback.postRefresh();
+            refreshCallback.postRefresh(true);
         }
     }
 
@@ -226,12 +236,18 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex
         return panel;
     }
 
-    protected void refresh(final IDataRefreshCallback newRefreshCallback, String newHeader,
+    /**
+     * Refreshes the grid.
+     * <p>
+     * Note that, doing so, the result set associated on the server side will be removed.
+     * </p>
+     */
+    protected void refresh(final IDataRefreshCallback newRefreshCallback, String newHeaderOrNull,
             boolean refreshColumnsDefinition)
     {
         disposeCache();
         this.refreshCallback = newRefreshCallback;
-        this.contentPanel.setHeading(newHeader);
+        setHeader(newHeaderOrNull);
         if (refreshColumnsDefinition)
         {
             this.columns = createColumnsDefinition();
@@ -243,6 +259,17 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex
         pagingLoader.load(0, PAGE_SIZE);
     }
 
+    private void setHeader(String newHeaderOrNull)
+    {
+        if (newHeaderOrNull != null)
+        {
+            this.contentPanel.setHeading(newHeaderOrNull);
+        } else
+        {
+            this.contentPanel.setHeaderVisible(false);
+        }
+    }
+
     private List<IColumnDefinition<T>> getSelectedColumns(
             List<IColumnDefinition<T>> availableColumns)
     {
@@ -318,6 +345,7 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex
         grid.setLoadMask(true);
         grid.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
         grid.addListener(Events.CellDoubleClick, detailsViewer);
+        GWTUtils.setAutoExpandOnLastVisibleColumn(grid);
         return grid;
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractColumnDefinitionKind.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractColumnDefinitionKind.java
index 8b6b35bce9bdb75b184bd3ac2a582e76d29336ee..81b41dddc9549e0d1dda826107563dcf935a5bcf 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractColumnDefinitionKind.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractColumnDefinitionKind.java
@@ -19,8 +19,9 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.renderer.SimpleDateRenderer;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.renderer.SimplePersonRenderer;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.renderer.SimpleYesNoRenderer;
-import ch.systemsx.cisd.openbis.generic.client.web.client.dto.CodeWithRegistration;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.AbstractRegistrationHolder;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.IInvalidationProvider;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Person;
 
 /**
  * Abstract superclass which holds meta data. Subclasses must implement
@@ -80,17 +81,22 @@ public abstract class AbstractColumnDefinitionKind<T> implements IColumnDefiniti
     {
         return sortField; // NOTE: it should be possible to use name() when sorting will be fixed
     }
-    
-    protected String renderRegistrationDate(final CodeWithRegistration<?> entity)
+
+    protected String renderRegistrationDate(final AbstractRegistrationHolder entity)
     {
         return SimpleDateRenderer.renderDate(entity.getRegistrationDate());
     }
 
-    protected String renderRegistrator(final CodeWithRegistration<?> entity)
+    protected String renderRegistrator(final AbstractRegistrationHolder entity)
     {
-        return SimplePersonRenderer.createPersonName(entity.getRegistrator()).toString();
+        return renderRegistrator(entity.getRegistrator());
     }
-    
+
+    protected String renderRegistrator(final Person person)
+    {
+        return SimplePersonRenderer.createPersonName(person).toString();
+    }
+
     protected String renderInvalidationFlag(final IInvalidationProvider invalidationProvider)
     {
         return SimpleYesNoRenderer.render(invalidationProvider.getInvalidation() != null);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowserToolbar.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowserToolbar.java
index f7b472c28dfb3fb783d6653d3d12bcc4cf591eab..e318c41a256861cbefc7ac6a2d176963a05a981c 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowserToolbar.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowserToolbar.java
@@ -176,8 +176,7 @@ final class SampleBrowserToolbar extends ToolBar
                                             createListCriteria(selectedType, selectedGroup,
                                                     includeGroup, includeInstance);
 
-                                    entitiesBrowser
-                                            .refresh(criteria, createPostRefreshCallback());
+                                    entitiesBrowser.refresh(criteria, createPostRefreshCallback());
                                 }
 
                                 private ListSampleCriteria createListCriteria(
@@ -196,9 +195,12 @@ final class SampleBrowserToolbar extends ToolBar
                                 {
                                     return new IDataRefreshCallback()
                                         {
-                                            public void postRefresh()
+                                            public void postRefresh(boolean wasSuccessful)
                                             {
-                                                controller.enableExportButton();
+                                                if (wasSuccessful)
+                                                {
+                                                    controller.enableExportButton();
+                                                }
                                             }
                                         };
                                 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/columns/ColumnDefsAndConfigs.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/columns/ColumnDefsAndConfigs.java
index 72ca6f30322f2c631e17241f45fb2599ecdc0db1..7728af7e2df1f3758312ba686f772f4ea7de6892 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/columns/ColumnDefsAndConfigs.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/columns/ColumnDefsAndConfigs.java
@@ -33,6 +33,14 @@ public class ColumnDefsAndConfigs<T>
 
     private final List<IColumnDefinition<T>> columnDefs;
 
+    public static <T> ColumnDefsAndConfigs<T> create(
+            List<? extends IColumnDefinitionUI<T>> columnsSchema, boolean isSortable)
+    {
+        ColumnDefsAndConfigs<T> result = new ColumnDefsAndConfigs<T>();
+        result.addColumns(columnsSchema, isSortable);
+        return result;
+    }
+
     public ColumnDefsAndConfigs()
     {
         this.columnConfigs = new ArrayList<ColumnConfig>();
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/columns/SampleModel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/columns/SampleModel.java
index 0ab60439b0db8f3ba76e95b2bc858c2c00497be1..8481252b43a31c8ddae582b1ff468adc69ec300c 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/columns/SampleModel.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/columns/SampleModel.java
@@ -27,10 +27,8 @@ import ch.systemsx.cisd.openbis.generic.client.shared.SampleTypePropertyType;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.AbstractEntityModel;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.CommonColumnDefinition;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IColumnDefinitionUI;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IMessageProvider;
-import ch.systemsx.cisd.openbis.generic.client.web.client.dto.IColumnDefinition;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Sample;
 
 /**
@@ -43,18 +41,11 @@ public final class SampleModel extends AbstractEntityModel<Sample>
 {
     private static final long serialVersionUID = 1L;
 
-    public SampleModel(final Sample sample)
+    public SampleModel(final Sample entity)
     {
-        set(ModelDataPropertyNames.OBJECT, sample);
-        set(ModelDataPropertyNames.SAMPLE_TYPE, sample.getSampleType() != null ? sample
+        super(entity, createColumnsSchema(entity));
+        set(ModelDataPropertyNames.SAMPLE_TYPE, entity.getSampleType() != null ? entity
                 .getSampleType().getCode() : null);
-
-        List<IColumnDefinitionUI<Sample>> columnsSchema = createColumnsSchema(sample);
-        for (IColumnDefinition<Sample> column : columnsSchema)
-        {
-            String value = renderColumnValue(sample, column);
-            set(column.getIdentifier(), value);
-        }
     }
 
     public static ColumnDefsAndConfigs<Sample> createColumnsSchema(
@@ -107,27 +98,10 @@ public final class SampleModel extends AbstractEntityModel<Sample>
         return list;
     }
 
-    // result is added to allColumns map
     private static List<IColumnDefinitionUI<Sample>> createCommonColumnsSchema(
             IMessageProvider msgProviderOrNull)
     {
-        List<IColumnDefinitionUI<Sample>> list = createColDefList();
-        for (CommonSampleColDefKind columnKind : CommonSampleColDefKind.values())
-        {
-            list.add(createColumn(columnKind, msgProviderOrNull));
-        }
-        return list;
-    }
-
-    private static CommonColumnDefinition<Sample> createColumn(CommonSampleColDefKind columnKind,
-            IMessageProvider messageProviderOrNull)
-    {
-        String headerText = null;
-        if (messageProviderOrNull != null)
-        {
-            headerText = messageProviderOrNull.getMessage(columnKind.getHeaderMsgKey());
-        }
-        return new CommonColumnDefinition<Sample>(columnKind, headerText);
+        return createColumnsSchemaFrom(CommonSampleColDefKind.values(), msgProviderOrNull);
     }
 
     private static List<IColumnDefinitionUI<Sample>> createParentColumnsSchema(
@@ -159,11 +133,6 @@ public final class SampleModel extends AbstractEntityModel<Sample>
         return msgProviderOrNull == null ? null : msgProviderOrNull.getMessage(messageKey, depth);
     }
 
-    public final Sample getBaseObject()
-    {
-        return (Sample) get(ModelDataPropertyNames.OBJECT);
-    }
-
     public final static List<SampleModel> asSampleModels(final List<Sample> samples)
     {
         final List<SampleModel> sampleModels = new ArrayList<SampleModel>(samples.size());
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 f563aea454c4a5da273f500056f3a9216666ea51..c2de30e455670e9477823e97697cdf1ef3b76af5 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
@@ -344,6 +344,13 @@ public final class CommonClientService extends AbstractClientService implements
         return prepareExportEntities(criteria);
     }
 
+    public final String prepareExportMatchingEntities(
+            final TableExportCriteria<MatchingEntity> criteria)
+            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
+    {
+        return prepareExportEntities(criteria);
+    }
+
     private <T> String prepareExportEntities(TableExportCriteria<T> criteria)
             throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
     {
@@ -441,7 +448,8 @@ public final class CommonClientService extends AbstractClientService implements
         try
         {
             final String sessionToken = getSessionToken();
-            final ExperimentIdentifier identifier = new ExperimentIdentifierFactory(experimentIdentifier).createIdentifier();
+            final ExperimentIdentifier identifier =
+                    new ExperimentIdentifierFactory(experimentIdentifier).createIdentifier();
             final List<ExternalDataPE> externalData =
                     commonServer.listExternalData(sessionToken, identifier);
             return BeanUtils.createBeanList(ExternalData.class, externalData);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/ClientPluginFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/ClientPluginFactory.java
index 3daf46196338c4e1ba18bb3cf7f9c06dd06ed732..69d099e34a077cb4d4c5d724057f61f9470d0009 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/ClientPluginFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/ClientPluginFactory.java
@@ -34,8 +34,6 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.plugin.Cli
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.plugin.IClientPlugin;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.plugin.IClientPluginFactory;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.EntityKind;
-import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Experiment;
-import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Sample;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.IGenericClientServiceAsync;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.experiment.GenericExperimentRegistrationForm;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.experiment.GenericExperimentViewer;
@@ -97,14 +95,14 @@ public final class ClientPluginFactory extends
     // Helper classes
     //
 
-    private final class SampleClientPlugin implements IClientPlugin<SampleType, Sample>
+    private final class SampleClientPlugin implements IClientPlugin<SampleType, IIdentifierHolder>
     {
 
         //
         // IViewClientPlugin
         //
 
-        public ITabItemFactory createEntityViewer(final Sample sample)
+        public ITabItemFactory createEntityViewer(final IIdentifierHolder sample)
         {
             final String identifier = sample.getIdentifier();
             return new ITabItemFactory()
@@ -140,7 +138,7 @@ public final class ClientPluginFactory extends
     }
 
     private final class ExperimentClientPlugin extends
-            ClientPluginAdapter<ExperimentType, Experiment>
+            ClientPluginAdapter<ExperimentType, IIdentifierHolder>
     {
 
         //
@@ -148,9 +146,9 @@ public final class ClientPluginFactory extends
         //
 
         @Override
-        public final ITabItemFactory createEntityViewer(final Experiment experiment)
+        public final ITabItemFactory createEntityViewer(final IIdentifierHolder identifiable)
         {
-            final String identifier = experiment.getIdentifier();
+            final String identifier = identifiable.getIdentifier();
             return new ITabItemFactory()
                 {
                     public ITabItem create()
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/ExperimentDataSection.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/ExperimentDataSection.java
index 9783c9076e1a5cabf8d0e198ba1a3fd4eca3f7ce..b38b733f43cd37a1f0609213ba0c4bcc68125250 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/ExperimentDataSection.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/ExperimentDataSection.java
@@ -32,14 +32,10 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewConte
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ExternalDataModel;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.ColumnConfigFactory;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.columns.SampleModel;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListSampleCriteria;
-import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier;
-import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.IdentifierHelper;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.IGenericClientServiceAsync;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.ListExternalDataCallback;
-import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.experiment.ExperimentSamplesSection.ListSamplesCallback;
 
 /**
  * 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/ClientPluginFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/ClientPluginFactory.java
index 6ffff493c21524f5caa8b326a62bb55ceaa60e37..0c1d608b615745153f8923633b1fc2ae233a18bb 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/ClientPluginFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/ClientPluginFactory.java
@@ -38,8 +38,6 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.plugin.Cli
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.plugin.IClientPlugin;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.plugin.IClientPluginFactory;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.EntityKind;
-import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Experiment;
-import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Sample;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.SampleTypeCode;
 import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.IScreeningClientServiceAsync;
 
@@ -104,13 +102,13 @@ public final class ClientPluginFactory extends
     // Helper classes
     //
 
-    private final class SampleClientPlugin implements IClientPlugin<SampleType, Sample>
+    private final class SampleClientPlugin implements IClientPlugin<SampleType, IIdentifierHolder>
     {
         //
         // IViewClientPlugin
         //
 
-        public final ITabItemFactory createEntityViewer(final Sample sample)
+        public final ITabItemFactory createEntityViewer(final IIdentifierHolder sample)
         {
             final String sampleIdentifier = sample.getIdentifier();
             return new ITabItemFactory()
@@ -146,7 +144,7 @@ public final class ClientPluginFactory extends
     }
 
     private final static class ExperimentClientPlugin extends
-            ClientPluginAdapter<ExperimentType, Experiment>
+            ClientPluginAdapter<ExperimentType, IIdentifierHolder>
     {
 
         //
@@ -154,7 +152,7 @@ public final class ClientPluginFactory extends
         //
 
         @Override
-        public final ITabItemFactory createEntityViewer(final Experiment identifier)
+        public final ITabItemFactory createEntityViewer(final IIdentifierHolder identifier)
         {
             return new ITabItemFactory()
                 {
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/SearchTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/SearchTest.java
index a8283c949aee90d637bfe942bee4dfff8d1e8db9..03780ef6441c91483e4d48af268a261f67fcd41e 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/SearchTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/SearchTest.java
@@ -18,7 +18,6 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application;
 
 import static ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames.IDENTIFIER;
 
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.SearchWidget.SearchResultCallback;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.Login;
 import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.AbstractGWTTestCase;
 import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.CheckTableCommand;
@@ -34,8 +33,8 @@ public class SearchTest extends AbstractGWTTestCase
     private final static CheckTableCommand createCheckTableCommandForAll()
     {
         final CheckTableCommand checkTableCommand =
-                new CheckTableCommand(MatchingEntitiesPanel.GRID_ID, SearchResultCallback.class)
-                        .expectedSize(2);
+                new CheckTableCommand(MatchingEntitiesPanel.GRID_ID,
+                        MatchingEntitiesPanel.ListEntitiesCallback.class).expectedSize(2);
         checkTableCommand.expectedRow(new Row().withCell(IDENTIFIER, "CISD:/MP"));
         checkTableCommand.expectedRow(new Row().withCell(IDENTIFIER, "CISD:/CISD/EMPTY-MP"));
         return checkTableCommand;
@@ -44,8 +43,8 @@ public class SearchTest extends AbstractGWTTestCase
     private final static CheckTableCommand createCheckTableCommandForExperiment()
     {
         final CheckTableCommand checkTableCommand =
-                new CheckTableCommand(MatchingEntitiesPanel.GRID_ID, SearchResultCallback.class)
-                        .expectedSize(5);
+                new CheckTableCommand(MatchingEntitiesPanel.GRID_ID,
+                        MatchingEntitiesPanel.ListEntitiesCallback.class).expectedSize(5);
         checkTableCommand.expectedRow(new Row().withCell(IDENTIFIER, "CISD:/CISD/NEMO/EXP10"));
         checkTableCommand.expectedRow(new Row().withCell(IDENTIFIER, "CISD:/CISD/NEMO/EXP11"));
         checkTableCommand.expectedRow(new Row().withCell(IDENTIFIER, "CISD:/CISD/NEMO/EXP1"));