Index: src/main/java/geniusweb/partiesserver/AvailablePartiesUpdater.java
===================================================================
--- src/main/java/geniusweb/partiesserver/AvailablePartiesUpdater.java	(revision 46)
+++ src/main/java/geniusweb/partiesserver/AvailablePartiesUpdater.java	(revision 1)
@@ -3,7 +3,9 @@
 import java.io.File;
 import java.io.IOException;
+import java.net.JarURLConnection;
 import java.net.MalformedURLException;
 import java.net.URISyntaxException;
 import java.net.URL;
+import java.net.URLClassLoader;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -12,5 +14,4 @@
 import java.util.logging.Level;
 
-import geniusweb.partiesserver.repository.AvailableJavaParty;
 import geniusweb.partiesserver.repository.AvailablePartiesRepo;
 import geniusweb.partiesserver.repository.AvailableParty;
@@ -23,4 +24,5 @@
 import tudelft.utilities.logging.Reporter;
 import tudelft.utilities.repository.Repository;
+import java.util.jar.Attributes;
 
 /**
@@ -108,6 +110,5 @@
 	private void tryLoad(File file) {
 		try {
-			repository.put(
-					new AvailableJavaParty(getShortName(file), load(file)));
+			repository.put(new AvailableParty(getShortName(file), load(file)));
 		} catch (Throwable e) {
 			log.log(Level.WARNING, "Can not load class from file " + file, e);
@@ -225,2 +226,4 @@
 	}
 }
+
+
Index: src/main/java/geniusweb/partiesserver/Constants.java
===================================================================
--- src/main/java/geniusweb/partiesserver/Constants.java	(revision 46)
+++ 	(revision )
@@ -1,62 +1,0 @@
-package geniusweb.partiesserver;
-
-import java.lang.management.ManagementFactory;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.Set;
-
-import javax.management.MBeanServer;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-import javax.management.Query;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-/**
- * A central class containing the constants/configuration of the server.
- * 
- * <b> This class should is private to the server and should not be used by
- * others. However servers that derive from this server can completely override
- * this class to change the constants/configuration</b>
- */
-public class Constants {
-	private static transient ObjectMapper jackson; // cache
-	private static transient String hostport = ""; // cache
-
-	/**
-	 * 
-	 * @return the object mapper, so that we can extend the objectmapper (with
-	 *         custom classes) centrally. Also allows us to cache the objectmapper
-	 */
-	public static ObjectMapper getJackson() {
-		if (jackson == null) {
-			jackson = new ObjectMapper();
-		}
-		return jackson;
-	}
-
-	/**
-	 * 
-	 * @return a string like "127.0.1.1:8080" containing the server address on which
-	 *         this service is running.
-	 * @throws UnknownHostException         if we can not get the host ip
-	 * @throws MalformedObjectNameException if we can not get the host ip
-	 */
-	public static String getIpAddressAndPort() throws UnknownHostException, MalformedObjectNameException {
-		synchronized (hostport) {
-			if (hostport.isEmpty()) {
-				MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
-
-				Set<ObjectName> objectNames = beanServer.queryNames(new ObjectName("*:type=Connector,*"),
-						Query.match(Query.attr("protocol"), Query.value("HTTP/1.1")));
-
-				String host = InetAddress.getLocalHost().getHostAddress();
-				String port = objectNames.iterator().next().getKeyProperty("port");
-
-				hostport = host + ":" + port;
-			}
-			return hostport;
-		}
-
-	}
-}
Index: src/main/java/geniusweb/partiesserver/Info.java
===================================================================
--- src/main/java/geniusweb/partiesserver/Info.java	(revision 46)
+++ src/main/java/geniusweb/partiesserver/Info.java	(revision 1)
@@ -7,4 +7,6 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
 
 import geniusweb.partiesserver.repository.RunningPartiesRepo;
@@ -18,22 +20,23 @@
 	private final static RunningPartiesRepo repo = RunningPartiesRepo
 			.instance();
