diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/SearchCriteriaToDetailedSearchCriteriaTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/SearchCriteriaToDetailedSearchCriteriaTranslator.java
index e045d0c293517b68c75835c550e1339159cf5bc3..7a3c5e085767758928c4ca0fea781c6a32b2496c 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/SearchCriteriaToDetailedSearchCriteriaTranslator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/SearchCriteriaToDetailedSearchCriteriaTranslator.java
@@ -322,10 +322,10 @@ public class SearchCriteriaToDetailedSearchCriteriaTranslator
                     t = CompareType.EQUALS;
                     break;
                 case LESS_THAN:
-                    t = CompareType.LESS_THAN;
+                    t = CompareType.LESS_THAN_OR_EQUAL;
                     break;
                 case MORE_THAN:
-                    t = CompareType.MORE_THAN;
+                    t = CompareType.MORE_THAN_OR_EQUAL;
                     break;
                 default:
                     throw new IllegalArgumentException("" + matchClause.getCompareMode());
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/detailed/DetailedQueryBuilder.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/detailed/DetailedQueryBuilder.java
index 35570474182fe7dd365b0115291248a446b1da0d..9dca1e685c68a99d4c4a5e40b8cc3288fd789531 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/detailed/DetailedQueryBuilder.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/detailed/DetailedQueryBuilder.java
@@ -105,20 +105,20 @@ public class DetailedQueryBuilder
                 resultQuery.add(luceneQuery, occureCondition);
             } else
             {
-                Date lower = criterion.getDate();
                 Calendar c = Calendar.getInstance();
-                c.setTime(lower);
+                c.setTime(criterion.getDate());
                 c.add(Calendar.DAY_OF_MONTH, 1);
-                Date upper = c.getTime();
+                Date upper, lower;
+                upper = lower = c.getTime();
 
                 switch (criterion.getType())
                 {
                     case EQUALS:
                         break;
-                    case LESS_THAN:
+                    case LESS_THAN_OR_EQUAL:
                         lower = new Date(0);
                         break;
-                    case MORE_THAN:
+                    case MORE_THAN_OR_EQUAL:
                         upper = new Date(Long.MAX_VALUE);
                         break;
                 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/CompareType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/CompareType.java
index 64d4192abaf9a467d20da167aae5fea217316e81..0a4822ede29c32699d41e1380a787792e6d59b73 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/CompareType.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/CompareType.java
@@ -18,5 +18,5 @@ package ch.systemsx.cisd.openbis.generic.shared.basic.dto;
 
 public enum CompareType
 {
-    LESS_THAN, EQUALS, MORE_THAN
+    LESS_THAN_OR_EQUAL, EQUALS, MORE_THAN_OR_EQUAL
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/remoteapitest/api/v1/GeneralInformationServiceJsonApiTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/remoteapitest/api/v1/GeneralInformationServiceJsonApiTest.java
index 643b248df00d4e2e3584c70ed78d5ad03ccd85c8..a087ca09b8a635acc8dfe022330130fcf75134b9 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/remoteapitest/api/v1/GeneralInformationServiceJsonApiTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/remoteapitest/api/v1/GeneralInformationServiceJsonApiTest.java
@@ -38,11 +38,13 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.commons.lang.ArrayUtils;
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
 import org.hamcrest.TypeSafeMatcher;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.common.utilities.ToStringComparator;
@@ -63,6 +65,7 @@ import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchSubCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SpaceWithProjectsAndRoleAssignments;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Vocabulary;
 import ch.systemsx.cisd.openbis.remoteapitest.RemoteApiTestCase;
+import ch.systemsx.cisd.openbis.remoteapitest.api.v1.GeneralInformationServiceJsonApiTest.ContainsDataSetMatcher.CheckMode;
 
 /**
  * Verifies that an instance of {@link IGeneralInformationService} is published via JSON-RPC and
@@ -492,6 +495,9 @@ public class GeneralInformationServiceJsonApiTest extends RemoteApiTestCase
         fail("result didn't contain data set" + expectedDataSetCode);
     }
 
+    /**
+     * reads date in format "y-M-d"
+     */
     private Date getDate(String date)
     {
         SimpleDateFormat sdf = new SimpleDateFormat("y-M-d");
@@ -504,92 +510,138 @@ public class GeneralInformationServiceJsonApiTest extends RemoteApiTestCase
         }
     }
 
-    @Test
-    public void testSearchForDataSetsWithRegistrationDateAndEqualsCompareMode()
+    @DataProvider(name = "testSearchForDataSetsWithRegistrationDate")
+    public Object[][] dataForDataSetRegistrationDateTest()
     {
-        Date date = getDate("2009-02-09");
-
-        SearchCriteria sc = new SearchCriteria();
-        sc.addMatchClause(MatchClause.createAttributeMatch(MatchClauseAttribute.REGISTRATION_DATE,
-                SearchCriteria.CompareMode.EQUALS, date));
-        List<DataSet> result = generalInformationService.searchForDataSets(sessionToken, sc);
+        // datasets from 2008-11-05
+        String[] a =
+                new String[]
+                    { "20081105092159188-3", "20081105092259000-8", "20081105092259000-9",
+                            "20081105092259900-0", "20081105092259900-1", "20081105092359990-2",
+                            "20081105092259000-18", "20081105092259000-19", "20081105092259000-20",
+                            "20081105092259000-21" };
+        // 2009-02-09
+        String[] b =
+                new String[]
+                    { "20110805092359990-17", "20081105092159111-1", "20081105092159222-2",
+                            "20081105092159333-3" };
+        // 2011-05-09
+        String[] c = new String[]
+            { "20110509092359990-10", "20110509092359990-11", "20110509092359990-12" };
+
+        String[] ab = (String[]) ArrayUtils.addAll(a, b);
+        String[] bc = (String[]) ArrayUtils.addAll(b, c);
+        String[] abc = (String[]) ArrayUtils.addAll(ab, c);
+        String[] ac = (String[]) ArrayUtils.addAll(a, c);
+
+        return new Object[][]
+            {
+                        { "less than now", getDate("2012-01-01"), null, null, abc, null },
+                        { "less than late+1", getDate("2011-05-10"), null, null, abc, null },
+                        { "less than late", getDate("2011-05-09"), null, null, abc, null },
+                        { "less than late-1", getDate("2011-05-08"), null, null, ab, c },
+                        { "less than beetween middle / late", getDate("2011-01-01"), null, null,
+                                ab, c },
+                        { "less than middle+1", getDate("2009-02-10"), null, null, ab, c },
+                        { "less than middle", getDate("2009-02-09"), null, null, ab, c },
+                        { "less than middle-1", getDate("2009-02-08"), null, null, a, bc },
+                        { "less than beetween middle / early", getDate("2009-01-01"), null, null,
+                                a, bc },
+                        { "less than early+1", getDate("2008-11-06"), null, null, a, bc },
+                        { "less than early", getDate("2008-11-05"), null, null, a, bc },
+                        { "less than early-1", getDate("2008-11-04"), null, null, null, abc },
+                        { "less than in the past", getDate("2007-12-30"), null, null, null, abc },
+
+                        { "more than now", null, getDate("2012-01-01"), null, null, abc },
+                        { "more than late+1", null, getDate("2011-05-10"), null, null, abc },
+                        { "more than late", null, getDate("2011-05-09"), null, c, ab },
+                        { "more than late-1", null, getDate("2011-05-08"), null, c, ab },
+                        { "more than beetween middle / late", null, getDate("2011-01-01"), null, c,
+                                ab },
+                        { "more than middle+1", null, getDate("2009-02-10"), null, c, ab },
+                        { "more than middle", null, getDate("2009-02-09"), null, bc, a },
+                        { "more than middle-1", null, getDate("2009-02-08"), null, bc, a },
+                        { "more than beetween middle / early", null, getDate("2009-01-01"), null,
+                                bc, a },
+                        { "more than early+1", null, getDate("2008-11-06"), null, bc, a },
+                        { "more than early", null, getDate("2008-11-05"), null, abc, null },
+                        { "more than early-1", null, getDate("2008-11-04"), null, abc, null },
+                        { "more than in the past", null, getDate("2007-12-30"), null, abc, null },
+
+                        { "equal now", null, null, getDate("2012-01-01"), null, abc },
+                        { "equal late+1", null, null, getDate("2011-05-10"), null, abc },
+                        { "equal late", null, null, getDate("2011-05-09"), c, ab },
+                        { "equal late-1", null, null, getDate("2011-05-08"), null, abc },
+                        { "equal beetween middle / late", null, null, getDate("2011-01-01"), null,
+                                abc },
+                        { "equal middle+1", null, null, getDate("2009-02-10"), null, abc },
+                        { "equal middle", null, null, getDate("2009-02-09"), b, ac },
+                        { "equal middle-1", null, null, getDate("2009-02-08"), null, abc },
+                        { "equal beetween middle / early", null, null, getDate("2009-01-01"), null,
+                                abc },
+                        { "equal early+1", null, null, getDate("2008-11-06"), null, abc },
+                        { "equal early", null, null, getDate("2008-11-05"), a, bc },
+                        { "equal early-1", null, null, getDate("2008-11-04"), null, abc },
+                        { "equal in the past", null, null, getDate("2007-12-30"), null, abc },
+
+                        { "later/earlier constraint for all data", getDate("2011-05-09"),
+                                getDate("2008-11-05"), null, abc, null },
+                        { "triple constraint for middle data", getDate("2011-05-09"),
+                                getDate("2008-11-05"), getDate("2009-02-09"), b, ac },
+                        { "invalid contraint constraint for middle data", getDate("2009-01-01"),
+                                getDate("2009-01-01"), null, null, abc },
+                        { "later/earlier constraint for the middle data", getDate("2011-05-08"),
+                                getDate("2008-11-06"), getDate("2009-02-09"), b, ac }, };
 
-        assertThat(
-                result,
-                containsDataSets("20081105092159111-1", "20081105092159222-2",
-                        "20081105092159333-3", "20110805092359990-17"));
     }
 
-    @Test
-    public void testSearchForDataSetsWithRegistrationDateAndLessThanCompareMode()
+    @Test(dataProvider = "testSearchForDataSetsWithRegistrationDate")
+    public void testSearchForDataSetsWithRegistrationDate(String description, Date lessThan,
+            Date moreThan, Date equal, String[] expectedDatasets, String[] unexpectedDataSets)
     {
-        Date date = getDate("2009-02-09");
-
-        SearchCriteria sc = new SearchCriteria();
-        sc.addMatchClause(MatchClause.createAttributeMatch(MatchClauseAttribute.REGISTRATION_DATE,
-                SearchCriteria.CompareMode.LESS_THAN, date));
-        List<DataSet> result = generalInformationService.searchForDataSets(sessionToken, sc);
-
-        assertThat(
-                result,
-                containsDataSets("20081105092159188-3", "20081105092159111-1",
-                        "20081105092159222-2", "20081105092159333-3", "20081105092259000-8",
-                        "20081105092259000-9", "20081105092259900-0", "20081105092259900-1",
-                        "20081105092359990-2", "20110805092359990-17", "20081105092259000-18",
-                        "20081105092259000-19", "20081105092259000-20", "20081105092259000-21"));
-    }
 
-    @Test
-    public void testSearchForDataSetsWithRegistrationDateAndMoreThanCompareMode()
-    {
-        Date date = getDate("2009-03-09");
+        if (lessThan == null && moreThan == null && equal == null)
+        {
+            throw new IllegalArgumentException("Specify at least one date criterium for this test.");
+        }
 
         SearchCriteria sc = new SearchCriteria();
-        sc.addMatchClause(MatchClause.createAttributeMatch(MatchClauseAttribute.REGISTRATION_DATE,
-                SearchCriteria.CompareMode.MORE_THAN, date));
-        List<DataSet> result = generalInformationService.searchForDataSets(sessionToken, sc);
 
-        assertThat(
-                result,
-                containsDataSets("20110509092359990-10", "20110509092359990-11",
-                        "20110509092359990-12"));
-    }
+        if (lessThan != null)
+        {
 
-    @Test
-    public void testSearchForDataSetsWithRegistrationDateRange()
-    {
+            sc.addMatchClause(MatchClause.createAttributeMatch(
+                    MatchClauseAttribute.REGISTRATION_DATE, SearchCriteria.CompareMode.LESS_THAN,
+                    lessThan));
+        }
 
-        Date lower = getDate("2009-02-09");
-        Date upper = getDate("2011-05-09");
+        if (moreThan != null)
+        {
 
-        SearchCriteria sc = new SearchCriteria();
-        sc.addMatchClause(MatchClause.createAttributeMatch(MatchClauseAttribute.REGISTRATION_DATE,
-                SearchCriteria.CompareMode.MORE_THAN, lower));
-        sc.addMatchClause(MatchClause.createAttributeMatch(MatchClauseAttribute.REGISTRATION_DATE,
-                SearchCriteria.CompareMode.LESS_THAN, upper));
-        List<DataSet> result = generalInformationService.searchForDataSets(sessionToken, sc);
+            sc.addMatchClause(MatchClause.createAttributeMatch(
+                    MatchClauseAttribute.REGISTRATION_DATE, SearchCriteria.CompareMode.MORE_THAN,
+                    moreThan));
+        }
 
-        assertThat(
-                result,
-                containsDataSets("20081105092159111-1", "20081105092159222-2",
-                        "20081105092159333-3", "20110509092359990-10", "20110509092359990-11",
-                        "20110509092359990-12", "20110805092359990-17"));
-    }
+        if (equal != null)
+        {
 
-    @Test
-    public void testSearchForDataSetsWithInvalidDateRange()
-    {
-        Date lower = getDate("2011-05-09");
-        Date upper = getDate("2009-02-09");
+            sc.addMatchClause(MatchClause.createAttributeMatch(
+                    MatchClauseAttribute.REGISTRATION_DATE, SearchCriteria.CompareMode.EQUALS,
+                    equal));
+        }
 
-        SearchCriteria sc = new SearchCriteria();
-        sc.addMatchClause(MatchClause.createAttributeMatch(MatchClauseAttribute.REGISTRATION_DATE,
-                SearchCriteria.CompareMode.MORE_THAN, lower));
-        sc.addMatchClause(MatchClause.createAttributeMatch(MatchClauseAttribute.REGISTRATION_DATE,
-                SearchCriteria.CompareMode.LESS_THAN, upper));
         List<DataSet> result = generalInformationService.searchForDataSets(sessionToken, sc);
 
-        assertThat(result.size(), is(0));
+        if (expectedDatasets != null)
+        {
+            assertThat(result, containsDataSets(expectedDatasets));
+        }
+
+        if (unexpectedDataSets != null)
+        {
+            assertThat(result, doesntContainDataSets(unexpectedDataSets));
+        }
     }
 
     @Test
@@ -876,22 +928,37 @@ public class GeneralInformationServiceJsonApiTest extends RemoteApiTestCase
 
     public static Matcher<Collection<DataSet>> containsDataSets(String... codes)
     {
-        return new ContainsDataSetMatcher(codes);
+        return new ContainsDataSetMatcher(CheckMode.CHECK_CONTAINS, codes);
+    }
+
+    public static Matcher<Collection<DataSet>> doesntContainDataSets(String... codes)
+    {
+        return new ContainsDataSetMatcher(CheckMode.CHECK_DOESNT_CONTAIN, codes);
     }
 
     public static class ContainsDataSetMatcher extends TypeSafeMatcher<Collection<DataSet>>
     {
+        public enum CheckMode
+        {
+            CHECK_CONTAINS, CHECK_DOESNT_CONTAIN
+        }
 
-        private Collection<String> codes;
+        private final CheckMode checkMode;
+
+        private final Collection<String> codes;
 
-        public ContainsDataSetMatcher(String... datasetCodes)
+        private String fatalString;
+
+        public ContainsDataSetMatcher(CheckMode checkMode, String... datasetCodes)
         {
             this.codes = Collections.unmodifiableCollection(Arrays.asList(datasetCodes));
+            this.checkMode = checkMode;
         }
 
         public void describeTo(Description description)
         {
-            description.appendText("a collection containing all datasets " + this.codes);
+            description.appendText("a collection containing unwanted " + fatalString
+                    + " as well as all datasets " + this.codes);
         }
 
         @Override
@@ -906,9 +973,24 @@ public class GeneralInformationServiceJsonApiTest extends RemoteApiTestCase
 
             for (String code : this.codes)
             {
-                if (!actualCodes.contains(code))
+                boolean codeContained = actualCodes.contains(code);
+
+                switch (checkMode)
                 {
-                    return false;
+                    case CHECK_CONTAINS:
+                        if (false == codeContained)
+                        {
+                            fatalString = code;
+                            return false;
+                        }
+                        break;
+                    case CHECK_DOESNT_CONTAIN:
+                        if (codeContained)
+                        {
+                            fatalString = code;
+                            return false;
+                        }
+                        break;
                 }
             }
             return true;