diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchCriteriaWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchCriteriaWidget.java
index 6286b79010e9f3206423ee64cd25ee0305709f89..c494714294d010c001a9f26bca3a0663c416095e 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchCriteriaWidget.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchCriteriaWidget.java
@@ -21,29 +21,28 @@ import java.util.List;
 
 import com.extjs.gxt.ui.client.event.KeyboardEvents;
 import com.extjs.gxt.ui.client.widget.VerticalPanel;
+import com.google.gwt.user.client.Element;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriterion;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SearchCriteriaConnection;
 
 /**
- * Widget for {@link DetailedSearchCriteria} management.
+ * Abstract widget for management of detailed search criteria (main criteria or sub criteria).
  * 
  * @author Izabela Adamczyk
  * @author Piotr Buczek
  */
-public class DetailedSearchCriteriaWidget extends VerticalPanel
+abstract public class DetailedSearchCriteriaWidget extends VerticalPanel
 {
     public static final String FIRST_ID_SUFFIX = "_first";
 
     private final List<DetailedSearchCriterionWidget> criteriaWidgets;
 
-    private final MatchCriteriaRadio matchRadios;
-
     private final IViewContext<ICommonClientServiceAsync> viewContext;
 
     private final EntityKind entityKind;
@@ -55,13 +54,25 @@ public class DetailedSearchCriteriaWidget extends VerticalPanel
         this.entityKind = entityKind;
         setLayoutOnChange(true);
         criteriaWidgets = new ArrayList<DetailedSearchCriterionWidget>();
-        add(matchRadios =
-                new MatchCriteriaRadio(viewContext.getMessage(Dict.MATCH_ALL), viewContext
-                        .getMessage(Dict.MATCH_ANY)));
+    }
+
+    protected abstract SearchCriteriaConnection getConnection();
+
+    protected abstract void setConnection(SearchCriteriaConnection connection);
+
+    protected void addInitialWidgets()
+    {
         addCriterion(new DetailedSearchCriterionWidget(viewContext, this, FIRST_ID_SUFFIX,
                 this.entityKind));
     }
 
+    @Override
+    protected void onRender(Element parent, int pos)
+    {
+        super.onRender(parent, pos);
+        addInitialWidgets();
+    }
+
     private void enableRemovalIfOneExists(final boolean enable)
     {
         if (criteriaWidgets.size() == 1)
@@ -126,11 +137,10 @@ public class DetailedSearchCriteriaWidget extends VerticalPanel
 
     /**
      * @return <b>search criteria</b> extracted from criteria widgets and "match" radio buttons<br>
-     *         <b>null</b> if no criteria were selected
+     *         <b>NOTE:</b> criterion list of resulting criteria may be empty
      */
-    public DetailedSearchCriteria tryGetCriteria()
+    public DetailedSearchCriteria extractCriteria()
     {
-
         List<DetailedSearchCriterion> criteria = new ArrayList<DetailedSearchCriterion>();
         for (DetailedSearchCriterionWidget cw : criteriaWidgets)
         {
@@ -140,24 +150,19 @@ public class DetailedSearchCriteriaWidget extends VerticalPanel
                 criteria.add(value);
             }
         }
-        if (criteria.size() > 0)
-        {
-            final DetailedSearchCriteria result = new DetailedSearchCriteria();
-            result.setUseWildcardSearchMode(viewContext.getDisplaySettingsManager()
-                    .isUseWildcardSearchMode());
-            result.setConnection(matchRadios.getSelected());
-            result.setCriteria(criteria);
-            return result;
-        }
-        return null;
-
+        final DetailedSearchCriteria result = new DetailedSearchCriteria();
+        result.setUseWildcardSearchMode(viewContext.getDisplaySettingsManager()
+                .isUseWildcardSearchMode());
+        result.setConnection(getConnection());
+        result.setCriteria(criteria);
+        return result;
     }
 
     /** description of the search criteria for the user */
     public String getCriteriaDescription()
     {
         StringBuffer sb = new StringBuffer();
-        sb.append(matchRadios.getSelectedLabel());
+        sb.append(getConnection().getLabel());
         sb.append(": ");
         boolean first = true;
         for (DetailedSearchCriterionWidget cw : criteriaWidgets)
@@ -178,13 +183,25 @@ public class DetailedSearchCriteriaWidget extends VerticalPanel
         return sb.toString();
     }
 
