Index: bidspace/pom.xml
===================================================================
--- bidspace/pom.xml	(revision 52)
+++ bidspace/pom.xml	(revision 1)
@@ -6,5 +6,5 @@
 	<groupId>geniusweb</groupId>
 	<artifactId>bidspace</artifactId>
-	<version>2.1.6</version>
+	<version>1.0.0</version>
 	<packaging>jar</packaging>
 
@@ -15,6 +15,5 @@
 		<basedir>.</basedir>
 		<passwd>${env.ARTIFACTORY_PASS}</passwd>
-		<jackson-2-version>2.12.3</jackson-2-version>
-		<geniusweb.version>${project.version}</geniusweb.version>
+		<jackson-2-version>2.9.6</jackson-2-version>
 	</properties>
 
@@ -22,5 +21,5 @@
 		<repository>
 			<id>artifactory.ewi.tudelft.nl</id>
-			<url>https://artifactory.ewi.tudelft.nl/artifactory/libs-release</url>
+			<url>http://artifactory.ewi.tudelft.nl/artifactory/libs-release</url>
 		</repository>
 	</distributionManagement>
@@ -37,11 +36,11 @@
 			<groupId>geniusweb</groupId>
 			<artifactId>profile</artifactId>
-			<version>${geniusweb.version}</version>
+			<version>1.0.0</version>
 		</dependency>
 
 		<dependency>
 			<groupId>tudelft.utilities</groupId>
-			<artifactId>utilities</artifactId>
-			<version>1.2.1</version>
+			<artifactId>immutablelist</artifactId>
+			<version>1.0.0</version>
 		</dependency>
 
@@ -96,6 +95,6 @@
 		<dependency>
 			<groupId>org.mockito</groupId>
-			<artifactId>mockito-core</artifactId>
-			<version>3.11.2</version>
+			<artifactId>mockito-all</artifactId>
+			<version>1.9.5</version>
 			<scope>test</scope>
 		</dependency>
@@ -104,11 +103,5 @@
 			<groupId>tudelft.utilities</groupId>
 			<artifactId>junit</artifactId>
-			<version>1.0.5</version>
-			<scope>test</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.openjdk.jol</groupId>
-			<artifactId>jol-core</artifactId>
-			<version>0.16</version>
+			<version>1.0.1</version>
 			<scope>test</scope>
 		</dependency>
@@ -120,22 +113,18 @@
 		<repository>
 			<id>artifactory.ewi.tudelft.nl</id>
-			<url>https://artifactory.ewi.tudelft.nl/artifactory/libs-release</url>
+			<url>http://artifactory.ewi.tudelft.nl/artifactory/libs-release</url>
 			<snapshots>
 				<enabled>false</enabled>
 			</snapshots>
 		</repository>
+
 	</repositories>
 
 	<pluginRepositories>
 		<pluginRepository>
-			<id>central</id>
-			<url>https://repo1.maven.org/maven2</url>
-		</pluginRepository>
-		<pluginRepository>
-			<id>artifactory.ewi.tudelft.nl</id>
-			<url>https://artifactory.ewi.tudelft.nl/artifactory/libs-release</url>
+			<id>jcenter</id>
+			<url>http://jcenter.bintray.com</url>
 		</pluginRepository>
 	</pluginRepositories>
-
 
 
@@ -152,22 +141,9 @@
 				</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-javadoc-plugin</artifactId>
-				<version>3.2.0</version>
+				<version>2.10.1</version>
 				<executions>
 					<execution>
@@ -176,4 +152,8 @@
 							<goal>jar</goal>
 						</goals>
+						<configuration>
+							<additionalparam>${javadoc.opts}</additionalparam>
+							<additionalparam>-Xdoclint:none</additionalparam>
+						</configuration>
 					</execution>
 				</executions>
@@ -183,5 +163,5 @@
 				<groupId>org.jfrog.buildinfo</groupId>
 				<artifactId>artifactory-maven-plugin</artifactId>
-				<version>3.2.3</version>
+				<version>2.6.1</version>
 				<executions>
 					<execution>
Index: bidspace/src/main/java/geniusweb/bidspace/AllBidsList.java
===================================================================
--- bidspace/src/main/java/geniusweb/bidspace/AllBidsList.java	(revision 52)
+++ bidspace/src/main/java/geniusweb/bidspace/AllBidsList.java	(revision 1)
@@ -26,8 +26,6 @@
 
 	/**
-	 * This object contains s list containing all bids in the space. This is an
-	 * ImmutableList so it can contain all bids without pre-computing them.
-	 * 
-	 * @param domain the {@link Domain}
+	 * A list containing all bids in the space. This is an ImmutableList so it
+	 * can contain all bids without pre-computing them.
 	 * 
 	 */
Index: bidspace/src/main/java/geniusweb/bidspace/AllPartialBidsList.java
===================================================================
--- bidspace/src/main/java/geniusweb/bidspace/AllPartialBidsList.java	(revision 52)
+++ bidspace/src/main/java/geniusweb/bidspace/AllPartialBidsList.java	(revision 1)
@@ -32,5 +32,4 @@
 	 * pre-computing them.
 	 * 
