Index: events/src/main/java/geniusweb/actions/AbstractAction.java
===================================================================
--- events/src/main/java/geniusweb/actions/AbstractAction.java	(revision 52)
+++ events/src/main/java/geniusweb/actions/AbstractAction.java	(revision 1)
@@ -6,5 +6,5 @@
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE, isGetterVisibility = Visibility.NONE)
+@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
 public class AbstractAction implements Action {
 
Index: events/src/main/java/geniusweb/actions/Accept.java
===================================================================
--- events/src/main/java/geniusweb/actions/Accept.java	(revision 52)
+++ events/src/main/java/geniusweb/actions/Accept.java	(revision 1)
@@ -3,4 +3,5 @@
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
 
 import geniusweb.issuevalue.Bid;
@@ -11,4 +12,5 @@
  * {@link Offer}ed by some party.
  */
+@JsonTypeName("accept")
 public class Accept extends ActionWithBid {
 
Index: events/src/main/java/geniusweb/actions/Action.java
===================================================================
--- events/src/main/java/geniusweb/actions/Action.java	(revision 52)
+++ events/src/main/java/geniusweb/actions/Action.java	(revision 1)
@@ -12,14 +12,6 @@
  */
 @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = As.WRAPPER_OBJECT)
-@JsonSubTypes({ @JsonSubTypes.Type(value = EndNegotiation.class),
-		@JsonSubTypes.Type(value = Offer.class),
-		@JsonSubTypes.Type(value = Accept.class),
-		@JsonSubTypes.Type(value = Comparison.class),
-		@JsonSubTypes.Type(value = ElicitComparison.class),
-		@JsonSubTypes.Type(value = Vote.class),
-		@JsonSubTypes.Type(value = Votes.class),
-		@JsonSubTypes.Type(value = VoteWithValue.class),
-		@JsonSubTypes.Type(value = VotesWithValue.class),
-		@JsonSubTypes.Type(value = LearningDone.class) })
+@JsonSubTypes({ @JsonSubTypes.Type(value = EndNegotiation.class), @JsonSubTypes.Type(value = Offer.class),
+		@JsonSubTypes.Type(value = Accept.class) })
 public interface Action {
 	/**
Index: events/src/main/java/geniusweb/actions/ActionWithBid.java
===================================================================
--- events/src/main/java/geniusweb/actions/ActionWithBid.java	(revision 52)
+++ events/src/main/java/geniusweb/actions/ActionWithBid.java	(revision 1)
@@ -7,6 +7,5 @@
 
 /**
- * An {@link Action} containing a bid. Note that the presense of a bid does not
- * necessarily mean that an offer was placed for this bid.
+ * An {@link Action} containing a bid.
  * 
  */
Index: events/src/main/java/geniusweb/actions/Comparison.java
===================================================================
--- events/src/main/java/geniusweb/actions/Comparison.java	(revision 52)
+++ 	(revision )
@@ -1,94 +1,0 @@
-package geniusweb.actions;
-
-import java.util.List;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import geniusweb.issuevalue.Bid;
-
-/**
- * A statement from a Party that some bids are better and worse than
- * {@link #getBid()} bid. Typically this is a response to a CompareWithBid
- * inform
- *
- */
-public class Comparison extends ActionWithBid {
-
-	private List<Bid> better;
-	private List<Bid> worse;
-
-	/**
-	 * @param id     the party id that made this comparison
-	 * @param bid    the bid that is compared wiht
-	 * @param better list of bids that are better than bid
-	 * @param worse  list of bids that are worse than bid
-	 */
-	@JsonCreator
-	public Comparison(@JsonProperty("id") PartyId id,
-			@JsonProperty("bid") Bid bid,
-			@JsonProperty("better") List<Bid> better,
-			@JsonProperty("worse") List<Bid> worse) {
-		super(id, bid);
-		if (bid == null || better == null || worse == null)
-			throw new IllegalArgumentException(
-					"bid, better and worse must not be null");
-		this.better = better;
-		this.worse = worse;
-	}
-
-	/**
-	 * @return All bids that are better than the bid. Maybe empty
-	 * 
-	 */
-	public List<Bid> getBetter() {
-		return better;
-	}
-
-	/**
-	 * @return All bids that are worse than the bid. Maybe empty
-	 * 
-	 */
-
-	public List<Bid> getWorse() {
-		return worse;
-	}
-
-	@Override
-	public String toString() {
-		return "Comparison[" + getActor() + "," + getBid() + ",better=" + better
-				+ ",worse=" + worse + "]";
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = super.hashCode();
-		result = prime * result + ((better == null) ? 0 : better.hashCode());
-		result = prime * result + ((worse == null) ? 0 : worse.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (!super.equals(obj))
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		Comparison other = (Comparison) obj;
-		if (better == null) {
-			if (other.better != null)
-				return false;
-		} else if (!better.equals(other.better))
-			return false;
-		if (worse == null) {
-			if (other.worse != null)
-				return false;
-		} else if (!worse.equals(other.worse))
-			return false;
-		return true;
-	}
-
-}
Index: events/src/main/java/geniusweb/actions/ElicitComparison.java
===================================================================
--- events/src/main/java/geniusweb/actions/ElicitComparison.java	(revision 52)
+++ 	(revision )
@@ -1,80 +1,0 @@
-package geniusweb.actions;
-
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import geniusweb.issuevalue.Bid;
-
-/**
- * Request a comparison from the cob party. The party can do a
- * {@link Comparison} action as a response.
- */
-public class ElicitComparison extends ActionWithBid {
-	private final List<Bid> options = new LinkedList<>();
-
-	/**
-	 * @param id   the eliciting party.
-	 * @param bid  the bid to compare the options with
-	 * @param opts the available options that may be chosen from. Must not be
-	 *             null and must have at least 2 options.
-	 */
-	@JsonCreator
-	public ElicitComparison(@JsonProperty("actor") PartyId id,
-			@JsonProperty("bid") Bid bid,
-			@JsonProperty("options") List<Bid> opts) {
-		super(id, bid);
-		if (bid == null)
-			throw new IllegalArgumentException(
-					"Bid to compare with must not be null");
-		if (opts == null || opts.size() < 1) {
-			throw new IllegalArgumentException(
-					"opts must not be null and have at least 1 option");
-		}
-		this.options.addAll(opts);
-	}
-
-	/**
-	 * 
-	 * @return the list of {@link Bid}s to compare {@link #getBid()} with
-	 */
-	public List<Bid> getOptions() {
-		return Collections.unmodifiableList(options);
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = super.hashCode();
-		result = prime * result + ((options == null) ? 0 : options.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (!super.equals(obj))
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		ElicitComparison other = (ElicitComparison) obj;
-		if (options == null) {
-			if (other.options != null)
-				return false;
-		} else if (!options.equals(other.options))
-			return false;
-		return true;
-	}
-
-	@Override
-	public String toString() {
-		return "ElicitComparison[" + getActor() + "," + getBid() + "," + options
-				+ "]";
-
-	}
-
-}
Index: events/src/main/java/geniusweb/actions/EndNegotiation.java
===================================================================
--- events/src/main/java/geniusweb/actions/EndNegotiation.java	(revision 52)
+++ events/src/main/java/geniusweb/actions/EndNegotiation.java	(revision 1)
@@ -3,4 +3,5 @@
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
 
 /**
@@ -8,4 +9,5 @@
  *
  */
+@JsonTypeName("endnegotiation")
 public class EndNegotiation extends AbstractAction {
 
Index: events/src/main/java/geniusweb/actions/FileLocation.java
===================================================================
--- events/src/main/java/geniusweb/actions/FileLocation.java	(revision 52)
+++ 	(revision )
@@ -1,109 +1,0 @@
-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}. See {@link #getFile()} to get the file referenced by this. 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) {
-		if (!rootfolder.exists()) {
-			rootfolder.mkdir();
-			System.out
-					.println("created FileLocation root dir at " + rootfolder);
-		}
-
-		this.name = name;
-	}
-
-	/**
-	 * Creates a new "random" FileLocation.
-	 */
-	public FileLocation() {
-		this(UUID.randomUUID());
-	}
-
-	/**
-	 * @return the UUID string
-	 */
-	public String getUUIDString() {
-		return name.toString();
-	}
-
-	/**
-	 * 
-	 * @return Actual file that can be used for read/write operations. This file
-	 *         usually resides in the geniusweb folder inside the java.io.tmpdir
-	 *         system property. This temp dir depends on the run configuration,
-	 *         eg some directory inside the user's home directory, or a temp
-	 *         folder inside tomcat.
-	 */
-	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 52)
+++ 	(revision )
@@ -1,20 +1,0 @@
-package geniusweb.actions;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-/**
- * The party that sends this action indicates that it's finished with the learning.
- * 
- */
-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/Offer.java
===================================================================
--- events/src/main/java/geniusweb/actions/Offer.java	(revision 52)
+++ events/src/main/java/geniusweb/actions/Offer.java	(revision 1)
@@ -3,4 +3,5 @@
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
 
 import geniusweb.issuevalue.Bid;
@@ -11,4 +12,5 @@
  * accepts the offer himself.
  */
+@JsonTypeName("offer")
 public class Offer extends ActionWithBid {
 
Index: events/src/main/java/geniusweb/actions/PartyId.java
===================================================================
--- events/src/main/java/geniusweb/actions/PartyId.java	(revision 52)
+++ events/src/main/java/geniusweb/actions/PartyId.java	(revision 1)
@@ -4,12 +4,9 @@
 
 /**
- * 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.
+ * 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.
  */
 public final class PartyId {
Index: events/src/main/java/geniusweb/actions/Vote.java
===================================================================
--- events/src/main/java/geniusweb/actions/Vote.java	(revision 52)
+++ 	(revision )
@@ -1,100 +1,0 @@
-package geniusweb.actions;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import geniusweb.issuevalue.Bid;
-
-/**
- * A vote is an indication by a party that it conditionally accepts a bid. It's
- * then up to the protocol to determine the outcome.
- */
-public class Vote extends ActionWithBid {
-	private final Integer minPower;
-	private final Integer maxPower;
-
-	/**
-	 * @param actor    the {@link PartyId} that does the action
-	 * @param bid      the bid that is voted on
-	 * @param minPower the minimum power this bid must get in order for the vote
-	 *                 to be valid. Power is the sum of the powers of the
-	 *                 parties that are in the deal. If power=1 for all
-	 *                 participants (usually the default) power can be
-	 *                 interpreted as number of votes
-	 * @param maxPower the maximum power this bid must get in order for the vote
-	 *                 to be valid. See {@link #minPower}
-	 */
-	@JsonCreator
-	public Vote(@JsonProperty("actor") PartyId actor,
-			@JsonProperty("bid") Bid bid,
-			@JsonProperty("minPower") Integer minPower,
-			@JsonProperty("maxPower") Integer maxPower) {
-		super(actor, bid);
-		this.minPower = minPower;
-		this.maxPower = maxPower;
-		if (bid == null || minPower == null || minPower < 1 || maxPower == null
-				|| maxPower < minPower) {
-			throw new IllegalArgumentException(
-					"Vote must have non-null bid and minVotes, and minPower must be >=1 and maxPower must be >=minPower");
-		}
-	}
-
-	/**
-	 * 
-	 * @return the minimum power this bid must get in order for the vote to be
-	 *         valid.
-	 */
-	public Integer getMinPower() {
-		return minPower;
-	}
-
-	/**
-	 * 
-	 * @return the max power this bid must get in order for the vote to be
-	 *         valid.
-	 */
-
-	public Integer getMaxPower() {
-		return maxPower;
-	}
-
-	@Override
-	public String toString() {
-		return "Vote[" + getActor() + "," + getBid() + "," + minPower + ","
-				+ maxPower + "]";
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = super.hashCode();
-		result = prime * result
-				+ ((maxPower == null) ? 0 : maxPower.hashCode());
-		result = prime * result
-				+ ((minPower == null) ? 0 : minPower.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (!super.equals(obj))
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		Vote other = (Vote) obj;
-		if (maxPower == null) {
-			if (other.maxPower != null)
-				return false;
-		} else if (!maxPower.equals(other.maxPower))
-			return false;
-		if (minPower == null) {
-			if (other.minPower != null)
-				return false;
-		} else if (!minPower.equals(other.minPower))
-			return false;
-		return true;
-	}
-
-}
Index: events/src/main/java/geniusweb/actions/VoteWithValue.java
===================================================================
--- events/src/main/java/geniusweb/actions/VoteWithValue.java	(revision 52)
+++ 	(revision )
@@ -1,125 +1,0 @@
-package geniusweb.actions;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import geniusweb.issuevalue.Bid;
-
-/**
- * A vote is an indication by a party that it conditionally accepts a bid. It's
- * then up to the protocol to determine the outcome.
- */
-public class VoteWithValue extends ActionWithBid {
-	private final Integer minPower;
-	private final Integer maxPower;
-	private final Integer value;
-
-	/**
-	 * @param id       the {@link PartyId} that does the action
-	 * @param bid      the bid that is voted on
-	 * @param minPower the minimum power this bid must get in order for the vote
-	 *                 to be valid. Power is the sum of the powers of the
-	 *                 parties that are in the deal. If power=1 for all
-	 *                 participants (usually the default) power can be
-	 *                 interpreted as number of votes
-	 * @param maxPower the maximum power this bid must get in order for the vote
-	 *                 to be valid. See {@link #minPower}
-	 * @param value    the value for this vote. An integer in [1,100]. Higher
-	 *                 means that the actor likes this bid better. Note: value 0
-	 *                 is reserved for "unacceptable" and therefore can not be
-	 *                 used as a valid value.
-	 */
-	@JsonCreator
-	public VoteWithValue(@JsonProperty("actor") PartyId id,
-			@JsonProperty("bid") Bid bid,
-			@JsonProperty("minPower") Integer minPower,
-			@JsonProperty("maxPower") Integer maxPower,
-			@JsonProperty("value") Integer value) {
-		super(id, bid);
-		this.minPower = minPower;
-		this.maxPower = maxPower;
-		this.value = value;
-		if (value < 1 || value > 100)
-			throw new IllegalArgumentException(
-					"value must be in [1,100] but got " + value);
-		if (bid == null || minPower == null || minPower < 1 || maxPower == null
-				|| maxPower < minPower) {
-			throw new IllegalArgumentException(
-					"Vote must have non-null bid and minVotes, and minPower must be >=1 and maxPower must be >=minPower");
-		}
-	}
-
-	/**
-	 * 
-	 * @return the minimum power this bid must get in order for the vote to be
-	 *         valid.
-	 */
-	public Integer getMinPower() {
-		return minPower;
-	}
-
-	/**
-	 * 
-	 * @return the max power this bid must get in order for the vote to be
-	 *         valid.
-	 */
-	public Integer getMaxPower() {
-		return maxPower;
-	}
-
-	/**
-	 * 
-	 * @return the value for this vote. An integer in [1,100]. Higher means that
-	 *         the actor likes this bid better.
-	 * 
-	 */
-	public Integer getValue() {
-		return value;
-	}
-
-	@Override
-	public String toString() {
-		return "VoteWithValue[" + getActor() + "," + getBid() + "," + minPower
-				+ "," + maxPower + "," + value + "]";
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = super.hashCode();
-		result = prime * result
-				+ ((maxPower == null) ? 0 : maxPower.hashCode());
-		result = prime * result
-				+ ((minPower == null) ? 0 : minPower.hashCode());
-		result = prime * result + ((value == null) ? 0 : value.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (!super.equals(obj))
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		VoteWithValue other = (VoteWithValue) obj;
-		if (maxPower == null) {
-			if (other.maxPower != null)
-				return false;
-		} else if (!maxPower.equals(other.maxPower))
-			return false;
-		if (minPower == null) {
-			if (other.minPower != null)
-				return false;
-		} else if (!minPower.equals(other.minPower))
-			return false;
-		if (value == null) {
-			if (other.value != null)
-				return false;
-		} else if (!value.equals(other.value))
-			return false;
-		return true;
-	}
-
-}
Index: events/src/main/java/geniusweb/actions/Votes.java
===================================================================
--- events/src/main/java/geniusweb/actions/Votes.java	(revision 52)
+++ 	(revision )
@@ -1,118 +1,0 @@
-package geniusweb.actions;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import geniusweb.issuevalue.Bid;
-
-/**
- * Indicates that a party conditionally agrees with any of the {@link Vote}s
- * provided.
- */
-public class Votes extends AbstractAction {
-	private final Set<Vote> votes;
-
-	/**
-	 * 
-	 * @param actor party id
-	 * @param votes the {@link Vote}s that the party can agree on, if the
-	 *              condition of the Vote holds. Every {@link Vote#getActor()}
-	 *              should equal the id. There may be at most 1 vote per
-	 *              {@link Bid}.
-	 */
-	@JsonCreator
-	public Votes(@JsonProperty("actor") PartyId actor,
-			@JsonProperty("votes") Set<Vote> votes) {
-		super(actor);
-		this.votes = new HashSet<>(votes);
-		if (votes == null)
-			throw new NullPointerException("votes must be not null");
-
-		List<Bid> votedBids = new LinkedList<>();
-		for (Vote vote : votes) {
-			if (!vote.getActor().equals(actor))
-				throw new IllegalArgumentException("All votes must come from "
-						+ actor + " but found " + vote);
-
-			Bid bid = vote.getBid();
-			if (votedBids.contains(bid))
-				throw new IllegalArgumentException(
-						"Votes contains multiple Vote's for " + bid);
-			votedBids.add(bid);
-		}
-	}
-
-	/**
-	 * Test if Votes extends other votes. Extending means that for each vote on
-	 * bid B with power P in othervotes, this contains also a vote for bid B
-	 * with power at most P.
-	 * 
-	 * @param otherVotes the {@link Votes}, usually from a previous round, that
-	 *                   this should extend.
-	 * @return true iff this extends the otherVotes.
-	 */
-	public boolean isExtending(Votes otherVotes) {
-		if (!otherVotes.getActor().equals(getActor()))
-			return false;
-		for (Vote vote : otherVotes.getVotes()) {
-			Vote myvote = getVote(vote.getBid());
-			if (myvote == null || myvote.getMinPower() > vote.getMinPower()
-					|| myvote.getMaxPower() < vote.getMaxPower())
-				return false;
-		}
-		return true;
-	}
-
-	/**
-	 * 
-	 * @param bid the bid that we may have a vote for
-	 * @return myvote for bid, or null if no vote for that bid;
-	 */
-	public Vote getVote(Bid bid) {
-		for (Vote vote : votes) {
-			if (vote.getBid().equals(bid))
-				return vote;
-		}
-		return null;
-	}
-
-	public Set<Vote> getVotes() {
-		return Collections.unmodifiableSet(votes);
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = super.hashCode();
-		result = prime * result + ((votes == null) ? 0 : votes.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (!super.equals(obj))
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		Votes other = (Votes) obj;
-		if (votes == null) {
-			if (other.votes != null)
-				return false;
-		} else if (!votes.equals(other.votes))
-			return false;
-		return true;
-	}
-
-	@Override
-	public String toString() {
-		return "Votes[" + getActor() + "," + votes + "]";
-	}
-}
Index: events/src/main/java/geniusweb/actions/VotesWithValue.java
===================================================================
--- events/src/main/java/geniusweb/actions/VotesWithValue.java	(revision 52)
+++ 	(revision )
@@ -1,125 +1,0 @@
-package geniusweb.actions;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import geniusweb.issuevalue.Bid;
-
-/**
- * Indicates that a party conditionally agrees with any of the
- * {@link VoteWithValue}s provided.
- */
-public class VotesWithValue extends AbstractAction {
-	private final Set<VoteWithValue> votes;
-
-	/**
-	 * 
-	 * @param id    party id
-	 * @param votes the {@link Vote}s that the party can agree on, if the
-	 *              condition of the Vote holds. Every {@link Vote#getActor()}
-	 *              should equal the id. The sum of the values must =100.
-	 */
-	@JsonCreator
-	public VotesWithValue(@JsonProperty("actor") PartyId id,
-			@JsonProperty("votes") Set<VoteWithValue> votes) {
-		super(id);
-		this.votes = votes;
-		if (votes == null)
-			throw new NullPointerException("votes must be not null");
-		for (VoteWithValue vote : votes) {
-			if (!vote.getActor().equals(id)) {
-				throw new IllegalArgumentException("All votes must come from "
-						+ id + " but found " + vote);
-			}
-		}
-		if (votes.stream().map(v -> v.getValue()).reduce(0,
-				Integer::sum) != 100)
-			throw new IllegalArgumentException(
-					"Sum of the placed votes must be 100");
-		// check for duplicate Vote's, possibly with different powers
-		Map<Bid, Long> counts = votes.stream().map(vote -> vote.getBid())
-				.collect(Collectors.groupingBy(bid -> bid,
-						Collectors.counting()));
-		Optional<Entry<Bid, Long>> nonunique = counts.entrySet().stream()
-				.filter(entry -> entry.getValue() > 1).findAny();
-		if (nonunique.isPresent())
-			throw new IllegalArgumentException(
-					"Votes contains multiple Vote's for "
-							+ nonunique.get().getKey());
-	}
-
-	/**
-	 * Test if Votes extends other votes. Extending means that for each vote on
-	 * bid B with power P in othervotes, this contains also a vote for bid B
-	 * with power at most P.
-	 * 
-	 * @param otherVotes the {@link VotesWithValue}, usually from a previous
-	 *                   round, that this should extend.
-	 * @return true iff this extends the otherVotes.
-	 */
-	public boolean isExtending(VotesWithValue otherVotes) {
-		if (!otherVotes.getActor().equals(getActor()))
-			return false;
-		for (VoteWithValue vote : otherVotes.getVotes()) {
-			VoteWithValue myvote = getVote(vote.getBid());
-			if (myvote == null || myvote.getMinPower() > vote.getMinPower()
-					|| myvote.getMaxPower() < vote.getMaxPower())
-				return false;
-		}
-		return true;
-	}
-
-	/**
-	 * 
-	 * @param bid the bid that we may have a vote for
-	 * @return myvote for bid, or null if no vote for that bid;
-	 */
-	public VoteWithValue getVote(Bid bid) {
-		for (VoteWithValue vote : votes) {
-			if (vote.getBid().equals(bid))
-				return vote;
-		}
-		return null;
-	}
-
-	public Set<VoteWithValue> getVotes() {
-		return Collections.unmodifiableSet(votes);
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = super.hashCode();
-		result = prime * result + ((votes == null) ? 0 : votes.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (!super.equals(obj))
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		VotesWithValue other = (VotesWithValue) obj;
-		if (votes == null) {
-			if (other.votes != null)
-				return false;
-		} else if (!votes.equals(other.votes))
-			return false;
-		return true;
-	}
-
-	@Override
-	public String toString() {
-		return "VotesWithValue[" + getActor() + "," + votes + "]";
-	}
-}
Index: events/src/main/java/geniusweb/events/ActionEvent.java
===================================================================
--- events/src/main/java/geniusweb/events/ActionEvent.java	(revision 52)
+++ events/src/main/java/geniusweb/events/ActionEvent.java	(revision 1)
@@ -3,4 +3,5 @@
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
 
 import geniusweb.actions.Action;
@@ -10,4 +11,5 @@
  *
  */
+@JsonTypeName("actionevent")
 public class ActionEvent extends AbstractEvent {
 
@@ -16,5 +18,5 @@
 	/**
 	 * 
-	 * @param action the {@link Action} that was done
+	 * @param action
 	 * @param time   the current time to use. see
 	 *               {@link System#currentTimeMillis()}.
Index: events/src/main/java/geniusweb/events/CurrentState.java
===================================================================
--- events/src/main/java/geniusweb/events/CurrentState.java	(revision 52)
+++ events/src/main/java/geniusweb/events/CurrentState.java	(revision 1)
@@ -20,9 +20,4 @@
  */
 public abstract class CurrentState extends ProtocolEvent {
-	public CurrentState() {
-	}
-
-	public CurrentState(Long now) {
-		super(now);
-	}
+	// all should implement NegoState getState();
 }
Index: events/src/main/java/geniusweb/events/NegotiationEvent.java
===================================================================
--- events/src/main/java/geniusweb/events/NegotiationEvent.java	(revision 52)
+++ events/src/main/java/geniusweb/events/NegotiationEvent.java	(revision 1)
@@ -6,6 +6,4 @@
 import com.fasterxml.jackson.annotation.JsonTypeInfo;
 import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
-
-import geniusweb.actions.Action;
 
 /**
Index: events/src/main/java/geniusweb/events/SessionStarted.java
===================================================================
--- events/src/main/java/geniusweb/events/SessionStarted.java	(revision 52)
+++ events/src/main/java/geniusweb/events/SessionStarted.java	(revision 1)
@@ -5,7 +5,9 @@
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
 
 import geniusweb.actions.PartyId;
 
+@JsonTypeName("sessionstarted")
 public class SessionStarted extends ProtocolEvent {
 	private Long sessionNumber;
Index: events/src/main/java/geniusweb/events/TournamentStarted.java
===================================================================
--- events/src/main/java/geniusweb/events/TournamentStarted.java	(revision 52)
+++ events/src/main/java/geniusweb/events/TournamentStarted.java	(revision 1)
@@ -1,4 +1,7 @@
 package geniusweb.events;
 
+import com.fasterxml.jackson.annotation.JsonTypeName;
+
+@JsonTypeName("tournamentstarted")
 public class TournamentStarted extends ProtocolEvent {
 	private Long numberOfSessions;
Index: events/src/test/java/actions/AcceptTest.java
===================================================================
--- events/src/test/java/actions/AcceptTest.java	(revision 1)
+++ events/src/test/java/actions/AcceptTest.java	(revision 1)
@@ -0,0 +1,94 @@
+package actions;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import geniusweb.actions.Accept;
+import geniusweb.actions.Action;
+import geniusweb.actions.PartyId;
+import geniusweb.issuevalue.Bid;
+import geniusweb.issuevalue.DiscreteValue;
+import geniusweb.issuevalue.NumberValue;
+import geniusweb.issuevalue.Value;
+import tudelft.utilities.junit.GeneralTests;
+
+public class AcceptTest extends GeneralTests<Accept> {
+	private final ObjectMapper jackson = new ObjectMapper();
+
+	private static final PartyId id = new PartyId("party1");
+	private static final PartyId id2 = new PartyId("party2");
+	private final static Map<String, Value> issuevalues = new HashMap<String, Value>();
+	private final static Map<String, Value> issuevaluesb = new HashMap<String, Value>();
+	private static Bid bid;
+	private static Bid bidb;
+	private final static String ISSUE1 = "issue1";
+	private final static Value VALUE1 = new DiscreteValue("value1");
+	private final static String ISSUE2 = "issue2";
+	private final static Value VALUE2 = new NumberValue("10");
+	// issue 2 is NUMBER and thus serializes with leading '='
+	private final String acceptstring = "{\"accept\":{\"actor\":\"party1\",\"bid\":{\"issuevalues\":{\"issue2\":10,\"issue1\":\"value1\"}}}}";
+
+	private static Accept accept, accept1, accept2, acceptb;
+
+	static {
+		issuevalues.put(ISSUE1, VALUE1);
+		issuevalues.put(ISSUE2, VALUE2);
+		bid = new Bid(issuevalues);
+		accept = new Accept(id, bid);
+		accept1 = new Accept(id, bid);
+
+		accept2 = new Accept(id2, bid);
+
+		// values swapped, so different issuevalues.
+		issuevaluesb.put(ISSUE1, VALUE2);
+		issuevaluesb.put(ISSUE2, VALUE2);
+		bidb = new Bid(issuevaluesb);
+		acceptb = new Accept(id, bidb);
+
+	}
+
+	@Override
+	public List<List<Accept>> getGeneralTestData() {
+		List<List<Accept>> list = new LinkedList<>();
+		list.add(Arrays.asList(accept, accept1));
+		list.add(Arrays.asList(accept2));
+		list.add(Arrays.asList(acceptb));
+		return list;
+	}
+
+	@Override
+	public List<String> getGeneralTestStrings() {
+		return Arrays.asList("Accept.*" + id + ".*]", "Accept.*" + id2 + ".*]",
+				"Accept.*" + id + ".*]");
+	}
+
+	@Before
+	public void before() {
+
+	}
+
+	@Test
+	public void serializeAcceptTest() throws JsonProcessingException {
+		System.out.println(jackson.writeValueAsString(accept));
+		assertEquals(acceptstring, jackson.writeValueAsString(accept));
+	}
+
+	@Test
+	public void deserializeAcceptTest() throws IOException {
+		Action act = jackson.readValue(acceptstring, Action.class);
+		assertEquals(accept, act);
+	}
+
+}
Index: events/src/test/java/actions/EndNegoTest.java
===================================================================
--- events/src/test/java/actions/EndNegoTest.java	(revision 1)
+++ events/src/test/java/actions/EndNegoTest.java	(revision 1)
@@ -0,0 +1,53 @@
+package 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 geniusweb.actions.Action;
+import geniusweb.actions.EndNegotiation;
+import geniusweb.actions.PartyId;
+import tudelft.utilities.junit.GeneralTests;
+
+public class EndNegoTest extends GeneralTests<EndNegotiation> {
+	private final ObjectMapper jackson = new ObjectMapper();
+
+	private final PartyId id = new PartyId("party1");
+	private final PartyId idb = new PartyId("party2");
+
+	private final EndNegotiation endnego = new EndNegotiation(id);
+	private final EndNegotiation endnego1 = new EndNegotiation(id);
+	private final EndNegotiation endnegob = new EndNegotiation(idb);
+
+	private final String endnegostring = "{\"endnegotiation\":{\"actor\":\"party1\"}}";
+
+	@Override
+	public List<List<EndNegotiation>> getGeneralTestData() {
+		return Arrays.asList(Arrays.asList(endnego, endnego1), Arrays.asList(endnegob));
+	}
+
+	@Override
+	public List<String> getGeneralTestStrings() {
+		return Arrays.asList("EndNegotiation\\[.*" + id + ".*\\]", "EndNegotiation\\[.*" + idb + ".*\\]");
+	}
+
+	@Test
+	public void serializeEndNegoTest() throws JsonProcessingException {
+		System.out.println(jackson.writeValueAsString(endnego));
+		assertEquals(endnegostring, jackson.writeValueAsString(endnego));
+	}
+
+	@Test
+	public void deserializeEndNegoTest() throws IOException {
+		Action act = jackson.readValue(endnegostring, Action.class);
+		assertEquals(endnego, act);
+	}
+
+}
Index: events/src/test/java/actions/OfferTest.java
===================================================================
--- events/src/test/java/actions/OfferTest.java	(revision 1)
+++ events/src/test/java/actions/OfferTest.java	(revision 1)
@@ -0,0 +1,82 @@
+package actions;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import geniusweb.actions.Action;
+import geniusweb.actions.Offer;
+import geniusweb.actions.PartyId;
+import geniusweb.issuevalue.Bid;
+import geniusweb.issuevalue.DiscreteValue;
+import geniusweb.issuevalue.NumberValue;
+import geniusweb.issuevalue.Value;
+import tudelft.utilities.junit.GeneralTests;
+
+public class OfferTest extends GeneralTests<Offer> {
+	private final ObjectMapper jackson = new ObjectMapper();
+
+	private static final PartyId id = new PartyId("party1");
+	private static final Map<String, Value> issuevalues = new HashMap<String, Value>();
+	private static final Map<String, Value> issuevaluesb = new HashMap<String, Value>();
+	private static Bid bid;
+	private static Bid bidb;
+	private static final String ISSUE1 = "issue1";
+	private static final Value VALUE1 = new DiscreteValue("value1");
+	private static final String ISSUE2 = "issue2";
+	private static final Value VALUE2 = new NumberValue("10");
+	private static final String acceptstring = "{\"offer\":{\"actor\":\"party1\",\"bid\":{\"issuevalues\":{\"issue2\":10,\"issue1\":\"value1\"}}}}";
+
+	private static Offer offer;
+	private static Offer offer1;
+	private static Offer offerb;
+
+	static {
+		issuevalues.put(ISSUE1, VALUE1);
+		issuevalues.put(ISSUE2, VALUE2);
+		bid = new Bid(issuevalues);
+		offer = new Offer(id, bid);
+		offer1 = new Offer(id, bid);
+
+		// values swapped, so different issuevalues.
+		issuevaluesb.put(ISSUE1, VALUE2);
+		issuevaluesb.put(ISSUE2, VALUE2);
+		bidb = new Bid(issuevaluesb);
+		offerb = new Offer(id, bidb);
+
+	}
+
+	@Override
+	public List<List<Offer>> getGeneralTestData() {
+		return Arrays.asList(Arrays.asList(offer, offer1),
+				Arrays.asList(offerb));
+	}
+
+	@Override
+	public List<String> getGeneralTestStrings() {
+		return Arrays.asList("Offer\\[.*" + id + ".*Bid.*\\]",
+				"Offer\\[.*" + id + ".*Bid.*\\]");
+	}
+
+	@Test
+	public void serializeAcceptTest() throws JsonProcessingException {
+		System.out.println(jackson.writeValueAsString(offer));
+		assertEquals(acceptstring, jackson.writeValueAsString(offer));
+	}
+
+	@Test
+	public void deserializeAcceptTest() throws IOException {
+		Action act = jackson.readValue(acceptstring, Action.class);
+		assertEquals(offer, act);
+	}
+
+}
Index: events/src/test/java/actions/PartyIdTest.java
===================================================================
--- events/src/test/java/actions/PartyIdTest.java	(revision 1)
+++ events/src/test/java/actions/PartyIdTest.java	(revision 1)
@@ -0,0 +1,68 @@
+package actions;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+
+import geniusweb.actions.PartyId;
+import tudelft.utilities.junit.GeneralTests;
+
+public class PartyIdTest extends GeneralTests<PartyId> {
+	private final PartyId id = new PartyId("party1");
+	private final PartyId id1 = new PartyId("party1");
+	private final PartyId idb = new PartyId("party2");
+
+	@Override
+	public List<List<PartyId>> getGeneralTestData() {
+		return Arrays.asList(Arrays.asList(id, id1), Arrays.asList(idb));
+	}
+
+	@Override
+	public List<String> getGeneralTestStrings() {
+		return Arrays.asList("party1", "party2");
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void testRestrictions() {
+		new PartyId("");
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void testRestrictions2() {
+		new PartyId("@2");
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void testRestrictions3() {
+		new PartyId("_12");
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void testRestrictions4() {
+		new PartyId("12A");
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void testRestrictions5() {
+		new PartyId(" fds ");
+	}
+
+	@Test
+	public void testGetName() {
+		assertEquals("party1", id.getName());
+	}
+
+	@Test
+	public void testRestrictions6() {
+		new PartyId("A_1_23_ok");
+	}
+
+	@Test
+	public void testRestrictions7() {
+		new PartyId("a_1_23_ok");
+	}
+
+}
Index: events/src/test/java/actions/PartyIdTest1.java
===================================================================
--- events/src/test/java/actions/PartyIdTest1.java	(revision 1)
+++ events/src/test/java/actions/PartyIdTest1.java	(revision 1)
@@ -0,0 +1,73 @@
+package actions;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Before;
+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;
+
+import geniusweb.actions.PartyId;
+import tudelft.utilities.junit.GeneralTests;
+
+public class PartyIdTest1 extends GeneralTests<PartyId> {
+
+	private PartyId party1, party1a, party2, party3;
+	private String asJson = "\"party1\"";
+
+	@Before
+	public void before() throws URISyntaxException {
+		party1 = new PartyId("party1");
+		party1a = new PartyId("party1");
+		party2 = new PartyId("party2");
+		party3 = new PartyId("party3");
+	}
+
+	@Override
+	public List<List<PartyId>> getGeneralTestData() {
+		return Arrays.asList(Arrays.asList(party1, party1a),
+				Arrays.asList(party2), Arrays.asList(party3));
+	}
+
+	@Override
+	public List<String> getGeneralTestStrings() {
+		return Arrays.asList("party1", "party2", "party3");
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void smokeTest() throws URISyntaxException {
+		new PartyId("*Csh789&@#^!^@^&");
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void nullTest() throws URISyntaxException {
+		new PartyId(null);
+	}
+
+	@Test
+	public void testSerialize() throws JsonProcessingException {
+		ObjectMapper jackson = new ObjectMapper();
+
+		String json = jackson.writeValueAsString(party1);
+		System.out.println(json);
+		assertEquals(asJson, json);
+	}
+
+	@Test
+	public void testDeserialize()
+			throws JsonParseException, JsonMappingException, IOException {
+		ObjectMapper jackson = new ObjectMapper();
+		PartyId p = jackson.readValue(asJson, PartyId.class);
+		System.out.println(p);
+		assertEquals(party1, p);
+	}
+
+}
Index: events/src/test/java/events/ActionEventTest.java
===================================================================
--- events/src/test/java/events/ActionEventTest.java	(revision 1)
+++ events/src/test/java/events/ActionEventTest.java	(revision 1)
@@ -0,0 +1,73 @@
+package events;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+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 geniusweb.actions.Action;
+import geniusweb.actions.EndNegotiation;
+import geniusweb.actions.PartyId;
+import geniusweb.events.ActionEvent;
+import geniusweb.events.NegotiationEvent;
+import tudelft.utilities.junit.GeneralTests;
+
+public class ActionEventTest extends GeneralTests<ActionEvent> {
+	private static final long NOW = 101l;
+	private final ObjectMapper jackson = new ObjectMapper();
+	private final String string = "{\"actionevent\":{\"action\":{\"endnegotiation\":{\"actor\":\"party1\"}},\"time\":101}}";
+	private final PartyId id = new PartyId("party1");
+	private final Action action = new EndNegotiation(id);
+	private final ActionEvent evt = new ActionEvent(action, NOW);
+	private final ActionEvent evt1 = new ActionEvent(action, NOW);
+	private final ActionEvent evtb = new ActionEvent(action, NOW + 1);
+
+	@Override
+	public List<List<ActionEvent>> getGeneralTestData() {
+		return Arrays.asList(Arrays.asList(evt, evt1), Arrays.asList(evtb));
+	}
+
+	@Override
+	public List<String> getGeneralTestStrings() {
+		return Arrays.asList("ActionEvent\\[.*" + NOW + ".*EndNegotiation.*\\]",
+				"ActionEvent\\[.*" + (NOW + 1) + ".*EndNegotiation.*\\]");
+	}
+
+	@Test
+	public void smoketest() {
+		Action action = mock(EndNegotiation.class);
+		ActionEvent evt = new ActionEvent(action, 0l);
+	}
+
+	@Test
+	public void serializeTest() throws JsonProcessingException {
+		System.out.println(jackson.writeValueAsString(evt));
+		assertEquals(string, jackson.writeValueAsString(evt));
+	}
+
+	@Test
+	public void deserializeTestReadActionEvent() throws IOException {
+		ActionEvent evt1 = jackson.readValue(string, ActionEvent.class);
+		// compare fields, as evt is a derived/new inner class
+		assertEquals(EndNegotiation.class, evt1.getAction().getClass());
+		assertEquals((Long) 101l, evt1.getTime());
+	}
+
+	@Test
+	public void deserializeTestReadEvent() throws IOException {
+		NegotiationEvent evt1 = jackson.readValue(string,
+				NegotiationEvent.class);
+		assertEquals(ActionEvent.class, evt1.getClass());
+		ActionEvent ev1 = (ActionEvent) evt1;
+		assertEquals(EndNegotiation.class, ev1.getAction().getClass());
+		assertEquals((Long) 101l, ev1.getTime());
+	}
+
+}
Index: events/src/test/java/events/SessionStartedTest.java
===================================================================
--- events/src/test/java/events/SessionStartedTest.java	(revision 1)
+++ events/src/test/java/events/SessionStartedTest.java	(revision 1)
@@ -0,0 +1,97 @@
+package events;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.DataPoints;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import geniusweb.actions.PartyId;
+import geniusweb.events.NegotiationEvent;
+import geniusweb.events.SessionStarted;
+import tudelft.utilities.junit.GeneralTests;
+
+public class SessionStartedTest extends GeneralTests<SessionStarted> {
+
+	private final ObjectMapper jackson = new ObjectMapper();
+
+	private static final Long SESSIONNR = 1l;
+	protected static final Long NOW = (long) 101;
+	protected static final Long NOW1 = NOW + 1;
+
+	private static final PartyId PARTY1 = new PartyId("party1");
+	private static final PartyId PARTY2 = new PartyId("party2");
+
+	private static List<PartyId> parties = Arrays.asList(PARTY1, PARTY2);
+
+	private static final SessionStarted sessionStartedLater = new SessionStarted(
+			SESSIONNR, parties, NOW1);
+	private static final SessionStarted othersessionStarted = new SessionStarted(
+			SESSIONNR + 1, parties, NOW);
+
+	public static SessionStarted sessionStarted = new SessionStarted(SESSIONNR,
+			parties, NOW);
+	private static final SessionStarted sessionStarted1 = new SessionStarted(
+			SESSIONNR, parties, NOW);
+	// jackson expected format.
+	private static String sessionstartedstring = "{\"sessionstarted\":{\"sessionNumber\":1,\"parties\":[\"party1\",\"party2\"],\"time\":101}}";
+	// "{\"sessionstarted\":{\"time\":101,\"sessionNumber\":1,\"parties\":[\"party1\",\"party2\"]}}";
+	public static String expectedstring = "SessionStarted.*101.*";
+
+	@Override
+	public List<List<SessionStarted>> getGeneralTestData() {
+		List<List<SessionStarted>> list = new LinkedList<>();
+		list.add(Arrays.asList(sessionStarted, sessionStarted1));
+		list.add(Arrays.asList(sessionStartedLater));
+		list.add(Arrays.asList(othersessionStarted));
+		return list;
+	}
+
+	@Override
+	public List<String> getGeneralTestStrings() {
+		return Arrays.asList("SessionStarted.*" + SESSIONNR + ".*" + NOW + ".*",
+				"SessionStarted.*" + SESSIONNR + ".*" + NOW1 + ".*",
+				"SessionStarted.*" + (SESSIONNR + 1) + ".*" + NOW + ".*");
+	}
+
+	@DataPoints("equal")
+	public static SessionStarted[] equal() {
+		return new SessionStarted[] { sessionStarted, sessionStarted1 };
+	}
+
+	@DataPoints("notequal")
+	public static SessionStarted[] notequal() {
+		return new SessionStarted[] { sessionStartedLater,
+				sessionStartedLater };
+	}
+
+	@DataPoint("equalstring")
+
+	@Test
+	public void serializeStartedTest() throws JsonProcessingException {
+		System.out.println(jackson.writeValueAsString(sessionStarted));
+		assertEquals(sessionstartedstring,
+				jackson.writeValueAsString(sessionStarted));
+	}
+
+	@Test
+	public void deserializeStartedTest() throws IOException {
+		NegotiationEvent evt = jackson.readValue(sessionstartedstring,
+				NegotiationEvent.class);
+		assertEquals(SessionStarted.class, evt.getClass());
+		SessionStarted event = (SessionStarted) evt;
+		// compare fields, as sessionended is a derived/new inner class
+		assertEquals(NOW, event.getTime());
+		assertEquals(SESSIONNR, event.getSessionNumber());
+		assertEquals(2, event.getParties().size());
+	}
+
+}
Index: events/src/test/java/events/TournamentStartedTest.java
===================================================================
--- events/src/test/java/events/TournamentStartedTest.java	(revision 1)
+++ events/src/test/java/events/TournamentStartedTest.java	(revision 1)
@@ -0,0 +1,77 @@
+package events;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import geniusweb.events.NegotiationEvent;
+import geniusweb.events.TournamentStarted;
+import tudelft.utilities.junit.GeneralTests;
+
+public class TournamentStartedTest extends GeneralTests<TournamentStarted> {
+
+	private final ObjectMapper jackson = new ObjectMapper();
+
+	private static final Long SESSIONNR = 1l;
+	protected static final Long NOW = (long) 101;
+	protected static final Long NOW1 = NOW + 1;
+	private static final Long NSESSIONS = 5l;
+
+	private static TournamentStarted tournamentStarted = new TournamentStarted(NSESSIONS, NOW);
+	private static TournamentStarted tournamentStarteda = new TournamentStarted(NSESSIONS, NOW);
+	private TournamentStarted otherTournamentStarted = new TournamentStarted(NSESSIONS + 1, NOW);
+	private TournamentStarted tournamentStartedLater = new TournamentStarted(NSESSIONS, NOW1);
+
+	private String tournamentstartedstring = "{\"tournamentstarted\":{\"time\":101,\"numberOfSessions\":5}}";
+
+	@Override
+	public List<List<TournamentStarted>> getGeneralTestData() {
+		List<List<TournamentStarted>> list = new LinkedList<>();
+		list.add(Arrays.asList(tournamentStarted, tournamentStarteda));
+		list.add(Arrays.asList(otherTournamentStarted));
+		list.add(Arrays.asList(tournamentStartedLater));
+		return list;
+	}
+
+	@Override
+	public List<String> getGeneralTestStrings() {
+		return Arrays.asList("TournamentStarted\\[.*" + NOW + ".*" + NSESSIONS + ".*\\]",
+				"TournamentStarted\\[.*" + NOW + ".*" + (NSESSIONS + 1) + ".*\\]",
+				"TournamentStarted\\[.*" + NOW1 + ".*" + NSESSIONS + ".*\\]");
+	}
+
+	@Test
+	public void serializeTournamentStartedTest() throws JsonProcessingException {
+		System.out.println(jackson.writeValueAsString(tournamentStarted));
+		assertEquals(tournamentstartedstring, jackson.writeValueAsString(tournamentStarted));
+	}
+
+	@Test
+	public void deserializeTournamentStartedTest() throws IOException {
+		NegotiationEvent evt = jackson.readValue(tournamentstartedstring, NegotiationEvent.class);
+		assertEquals(TournamentStarted.class, evt.getClass());
+		TournamentStarted event = (TournamentStarted) evt;
+		// compare fields, as sessionended is a derived/new inner class
+		assertEquals(NSESSIONS, event.getNumberOfSessions());
+		assertEquals(NOW, event.getTime());
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void testNullTime() {
+		new TournamentStarted(NSESSIONS, null);
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void testNegativeTime() {
+		new TournamentStarted(NSESSIONS, -1l);
+	}
+
+}
