http://git-wip-us.apache.org/repos/asf/syncope/blob/bc2afa9a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/SubjectSearchTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/SubjectSearchTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/SubjectSearchTest.java
new file mode 100644
index 0000000..d0a6d0c
--- /dev/null
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/SubjectSearchTest.java
@@ -0,0 +1,471 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.syncope.core.persistence.jpa.entity;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.core.persistence.api.dao.search.MembershipCond;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.dao.search.SubjectCond;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class SubjectSearchTest extends AbstractTest {
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    private SubjectSearchDAO searchDAO;
+
+    @Test
+    public void userMatch() {
+        User user = userDAO.find(1L);
+        assertNotNull(user);
+
+        MembershipCond membershipCond = new MembershipCond();
+        membershipCond.setGroupId(5L);
+
+        assertFalse(searchDAO.matches(user, 
SearchCond.getLeafCond(membershipCond), SubjectType.USER));
+
+        membershipCond.setGroupId(1L);
+
+        assertTrue(searchDAO.matches(user, 
SearchCond.getLeafCond(membershipCond), SubjectType.USER));
+    }
+
+    @Test
+    public void groupMatch() {
+        Group group = groupDAO.find(1L);
+        assertNotNull(group);
+
+        AttributeCond attrCond = new AttributeCond();
+        attrCond.setSchema("show");
+        attrCond.setType(AttributeCond.Type.ISNOTNULL);
+
+        assertTrue(searchDAO.matches(group, SearchCond.getLeafCond(attrCond), 
SubjectType.GROUP));
+    }
+
+    @Test
+    public void searchWithLikeCondition() {
+        AttributeCond fullnameLeafCond = new 
AttributeCond(AttributeCond.Type.LIKE);
+        fullnameLeafCond.setSchema("fullname");
+        fullnameLeafCond.setExpression("%o%");
+
+        MembershipCond membershipCond = new MembershipCond();
+        membershipCond.setGroupId(1L);
+
+        AttributeCond loginDateCond = new AttributeCond(AttributeCond.Type.EQ);
+        loginDateCond.setSchema("loginDate");
+        loginDateCond.setExpression("2009-05-26");
+
+        SearchCond subCond = 
SearchCond.getAndCond(SearchCond.getLeafCond(fullnameLeafCond), 
SearchCond.getLeafCond(
+                membershipCond));
+
+        assertTrue(subCond.isValid());
+
+        SearchCond cond = SearchCond.getAndCond(subCond, 
SearchCond.getLeafCond(loginDateCond));
+
+        assertTrue(cond.isValid());
+
+        List<User> users = 
searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, cond, SubjectType.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+    }
+
+    @Test
+    public void searchWithNotCondition() {
+        AttributeCond fullnameLeafCond = new 
AttributeCond(AttributeCond.Type.EQ);
+        fullnameLeafCond.setSchema("fullname");
+        fullnameLeafCond.setExpression("Giuseppe Verdi");
+
+        SearchCond cond = SearchCond.getNotLeafCond(fullnameLeafCond);
+        assertTrue(cond.isValid());
+
+        List<User> users = 
searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, cond, SubjectType.USER);
+        assertNotNull(users);
+        assertEquals(4, users.size());
+
+        Set<Long> ids = new HashSet<>(users.size());
+        for (User user : users) {
+            ids.add(user.getKey());
+        }
+        assertTrue(ids.contains(1L));
+        assertTrue(ids.contains(3L));
+    }
+
+    @Test
+    public void searchByBoolean() {
+        AttributeCond coolLeafCond = new AttributeCond(AttributeCond.Type.EQ);
+        coolLeafCond.setSchema("cool");
+        coolLeafCond.setExpression("true");
+
+        SearchCond cond = SearchCond.getLeafCond(coolLeafCond);
+        assertTrue(cond.isValid());
+
+        List<User> users = 
searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, cond, SubjectType.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+
+        assertEquals(Long.valueOf(4L), users.get(0).getKey());
+    }
+
+    @Test
+    public void searchByPageAndSize() {
+        AttributeCond fullnameLeafCond = new 
AttributeCond(AttributeCond.Type.LIKE);
+        fullnameLeafCond.setSchema("fullname");
+        fullnameLeafCond.setExpression("%o%");
+
+        MembershipCond membershipCond = new MembershipCond();
+        membershipCond.setGroupId(1L);
+
+        AttributeCond loginDateCond = new AttributeCond(AttributeCond.Type.EQ);
+        loginDateCond.setSchema("loginDate");
+        loginDateCond.setExpression("2009-05-26");
+
+        SearchCond subCond = SearchCond.getAndCond(
+                SearchCond.getLeafCond(fullnameLeafCond), 
SearchCond.getLeafCond(membershipCond));
+
+        assertTrue(subCond.isValid());
+
+        SearchCond cond = SearchCond.getAndCond(subCond, 
SearchCond.getLeafCond(loginDateCond));
+
+        assertTrue(cond.isValid());
+
+        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                cond, 1, 2, Collections.<OrderByClause>emptyList(),
+                SubjectType.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+
+        users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                cond, 2, 2, Collections.<OrderByClause>emptyList(),
+                SubjectType.USER);
+        assertNotNull(users);
+        assertTrue(users.isEmpty());
+    }
+
+    @Test
+    public void searchByMembership() {
+        MembershipCond membershipCond = new MembershipCond();
+        membershipCond.setGroupId(1L);
+
+        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                SearchCond.getLeafCond(membershipCond), SubjectType.USER);
+        assertNotNull(users);
+        assertEquals(2, users.size());
+
+        membershipCond = new MembershipCond();
+        membershipCond.setGroupId(5L);
+
+        users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                SearchCond.getNotLeafCond(membershipCond), SubjectType.USER);
+        assertNotNull(users);
+        assertEquals(5, users.size());
+    }
+
+    @Test
+    public void searchByIsNull() {
+        AttributeCond coolLeafCond = new 
AttributeCond(AttributeCond.Type.ISNULL);
+        coolLeafCond.setSchema("cool");
+
+        List<User> users = searchDAO.search(
+                SyncopeConstants.FULL_ADMIN_REALMS, 
SearchCond.getLeafCond(coolLeafCond), SubjectType.USER);
+        assertNotNull(users);
+        assertEquals(4, users.size());
+
+        coolLeafCond = new AttributeCond(AttributeCond.Type.ISNOTNULL);
+        coolLeafCond.setSchema("cool");
+
+        users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                SearchCond.getLeafCond(coolLeafCond), SubjectType.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+    }
+
+    @Test
+    public void searchByResource() {
+        ResourceCond ws2 = new ResourceCond();
+        ws2.setResourceName("ws-target-resource-2");
+
+        ResourceCond ws1 = new ResourceCond();
+        ws1.setResourceName("ws-target-resource-list-mappings-2");
+
+        SearchCond searchCondition = 
SearchCond.getAndCond(SearchCond.getNotLeafCond(ws2), 
SearchCond.getLeafCond(ws1));
+
+        assertTrue(searchCondition.isValid());
+
+        List<User> users = 
searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, 
SubjectType.USER);
+
+        assertNotNull(users);
+        assertEquals(1, users.size());
+    }
+
+    @Test
+    public void searchByBooleanSubjectCond() {
+        AttributeCond booleanCond = new AttributeCond(SubjectCond.Type.EQ);
+        booleanCond.setSchema("show");
+        booleanCond.setExpression("true");
+
+        List<Group> matchingGroups = 
searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                SearchCond.getLeafCond(booleanCond), SubjectType.GROUP);
+        assertNotNull(matchingGroups);
+        assertFalse(matchingGroups.isEmpty());
+    }
+
+    @Test
+    public void searchByUsernameAndKey() {
+        SubjectCond usernameLeafCond = new SubjectCond(SubjectCond.Type.LIKE);
+        usernameLeafCond.setSchema("username");
+        usernameLeafCond.setExpression("%ini");
+
+        SubjectCond idRightCond = new SubjectCond(SubjectCond.Type.LT);
+        idRightCond.setSchema("key");
+        idRightCond.setExpression("2");
+
+        SearchCond searchCondition = SearchCond.getAndCond(
+                SearchCond.getLeafCond(usernameLeafCond),
+                SearchCond.getLeafCond(idRightCond));
+
+        List<User> matchingUsers = 
searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                searchCondition, SubjectType.USER);
+
+        assertNotNull(matchingUsers);
+        assertEquals(1, matchingUsers.size());
+        assertEquals("rossini", matchingUsers.iterator().next().getUsername());
+        assertEquals(1L, matchingUsers.iterator().next().getKey(), 0);
+    }
+
+    @Test
+    public void searchByGroupNameAndKey() {
+        SubjectCond groupNameLeafCond = new SubjectCond(SubjectCond.Type.EQ);
+        groupNameLeafCond.setSchema("name");
+        groupNameLeafCond.setExpression("root");
+
+        SubjectCond idRightCond = new SubjectCond(SubjectCond.Type.LT);
+        idRightCond.setSchema("key");
+        idRightCond.setExpression("2");
+
+        SearchCond searchCondition = SearchCond.getAndCond(
+                SearchCond.getLeafCond(groupNameLeafCond),
+                SearchCond.getLeafCond(idRightCond));
+
+        assertTrue(searchCondition.isValid());
+
+        List<Group> matchingGroups = 
searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                searchCondition, SubjectType.GROUP);
+
+        assertNotNull(matchingGroups);
+        assertEquals(1, matchingGroups.size());
+        assertEquals("root", matchingGroups.iterator().next().getName());
+        assertEquals(1L, matchingGroups.iterator().next().getKey(), 0);
+    }
+
+    @Test
+    public void searchByUsernameAndFullname() {
+        SubjectCond usernameLeafCond = new SubjectCond(SubjectCond.Type.EQ);
+        usernameLeafCond.setSchema("username");
+        usernameLeafCond.setExpression("rossini");
+
+        AttributeCond idRightCond = new AttributeCond(AttributeCond.Type.LIKE);
+        idRightCond.setSchema("fullname");
+        idRightCond.setExpression("Giuseppe V%");
+
+        SearchCond searchCondition = SearchCond.getOrCond(
+                SearchCond.getLeafCond(usernameLeafCond),
+                SearchCond.getLeafCond(idRightCond));
+
+        List<User> matchingUsers = 
searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                searchCondition, SubjectType.USER);
+        assertNotNull(matchingUsers);
+        assertEquals(2, matchingUsers.size());
+    }
+
+    @Test
+    public void searchById() {
+        SubjectCond idLeafCond = new SubjectCond(SubjectCond.Type.LT);
+        idLeafCond.setSchema("id");
+        idLeafCond.setExpression("2");
+
+        SearchCond searchCondition = SearchCond.getLeafCond(idLeafCond);
+        assertTrue(searchCondition.isValid());
+
+        List<User> users = 
searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, 
SubjectType.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+        assertEquals(1L, users.iterator().next().getKey(), 0);
+
+        idLeafCond = new SubjectCond(SubjectCond.Type.LT);
+        idLeafCond.setSchema("id");
+        idLeafCond.setExpression("4");
+
+        searchCondition = SearchCond.getNotLeafCond(idLeafCond);
+        assertTrue(searchCondition.isValid());
+
+        users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, 
searchCondition, SubjectType.USER);
+        assertNotNull(users);
+        assertEquals(2, users.size());
+        assertTrue(CollectionUtils.exists(users, new Predicate<User>() {
+
+            @Override
+            public boolean evaluate(User user) {
+                return user.getKey() == 4;
+            }
+        }));
+    }
+
+    @Test
+    public void userOrderBy() {
+        SubjectCond usernameLeafCond = new SubjectCond(SubjectCond.Type.EQ);
+        usernameLeafCond.setSchema("username");
+        usernameLeafCond.setExpression("rossini");
+        AttributeCond idRightCond = new AttributeCond(AttributeCond.Type.LIKE);
+        idRightCond.setSchema("fullname");
+        idRightCond.setExpression("Giuseppe V%");
+        SearchCond searchCondition = SearchCond.getOrCond(
+                SearchCond.getLeafCond(usernameLeafCond), 
SearchCond.getLeafCond(idRightCond));
+
+        List<OrderByClause> orderByClauses = new ArrayList<>();
+        OrderByClause orderByClause = new OrderByClause();
+        orderByClause.setField("username");
+        orderByClause.setDirection(OrderByClause.Direction.DESC);
+        orderByClauses.add(orderByClause);
+        orderByClause = new OrderByClause();
+        orderByClause.setField("fullname");
+        orderByClause.setDirection(OrderByClause.Direction.ASC);
+        orderByClauses.add(orderByClause);
+
+        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                searchCondition, orderByClauses, SubjectType.USER);
+        assertEquals(searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS, 
searchCondition, SubjectType.USER),
+                users.size());
+    }
+
+    @Test
+    public void groupOrderBy() {
+        SubjectCond idLeafCond = new SubjectCond(SubjectCond.Type.LIKE);
+        idLeafCond.setSchema("name");
+        idLeafCond.setExpression("%r");
+        SearchCond searchCondition = SearchCond.getLeafCond(idLeafCond);
+        assertTrue(searchCondition.isValid());
+
+        OrderByClause orderByClause = new OrderByClause();
+        orderByClause.setField("name");
+
+        List<Group> groups = 
searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                searchCondition, Collections.singletonList(orderByClause), 
SubjectType.GROUP);
+        assertEquals(searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS,
+                searchCondition, SubjectType.GROUP),
+                groups.size());
+    }
+
+    @Test
+    public void issue202() {
+        ResourceCond ws2 = new ResourceCond();
+        ws2.setResourceName("ws-target-resource-2");
+
+        ResourceCond ws1 = new ResourceCond();
+        ws1.setResourceName("ws-target-resource-list-mappings-1");
+
+        SearchCond searchCondition =
+                SearchCond.getAndCond(SearchCond.getNotLeafCond(ws2), 
SearchCond.getNotLeafCond(ws1));
+        assertTrue(searchCondition.isValid());
+
+        List<User> users = 
searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, 
SubjectType.USER);
+        assertNotNull(users);
+        assertEquals(2, users.size());
+        assertTrue(CollectionUtils.exists(users, new Predicate<User>() {
+
+            @Override
+            public boolean evaluate(User user) {
+                return user.getKey() == 4;
+            }
+        }));
+    }
+
+    @Test
+    public void issue242() {
+        SubjectCond cond = new SubjectCond(AttributeCond.Type.LIKE);
+        cond.setSchema("id");
+        cond.setExpression("test%");
+
+        SearchCond searchCondition = SearchCond.getLeafCond(cond);
+        assertTrue(searchCondition.isValid());
+
+        List<User> users = 
searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, 
SubjectType.USER);
+        assertNotNull(users);
+        assertTrue(users.isEmpty());
+    }
+
+    @Test
+    public void issueSYNCOPE46() {
+        SubjectCond cond = new SubjectCond(AttributeCond.Type.LIKE);
+        cond.setSchema("username");
+        cond.setExpression("%ossin%");
+
+        SearchCond searchCondition = SearchCond.getLeafCond(cond);
+        assertTrue(searchCondition.isValid());
+
+        List<User> users = 
searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, 
SubjectType.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+    }
+
+    @Test
+    public void issueSYNCOPE433() {
+        AttributeCond isNullCond = new 
AttributeCond(AttributeCond.Type.ISNULL);
+        isNullCond.setSchema("loginDate");
+
+        SubjectCond likeCond = new SubjectCond(AttributeCond.Type.LIKE);
+        likeCond.setSchema("username");
+        likeCond.setExpression("%ossin%");
+
+        SearchCond searchCond = SearchCond.getOrCond(
+                SearchCond.getLeafCond(isNullCond), 
SearchCond.getLeafCond(likeCond));
+
+        Integer count = searchDAO.count(SyncopeConstants.FULL_ADMIN_REALMS, 
searchCond, SubjectType.USER);
+        assertNotNull(count);
+        assertTrue(count > 0);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/bc2afa9a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AttributableSearchTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AttributableSearchTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AttributableSearchTest.java
deleted file mode 100644
index 02f86de..0000000
--- 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AttributableSearchTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.apache.syncope.core.persistence.jpa.relationship;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.SubjectType;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
-import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.persistence.jpa.AbstractTest;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class AttributableSearchTest extends AbstractTest {
-
-    @Autowired
-    private GroupDAO groupDAO;
-
-    @Autowired
-    private SubjectSearchDAO searchDAO;
-
-    @Test
-    public void issueSYNCOPE95() {
-        Set<Group> groups = new 
HashSet<>(groupDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 100));
-        for (Group group : groups) {
-            groupDAO.delete(group.getKey());
-        }
-        groupDAO.flush();
-
-        final AttributeCond coolLeafCond = new 
AttributeCond(AttributeCond.Type.EQ);
-        coolLeafCond.setSchema("cool");
-        coolLeafCond.setExpression("true");
-
-        final SearchCond cond = SearchCond.getLeafCond(coolLeafCond);
-        assertTrue(cond.isValid());
-
-        final List<User> users =
-                searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, cond, 
SubjectType.USER);
-        assertNotNull(users);
-        assertEquals(1, users.size());
-
-        assertEquals(Long.valueOf(4L), users.get(0).getKey());
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/bc2afa9a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/SubjectSearchTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/SubjectSearchTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/SubjectSearchTest.java
new file mode 100644
index 0000000..d3eb0be
--- /dev/null
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/SubjectSearchTest.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.syncope.core.persistence.jpa.relationship;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class SubjectSearchTest extends AbstractTest {
+
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    private SubjectSearchDAO searchDAO;
+
+    @Test
+    public void issueSYNCOPE95() {
+        Set<Group> groups = new 
HashSet<>(groupDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 100));
+        for (Group group : groups) {
+            groupDAO.delete(group.getKey());
+        }
+        groupDAO.flush();
+
+        final AttributeCond coolLeafCond = new 
AttributeCond(AttributeCond.Type.EQ);
+        coolLeafCond.setSchema("cool");
+        coolLeafCond.setExpression("true");
+
+        final SearchCond cond = SearchCond.getLeafCond(coolLeafCond);
+        assertTrue(cond.isValid());
+
+        final List<User> users =
+                searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, cond, 
SubjectType.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+
+        assertEquals(Long.valueOf(4L), users.get(0).getKey());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/bc2afa9a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/QueryResourceInfoComparator.java
----------------------------------------------------------------------
diff --git 
a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/QueryResourceInfoComparator.java
 
b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/QueryResourceInfoComparator.java
deleted file mode 100644
index a45e275..0000000
--- 
a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/QueryResourceInfoComparator.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.apache.syncope.core.rest.cxf;
-
-import java.util.List;
-import java.util.Map;
-
-import org.apache.cxf.jaxrs.ext.ResourceComparator;
-import org.apache.cxf.jaxrs.model.ClassResourceInfo;
-import org.apache.cxf.jaxrs.model.OperationResourceInfo;
-import org.apache.cxf.jaxrs.model.OperationResourceInfoComparator;
-import org.apache.cxf.jaxrs.model.Parameter;
-import org.apache.cxf.jaxrs.utils.JAXRSUtils;
-import org.apache.cxf.message.Message;
-
-public class QueryResourceInfoComparator extends 
OperationResourceInfoComparator implements ResourceComparator {
-
-    public QueryResourceInfoComparator() {
-        super(null, null);
-    }
-
-    @Override
-    public int compare(final ClassResourceInfo cri1, final ClassResourceInfo 
cri2, final Message message) {
-        // Leave Class selection to CXF
-        return 0;
-    }
-
-    @Override
-    public int compare(final OperationResourceInfo oper1, final 
OperationResourceInfo oper2, final Message message) {
-        // Check if CXF can make a decision
-        int cxfResult = super.compare(oper1, oper2);
-        if (cxfResult != 0) {
-            return cxfResult;
-        }
-
-        int op1Counter = getMatchingRate(oper1, message);
-        int op2Counter = getMatchingRate(oper2, message);
-
-        return op1Counter == op2Counter
-                ? 0
-                : op1Counter < op2Counter
-                ? 1
-                : -1;
-    }
-
-    /**
-     * This method calculates a number indicating a good or bad match between 
values provided within the request and
-     * expected method parameters. A higher number means a better match.
-     *
-     * @param operation The operation to be rated, based on contained 
parameterInfo values.
-     * @param message A message containing query and header values from user 
request
-     * @return A positive or negative number, indicating a good match between 
query and method
-     */
-    protected int getMatchingRate(final OperationResourceInfo operation, final 
Message message) {
-        List<Parameter> params = operation.getParameters();
-        if (params == null || params.isEmpty()) {
-            return 0;
-        }
-
-        // Get Request QueryParams
-        String query = (String) message.get(Message.QUERY_STRING);
-        String path = (String) message.get(Message.REQUEST_URI);
-        Map<String, List<String>> qParams = 
JAXRSUtils.getStructuredParams(query, "&", true, false);
-        Map<String, List<String>> mParams = JAXRSUtils.getMatrixParams(path, 
true);
-        // Get Request Headers
-        Map<?, ?> qHeader = (java.util.Map<?, ?>) 
message.get(Message.PROTOCOL_HEADERS);
-
-        int rate = 0;
-        for (Parameter p : params) {
-            switch (p.getType()) {
-                case QUERY:
-                    if (qParams.containsKey(p.getName())) {
-                        rate += 2;
-                    } else if (p.getDefaultValue() == null) {
-                        rate -= 1;
-                    }
-                    break;
-                case MATRIX:
-                    if (mParams.containsKey(p.getName())) {
-                        rate += 2;
-                    } else if (p.getDefaultValue() == null) {
-                        rate -= 1;
-                    }
-                    break;
-                case HEADER:
-                    if (qHeader.containsKey(p.getName())) {
-                        rate += 2;
-                    } else if (p.getDefaultValue() == null) {
-                        rate -= 1;
-                    }
-                    break;
-                default:
-                    break;
-            }
-        }
-        return rate;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/bc2afa9a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
 
b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
index 5efee1e..ee4825e 100644
--- 
a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
+++ 
b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java
@@ -34,9 +34,10 @@ import 
org.apache.syncope.common.lib.types.ResourceAssociationActionType;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.wrap.ResourceName;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.beans.SubjectListQuery;
+import org.apache.syncope.common.rest.api.beans.SubjectSearchQuery;
 import org.apache.syncope.common.rest.api.service.GroupService;
 import org.apache.syncope.core.logic.GroupLogic;
-import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -64,25 +65,8 @@ public class GroupServiceImpl extends AbstractServiceImpl 
implements GroupServic
     }
 
     @Override
-    public PagedResult<GroupTO> list(final List<String> realms) {
-        return list(realms, DEFAULT_PARAM_PAGE_VALUE, 
DEFAULT_PARAM_SIZE_VALUE, null);
-    }
-
-    @Override
-    public PagedResult<GroupTO> list(final List<String> realms, final String 
orderBy) {
-        return list(realms, DEFAULT_PARAM_PAGE_VALUE, 
DEFAULT_PARAM_SIZE_VALUE, orderBy);
-    }
-
-    @Override
-    public PagedResult<GroupTO> list(final List<String> realms, final Integer 
page, final Integer size) {
-        return list(realms, page, size, null);
-    }
-
-    @Override
-    public PagedResult<GroupTO> list(
-            final List<String> realms, final Integer page, final Integer size, 
final String orderBy) {
-
-        CollectionUtils.transform(realms, new Transformer<String, String>() {
+    public PagedResult<GroupTO> list(final SubjectListQuery listQuery) {
+        CollectionUtils.transform(listQuery.getRealms(), new 
Transformer<String, String>() {
 
             @Override
             public String transform(final String input) {
@@ -90,10 +74,15 @@ public class GroupServiceImpl extends AbstractServiceImpl 
implements GroupServic
             }
         });
 
-        List<OrderByClause> orderByClauses = getOrderByClauses(orderBy);
         return buildPagedResult(
-                logic.list(page, size, orderByClauses, realms), page, size,
-                logic.count(realms));
+                logic.list(
+                        listQuery.getPage(),
+                        listQuery.getSize(),
+                        getOrderByClauses(listQuery.getOrderBy()),
+                        listQuery.getRealms()),
+                listQuery.getPage(),
+                listQuery.getSize(),
+                logic.count(listQuery.getRealms()));
     }
 
     @Override
@@ -102,27 +91,8 @@ public class GroupServiceImpl extends AbstractServiceImpl 
implements GroupServic
     }
 
     @Override
-    public PagedResult<GroupTO> search(final List<String> realms, final String 
fiql) {
-        return search(realms, fiql, DEFAULT_PARAM_PAGE_VALUE, 
DEFAULT_PARAM_SIZE_VALUE, null);
-    }
-
-    @Override
-    public PagedResult<GroupTO> search(final List<String> realms, final String 
fiql, final String orderBy) {
-        return search(realms, fiql, DEFAULT_PARAM_PAGE_VALUE, 
DEFAULT_PARAM_SIZE_VALUE, orderBy);
-    }
-
-    @Override
-    public PagedResult<GroupTO> search(
-            final List<String> realms, final String fiql, final Integer page, 
final Integer size) {
-
-        return search(realms, fiql, page, size, null);
-    }
-
-    @Override
-    public PagedResult<GroupTO> search(final List<String> realms, final String 
fiql,
-            final Integer page, final Integer size, final String orderBy) {
-
-        CollectionUtils.transform(realms, new Transformer<String, String>() {
+    public PagedResult<GroupTO> search(final SubjectSearchQuery searchQuery) {
+        CollectionUtils.transform(searchQuery.getRealms(), new 
Transformer<String, String>() {
 
             @Override
             public String transform(final String input) {
@@ -130,11 +100,17 @@ public class GroupServiceImpl extends AbstractServiceImpl 
implements GroupServic
             }
         });
 
-        SearchCond cond = getSearchCond(fiql);
-        List<OrderByClause> orderByClauses = getOrderByClauses(orderBy);
+        SearchCond cond = getSearchCond(searchQuery.getFiql());
         return buildPagedResult(
-                logic.search(cond, page, size, orderByClauses, realms), page, 
size,
-                logic.searchCount(cond, realms));
+                logic.search(
+                        cond,
+                        searchQuery.getPage(),
+                        searchQuery.getSize(),
+                        getOrderByClauses(searchQuery.getOrderBy()),
+                        searchQuery.getRealms()),
+                searchQuery.getPage(),
+                searchQuery.getSize(),
+                logic.searchCount(cond, searchQuery.getRealms()));
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/bc2afa9a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java
 
b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java
index 3fd69a4..dfde009 100644
--- 
a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java
+++ 
b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java
@@ -32,9 +32,9 @@ import 
org.apache.syncope.common.lib.types.ReportExecExportFormat;
 import org.apache.syncope.common.lib.wrap.ReportletConfClass;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.beans.ListQuery;
 import org.apache.syncope.common.rest.api.service.ReportService;
 import org.apache.syncope.core.logic.ReportLogic;
-import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.ReportExec;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -50,7 +50,7 @@ public class ReportServiceImpl extends AbstractServiceImpl 
implements ReportServ
         ReportTO createdReportTO = logic.create(reportTO);
         URI location = 
uriInfo.getAbsolutePathBuilder().path(String.valueOf(createdReportTO.getKey())).build();
         return Response.created(location).
-                header(RESTHeaders.RESOURCE_ID.toString(), 
createdReportTO.getKey()).
+                header(RESTHeaders.RESOURCE_ID, createdReportTO.getKey()).
                 build();
     }
 
@@ -61,24 +61,15 @@ public class ReportServiceImpl extends AbstractServiceImpl 
implements ReportServ
     }
 
     @Override
-    public PagedResult<ReportTO> list() {
-        return list(DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, null);
-    }
-
-    @Override
-    public PagedResult<ReportTO> list(final String orderBy) {
-        return list(DEFAULT_PARAM_PAGE_VALUE, DEFAULT_PARAM_SIZE_VALUE, 
orderBy);
-    }
-
-    @Override
-    public PagedResult<ReportTO> list(final Integer page, final Integer size) {
-        return list(page, size, null);
-    }
-
-    @Override
-    public PagedResult<ReportTO> list(final Integer page, final Integer size, 
final String orderBy) {
-        List<OrderByClause> orderByClauses = getOrderByClauses(orderBy);
-        return buildPagedResult(logic.list(page, size, orderByClauses), page, 
size, logic.count());
+    public PagedResult<ReportTO> list(final ListQuery listQuery) {
+        return buildPagedResult(
+                logic.list(
+                        listQuery.getPage(),
+                        listQuery.getSize(),
+                        getOrderByClauses(listQuery.getOrderBy())),
+                listQuery.getPage(),
+                listQuery.getSize(),
+                logic.count());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/bc2afa9a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
 
b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
index ce1a394..83edcc0 100644
--- 
a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
+++ 
b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
@@ -19,7 +19,6 @@
 package org.apache.syncope.core.rest.cxf.service;
 
 import java.net.URI;
-import java.util.List;
 import javax.ws.rs.BadRequestException;
 import javax.ws.rs.core.Response;
 import org.apache.syncope.common.lib.to.AbstractTaskTO;
@@ -34,9 +33,9 @@ import org.apache.syncope.common.lib.to.TaskExecTO;
 import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.beans.ListQuery;
 import org.apache.syncope.common.rest.api.service.TaskService;
 import org.apache.syncope.core.logic.TaskLogic;
-import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -76,31 +75,18 @@ public class TaskServiceImpl extends AbstractServiceImpl 
implements TaskService
         return logic.execute(taskKey, dryRun);
     }
 
-    @Override
-    public <T extends AbstractTaskTO> PagedResult<T> list(final TaskType 
taskType) {
-        return list(taskType, DEFAULT_PARAM_PAGE_VALUE, 
DEFAULT_PARAM_SIZE_VALUE, null);
-    }
-
-    @Override
-    public <T extends AbstractTaskTO> PagedResult<T> list(final TaskType 
taskType, final String orderBy) {
-        return list(taskType, DEFAULT_PARAM_PAGE_VALUE, 
DEFAULT_PARAM_SIZE_VALUE, orderBy);
-    }
-
-    @Override
-    public <T extends AbstractTaskTO> PagedResult<T> list(
-            final TaskType taskType, final Integer page, final Integer size) {
-
-        return list(taskType, page, size, null);
-    }
-
-    @Override
     @SuppressWarnings("unchecked")
-    public <T extends AbstractTaskTO> PagedResult<T> list(final TaskType 
taskType,
-            final Integer page, final Integer size, final String orderBy) {
-
-        List<OrderByClause> orderByClauses = getOrderByClauses(orderBy);
+    @Override
+    public <T extends AbstractTaskTO> PagedResult<T> list(final TaskType 
taskType, final ListQuery listQuery) {
         return (PagedResult<T>) buildPagedResult(
-                logic.list(taskType, page, size, orderByClauses), page, size, 
logic.count(taskType));
+                logic.list(
+                        taskType,
+                        listQuery.getPage(),
+                        listQuery.getSize(),
+                        getOrderByClauses(listQuery.getOrderBy())),
+                listQuery.getPage(),
+                listQuery.getSize(),
+                logic.count(taskType));
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/bc2afa9a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
 
b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
index 320a37c..a758993 100644
--- 
a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
+++ 
b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java
@@ -38,9 +38,10 @@ import 
org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.wrap.ResourceName;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.beans.SubjectListQuery;
+import org.apache.syncope.common.rest.api.beans.SubjectSearchQuery;
 import org.apache.syncope.common.rest.api.service.UserService;
 import org.apache.syncope.core.logic.UserLogic;
-import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -82,25 +83,8 @@ public class UserServiceImpl extends AbstractServiceImpl 
implements UserService
     }
 
     @Override
-    public PagedResult<UserTO> list(final List<String> realms) {
-        return list(realms, DEFAULT_PARAM_PAGE_VALUE, 
DEFAULT_PARAM_SIZE_VALUE, null);
-    }
-
-    @Override
-    public PagedResult<UserTO> list(final List<String> realms, final String 
orderBy) {
-        return list(realms, DEFAULT_PARAM_PAGE_VALUE, 
DEFAULT_PARAM_SIZE_VALUE, orderBy);
-    }
-
-    @Override
-    public PagedResult<UserTO> list(final List<String> realms, final Integer 
page, final Integer size) {
-        return list(realms, page, size, null);
-    }
-
-    @Override
-    public PagedResult<UserTO> list(
-            final List<String> realms, final Integer page, final Integer size, 
final String orderBy) {
-
-        CollectionUtils.transform(realms, new Transformer<String, String>() {
+    public PagedResult<UserTO> list(final SubjectListQuery listQuery) {
+        CollectionUtils.transform(listQuery.getRealms(), new 
Transformer<String, String>() {
 
             @Override
             public String transform(final String input) {
@@ -108,10 +92,15 @@ public class UserServiceImpl extends AbstractServiceImpl 
implements UserService
             }
         });
 
-        List<OrderByClause> orderByClauses = getOrderByClauses(orderBy);
         return buildPagedResult(
-                logic.list(page, size, orderByClauses, realms), page, size,
-                logic.count(realms));
+                logic.list(
+                        listQuery.getPage(),
+                        listQuery.getSize(),
+                        getOrderByClauses(listQuery.getOrderBy()),
+                        listQuery.getRealms()),
+                listQuery.getPage(),
+                listQuery.getSize(),
+                logic.count(listQuery.getRealms()));
     }
 
     @Override
@@ -120,27 +109,8 @@ public class UserServiceImpl extends AbstractServiceImpl 
implements UserService
     }
 
     @Override
-    public PagedResult<UserTO> search(final List<String> realms, final String 
fiql) {
-        return search(realms, fiql, DEFAULT_PARAM_PAGE_VALUE, 
DEFAULT_PARAM_SIZE_VALUE, null);
-    }
-
-    @Override
-    public PagedResult<UserTO> search(final List<String> realms, final String 
fiql, final String orderBy) {
-        return search(realms, fiql, DEFAULT_PARAM_PAGE_VALUE, 
DEFAULT_PARAM_SIZE_VALUE, orderBy);
-    }
-
-    @Override
-    public PagedResult<UserTO> search(
-            final List<String> realms, final String fiql, final Integer page, 
final Integer size) {
-
-        return search(realms, fiql, page, size, null);
-    }
-
-    @Override
-    public PagedResult<UserTO> search(final List<String> realms, final String 
fiql,
-            final Integer page, final Integer size, final String orderBy) {
-
-        CollectionUtils.transform(realms, new Transformer<String, String>() {
+    public PagedResult<UserTO> search(final SubjectSearchQuery searchQuery) {
+        CollectionUtils.transform(searchQuery.getRealms(), new 
Transformer<String, String>() {
 
             @Override
             public String transform(final String input) {
@@ -148,11 +118,17 @@ public class UserServiceImpl extends AbstractServiceImpl 
implements UserService
             }
         });
 
-        SearchCond cond = getSearchCond(fiql);
-        List<OrderByClause> orderByClauses = getOrderByClauses(orderBy);
+        SearchCond cond = getSearchCond(searchQuery.getFiql());
         return buildPagedResult(
-                logic.search(cond, page, size, orderByClauses, realms), page, 
size,
-                logic.searchCount(cond, realms));
+                logic.search(
+                        cond,
+                        searchQuery.getPage(),
+                        searchQuery.getSize(),
+                        getOrderByClauses(searchQuery.getOrderBy()),
+                        searchQuery.getRealms()),
+                searchQuery.getPage(),
+                searchQuery.getSize(),
+                logic.searchCount(cond, searchQuery.getRealms()));
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/bc2afa9a/core/rest-cxf/src/main/resources/restCXFContext.xml
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/resources/restCXFContext.xml 
b/core/rest-cxf/src/main/resources/restCXFContext.xml
index e5e14d6..c6a472e 100644
--- a/core/rest-cxf/src/main/resources/restCXFContext.xml
+++ b/core/rest-cxf/src/main/resources/restCXFContext.xml
@@ -93,9 +93,6 @@ under the License.
   <jaxrs:server id="restContainer" address="/" 
                 basePackages="org.apache.syncope.common.rest.api.service, 
org.apache.syncope.core.rest.cxf.service" 
                 staticSubresourceResolution="true">
-    <jaxrs:resourceComparator>
-      <bean 
class="org.apache.syncope.core.rest.cxf.QueryResourceInfoComparator"/>
-    </jaxrs:resourceComparator>
     <jaxrs:properties> 
       <entry key="search.lax.property.match" value="true"/> 
     </jaxrs:properties> 

http://git-wip-us.apache.org/repos/asf/syncope/blob/bc2afa9a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
index 669d088..6545be5 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
@@ -34,6 +34,7 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
+import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.to.AbstractTaskTO;
 import org.apache.syncope.common.lib.to.NotificationTaskTO;
 import org.apache.syncope.common.lib.to.PagedResult;
@@ -140,7 +141,8 @@ public abstract class AbstractTaskITCase extends 
AbstractITCase {
     }
 
     protected NotificationTaskTO findNotificationTaskBySender(final String 
sender) {
-        PagedResult<NotificationTaskTO> tasks = 
taskService.list(TaskType.NOTIFICATION);
+        PagedResult<NotificationTaskTO> tasks =
+                taskService.list(TaskType.NOTIFICATION, 
SyncopeClient.getListQueryBuilder().build());
         assertNotNull(tasks);
         assertFalse(tasks.getResult().isEmpty());
         NotificationTaskTO taskTO = null;

http://git-wip-us.apache.org/repos/asf/syncope/blob/bc2afa9a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
index 9598436..84b78cd 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
@@ -25,7 +25,6 @@ import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.security.AccessControlException;
-import java.util.Collections;
 import java.util.Map;
 import java.util.Set;
 
@@ -34,6 +33,7 @@ import org.apache.commons.collections4.Predicate;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.mod.StatusMod;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.BulkActionResult;
@@ -200,8 +200,8 @@ public class AuthenticationITCase extends AbstractITCase {
                 getService(UserService.class);
 
         PagedResult<UserTO> matchedUsers = userService2.search(
-                Collections.singletonList("/"),
-                
SyncopeClient.getUserSearchConditionBuilder().isNotNull("loginDate").query());
+                
SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                
fiql(SyncopeClient.getUserSearchConditionBuilder().isNotNull("loginDate").query()).build());
         assertNotNull(matchedUsers);
         assertFalse(matchedUsers.getResult().isEmpty());
         assertTrue(CollectionUtils.exists(matchedUsers.getResult(), new 
Predicate<UserTO>() {
@@ -215,8 +215,8 @@ public class AuthenticationITCase extends AbstractITCase {
         UserService userService3 = clientFactory.create("verdi", 
"password").getService(UserService.class);
 
         matchedUsers = userService3.search(
-                Collections.singletonList("/even/two"),
-                
SyncopeClient.getUserSearchConditionBuilder().isNotNull("loginDate").query());
+                
SyncopeClient.getSubjectSearchQueryBuilder().realm("/even/two").
+                
fiql(SyncopeClient.getUserSearchConditionBuilder().isNotNull("loginDate").query()).build());
         assertNotNull(matchedUsers);
         assertFalse(CollectionUtils.exists(matchedUsers.getResult(), new 
Predicate<UserTO>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/bc2afa9a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
index 7fac061..7071c22 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/GroupITCase.java
@@ -28,7 +28,6 @@ import static org.junit.Assert.fail;
 import java.io.IOException;
 import java.io.InputStream;
 import java.security.AccessControlException;
-import java.util.Collections;
 import java.util.List;
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
@@ -40,6 +39,7 @@ import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.mod.ReferenceMod;
 import org.apache.syncope.common.lib.mod.GroupMod;
 import org.apache.syncope.common.lib.to.BulkActionResult;
@@ -148,7 +148,8 @@ public class GroupITCase extends AbstractITCase {
 
     @Test
     public void list() {
-        PagedResult<GroupTO> groupTOs = 
groupService.list(Collections.singletonList("/"));
+        PagedResult<GroupTO> groupTOs =
+                
groupService.list(SyncopeClient.getSubjectListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).build());
         assertNotNull(groupTOs);
         assertTrue(groupTOs.getResult().size() >= 8);
         for (GroupTO groupTO : groupTOs.getResult()) {
@@ -548,14 +549,15 @@ public class GroupITCase extends AbstractITCase {
     public void anonymous() {
         GroupService unauthenticated = 
clientFactory.createAnonymous().getService(GroupService.class);
         try {
-            unauthenticated.list(Collections.singletonList("/"));
+            
unauthenticated.list(SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).build());
             fail();
         } catch (AccessControlException e) {
             assertNotNull(e);
         }
 
         GroupService anonymous = clientFactory.create(ANONYMOUS_UNAME, 
ANONYMOUS_KEY).getService(GroupService.class);
-        
assertFalse(anonymous.list(Collections.singletonList("/")).getResult().isEmpty());
+        
assertFalse(anonymous.list(SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).build()).
+                getResult().isEmpty());
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/syncope/blob/bc2afa9a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java
index a4598b2..66185f5 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PropagationTaskITCase.java
@@ -26,6 +26,7 @@ import static org.junit.Assert.assertTrue;
 import java.util.ArrayList;
 import java.util.List;
 import javax.ws.rs.core.Response;
+import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AbstractTaskTO;
 import org.apache.syncope.common.lib.to.BulkAction;
@@ -45,27 +46,30 @@ public class PropagationTaskITCase extends 
AbstractTaskITCase {
 
     @Test
     public void paginatedList() {
-        PagedResult<PropagationTaskTO> tasks = 
taskService.list(TaskType.PROPAGATION, 1, 2);
-
+        PagedResult<PropagationTaskTO> tasks = taskService.list(
+                TaskType.PROPAGATION,
+                SyncopeClient.getListQueryBuilder().page(1).size(2).build());
         assertNotNull(tasks);
-        assertFalse(tasks.getResult().isEmpty());
         assertEquals(2, tasks.getResult().size());
 
         for (AbstractTaskTO task : tasks.getResult()) {
             assertNotNull(task);
         }
 
-        tasks = taskService.list(TaskType.PROPAGATION, 2, 2);
-
+        tasks = taskService.list(
+                TaskType.PROPAGATION,
+                SyncopeClient.getListQueryBuilder().page(2).size(2).build());
         assertNotNull(tasks);
-        assertFalse(tasks.getResult().isEmpty());
+        assertEquals(2, tasks.getPage());
+        assertEquals(2, tasks.getResult().size());
 
         for (AbstractTaskTO task : tasks.getResult()) {
             assertNotNull(task);
         }
 
-        tasks = taskService.list(TaskType.PROPAGATION, 1000, 2);
-
+        tasks = taskService.list(
+                TaskType.PROPAGATION,
+                
SyncopeClient.getListQueryBuilder().page(1000).size(2).build());
         assertNotNull(tasks);
         assertTrue(tasks.getResult().isEmpty());
     }
@@ -122,29 +126,30 @@ public class PropagationTaskITCase extends 
AbstractTaskITCase {
 
     @Test
     public void bulkAction() {
-        final PagedResult<PropagationTaskTO> before = 
taskService.list(TaskType.PROPAGATION);
+        PagedResult<PropagationTaskTO> before = taskService.list(
+                TaskType.PROPAGATION, 
SyncopeClient.getListQueryBuilder().build());
 
         // create user with testdb resource
-        final UserTO userTO = 
UserITCase.getUniqueSampleTO("taskb...@apache.org");
+        UserTO userTO = UserITCase.getUniqueSampleTO("taskb...@apache.org");
         userTO.getResources().add(RESOURCE_NAME_TESTDB);
         createUser(userTO);
 
-        final List<PropagationTaskTO> after = new ArrayList<>(
-                
taskService.<PropagationTaskTO>list(TaskType.PROPAGATION).getResult());
-
+        List<PropagationTaskTO> after = new ArrayList<>(
+                taskService.<PropagationTaskTO>list(TaskType.PROPAGATION, 
SyncopeClient.getListQueryBuilder().build()).
+                getResult());
         after.removeAll(before.getResult());
-
         assertFalse(after.isEmpty());
 
-        final BulkAction bulkAction = new BulkAction();
+        BulkAction bulkAction = new BulkAction();
         bulkAction.setOperation(BulkAction.Type.DELETE);
 
-        for (AbstractTaskTO taskTO : after) {
+        for (PropagationTaskTO taskTO : after) {
             bulkAction.getTargets().add(String.valueOf(taskTO.getKey()));
         }
 
         taskService.bulk(bulkAction);
 
-        
assertFalse(taskService.list(TaskType.PROPAGATION).getResult().containsAll(after));
+        assertFalse(taskService.list(TaskType.PROPAGATION, 
SyncopeClient.getListQueryBuilder().build()).getResult().
+                containsAll(after));
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/bc2afa9a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
index 918c22b..33ee57a 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/PushTaskITCase.java
@@ -78,7 +78,8 @@ public class PushTaskITCase extends AbstractTaskITCase {
 
     @Test
     public void list() {
-        final PagedResult<PushTaskTO> tasks = taskService.list(TaskType.PUSH);
+        PagedResult<PushTaskTO> tasks = taskService.list(
+                TaskType.PUSH, SyncopeClient.getListQueryBuilder().build());
         assertFalse(tasks.getResult().isEmpty());
         for (AbstractTaskTO task : tasks.getResult()) {
             if (!(task instanceof PushTaskTO)) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/bc2afa9a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java
index 78ab74f..2199bc8 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java
@@ -30,6 +30,7 @@ import java.util.List;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response;
 import org.apache.commons.io.IOUtils;
+import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.report.UserReportletConf;
@@ -62,7 +63,7 @@ public class ReportITCase extends AbstractITCase {
 
     @Test
     public void list() {
-        PagedResult<ReportTO> reports = reportService.list();
+        PagedResult<ReportTO> reports = 
reportService.list(SyncopeClient.getListQueryBuilder().build());
         assertNotNull(reports);
         assertFalse(reports.getResult().isEmpty());
         for (ReportTO report : reports.getResult()) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/bc2afa9a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
index 2068704..437bca5 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
@@ -26,6 +26,7 @@ import static org.junit.Assert.fail;
 
 import java.util.List;
 import javax.ws.rs.core.Response;
+import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.to.AbstractTaskTO;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.PushTaskTO;
@@ -50,7 +51,8 @@ public class SchedTaskITCase extends AbstractTaskITCase {
 
     @Test
     public void list() {
-        final PagedResult<SchedTaskTO> tasks = 
taskService.list(TaskType.SCHEDULED);
+        PagedResult<SchedTaskTO> tasks =
+                taskService.list(TaskType.SCHEDULED, 
SyncopeClient.getListQueryBuilder().build());
         assertFalse(tasks.getResult().isEmpty());
         for (AbstractTaskTO task : tasks.getResult()) {
             if (!(task instanceof SchedTaskTO) || task instanceof SyncTaskTO 
|| task instanceof PushTaskTO) {
@@ -64,7 +66,7 @@ public class SchedTaskITCase extends AbstractTaskITCase {
         SchedTaskTO task = taskService.read(SCHED_TASK_ID);
         assertNotNull(task);
 
-        final SchedTaskTO taskMod = new SchedTaskTO();
+        SchedTaskTO taskMod = new SchedTaskTO();
         taskMod.setKey(5);
         taskMod.setCronExpression(null);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/bc2afa9a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
index 7cd72db..b17d7f3 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SearchITCase.java
@@ -23,12 +23,12 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.Collection;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.CollectionUtils2;
+import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
@@ -43,9 +43,9 @@ public class SearchITCase extends AbstractITCase {
     public void searchUser() {
         // LIKE
         PagedResult<UserTO> matchedUsers = userService.search(
-                Collections.singletonList("/"),
-                SyncopeClient.getUserSearchConditionBuilder().
-                
is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query());
+                
SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().
+                        
is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query()).build());
         assertNotNull(matchedUsers);
         assertFalse(matchedUsers.getResult().isEmpty());
 
@@ -55,25 +55,27 @@ public class SearchITCase extends AbstractITCase {
 
         // ISNULL
         matchedUsers = userService.search(
-                Collections.singletonList("/"),
-                
SyncopeClient.getUserSearchConditionBuilder().isNull("loginDate").query());
+                
SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                
fiql(SyncopeClient.getUserSearchConditionBuilder().isNull("loginDate").query()).build());
         assertNotNull(matchedUsers);
         assertFalse(matchedUsers.getResult().isEmpty());
 
-        Set<Long> userIds = new HashSet<Long>(matchedUsers.getResult().size());
-        for (UserTO user : matchedUsers.getResult()) {
-            userIds.add(user.getKey());
-        }
-        assertTrue(userIds.contains(2L));
-        assertTrue(userIds.contains(3L));
+        Collection<UserTO> found = 
CollectionUtils2.find(matchedUsers.getResult(), new Predicate<UserTO>() {
+
+            @Override
+            public boolean evaluate(final UserTO user) {
+                return user.getKey() == 2L || user.getKey() == 3L;
+            }
+        });
+        assertEquals(2, found.size());
     }
 
     @Test
     public void searchByUsernameAndKey() {
-        final PagedResult<UserTO> matchingUsers = userService.search(
-                Collections.singletonList("/"),
-                SyncopeClient.getUserSearchConditionBuilder().
-                
is("username").equalTo("rossini").and("key").lessThan(2).query());
+        PagedResult<UserTO> matchingUsers = userService.search(
+                
SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().
+                        
is("username").equalTo("rossini").and("key").lessThan(2).query()).build());
         assertNotNull(matchingUsers);
         assertEquals(1, matchingUsers.getResult().size());
         assertEquals("rossini", 
matchingUsers.getResult().iterator().next().getUsername());
@@ -82,10 +84,10 @@ public class SearchITCase extends AbstractITCase {
 
     @Test
     public void searchByGroupNameAndKey() {
-        final PagedResult<GroupTO> matchingGroups = groupService.search(
-                Collections.singletonList("/"),
-                SyncopeClient.getGroupSearchConditionBuilder().
-                is("name").equalTo("root").and("key").lessThan(2).query());
+        PagedResult<GroupTO> matchingGroups = groupService.search(
+                
SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().
+                        
is("name").equalTo("root").and("key").lessThan(2).query()).build());
         assertNotNull(matchingGroups);
         assertEquals(1, matchingGroups.getResult().size());
         assertEquals("root", 
matchingGroups.getResult().iterator().next().getName());
@@ -95,8 +97,9 @@ public class SearchITCase extends AbstractITCase {
     @Test
     public void searchUserByResourceName() {
         PagedResult<UserTO> matchedUsers = userService.search(
-                Collections.singletonList("/"),
-                
SyncopeClient.getUserSearchConditionBuilder().hasResources(RESOURCE_NAME_MAPPINGS2).query());
+                
SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                
fiql(SyncopeClient.getUserSearchConditionBuilder().hasResources(RESOURCE_NAME_MAPPINGS2).query()).
+                build());
         assertNotNull(matchedUsers);
         assertFalse(matchedUsers.getResult().isEmpty());
 
@@ -113,9 +116,9 @@ public class SearchITCase extends AbstractITCase {
     public void paginatedSearch() {
         // LIKE
         PagedResult<UserTO> matchingUsers = userService.search(
-                Collections.singletonList("/"),
-                SyncopeClient.getUserSearchConditionBuilder().
-                
is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query(), 1, 2);
+                
SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getUserSearchConditionBuilder().
+                        
is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query()).page(1).size(2).build());
         assertNotNull(matchingUsers);
 
         assertFalse(matchingUsers.getResult().isEmpty());
@@ -125,27 +128,28 @@ public class SearchITCase extends AbstractITCase {
 
         // ISNULL
         matchingUsers = userService.search(
-                Collections.singletonList("/"),
-                
SyncopeClient.getUserSearchConditionBuilder().isNull("loginDate").query(), 1, 
2);
+                
SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                
fiql(SyncopeClient.getUserSearchConditionBuilder().isNull("loginDate").query()).page(2).size(2).
+                build());
         assertNotNull(matchingUsers);
-        assertFalse(matchingUsers.getResult().isEmpty());
+        assertEquals(2, matchingUsers.getPage());
         assertEquals(2, matchingUsers.getResult().size());
     }
 
     @Test
     public void searchByBooleanSubjectCond() {
-        final PagedResult<GroupTO> matchingGroups = groupService.search(
-                Collections.singletonList("/"),
-                
SyncopeClient.getGroupSearchConditionBuilder().is("show").equalTo("true").query());
+        PagedResult<GroupTO> matchingGroups = groupService.search(
+                
SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                
fiql(SyncopeClient.getGroupSearchConditionBuilder().is("show").equalTo("true").query()).build());
         assertNotNull(matchingGroups);
         assertFalse(matchingGroups.getResult().isEmpty());
     }
 
     @Test
     public void searchByRelationshipSubjectCond() {
-        final PagedResult<GroupTO> matchingGroups = groupService.search(
-                Collections.singletonList("/"),
-                
SyncopeClient.getGroupSearchConditionBuilder().is("userOwner").equalTo(5).query());
+        PagedResult<GroupTO> matchingGroups = groupService.search(
+                
SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                
fiql(SyncopeClient.getGroupSearchConditionBuilder().is("userOwner").equalTo(5).query()).build());
         assertNotNull(matchingGroups);
         assertEquals(1, matchingGroups.getResult().size());
         assertEquals(6L, 
matchingGroups.getResult().iterator().next().getKey());
@@ -154,8 +158,8 @@ public class SearchITCase extends AbstractITCase {
     @Test
     public void nested() {
         PagedResult<UserTO> matchedUsers = userService.search(
-                Collections.singletonList("/"),
-                
"((fullname==*o*,fullname==*i*);$resources!=ws-target-resource-1)", 1, 2);
+                
SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                
fiql("((fullname==*o*,fullname==*i*);$resources!=ws-target-resource-1)").page(1).size(2).build());
         assertNotNull(matchedUsers);
 
         assertFalse(matchedUsers.getResult().isEmpty());
@@ -167,9 +171,9 @@ public class SearchITCase extends AbstractITCase {
     @Test
     public void orderBy() {
         PagedResult<UserTO> matchedUsers = userService.search(
-                Collections.singletonList("/"),
-                
SyncopeClient.getUserSearchConditionBuilder().is("userId").equalTo("*@apache.org").query(),
-                
SyncopeClient.getOrderByClauseBuilder().asc("status").desc("firstname").build());
+                
SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                
fiql(SyncopeClient.getUserSearchConditionBuilder().is("userId").equalTo("*@apache.org").query()).
+                
orderBy(SyncopeClient.getOrderByClauseBuilder().asc("status").desc("firstname").build()).build());
         assertNotNull(matchedUsers);
 
         assertFalse(matchedUsers.getResult().isEmpty());

http://git-wip-us.apache.org/repos/asf/syncope/blob/bc2afa9a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
index f0e9920..7fd817a 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SyncTaskITCase.java
@@ -25,7 +25,6 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -87,7 +86,8 @@ public class SyncTaskITCase extends AbstractTaskITCase {
 
     @Test
     public void list() {
-        final PagedResult<SyncTaskTO> tasks = 
taskService.list(TaskType.SYNCHRONIZATION);
+        PagedResult<SyncTaskTO> tasks =
+                taskService.list(TaskType.SYNCHRONIZATION, 
SyncopeClient.getListQueryBuilder().build());
         assertFalse(tasks.getResult().isEmpty());
         for (AbstractTaskTO task : tasks.getResult()) {
             if (!(task instanceof SyncTaskTO)) {
@@ -153,7 +153,9 @@ public class SyncTaskITCase extends AbstractTaskITCase {
 
         // -----------------------------
         try {
-            int usersPre = userService.list(Collections.singletonList("/"), 1, 
1).getTotalCount();
+            int usersPre = userService.list(
+                    
SyncopeClient.getSubjectListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                    page(1).size(1).build()).getTotalCount();
             assertNotNull(usersPre);
 
             execSyncTask(SYNC_TASK_ID, 50, false);
@@ -200,7 +202,9 @@ public class SyncTaskITCase extends AbstractTaskITCase {
             assertEquals("TYPE_8", 
userTO.getPlainAttrMap().get("type").getValues().get(0));
 
             // check for sync results
-            int usersPost = userService.list(Collections.singletonList("/"), 
1, 1).getTotalCount();
+            int usersPost = userService.list(
+                    
SyncopeClient.getSubjectListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                    page(1).size(1).build()).getTotalCount();
             assertNotNull(usersPost);
             assertEquals(usersPre + 9, usersPost);
 
@@ -269,8 +273,9 @@ public class SyncTaskITCase extends AbstractTaskITCase {
      */
     private void ldapCleanup() {
         PagedResult<GroupTO> matchingGroups = groupService.search(
-                Collections.singletonList("/"),
-                
SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query());
+                
SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                
fiql(SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query()).
+                build());
         if (matchingGroups.getSize() > 0) {
             for (GroupTO group : matchingGroups.getResult()) {
                 groupService.bulkDeassociation(group.getKey(),
@@ -280,8 +285,9 @@ public class SyncTaskITCase extends AbstractTaskITCase {
             }
         }
         PagedResult<UserTO> matchingUsers = userService.search(
-                Collections.singletonList("/"),
-                
SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query());
+                
SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                
fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query()).
+                build());
         if (matchingUsers.getSize() > 0) {
             for (UserTO user : matchingUsers.getResult()) {
                 userService.bulkDeassociation(user.getKey(),
@@ -301,20 +307,22 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         TaskExecTO execution = execSyncTask(11L, 50, false);
 
         // 1. verify execution status
-        final String status = execution.getStatus();
+        String status = execution.getStatus();
         assertNotNull(status);
         assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
 
         // 2. verify that synchronized group is found, with expected attributes
-        final PagedResult<GroupTO> matchingGroups = groupService.search(
-                Collections.singletonList("/"),
-                
SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query());
+        PagedResult<GroupTO> matchingGroups = groupService.search(
+                
SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                
fiql(SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query()).
+                build());
         assertNotNull(matchingGroups);
         assertEquals(1, matchingGroups.getResult().size());
 
-        final PagedResult<UserTO> matchingUsers = userService.search(
-                Collections.singletonList("/"),
-                
SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query());
+        PagedResult<UserTO> matchingUsers = userService.search(
+                
SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                
fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query()).
+                build());
         assertNotNull(matchingUsers);
         assertEquals(1, matchingUsers.getResult().size());
 
@@ -334,9 +342,9 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         assertNull(groupTO.getGroupOwner());
 
         // 3. verify that LDAP group membership is propagated as Syncope group 
membership
-        final PagedResult<UserTO> members = userService.search(
-                Collections.singletonList("/"),
-                
SyncopeClient.getUserSearchConditionBuilder().inGroups(groupTO.getKey()).query());
+        PagedResult<UserTO> members = userService.search(
+                
SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                
fiql(SyncopeClient.getUserSearchConditionBuilder().inGroups(groupTO.getKey()).query()).build());
         assertNotNull(members);
         assertEquals(1, members.getResult().size());
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/bc2afa9a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
index 723a10a..43f0ffb 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
@@ -128,10 +128,11 @@ public class UserITCase extends AbstractITCase {
     }
 
     @Test
-    @SuppressWarnings("unchecked")
     public void createUserWithNoPropagation() {
         // get task list
-        PagedResult<PropagationTaskTO> tasks = 
taskService.list(TaskType.PROPAGATION, 1, 1);
+        PagedResult<PropagationTaskTO> tasks = taskService.list(
+                TaskType.PROPAGATION,
+                SyncopeClient.getListQueryBuilder().page(1).size(1).build());
         assertNotNull(tasks);
         assertFalse(tasks.getResult().isEmpty());
 
@@ -146,7 +147,9 @@ public class UserITCase extends AbstractITCase {
         createUser(userTO);
 
         // get the new task list
-        tasks = taskService.list(TaskType.PROPAGATION, 1, 1);
+        tasks = taskService.list(
+                TaskType.PROPAGATION,
+                SyncopeClient.getListQueryBuilder().page(1).size(1).build());
         assertNotNull(tasks);
         assertFalse(tasks.getResult().isEmpty());
 
@@ -327,7 +330,9 @@ public class UserITCase extends AbstractITCase {
     @Test
     public void create() {
         // get task list
-        PagedResult<PropagationTaskTO> tasks = 
taskService.list(TaskType.PROPAGATION, 1, 1);
+        PagedResult<PropagationTaskTO> tasks = taskService.list(
+                TaskType.PROPAGATION,
+                SyncopeClient.getListQueryBuilder().page(1).size(1).build());
         assertNotNull(tasks);
         assertFalse(tasks.getResult().isEmpty());
 
@@ -381,7 +386,9 @@ public class UserITCase extends AbstractITCase {
         assertEquals("virtualvalue", 
newUserTO.getVirAttrMap().get("virtualdata").getValues().get(0));
 
         // get the new task list
-        tasks = taskService.list(TaskType.PROPAGATION, 1, 1);
+        tasks = taskService.list(
+                TaskType.PROPAGATION,
+                SyncopeClient.getListQueryBuilder().page(1).size(1).build());
         assertNotNull(tasks);
         assertFalse(tasks.getResult().isEmpty());
 
@@ -527,7 +534,8 @@ public class UserITCase extends AbstractITCase {
 
     @Test
     public void list() {
-        PagedResult<UserTO> users = 
userService.list(Collections.singletonList("/"));
+        PagedResult<UserTO> users = userService.list(
+                
SyncopeClient.getSubjectListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).build());
         assertNotNull(users);
         assertFalse(users.getResult().isEmpty());
 
@@ -538,7 +546,8 @@ public class UserITCase extends AbstractITCase {
 
     @Test
     public void paginatedList() {
-        PagedResult<UserTO> users = 
userService.list(Collections.singletonList("/"), 1, 2);
+        PagedResult<UserTO> users = userService.list(
+                
SyncopeClient.getSubjectListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).page(1).size(2).build());
         assertNotNull(users);
         assertFalse(users.getResult().isEmpty());
         assertEquals(2, users.getResult().size());
@@ -547,12 +556,14 @@ public class UserITCase extends AbstractITCase {
             assertNotNull(user);
         }
 
-        users = userService.list(Collections.singletonList("/"), 2, 2);
+        users = 
userService.list(SyncopeClient.getSubjectListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                page(2).size(2).build());
         assertNotNull(users);
-        assertFalse(users.getResult().isEmpty());
+        assertEquals(2, users.getPage());
         assertEquals(2, users.getResult().size());
 
-        users = userService.list(Collections.singletonList("/"), 100, 2);
+        users = 
userService.list(SyncopeClient.getSubjectListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                page(100).size(2).build());
         assertNotNull(users);
         assertTrue(users.getResult().isEmpty());
     }
@@ -678,7 +689,8 @@ public class UserITCase extends AbstractITCase {
 
     @Test
     public void updatePasswordOnly() {
-        int beforeTasks = taskService.list(TaskType.PROPAGATION, 1, 
1).getTotalCount();
+        int beforeTasks = taskService.list(TaskType.PROPAGATION,
+                
SyncopeClient.getListQueryBuilder().page(1).size(1).build()).getTotalCount();
         assertFalse(beforeTasks <= 0);
 
         UserTO userTO = getUniqueSampleTO("pwdo...@t.com");
@@ -698,7 +710,8 @@ public class UserITCase extends AbstractITCase {
         // check for changePwdDate
         assertNotNull(userTO.getChangePwdDate());
 
-        int afterTasks = taskService.list(TaskType.PROPAGATION, 1, 
1).getTotalCount();
+        int afterTasks = taskService.list(TaskType.PROPAGATION,
+                
SyncopeClient.getListQueryBuilder().page(1).size(1).build()).getTotalCount();
         assertFalse(beforeTasks <= 0);
 
         assertTrue(beforeTasks < afterTasks);
@@ -708,7 +721,9 @@ public class UserITCase extends AbstractITCase {
     @Test
     public void verifyTaskRegistration() {
         // get task list
-        PagedResult<PropagationTaskTO> tasks = 
taskService.list(TaskType.PROPAGATION, 1, 1);
+        PagedResult<PropagationTaskTO> tasks = taskService.list(
+                TaskType.PROPAGATION,
+                SyncopeClient.getListQueryBuilder().page(1).size(1).build());
         assertNotNull(tasks);
         assertFalse(tasks.getResult().isEmpty());
 
@@ -729,7 +744,9 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(userTO);
 
         // get the new task list
-        tasks = taskService.list(TaskType.PROPAGATION, 1, 1);
+        tasks = taskService.list(
+                TaskType.PROPAGATION,
+                SyncopeClient.getListQueryBuilder().page(1).size(1).build());
         assertNotNull(tasks);
         assertFalse(tasks.getResult().isEmpty());
 
@@ -753,7 +770,9 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(userTO);
 
         // get the new task list
-        tasks = taskService.list(TaskType.PROPAGATION, 1, 1);
+        tasks = taskService.list(
+                TaskType.PROPAGATION,
+                SyncopeClient.getListQueryBuilder().page(1).size(1).build());
 
         maxKey = newMaxKey;
         newMaxKey = tasks.getResult().iterator().next().getKey();
@@ -773,7 +792,9 @@ public class UserITCase extends AbstractITCase {
         userService.delete(userTO.getKey());
 
         // get the new task list
-        tasks = taskService.list(TaskType.PROPAGATION, 1, 1);
+        tasks = taskService.list(
+                TaskType.PROPAGATION,
+                SyncopeClient.getListQueryBuilder().page(1).size(1).build());
 
         maxKey = newMaxKey;
         newMaxKey = tasks.getResult().iterator().next().getKey();

Reply via email to