Merge remote-tracking branch 'origin/master'
diff --git a/cli/src/main/java/org/onlab/onos/cli/net/DevicesListCommand.java b/cli/src/main/java/org/onlab/onos/cli/net/DevicesListCommand.java
index 6f0dd30..f34f97e 100644
--- a/cli/src/main/java/org/onlab/onos/cli/net/DevicesListCommand.java
+++ b/cli/src/main/java/org/onlab/onos/cli/net/DevicesListCommand.java
@@ -35,7 +35,7 @@
      * @param service device service
      * @return sorted device list
      */
-    protected List<Device> getSortedDevices(DeviceService service) {
+    protected static List<Device> getSortedDevices(DeviceService service) {
         List<Device> devices = newArrayList(service.getDevices());
         Collections.sort(devices, Comparators.ELEMENT_COMPARATOR);
         return devices;
diff --git a/cli/src/main/java/org/onlab/onos/cli/net/FlowsListCommand.java b/cli/src/main/java/org/onlab/onos/cli/net/FlowsListCommand.java
index 8b6cefc..21acb18 100644
--- a/cli/src/main/java/org/onlab/onos/cli/net/FlowsListCommand.java
+++ b/cli/src/main/java/org/onlab/onos/cli/net/FlowsListCommand.java
@@ -1,6 +1,7 @@
 package org.onlab.onos.cli.net;
 
 import static com.google.common.collect.Lists.newArrayList;
+import static org.onlab.onos.cli.net.DevicesListCommand.getSortedDevices;
 
 import java.util.Collections;
 import java.util.List;
@@ -64,7 +65,7 @@
         if (state != null && !state.equals("any")) {
             s = FlowEntryState.valueOf(state.toUpperCase());
         }
-        Iterable<Device> devices = uri == null ?  deviceService.getDevices() :
+        Iterable<Device> devices = uri == null ?  getSortedDevices(deviceService) :
             Collections.singletonList(deviceService.getDevice(DeviceId.deviceId(uri)));
         for (Device d : devices) {
             if (s == null) {
diff --git a/core/api/src/test/java/org/onlab/onos/net/intent/FakeIntentManager.java b/core/api/src/test/java/org/onlab/onos/net/intent/FakeIntentManager.java
index 9afccc8..58c5a9c 100644
--- a/core/api/src/test/java/org/onlab/onos/net/intent/FakeIntentManager.java
+++ b/core/api/src/test/java/org/onlab/onos/net/intent/FakeIntentManager.java
@@ -128,7 +128,7 @@
             setState(intent, IntentState.WITHDRAWN);
             dispatch(new IntentEvent(IntentEvent.Type.WITHDRAWN, intent));
         } catch (IntentException e) {
-            // FIXME: Do we really want to do this?
+            // FIXME: Rework this to always go from WITHDRAWING to WITHDRAWN!
             setState(intent, IntentState.FAILED);
             dispatch(new IntentEvent(IntentEvent.Type.FAILED, intent));
         }
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 197c2b2..9a2039c 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
@@ -36,6 +36,7 @@
 import static com.google.common.base.Preconditions.checkNotNull;
 import static java.util.concurrent.Executors.newSingleThreadExecutor;
 import static org.onlab.onos.net.intent.IntentState.*;
+import static org.onlab.util.Tools.delay;
 import static org.onlab.util.Tools.namedThreads;
 import static org.slf4j.LoggerFactory.getLogger;
 
@@ -226,6 +227,8 @@
             executeInstallingPhase(intent);
 
         } catch (Exception e) {
+            log.warn("Unable to compile intent {} due to: {}", intent.id(), e);
+
             // If compilation failed, mark the intent as failed.
             store.setState(intent, FAILED);
         }
@@ -238,8 +241,6 @@
         for (Intent compiled : getCompiler(intent).compile(intent)) {
             InstallableIntent installableIntent = (InstallableIntent) compiled;
             installable.add(installableIntent);
-            trackerService.addTrackedResources(intent.id(),
-                                               installableIntent.requiredLinks());
         }
         return installable;
     }
@@ -259,12 +260,17 @@
             if (installables != null) {
                 for (InstallableIntent installable : installables) {
                     registerSubclassInstallerIfNeeded(installable);
+                    trackerService.addTrackedResources(intent.id(),
+                                                       installable.requiredLinks());
                     getInstaller(installable).install(installable);
                 }
             }
             eventDispatcher.post(store.setState(intent, INSTALLED));
 
         } catch (Exception e) {
+            log.warn("Unable to install intent {} due to: {}", intent.id(), e);
+            uninstallIntent(intent);
+
             // If compilation failed, kick off the recompiling phase.
             executeRecompilingPhase(intent);
         }
@@ -299,6 +305,8 @@
                 executeInstallingPhase(intent);
             }
         } catch (Exception e) {
+            log.warn("Unable to recompile intent {} due to: {}", intent.id(), e);
+
             // If compilation failed, mark the intent as failed.
             eventDispatcher.post(store.setState(intent, FAILED));
         }
@@ -313,12 +321,7 @@
     private void executeWithdrawingPhase(Intent intent) {
         // Indicate that the intent is being withdrawn.
         store.setState(intent, WITHDRAWING);
-        List<InstallableIntent> installables = store.getInstallableIntents(intent.id());
-        if (installables != null) {
-            for (InstallableIntent installable : installables) {
-                getInstaller(installable).uninstall(installable);
-            }
-        }
+        uninstallIntent(intent);
 
         // If all went well, disassociate the top-level intent with its
         // installable derivatives and mark it as withdrawn.
@@ -327,6 +330,24 @@
     }
 
     /**
+     * Uninstalls all installable intents associated with the given intent.
+     *
+     * @param intent intent to be uninstalled
+     */
+    private void uninstallIntent(Intent intent) {
+        try {
+            List<InstallableIntent> installables = store.getInstallableIntents(intent.id());
+            if (installables != null) {
+                for (InstallableIntent installable : installables) {
+                    getInstaller(installable).uninstall(installable);
+                }
+            }
+        } catch (IntentException e) {
+            log.warn("Unable to uninstall intent {} due to: {}", intent.id(), e);
+        }
+    }
+
+    /**
      * Registers an intent compiler of the specified intent if an intent compiler
      * for the intent is not registered. This method traverses the class hierarchy of
      * the intent. Once an intent compiler for a parent type is found, this method
@@ -394,7 +415,10 @@
                                    boolean compileAllFailed) {
             // Attempt recompilation of the specified intents first.
             for (IntentId intentId : intentIds) {
-                executeRecompilingPhase(getIntent(intentId));
+                Intent intent = getIntent(intentId);
+                uninstallIntent(intent);
+                delay(1000);
+                executeRecompilingPhase(intent);
             }
 
             if (compileAllFailed) {
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/ObjectiveTracker.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/ObjectiveTracker.java
index 17d420b..820668e 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/ObjectiveTracker.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/ObjectiveTracker.java
@@ -113,7 +113,7 @@
         @Override
         public void run() {
             if (event.reasons() == null) {
-                delegate.triggerCompile(null, false);
+                delegate.triggerCompile(null, true);
 
             } else {
                 Set<IntentId> toBeRecompiled = new HashSet<>();