Index: exampleparties/comparebids/pom.xml
===================================================================
--- exampleparties/comparebids/pom.xml	(revision 10)
+++ exampleparties/comparebids/pom.xml	(revision 10)
@@ -0,0 +1,289 @@
+<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>comparebids</artifactId>
+	<version>1.0.0</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>
+	</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>1.1.0</version>
+		</dependency>
+
+		<dependency>
+			<groupId>geniusweb</groupId>
+			<artifactId>bidspace</artifactId>
+			<version>1.1.0</version>
+		</dependency>
+		<dependency>
+			<groupId>geniusweb</groupId>
+			<artifactId>profileconnection</artifactId>
+			<version>1.1.0</version>
+		</dependency>
+		<dependency>
+			<groupId>tudelft.utilities</groupId>
+			<artifactId>logging</artifactId>
+			<version>1.0.0</version>
+		</dependency>
+		<dependency>
+			<groupId>tudelft.utilities</groupId>
+			<artifactId>immutablelist</artifactId>
+			<version>1.0.1</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>
+			<scope>test</scope>
+		</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>
+			<scope>test</scope>
+		</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>
+			<scope>test</scope>
+		</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>
+			<scope>test</scope>
+		</dependency>
+		<!-- JAX-RS provider -->
+		<dependency>
+			<groupId>com.fasterxml.jackson.jaxrs</groupId>
+			<artifactId>jackson-jaxrs-json-provider</artifactId>
+			<version>${jackson-2-version}</version>
+			<scope>test</scope>
+		</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>
+			<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>
+		<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>http://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>
+				<version>3.2.0</version>
+				<configuration>
+					<archive>
+						<manifest>
+							<mainClass>geniusweb.exampleparties.comparebids.CompareBids</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.comparebids.CompareBids</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/comparebids/src/main/java/geniusweb/exampleparties/comparebids/CompareBids.java
===================================================================
--- exampleparties/comparebids/src/main/java/geniusweb/exampleparties/comparebids/CompareBids.java	(revision 10)
+++ exampleparties/comparebids/src/main/java/geniusweb/exampleparties/comparebids/CompareBids.java	(revision 10)
@@ -0,0 +1,103 @@
+package geniusweb.exampleparties.comparebids;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.logging.Level;
+
+import geniusweb.actions.Action;
+import geniusweb.actions.Comparison;
+import geniusweb.actions.ElicitComparison;
+import geniusweb.actions.PartyId;
+import geniusweb.issuevalue.Bid;
+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.profile.PartialOrdering;
+import geniusweb.profile.Profile;
+import geniusweb.profileconnection.ProfileConnectionFactory;
+import geniusweb.profileconnection.ProfileInterface;
+import tudelft.utilities.logging.Reporter;
+
+/**
+ * A party following the COB protocol and thus answers {@link ElicitComparison}
+ * questions. This party does not use a GUI but uses the given profile to
+ * determine the answer.
+ */
+public class CompareBids extends DefaultParty {
+
+	private PartyId me;
+	protected ProfileInterface profileint;
+
+	public CompareBids() {
+	}
+
+	public CompareBids(Reporter reporter) {
+		super(reporter); // for debugging
+	}
+
+	@Override
+	public void notifyChange(Inform info) {
+		try {
+			if (info instanceof Settings) {
+				Settings settings = (Settings) info;
+				this.profileint = ProfileConnectionFactory
+						.create(settings.getProfile().getURI(), getReporter());
+				this.me = settings.getID();
+			} else if (info instanceof ActionDone) {
+				Action action = ((ActionDone) info).getAction();
+				if (action instanceof ElicitComparison) {
+					reply((ElicitComparison) action);
+				}
+			} else if (info instanceof Finished) {
+			} else {
+				reporter.log(Level.WARNING, "COB party ignores " + info);
+			}
+		} catch (Exception e) {
+			throw new RuntimeException("Failed to handle info", e);
+		}
+	}
+
+	@Override
+	public Capabilities getCapabilities() {
+		return new Capabilities(new HashSet<>(Arrays.asList("COB")));
+	}
+
+	@Override
+	public String getDescription() {
+		return "compares a bid with a given list of other bids.";
+	}
+
+	/**
+	 * Handle the {@link ElicitComparison} and reply with {@link Comparison}.
+	 * This shoul dbe fast (assuming the request is reasonably sized) so we
+	 * handle this in-line instead of in separate thread.
+	 */
+	private void reply(ElicitComparison compareRequest) throws IOException {
+		List<Bid> better = new LinkedList<>();
+		List<Bid> worse = new LinkedList<>();
+		Profile profile1 = profileint.getProfile();
+		if (!(profile1 instanceof PartialOrdering)) {
+			throw new IllegalStateException(
+					"Profile must be a partial ordering");
+		}
+		PartialOrdering profile = (PartialOrdering) profile1;
+
+		Bid bid = compareRequest.getBid();
+		for (Bid otherbid : compareRequest.getOptions()) {
+			boolean betteroreq = profile.isPreferredOrEqual(otherbid, bid);
+			boolean worseoreq = profile.isPreferredOrEqual(bid, otherbid);
+			if (betteroreq && !worseoreq)
+				better.add(otherbid);
+			else if (worseoreq && !betteroreq)
+				worse.add(otherbid);
+		}
+		getConnection().send(new Comparison(me, bid, better, worse));
+	}
+
+}
Index: exampleparties/comparebids/src/test/java/geniusweb/exampleparties/comparebids/CompareBidsTest.java
===================================================================
--- exampleparties/comparebids/src/test/java/geniusweb/exampleparties/comparebids/CompareBidsTest.java	(revision 10)
+++ exampleparties/comparebids/src/test/java/geniusweb/exampleparties/comparebids/CompareBidsTest.java	(revision 10)
@@ -0,0 +1,179 @@
+package geniusweb.exampleparties.comparebids;
+
+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.Mockito.mock;
+
+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 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.Action;
+import geniusweb.actions.EndNegotiation;
+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.Inform;
+import geniusweb.party.inform.Settings;
+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;
+
+public class CompareBidsTest {
+
+	private static final String COB = "COB";
+	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 CompareBids 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 CompareBids();
+		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 testGetCapabilities() {
+		assertTrue(party.getCapabilities().getBehaviours().contains(COB));
+	}
+
+	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/comparebids/src/test/resources/testprofile.json
===================================================================
--- exampleparties/comparebids/src/test/resources/testprofile.json	(revision 10)
+++ exampleparties/comparebids/src/test/resources/testprofile.json	(revision 10)
@@ -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/humangui/src/main/java/geniusweb/exampleparties/humangui/HumanGui.java
===================================================================
--- exampleparties/humangui/src/main/java/geniusweb/exampleparties/humangui/HumanGui.java	(revision 9)
+++ exampleparties/humangui/src/main/java/geniusweb/exampleparties/humangui/HumanGui.java	(revision 10)
@@ -2,6 +2,4 @@
 
 import java.awt.BorderLayout;
-import java.net.URI;
-import java.net.URISyntaxException;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -23,5 +21,4 @@
 import geniusweb.profileconnection.ProfileConnectionFactory;
 import geniusweb.profileconnection.ProfileInterface;
-import geniusweb.references.ProtocolRef;
 import tudelft.utilities.logging.Reporter;
 
@@ -85,12 +82,5 @@
 	@Override
 	public Capabilities getCapabilities() {
-		try {
-			return new Capabilities(new HashSet<>(
-					Arrays.asList(new ProtocolRef(new URI("SAOP")))));
-		} catch (URISyntaxException e) {
-			getReporter().log(Level.SEVERE, "Failed to create capabilities URI",
-					e);
-			return null;
-		}
+		return new Capabilities(new HashSet<>(Arrays.asList("SAOP")));
 	}
 
Index: exampleparties/humangui/src/test/java/geniusweb/exampleparties/humangui/BiddingInfoTest.java
===================================================================
--- exampleparties/humangui/src/test/java/geniusweb/exampleparties/humangui/BiddingInfoTest.java	(revision 9)
+++ exampleparties/humangui/src/test/java/geniusweb/exampleparties/humangui/BiddingInfoTest.java	(revision 10)
@@ -32,5 +32,5 @@
 import geniusweb.party.inform.Settings;
 import geniusweb.profile.Profile;
-import geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace;
+import geniusweb.profile.utilityspace.LinearAdditive;
 import geniusweb.profileconnection.ProfileConnectionFactory;
 import geniusweb.profileconnection.ProfileInterface;
@@ -61,5 +61,5 @@
 	private final ProgressRounds progress = mock(ProgressRounds.class);
 	private Settings settings;
-	private LinearAdditiveUtilitySpace profile, profile2;
+	private LinearAdditive profile, profile2;
 	private final Parameters parameters = new Parameters();
 	private Reporter reporter = mock(Reporter.class);
@@ -76,9 +76,8 @@
 		String serialized = new String(Files.readAllBytes(Paths.get(PROFILE)),
 				StandardCharsets.UTF_8);
-		profile = (LinearAdditiveUtilitySpace) jackson.readValue(serialized,
-				Profile.class);
+		profile = (LinearAdditive) jackson.readValue(serialized, Profile.class);
 		String serialized2 = new String(Files.readAllBytes(Paths.get(PROFILE2)),
 				StandardCharsets.UTF_8);
-		profile2 = (LinearAdditiveUtilitySpace) jackson.readValue(serialized2,
+		profile2 = (LinearAdditive) jackson.readValue(serialized2,
 				Profile.class);
 
Index: exampleparties/humangui/src/test/java/geniusweb/exampleparties/humangui/HumanGuiTest.java
===================================================================
--- exampleparties/humangui/src/test/java/geniusweb/exampleparties/humangui/HumanGuiTest.java	(revision 9)
+++ exampleparties/humangui/src/test/java/geniusweb/exampleparties/humangui/HumanGuiTest.java	(revision 10)
@@ -34,5 +34,5 @@
 import geniusweb.party.inform.YourTurn;
 import geniusweb.profile.Profile;
-import geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace;
+import geniusweb.profile.utilityspace.LinearAdditive;
 import geniusweb.progress.ProgressRounds;
 import geniusweb.references.Parameters;
@@ -57,5 +57,5 @@
 	private final ProgressRounds progress = mock(ProgressRounds.class);
 	private Settings settings;
-	private LinearAdditiveUtilitySpace profile;
+	private LinearAdditive profile;
 	private final Parameters parameters = new Parameters();
 
@@ -70,6 +70,5 @@
 		String serialized = new String(Files.readAllBytes(Paths.get(PROFILE)),
 				StandardCharsets.UTF_8);
-		profile = (LinearAdditiveUtilitySpace) jackson.readValue(serialized,
-				Profile.class);
+		profile = (LinearAdditive) jackson.readValue(serialized, Profile.class);
 
 	}
@@ -93,10 +92,10 @@
 		Capabilities capabilities = party.getCapabilities();
 		assertFalse("party does not define protocols",
-				capabilities.getProtocols().isEmpty());
+				capabilities.getBehaviours().isEmpty());
 	}
 
 	@Test
 	public void testGetCapabilities() {
-		assertTrue(party.getCapabilities().getProtocols().contains(SAOP));
+		assertTrue(party.getCapabilities().getBehaviours().contains(SAOP));
 	}
 