-	 * @param domain the {@link Domain}
 	 */
 	public AllPartialBidsList(Domain domain) {
Index: bidspace/src/main/java/geniusweb/bidspace/BidsWithUtility.java
===================================================================
--- bidspace/src/main/java/geniusweb/bidspace/BidsWithUtility.java	(revision 52)
+++ 	(revision )
@@ -1,275 +1,0 @@
-package geniusweb.bidspace;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import geniusweb.issuevalue.Bid;
-import geniusweb.issuevalue.Domain;
-import geniusweb.issuevalue.Value;
-import geniusweb.profile.utilityspace.LinearAdditive;
-import tudelft.utilities.immutablelist.AbstractImmutableList;
-import tudelft.utilities.immutablelist.FixedList;
-import tudelft.utilities.immutablelist.ImmutableList;
-import tudelft.utilities.immutablelist.JoinedList;
-import tudelft.utilities.immutablelist.MapList;
-import tudelft.utilities.immutablelist.Tuple;
-
-/**
- * Tool class containing functions dealing with utilities of all bids in a given
- * {@link LinearAdditive}. This class caches previously computed values to
- * accelerate the calls and subsequent calls. Re-use the object to keep/reuse
- * the cache.
- * <h2>Rounding</h2> Internally, utilities of bids are rounded to the given
- * precision. This may cause inclusion/exclusion of some bids in the results.
- * See {@link #BidsWithUtility(LinearAdditive, int)} for more details
- */
-public class BidsWithUtility {
-
-	private final List<IssueInfo> issueInfo;
-	private final int precision; // #digits used for Intervals
-
-	/**
-	 * cache. Key = call arguments for {@link #get(int, Interval)}. Value=return
-	 * value of that call.
-	 */
-	private final Map<Tuple<Integer, Interval>, ImmutableList<Bid>> cache = new HashMap<>();
-	private ImmutableList<Bid> emptylist = new FixedList<>();
-
-	/**
-	 * Default constructor, uses default precision 6. This value seems practical
-	 * for the common range of issues, utilities and weights. See
-	 * {@link #BidsWithUtility(LinearAdditive, int)} for more details on the
-	 * precision.
-	 * 
-	 * @param space the {@link LinearAdditive} to analyze
-	 */
-	public BidsWithUtility(LinearAdditive space) {
-		this(space, 6);
-	}
-
-	/**
-	 * 
-	 * @param space     the {@link LinearAdditive} to analyze
-	 * @param precision the number of digits to use for computations. In
-	 *                  practice, 6 seems a good default value.
-	 *                  <p>
-	 *                  All utilities * weight are rounded to this number of
-	 *                  digits. This value should match the max number of
-	 *                  (digits used in the weight of an issue + number of
-	 *                  digits used in the issue utility). To determine the
-	 *                  optimal value, one may consider the step size of the
-	 *                  issues, and the range of interest. For instance if the
-	 *                  utility function has values 1/3 and 2/3, then these have
-	 *                  an 'infinite' number of relevant digits. But if the goal
-	 *                  is to search bids between utility 0.1 and 0.2, then
-	 *                  computing in 2 digits might already be sufficient.
-	 *                  <p>
-	 *                  This algorithm has memory and space complexity O(
-	 *                  |nissues| 10^precision ). For spaces up to 7 issues, 7
-	 *                  digits should be feasible; for 9 issues, 6 digits may be
-	 *                  the maximum.
-	 */
-	public BidsWithUtility(LinearAdditive space, int precision) {
-		this(getInfo(space, precision), precision);
-	}
-
-	/**
-	 * 
-	 * @param issuesInfo List of the relevant issues (in order of relevance) and
-	 *                   all info of each issue.
-	 * @param precision  the number of digits used in Intervals.
-	 */
-	public BidsWithUtility(List<IssueInfo> issuesInfo, int precision) {
-		if (issuesInfo == null || issuesInfo.isEmpty()) {
-			throw new IllegalArgumentException(
-					"sortedissues list must contain at least 1 element");
-		}
-
-		this.issueInfo = issuesInfo;
-		this.precision = precision;
-
-	}
-
-	/**
-	 * @return the (rounded) utility {@link Interval} of this space: minimum and
-	 *         maximum achievable utility.
-	 */
-	public Interval getRange() {
-		return getRange(issueInfo.size() - 1);
-	}
-
-	/**
-	 * 
-	 * @param range the minimum and maximum utility required of the bids. to be
-	 *              included (both ends inclusive).
-	 * @return a list with bids that have a (rounded) utility inside range.
-	 *         possibly empty.
-	 */
-	public ImmutableList<Bid> getBids(Interval range) {
-		return get(issueInfo.size() - 1, range.round(precision));
-	}
-
-	public List<IssueInfo> getInfo() {
-		return Collections.unmodifiableList(issueInfo);
-	}
-
-	/**
-	 * 
-	 * @param isMax the extreme bid required
-	 * @return the extreme bid, either the minimum if isMax=false or maximum if
-	 *         isMax=true
-	 */
-	public Bid getExtremeBid(boolean isMax) {
-		Map<String, Value> map = new HashMap<>();
-		for (IssueInfo info : issueInfo) {
-			map.put(info.getName(), info.getExtreme(isMax));
-		}
-		return new Bid(map);
-	}
-
-	/**
-	 * Create partial BidsWithUtil list considering only issues 0..n, with
-	 * utilities in given range.
-	 * <h2>Memory use</h2> Memory use of the return value can be large, if large
-	 * domains are given and the requested interval contains large numbers of
-	 * bids. To give some idea, here are some typical memory uses:
-	 * <table border="1">
-	 * <tr>
-	 * <td>domain</td>
-	 * <td>mem use (MB) of returned object</td>
-	 * <td>nr. of selected bids</td>
-	 * </tr>
-	 * <tr>
-	 * <td>jobs1</td>
-	 * <td>0.028</td>
-	 * <td>23</td>
-	 * </tr>
-	 * <tr>
-	 * <td>7issues1</td>
-	 * <td>34</td>
-	 * <td>346327</td>
-	 * </tr>
-	 * <tr>
-	 * <td>9issues1</td>
-	 * <td>98</td>
-	 * <td>37160666</td>
-	 * </tr>
-	 * </table>
-	 * 
-	 * @param n    the number of issueRanges to consider, we consider 0..n here.
-	 *             The recursion decreases n until n=0
-	 * @param goal the minimum and maximum utility required of the bids. to be
-	 *             included (both ends inclusive)
-	 * @return BidsWithUtil list, possibly empty.
-	 */
-	protected ImmutableList<Bid> get(int n, Interval goal) {
-		if (goal == null) {
-			throw new NullPointerException("Interval=null");
-		}
-
-		// clamp goal into what is reachable. Avoid caching empty
-		goal = goal.intersect(getRange(n));
-		if (goal.isEmpty()) {
-			return new FixedList<>();
-		}
-
-		Tuple<Integer, Interval> cachetuple = new Tuple<>(n, goal);
-		ImmutableList<Bid> cached = cache.get(cachetuple);
-		if (cached != null) {
-			// hits++;
-			return cached;
-		}
-
-		ImmutableList<Bid> result = checkedGet(n, goal);
-		cache.put(cachetuple, result);
-		return result;
-	}
-
-	private static List<IssueInfo> getInfo(LinearAdditive space2,
-			int precision) {
-		Domain dom = space2.getDomain();
-		return space2.getDomain().getIssues().stream()
-				.map(issue -> new IssueInfo(issue, dom.getValues(issue),
-						space2.getUtilities().get(issue),
-						space2.getWeight(issue), precision))
-				.collect(Collectors.toList());
-	}
-
-	private ImmutableList<Bid> checkedGet(int n, Interval goal) {
-		IssueInfo info = issueInfo.get(n);
-		// issue is the first issuesWithRange.
-		String issue = info.getName();
-
-		if (n == 0)
-			return new OneIssueSubset(info, goal);
-
-		// make new list, joining all sub-lists
-		ImmutableList<Bid> fulllist = emptylist;
-		for (Value val : info.getValues()) {
-			BigDecimal weightedutil = info.getWeightedUtil(val);
-			Interval subgoal = goal.subtract(weightedutil);
-			// recurse: get list of bids for the subspace
-			ImmutableList<Bid> partialbids = get(n - 1, subgoal);
-
-			ImmutableList<Bid> fullbids = new MapList<Bid, Bid>(
-					pbid -> pbid.merge(new Bid(issue, val)), partialbids);
-			if (!fullbids.size().equals(BigInteger.ZERO))
-				fulllist = new JoinedList<Bid>(fullbids, fulllist);
-		}
-		return fulllist;
-	}
-
-	/**
-	 * @param n the maximum issuevalue utility to include. Use n=index of last
-	 *          issue s= (#issues in the domain - 1) for the full range of this
-	 *          domain.
-	 * @return Interval (min, max) of the total weighted utility Interval of
-	 *         issues 0..n. All weighted utilities have been rounded to the set
-	 *         {@link #precision}
-	 */
-	private Interval getRange(int n) {
-		Interval value = Interval.ZERO;
-		for (int i = 0; i <= n; i++) {
-			value = value.add(issueInfo.get(i).getInterval());
-		}
-		return value;
-	}
-
-}
-
-/**
- * List of all one-issue bids that have utility inside given interval.
- */
-class OneIssueSubset extends AbstractImmutableList<Bid> {
-	private final IssueInfo info;
-	private final Interval interval;
-	private BigInteger size;
-
-	/**
-	 * 
-	 * @param info     the {@link IssueInfo}
-	 * @param interval a utility interval (weighted)
-	 */
-	OneIssueSubset(IssueInfo info, Interval interval) {
-		this.info = info;
-		this.interval = interval;
-		this.size = BigInteger.valueOf(info.subsetSize(interval));
-	}
-
-	@Override
-	public Bid get(BigInteger index) {
-		return new Bid(info.getName(),
-				info.subset(interval).get(index.intValue()));
-	}
-
-	@Override
-	public BigInteger size() {
-		return size;
-	}
-
-}
Index: bidspace/src/main/java/geniusweb/bidspace/FrequencyOpponentModel.java
===================================================================
--- bidspace/src/main/java/geniusweb/bidspace/FrequencyOpponentModel.java	(revision 1)
+++ bidspace/src/main/java/geniusweb/bidspace/FrequencyOpponentModel.java	(revision 1)
@@ -0,0 +1,194 @@
+package geniusweb.bidspace;
+
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import geniusweb.issuevalue.Bid;
+import geniusweb.issuevalue.Domain;
+import geniusweb.issuevalue.NumberValue;
+import geniusweb.issuevalue.Value;
+import geniusweb.profile.utilityspace.NumberValueSetUtilities;
+
+/**
+ * implements an {@link OpponentModel} by counting frequencies of bids placed by
+ * the opponent.
+ * <p>
+ * NOTE: {@link NumberValue}s are also treated as 'discrete', so the frequency
+ * of one value does not influence the influence the frequency of nearby values
+ * (as you might expect as {@link NumberValueSetUtilities} is only affected by
+ * the endpoints).
+ *
+ */
+public class FrequencyOpponentModel implements OpponentModel {
+
+	private static final int DECIMALS = 4; // accuracy of our computations.
+	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) {
+		// map with empth hashmap for each issue.
+		this(domain,
+				domain.getIssues().stream().collect(
+						Collectors.toMap(iss -> iss, iss -> new HashMap<>())),
+				BigDecimal.ZERO);
+	}
+
+	@Override
+	public BigDecimal getUtility(Bid bid) {
+		String err = domain.isComplete(bid);
+		if (err != null) {
+			throw new IllegalArgumentException(err);
+		}
+		if (totalBids == BigDecimal.ZERO) {
+			return BigDecimal.ONE;
+		}
+		BigDecimal sum = BigDecimal.ZERO;
+		// Assume all issues have equal weight.
+		for (String issue : domain.getIssues()) {
+			sum = sum.add(getFraction(issue, bid.getValue(issue)));
+		}
+		return sum.divide(new BigDecimal(bidFrequencies.size()), DECIMALS,
+				BigDecimal.ROUND_HALF_UP);
+	}
+
+	@Override
+	public String getName() {
+		return "FreqOppModel" + (serial++) + "For" + domain;
+	}
+
+	/**
+	 * 
+	 * @param issue the issue to check
+	 * @param value the value to check
+	 * @return the fraction of the total cases that bids contained given value
+	 *         for the issue.
+	 */
+	private BigDecimal getFraction(String issue, Value value) {
+		if (totalBids == BigDecimal.ZERO) {
+			return BigDecimal.ONE;
+		}
+		Integer freq = bidFrequencies.get(issue).get(value);
+		if (freq == null) {
+			freq = 0;
+		}
+		return new BigDecimal(freq).divide(totalBids, DECIMALS,
+				BigDecimal.ROUND_HALF_UP);
+	}
+
+	@Override
+	public Domain getDomain() {
+		return domain;
+	}
+
+	@Override
+	public OpponentModel update(Bid bid) {
+		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;
+			}
+			freqs.put(value, oldfreq + 1);
+		}
+
+		return new FrequencyOpponentModel(domain, newFreqs,
+				totalBids.add(BigDecimal.ONE));
+	}
+
+	/**
+	 * internal constructor. Assumes the freqs keyset is equal to the available
+	 * issues.
+	 * 
+	 * @param domain the domain
+	 * @param freqs  the observed frequencies for all issue values. This map is
+	 *               assumed to be a fresh private-access only copy.
+	 * @param total  the total number of bids contained in the freqs map. This
+	 *               must be equal to the sum of the Integer values in the
+	 *               {@link #bidFrequencies} for each issue (this is not
+	 *               checked).
+	 */
+	private FrequencyOpponentModel(Domain domain,
+			Map<String, Map<Value, Integer>> freqs, BigDecimal total) {
+		if (domain == null) {
+			throw new NullPointerException("domain=null");
+		}
+		this.domain = domain;
+		this.bidFrequencies = freqs;
+		this.totalBids = total;
+	}
+
+	/**
+	 * 
+	 * @param freqs
+	 * @return deep copy of freqs map.
+	 */
+	private static Map<String, Map<Value, Integer>> cloneMap(
+			Map<String, Map<Value, Integer>> freqs) {
+		Map<String, Map<Value, Integer>> map = new HashMap<>();
+		for (String issue : freqs.keySet()) {
+			map.put(issue, new HashMap<Value, Integer>(freqs.get(issue)));
+		}
+		return map;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result
+				+ ((bidFrequencies == null) ? 0 : bidFrequencies.hashCode());
+		result = prime * result + ((domain == null) ? 0 : domain.hashCode());
+		result = prime * result
+				+ ((totalBids == null) ? 0 : totalBids.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;
+		FrequencyOpponentModel other = (FrequencyOpponentModel) obj;
+		if (bidFrequencies == null) {
+			if (other.bidFrequencies != null)
+				return false;
+		} else if (!bidFrequencies.equals(other.bidFrequencies))
+			return false;
+		if (domain == null) {
+			if (other.domain != null)
+				return false;
+		} else if (!domain.equals(other.domain))
+			return false;
+		if (totalBids == null) {
+			if (other.totalBids != null)
+				return false;
+		} else if (!totalBids.equals(other.totalBids))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "FrequencyOpponentModel[" + totalBids + "," + bidFrequencies
+				+ "]";
+	}
+
+	@Override
+	public Bid getReservationBid() {
+		throw new UnsupportedOperationException();
+	}
+
+}
Index: bidspace/src/main/java/geniusweb/bidspace/Interval.java
===================================================================
--- bidspace/src/main/java/geniusweb/bidspace/Interval.java	(revision 52)
+++ 	(revision )
@@ -1,161 +1,0 @@
-package geniusweb.bidspace;
-
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-
-/**
- * An interval [min, max].
- *
- */
-public class Interval {
-	public static Interval ZERO = new Interval(BigDecimal.ZERO,
-			BigDecimal.ZERO);
-
-	private final BigDecimal min;
-	private final BigDecimal max;
-
-	/**
-	 * AN interval [min,max]. If min &gt; max, then there are no values in this
-	 * interval.
-	 * 
-	 * @param min the minimum value of the interval (inclusive)
-	 * @param max the maximum value of the interval (inclusive)
-	 */
-	public Interval(BigDecimal min, BigDecimal max) {
-		if (min == null || max == null) {
-			throw new NullPointerException("min and max must contain not null");
-		}
-		this.min = min;
-		this.max = max;
-	}
-
-	/**
-	 * 
-	 * @return the minimum value of the interval
-	 */
-	public BigDecimal getMin() {
-		return min;
-	}
-
-	/**
-	 * 
-	 * @return the maximum value of the interval
-	 */
-	public BigDecimal getMax() {
-		return max;
-	}
-
-	/**
-	 * 
-	 * @return true iff this range does not contain any element.
-	 */
-	public boolean isEmpty() {
-		return min.compareTo(max) > 0;
-	}
-
-	/**
-	 * 
-	 * @param value the value to test
-	 * @return true iff min &le; value &le; max
-	 */
-	public boolean contains(BigDecimal value) {
-		return min.compareTo(value) <= 0 && max.compareTo(value) >= 0;
-	}
-
-	/**
-	 * 
-	 * @param other {@link Interval} to be added to this
-	 * @return new interval [ this.min + other.min , this.max + other.max ]
-	 */
-	public Interval add(Interval other) {
-		return new Interval(min.add(other.min), max.add(other.max));
-	}
-
-	/**
-	 * 
-	 * @param other another {@link Interval} intersect with
-	 * @return intersection of this with other. returns null if intersection is
-	 *         empty.
-	 */
-	public Interval intersect(Interval other) {
-		return new Interval(min.max(other.min), max.min(other.max));
-	}
-
-	/**
-	 * 
-	 * @param other the other minmax to deal with
-	 * @return the range of values that, when added to a value from other, will
-	 *         possibly get in our range. effectively, [min-other.max,
-	 *         max-other.min]. Returns null if the resulting range is empty.
-	 */
-	public Interval invert(Interval other) {
-		BigDecimal newmin = min.subtract(other.max);
-		BigDecimal newmax = max.subtract(other.min);
-		if (newmin.compareTo(newmax) > 0)
-			return null;
-		return new Interval(newmin, newmax);
-	}
-
-	/**
-	 * 
-	 * @param value the value to subtract
-	 * @return Interval with both min and max reduced by value.
-	 */
-	public Interval subtract(BigDecimal value) {
-		return new Interval(min.subtract(value), max.subtract(value));
-	}
-
-	public Interval multiply(BigDecimal weight) {
-		return new Interval(min.multiply(weight), max.multiply(weight));
-	}
-
-	@Override
-	public String toString() {
-		return "Interval[" + min + "," + max + "]";
-	}
-
-	/**
-	 * @param precision number of digits required
-	 * @return this but with modified precision. The interval is rounded so that
-	 *         the new interval is inside the old one.
-	 */
-	public Interval round(int precision) {
-		return new Interval(min.setScale(precision, RoundingMode.UP),
-				max.setScale(precision, RoundingMode.DOWN));
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + ((max == null) ? 0 : max.hashCode());
-		result = prime * result + ((min == null) ? 0 : min.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;
-		Interval other = (Interval) obj;
-		if (max == null) {
-			if (other.max != null)
-				return false;
-
-		} else if (max.compareTo(other.max) != 0)
-			// THIS WAS FIXED MANUALLY TO USE COMPARETO
-			return false;
-		if (min == null) {
-			if (other.min != null)
-				return false;
-		} else if (min.compareTo(other.min) != 0)
-			// THIS WAS FIXED MANUALLY TO USE COMPARETO
-			return false;
-		return true;
-	}
-
-}
Index: bidspace/src/main/java/geniusweb/bidspace/IssueInfo.java
===================================================================
--- bidspace/src/main/java/geniusweb/bidspace/IssueInfo.java	(revision 52)
+++ 	(revision )
@@ -1,165 +1,0 @@
-package geniusweb.bidspace;
-
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import geniusweb.issuevalue.Value;
-import geniusweb.issuevalue.ValueSet;
-import geniusweb.profile.utilityspace.ValueSetUtilities;
-
-/**
- * Tool class to collect all relevant info about one issue (from LinearAdditive)
- * in one class. Used for internally grouping data for more efficient
- * processing. This class may change in the future, not recommended for direct
- * use.
- * <p>
- * immutable
- */
-public class IssueInfo {
-	private final String name;
-	private final ValueSet values;
-	private final Interval interval;
-	private final Map<Value, BigDecimal> weightedUtils;
-
-	/**
-	 * 
-	 * @param name      the issue name
-	 * @param values    the {@link ValueSet} of the issue
-	 * @param utils     the {@link ValueSetUtilities} of the issue profile
-	 * @param weight    the weight of the {@link ValueSetUtilities}
-	 * @param precision the precision to compute with. Basically the number of
-	 *                  decimal places used for the computations.
-	 * 
-	 */
-	public IssueInfo(String name, ValueSet values, ValueSetUtilities utils,
-			BigDecimal weight, int precision) {
-		this.name = name;
-		this.values = values;
-		this.weightedUtils = computeWeightedUtils(utils, weight, precision);
-		this.interval = getRange();
-	}
-
-	public ValueSet getValues() {
-		return values;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	/**
-	 * 
-	 * @return weighted minimum and maximum utility achievable with this issue,
-	 *         rounded to the requested precision.
-	 */
-	public Interval getInterval() {
-		return interval;
-	}
-
-	/**
-	 * 
-	 * @param isMax if true the max {@link Value} is returned, else the min is
-	 *              returned.
-	 * @return the extreme value, either the minimum if isMax=false or maximum
-	 *         if isMax=true
-	 */
-	public Value getExtreme(boolean isMax) {
-		BigDecimal extremeutil = null;
-		Value extremeval = null;
-		for (Value val : values) {
-			BigDecimal util = weightedUtils.get(val);
-			if (extremeval == null) {
-				extremeutil = weightedUtils.get(val);
-				extremeval = val;
-			} else {
-				if (isMax) {
-					if (util.compareTo(extremeutil) > 0) {
-						extremeutil = util;
-						extremeval = val;
-					}
-				} else {
-					if (util.compareTo(extremeutil) < 0) {
-						extremeutil = util;
-						extremeval = val;
-					}
-
-				}
-			}
-		}
-		return extremeval;
-	}
-
-	/**
-	 * @param val the issue value to be evaluated
-	 * @return weighted utility of given value, rounded to nearest value with
-	 *         the requested precision number of digits.
-	 */
-	public BigDecimal getWeightedUtil(Value val) {
-		return weightedUtils.get(val);
-	}
-
-	/**
-	 * 
-	 * @param interval an {@link Interval} of utility values.
-	 * @return all values that are inside the interval.
-	 */
-	protected List<Value> subset(Interval interval) {
-
-		List<Value> selection = new ArrayList<>();
-		for (Value value : values) {
-			if (interval.contains(getWeightedUtil(value)))
-				selection.add(value);
-		}
-		return selection;
-	}
-
-	/**
-	 * Faster way to determine subset size, it does not create a list
-	 * 
-	 * @param interval an {@link Interval} of utility values.
-	 * @return size of the subset that you will get from calling subset
-	 */
-	protected int subsetSize(Interval interval) {
-		int n = 0;
-		for (Value value : values)
-			if (interval.contains(getWeightedUtil(value)))
-				n++;
-		return n;
-	}
-
-	/**
-	 * @return the {@link Interval} (minimum and maximum) of the utility of the
-	 *         weighted utility of this issue, properly rounded to the
-	 *         {@link #precision}/
-	 * 
-	 */
-	private Interval getRange() {
-		BigDecimal min = BigDecimal.ONE;
-		BigDecimal max = BigDecimal.ZERO;
-		for (Value value : values) {
-			BigDecimal util = getWeightedUtil(value);
-			if (util.compareTo(min) < 0)
-				min = util;
-			if (util.compareTo(max) > 0)
-				max = util;
-		}
-		return new Interval(min, max);
-
-	}
-
-	private Map<Value, BigDecimal> computeWeightedUtils(
-			ValueSetUtilities utilities, BigDecimal w, int prec) {
-		Map<Value, BigDecimal> map = new HashMap<>();
-
-		for (Value val : values) {
-			map.put(val, utilities.getUtility(val).multiply(w).setScale(prec,
-					RoundingMode.HALF_UP));
-		}
-		return map;
-	}
-
-}
Index: bidspace/src/main/java/geniusweb/bidspace/OpponentModel.java
===================================================================
--- bidspace/src/main/java/geniusweb/bidspace/OpponentModel.java	(revision 1)
+++ bidspace/src/main/java/geniusweb/bidspace/OpponentModel.java	(revision 1)
@@ -0,0 +1,18 @@
+package geniusweb.bidspace;
+
+import geniusweb.issuevalue.Bid;
+import geniusweb.profile.utilityspace.UtilitySpace;
+
+/**
+ * An opponentmodel estimates a {@link UtilitySpace} from received opponent
+ * bids.
+ */
+public interface OpponentModel extends UtilitySpace {
+	/**
+	 *
+	 * @param bid the next bid that was received
+	 * @return a new {@link OpponentModel} that takes the next bid into account.
+	 */
+	OpponentModel update(Bid bid);
+
+}
Index: bidspace/src/main/java/geniusweb/bidspace/PartialSpaceFromUtility.java
===================================================================
--- bidspace/src/main/java/geniusweb/bidspace/PartialSpaceFromUtility.java	(revision 52)
+++ 	(revision )
@@ -1,91 +1,0 @@
-package geniusweb.bidspace;
-
-import java.math.BigInteger;
-import java.security.SecureRandom;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import geniusweb.issuevalue.Bid;
-import geniusweb.profile.DefaultPartialOrdering;
-import geniusweb.profile.PartialOrdering;
-import geniusweb.profile.utilityspace.UtilitySpace;
-import tudelft.utilities.immutablelist.ListWithRemove;
-import tudelft.utilities.immutablelist.Tuple;
-import tudelft.utilities.immutablelist.Tuples;
-
-/**
- * Simple demo converting a {@link UtilitySpace} into a {@link PartialOrdering}.
- * Notice, a UtilitySpace IS a PartialOrdering, but a special one that is in
- * fact a full ordering. This converter makes it a space that really has all
- * info removed except for a few basic "isBetter" informations.
- */
-public class PartialSpaceFromUtility extends DefaultPartialOrdering {
-	public PartialSpaceFromUtility(UtilitySpace space, int nRankings) {
-		super(space.getName() + "_" + nRankings, space.getDomain(), space.getReservationBid(),
-				pickBetter(space, nRankings));
-	}
-
-	/**
-	 * Pick subset of static isbetter rankings. Notice, ShuffledList currently can't
-	 * handle really large lists which also limits this. This has to be fixed.
-	 * 
-	 * @param space     the space to sample from
-	 * @param nRankings the number of rankings to be placed in the PartialOrdering.
-	 * @return a subset creating a partial profile of the geiven UtilitySpace
-	 */
-	private static Map<Bid, Set<Bid>> pickBetter(UtilitySpace space, int nRankings) {
-		Map<Bid, Set<Bid>> eqOrBetter = new HashMap<>();
-
-		AllBidsList allbids = new AllBidsList(space.getDomain());
-		ListWithRemove<Tuple<Bid, Bid>> available = new ListWithRemove<>(new Tuples<Bid, Bid>(allbids, allbids));
-		for (int n = 0; n < nRankings; n++) {
-			BigInteger sel = rnd(available.size());
-			Tuple<Bid, Bid> tuple = available.get(sel);
-			Bid bid1 = tuple.get1();
-			Bid bid2 = tuple.get2();
-			switch (space.getUtility(bid1).compareTo(space.getUtility(bid2))) {
-			case -1: // bid1 is worse
-				add(eqOrBetter, bid2, bid1);
-				break;
-			case 0:
-				add(eqOrBetter, bid2, bid1);
-				add(eqOrBetter, bid1, bid2);
-				break;
-			case 1:// bid1 is better
-				add(eqOrBetter, bid1, bid2);
-				break;
-			}
-			available = available.remove(sel);
-		}
-		return eqOrBetter;
-	}
-
-	/**
-	 * 
-	 * @param eqOrBetter map to be extended with (key=bid1, value=bid2)
-	 * @param bid1       the key to add a value to
-	 * @param bid2       the value to be added
-	 */
-	private static void add(Map<Bid, Set<Bid>> eqOrBetter, Bid bid1, Bid bid2) {
-		Set<Bid> set = eqOrBetter.get(bid1);
-		if (set == null) {
-			set = new HashSet<Bid>();
-		}
-		set.add(bid2);
-		eqOrBetter.put(bid1, set);
-	}
-
-	/**
-	 * Bit simplistic way to generate random in [0,n>. Simplistic because the mod()
-	 * operator that we use causes bias in the random numbers.
-	 * 
-	 * @param n the maximum value for the random number
-	 * @return random in [0,n>
-	 * 
-	 */
-	private static final BigInteger rnd(BigInteger n) {
-		return new BigInteger(n.bitLength(), new SecureRandom()).mod(n);
-	}
-}
Index: bidspace/src/main/java/geniusweb/bidspace/pareto/GenericPareto.java
===================================================================
--- bidspace/src/main/java/geniusweb/bidspace/pareto/GenericPareto.java	(revision 52)
+++ bidspace/src/main/java/geniusweb/bidspace/pareto/GenericPareto.java	(revision 1)
@@ -1,6 +1,4 @@
 package geniusweb.bidspace.pareto;
 
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
@@ -16,11 +14,10 @@
 /**
  * A set of all pareto points associated with a set of profiles. Generally
- * applicable but slow. It is recommended to use {@link ParetoLinearAdditive} if
- * applicable.
+ * applicable but slow.
  */
 public class GenericPareto implements ParetoFrontier {
 
 	private final List<? extends PartialOrdering> profiles;
-	private transient Set<Bid> paretobids = null; // cache
+	private Set<Bid> paretobids = null;
 
 	/**
@@ -38,5 +35,5 @@
 					"at least 2 profiles are needed");
 		}
-		if (profiles.contains(null)) {
+		if (profiles.stream().anyMatch(profile -> profile == null)) {
 			throw new IllegalArgumentException("Profiles must not be null");
 		}
@@ -49,10 +46,10 @@
 			}
 		}
-		this.profiles = new ArrayList<>(profiles);
+		this.profiles = profiles;
 	}
 
 	@Override
-	public List<Profile> getProfiles() {
-		return Collections.unmodifiableList(profiles);
+	public List<? extends Profile> getProfiles() {
+		return profiles;
 	}
 
@@ -61,5 +58,5 @@
 		if (paretobids == null)
 			computePareto();
-		return Collections.unmodifiableSet(paretobids);
+		return paretobids;
 	}
 
Index: bidspace/src/main/java/geniusweb/bidspace/pareto/ParetoLinearAdditive.java
===================================================================
--- bidspace/src/main/java/geniusweb/bidspace/pareto/ParetoLinearAdditive.java	(revision 52)
+++ bidspace/src/main/java/geniusweb/bidspace/pareto/ParetoLinearAdditive.java	(revision 1)
@@ -10,13 +10,13 @@
 import geniusweb.issuevalue.Domain;
 import geniusweb.profile.Profile;
-import geniusweb.profile.utilityspace.LinearAdditive;
+import geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace;
 
 /**
- * pareto frontier implementation for {@link LinearAdditive}. This is a highly
- * optimized pareto method for {@link LinearAdditive} spaces
+ * pareto frontier implementation for {@link LinearAdditiveUtilitySpace}.
+ * Simplistic implementation that iterates over all bids.
  */
 public class ParetoLinearAdditive implements ParetoFrontier {
 
-	private final List<LinearAdditive> utilSpaces;
+	private final List<LinearAdditiveUtilitySpace> utilSpaces;
 	private Set<Bid> points = null;
 	// all issues in a deterministic order
@@ -24,8 +24,9 @@
 	/**
 	 * 
-	 * @param utilSpaces. Must contain at least two {@link LinearAdditive}s and
-	 *                    all must be defined on the same donain.
+	 * @param utilSpaces. Must contain at least two
+	 *                    {@link LinearAdditiveUtilitySpace}s and all must be
+	 *                    defined on the same donain.
 	 */
-	public ParetoLinearAdditive(List<LinearAdditive> utilSpaces) {
+	public ParetoLinearAdditive(List<LinearAdditiveUtilitySpace> utilSpaces) {
 		if (utilSpaces == null || utilSpaces.size() < 2) {
 			throw new IllegalArgumentException(
@@ -33,5 +34,5 @@
 		}
 		Domain domain = utilSpaces.get(0).getDomain();
-		for (LinearAdditive space : utilSpaces) {
+		for (LinearAdditiveUtilitySpace space : utilSpaces) {
 			if (!space.getDomain().equals(domain)) {
 				throw new IllegalArgumentException(
Index: bidspace/src/main/java/geniusweb/bidspace/pareto/ParetoPoint.java
===================================================================
--- bidspace/src/main/java/geniusweb/bidspace/pareto/ParetoPoint.java	(revision 52)
+++ bidspace/src/main/java/geniusweb/bidspace/pareto/ParetoPoint.java	(revision 1)
@@ -3,9 +3,12 @@
 import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 
 import geniusweb.issuevalue.Bid;
-import geniusweb.profile.utilityspace.LinearAdditive;
+import geniusweb.issuevalue.Value;
+import geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace;
 
 /**
@@ -23,10 +26,10 @@
 	 * 
 	 * @param bid    a (possibly partial) {@link Bid}
-	 * @param spaces the {@link LinearAdditive}s to consider
+	 * @param spaces the {@link LinearAdditiveUtilitySpace}s to consider
 	 */
-	public ParetoPoint(Bid bid, List<LinearAdditive> spaces) {
+	public ParetoPoint(Bid bid, List<LinearAdditiveUtilitySpace> spaces) {
 		this.bid = bid;
 		utilities = new ArrayList<>();
-		for (LinearAdditive space : spaces) {
+		for (LinearAdditiveUtilitySpace space : spaces) {
 			utilities.add(space.getUtility(bid));
 		}
@@ -46,4 +49,11 @@
 	 */
 	public ParetoPoint merge(ParetoPoint otherpoint) {
+		Map<String, Value> issuevalues = new HashMap<>();
+		for (String issue : bid.getIssues()) {
+			issuevalues.put(issue, bid.getValue(issue));
+		}
+		for (String issue : otherpoint.bid.getIssues()) {
+			issuevalues.put(issue, otherpoint.bid.getValue(issue));
+		}
 		List<BigDecimal> summedutils = new LinkedList<>();
 		for (int n = 0; n < utilities.size(); n++) {
@@ -51,5 +61,5 @@
 		}
 
-		return new ParetoPoint(summedutils, bid.merge(otherpoint.getBid()));
+		return new ParetoPoint(summedutils, new Bid(issuevalues));
 	}
 
Index: bidspace/src/main/java/geniusweb/bidspace/pareto/PartialPareto.java
===================================================================
--- bidspace/src/main/java/geniusweb/bidspace/pareto/PartialPareto.java	(revision 52)
+++ bidspace/src/main/java/geniusweb/bidspace/pareto/PartialPareto.java	(revision 1)
@@ -8,5 +8,5 @@
 import geniusweb.issuevalue.Bid;
 import geniusweb.issuevalue.Value;
-import geniusweb.profile.utilityspace.LinearAdditive;
+import geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace;
 
 /**
@@ -28,5 +28,5 @@
 	 * implemented recursively (O(log(#issues))).
 	 * 
-	 * @param utilSpaces the {@link LinearAdditive}s
+	 * @param utilSpaces the {@link LinearAdditiveUtilitySpace}s
 	 * @param issues     the issues (subset of all issues in the space) to be
 	 *                   used for this pareto
@@ -34,6 +34,6 @@
 	 *         given issues.
 	 */
-	public static PartialPareto create(List<LinearAdditive> utilSpaces,
-			List<String> issues) {
+	public static PartialPareto create(
+			List<LinearAdditiveUtilitySpace> utilSpaces, List<String> issues) {
 
 		if (issues.size() == 1) {
Index: bidspace/src/test/java/geniusweb/bidspace/BidsWithUtilityTest.java
===================================================================
--- bidspace/src/test/java/geniusweb/bidspace/BidsWithUtilityTest.java	(revision 52)
+++ 	(revision )
@@ -1,154 +1,0 @@
-package geniusweb.bidspace;
-
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.math.RoundingMode;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Random;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import geniusweb.issuevalue.Bid;
-import geniusweb.profile.Profile;
-import geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace;
-import tudelft.utilities.immutablelist.ImmutableList;
-
-@RunWith(Parameterized.class)
-public class BidsWithUtilityTest {
-	private final static ObjectMapper jackson = new ObjectMapper();
-	private final Interval utilityGoal = new Interval(new BigDecimal("0.50"),
-			new BigDecimal("0.51"));
-	private LinearAdditiveUtilitySpace profile;
-	private long expectedSize;
-	private int accuracy = 5;
-	private final static Runtime r = Runtime.getRuntime();
-
-	@Parameters
-	public static Collection<Object[]> data() {
-		return Arrays.asList(new Object[][] {
-				{ "src/test/resources/jobs/jobs1.json", 11 },
-				{ "src/test/resources/7issues/7issues1.json", 260000 },
-				{ "src/test/resources/9issues/9issues1.json", 25000000 } });
-	}
-
-	public BidsWithUtilityTest(String filename, long expectedsize)
-			throws IOException {
-		String file = new String(Files.readAllBytes(Paths.get(filename)));
-		profile = (LinearAdditiveUtilitySpace) jackson.readValue(file,
-				Profile.class);
-		this.expectedSize = expectedsize;
-	}
-
-	/**
-	 * Test if the values are within acceptable range from the goal.
-	 */
-	@Test
-	public void test() {
-		ImmutableList<Bid> list = new BidsWithUtility(profile, accuracy)
-				.getBids(utilityGoal);
-		Random rand = new Random();
-		// check not all but only 10000 random bids as list may be way too large
-		// to test them all. Testing 1 billion bids may take 15 minutes or so on
-		// quad core i7 @2.4GHz.....
-		// also notice that we may be checking only part of the list if
-		// the size of the list would become bigger than maxint.
-		for (int n = 0; n < 10000; n++) {
-			Bid bid = list.get(rand.nextInt(list.size().intValue()));
-			assertTrue(utilityGoal.contains(profile.getUtility(bid)
-					.setScale(accuracy - 1, RoundingMode.HALF_UP)));
-		}
-		assertTrue(
-				list.size().compareTo(BigInteger.valueOf(expectedSize)) >= 0);
-
-	}
-
-	@Test
-	public void testMaxUtil() {
-		BidsWithUtility bidswithutil = new BidsWithUtility(profile);
-		// notice, this is the *rounded* max util
-		BigDecimal maxutil = bidswithutil.getRange().getMax();
-		Interval goal = new Interval(
-				maxutil.subtract(new BigDecimal("0.00001")), maxutil);
-
-		ImmutableList<Bid> bidsnearmax = bidswithutil.getBids(goal);
-		assertTrue(bidsnearmax.size() != BigInteger.ZERO);
-
-		BigDecimal foundmax = BigDecimal.ZERO;
-		for (Bid bid : bidsnearmax) {
-			BigDecimal util = profile.getUtility(bid);
-			if (util.compareTo(foundmax) > 0) {
-				foundmax = util;
-			}
-		}
-		// found maximum may be slightly lower or higher because we rounded
-		// all weighted utilities.
-		assertTrue(Math
-				.abs(foundmax.doubleValue() - maxutil.doubleValue()) < 0.0001);
-	}
-
-	@Test
-	public void benchmark() {
-		System.out.println("\nBenchmarking " + profile.getName());
-		BigInteger domainsize = new AllBidsList(profile.getDomain()).size();
-
-		long presize = usedMemory();
-		long start = System.currentTimeMillis();
-		BidsWithUtility body = new BidsWithUtility(profile, accuracy);
-		ImmutableList<Bid> list = body.getBids(utilityGoal);
-		long end = System.currentTimeMillis();
-		long postsize = usedMemory();
-		System.out.println("run time: " + (end - start) / 1000. + "s");
-		System.out.println("Total size of complete domain:" + domainsize);
-		System.out.println("size of selection: " + list.size());
-		System.out.println("Memory use of selection(MB):"
-				+ (double) (postsize - presize) / (1024 * 1024));
-	}
-
-	/**
-	 * see https://www.geeksforgeeks.org/java-lang-runtime-class-in-java/
-	 * 
-	 * @return currently used memory after doing GC.
-	 * 
-	 */
-	public static long usedMemory() {
-		for (int n = 0; n < 4; n++)
-			gc1(); // repeat as gct seems getting more agressive then
-		return used();
-	}
-
-	/**
-	 * 
-	 * @return used heap mem. Does NOT GC. Uses {@link Runtime#totalMemory()}
-	 *         and {@link Runtime#freeMemory()} to avoid problems when JVM gets
-	 *         more system memory which can happen at any time.
-	 */
-	private static long used() {
-		return r.totalMemory() - r.freeMemory();
-	}
-
-	/**
-	 * repeat garbage collection till heap memory gets stable
-	 */
-	private static void gc1() {
-		long usedMem1 = used(), usedMem2 = Long.MAX_VALUE;
-		for (int i = 0; (usedMem1 < usedMem2) && (i < 500); ++i) {
-			r.runFinalization();
-			r.gc();
-			Thread.currentThread().yield();
-
-			usedMem2 = usedMem1;
-			usedMem1 = used();
-		}
-	}
-}
Index: bidspace/src/test/java/geniusweb/bidspace/FrequencyOppModelTest.java
===================================================================
--- bidspace/src/test/java/geniusweb/bidspace/FrequencyOppModelTest.java	(revision 1)
+++ bidspace/src/test/java/geniusweb/bidspace/FrequencyOppModelTest.java	(revision 1)
@@ -0,0 +1,138 @@
+package geniusweb.bidspace;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Test;
+
+import geniusweb.bidspace.FrequencyOpponentModel;
+import geniusweb.bidspace.OpponentModel;
+import geniusweb.issuevalue.Bid;
+import geniusweb.issuevalue.DiscreteValue;
+import geniusweb.issuevalue.DiscreteValueSet;
+import geniusweb.issuevalue.Domain;
+import geniusweb.issuevalue.NumberValue;
+import geniusweb.issuevalue.NumberValueSet;
+import geniusweb.issuevalue.Value;
+import geniusweb.issuevalue.ValueSet;
+import tudelft.utilities.junit.GeneralTests;
+
+public class FrequencyOppModelTest extends GeneralTests<FrequencyOpponentModel> {
+	private final static String ISS1 = "issue1";
+	private final static String ISS2 = "issue2";
+	private static final DiscreteValue I1V1 = new DiscreteValue("i1v1");
+	private static final DiscreteValue I1V2 = new DiscreteValue("i1v2");
+	private static final DiscreteValue I1V2b = new DiscreteValue("i1v2b");
+
+	private static Domain domain, domain2, domain3;
+	private static FrequencyOpponentModel oppModel1, oppModel1b, oppModel2, oppModel3, oppModel4;
+
+	private final static List<List<Bid>> list = new LinkedList<>();
+
+	private final static Bid bid1, bid2, bid3;
+	private static final BigDecimal HALF = new BigDecimal("0.5");
+
+	static {
+		Map<String, ValueSet> issues = new HashMap<>();
+		Collection<DiscreteValue> discretevalues1 = new LinkedList<>();
+		discretevalues1.add(I1V1);
+		discretevalues1.add(I1V2);
+		DiscreteValueSet values1 = new DiscreteValueSet(discretevalues1);
+		issues.put(ISS1, values1);
+		NumberValueSet values2 = new NumberValueSet(BigDecimal.ZERO, BigDecimal.TEN, new BigDecimal("0.3"));
+		issues.put(ISS2, values2);
+		domain = new Domain("test", issues);
+		domain2 = new Domain("test2", issues);
+
+		// slightly different issue1
+		issues = new HashMap<>();
+		discretevalues1 = new LinkedList<>();
+		discretevalues1.add(I1V1);
+		discretevalues1.add(I1V2b);
+		values1 = new DiscreteValueSet(discretevalues1);
+		issues.put(ISS1, values1);
+		values2 = new NumberValueSet(BigDecimal.ZERO, BigDecimal.TEN, new BigDecimal("0.3"));
+		issues.put(ISS2, values2);
+		domain3 = new Domain("test", issues);
+
+		// all bids are for domain
+		Map<String, Value> issuevalues = new HashMap<>();
+		issuevalues.put(ISS1, I1V1);
+		issuevalues.put(ISS2, new NumberValue(new BigDecimal("1.2")));
+		bid1 = new Bid(issuevalues);
+
+		issuevalues.put(ISS1, I1V1);
+		issuevalues.put(ISS2, new NumberValue(new BigDecimal("1.5")));
+		bid2 = new Bid(issuevalues);
+
+		issuevalues.put(ISS1, I1V2);
+		issuevalues.put(ISS2, new NumberValue(new BigDecimal("1.5")));
+		bid3 = new Bid(issuevalues);
+
+		oppModel1 = new FrequencyOpponentModel(domain);
+		oppModel1b = new FrequencyOpponentModel(domain);
+		oppModel2 = new FrequencyOpponentModel(domain2);
+		oppModel3 = new FrequencyOpponentModel(domain3);
+		oppModel4 = (FrequencyOpponentModel) oppModel3.update(bid1);
+
+	}
+
+	@Override
+	public List<List<FrequencyOpponentModel>> getGeneralTestData() {
+		return Arrays.asList(Arrays.asList(oppModel1, oppModel1b), Arrays.asList(oppModel2), Arrays.asList(oppModel3),
+				Arrays.asList(oppModel4));
+	}
+
+	@Override
+	public List<String> getGeneralTestStrings() {
+		return Arrays.asList("FrequencyOpponentModel\\[0,\\{issue2=\\{\\}, issue1=\\{\\}\\}\\]",
+				"FrequencyOpponentModel\\[0,\\{issue2=\\{\\}, issue1=\\{\\}\\}\\]",
+				"FrequencyOpponentModel\\[0,\\{issue2=\\{\\}, issue1=\\{\\}\\}\\]",
+				"FrequencyOpponentModel\\[1,\\{issue2=\\{1.2=1\\}, issue1=\\{\"i1v1\"=1\\}\\}\\]");
+	}
+
+	@Test(expected = NullPointerException.class)
+	public void smokeNullTest() {
+		new FrequencyOpponentModel(null);
+	}
+
+	@Test
+	public void smokeTest() {
+		new FrequencyOpponentModel(domain);
+	}
+
+	@Test
+	public void testEmptyModel() {
+		FrequencyOpponentModel oppModel = new FrequencyOpponentModel(domain);
+		assertEquals(BigDecimal.ONE, oppModel.getUtility(bid1));
+		assertEquals(BigDecimal.ONE, oppModel.getUtility(bid2));
+	}
+
+	@Test
+	public void testUpdate() {
+		OpponentModel oppModel = oppModel1.update(bid1);
+		assertTrue(BigDecimal.ONE.compareTo(oppModel.getUtility(bid1)) == 0);
+		assertTrue(BigDecimal.ZERO.compareTo(oppModel.getUtility(bid3)) == 0);
+		// bid2 has 1 of 2 issue values same as bid1.
+		assertTrue(HALF.compareTo(oppModel.getUtility(bid2)) == 0);
+	}
+
+	@Test
+	public void testUpdate2() {
+		// bid1 and bid2 both want I1V1. They differ on the number value.
+		// bid3 wants I1V2 but does have the number value from bid2
+		OpponentModel oppModel = oppModel1.update(bid1).update(bid2);
+		assertTrue(new BigDecimal("0.75").compareTo(oppModel.getUtility(bid1)) == 0);
+		assertTrue(new BigDecimal("0.75").compareTo(oppModel.getUtility(bid2)) == 0);
+		assertTrue(new BigDecimal("0.25").compareTo(oppModel.getUtility(bid3)) == 0);
+	}
+
+}
Index: bidspace/src/test/java/geniusweb/bidspace/IntervalTest.java
===================================================================
--- bidspace/src/test/java/geniusweb/bidspace/IntervalTest.java	(revision 52)
+++ 	(revision )
@@ -1,118 +1,0 @@
-package geniusweb.bidspace;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.math.BigDecimal;
-import java.util.Arrays;
-import java.util.List;
-
-import org.junit.Test;
-
-import tudelft.utilities.junit.GeneralTests;
-
-public class IntervalTest extends GeneralTests<Interval> {
-
-	private static final BigDecimal ZERO = BigDecimal.ZERO;
-	private static final BigDecimal ONE = BigDecimal.ONE;
-	private static final BigDecimal TWO = BigDecimal.valueOf(2);
-	private static final BigDecimal THREE = BigDecimal.valueOf(3);
-	private static final BigDecimal TEN = BigDecimal.TEN;
-	private static final Interval int1 = new Interval(ZERO, ONE);
-	private static final Interval int1a = new Interval(ZERO, ONE);
-	private static final Interval int2 = new Interval(ONE, TEN);
-	private static final Interval int3 = new Interval(TWO, TEN);
-
-	@Override
-	public List<List<Interval>> getGeneralTestData() {
-		return Arrays.asList(Arrays.asList(int1, int1a), Arrays.asList(int2),
-				Arrays.asList(int3));
-	}
-
-	@Override
-	public List<String> getGeneralTestStrings() {
-		return Arrays.asList("Interval\\[0,1\\]", "Interval\\[1,10\\]",
-				"Interval\\[2,10\\]");
-	}
-
-	@Test
-	public void smokeTest() {
-		new Interval(BigDecimal.ZERO, BigDecimal.ONE);
-	}
-
-	@Test
-	public void smokeTestBad() {
-		Interval i = new Interval(BigDecimal.TEN, BigDecimal.ONE);
-		assertTrue(i.isEmpty());
-	}
-
-	@Test(expected = NullPointerException.class)
-	public void smokeNull1() {
-		new Interval(null, BigDecimal.ZERO);
-	}
-
-	@Test(expected = NullPointerException.class)
-	public void smokeNull2() {
-		new Interval(BigDecimal.ZERO, null);
-	}
-
-	@Test
-	public void testMin() {
-		assertEquals(BigDecimal.ZERO, int1.getMin());
-		assertEquals(BigDecimal.ONE, int2.getMin());
-	}
-
-	@Test
-	public void testMax() {
-		assertEquals(BigDecimal.ONE, int1.getMax());
-		assertEquals(BigDecimal.TEN, int2.getMax());
-	}
-
-	@Test
-	public void containsTest() {
-		assertTrue(int1.contains(BigDecimal.valueOf(0.3)));
-		assertFalse(int1.contains(BigDecimal.valueOf(-0.3)));
-		assertFalse(int1.contains(BigDecimal.valueOf(1.3)));
-
-		assertFalse(int3.contains(ZERO));
-		assertFalse(int3.contains(ONE));
-		assertTrue(int3.contains(TWO));
-		assertTrue(int3.contains(THREE));
-		assertTrue(int3.contains(TEN));
-		assertFalse(int3.contains(BigDecimal.valueOf(10.3)));
-
-	}
-
-	@Test
-	public void testIntersect() {
-		assertEquals(int1, int1.intersect(int1));
-		assertEquals(new Interval(ONE, ONE), int1.intersect(int2));
-		assertTrue(int1.intersect(int3).isEmpty());
-		assertEquals(new Interval(ONE, TWO),
-				new Interval(ZERO, TEN).intersect(new Interval(ONE, TWO)));
-		assertEquals(new Interval(ONE, TWO),
-				new Interval(ONE, TWO).intersect(new Interval(ZERO, TEN)));
-		assertEquals(new Interval(ONE, TWO),
-				new Interval(ZERO, TWO).intersect(new Interval(ONE, TEN)));
-		assertEquals(new Interval(ONE, TWO),
-				new Interval(ONE, TEN).intersect(new Interval(ZERO, TWO)));
-	}
-
-	@Test
-	public void subtractTest() {
-		assertEquals(new Interval(BigDecimal.valueOf(-1), ZERO),
-				int1.subtract(ONE));
-	}
-
-	@Test
-	public void invertTest() {
-		assertEquals(new Interval(BigDecimal.valueOf(-10), ZERO),
-				int1.invert(int2));
-		assertEquals(new Interval(ZERO, TEN), int2.invert(int1));
-		assertEquals(
-				new Interval(BigDecimal.valueOf(-9), BigDecimal.valueOf(8)),
-				int2.invert(int3));
-	}
-
-}
Index: bidspace/src/test/java/geniusweb/bidspace/IssueInfoTest.java
===================================================================
--- bidspace/src/test/java/geniusweb/bidspace/IssueInfoTest.java	(revision 52)
+++ 	(revision )
@@ -1,68 +1,0 @@
-package geniusweb.bidspace;
-
-import static org.junit.Assert.assertEquals;
-
-import java.math.BigDecimal;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import geniusweb.issuevalue.DiscreteValue;
-import geniusweb.issuevalue.DiscreteValueSet;
-import geniusweb.issuevalue.ValueSet;
-import geniusweb.profile.utilityspace.DiscreteValueSetUtilities;
-import geniusweb.profile.utilityspace.ValueSetUtilities;
-
-public class IssueInfoTest {
-
-	private static final String NAME = "name";
-	private static final DiscreteValue VAL1 = new DiscreteValue("v1"),
-			VAL2 = new DiscreteValue("v2"), VAL3 = new DiscreteValue("v3");
-	private static final BigDecimal N03 = new BigDecimal("0.3");
-	private static final BigDecimal N04 = new BigDecimal("0.4");
-	private static final BigDecimal N05 = new BigDecimal("0.5");
-	private static final BigDecimal N06 = new BigDecimal("0.6");
-	private IssueInfo info;
-
-	@Before
-	public void before() {
-		Set<DiscreteValue> issuevalues = new HashSet<>();
-		issuevalues.add(VAL1);
-		issuevalues.add(VAL2);
-		issuevalues.add(VAL3);
-		ValueSet values = new DiscreteValueSet(issuevalues);
-		Map<DiscreteValue, BigDecimal> valueUtils = new HashMap<>();
-		valueUtils.put(VAL1, N03);
-		valueUtils.put(VAL2, N04);
-		valueUtils.put(VAL3, N05);
-		ValueSetUtilities utils = new DiscreteValueSetUtilities(valueUtils);
-		info = new IssueInfo(NAME, values, utils, N06, 6);
-	}
-
-	@Test
-	public void smokeTest() {
-
-	}
-
-	@Test
-	public void testGetExtremeMin() {
-
-		assertEquals(VAL1, info.getExtreme(false));
-		assertEquals(VAL3, info.getExtreme(true));
-	}
-
-	@Test
-	public void getNameTest() {
-		assertEquals(NAME, info.getName());
-	}
-
-	@Test
-	public void getIntervalTest() {
-		assertEquals(new Interval(N03.multiply(N06), N05.multiply(N06)),
-				info.getInterval());
-	}
-}
Index: bidspace/src/test/java/geniusweb/bidspace/PartialSpaceFromUtilityTest.java
===================================================================
--- bidspace/src/test/java/geniusweb/bidspace/PartialSpaceFromUtilityTest.java	(revision 52)
+++ 	(revision )
@@ -1,32 +1,0 @@
-package geniusweb.bidspace;
-
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-
-import org.junit.Test;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import geniusweb.profile.Profile;
-import geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace;
-
-public class PartialSpaceFromUtilityTest {
-	private final static ObjectMapper jackson = new ObjectMapper();
-
-	@Test
-	public void createPartialSpaceJobs() throws IOException {
-		String file1 = new String(Files
-				.readAllBytes(Paths.get("src/test/resources/jobs/jobs1.json")));
-		LinearAdditiveUtilitySpace profile = (LinearAdditiveUtilitySpace) jackson
-				.readValue(file1, Profile.class);
-		PartialSpaceFromUtility partial = new PartialSpaceFromUtility(profile,
-				20);
-		System.out.println(jackson.writeValueAsString(partial));
-		int size = partial.getBetter().size();
-		assertTrue(size >= 20); // sometimes 20, sometimes 21
-		assertTrue(size <= 21);
-	}
-}
Index: bidspace/src/test/java/geniusweb/bidspace/pareto/GenericParetoTest.java
===================================================================
--- bidspace/src/test/java/geniusweb/bidspace/pareto/GenericParetoTest.java	(revision 52)
+++ bidspace/src/test/java/geniusweb/bidspace/pareto/GenericParetoTest.java	(revision 1)
@@ -2,11 +2,10 @@
 
 import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
+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 java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -15,9 +14,8 @@
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
-import org.junit.Before;
 import org.junit.Test;
 
+import geniusweb.bidspace.pareto.GenericPareto;
 import geniusweb.issuevalue.Bid;
 import geniusweb.issuevalue.DiscreteValue;
@@ -29,5 +27,4 @@
 import geniusweb.issuevalue.ValueSet;
 import geniusweb.profile.PartialOrdering;
-import geniusweb.profile.Profile;
 
 public class GenericParetoTest {
@@ -42,17 +39,13 @@
 	private static final Map<String, ValueSet> issues = new HashMap<>();
 
-	private static ValueSet values1;
-	private static ValueSet values2;
+	private static final ValueSet values1;
+	private static final ValueSet values2;
 	private static final BigDecimal TWO = new BigDecimal("2");
 	private static final BigDecimal THREE = new BigDecimal("3");
 
-	private static Domain domain;
+	private static final Domain domain;
 	private static Bid bid1, bid2, bid3;
 
-	private PartialOrdering profile1, profile2, profile3;
-	private GenericPareto pareto;
-
-	@Before
-	public void before() {
+	static {
 		Collection<DiscreteValue> discretevalues1 = new LinkedList<>();
 		discretevalues1.add(I1V1);
@@ -77,17 +70,13 @@
 		bid3 = new Bid(issuevalues);
 
-		profile1 = mock(PartialOrdering.class);
-		profile2 = mock(PartialOrdering.class);
-		profile3 = mock(PartialOrdering.class);
-		when(profile1.getDomain()).thenReturn(domain);
-		when(profile2.getDomain()).thenReturn(domain);
-		when(profile3.getDomain()).thenReturn(domain);
-
-		pareto = new GenericPareto(Arrays.asList(profile1, profile2));
-
 	}
 
 	@Test
 	public void genericParetoTest() {
+		PartialOrdering profile1 = mock(PartialOrdering.class);
+		PartialOrdering profile2 = mock(PartialOrdering.class);
+
+		when(profile1.getDomain()).thenReturn(domain);
+		when(profile2.getDomain()).thenReturn(domain);
 
 		// fefault: there is no preference at all, all isPreferredOrEqual
@@ -103,4 +92,9 @@
 	@Test
 	public void genericParetoTest1() {
+		PartialOrdering profile1 = mock(PartialOrdering.class);
+		PartialOrdering profile2 = mock(PartialOrdering.class);
+
+		when(profile1.getDomain()).thenReturn(domain);
+		when(profile2.getDomain()).thenReturn(domain);
 
 		// both prefer bid1 over any other bid.
@@ -109,4 +103,7 @@
 		when(profile2.isPreferredOrEqual(eq(bid1), any(Bid.class)))
 				.thenReturn(true);
+
+		List<PartialOrdering> profiles = Arrays.asList(profile1, profile2);
+		GenericPareto pareto = new GenericPareto(profiles);
 
 		Collection<Bid> points = pareto.getPoints();
@@ -117,4 +114,9 @@
 	@Test
 	public void genericParetoTest2() {
+		PartialOrdering profile1 = mock(PartialOrdering.class);
+		PartialOrdering profile2 = mock(PartialOrdering.class);
+
+		when(profile1.getDomain()).thenReturn(domain);
+		when(profile2.getDomain()).thenReturn(domain);
 
 		// both prefer bid2 over any other bid.
@@ -123,4 +125,6 @@
 		when(profile2.isPreferredOrEqual(eq(bid2), any(Bid.class)))
 				.thenReturn(true);
+		List<PartialOrdering> profiles = Arrays.asList(profile1, profile2);
+		GenericPareto pareto = new GenericPareto(profiles);
 
 		Collection<Bid> points = pareto.getPoints();
@@ -132,4 +136,10 @@
 	@Test
 	public void genericParetoTest3() {
+		PartialOrdering profile1 = mock(PartialOrdering.class);
+		PartialOrdering profile2 = mock(PartialOrdering.class);
+
+		when(profile1.getDomain()).thenReturn(domain);
+		when(profile2.getDomain()).thenReturn(domain);
+
 		// profile1 prefers bid1, profile2 prefers bid2.
 		// now neither bid1 nor bid2 are dominating each other
@@ -139,4 +149,6 @@
 		when(profile2.isPreferredOrEqual(eq(bid2), any(Bid.class)))
 				.thenReturn(true);
+		List<PartialOrdering> profiles = Arrays.asList(profile1, profile2);
+		GenericPareto pareto = new GenericPareto(profiles);
 
 		Collection<Bid> points = pareto.getPoints();
@@ -147,4 +159,9 @@
 	@Test
 	public void genericParetoTest4() {
+		PartialOrdering profile1 = mock(PartialOrdering.class);
+		PartialOrdering profile2 = mock(PartialOrdering.class);
+
+		when(profile1.getDomain()).thenReturn(domain);
+		when(profile2.getDomain()).thenReturn(domain);
 
 		// profile1 prefers bid1, profile2 prefers bid2.
@@ -158,4 +175,6 @@
 		when(profile2.isPreferredOrEqual(eq(bid2), any(Bid.class)))
 				.thenReturn(true);
+		List<PartialOrdering> profiles = Arrays.asList(profile1, profile2);
+		GenericPareto pareto = new GenericPareto(profiles);
 
 		Collection<Bid> points = pareto.getPoints();
@@ -164,31 +183,3 @@
 	}
 
-	@Test(expected = IllegalArgumentException.class)
-	public void testNullNotOk() {
-		new GenericPareto(Arrays.asList(profile1, null, profile1));
-	}
-
-	@Test
-	public void testImmutable() {
-		List<PartialOrdering> list = new ArrayList<>(
-				Arrays.asList(profile1, profile2));
-		GenericPareto pareto = new GenericPareto(list);
-		// if we modify the list, the pareto should not change
-		list.add(profile3);
-		assertEquals(2, pareto.getProfiles().size());
-	}
-
-	@Test(expected = UnsupportedOperationException.class)
-	public void testGetParetoAndAdd() {
-		List<Profile> list = pareto.getProfiles();
-		list.add(profile3);
-
-	}
-
-	@Test(expected = UnsupportedOperationException.class)
-	public void testGetPointsAndAdd() {
-		Set<Bid> list = pareto.getPoints();
-		list.add(bid1);
-	}
-
 }
Index: bidspace/src/test/java/geniusweb/bidspace/pareto/ParetoE2Etest.java
===================================================================
--- bidspace/src/test/java/geniusweb/bidspace/pareto/ParetoE2Etest.java	(revision 52)
+++ bidspace/src/test/java/geniusweb/bidspace/pareto/ParetoE2Etest.java	(revision 1)
@@ -19,6 +19,8 @@
 import com.fasterxml.jackson.databind.ObjectMapper;
 
+import geniusweb.bidspace.pareto.GenericPareto;
+import geniusweb.bidspace.pareto.ParetoFrontier;
+import geniusweb.bidspace.pareto.ParetoLinearAdditive;
 import geniusweb.profile.Profile;
-import geniusweb.profile.utilityspace.LinearAdditive;
 import geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace;
 
@@ -36,5 +38,5 @@
 						"src/test/resources/jobs/jobs2.json", 18 },
 				{ "src/test/resources/7issues/7issues1.json",
-						"src/test/resources/7issues/7issues2.json", 557 } });
+						"src/test/resources/7issues/7issues2.json", 351 } });
 	}
 
@@ -59,5 +61,5 @@
 				.readValue(file2, Profile.class);
 
-		List<LinearAdditive> profiles = new LinkedList<>();
+		List<LinearAdditiveUtilitySpace> profiles = new LinkedList<>();
 		profiles.add(profile1);
 		profiles.add(profile2);
Index: bidspace/src/test/java/geniusweb/bidspace/pareto/ParetoPointTest.java
===================================================================
--- bidspace/src/test/java/geniusweb/bidspace/pareto/ParetoPointTest.java	(revision 52)
+++ bidspace/src/test/java/geniusweb/bidspace/pareto/ParetoPointTest.java	(revision 1)
@@ -4,5 +4,5 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -10,13 +10,13 @@
 import java.math.BigDecimal;
 import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.HashSet;
 
 import org.junit.Before;
 import org.junit.Test;
 
+import geniusweb.bidspace.pareto.ParetoPoint;
 import geniusweb.issuevalue.Bid;
 import geniusweb.issuevalue.Value;
-import geniusweb.profile.utilityspace.LinearAdditive;
+import geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace;
 
 public class ParetoPointTest {
@@ -26,6 +26,7 @@
 	private static final BigDecimal D0_4 = BigDecimal.valueOf(0.4);
 	private static final BigDecimal D0_5 = BigDecimal.valueOf(0.5);
-	private final LinearAdditive space1 = mock(LinearAdditive.class),
-			space2 = mock(LinearAdditive.class);
+	private final LinearAdditiveUtilitySpace space1 = mock(
+			LinearAdditiveUtilitySpace.class),
+			space2 = mock(LinearAdditiveUtilitySpace.class);
 	private final Bid bid11 = mock(Bid.class), bid12 = mock(Bid.class),
 			bid21 = mock(Bid.class), bid22 = mock(Bid.class);
@@ -86,15 +87,21 @@
 	@Test
 	public void mergeTest() {
+		// partial bid 020_010 has value 0.2 for issue 2 in space1 and 0.1 for
+		// issue 2 in space2.
+		Bid partialbid020_010 = mock(Bid.class),
+				partialbid102_301 = mock(Bid.class);
+		// merged this should be a bid 122_311 so it has utilities
+		// 1+2+2=0.5 in space1 and 3+1+1=0.5 in space2
+
+		when(partialbid020_010.getIssues())
+				.thenReturn(new HashSet<String>(Arrays.asList("issue2")));
+		when(partialbid102_301.getIssues()).thenReturn(
+				new HashSet<String>(Arrays.asList("issue1", "issue3")));
+
 		Value value1 = mock(Value.class), value2 = mock(Value.class),
 				value3 = mock(Value.class);
-		// partial bid 020_010 has value 0.2 for issue 2 in space1 and 0.1 for
-		// issue 2 in space2.
-		Bid partialbid020_010 = new Bid("issue2", value2);
-		Map<String, Value> vals2 = new HashMap<>();
-		vals2.put("issue1", value1);
-		vals2.put("issue3", value3);
-		Bid partialbid102_301 = new Bid(vals2);
-		// merged this should be a bid 122_311 so it has utilities
-		// 1+2+2=0.5 in space1 and 3+1+1=0.5 in space2
+		when(partialbid020_010.getValue(eq("issue2"))).thenReturn(value2);
+		when(partialbid102_301.getValue(eq("issue1"))).thenReturn(value1);
+		when(partialbid102_301.getValue(eq("issue3"))).thenReturn(value3);
 
 		when(space1.getUtility(eq(partialbid020_010))).thenReturn(D0_2);
@@ -110,4 +117,11 @@
 		ParetoPoint p = p1.merge(p2);
 		Bid bid = p.getBid();
+		assertEquals(
+				new HashSet<String>(
+						Arrays.asList("issue1", "issue2", "issue3")),
+				bid.getIssues());
+		assertEquals(value1, bid.getValue("issue1"));
+		assertEquals(value2, bid.getValue("issue2"));
+		assertEquals(value3, bid.getValue("issue3"));
 		assertEquals(D0_5, p.getUtilities().get(0));
 		assertEquals(D0_5, p.getUtilities().get(1));
Index: bidspace/src/test/java/geniusweb/bidspace/pareto/PartialParetoTest.java
===================================================================
--- bidspace/src/test/java/geniusweb/bidspace/pareto/PartialParetoTest.java	(revision 52)
+++ bidspace/src/test/java/geniusweb/bidspace/pareto/PartialParetoTest.java	(revision 1)
@@ -16,9 +16,10 @@
 import org.junit.Test;
 
+import geniusweb.bidspace.pareto.PartialPareto;
 import geniusweb.issuevalue.Bid;
 import geniusweb.issuevalue.Domain;
 import geniusweb.issuevalue.Value;
 import geniusweb.issuevalue.ValueSet;
-import geniusweb.profile.utilityspace.LinearAdditive;
+import geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace;
 
 public class PartialParetoTest {
@@ -30,6 +31,7 @@
 	private static final BigDecimal D0_5 = BigDecimal.valueOf(0.5);
 
-	private final LinearAdditive space1 = mock(LinearAdditive.class),
-			space2 = mock(LinearAdditive.class);
+	private final LinearAdditiveUtilitySpace space1 = mock(
+			LinearAdditiveUtilitySpace.class),
+			space2 = mock(LinearAdditiveUtilitySpace.class);
 
 	private Domain domain = mock(Domain.class);
Index: bidspace/src/test/resources/7issues/7issues1.json
===================================================================
--- bidspace/src/test/resources/7issues/7issues1.json	(revision 52)
+++ bidspace/src/test/resources/7issues/7issues1.json	(revision 1)
@@ -4,57 +4,64 @@
 		"issueUtilities": {
 			"i1": {
-				"NumberValueSetUtilities": {
+				"numberutils": {
 					"lowValue": 0,
 					"lowUtility": 0.11,
 					"highValue": 9,
 					"highUtility": 0.99
+
 				}
 			},
 			"i2": {
-				"NumberValueSetUtilities": {
+				"numberutils": {
 					"lowValue": 0,
 					"lowUtility": 0.12,
 					"highValue": 9,
 					"highUtility": 0.97
+
 				}
 			},
 			"i3": {
-				"NumberValueSetUtilities": {
+				"numberutils": {
 					"lowValue": 0,
 					"lowUtility": 0.13,
 					"highValue": 9,
 					"highUtility": 0.96
+
 				}
 			},
 			"i4": {
-				"NumberValueSetUtilities": {
+				"numberutils": {
 					"lowValue": 0,
 					"lowUtility": 0.14,
 					"highValue": 9,
 					"highUtility": 0.94
+
 				}
 			},
 			"i5": {
-				"NumberValueSetUtilities": {
+				"numberutils": {
 					"lowValue": 0,
 					"lowUtility": 0.15,
 					"highValue": 9,
 					"highUtility": 0.93
+
 				}
 			},
 			"i6": {
-				"NumberValueSetUtilities": {
+				"numberutils": {
 					"lowValue": 0,
 					"lowUtility": 0.16,
 					"highValue": 9,
 					"highUtility": 0.92
+
 				}
 			},
 			"i7": {
-				"NumberValueSetUtilities": {
+				"numberutils": {
 					"lowValue": 0,
 					"lowUtility": 0.16,
 					"highValue": 9,
 					"highUtility": 0.91
+
 				}
 			}
@@ -73,23 +80,23 @@
 			"issuesValues": {
 				"i1": {
-					"range": {"low":0,"high":9,"step":1} 
+					"range": ["0", "9", "1"]
 				},
 				"i2": {
-					"range": {"low":0,"high":9,"step":1} 
+					"range": ["0", "9", "1"]
 				},
 				"i3": {
-					"range": {"low":0,"high":9,"step":1} 
+					"range": ["0", "9", "1"]
 				},
 				"i4": {
-					"range": {"low":0,"high":9,"step":1} 
+					"range": ["0", "9", "1"]
 				},
 				"i5": {
-					"range": {"low":0,"high":9,"step":1} 
+					"range": ["0", "9", "1"]
 				},
 				"i6": {
-					"range": {"low":0,"high":9,"step":1} 
+					"range": ["0", "9", "1"]
 				},
 				"i7": {
-					"range": {"low":0,"high":9,"step":1} 
+					"range": ["0", "9", "1"]
 				}
 			}
Index: bidspace/src/test/resources/7issues/7issues2.json
===================================================================
--- bidspace/src/test/resources/7issues/7issues2.json	(revision 52)
+++ bidspace/src/test/resources/7issues/7issues2.json	(revision 1)
@@ -4,68 +4,75 @@
 		"issueUtilities": {
 			"i1": {
-				"NumberValueSetUtilities": {
+				"numberutils": {
 					"lowValue": 0,
 					"lowUtility": 0.51,
 					"highValue": 9,
 					"highUtility": 0.11
+
 				}
 			},
 			"i2": {
-				"NumberValueSetUtilities": {
+				"numberutils": {
 					"lowValue": 0,
 					"lowUtility": 0.92,
 					"highValue": 9,
 					"highUtility": 0.21
+
 				}
 			},
 			"i3": {
-				"NumberValueSetUtilities": {
+				"numberutils": {
 					"lowValue": 0,
 					"lowUtility": 0.93,
 					"highValue": 9,
 					"highUtility": 0.13
+
 				}
 			},
 			"i4": {
-				"NumberValueSetUtilities": {
+				"numberutils": {
 					"lowValue": 0,
 					"lowUtility": 0.94,
 					"highValue": 9,
 					"highUtility": 0.14
+
 				}
 			},
 			"i5": {
-				"NumberValueSetUtilities": {
+				"numberutils": {
 					"lowValue": 0,
 					"lowUtility": 0.95,
 					"highValue": 9,
 					"highUtility": 0.15
+
 				}
 			},
 			"i6": {
-				"NumberValueSetUtilities": {
+				"numberutils": {
 					"lowValue": 0,
 					"lowUtility": 0.96,
 					"highValue": 9,
 					"highUtility": 0.16
+
 				}
 			},
 			"i7": {
-				"NumberValueSetUtilities": {
+				"numberutils": {
 					"lowValue": 0,
 					"lowUtility": 0.97,
 					"highValue": 9,
 					"highUtility": 0.17
+
 				}
 			}
 		},
 		"issueWeights": {
-			"i1": 0.24746,
-			"i2": 0.118241,
-			"i3": 0.186047,
-			"i4": 0.206295,
-			"i5": 0.161126,
+			"i1": 0.24745759773026107,
+			"i2": 0.11824193959921694,
+			"i3": 0.1860471425098606,
+			"i4": 0.20629555826677742,
+			"i5": 0.16112666189388397,
 			"i6": 0.0538874,
-			"i7": 0.0269436
+			"i7": 0.0269437
 		},
 		"domain": {
@@ -73,23 +80,23 @@
 			"issuesValues": {
 				"i1": {
-					"range": {"low":0,"high":9,"step":1} 
+					"range": ["0", "9", "1"]
 				},
 				"i2": {
-					"range": {"low":0,"high":9,"step":1} 
+					"range": ["0", "9", "1"]
 				},
 				"i3": {
-					"range": {"low":0,"high":9,"step":1} 
+					"range": ["0", "9", "1"]
 				},
 				"i4": {
-					"range": {"low":0,"high":9,"step":1} 
+					"range": ["0", "9", "1"]
 				},
 				"i5": {
-					"range": {"low":0,"high":9,"step":1} 
+					"range": ["0", "9", "1"]
 				},
 				"i6": {
-					"range": {"low":0,"high":9,"step":1} 
+					"range": ["0", "9", "1"]
 				},
 				"i7": {
-					"range": {"low":0,"high":9,"step":1} 
+					"range": ["0", "9", "1"]
 				}
 			}
Index: bidspace/src/test/resources/jobs/jobs1.json
===================================================================
--- bidspace/src/test/resources/jobs/jobs1.json	(revision 52)
+++ bidspace/src/test/resources/jobs/jobs1.json	(revision 1)
@@ -3,5 +3,5 @@
 		"issueUtilities": {
 			"salary": {
-				"DiscreteValueSetUtilities": {
+				"discreteutils": {
 					"valueUtilities": {
 						"2000": 0,
@@ -14,5 +14,5 @@
 			},
 			"fte": {
-				"DiscreteValueSetUtilities": {
+				"discreteutils": {
 					"valueUtilities": {
 						"0.6": 0.25,
@@ -23,5 +23,5 @@
 			},
 			"work from home": {
-				"DiscreteValueSetUtilities": {
+				"discreteutils": {
 					"valueUtilities": {
 						"0": 0.333333333,
@@ -32,5 +32,5 @@
 			},
 			"lease car": {
-				"DiscreteValueSetUtilities": {
+				"discreteutils": {
 					"valueUtilities": {
 						"yes":1,
@@ -40,5 +40,5 @@
 			},
 			"permanent contract": {
-				"DiscreteValueSetUtilities": {
+				"discreteutils": {
 					"valueUtilities": {
 						"yes":1,
@@ -48,5 +48,5 @@
 			},
 			"career development opportunities": {
-				"DiscreteValueSetUtilities": {
+				"discreteutils": {
 					"valueUtilities": {
 						"low":0,
Index: bidspace/src/test/resources/jobs/jobs2.json
===================================================================
--- bidspace/src/test/resources/jobs/jobs2.json	(revision 52)
+++ bidspace/src/test/resources/jobs/jobs2.json	(revision 1)
@@ -3,5 +3,5 @@
 		"issueUtilities": {
 			"salary": {
-				"DiscreteValueSetUtilities": {
+				"discreteutils": {
 					"valueUtilities": {
 						"2000": 1.0,
@@ -14,5 +14,5 @@
 			},
 			"fte": {
-				"DiscreteValueSetUtilities": {
+				"discreteutils": {
 					"valueUtilities": {
 						"0.6": 0.363636363636363636,
@@ -23,5 +23,5 @@
 			},
 			"work from home": {
-				"DiscreteValueSetUtilities": {
+				"discreteutils": {
 					"valueUtilities": {
 						"0": 1.0,
@@ -32,5 +32,5 @@
 			},
 			"lease car": {
-				"DiscreteValueSetUtilities": {
+				"discreteutils": {
 					"valueUtilities": {
 						"yes":0,
@@ -40,5 +40,5 @@
 			},
 			"permanent contract": {
-				"DiscreteValueSetUtilities": {
+				"discreteutils": {
 					"valueUtilities": {
 						"yes":0.23809523809523808,
@@ -48,5 +48,5 @@
 			},
 			"career development opportunities": {
-				"DiscreteValueSetUtilities": {
+				"discreteutils": {
 					"valueUtilities": {
 						"low":1.0,
