Index: tmp/org.txm.utils/src/org/txm/utils/i18n/LangFormater.java
===================================================================
--- tmp/org.txm.utils/src/org/txm/utils/i18n/LangFormater.java	(revision 2936)
+++ tmp/org.txm.utils/src/org/txm/utils/i18n/LangFormater.java	(revision 2937)
@@ -88,6 +88,8 @@
 
 		if (lang.startsWith("fr") || lang.startsWith("FR")) //$NON-NLS-1$ //$NON-NLS-2$
 			return (FRNoSpaceBefore);
+		else if (lang.startsWith("fro") || lang.startsWith("FRO")) //$NON-NLS-1$ //$NON-NLS-2$
+			return (FRONoSpaceBefore);
 		else if (lang.startsWith("en") || lang.startsWith("EN") //$NON-NLS-1$ //$NON-NLS-2$
 				|| lang.startsWith("us") || lang.startsWith("US")) //$NON-NLS-1$ //$NON-NLS-2$
 			return (ENNoSpaceBefore);
@@ -106,6 +108,8 @@
 
 		if (lang.startsWith("fr") || lang.startsWith("FR")) //$NON-NLS-1$ //$NON-NLS-2$
 			return (FRNoSpaceAfter);
+		else if (lang.startsWith("fro") || lang.startsWith("FRO")) //$NON-NLS-1$ //$NON-NLS-2$
+			return (FRONoSpaceAfter);
 		else if (lang.startsWith("en") || lang.startsWith("EN") //$NON-NLS-1$ //$NON-NLS-2$
 				|| lang.startsWith("us") || lang.startsWith("US")) //$NON-NLS-1$ //$NON-NLS-2$
 			return (ENNoSpaceAfter);
Index: tmp/org.txm.tigersearch.rcp/src/org/txm/tigersearch/commands/ExportCorpusAsCONNLU.java
===================================================================
--- tmp/org.txm.tigersearch.rcp/src/org/txm/tigersearch/commands/ExportCorpusAsCONNLU.java	(revision 2936)
+++ tmp/org.txm.tigersearch.rcp/src/org/txm/tigersearch/commands/ExportCorpusAsCONNLU.java	(revision 2937)
@@ -32,6 +32,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 
 import org.apache.commons.lang.StringUtils;
 import org.eclipse.core.commands.AbstractHandler;
@@ -48,7 +49,9 @@
 import org.txm.searchengine.cqp.corpus.CQPCorpus;
 import org.txm.searchengine.cqp.corpus.MainCorpus;
 import org.txm.searchengine.cqp.corpus.WordProperty;
+import org.txm.searchengine.cqp.corpus.query.CQLQuery;
 import org.txm.searchengine.cqp.serverException.CqiServerError;
+import org.txm.utils.i18n.LangFormater;
 import org.txm.utils.io.IOUtils;
 import org.txm.utils.logger.Log;
 
@@ -70,12 +73,22 @@
 	@Option(name = "propertiesPrefix", usage = "optional prefix for the properties to create", widget = "String", required = true, def = "ud")
 	String propertiesPrefix;
 	
+	@Option(name = "separator", usage = "Options", widget = "Separator", required = true, def = "options")
+	Boolean separator = false;
+	
 	// @Option(name = "useUDForms", usage = "use the ud form property instead of CQP 'word' property", widget = "Boolean", required = true, def = "true")
 	Boolean useUDForms = true;
 	
+	
 	// @Option(name = "transfertAllWords", usage = "Transfert word not initially in the Connlu corpus", widget = "Boolean", required = true, def = "true")
 	Boolean transfertAllWords = true;
 	
+	@Option(name = "insertNoSpaceAfter", usage = "Insert the NoSpaceAfter misc property if not initially in the Connlu corpus", widget = "Boolean", required = true, def = "true")
+	Boolean insertNoSpaceAfter = true;
+	
+	@Option(name = "insertParagraphs", usage = "Insert paragraph marks in the Connlu corpus", widget = "Boolean", required = true, def = "true")
+	Boolean insertParagraphs = false;
+	
 	// @Option(name = "detectGap", usage = "Insert gap comment using the CQP 'gap' property", widget = "Boolean", required = true, def = "true")
 	Boolean detectGap = false;
 	
@@ -91,6 +104,15 @@
 	@Option(name = "xposCorrPropertyName", usage = "optional CQP property to fix the missing 'xpos' ud property", widget = "String", required = false, def = "")
 	String xposCorrPropertyName;
 	
+	@Option(name = "separator2", usage = "Options", widget = "Separator", required = true, def = "sentence fix options")
+	Boolean separator2 = false;
+	
+	// @Option(name = "punctStrong", usage = "optional prefix for the properties to create", widget = "String", required = true, def = "[?!\\.]")
+	// String punctStrong;
+	
+	@Option(name = "openingPunct", usage = "optional prefix for the properties to create", widget = "String", required = true, def = "[\\-–«‘“\\(]")
+	String openingPunct;
+	
 	public static String[] propNames = { "id", "form", "lemma", "upos", "xpos", "feats", "head", "deprel", "deps", "misc" };
 	
 	/*
@@ -108,7 +130,10 @@
 			return null;
 		}
 		
-		ParametersDialog.open(this);
+		if (!ParametersDialog.open(this)) {
+			return null;
+		}
+		
 		connluResultDirectory.mkdirs();
 		if (connluResultDirectory == null || !connluResultDirectory.exists() || !connluResultDirectory.isDirectory()) {
 			Log.warning("Error: connlu result directory does not exists: " + connluResultDirectory);
@@ -119,7 +144,9 @@
 		MainCorpus mainCorpus = corpus.getMainCorpus();
 		
 		try {
-			return exportAnnotationsAsCorpus(mainCorpus, connluResultDirectory, propertiesPrefix, formCorrPropertyName, lemmaCorrPropertyName, uposCorrPropertyName, xposCorrPropertyName, detectGap);
+			return exportAnnotationsAsCorpus(mainCorpus, connluResultDirectory, propertiesPrefix, openingPunct,
+					formCorrPropertyName, lemmaCorrPropertyName, uposCorrPropertyName, xposCorrPropertyName,
+					detectGap, insertParagraphs, insertNoSpaceAfter);
 		}
 		catch (Exception e) {
 			Log.warning(e);
@@ -144,8 +171,8 @@
 	 * @throws UnexpectedAnswerException
 	 * @throws InvalidCqpIdException
 	 */
