Index: /pom.xml
===================================================================
--- /pom.xml	(revision 13)
+++ /pom.xml	(revision 14)
@@ -6,5 +6,5 @@
 	<artifactId>runserver</artifactId>
 	<packaging>war</packaging>
-	<version>1.4.0</version>
+	<version>1.4.1</version> <!-- must equal ${geniusweb.version} -->
 	<name>runserver Maven Webapp</name>
 	<url>http://maven.apache.org</url>
@@ -19,6 +19,5 @@
 		<jackson-2-version>2.9.10</jackson-2-version>
 		<tomcat.version>8.0.53</tomcat.version>
-		<geniusweb.version>1.4.0</geniusweb.version>
-		
+		<geniusweb.version>1.4.1</geniusweb.version>
 	</properties>
 
@@ -79,5 +78,5 @@
 			<groupId>tudelft.utilities</groupId>
 			<artifactId>repository</artifactId>
-			<version>1.0.1</version>
+			<version>1.1.0</version>
 		</dependency>
 
@@ -154,5 +153,5 @@
 
 	<build>
-		<finalName>runserver-1.4.0</finalName>
+		<!-- Don't specify finalName as the war number would mismatch the pom version -->
 
 
@@ -216,4 +215,17 @@
 					</execution>
 				</executions>
+			</plugin>
+
+			<!-- Includes version nr in war to enable getImplementationVersion() -->
+			<plugin>
+				<artifactId>maven-war-plugin</artifactId>
+				<version>2.2</version>
+				<configuration>
+					<archive>
+						<manifest>
+							<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+						</manifest>
+					</archive>
+				</configuration>
 			</plugin>
 
Index: /src/main/java/geniusweb/runserver/Info.java
===================================================================
--- /src/main/java/geniusweb/runserver/Info.java	(revision 14)
+++ /src/main/java/geniusweb/runserver/Info.java	(revision 14)
@@ -0,0 +1,43 @@
+package geniusweb.runserver;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import geniusweb.protocol.NegoSettings;
+
+/**
+ * Contains incoming connection to run a Nego. runserver/runsession with the
+ * JSON {@link NegoSettings} in the request header. After the session is
+ * started, the new Nego ID is returned. This can be used to find back the log
+ * files..
+ */
+@SuppressWarnings("serial")
+public class Info extends HttpServlet {
+	private final static ObjectMapper jackson = new ObjectMapper();
+
+	/**
+	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
+	 *      response).
+	 * 
+	 * @return the ID of the new started run. Or SC_BAD_REQUEST if the request
+	 *         can not be processed.
+	 */
+	@Override
+	protected void doGet(HttpServletRequest request,
+			HttpServletResponse response) throws ServletException, IOException {
+		response.setContentType("text/plain");
+		// HACK but should be generizable easy in the future.
+		Map<String, Object> info = new HashMap<>();
+		info.put("version", getClass().getPackage().getImplementationVersion());
+		response.getWriter().append(jackson.writeValueAsString(info));
+	}
+
+}
Index: /src/main/webapp/WEB-INF/web.xml
===================================================================
--- /src/main/webapp/WEB-INF/web.xml	(revision 13)
+++ /src/main/webapp/WEB-INF/web.xml	(revision 14)
@@ -45,4 +45,11 @@
 	</servlet>
 
+	<servlet>
+		<servlet-name>Info</servlet-name>
+		<display-name>Info</display-name>
+		<description>get info</description>
+		<servlet-class>geniusweb.runserver.Info</servlet-class>
+	</servlet>
+
 
 	<servlet-mapping>
@@ -54,5 +61,8 @@
 		<url-pattern>/run</url-pattern>
 	</servlet-mapping>
-
+	<servlet-mapping>
+		<servlet-name>Info</servlet-name>
+		<url-pattern>/info</url-pattern>
+	</servlet-mapping>
 
 </web-app>
Index: /src/main/webapp/newsession.xhtml
===================================================================
--- /src/main/webapp/newsession.xhtml	(revision 13)
+++ /src/main/webapp/newsession.xhtml	(revision 14)
@@ -29,5 +29,5 @@
 	<br /> Domain/Profile Server:
 	<input type="url" name="url" id="profilesserverurl"
-		value="localhost:8080/profilesserver-1.4.0"
+		value="localhost:8080/profilesserver-1.4.1"
 		pattern=".*:[0-9]+/profilesserver" size="30"
 		onchange="connectDomain()"> </input>
