Index: exampleparties/randomparty/src/main/java/geniusweb/exampleparties/randomparty/RandomParty.java
===================================================================
--- exampleparties/randomparty/src/main/java/geniusweb/exampleparties/randomparty/RandomParty.java	(revision 29)
+++ exampleparties/randomparty/src/main/java/geniusweb/exampleparties/randomparty/RandomParty.java	(revision 30)
@@ -6,4 +6,5 @@
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Random;
 import java.util.Set;
@@ -16,5 +17,7 @@
 import geniusweb.actions.PartyId;
 import geniusweb.actions.Vote;
+import geniusweb.actions.VoteWithValue;
 import geniusweb.actions.Votes;
+import geniusweb.actions.VotesWithValue;
 import geniusweb.bidspace.AllPartialBidsList;
 import geniusweb.inform.ActionDone;
@@ -22,4 +25,5 @@
 import geniusweb.inform.Inform;
 import geniusweb.inform.OptIn;
+import geniusweb.inform.OptInWithValue;
 import geniusweb.inform.Settings;
 import geniusweb.inform.Voting;
@@ -38,6 +42,8 @@
 
 /**
- * A simple party that places random bids and accepts when it receives an offer
- * with sufficient utility.
+ * A party that places random bids and accepts when it receives an offer with
+ * sufficient utility. This party is also a demo on how to support the various
+ * protocols, which causes this party to look a bit complex.
+ * 
  * <h2>parameters</h2>
  * <table >
@@ -60,8 +66,9 @@
 	private PartyId me;
 	private final Random random = new Random();
-	protected ProfileInterface profileint;
+	protected ProfileInterface profileint = null;
 	private Progress progress;
 	private Settings settings;
 	private Votes lastvotes;
+	private VotesWithValue lastvoteswithvalue;
 	private String protocol;
 
@@ -95,9 +102,18 @@
 				getReporter().log(Level.INFO, "Final ourcome:" + info);
 			} else if (info instanceof Voting) {
-				lastvotes = vote((Voting) info);
-				getConnection().send(lastvotes);
+				switch (protocol) {
+				case "MOPAC":
+					lastvotes = vote((Voting) info);
+					getConnection().send(lastvotes);
+					break;
+				case "MOPAC2":
+					lastvoteswithvalue = voteWithValue((Voting) info);
+					getConnection().send(lastvoteswithvalue);
+				}
 			} else if (info instanceof OptIn) {
 				// just repeat our last vote.
 				getConnection().send(lastvotes);
+			} else if (info instanceof OptInWithValue) {
+				getConnection().send(lastvoteswithvalue);
 			}
 		} catch (Exception e) {
@@ -110,5 +126,5 @@
 	public Capabilities getCapabilities() {
 		return new Capabilities(
-				new HashSet<>(Arrays.asList("SAOP", "AMOP", "MOPAC")),
+				new HashSet<>(Arrays.asList("SAOP", "AMOP", "MOPAC", "MOPAC2")),
 				Collections.singleton(Profile.class));
 	}
@@ -119,4 +135,15 @@
 				+ "Parameters minPower and maxPower can be used to control voting behaviour.";
 	}
+
+	@Override
+	public void terminate() {
+		super.terminate();
+		if (this.profileint != null) {
+			this.profileint.close();
+			this.profileint = null;
+		}
+	}
+
+	/******************* private support funcs ************************/
 
 	/**
@@ -137,4 +164,8 @@
 		case "MOPAC":
 			if (!(info instanceof OptIn))
+				return;
+			break;
+		case "MOPAC2":
+			if (!(info instanceof OptInWithValue))
 				return;
 			break;
@@ -213,3 +244,34 @@
 	}
 
+	/**
+	 * @param voting the {@link Voting} object containing the options
+	 * 
+	 * @return our next Votes. Returns only votes on good bids and tries to
+	 *         distribute vote values evenly over all good bids.
+	 */
+	private VotesWithValue voteWithValue(Voting voting) throws IOException {
+		Object val = settings.getParameters().get("minPower");
+		Integer minpower = (val instanceof Integer) ? (Integer) val : 2;
+		val = settings.getParameters().get("maxPower");
+		Integer maxpower = (val instanceof Integer) ? (Integer) val
+				: Integer.MAX_VALUE;
+
+		List<Bid> goodbids = voting.getBids().stream().distinct()
+				.filter(offer -> isGood(offer.getBid()))
+				.map(offer -> offer.getBid()).collect(Collectors.toList());
+
+		if (goodbids.isEmpty()) {
+			return new VotesWithValue(me, Collections.emptySet());
+		}
+		// extra difficulty now is to have the utility sum to exactly 100
+		int mostvalues = 100 / goodbids.size();
+		int value = 100 - mostvalues * (goodbids.size() - 1);
+		Set<VoteWithValue> votes = new HashSet<>();
+		for (Bid bid : goodbids) {
+			votes.add(new VoteWithValue(me, bid, minpower, maxpower, value));
+			value = mostvalues;
+		}
+		return new VotesWithValue(me, votes);
+	}
+
 }
