diff --git a/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java b/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java
index 737e0819d4c85cc3f53c7aae600eb1dddb4b5718..ef68c552e7e637e1fd0f05ad91fe9b7c8112265d 100644
--- a/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java
+++ b/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java
@@ -16,6 +16,11 @@ import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+/**
+ * An {@link java.util.EventListener} in charge of reaction to Keycloak models
+ * modification (e.g. User creation, Group deletion, membership modifications...)
+ * by propagating it to all registered SCIM servers.
+ */
 public class ScimEventListenerProvider implements EventListenerProvider {
 
     private static final Logger LOGGER = Logger.getLogger(ScimEventListenerProvider.class);
@@ -36,14 +41,13 @@ public class ScimEventListenerProvider implements EventListenerProvider {
         dispatcher = new ScimDispatcher(session);
     }
 
-    @Override
-    public void close() {
-    }
 
     @Override
     public void onEvent(Event event) {
+        // React to User-related event : creation, deletion, update
         EventType eventType = event.getType();
         String eventUserId = event.getUserId();
+        LOGGER.infof("[SCIM] Propagate User Event %s - %s", eventType, eventUserId);
         switch (eventType) {
             case REGISTER -> {
                 UserModel user = getUser(eventUserId);
@@ -54,81 +58,123 @@ public class ScimEventListenerProvider implements EventListenerProvider {
                 dispatcher.dispatchUserModificationToAll(client -> client.replace(user));
             }
             case DELETE_ACCOUNT -> dispatcher.dispatchUserModificationToAll(client -> client.delete(eventUserId));
-            default -> LOGGER.trace("ignore event " + eventType);
+            default -> {
+                // No other event has to be propagated to SCIM Servers
+            }
         }
     }
 
     @Override
     public void onEvent(AdminEvent event, boolean includeRepresentation) {
+        // Step 1: check if event is relevant for propagation through SCIM
         Pattern pattern = patterns.get(event.getResourceType());
         if (pattern == null)
             return;
         Matcher matcher = pattern.matcher(event.getResourcePath());
         if (!matcher.find())
             return;
+
+        // Step 2: propagate event (if needed) according to its resource type
         switch (event.getResourceType()) {
             case USER -> {
                 String userId = matcher.group(1);
-                LOGGER.infof("%s %s", userId, event.getOperationType());
-                switch (event.getOperationType()) {
-                    case CREATE -> {
-                        UserModel user = getUser(userId);
-                        dispatcher.dispatchUserModificationToAll(client -> client.create(user));
-                        user.getGroupsStream().forEach(group -> {
-                            dispatcher.dispatchGroupModificationToAll(client -> client.replace(group));
-                        });
-                    }
-                    case UPDATE -> {
-                        UserModel user = getUser(userId);
-                        dispatcher.dispatchUserModificationToAll(client -> client.replace(user));
-                    }
-                    case DELETE -> dispatcher.dispatchUserModificationToAll(client -> client.delete(userId));
-                }
+                handleUserEvent(event, userId);
             }
             case GROUP -> {
                 String groupId = matcher.group(1);
-                LOGGER.infof("group %s %s", groupId, event.getOperationType());
-                switch (event.getOperationType()) {
-                    case CREATE -> {
-                        GroupModel group = getGroup(groupId);
-                        dispatcher.dispatchGroupModificationToAll(client -> client.create(group));
-                    }
-                    case UPDATE -> {
-                        GroupModel group = getGroup(groupId);
-                        dispatcher.dispatchGroupModificationToAll(client -> client.replace(group));
-                    }
-                    case DELETE -> dispatcher.dispatchGroupModificationToAll(client -> client.delete(groupId));
-                }
+                handleGroupEvent(event, groupId);
             }
             case GROUP_MEMBERSHIP -> {
                 String userId = matcher.group(1);
                 String groupId = matcher.group(2);
-                LOGGER.infof("%s %s from %s", event.getOperationType(), userId, groupId);
-                GroupModel group = getGroup(groupId);
-                group.setSingleAttribute("scim-dirty", BooleanUtils.TRUE);
-                UserModel user = getUser(userId);
-                dispatcher.dispatchUserModificationToAll(client -> client.replace(user));
+                handleGroupMemberShipEvent(event, userId, groupId);
             }
             case REALM_ROLE_MAPPING -> {
                 String type = matcher.group(1);
                 String id = matcher.group(2);
-                LOGGER.infof("%s %s %s roles", event.getOperationType(), type, id);
-                switch (type) {
-                    case "users" -> {
-                        UserModel user = getUser(id);
-                        dispatcher.dispatchUserModificationToAll(client -> client.replace(user));
-                    }
-                    case "groups" -> {
-                        GroupModel group = getGroup(id);
-                        session.users().getGroupMembersStream(session.getContext().getRealm(), group).forEach(user -> {
-                            dispatcher.dispatchUserModificationToAll(client -> client.replace(user));
-                        });
-                    }
-                }
+                handleRoleMappingEvent(event, type, id);
+            }
+            default -> {
+                // No other resource modification has to be propagated to SCIM Servers
+            }
+        }
+    }
+
+    private void handleUserEvent(AdminEvent userEvent, String userId) {
+        LOGGER.infof("[SCIM] Propagate User %s - %s", userEvent.getOperationType(), userId);
+        switch (userEvent.getOperationType()) {
+            case CREATE -> {
+                UserModel user = getUser(userId);
+                dispatcher.dispatchUserModificationToAll(client -> client.create(user));
+                user.getGroupsStream().forEach(group ->
+                        dispatcher.dispatchGroupModificationToAll(client -> client.replace(group)
+                        ));
+            }
+            case UPDATE -> {
+                UserModel user = getUser(userId);
+                dispatcher.dispatchUserModificationToAll(client -> client.replace(user));
+            }
+            case DELETE -> dispatcher.dispatchUserModificationToAll(client -> client.delete(userId));
+            default -> {
+                // ACTION userEvent are not relevant, nothing to do
+            }
+        }
+    }
+
+    /**
+     * Propagating the given group-related event to SCIM servers.
+     *
+     * @param event   the event to propagate
+     * @param groupId event target's id
+     */
+    private void handleGroupEvent(AdminEvent event, String groupId) {
+        LOGGER.infof("[SCIM] Propagate Group %s - %s", event.getOperationType(), groupId);
+        switch (event.getOperationType()) {
+            case CREATE -> {
+                GroupModel group = getGroup(groupId);
+                dispatcher.dispatchGroupModificationToAll(client -> client.create(group));
+            }
+            case UPDATE -> {
+                GroupModel group = getGroup(groupId);
+                dispatcher.dispatchGroupModificationToAll(client -> client.replace(group));
+            }
+            case DELETE -> dispatcher.dispatchGroupModificationToAll(client -> client.delete(groupId));
+            default -> {
+                // ACTION event are not relevant, nothing to do
             }
         }
     }
 
+    private void handleGroupMemberShipEvent(AdminEvent groupMemberShipEvent, String userId, String groupId) {
+        LOGGER.infof("[SCIM] Propagate GroupMemberShip %s - User %s Group %s", groupMemberShipEvent.getOperationType(), userId, groupId);
+        GroupModel group = getGroup(groupId);
+        group.setSingleAttribute("scim-dirty", BooleanUtils.TRUE);
+        UserModel user = getUser(userId);
+        dispatcher.dispatchUserModificationToAll(client -> client.replace(user));
+    }
+
+    private void handleRoleMappingEvent(AdminEvent roleMappingEvent, String type, String id) {
+        LOGGER.infof("[SCIM] Propagate RoleMapping %s - %s %s", roleMappingEvent.getOperationType(), type, id);
+        switch (type) {
+            case "users" -> {
+                UserModel user = getUser(id);
+                dispatcher.dispatchUserModificationToAll(client -> client.replace(user));
+            }
+            case "groups" -> {
+                GroupModel group = getGroup(id);
+                session.users()
+                        .getGroupMembersStream(session.getContext().getRealm(), group)
+                        .forEach(user ->
+                                dispatcher.dispatchUserModificationToAll(client -> client.replace(user)
+                                ));
+            }
+            default -> {
+                // No other type is relevant for propagation
+            }
+        }
+    }
+
+
     private UserModel getUser(String id) {
         return session.users().getUserById(session.getContext().getRealm(), id);
     }
@@ -136,4 +182,10 @@ public class ScimEventListenerProvider implements EventListenerProvider {
     private GroupModel getGroup(String id) {
         return session.groups().getGroupById(session.getContext().getRealm(), id);
     }
+
+    @Override
+    public void close() {
+        // Nothing to close here
+    }
+
 }
diff --git a/src/main/java/sh/libre/scim/event/ScimEventListenerProviderFactory.java b/src/main/java/sh/libre/scim/event/ScimEventListenerProviderFactory.java
index debe59b8fb75f30b9aecacbb5d83c5e2e83385cf..c7b437a287dcb0aa1001a134aad3749505b06925 100644
--- a/src/main/java/sh/libre/scim/event/ScimEventListenerProviderFactory.java
+++ b/src/main/java/sh/libre/scim/event/ScimEventListenerProviderFactory.java
@@ -13,20 +13,24 @@ public class ScimEventListenerProviderFactory implements EventListenerProviderFa
         return new ScimEventListenerProvider(session);
     }
 
+    @Override
+    public String getId() {
+        return "scim";
+    }
+
     @Override
     public void init(Scope config) {
+        // Nothing to initialize
     }
 
     @Override
     public void postInit(KeycloakSessionFactory factory) {
+        // Nothing to initialize
     }
 
     @Override
     public void close() {
+        // Nothing to close
     }
 
-    @Override
-    public String getId() {
-        return "scim";
-    }
 }