diff --git a/src/test/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModuleTest.java b/src/test/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModuleTest.java
index 6b146ca..9096d2d 100644
--- a/src/test/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModuleTest.java
+++ b/src/test/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModuleTest.java
@@ -5,11 +5,20 @@
 import net.onrc.onos.datagrid.IDatagridService;
 import net.onrc.onos.datagrid.IEventChannel;
 import net.onrc.onos.datagrid.IEventChannelListener;
-import net.onrc.onos.intent.*;
+
+import net.onrc.onos.intent.Intent;
 import net.onrc.onos.intent.Intent.IntentState;
+import net.onrc.onos.intent.IntentMap;
 import net.onrc.onos.intent.IntentOperation.Operator;
+import net.onrc.onos.intent.IntentOperationList;
+import net.onrc.onos.intent.MockNetworkGraph;
+import net.onrc.onos.intent.ShortestPathIntent;
+import net.onrc.onos.ofcontroller.networkgraph.DeviceEvent;
 import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphListener;
 import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
+import net.onrc.onos.ofcontroller.networkgraph.LinkEvent;
+import net.onrc.onos.ofcontroller.networkgraph.PortEvent;
+import net.onrc.onos.ofcontroller.networkgraph.SwitchEvent;
 import net.onrc.onos.registry.controller.IControllerRegistryService;
 
 import org.junit.After;
@@ -21,29 +30,44 @@
 import org.powermock.modules.junit4.PowerMockRunner;
 
 import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
 
+import org.hamcrest.Description;
+import org.hamcrest.Factory;
+import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
+import org.hamcrest.TypeSafeMatcher;
 import static org.easymock.EasyMock.*;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.*;
 