+    public boolean isCriteriaFilled()
+    {
+        for (DetailedSearchCriterionWidget cw : criteriaWidgets)
+        {
+            DetailedSearchCriterion value = cw.tryGetValue();
+            if (value != null)
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Resets "match criteria" radio buttons to initial values, removes unnecessary criteria widgets
      * and resets the remaining ones.
      */
     public void reset()
     {
-        matchRadios.reset();
         List<DetailedSearchCriterionWidget> list =
                 new ArrayList<DetailedSearchCriterionWidget>(criteriaWidgets);
         for (DetailedSearchCriterionWidget cw : list)
@@ -220,7 +237,7 @@ public class DetailedSearchCriteriaWidget extends VerticalPanel
             addCriterion(widget);
         }
 
-        matchRadios.setValue(searchCriteria.getConnection());
+        setConnection(searchCriteria.getConnection());
     }
 
     void onEnterKey()
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchMainCriteriaWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchMainCriteriaWidget.java
new file mode 100644
index 0000000000000000000000000000000000000000..a8b797bd989578d8ffa6ad6ae51caa7e66bbab24
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchMainCriteriaWidget.java
@@ -0,0 +1,70 @@
+/*
+ * 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.application.ui.search;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SearchCriteriaConnection;
+
+/**
+ * Widget for {@link DetailedSearchCriteria} management.
+ * 
+ * @author Izabela Adamczyk
+ * @author Piotr Buczek
+ */
+public class DetailedSearchMainCriteriaWidget extends DetailedSearchCriteriaWidget
+{
+    private final MatchCriteriaRadio matchRadios;
+
+    public DetailedSearchMainCriteriaWidget(IViewContext<ICommonClientServiceAsync> viewContext,
+            EntityKind entityKind)
+    {
+        super(viewContext, entityKind);
+        matchRadios =
+                new MatchCriteriaRadio(viewContext.getMessage(Dict.MATCH_ALL),
+                        viewContext.getMessage(Dict.MATCH_ANY));
+    }
+
+    @Override
+    protected void addInitialWidgets()
+    {
+        add(matchRadios);
+        super.addInitialWidgets();
+    }
+
+    @Override
+    public void reset()
+    {
+        matchRadios.reset();
+        super.reset();
+    }
+
+    @Override
+    protected SearchCriteriaConnection getConnection()
+    {
+        return matchRadios.getSelected();
+    }
+
+    @Override
+    protected void setConnection(SearchCriteriaConnection connection)
+    {
+        matchRadios.setValue(connection);
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchSubCriteriaWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchSubCriteriaWidget.java
new file mode 100644
index 0000000000000000000000000000000000000000..8998f04c74dd88503ce1e5359db21ce04d7237e0
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchSubCriteriaWidget.java
@@ -0,0 +1,76 @@
+/*
+ * 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.application.ui.search;
+
+import com.extjs.gxt.ui.client.widget.Label;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AssociatedEntityKind;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchSubCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SearchCriteriaConnection;
+
+/**
+ * Widget for {@link DetailedSearchSubCriteria} management.
+ * 
+ * @author Piotr Buczek
+ */
+public class DetailedSearchSubCriteriaWidget extends DetailedSearchCriteriaWidget
+{
+    private AssociatedEntityKind association;
+
+    private SearchCriteriaConnection connection;
+
+    public DetailedSearchSubCriteriaWidget(IViewContext<ICommonClientServiceAsync> viewContext,
+            AssociatedEntityKind association)
+    {
+        super(viewContext, association.getEntityKind());
+        this.association = association;
+        setConnection(SearchCriteriaConnection.MATCH_ALL);
+    }
+
+    @Override
+    protected void addInitialWidgets()
+    {
+        add(new Label(association.getDescription()));
+        super.addInitialWidgets();
+    }
+
+    @Override
+    protected SearchCriteriaConnection getConnection()
+    {
+        return connection;
+    }
+
+    @Override
+    protected void setConnection(SearchCriteriaConnection connection)
+    {
+        this.connection = connection;
+    }
+
+    @Override
+    public String getCriteriaDescription()
+    {
+        return association.getDescription() + "(" + super.getCriteriaDescription() + ")";
+    }
+
+    public DetailedSearchSubCriteria extractSubCriteria()
+    {
+        return new DetailedSearchSubCriteria(association, extractCriteria());
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchWindow.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchWindow.java
index 99914a13c11f13c5335a718383de1a7f6d4c739f..a5181449e0b45c3c70f8e1349039b6ced047b4cf 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchWindow.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/search/DetailedSearchWindow.java
@@ -1,5 +1,7 @@
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.search;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 import com.extjs.gxt.ui.client.Style.Scroll;
@@ -12,8 +14,7 @@ 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.button.ButtonBar;
-import com.extjs.gxt.ui.client.widget.layout.FitData;
-import com.extjs.gxt.ui.client.widget.layout.FitLayout;
+import com.extjs.gxt.ui.client.widget.layout.FillLayout;
 import com.google.gwt.event.dom.client.KeyCodes;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
@@ -22,7 +23,9 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewConte
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.help.HelpPageIdentifier;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.data.DataSetSearchHitGrid;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.DialogWithOnlineHelpUtils;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AssociatedEntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchSubCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 
@@ -36,7 +39,7 @@ public class DetailedSearchWindow extends Dialog
 {
     public static final String SEARCH_BUTTON_ID = DataSetSearchHitGrid.BROWSER_ID + "search_button";
 
-    private static final int MARGIN = 5;
+    // private static final int MARGIN = 5;
 
     private static final int HEIGHT = 400;
 
@@ -44,6 +47,9 @@ public class DetailedSearchWindow extends Dialog
 
     private DetailedSearchCriteriaWidget criteriaWidget;
 
+    private List<DetailedSearchSubCriteriaWidget> subCriteriaWidgets =
+            new ArrayList<DetailedSearchSubCriteriaWidget>();
+
     private DetailedSearchToolbar updateListener;
 
     public DetailedSearchWindow(final IViewContext<ICommonClientServiceAsync> viewContext,
@@ -52,10 +58,18 @@ public class DetailedSearchWindow extends Dialog
         setSize(WIDTH, HEIGHT);
         setModal(true);
         setScrollMode(Scroll.AUTOY);
-        setLayout(new FitLayout());
+        setLayout(new FillLayout());
         setResizable(false);
-        add(criteriaWidget = new DetailedSearchCriteriaWidget(viewContext, entityKind),
-                new FitData(MARGIN));
+        add(criteriaWidget = new DetailedSearchMainCriteriaWidget(viewContext, entityKind));
+        for (AssociatedEntityKind association : getAssociatedEntityKinds(entityKind))
+        {
+            DetailedSearchSubCriteriaWidget subCriteriaWidget =
+                    new DetailedSearchSubCriteriaWidget(viewContext, association);
+            subCriteriaWidgets.add(subCriteriaWidget);
+            add(subCriteriaWidget);
+        }
+        // new FitData(MARGIN));
+        // new FitData(MARGIN));
         addEnterListener();
         final ButtonBar bar = getButtonBar();
         bar.removeAll();
@@ -75,6 +89,10 @@ public class DetailedSearchWindow extends Dialog
                         public void componentSelected(ButtonEvent ce)
                         {
                             criteriaWidget.reset();
+                            for (DetailedSearchCriteriaWidget widget : subCriteriaWidgets)
+                            {
+                                widget.reset();
+                            }
                         }
                     }));
         final Button searchButton =
@@ -114,6 +132,7 @@ public class DetailedSearchWindow extends Dialog
                 }
 
             });
+        // TODO improve
     }
 
     @Override
