diff --git a/integration-tests/testData/test_scu_microscopy/ouoldiafa1atfromqcb7kvfdqu.properties b/integration-tests/testData/test_scu_microscopy/ouoldiafa1atfromqcb7kvfdqu.properties
index 253a4ac50c757c32764b6cb0d5f526caa3899b49..55b2a3cbb9a49fe52ea0fb8ab24409c91caf381c 100644
--- a/integration-tests/testData/test_scu_microscopy/ouoldiafa1atfromqcb7kvfdqu.properties
+++ b/integration-tests/testData/test_scu_microscopy/ouoldiafa1atfromqcb7kvfdqu.properties
@@ -3,5 +3,5 @@ number-of-additional-data-sets = 1
 number-of-experiments = 1
 number-of-samples = 1
 registration-timeout-in-minutes = 4
-thumbnail-generation-time-in-seconds = 46
-registration-time-in-seconds = 54
+thumbnail-generation-time-in-seconds = 60
+registration-time-in-seconds = 65
diff --git a/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-jsVSjava.js b/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-jsVSjava.js
index 9cb02f6229d347f2d9a639fc03d5bae600440791..edbae18aad43dd6735c04eb81d740c728ff391b0 100644
--- a/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-jsVSjava.js
+++ b/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-jsVSjava.js
@@ -18,6 +18,8 @@ define([ 'jquery', 'underscore', 'openbis', 'test/common' ], function($, _, open
 			"CustomASServiceContext" : "Java class ignored: ",
 			"AbstractCollectionView" : "Java class ignored: ",
 			"AbstractExecutionOptionsWithParameters" : "Java class ignored: ",
+			"AbstractSampleSearchCriteria" : "Java class ignored: ",
+			"AbstractDataSetSearchCriteria" : "Java class ignored: ",
 			"ListView" : "Java class ignored: ",
 			"SetView" : "Java class ignored: ",
 			"NotFetchedException" : "Java class ignored: ",
diff --git a/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-search.js b/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-search.js
index 12d867d5184d45159cef02fffca1d2d17fd36315..5f78fcebfad7c6723f59e208b34e9c9c7360b9ef 100644
--- a/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-search.js
+++ b/js-test/servers/common/core-plugins/tests/1/as/webapps/openbis-v3-api-test/html/test/test-search.js
@@ -606,6 +606,38 @@ define([ 'jquery', 'underscore', 'openbis', 'test/openbis-execute-operations', '
 			testSearch(c, fSearch, fCheck);
 		});
 
+		QUnit.test("searchSamples() withChildren", function(assert) {
+			var c = new common(assert, openbis);
+			
+			var fSearch = function(facade) {
+				var criteria = new c.SampleSearchCriteria();
+				criteria.withChildren().withCode().thatContains("CHILD");
+				return facade.searchSamples(criteria, c.createSampleFetchOptions());
+			}
+			
+			var fCheck = function(facade, samples) {
+				c.assertObjectsWithValues(samples, "code", [ "TEST-SAMPLE-2" ]);
+			}
+			
+			testSearch(c, fSearch, fCheck);
+		});
+		
+		QUnit.test("searchSamples() withParents", function(assert) {
+			var c = new common(assert, openbis);
+			
+			var fSearch = function(facade) {
+				var criteria = new c.SampleSearchCriteria();
+				criteria.withParents().withCode().thatContains("ARE");
+				return facade.searchSamples(criteria, c.createSampleFetchOptions());
+			}
+			
+			var fCheck = function(facade, samples) {
+				c.assertObjectsWithValues(samples, "code", [ "TEST-SAMPLE-2" ]);
+			}
+			
+			testSearch(c, fSearch, fCheck);
+		});
+		
 		QUnit.test("searchSamples() with sorting by identifier", function(assert) {
 			var c = new common(assert, openbis);
 
@@ -999,6 +1031,54 @@ define([ 'jquery', 'underscore', 'openbis', 'test/openbis-execute-operations', '
 			testSearch(c, fSearch, fCheck);
 		});
 
+		QUnit.test("searchDataSets() withChildren", function(assert) {
+			var c = new common(assert, openbis);
+			
+			var fSearch = function(facade) {
+				var criteria = new c.DataSetSearchCriteria();
+				criteria.withChildren().withCode().thatEquals("20130415100238098-408");
+				return facade.searchDataSets(criteria, c.createDataSetFetchOptions());
+			}
+			
+			var fCheck = function(facade, dataSets) {
+				c.assertObjectsWithValues(dataSets, "code", [ "20130415093804724-403" ]);
+			}
+			
+			testSearch(c, fSearch, fCheck);
+		});
+		
+		QUnit.test("searchDataSets() withParents", function(assert) {
+			var c = new common(assert, openbis);
+			
+			var fSearch = function(facade) {
+				var criteria = new c.DataSetSearchCriteria();
+				criteria.withParents().withCode().thatEquals("20130415100158230-407");
+				return facade.searchDataSets(criteria, c.createDataSetFetchOptions());
+			}
+			
+			var fCheck = function(facade, dataSets) {
+				c.assertObjectsWithValues(dataSets, "code", [ "20130415093804724-403" ]);
+			}
+			
+			testSearch(c, fSearch, fCheck);
+		});
+		
+		QUnit.test("searchDataSets() withContainer", function(assert) {
+			var c = new common(assert, openbis);
+			
+			var fSearch = function(facade) {
+				var criteria = new c.DataSetSearchCriteria();
+				criteria.withContainer().withCode().thatEquals("20130412153119864-385");
+				return facade.searchDataSets(criteria, c.createDataSetFetchOptions());
+			}
+			
+			var fCheck = function(facade, dataSets) {
+				c.assertObjectsWithValues(dataSets, "code", [ "20130412153118625-384" ]);
+			}
+			
+			testSearch(c, fSearch, fCheck);
+		});
+		
 		QUnit.test("searchDataSets() withPhysicalData", function(assert) {
 			var c = new common(assert, openbis);
 
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/dataset/search/DataSetSearchCriteriaTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/dataset/search/DataSetSearchCriteriaTranslator.java
index 964619f35151c784cdf002d01f904c8435ec5d01..c122aa54ec99370c18a6d06500f8d05d5733559a 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/dataset/search/DataSetSearchCriteriaTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/dataset/search/DataSetSearchCriteriaTranslator.java
@@ -17,6 +17,7 @@
 package ch.ethz.sis.openbis.generic.server.asapi.v3.translator.dataset.search;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.ISearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.search.AbstractDataSetSearchCriteria;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.search.DataSetChildrenSearchCriteria;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.search.DataSetContainerSearchCriteria;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.search.DataSetParentsSearchCriteria;
@@ -44,7 +45,7 @@ public class DataSetSearchCriteriaTranslator extends AbstractCompositeSearchCrit
     @Override
     protected boolean doAccepts(ISearchCriteria criteria)
     {
-        return criteria instanceof DataSetSearchCriteria;
+        return criteria instanceof AbstractDataSetSearchCriteria;
     }
 
     @Override
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/sample/search/SampleSearchCriteriaTranslator.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/sample/search/SampleSearchCriteriaTranslator.java
index 72ca071e81d0b511b2ab696112d702129089ab6c..b723a7ae6481d14675f621f49593f906e6fd7480 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/sample/search/SampleSearchCriteriaTranslator.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/sample/search/SampleSearchCriteriaTranslator.java
@@ -17,6 +17,7 @@
 package ch.ethz.sis.openbis.generic.server.asapi.v3.translator.sample.search;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.ISearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.search.AbstractSampleSearchCriteria;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.search.NoSampleContainerSearchCriteria;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.search.NoSampleSearchCriteria;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.search.SampleChildrenSearchCriteria;
@@ -46,7 +47,7 @@ public class SampleSearchCriteriaTranslator extends AbstractCompositeSearchCrite
     @Override
     protected boolean doAccepts(ISearchCriteria criteria)
     {
-        return criteria instanceof SampleSearchCriteria
+        return criteria instanceof AbstractSampleSearchCriteria
                 || criteria instanceof NoSampleSearchCriteria;
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/dataset/search/DataSetSearchCriteria.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/dataset/search/DataSetSearchCriteria.js
index eb41574c67b99fcd997c84dd7d8beba3bc3fd85b..73a54d2e3da2290f2ff38eea3420fbcd2f43b322 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/dataset/search/DataSetSearchCriteria.js
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/dataset/search/DataSetSearchCriteria.js
@@ -5,12 +5,12 @@ define([ "require", "stjs", "as/dto/common/search/AbstractEntitySearchCriteria",
 		"as/dto/experiment/search/ExperimentSearchCriteria", "as/dto/experiment/search/NoExperimentSearchCriteria", "as/dto/sample/search/SampleSearchCriteria",
 		"as/dto/sample/search/NoSampleSearchCriteria", "as/dto/dataset/search/DataSetTypeSearchCriteria", "as/dto/dataset/search/PhysicalDataSearchCriteria",
 		"as/dto/dataset/search/LinkedDataSearchCriteria" ], function(require, stjs, AbstractEntitySearchCriteria, SearchOperator, DataSetSearchRelation) {
-	var DataSetSearchCriteria = function(relation) {
+	var AbstractDataSetSearchCriteria = function(relation) {
 		AbstractEntitySearchCriteria.call(this);
 		this.relation = relation ? relation : DataSetSearchRelation.DATASET;
 	};
-	stjs.extend(DataSetSearchCriteria, AbstractEntitySearchCriteria, [ AbstractEntitySearchCriteria ], function(constructor, prototype) {
-		prototype['@type'] = 'as.dto.dataset.search.DataSetSearchCriteria';
+	stjs.extend(AbstractDataSetSearchCriteria, AbstractEntitySearchCriteria, [ AbstractEntitySearchCriteria ], function(constructor, prototype) {
+		prototype['@type'] = 'as.dto.dataset.search.AbstractDataSetSearchCriteria';
 		constructor.serialVersionUID = 1;
 		prototype.relation = null;
 		prototype.withType = function() {
@@ -25,15 +25,6 @@ define([ "require", "stjs", "as/dto/common/search/AbstractEntitySearchCriteria",
 			var LinkedDataSearchCriteria = require("as/dto/dataset/search/LinkedDataSearchCriteria");
 			return this.addCriteria(new LinkedDataSearchCriteria());
 		};
-		prototype.withParents = function() {
-			return this.addCriteria(new DataSetParentsSearchCriteria());
-		};
-		prototype.withChildren = function() {
-			return this.addCriteria(new DataSetChildrenSearchCriteria());
-		};
-		prototype.withContainer = function() {
-			return this.addCriteria(new DataSetContainerSearchCriteria());
-		};
 		prototype.withExperiment = function() {
 			var ExperimentSearchCriteria = require("as/dto/experiment/search/ExperimentSearchCriteria");
 			return this.addCriteria(new ExperimentSearchCriteria());
@@ -76,10 +67,40 @@ define([ "require", "stjs", "as/dto/common/search/AbstractEntitySearchCriteria",
 		}
 	});
 
+	var DataSetSearchCriteria = function() {
+		AbstractDataSetSearchCriteria.call(this, DataSetSearchRelation.PARENTS);
+	};
+	stjs.extend(DataSetSearchCriteria, AbstractDataSetSearchCriteria, [ AbstractDataSetSearchCriteria ], function(constructor, prototype) {
+		prototype['@type'] = 'as.dto.dataset.search.DataSetSearchCriteria';
+		constructor.serialVersionUID = 1;
+		prototype.withParents = function() {
+			return this.addCriteria(new DataSetParentsSearchCriteria());
+		};
+		prototype.withChildren = function() {
+			return this.addCriteria(new DataSetChildrenSearchCriteria());
+		};
+		prototype.withContainer = function() {
+			return this.addCriteria(new DataSetContainerSearchCriteria());
+		};
+	}, {
+		relation : {
+			name : "Enum",
+			arguments : [ "DataSetSearchRelation" ]
+		},
+		operator : {
+			name : "Enum",
+			arguments : [ "SearchOperator" ]
+		},
+		criteria : {
+			name : "Collection",
+			arguments : [ "ISearchCriteria" ]
+		}
+	});
+	
 	var DataSetParentsSearchCriteria = function() {
-		DataSetSearchCriteria.call(this, DataSetSearchRelation.PARENTS);
+		AbstractDataSetSearchCriteria.call(this, DataSetSearchRelation.PARENTS);
 	};
-	stjs.extend(DataSetParentsSearchCriteria, DataSetSearchCriteria, [ DataSetSearchCriteria ], function(constructor, prototype) {
+	stjs.extend(DataSetParentsSearchCriteria, AbstractDataSetSearchCriteria, [ AbstractDataSetSearchCriteria ], function(constructor, prototype) {
 		prototype['@type'] = 'as.dto.dataset.search.DataSetParentsSearchCriteria';
 		constructor.serialVersionUID = 1;
 	}, {
@@ -98,9 +119,9 @@ define([ "require", "stjs", "as/dto/common/search/AbstractEntitySearchCriteria",
 	});
 
 	var DataSetChildrenSearchCriteria = function() {
-		DataSetSearchCriteria.call(this, DataSetSearchRelation.CHILDREN);
+		AbstractDataSetSearchCriteria.call(this, DataSetSearchRelation.CHILDREN);
 	};
-	stjs.extend(DataSetChildrenSearchCriteria, DataSetSearchCriteria, [ DataSetSearchCriteria ], function(constructor, prototype) {
+	stjs.extend(DataSetChildrenSearchCriteria, AbstractDataSetSearchCriteria, [ AbstractDataSetSearchCriteria ], function(constructor, prototype) {
 		prototype['@type'] = 'as.dto.dataset.search.DataSetChildrenSearchCriteria';
 		constructor.serialVersionUID = 1;
 	}, {
@@ -119,9 +140,9 @@ define([ "require", "stjs", "as/dto/common/search/AbstractEntitySearchCriteria",
 	});
 
 	var DataSetContainerSearchCriteria = function() {
-		DataSetSearchCriteria.call(this, DataSetSearchRelation.CONTAINER);
+		AbstractDataSetSearchCriteria.call(this, DataSetSearchRelation.CONTAINER);
 	};
-	stjs.extend(DataSetContainerSearchCriteria, DataSetSearchCriteria, [ DataSetSearchCriteria ], function(constructor, prototype) {
+	stjs.extend(DataSetContainerSearchCriteria, AbstractDataSetSearchCriteria, [ AbstractDataSetSearchCriteria ], function(constructor, prototype) {
 		prototype['@type'] = 'as.dto.dataset.search.DataSetContainerSearchCriteria';
 		constructor.serialVersionUID = 1;
 	}, {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/sample/search/SampleSearchCriteria.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/sample/search/SampleSearchCriteria.js
index 9b3bdedb21f55a9559ea5433a6de0a36655a63a6..1d622208a225ee5fe8617c639cc2dcc76d3b8e75 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/sample/search/SampleSearchCriteria.js
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/sample/search/SampleSearchCriteria.js
@@ -6,12 +6,12 @@ define([ "require", "stjs", "as/dto/common/search/AbstractEntitySearchCriteria",
 		"as/dto/experiment/search/NoExperimentSearchCriteria", "as/dto/sample/search/NoSampleContainerSearchCriteria", "as/dto/sample/search/SampleTypeSearchCriteria",
 		"as/dto/common/search/IdentifierSearchCriteria" ], function(require, stjs, AbstractEntitySearchCriteria, SearchOperator, SampleSearchRelation) {
 
-	var SampleSearchCriteria = function(relation) {
+	var AbstractSampleSearchCriteria = function(relation) {
 		AbstractEntitySearchCriteria.call(this);
 		this.relation = relation ? relation : SampleSearchRelation.SAMPLE;
 	};
-	stjs.extend(SampleSearchCriteria, AbstractEntitySearchCriteria, [ AbstractEntitySearchCriteria ], function(constructor, prototype) {
-		prototype['@type'] = 'as.dto.sample.search.SampleSearchCriteria';
+	stjs.extend(AbstractSampleSearchCriteria, AbstractEntitySearchCriteria, [ AbstractEntitySearchCriteria ], function(constructor, prototype) {
+		prototype['@type'] = 'as.dto.sample.search.AbstractSampleSearchCriteria';
 		constructor.serialVersionUID = 1;
 		prototype.relation = null;
 		prototype.withIdentifier = function() {
@@ -43,15 +43,6 @@ define([ "require", "stjs", "as/dto/common/search/AbstractEntitySearchCriteria",
 			this.addCriteria(new NoExperimentSearchCriteria());
 			return this;
 		};
-		prototype.withParents = function() {
-			return this.addCriteria(new SampleParentsSearchCriteria());
-		};
-		prototype.withChildren = function() {
-			return this.addCriteria(new SampleChildrenSearchCriteria());
-		};
-		prototype.withContainer = function() {
-			return this.addCriteria(new SampleContainerSearchCriteria());
-		};
 		prototype.withoutContainer = function() {
 			var NoSampleContainerSearchCriteria = require("as/dto/sample/search/NoSampleContainerSearchCriteria");
 			this.addCriteria(new NoSampleContainerSearchCriteria());
@@ -85,10 +76,40 @@ define([ "require", "stjs", "as/dto/common/search/AbstractEntitySearchCriteria",
 		}
 	});
 
+	var SampleSearchCriteria = function() {
+		AbstractSampleSearchCriteria.call(this, SampleSearchRelation.PARENTS);
+	};
+	stjs.extend(SampleSearchCriteria, AbstractSampleSearchCriteria, [ AbstractSampleSearchCriteria ], function(constructor, prototype) {
+		prototype['@type'] = 'as.dto.sample.search.SampleSearchCriteria';
+		constructor.serialVersionUID = 1;
+		prototype.withParents = function() {
+			return this.addCriteria(new SampleParentsSearchCriteria());
+		};
+		prototype.withChildren = function() {
+			return this.addCriteria(new SampleChildrenSearchCriteria());
+		};
+		prototype.withContainer = function() {
+			return this.addCriteria(new SampleContainerSearchCriteria());
+		};
+	}, {
+		relation : {
+			name : "Enum",
+			arguments : [ "SampleSearchRelation" ]
+		},
+		operator : {
+			name : "Enum",
+			arguments : [ "SearchOperator" ]
+		},
+		criteria : {
+			name : "Collection",
+			arguments : [ "ISearchCriteria" ]
+		}
+	});
+
 	var SampleParentsSearchCriteria = function() {
-		SampleSearchCriteria.call(this, SampleSearchRelation.PARENTS);
+		AbstractSampleSearchCriteria.call(this, SampleSearchRelation.PARENTS);
 	};
-	stjs.extend(SampleParentsSearchCriteria, SampleSearchCriteria, [ SampleSearchCriteria ], function(constructor, prototype) {
+	stjs.extend(SampleParentsSearchCriteria, AbstractSampleSearchCriteria, [ AbstractSampleSearchCriteria ], function(constructor, prototype) {
 		prototype['@type'] = 'as.dto.sample.search.SampleParentsSearchCriteria';
 		constructor.serialVersionUID = 1;
 	}, {
@@ -105,11 +126,11 @@ define([ "require", "stjs", "as/dto/common/search/AbstractEntitySearchCriteria",
 			arguments : [ "ISearchCriteria" ]
 		}
 	});
-
+	
 	var SampleChildrenSearchCriteria = function() {
-		SampleSearchCriteria.call(this, SampleSearchRelation.CHILDREN);
+		AbstractSampleSearchCriteria.call(this, SampleSearchRelation.CHILDREN);
 	};
-	stjs.extend(SampleChildrenSearchCriteria, SampleSearchCriteria, [ SampleSearchCriteria ], function(constructor, prototype) {
+	stjs.extend(SampleChildrenSearchCriteria, AbstractSampleSearchCriteria, [ AbstractSampleSearchCriteria ], function(constructor, prototype) {
 		prototype['@type'] = 'as.dto.sample.search.SampleChildrenSearchCriteria';
 		constructor.serialVersionUID = 1;
 	}, {
@@ -128,9 +149,9 @@ define([ "require", "stjs", "as/dto/common/search/AbstractEntitySearchCriteria",
 	});
 
 	var SampleContainerSearchCriteria = function() {
-		SampleSearchCriteria.call(this, SampleSearchRelation.CONTAINER);
+		AbstractSampleSearchCriteria.call(this, SampleSearchRelation.CONTAINER);
 	};
-	stjs.extend(SampleContainerSearchCriteria, SampleSearchCriteria, [ SampleSearchCriteria ], function(constructor, prototype) {
+	stjs.extend(SampleContainerSearchCriteria, AbstractSampleSearchCriteria, [ AbstractSampleSearchCriteria ], function(constructor, prototype) {
 		prototype['@type'] = 'as.dto.sample.search.SampleContainerSearchCriteria';
 		constructor.serialVersionUID = 1;
 	}, {
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/search/SampleSearchCriteriaTranslatorTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/search/SampleSearchCriteriaTranslatorTest.java
index c2a9ec832dc3521e7b87ec37e7398804863f1ac6..a59ec066d9b3c4692c97db26f0c2ba8dbbed02bd 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/search/SampleSearchCriteriaTranslatorTest.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/generic/server/asapi/v3/translator/search/SampleSearchCriteriaTranslatorTest.java
@@ -150,24 +150,6 @@ public class SampleSearchCriteriaTranslatorTest extends AbstractSearchCriteriaTr
         translateAndAssertEqual(v1Criteria, v3Criteria);
     }
 
-    @Test
-    public void testWithParentsWithParents()
-    {
-        SearchCriteria subSubCriteria = new SearchCriteria();
-        subSubCriteria.addMatchClause(MatchClause.createAttributeMatch(MatchClauseAttribute.CODE, "parentCode"));
-
-        SearchCriteria subCriteria = new SearchCriteria();
-        subCriteria.addSubCriteria(SearchSubCriteria.createSampleParentCriteria(subSubCriteria));
-
-        SearchCriteria v1Criteria = new SearchCriteria();
-        v1Criteria.addSubCriteria(SearchSubCriteria.createSampleParentCriteria(subCriteria));
-
-        SampleSearchCriteria v3Criteria = new SampleSearchCriteria();
-        v3Criteria.withParents().withParents().withCode().thatEquals("parentCode");
-
-        translateAndAssertEqual(v1Criteria, v3Criteria);
-    }
-
     @Test
     public void testWithChildren()
     {
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/search/AbstractDataSetSearchCriteria.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/search/AbstractDataSetSearchCriteria.java
new file mode 100644
index 0000000000000000000000000000000000000000..d4d91c5c9483fda0bb1fdd620136c6283fdd3577
--- /dev/null
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/search/AbstractDataSetSearchCriteria.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2014 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.ethz.sis.openbis.generic.asapi.v3.dto.dataset.search;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.AbstractEntitySearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchCriteriaToStringBuilder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchOperator;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.search.ExperimentSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.search.NoExperimentSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.search.NoSampleSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.search.SampleSearchCriteria;
+import ch.systemsx.cisd.base.annotation.JsonObject;
+
+/**
+ * @author pkupczyk
+ */
+@JsonObject("as.dto.dataset.search.AbstractDataSetSearchCriteria")
+public class AbstractDataSetSearchCriteria<T extends AbstractDataSetSearchCriteria<T>> extends AbstractEntitySearchCriteria<IDataSetId>
+{
+
+    private static final long serialVersionUID = 1L;
+
+    private DataSetSearchRelation relation;
+
+    AbstractDataSetSearchCriteria(DataSetSearchRelation relation)
+    {
+        this.relation = relation;
+    }
+
+    public DataSetTypeSearchCriteria withType()
+    {
+        return with(new DataSetTypeSearchCriteria());
+    }
+
+    public PhysicalDataSearchCriteria withPhysicalData()
+    {
+        return with(new PhysicalDataSearchCriteria());
+    }
+
+    public LinkedDataSearchCriteria withLinkedData()
+    {
+        return with(new LinkedDataSearchCriteria());
+    }
+
+    public ExperimentSearchCriteria withExperiment()
+    {
+        return with(new ExperimentSearchCriteria());
+    }
+
+    @SuppressWarnings("unchecked")
+    public T withoutExperiment()
+    {
+        with(new NoExperimentSearchCriteria());
+        return (T) this;
+    }
+
+    public SampleSearchCriteria withSample()
+    {
+        return with(new SampleSearchCriteria());
+    }
+
+    @SuppressWarnings("unchecked")
+    public T withoutSample()
+    {
+        with(new NoSampleSearchCriteria());
+        return (T) this;
+    }
+
+    @SuppressWarnings("unchecked")
+    public T withOrOperator()
+    {
+        return (T) withOperator(SearchOperator.OR);
+    }
+
+    @SuppressWarnings("unchecked")
+    public T withAndOperator()
+    {
+        return (T) withOperator(SearchOperator.AND);
+    }
+
+    public DataSetSearchRelation getRelation()
+    {
+        return relation;
+    }
+
+    @Override
+    protected SearchCriteriaToStringBuilder createBuilder()
+    {
+        SearchCriteriaToStringBuilder builder = super.createBuilder();
+        builder.setName(relation.name());
+        return builder;
+    }
+
+}
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/search/DataSetChildrenSearchCriteria.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/search/DataSetChildrenSearchCriteria.java
index 6150d251dab7808b2d816883ddf2410e6e470aee..f10d2dc9bb5cc79dad2aed8e234a02a0c8104733 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/search/DataSetChildrenSearchCriteria.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/search/DataSetChildrenSearchCriteria.java
@@ -22,7 +22,7 @@ import ch.systemsx.cisd.base.annotation.JsonObject;
  * @author Jakub Straszewski
  */
 @JsonObject("as.dto.dataset.search.DataSetChildrenSearchCriteria")
-public class DataSetChildrenSearchCriteria extends DataSetSearchCriteria
+public class DataSetChildrenSearchCriteria extends AbstractDataSetSearchCriteria<DataSetChildrenSearchCriteria>
 {
     private static final long serialVersionUID = 1L;
 
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/search/DataSetContainerSearchCriteria.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/search/DataSetContainerSearchCriteria.java
index fb9eda2c90df39f9b43432f4324c49448a01ebfa..4a2e7b23817bc6ebbc8c9042b8c5857f2872df79 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/search/DataSetContainerSearchCriteria.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/search/DataSetContainerSearchCriteria.java
@@ -22,7 +22,7 @@ import ch.systemsx.cisd.base.annotation.JsonObject;
  * @author Jakub Straszewski
  */
 @JsonObject("as.dto.dataset.search.DataSetContainerSearchCriteria")
-public class DataSetContainerSearchCriteria extends DataSetSearchCriteria
+public class DataSetContainerSearchCriteria extends AbstractDataSetSearchCriteria<DataSetContainerSearchCriteria>
 {
     private static final long serialVersionUID = 1L;
 
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/search/DataSetParentsSearchCriteria.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/search/DataSetParentsSearchCriteria.java
index d4203f40dc50c3945a96337ad09d5f294fd25978..a5b0c80e1e97e0c0219d3b79c63caad82b364d02 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/search/DataSetParentsSearchCriteria.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/search/DataSetParentsSearchCriteria.java
@@ -22,7 +22,7 @@ import ch.systemsx.cisd.base.annotation.JsonObject;
  * @author Jakub Straszewski
  */
 @JsonObject("as.dto.dataset.search.DataSetParentsSearchCriteria")
-public class DataSetParentsSearchCriteria extends DataSetSearchCriteria
+public class DataSetParentsSearchCriteria extends AbstractDataSetSearchCriteria<DataSetParentsSearchCriteria>
 {
     private static final long serialVersionUID = 1L;
 
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/search/DataSetSearchCriteria.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/search/DataSetSearchCriteria.java
index 1f01f28a57aeb1be5d05e4713d920eba567828da..5e50b5973bff0bf05f5a4e8c8ec25157f10c05a8 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/search/DataSetSearchCriteria.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/search/DataSetSearchCriteria.java
@@ -16,110 +16,35 @@
 
 package ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.search;
 
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.AbstractEntitySearchCriteria;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchCriteriaToStringBuilder;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchOperator;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.search.ExperimentSearchCriteria;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.search.NoExperimentSearchCriteria;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.search.NoSampleSearchCriteria;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.search.SampleSearchCriteria;
 import ch.systemsx.cisd.base.annotation.JsonObject;
 
 /**
  * @author pkupczyk
  */
 @JsonObject("as.dto.dataset.search.DataSetSearchCriteria")
-public class DataSetSearchCriteria extends AbstractEntitySearchCriteria<IDataSetId>
+public class DataSetSearchCriteria extends AbstractDataSetSearchCriteria<DataSetSearchCriteria>
 {
 
     private static final long serialVersionUID = 1L;
 
-    private DataSetSearchRelation relation;
-
     public DataSetSearchCriteria()
     {
-        this(DataSetSearchRelation.DATASET);
-    }
-
-    DataSetSearchCriteria(DataSetSearchRelation relation)
-    {
-        this.relation = relation;
-    }
-
-    public DataSetTypeSearchCriteria withType()
-    {
-        return with(new DataSetTypeSearchCriteria());
-    }
-
-    public PhysicalDataSearchCriteria withPhysicalData()
-    {
-        return with(new PhysicalDataSearchCriteria());
+        super(DataSetSearchRelation.DATASET);
     }
 
-    public LinkedDataSearchCriteria withLinkedData()
-    {
-        return with(new LinkedDataSearchCriteria());
-    }
-
-    public DataSetSearchCriteria withParents()
+    public DataSetParentsSearchCriteria withParents()
     {
         return with(new DataSetParentsSearchCriteria());
     }
 
-    public DataSetSearchCriteria withChildren()
+    public DataSetChildrenSearchCriteria withChildren()
     {
         return with(new DataSetChildrenSearchCriteria());
     }
 
-    public DataSetSearchCriteria withContainer()
+    public DataSetContainerSearchCriteria withContainer()
     {
         return with(new DataSetContainerSearchCriteria());
     }
 
-    public ExperimentSearchCriteria withExperiment()
-    {
-        return with(new ExperimentSearchCriteria());
-    }
-
-    public DataSetSearchCriteria withoutExperiment()
-    {
-        with(new NoExperimentSearchCriteria());
-        return this;
-    }
-
-    public SampleSearchCriteria withSample()
-    {
-        return with(new SampleSearchCriteria());
-    }
-
-    public DataSetSearchCriteria withoutSample()
-    {
-        with(new NoSampleSearchCriteria());
-        return this;
-    }
-
-    public DataSetSearchCriteria withOrOperator()
-    {
-        return (DataSetSearchCriteria) withOperator(SearchOperator.OR);
-    }
-
-    public DataSetSearchCriteria withAndOperator()
-    {
-        return (DataSetSearchCriteria) withOperator(SearchOperator.AND);
-    }
-
-    public DataSetSearchRelation getRelation()
-    {
-        return relation;
-    }
-
-    @Override
-    protected SearchCriteriaToStringBuilder createBuilder()
-    {
-        SearchCriteriaToStringBuilder builder = super.createBuilder();
-        builder.setName(relation.name());
-        return builder;
-    }
-
 }
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/search/AbstractSampleSearchCriteria.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/search/AbstractSampleSearchCriteria.java
new file mode 100644
index 0000000000000000000000000000000000000000..6ceebabf8c4ff6f6474d51496b2f210ce68d9194
--- /dev/null
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/search/AbstractSampleSearchCriteria.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2019 ETH Zuerich, SIS
+ *
+ * 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.ethz.sis.openbis.generic.asapi.v3.dto.sample.search;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.AbstractEntitySearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.IdentifierSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchCriteriaToStringBuilder;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchOperator;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.search.ExperimentSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.search.NoExperimentSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.search.NoProjectSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.search.ProjectSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.ISampleId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.search.NoSpaceSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.search.SpaceSearchCriteria;
+import ch.systemsx.cisd.base.annotation.JsonObject;
+
+/**
+ * @author Franz-Josef Elmer
+ *
+ */
+@JsonObject("as.dto.sample.search.AbstractSampleSearchCriteria")
+public abstract class AbstractSampleSearchCriteria<T extends AbstractSampleSearchCriteria<T>> extends AbstractEntitySearchCriteria<ISampleId>
+{
+
+    private static final long serialVersionUID = 1L;
+
+    private SampleSearchRelation relation;
+
+    AbstractSampleSearchCriteria(SampleSearchRelation relation)
+    {
+        this.relation = relation;
+    }
+
+    public IdentifierSearchCriteria withIdentifier()
+    {
+        return with(new IdentifierSearchCriteria());
+    }
+
+    public SpaceSearchCriteria withSpace()
+    {
+        return with(new SpaceSearchCriteria());
+    }
+
+    @SuppressWarnings("unchecked")
+    public T withoutSpace()
+    {
+        with(new NoSpaceSearchCriteria());
+        return (T) this;
+    }
+    
+    public ProjectSearchCriteria withProject()
+    {
+        return with(new ProjectSearchCriteria());
+    }
+
+    @SuppressWarnings("unchecked")
+    public T withoutProject()
+    {
+        with(new NoProjectSearchCriteria());
+        return (T) this;
+    }
+
+    public ExperimentSearchCriteria withExperiment()
+    {
+        return with(new ExperimentSearchCriteria());
+    }
+
+    @SuppressWarnings("unchecked")
+    public T withoutExperiment()
+    {
+        with(new NoExperimentSearchCriteria());
+        return (T) this;
+    }
+
+    @SuppressWarnings("unchecked")
+    public T withoutContainer()
+    {
+        with(new NoSampleContainerSearchCriteria());
+        return (T) this;
+    }
+
+    public SampleTypeSearchCriteria withType()
+    {
+        return with(new SampleTypeSearchCriteria());
+    }
+
+    public SampleSearchCriteria withOrOperator()
+    {
+        return (SampleSearchCriteria) withOperator(SearchOperator.OR);
+    }
+
+    public SampleSearchCriteria withAndOperator()
+    {
+        return (SampleSearchCriteria) withOperator(SearchOperator.AND);
+    }
+
+    public SampleSearchRelation getRelation()
+    {
+        return relation;
+    }
+
+    @Override
+    protected SearchCriteriaToStringBuilder createBuilder()
+    {
+        SearchCriteriaToStringBuilder builder = super.createBuilder();
+        builder.setName(relation.name());
+        return builder;
+    }
+
+}
\ No newline at end of file
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/search/SampleChildrenSearchCriteria.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/search/SampleChildrenSearchCriteria.java
index 07e991c4aa026a7ecb5c23c80cb28b2f38d71528..4c7d5ff735d98fd84d5c116a129a4570a52e2331 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/search/SampleChildrenSearchCriteria.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/search/SampleChildrenSearchCriteria.java
@@ -22,7 +22,7 @@ import ch.systemsx.cisd.base.annotation.JsonObject;
  * @author pkupczyk
  */
 @JsonObject("as.dto.sample.search.SampleChildrenSearchCriteria")
-public class SampleChildrenSearchCriteria extends SampleSearchCriteria
+public class SampleChildrenSearchCriteria extends AbstractSampleSearchCriteria<SampleChildrenSearchCriteria>
 {
 
     private static final long serialVersionUID = 1L;
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/search/SampleContainerSearchCriteria.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/search/SampleContainerSearchCriteria.java
index b3177043ebf75706d68986220b9dc2d99d406d08..e9dde6411ad59ac346df29bea3d1efe15464014b 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/search/SampleContainerSearchCriteria.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/search/SampleContainerSearchCriteria.java
@@ -22,7 +22,7 @@ import ch.systemsx.cisd.base.annotation.JsonObject;
  * @author pkupczyk
  */
 @JsonObject("as.dto.sample.search.SampleContainerSearchCriteria")
-public class SampleContainerSearchCriteria extends SampleSearchCriteria
+public class SampleContainerSearchCriteria extends AbstractSampleSearchCriteria<SampleContainerSearchCriteria>
 {
 
     private static final long serialVersionUID = 1L;
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/search/SampleParentsSearchCriteria.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/search/SampleParentsSearchCriteria.java
index 8ff43ed07f92161d5ed6d875c332d2bba8153241..227e3d3157fefad4944ffd4936f99990391f5994 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/search/SampleParentsSearchCriteria.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/search/SampleParentsSearchCriteria.java
@@ -22,7 +22,7 @@ import ch.systemsx.cisd.base.annotation.JsonObject;
  * @author pkupczyk
  */
 @JsonObject("as.dto.sample.search.SampleParentsSearchCriteria")
-public class SampleParentsSearchCriteria extends SampleSearchCriteria
+public class SampleParentsSearchCriteria extends AbstractSampleSearchCriteria<SampleParentsSearchCriteria>
 {
 
     private static final long serialVersionUID = 1L;
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/search/SampleSearchCriteria.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/search/SampleSearchCriteria.java
index f6c47aee0011ec2603d08505dba5d9a20ca8552d..fe76a7d761efd310e8bbc5048c88e080a3750a6d 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/search/SampleSearchCriteria.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/search/SampleSearchCriteria.java
@@ -16,76 +16,20 @@
 
 package ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.search;
 
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.AbstractEntitySearchCriteria;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.IdentifierSearchCriteria;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchCriteriaToStringBuilder;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchOperator;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.search.ExperimentSearchCriteria;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.search.NoExperimentSearchCriteria;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.search.NoProjectSearchCriteria;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.search.ProjectSearchCriteria;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.ISampleId;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.search.NoSpaceSearchCriteria;
-import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.search.SpaceSearchCriteria;
 import ch.systemsx.cisd.base.annotation.JsonObject;
 
 /**
  * @author pkupczyk
  */
 @JsonObject("as.dto.sample.search.SampleSearchCriteria")
-public class SampleSearchCriteria extends AbstractEntitySearchCriteria<ISampleId>
+public class SampleSearchCriteria extends AbstractSampleSearchCriteria<SampleSearchCriteria>
 {
 
     private static final long serialVersionUID = 1L;
 
-    private SampleSearchRelation relation;
-
     public SampleSearchCriteria()
     {
-        this(SampleSearchRelation.SAMPLE);
-    }
-
-    SampleSearchCriteria(SampleSearchRelation relation)
-    {
-        this.relation = relation;
-    }
-
-    public IdentifierSearchCriteria withIdentifier()
-    {
-        return with(new IdentifierSearchCriteria());
-    }
-
-    public SpaceSearchCriteria withSpace()
-    {
-        return with(new SpaceSearchCriteria());
-    }
-
-    public SampleSearchCriteria withoutSpace()
-    {
-        with(new NoSpaceSearchCriteria());
-        return this;
-    }
-    
-    public ProjectSearchCriteria withProject()
-    {
-        return with(new ProjectSearchCriteria());
-    }
-
-    public SampleSearchCriteria withoutProject()
-    {
-        with(new NoProjectSearchCriteria());
-        return this;
-    }
-
-    public ExperimentSearchCriteria withExperiment()
-    {
-        return with(new ExperimentSearchCriteria());
-    }
-
-    public SampleSearchCriteria withoutExperiment()
-    {
-        with(new NoExperimentSearchCriteria());
-        return this;
+        super(SampleSearchRelation.SAMPLE);
     }
 
     public SampleParentsSearchCriteria withParents()
@@ -103,38 +47,4 @@ public class SampleSearchCriteria extends AbstractEntitySearchCriteria<ISampleId
         return with(new SampleContainerSearchCriteria());
     }
 
-    public SampleSearchCriteria withoutContainer()
-    {
-        with(new NoSampleContainerSearchCriteria());
-        return this;
-    }
-
-    public SampleTypeSearchCriteria withType()
-    {
-        return with(new SampleTypeSearchCriteria());
-    }
-
-    public SampleSearchCriteria withOrOperator()
-    {
-        return (SampleSearchCriteria) withOperator(SearchOperator.OR);
-    }
-
-    public SampleSearchCriteria withAndOperator()
-    {
-        return (SampleSearchCriteria) withOperator(SearchOperator.AND);
-    }
-
-    public SampleSearchRelation getRelation()
-    {
-        return relation;
-    }
-
-    @Override
-    protected SearchCriteriaToStringBuilder createBuilder()
-    {
-        SearchCriteriaToStringBuilder builder = super.createBuilder();
-        builder.setName(relation.name());
-        return builder;
-    }
-
 }
diff --git a/openbis_api/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt b/openbis_api/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt
index 61d7eb8ca6ba6556ed974cdfd10c46239280af2f..002d2d0c0b66fe9f7f02de0a45830a6ba9447794 100644
--- a/openbis_api/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt
+++ b/openbis_api/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt
@@ -110,6 +110,7 @@ DataSetKind
 DataSetParentsSearchCriteria
 DataSetPermId
 DataSetRelationType
+AbstractDataSetSearchCriteria
 DataSetSearchCriteria
 DataSetSearchRelation
 DataSetSortOptions
@@ -567,6 +568,7 @@ SampleIdentifier
 SampleParentsSearchCriteria
 SamplePermId
 SampleRelationType
+Abstract Sample Search Criteria
 SampleSearchCriteria
 SampleSearchRelation
 SampleSortOptions
diff --git a/openbis_ng_ui/.babelrc b/openbis_ng_ui/.babelrc
index ec66626b190f5a2ab25c7d3577fb2304a1666247..7683f4458cdc954baa9ef62e6891fdd95821cc54 100644
--- a/openbis_ng_ui/.babelrc
+++ b/openbis_ng_ui/.babelrc
@@ -1,4 +1,4 @@
 {
-    "presets":["env", "react"],
-    "plugins": ["transform-class-properties", "transform-object-rest-spread"]
+    "presets":["@babel/preset-env", "@babel/preset-react"],
+    "plugins": ["@babel/plugin-transform-runtime", "@babel/plugin-proposal-object-rest-spread", "@babel/plugin-proposal-class-properties"]
 }
diff --git a/openbis_ng_ui/package.json b/openbis_ng_ui/package.json
index 98462b29405c200954202ff26807f7ddb2f8d23a..e204e134575ceea425bdda57d961536dc6f3bb44 100644
--- a/openbis_ng_ui/package.json
+++ b/openbis_ng_ui/package.json
@@ -14,7 +14,7 @@
     "react-dnd": "^7.4.5",
     "react-dnd-html5-backend": "^7.4.4",
     "react-dom": "^16.8.6",
-    "react-redux": "^7.0.2",
+    "react-redux": "^7.0.3",
     "redux": "^4.0.1",
     "redux-saga": "^1.0.2",
     "reselect": "^4.0.0",
@@ -22,14 +22,15 @@
   },
   "devDependencies": {
     "auto-bind": "^2.1.0",
-    "babel-core": "^6.26.3",
-    "babel-eslint": "^10.0.1",
+    "@babel/core": "^7.4.4",
+    "@babel/preset-env": "^7.4.4",
+    "@babel/preset-react": "^7.0.0",
+    "@babel/plugin-transform-runtime": "^7.4.4",
+    "@babel/plugin-proposal-object-rest-spread": "^7.4.4",
+    "@babel/plugin-proposal-class-properties": "^7.4.4",
     "babel-jest": "^24.7.1",
     "babel-loader": "^8.0.5",
-    "babel-plugin-transform-class-properties": "^6.24.1",
-    "babel-plugin-transform-object-rest-spread": "^6.26.0",
-    "babel-preset-env": "^1.7.0",
-    "babel-preset-react": "^6.24.1",
+    "babel-eslint": "^10.0.1",
     "css-loader": "^2.1.1",
     "enzyme": "^3.9.0",
     "enzyme-adapter-react-16": "^1.12.1",
@@ -37,14 +38,14 @@
     "eslint-config-standard": "^12.0.0",
     "eslint-plugin-import": "^2.17.2",
     "eslint-plugin-jest": "^22.5.1",
-    "eslint-plugin-node": "^8.0.1",
+    "eslint-plugin-node": "^9.0.0",
     "eslint-plugin-promise": "^4.1.1",
-    "eslint-plugin-react": "^7.12.4",
+    "eslint-plugin-react": "^7.13.0",
     "eslint-plugin-standard": "^4.0.0",
     "file-loader": "^3.0.1",
     "html-webpack-plugin": "^3.2.0",
     "jest": "^24.7.1",
-    "jest-junit": "^6.0.1",
+    "jest-junit": "^6.4.0",
     "raw-loader": "^2.0.0",
     "react-hot-loader": "^4.8.4",
     "react-loader": "^2.4.5",
@@ -69,6 +70,8 @@
       "default",
       "jest-junit"
     ],
-    "setupTestFrameworkScriptFile": "<rootDir>srcTest/setupTests.js"
+    "setupFilesAfterEnv": [
+      "<rootDir>srcTest/setupTests.js"
+    ]
   }
 }
diff --git a/openbis_ng_ui/src/store/reducers/ui/pages/common/browser.js b/openbis_ng_ui/src/store/reducers/ui/pages/common/browser.js
index 56dfe80e0e0a874f72a294bb924dd6d495577ac7..1fa5e8ba9545d2be4cf44c837320f851398b70da 100644
--- a/openbis_ng_ui/src/store/reducers/ui/pages/common/browser.js
+++ b/openbis_ng_ui/src/store/reducers/ui/pages/common/browser.js
@@ -3,7 +3,6 @@ import { combineReducers } from 'redux'
 import * as actions from '../../../../actions/actions.js'
 
 export const browser = combineReducers({
-  initialized,
   filter,
   nodes,
   selectedNodes,
@@ -11,19 +10,6 @@ export const browser = combineReducers({
   expandedNodes
 })
 
-function initialized(state = false, action){
-  switch(action.type){
-    case actions.BROWSER_SET_INITIALIZED:
-      if(_.isEqual(state, action.payload.initialized)){
-        return state
-      }else{
-        return action.payload.initialized
-      }
-    default:
-      return state
-  }
-}
-
 function filter(state = '', action){
   switch(action.type){
     case actions.BROWSER_SET_FILTER:
diff --git a/openbis_ng_ui/src/store/reducers/ui/ui.js b/openbis_ng_ui/src/store/reducers/ui/ui.js
index f4f13604ef0aa95ff4544083903302648d728e70..2bd477d709ed98da004dfed8053c75604f432a50 100644
--- a/openbis_ng_ui/src/store/reducers/ui/ui.js
+++ b/openbis_ng_ui/src/store/reducers/ui/ui.js
@@ -3,22 +3,12 @@ import * as actions from '../../actions/actions.js'
 import pages from './pages/pages.js'
 
 export default combineReducers({
-  initialized,
   loading,
   currentPage,
   pages,
   error
 })
 
-function initialized(state = false, action){
-  switch(action.type){
-    case actions.SET_INITIALIZED:
-      return action.payload.initialized
-    default:
-      return state
-  }
-}
-
 function loading(state = false, action){
   switch (action.type) {
     case actions.SET_LOADING: {
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataSetForm/widgets/JupyterNotebookController.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataSetForm/widgets/JupyterNotebookController.js
index add4c3941a167d32495236bacd89f66d35d325e3..250c6baabb6be27cb06373947bbf09024b7c8007 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataSetForm/widgets/JupyterNotebookController.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataSetForm/widgets/JupyterNotebookController.js
@@ -26,4 +26,10 @@ function JupyterNotebookController(entity) {
 		JupyterUtil.createJupyterNotebookAndOpen(workspace, notebook, datasets, notebookOwner);
 		Util.unblockUI();
 	}
+	
+	this.createAndSave = function(fileName, datasets, notebookOwner) {
+		var jnb = JSON.stringify(JupyterUtil.createJupyterNotebookContent(datasets, notebookOwner, fileName));
+		Util.downloadTextFile(jnb, fileName);
+		Util.unblockUI();
+	}
 }
\ No newline at end of file
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataSetForm/widgets/JupyterNotebookView.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataSetForm/widgets/JupyterNotebookView.js
index 04528ecf45c51d7b1d0232de8d23f89c8bd5b74e..fe8f372a87e94a47f903dd9084eefddf56f6b8e0 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataSetForm/widgets/JupyterNotebookView.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataSetForm/widgets/JupyterNotebookView.js
@@ -19,13 +19,32 @@ function JupyterNotebookView(jupyterNotebookController, jupyterNotebookModel) {
 	this._jupyterNotebookModel = jupyterNotebookModel;
 	
 	this.repaint = function() {
-		var _this = this;
-		var entity = this._jupyterNotebookModel.entity;
-		
 		var $window = $('<form>', { 'action' : 'javascript:void(0);' });
-		
 		$window.append($('<legend>').append("Create Jupyter Notebook"));
-		
+		var $btns = $('<div>', {'id' : 'jnb_buttons'});
+		$window.append($btns);
+		var $btnOpen = $('<div>', { 'class' : 'btn btn-default', 'text' : 'For immediate use', 'id' : 'open_jnb' });
+		$btnOpen.click(["open", $window, this], this._handle);
+		var $btnSave = $('<div>', { 'class' : 'btn btn-default', 'text' : 'For later use', 'id' : 'save_jnb' });
+		$btnSave.click(["save", $window, this], this._handle);
+		$btns.append($btnOpen).append('&nbsp;').append($btnSave);
+		var css = {
+				'text-align' : 'left',
+				'top' : '15%',
+				'width' : '70%',
+				'left' : '15%',
+				'right' : '20%',
+				'overflow' : 'hidden'
+		};
+		Util.blockUI($window, css);
+	};
+	
+	this._handle = function(event) {
+		var actionType = event.data[0];
+		var $window = event.data[1];
+		var _this = event.data[2];
+		var entity = _this._jupyterNotebookModel.entity;
+		$("#jnb_buttons").hide();
 		var $datasetsContainer = $("<div>", { style : "width: 100%;" });
 		$window.append(FormUtil.getInfoText("Please enter the names/codes of the datasets you want to download, or the names/codes of the experiments/objects which contain those datasets. "));
 		$window.append(FormUtil.getFieldForComponentWithLabel($datasetsContainer, "Datasets"));
@@ -85,35 +104,30 @@ function JupyterNotebookView(jupyterNotebookController, jupyterNotebookModel) {
 			}
 		}
 		
-		
-		var $workspace = FormUtil._getInputField('text', null, 'directory Name', null, true);
+		var buttonLabel = "Accept & Download";
+		if (actionType === 'open') {
+			var $workspace = FormUtil._getInputField('text', null, 'directory Name', null, true);
+			$window.append(FormUtil.getFieldForComponentWithLabel($workspace, "Directory Name"));
+			buttonLabel = "Accept & Open";
+		}
 		var $notebookName = FormUtil._getInputField('text', null, 'notebook Name', null, true);
-		$window.append(FormUtil.getFieldForComponentWithLabel($workspace, "Directory Name"));
 		$window.append(FormUtil.getFieldForComponentWithLabel($notebookName, "Notebook Name"));
 		
-		var $btnAccept = $('<input>', { 'type': 'submit', 'class' : 'btn btn-primary', 'value' : 'Accept' });
+		var $btnAccept = $('<input>', { 'type': 'submit', 'class' : 'btn btn-primary', 'value' : buttonLabel });
 		$window.submit(function() {
 			var selectedDatasets = datasetsSearchDropdown.getSelected();
 			var selectedOwner = ownerSearchDropdown.getSelected();
 			var notebookOwner = selectedOwner[0];
-			_this._jupyterNotebookController.create($workspace.val(), $notebookName.val(), selectedDatasets, notebookOwner);
+			if (actionType === 'open') {
+				_this._jupyterNotebookController.create($workspace.val(), $notebookName.val(), selectedDatasets, notebookOwner);
+			} else {
+				_this._jupyterNotebookController.createAndSave($notebookName.val() + ".ipynb", selectedDatasets, notebookOwner);
+			}
 		});
 		var $btnCancel = $('<a>', { 'class' : 'btn btn-default' }).append('Cancel');
 		$btnCancel.click(function() {
 			Util.unblockUI();
 		});
-		
 		$window.append($btnAccept).append('&nbsp;').append($btnCancel);
-		
-		var css = {
-				'text-align' : 'left',
-				'top' : '15%',
-				'width' : '70%',
-				'left' : '15%',
-				'right' : '20%',
-				'overflow' : 'hidden'
-		};
-		
-		Util.blockUI($window, css);
 	}
 }
\ No newline at end of file