Index: exampleparties/randomparty/src/test/java/geniusweb/exampleparties/randomparty/RandomPartyTest.java
===================================================================
--- exampleparties/randomparty/src/test/java/geniusweb/exampleparties/randomparty/RandomPartyTest.java	(revision 29)
+++ exampleparties/randomparty/src/test/java/geniusweb/exampleparties/randomparty/RandomPartyTest.java	(revision 30)
@@ -37,4 +37,5 @@
 import geniusweb.actions.PartyId;
 import geniusweb.actions.Votes;
+import geniusweb.actions.VotesWithValue;
 import geniusweb.bidspace.AllBidsList;
 import geniusweb.connection.ConnectionEnd;
@@ -71,6 +72,7 @@
 	private final ProtocolRef protocol = new ProtocolRef(SAOP);
 	private final ProtocolRef mopacProtocol = new ProtocolRef("MOPAC");
+	private final ProtocolRef mopac2Protocol = new ProtocolRef("MOPAC2");
 	private final ProgressRounds progress = mock(ProgressRounds.class);
-	private Settings settings, mopacSettings;
+	private Settings settings, mopacSettings, mopac2Settings;
 	private LinearAdditive profile;
 	private final Parameters parameters = new Parameters();
@@ -86,4 +88,7 @@
 				new ProfileRef(new URI("file:" + PROFILE)), mopacProtocol,
 				progress, parameters);
+		mopac2Settings = new Settings(PARTY1,
+				new ProfileRef(new URI("file:" + PROFILE)), mopac2Protocol,
+				progress, parameters);
 
 		String serialized = new String(Files.readAllBytes(Paths.get(PROFILE)),
@@ -235,4 +240,20 @@
 	}
 
+	@Test
+	public void testVotingWithValue() throws URISyntaxException {
+		party.connect(connection);
+		party.notifyChange(mopac2Settings);
+
+		Bid bid = findGoodBid();
+		Offer offer = new Offer(PARTY1, bid);
+		party.notifyChange(new Voting(Arrays.asList(offer),
+				Collections.singletonMap(PARTY1, 1)));
+		assertEquals(1, connection.getActions().size());
+		Action action = connection.getActions().get(0);
+		assertTrue(action instanceof VotesWithValue);
+		assertEquals(1, ((VotesWithValue) action).getVotes().size());
+		assertEquals(bid, ((VotesWithValue) action).getVotes().iterator().next()
+				.getBid());
+	}
 }
 
Index: exampleparties/randomparty/src/test/resources/testprofile.json
===================================================================
--- exampleparties/randomparty/src/test/resources/testprofile.json	(revision 29)
+++ exampleparties/randomparty/src/test/resources/testprofile.json	(revision 30)
@@ -27,19 +27,25 @@
 			"issuesValues": {
 				"issue2": {
-					"range": ["12", "18", "1"]
+					"range": [
+						"12",
+						"18",
+						"1"
+					]
 				},
 				"issue1": {
-					"values": ["issue1value1", "issue1value2"]
+					"values": [
+						"issue1value1",
+						"issue1value2"
+					]
 				}
 			}
 		},
 		"name": "testprofile",
-				"reservationBid": {
+		"reservationBid": {
 			"issuevalues": {
-				"issue1": "issuevalue1",
-				"issue2": "12"
+				"issue1": "issue1value1",
+				"issue2": 12
 			}
 		}
-		
 	}
 }