Index: exampleparties/pom.xml
===================================================================
--- exampleparties/pom.xml	(revision 9)
+++ exampleparties/pom.xml	(revision 10)
@@ -23,4 +23,6 @@
 		<module>boulware</module>
 		<module>linear</module>
+		<module>simpleshaop</module>
+		<module>comparebids</module>
 	</modules>
 </project>
Index: exampleparties/randomparty/src/main/java/geniusweb/exampleparties/randomparty/RandomParty.java
===================================================================
--- exampleparties/randomparty/src/main/java/geniusweb/exampleparties/randomparty/RandomParty.java	(revision 9)
+++ exampleparties/randomparty/src/main/java/geniusweb/exampleparties/randomparty/RandomParty.java	(revision 10)
@@ -3,6 +3,4 @@
 import java.io.IOException;
 import java.math.BigInteger;
-import java.net.URI;
-import java.net.URISyntaxException;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -30,5 +28,4 @@
 import geniusweb.progress.Progress;
 import geniusweb.progress.ProgressRounds;
-import geniusweb.references.ProtocolRef;
 import tudelft.utilities.logging.Reporter;
 
@@ -81,12 +78,5 @@
 	@Override
 	public Capabilities getCapabilities() {
-		try {
-			return new Capabilities(new HashSet<>(
-					Arrays.asList(new ProtocolRef(new URI("SAOP")))));
-		} catch (URISyntaxException e) {
-			getReporter().log(Level.SEVERE, "Failed to create capabilities URI",
-					e);
-			return null;
-		}
+		return new Capabilities(new HashSet<>(Arrays.asList("SAOP")));
 	}
 
