Merge remote-tracking branch 'origin/master'
diff --git a/cli/src/main/java/org/onlab/onos/cli/SummaryCommand.java b/cli/src/main/java/org/onlab/onos/cli/SummaryCommand.java
new file mode 100644
index 0000000..b3e03b3
--- /dev/null
+++ b/cli/src/main/java/org/onlab/onos/cli/SummaryCommand.java
@@ -0,0 +1,35 @@
+package org.onlab.onos.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onlab.onos.cluster.ClusterService;
+import org.onlab.onos.net.device.DeviceService;
+import org.onlab.onos.net.flow.FlowRuleService;
+import org.onlab.onos.net.host.HostService;
+import org.onlab.onos.net.intent.IntentService;
+import org.onlab.onos.net.link.LinkService;
+import org.onlab.onos.net.topology.Topology;
+import org.onlab.onos.net.topology.TopologyService;
+
+/**
+ * Provides summary of ONOS model.
+ */
+@Command(scope = "onos", name = "summary",
+         description = "Provides summary of ONOS model")
+public class SummaryCommand extends AbstractShellCommand {
+
+    @Override
+    protected void execute() {
+        TopologyService topologyService = get(TopologyService.class);
+        Topology topology = topologyService.currentTopology();
+        print("nodes=%d, devices=%d, links=%d, hosts=%d, clusters=%s, paths=%d, flows=%d, intents=%d",
+              get(ClusterService.class).getNodes().size(),
+              get(DeviceService.class).getDeviceCount(),
+              get(LinkService.class).getLinkCount(),
+              get(HostService.class).getHostCount(),
+              topologyService.getClusters(topology).size(),
+              topology.pathCount(),
+              get(FlowRuleService.class).getFlowRuleCount(),
+              get(IntentService.class).getIntentCount());
+    }
+
+}
diff --git a/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index 9ed8a47..96f974a 100644
--- a/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -2,6 +2,9 @@
 
     <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
         <command>
+            <action class="org.onlab.onos.cli.SummaryCommand"/>
+        </command>
+        <command>
             <action class="org.onlab.onos.cli.NodesListCommand"/>
         </command>
         <command>
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java
index 2ebc5a25..ccbb33b 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java
@@ -13,6 +13,13 @@
 public interface FlowRuleService {
 
     /**
+     * Returns the number of flow rules in the system.
+     *
+     * @return flow rule count
+     */
+    int getFlowRuleCount();
+
+    /**
      * Returns the collection of flow entries applied on the specified device.
      * This will include flow rules which may not yet have been applied to
      * the device.
@@ -72,7 +79,4 @@
      * @param listener flow rule listener
      */
     void removeListener(FlowRuleListener listener);
-
-
-
 }
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java
index 4d68e74..5ce7eb1 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java
@@ -10,7 +10,15 @@
 public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegate> {
 
     /**
+     * Returns the number of flow rule in the store.
+     *
+     * @return number of flow rules
+     */
+    int getFlowRuleCount();
+
+    /**
      * Returns the stored flow.
+     *
      * @param rule the rule to look for
      * @return a flow rule
      */
@@ -60,5 +68,4 @@
      * @return flow_removed event, or null if nothing removed
      */
     FlowRuleEvent removeFlowRule(FlowEntry rule);
-
 }
diff --git a/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java b/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
index 385e300..ce11cea 100644
--- a/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
+++ b/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
@@ -40,14 +40,14 @@
 @Component(immediate = true)
 @Service
 public class FlowRuleManager
-extends AbstractProviderRegistry<FlowRuleProvider, FlowRuleProviderService>
-implements FlowRuleService, FlowRuleProviderRegistry {
+        extends AbstractProviderRegistry<FlowRuleProvider, FlowRuleProviderService>
+        implements FlowRuleService, FlowRuleProviderRegistry {
 
     public static final String FLOW_RULE_NULL = "FlowRule cannot be null";
     private final Logger log = getLogger(getClass());
 
     private final AbstractListenerRegistry<FlowRuleEvent, FlowRuleListener>
-    listenerRegistry = new AbstractListenerRegistry<>();
+            listenerRegistry = new AbstractListenerRegistry<>();
 
     private final FlowRuleStoreDelegate delegate = new InternalStoreDelegate();
 
@@ -75,6 +75,11 @@
     }
 
     @Override
+    public int getFlowRuleCount() {
+        return store.getFlowRuleCount();
+    }
+
+    @Override
     public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
         return store.getFlowEntries(deviceId);
     }
@@ -98,15 +103,17 @@
         for (int i = 0; i < flowRules.length; i++) {
             f = flowRules[i];
             device = deviceService.getDevice(f.deviceId());
-            frp = getProvider(device.providerId());
             store.deleteFlowRule(f);
-            frp.removeFlowRule(f);
+            if (device != null) {
+                frp = getProvider(device.providerId());
+                frp.removeFlowRule(f);
+            }
         }
     }
 
     @Override
     public void removeFlowRulesById(ApplicationId id) {
-        Iterable<FlowRule> rules =  getFlowRulesById(id);
+        Iterable<FlowRule> rules = getFlowRulesById(id);
         FlowRuleProvider frp;
         Device device;
 
@@ -140,8 +147,8 @@
     }
 
     private class InternalFlowRuleProviderService
