You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by mb...@apache.org on 2019/12/11 12:54:35 UTC

[incubator-daffodil] 01/02: Removed DaffodilTunables object from the Infoset entirely.

This is an automated email from the ASF dual-hosted git repository.

mbeckerle pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-daffodil.git

commit cf80a224d506afa9d2420edd2fef5db991ef627d
Author: Michael Beckerle <mb...@tresys.com>
AuthorDate: Fri Nov 8 00:13:36 2019 -0500

    Removed DaffodilTunables object from the Infoset entirely.
    
    They aren't stored on the DIDocument even.
    Nor are they available on the RuntimeData/DPathCompileInfo.
    
    They are saved in the state of the DataProcessor object when it is
    serialized. They exist nowhere else in the runtime data structures.
    
    They go from there, as modified by setTunable() calls, into
    the PState/UState for runtime usage. They, or
    some value they contain, must be passed everywhere they are needed
    at runtime.
    
    DAFFODIL-2242
---
 .../src/main/scala/org/apache/daffodil/Main.scala  |  2 +-
 .../org/apache/daffodil/compiler/Compiler.scala    |  8 +--
 .../daffodil/dpath/DFDLExpressionParser.scala      |  5 +-
 .../org/apache/daffodil/dpath/Expression.scala     | 24 ++++---
 .../apache/daffodil/dsom/CompiledExpression.scala  | 10 +--
 .../apache/daffodil/dsom/DFDLDefineVariable.scala  |  4 +-
 .../apache/daffodil/dsom/DFDLEscapeScheme.scala    |  8 +--
 .../apache/daffodil/dsom/ElementDeclMixin.scala    |  2 +-
 .../apache/daffodil/dsom/RestrictionUnion.scala    |  3 +-
 .../daffodil/dsom/RuntimePropertyMixins.scala      | 60 ++++++++--------
 .../org/apache/daffodil/dsom/SchemaComponent.scala | 10 +--
 .../org/apache/daffodil/dsom/SequenceGroup.scala   |  2 +-
 .../org/apache/daffodil/dsom/SimpleTypes.scala     |  4 +-
 .../apache/daffodil/grammar/BitOrderMixin.scala    |  4 +-
 .../org/apache/daffodil/grammar/GrammarTerm.scala  | 12 +++-
 .../grammar/primitives/PrimitivesDateTime.scala    | 16 ++---
 .../grammar/primitives/PrimitivesLengthKind.scala  |  2 +-
 .../runtime1/ChoiceTermRuntime1Mixin.scala         |  2 +-
 .../runtime1/ElementBaseRuntime1Mixin.scala        |  2 +-
 .../org/apache/daffodil/infoset/TestInfoset.scala  | 46 ++++++-------
 .../infoset/TestInfosetCursorFromReader.scala      | 31 +++++----
 .../org/apache/daffodil/externalvars/Binding.scala |  9 +--
 .../scala/org/apache/daffodil/util/Cursor.scala    |  4 +-
 .../scala/org/apache/daffodil/xml/QNameBase.scala  | 27 +++++---
 .../scala/org/apache/daffodil/xml/QNames.scala     |  6 +-
 .../annotation/props/TestGeneratedProperties.scala |  2 +-
 .../apache/daffodil/propGen/TunableGenerator.scala |  5 +-
 .../processors/unparsers/ElementUnparser.scala     | 10 +--
 .../scala/org/apache/daffodil/BasicComponent.scala | 39 +++++++++++
 .../daffodil/debugger/InteractiveDebugger.scala    | 21 +++++-
 .../org/apache/daffodil/dpath/DFDLXFunctions.scala |  2 +-
 .../org/apache/daffodil/dpath/DPathRuntime.scala   | 10 +--
 .../scala/org/apache/daffodil/dpath/DState.scala   |  8 ++-
 .../org/apache/daffodil/dpath/UpDownMoves.scala    | 11 +--
 .../apache/daffodil/dsom/CompiledExpression1.scala | 12 ++--
 .../apache/daffodil/dsom/ExpressionCompiler.scala  |  3 +-
 .../externalvars/ExternalVariablesLoader.scala     | 10 +--
 .../org/apache/daffodil/infoset/Infoset.scala      |  9 +--
 .../org/apache/daffodil/infoset/InfosetImpl.scala  | 79 ++++++++++------------
 .../apache/daffodil/infoset/InfosetInputter.scala  |  2 +-
 .../apache/daffodil/processors/DataProcessor.scala | 16 +++--
 .../apache/daffodil/processors/Evaluatable.scala   |  6 +-
 .../daffodil/processors/ProcessorStateBases.scala  | 15 ++--
 .../apache/daffodil/processors/RuntimeData.scala   | 22 +++---
 .../daffodil/processors/SchemaSetRuntimeData.scala |  2 +-
 .../processors/parsers/ElementCombinator1.scala    |  2 +-
 .../daffodil/processors/parsers/PState.scala       |  8 +--
 .../org/apache/daffodil/tdml/TDMLRunner.scala      |  2 +-
 48 files changed, 346 insertions(+), 253 deletions(-)

diff --git a/daffodil-cli/src/main/scala/org/apache/daffodil/Main.scala b/daffodil-cli/src/main/scala/org/apache/daffodil/Main.scala
index 1011042..dffea38 100644
--- a/daffodil-cli/src/main/scala/org/apache/daffodil/Main.scala
+++ b/daffodil-cli/src/main/scala/org/apache/daffodil/Main.scala
@@ -621,7 +621,7 @@ object Main extends Logging {
         extVarBindingNodeOpt match {
           case None => Seq.empty
           case Some(extVarBindingsNode) => {
-            ExternalVariablesLoader.getVariables(extVarBindingsNode, tunables)
+            ExternalVariablesLoader.getVariables(extVarBindingsNode)
           }
         }
       }
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/compiler/Compiler.scala b/daffodil-core/src/main/scala/org/apache/daffodil/compiler/Compiler.scala
index 67aa13e..674878b 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/compiler/Compiler.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/compiler/Compiler.scala
@@ -176,7 +176,7 @@ final class ProcessorFactory(val sset: SchemaSet)
       if (rootElem.numComponents > rootElem.numUniqueComponents)
         log(LogLevel.Info, "Compiler: component counts: unique %s, actual %s.",
           rootElem.numUniqueComponents, rootElem.numComponents)
-      val dataProc = new DataProcessor(ssrd)
+      val dataProc = new DataProcessor(ssrd, tunable)
       if (dataProc.isError) {
         // NO longer printing anything here. Callers must do this.
         //        val diags = dataProc.getDiagnostics
@@ -248,7 +248,7 @@ class Compiler(var validateDFDLSchemas: Boolean = true)
   def setExternalDFDLVariable(variable: Binding) = externalDFDLVariables.enqueue(variable)
   def setExternalDFDLVariables(variables: Seq[Binding]) = variables.foreach(b => setExternalDFDLVariable(b))
   def setExternalDFDLVariables(extVarsFile: File): Unit = {
-    val extVars = ExternalVariablesLoader.getVariables(extVarsFile, tunablesObj)
+    val extVars = ExternalVariablesLoader.getVariables(extVarsFile)
     setExternalDFDLVariables(extVars)
   }
 
@@ -260,10 +260,6 @@ class Compiler(var validateDFDLSchemas: Boolean = true)
     tunablesObj = tunablesObj.setTunables(tunables)
   }
 
-  def resetTunables(): Unit = {
-    tunablesObj = DaffodilTunables()
-  }
-
   /**
    * Controls whether we check everything in the schema, or just the element
    * we care about (and everything reachable from it.)
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dpath/DFDLExpressionParser.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dpath/DFDLExpressionParser.scala
index bc3be1a..dd23028 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dpath/DFDLExpressionParser.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dpath/DFDLExpressionParser.scala
@@ -31,6 +31,7 @@ import org.apache.daffodil.exceptions.Assert
 import org.apache.daffodil.oolag.OOLAG.OOLAGHost
 import org.apache.daffodil.xml.NamedQName
 import org.apache.daffodil.xml.QNameRegex
+import org.apache.daffodil.BasicComponent
 
 /**
  * Parses DPath expressions. Most real analysis is done later. This is
@@ -52,14 +53,14 @@ class DFDLPathExpressionParser[T <: AnyRef](
   namespaces: NamespaceBinding,
   context: DPathCompileInfo,
   isEvaluatedAbove: Boolean,
-  host: OOLAGHost) extends RegexParsers {
+  host: BasicComponent) extends RegexParsers {
 
   def compile(expr: String): CompiledExpression[T] = {
     val tree = getExpressionTree(expr)
 
     val recipe = tree.compiledDPath // if we cannot get one this will fail by throwing out of here.
 
-    val value = recipe.runExpressionForConstant(context.schemaFileLocation, context)
+    val value = recipe.runExpressionForConstant(context.schemaFileLocation, context, host.tunable)
     val res: CompiledExpression[T] = value match {
       case Some(constantValue) => {
         Assert.invariant(constantValue != null)
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dpath/Expression.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dpath/Expression.scala
index dc75e80..eb135fd 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dpath/Expression.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dpath/Expression.scala
@@ -17,7 +17,6 @@
 
 package org.apache.daffodil.dpath
 
-import org.apache.daffodil.oolag.OOLAG._
 import org.apache.daffodil.exceptions._
 import org.apache.daffodil.dsom._
 import scala.xml.NamespaceBinding
@@ -36,6 +35,10 @@ import org.apache.daffodil.infoset.SeveralPossibilitiesForNextElement
 import org.apache.daffodil.util.LogLevel
 import org.apache.daffodil.udf.UserDefinedFunctionService
 import org.apache.daffodil.util.Maybe
+import org.apache.daffodil.BasicComponent
+import org.apache.daffodil.api.DaffodilTunables
+import org.apache.daffodil.oolag.OOLAG.OOLAGHostImpl
+import org.apache.daffodil.oolag.OOLAG.OOLAGHost
 
 /**
  * Root class of the type hierarchy for the AST nodes used when we
@@ -47,7 +50,7 @@ import org.apache.daffodil.util.Maybe
  * This is the OOLAG pattern again.
  */
 abstract class Expression extends OOLAGHostImpl()
