Index: simplerunner/pom.xml
===================================================================
--- simplerunner/pom.xml	(revision 44)
+++ simplerunner/pom.xml	(revision 45)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb</groupId>
 	<artifactId>simplerunner</artifactId>
-	<version>2.0.8</version> 
+	<version>2.1.0</version>
 	<packaging>jar</packaging>
 
Index: simplerunner/src/main/java/geniusweb/simplerunner/NegoRunner.java
===================================================================
--- simplerunner/src/main/java/geniusweb/simplerunner/NegoRunner.java	(revision 44)
+++ simplerunner/src/main/java/geniusweb/simplerunner/NegoRunner.java	(revision 45)
@@ -5,16 +5,9 @@
 import java.nio.file.Files;
 import java.nio.file.Paths;
-import java.util.List;
 import java.util.logging.Level;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 
-import geniusweb.events.ProtocolEvent;
-import geniusweb.protocol.CurrentNegoState;
-import geniusweb.protocol.NegoProtocol;
 import geniusweb.protocol.NegoSettings;
-import geniusweb.protocol.NegoState;
-import geniusweb.protocol.partyconnection.ProtocolToPartyConnFactory;
 import geniusweb.simplerunner.gui.GUI;
 import tudelft.utilities.logging.Reporter;
@@ -36,108 +29,13 @@
  * </ul>
  */
-public class NegoRunner implements Runnable {
+public class NegoRunner {
 	private final static ObjectMapper jackson = new ObjectMapper();
-
-	private final NegoSettings settings;
-	private final NegoProtocol protocol;
-	private final ClassPathConnectionFactory connectionfactory;
-	protected final Reporter log;
-	private boolean properlyStopped = false;
-	private final int LOOPTIME = 200;// ms
-	private final int FINALWAITTIME = 5000;// ms
-	private long maxruntime;
-
-	/**
-	 * 
-	 * @param settings          the {@link NegoSettings}
-	 * @param connectionfactory the {@link ProtocolToPartyConnFactory}
-	 * @param logger            the {@link Reporter} to log problems
-	 * @param maxruntime        limit in millisecs. Ignored if 0
-	 */
-	public NegoRunner(NegoSettings settings,
-			ClassPathConnectionFactory connectionfactory, Reporter logger,
-			long maxruntime) {
-		if (settings == null || connectionfactory == null) {
-			throw new NullPointerException("Arguments must be not null");
-		}
-		this.settings = settings;
-		this.log = logger;
-		this.protocol = settings.getProtocol(log);
-		this.connectionfactory = connectionfactory;
-		this.maxruntime = maxruntime;
-	}
-
-	/**
-	 * 
-	 * @return true if the runner has finished
-	 */
-	public boolean isProperlyStopped() {
-		return properlyStopped;
-	}
-
-	@Override
-	public void run() {
-		protocol.addListener(evt -> handle(evt));
-		protocol.start(connectionfactory);
-		long remainingtime = maxruntime;
-		while (!properlyStopped && (maxruntime == 0 || remainingtime > 0)) {
-			try {
-				Thread.sleep(LOOPTIME);
-				remainingtime -= LOOPTIME;
-			} catch (InterruptedException e) {
-				e.printStackTrace();
-			}
-		}
-		log.log(Level.INFO, "Waiting for connection closure");
-
-		remainingtime = FINALWAITTIME;
-		while (remainingtime > 0
-				&& !connectionfactory.getOpenConnections().isEmpty()) {
-			try {
-				Thread.sleep(LOOPTIME);
-				remainingtime -= LOOPTIME;
-			} catch (InterruptedException e) {
-				e.printStackTrace();
-			}
-		}
-		List<BasicConnection> openconn = connectionfactory.getOpenConnections();
-		if (!openconn.isEmpty())
-			log.log(Level.WARNING, "Connections " + openconn
-					+ " did not close properly at end of run");
-		log.log(Level.INFO, "end run");
-	}
-
-	private void handle(ProtocolEvent evt) {
-		if (evt instanceof CurrentNegoState && ((CurrentNegoState) evt)
-				.getState().isFinal(System.currentTimeMillis())) {
-			stop();
-		}
-	}
-
-	protected void stop() {
-		logFinal(Level.INFO, protocol.getState());
-		properlyStopped = true;
-	}
-
-	/**
-	 * Separate so that we can intercept this when mocking, as this will crash
-	 * on mocks because {@link #jackson} can not handle mocks.
-	 * 
-	 * @param level the log {@link Level}
-	 * @param state the {@link NegoState} to log
-	 */
-	protected void logFinal(Level level, NegoState state) {
-		try {
-			log.log(level, "protocol ended normally: "
-					+ jackson.writeValueAsString(protocol.getState()));
-		} catch (JsonProcessingException e) {
-			e.printStackTrace();
-		}
-	}
 
 	/**
 	 * The main runner
 	 * 
-	 * @param args should have 1 argument, the settings.json file to be used.
+	 * @param args should have 0 or 1 argument. If 0 arguments, the {@link GUI}
+	 *             is started. If one argoment, it should be a filename
+	 *             containing a settings.json file. That session is then run.
 	 * @throws IOException if problem occurs
 	 */
@@ -156,6 +54,6 @@
 				NegoSettings.class);
 
-		NegoRunner runner = new NegoRunner(settings,
-				new ClassPathConnectionFactory(), new StdOutReporter(), 0);
+		Runner runner = new Runner(settings, new ClassPathConnectionFactory(),
+				new StdOutReporter(), 0);
 		runner.run();
 	}