-    extends AbstractProviderService<FlowRuleProvider>
-    implements FlowRuleProviderService {
+            extends AbstractProviderService<FlowRuleProvider>
+            implements FlowRuleProviderService {
 
         protected InternalFlowRuleProviderService(FlowRuleProvider provider) {
             super(provider);
@@ -160,16 +167,16 @@
             FlowRuleProvider frp = getProvider(device.providerId());
             FlowRuleEvent event = null;
             switch (stored.state()) {
-            case ADDED:
-            case PENDING_ADD:
+                case ADDED:
+                case PENDING_ADD:
                     frp.applyFlowRule(stored);
-                break;
-            case PENDING_REMOVE:
-            case REMOVED:
-                event = store.removeFlowRule(stored);
-                break;
-            default:
-                break;
+                    break;
+                case PENDING_REMOVE:
+                case REMOVED:
+                    event = store.removeFlowRule(stored);
+                    break;
+                default:
+                    break;
 
             }
             if (event != null) {
@@ -186,17 +193,17 @@
             FlowRuleProvider frp = getProvider(device.providerId());
             FlowRuleEvent event = null;
             switch (flowRule.state()) {
-            case PENDING_REMOVE:
-            case REMOVED:
-                event = store.removeFlowRule(flowRule);
-                frp.removeFlowRule(flowRule);
-                break;
-            case ADDED:
-            case PENDING_ADD:
-                frp.applyFlowRule(flowRule);
-                break;
-            default:
-                log.debug("Flow {} has not been installed.", flowRule);
+                case PENDING_REMOVE:
+                case REMOVED:
+                    event = store.removeFlowRule(flowRule);
+                    frp.removeFlowRule(flowRule);
+                    break;
+                case ADDED:
+                case PENDING_ADD:
+                    frp.applyFlowRule(flowRule);
+                    break;
+                default:
+                    log.debug("Flow {} has not been installed.", flowRule);
             }
 
             if (event != null) {
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/FlowTracker.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/FlowTracker.java
index 8f4a5c7..f69bf78 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/FlowTracker.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/FlowTracker.java
@@ -115,12 +115,7 @@
                 for (Event reason : event.reasons()) {
                     if (reason instanceof LinkEvent) {
                         LinkEvent linkEvent = (LinkEvent) reason;
-                        if (linkEvent.type() == LinkEvent.Type.LINK_ADDED ||
-                                linkEvent.type() == LinkEvent.Type.LINK_UPDATED) {
-                            delegate.bumpIntents(intentsByLink.get(new LinkKey(linkEvent.subject())));
-                        } else if (linkEvent.type() == LinkEvent.Type.LINK_REMOVED) {
-                            delegate.failIntents(intentsByLink.get(new LinkKey(linkEvent.subject())));
-                        }
+                        delegate.bumpIntents(intentsByLink.get(new LinkKey(linkEvent.subject())));
                     }
                 }
             }
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/IntentManager.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/IntentManager.java
index ebcb789..6268245 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/IntentManager.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/IntentManager.java
@@ -359,13 +359,5 @@
             }
         }
 
-        @Override
-        public void failIntents(Iterable<IntentId> intentIds) {
-            for (IntentId intentId : intentIds) {
-                Intent intent = getIntent(intentId);
-                uninstallIntent(intent);
-                compileIntent(intent);
-            }
-        }
     }
 }
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/TopologyChangeDelegate.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/TopologyChangeDelegate.java
index 8c39c75..d8a5a95 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/TopologyChangeDelegate.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/TopologyChangeDelegate.java
@@ -15,12 +15,4 @@
      */
     void bumpIntents(Iterable<IntentId> intentIds);
 
-    /**
-     * Notifies that topology has changed in such a way that the specified
-     * intents should be marked failed and then recompiled.
-     *
-     * @param intentIds intents that should be failed and recompiled
-     */
-    void failIntents(Iterable<IntentId> intentIds);
-
 }
diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java b/core/store/dist/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
index f3c8f34..d49e00b 100644
--- a/core/store/dist/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
+++ b/core/store/dist/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
@@ -58,6 +58,11 @@
 
 
     @Override
+    public int getFlowRuleCount() {
+        return flowEntries.size();
+    }
+
+    @Override
     public synchronized FlowEntry getFlowEntry(FlowRule rule) {
         for (FlowEntry f : flowEntries.get(rule.deviceId())) {
             if (f.equals(rule)) {
diff --git a/core/store/hz/net/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java b/core/store/hz/net/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
index f3c8f34..d49e00b 100644
--- a/core/store/hz/net/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
+++ b/core/store/hz/net/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
@@ -58,6 +58,11 @@
 
 
     @Override
+    public int getFlowRuleCount() {
+        return flowEntries.size();
+    }
+
+    @Override
     public synchronized FlowEntry getFlowEntry(FlowRule rule) {
         for (FlowEntry f : flowEntries.get(rule.deviceId())) {
             if (f.equals(rule)) {
diff --git a/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleFlowRuleStore.java b/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleFlowRuleStore.java
index 5fa92f3..833d6a6 100644
--- a/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleFlowRuleStore.java
+++ b/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleFlowRuleStore.java
@@ -57,6 +57,11 @@
 
 
     @Override
+    public int getFlowRuleCount() {
+        return flowEntries.size();
+    }
+
+    @Override
     public synchronized FlowEntry getFlowEntry(FlowRule rule) {
         for (FlowEntry f : flowEntries.get(rule.deviceId())) {
             if (f.equals(rule)) {