@@ -43,5 +43,5 @@
 		<br /> <b>Participants</b> <br /> Parties Server: <input type="url"
 			name="url" id="partiesserverurl"
-			value="localhost:8080/partiesserver-1.4.0"
+			value="localhost:8080/partiesserver-1.4.1"
 			pattern=".*:[0-9]+/partiesserver" size="30"
 			onchange="connectParties()"> </input> <br /> <br /> <b>Party
@@ -273,8 +273,8 @@
 	 refresh table: copy all parties elements in there.
 	 Typically parties is something like
-	 [{"uri":"http:130.161.180.1:8080/partiesserver/run/randomparty-1.4.0",
+	 [{"uri":"http:130.161.180.1:8080/partiesserver/run/randomparty-1.4.1",
 		 "capabilities":{"protocols":["SAOP"]},
 		 "description":"places random bids until it can accept an offer with utility >0.6",
-		 "id":"randomparty-1.4.0",
+		 "id":"randomparty-1.4.1",
 		 "partyClass":"geniusweb.exampleparties.randomparty.RandomParty"},
 		 		 ...]
@@ -571,6 +571,6 @@
 	function init() {
 		selectProtocol();
-		document.getElementById("partiesserverurl").value =window.location.hostname+":8080/partiesserver-1.4.0"
-		document.getElementById("profilesserverurl").value =window.location.hostname+":8080/profilesserver-1.4.0"
+		document.getElementById("partiesserverurl").value =window.location.hostname+":8080/partiesserver-1.4.1"
+		document.getElementById("profilesserverurl").value =window.location.hostname+":8080/profilesserver-1.4.1"
 		connectDomain();
 		connectParties();
Index: /src/main/webapp/newtournament.xhtml
===================================================================
--- /src/main/webapp/newtournament.xhtml	(revision 13)
+++ /src/main/webapp/newtournament.xhtml	(revision 14)
@@ -18,7 +18,11 @@
 	</select>
 	<br />
-	<br />
-	<input type="number" id="teamspersession" name="tentacles" min="2"
-		max="10" value="2" /> Number of teams in each session
+	<input type="number" id="ntournaments" min="1" max="1000000" value="1" />
+	Number of times to repeat the entire tournament
+	<br />
+
+	<br />
+	<input type="number" id="teamspersession" min="2" max="10" value="2" />
+	Number of teams in each session
 	<br />
 
@@ -103,6 +107,8 @@
 				<th align="left">Party</th>
 				<th align="left">Parameters</th>
-				<th align="left"><div class="onlySHAOP">Compare Bids Party</div></th>
-				<th align="left"><div class="onlySHAOP">Compare Bids Parameters</div></th>
+				<th align="left"><div class="onlySHAOP">Compare Bids
+						Party</div></th>
+				<th align="left"><div class="onlySHAOP">Compare Bids
+						Parameters</div></th>
 			</thead>
 			<tbody id="teamList">
@@ -127,4 +133,5 @@
 
 <script type="application/javascript">
+	
 	
 	
@@ -506,4 +513,5 @@
 	function makeRequest() {
 		const npersession = document.getElementById("teamspersession").value;
+		const ntournaments = document.getElementById("ntournaments").value;
 		const reuseTeams  = document.getElementById("reuseteams").checked;
 		const protocolcombobox = document.getElementById("protocolselection");
@@ -540,5 +548,6 @@
 		
 		return JSON.stringify({"AllPermutationsSettings":{"teams":teamsFull,"profileslists":profilesFull,
-			"reuseTeams":reuseTeams,"teamsPerSession":npersession,"sessionsettings":sessionSettings}});
+			"reuseTeams":reuseTeams,"teamsPerSession":npersession,"sessionsettings":sessionSettings,
+			"numberTournaments":ntournaments}});
 	}
 	
