diff --git a/.classpath b/.classpath
index 0f6d86f21ee6f545513ec7fa4d4eb3f3a98045f6..bd7c971a1deead9c03d26c8f756bc34d5ba1dd11 100644
--- a/.classpath
+++ b/.classpath
@@ -16,7 +16,7 @@
 	<classpathentry kind="lib" path="lib/commons-logging-1.1.1.jar"/>
 	<classpathentry kind="lib" path="lib/args4j-2.33.jar"/>
 	<classpathentry kind="lib" path="lib/flexjson-2.1/flexjson-2.1.jar" sourcepath="lib/flexjson-2.1/flexjson-2.1-sources.jar"/>
-	<classpathentry kind="lib" path="lib/proxy-vole/proxy-vole-1.0.5-SNAPSHOT-jar-with-dependencies.jar" sourcepath="lib/proxy-vole/proxy-vole-1.0.5-SNAPSHOT-sources.jar"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry exported="true" kind="lib" path="lib/proxy-vole/proxy-vole-1.0.5-jar-with-dependencies.jar"/>
 	<classpathentry kind="output" path="target/classes"/>
 </classpath>
diff --git a/.project b/.project
index 7698d41ae54de7a284c2455f3bd5c1a9aac15c71..e78f869f7cae861a5907c2d95a9be922924045ef 100644
--- a/.project
+++ b/.project
@@ -12,9 +12,6 @@
 		</buildCommand>
 	</buildSpec>
 	<natures>
-		<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
 		<nature>org.eclipse.jdt.core.javanature</nature>
-		<nature>org.eclipse.jem.beaninfo.BeanInfoNature</nature>
-		<nature>ch.acanda.eclipse.pmd.builder.PMDNature</nature>
 	</natures>
 </projectDescription>
diff --git a/CHANGES b/CHANGES
index da9955c39a36ad881a73d93cd8b793a53f6d2393..88ee87d683c1670b29b09c793e7ef6d6a186b511 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,9 +1,21 @@
+v3.1
+----
+
+- Auto-detection of proxy settings is now available.
+
+- Fix a bug which prevented executions when
+  simpleWorkflowPlanner_aggregate_activities is set.  In particular,
+  this variable is set in the bridge so that the bridge sends the
+  largest possible workflow to the server.
+
+
 v3.0.2
 ------
 
 - Fix a bug causing an application to crash if no logging.properties
   could be found (*sigh*)
 
+
 v3.0.1
 ------
 
diff --git a/ant/dependencies.xml b/ant/dependencies.xml
index 3183ca02e9685e001a9c4608df2e2fcec9b76deb..0e8b8a12a42fd54531082964f624100ed0b2f573 100644
--- a/ant/dependencies.xml
+++ b/ant/dependencies.xml
@@ -26,6 +26,7 @@
       <filename name="woodstox-core-5.0.3.jar"/>
       <filename name="velocity-1.6.3-dep.jar"/>
       <filename name="velocity-1.6.3.jar"/>
+      <filename name="proxy-vole/proxy-vole-1.0.5-jar-with-dependencies.jar"/>
     </or>
   </selector>
 
@@ -56,6 +57,7 @@
       <filename name="sqlite-jdbc-3.20.0.jar"/>
       <filename name="stax2-api-4.0.0.jar"/>
       <filename name="woodstox-core-5.0.3.jar"/>
+      <filename name="proxy-vole/proxy-vole-1.0.5-jar-with-dependencies.jar"/>
     </or>
   </selector>
   <fileset dir="${praxis.core.lib}" id="praxis.server.dependencies">
@@ -75,6 +77,7 @@
       <filename name="jdom.jar" />
       <filename name="saxpath.jar" />
       <filename name="org.apache.common.lang.SystemUtils.jar" />
+      <filename name="proxy-vole/proxy-vole-1.0.5-jar-with-dependencies.jar"/>
     </or>
   </selector>
   <fileset dir="${praxis.core.lib}" id="praxis.platform.dependencies">
diff --git a/build.xml b/build.xml
index e56ac185a66bc0d31aaeae6c41fa99fd5e56f57f..66d8c6186d28b98e33672d6c2cf9757cba033463 100644
--- a/build.xml
+++ b/build.xml
@@ -7,7 +7,7 @@
     <format property="build.time" pattern="yyyy-MM-dd'T'hh:mm:ss.SSSZ"/>
   </tstamp>
 
-  <property name="praxis.version" value="3.0.2"/>
+  <property name="praxis.version" value="3.1"/>
   <!-- If not called from an other project setting praxis.home, define it.
        In details:
        - it is unset when directly building the jars of Praxis,
