Fix daf:trace so you can trace a complex element.

E.g. useful to trace in this context:
   fn:exists(daf:trace(/foo/bar, "bar is complex type"))

I needed this fixed to debug jpeg's dfdl:assert expressions.

DFDL-1804
diff --git a/daffodil-runtime1/src/main/scala/edu/illinois/ncsa/daffodil/dpath/DAFFunctions.scala b/daffodil-runtime1/src/main/scala/edu/illinois/ncsa/daffodil/dpath/DAFFunctions.scala
index 39bed7a..4a9b7ca 100644
--- a/daffodil-runtime1/src/main/scala/edu/illinois/ncsa/daffodil/dpath/DAFFunctions.scala
+++ b/daffodil-runtime1/src/main/scala/edu/illinois/ncsa/daffodil/dpath/DAFFunctions.scala
@@ -35,14 +35,39 @@
 import edu.illinois.ncsa.daffodil.processors.unparsers.UnparseError
 import edu.illinois.ncsa.daffodil.util.Maybe.Nope
 import edu.illinois.ncsa.daffodil.util.Maybe.One
+import edu.illinois.ncsa.daffodil.infoset.DISimple
+import edu.illinois.ncsa.daffodil.infoset.XMLTextInfosetOutputter
+import edu.illinois.ncsa.daffodil.infoset.InfosetCommon
 
 case class DAFTrace(recipe: CompiledDPath, msg: String)
-  extends FNOneArg(recipe, NodeInfo.AnyType) {
+  extends RecipeOpWithSubRecipes(recipe) {
 
-  override def computeValue(str: AnyRef, dstate: DState) = {
-    System.err.println("trace " + msg + ":" + str.toString)
-    str
+  private def asXMLString(ie: InfosetCommon) = {
+    val sw = new java.io.StringWriter()
+    val xml = new XMLTextInfosetOutputter(sw)
+    ie.visit(xml, false)
+    sw.toString()
   }
+
+  override def run(dstate: DState): Unit = {
+    recipe.run(dstate)
+    val nodeString: String = dstate.currentNode match {
+      case _: DISimple | null => {
+        // if there is no current node (null case) then there must be a
+        // current value.
+        val v = dstate.currentValue
+        dstate.setCurrentValue(v)
+        v.toString()
+      }
+      case other: InfosetCommon => "\n" + asXMLString(other)
+    }
+    System.err.println("trace " + msg + ":" + nodeString)
+  }
+
+  // This is toXML for the case class object, not the infoset node it is
+  // dealing with.
+  override def toXML = toXML(recipe.toXML)
+
 }
 
 case object DAFError extends RecipeOp {
diff --git a/daffodil-runtime1/src/main/scala/edu/illinois/ncsa/daffodil/dpath/FNFunctions.scala b/daffodil-runtime1/src/main/scala/edu/illinois/ncsa/daffodil/dpath/FNFunctions.scala
index b486de0..b438da5 100644
--- a/daffodil-runtime1/src/main/scala/edu/illinois/ncsa/daffodil/dpath/FNFunctions.scala
+++ b/daffodil-runtime1/src/main/scala/edu/illinois/ncsa/daffodil/dpath/FNFunctions.scala
@@ -32,7 +32,7 @@
 
 package edu.illinois.ncsa.daffodil.dpath
 
-import edu.illinois.ncsa.daffodil.processors._ ; import edu.illinois.ncsa.daffodil.infoset._
+import edu.illinois.ncsa.daffodil.processors._; import edu.illinois.ncsa.daffodil.infoset._
 import edu.illinois.ncsa.daffodil.processors.unparsers.UnparseError
 import edu.illinois.ncsa.daffodil.api.Diagnostic
 import edu.illinois.ncsa.daffodil.api.DataLocation
@@ -594,6 +594,11 @@
       // if you reach into a child element slot that isn't filled
       case e: InfosetNoSuchChildElementException => ifClosedDoesntExist(dstate, th)
       case e: InfosetArrayIndexOutOfBoundsException => ifClosedDoesntExist(dstate, th)
+
+      // Note that in debugger, expressions are sometimes evaluated in contexts
+      // where they don't make sense.
+      // But we must rethrow this or it will get suppressed when it is a real error.
+      case e: InfosetWrongNodeType => throw th
       //
       // other processing errors indicate it doesn't exist
       //
@@ -988,8 +993,8 @@
     dstate.mode match {
       case UnparserNonBlocking | UnparserBlocking =>
         UnparseError(maybeSFL, dstate.contextLocation, errorString)
-      case _ : ParserMode => {
-        val fe  = new FNErrorFunctionException(maybeSFL, dstate.contextLocation, errorString)
+      case _: ParserMode => {
+        val fe = new FNErrorFunctionException(maybeSFL, dstate.contextLocation, errorString)
         throw fe
       }
     }
diff --git a/daffodil-test/src/test/resources/edu/illinois/ncsa/daffodil/section23/dfdl_expressions/expressions2.tdml b/daffodil-test/src/test/resources/edu/illinois/ncsa/daffodil/section23/dfdl_expressions/expressions2.tdml
index ef678d2..2baca72 100644
--- a/daffodil-test/src/test/resources/edu/illinois/ncsa/daffodil/section23/dfdl_expressions/expressions2.tdml
+++ b/daffodil-test/src/test/resources/edu/illinois/ncsa/daffodil/section23/dfdl_expressions/expressions2.tdml
@@ -245,5 +245,42 @@
       <tdml:error>String</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
+
+  <tdml:defineSchema name="traceComplex" elementFormDefault="unqualified">
+
+    <dfdl:format ref="ex:daffodilTest1" />
+
+    <xs:element name="e">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="aComplexElement">
+            <xs:complexType>
+              <xs:sequence>
+                <xs:element name="y" type="xs:int" dfdl:inputValueCalc="{ 0 }" />
+              </xs:sequence>
+            </xs:complexType>
+          </xs:element>
+          <xs:element name="f" type="xs:string"
+            dfdl:inputValueCalc="{ if (fn:exists(daf:trace(../aComplexElement, 'We can trace a complex element'))) then 'exists' else 'nope' }" />
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+  </tdml:defineSchema>
+
+  <tdml:parserTestCase name="traceComplex" model="traceComplex" root="e"
+    description="Test that daf:trace can take as argument a complex element.">
+    <tdml:document />
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:e>
+          <aComplexElement>
+            <y>0</y>
+          </aComplexElement>
+          <f>exists</f>
+        </ex:e>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+
+  </tdml:parserTestCase>
  
 </tdml:testSuite>
diff --git a/daffodil-test/src/test/scala/edu/illinois/ncsa/daffodil/section23/dfdl_expressions/TestDFDLExpressions.scala b/daffodil-test/src/test/scala/edu/illinois/ncsa/daffodil/section23/dfdl_expressions/TestDFDLExpressions.scala
index 310c010..c279faa 100644
--- a/daffodil-test/src/test/scala/edu/illinois/ncsa/daffodil/section23/dfdl_expressions/TestDFDLExpressions.scala
+++ b/daffodil-test/src/test/scala/edu/illinois/ncsa/daffodil/section23/dfdl_expressions/TestDFDLExpressions.scala
@@ -1009,4 +1009,8 @@
 
 // DFDL-1771
   @Test def test_expr_path_past_root1 { runner7.runOneTest("test_expr_path_past_root1") }
+
+  // DFDL-1804
+    @Test def test_traceComplex { runner7.runOneTest("traceComplex") }
+
 }