Index: issuevalue/pom.xml
===================================================================
--- issuevalue/pom.xml	(revision 2)
+++ issuevalue/pom.xml	(revision 4)
@@ -128,4 +128,17 @@
 					<target>1.8</target>
 				</configuration>
+			</plugin>
+			
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-source-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>attach-sources</id>
+						<goals>
+							<goal>jar</goal>
+						</goals>
+					</execution>
+				</executions>
 			</plugin>
 
Index: issuevalue/src/main/java/geniusweb/issuevalue/Bid.java
===================================================================
--- issuevalue/src/main/java/geniusweb/issuevalue/Bid.java	(revision 2)
+++ issuevalue/src/main/java/geniusweb/issuevalue/Bid.java	(revision 4)
@@ -3,4 +3,5 @@
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
@@ -40,4 +41,19 @@
 
 	/**
+	 * Makes partial bid with just 1 issue and value.
+	 * 
+	 * @param issue the issue name
+	 * @param value the {@link Value}
+	 */
+	public Bid(String issue, Value value) {
+		if (issue == null || value == null) {
+			throw new NullPointerException("issue and value must be not =null");
+		}
+
+		issuevalues = new HashMap<>();
+		issuevalues.put(issue, value);
+	}
+
+	/**
 	 * @param issue
 	 * @return the value for the given issue, or null if there is no value for
@@ -59,4 +75,25 @@
 	public Set<String> getIssues() {
 		return Collections.unmodifiableSet(issuevalues.keySet());
+	}
+
+	/**
+	 * Merges this partial bid with another partial bid.
+	 * 
+	 * @param otherbid another partial bid.
+	 * @return a bid with the combined values of both partial bids.
+	 * @throws IllegalArgumentException if issues overlap.
+	 */
+	public Bid merge(Bid otherbid) {
+		Set<String> ourissues = new HashSet<>(issuevalues.keySet());
+		ourissues.retainAll(otherbid.getIssues());
+		if (!ourissues.isEmpty()) {
+			throw new IllegalArgumentException(
+					"Otherbid contains issues that are already set:"
+							+ ourissues);
+		}
+		HashMap<String, Value> newvalues = new HashMap<>(issuevalues);
+		newvalues.putAll(otherbid.issuevalues);
+		return new Bid(newvalues);
+
 	}
 
Index: issuevalue/src/test/java/geniusweb/issuevalue/BidTest.java
===================================================================
--- issuevalue/src/test/java/geniusweb/issuevalue/BidTest.java	(revision 2)
+++ issuevalue/src/test/java/geniusweb/issuevalue/BidTest.java	(revision 4)
@@ -17,8 +17,4 @@
 import com.fasterxml.jackson.databind.ObjectMapper;
 
-import geniusweb.issuevalue.Bid;
-import geniusweb.issuevalue.DiscreteValue;
-import geniusweb.issuevalue.NumberValue;
-import geniusweb.issuevalue.Value;
 import tudelft.utilities.junit.GeneralTests;
 
@@ -125,3 +121,50 @@
 	}
 
+	@Test
+	public void testMerge() {
+		Map<String, Value> issuevalues = new HashMap<>();
+		issuevalues.put(ISSUE1, VALUE1);
+		Bid partial1 = new Bid(issuevalues);
+
+		issuevalues = new HashMap<>();
+		issuevalues.put(ISSUE2, VALUE2);
+		Bid partial2 = new Bid(issuevalues);
+
+		Bid mergedbid = partial1.merge(partial2);
+		assertEquals(bidc, mergedbid);
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void testMergeIssuesOverlap() {
+		Map<String, Value> issuevalues = new HashMap<>();
+		issuevalues.put(ISSUE1, VALUE1);
+		Bid partial1 = new Bid(issuevalues);
+
+		issuevalues = new HashMap<>();
+		issuevalues.put(ISSUE1, VALUE2);
+		Bid partial2 = new Bid(issuevalues);
+
+		partial1.merge(partial2);
+	}
+
+	@Test
+	public void smokeTestConstructor2() {
+		new Bid("issue", new DiscreteValue("dss"));
+	}
+
+	@Test
+	public void smokeTestConstructor2b() {
+		new Bid("issue", new NumberValue("0.5"));
+	}
+
+	@Test(expected = NullPointerException.class)
+	public void smokeTestConstructor2Null1() {
+		new Bid(null, new DiscreteValue("dss"));
+	}
+
+	@Test(expected = NullPointerException.class)
+	public void smokeTestConstructor2Null2() {
+		new Bid("issue", null);
+	}
+
 }