diff --git a/build/DATE b/build/DATE
new file mode 100644
index 0000000000000000000000000000000000000000..7fb15a38ea4d0a47d80c444b0f7c81d9113f11ed
--- /dev/null
+++ b/build/DATE
@@ -0,0 +1 @@
+2019-05-09
diff --git a/build/VERSION b/build/VERSION
new file mode 100644
index 0000000000000000000000000000000000000000..8c50098d8aed57b02fd10f40a670a7c673b7c5a5
--- /dev/null
+++ b/build/VERSION
@@ -0,0 +1 @@
+3.1
diff --git a/build/build.sh b/build/build.sh
new file mode 100755
index 0000000000000000000000000000000000000000..2c3174d547b463db87e741bfe5f5ba15da02b504
--- /dev/null
+++ b/build/build.sh
@@ -0,0 +1,54 @@
+#! /bin/bash
+set -e
+VERSION=$(cat ${0%/*}/VERSION)
+DATE=$(cat ${0%/*}/DATE)
+GUI="../praxis-swing-gui"
+cd "${0%/*}"/..
+BUILD_DATE=$(date --iso-8601=seconds)
+
+# NB: Changed files hereafter should be ignored by the version control,
+# e.g. git update-index --assume-unchanged <file>
+# or the commits retrieved here won't be the right ones
+CORE_COMMIT=$(git describe --tags --always --broken)
+GUI_COMMIT=$(cd "${GUI}" && git describe --tags --always --broken)
+
+sed -i -e 's#<property name="praxis.version" value="[^"]*"/>#<property name="praxis.version" value="'${VERSION}'"/>#' build.xml
+sed -e '/public static final String release / s/"[^"]*"/"'${VERSION}'"/' \
+    -i src/eu/telecom_bretagne/praxis/common/ReleaseInfo.java
+sed -e '/public static final String release_date / s/"[^"]*"/"'${DATE}'"/' \
+    -i src/eu/telecom_bretagne/praxis/common/ReleaseInfo.java
+sed -e "/DATE/ s/=.*;$/= \"${BUILD_DATE}\";/" \
+    -i src/eu/telecom_bretagne/praxis/common/BuildInfo.java
+sed -e "/COMMIT/ s/=.*;$/= \"${CORE_COMMIT}\";/" \
+    -i src/eu/telecom_bretagne/praxis/common/BuildInfo.java
+
+sed -e "/DATE/ s/=.*;$/= \"${BUILD_DATE}\";/" \
+    -i ${GUI}/src/eu/telecom_bretagne/praxis/client/ui/BuildInfo.java
+sed -e "/COMMIT/ s/=.*;$/= \"${GUI_COMMIT}\";/" \
+    -i ${GUI}/src/eu/telecom_bretagne/praxis/client/ui/BuildInfo.java
+
+./data/i18n/native_to_ascii.sh
+\rm -f target/jars/praxis.jar target/jars/praxis_server_platform.jar
+
+# even if the file is marked "assumed-unchanged", git describe marks it as
+# dirty: refresh the index
+( set +e; git update-index --refresh > /dev/null 2>&1 ; exit 0 )
+( set +e; cd "${GUI}" && git update-index --refresh  > /dev/null 2>&1 ; exit 0)
+
+ant praxis.build.standalone.jar  praxis.build.server_platform.jar
+
+NEW_CORE_COMMIT=$(git describe --tags --always --broken)
+if [ "${CORE_COMMIT}" != "${NEW_CORE_COMMIT}" ]; then
+    echo "Warning: description of core commit changed!"
+    echo "    ${CORE_COMMIT} -> ${NEW_CORE_COMMIT}"
+fi
+NEW_GUI_COMMIT=$(cd "${GUI}" && git describe --tags --always --broken)
+if [ "${GUI_COMMIT}" != "${NEW_GUI_COMMIT}" ]; then
+    echo "Warning: description of GUI commit changed!"
+    echo "    ${GUI_COMMIT} -> ${NEW_GUI_COMMIT}"
+fi
+
+
+echo Built ${CORE_COMMIT} / ${GUI_COMMIT}
+#
+exit 0
diff --git a/configurations/configuration.defaults b/configurations/configuration.defaults
index 0eab0438d021942ff4125065118b4e822639938a..92bf8498740ac8b9595b81706c634b4255e744de 100644
--- a/configurations/configuration.defaults
+++ b/configurations/configuration.defaults
@@ -19,6 +19,9 @@ javax.net.ssl.trustStorePassword=
 
 rmi.useHTTP_BOOLEAN-CHECK_
 
+proxy.auto_detect.enabled=false
+proxy.auto_detect.enabled_BOOLEAN-CHECK_
+
 # Whether the (stdin) console should be started or not
 console_BOOLEAN-CHECK_
 console=false
@@ -112,7 +115,7 @@ client.color.datasource.invalid=0xFF6464
 client.color.focus=green
 # TODO shadow new Color(142,178,190,64);
 client.color.shadow=0x8EB2BE
-#client.color.link=GRAY
+client.color.link=BLACK
 client.color.link.focused=RED
 client.color.program.background=0xDCE7CD
 client.color.program.executed=0x85EE89
diff --git a/configurations/configuration.template b/configurations/configuration.template
index c8f2a76a2ec80fd6ff5ac38857632e2d67a29b7e..a5b0ff9048ec9a6019f14d636b32626cc16377c2 100644
--- a/configurations/configuration.template
+++ b/configurations/configuration.template
@@ -20,6 +20,8 @@ javax.net.ssl.trustStorePassword=
 rmi.useHTTP=false
 rmi.useSSL=false
 
+proxy.auto_detect.enabled=false
+
 # Whether the (stdin) console should be started or not
 console=false
 
diff --git a/data/i18n/native_to_ascii.sh b/data/i18n/native_to_ascii.sh
index b6d0467b4d6667f9d9eb2678783b86379e6e24cf..f012b5d9ad288df82e2f7a154ed753f9cdfbdf40 100755
--- a/data/i18n/native_to_ascii.sh
+++ b/data/i18n/native_to_ascii.sh
@@ -5,7 +5,7 @@ shopt -s nullglob
 
 cd ${0%/*}/original
 for lang in el en es fr; do
-    t9n="praxis_${lang}"
+    t9n="praxis_${lang}.properties"
     encoding=("praxis_${lang}.encoding".*)
     encoding="${encoding##*.}"
     if [ -z "${encoding}" ]; then
@@ -14,11 +14,11 @@ for lang in el en es fr; do
     fi
     echo "${t9n}: ${encoding} to ascii..." >&2
 
-    native2ascii -encoding "${encoding}" "${t9n}" "../${t9n}.properties"
+    native2ascii -encoding "${encoding}" "${t9n}" "../${t9n}"
     # we use java.text.MessageFormat, escape simple quotes
-    sed -i -e "s/'/''/g" "../${t9n}.properties"
+    sed -i -e "s/'/''/g" "../${t9n}"
     # remove the emacs' coding system
-    sed -i -e '/^# *-\*- coding:/ d' "../${t9n}.properties"
+    sed -i -e '/^# *-\*- coding:/ d' "../${t9n}"
 done
 cd -
 
diff --git a/data/i18n/original/README.dev b/data/i18n/original/README.dev
new file mode 100644
index 0000000000000000000000000000000000000000..9c9376e1405de48b44a81c8dad3d2cbc3ac3fab2
--- /dev/null
+++ b/data/i18n/original/README.dev
@@ -0,0 +1,11 @@
+Java 9+: properties are loaded in UTF-8 by default.
+
+For now, even when Java 9+ is supported by Praxis, Java 8 is still the
+default (https://www.java.com/fr/download/), so the only option we
+will have will be to set
+java.util.PropertyResourceBundle.encoding=ISO-8859-1 and build the jar
+as usual.
+
+cf. https://docs.oracle.com/javase/9/intl/internationalization-enhancements-jdk-9.htm#JSINT-GUID-9DCDB41C-A989-4220-8140-DBFB844A0FCA
+UTF-8 Properties Files
+Internationalization Enhancements in JDK 9
diff --git a/data/i18n/original/praxis_el b/data/i18n/original/praxis_el.properties
similarity index 99%
rename from data/i18n/original/praxis_el
rename to data/i18n/original/praxis_el.properties
index dc3758fedd93a6b7be0060f8ff4d3d6cc71e7a5e..e6fefc1057068d3fe5b6ca7edad80d7693206220 100644
--- a/data/i18n/original/praxis_el
+++ b/data/i18n/original/praxis_el.properties
@@ -130,6 +130,9 @@ UI.dialog.prg_properties.main_label                   = Περιγραφή το
 UI.dialog.prg_properties.parameters                   = Παράμετροι:
 UI.dialog.prg_properties.parameters_default           = (και η προεπιλεγμένη τιμή τους)
 UI.dialog.prg_properties.title                        = Ιδιότητες προγράμματος
+UI.dialog.prg_properties.invalid_value                = Μη έγκυρη τιμή
+UI.dialog.prg_properties.invalid_integer_value        = Μη έγκυρη τιμή: απαιτείται ακέραιος αριθμός
+UI.dialog.prg_properties.invalid_float_value          = Μη έγκυρη τιμή: απαιτείται αριθμός για το κυμαινόμενο σημείο
 UI.dialog.quit                                        = Εγκαταλείψτε
 UI.dialog.quit_and_disconnect_msg                     = \n\
 Θέλετε να εγκαταλείψετε;\n\
diff --git a/data/i18n/original/praxis_en b/data/i18n/original/praxis_en.properties
similarity index 99%
rename from data/i18n/original/praxis_en
rename to data/i18n/original/praxis_en.properties
index c895e75d1974e9d24cbeb193a4a4953d5bf16ab0..c1f073aacf4234c4ede25f4bf962061e9978f40c 100644
--- a/data/i18n/original/praxis_en
+++ b/data/i18n/original/praxis_en.properties
@@ -131,6 +131,9 @@ UI.dialog.prg_properties.main_label                   = Description of {0}  (cli
 UI.dialog.prg_properties.parameters                   = Parameters:
 UI.dialog.prg_properties.parameters_default           = (and their default value)
 UI.dialog.prg_properties.title                        = Program properties
+UI.dialog.prg_properties.invalid_value                = Invalid value
+UI.dialog.prg_properties.invalid_integer_value        = Invalid value: an integer number is required
+UI.dialog.prg_properties.invalid_float_value          = Invalid value: a floating point number is required
 UI.dialog.quit                                        = Quit
 UI.dialog.quit_and_disconnect_msg                     = \n\
 Do you want to quit?\n\
diff --git a/data/i18n/original/praxis_es b/data/i18n/original/praxis_es.properties
similarity index 99%
rename from data/i18n/original/praxis_es
rename to data/i18n/original/praxis_es.properties
index 478520d4e72c397935479e70a5ca575500f6dcfe..185d07c4b8173f74b5a2f73c6a2bea3f91983d0b 100644
--- a/data/i18n/original/praxis_es
+++ b/data/i18n/original/praxis_es.properties
@@ -137,6 +137,9 @@ UI.dialog.prg_properties.main_label                   = Descripci
 UI.dialog.prg_properties.parameters                   = Par�metros:
 UI.dialog.prg_properties.parameters_default           = (y sus valores por defecto)
 UI.dialog.prg_properties.title                        = Propiedades del programa
+UI.dialog.prg_properties.invalid_value                = Valor no v�lido
+UI.dialog.prg_properties.invalid_integer_value        = Valor no v�lido: se requiere un n�mero entero
+UI.dialog.prg_properties.invalid_float_value          = Valor no v�lido: se requiere un n�mero de coma flotante
 UI.dialog.quit                                        = Salir
 UI.dialog.quit_and_disconnect_msg                     = \n\
 �Desea salir?\n\
diff --git a/data/i18n/original/praxis_fr b/data/i18n/original/praxis_fr.properties
similarity index 99%
rename from data/i18n/original/praxis_fr
rename to data/i18n/original/praxis_fr.properties
index 671478f1ca703f2eb9457ac43ad6e05506d5d9b6..ec412bfd24c6a6e9d96e4368428b03690a057bb8 100644
--- a/data/i18n/original/praxis_fr
+++ b/data/i18n/original/praxis_fr.properties
@@ -131,6 +131,9 @@ UI.dialog.prg_properties.main_label                   = Description de: {0}  (cl
 UI.dialog.prg_properties.parameters                   = Paramètres :
 UI.dialog.prg_properties.parameters_default           = (et leur valeur par défaut)
 UI.dialog.prg_properties.title                        = Propriétés de programme
+UI.dialog.prg_properties.invalid_value                = Valeur incorrecte
+UI.dialog.prg_properties.invalid_integer_value        = Valeur incorrecte: un nombre entier est requis
+UI.dialog.prg_properties.invalid_float_value          = Valeur incorrecte: un nombre r�el est requis
 UI.dialog.quit                                        = Quitter
 UI.dialog.quit_and_disconnect_msg                     = \n\
 Voulez-vous quitter l'application?\n\
diff --git a/data/i18n/praxis_el.properties b/data/i18n/praxis_el.properties
index 911513ce4a5ee08e16ec1583a4374c7bde243f5f..e2b7f3802d100013cb4f6bb3789556fc182b79a4 100644
--- a/data/i18n/praxis_el.properties
+++ b/data/i18n/praxis_el.properties
@@ -130,6 +130,9 @@ UI.dialog.prg_properties.main_label                   = \u03a0\u03b5\u03c1\u03b9
 UI.dialog.prg_properties.parameters                   = \u03a0\u03b1\u03c1\u03ac\u03bc\u03b5\u03c4\u03c1\u03bf\u03b9:
 UI.dialog.prg_properties.parameters_default           = (\u03ba\u03b1\u03b9 \u03b7 \u03c0\u03c1\u03bf\u03b5\u03c0\u03b9\u03bb\u03b5\u03b3\u03bc\u03ad\u03bd\u03b7 \u03c4\u03b9\u03bc\u03ae \u03c4\u03bf\u03c5\u03c2)
 UI.dialog.prg_properties.title                        = \u0399\u03b4\u03b9\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2 \u03c0\u03c1\u03bf\u03b3\u03c1\u03ac\u03bc\u03bc\u03b1\u03c4\u03bf\u03c2
+UI.dialog.prg_properties.invalid_value                = \u039c\u03b7 \u03ad\u03b3\u03ba\u03c5\u03c1\u03b7 \u03c4\u03b9\u03bc\u03ae
+UI.dialog.prg_properties.invalid_integer_value        = \u039c\u03b7 \u03ad\u03b3\u03ba\u03c5\u03c1\u03b7 \u03c4\u03b9\u03bc\u03ae: \u03b1\u03c0\u03b1\u03b9\u03c4\u03b5\u03af\u03c4\u03b1\u03b9 \u03b1\u03ba\u03ad\u03c1\u03b1\u03b9\u03bf\u03c2 \u03b1\u03c1\u03b9\u03b8\u03bc\u03cc\u03c2
+UI.dialog.prg_properties.invalid_float_value          = \u039c\u03b7 \u03ad\u03b3\u03ba\u03c5\u03c1\u03b7 \u03c4\u03b9\u03bc\u03ae: \u03b1\u03c0\u03b1\u03b9\u03c4\u03b5\u03af\u03c4\u03b1\u03b9 \u03b1\u03c1\u03b9\u03b8\u03bc\u03cc\u03c2 \u03b3\u03b9\u03b1 \u03c4\u03bf \u03ba\u03c5\u03bc\u03b1\u03b9\u03bd\u03cc\u03bc\u03b5\u03bd\u03bf \u03c3\u03b7\u03bc\u03b5\u03af\u03bf
 UI.dialog.quit                                        = \u0395\u03b3\u03ba\u03b1\u03c4\u03b1\u03bb\u03b5\u03af\u03c8\u03c4\u03b5
 UI.dialog.quit_and_disconnect_msg                     = \n\
 \u0398\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03b5\u03b3\u03ba\u03b1\u03c4\u03b1\u03bb\u03b5\u03af\u03c8\u03b5\u03c4\u03b5;\n\
diff --git a/data/i18n/praxis_en.properties b/data/i18n/praxis_en.properties
index ce0709ba29fe026d261c339e2bc9fc3c0da61df2..be19376ff9ba24c2fef8dcc39b66a4256775b35d 100644
--- a/data/i18n/praxis_en.properties
+++ b/data/i18n/praxis_en.properties
@@ -130,6 +130,9 @@ UI.dialog.prg_properties.main_label                   = Description of {0}  (cli
 UI.dialog.prg_properties.parameters                   = Parameters:
 UI.dialog.prg_properties.parameters_default           = (and their default value)
 UI.dialog.prg_properties.title                        = Program properties
+UI.dialog.prg_properties.invalid_value                = Invalid value
+UI.dialog.prg_properties.invalid_integer_value        = Invalid value: an integer number is required
+UI.dialog.prg_properties.invalid_float_value          = Invalid value: a floating point number is required
 UI.dialog.quit                                        = Quit
 UI.dialog.quit_and_disconnect_msg                     = \n\
 Do you want to quit?\n\
diff --git a/data/i18n/praxis_es.properties b/data/i18n/praxis_es.properties
index e433475d2437fb5dfece12682559ad2bcd1d46db..1932acb219d0663ad79da1e40f2524cd82ebd7d7 100644
--- a/data/i18n/praxis_es.properties
+++ b/data/i18n/praxis_es.properties
@@ -136,6 +136,9 @@ UI.dialog.prg_properties.main_label                   = Descripci\u00f3n de {0}
 UI.dialog.prg_properties.parameters                   = Par\u00e1metros:
 UI.dialog.prg_properties.parameters_default           = (y sus valores por defecto)
 UI.dialog.prg_properties.title                        = Propiedades del programa
+UI.dialog.prg_properties.invalid_value                = Valor no v\u00e1lido
+UI.dialog.prg_properties.invalid_integer_value        = Valor no v\u00e1lido: se requiere un n\u00famero entero
+UI.dialog.prg_properties.invalid_float_value          = Valor no v\u00e1lido: se requiere un n\u00famero de coma flotante
 UI.dialog.quit                                        = Salir
 UI.dialog.quit_and_disconnect_msg                     = \n\
 \u00bfDesea salir?\n\
diff --git a/data/i18n/praxis_fr.properties b/data/i18n/praxis_fr.properties
index 067931db0127c1b9d81a9e74fa6ba02927430b4d..55b05e4e915ad9e33ab9a8776f1d29009ca4fe7d 100644
--- a/data/i18n/praxis_fr.properties
+++ b/data/i18n/praxis_fr.properties
@@ -130,6 +130,9 @@ UI.dialog.prg_properties.main_label                   = Description de: {0}  (cl
 UI.dialog.prg_properties.parameters                   = Param\u00e8tres :
 UI.dialog.prg_properties.parameters_default           = (et leur valeur par d\u00e9faut)
 UI.dialog.prg_properties.title                        = Propri\u00e9t\u00e9s de programme
+UI.dialog.prg_properties.invalid_value                = Valeur incorrecte
+UI.dialog.prg_properties.invalid_integer_value        = Valeur incorrecte: un nombre entier est requis
+UI.dialog.prg_properties.invalid_float_value          = Valeur incorrecte: un nombre r\ufffdel est requis
 UI.dialog.quit                                        = Quitter
 UI.dialog.quit_and_disconnect_msg                     = \n\
 Voulez-vous quitter l''application?\n\
diff --git a/src/eu/telecom_bretagne/praxis/client/Client.java b/src/eu/telecom_bretagne/praxis/client/Client.java
index dbe02a3b820d5dcc02ca801afbd6a82a8fbbbf78..da60a82788c153922ab5373a5cfd365c55ef8121 100644
--- a/src/eu/telecom_bretagne/praxis/client/Client.java
+++ b/src/eu/telecom_bretagne/praxis/client/Client.java
@@ -157,7 +157,6 @@ public class Client implements ApplicationListener
 	 * @param workflow
 	 * @param zip
 	 *            . It is deleted after the event has been sent.
-	 * @return
 	 */
 	public void requestExecution(Result result)
 	{
@@ -352,7 +351,7 @@ public class Client implements ApplicationListener
 						else
 							error_title = "Unknown error";
 
-						ErrorDialog.displayErrorMessage(error_title, error);
+						ErrorDialog.showErrorMessage(error_title, error);
 						System.exit(-1);// TODO list & identify all exit status
 					}
 					connection_status.data = ( event.data instanceof Integer );
@@ -381,13 +380,18 @@ public class Client implements ApplicationListener
 				e.printStackTrace();
 			}
 		}