@@ -115,5 +105,5 @@
 	}
 
-	private boolean isGood(Bid bid) {
+	private boolean isGood(Bid bid) throws IOException {
 		if (bid == null)
 			return false;
Index: exampleparties/randomparty/src/test/java/geniusweb/exampleparties/randomparty/RandomPartyTest.java
===================================================================
--- exampleparties/randomparty/src/test/java/geniusweb/exampleparties/randomparty/RandomPartyTest.java	(revision 9)
+++ exampleparties/randomparty/src/test/java/geniusweb/exampleparties/randomparty/RandomPartyTest.java	(revision 10)
@@ -42,5 +42,5 @@
 import geniusweb.party.inform.YourTurn;
 import geniusweb.profile.Profile;
-import geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace;
+import geniusweb.profile.utilityspace.LinearAdditive;
 import geniusweb.progress.ProgressRounds;
 import geniusweb.references.Parameters;
@@ -53,5 +53,5 @@
 public class RandomPartyTest {
 
-	private static final ProtocolRef SAOP = new ProtocolRef("SAOP");
+	private static final String SAOP = "SAOP";
 	private static final PartyId otherparty = new PartyId("other");
 	private static final String PROFILE = "src/test/resources/testprofile.json";
@@ -63,5 +63,5 @@
 	private final ProgressRounds progress = mock(ProgressRounds.class);
 	private Settings settings;
-	private LinearAdditiveUtilitySpace profile;
+	private LinearAdditive profile;
 	private final Parameters parameters = new Parameters();
 
@@ -76,6 +76,5 @@
 		String serialized = new String(Files.readAllBytes(Paths.get(PROFILE)),
 				StandardCharsets.UTF_8);
-		profile = (LinearAdditiveUtilitySpace) jackson.readValue(serialized,
-				Profile.class);
+		profile = (LinearAdditive) jackson.readValue(serialized, Profile.class);
 
 	}
@@ -94,5 +93,5 @@
 		Capabilities capabilities = party.getCapabilities();
 		assertFalse("party does not define protocols",
-				capabilities.getProtocols().isEmpty());
+				capabilities.getBehaviours().isEmpty());
 	}
 
@@ -176,5 +175,5 @@
 	@Test
 	public void testGetCapabilities() {
-		assertTrue(party.getCapabilities().getProtocols().contains(SAOP));
+		assertTrue(party.getCapabilities().getBehaviours().contains(SAOP));
 	}
 
Index: exampleparties/randompartypy/src/main/resources/RandomParty.py
===================================================================
--- exampleparties/randompartypy/src/main/resources/RandomParty.py	(revision 9)
+++ exampleparties/randompartypy/src/main/resources/RandomParty.py	(revision 10)
@@ -65,9 +65,5 @@
 	# Override
 	def getCapabilities(self): # -> Capabilities
-		try:
-			return Capabilities(HashSet([ ProtocolRef(URI("SAOP"))]))
-		except:
-			getReporter().log(Level.SEVERE, "Failed to create capabilities URI",e);
-		return None
+			return Capabilities(HashSet([ "SAOP"]))
 
 	# Override
Index: exampleparties/randompartypy/src/test/java/geniusweb/exampleparties/randompartypy/RandomPartyTest.java
===================================================================
--- exampleparties/randompartypy/src/test/java/geniusweb/exampleparties/randompartypy/RandomPartyTest.java	(revision 9)
+++ exampleparties/randompartypy/src/test/java/geniusweb/exampleparties/randompartypy/RandomPartyTest.java	(revision 10)
@@ -39,5 +39,5 @@
 import geniusweb.party.inform.YourTurn;
 import geniusweb.profile.Profile;
-import geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace;
+import geniusweb.profile.utilityspace.LinearAdditive;
 import geniusweb.progress.ProgressRounds;
 import geniusweb.pythonadapter.PythonPartyAdapter;
@@ -51,5 +51,5 @@
 
 	private static final String PROFILE = "src/test/resources/testprofile.json";
-	private static final ProtocolRef SAOP = new ProtocolRef("SAOP");
+	private static final String SAOP = "SAOP";
 	private static final PartyId otherparty = new PartyId("other");
 	private final static ObjectMapper jackson = new ObjectMapper();
