Index: tmp/org.txm.concordance.core/src/TestConcordance.java
===================================================================
--- tmp/org.txm.concordance.core/src/TestConcordance.java	(revision 0)
+++ tmp/org.txm.concordance.core/src/TestConcordance.java	(revision 367)
@@ -0,0 +1,126 @@
+
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.txm.concordance.core.functions.Concordance;
+import org.txm.concordance.core.functions.comparators.LexicographicKeywordComparator;
+import org.txm.concordance.core.functions.comparators.LexicographicLeftContextComparator;
+import org.txm.concordance.core.functions.comparators.LexicographicRightContextComparator;
+import org.txm.concordance.core.functions.comparators.LineComparator;
+import org.txm.concordance.core.functions.comparators.NullComparator;
+import org.txm.concordance.core.functions.comparators.PropertiesReferenceComparator;
+import org.txm.functions.ReferencePattern;
+import org.txm.searchengine.cqp.corpus.Corpus;
+import org.txm.searchengine.cqp.corpus.CorpusManager;
+import org.txm.searchengine.cqp.corpus.Property;
+import org.txm.searchengine.cqp.corpus.query.Query;
+
+/**
+ * Test class for the concordances
+ * 
+ * @author mdecorde
+ *
+ */
+public class TestConcordance {
+	/**
+	 * the corpus name to use
+	 */
+	static String CORPUS = "DISCOURS"; //$NON-NLS-1$
+	
+	public static boolean allTests(File outdir) {
+		TestConcordance tester = new TestConcordance();
+		return tester.test1(outdir);
+	}
+	
+	/**
+	 * First test
+	 * @param outdir : the out folder
+	 */
+	public boolean test1(File outdir) {
+		return test(new File(outdir, TestConcordance.class.getName()+"_test1.csv"), CORPUS, null, "je", //$NON-NLS-1$ //$NON-NLS-2$
+				Arrays.asList("word"), Arrays.asList("word"),Arrays.asList("word"),  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				Arrays.asList("word"), Arrays.asList("word"),Arrays.asList("word"),  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				Arrays.asList("text_id", "text_loc"), Arrays.asList("text_id"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				10, 40, null);
+	}
+	
+	private boolean test(File outfile, String corpusname, String subcorpusname, String queryString,
+			List<String> leftCSortPropertiesString, List<String> rightCSortPropertiesString, List<String> keywordSortPropertiesString,
+			List<String> leftCViewPropertiesString, List<String> rightCViewPropertiesString, List<String> keywordViewPropertiesString,
+			List<String> refPatternsString, List<String> refAnalysePatternString, int leftContextSize, int rightContextSize, String sortBy) {
+		try {
+			Corpus corpus = CorpusManager.getCorpusManager().getCorpus(corpusname);
+			if (subcorpusname != null) {
+				corpus = corpus.getSubcorpusByName(subcorpusname);
+			}
+			Query query = new Query(Query.fixQuery(queryString));
+			
+			List<Property> leftCSortProperties = new ArrayList<Property>();
+			for (String p : leftCSortPropertiesString) leftCSortProperties.add(corpus.getProperty(p));
+			
+			List<Property> rightCSortProperties =  new ArrayList<Property>();
+			for (String p : rightCSortPropertiesString) rightCSortProperties.add(corpus.getProperty(p));
+			
+			List<Property> keywordSortProperties =  new ArrayList<Property>();
+			for (String p : keywordSortPropertiesString) keywordSortProperties.add(corpus.getProperty(p));
+			
+			List<Property> leftCViewProperties = new ArrayList<Property>();
+			for (String p : leftCViewPropertiesString) leftCViewProperties.add(corpus.getProperty(p));
+			
+			List<Property> rightCViewProperties =  new ArrayList<Property>();
+			for (String p : rightCViewPropertiesString) rightCViewProperties.add(corpus.getProperty(p));
+			
+			List<Property> keywordViewProperties =  new ArrayList<Property>();
+			for (String p : keywordViewPropertiesString) keywordViewProperties.add(corpus.getProperty(p));
+
+			ArrayList<Property> refPatterns = new ArrayList<Property>();
+			for (String p : refPatternsString) {
+				String[] split = p.split("_",2); //$NON-NLS-1$
+				if (split != null && split[0].length() > 0 && split[1].length() > 0) {
+					refPatterns.add(corpus.getStructuralUnit(split[0]).getProperty(split[1]));
+				} else {
+					refPatterns.add(corpus.getProperty(p));
+				}
+			}
+			ReferencePattern referencePattern = new ReferencePattern(refPatterns);
+			
+			refPatterns = new ArrayList<Property>();
+			for (String p : refAnalysePatternString) {
+				String[] split = p.split("_",2); //$NON-NLS-1$
+				if (split != null && split[0].length() > 0 && split[1].length() > 0) {
+					refPatterns.add(corpus.getStructuralUnit(split[0]).getProperty(split[1]));
+				} else {
+					refPatterns.add(corpus.getProperty(p));
+				}
+			}
+			ReferencePattern refAnalysePattern = new ReferencePattern(refPatterns);
+
+
+			Concordance conc = new Concordance(corpus, query,
+					leftCSortProperties, rightCSortProperties, keywordSortProperties,
+					leftCViewProperties, rightCViewProperties, keywordViewProperties,
+					referencePattern, refAnalysePattern, 
+					leftContextSize, rightContextSize);
+			conc.getLines(0, conc.getNLines());
+			
+			if (sortBy != null) {
+				LineComparator comparator;
+				if ("null".equals(sortBy)) comparator = new NullComparator(); //$NON-NLS-1$
+				else if ("lexicographic".equals(sortBy)) comparator = new LexicographicKeywordComparator(); //$NON-NLS-1$
+				else if ("leftcontext".equals(sortBy)) comparator = new LexicographicLeftContextComparator(); //$NON-NLS-1$
+				else if ("rightcontext".equals(sortBy)) comparator = new LexicographicRightContextComparator(); //$NON-NLS-1$
+				else if ("reference".equals(sortBy)) comparator = new PropertiesReferenceComparator(); //$NON-NLS-1$
+				else comparator = new NullComparator();
+				conc.sort(comparator);
+			}
+			conc.toTxt(outfile, "UTF-8", "\t", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		} catch (Exception e) {
+			org.txm.utils.logger.Log.printStackTrace(e);
+			return false;
+		}
+		return true;
+	}
+}

Property changes on: tmp/org.txm.concordance.core/src/TestConcordance.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/src/org/txm/concordance/core/package.html
===================================================================
--- tmp/org.txm.concordance.core/src/org/txm/concordance/core/package.html	(revision 0)
+++ tmp/org.txm.concordance.core/src/org/txm/concordance/core/package.html	(revision 367)
@@ -0,0 +1,5 @@
+<html>
+<body>
+<p>Concordance.</p>
+</body>
+</html>
\ No newline at end of file

Property changes on: tmp/org.txm.concordance.core/src/org/txm/concordance/core/package.html
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/src/org/txm/concordance/core/preferences/ConcordancePreferences.java
===================================================================
--- tmp/org.txm.concordance.core/src/org/txm/concordance/core/preferences/ConcordancePreferences.java	(revision 0)
+++ tmp/org.txm.concordance.core/src/org/txm/concordance/core/preferences/ConcordancePreferences.java	(revision 367)
@@ -0,0 +1,45 @@
+package org.txm.concordance.core.preferences;
+
+
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.service.prefs.Preferences;
+import org.txm.core.preferences.TXMPreferences;
+
+/**
+ * Default preferences initializer.
+ * 
+ * @author mdecorde
+ * @author sjacquot
+ *
+ */
+public class ConcordancePreferences extends TXMPreferences {
+
+
+	// auto populate the preference node qualifier from the current bundle id
+	public static final String PREFERENCES_NODE = FrameworkUtil.getBundle(ConcordancePreferences.class).getSymbolicName();
+
+	
+	public static final String PREFERENCES_PREFIX = "concordance_"; //$NON-NLS-1$
+	public static final String N_LINE_PER_PAGE = PREFERENCES_PREFIX + "n_line_per_page"; //$NON-NLS-1$
+	public static final String LEFT_CONTEXT_SIZE = PREFERENCES_PREFIX + "left_context_size"; //$NON-NLS-1$
+	public static final String RIGHT_CONTEXT_SIZE = PREFERENCES_PREFIX + "right_context_size"; //$NON-NLS-1$
+
+	
+	/**
+	 * 
+	 */
+	public ConcordancePreferences() {
+		// TODO Auto-generated constructor stub
+	}
+
+	@Override
+	public void initializeDefaultPreferences() {
+		Preferences preferences = DefaultScope.INSTANCE.getNode(PREFERENCES_NODE);
+		
+		preferences.putInt(N_LINE_PER_PAGE, 100);
+		preferences.putInt(LEFT_CONTEXT_SIZE, 8);
+		preferences.putInt(RIGHT_CONTEXT_SIZE, 12);
+	}
+	
+}

Property changes on: tmp/org.txm.concordance.core/src/org/txm/concordance/core/preferences/ConcordancePreferences.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/src/org/txm/concordance/core/messages/messages_ru.properties
===================================================================
--- tmp/org.txm.concordance.core/src/org/txm/concordance/core/messages/messages_ru.properties	(revision 0)
+++ tmp/org.txm.concordance.core/src/org/txm/concordance/core/messages/messages_ru.properties	(revision 367)
@@ -0,0 +1,25 @@
+#created/updated with GetStringsFromPropertiesFile.groovy
+#Mon Jul 03 14:53:55 CEST 2017
+LexicographicLeftContextComparator_0=MISSING
+NullComparator_0=MISSING
+Concordance_8=MISSING
+Concordance_7=MISSING
+PropertiesReferenceComparator_0=MISSING
+Concordance_6=MISSING
+Concordance_5=MISSING
+Concordance_4=MISSING
+Concordance_3=MISSING
+Concordance_2=MISSING
+Concordance_1=MISSING
+Concordance_0=MISSING
+CompositeComparator_0=MISSING
+LexicographicRightContextComparator_0=MISSING
+LexicographicKeywordComparator_0=MISSING
+Concordance_19=MISSING
+Concordance_18=MISSING
+Concordance_17=MISSING
+Concordance_16=MISSING
+Concordance_15=MISSING
+Concordance_14=MISSING
+Concordance_13=MISSING
+Concordance_12=MISSING

Property changes on: tmp/org.txm.concordance.core/src/org/txm/concordance/core/messages/messages_ru.properties
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/src/org/txm/concordance/core/messages/messages_fr.properties
===================================================================
--- tmp/org.txm.concordance.core/src/org/txm/concordance/core/messages/messages_fr.properties	(revision 0)
+++ tmp/org.txm.concordance.core/src/org/txm/concordance/core/messages/messages_fr.properties	(revision 367)
@@ -0,0 +1,25 @@
+#created/updated with GetStringsFromPropertiesFile.groovy
+#Mon Jul 03 14:53:55 CEST 2017
+LexicographicLeftContextComparator_0=Contexte gauche
+NullComparator_0=Aucun
+Concordance_8=Echec de la récupération des limites de texte \: 
+Concordance_7=\ résultats
+PropertiesReferenceComparator_0=Références
+Concordance_6=Récupération 
+Concordance_5=MISSING
+Concordance_4=Echec de la suppression du QueryResult de CQP\: 
+Concordance_3=\ résultats obtenus en 
+Concordance_2=indéfini
+Concordance_1=** Echec de récupération de la propriété 'text_id' des lignes 
+Concordance_0=\ 
+CompositeComparator_0=Composé \: 
+LexicographicRightContextComparator_0=Contexte droit
+LexicographicKeywordComparator_0=Pivot
+Concordance_19=Contexte
+Concordance_18=MISSING
+Concordance_17=Référence
+Concordance_16=ContexteDroit
+Concordance_15=Pivot
+Concordance_14=ContexteGauche
+Concordance_13=Référence
+Concordance_12=** Echec de l'exportation de la concordance \: 

Property changes on: tmp/org.txm.concordance.core/src/org/txm/concordance/core/messages/messages_fr.properties
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/src/org/txm/concordance/core/messages/messages.properties
===================================================================
--- tmp/org.txm.concordance.core/src/org/txm/concordance/core/messages/messages.properties	(revision 0)
+++ tmp/org.txm.concordance.core/src/org/txm/concordance/core/messages/messages.properties	(revision 367)
@@ -0,0 +1,25 @@
+#created/updated with GetStringsFromPropertiesFile.groovy
+#Mon Jul 03 14:53:55 CEST 2017
+LexicographicLeftContextComparator_0=Left context
+NullComparator_0=None
+Concordance_8=Failed to get texts limits\: 
+Concordance_7=\ results
+PropertiesReferenceComparator_0=References
+Concordance_6=Retrieving 
+Concordance_5=
+Concordance_4=Failed to remove QueryResult from CQP\: 
+Concordance_3=\ results retrieved in 
+Concordance_2=undefined
+Concordance_1=** Failed to retrieve text_id property from lines
+Concordance_0=\ 
+CompositeComparator_0=Composite\: 
+LexicographicRightContextComparator_0=Right context
+LexicographicKeywordComparator_0=Keyword
+Concordance_19=Context
+Concordance_18=
+Concordance_17=Reference
+Concordance_16=RightContext
+Concordance_15=Keyword
+Concordance_14=LeftContext
+Concordance_13=Reference
+Concordance_12=** Failed to export Concordance\: 

Property changes on: tmp/org.txm.concordance.core/src/org/txm/concordance/core/messages/messages.properties
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/src/org/txm/concordance/core/messages/ConcordanceMessages.java
===================================================================
--- tmp/org.txm.concordance.core/src/org/txm/concordance/core/messages/ConcordanceMessages.java	(revision 0)
+++ tmp/org.txm.concordance.core/src/org/txm/concordance/core/messages/ConcordanceMessages.java	(revision 367)
@@ -0,0 +1,45 @@
+package org.txm.concordance.core.messages;
+
+import org.eclipse.osgi.util.NLS;
+import org.txm.utils.messages.Utf8NLS;
+
+/**
+ * Toolbox core messages.
+ * 
+ * @author mdecorde
+ * @author sjacquot
+ *
+ */
+public class ConcordanceMessages extends NLS {
+
+	private static final String BUNDLE_NAME = "org.txm.concordance.core.messages.messages"; //$NON-NLS-1$
+
+	public static String Concordance_0;
+	public static String Concordance_1;
+	public static String Concordance_12;
+	public static String Concordance_13;
+	public static String Concordance_14;
+	public static String Concordance_15;
+	public static String Concordance_16;
+	public static String Concordance_17;
+	public static String Concordance_18;
+	public static String Concordance_19;
+	public static String Concordance_2;
+	public static String Concordance_3;
+	public static String Concordance_4;
+	public static String Concordance_5;
+	public static String Concordance_6;
+	public static String Concordance_7;
+	public static String Concordance_8;
+	public static String CompositeComparator_0;
+	public static String PropertiesReferenceComparator_0;
+	public static String LexicographicLeftContextComparator_0;
+	public static String LexicographicKeywordComparator_0;
+	public static String LexicographicRightContextComparator_0;
+	public static String NullComparator_0;
+	
+	static {
+		// initialize resource bundle
+		Utf8NLS.initializeMessages(BUNDLE_NAME, ConcordanceMessages.class);
+	}
+}

Property changes on: tmp/org.txm.concordance.core/src/org/txm/concordance/core/messages/ConcordanceMessages.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/Line.java
===================================================================
--- tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/Line.java	(revision 0)
+++ tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/Line.java	(revision 367)
@@ -0,0 +1,698 @@
+// Copyright © 2010-2013 ENS de Lyon.
+// Copyright © 2007-2010 ENS de Lyon, CNRS, INRP, University of
+// Lyon 2, University of Franche-Comté, University of Nice
+// Sophia Antipolis, University of Paris 3.
+// 
+// The TXM platform 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 2 of the License, or (at your option) any
+// later version.
+// 
+// The TXM platform 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 the TXM platform. If not, see
+// http://www.gnu.org/licenses.
+// 
+// 
+// 
+// $LastChangedDate: 2016-02-01 09:53:38 +0100 (Mon, 01 Feb 2016) $
+// $LastChangedRevision: 3101 $
+// $LastChangedBy: mdecorde $ 
+//
+package org.txm.concordance.core.functions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.txm.annotation.Annotation;
+import org.txm.annotation.repository.TypedValue;
+import org.txm.functions.Reference;
+import org.txm.searchengine.cqp.clientExceptions.CqiClientException;
+import org.txm.searchengine.cqp.corpus.Corpus;
+import org.txm.searchengine.cqp.corpus.Property;
+import org.txm.searchengine.cqp.corpus.query.Match;
+import org.txm.utils.i18n.LangFormater;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class Line represents concordance line.
+ *
+ * @author jmague
+ */
+public class Line {
+
+	/** The concordance. */
+	private Concordance concordance;
+
+	/** The left ctx view properties. */
+	private Map<Property, List<String>> leftCtxViewProperties;
+	
+	/** The keywords view properties. */
+	private Map<Property, List<String>> keywordsViewProperties;
+	
+	/** The right ctx view properties. */
+	private Map<Property, List<String>> rightCtxViewProperties;
+
+	/** The left ctx analysis property. */
+	private HashMap<Property, List<String>> leftCtxAnalysisProperty;
+	
+	/** The keywords analysis property. */
+	private HashMap<Property, List<String>> keywordsAnalysisProperty;
+	
+	/** The right ctx analysis property. */
+	private HashMap<Property, List<String>> rightCtxAnalysisProperty;
+	
+	/** The PRO p_ separtor. */
+	public static String PROP_SEPARTOR ="_"; //$NON-NLS-1$
+
+	/** The references : view and sort */
+	private Reference refView;
+	private Reference refAna;
+	
+	/** The match. */
+	private Match match;
+
+	/** the line's text. */
+	private String textId;
+
+	/** the ids of the keywords. */
+	private List<String> keywordsIdValues;
+
+	/** The keywordpos. */
+	private int keywordpos;
+	
+	/**
+	 * the @target corpus position of the query
+	 */
+	private int targetpos;
+
+	private TypedValue annotationValue;
+
+	private Annotation annotation;
+
+	/**
+	 * Instantiates a new line.
+	 *
+	 * @param concordance the concordance
+	 * @param keywordsIdValues the keywords id values
+	 * @param textId the text id
+	 * @param leftCtxViewProperty the left context view property values
+	 * @param keywordsViewProperty the keywords view property values
+	 * @param rightCtxViewProperty the right context view property values
+	 * @param lineLeftCtxAnaPropValue the left context analysis property values
+	 * @param lineKeywordsAnaPropValue the keywords analysis property values
+	 * @param lineRightCtxAnaPropValue the right context analysis property values
+	 * @param refView the view references
+	 * @param reference2 the sort references
+	 * @param matchs the matchs
+	 * @param annotation 
+	 * @param annotationValue 
+	 */
+	public Line(Concordance concordance, List<String> keywordsIdValues,
+			String textId, Map<Property, List<String>> leftCtxViewProperty,
+			Map<Property, List<String>> keywordsViewProperty,
+			Map<Property, List<String>> rightCtxViewProperty,
+			HashMap<Property, List<String>> lineLeftCtxAnaPropValue,
+			HashMap<Property, List<String>> lineKeywordsAnaPropValue,
+			HashMap<Property, List<String>> lineRightCtxAnaPropValue, Reference refView,
+			Reference refAna, Match matchs, Annotation annotation, TypedValue annotationValue, int targetpos) {
+		this.textId = textId;
+		this.targetpos = targetpos;
+		this.keywordsIdValues = keywordsIdValues;
+		this.concordance = concordance;
+		this.leftCtxViewProperties = leftCtxViewProperty;
+		this.keywordsViewProperties = keywordsViewProperty;
+		this.rightCtxViewProperties = rightCtxViewProperty;
+		this.leftCtxAnalysisProperty = lineLeftCtxAnaPropValue;
+		this.keywordsAnalysisProperty = lineKeywordsAnaPropValue;
+		this.rightCtxAnalysisProperty = lineRightCtxAnaPropValue;
+		this.refView = refView;
+		this.refAna = refAna;
+		this.match = matchs;
+		this.keywordpos = matchs.getStart();
+		this.annotationValue = annotationValue;
+		this.annotation = annotation;
+	}
+
+	/**
+	 * Gets the keywords analysis property.
+	 * 
+	 * @return the keywords analysis property
+	 */
+	public HashMap<Property, List<String>> getKeywordsAnalysisProperty() {
+		return keywordsAnalysisProperty;
+	}
+
+	public TypedValue getAnnotationValue() {
+		return annotationValue;
+	}
+	
+	/**
+	 * Gets the left context analysis property.
+	 * 
+	 * @return the left context analysis property
+	 */
+	public HashMap<Property, List<String>> getLeftAnalysisProperty() {
+		return leftCtxAnalysisProperty;
+	}
+
+	/**
+	 * Gets the right ctx analysis property.
+	 * 
+	 * @return the right ctx analysis property
+	 */
+	public HashMap<Property, List<String>> getRightAnalysisProperty() {
+		return rightCtxAnalysisProperty;
+	}
+
+	/**
+	 * Gets the keywords view properties.
+	 * 
+	 * @return the keywords view properties
+	 */
+	public Map<Property, List<String>> getKeywordsViewProperties() {
+		return keywordsViewProperties;
+	}
+
+	/**
+	 * Gets the left context view properties.
+	 * 
+	 * @return the left context view properties
+	 */
+	public Map<Property, List<String>> getLeftCtxViewProperties() {
+		return leftCtxViewProperties;
+	}
+
+	/**
+	 * Gets the right context view properties.
+	 * 
+	 * @return the right context view properties
+	 */
+	public Map<Property, List<String>> getRightCtxViewProperties() {
+		return rightCtxViewProperties;
+	}
+
+	/**
+	 * Gets the reference.
+	 * 
+	 * @return the reference
+	 */
+	public Reference getViewRef() {
+		return refView;
+	}
+	
+	/**
+	 * Gets the reference.
+	 * 
+	 * @return the reference
+	 */
+	public Reference getAnaRef() {
+		return refAna;
+	}
+	
+
+	/**
+	 * Gets the left context size.
+	 * 
+	 * @return the left context size
+	 */
+	public int getLeftContextSize() {
+		return leftCtxViewProperties.values().iterator().next().size();
+	}
+
+	/**
+	 * Gets the keywords size.
+	 * 
+	 * @return the keywords size
+	 */
+	public int getKeywordsSize() {
+		return keywordsViewProperties.values().iterator().next().size();
+	}
+
+	/**
+	 * Gets the right context size.
+	 * 
+	 * @return the right context size
+	 */
+	public int getRightContextSize() {
+		return rightCtxViewProperties.values().iterator().next().size();
+	}
+
+	/**
+	 * Gets the match.
+	 * 
+	 * @return the match
+	 */
+	public Match getMatch() {
+		return match;
+	}
+
+	/**
+	 * Used by leftContextToString, keywordsToString and rightContextToString to
+	 * build te string they return.
+	 *
+	 * @param values A map returned by getLeftCtxViewProperties,
+	 * getKeywordsViewProperties or getRightCtxViewProperties
+	 * @param propertySeparator The string used to separate the dif ferent view properties for
+	 * each word
+	 * @param wordSeparator The string used to separate the dif ferent words
+	 * @return The string representation
+	 */
+	private String fieldToString(Map<Property, List<String>> values,
+			String propertySeparator, String wordSeparator) {
+		List<String> words = new ArrayList<String>();
+		for (int i = 0; i < values.get(concordance.getViewProperties().get(0))
+				.size(); i++) {
+			List<String> word = new ArrayList<String>();
+			for (Property property : concordance.getViewProperties())
+				word.add(values.get(property).get(i));
+			words.add(StringUtils.join(word, propertySeparator));
+		}
+		return LangFormater.format(StringUtils.join(words, wordSeparator),
+				concordance.getCorpus().getAttribute("lang")); //$NON-NLS-1$
+	}
+
+	/**
+	 * Fix spaces.
+	 *
+	 * @param str the str
+	 * @return the string
+	 */
+	private String fixSpaces(String str) {
+		str = str.replace(" ' ", " '"); //$NON-NLS-1$ //$NON-NLS-2$
+		str = str.replace("' ", "'"); //$NON-NLS-1$ //$NON-NLS-2$
+		str = str.replace(" , ", ", "); //$NON-NLS-1$ //$NON-NLS-2$
+		str = str.replace(" \" ", " \""); //$NON-NLS-1$ //$NON-NLS-2$
+		str = str.replace(" . ", ". "); //$NON-NLS-1$ //$NON-NLS-2$
+		str = str.replace("( ", "("); //$NON-NLS-1$ //$NON-NLS-2$
+		str = str.replace(" )", ")"); //$NON-NLS-1$ //$NON-NLS-2$
+		str = str.replace("[ ", "["); //$NON-NLS-1$ //$NON-NLS-2$
+		str = str.replace(" ]", "]"); //$NON-NLS-1$ //$NON-NLS-2$
+		str = str.replace("{ ", "{"); //$NON-NLS-1$ //$NON-NLS-2$
+		str = str.replace(" }", "}"); //$NON-NLS-1$ //$NON-NLS-2$
+		return str;
+	}
+
+	/**
+	 * Returns a string representing the left context.
+	 *
+	 * @param propertySeparator The string used to separate the dif ferent view properties for
+	 * each word
+	 * @param wordSeparator The string used to separate the dif ferent words
+	 * @param limit the limit
+	 * @return The string representation
+	 */
+	public String leftContextToString(String propertySeparator,
+			String wordSeparator, int limit) {
+		int currentPos = keywordpos - getLeftContextSize();
+		
+		List<String> words = new ArrayList<String>();
+		Map<Property, List<String>> values = getLeftCtxViewProperties();
+		int max = (limit == -1) ? (values.get(concordance
+				.getLeftViewProperties().get(0)).size()) : (limit);
+		int start = this.getLeftContextSize() - max;
+		for (int i = start; i < this.getLeftContextSize(); i++) {
+			List<String> word = new ArrayList<String>();
+			for (Property property : concordance.getLeftViewProperties())
+				word.add(values.get(property).get(i));
+			
+			words.add(StringUtils.join(word, propertySeparator));
+			
+			if (annotation != null) {
+				if (currentPos == annotation.getStart()) {
+					words.set(i, "< "+words.get(i));
+				} else if (currentPos == annotation.getEnd()) {
+					words.set(i, words.get(i)+" >");
+				}
+			}
+			
+			currentPos++; // next position
+		}
+
+		return LangFormater.format(StringUtils.join(words, wordSeparator),
+				concordance.getCorpus().getAttribute("lang")); //$NON-NLS-1$
+		// return fieldToString(getLeftCtxViewProperties(), propertySeparator,
+		// wordSeparator);
+	}
+
+	/**
+	 * Returns a string representing the keywords.
+	 *
+	 * @param propertySeparator The string used to separate the dif ferent view properties for
+	 * each word
+	 * @param wordSeparator The string used to separate the dif ferent words
+	 * @return The string representation
+	 */
+	public String keywordToString(String propertySeparator, String wordSeparator) {
+		
+		int currentPos = keywordpos;
+		
+		List<String> words = new ArrayList<String>();
+		Map<Property, List<String>> values = getKeywordsViewProperties();
+		int s = values.get(concordance.getKeywordViewProperties().get(0)).size();
+		int keywordEndPos = keywordpos + s - 1;
+		//System.out.println("Build STR of currentpos="+currentPos+" length="+s);
+		for (int i = 0; i < s; i++) {
+			List<String> word = new ArrayList<String>();
+			for (Property property : concordance.getKeywordViewProperties())
+				word.add(values.get(property).get(i));
+			
+			if (currentPos == targetpos) { // highlight the @ target 
+				words.add("["+StringUtils.join(word, propertySeparator)+"]");
+			} else {
+				words.add(StringUtils.join(word, propertySeparator));
+			}
+			if (annotation != null && (annotation.getStart() != keywordpos || annotation.getEnd() != keywordEndPos)) {
+				if (currentPos == annotation.getStart()) {
+					words.set(i, "< "+words.get(i));
+				}
+				if (currentPos == annotation.getEnd()) {
+					words.set(i, words.get(i)+" >");
+				}
+			}
+			
+			currentPos++; // next position
+		}
+		return LangFormater.format(StringUtils.join(words, wordSeparator),
+				concordance.getCorpus().getAttribute("lang")); //$NON-NLS-1$
+		// return fieldToString(getKeywordsViewProperties(), propertySeparator,
+		// wordSeparator);
+	}
+
+	/**
+	 * Returns a string representing the right context.
+	 *
+	 * @param propertySeparator The string used to separate the dif ferent view properties for
+	 * each word
+	 * @param wordSeparator The string used to separate the dif ferent words
+	 * @param limit the limit
+	 * @return The string representation
+	 */
+	public String rightContextToString(String propertySeparator,
+			String wordSeparator, int limit) {
+		List<String> words = new ArrayList<String>();
+		Map<Property, List<String>> values = getRightCtxViewProperties();
+		int max = (limit == -1) ? (values.get(concordance.getRightViewProperties().get(0)).size()) : (limit);
+		
+		int s = getKeywordsSize();
+		int currentPos = keywordpos + s;
+		//System.out.println("Line "+keywordToString()+" right context, currentpos="+currentPos+" keywordpos="+keywordpos+" keywordlength="+s);
+		for (int i = 0; i < max; i++) {
+			List<String> word = new ArrayList<String>();
+			for (Property property : concordance.getRightViewProperties())
+				word.add(values.get(property).get(i));
+			words.add(StringUtils.join(word, propertySeparator));
+			
+			if (annotation != null) {
+				if (currentPos == annotation.getStart()) {
+					words.set(i, "< "+words.get(i));
+				} else if (currentPos == annotation.getEnd()) {
+					words.set(i, words.get(i)+" >");
+				}
+			}
+			currentPos++;
+		}
+		return LangFormater.format(StringUtils.join(words, wordSeparator),
+				concordance.getCorpus().getLang()); 
+		// return fieldToString(getRightCtxViewProperties(), propertySeparator,
+		// wordSeparator);
+	}
+	
+	/** The properties to process. */
+	protected static HashSet<String> propertiesToProcess;
+	
+	/**
+	 * Right context render.
+	 *
+	 * @param limit the limit
+	 * @return the string
+	 */
+	public String rightContextRender(int limit)
+	{
+//		if(propertiesToProcess == null)
+//			propertiesToProcess = TxmRenderer.getPropertyToRender(concordance, "jsesh"); //$NON-NLS-1$
+		
+		List<String> words = new ArrayList<String>();
+		Map<Property, List<String>> values = getRightCtxViewProperties();
+		int max = (limit == -1) ? (values.get(concordance.getRightViewProperties().get(0)).size()) : (limit);
+		
+		for (int i = 0; i < max; i++) 
+		{
+			List<String> word = new ArrayList<String>();
+			for (Property property : concordance.getRightViewProperties())
+			{
+//				if(propertiesToProcess.contains(property.getName()))
+//					word.add(TxmRenderer.jseshrenderer.render(values.get(property).get(i)));
+//				else
+					word.add(values.get(property).get(i));
+			}
+			words.add(StringUtils.join(word, "_")); //$NON-NLS-1$
+		}
+		return LangFormater.format(StringUtils.join(words, " "), //$NON-NLS-1$
+				concordance.getCorpus().getAttribute("lang")); //$NON-NLS-1$
+	}
+	
+	/**
+	 * Keyword render.
+	 *
+	 * @param wordSeparator the word separator
+	 * @return the string
+	 */
+	public String keywordRender(String wordSeparator) {
+//		if(propertiesToProcess == null)
+//			propertiesToProcess = TxmRenderer.getPropertyToRender(concordance, "jsesh"); //$NON-NLS-1$
+		
+		List<String> words = new ArrayList<String>();
+		Map<Property, List<String>> values = getKeywordsViewProperties();
+		for (int i = 0; i < values.get(
+				concordance.getKeywordViewProperties().get(0)).size(); i++) {
+			List<String> word = new ArrayList<String>();
+			for (Property property : concordance.getKeywordViewProperties())
+			{
+//				if(propertiesToProcess.contains(property.getName()))
+//					word.add(TxmRenderer.jseshrenderer.render(values.get(property).get(i)));
+//				else
+					word.add(values.get(property).get(i));
+			}
+			words.add(StringUtils.join(word, wordSeparator));
+		}
+		return LangFormater.format(StringUtils.join(words, wordSeparator),
+				concordance.getCorpus().getAttribute("lang")); //$NON-NLS-1$
+	}
+	
+	/**
+	 * Left context render.
+	 *
+	 * @param limit the limit
+	 * @return the string
+	 */
+	public String leftContextRender(int limit) {
+		List<String> words = new ArrayList<String>();
+		Map<Property, List<String>> values = getLeftCtxViewProperties();
+		int max = (limit == -1) ? (values.get(concordance
+				.getLeftViewProperties().get(0)).size()) : (limit);
+		int start = this.getLeftContextSize() - max;
+		for (int i = start; i < this.getLeftContextSize(); i++) {
+			List<String> word = new ArrayList<String>();
+			for (Property property : concordance.getLeftViewProperties())
+			{
+//				if(propertiesToProcess.contains(property.getName()))
+//					word.add(TxmRenderer.jseshrenderer.render(values.get(property).get(i)));
+//				else
+					word.add(values.get(property).get(i));
+			}
+			words.add(StringUtils.join(word, "_")); //$NON-NLS-1$
+		}
+
+		return LangFormater.format(StringUtils.join(words, " "), //$NON-NLS-1$
+				concordance.getCorpus().getAttribute("lang")); //$NON-NLS-1$
+		// return fieldToString(getLeftCtxViewProperties(), propertySeparator,
+		// wordSeparator);
+	}
+
+	/**
+	 * Returns a string representing the left context. Equivalent to
+	 * leftContextToString("/"," ")
+	 * 
+	 * @return The string representation
+	 */
+	public String leftContextToString() {
+		return leftContextToString(PROP_SEPARTOR, " ", -1); //$NON-NLS-1$ 
+	}
+
+	/**
+	 * Left context to string.
+	 *
+	 * @param limit the limit
+	 * @return the string
+	 */
+	public String leftContextToString(int limit) {
+		return leftContextToString(PROP_SEPARTOR, " ", limit); //$NON-NLS-1$ 
+	}
+
+	/**
+	 * Returns a string representing the keywords. Equivalent to
+	 * keywordToString("/"," ")
+	 * 
+	 * @return The string representation
+	 */
+	public String keywordToString() {
+		return keywordToString(PROP_SEPARTOR, " "); //$NON-NLS-1$ 
+	}
+
+	/**
+	 * Returns a string representing the right context. Equivalent to
+	 * rightContextToString("/"," ")
+	 * 
+	 * @return The string representation
+	 */
+	public String rightContextToString() {
+		return rightContextToString(PROP_SEPARTOR, " ", -1); //$NON-NLS-1$ 
+	}
+
+	/**
+	 * Right context to string.
+	 *
+	 * @param limit the limit
+	 * @return the string
+	 */
+	public String rightContextToString(int limit) {
+		return rightContextToString(PROP_SEPARTOR, " ", limit); //$NON-NLS-1$ 
+	}
+
+	/**
+	 * Match get start.
+	 *
+	 * @return the integer
+	 */
+	public Integer matchGetStart() {
+		return match.getStart();
+	}
+
+	/**
+	 * Match get end.
+	 *
+	 * @return the integer
+	 */
+	public Integer matchGetEnd() {
+		return match.getEnd();
+	}
+
+	/**
+	 * Match get col.
+	 *
+	 * @param corpus the corpus
+	 * @return the string
+	 * @throws CqiClientException the cqi client exception
+	 */
+	public String matchGetCol(Corpus corpus) throws CqiClientException {
+		return match.getValueForProperty(corpus.getProperty("col")); //$NON-NLS-1$
+	}
+
+	/**
+	 * Match get id.
+	 *
+	 * @param corpus the corpus
+	 * @return the list
+	 * @throws CqiClientException the cqi client exception
+	 */
+	public List<String> matchGetId(Corpus corpus) throws CqiClientException {
+		return match.getValuesForProperty(corpus.getProperty("id")); //$NON-NLS-1$
+	}
+
+	/**
+	 * Match get id.
+	 *
+	 * @param corpus the corpus
+	 * @param positions the positions
+	 * @return the list
+	 * @throws CqiClientException the cqi client exception
+	 */
+	@SuppressWarnings("static-access") //$NON-NLS-1$
+	public List<String> matchGetId(Corpus corpus, int[] positions)
+			throws CqiClientException {
+		return match.getValuesForProperty(corpus.getProperty("id"), positions); //$NON-NLS-1$
+	}
+
+	/**
+	 * Match get propertie.
+	 *
+	 * @param corpus the corpus
+	 * @param propertie the propertie
+	 * @param positions the positions
+	 * @return the list
+	 * @throws CqiClientException the cqi client exception
+	 */
+	@SuppressWarnings("static-access") //$NON-NLS-1$
+	public List<String> matchGetPropertie(Corpus corpus, String propertie,
+			int[] positions) throws CqiClientException {
+		return match.getValuesForProperty(corpus.getProperty(propertie),
+				positions);
+	}
+
+	/**
+	 * Match get properties.
+	 *
+	 * @param corpus the corpus
+	 * @param propertie the propertie
+	 * @param positions the positions
+	 * @return the list
+	 * @throws CqiClientException the cqi client exception
+	 */
+	@SuppressWarnings("static-access") //$NON-NLS-1$
+	public List<String> matchGetProperties(Corpus corpus, Property propertie,
+			int[] positions) throws CqiClientException {
+		return match.getValuesForProperty(propertie, positions);
+	}
+
+	/**
+	 * Gets the text id.
+	 *
+	 * @return the text id
+	 */
+	public Object getTextId() {
+		return this.textId;
+	}
+
+	/**
+	 * Gets the concordance.
+	 *
+	 * @return the concordance
+	 */
+	public Concordance getConcordance() {
+		return concordance;
+	}
+
+	/**
+	 * Gets the keyword ids.
+	 *
+	 * @return the keyword ids
+	 */
+	public Collection<? extends String> getKeywordIds() {
+		return this.keywordsIdValues;
+	}
+
+	/**
+	 * Gets the keyword position.
+	 *
+	 * @return the keyword position
+	 */
+	public int getKeywordPosition() {
+		return keywordpos;
+	}
+
+	public Annotation getAnnotation() {
+		return annotation;
+	}
+}

Property changes on: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/Line.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/LexicographicLeftContextComparator.java
===================================================================
--- tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/LexicographicLeftContextComparator.java	(revision 0)
+++ tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/LexicographicLeftContextComparator.java	(revision 367)
@@ -0,0 +1,101 @@
+// Copyright © 2010-2013 ENS de Lyon.
+// Copyright © 2007-2010 ENS de Lyon, CNRS, INRP, University of
+// Lyon 2, University of Franche-Comté, University of Nice
+// Sophia Antipolis, University of Paris 3.
+// 
+// The TXM platform 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 2 of the License, or (at your option) any
+// later version.
+// 
+// The TXM platform 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 the TXM platform. If not, see
+// http://www.gnu.org/licenses.
+// 
+// 
+// 
+// $LastChangedDate: 2014-07-15 09:42:00 +0200 (mar., 15 juil. 2014) $
+// $LastChangedRevision: 2820 $
+// $LastChangedBy: mdecorde $ 
+//
+package org.txm.concordance.core.functions.comparators;
+
+import java.util.HashMap;
+import java.util.List;
+
+import org.txm.concordance.core.functions.Concordance;
+import org.txm.concordance.core.functions.Line;
+import org.txm.concordance.core.messages.ConcordanceMessages;
+import org.txm.searchengine.cqp.corpus.Property;
+
+// TODO: Auto-generated Javadoc
+/**
+ * Compare two values of left context of a concordance line @ author mdecorde.
+ */
+public class LexicographicLeftContextComparator extends
+		StringListBasedComparator {
+
+	/** The Constant NAME. */
+	private static final String NAME = ConcordanceMessages.LexicographicLeftContextComparator_0;
+	private Concordance conc;
+	private List<Property> props;
+
+	/**
+	 * Instantiates a new lexicographic left context comparator.
+	 */
+	public LexicographicLeftContextComparator() {
+		super(NAME);
+	}
+
+	/* (non-Javadoc)
+	 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+	 */
+	@Override
+	public int compare(Line l1, Line l2) {
+		
+		this.conc = l1.getConcordance();
+		this.props = conc.getLeftAnalysisProperties();
+		if (props.size() == 0)
+			return 0;
+		int rez = 0;
+		int i = 0;
+
+		HashMap<Property, List<String>> values1 = l1.getLeftAnalysisProperty();
+		HashMap<Property, List<String>> values2 = l2.getLeftAnalysisProperty();
+		int j1 = l1.getLeftAnalysisProperty().get(props.get(0)).size() -1;
+		int j2 = l2.getLeftAnalysisProperty().get(props.get(0)).size() -1;
+		
+		String v1, v2;
+		
+		while (rez == 0) {
+			
+			if ((j1 < 0) && (j2 < 0))
+				return 0;
+			if (j1 < 0)
+				return -1; // end of line 1
+			if (j2 < 0)
+				return 1; // end of line 2
+			
+			v1 = values1.get(props.get(i)).get(j1);
+			v2 = values2.get(props.get(i)).get(j2);
+			
+			if (v1 == null) return -1;
+			if (v2 == null) return 1;
+			
+			rez = collator.compare(v1, v2);
+			if (++i >= props.size()) { // iterates over properties before tokens
+				i = 0;
+				j1--;
+				j2--;
+			}
+		}
+		return rez;
+	}
+}

Property changes on: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/LexicographicLeftContextComparator.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/StringListBasedComparator.java
===================================================================
--- tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/StringListBasedComparator.java	(revision 0)
+++ tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/StringListBasedComparator.java	(revision 367)
@@ -0,0 +1,70 @@
+// Copyright © 2010-2013 ENS de Lyon.
+// Copyright © 2007-2010 ENS de Lyon, CNRS, INRP, University of
+// Lyon 2, University of Franche-Comté, University of Nice
+// Sophia Antipolis, University of Paris 3.
+// 
+// The TXM platform 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 2 of the License, or (at your option) any
+// later version.
+// 
+// The TXM platform 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 the TXM platform. If not, see
+// http://www.gnu.org/licenses.
+// 
+// 
+// 
+// $LastChangedDate: 2013-05-06 17:38:43 +0200 (lun., 06 mai 2013) $
+// $LastChangedRevision: 2386 $
+// $LastChangedBy: mdecorde $ 
+//
+package org.txm.concordance.core.functions.comparators;
+
+import java.util.Iterator;
+import java.util.List;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class StringListBasedComparator.
+ */
+public abstract class StringListBasedComparator extends LocalizedLineComparator {
+
+	/**
+	 * Instantiates a new string list based comparator.
+	 *
+	 * @param name the name
+	 */
+	StringListBasedComparator(String name) {
+		super(name);
+	}
+
+	/**
+	 * Compare list.
+	 *
+	 * @param l1 the l1
+	 * @param l2 the l2
+	 * @return the int
+	 */
+	protected int compareList(List<String> l1, List<String> l2) {
+		Iterator<String> it1 = l1.iterator();
+		Iterator<String> it2 = l2.iterator();
+
+		while (it1.hasNext() && it2.hasNext()) {
+			int c = collator.compare(it1.next(), it2.next());
+			if (c != 0)
+				return c;
+		}
+		if (it1.hasNext())
+			return 1; // it2 is a prefix of it1
+		if (it2.hasNext())
+			return -1; // it1 is a prefix of it2
+		return 0;
+	}
+}

Property changes on: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/StringListBasedComparator.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/CompositeComparator.java
===================================================================
--- tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/CompositeComparator.java	(revision 0)
+++ tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/CompositeComparator.java	(revision 367)
@@ -0,0 +1,109 @@
+// Copyright © 2010-2013 ENS de Lyon.
+// Copyright © 2007-2010 ENS de Lyon, CNRS, INRP, University of
+// Lyon 2, University of Franche-Comté, University of Nice
+// Sophia Antipolis, University of Paris 3.
+// 
+// The TXM platform 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 2 of the License, or (at your option) any
+// later version.
+// 
+// The TXM platform 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 the TXM platform. If not, see
+// http://www.gnu.org/licenses.
+// 
+// 
+// 
+// $LastChangedDate: 2013-05-06 17:38:43 +0200 (lun., 06 mai 2013) $
+// $LastChangedRevision: 2386 $
+// $LastChangedBy: mdecorde $ 
+//
+package org.txm.concordance.core.functions.comparators;
+
+import java.util.List;
+
+import org.txm.concordance.core.functions.Line;
+import org.txm.concordance.core.messages.ConcordanceMessages;
+import org.txm.searchengine.cqp.corpus.Corpus;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class CompositeComparator.
+ */
+public class CompositeComparator extends LineComparator {
+
+	/** The comparators. */
+	private List<LineComparator> comparators;
+
+	/**
+	 * Instantiates a new composite comparator. A composite comparator C is made
+	 * of a list compartors [C0,...,Cn]. C.compare(l1,l2) == 1 (resp. -1) if and
+	 * only if their exists k such as Ci.compare(l1,l2)==0 for i<k and
+	 * Ck.compare(l1,l2)=1 (resp. -1) C.compare(l1,l2) == 0 if and only if
+	 * Ci.compare(l1,l2)==0 for all i
+	 *
+	 * @param name the name
+	 * @param comparators the comparators
+	 */
+	public CompositeComparator(String name, List<LineComparator> comparators) {
+		super(name);
+		setComparators(comparators);
+	}
+
+	/*public CompositeComparator addComparator(LineComparator comparator) {
+		this.comparators.add(comparator);
+		return this;
+	}*/
+
+	/* (non-Javadoc)
+	 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+	 */
+	@Override
+	public int compare(Line l1, Line l2) {
+		//System.out.println("compare: "+l1+" "+l2);
+		for (LineComparator comparator : comparators) {
+			int c = comparator.compare(l1, l2);
+			//System.out.println("comparator: "+comparator+" = "+c);
+			if (c != 0)
+				return c;
+		}
+		return 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.txm.functions.concordances.comparators.LineComparator#initialize(org.txm.searchengine.cqp.corpus.Corpus)
+	 */
+	@Override
+	public void initialize(Corpus corpus) {
+		for (LineComparator comparator : comparators)
+			comparator.initialize(corpus);
+	}
+
+	/**
+	 * Gets the comparators.
+	 *
+	 * @return the comparators
+	 */
+	public List<LineComparator> getComparators() {
+		return comparators;
+	}
+
+	/**
+	 * Sets the comparators.
+	 *
+	 * @param comp the new comparators
+	 */
+	public void setComparators(List<LineComparator> comp) {
+		this.comparators = comp;
+		this.name = ConcordanceMessages.CompositeComparator_0;
+		for(LineComparator c: comp)
+			this.name += c.getName()+" "; //$NON-NLS-1$
+		}
+}

Property changes on: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/CompositeComparator.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/LexicographicRightContextComparator.java
===================================================================
--- tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/LexicographicRightContextComparator.java	(revision 0)
+++ tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/LexicographicRightContextComparator.java	(revision 367)
@@ -0,0 +1,106 @@
+// Copyright © 2010-2013 ENS de Lyon.
+// Copyright © 2007-2010 ENS de Lyon, CNRS, INRP, University of
+// Lyon 2, University of Franche-Comté, University of Nice
+// Sophia Antipolis, University of Paris 3.
+// 
+// The TXM platform 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 2 of the License, or (at your option) any
+// later version.
+// 
+// The TXM platform 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 the TXM platform. If not, see
+// http://www.gnu.org/licenses.
+// 
+// 
+// 
+// $LastChangedDate: 2014-07-15 09:42:00 +0200 (mar., 15 juil. 2014) $
+// $LastChangedRevision: 2820 $
+// $LastChangedBy: mdecorde $ 
+//
+package org.txm.concordance.core.functions.comparators;
+
+import java.util.HashMap;
+import java.util.List;
+
+import org.txm.concordance.core.functions.Concordance;
+import org.txm.concordance.core.functions.Line;
+import org.txm.concordance.core.messages.ConcordanceMessages;
+import org.txm.searchengine.cqp.corpus.Property;
+
+// TODO: Auto-generated Javadoc
+/**
+ * Compare two values of right context of a concordance line @ author mdecorde.
+ */
+public class LexicographicRightContextComparator extends
+		StringListBasedComparator {
+
+	/** The Constant NAME. */
+	private static final String NAME = ConcordanceMessages.LexicographicRightContextComparator_0;
+	private Concordance conc;
+	private List<Property> props;
+
+	/**
+	 * Instantiates a new lexicographic right context comparator.
+	 */
+	public LexicographicRightContextComparator() {
+		super(NAME);
+	}
+
+	/* (non-Javadoc)
+	 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+	 */
+	@Override
+	public int compare(Line l1, Line l2) {
+		int rez = 0;
+		int i = 0; // property counter
+		int j = 0; // position counter
+		HashMap<Property, List<String>> values1 = l1.getRightAnalysisProperty();
+		HashMap<Property, List<String>> values2 = l2.getRightAnalysisProperty();
+		this.conc = l1.getConcordance();
+		this.props = conc.getRightAnalysisProperties();
+		
+		List<String> vals1;
+		List<String> vals2;
+		
+		String v1, v2;
+				
+		int size1  = values1.get(props.get(0)).size();
+		int size2 = values2.get(props.get(0)).size();
+		
+		while (rez == 0) {
+//			vals1 = values1.get(props.get(i));
+//			vals2 = values2.get(props.get(i));
+			
+			//System.out.println("LINE 1: "+vals1);
+			//System.out.println("LINE 2: "+vals2);
+			if(size1 <= j && size2 <= j)
+				return 0; // end of line 1
+			if (size1 <= j)
+				return -1; // end of line 1
+			if (size2 <= j)
+				return 1; // end of line 2
+			
+			v1 = values1.get(props.get(i)).get(j);
+			v2 = values2.get(props.get(i)).get(j);
+			
+			//System.out.println("COMP "+j+" : "+v1+" "+v2);
+			if (v1 == null) return -1;
+			if (v2 == null) return 1;
+			
+			rez = collator.compare(v1, v2);
+			if (++i >= props.size()) { // iterates over properties before tokens
+				i = 0;
+				j++;
+			}
+		}
+		return rez;
+	}
+}

Property changes on: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/LexicographicRightContextComparator.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/LexicographicKeywordComparator.java
===================================================================
--- tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/LexicographicKeywordComparator.java	(revision 0)
+++ tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/LexicographicKeywordComparator.java	(revision 367)
@@ -0,0 +1,87 @@
+// Copyright © 2010-2013 ENS de Lyon.
+// Copyright © 2007-2010 ENS de Lyon, CNRS, INRP, University of
+// Lyon 2, University of Franche-Comté, University of Nice
+// Sophia Antipolis, University of Paris 3.
+// 
+// The TXM platform 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 2 of the License, or (at your option) any
+// later version.
+// 
+// The TXM platform 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 the TXM platform. If not, see
+// http://www.gnu.org/licenses.
+// 
+// 
+// 
+// $LastChangedDate: 2013-05-06 17:38:43 +0200 (lun., 06 mai 2013) $
+// $LastChangedRevision: 2386 $
+// $LastChangedBy: mdecorde $ 
+//
+package org.txm.concordance.core.functions.comparators;
+
+import java.util.HashMap;
+import java.util.List;
+
+import org.txm.concordance.core.functions.Concordance;
+import org.txm.concordance.core.functions.Line;
+import org.txm.concordance.core.messages.ConcordanceMessages;
+import org.txm.searchengine.cqp.corpus.Property;
+
+// TODO: Auto-generated Javadoc
+/**
+ * Compare two values of keyword of a concordance line 
+ * @author mdecorde.
+ */
+public class LexicographicKeywordComparator extends LocalizedLineComparator {
+
+	/** The Constant NAME. */
+	private static final String NAME = ConcordanceMessages.LexicographicKeywordComparator_0;
+	private Concordance conc;
+	private List<Property> props;
+
+	/**
+	 * Instantiates a new lexicographic keyword comparator.
+	 */
+	public LexicographicKeywordComparator() {
+		super(NAME);
+	}
+
+	/* (non-Javadoc)
+	 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+	 */
+	@Override
+	public int compare(Line l1, Line l2) {
+		int rez = 0;
+		int i = 0;
+		int j = 0;
+		HashMap<Property, List<String>> values1 = l1.getKeywordsAnalysisProperty();
+		HashMap<Property, List<String>> values2 = l2.getKeywordsAnalysisProperty();
+		this.conc = l1.getConcordance();
+		this.props = conc.getKeywordAnalysisProperties();
+		while(rez == 0) {
+			List<String> vals1 = values1.get(props.get(i));
+			List<String> vals2 = values2.get(props.get(i));
+			if(vals1.size() <= j && vals2.size() <= j)
+				return 0; // end of line 1
+			if(vals1.size() <= j)
+				return -1; // end of line 1
+			if(vals2.size() <= j)
+				return 1; // end of line 2
+			rez = collator.compare(vals1.get(j), vals2.get(j));
+			if(++i >= props.size()) { // iterates over properties before tokens
+				i = 0;
+				j++;
+			}
+		}
+
+		return rez;
+	}
+}

Property changes on: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/LexicographicKeywordComparator.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/package.html
===================================================================
--- tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/package.html	(revision 0)
+++ tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/package.html	(revision 367)
@@ -0,0 +1,5 @@
+<html>
+<body>
+<p>Sorters for displaying concordance.</p>
+</body>
+</html>
\ No newline at end of file

Property changes on: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/package.html
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/LineComparator.java
===================================================================
--- tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/LineComparator.java	(revision 0)
+++ tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/LineComparator.java	(revision 367)
@@ -0,0 +1,97 @@
+// Copyright © 2010-2013 ENS de Lyon.
+// Copyright © 2007-2010 ENS de Lyon, CNRS, INRP, University of
+// Lyon 2, University of Franche-Comté, University of Nice
+// Sophia Antipolis, University of Paris 3.
+// 
+// The TXM platform 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 2 of the License, or (at your option) any
+// later version.
+// 
+// The TXM platform 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 the TXM platform. If not, see
+// http://www.gnu.org/licenses.
+// 
+// 
+// 
+// $LastChangedDate: 2013-05-06 17:38:43 +0200 (lun., 06 mai 2013) $
+// $LastChangedRevision: 2386 $
+// $LastChangedBy: mdecorde $ 
+//
+package org.txm.concordance.core.functions.comparators;
+
+import java.util.Comparator;
+
+import org.txm.concordance.core.functions.Line;
+import org.txm.searchengine.cqp.corpus.Corpus;
+
+// TODO: Auto-generated Javadoc
+/**
+ * Abstract comparator of concordance line @ author mdecorde.
+ */
+public abstract class LineComparator implements Comparator<Line> {
+
+	/** The name. */
+	protected String name;
+
+	/** The available comparator. */
+	private static String[] availableComparator = new String[] {
+			"org.txm.functions.concordances.comparators.LexicographicKeywordComparator", //$NON-NLS-1$
+			"org.txm.functions.concordances.comparators.LexicographicLeftContextComparator", //$NON-NLS-1$
+			"org.txm.functions.concordances.comparators.LexicographicRightContextComparator", //$NON-NLS-1$
+			"org.txm.functions.concordances.comparators.PropertiesReferenceComparator" //$NON-NLS-1$
+	};
+
+	/**
+	 * Return the list of all the known comparators. Any non-abstract class
+	 * extending LineComparator should be mentionned in the availableComparator
+	 * list
+	 *
+	 * @return the available comparators
+	 */
+	static public String[] getAvailableComparators() {
+		return availableComparator;
+	}
+
+	/**
+	 * Instantiates a new line comparator.
+	 *
+	 * @param name the name
+	 */
+	public LineComparator(String name) {
+		this.name = name;
+
+	}
+
+	/**
+	 * Gets the name.
+	 *
+	 * @return the name
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#toString()
+	 */
+	@Override
+	public String toString() {
+		return "C:" + name; //$NON-NLS-1$
+	}
+
+	/**
+	 * Initialize.
+	 *
+	 * @param corpus the corpus
+	 */
+	public abstract void initialize(Corpus corpus);
+
+}

Property changes on: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/LineComparator.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/NullComparator.java
===================================================================
--- tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/NullComparator.java	(revision 0)
+++ tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/NullComparator.java	(revision 367)
@@ -0,0 +1,58 @@
+// Copyright © 2010-2013 ENS de Lyon.
+// Copyright © 2007-2010 ENS de Lyon, CNRS, INRP, University of
+// Lyon 2, University of Franche-Comté, University of Nice
+// Sophia Antipolis, University of Paris 3.
+// 
+// The TXM platform 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 2 of the License, or (at your option) any
+// later version.
+// 
+// The TXM platform 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 the TXM platform. If not, see
+// http://www.gnu.org/licenses.
+// 
+// 
+// 
+// $LastChangedDate: 2013-05-06 17:38:43 +0200 (lun., 06 mai 2013) $
+// $LastChangedRevision: 2386 $
+// $LastChangedBy: mdecorde $ 
+//
+package org.txm.concordance.core.functions.comparators;
+
+import org.txm.concordance.core.functions.Line;
+import org.txm.concordance.core.messages.ConcordanceMessages;
+
+// TODO: Auto-generated Javadoc
+/**
+ * return the order of the text.
+ *
+ * @author mdecorde
+ */
+public class NullComparator extends LocalizedLineComparator {
+
+	/** The Constant NAME. */
+	private static final String NAME = ConcordanceMessages.NullComparator_0;
+
+	/**
+	 * Instantiates a new null comparator.
+	 */
+	public NullComparator() {
+		super(NAME);
+	}
+
+	/* (non-Javadoc)
+	 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+	 */
+	@Override
+	public int compare(Line l1, Line l2) {
+		return l1.getKeywordPosition() - l2.getKeywordPosition();
+	}
+}

Property changes on: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/NullComparator.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/PropertiesReferenceComparator.java
===================================================================
--- tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/PropertiesReferenceComparator.java	(revision 0)
+++ tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/PropertiesReferenceComparator.java	(revision 367)
@@ -0,0 +1,81 @@
+// Copyright © 2010-2013 ENS de Lyon.
+// Copyright © 2007-2010 ENS de Lyon, CNRS, INRP, University of
+// Lyon 2, University of Franche-Comté, University of Nice
+// Sophia Antipolis, University of Paris 3.
+// 
+// The TXM platform 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 2 of the License, or (at your option) any
+// later version.
+// 
+// The TXM platform 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 the TXM platform. If not, see
+// http://www.gnu.org/licenses.
+// 
+// 
+// 
+// $LastChangedDate: 2013-05-06 17:38:43 +0200 (lun., 06 mai 2013) $
+// $LastChangedRevision: 2386 $
+// $LastChangedBy: mdecorde $ 
+//
+package org.txm.concordance.core.functions.comparators;
+
+import org.txm.concordance.core.functions.Line;
+import org.txm.concordance.core.messages.ConcordanceMessages;
+import org.txm.functions.Reference;
+import org.txm.searchengine.cqp.corpus.Property;
+
+// TODO: Auto-generated Javadoc
+/**
+ * Compare the references of concordance line @ author mdecorde.
+ */
+public class PropertiesReferenceComparator extends LocalizedLineComparator {
+
+	/** The Constant NAME. */
+	private static final String NAME = ConcordanceMessages.PropertiesReferenceComparator_0;
+
+	//protected Collator collator = Collator.getInstance(new Locale(System.getProperty("user.language"))); //$NON-NLS-1$
+
+	/**
+	 * Instantiates a new properties reference comparator.
+	 */
+	public PropertiesReferenceComparator() {
+		super(NAME);
+	}
+
+	/* (non-Javadoc)
+	 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+	 */
+	@Override
+	public int compare(Line l1, Line l2) {
+		if (l1 == null || l2 == null)
+			return 0;
+
+		Reference ref1 = l1.getAnaRef();
+		Reference ref2 = l2.getAnaRef();
+		assert (ref1.getReferencePattern().equals(ref2.getReferencePattern()));
+		for (Property prop : ref1.getProperties()) {
+			int c = 0;
+			try {
+				Integer i1 = Integer.parseInt(ref1.getValue(prop));
+				Integer i2 = Integer.parseInt(ref2.getValue(prop));
+				c = i1.compareTo(i2);
+			} catch (NumberFormatException e) {
+				//System.out.println("sort "+ref1+ " "+ ref2 +" with "+collator);
+				c = collator.compare(ref1.getValue(prop), ref2.getValue(prop));
+			}
+
+			if (c != 0) {
+				return c;
+			}
+		}
+		return 0;
+	}
+}

Property changes on: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/PropertiesReferenceComparator.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/ReverseComparator.java
===================================================================
--- tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/ReverseComparator.java	(revision 0)
+++ tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/ReverseComparator.java	(revision 367)
@@ -0,0 +1,78 @@
+// Copyright © 2010-2013 ENS de Lyon.
+// Copyright © 2007-2010 ENS de Lyon, CNRS, INRP, University of
+// Lyon 2, University of Franche-Comté, University of Nice
+// Sophia Antipolis, University of Paris 3.
+// 
+// The TXM platform 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 2 of the License, or (at your option) any
+// later version.
+// 
+// The TXM platform 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 the TXM platform. If not, see
+// http://www.gnu.org/licenses.
+// 
+// 
+// 
+// $LastChangedDate: 2013-05-06 17:38:43 +0200 (lun., 06 mai 2013) $
+// $LastChangedRevision: 2386 $
+// $LastChangedBy: mdecorde $ 
+//
+package org.txm.concordance.core.functions.comparators;
+
+import org.txm.concordance.core.functions.Line;
+import org.txm.searchengine.cqp.corpus.Corpus;
+
+// TODO: Auto-generated Javadoc
+/**
+ * Revert a comparator @ author mdecorde.
+ */
+public class ReverseComparator extends LineComparator {
+
+	/** The comparator. */
+	private LineComparator comparator;
+
+	/**
+	 * Instantiates a new reverse comparator.
+	 *
+	 * @param name the name
+	 * @param comparator the comparator
+	 */
+	public ReverseComparator(String name, LineComparator comparator) {
+		super(name);
+		this.comparator = comparator;
+	}
+
+	/**
+	 * Instantiates a new reverse comparator.
+	 *
+	 * @param comparator the comparator
+	 */
+	public ReverseComparator(LineComparator comparator) {
+		super(comparator.getName());
+		this.comparator = comparator;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.txm.functions.concordances.comparators.LineComparator#initialize(org.txm.searchengine.cqp.corpus.Corpus)
+	 */
+	@Override
+	public void initialize(Corpus corpus) {
+		comparator.initialize(corpus);
+	}
+
+	/* (non-Javadoc)
+	 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+	 */
+	@Override
+	public int compare(Line l1, Line l2) {
+		return -1 * comparator.compare(l1, l2);
+	}
+}

Property changes on: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/ReverseComparator.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/LocalizedLineComparator.java
===================================================================
--- tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/LocalizedLineComparator.java	(revision 0)
+++ tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/LocalizedLineComparator.java	(revision 367)
@@ -0,0 +1,86 @@
+// Copyright © 2010-2013 ENS de Lyon.
+// Copyright © 2007-2010 ENS de Lyon, CNRS, INRP, University of
+// Lyon 2, University of Franche-Comté, University of Nice
+// Sophia Antipolis, University of Paris 3.
+// 
+// The TXM platform 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 2 of the License, or (at your option) any
+// later version.
+// 
+// The TXM platform 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 the TXM platform. If not, see
+// http://www.gnu.org/licenses.
+// 
+// 
+// 
+// $LastChangedDate: 2014-07-15 09:42:00 +0200 (mar., 15 juil. 2014) $
+// $LastChangedRevision: 2820 $
+// $LastChangedBy: mdecorde $ 
+//
+package org.txm.concordance.core.functions.comparators;
+
+import java.text.Collator;
+import java.util.Locale;
+
+import org.txm.searchengine.cqp.corpus.Corpus;
+import org.txm.utils.logger.Log;
+
+// TODO: Auto-generated Javadoc
+/**
+ * use the giver locale to compare concordance line, if locale is not defined,
+ * use the system locale @ author mdecorde.
+ */
+public abstract class LocalizedLineComparator extends LineComparator {
+
+	/** The locale. */
+	private Locale locale = new Locale("en", "US"); //$NON-NLS-1$ //$NON-NLS-2$
+
+	/** The collator. */
+	protected Collator collator;
+
+	/**
+	 * Instantiates a new localized line comparator.
+	 *
+	 * @param name the name
+	 */
+	public LocalizedLineComparator(String name) {
+		super(name);
+	}
+
+	/**
+	 * Gets the locale.
+	 *
+	 * @return the locale
+	 */
+	public Locale getLocale() {
+		return locale;
+	}
+
+	/**
+	 * Sets the locale.
+	 *
+	 * @param locale the new locale
+	 */
+	public void setLocale(Locale locale) {
+		Log.info("Set comparator locale to "+locale);
+		this.locale = locale;
+		this.collator = Collator.getInstance(locale);
+		this.collator.setStrength(Collator.TERTIARY);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.txm.functions.concordances.comparators.LineComparator#initialize(org.txm.searchengine.cqp.corpus.Corpus)
+	 */
+	@Override
+	public void initialize(Corpus corpus) {
+		setLocale(corpus.getLocale());
+	}
+}

Property changes on: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/comparators/LocalizedLineComparator.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/Concordance.java
===================================================================
--- tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/Concordance.java	(revision 0)
+++ tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/Concordance.java	(revision 367)
@@ -0,0 +1,1671 @@
+// Copyright © 2010-2013 ENS de Lyon.
+// Copyright © 2007-2010 ENS de Lyon, CNRS, INRP, University of
+// Lyon 2, University of Franche-Comté, University of Nice
+// Sophia Antipolis, University of Paris 3.
+// 
+// The TXM platform 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 2 of the License, or (at your option) any
+// later version.
+// 
+// The TXM platform 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 the TXM platform. If not, see
+// http://www.gnu.org/licenses.
+// 
+// 
+// 
+// $LastChangedDate: 2016-11-29 16:47:07 +0100 (Tue, 29 Nov 2016) $
+// $LastChangedRevision: 3349 $
+// $LastChangedBy: mdecorde $ 
+//
+package org.txm.concordance.core.functions;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import org.txm.annotation.Annotation;
+import org.txm.annotation.AnnotationManager;
+import org.txm.annotation.repository.AnnotationType;
+import org.txm.annotation.repository.TypedValue;
+import org.txm.concordance.core.functions.comparators.LineComparator;
+import org.txm.concordance.core.messages.ConcordanceMessages;
+//import org.txm.core.messages.ConcordanceMessages;
+import org.txm.functions.Function;
+import org.txm.functions.Reference;
+import org.txm.functions.ReferencePattern;
+import org.txm.searchengine.cqp.AbstractCqiClient;
+import org.txm.searchengine.cqp.MemCqiClient;
+import org.txm.searchengine.cqp.clientExceptions.CqiClientException;
+import org.txm.searchengine.cqp.corpus.Corpus;
+import org.txm.searchengine.cqp.corpus.CorpusManager;
+import org.txm.searchengine.cqp.corpus.Property;
+import org.txm.searchengine.cqp.corpus.QueryResult;
+import org.txm.searchengine.cqp.corpus.StructuralUnit;
+import org.txm.searchengine.cqp.corpus.query.Match;
+import org.txm.searchengine.cqp.corpus.query.Query;
+import org.txm.searchengine.cqp.serverException.CqiServerError;
+import org.txm.statsengine.r.core.RWorkspace;
+import org.txm.statsengine.r.core.exceptions.RWorkspaceException;
+import org.txm.utils.logger.Log;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class Concordance.
+ * 
+ * @author jmague, mdecorde
+ */
+public class Concordance extends Function {
+
+	/**
+	 * The Enum Format.
+	 */
+	public enum Format {
+		/** The CONCORDANCE. */
+		CONCORDANCE, 
+		/** The CONTEXT. */
+		CONTEXT
+	};
+
+	/** The lines. */
+	private List<Line> lines;
+
+	/** The query result. */
+	private QueryResult queryResult;
+
+	/** The view properties. */
+	private List<Property> viewProperties; // contains all the view properties
+	// needed
+	/** The left c view properties. */
+	private List<Property> leftCViewProperties;
+
+	/** The right c view properties. */
+	private List<Property> rightCViewProperties;
+
+	/** The keyword view properties. */
+	private List<Property> keywordViewProperties;
+
+	/** The analysis property. */
+	private List<Property> leftAnalysisProperties;
+
+	/** The right c analysis property. */
+	private List<Property> rightAnalysisProperties;
+
+	/** The keyword analysis property. */
+	private List<Property> keywordAnalysisProperties;
+
+	/** The n lines. */
+	private int nLines;
+
+	/** The right context size. */
+	private int rightContextSize;
+
+	/** The left context size. */
+	private int leftContextSize;
+
+	/** The corpus. */
+	//private Corpus corpus;
+
+	/** The reference pattern. */
+	private ReferencePattern refViewPattern;
+	private ReferencePattern refAnalysePattern;
+
+	/** The cache. */
+	//private Map<Property, CqpDataProxy> cache;
+
+	/** The query. */
+	private Query query;
+
+	/** The symbol. */
+	private String symbol;
+
+	/** The writer. */
+	private Writer writer;
+
+	/**
+	 * Creates a new concordance and compute it.
+	 *
+	 * @param corpus The corpus on which apply the query
+	 * @param query The query defining the keywords
+	 * @param analysisProperty The property used to sort the lines
+	 * @param viewProperties The property used to print the lines
+	 * @param referencePattern the reference pattern
+	 * @param leftContextSize The size in words of the left context
+	 * @param rightContextSize The size in words of the right context
+	 * @throws CqiClientException the cqi client exception
+	 */
+	public Concordance(Corpus corpus, Query query, Property analysisProperty,
+			List<Property> viewProperties, ReferencePattern referencePattern, ReferencePattern refAnalysePattern,
+			int leftContextSize, int rightContextSize)
+					throws CqiClientException {
+
+		super(corpus);
+		// set concordance parameters
+		this.query = query;
+		this.leftAnalysisProperties = Arrays.asList(analysisProperty); // same analysis property
+		this.rightAnalysisProperties = Arrays.asList(analysisProperty);
+		this.keywordAnalysisProperties = Arrays.asList(analysisProperty);
+		this.viewProperties = viewProperties; // same view property for left, right context and keyword
+		this.leftCViewProperties = viewProperties;
+		this.rightCViewProperties = viewProperties;
+		this.keywordViewProperties = viewProperties;
+		this.updateViewPropertiesList();
+		this.refViewPattern = referencePattern;
+		this.refAnalysePattern = refAnalysePattern;
+		this.leftContextSize = leftContextSize;
+		this.rightContextSize = rightContextSize;
+
+		if (corpus != null) {
+			setCQLSeparator(corpus.getCQLLimitQuery());
+		}
+
+		computeConcordance();
+	}
+
+	/**
+	 * Creates a new concordance and compute it.
+	 *
+	 * @param corpus The corpus on which apply the query
+	 * @param query The query defining the keywords
+	 * @param analysisProperty The property used to sort the lines
+	 * @param leftCViewProperties The property used to print the lines of Left context
+	 * @param rightCViewProperties The property used to print the lines of right context
+	 * @param keywordViewProperties The property used to print the lines of keyword
+	 * @param referencePattern the reference pattern
+	 * @param leftContextSize The size in words of the left context
+	 * @param rightContextSize The size in words of the right context
+	 * @throws CqiClientException the cqi client exception
+	 */
+	public Concordance(Corpus corpus, Query query, Property analysisProperty,
+			List<Property> leftCViewProperties,
+			List<Property> rightCViewProperties,
+			List<Property> keywordViewProperties,
+			ReferencePattern referencePattern, 
+			ReferencePattern refAnalysePattern,int leftContextSize,
+			int rightContextSize) throws CqiClientException {
+		super(corpus);
+		// set concordance parameters
+		this.query = query;
+		this.leftAnalysisProperties = Arrays.asList(analysisProperty);
+		this.rightAnalysisProperties = Arrays.asList(analysisProperty);
+		this.keywordAnalysisProperties = Arrays.asList(analysisProperty);
+		this.leftCViewProperties = leftCViewProperties;
+		this.rightCViewProperties = rightCViewProperties;
+		this.keywordViewProperties = keywordViewProperties;
+		this.updateViewPropertiesList();
+		this.refViewPattern = referencePattern;
+		this.refAnalysePattern = refAnalysePattern;
+		this.leftContextSize = leftContextSize;
+		this.rightContextSize = rightContextSize;
+
+		if (corpus != null) {
+			setCQLSeparator(corpus.getCQLLimitQuery());
+		}
+
+		computeConcordance();
+	}
+
+	/**
+	 * Creates a new concordance and compute it.
+	 *
+	 * @param corpus The corpus on which apply the query
+	 * @param query The query defining the keywords
+	 * @param leftCAnalysisProperty the left c analysis property
+	 * @param rightCAnalysisProperty the right c analysis property
+	 * @param keywordAnalysisProperty the keyword analysis property
+	 * @param leftCViewProperties The property used to print the lines of Left context
+	 * @param rightCViewProperties The property used to print the lines of right context
+	 * @param keywordViewProperties The property used to print the lines of keyword
+	 * @param referencePattern the reference pattern
+	 * @param leftContextSize The size in words of the left context
+	 * @param rightContextSize The size in words of the right context
+	 * @throws CqiClientException the cqi client exception
+	 */
+	public Concordance(Corpus corpus, Query query,
+			Property leftCAnalysisProperty, Property rightCAnalysisProperty,
+			Property keywordAnalysisProperty,
+			List<Property> leftCViewProperties,
+			List<Property> rightCViewProperties,
+			List<Property> keywordViewProperties,
+			ReferencePattern referencePattern, 
+			ReferencePattern refAnalysePattern,
+			int leftContextSize,
+			int rightContextSize) throws CqiClientException {
+		
+		super(corpus);
+		// set concordance parameters
+		this.query = query;
+		this.leftAnalysisProperties = Arrays.asList(leftCAnalysisProperty);
+		this.rightAnalysisProperties = Arrays.asList(rightCAnalysisProperty);
+		this.keywordAnalysisProperties = Arrays.asList(keywordAnalysisProperty);
+		this.leftCViewProperties = leftCViewProperties;
+		this.rightCViewProperties = rightCViewProperties;
+		this.keywordViewProperties = keywordViewProperties;
+		this.updateViewPropertiesList();
+		this.refViewPattern = referencePattern;
+		this.refAnalysePattern = refAnalysePattern;
+		this.leftContextSize = leftContextSize;
+		this.rightContextSize = rightContextSize;
+
+		computeConcordance();
+	}
+
+	public Concordance(Corpus corpus, Query query,
+			List<Property> selectedLeftCSortProperty,
+			List<Property> selectedRightCSortProperty,
+			List<Property> selectedKeywordSortProperty,
+			List<Property> selectedLeftCViewProperties,
+			List<Property> selectedRightCViewProperties,
+			List<Property> selectedKeywordViewProperties,
+			ReferencePattern referencePattern, 
+			ReferencePattern refAnalysePattern, int leftContextSize,
+			int rightContextSize) throws CqiClientException {
+		
+		super(corpus);
+		// set concordance parameters
+		this.query = query;
+		this.leftAnalysisProperties = selectedLeftCSortProperty;
+		this.rightAnalysisProperties = selectedRightCSortProperty;
+		this.keywordAnalysisProperties = selectedKeywordSortProperty;
+		this.leftCViewProperties = selectedLeftCViewProperties;
+		this.rightCViewProperties = selectedRightCViewProperties;
+		this.keywordViewProperties = selectedKeywordViewProperties;
+		this.updateViewPropertiesList();
+		this.refViewPattern = referencePattern;
+		this.refAnalysePattern = refAnalysePattern;
+		this.leftContextSize = leftContextSize;
+		this.rightContextSize = rightContextSize;
+
+		computeConcordance();
+	}
+
+	/**
+	 * Update view properties list.
+	 */
+	private void updateViewPropertiesList() {
+		// reset view properties
+		this.viewProperties = new ArrayList<Property>();
+		// fill it with the properties of the others
+		viewProperties.addAll(keywordViewProperties);
+
+		for (Property p : leftCViewProperties)// add the view properties of left context
+		{
+			if (!viewProperties.contains(p)) {
+				viewProperties.add(p);
+			}
+		}
+
+		for (Property p : rightCViewProperties)// add the view properties of right context
+		{
+			if (!viewProperties.contains(p)) {
+				viewProperties.add(p);
+			}
+		}
+	}
+
+	/**
+	 * Compute concordance.
+	 *
+	 * @return true, if successful
+	 * @throws CqiClientException 
+	 */
+	private boolean computeConcordance() throws CqiClientException {
+		this.queryResult = this.getCorpus().query(query, query.getQueryString()
+				.replace(" ", "_") + "_concordance", true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+		this.nLines = queryResult.getNMatch();
+		this.lines = new ArrayList<Line>(Collections.nCopies(nLines,
+				(Line) null));// lines are lazily fetched; we force an
+		// ArrayList so we can use the 'set' method
+
+		return true;
+	}
+
+
+	/**
+	 * Returns the query used to build the concordance.
+	 * 
+	 * @return the query
+	 */
+	public Query getQuery() {
+		return query;
+	}
+
+	//int[] textStarts = null;
+	int[] CQLLimitStarts = null;
+	String cql_limit;
+
+	public List<Line> reloadLines(int topLine, int bottomLine) throws CqiClientException, IOException, CqiServerError {
+		for (int i = topLine; i < bottomLine; i++) {
+			lines.set(i, null);
+		}
+
+		return getLines(topLine, bottomLine);
+	}
+
+	/**
+	 * Returns the line between from and to.
+	 * 
+	 * @param from
+	 *            the from
+	 * @param to
+	 *            the to
+	 * 
+	 * @return the lines
+	 * 
+	 * @throws CqiClientException
+	 *             the cqi client exception
+	 * @throws CqiServerError 
+	 * @throws IOException 
+	 */
+	public List<Line> getLines(int from, int to) throws CqiClientException, IOException, CqiServerError {
+
+		Log.info(ConcordanceMessages.Concordance_6 + (to - from + 1) + ConcordanceMessages.Concordance_7);
+
+		AnnotationManager am = this.getCorpus().getAnnotationManager();
+
+		AbstractCqiClient cqiClient = CorpusManager.getCorpusManager().getCqiClient();
+		
+		long start = System.currentTimeMillis();
+
+		// check asked lines numbers
+		if (from < 0) from = 0;
+		if (from > to) from = to;
+		if (to >= nLines) to = nLines - 1;
+		if (from < 0 || from > to || to >= nLines) {
+			throw new IndexOutOfBoundsException();
+		}
+
+		List<Match> matches = queryResult.getMatches(from, to);
+
+		//		System.out.println("cqllimit="+cql_limit);
+		//		System.out.println("CQLLimitStarts="+CQLLimitStarts);
+		if (cql_limit != null && CQLLimitStarts == null) { // initialize text limits
+			try {
+				Log.warning("Get CQL limit for query="+cql_limit);
+				CQLLimitStarts = this.getCorpus().getStartLimits(cql_limit);
+				if (CQLLimitStarts.length > 0 && CQLLimitStarts[0] != 0) {
+					int[] tmp  = new int[CQLLimitStarts.length + 1];
+					System.arraycopy(CQLLimitStarts, 0, tmp, 1, CQLLimitStarts.length);
+					CQLLimitStarts = tmp;
+				}
+			} catch (Exception e) {
+				org.txm.utils.logger.Log.printStackTrace(e);
+				Log.severe(ConcordanceMessages.Concordance_8+e);
+			}
+		}
+
+		int currentCQLLimit = 0;
+		// System.out.println("texts: "+Arrays.toString(textStarts));
+		// we create the blocks of lines not created yet that may occur between
+		// from and to
+		//int step = Math.max(100/(to - from), 1);
+		for (int i = from; i <= to; i++) {
+			int j;
+			for (j = i; j <= to && lines.get(j) == null; j++); // THIS IS MANDATORY
+			// j is the index of the first next existing line
+			if (i != j) { // i does point at the beginning of a block of non
+				// existing lines. We have to create the lines between i and j
+
+				if (isCanceled()) return new ArrayList<Line>(); // check if user canceled the Job
+
+				// First we get all the data we need : values for the view
+				// properties, the analysis property and the reference
+				List<Integer> beginingOfKeywordsPositions = new ArrayList<Integer>(j - i);
+				List<Integer> targetPositions = new ArrayList<Integer>(j - i);
+				List<Integer> lengthOfKeywords = new ArrayList<Integer>(j - i);
+				List<Integer> beginingOfRightCtxPositions = new ArrayList<Integer>(	j - i);
+				List<Integer> lengthOfRightCtx = new ArrayList<Integer>(j - i);
+				List<Integer> beginingOfLeftCtxPositions = new ArrayList<Integer>(j - i);
+				List<Integer> lengthOfLeftCtx = new ArrayList<Integer>(j - i);
+
+				// get all first token and last token of all lines
+				int currentKeywordPos;// = matches.get(0).getStart();
+				//currentText = previousPivotText;
+
+				List<Match> subsetMatch = new ArrayList<Match>(); 
+
+				for (int k = 0; k < j - i; k++) {
+					Match match = matches.get(i - from + k);
+					subsetMatch.add(match);
+					//System.out.println("match: "+match);
+					//1) find current text using keyword position
+					currentKeywordPos = match.getStart();
+
+					if (CQLLimitStarts != null && currentCQLLimit < CQLLimitStarts.length) {
+						while (currentCQLLimit < CQLLimitStarts.length && CQLLimitStarts[currentCQLLimit] <= currentKeywordPos) { // find the match's text
+							currentCQLLimit++; // matches are ordered
+						}
+						if (currentCQLLimit > 0) {
+							currentCQLLimit--; // get the previous text
+						}
+					}
+
+					//System.out.println("text no: "+currentText+" text position: "+textStarts[currentText]);
+					// LEFT CONTEXT LIMITS
+					int ctxPosition = currentKeywordPos - leftContextSize; // left context start position
+					if (CQLLimitStarts != null && currentCQLLimit < CQLLimitStarts.length) {
+						if (CQLLimitStarts[currentCQLLimit] > ctxPosition) { // test if the end of left context is in the same text
+							ctxPosition = CQLLimitStarts[currentCQLLimit]; // the context start is the start of the text
+							//System.out.println("fix right "+currentText+" pos: "+ctxPosition);
+						}
+					}
+					beginingOfLeftCtxPositions.add(ctxPosition);
+					lengthOfLeftCtx.add(match.getStart() - ctxPosition); // distance between let context start position and keyword position
+					//System.out.println("left: "+ctxPosition+ "len: "+(match.getStart() - ctxPosition));
+
+					// KEYWORD LIMITS
+					beginingOfKeywordsPositions.add(match.getStart());
+					lengthOfKeywords.add(match.getEnd() - match.getStart() + 1);
+
+					//TARGET POSITION
+					targetPositions.add(match.getTarget());
+
+					// check if the end of keyword pass a text limit
+					// TODO: Can a keyword be over 2 texts ??
+					currentKeywordPos = match.getEnd();
+
+					if (CQLLimitStarts != null)
+						if (currentCQLLimit < CQLLimitStarts.length) {
+							while (currentCQLLimit < CQLLimitStarts.length && CQLLimitStarts[currentCQLLimit] <= currentKeywordPos) { // find the match's text
+								currentCQLLimit++; // matches are ordered
+							}
+							if (currentCQLLimit > 0)
+								currentCQLLimit--; // get the previous text
+						}
+					// find the right limit
+					ctxPosition = match.getEnd() + rightContextSize;
+
+					if (CQLLimitStarts != null)
+						if (currentCQLLimit + 1 < CQLLimitStarts.length) {
+							if (CQLLimitStarts[currentCQLLimit+1] < ctxPosition) { // test if the right context last position is in the same text as the pivot
+								ctxPosition = CQLLimitStarts[currentCQLLimit+1] -1 ; // the context end is the next text start position
+							}
+						}
+
+					//if (ctxPosition > corpus.getSize()) ctxPosition = corpus.getSize();
+
+					beginingOfRightCtxPositions.add(match.getEnd() + 1);
+					lengthOfRightCtx.add(ctxPosition - match.getEnd());
+					//System.out.println("right: "+ctxPosition+" len: "+(ctxPosition - match.getEnd() + 1)+"\n");
+				}
+
+				//List<Annotation> allAnnotations = null;
+				List<Annotation> annotationsPerMatch = null;;
+				if (viewAnnotation != null && am != null) {
+					try {
+						annotationsPerMatch = am.getAnnotationsForMatches(viewAnnotation, subsetMatch, overlapAnnotation);
+						//System.out.println("annotationsPerMatch: "+annotationsPerMatch);
+					} catch (Exception e) {
+						System.out.println("Error while reading annotation "+viewAnnotation+" and with "+subsetMatch.size()+" matches");
+						Log.printStackTrace(e);
+					}
+				}
+
+				//System.out.println("RIGHT ctx lengths: "+lengthOfRightCtx);
+				// get all view property values of all lines
+				Map<Property, List<List<String>>> keywordsViewPropValues = new HashMap<Property, List<List<String>>>();
+				Map<Property, List<List<String>>> leftCtxViewPropValues = new HashMap<Property, List<List<String>>>();
+				Map<Property, List<List<String>>> rightCtxViewPropValues = new HashMap<Property, List<List<String>>>();
+				for (Property property : leftCViewProperties) {
+					leftCtxViewPropValues.put(property, cqiClient.getData(property, beginingOfLeftCtxPositions,
+							lengthOfLeftCtx));
+				}
+				for (Property property : rightCViewProperties) {
+					rightCtxViewPropValues.put(property, cqiClient.getData(property, beginingOfRightCtxPositions,
+							lengthOfRightCtx));
+				}
+				for (Property property : keywordViewProperties) {
+					keywordsViewPropValues.put(property, cqiClient.getData(property, beginingOfKeywordsPositions,
+							lengthOfKeywords));
+				}
+
+				// get all analysis property values of all lines
+				HashMap<Property, List<List<String>>> leftCtxAnaPropValues = new HashMap<Property, List<List<String>>>();
+				for(Property p : leftAnalysisProperties) {
+					leftCtxAnaPropValues.put(p, cqiClient.getData(p, beginingOfLeftCtxPositions, lengthOfLeftCtx));
+				}
+				HashMap<Property, List<List<String>>> keywordsAnaPropValues = new HashMap<Property, List<List<String>>>();
+				for(Property p : keywordAnalysisProperties) {
+					keywordsAnaPropValues.put(p, cqiClient.getData(p, beginingOfKeywordsPositions, lengthOfKeywords));
+				}
+				HashMap<Property, List<List<String>>> rightCtxAnaPropValues = new HashMap<Property, List<List<String>>>();
+				for(Property p : rightAnalysisProperties) {
+					rightCtxAnaPropValues.put(p, cqiClient.getData(p, beginingOfRightCtxPositions, lengthOfRightCtx));
+				}
+				// get all view reference values of all lines
+				Map<Property, List<List<String>>> refValues = new HashMap<Property, List<List<String>>>();
+				for (Property property : refViewPattern) {
+					refValues.put(property, cqiClient.getData(property, 
+							beginingOfKeywordsPositions,
+							Collections.nCopies(beginingOfKeywordsPositions.size(), 1)));
+				}
+
+				// get all sort reference values of all lines
+				Map<Property, List<List<String>>> refSortValues = new HashMap<Property, List<List<String>>>();
+				for (Property property : refAnalysePattern) {
+					refSortValues.put(property, cqiClient.getData(property, beginingOfKeywordsPositions,
+							Collections.nCopies(beginingOfKeywordsPositions.size(), 1)));
+				}
+
+				// get all lines' tokens ids
+				Property id = this.getCorpus().getProperty("id"); //$NON-NLS-1$
+				StructuralUnit text = this.getCorpus().getStructuralUnit("text"); //$NON-NLS-1$
+				Property text_id = text.getProperty("id"); //$NON-NLS-1$
+
+				List<List<String>> keywordsIdValues;
+				List<List<String>> keywordsTextValues;
+				if (id != null && text_id != null) {
+					/** The occurrences Ids&Text => BackToText */
+					keywordsIdValues = cqiClient.getData(id, beginingOfKeywordsPositions, lengthOfKeywords);
+					keywordsTextValues = cqiClient.getData(text_id, beginingOfKeywordsPositions,
+							Collections.nCopies(beginingOfKeywordsPositions
+									.size(), 1));
+				} else {
+					keywordsTextValues = null;
+					keywordsIdValues = null;
+					Log.warning(ConcordanceMessages.Concordance_1);
+				}
+
+				// Since we get the value only for the first word of the
+				// keyword, we know that refValues maps each property to a list
+				// of list of size==1 : refValue.get(p).get(i).size()==1
+
+				// Second, we build the lines
+				for (int k = 0; k < j - i; k++) {
+					//worked(1);
+					// get the kth line's analysis property values
+					HashMap<Property, List<String>> lineLeftCtxAnaPropValue = new HashMap<Property, List<String>>();
+					for(Property p : leftAnalysisProperties) {
+						lineLeftCtxAnaPropValue.put(p, leftCtxAnaPropValues.get(p).get(k));
+					}
+					HashMap<Property, List<String>> lineKeywordsAnaPropValue = new HashMap<Property, List<String>>();
+					for(Property p : keywordAnalysisProperties) {
+						lineKeywordsAnaPropValue.put(p, keywordsAnaPropValues.get(p).get(k));
+					}
+					HashMap<Property, List<String>> lineRightCtxAnaPropValue = new HashMap<Property, List<String>>();
+					for(Property p : rightAnalysisProperties) {
+						lineRightCtxAnaPropValue.put(p, rightCtxAnaPropValues.get(p).get(k));
+					}
+					// get the kth line's view property values
+					Map<Property, List<String>> lineLeftCtxViewPropValue = new HashMap<Property, List<String>>();
+					Map<Property, List<String>> lineKeywordsViewPropValue = new HashMap<Property, List<String>>();
+					Map<Property, List<String>> lineRightCtxViewPropValue = new HashMap<Property, List<String>>();
+					for (Property property : leftCViewProperties) {
+						lineLeftCtxViewPropValue.put(property,
+								leftCtxViewPropValues.get(property).get(k));
+					}
+					for (Property property : rightCViewProperties) {
+						lineRightCtxViewPropValue.put(property,
+								rightCtxViewPropValues.get(property).get(k));
+					}
+					for (Property property : keywordViewProperties) {
+						lineKeywordsViewPropValue.put(property,
+								keywordsViewPropValues.get(property).get(k));
+					}
+
+					// get the kth line reference values
+					Map<Property, String> ref = new HashMap<Property, String>();
+					for (Property property : refViewPattern) {
+						ref.put(property, refValues.get(property).get(k).get(0));
+					}
+
+					// get the kth line reference values
+					Map<Property, String> refAna = new HashMap<Property, String>();
+					for (Property property : refAnalysePattern) {
+						refAna.put(property, refSortValues.get(property).get(k).get(0));
+					}
+
+					// get Text id of the line
+					String TextId;
+					List<String> wordids;
+					if (keywordsIdValues != null && keywordsTextValues != null) {
+						TextId = keywordsTextValues.get(k).get(0);
+						wordids = keywordsIdValues.get(k);
+					} else {
+						TextId = ConcordanceMessages.Concordance_2;
+						wordids = new ArrayList<String>();
+					}
+
+					int targetpos = targetPositions.get(k);
+
+
+					Annotation annotation = null;
+					Match match = matches.get(i- from + k);
+					if (annotationsPerMatch != null) {
+						annotation = annotationsPerMatch.get(k);
+					}
+					TypedValue annotationValue = null;
+					if (annotation!=null) {
+						annotationValue = viewAnnotation.getTypedValue(annotation.getValue());
+						if (annotationValue == null) { // the annotation is not stored in the KR type -> the annotation is surely built with the CQPAnnotationManager
+							//System.out.println("WARNING: no annotation value found for value id="+annotation.getValue()+" - will be created.");
+							annotationValue = new TypedValue(annotation.getValue(), annotation.getValue(), annotation.getType());
+						}
+					}
+
+					Line line = new Line(this, wordids, TextId,
+							lineLeftCtxViewPropValue,
+							lineKeywordsViewPropValue,
+							lineRightCtxViewPropValue, lineLeftCtxAnaPropValue,
+							lineKeywordsAnaPropValue, lineRightCtxAnaPropValue,
+							new Reference(ref, refViewPattern), 
+							new Reference(refAna, refAnalysePattern), 
+							match, 
+							annotation,
+							annotationValue,
+							targetpos);
+					lines.set(i + k, line);
+				}
+			}
+			i = j;
+		}
+		List<Line> res = lines.subList(from, to + 1);// our to is inclusive,
+		// sublist's is exlusive
+		Log.info((to - from + 1) + ConcordanceMessages.Concordance_3
+				+ (System.currentTimeMillis() - start) + "ms"); //$NON-NLS-1$ 
+		return res;
+	}
+
+
+	private List<Annotation> prepareAnnotationsList(List<Match> matches, List<Annotation> annotations, boolean overlap){
+		List<Annotation> annotsList = new ArrayList<Annotation>();
+
+		int iMatch = 0;
+		int iAnnotation = 0;
+		int nMatch = matches.size();
+		int nAnnotations = annotations.size();
+
+		while (iMatch < nMatch && iAnnotation < nAnnotations) {
+			if (overlap) {
+				if (matches.get(iMatch).getEnd() < annotations.get(iAnnotation).getStart()) {
+					iMatch++;
+					annotsList.add(null); // nothing for this match
+				} else if (annotations.get(iAnnotation).getEnd() < matches.get(iMatch).getStart()) {
+					iAnnotation++;
+				} else {
+					annotsList.add(annotations.get(iAnnotation));
+					iMatch++;
+				}
+			} else {
+				if (matches.get(iMatch).getEnd() < annotations.get(iAnnotation).getStart()) {
+					iMatch++;
+					annotsList.add(null); // nothing for this match
+				} else if (annotations.get(iAnnotation).getEnd() < matches.get(iMatch).getStart()) {
+					iAnnotation++;
+				} else if (annotations.get(iAnnotation).getStart() == matches.get(iMatch).getStart() && 
+						annotations.get(iAnnotation).getEnd() == matches.get(iMatch).getEnd()) {
+					annotsList.add(annotations.get(iAnnotation));
+					iMatch++;
+					iAnnotation++;
+				} else {
+					iAnnotation++;
+				}
+			}
+		}
+
+		while (annotsList.size() < matches.size() ) annotsList.add(null); // fill matches that were not process due to no more annotations
+
+		return annotsList;
+	}
+
+	private HashMap<Match, Annotation> prepareAnnotationsMap(List<Match> matches, List<Annotation> annots, boolean overlap){
+		HashMap<Match, Annotation> annotsList = new HashMap<Match, Annotation>();
+		for(Match m : matches){
+			boolean hasAnnotations = false;
+			if(annots!=null){
+				if(!annots.isEmpty()){
+					for(Annotation annot : annots) {
+						if(overlap){
+							if ((annot.getStart() <= m.getStart() && m.getStart() <= annot.getEnd() && m.getEnd() >= annot.getEnd()) || 
+									(annot.getStart() <= m.getEnd() && m.getEnd() <= annot.getEnd() && m.getStart() <= annot.getStart()) 
+									|| !(annot.getEnd() < m.getStart() || annot.getStart() > m.getEnd())){
+								annotsList.put(m, annot);
+								hasAnnotations = true;
+							}
+						}else {
+							if(annot.getStart()==m.getStart() && annot.getEnd()==m.getEnd()){
+								annotsList.put(m, annot); 
+								hasAnnotations = true;
+							}
+						}
+					}
+				}
+			}
+			if(!hasAnnotations){
+				annotsList.put(m, null);
+			}
+		}
+		return annotsList;
+	}
+
+	private String findAnnotationForLine(Match match, List<Annotation> annots, boolean overlap){
+		String annotationValue = "";
+		if(annots!=null){
+			if(!annots.isEmpty()){
+				for(Annotation annot : annots){
+					if(overlap){
+						if((annot.getStart()<=match.getStart() && annot.getEnd()>=match.getEnd()) || (annot.getStart()>match.getStart() && annot.getEnd()<match.getEnd())
+								){
+							annotationValue = annot.getValue(); 
+							// use the first Annotation found, the one stored in the temporary HSQL database
+							//should be modified to display a list of annotation values corresponding to the match positions (or wrapped if overlap is admitted)
+						}
+					}else {
+						if(annot.getStart()==match.getStart() && annot.getEnd()==match.getEnd()){
+							annotationValue = annot.getValue(); 
+							// use the first Annotation found, the one stored in the temporary HSQL database
+						}
+					}
+				}
+			}
+		}
+		return annotationValue;
+	}
+
+	/**
+	 * Gets the number of lines.
+	 * 
+	 * @return the n lines
+	 */
+	public int getNLines() {
+		return nLines;
+	}
+
+	/**
+	 * Sort the lines of the concordance according a comparator.
+	 * 
+	 * @param comparator
+	 *            the comparator used to compare the lines
+	 * 
+	 * @throws CqiClientException
+	 *             the cqi client exception
+	 * @throws CqiServerError 
+	 * @throws IOException 
+	 */
+	public void sort(LineComparator comparator) throws CqiClientException, IOException, CqiServerError {
+		System.currentTimeMillis();
+		this.acquireSemaphore();
+		comparator.initialize(this.getCorpus());
+		this.releaseSemaphore();
+		if (getNLines() == 0) return;
+		getLines(0, nLines - 1);
+		if (lines.size() > 0) {
+			Collections.sort(lines, comparator);
+		}
+		System.currentTimeMillis();
+	}
+
+	/**
+	 * Write all the lines on a writer.
+	 *
+	 * @param outfile the outfile
+	 * @param encoding the encoding
+	 * @param colseparator the colseparator
+	 * @param txtseparator the txtseparator
+	 * @return true, if successful
+	 * @throws IOException 
+	 */
+	public boolean toTxt(File outfile, String encoding, String colseparator, String txtseparator) throws IOException {
+
+		// NK: writer declared as class attribute to perform a clean if the operation is interrupted
+		try {
+			this.writer = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(outfile)), encoding);
+			// if ("UTF-8".equals(encoding)) writer.write('\ufeff'); // UTF-8 BOM
+			toTxt(writer, 0, nLines - 1, colseparator, txtseparator);
+		} catch (UnsupportedEncodingException e) {
+			// TODO Auto-generated catch block
+			org.txm.utils.logger.Log.printStackTrace(e);
+		} catch (Exception e) {
+			System.err.println(ConcordanceMessages.Concordance_12 + e);
+			Log.printStackTrace(e);
+			return false;
+		} 
+
+		return true;
+	}
+
+	/**
+	 * To txt.
+	 *
+	 * @param outfile the outfile
+	 * @param format the format
+	 * @return true, if successful
+	 */
+	public boolean toTxt(File outfile, Format format) {
+		try {
+			this.writer = new BufferedWriter(new OutputStreamWriter(
+					new FileOutputStream(outfile), "UTF-8")); //$NON-NLS-1$
+			toTxt(writer, 0, nLines - 1, format, "\t",""); //$NON-NLS-1$ //$NON-NLS-2$
+		} catch (Exception e) {
+			System.err.println(ConcordanceMessages.Concordance_12 + e);
+			Log.printStackTrace(e);
+			return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Write the lines between from and to on a writer.
+	 * 
+	 * @param writer
+	 *            Where to write the lines
+	 * @param from
+	 *            The first line to be written
+	 * @param to
+	 *            The last line to be writen
+	 * 
+	 * @throws CqiClientException
+	 *             the cqi client exception
+	 * @throws IOException
+	 *             Signals that an I/O exception has occurred.
+	 * @throws CqiServerError 
+	 */
+	public void toTxt(Writer writer, int from, int to)
+			throws CqiClientException, IOException, CqiServerError {
+
+		toTxt(writer, from, to, Format.CONCORDANCE, "\t", ""); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	/**
+	 * Write the lines between from and to on a writer with custom col and txt separators.
+	 * 
+	 * @param writer
+	 *            Where to write the lines
+	 * @param from
+	 *            The first line to be written
+	 * @param to
+	 *            The last line to be writen
+	 * @param colseparator
+	 * 			  The column separator
+	 * @param txtseparator
+	 * 			  Thx text separator, e.g txtseparator=' : "I'm" >> "I''m"
+	 * 
+	 * @throws CqiClientException
+	 *             the cqi client exception
+	 * @throws IOException
+	 *             Signals that an I/O exception has occurred.
+	 * @throws CqiServerError 
+	 */
+	public void toTxt(Writer writer, int from, int to, String colseparator, String txtseparator)
+			throws CqiClientException, IOException, CqiServerError {
+
+		toTxt(writer, from, to, Format.CONCORDANCE, colseparator, txtseparator);
+	}
+
+	/**
+	 * Adds the txt sep.
+	 *
+	 * @param str the str
+	 * @param separator the separator
+	 * @return the string
+	 */
+	private String addTxtSep(String str, String separator)
+	{
+		return separator+(str.replace(separator, separator+separator))+separator;
+	}
+
+	/**
+	 * To txt.
+	 * Write line per packet to avoid memory limits
+	 *
+	 * @param writer the writer
+	 * @param from the from
+	 * @param to the to
+	 * @param format the format
+	 * @param colseparator the colseparator
+	 * @param txtseparator the txtseparator
+	 * @throws CqiClientException the cqi client exception
+	 * @throws IOException Signals that an I/O exception has occurred.
+	 * @throws CqiServerError 
+	 */
+	public void toTxt(Writer writer, int from, int to, Format format, String colseparator, String txtseparator)
+			throws CqiClientException, IOException, CqiServerError {
+
+		int packetSize = 5000;
+		int nlines = to - from;
+		if (nlines == 0) nlines = 1;
+		int step = (100*packetSize)/nlines;
+		if (step == 0) step = 1;
+
+		String keyColSeparator = colseparator; // the separator is "" if export in CONTEXT mode
+		// write header and set keywordColumnSeparator
+		if (format == Format.CONTEXT) {
+			keyColSeparator = "";
+			writer.write(
+					txtseparator+ConcordanceMessages.Concordance_17+txtseparator
+					+ colseparator+txtseparator+ConcordanceMessages.Concordance_19+txtseparator
+					+ "\n"); //$NON-NLS-1$
+		} else {
+			writer.write(
+					addTxtSep(ConcordanceMessages.Concordance_13, txtseparator)+colseparator
+					+ addTxtSep(ConcordanceMessages.Concordance_14, txtseparator)+colseparator
+					+ addTxtSep(ConcordanceMessages.Concordance_15, txtseparator)+colseparator
+					+ addTxtSep(ConcordanceMessages.Concordance_16, txtseparator)
+					+ "\n"); //$NON-NLS-1$
+		}
+
+		//write lines
+		for (int i = from ; i <= to ; i += packetSize +1) {
+			worked(step);
+			//println "worked: $step"
+			//println "packet $i -> "+(i+packetSize)
+			int to2 = i+packetSize;
+			if (to2 > to) to2 = to;
+			//println "get lines: $i -> $to2"
+			List<Line> sublines = getLines(i, to2);
+			for (Line line : sublines) {
+				writer.write(
+						addTxtSep(line.getViewRef().toString(), txtseparator)
+						+ colseparator + addTxtSep(line.leftContextToString(), txtseparator)
+						+ keyColSeparator + addTxtSep(line.keywordToString(), txtseparator)
+						+ keyColSeparator + addTxtSep(line.rightContextToString(), txtseparator)
+						+ "\n"); //$NON-NLS-1$
+				writer.flush();
+			}
+			//println "Lines1: "+lines
+			//lines.addAll(i,Collections.nCopies(packetSize,	(Line) null)); // delete created lines
+			for(int j = i ; j <= to2 && j < lines.size() ; j++)
+				lines.set(j, null);
+			//println "Lines2: "+lines
+		}
+
+		writer.flush();
+		writer.close();
+	}
+
+	@Override
+	public void clean() {
+		try {
+			if (queryResult != null)	{
+				queryResult.drop();
+			}
+		} catch (CqiClientException e) {
+			System.out.println(ConcordanceMessages.Concordance_4+e);
+		}
+		try {
+			this.writer.flush();
+			this.writer.close();
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			//org.txm.utils.logger.Log.printStackTrace(e);
+		}
+	}
+
+	/**
+	 * Set both left and right contexts size.
+	 *
+	 * @param size the new context size
+	 */
+	public void setLeftContextSize(int size) {
+		this.leftContextSize = size;
+		this.lines = new ArrayList<Line>(Collections.nCopies(nLines,
+				(Line) null));// we could make it less radically. But the data
+		// is cached anyway...
+	}
+
+	/**
+	 * Set both left and right contexts size.
+	 * 
+	 * @param size
+	 *            the new context size
+	 */
+	public void setRightContextSize(int size) {
+		this.rightContextSize = size;
+		this.lines = new ArrayList<Line>(Collections.nCopies(nLines,
+				(Line) null));// we could make it less radically. But the data
+		// is cached anyway...
+	}
+
+	/**
+	 * Set both left and right contexts size.
+	 * 
+	 * @param size
+	 *            the new context size
+	 */
+	public void setContextSize(int size) {
+		this.leftContextSize = size;
+		this.rightContextSize = size;
+		this.lines = new ArrayList<Line>(Collections.nCopies(nLines,
+				(Line) null));// we could make it less radically. But the data
+		// is cached anyway...
+	}
+
+	/**
+	 * Set left and right contexts size.
+	 *
+	 * @param leftsize the leftsize
+	 * @param rightsize the rightsize
+	 */
+	public void setContextSize(int leftsize, int rightsize) {
+		this.leftContextSize = leftsize;
+		this.rightContextSize = rightsize;
+		this.lines = new ArrayList<Line>(Collections.nCopies(nLines,
+				(Line) null));// we could make it less radically. But the data
+		// is cached anyway...
+	}
+
+	/**
+	 * Set the analysis property.
+	 * 
+	 * @param list the new analysis property
+	 */
+	public void setAnalysisProperty(List<Property> list) {
+		this.leftAnalysisProperties = list;
+		this.rightAnalysisProperties = list;
+		this.keywordAnalysisProperties = list;
+		this.lines = new ArrayList<Line>(Collections.nCopies(nLines,
+				(Line) null)); // empty lines
+	}
+
+	/**
+	 * Set the analysis property per column.
+	 * 
+	 * @param list the new analysis property
+	 */
+	public void setAnalysisProperty(List<Property> leftProps, List<Property> keywordProps, List<Property> rightProps) {
+		this.leftAnalysisProperties = leftProps;
+		this.rightAnalysisProperties = keywordProps;
+		this.keywordAnalysisProperties = rightProps;
+		this.lines = new ArrayList<Line>(Collections.nCopies(nLines, (Line) null)); // empty lines
+	}
+
+	/**
+	 * Set the analysis propertyof the left context.
+	 * 
+	 * @param selectedLeftSortProperty
+	 *            the new analysis property
+	 */
+	public void setLeftAnalysisProperties(List<Property> selectedLeftSortProperty) {
+		this.leftAnalysisProperties = selectedLeftSortProperty;
+		this.lines = new ArrayList<Line>(Collections.nCopies(nLines,
+				(Line) null)); // empty lines
+	}
+
+	/**
+	 * Set the analysis propertyof the left context.
+	 * 
+	 * @param selectedRightSortProperty
+	 *            the new analysis property
+	 */
+	public void setRightAnalysisProperties(List<Property> selectedRightSortProperty) {
+		this.rightAnalysisProperties = selectedRightSortProperty;
+		this.lines = new ArrayList<Line>(Collections.nCopies(nLines,
+				(Line) null)); // empty lines
+	}
+
+	/**
+	 * Set the analysis propertyof the left context.
+	 * 
+	 * @param selectedKeywordSortProperty
+	 *            the new analysis property
+	 */
+	public void setKeywordAnalysisProperties(List<Property> selectedKeywordSortProperty) {
+		this.keywordAnalysisProperties = selectedKeywordSortProperty;
+		this.lines = new ArrayList<Line>(Collections.nCopies(nLines,
+				(Line) null));// we could make it less radically.
+	}
+
+	/**
+	 * Set the same view properties for left context, right context and keyword.
+	 * 
+	 * @param viewProperties
+	 *            the new view properties
+	 */
+	public void setViewProperties(List<Property> viewProperties) {
+		this.viewProperties = viewProperties;
+		this.leftCViewProperties = viewProperties;
+		this.rightCViewProperties = viewProperties;
+		this.keywordViewProperties = viewProperties;
+		this.lines = new ArrayList<Line>(Collections.nCopies(nLines,
+				(Line) null));// we could make it less radically. But teh data
+		// is cached anyway...
+	}
+
+	/**
+	 * Set specif ic view properties for left context, right context and keyword.
+	 * if the List are null, the corresponding list will be reset
+	 * 
+	 * @param leftCViewProperties
+	 *            left context view properties
+	 * @param rightCViewProperties
+	 *            right context view properties
+	 * @param keywordViewProperties
+	 *            keyword view properties
+	 */
+	public void setViewProperties(List<Property> leftCViewProperties,
+			List<Property> rightCViewProperties,
+			List<Property> keywordViewProperties) {
+		// reset list or use the given ones
+		if (leftCViewProperties != null)
+			this.leftCViewProperties = leftCViewProperties;
+		else
+			this.leftCViewProperties = new ArrayList<Property>();
+
+		if (rightCViewProperties != null)
+			this.rightCViewProperties = rightCViewProperties;
+		else
+			this.rightCViewProperties = new ArrayList<Property>();
+
+		if (keywordViewProperties != null)
+			this.keywordViewProperties = keywordViewProperties;
+		else
+			this.keywordViewProperties = new ArrayList<Property>();
+
+		this.updateViewPropertiesList();
+		
+		this.lines = new ArrayList<Line>(Collections.nCopies(nLines, (Line) null));// we could make it less radically. But the data
+		// is cached anyway...
+	}
+
+	/**
+	 * Set the reference Pattern.
+	 * 
+	 * @param referencePattern
+	 *            the new reference Pattern
+	 */
+	public void setRefViewPattern(ReferencePattern referencePattern) {
+		this.refViewPattern = referencePattern;
+		this.lines = new ArrayList<Line>(Collections.nCopies(nLines,
+				(Line) null));// we could make it less radically. But the data
+		// is cached anyway...
+	}
+
+	/**
+	 * Set the reference Pattern.
+	 * 
+	 * @param referencePattern
+	 *            the new reference Pattern
+	 */
+	public void setRefAnalysePattern(ReferencePattern referencePattern) {
+		this.refAnalysePattern = referencePattern;
+		this.lines = new ArrayList<Line>(Collections.nCopies(nLines,
+				(Line) null));// we could make it less radically. But the data
+		// is cached anyway...
+	}
+
+	/**
+	 * Gets the corpus.
+	 *
+	 * @return the corpus
+	 */
+	public Corpus getCorpus() {
+		return (Corpus) this.parent;
+	}
+
+	/**
+	 * Gets the right context size.
+	 *
+	 * @return the rightContextSize
+	 */
+	public int getRightContextSize() {
+		return rightContextSize;
+	}
+
+	/**
+	 * Gets the left context size.
+	 *
+	 * @return the leftContextSize
+	 */
+	public int getLeftContextSize() {
+		return leftContextSize;
+	}
+
+	/**
+	 * Gets the view properties.
+	 *
+	 * @return the viewProperties
+	 */
+	public List<Property> getViewProperties() {
+		return viewProperties;
+	}
+
+	/**
+	 * Gets the left c view properties.
+	 *
+	 * @return the leftCViewProperties
+	 */
+	public List<Property> getLeftViewProperties() {
+		return leftCViewProperties;
+	}
+
+	/**
+	 * Gets the right c view properties.
+	 *
+	 * @return the rightCViewProperties
+	 */
+	public List<Property> getRightViewProperties() {
+		return rightCViewProperties;
+	}
+
+	/**
+	 * Gets the keyword view properties.
+	 *
+	 * @return the keywordViewProperties
+	 */
+	public List<Property> getKeywordViewProperties() {
+		return keywordViewProperties;
+	}
+
+	/**
+	 * Gets the left c analysis property.
+	 *
+	 * @return the analysisProperty
+	 */
+	public List<Property> getLeftAnalysisProperties() {
+		return leftAnalysisProperties;
+	}
+
+	/**
+	 * Gets the right c analysis property.
+	 *
+	 * @return the analysisProperty
+	 */
+	public List<Property> getRightAnalysisProperties() {
+		return rightAnalysisProperties;
+	}
+
+	/**
+	 * Gets the keyword analysis property.
+	 *
+	 * @return the analysisProperty
+	 */
+	public List<Property> getKeywordAnalysisProperties() {
+		return keywordAnalysisProperties;
+	}
+
+	/**
+	 * Gets the analysis property.
+	 *
+	 * @return the analysisProperty
+	 */
+	public List<Property> getAnalysisProperty() {
+		return keywordAnalysisProperties;
+	}
+
+	/**
+	 * Gets the reference pattern.
+	 *
+	 * @return the referencePattern
+	 */
+	public ReferencePattern getRefViewPattern() {
+		return refViewPattern;
+	}
+
+
+	public ReferencePattern getRefAnalysePattern() {
+		return refAnalysePattern;
+	}
+
+	/**
+	 * Gets the keywords id.
+	 *
+	 * @param text the text
+	 * @param from the from
+	 * @param to the to
+	 * @return the keywords id
+	 */
+	public List<String> getKeywordsId(String text, int from, int to) {
+		//System.out.println(Messages.Concordance_5+from+" "+to); //$NON-NLS-2$
+		HashSet<String> allids = new HashSet<String>();
+		for (int i = from; i < to && i < lines.size(); i++) {
+			if (i >= 0 && i < lines.size()) {
+				Line line = lines.get(i);
+				// System.out.println("line text "+line.getTextId());
+				if (line.getTextId().equals(text)) {
+					allids.addAll(line.getKeywordIds());
+				}
+			}
+		}
+		return new ArrayList<String>(allids);
+	}
+
+	/** The noconc. */
+	protected static int noconc = 1;
+
+	/** The prefix r. */
+	protected static String prefixR = "Concordances"; //$NON-NLS-1$
+
+	/**
+	 * As r matrix.
+	 *
+	 * @return the string
+	 * @throws RWorkspaceException the r workspace exception
+	 * @throws CqiServerError 
+	 * @throws IOException 
+	 */
+	public String asRMatrix() throws RWorkspaceException, IOException, CqiServerError {
+		symbol = prefixR+ noconc++;
+		String[] refs = new String[this.getNLines()];
+		String[] lefts = new String[this.getNLines()];
+		String[] keywords = new String[this.getNLines()];
+		String[] rights = new String[this.getNLines()];
+
+		int i = 0;
+		try {
+			for (Line line : this.getLines(0, this.getNLines())) {
+				refs[i] = line.getViewRef().toString();
+				lefts[i] = line.leftContextToString();
+				keywords[i] = line.keywordToString();
+				rights[i] = line.rightContextToString();
+				i++;
+			}
+		} catch (CqiClientException e) {
+			org.txm.utils.logger.Log.printStackTrace(e);
+			return ""; //$NON-NLS-1$
+		}
+
+		RWorkspace rw = RWorkspace.getRWorkspaceInstance();
+		rw.addVectorToWorkspace("concrefs", refs); //$NON-NLS-1$
+		rw.addVectorToWorkspace("conclefts", lefts); //$NON-NLS-1$
+		rw.addVectorToWorkspace("conckeywords", keywords); //$NON-NLS-1$
+		rw.addVectorToWorkspace("concrights", rights); //$NON-NLS-1$
+
+		rw.eval(symbol+ "<- matrix(data = c(concrefs, conclefts, conckeywords, concrights), nrow = "+this.getNLines()+", ncol = 4)"); //$NON-NLS-1$ //$NON-NLS-2$
+		rw.eval("colnames("+symbol+" ) <- c('refs', 'leftcontext', 'keyword', 'rightcontext')"); //$NON-NLS-1$ //$NON-NLS-2$
+		rw.eval(symbol+ "<- list(data="+symbol //$NON-NLS-1$
+				+ ", leftcontext="+this.leftContextSize //$NON-NLS-1$
+				+ ", rightcontext="+this.rightContextSize //$NON-NLS-1$
+				//+ ", query=\""+this.query.getQueryString()+"\""
+				+ ")"); //$NON-NLS-1$
+
+		return symbol;
+	}
+
+	/**
+	 * Gets the symbol.
+	 *
+	 * @return the symbol
+	 */
+	public String getSymbol() {
+		return symbol;
+	}
+
+	/** The properties to process. */
+	HashSet<String> propertiesToProcess;
+
+	private AnnotationType viewAnnotation;
+
+	private boolean overlapAnnotation;
+//
+//	/**
+//	 * Render.
+//	 *
+//	 * @param line the line
+//	 * @return the string
+//	 */
+//	public String render(Line line)
+//	{
+//		if(propertiesToProcess == null)
+//			propertiesToProcess = TxmRenderer.getPropertyToRender(this, "jsesh"); //$NON-NLS-1$
+//
+//		return line.toString();
+//	}
+	@Deprecated
+	public boolean toTxt(File file, String encoding) throws Exception {
+		// TODO Auto-generated method stub
+		return toTxt(file, encoding, "\t", ""); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+
+	@Override
+	public String[] getExportTXTExtensions() {
+		return new String[]{"*.csv"};
+	}
+
+
+
+	public void setCQLSeparator(String cql_limit) {
+		if (this.cql_limit != null && !this.cql_limit.equals(cql_limit)) { 
+			//the CQL limit changed !
+			CQLLimitStarts = null;
+		}
+		this.cql_limit = cql_limit;
+	}
+
+	public List<Line> getLines() throws CqiClientException, IOException, CqiServerError {
+		return getLines(0, this.getNLines());
+	}
+
+	public List<Match> getMatches() throws CqiClientException {
+		return queryResult.getMatches();
+	}
+
+	public void setViewAnnotation(AnnotationType type) {
+		viewAnnotation = type;
+		this.lines = new ArrayList<Line>(Collections.nCopies(nLines,
+				(Line) null)); // empty lines
+	}
+
+	public AnnotationType getViewAnnotation(AnnotationType type) {
+		return viewAnnotation;
+	}
+
+	public void setAnnotationOverlap(boolean overlap) {
+		overlapAnnotation = overlap;
+	}
+
+	public boolean getAnnotationOverlap() {
+		return overlapAnnotation;
+	}
+
+	public QueryResult getQueryResult() {
+		return queryResult;
+	}
+
+	/**
+	 * Update the QueryResult removing the match of the given line.
+	 * 
+	 * It uses the "delete" command but needs to find the match number of all the matches of the queryresult (may be long depending on the queryresult size)
+	 * 
+	 * @param line
+	 * @return
+	 * @throws CqiClientException
+	 * @throws IOException
+	 * @throws CqiServerError
+	 */
+	public boolean removeLine(Line line) throws CqiClientException, IOException, CqiServerError {
+
+		AbstractCqiClient CQI = CorpusManager.getCorpusManager().getCqiClient();
+		if (CQI instanceof MemCqiClient) {
+			MemCqiClient MCQI = (MemCqiClient)CQI;
+
+			Match m = line.getMatch();
+			Match m2;
+			List<Match> allMatches = queryResult.getMatches();
+			int to = allMatches.size();
+			for (int i = 0 ; i < to; i++) {
+				m2 = allMatches.get(i);
+				if (m2.getStart() == m.getStart() && m2.getEnd() == m.getEnd()) {
+					String query = "delete "+this.queryResult.getQualifiedCqpId()+" "+i+";";
+					MCQI.query(query);
+
+					this.lines.remove(line);
+					this.nLines = queryResult.getNMatch();
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Update the QueryResult removing the match of the given line.
+	 * 
+	 * It uses the "delete" command but needs to find the match number of all the matches of the queryresult (may be long depending on the queryresult size)
+	 * 
+	 * @param line
+	 * @return
+	 * @throws CqiClientException
+	 * @throws IOException
+	 * @throws CqiServerError
+	 */
+	public boolean removeLines(List<Line> linesToRemove) throws CqiClientException, IOException, CqiServerError {
+
+		//reorder lines to start with the last line
+		Collections.sort(linesToRemove, new Comparator<Line>() {
+			@Override
+			public int compare(Line o1, Line o2) {
+				return o2.getKeywordPosition() - o1.getKeywordPosition();
+			}
+		});
+
+		AbstractCqiClient CQI = CorpusManager.getCorpusManager().getCqiClient();
+		List<Match> allMatches = queryResult.getMatches();
+		int to = allMatches.size();
+		int c = 0;
+		if (CQI instanceof MemCqiClient) {
+			MemCqiClient MCQI = (MemCqiClient)CQI;
+			for (Line line : linesToRemove) {
+				Match m = line.getMatch();
+				Match m2;
+
+				for (int i = 0 ; i < to; i++) {
+					m2 = allMatches.get(i);
+					if (m2.getStart() == m.getStart() && m2.getEnd() == m.getEnd()) {
+						String query = "delete "+this.queryResult.getQualifiedCqpId()+" "+i+";";
+						MCQI.query(query);
+						this.lines.remove(line);
+						c++;
+					}
+				}
+			}
+
+			this.nLines = queryResult.getNMatch();
+			return c > 0;
+		}
+		return false;
+	}
+
+
+	/**
+	 * Gets the line index linked to the global token position in corpus according to the current concordance sorting.
+	 * @param globalPosition
+	 * @return
+	 */
+	public int indexOf(int globalPosition)	{
+		int index = -1;
+
+		// FIXME: works but may be optimized (e.g. get range by 50 token until the token is found instead of getting all the lines)
+		try {
+			List<Line> allLines = this.getLines(0, this.nLines);
+
+			for(int i = 0; i < allLines.size(); i++) {
+				Line line = allLines.get(i);
+				if(line != null && line.getMatch().getStart() == globalPosition)	{
+					index = i;
+					break;
+				}
+			}
+		}
+		catch(CqiClientException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		catch(IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		catch(CqiServerError e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+		// FIXME: tests for optimization by range
+		//		try {
+		//			List<Line> lines;
+		//			int rangeLength = 20;
+		//			int rangeMax = 0; 
+		//			for(int i = 0; i < this.nLines; i += rangeLength) {
+		//				rangeMax += rangeLength;
+		//				lines = this.getLines(i, rangeMax);
+		//				System.out.println("Concordance.indexOf(): getLines " + i + " / " + rangeMax);
+		//
+		//				for(int j = 0; j < lines.size(); j++) {
+		//					Line line = lines.get(j);
+		//					if(line != null && line.getMatch().getStart() == globalPosition)	{
+		//						index = i + j;
+		//						break;
+		//					}
+		//				}
+		//				if(index != -1)	{
+		//					break;
+		//				}
+		//			}
+		//		}
+		//		catch(CqiClientException e) {
+		//			// TODO Auto-generated catch block
+		//			e.printStackTrace();
+		//		}
+		//		catch(IOException e) {
+		//			// TODO Auto-generated catch block
+		//			e.printStackTrace();
+		//		}
+		//		catch(CqiServerError e) {
+		//			// TODO Auto-generated catch block
+		//			e.printStackTrace();
+		//		}
+
+
+		// FIXME: tests for optimization
+		// Problem here is that we need the sorted index of
+		//		try {
+		//			List<Match> matches = queryResult.getMatches(0, this.nLines - 1);
+		//			Collections.sort(matches, );
+		//			for(int i = 0; i < matches.size(); i++) {
+		//				if(matches.get(i).getStart() == globalPosition)	{
+		//					index = i;
+		//					break;
+		//				}
+		//			}
+		//		}
+		//		catch(CqiClientException e) {
+		//			// TODO Auto-generated catch block
+		//			e.printStackTrace();
+		//		}
+
+
+
+		return index;
+	}
+
+	@Override
+	public String getName() {
+		return ConcordanceMessages.Concordance_18 + this.getCorpus().getName()
+				+ ": " //$NON-NLS-1$
+				+ queryResult.getQuery().getQueryString();
+	}
+	
+	@Override
+	public String getSimpleName() {
+		// TODO Auto-generated method stub
+		return this.getName();
+	}
+
+	@Override
+	public String getDetails() {
+		// TODO Auto-generated method stub
+		return this.getName();
+	}
+
+}

Property changes on: tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/Concordance.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/build.properties
===================================================================
--- tmp/org.txm.concordance.core/build.properties	(revision 0)
+++ tmp/org.txm.concordance.core/build.properties	(revision 367)
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml

Property changes on: tmp/org.txm.concordance.core/build.properties
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/plugin.xml
===================================================================
--- tmp/org.txm.concordance.core/plugin.xml	(revision 0)
+++ tmp/org.txm.concordance.core/plugin.xml	(revision 367)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.core.runtime.preferences">
+      <initializer
+            class="org.txm.concordance.core.preferences.ConcordancePreferences">
+      </initializer>
+   </extension>
+
+</plugin>

Property changes on: tmp/org.txm.concordance.core/plugin.xml
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- tmp/org.txm.concordance.core/.settings/org.eclipse.jdt.core.prefs	(revision 0)
+++ tmp/org.txm.concordance.core/.settings/org.eclipse.jdt.core.prefs	(revision 367)
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6

Property changes on: tmp/org.txm.concordance.core/.settings/org.eclipse.jdt.core.prefs
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/.classpath
===================================================================
--- tmp/org.txm.concordance.core/.classpath	(revision 0)
+++ tmp/org.txm.concordance.core/.classpath	(revision 367)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

Property changes on: tmp/org.txm.concordance.core/.classpath
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/META-INF/MANIFEST.MF
===================================================================
--- tmp/org.txm.concordance.core/META-INF/MANIFEST.MF	(revision 0)
+++ tmp/org.txm.concordance.core/META-INF/MANIFEST.MF	(revision 367)
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Concordances Core
+Bundle-SymbolicName: org.txm.concordance.core;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Require-Bundle: org.txm.core,
+ org.txm.annotation.core;bundle-version="1.0.0",
+ org.eclipse.core.runtime;bundle-version="3.10.0"
+Export-Package: org.txm.concordance.core.functions,
+ org.txm.concordance.core.functions.comparators,
+ org.txm.concordance.core.messages,
+ org.txm.concordance.core.preferences
+Bundle-Vendor: Textometry.org

Property changes on: tmp/org.txm.concordance.core/META-INF/MANIFEST.MF
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.concordance.core/.project
===================================================================
--- tmp/org.txm.concordance.core/.project	(revision 0)
+++ tmp/org.txm.concordance.core/.project	(revision 367)
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.txm.concordance.core</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Property changes on: tmp/org.txm.concordance.core/.project
___________________________________________________________________
Added: svn:mime-type
   + text/plain