-		if (! (Boolean) connection_status.data)
-			cnx.disconnect();
-		else
+		// The following line triggers a bug in eclipse (oxygen, photon) when e.g. trying to get this class' type
+		// hierarchy.
+		// This is related to https://bugs.eclipse.org/bugs/show_bug.cgi?id=474080
+		// Note: the bug happens only if the condition is negated, and disappears when not doing anythiong but simply
+		// visiting Utils.java in an editor (Utils declares the SimpleContainer)
+		if ( connection_status.data != null && (Boolean) connection_status.data )
 		{
 			if (delegate != null)
 				delegate.authenticatedConnectionEstablished();
 		}
+		else
+			cnx.disconnect();
 
 	}
 	/**
diff --git a/src/eu/telecom_bretagne/praxis/client/ErrorDialog.java b/src/eu/telecom_bretagne/praxis/client/ErrorDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..5afc85d7b0595707d1cae3853832cf2999945850
--- /dev/null
+++ b/src/eu/telecom_bretagne/praxis/client/ErrorDialog.java
@@ -0,0 +1,60 @@
+package eu.telecom_bretagne.praxis.client;
+
+import java.awt.HeadlessException;
+
+import javax.swing.JOptionPane;
+
+import eu.telecom_bretagne.praxis.common.Log;
+
+public interface ErrorDialog
+{
+
+	/* No need to check Configuration.getBoolean("client.no_gui"): it loads to much classes (incl. sun.rmi.* classes)
+	 * and we want to be able to display something when called with a non-supported jre/jdk, so we'd better load as
+	 * little classes as possible. */
+
+	/**
+	 * Shows an error dialog message to the user. This includes:
+	 * <ul>
+	 * <li>opening a graphical dialog window displaying the error,
+	 * <li>logging the error message at the {@link java.util.logging.Level#SEVERE <i>severe</i> level},
+	 * <li>printing the error message on the {@link System#err standard error}.
+	 * </ul>
+	 * 
+	 * @param title
+	 *            the title of the message, or header of the dialog window shown
+	 * @param message
+	 *            the error message
+	 */
+	public static void showErrorMessage(String title, String message)
+	{
+		// print it & log it in any cases
+		System.err.println("Error: " + title + " - "+message);
+		Log.log.severe(()->title+" - "+message);
+		try { JOptionPane.showMessageDialog(null, message, title, JOptionPane.ERROR_MESSAGE); }
+		catch (HeadlessException e) { /* ignore */ }
+	}
+
+	/**
+	 * Show a warning message to the user. This includes:
+	 * <ul>
+	 * <li>opening a graphical dialog window displaying the warning,
+	 * <li>logging the warning message at the {@link java.util.logging.Level#WARNING <i>warning</i> level},
+	 * <li>printing the warning message on the {@link System#err standard error}.
+	 * </ul>
+	 * 
+	 * @param title
+	 *            the title of the message, or header of the dialog window shown
+	 * @param message
+	 *            the error message
+	 */
+	public static void showWarningMessage(String title, String message)
+	{
+		// print it & log it in any cases
+		System.err.println("Warning: " + title + " - "+message);
+		Log.log.warning(()->title+" - "+message);
+		try { JOptionPane.showMessageDialog(null, message, title, JOptionPane.WARNING_MESSAGE); }
+		catch (HeadlessException e) { /* ignore */ }
+	}
+
+}
diff --git a/src/eu/telecom_bretagne/praxis/client/SimpleCommandLine.java b/src/eu/telecom_bretagne/praxis/client/SimpleCommandLine.java
index 29ef561f5a82909fa940301232437191d257cdc7..1aa9b736393d8d821f7de31b011b7a996fa6504f 100644
--- a/src/eu/telecom_bretagne/praxis/client/SimpleCommandLine.java
+++ b/src/eu/telecom_bretagne/praxis/client/SimpleCommandLine.java
@@ -12,6 +12,8 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.logging.Level;
+import java.util.stream.Stream;
 
 import org.kohsuke.args4j.Argument;
 import org.kohsuke.args4j.CmdLineException;
