Index: tmp/org.txm.annotation.kr.core/src/org/txm/annotation/kr/core/conversion/XMLTXMFileRuledConversion.java
===================================================================
--- tmp/org.txm.annotation.kr.core/src/org/txm/annotation/kr/core/conversion/XMLTXMFileRuledConversion.java	(revision 3054)
+++ tmp/org.txm.annotation.kr.core/src/org/txm/annotation/kr/core/conversion/XMLTXMFileRuledConversion.java	(revision 3055)
@@ -7,13 +7,20 @@
 import java.util.regex.Pattern;
 
 import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
 
 import org.txm.importer.StaxIdentityParser;
 
 public class XMLTXMFileRuledConversion extends StaxIdentityParser {
 	
-	protected LinkedHashMap<Pattern, String> rules = new LinkedHashMap<Pattern, String>();
+	public boolean debug = false;
 	
+	protected LinkedHashMap<Pattern, String> rules = new LinkedHashMap<>();
+	
+	protected String elementName = null;
+	
+	boolean fixingElement = false; // true when the current element needs to be fixed
+	
 	protected String oldType;
 	
 	protected String newType;
@@ -24,9 +31,20 @@
 	
 	public static final String ABANDON = "abandon";
 	
-	HashSet<String> noMatchValues = new HashSet<String>();
+	HashSet<String> noMatchValues = new HashSet<>();
 	
-	public XMLTXMFileRuledConversion(File infile, LinkedHashMap<Pattern, String> rules, String oldType, String newType, String mode) throws IOException, XMLStreamException {
+	/**
+	 * 
+	 * @param infile the file to read
+	 * @param rules the conversion rules
+	 * @param elementPath if null, the conversion happens
+	 * @param oldType word type or element attribute to read
+	 * @param newType word type or element attribute to write
+	 * @param mode XMLTXMFileRuledConversion.DELETE or XMLTXMFileRuledConversion.COPY or XMLTXMFileRuledConversion.ABANDON
+	 * @throws IOException
+	 * @throws XMLStreamException
+	 */
+	public XMLTXMFileRuledConversion(File infile, LinkedHashMap<Pattern, String> rules, String elementPath, String oldType, String newType, String mode) throws IOException, XMLStreamException {
 		super(infile);
 		this.rules = rules;
 		this.oldType = oldType;
@@ -34,15 +52,21 @@
 		
 		this.mode = mode;
 		
-		if (!this.newType.startsWith("#")) this.newType = "#" + this.newType;
-		if (!this.oldType.startsWith("#")) this.oldType = "#" + this.oldType;
+		if (elementPath != null && elementPath.length() > 0) {
+			this.elementName = elementPath;
+		}
+		
+		if (elementPath == null) { // where fixing txm:words
+			if (!this.newType.startsWith("#")) this.newType = "#" + this.newType;
+			if (!this.oldType.startsWith("#")) this.oldType = "#" + this.oldType;
+		}
 	}
 	
 	boolean inW = false, inAna = false, inForm;
 	
-	LinkedHashMap<String, String> anaValues = new LinkedHashMap<String, String>();
+	LinkedHashMap<String, String> anaValues = new LinkedHashMap<>();
 	
-	LinkedHashMap<String, String> anaResps = new LinkedHashMap<String, String>();
+	LinkedHashMap<String, String> anaResps = new LinkedHashMap<>();
 	
 	String typeName = null;
 	
@@ -52,116 +76,223 @@
 	
 	private Object mode;
 	
+	public static class Converter {
+		
+		public Converter() {
+			
+		}
+		
+		public String getValue(XMLStreamReader parser, String localname, String attribute, String value) {
+			return value;
+		}
+	}
+	
+	private Converter converter = null;
+	
 	@Override
+	protected void writeAttributes() throws XMLStreamException {
+		if (fixingElement) {
+			String newValue = null;
+			for (int i = 0; i < parser.getAttributeCount(); i++) {
+				String att = parser.getAttributeLocalName(i);
+				String value = parser.getAttributeValue(i);
+				if (oldType != null && oldType.equals(att)) {
+					if (converter != null) {
+						if (debug) System.out.println("CALL CONVERTER with attribute $att");
+						newValue = converter.getValue(parser, localname, att, value);
+					}
+					else {
+						newValue = getValueIfMatch(value);
+					}
+				}
+				if (!newType.equals(att)) { // don't write the newType, it will be done at the end
+					writeAttribute(parser.getAttributePrefix(i), att, value);
+				}
+			}
+			
+			if (oldType == null && converter != null) {
+				if (debug) System.out.println("CALL CONVERTER with no attribute set");
+				newValue = converter.getValue(parser, localname, null, null);
+			}
+			
+			if (newValue != null) {
+				if (debug) System.out.println("WRITE NEWTYPE: " + newType + "=" + newValue);
+				writeAttribute(null, newType, newValue);
+			}
+		}
+		else {
+			super.writeAttributes();
+		}
+	}
+	
+	@Override
 	public void processStartElement() throws XMLStreamException, IOException {
-		if (!inW) super.processStartElement(); // don't write W content
 		
-		if (localname.equals("w")) {
-			inW = true;
-			anaValues.clear();
-			anaResps.clear();
+		
+		if (elementName != null) {
+			if (this.localname.equals(elementName)) {
+				fixingElement = true;
+			}
 			
-			// initialize the new type to a empty value in case there is transformation rule
-			anaValues.put(newType, "");
-			anaResps.put(newType, "#txm_recode");
+			super.processStartElement();
+			fixingElement = false;
 		}
-		else if (localname.equals("ana")) {
-			inAna = true;
-			typeName = parser.getAttributeValue(null, "type");
-			respName = parser.getAttributeValue(null, "resp");
-			anaResps.put(typeName, respName);
-			// if (typeName != null) typeName = typeName.substring(1); // remove #
-			typeValue = "";
+		else {
+			
+			if (!inW) super.processStartElement(); // don't write W content
+			
+			if (localname.equals("w")) {
+				inW = true;
+				anaValues.clear();
+				anaResps.clear();
+				
+				// initialize the new type to a empty value in case there is transformation rule
+				anaValues.put(newType, "");
+				anaResps.put(newType, "#txm_recode");
+			}
+			else if (localname.equals("ana")) {
+				inAna = true;
+				typeName = parser.getAttributeValue(null, "type");
+				respName = parser.getAttributeValue(null, "resp");
+				anaResps.put(typeName, respName);
+				// if (typeName != null) typeName = typeName.substring(1); // remove #
+				typeValue = "";
+			}
+			else if (localname.equals("form")) {
+				inForm = true;
+				formValue = "";
+			}
 		}
-		else if (localname.equals("form")) {
-			inForm = true;
-			formValue = "";
-		}
 	}
 	
 	@Override
 	public void processCharacters() throws XMLStreamException {
-		if (inW && inAna) typeValue += parser.getText();
-		else if (inW && inForm) formValue += parser.getText();
-		else super.processCharacters();
+		if (elementName != null) {
+			super.processCharacters();
+		}
+		else {
+			if (inW && inAna) typeValue += parser.getText();
+			else if (inW && inForm) formValue += parser.getText();
+			else super.processCharacters();
+		}
 	}
 	
 	@Override
 	public void processEndElement() throws XMLStreamException {
-		if (localname.equals("w")) {
-			inW = false;
+		
+		if (elementName != null) {
+			super.processEndElement();
+		}
+		else {
 			
-			// write W content
-			try {
-				// get the value to test
-				String value = null;
-				if (oldType.equals("word")) {
-					value = formValue;
-				}
-				else {
-					value = anaValues.get(oldType);
-				}
+			if (localname.equals("w")) {
+				inW = false;
 				
-				if (newType.equals("word")) { // update form property
-					updateFormValueIfMatch(value);
-				}
-				else { // update another word property
-					if (value != null) {
-						updateAnaValuesIfMatch(value);
+				// write W content
+				try {
+					// get the value to test
+					String value = null;
+					if (oldType.equals("word")) {
+						value = formValue;
 					}
-				}
-				
-				// write the word element
-				writer.writeStartElement("txm:form");
-				writer.writeCharacters(formValue);
-				writer.writeEndElement();
-				
-				for (String k : anaValues.keySet()) {
-					String resp = anaResps.get(k);
-					if (resp == null) resp = "#txm_recode";
+					else {
+						value = anaValues.get(oldType);
+					}
 					
-					writer.writeStartElement("txm:ana");
-					writer.writeAttribute("resp", resp);
-					writer.writeAttribute("type", k);
-					writer.writeCharacters(anaValues.get(k));
+					if (newType.equals("word")) { // update form property
+						updateFormValueIfMatch(value);
+					}
+					else { // update a ana property
+						if (value != null) {
+							updateAnaValuesIfMatch(value);
+						}
+					}
+					
+					// write the word element
+					writer.writeStartElement("txm:form");
+					writer.writeCharacters(formValue);
 					writer.writeEndElement();
+					
+					for (String k : anaValues.keySet()) {
+						String resp = anaResps.get(k);
+						if (resp == null) resp = "#txm_recode";
+						
+						writer.writeStartElement("txm:ana");
+						writer.writeAttribute("resp", resp);
+						writer.writeAttribute("type", k);
+						writer.writeCharacters(anaValues.get(k));
+						writer.writeEndElement();
+					}
 				}
+				catch (XMLStreamException e) {
+					e.printStackTrace();
+				}
 			}
-			catch (XMLStreamException e) {
-				e.printStackTrace();
+			else if (localname.equals("ana")) {
+				anaValues.put(typeName, typeValue);
+				inAna = false;
 			}
+			else if (localname.equals("form")) {
+				inForm = false;
+			}
+			
+			if (!inW) super.processEndElement(); // don't write W content
 		}
-		else if (localname.equals("ana")) {
-			anaValues.put(typeName, typeValue);
-			inAna = false;
+	}
+	
+	protected String getValueIfMatch(String value) {
+		for (Pattern rule : rules.keySet()) {
+			if (rule.matcher(value).matches()) {
+				return rules.get(rule); // ok stop
+			}
 		}
-		else if (localname.equals("form")) {
-			inForm = false;
-		}
 		
-		if (!inW) super.processEndElement(); // don't write W content
+		return value;
 	}
 	
 	protected void updateFormValueIfMatch(String value) {
-		for (Pattern rule : rules.keySet()) {
-			if (rule.matcher(value).matches()) {
-				formValue = rules.get(rule);
+		
+		if (converter != null) {
+			String v = converter.getValue(parser, localname, null, value);
+			if (v != null) {
+				formValue = v;
 				return; // ok stop
 			}
 		}
+		else {
+			for (Pattern rule : rules.keySet()) {
+				if (rule.matcher(value).matches()) {
+					formValue = rules.get(rule);
+					return; // ok stop
+				}
+			}
+		}
 		
+		
 		noMatchValues.add(value);
 	}
 	
 	protected void updateAnaValuesIfMatch(String value) {
-		for (Pattern rule : rules.keySet()) {
-			if (rule.matcher(value).matches()) {
-				value = rules.get(rule);
-				anaValues.put(newType, value); // do a replace if newType == oldType :-)
+		
+		if (converter != null) {
+			String v = converter.getValue(parser, localname, null, value);
+			if (v != null) {
+				anaValues.put(newType, v); // do a replace if newType == oldType :-)
 				anaResps.put(newType, "#txm_recode");
-				return;
+				return; // ok stop
 			}
 		}
+		else {
+			
+			for (Pattern rule : rules.keySet()) {
+				if (rule.matcher(value).matches()) {
+					value = rules.get(rule);
+					anaValues.put(newType, value); // do a replace if newType == oldType :-)
+					anaResps.put(newType, "#txm_recode");
+					return;
+				}
+			}
+		}
 		if (DELETE.equals(mode)) anaValues.put(newType, ""); // do a replace if newType == oldType :-)
 		else if (ABANDON.equals(mode)) anaValues.put(newType, "ERROR(" + value + ")"); // do a replace if newType == oldType :-)
 		
@@ -174,16 +305,23 @@
 	
 	public static void main(String args[]) {
 		try {
-			File xmlFile = new File("/home/mdecorde/TXM/corpora/XTZTEXTUALPLANS/txm/XTZTEXTUALPLANS/test.xml");
-			File tmpFile = new File("/home/mdecorde/TXM/corpora/XTZTEXTUALPLANS/txm/XTZTEXTUALPLANS/test-o.xml");
-			String oldType = "type";
-			String newType = "type";
-			LinkedHashMap<Pattern, String> rules = new LinkedHashMap<Pattern, String>();
-			rules.put(Pattern.compile("w"), "WORD");
+			File xmlFile = new File("/home/mdecorde/xml/recode/test.xml");
+			File tmpFile = new File("/home/mdecorde/xml/recode/test-o.xml");
+			String oldType = "myattr";
+			String newType = "myattr";
+			LinkedHashMap<Pattern, String> rules = new LinkedHashMap<>();
+			rules.put(Pattern.compile(".+"), "NEWW");
 			rules.put(Pattern.compile("x.+"), "XWORD");
 			rules.put(Pattern.compile("y"), "YWORD");
 			rules.put(Pattern.compile("y.*"), "YMULTIWORD");
-			XMLTXMFileRuledConversion converter = new XMLTXMFileRuledConversion(xmlFile, rules, oldType, newType, ABANDON);
+			XMLTXMFileRuledConversion converter = new XMLTXMFileRuledConversion(xmlFile, rules, "w", oldType, newType, ABANDON);
+			converter.converter = new Converter() {
+				
+				@Override
+				public String getValue(XMLStreamReader parser, String localname, String attribute, String value) {
+					return "NEW" + value;
+				}
+			};
 			System.out.println(converter.process(tmpFile));
 		}
 		catch (Exception e) {
Index: tmp/org.txm.annotation.kr.core/src/org/txm/annotation/kr/core/conversion/CorpusRuledConvertion.java
===================================================================
--- tmp/org.txm.annotation.kr.core/src/org/txm/annotation/kr/core/conversion/CorpusRuledConvertion.java	(revision 3054)
+++ tmp/org.txm.annotation.kr.core/src/org/txm/annotation/kr/core/conversion/CorpusRuledConvertion.java	(revision 3055)
@@ -17,7 +17,7 @@
 
 public class CorpusRuledConvertion {
 	
-	LinkedHashMap<Pattern, String> rules = new LinkedHashMap<Pattern, String>();
+	LinkedHashMap<Pattern, String> rules = new LinkedHashMap<>();
 	
 	private String oldType;
 	
@@ -75,7 +75,7 @@
 			if (!xmlFile.getName().endsWith(".xml")) continue;
 			
 			File tmpFile = new File(xmlFile.getParentFile(), "tmp_" + xmlFile.getName());
-			XMLTXMFileRuledConversion converter = new XMLTXMFileRuledConversion(xmlFile, rules, oldType, newType, XMLTXMFileRuledConversion.ABANDON);
+			XMLTXMFileRuledConversion converter = new XMLTXMFileRuledConversion(xmlFile, rules, null, oldType, newType, XMLTXMFileRuledConversion.ABANDON);
 			if (converter.process(tmpFile)) {
 				xmlFile.delete();
 				// try {
Index: tmp/org.txm.annotation.kr.core/META-INF/MANIFEST.MF
===================================================================
--- tmp/org.txm.annotation.kr.core/META-INF/MANIFEST.MF	(revision 3054)
+++ tmp/org.txm.annotation.kr.core/META-INF/MANIFEST.MF	(revision 3055)
@@ -1,12 +1,12 @@
 Manifest-Version: 1.0
 Automatic-Module-Name: org.txm.annotation.kr.core
 Bundle-SymbolicName: org.txm.annotation.kr.core;singleton:=true
-Require-Bundle: org.txm.searchengine.cqp.core;visibility:=reexport,jav
- ax.persistence;bundle-version="2.1.0";visibility:=reexport,org.eclips
- e.persistence.jpa;bundle-version="2.6.0";visibility:=reexport,org.ecl
- ipse.persistence.jpa.jpql;bundle-version="2.6.0";visibility:=reexport
- ,org.txm.annotation.core;visibility:=reexport,org.eclipse.persistence
- .asm;bundle-version="6.0.0"
+Require-Bundle: org.txm.searchengine.cqp.core;visibility:=reexport,
+ javax.persistence;bundle-version="2.1.0";visibility:=reexport,
+ org.eclipse.persistence.jpa;bundle-version="2.6.0";visibility:=reexport,
+ org.eclipse.persistence.jpa.jpql;bundle-version="2.6.0";visibility:=reexport,
+ org.txm.annotation.core;visibility:=reexport,
+ org.eclipse.persistence.asm;bundle-version="6.0.0";visibility:=reexport
 Meta-Persistence: META-INF/persistence.xml
 Bundle-ActivationPolicy: lazy
 Bundle-ManifestVersion: 2
Index: tmp/org.txm.annotation.core/src/org/txm/annotation/core/AnnotationEngine.java
===================================================================
--- tmp/org.txm.annotation.core/src/org/txm/annotation/core/AnnotationEngine.java	(revision 3054)
+++ tmp/org.txm.annotation.core/src/org/txm/annotation/core/AnnotationEngine.java	(revision 3055)
@@ -6,6 +6,8 @@
 
 import org.txm.core.engines.Engine;
 import org.txm.objects.CorpusBuild;
+import org.txm.tokenizer.SimpleStringTokenizer;
+import org.txm.tokenizer.StringTokenizer;
 import org.txm.utils.ConsoleProgressBar;
 import org.txm.utils.DeleteDir;
 
@@ -29,6 +31,15 @@
 	public abstract boolean hasAnnotationsToSave(CorpusBuild corpus);
 	
 	/**
+	 * 
+	 * @return a StringTokenizer, override this method if the engine needs a speciq tokenization
+	 * @throws Exception
+	 */
+	public StringTokenizer getStringTokenizer(String lang) throws Exception {
+		return new SimpleStringTokenizer(lang);
+	}
+	
+	/**
 	 * Automatically annotate a XML-TXM file
 	 * 
 	 * @param xmlFile to annotate
@@ -72,6 +83,7 @@
 		
 		for (File xmlFile : files) {
 			ret = processFile(xmlFile, binaryCorpusDirectory, parameters) && ret;
+			
 			cpb.tick();
 		}
 		cpb.done();
Index: tmp/org.txm.annotation.core/META-INF/MANIFEST.MF
===================================================================
--- tmp/org.txm.annotation.core/META-INF/MANIFEST.MF	(revision 3054)
+++ tmp/org.txm.annotation.core/META-INF/MANIFEST.MF	(revision 3055)
@@ -1,8 +1,8 @@
 Manifest-Version: 1.0
 Automatic-Module-Name: org.txm.annotation.core
 Bundle-SymbolicName: org.txm.annotation.core;singleton:=true
-Require-Bundle: org.txm.core;bundle-version="0.7.0";visibility:=reexpo
- rt
+Require-Bundle: org.txm.core;bundle-version="0.7.0";visibility:=reexport,
+ org.txm.tokenizer.core
 Bundle-ActivationPolicy: lazy
 Bundle-ManifestVersion: 2
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Index: tmp/org.txm.concordance.rcp/src/org/txm/concordance/rcp/editors/ConcordanceEditor.java
===================================================================
--- tmp/org.txm.concordance.rcp/src/org/txm/concordance/rcp/editors/ConcordanceEditor.java	(revision 3054)
+++ tmp/org.txm.concordance.rcp/src/org/txm/concordance/rcp/editors/ConcordanceEditor.java	(revision 3055)
@@ -1902,8 +1902,12 @@
 	 * Refresh reference column title.
 	 */
 	public void refreshReferenceColumnTitle() {
-		
-		referenceColumn.setText(concordance.getRefViewPattern().getTitle());
+		if (concordance.getRefViewPattern() != null) {
+			referenceColumn.setText(concordance.getRefViewPattern().getTitle());
+		}
+		else {
+			referenceColumn.setText("References");
+		}
 	}
 	
 	/**
Index: tmp/org.txm.core/src/java/org/txm/xml/DoNothingHook.java
===================================================================
--- tmp/org.txm.core/src/java/org/txm/xml/DoNothingHook.java	(revision 0)
+++ tmp/org.txm.core/src/java/org/txm/xml/DoNothingHook.java	(revision 3055)
@@ -0,0 +1,44 @@
+package org.txm.xml;
+
+import java.io.IOException;
+
+import javax.xml.stream.XMLStreamException;
+
+public class DoNothingHook<T extends XMLParser> extends SimpleHook<T> {
+	
+	public DoNothingHook(String name, HookActivator<T> activator, T parentParser) throws IOException, XMLStreamException {
+		super(name, activator, parentParser);
+		// TODO Auto-generated constructor stub
+	}
+	
+	@Override
+	public boolean _activate() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+	
+	@Override
+	public boolean deactivate() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+	
+	@Override
+	protected void processStartElement() throws XMLStreamException, IOException {
+		// TODO Auto-generated method stub
+		
+	}
+	
+	@Override
+	protected void processCharacters() throws XMLStreamException {
+		// TODO Auto-generated method stub
+		
+	}
+	
+	@Override
+	protected void processEndElement() throws XMLStreamException {
+		// TODO Auto-generated method stub
+		
+	}
+	
+}

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

Index: tmp/org.txm.core/src/java/org/txm/xml/SimpleHook.java
===================================================================
--- tmp/org.txm.core/src/java/org/txm/xml/SimpleHook.java	(revision 3054)
+++ tmp/org.txm.core/src/java/org/txm/xml/SimpleHook.java	(revision 3055)
@@ -12,7 +12,7 @@
  */
 public abstract class SimpleHook<T extends XMLParser> extends Hook<T> {
 	
-	public SimpleHook(String name, HookActivator activator, T parentParser) throws IOException, XMLStreamException {
+	public SimpleHook(String name, HookActivator<T> activator, T parentParser) throws IOException, XMLStreamException {
 		super(name, activator, parentParser);
 	}
 	
Index: tmp/org.txm.core/src/java/org/txm/xml/XMLParser.java
===================================================================
--- tmp/org.txm.core/src/java/org/txm/xml/XMLParser.java	(revision 3054)
+++ tmp/org.txm.core/src/java/org/txm/xml/XMLParser.java	(revision 3055)
@@ -53,9 +53,9 @@
 	
 	int processingXInclude = 0;
 	
-	LinkedHashMap<String, Hook> hooks = new LinkedHashMap<>();
+	LinkedHashMap<String, Hook<?>> hooks = new LinkedHashMap<>();
 	
-	private Hook activeHook = null;
+	private Hook<?> activeHook = null;
 	
 	public XMLParser(File infile) throws IOException, XMLStreamException {
 		this(infile.toURI().toURL());
@@ -409,11 +409,11 @@
 	 * 
 	 * @return the actual hooks hash
 	 */
-	public LinkedHashMap<String, Hook> getHooks() {
+	public LinkedHashMap<String, Hook<? extends XMLParser>> getHooks() {
 		return hooks;
 	}
 	
-	public void addHook(String name, Hook hook) {
+	public void addHook(String name, Hook<? extends XMLParser> hook) {
 		hooks.put(name, hook);
 	}
 }
Index: tmp/org.txm.core/src/java/org/txm/xml/XMLProcessor.java
===================================================================
--- tmp/org.txm.core/src/java/org/txm/xml/XMLProcessor.java	(revision 3054)
+++ tmp/org.txm.core/src/java/org/txm/xml/XMLProcessor.java	(revision 3055)
@@ -439,12 +439,12 @@
 	 * @return the actual hooks hash
 	 */
 	@Override
-	public LinkedHashMap<String, Hook> getHooks() {
+	public LinkedHashMap<String, Hook<?>> getHooks() {
 		return hooks;
 	}
 	
 	@Override
-	public void addHook(String name, Hook hook) {
+	public void addHook(String name, Hook<?> hook) {
 		hooks.put(name, hook);
 	}
 }
Index: tmp/org.txm.core/src/java/org/txm/Toolbox.java
===================================================================
--- tmp/org.txm.core/src/java/org/txm/Toolbox.java	(revision 3054)
+++ tmp/org.txm.core/src/java/org/txm/Toolbox.java	(revision 3055)
@@ -129,11 +129,10 @@
 				Log.fine("Registering " + enginesManager.getEnginesDescription() + " engines manager...");
 				addEngineManager(enginesManager);
 				if (enginesManager.fetchEngines()) {
-					// System.out.println("add engine: "+engine);
-					
+					Log.fine(NLS.bind("{0} {1} engine(s) loaded.", enginesManager.size(), EngineType.TAL));
 				}
 				else {
-					Log.warning("No engine found for " + enginesManager + ", installation failed.");
+					Log.fine("No engine found for " + enginesManager + ", installation failed.");
 				}
 			}
 			catch (Throwable e) {
Index: tmp/org.txm.core/META-INF/MANIFEST.MF
===================================================================
--- tmp/org.txm.core/META-INF/MANIFEST.MF	(revision 3054)
+++ tmp/org.txm.core/META-INF/MANIFEST.MF	(revision 3055)
@@ -461,7 +461,8 @@
  org.eclipse.core.resources;visibility:=reexport,
  org.txm.libs.office;bundle-version="0.0.0";visibility:=reexport,
  org.txm.libs.msoffice;bundle-version="0.0.0";visibility:=reexport,
- org.txm.libs.hsqldb;bundle-version="1.0.0";visibility:=reexport
+ org.txm.libs.hsqldb;bundle-version="1.0.0";visibility:=reexport,
+ org.txm.tokenizer.core;bundle-version="1.0.0";visibility:=reexport
 Bundle-ActivationPolicy: lazy
 Bundle-ManifestVersion: 2
 Bundle-Activator: org.txm.core.Activator
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 3054)
+++ tmp/org.txm.concordance.core/src/org/txm/concordance/core/functions/Concordance.java	(revision 3055)
@@ -951,7 +951,12 @@
 	
 	@Override
 	public String getComputingStartMessage() {
-		return TXMCoreMessages.bind(ConcordanceCoreMessages.concordanceOfP0InTheP1Corpus, this.pQuery.asString(), this.getCorpus().getName());
+		if (this.pQuery == null) {
+			return TXMCoreMessages.bind(ConcordanceCoreMessages.concordanceOfP0InTheP1Corpus, "<none>", this.getCorpus());
+		}
+		else {
+			return TXMCoreMessages.bind(ConcordanceCoreMessages.concordanceOfP0InTheP1Corpus, this.pQuery.asString(), this.getCorpus());
+		}
 	}
 	
 	@Override
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/xtz/XTZImporter.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/xtz/XTZImporter.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/xtz/XTZImporter.groovy	(revision 3055)
@@ -26,6 +26,7 @@
 import org.txm.utils.ConsoleProgressBar
 import org.txm.utils.io.*
 import org.txm.importer.xtz.*
+import org.txm.core.engines.*
 
 class XTZImporter extends Importer {
 	
@@ -381,6 +382,14 @@
 				File infile = f;
 				File outfile = new File(module.getBinaryDirectory(),"tokenized/"+f.getName());
 				SimpleTokenizerXml tokenizer = new SimpleTokenizerXml(infile, outfile, lang)
+				if (module.getProject().getAnnotate()) { // an annotation will be done, does the annotation engine needs another tokenizer ?
+					String engineName = module.getProject().getImportParameters().node("annotate").get("engine", "TreeTagger")
+					def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine(engineName)
+					def stringTokenizer = engine.getStringTokenizer(lang)
+					if (stringTokenizer != null) {
+						tokenizer.setStringTokenizer(stringTokenizer)
+					}
+				}
 				tokenizer.setRetokenize(retokenize)
 				if (outSideTextTagsRegex != null && outSideTextTagsRegex.trim().length() > 0) {
 					tokenizer.setOutSideTextTags(outSideTextTagsRegex)
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/xtz/TTAnnotater.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/xtz/TTAnnotater.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/xtz/TTAnnotater.groovy	(revision 3055)
@@ -28,7 +28,8 @@
 		String corpusname = module.getProject().getName();
 		String lang = module.getProject().getLang();
 
-		def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine("TreeTagger")
+		String engineName = module.getProject().getImportParameters().node("annotate").get("engine", "TreeTagger")
+		def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine(engineName)
 		if (module.isMultiThread()) {
 			def hash = [:]
 			for (File txmFile : inputDirectory.listFiles()) {
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/hyperprince/hyperprinceLoader.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/hyperprince/hyperprinceLoader.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/hyperprince/hyperprinceLoader.groovy	(revision 3055)
@@ -80,7 +80,8 @@
 //ANNOTATE
 println "-- ANNOTATE - Running NLP tools"
 if (annotate) {
-	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine("TreeTagger")
+	String engineName = project.getImportParameters().node("annotate").get("engine", "TreeTagger")
+	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine(engineName)
 	if (engine.processDirectory(txmDir, binDir, ["lang":model])) {
 		annotationSuccess = true;
 	}
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/frantext/frantextLoader.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/frantext/frantextLoader.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/frantext/frantextLoader.groovy	(revision 3055)
@@ -156,7 +156,8 @@
 boolean annotate_status = true;
 if (annotate) {
 	println "-- ANNOTATE - Running NLP tools - $model model"
-	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine("TreeTagger")
+	String engineName = project.getImportParameters().node("annotate").get("engine", "TreeTagger")
+	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine(engineName)
 	if (engine.processDirectory(txmDir, binDir, ["lang":model])) {
 		annotate_status = true;
 		if (project.getCleanAfterBuild()) {
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/xml/xmlLoader.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/xml/xmlLoader.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/xml/xmlLoader.groovy	(revision 3055)
@@ -237,7 +237,8 @@
 boolean annotationSuccess = false;
 if (annotate) {
 	println "-- ANNOTATE - Running NLP tools"
-	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine("TreeTagger")
+	String engineName = project.getImportParameters().node("annotate").get("engine", "TreeTagger")
+	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine(engineName)
 	if (engine.processDirectory(txmDir, binDir, ["lang":model])) {
 		annotationSuccess = true
 		if (project.getCleanAfterBuild()) {
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/bfm/bfmLoader.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/bfm/bfmLoader.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/bfm/bfmLoader.groovy	(revision 3055)
@@ -136,7 +136,8 @@
 boolean annotate_status = true;
 if (annotate) {
 	println "-- ANNOTATE - Running NLP tools - $model model"
-	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine("TreeTagger")
+	String engineName = project.getImportParameters().node("annotate").get("engine", "TreeTagger")
+	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine(engineName)
 	if (engine.processDirectory(txmDir, binDir, ["lang":model])) {
 		annotate_status = true;
 		
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/doc/docLoader.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/doc/docLoader.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/doc/docLoader.groovy	(revision 3055)
@@ -257,7 +257,8 @@
 boolean annotationSuccess = false;
 if (annotate) {
 	println "-- ANNOTATE - Running NLP tools"
-	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine("TreeTagger")
+	String engineName = project.getImportParameters().node("annotate").get("engine", "TreeTagger")
+	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine(engineName)
 	if (engine.processDirectory(txmDir, binDir, ["lang":model])) {
 		annotationSuccess = true;
 		if (project.getCleanAfterBuild()) {
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/tmx/tmxLoader.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/tmx/tmxLoader.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/tmx/tmxLoader.groovy	(revision 3055)
@@ -87,7 +87,8 @@
 if (MONITOR != null) MONITOR.worked(20, "ANNOTATE - Running NLP tools");
 if (annotate) {
 	println "-- ANNOTATE - Running NLP tools"
-	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine("TreeTagger")
+	String engineName = project.getImportParameters().node("annotate").get("engine", "TreeTagger")
+	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine(engineName)
 	def mapForTreeTagger = [:]
 	for (def k : textLangs.keySet()) mapForTreeTagger[k] = textLangs[k].toLowerCase();
 		println "TreeTagger models to use per text: $mapForTreeTagger"
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/factiva/factivaLoader.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/factiva/factivaLoader.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/factiva/factivaLoader.groovy	(revision 3055)
@@ -215,7 +215,8 @@
 boolean annotationSuccess = false;
 if (annotate) {
 	println "-- ANNOTATE - Running NLP tools"
-	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine("TreeTagger")
+	String engineName = project.getImportParameters().node("annotate").get("engine", "TreeTagger")
+	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine(engineName)
 	if (engine.processDirectory(txmDir, binDir, ["lang":model])) {
 		annotationSuccess = true;
 		if (project.getCleanAfterBuild()) {
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/factiva/factivamailLoader.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/factiva/factivamailLoader.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/factiva/factivamailLoader.groovy	(revision 3055)
@@ -104,7 +104,8 @@
 boolean annotationSuccess = false;
 if (annotate) {
 	println "-- ANNOTATE - Running NLP tools"
-	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine("TreeTagger")
+	String engineName = project.getImportParameters().node("annotate").get("engine", "TreeTagger")
+	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine(engineName)
 	if (engine.processDirectory(txmDir, binDir, ["lang":model])) {
 		annotationSuccess = true;
 	}
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/transcriber/transcriberLoader.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/transcriber/transcriberLoader.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/transcriber/transcriberLoader.groovy	(revision 3055)
@@ -191,7 +191,8 @@
 		boolean annotationSuccess = false;
 		if (annotate) {
 			println "-- ANNOTATE - Running NLP tools"
-			def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine("TreeTagger")
+			String engineName = project.getImportParameters().node("annotate").get("engine", "TreeTagger")
+	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine(engineName)
 			if (engine.processDirectory(txmDir, binDir, ["lang":model])) {
 				annotationSuccess = true;
 				
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/txt/txtLoader.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/txt/txtLoader.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/txt/txtLoader.groovy	(revision 3055)
@@ -133,7 +133,8 @@
 boolean annotationSuccess = true;
 if (annotate) {
 	println "-- ANNOTATE - Running NLP tools"
-	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine("TreeTagger")
+	String engineName = project.getImportParameters().node("annotate").get("engine", "TreeTagger")
+	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine(engineName)
 	if (engine.processDirectory(txmDir, binDir, ["lang":model])) {
 		annotationSuccess = true;
 		if (project.getCleanAfterBuild()) {
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/alceste/alcesteLoader.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/alceste/alcesteLoader.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/alceste/alcesteLoader.groovy	(revision 3055)
@@ -90,7 +90,8 @@
 
 if (annotate) {
 	println "-- ANNOTATE - Running NLP tools"
-	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine("TreeTagger")
+	String engineName = project.getImportParameters().node("annotate").get("engine", "TreeTagger")
+	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine(engineName)
 	if (engine.processDirectory(txmDir, binDir, ["lang":model])) {
 		annotationSuccess = true;
 	}
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/alceste/importer.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/alceste/importer.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/alceste/importer.groovy	(revision 3055)
@@ -47,6 +47,7 @@
 import java.io.PrintStream;
 import java.net.URL;
 
+import org.txm.core.engines*
 import org.txm.scripts.filters.CutHeader.*;
 import org.txm.scripts.filters.Tokeniser.*;
 import org.txm.scripts.filters.FusionHeader.*;
@@ -108,9 +109,17 @@
 			cpb.tick()
 			File resultfile = new File(tokenizeDir, f.getName());
 			try {
-				def builder = new SimpleTokenizerXml(f, resultfile, lang);
-				builder.setStartTag("text")
-				if (!builder.process()) {
+				def tokenizer = new SimpleTokenizerXml(f, resultfile, lang);
+				if (project.getAnnotate()) { // an annotation will be done, does the annotation engine needs another tokenizer ?
+					String engineName = project.getImportParameters().node("annotate").get("engine", "TreeTagger")
+					def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine(engineName)
+					def stringTokenizer = engine.getStringTokenizer(lang)
+					if (stringTokenizer != null) {
+						tokenizer.setStringTokenizer(stringTokenizer)
+					}
+				}
+				tokenizer.setStartTag("text")
+				if (!tokenizer.process()) {
 					println "Failed to tokenize: "+f;
 					resultfile.delete();
 				}
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/hyperbase/hyperbaseLoader.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/hyperbase/hyperbaseLoader.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/hyperbase/hyperbaseLoader.groovy	(revision 3055)
@@ -78,7 +78,7 @@
 if (MONITOR != null && MONITOR.isCanceled()) { return MONITOR.done(); }
 println "-- IMPORTER - Reading source files"
 
-if (!(new importer().run(srcDir, binDir, txmDir, encoding, basename, lang))) {
+if (!(new importer().run(srcDir, binDir, txmDir, encoding, basename, lang, project))) {
 	println "import process stopped";
 	return;
 }
@@ -88,7 +88,8 @@
 println "-- ANNOTATE - Running NLP tools"
 boolean annotationSuccess = false;
 if (annotate) {
-	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine("TreeTagger")
+	String engineName = project.getImportParameters().node("annotate").get("engine", "TreeTagger")
+	def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine(engineName)
 	if (engine.processDirectory(txmDir, binDir, ["lang":model])) {
 		annotationSuccess = true;
 		if (project.getCleanAfterBuild()) {
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/hyperbase/importer.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/hyperbase/importer.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/hyperbase/importer.groovy	(revision 3055)
@@ -51,7 +51,6 @@
 import org.txm.*;
 import org.txm.core.engines.*;
 import org.txm.utils.*;
-// TODO: Auto-generated Javadoc
 
 /**
  * The Class importer.
@@ -66,7 +65,7 @@
 	 * @param basename the basename
 	 * @return true, if successful
 	 */
-	public static boolean run(File srcDir, File binDir, File txmDir, String encoding, String basename, String lang)
+	public static boolean run(File srcDir, File binDir, File txmDir, String encoding, String basename, String lang, def project)
 	{
 		String rootDir = srcDir.getAbsolutePath()+"/"
 		//cleaning
@@ -113,6 +112,14 @@
 			File tfile = new File(binDir, "tokenized/"+filename+".xml");
 			
 			SimpleTokenizerXml tokenizer = new SimpleTokenizerXml(pfile, tfile, lang);
+			if (project.getAnnotate()) { // an annotation will be done, does the annotation engine needs another tokenizer ?
+				String engineName = project.getImportParameters().node("annotate").get("engine", "TreeTagger")
+				def engine = Toolbox.getEngineManager(EngineType.ANNOTATION).getEngine(engineName)
+				def stringTokenizer = engine.getStringTokenizer(lang)
+				if (stringTokenizer != null) {
+					tokenizer.setStringTokenizer(stringTokenizer)
+				}
+			}
 			if (!tokenizer.process()) {
 				println("Failed to tokenize file: "+pfile);
 				tfile.delete();
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/filters/Tokeniser/SimpleTokenizerXml.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/filters/Tokeniser/SimpleTokenizerXml.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/filters/Tokeniser/SimpleTokenizerXml.groovy	(revision 3055)
@@ -52,11 +52,14 @@
 import javax.xml.stream.*
 
 import org.txm.importer.PersonalNamespaceContext
+import org.txm.tokenizer.StringTokenizer
+import org.txm.tokenizer.SimpleStringTokenizer
 import org.txm.tokenizer.TokenizerClasses
 
 @CompileStatic
 public class SimpleTokenizerXml {
 	
+	StringTokenizer stringTokenizer;
 	boolean retokenize = false
 	LinkedHashMap<String, String>retokenizedWordProperties = new LinkedHashMap()
 	
@@ -67,18 +70,9 @@
 	/** The intraword_tags. */
 	String intraword_tags = TokenizerClasses.intraword_tags;
 	
-	/** The punct_strong. */
-	String punct_strong = TokenizerClasses.punct_strong;
-	
-	/** The punct_all. */
-	String punct_all = TokenizerClasses.punct_all;
-	
 	/** The word_chars. */
 	String word_chars = TokenizerClasses.word_chars;
 	
-	String fclitics = null; // default behavior don't manage clitics
-	String pclitics = null; // default behavior don't manage clitics
-	
 	/** The outside_text_tags_ignore_content. */
 	String note_content = null;
 	String outside_text_tags_keep_content = null // tag and content NOT removed but not tokenized
@@ -89,12 +83,10 @@
 	Pattern reg_outside_text_tags;
 	Pattern reg_startTag;
 	
-	Pattern reg_punct_other = Pattern.compile("\\p{P}")
-	
 	/** The DEBUG. */
 	public boolean DEBUG = false;
 	
-	/** The outfile. */
+	/** The outfile is the result file. */
 	File outfile;
 	
 	/** The infile. */
@@ -119,16 +111,8 @@
 	String prefix;
 	String filename;
 	
-	def regElision = null;
-	def reg3pts = null;
-	def regPunct;
-	def regFClitics = null ;
-	def regPClitics = null ;
-	String whitespaces;
-	Pattern regWhitespaces;
 	Pattern regLN;
 	Pattern regCTRL;
-	Pattern regSplitWhiteSpaces;
 	
 	public SimpleTokenizerXml(File infile, File outfile) {
 		this(infile, outfile, "");
@@ -142,24 +126,12 @@
 	 */
 	public SimpleTokenizerXml(File infile, File outfile, String lang) {
 		this.lang = lang;
-		if (lang != null)
-			if (lang.startsWith("en")) {
-				fclitics = TokenizerClasses.FClitic_en
-			} else if (lang.startsWith("fr")) {
-				fclitics = TokenizerClasses.FClitic_fr
-				pclitics = TokenizerClasses.PClitic_fr
-			} else if (lang.startsWith("gl")) {
-				fclitics = TokenizerClasses.FClitic_gl
-			} else if (lang.startsWith("it")) {
-				pclitics = TokenizerClasses.PClitic_it
-			}
+		this.stringTokenizer = new SimpleStringTokenizer(lang);
 		
 		word_tags = TokenizerClasses.word_tags;
 		reg_word_tags = Pattern.compile(word_tags);
 		
 		intraword_tags = TokenizerClasses.intraword_tags;
-		punct_strong = TokenizerClasses.punct_strong;
-		punct_all = TokenizerClasses.punct_all;
 		word_chars = TokenizerClasses.word_chars;
 		
 		this.outfile = outfile;
@@ -168,32 +140,20 @@
 		int index = filename.lastIndexOf(".");
 		if (index > 0) filename = filename.substring(0, index);
 		
-		String strRegElision = TokenizerClasses.regElision;
-		if (strRegElision != null && strRegElision.length() > 0)
-			regElision = ~/^([\p{L}-]++${strRegElision}[\p{L}-]++)(.*)$/ // the test must start with the start of string  ^
-		reg3pts = ~/^(.*?)(\.\.\.)(.*)$/
-		
-		String strRegPunct = TokenizerClasses.regPunct;
-		if (strRegPunct != null && strRegPunct.length() > 0)
-			regPunct = ~/^(.*?)($strRegPunct)(.*)$/
-		
-		if (fclitics != null && fclitics.length() > 0)
-			regFClitics = ~/(.+)($fclitics)$/ // the test must end with the end of string $
-		
-		if (pclitics != null && pclitics.length() > 0)
-			regPClitics = /^($pclitics)(.*)/ // the test must start with the start of string  ^
-		
-		if (TokenizerClasses.whitespaces != null && TokenizerClasses.whitespaces.length() > 0)
-			regWhitespaces = ~TokenizerClasses.whitespaces;
-		
-		if (TokenizerClasses.whitespaces != null && TokenizerClasses.whitespaces.length() > 0)
-			regSplitWhiteSpaces = Pattern.compile(TokenizerClasses.whitespaces);
-		
 		regLN = Pattern.compile("/\n/");
 		regCTRL = Pattern.compile("/\\p{C}/");
 	}
 	
 	/**
+	 * Replace the default SimpleStringTokenizer with another
+	 * @param stringTokenizer a StringTokenizer
+	 */
+	public void seStringTokenizer(StringTokenizer stringTokenizer) {
+		if (stringTokenizer == null) return;
+		this.stringTokenizer = stringTokenizer;
+	}
+	
+	/**
 	 * Fill infos.
 	 *
 	 * @param event the event
@@ -545,129 +505,18 @@
 		//if (DEBUG) println "-- chars: "+text+"--";
 		text = regLN.matcher(text).replaceAll(WHITESPACE);
 		text = regCTRL.matcher(text).replaceAll(EMPTY);						// remove ctrl characters
-		if (regSplitWhiteSpaces != null) {
-			for (String s : regSplitWhiteSpaces.split(text)) {		// separate with unicode white spaces
-				//	if (DEBUG){println "process $s"}
-				iterate(s);
-			}
-		} else {
-			iterate(text);
-		}
-	}
-	
-	/**
-	 * Iterate. a String, should be called when a word is found in a String
-	 *
-	 * @param s the s
-	 * @return the java.lang. object
-	 */
-	protected iterate(String s) {
-		while (s != null && s.length() > 0) {
-			//	if (DEBUG){println "  > $s"}
-			s = standardChecks(s);
-		}
-	}
-	
-	/**
-	 * Standard checks.
-	 *
-	 * @param s the s
-	 * @return the java.lang. object
-	 */
-	//	@CompileStatic(SKIP)
-	public String standardChecks(String s) {
-		Matcher m;
-		if (fclitics != null && (m = s =~ regFClitics) ) {
-			//	if (DEBUG) println "CLITIC found: $s ->"+ m
-			iterate(m.group(1))
-			
+
+				def words = stringTokenizer.processText(text);
+		for (def word : words) {
 			wordcount++;
 			writer.writeStartElement(word_element_to_create);
 			writeWordAttributes();// id
-			//writer.writeAttribute("type", "w");
-			writer.writeCharacters(m.group(2));
+			writer.writeCharacters(word);
 			writer.writeEndElement();
 			writer.writeCharacters("\n");
-			
-			return "";
-		} else if (pclitics != null && (m = s =~ regPClitics) ) {
-			if (DEBUG) println "PCLITIC found: $s ->"+ m
-			
-			wordcount++;
-			writer.writeStartElement(word_element_to_create);
-			writeWordAttributes();// id
-			//writer.writeAttribute("type", "w");
-			writer.writeCharacters(m.group(1));
-			writer.writeEndElement();
-			writer.writeCharacters("\n");
-			
-			iterate(m.group(2))
-			
-			return "";
-		} else if (regElision != null && (m = s =~ regElision) ) {
-			//	if (DEBUG) println "Elision found: $s ->"+ m.group(1)+" + "+m.group(2)+" + "+m.group(3)
-			//iterate(m.group(1))
-			
-			//			int sep = s.indexOf("'");
-			//			if (sep < 0)
-			//				sep = s.indexOf("’");
-			//			if (sep < 0)
-			//				sep = s.indexOf("‘");
-			
-			wordcount++;
-			writer.writeStartElement(word_element_to_create);
-			writeWordAttributes();// id
-			//writer.writeAttribute("type", "w");
-			writer.writeCharacters(m.group(1));
-			writer.writeEndElement();
-			writer.writeCharacters("\n");
-			
-			iterate(m.group(2))
-			
-			return "";
-		} else if (reg3pts != null && (m = s =~ reg3pts) )	{
-			//	if(DEBUG){println "REG '...' found: $s -> "+m.group(1)+" + "+m.group(2)+" + "+m.group(3)}
-			iterate(m.group(1))
-			
-			wordcount++;
-			writer.writeStartElement(word_element_to_create);
-			writeWordAttributes();// id
-			//writer.writeAttribute("type","pon");
-			writer.writeCharacters("...");
-			writer.writeEndElement();
-			writer.writeCharacters("\n");
-			
-			return m.group(3);
-		} else if (regPunct != null && (m = s =~ regPunct) ) {
-			if(DEBUG){println "PUNCT found: $s ->"+m.group(1)+" + "+m.group(2)+" + "+m.group(3)}
-			iterate(m.group(1));
-			
-			wordcount++;
-			writer.writeStartElement(word_element_to_create);
-			writeWordAttributes();// id
-			//writer.writeAttribute("type","pon");
-			writer.writeCharacters(m.group(2));
-			writer.writeEndElement();
-			writer.writeCharacters("\n");
-			
-			return m.group(3);
-		} else {
-			//		if(DEBUG){println "Other found: "+s}
-			wordcount++;
-			writer.writeStartElement(word_element_to_create);
-			writeWordAttributes();// id
-			//			if (reg_punct_other.matcher(s).matches())
-			//				writer.writeAttribute("type","pon");
-			//			else
-			//				writer.writeAttribute("type","w");
-			writer.writeCharacters(s);
-			writer.writeEndElement();
-			writer.writeCharacters("\n");
-			
-			return "";
 		}
 	}
-	
+
 	/**
 	 * Write word attributes.
 	 *
@@ -783,13 +632,16 @@
 		//		println "Done"
 		
 		String lang = "fr"
-		File inFile = new File(System.getProperty("user.home"), "xml/vocapia/test.trs")
-		File outFile = new File(System.getProperty("user.home"), "xml/vocapia/test-retokenized.trs")
+		File inFile = new File(System.getProperty("user.home"), "SVN/TXMSVN/trunk/corpora/tokenizer/test1.xml")
+		File outFile = new File(System.getProperty("user.home"), "SVN/TXMSVN/trunk/corpora/tokenizer/test1-tmp.xml")
 		
 		println "processing "+inFile
 		
 		SimpleTokenizerXml tokenizer = new SimpleTokenizerXml(inFile, outFile, lang)
-		tokenizer.setRetokenize(true)
+		tokenizer.setRetokenize(false)
+		tokenizer.setNote("note")
+		//tokenizer.setOutSideTextTags("outsideToEdit")
+		tokenizer.setOutSideTextTagsAndKeepContent("outsideToEdit")
 		//tokenizer.setDEBUG false
 		tokenizer.process();
 		
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/ApplyXQueryMacro.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/ApplyXQueryMacro.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/ApplyXQueryMacro.groovy	(revision 3055)
@@ -53,7 +53,7 @@
 	return false;
 }
 
-def xmlFiles = txmDir.listFiles();
+def xmlFiles = txmDir.listFiles().sort{ it.name };
 if (xmlFiles == null || xmlFiles.size() == 0) {
 	println "Error: no file found in $txmDir"
 	return false;
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/file/DirectoryInfoMacro.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/file/DirectoryInfoMacro.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/file/DirectoryInfoMacro.groovy	(revision 3055)
@@ -29,7 +29,7 @@
 println " write? "+directory.canWrite()
 println " executable? "+directory.canExecute()
 println " hidden? "+directory.isHidden()
-def files = directory.listFiles()
+def files = directory.listFiles().sort{ it.name }
 println " number of files? "+files.size()
 
 
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/FindMultiLineRegExpMacro.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/FindMultiLineRegExpMacro.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/FindMultiLineRegExpMacro.groovy	(revision 3055)
@@ -66,7 +66,7 @@
 
 println "-- looking for: $regexp"
 
-for (File inputfile : inputDirectory.listFiles()) {
+for (File inputfile : inputDirectory.listFiles().sort{ it.name }) {
 
 	if (inputfile.isDirectory()) continue // ignore
 
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/GetXPathMacro.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/GetXPathMacro.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/GetXPathMacro.groovy	(revision 3055)
@@ -53,7 +53,7 @@
 
 if (srcDirectory!=null && srcDirectory.exists()) {
 
-	def files = srcDirectory.listFiles()
+	def files = srcDirectory.listFiles().sort{ it.name }
 	if (files == null || files.size() == 0) {
 		println "No files in $srcDirectory"
 		return;
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/xml/XSL2CQPMacro.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/xml/XSL2CQPMacro.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/xml/XSL2CQPMacro.groovy	(revision 3055)
@@ -42,7 +42,7 @@
 	return false;
 }
 
-def xmlFiles = txmDir.listFiles();
+def xmlFiles = txmDir.listFiles().sort{ it.name };
 if (xmlFiles == null || xmlFiles.size() == 0) {
 	println "Error: no file found in $txmDir"
 	return false;
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/xml/ApplyXQueryMacro.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/xml/ApplyXQueryMacro.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/macro/prototypes/xml/ApplyXQueryMacro.groovy	(revision 3055)
@@ -53,7 +53,7 @@
 	return false;
 }
 
-def xmlFiles = txmDir.listFiles();
+def xmlFiles = txmDir.listFiles().sort{ it.name };
 if (xmlFiles == null || xmlFiles.size() == 0) {
 	println "Error: no file found in $txmDir"
 	return false;
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/macro/nlp/TT2XMLInDirectoryMacro.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/macro/nlp/TT2XMLInDirectoryMacro.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/macro/nlp/TT2XMLInDirectoryMacro.groovy	(revision 3055)
@@ -26,7 +26,7 @@
 	
 	XMLOutputFactory factory = XMLOutputFactory.newInstance()
 	
-	def files = inputDirectory.listFiles()
+	def files = inputDirectory.listFiles().sort{ it.name }
 	if (files == null || files.length == 0) {
 		println "Error: no file to process in $inputDirectory"
 		return false;
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/macro/projects/antract/FixINATRSMacro.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/macro/projects/antract/FixINATRSMacro.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/macro/projects/antract/FixINATRSMacro.groovy	(revision 3055)
@@ -14,7 +14,7 @@
 if (!ParametersDialog.open(this)) return;
 
 println "Fixing $trsDirectory"
-def files = trsDirectory.listFiles()
+def files = trsDirectory.listFiles().sort{ it.name }
 if (files == null) {
 	println "No files found in $trsDirectory"
 	return 0;
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/macro/imports/TeiHeader2MetadataCSVMacro.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/macro/imports/TeiHeader2MetadataCSVMacro.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/macro/imports/TeiHeader2MetadataCSVMacro.groovy	(revision 3055)
@@ -39,7 +39,7 @@
 	return
 }
 
-List<File> files = inputDirectory.listFiles()
+List<File> files = inputDirectory.listFiles().sort{ it.name }
 if (files == null || files.size() == 0) {
 	println "** TeiHeader2MetadataCSV: no files found in '$inputDirectory' directory."
 	return
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/macro/xml/CombineAttributesMacro.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/macro/xml/CombineAttributesMacro.groovy	(revision 0)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/macro/xml/CombineAttributesMacro.groovy	(revision 3055)
@@ -0,0 +1,59 @@
+// STANDARD DECLARATIONS
+package org.txm.macro.xml
+
+import org.txm.annotation.kr.core.conversion.*
+import javax.xml.stream.XMLStreamReader
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.regex.Pattern;
+
+@Field @Option(name="xmlFile", usage="fichier XML lu", widget="FileOpen", required=true, def="in.xml") // /home/mdecorde/TEMP/ANTRACT/AF/all.xlsx
+File xmlFile
+
+@Field @Option(name="resultFile", usage="fichier XML resultat", widget="FileSave", required=true, def="out.xml") // /home/mdecorde/TEMP/ANTRACT/AF/all.xlsx
+File resultFile
+
+@Field @Option(name = "elementName", usage = "oldType", widget = "String", required = true, def = "w")
+String elementName
+
+//@Field @Option(name = "oldType", usage = "oldType", widget = "String", required = true, def = "myattr")
+def oldType = null // not needed
+	
+@Field @Option(name = "newType", usage = "newType", widget = "String", required = true, def = "myattr")
+String newType
+
+@Field @Option(name = "separator", usage = "newType", widget = "Separator", required = false, def = "Code")
+def separator
+
+@Field @Option(name = "getValueCode", usage = "code of the getValue(XMLStreamReader parser, String localname, String attribute, String value) method", widget = "Text", required = true, def = "\"NEWGROOVE\" + parser.getAttributeValue(null, \"myattr\") ")
+String getValueCode
+
+@Field @Option(name = "additionalImportsCode", usage = "code of the getValue(XMLStreamReader parser, String localname, String attribute, String value) method", widget = "Text", required = true, def = "import java.io.File")
+String additionalImportsCode
+
+@Field @Option(name = "debug", usage = "show debug messages", widget = "Boolean", required = true, def = "false")
+boolean debug
+
+if (!ParametersDialog.open(this)) return;
+
+
+// not needed
+LinkedHashMap<Pattern, String> rules = new LinkedHashMap<>();
+
+XMLTXMFileRuledConversion converter = new XMLTXMFileRuledConversion(xmlFile, rules, elementName, oldType, newType, XMLTXMFileRuledConversion.ABANDON);
+
+// initialize a converter using getValueCode value to fill the getValue(parser, localname, attribute, value) method
+converter.converter = gse.evaluate("""import org.txm.annotation.kr.core.conversion.*;
+import javax.xml.stream.XMLStreamReader
+$additionalImportsCode
+
+return new XMLTXMFileRuledConversion.Converter() {
+	public String getValue(XMLStreamReader parser, String localname, String attribute, String value) {
+		$getValueCode
+	}
+};
+""");
+converter.debug = debug
+converter.process(resultFile)
\ No newline at end of file
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/macro/annotation/InjectWordPropTableMacro.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/macro/annotation/InjectWordPropTableMacro.groovy	(revision 3054)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/macro/annotation/InjectWordPropTableMacro.groovy	(revision 3055)
@@ -81,7 +81,7 @@
 
 println "Injecting..."
 //for (String textid : injections.keySet()) {
-for (File currentXMLFile : inputDirectory.listFiles()) {
+for (File currentXMLFile : inputDirectory.listFiles().sort{ it.name }) {
 	if (currentXMLFile.isDirectory()) continue;
 	if (currentXMLFile.isHidden()) continue;
 	
Index: tmp/org.txm.groovy.core/src/java/org/txm/groovy/core/GSERunner.java
===================================================================
--- tmp/org.txm.groovy.core/src/java/org/txm/groovy/core/GSERunner.java	(revision 3054)
+++ tmp/org.txm.groovy.core/src/java/org/txm/groovy/core/GSERunner.java	(revision 3055)
@@ -22,6 +22,7 @@
 
 import cern.colt.Arrays;
 import groovy.lang.Binding;
+import groovy.lang.GroovyShell;
 import groovy.util.GroovyScriptEngine;
 import groovy.util.ResourceException;
 import groovy.util.ScriptException;
@@ -128,6 +129,10 @@
 		return defaultGSE;
 	}
 	
+	public Object evaluate(String code) {
+		return new GroovyShell(this.getGroovyClassLoader(), new Binding()).evaluate(code);
+	}
+	
 	public static void getDependancies(String bundle, HashSet<String> defaultPlugins) {
 		// if (defaultPlugins.contains(bundle)) return;
 		
Index: tmp/org.txm.groovy.core/META-INF/MANIFEST.MF
===================================================================
--- tmp/org.txm.groovy.core/META-INF/MANIFEST.MF	(revision 3054)
+++ tmp/org.txm.groovy.core/META-INF/MANIFEST.MF	(revision 3055)
@@ -4,10 +4,11 @@
 Bundle-Version: 1.0.0.qualifier
 Bundle-Name: Macro
 Bundle-ClassPath: .,bin/
-Require-Bundle: org.txm.core;bundle-version="0.8.0";visibility:=reexpo
- rt,org.txm.annotation.core;visibility:=reexport,org.txm.searchengine.
- cqp.core;visibility:=reexport,org.txm.tokenizer.core;visibility:=reex
- port,org.eclipse.osgi
+Require-Bundle: org.txm.core;bundle-version="0.8.0";visibility:=reexport,
+ org.txm.annotation.core;visibility:=reexport,
+ org.txm.searchengine.cqp.core;visibility:=reexport,
+ org.txm.tokenizer.core;visibility:=reexport,
+ org.eclipse.osgi;visibility:=reexport
 Bundle-ActivationPolicy: lazy
 Bundle-ManifestVersion: 2
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Index: tmp/org.txm.ocaml.core/META-INF/MANIFEST.MF
===================================================================
--- tmp/org.txm.ocaml.core/META-INF/MANIFEST.MF	(revision 3054)
+++ tmp/org.txm.ocaml.core/META-INF/MANIFEST.MF	(revision 3055)
@@ -20,7 +20,8 @@
 Bundle-Name: Ocaml
 Bundle-Version: 2.0
 Bundle-ClassPath: .,lib/ocamlrun-scripting.jar,lib/ocaml-lib-files.jar
-Require-Bundle: org.txm.core,org.eclipse.core.runtime
+Require-Bundle: org.txm.core;visibility:=reexport,
+ org.eclipse.core.runtime;visibility:=reexport
 Bundle-ManifestVersion: 2
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Bundle-Vendor: Textometrie.org
Index: tmp/org.txm.practically.rcp/META-INF/MANIFEST.MF
===================================================================
--- tmp/org.txm.practically.rcp/META-INF/MANIFEST.MF	(revision 3054)
+++ tmp/org.txm.practically.rcp/META-INF/MANIFEST.MF	(revision 3055)
@@ -2,7 +2,7 @@
 Export-Package: practicallymacro.actions,practicallymacro.commands,pra
  cticallymacro.dialogs,practicallymacro.editormacros,practicallymacro.
  model,practicallymacro.preferences,practicallymacro.util
-Bundle-SymbolicName: org.txm.pratically.rcp;singleton:=true
+Bundle-SymbolicName: org.txm.practically.rcp;singleton:=true
 Bundle-Version: 0.4.5
 Bundle-Name: PracticallyMacro Plug-in
 Require-Bundle: org.eclipse.ui;visibility:=reexport,org.eclipse.core.r
Index: tmp/org.txm.practically.rcp/plugin.xml
===================================================================
--- tmp/org.txm.practically.rcp/plugin.xml	(revision 3054)
+++ tmp/org.txm.practically.rcp/plugin.xml	(revision 3055)
@@ -159,7 +159,7 @@
     </startup>
  </extension>
  <extension
-       point="org.txm.pratically.rcp.xmlCommandHandlers">
+       point="org.txm.practically.rcp.xmlCommandHandlers">
     <XMLCommandHandler
           class="practicallymacro.commands.EclipseCommand"
           type="EclipseCommand">
Index: tmp/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/StructuralUnitProperty.java
===================================================================
--- tmp/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/StructuralUnitProperty.java	(revision 3054)
+++ tmp/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/StructuralUnitProperty.java	(revision 3055)
@@ -39,6 +39,7 @@
 import org.txm.searchengine.cqp.clientExceptions.CqiClientException;
 import org.txm.searchengine.cqp.clientExceptions.UnexpectedAnswerException;
 import org.txm.searchengine.cqp.corpus.query.CQLQuery;
+import org.txm.searchengine.cqp.corpus.query.MatchUtils;
 import org.txm.searchengine.cqp.serverException.CqiServerError;
 import org.txm.utils.logger.Log;
 
@@ -301,14 +302,39 @@
 		
 		return null;
 	}
-
+	
 	public String cpos2Str(int position) throws UnexpectedAnswerException, IOException, CqiServerError {
 		AbstractCqiClient cqiClient = CorpusManager.getCorpusManager().getCqiClient();
-		return cqiClient.getSingleData(this, new int[] {position}).get(0);
+		return cqiClient.getSingleData(this, new int[] { position }).get(0);
 	}
 	
 	public String[] cpos2Str(int[] positions) throws UnexpectedAnswerException, IOException, CqiServerError {
 		AbstractCqiClient cqiClient = CorpusManager.getCorpusManager().getCqiClient();
 		return cqiClient.getSingleData(this, positions).toArray(new String[positions.length]);
 	}
+	
+	/**
+	 * Very slow
+	 * 
+	 * @return
+	 * @throws IOException
+	 * @throws CqiServerError
+	 * @throws CqiClientException
+	 */
+	public int getNValues() throws IOException, CqiServerError, CqiClientException {
+		return getValues().size();
+	}
+	
+	/**
+	 * Very slow
+	 * 
+	 * @return
+	 * @throws IOException
+	 * @throws CqiServerError
+	 * @throws CqiClientException
+	 */
+	public String[] getValuesAsStrings() throws IOException, CqiServerError, CqiClientException {
+		List<String> values = getValues();
+		return values.toArray(new String[values.size()]);
+	}
 }
Index: tmp/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/CQPCorpus.java
===================================================================
--- tmp/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/CQPCorpus.java	(revision 3054)
+++ tmp/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/CQPCorpus.java	(revision 3055)
@@ -1484,4 +1484,21 @@
 		
 		return null;
 	}
+	
+	/**
+	 * parse a "struct_prop" property name to find the matching StructuralUnitProperty
+	 * 
+	 * @param p
+	 * @return
+	 */
+	public StructuralUnitProperty getStructuralUnitProperty(String p) {
+		
+		try {
+			return StructuralUnitProperty.stringToStructuralUnitProperty(this, p);
+		}
+		catch (CqiClientException e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
 }
Index: tmp/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/WordProperty.java
===================================================================
--- tmp/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/WordProperty.java	(revision 3054)
+++ tmp/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/WordProperty.java	(revision 3055)
@@ -3,8 +3,11 @@
 import java.io.IOException;
 import java.util.List;
 
+import org.apache.commons.lang.math.IntRange;
+import org.txm.objects.Match;
 import org.txm.searchengine.cqp.clientExceptions.UnexpectedAnswerException;
 import org.txm.searchengine.cqp.corpus.query.CQLQuery;
+import org.txm.searchengine.cqp.corpus.query.MatchUtils;
 import org.txm.searchengine.cqp.serverException.CqiServerError;
 
 /**
@@ -62,7 +65,7 @@
 	}
 	
 	public String cpos2Str(int position) throws UnexpectedAnswerException, IOException, CqiServerError {
-		return CorpusManager.getCorpusManager().getCqiClient().cpos2Str(this.getQualifiedName(), new int[] {position})[0];
+		return CorpusManager.getCorpusManager().getCqiClient().cpos2Str(this.getQualifiedName(), new int[] { position })[0];
 	}
 	
 	public String[] cpos2Str(int[] positions) throws UnexpectedAnswerException, IOException, CqiServerError {
@@ -82,25 +85,35 @@
 	}
 	
 	public int str2Id(String value) throws UnexpectedAnswerException, IOException, CqiServerError {
-		return CorpusManager.getCorpusManager().getCqiClient().str2Id(this.getQualifiedName(), new String[] {value})[0];
+		return CorpusManager.getCorpusManager().getCqiClient().str2Id(this.getQualifiedName(), new String[] { value })[0];
 	}
 	
 	public String getCQLTest(String value) {
-		return this.getName() + "=\"" +  CQLQuery.addBackSlash(value)+ "\"";
+		return this.getName() + "=\"" + CQLQuery.addBackSlash(value) + "\"";
 	}
 	
 	public String getCQLTest(List<String> values) {
 		StringBuilder sb = new StringBuilder();
 		sb.append(this.getName() + "=\""); //$NON-NLS-1$
-		for (int i = 0 ; i < values.size() ; i++) {
+		for (int i = 0; i < values.size(); i++) {
 			String s = values.get(i);
 			s = CQLQuery.addBackSlash(s);
-			sb.append(s); //$NON-NLS-1$
-			if (i < values.size() -1) {
+			sb.append(s);
+			if (i < values.size() - 1) {
 				sb.append("|"); //$NON-NLS-1$
 			}
 		}
 		sb.append("\"");
 		return sb.toString();
+	}
+	
+	public String[] getValues() throws UnexpectedAnswerException, IOException, CqiServerError {
+		int n = CorpusManager.getCorpusManager().getCqiClient().lexiconSize(this.getQualifiedName());
+		int[] ids = MatchUtils.toPositions(0, n - 1);
+		return CorpusManager.getCorpusManager().getCqiClient().id2Str(this.getQualifiedName(), ids);
+	}
+	
+	public int getNValues() throws UnexpectedAnswerException, IOException, CqiServerError {
+		return CorpusManager.getCorpusManager().getCqiClient().lexiconSize(this.getQualifiedName());
 	};
 }
Index: tmp/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/query/MatchUtils.java
===================================================================
--- tmp/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/query/MatchUtils.java	(revision 3054)
+++ tmp/org.txm.searchengine.cqp.core/src/org/txm/searchengine/cqp/corpus/query/MatchUtils.java	(revision 3055)
@@ -70,21 +70,31 @@
 	 * @return array of int position from a Match start to another Match end
 	 */
 	public static int[] toPositions(Match match1, Match match2) {
-		int len = match2.end - match1.start + 1;
+		return toPositions(match1.start, match2.end);
+	}
+	
+	/**
+	 * 
+	 * @param match1
+	 * @param match2
+	 * @return array of int position from a Match start to another Match end
+	 */
+	public static int[] toPositions(int from, int to) {
+		int len = to - from + 1;
 		
 		if (len <= 0) {
 			return new int[0];
 		}
 		else if (len == 1) {
-			return new int[] { match1.start };
+			return new int[] { from };
 		}
 		else if (len == 2) {
-			return new int[] { match1.start, match2.end };
+			return new int[] { from, to };
 		}
 		else {
 			int[] positions = new int[len];
 			int n = 0;
-			for (int i = match1.start; i <= match2.end; i++) {
+			for (int i = from; i <= to; i++) {
 				positions[n++] = i;
 			}
 			return positions;
Index: tmp/org.txm.annotation.kr.rcp/src/org/txm/annotation/kr/rcp/commands/RecodeCorpus.java
===================================================================
--- tmp/org.txm.annotation.kr.rcp/src/org/txm/annotation/kr/rcp/commands/RecodeCorpus.java	(revision 3054)
+++ tmp/org.txm.annotation.kr.rcp/src/org/txm/annotation/kr/rcp/commands/RecodeCorpus.java	(revision 3055)
@@ -36,40 +36,45 @@
 import org.txm.utils.logger.Log;
 
 public class RecodeCorpus extends AbstractHandler {
-
+	
 	public static final String ID = RecodeCorpus.class.getCanonicalName();
-
-	@Option(name="conversionFile", usage="conversionFile", widget="File", required=true, def="conv.tsv")
+	
+	@Option(name = "conversionFile", usage = "conversionFile", widget = "File", required = true, def = "conv.tsv")
 	protected File conversionFile;
-	@Option(name="oldType", usage="oldType", widget="String", required=true, def="pos")
+	
+	@Option(name = "oldType", usage = "oldType", widget = "String", required = true, def = "pos")
 	protected String oldType;
-	@Option(name="newType", usage="newType", widget="String", required=true, def="pos2")
+	
+	@Option(name = "newType", usage = "newType", widget = "String", required = true, def = "pos2")
 	protected String newType;
-	@Option(name="gestionInconnus", usage="oldType", widget="String", required=true, def="abandon")
+	
+	@Option(name = "gestionInconnus", usage = "how to manage failed conversion", widget = "String", required = true, def = "abandon")
 	protected String gestionInconnus;
-
+	
 	@Override
 	public Object execute(ExecutionEvent event) throws ExecutionException {
-
+		
 		ISelection isel = HandlerUtil.getCurrentSelection(event);
-		if (isel == null) return null ;
-		if (!(isel instanceof IStructuredSelection)) return null ;
+		if (isel == null) return null;
+		if (!(isel instanceof IStructuredSelection)) return null;
 		IStructuredSelection selection = (IStructuredSelection) isel;
 		Object s = selection.getFirstElement();
 		if (!(s instanceof MainCorpus)) return null;
-
+		
 		final MainCorpus corpus = (MainCorpus) s;
-
+		
 		try {
 			if (ParametersDialog.open(this)) {
-
-				JobHandler job = new JobHandler("Recode corpus "+corpus) {
+				
+				JobHandler job = new JobHandler("Recode corpus " + corpus) {
+					
 					@Override
 					protected IStatus run(IProgressMonitor monitor) {
 						try {
 							recode(corpus, conversionFile, oldType, newType, monitor);
-						} catch (Exception e) {
-							System.out.println("Fail to convert properties of corpus "+corpus);
+						}
+						catch (Exception e) {
+							System.out.println("Fail to convert properties of corpus " + corpus);
 							e.printStackTrace();
 							return Status.CANCEL_STATUS;
 						}
@@ -79,70 +84,76 @@
 				job.startJob();
 				return corpus;
 			}
-		} catch (Exception e) {
+		}
+		catch (Exception e) {
 			e.printStackTrace();
 		}
-
+		
 		return corpus;
 	}
-
-	public static JobHandler recode(final MainCorpus corpus, CorpusRuledConvertion crc, String oldType, String newType, IProgressMonitor monitor) throws IOException, CqiClientException, XMLStreamException {
-
+	
+	public static JobHandler recode(final MainCorpus corpus, CorpusRuledConvertion crc, String oldType, String newType, IProgressMonitor monitor) throws IOException, CqiClientException,
+			XMLStreamException {
+		
 		Project project = corpus.getProject();
 		if (!"xtz".equals(project.getImportModuleName())) {
-			System.out.println("Corpus "+corpus+" was imported with XTZ import module");
+			System.out.println("Corpus " + corpus + " was not imported with the XTZ import module");
 			return null;
 		}
 		
 		Property p1 = corpus.getProperty(oldType);
 		if (p1 == null) {
-			System.out.println("Corpus "+corpus+" has not property "+oldType);
+			System.out.println("Corpus " + corpus + " has not property " + oldType);
 			return null;
 		}
-
-		System.out.println("Recoding "+corpus+" property "+oldType+" in "+newType);
-
+		
+		System.out.println("Recoding " + corpus + " property " + oldType + " in " + newType);
+		
 		monitor.beginTask("Recoding corpus properties...", 2);
 		monitor.setTaskName("Recoding XML-TXM files");
 		// apply conversion file
 		if (!crc.process(corpus)) {
-			System.out.println("Failed to edit XML-TXM of the corpus: "+corpus);
+			System.out.println("Failed to edit XML-TXM of the corpus: " + corpus);
 			return null;
 		}
 		monitor.worked(1);
 		
 		// update corpus indexes and edition
-//		String txmhome = Toolbox.getTxmHomePath();
-
+		// String txmhome = Toolbox.getTxmHomePath();
 		
-		project.setDoMultiThread(false); //too soon
+		
+		project.setDoMultiThread(false); // too soon
 		project.setDoUpdate(true);
-
-//		monitor.setTaskName("Updating corpus");
-//		File scriptDir = new File(txmhome, "scripts/groovy/user/org/txm/scripts/importer/xtz");
-//		File script = new File(scriptDir, "xtzLoader.groovy");
+		
+		// monitor.setTaskName("Updating corpus");
+		// File scriptDir = new File(txmhome, "scripts/groovy/user/org/txm/scripts/importer/xtz");
+		// File script = new File(scriptDir, "xtzLoader.groovy");
 		System.out.println(NLS.bind(KRAnnotationUIMessages.updatingTheP0Corpus, corpus));
 		JobHandler ret = ExecuteImportScript.executeScript(project);
 		Display.getDefault().syncExec(new Runnable() {
+			
 			@Override
-			public void run() {CloseEditorsUsing.corpus(corpus);}
+			public void run() {
+				CloseEditorsUsing.corpus(corpus);
+			}
 		});
 		monitor.worked(1);
 		return ret;
 	}
-
-	public static JobHandler recode(final MainCorpus corpus, LinkedHashMap<Pattern, String> rules, String oldType, String newType, IProgressMonitor monitor) throws IOException, CqiClientException, XMLStreamException {
-
+	
+	public static JobHandler recode(final MainCorpus corpus, LinkedHashMap<Pattern, String> rules, String oldType, String newType, IProgressMonitor monitor) throws IOException, CqiClientException,
+			XMLStreamException {
+		
 		// apply conversion file
 		CorpusRuledConvertion crc = new CorpusRuledConvertion(rules, newType, oldType);
-		return recode(corpus, crc, oldType, newType , monitor);
+		return recode(corpus, crc, oldType, newType, monitor);
 	}
-
+	
 	public static JobHandler recode(final MainCorpus corpus, File conversionFile, String oldType, String newType, IProgressMonitor monitor) throws IOException, CqiClientException, XMLStreamException {
-		System.out.println("Create CorpusRuledConvertion with "+conversionFile);
+		System.out.println("Create CorpusRuledConvertion with " + conversionFile);
 		// apply conversion file
 		CorpusRuledConvertion crc = new CorpusRuledConvertion(conversionFile, oldType, newType);
-
+		
 		return recode(corpus, crc, oldType, newType, monitor);
 	}
-}
\ No newline at end of file
+}
Index: tmp/org.txm.rcp/src/main/java/org/txm/rcp/handlers/results/DeleteObject.java
===================================================================
--- tmp/org.txm.rcp/src/main/java/org/txm/rcp/handlers/results/DeleteObject.java	(revision 3054)
+++ tmp/org.txm.rcp/src/main/java/org/txm/rcp/handlers/results/DeleteObject.java	(revision 3055)
@@ -77,6 +77,7 @@
 	public Object execute(ExecutionEvent event) throws ExecutionException {
 		
 		final IStructuredSelection selection = (IStructuredSelection) HandlerUtil.getCurrentSelection(event);
+		if (selection.isEmpty()) return null;
 		
 		if (!askContinueToDelete(selection)) {
 			return null;
Index: tmp/org.txm.rcp/src/main/java/org/txm/rcp/editors/imports/sections/LangSection.java
===================================================================
--- tmp/org.txm.rcp/src/main/java/org/txm/rcp/editors/imports/sections/LangSection.java	(revision 3054)
+++ tmp/org.txm.rcp/src/main/java/org/txm/rcp/editors/imports/sections/LangSection.java	(revision 3055)
@@ -1,6 +1,7 @@
 package org.txm.rcp.editors.imports.sections;
 
 import java.io.File;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Locale;
 
@@ -16,6 +17,11 @@
 import org.eclipse.ui.forms.widgets.ScrolledForm;
 import org.eclipse.ui.forms.widgets.TableWrapData;
 import org.eclipse.ui.forms.widgets.TableWrapLayout;
+import org.txm.Toolbox;
+import org.txm.annotation.core.AnnotationEngine;
+import org.txm.core.engines.Engine;
+import org.txm.core.engines.EngineType;
+import org.txm.core.engines.EnginesManager;
 import org.txm.objects.Project;
 import org.txm.rcp.messages.TXMUIMessages;
 import org.txm.treetagger.core.preferences.TreeTaggerPreferences;
@@ -32,6 +38,8 @@
 	
 	Button btnSelectAnnotate;
 	
+	Combo annotateEngineCombo;
+	
 	Button btnSelectLang;
 	
 	Combo langcombo;
@@ -65,6 +73,29 @@
 		btnSelectAnnotate = toolkit.createButton(sectionClient, TXMUIMessages.annotateTheCorpus, SWT.CHECK);
 		toolkit.createLabel(sectionClient, ""); //$NON-NLS-1$
 		
+		
+		
+		EnginesManager<? extends Engine> ema = Toolbox.getEngineManager(EngineType.ANNOTATION);
+		ArrayList<String> engines = new ArrayList<>();
+		for (String engine : ema.getEngines().keySet()) {
+			AnnotationEngine e = (AnnotationEngine) ema.getEngine(engine);
+			if (e.isAutomatic()) {
+				engines.add(engine);
+			}
+		}
+		if (engines.size() > 1) {
+			
+			toolkit.createLabel(sectionClient, "Annotation engine"); //$NON-NLS-1$
+			
+			annotateEngineCombo = new Combo(sectionClient, SWT.BORDER);
+			annotateEngineCombo.setLayoutData(getTextGridData());
+			annotateEngineCombo.setToolTipText("Annotation engines");
+			annotateEngineCombo.setItems(engines.toArray(new String[engines.size()]));
+			annotateEngineCombo.setText(annotateEngineCombo.getItem(0));
+		}
+		
+		// if widget selected change the radio buttons value
+		
 		btnGuessLang = toolkit.createButton(sectionClient, TXMUIMessages.guessColon, SWT.RADIO);
 		toolkit.createLabel(sectionClient, ""); //$NON-NLS-1$
 		
@@ -151,6 +182,10 @@
 		
 		langcombo.setText(defaultLang);
 		btnSelectAnnotate.setSelection(annotate);
+		
+		if (annotateEngineCombo != null) {
+			annotateEngineCombo.setText(project.getImportParameters().node("annotate").get("engine", "TreeTagger"));
+		}
 	}
 	
 	@Override
@@ -170,6 +205,11 @@
 			
 			project.setAnnotate(btnSelectAnnotate.getSelection());
 			project.setLang(lang);
+			
+			if (annotateEngineCombo != null) {
+				project.getImportParameters().node("annotate").put("engine", annotateEngineCombo.getText());
+			}
+			
 			return true;
 		}
 		return true;
Index: tmp/org.txm.rcp/src/main/java/org/txm/rcp/swt/dialog/QueryAssistDialog.java
===================================================================
--- tmp/org.txm.rcp/src/main/java/org/txm/rcp/swt/dialog/QueryAssistDialog.java	(revision 3054)
+++ tmp/org.txm.rcp/src/main/java/org/txm/rcp/swt/dialog/QueryAssistDialog.java	(revision 3055)
@@ -27,10 +27,14 @@
 //
 package org.txm.rcp.swt.dialog;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.eclipse.jface.bindings.keys.KeyStroke;
 import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.fieldassist.ComboContentAdapter;
+import org.eclipse.jface.fieldassist.TXMAutoCompleteField;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.ScrolledComposite;
@@ -50,64 +54,70 @@
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Spinner;
 import org.eclipse.swt.widgets.Text;
+import org.txm.searchengine.cqp.AbstractCqiClient;
 import org.txm.searchengine.cqp.clientExceptions.CqiClientException;
+import org.txm.searchengine.cqp.clientExceptions.UnexpectedAnswerException;
 import org.txm.searchengine.cqp.corpus.CQPCorpus;
+import org.txm.searchengine.cqp.corpus.CorpusManager;
 import org.txm.searchengine.cqp.corpus.Property;
 import org.txm.searchengine.cqp.corpus.StructuralUnit;
+import org.txm.searchengine.cqp.corpus.StructuralUnitProperty;
 import org.txm.searchengine.cqp.corpus.WordProperty;
+import org.txm.searchengine.cqp.serverException.CqiServerError;
 import org.txm.core.messages.TXMCoreMessages;
 import org.txm.rcp.IImageKeys;
 import org.txm.rcp.messages.TXMUIMessages;
 import org.txm.rcp.swt.GLComposite;
+
 // TODO: Auto-generated Javadoc
 /**
  * build a query with the help of simple questions @ author mdecorde.
  */
 public class QueryAssistDialog extends Dialog {
-
+	
 	/** The self. */
 	QueryAssistDialog self;
-
+	
 	/** The parent. */
 	Composite parent;
-
+	
 	/** The main panel. */
 	Composite mainPanel;
-
+	
 	/** The parent shell. */
 	Shell parentShell;
-
+	
 	/** The query. */
 	String query;
-
+	
 	/** The nbwords. */
 	int nbwords = 0;
-
+	
 	/** The wordfields. */
-	List<WordField> wordfields = new ArrayList<WordField>();
-
+	List<WordField> wordfields = new ArrayList<>();
+	
 	/** The linkfields. */
-	List<LinkField> linkfields = new ArrayList<LinkField>();
-
+	List<LinkField> linkfields = new ArrayList<>();
+	
 	/** The properties. */
 	List<WordProperty> properties;
-
+	
 	/** The cherche label. */
 	Label chercheLabel;
-
+	
 	/** The wordcontainer. */
 	Composite wordcontainer;
-
+	
 	private CQPCorpus corpus;
-
+	
 	private Combo structsCombo;
-
+	
 	private Button withinButton = null;
-
+	
 	private ScrolledComposite scrollComposite;
-
+	
 	private Spinner withinN;
-
+	
 	/**
 	 * Instantiates a new query assist dialog.
 	 *
@@ -121,12 +131,14 @@
 		this.corpus = corpus;
 		try {
 			properties = corpus.getOrderedProperties();
-		} catch (CqiClientException e) {
+		}
+		catch (CqiClientException e) {
 			org.txm.utils.logger.Log.printStackTrace(e);
 		}
 	}
-
-	/* (non-Javadoc)
+	
+	/*
+	 * (non-Javadoc)
 	 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
 	 */
 	@Override
@@ -135,8 +147,9 @@
 		newShell.setText(TXMUIMessages.queryAssistant);
 		newShell.setMinimumSize(500, 350);
 	}
-
-	/* (non-Javadoc)
+	
+	/*
+	 * (non-Javadoc)
 	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
 	 */
 	@Override
@@ -150,47 +163,49 @@
 			mainPanel.setLayout(mainlayout);
 			GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, true);
 			mainPanel.setLayoutData(gridData);
-
+			
 			// directory
 			chercheLabel = new Label(mainPanel, SWT.NONE);
 			chercheLabel.setAlignment(SWT.CENTER);
 			chercheLabel.setLayoutData(new GridData(GridData.BEGINNING, GridData.FILL, true, false, 1, 1));
 			chercheLabel.setText(TXMUIMessages.imLookingForColon);
 			
-			scrollComposite = new ScrolledComposite(mainPanel, SWT.V_SCROLL|SWT.H_SCROLL);
+			scrollComposite = new ScrolledComposite(mainPanel, SWT.V_SCROLL | SWT.H_SCROLL);
 			scrollComposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 2, 1));
-
+			
 			wordcontainer = new Composite(scrollComposite, SWT.NONE);
 			wordcontainer.setLayout(new GridLayout(1, false));
-
+			
 			scrollComposite.setContent(wordcontainer);
 			scrollComposite.setExpandVertical(true);
 			scrollComposite.setExpandHorizontal(true);
 			scrollComposite.addControlListener(new ControlAdapter() {
+				
 				@Override
 				public void controlResized(ControlEvent e) {
-					//Rectangle r = scrollComposite.getClientArea();
+					// Rectangle r = scrollComposite.getClientArea();
 					scrollComposite.setMinSize(wordcontainer.computeSize(SWT.DEFAULT, SWT.DEFAULT));
 				}
 			});
-
+			
 			addWordField();
-
+			
 			Composite withinComposite = new Composite(mainPanel, SWT.NONE);
 			withinComposite.setLayout(new GridLayout(3, false));
 			withinComposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false, 2, 1));
 			withinButton = new Button(withinComposite, SWT.CHECK);
-			withinButton.setText(TXMUIMessages.withinAContextOf); //"within structure: "
+			withinButton.setText(TXMUIMessages.withinAContextOf); // "within structure: "
 			withinButton.setToolTipText("Check to add structure contraint");
 			withinButton.addSelectionListener(new SelectionListener() {
+				
 				@Override
 				public void widgetSelected(SelectionEvent e) {
 					structsCombo.setEnabled(withinButton.getSelection());
 					withinN.setEnabled(withinButton.getSelection());
 				}
-
+				
 				@Override
-				public void widgetDefaultSelected(SelectionEvent e) { }
+				public void widgetDefaultSelected(SelectionEvent e) {}
 			});
 			
 			withinN = new Spinner(withinComposite, SWT.CHECK);
@@ -207,7 +222,7 @@
 			int iText = -1;
 			int iP = -1;
 			List<StructuralUnit> sus = corpus.getOrderedStructuralUnits();
-			for (int i = 0 ; i < sus.size() ; i++) {
+			for (int i = 0; i < sus.size(); i++) {
 				StructuralUnit su = sus.get(i);
 				if (su.getName().equals("txmcorpus")) continue;
 				structsCombo.add(su.getName());
@@ -217,16 +232,18 @@
 			}
 			if (structsCombo.getItemCount() > 0) {
 				if (iP >= 0) {
-					structsCombo.select(iP+1);
-				} else {
-					structsCombo.select(iText+1);
+					structsCombo.select(iP + 1);
 				}
+				else {
+					structsCombo.select(iText + 1);
+				}
 			}
-
+			
 			Button addwordButton = new Button(mainPanel, SWT.PUSH);
 			addwordButton.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
 			addwordButton.setText(TXMUIMessages.addAWord);
 			addwordButton.addSelectionListener(new SelectionListener() {
+				
 				@Override
 				public void widgetSelected(SelectionEvent e) {
 					if (nbwords > 0) addLinkField();
@@ -241,52 +258,52 @@
 					scrollComposite.setMinSize(wordcontainer.computeSize(r.width, SWT.DEFAULT));
 					updateShell();
 				}
-
+				
 				@Override
-				public void widgetDefaultSelected(SelectionEvent e) {
-				}
+				public void widgetDefaultSelected(SelectionEvent e) {}
 			});
-
-			//			Button removeWordButton = new Button(mainPanel, SWT.PUSH);
-			//			removeWordButton.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
-			//			removeWordButton.setText(TXMUIMessages.removeTheLastWord);
-			//			removeWordButton.addSelectionListener(new SelectionListener() {
-			//				@Override
-			//				public void widgetSelected(SelectionEvent e) {
-			//					if (nbwords > 1) {
-			//						removeWordField();
-			//						removeLinkField();
-			//						
-			//						parent.layout(true);
-			//						mainPanel.layout(true);
-			//						wordcontainer.layout(true);
-			//						scrollComposite.layout(true);
-			//						mainPanel.update();
-			//						wordcontainer.update();
-			//						Rectangle r = scrollComposite.getClientArea();
-			//						scrollComposite.setMinSize(wordcontainer.computeSize(r.width, SWT.DEFAULT));
-			//						updateShell();
-			//					}
-			//				}
+			
+			// Button removeWordButton = new Button(mainPanel, SWT.PUSH);
+			// removeWordButton.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
+			// removeWordButton.setText(TXMUIMessages.removeTheLastWord);
+			// removeWordButton.addSelectionListener(new SelectionListener() {
+			// @Override
+			// public void widgetSelected(SelectionEvent e) {
+			// if (nbwords > 1) {
+			// removeWordField();
+			// removeLinkField();
 			//
-			//				@Override
-			//				public void widgetDefaultSelected(SelectionEvent e) {
-			//				}
-			//			});
-
-		} catch (Exception e) {
+			// parent.layout(true);
+			// mainPanel.layout(true);
+			// wordcontainer.layout(true);
+			// scrollComposite.layout(true);
+			// mainPanel.update();
+			// wordcontainer.update();
+			// Rectangle r = scrollComposite.getClientArea();
+			// scrollComposite.setMinSize(wordcontainer.computeSize(r.width, SWT.DEFAULT));
+			// updateShell();
+			// }
+			// }
+			//
+			// @Override
+			// public void widgetDefaultSelected(SelectionEvent e) {
+			// }
+			// });
+			
+		}
+		catch (Exception e) {
 			org.txm.utils.logger.Log.printStackTrace(e);
 		}
 		return null;
 	}
-
+	
 	/**
 	 * Adds the link field.
 	 */
 	protected void addLinkField() {
 		linkfields.add(new LinkField(wordcontainer, SWT.NONE));
 	}
-
+	
 	/**
 	 * Adds the word field.
 	 */
@@ -297,35 +314,36 @@
 		gd.minimumWidth = 200;
 		wf.setLayoutData(gd);
 		wordfields.add(wf);
-
+		
 		wordcontainer.update();
 		mainPanel.update();
 	}
-
+	
 	/**
 	 * remove the last link field.
 	 */
 	protected void removeLinkField() {
 		if (linkfields.size() > 0) {
-			linkfields.remove(linkfields.size()-1).dispose();	
+			linkfields.remove(linkfields.size() - 1).dispose();
 		}
 	}
-
+	
 	/**
 	 * remove the last word field.
 	 */
 	private void removeWordField() {
 		if (nbwords == 0) return;
-
+		
 		nbwords--;
-
+		
 		wordfields.remove(nbwords).dispose();
-
+		
 		wordcontainer.update();
 		mainPanel.update();
 	}
-
-	/* (non-Javadoc)
+	
+	/*
+	 * (non-Javadoc)
 	 * @see org.eclipse.jface.dialogs.Dialog#okPressed()
 	 */
 	@Override
@@ -339,29 +357,29 @@
 			query += lf.getQuery();
 			query += wf.getQuery();
 		}
-
+		
 		if (withinButton != null && withinButton.getSelection() && structsCombo.getText().length() > 0) {
 			query += " within ";
 			
 			if (withinN.getSelection() > 1) {
-				query += ""+withinN.getSelection()+" "; //$NON-NLS-1$
+				query += "" + withinN.getSelection() + " "; //$NON-NLS-1$
 			}
 			
 			if (!structsCombo.getText().equals("<word>")) {
-				query += structsCombo.getText(); //$NON-NLS-1$
+				query += structsCombo.getText();
 			}
 		}
-
+		
 		super.okPressed();
 	}
-
+	
 	/**
 	 * Update shell.
 	 */
 	public void updateShell() {
 		parentShell.layout(true);
 	}
-
+	
 	/**
 	 * Gets the query.
 	 *
@@ -370,19 +388,19 @@
 	public String getQuery() {
 		return this.query;
 	}
-
+	
 	public class WordPropertyField extends GLComposite {
-
-
+		
+		
 		/** The prop combo. */
 		Combo propCombo;
-
+		
 		/** The test combo. */
 		Combo testCombo;
-
+		
 		/** The value t. */
-		Text valueT;
-
+		Combo valueT;
+		
 		/**
 		 * Instantiates a new word field.
 		 *
@@ -391,18 +409,28 @@
 		 * @param no the no
 		 */
 		public WordPropertyField(Composite parent, int style, int no) {
-			super(parent, style, ""+no);
-
+			super(parent, style, "" + no);
+			
 			this.getLayout().numColumns = 3;
-
+			
 			propCombo = new Combo(this, SWT.READ_ONLY | SWT.SINGLE);
 			propCombo.setToolTipText("Property to test");
 			if (properties != null) {
-				for (Property p : properties)
+				for (Property p : properties) {
 					propCombo.add(p.getName());
+				}
+				try {
+					for (StructuralUnitProperty p : corpus.getOrderedStructuralUnitProperties()) {
+						propCombo.add(p.getFullName());
+					}
+				}
+				catch (CqiClientException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
 				propCombo.select(0);
 			}
-
+			
 			testCombo = new Combo(this, SWT.READ_ONLY | SWT.SINGLE);
 			testCombo.setToolTipText("Test to do");
 			testCombo.add(TXMUIMessages.equalsTo);
@@ -411,32 +439,93 @@
 			testCombo.add(TXMUIMessages.contains);
 			testCombo.add(TXMUIMessages.isDifferentFrom);
 			testCombo.select(0);
-
-			valueT = new Text(this, SWT.SINGLE | SWT.BORDER);
+			
+			valueT = new Combo(this, SWT.SINGLE);
 			valueT.setToolTipText("The word property value");
 			GridData gdata = new GridData(GridData.FILL, GridData.FILL, false, false);
 			gdata.widthHint = 150;
 			gdata.minimumWidth = 150;
 			valueT.setLayoutData(gdata);
+			
+			propCombo.addSelectionListener(new SelectionListener() {
+				
+				@Override
+				public void widgetSelected(SelectionEvent e) {
+					updateAvailableValues();
+				}
+				
+				
+				
+				@Override
+				public void widgetDefaultSelected(SelectionEvent e) {}
+			});
+			
+			updateAvailableValues();
 		}
+		
+		private void updateAvailableValues() {
+			String p = propCombo.getText();
+			String[] items = null;
+			if (p.contains("_")) {
+				StructuralUnitProperty sup = corpus.getStructuralUnitProperty(p);
+				try {
+					if (sup.getNValues() > 1000) {
+						valueT.setItems(new String[0]);
+						return;
+					}
+					items = sup.getValuesAsStrings();
+				}
+				catch (Exception e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+			else {
+				try {
+					WordProperty prop = corpus.getProperty(p);
+					if (prop.getNValues() > 1000) {
+						valueT.setItems(new String[0]);
+						return;
+					}
+					items = prop.getValues();
+				}
+				catch (Exception e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+					
+				}
+			}
+			
+			if (items != null) {
+				valueT.setItems(items);
+				KeyStroke keys = KeyStroke.getInstance(SWT.CONTROL, SWT.SPACE);
+				new TXMAutoCompleteField(valueT, new ComboContentAdapter(), items, keys);
+			}
+			else {
+				valueT.setItems(new String[0]);
+			}
+		}
 	}
-
+	
 	/**
 	 * The Class WordField.
 	 */
 	public class WordField extends Composite {
-
-		ArrayList<QueryAssistDialog.WordPropertyField> propertyFields = new ArrayList<QueryAssistDialog.WordPropertyField>();
-//		Combo propertiesAllOrOne;
-
+		
+		ArrayList<QueryAssistDialog.WordPropertyField> propertyFields = new ArrayList<>();
+		// Combo propertiesAllOrOne;
+		
 		Button targetButton;
-
+		
 		Button removeButton;
+		
 		GLComposite propertiesFieldComposite;
+		
 		private Label titleL;
+		
 		private int no;
-
-
+		
+		
 		/**
 		 * Instantiates a new word field.
 		 *
@@ -448,60 +537,63 @@
 			super(parent, style);
 			this.no = no;
 			this.setLayout(new GridLayout(8, false));
-
+			
 			titleL = new Label(this, SWT.NONE);
-
+			
 			GridData datalayout = new GridData(GridData.FILL, GridData.CENTER, true, false);
 			titleL.setLayoutData(datalayout);
-
+			
 			GridData buttonLayout = new GridData(GridData.FILL, GridData.CENTER, false, false);
-			buttonLayout.widthHint=25;
-
+			buttonLayout.widthHint = 25;
+			
 			Button addPropertyButton = new Button(this, SWT.PUSH);
 			addPropertyButton.setLayoutData(buttonLayout);
 			addPropertyButton.setText("+");
 			addPropertyButton.setToolTipText("add a property test");
 			addPropertyButton.addSelectionListener(new SelectionListener() {
+				
 				@Override
 				public void widgetSelected(SelectionEvent e) {
 					addProperty();
 				}
-
+				
 				@Override
-				public void widgetDefaultSelected(SelectionEvent e) { }
+				public void widgetDefaultSelected(SelectionEvent e) {}
 			});
-
+			
 			Button removePropertyButton = new Button(this, SWT.PUSH);
 			removePropertyButton.setLayoutData(buttonLayout);
 			removePropertyButton.setText("-");
 			removePropertyButton.setToolTipText("remove the last property test");
 			removePropertyButton.addSelectionListener(new SelectionListener() {
+				
 				@Override
 				public void widgetSelected(SelectionEvent e) {
 					removeProperty();
 				}
-
+				
 				@Override
-				public void widgetDefaultSelected(SelectionEvent e) { }
+				public void widgetDefaultSelected(SelectionEvent e) {}
 			});
-
+			
 			propertiesFieldComposite = new GLComposite(this, SWT.NONE, "properties");
 			GridData propertiesvlayout = new GridData(GridData.FILL, GridData.CENTER, true, false);
 			propertiesFieldComposite.setLayoutData(propertiesvlayout);
 			propertiesFieldComposite.getLayout().numColumns = 2;
-
-//			propertiesAllOrOne = new Combo(this, SWT.SINGLE-SWT.READ_ONLY);
-//			propertiesAllOrOne.setToolTipText("ALL=all properties test must match / ONE=one property match is enough");
-//			propertiesAllOrOne.add("ALL");
-//			propertiesAllOrOne.add("ONE");
-//			propertiesAllOrOne.select(0);
-//			propertiesAllOrOne.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false));
-
+			
+			// propertiesAllOrOne = new Combo(this, SWT.SINGLE-SWT.READ_ONLY);
+			// propertiesAllOrOne.setToolTipText("ALL=all properties test must match / ONE=one property match is enough");
+			// propertiesAllOrOne.add("ALL");
+			// propertiesAllOrOne.add("ONE");
+			// propertiesAllOrOne.select(0);
+			// propertiesAllOrOne.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false));
+			
 			addProperty();
-
+			
 			targetButton = new Button(this, SWT.CHECK);
 			targetButton.setToolTipText("Check to target the word in the query");
 			targetButton.addSelectionListener(new SelectionListener() {
+				
 				@Override
 				public void widgetSelected(SelectionEvent e) {
 					if (targetButton.getSelection()) {
@@ -511,24 +603,24 @@
 						targetButton.setSelection(true);
 					}
 				}
-
+				
 				@Override
-				public void widgetDefaultSelected(SelectionEvent e) { }
+				public void widgetDefaultSelected(SelectionEvent e) {}
 			});
-
-
+			
+			
 			removeButton = new Button(this, SWT.PUSH);
 			removeButton.setImage(IImageKeys.getImage(IImageKeys.ACTION_DELETE));
 			removeButton.setToolTipText(TXMCoreMessages.common_delete);
 			removeButton.addSelectionListener(new SelectionListener() {
-
+				
 				@Override
 				public void widgetSelected(SelectionEvent e) {
 					if (nbwords < 2) return;
-
+					
 					int idx = QueryAssistDialog.this.wordfields.indexOf(WordField.this);
-					//					System.out.println("field: "+idx);
-					//					System.out.println(QueryAssistDialog.this.linkfields);
+					// System.out.println("field: "+idx);
+					// System.out.println(QueryAssistDialog.this.linkfields);
 					if (QueryAssistDialog.this.linkfields.size() > 0) {
 						if (idx > 0) idx--;
 						LinkField field = QueryAssistDialog.this.linkfields.remove(idx);
@@ -537,55 +629,57 @@
 					QueryAssistDialog.this.wordfields.remove(WordField.this);
 					QueryAssistDialog.this.nbwords--;
 					WordField.this.dispose();
-
+					
 					wordcontainer.update();
 					mainPanel.update();
-
+					
 					QueryAssistDialog.this.parent.layout(true);
 					QueryAssistDialog.this.mainPanel.layout(true);
 					QueryAssistDialog.this.wordcontainer.layout(true);
 					QueryAssistDialog.this.scrollComposite.layout(true);
 				}
-
+				
 				@Override
-				public void widgetDefaultSelected(SelectionEvent e) { }
+				public void widgetDefaultSelected(SelectionEvent e) {}
 			});
 		}
-
+		
 		private void addProperty() {
 			WordPropertyField pField = new WordPropertyField(propertiesFieldComposite, SWT.NONE, propertyFields.size());
 			pField.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false, 2, 1));
 			propertyFields.add(pField);
 			updateWidgets();
 		}
-
+		
 		private void removeProperty() {
 			if (propertyFields.size() > 0) {
-				WordPropertyField pField = propertyFields.remove(propertyFields.size()-1);
+				WordPropertyField pField = propertyFields.remove(propertyFields.size() - 1);
 				pField.dispose();
 			}
 			updateWidgets();
 		}
-
+		
 		private void updateWidgets() {
-//			propertiesAllOrOne.setEnabled(propertyFields.size() > 1);
-//			propertiesAllOrOne.setVisible(propertyFields.size() > 1);
-//			((GridData)propertiesAllOrOne.getLayoutData()).exclude = propertyFields.size() < 2;
+			// propertiesAllOrOne.setEnabled(propertyFields.size() > 1);
+			// propertiesAllOrOne.setVisible(propertyFields.size() > 1);
+			// ((GridData)propertiesAllOrOne.getLayoutData()).exclude = propertyFields.size() < 2;
 			if (propertyFields.size() == 0) {
 				titleL.setText(TXMUIMessages.aWord);
-			} else if (propertyFields.size() == 1) {
+			}
+			else if (propertyFields.size() == 1) {
 				titleL.setText(NLS.bind(TXMUIMessages.aWordWithItsProperty, no));
-			} else {
+			}
+			else {
 				titleL.setText(NLS.bind(TXMUIMessages.aWordWithItsProperties, no));
 			}
 			propertiesFieldComposite.layout();
-			//	this.layout(true);
-			//mainPanel.layout(true);
+			// this.layout(true);
+			// mainPanel.layout(true);
 			wordcontainer.layout();
 			wordcontainer.update();
-			//mainPanel.update();
+			// mainPanel.update();
 		}
-
+		
 		/**
 		 * Gets the query.
 		 *
@@ -597,18 +691,20 @@
 				query += "@";
 			}
 			query += "["; //$NON-NLS-1$
-
+			
 			int nField = 0;
 			for (WordPropertyField f : propertyFields) {
 				Combo propCombo = f.propCombo;
 				Combo testCombo = f.testCombo;
-				Text valueT = f.valueT;
+				Combo valueT = f.valueT;
 				if (nField > 0) {
-					//query += " "+(propertiesAllOrOne.getText().equals("ALL")?"&":"|")+" ";
+					// query += " "+(propertiesAllOrOne.getText().equals("ALL")?"&":"|")+" ";
 					query += " & ";
 				}
-
-				query += propCombo.getItem(propCombo.getSelectionIndex());
+				
+				String p = propCombo.getItem(propCombo.getSelectionIndex());
+				if (p.contains("_")) query += "_."; // structural properties must be prefixed with "_."
+				query += p;
 				if (testCombo.getSelectionIndex() == 0)// equals
 					query += " = \"" + valueT.getText().replace("\"", "\\\"") + "\""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
 				else if (testCombo.getSelectionIndex() == 1)// starts with
@@ -624,15 +720,15 @@
 			return query + "]"; //$NON-NLS-1$
 		}
 	}
-
+	
 	/**
 	 * The Class LinkField.
 	 */
 	public class LinkField extends Composite {
-
+		
 		/** The link combo. */
 		Combo linkCombo;
-
+		
 		/**
 		 * Instantiates a new link field.
 		 *
@@ -642,15 +738,15 @@
 		public LinkField(Composite parent, int style) {
 			super(parent, style);
 			this.setLayout(new RowLayout());
-
+			
 			linkCombo = new Combo(this, SWT.READ_ONLY | SWT.SINGLE);
 			linkCombo.add(TXMUIMessages.followedBy);
 			linkCombo.add(TXMUIMessages.separatedByAtLeast0Word);
 			linkCombo.add(TXMUIMessages.separatedByAtLeast1Word);
-
+			
 			linkCombo.select(0);
 		}
-
+		
 		/**
 		 * Gets the query.
 		 *
@@ -666,4 +762,4 @@
 			return ""; //$NON-NLS-1$
 		}
 	}
-}
\ No newline at end of file
+}
