diff --git a/duniter4j-core-client/src/license/THIRD-PARTY.properties b/duniter4j-core-client/src/license/THIRD-PARTY.properties
new file mode 100644
index 0000000000000000000000000000000000000000..2258c131248f649ad89834ea9403a32beceedee8
--- /dev/null
+++ b/duniter4j-core-client/src/license/THIRD-PARTY.properties
@@ -0,0 +1,22 @@
+# Generated by org.codehaus.mojo.license.AddThirdPartyMojo
+#-------------------------------------------------------------------------------
+# Already used licenses in project :
+# - BSD License
+# - CDDL+GPL
+# - COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
+# - Dual license consisting of the CDDL v1.1 and GPL v2
+# - Eclipse Public License 1.0
+# - General Public License (GPL) v3
+# - Indiana University Extreme! Lab Software License, vesion 1.1.1
+# - Lesser General Public License (LGPL) v 3.0
+# - Lesser General Public License (LPGL)
+# - Lesser General Public License (LPGL) v 2.1
+# - MIT License
+# - New BSD License
+# - The Apache Software License, Version 2.0
+#-------------------------------------------------------------------------------
+# Please fill the missing licenses for dependencies :
+#
+#
+#Wed Nov 16 11:35:31 CET 2016
+commons-primitives--commons-primitives--1.0=The Apache Software License, Version 2.0
diff --git a/duniter4j-core-shared/src/license/THIRD-PARTY.properties b/duniter4j-core-shared/src/license/THIRD-PARTY.properties
new file mode 100644
index 0000000000000000000000000000000000000000..7a2eb6f874024ea8f103301e8cd45e68e4276ae2
--- /dev/null
+++ b/duniter4j-core-shared/src/license/THIRD-PARTY.properties
@@ -0,0 +1,20 @@
+# Generated by org.codehaus.mojo.license.AddThirdPartyMojo
+#-------------------------------------------------------------------------------
+# Already used licenses in project :
+# - BSD License
+# - COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
+# - Dual license consisting of the CDDL v1.1 and GPL v2
+# - Eclipse Public License 1.0
+# - Indiana University Extreme! Lab Software License, vesion 1.1.1
+# - Lesser General Public License (LGPL) v 3.0
+# - Lesser General Public License (LPGL)
+# - Lesser General Public License (LPGL) v 2.1
+# - MIT License
+# - New BSD License
+# - The Apache Software License, Version 2.0
+#-------------------------------------------------------------------------------
+# Please fill the missing licenses for dependencies :
+#
+#
+#Wed Nov 16 11:35:28 CET 2016
+commons-primitives--commons-primitives--1.0=The Apache Software License, Version 2.0
diff --git a/duniter4j-core-shared/src/main/java/org/duniter/core/util/websocket/WebsocketClientEndpoint.java b/duniter4j-core-shared/src/main/java/org/duniter/core/util/websocket/WebsocketClientEndpoint.java
index 277334276ee0930a87ad5efbfc6adcdf6e368779..3f2bea6ed7304f57fe8ba22b0ee7fad7a4142d91 100644
--- a/duniter4j-core-shared/src/main/java/org/duniter/core/util/websocket/WebsocketClientEndpoint.java
+++ b/duniter4j-core-shared/src/main/java/org/duniter/core/util/websocket/WebsocketClientEndpoint.java
@@ -195,7 +195,7 @@ public class WebsocketClientEndpoint implements Closeable {
             } catch (Exception e) {
                 notifyConnectionError(e);
                 if (!this.autoReconnect) throw new TechnicalException(e);
-                log.warn(String.format("[%s] Unable to connect. Retrying in 10s...", endpointURI.toString()));
+                log.warn(String.format("[%s] Unable to connect [%s]. Retrying in 10s...", endpointURI.toString(), e.getMessage()));
             }
 
             // wait 10s, then try again