@@ -125,12 +144,46 @@ public class DetailedSearchWindow extends Dialog
 
     public DetailedSearchCriteria tryGetCriteria()
     {
-        return criteriaWidget.tryGetCriteria();
+        final DetailedSearchCriteria mainCriteria = criteriaWidget.extractCriteria();
+        for (DetailedSearchSubCriteriaWidget subCriteriaWidget : subCriteriaWidgets)
+        {
+            if (subCriteriaWidget.isCriteriaFilled())
+            {
+                final DetailedSearchSubCriteria subCriteria =
+                        subCriteriaWidget.extractSubCriteria();
+                mainCriteria.addSubCriteria(subCriteria);
+            }
+        }
+
+        if (mainCriteria.isEmpty())
+        {
+            return null;
+        } else
+        {
+            return mainCriteria;
+        }
     }
 
     public String getCriteriaDescription()
     {
-        return criteriaWidget.getCriteriaDescription();
+        StringBuilder sb = new StringBuilder();
+        if (criteriaWidget.isCriteriaFilled())
+        {
+            sb.append(criteriaWidget.getCriteriaDescription());
+        }
+        for (DetailedSearchCriteriaWidget subCriteriaWidget : subCriteriaWidgets)
+        {
+            if (subCriteriaWidget.isCriteriaFilled())
+            {
+                sb.append(", ");
+                sb.append(subCriteriaWidget.getCriteriaDescription());
+            }
+        }
+        if (criteriaWidget.isCriteriaFilled() == false)
+        {
+            sb.delete(0, 2);
+        }
+        return sb.toString();
     }
 
     public void setUpdateListener(DetailedSearchToolbar toolbar)
