diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/HostToHostIntent.java b/core/api/src/main/java/org/onlab/onos/net/intent/HostToHostIntent.java
index f420fc2..7a894be6 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/HostToHostIntent.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/HostToHostIntent.java
@@ -12,7 +12,7 @@
 /**
  * Abstraction of end-station to end-station bidirectional connectivity.
  */
-public class HostToHostIntent extends ConnectivityIntent {
+public final class HostToHostIntent extends ConnectivityIntent {
 
     private final HostId one;
     private final HostId two;
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/LinkCollectionIntent.java b/core/api/src/main/java/org/onlab/onos/net/intent/LinkCollectionIntent.java
index 78c95cf..9d0fde8 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/LinkCollectionIntent.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/LinkCollectionIntent.java
@@ -14,7 +14,7 @@
  * Abstraction of a connectivity intent that is implemented by a set of path
  * segments.
  */
-public class LinkCollectionIntent extends ConnectivityIntent implements InstallableIntent {
+public final class LinkCollectionIntent extends ConnectivityIntent implements InstallableIntent {
 
     private final Set<Link> links;
 
@@ -46,6 +46,12 @@
         return links;
     }
 
+    /**
+     * Returns the set of links that represent the network connections needed
+     * by this intent.
+     *
+     * @return Set of links for the network hops needed by this intent
+     */
     public Set<Link> links() {
         return links;
     }
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/MultiPointToSinglePointIntent.java b/core/api/src/main/java/org/onlab/onos/net/intent/MultiPointToSinglePointIntent.java
index be8d309..8ee4a9e 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/MultiPointToSinglePointIntent.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/MultiPointToSinglePointIntent.java
@@ -15,7 +15,7 @@
 /**
  * Abstraction of multiple source to single destination connectivity intent.
  */
-public class MultiPointToSinglePointIntent extends ConnectivityIntent {
+public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
 
     private final Set<ConnectPoint> ingressPoints;
     private final ConnectPoint egressPoint;
diff --git a/core/api/src/test/java/org/onlab/onos/net/NetTestTools.java b/core/api/src/test/java/org/onlab/onos/net/NetTestTools.java
index 379ec7a..bd2e3ee 100644
--- a/core/api/src/test/java/org/onlab/onos/net/NetTestTools.java
+++ b/core/api/src/test/java/org/onlab/onos/net/NetTestTools.java
@@ -47,10 +47,16 @@
                                new HashSet<IpPrefix>());
     }
 
+    // Short-hand for creating a connection point.
+    public static ConnectPoint connectPoint(String id, int port) {
+        return new ConnectPoint(did(id), portNumber(port));
+    }
+
     // Short-hand for creating a link.
     public static Link link(String src, int sp, String dst, int dp) {
-        return new DefaultLink(PID, new ConnectPoint(did(src), portNumber(sp)),
-                               new ConnectPoint(did(dst), portNumber(dp)),
+        return new DefaultLink(PID,
+                               connectPoint(src, sp),
+                               connectPoint(dst, dp),
                                Link.Type.DIRECT);
     }
 
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/HostToHostIntentCompiler.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/HostToHostIntentCompiler.java
index de61e8e..50faf38 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/HostToHostIntentCompiler.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/HostToHostIntentCompiler.java
@@ -41,7 +41,7 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected HostService hostService;
 
-    private IdGenerator<IntentId> intentIdGenerator;
+    protected IdGenerator<IntentId> intentIdGenerator;
 
     @Activate
     public void activate() {
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/MultiPointToSinglePointIntentCompiler.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/MultiPointToSinglePointIntentCompiler.java
index 68c55dd..aecd3ba 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/MultiPointToSinglePointIntentCompiler.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/MultiPointToSinglePointIntentCompiler.java
@@ -37,7 +37,7 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected PathService pathService;
 
-    private IdGenerator<IntentId> intentIdGenerator;
+    protected IdGenerator<IntentId> intentIdGenerator;
 
     @Activate
     public void activate() {
diff --git a/core/net/src/test/java/org/onlab/onos/net/intent/IntentTestsMocks.java b/core/net/src/test/java/org/onlab/onos/net/intent/IntentTestsMocks.java
new file mode 100644
index 0000000..0f020a4
--- /dev/null
+++ b/core/net/src/test/java/org/onlab/onos/net/intent/IntentTestsMocks.java
@@ -0,0 +1,86 @@
+package org.onlab.onos.net.intent;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.onlab.onos.net.ElementId;
+import org.onlab.onos.net.Path;
+import org.onlab.onos.net.flow.TrafficSelector;
+import org.onlab.onos.net.flow.TrafficTreatment;
+import org.onlab.onos.net.flow.criteria.Criterion;
+import org.onlab.onos.net.flow.instructions.Instruction;
+import org.onlab.onos.net.topology.LinkWeight;
+import org.onlab.onos.net.topology.PathService;
+
+import static org.onlab.onos.net.NetTestTools.createPath;
+
+/**
+ * Common mocks used by the intent framework tests.
+ */
+public class IntentTestsMocks {
+    /**
+     * Mock traffic selector class used for satisfying API requirements.
+     */
+    public static class MockSelector implements TrafficSelector {
+        @Override
+        public Set<Criterion> criteria() {
+            return new HashSet<>();
+        }
+    }
+
+    /**
+     * Mock traffic treatment class used for satisfying API requirements.
+     */
+    public static class MockTreatment implements TrafficTreatment {
+        @Override
+        public List<Instruction> instructions() {
+            return new ArrayList<>();
+        }
+    }
+
+    /**
+     * Mock path service for creating paths within the test.
+     */
+    public static class MockPathService implements PathService {
+
+        final String[] pathHops;
+        final String[] reversePathHops;
+
+        /**
+         * Constructor that provides a set of hops to mock.
+         *
+         * @param pathHops path hops to mock
+         */
+        public MockPathService(String[] pathHops) {
+            this.pathHops = pathHops;
+            String[] reversed = pathHops.clone();
+            Collections.reverse(Arrays.asList(reversed));
+            reversePathHops = reversed;
+        }
+
+        @Override
+        public Set<Path> getPaths(ElementId src, ElementId dst) {
+            Set<Path> result = new HashSet<>();
+
+            String[] allHops = new String[pathHops.length];
+
+            if (src.toString().endsWith(pathHops[0])) {
+                System.arraycopy(pathHops, 0, allHops, 0, pathHops.length);
+            } else {
+                System.arraycopy(reversePathHops, 0, allHops, 0, pathHops.length);
+            }
+
+            result.add(createPath(allHops));
+            return result;
+        }
+
+        @Override
+        public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) {
+            return getPaths(src, dst);
+        }
+    }
+}
diff --git a/core/net/src/test/java/org/onlab/onos/net/intent/LinksHaveEntryWithSourceDestinationPairMatcher.java b/core/net/src/test/java/org/onlab/onos/net/intent/LinksHaveEntryWithSourceDestinationPairMatcher.java
new file mode 100644
index 0000000..869cefe
--- /dev/null
+++ b/core/net/src/test/java/org/onlab/onos/net/intent/LinksHaveEntryWithSourceDestinationPairMatcher.java
@@ -0,0 +1,73 @@
+package org.onlab.onos.net.intent;
+
+import java.util.Collection;
+
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
+import org.onlab.onos.net.Link;
+
+/**
+ * Matcher to determine if a Collection of Links contains a path between a source
+ * and a destination.
+ */
+public class LinksHaveEntryWithSourceDestinationPairMatcher extends
+        TypeSafeMatcher<Collection<Link>> {
+    private final String source;
+    private final String destination;
+
+    /**
+     * Creates a matcher for a given path represented by a source and
+     * a destination.
+     *
+     * @param source string identifier for the source of the path
+     * @param destination string identifier for the destination of the path
+     */
+    LinksHaveEntryWithSourceDestinationPairMatcher(String source,
+                                                   String destination) {
+        this.source = source;
+        this.destination = destination;
+    }
+
+    @Override
+    public boolean matchesSafely(Collection<Link> links) {
+        for (Link link : links) {
+            if (link.src().elementId().toString().endsWith(source) &&
+                    link.dst().elementId().toString().endsWith(destination)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public void describeTo(Description description) {
+        description.appendText("link lookup for source \"");
+        description.appendText(source);
+        description.appendText(" and destination ");
+        description.appendText(destination);
+        description.appendText("\"");
+    }
+
+    @Override
+    public void describeMismatchSafely(Collection<Link> links,
+                                       Description mismatchDescription) {
+        mismatchDescription.appendText("was ").
+                appendText(links.toString());
+    }
+
+    /**
+     * Creates a link has path matcher.
+     *
+     * @param source string identifier for the source of the path
+     * @param destination string identifier for the destination of the path
+     * @return matcher to match the path
+     */
+    public static LinksHaveEntryWithSourceDestinationPairMatcher linksHasPath(
+            String source,
+            String destination) {
+        return new LinksHaveEntryWithSourceDestinationPairMatcher(source,
+                destination);
+    }
+}
+
diff --git a/core/net/src/test/java/org/onlab/onos/net/intent/TestHostToHostIntent.java b/core/net/src/test/java/org/onlab/onos/net/intent/TestHostToHostIntent.java
new file mode 100644
index 0000000..f5e2551
--- /dev/null
+++ b/core/net/src/test/java/org/onlab/onos/net/intent/TestHostToHostIntent.java
@@ -0,0 +1,112 @@
+package org.onlab.onos.net.intent;
+
+import org.junit.Test;
+import org.onlab.onos.net.HostId;
+import org.onlab.onos.net.flow.TrafficSelector;
+import org.onlab.onos.net.flow.TrafficTreatment;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.onlab.onos.net.NetTestTools.hid;
+
+/**
+ * Unit tests for the HostToHostIntent class.
+ */
+public class TestHostToHostIntent {
+
+    private TrafficSelector selector = new IntentTestsMocks.MockSelector();
+    private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment();
+
+    private HostToHostIntent makeHostToHost(long id, HostId one, HostId two) {
+        return new HostToHostIntent(new IntentId(id),
+                                    one,
+                                    two,
+                                    selector,
+                                    treatment);
+    }
+
+    /**
+     * Tests the equals() method where two HostToHostIntents have references
+     * to the same hosts. These should compare equal.
+     */
+    @Test
+    public void testSameEquals() {
+
+        HostId one = hid("00:00:00:00:00:01/-1");
+        HostId two = hid("00:00:00:00:00:02/-1");
+        HostToHostIntent i1 = makeHostToHost(12, one, two);
+        HostToHostIntent i2 = makeHostToHost(12, one, two);
+
+        assertThat(i1, is(equalTo(i2)));
+    }
+
+    /**
+     * Tests the equals() method where two HostToHostIntents have references
+     * to different Hosts. These should compare not equal.
+     */
+    @Test
+    public void testLinksDifferentEquals() {
+
+        HostId one = hid("00:00:00:00:00:01/-1");
+        HostId two = hid("00:00:00:00:00:02/-1");
+        HostToHostIntent i1 = makeHostToHost(12, one, two);
+        HostToHostIntent i2 = makeHostToHost(12, two, one);
+
+        assertThat(i1, is(not(equalTo(i2))));
+    }
+
+    /**
+     * Tests the equals() method where two HostToHostIntents have different
+     * ids. These should compare not equal.
+     */
+
+    @Test
+    public void testBaseDifferentEquals() {
+        HostId one = hid("00:00:00:00:00:01/-1");
+        HostId two = hid("00:00:00:00:00:02/-1");
+        HostToHostIntent i1 = makeHostToHost(12, one, two);
+        HostToHostIntent i2 = makeHostToHost(11, one, two);
+
+        assertThat(i1, is(not(equalTo(i2))));
+    }
+
+    /**
+     * Tests that the hashCode() values for two equivalent HostToHostIntent
+     * objects are the same.
+     */
+
+    @Test
+    public void testHashCodeEquals() {
+        HostId one = hid("00:00:00:00:00:01/-1");
+        HostId two = hid("00:00:00:00:00:02/-1");
+        HostToHostIntent i1 = makeHostToHost(12, one, two);
+        HostToHostIntent i2 = makeHostToHost(12, one, two);
+
+        assertThat(i1.hashCode(), is(equalTo(i2.hashCode())));
+    }
+
+    /**
+     * Tests that the hashCode() values for two distinct LinkCollectionIntent
+     * objects are different.
+     */
+
+    @Test
+    public void testHashCodeDifferent() {
+        HostId one = hid("00:00:00:00:00:01/-1");
+        HostId two = hid("00:00:00:00:00:02/-1");
+        HostToHostIntent i1 = makeHostToHost(12, one, two);
+        HostToHostIntent i2 = makeHostToHost(112, one, two);
+
+        assertThat(i1.hashCode(), is(not(equalTo(i2.hashCode()))));
+    }
+
+    /**
+     * Checks that the HostToHostIntent class is immutable.
+     */
+    @Test
+    public void checkImmutability() {
+        ImmutableClassChecker.assertThatClassIsImmutable(HostToHostIntent.class);
+    }
+}
diff --git a/core/net/src/test/java/org/onlab/onos/net/intent/TestLinkCollectionIntent.java b/core/net/src/test/java/org/onlab/onos/net/intent/TestLinkCollectionIntent.java
index ba67a6a..f781cf3 100644
--- a/core/net/src/test/java/org/onlab/onos/net/intent/TestLinkCollectionIntent.java
+++ b/core/net/src/test/java/org/onlab/onos/net/intent/TestLinkCollectionIntent.java
@@ -1,47 +1,145 @@
 package org.onlab.onos.net.intent;
 
-import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.onlab.onos.net.Link;
 import org.onlab.onos.net.flow.TrafficSelector;
 import org.onlab.onos.net.flow.TrafficTreatment;
-import org.onlab.onos.net.flow.criteria.Criterion;
-import org.onlab.onos.net.flow.instructions.Instruction;
 
+import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.is;
+import static org.onlab.onos.net.NetTestTools.link;
 
+/**
+ * Unit tests for the LinkCollectionIntent class.
+ */
 public class TestLinkCollectionIntent {
 
-    private static class MockSelector implements TrafficSelector {
-        @Override
-        public Set<Criterion> criteria() {
-            return new HashSet<Criterion>();
-        }
+    private Link link1 = link("dev1", 1, "dev2", 2);
+    private Link link2 = link("dev1", 1, "dev3", 2);
+    private Link link3 = link("dev2", 1, "dev3", 2);
+
+    private Set<Link> links1;
+    private Set<Link> links2;
+
+    private TrafficSelector selector = new IntentTestsMocks.MockSelector();
+    private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment();
+
+    private LinkCollectionIntent makeLinkCollection(long id, Set<Link> links) {
+        return new LinkCollectionIntent(new IntentId(id),
+                                        selector, treatment, links);
     }
 
-    private static class MockTreatment implements TrafficTreatment {
-        @Override
-        public List<Instruction> instructions() {
-            return new ArrayList<>();
-        }
+    @Before
+    public void setup() {
+        links1 = new HashSet<>();
+        links2 = new HashSet<>();
     }
 
+    /**
+     * Tests the equals() method where two LinkCollectionIntents have references
+     * to the same Links in different orders. These should compare equal.
+     */
     @Test
-    public void testComparison() {
-        TrafficSelector selector = new MockSelector();
-        TrafficTreatment treatment = new MockTreatment();
-        Set<Link> links = new HashSet<>();
-        LinkCollectionIntent i1 = new LinkCollectionIntent(new IntentId(12),
-                selector, treatment, links);
-        LinkCollectionIntent i2 = new LinkCollectionIntent(new IntentId(12),
-                selector, treatment, links);
+    public void testSameEquals() {
+        links1.add(link1);
+        links1.add(link2);
+        links1.add(link3);
 
-        assertThat(i1.equals(i2), is(true));
+        links2.add(link3);
+        links2.add(link2);
+        links2.add(link1);
+
+        LinkCollectionIntent i1 = makeLinkCollection(12, links1);
+        LinkCollectionIntent i2 = makeLinkCollection(12, links2);
+
+        assertThat(i1, is(equalTo(i2)));
     }
 
+    /**
+     * Tests the equals() method where two LinkCollectionIntents have references
+     * to different Links. These should compare not equal.
+     */
+    @Test
+    public void testLinksDifferentEquals() {
+        links1.add(link1);
+        links1.add(link2);
+
+        links2.add(link3);
+        links2.add(link1);
+
+        LinkCollectionIntent i1 = makeLinkCollection(12, links1);
+        LinkCollectionIntent i2 = makeLinkCollection(12, links2);
+
+        assertThat(i1, is(not(equalTo(i2))));
+    }
+
+    /**
+     * Tests the equals() method where two LinkCollectionIntents have different
+     * ids. These should compare not equal.
+     */
+    @Test
+    public void testBaseDifferentEquals() {
+        links1.add(link1);
+        links1.add(link2);
+
+        links2.add(link2);
+        links2.add(link1);
+
+        LinkCollectionIntent i1 = makeLinkCollection(1, links1);
+        LinkCollectionIntent i2 = makeLinkCollection(2, links2);
+
+        assertThat(i1, is(not(equalTo(i2))));
+    }
+
+    /**
+     * Tests that the hashCode() values for two equivalent LinkCollectionIntent
+     * objects are the same.
+     */
+    @Test
+    public void testHashCodeEquals() {
+        links1.add(link1);
+        links1.add(link2);
+        links1.add(link3);
+
+        links2.add(link3);
+        links2.add(link2);
+        links2.add(link1);
+
+        LinkCollectionIntent i1 = makeLinkCollection(1, links1);
+        LinkCollectionIntent i2 = makeLinkCollection(1, links2);
+
+        assertThat(i1.hashCode(), is(equalTo(i2.hashCode())));
+    }
+
+    /**
+     * Tests that the hashCode() values for two distinct LinkCollectionIntent
+     * objects are different.
+     */
+    @Test
+    public void testHashCodeDifferent() {
+        links1.add(link1);
+        links1.add(link2);
+
+        links2.add(link1);
+        links2.add(link3);
+
+        LinkCollectionIntent i1 = makeLinkCollection(1, links1);
+        LinkCollectionIntent i2 = makeLinkCollection(1, links2);
+
+        assertThat(i1.hashCode(), is(not(equalTo(i2.hashCode()))));
+    }
+
+    /**
+     * Checks that the HostToHostIntent class is immutable.
+     */
+    @Test
+    public void checkImmutability() {
+        ImmutableClassChecker.assertThatClassIsImmutable(LinkCollectionIntent.class);
+    }
 }
diff --git a/core/net/src/test/java/org/onlab/onos/net/intent/TestMultiPointToSinglePointIntent.java b/core/net/src/test/java/org/onlab/onos/net/intent/TestMultiPointToSinglePointIntent.java
new file mode 100644
index 0000000..e921907
--- /dev/null
+++ b/core/net/src/test/java/org/onlab/onos/net/intent/TestMultiPointToSinglePointIntent.java
@@ -0,0 +1,157 @@
+package org.onlab.onos.net.intent;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.onos.net.ConnectPoint;
+import org.onlab.onos.net.flow.TrafficSelector;
+import org.onlab.onos.net.flow.TrafficTreatment;
+
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.onlab.onos.net.NetTestTools.connectPoint;
+
+/**
+ * Unit tests for the MultiPointToSinglePointIntent class.
+ */
+public class TestMultiPointToSinglePointIntent {
+
+    private ConnectPoint point1 = connectPoint("dev1", 1);
+    private ConnectPoint point2 = connectPoint("dev2", 1);
+    private ConnectPoint point3 = connectPoint("dev3", 1);
+
+    private TrafficSelector selector = new IntentTestsMocks.MockSelector();
+    private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment();
+
+    Set<ConnectPoint> ingress1;
+    Set<ConnectPoint> ingress2;
+
+    /**
+     * Creates a MultiPointToSinglePointIntent object.
+     *
+     * @param id identifier to use for the new intent
+     * @param ingress set of ingress points
+     * @param egress egress point
+     * @return MultiPointToSinglePoint intent
+     */
+    private MultiPointToSinglePointIntent makeIntent(long id,
+                       Set<ConnectPoint> ingress,
+                       ConnectPoint egress) {
+        return new MultiPointToSinglePointIntent(new IntentId(id),
+                                                 selector,
+                                                 treatment,
+                                                 ingress,
+                                                 egress);
+    }
+
+    /**
+     * Initializes the ingress sets.
+     */
+    @Before
+    public void setup() {
+        ingress1 = new HashSet<>();
+        ingress2 = new HashSet<>();
+    }
+
+    /**
+     * Tests the equals() method where two MultiPointToSinglePoint have references
+     * to the same Links in different orders. These should compare equal.
+     */
+    @Test
+    public void testSameEquals() {
+
+        Set<ConnectPoint> ingress1 = new HashSet<>();
+        ingress1.add(point2);
+        ingress1.add(point3);
+
+        Set<ConnectPoint> ingress2 = new HashSet<>();
+        ingress2.add(point3);
+        ingress2.add(point2);
+
+        Intent i1 = makeIntent(12, ingress1, point1);
+        Intent i2 = makeIntent(12, ingress2, point1);
+
+        assertThat(i1, is(equalTo(i2)));
+    }
+
+    /**
+     * Tests the equals() method where two MultiPointToSinglePoint have references
+     * to different Links. These should compare not equal.
+     */
+    @Test
+    public void testLinksDifferentEquals() {
+        ingress1.add(point3);
+
+        ingress2.add(point3);
+        ingress2.add(point2);
+
+        Intent i1 = makeIntent(12, ingress1, point1);
+        Intent i2 = makeIntent(12, ingress2, point1);
+
+        assertThat(i1, is(not(equalTo(i2))));
+    }
+
+    /**
+     * Tests the equals() method where two MultiPointToSinglePoint have different
+     * ids. These should compare not equal.
+     */
+    @Test
+    public void testBaseDifferentEquals() {
+        ingress1.add(point3);
+        ingress2.add(point3);
+
+        Intent i1 = makeIntent(12, ingress1, point1);
+        Intent i2 = makeIntent(11, ingress2, point1);
+
+        assertThat(i1, is(not(equalTo(i2))));
+    }
+
+    /**
+     * Tests that the hashCode() values for two equivalent MultiPointToSinglePoint
+     * objects are the same.
+     */
+    @Test
+    public void testHashCodeEquals() {
+        ingress1.add(point2);
+        ingress1.add(point3);
+
+        ingress2.add(point3);
+        ingress2.add(point2);
+
+        Intent i1 = makeIntent(12, ingress1, point1);
+        Intent i2 = makeIntent(12, ingress2, point1);
+
+        assertThat(i1.hashCode(), is(equalTo(i2.hashCode())));
+    }
+
+    /**
+     * Tests that the hashCode() values for two distinct MultiPointToSinglePoint
+     * objects are different.
+     */
+    @Test
+    public void testHashCodeDifferent() {
+        ingress1.add(point2);
+
+        ingress2.add(point3);
+        ingress2.add(point2);
+
+        Intent i1 = makeIntent(12, ingress1, point1);
+        Intent i2 = makeIntent(12, ingress2, point1);
+
+
+        assertThat(i1.hashCode(), is(not(equalTo(i2.hashCode()))));
+    }
+
+    /**
+     * Checks that the MultiPointToSinglePointIntent class is immutable.
+     */
+    @Test
+    public void checkImmutability() {
+        ImmutableClassChecker.
+                assertThatClassIsImmutable(MultiPointToSinglePointIntent.class);
+    }
+}
diff --git a/core/net/src/test/java/org/onlab/onos/net/intent/impl/TestHostToHostIntentCompiler.java b/core/net/src/test/java/org/onlab/onos/net/intent/impl/TestHostToHostIntentCompiler.java
new file mode 100644
index 0000000..bd61b7a
--- /dev/null
+++ b/core/net/src/test/java/org/onlab/onos/net/intent/impl/TestHostToHostIntentCompiler.java
@@ -0,0 +1,151 @@
+package org.onlab.onos.net.intent.impl;
+
+import java.util.List;
+
+import org.hamcrest.Matchers;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.onos.net.Host;
+import org.onlab.onos.net.HostId;
+import org.onlab.onos.net.flow.TrafficSelector;
+import org.onlab.onos.net.flow.TrafficTreatment;
+import org.onlab.onos.net.host.HostService;
+import org.onlab.onos.net.intent.HostToHostIntent;
+import org.onlab.onos.net.intent.Intent;
+import org.onlab.onos.net.intent.IntentId;
+import org.onlab.onos.net.intent.IntentTestsMocks;
+import org.onlab.onos.net.intent.PathIntent;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.onlab.onos.net.NetTestTools.hid;
+import static org.onlab.onos.net.intent.LinksHaveEntryWithSourceDestinationPairMatcher.linksHasPath;
+
+/**
+ * Unit tests for the HostToHost intent compiler.
+ */
+public class TestHostToHostIntentCompiler {
+    private static final String HOST_ONE_MAC = "00:00:00:00:00:01";
+    private static final String HOST_TWO_MAC = "00:00:00:00:00:02";
+    private static final String HOST_ONE_VLAN = "-1";
+    private static final String HOST_TWO_VLAN = "-1";
+    private static final String HOST_ONE = HOST_ONE_MAC + "/" + HOST_ONE_VLAN;
+    private static final String HOST_TWO = HOST_TWO_MAC + "/" + HOST_TWO_VLAN;
+
+    private TrafficSelector selector = new IntentTestsMocks.MockSelector();
+    private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment();
+
+    private HostId hostOneId = HostId.hostId(HOST_ONE);
+    private HostId hostTwoId = HostId.hostId(HOST_TWO);
+    private HostService mockHostService;
+
+    @Before
+    public void setup() {
+        Host hostOne = createMock(Host.class);
+        expect(hostOne.mac()).andReturn(new MacAddress(HOST_ONE_MAC.getBytes())).anyTimes();
+        expect(hostOne.vlan()).andReturn(VlanId.vlanId()).anyTimes();
+        replay(hostOne);
+
+        Host hostTwo = createMock(Host.class);
+        expect(hostTwo.mac()).andReturn(new MacAddress(HOST_TWO_MAC.getBytes())).anyTimes();
+        expect(hostTwo.vlan()).andReturn(VlanId.vlanId()).anyTimes();
+        replay(hostTwo);
+
+        mockHostService = createMock(HostService.class);
+        expect(mockHostService.getHost(eq(hostOneId))).andReturn(hostOne).anyTimes();
+        expect(mockHostService.getHost(eq(hostTwoId))).andReturn(hostTwo).anyTimes();
+        replay(mockHostService);
+    }
+
+    /**
+     * Creates a HostToHost intent based on two host Ids.
+     *
+     * @param oneIdString string for host one id
+     * @param twoIdString string for host two id
+     * @return HostToHostIntent for the two hosts
+     */
+    private HostToHostIntent makeIntent(String oneIdString, String twoIdString) {
+        return new HostToHostIntent(new IntentId(12),
+                                    hid(oneIdString),
+                                    hid(twoIdString),
+                                    selector,
+                                    treatment);
+    }
+
+    /**
+     * Creates a compiler for HostToHost intents.
+     *
+     * @param hops string array describing the path hops to use when compiling
+     * @return HostToHost intent compiler
+     */
+    private HostToHostIntentCompiler makeCompiler(String[] hops) {
+        HostToHostIntentCompiler compiler =
+                new HostToHostIntentCompiler();
+        compiler.pathService = new IntentTestsMocks.MockPathService(hops);
+        compiler.hostService = mockHostService;
+        IdBlockAllocator idBlockAllocator = new DummyIdBlockAllocator();
+        compiler.intentIdGenerator =
+                new IdBlockAllocatorBasedIntentIdGenerator(idBlockAllocator);
+        return compiler;
+    }
+
+
+    /**
+     * Tests a pair of hosts with 8 hops between them.
+     */
+    @Test
+    public void testSingleLongPathCompilation() {
+
+        HostToHostIntent intent = makeIntent(HOST_ONE,
+                                             HOST_TWO);
+        assertThat(intent, is(notNullValue()));
+
+        String[] hops = {HOST_ONE, "h1", "h2", "h3", "h4", "h5", "h6", "h7", "h8", HOST_TWO};
+        HostToHostIntentCompiler compiler = makeCompiler(hops);
+        assertThat(compiler, is(notNullValue()));
+
+        List<Intent> result = compiler.compile(intent);
+        assertThat(result, is(Matchers.notNullValue()));
+        assertThat(result, hasSize(2));
+        Intent forwardResultIntent = result.get(0);
+        assertThat(forwardResultIntent instanceof PathIntent, is(true));
+        Intent reverseResultIntent = result.get(1);
+        assertThat(reverseResultIntent instanceof PathIntent, is(true));
+
+        if (forwardResultIntent instanceof PathIntent) {
+            PathIntent forwardPathIntent = (PathIntent) forwardResultIntent;
+            assertThat(forwardPathIntent.path().links(), hasSize(9));
+            assertThat(forwardPathIntent.path().links(), linksHasPath(HOST_ONE, "h1"));
+            assertThat(forwardPathIntent.path().links(), linksHasPath("h1", "h2"));
+            assertThat(forwardPathIntent.path().links(), linksHasPath("h2", "h3"));
+            assertThat(forwardPathIntent.path().links(), linksHasPath("h3", "h4"));
+            assertThat(forwardPathIntent.path().links(), linksHasPath("h4", "h5"));
+            assertThat(forwardPathIntent.path().links(), linksHasPath("h5", "h6"));
+            assertThat(forwardPathIntent.path().links(), linksHasPath("h6", "h7"));
+            assertThat(forwardPathIntent.path().links(), linksHasPath("h7", "h8"));
+            assertThat(forwardPathIntent.path().links(), linksHasPath("h8", HOST_TWO));
+        }
+
+        if (reverseResultIntent instanceof PathIntent) {
+            PathIntent reversePathIntent = (PathIntent) reverseResultIntent;
+            assertThat(reversePathIntent.path().links(), hasSize(9));
+            assertThat(reversePathIntent.path().links(), linksHasPath("h1", HOST_ONE));
+            assertThat(reversePathIntent.path().links(), linksHasPath("h2", "h1"));
+            assertThat(reversePathIntent.path().links(), linksHasPath("h3", "h2"));
+            assertThat(reversePathIntent.path().links(), linksHasPath("h4", "h3"));
+            assertThat(reversePathIntent.path().links(), linksHasPath("h5", "h4"));
+            assertThat(reversePathIntent.path().links(), linksHasPath("h6", "h5"));
+            assertThat(reversePathIntent.path().links(), linksHasPath("h7", "h6"));
+            assertThat(reversePathIntent.path().links(), linksHasPath("h8", "h7"));
+            assertThat(reversePathIntent.path().links(), linksHasPath(HOST_TWO, "h8"));
+        }
+    }
+}
diff --git a/core/net/src/test/java/org/onlab/onos/net/intent/impl/TestMultiPointToSinglePointIntentCompiler.java b/core/net/src/test/java/org/onlab/onos/net/intent/impl/TestMultiPointToSinglePointIntentCompiler.java
new file mode 100644
index 0000000..8d286cf
--- /dev/null
+++ b/core/net/src/test/java/org/onlab/onos/net/intent/impl/TestMultiPointToSinglePointIntentCompiler.java
@@ -0,0 +1,214 @@
+package org.onlab.onos.net.intent.impl;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.hamcrest.Matchers;
+import org.junit.Test;
+import org.onlab.onos.net.ConnectPoint;
+import org.onlab.onos.net.ElementId;
+import org.onlab.onos.net.Path;
+import org.onlab.onos.net.flow.TrafficSelector;
+import org.onlab.onos.net.flow.TrafficTreatment;
+import org.onlab.onos.net.intent.Intent;
+import org.onlab.onos.net.intent.IntentId;
+import org.onlab.onos.net.intent.IntentTestsMocks;
+import org.onlab.onos.net.intent.LinkCollectionIntent;
+import org.onlab.onos.net.intent.MultiPointToSinglePointIntent;
+import org.onlab.onos.net.topology.LinkWeight;
+import org.onlab.onos.net.topology.PathService;
+
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.onlab.onos.net.NetTestTools.connectPoint;
+import static org.onlab.onos.net.NetTestTools.createPath;
+import static org.onlab.onos.net.intent.LinksHaveEntryWithSourceDestinationPairMatcher.linksHasPath;
+
+/**
+ * Unit tests for the MultiPointToSinglePoint intent compiler.
+ */
+public class TestMultiPointToSinglePointIntentCompiler {
+
+    private TrafficSelector selector = new IntentTestsMocks.MockSelector();
+    private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment();
+
+    /**
+     * Mock path service for creating paths within the test.
+     */
+    private static class MockPathService implements PathService {
+
+        final String[] pathHops;
+
+        /**
+         * Constructor that provides a set of hops to mock.
+         *
+         * @param pathHops path hops to mock
+         */
+        MockPathService(String[] pathHops) {
+            this.pathHops = pathHops;
+        }
+
+        @Override
+        public Set<Path> getPaths(ElementId src, ElementId dst) {
+            Set<Path> result = new HashSet<>();
+
+            String[] allHops = new String[pathHops.length + 1];
+            allHops[0] = src.toString();
+            System.arraycopy(pathHops, 0, allHops, 1, pathHops.length);
+
+            result.add(createPath(allHops));
+            return result;
+        }
+
+        @Override
+        public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) {
+            return null;
+        }
+    }
+
+    /**
+     * Creates a MultiPointToSinglePoint intent for a group of ingress points
+     * and an egress point.
+     *
+     * @param ingressIds array of ingress device ids
+     * @param egressId device id of the egress point
+     * @return MultiPointToSinglePoint intent
+     */
+    private MultiPointToSinglePointIntent makeIntent(String[] ingressIds, String egressId) {
+        Set<ConnectPoint> ingressPoints = new HashSet<>();
+        ConnectPoint egressPoint = connectPoint(egressId, 1);
+
+        for (String ingressId : ingressIds) {
+                ingressPoints.add(connectPoint(ingressId, 1));
+        }
+
+        return new MultiPointToSinglePointIntent(
+                new IntentId(12),
+                selector,
+                treatment,
+                ingressPoints,
+                egressPoint);
+    }
+
+    /**
+     * Creates a compiler for MultiPointToSinglePoint intents.
+     *
+     * @param hops hops to use while computing paths for this intent
+     * @return MultiPointToSinglePoint intent
+     */
+    private MultiPointToSinglePointIntentCompiler makeCompiler(String[] hops) {
+        MultiPointToSinglePointIntentCompiler compiler =
+                new MultiPointToSinglePointIntentCompiler();
+        compiler.pathService = new MockPathService(hops);
+        IdBlockAllocator idBlockAllocator = new DummyIdBlockAllocator();
+        compiler.intentIdGenerator =
+                new IdBlockAllocatorBasedIntentIdGenerator(idBlockAllocator);
+        return compiler;
+    }
+
+    /**
+     * Tests a single ingress point with 8 hops to its egress point.
+     */
+    @Test
+    public void testSingleLongPathCompilation() {
+
+        String[] ingress = {"ingress"};
+        String egress = "egress";
+
+        MultiPointToSinglePointIntent intent = makeIntent(ingress, egress);
+        assertThat(intent, is(notNullValue()));
+
+        String[] hops = {"h1", "h2", "h3", "h4", "h5", "h6", "h7", "h8",
+                         egress};
+        MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops);
+        assertThat(compiler, is(notNullValue()));
+
+        List<Intent> result = compiler.compile(intent);
+        assertThat(result, is(Matchers.notNullValue()));
+        assertThat(result, hasSize(1));
+        Intent resultIntent = result.get(0);
+        assertThat(resultIntent instanceof LinkCollectionIntent, is(true));
+
+        if (resultIntent instanceof LinkCollectionIntent) {
+            LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent;
+            assertThat(linkIntent.links(), hasSize(9));
+            assertThat(linkIntent.links(), linksHasPath("ingress", "h1"));
+            assertThat(linkIntent.links(), linksHasPath("h1", "h2"));
+            assertThat(linkIntent.links(), linksHasPath("h2", "h3"));
+            assertThat(linkIntent.links(), linksHasPath("h4", "h5"));
+            assertThat(linkIntent.links(), linksHasPath("h5", "h6"));
+            assertThat(linkIntent.links(), linksHasPath("h7", "h8"));
+            assertThat(linkIntent.links(), linksHasPath("h8", "egress"));
+        }
+    }
+
+    /**
+     * Tests a simple topology where two ingress points share some path segments
+     * and some path segments are not shared.
+     */
+    @Test
+    public void testTwoIngressCompilation() {
+        String[] ingress = {"ingress1", "ingress2"};
+        String egress = "egress";
+
+        MultiPointToSinglePointIntent intent = makeIntent(ingress, egress);
+        assertThat(intent, is(notNullValue()));
+
+        final String[] hops = {"inner1", "inner2", egress};
+        MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops);
+        assertThat(compiler, is(notNullValue()));
+
+        List<Intent> result = compiler.compile(intent);
+        assertThat(result, is(notNullValue()));
+        assertThat(result, hasSize(1));
+        Intent resultIntent = result.get(0);
+        assertThat(resultIntent instanceof LinkCollectionIntent, is(true));
+
+        if (resultIntent instanceof LinkCollectionIntent) {
+            LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent;
+            assertThat(linkIntent.links(), hasSize(4));
+            assertThat(linkIntent.links(), linksHasPath("ingress1", "inner1"));
+            assertThat(linkIntent.links(), linksHasPath("ingress2", "inner1"));
+            assertThat(linkIntent.links(), linksHasPath("inner1", "inner2"));
+            assertThat(linkIntent.links(), linksHasPath("inner2", "egress"));
+        }
+    }
+
+    /**
+     * Tests a large number of ingress points that share a common path to the
+     * egress point.
+     */
+    @Test
+    public void testMultiIngressCompilation() {
+        String[] ingress = {"i1", "i2", "i3", "i4", "i5",
+                            "i6", "i7", "i8", "i9", "i10"};
+        String egress = "e";
+
+        MultiPointToSinglePointIntent intent = makeIntent(ingress, egress);
+        assertThat(intent, is(notNullValue()));
+
+        final String[] hops = {"n1", egress};
+        MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops);
+        assertThat(compiler, is(notNullValue()));
+
+        List<Intent> result = compiler.compile(intent);
+        assertThat(result, is(notNullValue()));
+        assertThat(result, hasSize(1));
+        Intent resultIntent = result.get(0);
+        assertThat(resultIntent instanceof LinkCollectionIntent, is(true));
+
+        if (resultIntent instanceof LinkCollectionIntent) {
+            LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent;
+            assertThat(linkIntent.links(), hasSize(ingress.length + 1));
+            for (String ingressToCheck : ingress) {
+                assertThat(linkIntent.links(),
+                           linksHasPath(ingressToCheck,
+                                        "n1"));
+            }
+            assertThat(linkIntent.links(), linksHasPath("n1", egress));
+        }
+    }
+}
