allow if workflow step to take condition objects
diff --git a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/flow/IfWorkflowStep.java b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/flow/IfWorkflowStep.java
index 0fcdfdd..c269616 100644
--- a/core/src/main/java/org/apache/brooklyn/core/workflow/steps/flow/IfWorkflowStep.java
+++ b/core/src/main/java/org/apache/brooklyn/core/workflow/steps/flow/IfWorkflowStep.java
@@ -22,14 +22,18 @@
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.google.common.reflect.TypeToken;
+import org.apache.brooklyn.core.resolve.jackson.WrappedValue;
 import org.apache.brooklyn.core.workflow.WorkflowExpressionResolution.WorkflowExpressionStage;
 import org.apache.brooklyn.core.workflow.WorkflowExpressionResolution.WrappedResolvedExpression;
 import org.apache.brooklyn.core.workflow.WorkflowExpressionResolution.WrappingMode;
 import org.apache.brooklyn.core.workflow.WorkflowStepInstanceExecutionContext;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.predicates.DslPredicates.DslEntityPredicateDefault;
 import org.apache.brooklyn.util.core.predicates.DslPredicates.DslPredicate;
+import org.apache.brooklyn.util.core.predicates.DslPredicates.DslPredicateDefault;
 import org.apache.brooklyn.util.core.predicates.DslPredicates.WhenPresencePredicate;