@@ -171,10 +69,4 @@
 	}
 
-	/**
-	 * @return protocol that runs/ran the session.
-	 */
-	public NegoProtocol getProtocol() {
-		return protocol;
-	}
 }
 
Index: simplerunner/src/main/java/geniusweb/simplerunner/Runner.java
===================================================================
--- simplerunner/src/main/java/geniusweb/simplerunner/Runner.java	(revision 45)
+++ simplerunner/src/main/java/geniusweb/simplerunner/Runner.java	(revision 45)
@@ -0,0 +1,139 @@
+package geniusweb.simplerunner;
+
+import java.util.List;
+import java.util.logging.Level;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import geniusweb.events.ProtocolEvent;
+import geniusweb.protocol.CurrentNegoState;
+import geniusweb.protocol.NegoProtocol;
+import geniusweb.protocol.NegoSettings;
+import geniusweb.protocol.NegoState;
+import geniusweb.protocol.partyconnection.ProtocolToPartyConnFactory;
+import tudelft.utilities.logging.Reporter;
+
+/**
+ * A simple tool to run a negotiation stand-alone, without starting the servers.
+ * All referred files and classes need to be stored locally (or be in the
+ * dependency list if you use maven).
+ * <p>
+ * <em>IMPORTANT</em> SimpleRunner has a number of restrictions, compared to a
+ * run using a runserver and partyserver
+ * <ul>
+ * <li>With stand-alone runner, your parties are run together in a single
+ * classloader. The main implication is that there may arise version conflicts
+ * between parties.
+ * <li>Stand-alone runner does NOT enforce the time deadline. Parties may
+ * continue running indefinitely and thus bog down the JVM and stalling
+ * tournaments.
+ * </ul>
+ */
+public class Runner implements Runnable {
+	private final static ObjectMapper jackson = new ObjectMapper();
+
+	private final NegoSettings settings;
+	private final NegoProtocol protocol;
+	private final ClassPathConnectionFactory connectionfactory;
+	protected final Reporter log;
+	private boolean properlyStopped = false;
+	private final int LOOPTIME = 200;// ms
+	private final int FINALWAITTIME = 5000;// ms
+	private long maxruntime;
+
+	/**
+	 * 
+	 * @param settings          the {@link NegoSettings}
+	 * @param connectionfactory the {@link ProtocolToPartyConnFactory}
+	 * @param logger            the {@link Reporter} to log problems
+	 * @param maxruntime        limit in millisecs. Ignored if 0
+	 */
+	public Runner(NegoSettings settings,
+			ClassPathConnectionFactory connectionfactory, Reporter logger,
+			long maxruntime) {
+		if (settings == null || connectionfactory == null) {
+			throw new NullPointerException("Arguments must be not null");
+		}
+		this.settings = settings;
+		this.log = logger;
+		this.protocol = settings.getProtocol(log);
+		this.connectionfactory = connectionfactory;
+		this.maxruntime = maxruntime;
+	}
+
+	/**
+	 * 
+	 * @return true if the runner has finished
+	 */
+	public boolean isProperlyStopped() {
+		return properlyStopped;
+	}
+
+	@Override
+	public void run() {
+		protocol.addListener(evt -> handle(evt));
+		protocol.start(connectionfactory);
+		long remainingtime = maxruntime;
+		while (!properlyStopped && (maxruntime == 0 || remainingtime > 0)) {
+			try {
+				Thread.sleep(LOOPTIME);
+				remainingtime -= LOOPTIME;
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+		log.log(Level.INFO, "Waiting for connection closure");
+
+		remainingtime = FINALWAITTIME;
+		while (remainingtime > 0
+				&& !connectionfactory.getOpenConnections().isEmpty()) {
+			try {
+				Thread.sleep(LOOPTIME);
+				remainingtime -= LOOPTIME;
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+		List<BasicConnection> openconn = connectionfactory.getOpenConnections();
+		if (!openconn.isEmpty())
+			log.log(Level.WARNING, "Connections " + openconn
+					+ " did not close properly at end of run");
+		log.log(Level.INFO, "end run");
+	}
+
+	private void handle(ProtocolEvent evt) {
+		if (evt instanceof CurrentNegoState && ((CurrentNegoState) evt)
+				.getState().isFinal(System.currentTimeMillis())) {
+			stop();
+		}
+	}
+
+	protected void stop() {
+		logFinal(Level.INFO, protocol.getState());
+		properlyStopped = true;
+	}
+
+	/**
+	 * Separate so that we can intercept this when mocking, as this will crash
+	 * on mocks because {@link #jackson} can not handle mocks.
+	 * 
+	 * @param level the log {@link Level}
+	 * @param state the {@link NegoState} to log
+	 */
+	protected void logFinal(Level level, NegoState state) {
+		try {
+			log.log(level, "protocol ended normally: "
+					+ jackson.writeValueAsString(protocol.getState()));
+		} catch (JsonProcessingException e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * @return protocol that runs/ran the session.
+	 */
+	public NegoProtocol getProtocol() {
+		return protocol;
+	}
+}
Index: simplerunner/src/main/java/geniusweb/simplerunner/gui/GUI.java
===================================================================
--- simplerunner/src/main/java/geniusweb/simplerunner/gui/GUI.java	(revision 44)
+++ simplerunner/src/main/java/geniusweb/simplerunner/gui/GUI.java	(revision 45)
@@ -11,7 +11,8 @@
 import javax.swing.JScrollPane;
 import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
 
 import geniusweb.simplerunner.ClassPathConnectionFactory;
-import geniusweb.simplerunner.NegoRunner;
+import geniusweb.simplerunner.Runner;
 import tudelft.utilities.logging.Reporter;
 
@@ -50,16 +51,28 @@
 			@Override
 			public void log(Level level, String msg) {
-				resultarea.append("[" + level + "] " + msg + "\n");
+				SwingUtilities.invokeLater(new Runnable() {
+					@Override
+					public void run() {
+						resultarea.append("[" + level + "] " + msg + "\n");
+					}
+				});
 			}
 
 			@Override
 			public void log(Level level, String msg, Throwable thrown) {
-				resultarea.append("[" + level + "] throws " + msg + "\n");
-				StringWriter errors = new StringWriter();
-				thrown.printStackTrace(new PrintWriter(errors));
-				resultarea.append(errors.toString() + "\n");
+				SwingUtilities.invokeLater(new Runnable() {
+
+					@Override
+					public void run() {
+						resultarea
+								.append("[" + level + "] throws " + msg + "\n");
+						StringWriter errors = new StringWriter();
+						thrown.printStackTrace(new PrintWriter(errors));
+						resultarea.append(errors.toString() + "\n");
+					}
+				});
 			}
 		};
-		NegoRunner runner = new NegoRunner(settingsPanel.getSettings(),
+		Runner runner = new Runner(settingsPanel.getSettings(),
 				new ClassPathConnectionFactory(), myreporter, 0);
 		runner.run();
Index: simplerunner/src/test/java/geniusweb/simplerunner/SessionRunnerE2ETest.java
===================================================================
--- simplerunner/src/test/java/geniusweb/simplerunner/SessionRunnerE2ETest.java	(revision 44)
+++ simplerunner/src/test/java/geniusweb/simplerunner/SessionRunnerE2ETest.java	(revision 45)
@@ -37,5 +37,5 @@
 	private static final int TEST_RUNTIME = 5000;
 	private final ObjectMapper jackson = new ObjectMapper();
-	private NegoRunner runner;
+	private Runner runner;
 	private Reporter logger = spy(new ReportToLogger("test"));
 	private String filename;
@@ -65,6 +65,6 @@
 				NegoSettings.class);
 
-		runner = new NegoRunner(settings, new ClassPathConnectionFactory(),
-				logger, TEST_RUNTIME);
+		runner = new Runner(settings, new ClassPathConnectionFactory(), logger,
+				TEST_RUNTIME);
 
 	}
Index: simplerunner/src/test/java/geniusweb/simplerunner/SessionRunnerTest.java
===================================================================
--- simplerunner/src/test/java/geniusweb/simplerunner/SessionRunnerTest.java	(revision 44)
+++ simplerunner/src/test/java/geniusweb/simplerunner/SessionRunnerTest.java	(revision 45)
@@ -1,7 +1,7 @@
 package geniusweb.simplerunner;
 
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.eq;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -46,5 +46,5 @@
 	@Test
 	public void smokeTest() {
-		new NegoRunner(mock(SessionSettings.class),
+		new Runner(mock(SessionSettings.class),
 				mock(ClassPathConnectionFactory.class), logger, 5000);
 	}
@@ -59,6 +59,5 @@
 				ClassPathConnectionFactory.class);
 
-		NegoRunner runner = spy(
-				new NegoRunner(settings, factory, logger, 5000));
+		Runner runner = spy(new Runner(settings, factory, logger, 5000));
 		runner.run();
 
@@ -81,11 +80,10 @@
 		ClassPathConnectionFactory factory = mock(
 				ClassPathConnectionFactory.class);
-		NegoRunner runner = spy(
-				new NegoRunner(settings, factory, logger, 5000) {
-					@Override
-					protected void logFinal(Level level, NegoState state) {
-						log.log(level, state.toString());
-					}
-				});
+		Runner runner = spy(new Runner(settings, factory, logger, 5000) {
+			@Override
+			protected void logFinal(Level level, NegoState state) {
+				log.log(level, state.toString());
+			}
+		});
 		ArgumentCaptor<Listener> listener = ArgumentCaptor
 				.forClass(Listener.class);
@@ -112,11 +110,10 @@
 		ClassPathConnectionFactory factory = mock(
 				ClassPathConnectionFactory.class);
-		NegoRunner runner = spy(
-				new NegoRunner(settings, factory, logger, 5000) {
-					@Override
-					protected void logFinal(Level level, NegoState state) {
-						log.log(level, state.toString());
-					}
-				});
+		Runner runner = spy(new Runner(settings, factory, logger, 5000) {
+			@Override
+			protected void logFinal(Level level, NegoState state) {
+				log.log(level, state.toString());
+			}
+		});
 		ArgumentCaptor<Listener> listener = ArgumentCaptor
 				.forClass(Listener.class);
