Updated connection params to follow relay cursor connection specs
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/condition/factories/EventConditionFactory.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/condition/factories/EventConditionFactory.java
index af8eb49..d9bc0c8 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/condition/factories/EventConditionFactory.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/condition/factories/EventConditionFactory.java
@@ -32,7 +32,6 @@
 import org.apache.unomi.graphql.utils.ReflectionUtil;
 
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -52,129 +51,100 @@
         super("eventPropertyCondition", environment);
     }
 
-    public Condition eventFilterInputCondition(final String profileId, final Date after, final Date before) {
-        final List<Condition> rootSubConditions = new ArrayList<>();
-
-        if (after != null) {
-            rootSubConditions.add(datePropertyCondition("timeStamp", "greaterThan", after));
-        }
-
-        if (before != null) {
-            rootSubConditions.add(datePropertyCondition("timeStamp", "lessThanOrEqual", before));
-        }
-
-        if (profileId != null) {
-            rootSubConditions.add(propertyCondition("profileId", profileId));
-        }
-
-        return booleanCondition("and", rootSubConditions);
-    }
-
-    public Condition eventFilterInputCondition(final CDPEventFilterInput filterInput, final Map<String, Object> filterInputAsMap) {
-        return eventFilterInputCondition(filterInput, filterInputAsMap, null, null);
-    }
-
     @SuppressWarnings("unchecked")
