diff --git a/src/test/java/net/onrc/onos/api/newintent/ConnectivityIntentTest.java b/src/test/java/net/onrc/onos/api/newintent/ConnectivityIntentTest.java
new file mode 100644
index 0000000..bb05832
--- /dev/null
+++ b/src/test/java/net/onrc/onos/api/newintent/ConnectivityIntentTest.java
@@ -0,0 +1,85 @@
+package net.onrc.onos.api.newintent;
+
+import net.onrc.onos.core.matchaction.action.Action;
+import net.onrc.onos.core.matchaction.match.Match;
+import net.onrc.onos.core.matchaction.match.PacketMatch;
+import net.onrc.onos.core.util.SwitchPort;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.junit.Assert.*;
+
+/**
+ * Base facilities to test various connectivity tests.
+ */
+public abstract class ConnectivityIntentTest {
+
+    public static final IntentId IID = new IntentId(123);
+    public static final Match MATCH = new PacketMatch();
+    public static final Action NOP = new NoAction();
+
+    public static final SwitchPort P1 = new SwitchPort(111, (short) 0x1);
+    public static final SwitchPort P2 = new SwitchPort(222, (short) 0x2);
+    public static final SwitchPort P3 = new SwitchPort(333, (short) 0x3);
+
+    public static final Set<SwitchPort> PS1 = itemSet(new SwitchPort[]{P1, P3});
+    public static final Set<SwitchPort> PS2 = itemSet(new SwitchPort[]{P2, P3});
+
+
+    @Test
+    public void equalsAndHashCode() {
+        Intent one = createOne();
+        Intent like = createOne();
+        Intent another = createAnother();
+
+        assertTrue("should be equal", one.equals(like));
+        assertEquals("incorrect hashCode", one.hashCode(), like.hashCode());
+
+        assertFalse("should not be equal", one.equals(another));
+
+        assertFalse("should not be equal", one.equals(null));
+        assertFalse("should not be equal", one.equals("foo"));
+    }
+
+    @Test
+    public void testToString() {
+        Intent one = createOne();
+        Intent like = createOne();
+        assertEquals("incorrect toString", one.toString(), like.toString());
+    }
+
+    /**
+     * Creates a new intent, but always a like intent, i.e. all instances will
+     * be equal, but should not be the same.
+     *
+     * @return intent
+     */
+    protected abstract Intent createOne();
+
+    /**
+     * Creates another intent, not equals to the one created by
+     * {@link #createOne()} and with a different hash code.
+     *
+     * @return another intent
+     */
+    protected abstract Intent createAnother();
+
+
+    /**
+     * Produces a set of items from the supplied items.
+     *
+     * @param items items to be placed in set
+     * @param <T>   item type
+     * @return set of items
+     */
+    private static <T> Set<T> itemSet(T[] items) {
+        return new HashSet<>(Arrays.asList(items));
+    }
+
+    // TODO: move to the match-action related package
+    private static class NoAction implements Action {
+    }
+}
diff --git a/src/test/java/net/onrc/onos/api/newintent/FakeIntentManager.java b/src/test/java/net/onrc/onos/api/newintent/FakeIntentManager.java
new file mode 100644
index 0000000..ebaf6af
--- /dev/null
+++ b/src/test/java/net/onrc/onos/api/newintent/FakeIntentManager.java
@@ -0,0 +1,271 @@
+package net.onrc.onos.api.newintent;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * Fake implementation of the intent service to assist in developing tests
+ * of the interface contract.
+ */
+public class FakeIntentManager implements TestableIntentService {
+
+    private final Map<IntentId, Intent> intents = new HashMap<>();
+    private final Map<IntentId, IntentState> intentStates = new HashMap<>();
+    private final Map<IntentId, List<InstallableIntent>> installables = new HashMap<>();
+    private final Set<IntentEventListener> listeners = new HashSet<>();
+
+    private final Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> compilers = new HashMap<>();
+    private final Map<Class<? extends InstallableIntent>,
+            IntentInstaller<? extends InstallableIntent>> installers = new HashMap<>();
+
+    private final ExecutorService executor = Executors.newSingleThreadExecutor();
+    private final List<IntentException> exceptions = new ArrayList<>();
+
+    @Override
+    public List<IntentException> getExceptions() {
+        return exceptions;
+    }
+
+    // Provides an out-of-thread simulation of intent submit life-cycle
+    private void executeSubmit(final Intent intent) {
+        registerSubclassCompilerIfNeeded(intent);
+        registerSubclassInstallerIfNeeded((InstallableIntent) intent);
+        executor.execute(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    List<InstallableIntent> installable = compileIntent(intent);
+                    installIntents(intent, installable);
+                } catch (IntentException e) {
+                    exceptions.add(e);
+                }
+            }
+        });
+    }
+
+    // Provides an out-of-thread simulation of intent withdraw life-cycle
+    private void executeWithdraw(final Intent intent) {
+        executor.execute(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    List<InstallableIntent> installable = getInstallable(intent.getId());
+                    uninstallIntents(intent, installable);
+                } catch (IntentException e) {
+                    exceptions.add(e);
+                }
+
+            }
+        });
+    }
+
+    private <T extends Intent> IntentCompiler<T> getCompiler(T intent) {
+        @SuppressWarnings("unchecked")
+        IntentCompiler<T> compiler = (IntentCompiler<T>) compilers.get(intent.getClass());
+        if (compiler == null) {
+            throw new IntentException("no compiler for class " + intent.getClass());
+        }
+        return compiler;
+    }
+
+    private <T extends InstallableIntent> IntentInstaller<T> getInstaller(T intent) {
+        @SuppressWarnings("unchecked")
+        IntentInstaller<T> installer = (IntentInstaller<T>) installers.get(intent.getClass());
+        if (installer == null) {
+            throw new IntentException("no installer for class " + intent.getClass());
+        }
+        return installer;
+    }
+
+    private <T extends Intent> List<InstallableIntent> compileIntent(T intent) {
+        try {
+            // For the fake, we compile using a single level pass
+            List<InstallableIntent> installable = new ArrayList<>();
+            for (Intent compiled : getCompiler(intent).compile(intent)) {
+                installable.add((InstallableIntent) compiled);
+            }
+            setState(intent, IntentState.COMPILED);
+            return installable;
+        } catch (IntentException e) {
+            setState(intent, IntentState.FAILED);
+            throw e;
+        }
+    }
+
+    private void installIntents(Intent intent, List<InstallableIntent> installable) {
+        try {
+            for (InstallableIntent ii : installable) {
+                getInstaller(ii).install(ii);
+            }
+            setState(intent, IntentState.INSTALLED);
+            putInstallable(intent.getId(), installable);
+        } catch (IntentException e) {
+            setState(intent, IntentState.FAILED);
+            throw e;
+        }
+    }
+
+    private void uninstallIntents(Intent intent, List<InstallableIntent> installable) {
+        try {
+            for (InstallableIntent ii : installable) {
+                getInstaller(ii).remove(ii);
+            }
+            setState(intent, IntentState.WITHDRAWN);
+            removeInstallable(intent.getId());
+        } catch (IntentException e) {
+            setState(intent, IntentState.FAILED);
+            throw e;
+        }
+    }
+
+
+    // Sets the internal state for the given intent and dispatches an event
+    private void setState(Intent intent, IntentState state) {
+        IntentState previous = intentStates.get(intent.getId());
+        intentStates.put(intent.getId(), state);
+        dispatch(new IntentEvent(intent, state, previous, System.currentTimeMillis()));
+    }
+
+    private void putInstallable(IntentId id, List<InstallableIntent> installable) {
+        installables.put(id, installable);
+    }
+
+    private void removeInstallable(IntentId id) {
+        installables.remove(id);
+    }
+
+    private List<InstallableIntent> getInstallable(IntentId id) {
+        List<InstallableIntent> installable = installables.get(id);
+        if (installable != null) {
+            return installable;
+        } else {
+            return Collections.emptyList();
+        }
+    }
+
+    @Override
+    public void submit(Intent intent) {
+        intents.put(intent.getId(), intent);
+        setState(intent, IntentState.SUBMITTED);
+        executeSubmit(intent);
+    }
+
+    @Override
+    public void withdraw(Intent intent) {
+        intents.remove(intent.getId());
+        setState(intent, IntentState.WITHDRAWING);
+        executeWithdraw(intent);
+    }
+
+    @Override
+    public void execute(IntentOperations operations) {
+        // TODO: implement later
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Set<Intent> getIntents() {
+        return Collections.unmodifiableSet(new HashSet<>(intents.values()));
+    }
+
+    @Override
+    public Intent getIntent(IntentId id) {
+        return intents.get(id);
+    }
+
+    @Override
+    public IntentState getIntentState(IntentId id) {
+        return intentStates.get(id);
+    }
+
+    @Override
+    public void addListener(IntentEventListener listener) {
+        listeners.add(listener);
+    }
+
+    @Override
+    public void removeListener(IntentEventListener listener) {
+        listeners.remove(listener);
+    }
+
+    private void dispatch(IntentEvent event) {
+        for (IntentEventListener listener : listeners) {
+            listener.event(event);
+        }
+    }
+
+    @Override
+    public <T extends Intent> void registerCompiler(Class<T> cls, IntentCompiler<T> compiler) {
+        compilers.put(cls, compiler);
+    }
+
+    @Override
+    public <T extends Intent> void unregisterCompiler(Class<T> cls) {
+        compilers.remove(cls);
+    }
+
+    @Override
+    public Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> getCompilers() {
+        return Collections.unmodifiableMap(compilers);
+    }
+
+    @Override
+    public <T extends InstallableIntent> void registerInstaller(Class<T> cls, IntentInstaller<T> installer) {
+        installers.put(cls, installer);
+    }
+
+    @Override
+    public <T extends InstallableIntent> void unregisterInstaller(Class<T> cls) {
+        installers.remove(cls);
+    }
+
+    @Override
+    public Map<Class<? extends InstallableIntent>,
+            IntentInstaller<? extends InstallableIntent>> getInstallers() {
+        return Collections.unmodifiableMap(installers);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void registerSubclassCompilerIfNeeded(Intent intent) {
+        if (!compilers.containsKey(intent.getClass())) {
+            Class<?> cls = intent.getClass();
+            while (cls != Object.class) {
+                // As long as we're within the Intent class descendants
+                if (Intent.class.isAssignableFrom(cls)) {
+                    IntentCompiler<?> compiler = compilers.get(cls);
+                    if (compiler != null) {
+                        compilers.put(intent.getClass(), compiler);
+                        return;
+                    }
+                }
+                cls = cls.getSuperclass();
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private void registerSubclassInstallerIfNeeded(InstallableIntent intent) {
+        if (!installers.containsKey(intent.getClass())) {
+            Class<?> cls = intent.getClass();
+            while (cls != Object.class) {
+                // As long as we're within the InstallableIntent class descendants
+                if (InstallableIntent.class.isAssignableFrom(cls)) {
+                    IntentInstaller<?> installer = installers.get(cls);
+                    if (installer != null) {
+                        installers.put(intent.getClass(), installer);
+                        return;
+                    }
+                }
+                cls = cls.getSuperclass();
+            }
+        }
+    }
+
+}
diff --git a/src/test/java/net/onrc/onos/api/newintent/IntentExceptionTest.java b/src/test/java/net/onrc/onos/api/newintent/IntentExceptionTest.java
new file mode 100644
index 0000000..574449b
--- /dev/null
+++ b/src/test/java/net/onrc/onos/api/newintent/IntentExceptionTest.java
@@ -0,0 +1,33 @@
+package net.onrc.onos.api.newintent;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test of the intent exception.
+ */
+public class IntentExceptionTest {
+
+    @Test
+    public void basics() {
+        validate(new IntentException(), null, null);
+        validate(new IntentException("foo"), "foo", null);
+
+        Throwable cause = new NullPointerException("bar");
+        validate(new IntentException("foo", cause), "foo", cause);
+    }
+
+    /**
+     * Validates that the specified exception has the correct message and cause.
+     *
+     * @param e       exception to test
+     * @param message expected message
+     * @param cause   expected cause
+     */
+    protected void validate(RuntimeException e, String message, Throwable cause) {
+        assertEquals("incorrect message", message, e.getMessage());
+        assertEquals("incorrect cause", cause, e.getCause());
+    }
+
+}
diff --git a/src/test/java/net/onrc/onos/api/newintent/IntentIdTest.java b/src/test/java/net/onrc/onos/api/newintent/IntentIdTest.java
new file mode 100644
index 0000000..01b65c0
--- /dev/null
+++ b/src/test/java/net/onrc/onos/api/newintent/IntentIdTest.java
@@ -0,0 +1,58 @@
+package net.onrc.onos.api.newintent;
+
+import org.junit.Test;
+
+import static net.onrc.onos.core.util.ImmutableClassChecker.assertThatClassIsImmutable;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+/**
+ * This class tests the immutability, equality, and non-equality of
+ * {@link net.onrc.onos.api.intent.IntentId}.
+ */
+public class IntentIdTest {
+    /**
+     * Tests the immutability of {@link net.onrc.onos.api.intent.IntentId}.
+     */
+    @Test
+    public void intentIdFollowsGuidelineForImmutableObject() {
+        assertThatClassIsImmutable(IntentId.class);
+    }
+
+    /**
+     * Tests equality of {@link net.onrc.onos.api.intent.IntentId}.
+     */
+    @Test
+    public void testEquality() {
+        IntentId id1 = new IntentId(1L);
+        IntentId id2 = new IntentId(1L);
+
+        assertThat(id1, is(id2));
+    }
+
+    /**
+     * Tests non-equality of {@link net.onrc.onos.api.intent.IntentId}.
+     */
+    @Test
+    public void testNonEquality() {
+        IntentId id1 = new IntentId(1L);
+        IntentId id2 = new IntentId(2L);
+
+        assertThat(id1, is(not(id2)));
+    }
+
+    @Test
+    public void valueOf() {
+        IntentId id = new IntentId(12345);
+        assertEquals("incorrect valueOf", id, IntentId.valueOf("12345"));
+    }
+
+    @Test
+    public void valueOfHex() {
+        IntentId id = new IntentId(0xdeadbeefL);
+        assertEquals("incorrect valueOf", id, IntentId.valueOf(id.toString()));
+    }
+
+}
diff --git a/src/test/java/net/onrc/onos/api/newintent/IntentServiceTest.java b/src/test/java/net/onrc/onos/api/newintent/IntentServiceTest.java
new file mode 100644
index 0000000..5fce2b6
--- /dev/null
+++ b/src/test/java/net/onrc/onos/api/newintent/IntentServiceTest.java
@@ -0,0 +1,313 @@
+package net.onrc.onos.api.newintent;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import static net.onrc.onos.api.newintent.IntentState.*;
+import static org.junit.Assert.*;
+
+// TODO: consider make it categorized as integration test when it become
+//   slow test or fragile test
+/**
+ * Suite of tests for the intent service contract.
+ */
+public class IntentServiceTest {
+
+    public static final IntentId IID = new IntentId(123);
+
+    protected static final int GRACE_MS = 500; // millis
+
+    protected TestableIntentService service;
+    protected TestListener listener = new TestListener();
+
+    @Before
+    public void setUp() {
+        service = createIntentService();
+        service.addListener(listener);
+    }
+
+    @After
+    public void tearDown() {
+        service.removeListener(listener);
+    }
+
+    /**
+     * Creates a service instance appropriately instrumented for testing.
+     *
+     * @return testable intent service
+     */
+    protected TestableIntentService createIntentService() {
+        return new FakeIntentManager();
+    }
+
+    @Test
+    public void basics() {
+        // Make sure there are no intents
+        assertEquals("incorrect intent count", 0, service.getIntents().size());
+
+        // Register a compiler and an installer both setup for success.
+        service.registerCompiler(TestIntent.class, new TestCompiler(false));
+        service.registerInstaller(TestIntent.class, new TestInstaller(false));
+
+        final Intent intent = new TestIntent(IID);
+        service.submit(intent);
+
+        // Allow a small window of time until the intent is in the expected state
+        TestTools.assertAfter(GRACE_MS, new Runnable() {
+            @Override
+            public void run() {
+                assertEquals("incorrect intent state", INSTALLED,
+                             service.getIntentState(intent.getId()));
+            }
+        });
+
+        // Make sure that all expected events have been emitted
+        validateEvents(intent, SUBMITTED, COMPILED, INSTALLED);
+
+        // Make sure there is just one intent (and is ours)
+        assertEquals("incorrect intent count", 1, service.getIntents().size());
+        assertEquals("incorrect intent", intent, service.getIntent(intent.getId()));
+
+        // Reset the listener events
+        listener.events.clear();
+
+        // Now withdraw the intent
+        service.withdraw(intent);
+
+        // Allow a small window of time until the event is in the expected state
+        TestTools.assertAfter(GRACE_MS, new Runnable() {
+            @Override
+            public void run() {
+                assertEquals("incorrect intent state", WITHDRAWN,
+                             service.getIntentState(intent.getId()));
+            }
+        });
+
+        // Make sure that all expected events have been emitted
+        validateEvents(intent, WITHDRAWING, WITHDRAWN);
+
+        // TODO: discuss what is the fate of intents after they have been withdrawn
+        // Make sure that the intent is no longer in the system
+//        assertEquals("incorrect intent count", 0, service.getIntents().size());
+//        assertNull("intent should not be found", service.getIntent(intent.getId()));
+//        assertNull("intent state should not be found", service.getIntentState(intent.getId()));
+    }
+
+    @Test
+    public void failedCompilation() {
+        // Register a compiler programmed for success
+        service.registerCompiler(TestIntent.class, new TestCompiler(true));
+
+        // Submit an intent
+        final Intent intent = new TestIntent(IID);
+        service.submit(intent);
+
+        // Allow a small window of time until the intent is in the expected state
+        TestTools.assertAfter(GRACE_MS, new Runnable() {
+            @Override
+            public void run() {
+                assertEquals("incorrect intent state", FAILED,
+                             service.getIntentState(intent.getId()));
+            }
+        });
+
+        // Make sure that all expected events have been emitted
+        validateEvents(intent, SUBMITTED, FAILED);
+    }
+
+    @Test
+    public void failedInstallation() {
+        // Register a compiler programmed for success and installer for failure
+        service.registerCompiler(TestIntent.class, new TestCompiler(false));
+        service.registerInstaller(TestIntent.class, new TestInstaller(true));
+
+        // Submit an intent
+        final Intent intent = new TestIntent(IID);
+        service.submit(intent);
+
+        // Allow a small window of time until the intent is in the expected state
+        TestTools.assertAfter(GRACE_MS, new Runnable() {
+            @Override
+            public void run() {
+                assertEquals("incorrect intent state", FAILED,
+                             service.getIntentState(intent.getId()));
+            }
+        });
+
+        // Make sure that all expected events have been emitted
+        validateEvents(intent, SUBMITTED, COMPILED, FAILED);
+    }
+
+    /**
+     * Validates that the test event listener has received the following events
+     * for the specified intent. Events received for other intents will not be
+     * considered.
+     *
+     * @param intent intent subject
+     * @param states list of states for which events are expected
+     */
+    protected void validateEvents(Intent intent, IntentState... states) {
+        Iterator<IntentEvent> events = listener.events.iterator();
+        for (IntentState state : states) {
+            IntentEvent event = events.hasNext() ? events.next() : null;
+            if (event == null) {
+                fail("expected event not found: " + state);
+            } else if (intent.equals(event.getIntent())) {
+                assertEquals("incorrect state", state, event.getState());
+            }
+        }
+
+        // Remainder of events should not apply to this intent; make sure.
+        while (events.hasNext()) {
+            assertFalse("unexpected event for intent",
+                        intent.equals(events.next().getIntent()));
+        }
+    }
+
+    @Test
+    public void compilerBasics() {
+        // Make sure there are no compilers
+        assertEquals("incorrect compiler count", 0, service.getCompilers().size());
+
+        // Add a compiler and make sure that it appears in the map
+        IntentCompiler<TestIntent> compiler = new TestCompiler(false);
+        service.registerCompiler(TestIntent.class, compiler);
+        assertEquals("incorrect compiler", compiler,
+                     service.getCompilers().get(TestIntent.class));
+
+        // Remove the same and make sure that it no longer appears in the map
+        service.unregisterCompiler(TestIntent.class);
+        assertNull("compiler should not be registered",
+                   service.getCompilers().get(TestIntent.class));
+    }
+
+    @Test
+    public void installerBasics() {
+        // Make sure there are no installers
+        assertEquals("incorrect installer count", 0, service.getInstallers().size());
+
+        // Add an installer and make sure that it appears in the map
+        IntentInstaller<TestIntent> installer = new TestInstaller(false);
+        service.registerInstaller(TestIntent.class, installer);
+        assertEquals("incorrect installer", installer,
+                     service.getInstallers().get(TestIntent.class));
+
+        // Remove the same and make sure that it no longer appears in the map
+        service.unregisterInstaller(TestIntent.class);
+        assertNull("installer should not be registered",
+                   service.getInstallers().get(TestIntent.class));
+    }
+
+    @Test
+    public void implicitRegistration() {
+        // Add a compiler and make sure that it appears in the map
+        IntentCompiler<TestIntent> compiler = new TestCompiler(false);
+        service.registerCompiler(TestIntent.class, compiler);
+        assertEquals("incorrect compiler", compiler,
+                     service.getCompilers().get(TestIntent.class));
+
+        // Add a installer and make sure that it appears in the map
+        IntentInstaller<TestIntent> installer = new TestInstaller(false);
+        service.registerInstaller(TestIntent.class, installer);
+        assertEquals("incorrect installer", installer,
+                     service.getInstallers().get(TestIntent.class));
+
+
+        // Submit an intent which is a subclass of the one we registered
+        final Intent intent = new TestSubclassIntent(IID);
+        service.submit(intent);
+
+        // Allow some time for the intent to be compiled and installed
+        TestTools.assertAfter(GRACE_MS, new Runnable() {
+            @Override
+            public void run() {
+                assertEquals("incorrect intent state", INSTALLED,
+                             service.getIntentState(intent.getId()));
+            }
+        });
+
+        // Make sure that now we have an implicit registration of the compiler
+        // under the intent subclass
+        assertEquals("incorrect compiler", compiler,
+                     service.getCompilers().get(TestSubclassIntent.class));
+
+        // Make sure that now we have an implicit registration of the installer
+        // under the intent subclass
+        assertEquals("incorrect installer", installer,
+                     service.getInstallers().get(TestSubclassIntent.class));
+
+        // TODO: discuss whether or if implicit registration should require implicit unregistration
+        // perhaps unregister by compiler or installer itself, rather than by class would be better
+    }
+
+
+    // Fixture to track emitted intent events
+    protected class TestListener implements IntentEventListener {
+        final List<IntentEvent> events = new ArrayList<>();
+
+        @Override
+        public void event(IntentEvent event) {
+            events.add(event);
+        }
+    }
+
+    private class TestIntent extends AbstractIntent implements InstallableIntent {
+        TestIntent(IntentId id) {
+            super(id);
+        }
+    }
+
+    private class TestSubclassIntent extends TestIntent {
+        TestSubclassIntent(IntentId id) {
+            super(id);
+        }
+    }
+
+    // Controllable compiler
+    private class TestCompiler implements IntentCompiler<TestIntent> {
+        private final boolean fail;
+
+        TestCompiler(boolean fail) {
+            this.fail = fail;
+        }
+
+        @Override
+        public List<Intent> compile(TestIntent intent) {
+            if (fail) {
+                throw new IntentException("compile failed by design");
+            }
+            List<Intent> compiled = new ArrayList<>(1);
+            compiled.add(intent);
+            return compiled;
+        }
+    }
+
+    // Controllable installer
+    private class TestInstaller implements IntentInstaller<TestIntent> {
+        private final boolean fail;
+
+        TestInstaller(boolean fail) {
+            this.fail = fail;
+        }
+
+        @Override
+        public void install(TestIntent intent) {
+            if (fail) {
+                throw new IntentException("install failed by design");
+            }
+        }
+
+        @Override
+        public void remove(TestIntent intent) {
+            if (fail) {
+                throw new IntentException("remove failed by design");
+            }
+        }
+    }
+
+}
diff --git a/src/test/java/net/onrc/onos/api/newintent/MultiPointToSinglePointIntentTest.java b/src/test/java/net/onrc/onos/api/newintent/MultiPointToSinglePointIntentTest.java
new file mode 100644
index 0000000..36a8aae
--- /dev/null
+++ b/src/test/java/net/onrc/onos/api/newintent/MultiPointToSinglePointIntentTest.java
@@ -0,0 +1,30 @@
+package net.onrc.onos.api.newintent;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Suite of tests of the multi-to-single point intent descriptor.
+ */
+public class MultiPointToSinglePointIntentTest extends ConnectivityIntentTest {
+
+    @Test
+    public void basics() {
+        MultiPointToSinglePointIntent intent = createOne();
+        assertEquals("incorrect id", IID, intent.getId());
+        assertEquals("incorrect match", MATCH, intent.getMatch());
+        assertEquals("incorrect ingress", PS1, intent.getIngressPorts());
+        assertEquals("incorrect egress", P2, intent.getEgressPort());
+    }
+
+    @Override
+    protected MultiPointToSinglePointIntent createOne() {
+        return new MultiPointToSinglePointIntent(IID, MATCH, NOP, PS1, P2);
+    }
+
+    @Override
+    protected MultiPointToSinglePointIntent createAnother() {
+        return new MultiPointToSinglePointIntent(IID, MATCH, NOP, PS2, P1);
+    }
+}
diff --git a/src/test/java/net/onrc/onos/api/newintent/PathIntentTest.java b/src/test/java/net/onrc/onos/api/newintent/PathIntentTest.java
new file mode 100644
index 0000000..b68b506
--- /dev/null
+++ b/src/test/java/net/onrc/onos/api/newintent/PathIntentTest.java
@@ -0,0 +1,44 @@
+package net.onrc.onos.api.newintent;
+
+import net.onrc.onos.core.util.LinkTuple;
+import net.onrc.onos.core.util.SwitchPort;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class PathIntentTest extends ConnectivityIntentTest {
+    public static final SwitchPort P1_2 = new SwitchPort(111, (short) 0x11);
+    public static final SwitchPort P2_2 = new SwitchPort(222, (short) 0x22);
+    public static final SwitchPort P3_2 = new SwitchPort(333, (short) 0x33);
+
+    private static final List<LinkTuple> PATH1 = Arrays.asList(
+            new LinkTuple(P1_2, P2_2)
+    );
+    private static final List<LinkTuple> PATH2 = Arrays.asList(
+            new LinkTuple(P1_2, P3_2)
+    );
+
+    @Test
+    public void basics() {
+        PathIntent intent = createOne();
+        assertEquals("incorrect id", IID, intent.getId());
+        assertEquals("incorrect match", MATCH, intent.getMatch());
+        assertEquals("incorrect action", NOP, intent.getAction());
+        assertEquals("incorrect ingress", P1, intent.getIngressPort());
+        assertEquals("incorrect egress", P2, intent.getEgressPort());
+        assertEquals("incorrect path", PATH1, intent.getPath());
+    }
+
+    @Override
+    protected PathIntent createOne() {
+        return new PathIntent(IID, MATCH, NOP, P1, P2, PATH1);
+    }
+
+    @Override
+    protected PathIntent createAnother() {
+        return new PathIntent(IID, MATCH, NOP, P1, P3, PATH2);
+    }
+}
diff --git a/src/test/java/net/onrc/onos/api/newintent/PointToPointIntentTest.java b/src/test/java/net/onrc/onos/api/newintent/PointToPointIntentTest.java
new file mode 100644
index 0000000..492b895
--- /dev/null
+++ b/src/test/java/net/onrc/onos/api/newintent/PointToPointIntentTest.java
@@ -0,0 +1,30 @@
+package net.onrc.onos.api.newintent;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Suite of tests of the point-to-point intent descriptor.
+ */
+public class PointToPointIntentTest extends ConnectivityIntentTest {
+
+    @Test
+    public void basics() {
+        PointToPointIntent intent = createOne();
+        assertEquals("incorrect id", IID, intent.getId());
+        assertEquals("incorrect match", MATCH, intent.getMatch());
+        assertEquals("incorrect ingress", P1, intent.getIngressPort());
+        assertEquals("incorrect egress", P2, intent.getEgressPort());
+    }
+
+    @Override
+    protected PointToPointIntent createOne() {
+        return new PointToPointIntent(IID, MATCH, NOP, P1, P2);
+    }
+
+    @Override
+    protected PointToPointIntent createAnother() {
+        return new PointToPointIntent(IID, MATCH, NOP, P2, P1);
+    }
+}
diff --git a/src/test/java/net/onrc/onos/api/newintent/SinglePointToMultiPointIntentTest.java b/src/test/java/net/onrc/onos/api/newintent/SinglePointToMultiPointIntentTest.java
new file mode 100644
index 0000000..240ce47
--- /dev/null
+++ b/src/test/java/net/onrc/onos/api/newintent/SinglePointToMultiPointIntentTest.java
@@ -0,0 +1,30 @@
+package net.onrc.onos.api.newintent;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Suite of tests of the single-to-multi point intent descriptor.
+ */
+public class SinglePointToMultiPointIntentTest extends ConnectivityIntentTest {
+
+    @Test
+    public void basics() {
+        SinglePointToMultiPointIntent intent = createOne();
+        assertEquals("incorrect id", IID, intent.getId());
+        assertEquals("incorrect match", MATCH, intent.getMatch());
+        assertEquals("incorrect ingress", P1, intent.getIngressPort());
+        assertEquals("incorrect egress", PS2, intent.getEgressPorts());
+    }
+
+    @Override
+    protected SinglePointToMultiPointIntent createOne() {
+        return new SinglePointToMultiPointIntent(IID, MATCH, NOP, P1, PS2);
+    }
+
+    @Override
+    protected SinglePointToMultiPointIntent createAnother() {
+        return new SinglePointToMultiPointIntent(IID, MATCH, NOP, P2, PS1);
+    }
+}
diff --git a/src/test/java/net/onrc/onos/api/newintent/TestTools.java b/src/test/java/net/onrc/onos/api/newintent/TestTools.java
new file mode 100644
index 0000000..3e241f5
--- /dev/null
+++ b/src/test/java/net/onrc/onos/api/newintent/TestTools.java
@@ -0,0 +1,126 @@
+package net.onrc.onos.api.newintent;
+
+import static org.junit.Assert.fail;
+
+/**
+ * Set of test tools.
+ */
+public final class TestTools {
+
+    // Disallow construction
+    private TestTools() {
+    }
+
+    /**
+     * Utility method to pause the current thread for the specified number of
+     * milliseconds.
+     *
+     * @param ms number of milliseconds to pause
+     */
+    public static void delay(int ms) {
+        try {
+            Thread.sleep(ms);
+        } catch (InterruptedException e) {
+            fail("unexpected interrupt");
+        }
+    }
+
+    /**
+     * Periodically runs the given runnable, which should contain a series of
+     * test assertions until all the assertions succeed, in which case it will
+     * return, or until the the time expires, in which case it will throw the
+     * first failed assertion error.
+     *
+     * @param start start time, in millis since start of epoch from which the
+     *        duration will be measured
+     * @param delay initial delay (in milliseconds) before the first assertion
+     *        attempt
+     * @param step delay (in milliseconds) between successive assertion
+     *        attempts
+     * @param duration number of milliseconds beyond the given start time,
+     *        after which the failed assertions will be propagated and allowed
+     *        to fail the test
+     * @param assertions runnable housing the test assertions
+     */
+    public static void assertAfter(long start, int delay, int step,
+                                   int duration, Runnable assertions) {
+        delay(delay);
+        while (true) {
+            try {
+                assertions.run();
+                break;
+            } catch (AssertionError e) {
+                if (System.currentTimeMillis() - start > duration) {
+                    throw e;
+                }
+            }
+            delay(step);
+        }
+    }
+
+    /**
+     * Periodically runs the given runnable, which should contain a series of
+     * test assertions until all the assertions succeed, in which case it will
+     * return, or until the the time expires, in which case it will throw the
+     * first failed assertion error.
+     * <p>
+     * The start of the period is the current time.
+     *
+     * @param delay initial delay (in milliseconds) before the first assertion
+     *        attempt
+     * @param step delay (in milliseconds) between successive assertion
+     *        attempts
+     * @param duration number of milliseconds beyond the current time time,
+     *        after which the failed assertions will be propagated and allowed
+     *        to fail the test
+     * @param assertions runnable housing the test assertions
+     */
+    public static void assertAfter(int delay, int step, int duration,
+                                   Runnable assertions) {
+        assertAfter(System.currentTimeMillis(), delay, step, duration,
+                    assertions);
+    }
+
+    /**
+     * Periodically runs the given runnable, which should contain a series of
+     * test assertions until all the assertions succeed, in which case it will
+     * return, or until the the time expires, in which case it will throw the
+     * first failed assertion error.
+     * <p>
+     * The start of the period is the current time and the first assertion
+     * attempt is delayed by the value of {@code step} parameter.
+     *
+     * @param step delay (in milliseconds) between successive assertion
+     *        attempts
+     * @param duration number of milliseconds beyond the current time time,
+     *        after which the failed assertions will be propagated and allowed
+     *        to fail the test
+     * @param assertions runnable housing the test assertions
+     */
+    public static void assertAfter(int step, int duration,
+                                   Runnable assertions) {
+        assertAfter(step, step, duration, assertions);
+    }
+
+    /**
+     * Periodically runs the given runnable, which should contain a series of
+     * test assertions until all the assertions succeed, in which case it will
+     * return, or until the the time expires, in which case it will throw the
+     * first failed assertion error.
+     * <p>
+     * The start of the period is the current time and each successive
+     * assertion attempt is delayed by at least 10 milliseconds unless the
+     * {@code duration} is less than that, in which case the one and only
+     * assertion is made after that delay.
+     *
+     * @param duration number of milliseconds beyond the current time,
+     *        after which the failed assertions will be propagated and allowed
+     *        to fail the test
+     * @param assertions runnable housing the test assertions
+     */
+    public static void assertAfter(int duration, Runnable assertions) {
+        int step = Math.min(duration, Math.max(10, duration / 10));
+        assertAfter(step, duration, assertions);
+    }
+
+}
diff --git a/src/test/java/net/onrc/onos/api/newintent/TestableIntentService.java b/src/test/java/net/onrc/onos/api/newintent/TestableIntentService.java
new file mode 100644
index 0000000..27921de
--- /dev/null
+++ b/src/test/java/net/onrc/onos/api/newintent/TestableIntentService.java
@@ -0,0 +1,12 @@
+package net.onrc.onos.api.newintent;
+
+import java.util.List;
+
+/**
+ * Abstraction of an extensible intent service enabled for unit tests.
+ */
+public interface TestableIntentService extends IntentService, IntentExtensionService {
+
+    List<IntentException> getExceptions();
+
+}
