Index: /bidspace/pom.xml
===================================================================
--- /bidspace/pom.xml	(revision 19)
+++ /bidspace/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb</groupId>
 	<artifactId>bidspace</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -16,5 +16,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.10</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /boa/pom.xml
===================================================================
--- /boa/pom.xml	(revision 20)
+++ /boa/pom.xml	(revision 20)
@@ -0,0 +1,248 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<groupId>geniusweb</groupId>
+	<artifactId>boa</artifactId>
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
+	<packaging>jar</packaging>
+
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<maven.compiler.target>1.8</maven.compiler.target>
+		<maven.compiler.source>1.8</maven.compiler.source>
+		<basedir>.</basedir>
+		<passwd>${env.ARTIFACTORY_PASS}</passwd>
+		<jackson-2-version>2.9.10</jackson-2-version>
+		<geniusweb.version>1.4.4</geniusweb.version>
+	</properties>
+
+	<distributionManagement>
+		<repository>
+			<id>artifactory.ewi.tudelft.nl</id>
+			<url>http://artifactory.ewi.tudelft.nl/artifactory/libs-release</url>
+		</repository>
+	</distributionManagement>
+
+
+	<dependencies>
+		<dependency>
+			<groupId>geniusweb</groupId>
+			<artifactId>party</artifactId>
+			<version>${geniusweb.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>geniusweb</groupId>
+			<artifactId>profile</artifactId>
+			<version>${geniusweb.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>geniusweb</groupId>
+			<artifactId>events</artifactId>
+			<version>${geniusweb.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>geniusweb</groupId>
+			<artifactId>timeline</artifactId>
+			<version>${geniusweb.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>geniusweb</groupId>
+			<artifactId>profileconnection</artifactId>
+			<version>${geniusweb.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>geniusweb</groupId>
+			<artifactId>bidspace</artifactId>
+			<version>${geniusweb.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>geniusweb</groupId>
+			<artifactId>opponentmodel</artifactId>
+			<version>${geniusweb.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>tudelft.utilities</groupId>
+			<artifactId>logging</artifactId>
+			<version>1.0.0</version>
+		</dependency>
+
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.12</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.mockito</groupId>
+			<artifactId>mockito-all</artifactId>
+			<version>1.9.5</version>
+			<scope>test</scope>
+		</dependency>
+
+	</dependencies>
+
+
+	<repositories>
+		<repository>
+			<id>artifactory.ewi.tudelft.nl</id>
+			<url>http://artifactory.ewi.tudelft.nl/artifactory/libs-release</url>
+			<snapshots>
+				<enabled>false</enabled>
+			</snapshots>
+		</repository>
+
+	</repositories>
+
+	<pluginRepositories>
+		<pluginRepository>
+			<id>jcenter</id>
+			<url>https://jcenter.bintray.com</url>
+		</pluginRepository>
+	</pluginRepositories>
+
+
+	<build>
+
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>3.8.0</version>
+				<configuration>
+					<source>1.8</source>
+					<target>1.8</target>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-source-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>attach-sources</id>
+						<goals>
+							<goal>jar</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-jar-plugin</artifactId>
+				<configuration>
+					<archive>
+						<manifest>
+							<mainClass>geniusweb.boa.BoaParty</mainClass>
+						</manifest>
+					</archive>
+				</configuration>
+			</plugin>
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-javadoc-plugin</artifactId>
+				<version>2.10.1</version>
+				<executions>
+					<execution>
+						<id>attach-javadocs</id>
+						<goals>
+							<goal>jar</goal>
+						</goals>
+						<configuration>
+							<additionalparam>${javadoc.opts}</additionalparam>
+							<additionalparam>-Xdoclint:none</additionalparam>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+
+			<plugin>
+				<groupId>org.jfrog.buildinfo</groupId>
+				<artifactId>artifactory-maven-plugin</artifactId>
+				<version>2.6.1</version>
+				<executions>
+					<execution>
+						<id>build-info</id>
+						<goals>
+							<goal>publish</goal>
+						</goals>
+						<configuration>
+							<publisher>
+								<contextUrl>http://artifactory.ewi.tudelft.nl/artifactory</contextUrl>
+								<repoKey>libs-release</repoKey>
+								<username>wouter</username>
+								<password>${passwd}</password>
+							</publisher>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-assembly-plugin</artifactId>
+				<version>2.4.1</version>
+				<configuration>
+					<!-- get all project dependencies -->
+					<descriptorRefs>
+						<descriptorRef>jar-with-dependencies</descriptorRef>
+					</descriptorRefs>
+					<archive>
+						<manifest>
+							<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+							<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+							<mainClass>geniusweb.boa.BoaParty</mainClass>
+						</manifest>
+					</archive>
+				</configuration>
+				<executions>
+					<execution>
+						<id>make-assembly</id>
+						<!-- bind to the packaging phase -->
+						<phase>package</phase>
+						<goals>
+							<goal>single</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+
+
+		</plugins>
+
+		<pluginManagement>
+			<plugins>
+				<plugin>
+					<groupId>org.eclipse.m2e</groupId>
+					<artifactId>lifecycle-mapping</artifactId>
+					<version>1.0.0</version>
+					<configuration>
+						<lifecycleMappingMetadata>
+							<pluginExecutions>
+								<pluginExecution>
+									<pluginExecutionFilter>
+										<groupId>org.jfrog.buildinfo</groupId>
+										<artifactId>artifactory-maven-plugin</artifactId>
+										<versionRange>[1.0.0,)</versionRange>
+										<goals>
+											<goal>publish</goal>
+										</goals>
+									</pluginExecutionFilter>
+									<action>
+										<ignore />
+									</action>
+								</pluginExecution>
+							</pluginExecutions>
+						</lifecycleMappingMetadata>
+					</configuration>
+				</plugin>
+			</plugins>
+		</pluginManagement>
+
+
+	</build>
+</project>
Index: /boa/src/main/java/geniusweb/boa/BoaParty.java
===================================================================
--- /boa/src/main/java/geniusweb/boa/BoaParty.java	(revision 20)
+++ /boa/src/main/java/geniusweb/boa/BoaParty.java	(revision 20)
@@ -0,0 +1,137 @@
+package geniusweb.boa;
+
+import java.util.HashMap;
+
+import geniusweb.actions.Action;
+import geniusweb.boa.acceptancestrategy.AcceptanceStrategy;
+import geniusweb.boa.biddingstrategy.BiddingStrategy;
+import geniusweb.opponentmodel.OpponentModel;
+import geniusweb.party.inform.Settings;
+import tudelft.utilities.logging.Reporter;
+
+/**
+ * Determines the next {@link Action} given our profile, the opponent models,
+ * the acceptance strategy and BiddingStrategy.
+ * <p>
+ * The settings are assumed to contain parameters to set the BOA components:
+ * <ul>
+ * <li>"as" containing the full.class.path to the {@link AcceptanceStrategy}
+ * clas,
+ * <li>"os" containing the full.class.path to the   {@link OpponentModel} class
+ * <li>"bs" containing the full.class.path to the   {@link BiddingStrategy}
+ * class.
+ * <li>Other parameters as needed by the components
+ * </ul>
+ * <h1>more info</h1> For more information, see: Baarslag T., Hindriks K.V.,
+ * Hendrikx M., Dirkzwager A., Jonker C.M. Decoupling Negotiating Agents to
+ * Explore the Space of Negotiation Strategies. Proceedings of The Fifth
+ * International Workshop on Agent-based Complex Automated Negotiations (ACAN
+ * 2012), 2012.
+ * https://homepages.cwi.nl/~baarslag/pub/Decoupling_Negotiating_Agents_to_Explore_the_Space_of_Negotiation_Strategies_ACAN_2012.pdf
+ * 
+ */
+public class BoaParty extends DefaultBoa {
+	public BoaParty() {
+		super();
+	}
+
+	public BoaParty(Reporter reporter) {
+		super(reporter); // for debugging
+	}
+
+	@Override
+	public String getDescription() {
+		return "BOA party that is fully configurable through parameters. "
+				+ "Takes parameters om=OpponentModel full.class.path, "
+				+ "as=AcceptanceStrategy full.class.path "
+				+ "and bs=BiddingStrategy full.class.path. ";
+	}
+
+	/**
+	 * Overridable getter for the acceptance strategy. Override if you want to
+	 * hard code a {@link BoaParty} behaviour
+	 * 
+	 * @param settings the {@link Settings}
+	 * @return the {@link OpponentModel} class to use for modeling opponents
+	 */
+	@Override
+	protected Class<? extends OpponentModel> getOpponentModel(Settings settings)
+			throws InstantiationFailedException {
+		HashMap<String, Object> parameters = settings.getParameters();
+		return loadClass("om", OpponentModel.class, parameters);
+	}
+
+	/**
+	 * Overridable getter for the acceptance strategy. Override if you want to
+	 * hard code a {@link BoaParty} behaviour
+	 * 
+	 * @param settings the {@link Settings}
+	 * @return the {@link BiddingStrategy} to use for determining the next
+	 *         {@link Action}
+	 */
+	@Override
+	protected BiddingStrategy getBiddingStrategy(Settings settings)
+			throws InstantiationFailedException {
+		try {
+			return loadClass("bs", BiddingStrategy.class,
+					settings.getParameters()).newInstance();
+		} catch (InstantiationException | IllegalAccessException e) {
+			throw new InstantiationFailedException(
+					"Can't instantiate bidding strategy", e);
+		}
+	}
+
+	/**
+	 * Overridable getter for the acceptance strategy. Override if you want to
+	 * hard code a {@link BoaParty} behaviour
+	 * 
+	 * @param settings the {@link Settings}
+	 * @return the {@link AcceptanceStrategy} to use for determining if a bid is
+	 *         acceptable
+	 */
+	@Override
+	protected AcceptanceStrategy getAccceptanceStrategy(Settings settings)
+			throws InstantiationFailedException {
+		try {
+			return loadClass("as", AcceptanceStrategy.class,
+					settings.getParameters()).newInstance();
+		} catch (InstantiationException | IllegalAccessException e) {
+			throw new InstantiationFailedException(
+					"Can't instantiate acceptance strategy", e);
+		}
+	}
+
+	/**
+	 * 
+	 * @param <T>        the type of the class object to load
+	 * @param paramname  the name of the parameter in parameters that contains
+	 *                   the class reference, shoul dbe full.clsss.path
+	 * @param clazz      the class object to load
+	 * @param parameters the parameterlist
+	 * @return object of T, loaded from the parameter with paramname
+	 * @throws ClassNotFoundException
+	 * @throws InstantiationFailedException
+	 */
+	@SuppressWarnings("unchecked")
+	private <T> Class<T> loadClass(String paramname, Class<T> clazz,
+			HashMap<String, Object> parameters)
+			throws InstantiationFailedException {
+
+		if (!parameters.containsKey(paramname))
+			throw new InstantiationFailedException(
+					"Can not load BOA component: the parameter " + paramname
+							+ " is not specified");
+		Class<?> c;
+		try {
+			c = Class.forName((String) parameters.get(paramname));
+		} catch (ClassNotFoundException e) {
+			throw new InstantiationFailedException("Unknown BOA component", e);
+		}
+		if (!clazz.isAssignableFrom(c))
+			throw new InstantiationFailedException("Parameter " + paramname
+					+ " requires an instance of  " + clazz + ", but got " + c);
+
+		return (Class<T>) c;
+	}
+
+}
Index: /boa/src/main/java/geniusweb/boa/BoaState.java
===================================================================
--- /boa/src/main/java/geniusweb/boa/BoaState.java	(revision 20)
+++ /boa/src/main/java/geniusweb/boa/BoaState.java	(revision 20)
@@ -0,0 +1,244 @@
+package geniusweb.boa;
+
+import java.lang.reflect.Parameter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import geniusweb.actions.Action;
+import geniusweb.actions.PartyId;
+import geniusweb.boa.acceptancestrategy.AcceptanceStrategy;
+import geniusweb.boa.biddingstrategy.BiddingStrategy;
+import geniusweb.issuevalue.Bid;
+import geniusweb.opponentmodel.OpponentModel;
+import geniusweb.party.inform.Settings;
+import geniusweb.profile.Profile;
+import geniusweb.progress.Progress;
+import geniusweb.progress.ProgressRounds;
+import tudelft.utilities.logging.Reporter;
+
+/**
+ * Stores the current state of the negotiation for a {@link BoaParty}, including
+ * the state of the opponent models. immutable.
+ *
+ */
+public class BoaState {
+	private final Settings settings;
+	private final Profile profile;
+	private final Progress progress;
+	private final Class<? extends OpponentModel> opponentModelClass;
+	private final Map<PartyId, OpponentModel> opponentModels;
+	private final List<Action> actionHistory;
+	private final BiddingStrategy biddingStrategy;
+	private final AcceptanceStrategy acceptanceStrategy;
+	private final Reporter reporter;
+
+	/**
+	 * Initial state. Update using with(settings).
+	 */
+	public BoaState(Reporter reporter) {
+		this(null, null, null, null, null, null, Collections.emptyList(),
+				Collections.emptyMap(), reporter);
+		if (reporter == null) {
+			throw new NullPointerException("reporter must be not null");
+		}
+	}
+
+	/**
+	 * Internal constructor. Use
+	 * {@link #with(Settings, BiddingStrategy, AcceptanceStrategy, Class, Reporter)}
+	 * 
+	 * @param settings      the negoi {@link Settings}
+	 * @param profile       the {@link Profile} to be used
+	 * @param progr         the {@link Progress}
+	 * @param bidstrat      the {@link BiddingStrategy}
+	 * @param acceptstrat   the {@link AcceptanceStrategy}
+	 * @param omClass       the class of the {@link OpponentModel}
+	 * @param actionHistory list of {@link Action}s that have been done in the
+	 *                      negotiatino (by us and others), first action is the
+	 *                      oldest.
+	 * @param oppMods       a map of {@link OpponentModel}s, one for each
+	 *                      {@link PartyId} encountered in the negotiation
+	 * @param reporter      the {@link Reporter} that can be used to log
+	 *                      messages. Should equal {@link BoaParty}'s reporter
+	 */
+	private BoaState(Settings settings, Profile profile, Progress progr,
+			BiddingStrategy bidstrat, AcceptanceStrategy acceptstrat,
+			Class<? extends OpponentModel> omClass, List<Action> actionHistory,
+			Map<PartyId, OpponentModel> oppMods, Reporter reporter) {
+		this.settings = settings;
+		this.profile = profile;
+		this.progress = progr;
+		this.biddingStrategy = bidstrat;
+		this.acceptanceStrategy = acceptstrat;
+		this.opponentModelClass = omClass;
+		this.actionHistory = actionHistory;
+		this.opponentModels = oppMods;
+		this.reporter = reporter;
+	}
+
+	/**
+	 * This should be the first update call used.
+	 * 
+	 * @param settings    the negoi {@link Settings}
+	 * @param bidstrat    the {@link BiddingStrategy}
+	 * @param acceptstrat the {@link AcceptanceStrategy}
+	 * @param omClass     the class of the {@link OpponentModel}
+	 * @param reporter    the {@link Reporter} that can be used to log messages
+	 * @return initialized BoaState
+	 */
+	public BoaState with(Settings newsettings, BiddingStrategy bidstrat,
+			AcceptanceStrategy acceptstrat,
+			Class<? extends OpponentModel> omClass) {
+		if (settings != null)
+			throw new IllegalStateException("settings already set");
+		if (newsettings == null || omClass == null || bidstrat == null
+				|| acceptstrat == null || reporter == null)
+			throw new NullPointerException(
+					"settings, reporter, bidstrat, acceptstrat, omClass and oModels must be not null");
+		return new BoaState(newsettings, null, newsettings.getProgress(),
+				bidstrat, acceptstrat, omClass, actionHistory,
+				new HashMap<PartyId, OpponentModel>(), reporter);
+	}
+
+	public BoaState with(Profile newprofile) {
+		return new BoaState(settings, newprofile, progress, biddingStrategy,
+				acceptanceStrategy, opponentModelClass, actionHistory,
+				opponentModels, reporter);
+
+	}
+
+	/**
+	 * 
+	 * @return the settings for this negotiation, includes my {@link PartyId},
+	 *         {@link Parameter}, {@link Profile} etc.
+	 */
+	public Settings getSettings() {
+		return settings;
+	}
+
+	/**
+	 * 
+	 * @return the {@link Profile} as fetched from the profiles server, or null
+	 *         if no profile was received yet.
+	 */
+	public Profile getProfile() {
+		return profile;
+	}
+
+	/**
+	 * 
+	 * @param action the action that was done by some participant (possibly us).
+	 * @return new BoaState that includes action.getBid as last bid (if action
+	 *         contains a bid), and with updated opponentmodel of that
+	 *         participant.
+	 * @throws InstantiationFailedException if one of provided classes can not
+	 *                                      be instantiated.
+	 */
+	public BoaState with(Action action) throws InstantiationFailedException {
+		List<Action> newactions = new ArrayList<Action>(actionHistory);
+		newactions.add(action);
+		Progress newprogress = progress;
+		Map<PartyId, OpponentModel> newmodels = opponentModels;
+
+		if (action.getActor().equals(settings.getID())) {
+			// ourside, just advance progress
+			if (progress instanceof ProgressRounds) {
+				// bit hacky, maybe we should wait
+				newprogress = ((ProgressRounds) progress).advance();
+			}
+		} else {
+			// not ourselves, update the OpponentModel
+			newmodels = updateModels(action);
+		}
+		return new BoaState(settings, profile, newprogress, biddingStrategy,
+				acceptanceStrategy, opponentModelClass, newactions, newmodels,
+				reporter);
+	}
+
+	/**
+	 * @return the current {@link Progress}
+	 */
+	public Progress getProgress() {
+		return progress;
+	}
+
+	/**
+	 * @return list of actions done so far, oldest action first
+	 */
+	public List<Action> getActionHistory() {
+		return Collections.unmodifiableList(actionHistory);
+	}
+
+	/**
+	 * 
+	 * @param bid
+	 * @return true iff {@link #acceptanceStrategy} says the bid is acceptable
+	 */
+	public boolean isAcceptable(Bid bid) {
+		return acceptanceStrategy.isAcceptable(bid, this);
+	}
+
+	/**
+	 * 
+	 * @return the next recommended action according to the
+	 *         {@link #biddingStrategy}
+	 */
+	public Action getAction() {
+		return biddingStrategy.getAction(this);
+	}
+
+	/**
+	 * 
+	 * @return the Reporter (same as the BoaParty's reporter)
+	 */
+	public Reporter getReporter() {
+		return reporter;
+	}
+
+	/**
+	 * @param action
+	 * @return the map with the opponentmodels, with the model for the party
+	 *         that did the action updated.
+	 * @throws InstantiationFailedException
+	 */
+	private Map<PartyId, OpponentModel> updateModels(Action action)
+			throws InstantiationFailedException {
+		PartyId actor = action.getActor();
+		Map<PartyId, OpponentModel> updated = extendedOpponentModels(actor);
+		updated.put(actor, updated.get(actor).with(action, progress));
+		return updated;
+	}
+
+	/**
+	 * Get the current opponent model, extended with newparty if there is no
+	 * model yet for newparty.
+	 * 
+	 * @param newparty a possibly new party
+	 * @return a (possibly new) opponentModels map
+	 * @throws InstantiationException
+	 * @throws IllegalAccessException
+	 * @throws InstantiationFailedException
+	 */
+	private Map<PartyId, OpponentModel> extendedOpponentModels(PartyId newparty)
+			throws InstantiationFailedException {
+		// check if this is new party
+		if (opponentModels.containsKey(newparty))
+			return opponentModels;
+
+		Map<PartyId, OpponentModel> newmodels = new HashMap<>(opponentModels);
+		OpponentModel newmodel;
+		try {
+			newmodel = opponentModelClass.newInstance()
+					.with(profile.getDomain(), profile.getReservationBid());
+		} catch (Exception e) {
+			throw new InstantiationFailedException(
+					"Failed to instantiate " + opponentModelClass, e);
+		}
+		newmodels.put(newparty, newmodel);
+		return newmodels;
+	}
+
+}
Index: /boa/src/main/java/geniusweb/boa/DefaultBoa.java
===================================================================
--- /boa/src/main/java/geniusweb/boa/DefaultBoa.java	(revision 20)
+++ /boa/src/main/java/geniusweb/boa/DefaultBoa.java	(revision 20)
@@ -0,0 +1,166 @@
+package geniusweb.boa;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.logging.Level;
+
+import geniusweb.actions.Accept;
+import geniusweb.actions.Action;
+import geniusweb.actions.Offer;
+import geniusweb.boa.acceptancestrategy.AcceptanceStrategy;
+import geniusweb.boa.biddingstrategy.BiddingStrategy;
+import geniusweb.issuevalue.Bid;
+import geniusweb.opponentmodel.OpponentModel;
+import geniusweb.party.Capabilities;
+import geniusweb.party.DefaultParty;
+import geniusweb.party.inform.ActionDone;
+import geniusweb.party.inform.Finished;
+import geniusweb.party.inform.Inform;
+import geniusweb.party.inform.Settings;
+import geniusweb.party.inform.YourTurn;
+import geniusweb.profileconnection.ProfileConnectionFactory;
+import geniusweb.profileconnection.ProfileInterface;
+import tudelft.utilities.logging.Reporter;
+
+/**
+ * Default behaviour for Boa-style parties
+ */
+public abstract class DefaultBoa extends DefaultParty {
+
+	private BoaState negoState;
+	private ProfileInterface profileint = null;
+
+	public DefaultBoa() {
+		super();
+		negoState = initialState();
+	}
+
+	public DefaultBoa(Reporter reporter) {
+		super(reporter); // for debugging
+		negoState = initialState();
+	}
+
+	/**
+	 * This only supports SAOP protocol because it is not clear how the
+	 * BiddingStrategy could be made more general without basically becoming a
+	 * full Party.
+	 * 
+	 */
+	@Override
+	public Capabilities getCapabilities() {
+		/*
+		 * At this moment only SAOP is supported by BOA. To support others, the
+		 * components also need to get capabilities
+		 */
+		return new Capabilities(new HashSet<>(Arrays.asList("SAOP")));
+	}
+
+	/**
+	 * Impementation of generic BOA behaviour.
+	 */
+	@Override
+	public void notifyChange(Inform info) {
+		try {
+			if (info instanceof Settings) {
+				/*
+				 * this should be first call. We can not yet create the state
+				 * because we need to wait for the profile fetch.
+				 */
+				Settings settings = (Settings) info;
+				Class<? extends OpponentModel> omClass = getOpponentModel(
+						settings);
+				BiddingStrategy bidStrat = getBiddingStrategy(settings);
+				AcceptanceStrategy acceptStrat = getAccceptanceStrategy(
+						settings);
+				negoState = negoState.with(settings, bidStrat, acceptStrat,
+						omClass);
+				this.profileint = ProfileConnectionFactory
+						.create(settings.getProfile().getURI(), getReporter());
+				return;
+			}
+
+			// Beyond this point we should have a profile
+			if (negoState.getProfile() == null) {
+				negoState = negoState.with(this.profileint.getProfile());
+			}
+
+			if (info instanceof ActionDone) {
+				negoState = negoState.with(((ActionDone) info).getAction());
+			} else if (info instanceof YourTurn) {
+				getConnection().send(getAction());
+				// we will receive ActionDone and update state then
+			} else if (info instanceof Finished) {
+				getReporter().log(Level.INFO, "Final ourcome:" + info);
+			}
+		} catch (Exception e) {
+			throw new RuntimeException("Failed to handle info " + info, e);
+		}
+
+	}
+
+	/**
+	 * Overridable getter for the acceptance strategy. Override if you want to
+	 * hard code a {@link BoaParty} behaviour
+	 * 
+	 * @param settings the {@link Settings}
+	 * @return the {@link OpponentModel} class to use for modeling opponents
+	 */
+	abstract protected Class<? extends OpponentModel> getOpponentModel(
+			Settings settings) throws InstantiationFailedException;
+
+	/**
+	 * Overridable getter for the acceptance strategy. Override if you want to
+	 * hard code a {@link BoaParty} behaviour
+	 * 
+	 * @param settings the {@link Settings}
+	 * @return the {@link BiddingStrategy} to use for determining the next
+	 *         {@link Action}
+	 */
+	abstract protected BiddingStrategy getBiddingStrategy(Settings settings)
+			throws InstantiationFailedException;
+
+	/**
+	 * Overridable getter for the acceptance strategy. Override if you want to
+	 * hard code a {@link BoaParty} behaviour
+	 * 
+	 * @param settings the {@link Settings}
+	 * @return the {@link AcceptanceStrategy} to use for determining if a bid is
+	 *         acceptable
+	 */
+	abstract protected AcceptanceStrategy getAccceptanceStrategy(
+			Settings settings) throws InstantiationFailedException;
+
+	/**
+	 * Factory method to create initial state. Override to insert mock
+	 * 
+	 * @return initial BoaState
+	 */
+	protected BoaState initialState() {
+		return new BoaState(getReporter());
+	}
+
+	/**
+	 * @return the most recent bid that was offered, or null if no offer has
+	 *         been done yet.
+	 */
+	protected Bid getLastBid() {
+		List<Action> actions = negoState.getActionHistory();
+		for (int n = actions.size() - 1; n >= 0; n--) {
+			Action action = actions.get(n);
+			if (action instanceof Offer) {
+				return ((Offer) action).getBid();
+			}
+		}
+		return null;
+	}
+
+	private Action getAction() {
+		Bid lastBid = getLastBid();
+		if (lastBid != null && negoState.isAcceptable(lastBid)) {
+			return new Accept(negoState.getSettings().getID(), lastBid);
+		}
+		return negoState.getAction();
+	}
+
+}
Index: /boa/src/main/java/geniusweb/boa/InstantiationFailedException.java
===================================================================
--- /boa/src/main/java/geniusweb/boa/InstantiationFailedException.java	(revision 20)
+++ /boa/src/main/java/geniusweb/boa/InstantiationFailedException.java	(revision 20)
@@ -0,0 +1,19 @@
+package geniusweb.boa;
+
+/**
+ * Failed to create instance of some class
+ *
+ */
+public class InstantiationFailedException extends Exception {
+
+	private static final long serialVersionUID = -3368583000286378339L;
+
+	public InstantiationFailedException(String string) {
+		super(string);
+	}
+
+	public InstantiationFailedException(String string, Throwable e) {
+		super(string, e);
+	}
+
+}
Index: /boa/src/main/java/geniusweb/boa/acceptancestrategy/AcceptanceStrategy.java
===================================================================
--- /boa/src/main/java/geniusweb/boa/acceptancestrategy/AcceptanceStrategy.java	(revision 20)
+++ /boa/src/main/java/geniusweb/boa/acceptancestrategy/AcceptanceStrategy.java	(revision 20)
@@ -0,0 +1,34 @@
+package geniusweb.boa.acceptancestrategy;
+
+import geniusweb.boa.BoaParty;
+import geniusweb.boa.BoaState;
+import geniusweb.issuevalue.Bid;
+import geniusweb.party.inform.Settings;
+
+/**
+ * Determines in which states a bid is acceptable. Typically used as one of the
+ * components of a {@link BoaParty}
+ * <p>
+ * <em>MUST</em> have an empty constructor.
+ */
+public interface AcceptanceStrategy {
+
+	/**
+	 * determine acceptability of a bid.
+	 * <p>
+	 * <b>Note</b> for implementors: The AcceptanceStrategy can extract
+	 * configuration parameters from {@link Settings#getParameters} using
+	 * {@link BoaState#getSettings()}. Generally we recommend to write
+	 * implementations such that they can also be hard-configured, for easier
+	 * use of the components in hard-coded settings.
+	 * 
+	 * @param bid       the bid to be checked
+	 * @param negoState the current {@link BoaState}.
+	 * 
+	 * 
+	 * @return true iff current bid is acceptable at this moment. Notice that in
+	 *         theory a protocol might allow accepting other bids than the
+	 *         latest. But at this moment only SAOP is supported by BOA.
+	 */
+	Boolean isAcceptable(Bid bid, BoaState negoState);
+}
Index: /boa/src/main/java/geniusweb/boa/acceptancestrategy/TimeDependentAcceptanceStrategy.java
===================================================================
--- /boa/src/main/java/geniusweb/boa/acceptancestrategy/TimeDependentAcceptanceStrategy.java	(revision 20)
+++ /boa/src/main/java/geniusweb/boa/acceptancestrategy/TimeDependentAcceptanceStrategy.java	(revision 20)
@@ -0,0 +1,166 @@
+package geniusweb.boa.acceptancestrategy;
+
+import java.util.HashMap;
+
+import geniusweb.bidspace.BidsWithUtility;
+import geniusweb.boa.BoaState;
+import geniusweb.boa.biddingstrategy.TimeDependentBiddingStrategy;
+import geniusweb.issuevalue.Bid;
+import geniusweb.party.inform.Settings;
+import geniusweb.profile.Profile;
+import geniusweb.profile.utilityspace.LinearAdditive;
+import geniusweb.profile.utilityspace.UtilitySpace;
+
+/**
+ * Simple implementation similar to the {@link TimeDependentBiddingStrategy}.
+ * Uses 4 parameters:
+ * <ul>
+ * <li>e: the exponent for the target-utility function. See {@link #f(double)}
+ * <li>k: the constant for the target-utility function. See {@link #f(double)}
+ * <li>max: the maximum utility target used at t=0.
+ * <li>min: the minimum utility target used at t=1
+ * </ul>
+ */
+public class TimeDependentAcceptanceStrategy implements AcceptanceStrategy {
+
+	private Double min = null, max = null, e = null, k = null;
+
+	@Override
+	public Boolean isAcceptable(Bid bid, BoaState state) {
+		if (min == null || max == null || e == null || k == null) {
+			min = getMin(state);
+			max = getMax(state);
+			e = getE(state);
+			k = getK(state);
+		}
+		double targetUtil = p(
+				state.getProgress().get(System.currentTimeMillis()));
+		// we subtract epsilon because of rounding errors in computation.
+		return ((UtilitySpace) state.getProfile()).getUtility(bid)
+				.doubleValue() >= targetUtil - 0.0000001;
+	}
+
+	/**
+	 * Overrideable for hard configuring this component.
+	 * 
+	 * @param state the {@link BoaState}
+	 * @return the parameter e for the time depemdency function
+	 *         {@link #f(double)}. The parameter is 1 by default, or the value
+	 *         for the "e" parameter in the {@link Settings} if available.
+	 */
+	protected Double getE(BoaState state) {
+		HashMap<String, Object> params = state.getSettings().getParameters();
+		Double e = 1d;
+		if (params.containsKey("e")) {
+			e = (Double) params.get("e");
+			if (e < 0 || e > 1)
+				throw new IllegalArgumentException(
+						"e must be in [0,1] but got " + this.e);
+		}
+		return e;
+	}
+
+	/**
+	 * Overrideable for hard configuring this component.
+	 * 
+	 * @param state the {@link BoaState}
+	 * @return the parameter k for the time depemdency function
+	 *         {@link #f(double)}. The parameter is 0 by default, or the value
+	 *         for the "k" parameter in the {@link Settings} if available.
+	 */
+	protected Double getK(BoaState state) {
+		HashMap<String, Object> params = state.getSettings().getParameters();
+		Double k = 0d; // default
+		if (params.containsKey("k")) {
+			k = (Double) params.get("k");
+			if (k < 0 || k > 1)
+				throw new IllegalArgumentException(
+						"k must be in [0,1] but got " + this.e);
+		}
+		return k;
+	}
+
+	/**
+	 * Overrideable for hard configuring this component.
+	 * 
+	 * @param state the {@link BoaState}
+	 * @return the min value for {@link #p(double)}. We use the "min" parameter
+	 *         in the {@link Settings} if available. If not available, the
+	 *         parameter is computed as the utility of the reservation bid. If
+	 *         there is no reservation bid, we use the minimum utility of the
+	 *         available profile.
+	 */
+	protected Double getMin(BoaState state) {
+		HashMap<String, Object> params = state.getSettings().getParameters();
+		if (params.containsKey("min")) {
+			return Math.max(0f, Math.min(1f, (Double) params.get("min")));
+		}
+		UtilitySpace profile = (UtilitySpace) state.getProfile();
+		if (profile.getReservationBid() != null) {
+			return profile.getUtility(profile.getReservationBid())
+					.doubleValue();
+		}
+
+		return getBidspace(profile).getRange().getMin().doubleValue();
+	}
+
+	/**
+	 * Overrideable for hard configuring this component.
+	 * 
+	 * @param state the {@link BoaState}
+	 * @return the max value for {@link #p(double)}. We use the "max" parameter
+	 *         in the {@link Settings} if available. If not available, we use
+	 *         the maximum utility of the available profile.
+	 */
+	protected Double getMax(BoaState state) {
+		HashMap<String, Object> params = state.getSettings().getParameters();
+		if (params.containsKey("max")) {
+			return Math.max(0f, Math.min(1f, (Double) params.get("max")));
+		}
+		UtilitySpace profile = (UtilitySpace) state.getProfile();
+		return getBidspace(profile).getRange().getMax().doubleValue();
+
+	}
+
+	/**
+	 * factory method. Overridable for testing
+	 * 
+	 * @param profile the profile to get a bidspace for
+	 * @return {@link BidsWithUtility}
+	 */
+	protected BidsWithUtility getBidspace(Profile profile) {
+		return new BidsWithUtility((LinearAdditive) profile);
+	}
+
+	/**
+	 * Makes sure the target utility with in the acceptable range according to
+	 * the domain
+	 * 
+	 * @param t the normalized current time in the negotiation, where t=9 at
+	 *          start of negotiation and t=1 at end of negotiation.
+	 * @return double
+	 */
+	private double p(double t) {
+		return this.min + (this.max - this.min) * (1.0 - f(t));
+	}
+
+	/**
+	 * From the paper:
+	 * 
+	 * A wide range of time dependent functions can be defined by varying the
+	 * way in which f(t) is computed. However, functions must ensure that 0 <=
+	 * f(t) <= 1, f(0) = k, and f(1) = 1.
+	 * 
+	 * That is, the offer will always be between the value range, at the
+	 * beginning it will give the initial constant and when the deadline is
+	 * reached, it will offer the reservation value.
+	 * 
+	 * @param t the normalized current time in the negotiation, where t=9 at
+	 *          start of negotiation and t=1 at end of negotiation.
+	 * @return
+	 */
+	private double f(double t) {
+		return k + (1.0 - k) * Math.pow(t, 1.0 / e);
+	}
+
+}
Index: /boa/src/main/java/geniusweb/boa/biddingstrategy/BiddingStrategy.java
===================================================================
--- /boa/src/main/java/geniusweb/boa/biddingstrategy/BiddingStrategy.java	(revision 20)
+++ /boa/src/main/java/geniusweb/boa/biddingstrategy/BiddingStrategy.java	(revision 20)
@@ -0,0 +1,34 @@
+package geniusweb.boa.biddingstrategy;
+
+import geniusweb.actions.Action;
+import geniusweb.boa.BoaParty;
+import geniusweb.boa.BoaState;
+import geniusweb.party.inform.Settings;
+
+/**
+ * Determines what action to take in which state.
+ * <p>
+ * Assumed part of a {@link BoaParty}.
+ * 
+ * <p>
+ * <em>MUST</em> have an empty constructor.
+ */
+public interface BiddingStrategy {
+
+	/**
+	 * Recommend a next action.
+	 * <p>
+	 * <b>Note</b> for implementors: This can extract configuration parameters
+	 * from {@link Settings#getParameters} using {@link BoaState#getSettings()}.
+	 * Generally we recommend to write implementations such that they can also
+	 * be hard-configured, for easier use of the components in hard-coded
+	 * settings.
+	 * 
+	 * @param state the current {@link BoaState}
+	 * 
+	 * @return the suggested next Action. Should always return a valid action,
+	 *         not null.
+	 */
+	Action getAction(BoaState state);
+
+}
Index: /boa/src/main/java/geniusweb/boa/biddingstrategy/ExtendedUtilSpace.java
===================================================================
--- /boa/src/main/java/geniusweb/boa/biddingstrategy/ExtendedUtilSpace.java	(revision 20)
+++ /boa/src/main/java/geniusweb/boa/biddingstrategy/ExtendedUtilSpace.java	(revision 20)
@@ -0,0 +1,103 @@
+package geniusweb.boa.biddingstrategy;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Collections;
+import java.util.LinkedList;
+
+import geniusweb.bidspace.BidsWithUtility;
+import geniusweb.bidspace.Interval;
+import geniusweb.bidspace.IssueInfo;
+import geniusweb.issuevalue.Bid;
+import geniusweb.issuevalue.Value;
+import geniusweb.profile.utilityspace.LinearAdditive;
+import tudelft.utilities.immutablelist.ImmutableList;
+
+/**
+ * Inner class for TimeDependentParty, made public for testing purposes. This
+ * class may change in the future, use at your own risk. Copy of
+ * geniusweb.exampleparties.timedependentparty
+ *
+ */
+public class ExtendedUtilSpace {
+	private LinearAdditive utilspace;
+	private BigDecimal tolerance; // utility tolerance for a bid.
+	private BidsWithUtility bidutils;
+	// min and max achievable utility
+	private BigDecimal minUtil;
+	private BigDecimal maxUtil;
+
+	public ExtendedUtilSpace(LinearAdditive space) {
+		this.utilspace = space;
+		bidutils = new BidsWithUtility(utilspace);
+		computeMinMax();
+		this.tolerance = computeTolerance();
+
+	}
+
+	/**
+	 * Computes the fields minutil and maxUtil.
+	 * <p>
+	 * TODO this is simplistic, very expensive method and may cause us to run
+	 * out of time on large domains.
+	 * <p>
+	 * Assumes that utilspace and bidutils have been set properly.
+	 */
+	private void computeMinMax() {
+		Interval range = bidutils.getRange();
+		this.minUtil = range.getMin();
+		this.maxUtil = range.getMax();
+
+		Bid rvbid = utilspace.getReservationBid();
+		if (rvbid != null) {
+			BigDecimal rv = utilspace.getUtility(rvbid);
+			if (rv.compareTo(minUtil) > 0)
+				minUtil = rv;
+		}
+	}
+
+	/**
+	 * Tolerance is the Interval we need when searching bids. When we are close
+	 * to the maximum utility, this value has to be the distance between the
+	 * best and one-but-best utility.
+	 * 
+	 * @return the minimum tolerance required, which is the minimum difference
+	 *         between the weighted utility of the best and one-but-best issue
+	 *         value.
+	 */
+	protected BigDecimal computeTolerance() {
+		BigDecimal tolerance = BigDecimal.ONE;
+		for (IssueInfo iss : bidutils.getInfo()) {
+			if (iss.getValues().size().compareTo(BigInteger.ONE) > 0) {
+				// we have at least 2 values.
+				LinkedList<BigDecimal> values = new LinkedList<BigDecimal>();
+				for (Value val : iss.getValues()) {
+					values.add(iss.getWeightedUtil(val));
+				}
+				Collections.sort(values);
+				Collections.reverse(values);
+				tolerance = tolerance
+						.min(values.get(0).subtract(values.get(1)));
+			}
+		}
+		return tolerance;
+	}
+
+	public BigDecimal getMin() {
+		return minUtil;
+	}
+
+	public BigDecimal getMax() {
+		return maxUtil;
+	}
+
+	/**
+	 * @param utilityGoal
+	 * @return bids with utility inside [utilitygoal-tolerance, utilitygoal]
+	 */
+	public ImmutableList<Bid> getBids(BigDecimal utilityGoal) {
+		return bidutils.getBids(
+				new Interval(utilityGoal.subtract(tolerance), utilityGoal));
+	}
+
+}
Index: /boa/src/main/java/geniusweb/boa/biddingstrategy/TimeDependentBiddingStrategy.java
===================================================================
--- /boa/src/main/java/geniusweb/boa/biddingstrategy/TimeDependentBiddingStrategy.java	(revision 20)
+++ /boa/src/main/java/geniusweb/boa/biddingstrategy/TimeDependentBiddingStrategy.java	(revision 20)
@@ -0,0 +1,251 @@
+package geniusweb.boa.biddingstrategy;
+
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.logging.Level;
+
+import geniusweb.actions.Accept;
+import geniusweb.actions.Action;
+import geniusweb.actions.EndNegotiation;
+import geniusweb.actions.Offer;
+import geniusweb.actions.PartyId;
+import geniusweb.boa.BoaState;
+import geniusweb.issuevalue.Bid;
+import geniusweb.party.inform.Settings;
+import geniusweb.profile.Profile;
+import geniusweb.profile.utilityspace.LinearAdditive;
+import tudelft.utilities.immutablelist.ImmutableList;
+
+/**
+ * This is an abstract class used to implement a TimeDependentAgent Strategy
+ * adapted from S. Shaheen Fatima Michael Wooldridge Nicholas R. Jennings
+ * Optimal Negotiation Strategies for Agents with Incomplete Information
+ * http://eprints.ecs.soton.ac.uk/6151/1/atal01.pdf
+ * <p>
+ * Required: the profile is {@link LinearAdditive}. Does not currently handle
+ * profile changes.
+ * <p>
+ * As basis, the original Genius'
+ * negotiator.boaframework.offeringstrategy.other.GeniusTimeDependent_Offering
+ * was used. However that seems to ignore the reservation value. This was fixed
+ * here.
+ * <p>
+ * The default strategy was extended to enable the usage of opponent models.
+ * <p>
+ * The time-dependent utility target function is f(t) = k + (1.0 - k) *
+ * Math.pow((t - startTime) / (1.0 - startTime), 1.0 / e). The utility target is
+ * then set at min+(max-min)*f(t) where the default values for min = either the
+ * utility of the reservation bid or the absolute minimum utility of the
+ * profile, and default for max the maximum attainable utility.
+ * <p>
+ * 
+ * Parameters:
+ * <ul>
+ * <li>e: see {@link #getE(BoaState)}
+ * <li>k: see {@link #getK(BoaState)}
+ * <li>min: see {@link #getMin(BoaState)}.
+ * <li>max: see {@link #getMax(BoaState)}
+ * </ul>
+ */
+public class TimeDependentBiddingStrategy implements BiddingStrategy {
+	// bidSpace=null means we're not yet initialized.
+	private ExtendedUtilSpace bidSpace = null;
+	private Double e, k, min, max; // min, max attainable utility
+	private PartyId me;
+
+	@Override
+	public Action getAction(BoaState state) {
+		if (bidSpace == null) {
+			init(state);
+		}
+
+		double utilityGoal = p(
+				state.getProgress().get(System.currentTimeMillis()));
+
+		// if there is no opponent model available
+		ImmutableList<Bid> bidOptions = bidSpace
+				.getBids((BigDecimal.valueOf(utilityGoal)));
+
+		if (bidOptions.size().intValue() == 0) {
+			// should not happen, emergency exit
+			state.getReporter().log(Level.WARNING,
+					"No viable bids found around current utility target");
+			Bid lastBid = getLastBid(state.getActionHistory());
+			if (lastBid == null)
+				return new EndNegotiation(me);
+			return new Accept(me, lastBid);
+		}
+		Bid pickedBid = bidOptions.get(ThreadLocalRandom.current()
+				.nextInt(bidOptions.size().intValue()));
+		return new Offer(me, pickedBid);
+
+	}
+
+	/**
+	 * Overrideable for hard configuring this component.
+	 * 
+	 * @param state the {@link BoaState}
+	 * @return the parameter e for the time depemdency function
+	 *         {@link #f(double)}. The parameter is 1 by default, or the value
+	 *         for the "e" parameter in the {@link Settings} if available.
+	 */
+	protected Double getE(BoaState state) {
+		HashMap<String, Object> params = state.getSettings().getParameters();
+		Double e = 1d;
+		if (params.containsKey("e")) {
+			e = (Double) params.get("e");
+			if (e < 0 || e > 1)
+				throw new IllegalArgumentException(
+						"e must be in [0,1] but got " + this.e);
+		}
+		return e;
+	}
+
+	/**
+	 * Overrideable for hard configuring this component.
+	 * 
+	 * @param state the {@link BoaState}
+	 * @return the parameter k for the time depemdency function
+	 *         {@link #f(double)}. The parameter is 0 by default, or the value
+	 *         for the "k" parameter in the {@link Settings} if available.
+	 */
+	protected Double getK(BoaState state) {
+		HashMap<String, Object> params = state.getSettings().getParameters();
+		Double k = 0d; // default
+		if (params.containsKey("k")) {
+			k = (Double) params.get("k");
+			if (k < 0 || k > 1)
+				throw new IllegalArgumentException(
+						"k must be in [0,1] but got " + this.e);
+		}
+		return k;
+	}
+
+	/**
+	 * Assumes {@link #bidSpace} has been initialized.
+	 * <p>
+	 * Overrideable for hard configuring this component.
+	 * 
+	 * @param state the {@link BoaState}
+	 * @return the min value for {@link #p(double)}. We use the "min" parameter
+	 *         in the {@link Settings} if available. If not available, the
+	 *         parameter is computed as the utility of the reservation bid. If
+	 *         there is no reservation bid, we use the minimum utility of the
+	 *         available profile.
+	 */
+	protected Double getMin(BoaState state) {
+		HashMap<String, Object> params = state.getSettings().getParameters();
+		if (params.containsKey("min")) {
+			return Math.max(0f, Math.min(1f, (Double) params.get("min")));
+		}
+		LinearAdditive profile = (LinearAdditive) state.getProfile();
+		if (profile.getReservationBid() != null) {
+			return profile.getUtility(profile.getReservationBid())
+					.doubleValue();
+		}
+
+		return bidSpace.getMin().doubleValue();
+	}
+
+	/**
+	 * Assumes {@link #bidSpace} has been initialized.
+	 * <p>
+	 * Overrideable for hard configuring this component.
+	 * 
+	 * @param state the {@link BoaState}
+	 * @return the max value for {@link #p(double)}. We use the "max" parameter
+	 *         in the {@link Settings} if available. If not available, we use
+	 *         the maximum utility of the available profile.
+	 */
+	protected Double getMax(BoaState state) {
+		HashMap<String, Object> params = state.getSettings().getParameters();
+		if (params.containsKey("max")) {
+			return Math.max(0f, Math.min(1f, (Double) params.get("max")));
+		}
+		return bidSpace.getMax().doubleValue();
+
+	}
+
+	/**
+	 * @return the most recent bid that was offered, or null if no offer has
+	 *         been done yet.
+	 */
+	private Bid getLastBid(List<Action> history) {
+		for (int n = history.size() - 1; n >= 0; n--) {
+			Action action = history.get(n);
+			if (action instanceof Offer) {
+				return ((Offer) action).getBid();
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * initializes bidSpace
+	 * 
+	 * @param state
+	 */
+	private void init(BoaState state) {
+		this.me = state.getSettings().getID();
+		Profile prof = state.getProfile();
+		if (!(prof instanceof LinearAdditive))
+			throw new IllegalArgumentException(
+					"Requires a LinearAdditive space but got " + prof);
+		LinearAdditive profile = (LinearAdditive) prof;
+
+		this.bidSpace = getBidSpace(profile);
+		this.e = getE(state);
+		this.k = getK(state);
+		this.min = getMin(state);
+		this.max = getMax(state);
+
+		state.getReporter().log(Level.INFO,
+				"BOA biddingstrategy min util = " + this.min);
+	}
+
+	/**
+	 * Makes sure the target utility with in the acceptable range according to
+	 * the domain
+	 * 
+	 * @param t the normalized current time in the negotiation, where t=9 at
+	 *          start of negotiation and t=1 at end of negotiation.
+	 * @return double
+	 */
+	private double p(double t) {
+		return this.min + (this.max - this.min) * (1.0 - f(t));
+	}
+
+	/**
+	 * From the paper:
+	 * 
+	 * A wide range of time dependent functions can be defined by varying the
+	 * way in which f(t) is computed. However, functions must ensure that 0 <=
+	 * f(t) <= 1, f(0) = k, and f(1) = 1.
+	 * 
+	 * That is, the offer will always be between the value range, at the
+	 * beginning it will give the initial constant and when the deadline is
+	 * reached, it will offer the reservation value.
+	 * 
+	 * @param t the normalized current time in the negotiation, where t=9 at
+	 *          start of negotiation and t=1 at end of negotiation.
+	 * @return
+	 */
+	private double f(double t) {
+		double ft = k + (1.0 - k) * Math.pow(t, 1.0 / e);
+		return ft;
+	}
+
+	/**
+	 * Factory method to get the {@link ExtendedUtilSpace} helper class.
+	 * Overridable eg for tests
+	 * 
+	 * @param profile
+	 * 
+	 * @return {@link ExtendedUtilSpace}
+	 */
+	protected ExtendedUtilSpace getBidSpace(LinearAdditive profile) {
+		return new ExtendedUtilSpace(profile);
+	}
+}
Index: /boa/src/test/java/geniusweb/boa/BoaPartyTest.java
===================================================================
--- /boa/src/test/java/geniusweb/boa/BoaPartyTest.java	(revision 20)
+++ /boa/src/test/java/geniusweb/boa/BoaPartyTest.java	(revision 20)
@@ -0,0 +1,235 @@
+package geniusweb.boa;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.junit.Test;
+
+import geniusweb.actions.Accept;
+import geniusweb.actions.Action;
+import geniusweb.actions.EndNegotiation;
+import geniusweb.actions.Offer;
+import geniusweb.actions.PartyId;
+import geniusweb.boa.acceptancestrategy.AcceptanceStrategy;
+import geniusweb.boa.biddingstrategy.BiddingStrategy;
+import geniusweb.connection.ConnectionEnd;
+import geniusweb.issuevalue.Bid;
+import geniusweb.issuevalue.DiscreteValue;
+import geniusweb.issuevalue.Domain;
+import geniusweb.opponentmodel.OpponentModel;
+import geniusweb.party.inform.ActionDone;
+import geniusweb.party.inform.Inform;
+import geniusweb.party.inform.Settings;
+import geniusweb.party.inform.YourTurn;
+import geniusweb.progress.Progress;
+import geniusweb.references.Parameters;
+import geniusweb.references.ProfileRef;
+import geniusweb.references.ProtocolRef;
+import geniusweb.references.Reference;
+import tudelft.utilities.listener.DefaultListenable;
+
+public class BoaPartyTest {
+	private static final Bid otherBid = new Bid("issue",
+			new DiscreteValue("value2"));
+	private static final PartyId OTHER = new PartyId("other");
+	private static final Bid BID1 = new Bid("issue",
+			new DiscreteValue("value"));
+	private static final PartyId ME = new PartyId("me");
+	private TestConnection connection = new TestConnection();
+	private static final String PROFILE = "src/test/resources/testprofile.json";
+
+	protected static final Offer biddingstratOffer = new Offer(ME, BID1);
+	private static final Offer othersOffer = new Offer(OTHER, otherBid);
+	private static final Accept accept = new Accept(ME, BID1);
+	private static final EndNegotiation endnego = new EndNegotiation(OTHER);
+
+	@Test(expected = RuntimeException.class)
+	public void smokeTestMissingInit() {
+		BoaParty boa = new BoaParty();
+		boa.connect(connection);
+		boa.notifyChange(mock(ActionDone.class));
+	}
+
+	@Test
+	public void settingsTest() throws URISyntaxException {
+		BoaState state = mock(BoaState.class);
+		BoaParty boa = new BoaParty() {
+			@Override
+			protected BoaState initialState() {
+				return state;
+			}
+		};
+		boa.connect(connection);
+		PartyId id = new PartyId("testparty");
+		ProfileRef profile = new ProfileRef(new URI("file:" + PROFILE));
+		ProtocolRef protocol = new ProtocolRef("SAOP");
+		Progress progress = mock(Progress.class);
+		Parameters parameters = new Parameters();
+		parameters.put("om", omMock.class.getCanonicalName());
+		parameters.put("bs", bsMock.class.getCanonicalName());
+		parameters.put("as", asMock.class.getCanonicalName());
+		Settings info = new Settings(id, profile, protocol, progress,
+				parameters);
+		boa.notifyChange(info);
+		// weird bug in Mockito? Work around with a weird cast...
+		verify(state).with((Settings) eq(info), any(bsMock.class),
+				any(asMock.class), (Class) eq(omMock.class));
+	}
+
+	@Test
+	public void youStartTestE2E() throws URISyntaxException {
+		BoaParty boa = getInitializedBoa();
+
+		boa.notifyChange(new YourTurn());
+		assertEquals(1, connection.getActions().size());
+		System.out.println("party did action:" + connection.getActions());
+		// this should come out of bidding strat as there is no acceptable offer
+		assertEquals(biddingstratOffer, connection.getActions().get(0));
+	}
+
+	@Test
+	public void otherOfferstTestE2E() throws URISyntaxException {
+		BoaParty boa = getInitializedBoa();
+
+		boa.notifyChange(new ActionDone(othersOffer));
+
+		boa.notifyChange(new YourTurn());
+		assertEquals(1, connection.getActions().size());
+		System.out.println("party did action:" + connection.getActions());
+		// this should come out of bidding strat as there is no acceptable offer
+		// Because asMock always accepts, this should accept.
+		assertTrue(connection.getActions().get(0) instanceof Accept);
+	}
+
+	@Test
+	public void getLastBidTest() throws URISyntaxException {
+		BoaParty boa = getInitializedBoa();
+
+		// just a potpourri of actions.
+		boa.notifyChange(new ActionDone(biddingstratOffer));
+		boa.notifyChange(new ActionDone(endnego));
+		boa.notifyChange(new ActionDone(othersOffer));
+		boa.notifyChange(new ActionDone(accept));
+		assertEquals(otherBid, boa.getLastBid());
+
+	}
+
+	private BoaParty getInitializedBoa() throws URISyntaxException {
+		BoaParty boa = new BoaParty();
+		boa.connect(connection);
+		PartyId id = new PartyId("testparty");
+		ProfileRef profile = new ProfileRef(new URI("file:" + PROFILE));
+		ProtocolRef protocol = new ProtocolRef("SAOP");
+		Progress progress = mock(Progress.class);
+		Parameters parameters = new Parameters();
+		parameters.put("om", omMock.class.getCanonicalName());
+		parameters.put("bs", bsMock.class.getCanonicalName());
+		parameters.put("as", asMock.class.getCanonicalName());
+		Settings info = new Settings(id, profile, protocol, progress,
+				parameters);
+		boa.notifyChange(info);
+		return boa;
+	}
+
+}
+
+class asMock implements AcceptanceStrategy {
+
+	@Override
+	public Boolean isAcceptable(Bid bid, BoaState negoState) {
+		return true;
+	}
+
+}
+
+class bsMock implements BiddingStrategy {
+
+	@Override
+	public Action getAction(BoaState state) {
+		return BoaPartyTest.biddingstratOffer;
+	}
+
+}
+
+class omMock implements OpponentModel {
+
+	@Override
+	public String getName() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Domain getDomain() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Bid getReservationBid() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public OpponentModel with(Domain domain, Bid resBid) {
+		return this;
+	}
+
+	@Override
+	public OpponentModel with(Action action, Progress progress) {
+		return this;
+	}
+
+}
+
+/**
+ * A "real" connection object, because the party is going to subscribe etc, and
+ * without a real connection we would have to do a lot of mocks that would make
+ * the test very hard to read.
+ *
+ */
+class TestConnection extends DefaultListenable<Inform>
+		implements ConnectionEnd<Inform, Action> {
+	private List<Action> actions = new LinkedList<>();
+
+	@Override
+	public void send(Action action) throws IOException {
+		actions.add(action);
+	}
+
+	@Override
+	public Reference getReference() {
+		return null;
+	}
+
+	@Override
+	public URI getRemoteURI() {
+		return null;
+	}
+
+	@Override
+	public void close() {
+
+	}
+
+	@Override
+	public Error getError() {
+		return null;
+	}
+
+	public List<Action> getActions() {
+		return actions;
+	}
+
+}
Index: /boa/src/test/java/geniusweb/boa/BoaStateTest.java
===================================================================
--- /boa/src/test/java/geniusweb/boa/BoaStateTest.java	(revision 20)
+++ /boa/src/test/java/geniusweb/boa/BoaStateTest.java	(revision 20)
@@ -0,0 +1,5 @@
+package geniusweb.boa;
+
+public class BoaStateTest {
+
+}
Index: /boa/src/test/java/geniusweb/boa/acceptancestrategy/TimeDepAccStratTest.java
===================================================================
--- /boa/src/test/java/geniusweb/boa/acceptancestrategy/TimeDepAccStratTest.java	(revision 20)
+++ /boa/src/test/java/geniusweb/boa/acceptancestrategy/TimeDepAccStratTest.java	(revision 20)
@@ -0,0 +1,131 @@
+package geniusweb.boa.acceptancestrategy;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.math.BigDecimal;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import geniusweb.bidspace.BidsWithUtility;
+import geniusweb.bidspace.Interval;
+import geniusweb.boa.BoaState;
+import geniusweb.issuevalue.Bid;
+import geniusweb.party.inform.Settings;
+import geniusweb.profile.Profile;
+import geniusweb.profile.utilityspace.LinearAdditive;
+import geniusweb.progress.Progress;
+import geniusweb.progress.ProgressRounds;
+
+public class TimeDepAccStratTest {
+	private static final Bid resbid = mock(Bid.class);
+	private final Progress progress = mock(ProgressRounds.class);
+	private final BidsWithUtility testbidspace = mock(BidsWithUtility.class);
+	private final BoaState state = mock(BoaState.class);
+	private final Bid bid1 = mock(Bid.class);
+	private final Settings settings = mock(Settings.class);
+	private final LinearAdditive linearprofile = mock(LinearAdditive.class);
+
+	@Before
+	public void before() {
+		when(state.getSettings()).thenReturn(settings);
+		when(state.getProfile()).thenReturn(linearprofile);
+		when(state.getProgress()).thenReturn(progress);
+
+	}
+
+	@Test
+	public void testRoundsProgressAtStart() {
+		when(testbidspace.getRange())
+				.thenReturn(new Interval(BigDecimal.ZERO, BigDecimal.ONE));
+
+		TimeDependentAcceptanceStrategy ac = new TimeDependentAcceptanceStrategy() {
+			protected BidsWithUtility getBidspace(Profile profile) {
+				return testbidspace;
+			}
+		};
+		// we use default e=1, k=0 which means p(0)=1
+
+		when(progress.get(any())).thenReturn((Double) 0.0d);
+
+		when(linearprofile.getUtility(eq(bid1)))
+				.thenReturn(BigDecimal.valueOf(0.4));
+
+		assertFalse(ac.isAcceptable(bid1, state));
+	}
+
+	@Test
+	public void testRoundsProgressAtStart1() {
+		when(testbidspace.getRange()).thenReturn(
+				new Interval(BigDecimal.ZERO, new BigDecimal("0.4")));
+		// the max util in this space is 0.4
+
+		TimeDependentAcceptanceStrategy ac = new TimeDependentAcceptanceStrategy() {
+			protected BidsWithUtility getBidspace(Profile profile) {
+				return testbidspace;
+			}
+		};
+		// we use default e=1, k=0 which means p(0)=1
+
+		when(progress.get(any())).thenReturn((Double) 0.0d);
+
+		when(linearprofile.getUtility(eq(bid1)))
+				.thenReturn(new BigDecimal("0.4")); // now =max util
+
+		assertTrue(ac.isAcceptable(bid1, state));
+	}
+
+	@Test
+	public void testRoundsProgressAtEnd() {
+		when(testbidspace.getRange())
+				.thenReturn(new Interval(BigDecimal.ZERO, BigDecimal.ONE));
+
+		TimeDependentAcceptanceStrategy ac = new TimeDependentAcceptanceStrategy() {
+			protected BidsWithUtility getBidspace(Profile profile) {
+				return testbidspace;
+			}
+		};
+		// we use default e=1, k=0 which means p(1)=0
+
+		when(progress.get(any())).thenReturn((Double) 1.0d);
+
+		when(linearprofile.getUtility(eq(bid1)))
+				.thenReturn(BigDecimal.valueOf(0.4));
+
+		assertTrue(ac.isAcceptable(bid1, state));
+	}
+
+	@Test
+	public void testRoundsProgressResValueIsUsed() {
+		// resbid should raise the minimum at the end.
+		// we check that at the end a bid with lower util than resbid is
+		// not accepted.
+		when(testbidspace.getRange())
+				.thenReturn(new Interval(BigDecimal.ZERO, BigDecimal.ONE));
+
+		TimeDependentAcceptanceStrategy ac = new TimeDependentAcceptanceStrategy() {
+			protected BidsWithUtility getBidspace(Profile profile) {
+				return testbidspace;
+			}
+		};
+		// we use default e=1, k=0 which means p(1)=resValue.
+
+		when(progress.get(any())).thenReturn((Double) 1.0d);
+
+		when(linearprofile.getUtility(eq(bid1)))
+				.thenReturn(BigDecimal.valueOf(0.4));
+
+		when(linearprofile.getReservationBid()).thenReturn(resbid);
+		when(linearprofile.getUtility(eq(resbid)))
+				.thenReturn(new BigDecimal("0.5"));
+
+		// bid1 has util 0.4 which is below res value.
+		assertFalse(ac.isAcceptable(bid1, state));
+	}
+
+}
Index: /boa/src/test/java/geniusweb/boa/biddingstrategy/TimeDepBidStratTest.java
===================================================================
--- /boa/src/test/java/geniusweb/boa/biddingstrategy/TimeDepBidStratTest.java	(revision 20)
+++ /boa/src/test/java/geniusweb/boa/biddingstrategy/TimeDepBidStratTest.java	(revision 20)
@@ -0,0 +1,155 @@
+package geniusweb.boa.biddingstrategy;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.math.BigDecimal;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import geniusweb.actions.Action;
+import geniusweb.actions.Offer;
+import geniusweb.boa.BoaState;
+import geniusweb.issuevalue.Bid;
+import geniusweb.issuevalue.DiscreteValue;
+import geniusweb.party.inform.Settings;
+import geniusweb.profile.utilityspace.LinearAdditive;
+import geniusweb.progress.Progress;
+import tudelft.utilities.immutablelist.FixedList;
+import tudelft.utilities.immutablelist.ImmutableList;
+import tudelft.utilities.logging.ReportToLogger;
+
+public class TimeDepBidStratTest {
+
+	// private static final String PROFILE =
+	// "src/test/resources/testprofile.json";
+	// private ProfileRef profileref;
+	private LinearAdditive profile = mock(LinearAdditive.class);
+	private TimeDependentBiddingStrategy biddingstrat;
+	private ExtendedUtilSpace extUtilSpace;
+	private Settings settings = mock(Settings.class);
+	private BoaState state = mock(BoaState.class);
+
+	private Bid bid1 = new Bid("iss1", new DiscreteValue("val1"));
+	private Bid resBid = new Bid("iss1", new DiscreteValue("val2"));
+	ImmutableList<Bid> alternatives = new FixedList<Bid>(Arrays.asList(bid1));
+
+	@Before
+	public void before() throws URISyntaxException {
+		when(state.getReporter()).thenReturn(new ReportToLogger("test"));
+
+		biddingstrat = new TimeDependentBiddingStrategy() {
+			protected ExtendedUtilSpace getBidSpace(LinearAdditive profile) {
+				return extUtilSpace;
+			}
+
+		};
+		// profileref = new ProfileRef(PROFILE);
+
+		extUtilSpace = mock(ExtendedUtilSpace.class);
+		when(extUtilSpace.getMin()).thenReturn(BigDecimal.ZERO);
+		when(extUtilSpace.getMax()).thenReturn(BigDecimal.ONE);
+
+	}
+
+	@Test
+	public void smoke() {
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void getActionTestNoProfile() {
+		when(state.getSettings()).thenReturn(settings);
+
+		biddingstrat.getAction(state);
+	}
+
+	@Test
+	public void getActionAtStart() {
+
+		when(state.getProfile()).thenReturn(profile);
+		when(state.getSettings()).thenReturn(settings);
+
+		Progress progress = mock(Progress.class);
+		when(progress.get(any())).thenReturn(0d);
+		// progress = right at start => utilitygoal 1.0
+
+		when(state.getProgress()).thenReturn(progress);
+		when(extUtilSpace.getBids(any())).thenReturn(alternatives);
+
+		Action action = biddingstrat.getAction(state);
+
+		// check that the recommender chose a bid in of utility 1.0
+		verify(extUtilSpace).getBids(BigDecimal.valueOf(1.0));
+		assertTrue(action instanceof Offer);
+	}
+
+	@Test
+	public void getActionAtHalfway() {
+
+		when(state.getProfile()).thenReturn(profile);
+		when(state.getSettings()).thenReturn(settings);
+
+		Progress progress = mock(Progress.class);
+		when(progress.get(any())).thenReturn(0.5d);
+		// progress = halfway => utilitygoal= 0.5
+
+		when(state.getProgress()).thenReturn(progress);
+		when(extUtilSpace.getBids(any())).thenReturn(alternatives);
+
+		Action action = biddingstrat.getAction(state);
+
+		// check that the recommender chose a bid in of utility 1.0
+		verify(extUtilSpace).getBids(BigDecimal.valueOf(0.5));
+		assertTrue(action instanceof Offer);
+	}
+
+	@Test
+	public void getActionAtEnd() {
+
+		when(state.getProfile()).thenReturn(profile);
+		when(state.getSettings()).thenReturn(settings);
+
+		Progress progress = mock(Progress.class);
+		when(progress.get(any())).thenReturn(1d);
+		// progress = end => utilitygoal= 0
+
+		when(state.getProgress()).thenReturn(progress);
+		when(extUtilSpace.getBids(any())).thenReturn(alternatives);
+
+		Action action = biddingstrat.getAction(state);
+
+		// check that the recommender chose a bid in of utility 1.0
+		verify(extUtilSpace).getBids(BigDecimal.valueOf(0.0));
+		assertTrue(action instanceof Offer);
+	}
+
+	@Test
+	public void getActionAtEndWithReservation() {
+		// if there is reservation bid, it should be considered min
+		when(profile.getReservationBid()).thenReturn(resBid);
+		when(profile.getUtility(resBid)).thenReturn(new BigDecimal("0.5"));
+
+		when(state.getProfile()).thenReturn(profile);
+		when(state.getSettings()).thenReturn(settings);
+
+		Progress progress = mock(Progress.class);
+		when(progress.get(any())).thenReturn(1d);
+		// progress = end => utilitygoal= resvalue=0.6
+
+		when(state.getProgress()).thenReturn(progress);
+		when(extUtilSpace.getBids(any())).thenReturn(alternatives);
+
+		Action action = biddingstrat.getAction(state);
+
+		// check that the recommender chose a bid in of utility 0.5
+		verify(extUtilSpace).getBids(BigDecimal.valueOf(0.5));
+		assertTrue(action instanceof Offer);
+	}
+
+}
Index: /boa/src/test/resources/testprofile.json
===================================================================
--- /boa/src/test/resources/testprofile.json	(revision 20)
+++ /boa/src/test/resources/testprofile.json	(revision 20)
@@ -0,0 +1,45 @@
+{
+	"LinearAdditiveUtilitySpace": {
+		"issueUtilities": {
+			"issue2": {
+				"numberutils": {
+					"lowValue": 12,
+					"lowUtility": 0.3,
+					"highValue": 18,
+					"highUtility": 0.9
+				}
+			},
+			"issue1": {
+				"discreteutils": {
+					"valueUtilities": {
+						"issue1value1": 0.2,
+						"issue1value2": 0.8
+					}
+				}
+			}
+		},
+		"issueWeights": {
+			"issue2": 0.4,
+			"issue1": 0.6
+		},
+		"domain": {
+			"name": "test",
+			"issuesValues": {
+				"issue2": {
+					"range": ["12", "18", "1"]
+				},
+				"issue1": {
+					"values": ["issue1value1", "issue1value2"]
+				}
+			}
+		},
+		"name": "testprofile",
+				"reservationBid": {
+			"issuevalues": {
+				"issue1": "issuevalue1",
+				"issue2": "12"
+			}
+		}
+		
+	}
+}
Index: /collectparties.sh
===================================================================
--- /collectparties.sh	(revision 20)
+++ /collectparties.sh	(revision 20)
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+# this script collects all parties that are standard parties
+# on the partiesserver, and renames the jar-with-dependencies
+# The collected parties are placed in a new directory "collectedparties".
+
+rm -rf collectedparties
+mkdir collectedparties
+VERSION=1.4.4
+
+cp "exampleparties/anac2019/agentgg/target/agentgg-${VERSION}-jar-with-dependencies.jar" collectedparties
+cp "exampleparties/boulware/target/boulware-${VERSION}-jar-with-dependencies.jar" collectedparties
+cp "exampleparties/comparebids/target/comparebids-${VERSION}-jar-with-dependencies.jar" collectedparties
+cp "exampleparties/conceder/target/conceder-${VERSION}-jar-with-dependencies.jar" collectedparties
+cp "exampleparties/hardliner/target/hardliner-${VERSION}-jar-with-dependencies.jar" collectedparties
+cp "exampleparties/linear/target/linear-${VERSION}-jar-with-dependencies.jar" collectedparties
+cp "exampleparties/randomparty/target/randomparty-${VERSION}-jar-with-dependencies.jar" collectedparties
+cp "exampleparties/randompartypy/target/randompyparty-${VERSION}-jar-with-dependencies.jar" collectedparties
+cp "exampleparties/simpleshaop/target/simpleshaop-${VERSION}-jar-with-dependencies.jar" collectedparties
+cp "exampleparties/timedependentparty/target/timedependentparty-${VERSION}-jar-with-dependencies.jar" collectedparties
+cp "exampleparties/anac2019/winkyagent/target/winkyagent-${VERSION}-jar-with-dependencies.jar" collectedparties
+cp "boa/target/boa-${VERSION}-jar-with-dependencies.jar" collectedparties
+
+cd collectedparties
+ for filename in ./*; do mv "./$filename" "./$(echo "$filename" | sed -e 's/-jar-with-dependencies//g')";  done
+
+
Index: /events/pom.xml
===================================================================
--- /events/pom.xml	(revision 19)
+++ /events/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb</groupId>
 	<artifactId>events</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.10</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /exampleparties/anac2019/agentgg/pom.xml
===================================================================
--- /exampleparties/anac2019/agentgg/pom.xml	(revision 19)
+++ /exampleparties/anac2019/agentgg/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb.exampleparties.anac2019</groupId>
 	<artifactId>agentgg</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.6</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /exampleparties/anac2019/winkyagent/pom.xml
===================================================================
--- /exampleparties/anac2019/winkyagent/pom.xml	(revision 19)
+++ /exampleparties/anac2019/winkyagent/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb.exampleparties.anac2019</groupId>
 	<artifactId>winkyagent</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.6</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /exampleparties/boulware/pom.xml
===================================================================
--- /exampleparties/boulware/pom.xml	(revision 19)
+++ /exampleparties/boulware/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb.exampleparties</groupId>
 	<artifactId>boulware</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.10</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
@@ -34,5 +34,5 @@
 			<groupId>geniusweb.exampleparties</groupId>
 			<artifactId>timedependentparty</artifactId>
-			<version>1.4.1</version> <!-- must equal ${geniusweb.version} -->
+			<version>${geniusweb.version}</version>
 		</dependency>
 		<dependency>
Index: /exampleparties/comparebids/pom.xml
===================================================================
--- /exampleparties/comparebids/pom.xml	(revision 19)
+++ /exampleparties/comparebids/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb.exampleparties</groupId>
 	<artifactId>comparebids</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.6</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /exampleparties/conceder/pom.xml
===================================================================
--- /exampleparties/conceder/pom.xml	(revision 19)
+++ /exampleparties/conceder/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb.exampleparties</groupId>
 	<artifactId>conceder</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.10</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /exampleparties/hardliner/pom.xml
===================================================================
--- /exampleparties/hardliner/pom.xml	(revision 19)
+++ /exampleparties/hardliner/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb.exampleparties</groupId>
 	<artifactId>hardliner</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.10</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /exampleparties/humangui/pom.xml
===================================================================
--- /exampleparties/humangui/pom.xml	(revision 19)
+++ /exampleparties/humangui/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb.exampleparties</groupId>
 	<artifactId>humangui</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.6</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /exampleparties/linear/pom.xml
===================================================================
--- /exampleparties/linear/pom.xml	(revision 19)
+++ /exampleparties/linear/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb.exampleparties</groupId>
 	<artifactId>linear</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.10</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /exampleparties/pom.xml
===================================================================
--- /exampleparties/pom.xml	(revision 19)
+++ /exampleparties/pom.xml	(revision 20)
@@ -27,4 +27,5 @@
 		<module>comparebids</module>
 		<module>anac2019</module>
+		<module>simpleboa</module>
 	</modules>
 </project>
Index: /exampleparties/randomparty/pom.xml
===================================================================
--- /exampleparties/randomparty/pom.xml	(revision 19)
+++ /exampleparties/randomparty/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb.exampleparties</groupId>
 	<artifactId>randomparty</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.6</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /exampleparties/randompartypy/pom.xml
===================================================================
--- /exampleparties/randompartypy/pom.xml	(revision 19)
+++ /exampleparties/randompartypy/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb.exampleparties</groupId>
 	<artifactId>randompyparty</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.10</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /exampleparties/simpleboa/pom.xml
===================================================================
--- /exampleparties/simpleboa/pom.xml	(revision 20)
+++ /exampleparties/simpleboa/pom.xml	(revision 20)
@@ -0,0 +1,227 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<groupId>geniusweb.exampleparties</groupId>
+	<artifactId>simpleboaparty</artifactId>
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
+	<packaging>jar</packaging>
+
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<maven.compiler.target>1.8</maven.compiler.target>
+		<maven.compiler.source>1.8</maven.compiler.source>
+		<basedir>.</basedir>
+		<passwd>${env.ARTIFACTORY_PASS}</passwd>
+		<jackson-2-version>2.9.6</jackson-2-version>
+		<geniusweb.version>1.4.4</geniusweb.version>
+	</properties>
+
+	<distributionManagement>
+		<repository>
+			<id>artifactory.ewi.tudelft.nl</id>
+			<url>http://artifactory.ewi.tudelft.nl/artifactory/libs-release</url>
+		</repository>
+	</distributionManagement>
+
+
+	<dependencies>
+
+
+		<dependency>
+			<groupId>geniusweb</groupId>
+			<artifactId>boa</artifactId>
+			<version>${geniusweb.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>geniusweb</groupId>
+			<artifactId>opponentmodel</artifactId>
+			<version>${geniusweb.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.12</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.mockito</groupId>
+			<artifactId>mockito-all</artifactId>
+			<version>1.9.5</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>tudelft.utilities</groupId>
+			<artifactId>junit</artifactId>
+			<version>1.0.1</version>
+			<scope>test</scope>
+		</dependency>
+
+	</dependencies>
+
+
+	<repositories>
+		<repository>
+			<id>artifactory.ewi.tudelft.nl</id>
+			<url>http://artifactory.ewi.tudelft.nl/artifactory/libs-release</url>
+			<snapshots>
+				<enabled>false</enabled>
+			</snapshots>
+		</repository>
+
+	</repositories>
+
+	<pluginRepositories>
+		<pluginRepository>
+			<id>jcenter</id>
+			<url>https://jcenter.bintray.com</url>
+		</pluginRepository>
+	</pluginRepositories>
+
+
+	<build>
+
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>3.8.0</version>
+				<configuration>
+					<source>1.8</source>
+					<target>1.8</target>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-source-plugin</artifactId>
+				<version>3.1.0</version>
+				<executions>
+					<execution>
+						<id>attach-sources</id>
+						<goals>
+							<goal>jar</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-jar-plugin</artifactId>
+				<configuration>
+					<archive>
+						<manifest>
+							<mainClass>geniusweb.exampleparties.simpleboa.SimpleBoa</mainClass>
+						</manifest>
+					</archive>
+				</configuration>
+			</plugin>
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-javadoc-plugin</artifactId>
+				<version>2.10.1</version>
+				<executions>
+					<execution>
+						<id>attach-javadocs</id>
+						<goals>
+							<goal>jar</goal>
+						</goals>
+						<configuration>
+							<additionalparam>${javadoc.opts}</additionalparam>
+							<additionalparam>-Xdoclint:none</additionalparam>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+
+			<plugin>
+				<groupId>org.jfrog.buildinfo</groupId>
+				<artifactId>artifactory-maven-plugin</artifactId>
+				<version>2.6.1</version>
+				<executions>
+					<execution>
+						<id>build-info</id>
+						<goals>
+							<goal>publish</goal>
+						</goals>
+						<configuration>
+							<publisher>
+								<contextUrl>http://artifactory.ewi.tudelft.nl/artifactory</contextUrl>
+								<repoKey>libs-release</repoKey>
+								<username>wouter</username>
+								<password>${passwd}</password>
+							</publisher>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-assembly-plugin</artifactId>
+				<version>2.4.1</version>
+				<configuration>
+					<!-- get all project dependencies -->
+					<descriptorRefs>
+						<descriptorRef>jar-with-dependencies</descriptorRef>
+					</descriptorRefs>
+					<archive>
+						<manifest>
+							<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+							<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+							<mainClass>geniusweb.exampleparties.simpleboa.SimpleBoa</mainClass>
+						</manifest>
+					</archive>
+				</configuration>
+				<executions>
+					<execution>
+						<id>make-assembly</id>
+						<!-- bind to the packaging phase -->
+						<phase>package</phase>
+						<goals>
+							<goal>single</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+
+
+		</plugins>
+
+		<pluginManagement>
+			<plugins>
+				<plugin>
+					<groupId>org.eclipse.m2e</groupId>
+					<artifactId>lifecycle-mapping</artifactId>
+					<version>1.0.0</version>
+					<configuration>
+						<lifecycleMappingMetadata>
+							<pluginExecutions>
+								<pluginExecution>
+									<pluginExecutionFilter>
+										<groupId>org.jfrog.buildinfo</groupId>
+										<artifactId>artifactory-maven-plugin</artifactId>
+										<versionRange>[1.0.0,)</versionRange>
+										<goals>
+											<goal>publish</goal>
+										</goals>
+									</pluginExecutionFilter>
+									<action>
+										<ignore />
+									</action>
+								</pluginExecution>
+							</pluginExecutions>
+						</lifecycleMappingMetadata>
+					</configuration>
+				</plugin>
+			</plugins>
+		</pluginManagement>
+
+
+	</build>
+</project>
Index: /exampleparties/simpleboa/src/main/java/geniusweb/exampleparties/simpleboa/SimpleBoa.java
===================================================================
--- /exampleparties/simpleboa/src/main/java/geniusweb/exampleparties/simpleboa/SimpleBoa.java	(revision 20)
+++ /exampleparties/simpleboa/src/main/java/geniusweb/exampleparties/simpleboa/SimpleBoa.java	(revision 20)
@@ -0,0 +1,74 @@
+package geniusweb.exampleparties.simpleboa;
+
+import geniusweb.boa.BoaState;
+import geniusweb.boa.DefaultBoa;
+import geniusweb.boa.InstantiationFailedException;
+import geniusweb.boa.acceptancestrategy.AcceptanceStrategy;
+import geniusweb.boa.acceptancestrategy.TimeDependentAcceptanceStrategy;
+import geniusweb.boa.biddingstrategy.BiddingStrategy;
+import geniusweb.boa.biddingstrategy.TimeDependentBiddingStrategy;
+import geniusweb.opponentmodel.FrequencyOpponentModel;
+import geniusweb.opponentmodel.OpponentModel;
+import geniusweb.party.Party;
+import geniusweb.party.inform.Settings;
+import tudelft.utilities.logging.Reporter;
+
+/**
+ * This example illustrates how to make a custom party by extending Boa and
+ * plugging in some components. This is an easy way to make a {@link Party} that
+ * is not requiring configuration/parameters. This also demonstrates how to hard
+ * set parameters of strategies so that the party runs as expected without
+ * requiring any parameters to be set.
+ */
+public class SimpleBoa extends DefaultBoa {
+	public SimpleBoa() {
+		super();
+	}
+
+	public SimpleBoa(Reporter reporter) {
+		super(reporter); // for debugging
+	}
+
+	@Override
+	protected Class<? extends OpponentModel> getOpponentModel(Settings settings)
+			throws InstantiationFailedException {
+		return FrequencyOpponentModel.class;
+	}
+
+	@Override
+	protected BiddingStrategy getBiddingStrategy(Settings settings)
+			throws InstantiationFailedException {
+		return new TimeDependentBiddingStrategy() {
+			@Override
+			protected Double getE(BoaState state) {
+				return 0.7;
+			}
+
+			@Override
+			protected Double getK(BoaState state) {
+				return 0.2;
+			}
+		};
+	}
+
+	@Override
+	protected AcceptanceStrategy getAccceptanceStrategy(Settings settings)
+			throws InstantiationFailedException {
+		return new TimeDependentAcceptanceStrategy() {
+			@Override
+			protected Double getE(BoaState state) {
+				return 0.7;
+			}
+
+			@Override
+			protected Double getK(BoaState state) {
+				return 0.2;
+			}
+		};
+	}
+
+	@Override
+	public String getDescription() {
+		return "Demo of hard coding a party with Boa Components";
+	}
+}
Index: /exampleparties/simpleboa/src/test/java/geniusweb/exampleparties/simpleboa/SimpleBoaTest.java
===================================================================
--- /exampleparties/simpleboa/src/test/java/geniusweb/exampleparties/simpleboa/SimpleBoaTest.java	(revision 20)
+++ /exampleparties/simpleboa/src/test/java/geniusweb/exampleparties/simpleboa/SimpleBoaTest.java	(revision 20)
@@ -0,0 +1,229 @@
+package geniusweb.exampleparties.simpleboa;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.logging.Level;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import geniusweb.actions.Accept;
+import geniusweb.actions.Action;
+import geniusweb.actions.EndNegotiation;
+import geniusweb.actions.Offer;
+import geniusweb.actions.PartyId;
+import geniusweb.bidspace.AllBidsList;
+import geniusweb.connection.ConnectionEnd;
+import geniusweb.issuevalue.Bid;
+import geniusweb.party.Capabilities;
+import geniusweb.party.inform.ActionDone;
+import geniusweb.party.inform.Finished;
+import geniusweb.party.inform.Inform;
+import geniusweb.party.inform.Settings;
+import geniusweb.party.inform.YourTurn;
+import geniusweb.profile.Profile;
+import geniusweb.profile.utilityspace.LinearAdditive;
+import geniusweb.progress.ProgressRounds;
+import geniusweb.references.Parameters;
+import geniusweb.references.ProfileRef;
+import geniusweb.references.ProtocolRef;
+import geniusweb.references.Reference;
+import tudelft.utilities.listener.DefaultListenable;
+import tudelft.utilities.logging.Reporter;
+
+public class SimpleBoaTest {
+
+	private static final String SAOP = "SAOP";
+	private static final PartyId otherparty = new PartyId("other");
+	private static final String PROFILE = "src/test/resources/testprofile.json";
+	private final static ObjectMapper jackson = new ObjectMapper();
+
+	private SimpleBoa party;
+	private final TestConnection connection = new TestConnection();
+	private final ProtocolRef protocol = mock(ProtocolRef.class);
+	private final ProgressRounds progress = mock(ProgressRounds.class);
+	private Settings settings;
+	private LinearAdditive profile;
+	private final Parameters parameters = new Parameters();
+
+	@Before
+	public void before() throws JsonParseException, JsonMappingException,
+			IOException, URISyntaxException {
+		party = new SimpleBoa();
+		settings = new Settings(new PartyId("party1"),
+				new ProfileRef(new URI("file:" + PROFILE)), protocol, progress,
+				parameters);
+
+		String serialized = new String(Files.readAllBytes(Paths.get(PROFILE)),
+				StandardCharsets.UTF_8);
+		profile = (LinearAdditive) jackson.readValue(serialized, Profile.class);
+
+	}
+
+	@Test
+	public void smokeTest() {
+	}
+
+	@Test
+	public void getDescriptionTest() {
+		assertNotNull(party.getDescription());
+	}
+
+	@Test
+	public void getCapabilitiesTest() {
+		Capabilities capabilities = party.getCapabilities();
+		assertFalse("party does not define protocols",
+				capabilities.getBehaviours().isEmpty());
+	}
+
+	@Test
+	public void testInformConnection() {
+		party.connect(connection);
+		// agent should not start acting just after an inform
+		assertEquals(0, connection.getActions().size());
+	}
+
+	@Test
+	public void testInformSettings() {
+		party.connect(connection);
+		connection.notifyListeners(settings);
+		assertEquals(0, connection.getActions().size());
+	}
+
+	@Test
+	public void testInformAndConnection() {
+		party.connect(connection);
+		party.notifyChange(settings);
+		assertEquals(0, connection.getActions().size());
+	}
+
+	@Test
+	public void testOtherWalksAway() {
+		party.connect(connection);
+		party.notifyChange(settings);
+
+		party.notifyChange(new ActionDone(new EndNegotiation(otherparty)));
+
+		// party should not act at this point
+		assertEquals(0, connection.getActions().size());
+	}
+
+	@Test
+	public void testAgentHasFirstTurn() {
+		party.connect(connection);
+		party.notifyChange(settings);
+
+		party.notifyChange(new YourTurn());
+		assertEquals(1, connection.getActions().size());
+		assertTrue(connection.getActions().get(0) instanceof Offer);
+	}
+
+	@Test
+	public void testAgentAccepts() {
+		// at very start, only perfect bid is accepted.
+		// so set time at 10% where good bids are also accepted.
+		when(progress.get(any())).thenReturn(0.1);
+
+		party.connect(connection);
+		party.notifyChange(settings);
+
+		Bid bid = findGoodBid();
+		party.notifyChange(new ActionDone(new Offer(otherparty, bid)));
+		party.notifyChange(new YourTurn());
+		assertEquals(1, connection.getActions().size());
+		assertTrue(connection.getActions().get(0) instanceof Accept);
+
+	}
+
+	@Test
+	public void testAgentLogsFinal() {
+		// this log output is optional, this is to show how to check log
+		Reporter reporter = mock(Reporter.class);
+		party = new SimpleBoa(reporter);
+		party.connect(connection);
+		party.notifyChange(settings);
+		party.notifyChange(new Finished(null));
+
+		verify(reporter).log(eq(Level.INFO),
+				eq("Final ourcome:Finished[null]"));
+	}
+
+	@Test
+	public void testGetCapabilities() {
+		assertTrue(party.getCapabilities().getBehaviours().contains(SAOP));
+	}
+
+	private Bid findGoodBid() {
+		for (Bid bid : new AllBidsList(profile.getDomain())) {
+			if (profile.getUtility(bid)
+					.compareTo(BigDecimal.valueOf(0.7)) > 0) {
+				return bid;
+			}
+		}
+		throw new IllegalStateException(
+				"Test can not be done: there is no good bid with utility>0.7");
+	}
+
+}
+
+/**
+ * A "real" connection object, because the party is going to subscribe etc, and
+ * without a real connection we would have to do a lot of mocks that would make
+ * the test very hard to read.
+ *
+ */
+class TestConnection extends DefaultListenable<Inform>
+		implements ConnectionEnd<Inform, Action> {
+	private List<Action> actions = new LinkedList<>();
+
+	@Override
+	public void send(Action action) throws IOException {
+		actions.add(action);
+	}
+
+	@Override
+	public Reference getReference() {
+		return null;
+	}
+
+	@Override
+	public URI getRemoteURI() {
+		return null;
+	}
+
+	@Override
+	public void close() {
+
+	}
+
+	@Override
+	public Error getError() {
+		return null;
+	}
+
+	public List<Action> getActions() {
+		return actions;
+	}
+
+}
Index: /exampleparties/simpleboa/src/test/resources/testprofile.json
===================================================================
--- /exampleparties/simpleboa/src/test/resources/testprofile.json	(revision 20)
+++ /exampleparties/simpleboa/src/test/resources/testprofile.json	(revision 20)
@@ -0,0 +1,45 @@
+{
+	"LinearAdditiveUtilitySpace": {
+		"issueUtilities": {
+			"issue2": {
+				"numberutils": {
+					"lowValue": 12,
+					"lowUtility": 0.3,
+					"highValue": 18,
+					"highUtility": 0.9
+				}
+			},
+			"issue1": {
+				"discreteutils": {
+					"valueUtilities": {
+						"issue1value1": 0.2,
+						"issue1value2": 0.8
+					}
+				}
+			}
+		},
+		"issueWeights": {
+			"issue2": 0.4,
+			"issue1": 0.6
+		},
+		"domain": {
+			"name": "test",
+			"issuesValues": {
+				"issue2": {
+					"range": ["12", "18", "1"]
+				},
+				"issue1": {
+					"values": ["issue1value1", "issue1value2"]
+				}
+			}
+		},
+		"name": "testprofile",
+				"reservationBid": {
+			"issuevalues": {
+				"issue1": "issuevalue1",
+				"issue2": "12"
+			}
+		}
+		
+	}
+}
Index: /exampleparties/simpleshaop/pom.xml
===================================================================
--- /exampleparties/simpleshaop/pom.xml	(revision 19)
+++ /exampleparties/simpleshaop/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb.exampleparties</groupId>
 	<artifactId>simpleshaop</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.6</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /exampleparties/timedependentparty/pom.xml
===================================================================
--- /exampleparties/timedependentparty/pom.xml	(revision 19)
+++ /exampleparties/timedependentparty/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb.exampleparties</groupId>
 	<artifactId>timedependentparty</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.10</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /exampleparties/timedependentparty/src/main/java/geniusweb/exampleparties/timedependentparty/TimeDependentParty.java
===================================================================
--- /exampleparties/timedependentparty/src/main/java/geniusweb/exampleparties/timedependentparty/TimeDependentParty.java	(revision 19)
+++ /exampleparties/timedependentparty/src/main/java/geniusweb/exampleparties/timedependentparty/TimeDependentParty.java	(revision 20)
@@ -126,7 +126,7 @@
 
 		Action myAction;
-		if (bid == null || lastReceivedBid != null
+		if (bid == null || (lastReceivedBid != null
 				&& utilspace.getUtility(lastReceivedBid)
-						.compareTo(utilspace.getUtility(bid)) >= 0) {
+						.compareTo(utilspace.getUtility(bid)) >= 0)) {
 			// if bid==null we failed to suggest next bid.
 			myAction = new Accept(me, lastReceivedBid);
@@ -155,6 +155,8 @@
 		BigDecimal utilityGoal = utilityGoal(time, getE());
 		ImmutableList<Bid> options = extendedspace.getBids(utilityGoal);
-		if (options.size() == BigInteger.ZERO)
-			return null;
+		if (options.size() == BigInteger.ZERO) {
+			// if we can't find good bid, get max util bid....
+			options = extendedspace.getBids(extendedspace.getMax());
+		}
 		// pick a random one.
 		return options.get(new Random().nextInt(options.size().intValue()));
Index: /issuevalue/pom.xml
===================================================================
--- /issuevalue/pom.xml	(revision 19)
+++ /issuevalue/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb</groupId>
 	<artifactId>issuevalue</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.10</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /opponentmodel/bin/pom.xml
===================================================================
--- /opponentmodel/bin/pom.xml	(revision 20)
+++ /opponentmodel/bin/pom.xml	(revision 20)
@@ -0,0 +1,268 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<groupId>geniusweb</groupId>
+	<artifactId>opponentmodel</artifactId>
+	<version>1.4.3</version> <!-- must equal ${geniusweb.version} -->
+	<packaging>jar</packaging>
+
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<maven.compiler.target>1.8</maven.compiler.target>
+		<maven.compiler.source>1.8</maven.compiler.source>
+		<basedir>.</basedir>
+		<passwd>${env.ARTIFACTORY_PASS}</passwd>
+		<jackson-2-version>2.9.10</jackson-2-version>
+		<geniusweb.version>1.4.3</geniusweb.version>
+	</properties>
+
+	<distributionManagement>
+		<repository>
+			<id>artifactory.ewi.tudelft.nl</id>
+			<url>http://artifactory.ewi.tudelft.nl/artifactory/libs-release</url>
+		</repository>
+	</distributionManagement>
+
+	<dependencies>
+
+		<dependency>
+			<groupId>geniusweb</groupId>
+			<artifactId>issuevalue</artifactId>
+			<version>${geniusweb.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>geniusweb</groupId>
+			<artifactId>profile</artifactId>
+			<version>${geniusweb.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>geniusweb</groupId>
+			<artifactId>references</artifactId>
+			<version>${geniusweb.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>geniusweb</groupId>
+			<artifactId>events</artifactId>
+			<version>${geniusweb.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>geniusweb</groupId>
+			<artifactId>timeline</artifactId>
+			<version>${geniusweb.version}</version>
+		</dependency>
+
+		<!-- the core, which includes Streaming API, shared low-level abstractions 
+			(but NOT data-binding) -->
+		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-core</artifactId>
+			<version>${jackson-2-version}</version>
+		</dependency>
+
+		<!-- Just the annotations; use this dependency if you want to attach annotations 
+			to classes without connecting them to the code. -->
+		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-annotations</artifactId>
+			<version>${jackson-2-version}</version>
+		</dependency>
+
+		<!-- databinding; ObjectMapper, JsonNode and related classes are here -->
+		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-databind</artifactId>
+			<version>${jackson-2-version}</version>
+		</dependency>
+
+		<!-- smile (binary JSON). Other artifacts in this group do other formats. -->
+		<dependency>
+			<groupId>com.fasterxml.jackson.dataformat</groupId>
+			<artifactId>jackson-dataformat-smile</artifactId>
+			<version>${jackson-2-version}</version>
+		</dependency>
+		<!-- JAX-RS provider -->
+		<dependency>
+			<groupId>com.fasterxml.jackson.jaxrs</groupId>
+			<artifactId>jackson-jaxrs-json-provider</artifactId>
+			<version>${jackson-2-version}</version>
+		</dependency>
+		<!-- Support for JAX-B annotations as additional configuration -->
+		<dependency>
+			<groupId>com.fasterxml.jackson.module</groupId>
+			<artifactId>jackson-module-jaxb-annotations</artifactId>
+			<version>${jackson-2-version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>tudelft.utilities</groupId>
+			<artifactId>junit</artifactId>
+			<version>1.0.2</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.12</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.mockito</groupId>
+			<artifactId>mockito-all</artifactId>
+			<version>1.9.5</version>
+			<scope>test</scope>
+		</dependency>
+
+
+	</dependencies>
+
+
+	<repositories>
+		<repository>
+			<id>artifactory.ewi.tudelft.nl</id>
+			<url>http://artifactory.ewi.tudelft.nl/artifactory/libs-release</url>
+			<snapshots>
+				<enabled>false</enabled>
+			</snapshots>
+		</repository>
+
+	</repositories>
+
+	<pluginRepositories>
+		<pluginRepository>
+			<id>jcenter</id>
+			<url>https://jcenter.bintray.com</url>
+		</pluginRepository>
+	</pluginRepositories>
+
+
+	<build>
+
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>3.8.0</version>
+				<configuration>
+					<source>1.8</source>
+					<target>1.8</target>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-source-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>attach-sources</id>
+						<goals>
+							<goal>jar</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-javadoc-plugin</artifactId>
+				<version>2.10.1</version>
+				<executions>
+					<execution>
+						<id>attach-javadocs</id>
+						<goals>
+							<goal>jar</goal>
+						</goals>
+						<configuration>
+							<additionalparam>${javadoc.opts}</additionalparam>
+							<additionalparam>-Xdoclint:none</additionalparam>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+
+			<plugin>
+				<groupId>org.jfrog.buildinfo</groupId>
+				<artifactId>artifactory-maven-plugin</artifactId>
+				<version>2.6.1</version>
+				<executions>
+					<execution>
+						<id>build-info</id>
+						<goals>
+							<goal>publish</goal>
+						</goals>
+						<configuration>
+							<publisher>
+								<contextUrl>http://artifactory.ewi.tudelft.nl/artifactory</contextUrl>
+								<repoKey>libs-release</repoKey>
+								<username>wouter</username>
+								<password>${passwd}</password>
+							</publisher>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-assembly-plugin</artifactId>
+				<version>2.4.1</version>
+				<configuration>
+					<!-- get all project dependencies -->
+					<descriptorRefs>
+						<descriptorRef>jar-with-dependencies</descriptorRef>
+					</descriptorRefs>
+					<archive>
+						<manifest>
+							<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+							<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+						</manifest>
+					</archive>
+				</configuration>
+				<executions>
+					<execution>
+						<id>make-assembly</id>
+						<!-- bind to the packaging phase -->
+						<phase>package</phase>
+						<goals>
+							<goal>single</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+
+
+		</plugins>
+
+		<pluginManagement>
+			<plugins>
+				<plugin>
+					<groupId>org.eclipse.m2e</groupId>
+					<artifactId>lifecycle-mapping</artifactId>
+					<version>1.0.0</version>
+					<configuration>
+						<lifecycleMappingMetadata>
+							<pluginExecutions>
+								<pluginExecution>
+									<pluginExecutionFilter>
+										<groupId>org.jfrog.buildinfo</groupId>
+										<artifactId>artifactory-maven-plugin</artifactId>
+										<versionRange>[1.0.0,)</versionRange>
+										<goals>
+											<goal>publish</goal>
+										</goals>
+									</pluginExecutionFilter>
+									<action>
+										<ignore />
+									</action>
+								</pluginExecution>
+							</pluginExecutions>
+						</lifecycleMappingMetadata>
+					</configuration>
+				</plugin>
+			</plugins>
+		</pluginManagement>
+
+
+	</build>
+</project>
Index: /opponentmodel/pom.xml
===================================================================
--- /opponentmodel/pom.xml	(revision 19)
+++ /opponentmodel/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb</groupId>
 	<artifactId>opponentmodel</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.10</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /opponentmodel/src/main/java/geniusweb/opponentmodel/FrequencyOpponentModel.java
===================================================================
--- /opponentmodel/src/main/java/geniusweb/opponentmodel/FrequencyOpponentModel.java	(revision 19)
+++ /opponentmodel/src/main/java/geniusweb/opponentmodel/FrequencyOpponentModel.java	(revision 20)
@@ -24,21 +24,26 @@
  * (as you might expect as {@link NumberValueSetUtilities} is only affected by
  * the endpoints).
- *
+ * <p>
+ * immutable.
  */
 public class FrequencyOpponentModel implements UtilitySpace, OpponentModel {
 
 	private static final int DECIMALS = 4; // accuracy of our computations.
+	private static int serial = 1; // counter for auto name generation
+
 	private final Domain domain;
 	private final Map<String, Map<Value, Integer>> bidFrequencies;
 	private final BigDecimal totalBids;
-	private static int serial = 1; // counter for auto name generation
-
-	public FrequencyOpponentModel(Domain domain) {
-		/*
-		 * simply reset the whole model and make a new one... maybe this can be
-		 * done smarter for minor changes? map with empth hashmap for each
-		 * issue.
-		 */
-		this(domain,
+
+	public FrequencyOpponentModel() {
+		this.domain = null;
+		this.bidFrequencies = null;
+		this.totalBids = BigDecimal.ZERO;
+	}
+
+	@Override
+	public FrequencyOpponentModel with(Domain domain, Bid resBid) {
+		// FIXME merge already available frequencies?
+		return new FrequencyOpponentModel(domain,
 				domain.getIssues().stream().collect(
 						Collectors.toMap(iss -> iss, iss -> new HashMap<>())),
@@ -115,10 +120,4 @@
 	}
 
-	/**
-	 * {@inheritDoc}
-	 * 
-	 * <h1>change info</h1> This replaces update(Bid). Now you pass the entire
-	 * action and the progress instead of just the bid.
-	 */
 	@Override
 	public FrequencyOpponentModel with(Action action, Progress progress) {
@@ -127,17 +126,15 @@
 
 		Bid bid = ((Offer) action).getBid();
-		String err = domain.isComplete(bid);
-		if (err != null) {
-			throw new IllegalArgumentException(err);
-		}
 		Map<String, Map<Value, Integer>> newFreqs = cloneMap(bidFrequencies);
 		for (String issue : domain.getIssues()) {
 			Map<Value, Integer> freqs = newFreqs.get(issue);
 			Value value = bid.getValue(issue);
-			Integer oldfreq = freqs.get(value);
-			if (oldfreq == null) {
-				oldfreq = 0;
+			if (value != null) {
+				Integer oldfreq = freqs.get(value);
+				if (oldfreq == null) {
+					oldfreq = 0;
+				}
+				freqs.put(value, oldfreq + 1);
 			}
-			freqs.put(value, oldfreq + 1);
 		}
 
Index: /opponentmodel/src/main/java/geniusweb/opponentmodel/OpponentModel.java
===================================================================
--- /opponentmodel/src/main/java/geniusweb/opponentmodel/OpponentModel.java	(revision 19)
+++ /opponentmodel/src/main/java/geniusweb/opponentmodel/OpponentModel.java	(revision 20)
@@ -2,4 +2,5 @@
 
 import geniusweb.actions.Action;
+import geniusweb.issuevalue.Bid;
 import geniusweb.issuevalue.Domain;
 import geniusweb.profile.Profile;
@@ -13,6 +14,24 @@
  * Domain as argument. unfortunately this can not be enforced in a java
  * interface
+ * 
+ * <p>
+ * <em>MUST</em> have an empty constructor as these are also used as part of the
+ * BOA framework.
+ * 
  */
 public interface OpponentModel extends Profile {
+
+	/**
+	 * Initializes the model. This function must be called first after
+	 * constructing an instance. It can also be called later, if there is a
+	 * change in the domain or resBid.
+	 * 
+	 * @param domain the domain to work with
+	 * @param resBid the reservation bid, or null if no reservationbid is
+	 *               available.
+	 * @return OpponentModel that uses given domain and reservationbid.
+	 * 
+	 */
+	OpponentModel with(Domain domain, Bid resBid);
 
 	/**
Index: /opponentmodel/src/test/java/geniusweb/profile/opponentmodel/FrequencyOppModelTest.java
===================================================================
--- /opponentmodel/src/test/java/geniusweb/profile/opponentmodel/FrequencyOppModelTest.java	(revision 19)
+++ /opponentmodel/src/test/java/geniusweb/profile/opponentmodel/FrequencyOppModelTest.java	(revision 20)
@@ -87,8 +87,8 @@
 		bid3 = new Bid(issuevalues);
 
-		oppModel1 = new FrequencyOpponentModel(domain);
-		oppModel1b = new FrequencyOpponentModel(domain);
-		oppModel2 = new FrequencyOpponentModel(domain2);
-		oppModel3 = new FrequencyOpponentModel(domain3);
+		oppModel1 = new FrequencyOpponentModel().with(domain, null);
+		oppModel1b = new FrequencyOpponentModel().with(domain, null);
+		oppModel2 = new FrequencyOpponentModel().with(domain2, null);
+		oppModel3 = new FrequencyOpponentModel().with(domain3, null);
 		oppModel4 = oppModel3.with(new Offer(other, bid1), progress);
 
@@ -113,15 +113,16 @@
 	@Test(expected = NullPointerException.class)
 	public void smokeTestNull() {
-		new FrequencyOpponentModel(null);
+		new FrequencyOpponentModel().with((Domain) null, null);
 	}
 
 	@Test
 	public void smokeTest() {
-		new FrequencyOpponentModel(domain);
+		new FrequencyOpponentModel().with(domain, null);
 	}
 
 	@Test
 	public void testEmptyModel() {
-		FrequencyOpponentModel oppModel = new FrequencyOpponentModel(domain);
+		FrequencyOpponentModel oppModel = new FrequencyOpponentModel()
+				.with(domain, null);
 		assertEquals(BigDecimal.ONE, oppModel.getUtility(bid1));
 		assertEquals(BigDecimal.ONE, oppModel.getUtility(bid2));
@@ -153,3 +154,11 @@
 	}
 
+	@Test
+	public void testPartialBidUpdate() {
+		FrequencyOpponentModel oppModel = oppModel1.with(new Offer(other, bid1),
+				progress);
+		Bid partialbid = new Bid(ISS1, I1V1);
+		oppModel.with(new Offer(other, partialbid), progress);
+	}
+
 }
Index: /party/pom.xml
===================================================================
--- /party/pom.xml	(revision 19)
+++ /party/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb</groupId>
 	<artifactId>party</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.10</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /pom.xml
===================================================================
--- /pom.xml	(revision 19)
+++ /pom.xml	(revision 20)
@@ -30,4 +30,5 @@
 		<module>simplerunner</module>
 		<module>opponentmodel</module>
+		<module>boa</module>
 	</modules>
 </project>
Index: /profile/pom.xml
===================================================================
--- /profile/pom.xml	(revision 19)
+++ /profile/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb</groupId>
 	<artifactId>profile</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.10</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /profile/src/test/java/geniusweb/profile/utilityspace/LinearAdditiveSerializationTest.java
===================================================================
--- /profile/src/test/java/geniusweb/profile/utilityspace/LinearAdditiveSerializationTest.java	(revision 19)
+++ /profile/src/test/java/geniusweb/profile/utilityspace/LinearAdditiveSerializationTest.java	(revision 20)
@@ -27,4 +27,5 @@
 
 public class LinearAdditiveSerializationTest {
+
 	private static final BigDecimal VAL2 = new BigDecimal("0.2");
 	private static final BigDecimal VAL3 = new BigDecimal("0.3");
@@ -106,5 +107,4 @@
 	@Test
 	public void testSerialize() throws JsonProcessingException {
-		ObjectMapper jackson = new ObjectMapper();
 		String string = jackson.writeValueAsString(space);
 		System.out.println(string);
@@ -114,5 +114,4 @@
 	@Test
 	public void testDeserialize() throws IOException {
-		ObjectMapper jackson = new ObjectMapper();
 		assertEquals(space, jackson.readValue(serialized, Profile.class));
 	}
@@ -120,5 +119,4 @@
 	@Test(expected = InvalidDefinitionException.class)
 	public void testDeserializeWrongIssues() throws IOException {
-		ObjectMapper jackson = new ObjectMapper();
 		jackson.readValue(serializedWrongIssues, Profile.class);
 	}
Index: /profileconnection/pom.xml
===================================================================
--- /profileconnection/pom.xml	(revision 19)
+++ /profileconnection/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb</groupId>
 	<artifactId>profileconnection</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.10</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /profileconnection/src/main/java/geniusweb/profileconnection/WebsocketProfileConnector.java
===================================================================
--- /profileconnection/src/main/java/geniusweb/profileconnection/WebsocketProfileConnector.java	(revision 19)
+++ /profileconnection/src/main/java/geniusweb/profileconnection/WebsocketProfileConnector.java	(revision 20)
@@ -49,4 +49,6 @@
 		this.uri = uri;
 		this.logger = reporter;
+		// see #1763 expected max size of profiles.
+		wscontainer.setDefaultMaxTextMessageBufferSize(200000);
 		wscontainer.connectToServer(this, uri);
 	}
Index: /protocol/pom.xml
===================================================================
--- /protocol/pom.xml	(revision 19)
+++ /protocol/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb</groupId>
 	<artifactId>protocol</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.10</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /protocol/src/main/java/geniusweb/protocol/session/SessionResult.java
===================================================================
--- /protocol/src/main/java/geniusweb/protocol/session/SessionResult.java	(revision 20)
+++ /protocol/src/main/java/geniusweb/protocol/session/SessionResult.java	(revision 20)
@@ -0,0 +1,151 @@
+package geniusweb.protocol.session;
+
+import java.util.Collections;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+
+import geniusweb.issuevalue.Bid;
+import geniusweb.references.PartyWithProfile;
+
+/**
+ * All results collected from running a session. Normally this does not contain
+ * all the details, only the final outcome and other global notes.
+ */
+@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
+public class SessionResult {
+	private final List<PartyWithProfile> participants;
+	private final Bid agreement;
+	private final List<Double> penalties;
+
+	// add more type info so that jackson can deserialize the actual class
+	@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.WRAPPER_OBJECT)
+	private final Throwable error;
+
+	/**
+	 * 
+	 * @param participants the list oof {@link PartyWithProfile}, in the proper
+	 *                     order (this is relevant for the protocol etc). Should
+	 *                     never be null. Some of them may have entered later of
+	 *                     left early. This list should contain them all.
+	 * @param agreement    the final agreement {@link Bid} of the session. Null
+	 *                     if no agreement was reached.
+	 * @param penalties    the penalties in [0,1] for each participant, same
+	 *                     order as the participants list.
+	 * @param error        a fatal error that terminated the session. Non-fatal
+	 *                     errors (warnings) are not to be reported. Null if no
+	 *                     fatal error occured (session ended following the
+	 *                     protocol). Normally, a fatal error results in no
+	 *                     agreement but there might be protocols that allow a
+	 *                     session to end with an error but stick with a already
+	 *                     reached agreement as well.
+	 */
+	@JsonCreator
+	public SessionResult(
+			@JsonProperty("participants") List<PartyWithProfile> participants,
+			@JsonProperty("agreement") Bid agreement,
+			@JsonProperty("penalties") List<Double> penalties,
+			@JsonProperty("error") Throwable error) {
+		this.participants = participants;
+		this.agreement = agreement;
+		this.penalties = penalties;
+		this.error = error;
+	}
+
+	/**
+	 * 
+	 * @return the list oof {@link PartyWithProfile}, in the proper order (this
+	 *         is relevant for the protocol etc). Should never be null. Some of
+	 *         them may have entered later of left early. This list should
+	 *         contain them all.
+	 */
+	public List<PartyWithProfile> getParticipants() {
+		return Collections.unmodifiableList(participants);
+	}
+
+	/**
+	 * 8return the final agreement {@link Bid} of the session. Null if no
+	 * agreement was reached.
+	 */
+	public Bid getAgreement() {
+		return agreement;
+	};
+
+	/**
+	 * 
+	 * @return list of penalties, in same order as {@link #getParticipants()}.
+	 */
+	public List<Double> getPenalties() {
+		return Collections.unmodifiableList(penalties);
+	}
+
+	/**
+	 * 
+	 * @return a fatal error that terminated the session. Non-fatal errors
+	 *         (warnings) are not to be reported. Null if no fatal error occured
+	 *         (session ended following the protocol). Normally, a fatal error
+	 *         results in no agreement but there might be protocols that allow a
+	 *         session to end with an error but stick with a already reached
+	 *         agreement as well.
+	 */
+	public Throwable getError() {
+		return error;
+	}
+
+	@Override
+	public String toString() {
+		return "SessionResult[" + participants + "," + agreement + ","
+				+ penalties + "," + error + "]";
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result
+				+ ((agreement == null) ? 0 : agreement.hashCode());
+		result = prime * result + ((error == null) ? 0 : error.hashCode());
+		result = prime * result
+				+ ((participants == null) ? 0 : participants.hashCode());
+		result = prime * result
+				+ ((penalties == null) ? 0 : penalties.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;
+		SessionResult other = (SessionResult) obj;
+		if (agreement == null) {
+			if (other.agreement != null)
+				return false;
+		} else if (!agreement.equals(other.agreement))
+			return false;
+		if (error == null) {
+			if (other.error != null)
+				return false;
+		} else if (!error.equals(other.error))
+			return false;
+		if (participants == null) {
+			if (other.participants != null)
+				return false;
+		} else if (!participants.equals(other.participants))
+			return false;
+		if (penalties == null) {
+			if (other.penalties != null)
+				return false;
+		} else if (!penalties.equals(other.penalties))
+			return false;
+		return true;
+	}
+
+}
Index: /protocol/src/main/java/geniusweb/protocol/session/SessionState.java
===================================================================
--- /protocol/src/main/java/geniusweb/protocol/session/SessionState.java	(revision 19)
+++ /protocol/src/main/java/geniusweb/protocol/session/SessionState.java	(revision 20)
@@ -65,3 +65,10 @@
 	 */
 	Bid getAgreement();
+
+	/**
+	 * 
+	 * @return the {@link SessionResult}. Assumes {@link #isFinal(long)}. result
+	 *         may be undefined if not.
+	 */
+	SessionResult getResult();
 }
Index: /protocol/src/main/java/geniusweb/protocol/session/saop/SAOPState.java
===================================================================
--- /protocol/src/main/java/geniusweb/protocol/session/saop/SAOPState.java	(revision 19)
+++ /protocol/src/main/java/geniusweb/protocol/session/saop/SAOPState.java	(revision 20)
@@ -19,4 +19,5 @@
 import geniusweb.protocol.partyconnection.ProtocolToPartyConnections;
 import geniusweb.protocol.session.DefaultSessionState;
+import geniusweb.protocol.session.SessionResult;
 import geniusweb.protocol.session.SessionSettings;
 import geniusweb.references.PartyWithProfile;
@@ -248,3 +249,12 @@
 	}
 
+	@Override
+	public SessionResult getResult() {
+		List<Double> emptylist = new LinkedList<>();
+		for (int n = 0; n < getConnections().size(); n++)
+			emptylist.add(0d);
+		return new SessionResult(getSettings().getAllParties(), getAgreement(),
+				emptylist, getError());
+	}
+
 }
Index: /protocol/src/main/java/geniusweb/protocol/session/shaop/BareSHAOPState.java
===================================================================
--- /protocol/src/main/java/geniusweb/protocol/session/shaop/BareSHAOPState.java	(revision 19)
+++ /protocol/src/main/java/geniusweb/protocol/session/shaop/BareSHAOPState.java	(revision 20)
@@ -1,4 +1,5 @@
 package geniusweb.protocol.session.shaop;
 
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.LinkedList;
@@ -13,4 +14,5 @@
 import geniusweb.protocol.ProtocolException;
 import geniusweb.protocol.partyconnection.ProtocolToPartyConnections;
+import geniusweb.protocol.session.SessionResult;
 import geniusweb.protocol.session.SessionSettings;
 import geniusweb.protocol.session.SessionState;
@@ -169,4 +171,21 @@
 
 	@Override
+	public SessionResult getResult() {
+		Double[] penalties = new Double[partyNumbers.size()];
+		for (PartyId party : partyNumbers.keySet()) {
+			Double spent = totalSpent.get(party);
+			if (spent == null) {
+				spent = 0d;
+			} else {
+				spent = Math.max(0, Math.min(1.0, spent));
+			}
+			penalties[partyNumbers.get(party)] = spent;
+		}
+		return new SessionResult(getSettings().getAllParties(), getAgreement(),
+				Arrays.asList(penalties), getError());
+
+	}
+
+	@Override
 	public int hashCode() {
 		final int prime = 31;
Index: /protocol/src/main/java/geniusweb/protocol/tournament/allpermutations/AllPermutationsProtocol.java
===================================================================
--- /protocol/src/main/java/geniusweb/protocol/tournament/allpermutations/AllPermutationsProtocol.java	(revision 19)
+++ /protocol/src/main/java/geniusweb/protocol/tournament/allpermutations/AllPermutationsProtocol.java	(revision 20)
@@ -6,7 +6,7 @@
 import geniusweb.events.TournamentStarted;
 import geniusweb.protocol.CurrentNegoState;
-import geniusweb.protocol.SessionResult;
 import geniusweb.protocol.partyconnection.ProtocolToPartyConnFactory;
 import geniusweb.protocol.session.SessionProtocol;
+import geniusweb.protocol.session.SessionResult;
 import geniusweb.protocol.session.SessionSettings;
 import geniusweb.protocol.session.SessionState;
@@ -83,7 +83,5 @@
 				// List<TeamOfPartiesAndProfiles> participants =
 				// sessionstate.getSettings().getParticipants()
-				SessionResult result = new SessionResult(
-						sessionstate.getSettings().getAllParties(),
-						sessionstate.getAgreement(), sessionstate.getError());
+				SessionResult result = sessionstate.getResult();
 				state = state.with(result);
 				notifyListeners(new CurrentNegoState(state));
Index: /protocol/src/main/java/geniusweb/protocol/tournament/allpermutations/AllPermutationsState.java
===================================================================
--- /protocol/src/main/java/geniusweb/protocol/tournament/allpermutations/AllPermutationsState.java	(revision 19)
+++ /protocol/src/main/java/geniusweb/protocol/tournament/allpermutations/AllPermutationsState.java	(revision 20)
@@ -6,5 +6,5 @@
 
 import geniusweb.protocol.ProtocolException;
-import geniusweb.protocol.SessionResult;
+import geniusweb.protocol.session.SessionResult;
 import geniusweb.protocol.session.SessionSettings;
 import geniusweb.protocol.tournament.TournamentState;
Index: /protocol/src/test/java/geniusweb/protocol/session/DefaultSessionStateTest.java
===================================================================
--- /protocol/src/test/java/geniusweb/protocol/session/DefaultSessionStateTest.java	(revision 19)
+++ /protocol/src/test/java/geniusweb/protocol/session/DefaultSessionStateTest.java	(revision 20)
@@ -139,3 +139,14 @@
 	}
 
+	@Override
+	public SessionResult getResult() {
+
+		List<Double> emptylist = new LinkedList<>();
+		for (int n = 0; n < getConnections().size(); n++)
+			emptylist.add(0d);
+		return new SessionResult(getSettings().getAllParties(), getAgreement(),
+				emptylist, getError());
+
+	}
+
 }
Index: /protocol/src/test/java/geniusweb/protocol/session/SessionResultTest.java
===================================================================
--- /protocol/src/test/java/geniusweb/protocol/session/SessionResultTest.java	(revision 19)
+++ /protocol/src/test/java/geniusweb/protocol/session/SessionResultTest.java	(revision 20)
@@ -19,5 +19,4 @@
 import geniusweb.issuevalue.DiscreteValue;
 import geniusweb.issuevalue.Value;
-import geniusweb.protocol.SessionResult;
 import geniusweb.references.Parameters;
 import geniusweb.references.PartyRef;
@@ -32,8 +31,10 @@
 
 	private final String ISSUE1 = "issue1";
-	private SessionResult result1, result1a, result2, result3;// , result4;
+	private SessionResult result1, result1a, result2, result3, result4;
 	private String errorstring; // created dynamically: eclipse and maven
 								// generate different stacktrace.
-	private String jsonstring = "{\"participants\":[{\"party\":{\"partyref\":\"party1\",\"parameters\":{}},\"profile\":\"profile1\"},{\"party\":{\"partyref\":\"party2\",\"parameters\":{}},\"profile\":\"profile2\"}],\"agreement\":{\"issuevalues\":{\"issue1\":\"a\"}},\"error\":null}";
+	private String jsonstring = "{\"participants\":[{\"party\":{\"partyref\":\"party1\",\"parameters\":{}},\"profile\":\"profile1\"},{\"party\":{\"partyref\":\"party2\",\"parameters\":{}},\"profile\":\"profile2\"}],\"agreement\":{\"issuevalues\":{\"issue1\":\"a\"}},\"penalties\":[0.0,0.0],\"error\":null}";
+	private List<Double> nopenalties = Arrays.asList(0d, 0d);
+	private List<Double> penalties = Arrays.asList(0.1d, 0.2d);
 
 	@Before
@@ -63,11 +64,15 @@
 
 		result1 = new SessionResult(Arrays.asList(partyprofile1, partyprofile2),
-				bid1, null);
+				bid1, nopenalties, null);
 		result1a = new SessionResult(
-				Arrays.asList(partyprofile1, partyprofile2), bid1, null);
+				Arrays.asList(partyprofile1, partyprofile2), bid1, nopenalties,
+				null);
 		result2 = new SessionResult(Arrays.asList(partyprofile1, partyprofile2),
-				bid2, null);
+				bid2, nopenalties, null);
 		result3 = new SessionResult(Arrays.asList(partyprofile2, partyprofile1),
-				bid2, null);
+				bid2, nopenalties, null);
+		result4 = new SessionResult(Arrays.asList(partyprofile2, partyprofile1),
+				bid2, penalties, null);
+
 		// IGNORE ERROR for now, it fails somewhere deep in maven suddenly.
 		// result4 = new SessionResult(Arrays.asList(partyprofile1,
@@ -78,7 +83,6 @@
 	public List<List<SessionResult>> getGeneralTestData() {
 		return Arrays.asList(Arrays.asList(result1, result1a),
-				Arrays.asList(result2), Arrays.asList(result3)
-		// ,Arrays.asList(result4)
-		);
+				Arrays.asList(result2), Arrays.asList(result3),
+				Arrays.asList(result4));
 	}
 
@@ -86,8 +90,8 @@
 	public List<String> getGeneralTestStrings() {
 		return Arrays.asList(
-				"SessionResult.*party1.*profile1.*,.*party2.*profile2.*Bid.*issue1=\"a\".*null.",
-				"SessionResult.*party1.*profile1.*,.*party2.*profile2.*Bid.*issue1=\"b\".*null.*",
-				"SessionResult.*party2.*profile2.*,.*party1.*profile1.*Bid.*issue1=\"b\".*null.*"
-		// ,"SessionResult.*party1.*profile1.*,.*party2.*profile2.*Bid.*issue1=\"a\".*null.*"
+				"SessionResult.*party1.*profile1.*,.*party2.*profile2.*Bid.*issue1=\"a\".*0\\.0.*0\\.0.*null.*",
+				"SessionResult.*party1.*profile1.*,.*party2.*profile2.*Bid.*issue1=\"b\".*0\\.0.*0\\.0.*null.*",
+				"SessionResult.*party2.*profile2.*,.*party1.*profile1.*Bid.*issue1=\"b\".*0\\.0.*0\\.0.*null.*",
+				"SessionResult.*party2.*profile2.*,.*party1.*profile1.*Bid.*issue1=\"b\".*0\\.1.*0\\.2.*null.*"
 
 		);
Index: /protocol/src/test/java/geniusweb/protocol/session/shaop/SHAOPStateTest.java
===================================================================
--- /protocol/src/test/java/geniusweb/protocol/session/shaop/SHAOPStateTest.java	(revision 19)
+++ /protocol/src/test/java/geniusweb/protocol/session/shaop/SHAOPStateTest.java	(revision 20)
@@ -31,4 +31,5 @@
 import geniusweb.protocol.partyconnection.ProtocolToPartyConn;
 import geniusweb.protocol.partyconnection.ProtocolToPartyConnections;
+import geniusweb.protocol.session.SessionResult;
 import geniusweb.protocol.session.TeamOfPartiesAndProfiles;
 import tudelft.utilities.junit.GeneralTests;
@@ -314,3 +315,15 @@
 	}
 
+	@Test
+	public void getResultTest() {
+
+		Map<PartyId, Double> spent = new HashMap<>();
+		spent.put(party1, 0.1d);
+		SHAOPState state = new SHAOPState(actions, connections4,
+				new ProgressRounds(10, 0, null), settings, null, 0, partynrs,
+				spent);
+		SessionResult res = state.getResult();
+
+	}
+
 }
Index: /protocol/src/test/java/geniusweb/protocol/tournament/allpermutations/AllPermutationsProtocolTest.java
===================================================================
--- /protocol/src/test/java/geniusweb/protocol/tournament/allpermutations/AllPermutationsProtocolTest.java	(revision 19)
+++ /protocol/src/test/java/geniusweb/protocol/tournament/allpermutations/AllPermutationsProtocolTest.java	(revision 20)
@@ -23,7 +23,7 @@
 import geniusweb.protocol.CurrentNegoState;
 import geniusweb.protocol.NegoState;
-import geniusweb.protocol.SessionResult;
 import geniusweb.protocol.partyconnection.ProtocolToPartyConnFactory;
 import geniusweb.protocol.session.SessionProtocol;
+import geniusweb.protocol.session.SessionResult;
 import geniusweb.protocol.session.SessionSettings;
 import geniusweb.protocol.session.SessionState;
@@ -46,4 +46,5 @@
 	private Bid agreement = mock(Bid.class);
 	private final long NOW = 1000;
+	private SessionResult finalstate = mock(SessionResult.class);
 
 	@Before
@@ -53,4 +54,6 @@
 		when(finalsessionstate.getSettings()).thenReturn(settings);
 		when(finalsessionstate.getAgreement()).thenReturn(agreement);
+		when(finalsessionstate.getResult()).thenReturn(finalstate);
+		when(finalstate.getAgreement()).thenReturn(agreement);
 		when(state.with(any())).thenReturn(newstate);
 	}
Index: /protocol/src/test/java/geniusweb/protocol/tournament/allpermutations/AllPermutationsStateTest.java
===================================================================
--- /protocol/src/test/java/geniusweb/protocol/tournament/allpermutations/AllPermutationsStateTest.java	(revision 19)
+++ /protocol/src/test/java/geniusweb/protocol/tournament/allpermutations/AllPermutationsStateTest.java	(revision 20)
@@ -13,5 +13,5 @@
 import org.junit.Test;
 
-import geniusweb.protocol.SessionResult;
+import geniusweb.protocol.session.SessionResult;
 import geniusweb.protocol.session.SessionSettings;
 import geniusweb.references.PartyWithProfile;
Index: /pythonadapter/pom.xml
===================================================================
--- /pythonadapter/pom.xml	(revision 19)
+++ /pythonadapter/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb</groupId>
 	<artifactId>pythonadapter</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.10</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /references/pom.xml
===================================================================
--- /references/pom.xml	(revision 19)
+++ /references/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb</groupId>
 	<artifactId>references</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.10</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /simplerunner/pom.xml
===================================================================
--- /simplerunner/pom.xml	(revision 19)
+++ /simplerunner/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb</groupId>
 	<artifactId>simplerunner</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -17,5 +17,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.10</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
Index: /timeline/pom.xml
===================================================================
--- /timeline/pom.xml	(revision 19)
+++ /timeline/pom.xml	(revision 20)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb</groupId>
 	<artifactId>timeline</artifactId>
-	<version>1.4.2</version> <!-- must equal ${geniusweb.version} -->
+	<version>1.4.4</version> <!-- must equal ${geniusweb.version} -->
 	<packaging>jar</packaging>
 
@@ -16,5 +16,5 @@
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
 		<jackson-2-version>2.9.10</jackson-2-version>
-		<geniusweb.version>1.4.2</geniusweb.version>
+		<geniusweb.version>1.4.4</geniusweb.version>
 	</properties>
 
