diff --git a/pom.xml b/pom.xml
index 10b332872c88ac88f0b00133d05bff05e5581a19..b0ec73511f6573fb61343d90f091b77fe807303a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
     <kalium.version>0.4.0</kalium.version>
     <scrypt.version>1.4.0</scrypt.version>
     <!--<elasticsearch.version>2.2.0</elasticsearch.version>-->
-    <elasticsearch.version>2.1.1</elasticsearch.version>
+    <elasticsearch.version>2.3.1</elasticsearch.version>
     <jna.version>4.1.0</jna.version>
 
     <nuitonConfigVersion>3.0-rc-2</nuitonConfigVersion>
diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteServiceImpl.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteServiceImpl.java
index 85a9f877bbafdfa56aa77d7f08a6bc76213f6598..91179e1bd712e5fef5f8b121476cac4ad5dfaf92 100644
--- a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteServiceImpl.java
+++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteServiceImpl.java
@@ -82,7 +82,7 @@ public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implemen
 				getPath(wallet.getCurrencyId(), URL_TX_PROCESS));
 
 		// compute transaction
-		String transaction = getSignedTransaction(wallet, destPubKey, amount,
+		String transaction = getSignedTransaction(wallet, destPubKey, 0, amount,
                 comment);
 
 		if (log.isDebugEnabled()) {
@@ -211,8 +211,11 @@ public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implemen
 
 	/* -- internal methods -- */
 
-	public String getSignedTransaction(Wallet wallet, String destPubKey,
-			long amount, String comment) throws InsufficientCreditException {
+	public String getSignedTransaction(Wallet wallet,
+									   String destPubKey,
+									   int locktime,
+									   long amount,
+									   String comment) throws InsufficientCreditException {
         ObjectUtils.checkNotNull(wallet);
         ObjectUtils.checkArgument(StringUtils.isNotBlank(wallet.getCurrency()));
         ObjectUtils.checkArgument(StringUtils.isNotBlank(wallet.getPubKeyHash()));
@@ -235,7 +238,7 @@ public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implemen
 				sources, amount, txInputs, txOutputs);
 
 		String transaction = getTransaction(wallet.getCurrency(),
-				wallet.getPubKeyHash(), destPubKey, txInputs, txOutputs,
+				wallet.getPubKeyHash(), destPubKey, locktime, txInputs, txOutputs,
 				comment);
 
 		String signature = cryptoService.sign(transaction, wallet.getSecKey());
@@ -244,14 +247,18 @@ public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implemen
 				.append('\n').toString();
 	}
 
-	public String getTransaction(String currency, String srcPubKey,
-			String destPubKey, List<TxSource.Source> inputs, List<TxOutput> outputs,
+	public String getTransaction(String currency,
+								 String srcPubKey,
+								 String destPubKey,
+								 int locktime,
+								 List<TxSource.Source> inputs, List<TxOutput> outputs,
 			String comments) {
 
 		StringBuilder sb = new StringBuilder();
 		sb.append("Version: ").append(Protocol.VERSION).append("\n")
 				.append("Type: ").append(Protocol.TYPE_TRANSACTION).append("\n")
 				.append("Currency: ").append(currency).append('\n')
+				.append("Locktime: ").append(locktime).append('\n')
 				.append("Issuers:\n")
 				// add issuer pubkey
 				.append(srcPubKey).append('\n');
diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/service/CryptoService.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/service/CryptoService.java
index 1041f32dee8ddca237eeb86149e4b5a0bcd47cd8..e2030dd506cb20463b005466a5e8f4c6fd328f88 100644
--- a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/service/CryptoService.java
+++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/service/CryptoService.java
@@ -58,4 +58,11 @@ public interface CryptoService extends Bean {
     String sign(String message, String secretKey);
 
     boolean verify(String message, String signature, String publicKey);
+
+    /**
+     * Do a SHA256 then a hexa convert
+     * @param message
+     * @return
+     */
+    String hash(String message);
 }
diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/service/Ed25519CryptoServiceImpl.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/service/Ed25519CryptoServiceImpl.java
index 0e7eb0773482c5b3af7c21c4e935ee64a355d25d..d3fd5e68cc50584f022d0d78f4a07d85b7b36a84 100644
--- a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/service/Ed25519CryptoServiceImpl.java
+++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/service/Ed25519CryptoServiceImpl.java
@@ -25,11 +25,13 @@ package io.ucoin.ucoinj.core.service;
 
 import com.lambdaworks.crypto.SCrypt;
 import io.ucoin.ucoinj.core.exception.TechnicalException;
+import io.ucoin.ucoinj.core.util.crypto.CryptoUtils;
 import io.ucoin.ucoinj.core.util.crypto.KeyPair;
 import jnr.ffi.byref.LongLongByReference;
 import org.abstractj.kalium.NaCl;
 import org.abstractj.kalium.NaCl.Sodium;
 
+import java.math.BigInteger;
 import java.security.GeneralSecurityException;
 
 import static io.ucoin.ucoinj.core.util.crypto.CryptoUtils.*;
@@ -55,6 +57,11 @@ public class Ed25519CryptoServiceImpl implements CryptoService {
     private static int SCRYPT_PARAMS_r = 16;
     private static int SCRYPT_PARAMS_p = 1;
 
+    protected final static char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();
+
+    // Hash
+    private static int HASH_BYTES = 256;
+
     private final Sodium naCl;
 
     public Ed25519CryptoServiceImpl() {
@@ -117,6 +124,14 @@ public class Ed25519CryptoServiceImpl implements CryptoService {
         return verify(messageBinary, signatureBinary, publicKeyBinary);
     }
 
+    @Override
+    public String hash(String message) {
+        byte[] hash = new byte[Sodium.SHA256BYTES];
+        byte[] messageBinary = decodeUTF8(message);
+        naCl.crypto_hash_sha256(hash, messageBinary, messageBinary.length);
+        return bytesToHex(hash).toUpperCase();
+    }
+
     /* -- Internal methods -- */
 
     protected byte[] sign(byte[] message, byte[] secretKey) {
@@ -143,4 +158,14 @@ public class Ed25519CryptoServiceImpl implements CryptoService {
         return validSignature;
     }
 
+    protected static String bytesToHex(byte[] bytes) {
+        char[] hexChars = new char[bytes.length * 2];
+        for ( int j = 0; j < bytes.length; j++ ) {
+            int v = bytes[j] & 0xFF;
+            hexChars[j * 2] = HEX_CHARS[v >>> 4];
+            hexChars[j * 2 + 1] = HEX_CHARS[v & 0x0F];
+        }
+        return new String(hexChars);
+    }
+
 }
diff --git a/ucoinj-core-shared/src/test/java/io/ucoin/ucoinj/core/service/Ed25519CryptoServiceTest.java b/ucoinj-core-shared/src/test/java/io/ucoin/ucoinj/core/service/Ed25519CryptoServiceTest.java
index 7be64c870e2d9ae89ccc0150cebfce29b17245d6..00d38f5f158a928158cf09317e34bd68c3013031 100644
--- a/ucoinj-core-shared/src/test/java/io/ucoin/ucoinj/core/service/Ed25519CryptoServiceTest.java
+++ b/ucoinj-core-shared/src/test/java/io/ucoin/ucoinj/core/service/Ed25519CryptoServiceTest.java
@@ -67,6 +67,17 @@ public class Ed25519CryptoServiceTest {
         Assert.assertTrue(validSignature);
 	}
 
+    @Test
+    public void hash() throws Exception {
+
+        String record = "{\"isCompany\":false,\"title\":\"toto\",\"description\":\"toto\",\"pictures\":[],\"time\":1461162142,\"issuer\":\"G2CBgZBPLe6FSFUgpx2Jf1Aqsgta6iib3vmDRA1yLiqU\"}";
+
+        String hash = service.hash(record);
+
+        Assert.assertEquals("AC31F1E3EAEB7A535A3BF1182AA53100BB3B610C5D63643ACB145EB99764B0CA", hash);
+    }
+
+
 
 	/* -- internal methods */
 
diff --git a/ucoinj-elasticsearch-plugin/src/main/filtered-resources/plugin-descriptor.properties b/ucoinj-elasticsearch-plugin/src/main/filtered-resources/plugin-descriptor.properties
index 7960daf87a68f056f195609c9965c5d886b34736..6a54716d6a9c44daa9f65f46d77623339ad8f46d 100644
--- a/ucoinj-elasticsearch-plugin/src/main/filtered-resources/plugin-descriptor.properties
+++ b/ucoinj-elasticsearch-plugin/src/main/filtered-resources/plugin-descriptor.properties
@@ -7,5 +7,5 @@ site=false
 jvm=true
 classname=io.ucoin.ucoinj.elasticsearch.plugin.Plugin
 java.version=1.7
-elasticsearch.version=2.1.1
+elasticsearch.version=2.3.1
 isolated=false
\ No newline at end of file
diff --git a/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/RestModule.java b/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/RestModule.java
index 1433bf1be26cb2d5c0ef6adb8281378b512fc02b..52a958d971812c2b7273be7566509017638ff262 100644
--- a/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/RestModule.java
+++ b/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/RestModule.java
@@ -23,8 +23,7 @@ package io.ucoin.ucoinj.elasticsearch.action;
  */
 
 import io.ucoin.ucoinj.elasticsearch.action.currency.RestCurrencyIndexAction;
-import io.ucoin.ucoinj.elasticsearch.action.market.RestMarketDemandIndexAction;
-import io.ucoin.ucoinj.elasticsearch.action.market.RestMarketOfferIndexAction;
+import io.ucoin.ucoinj.elasticsearch.action.market.RestMarketRecordIndexAction;
 import io.ucoin.ucoinj.elasticsearch.action.registry.RestRegistryRecordIndexAction;
 import io.ucoin.ucoinj.elasticsearch.action.security.RestSecurityAuthAction;
 import io.ucoin.ucoinj.elasticsearch.action.security.RestSecurityGetChallengeAction;
@@ -36,8 +35,7 @@ public class RestModule extends AbstractModule implements Module {
     @Override protected void configure() {
         bind(RestCurrencyIndexAction.class).asEagerSingleton();
 
-        bind(RestMarketOfferIndexAction.class).asEagerSingleton();
-        bind(RestMarketDemandIndexAction.class).asEagerSingleton();
+        bind(RestMarketRecordIndexAction.class).asEagerSingleton();
 
         bind(RestRegistryRecordIndexAction.class).asEagerSingleton();
 
diff --git a/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/currency/RestCurrencyIndexAction.java b/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/currency/RestCurrencyIndexAction.java
index a38c648cb26c2f5df74bbfaaa8c276928c3a1440..0409273ee9307a379738b7e1e0c497fe92da78aa 100644
--- a/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/currency/RestCurrencyIndexAction.java
+++ b/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/currency/RestCurrencyIndexAction.java
@@ -22,6 +22,7 @@ package io.ucoin.ucoinj.elasticsearch.action.currency;
  * #L%
  */
 
+import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator;
 import org.elasticsearch.client.Client;
 import org.elasticsearch.common.inject.Inject;
 import org.elasticsearch.common.settings.Settings;
@@ -40,7 +41,7 @@ public class RestCurrencyIndexAction extends BaseRestHandler {
     @Override
     protected void handleRequest(RestRequest restRequest, RestChannel restChannel, Client client) throws Exception {
         String json = restRequest.content().toUtf8();
-        //ServiceLocator.instance().getCurrencyIndexerService().indexCurrency();
+        //ServiceLocator.instance().getRegistryCurrencyIndexerService().indexCurrency();
         String currencyName = "";
         restChannel.sendResponse(new BytesRestResponse(OK, currencyName));
     }
diff --git a/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/market/RestMarketOfferIndexAction.java b/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/market/RestMarketOfferIndexAction.java
deleted file mode 100644
index bbfefcc94d9c8f7345a8d05f0af00f569fe141d7..0000000000000000000000000000000000000000
--- a/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/market/RestMarketOfferIndexAction.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package io.ucoin.ucoinj.elasticsearch.action.market;
-
-/*
- * #%L
- * ucoinj-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 io.ucoin.ucoinj.core.exception.BusinessException;
-import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator;
-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.*;
-
-import static org.elasticsearch.rest.RestRequest.Method.POST;
-import static org.elasticsearch.rest.RestStatus.BAD_REQUEST;
-import static org.elasticsearch.rest.RestStatus.OK;
-
-public class RestMarketOfferIndexAction extends BaseRestHandler {
-
-    private static final ESLogger log = ESLoggerFactory.getLogger(RestMarketOfferIndexAction.class.getName());
-
-    @Inject
-    public RestMarketOfferIndexAction(Settings settings, RestController controller, Client client) {
-        super(settings, controller, client);
-        controller.registerHandler(POST, "/market/offer", this);
-    }
-
-    @Override
-    protected void handleRequest(final RestRequest request, RestChannel restChannel, Client client) throws Exception {
-
-        try {
-            String recordId = ServiceLocator.instance().getMarketRecordIndexerService().indexOfferFromJson(request.content().toUtf8());
-
-            restChannel.sendResponse(new BytesRestResponse(OK, recordId));
-        }
-        catch(BusinessException e) {
-            log.error(e.getMessage(), e);
-            restChannel.sendResponse(new BytesRestResponse(BAD_REQUEST, String.format("{error: {ucode: 'XXX', message:'%s'}}", e.getMessage())));
-        }
-        catch(Exception e) {
-            log.error(e.getMessage(), e);
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/market/RestMarketDemandIndexAction.java b/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/market/RestMarketRecordIndexAction.java
similarity index 87%
rename from ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/market/RestMarketDemandIndexAction.java
rename to ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/market/RestMarketRecordIndexAction.java
index e721244e30bb3f988d8f1152ed8f7cd6b220179a..5fe953ac23be97069a1306578d5a269367b8e50c 100644
--- a/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/market/RestMarketDemandIndexAction.java
+++ b/ucoinj-elasticsearch-plugin/src/main/java/io/ucoin/ucoinj/elasticsearch/action/market/RestMarketRecordIndexAction.java
@@ -35,21 +35,21 @@ import static org.elasticsearch.rest.RestRequest.Method.POST;
 import static org.elasticsearch.rest.RestStatus.BAD_REQUEST;
 import static org.elasticsearch.rest.RestStatus.OK;
 
-public class RestMarketDemandIndexAction extends BaseRestHandler {
+public class RestMarketRecordIndexAction extends BaseRestHandler {
 
-    private static final ESLogger log = ESLoggerFactory.getLogger(RestMarketDemandIndexAction.class.getName());
+    private static final ESLogger log = ESLoggerFactory.getLogger(RestMarketRecordIndexAction.class.getName());
 
     @Inject
-    public RestMarketDemandIndexAction(Settings settings, RestController controller, Client client) {
+    public RestMarketRecordIndexAction(Settings settings, RestController controller, Client client) {
         super(settings, controller, client);
-        controller.registerHandler(POST, "/market/demand", this);
+        controller.registerHandler(POST, "/market/record", this);
     }
 
     @Override
     protected void handleRequest(final RestRequest request, RestChannel restChannel, Client client) throws Exception {
 
         try {
-            String recordId = ServiceLocator.instance().getMarketRecordIndexerService().indexDemandFromJson(request.content().toUtf8());
+            String recordId = ServiceLocator.instance().getMarketRecordIndexerService().indexRecordFromJson(request.content().toUtf8());
 
             restChannel.sendResponse(new BytesRestResponse(OK, recordId));
         }
diff --git a/ucoinj-elasticsearch-plugin/src/test/es-home/plugins/ucoinj-elasticsearch/plugin-descriptor.properties b/ucoinj-elasticsearch-plugin/src/test/es-home/plugins/ucoinj-elasticsearch/plugin-descriptor.properties
index de3dcc30b890f6598aeee05350a453bdb5ff5d9c..de5abaf5d82cd0b505463db827c2ac9b7be10c69 100644
--- a/ucoinj-elasticsearch-plugin/src/test/es-home/plugins/ucoinj-elasticsearch/plugin-descriptor.properties
+++ b/ucoinj-elasticsearch-plugin/src/test/es-home/plugins/ucoinj-elasticsearch/plugin-descriptor.properties
@@ -5,5 +5,5 @@ site=false
 jvm=true
 classname=io.ucoin.ucoinj.elasticsearch.plugin.Plugin
 java.version=1.7
-elasticsearch.version=2.1.1
+elasticsearch.version=2.3.1
 isolated=false
\ No newline at end of file
diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/action/IndexerAction.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/action/IndexerAction.java
index 85831caed19acce807cb96e9d7f440ef7ab182f5..062d2320b5975d957db463d81f1f7a71e42b9105 100644
--- a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/action/IndexerAction.java
+++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/action/IndexerAction.java
@@ -30,12 +30,13 @@ import io.ucoin.ucoinj.core.client.model.local.Peer;
 import io.ucoin.ucoinj.core.client.service.bma.BlockchainRemoteService;
 import io.ucoin.ucoinj.core.util.websocket.WebsocketClientEndpoint;
 import io.ucoin.ucoinj.elasticsearch.config.Configuration;
-import io.ucoin.ucoinj.elasticsearch.service.BlockIndexerService;
+import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator;
+import io.ucoin.ucoinj.elasticsearch.service.currency.BlockIndexerService;
 import io.ucoin.ucoinj.elasticsearch.service.market.MarketCategoryIndexerService;
 import io.ucoin.ucoinj.elasticsearch.service.market.MarketRecordIndexerService;
-import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator;
 import io.ucoin.ucoinj.elasticsearch.service.registry.RegistryCategoryIndexerService;
 import io.ucoin.ucoinj.elasticsearch.service.registry.RegistryCitiesIndexerService;
+import io.ucoin.ucoinj.elasticsearch.service.registry.RegistryCurrencyIndexerService;
 import io.ucoin.ucoinj.elasticsearch.service.registry.RegistryRecordIndexerService;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
@@ -55,6 +56,8 @@ public class IndexerAction {
                 Configuration config = Configuration.instance();
                 final Peer peer = checkConfigAndGetPeer(config);
                 final BlockIndexerService blockIndexerService = ServiceLocator.instance().getBlockIndexerService();
+
+                // Will create the currency if not exist
                 blockIndexerService.indexLastBlocks(peer);
 
                 if (async) {
@@ -82,11 +85,17 @@ public class IndexerAction {
     }
 
     public void resetAllData() {
+        resetAllCurrencies();
         resetDataBlocks();
         resetMarketRecords();
         resetRegistry();
     }
 
+    public void resetAllCurrencies() {
+        RegistryCurrencyIndexerService currencyIndexerService = ServiceLocator.instance().getRegistryCurrencyIndexerService();
+        currencyIndexerService.deleteAllCurrencies();
+    }
+
     public void resetDataBlocks() {
         BlockchainRemoteService blockchainService = ServiceLocator.instance().getBlockchainRemoteService();
         BlockIndexerService indexerService = ServiceLocator.instance().getBlockIndexerService();
@@ -147,17 +156,23 @@ public class IndexerAction {
 
         try {
             // Delete then create index on records
-            boolean indexExists = recordIndexerService.existsIndex();
-            if (indexExists) {
+            if (recordIndexerService.existsIndex()) {
                 recordIndexerService.deleteIndex();
             }
+            recordIndexerService.createIndex();
             log.info(String.format("Successfully reset registry records"));
 
-            categoryIndexerService.createIndex();
 
+            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"));
 
diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/action/NodeAction.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/action/NodeAction.java
index fad714952a9b59012c97ce9635c6c3d9e5b0febf..94ded39bace18a0c1ea7f3d61c9de1468c8638b8 100644
--- a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/action/NodeAction.java
+++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/action/NodeAction.java
@@ -25,9 +25,11 @@ package io.ucoin.ucoinj.elasticsearch.action;
  */
 
 import io.ucoin.ucoinj.elasticsearch.config.Configuration;
-import io.ucoin.ucoinj.elasticsearch.service.*;
+import io.ucoin.ucoinj.elasticsearch.service.ElasticSearchService;
+import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator;
 import io.ucoin.ucoinj.elasticsearch.service.market.MarketCategoryIndexerService;
 import io.ucoin.ucoinj.elasticsearch.service.market.MarketRecordIndexerService;
+import io.ucoin.ucoinj.elasticsearch.service.registry.RegistryCurrencyIndexerService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -72,7 +74,7 @@ public class NodeAction {
         // Create indexed if need
         {
             // Currency index
-            CurrencyIndexerService currencyIndexerService = ServiceLocator.instance().getCurrencyIndexerService();
+            RegistryCurrencyIndexerService currencyIndexerService = ServiceLocator.instance().getRegistryCurrencyIndexerService();
             currencyIndexerService.createIndexIfNotExists();
 
             // Product index
diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/config/Configuration.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/config/Configuration.java
index 875e258b9cd35db2198c7a9e3ecfd364245df4fb..26412f8fc8a4eeb8c8fae81a0bdb197c320e9aea 100644
--- a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/config/Configuration.java
+++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/config/Configuration.java
@@ -310,4 +310,8 @@ public class Configuration  {
     public int getIndexBulkSize() {
         return applicationConfig.getOptionAsInt(ConfigurationOption.INDEX_BULK_SIZE.getKey());
     }
+
+    public String getIndexStringAnalyzer() {
+        return applicationConfig.getOption(ConfigurationOption.INDEX_STRING_ANALYZER.getKey());
+    }
 }
diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/config/ConfigurationOption.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/config/ConfigurationOption.java
index 7aef5d5a461291373c0b8680f909cf80f53ed630..ee5b588e8259f899e8dfdee49ad1eded36d06fe0 100644
--- a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/config/ConfigurationOption.java
+++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/config/ConfigurationOption.java
@@ -191,6 +191,13 @@ public enum ConfigurationOption  implements ConfigOptionDef {
             Integer.class,
             false),
 
+    INDEX_STRING_ANALYZER(
+            "ucoinj.elasticsearch.string.analyzer",
+            n("ucoinj.config.option.elasticsearch.string.analyze.description"),
+            "french",
+            String.class,
+            false),
+
     TASK_EXECUTOR_QUEUE_CAPACITY(
             "ucoinj.elasticsearch.tasks.queueCapacity",
             n("ucoinj.config.option.tasks.queueCapacity.description"),
diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/ElasticSearchService.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/ElasticSearchService.java
index 93194e3dd2a1f06e8e13e5e4694724a6444d8ace..0b84f165ca9d477acd648f37e764744e81ee08e6 100644
--- a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/ElasticSearchService.java
+++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/ElasticSearchService.java
@@ -51,7 +51,7 @@ import java.net.UnknownHostException;
  */
 public class ElasticSearchService implements Bean,InitializingBean, Closeable {
 
-    private static final Logger log = LoggerFactory.getLogger(CurrencyIndexerService.class);
+    private static final Logger log = LoggerFactory.getLogger(ElasticSearchService.class);
     private Client client;
     private Node node;
     private boolean localNode = false;
diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/ServiceLocator.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/ServiceLocator.java
index b9e1e409a054de4b3fa31d994a6266cfbd639770..237565bd85bc67689d973f2652f9782b003c54ed 100644
--- a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/ServiceLocator.java
+++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/ServiceLocator.java
@@ -23,9 +23,11 @@ package io.ucoin.ucoinj.elasticsearch.service;
  */
 
 
+import io.ucoin.ucoinj.elasticsearch.service.currency.BlockIndexerService;
 import io.ucoin.ucoinj.elasticsearch.service.market.MarketCategoryIndexerService;
 import io.ucoin.ucoinj.elasticsearch.service.market.MarketRecordIndexerService;
 import io.ucoin.ucoinj.elasticsearch.service.registry.RegistryCategoryIndexerService;
+import io.ucoin.ucoinj.elasticsearch.service.registry.RegistryCurrencyIndexerService;
 import io.ucoin.ucoinj.elasticsearch.service.registry.RegistryRecordIndexerService;
 import io.ucoin.ucoinj.elasticsearch.service.registry.RegistryCitiesIndexerService;
 import org.slf4j.Logger;
@@ -52,8 +54,8 @@ public class ServiceLocator extends io.ucoin.ucoinj.core.client.service.ServiceL
 
     /* -- ElasticSearch Service-- */
 
-    public CurrencyIndexerService getCurrencyIndexerService() {
-        return getBean(CurrencyIndexerService.class);
+    public RegistryCurrencyIndexerService getRegistryCurrencyIndexerService() {
+        return getBean(RegistryCurrencyIndexerService.class);
     }
 
     public ElasticSearchService getElasticSearchService() {
diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/BlockIndexerService.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/currency/BlockIndexerService.java
similarity index 97%
rename from ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/BlockIndexerService.java
rename to ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/currency/BlockIndexerService.java
index 8469dc6c12fa7f3489eedc81b04ed7437be6d846..af21900edbf65b93a1848390ac1a9ccb7d22bbdd 100644
--- a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/BlockIndexerService.java
+++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/currency/BlockIndexerService.java
@@ -1,4 +1,4 @@
-package io.ucoin.ucoinj.elasticsearch.service;
+package io.ucoin.ucoinj.elasticsearch.service.currency;
 
 /*
  * #%L
@@ -45,10 +45,12 @@ import io.ucoin.ucoinj.core.util.CollectionUtils;
 import io.ucoin.ucoinj.core.util.ObjectUtils;
 import io.ucoin.ucoinj.core.util.StringUtils;
 import io.ucoin.ucoinj.elasticsearch.config.Configuration;
+import io.ucoin.ucoinj.elasticsearch.service.BaseIndexerService;
+import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator;
 import io.ucoin.ucoinj.elasticsearch.service.exception.DuplicateIndexIdException;
+import io.ucoin.ucoinj.elasticsearch.service.registry.RegistryCurrencyIndexerService;
 import org.elasticsearch.action.ActionFuture;
 import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
-import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
 import org.elasticsearch.action.bulk.BulkItemResponse;
 import org.elasticsearch.action.bulk.BulkRequestBuilder;
 import org.elasticsearch.action.bulk.BulkResponse;
@@ -89,7 +91,7 @@ public class BlockIndexerService extends BaseIndexerService {
 
     private static final int SYNC_MISSING_BLOCK_MAX_RETRY = 5;
 
-    private CurrencyIndexerService currencyIndexerService;
+    private RegistryCurrencyIndexerService registryCurrencyIndexerService;
 
     private BlockchainRemoteService blockchainService;
 
@@ -104,7 +106,7 @@ public class BlockIndexerService extends BaseIndexerService {
     @Override
     public void afterPropertiesSet() throws Exception {
         super.afterPropertiesSet();
-        currencyIndexerService = ServiceLocator.instance().getCurrencyIndexerService();
+        registryCurrencyIndexerService = ServiceLocator.instance().getRegistryCurrencyIndexerService();
         blockchainService = ServiceLocator.instance().getBlockchainRemoteService();
         config = Configuration.instance();
     }
@@ -112,7 +114,7 @@ public class BlockIndexerService extends BaseIndexerService {
     @Override
     public void close() throws IOException {
         super.close();
-        currencyIndexerService = null;
+        registryCurrencyIndexerService = null;
         blockchainService = null;
         config = null;
         gson = null;
@@ -145,11 +147,11 @@ public class BlockIndexerService extends BaseIndexerService {
                     currencyName, config.getNodeBmaHost(), config.getNodeBmaPort()));
 
             // Create index currency if need
-            currencyIndexerService.createIndexIfNotExists();
+            registryCurrencyIndexerService.createIndexIfNotExists();
 
-            Currency currency = currencyIndexerService.getCurrencyById(currencyName);
+            Currency currency = registryCurrencyIndexerService.getCurrencyById(currencyName);
             if (currency == null) {
-                currencyIndexerService.indexCurrencyFromPeer(peer);
+                registryCurrencyIndexerService.indexCurrencyFromPeer(peer);
             }
 
             // Check if index exists
@@ -162,7 +164,7 @@ public class BlockIndexerService extends BaseIndexerService {
                 int maxBlockNumber = currentBlock.getNumber();
 
                 // DEV mode
-                if (!config.isFullMode()) {
+                if (!config.isFullMode() && maxBlockNumber > 5000) {
                     maxBlockNumber = 5000;
                 }
 
@@ -241,7 +243,7 @@ public class BlockIndexerService extends BaseIndexerService {
         Settings indexSettings = Settings.settingsBuilder()
                 .put("number_of_shards", 1)
                 .put("number_of_replicas", 1)
-                .put("analyzer", createDefaultAnalyzer())
+                //.put("analyzer", createDefaultAnalyzer())
                 .build();
         createIndexRequestBuilder.setSettings(indexSettings);
         createIndexRequestBuilder.addMapping(INDEX_TYPE_BLOCK, createIndexMapping());
@@ -681,6 +683,7 @@ public class BlockIndexerService extends BaseIndexerService {
         boolean debug = log.isDebugEnabled();
 
         int batchSize = config.getIndexBulkSize();
+        String currentBlockJson = null;
         JsonAttributeParser blockNumberParser = new JsonAttributeParser("number");
 
         for (int batchFirstNumber = firstNumber; batchFirstNumber < lastNumber; ) {
@@ -736,10 +739,7 @@ public class BlockIndexerService extends BaseIndexerService {
 
                     // If last block : also update the current block
                     if (itemNumber == lastNumber) {
-                        bulkRequest.add(client.prepareIndex(currencyName, INDEX_TYPE_BLOCK, INDEX_BLOCK_CURRENT_ID)
-                                .setRefresh(true)
-                                .setSource(blockAsJson)
-                        );
+                        currentBlockJson = blockAsJson;
                     }
                 }
 
@@ -772,6 +772,10 @@ public class BlockIndexerService extends BaseIndexerService {
 
         }
 
+        if (StringUtils.isNotBlank(currentBlockJson)) {
+            indexCurrentBlockAsJson(currencyName, currentBlockJson, false);
+        }
+
         return missingBlockNumbers;
     }
 
diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/market/MarketCategoryIndexerService.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/market/MarketCategoryIndexerService.java
index 660124a112bfc21c91d776951c2721db6006588c..2791037ed03709484a79895f3fe22e2891ee4bfa 100644
--- a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/market/MarketCategoryIndexerService.java
+++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/market/MarketCategoryIndexerService.java
@@ -94,7 +94,7 @@ public class MarketCategoryIndexerService extends BaseIndexerService {
         Settings indexSettings = Settings.settingsBuilder()
                 .put("number_of_shards", 1)
                 .put("number_of_replicas", 1)
-                .put("analyzer", createDefaultAnalyzer())
+                //.put("analyzer", createDefaultAnalyzer())
                 .build();
         createIndexRequestBuilder.setSettings(indexSettings);
         createIndexRequestBuilder.addMapping(INDEX_TYPE, createIndexMapping());
diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/market/MarketRecordIndexerService.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/market/MarketRecordIndexerService.java
index d81187d8b6bbd707c798c9e1c8f5bbc0a5d68677..312f92dde4d49ff28a2be3aa0531c0bff3cff0da 100644
--- a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/market/MarketRecordIndexerService.java
+++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/market/MarketRecordIndexerService.java
@@ -34,6 +34,7 @@ import io.ucoin.ucoinj.core.client.model.elasticsearch.Record;
 import io.ucoin.ucoinj.core.client.service.bma.WotRemoteService;
 import io.ucoin.ucoinj.core.exception.TechnicalException;
 import io.ucoin.ucoinj.core.service.CryptoService;
+import io.ucoin.ucoinj.core.util.StringUtils;
 import io.ucoin.ucoinj.elasticsearch.config.Configuration;
 import io.ucoin.ucoinj.elasticsearch.service.BaseIndexerService;
 import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator;
@@ -62,13 +63,14 @@ public class MarketRecordIndexerService extends BaseIndexerService {
 
     public static final String INDEX_NAME = "market";
 
-    public static final String INDEX_TYPE_OFFER = "offer";
-    public static final String INDEX_TYPE_DEMAND = "demand";
+    public static final String INDEX_TYPE = "record";
 
     private WotRemoteService wotRemoteService;
 
     private CryptoService cryptoService;
 
+    private Configuration config;
+
     public MarketRecordIndexerService() {
 
     }
@@ -78,6 +80,7 @@ public class MarketRecordIndexerService extends BaseIndexerService {
         super.afterPropertiesSet();
         wotRemoteService = ServiceLocator.instance().getWotRemoteService();
         cryptoService = ServiceLocator.instance().getCryptoService();
+        config = Configuration.instance();
     }
 
     @Override
@@ -122,45 +125,35 @@ public class MarketRecordIndexerService extends BaseIndexerService {
         Settings indexSettings = Settings.settingsBuilder()
                 .put("number_of_shards", 3)
                 .put("number_of_replicas", 2)
-                .put("analyzer", createDefaultAnalyzer())
+                //.put("analyzer", createDefaultAnalyzer())
                 .build();
 
-        // Create offer index
-        log.info(String.format("Creating index [%s/%s]", INDEX_NAME, INDEX_TYPE_OFFER));
-        createIndexRequestBuilder.setSettings(indexSettings);
-        createIndexRequestBuilder.addMapping(INDEX_TYPE_OFFER, createIndexMapping(INDEX_TYPE_OFFER));
-        createIndexRequestBuilder.execute().actionGet();
-
-        // Create demand index
-        log.info(String.format("Creating index [%s/%s]", INDEX_NAME, INDEX_TYPE_DEMAND));
+        // Create record index type
+        log.info(String.format("Creating index [%s/%s]", INDEX_NAME, INDEX_TYPE));
         createIndexRequestBuilder.setSettings(indexSettings);
-        createIndexRequestBuilder.addMapping(INDEX_TYPE_DEMAND, createIndexMapping(INDEX_TYPE_DEMAND));
+        createIndexRequestBuilder.addMapping(INDEX_NAME, createIndexMapping(INDEX_TYPE));
         createIndexRequestBuilder.execute().actionGet();
     }
 
     /**
-     * Index a new offer
+     * Index a new record
      * @param recordJson
      * @return the record id
      */
-    public String indexOfferFromJson(String recordJson) {
+    public String indexRecordFromJson(String recordJson) {
 
-        return indexRecordFromJson(recordJson, INDEX_TYPE_OFFER);
-    }
-
-    /**
-     * Index a new demand
-     * @param recordJson
-     * @return the record id
-     */
-    public String indexDemandFromJson(String recordJson) {
-        return indexRecordFromJson(recordJson, INDEX_TYPE_DEMAND);
+        return indexRecordFromJson(recordJson, INDEX_TYPE);
     }
 
     /* -- Internal methods -- */
 
 
     public XContentBuilder createIndexMapping(String indexType) {
+        String stringAnalyzer = config.getIndexStringAnalyzer();
+        if (StringUtils.isBlank(stringAnalyzer)) {
+            stringAnalyzer = "english";
+        }
+
         try {
             XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject(indexType)
                     .startObject("properties")
@@ -168,11 +161,13 @@ public class MarketRecordIndexerService extends BaseIndexerService {
                     // title
                     .startObject("title")
                     .field("type", "string")
+                    .field("analyzer", stringAnalyzer)
                     .endObject()
 
                     // description
                     .startObject("description")
                     .field("type", "string")
+                    .field("analyzer", stringAnalyzer)
                     .endObject()
 
                     // time
@@ -180,25 +175,61 @@ public class MarketRecordIndexerService extends BaseIndexerService {
                     .field("type", "integer")
                     .endObject()
 
+                    // price
+                    .startObject("price")
+                    .field("type", "double")
+                    .endObject()
+
+                    // price Id UD
+                    .startObject("priceInUD")
+                    .field("type", "boolean")
+                    .endObject()
+
                     // issuer
                     .startObject("issuer")
                     .field("type", "string")
+                    .field("index", "not_analyzed")
                     .endObject()
 
-                    // issuer
+                    // location
                     .startObject("location")
+                    .field("type", "string")
+                    .endObject()
+
+                    // geoPoint
+                    .startObject("geoPoint")
                     .field("type", "geo_point")
                     .endObject()
 
+                    // pictures
+                    .startObject("pictures")
+                    .field("type", "nested")
+                    .startObject("properties")
+                    .startObject("src") // src
+                    .field("type", "attachment")
+                    .field("index", "not_analyzed")
+                    .endObject()
+                    .startObject("title") // title
+                    .field("title", "string")
+                    .field("analyzer", stringAnalyzer)
+                    .startObject("norms") // disabled norms on title
+                    .field("enabled", "false")
+                    .endObject()
+                    .endObject()
+                    .endObject()
+                    .endObject()
+
                     // categories
                     .startObject("categories")
                     .field("type", "nested")
                     .startObject("properties")
                     .startObject("cat1") // cat1
                     .field("type", "string")
+                    .field("index", "not_analyzed")
                     .endObject()
                     .startObject("cat2") // cat2
                     .field("type", "string")
+                    .field("index", "not_analyzed")
                     .endObject()
                     .endObject()
                     .endObject()
diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/registry/RegistryCategoryIndexerService.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/registry/RegistryCategoryIndexerService.java
index cae674e8f6a994f99d6355323aafd01fc2dcbb4f..24b34ef487c110e6be6c94fb29040dec85a30f7b 100644
--- a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/registry/RegistryCategoryIndexerService.java
+++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/registry/RegistryCategoryIndexerService.java
@@ -30,6 +30,7 @@ import io.ucoin.ucoinj.core.exception.TechnicalException;
 import io.ucoin.ucoinj.core.util.StringUtils;
 import io.ucoin.ucoinj.elasticsearch.config.Configuration;
 import io.ucoin.ucoinj.elasticsearch.service.BaseIndexerService;
+import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator;
 import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
 import org.elasticsearch.action.bulk.BulkRequest;
 import org.elasticsearch.action.index.IndexRequestBuilder;
@@ -59,6 +60,14 @@ public class RegistryCategoryIndexerService extends BaseIndexerService {
     public static final String INDEX_NAME = "registry";
     public static final String INDEX_TYPE = "category";
 
+    private Configuration config;
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        super.afterPropertiesSet();
+        config = Configuration.instance();
+    }
+
     /**
      * Delete currency index, and all data
      * @throws JsonProcessingException
@@ -97,7 +106,7 @@ public class RegistryCategoryIndexerService extends BaseIndexerService {
         Settings indexSettings = Settings.settingsBuilder()
                 .put("number_of_shards", 1)
                 .put("number_of_replicas", 1)
-                .put("analyzer", createDefaultAnalyzer())
+                //.put("analyzer", createDefaultAnalyzer())
                 .build();
         createIndexRequestBuilder.setSettings(indexSettings);
         createIndexRequestBuilder.addMapping(INDEX_TYPE, createIndexMapping());
@@ -140,6 +149,11 @@ public class RegistryCategoryIndexerService extends BaseIndexerService {
 
 
     public XContentBuilder createIndexMapping() {
+        String stringAnalyzer = config.getIndexStringAnalyzer();
+        if (StringUtils.isBlank(stringAnalyzer)) {
+            stringAnalyzer = "english";
+        }
+
         try {
             XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject(INDEX_TYPE)
                     .startObject("properties")
@@ -147,6 +161,7 @@ public class RegistryCategoryIndexerService extends BaseIndexerService {
                     // name
                     .startObject("name")
                     .field("type", "string")
+                    .field("analyzer", stringAnalyzer)
                     .endObject()
 
                     // description
@@ -157,6 +172,7 @@ public class RegistryCategoryIndexerService extends BaseIndexerService {
                     // parent
                     .startObject("parent")
                     .field("type", "string")
+                    .field("index", "not_analyzed")
                     .endObject()
 
                     // tags
diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/registry/RegistryCitiesIndexerService.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/registry/RegistryCitiesIndexerService.java
index 5e86d47ca1301dce8542592b740c0153c133620b..f674ef444f5cf747971f50096dfa531065ce449a 100644
--- a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/registry/RegistryCitiesIndexerService.java
+++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/registry/RegistryCitiesIndexerService.java
@@ -54,6 +54,8 @@ public class RegistryCitiesIndexerService extends BaseIndexerService {
 
     private static final String CITIES_SOURCE_CLASSPATH_FILE = "cities/countriesToCities.json";
 
+    private static final String CITIES_SOURCE_FILE2 = "/home/blavenie/git/ucoin-io/ucoinj/ucoinj-elasticsearch/src/main/misc/geoflar-communes-2015.geojson";
+
     public static final String INDEX_NAME = "registry";
     public static final String INDEX_TYPE = "city";
 
@@ -116,7 +118,7 @@ public class RegistryCitiesIndexerService extends BaseIndexerService {
         Settings indexSettings = Settings.settingsBuilder()
                 .put("number_of_shards", 1)
                 .put("number_of_replicas", 1)
-                .put("analyzer", createDefaultAnalyzer())
+                //.put("analyzer", createDefaultAnalyzer())
                 .build();
         createIndexRequestBuilder.setSettings(indexSettings);
         createIndexRequestBuilder.addMapping(INDEX_TYPE, createIndexMapping());
@@ -128,10 +130,10 @@ public class RegistryCitiesIndexerService extends BaseIndexerService {
             log.debug("Initializing all registry cities");
         }
 
-        File bulkFile = createCitiesBulkFile();
+        //File bulkFile = createCitiesBulkFile2();
 
         // Insert cities
-        bulkFromFile(bulkFile, INDEX_NAME, INDEX_TYPE);
+        //bulkFromFile(bulkFile, INDEX_NAME, INDEX_TYPE);
     }
 
 
@@ -139,6 +141,7 @@ public class RegistryCitiesIndexerService extends BaseIndexerService {
 
 
     public XContentBuilder createIndexMapping() {
+
         try {
             XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject(INDEX_TYPE)
                     .startObject("properties")
@@ -151,6 +154,7 @@ public class RegistryCitiesIndexerService extends BaseIndexerService {
                     // country
                     .startObject("country")
                     .field("type", "string")
+                    .field("index", "not_analyzed")
                     .endObject()
 
                     .endObject()
@@ -262,4 +266,105 @@ public class RegistryCitiesIndexerService extends BaseIndexerService {
 
         return result;
     }
+
+    public File createCitiesBulkFile2() {
+
+        File result = new File(config.getTempDirectory(), CITIES_BULK_FILENAME);
+        File inputFile = new File(CITIES_SOURCE_FILE2);
+
+        InputStream ris = null;
+        BufferedReader bf = null;
+        FileWriter fw = null;
+        try {
+            if (result.exists()) {
+                FileUtils.forceDelete(result);
+            }
+            else if (!result.getParentFile().exists()) {
+                FileUtils.forceMkdir(result.getParentFile());
+            }
+
+            ris = new BufferedInputStream(new FileInputStream(inputFile));
+            if (ris == null) {
+                throw new TechnicalException(String.format("Could not retrieve file [%s] from test classpath. Make sure git submodules has been initialized before building.", CITIES_SOURCE_FILE2));
+            }
+
+            boolean firstLine = true;
+            java.lang.reflect.Type typeOfHashMap = new TypeToken<Map<String, String[]>>() { }.getType();
+
+            Gson gson = GsonUtils.newBuilder().create();
+
+            StringBuilder builder = new StringBuilder();
+            bf = new BufferedReader(
+                    new InputStreamReader(
+                            ris, "UTF-16LE"), 2048);
+
+            fw = new FileWriter(result);
+            char[] buf = new char[2048];
+            int len;
+
+            while((len = bf.read(buf)) != -1) {
+                String bufStr = new String(buf, 0, len);
+
+                if (firstLine) {
+                    // Remove UTF-16 BOM char
+                    int objectStartIndex = bufStr.indexOf('\uFEFF');
+                    if (objectStartIndex != -1) {
+                        bufStr = bufStr.substring(objectStartIndex);
+                    }
+                    firstLine=false;
+                }
+
+                int arrayEndIndex = bufStr.indexOf("],\"");
+                if (arrayEndIndex == -1) {
+                    arrayEndIndex = bufStr.indexOf("]}");
+                }
+
+                if (arrayEndIndex == -1) {
+                    builder.append(bufStr);
+                }
+                else {
+                    builder.append(bufStr.substring(0, arrayEndIndex+1));
+                    builder.append("}");
+                    if (log.isTraceEnabled()) {
+                        log.trace(builder.toString());
+                    }
+                    Map<String, String[]> citiesByCountry = gson.fromJson(builder.toString(), typeOfHashMap);
+
+                    builder.setLength(0);
+                    for (String country: citiesByCountry.keySet()) {
+                        if (StringUtils.isNotBlank(country)) {
+                            for (String city : citiesByCountry.get(country)) {
+                                if (StringUtils.isNotBlank(city)) {
+                                    fw.write(String.format("{\"index\":{\"_id\" : \"%s-%s\"}}\n", country, city));
+                                    fw.write(String.format("{\"country\":\"%s\", \"name\":\"%s\"}\n", country, city));
+                                }
+                            }
+                        }
+                    }
+
+                    fw.flush();
+
+                    // reset and prepare buffer for next country
+                    builder.setLength(0);
+                    builder.append("{");
+                    if (arrayEndIndex+2 < bufStr.length()) {
+                        builder.append(bufStr.substring(arrayEndIndex+2));
+                    }
+                }
+            }
+
+            fw.close();
+            bf.close();
+
+        } catch(Exception e) {
+            throw new TechnicalException(String.format("Error while creating cities file [%s]", result.getName()), e);
+        }
+        finally {
+            IOUtils.closeQuietly(bf);
+            IOUtils.closeQuietly(ris);
+            IOUtils.closeQuietly(fw);
+        }
+
+        return result;
+    }
 }
diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/CurrencyIndexerService.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/registry/RegistryCurrencyIndexerService.java
similarity index 89%
rename from ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/CurrencyIndexerService.java
rename to ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/registry/RegistryCurrencyIndexerService.java
index d215e2c69afad98c5a3c24a4a84c5d5e20efc350..f99cbfd2993624d3a19e55214e1cf92f7a167d95 100644
--- a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/CurrencyIndexerService.java
+++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/registry/RegistryCurrencyIndexerService.java
@@ -1,4 +1,4 @@
-package io.ucoin.ucoinj.elasticsearch.service;
+package io.ucoin.ucoinj.elasticsearch.service.registry;
 
 /*
  * #%L
@@ -29,21 +29,23 @@ import com.google.common.collect.Lists;
 import com.google.gson.Gson;
 import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock;
 import io.ucoin.ucoinj.core.client.model.bma.BlockchainParameters;
+import io.ucoin.ucoinj.core.client.model.bma.gson.GsonUtils;
+import io.ucoin.ucoinj.core.client.model.elasticsearch.Currency;
 import io.ucoin.ucoinj.core.client.model.local.Peer;
 import io.ucoin.ucoinj.core.client.service.bma.BlockchainRemoteService;
+import io.ucoin.ucoinj.core.exception.TechnicalException;
 import io.ucoin.ucoinj.core.service.CryptoService;
 import io.ucoin.ucoinj.core.util.ObjectUtils;
-import io.ucoin.ucoinj.core.client.model.bma.gson.GsonUtils;
-import io.ucoin.ucoinj.core.exception.TechnicalException;
-import io.ucoin.ucoinj.core.client.model.elasticsearch.Currency;
 import io.ucoin.ucoinj.elasticsearch.model.SearchResult;
+import io.ucoin.ucoinj.elasticsearch.service.BaseIndexerService;
+import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator;
+import io.ucoin.ucoinj.elasticsearch.service.currency.BlockIndexerService;
 import io.ucoin.ucoinj.elasticsearch.service.exception.AccessDeniedException;
 import io.ucoin.ucoinj.elasticsearch.service.exception.DuplicateIndexIdException;
 import io.ucoin.ucoinj.elasticsearch.service.exception.InvalidSignatureException;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.ArrayUtils;
 import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
-import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
 import org.elasticsearch.action.index.IndexRequestBuilder;
 import org.elasticsearch.action.search.SearchPhaseExecutionException;
 import org.elasticsearch.action.search.SearchRequestBuilder;
@@ -73,13 +75,13 @@ import java.util.Objects;
 /**
  * Created by Benoit on 30/03/2015.
  */
-public class CurrencyIndexerService extends BaseIndexerService {
+public class RegistryCurrencyIndexerService extends BaseIndexerService {
 
-    private static final Logger log = LoggerFactory.getLogger(CurrencyIndexerService.class);
+    private static final Logger log = LoggerFactory.getLogger(RegistryCurrencyIndexerService.class);
 
-    public static final String INDEX_NAME = "currency";
+    public static final String INDEX_NAME = "registry";
 
-    public static final String INDEX_TYPE_SIMPLE = "simple";
+    public static final String INDEX_TYPE = "currency";
 
     public static final String REGEX_WORD_SEPARATOR = "[-\\t@# ]+";
     public static final String REGEX_SPACE = "[\\t\\n\\r ]+";
@@ -88,7 +90,7 @@ public class CurrencyIndexerService extends BaseIndexerService {
     private BlockIndexerService blockIndexerService;
     private Gson gson;
 
-    public CurrencyIndexerService() {
+    public RegistryCurrencyIndexerService() {
         super();
         this.gson = GsonUtils.newBuilder().create();
     }
@@ -136,16 +138,16 @@ public class CurrencyIndexerService extends BaseIndexerService {
      * @throws JsonProcessingException
      */
     public void createIndex() throws JsonProcessingException {
-        log.info(String.format("Creating index [%s/]", INDEX_NAME, INDEX_TYPE_SIMPLE));
+        log.info(String.format("Creating index [%s/]", INDEX_NAME, INDEX_TYPE));
 
         CreateIndexRequestBuilder createIndexRequestBuilder = getClient().admin().indices().prepareCreate(INDEX_NAME);
         Settings indexSettings = Settings.settingsBuilder()
                 .put("number_of_shards", 1)
                 .put("number_of_replicas", 1)
-                .put("analyzer", createDefaultAnalyzer())
+                //.put("analyzer", createDefaultAnalyzer())
                 .build();
         createIndexRequestBuilder.setSettings(indexSettings);
-        createIndexRequestBuilder.addMapping(INDEX_TYPE_SIMPLE, createIndexMapping());
+        createIndexRequestBuilder.addMapping(INDEX_TYPE, createIndexMapping());
         createIndexRequestBuilder.execute().actionGet();
     }
 
@@ -207,7 +209,7 @@ public class CurrencyIndexerService extends BaseIndexerService {
             byte[] json = getObjectMapper().writeValueAsBytes(currency);
 
             // Preparing indexBlocksFromNode
-            IndexRequestBuilder indexRequest = getClient().prepareIndex(INDEX_NAME, INDEX_TYPE_SIMPLE)
+            IndexRequestBuilder indexRequest = getClient().prepareIndex(INDEX_NAME, INDEX_TYPE)
                     .setId(currency.getCurrencyName())
                     .setSource(json);
 
@@ -227,7 +229,7 @@ public class CurrencyIndexerService extends BaseIndexerService {
      * @return
      */
     public List<String> getSuggestions(String query) {
-        CompletionSuggestionBuilder suggestionBuilder = new CompletionSuggestionBuilder(INDEX_TYPE_SIMPLE)
+        CompletionSuggestionBuilder suggestionBuilder = new CompletionSuggestionBuilder(INDEX_TYPE)
             .text(query)
             .size(10) // limit to 10 results
             .field("tags");
@@ -241,7 +243,7 @@ public class CurrencyIndexerService extends BaseIndexerService {
         SuggestResponse response = suggestRequest.execute().actionGet();
 
         // Read query result
-        return toSuggestions(response, INDEX_TYPE_SIMPLE, query);
+        return toSuggestions(response, INDEX_TYPE, query);
     }
 
     /**
@@ -255,7 +257,7 @@ public class CurrencyIndexerService extends BaseIndexerService {
         // Prepare request
         SearchRequestBuilder searchRequest = getClient()
                 .prepareSearch(INDEX_NAME)
-                .setTypes(INDEX_TYPE_SIMPLE)
+                .setTypes(INDEX_TYPE)
                 .setSearchType(SearchType.DFS_QUERY_THEN_FETCH);
 
         // If only one term, search as prefix
@@ -268,9 +270,9 @@ public class CurrencyIndexerService extends BaseIndexerService {
             searchRequest.setQuery(QueryBuilders.matchQuery("currencyName", query));
         }
 
-        // Sort as score/memberCount
+        // Sort as score/membersCount
         searchRequest.addSort("_score", SortOrder.DESC)
-                .addSort("memberCount", SortOrder.DESC);
+                .addSort("membersCount", SortOrder.DESC);
 
         // Highlight matched words
         searchRequest.setHighlighterTagsSchema("styled")
@@ -285,6 +287,33 @@ public class CurrencyIndexerService extends BaseIndexerService {
         return toCurrencies(searchResponse, true);
     }
 
+    public void deleteAllCurrencies() {
+        if (!existsIndex(INDEX_NAME)) {
+            return;
+        }
+
+        log.info(String.format("Deleting all currency indexes"));
+
+        // Prepare request
+        SearchRequestBuilder request = getClient()
+                .prepareSearch(INDEX_NAME)
+                .setTypes(INDEX_TYPE);
+
+        // Execute query
+        SearchResponse response = request.execute().actionGet();
+
+        // Delete every currencies
+        List<Currency> currencies = toCurrencies(response);
+        for (Currency currency: currencies){
+            log.info(String.format("Deleting currency [%s]...", currency.getCurrencyName()));
+            deleteIndexIfExists(currency.getCurrencyName());
+        }
+
+        deleteIndexIfExists(INDEX_NAME);
+
+        log.info("All currency successfully deleted");
+    }
+
     /**
      * find currency that match string query (full text search), and return a generic VO for search result.
      * @param query
@@ -296,7 +325,7 @@ public class CurrencyIndexerService extends BaseIndexerService {
         // Prepare request
         SearchRequestBuilder searchRequest = getClient()
                 .prepareSearch(INDEX_NAME)
-                .setTypes(INDEX_TYPE_SIMPLE)
+                .setTypes(INDEX_TYPE)
                 .setSearchType(SearchType.DFS_QUERY_THEN_FETCH);
 
         // If only one term, search as prefix
@@ -309,15 +338,15 @@ public class CurrencyIndexerService extends BaseIndexerService {
             searchRequest.setQuery(QueryBuilders.matchQuery("currencyName", query));
         }
 
-        // Sort as score/memberCount
+        // Sort as score/membersCount
         searchRequest.addSort("_score", SortOrder.DESC)
-                .addSort("memberCount", SortOrder.DESC);
+                .addSort("membersCount", SortOrder.DESC);
 
         // Highlight matched words
         searchRequest.setHighlighterTagsSchema("styled")
                 .addHighlightedField("currencyName")
                 .addFields("currencyName")
-                .addFields("memberCount");
+                .addFields("membersCount");
 
         // Execute query
         SearchResponse searchResponse = searchRequest.execute().actionGet();
@@ -340,7 +369,7 @@ public class CurrencyIndexerService extends BaseIndexerService {
         // Prepare request
         SearchRequestBuilder searchRequest = getClient()
                 .prepareSearch(INDEX_NAME)
-                .setTypes(INDEX_TYPE_SIMPLE)
+                .setTypes(INDEX_TYPE)
                 .setSearchType(SearchType.DFS_QUERY_THEN_FETCH);
 
         // If more than a word, search on terms match
@@ -350,7 +379,7 @@ public class CurrencyIndexerService extends BaseIndexerService {
         List<Currency> currencies = null;
         try {
             SearchResponse searchResponse = searchRequest.execute().actionGet();
-            currencies = toCurrencies(searchResponse, false);
+            currencies = toCurrencies(searchResponse);
         }
         catch(SearchPhaseExecutionException e) {
             // Failed or no item on index
@@ -409,9 +438,9 @@ public class CurrencyIndexerService extends BaseIndexerService {
         // Prepare request
         SearchRequestBuilder searchRequest = getClient()
                 .prepareSearch(INDEX_NAME)
-                .setTypes(INDEX_TYPE_SIMPLE);
+                .setTypes(INDEX_TYPE);
 
-        // Sort as score/memberCount
+        // Sort as score/membersCount
         searchRequest.addSort("currencyName", SortOrder.ASC)
             .addField("_id");
 
@@ -457,7 +486,7 @@ public class CurrencyIndexerService extends BaseIndexerService {
 
     public XContentBuilder createIndexMapping() {
         try {
-            XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject(INDEX_TYPE_SIMPLE)
+            XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject(INDEX_TYPE)
                 .startObject("properties")
 
                 // currency name
@@ -466,8 +495,8 @@ public class CurrencyIndexerService extends BaseIndexerService {
                 .endObject()
 
                 // member count
-                .startObject("memberCount")
-                .field("type", "integer")
+                .startObject("membersCount")
+                .field("type", "long")
                 .endObject()
 
                 // tags
@@ -484,7 +513,7 @@ public class CurrencyIndexerService extends BaseIndexerService {
             return mapping;
         }
         catch(IOException ioe) {
-            throw new TechnicalException(String.format("Error while getting mapping for index [%s/%s]: %s", INDEX_NAME, INDEX_TYPE_SIMPLE, ioe.getMessage()), ioe);
+            throw new TechnicalException(String.format("Error while getting mapping for index [%s/%s]: %s", INDEX_NAME, INDEX_TYPE, ioe.getMessage()), ioe);
         }
     }
 
@@ -504,6 +533,10 @@ public class CurrencyIndexerService extends BaseIndexerService {
         ServiceLocator.instance().getBlockIndexerService().createIndex(currency.getCurrencyName());
     }
 
+    protected List<Currency> toCurrencies(SearchResponse response) {
+        return toCurrencies(response, false);
+    }
+
     protected List<Currency> toCurrencies(SearchResponse response, boolean withHighlight) {
         try {
             // Read query result
@@ -512,7 +545,7 @@ public class CurrencyIndexerService extends BaseIndexerService {
             for (SearchHit searchHit : searchHits) {
                 Currency currency = null;
                 if (searchHit.source() != null) {
-                    currency = getObjectMapper().readValue(searchHit.source(), Currency.class);
+                    currency = gson.fromJson(new String(searchHit.source(), "UTF-8"), Currency.class);
                 }
                 else {
                     currency = new Currency();
diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/registry/RegistryRecordIndexerService.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/registry/RegistryRecordIndexerService.java
index 6f8dbaf475d8988af7fede44f64c0e73f5354098..8cba7acde996ac8ef2e93a9fa068bdea72ffcf6a 100644
--- a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/registry/RegistryRecordIndexerService.java
+++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/registry/RegistryRecordIndexerService.java
@@ -34,6 +34,7 @@ import io.ucoin.ucoinj.core.client.model.elasticsearch.Record;
 import io.ucoin.ucoinj.core.client.service.bma.WotRemoteService;
 import io.ucoin.ucoinj.core.exception.TechnicalException;
 import io.ucoin.ucoinj.core.service.CryptoService;
+import io.ucoin.ucoinj.core.util.StringUtils;
 import io.ucoin.ucoinj.elasticsearch.config.Configuration;
 import io.ucoin.ucoinj.elasticsearch.service.BaseIndexerService;
 import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator;
@@ -130,7 +131,7 @@ public class RegistryRecordIndexerService extends BaseIndexerService {
         Settings indexSettings = Settings.settingsBuilder()
                 .put("number_of_shards", 1)
                 .put("number_of_replicas", 1)
-                .put("analyzer", createDefaultAnalyzer())
+                //.put("analyzer", createDefaultAnalyzer())
                 .build();
         createIndexRequestBuilder.setSettings(indexSettings);
         createIndexRequestBuilder.addMapping(INDEX_TYPE, createIndexMapping());
@@ -162,6 +163,11 @@ public class RegistryRecordIndexerService extends BaseIndexerService {
                 throw new InvalidSignatureException("Invalid signature for JSON string: " + recordNoSign);
             }
 
+            // TODO verify hash
+            //if (!cryptoService.verifyHash(recordNoSign, signature, issuer)) {
+            //    throw new InvalidSignatureException("Invalid signature for JSON string: " + recordNoSign);
+            //}
+
             if (log.isDebugEnabled()) {
                 log.debug(String.format("Indexing a record from issuer [%s]", issuer.substring(0, 8)));
             }
@@ -198,6 +204,11 @@ public class RegistryRecordIndexerService extends BaseIndexerService {
 
 
     public XContentBuilder createIndexMapping() {
+        String stringAnalyzer = config.getIndexStringAnalyzer();
+        if (StringUtils.isBlank(stringAnalyzer)) {
+            stringAnalyzer = "english";
+        }
+
         try {
             XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject(INDEX_TYPE)
                     .startObject("properties")
@@ -205,11 +216,13 @@ public class RegistryRecordIndexerService extends BaseIndexerService {
                     // title
                     .startObject("title")
                     .field("type", "string")
+                    .field("analyzer", stringAnalyzer)
                     .endObject()
 
                     // description
                     .startObject("description")
                     .field("type", "string")
+                    .field("analyzer", stringAnalyzer)
                     .endObject()
 
                     // time
@@ -220,22 +233,36 @@ public class RegistryRecordIndexerService extends BaseIndexerService {
                     // issuer
                     .startObject("issuer")
                     .field("type", "string")
+                    .field("index", "not_analyzed")
                     .endObject()
 
-                    // issuer
+                    // location
                     .startObject("location")
+                    .field("type", "string")
+                    .endObject()
+
+                    // geoPoint
+                    .startObject("geoPoint")
                     .field("type", "geo_point")
                     .endObject()
 
+                    // avatar
+                    .startObject("avatar")
+                    .field("type", "string")
+                    .field("index", "not_analyzed")
+                    .endObject()
+
                     // categories
                     .startObject("categories")
                     .field("type", "nested")
                     .startObject("properties")
                     .startObject("cat1") // cat1
                     .field("type", "string")
+                    .field("index", "not_analyzed")
                     .endObject()
                     .startObject("cat2") // cat2
                     .field("type", "string")
+                    .field("index", "not_analyzed")
                     .endObject()
                     .endObject()
                     .endObject()
diff --git a/ucoinj-elasticsearch/src/main/misc/cities-fr.geoJson.txt b/ucoinj-elasticsearch/src/main/misc/cities-fr.geoJson.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bb4b1bd422f6de2c147bba0ab39ce74aadf01f6c
--- /dev/null
+++ b/ucoinj-elasticsearch/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/ucoinj-elasticsearch/src/main/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean b/ucoinj-elasticsearch/src/main/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean
index 472e0b171c9cde90b77afd83c77e046d7d5e27d2..32427c9dcf4a3b778e9d9f7d136aaf8770160499 100644
--- a/ucoinj-elasticsearch/src/main/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean
+++ b/ucoinj-elasticsearch/src/main/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean
@@ -11,11 +11,11 @@ io.ucoin.ucoinj.core.client.service.local.CurrencyServiceImpl
 io.ucoin.ucoinj.core.client.dao.mem.MemoryCurrencyDaoImpl
 io.ucoin.ucoinj.core.client.dao.mem.MemoryPeerDaoImpl
 io.ucoin.ucoinj.elasticsearch.service.ElasticSearchService
-io.ucoin.ucoinj.elasticsearch.service.CurrencyIndexerService
-io.ucoin.ucoinj.elasticsearch.service.BlockIndexerService
+io.ucoin.ucoinj.elasticsearch.service.currency.BlockIndexerService
 io.ucoin.ucoinj.elasticsearch.service.ExecutorServiceImpl
 io.ucoin.ucoinj.elasticsearch.service.market.MarketRecordIndexerService
 io.ucoin.ucoinj.elasticsearch.service.market.MarketCategoryIndexerService
+io.ucoin.ucoinj.elasticsearch.service.registry.RegistryCurrencyIndexerService
 io.ucoin.ucoinj.elasticsearch.service.registry.RegistryRecordIndexerService
 io.ucoin.ucoinj.elasticsearch.service.registry.RegistryCategoryIndexerService
 io.ucoin.ucoinj.elasticsearch.service.registry.RegistryCitiesIndexerService
diff --git a/ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/service/CurrencyIndexerServiceTest.java b/ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/service/CurrencyIndexerServiceTest.java
deleted file mode 100644
index 84ac72e9ad1f0c8ee3154aca15d4d9e57c35bf5c..0000000000000000000000000000000000000000
--- a/ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/service/CurrencyIndexerServiceTest.java
+++ /dev/null
@@ -1,210 +0,0 @@
-package io.ucoin.ucoinj.elasticsearch.service;
-
-/*
- * #%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%
- */
-
-import io.ucoin.ucoinj.core.client.model.local.Wallet;
-import io.ucoin.ucoinj.core.client.model.bma.BlockchainParameters;
-import io.ucoin.ucoinj.core.client.service.bma.BlockchainRemoteService;
-import io.ucoin.ucoinj.core.service.CryptoService;
-import io.ucoin.ucoinj.core.client.model.bma.gson.GsonUtils;
-import io.ucoin.ucoinj.core.client.model.local.Peer;
-import io.ucoin.ucoinj.core.util.crypto.CryptoUtils;
-import io.ucoin.ucoinj.elasticsearch.TestResource;
-import io.ucoin.ucoinj.elasticsearch.config.Configuration;
-import io.ucoin.ucoinj.core.client.model.elasticsearch.Currency;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.List;
-
-/**
- * Created by Benoit on 06/05/2015.
- */
-public class CurrencyIndexerServiceTest {
-    private static final Logger log = LoggerFactory.getLogger(CurrencyIndexerService.class);
-
-    @ClassRule
-    public static final TestResource resource = TestResource.create();
-
-    private CurrencyIndexerService service;
-    private Configuration config;
-    private Peer peer;
-
-    @Before
-    public void setUp() throws Exception {
-        service = ServiceLocator.instance().getCurrencyIndexerService();
-        config = Configuration.instance();
-        peer = createTestPeer();
-
-        if (config.isLocal()) {
-            initLocalNode();
-        }
-    }
-
-    @Test
-    public void registerCurrency() {
-        Currency currency = new Currency();
-        currency.setCurrencyName("register-test-" + System.currentTimeMillis());
-
-        String currencyJson = GsonUtils.newBuilder().create().toJson(currency);
-
-        String pubKey = resource.getFixtures().getUserPublicKey();
-        String secretKey = resource.getFixtures().getUserSecretKey();
-
-        CryptoService cryptoService = ServiceLocator.instance().getCryptoService();
-        String signature = cryptoService.sign(currencyJson, secretKey);
-
-        service.registerCurrency(pubKey, currencyJson, signature);
-    }
-
-
-    @Test
-    public void createIndex() throws Exception {
-
-        // drop and recreate index
-        service.deleteIndex();
-
-        service.createIndex();
-    }
-
-    @Test
-    public void getAllCurrencyNames() {
-        List<String> currencyNames = service.getAllCurrencyNames();
-        for (String currencyName: currencyNames) {
-            log.info("  - " + currencyName);
-        }
-    }
-
-    @Test
-    public void allInOne() throws Exception {
-
-        createIndex();
-        indexCurrency();
-        getSuggestions();
-        searchCurrencies();
-    }
-
-    @Test
-    public void indexCurrency() throws Exception {
-
-        // Create a new non-existing currency
-        Currency currency = new Currency();
-        currency.setCurrencyName("kimamila-test-" + System.currentTimeMillis());
-        service.indexCurrency(currency);
-
-        // Update a existing currency, with peer
-        {
-            Peer peer = createTestPeer();
-            BlockchainRemoteService blockchainService = ServiceLocator.instance().getBlockchainRemoteService();
-
-            BlockchainParameters parameter = blockchainService.getParameters(peer);
-
-            currency = new Currency();
-            currency.setCurrencyName(parameter.getCurrency());
-            currency.setMembersCount(10);
-            currency.setPeers(new Peer[]{peer});
-
-            service.indexCurrency(currency);
-        }
-    }
-
-    @Test
-    public void getSuggestions() throws Exception {
-
-        // match multi words
-        String queryText = "kimamilat";
-        List<String> suggestions = service.getSuggestions(queryText);
-        assertSuggestions(queryText, suggestions);
-    }
-
-    @Test
-    public void searchCurrencies() throws Exception {
-
-        // match multi words
-        String queryText = "kimamila test";
-        List<Currency> currencies = service.searchCurrencies(queryText);
-        assertResults(queryText, currencies);
-
-        // match a partial word
-        queryText = "kim";
-        currencies = service.searchCurrencies(queryText);
-        assertResults(queryText, currencies);
-
-        // match with words (using underscore)
-        queryText = "meta brouzouf";
-        currencies = service.searchCurrencies(queryText);
-        // FIXME : the "underscore" should be used as word separator
-        //assertResults(queryText, currencies);
-    }
-
-
-    /* -- internal methods -- */
-
-    protected void initLocalNode() throws Exception {
-        service.deleteIndex();
-        service.createIndex();
-        indexCurrency();
-    }
-
-    protected Wallet createTestWallet() {
-        Wallet wallet = new Wallet(
-                resource.getFixtures().getCurrency(),
-                resource.getFixtures().getUid(),
-                CryptoUtils.decodeBase58(resource.getFixtures().getUserPublicKey()),
-                CryptoUtils.decodeBase58(resource.getFixtures().getUserSecretKey()));
-
-        return wallet;
-    }
-
-    protected void assertResults(String queryText, List<Currency> result) {
-        log.info(String.format("Results for a search on [%s]", queryText));
-        Assert.assertNotNull(result);
-        Assert.assertTrue(result.size() > 0);
-        for (Currency currency: result) {
-            log.info("  - " + currency.getCurrencyName());
-        }
-    }
-
-    protected void assertSuggestions(String queryText, List<String> result) {
-        log.info(String.format("Suggestions for [%s]", queryText));
-        Assert.assertNotNull(result);
-        Assert.assertTrue(result.size() > 0);
-        for (String suggestion: result) {
-            log.info("  - " + suggestion);
-        }
-    }
-
-    protected Peer createTestPeer() {
-        Configuration config = Configuration.instance();
-
-        Peer peer = new Peer(
-                config.getNodeBmaHost(),
-                config.getNodeBmaPort());
-
-        return peer;
-    }
-}
diff --git a/ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/service/BlockIndexerServiceTest.java b/ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/service/currency/BlockIndexerServiceTest.java
similarity index 97%
rename from ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/service/BlockIndexerServiceTest.java
rename to ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/service/currency/BlockIndexerServiceTest.java
index dcc7eb8f917f9cb84e4e5d3807878dfd04f96c5c..189deec3e3308b8d471e67352e7189989c52706d 100644
--- a/ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/service/BlockIndexerServiceTest.java
+++ b/ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/service/currency/BlockIndexerServiceTest.java
@@ -1,4 +1,4 @@
-package io.ucoin.ucoinj.elasticsearch.service;
+package io.ucoin.ucoinj.elasticsearch.service.currency;
 
 /*
  * #%L
@@ -28,6 +28,7 @@ import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock;
 import io.ucoin.ucoinj.core.client.model.local.Peer;
 import io.ucoin.ucoinj.core.client.service.bma.BlockchainRemoteService;
 import io.ucoin.ucoinj.elasticsearch.TestResource;
+import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator;
 import org.junit.*;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/ucoinj-elasticsearch/src/test/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean b/ucoinj-elasticsearch/src/test/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean
index fc3c26a12cdc0b222ddfcbdafb5e256a471f8a4c..19a694133250aaea47b9fc07fde9dc74557ebb97 100644
--- a/ucoinj-elasticsearch/src/test/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean
+++ b/ucoinj-elasticsearch/src/test/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean
@@ -10,4 +10,4 @@ io.ucoin.ucoinj.core.client.service.local.CurrencyServiceImpl
 io.ucoin.ucoinj.core.client.dao.mem.MemoryCurrencyDaoImpl
 io.ucoin.ucoinj.core.client.dao.mem.MemoryPeerDaoImpl
 io.ucoin.ucoinj.elasticsearch.service.ElasticSearchService
-io.ucoin.ucoinj.elasticsearch.service.CurrencyIndexerService
\ No newline at end of file
+io.ucoin.ucoinj.elasticsearch.service.registry.RegistryCurrencyIndexerService
\ No newline at end of file
diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/application/Application.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/application/Application.java
index 7008d3c13e3882b640aa3d10a5b087ae7c5557ef..5b02da5f04f7705c2ae932e532bb9c65e6985083 100644
--- a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/application/Application.java
+++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/application/Application.java
@@ -26,7 +26,7 @@ package io.ucoin.ucoinj.web.application;
 import io.ucoin.ucoinj.core.client.model.local.Peer;
 import io.ucoin.ucoinj.core.exception.TechnicalException;
 import io.ucoin.ucoinj.elasticsearch.config.ConfigurationOption;
-import io.ucoin.ucoinj.elasticsearch.service.CurrencyIndexerService;
+import io.ucoin.ucoinj.elasticsearch.service.registry.RegistryCurrencyIndexerService;
 import io.ucoin.ucoinj.web.config.WebConfiguration;
 import io.ucoin.ucoinj.web.pages.admin.JobManagerPage;
 import io.ucoin.ucoinj.web.pages.admin.ToolsPage;
@@ -42,11 +42,8 @@ import org.apache.wicket.markup.html.WebPage;
 import org.apache.wicket.util.time.Duration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.context.ApplicationContextAware;
 import org.springframework.stereotype.Component;
 
-import javax.servlet.ServletContext;
-
 @Component("wicketApplication")
 public class Application extends AuthenticatedWebApplication {
 
@@ -127,7 +124,7 @@ public class Application extends AuthenticatedWebApplication {
         if (localEsNode) {
 
             // Make sure main index exists
-            CurrencyIndexerService currencyIndexerService = ServiceLocator.instance().getCurrencyIndexerService();
+            RegistryCurrencyIndexerService currencyIndexerService = ServiceLocator.instance().getRegistryCurrencyIndexerService();
             currencyIndexerService.createIndexIfNotExists();
 
             // Make sure currency from default peer exists
diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/home/HomePage.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/home/HomePage.java
index e7b4f9e4a73991c9b7b5d0101a8b9577e3e6c962..2c7c96359b213452e6a35ef508baf19e1c450794 100644
--- a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/home/HomePage.java
+++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/home/HomePage.java
@@ -26,9 +26,8 @@ package io.ucoin.ucoinj.web.pages.home;
 //import com.googlecode.wicket.jquery.ui.form.autocomplete.AutoCompleteTextField;
 
 import com.googlecode.wicket.jquery.ui.panel.JQueryFeedbackPanel;
-import io.ucoin.ucoinj.elasticsearch.model.Currency;
 import io.ucoin.ucoinj.elasticsearch.model.SearchResult;
-import io.ucoin.ucoinj.elasticsearch.service.CurrencyIndexerService;
+import io.ucoin.ucoinj.elasticsearch.service.registry.RegistryCurrencyIndexerService;
 import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator;
 import io.ucoin.ucoinj.web.pages.BasePage;
 import io.ucoin.ucoinj.web.pages.registry.CurrencyPage;
@@ -47,12 +46,10 @@ import org.apache.wicket.markup.html.link.BookmarkablePageLink;
 import org.apache.wicket.markup.html.list.ListItem;
 import org.apache.wicket.markup.html.list.ListView;
 import org.apache.wicket.markup.html.panel.FeedbackPanel;
-import org.apache.wicket.model.Model;
 import org.apache.wicket.model.PropertyModel;
 import org.apache.wicket.model.util.ListModel;
 import org.apache.wicket.request.Response;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
-import org.apache.wicket.util.string.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -204,7 +201,7 @@ public class HomePage extends BasePage {
         }
         else {
 
-            CurrencyIndexerService service = ServiceLocator.instance().getCurrencyIndexerService();
+            RegistryCurrencyIndexerService service = ServiceLocator.instance().getRegistryCurrencyIndexerService();
             List<SearchResult> result = service.searchCurrenciesAsVO(searchQuery);
 
             if (CollectionUtils.isNotEmpty(result)) {
@@ -233,7 +230,7 @@ public class HomePage extends BasePage {
             suggestions = Collections.<String>emptyList();
         }
         else {
-            CurrencyIndexerService service = ServiceLocator.instance().getCurrencyIndexerService();
+            RegistryCurrencyIndexerService service = ServiceLocator.instance().getRegistryCurrencyIndexerService();
             suggestions = service.getSuggestions(input);
 
             if (CollectionUtils.isEmpty(suggestions)) {
diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/registry/CurrencyPage.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/registry/CurrencyPage.java
index 693ce2a057eb239af1c0aadef2a9379a435f0eae..ca86310737d7a2c2c1a695e8e5e06581c321c839 100644
--- a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/registry/CurrencyPage.java
+++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/registry/CurrencyPage.java
@@ -45,7 +45,7 @@ public class CurrencyPage extends BasePage {
         setDefaultModel(new CompoundPropertyModel<Currency>(new LoadableDetachableModel<Currency>() {
             @Override
             protected Currency load() {
-                return ServiceLocator.instance().getCurrencyIndexerService().getCurrencyById(currencyName);
+                return ServiceLocator.instance().getRegistryCurrencyIndexerService().getCurrencyById(currencyName);
             }
         }));
 
diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/rest/CurrencyRestController.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/rest/CurrencyRestController.java
index cf05b8401b527374e797c44430fb9d97f1d5646b..1150c9d2e66cad53f2e0d10e09c242dade52872f 100644
--- a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/rest/CurrencyRestController.java
+++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/rest/CurrencyRestController.java
@@ -24,7 +24,7 @@ package io.ucoin.ucoinj.web.rest;
 
 
 import io.ucoin.ucoinj.core.client.model.elasticsearch.Currency;
-import io.ucoin.ucoinj.elasticsearch.service.CurrencyIndexerService;
+import io.ucoin.ucoinj.elasticsearch.service.registry.RegistryCurrencyIndexerService;
 import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator;
 import io.ucoin.ucoinj.elasticsearch.service.exception.InvalidSignatureException;
 import io.ucoin.ucoinj.web.application.WebSession;
@@ -41,7 +41,7 @@ public class CurrencyRestController {
 
     @RequestMapping(value="/{currencyId}", method = RequestMethod.GET)
     public @ResponseBody Currency getCurrencyById(@PathVariable(value="currencyId") String currencyId) {
-        CurrencyIndexerService service = ServiceLocator.instance().getCurrencyIndexerService();
+        RegistryCurrencyIndexerService service = ServiceLocator.instance().getRegistryCurrencyIndexerService();
         return service.getCurrencyById(currencyId);
     }
 
@@ -52,7 +52,7 @@ public class CurrencyRestController {
             log.debug(String.format("Asking to add new currency:\n - pubkey: %s\n - currency: %s\n - signature: %s", pubkey, jsonCurrency, signature));
         }
 
-        CurrencyIndexerService service = ServiceLocator.instance().getCurrencyIndexerService();
+        RegistryCurrencyIndexerService service = ServiceLocator.instance().getRegistryCurrencyIndexerService();
         service.registerCurrency(pubkey, jsonCurrency, signature);
 
         /*CryptoService cryptoService = ServiceLocator.instance().getCryptoService();
diff --git a/ucoinj-ui-wicket/src/main/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean b/ucoinj-ui-wicket/src/main/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean
index ef8d07e32710007d2e38a0be666fc4b6fd838d27..ed53f7193606fedba58245b7c9ccd221e7b359fc 100644
--- a/ucoinj-ui-wicket/src/main/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean
+++ b/ucoinj-ui-wicket/src/main/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean
@@ -10,5 +10,5 @@ io.ucoin.ucoinj.core.client.service.local.CurrencyServiceImpl
 io.ucoin.ucoinj.core.client.dao.mem.MemoryCurrencyDaoImpl
 io.ucoin.ucoinj.core.client.dao.mem.MemoryPeerDaoImpl
 io.ucoin.ucoinj.elasticsearch.service.ElasticSearchService
-io.ucoin.ucoinj.elasticsearch.service.CurrencyIndexerService
-io.ucoin.ucoinj.elasticsearch.service.BlockIndexerService
+io.ucoin.ucoinj.elasticsearch.service.currency.CurrencyIndexerService
+io.ucoin.ucoinj.elasticsearch.service.currency.BlockIndexerService