@@ -169,8 +222,22 @@ public class DetailedSearchWindow extends Dialog
     {
         hide();
         List<PropertyType> availablePropertyTypes = criteriaWidget.getAvailablePropertyTypes();
-        DetailedSearchCriteria criteria = criteriaWidget.tryGetCriteria();
-        String criteriaDescription = criteriaWidget.getCriteriaDescription();
+        DetailedSearchCriteria criteria = tryGetCriteria();
+        String criteriaDescription = getCriteriaDescription();
         updateListener.updateSearchResults(criteria, criteriaDescription, availablePropertyTypes);
     }
+
+    private static List<AssociatedEntityKind> getAssociatedEntityKinds(final EntityKind sourceEntity)
+    {
+        // TODO 2011-05-06, Piotr Buczek: use
+        // AssociatedEntityKind.getAssociatedEntityKinds(sourceEntity)
+        // after extending data set search
+        if (sourceEntity == EntityKind.SAMPLE)
+        {
+            return AssociatedEntityKind.getAssociatedEntityKinds(sourceEntity);
+        } else
+        {
+            return Collections.emptyList();
+        }
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ListSamplesOriginalDataProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ListSamplesOriginalDataProvider.java
index cb9d71fc0d766c218c41b05fa3ba690e1051707f..c7ecf7a1b7d2557f9b4429a6814b8d639f819c2c 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ListSamplesOriginalDataProvider.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ListSamplesOriginalDataProvider.java
@@ -1,12 +1,10 @@
 package ch.systemsx.cisd.openbis.generic.client.web.server;
 
-import java.util.Collections;
 import java.util.List;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListSampleDisplayCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.IOriginalDataProvider;
 import ch.systemsx.cisd.openbis.generic.shared.ICommonServer;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchSubCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 
 /**
@@ -39,8 +37,7 @@ final class ListSamplesOriginalDataProvider extends AbstractOriginalDataProvider
             case BROWSE:
                 return commonServer.listSamples(sessionToken, criteria.getBrowseCriteria());
             case SEARCH:
-                return commonServer.searchForSamples(sessionToken, criteria.getSearchCriteria(),
-                        Collections.<DetailedSearchSubCriteria> emptyList());
+                return commonServer.searchForSamples(sessionToken, criteria.getSearchCriteria());
         }
         return null; // not possible
     }
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
index 19bab51b8f9b8e4d258d9d5ff6e42871a18b6c06..c1bd667814bd9bfd1e076169e4589e0e373ede2d 100644
--- 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
@@ -34,7 +34,6 @@ import static ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGridC
 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.Collections;
 import java.util.List;
 import java.util.Set;
 
@@ -44,7 +43,6 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListSampleDisplayC
 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.DetailedSearchSubCriteria;
 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.SampleType;
@@ -204,8 +202,7 @@ public class SampleProvider extends AbstractCommonTableModelProvider<Sample>
             case BROWSE:
                 return commonServer.listSamples(sessionToken, criteria.getBrowseCriteria());
             case SEARCH:
-                return commonServer.searchForSamples(sessionToken, criteria.getSearchCriteria(),
-                        Collections.<DetailedSearchSubCriteria> emptyList());
+                return commonServer.searchForSamples(sessionToken, criteria.getSearchCriteria());
         }
         return null; // not possible
     }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
index 4d6c378db8e1a9611a80de3bfb7fb23caf1b5422..daaac03b22b104011ab5753fb6e44e1079eeef29 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
@@ -470,6 +470,20 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
         return sampleLister.list(new ListOrSearchSampleCriteria(criteria));
     }
 
+    public List<Sample> searchForSamples(String sessionToken, DetailedSearchCriteria criteria)
+    {
+        final Session session = getSession(sessionToken);
+        try
+        {
+            final ISampleLister sampleLister = businessObjectFactory.createSampleLister(session);
+            final IHibernateSearchDAO searchDAO = getDAOFactory().getHibernateSearchDAO();
+            return new DetailedSearchManager(searchDAO, sampleLister).searchForSamples(criteria);
+        } catch (final DataAccessException ex)
+        {
+            throw createUserFailureException(ex);
+        }
+    }
+
     public List<Sample> searchForSamples(String sessionToken, DetailedSearchCriteria criteria,
             List<DetailedSearchSubCriteria> subCriterias)
     {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/DetailedSearchManager.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/DetailedSearchManager.java
index 74e1501b10d974346bbcd00e610f1af4cdafcfea..59cddcbfed58c8949d6b3290aa109a778cf5bf1e 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/DetailedSearchManager.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/DetailedSearchManager.java
@@ -57,6 +57,54 @@ public class DetailedSearchManager
         this.sampleLister = sampleLister;
     }
 
+    public List<Sample> searchForSamples(DetailedSearchCriteria criteria)
+            throws DataAccessException
+    {
+        final DetailedSearchCriteria parentCriteria = new DetailedSearchCriteria();
+        final DetailedSearchCriteria childCriteria = new DetailedSearchCriteria();
+        final List<DetailedSearchSubCriteria> otherSubCriterias =
+                new ArrayList<DetailedSearchSubCriteria>();
+        groupSampleSubCriteria(criteria.getSubCriterias(), parentCriteria, childCriteria,
+                otherSubCriterias);
+
+        final List<Long> mainSampleIds = findSampleIds(criteria, otherSubCriterias);
+
+        final Set<Long> filteredSampleIds = new HashSet<Long>();
+        if (false == parentCriteria.isEmpty())
+        {
+            final List<Long> parentSampleIds =
+                    findSampleIds(parentCriteria,
+                            Collections.<DetailedSearchSubCriteria> emptyList());
+            if (mainSampleIds.size() > parentSampleIds.size())
+            {
+                listParentsChildrenAndFilterChildren(mainSampleIds, parentSampleIds,
+                        filteredSampleIds);
+            } else
+            {
+                listChildrensParentsAndFilterChildren(mainSampleIds, parentSampleIds,
+                        filteredSampleIds);
+            }
+        } else if (false == childCriteria.isEmpty())
+        {
+            final List<Long> childSampleIds =
+                    findSampleIds(childCriteria,
+                            Collections.<DetailedSearchSubCriteria> emptyList());
+            if (mainSampleIds.size() > childSampleIds.size())
+            {
+                listChildrensParentsAndFilterParents(childSampleIds, mainSampleIds,
+                        filteredSampleIds);
+            } else
+            {
+                listParentsChildrenAndFilterParents(childSampleIds, mainSampleIds,
+                        filteredSampleIds);
+            }
+        } else
+        {
+            filteredSampleIds.addAll(mainSampleIds);
+        }
+        return sampleLister.list(new ListOrSearchSampleCriteria(filteredSampleIds));
+    }
+
     public List<Sample> searchForSamples(DetailedSearchCriteria criteria,
             List<DetailedSearchSubCriteria> subCriterias) throws DataAccessException
     {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java
index 2c3f884e7c96cad1125d1a00ea253e4d2aafcb62..de4d0ad93a618d5f2d5a3508e091eb64a4afd84a 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java
@@ -577,6 +577,14 @@ public interface ICommonServer extends IServer
     public List<Sample> searchForSamples(String sessionToken, DetailedSearchCriteria criteria,
             List<DetailedSearchSubCriteria> subCriterias);
 
+    /**
+     * Performs an <i>Hibernate Search</i> based on given parameters.
+     */
+    @Transactional(readOnly = true)
+    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
+    @ReturnValueFilter(validatorClass = SampleValidator.class)
+    public List<Sample> searchForSamples(String sessionToken, DetailedSearchCriteria criteria);
+
     /**
      * Returns all data sets related to specified entities.
      */
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/AssociatedEntityKind.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/AssociatedEntityKind.java
index e50c8df8b0efa856f8712613fefce5079c999e13..e85d5ca516236e4e7ae72d536e7cdf321176d05b 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/AssociatedEntityKind.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/AssociatedEntityKind.java
@@ -16,6 +16,11 @@
 
 package ch.systemsx.cisd.openbis.generic.shared.basic.dto;
 
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
+
 import ch.systemsx.cisd.openbis.generic.shared.basic.ISerializable;
 
 /**
@@ -26,24 +31,29 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.ISerializable;
  */
 public enum AssociatedEntityKind implements ISerializable
 {
-    SAMPLE("Sample", EntityKind.SAMPLE),
+    SAMPLE("Sample", EntityKind.SAMPLE, EnumSet.of(EntityKind.DATA_SET)),
 
-    EXPERIMENT("Experiment", EntityKind.EXPERIMENT),
+    EXPERIMENT("Experiment", EntityKind.EXPERIMENT, EnumSet.of(EntityKind.SAMPLE,
+            EntityKind.DATA_SET)),
 
-    SAMPLE_CONTAINER("Container", EntityKind.SAMPLE),
+    SAMPLE_CONTAINER("Container", EntityKind.SAMPLE, EnumSet.of(EntityKind.SAMPLE)),
 
-    SAMPLE_PARENT("Parent", EntityKind.SAMPLE),
+    SAMPLE_PARENT("Parent", EntityKind.SAMPLE, EnumSet.of(EntityKind.SAMPLE)),
 
-    SAMPLE_CHILD("Child", EntityKind.SAMPLE);
+    SAMPLE_CHILD("Child", EntityKind.SAMPLE, EnumSet.of(EntityKind.SAMPLE));
 
     private final String description;
 
     private final EntityKind entityKind;
 
-    private AssociatedEntityKind(final String description, final EntityKind entityKind)
+    private final Set<EntityKind> sourceEntityKinds;
+
+    private AssociatedEntityKind(final String description, final EntityKind entityKind,
+            final Set<EntityKind> sourceEntityKinds)
     {
         this.description = description;
         this.entityKind = entityKind;
+        this.sourceEntityKinds = sourceEntityKinds;
     }
 
     public final String getDescription()
@@ -56,4 +66,17 @@ public enum AssociatedEntityKind implements ISerializable
         return entityKind;
     }
 
+    public static List<AssociatedEntityKind> getAssociatedEntityKinds(EntityKind sourceEntity)
+    {
+        List<AssociatedEntityKind> result = new ArrayList<AssociatedEntityKind>();
+        for (AssociatedEntityKind associatedEntityKind : values())
+        {
+            if (associatedEntityKind.sourceEntityKinds.contains(sourceEntity))
+            {
+                result.add(associatedEntityKind);
+            }
+        }
+        return result;
+    }
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailedSearchCriteria.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailedSearchCriteria.java
index a266675ba0ab7e293ef30241be79580529c1f3b4..3dad9cfe52e68c87c48155e22077b08eae3b9b04 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailedSearchCriteria.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailedSearchCriteria.java
@@ -16,6 +16,7 @@
 
 package ch.systemsx.cisd.openbis.generic.shared.basic.dto;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import ch.systemsx.cisd.openbis.generic.shared.basic.ISerializable;
@@ -36,6 +37,9 @@ public class DetailedSearchCriteria implements ISerializable
 
     private boolean useWildcardSearchMode;
 
+    private List<DetailedSearchSubCriteria> subCriterias =
+            new ArrayList<DetailedSearchSubCriteria>();
+
     public DetailedSearchCriteria()
     {
     }
@@ -50,6 +54,21 @@ public class DetailedSearchCriteria implements ISerializable
         this.criteria = criteria;
     }
 