diff --git a/duniter4j-es-assembly/src/license/THIRD-PARTY.properties b/duniter4j-es-assembly/src/license/THIRD-PARTY.properties
new file mode 100644
index 0000000000000000000000000000000000000000..8610ec5bda0d6673a7c224b7fd16226cc1bcd664
--- /dev/null
+++ b/duniter4j-es-assembly/src/license/THIRD-PARTY.properties
@@ -0,0 +1,26 @@
+# Generated by org.codehaus.mojo.license.AddThirdPartyMojo
+#-------------------------------------------------------------------------------
+# Already used licenses in project :
+# - ASL, version 2
+# - Apache License 2.0
+# - Apache License Version 2.0
+# - BSD License
+# - CC0 1.0 Universal
+# - COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
+# - Eclipse Public License 1.0
+# - General Public License (GPL) v3
+# - Indiana University Extreme! Lab Software License, vesion 1.1.1
+# - LGPL, version 2.1
+# - Lesser General Public License (LGPL) v 3.0
+# - Lesser General Public License (LPGL)
+# - Lesser General Public License (LPGL) v 2.1
+# - MIT License
+# - New BSD License
+# - Public Domain, per Creative Commons CC0
+# - The Apache Software License, Version 2.0
+#-------------------------------------------------------------------------------
+# Please fill the missing licenses for dependencies :
+#
+#
+#Tue Jan 05 15:24:57 CET 2016
+commons-primitives--commons-primitives--1.0=The Apache Software License, Version 2.0
diff --git a/duniter4j-es-assembly/src/main/assembly/config/elasticsearch.yml b/duniter4j-es-assembly/src/main/assembly/config/elasticsearch.yml
index f63204e119ba7427444c36e3447ca94848216453..ad6f799de36bb579155407b98e5246dc04382cd9 100644
--- a/duniter4j-es-assembly/src/main/assembly/config/elasticsearch.yml
+++ b/duniter4j-es-assembly/src/main/assembly/config/elasticsearch.yml
@@ -114,7 +114,7 @@ security.manager.enabled: false
 # Reset and reload all Duniter4j data at startup - DO SET to true in production
 #
 # duniter.indices.reload: true
-#
+#:
 # Default string analyzer
 #
 duniter.string.analyzer: french
@@ -130,6 +130,11 @@ duniter.port: 9330
 #
 # ---------------------------------- Duniter4j security -------------------------
 #
+# Allow admin actions
+#
+#duniter.keyring.salt:
+#duniter.keyring.password:
+#
 # Enable security, to disable HTTP access to the default ES admin API
 #
 duniter.security.enable: true
diff --git a/duniter4j-es-assembly/src/test/es-home/config/elasticsearch.yml b/duniter4j-es-assembly/src/test/es-home/config/elasticsearch.yml
index 8e0079e2987d7e977932863296ea64379aaef16a..cfc87eedc05750b8a381b72b2aa85a5b8c471ed9 100644
--- a/duniter4j-es-assembly/src/test/es-home/config/elasticsearch.yml
+++ b/duniter4j-es-assembly/src/test/es-home/config/elasticsearch.yml
@@ -128,7 +128,8 @@ duniter.blockchain.sync.enable: true
 #
 #duniter.host: cgeek.fr
 #duniter.port: 9330
-duniter.host: test-net.duniter.fr
+#duniter.host: test-net.duniter.fr
+duniter.host: 192.168.0.5
 duniter.port: 9201
 #duniter.host: 192.168.0.28
 #duniter.port: 21378
@@ -141,7 +142,7 @@ duniter.keyring.password: def
 # Enable security, to disable HTTP access to the default ES admin API
 #
 #duniter.security.enable: false
-duniter.security.enable: false
+duniter.security.enable: true
 #
 # Security token prefix (default: 'duniter-')
 #
diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/AbstractRestPostMarkAsReadAction.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/AbstractRestPostMarkAsReadAction.java
index 7be26a52d1e331e977f70b4e0733d8a824376bcf..122f1120fdaa6c3d6bfa277010c2e86b570eb617 100644
--- a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/AbstractRestPostMarkAsReadAction.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/AbstractRestPostMarkAsReadAction.java
@@ -50,7 +50,7 @@ public abstract class AbstractRestPostMarkAsReadAction extends BaseRestHandler {
         controller.registerHandler(POST,
                 String.format("/%s/%s/{id}/_read", indexName, typeName),
                 this);
-        securityController.allowIndexType(POST, indexName, typeName);
+        securityController.allow(POST, String.format("/%s/%s/[^/]+/_read", indexName, typeName));
         log = ESLoggerFactory.getLogger(String.format("[%s]", indexName));
         this.updater = updater;
     }
diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/AbstractSynchroService.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/AbstractSynchroService.java
index 4a82e385ee766255633262d2c89c87df6d4a0048..5ebf469a1e251f08698d7ba10b67b413baf41424 100644
--- a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/AbstractSynchroService.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/AbstractSynchroService.java
@@ -189,8 +189,8 @@ public abstract class AbstractSynchroService extends AbstractService {
 
         node = node.get("hits");
         int total = node == null ? 0 : node.get("total").asInt(0);
-        if (logger.isDebugEnabled()) {
-            logger.debug(String.format("[%s] [%s/%s] total to update: %s", peer, toIndex, toType, total));
+        if (logger.isDebugEnabled() && offset == 0) {
+            logger.debug(String.format("[%s] [%s/%s] Rows to update: %s", peer, toIndex, toType, total));
         }
 
         boolean debug = logger.isTraceEnabled();
diff --git a/duniter4j-es-gchange/src/main/resources/i18n/duniter4j-es-gchange_en_GB.properties b/duniter4j-es-gchange/src/main/resources/i18n/duniter4j-es-gchange_en_GB.properties
new file mode 100644
index 0000000000000000000000000000000000000000..dd29729a2e711db27e13cfc3f804fa441d74b608
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/resources/i18n/duniter4j-es-gchange_en_GB.properties
@@ -0,0 +1,12 @@
+duniter.event.NODE_BMA_DOWN=
+duniter.event.NODE_BMA_UP=
+duniter.market.error.comment.recordNotFound=Ad [%s] referenced by comment not found
+duniter.market.event.newComment=
+duniter.market.event.newReplyComment=
+duniter.market.event.updateComment=
+duniter.market.event.updateReplyComment=
+duniter.registry.error.comment.recordNotFound=Record [%s] referenced by comment not found
+duniter.registry.event.newComment=
+duniter.registry.event.newReplyComment=
+duniter.registry.event.updateComment=
+duniter.registry.event.updateReplyComment=
diff --git a/duniter4j-es-gchange/src/main/resources/i18n/duniter4j-es-gchange_fr_FR.properties b/duniter4j-es-gchange/src/main/resources/i18n/duniter4j-es-gchange_fr_FR.properties
new file mode 100644
index 0000000000000000000000000000000000000000..40d7fb34f50c9be5947023487bda6434025fa243
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/resources/i18n/duniter4j-es-gchange_fr_FR.properties
@@ -0,0 +1,12 @@
+duniter.event.NODE_BMA_DOWN=
+duniter.event.NODE_BMA_UP=
+duniter.market.error.comment.recordNotFound=L'annonce [%s] référencée par le commentaire n'existe pas.
+duniter.market.event.newComment=%2$s a commenté votre annonce '%3$s'
+duniter.market.event.newReplyComment=%2$s a répondu à votre commentaire sur l'annonce '%3$s'
+duniter.market.event.updateComment=%2$s a mise à jour son commentaire sur votre annonce '%3$s'
+duniter.market.event.updateReplyComment=%2$s a modifié sa réponse à votre commentaire, sur l'annonce '%3$s'
+duniter.registry.error.comment.recordNotFound=Le référencement [%s] référencée par le commentaire n'existe pas.
+duniter.registry.event.newComment=%2$s a commenté votre référencement '%3$s'
+duniter.registry.event.newReplyComment=%2$s a répondu à votre commentaire sur le référencement '%3$s'
+duniter.registry.event.updateComment=%2$s a modifié son commentaire sur votre référencement '%3$s'
+duniter.registry.event.updateReplyComment=%2$s a modifié sa réponse à votre commentaire, sur le référencement '%3$s'
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/user/RestUserEventMarkAsReadAction.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/user/RestUserEventMarkAsReadAction.java
index 3dad8d61edcb703956b8e0ce3a4cd3a48e246feb..a2d545d8425815199b2ce4c365370c428d8ce522 100644
--- a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/user/RestUserEventMarkAsReadAction.java
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/user/RestUserEventMarkAsReadAction.java
@@ -37,8 +37,6 @@ public class RestUserEventMarkAsReadAction extends AbstractRestPostMarkAsReadAct
                                          RestSecurityController securityController,
                                          UserEventService userEventService) {
         super(settings, controller, client, securityController, UserEventService.INDEX, UserEventService.EVENT_TYPE,
-                (id, signature) -> {
-                    userEventService.markEventAsRead(id, signature);
-                });
+                (id, signature) -> userEventService.markEventAsRead(id, signature));
     }
 }