@@ -57,6 +59,8 @@ public class SimpleCommandLine extends StorageListenerAdapter
 	
 	public static final int DEBUG   = 1;
 
+	static final String CLASS = SimpleCommandLine.class.getName();
+
 	public static class DirectoryOptionHandler
 	    extends OptionHandler<File>
 	{
@@ -131,6 +135,12 @@ public class SimpleCommandLine extends StorageListenerAdapter
 				throw new CmdLineException(null, "Invalid value \"" + $id_path + "\": expecting id=file");
 			try
 			{
+				// a workflow interprets a relative path in an input as relative to the file it was loaded from,
+				// but the paths passed to option -i are relative to the current directory: we must store the
+				// absolute paths in the mapping instead.
+				id_path[1]=new File(id_path[1]).getAbsolutePath();
+				if (options.verbose > DEBUG)
+					System.err.printf(String.format("mapping input %s to: %s\n", id_path));
 				inputMap.put(id_path[0], id_path[1]);
 			}
 			catch (NumberFormatException e)
@@ -484,6 +494,7 @@ public class SimpleCommandLine extends StorageListenerAdapter
 	public static Result executeAndGetResult(Workflow workflow) throws InvalidXMLException, IOException,
 	        InterruptedException
 	{
+		Log.log.entering(CLASS, "executeAndGetResult", workflow);
 		// execute: wait() on singleton, triggered by resultModified()
 		executeWorkflow(workflow);
 		
@@ -494,13 +505,19 @@ public class SimpleCommandLine extends StorageListenerAdapter
 		 * as a consequence the result remains registered.
 		 * NB: it is deleted by a request made by the StorageManager
 		 */
-		while (getAvailableResults(workflow).contains(result))
+		Stream <Result> results = getAvailableResults(workflow).stream();
+		while (results.anyMatch((aResult)->aResult.executionID().equals(result.executionID())))
+		{
+			Log.log.finest("The result has not been deleted server-side yet");
 			try
 			{
 				Thread.sleep(50);
 			}
 			catch (InterruptedException e)
-			{}
+			{ Log.exception.log(Level.INFO, "Interrupted", e); }
+			results = getAvailableResults(workflow).stream();
+		}
+		Log.log.exiting(CLASS, "executeAndGetResult", result);
 		return result;
 		
 	}
@@ -576,6 +593,12 @@ public class SimpleCommandLine extends StorageListenerAdapter
 	}
 	
 	/* Implementation of ServerMessageListener */
