You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2020/03/23 10:41:14 UTC

[syncope] 01/05: Enhance SearchConditionBuilder features

This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git

commit bd5bb0583784b8a36bb1815749adffc02d15bc88
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Mon Mar 23 11:23:45 2020 +0100

    Enhance SearchConditionBuilder features
---
 .../search/AbstractFiqlSearchConditionBuilder.java | 112 ++++++++++++++++-----
 ...operty.java => AnyObjectCompleteCondition.java} |  11 +-
 .../AnyObjectFiqlSearchConditionBuilder.java       |  37 +++----
 ...roperty.java => AnyObjectPartialCondition.java} |  11 +-
 .../common/lib/search/AnyObjectProperty.java       |  19 ++--
 ...rty.java => ConnObjectTOCompleteCondition.java} |  11 +-
 .../ConnObjectTOFiqlSearchConditionBuilder.java    |  33 ++----
 ...erty.java => ConnObjectTOPartialCondition.java} |  11 +-
 ...roupProperty.java => ConnObjectTOProperty.java} |  10 +-
 ...upProperty.java => GroupCompleteCondition.java} |  10 +-
 .../search/GroupFiqlSearchConditionBuilder.java    |  21 ++--
 ...oupProperty.java => GroupPartialCondition.java} |  10 +-
 .../syncope/common/lib/search/GroupProperty.java   |  10 +-
 ...Property.java => SyncopeCompleteCondition.java} |  15 ++-
 ...tProperty.java => SyncopePartialCondition.java} |  25 +++--
 .../syncope/common/lib/search/SyncopeProperty.java |  22 ++--
 ...oupProperty.java => UserCompleteCondition.java} |  10 +-
 .../lib/search/UserFiqlSearchConditionBuilder.java |  49 ++++-----
 ...roupProperty.java => UserPartialCondition.java} |  10 +-
 .../syncope/common/lib/search/UserProperty.java    |  25 ++---
 .../api/search/FilterConverterTest.java            |  29 ------
 21 files changed, 222 insertions(+), 269 deletions(-)

diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java
index 5f8aa43..b16d652 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java
@@ -20,13 +20,18 @@ package org.apache.syncope.common.lib.search;
 
 import java.io.Serializable;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import org.apache.cxf.jaxrs.ext.search.SearchUtils;
 import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
 import org.apache.cxf.jaxrs.ext.search.client.FiqlSearchConditionBuilder;
 import org.apache.cxf.jaxrs.ext.search.fiql.FiqlParser;
 