@@ -62,5 +62,5 @@
 	private final Parameters parameters = new Parameters();
 
-	private LinearAdditiveUtilitySpace profile; // the real profile
+	private LinearAdditive profile; // the real profile
 
 	@Before
@@ -80,6 +80,5 @@
 		String serialized = new String(Files.readAllBytes(Paths.get(PROFILE)),
 				StandardCharsets.UTF_8);
-		profile = (LinearAdditiveUtilitySpace) jackson.readValue(serialized,
-				Profile.class);
+		profile = (LinearAdditive) jackson.readValue(serialized, Profile.class);
 
 	}
@@ -98,5 +97,5 @@
 		Capabilities capabilities = party.getCapabilities();
 		assertFalse("party does not define protocols",
-				capabilities.getProtocols().isEmpty());
+				capabilities.getBehaviours().isEmpty());
 	}
 
@@ -167,5 +166,5 @@
 	@Test
 	public void testGetCapabilities() {
-		assertTrue(party.getCapabilities().getProtocols().contains(SAOP));
+		assertTrue(party.getCapabilities().getBehaviours().contains(SAOP));
 	}
 
Index: exampleparties/simpleshaop/pom.xml
===================================================================
--- exampleparties/simpleshaop/pom.xml	(revision 10)
+++ exampleparties/simpleshaop/pom.xml	(revision 10)
@@ -0,0 +1,289 @@
+<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>simpleshaop</artifactId>
+	<version>1.0.0</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>
+	</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>1.1.0</version>
+		</dependency>
+
+		<dependency>
+			<groupId>geniusweb</groupId>
+			<artifactId>bidspace</artifactId>
+			<version>1.1.0</version>
+		</dependency>
+		<dependency>
+			<groupId>geniusweb</groupId>
+			<artifactId>profileconnection</artifactId>
+			<version>1.1.0</version>
+		</dependency>
+		<dependency>
+			<groupId>tudelft.utilities</groupId>
+			<artifactId>logging</artifactId>
+			<version>1.0.0</version>
+		</dependency>
+		<dependency>
+			<groupId>tudelft.utilities</groupId>
+			<artifactId>immutablelist</artifactId>
+			<version>1.0.1</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>
+			<scope>test</scope>
+		</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>
+			<scope>test</scope>
+		</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>
+			<scope>test</scope>
+		</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>
+			<scope>test</scope>
+		</dependency>
+		<!-- JAX-RS provider -->
+		<dependency>
+			<groupId>com.fasterxml.jackson.jaxrs</groupId>
+			<artifactId>jackson-jaxrs-json-provider</artifactId>
+			<version>${jackson-2-version}</version>
+			<scope>test</scope>
+		</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>
+			<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>
+		<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>http://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>
+				<version>3.2.0</version>
+				<configuration>
+					<archive>
+						<manifest>
+							<mainClass>geniusweb.exampleparties.simpleshaop.ShaopParty</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.simpleshaop.ShaopParty</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/simpleshaop/src/main/java/geniusweb/exampleparties/simpleshaop/ShaopParty.java
===================================================================
--- exampleparties/simpleshaop/src/main/java/geniusweb/exampleparties/simpleshaop/ShaopParty.java	(revision 10)
+++ exampleparties/simpleshaop/src/main/java/geniusweb/exampleparties/simpleshaop/ShaopParty.java	(revision 10)
@@ -0,0 +1,147 @@
+package geniusweb.exampleparties.simpleshaop;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Random;
+import java.util.logging.Level;
+
+import geniusweb.actions.Accept;
+import geniusweb.actions.Action;
+import geniusweb.actions.Comparison;
+import geniusweb.actions.ElicitComparison;
+import geniusweb.actions.Offer;
+import geniusweb.actions.PartyId;
+import geniusweb.bidspace.AllPartialBidsList;
+import geniusweb.issuevalue.Bid;
+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.profile.PartialOrdering;
+import geniusweb.profileconnection.ProfileConnectionFactory;
+import geniusweb.profileconnection.ProfileInterface;
+import geniusweb.progress.Progress;
+import geniusweb.progress.ProgressRounds;
+import tudelft.utilities.logging.Reporter;
+
+/**
+ * A simple implementation of a SHAOP party that can handle only bilateral
+ * negotiations (1 other party). It will ignore all other parties except the one
+ * that has the turn right before us. It estimates the utilities of bids by
+ * assigning a linear increasing utility from the orderings that have been
+ * created.
+ * <p>
+ * <b>Requirement<b> the initial {@link PartialOrdering} must contain at least
+ * the bids with lowest utility and highest utility, and the proper comparison
+ * info for these two bids.
+ */
+public class ShaopParty extends DefaultParty {
+
+	private static final BigDecimal N09 = new BigDecimal("0.9");
+	private Bid lastReceivedBid = null; // we ignore all others
+	private PartyId me;
+	private final Random random = new Random();
+	protected ProfileInterface profileint;
+	private Progress progress;
+	private SimpleLinearOrdering estimatedProfile = null;
+
+	public ShaopParty() {
+	}
+
+	public ShaopParty(Reporter reporter) {
+		super(reporter); // for debugging
+	}
+
+	@Override
+	public void notifyChange(Inform info) {
+		try {
+			if (info instanceof Settings) {
+				Settings settings = (Settings) info;
+				this.profileint = ProfileConnectionFactory
+						.create(settings.getProfile().getURI(), getReporter());
+				this.me = settings.getID();
+				this.progress = settings.getProgress();
+			} else if (info instanceof ActionDone) {
+				Action otheract = ((ActionDone) info).getAction();
+				if (otheract instanceof Offer) {
+					lastReceivedBid = ((Offer) otheract).getBid();
+				} else if (otheract instanceof Comparison) {
+					estimatedProfile = estimatedProfile.with(
+							((Comparison) otheract).getBid(),
+							((Comparison) otheract).getWorse());
+					myTurn();
+				}
+			} else if (info instanceof YourTurn) {
+				myTurn();
+			} else if (info instanceof Finished) {
+				getReporter().log(Level.INFO, "Final ourcome:" + info);
+			}
+		} catch (Exception e) {
+			throw new RuntimeException("Failed to handle info", e);
+		}
+	}
+
+	@Override
+	public Capabilities getCapabilities() {
+		return new Capabilities(new HashSet<>(Arrays.asList("SHAOP")));
+	}
+
+	@Override
+	public String getDescription() {
+		return "Communicates with COB party to figure out which bids are good. Accepts bids with utility > 0.9. Offers random bids.";
+	}
+
+	/**
+	 * Called when it's (still) our turn and we should take some action. Also
+	 * Updates the progress if necessary.
+	 */
+	private void myTurn() throws IOException {
+		Action action = null;
+		if (estimatedProfile == null) {
+			estimatedProfile = new SimpleLinearOrdering(
+					profileint.getProfile());
+		}
+
+		if (lastReceivedBid != null) {
+			// then we do the action now, no need to ask user
+			if (estimatedProfile.contains(lastReceivedBid)) {
+				if (isGood(lastReceivedBid)) {
+					action = new Accept(me, lastReceivedBid);
+				}
+			} else {
+				// we did not yet assess the received bid
+				action = new ElicitComparison(me, lastReceivedBid,
+						estimatedProfile.getBids());
+			}
+			if (progress instanceof ProgressRounds) {
+				progress = ((ProgressRounds) progress).advance();
+			}
+		}
+		// Otherwise just offer a Random bid
+		// FIXME this is weird, can't we do better than random?
+		if (action == null)
+			action = randomBid();
+		getConnection().send(action);
+	}
+
+	private Offer randomBid() throws IOException {
+		AllPartialBidsList bidspace = new AllPartialBidsList(
+				profileint.getProfile().getDomain());
+		long i = random.nextInt(bidspace.size().intValue());
+		Bid bid = bidspace.get(BigInteger.valueOf(i));
+		return new Offer(me, bid);
+	}
+
+	private boolean isGood(Bid bid) {
+		if (bid == null)
+			return false;
+		return estimatedProfile.getUtility(bid).compareTo(N09) >= 0;
+	}
+
+}
Index: exampleparties/simpleshaop/src/main/java/geniusweb/exampleparties/simpleshaop/SimpleLinearOrdering.java
===================================================================
--- exampleparties/simpleshaop/src/main/java/geniusweb/exampleparties/simpleshaop/SimpleLinearOrdering.java	(revision 10)
+++ exampleparties/simpleshaop/src/main/java/geniusweb/exampleparties/simpleshaop/SimpleLinearOrdering.java	(revision 10)
@@ -0,0 +1,125 @@
+package geniusweb.exampleparties.simpleshaop;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+
+import geniusweb.issuevalue.Bid;
+import geniusweb.issuevalue.Domain;
+import geniusweb.profile.DefaultPartialOrdering;
+import geniusweb.profile.Profile;
+import geniusweb.profile.utilityspace.UtilitySpace;
+
+/**
+ * A simple list of bids, but all bids are fully ordered (better or worse than
+ * other bids in the list).
+ */
+public class SimpleLinearOrdering implements UtilitySpace {
+
+	private final Domain domain;
+	private final List<Bid> bids; // worst bid first, best bid last.
+
+	SimpleLinearOrdering(Profile profile) {
+		this(profile.getDomain(), getSortedBids(profile));
+	}
+
+	/**
+	 * 
+	 * @param domain
+	 * @param bids   a list of bids, ordered from lowest to highest util. The
+	 *               first bid will have utility 0, the last utility 1. If only
+	 *               0 or 1 bid in the list, or if the bid is not known, it will
+	 *               have utility 0.
+	 */
+	SimpleLinearOrdering(Domain domain, List<Bid> bids) {
+		this.domain = domain;
+		this.bids = bids;
+	}
+
+	@Override
+	public String getName() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public Domain getDomain() {
+		return domain;
+	}
+
+	@Override
+	public Bid getReservationBid() {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override
+	public BigDecimal getUtility(Bid bid) {
+		if (bids.size() < 2 || !bids.contains(bid)) {
+			return BigDecimal.ZERO;
+		}
+		// using 8 decimals, we have to pick something here
+		return new BigDecimal(bids.indexOf(bid)).divide(
+				new BigDecimal((bids.size() - 1)), 8, RoundingMode.HALF_UP);
+	}
+
+	/**
+	 * 
+	 * @param bid
+	 * @return true iff bid is contained in this ordering
+	 */
+	public boolean contains(Bid bid) {
+		return bids.contains(bid);
+	}
+
+	/**
+	 * 
+	 * @return list of all bids in the current ordering.
+	 */
+	public List<Bid> getBids() {
+		return Collections.unmodifiableList(bids);
+	}
+
+	/**
+	 * 
+	 * @param profile
+	 * @return a list of bids in the profile sorted from low to high utility.
+	 */
+	private static List<Bid> getSortedBids(Profile profile) {
+		if (!(profile instanceof DefaultPartialOrdering)) {
+			throw new UnsupportedOperationException(
+					"Only DefaultPartialOrdering supported");
+		}
+		DefaultPartialOrdering prof = (DefaultPartialOrdering) profile;
+		List<Bid> bidslist = prof.getBids();
+		Collections.sort(bidslist, new Comparator<Bid>() {
+
+			@Override
+			public int compare(Bid b1, Bid b2) {
+				// notice, -1 if better because WORST bid first
+				return prof.isPreferredOrEqual(b1, b2) ? -1 : 1;
+			}
+
+		});
+
+		return bidslist;
+	}
+
+	/**
+	 * @param bid       a new bid to be inserted
+	 * @param worseBids all bids that are worse than this bid.
+	 * @return a SimpleLinearOrdering, updated with the given comparison. Thee
+	 *         bid will be inserted after the first bid that is not worse than
+	 *         bid.
+	 */
+	public SimpleLinearOrdering with(Bid bid, List<Bid> worseBids) {
+		int n = 0;
+		while (n < bids.size() && worseBids.contains(bids.get(n)))
+			n++;
+		LinkedList<Bid> newbids = new LinkedList<Bid>(bids);
+		newbids.add(n, bid);
+		return new SimpleLinearOrdering(domain, newbids);
+	}
+
+}
Index: exampleparties/simpleshaop/src/test/java/geniusweb/exampleparties/simpleshaop/ShaopPartyTest.java
===================================================================
--- exampleparties/simpleshaop/src/test/java/geniusweb/exampleparties/simpleshaop/ShaopPartyTest.java	(revision 10)
+++ exampleparties/simpleshaop/src/test/java/geniusweb/exampleparties/simpleshaop/ShaopPartyTest.java	(revision 10)
@@ -0,0 +1,251 @@
+package geniusweb.exampleparties.simpleshaop;
+
+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.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.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+
+import org.junit.Before;
+import org.junit.Ignore;
+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.ElicitComparison;
+import geniusweb.actions.EndNegotiation;
+import geniusweb.actions.Offer;
+import geniusweb.actions.PartyId;
+import geniusweb.connection.ConnectionEnd;
+import geniusweb.issuevalue.Bid;
+import geniusweb.issuevalue.DiscreteValue;
+import geniusweb.issuevalue.Value;
+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.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 ShaopPartyTest {
+
+	private static final String SHAOP = "SHAOP";
+	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 ShaopParty 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 Profile profile;
+	private final Parameters parameters = new Parameters();
+
+	@Before
+	public void before() throws JsonParseException, JsonMappingException,
+			IOException, URISyntaxException {
+		party = new ShaopParty();
+		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 = 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 testAgentElicitsComparison() {
+		party.connect(connection);
+		party.notifyChange(settings);
+
+		Bid bid = makeBid("3", "3"); // not yet in profile
+		party.notifyChange(new ActionDone(new Offer(otherparty, bid)));
+		party.notifyChange(new YourTurn());
+		assertEquals(1, connection.getActions().size());
+		assertTrue(connection.getActions().get(0) instanceof ElicitComparison);
+
+	}
+
+	@Ignore
+	@Test
+	public void testAgentAccepts() {
+		// to make agent accept, the offered bid must score >0.9
+		// we would need to mock a lot t make that happen
+		// as we need to place >10 comparable bids for that.
+		party.connect(connection);
+		party.notifyChange(settings);
+
+		Bid bid = makeBid("1", "1");// best pssible
+		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 ShaopParty(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 testAgentsUpdatesProgress() {
+		party.connect(connection);
+		party.notifyChange(settings);
+
+		party.notifyChange(new ActionDone(new Offer(null, mock(Bid.class))));
+
+		party.notifyChange(new YourTurn());
+		verify(progress).advance();
+	}
+
+	@Test
+	public void testGetCapabilities() {
+		assertTrue(party.getCapabilities().getBehaviours().contains(SHAOP));
+	}
+
+	private Bid makeBid(String val1, String val2) {
+		Map<String, Value> map = new HashMap<>();
+		map.put("iss1", new DiscreteValue(val1));
+		map.put("iss2", new DiscreteValue(val2));
+		return new Bid(map);
+
+	}
+
+}
+
+/**
+ * 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/simpleshaop/src/test/java/geniusweb/exampleparties/simpleshaop/SimpleLinearOrderingTest.java
===================================================================
--- exampleparties/simpleshaop/src/test/java/geniusweb/exampleparties/simpleshaop/SimpleLinearOrderingTest.java	(revision 10)
+++ exampleparties/simpleshaop/src/test/java/geniusweb/exampleparties/simpleshaop/SimpleLinearOrderingTest.java	(revision 10)
@@ -0,0 +1,120 @@
+package geniusweb.exampleparties.simpleshaop;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import geniusweb.issuevalue.Bid;
+import geniusweb.issuevalue.Domain;
+import geniusweb.profile.DefaultPartialOrdering;
+
+public class SimpleLinearOrderingTest {
+	private DefaultPartialOrdering realprofile = mock(
+			DefaultPartialOrdering.class);;
+	private Domain domain = mock(Domain.class);
+	private SimpleLinearOrdering estprofile;
+	private Bid bid1 = makeBid(1);
+	private Bid bid2 = makeBid(2);
+	private Bid bid3 = makeBid(3);
+	private Bid bid4 = makeBid(4);
+	private final List<Bid> emptyList = Collections.emptyList();
+
+	@Before
+	public void before() {
+		when(realprofile.getDomain()).thenReturn(domain);
+		estprofile = new SimpleLinearOrdering(realprofile);
+		when(bid1.toString()).thenReturn("bid1");
+
+	}
+
+	private static Bid makeBid(int n) {
+		Bid mockbid = mock(Bid.class);
+		when(mockbid.toString()).thenReturn("bid " + n);
+		return mockbid;
+	}
+
+	@Test
+	public void testSmoke() {
+	}
+
+	@Test
+	public void testInitialBids() {
+		assertTrue(estprofile.getBids().isEmpty());
+	}
+
+	@Test
+	public void largerInitialListTest() {
+		when(realprofile.getBids()).thenReturn(Arrays.asList(bid1, bid2, bid3));
+		// idea is that 3 > 2 > 1
+		when(realprofile.isPreferredOrEqual(bid2, bid1)).thenReturn(true);
+		when(realprofile.isPreferredOrEqual(bid1, bid2)).thenReturn(false);
+		when(realprofile.isPreferredOrEqual(bid3, bid2)).thenReturn(true);
+		when(realprofile.isPreferredOrEqual(bid2, bid3)).thenReturn(false);
+		when(realprofile.isPreferredOrEqual(bid3, bid1)).thenReturn(true);
+		when(realprofile.isPreferredOrEqual(bid1, bid3)).thenReturn(false);
+		SimpleLinearOrdering testprofile = new SimpleLinearOrdering(
+				realprofile);
+		assertEquals(Arrays.asList(bid3, bid2, bid1), testprofile.getBids());
+	}
+
+	@Test
+	public void testAddFirstBid() {
+		SimpleLinearOrdering prof1 = estprofile.with(bid1,
+				Collections.emptyList());
+
+		assertEquals(1, prof1.getBids().size());
+	}
+
+	@Test
+	public void testAddTwoBidsSecondIsWorse() {
+		SimpleLinearOrdering prof1 = estprofile.with(bid1, emptyList);
+		// new bid is worse as bid1, so list of worse bids is empty
+		SimpleLinearOrdering prof2 = prof1.with(bid2, emptyList);
+
+		assertEquals(Arrays.asList(bid2, bid1), prof2.getBids());
+	}
+
+	@Test
+	public void testAddTwoBidsSecondIsBetter() {
+		SimpleLinearOrdering prof1 = estprofile.with(bid1, emptyList);
+		SimpleLinearOrdering prof2 = prof1.with(bid2, Arrays.asList(bid1));
+
+		assertEquals(Arrays.asList(bid1, bid2), prof2.getBids());
+	}
+
+	@Test
+	public void testAddThreeBidsThirdIsMiddle() {
+		SimpleLinearOrdering prof1 = new SimpleLinearOrdering(domain,
+				Arrays.asList(bid1, bid2));
+		SimpleLinearOrdering prof2 = prof1.with(bid3, Arrays.asList(bid1));
+
+		assertEquals(Arrays.asList(bid1, bid3, bid2), prof2.getBids());
+	}
+
+	@Test
+	public void getUtilityTest3Bids() {
+		SimpleLinearOrdering prof1 = new SimpleLinearOrdering(domain,
+				Arrays.asList(bid1, bid3, bid2));
+
+		assertEquals(new BigDecimal("0.50000000"), prof1.getUtility(bid3));
+	}
+
+	@Test
+	public void getUtilityTest4Bids() {
+		// with 4 bids, we get utility 1/3 which causes deximal expansiion issue
+		SimpleLinearOrdering prof1 = new SimpleLinearOrdering(domain,
+				Arrays.asList(bid1, bid2, bid3, bid4));
+
+		assertEquals(new BigDecimal("0.33333333"), prof1.getUtility(bid2));
+	}
+
+}
Index: exampleparties/simpleshaop/src/test/resources/testprofile.json
===================================================================
--- exampleparties/simpleshaop/src/test/resources/testprofile.json	(revision 10)
+++ exampleparties/simpleshaop/src/test/resources/testprofile.json	(revision 10)
@@ -0,0 +1,182 @@
+{
+	"DefaultPartialOrdering": {
+		"name": "ordering1",
+		"domain": {
+			"name": "dom1",
+			"issuesValues": {
+				"iss1": {
+					"values": [
+						"1",
+						"2",
+						"3",
+						"4"
+					]
+				},
+				"iss2": {
+					"values": [
+						"1",
+						"2",
+						"3",
+						"4"
+					]
+				}
+			}
+		},
+		"reservationBid": {
+			"issuevalues": {
+				"iss1": "3",
+				"iss2": "3"
+			}
+		},
+		"bids": [
+			{
+				"issuevalues": {
+					"iss1": "1",
+					"iss2": "1"
+				}
+			},
+			{
+				"issuevalues": {
+					"iss1": "2",
+					"iss2": "1"
+				}
+			},
+			{
+				"issuevalues": {
+					"iss1": "3",
+					"iss2": "1"
+				}
+			},
+			{
+				"issuevalues": {
+					"iss1": "4",
+					"iss2": "1"
+				}
+			},
+			{
+				"issuevalues": {
+					"iss1": "1",
+					"iss2": "2"
+				}
+			},
+			{
+				"issuevalues": {
+					"iss1": "2",
+					"iss2": "2"
+				}
+			},
+			{
+				"issuevalues": {
+					"iss1": "3",
+					"iss2": "2"
+				}
+			},
+			{
+				"issuevalues": {
+					"iss1": "4",
+					"iss2": "2"
+				}
+			},
+			{
+				"issuevalues": {
+					"iss1": "1",
+					"iss2": "3"
+				}
+			},
+			{
+				"issuevalues": {
+					"iss1": "2",
+					"iss2": "3"
+				}
+			},
+			{
+				"issuevalues": {
+					"iss1": "4",
+					"iss2": "3"
+				}
+			},
+			{
+				"issuevalues": {
+					"iss1": "1",
+					"iss2": "4"
+				}
+			},
+			{
+				"issuevalues": {
+					"iss1": "2",
+					"iss2": "4"
+				}
+			},
+			{
+				"issuevalues": {
+					"iss1": "3",
+					"iss2": "4"
+				}
+			},
+			{
+				"issuevalues": {
+					"iss1": "4",
+					"iss2": "4"
+				}
+			}
+		],
+		"better": [
+			[
+				0,
+				1
+			],
+			[
+				1,
+				2
+			],
+			[
+				2,
+				3
+			],
+			[
+				3,
+				4
+			],
+			[
+				4,
+				5
+			],
+			[
+				5,
+				6
+			],
+			[
+				6,
+				7
+			],
+			[
+				7,
+				8
+			],
+			[
+				8,
+				9
+			],
+			[
+				9,
+				10
+			],
+			[
+				10,
+				11
+			],
+			[
+				11,
+				12
+			],
+			[
+				12,
+				13
+			],
+			[
+				13,
+				14
+			]
+		]
+	}
+}
Index: exampleparties/timedependentparty/src/main/java/geniusweb/exampleparties/timedependentparty/ExtendedUtilSpace.java
===================================================================
--- exampleparties/timedependentparty/src/main/java/geniusweb/exampleparties/timedependentparty/ExtendedUtilSpace.java	(revision 9)
+++ exampleparties/timedependentparty/src/main/java/geniusweb/exampleparties/timedependentparty/ExtendedUtilSpace.java	(revision 10)
@@ -11,5 +11,5 @@
 import geniusweb.issuevalue.Bid;
 import geniusweb.issuevalue.Value;
-import geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace;
+import geniusweb.profile.utilityspace.LinearAdditive;
 import tudelft.utilities.immutablelist.ImmutableList;
 
@@ -20,5 +20,5 @@
  */
 public class ExtendedUtilSpace {
-	private LinearAdditiveUtilitySpace utilspace;
+	private LinearAdditive utilspace;
 	private BigDecimal tolerance; // utility tolerance for a bid.
 	private BidsWithUtility bidutils;
@@ -27,5 +27,5 @@
 	private BigDecimal maxUtil;
 
-	public ExtendedUtilSpace(LinearAdditiveUtilitySpace space) {
+	public ExtendedUtilSpace(LinearAdditive space) {
 		this.utilspace = space;
 		bidutils = new BidsWithUtility(utilspace);
Index: exampleparties/timedependentparty/src/main/java/geniusweb/exampleparties/timedependentparty/TimeDependentParty.java
===================================================================
--- exampleparties/timedependentparty/src/main/java/geniusweb/exampleparties/timedependentparty/TimeDependentParty.java	(revision 9)
+++ exampleparties/timedependentparty/src/main/java/geniusweb/exampleparties/timedependentparty/TimeDependentParty.java	(revision 10)
@@ -4,6 +4,4 @@
 import java.math.BigDecimal;
 import java.math.BigInteger;
-import java.net.URI;
-import java.net.URISyntaxException;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -24,10 +22,9 @@
 import geniusweb.party.inform.YourTurn;
 import geniusweb.profile.Profile;
-import geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace;
+import geniusweb.profile.utilityspace.LinearAdditive;
 import geniusweb.profileconnection.ProfileConnectionFactory;
 import geniusweb.profileconnection.ProfileInterface;
 import geniusweb.progress.Progress;
 import geniusweb.progress.ProgressRounds;
-import geniusweb.references.ProtocolRef;
 import tudelft.utilities.immutablelist.ImmutableList;
 import tudelft.utilities.logging.Reporter;
@@ -44,5 +41,5 @@
 	private static final BigDecimal DEC100 = new BigDecimal("100");
 	private ProfileInterface profileint;
-	private LinearAdditiveUtilitySpace utilspace = null; // last received space
+	private LinearAdditive utilspace = null; // last received space
 	private PartyId me;
 	private Progress progress;
@@ -61,12 +58,5 @@
 	@Override
 	public Capabilities getCapabilities() {
-		try {
-			return new Capabilities(new HashSet<>(
-					Arrays.asList(new ProtocolRef(new URI("SAOP")))));
-		} catch (URISyntaxException e) {
-			getReporter().log(Level.SEVERE, "Failed to create capabilities URI",
-					e);
-			return null;
-		}
+		return new Capabilities(new HashSet<>(Arrays.asList("SAOP")));
 	}
 
@@ -148,8 +138,8 @@
 	}
 
-	private LinearAdditiveUtilitySpace updateUtilSpace() {
+	private LinearAdditive updateUtilSpace() throws IOException {
 		Profile newutilspace = profileint.getProfile();
 		if (!newutilspace.equals(utilspace)) {
-			utilspace = (LinearAdditiveUtilitySpace) newutilspace;
+			utilspace = (LinearAdditive) newutilspace;
 			extendedspace = new ExtendedUtilSpace(utilspace);
 		}
Index: exampleparties/timedependentparty/src/test/java/geniusweb/exampleparties/timedependentparty/TimeDependentPartyTest.java
===================================================================
--- exampleparties/timedependentparty/src/test/java/geniusweb/exampleparties/timedependentparty/TimeDependentPartyTest.java	(revision 9)
+++ exampleparties/timedependentparty/src/test/java/geniusweb/exampleparties/timedependentparty/TimeDependentPartyTest.java	(revision 10)
@@ -53,5 +53,5 @@
 public class TimeDependentPartyTest {
 
-	private static final ProtocolRef SAOP = new ProtocolRef("SAOP");
+	private static final String SAOP = "SAOP";
 	private static final PartyId otherparty = new PartyId("other");
 	private static final String PROFILE = "src/test/resources/testprofile.json";
@@ -105,5 +105,5 @@
 		Capabilities capabilities = party.getCapabilities();
 		assertFalse("party does not define protocols",
-				capabilities.getProtocols().isEmpty());
+				capabilities.getBehaviours().isEmpty());
 	}
 
@@ -198,5 +198,5 @@
 	@Test
 	public void testGetCapabilities() {
-		assertTrue(party.getCapabilities().getProtocols().contains(SAOP));
+		assertTrue(party.getCapabilities().getBehaviours().contains(SAOP));
 	}
 