-    public Condition eventFilterInputCondition(final CDPEventFilterInput filterInput, final Map<String, Object> filterInputAsMap, final Date after, final Date before) {
+    public Condition eventFilterInputCondition(final CDPEventFilterInput filterInput, final Map<String, Object> filterInputAsMap) {
+        if (filterInput == null) {
+            return matchAllCondition();
+        }
+
         final List<Condition> rootSubConditions = new ArrayList<>();
 
-        if (after != null) {
-            rootSubConditions.add(datePropertyCondition("timeStamp", "greaterThan", after));
+        if (filterInput.getCdp_timestamp_equals() != null) {
+            rootSubConditions.add(datePropertyCondition("timeStamp", "equals", filterInput.getCdp_timestamp_equals()));
         }
 
-        if (before != null) {
-            rootSubConditions.add(datePropertyCondition("timeStamp", "lessThanOrEqual", before));
+        if (filterInput.getCdp_timestamp_gt() != null) {
+            rootSubConditions.add(datePropertyCondition("timeStamp", "greaterThan", filterInput.getCdp_timestamp_gt()));
         }
 
-        if (filterInput != null) {
+        if (filterInput.getCdp_timestamp_gte() != null) {
+            rootSubConditions.add(datePropertyCondition("timeStamp", "greaterThanOrEqualTo", filterInput.getCdp_timestamp_gte()));
+        }
 
-            if (filterInput.getCdp_timestamp_equals() != null) {
-                rootSubConditions.add(datePropertyCondition("timeStamp", "equals", filterInput.getCdp_timestamp_equals()));
+        if (filterInput.getCdp_timestamp_lt() != null) {
+            rootSubConditions.add(datePropertyCondition("timeStamp", "lessThan", filterInput.getCdp_timestamp_lt()));
+        }
+
+        if (filterInput.getCdp_timestamp_lte() != null) {
+            rootSubConditions.add(datePropertyCondition("timeStamp", "lessThanOrEqualTo", filterInput.getCdp_timestamp_lte()));
+        }
+
+        if (filterInput.getId_equals() != null) {
+            rootSubConditions.add(propertyCondition("itemId", filterInput.getId_equals()));
+        }
+
+        if (filterInput.getCdp_clientID_equals() != null) {
+            rootSubConditions.add(propertyCondition("properties.clientId", filterInput.getCdp_clientID_equals()));
+        }
+
+        if (filterInput.getCdp_profileID_equals() != null) {
+            rootSubConditions.add(propertyCondition("profileId", filterInput.getCdp_profileID_equals()));
+        }
+
+        if (filterInput.getCdp_sourceID_equals() != null) {
+            rootSubConditions.add(propertyCondition("source.itemId", filterInput.getCdp_sourceID_equals()));
+        }
+
+        if (filterInput.getCdp_listsUpdateEvent() != null) {
+            rootSubConditions.add(listUpdateEventCondition(filterInput.getCdp_listsUpdateEvent()));
+        }
+
+        if (filterInput.getCdp_consentUpdateEvent() != null) {
+            rootSubConditions.add(createCdpConsentUpdateEventCondition(filterInput.getCdp_consentUpdateEvent()));
+        }
+
+        if (filterInput.getCdp_sessionEvent() != null) {
+            rootSubConditions.add(createCdpSessionEventCondition(filterInput.getCdp_sessionEvent()));
+        }
+
+        if (filterInput.getCdp_profileUpdateEvent() != null) {
+            final Map<String, Object> profileUpdateEventAsMap = (Map<String, Object>) filterInputAsMap.get("cdp_profileUpdateEvent");
+
+            rootSubConditions.add(
+                    createDynamicEventCondition("cdp_profileUpdateEvent", profileUpdateEventAsMap, CDPProfileUpdateEventFilterInput.TYPE_NAME));
+        }
+
+        final List<String> nonDynamicFields = ReflectionUtil.getNonDynamicFields(filterInput.getClass());
+
+        final GraphQLInputObjectType inputObjectType =
+                (GraphQLInputObjectType) environment.getGraphQLSchema().getType(ReflectionUtil.resolveTypeName(CDPEventFilterInput.class));
+
+        final List<String> dynamicInputFields = inputObjectType.getFieldDefinitions()
+                .stream()
+                .filter(inputObjectField -> !nonDynamicFields.contains(inputObjectField.getName()))
+                .map(GraphQLInputObjectField::getName)
+                .collect(Collectors.toList());
+
+        dynamicInputFields.forEach(fieldName -> {
+            final Map<String, Object> dynamicEventAsMap = (Map<String, Object>) filterInputAsMap.get(fieldName);
+
+            if (dynamicEventAsMap != null) {
+                final String typeName = ((GraphQLInputObjectType) inputObjectType.getFieldDefinition(fieldName).getType()).getName();
+
+                rootSubConditions.add(createDynamicEventCondition(fieldName, dynamicEventAsMap, typeName));
             }
+        });
 
-            if (filterInput.getCdp_timestamp_gt() != null) {
-                rootSubConditions.add(datePropertyCondition("timeStamp", "greaterThan", filterInput.getCdp_timestamp_gt()));
-            }
+        if (filterInput.getAnd() != null && !filterInput.getAnd().isEmpty()) {
+            final List<Map<String, Object>> listFilterInputAsMap = (List<Map<String, Object>>) filterInputAsMap.get("and");
 
-            if (filterInput.getCdp_timestamp_gte() != null) {
-                rootSubConditions.add(datePropertyCondition("timeStamp", "greaterThanOrEqualTo", filterInput.getCdp_timestamp_gte()));
-            }
+            rootSubConditions.add(filtersToCondition(filterInput.getAnd(), listFilterInputAsMap, this::eventFilterInputCondition, "and"));
+        }
 
-            if (filterInput.getCdp_timestamp_lt() != null) {
-                rootSubConditions.add(datePropertyCondition("timeStamp", "lessThan", filterInput.getCdp_timestamp_lt()));
-            }
+        if (filterInput.getOr() != null && !filterInput.getOr().isEmpty()) {
+            final List<Map<String, Object>> listFilterInputAsMap = (List<Map<String, Object>>) filterInputAsMap.get("or");
 
-            if (filterInput.getCdp_timestamp_lte() != null) {
-                rootSubConditions.add(datePropertyCondition("timeStamp", "lessThanOrEqualTo", filterInput.getCdp_timestamp_lte()));
-            }
-
-            if (filterInput.getId_equals() != null) {
-                rootSubConditions.add(propertyCondition("itemId", filterInput.getId_equals()));
-            }
-
-            if (filterInput.getCdp_clientID_equals() != null) {
-                rootSubConditions.add(propertyCondition("properties.clientId", filterInput.getCdp_clientID_equals()));
-            }
-
-            if (filterInput.getCdp_profileID_equals() != null) {
-                rootSubConditions.add(propertyCondition("profileId", filterInput.getCdp_profileID_equals()));
-            }
-
-            if (filterInput.getCdp_sourceID_equals() != null) {
-                rootSubConditions.add(propertyCondition("source.itemId", filterInput.getCdp_sourceID_equals()));
-            }
-
-            if (filterInput.getCdp_listsUpdateEvent() != null) {
-                rootSubConditions.add(listUpdateEventCondition(filterInput.getCdp_listsUpdateEvent()));
-            }
-
-            if (filterInput.getCdp_consentUpdateEvent() != null) {
-                rootSubConditions.add(createCdpConsentUpdateEventCondition(filterInput.getCdp_consentUpdateEvent()));
-            }
-
-            if (filterInput.getCdp_sessionEvent() != null) {
-                rootSubConditions.add(createCdpSessionEventCondition(filterInput.getCdp_sessionEvent()));
-            }
-
-            if (filterInput.getCdp_profileUpdateEvent() != null) {
-                final Map<String, Object> profileUpdateEventAsMap = (Map<String, Object>) filterInputAsMap.get("cdp_profileUpdateEvent");
-
-                rootSubConditions.add(
-                        createDynamicEventCondition("cdp_profileUpdateEvent", profileUpdateEventAsMap, CDPProfileUpdateEventFilterInput.TYPE_NAME));
-            }
-
-            final List<String> nonDynamicFields = ReflectionUtil.getNonDynamicFields(filterInput.getClass());
-
-            final GraphQLInputObjectType inputObjectType =
-                    (GraphQLInputObjectType) environment.getGraphQLSchema().getType(ReflectionUtil.resolveTypeName(CDPEventFilterInput.class));
-
-            final List<String> dynamicInputFields = inputObjectType.getFieldDefinitions()
-                    .stream()
-                    .filter(inputObjectField -> !nonDynamicFields.contains(inputObjectField.getName()))
-                    .map(GraphQLInputObjectField::getName)
-                    .collect(Collectors.toList());
-
-            dynamicInputFields.forEach(fieldName -> {
-                final Map<String, Object> dynamicEventAsMap = (Map<String, Object>) filterInputAsMap.get(fieldName);
-
-                if (dynamicEventAsMap != null) {
-                    final String typeName = ((GraphQLInputObjectType) inputObjectType.getFieldDefinition(fieldName).getType()).getName();
-
-                    rootSubConditions.add(createDynamicEventCondition(fieldName, dynamicEventAsMap, typeName));
-                }
-            });
-
-            if (filterInput.getAnd() != null && !filterInput.getAnd().isEmpty()) {
-                final List<Map<String, Object>> listFilterInputAsMap = (List<Map<String, Object>>) filterInputAsMap.get("and");
-
-                rootSubConditions.add(filtersToCondition(filterInput.getAnd(), listFilterInputAsMap, this::eventFilterInputCondition, "and"));
-            }
-
-            if (filterInput.getOr() != null && !filterInput.getOr().isEmpty()) {
-                final List<Map<String, Object>> listFilterInputAsMap = (List<Map<String, Object>>) filterInputAsMap.get("or");
-
-                rootSubConditions.add(filtersToCondition(filterInput.getOr(), listFilterInputAsMap, this::eventFilterInputCondition, "or"));
-            }
+            rootSubConditions.add(filtersToCondition(filterInput.getOr(), listFilterInputAsMap, this::eventFilterInputCondition, "or"));
         }
 
         return booleanCondition("and", rootSubConditions);
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/condition/factories/ProfileConditionFactory.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/condition/factories/ProfileConditionFactory.java
index 2bb5f6b..aba3dd3 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/condition/factories/ProfileConditionFactory.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/condition/factories/ProfileConditionFactory.java
@@ -35,7 +35,6 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Function;
@@ -56,97 +55,81 @@
         super("profilePropertyCondition", environment);
     }
 
-    public Condition segmentFilterInputCondition(final CDPSegmentFilterInput filterInput, Date after, Date before) {
+    public Condition segmentFilterInputCondition(final CDPSegmentFilterInput filterInput) {
+        if (filterInput == null) {
+            return matchAllCondition();
+        }
+
         final List<Condition> rootSubConditions = new ArrayList<>();
 
-        if (after != null) {
-            rootSubConditions.add(datePropertyCondition("timeStamp", "greaterThan", after));
+        if (filterInput.getNameEquals() != null) {
+            rootSubConditions.add(propertyCondition("metadata.name", filterInput.getNameEquals(), definitionsService));
         }
 
-        if (before != null) {
-            rootSubConditions.add(datePropertyCondition("timeStamp", "lessThanOrEqual", before));
+        if (filterInput.getViewEquals() != null) {
+            rootSubConditions.add(propertyCondition("metadata.scope", filterInput.getViewEquals(), definitionsService));
         }
 
-        if (filterInput != null) {
-            if (filterInput.getNameEquals() != null) {
-                rootSubConditions.add(propertyCondition("metadata.name", filterInput.getNameEquals(), definitionsService));
-            }
+        if (filterInput.getAndFilters() != null && !filterInput.getAndFilters().isEmpty()) {
+            final List<Condition> filterAndSubConditions = filterInput.getAndFilters().stream()
+                    .map(this::segmentFilterInputCondition)
+                    .collect(Collectors.toList());
+            rootSubConditions.add(booleanCondition("and", filterAndSubConditions));
+        }
 
-            if (filterInput.getViewEquals() != null) {
-                rootSubConditions.add(propertyCondition("metadata.scope", filterInput.getViewEquals(), definitionsService));
-            }
-
-            if (filterInput.getAndFilters() != null && !filterInput.getAndFilters().isEmpty()) {
-                final List<Condition> filterAndSubConditions = filterInput.getAndFilters().stream()
-                        .map(andInput -> segmentFilterInputCondition(andInput, null, null))
-                        .collect(Collectors.toList());
-                rootSubConditions.add(booleanCondition("and", filterAndSubConditions));
-            }
-
-            if (filterInput.getOrFilters() != null && !filterInput.getOrFilters().isEmpty()) {
-                final List<Condition> filterOrSubConditions = filterInput.getOrFilters().stream()
-                        .map(orInput -> segmentFilterInputCondition(orInput, null, null))
-                        .collect(Collectors.toList());
-                rootSubConditions.add(booleanCondition("or", filterOrSubConditions));
-            }
+        if (filterInput.getOrFilters() != null && !filterInput.getOrFilters().isEmpty()) {
+            final List<Condition> filterOrSubConditions = filterInput.getOrFilters().stream()
+                    .map(this::segmentFilterInputCondition)
+                    .collect(Collectors.toList());
+            rootSubConditions.add(booleanCondition("or", filterOrSubConditions));
         }
 
         return booleanCondition("and", rootSubConditions);
     }
 
-    public Condition profileFilterInputCondition(final CDPProfileFilterInput filterInput, final Map<String, Object> filterInputAsMap) {
-        return profileFilterInputCondition(filterInput, filterInputAsMap, null, null);
-    }
-
     @SuppressWarnings("unchecked")
-    public Condition profileFilterInputCondition(final CDPProfileFilterInput filterInput, final Map<String, Object> filterInputAsMap, Date after, Date before) {
+    public Condition profileFilterInputCondition(final CDPProfileFilterInput filterInput, final Map<String, Object> filterInputAsMap) {
+        if (filterInput == null) {
+            return matchAllCondition();
+        }
+
         final List<Condition> rootSubConditions = new ArrayList<>();
 
-        if (after != null) {
-            rootSubConditions.add(datePropertyCondition("timeStamp", "greaterThan", after));
+        if (filterInput.getProfileIDs_contains() != null && !filterInput.getProfileIDs_contains().isEmpty()) {
+            rootSubConditions.add(propertiesCondition("itemId", "inContains", filterInput.getProfileIDs_contains()));
         }
 
-        if (before != null) {
-            rootSubConditions.add(datePropertyCondition("timeStamp", "lessThanOrEqual", before));
+        if (filterInput.getSegments_contains() != null && filterInput.getSegments_contains().isEmpty()) {
+            rootSubConditions.add(ConditionBuilder.create(getConditionType("profileSegmentCondition"))
+                    .parameter("segments", filterInput.getSegments_contains())
+                    .parameter("matchType", "in")
+                    .build());
         }
 
-        if (filterInput != null) {
-            if (filterInput.getProfileIDs_contains() != null && !filterInput.getProfileIDs_contains().isEmpty()) {
-                rootSubConditions.add(propertiesCondition("itemId", "inContains", filterInput.getProfileIDs_contains()));
-            }
+        if (filterInput.getConsents_contains() != null && !filterInput.getConsents_contains().isEmpty()) {
+            rootSubConditions.add(consentContainsCondition(filterInput.getConsents_contains()));
 
-            if (filterInput.getSegments_contains() != null && filterInput.getSegments_contains().isEmpty()) {
-                rootSubConditions.add(ConditionBuilder.create(getConditionType("profileSegmentCondition"))
-                        .parameter("segments", filterInput.getSegments_contains())
-                        .parameter("matchType", "in")
-                        .build());
-            }
+        }
 
-            if (filterInput.getConsents_contains() != null && !filterInput.getConsents_contains().isEmpty()) {
-                rootSubConditions.add(consentContainsCondition(filterInput.getConsents_contains()));
+        if (filterInput.getLists_contains() != null && filterInput.getLists_contains().isEmpty()) {
+            rootSubConditions.add(ConditionBuilder.create(getConditionType("profileUserListCondition"))
+                    .parameter("lists", filterInput.getLists_contains())
+                    .parameter("matchType", "in")
+                    .build());
+        }
 
-            }
+        if (filterInput.getProperties() != null) {
+            final Map<String, Object> propertiesFilterAsMap = (Map<String, Object>) filterInputAsMap.get("properties");
+            rootSubConditions.add(profilePropertiesFilterInputCondition(filterInput.getProperties(), propertiesFilterAsMap));
+        }
 
-            if (filterInput.getLists_contains() != null && filterInput.getLists_contains().isEmpty()) {
-                rootSubConditions.add(ConditionBuilder.create(getConditionType("profileUserListCondition"))
-                        .parameter("lists", filterInput.getLists_contains())
-                        .parameter("matchType", "in")
-                        .build());
-            }
+        if (filterInput.getEvents() != null) {
+            final Map<String, Object> eventsFilterAsMap = (Map<String, Object>) filterInputAsMap.get("events");
+            rootSubConditions.add(profileEventsFilterInputCondition(filterInput.getEvents(), eventsFilterAsMap));
+        }
 
-            if (filterInput.getProperties() != null) {
-                final Map<String, Object> propertiesFilterAsMap = (Map<String, Object>) filterInputAsMap.get("properties");
-                rootSubConditions.add(profilePropertiesFilterInputCondition(filterInput.getProperties(), propertiesFilterAsMap));
-            }
-
-            if (filterInput.getEvents() != null) {
-                final Map<String, Object> eventsFilterAsMap = (Map<String, Object>) filterInputAsMap.get("events");
-                rootSubConditions.add(profileEventsFilterInputCondition(filterInput.getEvents(), eventsFilterAsMap));
-            }
-
-            if (filterInput.getInterests() != null) {
-                rootSubConditions.add(interestFilterInputCondition(filterInput.getInterests()));
-            }
+        if (filterInput.getInterests() != null) {
+            rootSubConditions.add(interestFilterInputCondition(filterInput.getInterests()));
         }
 
         return booleanCondition("and", rootSubConditions);
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/BaseConnectionDataFetcher.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/BaseConnectionDataFetcher.java
index 49ec092..ded6e34 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/BaseConnectionDataFetcher.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/BaseConnectionDataFetcher.java
@@ -30,10 +30,10 @@
 
     protected ConnectionParams parseConnectionParams(final DataFetchingEnvironment environment) {
         return ConnectionParams.create()
-                .first(parseParam("first", 0, environment))
-                .last(parseParam("last", DEFAULT_PAGE_SIZE, environment))
-                .after(parseDateParam("after", environment))
-                .before(parseDateParam("before", environment))
+                .first(parseParam("first", null, environment))
+                .last(parseParam("last", null, environment))
+                .after(parseParam("after", null, environment))
+                .before(parseParam("before", null, environment))
                 .build();
     }
 
@@ -42,7 +42,7 @@
         query.setCondition(condition);
 
         if (params != null) {
-            query.setOffset(params.getFirst());
+            query.setOffset(params.getOffset());
             query.setLimit(params.getSize());
         }
 
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/BaseDataFetcher.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/BaseDataFetcher.java
index cd66338..629d50a 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/BaseDataFetcher.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/BaseDataFetcher.java
@@ -31,8 +31,6 @@
 
 public abstract class BaseDataFetcher<T> implements DataFetcher<T> {
 
-    public static int DEFAULT_PAGE_SIZE = 10;
-
     private static final Logger logger = LoggerFactory.getLogger(BaseDataFetcher.class);
 
     protected <E> E parseObjectParam(String name, Class<E> clazz, DataFetchingEnvironment environment) {
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/ConnectionParams.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/ConnectionParams.java
index 757c567..412322a 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/ConnectionParams.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/ConnectionParams.java
@@ -17,38 +17,68 @@
 
 package org.apache.unomi.graphql.fetchers;
 
-import java.util.Date;
-
 public class ConnectionParams {
-    private int first;
-    private int last;
-    private Date after;
-    private Date before;
+    private Integer first;
+    private Integer last;
+    private String after;
+    private String before;
+
+    public static int DEFAULT_PAGE_SIZE = 10;
 
     private ConnectionParams(final Builder builder) {
         first = builder.first;
         last = builder.last;
         after = builder.after;
         before = builder.before;
+
+        if (first != null && before != null
+                || last != null && after != null) {
+            throw new IllegalArgumentException("Incorrect params: either 'first' and 'after' or 'last' and 'before' should be used simultaneously");
+        }
     }
 
-    public int getFirst() {
+    public Integer getFirst() {
         return first;
     }
 
-    public int getLast() {
+    public Integer getLast() {
         return last;
     }
 
     public int getSize() {
-        return last - first;
+        if (first != null) {
+            return first;
+        } else if (last != null) {
+            return last;
+        }
+        return DEFAULT_PAGE_SIZE;
     }
 
-    public Date getAfter() {
+    public int getOffset() {
+        if (after != null) {
+            return parseInt(after, 0);
+        } else if (before != null) {
+            final int beforeInt = parseInt(before, -1);
+            if (beforeInt > 0) {
+                return beforeInt - (last != null ? last : DEFAULT_PAGE_SIZE);
+            }
+        }
+        return 0;
+    }
+
+    private int parseInt(String after, int defaultValue) {
+        try {
+            return Integer.parseInt(after);
+        } catch (NumberFormatException e) {
+            return defaultValue;
+        }
+    }
+
+    public String getAfter() {
         return after;
     }
 
-    public Date getBefore() {
+    public String getBefore() {
         return before;
     }
 
@@ -57,30 +87,30 @@
     }
 
     public static class Builder {
-        private int first;
-        private int last;
-        private Date after;
-        private Date before;
+        private Integer first;
+        private Integer last;
+        private String after;
+        private String before;
 
         private Builder() {
         }
 
-        public Builder first(int first) {
+        public Builder first(Integer first) {
             this.first = first;
             return this;
         }
 
-        public Builder last(int last) {
+        public Builder last(Integer last) {
             this.last = last;
             return this;
         }
 
-        public Builder after(Date after) {
+        public Builder after(String after) {
             this.after = after;
             return this;
         }
 
-        public Builder before(Date before) {
+        public Builder before(String before) {
             this.before = before;
             return this;
         }
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/EventConnectionDataFetcher.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/EventConnectionDataFetcher.java
index 7ac4695..50e4f2b 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/EventConnectionDataFetcher.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/EventConnectionDataFetcher.java
@@ -30,8 +30,8 @@
 
     protected CDPEventConnection createEventConnection(PartialList<Event> events) {
         final List<CDPEventEdge> eventEdges = events.getList().stream().map(CDPEventEdge::new).collect(Collectors.toList());
-        final CDPPageInfo cdpPageInfo = new CDPPageInfo(events.getOffset() > 0, events.getTotalSize() > events.getList().size());
+        final CDPPageInfo pageInfo = new CDPPageInfo(events.getOffset() > 0, events.getTotalSize() > events.getList().size());
 
-        return new CDPEventConnection(eventEdges, cdpPageInfo);
+        return new CDPEventConnection(eventEdges, pageInfo);
     }
 }
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/ProfileConnectionDataFetcher.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/ProfileConnectionDataFetcher.java
index 20cf1da..47ccf72 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/ProfileConnectionDataFetcher.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/ProfileConnectionDataFetcher.java
@@ -32,8 +32,8 @@
         final List<CDPProfileEdge> eventEdges = profiles.getList().stream()
                 .map(CDPProfileEdge::new)
                 .collect(Collectors.toList());
-        final CDPPageInfo cdpPageInfo = new CDPPageInfo(profiles.getOffset() > 0, profiles.getTotalSize() > profiles.getList().size());
+        final CDPPageInfo pageInfo = new CDPPageInfo(profiles.getOffset() > 0, profiles.getTotalSize() > profiles.getList().size());
 
-        return new CDPProfileConnection(eventEdges, cdpPageInfo);
+        return new CDPProfileConnection(eventEdges, pageInfo);
     }
 }
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/SegmentConnectionDataFetcher.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/SegmentConnectionDataFetcher.java
index d7b1f2b..dddf8be 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/SegmentConnectionDataFetcher.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/SegmentConnectionDataFetcher.java
@@ -31,9 +31,9 @@
 
     protected CDPSegmentConnection createSegmentConnection(PartialList<Segment> segments) {
         final List<CDPSegmentEdge> segmentEdges = segments.getList().stream().map(segment -> new CDPSegmentEdge(new CDPSegment(segment), segment.getItemId())).collect(Collectors.toList());
-        final CDPPageInfo cdpPageInfo = new CDPPageInfo(segments.getOffset() > 0, segments.getTotalSize() > segments.getList().size());
+        final CDPPageInfo pageInfo = new CDPPageInfo(segments.getOffset() > 0, segments.getTotalSize() > segments.getList().size());
 
-        return new CDPSegmentConnection(segmentEdges, cdpPageInfo);
+        return new CDPSegmentConnection(segmentEdges, pageInfo);
     }
 
 }
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/consent/ConsentEventConnectionDataFetcher.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/consent/ConsentEventConnectionDataFetcher.java
index 5e0589b..05090e2 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/consent/ConsentEventConnectionDataFetcher.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/consent/ConsentEventConnectionDataFetcher.java
@@ -22,6 +22,7 @@
 import org.apache.unomi.api.PartialList;
 import org.apache.unomi.api.conditions.Condition;
 import org.apache.unomi.graphql.condition.factories.EventConditionFactory;
+import org.apache.unomi.graphql.fetchers.ConnectionParams;
 import org.apache.unomi.graphql.fetchers.EventConnectionDataFetcher;
 import org.apache.unomi.graphql.services.ServiceManager;
 import org.apache.unomi.graphql.types.output.CDPConsent;
@@ -42,7 +43,7 @@
         final Condition consentCondition = factory.propertyCondition("target.token", consent.getToken(), serviceManager.getDefinitionsService());
 
         final Condition andCondition = factory.booleanCondition("and", Arrays.asList(eventCondition, consentCondition));
-        final PartialList<Event> events = serviceManager.getEventService().searchEvents(andCondition, 0, DEFAULT_PAGE_SIZE);
+        final PartialList<Event> events = serviceManager.getEventService().searchEvents(andCondition, 0, ConnectionParams.DEFAULT_PAGE_SIZE);
 
         return createEventConnection(events);
     }
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/event/FindEventsConnectionDataFetcher.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/event/FindEventsConnectionDataFetcher.java
index 79c4b45..68d060f 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/event/FindEventsConnectionDataFetcher.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/event/FindEventsConnectionDataFetcher.java
@@ -17,7 +17,6 @@
 
 package org.apache.unomi.graphql.fetchers.event;
 
-import com.google.common.base.Strings;
 import graphql.schema.DataFetchingEnvironment;
 import org.apache.unomi.api.Event;
 import org.apache.unomi.api.PartialList;
@@ -33,7 +32,6 @@
 
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
 
 public class FindEventsConnectionDataFetcher extends EventConnectionDataFetcher {
 
@@ -54,20 +52,9 @@
         final Map<String, Object> filterInputAsMap = environment.getArgument("filter");
 
         final Condition condition = EventConditionFactory.get(environment)
-                .eventFilterInputCondition(filterInput, filterInputAsMap, params.getAfter(), params.getBefore());
+                .eventFilterInputCondition(filterInput, filterInputAsMap);
 
-        final Query query = new Query();
-        if (orderByInput != null) {
-            final String sortBy = orderByInput.stream().map(CDPOrderByInput::asString)
-                    .collect(Collectors.joining(","));
-
-            if (!Strings.isNullOrEmpty(sortBy)) {
-                query.setSortby(sortBy);
-            }
-        }
-        query.setOffset(params.getFirst());
-        query.setLimit(params.getSize());
-        query.setCondition(condition);
+        final Query query = buildQuery(condition, orderByInput, params);
 
         PartialList<Event> events = serviceManager.getEventService().search(query);
 
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/list/ListProfileConnectionDataFetcher.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/list/ListProfileConnectionDataFetcher.java
index 82c7858..e37ca55 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/list/ListProfileConnectionDataFetcher.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/list/ListProfileConnectionDataFetcher.java
@@ -40,10 +40,7 @@
         Condition listIdCondition = ProfileConditionFactory.get(environment)
                 .propertyCondition("systemProperties.lists", "contains", cdpList.id());
 
-        final Query query = new Query();
-        query.setOffset(params.getFirst());
-        query.setLimit(params.getSize());
-        query.setCondition(listIdCondition);
+        final Query query = buildQuery(listIdCondition, null, params);
 
         PartialList<Profile> profiles = serviceManager.getProfileService().search(query, Profile.class);
 
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/FindProfilesConnectionDataFetcher.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/FindProfilesConnectionDataFetcher.java
index 26a614d..77d6b15 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/FindProfilesConnectionDataFetcher.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/FindProfilesConnectionDataFetcher.java
@@ -48,7 +48,7 @@
         final ConnectionParams params = parseConnectionParams(environment);
 
         final Condition condition = ProfileConditionFactory.get(environment)
-                .profileFilterInputCondition(filterInput, environment.getArgument("filter"), params.getAfter(), params.getBefore());
+                .profileFilterInputCondition(filterInput, environment.getArgument("filter"));
         final Query query = buildQuery(condition, orderByInput, params);
 
         PartialList<Profile> profiles = serviceManager.getProfileService().search(query, Profile.class);
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/ProfileAllEventsConnectionDataFetcher.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/ProfileAllEventsConnectionDataFetcher.java
index 5eb1b28..f29bede 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/ProfileAllEventsConnectionDataFetcher.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/ProfileAllEventsConnectionDataFetcher.java
@@ -51,14 +51,14 @@
         Condition condition;
 
         if (filterInput == null) {
-            condition = eventConditionFactory.eventFilterInputCondition(profile.getItemId(), params.getAfter(), params.getBefore());
+            condition = eventConditionFactory.propertyCondition("profileId", profile.getItemId());
         } else {
             final Map<String, Object> filterInputAsMap = environment.getArgument("filter");
 
-            condition = eventConditionFactory.eventFilterInputCondition(filterInput, filterInputAsMap, params.getAfter(), params.getBefore());
+            condition = eventConditionFactory.eventFilterInputCondition(filterInput, filterInputAsMap);
         }
 
-        final PartialList<Event> events = serviceManager.getEventService().searchEvents(condition, params.getFirst(), params.getSize());
+        final PartialList<Event> events = serviceManager.getEventService().searchEvents(condition, params.getOffset(), params.getSize());
 
         return createEventConnection(events);
     }
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/PropertiesConnectionDataFetcher.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/PropertiesConnectionDataFetcher.java
index a4888eb..a4c663c 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/PropertiesConnectionDataFetcher.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/profile/PropertiesConnectionDataFetcher.java
@@ -44,19 +44,19 @@
     }
 
     private CDPPropertyConnection createPropertiesConnection(Collection<PropertyType> properties, ConnectionParams params) {
-        if (properties == null || properties.size() == 0 || properties.size() < params.getFirst() || params.getFirst() > params.getLast()) {
+        final int startIndex = Math.max(0, params.getOffset());
+        final int lastIndex = Math.min(params.getOffset() + params.getSize(), properties.size());
+        if (properties == null || properties.size() == 0 || properties.size() < startIndex || lastIndex <= 0) {
             return new CDPPropertyConnection();
         }
-        final int startIndex = Math.max(params.getFirst(), 0);
-        final int lastIndex = Math.min(params.getLast(), properties.size());
 
-        final CDPPageInfo cdpPageInfo = new CDPPageInfo(startIndex > 0, lastIndex < properties.size());
+        final CDPPageInfo pageInfo = new CDPPageInfo(startIndex > 0, lastIndex < properties.size());
 
         final List<CDPPropertyEdge> edges = new ArrayList<>(properties)
                 .subList(startIndex, lastIndex)
                 .stream()
                 .map(CDPPropertyEdge::new)
                 .collect(Collectors.toList());
-        return new CDPPropertyConnection(edges, cdpPageInfo);
+        return new CDPPropertyConnection(edges, pageInfo);
     }
 }
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/segment/FindSegmentsConnectionDataFetcher.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/segment/FindSegmentsConnectionDataFetcher.java
index 1b2ce2b..3696ea2 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/segment/FindSegmentsConnectionDataFetcher.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/fetchers/segment/FindSegmentsConnectionDataFetcher.java
@@ -50,8 +50,7 @@
         final ServiceManager serviceManager = environment.getContext();
         final ConnectionParams params = parseConnectionParams(environment);
 
-        final Condition condition = ProfileConditionFactory.get(environment)
-                .segmentFilterInputCondition(filterInput, params.getAfter(), params.getBefore());
+        final Condition condition = ProfileConditionFactory.get(environment).segmentFilterInputCondition(filterInput);
         final Query query = buildQuery(condition, orderByInput, params);
         final PartialList<Metadata> metas = serviceManager.getSegmentService().getSegmentMetadatas(query);
 
diff --git a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPQuery.java b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPQuery.java
index 01ae3e6..c61cc92 100644
--- a/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPQuery.java
+++ b/graphql/cxs-impl/src/main/java/org/apache/unomi/graphql/types/output/CDPQuery.java
@@ -74,7 +74,9 @@
 
     @GraphQLField
     public CDPPropertyConnection getProfileProperties(final @GraphQLName("first") Integer first,
+                                                      final @GraphQLName("after") String after,
                                                       final @GraphQLName("last") Integer last,
+                                                      final @GraphQLName("before") String before,
                                                       final DataFetchingEnvironment environment) throws Exception {
         return new PropertiesConnectionDataFetcher().get(environment);
     }