+	/**
+	 * Called when available results are received. When the message is in response to the request made by
+	 * {@link #getAvailableResults(Workflow)}, that method is unblocked and returns the received results.
+	 * 
+	 * @param anEvent the received event
+	 */
 	@Override
 	public void receivedAvailableResults(ServerToClientEvent anEvent)
 	{
diff --git a/src/eu/telecom_bretagne/praxis/client/StorageManager.java b/src/eu/telecom_bretagne/praxis/client/StorageManager.java
index 94de30bf4e7df243053b5cf49ce26b1769685f9f..11e892d199b23c6e2048e951ef73b61f808fa35e 100644
--- a/src/eu/telecom_bretagne/praxis/client/StorageManager.java
+++ b/src/eu/telecom_bretagne/praxis/client/StorageManager.java
@@ -277,9 +277,8 @@ public class StorageManager
 	/**
 	 * @param dir
 	 * @return
-	 * @throws IllegalArgumentException
-	 *             if the directory has more than one file with the appropriate extension ( {@link Configuration
-	 *             configuration}'s key: file_extension)
+	 * @throws IllegalArgumentException if the directory has no file or more than one file with the appropriate
+	 *             extension ( {@link Configuration configuration}'s key: file_extension)
 	 */
 	static private File workflowFileInDir(File dir) throws IllegalArgumentException
 	{
@@ -719,8 +718,7 @@ public class StorageManager
 		try {
 			wsFile = workflowFileInDir(executionDir);
 		}
-		catch (IllegalArgumentException e) {}
-		if (wsFile==null)
+		catch (IllegalArgumentException iae)
 		{
 			/* on est dans le cas où on récupère les résultats d'une ancienne version de praxis: on n'a pas
 			 * le workflow initial dans l'objet Result, et il n'était pas non plus préalablement stocké dans le
diff --git a/src/eu/telecom_bretagne/praxis/client/event/ApplicationAdapter.java b/src/eu/telecom_bretagne/praxis/client/event/ApplicationAdapter.java
index ebe275c0f3967efa0740170dbb8894fbfadf4862..0ec202dc7a6b6d41e86d79fac35a20511754df65 100644
--- a/src/eu/telecom_bretagne/praxis/client/event/ApplicationAdapter.java
+++ b/src/eu/telecom_bretagne/praxis/client/event/ApplicationAdapter.java
@@ -13,8 +13,6 @@ public class ApplicationAdapter
 	 * @see eu.telecom_bretagne.praxis.client.ui.event.ApplicationListener#applicationClosing()
 	 */
 	@Override
-	public void applicationExiting()
-	{
-	}
+	public void applicationExiting() { /* does nothing */ }
 	
 }
diff --git a/src/eu/telecom_bretagne/praxis/common/CipherUtils.java b/src/eu/telecom_bretagne/praxis/common/CipherUtils.java
index d7653f0b85a9bc170849a94b2eaf235e1a3a6626..8cf9795210e09d44956a5b8b50e394a3dfd7b6b4 100644
--- a/src/eu/telecom_bretagne/praxis/common/CipherUtils.java
+++ b/src/eu/telecom_bretagne/praxis/common/CipherUtils.java
@@ -75,7 +75,9 @@ public class CipherUtils
     public static InputStream decryptedStream(String password, File input)
     throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException
     {
-    	return decryptedStream(password, new FileInputStream(input));
+    	try (InputStream is = new FileInputStream(input)) {
+    		return decryptedStream(password, is);
+    	}
     }
     
     protected static InputStream decryptedStream(String password, InputStream stream)
diff --git a/src/eu/telecom_bretagne/praxis/common/FileResources.java b/src/eu/telecom_bretagne/praxis/common/FileResources.java
index 23918d5ba64b37435d1429d8a6888181b9426833..18f30f93f4d0293825a7803c2f2b8f87e4d88d05 100644
--- a/src/eu/telecom_bretagne/praxis/common/FileResources.java
+++ b/src/eu/telecom_bretagne/praxis/common/FileResources.java
@@ -130,9 +130,10 @@ public class FileResources {
      * To avoid I/O errors such as files not existing, the supplied resource
      * should have been retrieved using {@link #file(String)}.
      * @param ciphered whether the resource is expected to be ciphered or not.
-     * @return the appropriate input stream, decyphered if parameter ciphered is true.
+     * @return the appropriate input stream, deciphered if parameter ciphered is true.
      * @throws ResourceNotFoundException
      */
+    @SuppressWarnings("resource")
     public static InputStream inputStreamForResource(File resource, boolean ciphered)
     throws ResourceNotFoundException
     {
diff --git a/src/eu/telecom_bretagne/praxis/common/Launcher.java b/src/eu/telecom_bretagne/praxis/common/Launcher.java
index d5856175b477034535c113e017333dee4a283113..69a342b02dde9c949916ed5cf81299c2d9ba650a 100644
--- a/src/eu/telecom_bretagne/praxis/common/Launcher.java
+++ b/src/eu/telecom_bretagne/praxis/common/Launcher.java
@@ -37,8 +37,7 @@ public class Launcher
 		 * @param platform indicates whether initialization specific to the platform-side should be performed
 		 */
 		public void initialize(boolean client, boolean server, boolean platform)
-		{
-		}
+		{ /* does nothing */ }
 	}
 	
 	/**
@@ -82,7 +81,7 @@ public class Launcher
 		// we do not want to display anything for mac os x / vendor="Apple Inc.", the jvm shipped with mac os is okay.
 		// since java 7, vendor is Oracle Corporation
 		if (!"Sun Microsystems Inc.".equals(vendor) && !"Apple Inc.".equals(vendor) && !"Oracle Corporation".equals(vendor))
-			ErrorDialog.displayWarningMessage("JVM Warning",
+			ErrorDialog.showWarningMessage("JVM Warning",
 			                           "We strongly recommend that you use a Java Virtual Machine provided by Oracle!\n\n"
 			                           + "You're currently using the following JVM:\n  - version: "
 			                           + version
@@ -92,7 +91,7 @@ public class Launcher
 
 		else if (jvmVersion >= 9)
 		{
-			ErrorDialog.displayErrorMessage("Error",
+			ErrorDialog.showErrorMessage("Error",
 			                                "Error: this application requires java 8 but java "+jvmVersion+" is used.");
 			System.exit(-2);
 		}
@@ -100,17 +99,6 @@ public class Launcher
 			Log.log.info(()->"Running with JVM version " + version + " by " + vendor + ", fine");
 	}
 
-	/**
-	 * Workaround for bug #7188755 (bugs.sun.com).
-	 * @see ProxySelectorWrapper ProxySelectorWrapper for details
-	 */
-	public static void workaroundBug7188755()
-	{
-		 ProxySelector defaultProxySelector = ProxySelector.getDefault();
-		 if (defaultProxySelector!=null)
-		     ProxySelector.setDefault(new ProxySelectorWrapper(defaultProxySelector));
-	}
-
 	public static void fixWmClass()
 	{
 		// cf. http://elliotth.blogspot.fr/2007/02/fixing-wmclass-for-your-java.html
@@ -168,9 +156,10 @@ public class Launcher
 		}
 
 		checkJVM();
-		workaroundBug7188755();
 		fixWmClass();
 		
+		ProxyAutoDetect.initialize();
+		
 		if (   Configuration.isDefined("client")
 			&& Configuration.isDefined("servers")
 		    && Configuration.isDefined("platforms"))
@@ -199,7 +188,7 @@ public class Launcher
 			}
 			catch (Throwable t)
 			{
-				ErrorDialog.displayErrorMessage("Connection error",
+				ErrorDialog.showErrorMessage("Connection error",
 				                                    "Error: unable to connect to the server\nReason: "+t.toString());
 				System.exit(1);
 			}
diff --git a/src/eu/telecom_bretagne/praxis/common/Log.java b/src/eu/telecom_bretagne/praxis/common/Log.java
index 76bdc767f5c860670983846a4e5dfd0cdd924e66..2ab04f77b73b48426c8adfdc48621e310f8c507f 100644
--- a/src/eu/telecom_bretagne/praxis/common/Log.java
+++ b/src/eu/telecom_bretagne/praxis/common/Log.java
@@ -9,8 +9,10 @@ public class Log
 	 * NB: Log levels are always localized
 	 * https://stackoverflow.com/questions/3920930/java-util-logging-how-to-set-level-by-logger-package-or-prefix
 	 */
-	public static final Logger log		 = Logger.getLogger("praxis", null);
+	public static final Logger log       = Logger.getLogger("praxis", null);
 
 	public static final Logger migration = Logger.getLogger("praxis.migration");
 
+	public static final Logger exception = Logger.getLogger("exception.ignored", null);
+
 }
diff --git a/src/eu/telecom_bretagne/praxis/common/PraxisPreferences.java b/src/eu/telecom_bretagne/praxis/common/PraxisPreferences.java
index 194baac4d25de85f2ae028f5bc527e8155d10d1d..29130083475559e527d7e090457d2110fa213217 100644
--- a/src/eu/telecom_bretagne/praxis/common/PraxisPreferences.java
+++ b/src/eu/telecom_bretagne/praxis/common/PraxisPreferences.java
@@ -58,14 +58,14 @@ public class PraxisPreferences
 		 * The default implementation does nothing.
 		 * @see #initCommon()
 		 */
-		public void initClient() {}
+		public void initClient() { /* does nothing */ }
 		
 		/**
 		 * Called by the framework at initialization time. Subclass this method if you need to add you own values to
 		 * the application's preferences. This method is always called when the preferences are initialized.<br>
 		 * The default implementation does nothing.
 		 */
-		public void initCommon() {}
+		public void initCommon() { /* does nothing */ }
 	}
 	
 	protected static final Preferences PRAXIS_ROOT_NODE;
diff --git a/src/eu/telecom_bretagne/praxis/common/ProxyAutoDetect.java b/src/eu/telecom_bretagne/praxis/common/ProxyAutoDetect.java
new file mode 100644
index 0000000000000000000000000000000000000000..51c730e5b62af7bf01ef42bdfbc97445f4d67e3a
--- /dev/null
+++ b/src/eu/telecom_bretagne/praxis/common/ProxyAutoDetect.java
@@ -0,0 +1,64 @@
+package eu.telecom_bretagne.praxis.common;
+
+import java.net.ProxySelector;
+
+import org.apache.commons.lang.SystemUtils;
+
+import com.github.markusbernhardt.proxy.ProxySearch;
+import com.github.markusbernhardt.proxy.ProxySearch.Strategy;
+
+public class ProxyAutoDetect
+{
+	/**
+	 * Initializes the proxy auto-detection by setting the {@link ProxySelector#setDefault(ProxySelector) default proxy
+	 * selector}.  If the configuration item {@code proxy.auto_detect.enabled} is false, it does nothing.
+	 */
+	public static void initialize()
+	{
+		if ( ! Configuration.getBoolean("proxy.auto_detect.enabled"))
+			return;
+
+		ProxySelector.setDefault(ProxyAutoDetect.getDefaultProxySearch().getProxySelector());
+	}
+
+	static ProxySearch getDefaultProxySearch()
+	{
+		final ProxySearch proxySearch = new ProxySearch(); // https://github.com/MarkusBernhardt/proxy-vole
+
+		/* 
+		 * NB: Strategy BROWSER: is equivalent to IE on windows, and FIREFOX on others
+		 *     See source code for
+		 *     - com.github.markusbernhardt.proxy.ProxySearch#addStrategy(Strategy)
+		 *     - com.github.markusbernhardt.proxy.ProxySearch#getDefaultBrowserStrategy()
+		 *     - com.github.markusbernhardt.proxy.util.PlatformUtil#getDefaultBrowser()
+		 */
+		if ( SystemUtils.IS_OS_LINUX )
+		{
+		    proxySearch.addStrategy(Strategy.JAVA);
+			proxySearch.addStrategy(Strategy.OS_DEFAULT);
+			proxySearch.addStrategy(Strategy.GNOME);
+			proxySearch.addStrategy(Strategy.KDE);
+			proxySearch.addStrategy(Strategy.FIREFOX);
+			proxySearch.addStrategy(Strategy.ENV_VAR);
+		}
+		else if ( SystemUtils.IS_OS_WINDOWS )
+		{
+		    proxySearch.addStrategy(Strategy.JAVA);
+			proxySearch.addStrategy(Strategy.OS_DEFAULT);
+			proxySearch.addStrategy(Strategy.WIN);
+			proxySearch.addStrategy(Strategy.FIREFOX);
+			proxySearch.addStrategy(Strategy.IE);
+			proxySearch.addStrategy(Strategy.ENV_VAR);
+		}
+		else
+		{
+		    proxySearch.addStrategy(Strategy.JAVA);
+			proxySearch.addStrategy(Strategy.OS_DEFAULT);
+			proxySearch.addStrategy(Strategy.FIREFOX);
+			proxySearch.addStrategy(Strategy.ENV_VAR);
+		}
+		// TODO WPAD ? quand est-ce que c'est appelé dans l'auto-détection?
+		return proxySearch;
+	}
+
+}
diff --git a/src/eu/telecom_bretagne/praxis/common/ReleaseInfo.java b/src/eu/telecom_bretagne/praxis/common/ReleaseInfo.java
index a927ce6783d054fb11bcf19ec64de9388ae44d42..bb80a639c36c0e80f0f8c9e3c05c996247428208 100644
--- a/src/eu/telecom_bretagne/praxis/common/ReleaseInfo.java
+++ b/src/eu/telecom_bretagne/praxis/common/ReleaseInfo.java
@@ -7,9 +7,9 @@ package eu.telecom_bretagne.praxis.common;
  */
 public abstract class ReleaseInfo
 {
-	public static final String release              = "3.0.2";
+	public static final String release              = "3.1";
 
-	public static final String release_date         = "2018-07-26";
+	public static final String release_date         = "2019-05-09";
 
 	public static final int    application_revision = Configuration.getInt("revision");
 
diff --git a/src/eu/telecom_bretagne/praxis/common/SplashWindow.java b/src/eu/telecom_bretagne/praxis/common/SplashWindow.java
index f49401baa7816e40403d7af7c6b8cdceea170f7e..64886df0466af1f0c921e1bd3b7c8130c1837416 100644
--- a/src/eu/telecom_bretagne/praxis/common/SplashWindow.java
+++ b/src/eu/telecom_bretagne/praxis/common/SplashWindow.java
@@ -27,6 +27,7 @@ import java.awt.Window;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.awt.geom.Rectangle2D;
+import java.util.logging.Level;
 
 import eu.telecom_bretagne.praxis.common.FileResources.ResourceNotFoundException;
 
@@ -109,7 +110,7 @@ public class SplashWindow
 			mt.waitForID(0);
 		}
 		catch (InterruptedException ie)
-		{}
+		{ Log.exception.log(Level.INFO, "Interrupted", ie); }
 		
 		// Center the window on the screen
 		int imgWidth = image.getWidth(this);
@@ -234,7 +235,7 @@ public class SplashWindow
 							instance.wait();
 						}
 						catch (InterruptedException e)
-						{}
+						{ Log.exception.log(Level.INFO, "Interrupted", e); }
 					}
 				}
 			}
diff --git a/src/eu/telecom_bretagne/praxis/common/SystemExecution.java b/src/eu/telecom_bretagne/praxis/common/SystemExecution.java
index 31e1b859ca00d83070e3e9af8a38542540f3da9f..d159d9c8aece50c331c3c8c7fb26ecfce837970c 100644
--- a/src/eu/telecom_bretagne/praxis/common/SystemExecution.java
+++ b/src/eu/telecom_bretagne/praxis/common/SystemExecution.java
@@ -241,7 +241,7 @@ public class SystemExecution
 	 * @param stderr_limit
 	 *            the maximum number of bytes to read from the standard error. If 0 or negative, no limitation
 	 *            applies.