-	public static int exportAnnotationsAsCorpus(MainCorpus mainCorpus, File conlluResultDirectory, String prefix, String formCorrPropertyName, String lemmaCorrPropertyName,
-			String uposCorrPropertyName, String xposCorrPropertyName, boolean detectGap) throws UnexpectedAnswerException,
+	public static int exportAnnotationsAsCorpus(MainCorpus mainCorpus, File conlluResultDirectory, String prefix, String openingPunct, String formCorrPropertyName, String lemmaCorrPropertyName,
+			String uposCorrPropertyName, String xposCorrPropertyName, boolean detectGap, boolean insertParagraphs, boolean insertNoSpaceAfter) throws UnexpectedAnswerException,
 			IOException,
 			CqiServerError,
 			CqiClientException, InvalidCqpIdException {
@@ -161,6 +188,9 @@
 		int[] start_limits = mainCorpus.getTextStartLimits();
 		int[] end_limits = mainCorpus.getTextEndLimits();
 		
+		HashSet<String> beforeSpacesRules = new HashSet<>(LangFormater.getNoSpaceBefore(mainCorpus.getLang()));
+		HashSet<String> afterSpacesRules = new HashSet<>(LangFormater.getNoSpaceAfter(mainCorpus.getLang()));
+		
 		for (String p : propNames) {
 			WordProperty wp = mainCorpus.getProperty(prefix + p);
 			if (wp == null) {
@@ -182,37 +212,75 @@
 			// Get UD properties
 			WordProperty wp;
 			wp = mainCorpus.getProperty(prefix + "id");
-			String[] idValues = CQPSearchEngine.getCqiClient().cpos2Str(wp.getQualifiedName(), positions);
+			String[] tmpValues = CQPSearchEngine.getCqiClient().cpos2Str(wp.getQualifiedName(), positions);
+			int[] idValues = new int[tmpValues.length];
+			for (int iId = 0; iId < tmpValues.length; iId++) {
+				if (tmpValues[iId].length() > 0 && !tmpValues[iId].equals("_") && !tmpValues[iId].equals("__UNDEF__")) {
+					idValues[iId] = Integer.parseInt(tmpValues[iId]);
+				}
+				else {
+					idValues[iId] = 0;
+				}
+			}
+			tmpValues = null;
 			
 			WordProperty formWordProperty = mainCorpus.getProperty(prefix + "form");
 			String[] formValues = CQPSearchEngine.getCqiClient().cpos2Str(formWordProperty.getQualifiedName(), positions);
+			fixUNDEFValues(formValues);
 			
 			wp = mainCorpus.getProperty(prefix + "lemma");
 			String[] lemmaValues = CQPSearchEngine.getCqiClient().cpos2Str(wp.getQualifiedName(), positions);
+			fixUNDEFValues(lemmaValues);
 			
 			wp = mainCorpus.getProperty(prefix + "upos");
 			String[] uposValues = CQPSearchEngine.getCqiClient().cpos2Str(wp.getQualifiedName(), positions);
+			fixUNDEFValues(uposValues);
 			
 			wp = mainCorpus.getProperty(prefix + "xpos");
 			String[] xposValues = CQPSearchEngine.getCqiClient().cpos2Str(wp.getQualifiedName(), positions);
+			fixUNDEFValues(xposValues);
 			
 			wp = mainCorpus.getProperty(prefix + "feats");
 			String[] featsValues = CQPSearchEngine.getCqiClient().cpos2Str(wp.getQualifiedName(), positions);
+			fixUNDEFValues(featsValues);
 			
 			wp = mainCorpus.getProperty(prefix + "head");
-			String[] headValues = CQPSearchEngine.getCqiClient().cpos2Str(wp.getQualifiedName(), positions);
+			// String[] headValues = CQPSearchEngine.getCqiClient().cpos2Str(wp.getQualifiedName(), positions);
+			tmpValues = CQPSearchEngine.getCqiClient().cpos2Str(wp.getQualifiedName(), positions);
+			int[] headValues = new int[tmpValues.length];
+			for (int iId = 0; iId < tmpValues.length; iId++) {
+				if (tmpValues[iId].length() > 0 && !tmpValues[iId].equals("_") && !tmpValues[iId].equals("__UNDEF__")) {
+					headValues[iId] = Integer.parseInt(tmpValues[iId]);
+				}
+				else {
+					headValues[iId] = -1;
+				}
+			}
+			tmpValues = null;
 			
 			wp = mainCorpus.getProperty(prefix + "deprel");
 			String[] deprelValues = CQPSearchEngine.getCqiClient().cpos2Str(wp.getQualifiedName(), positions);
+			fixUNDEFValues(deprelValues);
 			
 			wp = mainCorpus.getProperty(prefix + "deps");
 			String[] depsValues = CQPSearchEngine.getCqiClient().cpos2Str(wp.getQualifiedName(), positions);
+			fixUNDEFValues(depsValues);
 			
 			wp = mainCorpus.getProperty(prefix + "misc");
 			String[] miscValues = CQPSearchEngine.getCqiClient().cpos2Str(wp.getQualifiedName(), positions);
-			// print UD sentences
+			fixUNDEFValues(miscValues);
 			
+			HashSet<Integer> paragraphsStartPositions = new HashSet<>();
+			if (insertParagraphs) {
+				for (int position : mainCorpus.query(new CQLQuery("<p> [_.text_id=\"" + textIds[iText] + "\"]"), "textParagraphPositions", false).getStarts()) {
+					paragraphsStartPositions.add(position);
+				}
+			}
 			
+			HashMap<Integer, String> sentidStartPositions = getNonUNDEFPositionsAndValues(mainCorpus, "ud-sentid");
+			HashMap<Integer, String> newdocidStartPositions = getNonUNDEFPositionsAndValues(mainCorpus, "ud-newdocid");
+			
+			
 			// build sentence, first pass using UD word sentence positions
 			ArrayList<ArrayList<Integer>> sentences = new ArrayList<>();
 			ArrayList<Integer> tmpSentence = new ArrayList<>();
@@ -220,7 +288,7 @@
 				// System.out.println("p=" + p + " id=" + idValues[p] + " form=" + formValues[p] + " lemma=" + lemmaValues[p] + " upos=" + uposValues[p] + " xpos=" + xposValues[p] + " feats="
 				// + featsValues[p] + " head="
 				// + headValues[p] + " deprel=" + deprelValues[p] + " deps=" + depsValues[p] + " misc=" + miscValues[p]);
-				if (idValues[p].equals("1")) {
+				if (sentidStartPositions.containsKey(p)) { // new ud sentence
 					
 					if (tmpSentence.size() > 0) {
 						sentences.add(new ArrayList<>(tmpSentence));
@@ -239,6 +307,50 @@
 			
 			// fixing sentences
 			for (int s = 0; s < sentences.size(); s++) {
+				
+				ArrayList<Integer> sentence = sentences.get(s);
+				int max = -1;
+				int imax = 0;
+				for (int ip = 0; ip < sentence.size(); ip++) {
+					int p = sentence.get(ip);
+					if (max < idValues[p]) {
+						max = idValues[p];
+						imax = ip;
+					}
+				}
+				
+				ArrayList<Integer> newSentence = new ArrayList<>();
+				for (int ip = imax + 1; ip < sentence.size(); ip++) {
+					newSentence.add(sentence.get(ip));
+					sentence.remove(ip);
+					ip--;
+				}
+				if (newSentence.size() == 1) { // the new sentence size is 1, resinsert it
+					sentence.addAll(newSentence);
+					newSentence.clear();
+				}
+				if (newSentence.size() > 0) {
+					System.out.println("INSERT " + newSentence);
+					sentences.add(s + 1, newSentence);
+				}
+			}
+			
+			// fixing sentences
+			for (int s = 0; s < sentences.size(); s++) {
+				
+				ArrayList<Integer> sentence = sentences.get(s);
+				if (s > 0 && formValues[sentence.get(0)].matches(openingPunct)) {
+					System.out.println("FIXING: first position " + formValues[sentence.get(0)] + "in " + s);
+					int p = sentence.remove(0);
+					sentences.get(s - 1).add(p);
+				}
+				
+				if (s + 1 < sentences.size() && formValues[sentence.get(sentence.size() - 1)].matches(openingPunct)) {
+					System.out.println("FIXING: last position " + formValues[sentence.get(sentence.size() - 1)] + "in " + s);
+					int p = sentence.remove(sentence.size() - 1);
+					sentences.get(s + 1).add(0, p);
+				}
+				
 				// int c = 0;
 				// ArrayList<Integer> sentence = sentences.get(s);
 				// for (int ip = 0 ; ip < sentence.size() ; ip++) {
@@ -263,27 +375,28 @@
 				ArrayList<Integer> sentence = sentences.get(iSentence);
 				
 				int[] sentencePositions = new int[sentence.size()];
-				for (int p = 0; p < sentence.size(); p++)
+				for (int p = 0; p < sentence.size(); p++) {
 					sentencePositions[p] = sentence.get(p);
+				}
 				
 				// get CQP values fixing "form", "lemma", "upos", "xpos", "feats", "head", "deprel", "deps"
 				String[] ids = CQPSearchEngine.getCqiClient().cpos2Str(mainCorpus.getProperty("id").getQualifiedName(), sentencePositions);
 				
 				String[] words = null;
 				if (formCorrPropertyName != null && formCorrPropertyName.length() > 0) {
-					words = CQPSearchEngine.getCqiClient().cpos2Str(mainCorpus.getProperty(formCorrPropertyName).getQualifiedName(), sentencePositions);
+					words = getDefaultValues(mainCorpus, formCorrPropertyName, sentencePositions);
 				}
 				String[] lemmas = null;
 				if (lemmaCorrPropertyName != null && lemmaCorrPropertyName.length() > 0) {
-					lemmas = CQPSearchEngine.getCqiClient().cpos2Str(mainCorpus.getProperty(lemmaCorrPropertyName).getQualifiedName(), sentencePositions);
+					lemmas = getDefaultValues(mainCorpus, lemmaCorrPropertyName, sentencePositions);
 				}
 				String[] upos = null;
 				if (uposCorrPropertyName != null && uposCorrPropertyName.length() > 0) {
-					upos = CQPSearchEngine.getCqiClient().cpos2Str(mainCorpus.getProperty(uposCorrPropertyName).getQualifiedName(), sentencePositions);
+					upos = getDefaultValues(mainCorpus, uposCorrPropertyName, sentencePositions);
 				}
 				String[] xpos = null;
 				if (xposCorrPropertyName != null && xposCorrPropertyName.length() > 0) {
-					xpos = CQPSearchEngine.getCqiClient().cpos2Str(mainCorpus.getProperty(xposCorrPropertyName).getQualifiedName(), sentencePositions);
+					xpos = getDefaultValues(mainCorpus, xposCorrPropertyName, sentencePositions);
 				}
 				
 				// String[] feats = CQPSearchEngine.getCqiClient().cpos2Str(mainCorpus.getProperty(featsCorrPropertyName).getQualifiedName(), sentencePositions);
@@ -291,50 +404,59 @@
 				// String[] deprel = CQPSearchEngine.getCqiClient().cpos2Str(mainCorpus.getProperty(deprelCorrPropertyName).getQualifiedName(), sentencePositions);
 				// String[] deps = CQPSearchEngine.getCqiClient().cpos2Str(mainCorpus.getProperty(deprelCorrPropertyName).getQualifiedName(), sentencePositions);
 				
-				HashMap<String, String> sentIds = new HashMap<>();
+				HashMap<Integer, Integer> sentIds = new HashMap<>();
 				for (int ip = 0; ip < sentence.size(); ip++) {
 					int p = sentence.get(ip);
 					
-					if (!idValues[p].equals("__UNDEF__")) { // store "old id -> new id"
-						sentIds.put(idValues[p], "" + (ip + 1)); // from 1 to N
+					if (idValues[p] != 0) { // store "old id -> new id"
+						sentIds.put(idValues[p], (ip + 1)); // from 1 to N
 					}
 					
 					// new word
-					if (miscValues[p].equals("__UNDEF__")) {
+					if (miscValues[p].equals("_")) {
 						miscValues[p] = "XmlId=" + ids[ip];
 					}
 					
 					// { "id", "form", "lemma", "upos", "xpos", "feats", "head", "deprel", "deps", "misc" };
-					if (words != null && formValues[p].equals("__UNDEF__")) {
+					if (words != null && formValues[p].equals("_")) {
 						formValues[p] = words[ip];
 					}
-					if (lemmas != null && lemmaValues[p].equals("__UNDEF__")) {
+					if (lemmas != null && lemmaValues[p].equals("_")) {
 						lemmaValues[p] = lemmas[ip];
 					}
-					if (upos != null && uposValues[p].equals("__UNDEF__")) {
+					if (upos != null && uposValues[p].equals("_")) {
 						uposValues[p] = upos[ip];
 					}
-					if (xpos != null && xposValues[p].equals("__UNDEF__")) {
+					if (xpos != null && xposValues[p].equals("_")) {
 						xposValues[p] = xpos[ip];
 					}
+					
+					if (insertNoSpaceAfter) { // inserttino activated
+						if (!miscValues[p].contains("SpaceAfter=")) { // only update if not present
+							if (afterSpacesRules.contains(formValues[p])) {
+								miscValues[p] += " SpaceAfter=Yes";
+							}
+							else if (formValues.length < p + 1 && beforeSpacesRules.contains(formValues[p + 1])) {
+								miscValues[p] += " SpaceAfter=Yes";
+							}
+						}
+					}
 				}
 				
 				// fixing head and set missing head to 0 and root
 				for (int ip = 0; ip < sentence.size(); ip++) {
 					int p = sentence.get(ip);
 					
-					
-					
 					// fixing id value
-					idValues[p] = "" + (ip + 1);  // from 1 to N
+					idValues[p] = (ip + 1);  // from 1 to N
 					
 					// fixing head values
 					if (sentIds.containsKey(headValues[p])) {
 						headValues[p] = sentIds.get(headValues[p]);
 					}
 					else { // new word, set to default values
-						headValues[p] = "0";
-						deprelValues[p] = "root";
+						headValues[p] = -1;
+						deprelValues[p] = "_";
 						depsValues[p] = "_";
 					}
 				}
@@ -343,6 +465,9 @@
 			// writing sentences
 			File resultConlluFile = new File(conlluResultDirectory, textIds[iText] + ".conllu");
 			PrintWriter writer = IOUtils.getWriter(resultConlluFile);
+			
+			int iParagraph = 1;
+			
 			for (int iSentence = 0; iSentence < sentences.size(); iSentence++) {
 				ArrayList<Integer> sentence = sentences.get(iSentence);
 				
@@ -355,19 +480,43 @@
 					gap = CQPSearchEngine.getCqiClient().cpos2Str(mainCorpus.getProperty("gap").getQualifiedName(), sentencePositions);
 				}
 				
-				String[] tokens = new String[sentences.size()];
+				
+				
+				String[] tokens = new String[sentence.size()];
 				for (int ip = 0; ip < sentence.size(); ip++) {
 					tokens[ip] = formValues[sentence.get(ip)];
 				}
 				
-				writer.println("# text = " + StringUtils.join(tokens, " "));
-				writer.println("# newdoc id = " + textIds[iText]);
-				writer.println("# sent_id = " + (iSentence + 1));
+				if (insertNoSpaceAfter) {
+					writer.println("# text = " + LangFormater.format(StringUtils.join(tokens, " "), mainCorpus.getLang()));
+				}
+				else {
+					writer.println("# text = " + StringUtils.join(tokens, " "));
+				}
 				
+				if (newdocidStartPositions.containsKey(sentence.get(0))) {
+					writer.println("# newdoc id = " + newdocidStartPositions.get(sentence.get(0)));
+				}
+				else {
+					writer.println("# newdoc id = " + textIds[iText]);
+				}
+				
+				if (sentidStartPositions.containsKey(sentence.get(0))) {
+					writer.println("# sent_id = " + sentidStartPositions.get(sentence.get(0)));
+				}
+				else {
+					writer.println("# sent_id = " + textIds[iText] + "-" + (iSentence + 1) + ".new");
+				}
+				
+				
+				if (paragraphsStartPositions.contains(sentence.get(0))) { // paragraphsStartPositions is empty if the injectParagraph option is not set
+					writer.println("# newpar id = " + iParagraph);
+					iParagraph++;
+				}
+				
 				for (int p : sentence) {
 					
 					if (gap != null && gap[p] != null) writer.println("# gap");
-					
 					// { "id", "form", "lemma", "upos", "xpos", "feats", "head", "deprel", "deps", "misc" };
 					writer.println(idValues[p] + "\t" + formValues[p] + "\t" + lemmaValues[p] + "\t" + uposValues[p]
 							+ "\t" + xposValues[p] + "\t" + featsValues[p] + "\t" + headValues[p] + "\t" + deprelValues[p]
@@ -378,6 +527,7 @@
 			}
 			writer.close();
 			
+			System.out.println(" Text done: " + resultConlluFile);
 			numberOfTextsWritten++;
 		}
 		
@@ -387,4 +537,38 @@
 		
 		return numberOfWordsWritten;
 	}
+	
+	private static String[] getDefaultValues(MainCorpus mainCorpus, String property, int[] positions) throws UnexpectedAnswerException, IOException, CqiServerError, CqiClientException {
+		String[] upos = CQPSearchEngine.getCqiClient().cpos2Str(mainCorpus.getProperty(property).getQualifiedName(), positions);
+		for (int iupos = 0; iupos < upos.length; iupos++) { // recode the || CQP multiple values to ud multiple values
+			if (upos[iupos].length() > 2 && upos[iupos].startsWith("|") && upos[iupos].endsWith("|")) {
+				upos[iupos] = upos[iupos].substring(1, upos[iupos].length() - 1);
+			}
+		}
+		
+		return upos;
+	}
+	
+	private static HashMap<Integer, String> getNonUNDEFPositionsAndValues(MainCorpus mainCorpus, String property) throws UnexpectedAnswerException, IOException, CqiServerError, CqiClientException {
+		HashMap<Integer, String> sentidStartPositions = new HashMap<>();
+		int[] ids = CQPSearchEngine.getCqiClient().regex2Id(mainCorpus.getProperty(property).getQualifiedName(), "(?!__UNDEF__).+");
+		String[] strs = CQPSearchEngine.getCqiClient().id2Str(mainCorpus.getProperty(property).getQualifiedName(), ids);
+		for (int iId = 0; iId < ids.length; iId++) {
+			int id = ids[iId];
+			int[] pp = CQPSearchEngine.getCqiClient().id2Cpos(mainCorpus.getProperty(property).getQualifiedName(), id);
+			for (int p : pp) {
+				sentidStartPositions.put(p, strs[iId]);
+			}
+		}
+		
+		return sentidStartPositions;
+	}
+	
+	private static void fixUNDEFValues(String[] values) {
+		for (int i = 0; i < values.length; i++) {
+			if (values[i].equals("__UNDEF__") || values[i].equals("")) {
+				values[i] = "_";
+			}
+		}
+	}
 }
Index: tmp/org.txm.tigersearch.rcp/src/org/txm/tigersearch/commands/ImportCONNLUAnnotations.java
===================================================================
--- tmp/org.txm.tigersearch.rcp/src/org/txm/tigersearch/commands/ImportCONNLUAnnotations.java	(revision 2936)
+++ tmp/org.txm.tigersearch.rcp/src/org/txm/tigersearch/commands/ImportCONNLUAnnotations.java	(revision 2937)
@@ -88,7 +88,9 @@
 			return null;
 		}
 		
-		ParametersDialog.open(this);
+		if (!ParametersDialog.open(this)) {
+			return null;
+		}
 		if (connluDirectory == null || !connluDirectory.exists() || !connluDirectory.isDirectory() || connluDirectory.listFiles().length == 0) {
 			Log.warning("Error: connlu directory is empty: " + connluDirectory);
 			return null;
@@ -158,13 +160,34 @@
 			
 			int nWords2 = 0;
 			int nLine = 0;
+			String sent_id = null;
+			String newpar_id = null;
+			String newdoc_id = null;
 			while (line != null) {
 				nLine++;
-				if (line.startsWith("#") || line.length() == 0) {
+				if (line.length() == 0) {
 					line = reader.readLine();
 					continue; // comment
 				}
 				
+				if (line.startsWith("#")) {
+					if (line.startsWith("# sent_id = ")) {
+						sent_id = line.substring(12).trim();
+					}
+					else if (line.startsWith("# newdoc id = ")) {
+						newdoc_id = line.substring(14).trim();
+					}
+					else if (line.startsWith("# newpar id = ")) {
+						newpar_id = line.substring(14).trim();
+					}
+					else {
+						// nothing for now
+					}
+					
+					line = reader.readLine();
+					continue; // comment
+				}
+				
 				String[] split = line.split("\t", 10);
 				if (split.length < 10) {
 					Log.warning("Error: line " + nLine + " : " + line + " -> " + Arrays.toString(split) + " len=" + split.length);
@@ -188,7 +211,18 @@
 				for (int i = 0; i < split.length; i++) {
 					properties.put("#" + propertiesPrefix + propNames[i], split[i]); // add the property name using the prefix ; XML-TXM types are prefixed with '#'
 				}
-				
+				if (sent_id != null) {
+					properties.put("#ud-sentid", sent_id);
+					sent_id = null;
+				}
+				if (newdoc_id != null) {
+					properties.put("#ud-newdocid", newdoc_id);
+					newdoc_id = null;
+				}
+				if (newpar_id != null) {
+					properties.put("#ud-newparid", newpar_id);
+					newpar_id = null;
+				}
 				processor.addProperty(id, properties);
 				nWords2++;
 				line = reader.readLine();
Index: tmp/org.txm.core/src/java/org/txm/importer/StaxIdentityParser.java
===================================================================
--- tmp/org.txm.core/src/java/org/txm/importer/StaxIdentityParser.java	(revision 2936)
+++ tmp/org.txm.core/src/java/org/txm/importer/StaxIdentityParser.java	(revision 2937)
@@ -15,31 +15,42 @@
 import javax.xml.stream.XMLStreamWriter;
 
 public class StaxIdentityParser {
+	
 	/** The input */
 	protected URL inputurl;
+	
 	protected InputStream inputData;
+	
 	protected XMLInputFactory factory;
+	
 	protected XMLStreamReader parser;
-
+	
 	/** The output. */
 	protected XMLOutputFactory outfactory = XMLOutputFactory.newInstance();
+	
 	protected BufferedOutputStream output;
+	
 	protected XMLStreamWriter writer;
-
+	
 	public static String TXMNS = "http://textometrie.org/1.0";
+	
 	public static String TXM = "txm";
+	
 	public static String TEINS = "http://www.tei-c.org/ns/1.0";
+	
 	public static String TEI = "tei";
+	
 	protected static PersonalNamespaceContext Nscontext = new PersonalNamespaceContext();
-
-	//protected StringBuilder currentXPath = new StringBuilder("/")
+	
+	// protected StringBuilder currentXPath = new StringBuilder("/")
 	protected String localname;
+	
 	int processingXInclude = 0;
-
+	
 	public StaxIdentityParser(File infile) throws IOException, XMLStreamException {
 		this(infile.toURI().toURL());
 	}
-
+	
 	public StaxIdentityParser(URL inputurl) throws IOException, XMLStreamException {
 		this.inputurl = inputurl;
 		this.inputData = inputurl.openStream();
@@ -48,7 +59,7 @@
 	}
 	
 	/**
-	 * Helper method to get an attribute value 
+	 * Helper method to get an attribute value
 	 * 
 	 * @param name the attribute name
 	 * @return the value if any
@@ -57,7 +68,7 @@
 		if (name == null) return null;
 		
 		int c = parser.getAttributeCount();
-		for (int i = 0 ; i < c ; i++) {
+		for (int i = 0; i < c; i++) {
 			if (name.equals(parser.getAttributeLocalName(i))) {
 				return parser.getAttributeValue(i);
 			}
@@ -65,26 +76,26 @@
 		
 		return null;
 	}
-
+	
 	protected void before() {
-
+		
 	}
-
+	
 	protected void after() throws XMLStreamException, IOException {
 		factory = null;
-		if (parser !=null) parser.close();
+		if (parser != null) parser.close();
 		writer.flush();
 		if (writer != null) writer.close();
 		if (inputData != null) inputData.close();
 		writer = null;
 		parser = null;
 	}
-
+	
 	protected void closeForError() throws XMLStreamException, IOException {
-		if (parser !=null) parser.close();
+		if (parser != null) parser.close();
 		if (inputData != null) inputData.close();
 	}
-
+	
 	/**
 	 * Creates the output.
 	 *
@@ -97,23 +108,23 @@
 				writer.close();
 			if (output != null) // process from a file
 				output.close();
-
-			output = new BufferedOutputStream(new FileOutputStream(f), 16*1024);
-
-			writer = outfactory.createXMLStreamWriter(output, "UTF-8");//create a new file
+			
+			output = new BufferedOutputStream(new FileOutputStream(f), 16 * 1024);
+			
+			writer = outfactory.createXMLStreamWriter(output, "UTF-8");// create a new file
 			writer.setNamespaceContext(Nscontext);
 			return true;
-		} catch (Exception e) {
-			System.out.println("Error: create output of "+f+": "+e);
+		}
+		catch (Exception e) {
+			System.out.println("Error: create output of " + f + ": " + e);
 			return false;
 		}
 	}
-
-	public boolean process(File outfile) throws XMLStreamException, IOException
-	{
+	
+	public boolean process(File outfile) throws XMLStreamException, IOException {
 		if (!createOutput(outfile))
 			return false;
-
+		
 		writer.writeStartDocument("UTF-8", "1.0");
 		writer.writeCharacters("\n");
 		boolean ret = process(writer);
@@ -121,255 +132,271 @@
 			writer.close();
 		}
 		if (output != null) {
-			try {output.close();} catch(Exception e){System.out.println("output excep: "+e);}
+			try {
+				output.close();
+			}
+			catch (Exception e) {
+				System.out.println("output excep: " + e);
+			}
 		}
-
+		
 		if (parser != null) {
-			try {parser.close();} catch(Exception e){System.out.println("parser excep: "+e);}
+			try {
+				parser.close();
+			}
+			catch (Exception e) {
+				System.out.println("parser excep: " + e);
+			}
 		}
 		
 		if (inputData != null) {
-			try {inputData.close();} catch(Exception e){System.out.println("inputData excep: "+e);}
+			try {
+				inputData.close();
+			}
+			catch (Exception e) {
+				System.out.println("inputData excep: " + e);
+			}
 		}
-
+		
 		return ret;
 	}
-
+	
 	public final static String SLASH = "/";
-	public boolean process(XMLStreamWriter awriter) throws XMLStreamException, IOException
-	{
+	
+	public boolean process(XMLStreamWriter awriter) throws XMLStreamException, IOException {
 		this.writer = awriter;
-		//if (processingXInclude == 0) {
+		// if (processingXInclude == 0) {
 		before(); // if you need to do something before reading the xml
-		//}
+		// }
 		try {
 			for (int event = parser.next(); event != XMLStreamConstants.END_DOCUMENT; event = parser.next()) {
 				switch (event) {
-				case XMLStreamConstants.NAMESPACE:
-					processNamespace();
-					break;
-				case XMLStreamConstants.START_ELEMENT:
-					localname = parser.getLocalName();
-					//currentXPath.append(SLASH)
-					processStartElement();
-					break;		
-				case XMLStreamConstants.CHARACTERS:
-					processCharacters();
-					break;
-				case XMLStreamConstants.END_ELEMENT:
-					localname = parser.getLocalName();
-					processEndElement();
-					//currentXPath.substring(0, currentXPath.length() - localname.length() -1)
-					break;
-				case XMLStreamConstants.PROCESSING_INSTRUCTION:
-					processProcessingInstruction();
-					break;
-				case XMLStreamConstants.DTD:
-					processDTD();
-					break;
-				case XMLStreamConstants.CDATA:
-					processCDATA();
-					break;
-				case XMLStreamConstants.COMMENT:
-					processComment();
-					break;
-				case XMLStreamConstants.END_DOCUMENT:
-					processEndDocument();
-					break;
-				case XMLStreamConstants.ENTITY_REFERENCE:
-					processEntityReference();
-					break;
+					case XMLStreamConstants.NAMESPACE:
+						processNamespace();
+						break;
+					case XMLStreamConstants.START_ELEMENT:
+						localname = parser.getLocalName();
+						// currentXPath.append(SLASH)
+						processStartElement();
+						break;
+					case XMLStreamConstants.CHARACTERS:
+						processCharacters();
+						break;
+					case XMLStreamConstants.END_ELEMENT:
+						localname = parser.getLocalName();
+						processEndElement();
+						// currentXPath.substring(0, currentXPath.length() - localname.length() -1)
+						break;
+					case XMLStreamConstants.PROCESSING_INSTRUCTION:
+						processProcessingInstruction();
+						break;
+					case XMLStreamConstants.DTD:
+						processDTD();
+						break;
+					case XMLStreamConstants.CDATA:
+						processCDATA();
+						break;
+					case XMLStreamConstants.COMMENT:
+						processComment();
+						break;
+					case XMLStreamConstants.END_DOCUMENT:
+						processEndDocument();
+						break;
+					case XMLStreamConstants.ENTITY_REFERENCE:
+						processEntityReference();
+						break;
 				}
 			}
-		} catch(Exception e) {
-			System.out.println("Unexpected error while parsing file "+inputurl+" : "+e);
-			System.out.println("Location line: "+parser.getLocation().getLineNumber()+" character: "+parser.getLocation().getColumnNumber());
+		}
+		catch (Exception e) {
+			System.out.println("Unexpected error while parsing file " + inputurl + " : " + e);
+			System.out.println("Location line: " + parser.getLocation().getLineNumber() + " character: " + parser.getLocation().getColumnNumber());
 			org.txm.utils.logger.Log.printStackTrace(e);
-			//e.printStackTrace();
+			// e.printStackTrace();
 			if (writer != null) writer.close();
 			if (output != null) output.close();
 			parser.close();
 			inputData.close();
 			return false;
 		}
-		//if (processingXInclude == 0) {
+		// if (processingXInclude == 0) {
 		after(); // if you need to do something before closing the parser();
-		//}
+		// }
 		return true;
 	}
-
+	
 	/**
 	 * The start element has already been written
+	 * 
 	 * @param tagname
-	 * @throws XMLStreamException 
-	 * @throws IOException 
+	 * @throws XMLStreamException
+	 * @throws IOException
 	 */
 	public void goToEnd(String tagname) throws XMLStreamException, IOException {
-		//System.out.println("start gotoend $tagname"
+		// System.out.println("start gotoend $tagname"
 		int elements = 1;
 		try {
 			for (int event = parser.next(); event != XMLStreamConstants.END_DOCUMENT; event = parser.next()) {
-				//System.out.println("event "+event
+				// System.out.println("event "+event
 				switch (event) {
-				case XMLStreamConstants.NAMESPACE:
-					processNamespace();
-					break;
-				case XMLStreamConstants.START_ELEMENT:
-					elements++;
-					localname = parser.getLocalName();
-					//currentXPath.append(SLASH)
-					_processStartElement();
-					break;
-				case XMLStreamConstants.CHARACTERS:
-					processCharacters();
-					break;
-				case XMLStreamConstants.PROCESSING_INSTRUCTION:
-					processProcessingInstruction();
-					break;
-				case XMLStreamConstants.DTD:
-					processDTD();
-					break;
-				case XMLStreamConstants.CDATA:
-					processCDATA();
-					break;
-				case XMLStreamConstants.COMMENT:
-					processComment();
-					break;
-				case XMLStreamConstants.END_ELEMENT:
-					elements--;
-					localname = parser.getLocalName();
-					//currentXPath.substring(0, currentXPath.length() - localname.length() -1)
-					writer.writeEndElement();
-					if (elements == 0 && localname == tagname)
-						return;
-					break;
-				case XMLStreamConstants.END_DOCUMENT:
-					processEndDocument();
-					break;
-				case XMLStreamConstants.ENTITY_REFERENCE:
-					processEntityReference();
-					break;
+					case XMLStreamConstants.NAMESPACE:
+						processNamespace();
+						break;
+					case XMLStreamConstants.START_ELEMENT:
+						elements++;
+						localname = parser.getLocalName();
+						// currentXPath.append(SLASH)
+						_processStartElement();
+						break;
+					case XMLStreamConstants.CHARACTERS:
+						processCharacters();
+						break;
+					case XMLStreamConstants.PROCESSING_INSTRUCTION:
+						processProcessingInstruction();
+						break;
+					case XMLStreamConstants.DTD:
+						processDTD();
+						break;
+					case XMLStreamConstants.CDATA:
+						processCDATA();
+						break;
+					case XMLStreamConstants.COMMENT:
+						processComment();
+						break;
+					case XMLStreamConstants.END_ELEMENT:
+						elements--;
+						localname = parser.getLocalName();
+						// currentXPath.substring(0, currentXPath.length() - localname.length() -1)
+						writer.writeEndElement();
+						if (elements == 0 && localname == tagname)
+							return;
+						break;
+					case XMLStreamConstants.END_DOCUMENT:
+						processEndDocument();
+						break;
+					case XMLStreamConstants.ENTITY_REFERENCE:
+						processEntityReference();
+						break;
 				}
 			}
-		} catch(Exception e) {
-			System.out.println("Error while parsing file "+inputurl);
-			System.out.println("Location "+parser.getLocation());
+		}
+		catch (Exception e) {
+			System.out.println("Error while parsing file " + inputurl);
+			System.out.println("Location " + parser.getLocation());
 			org.txm.utils.logger.Log.printStackTrace(e);
 			output.close();
 			parser.close();
 			return;
 		}
 	}
-
+	
 	public String getLocation() {
 		if (parser != null)
-			return "Line: "+parser.getLocation().getLineNumber()+" Col: "+parser.getLocation().	getColumnNumber();
+			return "Line: " + parser.getLocation().getLineNumber() + " Col: " + parser.getLocation().getColumnNumber();
 		return null;
 	}
-
+	
 	protected void processNamespace() throws XMLStreamException {
 		writer.writeNamespace(parser.getPrefix(), parser.getNamespaceURI());
 	}
-
+	
 	public static final String INCLUDE = "include";
+	
 	public static final String XI = "xi";
-
-	protected void processStartElement() throws XMLStreamException, IOException
-	{
+	
+	protected void processStartElement() throws XMLStreamException, IOException {
 		String prefix = parser.getPrefix();
 		if (INCLUDE == localname && XI == prefix) {
 			processXInclude();
-		} else {
+		}
+		else {
 			if (prefix != null && prefix.length() > 0)
 				writer.writeStartElement(Nscontext.getNamespaceURI(prefix), localname);
 			else
 				writer.writeStartElement(localname);
-
-			for (int i = 0 ; i < parser.getNamespaceCount() ; i++) {
+			
+			for (int i = 0; i < parser.getNamespaceCount(); i++) {
 				writer.writeNamespace(parser.getNamespacePrefix(i), parser.getNamespaceURI(i));
 			}
-
+			
 			writeAttributes();
 		}
 	}
-
-	private void _processStartElement() throws XMLStreamException, IOException
-	{
+	
+	private void _processStartElement() throws XMLStreamException, IOException {
 		String prefix = parser.getPrefix();
 		if (INCLUDE == localname && XI == prefix) {
 			processXInclude();
-		} else {
+		}
+		else {
 			if (prefix != null && prefix.length() > 0)
 				writer.writeStartElement(Nscontext.getNamespaceURI(prefix), localname);
 			else
 				writer.writeStartElement(localname);
-
-			for (int i = 0 ; i < parser.getNamespaceCount() ; i++) {
+			
+			for (int i = 0; i < parser.getNamespaceCount(); i++) {
 				writer.writeNamespace(parser.getNamespacePrefix(i), parser.getNamespaceURI(i));
 			}
-
+			
 			writeAttributes();
 		}
 	}
-
+	
 	protected void writeAttributes() throws XMLStreamException {
-		for (int i = 0 ; i < parser.getAttributeCount() ; i++) {
+		for (int i = 0; i < parser.getAttributeCount(); i++) {
 			writeAttribute(parser.getAttributePrefix(i), parser.getAttributeLocalName(i), parser.getAttributeValue(i));
 		}
 	}
-
+	
 	protected void writeAttribute(String prefix, String name, String value) throws XMLStreamException {
 		if (prefix != null && prefix.length() > 0)
-			writer.writeAttribute(prefix+":"+name, value);
+			writer.writeAttribute(prefix + ":" + name, value);
 		else
 			writer.writeAttribute(name, value);
 	}
-
-	protected void processCharacters() throws XMLStreamException
-	{
+	
+	protected void processCharacters() throws XMLStreamException {
 		writer.writeCharacters(parser.getText());
 	}
-
-	protected void processProcessingInstruction() throws XMLStreamException
-	{
+	
+	protected void processProcessingInstruction() throws XMLStreamException {
 		writer.writeProcessingInstruction(parser.getPITarget(), parser.getPIData());
 	}
-
-	protected void processDTD() throws XMLStreamException
-	{
+	
+	protected void processDTD() throws XMLStreamException {
 		writer.writeDTD(parser.getText());
 	}
-
-	protected void processCDATA() throws XMLStreamException
-	{
-		writer.writeCData(parser.getText())	;
+	
+	protected void processCDATA() throws XMLStreamException {
+		writer.writeCData(parser.getText());
 	}
-
-	protected void processComment() throws XMLStreamException
-	{
+	
+	protected void processComment() throws XMLStreamException {
 		writer.writeComment(parser.getText());
 	}
-
-	protected void processEndElement() throws XMLStreamException
-	{
+	
+	protected void processEndElement() throws XMLStreamException {
 		if (localname == INCLUDE && parser.getPrefix() == XI) {
 			// nothing !!
-		} else {
+		}
+		else {
 			writer.writeEndElement();
 		}
 	}
-
+	
 	protected void processEndDocument() throws XMLStreamException {
 		writer.writeEndDocument();
 	}
-
+	
 	protected void processEntityReference() throws XMLStreamException {
 		writer.writeEntityRef(parser.getLocalName());
 	}
+	
 	/**
 	 * Process the XInclude elements
-	 * @throws IOException 
-	 * @throws XMLStreamException 
+	 * 
+	 * @throws IOException
+	 * @throws XMLStreamException
 	 */
 	protected void processXInclude() throws XMLStreamException, IOException {
 		String url = parser.getAttributeValue(null, "href"); // relative only
@@ -378,7 +405,7 @@
 		if (ref.exists()) {
 			URL includeurl = ref.toURI().toURL();
 			// save variables before killing them
-			System.out.println("process xi include: "+ref);
+			System.out.println("process xi include: " + ref);
 			XMLStreamReader parserSave = this.parser; // back up current parser
 			InputStream xiIncludeInputData = includeurl.openStream();
 			XMLStreamReader xiIncludeParser = factory.createXMLStreamReader(xiIncludeInputData);
@@ -387,32 +414,34 @@
 			this.process(writer);
 			processingXInclude--; // end of XInclude processing
 			this.parser = parserSave; // restore parser
-		} else {
+		}
+		else {
 			System.out.println("Warning referenced file: $ref does not exists");
 		}
 	}
-
-	public static void main(String[] args)
-	{
+	
+	public static void main(String[] args) {
 		try {
-			File input = new File("/home/mdecorde/xml/xiinclude/master.xml");
-			File output = new File("/home/mdecorde/xml/xiinclude/merged.xml");
+			File input = new File("/home/mdecorde/xml/identity/test.xml");
+			File output = new File("/home/mdecorde/xml/identity/test-copy.xml");
 			if (!(input.exists() && input.canRead())) {
 				System.out.println("cannot found $input");
 				return;
 			}
 			StaxIdentityParser builder;
-
+			
 			builder = new StaxIdentityParser(input.toURI().toURL());
-
+			
 			if (builder.process(output)) {
-				System.out.println("success ? "+ValidateXml.test(output));
-			} else {
+				System.out.println("success ? " + ValidateXml.test(output));
+			}
+			else {
 				System.out.println("failure !");
 			}
-		} catch (Exception e) {
+		}
+		catch (Exception e) {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
 	}
-}
\ No newline at end of file
+}
Index: tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersGlozz.java
===================================================================
--- tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersGlozz.java	(revision 2936)
+++ tmp/org.txm.analec.rcp/src/visuAnalec/fichiers/FichiersGlozz.java	(revision 2937)
@@ -20,47 +20,49 @@
  * @author Bernard
  */
 public abstract class FichiersGlozz {
-  public static void convertirCorpusGlozz(final Corpus corpus) {
-    File repGlozz;
-    final File repJava;
-    if ((repGlozz = Fichiers.choisirRepertoire("Choix du répertoire Glozz"))==null)
-      return;
-    if ((repJava = Fichiers.choisirRepertoire("Choix du répertoire Java"))==null)
-      return;
-    if (!repJava.exists()) {
-      if (!GMessages.confirmationAction("Le répertoire spécifié n'existe pas."
-              +" Voulez-vous le créer ?")) return;
-      if (!repJava.mkdir()) {
-        GMessages.impossibiliteAction("Echec de la création du répertoire");
-        return;
-      }
-    }
-    final File[] fics = Fichiers.listerFichiers(repGlozz, Fichiers.TypeFichier.GLOZZ_CORPUS);
-    final GMessages.GProgression progression =
-            new GMessages.GProgression(fics.length, "Conversion", "fichiers");
-    Thread traitement = new Thread() {
-      @Override
-      public void run() {
-        try {
-        for (int i = 0; i<fics.length; i++) {
-          if (progression.isCanceled()) break;
-          progression.setNbTraites(i+1);
-          File fichierCorpus = fics[i];
-          File fichierAnnot = Fichiers.trouverFichier(TypeFichier.GLOZZ_ANNOT, fichierCorpus);
-          if (fichierAnnot==null) continue;
-          importer(fichierCorpus, fichierAnnot, corpus);
-          FichiersJava.enregistrerCorpus(corpus, Fichiers.creerFichier(repJava, TypeFichier.DOC_ANALEC, fichierCorpus));
-//          corpus.fermer();
-        }
-        corpus.fermer();
-        } catch (Throwable ex) {
-          GMessages.erreurFatale(ex);
-        }
-      }
-    };
-    traitement.start();
-  }
-
+	
+	public static void convertirCorpusGlozz(final Corpus corpus) {
+		File repGlozz;
+		final File repJava;
+		if ((repGlozz = Fichiers.choisirRepertoire("Choix du répertoire Glozz")) == null)
+			return;
+		if ((repJava = Fichiers.choisirRepertoire("Choix du répertoire Java")) == null)
+			return;
+		if (!repJava.exists()) {
+			if (!GMessages.confirmationAction("Le répertoire spécifié n'existe pas."
+					+ " Voulez-vous le créer ?")) return;
+			if (!repJava.mkdir()) {
+				GMessages.impossibiliteAction("Echec de la création du répertoire");
+				return;
+			}
+		}
+		final File[] fics = Fichiers.listerFichiers(repGlozz, Fichiers.TypeFichier.GLOZZ_CORPUS);
+		final GMessages.GProgression progression = new GMessages.GProgression(fics.length, "Conversion", "fichiers");
+		Thread traitement = new Thread() {
+			
+			@Override
+			public void run() {
+				try {
+					for (int i = 0; i < fics.length; i++) {
+						if (progression.isCanceled()) break;
+						progression.setNbTraites(i + 1);
+						File fichierCorpus = fics[i];
+						File fichierAnnot = Fichiers.trouverFichier(TypeFichier.GLOZZ_ANNOT, fichierCorpus);
+						if (fichierAnnot == null) continue;
+						importer(fichierCorpus, fichierAnnot, corpus);
+						FichiersJava.enregistrerCorpus(corpus, Fichiers.creerFichier(repJava, TypeFichier.DOC_ANALEC, fichierCorpus));
+						// corpus.fermer();
+					}
+					corpus.fermer();
+				}
+				catch (Throwable ex) {
+					GMessages.erreurFatale(ex);
+				}
+			}
+		};
+		traitement.start();
+	}
+	
 	public static boolean importerGlozz(Corpus corpus, File fichierCorpus, File fichierAnnot) {
 		if (!importer(fichierCorpus, fichierAnnot, corpus)) {
 			return false;
@@ -78,72 +80,83 @@
 		File fichierCorpus;
 		File fichierAnnot;
 		if ((fichierCorpus = Fichiers.choisirFichier(Commande.OUVRIR,
-				"Choix du fichier corpus", Fichiers.TypeFichier.GLOZZ_CORPUS))==null)
+				"Choix du fichier corpus", Fichiers.TypeFichier.GLOZZ_CORPUS)) == null)
 			return false;
 		if ((fichierAnnot = Fichiers.choisirFichier(Commande.OUVRIR,
-				"Choix du fichier annotations", Fichiers.TypeFichier.GLOZZ_ANNOT))==null)
+				"Choix du fichier annotations", Fichiers.TypeFichier.GLOZZ_ANNOT)) == null)
 			return false;
 		
 		return importerGlozz(corpus, fichierCorpus, fichierAnnot);
 	}
 	
-  
-  private static boolean importer(File fichierCorpus, File fichierAnnot, Corpus corpus) {
-    BufferedReader text = null;
-    BufferedInputStream annot = null;
-    try {
-      text = new BufferedReader(new InputStreamReader(new FileInputStream(fichierCorpus), "UTF-8"));
-      annot = new BufferedInputStream(new FileInputStream(fichierAnnot));
-      corpus.setTexte(text.readLine());
-      SAXParserFactory pf = (SAXParserFactory) SAXParserFactory.newInstance();
-      SAXParser sp = pf.newSAXParser();
-      sp.parse(annot, new GlozzHandler(corpus));
-    } catch (IOException ex) {
-      corpus.fermer();
-      JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
-      return false;
-    } catch (ParserConfigurationException ex) {
-      corpus.fermer();
-      JOptionPane.showMessageDialog(null, ex, "Erreur de format de fichier", JOptionPane.ERROR_MESSAGE);
-      return false;
-    } catch (SAXException ex) {
-      corpus.fermer();
-      JOptionPane.showMessageDialog(null, ex, "Erreur de format de fichier", JOptionPane.ERROR_MESSAGE);
-      return false;
-    } finally {
-      try {
-        if (text!=null) text.close();
-        if (annot!=null) annot.close();
-      } catch (IOException ex) {
-        JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture du fichier lu", JOptionPane.ERROR_MESSAGE);
-      }
-    }
-    return true;
-  }
+	
+	private static boolean importer(File fichierCorpus, File fichierAnnot, Corpus corpus) {
+		BufferedReader text = null;
+		BufferedInputStream annot = null;
+		try {
+			text = new BufferedReader(new InputStreamReader(new FileInputStream(fichierCorpus), "UTF-8"));
+			annot = new BufferedInputStream(new FileInputStream(fichierAnnot));
+			corpus.setTexte(text.readLine());
+			SAXParserFactory pf = SAXParserFactory.newInstance();
+			SAXParser sp = pf.newSAXParser();
+			sp.parse(annot, new GlozzHandler(fichierAnnot, corpus));
+		}
+		catch (IOException ex) {
+			corpus.fermer();
+			JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		}
+		catch (ParserConfigurationException ex) {
+			corpus.fermer();
+			JOptionPane.showMessageDialog(null, ex, "Erreur de format de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		}
+		catch (SAXException ex) {
+			corpus.fermer();
+			JOptionPane.showMessageDialog(null, ex, "Erreur de format de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		}
+		finally {
+			try {
+				if (text != null) text.close();
+				if (annot != null) annot.close();
+			}
+			catch (IOException ex) {
+				JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture du fichier lu", JOptionPane.ERROR_MESSAGE);
+			}
+		}
+		return true;
+	}
+	
 	public static boolean importerModeleGlozz(Corpus corpus, File fichierModele) {
 		BufferedInputStream modele = null;
 		
 		try {
 			modele = new BufferedInputStream(new FileInputStream(fichierModele));
-			SAXParserFactory pf = (SAXParserFactory) SAXParserFactory.newInstance();
+			SAXParserFactory pf = SAXParserFactory.newInstance();
 			SAXParser sp = pf.newSAXParser();
 			Structure structureLue = new Structure();
-			sp.parse(modele, new ModeleGlozzHandler(structureLue));
+			sp.parse(modele, new ModeleGlozzHandler(fichierModele, structureLue));
 			corpus.fusionnerStructureLue(structureLue);
 			corpus.newCorpusLu();
-		} catch (IOException ex) {
+		}
+		catch (IOException ex) {
 			JOptionPane.showMessageDialog(null, ex, "Erreur de lecture de fichier", JOptionPane.ERROR_MESSAGE);
 			return false;
-		} catch (ParserConfigurationException ex) {
+		}
+		catch (ParserConfigurationException ex) {
 			JOptionPane.showMessageDialog(null, ex, "Erreur de format de fichier", JOptionPane.ERROR_MESSAGE);
 			return false;
-		} catch (SAXException ex) {
+		}
+		catch (SAXException ex) {
 			JOptionPane.showMessageDialog(null, ex, "Erreur de format de fichier", JOptionPane.ERROR_MESSAGE);
 			return false;
-		} finally {
+		}
+		finally {
 			try {
-				if (modele!=null) modele.close();
-			} catch (IOException ex) {
+				if (modele != null) modele.close();
+			}
+			catch (IOException ex) {
 				JOptionPane.showMessageDialog(null, ex, "Erreur de fermeture du fichier lu", JOptionPane.ERROR_MESSAGE);
 			}
 		}
@@ -153,566 +166,654 @@
 	public static boolean importerModeleGlozz(Corpus corpus) {
 		File fichierModele;
 		if ((fichierModele = Fichiers.choisirFichier(Commande.OUVRIR,
-				"Choix du fichier modèle", Fichiers.TypeFichier.GLOZZ_MODELE))==null)
+				"Choix du fichier modèle", Fichiers.TypeFichier.GLOZZ_MODELE)) == null)
 			return false;
 		
 		return importerModeleGlozz(corpus, fichierModele);
 	}
-  public static boolean exporterGlozz(Corpus corpus) {
-    PrintWriter text = null;
-    PrintWriter annot = null;
-    PrintWriter model = null;
-    File fichierCorpus;
-    File fichierAnnot;
-    File fichierModel;
-    if ((fichierCorpus = Fichiers.choisirFichier(Commande.ENREGISTRER,
-            "Nom du fichier corpus", Fichiers.TypeFichier.GLOZZ_CORPUS))==null) return false;
-    if ((fichierAnnot = Fichiers.choisirFichier(Commande.ENREGISTRER,
-            "Nom du fichier annotations", Fichiers.TypeFichier.GLOZZ_ANNOT))==null)
-      return false;
-    try {
-      text = new PrintWriter(fichierCorpus, "UTF-8");
-      annot = new PrintWriter(fichierAnnot, "UTF-8");
-      text.print(corpus.getTexte());
-      GlozzPrinter gp = new GlozzPrinter(corpus, annot);
-      gp.ecrireAnnot();
-    } catch (FileNotFoundException ex) {
-      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
-      return false;
-    } catch (UnsupportedEncodingException ex) {
-      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
-      return false;
-    } finally {
-      if (text!=null) text.close();
-      if (annot!=null) annot.close();
-    }
-    if ((fichierModel = Fichiers.choisirFichier(Commande.ENREGISTRER,
-            "Exporter aussi le modèle ?", Fichiers.TypeFichier.GLOZZ_MODELE))==null)
-      return true;
-    try {
-      model = new PrintWriter(fichierModel, "UTF-8");
-      ModelGlozzPrinter gp = new ModelGlozzPrinter(corpus.getStructure(), model);
-      gp.ecrireModel();
-    } catch (FileNotFoundException ex) {
-      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
-    } catch (UnsupportedEncodingException ex) {
-      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
-    } finally {
-      if (model!=null) model.close();
-    }
-    return true;
-  }
-  
-  public static boolean exporterModeleGlozz(Structure structure) {
-    PrintWriter model = null;
-    File fichierModel;
-    if ((fichierModel = Fichiers.choisirFichier(Commande.ENREGISTRER,
-            "Nom du fichier modèle ?", Fichiers.TypeFichier.GLOZZ_MODELE))==null)
-      return false;
-    try {
-      model = new PrintWriter(fichierModel, "UTF-8");
-      ModelGlozzPrinter gp = new ModelGlozzPrinter(structure, model);
-      gp.ecrireModel();
-    } catch (Exception ex) {
-      JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
-      return false;
-    } finally {
-      if (model!=null) model.close();
-    }
-    return true;
-  }
-
-  static class GlozzHandler extends DefaultHandler {
-    Corpus corpus;
-    Balise etatCourant = null;
-    Element elementCourant = null;
-    String champCourant = null;
-    String valCourant = null;
-    HashMap<String, Element> elements = new HashMap<String, Element>();
-    ArrayList<Relation> relations = new ArrayList<Relation>();
-    HashMap<Relation, ArrayList<String>> idTermes = new HashMap<Relation, ArrayList<String>>();
-    ArrayList<Schema> schemas = new ArrayList<Schema>();
-    HashMap<Schema, ArrayList<String>> idContenus = new HashMap<Schema, ArrayList<String>>();
-
-    enum Balise {
-      ANNOTATIONS, UNIT, RELATION, SCHEMA, METADATA, AUTHOR, CREATIONDATE,
-      LASTMODIFIER, LASTMODIFICATIONDATE, CHARACTERISATION, TYPE, FEATURESET,
-      FEATURE, POSITIONING, START, END, SINGLEPOSITION, TERM,
-      EMBEDDEDUNIT, EMBEDDEDRELATION, EMBEDDEDSCHEMA,
-      FLAG, COMMENT
-    };
-    static Balise balise(String nomBalise) {
-      return Balise.valueOf(nomBalise.replaceAll("\\W", "").toUpperCase());
-    }
-    GlozzHandler(Corpus corpus) {
-      super();
-      this.corpus = corpus;
-    }
-    @Override
-    public void startDocument() {
-      corpus.clearAnnot();
-    }
-    @Override
-    public void endDocument() throws SAXNotSupportedException {
-      for (Relation rel : relations) {
-        ArrayList<String> idterms = idTermes.get(rel);
-        if (idterms.size()!=2) {
-          throw new SAXNotSupportedException("Une relation de type "+rel.getType()+" n'a pas deux termes");
-        }
-        if (elements.get(idterms.get(0))==null) {
-          throw new SAXNotSupportedException("Terme inconnu id = "+idterms.get(0)
-                  +" pour une relation de type "+rel.getType());
-        }
-        rel.setElt1(elements.get(idterms.get(0)));
-        if (elements.get(idterms.get(1))==null) {
-          throw new SAXNotSupportedException("Terme inconnu id = "+idterms.get(1)
-                  +" pour une relation de type "+rel.getType());
-        }
-        rel.setElt2(elements.get(idterms.get(1)));
-        corpus.addRelationLue(rel);
-      }
-      for (Schema sch : schemas) {
-        for (String id : idContenus.get(sch)) {
-          if (elements.get(id)==null) {
-            throw new SAXNotSupportedException("Contenu inconnu id = "+id
-                    +" pour un schéma de type "+sch.getType());
-          }
-          sch.ajouter(elements.get(id));
-        }
-        corpus.addSchemaLu(sch);
-      }
-      corpus.verifierFinParagraphesTypesUnites(new String[]{
-                "title", "subTitle", "sectionTitle", "subSectionTitle",
-                "subSubSectionTitle", "subSubSubSectionTitle", "quote", "listItem"});
-      corpus.trierFinParagraphes();
-      corpus.verifierFinParagrapheFinTexte();
-    }
-    @Override
-    public void startElement(String uri, String local, String nomBalise, Attributes attributs) throws SAXException {
-      if (etatCourant==Balise.FLAG) return;
-      switch (balise(nomBalise)) {
-        case FLAG:
-          etatCourant = Balise.FLAG;
-          break;
-        case UNIT:
-          elementCourant = new Unite();
-          elements.put(attributs.getValue("id"), elementCourant);
-          break;
-        case RELATION:
-          elementCourant = new Relation();
-          elements.put(attributs.getValue("id"), elementCourant);
-          idTermes.put((Relation) elementCourant, new ArrayList<String>());
-          break;
-        case SCHEMA:
-          elementCourant = new Schema();
-          elements.put(attributs.getValue("id"), elementCourant);
-          idContenus.put((Schema) elementCourant, new ArrayList<String>());
-          break;
-        case TYPE:
-          etatCourant = Balise.TYPE;
-          valCourant = "";
-          break;
-        case FEATURE:
-          etatCourant = Balise.FEATURE;
-          champCourant = attributs.getValue("name");
-          valCourant = "";
-          break;
-        case START:
-          etatCourant = Balise.START;
-          break;
-        case END:
-          etatCourant = Balise.END;
-          break;
-        case SINGLEPOSITION:
-          if (elementCourant.getClass()!=Unite.class) {
-            throw new SAXNotSupportedException("La balise singlePosition ne peut être utilisée que pour des unités");
-          }
-          if (elementCourant.getType().equals("paragraph")) {
-            if (etatCourant==Balise.END) {
-              corpus.addFinParagraphe(Integer.parseInt(attributs.getValue("index")));
-            }
-          } else {
-            switch (etatCourant) {
-              case START:
-                ((Unite) elementCourant).setDeb(Integer.parseInt(attributs.getValue("index")));
-                break;
-              case END:
-                ((Unite) elementCourant).setFin(Integer.parseInt(attributs.getValue("index")));
-                break;
-            }
-          }
-          break;
-        case TERM:
-          if (elementCourant.getClass()!=Relation.class)
-            throw new SAXNotSupportedException("La balise term ne peut être utilisée que pour des relations");
-          idTermes.get((Relation) elementCourant).add(attributs.getValue("id"));
-          break;
-
-        case EMBEDDEDUNIT:
-        case EMBEDDEDRELATION:
-        case EMBEDDEDSCHEMA:
-          if (elementCourant.getClass()!=Schema.class)
-            throw new SAXNotSupportedException(
-                    "Les balises embedded ne peuvent être utilisées que pour des schémas");
-          idContenus.get((Schema) elementCourant).add(attributs.getValue("id"));
-          break;
-      }
-    }
-    @Override
-    public void endElement(String uri, String local, String nomBalise) throws SAXException {
-      if (etatCourant==Balise.FLAG) {
-        if (balise(nomBalise)==Balise.FLAG) etatCourant = null;
-        return;
-      }
-      String type = "";
-      switch (balise(nomBalise)) {
-        case UNIT:
-          type = elementCourant.getType();
-          if (type==null||type.isEmpty())
-            throw new SAXNotSupportedException("Pas trouvé de type pour cette unité");
-          if (!type.equals("paragraph")) {
-            corpus.addUniteLue((Unite) elementCourant);
-            elementCourant = null;
-          }
-          break;
-        case RELATION:
-          type = elementCourant.getType();
-          if (type==null||type.isEmpty())
-            throw new SAXNotSupportedException("Pas trouvé de type pour cette relation");
-          relations.add((Relation) elementCourant);
-          elementCourant = null;
-          break;
-        case SCHEMA:
-          type = elementCourant.getType();
-          if (type==null||type.isEmpty())
-            throw new SAXNotSupportedException("Pas trouvé de type pour ce shéma");
-          schemas.add((Schema) elementCourant);
-          elementCourant = null;
-          break;
-        case TYPE:
-          elementCourant.setType(valCourant);
-          valCourant = null;
-          etatCourant = null;
-          break;
-        case FEATURE:
-          elementCourant.putProp(champCourant, valCourant);
-          etatCourant = null;
-          champCourant = null;
-          valCourant = null;
-          break;
-        case START:
-          etatCourant = null;
-          break;
-        case END:
-          etatCourant = null;
-          break;
-      }
-    }
-    @Override
-    public void characters(char[] ch, int start, int taille) throws SAXException {
-      if (etatCourant==null||!EnumSet.of(Balise.TYPE, Balise.FEATURE).contains(etatCourant)) {
-        return;
-      }
-      valCourant += new String(ch, start, taille);
-    }
-  }
-
-  static class ModeleGlozzHandler extends DefaultHandler {
-    Structure structure;
-    boolean listeValeurs = false;
-    Class<? extends Element> classeCourante = Unite.class;  // par défaut : balise <units> sous-entendue 
-    String typeCourant = null;
-    String champCourant = null;
-    String valeurCourante = null;
-
-    enum Balise {
-      ANNOTATIONMODEL, UNITS, RELATIONS, SCHEMAS, TYPE, FEATURESET,
-      FEATURE, POSSIBLEVALUES, VALUE
-    };
-    static Balise balise(String nomBalise) throws SAXNotRecognizedException {
-      try {
-        return Balise.valueOf(nomBalise.replaceAll("\\W", "").toUpperCase());
-      } catch (Exception e) {
-        throw new SAXNotRecognizedException("Balise non reconnue : "+nomBalise);
-      }
-    }
-    ModeleGlozzHandler(Structure structure) {
-      super();
-      this.structure = structure;
-    }
-    @Override
-    public void startDocument() {
-    }
-    @Override
-    public void endDocument() throws SAXNotSupportedException {
-    }
-    @Override
-    public void startElement(String uri, String local, String nomBalise, Attributes attributs) throws SAXException {
-      String valdef = null;
-      switch (balise(nomBalise)) {
-        case UNITS:
-          classeCourante = Unite.class;
-          break;
-        case RELATIONS:
-          classeCourante = Relation.class;
-          break;
-        case SCHEMAS:
-          classeCourante = Schema.class;
-          break;
-        case TYPE:
-          typeCourant = attributs.getValue("name");
-          if (typeCourant==null||typeCourant.isEmpty())
-            throw new SAXNotSupportedException("Nom de type absent");
-          structure.ajouterType(classeCourante, typeCourant);
-          break;
-        case FEATURE:
-          if (typeCourant==null||typeCourant.isEmpty())
-            throw new SAXNotSupportedException("Nom de type absent");
-          champCourant = attributs.getValue("name");
-          if (champCourant==null||champCourant.isEmpty())
-            throw new SAXNotSupportedException("Nom de type absent");
-          structure.ajouterProp(classeCourante, typeCourant, champCourant);
-          break;
-        case POSSIBLEVALUES:
-          if (typeCourant==null||typeCourant.isEmpty()||champCourant==null||champCourant.isEmpty())
-            throw new SAXNotSupportedException("Nom de type ou de feature absent");
-          listeValeurs = true;
-          valdef = attributs.getValue("default");
-          if (valdef!=null&&!valdef.isEmpty())
-            structure.modifierValParDefaut(classeCourante, typeCourant, champCourant, valdef);
-          break;
-        case VALUE:
-          if (listeValeurs) valeurCourante = "";
-          valdef = attributs.getValue("default");
-          if (valdef!=null&&!valdef.isEmpty()) {
-            if (typeCourant==null||typeCourant.isEmpty()||champCourant==null||champCourant.isEmpty())
-              throw new SAXNotSupportedException("Nom de type ou de feature absent");
-            structure.ajouterVal(classeCourante, typeCourant, champCourant, valdef);
-            structure.modifierValParDefaut(classeCourante, typeCourant, champCourant, valdef);
-          }
-          break;
-      }
-    }
-    @Override
-    public void endElement(String uri, String local, String nomBalise) throws SAXException {
-      switch (balise(nomBalise)) {
-        case POSSIBLEVALUES:
-          listeValeurs = false;
-          break;
-        case VALUE:
-          if (listeValeurs&&valeurCourante!=null&&!valeurCourante.isEmpty())
-            structure.ajouterVal(classeCourante, typeCourant, champCourant, valeurCourante);
-          break;
-      }
-    }
-    @Override
-    public void characters(char[] ch, int start, int taille) throws SAXException {
-      if (listeValeurs) {
-        valeurCourante += new String(ch, start, taille);
-      }
-    }
-  }
-
-  static class GlozzPrinter {
-    Corpus corpus;
-    PrintWriter annot;
-    HashMap<Element, String> idDates = new HashMap<Element, String>();
-    String idAuteur = "analec0.2";
-    String idDateParagraphes = "0";
-    String idParagraphes = idAuteur+"_"+idDateParagraphes;
-    GlozzPrinter(Corpus corpus, PrintWriter annot) {
-      this.corpus = corpus;
-      this.annot = annot;
-      attribueIdDates();
-    }
-    void attribueIdDates() {
-      long idDate = (new Date()).getTime();
-      for (Unite unite : corpus.getToutesUnites()) {
-        idDates.put(unite, Long.toString(idDate++));
-      }
-      for (Relation relation : corpus.getToutesRelations()) {
-        idDates.put(relation, Long.toString(idDate++));
-      }
-      for (Schema schema : corpus.getTousSchemas()) {
-        idDates.put(schema, Long.toString(idDate++));
-      }
-    }
-    String getId(Element elt) {
-      return idAuteur+"_"+idDates.get(elt);
-    }
-    void ecrireAnnot() {
-      annot.println("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
-      annot.println("<annotations>");
-      ecrireFinParagraphes();
-      ecrireUnites();
-      ecrireRelations();
-      ecrireSchemas();
-      annot.println("</annotations>");
-    }
-    private void ecrireFinParagraphes() {
-      int deb = 0;
-      for (int fin : corpus.getFinParagraphes()) {
-        ecrireUnite("paragraph", idAuteur, idDateParagraphes, idParagraphes, new HashMap<String, String>(), deb, fin);
-        deb = fin;
-      }
-    }
-    private void ecrireUnites() {
-      for (Unite unit : corpus.getToutesUnites()) {
-        ecrireUnite(unit.getType(), idAuteur, idDates.get(unit), getId(unit), unit.getProps(), unit.getDeb(), unit.getFin());
-      }
-    }
-    private void ecrireRelations() {
-      for (Relation rel : corpus.getToutesRelations()) {
-        ecrireRelation(rel.getType(), idAuteur, idDates.get(rel), getId(rel), rel.getProps(), rel.getElt1(), rel.getElt2());
-      }
-    }
-    private void ecrireSchemas() {
-      for (Schema sch : corpus.getTousSchemas()) {
-        ecrireSchema(sch.getType(), idAuteur, idDates.get(sch), getId(sch), sch.getProps(), sch.getContenu());
-      }
-    }
-    private void ecrireUnite(String type, String idAuteur, String idDate, String id, HashMap<String, String> props, int deb, int fin) {
-      annot.println("<unit id=\""+id+"\">");
-      ecrireMetadata(idAuteur, idDate);
-      ecrireProps(type, props);
-      ecrirePos(deb, fin);
-      annot.println("</unit>");
-    }
-    private void ecrireRelation(String type, String idAuteur, String idDate, String id, HashMap<String, String> props, Element elt1, Element elt2) {
-      annot.println("<relation id=\""+id+"\">");
-      ecrireMetadata(idAuteur, idDate);
-      ecrireProps(type, props);
-      ecrireRel(elt1, elt2);
-      annot.println("</relation>");
-    }
-    private void ecrireSchema(String type, String idAuteur, String idDate, String id, HashMap<String, String> props, HashSet<Element> elts) {
-      annot.println("<schema id=\""+id+"\">");
-      ecrireMetadata(idAuteur, idDate);
-      ecrireProps(type, props);
-      ecrireSch(elts);
-      annot.println("</schema>");
-    }
-    private void ecrireMetadata(String idAuteur, String id) {
-      annot.println("<metadata>");
-      annot.println("<author>"+idAuteur+"</author>");
-      annot.println("<creation-date>"+id+"</creation-date>");
-      annot.println("</metadata>");
-    }
-    private void ecrireProps(String type, HashMap<String, String> props) {
-      annot.println("<characterisation>");
-      annot.println("<type>"+encodeXMLTexte(type)+"</type>");
-      if (props.isEmpty()) {
-        annot.println("<featureSet/>");
-      } else {
-        annot.println("<featureSet>");
-        for (String prop : props.keySet()) {
-          if (props.get(prop)!=null) {
-            annot.println("<feature name =\""+encodeXMLTexte(prop)+"\">"
-                    +encodeXMLTexte(props.get(prop))+"</feature>");
-          }
-        }
-        annot.println("</featureSet>");
-
-      }
-      annot.println("</characterisation>");
-    }
-    private void ecrirePos(int deb, int fin) {
-      annot.println("<positioning>");
-      annot.println("<start>");
-      annot.println("<singlePosition index = \""+deb+"\"/>");
-      annot.println("</start>");
-      annot.println("<end>");
-      annot.println("<singlePosition index = \""+fin+"\"/>");
-      annot.println("</end>");
-      annot.println("</positioning>");
-    }
-    private void ecrireRel(Element elt1, Element elt2) {
-      annot.println("<positioning>");
-      annot.println("<term id = \""+getId(elt1)+"\"/>");
-      annot.println("<term id = \""+getId(elt2)+"\"/>");
-      annot.println("</positioning>");
-    }
-    private void ecrireSch(HashSet<Element> elts) {
-      annot.println("<positioning>");
-      for (Element elt : elts) {
-        Class classe = elt.getClass();
-        if (classe==Unite.class) {
-          annot.print("<embedded-unit ");
-        }
-        if (classe==Relation.class) {
-          annot.print("<embedded-relation ");
-        }
-        if (classe==Schema.class) {
-          annot.print("<embedded-schema ");
-        }
-        annot.println("id = \""+getId(elt)+"\"/>");
-      }
-      annot.println("</positioning>");
-    }
-  }
-
-  public static class ModelGlozzPrinter {
-    Structure structure;
-    PrintWriter model;
-    public ModelGlozzPrinter(Structure structure, PrintWriter model) {
-      this.structure = structure;
-      this.model = model;
-    }
-    public void ecrireModel() {
-      model.println("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
-      model.println("<annotationModel>");
-      ecrireUnites();
-      ecrireRelations();
-      ecrireSchemas();
-      model.println("</annotationModel>");
-    }
-    private void ecrireUnites() {
-      model.println("<units>");
-      for (String type : structure.getTypes(Unite.class))
-        ecrireType(Unite.class, type);
-      model.println("</units>");
-    }
-    private void ecrireRelations() {
-      model.println("<relations>");
-      for (String type : structure.getTypes(Relation.class))
-        ecrireType(Relation.class, type);
-      model.println("</relations>");
-    }
-    private void ecrireSchemas() {
-      model.println("<schemas>");
-      for (String type : structure.getTypes(Schema.class))
-        ecrireType(Schema.class, type);
-      model.println("</schemas>");
-    }
-    private void ecrireType(Class<? extends Element> classe, String type) {
-      model.print("<type name=\""+encodeXMLTexte(type)+"\"");
-      if (classe==Relation.class) model.print(" oriented=\"true\"");
-      model.println(">");
-      model.println("<featureSet>");
-      for (String prop : structure.getNomsProps(classe, type))
-        ecrireProp(classe, type, prop);
-      model.println("</featureSet>");
-      model.println("</type>");
-    }
-    private void ecrireProp(Class<? extends Element> classe, String type, String prop) {
-      model.println("<feature name=\""+encodeXMLTexte(prop)+"\">");
-      if (structure.getValeursProp(classe, type, prop).isEmpty()) {
-        model.println("<value type=\"free\" default=\"\" />");
-      } else {
-        model.println("<possibleValues default = \""
-                +structure.getValeurParDefaut(classe, type, prop)+"\">");
-        for (String val : structure.getValeursProp(classe, type, prop))
-          model.println("<value>"+encodeXMLTexte(val)+"</value>");
-        model.println("</possibleValues>");
-      }
-      model.println("</feature>");
-
-    }
-  }
-  static String encodeXMLTexte(String ch) {
-//    return ch;
-    return ch.replaceAll("&", "&amp;").replaceAll("<", "&lt;").
-            replaceAll(">", "&gt;").replaceAll("\"", "&quot;").
-            replaceAll("\'", "&apos;");
-  }
+	
+	public static boolean exporterGlozz(Corpus corpus) {
+		PrintWriter text = null;
+		PrintWriter annot = null;
+		PrintWriter model = null;
+		File fichierCorpus;
+		File fichierAnnot;
+		File fichierModel;
+		if ((fichierCorpus = Fichiers.choisirFichier(Commande.ENREGISTRER,
+				"Nom du fichier corpus", Fichiers.TypeFichier.GLOZZ_CORPUS)) == null) return false;
+		if ((fichierAnnot = Fichiers.choisirFichier(Commande.ENREGISTRER,
+				"Nom du fichier annotations", Fichiers.TypeFichier.GLOZZ_ANNOT)) == null)
+			return false;
+		try {
+			text = new PrintWriter(fichierCorpus, "UTF-8");
+			annot = new PrintWriter(fichierAnnot, "UTF-8");
+			text.print(corpus.getTexte());
+			GlozzPrinter gp = new GlozzPrinter(corpus, annot);
+			gp.ecrireAnnot();
+		}
+		catch (FileNotFoundException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		}
+		catch (UnsupportedEncodingException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		}
+		finally {
+			if (text != null) text.close();
+			if (annot != null) annot.close();
+		}
+		if ((fichierModel = Fichiers.choisirFichier(Commande.ENREGISTRER,
+				"Exporter aussi le modèle ?", Fichiers.TypeFichier.GLOZZ_MODELE)) == null)
+			return true;
+		try {
+			model = new PrintWriter(fichierModel, "UTF-8");
+			ModelGlozzPrinter gp = new ModelGlozzPrinter(corpus.getStructure(), model);
+			gp.ecrireModel();
+		}
+		catch (FileNotFoundException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+		}
+		catch (UnsupportedEncodingException ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+		}
+		finally {
+			if (model != null) model.close();
+		}
+		return true;
+	}
+	
+	public static boolean exporterModeleGlozz(Structure structure) {
+		PrintWriter model = null;
+		File fichierModel;
+		if ((fichierModel = Fichiers.choisirFichier(Commande.ENREGISTRER,
+				"Nom du fichier modèle ?", Fichiers.TypeFichier.GLOZZ_MODELE)) == null)
+			return false;
+		try {
+			model = new PrintWriter(fichierModel, "UTF-8");
+			ModelGlozzPrinter gp = new ModelGlozzPrinter(structure, model);
+			gp.ecrireModel();
+		}
+		catch (Exception ex) {
+			JOptionPane.showMessageDialog(null, ex, "Erreur d'écriture de fichier", JOptionPane.ERROR_MESSAGE);
+			return false;
+		}
+		finally {
+			if (model != null) model.close();
+		}
+		return true;
+	}
+	
+	static class GlozzHandler extends DefaultHandler {
+		
+		Corpus corpus;
+		
+		Balise etatCourant = null;
+		
+		Element elementCourant = null;
+		
+		String champCourant = null;
+		
+		String valCourant = null;
+		
+		HashMap<String, Element> elements = new HashMap<>();
+		
+		ArrayList<Relation> relations = new ArrayList<>();
+		
+		HashMap<Relation, ArrayList<String>> idTermes = new HashMap<>();
+		
+		ArrayList<Schema> schemas = new ArrayList<>();
+		
+		HashMap<Schema, ArrayList<String>> idContenus = new HashMap<>();
+		
+		File parsedFile;
+		
+		enum Balise {
+			ANNOTATIONS, UNIT, RELATION, SCHEMA, METADATA, AUTHOR, CREATIONDATE, LASTMODIFIER, LASTMODIFICATIONDATE, CHARACTERISATION, TYPE, FEATURESET, FEATURE, POSITIONING, START, END, SINGLEPOSITION, TERM, EMBEDDEDUNIT, EMBEDDEDRELATION, EMBEDDEDSCHEMA, FLAG, COMMENT
+			// , POSSIBLEVALUES, VALUE
+		};
+		
+		Balise balise(String nomBalise) {
+			String s = nomBalise.replaceAll("\\W", "").toUpperCase();
+			try {
+				return Balise.valueOf(s);
+			}
+			catch (java.lang.IllegalArgumentException e) {
+				System.out.println("Error: unknown tag '" + nomBalise + "' in " + parsedFile);
+				throw e;
+			}
+		}
+		
+		GlozzHandler(File parsedFile, Corpus corpus) {
+			super();
+			this.corpus = corpus;
+			this.parsedFile = parsedFile;
+		}
+		
+		@Override
+		public void startDocument() {
+			corpus.clearAnnot();
+		}
+		
+		@Override
+		public void endDocument() throws SAXNotSupportedException {
+			for (Relation rel : relations) {
+				ArrayList<String> idterms = idTermes.get(rel);
+				if (idterms.size() != 2) {
+					throw new SAXNotSupportedException("Une relation de type " + rel.getType() + " n'a pas deux termes");
+				}
+				if (elements.get(idterms.get(0)) == null) {
+					throw new SAXNotSupportedException("Terme inconnu id = " + idterms.get(0)
+							+ " pour une relation de type " + rel.getType());
+				}
+				rel.setElt1(elements.get(idterms.get(0)));
+				if (elements.get(idterms.get(1)) == null) {
+					throw new SAXNotSupportedException("Terme inconnu id = " + idterms.get(1)
+							+ " pour une relation de type " + rel.getType());
+				}
+				rel.setElt2(elements.get(idterms.get(1)));
+				corpus.addRelationLue(rel);
+			}
+			for (Schema sch : schemas) {
+				for (String id : idContenus.get(sch)) {
+					if (elements.get(id) == null) {
+						throw new SAXNotSupportedException("Contenu inconnu id = " + id
+								+ " pour un schéma de type " + sch.getType());
+					}
+					sch.ajouter(elements.get(id));
+				}
+				corpus.addSchemaLu(sch);
+			}
+			corpus.verifierFinParagraphesTypesUnites(new String[] {
+					"title", "subTitle", "sectionTitle", "subSectionTitle",
+					"subSubSectionTitle", "subSubSubSectionTitle", "quote", "listItem" });
+			corpus.trierFinParagraphes();
+			corpus.verifierFinParagrapheFinTexte();
+		}
+		
+		@Override
+		public void startElement(String uri, String local, String nomBalise, Attributes attributs) throws SAXException {
+			if (etatCourant == Balise.FLAG) return;
+			switch (balise(nomBalise)) {
+				case FLAG:
+					etatCourant = Balise.FLAG;
+					break;
+				case UNIT:
+					elementCourant = new Unite();
+					elements.put(attributs.getValue("id"), elementCourant);
+					break;
+				case RELATION:
+					elementCourant = new Relation();
+					elements.put(attributs.getValue("id"), elementCourant);
+					idTermes.put((Relation) elementCourant, new ArrayList<String>());
+					break;
+				case SCHEMA:
+					elementCourant = new Schema();
+					elements.put(attributs.getValue("id"), elementCourant);
+					idContenus.put((Schema) elementCourant, new ArrayList<String>());
+					break;
+				case TYPE:
+					etatCourant = Balise.TYPE;
+					valCourant = "";
+					break;
+				case FEATURE:
+					etatCourant = Balise.FEATURE;
+					champCourant = attributs.getValue("name");
+					valCourant = "";
+					break;
+				case START:
+					etatCourant = Balise.START;
+					break;
+				case END:
+					etatCourant = Balise.END;
+					break;
+				case SINGLEPOSITION:
+					if (elementCourant.getClass() != Unite.class) {
+						throw new SAXNotSupportedException("La balise singlePosition ne peut être utilisée que pour des unités");
+					}
+					if (elementCourant.getType().equals("paragraph")) {
+						if (etatCourant == Balise.END) {
+							corpus.addFinParagraphe(Integer.parseInt(attributs.getValue("index")));
+						}
+					}
+					else {
+						switch (etatCourant) {
+							case START:
+								((Unite) elementCourant).setDeb(Integer.parseInt(attributs.getValue("index")));
+								break;
+							case END:
+								((Unite) elementCourant).setFin(Integer.parseInt(attributs.getValue("index")));
+								break;
+						}
+					}
+					break;
+				case TERM:
+					if (elementCourant.getClass() != Relation.class)
+						throw new SAXNotSupportedException("La balise term ne peut être utilisée que pour des relations");
+					idTermes.get(elementCourant).add(attributs.getValue("id"));
+					break;
+				
+				case EMBEDDEDUNIT:
+				case EMBEDDEDRELATION:
+				case EMBEDDEDSCHEMA:
+					if (elementCourant.getClass() != Schema.class)
+						throw new SAXNotSupportedException(
+								"Les balises embedded ne peuvent être utilisées que pour des schémas");
+					idContenus.get(elementCourant).add(attributs.getValue("id"));
+					break;
+				default:
+					// System.out.println("Warning: not supported '" + nomBalise + "' tag while parsing file: " + parsedFile);
+			}
+		}
+		
+		@Override
+		public void endElement(String uri, String local, String nomBalise) throws SAXException {
+			if (etatCourant == Balise.FLAG) {
+				if (balise(nomBalise) == Balise.FLAG) etatCourant = null;
+				return;
+			}
+			String type = "";
+			switch (balise(nomBalise)) {
+				case UNIT:
+					type = elementCourant.getType();
+					if (type == null || type.isEmpty())
+						throw new SAXNotSupportedException("Pas trouvé de type pour cette unité");
+					if (!type.equals("paragraph")) {
+						corpus.addUniteLue((Unite) elementCourant);
+						elementCourant = null;
+					}
+					break;
+				case RELATION:
+					type = elementCourant.getType();
+					if (type == null || type.isEmpty())
+						throw new SAXNotSupportedException("Pas trouvé de type pour cette relation");
+					relations.add((Relation) elementCourant);
+					elementCourant = null;
+					break;
+				case SCHEMA:
+					type = elementCourant.getType();
+					if (type == null || type.isEmpty())
+						throw new SAXNotSupportedException("Pas trouvé de type pour ce shéma");
+					schemas.add((Schema) elementCourant);
+					elementCourant = null;
+					break;
+				case TYPE:
+					elementCourant.setType(valCourant);
+					valCourant = null;
+					etatCourant = null;
+					break;
+				case FEATURE:
+					elementCourant.putProp(champCourant, valCourant);
+					etatCourant = null;
+					champCourant = null;
+					valCourant = null;
+					break;
+				case START:
+					etatCourant = null;
+					break;
+				case END:
+					etatCourant = null;
+					break;
+				default:
+					// System.out.println("Warning: not supported '" + nomBalise + "' tag while parsing: " + parsedFile);
+			}
+		}
+		
+		@Override
+		public void characters(char[] ch, int start, int taille) throws SAXException {
+			if (etatCourant == null || !EnumSet.of(Balise.TYPE, Balise.FEATURE).contains(etatCourant)) {
+				return;
+			}
+			valCourant += new String(ch, start, taille);
+		}
+	}
+	
+	static class ModeleGlozzHandler extends DefaultHandler {
+		
+		Structure structure;
+		
+		boolean listeValeurs = false;
+		
+		Class<? extends Element> classeCourante = Unite.class;  // par défaut : balise <units> sous-entendue
+		
+		String typeCourant = null;
+		
+		String champCourant = null;
+		
+		String valeurCourante = null;
+		
+		File parsedFile;
+		
+		public enum Balise {
+			ANNOTATIONMODEL, UNITS, RELATIONS, SCHEMAS, TYPE, FEATURESET, FEATURE, POSSIBLEVALUES, VALUE
+		};
+		
+		static Balise balise(String nomBalise) throws SAXNotRecognizedException {
+			try {
+				return Balise.valueOf(nomBalise.replaceAll("\\W", "").toUpperCase());
+			}
+			catch (Exception e) {
+				throw new SAXNotRecognizedException("Balise non reconnue : " + nomBalise);
+			}
+		}
+		
+		ModeleGlozzHandler(File parsedFile, Structure structure) {
+			super();
+			this.structure = structure;
+			this.parsedFile = parsedFile;
+		}
+		
+		@Override
+		public void startDocument() {}
+		
+		@Override
+		public void endDocument() throws SAXNotSupportedException {}
+		
+		@Override
+		public void startElement(String uri, String local, String nomBalise, Attributes attributs) throws SAXException {
+			String valdef = null;
+			switch (balise(nomBalise)) {
+				case UNITS:
+					classeCourante = Unite.class;
+					break;
+				case RELATIONS:
+					classeCourante = Relation.class;
+					break;
+				case SCHEMAS:
+					classeCourante = Schema.class;
+					break;
+				case TYPE:
+					typeCourant = attributs.getValue("name");
+					if (typeCourant == null || typeCourant.isEmpty())
+						throw new SAXNotSupportedException("Nom de type absent");
+					structure.ajouterType(classeCourante, typeCourant);
+					break;
+				case FEATURE:
+					if (typeCourant == null || typeCourant.isEmpty())
+						throw new SAXNotSupportedException("Nom de type absent");
+					champCourant = attributs.getValue("name");
+					if (champCourant == null || champCourant.isEmpty())
+						throw new SAXNotSupportedException("Nom de type absent");
+					structure.ajouterProp(classeCourante, typeCourant, champCourant);
+					break;
+				case POSSIBLEVALUES:
+					if (typeCourant == null || typeCourant.isEmpty() || champCourant == null || champCourant.isEmpty())
+						throw new SAXNotSupportedException("Nom de type ou de feature absent");
+					listeValeurs = true;
+					valdef = attributs.getValue("default");
+					if (valdef != null && !valdef.isEmpty())
+						structure.modifierValParDefaut(classeCourante, typeCourant, champCourant, valdef);
+					break;
+				case VALUE:
+					if (listeValeurs) valeurCourante = "";
+					valdef = attributs.getValue("default");
+					if (valdef != null && !valdef.isEmpty()) {
+						if (typeCourant == null || typeCourant.isEmpty() || champCourant == null || champCourant.isEmpty())
+							throw new SAXNotSupportedException("Nom de type ou de feature absent");
+						structure.ajouterVal(classeCourante, typeCourant, champCourant, valdef);
+						structure.modifierValParDefaut(classeCourante, typeCourant, champCourant, valdef);
+					}
+					break;
+				default:
+					// System.out.println("Warning: not supported '" + nomBalise + "' tag while parsing file: " + parsedFile);
+			}
+		}
+		
+		@Override
+		public void endElement(String uri, String local, String nomBalise) throws SAXException {
+			switch (balise(nomBalise)) {
+				case POSSIBLEVALUES:
+					listeValeurs = false;
+					break;
+				case VALUE:
+					if (listeValeurs && valeurCourante != null && !valeurCourante.isEmpty())
+						structure.ajouterVal(classeCourante, typeCourant, champCourant, valeurCourante);
+					break;
+				default:
+					// System.out.println("Warning: not supported '" + nomBalise + "' tag while parsing file: " + parsedFile);
+			}
+		}
+		
+		@Override
+		public void characters(char[] ch, int start, int taille) throws SAXException {
+			if (listeValeurs) {
+				valeurCourante += new String(ch, start, taille);
+			}
+		}
+	}
+	
+	static class GlozzPrinter {
+		
+		Corpus corpus;
+		
+		PrintWriter annot;
+		
+		HashMap<Element, String> idDates = new HashMap<>();
+		
+		String idAuteur = "analec0.2";
+		
+		String idDateParagraphes = "0";
+		
+		String idParagraphes = idAuteur + "_" + idDateParagraphes;
+		
+		GlozzPrinter(Corpus corpus, PrintWriter annot) {
+			this.corpus = corpus;
+			this.annot = annot;
+			attribueIdDates();
+		}
+		
+		void attribueIdDates() {
+			long idDate = (new Date()).getTime();
+			for (Unite unite : corpus.getToutesUnites()) {
+				idDates.put(unite, Long.toString(idDate++));
+			}
+			for (Relation relation : corpus.getToutesRelations()) {
+				idDates.put(relation, Long.toString(idDate++));
+			}
+			for (Schema schema : corpus.getTousSchemas()) {
+				idDates.put(schema, Long.toString(idDate++));
+			}
+		}
+		
+		String getId(Element elt) {
+			return idAuteur + "_" + idDates.get(elt);
+		}
+		
+		void ecrireAnnot() {
+			annot.println("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
+			annot.println("<annotations>");
+			ecrireFinParagraphes();
+			ecrireUnites();
+			ecrireRelations();
+			ecrireSchemas();
+			annot.println("</annotations>");
+		}
+		
+		private void ecrireFinParagraphes() {
+			int deb = 0;
+			for (int fin : corpus.getFinParagraphes()) {
+				ecrireUnite("paragraph", idAuteur, idDateParagraphes, idParagraphes, new HashMap<String, String>(), deb, fin);
+				deb = fin;
+			}
+		}
+		
+		private void ecrireUnites() {
+			for (Unite unit : corpus.getToutesUnites()) {
+				ecrireUnite(unit.getType(), idAuteur, idDates.get(unit), getId(unit), unit.getProps(), unit.getDeb(), unit.getFin());
+			}
+		}
+		
+		private void ecrireRelations() {
+			for (Relation rel : corpus.getToutesRelations()) {
+				ecrireRelation(rel.getType(), idAuteur, idDates.get(rel), getId(rel), rel.getProps(), rel.getElt1(), rel.getElt2());
+			}
+		}
+		
+		private void ecrireSchemas() {
+			for (Schema sch : corpus.getTousSchemas()) {
+				ecrireSchema(sch.getType(), idAuteur, idDates.get(sch), getId(sch), sch.getProps(), sch.getContenu());
+			}
+		}
+		
+		private void ecrireUnite(String type, String idAuteur, String idDate, String id, HashMap<String, String> props, int deb, int fin) {
+			annot.println("<unit id=\"" + id + "\">");
+			ecrireMetadata(idAuteur, idDate);
+			ecrireProps(type, props);
+			ecrirePos(deb, fin);
+			annot.println("</unit>");
+		}
+		
+		private void ecrireRelation(String type, String idAuteur, String idDate, String id, HashMap<String, String> props, Element elt1, Element elt2) {
+			annot.println("<relation id=\"" + id + "\">");
+			ecrireMetadata(idAuteur, idDate);
+			ecrireProps(type, props);
+			ecrireRel(elt1, elt2);
+			annot.println("</relation>");
+		}
+		
+		private void ecrireSchema(String type, String idAuteur, String idDate, String id, HashMap<String, String> props, HashSet<Element> elts) {
+			annot.println("<schema id=\"" + id + "\">");
+			ecrireMetadata(idAuteur, idDate);
+			ecrireProps(type, props);
+			ecrireSch(elts);
+			annot.println("</schema>");
+		}
+		
+		private void ecrireMetadata(String idAuteur, String id) {
+			annot.println("<metadata>");
+			annot.println("<author>" + idAuteur + "</author>");
+			annot.println("<creation-date>" + id + "</creation-date>");
+			annot.println("</metadata>");
+		}
+		
+		private void ecrireProps(String type, HashMap<String, String> props) {
+			annot.println("<characterisation>");
+			annot.println("<type>" + encodeXMLTexte(type) + "</type>");
+			if (props.isEmpty()) {
+				annot.println("<featureSet/>");
+			}
+			else {
+				annot.println("<featureSet>");
+				for (String prop : props.keySet()) {
+					if (props.get(prop) != null) {
+						annot.println("<feature name =\"" + encodeXMLTexte(prop) + "\">"
+								+ encodeXMLTexte(props.get(prop)) + "</feature>");
+					}
+				}
+				annot.println("</featureSet>");
+				
+			}
+			annot.println("</characterisation>");
+		}
+		
+		private void ecrirePos(int deb, int fin) {
+			annot.println("<positioning>");
+			annot.println("<start>");
+			annot.println("<singlePosition index = \"" + deb + "\"/>");
+			annot.println("</start>");
+			annot.println("<end>");
+			annot.println("<singlePosition index = \"" + fin + "\"/>");
+			annot.println("</end>");
+			annot.println("</positioning>");
+		}
+		
+		private void ecrireRel(Element elt1, Element elt2) {
+			annot.println("<positioning>");
+			annot.println("<term id = \"" + getId(elt1) + "\"/>");
+			annot.println("<term id = \"" + getId(elt2) + "\"/>");
+			annot.println("</positioning>");
+		}
+		
+		private void ecrireSch(HashSet<Element> elts) {
+			annot.println("<positioning>");
+			for (Element elt : elts) {
+				Class classe = elt.getClass();
+				if (classe == Unite.class) {
+					annot.print("<embedded-unit ");
+				}
+				if (classe == Relation.class) {
+					annot.print("<embedded-relation ");
+				}
+				if (classe == Schema.class) {
+					annot.print("<embedded-schema ");
+				}
+				annot.println("id = \"" + getId(elt) + "\"/>");
+			}
+			annot.println("</positioning>");
+		}
+	}
+	
+	public static class ModelGlozzPrinter {
+		
+		Structure structure;
+		
+		PrintWriter model;
+		
+		public ModelGlozzPrinter(Structure structure, PrintWriter model) {
+			this.structure = structure;
+			this.model = model;
+		}
+		
+		public void ecrireModel() {
+			model.println("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
+			model.println("<annotationModel>");
+			ecrireUnites();
+			ecrireRelations();
+			ecrireSchemas();
+			model.println("</annotationModel>");
+		}
+		
+		private void ecrireUnites() {
+			model.println("<units>");
+			for (String type : structure.getTypes(Unite.class))
+				ecrireType(Unite.class, type);
+			model.println("</units>");
+		}
+		
+		private void ecrireRelations() {
+			model.println("<relations>");
+			for (String type : structure.getTypes(Relation.class))
+				ecrireType(Relation.class, type);
+			model.println("</relations>");
+		}
+		
+		private void ecrireSchemas() {
+			model.println("<schemas>");
+			for (String type : structure.getTypes(Schema.class))
+				ecrireType(Schema.class, type);
+			model.println("</schemas>");
+		}
+		
+		private void ecrireType(Class<? extends Element> classe, String type) {
+			model.print("<type name=\"" + encodeXMLTexte(type) + "\"");
+			if (classe == Relation.class) model.print(" oriented=\"true\"");
+			model.println(">");
+			model.println("<featureSet>");
+			for (String prop : structure.getNomsProps(classe, type))
+				ecrireProp(classe, type, prop);
+			model.println("</featureSet>");
+			model.println("</type>");
+		}
+		
+		private void ecrireProp(Class<? extends Element> classe, String type, String prop) {
+			model.println("<feature name=\"" + encodeXMLTexte(prop) + "\">");
+			if (structure.getValeursProp(classe, type, prop).isEmpty()) {
+				model.println("<value type=\"free\" default=\"\" />");
+			}
+			else {
+				model.println("<possibleValues default = \""
+						+ structure.getValeurParDefaut(classe, type, prop) + "\">");
+				for (String val : structure.getValeursProp(classe, type, prop))
+					model.println("<value>" + encodeXMLTexte(val) + "</value>");
+				model.println("</possibleValues>");
+			}
+			model.println("</feature>");
+			
+		}
+	}
+	
+	static String encodeXMLTexte(String ch) {
+		// return ch;
+		return ch.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;").replaceAll("\'", "&apos;");
+	}
 }
Index: tmp/org.txm.analec.rcp/plugin.xml
===================================================================
--- tmp/org.txm.analec.rcp/plugin.xml	(revision 2936)
+++ tmp/org.txm.analec.rcp/plugin.xml	(revision 2937)
@@ -443,6 +443,9 @@
    </extension>
    <extension
          point="org.txm.searchengine.core.SearchEngine">
+      <SearchEngine
+            class="org.txm.annotation.urs.search.URSSearchEngine">
+      </SearchEngine>
    </extension>
    <extension
          point="org.eclipse.core.runtime.preferences">