\ No newline at end of file
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/UserEventService.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/UserEventService.java
index ec6d857dc76712ea107dd70ea2ae4db7642dde56..66f7124901b981fba882cc0b87aebb8aa1b28f8b 100644
--- a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/UserEventService.java
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/UserEventService.java
@@ -63,6 +63,7 @@ import org.nuiton.i18n.I18n;
 
 import java.io.IOException;
 import java.util.*;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Created by Benoit on 30/03/2015.
@@ -100,6 +101,7 @@ public class UserEventService extends AbstractService implements ChangeService.C
     public final KeyPair nodeKeyPair;
     public final String nodePubkey;
     public final boolean mailEnable;
+    public final boolean trace;
 
     @Inject
     public UserEventService(final Client client,
@@ -113,7 +115,8 @@ public class UserEventService extends AbstractService implements ChangeService.C
         this.nodeKeyPair = getNodeKeyPairOrNull(pluginSettings);
         this.nodePubkey = getNodePubKey(nodeKeyPair);
         this.mailEnable = pluginSettings.getMailEnable();
-        if (!this.mailEnable && logger.isTraceEnabled()) {
+        this.trace = logger.isTraceEnabled();
+        if (!this.mailEnable && this.trace) {
             logger.trace("Mail disable");
         }
 
@@ -486,12 +489,18 @@ public class UserEventService extends AbstractService implements ChangeService.C
 
             switch (change.getOperation()) {
                 // on create
+                case CREATE:
+                    if (change.getSource() != null) {
+                        UserEvent event = objectMapper.readValue(change.getSource().streamInput(), UserEvent.class);
+                        processEventCreate(change.getId(), event);
+                    }
+                    break;
+
                 // on update
                 case INDEX:
-                case CREATE: // create
                     if (change.getSource() != null) {
                         UserEvent event = objectMapper.readValue(change.getSource().streamInput(), UserEvent.class);
-                        processEventCreateOrUpdate(change.getId(), event);
+                        processEventUpdate(change.getId(), event);
                     }
                     break;
 
@@ -509,7 +518,7 @@ public class UserEventService extends AbstractService implements ChangeService.C
 
     }
 
-    private void processEventCreateOrUpdate(final String eventId, final UserEvent event) {
+    private void processEventCreate(final String eventId, final UserEvent event) {
 
         event.setId(eventId);
 
@@ -526,4 +535,15 @@ public class UserEventService extends AbstractService implements ChangeService.C
 
     }
 
+    private void processEventUpdate(final String eventId, final UserEvent event) {
+
+        // Skip if user has already read the event
+        if (StringUtils.isNotBlank(event.getReadSignature())) {
+            if (this.trace) logger.trace("Updated event already read: Skip propagation to listeners");
+            return;
+        }
+
+        processEventCreate(eventId, event);
+    }
+
 }