-	 * @param delegate
+	 * @param aDelegate
 	 *            Uses a different delegate than the {@link #setDelegate(Delegate) global one}: in some particular
 	 *            situations this is sometimes desirable to use a different delegate than the one used almost
 	 *            everywhere.
@@ -251,14 +251,14 @@ public class SystemExecution
 	 * @throws IllegalStateException
 	 *             if executed more than once.
 	 */
-	public int execute(Writer stdoutWriter, long stdout_limit, Writer stderrWriter, long stderr_limit, Delegate delegate)
+	public int execute(Writer stdoutWriter, long stdout_limit, Writer stderrWriter, long stderr_limit, Delegate aDelegate)
 	        throws InterruptedException, IllegalStateException
 	{
 		// System.getenv() is unmodifiable: we need a copy
 		Map<String, String> environment = new HashMap<String, String>(System.getenv());
 		
-		if (delegate != null)
-			cmd_array = delegate.prepareForExecution(cmd_array, environment);
+		if (aDelegate != null)
+			cmd_array = aDelegate.prepareForExecution(cmd_array, environment);
 		
 		/* Create String[] from Map */
 		// NB: do NOT initialize it here with a new String[] array, or, if the following condition are not satisfied,
diff --git a/src/eu/telecom_bretagne/praxis/common/SystemInformations.java b/src/eu/telecom_bretagne/praxis/common/SystemInformations.java
index 1a2c60fcb76f8e43d1e6fb1a0e6584737b231833..af748cf0136399ae5ec14dd60ad59998c425d0fb 100644
--- a/src/eu/telecom_bretagne/praxis/common/SystemInformations.java
+++ b/src/eu/telecom_bretagne/praxis/common/SystemInformations.java
@@ -295,6 +295,7 @@ public class SystemInformations
 		}
 	}
 
+
 	/**
 	 * Implements the {@link #detectProxy(Data)} method.
 	 */
@@ -303,38 +304,8 @@ public class SystemInformations
 		System.err.println("_detectProxy() start");
 		final Data proxyDetectionData = network.add("proxy detection");
 
-		final ProxySearch proxySearch = new ProxySearch(); // https://github.com/MarkusBernhardt/proxy-vole
-
-		/* 
-		 * NB: Strategy BROWSER: is equivalent to IE on windows, and FIREFOX on others
-		 *     See source code for
-		 *     - com.github.markusbernhardt.proxy.ProxySearch#addStrategy(Strategy)
-		 *     - com.github.markusbernhardt.proxy.ProxySearch#getDefaultBrowserStrategy()
-		 *     - com.github.markusbernhardt.proxy.util.PlatformUtil#getDefaultBrowser()
-		 */
-		if ( SystemUtils.IS_OS_LINUX )
-		{
-			proxySearch.addStrategy(Strategy.OS_DEFAULT);
-			proxySearch.addStrategy(Strategy.GNOME);
-			proxySearch.addStrategy(Strategy.KDE);
-			proxySearch.addStrategy(Strategy.FIREFOX);
-			proxySearch.addStrategy(Strategy.ENV_VAR);
-		}
-		else if ( SystemUtils.IS_OS_WINDOWS )
-		{
-			proxySearch.addStrategy(Strategy.OS_DEFAULT);
-			proxySearch.addStrategy(Strategy.WIN);
-			proxySearch.addStrategy(Strategy.FIREFOX);
-			proxySearch.addStrategy(Strategy.IE);
-		}
-		else
-		{
-			proxySearch.addStrategy(Strategy.OS_DEFAULT);
-			proxySearch.addStrategy(Strategy.FIREFOX);
-			proxySearch.addStrategy(Strategy.ENV_VAR);
-		}
-		// TODO WPAD ? quand est-ce que c'est appelé dans l'auto-détection?
-
+		ProxySearch proxySearch = ProxyAutoDetect.getDefaultProxySearch();
+		
 		Proxy proxy;
 		// http
 		proxy = _detectProxyForURL(proxySearch.getProxySelector(), CHECK_HTTP_URI, proxyDetectionData.add("http"));
diff --git a/src/eu/telecom_bretagne/praxis/common/Utile.java b/src/eu/telecom_bretagne/praxis/common/Utile.java
index b86ba0a488329fa510efdcf3d36ca667f338f245..552436926168c932cc2f462c76e3a4f830be6091 100644
--- a/src/eu/telecom_bretagne/praxis/common/Utile.java
+++ b/src/eu/telecom_bretagne/praxis/common/Utile.java
@@ -6,6 +6,7 @@ import java.io.BufferedInputStream;
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -508,14 +509,6 @@ public class Utile
 		 */
 	}
 	
