Update the Intent Delete API and semantics:

 * Added new Java API for adding/removing Application Intents:
   IPathCalcRuntimeService.addApplicationIntents(...)
   IPathCalcRuntimeService.removeApplicationIntents(...)
   IPathCalcRuntimeService.removeAllApplicationIntents(...)

 * Updated the corresponding REST API to use the new Java API, and
   move all API implementation complexity within the Intent framework.

 * Added a new REST API to support deleting multiple Intents together:
   REST DELETE: /wm/onos/intent/high?intent_id=1,2,3

 * Updated the semantics for deleting an Intent:
   Using the new Intent API (REST or Java) to delete an intent will
   prune the intent as well.
   For now, the pruning is asynchronous.

 * Implemented the corresponding backend support to automatically
   prune intents that have been deleted.
   See class DeleteIntentsTracker inside file PathCalcRuntimeModule.java

 * Updated test PathCalcRuntimeModuleTest.testIntentReroute() to
   reflect the old path deletion.

 * Updated the EntryForIntentMatcher.matchesSafely() to remove
   assertThat() statement.
   With the new implementation, this matcher can be used with not()
   Hamcrest wrapper.

Change-Id: I88e7de119bab9d955d71cede14eb7847c7b6afbf
diff --git a/src/main/java/net/onrc/onos/core/intent/IntentMap.java b/src/main/java/net/onrc/onos/core/intent/IntentMap.java
index e72cb13..7d87fa2 100644
--- a/src/main/java/net/onrc/onos/core/intent/IntentMap.java
+++ b/src/main/java/net/onrc/onos/core/intent/IntentMap.java
@@ -99,8 +99,13 @@
         notifyEvents();
     }
 
+    /**
+     * Purge all Intents that are in a state allowing them to be removed.
+     */
     public void purge() {
         LinkedList<String> removeIds = new LinkedList<>();
+
+        // Collect the IDs of all intents that can be removed
         for (Entry<String, Intent> entry : intents.entrySet()) {
             Intent intent = entry.getValue();
             if (intent.getState() == IntentState.DEL_ACK
@@ -108,6 +113,19 @@
                 removeIds.add(intent.getId());
             }
         }
+
+        purge(removeIds);
+    }
+
+    /**
+     * Purge a collection of Intents specified by Intent IDs.
+     *
+     * NOTE: The caller needs to make sure those intents are in a state
+     * that allows them to be removed.
+     *
+     * @param removeIds the collection of Intent IDs to purge.
+     */
+    public void purge(Collection<String> removeIds) {
         for (String intentId : removeIds) {
             removeIntent(intentId);
         }
@@ -216,6 +234,10 @@
     }
 
     protected void notifyEvents() {
+        if (events.isEmpty()) {
+            return;
+        }
+
         for (ChangedListener listener : listeners) {
             listener.intentsChange(events);
         }