-import org.hamcrest.Matchers;
-
 /**
  * @author Ray Milkey (ray@onlab.us)
+ *
+ * Unit tests for the Path Calculation Runtime module (PathCalcRuntimeModule).
+ * These test cases check the results of creating paths, deleting paths, and
+ * rerouting paths.  The network graph, controller registry, and data grid are
+ * mocked out.  The individual tests check the high level intents and the
+ * resulting operation lists to be sure they match the intended APIs.
+ *
  */
 @RunWith(PowerMockRunner.class)
 @PrepareForTest(PathCalcRuntimeModule.class)
 public class PathCalcRuntimeModuleTest {
+    private static final Long LOCAL_PORT = 0xFFFEL;
+
     private FloodlightModuleContext modContext;
     private IDatagridService datagridService;
     private INetworkGraphService networkGraphService;
     private IControllerRegistryService controllerRegistryService;
     private PersistIntent persistIntent;
+    private MockNetworkGraph graph;
 
     @SuppressWarnings("unchecked")
     @Before
     public void setUp() throws Exception {
-        final MockNetworkGraph graph = new MockNetworkGraph();
+        graph = new MockNetworkGraph();
         graph.createSampleTopology1();
 
         datagridService = createMock(IDatagridService.class);
@@ -92,6 +116,108 @@
         PowerMock.replay(persistIntent, PersistIntent.class);
     }
 
+
+    /**
+     * Hamcrest matcher to check that a collection of Intents contains an
+     * Intent with the specified Intent Id.
+     */
+    public static class EntryForIntentMatcher extends TypeSafeMatcher<Collection<Intent>> {
+        final private String id;
+
+        public EntryForIntentMatcher(String idValue) {
+            id = idValue;
+        }
+
+        @Override
+        public boolean matchesSafely(Collection<Intent> intents) {
+            assertThat(intents,
+                       hasItem(Matchers.<Intent>hasProperty("id", equalTo(id))));
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText("an intent with id \" ").
+                    appendText(id).
+                    appendText("\"");
+        }
+    }
+
+
+    /**
+     * Factory method to create an Intent entry Matcher.  Returns a matcher
+     * for the Intent with the given id.
+     * @param id id of the intent to match
+     * @return Matcher object
+     */
+    @Factory
+    public static Matcher<Collection<Intent>> hasIntentWithId(String id) {
+        return new EntryForIntentMatcher(id);
+    }
+
+
+    /**
+     * Matcher to determine if an IntentMap contains an entry with a given id,
+     * and that entry has a given state.
+     */
+    public static class IntentsHaveIntentWithStateMatcher extends TypeSafeMatcher<IntentMap> {
+        final private String id;
+        final private IntentState state;
+        private Intent intent;
+
+        public IntentsHaveIntentWithStateMatcher(String idValue,
+                                                 IntentState stateValue) {
+            id = idValue;
+            state = stateValue;
+        }
+
+        @Override
+        public boolean matchesSafely(IntentMap intents) {
+            intent = intents.getIntent(id);
+
+            return intent != null && intent.getState() == state;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            if (intent == null) {
+                description.appendText("intent lookup for id \"");
+                description.appendText(id);
+                description.appendText("\"");
+            } else {
+                description.appendText("state ");
+                description.appendText(state.toString());
+            }
+        }
+
+        @Override
+        public void describeMismatchSafely(IntentMap intents,
+                                           Description mismatchDescription) {
+            if (intent != null) {
+                mismatchDescription.appendText("was ").
+                                    appendText(intent.getState().toString());
+            } else {
+                mismatchDescription.appendText("that intent was not found");
+            }
+        }
+    }
+
+
+    /**
+     * Factory method to create a Matcher for an IntentMap that looks for an
+     * Intent with a given id and state.
+     *
+     * @param id id of the Intent to match
+     * @param state if the Intent is found, its state must match this
+     * @return Matcher object
+     */
+    @Factory
+    public static Matcher<IntentMap> hasIntentWithIdAndState(String id,
+                                                             IntentState state) {
+        return new IntentsHaveIntentWithStateMatcher(id, state);
+    }
+
+
     @After
     public void tearDown() {
         verify(datagridService);
@@ -105,7 +231,7 @@
      * Test the result of executing a path calculation on an
      * Intent Operation List which contains a path that references a
      * non-existent switch.
-     * <p/>
+     *
      * A 3 path list is created where one of the paths references a switch
      * that is not in the topology.  The test checks that the resulting
      * Operation List has entries for the 2 correct paths, and that the
@@ -113,8 +239,6 @@
      */
     @Test
     public void testInvalidSwitchName() throws FloodlightModuleException {
-
-        final Long LOCAL_PORT = 0xFFFEL;
         final String BAD_SWITCH_INTENT_NAME = "No Such Switch Intent";
 
         // create shortest path intents
@@ -148,37 +272,257 @@
         assertThat(pathIntentOpList, hasSize(opList.size() - 1));
 
         //  Should be a high level intent for each operation
-        assertThat(opList, hasSize(allIntents.size()));
+        assertThat(allIntents, hasSize(opList.size()));
 
         // Check that we got a high level intent for each operation
-        assertThat(allIntents,
-                   hasItem(Matchers.<Intent>
-                           hasProperty("id", equalTo("3"))));
-        assertThat(allIntents,
-                   hasItem(Matchers.<Intent>
-                           hasProperty("id", equalTo("2"))));
-        assertThat(allIntents,
-                   hasItem(Matchers.<Intent>
-                           hasProperty("id", equalTo(BAD_SWITCH_INTENT_NAME))));
+        assertThat(allIntents, hasIntentWithId("3"));
+        assertThat(allIntents, hasIntentWithId("2"));
+        assertThat(allIntents, hasIntentWithId(BAD_SWITCH_INTENT_NAME));
 
         //  Check that the non existent switch was NACKed
-        final Intent intentForBadSwitch =
-                highLevelIntents.getIntent(BAD_SWITCH_INTENT_NAME);
-        assertThat(intentForBadSwitch, notNullValue());
-        assertThat(intentForBadSwitch.getState(),
-                is(equalTo(IntentState.INST_NACK)));
+        assertThat(highLevelIntents, hasIntentWithIdAndState(BAD_SWITCH_INTENT_NAME, IntentState.INST_NACK));
 
         //  Check that switch 2 was correctly processed
-        final Intent intentForSwitch2 = highLevelIntents.getIntent("2");
-        assertThat(intentForSwitch2, notNullValue());
-        assertThat(intentForSwitch2.getState(),
-                is(equalTo(IntentState.INST_REQ)));
+        assertThat(highLevelIntents, hasIntentWithIdAndState("2", IntentState.INST_REQ));
 
         //  Check that switch 3 was correctly processed
-        final Intent intentForSwitch3 = highLevelIntents.getIntent("3");
-        assertThat(intentForSwitch3, notNullValue());
-        assertThat(intentForSwitch3.getState(),
-                is(equalTo(IntentState.INST_REQ)));
+        assertThat(highLevelIntents, hasIntentWithIdAndState("3", IntentState.INST_REQ));
+
+    }
+
+
+    /**
+     * Test the result of executing a path calculation on an
+     * Intent Operation List and then removing one of the switches.
+     *
+     * A 3 path list is created and then one of the paths is removed.
+     * The test checks that the resulting Operation List is correct,
+     * and that the high level intents contain a proper "delete requested"
+     * entry for the deleted path.
+     */
+    @Test
+    public void testIntentRemoval() throws FloodlightModuleException {
+
+        // create shortest path intents
+        final IntentOperationList opList = new IntentOperationList();
+        opList.add(Operator.ADD,
+                new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
+                                       LOCAL_PORT));
+        opList.add(Operator.ADD,
+                new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
+                                       LOCAL_PORT));
+        opList.add(Operator.ADD,
+                new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
+                                       LOCAL_PORT));
+
+        // compile high-level intent operations into low-level intent
+        // operations (calculate paths)
+        final PathCalcRuntimeModule runtime = new PathCalcRuntimeModule();
+        runtime.init(modContext);
+        runtime.startUp(modContext);
+        final IntentOperationList pathIntentOpList =
+                runtime.executeIntentOperations(opList);
+        assertThat(pathIntentOpList, notNullValue());
+
+        final IntentMap highLevelIntents = runtime.getHighLevelIntents();
+        assertThat(highLevelIntents, notNullValue());
+
+        final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
+        assertThat(allIntents, notNullValue());
+
+        //  Should be one operation per path
+        assertThat(pathIntentOpList, hasSize(opList.size()));
+
+        //  Should be a high level intent for each operation
+        assertThat(allIntents, hasSize(opList.size()));
+
+        // Check that we got a high level intent for each operation
+        assertThat(allIntents, hasIntentWithId("3"));
+        assertThat(allIntents, hasIntentWithId("2"));
+        assertThat(allIntents, hasIntentWithId("1"));
+
+        //  Check that switch 1 was correctly processed
+        assertThat(highLevelIntents,
+                   hasIntentWithIdAndState("1", IntentState.INST_REQ));
+
+        //  Check that switch 2 was correctly processed
+        assertThat(highLevelIntents,
+                   hasIntentWithIdAndState("2", IntentState.INST_REQ));
+
+        //  Check that switch 3 was correctly processed
+        assertThat(highLevelIntents,
+                   hasIntentWithIdAndState("3", IntentState.INST_REQ));
+
+        //  Now delete one path and check the results
+        final IntentOperationList opListForRemoval = new IntentOperationList();
+        opListForRemoval.add(Operator.REMOVE,
+                new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
+                        LOCAL_PORT));
+
+        final IntentOperationList pathIntentOpListAfterRemoval =
+                runtime.executeIntentOperations(opListForRemoval);
+        assertThat(pathIntentOpListAfterRemoval, notNullValue());
+        assertThat(pathIntentOpListAfterRemoval, hasSize(1));
+
+        //  Check the high level intents.
+        final IntentMap highLevelIntentsAfterRemoval = runtime.getHighLevelIntents();
+        assertThat(highLevelIntentsAfterRemoval, notNullValue());
+
+        final Collection<Intent> allIntentsAfterRemoval = highLevelIntentsAfterRemoval.getAllIntents();
+        assertThat(allIntentsAfterRemoval, notNullValue());
+        assertThat(allIntentsAfterRemoval, hasSize(3));
+
+        // Check that we got a high level intent for each operation
+        assertThat(allIntentsAfterRemoval, hasIntentWithId("3"));
+        assertThat(allIntentsAfterRemoval, hasIntentWithId("2"));
+        assertThat(allIntentsAfterRemoval, hasIntentWithId("1"));
+
+        //  Check the states of the high level intents
+        //  Check that switch 1 was correctly processed
+        assertThat(highLevelIntents,
+                hasIntentWithIdAndState("1", IntentState.DEL_REQ));
+
+        //  Check that switch 2 was correctly processed
+        assertThat(highLevelIntents,
+                hasIntentWithIdAndState("2", IntentState.INST_REQ));
+
+        //  Check that switch 3 was correctly processed
+        assertThat(highLevelIntents,
+                hasIntentWithIdAndState("3", IntentState.INST_REQ));
+    }
+
+    /**
+     * Test the result of executing a path calculation on an
+     * Intent Operation List and then forcing a reroute.
+     *
+     * A 3 path list is created and then one of the links is removed.
+     * The test checks that the resulting Operation List is correct,
+     * and that the high level intents contain a proper "reroute requested"
+     * entry for the deleted link.
+     */
+    @Test
+    public void testIntentReroute() throws FloodlightModuleException {
+
+        // create shortest path intents
+        final IntentOperationList opList = new IntentOperationList();
+        final ShortestPathIntent pathIntent1 =
+                new ShortestPathIntent("1", 1L, 12L, LOCAL_PORT, 2L, 21L,
+                                       LOCAL_PORT);
+
+        opList.add(Operator.ADD, pathIntent1);
+        opList.add(Operator.ADD,
+                new ShortestPathIntent("2", 1L, 14L, LOCAL_PORT, 4L, 41L,
+                                       LOCAL_PORT));
+        opList.add(Operator.ADD,
+                new ShortestPathIntent("3", 2L, 23L, LOCAL_PORT, 3L, 32L,
+                                       LOCAL_PORT));
+
+        // compile high-level intent operations into low-level intent
+        // operations (calculate paths)
+        final PathCalcRuntimeModule runtime = new PathCalcRuntimeModule();
+        runtime.init(modContext);
+        runtime.startUp(modContext);
+        final IntentOperationList pathIntentOpList =
+                runtime.executeIntentOperations(opList);
+        assertThat(pathIntentOpList, notNullValue());
+
+        final IntentMap highLevelIntents = runtime.getHighLevelIntents();
+        assertThat(highLevelIntents, notNullValue());
+
+        final Collection<Intent> allIntents = highLevelIntents.getAllIntents();
+        assertThat(allIntents, notNullValue());
+
+        //  Should be one operation per path
+        assertThat(pathIntentOpList, hasSize(opList.size()));
+
+        //  Should be a high level intent for each operation
+        assertThat(allIntents, hasSize(opList.size()));
+
+        // Check that we got a high level intent for each operation
+        assertThat(allIntents, hasIntentWithId("3"));
+        assertThat(allIntents, hasIntentWithId("2"));
+        assertThat(allIntents, hasIntentWithId("1"));
+
+        //  Check that switch 1 was correctly processed
+        assertThat(highLevelIntents,
+                   hasIntentWithIdAndState("1", IntentState.INST_REQ));
+
+        //  Check that switch 2 was correctly processed
+        assertThat(highLevelIntents,
+                   hasIntentWithIdAndState("2", IntentState.INST_REQ));
+
+        //  Check that switch 3 was correctly processed
+        assertThat(highLevelIntents,
+                   hasIntentWithIdAndState("3", IntentState.INST_REQ));
+
+        //  Now add a different path to one of the switches path and check
+        //  the results
+        IntentStateList states = new IntentStateList();
+        states.put("1", IntentState.INST_ACK);
+        states.put("2", IntentState.INST_ACK);
+        states.put("3", IntentState.INST_ACK);
+        runtime.getHighLevelIntents().changeStates(states);
+        states.clear();
+        states.put("1___0", IntentState.INST_ACK);
+        states.put("2___0", IntentState.INST_ACK);
+        states.put("3___0", IntentState.INST_ACK);
+        runtime.getPathIntents().changeStates(states);
+
+        final List<SwitchEvent> emptySwitchEvents = new LinkedList<>();
+        final List<PortEvent> emptyPortEvents = new LinkedList<>();
+        final List<DeviceEvent> emptyDeviceEvents = new LinkedList<>();
+        final List<LinkEvent> addedLinkEvents = new LinkedList<>();
+        final List<LinkEvent> removedLinkEvents = new LinkedList<>();
+
+        graph.removeLink(1L, 12L, 2L, 21L); // This link is used by the intent "1"
+        graph.removeLink(2L, 21L, 1L, 12L);
+        LinkEvent linkEvent1 = new LinkEvent(1L, 12L, 2L, 21L);
+        LinkEvent linkEvent2 = new LinkEvent(2L, 21L, 1L, 12L);
+        removedLinkEvents.add(linkEvent1);
+        removedLinkEvents.add(linkEvent2);
+        runtime.networkGraphEvents(
+                emptySwitchEvents,
+                emptySwitchEvents,
+                emptyPortEvents,
+                emptyPortEvents,
+                addedLinkEvents,
+                removedLinkEvents,
+                emptyDeviceEvents,
+                emptyDeviceEvents);
+        final IntentOperationList opListForReroute = new IntentOperationList();
+        opListForReroute.add(Operator.ADD, pathIntent1);
+
+        final IntentOperationList pathIntentOpListAfterReroute =
+                runtime.executeIntentOperations(opListForReroute);
+        assertThat(pathIntentOpListAfterReroute, notNullValue());
+        assertThat(pathIntentOpListAfterReroute, hasSize(2));
+
+        //  Check the high level intents.
+        final IntentMap highLevelIntentsAfterReroute = runtime.getHighLevelIntents();
+        assertThat(highLevelIntentsAfterReroute, notNullValue());
+
+        final Collection<Intent> allIntentsAfterReroute = highLevelIntentsAfterReroute.getAllIntents();
+        assertThat(allIntentsAfterReroute, notNullValue());
+        assertThat(allIntentsAfterReroute, hasSize(3));
+
+        // Check that we got a high level intent for each operation
+        assertThat(allIntentsAfterReroute, hasIntentWithId("3"));
+        assertThat(allIntentsAfterReroute, hasIntentWithId("2"));
+        assertThat(allIntentsAfterReroute, hasIntentWithId("1"));
+
+        //  Check the states of the high level intents
+        //  Check that switch 1 was correctly processed
+        assertThat(highLevelIntents,
+                hasIntentWithIdAndState("1", IntentState.REROUTE_REQ));
+
+        //  Check that switch 2 was correctly processed
+        assertThat(highLevelIntents,
+                hasIntentWithIdAndState("2", IntentState.INST_ACK));
+
+        //  Check that switch 3 was correctly processed
+        assertThat(highLevelIntents,
+                hasIntentWithIdAndState("3", IntentState.INST_ACK));
+
 
     }
 