-	public static java.awt.Dimension textDimension(java.awt.Component c, java.awt.Font font, String txt)
-	{
-		java.awt.font.FontRenderContext fontRenderContext = ((java.awt.Graphics2D) c.getGraphics())
-		        .getFontRenderContext();
-		java.awt.geom.Rectangle2D r = new java.awt.font.TextLayout(txt, font, fontRenderContext).getBounds();
-		return new java.awt.Dimension((int) r.getWidth(), (int) r.getHeight());
-	}
-	
 	/**
 	 * Turns every byte in the array into its 2 characters hexadecimal representation, and returns the corresponding
 	 * string.
@@ -965,8 +958,7 @@ public class Utile
         	try {
         		execution.execute(new StringWriter(), -1, null, -1);
         		appPaths32 = execution.getStdout().toString().toLowerCase();
-        	} catch (InterruptedException e) {
-        	}
+        	} catch (InterruptedException e) { Log.exception.log(Level.INFO, "Interrupted", e); }
         }
         if (appPaths6432Node==null)
         {
@@ -975,8 +967,7 @@ public class Utile
         	try {
         		execution.execute(new StringWriter(), -1, null, -1);
         		appPaths6432Node = execution.getStdout().toString().toLowerCase();
-        	} catch (InterruptedException e) {
-        	}
+        	} catch (InterruptedException e) { Log.exception.log(Level.INFO, "Interrupted", e); }
         }
 		
 		/*
@@ -1129,6 +1120,25 @@ public class Utile
 			throw new IllegalArgumentException("There are unbalanced quotes");
 		return args.toArray(new String[args.size()]);
 	}
+	
+	/**
+	 * Calls {@link Closeable#close()} and ignore any IOException raised.
+	 * @param closable the input stream to be closed.  It may be {@code null}.
+	 */
+	public static void closeSilently(Closeable closable)
+	{
+		if ( closable == null )
+			return;
+		try
+		{
+			closable.close();
+		}
+		catch (IOException e)
+		{
+			Log.log.log(Level.FINE, "exception ignored", e);
+		}
+	}
+
 	public static void main(String[] args)
 	{
 		String test = "cmd -p'v1' --p3=\"v\"'\"'\"3\"";//"cmd -p'v1' --p3=\"v'3\"";
diff --git a/src/eu/telecom_bretagne/praxis/common/events/DirectCommunicationFacade.java b/src/eu/telecom_bretagne/praxis/common/events/DirectCommunicationFacade.java
index 7f283b7b66e244144fb2bb993310b44890df3a09..ab15412df23316562007dcf1dbd990fa9d98d6b5 100644
--- a/src/eu/telecom_bretagne/praxis/common/events/DirectCommunicationFacade.java
+++ b/src/eu/telecom_bretagne/praxis/common/events/DirectCommunicationFacade.java
@@ -26,7 +26,7 @@ public class DirectCommunicationFacade extends CommunicationFacade
      * Static initializer is empty: client and platform connects to the server
      * using the accept() method
      */
-    static {}
+    static { /* left intentionally empty */ }
     
     public static void accept(DirectCommunicationFacade platformFacade)
     {
@@ -116,7 +116,7 @@ public class DirectCommunicationFacade extends CommunicationFacade
         while (other_end == null && !disconnected)
             synchronized(this)
             {
-                try{ wait(1); } catch (InterruptedException e) {}
+                try{ wait(1); } catch (InterruptedException e) { Log.exception.log(Level.INFO, "Interrupted", e); }
             }
         final ArrayList <Event> events_copy = new ArrayList<Event>();
         while (other_end != null && !disconnected) {
diff --git a/src/eu/telecom_bretagne/praxis/common/events/RMICommunicationFacade.java b/src/eu/telecom_bretagne/praxis/common/events/RMICommunicationFacade.java
index 1e90dd33f588f63a8e18b7f12cbb23d5a8131d6a..5aaf65d8f5c47223582314a58b0d458c04292cc0 100644
--- a/src/eu/telecom_bretagne/praxis/common/events/RMICommunicationFacade.java
+++ b/src/eu/telecom_bretagne/praxis/common/events/RMICommunicationFacade.java
@@ -463,7 +463,7 @@ public class RMICommunicationFacade
 					wait(1);
 				}
 				catch (InterruptedException e)
-				{}
+				{ Log.exception.log(Level.INFO, "Interrupted", e); }
 			}
 		Log.log.info("Client is connected: thread starts polling the server for events");
 		while (isConnected())
@@ -475,7 +475,7 @@ public class RMICommunicationFacade
 				serialized_event = clientCnxToServer.retrieveEvent();
 				/* wait a little, if and only if we did not receive anything */
 				try { if (serialized_event==null) Thread.sleep(500); }
-				catch (InterruptedException e) {}
+				catch (InterruptedException e) { Log.exception.log(Level.INFO, "Interrupted", e); }
 			}
 			catch (Exception e)
 			{
diff --git a/src/eu/telecom_bretagne/praxis/common/events/SSLSocketCommunicationFacade.java b/src/eu/telecom_bretagne/praxis/common/events/SSLSocketCommunicationFacade.java
index e70bb4db2685459bb826cde8f2c9e5fb430e4005..cd1ff50a23c9cc54a06da320d48243e0ed644a19 100644
--- a/src/eu/telecom_bretagne/praxis/common/events/SSLSocketCommunicationFacade.java
+++ b/src/eu/telecom_bretagne/praxis/common/events/SSLSocketCommunicationFacade.java
@@ -47,6 +47,7 @@ public class SSLSocketCommunicationFacade
 				Log.log.info(()->"SSL Socket server started on port "+port);
 				while (true)
 				{
+					@SuppressWarnings("resource") // socket is intentionally not closed here!
 					Socket socket = serverSocket.accept();
 					SocketCommunicationFacade cnx = new SocketCommunicationFacade("Server (socket SSL)", socket);
 					new Server(cnx);
diff --git a/src/eu/telecom_bretagne/praxis/common/events/ServerToClientEvent.java b/src/eu/telecom_bretagne/praxis/common/events/ServerToClientEvent.java
index 18f3ed18d127bd3637f177fb1e2aeb3c44a62e4e..d790fbf04211636e43b6f519534e35647b06b8a5 100644
--- a/src/eu/telecom_bretagne/praxis/common/events/ServerToClientEvent.java
+++ b/src/eu/telecom_bretagne/praxis/common/events/ServerToClientEvent.java
@@ -26,7 +26,7 @@ import eu.telecom_bretagne.praxis.core.workflow.WorkflowID;
  *     </ul>
  * <li>LIST_OF_AVAILABLE_RESULTS: sets username  and workflow
  *     <ul>
- *     <li>{@link Event#data}: List of {@link Result}
+ *     <li>{@link Event#data}: a non-null list of {@link Result}
  *     <li>{@link Event#file_conveyor}: not used
  *     </ul>
  * <li>MESSAGE: sets username and workflow
diff --git a/src/eu/telecom_bretagne/praxis/common/events/SocketCommunicationFacade.java b/src/eu/telecom_bretagne/praxis/common/events/SocketCommunicationFacade.java
index 38947f5bc252c2460d0337d03214e15987856a6d..2682478dc2a2947b0bc01559d3194f89441c704b 100644
--- a/src/eu/telecom_bretagne/praxis/common/events/SocketCommunicationFacade.java
+++ b/src/eu/telecom_bretagne/praxis/common/events/SocketCommunicationFacade.java
@@ -51,6 +51,7 @@ public class SocketCommunicationFacade
                 Log.log.info(()->"Socket server started on port "+port);
                 while (true)
                 {
+                    @SuppressWarnings("resource") // socket is intentionally not closed here!
                     Socket socket = serverSocket.accept();
                     SocketCommunicationFacade cnx = new SocketCommunicationFacade("Server (socket)", socket);
                     new Server(cnx);
@@ -125,7 +126,7 @@ public class SocketCommunicationFacade
         while (!isConnected())
             synchronized(this)
             {
-                try{ wait(1); } catch (InterruptedException e) {}
+                try{ wait(1); } catch (InterruptedException e) { Log.exception.log(Level.INFO, "Interrupted", e); }
             }
         int successive_failure = 0;
         while (isConnected()) {
diff --git a/src/eu/telecom_bretagne/praxis/core/execution/ExecutionSet.java b/src/eu/telecom_bretagne/praxis/core/execution/ExecutionSet.java
index 6fb767452dcbe66bc810477dfc12d814a9296a13..827a0fe7f08473b75c458f21afede7e61344d8ac 100644
--- a/src/eu/telecom_bretagne/praxis/core/execution/ExecutionSet.java
+++ b/src/eu/telecom_bretagne/praxis/core/execution/ExecutionSet.java
@@ -206,4 +206,10 @@ public class ExecutionSet extends AbstractSet<Program> implements java.io.Serial
 		});
 		return sortedPrograms;
 	}
+	
+	@Override
+	public String toString()
+	{
+		return super.toString() + " tag: " + ( tag == null ? "<null>" : tag.toString() );
+	}
 }
diff --git a/src/eu/telecom_bretagne/praxis/core/execution/ResultStore.java b/src/eu/telecom_bretagne/praxis/core/execution/ResultStore.java
index 36d08889885790d85bd4961915a87893d1bca450..39707f9aba0db1327b6b7350fc565c00b5bd577d 100644
--- a/src/eu/telecom_bretagne/praxis/core/execution/ResultStore.java
+++ b/src/eu/telecom_bretagne/praxis/core/execution/ResultStore.java
@@ -397,12 +397,20 @@ public class ResultStore
 		}
 	}
 
+	/**
+	 * Returns the results available for the supplied workflow and user. The returned results'
+	 * {@link Result#zipFile()} is always null.
+	 * 
+	 * @param workflowID the workflow ID for which results
+	 * @param username the username
+	 * @return list of the available results. It may be null if the results could not be retrieved from the store.
+	 */
 	public ArrayList<Result> getResultsSummaryForWorkflow(WorkflowID workflowID, String username)
     {
 		synchronized(db_connection)
 		{
 		String select = "SELECT * FROM " + RESULT + " WHERE " + RESULT_scid + "=? AND "+RESULT_user+"=?";
-		ArrayList <Result>summary = new ArrayList<Result>();
+		final ArrayList <Result> summary = new ArrayList<Result>();
 		try (PreparedStatement st = db_connection.prepareStatement(select))
 		{
 			st.setString(1, workflowID.dumpID());
@@ -432,12 +440,18 @@ public class ResultStore
 		}
     }
 
+	/**
+	 * Returns the results available for a given user. The returned results' {@link Result#zipFile()} are always null.
+	 * 
+	 * @param username the user name
+	 * @return list of the available results. It may be null if the results could not be retrieved from the store.
+	 */
 	public ArrayList<Result> getResultsSummaryForUser(String username)
     {
 		synchronized(db_connection)
 		{
 		String select = "SELECT * FROM " + RESULT + " where " + RESULT_user + "=?";
-		ArrayList <Result>summary = new ArrayList<Result>();
+		final ArrayList<Result> summary = new ArrayList<Result>();
 		try (PreparedStatement st = db_connection.prepareStatement(select))
 		{
 			st.setString(1, username);
diff --git a/src/eu/telecom_bretagne/praxis/core/execution/SimpleWorkflowPlanner.java b/src/eu/telecom_bretagne/praxis/core/execution/SimpleWorkflowPlanner.java
index ed7bccf3e0b5e608dd2a40a5e4a56bfdef3e5cb3..252afd12c4232dc449885f3dfe1e2b0a30da9c7d 100644
--- a/src/eu/telecom_bretagne/praxis/core/execution/SimpleWorkflowPlanner.java
+++ b/src/eu/telecom_bretagne/praxis/core/execution/SimpleWorkflowPlanner.java
@@ -57,7 +57,8 @@ public class SimpleWorkflowPlanner
     	
     	for (Long tag=1L; tag<=max_tag; tag++)
     	{
-    		for (Activity a: new ArrayList<Activity>(process.activities)) // decideExecSet() may modify the list
+    		final ArrayList<Activity> activities = new ArrayList<Activity>(process.activities);
+    		for (Activity a: activities) // decideExecSet() may modify the list
     		{
     			if (a.getContainer()==null) // activity has been merged into an other one and is not in the process anymore
     				continue;
@@ -149,9 +150,15 @@ public class SimpleWorkflowPlanner
 		}
 		
 		// Finally, assign all predecessors to the same platform as activity: merge them
+		// The resulting activity gets the smallest tag value of all the merged activities.
+		Long tag = (Long) activity.getExecutionSet().getTag();
 		for (Activity predecessor: predecessors)
 		{
+			final Long pred_tag = (Long) predecessor.getExecutionSet().getTag();
 			activity = process.merge(activity, predecessor);
+			if (pred_tag < tag)
+				tag = pred_tag;
+			activity.getExecutionSet().setTag(tag);
 		}
 	}
 	
diff --git a/src/eu/telecom_bretagne/praxis/core/resource/ParameterDescription.java b/src/eu/telecom_bretagne/praxis/core/resource/ParameterDescription.java
index 262a7893ca81a72f9e8bf4cc0e8fe81ba239639e..b8db35f9bd490d222add05286c06ad4c13edb015 100644
--- a/src/eu/telecom_bretagne/praxis/core/resource/ParameterDescription.java
+++ b/src/eu/telecom_bretagne/praxis/core/resource/ParameterDescription.java
@@ -26,6 +26,7 @@ import org.jdom.JDOMException;
 import org.jdom.xpath.XPath;
 
 import eu.telecom_bretagne.praxis.common.Facade_xml;
+import eu.telecom_bretagne.praxis.common.I18N;
 import eu.telecom_bretagne.praxis.common.InvalidXMLException;
 import eu.telecom_bretagne.praxis.common.InvalidXMLException.ELEMENT_TYPE;
 import eu.telecom_bretagne.praxis.core.workflow.Parameter;
@@ -323,6 +324,7 @@ public class ParameterDescription implements Serializable
 	 * @param value
 	 *            the value to check
 	 * @return true if the value is valid with respect to the parameter's type
+	 * @see #getValueConstraintMessage()
 	 */
     public boolean isaValidValue_wrtType(String value)
     {
@@ -604,7 +606,27 @@ public class ParameterDescription implements Serializable
         return valueConstraintDescription;
     }
 
-	/**
+    /**
+     * Returns the message to display when the value is {@link #isaValidValue(String) invalid}.
+     * 
+     * @return either the {@link #getValueConstraintDescription() description of the constraint}, or a default message
+     *         if the latter is null or empty.
+     */
+    public String getValueConstraintMessage() {
+        if ( valueConstraintDescription != null && ! "".equals(valueConstraintDescription) )
+            return valueConstraintDescription;
+        switch (type)
+        {
+            case FLOAT:
+                return I18N.s("UI.dialog.prg_properties.invalid_float_value");
+            case INT:
+                return I18N.s("UI.dialog.prg_properties.invalid_integer_value");
+            default:
+                return I18N.s("UI.dialog.prg_properties.invalid_value");
+        }
+    }
+
+    /**
 	 * Parses the value constraint and transforms it into a valid java boolean expression. The built expression
 	 * determines whether a given value is valid wrt. the constraint; this value is named <code>value</code> in the
 	 * built expression.
diff --git a/src/eu/telecom_bretagne/praxis/core/workflow/Parameter.java b/src/eu/telecom_bretagne/praxis/core/workflow/Parameter.java
index 7be85f13cb782e5684b777fbdb3907b078b67c96..2b07ba522ce4b3c59dd78f9efca2609a5c8a206d 100644
--- a/src/eu/telecom_bretagne/praxis/core/workflow/Parameter.java
+++ b/src/eu/telecom_bretagne/praxis/core/workflow/Parameter.java
@@ -604,6 +604,11 @@ public class Parameter implements Cloneable, PropertyChangeListener, java.io.Ser
 		return p;
 	}
 
+	public String toString()
+	{
+		return "[Parameter ref_id:"+ref_id+"]";
+	}
+
 	/* PropertyChangeSupport listeners & */
 
 	public void addPropertyChangeListener(PropertyChangeListener listener) {
diff --git a/src/eu/telecom_bretagne/praxis/platform/PlatformToClientBridge.java b/src/eu/telecom_bretagne/praxis/platform/PlatformToClientBridge.java
index c0fe672bb3acd5a90655b0e384a13402c5764fb8..582e82c2811e4fd5f65d848e93c76dc0309a800d 100644
--- a/src/eu/telecom_bretagne/praxis/platform/PlatformToClientBridge.java
+++ b/src/eu/telecom_bretagne/praxis/platform/PlatformToClientBridge.java
@@ -96,7 +96,7 @@ public class PlatformToClientBridge
 
 			Log.log.severe(()->error_title+": "+error);
 
-			ErrorDialog.displayErrorMessage(error_title, error);
+			ErrorDialog.showErrorMessage(error_title, error);
 			System.exit(-1);// TODO list & identify all exit status
 		}
 	}
@@ -161,7 +161,7 @@ public class PlatformToClientBridge
 		{
 			// this is the result of an execution that was not sent by us. It may come from a different configuration
 			// where the bridge is not activated.  Log it and send it as-is.
-			Log.log.info(()->"Received a result with result.data==null. This cant be for use. "+result);
+			Log.log.info(()->"Received a result with result.data==null. This was not sent by the bridge. "+result);
 		}
 		this.sendResults(result);
 		if (result.data!=null && result.getStatus().isClosed())
@@ -197,7 +197,7 @@ public class PlatformToClientBridge
 	public void receivedMessage(ServerToClientEvent event)
 	{
 		if (event.forward)
-			ErrorDialog.displayWarningMessage("Message from server", (String)((Object[]) event.data)[0]);
+			ErrorDialog.showWarningMessage("Message from server", (String)((Object[]) event.data)[0]);
 	}
 
 	@Override
diff --git a/src/eu/telecom_bretagne/praxis/server/Client.java b/src/eu/telecom_bretagne/praxis/server/Client.java
index 4dc837ece2a50e1b80d826ee22c55e39440a5f6e..886ed3af6bd92f5f022d842471bf3c0d0728d1e1 100644
--- a/src/eu/telecom_bretagne/praxis/server/Client.java
+++ b/src/eu/telecom_bretagne/praxis/server/Client.java
@@ -9,6 +9,7 @@ import static eu.telecom_bretagne.praxis.common.events.ServerToClientEvent.Type.
 
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.logging.Level;
 
 import eu.telecom_bretagne.praxis.common.Log;
 import eu.telecom_bretagne.praxis.common.ReleaseInfo;
@@ -81,7 +82,7 @@ public class Client implements Requester
         	// can happen before the message is delivered TODO should be fixed
         	Thread.sleep(500);
         }
-        catch (InterruptedException e) {}
+        catch (InterruptedException e) { Log.exception.log(Level.INFO, "Interrupted", e); }
         cnx.disconnect();
     }
 
@@ -154,8 +155,8 @@ public class Client implements Requester
 		ServerToClientEvent event = new ServerToClientEvent(LIST_OF_AVAILABLE_RESULTS);
 		event.workflowID = workflowID;
 		ArrayList<Result> results = Serveur.resultStore().getResultsSummaryForWorkflow(workflowID, login);
-		if (results==null || results.isEmpty())
-			return;
+		if (results == null)
+		    results = new ArrayList<>();
 		// method getResultsSummaryForWorkflow() returns results w/ null zipFile, we want to make it explicit that
 		// zipFile should not be sent.
 		for (Result result: results)
diff --git a/src/eu/telecom_bretagne/praxis/server/execution/ExecutionEngine.java b/src/eu/telecom_bretagne/praxis/server/execution/ExecutionEngine.java
index df304aee153b808056c3ffa15613359554c8e29b..b1fd99dff39cc7947e15f71a2ae1c33a1b8d8c11 100644
--- a/src/eu/telecom_bretagne/praxis/server/execution/ExecutionEngine.java
+++ b/src/eu/telecom_bretagne/praxis/server/execution/ExecutionEngine.java
@@ -106,7 +106,7 @@ public abstract class ExecutionEngine
 	/** An execution progress monitor doing nothing whose operations are no-op */
 	public static final ExecutionProgressMonitor noopProgressMonitor = new ExecutionProgressMonitor()
 	{
-		@Override public void setProgress(Result result) { }
+		@Override public void setProgress(Result result) { /* no-op */ }
 	};
 
 	/**
diff --git a/test/eu/telecom_bretagne/praxis/core/execution/EventAuditTest.java b/test/eu/telecom_bretagne/praxis/core/execution/EventAuditTest.java
index f3188496716c39161f7bb2461080e501e643a265..29c19af8dbf25adb9ed7723b14a03fe38d8d379b 100644
--- a/test/eu/telecom_bretagne/praxis/core/execution/EventAuditTest.java
+++ b/test/eu/telecom_bretagne/praxis/core/execution/EventAuditTest.java
@@ -20,13 +20,13 @@ public class EventAuditTest
 	 */
 	@Before
 	public void setUp() throws Exception
-	{}
+	{ ; }
 	
 	/**
 	 * @throws java.lang.Exception
 	 */
 	@After
 	public void tearDown() throws Exception
-	{}
+	{ ; }
 	
 }
diff --git a/test/eu/telecom_bretagne/praxis/core/execution/ExecutionSetTest.java b/test/eu/telecom_bretagne/praxis/core/execution/ExecutionSetTest.java
index 6464dff1e261a62c7dd9a893f112678d15da40c7..9704cbcab310dd63cf27e20c298dc063f8a11188 100644
--- a/test/eu/telecom_bretagne/praxis/core/execution/ExecutionSetTest.java
+++ b/test/eu/telecom_bretagne/praxis/core/execution/ExecutionSetTest.java
@@ -11,8 +11,6 @@ import static org.junit.Assert.assertTrue;
 
 import java.util.Arrays;
 
-import org.junit.After;
-import org.junit.Before;
 import org.junit.Test;
 
 import eu.telecom_bretagne.praxis.core.execution.ExecutionSet.ProgramInfo;
@@ -24,16 +22,6 @@ import eu.telecom_bretagne.praxis.core.workflow.Program;
  */
 public class ExecutionSetTest
 {   
-    @Before
-	public void setUp()
-	{
-	}
-
-    @After
-    public void cleanUp()
-    {
-    }
-    
 	@Test
 	public void addToSet()
 	{
diff --git a/test/eu/telecom_bretagne/praxis/core/execution/ProcessTest.java b/test/eu/telecom_bretagne/praxis/core/execution/ProcessTest.java
index 5def8df6d38e275af6be4d55fe884a267ac6a6fb..2d534e1d1588c5a102798637c8c74a5f63baec6a 100644
--- a/test/eu/telecom_bretagne/praxis/core/execution/ProcessTest.java
+++ b/test/eu/telecom_bretagne/praxis/core/execution/ProcessTest.java
@@ -1,7 +1,6 @@
 /* License: please refer to the file README.license located at the root directory of the project */
 package eu.telecom_bretagne.praxis.core.execution;
 
-import org.junit.Before;
 import org.junit.Test;
 
 import eu.telecom_bretagne.praxis.core.execution.Activity;
@@ -30,12 +29,6 @@ public class ProcessTest
 		super(null,null);
 	}
 	
-	@Before
-	public void SetUp()
-	{
-		
-	}
-
 	@Test
 	public void activityHasaDefaultContext()
 	{