-public abstract class AbstractFiqlSearchConditionBuilder extends FiqlSearchConditionBuilder implements Serializable {
+public abstract class AbstractFiqlSearchConditionBuilder<
+        P extends SyncopeProperty<C>,
+        PA extends SyncopePartialCondition<P, C>, 
+        C extends SyncopeCompleteCondition<PA, P>>
+        extends FiqlSearchConditionBuilder implements Serializable {
 
     private static final long serialVersionUID = 9043884238032703381L;
 
@@ -48,103 +53,162 @@ public abstract class AbstractFiqlSearchConditionBuilder extends FiqlSearchCondi
     }
 
     @Override
-    protected Builder newBuilderInstance() {
-        return new Builder(properties);
+    protected Builder<P, PA, C> newBuilderInstance() {
+        return new Builder<>(properties);
     }
 
     @Override
-    public SyncopeProperty is(final String property) {
+    public P is(final String property) {
         return newBuilderInstance().is(property);
     }
 
-    public CompleteCondition isNull(final String property) {
+    public C isNull(final String property) {
         return newBuilderInstance().is(property).nullValue();
     }
 
-    public CompleteCondition isNotNull(final String property) {
+    public C isNotNull(final String property) {
         return newBuilderInstance().is(property).notNullValue();
     }
 
-    public CompleteCondition inDynRealms(final String dynRealm, final String... moreDynRealms) {
+    public C inDynRealms(final String dynRealm, final String... moreDynRealms) {
         return newBuilderInstance().
                 is(SpecialAttr.DYNREALMS.toString()).
                 inDynRealms(dynRealm, moreDynRealms);
     }
 
-    public CompleteCondition notInDynRealms(final String dynRealm, final String... moreDynRealms) {
+    public C notInDynRealms(final String dynRealm, final String... moreDynRealms) {
         return newBuilderInstance().
                 is(SpecialAttr.DYNREALMS.toString()).
                 notInDynRealms(dynRealm, moreDynRealms);
     }
 
-    public CompleteCondition hasResources(final String resource, final String... moreResources) {
+    public C hasResources(final String resource, final String... moreResources) {
         return newBuilderInstance().is(SpecialAttr.RESOURCES.toString()).hasResources(resource, moreResources);
     }
 
-    public CompleteCondition hasNotResources(final String resource, final String... moreResources) {
+    public C hasNotResources(final String resource, final String... moreResources) {
         return newBuilderInstance().is(SpecialAttr.RESOURCES.toString()).hasNotResources(resource, moreResources);
     }
 
-    protected static class Builder extends FiqlSearchConditionBuilder.Builder
-            implements SyncopeProperty, CompleteCondition {
+    @SuppressWarnings("unchecked")
+    protected static class Builder<
+            P extends SyncopeProperty<C>,
+            PA extends SyncopePartialCondition<P, C>,
+            C extends SyncopeCompleteCondition<PA, P>>
+            extends FiqlSearchConditionBuilder.Builder
+            implements SyncopeProperty<C>, SyncopeCompleteCondition<PA, P>, SyncopePartialCondition<P, C> {
 
         protected Builder(final Map<String, String> properties) {
             super(properties);
         }
 
-        protected Builder(final Builder parent) {
+        protected Builder(final Builder<P, PA, C> parent) {
             super(parent);
         }
 
         @Override
-        public SyncopeProperty is(final String property) {
-            Builder b = new Builder(this);
+        public P is(final String property) {
+            Builder<P, PA, C> b = new Builder<>(this);
             b.result = property;
-            return b;
+            return (P) b;
         }
 
         @Override
-        public CompleteCondition nullValue() {
+        protected C condition(
+                final String operator, final Object value, final Object... moreValues) {
+
+            super.condition(operator, value, moreValues);
+            return (C) this;
+        }
+
+        @Override
+        public C nullValue() {
             return condition(FiqlParser.EQ, SpecialAttr.NULL);
         }
 
         @Override
-        public CompleteCondition notNullValue() {
+        public C notNullValue() {
             return condition(FiqlParser.NEQ, SpecialAttr.NULL);
         }
 
         @Override
-        public CompleteCondition hasResources(final String resource, final String... moreResources) {
+        public C hasResources(final String resource, final String... moreResources) {
             this.result = SpecialAttr.RESOURCES.toString();
             return condition(FiqlParser.EQ, resource, (Object[]) moreResources);
         }
 
         @Override
-        public CompleteCondition hasNotResources(final String resource, final String... moreResources) {
+        public C hasNotResources(final String resource, final String... moreResources) {
             this.result = SpecialAttr.RESOURCES.toString();
             return condition(FiqlParser.NEQ, resource, (Object[]) moreResources);
         }
 
         @Override
-        public CompleteCondition equalToIgnoreCase(final String value, final String... moreValues) {
+        public C equalToIgnoreCase(final String value, final String... moreValues) {
             return condition(SyncopeFiqlParser.IEQ, value, (Object[]) moreValues);
         }
 
         @Override
-        public CompleteCondition notEqualTolIgnoreCase(final String literalOrPattern) {
+        public C notEqualTolIgnoreCase(final String literalOrPattern) {
             return condition(SyncopeFiqlParser.NIEQ, literalOrPattern);
         }
 
         @Override
-        public CompleteCondition inDynRealms(final String dynRealm, final String... moreDynRealms) {
+        public C inDynRealms(final String dynRealm, final String... moreDynRealms) {
             this.result = SpecialAttr.DYNREALMS.toString();
             return condition(FiqlParser.EQ, dynRealm, (Object[]) moreDynRealms);
         }
 
         @Override
-        public CompleteCondition notInDynRealms(final String dynRealm, final String... moreDynRealms) {
+        public C notInDynRealms(final String dynRealm, final String... moreDynRealms) {
             this.result = SpecialAttr.DYNREALMS.toString();
             return condition(FiqlParser.NEQ, dynRealm, (Object[]) moreDynRealms);
         }
+
+        @Override
+        public PA and() {
+            super.and();
+            return (PA) this;
+        }
+
+        @Override
+        public P and(final String name) {
+            return and().is(name);
+        }
+
+        @Override
+        public PA or() {
+            super.or();
+            return (PA) this;
+        }
+
+        @Override
+        public P or(final String name) {
+            return or().is(name);
+        }
+
+        @Override
+        public C and(final CompleteCondition cc, final CompleteCondition cc1, final CompleteCondition... cn) {
+            super.and(cc1, cc, cn);
+            return (C) this;
+        }
+
+        @Override
+        public C or(final CompleteCondition cc, final CompleteCondition cc1, final CompleteCondition... cn) {
+            super.or(cc1, cc, cn);
+            return (C) this;
+        }
+
+        @Override
+        public C and(final List<CompleteCondition> conditions) {
+            super.and(conditions);
+            return (C) this;
+        }
+
+        @Override
+        public C or(final List<CompleteCondition> conditions) {
+            super.or(conditions);
+            return (C) this;
+        }
     }
 }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectCompleteCondition.java
similarity index 73%
copy from common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
copy to common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectCompleteCondition.java
index 0325a72..d0002ac 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectCompleteCondition.java
@@ -18,13 +18,6 @@
  */
 package org.apache.syncope.common.lib.search;
 
-import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
-
-public interface GroupProperty extends SyncopeProperty {
-
-    CompleteCondition isAssignable();
-
-    CompleteCondition withMembers(String member, String... moreMembers);
-
-    CompleteCondition withoutMembers(String member, String... moreMembers);
+public interface AnyObjectCompleteCondition
+        extends SyncopeCompleteCondition<AnyObjectPartialCondition, AnyObjectProperty> {
 }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectFiqlSearchConditionBuilder.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectFiqlSearchConditionBuilder.java
index b497c7b..c2d8895 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectFiqlSearchConditionBuilder.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectFiqlSearchConditionBuilder.java
@@ -20,7 +20,6 @@ package org.apache.syncope.common.lib.search;
 
 import java.util.Collections;
 import java.util.Map;
-import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
 import org.apache.cxf.jaxrs.ext.search.client.FiqlSearchConditionBuilder;
 import org.apache.cxf.jaxrs.ext.search.fiql.FiqlParser;
 
@@ -28,7 +27,8 @@ import org.apache.cxf.jaxrs.ext.search.fiql.FiqlParser;
  * Extends {@link AbstractFiqlSearchConditionBuilder} by providing some additional facilities for searching
  * any objects in Syncope.
  */
-public class AnyObjectFiqlSearchConditionBuilder extends AbstractFiqlSearchConditionBuilder {
+public class AnyObjectFiqlSearchConditionBuilder extends AbstractFiqlSearchConditionBuilder<
+        AnyObjectProperty, AnyObjectPartialCondition, AnyObjectCompleteCondition> {
 
     private static final long serialVersionUID = -3248603004632741935L;
 
@@ -55,50 +55,51 @@ public class AnyObjectFiqlSearchConditionBuilder extends AbstractFiqlSearchCondi
         return newBuilderInstance().is(property);
     }
 
-    public CompleteCondition inGroups(final String group, final String... moreGroups) {
+    public AnyObjectCompleteCondition inGroups(final String group, final String... moreGroups) {
         return newBuilderInstance().
                 is(SpecialAttr.GROUPS.toString()).
                 inGroups(group, moreGroups);
     }
 
-    public CompleteCondition notInGroups(final String group, final String... moreGroups) {
+    public AnyObjectCompleteCondition notInGroups(final String group, final String... moreGroups) {
         return newBuilderInstance().
                 is(SpecialAttr.GROUPS.toString()).
                 notInGroups(group, moreGroups);
     }
 
-    public CompleteCondition inRelationships(final String anyType, final String... moreAnyTypes) {
+    public AnyObjectCompleteCondition inRelationships(final String anyType, final String... moreAnyTypes) {
         return newBuilderInstance().
                 is(SpecialAttr.RELATIONSHIPS.toString()).
                 inRelationships(anyType, moreAnyTypes);
     }
 
-    public CompleteCondition notInRelationships(final String anyType, final String... moreAnyTypes) {
+    public AnyObjectCompleteCondition notInRelationships(final String anyType, final String... moreAnyTypes) {
         return newBuilderInstance().
                 is(SpecialAttr.RELATIONSHIPS.toString()).
                 notInRelationships(anyType, moreAnyTypes);
     }
 
-    public CompleteCondition inRelationshipTypes(final String type, final String... moreTypes) {
+    public AnyObjectCompleteCondition inRelationshipTypes(final String type, final String... moreTypes) {
         return newBuilderInstance().
                 is(SpecialAttr.RELATIONSHIP_TYPES.toString()).
                 inRelationshipTypes(type, moreTypes);
     }
 
-    public CompleteCondition notInRelationshipTypes(final String type, final String... moreTypes) {
+    public AnyObjectCompleteCondition notInRelationshipTypes(final String type, final String... moreTypes) {
         return newBuilderInstance().
                 is(SpecialAttr.RELATIONSHIP_TYPES.toString()).
                 notInRelationshipTypes(type, moreTypes);
     }
 
-    public CompleteCondition isAssignable() {
+    public AnyObjectCompleteCondition isAssignable() {
         return newBuilderInstance().
                 is(SpecialAttr.ASSIGNABLE.toString()).
                 isAssignable();
     }
 
-    protected class Builder extends AbstractFiqlSearchConditionBuilder.Builder
-            implements AnyObjectProperty, CompleteCondition {
+    protected class Builder extends AbstractFiqlSearchConditionBuilder.Builder<
+            AnyObjectProperty, AnyObjectPartialCondition, AnyObjectCompleteCondition>
+            implements AnyObjectProperty, AnyObjectPartialCondition, AnyObjectCompleteCondition {
 
         public Builder(final Map<String, String> properties) {
             super(properties);
@@ -122,43 +123,43 @@ public class AnyObjectFiqlSearchConditionBuilder extends AbstractFiqlSearchCondi
         }
 
         @Override
-        public CompleteCondition inGroups(final String group, final String... moreGroups) {
+        public AnyObjectCompleteCondition inGroups(final String group, final String... moreGroups) {
             this.result = SpecialAttr.GROUPS.toString();
             return condition(FiqlParser.EQ, group, (Object[]) moreGroups);
         }
 
         @Override
-        public CompleteCondition notInGroups(final String group, final String... moreGroups) {
+        public AnyObjectCompleteCondition notInGroups(final String group, final String... moreGroups) {
             this.result = SpecialAttr.GROUPS.toString();
             return condition(FiqlParser.NEQ, group, (Object[]) moreGroups);
         }
 
         @Override
-        public CompleteCondition inRelationships(final String anyObject, final String... moreAnyObjects) {
+        public AnyObjectCompleteCondition inRelationships(final String anyObject, final String... moreAnyObjects) {
             this.result = SpecialAttr.RELATIONSHIPS.toString();
             return condition(FiqlParser.EQ, anyObject, (Object[]) moreAnyObjects);
         }
 
         @Override
-        public CompleteCondition notInRelationships(final String group, final String... moreRelationships) {
+        public AnyObjectCompleteCondition notInRelationships(final String group, final String... moreRelationships) {
             this.result = SpecialAttr.RELATIONSHIPS.toString();
             return condition(FiqlParser.NEQ, group, (Object[]) moreRelationships);
         }
 
         @Override
-        public CompleteCondition inRelationshipTypes(final String type, final String... moreTypes) {
+        public AnyObjectCompleteCondition inRelationshipTypes(final String type, final String... moreTypes) {
             this.result = SpecialAttr.RELATIONSHIP_TYPES.toString();
             return condition(FiqlParser.EQ, type, (Object[]) moreTypes);
         }
 
         @Override
-        public CompleteCondition notInRelationshipTypes(final String type, final String... moreTypes) {
+        public AnyObjectCompleteCondition notInRelationshipTypes(final String type, final String... moreTypes) {
             this.result = SpecialAttr.RELATIONSHIP_TYPES.toString();
             return condition(FiqlParser.NEQ, type, (Object[]) moreTypes);
         }
 
         @Override
-        public CompleteCondition isAssignable() {
+        public AnyObjectCompleteCondition isAssignable() {
             this.result = SpecialAttr.ASSIGNABLE.toString();
             return condition(FiqlParser.EQ, SpecialAttr.NULL);
         }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectPartialCondition.java
similarity index 73%
copy from common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
copy to common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectPartialCondition.java
index 0325a72..ab76fbe 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectPartialCondition.java
@@ -18,13 +18,6 @@
  */
 package org.apache.syncope.common.lib.search;
 
-import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
-
-public interface GroupProperty extends SyncopeProperty {
-
-    CompleteCondition isAssignable();
-
-    CompleteCondition withMembers(String member, String... moreMembers);
-
-    CompleteCondition withoutMembers(String member, String... moreMembers);
+public interface AnyObjectPartialCondition
+        extends SyncopePartialCondition<AnyObjectProperty, AnyObjectCompleteCondition> {
 }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectProperty.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectProperty.java
index 9d32013..24cd943 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectProperty.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectProperty.java
@@ -18,22 +18,19 @@
  */
 package org.apache.syncope.common.lib.search;
 
-import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
+public interface AnyObjectProperty extends SyncopeProperty<AnyObjectCompleteCondition> {
 
-public interface AnyObjectProperty extends SyncopeProperty {
+    AnyObjectCompleteCondition inGroups(String group, String... moreGroups);
 
-    CompleteCondition inGroups(String group, String... moreGroups);
+    AnyObjectCompleteCondition notInGroups(String group, String... moreGroups);
 
-    CompleteCondition notInGroups(String group, String... moreGroups);
+    AnyObjectCompleteCondition inRelationships(String anyObject, String... moreAnyObjects);
 
-    CompleteCondition inRelationships(String anyObject, String... moreAnyObjects);
+    AnyObjectCompleteCondition notInRelationships(String anyObject, String... moreAnyObjects);
 
-    CompleteCondition notInRelationships(String anyObject, String... moreAnyObjects);
+    AnyObjectCompleteCondition inRelationshipTypes(String type, String... moreTypes);
 
-    CompleteCondition inRelationshipTypes(String type, String... moreTypes);
-
-    CompleteCondition notInRelationshipTypes(String type, String... moreTypes);
-
-    CompleteCondition isAssignable();
+    AnyObjectCompleteCondition notInRelationshipTypes(String type, String... moreTypes);
 
+    AnyObjectCompleteCondition isAssignable();
 }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/ConnObjectTOCompleteCondition.java
similarity index 73%
copy from common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
copy to common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/ConnObjectTOCompleteCondition.java
index 0325a72..a8b18ba 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/ConnObjectTOCompleteCondition.java
@@ -18,13 +18,6 @@
  */
 package org.apache.syncope.common.lib.search;
 
-import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
-
-public interface GroupProperty extends SyncopeProperty {
-
-    CompleteCondition isAssignable();
-
-    CompleteCondition withMembers(String member, String... moreMembers);
-
-    CompleteCondition withoutMembers(String member, String... moreMembers);
+public interface ConnObjectTOCompleteCondition
+        extends SyncopeCompleteCondition<ConnObjectTOPartialCondition, ConnObjectTOProperty> {
 }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/ConnObjectTOFiqlSearchConditionBuilder.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/ConnObjectTOFiqlSearchConditionBuilder.java
index d028a71..c679928 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/ConnObjectTOFiqlSearchConditionBuilder.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/ConnObjectTOFiqlSearchConditionBuilder.java
@@ -19,13 +19,13 @@
 package org.apache.syncope.common.lib.search;
 
 import java.util.Map;
-import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
 
 /**
  * Extends {@link AbstractFiqlSearchConditionBuilder} by providing some additional facilities for searching
  * connector objects.
  */
-public class ConnObjectTOFiqlSearchConditionBuilder extends AbstractFiqlSearchConditionBuilder {
+public class ConnObjectTOFiqlSearchConditionBuilder extends AbstractFiqlSearchConditionBuilder<
+        ConnObjectTOProperty, ConnObjectTOPartialCondition, ConnObjectTOCompleteCondition> {
 
     private static final long serialVersionUID = 4983742159694010935L;
 
@@ -35,12 +35,13 @@ public class ConnObjectTOFiqlSearchConditionBuilder extends AbstractFiqlSearchCo
     }
 
     @Override
-    public SyncopeProperty is(final String property) {
+    public ConnObjectTOProperty is(final String property) {
         return newBuilderInstance().is(property);
     }
 
-    protected class Builder extends AbstractFiqlSearchConditionBuilder.Builder
-            implements SyncopeProperty, CompleteCondition {
+    protected class Builder extends AbstractFiqlSearchConditionBuilder.Builder<
+        ConnObjectTOProperty, ConnObjectTOPartialCondition, ConnObjectTOCompleteCondition>
+            implements ConnObjectTOProperty, ConnObjectTOPartialCondition, ConnObjectTOCompleteCondition {
 
         public Builder(final Map<String, String> properties) {
             super(properties);
@@ -51,30 +52,10 @@ public class ConnObjectTOFiqlSearchConditionBuilder extends AbstractFiqlSearchCo
         }
 
         @Override
-        public SyncopeProperty is(final String property) {
+        public ConnObjectTOProperty is(final String property) {
             Builder b = new Builder(this);
             b.result = property;
             return b;
         }
-
-        @Override
-        public CompleteCondition inDynRealms(final String dynRealm, final String... moreDynRealms) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public CompleteCondition notInDynRealms(final String dynRealm, final String... moreDynRealms) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public CompleteCondition hasResources(final String resource, final String... moreResources) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public CompleteCondition hasNotResources(final String resource, final String... moreResources) {
-            throw new UnsupportedOperationException();
-        }
     }
 }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/ConnObjectTOPartialCondition.java
similarity index 73%
copy from common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
copy to common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/ConnObjectTOPartialCondition.java
index 0325a72..88b9f4a 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/ConnObjectTOPartialCondition.java
@@ -18,13 +18,6 @@
  */
 package org.apache.syncope.common.lib.search;
 
-import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
-
-public interface GroupProperty extends SyncopeProperty {
-
-    CompleteCondition isAssignable();
-
-    CompleteCondition withMembers(String member, String... moreMembers);
-
-    CompleteCondition withoutMembers(String member, String... moreMembers);
+public interface ConnObjectTOPartialCondition
+        extends SyncopePartialCondition<ConnObjectTOProperty, ConnObjectTOCompleteCondition> {
 }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/ConnObjectTOProperty.java
similarity index 73%
copy from common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
copy to common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/ConnObjectTOProperty.java
index 0325a72..a880fbf 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/ConnObjectTOProperty.java
@@ -18,13 +18,5 @@
  */
 package org.apache.syncope.common.lib.search;
 
-import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
-
-public interface GroupProperty extends SyncopeProperty {
-
-    CompleteCondition isAssignable();
-
-    CompleteCondition withMembers(String member, String... moreMembers);
-
-    CompleteCondition withoutMembers(String member, String... moreMembers);
+public interface ConnObjectTOProperty extends SyncopeProperty<ConnObjectTOCompleteCondition> {
 }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupCompleteCondition.java
similarity index 73%
copy from common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
copy to common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupCompleteCondition.java
index 0325a72..6958ee9 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupCompleteCondition.java
@@ -18,13 +18,5 @@
  */
 package org.apache.syncope.common.lib.search;
 
-import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
-
-public interface GroupProperty extends SyncopeProperty {
-
-    CompleteCondition isAssignable();
-
-    CompleteCondition withMembers(String member, String... moreMembers);
-
-    CompleteCondition withoutMembers(String member, String... moreMembers);
+public interface GroupCompleteCondition extends SyncopeCompleteCondition<GroupPartialCondition, GroupProperty> {
 }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupFiqlSearchConditionBuilder.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupFiqlSearchConditionBuilder.java
index 1a875c9..bf7ddb2 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupFiqlSearchConditionBuilder.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupFiqlSearchConditionBuilder.java
@@ -19,14 +19,14 @@
 package org.apache.syncope.common.lib.search;
 
 import java.util.Map;
-import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
 import org.apache.cxf.jaxrs.ext.search.fiql.FiqlParser;
 
 /**
  * Extends {@link AbstractFiqlSearchConditionBuilder} by providing some additional facilities for searching
  * groups in Syncope.
  */
-public class GroupFiqlSearchConditionBuilder extends AbstractFiqlSearchConditionBuilder {
+public class GroupFiqlSearchConditionBuilder
+        extends AbstractFiqlSearchConditionBuilder<GroupProperty, GroupPartialCondition, GroupCompleteCondition> {
 
     private static final long serialVersionUID = 6275686371606165706L;
 
@@ -40,26 +40,27 @@ public class GroupFiqlSearchConditionBuilder extends AbstractFiqlSearchCondition
         return newBuilderInstance().is(property);
     }
 
-    public CompleteCondition isAssignable() {
+    public GroupCompleteCondition isAssignable() {
         return newBuilderInstance().
                 is(SpecialAttr.ASSIGNABLE.toString()).
                 isAssignable();
     }
 
-    public CompleteCondition withMembers(final String member, final String... moreMembers) {
+    public GroupCompleteCondition withMembers(final String member, final String... moreMembers) {
         return newBuilderInstance().
                 is(SpecialAttr.MEMBER.toString()).
                 withMembers(member, moreMembers);
     }
 
-    public CompleteCondition withoutMembers(final String member, final String... moreMembers) {
+    public GroupCompleteCondition withoutMembers(final String member, final String... moreMembers) {
         return newBuilderInstance().
                 is(SpecialAttr.MEMBER.toString()).
                 withoutMembers(member, moreMembers);
     }
 
-    protected static class Builder extends AbstractFiqlSearchConditionBuilder.Builder
-            implements GroupProperty, CompleteCondition {
+    protected static class Builder extends AbstractFiqlSearchConditionBuilder.Builder<
+            GroupProperty, GroupPartialCondition, GroupCompleteCondition>
+            implements GroupProperty, GroupCompleteCondition, GroupPartialCondition {
 
         public Builder(final Map<String, String> properties) {
             super(properties);
@@ -77,19 +78,19 @@ public class GroupFiqlSearchConditionBuilder extends AbstractFiqlSearchCondition
         }
 
         @Override
-        public CompleteCondition isAssignable() {
+        public GroupCompleteCondition isAssignable() {
             this.result = SpecialAttr.ASSIGNABLE.toString();
             return condition(FiqlParser.EQ, SpecialAttr.NULL);
         }
 
         @Override
-        public CompleteCondition withMembers(final String member, final String... moreMembers) {
+        public GroupCompleteCondition withMembers(final String member, final String... moreMembers) {
             this.result = SpecialAttr.MEMBER.toString();
             return condition(FiqlParser.EQ, member, (Object[]) moreMembers);
         }
 
         @Override
-        public CompleteCondition withoutMembers(final String member, final String... moreMembers) {
+        public GroupCompleteCondition withoutMembers(final String member, final String... moreMembers) {
             this.result = SpecialAttr.MEMBER.toString();
             return condition(FiqlParser.NEQ, member, (Object[]) moreMembers);
         }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupPartialCondition.java
similarity index 73%
copy from common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
copy to common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupPartialCondition.java
index 0325a72..4052006 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupPartialCondition.java
@@ -18,13 +18,5 @@
  */
 package org.apache.syncope.common.lib.search;
 
-import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
-
-public interface GroupProperty extends SyncopeProperty {
-
-    CompleteCondition isAssignable();
-
-    CompleteCondition withMembers(String member, String... moreMembers);
-
-    CompleteCondition withoutMembers(String member, String... moreMembers);
+public interface GroupPartialCondition extends SyncopePartialCondition<GroupProperty, GroupCompleteCondition> {
 }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
index 0325a72..8108012 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
@@ -18,13 +18,11 @@
  */
 package org.apache.syncope.common.lib.search;
 
-import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
+public interface GroupProperty extends SyncopeProperty<GroupCompleteCondition> {
 
-public interface GroupProperty extends SyncopeProperty {
+    GroupCompleteCondition isAssignable();
 
-    CompleteCondition isAssignable();
+    GroupCompleteCondition withMembers(String member, String... moreMembers);
 
-    CompleteCondition withMembers(String member, String... moreMembers);
-
-    CompleteCondition withoutMembers(String member, String... moreMembers);
+    GroupCompleteCondition withoutMembers(String member, String... moreMembers);
 }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeCompleteCondition.java
similarity index 76%
copy from common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
copy to common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeCompleteCondition.java
index 0325a72..c9cfec4 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeCompleteCondition.java
@@ -20,11 +20,18 @@ package org.apache.syncope.common.lib.search;
 
 import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
 
-public interface GroupProperty extends SyncopeProperty {
+public interface SyncopeCompleteCondition<PA extends SyncopePartialCondition<P, ?>, P extends SyncopeProperty<?>>
+        extends CompleteCondition {
 
-    CompleteCondition isAssignable();
+    @Override
+    PA and();
 
-    CompleteCondition withMembers(String member, String... moreMembers);
+    @Override
+    P and(String string);
 
-    CompleteCondition withoutMembers(String member, String... moreMembers);
+    @Override
+    PA or();
+
+    @Override
+    P or(String string);
 }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectProperty.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopePartialCondition.java
similarity index 61%
copy from common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectProperty.java
copy to common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopePartialCondition.java
index 9d32013..4f8efb5 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectProperty.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopePartialCondition.java
@@ -18,22 +18,25 @@
  */
 package org.apache.syncope.common.lib.search;
 
+import java.util.List;
 import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
+import org.apache.cxf.jaxrs.ext.search.client.PartialCondition;
 
-public interface AnyObjectProperty extends SyncopeProperty {
+public interface SyncopePartialCondition<P extends SyncopeProperty<C>, C extends SyncopeCompleteCondition<?, P>>
+        extends PartialCondition {
 
-    CompleteCondition inGroups(String group, String... moreGroups);
+    @Override
+    P is(String string);
 
-    CompleteCondition notInGroups(String group, String... moreGroups);
+    @Override
+    C and(CompleteCondition cc, CompleteCondition cc1, CompleteCondition... ccs);
 
-    CompleteCondition inRelationships(String anyObject, String... moreAnyObjects);
+    @Override
+    C or(CompleteCondition cc, CompleteCondition cc1, CompleteCondition... ccs);
 
-    CompleteCondition notInRelationships(String anyObject, String... moreAnyObjects);
-
-    CompleteCondition inRelationshipTypes(String type, String... moreTypes);
-
-    CompleteCondition notInRelationshipTypes(String type, String... moreTypes);
-
-    CompleteCondition isAssignable();
+    @Override
+    C and(List<CompleteCondition> list);
 
+    @Override
+    C or(List<CompleteCondition> list);
 }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeProperty.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeProperty.java
index bcc55ca..e792826 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeProperty.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/SyncopeProperty.java
@@ -18,14 +18,15 @@
  */
 package org.apache.syncope.common.lib.search;
 
-import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
 import org.apache.cxf.jaxrs.ext.search.client.Property;
 
 /**
  * Extension of fluent interface, for {@link org.apache.syncope.common.lib.search.AbstractFiqlSearchConditionBuilder}
  * and subclasses.
+ *
+ * @param <C> the actual complete condition
  */
-public interface SyncopeProperty extends Property {
+public interface SyncopeProperty<C extends SyncopeCompleteCondition<?, ?>> extends Property {
 
     /** Is textual property equal to (ignoring case) given literal or matching given pattern?
      *
@@ -33,26 +34,26 @@ public interface SyncopeProperty extends Property {
      * @param moreValues more values
      * @return updated condition
      */
-    CompleteCondition equalToIgnoreCase(String value, String... moreValues);
+    C equalToIgnoreCase(String value, String... moreValues);
 
     /** Is textual property different (ignoring case) than given literal or not matching given pattern?
      *
      * @param literalOrPattern The literal or Pattern String
      * @return updated condition
      */
-    CompleteCondition notEqualTolIgnoreCase(String literalOrPattern);
+    C notEqualTolIgnoreCase(String literalOrPattern);
 
     /** Is property null?
      *
      * @return updated condition
      */
-    CompleteCondition nullValue();
+    C nullValue();
 
     /** Is property not null?
      *
      * @return updated condition
      */
-    CompleteCondition notNullValue();
+    C notNullValue();
 
     /** Is user, group or any object owning given resource(s)?
      *
@@ -60,7 +61,7 @@ public interface SyncopeProperty extends Property {
      * @param moreResources more resources
      * @return updated condition
      */
-    CompleteCondition hasResources(String resource, String... moreResources);
+    C hasResources(String resource, String... moreResources);
 
     /** Is user, group or any object not owning given resource(s)?
      *
@@ -68,10 +69,9 @@ public interface SyncopeProperty extends Property {
      * @param moreResources more resources
      * @return updated condition
      */
-    CompleteCondition hasNotResources(String resource, String... moreResources);
-
-    CompleteCondition inDynRealms(String dynRealm, String... moreDynRealms);
+    C hasNotResources(String resource, String... moreResources);
 
-    CompleteCondition notInDynRealms(String dynRealm, String... moreDynRealms);
+    C inDynRealms(String dynRealm, String... moreDynRealms);
 
+    C notInDynRealms(String dynRealm, String... moreDynRealms);
 }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/UserCompleteCondition.java
similarity index 73%
copy from common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
copy to common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/UserCompleteCondition.java
index 0325a72..f037395 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/UserCompleteCondition.java
@@ -18,13 +18,5 @@
  */
 package org.apache.syncope.common.lib.search;
 
-import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
-
-public interface GroupProperty extends SyncopeProperty {
-
-    CompleteCondition isAssignable();
-
-    CompleteCondition withMembers(String member, String... moreMembers);
-
-    CompleteCondition withoutMembers(String member, String... moreMembers);
+public interface UserCompleteCondition extends SyncopeCompleteCondition<UserPartialCondition, UserProperty> {
 }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/UserFiqlSearchConditionBuilder.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/UserFiqlSearchConditionBuilder.java
index 88cdc6b..71447c8 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/UserFiqlSearchConditionBuilder.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/UserFiqlSearchConditionBuilder.java
@@ -19,14 +19,14 @@
 package org.apache.syncope.common.lib.search;
 
 import java.util.Map;
-import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
 import org.apache.cxf.jaxrs.ext.search.fiql.FiqlParser;
 
 /**
  * Extends {@link AbstractFiqlSearchConditionBuilder} by providing some additional facilities for searching
  * users in Syncope.
  */
-public class UserFiqlSearchConditionBuilder extends AbstractFiqlSearchConditionBuilder {
+public class UserFiqlSearchConditionBuilder
+        extends AbstractFiqlSearchConditionBuilder<UserProperty, UserPartialCondition, UserCompleteCondition> {
 
     private static final long serialVersionUID = 3485708634448845774L;
 
@@ -40,68 +40,69 @@ public class UserFiqlSearchConditionBuilder extends AbstractFiqlSearchConditionB
         return newBuilderInstance().is(property);
     }
 
-    public CompleteCondition inGroups(final String group, final String... moreGroups) {
+    public UserCompleteCondition inGroups(final String group, final String... moreGroups) {
         return newBuilderInstance().
                 is(SpecialAttr.GROUPS.toString()).
                 inGroups(group, moreGroups);
     }
 
-    public CompleteCondition notInGroups(final String group, final String... moreGroups) {
+    public UserCompleteCondition notInGroups(final String group, final String... moreGroups) {
         return newBuilderInstance().
                 is(SpecialAttr.GROUPS.toString()).
                 notInGroups(group, moreGroups);
     }
 
-    public CompleteCondition inRelationships(final String anyType, final String... moreAnyTypes) {
+    public UserCompleteCondition inRelationships(final String anyType, final String... moreAnyTypes) {
         return newBuilderInstance().
                 is(SpecialAttr.RELATIONSHIPS.toString()).
                 inRelationships(anyType, moreAnyTypes);
     }
 
-    public CompleteCondition notInRelationships(final String anyType, final String... moreAnyTypes) {
+    public UserCompleteCondition notInRelationships(final String anyType, final String... moreAnyTypes) {
         return newBuilderInstance().
                 is(SpecialAttr.RELATIONSHIPS.toString()).
                 notInRelationships(anyType, moreAnyTypes);
     }
 
-    public CompleteCondition inRelationshipTypes(final String type, final String... moreTypes) {
+    public UserCompleteCondition inRelationshipTypes(final String type, final String... moreTypes) {
         return newBuilderInstance().
                 is(SpecialAttr.RELATIONSHIP_TYPES.toString()).
                 inRelationshipTypes(type, moreTypes);
     }
 
-    public CompleteCondition notInRelationshipTypes(final String type, final String... moreTypes) {
+    public UserCompleteCondition notInRelationshipTypes(final String type, final String... moreTypes) {
         return newBuilderInstance().
                 is(SpecialAttr.RELATIONSHIP_TYPES.toString()).
                 notInRelationshipTypes(type, moreTypes);
     }
 
-    public CompleteCondition inRoles(final String role, final String... moreRoles) {
+    public UserCompleteCondition inRoles(final String role, final String... moreRoles) {
         return newBuilderInstance().
                 is(SpecialAttr.ROLES.toString()).
                 inRoles(role, moreRoles);
     }
 
-    public CompleteCondition notInRoles(final String role, final String... moreRoles) {
+    public UserCompleteCondition notInRoles(final String role, final String... moreRoles) {
         return newBuilderInstance().
                 is(SpecialAttr.ROLES.toString()).
                 notInRoles(role, moreRoles);
     }
 
-    public CompleteCondition withPrivileges(final String privilege, final String... morePrivileges) {
+    public UserCompleteCondition withPrivileges(final String privilege, final String... morePrivileges) {
         return newBuilderInstance().
                 is(SpecialAttr.PRIVILEGES.toString()).
                 withPrivileges(privilege, morePrivileges);
     }
 
-    public CompleteCondition withoutPrivileges(final String privilege, final String... morePrivileges) {
+    public UserCompleteCondition withoutPrivileges(final String privilege, final String... morePrivileges) {
         return newBuilderInstance().
                 is(SpecialAttr.PRIVILEGES.toString()).
                 withoutPrivileges(privilege, morePrivileges);
     }
 
-    protected static class Builder extends AbstractFiqlSearchConditionBuilder.Builder
-            implements UserProperty, CompleteCondition {
+    protected static class Builder extends AbstractFiqlSearchConditionBuilder.Builder<
+            UserProperty, UserPartialCondition, UserCompleteCondition>
+            implements UserProperty, UserPartialCondition, UserCompleteCondition {
 
         public Builder(final Map<String, String> properties) {
             super(properties);
@@ -119,61 +120,61 @@ public class UserFiqlSearchConditionBuilder extends AbstractFiqlSearchConditionB
         }
 
         @Override
-        public CompleteCondition inGroups(final String group, final String... moreGroups) {
+        public UserCompleteCondition inGroups(final String group, final String... moreGroups) {
             this.result = SpecialAttr.GROUPS.toString();
             return condition(FiqlParser.EQ, group, (Object[]) moreGroups);
         }
 
         @Override
-        public CompleteCondition notInGroups(final String group, final String... moreGroups) {
+        public UserCompleteCondition notInGroups(final String group, final String... moreGroups) {
             this.result = SpecialAttr.GROUPS.toString();
             return condition(FiqlParser.NEQ, group, (Object[]) moreGroups);
         }
 
         @Override
-        public CompleteCondition inRelationships(final String anyObject, final String... moreAnyObjects) {
+        public UserCompleteCondition inRelationships(final String anyObject, final String... moreAnyObjects) {
             this.result = SpecialAttr.RELATIONSHIPS.toString();
             return condition(FiqlParser.EQ, anyObject, (Object[]) moreAnyObjects);
         }
 
         @Override
-        public CompleteCondition notInRelationships(final String anyObject, final String... moreAnyObjects) {
+        public UserCompleteCondition notInRelationships(final String anyObject, final String... moreAnyObjects) {
             this.result = SpecialAttr.RELATIONSHIPS.toString();
             return condition(FiqlParser.NEQ, anyObject, (Object[]) moreAnyObjects);
         }
 
         @Override
-        public CompleteCondition inRelationshipTypes(final String type, final String... moreTypes) {
+        public UserCompleteCondition inRelationshipTypes(final String type, final String... moreTypes) {
             this.result = SpecialAttr.RELATIONSHIP_TYPES.toString();
             return condition(FiqlParser.EQ, type, (Object[]) moreTypes);
         }
 
         @Override
-        public CompleteCondition notInRelationshipTypes(final String type, final String... moreTypes) {
+        public UserCompleteCondition notInRelationshipTypes(final String type, final String... moreTypes) {
             this.result = SpecialAttr.RELATIONSHIP_TYPES.toString();
             return condition(FiqlParser.NEQ, type, (Object[]) moreTypes);
         }
 
         @Override
-        public CompleteCondition inRoles(final String role, final String... moreRoles) {
+        public UserCompleteCondition inRoles(final String role, final String... moreRoles) {
             this.result = SpecialAttr.ROLES.toString();
             return condition(FiqlParser.EQ, role, (Object[]) moreRoles);
         }
 
         @Override
-        public CompleteCondition notInRoles(final String role, final String... moreRoles) {
+        public UserCompleteCondition notInRoles(final String role, final String... moreRoles) {
             this.result = SpecialAttr.ROLES.toString();
             return condition(FiqlParser.NEQ, role, (Object[]) moreRoles);
         }
 
         @Override
-        public CompleteCondition withPrivileges(final String privilege, final String... morePrivileges) {
+        public UserCompleteCondition withPrivileges(final String privilege, final String... morePrivileges) {
             this.result = SpecialAttr.PRIVILEGES.toString();
             return condition(FiqlParser.EQ, privilege, (Object[]) morePrivileges);
         }
 
         @Override
-        public CompleteCondition withoutPrivileges(final String privilege, final String... morePrivileges) {
+        public UserCompleteCondition withoutPrivileges(final String privilege, final String... morePrivileges) {
             this.result = SpecialAttr.PRIVILEGES.toString();
             return condition(FiqlParser.NEQ, privilege, (Object[]) morePrivileges);
         }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/UserPartialCondition.java
similarity index 73%
copy from common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
copy to common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/UserPartialCondition.java
index 0325a72..b63ca7d 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/GroupProperty.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/UserPartialCondition.java
@@ -18,13 +18,5 @@
  */
 package org.apache.syncope.common.lib.search;
 
-import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
-
-public interface GroupProperty extends SyncopeProperty {
-
-    CompleteCondition isAssignable();
-
-    CompleteCondition withMembers(String member, String... moreMembers);
-
-    CompleteCondition withoutMembers(String member, String... moreMembers);
+public interface UserPartialCondition extends SyncopePartialCondition<UserProperty, UserCompleteCondition> {
 }
diff --git a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/UserProperty.java b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/UserProperty.java
index 7ac5be6..5c17f22 100644
--- a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/UserProperty.java
+++ b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/search/UserProperty.java
@@ -18,28 +18,25 @@
  */
 package org.apache.syncope.common.lib.search;
 
-import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
+public interface UserProperty extends SyncopeProperty<UserCompleteCondition> {
 
-public interface UserProperty extends SyncopeProperty {
+    UserCompleteCondition inGroups(String group, String... moreGroups);
 
-    CompleteCondition inGroups(String group, String... moreGroups);
+    UserCompleteCondition notInGroups(String group, String... moreGroups);
 
-    CompleteCondition notInGroups(String group, String... moreGroups);
+    UserCompleteCondition inRelationships(String anyObject, String... moreAnyObjects);
 
-    CompleteCondition inRelationships(String anyObject, String... moreAnyObjects);
+    UserCompleteCondition notInRelationships(String anyObject, String... moreAnyObjects);
 
-    CompleteCondition notInRelationships(String anyObject, String... moreAnyObjects);
+    UserCompleteCondition inRelationshipTypes(String type, String... moreTypes);
 
-    CompleteCondition inRelationshipTypes(String type, String... moreTypes);
+    UserCompleteCondition notInRelationshipTypes(String type, String... moreTypes);
 
-    CompleteCondition notInRelationshipTypes(String type, String... moreTypes);
+    UserCompleteCondition inRoles(String role, String... moreRoles);
 
-    CompleteCondition inRoles(String role, String... moreRoles);
+    UserCompleteCondition notInRoles(String role, String... moreRoles);
 
-    CompleteCondition notInRoles(String role, String... moreRoles);
-
-    CompleteCondition withPrivileges(String privilege, String... morePrivileges);
-
-    CompleteCondition withoutPrivileges(String privilege, String... morePrivileges);
+    UserCompleteCondition withPrivileges(String privilege, String... morePrivileges);
 
+    UserCompleteCondition withoutPrivileges(String privilege, String... morePrivileges);
 }
diff --git a/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/FilterConverterTest.java b/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/FilterConverterTest.java
index 52834f8..d314db0 100644
--- a/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/FilterConverterTest.java
+++ b/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/FilterConverterTest.java
@@ -19,7 +19,6 @@
 package org.apache.syncope.core.persistence.api.search;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
 
@@ -176,13 +175,6 @@ public class FilterConverterTest {
     @Test
     public void inDynRealms() {
         try {
-            new ConnObjectTOFiqlSearchConditionBuilder().inDynRealms("realm").query();
-            fail();
-        } catch (UnsupportedOperationException e) {
-            assertNotNull(e);
-        }
-
-        try {
             FilterConverter.convert(SpecialAttr.DYNREALMS + "==realm");
             fail();
         } catch (SyncopeClientException e) {
@@ -193,13 +185,6 @@ public class FilterConverterTest {
     @Test
     public void notInDynRealms() {
         try {
-            new ConnObjectTOFiqlSearchConditionBuilder().notInDynRealms("realm").query();
-            fail();
-        } catch (UnsupportedOperationException e) {
-            assertNotNull(e);
-        }
-
-        try {
             FilterConverter.convert(SpecialAttr.DYNREALMS + "!=realm");
             fail();
         } catch (SyncopeClientException e) {
@@ -210,13 +195,6 @@ public class FilterConverterTest {
     @Test
     public void hasResources() {
         try {
-            new ConnObjectTOFiqlSearchConditionBuilder().hasResources("resource").query();
-            fail();
-        } catch (UnsupportedOperationException e) {
-            assertNotNull(e);
-        }
-
-        try {
             FilterConverter.convert(SpecialAttr.RESOURCES + "==resource");
             fail();
         } catch (SyncopeClientException e) {
@@ -227,13 +205,6 @@ public class FilterConverterTest {
     @Test
     public void hasNotResources() {
         try {
-            new ConnObjectTOFiqlSearchConditionBuilder().hasNotResources("resource").query();
-            fail();
-        } catch (UnsupportedOperationException e) {
-            assertNotNull(e);
-        }
-
-        try {
             FilterConverter.convert(SpecialAttr.RESOURCES + "!=resource");
             fail();
         } catch (SyncopeClientException e) {