-  with ImplementsThrowsOrSavesSDE {
+  with BasicComponent {
 
   /**
    * Use several calls instead of one, because then OOLAG will try them
@@ -59,8 +62,8 @@ abstract class Expression extends OOLAGHostImpl()
   requiredEvaluations(isTypeCorrect)
   requiredEvaluations(compiledDPath_)
 
-  def tunable = compileInfo.tunable
-
+  override lazy val tunable = parent.tunable
+  override lazy val unqualifiedPathStepPolicy = parent.unqualifiedPathStepPolicy
   /**
    * Override where we traverse/access elements.
    */
@@ -236,7 +239,7 @@ abstract class Expression extends OOLAGHostImpl()
   def inherentType: NodeInfo.Kind
 
   def resolveRef(qnameString: String) = {
-    QName.resolveRef(qnameString, namespaces, tunable).recover {
+    QName.resolveRef(qnameString, namespaces, tunable.unqualifiedPathStepPolicy).recover {
       case _: Throwable =>
         SDE("The prefix of '%s' has no corresponding namespace definition.", qnameString)
     }.get
@@ -569,9 +572,12 @@ case class WholeExpression(
   ifor: Expression,
   nsBindingForPrefixResolution: NamespaceBinding,
   ci: DPathCompileInfo,
-  host: OOLAGHost)
+  host: BasicComponent)
   extends Expression {
 
+  final override lazy val tunable = host.tunable
+  final override lazy val unqualifiedPathStepPolicy = host.unqualifiedPathStepPolicy
+
   def init() {
     this.setOOLAGContext(host) // we are the root of expression, but we propagate diagnostics further.
     this.setContextsForChildren()
@@ -899,7 +905,7 @@ sealed abstract class StepExpression(val step: String, val pred: Option[Predicat
   }
 
   lazy val stepQName = {
-    val e = QName.resolveStep(step, namespaces, tunable)
+    val e = QName.resolveStep(step, namespaces, tunable.unqualifiedPathStepPolicy)
     e match {
       case Failure(th) => SDE("Step %s prefix has no corresponding namespace.", step)
       case Success(v) => v
@@ -1920,7 +1926,9 @@ case class FunctionCallExpression(functionQNameString: String, expressions: List
       case typeCalcName: LiteralExpression => typeCalcName.v.asInstanceOf[String]
       case _ => SDE("The type calculator name argument must be a constant string")
     }
-    val refType = QName.resolveRef(qname, compileInfo.namespaces, compileInfo.tunable).get.toGlobalQName
+    val refType = QName.resolveRef(
+      qname, compileInfo.namespaces,
+      tunable.unqualifiedPathStepPolicy).get.toGlobalQName
     val typeCalculator = compileInfo.typeCalcMap.get(refType) match {
       case None => SDE("Simple type %s does not exist or does not have a repType", refType)
       case Some(x) => x
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/CompiledExpression.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/CompiledExpression.scala
index fcc3c89..e6f82bc 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/CompiledExpression.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/CompiledExpression.scala
@@ -24,6 +24,8 @@ import org.apache.daffodil.xml.NamedQName
 import java.lang.{ Long => JLong, Boolean => JBoolean }
 import org.apache.daffodil.schema.annotation.props.Found
 import org.apache.daffodil.oolag.OOLAG._
+import org.apache.daffodil.processors.HasTunable
+import org.apache.daffodil.BasicComponent
 
 object ExpressionCompilers extends ExpressionCompilerClass {
   override val String = new ExpressionCompiler[String]
@@ -55,7 +57,7 @@ class ExpressionCompiler[T <: AnyRef] extends ExpressionCompilerBase[T] {
     namespaces: NamespaceBinding,
     compileInfoWhereExpressionWasLocated: DPathCompileInfo,
     isEvaluatedAbove: Boolean,
-    host: OOLAGHost,
+    host: BasicComponent,
     compileInfo: DPathCompileInfo): CompiledExpression[T] = {
 
     val res =
@@ -99,7 +101,7 @@ class ExpressionCompiler[T <: AnyRef] extends ExpressionCompilerBase[T] {
     qn: NamedQName,
     nodeInfoKind: NodeInfo.Kind,
     property: Found,
-    host: OOLAGHost,
+    host: BasicComponent,
     compileInfo: DPathCompileInfo,
     isEvaluatedAbove: Boolean = false): CompiledExpression[T] = {
 
@@ -138,7 +140,7 @@ class ExpressionCompiler[T <: AnyRef] extends ExpressionCompilerBase[T] {
     staticNodeInfoKind: NodeInfo.Kind,
     runtimeNodeInfoKind: NodeInfo.Kind,
     property: Found,
-    host: OOLAGHost,
+    host: BasicComponent,
     compileInfo: DPathCompileInfo): CompiledExpression[T] = {
 
     val isEvaluatedAbove = false
@@ -196,7 +198,7 @@ class ExpressionCompiler[T <: AnyRef] extends ExpressionCompilerBase[T] {
     namespaces: NamespaceBinding,
     compileInfoWhereExpressionWasLocated: DPathCompileInfo,
     isEvaluatedAbove: Boolean,
-    host: OOLAGHost,
+    host: BasicComponent,
     compileInfo: DPathCompileInfo): CompiledExpression[T] = {
 
     // Treat this as an expression--validate and compile it
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLDefineVariable.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLDefineVariable.scala
index 3f73dcd..b2cc7dd 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLDefineVariable.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLDefineVariable.scala
@@ -53,7 +53,7 @@ class DFDLDefineVariable(node: Node, doc: SchemaDocument)
   }
 
   final lazy val typeQName = {
-    val eQN = QName.resolveRef(typeQNameString, namespaces, tunable)
+    val eQN = QName.resolveRef(typeQNameString, namespaces, tunable.unqualifiedPathStepPolicy)
     val res = eQN.recover {
       case _: Throwable =>
         SDE("Variables must have primitive types. Type is '%s'.", typeQNameString)
@@ -88,7 +88,7 @@ class DFDLDefineVariable(node: Node, doc: SchemaDocument)
     this.typeQName,
     this.namedQName.asInstanceOf[GlobalQName],
     this.primType,
-    this.tunable)
+    this.tunable.unqualifiedPathStepPolicy)
 }
 
 abstract class VariableReference(node: Node, decl: AnnotatedSchemaComponent)
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLEscapeScheme.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLEscapeScheme.scala
index aa13c61..64fbb49 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLEscapeScheme.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLEscapeScheme.scala
@@ -87,7 +87,7 @@ final class DFDLEscapeScheme(node: Node, decl: AnnotatedSchemaComponent, defES:
     val expr = ExpressionCompilers.String.compileProperty(qn, NodeInfo.NonEmptyString, escapeCharacterRaw, this,
       defES.pointOfUse.dpathCompileInfo)
     val ev = new EscapeCharEv(expr, runtimeData)
-    ev.compile()
+    ev.compile(tunable)
     ev
   }.value
 
@@ -101,7 +101,7 @@ final class DFDLEscapeScheme(node: Node, decl: AnnotatedSchemaComponent, defES:
         val expr = ExpressionCompilers.String.compileDelimiter(qn, typeIfStaticallyKnown, typeIfRuntimeKnown, found, this,
           defES.pointOfUse.dpathCompileInfo)
         val ev = new EscapeEscapeCharEv(expr, runtimeData)
-        ev.compile()
+        ev.compile(tunable)
         One(ev)
       }
     }
@@ -119,7 +119,7 @@ final class DFDLEscapeScheme(node: Node, decl: AnnotatedSchemaComponent, defES:
       case EscapeKind.EscapeBlock => new EscapeSchemeBlockParseEv(escapeBlockStart, escapeBlockEnd, optionEscapeEscapeCharacterEv, runtimeData)
       case EscapeKind.EscapeCharacter => new EscapeSchemeCharParseEv(escapeCharacterEv, optionEscapeEscapeCharacterEv, runtimeData)
     }
-    espev.compile()
+    espev.compile(tunable)
     espev
   }
 
@@ -128,7 +128,7 @@ final class DFDLEscapeScheme(node: Node, decl: AnnotatedSchemaComponent, defES:
       case EscapeKind.EscapeBlock => new EscapeSchemeBlockUnparseEv(escapeBlockStart, escapeBlockEnd, optionEscapeEscapeCharacterEv, optionExtraEscapedCharacters, generateEscapeBlock, runtimeData)
       case EscapeKind.EscapeCharacter => new EscapeSchemeCharUnparseEv(escapeCharacterEv, optionEscapeEscapeCharacterEv, optionExtraEscapedCharacters, runtimeData)
     }
-    esuev.compile()
+    esuev.compile(tunable)
     esuev
   }
 
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementDeclMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementDeclMixin.scala
index 2c43a79..1434538 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementDeclMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementDeclMixin.scala
@@ -166,7 +166,7 @@ trait ElementDeclFactoryImplMixin
 
   final override lazy val namedTypeQName: Option[RefQName] = {
     typeName.map { tname =>
-      QName.resolveRef(tname, namespaces, tunable).get
+      QName.resolveRef(tname, namespaces, tunable.unqualifiedPathStepPolicy).get
     }
   }
 
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/RestrictionUnion.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/RestrictionUnion.scala
index b09fa05..d3f8315 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/RestrictionUnion.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/RestrictionUnion.scala
@@ -73,7 +73,8 @@ final class Restriction(xmlArg: Node, val simpleTypeDef: SimpleTypeDefBase)
   lazy val baseQName = {
     val baseQNameNodeSeq = xml \ "@base"
     val baseQNameString = baseQNameNodeSeq.text
-    val tryBaseQName = QName.resolveRef(baseQNameString, xml.scope, tunable)
+    val tryBaseQName = QName.resolveRef(baseQNameString, xml.scope,
+      tunable.unqualifiedPathStepPolicy)
     Assert.invariant(tryBaseQName.isSuccess)
     tryBaseQName.get
   }
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/RuntimePropertyMixins.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/RuntimePropertyMixins.scala
index c81316a..c9ca99b 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/RuntimePropertyMixins.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/RuntimePropertyMixins.scala
@@ -109,7 +109,7 @@ trait TermRuntimeValuedPropertiesMixin
 
   final lazy val encodingEv = {
     val ev = new EncodingEv(encodingExpr, termRuntimeData)
-    ev.compile()
+    ev.compile(tunable)
     ev
   }
 
@@ -121,7 +121,7 @@ trait TermRuntimeValuedPropertiesMixin
   final lazy val maybeCharsetEv =
     if (optionEncodingRaw.isDefined) {
       val ev = new CharsetEv(encodingEv, termRuntimeData)
-      ev.compile()
+      ev.compile(tunable)
       One(ev)
     } else
       Nope
@@ -129,7 +129,7 @@ trait TermRuntimeValuedPropertiesMixin
   final lazy val maybeFillByteEv = {
     if (optionFillByteRaw.isDefined) {
       val ev = new FillByteEv(fillByte, charsetEv, termRuntimeData)
-      ev.compile()
+      ev.compile(tunable)
       One(ev)
     } else {
       Nope
@@ -146,7 +146,7 @@ trait TermRuntimeValuedPropertiesMixin
       ExpressionCompilers.String.compileProperty(qn, NodeInfo.NonEmptyString, outputNewLineRaw, decl, dpathCompileInfo)
     }
     val ev = new OutputNewLineEv(outputNewLineExpr, termRuntimeData)
-    ev.compile()
+    ev.compile(tunable)
     ev
   }
 
@@ -197,12 +197,12 @@ trait DelimitedRuntimeValuedPropertiesMixin
 
   lazy val initiatorParseEv = {
     val ev = new InitiatorParseEv(initiatorExpr, decl.ignoreCaseBool, decl.termRuntimeData)
-    ev.compile()
+    ev.compile(tunable)
     ev
   }
   lazy val initiatorUnparseEv = {
     val ev = new InitiatorUnparseEv(initiatorExpr, outputNewLineEv, decl.termRuntimeData)
-    ev.compile()
+    ev.compile(tunable)
     ev
   }
 
@@ -220,12 +220,12 @@ trait DelimitedRuntimeValuedPropertiesMixin
 
   lazy val terminatorParseEv = {
     val ev = new TerminatorParseEv(terminatorExpr, isLengthKindDelimited, decl.ignoreCaseBool, decl.termRuntimeData)
-    ev.compile()
+    ev.compile(tunable)
     ev
   }
   lazy val terminatorUnparseEv = {
     val ev = new TerminatorUnparseEv(terminatorExpr, isLengthKindDelimited, outputNewLineEv, decl.termRuntimeData)
-    ev.compile()
+    ev.compile(tunable)
     ev
   }
 
@@ -270,7 +270,7 @@ trait ElementRuntimeValuedPropertiesMixin
       Nope
     } else if (optionByteOrderRaw.isDefined) {
       val ev = new ByteOrderEv(byteOrderExpr, elementRuntimeData)
-      ev.compile()
+      ev.compile(tunable)
       One(ev)
     } else {
       Nope
@@ -285,7 +285,7 @@ trait ElementRuntimeValuedPropertiesMixin
   private lazy val explicitLengthEv: ExplicitLengthEv = {
     Assert.usage(lengthKind eq LengthKind.Explicit)
     val ev = new ExplicitLengthEv(lengthExpr, erd)
-    ev.compile()
+    ev.compile(tunable)
     ev
   }
 
@@ -301,7 +301,7 @@ trait ElementRuntimeValuedPropertiesMixin
       case (Text, _) =>
         SDE("Type %s with dfdl:representation='text' cannot have dfdl:lengthKind='implicit'", typeDef.typeNode.name)
     }
-    ev.compile()
+    ev.compile(tunable)
     ev
   }
 
@@ -355,7 +355,7 @@ trait ElementRuntimeValuedPropertiesMixin
         case _ => Assert.invariantFailed("not Implicit or Explicit")
       }
     val ev = new LengthInBitsEv(units, lengthKind, maybeCharsetEv, lenEv, erd)
-    ev.compile()
+    ev.compile(tunable)
     ev
   }
 
@@ -370,7 +370,7 @@ trait ElementRuntimeValuedPropertiesMixin
    */
   private lazy val minLengthInBitsEv: MinLengthInBitsEv = {
     val ev = new MinLengthInBitsEv(minLenUnits, lengthKind, maybeCharsetEv, minLen, erd)
-    ev.compile()
+    ev.compile(tunable)
     ev
   }
 
@@ -483,7 +483,7 @@ trait ElementRuntimeValuedPropertiesMixin
       this.simpleType.optRepTypeElement.get.unparseTargetLengthInBitsEv
     } else {
       val ev = new UnparseTargetLengthInBitsEv(elementLengthInBitsEv, minLengthInBitsEv, erd)
-      ev.compile()
+      ev.compile(tunable)
       ev
     }
   }
@@ -499,7 +499,7 @@ trait ElementRuntimeValuedPropertiesMixin
         val optCs = charsetEv.optConstant
         if (optCs.isEmpty || optCs.get.maybeFixedWidth.isEmpty) {
           val ev = new UnparseTargetLengthInCharactersEv(lengthEv, charsetEv, minLen, erd)
-          ev.compile()
+          ev.compile(tunable)
           One(ev)
         } else
           Nope
@@ -530,13 +530,13 @@ trait ElementRuntimeValuedPropertiesMixin
 
   lazy val occursCountEv = {
     val ev = new OccursCountEv(occursCountExpr, erd)
-    ev.compile()
+    ev.compile(tunable)
     ev
   }
 
   lazy val nilStringLiteralForUnparserEv = {
     val ev = new NilStringLiteralForUnparserEv(termRuntimeData, maybeOutputNewLineEv, rawNilValuesForUnparse.head)
-    ev.compile()
+    ev.compile(tunable)
     ev
   }
 
@@ -669,13 +669,13 @@ trait SequenceRuntimeValuedPropertiesMixin
 
   lazy val separatorParseEv = {
     val ev = new SeparatorParseEv(separatorExpr, decl.ignoreCaseBool, decl.termRuntimeData)
-    ev.compile()
+    ev.compile(tunable)
     ev
   }
 
   lazy val separatorUnparseEv = {
     val ev = new SeparatorUnparseEv(separatorExpr, outputNewLineEv, decl.termRuntimeData)
-    ev.compile()
+    ev.compile(tunable)
     ev
   }
 
@@ -713,7 +713,7 @@ trait LayeringRuntimeValuedPropertiesMixin
   final lazy val maybeLayerTransformEv = {
     if (optionLayerTransformRaw.isDefined) {
       val ev = new LayerTransformEv(layerTransformExpr, termRuntimeData)
-      ev.compile()
+      ev.compile(tunable)
       One(ev)
     } else {
       Nope
@@ -733,7 +733,7 @@ trait LayeringRuntimeValuedPropertiesMixin
   private final lazy val maybeLayerEncodingEv = {
     if (optionLayerEncodingRaw.isDefined) {
       val ev = new LayerEncodingEv(layerEncodingExpr, termRuntimeData)
-      ev.compile()
+      ev.compile(tunable)
       One(ev)
     } else {
       Nope
@@ -743,7 +743,7 @@ trait LayeringRuntimeValuedPropertiesMixin
   final lazy val maybeLayerCharsetEv =
     if (optionLayerEncodingRaw.isDefined) {
       val ev = new LayerCharsetEv(layerEncodingEv, termRuntimeData)
-      ev.compile()
+      ev.compile(tunable)
       One(ev)
     } else
       Nope
@@ -757,7 +757,7 @@ trait LayeringRuntimeValuedPropertiesMixin
     if (optionLayerLengthRaw.isDefined) {
       layerLengthUnits
       val ev = new LayerLengthInBytesEv(layerLengthExpr, termRuntimeData)
-      ev.compile()
+      ev.compile(tunable)
       One(ev)
     } else {
       Nope
@@ -777,7 +777,7 @@ trait LayeringRuntimeValuedPropertiesMixin
   final lazy val maybeLayerBoundaryMarkEv = {
     if (optionLayerBoundaryMarkRaw.isDefined) {
       val ev = new LayerBoundaryMarkEv(layerBoundaryMarkExpr, termRuntimeData)
-      ev.compile()
+      ev.compile(tunable)
       One(ev)
     } else {
       Nope
@@ -799,7 +799,7 @@ trait SimpleTypeRuntimeValuedPropertiesMixin
 
   final lazy val textStandardDecimalSeparatorEv = {
     val ev = new TextStandardDecimalSeparatorEv(textStandardDecimalSeparatorExpr, erd)
-    ev.compile()
+    ev.compile(tunable)
     ev
   }
 
@@ -811,7 +811,7 @@ trait SimpleTypeRuntimeValuedPropertiesMixin
 
   final lazy val textStandardGroupingSeparatorEv = {
     val ev = new TextStandardGroupingSeparatorEv(textStandardGroupingSeparatorExpr, erd)
-    ev.compile()
+    ev.compile(tunable)
     ev
   }
 
@@ -823,7 +823,7 @@ trait SimpleTypeRuntimeValuedPropertiesMixin
 
   final lazy val textStandardExponentRepEv = {
     val ev = new TextStandardExponentRepEv(textStandardExponentRepExpr, erd)
-    ev.compile()
+    ev.compile(tunable)
     ev
   }
 
@@ -840,7 +840,7 @@ trait SimpleTypeRuntimeValuedPropertiesMixin
   final lazy val maybeBinaryFloatRepEv = {
     if (optionBinaryFloatRepRaw.isDefined) {
       val ev = new BinaryFloatRepEv(binaryFloatRepExpr, erd)
-      ev.compile()
+      ev.compile(tunable)
       One(ev)
     } else {
       Nope
@@ -861,13 +861,13 @@ trait SimpleTypeRuntimeValuedPropertiesMixin
     val mustBeSameLength = (((this.lengthKind eq LengthKind.Explicit) || (this.lengthKind eq LengthKind.Implicit)) &&
       ((this.textPadKind eq TextPadKind.None) || (this.textTrimKind eq TextTrimKind.None)))
     val ev = new TextBooleanTrueRepEv(textBooleanTrueRepExpr, textBooleanFalseRepEv, mustBeSameLength, erd)
-    ev.compile()
+    ev.compile(tunable)
     ev
   }
 
   final lazy val textBooleanFalseRepEv = {
     val ev = new TextBooleanFalseRepEv(textBooleanFalseRepExpr, erd)
-    ev.compile()
+    ev.compile(tunable)
     ev
   }
 
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaComponent.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaComponent.scala
index 02b2295..668d18e 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaComponent.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaComponent.scala
@@ -35,6 +35,7 @@ import org.apache.daffodil.xml.GetAttributesMixin
 import org.apache.daffodil.schema.annotation.props.PropTypes
 import org.apache.daffodil.util.Maybe
 import org.apache.daffodil.util.Misc
+import org.apache.daffodil.BasicComponent
 
 abstract class SchemaComponentImpl(
   final override val xml: Node,
@@ -51,7 +52,7 @@ abstract class SchemaComponentImpl(
  * Every schema component has a schema document, and a schema, and a namespace.
  */
 trait SchemaComponent
-  extends OOLAGHost
+  extends BasicComponent
   with ImplementsThrowsOrSavesSDE
   with GetAttributesMixin
   with SchemaComponentIncludesAndImportsMixin
@@ -63,7 +64,8 @@ trait SchemaComponent
 
   override def oolagContextViaArgs = optLexicalParent
 
-  lazy val tunable: DaffodilTunables = optLexicalParent.get.tunable
+  override lazy val tunable: DaffodilTunables = optLexicalParent.get.tunable
+  final override lazy val unqualifiedPathStepPolicy = tunable.unqualifiedPathStepPolicy
 
   lazy val dpathCompileInfo: DPathCompileInfo = {
     lazy val parents = enclosingComponent.map { _.dpathCompileInfo }.toSeq
@@ -73,7 +75,7 @@ trait SchemaComponent
       namespaces,
       path,
       schemaFileLocation,
-      tunable,
+      tunable.unqualifiedPathStepPolicy,
       schemaSet.typeCalcMap,
       runtimeData)
   }
@@ -98,7 +100,7 @@ trait SchemaComponent
       diagnosticDebugName,
       path,
       namespaces,
-      tunable)
+      tunable.unqualifiedPathStepPolicy)
   }.value
 
   def variableMap: VariableMap = LV('variableMap) {
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SequenceGroup.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SequenceGroup.scala
index 17ff44a..92df20a 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SequenceGroup.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SequenceGroup.scala
@@ -244,7 +244,7 @@ abstract class SequenceGroupTermBase(
         Maybe.toMaybe(optionLayerLengthUnits),
         maybeLayerBoundaryMarkEv,
         termRuntimeData)
-      lt.compile()
+      lt.compile(tunable)
       Maybe.One(lt)
     }
   }
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SimpleTypes.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SimpleTypes.scala
index ebff732..bab02ad 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SimpleTypes.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SimpleTypes.scala
@@ -248,7 +248,7 @@ abstract class SimpleTypeDefBase(xml: Node, lexicalParent: SchemaComponent)
       optRestriction.flatMap { r => toOpt(r.hasTotalDigits, r.totalDigitsValue) },
       optRestriction.flatMap { r => toOpt(r.hasFractionDigits, r.fractionDigitsValue) },
       optUnion.orElse(optRestriction.flatMap { _.optUnion }).toSeq.flatMap { _.unionMemberTypes.map { _.simpleTypeRuntimeData } },
-      tunable,
+      tunable.unqualifiedPathStepPolicy,
       optRepTypeDef.map(_.simpleTypeRuntimeData),
       optRepValueSet,
       optTypeCalculator,
@@ -425,7 +425,7 @@ abstract class SimpleTypeDefBase(xml: Node, lexicalParent: SchemaComponent)
     lazy val fromSelf: Option[SimpleTypeBase with NamedMixin] = {
       val qName = findPropertyOption("repType").toOption
         .map(qn => {
-          QName.resolveRef(qn, namespaces, tunable).toOption match {
+          QName.resolveRef(qn, namespaces, tunable.unqualifiedPathStepPolicy).toOption match {
             case Some(x) => x
             case None => SDE(s"Cannot resolve type ${qn}")
           }
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/BitOrderMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/BitOrderMixin.scala
index fe1be72..5e3d1de 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/BitOrderMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/BitOrderMixin.scala
@@ -84,7 +84,7 @@ trait BitOrderMixin extends GrammarMixin with ByteOrderAnalysisMixin { self: Ter
     else {
       val checkByteAndBitOrder = {
         val ev = new CheckByteAndBitOrderEv(termRuntimeData, defaultBitOrder)
-        ev.compile()
+        ev.compile(tunable)
         ev
       }
       Maybe(checkByteAndBitOrder)
@@ -98,7 +98,7 @@ trait BitOrderMixin extends GrammarMixin with ByteOrderAnalysisMixin { self: Ter
     else {
       val checkBitOrderAndCharset = {
         val ev = new CheckBitOrderAndCharsetEv(termRuntimeData, defaultBitOrder, charsetEv)
-        ev.compile()
+        ev.compile(tunable)
         ev
       }
       Maybe(checkBitOrderAndCharset)
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/GrammarTerm.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/GrammarTerm.scala
index f28178a..1b8bc3a 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/GrammarTerm.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/GrammarTerm.scala
@@ -27,6 +27,7 @@ import org.apache.daffodil.compiler.BothParserAndUnparser
 import org.apache.daffodil.api.WarnID
 import org.apache.daffodil.util.Maybe
 import org.apache.daffodil.runtime1.GramRuntime1Mixin
+import org.apache.daffodil.BasicComponent
 
 /**
  * Gram - short for "Grammar Term"
@@ -51,11 +52,18 @@ import org.apache.daffodil.runtime1.GramRuntime1Mixin
  */
 abstract class Gram(contextArg: SchemaComponent)
   extends OOLAGHostImpl(contextArg)
+  with BasicComponent
   with GramRuntime1Mixin {
 
-  final def SDE(str: String, args: Any*): Nothing = context.SDE(str, args: _*)
+  final override lazy val tunable = context.tunable
 
-  final def SDW(warnID: WarnID, str: String, args: Any*): Unit = context.SDW(warnID, str, args: _*)
+  final override def namespaces = context.namespaces
+  final override def unqualifiedPathStepPolicy = context.unqualifiedPathStepPolicy
+  final override def schemaFileLocation = context.schemaFileLocation
+
+  final override def SDE(str: String, args: Any*): Nothing = context.SDE(str, args: _*)
+
+  final override def SDW(warnID: WarnID, str: String, args: Any*): Unit = context.SDW(warnID, str, args: _*)
 
   val forWhat: ParserOrUnparser = BothParserAndUnparser
 
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesDateTime.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesDateTime.scala
index fee4c51..fbd3a53 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesDateTime.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesDateTime.scala
@@ -128,13 +128,13 @@ abstract class ConvertTextCalendarPrimBase(e: ElementBase, guard: Boolean)
 
   private lazy val localeEv = {
     val ev = new CalendarLanguageEv(e.calendarLanguage, e.erd)
-    ev.compile()
+    ev.compile(e.tunable)
     ev
   }
 
   private lazy val calendarEv = {
     val cev = new CalendarEv(localeEv, calendarTz, firstDay, calendarDaysInFirstWeek, calendarCheckPolicy, e.erd)
-    cev.compile()
+    cev.compile(e.tunable)
     cev
   }
 
@@ -147,7 +147,7 @@ abstract class ConvertTextCalendarPrimBase(e: ElementBase, guard: Boolean)
       }
     }
 
-    val patternToCheck : String = if (e.representation == Representation.Text) {
+    val patternToCheck: String = if (e.representation == Representation.Text) {
       val escapedText = "(''|'[^']+'|[^a-zA-Z])".r
       escapedText.replaceAllIn(p, "")
     } else {
@@ -276,9 +276,9 @@ case class ConvertBinaryDateTimeSecMilliPrim(e: ElementBase, lengthInBits: Long)
 
   override lazy val unparser =
     new ConvertBinaryCalendarSecMilliUnparser(
-    e.elementRuntimeData,
-    e.binaryCalendarRep,
-    epochCalendar.getTimeInMillis,
-    lengthInBits.toInt,
-    !epochCalendar.getTimeZone.equals(TimeZone.UNKNOWN_ZONE))
+      e.elementRuntimeData,
+      e.binaryCalendarRep,
+      epochCalendar.getTimeInMillis,
+      lengthInBits.toInt,
+      !epochCalendar.getTimeZone.equals(TimeZone.UNKNOWN_ZONE))
 }
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesLengthKind.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesLengthKind.scala
index 39ac0d7..26e3d22 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesLengthKind.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesLengthKind.scala
@@ -131,7 +131,7 @@ abstract class StringDelimited(e: ElementBase)
   // TODO: move out of parser and into the dsom
   lazy val fieldDFAParseEv = {
     val ev = new FieldDFAParseEv(escapeSchemeParseEvOpt, context.runtimeData)
-    ev.compile()
+    ev.compile(context.tunable)
     ev
   }
 
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ChoiceTermRuntime1Mixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ChoiceTermRuntime1Mixin.scala
index 17be65b..a47ee57 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ChoiceTermRuntime1Mixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ChoiceTermRuntime1Mixin.scala
@@ -42,7 +42,7 @@ trait ChoiceTermRuntime1Mixin { self: ChoiceTermBase =>
   final lazy val choiceDispatchKeyEv = {
     Assert.invariant(isDirectDispatch)
     val ev = new ChoiceDispatchKeyEv(choiceDispatchKeyExpr, modelGroupRuntimeData)
-    ev.compile()
+    ev.compile(tunable)
     ev
   }
 
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ElementBaseRuntime1Mixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ElementBaseRuntime1Mixin.scala
index a332379..5131811 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ElementBaseRuntime1Mixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ElementBaseRuntime1Mixin.scala
@@ -140,7 +140,7 @@ trait ElementBaseRuntime1Mixin { self: ElementBase =>
       namedQName,
       optPrimType,
       schemaFileLocation,
-      tunable,
+      tunable.unqualifiedPathStepPolicy,
       schemaSet.typeCalcMap,
       runtimeData,
       shortSchemaComponentDesignator)
diff --git a/daffodil-core/src/test/scala/org/apache/daffodil/infoset/TestInfoset.scala b/daffodil-core/src/test/scala/org/apache/daffodil/infoset/TestInfoset.scala
index 767702a..6fa9812 100644
--- a/daffodil-core/src/test/scala/org/apache/daffodil/infoset/TestInfoset.scala
+++ b/daffodil-core/src/test/scala/org/apache/daffodil/infoset/TestInfoset.scala
@@ -94,7 +94,7 @@ object TestInfoset {
       fail("dp compile errors: " + msgs)
     }
     val infosetRootElem = TestInfoset.elem2Infoset(infosetAsXML, dp)
-    (infosetRootElem, pf.rootElem)
+    (infosetRootElem, pf.rootElem, dp.tunable)
   }
 
 }
@@ -119,11 +119,11 @@ class TestInfoset1 {
 
     val xmlInfoset = <list xmlns={ ex }><w>4</w></list>
 
-    val (infoset: DIComplex, _) = testInfoset(testSchema, xmlInfoset)
+    val (infoset: DIComplex, _, tunable) = testInfoset(testSchema, xmlInfoset)
     val list_erd = infoset.erd
     assertEquals(list_erd, infoset.runtimeData)
     val Seq(w_erd) = list_erd.childERDs
-    val wItem = infoset.getChild(w_erd).asInstanceOf[InfosetSimpleElement]
+    val wItem = infoset.getChild(w_erd, tunable).asInstanceOf[InfosetSimpleElement]
     assertEquals(infoset, wItem.parent)
     assertEquals(4, wItem.dataValue)
 
@@ -146,14 +146,14 @@ class TestInfoset1 {
       </xs:complexType>)
 
     val xmlInfoset = <list xmlns={ ex }><w>4</w><c>7</c></list>
-    val (infoset, _) = testInfoset(testSchema, xmlInfoset)
+    val (infoset, _, tunable) = testInfoset(testSchema, xmlInfoset)
     assertNotNull(infoset.parent)
     val list_erd = infoset.erd
     val Seq(w_erd, _, _, c_erd) = list_erd.childERDs
     assertEquals(list_erd, infoset.runtimeData)
-    val wItem = infoset.asComplex.getChild(w_erd).asInstanceOf[InfosetSimpleElement]
+    val wItem = infoset.asComplex.getChild(w_erd, tunable).asInstanceOf[InfosetSimpleElement]
     assertEquals(4, wItem.dataValue)
-    val cItem = infoset.asComplex.getChild(c_erd).asInstanceOf[InfosetSimpleElement]
+    val cItem = infoset.asComplex.getChild(c_erd, tunable).asInstanceOf[InfosetSimpleElement]
     assertEquals(7, cItem.dataValue)
     assertEquals(infoset, cItem.parent)
   }
@@ -170,9 +170,9 @@ class TestInfoset1 {
       </xs:complexType>)
 
     val xmlInfoset = <list xmlns={ ex }><w>4</w><w>5</w></list>
-    val (infoset: DIComplex, _) = testInfoset(testSchema, xmlInfoset)
+    val (infoset: DIComplex, _, tunable) = testInfoset(testSchema, xmlInfoset)
     val Seq(w_erd) = infoset.erd.childERDs
-    infoset.getChildArray(w_erd) match {
+    infoset.getChildArray(w_erd, tunable) match {
       case arr: DIArray => {
         assertEquals(2, arr.length)
         var a = arr(1).asInstanceOf[InfosetSimpleElement]
@@ -205,10 +205,10 @@ class TestInfoset1 {
 
     val xmlInfoset = <list xmlns={ ex }><w>4</w><w>5</w><c>7</c></list>
 
-    val (infoset: DIComplex, _) = testInfoset(testSchema, xmlInfoset)
+    val (infoset: DIComplex, _, tunable) = testInfoset(testSchema, xmlInfoset)
     val list_erd = infoset.erd
     val Seq(w_erd, _, _, c_erd) = list_erd.childERDs
-    infoset.getChildArray(w_erd) match {
+    infoset.getChildArray(w_erd, tunable) match {
       case arr: DIArray => {
         var a = arr(1).asInstanceOf[InfosetSimpleElement]
         assertEquals(2, arr.length)
@@ -220,7 +220,7 @@ class TestInfoset1 {
         assertEquals(infoset, a.parent)
       }
     }
-    infoset.getChild(c_erd) match {
+    infoset.getChild(c_erd, tunable) match {
       case s: DISimple => assertEquals(7, s.dataValue)
     }
   }
@@ -239,13 +239,13 @@ class TestInfoset1 {
 
     val xmlInfoset = <list xmlns={ ex } xmlns:xsi={ xsi }><x xsi:nil='true'/></list>
 
-    val (infoset: DIComplex, _) = testInfoset(testSchema, xmlInfoset)
+    val (infoset: DIComplex, _, tunable) = testInfoset(testSchema, xmlInfoset)
     val list_erd = infoset.erd
     val Seq(x_erd) = list_erd.childERDs
     assertTrue(x_erd.isArray)
 
     assertTrue(infoset.isInstanceOf[DIComplex])
-    val xchild = infoset.getChildArray(x_erd)
+    val xchild = infoset.getChildArray(x_erd, tunable)
     xchild match {
       case arr: DIArray => {
         assertEquals(1, arr.length)
@@ -277,10 +277,10 @@ class TestInfoset1 {
 
     val xmlInfoset = <list xmlns={ ex } xmlns:xsi={ xsi }><x xsi:nil='true'/></list>
 
-    val (infoset: DIComplex, _) = testInfoset(testSchema, xmlInfoset)
+    val (infoset: DIComplex, _, tunable) = testInfoset(testSchema, xmlInfoset)
     val list_erd = infoset.erd
     val Seq(x_erd) = list_erd.childERDs
-    infoset.getChildArray(x_erd) match {
+    infoset.getChildArray(x_erd, tunable) match {
       case xa: DIArray => {
         assertEquals(1, xa.length)
         val e = xa.getOccurrence(1)
@@ -311,21 +311,21 @@ class TestInfoset1 {
 
     val xmlInfoset = <list xmlns={ ex } xmlns:xsi={ xsi }><w>4</w><w>5</w><x xsi:nil='true'/><x><c>7</c></x></list>
 
-    val (infoset: DIComplex, rootTerm) = testInfoset(testSchema, xmlInfoset)
+    val (infoset: DIComplex, rootTerm, tunable) = testInfoset(testSchema, xmlInfoset)
     val list_erd = infoset.erd
     val rootPossibles = rootTerm.possibleNextLexicalSiblingStreamingUnparserElements
     val Seq(wTerm: ElementBase, xTerm: ElementBase) = rootTerm.complexType.modelGroup.groupMembers
     val xPossibles = xTerm.possibleNextLexicalSiblingStreamingUnparserElements
     val Seq(w_erd, x_erd) = list_erd.childERDs
     val Seq(a_erd, b_erd, c_erd) = x_erd.childERDs
-    infoset.getChildArray(x_erd) match {
+    infoset.getChildArray(x_erd, tunable) match {
       case arr: DIArray => {
         assertEquals(2, arr.length)
         var xa = arr(1).asInstanceOf[InfosetComplexElement]
         assertEquals(x_erd, xa.runtimeData)
         assertTrue(xa.isNilled)
         xa = arr(2).asInstanceOf[InfosetComplexElement] // 1-based
-        val c = xa.getChild(c_erd)
+        val c = xa.getChild(c_erd, tunable)
         c match {
           case c: DISimple => assertEquals(7, c.dataValue)
         }
@@ -355,13 +355,13 @@ class TestInfoset1 {
 
     val xmlInfoset = <list xmlns={ ex }><x><c>7</c></x><x><b>8</b></x></list>
 
-    val (infoset: DIComplex, _) = testInfoset(testSchema, xmlInfoset)
+    val (infoset: DIComplex, _, tunable) = testInfoset(testSchema, xmlInfoset)
     val list_erd = infoset.erd
     val Seq(w_erd, x_erd) = list_erd.childERDs
     val Seq(a_erd, b_erd, c_erd) = x_erd.childERDs
 
     try {
-      infoset.getChildArray(w_erd)
+      infoset.getChildArray(w_erd, tunable)
       fail("Expected InfosetNoSuchChildElementException")
     } catch {
       case e: InfosetNoSuchChildElementException => /* w element is not in xmlInfoset */
@@ -369,17 +369,17 @@ class TestInfoset1 {
 
     assertTrue(infoset.isInstanceOf[DIComplex])
 
-    infoset.getChildArray(x_erd) match {
+    infoset.getChildArray(x_erd, tunable) match {
       case arr: DIArray => {
         assertEquals(2, arr.length)
         var xa = arr(1).asInstanceOf[InfosetComplexElement]
         assertEquals(x_erd, xa.runtimeData)
-        val c = xa.getChild(c_erd)
+        val c = xa.getChild(c_erd, tunable)
         c match {
           case c: DISimple => assertEquals(7, c.dataValue)
         }
         xa = arr(2).asInstanceOf[InfosetComplexElement]
-        val b = xa.getChild(b_erd)
+        val b = xa.getChild(b_erd, tunable)
         b match {
           case c: DISimple => assertEquals(8, c.dataValue)
         }
diff --git a/daffodil-core/src/test/scala/org/apache/daffodil/infoset/TestInfosetCursorFromReader.scala b/daffodil-core/src/test/scala/org/apache/daffodil/infoset/TestInfosetCursorFromReader.scala
index 1f6ae8e..2b7128f 100644
--- a/daffodil-core/src/test/scala/org/apache/daffodil/infoset/TestInfosetCursorFromReader.scala
+++ b/daffodil-core/src/test/scala/org/apache/daffodil/infoset/TestInfosetCursorFromReader.scala
@@ -58,7 +58,7 @@ class TestInfosetInputterFromReader {
     val inputter = new ScalaXMLInfosetInputter(infosetXML)
     inputter.initialize(rootERD, u.getTunables())
     val is = Adapter(inputter)
-    (is, rootERD, inputter)
+    (is, rootERD, inputter, u.tunable)
   }
 
   @Test def testUnparseFixedLengthString1() {
@@ -76,7 +76,7 @@ class TestInfosetInputterFromReader {
       <dfdl:format ref="tns:GeneralFormat"/>,
       <xs:element name="foo" dfdl:lengthKind="explicit" dfdl:length="5" type="xs:string"/>)
     val infosetXML = <foo xmlns={ XMLUtils.EXAMPLE_NAMESPACE }>Hello</foo>
-    val (ii, _, _) = infosetInputter(sch, infosetXML)
+    val (ii, _, _, _) = infosetInputter(sch, infosetXML)
     val is = ii.toStream.toList
     val List(Start(s: DISimple), End(e: DISimple)) = is
     assertTrue(s eq e) // exact same object
@@ -90,7 +90,7 @@ class TestInfosetInputterFromReader {
       <dfdl:format ref="tns:GeneralFormat"/>,
       <xs:element nillable="true" dfdl:nilValue="nil" dfdl:nilKind="literalValue" name="foo" dfdl:lengthKind="explicit" dfdl:length="3" type="xs:string"/>)
     val infosetXML = <foo xsi:nil="true" xmlns={ XMLUtils.EXAMPLE_NAMESPACE } xmlns:xsi={ XMLUtils.XSI_NAMESPACE }/>
-    val (ii, _, _) = infosetInputter(sch, infosetXML)
+    val (ii, _, _, _) = infosetInputter(sch, infosetXML)
     val is = ii.toStream.toList
     val List(Start(s: DISimple), End(e: DISimple)) = is
     assertTrue(s eq e) // exact same object
@@ -109,12 +109,13 @@ class TestInfosetInputterFromReader {
         </xs:complexType>
       </xs:element>)
     val infosetXML = <bar xmlns={ XMLUtils.EXAMPLE_NAMESPACE }><foo>Hello</foo></bar>
-    val (is, rootERD, inp) = infosetInputter(sch, infosetXML)
+    val (is, rootERD, inp, tunable) = infosetInputter(sch, infosetXML)
     val Seq(fooERD) = rootERD.childERDs
     val Start(bar_s: DIComplex) = is.next
+
     inp.pushTRD(fooERD)
     val Start(foo_s: DISimple) = is.next
-    bar_s.addChild(foo_s)
+    bar_s.addChild(foo_s, tunable)
     val End(foo_e: DISimple) = is.next
     val poppedERD = inp.popTRD()
     assertEquals(fooERD, poppedERD)
@@ -139,7 +140,7 @@ class TestInfosetInputterFromReader {
         </xs:complexType>
       </xs:element>)
     val infosetXML = <bar xmlns={ XMLUtils.EXAMPLE_NAMESPACE }><foo>Hello</foo><baz>World</baz></bar>
-    val (is, rootERD, inp) = infosetInputter(sch, infosetXML)
+    val (is, rootERD, inp, tunable) = infosetInputter(sch, infosetXML)
     val Start(bar_s: DIComplex) = is.next
     val Seq(fooERD, bazERD) = rootERD.childERDs
     inp.pushTRD(fooERD)
@@ -190,7 +191,7 @@ class TestInfosetInputterFromReader {
                        <bar1><foo1>Hello</foo1><baz1>World</baz1></bar1>
                        <bar2><foo2>Hello</foo2><baz2>World</baz2></bar2>
                      </quux>
-    val (is, rootERD, inp) = infosetInputter(sch, infosetXML)
+    val (is, rootERD, inp, tunable) = infosetInputter(sch, infosetXML)
     //
     // Get all the ERDs and Sequence TRDs
     //
@@ -273,7 +274,7 @@ class TestInfosetInputterFromReader {
         </xs:complexType>
       </xs:element>)
     val infosetXML = <bar xmlns={ XMLUtils.EXAMPLE_NAMESPACE }><foo>Hello</foo><foo>World</foo></bar>
-    val (is, rootERD, inp) = infosetInputter(sch, infosetXML)
+    val (is, rootERD, inp, tunable) = infosetInputter(sch, infosetXML)
     val Some(barSeqTRD: SequenceRuntimeData) = rootERD.optComplexTypeModelGroupRuntimeData
     val Seq(fooERD: ElementRuntimeData) = barSeqTRD.groupMembers
     val doc = inp.documentElement
@@ -283,10 +284,10 @@ class TestInfosetInputterFromReader {
     inp.pushTRD(fooERD)
     val StartArray(foo_arr_s) = is.next
     val Start(foo_1_s: DISimple) = is.next
-    bar_s.addChild(foo_1_s)
+    bar_s.addChild(foo_1_s, tunable)
     val End(foo_1_e: DISimple) = is.next
     val Start(foo_2_s: DISimple) = is.next
-    bar_s.addChild(foo_2_s)
+    bar_s.addChild(foo_2_s, tunable)
     val End(foo_2_e: DISimple) = is.next
     val EndArray(foo_arr_e) = is.next
     assertEquals(fooERD, inp.popTRD())
@@ -316,7 +317,7 @@ class TestInfosetInputterFromReader {
         </xs:complexType>
       </xs:element>)
     val infosetXML = <bar xmlns={ XMLUtils.EXAMPLE_NAMESPACE }><foo>Hello</foo><foo>World</foo><baz>Yadda</baz></bar>
-    val (is, rootERD, inp) = infosetInputter(sch, infosetXML)
+    val (is, rootERD, inp, tunable) = infosetInputter(sch, infosetXML)
     val Some(barSeqTRD: SequenceRuntimeData) = rootERD.optComplexTypeModelGroupRuntimeData
     val Seq(fooERD: ElementRuntimeData, bazERD: ElementRuntimeData) = barSeqTRD.groupMembers
     val Start(bar_s: DIComplex) = is.next
@@ -366,7 +367,7 @@ class TestInfosetInputterFromReader {
         </xs:complexType>
       </xs:element>)
     val infosetXML = <bar xmlns={ XMLUtils.EXAMPLE_NAMESPACE }><baz>Yadda</baz><foo>Hello</foo><foo>World</foo></bar>
-    val (is, rootERD, inp) = infosetInputter(sch, infosetXML)
+    val (is, rootERD, inp, tunable) = infosetInputter(sch, infosetXML)
     val Some(barSeqTRD: SequenceRuntimeData) = rootERD.optComplexTypeModelGroupRuntimeData
     val Seq(bazERD: ElementRuntimeData, fooERD: ElementRuntimeData) = barSeqTRD.groupMembers
 
@@ -416,7 +417,7 @@ class TestInfosetInputterFromReader {
         </xs:complexType>
       </xs:element>)
     val infosetXML = <bar xmlns={ XMLUtils.EXAMPLE_NAMESPACE }><baz>Yadda</baz><foo>Hello</foo><foo>World</foo></bar>
-    val (is, rootERD, inp) = infosetInputter(sch, infosetXML)
+    val (is, rootERD, inp, tunable) = infosetInputter(sch, infosetXML)
     val Some(barSeqTRD: SequenceRuntimeData) = rootERD.optComplexTypeModelGroupRuntimeData
     val Seq(bazERD: ElementRuntimeData, fooERD: ElementRuntimeData) = barSeqTRD.groupMembers
 
@@ -462,7 +463,7 @@ class TestInfosetInputterFromReader {
         </xs:complexType>
       </xs:element>)
     val infosetXML = <bar xmlns={ XMLUtils.EXAMPLE_NAMESPACE }><foo>Hello</foo></bar>
-    val (is, rootERD, inp) = infosetInputter(sch, infosetXML)
+    val (is, rootERD, inp, tunable) = infosetInputter(sch, infosetXML)
     val Some(barSeqTRD: SequenceRuntimeData) = rootERD.optComplexTypeModelGroupRuntimeData
     val Seq(fooERD: ElementRuntimeData) = barSeqTRD.groupMembers
 
@@ -508,7 +509,7 @@ class TestInfosetInputterFromReader {
         </xs:complexType>
       </xs:element>)
     val infosetXML = <e xmlns={ XMLUtils.EXAMPLE_NAMESPACE }><s><c1>Hello</c1></s><s><c2>World</c2></s></e>
-    val (is, eERD, inp) = infosetInputter(sch, infosetXML)
+    val (is, eERD, inp, tunable) = infosetInputter(sch, infosetXML)
     val Some(eSeqTRD: SequenceRuntimeData) = eERD.optComplexTypeModelGroupRuntimeData
     val Seq(sERD: ElementRuntimeData) = eSeqTRD.groupMembers
     val Some(sChoTRD: ChoiceRuntimeData) = sERD.optComplexTypeModelGroupRuntimeData
diff --git a/daffodil-lib/src/main/scala/org/apache/daffodil/externalvars/Binding.scala b/daffodil-lib/src/main/scala/org/apache/daffodil/externalvars/Binding.scala
index 41b8233..e782c5e 100644
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/externalvars/Binding.scala
+++ b/daffodil-lib/src/main/scala/org/apache/daffodil/externalvars/Binding.scala
@@ -20,6 +20,7 @@ package org.apache.daffodil.externalvars
 import scala.xml.Node
 import org.apache.daffodil.xml._
 import org.apache.daffodil.api.DaffodilTunables
+import org.apache.daffodil.api.UnqualifiedPathStepPolicy
 
 class Binding(val varQName: RefQName, val varValue: String, scope: scala.xml.NamespaceBinding = null) {
 
@@ -64,10 +65,10 @@ object Binding {
     case e: Throwable => throw BindingException(e.getMessage)
   }
 
-  def apply(node: Node, tunable: DaffodilTunables): Binding = {
+  def apply(node: Node, unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy): Binding = {
     val name = (node \ "@name").head.text
     val refQName = try {
-      QName.resolveRef(name, node.scope, tunable)
+      QName.resolveRef(name, node.scope, unqualifiedPathStepPolicy)
     } catch {
       case e: Throwable => throw BindingException(e.getMessage)
     }
@@ -81,10 +82,10 @@ object Binding {
     case e: Throwable => throw BindingException(e.getMessage)
   }
 
-  def getBindings(extVarBindings: Node, tunableArg: DaffodilTunables) = {
+  def getBindings(extVarBindings: Node, unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy) = {
     val bindings = extVarBindings \ "bind"
     try {
-      bindings.map(b => Binding(b, tunableArg))
+      bindings.map(b => Binding(b, unqualifiedPathStepPolicy))
     } catch {
       case e: Throwable => throw BindingException(e.getMessage)
     }
diff --git a/daffodil-lib/src/main/scala/org/apache/daffodil/util/Cursor.scala b/daffodil-lib/src/main/scala/org/apache/daffodil/util/Cursor.scala
index 28b30f3..c709b0d 100644
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/util/Cursor.scala
+++ b/daffodil-lib/src/main/scala/org/apache/daffodil/util/Cursor.scala
@@ -94,7 +94,7 @@ trait Cursor[AccessorType <: Accessor[AccessorType]] {
    * boolean indicates whether that happened successfully or there
    * was no more data.
    *
-   * This has no side-effects on the infoset. 
+   * This has no side-effects on the infoset.
    */
   def inspect: Boolean
 
@@ -123,7 +123,7 @@ trait CursorImplMixin[AccessorType <: Accessor[AccessorType]]
   extends Cursor[AccessorType] {
   /*
    * We are a bit of a state machine based on what the last operation was.
-   * At all times, we have a "current" element, which is what future calls to 
+   * At all times, we have a "current" element, which is what future calls to
    * advance/inspect provide information about.
    *
    * Our states our as follows:
diff --git a/daffodil-lib/src/main/scala/org/apache/daffodil/xml/QNameBase.scala b/daffodil-lib/src/main/scala/org/apache/daffodil/xml/QNameBase.scala
index d38db5e..2ff5828 100644
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/xml/QNameBase.scala
+++ b/daffodil-lib/src/main/scala/org/apache/daffodil/xml/QNameBase.scala
@@ -107,8 +107,9 @@ import org.apache.daffodil.exceptions.Assert
  */
 object QName {
 
-  def resolveRef(qnameString: String, scope: scala.xml.NamespaceBinding, tunable: DaffodilTunables): Try[RefQName] =
-    RefQNameFactory.resolveRef(qnameString, scope, tunable)
+  def resolveRef(qnameString: String, scope: scala.xml.NamespaceBinding,
+      unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy): Try[RefQName] =
+    RefQNameFactory.resolveRef(qnameString, scope, unqualifiedPathStepPolicy)
 
   /**
    * Specialized getQName function for handling
@@ -152,8 +153,9 @@ object QName {
     res
   }
 
-  def resolveStep(qnameString: String, scope: scala.xml.NamespaceBinding, tunable: DaffodilTunables): Try[StepQName] =
-    StepQNameFactory.resolveRef(qnameString, scope, tunable)
+  def resolveStep(qnameString: String, scope: scala.xml.NamespaceBinding,
+      unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy): Try[StepQName] =
+    StepQNameFactory.resolveRef(qnameString, scope, unqualifiedPathStepPolicy)
 
   def createLocal(name: String, targetNamespace: NS, isQualified: Boolean,
     scope: scala.xml.NamespaceBinding) = {
@@ -470,17 +472,19 @@ final case class StepQName(prefix: Option[String], local: String, namespace: NS)
 
 protected trait RefQNameFactoryBase[T] {
 
-  protected def resolveDefaultNamespace(scope: scala.xml.NamespaceBinding, tunable: DaffodilTunables): Option[String]
+  protected def resolveDefaultNamespace(scope: scala.xml.NamespaceBinding,
+      unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy): Option[String]
 
   protected def constructor(prefix: Option[String], local: String, namespace: NS): T
 
-  def resolveRef(qnameString: String, scope: scala.xml.NamespaceBinding, tunable: DaffodilTunables): Try[T] = Try {
+  def resolveRef(qnameString: String, scope: scala.xml.NamespaceBinding,
+      unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy): Try[T] = Try {
     qnameString match {
       case QNameRegex.QName(pre, local) => {
         val prefix = Option(pre)
         // note that the prefix, if defined, can never be ""
         val optURI = prefix match {
-          case None => resolveDefaultNamespace(scope, tunable)
+          case None => resolveDefaultNamespace(scope, unqualifiedPathStepPolicy)
           case Some(pre) => Option(scope.getURI(pre))
         }
         val ns = (prefix, optURI) match {
@@ -501,7 +505,9 @@ object RefQNameFactory extends RefQNameFactoryBase[RefQName] {
   override def constructor(prefix: Option[String], local: String, namespace: NS) =
     RefQName(prefix, local, namespace)
 
-  override def resolveDefaultNamespace(scope: scala.xml.NamespaceBinding, tunable: DaffodilTunables) =
+  override def resolveDefaultNamespace(
+      scope: scala.xml.NamespaceBinding,
+      unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy) =
     Option(scope.getURI(null)) // could be a default namespace
 }
 
@@ -511,8 +517,9 @@ object StepQNameFactory extends RefQNameFactoryBase[StepQName] {
     StepQName(prefix, local, namespace)
 
   /* This is what needs Tunables and propagates into Expression */
-  override def resolveDefaultNamespace(scope: scala.xml.NamespaceBinding, tunable: DaffodilTunables) = {
-    tunable.unqualifiedPathStepPolicy match {
+  override def resolveDefaultNamespace(scope: scala.xml.NamespaceBinding,
+      unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy) = {
+    unqualifiedPathStepPolicy match {
       case UnqualifiedPathStepPolicy.NoNamespace => None // don't consider default namespace
       case UnqualifiedPathStepPolicy.DefaultNamespace => Option(scope.getURI(null)) // could be a default namespace
       case UnqualifiedPathStepPolicy.PreferDefaultNamespace => Option(scope.getURI(null)) // could be a default namespace
diff --git a/daffodil-lib/src/main/scala/org/apache/daffodil/xml/QNames.scala b/daffodil-lib/src/main/scala/org/apache/daffodil/xml/QNames.scala
index 4c95055..f37e8bb 100644
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/xml/QNames.scala
+++ b/daffodil-lib/src/main/scala/org/apache/daffodil/xml/QNames.scala
@@ -20,6 +20,7 @@ package org.apache.daffodil.xml
 import org.apache.daffodil.api.DaffodilTunables
 import org.apache.daffodil.exceptions.Assert
 import org.apache.daffodil.exceptions.ThrowsSDE
+import org.apache.daffodil.api.UnqualifiedPathStepPolicy
 
 /**
  * Element references and Group References use this.
@@ -59,14 +60,15 @@ object ResolvesQNames {
 
 trait ResolvesQNames
   extends ThrowsSDE {
+
   def namespaces: scala.xml.NamespaceBinding
-  protected def tunable: DaffodilTunables
+  def unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy
 
   /**
    * If prefix of name is unmapped, SDE
    */
   def resolveQName(qnString: String): RefQName = {
-    val eQN = QName.resolveRef(qnString, namespaces, tunable)
+    val eQN = QName.resolveRef(qnString, namespaces, unqualifiedPathStepPolicy)
     // we don't want to just throw the exception, we want to
     // convert to an SDE, so we use recover
     val res = eQN.recover { ThrowSDE }.get
diff --git a/daffodil-lib/src/test/scala/org/apache/daffodil/schema/annotation/props/TestGeneratedProperties.scala b/daffodil-lib/src/test/scala/org/apache/daffodil/schema/annotation/props/TestGeneratedProperties.scala
index 19c2fa1..adc411e 100644
--- a/daffodil-lib/src/test/scala/org/apache/daffodil/schema/annotation/props/TestGeneratedProperties.scala
+++ b/daffodil-lib/src/test/scala/org/apache/daffodil/schema/annotation/props/TestGeneratedProperties.scala
@@ -57,7 +57,7 @@ class TestGeneratedProperties {
     val xml = bagOfProps
     lazy val fileName = "file:dummy"
     lazy val properties: PropMap = Map.empty
-    lazy val tunable = DaffodilTunables()
+    lazy val unqualifiedPathStepPolicy = DaffodilTunables().unqualifiedPathStepPolicy
 
     def SDE(id: String, args: Any*): Nothing = {
       throw new Exception(id.format(args: _*))
diff --git a/daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/TunableGenerator.scala b/daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/TunableGenerator.scala
index d5b94b8..929d10b 100644
--- a/daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/TunableGenerator.scala
+++ b/daffodil-propgen/src/main/scala/org/apache/daffodil/propGen/TunableGenerator.scala
@@ -127,8 +127,7 @@ class TunableGenerator(schemaRootConfig: scala.xml.Node, schemaRootExt: scala.xm
 
   val excludedSimpleTypes = Seq(
     "TunableEmptyElementParsePolicy",
-    "TunableSuppressSchemaDefinitionWarnings"
-  )
+    "TunableSuppressSchemaDefinitionWarnings")
   val tunableSimpleTypeNodes = (schemaRootConfig \ "simpleType")
     .filter { st => (st \@ "name").startsWith("Tunable") }
     .filter { st => !excludedSimpleTypes.contains(st \@ "name") }
@@ -190,7 +189,7 @@ class PrimitiveTunable(name: String, schemaType: String, schemaDefault: String)
 
   private val scalaType = schemaType match {
     case "xs:boolean" => "Boolean"
-    case "xs:int" =>  "Int"
+    case "xs:int" => "Int"
     case "xs:long" => "Long"
     case "xs:string" => "String"
   }
diff --git a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ElementUnparser.scala b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ElementUnparser.scala
index 8cd11e3..956cfd8 100644
--- a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ElementUnparser.scala
+++ b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ElementUnparser.scala
@@ -429,7 +429,7 @@ sealed trait RegularElementUnparserStartEndStrategy
                 c.erd.namedQName.toExtendedSyntax,
                 res.erd.namedQName.toExtendedSyntax)
             }
-            c.addChild(res)
+            c.addChild(res, state.tunable)
           } else {
             val doc = state.documentElement
             doc.addChild(res) // DIDocument, which is never a current node, must have the child added
@@ -441,7 +441,7 @@ sealed trait RegularElementUnparserStartEndStrategy
           // Since we never get events for hidden elements, their infoset elements
           // will have never been created. This means we need to manually create them
           val e = if (erd.isComplexType) new DIComplex(erd) else new DISimple(erd)
-          state.currentInfosetNode.asComplex.addChild(e)
+          state.currentInfosetNode.asComplex.addChild(e, state.tunable)
           e
         }
 
@@ -511,7 +511,7 @@ trait OVCStartEndStrategy
           Assert.invariant(endEv.isEnd && endEv.erd == erd)
 
           val e = new DISimple(erd)
-          state.currentInfosetNode.asComplex.addChild(e)
+          state.currentInfosetNode.asComplex.addChild(e, state.tunable)
           // Remove any state that was set by what created this event. Later
           // code asserts that OVC elements do not have a value
           e.resetValue
@@ -519,13 +519,13 @@ trait OVCStartEndStrategy
         } else {
           // Event was optional and didn't exist, create a new InfosetElement and add it
           val e = new DISimple(erd)
-          state.currentInfosetNode.asComplex.addChild(e)
+          state.currentInfosetNode.asComplex.addChild(e, state.tunable)
           e
         }
       } else {
         // Event was hidden and will never exist, create a new InfosetElement and add it
         val e = new DISimple(erd)
-        state.currentInfosetNode.asComplex.addChild(e)
+        state.currentInfosetNode.asComplex.addChild(e, state.tunable)
         e
       }
 
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/BasicComponent.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/BasicComponent.scala
new file mode 100644
index 0000000..40e155c
--- /dev/null
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/BasicComponent.scala
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.daffodil
+
+import org.apache.daffodil.xml.ResolvesQNames
+import org.apache.daffodil.oolag.OOLAG.OOLAGHost
+import org.apache.daffodil.processors.HasTunable
+import org.apache.daffodil.dsom.ImplementsThrowsOrSavesSDE
+
+/**
+ * Base trait shared by all component families in Daffodil
+ * including schema components, expression components,
+ * grammar subsystem components (e.g, Combinators), etc.
+ *
+ * Common to them is OOLAG, and availablility of Daffodil's
+ * tunables, and the ability to resolve QNames
+ */
+trait BasicComponent
+  extends OOLAGHost
+  with HasTunable
+  with ResolvesQNames
+  with ImplementsThrowsOrSavesSDE {
+
+}
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/debugger/InteractiveDebugger.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/debugger/InteractiveDebugger.scala
index 24a6954..750ed36 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/debugger/InteractiveDebugger.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/debugger/InteractiveDebugger.scala
@@ -51,6 +51,8 @@ import org.apache.daffodil.infoset.XMLTextInfosetOutputter
 import org.apache.daffodil.processors.parsers.ConvertTextCombinatorParser
 import org.apache.daffodil.oolag.OOLAG._
 import scala.collection.JavaConverters._
+import org.apache.daffodil.api.DaffodilTunables
+import org.apache.daffodil.BasicComponent
 
 abstract class InteractiveDebuggerRunner {
   def init(id: InteractiveDebugger): Unit
@@ -301,7 +303,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
       // compile the expression
       //
       val compiledExpr = try {
-        val hostForDiags = new DebuggerHost()
+        val hostForDiags = new DebuggerHost(state.tunable)
         val ce = eCompilers.JBoolean.compileExpression(
           debuggerQName,
           NodeInfo.Boolean, expression, processor.context.namespaces, context.dpathCompileInfo, false,
@@ -1047,7 +1049,7 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
           else adjustedExpression
         val isEvaluatedAbove = false
         try {
-          val hostForDiags = new DebuggerHost()
+          val hostForDiags = new DebuggerHost(state.tunable)
           val compiledExpression = eCompilers.AnyRef.compileExpression(
             debuggerQName,
             NodeInfo.AnyType, expressionWithBraces, namespaces, context.dpathCompileInfo,
@@ -1817,4 +1819,17 @@ class InteractiveDebugger(runner: InteractiveDebuggerRunner, eCompilers: Express
  * A stub OOLAGHost is needed to accumulate warnings that may be created
  * during expression compilation in the debugger.
  */
-class DebuggerHost extends OOLAGHostImpl(null) // null means this is the root OOLAG Host
+class DebuggerHost(override val tunable: DaffodilTunables)
+  extends OOLAGHostImpl(null) // null means this is the root OOLAG Host
+  with BasicComponent {
+
+  /**
+   * As seen from class DebuggerHost, the missing signatures are as follows.
+   *  *  For convenience, these are usable as stub implementations.
+   */
+  // Members declared in org.apache.daffodil.xml.ResolvesQNames
+  def namespaces: scala.xml.NamespaceBinding = ???
+  def unqualifiedPathStepPolicy: org.apache.daffodil.api.UnqualifiedPathStepPolicy = ???
+  // Members declared in org.apache.daffodil.exceptions.ThrowsSDE
+  def schemaFileLocation: org.apache.daffodil.exceptions.SchemaFileLocation = ???
+}
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLXFunctions.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLXFunctions.scala
index 51d2ace..f389744 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLXFunctions.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLXFunctions.scala
@@ -95,7 +95,7 @@ case class DFDLXLookAhead(recipes: List[CompiledDPath])
     Assert.invariant(lBitSize >= 0)
 
     val totalLookahead = offset + lBitSize
-    val maxLookahead = dstate.compileInfo.tunable.maxLookaheadFunctionBits
+    val maxLookahead = dstate.tunable.maxLookaheadFunctionBits
     if (totalLookahead > maxLookahead) {
       dstate.SDE("Look-ahead distance of %s bits exceeds implementation defined limit of %s bits", totalLookahead, maxLookahead)
     }
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DPathRuntime.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DPathRuntime.scala
index 362ea6a..e98f9bc 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DPathRuntime.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DPathRuntime.scala
@@ -38,6 +38,7 @@ import org.apache.daffodil.dpath.NodeInfo.PrimType
 import org.apache.daffodil.dsom.DPathCompileInfo
 import org.apache.daffodil.xml.GlobalQName
 import org.apache.daffodil.processors.TypeCalculator
+import org.apache.daffodil.api.DaffodilTunables
 
 class CompiledDPath(val ops: RecipeOp*) extends Serializable {
 
@@ -75,14 +76,15 @@ class CompiledDPath(val ops: RecipeOp*) extends Serializable {
    * so that part of an expression can be constant, not necessarily the whole thing.
    */
   def runExpressionForConstant(
-      sfl: SchemaFileLocation, 
-      compileInfo: DPathCompileInfo ): Option[AnyRef] = {
+    sfl: SchemaFileLocation,
+    compileInfo: DPathCompileInfo,
+    tunable: DaffodilTunables): Option[AnyRef] = {
 
     //
     // we use a special dummy dstate here that errors out via throw
     // if the evaluation tries to get a processor state or node.
     //
-    val dstate = new DStateForConstantFolding(compileInfo)
+    val dstate = new DStateForConstantFolding(compileInfo, tunable)
     val isConstant: Boolean =
       try {
         run(dstate)
@@ -159,7 +161,7 @@ abstract class RecipeOp
    * there are children to display.
    */
   def toXML: scala.xml.Node = toXML(scala.xml.NodeSeq.Empty)
-  
+
 }
 
 abstract class RecipeOpWithSubRecipes(recipes: List[CompiledDPath]) extends RecipeOp {
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DState.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DState.scala
index 9e10ec1..424aa10 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DState.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DState.scala
@@ -29,6 +29,7 @@ import org.apache.daffodil.api.WarnID
 import org.apache.daffodil.dsom.DPathCompileInfo
 import org.apache.daffodil.xml.GlobalQName
 import org.apache.daffodil.processors.TypeCalculatorCompiler.TypeCalcMap
+import org.apache.daffodil.api.DaffodilTunables
 
 /**
  * Modes for expression evaluation.
@@ -98,7 +99,9 @@ case object UnparserNonBlocking extends EvalMode
  * if used in a forward referencing expression the expression can block until the information
  * becomes available.
  */
-case class DState(val maybeSsrd: Maybe[SchemaSetRuntimeData]) {
+case class DState(
+  val maybeSsrd: Maybe[SchemaSetRuntimeData],
+  tunable: DaffodilTunables) {
   import org.apache.daffodil.util.Numbers._
 
   var isCompile = false
@@ -439,7 +442,8 @@ object DState {
 }
 
 class DStateForConstantFolding(
-  override val compileInfo: DPathCompileInfo) extends DState(Nope) {
+  override val compileInfo: DPathCompileInfo,
+  tunable: DaffodilTunables) extends DState(Nope, tunable) {
   private def die = throw new java.lang.IllegalStateException("No infoset at compile time.")
 
   override def currentSimple = currentNode.asInstanceOf[DISimple]
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/UpDownMoves.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/UpDownMoves.scala
index 032dce9..916a6b1 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/UpDownMoves.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/UpDownMoves.scala
@@ -69,7 +69,7 @@ case class DownElement(nqn: NamedQName) extends RecipeOp {
     val now = dstate.currentComplex
     // TODO PE ? if doesn't exist should be a processing error.
     // It will throw and so will be a PE, but may be poor diagnostic.
-    val c = dstate.withRetryIfBlocking(now.getChild(nqn))
+    val c = dstate.withRetryIfBlocking(now.getChild(nqn, dstate.tunable))
     dstate.setCurrentNode(c.asInstanceOf[DIElement])
   }
 
@@ -95,8 +95,9 @@ case class DownArrayOccurrence(nqn: NamedQName, indexRecipe: CompiledDPath)
     // necessary since one of the following functions could throw, leaving the
     // current node to null. And future calls depend on a current node to be set
     dstate.setCurrentNode(savedCurrentElement)
-    val childArrayElementERD = dstate.withRetryIfBlocking(savedCurrentElement.getChildArray(nqn).asInstanceOf[DIArray].erd)
-    val arr = dstate.withRetryIfBlocking(savedCurrentElement.getChildArray(childArrayElementERD))
+    val childArrayElementERD = 
+      dstate.withRetryIfBlocking(savedCurrentElement.getChildArray(nqn, dstate.tunable).asInstanceOf[DIArray].erd)
+    val arr = dstate.withRetryIfBlocking(savedCurrentElement.getChildArray(childArrayElementERD, dstate.tunable))
     val occurrence = dstate.withRetryIfBlocking(arr.getOccurrence(index)) // will throw on out of bounds
     dstate.setCurrentNode(occurrence.asInstanceOf[DIElement])
   }
@@ -114,7 +115,7 @@ case class DownArray(nqn: NamedQName) extends RecipeOp {
 
   override def run(dstate: DState) {
     val now = dstate.currentComplex
-    val arr = dstate.withRetryIfBlocking(now.getChildArray(nqn))
+    val arr = dstate.withRetryIfBlocking(now.getChildArray(nqn, dstate.tunable))
     Assert.invariant(arr ne null)
     dstate.setCurrentNode(arr.asInstanceOf[DIArray])
   }
@@ -129,7 +130,7 @@ case class DownArrayExists(nqn: NamedQName) extends RecipeOp {
 
   override def run(dstate: DState) {
     val now = dstate.currentComplex
-    val arr = dstate.withRetryIfBlocking(now.getChildArray(nqn))
+    val arr = dstate.withRetryIfBlocking(now.getChildArray(nqn, dstate.tunable))
 
     if ((arr eq null) || arr.length == 0)
       throw new InfosetNoSuchChildElementException(now, nqn)
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dsom/CompiledExpression1.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dsom/CompiledExpression1.scala
index 97bdb2b..ac0fba1 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dsom/CompiledExpression1.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dsom/CompiledExpression1.scala
@@ -205,7 +205,7 @@ class DPathCompileInfo(
   val namespaces: scala.xml.NamespaceBinding,
   val path: String,
   override val schemaFileLocation: SchemaFileLocation,
-  val tunable: DaffodilTunables,
+  val unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy,
   @TransientParam typeCalcMapArg: => TypeCalcMap,
   val lexicalContextRuntimeData: RuntimeData)
   extends ImplementsThrowsSDE with PreSerialization
@@ -289,11 +289,13 @@ class DPathElementCompileInfo(
   val namedQName: NamedQName,
   val optPrimType: Option[PrimType],
   sfl: SchemaFileLocation,
-  override val tunable: DaffodilTunables,
+  override val unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy,
   typeCalcMap: TypeCalcMap,
   lexicalContextRuntimeData: RuntimeData,
   val sscd: String)
-  extends DPathCompileInfo(parentsArg, variableMap, namespaces, path, sfl, tunable, typeCalcMap, lexicalContextRuntimeData) {
+  extends DPathCompileInfo(parentsArg, variableMap, namespaces, path, sfl,
+    unqualifiedPathStepPolicy,
+    typeCalcMap, lexicalContextRuntimeData) {
 
   lazy val elementChildrenCompileInfo = elementChildrenCompileInfoArg
 
@@ -376,7 +378,7 @@ class DPathElementCompileInfo(
 
     val retryMatchesERD =
       if (matchesERD.isEmpty &&
-        tunable.unqualifiedPathStepPolicy == UnqualifiedPathStepPolicy.PreferDefaultNamespace &&
+        unqualifiedPathStepPolicy == UnqualifiedPathStepPolicy.PreferDefaultNamespace &&
         step.prefix.isEmpty && step.namespace != NoNamespace) {
         // we failed to find a match with the default namespace. Since the
         // default namespace was assumed but didn't match, the unqualified path
@@ -399,7 +401,7 @@ class DPathElementCompileInfo(
     val matchesERD = step.findMatches(possibles)
     val retryMatchesERD =
       if (matchesERD.isEmpty &&
-        tunable.unqualifiedPathStepPolicy == UnqualifiedPathStepPolicy.PreferDefaultNamespace &&
+        unqualifiedPathStepPolicy == UnqualifiedPathStepPolicy.PreferDefaultNamespace &&
         step.prefix.isEmpty && step.namespace != NoNamespace) {
         // we failed to find a match with the default namespace. Since the
         // default namespace was assumed but didn't match, the unqualified path
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dsom/ExpressionCompiler.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dsom/ExpressionCompiler.scala
index 410690a..beab2d0 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dsom/ExpressionCompiler.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dsom/ExpressionCompiler.scala
@@ -23,13 +23,14 @@ import scala.xml.NamespaceBinding
 import java.lang.{ Long => JLong, Boolean => JBoolean }
 import org.apache.daffodil.oolag.OOLAG._
 import org.apache.daffodil.processors.TypeCalculatorCompiler.TypeCalcMap
+import org.apache.daffodil.BasicComponent
 
 trait ExpressionCompilerBase[T <: AnyRef] {
 
   def compileExpression(qn: NamedQName, nodeInfoKind: NodeInfo.Kind, exprWithBracesMaybe: String, namespaces: NamespaceBinding,
     compileInfoWherePropertyWasLocated: DPathCompileInfo,
     isEvaluatedAbove: Boolean,
-    host: OOLAGHost,
+    host: BasicComponent,
     compileInfo: DPathCompileInfo): CompiledExpression[T]
 }
 
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/externalvars/ExternalVariablesLoader.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/externalvars/ExternalVariablesLoader.scala
index c138d48..81d6e0f 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/externalvars/ExternalVariablesLoader.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/externalvars/ExternalVariablesLoader.scala
@@ -28,6 +28,7 @@ import org.apache.daffodil.exceptions.Assert
 import org.apache.daffodil.util.Misc._
 import org.apache.daffodil.exceptions.ThrowsSDE
 import org.apache.daffodil.api.DaffodilTunables
+import org.apache.daffodil.api.UnqualifiedPathStepPolicy
 
 /**
  * The purpose of this object is to be able to take
@@ -57,11 +58,12 @@ object ExternalVariablesLoader {
     bindings
   }
 
-  def getVariables(node: Node, tunableArg: DaffodilTunables): Seq[Binding] = Binding.getBindings(node, tunableArg)
+  def getVariables(node: Node): Seq[Binding] =
+    Binding.getBindings(node, UnqualifiedPathStepPolicy.DefaultNamespace)
 
-  def getVariables(varsFile: File, tunableArg: DaffodilTunables): Seq[Binding] = {
+  def getVariables(varsFile: File): Seq[Binding] = {
     val node = getVariablesAsNode(varsFile)
-    val bindings = Binding.getBindings(node, tunableArg)
+    val bindings = Binding.getBindings(node, UnqualifiedPathStepPolicy.DefaultNamespace)
     bindings
   }
 
@@ -121,7 +123,7 @@ object ExternalVariablesLoader {
     Assert.usage(node != null, "loadVariables expects 'node' to not be null!")
     Assert.usage(referringContext != null, "loadVariables expects 'referringContext' to not be null!")
     val bindings = try {
-      Binding.getBindings(node, tunableArg)
+      Binding.getBindings(node, tunableArg.unqualifiedPathStepPolicy)
     } catch {
       case e: Throwable => referringContext.SDE("Exception when processing external variable binding file: %s", e.getMessage)
     }
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/Infoset.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/Infoset.scala
index af304cd..099c06a 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/Infoset.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/Infoset.scala
@@ -22,6 +22,7 @@ import org.apache.daffodil.xml.NS
 import org.apache.daffodil.util.MaybeBoolean
 import org.apache.daffodil.util.Maybe
 import org.apache.daffodil.processors.ElementRuntimeData
+import org.apache.daffodil.api.DaffodilTunables
 
 object INoWarn2 { ImplicitsSuppressUnusedImportWarning() }
 
@@ -64,8 +65,8 @@ trait InfosetElement extends InfosetItem {
 
 trait InfosetComplexElement extends InfosetElement {
 
-  def getChild(erd: ElementRuntimeData): InfosetElement
-  def getChildArray(erd: ElementRuntimeData): InfosetArray
+  def getChild(erd: ElementRuntimeData, tunable: DaffodilTunables): InfosetElement
+  def getChildArray(erd: ElementRuntimeData, tunable: DaffodilTunables): InfosetArray
 
   /**
    * Determines slotInParent from the ERD of the infoset element arg.
@@ -73,7 +74,7 @@ trait InfosetComplexElement extends InfosetElement {
    *
    * When slot contains an array, this appends to the end of the array.
    */
-  def addChild(e: InfosetElement): Unit
+  def addChild(e: InfosetElement, tunable: DaffodilTunables): Unit
 
 }
 
@@ -91,7 +92,7 @@ trait InfosetSimpleElement extends InfosetElement {
 
 trait InfosetDocument extends InfosetItem {
   def getRootElement(): InfosetElement
-  def setRootElement(root: InfosetElement): Unit
+  def setRootElement(root: InfosetElement, tunable: DaffodilTunables): Unit
 }
 
 trait InfosetItem extends InfosetCommon {
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetImpl.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetImpl.scala
index 12ff7cf..23d0194 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetImpl.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetImpl.scala
@@ -830,7 +830,7 @@ sealed trait DIElement
 
   def valueStringForDebug: String
 
-  def isRoot = parent match {
+  def isRoot = toParent match {
     case doc: DIDocument => !doc.isCompileExprFalseRoot
     case _ => false
   }
@@ -840,20 +840,9 @@ sealed trait DIElement
     case _ => false
   }
 
-  def toRootDoc: DIDocument = toRootDoc1(this)
-
-  private def toRootDoc1(orig: DIElement): DIDocument = {
+  final def toRootDoc: DIDocument = {
     if (isRootDoc) this.asInstanceOf[DIDocument]
-    else if (isRoot) diParent.asInstanceOf[DIDocument]
-    else {
-      parent match {
-        case null =>
-          orig.erd.toss(new InfosetNoRootException(orig, erd))
-        case elt: DIElement => elt.toRootDoc1(orig)
-        case _ =>
-          orig.erd.toss(new InfosetNoRootException(orig, erd))
-      }
-    }
+    else toParent.toRootDoc
   }
 
   def toParent = {
@@ -939,7 +928,15 @@ sealed trait DIElement
 //
 final class DIArray(
   override val erd: ElementRuntimeData,
-  val parent: DIComplex)
+  val parent: DIComplex,
+  initialSize: Int //TODO: really this needs to be adaptive, and resize upwards reasonably.
+//A non-copying thing - list like, may be better, but we do need access to be
+//constant time.
+// FIXME: for streaming behavior, arrays are going to get elements removed from
+// them when no longer needed. However, the array itself would still be growing
+// without bound. So, replace this with a mutable map so that it can shrink
+// as well as grow. // not saved. Needed only to get initial size.
+)
   extends DINode with InfosetArray
   with DIFinalizable {
 
@@ -972,14 +969,6 @@ final class DIArray(
 
   def namedQName = erd.namedQName
 
-  private val initialSize = parent.tunable.initialElementOccurrencesHint.toInt
-  //TODO: really this needs to be adaptive, and resize upwards reasonably.
-  //A non-copying thing - list like, may be better, but we do need access to be
-  //constant time.
-  // FIXME: for streaming behavior, arrays are going to get elements removed from
-  // them when no longer needed. However, the array itself would still be growing
-  // without bound. So, replace this with a mutable map so that it can shrink
-  // as well as grow.
   protected final val _contents = new ArrayBuffer[DIElement](initialSize)
 
   override def children = _contents.toStream.asInstanceOf[Stream[DINode]]
@@ -1356,8 +1345,6 @@ sealed class DIComplex(override val erd: ElementRuntimeData)
   with DIFinalizable // with HasModelGroupMixin
   { diComplex =>
 
-  def tunable: DaffodilTunables = toRootDoc.tunable
-
   final override def isSimple = false
   final override def isComplex = true
 
@@ -1405,8 +1392,8 @@ sealed class DIComplex(override val erd: ElementRuntimeData)
 
   var hasVisibleChildren = false
 
-  final def getChild(erd: ElementRuntimeData): InfosetElement = {
-    getChild(erd.dpathElementCompileInfo.namedQName)
+  final def getChild(erd: ElementRuntimeData, tunable: DaffodilTunables): InfosetElement = {
+    getChild(erd.dpathElementCompileInfo.namedQName, tunable)
   }
 
   private def noQuerySupportCheck(nodes: Seq[DINode], nqn: NamedQName) = {
@@ -1424,22 +1411,22 @@ sealed class DIComplex(override val erd: ElementRuntimeData)
     }
   }
 
-  final def getChild(nqn: NamedQName): InfosetElement = {
-    val maybeNode = findChild(nqn)
+  final def getChild(nqn: NamedQName, tunable: DaffodilTunables): InfosetElement = {
+    val maybeNode = findChild(nqn, tunable)
     if (maybeNode.isDefined)
       maybeNode.get.asInstanceOf[InfosetElement]
     else
       erd.toss(new InfosetNoSuchChildElementException(this, nqn))
   }
 
-  final def getChildArray(childERD: ElementRuntimeData): InfosetArray = {
+  final def getChildArray(childERD: ElementRuntimeData, tunable: DaffodilTunables): InfosetArray = {
     Assert.usage(childERD.isArray)
 
-    getChildArray(childERD.dpathElementCompileInfo.namedQName)
+    getChildArray(childERD.dpathElementCompileInfo.namedQName, tunable)
   }
 
-  final def getChildArray(nqn: NamedQName): InfosetArray = {
-    val maybeNode = findChild(nqn)
+  final def getChildArray(nqn: NamedQName, tunable: DaffodilTunables): InfosetArray = {
+    val maybeNode = findChild(nqn, tunable)
     if (maybeNode.isDefined) {
       maybeNode.get.asInstanceOf[InfosetArray]
     } else {
@@ -1497,14 +1484,14 @@ sealed class DIComplex(override val erd: ElementRuntimeData)
     childNodes ++= unordered.sortBy(_.erd.position)
   }
 
-  override def addChild(e: InfosetElement): Unit = {
+  override def addChild(e: InfosetElement, tunable: DaffodilTunables): Unit = {
     if (!e.isHidden && !hasVisibleChildren) hasVisibleChildren = true
     if (e.runtimeData.isArray) {
       val childERD = e.runtimeData
       if (childNodes.isEmpty || childNodes.last.erd != childERD) {
         // no children, or last child is not a DIArray for
         // this element, create the DIArray
-        val ia = new DIArray(childERD, this)
+        val ia = new DIArray(childERD, this, tunable.initialElementOccurrencesHint.toInt)
         if (childERD.dpathElementCompileInfo.isReferencedByExpressions) {
           addChildToFastLookup(ia)
         }
@@ -1555,7 +1542,7 @@ sealed class DIComplex(override val erd: ElementRuntimeData)
     }
   }
 
-  def findChild(qname: NamedQName): Maybe[DINode] = {
+  def findChild(qname: NamedQName, tunable: DaffodilTunables): Maybe[DINode] = {
     val fastSeq = nameToChildNodeLookup.get(qname)
     if (fastSeq != null) {
       // Daffodil does not support query expressions yet, so there should only
@@ -1643,8 +1630,7 @@ sealed class DIComplex(override val erd: ElementRuntimeData)
  * conditions having to do with the document root element.
  */
 final class DIDocument(
-  erd: ElementRuntimeData,
-  override val tunable: DaffodilTunables)
+  erd: ElementRuntimeData)
   extends DIComplex(erd)
   with InfosetDocument {
   var root: DIElement = null
@@ -1656,12 +1642,15 @@ final class DIDocument(
    */
   var isCompileExprFalseRoot: Boolean = false
 
-  def setRootElement(rootElement: InfosetElement) {
+  def setRootElement(rootElement: InfosetElement, tunable: DaffodilTunables) {
     root = rootElement.asInstanceOf[DIElement]
-    addChild(root)
+    addChild(root, tunable)
   }
 
-  override def addChild(child: InfosetElement) {
+  override def addChild(child: InfosetElement, tunable: DaffodilTunables) =
+    addChild(child)
+
+  def addChild(child: InfosetElement) {
     /*
      * DIDocument normally only has a single child.
      * However, if said child wants to create a quasi-element (eg. if it is a simpleType with a typeCalc),
@@ -1699,13 +1688,13 @@ object Infoset {
     else new DIComplex(erd)
   }
 
-  def newDocument(erd: ElementRuntimeData, tunable: DaffodilTunables): InfosetDocument = {
-    new DIDocument(erd, tunable)
+  def newDocument(erd: ElementRuntimeData): InfosetDocument = {
+    new DIDocument(erd)
   }
 
   def newDocument(root: InfosetElement, tunable: DaffodilTunables): InfosetDocument = {
-    val doc = newDocument(root.runtimeData, tunable)
-    doc.setRootElement(root)
+    val doc = newDocument(root.runtimeData)
+    doc.setRootElement(root, tunable)
     doc
   }
 
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetInputter.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetInputter.scala
index 1a538b2..e026a56 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetInputter.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetInputter.scala
@@ -171,7 +171,7 @@ abstract class InfosetInputter
     tunable = tunableArg
     isInitialized_ = true
 
-    documentElement_ = new DIDocument(rootElementInfo, tunable)
+    documentElement_ = new DIDocument(rootElementInfo)
     infoStack.push(documentElement_)
 
     try {
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/DataProcessor.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/DataProcessor.scala
index 9682e61..3d96f7a 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/DataProcessor.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/DataProcessor.scala
@@ -80,8 +80,10 @@ class InvalidUsageException(msg: String, cause: Throwable = null) extends Except
 /**
  * This is the DataProcessor constructed from a saved Parser.
  */
-class SerializableDataProcessor(val data: SchemaSetRuntimeData)
-  extends DataProcessor(data) {
+class SerializableDataProcessor(
+  val data: SchemaSetRuntimeData,
+  tunable: DaffodilTunables)
+  extends DataProcessor(data, tunable) {
   override def setValidationMode(mode: ValidationMode.Type): Unit = {
     if (mode == ValidationMode.Full) { throw new InvalidUsageException("'Full' validation not allowed when using a restored parser.") }
     super.setValidationMode(mode)
@@ -92,12 +94,15 @@ class SerializableDataProcessor(val data: SchemaSetRuntimeData)
  * The very last aspects of compilation, and the start of the
  * back-end runtime.
  */
-class DataProcessor(val ssrd: SchemaSetRuntimeData)
+class DataProcessor(
+  val ssrd: SchemaSetRuntimeData,
+  protected var tunablesObj: DaffodilTunables // Compiler-set tunables
+)
   extends DFDL.DataProcessor with Logging
   with HasSetDebugger with Serializable
   with MultipleEventHandler {
 
-  protected var tunablesObj = ssrd.tunable // Compiler-set tunables
+  def tunable = getTunables
 
   // This thread local state is used by the PState when it needs buffers for
   // regex matching. This cannot be in PState because a PState does not last
@@ -163,7 +168,6 @@ class DataProcessor(val ssrd: SchemaSetRuntimeData)
 
   def setTunable(tunable: String, value: String): Unit = tunablesObj = tunablesObj.setTunable(tunable, value)
   def setTunables(tunables: Map[String, String]): Unit = tunablesObj = tunablesObj.setTunables(tunables)
-  def resetTunables(): Unit = tunablesObj = ssrd.tunable // Compiler-set values
 
   override def isError = false // really there is no compiling at all currently, so there can be no errors.
 
@@ -171,7 +175,7 @@ class DataProcessor(val ssrd: SchemaSetRuntimeData)
 
   def save(output: DFDL.Output): Unit = {
     val oos = new ObjectOutputStream(new GZIPOutputStream(Channels.newOutputStream(output)))
-    oos.writeObject(new SerializableDataProcessor(ssrd))
+    oos.writeObject(new SerializableDataProcessor(ssrd, tunablesObj))
     oos.close()
   }
 
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/Evaluatable.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/Evaluatable.scala
index 6206048..bbaf6ed 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/Evaluatable.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/Evaluatable.scala
@@ -38,6 +38,7 @@ import org.apache.daffodil.dsom.ContentValueReferencedElementInfoMixin
 import org.apache.daffodil.infoset._
 import org.apache.daffodil.processors.parsers.DoSDEMixin
 import org.apache.daffodil.processors.parsers.PState
+import org.apache.daffodil.api.DaffodilTunables
 
 /**
  * Generates unique int for use as key into EvalCache
@@ -305,8 +306,8 @@ abstract class Evaluatable[+T <: AnyRef](protected val rd: RuntimeData, qNameArg
     y
   }
 
-  final def compile(): Maybe[T] = {
-    val compState = new CompileState(rd, Nope)
+  final def compile(tunable: DaffodilTunables): Maybe[T] = {
+    val compState = new CompileState(rd, Nope, tunable)
     compile(compState)
   }
 
@@ -503,4 +504,3 @@ abstract class EvaluatableConvertedExpression[ExprType <: AnyRef, +ConvertedType
   rd: RuntimeData)
   extends Evaluatable[ConvertedType](rd)
   with EvaluatableConvertedExpressionMixin[ExprType, ConvertedType]
-
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/ProcessorStateBases.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/ProcessorStateBases.scala
index 4acf128..7133044 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/ProcessorStateBases.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/ProcessorStateBases.scala
@@ -112,6 +112,10 @@ trait SetProcessorMixin {
     maybeProcessor_ = mp
   }
 }
+
+trait HasTunable {
+  def tunable: DaffodilTunables
+}
 /**
  * A parser takes a state, and returns an updated state
  *
@@ -127,7 +131,7 @@ abstract class ParseOrUnparseState protected (
   protected var variableBox: VariableBox,
   var diagnostics: List[Diagnostic],
   var dataProc: Maybe[DataProcessor],
-  val tunable: DaffodilTunables) extends DFDL.State
+  override val tunable: DaffodilTunables) extends DFDL.State
   with StateForDebugger
   with ThrowsSDE
   with SavesErrorsAndWarnings
@@ -135,7 +139,8 @@ abstract class ParseOrUnparseState protected (
   with EncoderDecoderMixin
   with Logging
   with FormatInfo
-  with SetProcessorMixin {
+  with SetProcessorMixin
+  with HasTunable {
 
   def this(vmap: VariableMap, diags: List[Diagnostic], dataProc: Maybe[DataProcessor], tunable: DaffodilTunables) =
     this(new VariableBox(vmap), diags, dataProc, tunable)
@@ -406,7 +411,7 @@ abstract class ParseOrUnparseState protected (
 
   private val maybeSsrd = if (dataProc.isDefined) { One(dataProc.get.ssrd) } else Maybe.Nope
 
-  private val _dState = new DState(maybeSsrd)
+  private val _dState = new DState(maybeSsrd, tunable)
 
   /**
    * Used when evaluating expressions. Holds state of expression
@@ -539,8 +544,8 @@ abstract class ParseOrUnparseState protected (
  *  inconsistent with constant-value are attempted to be extracted from the state. By "blow up" it throws
  *  a structured set of exceptions, typically children of InfosetException or VariableException.
  */
-final class CompileState(trd: RuntimeData, maybeDataProc: Maybe[DataProcessor])
-  extends ParseOrUnparseState(trd.variableMap, Nil, maybeDataProc, tunable = trd.tunable) {
+final class CompileState(trd: RuntimeData, maybeDataProc: Maybe[DataProcessor], tunable: DaffodilTunables)
+  extends ParseOrUnparseState(trd.variableMap, Nil, maybeDataProc, tunable) {
 
   def arrayPos: Long = 1L
   def bitLimit0b: MaybeULong = MaybeULong.Nope
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/RuntimeData.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/RuntimeData.scala
index 1b03abb..b3e8522 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/RuntimeData.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/RuntimeData.scala
@@ -59,6 +59,7 @@ import org.apache.daffodil.schema.annotation.props.gen.OccursCountKind
 import org.apache.daffodil.xml.NamedQName
 import org.apache.daffodil.processors.unparsers.UnparseError
 import org.apache.daffodil.util.Misc
+import org.apache.daffodil.api.UnqualifiedPathStepPolicy
 
 /*
  * NOTE: Any time you add a member to one of these objects, you must modify at least 3 places.
@@ -83,7 +84,7 @@ sealed trait RuntimeData
   def variableMap: VariableMap
   override def toString = diagnosticDebugName
 
-  def tunable: DaffodilTunables
+  def unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy
 
 }
 
@@ -147,7 +148,7 @@ sealed abstract class TermRuntimeData(
    * expressions at runtime (in the debugger, which is part of the runtime;
    * hence, need this info at runtime.)
    */
-  def tunable = dpathCompileInfo.tunable
+  def unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy = dpathCompileInfo.unqualifiedPathStepPolicy
 
   lazy val position = positionArg
   lazy val partialNextElementResolver = partialNextElementResolverArg
@@ -176,7 +177,6 @@ sealed abstract class TermRuntimeData(
     defaultBitOrder
     optIgnoreCase
     maybeFillByteEv
-    tunable
     maybeCheckByteAndBitOrderEv
     maybeCheckBitOrderAndCharsetEv
   }
@@ -196,7 +196,7 @@ sealed class NonTermRuntimeData(
   @TransientParam diagnosticDebugNameArg: => String,
   @TransientParam pathArg: => String,
   @TransientParam namespacesArg: => NamespaceBinding,
-  @TransientParam tunableArg: => DaffodilTunables)
+  @TransientParam unqualifiedPathStepPolicyArg: => UnqualifiedPathStepPolicy)
   extends RuntimeData
   with PreSerialization {
 
@@ -205,7 +205,7 @@ sealed class NonTermRuntimeData(
   lazy val diagnosticDebugName = diagnosticDebugNameArg
   lazy val path = pathArg
   lazy val namespaces = namespacesArg
-  lazy val tunable = tunableArg
+  lazy val unqualifiedPathStepPolicy = unqualifiedPathStepPolicyArg
 
   override def preSerialization: Unit = {
     super.preSerialization
@@ -214,7 +214,7 @@ sealed class NonTermRuntimeData(
     diagnosticDebugName
     path
     namespaces
-    tunable
+    unqualifiedPathStepPolicy
   }
   @throws(classOf[java.io.IOException])
   final private def writeObject(out: java.io.ObjectOutputStream): Unit = serializeObject(out)
@@ -246,13 +246,13 @@ final class SimpleTypeRuntimeData(
   @TransientParam totalDigitsArg: => Option[java.math.BigDecimal],
   @TransientParam fractionDigitsArg: => Option[java.math.BigDecimal],
   @TransientParam unionMemberTypesArg: => Seq[SimpleTypeRuntimeData],
-  @TransientParam tunableArg: => DaffodilTunables,
+  @TransientParam unqualifiedPathStepPolicyArg: => UnqualifiedPathStepPolicy,
   @TransientParam repTypeRuntimeDataArg: => Option[SimpleTypeRuntimeData],
   @TransientParam repValueSetArg: => Option[RepValueSet[AnyRef]],
   @TransientParam typeCalculatorArg: => Option[TypeCalculator[AnyRef, AnyRef]],
   @TransientParam optRepPrimTypeArg: => Option[PrimType])
   extends NonTermRuntimeData(variableMapArg, schemaFileLocationArg, diagnosticDebugNameArg,
-    pathArg, namespacesArg, tunableArg) {
+    pathArg, namespacesArg, unqualifiedPathStepPolicyArg) {
 
   import OKOrError._
 
@@ -807,7 +807,7 @@ sealed abstract class ErrorERD(local: String, namespaceURI: String)
       LocalDeclQName(None, local, NS(namespaceURI)), // val namedQName: NamedQName,
       None, // val optPrimType: Option[PrimType],
       null, // sfl: SchemaFileLocation,
-      null, // override val tunable: DaffodilTunables,
+      null, // override val unqualifiedPathStepPolicy : UnqualifiedPathStepPolicy,
       null, // typeCalcMap: TypeCalcMap,
       null, // lexicalContextRuntimeData: RuntimeData,
       null), // val sscd: String),
@@ -1035,14 +1035,14 @@ final class VariableRuntimeData(
   @TransientParam typeRefArg: => RefQName,
   @TransientParam globalQNameArg: => GlobalQName,
   @TransientParam primTypeArg: => NodeInfo.PrimType,
-  @TransientParam tunableArg: => DaffodilTunables)
+  @TransientParam unqualifiedPathStepPolicyArg: => UnqualifiedPathStepPolicy)
   extends NonTermRuntimeData(
     null, // no variable map
     schemaFileLocationArg,
     diagnosticDebugNameArg,
     pathArg,
     namespacesArg,
-    tunableArg)
+    unqualifiedPathStepPolicyArg)
   with Serializable {
 
   lazy val external = externalArg
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/SchemaSetRuntimeData.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/SchemaSetRuntimeData.scala
index fc47d77..b974cb7 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/SchemaSetRuntimeData.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/SchemaSetRuntimeData.scala
@@ -35,7 +35,7 @@ final class SchemaSetRuntimeData(
   val typeCalculators: TypeCalcMap)
   extends Serializable with ThrowsSDE {
 
-  def tunable = elementRuntimeData.tunable
+  def unqualifiedPathStepPolicy = elementRuntimeData.unqualifiedPathStepPolicy
   def encodingInfo = elementRuntimeData.encodingInfo
   override def schemaFileLocation = elementRuntimeData.schemaFileLocation
   override def SDE(str: String, args: Any*) = elementRuntimeData.SDE(str, args)
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/ElementCombinator1.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/ElementCombinator1.scala
index d094e1a..f63e466 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/ElementCombinator1.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/ElementCombinator1.scala
@@ -248,7 +248,7 @@ class ElementParser(
     log(LogLevel.Debug, "currentElement = %s", currentElement)
     val priorElement = pstate.infoset
     priorElement match {
-      case ct: DIComplex => ct.addChild(currentElement)
+      case ct: DIComplex => ct.addChild(currentElement, pstate.tunable)
       case st: DISimple => {
         // don't add as a child. This corner case
         // comes up with QuasiElements, which do not actually get inserted into the infoset
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PState.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PState.scala
index a6aeea8..6484265 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PState.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PState.scala
@@ -350,7 +350,7 @@ final class PState private (
    * If for some reason parsing ends with a throw (not supposed to, but just if)
    * then all bets are off, so most checks are disabled.
    * Some checks are still done. If those fail, we include the original error (if present) as the cause.
-   * 
+   *
    * verifyFinalState may be called from within another try..catch block for which certain excepetions
    * are expected as control flow.
    * To avoid accidently creating such an exception, we wrap our generated exception in UnsuppressableException
@@ -462,8 +462,8 @@ object PState {
       val blobsToKeep = this.blobPaths
       var currentBlobs = ps.blobPaths
       while (currentBlobs ne blobsToKeep) {
-          Files.delete(currentBlobs.head)
-          currentBlobs = currentBlobs.tail
+        Files.delete(currentBlobs.head)
+        currentBlobs = currentBlobs.tail
       }
       ps.blobPaths = blobsToKeep
     }
@@ -484,7 +484,7 @@ object PState {
     dataProc: DFDL.DataProcessor): PState = {
 
     val tunables = dataProc.getTunables()
-    val doc = Infoset.newDocument(root, tunables).asInstanceOf[DIElement]
+    val doc = Infoset.newDocument(root).asInstanceOf[DIElement]
     createInitialPState(doc.asInstanceOf[InfosetDocument], root, dis, output, dataProc)
   }
 
diff --git a/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala b/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala
index aec1df1..6f9807f 100644
--- a/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala
+++ b/daffodil-tdml-lib/src/main/scala/org/apache/daffodil/tdml/TDMLRunner.scala
@@ -574,7 +574,7 @@ abstract class TestCase(testCaseXML: NodeSeq, val parent: DFDLTestSuite)
   private def retrieveBindings(cfg: DefinedConfig, tunable: DaffodilTunables): Seq[Binding] = {
     val bindings: Seq[Binding] = cfg.externalVariableBindings match {
       case None => Seq.empty
-      case Some(bindingsNode) => Binding.getBindings(bindingsNode, tunable)
+      case Some(bindingsNode) => Binding.getBindings(bindingsNode, tunable.unqualifiedPathStepPolicy)
     }
     bindings
   }