Index: TXM/trunk/bundles/org.txm.core/src/java/org/txm/core/results/TXMResult.java
===================================================================
--- TXM/trunk/bundles/org.txm.core/src/java/org/txm/core/results/TXMResult.java	(revision 3689)
+++ TXM/trunk/bundles/org.txm.core/src/java/org/txm/core/results/TXMResult.java	(revision 3690)
@@ -5,6 +5,7 @@
 import java.io.IOException;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
 import java.nio.file.Path;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
@@ -73,95 +74,95 @@
  * 
  */
 public abstract class TXMResult implements Cloneable, Comparable<TXMResult> {
-	
+
 	public static final DateFormat ID_TIME_FORMAT = new SimpleDateFormat("yyyyMMdd_HHmmssSSS"); //$NON-NLS-1$
-	
+
 	public static final DateFormat PRETTY_TIME_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); //$NON-NLS-1$
-	
+
 	public static final DateFormat PRETTY_LOCALIZED_TIME_FORMAT = new SimpleDateFormat("dd MMMM yyyy, HH'h'mm", Locale.getDefault()); //$NON-NLS-1$
-	
+
 	public static final String UUID_PREFIX = "txm_res_"; //$NON-NLS-1$
-	
+
 	public static final Pattern FILE_NAME_PATTERN = Pattern.compile("[^a-zA-Z0-9\\.-_]+"); //$NON-NLS-1$
-	
+
 	public static final String UNDERSCORE = "_"; //$NON-NLS-1$
-	
+
 	/**
 	 * Results counter to create unique ids.
 	 */
 	private static int next = 0;
-	
+
 	/**
 	 * The weight, essentially used for sorting purpose.
 	 */
 	protected int weight;
-	
+
 	/**
 	 * the command this command to true when the result needs to be recomputed.
 	 * like after updating parameters
 	 */
 	private boolean dirty = true;
-	
+
 	/**
 	 * If a method changed the internal data without **recomputing** the result, the result must be marked "altered"
 	 */
 	private boolean altered = false;
-	
+
 	/**
 	 * The result parent. Should not be null except for roots TXMResult.
 	 */
 	protected TXMResult parent;
-	
+
 	/**
 	 * Children results.
 	 */
 	protected List<TXMResult> children;
-	
+
 	/**
 	 * Command preferences node path.
 	 */
 	protected String commandPreferencesNodePath;
-	
+
 	/**
 	 * Parameters node path. Concatenation of the Project scope path + the result uuid
 	 */
 	private String parametersNodePath;
-	
+
 	/**
 	 * Thread used when calling compute().
 	 */
 	protected Thread computingThread;
-	
+
 	/**
 	 * To manage the computing cancel with TreadDeath.
 	 */
 	// FIXME: SJ: became useless? 
 	private Semaphore progressSemaphore = new Semaphore(1);
-	
+
 	/**
 	 * To keep track of the parameters used for the last computing and to determine if the result is dirty.
 	 * Also permits to optimize computing by testing if a specific parameter value has changed since last computing and skip or not some computing steps.
 	 */
 	protected ArrayList<HashMap<String, Object>> parametersHistory = null;
-	
+
 	/**
 	 * User persistable state.
 	 */
 	@Parameter(key = TXMPreferences.PERSITABLE, type = Parameter.INTERNAL)
 	private boolean userPersistable;
-	
+
 	/**
 	 * The visibility state.
 	 */
 	@Parameter(key = TXMPreferences.VISIBLE, type = Parameter.INTERNAL)
 	private Boolean visible;
-	
+
 	/**
 	 * The user name (to rename a result).
 	 */
 	@Parameter(key = TXMPreferences.USER_NAME, type = Parameter.INTERNAL)
 	private String userName;
-	
+
 	/**
 	 * To store the simple name for unserialization and lazy loading.
 	 * This string can be used, for example, to display some information in UI even if the result has not yet been recomputed.
@@ -169,38 +170,38 @@
 	// TODO: SJ: we should do the same with getDetails() method
 	@Parameter(key = TXMPreferences.LAZY_NAME, type = Parameter.INTERNAL)
 	private String lazyName;
-	
+
 	/**
 	 * Last computing date.
 	 */
 	@Parameter(key = TXMPreferences.LAST_COMPUTING_DATE, type = Parameter.INTERNAL)
 	private Date lastComputingDate;
-	
+
 	/**
 	 * Creation date.
 	 */
 	@Parameter(key = TXMPreferences.CREATION_DATE, type = Parameter.INTERNAL)
 	private Date creationDate;
-	
+
 	/**
 	 * If locked, the result is not updated when computed.
 	 */
 	@Parameter(key = TXMPreferences.LOCK, type = Parameter.INTERNAL)
 	private Boolean locked = false;
-	
+
 	/**
 	 * Current computing state.
 	 * True if the result is in the process of computing (is in compute(,) method)
 	 */
 	private boolean computing = false;
-	
+
 	/**
 	 * Synchronization state between this result and its parent.
 	 * If true, computing the parent will always also computes this child.
 	 */
 	protected boolean synchronizedWithParent = false;
-	
-	
+
+
 	/**
 	 * Creates a new TXMResult, child of the specified parent.
 	 * 
@@ -209,7 +210,7 @@
 	public TXMResult(TXMResult parent) {
 		this(null, parent);
 	}
-	
+
 	/**
 	 * Creates a new TXMResult with no parent.
 	 * If a local preference node exists with parent_parameters_node_path value, the parent will be retrieved and this result will be added to it.
@@ -219,7 +220,7 @@
 	public TXMResult(String parametersNodePath) {
 		this(parametersNodePath, null);
 	}
-	
+
 	/**
 	 * Creates a new TXMResult, child of the specified parent.
 	 * If the parameters node path is null, a new path is generated from the project root path ending by a new generated UUID.
@@ -234,7 +235,7 @@
 		if (parent != null) {
 			parent.addChild(this);
 		}
-		
+
 		// new result
 		if (parametersNodePath == null) {
 			if (this.getProject() != null) {
@@ -243,45 +244,45 @@
 			else {
 				parametersNodePath = ""; //$NON-NLS-1$
 			}
-			
+
 			this.parametersNodePath = parametersNodePath + createUUID() + "_" + this.getClass().getSimpleName(); //$NON-NLS-1$ ;
 		}
 		// lazy result (persistence / import) or linked result ("send to" commands)
 		else {
 			this.parametersNodePath = parametersNodePath;
 		}
-		
+
 		Log.finest("TXMResult.TXMResult(): parameters node path: " + this.parametersNodePath + "."); //$NON-NLS-1$ //$NON-NLS-2$
-		
+
 		this.weight = 0;
-		
+
 		this.children = new ArrayList<>(1);
 		// this.children = Collections.synchronizedList(new ArrayList<TXMResult>()); // FIXME: SJ: can fix the concurrent exception if needed when accessing children from multiple threads
-		
+
 		this.commandPreferencesNodePath = FrameworkUtil.getBundle(getClass()).getSymbolicName();
 		Log.finest("TXMResult.TXMResult(): command preferences node path: " + this.commandPreferencesNodePath + "."); //$NON-NLS-1$ //$NON-NLS-2$
-		
+
 		this.visible = true;
 		this.dirty = true;
-		
+
 		// set result as persistent if AUTO_PERSISTENCE_ENABLED preference is activated
 		if (TBXPreferences.getInstance().getBoolean(TBXPreferences.AUTO_PERSISTENCE_ENABLED)) {
 			this.saveParameter(TXMPreferences.PERSITABLE, true);
 		}
-		
+
 		// retrieving parent from UUID/node path
 		String parentNodePath = this.getStringParameterValue(TXMPreferences.PARENT_PARAMETERS_NODE_PATH);
-		
+
 		// System.out.println("TXMResult.TXMResult(): parent UUID = " + parentUUID);
-		
-		 // search for parent only if UUID != "ROOT"
+
+		// search for parent only if UUID != "ROOT"
 		if (!("ROOT".equals(this.parametersNodePath)) && //$NON-NLS-1$
 				parent == null &&
 				this.parametersNodePath != null &&
 				!parentNodePath.isEmpty()) {
-			
+
 			Log.finest("Searching parent with UUID/node path " + parentNodePath + "..."); //$NON-NLS-1$ //$NON-NLS-2$
-			
+
 			TXMResult retrievedParent = null;
 			if (this.getProject() != null) {
 				retrievedParent = TXMResult.getResult(this.getProject(), parentNodePath); // works only if parent and child are in the same project (which should be).
@@ -301,17 +302,17 @@
 					TBXPreferences.delete(this);
 				}
 				catch (Exception e) {
-					
+
 				}
 				return;
 			}
 		}
-		
+
 		// loads parameters from local result node, current command preferences or default command preferences
 		try {
 			this.autoLoadParametersFromAnnotations(); // auto fill from Parameter annotations
 			this.loadParameters(); // subclasses manual settings
-			
+
 			try {
 				if (this.creationDate == null) {
 					this.creationDate = Calendar.getInstance().getTime();
@@ -327,13 +328,13 @@
 			Log.severe("Fail to load the " + parametersNodePath + " result: " + e); //$NON-NLS-1$ //$NON-NLS-2$
 			Log.printStackTrace(e);
 		}
-		
+
 		// Log
 		if (this.parent == null) {
 			Log.finest("Warning: the TXMResult of " + this.getClass() + " is attached to no parent. (uuid = " + this.parametersNodePath + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-1$
 		}
 	}
-	
+
 	/**
 	 * Sets the user name.
 	 * 
@@ -342,41 +343,41 @@
 	public void setUserName(String name) {
 		this.userName = name;
 	}
-	
+
 	/**
 	 * @return true if the internal data has been modified
 	 */
 	public boolean isAltered() {
 		return altered;
 	}
