Index: tmp/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/query/MatchUtils.java
===================================================================
--- tmp/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/query/MatchUtils.java	(revision 2406)
+++ tmp/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/query/MatchUtils.java	(revision 2407)
@@ -4,6 +4,7 @@
 import java.util.List;
 
 public class MatchUtils {
+	
 	/**
 	 * 
 	 * @param list the matches to cover
@@ -11,23 +12,50 @@
 	 * @return the indexes of 'b' matches that covers the 'a' matches
 	 */
 	public static ArrayList<Integer> matchesCoveredByB(List<Match> list, List<Match> b) {
-		int ai=0, bi=0;
-		ArrayList<Integer> result = new ArrayList<Integer>();
+		int ai = 0, bi = 0;
+		ArrayList<Integer> result = new ArrayList<>();
 		
-		while (ai < list.size() && bi < b.size() ) {
-			if (b.get(bi).contains(list.get(ai))) { 
+		while (ai < list.size() && bi < b.size()) {
+			if (b.get(bi).contains(list.get(ai))) {
 				result.add(bi);
-				bi++; 
-			} else { 
-				ai++; 
-			} 
+				bi++;
+			}
+			else {
+				ai++;
+			}
 		}
 		
 		return result;
 	}
 	
 	/**
+	 * Gets an array of all positions of the specified list of matches.
 	 * 
+	 * @param list the list of matches
+	 * @return an array of all positions of the specified list of matches
+	 */
+	public static int[] toPositions(List<Match> list) {
+		ArrayList<Integer> result = new ArrayList<>();
+		for (Match m : list) {
+			if (m.getStart() == m.getEnd()) {
+				result.add(m.getStart());
+			}
+			else {
+				for (int i = m.getStart(); i <= m.getEnd(); i++) {
+					result.add(i);
+				}
+			}
+		}
+		
+		int[] positions = new int[result.size()];
+		for (int i = 0; i < result.size(); i++) {
+			positions[i] = result.get(i);
+		}
+		return positions;
+	}
+	
+	/**
+	 * 
 	 * @param match
 	 * @return array of int position from a Match
 	 */
@@ -44,16 +72,19 @@
 	public static int[] toPositions(Match match1, Match match2) {
 		int len = match2.end - match1.start + 1;
 		
-		if (len <= 0 ) {
+		if (len <= 0) {
 			return new int[0];
-		} else if (len == 1) {
-			return new int[] {match1.start};
-		} else if (len == 2) {
-			return new int[] {match1.start, match2.end};
-		} else {
+		}
+		else if (len == 1) {
+			return new int[] { match1.start };
+		}
+		else if (len == 2) {
+			return new int[] { match1.start, match2.end };
+		}
+		else {
 			int[] positions = new int[len];
 			int n = 0;
-			for (int i = match1.start ; i <= match2.end ; i++) {
+			for (int i = match1.start; i <= match2.end; i++) {
 				positions[n++] = i;
 			}
 			return positions;
Index: tmp/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/CQPLexicon.java
===================================================================
--- tmp/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/CQPLexicon.java	(revision 2406)
+++ tmp/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/CQPLexicon.java	(revision 2407)
@@ -44,6 +44,7 @@
 import org.txm.searchengine.cqp.AbstractCqiClient;
 import org.txm.searchengine.cqp.ICqiClient;
 import org.txm.searchengine.cqp.clientExceptions.CqiClientException;
+import org.txm.searchengine.cqp.corpus.query.MatchUtils;
 import org.txm.searchengine.cqp.serverException.CqiServerError;
 //import org.txm.statsengine.core.StatException;
 //import org.txm.statsengine.core.data.Vector;
@@ -145,6 +146,57 @@
 		return true;
 	}
 	
+	// /**
+	// *
+	// * @param corpus
+	// * @param property
+	// * @param monitor
+	// * @return
+	// * @throws CqiClientException
+	// */
+	// // FIXME: why this method needs to create and delete some new subcorpus???? the computing can't be done directly on the corpus argument???
+	// // eg. dist = CorpusManager.getCorpusManager().getCqiClient().fdist1(corpus.getQualifiedCqpId(), 0, ICqiClient.CQI_CONST_FIELD_MATCH, property.getName());
+	// protected boolean computewithSubCorpus(Subcorpus corpus, Property property, IProgressMonitor monitor) throws CqiClientException {
+	//
+	// //System.out.println("not found");
+	//// Log.finest(NLS.bind(IndexCoreMessages.computingTheLexiconOfSubcorpusP0, corpus.getName()));
+	// //long start = System.currentTimeMillis();
+	// int[][] fdist = null;
+	// AbstractCqiClient cqi = CorpusManager.getCorpusManager().getCqiClient();
+	// String tmp = "TMP" + CQPCorpus.getNextSubcorpusCounter();
+	// String qtmp = corpus.getMainCorpus().getQualifiedCqpId()+":"+tmp;
+	// try {
+	//// System.out.println("subcorpus: "+corpus.getQualifiedCqpId());
+	//// System.out.println("query subcorpus: "+qtmp);
+	// cqi.cqpQuery(corpus.getQualifiedCqpId(), tmp, "[]"); //$NON-NLS-1$
+	// fdist = CorpusManager.getCorpusManager().getCqiClient().fdist1(qtmp, 0, ICqiClient.CQI_CONST_FIELD_MATCH, property.getName());
+	// //System.out.println("nb lines: "+fdist.length);
+	// } catch (Exception e) {
+	// throw new CqiClientException(e);
+	// } finally {
+	// try {
+	// cqi.dropSubCorpus(qtmp);
+	// } catch (IOException e) {
+	// // TODO Auto-generated catch block
+	// e.printStackTrace();
+	// } catch (CqiServerError e) {
+	// // TODO Auto-generated catch block
+	// e.printStackTrace();
+	// }
+	// }
+	// int lexiconSize = fdist.length;
+	//
+	// int[] freqs = new int[lexiconSize];
+	// int[] ids = new int[lexiconSize];
+	// for (int i = 0; i < fdist.length; i++) {
+	// ids[i] = fdist[i][0];
+	// freqs[i] = fdist[i][1];
+	// }
+	//
+	// init(corpus, property, freqs, ids);
+	// return true;
+	// }
+	
 	/**
 	 * 
 	 * @param corpus
@@ -153,7 +205,7 @@
 	 * @return
 	 * @throws CqiClientException
 	 */
-	// FIXME: why this method needs to create and delete some new subcorpus???? the computing can't be done directly on the corpus argument???
+	// FIXME: SJ: why this method needs to create and delete some new subcorpus? the computing can't be done directly on the corpus argument?
 	// eg. dist = CorpusManager.getCorpusManager().getCqiClient().fdist1(corpus.getQualifiedCqpId(), 0, ICqiClient.CQI_CONST_FIELD_MATCH, property.getName());
 	protected boolean computewithSubCorpus(Subcorpus corpus, Property property, IProgressMonitor monitor) throws CqiClientException {
 		
@@ -161,31 +213,65 @@
 		// Log.finest(NLS.bind(IndexCoreMessages.computingTheLexiconOfSubcorpusP0, corpus.getName()));
 		// long start = System.currentTimeMillis();
 		int[][] fdist = null;
-		AbstractCqiClient cqi = CorpusManager.getCorpusManager().getCqiClient();
-		String tmp = "TMP" + CQPCorpus.getNextSubcorpusCounter();
-		String qtmp = corpus.getMainCorpus().getQualifiedCqpId() + ":" + tmp;
-		try {
-			// System.out.println("subcorpus: "+corpus.getQualifiedCqpId());
-			// System.out.println("query subcorpus: "+qtmp);
-			cqi.cqpQuery(corpus.getQualifiedCqpId(), tmp, "[]"); //$NON-NLS-1$
-			fdist = CorpusManager.getCorpusManager().getCqiClient().fdist1(qtmp, 0, ICqiClient.CQI_CONST_FIELD_MATCH, property.getName());
-			// System.out.println("nb lines: "+fdist.length);
+		
+		boolean fast = false;
+		
+		// FIXME: SJ: old version
+		if (!fast) {
+			
+			AbstractCqiClient cqi = CorpusManager.getCorpusManager().getCqiClient();
+			String tmp = "TMP" + CQPCorpus.getNextSubcorpusCounter();
+			String qtmp = corpus.getMainCorpus().getQualifiedCqpId() + ":" + tmp;
+			
+			try {
+				// System.out.println("subcorpus: "+corpus.getQualifiedCqpId());
+				// System.out.println("query subcorpus: "+qtmp);
+				
+				cqi.cqpQuery(corpus.getQualifiedCqpId(), tmp, "[]"); //$NON-NLS-1$
+				fdist = CorpusManager.getCorpusManager().getCqiClient().fdist1(qtmp, 0, ICqiClient.CQI_CONST_FIELD_MATCH, property.getName());
+				// System.out.println("nb lines: "+fdist.length);
+			}
+			catch (Exception e) {
+				throw new CqiClientException(e);
+			}
+			finally {
+				try {
+					cqi.dropSubCorpus(qtmp);
+				}
+				catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+				catch (CqiServerError e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
 		}
-		catch (Exception e) {
-			throw new CqiClientException(e);
-		}
-		finally {
+		// FIXME: SJ: new version by MD that seems fastest, need to test on all types of lexicons corpora before replacing old version
+		else {
+			
 			try {
-				cqi.dropSubCorpus(qtmp);
+				int[] positions = MatchUtils.toPositions(corpus.getMatches());
+				int[] indexes = CorpusManager.getCorpusManager().getCqiClient().cpos2Id(property.getQualifiedName(), positions);
+				int n_indexes = CorpusManager.getCorpusManager().getCqiClient().attributeSize(property.getQualifiedName());
+				int[] counts = new int[n_indexes];
+				for (int i : indexes) {
+					counts[i]++;
+				}
+				fdist = new int[indexes.length][2];
+				
+				int n = 0;
+				for (int i : indexes) {
+					fdist[n][0] = i;
+					fdist[n][1] = counts[i];
+					n++;
+				}
 			}
-			catch (IOException e) {
+			catch (Exception e) {
 				// TODO Auto-generated catch block
 				e.printStackTrace();
 			}
-			catch (CqiServerError e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
 		}
 		int lexiconSize = fdist.length;
 		
@@ -200,6 +286,7 @@
 		return true;
 	}
 	
+	
 	/**
 	 * Compute number of tokens. / this.nbr
 	 */
