diff --git a/doc/fr/development_tutorial.md b/doc/fr/development_tutorial.md
index 27bcfc6a635d9fbeceb728dede7ad9629b18c5f2..2cccc2296acd6a0be3f07a0ecf279fc0a84499eb 100644
--- a/doc/fr/development_tutorial.md
+++ b/doc/fr/development_tutorial.md
@@ -286,7 +286,7 @@ Ouvrir votre IDE, et ouvrir le projet Duniter4j.
 
 Dans le répertoire `duniter4j-elasticsearch/src/main/java`, cherchez et répérez dans le code : 
 
-- les controlleurs REST : package `org.duniter.elasticsearch.action`
+- les controlleurs REST : package `org.duniter.elasticsearch.rest`
 - les services d'indexation : package `org.duniter.elasticsearch.service`.
   * Il existe un service d'indexation par type de stockage. Par exemple : `BlockchainService`, `UserService`, etc.
 
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/Constants.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/Constants.java
index ff2ee8c223377fddab75f03100c7c2bc9e1b115f..1df3da70caa447790e09943d22cce224f1a94be9 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/Constants.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/Constants.java
@@ -28,6 +28,8 @@ package org.duniter.core.client.model.bma;
 public interface Constants {
 
     interface Regex {
-        String CURRENCY_NAME = "[a-zA-Z_-]";
+        String USER_ID = "[A-Za-z0-9_-]+";
+        String CURRENCY_NAME = "[A-Za-z0-9_-]";
+        String PUBKEY = "[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{43,44}";
     }
 }
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/elasticsearch/Event.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/elasticsearch/Event.java
index d535ad58ac20900c119e114a00f4adea169c33a4..ffb926ef1667ab97320e004160c565a38b2fa812 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/elasticsearch/Event.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/elasticsearch/Event.java
@@ -1,5 +1,27 @@
 package org.duniter.core.client.model.elasticsearch;
 
+/*
+ * #%L
+ * Duniter4j :: Core Client API
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
 import org.nuiton.i18n.I18n;
 
 import java.util.Locale;
diff --git a/duniter4j-core-shared/src/main/java/org/duniter/core/service/MailService.java b/duniter4j-core-shared/src/main/java/org/duniter/core/service/MailService.java
index 3bb0859189f10e3be065383d02050baf2420866f..64975b25ce5240bdece733be974e4a995e0f3977 100644
--- a/duniter4j-core-shared/src/main/java/org/duniter/core/service/MailService.java
+++ b/duniter4j-core-shared/src/main/java/org/duniter/core/service/MailService.java
@@ -1,5 +1,27 @@
 package org.duniter.core.service;
 
+/*
+ * #%L
+ * Duniter4j :: Core Shared
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
 import org.duniter.core.beans.Bean;
 import org.duniter.core.exception.TechnicalException;
 
diff --git a/duniter4j-core-shared/src/main/java/org/duniter/core/service/MailServiceImpl.java b/duniter4j-core-shared/src/main/java/org/duniter/core/service/MailServiceImpl.java
index d217524284f599a30280685c129820f15139a4f9..ec7bb898b1ffd51c2e62049835e3fe7ad6257931 100644
--- a/duniter4j-core-shared/src/main/java/org/duniter/core/service/MailServiceImpl.java
+++ b/duniter4j-core-shared/src/main/java/org/duniter/core/service/MailServiceImpl.java
@@ -1,5 +1,27 @@
 package org.duniter.core.service;
 
+/*
+ * #%L
+ * Duniter4j :: Core Shared
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
 import org.duniter.core.exception.TechnicalException;
 import org.duniter.core.util.StringUtils;
 
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/cli/action/HelpCliAction.java b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/cli/action/HelpCliAction.java
deleted file mode 100644
index 5fd18e0be55780c9e0aa94c360046f299aecf043..0000000000000000000000000000000000000000
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/cli/action/HelpCliAction.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.duniter.elasticsearch.cli.action;
-
-/*
- * #%L
- * SIH-Adagio :: Shared
- * $Id:$
- * $HeadURL:$
- * %%
- * Copyright (C) 2012 - 2014 Ifremer
- * %%
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, either version 3 of the 
- * License, or (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program.  If not, see
- * <http://www.gnu.org/licenses/gpl-3.0.html>.
- * #L%
- */
-
-public class HelpCliAction {
-
-	public void show() {
-		StringBuilder sb = new StringBuilder();
-
-		sb.append("Usage: duniter4j-elaticsearch.<sh|bat> <commands> [options]\n\n")
-				.append("Commands:\n\n")
-				.append(" start                            Start elastic search node\n")
-				.append(" index                            Index blocks from BMA Node\n")
-				.append(" reset-data                       Reset all indexed data (blocks and records)\n")
-				.append(" reset-data-blocks                Reset only indexed blocks (from uCoin node's)\n")
-				.append(" reset-data-records               Reset only indexed records\n")
-				.append("\n")
-				.append("\n")
-				.append("Options:\n\n")
-				.append(" --help                           Output usage information\n")
-				.append(" -h --host <user>		           uCoin node host (with Basic Merkled API)\n")
-				.append(" -p --port <pwd> 		           uCoin node port (with Basic Merkled API)\n")
-				.append("\n")
-				.append(" -esh  --es-host <user>           ElasticSearch node host\n")
-				.append(" -esp  --es-port <pwd>            ElasticSearch node port\n");
-
-		System.out.println(sb.toString());
-	}
-}
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/cli/action/IndexerCliAction.java b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/cli/action/IndexerCliAction.java
deleted file mode 100644
index 5220383c2343d76ebfad5c27917241646449a6dd..0000000000000000000000000000000000000000
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/cli/action/IndexerCliAction.java
+++ /dev/null
@@ -1,187 +0,0 @@
-package org.duniter.elasticsearch.cli.action;
-
-/*
- * #%L
- * SIH-Adagio :: Shared
- * $Id:$
- * $HeadURL:$
- * %%
- * Copyright (C) 2012 - 2014 Ifremer
- * %%
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, either version 3 of the 
- * License, or (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program.  If not, see
- * <http://www.gnu.org/licenses/gpl-3.0.html>.
- * #L%
- */
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class IndexerCliAction {
-	/* Logger */
-	private static final Logger log = LoggerFactory.getLogger(IndexerCliAction.class);
-
-    /*
-    public void indexBlocksFromNode() {
-
-        final boolean async = ServiceLocator.instance().getElasticSearchService().isNodeInstance();
-
-        Runnable runnable = new Runnable() {
-            @Override
-            public void run() {
-                PluginSettings config = PluginSettings.instance();
-                final Peer peer = checkConfigAndGetPeer(config);
-                final BlockchainService blockIndexerService = ServiceLocator.instance().getBlockIndexerService();
-
-                // Will create the blockchain if not exist
-                blockIndexerService.indexLastBlocks(peer);
-
-                if (async) {
-                    ServiceLocator.instance().getBlockchainRemoteService().addNewBlockListener(peer, new WebsocketClientEndpoint.MessageHandler() {
-                        @Override
-                        public void handleMessage(String message) {
-                            String currencyName = GsonUtils.getValueFromJSONAsString(message, "blockchain");
-                            *///blockIndexerService.indexLastBlockFromJson(peer, message, true /*refresh*/, true /*wait*/);
-                            //blockIndexerService.indexCurrentBlockAsJson(currencyName, message, true /*wait*/);
-               /*         }
-                    });
-                }
-            }
-        };
-
-        // Async execution
-        if (async) {
-            ServiceLocator.instance().getExecutorService().execute(runnable);
-        }
-
-        // Synchrone execution
-        else {
-            runnable.run();
-        }
-    }
-
-    public void resetAllData() {
-        resetAllCurrencies();
-        resetDataBlocks();
-        resetMarketRecords();
-        resetRegistry();
-    }
-
-    public void resetAllCurrencies() {
-        CurrencyRegistryService currencyIndexerService = ServiceLocator.instance().getRegistryCurrencyIndexerService();
-        currencyIndexerService.deleteAllCurrencies();
-    }
-
-    public void resetDataBlocks() {
-        BlockchainRemoteService blockchainService = ServiceLocator.instance().getBlockchainRemoteService();
-        BlockchainService indexerService = ServiceLocator.instance().getBlockIndexerService();
-        PluginSettings config = PluginSettings.instance();
-        Peer peer = checkConfigAndGetPeer(config);
-
-        try {
-            // Get the blockchain name from node
-            BlockchainParameters parameter = blockchainService.getParameters(peer);
-            if (parameter == null) {
-                log.error(String.format("Could not connect to node [%s:%s]",
-                        config.getNodeBmaHost(), config.getNodeBmaPort()));
-                return;
-            }
-            String currencyName = parameter.getCurrency();
-
-            log.info(String.format("Reset data for index [%s]", currencyName));
-
-            // Delete then create index on blockchain
-            boolean indexExists = indexerService.existsIndex(currencyName);
-            if (indexExists) {
-                indexerService.deleteIndex(currencyName);
-                indexerService.createIndex(currencyName);
-            }
-
-
-            log.info(String.format("Successfully reset data for index [%s]", currencyName));
-        } catch(Exception e) {
-            log.error("Error during reset data: " + e.getMessage(), e);
-        }
-    }
-
-    public void resetMarketRecords() {
-        RecordMarketService recordIndexerService = ServiceLocator.instance().getMarketRecordIndexerService();
-        CategoryMarketService categoryIndexerService = ServiceLocator.instance().getMarketCategoryIndexerService();
-
-        try {
-            // Delete then create index on records
-            boolean indexExists = recordIndexerService.existsIndex();
-            if (indexExists) {
-                recordIndexerService.deleteIndex();
-            }
-            log.info(String.format("Successfully reset market records"));
-
-            categoryIndexerService.createIndex();
-            categoryIndexerService.initCategories();
-            log.info(String.format("Successfully re-initialized market categories data"));
-
-        } catch(Exception e) {
-            log.error("Error during reset market records: " + e.getMessage(), e);
-        }
-    }
-
-    public void resetRegistry() {
-        RecordRegistryService recordIndexerService = ServiceLocator.instance().getRegistryRecordIndexerService();
-        CategoryRegistryService categoryIndexerService = ServiceLocator.instance().getRegistryCategoryIndexerService();
-        CitiesRegistryService citiesIndexerService = ServiceLocator.instance().getRegistryCitiesIndexerService();
-
-        try {
-            // Delete then create index on records
-            if (recordIndexerService.existsIndex()) {
-                recordIndexerService.deleteIndex();
-            }
-            recordIndexerService.createIndex();
-            log.info(String.format("Successfully reset registry records"));
-
-
-            if (categoryIndexerService.existsIndex()) {
-                categoryIndexerService.deleteIndex();
-            }
-            categoryIndexerService.createIndex();
-            categoryIndexerService.initCategories();
-            log.info(String.format("Successfully re-initialized registry categories"));
-
-            if (citiesIndexerService.existsIndex()) {
-                citiesIndexerService.deleteIndex();
-            }
-            citiesIndexerService.initCities();
-            log.info(String.format("Successfully re-initialized registry cities"));
-
-        } catch(Exception e) {
-            log.error("Error during reset registry records: " + e.getMessage(), e);
-        }
-    }*/
-
-    /* -- internal methods -- */
-
-    /*protected Peer checkConfigAndGetPeer(PluginSettings config) {
-        if (StringUtils.isBlank(config.getNodeBmaHost())) {
-            log.error("ERROR: node host is required");
-            System.exit(-1);
-            return null;
-        }
-        if (config.getNodeBmaPort() <= 0) {
-            log.error("ERROR: node port is required");
-            System.exit(-1);
-            return null;
-        }
-
-        Peer peer = new Peer(config.getNodeBmaHost(), config.getNodeBmaPort());
-        return peer;
-    }*/
-}
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/event/EventCodes.java b/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/event/EventCodes.java
deleted file mode 100644
index f790e04670df91961cc3c46d7d839193b4d9e91a..0000000000000000000000000000000000000000
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/event/EventCodes.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.duniter.elasticsearch.service.event;
-
-/**
- * Created by blavenie on 29/11/16.
- */
-public enum EventCodes {
-
-    NODE_STARTED
-}
diff --git a/duniter4j-elasticsearch/pom.xml b/duniter4j-es-assembly/pom.xml
similarity index 68%
rename from duniter4j-elasticsearch/pom.xml
rename to duniter4j-es-assembly/pom.xml
index b4d5c8d8e4b57d477c025bd158bd2fc15df1e649..b3acfffe1a74e7a0e6a6cf5ff43d396a2fc7ff4a 100644
--- a/duniter4j-elasticsearch/pom.xml
+++ b/duniter4j-es-assembly/pom.xml
@@ -8,163 +8,31 @@
   </parent>
 
   <groupId>org.duniter</groupId>
-  <artifactId>duniter4j-elasticsearch</artifactId>
-  <packaging>jar</packaging>
-  <name>Duniter4j :: ElasticSearch Plugin</name>
+  <artifactId>duniter4j-es-assembly</artifactId>
+  <packaging>pom</packaging>
+  <name>Duniter4j :: ElasticSearch Assembly</name>
 
   <properties>
     <!-- bundle configuration -->
-    <bundlePrefix>duniter4j-elasticsearch-${project.version}</bundlePrefix>
+    <bundlePrefix>duniter4j-es-${project.version}</bundlePrefix>
 
     <!-- i18n configuration -->
-    <i18n.bundleOutputName>duniter4j-elasticsearch-i18n</i18n.bundleOutputName>
+    <i18n.bundleOutputName>duniter4j-es-i18n</i18n.bundleOutputName>
     <i18n.generateCsvFile>true</i18n.generateCsvFile>
     <i18n.bundleCsvFile>
       ${maven.gen.dir}/resources/META-INF/${i18n.bundleOutputName}.csv
     </i18n.bundleCsvFile>
     <config.i18nBundleName>${i18n.bundleOutputName}</config.i18nBundleName>
-
-    <duniter4j-elasticsearch.config>${project.basedir}/src/test/resources/duniter4j-elasticsearch-test.properties</duniter4j-elasticsearch.config>
-
     <assembly.skip>false</assembly.skip>
   </properties>
 
-  <dependencies>
-    <dependency>
-      <groupId>org.duniter</groupId>
-      <artifactId>duniter4j-core-client</artifactId>
-      <version>${project.version}</version>
-      <exclusions>
-        <exclusion>
-          <groupId>com.google.guava</groupId>
-          <artifactId>guava</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <!-- LOGGING DEPENDENCIES - SLF4J -->
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-log4j12</artifactId>
-      <optional>true</optional>
-    </dependency>
-    <dependency>
-      <groupId>log4j</groupId>
-      <artifactId>log4j</artifactId>
-      <optional>true</optional>
-      <scope>runtime</scope>
-    </dependency>
-
-    <!-- Elastic Search -->
-    <dependency>
-      <groupId>org.elasticsearch</groupId>
-      <artifactId>elasticsearch</artifactId>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-databind</artifactId>
-    </dependency>
-
-    <!-- JNA (need for OS shutdown hook) -->
-    <dependency>
-      <groupId>net.java.dev.jna</groupId>
-      <artifactId>jna</artifactId>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>net.java.dev.jna</groupId>
-      <artifactId>jna-platform</artifactId>
-      <exclusions>
-        <exclusion>
-          <groupId>net.java.dev.jna</groupId>
-          <artifactId>jna</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-
-<!--
-    <dependency>
-        <groupId>com.github.spullara.mustache.java</groupId>
-        <artifactId>compiler</artifactId>
-        <version>0.8.13</version>
-        <scope>compile</scope>
-    </dependency>
--->
-
-    <dependency>
-      <groupId>org.glassfish.tyrus</groupId>
-      <artifactId>tyrus-server</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.glassfish.tyrus</groupId>
-      <artifactId>tyrus-container-grizzly-server</artifactId>
-    </dependency>
-
-    <!-- Unit test -->
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-
   <build>
-    <resources>
-      <resource>
-        <directory>src/main/filtered-resources</directory>
-        <filtering>true</filtering>
-        <includes>
-          <include>*.config</include>
-          <include>**/*.properties</include>
-        </includes>
-      </resource>
-      <resource>
-        <directory>src/main/resources</directory>
-        <filtering>false</filtering>
-      </resource>
-    </resources>
 
     <plugins>
-      <plugin>
-        <groupId>org.nuiton.i18n</groupId>
-        <artifactId>i18n-maven-plugin</artifactId>
-
-        <executions>
-          <execution>
-            <id>scan-sources</id>
-            <configuration>
-              <entries>
-                <entry>
-                  <specificGoal>parserValidation</specificGoal>
-                  <basedir>${maven.src.dir}/main/java/</basedir>
-                  <includes>
-                    <param>**/**-validation.xml</param>
-                  </includes>
-                </entry>
-              </entries>
-            </configuration>
-            <goals>
-              <goal>parserJava</goal>
-              <goal>parserValidation</goal>
-              <goal>gen</goal>
-            </goals>
-          </execution>
-          <execution>
-            <id>make-bundle</id>
-            <goals>
-              <goal>bundle</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-
       <plugin>
         <artifactId>maven-dependency-plugin</artifactId>
         <executions>
+          <!-- unpack ES -->
           <execution>
             <id>unpack-elasticsearch</id>
             <goals>
@@ -185,6 +53,8 @@
               <skip>${assembly.skip}</skip>
             </configuration>
           </execution>
+
+          <!-- unpack attachment plugin -->
           <execution>
             <id>unpack-mapper-attachments-plugin</id>
             <goals>
@@ -205,30 +75,78 @@
               <skip>${assembly.skip}</skip>
             </configuration>
           </execution>
-        </executions>
-      </plugin>
 
-      <plugin>
-        <artifactId>maven-assembly-plugin</artifactId>
-        <executions>
+          <!-- unpack ES core plugin -->
           <execution>
-            <id>assembly-plugin</id>
-            <phase>package</phase>
+            <id>unpack-es-core-plugin</id>
             <goals>
-              <goal>single</goal>
+              <goal>unpack</goal>
             </goals>
+            <phase>prepare-package</phase>
             <configuration>
-              <attach>true</attach>
-              <appendAssemblyId>false</appendAssemblyId>
-              <finalName>${bundlePrefix}</finalName>
-              <descriptors>
-                <descriptor>
-                  ${basedir}/src/main/assembly/plugin.xml
-                </descriptor>
-              </descriptors>
-              <skipAssembly>${assembly.skip}</skipAssembly>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>org.duniter</groupId>
+                  <artifactId>duniter4j-es-core</artifactId>
+                  <version>${project.version}</version>
+                  <type>zip</type>
+                </artifactItem>
+              </artifactItems>
+              <outputDirectory>${project.build.directory}/elasticsearch-${elasticsearch.version}/plugins/duniter4j-es-core</outputDirectory>
+              <silent>true</silent>
+              <skip>${assembly.skip}</skip>
+            </configuration>
+          </execution>
+
+          <!-- unpack ES user plugin -->
+          <execution>
+            <id>unpack-es-user-plugin</id>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <phase>prepare-package</phase>
+            <configuration>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>org.duniter</groupId>
+                  <artifactId>duniter4j-es-user</artifactId>
+                  <version>${project.version}</version>
+                  <type>zip</type>
+                </artifactItem>
+              </artifactItems>
+              <outputDirectory>${project.build.directory}/elasticsearch-${elasticsearch.version}/plugins/duniter4j-es-user</outputDirectory>
+              <silent>true</silent>
+              <skip>${assembly.skip}</skip>
+            </configuration>
+          </execution>
+
+          <!-- unpack ES gchange plugin -->
+          <execution>
+            <id>unpack-es-gchange-plugin</id>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <phase>prepare-package</phase>
+            <configuration>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>org.duniter</groupId>
+                  <artifactId>duniter4j-es-gchange</artifactId>
+                  <version>${project.version}</version>
+                  <type>zip</type>
+                </artifactItem>
+              </artifactItems>
+              <outputDirectory>${project.build.directory}/elasticsearch-${elasticsearch.version}/plugins/duniter4j-es-gchange</outputDirectory>
+              <silent>true</silent>
+              <skip>${assembly.skip}</skip>
             </configuration>
           </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <executions>
           <execution>
             <id>assembly-standalone</id>
             <phase>package</phase>
@@ -291,10 +209,14 @@
                       <!-- reuse standalone files -->
                       <then>
                         <delete failonerror="false">
-                          <fileset dir="${run.es.home}/plugins/${project.artifactId}" includes="${project.artifactId}-*.jar" />
+                          <fileset dir="${run.es.home}/plugins/${project.groupId}" includes="duniter4j-*.jar" />
                         </delete>
-                        <copy todir="${run.es.home}/plugins/${project.artifactId}" overwrite="true">
-                          <fileset dir="${project.build.directory}" includes="*.jar">
+                        <copy todir="${run.es.home}/plugins/${project.groupId}" overwrite="true">
+                          <fileset dir="../duniter4j-es-core/target" includes="duniter4j-*${project.version}.jar">
+                          </fileset>
+                          <fileset dir="../duniter4j-es-user/target" includes="duniter4j-*${project.version}.jar">
+                          </fileset>
+                          <fileset dir="../duniter4j-es-gchange/target" includes="duniter4j-*${project.version}.jar">
                           </fileset>
                         </copy>
                       </then>
diff --git a/duniter4j-elasticsearch/src/main/assembly/config/elasticsearch.yml b/duniter4j-es-assembly/src/main/assembly/config/elasticsearch.yml
similarity index 99%
rename from duniter4j-elasticsearch/src/main/assembly/config/elasticsearch.yml
rename to duniter4j-es-assembly/src/main/assembly/config/elasticsearch.yml
index bfde540b2c396897a130de459f70d8a50646490b..b7eec87e9594b461d3321849282c0960b7472524 100644
--- a/duniter4j-elasticsearch/src/main/assembly/config/elasticsearch.yml
+++ b/duniter4j-es-assembly/src/main/assembly/config/elasticsearch.yml
@@ -100,7 +100,7 @@ http.cors.enabled: true
 #
 # Require explicit names when deleting indices:
 #
-# action.destructive_requires_name: true
+# rest.destructive_requires_name: true
 
 security.manager.enabled: false
 
diff --git a/duniter4j-elasticsearch/src/main/assembly/config/logging.yml b/duniter4j-es-assembly/src/main/assembly/config/logging.yml
similarity index 98%
rename from duniter4j-elasticsearch/src/main/assembly/config/logging.yml
rename to duniter4j-es-assembly/src/main/assembly/config/logging.yml
index 2fe5b777407e59b7c2faae4cbbd61a94d93017b9..82d2ed08061ae5b56335db6048aeb3906777b52b 100644
--- a/duniter4j-elasticsearch/src/main/assembly/config/logging.yml
+++ b/duniter4j-es-assembly/src/main/assembly/config/logging.yml
@@ -2,7 +2,7 @@
 es.logger.level: INFO
 rootLogger: ${es.logger.level}, console, file
 logger:
-  # log action execution errors for easier debugging
+  # log rest execution errors for easier debugging
   action: DEBUG
 
   # deprecation logging, turn to DEBUG to see them
diff --git a/duniter4j-elasticsearch/src/main/assembly/standalone.xml b/duniter4j-es-assembly/src/main/assembly/standalone.xml
similarity index 63%
rename from duniter4j-elasticsearch/src/main/assembly/standalone.xml
rename to duniter4j-es-assembly/src/main/assembly/standalone.xml
index 7ad07ec1bd98813a96be85b91d7519e4190280e5..e9d6a6ee5e808c7602ef3e4b3b8a3c788fc55cbe 100644
--- a/duniter4j-elasticsearch/src/main/assembly/standalone.xml
+++ b/duniter4j-es-assembly/src/main/assembly/standalone.xml
@@ -62,51 +62,9 @@
         <include>logging.yml</include>
       </includes>
     </fileSet>
-
-    <fileSet>
-      <directory>target</directory>
-      <outputDirectory>plugins/${project.artifactId}</outputDirectory>
-      <includes>
-        <include>${project.build.finalName}.${project.packaging}</include>
-      </includes>
-    </fileSet>
-
-    <fileSet>
-      <directory>target/classes</directory>
-      <outputDirectory>plugins/${project.artifactId}</outputDirectory>
-      <includes>
-        <include>plugin-descriptor.properties</include>
-        <include>plugin-security.policy</include>
-      </includes>
-    </fileSet>
-
-    <fileSet>
-      <outputDirectory>plugins/${project.artifactId}</outputDirectory>
-      <includes>
-        <include>LICENSE</include>
-      </includes>
-    </fileSet>
   </fileSets>
 
   <dependencySets>
-    <dependencySet>
-      <outputDirectory>plugins/${project.artifactId}</outputDirectory>
-      <useProjectArtifact>true</useProjectArtifact>
-      <useTransitiveFiltering>true</useTransitiveFiltering>
-      <excludes>
-        <exclude>org.elasticsearch:elasticsearch</exclude>
-        <exclude>net.java.dev.jna:jna</exclude>
-        <exclude>com.fasterxml.jackson.core:jackson-core</exclude>
-        <exclude>log4j:log4j</exclude>
-        <exclude>com.google.guava:guava</exclude>
-        <!-- lib to include in elasticsearch/libs/ -->
-        <exclude>javax.websocket:javax.websocket-api</exclude>
-        <exclude>org.glassfish.tyrus:tyrus-client</exclude>
-        <exclude>org.glassfish.tyrus:tyrus-container-grizzly-client</exclude>
-      </excludes>
-      <fileMode>0555</fileMode>
-    </dependencySet>
-
     <dependencySet>
       <outputDirectory>lib</outputDirectory>
       <useProjectArtifact>true</useProjectArtifact>
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/AbstractRestPostIndexAction.java b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/AbstractRestPostIndexAction.java
similarity index 97%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/AbstractRestPostIndexAction.java
rename to duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/AbstractRestPostIndexAction.java
index 9b2eb4d617d9568754829863afac029469d5ac4d..5f715ec31a9529a99e1c1133148b9e2068673de0 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/AbstractRestPostIndexAction.java
+++ b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/AbstractRestPostIndexAction.java
@@ -23,9 +23,9 @@ package org.duniter.elasticsearch.action;
  */
 
 import org.duniter.core.exception.BusinessException;
-import org.duniter.elasticsearch.action.security.RestSecurityController;
-import org.duniter.elasticsearch.exception.DuniterElasticsearchException;
 import org.duniter.elasticsearch.rest.XContentThrowableRestResponse;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.exception.DuniterElasticsearchException;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.logging.ESLogger;
 import org.elasticsearch.common.logging.ESLoggerFactory;
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/AbstractRestPostUpdateAction.java b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/AbstractRestPostUpdateAction.java
similarity index 97%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/AbstractRestPostUpdateAction.java
rename to duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/AbstractRestPostUpdateAction.java
index ee02158ab7289362434c6229722c95e1e5f2ae96..c56a0a23aef039d0b2fffcaeee94a93e1143c378 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/AbstractRestPostUpdateAction.java
+++ b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/AbstractRestPostUpdateAction.java
@@ -23,9 +23,9 @@ package org.duniter.elasticsearch.action;
  */
 
 import org.duniter.core.exception.BusinessException;
-import org.duniter.elasticsearch.action.security.RestSecurityController;
-import org.duniter.elasticsearch.exception.DuniterElasticsearchException;
 import org.duniter.elasticsearch.rest.XContentThrowableRestResponse;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.exception.DuniterElasticsearchException;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.logging.ESLogger;
 import org.elasticsearch.common.logging.ESLoggerFactory;
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/RestModule.java b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/RestModule.java
similarity index 87%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/RestModule.java
rename to duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/RestModule.java
index 6c68949b37aca1b2e3e7ea5009e5043103286375..a67d6f2a078292396379f7f74c30149b763b50b8 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/RestModule.java
+++ b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/RestModule.java
@@ -22,16 +22,16 @@ package org.duniter.elasticsearch.action;
  * #L%
  */
 
-import org.duniter.elasticsearch.action.currency.RestCurrencyIndexAction;
-import org.duniter.elasticsearch.action.history.RestHistoryDeleteIndexAction;
+import org.duniter.elasticsearch.rest.currency.RestCurrencyIndexAction;
+import org.duniter.elasticsearch.rest.history.RestHistoryDeleteIndexAction;
 import org.duniter.elasticsearch.action.market.*;
 import org.duniter.elasticsearch.action.message.RestMessageInboxIndexAction;
 import org.duniter.elasticsearch.action.message.RestMessageOutboxIndexAction;
 import org.duniter.elasticsearch.action.registry.*;
-import org.duniter.elasticsearch.action.security.RestSecurityAuthAction;
-import org.duniter.elasticsearch.action.security.RestSecurityController;
-import org.duniter.elasticsearch.action.security.RestSecurityFilter;
-import org.duniter.elasticsearch.action.security.RestSecurityGetChallengeAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityAuthAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.rest.security.RestSecurityFilter;
+import org.duniter.elasticsearch.rest.security.RestSecurityGetChallengeAction;
 import org.duniter.elasticsearch.action.user.RestUserProfileIndexAction;
 import org.duniter.elasticsearch.action.user.RestUserProfileUpdateAction;
 import org.duniter.elasticsearch.action.user.RestUserSettingsIndexAction;
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/history/RestHistoryDeleteIndexAction.java b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/history/RestHistoryDeleteIndexAction.java
similarity index 88%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/history/RestHistoryDeleteIndexAction.java
rename to duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/history/RestHistoryDeleteIndexAction.java
index 79936a4ec38c891918e004007a28ecf14876514d..0778b8d60ee0938c7320562848deec35c58e9ea9 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/history/RestHistoryDeleteIndexAction.java
+++ b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/history/RestHistoryDeleteIndexAction.java
@@ -22,8 +22,8 @@ package org.duniter.elasticsearch.action.history;
  * #L%
  */
 
-import org.duniter.elasticsearch.action.AbstractRestPostIndexAction;
-import org.duniter.elasticsearch.action.security.RestSecurityController;
+import org.duniter.elasticsearch.rest.AbstractRestPostIndexAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
 import org.duniter.elasticsearch.service.HistoryService;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.inject.Inject;
@@ -34,7 +34,7 @@ import org.elasticsearch.rest.RestController;
 
 public class RestHistoryDeleteIndexAction extends AbstractRestPostIndexAction {
 
-    private static final ESLogger log = ESLoggerFactory.getLogger(RestHistoryDeleteIndexAction.class.getName());
+    private static final ESLogger log = ESLoggerFactory.getLogger(org.duniter.elasticsearch.rest.history.RestHistoryDeleteIndexAction.class.getName());
 
     @Inject
     public RestHistoryDeleteIndexAction(Settings settings, RestController controller, Client client,
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/market/RestMarketCategoryAction.java b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/market/RestMarketCategoryAction.java
similarity index 94%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/market/RestMarketCategoryAction.java
rename to duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/market/RestMarketCategoryAction.java
index 6ece11506906aceae208f37a428b02c1c59e1653..7bf4f6ae423b0a3896c0900ab1914ff6a6e12a19 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/market/RestMarketCategoryAction.java
+++ b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/market/RestMarketCategoryAction.java
@@ -22,7 +22,7 @@ package org.duniter.elasticsearch.action.market;
  * #L%
  */
 
-import org.duniter.elasticsearch.action.security.RestSecurityController;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
 import org.duniter.elasticsearch.service.MarketService;
 import org.elasticsearch.common.inject.Inject;
 import org.elasticsearch.rest.RestRequest;
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/market/RestMarketCommentIndexAction.java b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/market/RestMarketCommentIndexAction.java
similarity index 91%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/market/RestMarketCommentIndexAction.java
rename to duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/market/RestMarketCommentIndexAction.java
index 08452ec88a89538970eacb90600fd9488fc80987..37b278a0ac678b036d88d19db4eaacd5ab5112bd 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/market/RestMarketCommentIndexAction.java
+++ b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/market/RestMarketCommentIndexAction.java
@@ -22,8 +22,8 @@ package org.duniter.elasticsearch.action.market;
  * #L%
  */
 
-import org.duniter.elasticsearch.action.AbstractRestPostIndexAction;
-import org.duniter.elasticsearch.action.security.RestSecurityController;
+import org.duniter.elasticsearch.rest.AbstractRestPostIndexAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
 import org.duniter.elasticsearch.service.MarketService;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.inject.Inject;
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/market/RestMarketCommentUpdateAction.java b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/market/RestMarketCommentUpdateAction.java
similarity index 91%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/market/RestMarketCommentUpdateAction.java
rename to duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/market/RestMarketCommentUpdateAction.java
index b1840100e7eb7bf4edcf747bf0240e849f0a58a2..a11d15ab94ece445162e8af7aa31b99ea28df8e6 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/market/RestMarketCommentUpdateAction.java
+++ b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/market/RestMarketCommentUpdateAction.java
@@ -22,8 +22,8 @@ package org.duniter.elasticsearch.action.market;
  * #L%
  */
 
-import org.duniter.elasticsearch.action.AbstractRestPostUpdateAction;
-import org.duniter.elasticsearch.action.security.RestSecurityController;
+import org.duniter.elasticsearch.rest.AbstractRestPostUpdateAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
 import org.duniter.elasticsearch.service.MarketService;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.inject.Inject;
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/market/RestMarketRecordIndexAction.java b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/market/RestMarketRecordIndexAction.java
similarity index 91%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/market/RestMarketRecordIndexAction.java
rename to duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/market/RestMarketRecordIndexAction.java
index 2d2b8d56fb30e3c649e9fdd43cf6fe36d2a32f2c..1f7cfc68dd69eb97c7453cfeac80af4bceee66b2 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/market/RestMarketRecordIndexAction.java
+++ b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/market/RestMarketRecordIndexAction.java
@@ -22,8 +22,8 @@ package org.duniter.elasticsearch.action.market;
  * #L%
  */
 
-import org.duniter.elasticsearch.action.AbstractRestPostIndexAction;
-import org.duniter.elasticsearch.action.security.RestSecurityController;
+import org.duniter.elasticsearch.rest.AbstractRestPostIndexAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
 import org.duniter.elasticsearch.service.MarketService;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.inject.Inject;
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/market/RestMarketRecordUpdateAction.java b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/market/RestMarketRecordUpdateAction.java
similarity index 91%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/market/RestMarketRecordUpdateAction.java
rename to duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/market/RestMarketRecordUpdateAction.java
index 9b1b99da434718d59a2a9b7ee496f563c94cb595..7b1cd758b089c8a287e32ac233c6b3b3ae760dbf 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/market/RestMarketRecordUpdateAction.java
+++ b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/market/RestMarketRecordUpdateAction.java
@@ -22,8 +22,8 @@ package org.duniter.elasticsearch.action.market;
  * #L%
  */
 
-import org.duniter.elasticsearch.action.AbstractRestPostUpdateAction;
-import org.duniter.elasticsearch.action.security.RestSecurityController;
+import org.duniter.elasticsearch.rest.AbstractRestPostUpdateAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
 import org.duniter.elasticsearch.service.MarketService;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.inject.Inject;
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/message/RestMessageInboxIndexAction.java b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/message/RestMessageInboxIndexAction.java
similarity index 91%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/message/RestMessageInboxIndexAction.java
rename to duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/message/RestMessageInboxIndexAction.java
index d6c5bdfd75b95bebc24b2f2d10b39c214ff61f26..1ab8b7d53c57ae106d5812a918cbc5c710b9eadf 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/message/RestMessageInboxIndexAction.java
+++ b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/message/RestMessageInboxIndexAction.java
@@ -22,8 +22,8 @@ package org.duniter.elasticsearch.action.message;
  * #L%
  */
 
-import org.duniter.elasticsearch.action.AbstractRestPostIndexAction;
-import org.duniter.elasticsearch.action.security.RestSecurityController;
+import org.duniter.elasticsearch.rest.AbstractRestPostIndexAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
 import org.duniter.elasticsearch.service.MessageService;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.inject.Inject;
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/message/RestMessageOutboxIndexAction.java b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/message/RestMessageOutboxIndexAction.java
similarity index 91%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/message/RestMessageOutboxIndexAction.java
rename to duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/message/RestMessageOutboxIndexAction.java
index 70e08b0ab147e44d2aa98a12b89d8c18c35c395c..5fc0c8ba24eb47502266301c9eb9fe3056b32fea 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/message/RestMessageOutboxIndexAction.java
+++ b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/message/RestMessageOutboxIndexAction.java
@@ -22,8 +22,8 @@ package org.duniter.elasticsearch.action.message;
  * #L%
  */
 
-import org.duniter.elasticsearch.action.AbstractRestPostIndexAction;
-import org.duniter.elasticsearch.action.security.RestSecurityController;
+import org.duniter.elasticsearch.rest.AbstractRestPostIndexAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
 import org.duniter.elasticsearch.service.MessageService;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.inject.Inject;
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryCategoryAction.java b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryCategoryAction.java
similarity index 94%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryCategoryAction.java
rename to duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryCategoryAction.java
index 7bfdf238cce3091dcf99e734fb7d0f5bc8adfb9a..db635061101d389b439931bb9fba650d3f95d5a3 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryCategoryAction.java
+++ b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryCategoryAction.java
@@ -22,7 +22,7 @@ package org.duniter.elasticsearch.action.registry;
  * #L%
  */
 
-import org.duniter.elasticsearch.action.security.RestSecurityController;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
 import org.duniter.elasticsearch.service.RegistryService;
 import org.elasticsearch.common.inject.Inject;
 import org.elasticsearch.rest.RestRequest;
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryCommentIndexAction.java b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryCommentIndexAction.java
similarity index 91%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryCommentIndexAction.java
rename to duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryCommentIndexAction.java
index 1c112ce448084527ee943ea9341949b8ca1eefc7..b1fb59693d0355602abec4487eaf7298d9c8c096 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryCommentIndexAction.java
+++ b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryCommentIndexAction.java
@@ -22,8 +22,8 @@ package org.duniter.elasticsearch.action.registry;
  * #L%
  */
 
-import org.duniter.elasticsearch.action.AbstractRestPostIndexAction;
-import org.duniter.elasticsearch.action.security.RestSecurityController;
+import org.duniter.elasticsearch.rest.AbstractRestPostIndexAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
 import org.duniter.elasticsearch.service.RegistryService;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.inject.Inject;
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryRecordIndexAction.java b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryRecordIndexAction.java
similarity index 91%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryRecordIndexAction.java
rename to duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryRecordIndexAction.java
index 1d3c576891bcc6bdfae0bfb02927c252a689c5e2..98d4fce014f567781d28a86a5276d5712af7c7d7 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryRecordIndexAction.java
+++ b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryRecordIndexAction.java
@@ -22,8 +22,8 @@ package org.duniter.elasticsearch.action.registry;
  * #L%
  */
 
-import org.duniter.elasticsearch.action.AbstractRestPostIndexAction;
-import org.duniter.elasticsearch.action.security.RestSecurityController;
+import org.duniter.elasticsearch.rest.AbstractRestPostIndexAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
 import org.duniter.elasticsearch.service.RegistryService;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.inject.Inject;
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryRecordUpdateAction.java b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryRecordUpdateAction.java
similarity index 91%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryRecordUpdateAction.java
rename to duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryRecordUpdateAction.java
index dcfba5eb166a5cf06b7eba171a6a76d02385af3f..3ea0b8a01ce461d0945eec000f96d1168872ebd7 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryRecordUpdateAction.java
+++ b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/registry/RestRegistryRecordUpdateAction.java
@@ -22,8 +22,8 @@ package org.duniter.elasticsearch.action.registry;
  * #L%
  */
 
-import org.duniter.elasticsearch.action.AbstractRestPostUpdateAction;
-import org.duniter.elasticsearch.action.security.RestSecurityController;
+import org.duniter.elasticsearch.rest.AbstractRestPostUpdateAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
 import org.duniter.elasticsearch.service.RegistryService;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.inject.Inject;
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/registry/RestregistryCommentUpdateAction.java b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/registry/RestregistryCommentUpdateAction.java
similarity index 88%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/registry/RestregistryCommentUpdateAction.java
rename to duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/registry/RestregistryCommentUpdateAction.java
index 6137eacbe420cbbde9077dd9b5d746ec9cb706df..329a5ae700849ad89611b93517b8a6f9f24cfd29 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/registry/RestregistryCommentUpdateAction.java
+++ b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/registry/RestregistryCommentUpdateAction.java
@@ -22,9 +22,8 @@ package org.duniter.elasticsearch.action.registry;
  * #L%
  */
 
-import org.duniter.elasticsearch.action.AbstractRestPostUpdateAction;
-import org.duniter.elasticsearch.action.security.RestSecurityController;
-import org.duniter.elasticsearch.service.MarketService;
+import org.duniter.elasticsearch.rest.AbstractRestPostUpdateAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
 import org.duniter.elasticsearch.service.RegistryService;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.inject.Inject;
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/user/RestUserProfileIndexAction.java b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/user/RestUserProfileIndexAction.java
similarity index 91%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/user/RestUserProfileIndexAction.java
rename to duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/user/RestUserProfileIndexAction.java
index 9e738f86a865c7d0585096db543cdf1c1819adc0..535fb070daf65705a69e5f5cb3e4ed612ac1bd84 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/user/RestUserProfileIndexAction.java
+++ b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/user/RestUserProfileIndexAction.java
@@ -22,8 +22,8 @@ package org.duniter.elasticsearch.action.user;
  * #L%
  */
 
-import org.duniter.elasticsearch.action.AbstractRestPostIndexAction;
-import org.duniter.elasticsearch.action.security.RestSecurityController;
+import org.duniter.elasticsearch.rest.AbstractRestPostIndexAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
 import org.duniter.elasticsearch.service.UserService;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.inject.Inject;
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/user/RestUserProfileUpdateAction.java b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/user/RestUserProfileUpdateAction.java
similarity index 91%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/user/RestUserProfileUpdateAction.java
rename to duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/user/RestUserProfileUpdateAction.java
index e6d60417be959af40b0fe323cb749525cd6ba6f3..c287a82eea4b60477088c3069e9b8738839178af 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/user/RestUserProfileUpdateAction.java
+++ b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/user/RestUserProfileUpdateAction.java
@@ -22,8 +22,8 @@ package org.duniter.elasticsearch.action.user;
  * #L%
  */
 
-import org.duniter.elasticsearch.action.AbstractRestPostUpdateAction;
-import org.duniter.elasticsearch.action.security.RestSecurityController;
+import org.duniter.elasticsearch.rest.AbstractRestPostUpdateAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
 import org.duniter.elasticsearch.service.UserService;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.inject.Inject;
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/user/RestUserSettingsIndexAction.java b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/user/RestUserSettingsIndexAction.java
similarity index 91%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/user/RestUserSettingsIndexAction.java
rename to duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/user/RestUserSettingsIndexAction.java
index cb9f7c75b72285368386ad1904ca43aff500226a..1948f583fe07f125725e9d2ef80b7343cf10958d 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/user/RestUserSettingsIndexAction.java
+++ b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/user/RestUserSettingsIndexAction.java
@@ -22,8 +22,8 @@ package org.duniter.elasticsearch.action.user;
  * #L%
  */
 
-import org.duniter.elasticsearch.action.AbstractRestPostIndexAction;
-import org.duniter.elasticsearch.action.security.RestSecurityController;
+import org.duniter.elasticsearch.rest.AbstractRestPostIndexAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
 import org.duniter.elasticsearch.service.UserService;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.inject.Inject;
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/user/RestUserSettingsUpdateAction.java b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/user/RestUserSettingsUpdateAction.java
similarity index 91%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/user/RestUserSettingsUpdateAction.java
rename to duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/user/RestUserSettingsUpdateAction.java
index 3cf36bae5b7b636c4836e543a841fcadf6ca6a6d..b7b3bd717f67ef8cb2517f7824ceafa7a060c889 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/user/RestUserSettingsUpdateAction.java
+++ b/duniter4j-es-assembly/src/main/java/org/duniter/elasticsearch/action/user/RestUserSettingsUpdateAction.java
@@ -22,8 +22,8 @@ package org.duniter.elasticsearch.action.user;
  * #L%
  */
 
-import org.duniter.elasticsearch.action.AbstractRestPostUpdateAction;
-import org.duniter.elasticsearch.action.security.RestSecurityController;
+import org.duniter.elasticsearch.rest.AbstractRestPostUpdateAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
 import org.duniter.elasticsearch.service.UserService;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.inject.Inject;
diff --git a/duniter4j-elasticsearch/src/test/es-home/config/elasticsearch.yml b/duniter4j-es-assembly/src/test/es-home/config/elasticsearch.yml
similarity index 98%
rename from duniter4j-elasticsearch/src/test/es-home/config/elasticsearch.yml
rename to duniter4j-es-assembly/src/test/es-home/config/elasticsearch.yml
index fc10df3236a31e354731c5a630787aec4fecc1c4..828ddbd04543ef810f380ec8e0dbf229e6c2c48c 100644
--- a/duniter4j-elasticsearch/src/test/es-home/config/elasticsearch.yml
+++ b/duniter4j-es-assembly/src/test/es-home/config/elasticsearch.yml
@@ -100,7 +100,7 @@ http.cors.enabled: true
 #
 # Require explicit names when deleting indices:
 #
-# action.destructive_requires_name: true
+# rest.destructive_requires_name: true
 
 security.manager.enabled: false
 
@@ -173,3 +173,6 @@ duniter.mail.admin: blavenie@EIS-DEV
 # Mail subject prefix
 #
 #duniter.mail.subject.prefix: [Duniter4j ES]
+
+duniter.changes.listenSource: */block
+duniter.ws.port: 9400
diff --git a/duniter4j-elasticsearch/src/test/es-home/config/logging.yml b/duniter4j-es-assembly/src/test/es-home/config/logging.yml
similarity index 98%
rename from duniter4j-elasticsearch/src/test/es-home/config/logging.yml
rename to duniter4j-es-assembly/src/test/es-home/config/logging.yml
index 63c95362ee33c175973e0c3d2d82dd076b5d400e..15cfa3e195cb46a62c7536f118d1684acfcc2ecf 100644
--- a/duniter4j-elasticsearch/src/test/es-home/config/logging.yml
+++ b/duniter4j-es-assembly/src/test/es-home/config/logging.yml
@@ -2,7 +2,7 @@
 es.logger.level: INFO
 rootLogger: ${es.logger.level}, console, file
 logger:
-  # log action execution errors for easier debugging
+  # log rest execution errors for easier debugging
   action: DEBUG
 
   # deprecation logging, turn to DEBUG to see them
diff --git a/duniter4j-elasticsearch/LICENSE b/duniter4j-es-core/LICENSE
similarity index 100%
rename from duniter4j-elasticsearch/LICENSE
rename to duniter4j-es-core/LICENSE
diff --git a/duniter4j-es-core/pom.xml b/duniter4j-es-core/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..06cf545266c6bd9584ddb7c98df458c383ab5154
--- /dev/null
+++ b/duniter4j-es-core/pom.xml
@@ -0,0 +1,175 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.duniter</groupId>
+    <artifactId>duniter4j</artifactId>
+    <version>0.3.5-SNAPSHOT</version>
+  </parent>
+
+  <groupId>org.duniter</groupId>
+  <artifactId>duniter4j-es-core</artifactId>
+  <packaging>jar</packaging>
+  <name>Duniter4j :: ElasticSearch Core plugin</name>
+
+  <properties>
+    <!-- i18n configuration -->
+    <i18n.bundleOutputName>duniter4j-es-core-i18n</i18n.bundleOutputName>
+    <i18n.generateCsvFile>true</i18n.generateCsvFile>
+    <i18n.bundleCsvFile>
+      ${maven.gen.dir}/resources/META-INF/${i18n.bundleOutputName}.csv
+    </i18n.bundleCsvFile>
+    <config.i18nBundleName>${i18n.bundleOutputName}</config.i18nBundleName>
+
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.duniter</groupId>
+      <artifactId>duniter4j-core-client</artifactId>
+      <version>${project.version}</version>
+      <exclusions>
+        <exclusion>
+          <groupId>com.google.guava</groupId>
+          <artifactId>guava</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <!-- LOGGING DEPENDENCIES - SLF4J -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+      <optional>true</optional>
+      <scope>runtime</scope>
+    </dependency>
+
+    <!-- Elastic Search -->
+    <dependency>
+      <groupId>org.elasticsearch</groupId>
+      <artifactId>elasticsearch</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-databind</artifactId>
+    </dependency>
+
+    <!-- JNA (need for OS shutdown hook) -->
+    <dependency>
+      <groupId>net.java.dev.jna</groupId>
+      <artifactId>jna</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>net.java.dev.jna</groupId>
+      <artifactId>jna-platform</artifactId>
+      <exclusions>
+        <exclusion>
+          <groupId>net.java.dev.jna</groupId>
+          <artifactId>jna</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.glassfish.tyrus</groupId>
+      <artifactId>tyrus-server</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.glassfish.tyrus</groupId>
+      <artifactId>tyrus-container-grizzly-server</artifactId>
+    </dependency>
+
+    <!-- Unit test -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <resources>
+      <resource>
+        <directory>src/main/filtered-resources</directory>
+        <filtering>true</filtering>
+        <includes>
+          <include>*.config</include>
+          <include>**/*.properties</include>
+        </includes>
+      </resource>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>false</filtering>
+      </resource>
+    </resources>
+
+    <plugins>
+      <plugin>
+        <groupId>org.nuiton.i18n</groupId>
+        <artifactId>i18n-maven-plugin</artifactId>
+
+        <executions>
+          <execution>
+            <id>scan-sources</id>
+            <configuration>
+              <entries>
+                <entry>
+                  <specificGoal>parserValidation</specificGoal>
+                  <basedir>${maven.src.dir}/main/java/</basedir>
+                  <includes>
+                    <param>**/**-validation.xml</param>
+                  </includes>
+                </entry>
+              </entries>
+            </configuration>
+            <goals>
+              <goal>parserJava</goal>
+              <goal>parserValidation</goal>
+              <goal>gen</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>make-bundle</id>
+            <goals>
+              <goal>bundle</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>assembly-plugin</id>
+            <phase>package</phase>
+            <goals>
+              <goal>single</goal>
+            </goals>
+            <configuration>
+              <attach>true</attach>
+              <appendAssemblyId>false</appendAssemblyId>
+              <finalName>${project.artifactId}-${project.version}</finalName>
+              <descriptors>
+                <descriptor>
+                  ${basedir}/src/main/assembly/plugin.xml
+                </descriptor>
+              </descriptors>
+              <skipAssembly>${assembly.skip}</skipAssembly>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
diff --git a/duniter4j-elasticsearch/src/license/THIRD-PARTY.properties b/duniter4j-es-core/src/license/THIRD-PARTY.properties
similarity index 100%
rename from duniter4j-elasticsearch/src/license/THIRD-PARTY.properties
rename to duniter4j-es-core/src/license/THIRD-PARTY.properties
diff --git a/duniter4j-elasticsearch/src/main/assembly/plugin.xml b/duniter4j-es-core/src/main/assembly/plugin.xml
similarity index 100%
rename from duniter4j-elasticsearch/src/main/assembly/plugin.xml
rename to duniter4j-es-core/src/main/assembly/plugin.xml
diff --git a/duniter4j-elasticsearch/src/main/filtered-resources/duniter4j.config b/duniter4j-es-core/src/main/filtered-resources/duniter4j.config
similarity index 100%
rename from duniter4j-elasticsearch/src/main/filtered-resources/duniter4j.config
rename to duniter4j-es-core/src/main/filtered-resources/duniter4j.config
diff --git a/duniter4j-elasticsearch/src/main/filtered-resources/log4j.properties b/duniter4j-es-core/src/main/filtered-resources/log4j.properties
similarity index 100%
rename from duniter4j-elasticsearch/src/main/filtered-resources/log4j.properties
rename to duniter4j-es-core/src/main/filtered-resources/log4j.properties
diff --git a/duniter4j-elasticsearch/src/main/filtered-resources/plugin-descriptor.properties b/duniter4j-es-core/src/main/filtered-resources/plugin-descriptor.properties
similarity index 66%
rename from duniter4j-elasticsearch/src/main/filtered-resources/plugin-descriptor.properties
rename to duniter4j-es-core/src/main/filtered-resources/plugin-descriptor.properties
index 1ab4c6e915c42745c50d8b5ebb85818f1405a600..27e01fac493896713e0c2083c527bbb975cfba80 100644
--- a/duniter4j-elasticsearch/src/main/filtered-resources/plugin-descriptor.properties
+++ b/duniter4j-es-core/src/main/filtered-resources/plugin-descriptor.properties
@@ -1,5 +1,5 @@
-name=duniter4j-elasticsearch
-description=Plugin for Duniter node indexation
+name=duniter4j-es-core
+description=Plugin for Duniter
 version=${project.version}
 site=false
 jvm=true
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/Plugin.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/Plugin.java
similarity index 91%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/Plugin.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/Plugin.java
index bb8715b414e778a14fb09800fae0276e65115a18..a64334b6cd4159657b5110c034b7aabae3f3e75b 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/Plugin.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/Plugin.java
@@ -23,11 +23,11 @@ package org.duniter.elasticsearch;
  */
 
 import com.google.common.collect.Lists;
-import org.duniter.elasticsearch.action.RestModule;
-import org.duniter.elasticsearch.node.DuniterNode;
+import org.duniter.elasticsearch.rest.RestModule;
 import org.duniter.elasticsearch.security.SecurityModule;
 import org.duniter.elasticsearch.service.ServiceModule;
 import org.duniter.elasticsearch.threadpool.ThreadPool;
+import org.duniter.elasticsearch.websocket.WebsocketModule;
 import org.elasticsearch.common.component.LifecycleComponent;
 import org.elasticsearch.common.inject.Inject;
 import org.elasticsearch.common.inject.Module;
@@ -65,10 +65,11 @@ public class Plugin extends org.elasticsearch.plugins.Plugin {
             return modules;
         }
         modules.add(new SecurityModule());
+
+        modules.add(new WebsocketModule());
         modules.add(new RestModule());
+
         modules.add(new ServiceModule());
-        // TODO : must be tested inside full release assembly
-        //modules.add(new ChangesModule());
 
         return modules;
     }
@@ -81,7 +82,7 @@ public class Plugin extends org.elasticsearch.plugins.Plugin {
         }
         components.add(PluginSettings.class);
         components.add(ThreadPool.class);
-        components.add(DuniterNode.class);
+        components.add(PluginInit.class);
         return components;
     }
 
diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/PluginInit.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/PluginInit.java
new file mode 100644
index 0000000000000000000000000000000000000000..110b3a0dabb3934ddd9ee0047baa832d09edd913
--- /dev/null
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/PluginInit.java
@@ -0,0 +1,132 @@
+package org.duniter.elasticsearch;
+
+/*
+ * #%L
+ * Duniter4j :: ElasticSearch Plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.core.client.model.elasticsearch.Currency;
+import org.duniter.core.client.model.local.Peer;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.service.BlockchainService;
+import org.duniter.elasticsearch.service.CurrencyService;
+import org.duniter.elasticsearch.threadpool.ThreadPool;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.cluster.health.ClusterHealthStatus;
+import org.elasticsearch.common.component.AbstractLifecycleComponent;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.inject.Injector;
+import org.elasticsearch.common.logging.ESLogger;
+import org.elasticsearch.common.logging.Loggers;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.rest.RestRequest;
+
+/**
+ * Created by blavenie on 17/06/16.
+ */
+public class PluginInit extends AbstractLifecycleComponent<PluginInit> {
+
+    private final PluginSettings pluginSettings;
+    private final ThreadPool threadPool;
+    private final Injector injector;
+    private final static ESLogger logger = Loggers.getLogger("duniter.core");
+    private final Client client;
+
+    @Inject
+    public PluginInit(Client client, Settings settings, PluginSettings pluginSettings, ThreadPool threadPool, final Injector injector) {
+        super(settings);
+        this.pluginSettings = pluginSettings;
+        this.threadPool = threadPool;
+        this.injector = injector;
+        this.client = client;
+    }
+
+    @Override
+    protected void doStart() {
+        threadPool.scheduleOnClusterHealthStatus(() -> {
+            createIndices();
+
+            // Waiting cluster back to GREEN or YELLOW state, before synchronize
+            threadPool.scheduleOnClusterHealthStatus(() -> {
+                synchronize();
+            }, ClusterHealthStatus.YELLOW, ClusterHealthStatus.GREEN);
+        }, ClusterHealthStatus.YELLOW, ClusterHealthStatus.GREEN);
+    }
+
+    @Override
+    protected void doStop() {
+
+    }
+
+    @Override
+    protected void doClose() {
+
+    }
+
+    protected void createIndices() {
+
+        boolean reloadIndices = pluginSettings.reloadIndices();
+
+        if (reloadIndices) {
+            if (logger.isInfoEnabled()) {
+                logger.info("Reloading all Duniter core indices...");
+            }
+
+            injector.getInstance(CurrencyService.class)
+                    .deleteIndex()
+                    .createIndexIfNotExists();
+
+            if (logger.isInfoEnabled()) {
+                logger.info("Reloading all Duniter indices... [OK]");
+            }
+        }
+        else {
+            if (logger.isInfoEnabled()) {
+                logger.info("Checking Duniter core indices...");
+            }
+
+            injector.getInstance(CurrencyService.class).createIndexIfNotExists();
+
+            if (logger.isInfoEnabled()) {
+                logger.info("Checking Duniter core indices... [OK]");
+            }
+        }
+    }
+
+    protected void synchronize() {
+        if (pluginSettings.enableBlockchainSync()) {
+
+            Peer peer = pluginSettings.checkAndGetPeer();
+
+            // Index (or refresh) node's currency
+            Currency currency = injector.getInstance(CurrencyService.class).indexCurrencyFromPeer(peer, true);
+
+            // Add access to currency index
+            injector.getInstance(RestSecurityController.class).allowIndexType(RestRequest.Method.GET,
+                    currency.getCurrencyName(),
+                    BlockchainService.BLOCK_TYPE);
+
+            // Index blocks (and listen if new block appear)
+            injector.getInstance(BlockchainService.class)
+                    .indexLastBlocks(peer)
+                    .listenAndIndexNewBlock(peer);
+        }
+    }
+}
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/PluginSettings.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/PluginSettings.java
similarity index 97%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/PluginSettings.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/PluginSettings.java
index 265473a9daec1ccd72ca42c4a87bbb489b9b880a..5fe14728a5452d817f73001d2c62160c37e4891a 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/PluginSettings.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/PluginSettings.java
@@ -60,7 +60,7 @@ import static org.nuiton.i18n.I18n.t;
  */
 public class PluginSettings extends AbstractLifecycleComponent<PluginSettings> {
 
-    private Settings settings;
+    protected final Settings settings;
 
     /**
      * Delegate application config.
@@ -269,6 +269,14 @@ public class PluginSettings extends AbstractLifecycleComponent<PluginSettings> {
         return settings.get("duniter.mail.subject.prefix", "[Duniter4j ES]");
     }
 
+    public int getWebSocketPort()  {
+        return settings.getAsInt("duniter.ws.port", 9200);
+    }
+
+    public String getWebSocketHost()  {
+        return settings.get("network.host", "locahost");
+    }
+
     /* protected methods */
 
     protected void initI18n() throws IOException {
@@ -301,6 +309,6 @@ public class PluginSettings extends AbstractLifecycleComponent<PluginSettings> {
     }
 
     protected String getI18nBundleName() {
-        return "duniter4j-elasticsearch-i18n";
+        return "duniter4j-es-core-i18n";
     }
 }
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/exception/AccessDeniedException.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/exception/AccessDeniedException.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/exception/AccessDeniedException.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/exception/AccessDeniedException.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/exception/DuniterElasticsearchException.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/exception/DuniterElasticsearchException.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/exception/DuniterElasticsearchException.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/exception/DuniterElasticsearchException.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/exception/DuplicateIndexIdException.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/exception/DuplicateIndexIdException.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/exception/DuplicateIndexIdException.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/exception/DuplicateIndexIdException.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/exception/InvalidFormatException.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/exception/InvalidFormatException.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/exception/InvalidFormatException.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/exception/InvalidFormatException.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/exception/InvalidSignatureException.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/exception/InvalidSignatureException.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/exception/InvalidSignatureException.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/exception/InvalidSignatureException.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/exception/NodeConfigException.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/exception/NodeConfigException.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/exception/NodeConfigException.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/exception/NodeConfigException.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/exception/NotFoundException.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/exception/NotFoundException.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/exception/NotFoundException.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/exception/NotFoundException.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/model/Currency.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/model/Currency.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/model/Currency.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/model/Currency.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/model/SearchResult.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/model/SearchResult.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/model/SearchResult.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/model/SearchResult.java
diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/AbstractRestPostIndexAction.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/AbstractRestPostIndexAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..c2a0f7fd4480d26f3d7f07a48bbfb0ef1bf9b558
--- /dev/null
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/AbstractRestPostIndexAction.java
@@ -0,0 +1,83 @@
+package org.duniter.elasticsearch.rest;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.core.exception.BusinessException;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.exception.DuniterElasticsearchException;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.logging.ESLogger;
+import org.elasticsearch.common.logging.ESLoggerFactory;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.rest.*;
+
+import static org.elasticsearch.rest.RestRequest.Method.GET;
+import static org.elasticsearch.rest.RestRequest.Method.POST;
+import static org.elasticsearch.rest.RestStatus.OK;
+
+public abstract class AbstractRestPostIndexAction extends BaseRestHandler {
+
+    private static ESLogger log = null;
+
+    private final JsonIndexer indexer;
+
+
+    public AbstractRestPostIndexAction(Settings settings, RestController controller, Client client,
+                                       RestSecurityController securityController,
+                                       String indexName,
+                                       String typeName,
+                                       JsonIndexer indexer) {
+        super(settings, controller, client);
+        controller.registerHandler(POST,
+                String.format("/%s/%s", indexName, typeName),
+                this);
+        securityController.allowIndexType(POST, indexName, typeName);
+        securityController.allowIndexType(GET, indexName, typeName);
+        log = ESLoggerFactory.getLogger(String.format("[%s]", indexName));
+        this.indexer = indexer;
+    }
+
+    @Override
+    protected void handleRequest(final RestRequest request, RestChannel restChannel, Client client) throws Exception {
+
+        try {
+            String id = indexer.handleJson(request.content().toUtf8());
+            restChannel.sendResponse(new BytesRestResponse(OK, id));
+        }
+        catch(DuniterElasticsearchException | BusinessException e) {
+            log.error(e.getMessage(), e);
+            restChannel.sendResponse(new XContentThrowableRestResponse(request, e));
+        }
+        catch(Exception e) {
+            log.error(e.getMessage(), e);
+        }
+    }
+
+
+    public interface JsonIndexer {
+        String handleJson(String json) throws DuniterElasticsearchException, BusinessException;
+    }
+
+
+
+}
\ No newline at end of file
diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/AbstractRestPostUpdateAction.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/AbstractRestPostUpdateAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..ede1eb5e089554e7b753d757cde0930305c8b76d
--- /dev/null
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/AbstractRestPostUpdateAction.java
@@ -0,0 +1,82 @@
+package org.duniter.elasticsearch.rest;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.core.exception.BusinessException;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.exception.DuniterElasticsearchException;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.logging.ESLogger;
+import org.elasticsearch.common.logging.ESLoggerFactory;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.rest.*;
+
+import static org.elasticsearch.rest.RestRequest.Method.POST;
+import static org.elasticsearch.rest.RestStatus.OK;
+
+public abstract class AbstractRestPostUpdateAction extends BaseRestHandler {
+
+    private static ESLogger log = null;
+
+    private final JsonUpdater updater;
+
+
+    public AbstractRestPostUpdateAction(Settings settings, RestController controller, Client client,
+                                        RestSecurityController securityController,
+                                        String indexName,
+                                        String typeName,
+                                        JsonUpdater updater) {
+        super(settings, controller, client);
+        controller.registerHandler(POST,
+                String.format("/%s/%s/{id}/_update", indexName, typeName),
+                this);
+        securityController.allowIndexType(POST, indexName, typeName);
+        log = ESLoggerFactory.getLogger(String.format("[%s]", indexName));
+        this.updater = updater;
+    }
+
+    @Override
+    protected void handleRequest(final RestRequest request, RestChannel restChannel, Client client) throws Exception {
+        String id = request.param("id");
+
+        try {
+            updater.handleJson(request.content().toUtf8(), id);
+            restChannel.sendResponse(new BytesRestResponse(OK, id));
+        }
+        catch(DuniterElasticsearchException | BusinessException e) {
+            log.error(e.getMessage(), e);
+            restChannel.sendResponse(new XContentThrowableRestResponse(request, e));
+        }
+        catch(Exception e) {
+            log.error(e.getMessage(), e);
+        }
+    }
+
+
+    public interface JsonUpdater {
+        void handleJson(String json, String id) throws DuniterElasticsearchException, BusinessException;
+    }
+
+
+
+}
\ No newline at end of file
diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/RestModule.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/RestModule.java
new file mode 100644
index 0000000000000000000000000000000000000000..68e8542ce6d8b2d58014bfab2f076b7b2e3ed7bc
--- /dev/null
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/RestModule.java
@@ -0,0 +1,47 @@
+package org.duniter.elasticsearch.rest;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.rest.currency.RestCurrencyIndexAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityAuthAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.rest.security.RestSecurityFilter;
+import org.duniter.elasticsearch.rest.security.RestSecurityGetChallengeAction;
+import org.elasticsearch.common.inject.AbstractModule;
+import org.elasticsearch.common.inject.Module;
+
+public class RestModule extends AbstractModule implements Module {
+
+    @Override protected void configure() {
+
+        // Currency
+        bind(RestCurrencyIndexAction.class).asEagerSingleton();
+
+        // Authentication & Security
+        bind(RestSecurityGetChallengeAction.class).asEagerSingleton();
+        bind(RestSecurityAuthAction.class).asEagerSingleton();
+        bind(RestSecurityFilter.class).asEagerSingleton();
+        bind(RestSecurityController.class).asEagerSingleton();
+
+    }
+}
\ No newline at end of file
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/rest/RestXContentBuilder.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/RestXContentBuilder.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/rest/RestXContentBuilder.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/RestXContentBuilder.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/rest/XContentRestResponse.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/XContentRestResponse.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/rest/XContentRestResponse.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/XContentRestResponse.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/rest/XContentThrowableRestResponse.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/XContentThrowableRestResponse.java
similarity index 95%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/rest/XContentThrowableRestResponse.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/XContentThrowableRestResponse.java
index e78ac86d987ee2ffe6a986d9645f5fdfbfc02bb3..4f498f4040c007324b37408de064afad0a8c8ea7 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/rest/XContentThrowableRestResponse.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/XContentThrowableRestResponse.java
@@ -31,7 +31,6 @@ import org.elasticsearch.rest.RestStatus;
 import java.io.IOException;
 
 import static org.elasticsearch.ExceptionsHelper.detailedMessage;
-import static org.duniter.elasticsearch.rest.RestXContentBuilder.restContentBuilder;
 
 public class XContentThrowableRestResponse extends XContentRestResponse {
 
@@ -44,7 +43,7 @@ public class XContentThrowableRestResponse extends XContentRestResponse {
     }
 
     private static XContentBuilder convert(RestRequest request, RestStatus status, Throwable t) throws IOException {
-        XContentBuilder builder = restContentBuilder(request).startObject()
+        XContentBuilder builder = RestXContentBuilder.restContentBuilder(request).startObject()
                 .field("error", detailedMessage(t))
                 .field("status", status.getStatus());
         if (t != null && request.paramAsBoolean("error_trace", false)) {
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/currency/RestCurrencyIndexAction.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/currency/RestCurrencyIndexAction.java
similarity index 94%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/currency/RestCurrencyIndexAction.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/currency/RestCurrencyIndexAction.java
index dea0ce5a284a49585b387695ac1710d66c946395..100df9ec37dc2acd44cdaf980ab314231dec8b52 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/currency/RestCurrencyIndexAction.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/currency/RestCurrencyIndexAction.java
@@ -1,4 +1,4 @@
-package org.duniter.elasticsearch.action.currency;
+package org.duniter.elasticsearch.rest.currency;
 
 /*
  * #%L
@@ -30,7 +30,7 @@ import org.elasticsearch.rest.*;
 import static org.elasticsearch.rest.RestStatus.OK;
 
 /**
- * A action to post a request to process a new currency/peer.
+ * A rest to post a request to process a new currency/peer.
  *
  * TODO :
  *  - add security, to allow only request from admin (check signature against settings keyring)
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/security/RestSecurityAuthAction.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityAuthAction.java
similarity index 98%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/security/RestSecurityAuthAction.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityAuthAction.java
index 945e8dce38775f58a37b8100e9f5d891ad7cdd52..b62408e8ac76c878fc2fff7205f9498834cac25f 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/security/RestSecurityAuthAction.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityAuthAction.java
@@ -1,4 +1,4 @@
-package org.duniter.elasticsearch.action.security;
+package org.duniter.elasticsearch.rest.security;
 
 /*
  * #%L
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/security/RestSecurityController.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityController.java
similarity index 98%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/security/RestSecurityController.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityController.java
index 4c5dc3c4f9f9c816b9e983d0956164df66437660..b52fb2a56e1e498c5e950742dbbfa1306dd9e8b7 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/security/RestSecurityController.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityController.java
@@ -1,4 +1,4 @@
-package org.duniter.elasticsearch.action.security;
+package org.duniter.elasticsearch.rest.security;
 
 /*
  * #%L
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/security/RestSecurityFilter.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityFilter.java
similarity index 97%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/security/RestSecurityFilter.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityFilter.java
index 189a999b477498efecd28760eecf15a419915c1f..9b6557d0486e8344a118dcd4abb755c0ac7a917f 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/security/RestSecurityFilter.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityFilter.java
@@ -1,4 +1,4 @@
-package org.duniter.elasticsearch.action.security;
+package org.duniter.elasticsearch.rest.security;
 
 /*
  * #%L
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/security/RestSecurityGetChallengeAction.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityGetChallengeAction.java
similarity index 97%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/security/RestSecurityGetChallengeAction.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityGetChallengeAction.java
index 416b75ffac1d0601ee2a71a6341efa98e42467cc..9b27b92a95e39ba4b9bf4baacf33be58bae52bb4 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/action/security/RestSecurityGetChallengeAction.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityGetChallengeAction.java
@@ -1,4 +1,4 @@
-package org.duniter.elasticsearch.action.security;
+package org.duniter.elasticsearch.rest.security;
 
 /*
  * #%L
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/security/SecurityModule.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/security/SecurityModule.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/security/SecurityModule.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/security/SecurityModule.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/security/challenge/ChallengeMessageStore.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/security/challenge/ChallengeMessageStore.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/security/challenge/ChallengeMessageStore.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/security/challenge/ChallengeMessageStore.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/security/token/SecurityTokenStore.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/security/token/SecurityTokenStore.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/security/token/SecurityTokenStore.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/security/token/SecurityTokenStore.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/AbstractService.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/AbstractService.java
similarity index 99%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/AbstractService.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/AbstractService.java
index f7cc988290f8642466b068a0b6c38b3971257b1b..89bc70ad9b1fedecded6ba0787b47a853f428a4a 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/AbstractService.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/AbstractService.java
@@ -30,7 +30,6 @@ import com.google.common.collect.ImmutableSet;
 import com.google.gson.JsonSyntaxException;
 import org.duniter.core.beans.Bean;
 import org.duniter.core.client.model.elasticsearch.Record;
-import org.duniter.core.client.service.exception.HttpBadRequestException;
 import org.duniter.core.exception.TechnicalException;
 import org.duniter.core.service.CryptoService;
 import org.duniter.core.util.StringUtils;
@@ -77,16 +76,6 @@ public abstract class AbstractService implements Bean {
     protected final int retryCount;
     protected final int retryWaitDuration;
 
-    public AbstractService(String loggerName, Client client, PluginSettings pluginSettings, CryptoService cryptoService) {
-        this.logger = Loggers.getLogger(loggerName);
-        this.client = client;
-        this.pluginSettings = pluginSettings;
-        this.cryptoService = cryptoService;
-        this.objectMapper = new ObjectMapper();
-        this.retryCount = pluginSettings.getNodeRetryCount();
-        this.retryWaitDuration = pluginSettings.getNodeRetryWaitDuration();
-    }
-
     public AbstractService(String loggerName, Client client, PluginSettings pluginSettings) {
         this(loggerName, client, pluginSettings, null);
     }
@@ -99,6 +88,16 @@ public abstract class AbstractService implements Bean {
         this("duniter", client, pluginSettings, cryptoService);
     }
 
+    public AbstractService(String loggerName, Client client, PluginSettings pluginSettings, CryptoService cryptoService) {
+        this.logger = Loggers.getLogger(loggerName);
+        this.client = client;
+        this.pluginSettings = pluginSettings;
+        this.cryptoService = cryptoService;
+        this.objectMapper = new ObjectMapper();
+        this.retryCount = pluginSettings.getNodeRetryCount();
+        this.retryWaitDuration = pluginSettings.getNodeRetryWaitDuration();
+    }
+
     /* -- protected methods  -- */
 
     protected boolean existsIndex(String indexes) {
@@ -124,6 +123,7 @@ public abstract class AbstractService implements Bean {
         JsonNode actualObj = readAndVerifyIssuerSignature(json);
         String issuer = getIssuer(actualObj);
 
+
         if (logger.isDebugEnabled()) {
             logger.debug(String.format("Indexing a %s from issuer [%s]", type, issuer.substring(0, 8)));
         }
@@ -132,7 +132,8 @@ public abstract class AbstractService implements Bean {
                 .setSource(json)
                 .setRefresh(false)
                 .execute().actionGet();
-        return response.getId();
+        String id = response.getId();
+        return id;
     }
 
     protected void checkIssuerAndUpdateDocumentFromJson(String index, String type, String json, String id) {
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/synchro/SynchroService.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/AbstractSynchroService.java
similarity index 78%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/synchro/SynchroService.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/AbstractSynchroService.java
index b95cb1ac609280725e8fd195f68e81ac0ef5a72b..57c9561f6f0469f972f9958b6fbab971d988b7ad 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/synchro/SynchroService.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/AbstractSynchroService.java
@@ -1,4 +1,4 @@
-package org.duniter.elasticsearch.service.synchro;
+package org.duniter.elasticsearch.service;
 
 /*
  * #%L
@@ -35,7 +35,8 @@ import org.duniter.core.service.CryptoService;
 import org.duniter.core.util.StringUtils;
 import org.duniter.elasticsearch.PluginSettings;
 import org.duniter.elasticsearch.exception.InvalidFormatException;
-import org.duniter.elasticsearch.service.*;
+import org.duniter.elasticsearch.service.AbstractService;
+import org.duniter.elasticsearch.service.ServiceLocator;
 import org.duniter.elasticsearch.threadpool.ThreadPool;
 import org.elasticsearch.action.bulk.BulkItemResponse;
 import org.elasticsearch.action.bulk.BulkRequestBuilder;
@@ -57,66 +58,32 @@ import java.util.Set;
 /**
  * Created by blavenie on 27/10/16.
  */
-public class SynchroService extends AbstractService {
+public abstract class AbstractSynchroService extends AbstractService {
 
     protected HttpService httpService;
 
     @Inject
-    public SynchroService(Client client, PluginSettings settings, CryptoService cryptoService,
-                          ThreadPool threadPool, final ServiceLocator serviceLocator) {
+    public AbstractSynchroService(Client client, PluginSettings settings, CryptoService cryptoService,
+                                  ThreadPool threadPool, final ServiceLocator serviceLocator) {
         super("duniter.network.p2p", client, settings,cryptoService);
         threadPool.scheduleOnStarted(() -> {
             httpService = serviceLocator.getHttpService();
         });
     }
 
-    public void synchronize() {
-        logger.info("Synchronizing data...");
+    /* -- protected methods -- */
 
+    protected Peer getPeerFromAPI(String filterApiName) {
         // TODO : get peers from currency - use peering BMA API, and select peers with ESA (ES API)
         Peer peer = new Peer(pluginSettings.getDataSyncHost(), pluginSettings.getDataSyncPort());
-
-        synchronize(peer);
-    }
-
-    public void synchronize(Peer peer) {
-
-        long sinceTime = 0; // ToDO: get last sync time from somewhere ? (e.g. a specific index)
-
-        logger.info(String.format("[%s] Synchronizing data since %s...", peer.toString(), sinceTime));
-
-        importMarketChanges(peer, sinceTime);
-        importRegistryChanges(peer, sinceTime);
-        importUserChanges(peer, sinceTime);
-        importMessageChanges(peer, sinceTime);
-
-        logger.info(String.format("[%s] Synchronizing data since %s [OK]", peer.toString(), sinceTime));
-    }
-
-    public void importMarketChanges(Peer peer, long sinceTime) {
-        importChanges(peer, MarketService.INDEX, MarketService.RECORD_TYPE,  sinceTime);
-        importChanges(peer, MarketService.INDEX, MarketService.RECORD_COMMENT_TYPE,  sinceTime);
-    }
-
-    public void importRegistryChanges(Peer peer, long sinceTime) {
-        importChanges(peer, RegistryService.INDEX, RegistryService.RECORD_TYPE,  sinceTime);
-        importChanges(peer, RegistryService.INDEX, RegistryService.RECORD_COMMENT_TYPE,  sinceTime);
-    }
-
-    public void importUserChanges(Peer peer, long sinceTime) {
-        importChanges(peer, UserService.INDEX, UserService.PROFILE_TYPE,  sinceTime);
-        importChanges(peer, UserService.INDEX, UserService.SETTINGS_TYPE,  sinceTime);
-    }
-
-    public void importMessageChanges(Peer peer, long sinceTime) {
-        importChanges(peer, MessageService.INDEX, MessageService.RECORD_TYPE,  sinceTime);
+        return peer;
     }
 
-    public void importChanges(Peer peer, String index, String type, long sinceTime) {
+    protected void importChanges(Peer peer, String index, String type, long sinceTime) {
         importChanges(peer, index, type, Record.PROPERTY_ISSUER, Record.PROPERTY_TIME, sinceTime);
     }
 
-    public void importChanges(Peer peer, String index, String type, String issuerFieldName, String versionFieldName, long sinceTime) {
+    protected void importChanges(Peer peer, String index, String type, String issuerFieldName, String versionFieldName, long sinceTime) {
 
         // Create the search query
         BytesStreamOutput bos;
@@ -125,28 +92,28 @@ public class SynchroService extends AbstractService {
             XContentBuilder builder = new XContentBuilder(JsonXContent.jsonXContent, bos);
             builder.startObject()
                     .startObject("query")
-                        // bool.should
-                        .startObject("bool")
-                            .startObject("should")
-                                // time > sinceDate
-                                .startObject("range")
-                                .startObject("time")
-                                .field("gte", sinceTime)
-                                .endObject()
-                                .endObject()
-                            .endObject()
-                            // currency
+                    // bool.should
+                    .startObject("bool")
+                    .startObject("should")
+                    // time > sinceDate
+                    .startObject("range")
+                    .startObject("time")
+                    .field("gte", sinceTime)
+                    .endObject()
+                    .endObject()
+                    .endObject()
+                    // currency
                             /*.startObject("filter")
                                 .startObject("term")
                                     .field("currency", "sou") // todo, filter on configured currency only
                                 .endObject()
                             .endObject()*/
-                        .endObject()
+                    .endObject()
                     // end: query
                     .endObject()
                     .field("from", 0) // todo
                     .field("size", 100) // todo
-                 .endObject();
+                    .endObject();
             builder.flush();
 
         } catch(IOException e) {
@@ -237,7 +204,7 @@ public class SynchroService extends AbstractService {
                                     logger.trace(String.format("[%s] [%s/%s] update _id=%s\n%s", peer, hitIndex, hitType, id, json));
                                 }
                                 bulkRequest.add(client.prepareIndex(hitIndex, hitType, id)
-                                            .setSource(json.getBytes()));
+                                        .setSource(json.getBytes()));
                             }
                         }
 
@@ -283,8 +250,4 @@ public class SynchroService extends AbstractService {
             IOUtils.closeQuietly(response);
         }
     }
-
-    /* -- protected methods -- */
-
-
 }
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/BlockchainService.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/BlockchainService.java
similarity index 99%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/BlockchainService.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/BlockchainService.java
index 0786e89ee1b92c00f4d74abecc3d72a7c15e633c..77fee625b794822dca61a20966abad991721f725 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/BlockchainService.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/BlockchainService.java
@@ -36,7 +36,6 @@ import org.duniter.core.client.model.local.Peer;
 import org.duniter.core.client.service.bma.BlockchainRemoteService;
 import org.duniter.core.client.service.bma.NetworkRemoteService;
 import org.duniter.core.client.service.exception.BlockNotFoundException;
-import org.duniter.core.client.service.exception.HttpBadRequestException;
 import org.duniter.core.client.service.exception.JsonSyntaxException;
 import org.duniter.core.exception.TechnicalException;
 import org.duniter.core.model.NullProgressionModel;
@@ -65,7 +64,6 @@ import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentFactory;
 import org.elasticsearch.index.query.QueryBuilders;
-import org.elasticsearch.search.SearchHit;
 import org.elasticsearch.search.SearchHitField;
 import org.elasticsearch.search.aggregations.AggregationBuilders;
 import org.elasticsearch.search.aggregations.metrics.max.Max;
@@ -89,7 +87,7 @@ public class BlockchainService extends AbstractService {
     private final ProgressionModel nullProgressionModel = new NullProgressionModel();
 
     private BlockchainRemoteService blockchainRemoteService;
-    private RegistryService registryService;
+    private CurrencyService currencyService;
     private ThreadPool threadPool;
 
     private JsonAttributeParser blockNumberParser = new JsonAttributeParser("number");
@@ -111,8 +109,8 @@ public class BlockchainService extends AbstractService {
     }
 
     @Inject
-    public void setRegistryService(RegistryService registryService) {
-        this.registryService = registryService;
+    public void setCurrencyService(CurrencyService currencyService) {
+        this.currencyService = currencyService;
     }
 
     public BlockchainService listenAndIndexNewBlock(Peer peer){
@@ -148,8 +146,8 @@ public class BlockchainService extends AbstractService {
             logger.info(I18n.t("duniter4j.blockIndexerService.indexLastBlocks.task", currencyName, peer));
 
             // Create index blockchain if need
-            if (!registryService.isCurrencyExists(currencyName)) {
-                registryService.indexCurrencyFromPeer(peer);
+            if (!currencyService.isCurrencyExists(currencyName)) {
+                currencyService.indexCurrencyFromPeer(peer);
             }
 
             // Check if index exists
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/RegistryService.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/CurrencyService.java
similarity index 58%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/RegistryService.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/CurrencyService.java
index 8d8da25177cc2d0a1c2da66810fb41d396977ede..0cd8989c80137616204dc1696ea8a4b642bbfdd4 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/RegistryService.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/CurrencyService.java
@@ -41,13 +41,11 @@ import org.duniter.core.service.CryptoService;
 import org.duniter.core.util.ObjectUtils;
 import org.duniter.core.util.StringUtils;
 import org.duniter.elasticsearch.PluginSettings;
-import org.duniter.elasticsearch.action.security.RestSecurityController;
 import org.duniter.elasticsearch.exception.AccessDeniedException;
 import org.duniter.elasticsearch.exception.DuplicateIndexIdException;
 import org.duniter.elasticsearch.exception.InvalidSignatureException;
 import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
 import org.elasticsearch.action.index.IndexRequestBuilder;
-import org.elasticsearch.action.index.IndexResponse;
 import org.elasticsearch.action.search.SearchPhaseExecutionException;
 import org.elasticsearch.action.search.SearchRequestBuilder;
 import org.elasticsearch.action.search.SearchResponse;
@@ -60,7 +58,6 @@ import org.elasticsearch.index.query.QueryBuilders;
 import org.elasticsearch.search.SearchHit;
 import org.elasticsearch.search.SearchHitField;
 
-import java.io.File;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.util.List;
@@ -69,24 +66,20 @@ import java.util.Objects;
 /**
  * Created by Benoit on 30/03/2015.
  */
-public class RegistryService extends AbstractService {
+public class CurrencyService extends AbstractService {
 
-    public static final String INDEX = "registry";
-    public static final String RECORD_TYPE = "record";
-    public static final String RECORD_CATEGORY_TYPE = "category";
-    public static final String RECORD_COMMENT_TYPE = "comment";
-    public static final String CURRENCY_TYPE = "currency";
-    private static final String CATEGORIES_BULK_CLASSPATH_FILE = "registry-categories-bulk-insert.json";
+    public static final String INDEX = "currency";
+    public static final String CURRENCY_TYPE = "record";
 
     private final Gson gson;
     private BlockchainRemoteService blockchainRemoteService;
 
     @Inject
-    public RegistryService(Client client,
+    public CurrencyService(Client client,
                            PluginSettings settings,
                            CryptoService cryptoService,
                            BlockchainRemoteService blockchainRemoteService) {
-        super("gchange." + INDEX, client, settings, cryptoService);
+        super("duniter." + INDEX, client, settings, cryptoService);
         this.gson = GsonUtils.newBuilder().create();
         this.blockchainRemoteService = blockchainRemoteService;
     }
@@ -94,12 +87,10 @@ public class RegistryService extends AbstractService {
     /**
      * Create index need for blockchain registry, if need
      */
-    public RegistryService createIndexIfNotExists() {
+    public CurrencyService createIndexIfNotExists() {
         try {
             if (!existsIndex(INDEX)) {
                 createIndex();
-
-                fillRecordCategories();
             }
         }
         catch(JsonProcessingException e) {
@@ -112,7 +103,7 @@ public class RegistryService extends AbstractService {
      * Create index for registry
      * @throws JsonProcessingException
      */
-    public RegistryService createIndex() throws JsonProcessingException {
+    public CurrencyService createIndex() throws JsonProcessingException {
         logger.info(String.format("Creating index [%s]", INDEX));
 
         CreateIndexRequestBuilder createIndexRequestBuilder = client.admin().indices().prepareCreate(INDEX);
@@ -123,15 +114,12 @@ public class RegistryService extends AbstractService {
                 .build();
         createIndexRequestBuilder.setSettings(indexSettings);
         createIndexRequestBuilder.addMapping(CURRENCY_TYPE, createCurrencyType());
-        createIndexRequestBuilder.addMapping(RECORD_CATEGORY_TYPE, createRecordCategoryType());
-        createIndexRequestBuilder.addMapping(RECORD_TYPE, createRecordType());
-        createIndexRequestBuilder.addMapping(RECORD_COMMENT_TYPE, createRecordCommentType(INDEX, RECORD_COMMENT_TYPE));
         createIndexRequestBuilder.execute().actionGet();
 
         return this;
     }
 
-    public RegistryService deleteIndex() {
+    public CurrencyService deleteIndex() {
         deleteIndexIfExists(INDEX);
         return this;
     }
@@ -140,50 +128,11 @@ public class RegistryService extends AbstractService {
         return super.existsIndex(INDEX);
     }
 
-    public RegistryService fillRecordCategories() {
-        if (logger.isDebugEnabled()) {
-            logger.debug(String.format("[%s/%s] Fill data", INDEX, RECORD_CATEGORY_TYPE));
-        }
-
-        // Insert categories
-        bulkFromClasspathFile(CATEGORIES_BULK_CLASSPATH_FILE, INDEX, RECORD_CATEGORY_TYPE,
-                // Add order attribute
-                new AddSequenceAttributeHandler("order", "\\{.*\"name\".*\\}", 1));
-
-        return this;
-    }
-
     public boolean isCurrencyExists(String currencyName) {
         String pubkey = getSenderPubkeyByCurrencyId(currencyName);
         return !StringUtils.isEmpty(pubkey);
     }
 
-    public String indexRecordFromJson(String json) {
-        return checkIssuerAndIndexDocumentFromJson(INDEX, RECORD_TYPE, json);
-    }
-
-    public void updateRecordFromJson(String json, String id) {
-        checkIssuerAndUpdateDocumentFromJson(INDEX, RECORD_TYPE, json, id);
-    }
-
-    public String indexCommentFromJson(String json) {
-        return checkIssuerAndIndexDocumentFromJson(INDEX, RECORD_COMMENT_TYPE, json);
-    }
-
-    public void updateCommentFromJson(String json, String id) {
-        checkIssuerAndUpdateDocumentFromJson(INDEX, RECORD_COMMENT_TYPE, json, id);
-    }
-
-    public void insertRecordFromBulkFile(File bulkFile) {
-
-        if (logger.isDebugEnabled()) {
-            logger.debug("Inserting records from file");
-        }
-
-        // Insert cities
-        bulkFromFile(bulkFile, INDEX, RECORD_TYPE);
-    }
-
     /**
      * Retrieve the blockchain data, from peer
      *
@@ -369,195 +318,6 @@ public class RegistryService extends AbstractService {
 
     /* -- Internal methods -- */
 
-
-    public XContentBuilder createRecordType() {
-        String stringAnalyzer = pluginSettings.getDefaultStringAnalyzer();
-
-        try {
-            XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject(RECORD_TYPE)
-                    .startObject("properties")
-
-                    // title
-                    .startObject("title")
-                    .field("type", "string")
-                    .field("analyzer", stringAnalyzer)
-                    .endObject()
-
-                    // description
-                    .startObject("description")
-                    .field("type", "string")
-                    .field("analyzer", stringAnalyzer)
-                    .endObject()
-
-                    // creationTime
-                    .startObject("creationTime")
-                    .field("type", "integer")
-                    .endObject()
-
-                    // time
-                    .startObject("time")
-                    .field("type", "integer")
-                    .endObject()
-
-                    // issuer
-                    .startObject("issuer")
-                    .field("type", "string")
-                    .field("index", "not_analyzed")
-                    .endObject()
-
-                    // pubkey
-                    .startObject("pubkey")
-                    .field("type", "string")
-                    .field("index", "not_analyzed")
-                    .endObject()
-
-                    // address
-                    .startObject("address")
-                    .field("type", "string")
-                    .field("analyzer", stringAnalyzer)
-                    .endObject()
-
-                    // city
-                    .startObject("city")
-                    .field("type", "string")
-                    .endObject()
-
-                    // geoPoint
-                    .startObject("geoPoint")
-                    .field("type", "geo_point")
-                    .endObject()
-
-                    // thumbnail
-                    .startObject("thumbnail")
-                    .field("type", "attachment")
-                    .startObject("fields") // src
-                    .startObject("content") // title
-                    .field("index", "no")
-                    .endObject()
-                    .startObject("title") // title
-                    .field("type", "string")
-                    .field("store", "no")
-                    .endObject()
-                    .startObject("author") // title
-                    .field("store", "no")
-                    .endObject()
-                    .startObject("content_type") // title
-                    .field("store", "yes")
-                    .endObject()
-                    .endObject()
-                    .endObject()
-
-                    // pictures
-                    .startObject("pictures")
-                    .field("type", "nested")
-                    .field("dynamic", "false")
-                    .startObject("properties")
-                    .startObject("file") // file
-                    .field("type", "attachment")
-                    .startObject("fields")
-                    .startObject("content") // content
-                    .field("index", "no")
-                    .endObject()
-                    .startObject("title") // title
-                    .field("type", "string")
-                    .field("store", "yes")
-                    .field("analyzer", stringAnalyzer)
-                    .endObject()
-                    .startObject("author") // author
-                    .field("type", "string")
-                    .field("store", "no")
-                    .endObject()
-                    .startObject("content_type") // content_type
-                    .field("store", "yes")
-                    .endObject()
-                    .endObject()
-                    .endObject()
-                    .endObject()
-                    .endObject()
-
-                    // picturesCount
-                    .startObject("picturesCount")
-                    .field("type", "integer")
-                    .endObject()
-
-                    // category
-                    .startObject("category")
-                    .field("type", "nested")
-                    .field("dynamic", "false")
-                    .startObject("properties")
-                    .startObject("id") // id
-                    .field("type", "string")
-                    .field("index", "not_analyzed")
-                    .endObject()
-                    .startObject("parent") // parent
-                    .field("type", "string")
-                    .field("index", "not_analyzed")
-                    .endObject()
-                    .startObject("name") // name
-                    .field("type", "string")
-                    .field("analyzer", stringAnalyzer)
-                    .endObject()
-                    .endObject()
-                    .endObject()
-
-                    // tags
-                    .startObject("tags")
-                    .field("type", "completion")
-                    .field("search_analyzer", "simple")
-                    .field("analyzer", "simple")
-                    .field("preserve_separators", "false")
-                    .endObject()
-
-                    .endObject()
-                    .endObject().endObject();
-
-            return mapping;
-        }
-        catch(IOException ioe) {
-            throw new TechnicalException(String.format("Error while getting mapping for index [%s/%s]: %s", INDEX, RECORD_TYPE, ioe.getMessage()), ioe);
-        }
-    }
-
-    public XContentBuilder createRecordCategoryType() {
-        try {
-            XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject(RECORD_CATEGORY_TYPE)
-                    .startObject("properties")
-
-                    // name
-                    .startObject("name")
-                    .field("type", "string")
-                    .field("analyzer", pluginSettings.getDefaultStringAnalyzer())
-                    .endObject()
-
-                    // description
-                    /*.startObject("description")
-                    .field("type", "string")
-                    .endObject()*/
-
-                    // parent
-                    .startObject("parent")
-                    .field("type", "string")
-                    .field("index", "not_analyzed")
-                    .endObject()
-
-                    // tags
-                    /*.startObject("tags")
-                    .field("type", "completion")
-                    .field("search_analyzer", "simple")
-                    .field("analyzer", "simple")
-                    .field("preserve_separators", "false")
-                    .endObject()*/
-
-                    .endObject()
-                    .endObject().endObject();
-
-            return mapping;
-        }
-        catch(IOException ioe) {
-            throw new TechnicalException(String.format("Error while getting mapping for index [%s/%s]: %s", INDEX, RECORD_CATEGORY_TYPE, ioe.getMessage()), ioe);
-        }
-    }
-
     public XContentBuilder createCurrencyType() {
         try {
             XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject(CURRENCY_TYPE)
@@ -591,30 +351,6 @@ public class RegistryService extends AbstractService {
         }
     }
 
-    /**
-     *
-     * @param jsonCategory
-     * @return the product id
-     */
-    public String indexCategoryFromJson(String jsonCategory) {
-        if (logger.isDebugEnabled()) {
-            logger.debug("Indexing a category");
-        }
-
-        // Preparing indexBlocksFromNode
-        IndexRequestBuilder indexRequest = client.prepareIndex(INDEX, RECORD_CATEGORY_TYPE)
-                .setSource(jsonCategory);
-
-        // Execute indexBlocksFromNode
-        IndexResponse response = indexRequest
-                .setRefresh(false)
-                .execute().actionGet();
-
-        return response.getId();
-    }
-
-
-
     /**
      * Retrieve a blockchain from its name
      * @param currencyId
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/ServiceLocator.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/ServiceLocator.java
similarity index 97%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/ServiceLocator.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/ServiceLocator.java
index d2b283fdd496814605ca1b1fa9990c45b6c08e64..98d46240d912a81aee7fcd89f905d6cf9d45032f 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/ServiceLocator.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/ServiceLocator.java
@@ -59,10 +59,10 @@ public class ServiceLocator
     private static BeanFactory beanFactory = null;
 
     @Inject
-    public ServiceLocator(Injector injector) {
+    public ServiceLocator() {
         super();
         if (logger.isDebugEnabled()) {
-            logger.debug("Starting Duniter4j client ServiceLocator...");
+            logger.debug("Starting Duniter4j ServiceLocator...");
         }
         setBeanFactory(getOrCreateBeanFactory());
 
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/ServiceModule.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/ServiceModule.java
similarity index 70%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/ServiceModule.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/ServiceModule.java
index 00890a8cfadc92ca62fb24747a88fe2dfda8f2be..9612444ee283c20f76bf5e3f4c609ff6c48533fa 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/ServiceModule.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/ServiceModule.java
@@ -34,9 +34,9 @@ import org.duniter.core.client.service.bma.WotRemoteService;
 import org.duniter.core.client.service.local.CurrencyService;
 import org.duniter.core.client.service.local.PeerService;
 import org.duniter.core.service.CryptoService;
+import org.duniter.elasticsearch.PluginInit;
 import org.duniter.elasticsearch.PluginSettings;
-import org.duniter.elasticsearch.service.event.EventService;
-import org.duniter.elasticsearch.service.synchro.SynchroService;
+import org.duniter.elasticsearch.service.changes.ChangeService;
 import org.elasticsearch.common.inject.AbstractModule;
 import org.elasticsearch.common.inject.Module;
 
@@ -45,19 +45,13 @@ public class ServiceModule extends AbstractModule implements Module {
     @Override protected void configure() {
         bind(ServiceLocator.class).asEagerSingleton();
 
-        // ES common service
+        // common services
         bind(PluginSettings.class).asEagerSingleton();
-        bind(EventService.class).asEagerSingleton();
+        bind(PluginInit.class).asEagerSingleton();
+        bind(ChangeService.class).asEagerSingleton();
 
-        // ES indexation services
-        bind(RegistryService.class).asEagerSingleton();
-        bind(MarketService.class).asEagerSingleton();
+        // indexation services
         bind(BlockchainService.class).asEagerSingleton();
-        bind(MessageService.class).asEagerSingleton();
-        bind(HistoryService.class).asEagerSingleton();
-
-        // ES Synchro services
-        bind(SynchroService.class).asEagerSingleton();
 
         // Duniter Client API beans
         bindWithLocator(BlockchainRemoteService.class);
@@ -74,19 +68,6 @@ public class ServiceModule extends AbstractModule implements Module {
         // Duniter Shared API beans
         bindWithLocator(CryptoService.class);
         bindWithLocator(org.duniter.core.service.MailService.class);
-
-/*
-        bindWithLocator(BlockchainRemoteServiceImpl.class);
-        bindWithLocator(NetworkRemoteServiceImpl.class);
-        bindWithLocator(WotRemoteServiceImpl.class);
-        bindWithLocator(TransactionRemoteServiceImpl.class);
-        bindWithLocator(Ed25519CryptoServiceImpl.class);
-        bindWithLocator(PeerServiceImpl.class);
-        bindWithLocator(CurrencyServiceImpl.class);
-        bindWithLocator(HttpServiceImpl.class);
-        bindWithLocator(MemoryCurrencyDaoImpl.class);
-        bindWithLocator(MemoryPeerDaoImpl.class);
-        bindWithLocator(DataContext.class);*/
     }
 
     /* protected methods */
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/websocket/ChangeEvent.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/changes/ChangeEvent.java
similarity index 88%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/websocket/ChangeEvent.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/changes/ChangeEvent.java
index f1dde61423642fa6ee1ec65076b3fea5a9555cdc..99d6fd7a0963fb770138e103d48e9bb3dc6661cc 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/websocket/ChangeEvent.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/changes/ChangeEvent.java
@@ -1,4 +1,4 @@
-package org.duniter.elasticsearch.websocket;
+package org.duniter.elasticsearch.service.changes;
 
 /*
  * #%L
@@ -43,6 +43,7 @@ import org.joda.time.DateTime;
 
 public class ChangeEvent {
     private final String id;
+    private final String index;
     private final String type;
     private final DateTime timestamp;
     private final Operation operation;
@@ -53,8 +54,9 @@ public class ChangeEvent {
         INDEX,CREATE,DELETE
     }
 
-    public ChangeEvent(String id, String type, DateTime timestamp, Operation operation, long version, BytesReference source) {
+    public ChangeEvent(String index, String type, String id, DateTime timestamp, Operation operation, long version, BytesReference source) {
         this.id = id;
+        this.index = index;
         this.type = type;
         this.timestamp = timestamp;
         this.operation = operation;
@@ -74,6 +76,10 @@ public class ChangeEvent {
         return timestamp;
     }
 
+    public String getIndex() {
+        return index;
+    }
+
     public String getType() {
         return type;
     }
@@ -85,4 +91,6 @@ public class ChangeEvent {
     public BytesReference getSource() {
         return source;
     }
+
+
 }
diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/changes/ChangeListener.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/changes/ChangeListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..af8ba0918419f329a85acb46592e8756c245dbec
--- /dev/null
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/changes/ChangeListener.java
@@ -0,0 +1,6 @@
+package org.duniter.elasticsearch.service.changes;
+
+public interface ChangeListener {
+    String getId();
+    void onChanges(String message);
+}
\ No newline at end of file
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/websocket/ChangeRegister.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/changes/ChangeService.java
similarity index 75%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/websocket/ChangeRegister.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/changes/ChangeService.java
index 4fbeba359826c4ba80d63cc5e24cd28c52ae9035..56487c3846fcf2a609be0120b5ed919039faeded 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/websocket/ChangeRegister.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/changes/ChangeService.java
@@ -1,4 +1,4 @@
-package org.duniter.elasticsearch.websocket;
+package org.duniter.elasticsearch.service.changes;
 
 /*
  * #%L
@@ -50,63 +50,32 @@ import org.elasticsearch.index.indexing.IndexingOperationListener;
 import org.elasticsearch.index.shard.IndexShard;
 import org.elasticsearch.indices.IndicesLifecycle;
 import org.elasticsearch.indices.IndicesService;
-import org.glassfish.tyrus.server.Server;
 import org.joda.time.DateTime;
 
-import javax.websocket.DeploymentException;
 import java.io.IOException;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
-public class ChangeRegister {
+public class ChangeService {
 
-    private static final String SETTING_PRIMARY_SHARD_ONLY = "changes.primaryShardOnly";
-    private static final String SETTING_PORT = "changes.port";
-    private static final String SETTING_LISTEN_SOURCE = "changes.listenSource";
+    private static final String SETTING_PRIMARY_SHARD_ONLY = "duniter.changes.primaryShardOnly";
+    private static final String SETTING_LISTEN_SOURCE = "duniter.changes.listenSource";
 
-    private final ESLogger log = Loggers.getLogger(ChangeRegister.class);
+    private final ESLogger log = Loggers.getLogger(ChangeService.class);
 
-    private static final Map<String, WebSocketServerEndPoint> LISTENERS = new HashMap<String, WebSocketServerEndPoint>();
+    private static final Map<String, ChangeListener> LISTENERS = new HashMap<>();
 
     @Inject
-    public ChangeRegister(final Settings settings, IndicesService indicesService) {
+    public ChangeService(final Settings settings, IndicesService indicesService) {
         final boolean allShards = !settings.getAsBoolean(SETTING_PRIMARY_SHARD_ONLY, Boolean.FALSE);
-        final int port = settings.getAsInt(SETTING_PORT, 9400);
         final String[] sourcesStr = settings.getAsArray(SETTING_LISTEN_SOURCE, new String[]{"*"});
         final Set<ChangeSource> sources = new HashSet<>();
         for(String sourceStr : sourcesStr) {
             sources.add(new ChangeSource(sourceStr));
         }
 
-        final Server server = new Server("localhost", port, "/ws", null, WebSocketServerEndPoint.class) ;
-
-        try {
-            log.info("Starting WebSocketServerEndPoint server");
-            AccessController.doPrivileged(new PrivilegedAction() {
-                @Override
-                public Object run() {
-                    try {
-                        // Tyrus tries to load the server code using reflection. In Elasticsearch 2.x Java
-                        // security manager is used which breaks the reflection code as it can't find the class.
-                        // This is a workaround for that
-                        Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
-                        server.start();
-                        return null;
-                    } catch (DeploymentException e) {
-                        throw new RuntimeException("Failed to start server", e);
-                    }
-                }
-            });
-            log.info("WebSocketServerEndPoint server started");
-        } catch (Exception e) {
-            log.error("Failed to start WebSocketServerEndPoint server",e);
-            throw new RuntimeException(e);
-        }
-
         indicesService.indicesLifecycle().addListener(new IndicesLifecycle.Listener() {
             @Override
             public void afterIndexShardStarted(IndexShard indexShard) {
@@ -117,8 +86,9 @@ public class ChangeRegister {
                         @Override
                         public void postCreate(Engine.Create create) {
                             ChangeEvent change=new ChangeEvent(
-                                    create.id(),
+                                    indexName,
                                     create.type(),
+                                    create.id(),
                                     new DateTime(),
                                     ChangeEvent.Operation.CREATE,
                                     create.version(),
@@ -131,8 +101,9 @@ public class ChangeRegister {
                         @Override
                         public void postDelete(Engine.Delete delete) {
                             ChangeEvent change=new ChangeEvent(
-                                    delete.id(),
+                                    indexName,
                                     delete.type(),
+                                    delete.id(),
                                     new DateTime(),
                                     ChangeEvent.Operation.DELETE,
                                     delete.version(),
@@ -146,8 +117,9 @@ public class ChangeRegister {
                         public void postIndex(Engine.Index index) {
 
                             ChangeEvent change=new ChangeEvent(
-                                    index.id(),
+                                    indexName,
                                     index.type(),
+                                    index.id(),
                                     new DateTime(),
                                     ChangeEvent.Operation.INDEX,
                                     index.version(),
@@ -205,17 +177,15 @@ public class ChangeRegister {
                                 }
                                 builder.endObject();
 
-
-
                                 message = builder.string();
                             } catch (IOException e) {
                                 log.error("Failed to write JSON", e);
                                 return;
                             }
 
-                            for (WebSocketServerEndPoint listener : LISTENERS.values()) {
+                            for (ChangeListener listener : LISTENERS.values()) {
                                 try {
-                                    listener.sendMessage(message);
+                                    listener.onChanges(message);
                                 } catch (Exception e) {
                                     log.error("Failed to send message", e);
                                 }
@@ -230,11 +200,13 @@ public class ChangeRegister {
         });
     }
 
-    public static void registerListener(WebSocketServerEndPoint webSocket) {
-        LISTENERS.put(webSocket.getId(), webSocket);
+    public static void registerListener(ChangeListener listener) {
+        LISTENERS.put(listener.getId(), listener);
     }
 
-    public static void unregisterListener(WebSocketServerEndPoint webSocket) {
-        LISTENERS.remove(webSocket.getId());
+    public static void unregisterListener(ChangeListener listener) {
+        LISTENERS.remove(listener.getId());
     }
+
+
 }
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/websocket/ChangeSource.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/changes/ChangeSource.java
similarity index 97%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/websocket/ChangeSource.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/changes/ChangeSource.java
index 9cf7a1793d2e7cdc051e12e550ebdf162849590a..6f79a5076ffaa77d7dee8a0211c3bad1aabd76b7 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/websocket/ChangeSource.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/changes/ChangeSource.java
@@ -1,4 +1,4 @@
-package org.duniter.elasticsearch.websocket;
+package org.duniter.elasticsearch.service.changes;
 
 /*
  * #%L
diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/changes/ChangeUtils.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/changes/ChangeUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..cfe6a16c9e79010ffbd69ca061402b36b08bf5a7
--- /dev/null
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/service/changes/ChangeUtils.java
@@ -0,0 +1,65 @@
+package org.duniter.elasticsearch.service.changes;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.gson.JsonSyntaxException;
+import org.duniter.core.exception.TechnicalException;
+import org.duniter.elasticsearch.exception.InvalidFormatException;
+import org.elasticsearch.common.bytes.BytesReference;
+import org.elasticsearch.common.io.stream.BytesStreamOutput;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.json.JsonXContent;
+import org.joda.time.DateTime;
+
+import java.io.IOException;
+
+/**
+ * Created by blavenie on 30/11/16.
+ */
+public class ChangeUtils {
+
+    public static ChangeEvent fromJson(ObjectMapper objectMapper, String json) {
+        try {
+            JsonNode actualObj = objectMapper.readTree(json);
+            String index = actualObj.get("_index").asText();
+            String type = actualObj.get("_type").asText();
+            String id = actualObj.get("_id").asText();
+            DateTime timestamp = new DateTime(actualObj.get("_timestamp").asLong());
+            ChangeEvent.Operation operation = ChangeEvent.Operation.valueOf(actualObj.get("_operation").asText());
+            long version = actualObj.get("_version").asLong();
+
+            JsonNode sourceNode = actualObj.get("_source");
+            BytesReference source = null;
+            if (sourceNode != null) {
+                // TODO : fill bytes reference from source
+                //source = sourceNode.
+            }
+
+            ChangeEvent event = new ChangeEvent(index, type, id, timestamp, operation, version, source);
+            return event;
+        } catch (IOException | JsonSyntaxException e) {
+            throw new InvalidFormatException("Invalid record JSON: " + e.getMessage(), e);
+        }
+    }
+
+    public static String toJson(ChangeEvent change) {
+        try {
+            XContentBuilder builder = new XContentBuilder(JsonXContent.jsonXContent, new BytesStreamOutput());
+            builder.startObject()
+                    .field("_index", change.getIndex())
+                    .field("_type", change.getType())
+                    .field("_id", change.getId())
+                    .field("_timestamp", change.getTimestamp())
+                    .field("_version", change.getVersion())
+                    .field("_operation", change.getOperation().toString());
+            if (change.getSource() != null) {
+                builder.rawField("_source", change.getSource());
+            }
+            builder.endObject();
+
+            return builder.string();
+        } catch (IOException e) {
+            throw new TechnicalException("Error while generating JSON from change event", e);
+        }
+    }
+}
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/threadpool/ThreadPool.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/threadpool/ThreadPool.java
similarity index 94%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/threadpool/ThreadPool.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/threadpool/ThreadPool.java
index b024cbc0d1e1dffe5ff41e47597f77044f1785d1..85944904ffe00ef687f6f7c1c1ab20da972f185e 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/threadpool/ThreadPool.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/threadpool/ThreadPool.java
@@ -98,9 +98,9 @@ public class ThreadPool extends AbstractLifecycleComponent<ThreadPool> {
     }
 
     /**
-     * Schedules an action when node is started (all services and modules ready)
+     * Schedules an rest when node is started (all services and modules ready)
      *
-     * @param job the action to execute when node started
+     * @param job the rest to execute when node started
      * @return a ScheduledFuture who's get will return when the task is complete and throw an exception if it is canceled
      */
     public void scheduleOnStarted(Runnable job) {
@@ -109,9 +109,9 @@ public class ThreadPool extends AbstractLifecycleComponent<ThreadPool> {
     }
 
     /**
-     * Schedules an action when cluster is ready
+     * Schedules an rest when cluster is ready
      *
-     * @param job the action to execute
+     * @param job the rest to execute
      * @param expectedStatus expected health status, to run the job
      * @return a ScheduledFuture who's get will return when the task is complete and throw an exception if it is canceled
      */
@@ -127,9 +127,9 @@ public class ThreadPool extends AbstractLifecycleComponent<ThreadPool> {
     }
 
     /**
-     * Schedules an action that runs on the scheduler thread, after a delay.
+     * Schedules an rest that runs on the scheduler thread, after a delay.
      *
-     * @param command the action to take
+     * @param command the rest to take
      * @param interval the delay interval
      * @return a ScheduledFuture who's get will return when the task is complete and throw an exception if it is canceled
      */
@@ -138,9 +138,9 @@ public class ThreadPool extends AbstractLifecycleComponent<ThreadPool> {
     }
 
     /**
-     * Schedules a periodic action that always runs on the scheduler thread.
+     * Schedules a periodic rest that always runs on the scheduler thread.
      *
-     * @param command the action to take
+     * @param command the rest to take
      * @param interval the delay interval
      * @return a ScheduledFuture who's get will return when the task is complete and throw an exception if it is canceled
      */
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/util/Desktop.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/util/Desktop.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/util/Desktop.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/util/Desktop.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/util/DesktopPower.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/util/DesktopPower.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/util/DesktopPower.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/util/DesktopPower.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/util/os/win/WindowsPower.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/util/os/win/WindowsPower.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/util/os/win/WindowsPower.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/util/os/win/WindowsPower.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/util/os/win/handle/CWPSSTRUCT.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/util/os/win/handle/CWPSSTRUCT.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/util/os/win/handle/CWPSSTRUCT.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/util/os/win/handle/CWPSSTRUCT.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/util/os/win/handle/HANDLER_ROUTINE.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/util/os/win/handle/HANDLER_ROUTINE.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/util/os/win/handle/HANDLER_ROUTINE.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/util/os/win/handle/HANDLER_ROUTINE.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/util/os/win/handle/WNDPROC.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/util/os/win/handle/WNDPROC.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/util/os/win/handle/WNDPROC.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/util/os/win/handle/WNDPROC.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/util/os/win/libs/Kernel32Ex.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/util/os/win/libs/Kernel32Ex.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/util/os/win/libs/Kernel32Ex.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/util/os/win/libs/Kernel32Ex.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/util/os/win/wrap/GetLastErrorException.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/util/os/win/wrap/GetLastErrorException.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/util/os/win/wrap/GetLastErrorException.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/util/os/win/wrap/GetLastErrorException.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/util/os/win/wrap/WNDCLASSEXWrap.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/util/os/win/wrap/WNDCLASSEXWrap.java
similarity index 100%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/util/os/win/wrap/WNDCLASSEXWrap.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/util/os/win/wrap/WNDCLASSEXWrap.java
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/websocket/WebSocketServerEndPoint.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/websocket/WebsocketChangeEndPoint.java
similarity index 84%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/websocket/WebSocketServerEndPoint.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/websocket/WebsocketChangeEndPoint.java
index eb6b2e90d64ec6b28f6c19a21defdd6695d46d32..23e983af34e1c6a1d2e1088d11a2c4bf1fc9bdb7 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/websocket/WebSocketServerEndPoint.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/websocket/WebsocketChangeEndPoint.java
@@ -38,6 +38,8 @@ package org.duniter.elasticsearch.websocket;
     limitations under the License.
 */
 
+import org.duniter.elasticsearch.service.changes.ChangeListener;
+import org.duniter.elasticsearch.service.changes.ChangeService;
 import org.elasticsearch.common.logging.ESLogger;
 import org.elasticsearch.common.logging.Loggers;
 
@@ -45,22 +47,24 @@ import javax.websocket.*;
 import javax.websocket.server.ServerEndpoint;
 
 @ServerEndpoint(value = "/_changes")
-public class WebSocketServerEndPoint {
+public class WebsocketChangeEndPoint implements ChangeListener{
 
-    private final ESLogger log = Loggers.getLogger(WebSocketServerEndPoint.class);
+    private final ESLogger log = Loggers.getLogger(WebsocketChangeEndPoint.class);
     private Session session;
 
     @OnOpen
     public void onOpen(Session session) {
         log.info("Connected ... " + session.getId());
         this.session = session;
-        ChangeRegister.registerListener(this);
+        ChangeService.registerListener(this);
     }
 
-    public void sendMessage(String message) {
+    @Override
+    public void onChanges(String message) {
         session.getAsyncRemote().sendText(message);
     }
 
+    @Override
     public String getId() {
         return session == null ? null : session.getId();
     }
@@ -73,7 +77,7 @@ public class WebSocketServerEndPoint {
     @OnClose
     public void onClose(CloseReason reason) {
         log.info("Closing websocket: "+reason);
-        ChangeRegister.unregisterListener(this);
+        ChangeService.unregisterListener(this);
         this.session = null;
     }
 
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/websocket/ChangesModule.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/websocket/WebsocketModule.java
similarity index 87%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/websocket/ChangesModule.java
rename to duniter4j-es-core/src/main/java/org/duniter/elasticsearch/websocket/WebsocketModule.java
index 4e02183bf3d7aaf70151db38a5e713b0c9567255..e3472356762aa94f1385fd79c357c252116addb2 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/websocket/ChangesModule.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/websocket/WebsocketModule.java
@@ -42,12 +42,12 @@ import org.elasticsearch.common.inject.AbstractModule;
 import org.elasticsearch.common.logging.ESLogger;
 import org.elasticsearch.common.logging.Loggers;
 
-public class ChangesModule extends AbstractModule {
-    private final ESLogger log = Loggers.getLogger(ChangesModule.class);
+public class WebsocketModule extends AbstractModule {
+    private final ESLogger log = Loggers.getLogger(WebsocketModule.class);
     
     @Override
     protected void configure() {
-        log.debug("Binding Changes Module");
-        bind(ChangeRegister.class).asEagerSingleton();
+        log.debug("Binding websocket Module");
+        bind(WebsocketServer.class).asEagerSingleton();
     }
 }
diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/websocket/WebsocketServer.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/websocket/WebsocketServer.java
new file mode 100644
index 0000000000000000000000000000000000000000..f3a44ae8c07495699c3fe34ac374b307e3cf4bfb
--- /dev/null
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/websocket/WebsocketServer.java
@@ -0,0 +1,86 @@
+package org.duniter.elasticsearch.websocket;
+
+/*
+ * #%L
+ * Duniter4j :: ElasticSearch Plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+/*
+    Copyright 2015 ForgeRock AS
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+*/
+
+import org.duniter.elasticsearch.PluginSettings;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.logging.ESLogger;
+import org.elasticsearch.common.logging.Loggers;
+import org.glassfish.tyrus.server.Server;
+
+import javax.websocket.DeploymentException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+public class WebsocketServer {
+
+    private final ESLogger log = Loggers.getLogger(WebsocketServer.class);
+
+    @Inject
+    public WebsocketServer(final PluginSettings pluginSettings) {
+        final String host = pluginSettings.getWebSocketHost();
+        final int port = pluginSettings.getWebSocketPort();
+
+        final Server server = new Server(host, port, "/ws", null, WebsocketChangeEndPoint.class) ;
+
+        try {
+            log.info("Starting websocket server");
+            AccessController.doPrivileged(new PrivilegedAction() {
+                @Override
+                public Object run() {
+                    try {
+                        // Tyrus tries to load the server code using reflection. In Elasticsearch 2.x Java
+                        // security manager is used which breaks the reflection code as it can't find the class.
+                        // This is a workaround for that
+                        Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+                        server.start();
+                        return null;
+                    } catch (DeploymentException e) {
+                        throw new RuntimeException("Failed to start server", e);
+                    }
+                }
+            });
+            log.info("Websocket server started");
+        } catch (Exception e) {
+            log.error("Failed to start Websocket server",e);
+            throw new RuntimeException(e);
+        }
+    }
+
+}
diff --git a/duniter4j-elasticsearch/src/main/resources/META-INF/services/javax.websocket.ContainerProvider b/duniter4j-es-core/src/main/resources/META-INF/services/javax.websocket.ContainerProvider
similarity index 100%
rename from duniter4j-elasticsearch/src/main/resources/META-INF/services/javax.websocket.ContainerProvider
rename to duniter4j-es-core/src/main/resources/META-INF/services/javax.websocket.ContainerProvider
diff --git a/duniter4j-elasticsearch/src/main/resources/META-INF/services/org.duniter.core.beans.Bean b/duniter4j-es-core/src/main/resources/META-INF/services/org.duniter.core.beans.Bean
similarity index 100%
rename from duniter4j-elasticsearch/src/main/resources/META-INF/services/org.duniter.core.beans.Bean
rename to duniter4j-es-core/src/main/resources/META-INF/services/org.duniter.core.beans.Bean
diff --git a/duniter4j-elasticsearch/src/main/resources/META-INF/services/org.nuiton.config.ApplicationConfigProvider b/duniter4j-es-core/src/main/resources/META-INF/services/org.nuiton.config.ApplicationConfigProvider
similarity index 100%
rename from duniter4j-elasticsearch/src/main/resources/META-INF/services/org.nuiton.config.ApplicationConfigProvider
rename to duniter4j-es-core/src/main/resources/META-INF/services/org.nuiton.config.ApplicationConfigProvider
diff --git a/duniter4j-elasticsearch/src/main/resources/i18n/duniter4j-elasticsearch_en_GB.properties b/duniter4j-es-core/src/main/resources/i18n/duniter4j-es-core_en_GB.properties
similarity index 92%
rename from duniter4j-elasticsearch/src/main/resources/i18n/duniter4j-elasticsearch_en_GB.properties
rename to duniter4j-es-core/src/main/resources/i18n/duniter4j-es-core_en_GB.properties
index d5a57ab3a335453416ed273e845cb91391aec15c..a6067b359c9b1b3288467e75f3b34faaa2ce093d 100644
--- a/duniter4j-elasticsearch/src/main/resources/i18n/duniter4j-elasticsearch_en_GB.properties
+++ b/duniter4j-es-core/src/main/resources/i18n/duniter4j-es-core_en_GB.properties
@@ -34,10 +34,6 @@ duniter4j.config.option.tasks.queueCapacity.description=
 duniter4j.config.option.temp.directory.description=
 duniter4j.config.option.version.description=
 duniter4j.config.parse.error=
-duniter4j.event.NODE_STARTED=Node started on cluster Duniter4j ES [%s]
-duniter4j.event.subject.ERROR=[%s] Error message
-duniter4j.event.subject.INFO=[%s] Information message
-duniter4j.event.subject.WARN=[%s] Warning message
 duniter4j.executor.task.waitingExecution=
 duniter4j.job.stopped=
 duniter4j.job.stopping=
diff --git a/duniter4j-elasticsearch/src/main/resources/i18n/duniter4j-elasticsearch_fr_FR.properties b/duniter4j-es-core/src/main/resources/i18n/duniter4j-es-core_fr_FR.properties
similarity index 91%
rename from duniter4j-elasticsearch/src/main/resources/i18n/duniter4j-elasticsearch_fr_FR.properties
rename to duniter4j-es-core/src/main/resources/i18n/duniter4j-es-core_fr_FR.properties
index 5c2ac7bf0f54f978cc5aa836d456b53f56dd835b..7e5877795b675d15bc9d49e6fd0be56f4cb548c5 100644
--- a/duniter4j-elasticsearch/src/main/resources/i18n/duniter4j-elasticsearch_fr_FR.properties
+++ b/duniter4j-es-core/src/main/resources/i18n/duniter4j-es-core_fr_FR.properties
@@ -1,4 +1,4 @@
-duniter4j-elasticsearch.config=
+duniter4j-es-core.config=
 duniter4j.blockIndexerService.detectFork.invalidBlock=[%s] [%s] Detecting fork\: block \#%s -> new hash [%s]
 duniter4j.blockIndexerService.detectFork.invalidBlockchain=[%s] [%s] Peer has another blockchain (no common blocks \!). Skipping block \#%s - hash [%s].
 duniter4j.blockIndexerService.detectFork.remoteBlockNotFound=[%s] [%s] Unable to get block \#%s from peer\: %s
@@ -34,10 +34,6 @@ duniter4j.config.option.tasks.queueCapacity.description=
 duniter4j.config.option.temp.directory.description=
 duniter4j.config.option.version.description=
 duniter4j.config.parse.error=
-duniter4j.event.NODE_STARTED=Noeud démarré sur le cluster Duniter4j ES [%s]
-duniter4j.event.subject.ERROR=%s Message d'erreur
-duniter4j.event.subject.INFO=%s Message d'information
-duniter4j.event.subject.WARN=%s Message d'avertissement
 duniter4j.executor.task.waitingExecution=
 duniter4j.job.stopped=
 duniter4j.job.stopping=
diff --git a/duniter4j-elasticsearch/src/main/resources/market-categories-bulk-insert.json b/duniter4j-es-core/src/main/resources/market-categories-bulk-insert.json
similarity index 100%
rename from duniter4j-elasticsearch/src/main/resources/market-categories-bulk-insert.json
rename to duniter4j-es-core/src/main/resources/market-categories-bulk-insert.json
diff --git a/duniter4j-elasticsearch/src/main/resources/plugin-security.policy b/duniter4j-es-core/src/main/resources/plugin-security.policy
similarity index 73%
rename from duniter4j-elasticsearch/src/main/resources/plugin-security.policy
rename to duniter4j-es-core/src/main/resources/plugin-security.policy
index 08f3659df8624bcdf38e613ce8920e539f3d49cb..3cc974ff17c10b2a5fcf00c39c9feda28b665210 100644
--- a/duniter4j-elasticsearch/src/main/resources/plugin-security.policy
+++ b/duniter4j-es-core/src/main/resources/plugin-security.policy
@@ -1,4 +1,4 @@
-grant codeBase "file:${es.path.home}/plugins/duniter4j-elasticsearch/"{
+grant codeBase "file:${es.path.home}/plugins/duniter4j-es-core/"{
   permission java.io.FilePermission "/etc/ld.so.conf", "read";
   permission java.io.FilePermission "/etc/ld.so.conf.d/*.conf", "read";
   permission java.io.FilePermission "/usr/local/lib/*", "read";
diff --git a/duniter4j-elasticsearch/src/main/resources/registry-categories-bulk-insert.json b/duniter4j-es-core/src/main/resources/registry-categories-bulk-insert.json
similarity index 100%
rename from duniter4j-elasticsearch/src/main/resources/registry-categories-bulk-insert.json
rename to duniter4j-es-core/src/main/resources/registry-categories-bulk-insert.json
diff --git a/duniter4j-es-core/src/test/es-home/config/elasticsearch.yml b/duniter4j-es-core/src/test/es-home/config/elasticsearch.yml
new file mode 100644
index 0000000000000000000000000000000000000000..828ddbd04543ef810f380ec8e0dbf229e6c2c48c
--- /dev/null
+++ b/duniter4j-es-core/src/test/es-home/config/elasticsearch.yml
@@ -0,0 +1,178 @@
+# ======================== Elasticsearch Configuration =========================
+#
+# NOTE: Elasticsearch comes with reasonable defaults for most settings.
+#       Before you set out to tweak and tune the configuration, make sure you
+#       understand what are you trying to accomplish and the consequences.
+#
+# The primary way of configuring a node is via this file. This template lists
+# the most important settings you may want to configure for a production cluster.
+#
+# Please see the documentation for further information on configuration options:
+# <http://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration.html>
+#
+# ---------------------------------- Cluster -----------------------------------
+#
+# Use a descriptive name for your cluster:
+#
+# cluster.name: my-application
+cluster.name: duniter4j-elasticsearch-TEST
+#
+# ------------------------------------ Node ------------------------------------
+#
+# Use a descriptive name for the node:
+#
+# node.name: node-1
+#
+# Add custom attributes to the node:
+#
+# node.rack: r1
+#
+# ----------------------------------- Paths ------------------------------------
+#
+# Path to directory where to store the data (separate multiple locations by comma):
+#
+# path.data: /path/to/data
+#
+# Path to log files:
+#
+# path.logs: /path/to/logs
+#
+# ----------------------------------- Memory -----------------------------------
+#
+# Lock the memory on startup:
+#
+# bootstrap.mlockall: true
+#
+# Make sure that the `ES_HEAP_SIZE` environment variable is set to about half the memory
+# available on the system and that the owner of the process is allowed to use this limit.
+#
+# Elasticsearch performs poorly when the system is swapping the memory.
+#
+# ---------------------------------- Network -----------------------------------
+#
+# Set the bind address to a specific IP (IPv4 or IPv6):
+#
+# network.host: 192.168.233.1
+#
+# Set a custom port for HTTP:
+#
+# http.port: 9200-9300
+
+http.cors.allow-origin: "/.*/"
+http.cors.enabled: true
+
+# Internal transport layer
+#
+# transport.tcp.port: 9210-9220
+#
+# For more information, see the documentation at:
+# <http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-network.html>
+#
+# --------------------------------- Discovery ----------------------------------
+#
+# Pass an initial list of hosts to perform discovery when new node is started:
+# The default list of hosts is ["127.0.0.1", "[::1]"]
+#
+# discovery.zen.ping.unicast.hosts: ["host1", "host2"]
+#discovery.zen.ping.unicast.hosts: ["127.0.0.1", ""]
+#
+# Prevent the "split brain" by configuring the majority of nodes (total number of nodes / 2 + 1):
+#
+# discovery.zen.minimum_master_nodes: 3
+#
+# For more information, see the documentation at:
+# <http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-discovery.html>
+#
+# ---------------------------------- Gateway -----------------------------------
+#
+# Block initial recovery after a full cluster restart until N nodes are started:
+#
+# gateway.recover_after_nodes: 3
+#
+# For more information, see the documentation at:
+# <http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-gateway.html>
+#
+# ---------------------------------- Various -----------------------------------
+#
+# Disable starting multiple nodes on a single system:
+#
+# node.max_local_storage_nodes: 1
+#
+# Require explicit names when deleting indices:
+#
+# rest.destructive_requires_name: true
+
+security.manager.enabled: false
+
+#
+# ---------------------------------- Duniter4j ---------------------------------
+#
+# Disbale duniter4j plugin
+#
+# duniter.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
+#
+# Enabling node blockchain synchronization
+#
+duniter.blockchain.sync.enable: false
+#
+# Duniter node to synchronize
+#
+duniter.host: cgeek.fr
+duniter.port: 9330
+#
+# ---------------------------------- Duniter4j security -------------------------
+#
+duniter.keyring.salt: abc
+duniter.keyring.password: def
+
+# Enable security, to disable HTTP access to the default ES admin API
+#
+duniter.security.enable: false
+#
+# Security token prefix (default: 'duniter-')
+#
+# duniter.auth.token.prefix: duniter-
+#
+# Token validity duration, in seconds (default: 600)
+#
+# duniter.auth.tokenValidityDuration: 3600  # = 1hour
+#
+# ---------------------------------- Duniter4j P2P sync -------------------------
+#
+# Should synchronize data using P2P
+#
+duniter.data.sync.enable: false
+#duniter.data.sync.host: data.duniter.fr
+#duniter.data.sync.port: 80
+
+# ---------------------------------- Duniter4j SMTP server -------------------------
+#
+# SMTP server configuration (host and port)
+#
+#duniter.mail.smtp.host: localhost
+#duniter.mail.smtp.port: 25
+#
+# Mail 'from' address
+#
+#duniter.mail.from: no-reply@domain.com
+duniter.mail.from: root@EIS-DEV
+#
+# Mail: admin address
+#
+#duniter.mail.admin: user@domain.com
+duniter.mail.admin: blavenie@EIS-DEV
+#
+# Mail subject prefix
+#
+#duniter.mail.subject.prefix: [Duniter4j ES]
+
+duniter.changes.listenSource: */block
+duniter.ws.port: 9400
diff --git a/duniter4j-es-core/src/test/es-home/config/logging.yml b/duniter4j-es-core/src/test/es-home/config/logging.yml
new file mode 100644
index 0000000000000000000000000000000000000000..15cfa3e195cb46a62c7536f118d1684acfcc2ecf
--- /dev/null
+++ b/duniter4j-es-core/src/test/es-home/config/logging.yml
@@ -0,0 +1,97 @@
+# you can override this using by setting a system property, for example -Des.logger.level=DEBUG
+es.logger.level: INFO
+rootLogger: ${es.logger.level}, console, file
+logger:
+  # log rest execution errors for easier debugging
+  action: DEBUG
+
+  # deprecation logging, turn to DEBUG to see them
+  deprecation: INFO, deprecation_log_file
+
+  # reduce the logging for aws, too much is logged under the default INFO
+  com.amazonaws: WARN
+  # aws will try to do some sketchy JMX stuff, but its not needed.
+  com.amazonaws.jmx.SdkMBeanRegistrySupport: ERROR
+  com.amazonaws.metrics.AwsSdkMetrics: ERROR
+
+  org.apache.http: INFO
+
+  org.duniter: INFO
+
+  org.duniter.elasticsearch: DEBUG
+
+  duniter : DEBUG
+  duniter.network.p2p: TRACE
+
+  security: DEBUG
+
+  org.nuiton.i18n: WARN
+  org.nuiton.config: WARN
+
+  # gateway
+  #gateway: DEBUG
+  #index.gateway: DEBUG
+
+  # peer shard recovery
+  #indices.recovery: DEBUG
+
+  # discovery
+  #discovery: TRACE
+
+  index.search.slowlog: TRACE, index_search_slow_log_file
+  index.indexing.slowlog: TRACE, index_indexing_slow_log_file
+
+additivity:
+  index.search.slowlog: false
+  index.indexing.slowlog: false
+  deprecation: false
+
+appender:
+  console:
+    type: console
+    layout:
+      type: consolePattern
+      conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
+
+  file:
+    type: dailyRollingFile
+    file: ${path.logs}/${cluster.name}.log
+    datePattern: "'.'yyyy-MM-dd"
+    layout:
+      type: pattern
+      conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %.10000m%n"
+
+  # Use the following log4j-extras RollingFileAppender to enable gzip compression of log files. 
+  # For more information see https://logging.apache.org/log4j/extras/apidocs/org/apache/log4j/rolling/RollingFileAppender.html
+  #file:
+    #type: extrasRollingFile
+    #file: ${path.logs}/${cluster.name}.log
+    #rollingPolicy: timeBased
+    #rollingPolicy.FileNamePattern: ${path.logs}/${cluster.name}.log.%d{yyyy-MM-dd}.gz
+    #layout:
+      #type: pattern
+      #conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
+
+  deprecation_log_file:
+    type: dailyRollingFile
+    file: ${path.logs}/${cluster.name}_deprecation.log
+    datePattern: "'.'yyyy-MM-dd"
+    layout:
+      type: pattern
+      conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
+
+  index_search_slow_log_file:
+    type: dailyRollingFile
+    file: ${path.logs}/${cluster.name}_index_search_slowlog.log
+    datePattern: "'.'yyyy-MM-dd"
+    layout:
+      type: pattern
+      conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
+
+  index_indexing_slow_log_file:
+    type: dailyRollingFile
+    file: ${path.logs}/${cluster.name}_index_indexing_slowlog.log
+    datePattern: "'.'yyyy-MM-dd"
+    layout:
+      type: pattern
+      conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
diff --git a/duniter4j-elasticsearch/src/test/java/org/duniter/elasticsearch/TestFixtures.java b/duniter4j-es-core/src/test/java/org/duniter/elasticsearch/TestFixtures.java
similarity index 100%
rename from duniter4j-elasticsearch/src/test/java/org/duniter/elasticsearch/TestFixtures.java
rename to duniter4j-es-core/src/test/java/org/duniter/elasticsearch/TestFixtures.java
diff --git a/duniter4j-elasticsearch/src/test/java/org/duniter/elasticsearch/TestResource.java b/duniter4j-es-core/src/test/java/org/duniter/elasticsearch/TestResource.java
similarity index 100%
rename from duniter4j-elasticsearch/src/test/java/org/duniter/elasticsearch/TestResource.java
rename to duniter4j-es-core/src/test/java/org/duniter/elasticsearch/TestResource.java
diff --git a/duniter4j-elasticsearch/src/test/java/org/duniter/elasticsearch/service/BlockchainServiceTest.java b/duniter4j-es-core/src/test/java/org/duniter/elasticsearch/service/BlockchainServiceTest.java
similarity index 100%
rename from duniter4j-elasticsearch/src/test/java/org/duniter/elasticsearch/service/BlockchainServiceTest.java
rename to duniter4j-es-core/src/test/java/org/duniter/elasticsearch/service/BlockchainServiceTest.java
diff --git a/duniter4j-elasticsearch/src/test/resources/META-INF/services/org.duniter.core.beans.Bean b/duniter4j-es-core/src/test/resources/META-INF/services/org.duniter.core.beans.Bean
similarity index 100%
rename from duniter4j-elasticsearch/src/test/resources/META-INF/services/org.duniter.core.beans.Bean
rename to duniter4j-es-core/src/test/resources/META-INF/services/org.duniter.core.beans.Bean
diff --git a/duniter4j-elasticsearch/src/test/resources/curl_test.sh b/duniter4j-es-core/src/test/resources/curl_test.sh
similarity index 100%
rename from duniter4j-elasticsearch/src/test/resources/curl_test.sh
rename to duniter4j-es-core/src/test/resources/curl_test.sh
diff --git a/duniter4j-elasticsearch/src/test/resources/duniter4j-elasticsearch-localhost-node.properties b/duniter4j-es-core/src/test/resources/duniter4j-elasticsearch-localhost-node.properties
similarity index 100%
rename from duniter4j-elasticsearch/src/test/resources/duniter4j-elasticsearch-localhost-node.properties
rename to duniter4j-es-core/src/test/resources/duniter4j-elasticsearch-localhost-node.properties
diff --git a/duniter4j-elasticsearch/src/test/resources/duniter4j-elasticsearch-test.properties b/duniter4j-es-core/src/test/resources/duniter4j-elasticsearch-test.properties
similarity index 100%
rename from duniter4j-elasticsearch/src/test/resources/duniter4j-elasticsearch-test.properties
rename to duniter4j-es-core/src/test/resources/duniter4j-elasticsearch-test.properties
diff --git a/duniter4j-elasticsearch/src/test/resources/log4j.properties b/duniter4j-es-core/src/test/resources/log4j.properties
similarity index 100%
rename from duniter4j-elasticsearch/src/test/resources/log4j.properties
rename to duniter4j-es-core/src/test/resources/log4j.properties
diff --git a/duniter4j-elasticsearch/src/test/resources/registry-test-records.json b/duniter4j-es-core/src/test/resources/registry-test-records.json
similarity index 100%
rename from duniter4j-elasticsearch/src/test/resources/registry-test-records.json
rename to duniter4j-es-core/src/test/resources/registry-test-records.json
diff --git a/duniter4j-es-gchange/pom.xml b/duniter4j-es-gchange/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a76429f4b6d8d8b9ab396ae7525e3cf85e6e8b9a
--- /dev/null
+++ b/duniter4j-es-gchange/pom.xml
@@ -0,0 +1,129 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.duniter</groupId>
+    <artifactId>duniter4j</artifactId>
+    <version>0.3.5-SNAPSHOT</version>
+  </parent>
+
+  <groupId>org.duniter</groupId>
+  <artifactId>duniter4j-es-gchange</artifactId>
+  <packaging>jar</packaging>
+  <name>Duniter4j :: ElasticSearch GChange plugin</name>
+
+  <properties>
+
+    <!-- i18n configuration -->
+    <i18n.bundleOutputName>duniter4j-es-gchange-i18n</i18n.bundleOutputName>
+    <i18n.generateCsvFile>true</i18n.generateCsvFile>
+    <i18n.bundleCsvFile>
+      ${maven.gen.dir}/resources/META-INF/${i18n.bundleOutputName}.csv
+    </i18n.bundleCsvFile>
+    <config.i18nBundleName>${i18n.bundleOutputName}</config.i18nBundleName>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.duniter</groupId>
+      <artifactId>duniter4j-es-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.duniter</groupId>
+      <artifactId>duniter4j-es-user</artifactId>
+      <version>${project.version}</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <!-- Elastic Search -->
+    <dependency>
+      <groupId>org.elasticsearch</groupId>
+      <artifactId>elasticsearch</artifactId>
+      <scope>provided</scope>
+    </dependency>
+
+    <!-- Unit test -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <resources>
+      <resource>
+        <directory>src/main/filtered-resources</directory>
+        <filtering>true</filtering>
+        <includes>
+          <include>*.config</include>
+          <include>**/*.properties</include>
+        </includes>
+      </resource>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>false</filtering>
+      </resource>
+    </resources>
+
+    <plugins>
+      <plugin>
+        <groupId>org.nuiton.i18n</groupId>
+        <artifactId>i18n-maven-plugin</artifactId>
+
+        <executions>
+          <execution>
+            <id>scan-sources</id>
+            <configuration>
+              <entries>
+                <entry>
+                  <specificGoal>parserValidation</specificGoal>
+                  <basedir>${maven.src.dir}/main/java/</basedir>
+                  <includes>
+                    <param>**/**-validation.xml</param>
+                  </includes>
+                </entry>
+              </entries>
+            </configuration>
+            <goals>
+              <goal>parserJava</goal>
+              <goal>parserValidation</goal>
+              <goal>gen</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>make-bundle</id>
+            <goals>
+              <goal>bundle</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>assembly-plugin</id>
+            <phase>package</phase>
+            <goals>
+              <goal>single</goal>
+            </goals>
+            <configuration>
+              <attach>true</attach>
+              <appendAssemblyId>false</appendAssemblyId>
+              <finalName>${project.artifactId}-${project.version}</finalName>
+              <descriptors>
+                <descriptor>
+                  ${basedir}/src/main/assembly/plugin.xml
+                </descriptor>
+              </descriptors>
+              <skipAssembly>${assembly.skip}</skipAssembly>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/duniter4j-es-gchange/src/license/THIRD-PARTY.properties b/duniter4j-es-gchange/src/license/THIRD-PARTY.properties
new file mode 100644
index 0000000000000000000000000000000000000000..8610ec5bda0d6673a7c224b7fd16226cc1bcd664
--- /dev/null
+++ b/duniter4j-es-gchange/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-gchange/src/main/assembly/plugin.xml b/duniter4j-es-gchange/src/main/assembly/plugin.xml
new file mode 100644
index 0000000000000000000000000000000000000000..004bbfa77a7e12db6bae7fc242ffbaec788f73d0
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/assembly/plugin.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<assembly>
+    <id>plugin</id>
+
+
+    <formats>
+        <format>zip</format>
+    </formats>
+
+    <includeBaseDirectory>false</includeBaseDirectory>
+
+    <dependencySets>
+        <dependencySet>
+            <outputDirectory>/</outputDirectory>
+            <useProjectArtifact>true</useProjectArtifact>
+            <useTransitiveFiltering>true</useTransitiveFiltering>
+            <excludes>
+                <exclude>org.duniter:duniter4j-es-core</exclude>
+                <exclude>org.duniter:duniter4j-es-user</exclude>
+                <exclude>org.elasticsearch:elasticsearch</exclude>
+                <exclude>net.java.dev.jna:jna</exclude>
+                <exclude>com.fasterxml.jackson.core:jackson-core</exclude>
+                <exclude>log4j:log4j</exclude>
+            </excludes>
+        </dependencySet>
+    </dependencySets>
+
+    <fileSets>
+        <fileSet>
+            <includes>
+                <include>LICENSE</include>
+            </includes>
+        </fileSet>
+
+        <fileSet>
+            <directory>target/classes</directory>
+            <outputDirectory/>
+            <includes>
+                <include>plugin-descriptor.properties</include>
+                <include>plugin-security.policy</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+</assembly>
\ No newline at end of file
diff --git a/duniter4j-es-gchange/src/main/filtered-resources/log4j.properties b/duniter4j-es-gchange/src/main/filtered-resources/log4j.properties
new file mode 100644
index 0000000000000000000000000000000000000000..7b6667b1facc361ed8b1993869f728e2c01f1799
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/filtered-resources/log4j.properties
@@ -0,0 +1,32 @@
+
+# Global logging configuration
+log4j.rootLogger=ERROR, stdout, file
+#log4j.rootLogger=ERROR, stdout
+
+# Console output
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %5p %m%n
+
+# Duniter4j levels
+log4j.logger.org.duniter=INFO
+#log4j.logger.org.duniter.core.client=DEBUG
+#log4j.logger.org.duniter.core.client.service=DEBUG
+log4j.logger.org.duniter.elasticsearch=DEBUG
+
+# Other frameworks levels
+log4j.logger.org.nuiton.util=WARN
+log4j.logger.org.nuiton.config=WARN
+log4j.logger.org.nuiton.converter=WARN
+log4j.logger.org.nuiton.i18n=ERROR
+log4j.logger.org.elasticsearch=WARN
+#log4j.logger.org.elasticsearch=INFO
+
+log4j.appender.file=org.apache.log4j.RollingFileAppender
+log4j.appender.file.file=${duniter4j.log.file}
+log4j.appender.file.MaxFileSize=10MB
+log4j.appender.file.MaxBackupIndex=4
+
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d{ISO8601} %5p (%c:%L) - [%t] %m%n
+
diff --git a/duniter4j-es-gchange/src/main/filtered-resources/plugin-descriptor.properties b/duniter4j-es-gchange/src/main/filtered-resources/plugin-descriptor.properties
new file mode 100644
index 0000000000000000000000000000000000000000..821d0eeb415c988ceea9887fa59d442ae9f65dd8
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/filtered-resources/plugin-descriptor.properties
@@ -0,0 +1,9 @@
+name=gchange
+description=Plugin for Gchange API
+version=${project.version}
+site=false
+jvm=true
+classname=org.duniter.elasticsearch.gchange.Plugin
+java.version=1.7
+elasticsearch.version=2.3.3
+isolated=true
diff --git a/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/Plugin.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/Plugin.java
new file mode 100644
index 0000000000000000000000000000000000000000..c7b1067c7cdd35bfa0b8174cdde750ad5cdcd59a
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/Plugin.java
@@ -0,0 +1,84 @@
+package org.duniter.elasticsearch.gchange;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import com.google.common.collect.Lists;
+import org.duniter.elasticsearch.gchange.rest.RestModule;
+import org.duniter.elasticsearch.gchange.service.ServiceModule;
+import org.elasticsearch.common.component.LifecycleComponent;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.inject.Module;
+import org.elasticsearch.common.logging.ESLogger;
+import org.elasticsearch.common.logging.ESLoggerFactory;
+import org.elasticsearch.common.settings.Settings;
+
+import java.util.Collection;
+
+public class Plugin extends org.elasticsearch.plugins.Plugin {
+
+    private ESLogger log = ESLoggerFactory.getLogger(Plugin.class.getName());
+
+    private boolean enable;
+
+    @Inject public Plugin(Settings settings) {
+        this.enable = settings.getAsBoolean("gchange.enabled", true);
+    }
+
+    @Override
+    public String name() {
+        return "gchange";
+    }
+
+    @Override
+    public String description() {
+        return "ElasticSearch Gchange Plugin";
+    }
+
+    @Override
+    public Collection<Module> nodeModules() {
+        Collection<Module> modules = Lists.newArrayList();
+        if (!enable) {
+            log.warn(description() + " has been disabled.");
+            return modules;
+        }
+        modules.add(new RestModule());
+        modules.add(new ServiceModule());
+
+        return modules;
+    }
+
+    @Override
+    public Collection<Class<? extends LifecycleComponent>> nodeServices() {
+        Collection<Class<? extends LifecycleComponent>> components = Lists.newArrayList();
+        if (!enable) {
+            return components;
+        }
+        components.add(PluginSettings.class);
+        components.add(PluginInit.class);
+        return components;
+    }
+
+    /* -- protected methods -- */
+
+
+}
\ No newline at end of file
diff --git a/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/PluginInit.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/PluginInit.java
new file mode 100644
index 0000000000000000000000000000000000000000..020dda5d578cba7119d169fc0c43c2e039dcf3d2
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/PluginInit.java
@@ -0,0 +1,134 @@
+package org.duniter.elasticsearch.gchange;
+
+/*
+ * #%L
+ * Duniter4j :: ElasticSearch Plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.gchange.service.MarketService;
+import org.duniter.elasticsearch.gchange.service.RegistryService;
+import org.duniter.elasticsearch.gchange.service.SynchroService;
+import org.duniter.elasticsearch.threadpool.ThreadPool;
+import org.duniter.elasticsearch.user.service.event.UserEvent;
+import org.duniter.elasticsearch.user.service.event.UserEventCodes;
+import org.duniter.elasticsearch.user.service.event.UserEventService;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.cluster.health.ClusterHealthStatus;
+import org.elasticsearch.common.component.AbstractLifecycleComponent;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.inject.Injector;
+import org.elasticsearch.common.logging.ESLogger;
+import org.elasticsearch.common.logging.Loggers;
+import org.elasticsearch.common.settings.Settings;
+
+/**
+ * Created by blavenie on 17/06/16.
+ */
+public class PluginInit extends AbstractLifecycleComponent<PluginInit> {
+
+    private final PluginSettings pluginSettings;
+    private final ThreadPool threadPool;
+    private final Injector injector;
+    private final static ESLogger logger = Loggers.getLogger("gchange");
+    private final Client client;
+    private final String clusterName;
+
+    @Inject
+    public PluginInit(Client client, Settings settings, PluginSettings pluginSettings, ThreadPool threadPool, final Injector injector) {
+        super(settings);
+        this.pluginSettings = pluginSettings;
+        this.threadPool = threadPool;
+        this.injector = injector;
+        this.client = client;
+        this.clusterName = settings.get("cluster.name");
+    }
+
+    @Override
+    protected void doStart() {
+        threadPool.scheduleOnClusterHealthStatus(() -> {
+            createIndices();
+
+            // Waiting cluster back to GREEN or YELLOW state, before synchronize
+            threadPool.scheduleOnClusterHealthStatus(() -> {
+                synchronize();
+            }, ClusterHealthStatus.YELLOW, ClusterHealthStatus.GREEN);
+        }, ClusterHealthStatus.YELLOW, ClusterHealthStatus.GREEN);
+
+        // When started
+        threadPool.scheduleOnStarted(() -> {
+            // Notify admin
+            injector.getInstance(UserEventService.class)
+                    .notifyAdmin(new UserEvent(
+                            UserEvent.EventType.INFO,
+                            UserEventCodes.NODE_STARTED.name(),
+                            new String[]{clusterName}));
+        });
+    }
+
+    @Override
+    protected void doStop() {
+
+    }
+
+    @Override
+    protected void doClose() {
+
+    }
+
+    protected void createIndices() {
+
+        boolean reloadIndices = pluginSettings.reloadIndices();
+
+        if (reloadIndices) {
+            if (logger.isInfoEnabled()) {
+                logger.info("Reloading all Gchange indices...");
+            }
+            injector.getInstance(RegistryService.class)
+                    .deleteIndex()
+                    .createIndexIfNotExists();
+            injector.getInstance(MarketService.class)
+                    .deleteIndex()
+                    .createIndexIfNotExists();
+
+            if (logger.isInfoEnabled()) {
+                logger.info("Reloading all Gchange indices... [OK]");
+            }
+        }
+        else {
+            if (logger.isInfoEnabled()) {
+                logger.info("Checking Gchange indices...");
+            }
+            injector.getInstance(RegistryService.class).createIndexIfNotExists();
+            injector.getInstance(MarketService.class).createIndexIfNotExists();
+
+            if (logger.isInfoEnabled()) {
+                logger.info("Checking Gchange indices... [OK]");
+            }
+        }
+    }
+
+    protected void synchronize() {
+
+        if (pluginSettings.enableDataSync()) {
+            // Synchronize
+            injector.getInstance(SynchroService.class).synchronize();
+        }
+    }
+}
diff --git a/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/PluginSettings.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/PluginSettings.java
new file mode 100644
index 0000000000000000000000000000000000000000..48498ce03af983fb6b016fc05c1e43cfbf9c8b5a
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/PluginSettings.java
@@ -0,0 +1,67 @@
+package org.duniter.elasticsearch.gchange;
+
+/*
+ * #%L
+ * UCoin Java Client :: Core API
+ * %%
+ * Copyright (C) 2014 - 2015 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.commons.io.FileUtils;
+import org.duniter.core.client.config.Configuration;
+import org.duniter.core.client.config.ConfigurationOption;
+import org.duniter.core.client.config.ConfigurationProvider;
+import org.duniter.core.client.model.local.Peer;
+import org.duniter.core.exception.TechnicalException;
+import org.duniter.core.util.StringUtils;
+import org.elasticsearch.common.component.*;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.settings.Settings;
+import org.nuiton.config.ApplicationConfig;
+import org.nuiton.config.ApplicationConfigHelper;
+import org.nuiton.config.ApplicationConfigProvider;
+import org.nuiton.config.ArgumentsParserException;
+import org.nuiton.i18n.I18n;
+import org.nuiton.i18n.init.DefaultI18nInitializer;
+import org.nuiton.i18n.init.UserI18nInitializer;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Locale;
+import java.util.Set;
+
+import static org.nuiton.i18n.I18n.t;
+
+/**
+ * Access to configuration options
+ * @author Benoit Lavenier <benoit.lavenier@e-is.pro>
+ * @since 1.0
+ */
+public class PluginSettings extends org.duniter.elasticsearch.user.PluginSettings {
+
+    @Inject
+    public PluginSettings(org.elasticsearch.common.settings.Settings settings) {
+        super(settings);
+    }
+
+    protected String getI18nBundleName() {
+        return "duniter4j-es-gchange-i18n";
+    }
+}
diff --git a/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/RestModule.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/RestModule.java
new file mode 100644
index 0000000000000000000000000000000000000000..4f45cec511d95315fb6fb73a46d6c38e8679418f
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/RestModule.java
@@ -0,0 +1,48 @@
+package org.duniter.elasticsearch.gchange.rest;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.gchange.rest.market.*;
+import org.duniter.elasticsearch.gchange.rest.registry.*;
+import org.elasticsearch.common.inject.AbstractModule;
+import org.elasticsearch.common.inject.Module;
+
+public class RestModule extends AbstractModule implements Module {
+
+    @Override protected void configure() {
+
+        // Market
+        bind(RestMarketRecordIndexAction.class).asEagerSingleton();
+        bind(RestMarketRecordUpdateAction.class).asEagerSingleton();
+        bind(RestMarketCommentIndexAction.class).asEagerSingleton();
+        bind(RestMarketCommentUpdateAction.class).asEagerSingleton();
+        bind(RestMarketCategoryAction.class).asEagerSingleton();
+
+        // Registry
+        bind(RestRegistryRecordIndexAction.class).asEagerSingleton();
+        bind(RestRegistryRecordUpdateAction.class).asEagerSingleton();
+        bind(RestRegistryCommentIndexAction.class).asEagerSingleton();
+        bind(RestregistryCommentUpdateAction.class).asEagerSingleton();
+        bind(RestRegistryCategoryAction.class).asEagerSingleton();
+    }
+}
\ No newline at end of file
diff --git a/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/market/RestMarketCategoryAction.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/market/RestMarketCategoryAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..7aa19360824d38cc8b56850dcbe924169f8d2c36
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/market/RestMarketCategoryAction.java
@@ -0,0 +1,38 @@
+package org.duniter.elasticsearch.gchange.rest.market;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.gchange.service.MarketService;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.rest.RestRequest;
+
+public class RestMarketCategoryAction {
+
+    @Inject
+    public RestMarketCategoryAction(RestSecurityController securityController) {
+        // Add security rule for category
+        securityController.allowIndexType(RestRequest.Method.GET, MarketService.INDEX, MarketService.RECORD_CATEGORY_TYPE);
+    }
+
+}
\ No newline at end of file
diff --git a/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/market/RestMarketCommentIndexAction.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/market/RestMarketCommentIndexAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..a65f154c946d241c15f93a7416d69fc1311cd3ae
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/market/RestMarketCommentIndexAction.java
@@ -0,0 +1,43 @@
+package org.duniter.elasticsearch.gchange.rest.market;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.rest.AbstractRestPostIndexAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.gchange.service.MarketService;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.rest.RestController;
+
+public class RestMarketCommentIndexAction extends AbstractRestPostIndexAction {
+
+    @Inject
+    public RestMarketCommentIndexAction(Settings settings, RestController controller, Client client, RestSecurityController securityController,
+                                        MarketService service) {
+        super(settings, controller, client, securityController,
+                MarketService.INDEX, MarketService.RECORD_COMMENT_TYPE,
+                json -> service.indexCommentFromJson(json));
+    }
+
+}
\ No newline at end of file
diff --git a/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/market/RestMarketCommentUpdateAction.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/market/RestMarketCommentUpdateAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..c10f58c8df3723f053620ddefd2a5b06dff3f559
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/market/RestMarketCommentUpdateAction.java
@@ -0,0 +1,43 @@
+package org.duniter.elasticsearch.gchange.rest.market;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.rest.AbstractRestPostUpdateAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.gchange.service.MarketService;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.rest.RestController;
+
+public class RestMarketCommentUpdateAction extends AbstractRestPostUpdateAction {
+
+    @Inject
+    public RestMarketCommentUpdateAction(Settings settings, RestController controller, Client client, RestSecurityController securityController,
+                                         MarketService service) {
+        super(settings, controller, client, securityController,
+                MarketService.INDEX, MarketService.RECORD_COMMENT_TYPE,
+                (json, id) -> service.updateCommentFromJson(json, id));
+    }
+
+}
\ No newline at end of file
diff --git a/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/market/RestMarketRecordIndexAction.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/market/RestMarketRecordIndexAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..55f4c5fbf4b093e9442a14621f734656cc9f4fe2
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/market/RestMarketRecordIndexAction.java
@@ -0,0 +1,43 @@
+package org.duniter.elasticsearch.gchange.rest.market;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.rest.AbstractRestPostIndexAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.gchange.service.MarketService;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.rest.RestController;
+
+public class RestMarketRecordIndexAction extends AbstractRestPostIndexAction {
+
+    @Inject
+    public RestMarketRecordIndexAction(Settings settings, RestController controller, Client client, RestSecurityController securityController,
+                                       MarketService service) {
+        super(settings, controller, client, securityController,
+                MarketService.INDEX, MarketService.RECORD_TYPE,
+                json -> service.indexRecordFromJson(json));
+    }
+
+}
\ No newline at end of file
diff --git a/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/market/RestMarketRecordUpdateAction.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/market/RestMarketRecordUpdateAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..9761924f2ffdcfdfb21a5c65907e9a8f3af8dda4
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/market/RestMarketRecordUpdateAction.java
@@ -0,0 +1,43 @@
+package org.duniter.elasticsearch.gchange.rest.market;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.rest.AbstractRestPostUpdateAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.gchange.service.MarketService;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.rest.RestController;
+
+public class RestMarketRecordUpdateAction extends AbstractRestPostUpdateAction {
+
+    @Inject
+    public RestMarketRecordUpdateAction(Settings settings, RestController controller, Client client, RestSecurityController securityController,
+                                        MarketService service) {
+        super(settings, controller, client, securityController,
+                MarketService.INDEX, MarketService.RECORD_TYPE,
+                (json, id) -> service.updateRecordFromJson(json, id));
+    }
+
+}
\ No newline at end of file
diff --git a/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/registry/RestRegistryCategoryAction.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/registry/RestRegistryCategoryAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..0fdb34fa17095d187e74a24269d5c3e30f36ec7c
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/registry/RestRegistryCategoryAction.java
@@ -0,0 +1,38 @@
+package org.duniter.elasticsearch.gchange.rest.registry;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.gchange.service.RegistryService;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.rest.RestRequest;
+
+public class RestRegistryCategoryAction {
+
+    @Inject
+    public RestRegistryCategoryAction(RestSecurityController securityController) {
+        // Add security rule for category
+        securityController.allowIndexType(RestRequest.Method.GET, RegistryService.INDEX, RegistryService.RECORD_CATEGORY_TYPE);
+    }
+
+}
\ No newline at end of file
diff --git a/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/registry/RestRegistryCommentIndexAction.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/registry/RestRegistryCommentIndexAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..bd0047608733aca88299aa1b8a577db679aefb01
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/registry/RestRegistryCommentIndexAction.java
@@ -0,0 +1,43 @@
+package org.duniter.elasticsearch.gchange.rest.registry;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.rest.AbstractRestPostIndexAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.gchange.service.RegistryService;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.rest.RestController;
+
+public class RestRegistryCommentIndexAction extends AbstractRestPostIndexAction {
+
+    @Inject
+    public RestRegistryCommentIndexAction(Settings settings, RestController controller, Client client, RestSecurityController securityController,
+                                          RegistryService service) {
+        super(settings, controller, client, securityController,
+                RegistryService.INDEX, RegistryService.RECORD_COMMENT_TYPE,
+                json -> service.indexCommentFromJson(json));
+    }
+
+}
\ No newline at end of file
diff --git a/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/registry/RestRegistryRecordIndexAction.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/registry/RestRegistryRecordIndexAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..02c2e963b271e0ef09d21e116498284a417044dd
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/registry/RestRegistryRecordIndexAction.java
@@ -0,0 +1,43 @@
+package org.duniter.elasticsearch.gchange.rest.registry;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.rest.AbstractRestPostIndexAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.gchange.service.RegistryService;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.rest.RestController;
+
+public class RestRegistryRecordIndexAction extends AbstractRestPostIndexAction {
+
+
+    @Inject
+    public RestRegistryRecordIndexAction(Settings settings, RestController controller, Client client, RestSecurityController securityController,
+                                         RegistryService service) {
+        super(settings, controller, client, securityController,
+                RegistryService.INDEX, RegistryService.RECORD_TYPE,
+                json -> service.indexRecordFromJson(json));
+    }
+}
\ No newline at end of file
diff --git a/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/registry/RestRegistryRecordUpdateAction.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/registry/RestRegistryRecordUpdateAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..e77b942513e52bd991d5639face16fd2f1c8a2db
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/registry/RestRegistryRecordUpdateAction.java
@@ -0,0 +1,43 @@
+package org.duniter.elasticsearch.gchange.rest.registry;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.rest.AbstractRestPostUpdateAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.gchange.service.RegistryService;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.rest.RestController;
+
+public class RestRegistryRecordUpdateAction extends AbstractRestPostUpdateAction {
+
+    @Inject
+    public RestRegistryRecordUpdateAction(Settings settings, RestController controller, Client client, RestSecurityController securityController,
+                                          RegistryService service) {
+        super(settings, controller, client, securityController,
+                RegistryService.INDEX, RegistryService.RECORD_TYPE,
+                (json, id) -> service.updateRecordFromJson(json, id));
+    }
+
+}
\ No newline at end of file
diff --git a/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/registry/RestregistryCommentUpdateAction.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/registry/RestregistryCommentUpdateAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..8687f463f298d5ee82b5d0da016874931c43d701
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/rest/registry/RestregistryCommentUpdateAction.java
@@ -0,0 +1,43 @@
+package org.duniter.elasticsearch.gchange.rest.registry;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.rest.AbstractRestPostUpdateAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.gchange.service.RegistryService;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.rest.RestController;
+
+public class RestregistryCommentUpdateAction extends AbstractRestPostUpdateAction {
+
+    @Inject
+    public RestregistryCommentUpdateAction(Settings settings, RestController controller, Client client, RestSecurityController securityController,
+                                           RegistryService service) {
+        super(settings, controller, client, securityController,
+                RegistryService.INDEX, RegistryService.RECORD_COMMENT_TYPE,
+                (json, id) -> service.updateCommentFromJson(json, id));
+    }
+
+}
\ No newline at end of file
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/registry/CitiesRegistryService.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/service/CitiesRegistryService.java
similarity index 99%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/registry/CitiesRegistryService.java
rename to duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/service/CitiesRegistryService.java
index 891791a829f951384016238925e07c2d31f78cea..e6f72a729581b50ab31594d50f03833f436b1881 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/registry/CitiesRegistryService.java
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/service/CitiesRegistryService.java
@@ -1,4 +1,4 @@
-package org.duniter.elasticsearch.service.registry;
+package org.duniter.elasticsearch.gchange.service;
 
 /*
  * #%L
@@ -26,13 +26,13 @@ package org.duniter.elasticsearch.service.registry;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
 import org.duniter.core.client.model.bma.gson.GsonUtils;
 import org.duniter.core.exception.TechnicalException;
 import org.duniter.core.util.StringUtils;
-import org.duniter.elasticsearch.PluginSettings;
+import org.duniter.elasticsearch.gchange.PluginSettings;
 import org.duniter.elasticsearch.service.AbstractService;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
 import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.inject.Inject;
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/MarketService.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/service/MarketService.java
similarity index 98%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/MarketService.java
rename to duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/service/MarketService.java
index 7b1a5a11daa82fd593d6ac8a8f4cdb1870c5893b..b037fc075ec2a417c81630e310624cb2f0e7915a 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/MarketService.java
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/service/MarketService.java
@@ -1,4 +1,4 @@
-package org.duniter.elasticsearch.service;
+package org.duniter.elasticsearch.gchange.service;
 
 /*
  * #%L
@@ -27,7 +27,8 @@ import com.fasterxml.jackson.core.JsonProcessingException;
 import org.duniter.core.client.service.bma.WotRemoteService;
 import org.duniter.core.exception.TechnicalException;
 import org.duniter.core.service.CryptoService;
-import org.duniter.elasticsearch.PluginSettings;
+import org.duniter.elasticsearch.gchange.PluginSettings;
+import org.duniter.elasticsearch.service.AbstractService;
 import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
 import org.elasticsearch.action.index.IndexRequestBuilder;
 import org.elasticsearch.action.index.IndexResponse;
diff --git a/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/service/RegistryService.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/service/RegistryService.java
new file mode 100644
index 0000000000000000000000000000000000000000..3542cd47c0b9b2dc7f7357098e6359ed7ae3f122
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/service/RegistryService.java
@@ -0,0 +1,357 @@
+package org.duniter.elasticsearch.gchange.service;
+
+/*
+ * #%L
+ * UCoin Java Client :: Core API
+ * %%
+ * Copyright (C) 2014 - 2015 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.google.gson.Gson;
+import org.duniter.core.client.model.bma.gson.GsonUtils;
+import org.duniter.core.client.service.bma.BlockchainRemoteService;
+import org.duniter.core.exception.TechnicalException;
+import org.duniter.core.service.CryptoService;
+import org.duniter.elasticsearch.gchange.PluginSettings;
+import org.duniter.elasticsearch.service.AbstractService;
+import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
+import org.elasticsearch.action.index.IndexRequestBuilder;
+import org.elasticsearch.action.index.IndexResponse;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentFactory;
+
+import java.io.IOException;
+
+/**
+ * Created by Benoit on 30/03/2015.
+ */
+public class RegistryService extends AbstractService {
+
+    public static final String INDEX = "registry";
+    public static final String RECORD_TYPE = "record";
+    public static final String RECORD_CATEGORY_TYPE = "category";
+    public static final String RECORD_COMMENT_TYPE = "comment";
+    private static final String CATEGORIES_BULK_CLASSPATH_FILE = "registry-categories-bulk-insert.json";
+
+    private final Gson gson;
+    private BlockchainRemoteService blockchainRemoteService;
+
+    @Inject
+    public RegistryService(Client client,
+                           PluginSettings settings,
+                           CryptoService cryptoService,
+                           BlockchainRemoteService blockchainRemoteService) {
+        super("gchange." + INDEX, client, settings, cryptoService);
+        this.gson = GsonUtils.newBuilder().create();
+        this.blockchainRemoteService = blockchainRemoteService;
+    }
+
+    /**
+     * Create index need for blockchain registry, if need
+     */
+    public RegistryService createIndexIfNotExists() {
+        try {
+            if (!existsIndex(INDEX)) {
+                createIndex();
+
+                fillRecordCategories();
+            }
+        }
+        catch(JsonProcessingException e) {
+            throw new TechnicalException(String.format("Error while creating index [%s]", INDEX));
+        }
+        return this;
+    }
+
+    /**
+     * Create index for registry
+     * @throws JsonProcessingException
+     */
+    public RegistryService createIndex() throws JsonProcessingException {
+        logger.info(String.format("Creating index [%s]", INDEX));
+
+        CreateIndexRequestBuilder createIndexRequestBuilder = client.admin().indices().prepareCreate(INDEX);
+        org.elasticsearch.common.settings.Settings indexSettings = org.elasticsearch.common.settings.Settings.settingsBuilder()
+                .put("number_of_shards", 3)
+                .put("number_of_replicas", 1)
+                //.put("analyzer", createDefaultAnalyzer())
+                .build();
+        createIndexRequestBuilder.setSettings(indexSettings);
+        createIndexRequestBuilder.addMapping(RECORD_CATEGORY_TYPE, createRecordCategoryType());
+        createIndexRequestBuilder.addMapping(RECORD_TYPE, createRecordType());
+        createIndexRequestBuilder.addMapping(RECORD_COMMENT_TYPE, createRecordCommentType(INDEX, RECORD_COMMENT_TYPE));
+        createIndexRequestBuilder.execute().actionGet();
+
+        return this;
+    }
+
+    public RegistryService deleteIndex() {
+        deleteIndexIfExists(INDEX);
+        return this;
+    }
+
+    public boolean existsIndex() {
+        return super.existsIndex(INDEX);
+    }
+
+    public RegistryService fillRecordCategories() {
+        if (logger.isDebugEnabled()) {
+            logger.debug(String.format("[%s/%s] Fill data", INDEX, RECORD_CATEGORY_TYPE));
+        }
+
+        // Insert categories
+        bulkFromClasspathFile(CATEGORIES_BULK_CLASSPATH_FILE, INDEX, RECORD_CATEGORY_TYPE,
+                // Add order attribute
+                new AddSequenceAttributeHandler("order", "\\{.*\"name\".*\\}", 1));
+
+        return this;
+    }
+
+    public String indexRecordFromJson(String json) {
+        return checkIssuerAndIndexDocumentFromJson(INDEX, RECORD_TYPE, json);
+    }
+
+    public void updateRecordFromJson(String json, String id) {
+        checkIssuerAndUpdateDocumentFromJson(INDEX, RECORD_TYPE, json, id);
+    }
+
+    public String indexCommentFromJson(String json) {
+        return checkIssuerAndIndexDocumentFromJson(INDEX, RECORD_COMMENT_TYPE, json);
+    }
+
+    public void updateCommentFromJson(String json, String id) {
+        checkIssuerAndUpdateDocumentFromJson(INDEX, RECORD_COMMENT_TYPE, json, id);
+    }
+
+    /* -- Internal methods -- */
+
+    public XContentBuilder createRecordType() {
+        String stringAnalyzer = pluginSettings.getDefaultStringAnalyzer();
+
+        try {
+            XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject(RECORD_TYPE)
+                    .startObject("properties")
+
+                    // title
+                    .startObject("title")
+                    .field("type", "string")
+                    .field("analyzer", stringAnalyzer)
+                    .endObject()
+
+                    // description
+                    .startObject("description")
+                    .field("type", "string")
+                    .field("analyzer", stringAnalyzer)
+                    .endObject()
+
+                    // creationTime
+                    .startObject("creationTime")
+                    .field("type", "integer")
+                    .endObject()
+
+                    // time
+                    .startObject("time")
+                    .field("type", "integer")
+                    .endObject()
+
+                    // issuer
+                    .startObject("issuer")
+                    .field("type", "string")
+                    .field("index", "not_analyzed")
+                    .endObject()
+
+                    // pubkey
+                    .startObject("pubkey")
+                    .field("type", "string")
+                    .field("index", "not_analyzed")
+                    .endObject()
+
+                    // address
+                    .startObject("address")
+                    .field("type", "string")
+                    .field("analyzer", stringAnalyzer)
+                    .endObject()
+
+                    // city
+                    .startObject("city")
+                    .field("type", "string")
+                    .endObject()
+
+                    // geoPoint
+                    .startObject("geoPoint")
+                    .field("type", "geo_point")
+                    .endObject()
+
+                    // thumbnail
+                    .startObject("thumbnail")
+                    .field("type", "attachment")
+                    .startObject("fields") // src
+                    .startObject("content") // title
+                    .field("index", "no")
+                    .endObject()
+                    .startObject("title") // title
+                    .field("type", "string")
+                    .field("store", "no")
+                    .endObject()
+                    .startObject("author") // title
+                    .field("store", "no")
+                    .endObject()
+                    .startObject("content_type") // title
+                    .field("store", "yes")
+                    .endObject()
+                    .endObject()
+                    .endObject()
+
+                    // pictures
+                    .startObject("pictures")
+                    .field("type", "nested")
+                    .field("dynamic", "false")
+                    .startObject("properties")
+                    .startObject("file") // file
+                    .field("type", "attachment")
+                    .startObject("fields")
+                    .startObject("content") // content
+                    .field("index", "no")
+                    .endObject()
+                    .startObject("title") // title
+                    .field("type", "string")
+                    .field("store", "yes")
+                    .field("analyzer", stringAnalyzer)
+                    .endObject()
+                    .startObject("author") // author
+                    .field("type", "string")
+                    .field("store", "no")
+                    .endObject()
+                    .startObject("content_type") // content_type
+                    .field("store", "yes")
+                    .endObject()
+                    .endObject()
+                    .endObject()
+                    .endObject()
+                    .endObject()
+
+                    // picturesCount
+                    .startObject("picturesCount")
+                    .field("type", "integer")
+                    .endObject()
+
+                    // category
+                    .startObject("category")
+                    .field("type", "nested")
+                    .field("dynamic", "false")
+                    .startObject("properties")
+                    .startObject("id") // id
+                    .field("type", "string")
+                    .field("index", "not_analyzed")
+                    .endObject()
+                    .startObject("parent") // parent
+                    .field("type", "string")
+                    .field("index", "not_analyzed")
+                    .endObject()
+                    .startObject("name") // name
+                    .field("type", "string")
+                    .field("analyzer", stringAnalyzer)
+                    .endObject()
+                    .endObject()
+                    .endObject()
+
+                    // tags
+                    .startObject("tags")
+                    .field("type", "completion")
+                    .field("search_analyzer", "simple")
+                    .field("analyzer", "simple")
+                    .field("preserve_separators", "false")
+                    .endObject()
+
+                    .endObject()
+                    .endObject().endObject();
+
+            return mapping;
+        }
+        catch(IOException ioe) {
+            throw new TechnicalException(String.format("Error while getting mapping for index [%s/%s]: %s", INDEX, RECORD_TYPE, ioe.getMessage()), ioe);
+        }
+    }
+
+    public XContentBuilder createRecordCategoryType() {
+        try {
+            XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject(RECORD_CATEGORY_TYPE)
+                    .startObject("properties")
+
+                    // name
+                    .startObject("name")
+                    .field("type", "string")
+                    .field("analyzer", pluginSettings.getDefaultStringAnalyzer())
+                    .endObject()
+
+                    // description
+                    /*.startObject("description")
+                    .field("type", "string")
+                    .endObject()*/
+
+                    // parent
+                    .startObject("parent")
+                    .field("type", "string")
+                    .field("index", "not_analyzed")
+                    .endObject()
+
+                    // tags
+                    /*.startObject("tags")
+                    .field("type", "completion")
+                    .field("search_analyzer", "simple")
+                    .field("analyzer", "simple")
+                    .field("preserve_separators", "false")
+                    .endObject()*/
+
+                    .endObject()
+                    .endObject().endObject();
+
+            return mapping;
+        }
+        catch(IOException ioe) {
+            throw new TechnicalException(String.format("Error while getting mapping for index [%s/%s]: %s", INDEX, RECORD_CATEGORY_TYPE, ioe.getMessage()), ioe);
+        }
+    }
+
+    /**
+     *
+     * @param jsonCategory
+     * @return the product id
+     */
+    public String indexCategoryFromJson(String jsonCategory) {
+        if (logger.isDebugEnabled()) {
+            logger.debug("Indexing a category");
+        }
+
+        // Preparing indexBlocksFromNode
+        IndexRequestBuilder indexRequest = client.prepareIndex(INDEX, RECORD_CATEGORY_TYPE)
+                .setSource(jsonCategory);
+
+        // Execute indexBlocksFromNode
+        IndexResponse response = indexRequest
+                .setRefresh(false)
+                .execute().actionGet();
+
+        return response.getId();
+    }
+
+}
diff --git a/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/service/ServiceModule.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/service/ServiceModule.java
new file mode 100644
index 0000000000000000000000000000000000000000..282c53beb704d4ccc8ea8a99ae5e760b79035785
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/service/ServiceModule.java
@@ -0,0 +1,36 @@
+package org.duniter.elasticsearch.gchange.service;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.elasticsearch.common.inject.AbstractModule;
+import org.elasticsearch.common.inject.Module;
+
+public class ServiceModule extends AbstractModule implements Module {
+
+    @Override protected void configure() {
+        bind(RegistryService.class).asEagerSingleton();
+        bind(CitiesRegistryService.class).asEagerSingleton();
+        bind(MarketService.class).asEagerSingleton();
+        bind(SynchroService.class).asEagerSingleton();
+    }
+}
\ No newline at end of file
diff --git a/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/service/SynchroService.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/service/SynchroService.java
new file mode 100644
index 0000000000000000000000000000000000000000..c91568582a394cb915dfbc28738deaf77ed84f6d
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/service/SynchroService.java
@@ -0,0 +1,74 @@
+package org.duniter.elasticsearch.gchange.service;
+
+/*
+ * #%L
+ * Duniter4j :: ElasticSearch Plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.core.client.model.local.Peer;
+import org.duniter.core.service.CryptoService;
+import org.duniter.elasticsearch.gchange.PluginSettings;
+import org.duniter.elasticsearch.service.AbstractSynchroService;
+import org.duniter.elasticsearch.service.ServiceLocator;
+import org.duniter.elasticsearch.threadpool.ThreadPool;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.inject.Inject;
+
+/**
+ * Created by blavenie on 27/10/16.
+ */
+public class SynchroService extends AbstractSynchroService {
+
+    @Inject
+    public SynchroService(Client client, PluginSettings settings, CryptoService cryptoService,
+                          ThreadPool threadPool, final ServiceLocator serviceLocator) {
+        super(client, settings, cryptoService, threadPool, serviceLocator);
+    }
+
+    public void synchronize() {
+        logger.info("Synchronizing data...");
+        Peer peer = getPeerFromAPI("GCHANGE API");
+        synchronize(peer);
+    }
+
+    /* -- protected methods -- */
+
+    protected void synchronize(Peer peer) {
+
+        long sinceTime = 0; // TODO: get last sync time from somewhere ? (e.g. a specific index)
+
+        logger.info(String.format("[%s] Synchronizing gchange data since %s...", peer.toString(), sinceTime));
+
+        importMarketChanges(peer, sinceTime);
+        importRegistryChanges(peer, sinceTime);
+
+        logger.info(String.format("[%s] Synchronizing gchange data since %s [OK]", peer.toString(), sinceTime));
+    }
+
+    protected void importMarketChanges(Peer peer, long sinceTime) {
+        importChanges(peer, MarketService.INDEX, MarketService.RECORD_TYPE,  sinceTime);
+        importChanges(peer, MarketService.INDEX, MarketService.RECORD_COMMENT_TYPE,  sinceTime);
+    }
+
+    protected void importRegistryChanges(Peer peer, long sinceTime) {
+        importChanges(peer, RegistryService.INDEX, RegistryService.RECORD_TYPE,  sinceTime);
+        importChanges(peer, RegistryService.INDEX, RegistryService.RECORD_COMMENT_TYPE,  sinceTime);
+    }
+}
diff --git a/duniter4j-elasticsearch/src/main/misc/cities-fr.geoJson.txt b/duniter4j-es-gchange/src/main/misc/cities-fr.geoJson.txt
similarity index 100%
rename from duniter4j-elasticsearch/src/main/misc/cities-fr.geoJson.txt
rename to duniter4j-es-gchange/src/main/misc/cities-fr.geoJson.txt
diff --git a/duniter4j-elasticsearch/src/main/misc/index.sh b/duniter4j-es-gchange/src/main/misc/index.sh
similarity index 100%
rename from duniter4j-elasticsearch/src/main/misc/index.sh
rename to duniter4j-es-gchange/src/main/misc/index.sh
diff --git a/duniter4j-elasticsearch/src/main/misc/registry-categories-naf2008_liste_n5.ods b/duniter4j-es-gchange/src/main/misc/registry-categories-naf2008_liste_n5.ods
similarity index 100%
rename from duniter4j-elasticsearch/src/main/misc/registry-categories-naf2008_liste_n5.ods
rename to duniter4j-es-gchange/src/main/misc/registry-categories-naf2008_liste_n5.ods
diff --git a/duniter4j-es-gchange/src/main/resources/market-categories-bulk-insert.json b/duniter4j-es-gchange/src/main/resources/market-categories-bulk-insert.json
new file mode 100644
index 0000000000000000000000000000000000000000..c9527a96a6f1a8d350067029670a10b4c1f2de74
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/resources/market-categories-bulk-insert.json
@@ -0,0 +1,151 @@
+{ "index": { "_id": "cat71"}}
+{ "name": "Emploi" , "parent": null}
+{ "index": { "_id": "cat33"}}
+{ "name": "Offres d'emploi", "parent": "cat71" }
+
+{ "index": { "_id": "cat1" }}
+{ "name": "Véhicules"  , "parent": null}
+{ "index": { "_id": "cat2" }}
+{ "name": "Voitures" , "parent": "cat2" }
+{ "index": { "_id": "cat3" }}
+{ "name": "Motos" , "parent": "cat3" }
+{ "index": { "_id": "cat4" }}
+{ "name": "Caravaning" , "parent": "cat3" }
+{ "index": { "_id": "cat5" }}
+{ "name": "Utilitaires" , "parent": "cat3" }
+{ "index": { "_id": "cat6" }}
+{ "name": "Equipement Auto" , "parent": "cat3" }
+{ "index": { "_id": "cat44" }}
+{ "name": "Equipement Moto" , "parent": "cat3" }
+{ "index": { "_id": "cat50" }}
+{ "name": "Equipement Caravaning" , "parent": "cat3" }
+{ "index": { "_id": "cat7" }}
+{ "name": "Nautisme" , "parent": "cat3" }
+{ "index": { "_id": "cat51" }}
+{ "name": "Equipement Nautisme" , "parent": "cat3" }
+
+{ "index": { "_id": "cat8" }}
+{ "name": "Immobilier"  , "parent": null}
+{ "index": { "_id": "cat9" }}
+{ "name": "Ventes immobilières" , "parent": "cat8" }
+{ "index": { "_id": "cat10" }}
+{ "name": "Locations" , "parent": "cat8" }
+{ "index": { "_id": "cat11" }}
+{ "name": "Colocations" , "parent": "cat8" }
+{ "index": { "_id": "cat13" }}
+{ "name": "Bureaux &amp; Commerces" , "parent": "cat8" }
+
+{ "index": { "_id": "cat66" }}
+{ "name": "Vacances"  , "parent": null}
+{ "index": { "_id": "cat12" }}
+{ "name": "Locations &amp; Gîtes" , "parent": "cat66" }
+{ "index": { "_id": "cat67" }}
+{ "name": "Chambres d'hôtes" , "parent": "cat66" }
+{ "index": { "_id": "cat68" }}
+{ "name": "Campings" , "parent": "cat66" }
+{ "index": { "_id": "cat69" }}
+{ "name": "Hôtels" , "parent": "cat66" }
+{ "index": { "_id": "cat70" }}
+{ "name": "Hébergements insolites" , "parent": "cat66" }
+
+{ "index": { "_id": "cat14" }}
+{ "name": "Multimédia"  , "parent": null}
+{ "index": { "_id": "cat15" }}
+{ "name": "Informatique" , "parent": "cat14" }
+{ "index": { "_id": "cat43" }}
+{ "name": "Consoles &amp; Jeux vidéo" , "parent": "cat14" }
+{ "index": { "_id": "cat16" }}
+{ "name": "Image &amp; Son" , "parent": "cat14" }
+{ "index": { "_id": "cat17" }}
+{ "name": "Téléphonie" , "parent": "cat14" }
+
+{ "index": { "_id": "cat18" }}
+{ "name": "Maison"  , "parent": null}
+{ "index": { "_id": "cat19" }}
+{ "name": "Ameublement" , "parent": "cat18" }
+{ "index": { "_id": "cat20" }}
+{ "name": "Electroménager" , "parent": "cat18" }
+{ "index": { "_id": "cat45" }}
+{ "name": "Arts de la table" , "parent": "cat18" }
+{ "index": { "_id": "cat39" }}
+{ "name": "Décoration" , "parent": "cat18" }
+{ "index": { "_id": "cat46" }}
+{ "name": "Linge de maison" , "parent": "cat18" }
+{ "index": { "_id": "cat21" }}
+{ "name": "Bricolage" , "parent": "cat18" }
+{ "index": { "_id": "cat52" }}
+{ "name": "Jardinage" , "parent": "cat18" }
+{ "index": { "_id": "cat22" }}
+{ "name": "Vêtements" , "parent": "cat18" }
+{ "index": { "_id": "cat53" }}
+{ "name": "Chaussures" , "parent": "cat18" }
+{ "index": { "_id": "cat47" }}
+{ "name": "Accessoires &amp; Bagagerie" , "parent": "cat18" }
+{ "index": { "_id": "cat42" }}
+{ "name": "Montres &amp; Bijoux" , "parent": "cat18" }
+{ "index": { "_id": "cat23" }}
+{ "name": "Equipement bébé" , "parent": "cat18" }
+{ "index": { "_id": "cat54" }}
+{ "name": "Vêtements bébé" , "parent": "cat18" }
+
+{ "index": { "_id": "cat24" }}
+{ "name": "Loisirs"  , "parent": null}
+{ "index": { "_id": "cat25" }}
+{ "name": "DVD / Films" , "parent": "cat24" }
+{ "index": { "_id": "cat26" }}
+{ "name": "CD / Musique" , "parent": "cat24" }
+{ "index": { "_id": "cat27" }}
+{ "name": "Livres" , "parent": "cat24" }
+{ "index": { "_id": "cat28" }}
+{ "name": "Animaux" , "parent": "cat24" }
+{ "index": { "_id": "cat55" }}
+{ "name": "Vélos" , "parent": "cat24" }
+{ "index": { "_id": "cat29" }}
+{ "name": "Sports &amp; Hobbies" }
+{ "index": { "_id": "cat30" }}
+{ "name": "Instruments de musique" , "parent": "cat24" }
+{ "index": { "_id": "cat40" }}
+{ "name": "Collection" , "parent": "cat24" }
+{ "index": { "_id": "cat41" }}
+{ "name": "Jeux &amp; Jouets" , "parent": "cat24" }
+{ "index": { "_id": "cat48" }}
+{ "name": "Vins &amp; Gastronomie" , "parent": "cat24" }
+
+{ "index": { "_id": "cat56" }}
+{ "name": "Matériel professionnel"  , "parent": null}
+{ "index": { "_id": "cat57" }}
+{ "name": "Matériel Agricole" , "parent": "cat56" }
+{ "index": { "_id": "cat58" }}
+{ "name": "Transport - Manutention" , "parent": "cat56" }
+{ "index": { "_id": "cat59" }}
+{ "name": "BTP - Chantier Gros-oeuvre" , "parent": "cat56" }
+{ "index": { "_id": "cat60" }}
+{ "name": "Outillage - Matériaux 2nd-oeuvre" , "parent": "cat56" }
+{ "index": { "_id": "cat32" }}
+{ "name": "Équipements Industriels" , "parent": "cat56" }
+{ "index": { "_id": "cat61" }}
+{ "name": "Restauration - Hôtellerie" , "parent": "cat56" }
+{ "index": { "_id": "cat62" }}
+{ "name": "Fournitures de Bureau" , "parent": "cat56" }
+{ "index": { "_id": "cat63" }}
+{ "name": "Commerces &amp; Marchés" , "parent": "cat56" }
+{ "index": { "_id": "cat64" }}
+{ "name": "Matériel Médical" , "parent": "cat56" }
+
+{ "index": { "_id": "cat31" }}
+{ "name": "Services"  , "parent": null}
+{ "index": { "_id": "cat34" }}
+{ "name": "Prestations de services" , "parent": "cat31" }
+{ "index": { "_id": "cat35" }}
+{ "name": "Billetterie" , "parent": "cat31" }
+{ "index": { "_id": "cat49" }}
+{ "name": "Evénements" , "parent": "cat31" }
+{ "index": { "_id": "cat36" }}
+{ "name": "Cours particuliers" , "parent": "cat31" }
+{ "index": { "_id": "cat65" }}
+{ "name": "Covoiturage" , "parent": "cat31" }
+{ "index": { "_id": "cat37" }}
+
+{ "name": "Divers"  , "parent": null}
+{ "index": { "_id": "cat38" }}
+{ "name": "Autres" , "parent": "cat37" }
diff --git a/duniter4j-es-gchange/src/main/resources/plugin-security.policy b/duniter4j-es-gchange/src/main/resources/plugin-security.policy
new file mode 100644
index 0000000000000000000000000000000000000000..3ea59400b9bd2a3d0e1b89091169fa50b60e1123
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/resources/plugin-security.policy
@@ -0,0 +1,5 @@
+grant codeBase "file:${es.path.home}/plugins/duniter4j-es-gchange/"{
+  permission java.io.FilePermission "/etc/ld.so.conf", "read";
+  permission java.io.FilePermission "/etc/ld.so.conf.d/*.conf", "read";
+  permission java.io.FilePermission "/usr/local/lib/*", "read";
+};
\ No newline at end of file
diff --git a/duniter4j-es-gchange/src/main/resources/registry-categories-bulk-insert.json b/duniter4j-es-gchange/src/main/resources/registry-categories-bulk-insert.json
new file mode 100644
index 0000000000000000000000000000000000000000..3ee70de3d3aa58dfd3ff01f1a578a2f917508d66
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/resources/registry-categories-bulk-insert.json
@@ -0,0 +1,1506 @@
+{"index": {"_id": "A"}}
+{"name": "Agriculture, sylviculture et pêche", "parent": null}
+{"index": {"_id": "01.11Z"}}
+{"name": "Culture de céréales (à l'exception du riz), de légumineuses et de graines oléagineuses", "parent": "A"}
+{"index": {"_id": "01.12Z"}}
+{"name": "Culture du riz", "parent": "A"}
+{"index": {"_id": "01.13Z"}}
+{"name": "Culture de légumes, de melons, de racines et de tubercules", "parent": "A"}
+{"index": {"_id": "01.14Z"}}
+{"name": "Culture de la canne à sucre", "parent": "A"}
+{"index": {"_id": "01.15Z"}}
+{"name": "Culture du tabac", "parent": "A"}
+{"index": {"_id": "01.16Z"}}
+{"name": "Culture de plantes à fibres", "parent": "A"}
+{"index": {"_id": "01.19Z"}}
+{"name": "Autres cultures non permanentes", "parent": "A"}
+{"index": {"_id": "01.21Z"}}
+{"name": "Culture de la vigne", "parent": "A"}
+{"index": {"_id": "01.22Z"}}
+{"name": "Culture de fruits tropicaux et subtropicaux", "parent": "A"}
+{"index": {"_id": "01.23Z"}}
+{"name": "Culture d'agrumes", "parent": "A"}
+{"index": {"_id": "01.24Z"}}
+{"name": "Culture de fruits à pépins et à noyau", "parent": "A"}
+{"index": {"_id": "01.25Z"}}
+{"name": "Culture d'autres fruits d'arbres ou d'arbustes et de fruits à coque", "parent": "A"}
+{"index": {"_id": "01.26Z"}}
+{"name": "Culture de fruits oléagineux", "parent": "A"}
+{"index": {"_id": "01.27Z"}}
+{"name": "Culture de plantes à boissons", "parent": "A"}
+{"index": {"_id": "01.28Z"}}
+{"name": "Culture de plantes à épices, aromatiques, médicinales et pharmaceutiques", "parent": "A"}
+{"index": {"_id": "01.29Z"}}
+{"name": "Autres cultures permanentes", "parent": "A"}
+{"index": {"_id": "01.30Z"}}
+{"name": "Reproduction de plantes", "parent": "A"}
+{"index": {"_id": "01.41Z"}}
+{"name": "Élevage de vaches laitières", "parent": "A"}
+{"index": {"_id": "01.42Z"}}
+{"name": "Élevage d'autres bovins et de buffles", "parent": "A"}
+{"index": {"_id": "01.43Z"}}
+{"name": "Élevage de chevaux et d'autres équidés", "parent": "A"}
+{"index": {"_id": "01.44Z"}}
+{"name": "Élevage de chameaux et d'autres camélidés", "parent": "A"}
+{"index": {"_id": "01.45Z"}}
+{"name": "Élevage d'ovins et de caprins", "parent": "A"}
+{"index": {"_id": "01.46Z"}}
+{"name": "Élevage de porcins", "parent": "A"}
+{"index": {"_id": "01.47Z"}}
+{"name": "Élevage de volailles", "parent": "A"}
+{"index": {"_id": "01.49Z"}}
+{"name": "Élevage d'autres animaux", "parent": "A"}
+{"index": {"_id": "01.50Z"}}
+{"name": "Culture et élevage associés", "parent": "A"}
+{"index": {"_id": "01.61Z"}}
+{"name": "Activités de soutien aux cultures", "parent": "A"}
+{"index": {"_id": "01.62Z"}}
+{"name": "Activités de soutien à la production animale", "parent": "A"}
+{"index": {"_id": "01.63Z"}}
+{"name": "Traitement primaire des récoltes", "parent": "A"}
+{"index": {"_id": "01.64Z"}}
+{"name": "Traitement des semences", "parent": "A"}
+{"index": {"_id": "01.70Z"}}
+{"name": "Chasse, piégeage et services annexes", "parent": "A"}
+{"index": {"_id": "02.10Z"}}
+{"name": "Sylviculture et autres activités forestières", "parent": "A"}
+{"index": {"_id": "02.20Z"}}
+{"name": "Exploitation forestière", "parent": "A"}
+{"index": {"_id": "02.30Z"}}
+{"name": "Récolte de produits forestiers non ligneux poussant à l'état sauvage", "parent": "A"}
+{"index": {"_id": "02.40Z"}}
+{"name": "Services de soutien à l'exploitation forestière", "parent": "A"}
+{"index": {"_id": "03.11Z"}}
+{"name": "Pêche en mer", "parent": "A"}
+{"index": {"_id": "03.12Z"}}
+{"name": "Pêche en eau douce", "parent": "A"}
+{"index": {"_id": "03.21Z"}}
+{"name": "Aquaculture en mer", "parent": "A"}
+{"index": {"_id": "03.22Z"}}
+{"name": "Aquaculture en eau douce", "parent": "A"}
+{"index": {"_id": "B"}}
+{"name": "Industries extractives", "parent": null}
+{"index": {"_id": "05.10Z"}}
+{"name": "Extraction de houille", "parent": "B"}
+{"index": {"_id": "05.20Z"}}
+{"name": "Extraction de lignite", "parent": "B"}
+{"index": {"_id": "06.10Z"}}
+{"name": "Extraction de pétrole brut", "parent": "B"}
+{"index": {"_id": "06.20Z"}}
+{"name": "Extraction de gaz naturel", "parent": "B"}
+{"index": {"_id": "07.10Z"}}
+{"name": "Extraction de minerais de fer", "parent": "B"}
+{"index": {"_id": "07.21Z"}}
+{"name": "Extraction de minerais d'uranium et de thorium", "parent": "B"}
+{"index": {"_id": "07.29Z"}}
+{"name": "Extraction d'autres minerais de métaux non ferreux", "parent": "B"}
+{"index": {"_id": "08.11Z"}}
+{"name": "Extraction de pierres ornementales et de construction, de calcaire industriel, de gypse, de craie et d'ardoise", "parent": "B"}
+{"index": {"_id": "08.12Z"}}
+{"name": "Exploitation de gravières et sablières, extraction d'argiles et de kaolin", "parent": "B"}
+{"index": {"_id": "08.91Z"}}
+{"name": "Extraction des minéraux chimiques et d'engrais minéraux", "parent": "B"}
+{"index": {"_id": "08.92Z"}}
+{"name": "Extraction de tourbe", "parent": "B"}
+{"index": {"_id": "08.93Z"}}
+{"name": "Production de sel", "parent": "B"}
+{"index": {"_id": "08.99Z"}}
+{"name": "Autres activités extractives n.c.a.", "parent": "B"}
+{"index": {"_id": "09.10Z"}}
+{"name": "Activités de soutien à l'extraction d'hydrocarbures", "parent": "B"}
+{"index": {"_id": "09.90Z"}}
+{"name": "Activités de soutien aux autres industries extractives", "parent": "B"}
+{"index": {"_id": "C"}}
+{"name": "Industrie manufacturière", "parent": null}
+{"index": {"_id": "10.11Z"}}
+{"name": "Transformation et conservation de la viande de boucherie", "parent": "C"}
+{"index": {"_id": "10.12Z"}}
+{"name": "Transformation et conservation de la viande de volaille", "parent": "C"}
+{"index": {"_id": "10.13A"}}
+{"name": "Préparation industrielle de produits à base de viande", "parent": "C"}
+{"index": {"_id": "10.13B"}}
+{"name": "Charcuterie", "parent": "C"}
+{"index": {"_id": "10.20Z"}}
+{"name": "Transformation et conservation de poisson, de crustacés et de mollusques", "parent": "C"}
+{"index": {"_id": "10.31Z"}}
+{"name": "Transformation et conservation de pommes de terre", "parent": "C"}
+{"index": {"_id": "10.32Z"}}
+{"name": "Préparation de jus de fruits et légumes", "parent": "C"}
+{"index": {"_id": "10.39A"}}
+{"name": "Autre transformation et conservation de légumes", "parent": "C"}
+{"index": {"_id": "10.39B"}}
+{"name": "Transformation et conservation de fruits", "parent": "C"}
+{"index": {"_id": "10.41A"}}
+{"name": "Fabrication d'huiles et graisses brutes", "parent": "C"}
+{"index": {"_id": "10.41B"}}
+{"name": "Fabrication d'huiles et graisses raffinées", "parent": "C"}
+{"index": {"_id": "10.42Z"}}
+{"name": "Fabrication de margarine et graisses comestibles similaires", "parent": "C"}
+{"index": {"_id": "10.51A"}}
+{"name": "Fabrication de lait liquide et de produits frais", "parent": "C"}
+{"index": {"_id": "10.51B"}}
+{"name": "Fabrication de beurre", "parent": "C"}
+{"index": {"_id": "10.51C"}}
+{"name": "Fabrication de fromage", "parent": "C"}
+{"index": {"_id": "10.51D"}}
+{"name": "Fabrication d'autres produits laitiers", "parent": "C"}
+{"index": {"_id": "10.52Z"}}
+{"name": "Fabrication de glaces et sorbets", "parent": "C"}
+{"index": {"_id": "10.61A"}}
+{"name": "Meunerie", "parent": "C"}
+{"index": {"_id": "10.61B"}}
+{"name": "Autres activités du travail des grains", "parent": "C"}
+{"index": {"_id": "10.62Z"}}
+{"name": "Fabrication de produits amylacés", "parent": "C"}
+{"index": {"_id": "10.71A"}}
+{"name": "Fabrication industrielle de pain et de pâtisserie fraîche", "parent": "C"}
+{"index": {"_id": "10.71B"}}
+{"name": "Cuisson de produits de boulangerie", "parent": "C"}
+{"index": {"_id": "10.71C"}}
+{"name": "Boulangerie et boulangerie-pâtisserie", "parent": "C"}
+{"index": {"_id": "10.71D"}}
+{"name": "Pâtisserie", "parent": "C"}
+{"index": {"_id": "10.72Z"}}
+{"name": "Fabrication de biscuits, biscottes et pâtisseries de conservation", "parent": "C"}
+{"index": {"_id": "10.73Z"}}
+{"name": "Fabrication de pâtes alimentaires", "parent": "C"}
+{"index": {"_id": "10.81Z"}}
+{"name": "Fabrication de sucre", "parent": "C"}
+{"index": {"_id": "10.82Z"}}
+{"name": "Fabrication de cacao, chocolat et de produits de confiserie", "parent": "C"}
+{"index": {"_id": "10.83Z"}}
+{"name": "Transformation du thé et du café", "parent": "C"}
+{"index": {"_id": "10.84Z"}}
+{"name": "Fabrication de condiments et assaisonnements", "parent": "C"}
+{"index": {"_id": "10.85Z"}}
+{"name": "Fabrication de plats préparés", "parent": "C"}
+{"index": {"_id": "10.86Z"}}
+{"name": "Fabrication d'aliments homogénéisés et diététiques", "parent": "C"}
+{"index": {"_id": "10.89Z"}}
+{"name": "Fabrication d'autres produits alimentaires n.c.a.", "parent": "C"}
+{"index": {"_id": "10.91Z"}}
+{"name": "Fabrication d'aliments pour animaux de ferme", "parent": "C"}
+{"index": {"_id": "10.92Z"}}
+{"name": "Fabrication d'aliments pour animaux de compagnie", "parent": "C"}
+{"index": {"_id": "11.01Z"}}
+{"name": "Production de boissons alcooliques distillées", "parent": "C"}
+{"index": {"_id": "11.02A"}}
+{"name": "Fabrication de vins effervescents", "parent": "C"}
+{"index": {"_id": "11.02B"}}
+{"name": "Vinification", "parent": "C"}
+{"index": {"_id": "11.03Z"}}
+{"name": "Fabrication de cidre et de vins de fruits", "parent": "C"}
+{"index": {"_id": "11.04Z"}}
+{"name": "Production d'autres boissons fermentées non distillées", "parent": "C"}
+{"index": {"_id": "11.05Z"}}
+{"name": "Fabrication de bière", "parent": "C"}
+{"index": {"_id": "11.06Z"}}
+{"name": "Fabrication de malt", "parent": "C"}
+{"index": {"_id": "11.07A"}}
+{"name": "Industrie des eaux de table", "parent": "C"}
+{"index": {"_id": "11.07B"}}
+{"name": "Production de boissons rafraîchissantes", "parent": "C"}
+{"index": {"_id": "12.00Z"}}
+{"name": "Fabrication de produits à base de tabac", "parent": "C"}
+{"index": {"_id": "13.10Z"}}
+{"name": "Préparation de fibres textiles et filature", "parent": "C"}
+{"index": {"_id": "13.20Z"}}
+{"name": "Tissage", "parent": "C"}
+{"index": {"_id": "13.30Z"}}
+{"name": "Ennoblissement textile", "parent": "C"}
+{"index": {"_id": "13.91Z"}}
+{"name": "Fabrication d'étoffes à mailles", "parent": "C"}
+{"index": {"_id": "13.92Z"}}
+{"name": "Fabrication d'articles textiles, sauf habillement", "parent": "C"}
+{"index": {"_id": "13.93Z"}}
+{"name": "Fabrication de tapis et moquettes", "parent": "C"}
+{"index": {"_id": "13.94Z"}}
+{"name": "Fabrication de ficelles, cordes et filets", "parent": "C"}
+{"index": {"_id": "13.95Z"}}
+{"name": "Fabrication de non-tissés, sauf habillement", "parent": "C"}
+{"index": {"_id": "13.96Z"}}
+{"name": "Fabrication d'autres textiles techniques et industriels", "parent": "C"}
+{"index": {"_id": "13.99Z"}}
+{"name": "Fabrication d'autres textiles n.c.a.", "parent": "C"}
+{"index": {"_id": "14.11Z"}}
+{"name": "Fabrication de vêtements en cuir", "parent": "C"}
+{"index": {"_id": "14.12Z"}}
+{"name": "Fabrication de vêtements de travail", "parent": "C"}
+{"index": {"_id": "14.13Z"}}
+{"name": "Fabrication de vêtements de dessus", "parent": "C"}
+{"index": {"_id": "14.14Z"}}
+{"name": "Fabrication de vêtements de dessous", "parent": "C"}
+{"index": {"_id": "14.19Z"}}
+{"name": "Fabrication d'autres vêtements et accessoires", "parent": "C"}
+{"index": {"_id": "14.20Z"}}
+{"name": "Fabrication d'articles en fourrure", "parent": "C"}
+{"index": {"_id": "14.31Z"}}
+{"name": "Fabrication d'articles chaussants à mailles", "parent": "C"}
+{"index": {"_id": "14.39Z"}}
+{"name": "Fabrication d'autres articles à mailles", "parent": "C"}
+{"index": {"_id": "15.11Z"}}
+{"name": "Apprêt et tannage des cuirs ; préparation et teinture des fourrures", "parent": "C"}
+{"index": {"_id": "15.12Z"}}
+{"name": "Fabrication d'articles de voyage, de maroquinerie et de sellerie", "parent": "C"}
+{"index": {"_id": "15.20Z"}}
+{"name": "Fabrication de chaussures", "parent": "C"}
+{"index": {"_id": "16.10A"}}
+{"name": "Sciage et rabotage du bois, hors imprégnation", "parent": "C"}
+{"index": {"_id": "16.10B"}}
+{"name": "Imprégnation du bois", "parent": "C"}
+{"index": {"_id": "16.21Z"}}
+{"name": "Fabrication de placage et de panneaux de bois", "parent": "C"}
+{"index": {"_id": "16.22Z"}}
+{"name": "Fabrication de parquets assemblés", "parent": "C"}
+{"index": {"_id": "16.23Z"}}
+{"name": "Fabrication de charpentes et d'autres menuiseries", "parent": "C"}
+{"index": {"_id": "16.24Z"}}
+{"name": "Fabrication d'emballages en bois", "parent": "C"}
+{"index": {"_id": "16.29Z"}}
+{"name": "Fabrication d'objets divers en bois ; fabrication d'objets en liège, vannerie et sparterie", "parent": "C"}
+{"index": {"_id": "17.11Z"}}
+{"name": "Fabrication de pâte à papier", "parent": "C"}
+{"index": {"_id": "17.12Z"}}
+{"name": "Fabrication de papier et de carton", "parent": "C"}
+{"index": {"_id": "17.21A"}}
+{"name": "Fabrication de carton ondulé", "parent": "C"}
+{"index": {"_id": "17.21B"}}
+{"name": "Fabrication de cartonnages", "parent": "C"}
+{"index": {"_id": "17.21C"}}
+{"name": "Fabrication d'emballages en papier", "parent": "C"}
+{"index": {"_id": "17.22Z"}}
+{"name": "Fabrication d'articles en papier à usage sanitaire ou domestique", "parent": "C"}
+{"index": {"_id": "17.23Z"}}
+{"name": "Fabrication d'articles de papeterie", "parent": "C"}
+{"index": {"_id": "17.24Z"}}
+{"name": "Fabrication de papiers peints", "parent": "C"}
+{"index": {"_id": "17.29Z"}}
+{"name": "Fabrication d'autres articles en papier ou en carton", "parent": "C"}
+{"index": {"_id": "18.11Z"}}
+{"name": "Imprimerie de journaux", "parent": "C"}
+{"index": {"_id": "18.12Z"}}
+{"name": "Autre imprimerie (labeur)", "parent": "C"}
+{"index": {"_id": "18.13Z"}}
+{"name": "Activités de pré-presse", "parent": "C"}
+{"index": {"_id": "18.14Z"}}
+{"name": "Reliure et activités connexes", "parent": "C"}
+{"index": {"_id": "18.20Z"}}
+{"name": "Reproduction d'enregistrements", "parent": "C"}
+{"index": {"_id": "19.10Z"}}
+{"name": "Cokéfaction", "parent": "C"}
+{"index": {"_id": "19.20Z"}}
+{"name": "Raffinage du pétrole", "parent": "C"}
+{"index": {"_id": "20.11Z"}}
+{"name": "Fabrication de gaz industriels", "parent": "C"}
+{"index": {"_id": "20.12Z"}}
+{"name": "Fabrication de colorants et de pigments", "parent": "C"}
+{"index": {"_id": "20.13A"}}
+{"name": "Enrichissement et retraitement de matières nucléaires", "parent": "C"}
+{"index": {"_id": "20.13B"}}
+{"name": "Fabrication d'autres produits chimiques inorganiques de base n.c.a.", "parent": "C"}
+{"index": {"_id": "20.14Z"}}
+{"name": "Fabrication d'autres produits chimiques organiques de base", "parent": "C"}
+{"index": {"_id": "20.15Z"}}
+{"name": "Fabrication de produits azotés et d'engrais", "parent": "C"}
+{"index": {"_id": "20.16Z"}}
+{"name": "Fabrication de matières plastiques de base", "parent": "C"}
+{"index": {"_id": "20.17Z"}}
+{"name": "Fabrication de caoutchouc synthétique", "parent": "C"}
+{"index": {"_id": "20.20Z"}}
+{"name": "Fabrication de pesticides et d'autres produits agrochimiques", "parent": "C"}
+{"index": {"_id": "20.30Z"}}
+{"name": "Fabrication de peintures, vernis, encres et mastics", "parent": "C"}
+{"index": {"_id": "20.41Z"}}
+{"name": "Fabrication de savons, détergents et produits d'entretien", "parent": "C"}
+{"index": {"_id": "20.42Z"}}
+{"name": "Fabrication de parfums et de produits pour la toilette", "parent": "C"}
+{"index": {"_id": "20.51Z"}}
+{"name": "Fabrication de produits explosifs", "parent": "C"}
+{"index": {"_id": "20.52Z"}}
+{"name": "Fabrication de colles", "parent": "C"}
+{"index": {"_id": "20.53Z"}}
+{"name": "Fabrication d'huiles essentielles", "parent": "C"}
+{"index": {"_id": "20.59Z"}}
+{"name": "Fabrication d'autres produits chimiques n.c.a.", "parent": "C"}
+{"index": {"_id": "20.60Z"}}
+{"name": "Fabrication de fibres artificielles ou synthétiques", "parent": "C"}
+{"index": {"_id": "21.10Z"}}
+{"name": "Fabrication de produits pharmaceutiques de base", "parent": "C"}
+{"index": {"_id": "21.20Z"}}
+{"name": "Fabrication de préparations pharmaceutiques", "parent": "C"}
+{"index": {"_id": "22.11Z"}}
+{"name": "Fabrication et rechapage de pneumatiques", "parent": "C"}
+{"index": {"_id": "22.19Z"}}
+{"name": "Fabrication d'autres articles en caoutchouc", "parent": "C"}
+{"index": {"_id": "22.21Z"}}
+{"name": "Fabrication de plaques, feuilles, tubes et profilés en matières plastiques", "parent": "C"}
+{"index": {"_id": "22.22Z"}}
+{"name": "Fabrication d'emballages en matières plastiques", "parent": "C"}
+{"index": {"_id": "22.23Z"}}
+{"name": "Fabrication d'éléments en matières plastiques pour la construction", "parent": "C"}
+{"index": {"_id": "22.29A"}}
+{"name": "Fabrication de pièces techniques à base de matières plastiques", "parent": "C"}
+{"index": {"_id": "22.29B"}}
+{"name": "Fabrication de produits de consommation courante en matières plastiques", "parent": "C"}
+{"index": {"_id": "23.11Z"}}
+{"name": "Fabrication de verre plat", "parent": "C"}
+{"index": {"_id": "23.12Z"}}
+{"name": "Façonnage et transformation du verre plat", "parent": "C"}
+{"index": {"_id": "23.13Z"}}
+{"name": "Fabrication de verre creux", "parent": "C"}
+{"index": {"_id": "23.14Z"}}
+{"name": "Fabrication de fibres de verre", "parent": "C"}
+{"index": {"_id": "23.19Z"}}
+{"name": "Fabrication et façonnage d'autres articles en verre, y compris verre technique", "parent": "C"}
+{"index": {"_id": "23.20Z"}}
+{"name": "Fabrication de produits réfractaires", "parent": "C"}
+{"index": {"_id": "23.31Z"}}
+{"name": "Fabrication de carreaux en céramique", "parent": "C"}
+{"index": {"_id": "23.32Z"}}
+{"name": "Fabrication de briques, tuiles et produits de construction, en terre cuite", "parent": "C"}
+{"index": {"_id": "23.41Z"}}
+{"name": "Fabrication d'articles céramiques à usage domestique ou ornemental", "parent": "C"}
+{"index": {"_id": "23.42Z"}}
+{"name": "Fabrication d'appareils sanitaires en céramique", "parent": "C"}
+{"index": {"_id": "23.43Z"}}
+{"name": "Fabrication d'isolateurs et pièces isolantes en céramique", "parent": "C"}
+{"index": {"_id": "23.44Z"}}
+{"name": "Fabrication d'autres produits céramiques à usage technique", "parent": "C"}
+{"index": {"_id": "23.49Z"}}
+{"name": "Fabrication d'autres produits céramiques", "parent": "C"}
+{"index": {"_id": "23.51Z"}}
+{"name": "Fabrication de ciment", "parent": "C"}
+{"index": {"_id": "23.52Z"}}
+{"name": "Fabrication de chaux et plâtre", "parent": "C"}
+{"index": {"_id": "23.61Z"}}
+{"name": "Fabrication d'éléments en béton pour la construction", "parent": "C"}
+{"index": {"_id": "23.62Z"}}
+{"name": "Fabrication d'éléments en plâtre pour la construction", "parent": "C"}
+{"index": {"_id": "23.63Z"}}
+{"name": "Fabrication de béton prêt à l'emploi", "parent": "C"}
+{"index": {"_id": "23.64Z"}}
+{"name": "Fabrication de mortiers et bétons secs", "parent": "C"}
+{"index": {"_id": "23.65Z"}}
+{"name": "Fabrication d'ouvrages en fibre-ciment", "parent": "C"}
+{"index": {"_id": "23.69Z"}}
+{"name": "Fabrication d'autres ouvrages en béton, en ciment ou en plâtre", "parent": "C"}
+{"index": {"_id": "23.70Z"}}
+{"name": "Taille, façonnage et finissage de pierres", "parent": "C"}
+{"index": {"_id": "23.91Z"}}
+{"name": "Fabrication de produits abrasifs", "parent": "C"}
+{"index": {"_id": "23.99Z"}}
+{"name": "Fabrication d'autres produits minéraux non métalliques n.c.a.", "parent": "C"}
+{"index": {"_id": "24.10Z"}}
+{"name": "Sidérurgie", "parent": "C"}
+{"index": {"_id": "24.20Z"}}
+{"name": "Fabrication de tubes, tuyaux, profilés creux et accessoires correspondants en acier", "parent": "C"}
+{"index": {"_id": "24.31Z"}}
+{"name": "Étirage à froid de barres", "parent": "C"}
+{"index": {"_id": "24.32Z"}}
+{"name": "Laminage à froid de feuillards", "parent": "C"}
+{"index": {"_id": "24.33Z"}}
+{"name": "Profilage à froid par formage ou pliage", "parent": "C"}
+{"index": {"_id": "24.34Z"}}
+{"name": "Tréfilage à froid", "parent": "C"}
+{"index": {"_id": "24.41Z"}}
+{"name": "Production de métaux précieux", "parent": "C"}
+{"index": {"_id": "24.42Z"}}
+{"name": "Métallurgie de l'aluminium", "parent": "C"}
+{"index": {"_id": "24.43Z"}}
+{"name": "Métallurgie du plomb, du zinc ou de l'étain", "parent": "C"}
+{"index": {"_id": "24.44Z"}}
+{"name": "Métallurgie du cuivre", "parent": "C"}
+{"index": {"_id": "24.45Z"}}
+{"name": "Métallurgie des autres métaux non ferreux", "parent": "C"}
+{"index": {"_id": "24.46Z"}}
+{"name": "Élaboration et transformation de matières nucléaires", "parent": "C"}
+{"index": {"_id": "24.51Z"}}
+{"name": "Fonderie de fonte", "parent": "C"}
+{"index": {"_id": "24.52Z"}}
+{"name": "Fonderie d'acier", "parent": "C"}
+{"index": {"_id": "24.53Z"}}
+{"name": "Fonderie de métaux légers", "parent": "C"}
+{"index": {"_id": "24.54Z"}}
+{"name": "Fonderie d'autres métaux non ferreux", "parent": "C"}
+{"index": {"_id": "25.11Z"}}
+{"name": "Fabrication de structures métalliques et de parties de structures", "parent": "C"}
+{"index": {"_id": "25.12Z"}}
+{"name": "Fabrication de portes et fenêtres en métal", "parent": "C"}
+{"index": {"_id": "25.21Z"}}
+{"name": "Fabrication de radiateurs et de chaudières pour le chauffage central", "parent": "C"}
+{"index": {"_id": "25.29Z"}}
+{"name": "Fabrication d'autres réservoirs, citernes et conteneurs métalliques", "parent": "C"}
+{"index": {"_id": "25.30Z"}}
+{"name": "Fabrication de générateurs de vapeur, à l'exception des chaudières pour le chauffage central", "parent": "C"}
+{"index": {"_id": "25.40Z"}}
+{"name": "Fabrication d'armes et de munitions", "parent": "C"}
+{"index": {"_id": "25.50A"}}
+{"name": "Forge, estampage, matriçage ; métallurgie des poudres", "parent": "C"}
+{"index": {"_id": "25.50B"}}
+{"name": "Découpage, emboutissage", "parent": "C"}
+{"index": {"_id": "25.61Z"}}
+{"name": "Traitement et revêtement des métaux", "parent": "C"}
+{"index": {"_id": "25.62A"}}
+{"name": "Décolletage", "parent": "C"}
+{"index": {"_id": "25.62B"}}
+{"name": "Mécanique industrielle", "parent": "C"}
+{"index": {"_id": "25.71Z"}}
+{"name": "Fabrication de coutellerie", "parent": "C"}
+{"index": {"_id": "25.72Z"}}
+{"name": "Fabrication de serrures et de ferrures", "parent": "C"}
+{"index": {"_id": "25.73A"}}
+{"name": "Fabrication de moules et modèles", "parent": "C"}
+{"index": {"_id": "25.73B"}}
+{"name": "Fabrication d'autres outillages", "parent": "C"}
+{"index": {"_id": "25.91Z"}}
+{"name": "Fabrication de fûts et emballages métalliques similaires", "parent": "C"}
+{"index": {"_id": "25.92Z"}}
+{"name": "Fabrication d'emballages métalliques légers", "parent": "C"}
+{"index": {"_id": "25.93Z"}}
+{"name": "Fabrication d'articles en fils métalliques, de chaînes et de ressorts", "parent": "C"}
+{"index": {"_id": "25.94Z"}}
+{"name": "Fabrication de vis et de boulons", "parent": "C"}
+{"index": {"_id": "25.99A"}}
+{"name": "Fabrication d'articles métalliques ménagers", "parent": "C"}
+{"index": {"_id": "25.99B"}}
+{"name": "Fabrication d'autres articles métalliques", "parent": "C"}
+{"index": {"_id": "26.11Z"}}
+{"name": "Fabrication de composants électroniques", "parent": "C"}
+{"index": {"_id": "26.12Z"}}
+{"name": "Fabrication de cartes électroniques assemblées", "parent": "C"}
+{"index": {"_id": "26.20Z"}}
+{"name": "Fabrication d'ordinateurs et d'équipements périphériques", "parent": "C"}
+{"index": {"_id": "26.30Z"}}
+{"name": "Fabrication d'équipements de communication", "parent": "C"}
+{"index": {"_id": "26.40Z"}}
+{"name": "Fabrication de produits électroniques grand public", "parent": "C"}
+{"index": {"_id": "26.51A"}}
+{"name": "Fabrication d'équipements d'aide à la navigation", "parent": "C"}
+{"index": {"_id": "26.51B"}}
+{"name": "Fabrication d'instrumentation scientifique et technique", "parent": "C"}
+{"index": {"_id": "26.52Z"}}
+{"name": "Horlogerie", "parent": "C"}
+{"index": {"_id": "26.60Z"}}
+{"name": "Fabrication d'équipements d'irradiation médicale, d'équipements électromédicaux et électrothérapeutiques", "parent": "C"}
+{"index": {"_id": "26.70Z"}}
+{"name": "Fabrication de matériels optique et photographique", "parent": "C"}
+{"index": {"_id": "26.80Z"}}
+{"name": "Fabrication de supports magnétiques et optiques", "parent": "C"}
+{"index": {"_id": "27.11Z"}}
+{"name": "Fabrication de moteurs, génératrices et transformateurs électriques", "parent": "C"}
+{"index": {"_id": "27.12Z"}}
+{"name": "Fabrication de matériel de distribution et de commande électrique", "parent": "C"}
+{"index": {"_id": "27.20Z"}}
+{"name": "Fabrication de piles et d'accumulateurs électriques", "parent": "C"}
+{"index": {"_id": "27.31Z"}}
+{"name": "Fabrication de câbles de fibres optiques", "parent": "C"}
+{"index": {"_id": "27.32Z"}}
+{"name": "Fabrication d'autres fils et câbles électroniques ou électriques", "parent": "C"}
+{"index": {"_id": "27.33Z"}}
+{"name": "Fabrication de matériel d'installation électrique", "parent": "C"}
+{"index": {"_id": "27.40Z"}}
+{"name": "Fabrication d'appareils d'éclairage électrique", "parent": "C"}
+{"index": {"_id": "27.51Z"}}
+{"name": "Fabrication d'appareils électroménagers", "parent": "C"}
+{"index": {"_id": "27.52Z"}}
+{"name": "Fabrication d'appareils ménagers non électriques", "parent": "C"}
+{"index": {"_id": "27.90Z"}}
+{"name": "Fabrication d'autres matériels électriques", "parent": "C"}
+{"index": {"_id": "28.11Z"}}
+{"name": "Fabrication de moteurs et turbines, à l'exception des moteurs d'avions et de véhicules", "parent": "C"}
+{"index": {"_id": "28.12Z"}}
+{"name": "Fabrication d'équipements hydrauliques et pneumatiques", "parent": "C"}
+{"index": {"_id": "28.13Z"}}
+{"name": "Fabrication d'autres pompes et compresseurs", "parent": "C"}
+{"index": {"_id": "28.14Z"}}
+{"name": "Fabrication d'autres articles de robinetterie", "parent": "C"}
+{"index": {"_id": "28.15Z"}}
+{"name": "Fabrication d'engrenages et d'organes mécaniques de transmission", "parent": "C"}
+{"index": {"_id": "28.21Z"}}
+{"name": "Fabrication de fours et brûleurs", "parent": "C"}
+{"index": {"_id": "28.22Z"}}
+{"name": "Fabrication de matériel de levage et de manutention", "parent": "C"}
+{"index": {"_id": "28.23Z"}}
+{"name": "Fabrication de machines et d'équipements de bureau (à l'exception des ordinateurs et équipements périphériques)", "parent": "C"}
+{"index": {"_id": "28.24Z"}}
+{"name": "Fabrication d'outillage portatif à moteur incorporé", "parent": "C"}
+{"index": {"_id": "28.25Z"}}
+{"name": "Fabrication d'équipements aérauliques et frigorifiques industriels", "parent": "C"}
+{"index": {"_id": "28.29A"}}
+{"name": "Fabrication d'équipements d'emballage, de conditionnement et de pesage", "parent": "C"}
+{"index": {"_id": "28.29B"}}
+{"name": "Fabrication d'autres machines d'usage général", "parent": "C"}
+{"index": {"_id": "28.30Z"}}
+{"name": "Fabrication de machines agricoles et forestières", "parent": "C"}
+{"index": {"_id": "28.41Z"}}
+{"name": "Fabrication de machines-outils pour le travail des métaux", "parent": "C"}
+{"index": {"_id": "28.49Z"}}
+{"name": "Fabrication d'autres machines-outils", "parent": "C"}
+{"index": {"_id": "28.91Z"}}
+{"name": "Fabrication de machines pour la métallurgie", "parent": "C"}
+{"index": {"_id": "28.92Z"}}
+{"name": "Fabrication de machines pour l'extraction ou la construction", "parent": "C"}
+{"index": {"_id": "28.93Z"}}
+{"name": "Fabrication de machines pour l'industrie agro-alimentaire", "parent": "C"}
+{"index": {"_id": "28.94Z"}}
+{"name": "Fabrication de machines pour les industries textiles", "parent": "C"}
+{"index": {"_id": "28.95Z"}}
+{"name": "Fabrication de machines pour les industries du papier et du carton", "parent": "C"}
+{"index": {"_id": "28.96Z"}}
+{"name": "Fabrication de machines pour le travail du caoutchouc ou des plastiques", "parent": "C"}
+{"index": {"_id": "28.99A"}}
+{"name": "Fabrication de machines d'imprimerie", "parent": "C"}
+{"index": {"_id": "28.99B"}}
+{"name": "Fabrication d'autres machines spécialisées", "parent": "C"}
+{"index": {"_id": "29.10Z"}}
+{"name": "Construction de véhicules automobiles", "parent": "C"}
+{"index": {"_id": "29.20Z"}}
+{"name": "Fabrication de carrosseries et remorques", "parent": "C"}
+{"index": {"_id": "29.31Z"}}
+{"name": "Fabrication d'équipements électriques et électroniques automobiles", "parent": "C"}
+{"index": {"_id": "29.32Z"}}
+{"name": "Fabrication d'autres équipements automobiles", "parent": "C"}
+{"index": {"_id": "30.11Z"}}
+{"name": "Construction de navires et de structures flottantes", "parent": "C"}
+{"index": {"_id": "30.12Z"}}
+{"name": "Construction de bateaux de plaisance", "parent": "C"}
+{"index": {"_id": "30.20Z"}}
+{"name": "Construction de locomotives et d'autre matériel ferroviaire roulant", "parent": "C"}
+{"index": {"_id": "30.30Z"}}
+{"name": "Construction aéronautique et spatiale", "parent": "C"}
+{"index": {"_id": "30.40Z"}}
+{"name": "Construction de véhicules militaires de combat", "parent": "C"}
+{"index": {"_id": "30.91Z"}}
+{"name": "Fabrication de motocycles", "parent": "C"}
+{"index": {"_id": "30.92Z"}}
+{"name": "Fabrication de bicyclettes et de véhicules pour invalides", "parent": "C"}
+{"index": {"_id": "30.99Z"}}
+{"name": "Fabrication d'autres équipements de transport n.c.a.", "parent": "C"}
+{"index": {"_id": "31.01Z"}}
+{"name": "Fabrication de meubles de bureau et de magasin", "parent": "C"}
+{"index": {"_id": "31.02Z"}}
+{"name": "Fabrication de meubles de cuisine", "parent": "C"}
+{"index": {"_id": "31.03Z"}}
+{"name": "Fabrication de matelas", "parent": "C"}
+{"index": {"_id": "31.09A"}}
+{"name": "Fabrication de sièges d'ameublement d'intérieur", "parent": "C"}
+{"index": {"_id": "31.09B"}}
+{"name": "Fabrication d'autres meubles et industries connexes de l'ameublement", "parent": "C"}
+{"index": {"_id": "32.11Z"}}
+{"name": "Frappe de monnaie", "parent": "C"}
+{"index": {"_id": "32.12Z"}}
+{"name": "Fabrication d'articles de joaillerie et bijouterie", "parent": "C"}
+{"index": {"_id": "32.13Z"}}
+{"name": "Fabrication d'articles de bijouterie fantaisie et articles similaires", "parent": "C"}
+{"index": {"_id": "32.20Z"}}
+{"name": "Fabrication d'instruments de musique", "parent": "C"}
+{"index": {"_id": "32.30Z"}}
+{"name": "Fabrication d'articles de sport", "parent": "C"}
+{"index": {"_id": "32.40Z"}}
+{"name": "Fabrication de jeux et jouets", "parent": "C"}
+{"index": {"_id": "32.50A"}}
+{"name": "Fabrication de matériel médico-chirurgical et dentaire", "parent": "C"}
+{"index": {"_id": "32.50B"}}
+{"name": "Fabrication de lunettes", "parent": "C"}
+{"index": {"_id": "32.91Z"}}
+{"name": "Fabrication d'articles de brosserie", "parent": "C"}
+{"index": {"_id": "32.99Z"}}
+{"name": "Autres activités manufacturières n.c.a.", "parent": "C"}
+{"index": {"_id": "33.11Z"}}
+{"name": "Réparation d'ouvrages en métaux", "parent": "C"}
+{"index": {"_id": "33.12Z"}}
+{"name": "Réparation de machines et équipements mécaniques", "parent": "C"}
+{"index": {"_id": "33.13Z"}}
+{"name": "Réparation de matériels électroniques et optiques", "parent": "C"}
+{"index": {"_id": "33.14Z"}}
+{"name": "Réparation d'équipements électriques", "parent": "C"}
+{"index": {"_id": "33.15Z"}}
+{"name": "Réparation et maintenance navale", "parent": "C"}
+{"index": {"_id": "33.16Z"}}
+{"name": "Réparation et maintenance d'aéronefs et d'engins spatiaux", "parent": "C"}
+{"index": {"_id": "33.17Z"}}
+{"name": "Réparation et maintenance d'autres équipements de transport", "parent": "C"}
+{"index": {"_id": "33.19Z"}}
+{"name": "Réparation d'autres équipements", "parent": "C"}
+{"index": {"_id": "33.20A"}}
+{"name": "Installation de structures métalliques, chaudronnées et de tuyauterie", "parent": "C"}
+{"index": {"_id": "33.20B"}}
+{"name": "Installation de machines et équipements mécaniques", "parent": "C"}
+{"index": {"_id": "33.20C"}}
+{"name": "Conception d'ensemble et assemblage sur site industriel d'équipements de contrôle des processus industriels", "parent": "C"}
+{"index": {"_id": "33.20D"}}
+{"name": "Installation d'équipements électriques, de matériels électroniques et optiques ou d'autres matériels", "parent": "C"}
+{"index": {"_id": "D"}}
+{"name": "Production et distribution d'électricité, de gaz, de vapeur et d'air conditionné", "parent": null}
+{"index": {"_id": "35.11Z"}}
+{"name": "Production d'électricité", "parent": "D"}
+{"index": {"_id": "35.12Z"}}
+{"name": "Transport d'électricité", "parent": "D"}
+{"index": {"_id": "35.13Z"}}
+{"name": "Distribution d'électricité", "parent": "D"}
+{"index": {"_id": "35.14Z"}}
+{"name": "Commerce d'électricité", "parent": "D"}
+{"index": {"_id": "35.21Z"}}
+{"name": "Production de combustibles gazeux", "parent": "D"}
+{"index": {"_id": "35.22Z"}}
+{"name": "Distribution de combustibles gazeux par conduites", "parent": "D"}
+{"index": {"_id": "35.23Z"}}
+{"name": "Commerce de combustibles gazeux par conduites", "parent": "D"}
+{"index": {"_id": "35.30Z"}}
+{"name": "Production et distribution de vapeur et d'air conditionné", "parent": "D"}
+{"index": {"_id": "E"}}
+{"name": "Production et distribution d'eau ; assainissement, gestion des déchets et dépollution", "parent": null}
+{"index": {"_id": "36.00Z"}}
+{"name": "Captage, traitement et distribution d'eau", "parent": "E"}
+{"index": {"_id": "37.00Z"}}
+{"name": "Collecte et traitement des eaux usées", "parent": "E"}
+{"index": {"_id": "38.11Z"}}
+{"name": "Collecte des déchets non dangereux", "parent": "E"}
+{"index": {"_id": "38.12Z"}}
+{"name": "Collecte des déchets dangereux", "parent": "E"}
+{"index": {"_id": "38.21Z"}}
+{"name": "Traitement et élimination des déchets non dangereux", "parent": "E"}
+{"index": {"_id": "38.22Z"}}
+{"name": "Traitement et élimination des déchets dangereux", "parent": "E"}
+{"index": {"_id": "38.31Z"}}
+{"name": "Démantèlement d'épaves", "parent": "E"}
+{"index": {"_id": "38.32Z"}}
+{"name": "Récupération de déchets triés", "parent": "E"}
+{"index": {"_id": "39.00Z"}}
+{"name": "Dépollution et autres services de gestion des déchets", "parent": "E"}
+{"index": {"_id": "F"}}
+{"name": "Construction", "parent": null}
+{"index": {"_id": "41.10A"}}
+{"name": "Promotion immobilière de logements", "parent": "F"}
+{"index": {"_id": "41.10B"}}
+{"name": "Promotion immobilière de bureaux", "parent": "F"}
+{"index": {"_id": "41.10C"}}
+{"name": "Promotion immobilière d'autres bâtiments", "parent": "F"}
+{"index": {"_id": "41.10D"}}
+{"name": "Supports juridiques de programmes", "parent": "F"}
+{"index": {"_id": "41.20A"}}
+{"name": "Construction de maisons individuelles", "parent": "F"}
+{"index": {"_id": "41.20B"}}
+{"name": "Construction d'autres bâtiments", "parent": "F"}
+{"index": {"_id": "42.11Z"}}
+{"name": "Construction de routes et autoroutes", "parent": "F"}
+{"index": {"_id": "42.12Z"}}
+{"name": "Construction de voies ferrées de surface et souterraines", "parent": "F"}
+{"index": {"_id": "42.13A"}}
+{"name": "Construction d'ouvrages d'art", "parent": "F"}
+{"index": {"_id": "42.13B"}}
+{"name": "Construction et entretien de tunnels", "parent": "F"}
+{"index": {"_id": "42.21Z"}}
+{"name": "Construction de réseaux pour fluides", "parent": "F"}
+{"index": {"_id": "42.22Z"}}
+{"name": "Construction de réseaux électriques et de télécommunications", "parent": "F"}
+{"index": {"_id": "42.91Z"}}
+{"name": "Construction d'ouvrages maritimes et fluviaux", "parent": "F"}
+{"index": {"_id": "42.99Z"}}
+{"name": "Construction d'autres ouvrages de génie civil n.c.a.", "parent": "F"}
+{"index": {"_id": "43.11Z"}}
+{"name": "Travaux de démolition", "parent": "F"}
+{"index": {"_id": "43.12A"}}
+{"name": "Travaux de terrassement courants et travaux préparatoires", "parent": "F"}
+{"index": {"_id": "43.12B"}}
+{"name": "Travaux de terrassement spécialisés ou de grande masse", "parent": "F"}
+{"index": {"_id": "43.13Z"}}
+{"name": "Forages et sondages", "parent": "F"}
+{"index": {"_id": "43.21A"}}
+{"name": "Travaux d'installation électrique dans tous locaux", "parent": "F"}
+{"index": {"_id": "43.21B"}}
+{"name": "Travaux d'installation électrique sur la voie publique", "parent": "F"}
+{"index": {"_id": "43.22A"}}
+{"name": "Travaux d'installation d'eau et de gaz en tous locaux", "parent": "F"}
+{"index": {"_id": "43.22B"}}
+{"name": "Travaux d'installation d'équipements thermiques et de climatisation", "parent": "F"}
+{"index": {"_id": "43.29A"}}
+{"name": "Travaux d'isolation", "parent": "F"}
+{"index": {"_id": "43.29B"}}
+{"name": "Autres travaux d'installation n.c.a.", "parent": "F"}
+{"index": {"_id": "43.31Z"}}
+{"name": "Travaux de plâtrerie", "parent": "F"}
+{"index": {"_id": "43.32A"}}
+{"name": "Travaux de menuiserie bois et PVC", "parent": "F"}
+{"index": {"_id": "43.32B"}}
+{"name": "Travaux de menuiserie métallique et serrurerie", "parent": "F"}
+{"index": {"_id": "43.32C"}}
+{"name": "Agencement de lieux de vente", "parent": "F"}
+{"index": {"_id": "43.33Z"}}
+{"name": "Travaux de revêtement des sols et des murs", "parent": "F"}
+{"index": {"_id": "43.34Z"}}
+{"name": "Travaux de peinture et vitrerie", "parent": "F"}
+{"index": {"_id": "43.39Z"}}
+{"name": "Autres travaux de finition", "parent": "F"}
+{"index": {"_id": "43.91A"}}
+{"name": "Travaux de charpente", "parent": "F"}
+{"index": {"_id": "43.91B"}}
+{"name": "Travaux de couverture par éléments", "parent": "F"}
+{"index": {"_id": "43.99A"}}
+{"name": "Travaux d'étanchéification", "parent": "F"}
+{"index": {"_id": "43.99B"}}
+{"name": "Travaux de montage de structures métalliques", "parent": "F"}
+{"index": {"_id": "43.99C"}}
+{"name": "Travaux de maçonnerie générale et gros œuvre de bâtiment", "parent": "F"}
+{"index": {"_id": "43.99D"}}
+{"name": "Autres travaux spécialisés de construction", "parent": "F"}
+{"index": {"_id": "43.99E"}}
+{"name": "Location avec opérateur de matériel de construction", "parent": "F"}
+{"index": {"_id": "G"}}
+{"name": "Commerce ; réparation d'automobiles et de motocycles", "parent": null}
+{"index": {"_id": "45.11Z"}}
+{"name": "Commerce de voitures et de véhicules automobiles légers", "parent": "G"}
+{"index": {"_id": "45.19Z"}}
+{"name": "Commerce d'autres véhicules automobiles", "parent": "G"}
+{"index": {"_id": "45.20A"}}
+{"name": "Entretien et réparation de véhicules automobiles légers", "parent": "G"}
+{"index": {"_id": "45.20B"}}
+{"name": "Entretien et réparation d'autres véhicules automobiles", "parent": "G"}
+{"index": {"_id": "45.31Z"}}
+{"name": "Commerce de gros d'équipements automobiles", "parent": "G"}
+{"index": {"_id": "45.32Z"}}
+{"name": "Commerce de détail d'équipements automobiles", "parent": "G"}
+{"index": {"_id": "45.40Z"}}
+{"name": "Commerce et réparation de motocycles", "parent": "G"}
+{"index": {"_id": "46.11Z"}}
+{"name": "Intermédiaires du commerce en matières premières agricoles, animaux vivants, matières premières textiles et produits semi-finis", "parent": "G"}
+{"index": {"_id": "46.12A"}}
+{"name": "Centrales d'achat de carburant", "parent": "G"}
+{"index": {"_id": "46.12B"}}
+{"name": "Autres intermédiaires du commerce en combustibles, métaux, minéraux et produits chimiques", "parent": "G"}
+{"index": {"_id": "46.13Z"}}
+{"name": "Intermédiaires du commerce en bois et matériaux de construction", "parent": "G"}
+{"index": {"_id": "46.14Z"}}
+{"name": "Intermédiaires du commerce en machines, équipements industriels, navires et avions", "parent": "G"}
+{"index": {"_id": "46.15Z"}}
+{"name": "Intermédiaires du commerce en meubles, articles de ménage et quincaillerie", "parent": "G"}
+{"index": {"_id": "46.16Z"}}
+{"name": "Intermédiaires du commerce en textiles, habillement, fourrures, chaussures et articles en cuir", "parent": "G"}
+{"index": {"_id": "46.17A"}}
+{"name": "Centrales d'achat alimentaires", "parent": "G"}
+{"index": {"_id": "46.17B"}}
+{"name": "Autres intermédiaires du commerce en denrées, boissons et tabac", "parent": "G"}
+{"index": {"_id": "46.18Z"}}
+{"name": "Intermédiaires spécialisés dans le commerce d'autres produits spécifiques", "parent": "G"}
+{"index": {"_id": "46.19A"}}
+{"name": "Centrales d'achat non alimentaires", "parent": "G"}
+{"index": {"_id": "46.19B"}}
+{"name": "Autres intermédiaires du commerce en produits divers", "parent": "G"}
+{"index": {"_id": "46.21Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de céréales, de tabac non manufacturé, de semences et d'aliments pour le bétail", "parent": "G"}
+{"index": {"_id": "46.22Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de fleurs et plantes", "parent": "G"}
+{"index": {"_id": "46.23Z"}}
+{"name": "Commerce de gros (commerce interentreprises) d'animaux vivants", "parent": "G"}
+{"index": {"_id": "46.24Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de cuirs et peaux", "parent": "G"}
+{"index": {"_id": "46.31Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de fruits et légumes", "parent": "G"}
+{"index": {"_id": "46.32A"}}
+{"name": "Commerce de gros (commerce interentreprises) de viandes de boucherie", "parent": "G"}
+{"index": {"_id": "46.32B"}}
+{"name": "Commerce de gros (commerce interentreprises) de produits à base de viande", "parent": "G"}
+{"index": {"_id": "46.32C"}}
+{"name": "Commerce de gros (commerce interentreprises) de volailles et gibier", "parent": "G"}
+{"index": {"_id": "46.33Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de produits laitiers, œufs, huiles et matières grasses comestibles", "parent": "G"}
+{"index": {"_id": "46.34Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de boissons", "parent": "G"}
+{"index": {"_id": "46.35Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de produits à base de tabac", "parent": "G"}
+{"index": {"_id": "46.36Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de sucre, chocolat et confiserie", "parent": "G"}
+{"index": {"_id": "46.37Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de café, thé, cacao et épices", "parent": "G"}
+{"index": {"_id": "46.38A"}}
+{"name": "Commerce de gros (commerce interentreprises) de poissons, crustacés et mollusques", "parent": "G"}
+{"index": {"_id": "46.38B"}}
+{"name": "Commerce de gros (commerce interentreprises) alimentaire spécialisé divers", "parent": "G"}
+{"index": {"_id": "46.39A"}}
+{"name": "Commerce de gros (commerce interentreprises) de produits surgelés", "parent": "G"}
+{"index": {"_id": "46.39B"}}
+{"name": "Commerce de gros (commerce interentreprises) alimentaire non spécialisé", "parent": "G"}
+{"index": {"_id": "46.41Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de textiles", "parent": "G"}
+{"index": {"_id": "46.42Z"}}
+{"name": "Commerce de gros (commerce interentreprises) d'habillement et de chaussures", "parent": "G"}
+{"index": {"_id": "46.43Z"}}
+{"name": "Commerce de gros (commerce interentreprises) d'appareils électroménagers", "parent": "G"}
+{"index": {"_id": "46.44Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de vaisselle, verrerie et produits d'entretien", "parent": "G"}
+{"index": {"_id": "46.45Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de parfumerie et de produits de beauté", "parent": "G"}
+{"index": {"_id": "46.46Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de produits pharmaceutiques", "parent": "G"}
+{"index": {"_id": "46.47Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de meubles, de tapis et d'appareils d'éclairage", "parent": "G"}
+{"index": {"_id": "46.48Z"}}
+{"name": "Commerce de gros (commerce interentreprises) d'articles d'horlogerie et de bijouterie", "parent": "G"}
+{"index": {"_id": "46.49Z"}}
+{"name": "Commerce de gros (commerce interentreprises) d'autres biens domestiques", "parent": "G"}
+{"index": {"_id": "46.51Z"}}
+{"name": "Commerce de gros (commerce interentreprises) d'ordinateurs, d'équipements informatiques périphériques et de logiciels", "parent": "G"}
+{"index": {"_id": "46.52Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de composants et d'équipements électroniques et de télécommunication", "parent": "G"}
+{"index": {"_id": "46.61Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de matériel agricole", "parent": "G"}
+{"index": {"_id": "46.62Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de machines-outils", "parent": "G"}
+{"index": {"_id": "46.63Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de machines pour l'extraction, la construction et le génie civil", "parent": "G"}
+{"index": {"_id": "46.64Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de machines pour l'industrie textile et l'habillement", "parent": "G"}
+{"index": {"_id": "46.65Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de mobilier de bureau", "parent": "G"}
+{"index": {"_id": "46.66Z"}}
+{"name": "Commerce de gros (commerce interentreprises) d'autres machines et équipements de bureau", "parent": "G"}
+{"index": {"_id": "46.69A"}}
+{"name": "Commerce de gros (commerce interentreprises) de matériel électrique", "parent": "G"}
+{"index": {"_id": "46.69B"}}
+{"name": "Commerce de gros (commerce interentreprises) de fournitures et équipements industriels divers", "parent": "G"}
+{"index": {"_id": "46.69C"}}
+{"name": "Commerce de gros (commerce interentreprises) de fournitures et équipements divers pour le commerce et les services", "parent": "G"}
+{"index": {"_id": "46.71Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de combustibles et de produits annexes", "parent": "G"}
+{"index": {"_id": "46.72Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de minerais et métaux", "parent": "G"}
+{"index": {"_id": "46.73A"}}
+{"name": "Commerce de gros (commerce interentreprises) de bois et de matériaux de construction", "parent": "G"}
+{"index": {"_id": "46.73B"}}
+{"name": "Commerce de gros (commerce interentreprises) d'appareils sanitaires et de produits de décoration", "parent": "G"}
+{"index": {"_id": "46.74A"}}
+{"name": "Commerce de gros (commerce interentreprises) de quincaillerie", "parent": "G"}
+{"index": {"_id": "46.74B"}}
+{"name": "Commerce de gros (commerce interentreprises) de fournitures pour la plomberie et le chauffage", "parent": "G"}
+{"index": {"_id": "46.75Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de produits chimiques", "parent": "G"}
+{"index": {"_id": "46.76Z"}}
+{"name": "Commerce de gros (commerce interentreprises) d'autres produits intermédiaires", "parent": "G"}
+{"index": {"_id": "46.77Z"}}
+{"name": "Commerce de gros (commerce interentreprises) de déchets et débris", "parent": "G"}
+{"index": {"_id": "46.90Z"}}
+{"name": "Commerce de gros (commerce interentreprises) non spécialisé", "parent": "G"}
+{"index": {"_id": "47.11A"}}
+{"name": "Commerce de détail de produits surgelés", "parent": "G"}
+{"index": {"_id": "47.11B"}}
+{"name": "Commerce d'alimentation générale", "parent": "G"}
+{"index": {"_id": "47.11C"}}
+{"name": "Supérettes", "parent": "G"}
+{"index": {"_id": "47.11D"}}
+{"name": "Supermarchés", "parent": "G"}
+{"index": {"_id": "47.11E"}}
+{"name": "Magasins multi-commerces", "parent": "G"}
+{"index": {"_id": "47.11F"}}
+{"name": "Hypermarchés", "parent": "G"}
+{"index": {"_id": "47.19A"}}
+{"name": "Grands magasins", "parent": "G"}
+{"index": {"_id": "47.19B"}}
+{"name": "Autres commerces de détail en magasin non spécialisé", "parent": "G"}
+{"index": {"_id": "47.21Z"}}
+{"name": "Commerce de détail de fruits et légumes en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.22Z"}}
+{"name": "Commerce de détail de viandes et de produits à base de viande en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.23Z"}}
+{"name": "Commerce de détail de poissons, crustacés et mollusques en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.24Z"}}
+{"name": "Commerce de détail de pain, pâtisserie et confiserie en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.25Z"}}
+{"name": "Commerce de détail de boissons en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.26Z"}}
+{"name": "Commerce de détail de produits à base de tabac en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.29Z"}}
+{"name": "Autres commerces de détail alimentaires en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.30Z"}}
+{"name": "Commerce de détail de carburants en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.41Z"}}
+{"name": "Commerce de détail d'ordinateurs, d'unités périphériques et de logiciels en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.42Z"}}
+{"name": "Commerce de détail de matériels de télécommunication en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.43Z"}}
+{"name": "Commerce de détail de matériels audio et vidéo en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.51Z"}}
+{"name": "Commerce de détail de textiles en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.52A"}}
+{"name": "Commerce de détail de quincaillerie, peintures et verres en petites surfaces (moins de 400 m²)", "parent": "G"}
+{"index": {"_id": "47.52B"}}
+{"name": "Commerce de détail de quincaillerie, peintures et verres en grandes surfaces (400 m² et plus)", "parent": "G"}
+{"index": {"_id": "47.53Z"}}
+{"name": "Commerce de détail de tapis, moquettes et revêtements de murs et de sols en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.54Z"}}
+{"name": "Commerce de détail d'appareils électroménagers en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.59A"}}
+{"name": "Commerce de détail de meubles", "parent": "G"}
+{"index": {"_id": "47.59B"}}
+{"name": "Commerce de détail d'autres équipements du foyer", "parent": "G"}
+{"index": {"_id": "47.61Z"}}
+{"name": "Commerce de détail de livres en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.62Z"}}
+{"name": "Commerce de détail de journaux et papeterie en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.63Z"}}
+{"name": "Commerce de détail d'enregistrements musicaux et vidéo en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.64Z"}}
+{"name": "Commerce de détail d'articles de sport en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.65Z"}}
+{"name": "Commerce de détail de jeux et jouets en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.71Z"}}
+{"name": "Commerce de détail d'habillement en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.72A"}}
+{"name": "Commerce de détail de la chaussure", "parent": "G"}
+{"index": {"_id": "47.72B"}}
+{"name": "Commerce de détail de maroquinerie et d'articles de voyage", "parent": "G"}
+{"index": {"_id": "47.73Z"}}
+{"name": "Commerce de détail de produits pharmaceutiques en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.74Z"}}
+{"name": "Commerce de détail d'articles médicaux et orthopédiques en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.75Z"}}
+{"name": "Commerce de détail de parfumerie et de produits de beauté en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.76Z"}}
+{"name": "Commerce de détail de fleurs, plantes, graines, engrais, animaux de compagnie et aliments pour ces animaux en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.77Z"}}
+{"name": "Commerce de détail d'articles d'horlogerie et de bijouterie en magasin spécialisé", "parent": "G"}
+{"index": {"_id": "47.78A"}}
+{"name": "Commerces de détail d'optique", "parent": "G"}
+{"index": {"_id": "47.78B"}}
+{"name": "Commerces de détail de charbons et combustibles", "parent": "G"}
+{"index": {"_id": "47.78C"}}
+{"name": "Autres commerces de détail spécialisés divers", "parent": "G"}
+{"index": {"_id": "47.79Z"}}
+{"name": "Commerce de détail de biens d'occasion en magasin", "parent": "G"}
+{"index": {"_id": "47.81Z"}}
+{"name": "Commerce de détail alimentaire sur éventaires et marchés", "parent": "G"}
+{"index": {"_id": "47.82Z"}}
+{"name": "Commerce de détail de textiles, d'habillement et de chaussures sur éventaires et marchés", "parent": "G"}
+{"index": {"_id": "47.89Z"}}
+{"name": "Autres commerces de détail sur éventaires et marchés", "parent": "G"}
+{"index": {"_id": "47.91A"}}
+{"name": "Vente à distance sur catalogue général", "parent": "G"}
+{"index": {"_id": "47.91B"}}
+{"name": "Vente à distance sur catalogue spécialisé", "parent": "G"}
+{"index": {"_id": "47.99A"}}
+{"name": "Vente à domicile", "parent": "G"}
+{"index": {"_id": "47.99B"}}
+{"name": "Vente par automates et autres commerces de détail hors magasin, éventaires ou marchés n.c.a.", "parent": "G"}
+{"index": {"_id": "H"}}
+{"name": "Transports et entreposage", "parent": null}
+{"index": {"_id": "49.10Z"}}
+{"name": "Transport ferroviaire interurbain de voyageurs", "parent": "H"}
+{"index": {"_id": "49.20Z"}}
+{"name": "Transports ferroviaires de fret", "parent": "H"}
+{"index": {"_id": "49.31Z"}}
+{"name": "Transports urbains et suburbains de voyageurs", "parent": "H"}
+{"index": {"_id": "49.32Z"}}
+{"name": "Transports de voyageurs par taxis", "parent": "H"}
+{"index": {"_id": "49.39A"}}
+{"name": "Transports routiers réguliers de voyageurs", "parent": "H"}
+{"index": {"_id": "49.39B"}}
+{"name": "Autres transports routiers de voyageurs", "parent": "H"}
+{"index": {"_id": "49.39C"}}
+{"name": "Téléphériques et remontées mécaniques", "parent": "H"}
+{"index": {"_id": "49.41A"}}
+{"name": "Transports routiers de fret interurbains", "parent": "H"}
+{"index": {"_id": "49.41B"}}
+{"name": "Transports routiers de fret de proximité", "parent": "H"}
+{"index": {"_id": "49.41C"}}
+{"name": "Location de camions avec chauffeur", "parent": "H"}
+{"index": {"_id": "49.42Z"}}
+{"name": "Services de déménagement", "parent": "H"}
+{"index": {"_id": "49.50Z"}}
+{"name": "Transports par conduites", "parent": "H"}
+{"index": {"_id": "50.10Z"}}
+{"name": "Transports maritimes et côtiers de passagers", "parent": "H"}
+{"index": {"_id": "50.20Z"}}
+{"name": "Transports maritimes et côtiers de fret", "parent": "H"}
+{"index": {"_id": "50.30Z"}}
+{"name": "Transports fluviaux de passagers", "parent": "H"}
+{"index": {"_id": "50.40Z"}}
+{"name": "Transports fluviaux de fret", "parent": "H"}
+{"index": {"_id": "51.10Z"}}
+{"name": "Transports aériens de passagers", "parent": "H"}
+{"index": {"_id": "51.21Z"}}
+{"name": "Transports aériens de fret", "parent": "H"}
+{"index": {"_id": "51.22Z"}}
+{"name": "Transports spatiaux", "parent": "H"}
+{"index": {"_id": "52.10A"}}
+{"name": "Entreposage et stockage frigorifique", "parent": "H"}
+{"index": {"_id": "52.10B"}}
+{"name": "Entreposage et stockage non frigorifique", "parent": "H"}
+{"index": {"_id": "52.21Z"}}
+{"name": "Services auxiliaires des transports terrestres", "parent": "H"}
+{"index": {"_id": "52.22Z"}}
+{"name": "Services auxiliaires des transports par eau", "parent": "H"}
+{"index": {"_id": "52.23Z"}}
+{"name": "Services auxiliaires des transports aériens", "parent": "H"}
+{"index": {"_id": "52.24A"}}
+{"name": "Manutention portuaire", "parent": "H"}
+{"index": {"_id": "52.24B"}}
+{"name": "Manutention non portuaire", "parent": "H"}
+{"index": {"_id": "52.29A"}}
+{"name": "Messagerie, fret express", "parent": "H"}
+{"index": {"_id": "52.29B"}}
+{"name": "Affrètement et organisation des transports", "parent": "H"}
+{"index": {"_id": "53.10Z"}}
+{"name": "Activités de poste dans le cadre d'une obligation de service universel", "parent": "H"}
+{"index": {"_id": "53.20Z"}}
+{"name": "Autres activités de poste et de courrier", "parent": "H"}
+{"index": {"_id": "I"}}
+{"name": "Hébergement et restauration", "parent": null}
+{"index": {"_id": "55.10Z"}}
+{"name": "Hôtels et hébergement similaire", "parent": "I"}
+{"index": {"_id": "55.20Z"}}
+{"name": "Hébergement touristique et autre hébergement de courte durée", "parent": "I"}
+{"index": {"_id": "55.30Z"}}
+{"name": "Terrains de camping et parcs pour caravanes ou véhicules de loisirs", "parent": "I"}
+{"index": {"_id": "55.90Z"}}
+{"name": "Autres hébergements", "parent": "I"}
+{"index": {"_id": "56.10A"}}
+{"name": "Restauration traditionnelle", "parent": "I"}
+{"index": {"_id": "56.10B"}}
+{"name": "Cafétérias et autres libres-services", "parent": "I"}
+{"index": {"_id": "56.10C"}}
+{"name": "Restauration de type rapide", "parent": "I"}
+{"index": {"_id": "56.21Z"}}
+{"name": "Services des traiteurs", "parent": "I"}
+{"index": {"_id": "56.29A"}}
+{"name": "Restauration collective sous contrat", "parent": "I"}
+{"index": {"_id": "56.29B"}}
+{"name": "Autres services de restauration n.c.a.", "parent": "I"}
+{"index": {"_id": "56.30Z"}}
+{"name": "Débits de boissons", "parent": "I"}
+{"index": {"_id": "J"}}
+{"name": "Information et communication", "parent": null}
+{"index": {"_id": "58.11Z"}}
+{"name": "Édition de livres", "parent": "J"}
+{"index": {"_id": "58.12Z"}}
+{"name": "Édition de répertoires et de fichiers d'adresses", "parent": "J"}
+{"index": {"_id": "58.13Z"}}
+{"name": "Édition de journaux", "parent": "J"}
+{"index": {"_id": "58.14Z"}}
+{"name": "Édition de revues et périodiques", "parent": "J"}
+{"index": {"_id": "58.19Z"}}
+{"name": "Autres activités d'édition", "parent": "J"}
+{"index": {"_id": "58.21Z"}}
+{"name": "Édition de jeux électroniques", "parent": "J"}
+{"index": {"_id": "58.29A"}}
+{"name": "Édition de logiciels système et de réseau", "parent": "J"}
+{"index": {"_id": "58.29B"}}
+{"name": "Édition de logiciels outils de développement et de langages", "parent": "J"}
+{"index": {"_id": "58.29C"}}
+{"name": "Édition de logiciels applicatifs", "parent": "J"}
+{"index": {"_id": "59.11A"}}
+{"name": "Production de films et de programmes pour la télévision", "parent": "J"}
+{"index": {"_id": "59.11B"}}
+{"name": "Production de films institutionnels et publicitaires", "parent": "J"}
+{"index": {"_id": "59.11C"}}
+{"name": "Production de films pour le cinéma", "parent": "J"}
+{"index": {"_id": "59.12Z"}}
+{"name": "Post-production de films cinématographiques, de vidéo et de programmes de télévision", "parent": "J"}
+{"index": {"_id": "59.13A"}}
+{"name": "Distribution de films cinématographiques", "parent": "J"}
+{"index": {"_id": "59.13B"}}
+{"name": "Édition et distribution vidéo", "parent": "J"}
+{"index": {"_id": "59.14Z"}}
+{"name": "Projection de films cinématographiques", "parent": "J"}
+{"index": {"_id": "59.20Z"}}
+{"name": "Enregistrement sonore et édition musicale", "parent": "J"}
+{"index": {"_id": "60.10Z"}}
+{"name": "Édition et diffusion de programmes radio", "parent": "J"}
+{"index": {"_id": "60.20A"}}
+{"name": "Édition de chaînes généralistes", "parent": "J"}
+{"index": {"_id": "60.20B"}}
+{"name": "Édition de chaînes thématiques", "parent": "J"}
+{"index": {"_id": "61.10Z"}}
+{"name": "Télécommunications filaires", "parent": "J"}
+{"index": {"_id": "61.20Z"}}
+{"name": "Télécommunications sans fil", "parent": "J"}
+{"index": {"_id": "61.30Z"}}
+{"name": "Télécommunications par satellite", "parent": "J"}
+{"index": {"_id": "61.90Z"}}
+{"name": "Autres activités de télécommunication", "parent": "J"}
+{"index": {"_id": "62.01Z"}}
+{"name": "Programmation informatique", "parent": "J"}
+{"index": {"_id": "62.02A"}}
+{"name": "Conseil en systèmes et logiciels informatiques", "parent": "J"}
+{"index": {"_id": "62.02B"}}
+{"name": "Tierce maintenance de systèmes et d'applications informatiques", "parent": "J"}
+{"index": {"_id": "62.03Z"}}
+{"name": "Gestion d'installations informatiques", "parent": "J"}
+{"index": {"_id": "62.09Z"}}
+{"name": "Autres activités informatiques", "parent": "J"}
+{"index": {"_id": "63.11Z"}}
+{"name": "Traitement de données, hébergement et activités connexes", "parent": "J"}
+{"index": {"_id": "63.12Z"}}
+{"name": "Portails Internet", "parent": "J"}
+{"index": {"_id": "63.91Z"}}
+{"name": "Activités des agences de presse", "parent": "J"}
+{"index": {"_id": "63.99Z"}}
+{"name": "Autres services d'information n.c.a.", "parent": "J"}
+{"index": {"_id": "K"}}
+{"name": "Activités financières et d'assurance", "parent": null}
+{"index": {"_id": "64.11Z"}}
+{"name": "Activités de banque centrale", "parent": "K"}
+{"index": {"_id": "64.19Z"}}
+{"name": "Autres intermédiations monétaires", "parent": "K"}
+{"index": {"_id": "64.20Z"}}
+{"name": "Activités des sociétés holding", "parent": "K"}
+{"index": {"_id": "64.30Z"}}
+{"name": "Fonds de placement et entités financières similaires", "parent": "K"}
+{"index": {"_id": "64.91Z"}}
+{"name": "Crédit-bail", "parent": "K"}
+{"index": {"_id": "64.92Z"}}
+{"name": "Autre distribution de crédit", "parent": "K"}
+{"index": {"_id": "64.99Z"}}
+{"name": "Autres activités des services financiers, hors assurance et caisses de retraite, n.c.a.", "parent": "K"}
+{"index": {"_id": "65.11Z"}}
+{"name": "Assurance vie", "parent": "K"}
+{"index": {"_id": "65.12Z"}}
+{"name": "Autres assurances", "parent": "K"}
+{"index": {"_id": "65.20Z"}}
+{"name": "Réassurance", "parent": "K"}
+{"index": {"_id": "65.30Z"}}
+{"name": "Caisses de retraite", "parent": "K"}
+{"index": {"_id": "66.11Z"}}
+{"name": "Administration de marchés financiers", "parent": "K"}
+{"index": {"_id": "66.12Z"}}
+{"name": "Courtage de valeurs mobilières et de marchandises", "parent": "K"}
+{"index": {"_id": "66.19A"}}
+{"name": "Supports juridiques de gestion de patrimoine mobilier", "parent": "K"}
+{"index": {"_id": "66.19B"}}
+{"name": "Autres activités auxiliaires de services financiers, hors assurance et caisses de retraite, n.c.a.", "parent": "K"}
+{"index": {"_id": "66.21Z"}}
+{"name": "Évaluation des risques et dommages", "parent": "K"}
+{"index": {"_id": "66.22Z"}}
+{"name": "Activités des agents et courtiers d'assurances", "parent": "K"}
+{"index": {"_id": "66.29Z"}}
+{"name": "Autres activités auxiliaires d'assurance et de caisses de retraite", "parent": "K"}
+{"index": {"_id": "66.30Z"}}
+{"name": "Gestion de fonds", "parent": "K"}
+{"index": {"_id": "L"}}
+{"name": "Activités immobilières", "parent": null}
+{"index": {"_id": "68.10Z"}}
+{"name": "Activités des marchands de biens immobiliers", "parent": "L"}
+{"index": {"_id": "68.20A"}}
+{"name": "Location de logements", "parent": "L"}
+{"index": {"_id": "68.20B"}}
+{"name": "Location de terrains et d'autres biens immobiliers", "parent": "L"}
+{"index": {"_id": "68.31Z"}}
+{"name": "Agences immobilières", "parent": "L"}
+{"index": {"_id": "68.32A"}}
+{"name": "Administration d'immeubles et autres biens immobiliers", "parent": "L"}
+{"index": {"_id": "68.32B"}}
+{"name": "Supports juridiques de gestion de patrimoine immobilier", "parent": "L"}
+{"index": {"_id": "M"}}
+{"name": "Activités spécialisées, scientifiques et techniques", "parent": null}
+{"index": {"_id": "69.10Z"}}
+{"name": "Activités juridiques", "parent": "M"}
+{"index": {"_id": "69.20Z"}}
+{"name": "Activités comptables", "parent": "M"}
+{"index": {"_id": "70.10Z"}}
+{"name": "Activités des sièges sociaux", "parent": "M"}
+{"index": {"_id": "70.21Z"}}
+{"name": "Conseil en relations publiques et communication", "parent": "M"}
+{"index": {"_id": "70.22Z"}}
+{"name": "Conseil pour les affaires et autres conseils de gestion", "parent": "M"}
+{"index": {"_id": "71.11Z"}}
+{"name": "Activités d'architecture", "parent": "M"}
+{"index": {"_id": "71.12A"}}
+{"name": "Activité des géomètres", "parent": "M"}
+{"index": {"_id": "71.12B"}}
+{"name": "Ingénierie, études techniques", "parent": "M"}
+{"index": {"_id": "71.20A"}}
+{"name": "Contrôle technique automobile", "parent": "M"}
+{"index": {"_id": "71.20B"}}
+{"name": "Analyses, essais et inspections techniques", "parent": "M"}
+{"index": {"_id": "72.11Z"}}
+{"name": "Recherche-développement en biotechnologie", "parent": "M"}
+{"index": {"_id": "72.19Z"}}
+{"name": "Recherche-développement en autres sciences physiques et naturelles", "parent": "M"}
+{"index": {"_id": "72.20Z"}}
+{"name": "Recherche-développement en sciences humaines et sociales", "parent": "M"}
+{"index": {"_id": "73.11Z"}}
+{"name": "Activités des agences de publicité", "parent": "M"}
+{"index": {"_id": "73.12Z"}}
+{"name": "Régie publicitaire de médias", "parent": "M"}
+{"index": {"_id": "73.20Z"}}
+{"name": "Études de marché et sondages", "parent": "M"}
+{"index": {"_id": "74.10Z"}}
+{"name": "Activités spécialisées de design", "parent": "M"}
+{"index": {"_id": "74.20Z"}}
+{"name": "Activités photographiques", "parent": "M"}
+{"index": {"_id": "74.30Z"}}
+{"name": "Traduction et interprétation", "parent": "M"}
+{"index": {"_id": "74.90A"}}
+{"name": "Activité des économistes de la construction", "parent": "M"}
+{"index": {"_id": "74.90B"}}
+{"name": "Activités spécialisées, scientifiques et techniques diverses", "parent": "M"}
+{"index": {"_id": "N"}}
+{"name": "Activités de services administratifs et de soutien", "parent": null}
+{"index": {"_id": "75.00Z"}}
+{"name": "Activités vétérinaires", "parent": "N"}
+{"index": {"_id": "77.11A"}}
+{"name": "Location de courte durée de voitures et de véhicules automobiles légers", "parent": "N"}
+{"index": {"_id": "77.11B"}}
+{"name": "Location de longue durée de voitures et de véhicules automobiles légers", "parent": "N"}
+{"index": {"_id": "77.12Z"}}
+{"name": "Location et location-bail de camions", "parent": "N"}
+{"index": {"_id": "77.21Z"}}
+{"name": "Location et location-bail d'articles de loisirs et de sport", "parent": "N"}
+{"index": {"_id": "77.22Z"}}
+{"name": "Location de vidéocassettes et disques vidéo", "parent": "N"}
+{"index": {"_id": "77.29Z"}}
+{"name": "Location et location-bail d'autres biens personnels et domestiques", "parent": "N"}
+{"index": {"_id": "77.31Z"}}
+{"name": "Location et location-bail de machines et équipements agricoles", "parent": "N"}
+{"index": {"_id": "77.32Z"}}
+{"name": "Location et location-bail de machines et équipements pour la construction", "parent": "N"}
+{"index": {"_id": "77.33Z"}}
+{"name": "Location et location-bail de machines de bureau et de matériel informatique", "parent": "N"}
+{"index": {"_id": "77.34Z"}}
+{"name": "Location et location-bail de matériels de transport par eau", "parent": "N"}
+{"index": {"_id": "77.35Z"}}
+{"name": "Location et location-bail de matériels de transport aérien", "parent": "N"}
+{"index": {"_id": "77.39Z"}}
+{"name": "Location et location-bail d'autres machines, équipements et biens matériels n.c.a.", "parent": "N"}
+{"index": {"_id": "77.40Z"}}
+{"name": "Location-bail de propriété intellectuelle et de produits similaires, à l'exception des œuvres soumises à copyright", "parent": "N"}
+{"index": {"_id": "78.10Z"}}
+{"name": "Activités des agences de placement de main-d'œuvre", "parent": "N"}
+{"index": {"_id": "78.20Z"}}
+{"name": "Activités des agences de travail temporaire", "parent": "N"}
+{"index": {"_id": "78.30Z"}}
+{"name": "Autre mise à disposition de ressources humaines", "parent": "N"}
+{"index": {"_id": "79.11Z"}}
+{"name": "Activités des agences de voyage", "parent": "N"}
+{"index": {"_id": "79.12Z"}}
+{"name": "Activités des voyagistes", "parent": "N"}
+{"index": {"_id": "79.90Z"}}
+{"name": "Autres services de réservation et activités connexes", "parent": "N"}
+{"index": {"_id": "80.10Z"}}
+{"name": "Activités de sécurité privée", "parent": "N"}
+{"index": {"_id": "80.20Z"}}
+{"name": "Activités liées aux systèmes de sécurité", "parent": "N"}
+{"index": {"_id": "80.30Z"}}
+{"name": "Activités d'enquête", "parent": "N"}
+{"index": {"_id": "81.10Z"}}
+{"name": "Activités combinées de soutien lié aux bâtiments", "parent": "N"}
+{"index": {"_id": "81.21Z"}}
+{"name": "Nettoyage courant des bâtiments", "parent": "N"}
+{"index": {"_id": "81.22Z"}}
+{"name": "Autres activités de nettoyage des bâtiments et nettoyage industriel", "parent": "N"}
+{"index": {"_id": "81.29A"}}
+{"name": "Désinfection, désinsectisation, dératisation", "parent": "N"}
+{"index": {"_id": "81.29B"}}
+{"name": "Autres activités de nettoyage n.c.a.", "parent": "N"}
+{"index": {"_id": "81.30Z"}}
+{"name": "Services d'aménagement paysager", "parent": "N"}
+{"index": {"_id": "82.11Z"}}
+{"name": "Services administratifs combinés de bureau", "parent": "N"}
+{"index": {"_id": "82.19Z"}}
+{"name": "Photocopie, préparation de documents et autres activités spécialisées de soutien de bureau", "parent": "N"}
+{"index": {"_id": "82.20Z"}}
+{"name": "Activités de centres d'appels", "parent": "N"}
+{"index": {"_id": "82.30Z"}}
+{"name": "Organisation de foires, salons professionnels et congrès", "parent": "N"}
+{"index": {"_id": "82.91Z"}}
+{"name": "Activités des agences de recouvrement de factures et des sociétés d'information financière sur la clientèle", "parent": "N"}
+{"index": {"_id": "82.92Z"}}
+{"name": "Activités de conditionnement", "parent": "N"}
+{"index": {"_id": "82.99Z"}}
+{"name": "Autres activités de soutien aux entreprises n.c.a.", "parent": "N"}
+{"index": {"_id": "O"}}
+{"name": "Administration publique", "parent": null}
+{"index": {"_id": "84.11Z"}}
+{"name": "Administration publique générale", "parent": "O"}
+{"index": {"_id": "84.12Z"}}
+{"name": "Administration publique (tutelle) de la santé, de la formation, de la culture et des services sociaux, autre que sécurité sociale", "parent": "O"}
+{"index": {"_id": "84.13Z"}}
+{"name": "Administration publique (tutelle) des activités économiques", "parent": "O"}
+{"index": {"_id": "84.21Z"}}
+{"name": "Affaires étrangères", "parent": "O"}
+{"index": {"_id": "84.22Z"}}
+{"name": "Défense", "parent": "O"}
+{"index": {"_id": "84.23Z"}}
+{"name": "Justice", "parent": "O"}
+{"index": {"_id": "84.24Z"}}
+{"name": "Activités d'ordre public et de sécurité", "parent": "O"}
+{"index": {"_id": "84.25Z"}}
+{"name": "Services du feu et de secours", "parent": "O"}
+{"index": {"_id": "84.30A"}}
+{"name": "Activités générales de sécurité sociale", "parent": "O"}
+{"index": {"_id": "84.30B"}}
+{"name": "Gestion des retraites complémentaires", "parent": "O"}
+{"index": {"_id": "84.30C"}}
+{"name": "Distribution sociale de revenus", "parent": "O"}
+{"index": {"_id": "P"}}
+{"name": "Enseignement", "parent": null}
+{"index": {"_id": "85.10Z"}}
+{"name": "Enseignement pré-primaire", "parent": "P"}
+{"index": {"_id": "85.20Z"}}
+{"name": "Enseignement primaire", "parent": "P"}
+{"index": {"_id": "85.31Z"}}
+{"name": "Enseignement secondaire général", "parent": "P"}
+{"index": {"_id": "85.32Z"}}
+{"name": "Enseignement secondaire technique ou professionnel", "parent": "P"}
+{"index": {"_id": "85.41Z"}}
+{"name": "Enseignement post-secondaire non supérieur", "parent": "P"}
+{"index": {"_id": "85.42Z"}}
+{"name": "Enseignement supérieur", "parent": "P"}
+{"index": {"_id": "85.51Z"}}
+{"name": "Enseignement de disciplines sportives et d'activités de loisirs", "parent": "P"}
+{"index": {"_id": "85.52Z"}}
+{"name": "Enseignement culturel", "parent": "P"}
+{"index": {"_id": "85.53Z"}}
+{"name": "Enseignement de la conduite", "parent": "P"}
+{"index": {"_id": "85.59A"}}
+{"name": "Formation continue d'adultes", "parent": "P"}
+{"index": {"_id": "85.59B"}}
+{"name": "Autres enseignements", "parent": "P"}
+{"index": {"_id": "85.60Z"}}
+{"name": "Activités de soutien à l'enseignement", "parent": "P"}
+{"index": {"_id": "Q"}}
+{"name": "Santé humaine et action sociale", "parent": null}
+{"index": {"_id": "86.10Z"}}
+{"name": "Activités hospitalières", "parent": "Q"}
+{"index": {"_id": "86.21Z"}}
+{"name": "Activité des médecins généralistes", "parent": "Q"}
+{"index": {"_id": "86.22A"}}
+{"name": "Activités de radiodiagnostic et de radiothérapie", "parent": "Q"}
+{"index": {"_id": "86.22B"}}
+{"name": "Activités chirurgicales", "parent": "Q"}
+{"index": {"_id": "86.22C"}}
+{"name": "Autres activités des médecins spécialistes", "parent": "Q"}
+{"index": {"_id": "86.23Z"}}
+{"name": "Pratique dentaire", "parent": "Q"}
+{"index": {"_id": "86.90A"}}
+{"name": "Ambulances", "parent": "Q"}
+{"index": {"_id": "86.90B"}}
+{"name": "Laboratoires d'analyses médicales", "parent": "Q"}
+{"index": {"_id": "86.90C"}}
+{"name": "Centres de collecte et banques d'organes", "parent": "Q"}
+{"index": {"_id": "86.90D"}}
+{"name": "Activités des infirmiers et des sages-femmes", "parent": "Q"}
+{"index": {"_id": "86.90E"}}
+{"name": "Activités des professionnels de la rééducation, de l'appareillage et des pédicures-podologues", "parent": "Q"}
+{"index": {"_id": "86.90F"}}
+{"name": "Activités de santé humaine non classées ailleurs", "parent": "Q"}
+{"index": {"_id": "87.10A"}}
+{"name": "Hébergement médicalisé pour personnes âgées", "parent": "Q"}
+{"index": {"_id": "87.10B"}}
+{"name": "Hébergement médicalisé pour enfants handicapés", "parent": "Q"}
+{"index": {"_id": "87.10C"}}
+{"name": "Hébergement médicalisé pour adultes handicapés et autre hébergement médicalisé", "parent": "Q"}
+{"index": {"_id": "87.20A"}}
+{"name": "Hébergement social pour handicapés mentaux et malades mentaux", "parent": "Q"}
+{"index": {"_id": "87.20B"}}
+{"name": "Hébergement social pour toxicomanes", "parent": "Q"}
+{"index": {"_id": "87.30A"}}
+{"name": "Hébergement social pour personnes âgées", "parent": "Q"}
+{"index": {"_id": "87.30B"}}
+{"name": "Hébergement social pour handicapés physiques", "parent": "Q"}
+{"index": {"_id": "87.90A"}}
+{"name": "Hébergement social pour enfants en difficultés", "parent": "Q"}
+{"index": {"_id": "87.90B"}}
+{"name": "Hébergement social pour adultes et familles en difficultés et autre hébergement social", "parent": "Q"}
+{"index": {"_id": "88.10A"}}
+{"name": "Aide à domicile", "parent": "Q"}
+{"index": {"_id": "88.10B"}}
+{"name": "Accueil ou accompagnement sans hébergement d'adultes handicapés ou de personnes âgées", "parent": "Q"}
+{"index": {"_id": "88.10C"}}
+{"name": "Aide par le travail", "parent": "Q"}
+{"index": {"_id": "88.91A"}}
+{"name": "Accueil de jeunes enfants", "parent": "Q"}
+{"index": {"_id": "88.91B"}}
+{"name": "Accueil ou accompagnement sans hébergement d'enfants handicapés", "parent": "Q"}
+{"index": {"_id": "88.99A"}}
+{"name": "Autre accueil ou accompagnement sans hébergement d'enfants et d'adolescents", "parent": "Q"}
+{"index": {"_id": "88.99B"}}
+{"name": "Action sociale sans hébergement n.c.a.", "parent": "Q"}
+{"index": {"_id": "R"}}
+{"name": "Arts, spectacles et activités récréatives", "parent": null}
+{"index": {"_id": "90.01Z"}}
+{"name": "Arts du spectacle vivant", "parent": "R"}
+{"index": {"_id": "90.02Z"}}
+{"name": "Activités de soutien au spectacle vivant", "parent": "R"}
+{"index": {"_id": "90.03A"}}
+{"name": "Création artistique relevant des arts plastiques", "parent": "R"}
+{"index": {"_id": "90.03B"}}
+{"name": "Autre création artistique", "parent": "R"}
+{"index": {"_id": "90.04Z"}}
+{"name": "Gestion de salles de spectacles", "parent": "R"}
+{"index": {"_id": "91.01Z"}}
+{"name": "Gestion des bibliothèques et des archives", "parent": "R"}
+{"index": {"_id": "91.02Z"}}
+{"name": "Gestion des musées", "parent": "R"}
+{"index": {"_id": "91.03Z"}}
+{"name": "Gestion des sites et monuments historiques et des attractions touristiques similaires", "parent": "R"}
+{"index": {"_id": "91.04Z"}}
+{"name": "Gestion des jardins botaniques et zoologiques et des réserves naturelles", "parent": "R"}
+{"index": {"_id": "92.00Z"}}
+{"name": "Organisation de jeux de hasard et d'argent", "parent": "R"}
+{"index": {"_id": "93.11Z"}}
+{"name": "Gestion d'installations sportives", "parent": "R"}
+{"index": {"_id": "93.12Z"}}
+{"name": "Activités de clubs de sports", "parent": "R"}
+{"index": {"_id": "93.13Z"}}
+{"name": "Activités des centres de culture physique", "parent": "R"}
+{"index": {"_id": "93.19Z"}}
+{"name": "Autres activités liées au sport", "parent": "R"}
+{"index": {"_id": "93.21Z"}}
+{"name": "Activités des parcs d'attractions et parcs à thèmes", "parent": "R"}
+{"index": {"_id": "93.29Z"}}
+{"name": "Autres activités récréatives et de loisirs", "parent": "R"}
+{"index": {"_id": "S"}}
+{"name": "Autres activités de services", "parent": null}
+{"index": {"_id": "94.11Z"}}
+{"name": "Activités des organisations patronales et consulaires", "parent": "S"}
+{"index": {"_id": "94.12Z"}}
+{"name": "Activités des organisations professionnelles", "parent": "S"}
+{"index": {"_id": "94.20Z"}}
+{"name": "Activités des syndicats de salariés", "parent": "S"}
+{"index": {"_id": "94.91Z"}}
+{"name": "Activités des organisations religieuses", "parent": "S"}
+{"index": {"_id": "94.92Z"}}
+{"name": "Activités des organisations politiques", "parent": "S"}
+{"index": {"_id": "94.99Z"}}
+{"name": "Autres organisations fonctionnant par adhésion volontaire", "parent": "S"}
+{"index": {"_id": "95.11Z"}}
+{"name": "Réparation d'ordinateurs et d'équipements périphériques", "parent": "S"}
+{"index": {"_id": "95.12Z"}}
+{"name": "Réparation d'équipements de communication", "parent": "S"}
+{"index": {"_id": "95.21Z"}}
+{"name": "Réparation de produits électroniques grand public", "parent": "S"}
+{"index": {"_id": "95.22Z"}}
+{"name": "Réparation d'appareils électroménagers et d'équipements pour la maison et le jardin", "parent": "S"}
+{"index": {"_id": "95.23Z"}}
+{"name": "Réparation de chaussures et d'articles en cuir", "parent": "S"}
+{"index": {"_id": "95.24Z"}}
+{"name": "Réparation de meubles et d'équipements du foyer", "parent": "S"}
+{"index": {"_id": "95.25Z"}}
+{"name": "Réparation d'articles d'horlogerie et de bijouterie", "parent": "S"}
+{"index": {"_id": "95.29Z"}}
+{"name": "Réparation d'autres biens personnels et domestiques", "parent": "S"}
+{"index": {"_id": "96.01A"}}
+{"name": "Blanchisserie-teinturerie de gros", "parent": "S"}
+{"index": {"_id": "96.01B"}}
+{"name": "Blanchisserie-teinturerie de détail", "parent": "S"}
+{"index": {"_id": "96.02A"}}
+{"name": "Coiffure", "parent": "S"}
+{"index": {"_id": "96.02B"}}
+{"name": "Soins de beauté", "parent": "S"}
+{"index": {"_id": "96.03Z"}}
+{"name": "Services funéraires", "parent": "S"}
+{"index": {"_id": "96.04Z"}}
+{"name": "Entretien corporel", "parent": "S"}
+{"index": {"_id": "96.09Z"}}
+{"name": "Autres services personnels n.c.a.", "parent": "S"}
+{"index": {"_id": "T"}}
+{"name": "Activités des ménages en tant qu'employeurs ; activités indifférenciées des ménages en tant que producteurs de biens et services pour usage propre", "parent": null}
+{"index": {"_id": "97.00Z"}}
+{"name": "Activités des ménages en tant qu'employeurs de personnel domestique", "parent": "T"}
+{"index": {"_id": "98.10Z"}}
+{"name": "Activités indifférenciées des ménages en tant que producteurs de biens pour usage propre", "parent": "T"}
+{"index": {"_id": "98.20Z"}}
+{"name": "Activités indifférenciées des ménages en tant que producteurs de services pour usage propre", "parent": "T"}
+{"index": {"_id": "U"}}
+{"name": "Activités extra-territoriales", "parent": null}
+{"index": {"_id": "99.00Z"}}
+{"name": "Activités des organisations et organismes extraterritoriaux", "parent": "U"}
diff --git a/duniter4j-es-gchange/src/test/es-home/config/elasticsearch.yml b/duniter4j-es-gchange/src/test/es-home/config/elasticsearch.yml
new file mode 100644
index 0000000000000000000000000000000000000000..828ddbd04543ef810f380ec8e0dbf229e6c2c48c
--- /dev/null
+++ b/duniter4j-es-gchange/src/test/es-home/config/elasticsearch.yml
@@ -0,0 +1,178 @@
+# ======================== Elasticsearch Configuration =========================
+#
+# NOTE: Elasticsearch comes with reasonable defaults for most settings.
+#       Before you set out to tweak and tune the configuration, make sure you
+#       understand what are you trying to accomplish and the consequences.
+#
+# The primary way of configuring a node is via this file. This template lists
+# the most important settings you may want to configure for a production cluster.
+#
+# Please see the documentation for further information on configuration options:
+# <http://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration.html>
+#
+# ---------------------------------- Cluster -----------------------------------
+#
+# Use a descriptive name for your cluster:
+#
+# cluster.name: my-application
+cluster.name: duniter4j-elasticsearch-TEST
+#
+# ------------------------------------ Node ------------------------------------
+#
+# Use a descriptive name for the node:
+#
+# node.name: node-1
+#
+# Add custom attributes to the node:
+#
+# node.rack: r1
+#
+# ----------------------------------- Paths ------------------------------------
+#
+# Path to directory where to store the data (separate multiple locations by comma):
+#
+# path.data: /path/to/data
+#
+# Path to log files:
+#
+# path.logs: /path/to/logs
+#
+# ----------------------------------- Memory -----------------------------------
+#
+# Lock the memory on startup:
+#
+# bootstrap.mlockall: true
+#
+# Make sure that the `ES_HEAP_SIZE` environment variable is set to about half the memory
+# available on the system and that the owner of the process is allowed to use this limit.
+#
+# Elasticsearch performs poorly when the system is swapping the memory.
+#
+# ---------------------------------- Network -----------------------------------
+#
+# Set the bind address to a specific IP (IPv4 or IPv6):
+#
+# network.host: 192.168.233.1
+#
+# Set a custom port for HTTP:
+#
+# http.port: 9200-9300
+
+http.cors.allow-origin: "/.*/"
+http.cors.enabled: true
+
+# Internal transport layer
+#
+# transport.tcp.port: 9210-9220
+#
+# For more information, see the documentation at:
+# <http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-network.html>
+#
+# --------------------------------- Discovery ----------------------------------
+#
+# Pass an initial list of hosts to perform discovery when new node is started:
+# The default list of hosts is ["127.0.0.1", "[::1]"]
+#
+# discovery.zen.ping.unicast.hosts: ["host1", "host2"]
+#discovery.zen.ping.unicast.hosts: ["127.0.0.1", ""]
+#
+# Prevent the "split brain" by configuring the majority of nodes (total number of nodes / 2 + 1):
+#
+# discovery.zen.minimum_master_nodes: 3
+#
+# For more information, see the documentation at:
+# <http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-discovery.html>
+#
+# ---------------------------------- Gateway -----------------------------------
+#
+# Block initial recovery after a full cluster restart until N nodes are started:
+#
+# gateway.recover_after_nodes: 3
+#
+# For more information, see the documentation at:
+# <http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-gateway.html>
+#
+# ---------------------------------- Various -----------------------------------
+#
+# Disable starting multiple nodes on a single system:
+#
+# node.max_local_storage_nodes: 1
+#
+# Require explicit names when deleting indices:
+#
+# rest.destructive_requires_name: true
+
+security.manager.enabled: false
+
+#
+# ---------------------------------- Duniter4j ---------------------------------
+#
+# Disbale duniter4j plugin
+#
+# duniter.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
+#
+# Enabling node blockchain synchronization
+#
+duniter.blockchain.sync.enable: false
+#
+# Duniter node to synchronize
+#
+duniter.host: cgeek.fr
+duniter.port: 9330
+#
+# ---------------------------------- Duniter4j security -------------------------
+#
+duniter.keyring.salt: abc
+duniter.keyring.password: def
+
+# Enable security, to disable HTTP access to the default ES admin API
+#
+duniter.security.enable: false
+#
+# Security token prefix (default: 'duniter-')
+#
+# duniter.auth.token.prefix: duniter-
+#
+# Token validity duration, in seconds (default: 600)
+#
+# duniter.auth.tokenValidityDuration: 3600  # = 1hour
+#
+# ---------------------------------- Duniter4j P2P sync -------------------------
+#
+# Should synchronize data using P2P
+#
+duniter.data.sync.enable: false
+#duniter.data.sync.host: data.duniter.fr
+#duniter.data.sync.port: 80
+
+# ---------------------------------- Duniter4j SMTP server -------------------------
+#
+# SMTP server configuration (host and port)
+#
+#duniter.mail.smtp.host: localhost
+#duniter.mail.smtp.port: 25
+#
+# Mail 'from' address
+#
+#duniter.mail.from: no-reply@domain.com
+duniter.mail.from: root@EIS-DEV
+#
+# Mail: admin address
+#
+#duniter.mail.admin: user@domain.com
+duniter.mail.admin: blavenie@EIS-DEV
+#
+# Mail subject prefix
+#
+#duniter.mail.subject.prefix: [Duniter4j ES]
+
+duniter.changes.listenSource: */block
+duniter.ws.port: 9400
diff --git a/duniter4j-es-gchange/src/test/es-home/config/logging.yml b/duniter4j-es-gchange/src/test/es-home/config/logging.yml
new file mode 100644
index 0000000000000000000000000000000000000000..15cfa3e195cb46a62c7536f118d1684acfcc2ecf
--- /dev/null
+++ b/duniter4j-es-gchange/src/test/es-home/config/logging.yml
@@ -0,0 +1,97 @@
+# you can override this using by setting a system property, for example -Des.logger.level=DEBUG
+es.logger.level: INFO
+rootLogger: ${es.logger.level}, console, file
+logger:
+  # log rest execution errors for easier debugging
+  action: DEBUG
+
+  # deprecation logging, turn to DEBUG to see them
+  deprecation: INFO, deprecation_log_file
+
+  # reduce the logging for aws, too much is logged under the default INFO
+  com.amazonaws: WARN
+  # aws will try to do some sketchy JMX stuff, but its not needed.
+  com.amazonaws.jmx.SdkMBeanRegistrySupport: ERROR
+  com.amazonaws.metrics.AwsSdkMetrics: ERROR
+
+  org.apache.http: INFO
+
+  org.duniter: INFO
+
+  org.duniter.elasticsearch: DEBUG
+
+  duniter : DEBUG
+  duniter.network.p2p: TRACE
+
+  security: DEBUG
+
+  org.nuiton.i18n: WARN
+  org.nuiton.config: WARN
+
+  # gateway
+  #gateway: DEBUG
+  #index.gateway: DEBUG
+
+  # peer shard recovery
+  #indices.recovery: DEBUG
+
+  # discovery
+  #discovery: TRACE
+
+  index.search.slowlog: TRACE, index_search_slow_log_file
+  index.indexing.slowlog: TRACE, index_indexing_slow_log_file
+
+additivity:
+  index.search.slowlog: false
+  index.indexing.slowlog: false
+  deprecation: false
+
+appender:
+  console:
+    type: console
+    layout:
+      type: consolePattern
+      conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
+
+  file:
+    type: dailyRollingFile
+    file: ${path.logs}/${cluster.name}.log
+    datePattern: "'.'yyyy-MM-dd"
+    layout:
+      type: pattern
+      conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %.10000m%n"
+
+  # Use the following log4j-extras RollingFileAppender to enable gzip compression of log files. 
+  # For more information see https://logging.apache.org/log4j/extras/apidocs/org/apache/log4j/rolling/RollingFileAppender.html
+  #file:
+    #type: extrasRollingFile
+    #file: ${path.logs}/${cluster.name}.log
+    #rollingPolicy: timeBased
+    #rollingPolicy.FileNamePattern: ${path.logs}/${cluster.name}.log.%d{yyyy-MM-dd}.gz
+    #layout:
+      #type: pattern
+      #conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
+
+  deprecation_log_file:
+    type: dailyRollingFile
+    file: ${path.logs}/${cluster.name}_deprecation.log
+    datePattern: "'.'yyyy-MM-dd"
+    layout:
+      type: pattern
+      conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
+
+  index_search_slow_log_file:
+    type: dailyRollingFile
+    file: ${path.logs}/${cluster.name}_index_search_slowlog.log
+    datePattern: "'.'yyyy-MM-dd"
+    layout:
+      type: pattern
+      conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
+
+  index_indexing_slow_log_file:
+    type: dailyRollingFile
+    file: ${path.logs}/${cluster.name}_index_indexing_slowlog.log
+    datePattern: "'.'yyyy-MM-dd"
+    layout:
+      type: pattern
+      conversionPattern: "[%d{ISO8601}][%-5p][%-25c] %m%n"
diff --git a/duniter4j-es-gchange/src/test/java/org/duniter/elasticsearch/TestFixtures.java b/duniter4j-es-gchange/src/test/java/org/duniter/elasticsearch/TestFixtures.java
new file mode 100644
index 0000000000000000000000000000000000000000..36f093303027109c68ee24aa3e8d1b763c865daf
--- /dev/null
+++ b/duniter4j-es-gchange/src/test/java/org/duniter/elasticsearch/TestFixtures.java
@@ -0,0 +1,28 @@
+package org.duniter.elasticsearch;
+
+/*
+ * #%L
+ * UCoin Java Client :: ElasticSearch Indexer
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+
+public class TestFixtures extends org.duniter.core.test.TestFixtures {
+
+}
diff --git a/duniter4j-es-gchange/src/test/java/org/duniter/elasticsearch/TestResource.java b/duniter4j-es-gchange/src/test/java/org/duniter/elasticsearch/TestResource.java
new file mode 100644
index 0000000000000000000000000000000000000000..2b27a3e55828026c4e9b37c4a3dba40020e161c4
--- /dev/null
+++ b/duniter4j-es-gchange/src/test/java/org/duniter/elasticsearch/TestResource.java
@@ -0,0 +1,141 @@
+package org.duniter.elasticsearch;
+
+/*
+ * #%L
+ * UCoin Java Client :: Core API
+ * %%
+ * Copyright (C) 2014 - 2015 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+
+import com.google.common.collect.Lists;
+import org.duniter.core.client.config.ConfigurationOption;
+import org.duniter.core.client.service.ServiceLocator;
+import org.apache.commons.io.FileUtils;
+import org.junit.runner.Description;
+import org.nuiton.i18n.I18n;
+import org.nuiton.i18n.init.DefaultI18nInitializer;
+import org.nuiton.i18n.init.UserI18nInitializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Locale;
+
+public class TestResource extends org.duniter.core.test.TestResource {
+
+    private static final Logger log = LoggerFactory.getLogger(TestResource.class);
+
+    public static TestResource create() {
+        return new TestResource(null);
+    }
+    
+    public static TestResource create(String configName) {
+        return new TestResource(configName);
+    }
+
+    private TestFixtures fixtures = new TestFixtures();
+
+    protected TestResource(String configName) {
+        super(configName);
+    }
+    
+    public TestFixtures getFixtures() {
+        return fixtures;
+    }
+
+    protected void before(Description description) throws Throwable {
+        super.before(description);
+
+        // Initialize configuration
+        initConfiguration(getConfigFileName());
+
+        // Init i18n
+        initI18n();
+
+        // Initialize service locator
+        ServiceLocator.instance().init();
+    }
+
+    /**
+     * Return configuration files prefix (i.e. 'allegro-test')
+     * Could be override by external project
+     * 
+     * @return the prefix to use to retrieve configuration files
+     */
+    protected String getConfigFilesPrefix() {
+        return "duniter4j-elasticsearch-test";
+    }
+    
+    protected String getI18nBundleName() {
+        return "duniter4j-elasticsearch-i18n";
+    }
+
+    /* -- -- */
+
+    /**
+     * Convenience methods that could be override to initialize other configuration
+     *
+     * @param configFilename
+     * @param configArgs
+     */
+    protected void initConfiguration(String configFilename) {
+        String[] configArgs = getConfigArgs();
+        //PluginSettings config = new PluginSettings(configFilename, configArgs);
+        //PluginSettings.setInstance(config);
+    }
+
+    protected void initI18n() throws IOException {
+        /*PluginSettings config ;//= PluginSettings.instance();
+
+        // --------------------------------------------------------------------//
+        // init i18n
+        // --------------------------------------------------------------------//
+        File i18nDirectory = new File(config.getDataDirectory(), "i18n");
+        if (i18nDirectory.exists()) {
+            // clean i18n cache
+            FileUtils.cleanDirectory(i18nDirectory);
+        }
+
+        FileUtils.forceMkdir(i18nDirectory);
+
+        if (log.isDebugEnabled()) {
+            log.debug("I18N directory: " + i18nDirectory);
+        }
+
+        Locale i18nLocale = config.getI18nLocale();
+
+        if (log.isInfoEnabled()) {
+            log.info(String.format("Starts i18n with locale [%s] at [%s]",
+                    i18nLocale, i18nDirectory));
+        }
+        I18n.init(new UserI18nInitializer(
+                        i18nDirectory, new DefaultI18nInitializer(getI18nBundleName())),
+                i18nLocale);*/
+    }
+
+    protected String[] getConfigArgs() {
+        List<String> configArgs = Lists.newArrayList();
+        configArgs.addAll(Lists.newArrayList(
+                "--option", ConfigurationOption.BASEDIR.getKey(), getResourceDirectory().getAbsolutePath()));
+        return configArgs.toArray(new String[configArgs.size()]);
+    }
+
+}
diff --git a/duniter4j-es-gchange/src/test/java/org/duniter/elasticsearch/service/BlockchainServiceTest.java b/duniter4j-es-gchange/src/test/java/org/duniter/elasticsearch/service/BlockchainServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..a305ac1b40ff0fca3ed27b843d7c737d1f117d50
--- /dev/null
+++ b/duniter4j-es-gchange/src/test/java/org/duniter/elasticsearch/service/BlockchainServiceTest.java
@@ -0,0 +1,172 @@
+package org.duniter.elasticsearch.service;
+
+/*
+ * #%L
+ * UCoin Java Client :: Core API
+ * %%
+ * Copyright (C) 2014 - 2015 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+
+import org.duniter.core.client.config.Configuration;
+import org.duniter.core.client.model.bma.BlockchainBlock;
+import org.duniter.core.client.model.local.Peer;
+import org.duniter.core.client.service.bma.BlockchainRemoteService;
+import org.duniter.elasticsearch.TestResource;
+import org.junit.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+@Ignore
+public class BlockchainServiceTest {
+
+	private static final Logger log = LoggerFactory.getLogger(BlockchainServiceTest.class);
+
+	@ClassRule
+	public static final TestResource resource = TestResource.create();
+
+    private BlockchainService service;
+    private BlockchainRemoteService blockchainRemoteService;
+    private Configuration config;
+    private Peer peer;
+
+    @Before
+    public void setUp() throws Exception {
+        //service = ServiceLocator.instance().getBlockIndexerService();
+        //blockchainRemoteService = ServiceLocator.instance().getBlockchainRemoteService();
+        config = Configuration.instance();
+        peer = createTestPeer();
+
+        initLocalNode();
+    }
+
+    @Test
+    public void createIndex() throws Exception {
+        String currencyName = resource.getFixtures().getCurrency();
+
+        // drop and recreate index
+        service.deleteIndex(currencyName);
+
+        service.createIndex(currencyName);
+    }
+
+
+    @Test
+	public void indexBlock() throws Exception {
+        // Read a block
+        BlockchainBlock currentBlock = blockchainRemoteService.getCurrentBlock(peer);
+
+        // Create a new non-existing block
+        service.indexBlock(currentBlock, true);
+
+        // Update a existing block
+        {
+            currentBlock.setMembersCount(1000000);
+
+            service.indexBlock(currentBlock, true);
+        }
+	}
+
+    @Test
+    public void indexCurrentBlock() throws Exception {
+        // Create a block with a fake hash
+        BlockchainBlock aBlock = blockchainRemoteService.getBlock(peer, 8450);
+        service.indexCurrentBlock(aBlock, true);
+    }
+
+    @Test
+    // FIXME make this works
+    @Ignore
+    public void searchBlocks() throws Exception {
+        String currencyName = resource.getFixtures().getCurrency();
+
+        // Create a block with a fake hash
+        BlockchainBlock aBlock = blockchainRemoteService.getCurrentBlock(peer);
+        aBlock.setHash("myUnitTestHash");
+        service.saveBlock(aBlock, true, true);
+
+        Thread.sleep(5 * 1000); // wait 5s that ES process the block
+
+        // match multi words
+        String queryText = aBlock.getHash();
+        List<BlockchainBlock> blocks = service.findBlocksByHash(currencyName, queryText);
+        //assertResults(queryText, blocks);
+
+        Thread.sleep(5 * 1000); // wait 5s that ES process the block
+
+        BlockchainBlock loadBlock = service.getBlockById(currencyName, aBlock.getNumber());
+        Assert.assertNotNull(loadBlock);
+        Assert.assertEquals(aBlock.getHash(), loadBlock.getHash());
+    }
+
+    @Test
+    public void getMaxBlockNumber() throws Exception {
+        String currencyName = resource.getFixtures().getCurrency();
+
+        // match multi words
+        Integer maxBlockNumber = service.getMaxBlockNumber(currencyName);
+        Assert.assertNotNull(maxBlockNumber);
+    }
+
+
+    @Test
+    @Ignore
+    public void allInOne() throws Exception {
+
+        createIndex();
+        indexBlock();
+        searchBlocks();
+    }
+
+	/* -- internal methods */
+
+    protected void initLocalNode() throws Exception {
+        String currencyName = resource.getFixtures().getCurrency();
+
+        // Make sure the index exists
+        service.deleteIndex(currencyName);
+        service.createIndex(currencyName);
+
+        // Get the first block from peer
+        BlockchainBlock firstBlock = blockchainRemoteService.getBlock(peer, 0);
+
+        // Make sure the block has been indexed
+        service.indexBlock(firstBlock, true);
+
+    }
+
+    protected void assertResults(String queryText, List<BlockchainBlock> result) {
+        log.info(String.format("Results for a search on [%s]", queryText));
+        Assert.assertNotNull(result);
+        Assert.assertTrue(result.size() > 0);
+        for (BlockchainBlock block: result) {
+            log.info("  - " + block.getNumber());
+        }
+    }
+
+    protected Peer createTestPeer() {
+        Peer peer = new Peer(
+                Configuration.instance().getNodeHost(),
+                Configuration.instance().getNodePort());
+
+        return peer;
+    }
+
+}
diff --git a/duniter4j-elasticsearch/src/test/java/org/duniter/elasticsearch/service/RegistryRecordIndexerServiceTest.java b/duniter4j-es-gchange/src/test/java/org/duniter/elasticsearch/service/RegistryRecordIndexerServiceTest.java
similarity index 96%
rename from duniter4j-elasticsearch/src/test/java/org/duniter/elasticsearch/service/RegistryRecordIndexerServiceTest.java
rename to duniter4j-es-gchange/src/test/java/org/duniter/elasticsearch/service/RegistryRecordIndexerServiceTest.java
index adc4a46c01cb12e9950be99e82a3684051099582..4987281db4a472a7657256319818daccb07a7bd4 100644
--- a/duniter4j-elasticsearch/src/test/java/org/duniter/elasticsearch/service/RegistryRecordIndexerServiceTest.java
+++ b/duniter4j-es-gchange/src/test/java/org/duniter/elasticsearch/service/RegistryRecordIndexerServiceTest.java
@@ -23,6 +23,7 @@ package org.duniter.elasticsearch.service;
  */
 
 import org.duniter.elasticsearch.TestResource;
+import org.duniter.elasticsearch.gchange.service.RegistryService;
 import org.junit.Before;
 import org.junit.ClassRule;
 import org.junit.Ignore;
diff --git a/duniter4j-es-gchange/src/test/resources/META-INF/services/org.duniter.core.beans.Bean b/duniter4j-es-gchange/src/test/resources/META-INF/services/org.duniter.core.beans.Bean
new file mode 100644
index 0000000000000000000000000000000000000000..1d327a744e4eec6703b417254f5b19dfdbc09fa4
--- /dev/null
+++ b/duniter4j-es-gchange/src/test/resources/META-INF/services/org.duniter.core.beans.Bean
@@ -0,0 +1,14 @@
+org.duniter.core.client.service.bma.BlockchainRemoteServiceImpl
+org.duniter.core.client.service.bma.NetworkRemoteServiceImpl
+org.duniter.core.client.service.bma.WotRemoteServiceImpl
+org.duniter.core.client.service.bma.TransactionRemoteServiceImpl
+org.duniter.core.service.Ed25519CryptoServiceImpl
+org.duniter.core.service.MailServiceImpl
+org.duniter.core.client.service.HttpServiceImpl
+org.duniter.core.client.service.DataContext
+org.duniter.core.client.service.local.PeerServiceImpl
+org.duniter.core.client.service.local.CurrencyServiceImpl
+org.duniter.core.client.dao.mem.MemoryCurrencyDaoImpl
+org.duniter.core.client.dao.mem.MemoryPeerDaoImpl
+org.duniter.elasticsearch.service.ElasticSearchService
+org.duniter.elasticsearch.service.registry.CurrencyRegistryService
\ No newline at end of file
diff --git a/duniter4j-es-gchange/src/test/resources/curl_test.sh b/duniter4j-es-gchange/src/test/resources/curl_test.sh
new file mode 100755
index 0000000000000000000000000000000000000000..4f62377a7b20ee747e1a99f1c6ab627e9caa8b35
--- /dev/null
+++ b/duniter4j-es-gchange/src/test/resources/curl_test.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+curl -XPOST "http://data.duniter.fr/market/comment/_search?pretty" -d'
+{
+  "query": {
+        "bool":{
+            "filter": [
+                {"term":{
+                        "record":"AVbieTIAup9uzWgKipsC"
+                    }
+                }
+            ]
+        }
+  }
+}'
+
diff --git a/duniter4j-es-gchange/src/test/resources/duniter4j-elasticsearch-localhost-node.properties b/duniter4j-es-gchange/src/test/resources/duniter4j-elasticsearch-localhost-node.properties
new file mode 100644
index 0000000000000000000000000000000000000000..38d7a5d9655c9a5bb5babc7487d246139417a8ff
--- /dev/null
+++ b/duniter4j-es-gchange/src/test/resources/duniter4j-elasticsearch-localhost-node.properties
@@ -0,0 +1,12 @@
+duniter4j.node.host=metab.ucoin.fr
+duniter4j.node.port=9201
+
+duniter4j.elasticsearch.embedded.enable=false
+duniter4j.elasticsearch.local=fals
+duniter4j.elasticsearch.http.enable=false
+duniter4j.elasticsearch.cluster.name=duniter4j-elacticsearch-test
+
+#duniter4j.elasticsearch.cluster.name=duniter4j-elacticsearch
+
+duniter4j.elasticsearch.host=localhost
+duniter4j.elasticsearch.port=9300
diff --git a/duniter4j-es-gchange/src/test/resources/duniter4j-elasticsearch-test.properties b/duniter4j-es-gchange/src/test/resources/duniter4j-elasticsearch-test.properties
new file mode 100644
index 0000000000000000000000000000000000000000..27e326f1e7a5e4a4ee67c86df9ca03e8c5b6d2df
--- /dev/null
+++ b/duniter4j-es-gchange/src/test/resources/duniter4j-elasticsearch-test.properties
@@ -0,0 +1,16 @@
+duniter4j.node.host=metab.ucoin.fr
+duniter4j.node.port=9201
+
+duniter4j.basedir=target/es-home
+
+#duniter4j.elasticsearch.data
+#duniter4j.elasticsearch.embedded.enable=true
+duniter4j.elasticsearch.local=false
+duniter4j.elasticsearch.http.enable=true
+duniter4j.elasticsearch.cluster.name=duniter4j-elasticsearch
+
+#duniter4j.elasticsearch.cluster.name=duniter4j-elacticsearch
+
+duniter4j.elasticsearch.embedded.enable=false
+duniter4j.elasticsearch.host=192.168.0.5
+duniter4j.elasticsearch.port=9300
diff --git a/duniter4j-es-gchange/src/test/resources/log4j.properties b/duniter4j-es-gchange/src/test/resources/log4j.properties
new file mode 100644
index 0000000000000000000000000000000000000000..2712b72e0f06c247e8b96a4b1265f95105fda739
--- /dev/null
+++ b/duniter4j-es-gchange/src/test/resources/log4j.properties
@@ -0,0 +1,18 @@
+###
+# Global logging configuration
+log4j.rootLogger=ERROR, stdout
+
+# Console output
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %5p (%c:%L) - [%t] %m%n
+
+# duniter4j levels
+log4j.logger.org.duniter=INFO
+#log4j.logger.org.duniter=DEBUG
+log4j.logger.org.duniter.core=WARN
+log4j.logger.org.duniter.elasticsearch=DEBUG
+
+# Other frameworks levels
+log4j.logger.org.elasticsearch=INFO
+
diff --git a/duniter4j-es-gchange/src/test/resources/registry-test-records.json b/duniter4j-es-gchange/src/test/resources/registry-test-records.json
new file mode 100644
index 0000000000000000000000000000000000000000..c9c11c01be29242dca860f9e0e692539c101e07c
--- /dev/null
+++ b/duniter4j-es-gchange/src/test/resources/registry-test-records.json
@@ -0,0 +1,23 @@
+/*
+ * #%L
+ * Duniter4j :: ElasticSearch Plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+{"index": {"_id": "AVOt3cmVo7-63byx1Jow"}}
+{"title": "Benoit Lavenier (kimamila)", "description": "Pasionné de plein de trucs...", "category": "particulier", "location":"Martigné-sur-Mayenne", "pictures": [{"src": "data:image/jpeg;base64,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"}], "issuer": "G2CBgZBPLe6FSFUgpx2Jf1Aqsgta6iib3vmDRA1yLiqU", "hash": "7zPfFwyXGZKYMmLTzVynFGVEwLDfj48a5E3EA2RWtifq", "signature": "CP4p0+Nby/Fs7exp/mlLnOAu8iMJwyLRW6UHkZXZX8q8WbqxHYBRo2uzpcFAT0zEYSig7j3HqYdeoA3MpU1BCQ=="}
diff --git a/duniter4j-es-user/pom.xml b/duniter4j-es-user/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d4f1f5651b7f30c470046df1cf94dcf91e589ec3
--- /dev/null
+++ b/duniter4j-es-user/pom.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>duniter4j</artifactId>
+        <groupId>org.duniter</groupId>
+        <version>0.3.5-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>duniter4j-es-user</artifactId>
+    <packaging>jar</packaging>
+    <name>Duniter4j :: ElasticSearch User plugin</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.duniter</groupId>
+            <artifactId>duniter4j-es-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- Elastic Search -->
+        <dependency>
+            <groupId>org.elasticsearch</groupId>
+            <artifactId>elasticsearch</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/filtered-resources</directory>
+                <filtering>true</filtering>
+                <includes>
+                    <include>*.config</include>
+                    <include>**/*.properties</include>
+                </includes>
+            </resource>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>false</filtering>
+            </resource>
+        </resources>
+
+        <plugins>
+            <plugin>
+                <groupId>org.nuiton.i18n</groupId>
+                <artifactId>i18n-maven-plugin</artifactId>
+
+                <executions>
+                    <execution>
+                        <id>scan-sources</id>
+                        <configuration>
+                            <entries>
+                                <entry>
+                                    <specificGoal>parserValidation</specificGoal>
+                                    <basedir>${maven.src.dir}/main/java/</basedir>
+                                    <includes>
+                                        <param>**/**-validation.xml</param>
+                                    </includes>
+                                </entry>
+                            </entries>
+                        </configuration>
+                        <goals>
+                            <goal>parserJava</goal>
+                            <goal>parserValidation</goal>
+                            <goal>gen</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>make-bundle</id>
+                        <goals>
+                            <goal>bundle</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>assembly-plugin</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <attach>true</attach>
+                            <appendAssemblyId>false</appendAssemblyId>
+                            <finalName>${bundlePrefix}</finalName>
+                            <descriptors>
+                                <descriptor>
+                                    ${basedir}/src/main/assembly/plugin.xml
+                                </descriptor>
+                            </descriptors>
+                            <skipAssembly>${assembly.skip}</skipAssembly>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/duniter4j-es-user/src/main/assembly/plugin.xml b/duniter4j-es-user/src/main/assembly/plugin.xml
new file mode 100644
index 0000000000000000000000000000000000000000..141f9bb56a0c0393ad0f19537ef197805bc5bc18
--- /dev/null
+++ b/duniter4j-es-user/src/main/assembly/plugin.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<assembly>
+    <id>plugin</id>
+
+
+    <formats>
+        <format>zip</format>
+    </formats>
+
+    <includeBaseDirectory>false</includeBaseDirectory>
+
+    <dependencySets>
+        <dependencySet>
+            <outputDirectory>/</outputDirectory>
+            <useProjectArtifact>true</useProjectArtifact>
+            <useTransitiveFiltering>true</useTransitiveFiltering>
+            <excludes>
+                <exclude>org.duniter:duniter4j-es-core</exclude>
+                <exclude>org.elasticsearch:elasticsearch</exclude>
+                <exclude>net.java.dev.jna:jna</exclude>
+                <exclude>com.fasterxml.jackson.core:jackson-core</exclude>
+                <exclude>log4j:log4j</exclude>
+            </excludes>
+        </dependencySet>
+    </dependencySets>
+
+    <fileSets>
+        <fileSet>
+            <includes>
+                <include>LICENSE</include>
+            </includes>
+        </fileSet>
+
+        <fileSet>
+            <directory>target/classes</directory>
+            <outputDirectory/>
+            <includes>
+                <include>plugin-descriptor.properties</include>
+                <include>plugin-security.policy</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+</assembly>
\ No newline at end of file
diff --git a/duniter4j-es-user/src/main/filtered-resources/log4j.properties b/duniter4j-es-user/src/main/filtered-resources/log4j.properties
new file mode 100644
index 0000000000000000000000000000000000000000..7b6667b1facc361ed8b1993869f728e2c01f1799
--- /dev/null
+++ b/duniter4j-es-user/src/main/filtered-resources/log4j.properties
@@ -0,0 +1,32 @@
+
+# Global logging configuration
+log4j.rootLogger=ERROR, stdout, file
+#log4j.rootLogger=ERROR, stdout
+
+# Console output
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %5p %m%n
+
+# Duniter4j levels
+log4j.logger.org.duniter=INFO
+#log4j.logger.org.duniter.core.client=DEBUG
+#log4j.logger.org.duniter.core.client.service=DEBUG
+log4j.logger.org.duniter.elasticsearch=DEBUG
+
+# Other frameworks levels
+log4j.logger.org.nuiton.util=WARN
+log4j.logger.org.nuiton.config=WARN
+log4j.logger.org.nuiton.converter=WARN
+log4j.logger.org.nuiton.i18n=ERROR
+log4j.logger.org.elasticsearch=WARN
+#log4j.logger.org.elasticsearch=INFO
+
+log4j.appender.file=org.apache.log4j.RollingFileAppender
+log4j.appender.file.file=${duniter4j.log.file}
+log4j.appender.file.MaxFileSize=10MB
+log4j.appender.file.MaxBackupIndex=4
+
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d{ISO8601} %5p (%c:%L) - [%t] %m%n
+
diff --git a/duniter4j-es-user/src/main/filtered-resources/plugin-descriptor.properties b/duniter4j-es-user/src/main/filtered-resources/plugin-descriptor.properties
new file mode 100644
index 0000000000000000000000000000000000000000..785b7ddf0ec956453593ec5a48aa641e6578269c
--- /dev/null
+++ b/duniter4j-es-user/src/main/filtered-resources/plugin-descriptor.properties
@@ -0,0 +1,9 @@
+name=duniter4j-es-user
+description=Plugin for Duniter User API
+version=${project.version}
+site=false
+jvm=true
+classname=org.duniter.elasticsearch.user.Plugin
+java.version=1.7
+elasticsearch.version=2.3.3
+isolated=true
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/Plugin.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/Plugin.java
new file mode 100644
index 0000000000000000000000000000000000000000..f1bde795a5cf87a32a28e936046038343f51fb35
--- /dev/null
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/Plugin.java
@@ -0,0 +1,86 @@
+package org.duniter.elasticsearch.user;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import com.google.common.collect.Lists;
+import org.duniter.elasticsearch.PluginInit;
+import org.duniter.elasticsearch.user.service.ServiceModule;
+import org.duniter.elasticsearch.user.rest.RestModule;
+import org.elasticsearch.common.component.LifecycleComponent;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.inject.Module;
+import org.elasticsearch.common.logging.ESLogger;
+import org.elasticsearch.common.logging.ESLoggerFactory;
+import org.elasticsearch.common.settings.Settings;
+
+import java.util.Collection;
+
+public class Plugin extends org.elasticsearch.plugins.Plugin {
+
+    private ESLogger log = ESLoggerFactory.getLogger(Plugin.class.getName());
+
+    private boolean enable;
+
+    @Inject public Plugin(Settings settings) {
+        this.enable = settings.getAsBoolean("duniter.user.enabled", true);
+    }
+
+    @Override
+    public String name() {
+        return "duniter.user";
+    }
+
+    @Override
+    public String description() {
+        return "Duniter ElasticSearch User Plugin";
+    }
+
+    @Override
+    public Collection<Module> nodeModules() {
+        Collection<Module> modules = Lists.newArrayList();
+        if (!enable) {
+            log.warn(description() + " has been disabled.");
+            return modules;
+        }
+
+        modules.add(new RestModule());
+        modules.add(new ServiceModule());
+
+        return modules;
+    }
+
+    @Override
+    public Collection<Class<? extends LifecycleComponent>> nodeServices() {
+        Collection<Class<? extends LifecycleComponent>> components = Lists.newArrayList();
+        if (!enable) {
+            return components;
+        }
+        components.add(PluginSettings.class);
+        components.add(PluginInit.class);
+        return components;
+    }
+
+    /* -- protected methods -- */
+
+
+}
\ No newline at end of file
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/node/DuniterNode.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/PluginInit.java
similarity index 57%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/node/DuniterNode.java
rename to duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/PluginInit.java
index 1f6d9019d64ea18069dc3984e0ac9cc978a568a0..87f044bf233fbc8891f4ead71a9cbd35a70c5889 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/node/DuniterNode.java
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/PluginInit.java
@@ -1,4 +1,4 @@
-package org.duniter.elasticsearch.node;
+package org.duniter.elasticsearch.user;
 
 /*
  * #%L
@@ -22,17 +22,13 @@ package org.duniter.elasticsearch.node;
  * #L%
  */
 
-import org.duniter.core.client.model.elasticsearch.Currency;
-import org.duniter.core.client.model.local.Peer;
 import org.duniter.elasticsearch.PluginSettings;
-import org.duniter.elasticsearch.action.security.RestSecurityController;
-import org.duniter.elasticsearch.service.*;
-import org.duniter.elasticsearch.service.event.Event;
-import org.duniter.elasticsearch.service.event.EventCodes;
-import org.duniter.elasticsearch.service.event.EventService;
-import org.duniter.elasticsearch.service.synchro.SynchroService;
 import org.duniter.elasticsearch.threadpool.ThreadPool;
-import org.elasticsearch.client.Client;
+import org.duniter.elasticsearch.user.service.HistoryService;
+import org.duniter.elasticsearch.user.service.MessageService;
+import org.duniter.elasticsearch.user.service.SynchroService;
+import org.duniter.elasticsearch.user.service.UserService;
+import org.duniter.elasticsearch.user.service.event.UserEventService;
 import org.elasticsearch.cluster.health.ClusterHealthStatus;
 import org.elasticsearch.common.component.AbstractLifecycleComponent;
 import org.elasticsearch.common.inject.Inject;
@@ -40,28 +36,23 @@ import org.elasticsearch.common.inject.Injector;
 import org.elasticsearch.common.logging.ESLogger;
 import org.elasticsearch.common.logging.Loggers;
 import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.rest.RestRequest;
 
 /**
  * Created by blavenie on 17/06/16.
  */
-public class DuniterNode extends AbstractLifecycleComponent<DuniterNode> {
+public class PluginInit extends AbstractLifecycleComponent<org.duniter.elasticsearch.PluginInit> {
 
     private final PluginSettings pluginSettings;
     private final ThreadPool threadPool;
     private final Injector injector;
     private final static ESLogger logger = Loggers.getLogger("node");
-    private final Client client;
-    private final String clusterName;
 
     @Inject
-    public DuniterNode(Client client, Settings settings, PluginSettings pluginSettings, ThreadPool threadPool, final Injector injector) {
+    public PluginInit(Settings settings, PluginSettings pluginSettings, ThreadPool threadPool, final Injector injector) {
         super(settings);
         this.pluginSettings = pluginSettings;
         this.threadPool = threadPool;
         this.injector = injector;
-        this.client = client;
-        this.clusterName = settings.get("cluster.name");
     }
 
     @Override
@@ -75,15 +66,6 @@ public class DuniterNode extends AbstractLifecycleComponent<DuniterNode> {
             }, ClusterHealthStatus.YELLOW, ClusterHealthStatus.GREEN);
         }, ClusterHealthStatus.YELLOW, ClusterHealthStatus.GREEN);
 
-        // When started
-        threadPool.scheduleOnStarted(() -> {
-            // Notify admin
-            injector.getInstance(EventService.class)
-                    .notifyAdmin(new Event(
-                            Event.EventType.INFO,
-                            EventCodes.NODE_STARTED.name(),
-                            new String[]{clusterName}));
-        });
     }
 
     @Override
@@ -102,27 +84,18 @@ public class DuniterNode extends AbstractLifecycleComponent<DuniterNode> {
 
         if (reloadIndices) {
             if (logger.isInfoEnabled()) {
-                logger.info("Reloading all Duniter indices...");
+                logger.info("Reloading all User indices...");
             }
-            injector.getInstance(RegistryService.class)
-                    .deleteIndex()
-                    .createIndexIfNotExists();
-            injector.getInstance(MarketService.class)
+            injector.getInstance(HistoryService.class)
                     .deleteIndex()
                     .createIndexIfNotExists();
             injector.getInstance(MessageService.class)
                     .deleteIndex()
                     .createIndexIfNotExists();
-
             injector.getInstance(UserService.class)
                     .deleteIndex()
                     .createIndexIfNotExists();
-
-            injector.getInstance(HistoryService.class)
-                    .deleteIndex()
-                    .createIndexIfNotExists();
-
-            injector.getInstance(EventService.class)
+            injector.getInstance(UserEventService.class)
                     .deleteIndex()
                     .createIndexIfNotExists();
 
@@ -135,12 +108,10 @@ public class DuniterNode extends AbstractLifecycleComponent<DuniterNode> {
             if (logger.isInfoEnabled()) {
                 logger.info("Checking Duniter indices...");
             }
-            injector.getInstance(RegistryService.class).createIndexIfNotExists();
-            injector.getInstance(MarketService.class).createIndexIfNotExists();
-            injector.getInstance(MessageService.class).createIndexIfNotExists();
-            injector.getInstance(UserService.class).createIndexIfNotExists();
             injector.getInstance(HistoryService.class).createIndexIfNotExists();
-            injector.getInstance(EventService.class).createIndexIfNotExists();
+            injector.getInstance(UserService.class).createIndexIfNotExists();
+            injector.getInstance(MessageService.class).createIndexIfNotExists();
+            injector.getInstance(UserEventService.class).createIndexIfNotExists();
 
             if (logger.isInfoEnabled()) {
                 logger.info("Checking Duniter indices... [OK]");
@@ -149,24 +120,6 @@ public class DuniterNode extends AbstractLifecycleComponent<DuniterNode> {
     }
 
     protected void synchronize() {
-        if (pluginSettings.enableBlockchainSync()) {
-
-            Peer peer = pluginSettings.checkAndGetPeer();
-
-            // Index (or refresh) node's currency
-            Currency currency = injector.getInstance(RegistryService.class).indexCurrencyFromPeer(peer, true);
-
-            // Add access to currency index
-            injector.getInstance(RestSecurityController.class).allowIndexType(RestRequest.Method.GET,
-                    currency.getCurrencyName(),
-                    BlockchainService.BLOCK_TYPE);
-
-            // Index blocks (and listen if new block appear)
-            injector.getInstance(BlockchainService.class)
-                    .indexLastBlocks(peer)
-                    .listenAndIndexNewBlock(peer);
-        }
-
         if (pluginSettings.enableDataSync()) {
             // Synchronize
             injector.getInstance(SynchroService.class).synchronize();
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/PluginSettings.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/PluginSettings.java
new file mode 100644
index 0000000000000000000000000000000000000000..2f6e10774d1140209e129e3cc85742a8b921e763
--- /dev/null
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/PluginSettings.java
@@ -0,0 +1,104 @@
+package org.duniter.elasticsearch.user;
+
+/*
+ * #%L
+ * UCoin Java Client :: Core API
+ * %%
+ * Copyright (C) 2014 - 2015 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.settings.Settings;
+
+/**
+ * Access to configuration options
+ * @author Benoit Lavenier <benoit.lavenier@e-is.pro>
+ * @since 1.0
+ */
+public class PluginSettings extends org.duniter.elasticsearch.PluginSettings {
+
+    @Inject
+    public PluginSettings(Settings settings) {
+        super(settings);
+    }
+
+    public String getDefaultStringAnalyzer() {
+        return settings.get("duniter.string.analyzer", "english");
+    }
+
+    public String getKeyringSalt() {
+        return settings.get("duniter.keyring.salt");
+    }
+
+    public String getKeyringPassword() {
+        return settings.get("duniter.keyring.password");
+    }
+
+    public String getKeyringPublicKey() {
+        return settings.get("duniter.keyring.pub");
+    }
+
+    public String getKeyringSecretKey() {
+        return settings.get("duniter.keyring.sec");
+    }
+
+    public boolean enableDataSync()  {
+        return settings.getAsBoolean("duniter.user.sync.enable", false);
+    }
+
+    public String getDataSyncHost()  {
+        return settings.get("duniter.user.sync.host", "data.duniter.fr");
+    }
+
+    public int getDataSyncPort()  {
+        return settings.getAsInt("duniter.user.sync.port", 80);
+    }
+
+    public String getMailSmtpHost()  {
+        return settings.get("duniter.mail.smtp.host", "localhost");
+    }
+
+    public int getMailSmtpPort()  {
+        return settings.getAsInt("duniter.mail.smtp.port", 25);
+    }
+
+    public String getMailSmtpUsername()  {
+        return settings.get("duniter.mail.smtp.username");
+    }
+
+    public String getMailSmtpPassword()  {
+        return settings.get("duniter.mail.smtp.password");
+    }
+
+    public String getMailAdmin()  {
+        return settings.get("duniter.mail.admin");
+    }
+
+    public String getMailFrom()  {
+        return settings.get("duniter.mail.from", "no-reply@duniter.fr");
+    }
+
+    public String getMailSubjectPrefix()  {
+        return settings.get("duniter.mail.subject.prefix", "[Duniter4j ES]");
+    }
+
+    protected String getI18nBundleName() {
+        return "duniter4j-es-user-i18n";
+    }
+}
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/RestModule.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/RestModule.java
new file mode 100644
index 0000000000000000000000000000000000000000..bb044f174266f3ec88b1c3e27f50f866df0de519
--- /dev/null
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/RestModule.java
@@ -0,0 +1,52 @@
+package org.duniter.elasticsearch.user.rest;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.user.rest.history.RestHistoryDeleteIndexAction;
+import org.duniter.elasticsearch.user.rest.message.RestMessageInboxIndexAction;
+import org.duniter.elasticsearch.user.rest.message.RestMessageOutboxIndexAction;
+import org.duniter.elasticsearch.user.rest.user.RestUserProfileIndexAction;
+import org.duniter.elasticsearch.user.rest.user.RestUserProfileUpdateAction;
+import org.duniter.elasticsearch.user.rest.user.RestUserSettingsIndexAction;
+import org.duniter.elasticsearch.user.rest.user.RestUserSettingsUpdateAction;
+import org.elasticsearch.common.inject.AbstractModule;
+import org.elasticsearch.common.inject.Module;
+
+public class RestModule extends AbstractModule implements Module {
+
+    @Override protected void configure() {
+
+        // User
+        bind(RestUserProfileIndexAction.class).asEagerSingleton();
+        bind(RestUserProfileUpdateAction.class).asEagerSingleton();
+        bind(RestUserSettingsIndexAction.class).asEagerSingleton();
+        bind(RestUserSettingsUpdateAction.class).asEagerSingleton();
+
+        // History
+        bind(RestHistoryDeleteIndexAction.class).asEagerSingleton();
+
+        // Message
+        bind(RestMessageInboxIndexAction.class).asEagerSingleton();
+        bind(RestMessageOutboxIndexAction.class).asEagerSingleton();
+    }
+}
\ No newline at end of file
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/history/RestHistoryDeleteIndexAction.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/history/RestHistoryDeleteIndexAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..8c7ddae551366ac77b78701bb70ea003b970ce41
--- /dev/null
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/history/RestHistoryDeleteIndexAction.java
@@ -0,0 +1,45 @@
+package org.duniter.elasticsearch.user.rest.history;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.rest.AbstractRestPostIndexAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.user.service.HistoryService;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.logging.ESLogger;
+import org.elasticsearch.common.logging.ESLoggerFactory;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.rest.RestController;
+
+public class RestHistoryDeleteIndexAction extends AbstractRestPostIndexAction {
+
+    @Inject
+    public RestHistoryDeleteIndexAction(Settings settings, RestController controller, Client client,
+                                        RestSecurityController securityController, HistoryService service) {
+        super(settings, controller, client, securityController,
+                HistoryService.INDEX,
+                HistoryService.DELETE_TYPE,
+                json -> service.indexDeleteFromJson(json));
+    }
+}
\ No newline at end of file
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/message/RestMessageInboxIndexAction.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/message/RestMessageInboxIndexAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..c469cba9b240b12f3f78baa1c16b777f317d106e
--- /dev/null
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/message/RestMessageInboxIndexAction.java
@@ -0,0 +1,44 @@
+package org.duniter.elasticsearch.user.rest.message;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.rest.AbstractRestPostIndexAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.user.service.MessageService;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.rest.RestController;
+
+public class RestMessageInboxIndexAction extends AbstractRestPostIndexAction {
+
+    @Inject
+    public RestMessageInboxIndexAction(Settings settings, RestController controller, Client client,
+                                       RestSecurityController securityController,
+                                       final MessageService service) {
+        super(settings, controller, client, securityController,
+                MessageService.INDEX,
+                MessageService.RECORD_TYPE,
+                json -> service.indexRecordFromJson(json));
+    }
+}
\ No newline at end of file
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/message/RestMessageOutboxIndexAction.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/message/RestMessageOutboxIndexAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..e2ac877416f12db6cea984347f1e7cb8197d16d8
--- /dev/null
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/message/RestMessageOutboxIndexAction.java
@@ -0,0 +1,44 @@
+package org.duniter.elasticsearch.user.rest.message;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.rest.AbstractRestPostIndexAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.user.service.MessageService;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.rest.RestController;
+
+public class RestMessageOutboxIndexAction extends AbstractRestPostIndexAction {
+
+    @Inject
+    public RestMessageOutboxIndexAction(Settings settings, RestController controller, Client client,
+                                        RestSecurityController securityController,
+                                        final MessageService service) {
+        super(settings, controller, client, securityController,
+                MessageService.INDEX,
+                MessageService.OUTBOX_TYPE,
+                json -> service.indexRecordFromJson(json));
+    }
+}
\ No newline at end of file
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/user/RestUserProfileIndexAction.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/user/RestUserProfileIndexAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..899db7e74d54db3a845941a58f762ff392496c28
--- /dev/null
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/user/RestUserProfileIndexAction.java
@@ -0,0 +1,44 @@
+package org.duniter.elasticsearch.user.rest.user;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.rest.AbstractRestPostIndexAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.user.service.UserService;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.rest.RestController;
+
+public class RestUserProfileIndexAction extends AbstractRestPostIndexAction {
+
+    @Inject
+    public RestUserProfileIndexAction(Settings settings, RestController controller, Client client,
+                                      RestSecurityController securityController,
+                                      UserService service) {
+        super(settings, controller, client, securityController,
+                UserService.INDEX,
+                UserService.PROFILE_TYPE,
+                json -> service.indexProfileFromJson(json));
+    }
+}
\ No newline at end of file
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/user/RestUserProfileUpdateAction.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/user/RestUserProfileUpdateAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..b33b4f710c26a79e0e36827d6a773dad3ddc5c3f
--- /dev/null
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/user/RestUserProfileUpdateAction.java
@@ -0,0 +1,45 @@
+package org.duniter.elasticsearch.user.rest.user;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.rest.AbstractRestPostUpdateAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.user.service.UserService;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.rest.RestController;
+
+public class RestUserProfileUpdateAction extends AbstractRestPostUpdateAction {
+
+    @Inject
+    public RestUserProfileUpdateAction(Settings settings, RestController controller, Client client,
+                                       RestSecurityController securityController,
+                                       UserService service) {
+        super(settings, controller, client, securityController,
+                UserService.INDEX,
+                UserService.PROFILE_TYPE,
+                (json, id) -> service.updateProfileFromJson(json, id));
+    }
+
+}
\ No newline at end of file
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/user/RestUserSettingsIndexAction.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/user/RestUserSettingsIndexAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..79371aa009d18686a411833a984847ea75fa0ff7
--- /dev/null
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/user/RestUserSettingsIndexAction.java
@@ -0,0 +1,45 @@
+package org.duniter.elasticsearch.user.rest.user;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.rest.AbstractRestPostIndexAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.user.service.UserService;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.rest.RestController;
+
+public class RestUserSettingsIndexAction extends AbstractRestPostIndexAction {
+
+    @Inject
+    public RestUserSettingsIndexAction(Settings settings, RestController controller, Client client,
+                                       RestSecurityController securityController,
+                                       final UserService service) {
+        super(settings, controller, client, securityController,
+                UserService.INDEX,
+                UserService.SETTINGS_TYPE,
+                json -> service.indexSettingsFromJson(json));
+    }
+
+}
\ No newline at end of file
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/user/RestUserSettingsUpdateAction.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/user/RestUserSettingsUpdateAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..24c8f5be74b42c771320bb455052832e00f56f1a
--- /dev/null
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/user/RestUserSettingsUpdateAction.java
@@ -0,0 +1,45 @@
+package org.duniter.elasticsearch.user.rest.user;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.rest.AbstractRestPostUpdateAction;
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.user.service.UserService;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.rest.RestController;
+
+public class RestUserSettingsUpdateAction extends AbstractRestPostUpdateAction {
+
+    @Inject
+    public RestUserSettingsUpdateAction(Settings settings, RestController controller, Client client,
+                                        RestSecurityController securityController,
+                                        final UserService service) {
+        super(settings, controller, client,  securityController,
+                UserService.INDEX,
+                UserService.SETTINGS_TYPE,
+                (json, id) -> service.updateSettingsFromJson(json, id));
+    }
+
+}
\ No newline at end of file
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/HistoryService.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/HistoryService.java
similarity index 98%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/HistoryService.java
rename to duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/HistoryService.java
index fc3f0e4368b1c4c9bfd757e71a9711f01f2caedf..a000508510784883614e8ec24c7c76edcf68fd0b 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/HistoryService.java
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/HistoryService.java
@@ -1,4 +1,4 @@
-package org.duniter.elasticsearch.service;
+package org.duniter.elasticsearch.user.service;
 
 /*
  * #%L
@@ -31,6 +31,7 @@ import org.duniter.core.exception.TechnicalException;
 import org.duniter.core.service.CryptoService;
 import org.duniter.elasticsearch.PluginSettings;
 import org.duniter.elasticsearch.exception.NotFoundException;
+import org.duniter.elasticsearch.service.AbstractService;
 import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
 import org.elasticsearch.action.index.IndexResponse;
 import org.elasticsearch.client.Client;
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/MessageService.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/MessageService.java
similarity index 96%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/MessageService.java
rename to duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/MessageService.java
index e6674b8756d5f2012de025443cec8956a472069c..3f501b75b044cef9db25a9e186fc4463db3e4d0a 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/MessageService.java
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/MessageService.java
@@ -1,4 +1,4 @@
-package org.duniter.elasticsearch.service;
+package org.duniter.elasticsearch.user.service;
 
 /*
  * #%L
@@ -28,6 +28,7 @@ import com.fasterxml.jackson.databind.JsonNode;
 import org.duniter.core.exception.TechnicalException;
 import org.duniter.core.service.CryptoService;
 import org.duniter.elasticsearch.PluginSettings;
+import org.duniter.elasticsearch.service.AbstractService;
 import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
 import org.elasticsearch.action.index.IndexResponse;
 import org.elasticsearch.client.Client;
@@ -49,8 +50,8 @@ public class MessageService extends AbstractService {
 
 
     @Inject
-    public MessageService(Client client, PluginSettings settings, CryptoService cryptoService) {
-        super("gchange." + INDEX, client, settings, cryptoService);
+    public MessageService(Client client, PluginSettings settings, CryptoService cryptoService, UserService userService) {
+        super("duniter." + INDEX, client, settings, cryptoService);
     }
 
     /**
@@ -62,7 +63,6 @@ public class MessageService extends AbstractService {
         return this;
     }
 
-
     public boolean existsIndex() {
         return super.existsIndex(INDEX);
     }
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/ServiceModule.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/ServiceModule.java
new file mode 100644
index 0000000000000000000000000000000000000000..a24ab24b969f2bf69e0b18fcc87d8eb6581bc7f4
--- /dev/null
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/ServiceModule.java
@@ -0,0 +1,41 @@
+package org.duniter.elasticsearch.user.service;
+
+/*
+ * #%L
+ * duniter4j-elasticsearch-plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.elasticsearch.user.service.event.UserEventService;
+import org.elasticsearch.common.inject.AbstractModule;
+import org.elasticsearch.common.inject.Module;
+
+public class ServiceModule extends AbstractModule implements Module {
+
+    @Override protected void configure() {
+        bind(MessageService.class).asEagerSingleton();
+        bind(HistoryService.class).asEagerSingleton();
+        bind(UserService.class).asEagerSingleton();
+        bind(UserEventService.class).asEagerSingleton();
+        bind(SynchroService.class).asEagerSingleton();
+    }
+
+    /* protected methods */
+
+}
\ No newline at end of file
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/SynchroService.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/SynchroService.java
new file mode 100644
index 0000000000000000000000000000000000000000..155e9c56fcc07bd7f036badf27405bde2d49f60a
--- /dev/null
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/SynchroService.java
@@ -0,0 +1,75 @@
+package org.duniter.elasticsearch.user.service;
+
+/*
+ * #%L
+ * Duniter4j :: ElasticSearch Plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+import org.duniter.core.client.model.local.Peer;
+import org.duniter.core.service.CryptoService;
+import org.duniter.elasticsearch.PluginSettings;
+import org.duniter.elasticsearch.service.ServiceLocator;
+import org.duniter.elasticsearch.service.AbstractSynchroService;
+import org.duniter.elasticsearch.threadpool.ThreadPool;
+import org.elasticsearch.client.Client;
+import org.elasticsearch.common.inject.Inject;
+
+/**
+ * Created by blavenie on 27/10/16.
+ */
+public class SynchroService extends AbstractSynchroService {
+
+   @Inject
+    public SynchroService(Client client, PluginSettings settings, CryptoService cryptoService,
+                          ThreadPool threadPool, final ServiceLocator serviceLocator) {
+        super(client, settings, cryptoService, threadPool, serviceLocator);
+    }
+
+    public void synchronize() {
+        logger.info("Synchronizing user data...");
+
+        Peer peer = getPeerFromAPI("ES API");
+        synchronize(peer);
+    }
+
+    /* -- protected methods -- */
+
+
+    protected void synchronize(Peer peer) {
+
+        long sinceTime = 0; // ToDO: get last sync time from somewhere ? (e.g. a specific index)
+
+        logger.info(String.format("[%s] Synchronizing user data since %s...", peer.toString(), sinceTime));
+
+        importUserChanges(peer, sinceTime);
+        importMessageChanges(peer, sinceTime);
+
+        logger.info(String.format("[%s] Synchronizing user data since %s [OK]", peer.toString(), sinceTime));
+    }
+
+    protected void importUserChanges(Peer peer, long sinceTime) {
+        importChanges(peer, UserService.INDEX, UserService.PROFILE_TYPE,  sinceTime);
+        importChanges(peer, UserService.INDEX, UserService.SETTINGS_TYPE,  sinceTime);
+    }
+
+    protected void importMessageChanges(Peer peer, long sinceTime) {
+        importChanges(peer, MessageService.INDEX, MessageService.RECORD_TYPE,  sinceTime);
+    }
+}
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/UserService.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/UserService.java
similarity index 98%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/UserService.java
rename to duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/UserService.java
index 4163b6e2f936922ad3f53c6b986de9d8d05fac84..9977f5a3b10d562522b9cd1b35780c614943479f 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/UserService.java
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/UserService.java
@@ -1,4 +1,4 @@
-package org.duniter.elasticsearch.service;
+package org.duniter.elasticsearch.user.service;
 
 /*
  * #%L
@@ -25,13 +25,12 @@ package org.duniter.elasticsearch.service;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.JsonNode;
-import org.duniter.core.client.service.bma.BlockchainRemoteService;
-import org.duniter.core.client.service.bma.WotRemoteService;
 import org.duniter.core.exception.TechnicalException;
 import org.duniter.core.service.CryptoService;
 import org.duniter.core.service.MailService;
 import org.duniter.elasticsearch.PluginSettings;
 import org.duniter.elasticsearch.exception.AccessDeniedException;
+import org.duniter.elasticsearch.service.AbstractService;
 import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
 import org.elasticsearch.action.index.IndexResponse;
 import org.elasticsearch.action.update.UpdateResponse;
@@ -50,6 +49,7 @@ public class UserService extends AbstractService {
 
     public static final String INDEX = "user";
     public static final String PROFILE_TYPE = "profile";
+    public static final String EVENT_TYPE = "profile";
     public static final String SETTINGS_TYPE = "settings";
 
     @Inject
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/event/Event.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/event/UserEvent.java
similarity index 58%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/event/Event.java
rename to duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/event/UserEvent.java
index 6b5d517646c118040d3e1170d3a896913b096413..9046f3c145480f2199dc86d54659e938f2179921 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/event/Event.java
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/event/UserEvent.java
@@ -1,4 +1,26 @@
-package org.duniter.elasticsearch.service.event;
+package org.duniter.elasticsearch.user.service.event;
+
+/*
+ * #%L
+ * Duniter4j :: ElasticSearch Plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
 
 import org.nuiton.i18n.I18n;
 
@@ -7,7 +29,7 @@ import java.util.Locale;
 /**
  * Created by blavenie on 29/11/16.
  */
-public class Event {
+public class UserEvent {
 
     private EventType type;
 
@@ -20,11 +42,11 @@ public class Event {
 
     private String[] params;
 
-    public Event(EventType type, String code) {
+    public UserEvent(EventType type, String code) {
         this(type, code, null);
     }
 
-    public Event(EventType type, String code, String[] params) {
+    public UserEvent(EventType type, String code, String[] params) {
         this.type = type;
         this.code = code;
         this.params = params;
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/event/UserEventCodes.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/event/UserEventCodes.java
new file mode 100644
index 0000000000000000000000000000000000000000..368e025de692bf7e1ee3540ca8549f6fa6851d7a
--- /dev/null
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/event/UserEventCodes.java
@@ -0,0 +1,34 @@
+package org.duniter.elasticsearch.user.service.event;
+
+/*
+ * #%L
+ * Duniter4j :: ElasticSearch Plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+/**
+ * Created by blavenie on 29/11/16.
+ */
+public enum UserEventCodes {
+
+    NODE_STARTED,
+    CREATE_DOC,
+    UPDATE_DOC,
+    COMMENT_DOC
+}
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/event/UserEventListener.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/event/UserEventListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..7d34b28bb45e7e0d8ca85a632a746fdf00eece72
--- /dev/null
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/event/UserEventListener.java
@@ -0,0 +1,6 @@
+package org.duniter.elasticsearch.user.service.event;
+
+public interface UserEventListener {
+    String getId();
+    void onEvent(UserEvent event);
+}
\ No newline at end of file
diff --git a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/event/EventService.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/event/UserEventService.java
similarity index 78%
rename from duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/event/EventService.java
rename to duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/event/UserEventService.java
index 745063d57705025440ba88191c78d4b23e409403..0ce4ede8b2c1e27aea6d47ea16f9b3ba130b63ae 100644
--- a/duniter4j-elasticsearch/src/main/java/org/duniter/elasticsearch/service/event/EventService.java
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/event/UserEventService.java
@@ -1,4 +1,4 @@
-package org.duniter.elasticsearch.service.event;
+package org.duniter.elasticsearch.user.service.event;
 
 /*
  * #%L
@@ -34,42 +34,63 @@ import org.duniter.core.util.crypto.CryptoUtils;
 import org.duniter.core.util.crypto.KeyPair;
 import org.duniter.elasticsearch.PluginSettings;
 import org.duniter.elasticsearch.service.AbstractService;
+import org.duniter.elasticsearch.service.changes.ChangeEvent;
+import org.duniter.elasticsearch.service.changes.ChangeListener;
+import org.duniter.elasticsearch.service.changes.ChangeService;
+import org.duniter.elasticsearch.service.changes.ChangeUtils;
+import org.duniter.elasticsearch.threadpool.ThreadPool;
 import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
 import org.elasticsearch.action.index.IndexResponse;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.inject.Inject;
 import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.common.unit.TimeValue;
 import org.elasticsearch.common.xcontent.XContentBuilder;
 import org.elasticsearch.common.xcontent.XContentFactory;
 import org.nuiton.i18n.I18n;
 
 import java.io.IOException;
+import java.util.HashMap;
 import java.util.Locale;
+import java.util.Map;
 
 /**
  * Created by Benoit on 30/03/2015.
  */
-public class EventService extends AbstractService {
+public class UserEventService extends AbstractService implements ChangeListener {
 
     public static final String INDEX = "user";
     public static final String EVENT_TYPE = "event";
+    private static final Map<String, UserEventListener> LISTENERS = new HashMap<>();
+
+    public static void registerListener(UserEventListener listener) {
+        LISTENERS.put(listener.getId(), listener);
+    }
+
+    public static void unregisterListener(UserEventListener listener) {
+        LISTENERS.remove(listener.getId());
+    }
 
     private final MailService mailService;
+    private final ThreadPool threadPool;
     public final KeyPair nodeKeyPair;
     public final String nodePubkey;
 
     @Inject
-    public EventService(Client client, PluginSettings settings, CryptoService cryptoService, MailService mailService) {
+    public UserEventService(Client client, PluginSettings settings, CryptoService cryptoService, MailService mailService,
+                            ThreadPool threadPool) {
         super("duniter.event." + INDEX, client, settings, cryptoService);
         this.mailService = mailService;
+        this.threadPool = threadPool;
         this.nodeKeyPair = getNodeKeyPairOrNull(pluginSettings);
         this.nodePubkey = getNodePubKey(this.nodeKeyPair);
+        ChangeService.registerListener(this);
     }
 
     /**
      * Notify cluster admin
      */
-    public void notifyAdmin(Event event) {
+    public void notifyAdmin(UserEvent event) {
         Locale locale = I18n.getDefaultLocale(); // TODO get locale from admin
 
         // Add new event to index
@@ -92,32 +113,54 @@ public class EventService extends AbstractService {
         }
     }
 
+    /**
+     * Notify a new document
+     */
+    public void notifyNewDocument(String index, String type, String id, String issuer) {
+
+        String docId = String.format("%s/%s/%s", index, type, id);
+        logger.info(String.format("Detected new document at: %s", docId));
+
+        notifyUser(issuer, new UserEvent(UserEvent.EventType.INFO, UserEventCodes.CREATE_DOC.name(), new String[]{docId}));
+    }
+
     /**
      * Notify a user
      */
-    public void notifyUser(String recipient, Event event) {
+    public void notifyUser(String recipient, UserEvent event) {
+        // Notify user
+        threadPool.schedule(() -> {
+            doNotifyUser(recipient, event);
+        }, TimeValue.timeValueMillis(100));
+    }
 
-        String email = getEmailByPk(recipient);
-        Locale locale = I18n.getDefaultLocale(); // TODO get locale
+    @Override
+    public void onChanges(String json) {
+        // TODO get doc issuer
+        String issuer = nodePubkey;
 
-        // Add new event to index
-        indexEvent(recipient, locale, event);
+        ChangeEvent event = ChangeUtils.fromJson(objectMapper, json);
 
-        // Send email to user
-        if (StringUtils.isNotBlank(email)) {
-            String subjectPrefix = pluginSettings.getMailSubjectPrefix();
-            sendEmail(email,
-                    I18n.l(locale, "duniter4j.event.subject."+event.getType().name(), subjectPrefix),
-                    event.getLocalizedMessage(locale));
+        // Skip event itself (avoid recursive call)
+        if (event.getIndex().equals(INDEX) && event.getType().equals(EVENT_TYPE)) {
+            return;
+        }
+
+        if (event.getOperation() == ChangeEvent.Operation.CREATE) {
+            notifyNewDocument(event.getIndex(), event.getType(), event.getId(), issuer);
         }
 
     }
 
+    @Override
+    public String getId() {
+        return "UserEventService";
+    }
+
     /**
      * Delete blockchain index, and all data
-     * @throws JsonProcessingException
      */
-    public EventService deleteIndex() {
+    public UserEventService deleteIndex() {
         deleteIndexIfExists(INDEX);
         return this;
     }
@@ -129,7 +172,7 @@ public class EventService extends AbstractService {
     /**
      * Create index need for blockchain registry, if need
      */
-    public EventService createIndexIfNotExists() {
+    public UserEventService createIndexIfNotExists() {
         try {
             if (!existsIndex(INDEX)) {
                 createIndex();
@@ -146,7 +189,7 @@ public class EventService extends AbstractService {
      * Create index need for category registry
      * @throws JsonProcessingException
      */
-    public EventService createIndex() throws JsonProcessingException {
+    public UserEventService createIndex() throws JsonProcessingException {
         logger.info(String.format("Creating index [%s/%s]", INDEX, EVENT_TYPE));
 
         CreateIndexRequestBuilder createIndexRequestBuilder = client.admin().indices().prepareCreate(INDEX);
@@ -162,7 +205,7 @@ public class EventService extends AbstractService {
         return this;
     }
 
-    public String indexEvent(String recipient, Locale locale, Event event) {
+    public String indexEvent(String recipient, Locale locale, UserEvent event) {
         // Generate json
         String eventJson;
         if (StringUtils.isNotBlank(nodePubkey)) {
@@ -265,10 +308,11 @@ public class EventService extends AbstractService {
     }
 
     private String getEmailByPk(String issuerPk) {
-        return "benoit.lavenier@e-is.pro";
+        // TODO get it from user profile ?
+        return pluginSettings.getMailAdmin();
     }
 
-    private String getEmailSubject(Locale locale, Event event) {
+    private String getEmailSubject(Locale locale, UserEvent event) {
 
         return  I18n.l(locale, "duniter4j.event.subject."+event.getType().name());
     }
@@ -296,7 +340,7 @@ public class EventService extends AbstractService {
         }
     }
 
-    private String toJson(String issuer, String recipient, Locale locale, Event event, String signature) {
+    private String toJson(String issuer, String recipient, Locale locale, UserEvent event, String signature) {
         try {
             XContentBuilder eventObject = XContentFactory.jsonBuilder().startObject()
                     .field("type", event.getType().name())
@@ -335,4 +379,28 @@ public class EventService extends AbstractService {
         if (nodeKeyPair == null) return null;
         return CryptoUtils.encodeBase58(nodeKeyPair.getPubKey());
     }
+
+    /**
+     * Notify a user
+     */
+    private void doNotifyUser(String recipient, UserEvent event) {
+
+        String email = getEmailByPk(recipient);
+        Locale locale = I18n.getDefaultLocale(); // TODO get locale
+
+        // Add new event to index
+        indexEvent(recipient, locale, event);
+
+        // Send email to user
+        if (StringUtils.isNotBlank(email)) {
+            String subjectPrefix = pluginSettings.getMailSubjectPrefix();
+            sendEmail(email,
+                    I18n.l(locale, "duniter4j.event.subject."+event.getType().name(), subjectPrefix),
+                    event.getLocalizedMessage(locale));
+        }
+
+        for (UserEventListener listener: LISTENERS.values()) {
+            listener.onEvent(event);
+        }
+    }
 }
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/websocket/WebsocketUserEventEndPoint.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/websocket/WebsocketUserEventEndPoint.java
new file mode 100644
index 0000000000000000000000000000000000000000..7591f42997c4c387f07585d68784edb9348a145f
--- /dev/null
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/websocket/WebsocketUserEventEndPoint.java
@@ -0,0 +1,98 @@
+package org.duniter.elasticsearch.user.websocket;
+
+/*
+ * #%L
+ * Duniter4j :: ElasticSearch Plugin
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+/*
+    Copyright 2015 ForgeRock AS
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+*/
+
+//@ServerEndpoint(value = "/event/user/{pubkey}")
+public class WebsocketUserEventEndPoint /*implements UserEventListener*/ {
+
+  /*  private static final String PATH_PARAM_PUBKEY = "pubkey";
+    private final static Pattern PUBKEY_PATTERN = Pattern.compile(Constants.Regex.PUBKEY);
+
+    private final ESLogger log = Loggers.getLogger("duniter.ws.user.event");
+    private Session session;
+    private String pubkey;
+
+
+    @OnOpen
+    public void onOpen(Session session) {
+        this.session = session;
+        this.pubkey = session.getPathParameters() != null ? session.getPathParameters().get(PATH_PARAM_PUBKEY) : null;
+
+        if (StringUtils.isBlank(pubkey) || !PUBKEY_PATTERN.matcher(pubkey).matches()) {
+            try {
+                this.session.close(new CloseReason(CloseReason.CloseCodes.CANNOT_ACCEPT, "Invalid pubkey"));
+            } catch (IOException e) {
+                // silent
+            }
+            return;
+        }
+
+        log.info("User [%s] connecting with id [%s]", session.getId());
+        UserEventService.registerListener(this);
+    }
+
+    @Override
+    public void onEvent(UserEvent event) {
+        session.getAsyncRemote().sendText("{\"type\":\""+event.getType().name()+"\",\"message\":\"" + event.getMessage() + "\"}");
+    }
+
+    @Override
+    public String getId() {
+        return session == null ? null : session.getId();
+    }
+
+    @OnMessage
+    public void onMessage(String message) {
+        log.info("Received message: "+message);
+    }
+
+    @OnClose
+    public void onClose(CloseReason reason) {
+        log.info("Closing websocket: "+reason);
+        UserEventService.unregisterListener(this);
+        this.session = null;
+    }
+
+    @OnError
+    public void onError(Throwable t) {
+        log.error("Error on websocket "+(session == null ? null : session.getId()), t);
+    }
+*/
+
+}
diff --git a/duniter4j-es-user/src/main/misc/cities-fr.geoJson.txt b/duniter4j-es-user/src/main/misc/cities-fr.geoJson.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bb4b1bd422f6de2c147bba0ab39ce74aadf01f6c
--- /dev/null
+++ b/duniter4j-es-user/src/main/misc/cities-fr.geoJson.txt
@@ -0,0 +1,8 @@
+Les données Francaise des communes provient de ce fichier  :
+http://public.opendatasoft.com/explore/dataset/geoflar-communes-2015/export/
+
+>> Cliquer sur Export > GeoJSON
+
+
+Ou directement via :
+ http://public.opendatasoft.com/explore/dataset/geoflar-communes-2015/download/?format=geojson&timezone=Europe/Berlin
\ No newline at end of file
diff --git a/duniter4j-es-user/src/main/misc/curl_test.sh b/duniter4j-es-user/src/main/misc/curl_test.sh
new file mode 100755
index 0000000000000000000000000000000000000000..4f62377a7b20ee747e1a99f1c6ab627e9caa8b35
--- /dev/null
+++ b/duniter4j-es-user/src/main/misc/curl_test.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+curl -XPOST "http://data.duniter.fr/market/comment/_search?pretty" -d'
+{
+  "query": {
+        "bool":{
+            "filter": [
+                {"term":{
+                        "record":"AVbieTIAup9uzWgKipsC"
+                    }
+                }
+            ]
+        }
+  }
+}'
+
diff --git a/duniter4j-es-user/src/main/misc/index.sh b/duniter4j-es-user/src/main/misc/index.sh
new file mode 100755
index 0000000000000000000000000000000000000000..02b66934dd45e338506a7adc1e25500fabac9710
--- /dev/null
+++ b/duniter4j-es-user/src/main/misc/index.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+curl -X POST '192.168.0.28:9200/places' -d '{
+    "mappings": {
+    "place": {
+        "properties": {
+            "id": {"type": "double"},
+            "name": {"type": "string"},
+            "type": {"type": "string"},
+            "location": {"type": "geo_point"}
+        }
+    }
+  }
+}'
\ No newline at end of file
diff --git a/duniter4j-es-user/src/main/misc/registry-categories-naf2008_liste_n5.ods b/duniter4j-es-user/src/main/misc/registry-categories-naf2008_liste_n5.ods
new file mode 100644
index 0000000000000000000000000000000000000000..acc6ea091339d82dacf7533c99e3cf9876599984
Binary files /dev/null and b/duniter4j-es-user/src/main/misc/registry-categories-naf2008_liste_n5.ods differ
diff --git a/duniter4j-es-user/src/main/resources/i18n/duniter4j-es-user_en_GB.properties b/duniter4j-es-user/src/main/resources/i18n/duniter4j-es-user_en_GB.properties
new file mode 100644
index 0000000000000000000000000000000000000000..452f86030f449dec66b1856c42eb67c701f51138
--- /dev/null
+++ b/duniter4j-es-user/src/main/resources/i18n/duniter4j-es-user_en_GB.properties
@@ -0,0 +1,4 @@
+duniter4j.event.NODE_STARTED=Node started on cluster Duniter4j ES [%s]
+duniter4j.event.subject.ERROR=[%s] Error message
+duniter4j.event.subject.INFO=[%s] Information message
+duniter4j.event.subject.WARN=[%s] Warning message
diff --git a/duniter4j-es-user/src/main/resources/i18n/duniter4j-es-user_fr_FR.properties b/duniter4j-es-user/src/main/resources/i18n/duniter4j-es-user_fr_FR.properties
new file mode 100644
index 0000000000000000000000000000000000000000..4ae1466a52f86484a597b4f91319ec1262e49b0b
--- /dev/null
+++ b/duniter4j-es-user/src/main/resources/i18n/duniter4j-es-user_fr_FR.properties
@@ -0,0 +1,4 @@
+duniter4j.event.NODE_STARTED=Noeud démarré sur le cluster Duniter4j ES [%s]
+duniter4j.event.subject.ERROR=%s Message d'erreur
+duniter4j.event.subject.INFO=%s Message d'information
+duniter4j.event.subject.WARN=%s Message d'avertissement
diff --git a/duniter4j-es-user/src/main/resources/plugin-security.policy b/duniter4j-es-user/src/main/resources/plugin-security.policy
new file mode 100644
index 0000000000000000000000000000000000000000..23b556b1994f188dcf5fd757e8861972b6b63699
--- /dev/null
+++ b/duniter4j-es-user/src/main/resources/plugin-security.policy
@@ -0,0 +1,5 @@
+grant codeBase "file:${es.path.home}/plugins/duniter4j-es-user/"{
+  permission java.io.FilePermission "/etc/ld.so.conf", "read";
+  permission java.io.FilePermission "/etc/ld.so.conf.d/*.conf", "read";
+  permission java.io.FilePermission "/usr/local/lib/*", "read";
+};
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 493d3164aa66694d6f2d004720a4e72463c8e77c..60b16e97cce2e7bdac3326977e05c2a4c8263088 100644
--- a/pom.xml
+++ b/pom.xml
@@ -84,6 +84,8 @@
     <distribution.snapshotRepository.url>http://nexus.e-is.pro/nexus/content/repositories/duniter4j-snapshots</distribution.snapshotRepository.url>
 
     <github.global.server>github</github.global.server>
+
+    <assembly.skip>false</assembly.skip>
   </properties>
 
   <licenses>
@@ -99,7 +101,10 @@
   <modules>
     <module>duniter4j-core-shared</module>
     <module>duniter4j-core-client</module>
-    <module>duniter4j-elasticsearch</module>
+    <module>duniter4j-es-core</module>
+    <module>duniter4j-es-user</module>
+    <module>duniter4j-es-gchange</module>
+    <module>duniter4j-es-assembly</module>
   </modules>
 
   <scm>