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));
+        }
+    }
+}