+	private final static ObjectMapper jackson = new ObjectMapper();
 
 	/**
-	 * see
-	 * {@link HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)}.
-	 * Returns to the http caller
-	 * <ul>
-	 * <li>URL with websocket address to contact the now running agent.
-	 * <li>SC_NOT_FOUND (404) if attempt is made to access non-running party.
-	 * <li>SC_SERVICE_UNAVAILABLE (503) if there are no free slots to run the
-	 * party.
-	 * <li>SC_EXPECTATION_FAILED (417) if something else goes wrong during
-	 * instantiating the party (then see logs for more details)
-	 * </ul>
+	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
+	 *      response). Returns
+	 *      <ul>
+	 *      <li>URL with websocket address to contact the now running agent.
+	 *      <li>SC_NOT_FOUND (404) if attempt is made to access non-running
+	 *      party.
+	 *      <li>SC_SERVICE_UNAVAILABLE (503) if there are no free slots to run
+	 *      the party.
+	 *      <li>SC_EXPECTATION_FAILED (417) if something else goes wrong during
+	 *      instantiating the party (then see logs for more details)
+	 *      </ul>
 	 */
 	@Override
 	protected void doGet(HttpServletRequest request,
 			HttpServletResponse response) throws ServletException, IOException {
-		response.getWriter().append(Constants.getJackson().writeValueAsString(
+		response.getWriter().append(jackson.writeValueAsString(
 				new ServerInfo(repo.availableSlots(), repo.maximumSlots())));
 	}
Index: src/main/java/geniusweb/partiesserver/RunParty.java
===================================================================
--- src/main/java/geniusweb/partiesserver/RunParty.java	(revision 46)
+++ src/main/java/geniusweb/partiesserver/RunParty.java	(revision 1)
@@ -2,8 +2,6 @@
 
 import java.io.IOException;
-import java.net.UnknownHostException;
 import java.util.logging.Level;
 
-import javax.management.MalformedObjectNameException;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
@@ -45,15 +43,15 @@
 
 	/**
-	 * See
-	 * {@link HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)}.
-	 * Returns
-	 * <ul>
-	 * <li>URL with websocket address to contact the now running agent.
-	 * <li>SC_NOT_FOUND (404) if attempt is made to access non-running party.
-	 * <li>SC_SERVICE_UNAVAILABLE (503) if there are no free slots to run the
-	 * party.
-	 * <li>SC_EXPECTATION_FAILED (417) if something else goes wrong during
-	 * instantiating the party (then see logs for more details)
-	 * </ul>
+	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
+	 *      response). Returns
+	 *      <ul>
+	 *      <li>URL with websocket address to contact the now running agent.
+	 *      <li>SC_NOT_FOUND (404) if attempt is made to access non-running
+	 *      party.
+	 *      <li>SC_SERVICE_UNAVAILABLE (503) if there are no free slots to run
+	 *      the party.
+	 *      <li>SC_EXPECTATION_FAILED (417) if something else goes wrong during
+	 *      instantiating the party (then see logs for more details)
+	 *      </ul>
 	 */
 	@Override
@@ -62,5 +60,5 @@
 		String name = request.getPathInfo().substring(1);
 		log.log(Level.INFO, "request to run " + name);
-		System.setSecurityManager(new SimpleSecurityManager());
+
 		AvailableParty party = AvailablePartiesRepo.instance().get(name);
 		if (party == null) {
@@ -97,11 +95,7 @@
 		}
 		log.log(Level.INFO, "started " + name);
-		String url;
-		try {
-			url = "ws://" + Constants.getIpAddressAndPort()
-					+ request.getContextPath() + "/party/" + running.getID();
-		} catch (MalformedObjectNameException | UnknownHostException e) {
-			throw new IOException("Failure creating websocket address", e);
-		}
+		String url = "ws://" + request.getLocalName() + ":"
+				+ request.getLocalPort() + request.getContextPath() + "/party/"
+				+ running.getID();
 		response.getWriter().append(url);
 
Index: src/main/java/geniusweb/partiesserver/RunningPartiesUpdater.java
===================================================================
--- src/main/java/geniusweb/partiesserver/RunningPartiesUpdater.java	(revision 46)
+++ src/main/java/geniusweb/partiesserver/RunningPartiesUpdater.java	(revision 1)
@@ -5,5 +5,4 @@
 import geniusweb.partiesserver.repository.RunningPartiesRepo;
 import geniusweb.partiesserver.repository.RunningParty;
-import geniusweb.party.Party;
 import tudelft.utilities.logging.ReportToLogger;
 import tudelft.utilities.logging.Reporter;
@@ -12,8 +11,5 @@
  * 
  * This object keeps the {@link RunningPartiesRepo} up to date. Main job is to
- * remove parties that have been timed out. When a party times out, it calls
- * {@link Party#terminate()} but that might fail to stop a party. In the end,
- * the protocol should close the connection after the deadline. Start and run
- * only once.
+ * remove parties that have been timed out. Start and run only once.
  */
 public class RunningPartiesUpdater implements Runnable {
@@ -24,15 +20,15 @@
 	 * when a negotiation runs out of time, the protocol may want to inform all
 	 * parties about the failed session. If the parties are all killed at that
-	 * moment, this is impossible. Therefore we wait KILL_DELAY extra time
-	 * before really killing the parties.
+	 * moment, this is impossible. Therefore we wait KILL_DELAY extra time before
+	 * really killing the parties.
 	 */
-	public static final long KILL_DELAY = 5000;
+	private static final long KILL_DELAY = 2000;
 
 	/**
 	 * @param repo   the {@link RunningPartiesRepo} that must be updated
 	 *               automatically
-	 * @param period the period with which to check time-out (ms). Recommended
-	 *               1000. After constructing you can run this in separate
-	 *               thread or just call {@link #run()}
+	 * @param period the period with which to check time-out (ms). Recommended 1000.
+	 *               After constructing you can run this in separate thread or just
+	 *               call {@link #run()}
 	 * 
 	 */
@@ -54,14 +50,12 @@
 			}
 		} catch (InterruptedException e) {
-			System.err
-					.println("ERROR:  RunningPartiesUpdater was interrupted!");
+			System.err.println("ERROR:  RunningPartiesUpdater was interrupted!");
 		}
 	}
 
 	/**
-	 * Removes parties when they ran out of time. Called when some file that may
-	 * be relevant has changed, and periodically every {@link #period}.
-	 * Synchronized to avoid weird states if filesystem changes rapidly. We
-	 * ignore everything but jar files.
+	 * Called when some file that may be relevant has changed. Synchronized to avoid
+	 * weird states if filesystem changes rapidly. We ignore everything but jar
+	 * files.
 	 */
 	void update() {
@@ -69,13 +63,6 @@
 			long now = System.currentTimeMillis();
 			if (now >= party.getEndDate().getTime() + KILL_DELAY) {
-				log.log(Level.WARNING,
-						"party " + party.getID() + " still running "
-								+ KILL_DELAY / 1000
-								+ "s after deadline. Removed now.");
 				running.remove(party.getID());
-				try {
-					Thread.sleep(20);
-				} catch (InterruptedException e) {
-				}
+				log.log(Level.WARNING, "party " + party.getID() + " was timed out and terminated");
 			}
 		}
Index: src/main/java/geniusweb/partiesserver/SimpleSecurityManager.java
===================================================================
--- src/main/java/geniusweb/partiesserver/SimpleSecurityManager.java	(revision 46)
+++ 	(revision )
@@ -1,13 +1,0 @@
-package geniusweb.partiesserver;
-
-import java.security.Permission;
-
-public class SimpleSecurityManager extends SecurityManager {
-	@Override
-	public void checkPermission(Permission permission) {
-		// System.out.println("Checking permission " + permission);
-		if (permission.getName().contains("exitVM")) {
-			throw new IllegalStateException("System.exit call not allowed");
-		}
-	}
-}
Index: src/main/java/geniusweb/partiesserver/jarClassLoader1.java
===================================================================
--- src/main/java/geniusweb/partiesserver/jarClassLoader1.java	(revision 46)
+++ src/main/java/geniusweb/partiesserver/jarClassLoader1.java	(revision 1)
@@ -4,6 +4,4 @@
 import java.io.IOException;
 import java.net.JarURLConnection;
-import java.net.MalformedURLException;
-import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLClassLoader;
@@ -12,5 +10,5 @@
 /**
  * Classloader that ensures loaded code is kept separate from other loaded code.
- * This is to prevent dependency conflicts between parties that we load.
+ * This is to prevent dependency conflicts between parties that we  load.
  *
  */
@@ -19,30 +17,20 @@
 	private URL u;
 
-	/**
-	 * @param url    The URL is like
-	 *               jar:file:/Web%20Servers/../partiesserver-1.4.1/partiesrepo/agentgg-1.5.5.jar!/
-	 * 
-	 * @param parent the parent classloader.
-	 */
 	public JarClassLoader1(URL url, ClassLoader parent) {
 		super(new URL[] { url }, parent);
 		this.u = url;
 
-		// we need to get to the actual file. This is very tricky,
-		// most solutions on the web don't work, throw, don't remove %20,etc
-		// url.toURI throws for multi-protocol URLs like "jar:file://...".
+		String filename = url.getPath();
+		if (filename.startsWith("file:")) {
+			filename = filename.substring(5);
+		}
+		if (filename.endsWith("/")) {
+			filename = filename.substring(0, filename.length() - 1);
+		}
+		if (filename.endsWith("!")) {
+			filename = filename.substring(0, filename.length() - 1);
+		}
 
-		// https://docs.oracle.com/javase/7/docs/api/java/net/JarURLConnection.html
-		// the syntax of a JAR URL is: jar:<url>!/{entry}
-
-		String filename = url.getPath(); // file:/bla%20bla/file.jar!/
-		filename = filename.substring(0, filename.indexOf("!/"));
-		File jarfile;
-		try {
-			jarfile = new File(new URL(filename).toURI());
-		} catch (MalformedURLException | URISyntaxException e) {
-			throw new IllegalArgumentException(
-					"file " + filename + " seems malformed", e);
-		}
+		File jarfile = new File(filename);
 
 		if (jarfile == null || !jarfile.exists()) {
Index: src/main/java/geniusweb/partiesserver/repository/AvailableJavaParty.java
===================================================================
--- src/main/java/geniusweb/partiesserver/repository/AvailableJavaParty.java	(revision 46)
+++ 	(revision )
@@ -1,124 +1,0 @@
-package geniusweb.partiesserver.repository;
-
-import geniusweb.actions.PartyId;
-import geniusweb.party.Capabilities;
-import geniusweb.party.Party;
-
-/**
- * An approved and ready to run party.
- */
-public class AvailableJavaParty implements AvailableParty {
-
-	private final Class<? extends Party> partyclass;
-	private final String name;
-	private final transient Capabilities capabilities;
-	private final transient String description;
-
-	/**
-	 * 
-	 * @param name       the filename. This is not a {@link PartyId}.
-	 * @param partyclass the class of the party.
-	 * @throws ClassNotFoundException if unknown partyclass
-	 */
-	public AvailableJavaParty(String name, Class<? extends Party> partyclass)
-			throws ClassNotFoundException {
-		this.name = name;
-		this.partyclass = partyclass;
-
-		Party party;
-		try {
-			party = partyclass.newInstance();
-		} catch (Throwable e) {
-			throw new ClassNotFoundException(
-					"Could not instantiate " + partyclass, e);
-		}
-		capabilities = party.getCapabilities();
-		description = party.getDescription();
-
-	}
-
-	@Override
-	public String getID() {
-		return name;
-	}
-
-	@Override
-	public String getName() {
-		return name;
-	}
-
-	/**
-	 * 
-	 * @return cached copy of what was received from a call to
-	 *         {@link Party#getDescription()}.
-	 */
-	@Override
-	public String getDescription() {
-		return description;
-	}
-
-	/**
-	 * 
-	 * @return cached copy of what was received from a call to
-	 *         {@link AvailableParty#getCapabilities()}
-	 */
-	@Override
-	public Capabilities getCapabilities() {
-		return capabilities;
-	}
-
-	@Override
-	public Party getInstance() throws InstantiationFailedException {
-		try {
-			return partyclass.newInstance();
-		} catch (Exception e) {
-			throw new InstantiationFailedException(
-					"Failed to create instance of party " + this, e);
-		}
-	}
-
-	@Override
-	public void free() {
-		// FAIK we can not unload the class or free resources.
-		// it would be done automatically if our classloader
-		// is garbage collected.
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + ((name == null) ? 0 : name.hashCode());
-		result = prime * result
-				+ ((partyclass == null) ? 0 : partyclass.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		AvailableJavaParty other = (AvailableJavaParty) obj;
-		if (name == null) {
-			if (other.name != null)
-				return false;
-		} else if (!name.equals(other.name))
-			return false;
-		if (partyclass == null) {
-			if (other.partyclass != null)
-				return false;
-		} else if (!partyclass.equals(other.partyclass))
-			return false;
-		return true;
-	}
-
-	@Override
-	public String toString() {
-		return name + " (" + partyclass + ")";
-	}
-
-}
Index: src/main/java/geniusweb/partiesserver/repository/AvailablePartiesRepo.java
===================================================================
--- src/main/java/geniusweb/partiesserver/repository/AvailablePartiesRepo.java	(revision 46)
+++ src/main/java/geniusweb/partiesserver/repository/AvailablePartiesRepo.java	(revision 1)
@@ -12,6 +12,5 @@
  * Stores all currently available parties that can be run.
  */
-public class AvailablePartiesRepo extends DefaultListenable<String>
-		implements Repository<String, AvailableParty> {
+public class AvailablePartiesRepo extends DefaultListenable<String> implements Repository<String, AvailableParty> {
 	private static final AvailablePartiesRepo instance = new AvailablePartiesRepo();
 
@@ -38,15 +37,11 @@
 	public void put(AvailableParty entity) {
 		availableParties.put(entity.getID(), entity);
-		notifyListeners(entity.getID());
+		notifyChange(entity.getID());
 	}
 
 	@Override
 	public void remove(String id) {
-		AvailableParty available = availableParties.get(id);
-		if (available != null) {
-			availableParties.remove(id);
-			available.free();
-			notifyListeners(id);
-		}
+		availableParties.remove(id);
+		notifyChange(id);
 	}
 
Index: src/main/java/geniusweb/partiesserver/repository/AvailableParty.java
===================================================================
--- src/main/java/geniusweb/partiesserver/repository/AvailableParty.java	(revision 46)
+++ src/main/java/geniusweb/partiesserver/repository/AvailableParty.java	(revision 1)
@@ -1,19 +1,52 @@
 package geniusweb.partiesserver.repository;
 
+import geniusweb.actions.PartyId;
 import geniusweb.party.Capabilities;
 import geniusweb.party.Party;
 import tudelft.utilities.repository.RepoElement;
 
-/**
- * An interface to an approved and ready to run party. To make a party
- * available, resources may have to be allocated.
- */
-public interface AvailableParty extends RepoElement<String> {
+public class AvailableParty implements RepoElement<String> {
+
+	private final Class<? extends Party> partyclass;
+	private final String name;
+	private final transient Capabilities capabilities;
+	private final transient String description;
 
 	/**
 	 * 
-	 * @return the (file) name of the available party
+	 * @param name       the filename. This is not a {@link PartyId}.
+	 * @param partyclass the class of the party.
+	 * @throws IllegalAccessException
+	 * @throws InstantiationException
 	 */
-	String getName();
+	public AvailableParty(String name, Class<? extends Party> partyclass)
+			throws ClassNotFoundException {
+		this.name = name;
+		this.partyclass = partyclass;
+
+		Party party;
+		try {
+			party = partyclass.newInstance();
+		} catch (Throwable e) {
+			throw new ClassNotFoundException(
+					"Could not instantiate " + partyclass, e);
+		}
+		capabilities = party.getCapabilities();
+		description = party.getDescription();
+
+	}
+
+	@Override
+	public String getID() {
+		return name;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public Class<? extends Party> getPartyClass() {
+		return partyclass;
+	}
 
 	/**
@@ -22,5 +55,7 @@
 	 *         {@link Party#getDescription()}.
 	 */
-	String getDescription();
+	public String getDescription() {
+		return description;
+	}
 
 	/**
@@ -29,23 +64,44 @@
 	 *         {@link AvailableParty#getCapabilities()}
 	 */
-	Capabilities getCapabilities();
+	public Capabilities getCapabilities() {
+		return capabilities;
+	}
 
-	/**
-	 * 
-	 * @return a link to a Party. Notice, Party may be a intermediary,
-	 *         redirecting data through remote objects
-	 * @throws InstantiationFailedException if party can not be instantiated
-	 *                                      (this should normally not happen,
-	 *                                      since we test thoroughly before a
-	 *                                      party is announced Available, but
-	 *                                      there might be special cases eg out
-	 *                                      of memory)
-	 */
-	Party getInstance() throws InstantiationFailedException;
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		result = prime * result
+				+ ((partyclass == null) ? 0 : partyclass.hashCode());
+		return result;
+	}
 
-	/**
-	 * Free resources associated with this . After this call, the AvailableParty
-	 * becomes invalid and should be disposed.
-	 */
-	void free();
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		AvailableParty other = (AvailableParty) obj;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		if (partyclass == null) {
+			if (other.partyclass != null)
+				return false;
+		} else if (!partyclass.equals(other.partyclass))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return name + " (" + partyclass + ")";
+	}
+
 }
Index: src/main/java/geniusweb/partiesserver/repository/InstantiationFailedException.java
===================================================================
--- src/main/java/geniusweb/partiesserver/repository/InstantiationFailedException.java	(revision 46)
+++ 	(revision )
@@ -1,15 +1,0 @@
-package geniusweb.partiesserver.repository;
-
-/**
- * 
- * Thrown if party can not be instantiated. This should normally not happen,
- * since we test thoroughly before a party is announced Available, but there
- * might be special cases eg out of memory *
- */
-public class InstantiationFailedException extends Exception {
-	private static final long serialVersionUID = -8971815685377471348L;
-
-	public InstantiationFailedException(String msg, Throwable e) {
-		super(msg, e);
-	}
-}
Index: src/main/java/geniusweb/partiesserver/repository/RunningPartiesRepo.java
===================================================================
--- src/main/java/geniusweb/partiesserver/repository/RunningPartiesRepo.java	(revision 46)
+++ src/main/java/geniusweb/partiesserver/repository/RunningPartiesRepo.java	(revision 1)
@@ -24,5 +24,5 @@
 	 * List of currently running parties.
 	 */
-	public static final int MAX_SLOTS = 16;
+	public static final int MAX_SLOTS = 4;
 	private static final RunningPartiesRepo instance = new RunningPartiesRepo(
 			new ReportToLogger("partiesserver"));
@@ -67,5 +67,4 @@
 			if (availableSlots() <= 0) {
 				Date date = estimateCleanupTime();
-				System.out.println("AAGHG!!" + runningParties.size());
 				throw new NoResourcesNowException(
 						"There are currently no free slots to register party "
@@ -75,5 +74,5 @@
 			runningParties.put(id, newParty);
 		}
-		notifyListeners(id);
+		notifyChange(id);
 	}
 
@@ -88,5 +87,5 @@
 			runningParties.put(id, newParty);
 		}
-		notifyListeners(id);
+		notifyChange(id);
 
 	}
@@ -126,5 +125,5 @@
 			}
 		}
-		notifyListeners(id);
+		notifyChange(id);
 	}
 
Index: src/main/java/geniusweb/partiesserver/repository/RunningParty.java
===================================================================
--- src/main/java/geniusweb/partiesserver/repository/RunningParty.java	(revision 46)
+++ src/main/java/geniusweb/partiesserver/repository/RunningParty.java	(revision 1)
@@ -9,15 +9,14 @@
 import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
 
+import geniusweb.actions.Action;
 import geniusweb.actions.PartyId;
-import geniusweb.inform.Inform;
-import geniusweb.partiesserver.RunningPartiesUpdater;
-import geniusweb.partiesserver.websocket.PartySocket;
+import geniusweb.connection.DefaultConnection;
 import geniusweb.party.Party;
+import geniusweb.party.inform.Inform;
 import tudelft.utilities.repository.RepoElement;
 
 /**
- * Contains a running party and additional info about it like time constraints
- * and connections. Adds a start/end times and generates party ID. Also stores
- * original filename of the party.
+ * Class that contains a running party. Adds a start/end times and generates
+ * party ID. Also stores original filename of the party.
  * 
  * This object can not be deserialized here because running parties have to be
@@ -40,5 +39,5 @@
 	 * set when someone contacts our socket. null if not set.
 	 */
-	private final transient PartySocket connection;
+	private final transient DefaultConnection<Inform, Action> connection;
 
 	/**
@@ -52,5 +51,4 @@
 	 * @param party the new party
 	 * @param id    the new id for the party.
-	 * @param name  the name, this should match the filename
 	 * @param start the start date for this party. Usually set to current time.
 	 * @param end   the end date for this party
@@ -59,5 +57,5 @@
 	 */
 	protected RunningParty(Party party, PartyId id, String name, Date start,
-			Date end, PartySocket conn) {
+			Date end, DefaultConnection conn) {
 		if (party == null || id == null || name == null || start == null
 				|| end == null) {
@@ -73,5 +71,8 @@
 
 	/**
+	 * Create instance from availableparty
+	 * 
 	 * @param availableparty the {@link AvailableParty}
+	 * @param name           the (file)name
 	 * @param maxlifetimems  the maximum life time for this party (ms). The
 	 *                       party will be killed and removed after this point.
@@ -79,16 +80,16 @@
 	 *                       time plus the worst time to actual start up of the
 	 *                       negotiation
-	 * @return a new RunningParty being an instance of availableparty
-	 * @throws InstantiationFailedException if class can not be instantiated
-	 * 
+	 * @throws IllegalAccessException
+	 * @throws InstantiationException
 	 */
 	public static RunningParty create(AvailableParty availableparty,
-			long maxlifetimems) throws InstantiationFailedException {
+			long maxlifetimems)
+			throws InstantiationException, IllegalAccessException {
 		if (availableparty == null) {
 			throw new IllegalArgumentException(
 					"availableparty must not be null");
 		}
-		return create(availableparty.getInstance(), availableparty.getName(),
-				maxlifetimems);
+		return create(availableparty.getPartyClass().newInstance(),
+				availableparty.getName(), maxlifetimems);
 	}
 
@@ -99,11 +100,7 @@
 	 * @param name         The name, this should match the filename in the repo
 	 *                     (without the .jar).
-	 * @param maxRunTimeMS the maximum runtime for this party (ms). The
-	 *                     {@link RunningPartiesUpdater} will keep an eye on the
-	 *                     time and handle removal after time is up.
-	 * @return new RunningParty created from the Party instance.
-	 * 
-	 */
-	private static RunningParty create(Party party, String name,
+	 * @param maxRunTimeMS the maximum runtime for this party (ms)
+	 */
+	public static RunningParty create(Party party, String name,
 			long maxRunTimeMS) {
 		if (maxRunTimeMS <= 0) {
@@ -112,6 +109,6 @@
 		Date now = new Date();
 		return new RunningParty(party,
-				new PartyId(squash1(name) + "_" + uniqueid + "_" + (nr++)),
-				name, now, new Date(now.getTime() + maxRunTimeMS), null);
+				new PartyId("party" + (nr++) + "_" + uniqueid), name, now,
+				new Date(now.getTime() + maxRunTimeMS), null);
 	}
 
@@ -132,7 +129,7 @@
 
 	/**
-	 * @return The name, this should match the filename in the repo (without the
-	 *         .jar).
-	 * 
+	 * The name, this should match the filename in the repo (without the .jar).
+	 * 
+	 * @return
 	 */
 	public String getName() {
@@ -206,11 +203,11 @@
 
 	/**
-	 * Pass {@link Inform} into the running party. You must have called
-	 * {@link #withConnection(PartySocket)} before calling this.
-	 * 
-	 * @param info the {@link Inform} to be sent to the {@link #connection}
+	 * You must have called {@link #connect(DefaultConnection)} before calling
+	 * this.
+	 * 
+	 * @param info
 	 */
 	public void inform(Inform info) {
-		connection.notifyListeners(info);
+		connection.notifyChange(info);
 	}
 
@@ -223,5 +220,6 @@
 	 * @throws IllegalStateException if the party is already connected.
 	 */
-	public RunningParty withConnection(PartySocket newconn) {
+	public RunningParty withConnection(
+			DefaultConnection<Inform, Action> newconn) {
 		if (newconn == null)
 			throw new NullPointerException("newconn must be not null");
@@ -258,30 +256,8 @@
 															// never be needed
 			}
-			uniqueid = squash(uniqueid);
+			uniqueid = uniqueid.replaceAll("\\.", "_");
 		}
 		return uniqueid;
 	}
 
-	/**
-	 * 
-	 * @param string
-	 * @return string with all non-word characters replaced with "_" so that the
-	 *         result is a "word" ( [a-zA-Z_0-9] ).
-	 */
-	protected static String squash(String string) {
-		return string.replaceAll("\\W", "_");
-	}
-
-	/**
-	 * @param string
-	 * @return as squash, but additionally if the name does not start with a
-	 *         letter we prefix the string with 'p'
-	 */
-	protected static String squash1(String string) {
-		String res = squash(string);
-		if (res.matches("[a-zA-Z]\\w*"))
-			return res;
-		return "p" + res;
-	}
-
 }
Index: src/main/java/geniusweb/partiesserver/websocket/ActiveThreads.java
===================================================================
--- src/main/java/geniusweb/partiesserver/websocket/ActiveThreads.java	(revision 46)
+++ 	(revision )
@@ -1,71 +1,0 @@
-package geniusweb.partiesserver.websocket;
-
-import java.util.LinkedList;
-import java.util.List;
-import java.util.logging.Level;
-
-import tudelft.utilities.logging.Reporter;
-
-/**
- * Keeps track of threads active for a PartySocket. Needed so that we can kill
- * all relevant threads when it comes to forced termination.
- */
-public class ActiveThreads {
-	private final List<Thread> threads = new LinkedList<>();
-	private final Reporter log;
-
-	public ActiveThreads(Reporter log) {
-		this.log = log;
-	}
-
-	/**
-	 * Add the current thread as active thread
-	 */
-	public synchronized void add() {
-		threads.add(Thread.currentThread());
-	}
-
-	/**
-	 * Remove the current thread as active thread. To be called when thread
-	 * finished nicely.
-	 */
-	public synchronized void remove() {
-		threads.remove(Thread.currentThread());
-
-	}
-
-	/**
-	 * 
-	 * @return true if no threads currently running.
-	 */
-	public synchronized boolean isEmpty() {
-		return threads.isEmpty();
-	}
-
-	@SuppressWarnings("deprecation")
-	public synchronized void killall() {
-
-		/*
-		 * The method stop(Throwable) does not work anymore. we need to call
-		 * stop() which will result in nonsense stacktrace pointing to US
-		 * instead of the real problem. Only solution is to print stacktrace
-		 * ourselves.
-		 */
-		for (Thread thread : threads) {
-			String stacktrace = "";
-			for (StackTraceElement element : thread.getStackTrace()) {
-				stacktrace += "\t" + element.toString() + "\n";
-			}
-
-			/* the most powerful kill, deprecated but required here. */
-			try {
-				thread.stop();
-				log.log(Level.INFO,
-						"Killed thread with stack trace\n" + stacktrace);
-			} catch (ThreadDeath e) {
-				log.log(Level.INFO, "Noticed thread already was stopped.");
-			}
-		}
-		threads.clear();
-	}
-}
Index: src/main/java/geniusweb/partiesserver/websocket/PartiesListSocket.java
===================================================================
--- src/main/java/geniusweb/partiesserver/websocket/PartiesListSocket.java	(revision 46)
+++ src/main/java/geniusweb/partiesserver/websocket/PartiesListSocket.java	(revision 1)
@@ -2,4 +2,6 @@
 
 import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.net.InetAddress;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -7,7 +9,11 @@
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Set;
 import java.util.logging.Level;
 
+import javax.management.MBeanServer;
 import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.Query;
 import javax.websocket.OnClose;
 import javax.websocket.OnError;
@@ -16,5 +22,6 @@
 import javax.websocket.server.ServerEndpoint;
 
-import geniusweb.partiesserver.Constants;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
 import geniusweb.partiesserver.repository.AvailablePartiesRepo;
 import geniusweb.partiesserver.repository.AvailableParty;
@@ -45,6 +52,4 @@
 
 	public PartiesListSocket(Reporter reporter) {
-		if (reporter == null)
-			throw new IllegalArgumentException("reporter must be not null");
 		this.log = reporter;
 	}
@@ -73,8 +78,8 @@
 	 */
 	private void sendUpdatedParties() {
-		log.log(Level.INFO, "sending updated parties list1");
+		System.out.println("sending updated parties list1");
 		String ip = DEFAULT_ADDRESS; // default if something fails
 		try {
-			ip = Constants.getIpAddressAndPort() + "/" + getServerName();
+			ip = getIpAddressAndPort() + "/" + getServerName();
 		} catch (MalformedObjectNameException | UnknownHostException e1) {
 			log.log(Level.SEVERE,
@@ -90,5 +95,5 @@
 						party.getDescription()));
 			}
-			String text = Constants.getJackson().writeValueAsString(list);
+			String text = new ObjectMapper().writeValueAsString(list);
 			outstream.send(text);
 		} catch (IOException | URISyntaxException e) {
@@ -133,5 +138,19 @@
 	}
 
+	private String getIpAddressAndPort()
+			throws UnknownHostException, MalformedObjectNameException {
 
+		MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
+
+		Set<ObjectName> objectNames = beanServer.queryNames(
+				new ObjectName("*:type=Connector,*"),
+				Query.match(Query.attr("protocol"), Query.value("HTTP/1.1")));
+
+		String host = InetAddress.getLocalHost().getHostAddress();
+		String port = objectNames.iterator().next().getKeyProperty("port");
+
+		return host + ":" + port;
+
+	}
 
 }
Index: src/main/java/geniusweb/partiesserver/websocket/PartySocket.java
===================================================================
--- src/main/java/geniusweb/partiesserver/websocket/PartySocket.java	(revision 46)
+++ src/main/java/geniusweb/partiesserver/websocket/PartySocket.java	(revision 1)
@@ -5,6 +5,4 @@
 import java.net.URI;
 import java.util.Date;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.logging.Level;
 
@@ -19,13 +17,17 @@
 import javax.websocket.server.ServerEndpoint;
 
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
 import geniusweb.actions.Action;
 import geniusweb.actions.PartyId;
-import geniusweb.connection.ConnectionEnd;
-import geniusweb.inform.Inform;
-import geniusweb.inform.Settings;
-import geniusweb.partiesserver.Constants;
+import geniusweb.connection.DefaultConnection;
 import geniusweb.partiesserver.repository.RunningPartiesRepo;
 import geniusweb.partiesserver.repository.RunningParty;
 import geniusweb.party.Party;
+import geniusweb.party.inform.Finished;
+import geniusweb.party.inform.Inform;
+import geniusweb.party.inform.Settings;
 import geniusweb.references.Reference;
 import tudelft.utilities.listener.Listener;
@@ -34,17 +36,13 @@
 
 /**
- * Returns a websocket that communicates with the {@link RunningParty}. The
- * websocket is initiated/called/requested by an external party, typicall hte
- * protocol running on another server. We close the socket when we detect the
- * party is gone (eg, due to a bug in the party or a time-out). If the socket
- * breaks, we close the party as it becomes isolated.
+ * Returns a websocket that communicates with the {@link RunningParty}. We close
+ * the socket when we detect the party is gone (eg, due to a bug in the party or
+ * a time-out). If the socket breaks, we close the party as it becomes isolated.
  */
 @ServerEndpoint("/party/{party}")
-public class PartySocket implements ConnectionEnd<Inform, Action> {
-
+public class PartySocket extends DefaultConnection<Inform, Action> {
+	private final static ObjectMapper jackson = new ObjectMapper();
 	private final Reporter log;
 	private final RunningPartiesRepo runningparties;
-	private final List<Listener<Inform>> listeners = new CopyOnWriteArrayList<Listener<Inform>>();
-	private final ActiveThreads threads;
 
 	// should all be final, except that we can only set them when start is
@@ -57,6 +55,4 @@
 	private Throwable error = null;
 
-	private StringBuffer buffer = new StringBuffer();
-
 	public PartySocket() {
 		this(RunningPartiesRepo.instance(),
@@ -67,5 +63,4 @@
 		this.runningparties = parties;
 		this.log = reporter;
-		this.threads = new ActiveThreads(log);
 	}
 
@@ -76,5 +71,4 @@
 			throw new IllegalArgumentException("party can't be null");
 		}
-
 		this.session = session;
 		this.partyID = new PartyId(partyidname);
@@ -92,5 +86,5 @@
 						runningparties.removeListener(this);
 						session.close(new CloseReason(CloseCodes.GOING_AWAY,
-								"detected that party vanished"));
+								"party died"));
 					} catch (IOException e) {
 						log.log(Level.WARNING,
@@ -120,80 +114,24 @@
 	 * @param informmessage the incoming string, supposedly a JSON-fornatted
 	 *                      {@link Inform}
-	 * @param last          true if this is the last part of the incoming
-	 *                      message. We queue these manually here, to avoid
-	 *                      pre-allocating a fixed, very large memory block.
 	 * @param session       the session. We already have this info.
-	 * @throws IOException if there is a socket/connection error, we can't parse
-	 *                     the received data, etc
 	 */
 	@OnMessage
-	public void onMessage(String informpart, boolean islast, Session session)
-			throws IOException {
+	public void onMessage(String informmessage, Session session)
+			throws JsonParseException, JsonMappingException, IOException {
 		if (this.session != session) {
 			throw new IllegalStateException("Unexpected change of session ID");
 		}
-		if (!threads.isEmpty()) {
-			log.log(Level.WARNING, "Party " + partyID
-					+ " is still busy with previous message");
-		}
-		buffer.append(informpart);
-		if (!islast)
-			return;
-
-		String informmessage = buffer.toString();
-		buffer = new StringBuffer();
-
-		// if we get here, full message is now in
-
-		Inform info = Constants.getJackson().readValue(informmessage, Inform.class);
+		Inform info = jackson.readValue(informmessage, Inform.class);
 		RunningParty party = runningparties.get(partyID);
 		if (party != null) {
-			// first sniff, to ensure the deadlines are updated first.
-			sniff(info, party);
 			log.log(Level.FINE, "Inform " + partyID + ": " + info);
 			try {
-				threads.add();
 				party.inform(info);
-				threads.remove();
 			} catch (Throwable e) {
-				threads.remove();
-				if (e instanceof ThreadDeath)
-					/*
-					 * ThreadDeath always prints stacktrace anwyay, stacktrace
-					 * is useless because it contains the thrower's stacktrace
-					 * instead of a useful message.
-					 */
-					log.log(Level.WARNING,
-							"Party was killed while handling inform.");
-				else
-					log.log(Level.WARNING, "Party failed on inform.", e);
-				/*
-				 * severe as someone wants to debug that. Not severe for us we
-				 * don't use jackson.writeValueAsString(e) here because
-				 * CloseReason has 123 char limit. The error will be too large
-				 * to fit and will be truncated therefore we send a plain string
-				 * and hope that enough will arrive at the other side (the
-				 * protocol)
-				 */
-				session.close(new CloseReason(
-						CloseReason.CloseCodes.CLOSED_ABNORMALLY,
-						"party threw exception: " + collectReasons(e)));
+				// simple sandbox
+				log.log(Level.WARNING, "Party failed on inform:", e);
 			}
-		} // else party is dead but that's handled in the listener above
-	}
-
-	/**
-	 * 
-	 * @param e an exception
-	 * @return collect all reasons and sub-reasons
-	 */
-	private String collectReasons(Throwable e) {
-		String reason = "";
-		do {
-			reason = reason + " : " + e.getClass().getSimpleName() + ":"
-					+ e.getMessage();
-			e = e.getCause();
-		} while (e != null);
-		return reason;
+			sniff(info, party);
+		} // else dead but that's handled in the listener above
 	}
 
@@ -206,7 +144,8 @@
 	 */
 	private void sniff(Inform info, RunningParty party) throws IOException {
-		// do NOT sniff Finished messages and close sockets. Parties and their
-		// sockets need to stay running till all messages are handled
-		if (info instanceof Settings) {
+		if (info instanceof Finished) {
+			session.close(new CloseReason(CloseCodes.GOING_AWAY,
+					"session reached agreement"));
+		} else if (info instanceof Settings) {
 			Date end = ((Settings) info).getProgress().getTerminationTime();
 			runningparties.replace(party.withEndTime(end));
@@ -217,9 +156,8 @@
 	public void onClose() throws IOException {
 		log.log(Level.INFO, "socket closed to " + partyID);
-		if (!threads.isEmpty()) {
-			log.log(Level.WARNING, "Party " + partyID
-					+ " failed to terminate. Trying to kill the remaining threads.");
-			threads.killall();
-		}
+		/*
+		 * for now just kill the party. Maybe we can do something with reconnect
+		 * but that will be complex.
+		 */
 		runningparties.remove(partyID);
 		outstream.stop();
@@ -230,5 +168,6 @@
 		if (t instanceof EOFException) {
 			// This is a standard exception from Apache when a socket closes.
-			// Just ignore it...
+			// Just ignore
+			// it...
 			log.log(Level.FINEST,
 					"apache reported EOF from (probably closed) socket, ignoring");
@@ -240,12 +179,6 @@
 	@Override
 	public void send(Action action) throws IOException {
-		if (action == null) {
-			log.log(Level.INFO, "null action received. Closing websocket");
-			// signals that party closed the stream
-			close();
-			return;
-		}
 		log.log(Level.FINE, "Action " + partyID + ": " + action);
-		outstream.send(Constants.getJackson().writeValueAsString(action));
+		outstream.send(jackson.writeValueAsString(action));
 	}
 
@@ -275,29 +208,3 @@
 	}
 
-	@Override
-	public void addListener(Listener<Inform> l) {
-		listeners.add(l);
-	}
-
-	@Override
-	public void removeListener(Listener<Inform> l) {
-		listeners.remove(l);
-	}
-
-	/**
-	 * This should only be called by the owner of the listenable, not by
-	 * listeners or others. Avoid calling this from synchronized blocks as a
-	 * notified listener might immediately make more calls to you.
-	 * <p>
-	 * Any listeners that throw an exception will be intercepted and their
-	 * stacktrace is printed.
-	 * 
-	 * @param data information about the change.
-	 */
-	public void notifyListeners(Inform data) {
-		for (Listener<Inform> l : listeners) {
-			l.notifyChange(data);
-		}
-	}
-
 }
Index: src/main/java/geniusweb/partiesserver/websocket/RunningListSocket.java
===================================================================
--- src/main/java/geniusweb/partiesserver/websocket/RunningListSocket.java	(revision 46)
+++ src/main/java/geniusweb/partiesserver/websocket/RunningListSocket.java	(revision 1)
@@ -13,6 +13,7 @@
 import javax.websocket.server.ServerEndpoint;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
+
 import geniusweb.actions.PartyId;
-import geniusweb.partiesserver.Constants;
 import geniusweb.partiesserver.repository.RunningPartiesRepo;
 import geniusweb.partiesserver.repository.RunningPartyInfo;
@@ -70,5 +71,5 @@
 		log.log(Level.FINE, "sending updated running parties list " + list);
 		try {
-			outstream.send(Constants.getJackson().writeValueAsString(repo.list()));
+			outstream.send(new ObjectMapper().writeValueAsString(repo.list()));
 		} catch (IOException e) {
 			log.log(Level.SEVERE, "Internal problem converting json", e);
Index: src/main/java/geniusweb/partiesserver/websocket/SendBuffer.java
===================================================================
--- src/main/java/geniusweb/partiesserver/websocket/SendBuffer.java	(revision 46)
+++ src/main/java/geniusweb/partiesserver/websocket/SendBuffer.java	(revision 1)
@@ -21,10 +21,6 @@
 
 	private final Basic remote;
-	/**
-	 * Buffer contains jackson-serialized objects, so can be "null" or "" but
-	 * not null. "" (empty string) indicates buffer should be closed and
-	 * terminated.
-	 */
 	private final LinkedBlockingQueue<String> fifo = new LinkedBlockingQueue<String>();
+	private final Thread thread;
 	private final Reporter log;
 
@@ -32,15 +28,11 @@
 		this.remote = basicRemote;
 		this.log = logger;
-		Thread thread = new Thread(new Runnable() {
+		thread = new Thread(new Runnable() {
 
 			@Override
 			public void run() {
-				String txt = "-";
 				try {
 					while (true) {
-						txt = fifo.take();
-						if (txt.isEmpty())
-							break;
-						remote.sendText(txt);
+						remote.sendText(fifo.take());
 					}
 				} catch (InterruptedException e) {
@@ -49,24 +41,12 @@
 							"sendbuffer is interrupted, assuming the party died.");
 				} catch (Exception e) {
-					logger.log(Level.SEVERE,
-							"Failed to write '" + txt + "' to stream", e);
+					logger.log(Level.SEVERE, "Failed to write to stream", e);
 				}
-				log.log(Level.INFO, "SendBuffer is closed.");
 			}
-		}, "SendBuffer");
+		});
 		thread.start();
 	}
 
-	/**
-	 * 
-	 * @param text (non-emptyy) text to be sent. Typically a jackson-serialized
-	 *             string.
-	 */
 	public void send(String text) {
-		if (fifo.contains(""))
-			return;
-		if (text == null || text.isEmpty())
-			throw new IllegalArgumentException(
-					"Text must not be null or empty");
 		try {
 			fifo.put(text);
@@ -81,12 +61,22 @@
 	 * Stop the que, disable, terminate threads
 	 */
-	public synchronized void stop() {
-		if (!fifo.contains(""))
+	public void stop() {
+		if (!fifo.isEmpty()) {
 			try {
-				fifo.put("");
+				log.log(Level.FINE, "Allowing short time to send remaining "
+						+ fifo.size() + "messages");
+				thread.sleep(1000);
 			} catch (InterruptedException e) {
-				log.log(Level.WARNING,
-						"Queue termination was interrupted, unsure about thread state");
+				log.log(Level.FINE,
+						"Waiting was interrupted, final messages have been deleted");
 			}
+		}
+		thread.interrupt();
+		try {
+			thread.join(400);
+		} catch (InterruptedException e) {
+			log.log(Level.WARNING,
+					"thread termination was interrupted, unsure about thread state");
+		}
 	}
 