+    public List<DetailedSearchSubCriteria> getSubCriterias()
+    {
+        return subCriterias;
+    }
+
+    public void setSubCriterias(List<DetailedSearchSubCriteria> subCriterias)
+    {
+        this.subCriterias = subCriterias;
+    }
+
+    public void addSubCriteria(DetailedSearchSubCriteria subCriteria)
+    {
+        subCriterias.add(subCriteria);
+    }
+
     public SearchCriteriaConnection getConnection()
     {
         return connection;
@@ -72,7 +91,7 @@ public class DetailedSearchCriteria implements ISerializable
 
     public boolean isEmpty()
     {
-        return criteria == null || criteria.isEmpty();
+        return (criteria == null || criteria.isEmpty()) && subCriterias.isEmpty();
     }
 
     @Override
@@ -90,6 +109,14 @@ public class DetailedSearchCriteria implements ISerializable
                 sb.append(element);
             }
         }
+        for (DetailedSearchSubCriteria subCriteria : subCriterias)
+        {
+            if (sb.length() > 0)
+            {
+                sb.append(", ");
+            }
+            sb.append(subCriteria.getTargetEntityKind() + ": " + subCriteria.toString());
+        }
         sb.append(" (" + (isUseWildcardSearchMode() ? "with" : "without") + " wildcards)");
         return sb.toString();
     }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailedSearchSubCriteria.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailedSearchSubCriteria.java
index 979ce58dc59e380057cc49b8c8fb4d0c31e397cd..1206e5b54322fa53a181587fcf280006b21f0f63 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailedSearchSubCriteria.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DetailedSearchSubCriteria.java
@@ -57,4 +57,9 @@ public class DetailedSearchSubCriteria implements ISerializable
         return sb.toString();
     }
 
+    // GWT only
+    @SuppressWarnings("unused")
+    private DetailedSearchSubCriteria()
+    {
+    }
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected
index 2c3f884e7c96cad1125d1a00ea253e4d2aafcb62..de4d0ad93a618d5f2d5a3508e091eb64a4afd84a 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected
@@ -577,6 +577,14 @@ public interface ICommonServer extends IServer
     public List<Sample> searchForSamples(String sessionToken, DetailedSearchCriteria criteria,
             List<DetailedSearchSubCriteria> subCriterias);
 
+    /**
+     * Performs an <i>Hibernate Search</i> based on given parameters.
+     */
+    @Transactional(readOnly = true)
+    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
+    @ReturnValueFilter(validatorClass = SampleValidator.class)
+    public List<Sample> searchForSamples(String sessionToken, DetailedSearchCriteria criteria);
+
     /**
      * Returns all data sets related to specified entities.
      */