Index: events/src/main/java/geniusweb/actions/Action.java
===================================================================
--- events/src/main/java/geniusweb/actions/Action.java	(revision 30)
+++ events/src/main/java/geniusweb/actions/Action.java	(revision 31)
@@ -20,5 +20,6 @@
 		@JsonSubTypes.Type(value = Votes.class),
 		@JsonSubTypes.Type(value = VoteWithValue.class),
-		@JsonSubTypes.Type(value = VotesWithValue.class) })
+		@JsonSubTypes.Type(value = VotesWithValue.class),
+		@JsonSubTypes.Type(value = LearningDone.class) })
 public interface Action {
 	/**
Index: events/src/main/java/geniusweb/actions/FileLocation.java
===================================================================
--- events/src/main/java/geniusweb/actions/FileLocation.java	(revision 31)
+++ events/src/main/java/geniusweb/actions/FileLocation.java	(revision 31)
@@ -0,0 +1,101 @@
+package geniusweb.actions;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.UUID;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+/**
+ * This contains a "system independent" {@link File}. This is represented by a
+ * {@link UUID}. The file may or may not yet exist (depending on whether your
+ * party already wrote some contents in that file in previous runs), may or may
+ * not be empty (your choice), and can contain any type of data. The original
+ * intent of this is that parties can store learned data in this file, while the
+ * name can be kept for later re-use in later runs (eg negotiation sessions) on
+ * the same machine.
+ * <p>
+ * This file is to be used locally on some other machine (typically a
+ * partiesserver). This object itself only contains a file name.
+ * {@link #getFile()} turns it into a system-specific {@link File}. <br>
+ * <h2>WARNING</h2> if used multiple times on different machines, multiple,
+ * separate files will be involved, there is no magical synchronization of
+ * multiple items with the same UUID used on different machines.
+ */
+public class FileLocation {
+
+	@JsonValue
+	private final UUID name;
+
+	private final static String TMP = System.getProperty("java.io.tmpdir");
+	private final static String GENIUSWEB = "geniusweb";
+	private final static Path rootpath = Paths.get(TMP, GENIUSWEB);
+	private final static File rootfolder = rootpath.toFile();
+
+	/**
+	 * @param name the name of the file (must be UUID to prevent injection of
+	 *             bad filenames like /.. or C:) Use {@link #FileLocation()} to
+	 *             create new FileLocation. That should ensure a new UUID that
+	 *             does not collide with existing ones.
+	 */
+	@JsonCreator
+	public FileLocation(UUID name) {
+		this.name = name;
+	}
+
+	/**
+	 * Default constructor creates a new "random" FileLocation.
+	 */
+	public FileLocation() {
+		if (!rootfolder.exists()) {
+			rootfolder.mkdir();
+			System.out
+					.println("created FileLocation root dir at " + rootfolder);
+		}
+		this.name = UUID.randomUUID();
+	}
+
+	/**
+	 * 
+	 * @return the UUID string
+	 */
+	public String getUUIDString() {
+		return name.toString();
+	}
+
+	public File getFile() {
+		return Paths.get(TMP, GENIUSWEB, name.toString()).toFile();
+	}
+
+	@Override
+	public String toString() {
+		return "FileLocation[" + name + "]";
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((name == null) ? 0 : name.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;
+		FileLocation other = (FileLocation) obj;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		return true;
+	}
+}
Index: events/src/main/java/geniusweb/actions/LearningDone.java
===================================================================
--- events/src/main/java/geniusweb/actions/LearningDone.java	(revision 31)
+++ events/src/main/java/geniusweb/actions/LearningDone.java	(revision 31)
@@ -0,0 +1,20 @@
+package geniusweb.actions;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Indicates that a party turns away from the negotiation and.
+ *
+ */
+public class LearningDone extends AbstractAction {
+	@JsonCreator
+	public LearningDone(@JsonProperty("actor") PartyId id) {
+		super(id);
+	}
+
+	@Override
+	public String toString() {
+		return "LearningDone[" + getActor() + "]";
+	}
+}
Index: events/src/main/java/geniusweb/actions/PartyId.java
===================================================================
--- events/src/main/java/geniusweb/actions/PartyId.java	(revision 30)
+++ events/src/main/java/geniusweb/actions/PartyId.java	(revision 31)
@@ -4,9 +4,12 @@
 
 /**
- * Globally (that is, worldwide) unique ID of a party in a negotiation.
- * Normally, negotiation parties should not create new Party IDs as all needed
- * IDs should be provided by the protocol. Serializes only as part of a bigger
- * object. This ID may contain parts of an ip address but that address should
- * not be used to make contact.
+ * Unique ID of a party in a negotiation. The name should start with a short
+ * string indicating the party (eg, the party name plus some machine
+ * identifier), optionally followed by an "_", and more characters to make the
+ * partyid unique. We require the name and "-" so that the string up to the
+ * first "-" can be used to determine between sessions which opponents are
+ * instances of the same class.
+ * <h2>Note</h2> Normally, negotiation parties should not create new Party IDs
+ * as all needed IDs should be provided by the protocol.
  */
 public final class PartyId {
Index: events/src/test/java/geniusweb/actions/FileLocationTest.java
===================================================================
--- events/src/test/java/geniusweb/actions/FileLocationTest.java	(revision 31)
+++ events/src/test/java/geniusweb/actions/FileLocationTest.java	(revision 31)
@@ -0,0 +1,66 @@
+package geniusweb.actions;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.UUID;
+
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class FileLocationTest {
+	private final ObjectMapper jackson = new ObjectMapper();
+	private FileLocation fileloc = new FileLocation();
+	private String filelocstr = "\"" + fileloc.getUUIDString() + "\"";
+
+	private String uuidstr = "b871e65c-e7fe-4664-b607-cb31898cc3ac";
+	private FileLocation fileloc2 = new FileLocation(UUID.fromString(uuidstr));
+
+	@Test
+	public void isUsable() throws IOException {
+		File file = fileloc.getFile();
+		assertFalse(file.exists());
+		assertTrue(file.createNewFile());
+		assertTrue(file.canRead());
+		assertTrue(file.canWrite());
+
+	}
+
+	@Test
+	public void serializeTest() throws JsonProcessingException {
+		System.out.println(jackson.writeValueAsString(fileloc));
+		assertEquals(filelocstr, jackson.writeValueAsString(fileloc));
+	}
+
+	@Test
+	public void deserializTest() throws IOException {
+		FileLocation loc = jackson.readValue(filelocstr, FileLocation.class);
+		assertEquals(fileloc, loc);
+	}
+
+	@Test(expected = JsonParseException.class)
+	public void deserializeTestInjectinon()
+			throws JsonParseException, JsonMappingException, IOException {
+		jackson.readValue("bla/../..", FileLocation.class);
+	}
+
+	@Test(expected = JsonParseException.class)
+	public void deserializeTestInjection2()
+			throws JsonParseException, JsonMappingException, IOException {
+		jackson.readValue("~/blabla", FileLocation.class);
+	}
+
+	@Test(expected = JsonParseException.class)
+	public void deserializeTestInjection3()
+			throws JsonParseException, JsonMappingException, IOException {
+		jackson.readValue("C:\\Windows", FileLocation.class);
+	}
+
+}
Index: events/src/test/java/geniusweb/actions/LearningDoneTest.java
===================================================================
--- events/src/test/java/geniusweb/actions/LearningDoneTest.java	(revision 31)
+++ events/src/test/java/geniusweb/actions/LearningDoneTest.java	(revision 31)
@@ -0,0 +1,52 @@
+package geniusweb.actions;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import tudelft.utilities.junit.GeneralTests;
+
+public class LearningDoneTest extends GeneralTests<LearningDone> {
+	private final ObjectMapper jackson = new ObjectMapper();
+
+	private final PartyId id = new PartyId("party1");
+	private final PartyId idb = new PartyId("party2");
+
+	private final LearningDone done = new LearningDone(id);
+	private final LearningDone done1 = new LearningDone(id);
+	private final LearningDone done2 = new LearningDone(idb);
+
+	private final String endnegostring = "{\"LearningDone\":{\"actor\":\"party1\"}}";
+
+	@Override
+	public List<List<LearningDone>> getGeneralTestData() {
+		return Arrays.asList(Arrays.asList(done, done1),
+				Arrays.asList(done2));
+	}
+
+	@Override
+	public List<String> getGeneralTestStrings() {
+		return Arrays.asList("LearningDone\\[.*" + id + ".*\\]",
+				"LearningDone\\[.*" + idb + ".*\\]");
+	}
+
+	@Test
+	public void serializeEndNegoTest() throws JsonProcessingException {
+		System.out.println(jackson.writeValueAsString(done));
+		assertEquals(endnegostring, jackson.writeValueAsString(done));
+	}
+
+	@Test
+	public void deserializeEndNegoTest() throws IOException {
+		Action act = jackson.readValue(endnegostring, Action.class);
+		assertEquals(done, act);
+	}
+
+}
Index: events/src/test/java/geniusweb/inform/SettingsTest.java
===================================================================
--- events/src/test/java/geniusweb/inform/SettingsTest.java	(revision 30)
+++ events/src/test/java/geniusweb/inform/SettingsTest.java	(revision 31)
@@ -62,6 +62,5 @@
 
 		Parameters settings1 = new Parameters();
-		Parameters settings2 = new Parameters();
-		settings2.put("a", 1);
+		Parameters settings2 = new Parameters().with("a", 1);
 
 		negoinfo1 = new Settings(id, profile1, protocol1, progress1, settings1);