+import org.apache.brooklyn.util.core.task.DeferredSupplier;
 
 public class IfWorkflowStep extends SubWorkflowStep {
 
@@ -77,21 +81,51 @@
         Map<String, Object> raw = MutableMap.of("target", getConditionRaw());
         Object conditionConstructed = this.condition;
         if (conditionConstructed==null) {
-            Object k = context.getWorkflowExectionContext().resolveWrapped(
-                    WorkflowExpressionStage.STEP_RUNNING, condition_target, TypeToken.of(Object.class),
-                    WrappingMode.WRAPPED_RESULT_DEFER_THROWING_ERROR_BUT_NO_RETRY);
-            Map c = MutableMap.of("target", WrappedResolvedExpression.ifNonDeferred(condition_target, k));
-
-            if (condition_equals !=null) {
-                Object v = context.getWorkflowExectionContext().resolveWrapped(
-                        WorkflowExpressionStage.STEP_RUNNING, condition_equals, TypeToken.of(Object.class),
-                        WrappingMode.WRAPPED_RESULT_DEFER_THROWING_ERROR_BUT_NO_RETRY);
-                c.put("check", WrappedResolvedExpression.ifNonDeferred(condition_equals, v));
-                c.put("assert", MutableMap.of("when", WhenPresencePredicate.PRESENT));  // when doing equals we need LHS and RHS to be present
-            } else {
-                c.put("when", WhenPresencePredicate.TRUTHY);
+            boolean isCondition = false;
+            boolean seemsStatic = false;
+            Object k = condition_target;
+            if (condition_equals==null) {
+                if (condition_target instanceof Map) isCondition = true;
+                else if (condition_target instanceof String) {
+                    if (((String) condition_target).trim().startsWith("$")) isCondition = false;
+                    if (((String) condition_target).trim().startsWith("{")) {
+                        isCondition = true;
+                        k = context.getWorkflowExectionContext().resolveWrapped(
+                                WorkflowExpressionStage.STEP_RUNNING, condition_target, TypeToken.of(Map.class),
+                                WrappingMode.WRAPPED_RESULT_DEFER_THROWING_ERROR_BUT_NO_RETRY);
+                    } else seemsStatic = true;
+                } else seemsStatic = true;
             }
-            conditionConstructed = c;
+            k = context.getWorkflowExectionContext().resolveWrapped(
+                    WorkflowExpressionStage.STEP_RUNNING, k, TypeToken.of(isCondition ? DslEntityPredicateDefault.class : Object.class),
+                    WrappingMode.WRAPPED_RESULT_DEFER_THROWING_ERROR_BUT_NO_RETRY);
+
+            if (seemsStatic && !(k instanceof DslPredicate || k instanceof Boolean || k instanceof DeferredSupplier)) {
+                throw new IllegalArgumentException("Argument supplied as condition target will always evaluate as true.");
+            }
+
+            if (isCondition) {
+                if (WrappedValue.getMaybe( ((DslPredicateDefault<?>)k).implicitEquals ).map(
+                        impEq -> condition_target.equals(impEq)).or(false)) {
+                    // will probably have thrown error when coercing from map, so probably not needed, but for good measure
+                    throw new IllegalArgumentException("Argument supplied as condition target could not be evaluated as condition.");
+                }
+                conditionConstructed = k;
+
+            } else {
+                Map c = MutableMap.of("target", WrappedResolvedExpression.ifNonDeferred(condition_target, k));
+
+                if (condition_equals != null) {
+                    Object v = context.getWorkflowExectionContext().resolveWrapped(
+                            WorkflowExpressionStage.STEP_RUNNING, condition_equals, TypeToken.of(Object.class),
+                            WrappingMode.WRAPPED_RESULT_DEFER_THROWING_ERROR_BUT_NO_RETRY);
+                    c.put("check", WrappedResolvedExpression.ifNonDeferred(condition_equals, v));
+                    c.put("assert", MutableMap.of("when", WhenPresencePredicate.PRESENT));  // when doing equals we need LHS and RHS to be present
+                } else {
+                    c.put("when", WhenPresencePredicate.TRUTHY);
+                }
+                conditionConstructed = c;
+            }
         }
 
         DslPredicate result = getConditionResolved(context, conditionConstructed);
diff --git a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowSubIfAndCustomExtensionEdgeTest.java b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowSubIfAndCustomExtensionEdgeTest.java
index 4505bd8..e411031 100644
--- a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowSubIfAndCustomExtensionEdgeTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowSubIfAndCustomExtensionEdgeTest.java
@@ -199,6 +199,11 @@
         Asserts.assertEquals(run.apply(null, "${x} == ${x}"), "yes");
         Asserts.assertEquals(run.apply("let boolean x = true", "${x} == true"), "yes");
 
+        Asserts.assertEquals(run.apply("set-sensor xy = yes", "{ sensor: xy, equals: yes }"), "yes");
+        Asserts.assertEquals(run.apply(null, "{ sensor: xn, equals: yes }"), "no");
+        Asserts.assertFailsWith(() -> run.apply(null, "{ unknown_field: xn }"),
+                Asserts.expectedFailureContainsIgnoreCase("unknown_field", "predicate"));
+
         // unresolvable things -- allowed iff no == block
         Asserts.assertEquals(run.apply(null, "${unresolvable_without_equals}"), "no");
         Asserts.assertFailsWith(() -> run.apply(null, "${x} == ${unresolvable_on_rhs}"),
@@ -210,11 +215,22 @@
         Asserts.assertEquals(runWorkflow(MutableList.of("let boolean x = true",
                 "if ${x} then return yes",
                 "return no")), "yes");
-
         Asserts.assertEquals(runWorkflow(MutableList.of("let integer x = 1",
                 MutableMap.of("id", "loop", "step", "let x = ${x} + 1"),
                 "if ${x} == 2 then goto loop",
                 "return ${x}")), 3);
     }
 
+    @Test
+    public void testIfWorkflowWithSteps() throws Exception {
+        BiFunction<String, String, Object> run = (preface, cond) ->
+                runWorkflow(MutableList.<Object>of(preface==null ? "let x = hi" : preface,
+                        MutableMap.of("step", "if "+(cond==null ? "${x}" : cond),
+                            "steps", MutableList.of("let y = yes", "return ${y}")),
+                        "return no"));
+
+        Asserts.assertEquals(run.apply(null, null), "yes");
+        Asserts.assertEquals(run.apply("let boolean x = false", null), "no");
+    }
+
 }