-	
+
 	/**
 	 * Mark the result as altered -> modifications are lost after a re-compute
 	 */
 	public void setAltered() {
 		this.altered = true;
 	}
-	
+
 	/**
 	 * Do something when project is closed
 	 */
 	public void onProjectClose() {
-		
+
 	}
-	
+
 	/**
 	 * Do something when project is opened
 	 */
 	public void onProjectOpen() {
-		
+
 	}
-	
+
 	/**
 	 * Locks/unlocks the result.
 	 */
 	public void setLocked(boolean state) {
 		this.locked = state;
-		
+
 		if (this.locked && this.parent != null) {
 			this.parent.setLocked(true);
 		}
@@ -386,14 +387,14 @@
 			}
 		}
 	}
-	
+
 	/**
 	 * @return true if the result is locked
 	 */
 	public boolean isLocked() {
 		return this.locked;
 	}
-	
+
 	/**
 	 * Creates an UUID dedicated to preferences/parameters storing and to persistence of a result.
 	 * 
@@ -402,7 +403,7 @@
 	public static String createUUID() {
 		return UUID_PREFIX + ID_TIME_FORMAT.format(new Date(System.currentTimeMillis())) + "_" + nextInt();
 	}
-	
+
 	/**
 	 * 
 	 * @return the next integer in the current session of TXM
@@ -410,7 +411,7 @@
 	private static synchronized String nextInt() {
 		return String.format("%04d", next++); //$NON-NLS-1$
 	}
-	
+
 	/**
 	 * Checks if the result has at least one child.
 	 * 
@@ -419,8 +420,8 @@
 	public boolean hasChildren() {
 		return this.children.size() > 0;
 	}
-	
-	
+
+
 	/**
 	 * Gets the preferences node path of the result linked command.
 	 * 
@@ -429,16 +430,16 @@
 	public String getCommandPreferencesNodePath() {
 		return this.commandPreferencesNodePath;
 	}
-	
-	
+
+
 	public String[] getCommandPreferencesKeys() throws BackingStoreException {
 		return TXMPreferences.getCommandScopeKeys(this.commandPreferencesNodePath);
 	}
-	
+
 	public String[] getDefaultPreferencesKeys() throws BackingStoreException {
 		return TXMPreferences.getDefaultScopeKeys(this.commandPreferencesNodePath);
 	}
-	
+
 	/**
 	 * Gets a current parameter specified by its annotation "key".
 	 * 
@@ -449,7 +450,7 @@
 	public Object getParameter(String key) {
 		return getParameter(key, false);
 	}
-	
+
 	/**
 	 * Gets a current parameter specified by its annotation "key".
 	 * 
@@ -474,7 +475,7 @@
 		}
 		return null;
 	}
-	
+
 	/**
 	 * Stores the parameters of the specified types used during last computing in the specified HashMap.
 	 * 
@@ -483,15 +484,15 @@
 	 * @throws Exception
 	 */
 	protected void updateLastParameters(ArrayList<Integer> parametersTypes, HashMap<String, Object> lastParameters) throws Exception {
-		
+
 		List<Field> fields = BeanParameters.getAllFields(this);
-		
+
 		for (Field f : fields) {
 			Parameter parameter = f.getAnnotation(Parameter.class);
 			if (parameter == null || !parametersTypes.contains(parameter.type())) {
 				continue;
 			}
-			
+
 			String name;
 			if (!parameter.key().isEmpty()) {
 				name = parameter.key();
@@ -499,20 +500,20 @@
 			else {
 				name = f.getName();
 			}
-			
+
 			f.setAccessible(true);
 			lastParameters.put(name, f.get(this));
 		}
-		
+
 		// if (lastParameters.isEmpty()) {
 		// System.out.println("TXMResult.updateLastParameters() empty");
 		// }
-		
+
 		if (this.parametersHistory == null) { // 
 			this.parametersHistory = new ArrayList<HashMap<String,Object>>();
 		}
 		this.parametersHistory.add(lastParameters);
-		
+
 		// truncate the stack to the max count
 		// FIXME: SJ: later, store this in a TBX preference
 		if (this.parametersHistory.size() > 5) {
@@ -521,7 +522,7 @@
 			this.parametersHistory.remove(0);
 		}
 	}
-	
+
 	/**
 	 * Stores the last parameters of the specified types used during last computing.
 	 * 
@@ -531,7 +532,7 @@
 	protected void updateLastParameters(ArrayList<Integer> parametersTypes) throws Exception {
 		this.updateLastParameters(parametersTypes, new HashMap<>());
 	}
-	
+
 	/**
 	 * Stores the last parameters used during last computing.
 	 * 
@@ -542,8 +543,8 @@
 		parametersTypes.add(Parameter.COMPUTING);
 		this.updateLastParameters(parametersTypes);
 	}
-	
-	
+
+
 	/**
 	 * Removes all the parameters of the specified type from the last parameters history.
 	 * 
@@ -551,17 +552,17 @@
 	 * @throws Exception
 	 */
 	protected void clearLastParameters(int parameterType) {
-		
+
 		if (parametersHistory == null) return; // nothing to do
-		
+
 		List<Field> fields = BeanParameters.getAllFields(this);
-		
+
 		for (Field f : fields) {
 			Parameter parameter = f.getAnnotation(Parameter.class);
 			if (parameter == null || parameter.type() != parameterType) {
 				continue;
 			}
-			
+
 			String name;
 			if (!parameter.key().isEmpty()) {
 				name = parameter.key();
@@ -569,7 +570,7 @@
 			else {
 				name = f.getName();
 			}
-			
+
 			f.setAccessible(true);
 			try {
 				this.getLastParametersFromHistory().remove(name);
@@ -578,8 +579,8 @@
 				// nothing to do if the stack is empty
 			}
 		}
-		
-		
+
+
 		try {
 			if (this.parametersHistory != null && !this.getLastParametersFromHistory().isEmpty()) {
 				this.parametersHistory.remove(this.parametersHistory.size() - 1);
@@ -589,8 +590,8 @@
 			// nothing to do if the stack is empty
 		}
 	}
-	
-	
+
+
 	/**
 	 * Checks if a parameter value has changed since last computing.
 	 * 
@@ -599,12 +600,12 @@
 	 * @return
 	 */
 	public boolean hasParameterChanged(String key) {
-		
+
 		if (parametersHistory == null) return true;
-		
+
 		return this.hasParameterChanged(key, this.getLastParametersFromHistory());
 	}
-	
+
 	/**
 	 * Checks if a parameter value has changed since last computing according to the specified external map.
 	 * 
@@ -613,15 +614,15 @@
 	 * @return
 	 */
 	public boolean hasParameterChanged(String key, HashMap<String, Object> lastParameters) {
-		
+
 		if (lastParameters == null) {
 			return true;
 		}
-		
+
 		if (key.isEmpty()) {
 			return false;
 		}
-		
+
 		Object lastValue = lastParameters.get(key);
 		Object newValue = this.getParameter(key, true);
 		if (lastValue == null) {
@@ -636,7 +637,7 @@
 			return !lastValue.equals(newValue);
 		}
 	}
-	
+
 	/**
 	 * Checks if at least one parameter value of the specified parameter type has changed since last computing according to the specified external map.
 	 * 
@@ -645,16 +646,16 @@
 	 * @return
 	 */
 	public boolean hasParametersChanged(HashMap<String, Object> lastParameters, int parameterType) throws Exception {
-		
+
 		// result has never been computed
 		if (lastParameters == null) {
 			return true;
 		}
-		
+
 		boolean hasParameterChanged = false;
-		
+
 		List<Field> fields = BeanParameters.getAllFields(this);
-		
+
 		for (Field f : fields) {
 			Parameter parameter = f.getAnnotation(Parameter.class);
 			if (parameter == null || parameter.type() != parameterType) {
@@ -667,21 +668,21 @@
 			else {
 				name = f.getName();
 			}
-			
+
 			f.setAccessible(true); // to be able to test the field values
-			
+
 			hasParameterChanged = this.hasParameterChanged(name, lastParameters);
-			
+
 			if (hasParameterChanged) {
 				Log.finest("TXMResult.hasParameterChanged(): " + this.getClass().getSimpleName() + ": parameter " + name + " has changed (type = " + parameterType + ").");
 				break;
 			}
 		}
-		
+
 		return hasParameterChanged;
 	}
-	
-	
+
+
 	/**
 	 * Checks if at least one computing parameter value has changed since last computing.
 	 * 
@@ -690,35 +691,35 @@
 	 */
 	public boolean hasParametersChanged() throws Exception {
 		if (parametersHistory == null) return true;
-		
+
 		return this.hasParametersChanged(this.getLastParametersFromHistory(), Parameter.COMPUTING);
 	}
-	
-	
+
+
 	/**
 	 * Dumps the result current parameters, the command user preferences and the command default preferences linked to the result.
 	 * 
 	 * @return
 	 */
 	public String dumpPreferences() {
-		
+
 		StringBuilder str = new StringBuilder();
-		
+
 		if (TXMPreferences.resultScopeNodeExists(this)) {
 			str.append("\nResult local node preferences\n"); //$NON-NLS-1$
 			str.append(TXMPreferences.getKeysAndValues(this.getParametersNodePath()));
 		}
-		
+
 		str.append("\nCommand preferences\n"); //$NON-NLS-1$
 		str.append(TXMPreferences.getKeysAndValues(this.commandPreferencesNodePath));
-		
+
 		str.append("\nDefault command preferences\n"); //$NON-NLS-1$
 		str.append(TXMPreferences.getKeysAndValues(DefaultScope.INSTANCE + "/" + this.commandPreferencesNodePath));
-		
+
 		return str.toString();
 	}
-	
-	
+
+
 	/**
 	 * Dumps the result computing parameters (Parameter annotation).
 	 * 
@@ -727,8 +728,8 @@
 	public String dumpParameters() {
 		return this.dumpParameters(Parameter.COMPUTING);
 	}
-	
-	
+
+
 	/**
 	 * Dumps the result computing parameters (Parameter annotation).
 	 * 
@@ -736,20 +737,20 @@
 	 * @return
 	 */
 	public String dumpParameters(int parametersType) {
-		
+
 		StringBuilder str = new StringBuilder();
-		
+
 		str.append("Parameters (type = " + parametersType + " / " + Parameter.types[parametersType] + ")\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-		
+
 		List<Field> fields = BeanParameters.getAllFields(this);
-		
+
 		for (Field f : fields) {
 			Parameter parameter = f.getAnnotation(Parameter.class);
 			if (parameter == null || parameter.type() != parametersType) {
 				continue;
 			}
 			f.setAccessible(true);
-			
+
 			String name;
 			if (!parameter.key().isEmpty()) {
 				name = parameter.key();
@@ -757,7 +758,7 @@
 			else {
 				name = f.getName();
 			}
-			
+
 			try {
 				Object v = f.get(this);
 				if (v != null) {
@@ -778,9 +779,9 @@
 		}
 		return str.toString();
 	}
-	
-	
-	
+
+
+
 	// /**
 	// * Updates the dirty state by comparing an old parameter with a new one.
 	// *
@@ -796,7 +797,7 @@
 	// this.setDirty();
 	// }
 	// }
-	
+
 	/**
 	 * Sets the dirty state to true if a parameter has changed since last computing.
 	 * 
@@ -857,12 +858,12 @@
 		// else {
 		// return this.hasParameterChanged();
 		// }
-		
+
 		if (this.hasParametersChanged()) {
 			this.dirty = true;
 		}
 	}
-	
+
 	/**
 	 * Gets the list of parameters used during last computing or null if the result has not been computed yet.
 	 * 
@@ -877,7 +878,7 @@
 			return null;
 		}
 	}
-	
+
 	/**
 	 * TODO seems to work but the TXMEditor.compute() method re-use the widgets values and the parametersHistory is appended with the 'new' parameters
 	 * 
@@ -886,17 +887,17 @@
 	public void revertParametersFromHistory() throws Exception {
 		ArrayList<HashMap<String, Object>> history = getParametersHistory();
 		if (history == null) return; // nothing to do
-		
+
 		if (history.size() < 2) return; // nothing to do
-		
+
 		history.remove(history.size() - 1);
-		
+
 		HashMap<String, Object> last = history.get(history.size() - 1);
-		
+
 		this.setParameters(last); // auto
 	}
-	
-	
+
+
 	/**
 	 * Dumps the parameters history stack to the specified StringBuffer.
 	 * 
@@ -914,8 +915,8 @@
 			}
 		}
 	}
-	
-	
+
+
 	/**
 	 * Gets the dirty state.
 	 * 
@@ -924,7 +925,7 @@
 	public boolean isDirty() {
 		return this.dirty;
 	}
-	
+
 	/**
 	 * Marks the result as dirty so editors or others will know the TXMResult needs to be recomputed.
 	 * This method is also recursively called on all the children branch to mark them as dirty.
@@ -932,7 +933,7 @@
 	public void setDirty() {
 		this.setDirty(true);
 	}
-	
+
 	/**
 	 * Sets the result dirty state so editors or others will know the TXMResult needs to be recomputed or not.
 	 * This method is also recursively called on all the children branch sets the new dirty state.
@@ -947,7 +948,7 @@
 			}
 		}
 	}
-	
+
 	/**
 	 * Gets the value of the specified key in parameters, local result node or
 	 * default preferences nodes.
@@ -958,7 +959,7 @@
 	public int getIntParameterValue(String key) {
 		return TXMPreferences.getInt(key, this, this.commandPreferencesNodePath);
 	}
-	
+
 	/**
 	 * Gets the value of the specified key in parameters, local result node or
 	 * default preferences nodes.
@@ -969,7 +970,7 @@
 	public float getFloatParameterValue(String key) {
 		return TXMPreferences.getFloat(key, this, this.commandPreferencesNodePath);
 	}
-	
+
 	/**
 	 * Gets the value of the specified key in parameters, local result node or
 	 * default preferences nodes.
@@ -980,7 +981,7 @@
 	public double getDoubleParameterValue(String key) {
 		return TXMPreferences.getDouble(key, this, this.commandPreferencesNodePath);
 	}
-	
+
 	/**
 	 * Gets the value of the specified key in parameters, local result node or
 	 * default preferences nodes.
@@ -991,7 +992,7 @@
 	public boolean getBooleanParameterValue(String key) {
 		return TXMPreferences.getBoolean(key, this, this.commandPreferencesNodePath);
 	}
-	
+
 	/**
 	 * Gets the value of the specified key in parameters, local result node or
 	 * default preferences nodes.
@@ -1002,7 +1003,7 @@
 	public long getLongParameterValue(String key) {
 		return TXMPreferences.getLong(key, this, this.commandPreferencesNodePath);
 	}
-	
+
 	/**
 	 * Gets the value of the specified key in parameters, local result node or
 	 * default preferences nodes.
@@ -1013,7 +1014,7 @@
 	public String getStringParameterValue(String key) {
 		return TXMPreferences.getString(key, this, this.commandPreferencesNodePath);
 	}
-	
+
 	/**
 	 * Gets the value of the specified key in parameters, local result node or
 	 * default preferences nodes.
@@ -1024,7 +1025,7 @@
 	public Date getDateParameterValue(String key) {
 		return TXMPreferences.getDate(key, this, this.commandPreferencesNodePath);
 	}
-	
+
 	/**
 	 * Gets the value of the specified key in parameters, local result node or
 	 * default preferences nodes.
@@ -1041,8 +1042,8 @@
 			return null;
 		}
 	}
-	
-	
+
+
 	/**
 	 * Checks if the specified parameter exists.
 	 * 
@@ -1052,7 +1053,7 @@
 	public boolean parameterExists(String key) {
 		return TXMPreferences.keyExists(this.parametersNodePath, key);
 	}
-	
+
 	/**
 	 * Checks if a preference is empty (equals to "") in the command preference node.
 	 * An empty preference can be used to disable a functionality for a kind of result
@@ -1064,7 +1065,7 @@
 	public boolean isEmptyPreference(String key) {
 		return TXMPreferences.isEmpty(this.commandPreferencesNodePath, key);
 	}
-	
+
 	/**
 	 * Stores the specified parameters pairs of key/value in a local node dedicated to the specified result. The node qualifier is generated by the <code>TXMResult.getUUID</code> method.
 	 * 
@@ -1074,8 +1075,8 @@
 	public void saveParameter(String key, List<?> values) {
 		this.saveParameter(key, StringUtils.join(values, UNDERSCORE));
 	}
-	
-	
+
+
 	/**
 	 * Stores the specified parameters pairs of key/value in a local node dedicated to the specified result. The node qualifier is generated by the <code>TXMResult.getUUID</code> method.
 	 * 
@@ -1086,11 +1087,11 @@
 	public void saveParameter(String key, Object value) {
 		// FIXME: debug
 		// Log.info("TXMResult.saveParameter(): saving parameter " + key + " = " + value + " for " + this.getClass() + " (" + value.getClass() + ") to node.");
-		
+
 		TXMPreferences.putLocal(this, key, value);
 	}
-	
-	
+
+
 	/**
 	 * Stores the result parameter fields declared by their @Parameter annotation in the persisted result node preferences.
 	 * One have to implement saveParameters() to save parameters that are not of primitive types (e.g. Property, List, HashMap...)
@@ -1099,9 +1100,9 @@
 	 * @throws Exception
 	 */
 	public boolean autoSaveParametersFromAnnotations() throws Exception {
-		
+
 		Log.finest("TXMResult.autoSaveParametersFromAnnotations(): " + this.getClass().getSimpleName() + ": saving parameters to local node...");
-		
+
 		// internal data to save for unserialization
 		if (this.getClass().isAnonymousClass()) {
 			this.saveParameter(TXMPreferences.CLASS, this.getClass().getSuperclass().getName()); // avoid bug later if an anonymous class has been used.
@@ -1110,18 +1111,18 @@
 		}
 		this.saveParameter(TXMPreferences.RESULT_PARAMETERS_NODE_PATH, this.parametersNodePath);
 		this.saveParameter(TXMPreferences.BUNDLE_ID, FrameworkUtil.getBundle(getClass()).getSymbolicName());
-		
-		
+
+
 		if (this.parent != null) {
 			this.saveParameter(TXMPreferences.PARENT_PARAMETERS_NODE_PATH, this.parent.getParametersNodePath());
 		}
-		
+
 		if (hasBeenComputedOnce()) {
 			this.lazyName = this.getSimpleName();
 		}
-		
+
 		List<Field> fields = BeanParameters.getAllFields(this);
-		
+
 		for (Field f : fields) {
 			Parameter parameter = f.getAnnotation(Parameter.class);
 			if (parameter == null) {
@@ -1131,20 +1132,20 @@
 			if (key.isEmpty()) {
 				continue; // no preference key defined
 			}
-			
+
 			if (f.getType().isAssignableFrom(int.class) || f.getType().isAssignableFrom(Integer.class) ||
 					f.getType().isAssignableFrom(double.class) || f.getType().isAssignableFrom(Double.class) ||
 					f.getType().isAssignableFrom(float.class) || f.getType().isAssignableFrom(Float.class) ||
 					f.getType().isAssignableFrom(boolean.class) || f.getType().isAssignableFrom(Boolean.class) ||
 					f.getType().isAssignableFrom(String.class) || f.getType().isAssignableFrom(File.class)
-			
-			// FIXME: do not pass a Serializable for now
-			// || !f.getType().isAssignableFrom(Serializable.class)
-			// || !Serializable.class.isInstance(f)
-			
-			) {
-				
-				
+
+					// FIXME: do not pass a Serializable for now
+					// || !f.getType().isAssignableFrom(Serializable.class)
+					// || !Serializable.class.isInstance(f)
+
+					) {
+
+
 				f.setAccessible(true); // set accessible to test the field values
 				try {
 					Object value = f.get(this);
@@ -1171,7 +1172,7 @@
 		}
 		return true;
 	}
-	
+
 	/**
 	 * Dedicated to stores the result parameters in the persisted result node preferences.
 	 * One have to implement this method to save parameters that are not of primitive types (e.g. Property, List, HashMap...)
@@ -1181,7 +1182,7 @@
 	 * @throws Exception
 	 */
 	public abstract boolean saveParameters() throws Exception;
-	
+
 	/**
 	 * calls saveParameters() on this and children if childrenAsWell is set to true
 	 * 
@@ -1192,9 +1193,9 @@
 	 * @throws Exception
 	 */
 	public boolean saveParameters(boolean childrenAsWell) throws Exception {
-		
+
 		boolean ret = true;
-		
+
 		if (this.mustBePersisted()) {
 			ret = this.saveParameters();
 			if (childrenAsWell) {
@@ -1205,7 +1206,7 @@
 		}
 		return ret;
 	}
-	
+
 	// FIXME: SJ: this method should not call persist on children if childrenAsWell == false?
 	public void persist(boolean childrenAsWell) {
 		if (this.mustBePersisted()) {
@@ -1215,7 +1216,7 @@
 			}
 		}
 	}
-	
+
 	/**
 	 *  load or reload parameters from the preference store node
 	 * @return
@@ -1224,7 +1225,7 @@
 	public boolean autoLoadParametersFromAnnotations() throws Exception {
 		return this.autoLoadParametersFromAnnotations(Parameter.COMPUTING) && this.autoLoadParametersFromAnnotations(Parameter.INTERNAL);
 	}
-	
+
 	/**
 	 * Fills the result parameter fields declared by their @Parameter annotation from the persisted result node or default node of the preferences.
 	 * One have to implement loadParameters() to load parameters that are not of primitive types (e.g. Property, List, HashMap...)
@@ -1233,26 +1234,26 @@
 	 * @throws Exception
 	 */
 	protected boolean autoLoadParametersFromAnnotations(int parameterType) throws Exception {
-		
+
 		List<Field> fields = BeanParameters.getAllFields(this);
-		
+
 		for (Field f : fields) {
-			
+
 			Parameter parameter = f.getAnnotation(Parameter.class);
 			if (parameter == null || parameter.type() != parameterType) {
 				continue;
 			}
-			
+
 			String key = parameter.key();
-			
+
 			if (key.isEmpty()) {
 				continue; // no preference key defined for the parameter so it can't be filled with default value or result persistence value from preferences nodes
 			}
 			try {
 				f.setAccessible(true); // set accessible to test the field values
-				
+
 				Object value = null;
-				
+
 				// only manage primitive types
 				if (f.getType().isAssignableFrom(String.class)) {
 					value = this.getStringParameterValue(key);
@@ -1284,10 +1285,10 @@
 				// SJ: or better, when the abstraction of Property, etc. will be done, we could implement some extensions as in ChartCreator model to other engines, eg. SearchEngine, that will return
 				// the right class here
 				f.set(this, value);
-				
+
 				// FIXME: Debug
 				Log.finest("TXMResult.autoLoadParametersFromAnnotations(): setting parameter " + key + " = " + value + "\t[" + this.getClass() + "]");
-				
+
 			}
 			catch (Exception e) {
 				e.printStackTrace();
@@ -1295,7 +1296,7 @@
 		}
 		return true;
 	}
-	
+
 	/**
 	 * Method dedicated to manually create and load non primitive parameters from strings stored in preference nodes in subclasses.
 	 * This method is called by the constructor of the class TXMResult.
@@ -1305,7 +1306,7 @@
 	 * @throws Exception
 	 */
 	public abstract boolean loadParameters() throws Exception;
-	
+
 	/**
 	 * Initializes the @Parameter class members objects
 	 * 
@@ -1313,7 +1314,7 @@
 	 * @return
 	 */
 	public abstract boolean setParameters(TXMParameters parameters) throws Exception;
-	
+
 	/**
 	 * Initializes the @Parameter class members objects
 	 * 
@@ -1324,7 +1325,7 @@
 	public final boolean setParameters(HashMap<String, Object> parameters) throws Exception {
 		return setParameters(new TXMParameters(parameters));
 	}
-	
+
 	/**
 	 * Sets a parameter from its parameter annotation "key".
 	 * 
@@ -1336,7 +1337,7 @@
 	public boolean setParameter(String key, Object value) throws Exception {
 		return setParameter(key, value, false);
 	}
-	
+
 	/**
 	 * Sets a parameter from its parameter annotation "key".
 	 * 
@@ -1348,25 +1349,25 @@
 	 * @throws Exception
 	 */
 	public boolean setParameter(String key, Object value, boolean propagateToParent) throws Exception {
-		
+
 		Field targetField = BeanParameters.getField(this, key);
-		
+
 		if (targetField != null) {
 			targetField.setAccessible(true);
 			targetField.set(this, value);
-			
+
 			// Log
 			String message = "TXMResult.setParameter(): " + this.getClass().getSimpleName() + ": setting parameter " + key + " = " + value; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 			Log.finest(message);
-			
+
 		}
 		else if (this.parent != null && propagateToParent) {
 			this.parent.setParameter(key, value, propagateToParent);
 		}
-		
+
 		return true;
 	}
-	
+
 	/**
 	 * Deletes the object from its parent, also deletes the children. The <code>TXMResult.clean()</code> methods of this result and children results are applied before the deletion.
 	 * default behavior is not silent
@@ -1376,7 +1377,7 @@
 	public final boolean delete() {
 		return delete(false);
 	}
-	
+
 	/**
 	 * Deletes the object from its parent, also deletes the children. The <code>TXMResult.clean()</code> methods of this result and children results are applied before the deletion.
 	 * 
@@ -1384,13 +1385,13 @@
 	 * @return
 	 */
 	public final boolean delete(boolean silent) {
-		
+
 		try {
 			// FIXME: debug
 			// System.err.println("TXMResult.delete()");
-			
+
 			// START WITH CHILDREN
-			
+
 			// remove children and clean resources
 			while (this.children.size() > 0) {
 				TXMResult c = this.children.get(0);
@@ -1398,34 +1399,33 @@
 				this.children.remove(c); // but should be done already...
 			}
 			this.children.clear();
-			
+
 			// THEN FINISH WITH THIS
 			// delete the local node
 			TXMPreferences.delete(this);
-			
+
 			// specific cleaning
 			this.clean();
-			
+
 			// log
-			if ((this.isVisible()
-					&& !silent) || Log.isLoggingFineLevel()) {
+			if ((this.isVisible() && !silent) || Log.isLoggingFineLevel()) {
 				Log.info(TXMCoreMessages.bind(TXMCoreMessages.info_p0P1Deleted, this.getResultType(), this.getSimpleName()));
 			}
-			
+
 			// removes the parent only after the log since getSimpleName() can use it
 			if (this.parent != null) {
 				this.parent.removeChild(this);
 			}
-			
+
 			return true;
 		}
 		catch (Exception e) {
 			e.printStackTrace();
 		}
-		
+
 		return false;
 	}
-	
+
 	/**
 	 * Deletes all non persistent results and saves the results to persist.
 	 */
@@ -1444,8 +1444,8 @@
 			}
 		}
 	}
-	
-	
+
+
 	/**
 	 * Gets a child specified by its index in the children list.
 	 * 
@@ -1460,7 +1460,7 @@
 			return null;
 		}
 	}
-	
+
 	/**
 	 * Adds a child result to this result.
 	 * If the child already have a parent, the child will be remove from its old parent children.
@@ -1472,7 +1472,7 @@
 		try {
 			// remove from current parent if exists
 			child.removeFromParent();
-			
+
 			child.setParent(this);
 			if (!this.children.contains(child)) {
 				return this.children.add(child);
@@ -1484,7 +1484,7 @@
 		}
 		return false;
 	}
-	
+
 	/**
 	 * Inserts a child result in this result children list at the specified position.
 	 * 
@@ -1504,7 +1504,7 @@
 		}
 		return false;
 	}
-	
+
 	/**
 	 * Removes the specified child result.
 	 * 
@@ -1520,7 +1520,7 @@
 		}
 		return false;
 	}
-	
+
 	/**
 	 * Removes the child result specified by its index.
 	 * 
@@ -1532,11 +1532,11 @@
 			return this.removeChild(this.children.get(index));
 		}
 		catch (Exception e) {
-			
+
 		}
 		return false;
 	}
-	
+
 	/**
 	 * Removes the result from its parent: call the parent's removeResult method.
 	 * 
@@ -1547,12 +1547,12 @@
 			return this.parent.removeChild(this);
 		}
 		catch (Exception e) {
-			
+
 		}
 		return false;
 	}
-	
-	
+
+
 	/**
 	 * Checks if the result has at least one child visible.
 	 * 
@@ -1561,8 +1561,8 @@
 	public boolean hasVisibleChild() {
 		return !this.getChildren(true).isEmpty();
 	}
-	
-	
+
+
 	/**
 	 * Gets all the children results (not a clone).
 	 * 
@@ -1571,7 +1571,7 @@
 	public List<TXMResult> getChildren() {
 		return this.children;
 	}
-	
+
 	/**
 	 * Gets the children results.
 	 * 
@@ -1580,7 +1580,7 @@
 	public List<TXMResult> getChildren(boolean onlyVisible) {
 		return this.getChildren(null, onlyVisible);
 	}
-	
+
 	/**
 	 * Gets the children results specified by their class.
 	 * 
@@ -1590,7 +1590,7 @@
 	public <T extends TXMResult> List<T> getChildren(Class<T> clazz) {
 		return TXMResult.getNodes(this.children, clazz, false);
 	}
-	
+
 	/**
 	 * Gets the children results specified by their class.
 	 * 
@@ -1600,7 +1600,7 @@
 	public <T extends TXMResult> List<T> getChildren(Class<T> clazz, boolean onlyVisible) {
 		return TXMResult.getNodes(this.children, clazz, onlyVisible);
 	}
-	
+
 	/**
 	 * Gets the first child result specified by its class.
 	 * 
@@ -1616,7 +1616,7 @@
 			return null;
 		}
 	}
-	
+
 	/**
 	 * Deletes all the children
 	 * 
@@ -1625,7 +1625,7 @@
 	public void deleteChildren() {
 		deleteChildren(null);
 	}
-	
+
 	/**
 	 * Deletes the children of the specified class.
 	 * 
@@ -1638,9 +1638,9 @@
 			children.get(i).delete();
 		}
 	}
-	
-	
-	
+
+
+
 	/**
 	 * Gets the children of all the branch of the specified node in a flat list according to their specified class.
 	 * 
@@ -1650,10 +1650,10 @@
 	 */
 	@SuppressWarnings("unchecked")
 	protected static <T extends TXMResult> List<T> getDeepChildren(TXMResult parent, Class<T> clazz) {
-		
+
 		List<T> results = new ArrayList<>();
 		List<TXMResult> children = parent.getChildren();
-		
+
 		for (int i = 0; i < children.size(); i++) {
 			TXMResult child = children.get(i);
 			if (clazz == null || child.getClass().isAssignableFrom(clazz)) {
@@ -1663,7 +1663,7 @@
 		}
 		return results;
 	}
-	
+
 	/**
 	 * Gets the children of all the branch in a flat list.
 	 * 
@@ -1672,7 +1672,7 @@
 	public <T extends TXMResult> List<T> getDeepChildren(Class<T> clazz) {
 		return TXMResult.getDeepChildren(this, clazz);
 	}
-	
+
 	/**
 	 * Gets the children of all the branch in a flat list.
 	 * 
@@ -1681,7 +1681,7 @@
 	public static List<TXMResult> getDeepChildren(TXMResult result) {
 		return TXMResult.getDeepChildren(result, null);
 	}
-	
+
 	/**
 	 * Gets the children of all the branch in a flat list.
 	 * 
@@ -1690,7 +1690,7 @@
 	public List<TXMResult> getDeepChildren() {
 		return TXMResult.getDeepChildren(this);
 	}
-	
+
 	/**
 	 * Gets the TXMResult specified by its node path (UUID) in the children of the specified root result.
 	 * Returns the root itself if the specified node path is equal to the root node path.
@@ -1700,22 +1700,22 @@
 	 * @return
 	 */
 	public static TXMResult getResult(TXMResult root, String nodePath) {
-		
+
 		// returns the root itself if the specified node path is equal to the root node path
 		if (root.getParametersNodePath().equals(nodePath)) {
 			return root;
 		}
 		else {
-			
+
 			List<TXMResult> children = root.getChildren();
-			
+
 			// pass 1: to optimize, search in direct children
 			for (int i = 0; i < children.size(); i++) {
 				if (children.get(i).getParametersNodePath().equals(nodePath)) {
 					return children.get(i);
 				}
 			}
-			
+
 			// pass 2: deep recursively search in all children
 			for (int i = 0; i < children.size(); i++) {
 				TXMResult result = getResult(children.get(i), nodePath);
@@ -1724,10 +1724,10 @@
 				}
 			}
 		}
-		
+
 		return null; // not found
 	}
-	
+
 	/**
 	 * Gets the TXMResult specified by its node path (UUID) in the children of the Toolbox Workspace (root of the tree).
 	 * 
@@ -1737,7 +1737,7 @@
 	public static TXMResult getResult(String nodePath) {
 		return getResult(Toolbox.workspace, nodePath);
 	}
-	
+
 	/**
 	 * Filters the nodes of the specified source nodes list according to by their class and their visibility state.
 	 * 
@@ -1756,7 +1756,7 @@
 						&& (onlyVisible == false || child.isVisible())) {
 					nodes.add((T) child);
 				}
-				
+
 				// add children of a non visible result
 				else if (!child.isVisible() && child.hasChildren()) {
 					List<T> subChidlren = child.getChildren(clazz, onlyVisible);
@@ -1769,7 +1769,7 @@
 		}
 		return nodes;
 	}
-	
+
 	/**
 	 * Gets the direct children count.
 	 * 
@@ -1778,8 +1778,8 @@
 	public int getChildrenCount() {
 		return this.children.size();
 	}
-	
-	
+
+
 	/**
 	 * Gets the root parent of the branch.
 	 * Returns the result itself if it's the root.
@@ -1794,11 +1794,11 @@
 			parent = parent.getParent();
 		}
 		while (parent != null);
-		
+
 		return root;
 	}
-	
-	
+
+
 	/**
 	 * Gets the first parent of the specified class, e.g. this.getFirstParent(Partition.class);
 	 * 
@@ -1814,16 +1814,16 @@
 				if (clazz == null || parent.getClass().equals(clazz) || clazz.isInstance(parent)) {
 					node = (T) parent;
 				}
-				
+
 				parent = parent.getParent();
 			}
 		}
 		while (parent != null && node == null);
-		
+
 		return node;
 	}
-	
-	
+
+
 	/**
 	 * Checks if the specified result is a child of this result.
 	 * 
@@ -1832,7 +1832,7 @@
 	public boolean isChild(TXMResult child) {
 		return this.getDeepChildren().contains(child);
 	}
-	
+
 	/**
 	 * Gets the sibling nodes of this node result.
 	 * Returns an empty list if the node has no siblings.
@@ -1847,7 +1847,7 @@
 		}
 		return sibling;
 	}
-	
+
 	/**
 	 * Gets the sibling nodes of this node result, specified by their class.
 	 * Returns an empty list if the node has no siblings of the specified class.
@@ -1863,7 +1863,7 @@
 		}
 		return sibling;
 	}
-	
+
 	/**
 	 * Checks if the result must be displayed.
 	 * 
@@ -1872,7 +1872,7 @@
 	public boolean isVisible() {
 		return this.visible;
 	}
-	
+
 	/**
 	 * Checks if the parent of this result must be displayed.
 	 * 
@@ -1881,7 +1881,7 @@
 	public boolean isParentVisible() {
 		return parent != null && (parent.isVisible() || parent.isInternalPersistable());
 	}
-	
+
 	/**
 	 * Sets the result visibility state.
 	 * Dedicated to UI purposes.
@@ -1891,7 +1891,7 @@
 	public void setVisible(boolean visible) {
 		this.visible = visible;
 	}
-	
+
 	/**
 	 * Sets the parent of this result.
 	 * 
@@ -1900,7 +1900,7 @@
 	public void setParent(TXMResult parent) {
 		this.parent = parent;
 	}
-	
+
 	/**
 	 * Gets the parent of this result.
 	 * 
@@ -1909,14 +1909,14 @@
 	public TXMResult getParent() {
 		return parent;
 	}
-	
+
 	/**
 	 * Gets the name of the result.
 	 * 
 	 * @return
 	 */
 	public abstract String getName();
-	
+
 	/**
 	 * Gets the simple name of the result.
 	 * Dedicated to be displayed in a small UI area.
@@ -1924,7 +1924,7 @@
 	 * @return
 	 */
 	public abstract String getSimpleName();
-	
+
 	/**
 	 * Gets some details about how the result has been computed (eg. additional parameters, etc.).
 	 * Dedicated to be displayed in a large UI area.
@@ -1932,8 +1932,8 @@
 	 * @return
 	 */
 	public abstract String getDetails();
-	
-	
+
+
 	/**
 	 * Gets a message indicating the start of computing.
 	 * Dedicated to indicate the start of computing and, for example, the parameters used for the computing.
@@ -1947,8 +1947,8 @@
 		return NLS.bind("Computing {0}...", this.getClass().getSimpleName());
 	}
 	// public abstract String getComputingStartMessage();
-	
-	
+
+
 	/**
 	 * Gets a message indicating the computing is done.
 	 * Dedicated to indicate the end of computing and, for example, some informations about the result (eg. : "12 matches found.", "No match found.", etc.).
@@ -1960,8 +1960,8 @@
 		return TXMCoreMessages.common_done;
 	}
 	// public abstract String getComputingDoneMessage();
-	
 
+
 	/**
 	 * Gets the user name if exists otherwise, the simple name if not null, otherwise the lazy name.
 	 * 
@@ -1986,10 +1986,10 @@
 		else {
 			return this.lazyName;
 		}
-		
+
 	}
-	
-	
+
+
 	/**
 	 * Convenience method to get a shared name when the result is empty (not yet computed).
 	 * 
@@ -1998,8 +1998,8 @@
 	public String getEmptyName() {
 		return "..."; //$NON-NLS-1$
 	}
-	
-	
+
+
 	/**
 	 * Gets a string representing the result that can be used as a file name (eg. for exporting in file).
 	 * 
@@ -2016,7 +2016,7 @@
 		}
 		return ""; //$NON-NLS-1$
 	}
-	
+
 	/**
 	 * Gets a string representing the concatenation of the simple names of the branch of this result.
 	 * 
@@ -2025,7 +2025,7 @@
 	public String getFullPathSimpleName() {
 		return getFullPathSimpleName(true);
 	}
-	
+
 	/**
 	 * Gets a string representing the concatenation of the simple names of the branch of this result.
 	 * 
@@ -2033,7 +2033,7 @@
 	 * @return the full path
 	 */
 	public String getFullPathSimpleName(boolean showTypes) {
-		
+
 		// fill the branch
 		List<TXMResult> branch = new ArrayList<>();
 		TXMResult node = this;
@@ -2042,7 +2042,7 @@
 			node = node.getParent();
 		}
 		while (node != null);
-		
+
 		// create the reversed string
 		StringBuilder b = new StringBuilder();
 		for (int i = branch.size() - 1; i >= 0; i--) {
@@ -2057,10 +2057,10 @@
 		b.deleteCharAt(b.length() - 3);
 		b.deleteCharAt(b.length() - 2);
 		b.deleteCharAt(b.length() - 1);
-		
+
 		return b.toString();
 	}
-	
+
 	/**
 	 * Gets the weight of the node. Essentially used for sorting purpose.
 	 * 
@@ -2069,22 +2069,22 @@
 	public int getWeight() {
 		return weight;
 	}
-	
+
 	/**
 	 * Cleans and free some resources if needed. This methods is applied when
 	 * calling <code>TXMResult.delete()</code>.
 	 */
 	public abstract void clean();
-	
+
 	@Override
 	public TXMResult clone() {
 		return clone(null, true);
 	}
-	
+
 	public TXMResult clone(boolean all) {
 		return clone(null, all);
 	}
-	
+
 	/**
 	 * recursive method to clone a result
 	 * 
@@ -2093,46 +2093,51 @@
 	 * @return
 	 */
 	public TXMResult clone(TXMResult newParent, boolean all) {
-		TXMResult clone = null;
+		
+		String newNodePath = this.getProject().getParametersNodeRootPath() + createUUID() + "_" + this.getClass().getSimpleName();
+		TXMPreferences.cloneNode(this.getParametersNodePath(), newNodePath);
+
+		if (newParent != null) { // change the cloned node parent preference
+			TXMPreferences.put(newNodePath, TXMPreferences.PARENT_PARAMETERS_NODE_PATH, newParent.getParametersNodePath());
+		}
 		try {
-			String newNodePath = this.getProject().getParametersNodeRootPath() + createUUID() + "_" + this.getClass().getSimpleName();
-			TXMPreferences.cloneNode(this.getParametersNodePath(), newNodePath);
-			
-			if (newParent != null) { // change the cloned node parent preference
-				TXMPreferences.put(newNodePath, TXMPreferences.PARENT_PARAMETERS_NODE_PATH, newParent.getParametersNodePath());
-			}
-			clone = this.getClass().getDeclaredConstructor(String.class).newInstance(newNodePath);
-			
+			TXMResult clone = this.getClass().getDeclaredConstructor(String.class).newInstance(newNodePath);
+
 			//System.out.println("CLONE HAS BEEN COMPUTED? " + clone.hasBeenComputedOnce());
 			//System.out.println("CLONE IS DIRTY? " + clone.isDirty());
-			
+
 			if (all) {
 				for (TXMResult child : this.children) {
 					child.clone(clone, all);
 				}
 			}
+			
+			return clone;
+		} catch (NoSuchMethodException e) {
+			Log.fine("Error: could not clone result "+this+". No constructor TXMResult(String id) available.");
+		}  catch (InstantiationException | IllegalAccessException | IllegalArgumentException
+				| InvocationTargetException | SecurityException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
 		}
-		catch (Exception e) {
-			Log.severe(NLS.bind("Fail to clone {0}: {1}", this, e));
-			Log.printStackTrace(e);
-		}
-		return clone;
+
+		return null;
 	}
-	
+
 	public boolean importParameters(File parameters) {
 		try {
 			Properties props = new Properties();
 			BufferedReader r = IOUtils.getReader(parameters);
 			props.load(r);
 			r.close();
-			
+
 			// some tests before...
 			String className = props.getProperty(TXMPreferences.CLASS);
 			if (className == null || className.length() == 0) {
 				System.out.println("** Error: No class internal parameter set. Can't import the parameters.");
 				return false;
 			}
-			
+
 			if (this.getClass().getName().equals(className)) {
 				for (Object p : props.keySet()) {
 					String ps = p.toString();
@@ -2151,10 +2156,10 @@
 		catch (Exception e) {
 			Log.printStackTrace(e);
 		}
-		
+
 		return true;
 	}
-	
+
 	/**
 	 * import a result from a parameter file
 	 * 
@@ -2165,26 +2170,26 @@
 		try {
 			Properties props = new Properties();
 			props.load(IOUtils.getReader(parameters));
-			
+
 			// some tests before...
 			String className = props.getProperty(TXMPreferences.CLASS);
 			if (className == null || className.length() == 0) {
 				System.out.println("** Error: No class internal parameter set.");
 				return null;
 			}
-			
+
 			String bundleId = props.getProperty(TXMPreferences.BUNDLE_ID);
 			if (bundleId == null || bundleId.length() == 0) {
 				System.out.println("** Error: No bundle_id internal parameter set.");
 				return null;
 			}
-			
+
 			Bundle bundle = Platform.getBundle(bundleId);
 			if (bundle == null) {
 				Log.finest("** Error: can not restore object with bundle name " + bundleId); //$NON-NLS-1$
 				return null;
 			}
-			
+
 			// copy parameters
 			String newNodePath = this.getProject().getParametersNodeRootPath() + createUUID() + "_" + className;
 			TXMPreferences.put(newNodePath, TXMPreferences.PARENT_PARAMETERS_NODE_PATH, this.getParametersNodePath());
@@ -2194,7 +2199,7 @@
 				if (TXMPreferences.RESULT_PARAMETERS_NODE_PATH.equals(ps)) continue;
 				TXMPreferences.put(newNodePath, ps, props.getProperty(ps, ""));
 			}
-			
+
 			// create instance
 			Class<?> cl = bundle.loadClass(className);
 			Constructor<?> cons = null;
@@ -2210,7 +2215,7 @@
 					clazz = clazz.getSuperclass();
 				}
 			}
-			
+
 			if (cons == null) {
 				System.out.println(NLS.bind("Cannot import {0} in {1}", parameters, this));
 			}
@@ -2220,7 +2225,7 @@
 				System.out.println(NLS.bind("{0} imported", result));
 				return result;
 			}
-			
+
 		}
 		catch (Exception e) {
 			System.out.println(NLS.bind("Fail to import result from {0}: {1}", parameters, e));
@@ -2228,7 +2233,7 @@
 		}
 		return null;
 	}
-	
+
 	/**
 	 * Set the TXMResult parameters
 	 * 
@@ -2238,7 +2243,7 @@
 	 * @throws CqiClientException
 	 */
 	// public abstract boolean setParameters(TXMParameters parameters) throws Exception;
-	
+
 	// this.parameters = parameters;
 	// if (this.parameters == null) {
 	// this.parameters = new TXMParameters();
@@ -2256,7 +2261,7 @@
 	// }
 	// }
 	// }
-	
+
 	/**
 	 * set the Java object class parameter members and check if the Java object
 	 * parameters are all set
@@ -2264,8 +2269,8 @@
 	 * @return true if parameters are all OK
 	 */
 	public abstract boolean canCompute() throws Exception;
-	
-	
+
+
 	// FIXME: SJ: became useless 
 	public void acquireSemaphore() {
 		try {
@@ -2275,7 +2280,7 @@
 			Log.printStackTrace(e);
 		}
 	}
-	
+
 	/**
 	 * Computes the result if:
 	 * - it can be computed (checking if all mandatory parameters are set)
@@ -2287,7 +2292,7 @@
 	public boolean compute(boolean deepComputing) throws InterruptedException {
 		return this.compute(new LogMonitor("Computing " + this), deepComputing);
 	}
-	
+
 	/**
 	 * Computes the result if:
 	 * - it can be computed (checking if all mandatory parameters are set)
@@ -2299,8 +2304,8 @@
 	public boolean compute() throws InterruptedException {
 		return this.compute(true);
 	}
-	
-	
+
+
 	/**
 	 * Computes the result if:
 	 * - it can be computed (checking if all mandatory parameters are set)
@@ -2312,8 +2317,8 @@
 	public boolean compute(IProgressMonitor monitor) throws InterruptedException {
 		return this.compute(monitor, true);
 	}
-	
-	
+
+
 	/**
 	 * Computes the result if:
 	 * - it can be computed (checking if all mandatory parameters are set)
@@ -2324,22 +2329,22 @@
 	 * @return
 	 */
 	public boolean compute(IProgressMonitor monitor, boolean deepComputing) throws InterruptedException {
-		
+
 		// FIXME: SJ: we may not override the current thread member if it already exists?
 		this.computingThread = Thread.currentThread();
-		
+
 		// FIXME: SJ: Debug tests
 		boolean debugSlowingProcess = false;
 		int sleepDuration = 15000;
-		
+
 		// skip the process if the result is already in computing stage
 		if (this.computing) {
 			Log.finest(NLS.bind("--- TXMResult.compute(): {0}: The result is already computing, compute process aborted.", this.getClass().getSimpleName())); // $NON-NLS-1$
 			return true;
 		}
-		
+
 		this.computing = true;
-		
+
 		// no changes to do
 		// FIXME: SJ: we need to do do some actions even if the object is locked, eg. updating parameters, saving parameters, etc.
 		// FIXME: MD: nope the parameters must not move and will be saved in the current state
@@ -2347,26 +2352,26 @@
 			this.computing = false;
 			return true;
 		}
-		
-		
+
+
 		Log.finest("*** TXMResult.compute(): " + this.getClass().getSimpleName() + ": starting computing process...");
-		
-		
+
+
 		// convert the monitor into a sub-monitor that is dedicated only to the TXMResult.compute() method process
 		SubMonitor mainSubMonitor = SubMonitor.convert(monitor, this.getComputingStartMessage(), 3);
-		
+
 		// FIXME: SJ: see if this skipComputing tests is still useful? is it possible to directly returns instead?
 		boolean skipComputing = false;
-		
+
 		try {
 			// compute the parent if needed
 			if (this.parent != null && !(this.parent instanceof Project) && !(this.parent instanceof Workspace)
 					&& !this.parent.isComputing()) {
-				
+
 				mainSubMonitor.setTaskName(NLS.bind(TXMCoreMessages.computingParentsOfP0, parent.getName()));
-				
+
 				Log.finest("TXMResult.compute(): " + this.getClass().getSimpleName() + ": starting parent (" + this.parent.getClass().getSimpleName() + ") computing process...");
-				
+
 				if (!this.parent.compute(mainSubMonitor.split(1).setWorkRemaining(100), deepComputing)) {
 					Log.finest("TXMResult.compute(): " + this.getClass().getSimpleName() + ": failed to compute parent result.");
 					this.computing = false;
@@ -2376,51 +2381,51 @@
 			else {
 				mainSubMonitor.setWorkRemaining(2);
 			}
-			
+
 			// update the dirty state from history if a parameter has changed since last computing
 			// this.updateDirtyFromHistory();
-			
+
 			// check if the result is dirty
 			if (!this.isDirty() && !hasParametersChanged()) {
 				Log.finest("--- TXMResult.compute(): " + this.getClass().getSimpleName() + ": result parameters have not changed since last computing, computing skipped.");
 				skipComputing = true;
 			}
-			
+
 			if (!skipComputing) {
-				
+
 				// Debug
 				Log.finest("+++ TXMResult.compute(): " + this.getClass().getSimpleName() + ": computing result of type " + this.getClass() + "...");
-				
+
 				// Computing requirements test
 				if (!this.canCompute()) {
 					Log.finest("TXMResult.compute(): " + this.getClass().getSimpleName() + ": can not compute, missing or wrong parameters or error with parent computing, computing aborted.");
 					this.computing = false;
 					return false;
 				}
-				
-				
+
+
 				try {
 					// console log, only for visible result or if the log level is superior to info level
 					if (!this.getComputingStartMessage().isEmpty() && (this.isVisible() || Log.isLoggingFineLevel())) {
 						Log.info(this.getComputingStartMessage());
 					}
-					
-					
+
+
 					// monitor log
 					// this.setTaskName(this.getComputingStartMessage());
 					mainSubMonitor.subTask(this.getComputingStartMessage());
-					
+
 				}
 				catch (Exception e) {
 					e.printStackTrace();
 					Log.severe("Error while retrieving the result computing start message."); //$NON-NLS-1$
 				}
-				
+
 				// FIXME: SJ: debug tests
 				if (debugSlowingProcess) {
 					Thread.sleep(sleepDuration);
 				}
-				
+
 				// Computing
 				if (!this._compute(new TXMProgressMonitor(mainSubMonitor.split(1)))) {
 					Log.finest("TXMResult.compute(): " + this.getClass().getSimpleName() + ": computing failed.");
@@ -2431,73 +2436,73 @@
 			else {
 				mainSubMonitor.setWorkRemaining(1);
 			}
-			
+
 			// clear the lazy name, no more needed since the object has been computed and getSimpleName() can now work
 			this.lazyName = null;
-			
+
 			// store last used parameters
 			this.updateLastParameters();
-			
-			
-			
+
+
+
 			if (!skipComputing) { // this code block updates the internal variables of the TXMResult (dirtiness, dates, etc.)
-				
+
 				// store last used parameters
 				// this.updateLastParameters();
 				if (hasBeenComputedOnce() // don't update the computing date if the object has been lazy loaded
 						|| this.lastComputingDate == null) { // set the update date if never computed once
 					this.lastComputingDate = Calendar.getInstance().getTime(); // update this internal parameter before saving parameters
 				}
-				
+
 				if (!this.autoSaveParametersFromAnnotations()) {
 					Log.severe("TXMResult.compute(): " + this.getClass().getSimpleName() + ": failed to save parameters from annotations for " + this.getName() + ".");
 				}
 				if (!this.saveParameters()) {
 					Log.severe("TXMResult.compute():" + this.getClass().getSimpleName() + ": failed to save parameters for " + this.getName() + ".");
 				}
-				
+
 				// FIXME: SJ: need to find a way to flush file only if it's necessary. For example at this time, at start when all Edition, Text, etc. are recreated, all .prefs file are flushed but it
 				// useless and slow
 				// file persistence flush
 				if (this.mustBePersisted()) {
 					TXMPreferences.flush(this);
 				}
-				
+
 				this.dirty = false; // the computing was successful, the result is no more dirty
-				
+
 				if (this.altered) {
 					Log.info(NLS.bind("Warning {0} manual modifications have been lost.", this.getSimpleName()));
 				}
 				this.altered = false;
 				Log.finest("TXMResult.compute(): " + this.getClass().getSimpleName() + ": computing of result type " + this.getClass() + " done.");
-				
+
 				// console log, only for visible result or if the log level is superior to info level
 				if (!this.getComputingDoneMessage().isEmpty() && (this.isVisible() || Log.isLoggingFineLevel())) {
 					Log.info(this.getComputingDoneMessage());
 				}
 			}
-			
-			
+
+
 			// Children computing
 			if ((!skipComputing
 					|| this.altered) // FIXME: SJ: fix for computing LexicalTable children even if the LT is not dirty but only altered, need to define if it's a temporary fix or not
 					// e.g. can't we use the dirty state rather than a new member "altered"?
 					&& this.hasChildren()  // don't bother if there is not child
 					&& this.parent != null) { // don't children cascade compute if parent == null (it is the Workspace (Tree root))
-				
+
 				// monitor log
 				mainSubMonitor.setTaskName(TXMCoreMessages.bind(TXMCoreMessages.info_computingChildrenOfP0P1, this, this.getClass().getSimpleName()));
-				
+
 				// create a monitor for children computing loop
 				SubMonitor loopMonitor = mainSubMonitor.split(1).setWorkRemaining(this.children.size());
-				
+
 				Log.finest("TXMResult.compute(): " + this.getClass().getSimpleName() + ": cascade computing of " + this.children.size() + " child(ren).");
-				
+
 				for (int i = 0; i < this.children.size(); i++) {
-					
+
 					TXMResult child = this.children.get(i);
 					child.setDirty(); // set the children as dirty since the result has changed
-					
+
 					// lazy loading test
 					// only compute the child if it has already been computed one time ("loaded" one time)
 					// or if this result always needs its children synchronized/computed to be consistent (e.g. Partition and children parts)
@@ -2514,18 +2519,18 @@
 		// so the engine can do some clean up, e.g. R destroying some objects, etc.
 		// But we also have a TXMResult.clean() method that we could use
 		catch (ThreadDeath | InterruptedException e) {
-			
+
 			// set result and its children as canceled
 			this.resetComputingState();
 			this.computing = false;
-			
+
 			// console log
 			String resultType = this.getResultType();
 			if (resultType.isEmpty()) {
 				resultType = this.getClass().getSimpleName();
 			}
 			Log.info(NLS.bind(TXMCoreMessages.info_cancelingComputingOfP0P1, this.getName(), resultType));
-			
+
 			if (e instanceof ThreadDeath) {
 				throw new InterruptedException("TXMResult computing thread stopped."); //$NON-NLS-1$
 			}
@@ -2541,8 +2546,8 @@
 			this.computing = false;
 			return false;
 		}
-		
-		
+
+
 		try {
 			// TODO see if later we can display the end of compute message here (only if it is the main result computed
 			// monitor log
@@ -2552,15 +2557,15 @@
 			Log.severe("** Error while retrieving the result computing done message."); //$NON-NLS-1$
 			Log.printStackTrace(e);
 		}
-		
+
 		this.computing = false;
-		
+
 		mainSubMonitor.done();
-		
+
 		return true;
 	}
-	
-	
+
+
 	/**
 	 * Sets the result and all its children as canceled (set them as dirty and set computing state as false).
 	 * Resets the computing state.
@@ -2569,26 +2574,26 @@
 	 */
 	public void resetComputingState() {
 		if (this.computing) {
-			
+
 			// set back to dirty
 			this.dirty = true;
 			this.computing = false;
-			
+
 			// FIXME: SJ: old code, used when the monitor was stored in the TXMResult, need to check if we need a replacement for this
 			// this.monitorSetCanceled(true);
 			// this.monitor = null;
-			
+
 			Log.finest(NLS.bind("Computing state of {0} ({1}) has been reset...", this.getName(), this.getClass().getSimpleName()));
-			
+
 			// deep canceling
 			for (int i = 0; i < this.children.size(); i++) {
 				this.children.get(i).resetComputingState();
 			}
-			
+
 		}
 	}
-	
-	
+
+
 	/**
 	 * This method is dedicated to be implemented by the inherited result classes to run the computing steps.
 	 * Subclasses can monitor progress using the dedicated methods.
@@ -2599,7 +2604,7 @@
 	 * @throws Exception
 	 */
 	protected abstract boolean _compute(TXMProgressMonitor monitor) throws Exception;
-	
+
 	/***
 	 * Checks if the result must be persisted according to the persistence global preference or the user persistable state.
 	 * 
@@ -2608,7 +2613,7 @@
 	public boolean mustBePersisted() {
 		return this.isInternalPersistable() || this.userPersistable;
 	}
-	
+
 	/**
 	 * 
 	 * @return the array of extensions to show in the FileDialog SWT widget
@@ -2618,22 +2623,22 @@
 	public String[] getExportTXTExtensions() {
 		return new String[] { "*.csv" };
 	}
-	
-	
-	
+
+
+
 	// FIXME: SJ: became useless?
 	public boolean tryAcquireSemaphore() {
 		return this.progressSemaphore.tryAcquire();
 	}
-	
+
 	// FIXME: SJ: became useless?
 	public void releaseSemaphore() {
 		this.progressSemaphore.release();
 	}
-	
-	
-	
-	
+
+
+
+
 	//
 	/**
 	 * @Deprecated
@@ -2659,7 +2664,7 @@
 		}
 		return _toTxt(outfile, encoding, colseparator, txtseparator);
 	}
-	
+
 	/**
 	 * @Deprecated
 	 * 			// FIXME: SJ: should be moved in an exporter extension
@@ -2674,9 +2679,9 @@
 	 * @throws Exception
 	 */
 	protected abstract boolean _toTxt(File outfile, String encoding, String colseparator, String txtseparator) throws Exception;
-	
-	
-	
+
+
+
 	// /**
 	// * Increments the progress of the specified amount of work and displays a message.
 	// *
@@ -2690,8 +2695,8 @@
 	// }
 	// Log.fine(message);
 	// }
-	
-	
+
+
 	// /**
 	// * Checks if the monitor is canceled.
 	// *
@@ -2729,9 +2734,9 @@
 	// }
 	// Log.fine(name);
 	// }
-	
-	
-	
+
+
+
 	//
 	// /**
 	// * You must set the current monitor to be available to manage the process
@@ -2751,7 +2756,7 @@
 	// return true;
 	// }
 	//
-	
+
 	/**
 	 * Gets the user defined name.
 	 * 
@@ -2760,7 +2765,7 @@
 	public String getUserName() {
 		return userName;
 	}
-	
+
 	/**
 	 * Gets the result type. Should be localized (eg. CA => AFC, Word cloud => Nuage de mots).
 	 * This method can be used for logging or UI.
@@ -2769,14 +2774,14 @@
 	 * @return an intended localized result type
 	 */
 	public abstract String getResultType();
-	
-	
+
+
 	@Override
 	public int compareTo(TXMResult o) {
 		// Compare node weights
 		return Integer.compare(this.weight, o.weight);
 	}
-	
+
 	/**
 	 * 
 	 * @param e1
@@ -2786,10 +2791,10 @@
 	public static int compare(TXMResult e1, TXMResult e2) {
 		if (e1 == null && e2 == null) return 0;
 		if (e1 == null) return 1;
-		
+
 		return e1.getParametersNodePath().compareTo(e2.getParametersNodePath());
 	}
-	
+
 	/**
 	 * Gets a boolean state defining if the result has already been computed at least once or not.
 	 * 
@@ -2800,8 +2805,8 @@
 	public boolean hasBeenComputedOnce() {
 		return parametersHistory != null;
 	}
-	
-	
+
+
 	/**
 	 * Gets the internal persistable state.
 	 * 
@@ -2810,7 +2815,7 @@
 	public boolean isInternalPersistable() {
 		return false;
 	}
-	
+
 	/**
 	 * Gets the lazy name.
 	 * Since some result names need computed data, this name is dedicated to display the result name even if it has not been recomputed after being loaded.
@@ -2820,7 +2825,7 @@
 	public String getLazyName() {
 		return lazyName;
 	}
-	
+
 	/**
 	 * Gets the user defined persistable state of the result.
 	 * 
@@ -2829,7 +2834,7 @@
 	public boolean isUserPersistable() {
 		return userPersistable;
 	}
-	
+
 	/**
 	 * Sets the user defined persistable state of the result.
 	 * 
@@ -2843,13 +2848,13 @@
 	 * @param userPersistable the state to set
 	 */
 	public void setUserPersistable(boolean userPersistable) {
-		
+
 		if (this.userPersistable == userPersistable) {
 			return;
 		}
-		
+
 		this.userPersistable = userPersistable;
-		
+
 		// 1- MANAGE THE PARENTS
 		// recursively force the persistable state of the parents if this result is set to persistable
 		if (userPersistable && this.parent != null && !this.parent.isInternalPersistable()) {
@@ -2867,7 +2872,7 @@
 				child.setUserPersistable(userPersistable);
 			}
 		}
-		
+
 		// directly save and flush the preference
 		try {
 			if (this.isUserPersistable()) {
@@ -2880,8 +2885,8 @@
 			e.printStackTrace();
 		}
 	}
-	
-	
+
+
 	/**
 	 * Swaps the user persistable state.
 	 * 
@@ -2890,7 +2895,7 @@
 	public void swapUserPersistableState() {
 		this.setUserPersistable(!this.userPersistable);
 	}
-	
+
 	/**
 	 * Gets the project of the result.
 	 * 
@@ -2899,7 +2904,7 @@
 	public final Project getProject() {
 		return this.getFirstParent(Project.class);
 	}
-	
+
 	/**
 	 * Gets the parameters node path.
 	 * 
@@ -2908,14 +2913,14 @@
 	public String getParametersNodePath() {
 		return parametersNodePath;
 	}
-	
+
 	/**
 	 * @return the parametersHistory
 	 */
 	public ArrayList<HashMap<String, Object>> getParametersHistory() {
 		return parametersHistory;
 	}
-	
+
 	/**
 	 * Gets the last computing date.
 	 * 
@@ -2924,7 +2929,7 @@
 	public Date getLastComputingDate() {
 		return this.lastComputingDate;
 	}
-	
+
 	/**
 	 * Gets the creation date.
 	 * 
@@ -2933,13 +2938,13 @@
 	public Date getCreationDate() {
 		return this.creationDate;
 	}
-	
-	
+
+
 	public boolean toParametersFile(File outfile) throws IOException {
 		return TXMPreferences.flush(this, outfile);
 	}
-	
-	
+
+
 	/**
 	 * Generic toString() method for TXMResult.
 	 */
@@ -2953,7 +2958,7 @@
 		}
 		return this.getSimpleName();
 	}
-	
+
 	/**
 	 * Default implementation getSimpleDetails
 	 * 
@@ -2962,8 +2967,8 @@
 	public String getSimpleDetails() {
 		return getDetails().replace("\n", " ");
 	}
-	
-	
+
+
 	/**
 	 * Checks if the result is in computing stage.
 	 * 
@@ -2972,8 +2977,8 @@
 	public boolean isComputing() {
 		return computing;
 	}
-	
-	
+
+
 	/**
 	 * Checks if this result must always been computed when its parent is computed.
 	 * 
@@ -2982,8 +2987,8 @@
 	public boolean mustBeSynchronizedWithParent() {
 		return synchronizedWithParent;
 	}
-	
-	
+
+
 	/**
 	 * @return the computingThread
 	 */