@@ -547,6 +556,6 @@
 	*/
 	function init() {
-		document.getElementById("partiesserverurl").value =window.location.hostname+":8080/partiesserver-1.4.0";
-		document.getElementById("profilesserverurl").value =window.location.hostname+":8080/profilesserver-1.4.0";
+		document.getElementById("partiesserverurl").value =window.location.hostname+":8080/partiesserver-1.4.1";
+		document.getElementById("profilesserverurl").value =window.location.hostname+":8080/profilesserver-1.4.1";
 
 		selectProtocol();
@@ -570,4 +579,5 @@
 
 
+
 </script>
 
Index: /src/main/webapp/plotlog.xhtml
===================================================================
--- /src/main/webapp/plotlog.xhtml	(revision 13)
+++ /src/main/webapp/plotlog.xhtml	(revision 14)
@@ -26,4 +26,6 @@
 		<canvas id="canvas"></canvas>
 	</div>
+	
+	Agreement: <div id="agreement" style="display:inline;">?</div>
 </body>
 
@@ -127,5 +129,5 @@
         	var keys = Object.keys(partyprofileURIs);
 			if (keys.length==0) {
-				plotResults(computeUtils(json, partyprofiles));
+				plotResults(computeUtils(json, partyprofiles), isAgreement(json));
 				return;
 			}
@@ -158,4 +160,12 @@
         
         /**
+        @return true if there is agreement
+        */
+        function isAgreement(logfile) {
+        	var actions=logfile['actions'];
+			var lastact = actions[actions.length -1];
+			return 'accept' in lastact;
+        }
+        /**
         @json the log file contents
         @param partyprofiles a dict with key=party id and value a the (linear additive) profile
@@ -199,8 +209,11 @@
         /**
         @param utilities the dict with key=party id  of the utilities of all steps for each party )
-        */
-        
-        function plotResults( utilities) {
+        @param isAgreement true iff there is agreement reached
+        */
+        
+        function plotResults( utilities, isAgreement) {
         	setStatus("Plotting" )
+        	
+            document.getElementById('agreement').innerHTML=isAgreement?"Yes":"No";
 
         	var parties=Object.keys(utilities);
Index: /src/main/webapp/utilstable.xhtml
===================================================================
--- /src/main/webapp/utilstable.xhtml	(revision 13)
+++ /src/main/webapp/utilstable.xhtml	(revision 14)
@@ -257,8 +257,4 @@
         */
         function addUtilityCell(cell, agreedbid, partyname, profileurl) {
-        	if (Object.keys(agreedbid).lengt==0) {
-            	cell.innerHTML = "0 :"+partyname;
-            	return;
-        	}
         	var util = utility(profiles[profileurl],agreedbid);
         	cell.innerHTML = Math.round(util*1000000)/1000000 +" :"+partyname;
@@ -267,31 +263,4 @@
         
 
-
-        
-        /**
-        @json the log file contents
-        @param partyprofiles a dict with key=party id and value a the (linear additive) profile
-        */
-        function computeUtils(json, partyprofiles) {
-        	
-        	setStatus("Computing utilities.")
-        	var utilities={};
-			for (var party in partyprofiles) {
-				utilities[party]=[];
-			}
-        	var actions = json['actions'];
-        	for (var action in actions) {
-        		var offer = actions[action];
-        		if (offer['offer']==undefined)
-        			continue;
-        		var issueutilities = offer['offer']['bid']['issuevalues']
-				for (var party in partyprofiles) {
-					utilities[party].push(utility(partyprofiles[party],issueutilities));
-				}
-        	}
-        	return utilities;
-        	
-        	
-        }
 
 
@@ -324,9 +293,24 @@
 		/**
 	 	Compute utilityes
-	 	@param linadditive the linear additive utility space
+	 	@param profile the linear additive utility space
 	 	@param issueValues the bid containing dict with values for the issues
-	 	@return utility of issueValues
+	 	@param isResBidAlternative true if the reservation bid is usable as alternative bid
+	 	  . If true, and the issueValues list is empty/null, this returns the utility
+	 	  of the reservation bid instead.
+	 	@return utility of issueValues. Returns 0 if profile =null or no bid available
+	 	
 	 	*/
-	 	function utility(profile, issueValues) {
+	 	function utility(profile, issueValues, isResBidAlternative) {
+	 		if (profile==null) return 0;
+
+	 		// check if we need the reservationbid.
+			if (issueValues==null || Object.keys(issueValues).length==0) {
+	 			var resBid = profile['reservationBid'];
+	 			if (resBid==null) return 0;
+	 			issueValues = resBid['issuevalues'];
+	 		}
+	 		
+	 		if (issueValues==null) return 0;
+	 		
 			var util=0;
 			var weights = profile['issueWeights'];
@@ -359,5 +343,7 @@
 			if (utilfunc['discreteutils']!=undefined) {
 				// it's discrete issue. Compute
-				return utilfunc['discreteutils']['valueUtilities'][value];
+				if (value in utilfunc['discreteutils']['valueUtilities']) 
+					return utilfunc['discreteutils']['valueUtilities'][value];
+				return 0;
 			}
 	    	setStatus("Unknown utility function type "+Object.keys(utilfunc));
