Issue 899:NPE on cleanUpIncidentalResourcesOfDeadNodes
diff --git a/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java b/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java
index 27a9547..bd4496b 100644
--- a/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java
+++ b/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java
@@ -32,7 +32,6 @@
 import static org.jclouds.concurrent.FutureIterables.awaitCompletion;
 import static org.jclouds.concurrent.FutureIterables.transformParallel;
 
-import java.util.Collections;
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Set;
@@ -82,6 +81,7 @@
 import org.jclouds.domain.Location;
 import org.jclouds.domain.LoginCredentials;
 import org.jclouds.domain.LoginCredentials.Builder;
+import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.logging.Logger;
 import org.jclouds.predicates.RetryablePredicate;
 import org.jclouds.scriptbuilder.domain.Statement;
@@ -225,9 +225,10 @@
     * {@inheritDoc}
     */
    @Override
-   public void destroyNode(final String id) {
-      NodeMetadata destroyedNode = doDestroyNode(id);
-      cleanUpIncidentalResourcesOfDeadNodes(Collections.singleton(destroyedNode));
+   public void destroyNode(String id) {
+      NodeMetadata destroyedNodeOrNull = doDestroyNode(id);
+      if (destroyedNodeOrNull != null)
+         cleanUpIncidentalResourcesOfDeadNodes(ImmutableSet.of(destroyedNodeOrNull));
    }
 
    /**
@@ -236,7 +237,7 @@
    @Override
    public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) {
       logger.debug(">> destroying nodes matching(%s)", filter);
-      Set<NodeMetadata> set = newLinkedHashSet(transformParallel(nodesMatchingFilterAndNotTerminated(filter),
+      Set<NodeMetadata> set = newLinkedHashSet(filter(transformParallel(nodesMatchingFilterAndNotTerminated(filter),
             new Function<NodeMetadata, Future<NodeMetadata>>() {
 
                // TODO make an async interface instead of re-wrapping
@@ -244,6 +245,7 @@
                public Future<NodeMetadata> apply(final NodeMetadata from) {
                   return executor.submit(new Callable<NodeMetadata>() {
 
+                     @Nullable
                      @Override
                      public NodeMetadata call() throws Exception {
                         doDestroyNode(from.getId());
@@ -257,13 +259,19 @@
                   });
                }
 
-            }, executor, null, logger, "destroyNodesMatching(" + filter + ")"));
+            }, executor, null, logger, "destroyNodesMatching(" + filter + ")"), notNull()));
       logger.debug("<< destroyed(%d)", set.size());
       
       cleanUpIncidentalResourcesOfDeadNodes(set);
       return set;
    }
 
+   /**
+    * 
+    * @param id
+    * @return node that was deleted or null if it wasn't found
+    */
+   @Nullable
    protected NodeMetadata doDestroyNode(final String id) {
       checkNotNull(id, "id");
       logger.debug(">> destroying node(%s)", id);
diff --git a/compute/src/main/java/org/jclouds/compute/strategy/DestroyNodeStrategy.java b/compute/src/main/java/org/jclouds/compute/strategy/DestroyNodeStrategy.java
index caf929f..d942c2d 100644
--- a/compute/src/main/java/org/jclouds/compute/strategy/DestroyNodeStrategy.java
+++ b/compute/src/main/java/org/jclouds/compute/strategy/DestroyNodeStrategy.java
@@ -19,6 +19,7 @@
 package org.jclouds.compute.strategy;
 
 import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.javax.annotation.Nullable;
 
 /**
  * terminates the node
@@ -31,6 +32,7 @@
     * 
     * @return null if the node wasn't found
     */
+   @Nullable
    NodeMetadata destroyNode(String id);
 
 }
\ No newline at end of file