RuntimeData objects simplified, compile-memory-leak fixed.

All transient params for runtime data objects are gone.

All by-name passing of args to runtime structures is gone.

Compile-time objects no longer retained after compilation is over.

Cyclic graph constructions are more explicit.

Only a select few TransientParam are left, and they have been
converted to use the Delay type instead of using by-name passing. They
are all ones that actually involve circular relationships, so they
cannot be removed without going to non-functional graph construction.

This is achieved by a Delay object type which is enhanced to avoid
retaining any closures or other objects the Scala compiler creates to
implement by-name/lazy evaluation.

OOLAG now uses regular lazy val again. Got rid of lvCache.

The lvCache strategy (which was to make objects smaller by keeping LVs
for objects in a centralized hash-table cache) was causing a
perceived massive number of schema-compiler objects and this made
figuring out the memory-leak (holding onto the compile-time objects)
too hard.

This change set also removes the extension functions and associated tests:
    dfdlx:repTypeValue
    dfdlx:logicalTypeValue
    dfdlx:outputTypeCalcNextSibling
which is part of DAFFODIL-2273

Made diagnosticDebugName more robust.

A large number of stack-overflow issues arise from a diagnostic
message needing the name, but computing the name somehow fails inside
a more complex method that itself is trying to issue a diagnostic.

Now we always catch these nests, which will help in some cases.
DSOM objects construct their diagnostic debug names when they are created.

Eliminated memory leak of holding onto all the compiler objects.

The culprit was the validator. Internally it caches the error handlers, and
all objects reachable from them. Hence, one must avoid making
mixing ErrorHandler into compiler objects because then they
and everything reachable from them cannot be reclaimed.

Some errors were being suppressed by throws of the
final fatal SAXParseError before they could be accumulated.

The logic for dealing with these errors/warnings is pretty convoluted.
I created DAFFODIL-2541 for cleaning up this logic.

Remove @TransientParam from SchemaFileLocation

Add forcing of most Delay objects in daffodil-core.runtime1 package
using requiredEvaluations calls.

Fixed that invalid DFDL schema was not being treated as a fatal error that
prevents Daffodil from proceeding to compile the schema.

Validation detects more errors now which must have been erroneously
dropped before. One is, e.g., that xs:import statements with no
namespace require both the source and target schemas to have a
namespace. Another is it detects UPA errors it wasn't detecting
before. 2 tests had ambiguity.

Tests that had these errors and numerous other tests had to be
fixed because errors in their DFDL schemas are now detected preventing
them from working as before.

Need for serialization to force things is gone. Any Delay objects that
have not been forced when serialization happens cause an abort.

The way things force delays now, is that things that use delays all
define an initialize method, which must be called to insure all
delays are forced.

The forcing is done not by explicitly forcing the delay objects
themselves, but by initializing the the cyclic objects.

This insures we're not in a circular situation because
it explicitly demands the creation of the objects be completed first
before requesting the delays are evaluatable.

NodeInfo object is now self-initializing.

Daffodil's schema compiler now has coarse "passes"

The first pass is validating the DFDL schema with XML Schema validation.

Next is the initialize method that runs when DSOM objects are constructed.

Next is constructing the DSOM tree/directed-graph. This is driven
by the SchemaSet.allSchemaComponents calculation.

Next pass is evaluating the requiredEvaluations, which are activated
only for the components created in SchemaSet.allSchemaComponents.

Next pass is checkUnusedProperties

Last pass is code-generation (or parser/unparser object creation)
and serialization.

Unified component traversal algorithms.

Improve commentary around initialize() protocol for DSOM objects.

Remove Delay of minimizedScope for ERD.

Other small changes to comments and to AV.dfdl.xsd to make it spit
out fewer warnings.

Test is TestRefMap.testUnusedGroup1 simulates failure that was only occuring
in the VMF schema (which is not public)

The tests characterize the situations where checkAllTopLevels
interacts with errors where global elements have up-and-out paths in
them.

Fixes to Namespaces tests which were failing because errors were going
undetected before, and had to be split out to use separate schemas to
isolate the error situations.

DAFFODIL-2326, DAFFODIL-1879, DAFFODIL-2273, DAFFODIL-2526
diff --git a/daffodil-cli/src/it/scala/org/apache/daffodil/CLI/Util.scala b/daffodil-cli/src/it/scala/org/apache/daffodil/CLI/Util.scala
index ab2b415..ea8082d 100644
--- a/daffodil-cli/src/it/scala/org/apache/daffodil/CLI/Util.scala
+++ b/daffodil-cli/src/it/scala/org/apache/daffodil/CLI/Util.scala
@@ -134,7 +134,10 @@
   }
 
   def cmdConvert(str: String): String = {
-    str.replaceAll("/", "\\\\")
+    if (isWindows)
+      str.replaceAll("/", "\\\\")
+    else
+      str
   }
 
   def fileConvert(str: String): String = {
diff --git a/daffodil-cli/src/it/scala/org/apache/daffodil/debugger/TestCLIDebugger.scala b/daffodil-cli/src/it/scala/org/apache/daffodil/debugger/TestCLIDebugger.scala
index a953519..a8fa4cf 100644
--- a/daffodil-cli/src/it/scala/org/apache/daffodil/debugger/TestCLIDebugger.scala
+++ b/daffodil-cli/src/it/scala/org/apache/daffodil/debugger/TestCLIDebugger.scala
@@ -932,7 +932,7 @@
       shell.expect(contains("hidden: true"))
 
       shell.sendLine("continue")
-      shell.expect(contains("<f>2</f>"))
+      shell.expect(contains("<f xmlns=\"\">2</f>"))
       shell.sendLine("quit")
     } finally {
       shell.close()
@@ -972,7 +972,7 @@
       shell.expect(contains("hidden: false"))
 
       shell.sendLine("continue")
-      shell.expect(contains("<f>3</f>"))
+      shell.expect(contains("<f xmlns=\"\">3</f>"))
       shell.sendLine("quit")
     } finally {
       shell.close()
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 e8a856a..5749811 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
@@ -97,7 +97,7 @@
 
   lazy val sset: SchemaSet =
     optSchemaSet.getOrElse(
-      new SchemaSet(optRootSpec, schemaSource, validateDFDLSchemas, checkAllTopLevel, tunables,
+      SchemaSet(optRootSpec, schemaSource, validateDFDLSchemas, checkAllTopLevel, tunables,
         compilerExternalVarSettings))
 
   lazy val rootView: RootView = sset.root
@@ -107,7 +107,7 @@
   def diagnostics = sset.diagnostics
   def getDiagnostics = diagnostics
 
-  override def onPath(xpath: String) = sset.onPath(xpath)
+  override def onPath(xpath: String): DFDL.DataProcessor = sset.onPath(xpath)
 
   override def forLanguage(language: String): DFDL.CodeGenerator = {
     Assert.usage(!isError)
@@ -156,13 +156,32 @@
    * This argument can be removed once this deprecated feature is removed.
    */
   private var externalDFDLVariables: Queue[Binding],
+
+  /**
+   * checkAllTopLevel should normally be true. There are some schemas where
+   * it must be false. Those are schemas where there are top-level elements that
+   * are unused (when certain roots are selected) which have "up and out" relative paths.
+   *
+   * That sort of element isn't ever intended to be a root, it's intended to be
+   * used by way of an element reference within a context that makes the relative path
+   * meaningful.
+   *
+   * Compiling a schema with that sort of element in it and compileAllTopLevel true
+   * causes an SDE about "relative path past root".
+   */
   private var checkAllTopLevel : Boolean,
   private var optRootName: Option[String],
   private var optRootNamespace: Option[String])
   extends DFDL.Compiler
   with Logging {
 
-  private def this(validateDFDLSchemas: Boolean = true) = this(validateDFDLSchemas, DaffodilTunables(), Queue.empty, true, None, None)
+  private def this(validateDFDLSchemas: Boolean = true) =
+    this(validateDFDLSchemas,
+      tunables = DaffodilTunables(),
+      externalDFDLVariables = Queue.empty,
+      checkAllTopLevel = true,
+      optRootName = None,
+      optRootNamespace = None)
 
   private def copy(validateDFDLSchemas: Boolean = validateDFDLSchemas,
     tunables : DaffodilTunables = tunables,
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 40cb85d..68ffc84 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
@@ -50,16 +50,6 @@
 abstract class Expression extends OOLAGHostImpl()
   with BasicComponent {
 
-  /**
-   * Use several calls instead of one, because then OOLAG will try them
-   * all separately, and perhaps if you're lucky report more errors.
-   */
-  requiredEvaluationsAlways(parent)
-  requiredEvaluationsAlways(targetType)
-  requiredEvaluationsAlways(inherentType)
-  requiredEvaluationsAlways(isTypeCorrect)
-  requiredEvaluationsAlways(compiledDPath_)
-
   override lazy val tunable: DaffodilTunables = parent.tunable
   override lazy val unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy = parent.unqualifiedPathStepPolicy
   /**
@@ -131,7 +121,7 @@
     res
   }
 
-  private def compiledDPath_ = LV('compiledDPath) { compiledDPath }
+  private lazy val compiledDPath_ = LV('compiledDPath) { compiledDPath }
   def compiledDPath: CompiledDPath
 
   final lazy val parentOpt = Option(parent)
@@ -861,9 +851,6 @@
       "Relative path '%s' past root element.", this.wholeExpressionText)
     toss(err)
   }
-  requiredEvaluationsAlways(priorStep)
-  requiredEvaluationsAlways(compileInfo)
-  requiredEvaluationsAlways(stepElements)
 
   def verifyQNames(cis: Seq[DPathElementCompileInfo]): Unit = {
     cis.foreach { ci =>
@@ -875,6 +862,9 @@
   // that enables a lazy calculation to call super.
   final lazy val stepElements = {
     val res = stepElementDefs
+    // We cannot check Assert.invariant(res.isDefinedAt(0))
+    // since that would prevent us from detecting illegal paths past root
+    // for example.
     res
   }
 
@@ -1090,8 +1080,6 @@
 case class Self2(s: String, predArg: Option[PredicateExpression])
   extends SelfStepExpression(s, predArg) {
 
-  requiredEvaluationsAlways(stepQName)
-
   override def stepElementDefs: Seq[DPathElementCompileInfo] = {
     val cis = super.stepElementDefs
     verifyQNames(cis)
@@ -1146,8 +1134,6 @@
 case class Up2(s: String, predArg: Option[PredicateExpression])
   extends UpStepExpression(s, predArg) {
 
-  requiredEvaluationsAlways(stepQName)
-
   override def text = ".."
 
   override protected def stepElementDefs: Seq[DPathElementCompileInfo] = {
@@ -1161,8 +1147,6 @@
 case class NamedStep(s: String, predArg: Option[PredicateExpression])
   extends DownStepExpression(s, predArg) {
 
-  requiredEvaluationsAlways(stepQName)
-
   override lazy val compiledDPath = {
     val d = downwardStep
     val conv = conversions
@@ -1693,97 +1677,6 @@
           typeCalc.srcType, NodeInfo.String, typeCalc.dstType, DFDLXOutputTypeCalc(_, typeCalc))
       }
 
-      case (RefQName(_, "outputTypeCalcNextSibling", DFDLX), args) => {
-        val erd = compileInfo.lexicalContextRuntimeData match {
-          case erd: ElementRuntimeData => erd
-          case _ => SDE("dfdlx:outputTypeCalcNextSibling can only be defined on an element")
-        }
-        val resolver = erd.partialNextElementResolver
-        val followingERDs = resolver.currentPossibleNextElements.dropWhile { _ == erd }
-
-        // It is required that the next sibling be a peer "adjacent or downward", but not up-and-out
-        // from the location of the term where this resides.
-        //
-        //we keep the ERD to be able to produce better error messages
-        val dstTypes: Seq[(NodeInfo.Kind, ElementRuntimeData)] = followingERDs.map(erd => {
-          val strd = erd.optSimpleTypeRuntimeData match {
-            case Some(x) => x
-            case None => SDE("dfdlx:outputTypeCalcNextSibling: potential next sibling %s does not have a simple type def. This could be because it has a primitive type, or a complex type.", erd.namedQName)
-          }
-          val calc = strd.typeCalculator match {
-            case Some(x) => x
-            case None => SDE("dfdlx:outputTypeCalcNextSibling(): potential next sibling %s does not define a type calculator", erd.namedQName)
-          }
-          if (!calc.supportsUnparse) {
-            SDE("dfdlx:outputTypeCalcNextSibling(): potential next sibling %s does not have an outputTypeCalc", erd.namedQName)
-          }
-          (calc.srcType, erd)
-        })
-        val dstType = dstTypes match {
-          case Seq() => SDE("dfdlx:outputTypeCalcNextSibling() called where no suitable next sibling exists")
-          case Seq(x) => x._1
-          case x +: xs => {
-            val (ans, headQName) = x
-            /*
-             * Verify that all next siblings have the same dstType
-             * In theory, we could loosen the requirement to having the same primitive type,
-             * but in the interest of being conservative, we will stick to the stricter interperatation for now
-             */
-            xs.map(other => {
-              val (otherAns, otherQName) = other
-              if (otherAns != ans) {
-                SDE(
-                  "dfdlx:outputTypeCalcNextSibling() requires that all the possible next siblings have the same " +
-                    "repType. However, the potential next siblings %s and %s have repTypes %s and %s respectively",
-                  headQName, otherQName, ans, otherAns)
-              }
-            })
-            ans
-          }
-        }
-
-        // We need to mark all possible following compileInfos as possibly used
-        // in an expression since the DFDLXOutputTypeCalcNextSibling expression
-        // might need them. We also need to mark this compileInfo as used in an
-        // expression since the evaluate method of DFDLXTypeCalcNextSibilng
-        // uses this element to find the next sibling
-        val dpeci = erd.dpathCompileInfo.asInstanceOf[DPathElementCompileInfo]
-        followingERDs.foreach { erd =>
-          dpeci.indicateReferencedByExpression(Seq(erd.dpathElementCompileInfo))
-        }
-        dpeci.indicateReferencedByExpression(Seq(dpeci))
-
-        FNZeroArgExpr(functionQNameString, functionQName,
-          dstType, NodeInfo.AnyAtomic, DFDLXOutputTypeCalcNextSibling(_, _))
-      }
-
-      case (RefQName(_, "repTypeValue", DFDLX), args) => {
-        val strd = compileInfo.lexicalContextRuntimeData match {
-          case strd: SimpleTypeRuntimeData => strd
-          case _ => {
-            SDE("dfdlx:repTypeValue() can only be defined on a simple type")
-          }
-        }
-        val repPrimType = strd.optRepPrimType match {
-          case Some(x) => x
-          case None => SDE("dfdlx:repTypeValue() used on type that does not have a repType.")
-        }
-        FNZeroArgExpr(functionQNameString, functionQName,
-          repPrimType, NodeInfo.AnyAtomic, DFDLXRepTypeValue(_, _))
-      }
-
-      case (RefQName(_, "logicalTypeValue", DFDLX), args) => {
-        val strd = compileInfo.lexicalContextRuntimeData match {
-          case strd: SimpleTypeRuntimeData => strd
-          case _ => {
-            SDE("dfdlx:logicalTypeValue() can only be defined on a simple type")
-          }
-        }
-        val logicalType = strd.primType
-        FNZeroArgExpr(functionQNameString, functionQName,
-          logicalType, NodeInfo.AnyAtomic, DFDLXLogicalTypeValue(_, _))
-      }
-
       //End typeValueCalc related functions
 
       case (RefQName(_, "lookAhead", DFDLX), args) =>
@@ -1948,6 +1841,7 @@
     if (requiresUnparse && !typeCalculator.supportsUnparse) {
       SDE("The type calculator defined by %s does not define an outputValueCalc.", qname)
     }
+    typeCalculator.initialize()
     typeCalculator
   }
 
@@ -2514,9 +2408,6 @@
 case class DFDLXTraceExpr(nameAsParsed: String, fnQName: RefQName, args: List[Expression])
   extends FunctionCallBase(nameAsParsed, fnQName, args) {
 
-  requiredEvaluationsAlways(realArg)
-  requiredEvaluationsAlways(msgText)
-
   lazy val (realArg, msgText) = args match {
     case List(arg0, LiteralExpression(txt: String)) => (arg0, txt)
     case List(arg0, other) =>
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/AnnotatedSchemaComponent.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/AnnotatedSchemaComponent.scala
index 2d67fd5..782dc3f 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/AnnotatedSchemaComponent.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/AnnotatedSchemaComponent.scala
@@ -273,7 +273,8 @@
    * we want to avoid evaluating that at all when the key is one
    * we have already seen.
    */
-  final def getShared(key: ShareKey, value: => SharedType): SharedType = {
+  final def getShared(key: ShareKey, valueArg: => SharedType): SharedType = {
+    lazy val value = valueArg // once only
     val opt = vals.get(key)
     opt match {
       case Some(y) => y
@@ -296,6 +297,10 @@
   with AnnotatedMixin
   with OverlapCheckMixin {
 
+  protected override def initialize(): Unit = {
+    super.initialize()
+  }
+
   /**
    * If two terms have the same propEnv, they have identical properties
    * in scope.
@@ -331,7 +336,7 @@
    */
   final protected def refersToForPropertyCombining: Option[AnnotatedSchemaComponent] = optReferredToComponent
 
-  protected def optReferredToComponent: Option[AnnotatedSchemaComponent] // override in ref objects
+  def optReferredToComponent: Option[AnnotatedSchemaComponent] // override in ref objects
 
   lazy val nonDefaultPropertySources: Seq[ChainPropProvider] = LV('nonDefaultPropertySources) {
     this match {
@@ -443,7 +448,7 @@
    * The DFDL annotations on the component, as objects
    * that are subtypes of DFDLAnnotation.
    */
-  final lazy val annotationObjs = LV('annotationObjs) {
+  final lazy val annotationObjs = {
     val objs = dfdlAppInfos.flatMap { dai =>
       {
         val children = dai.child
@@ -456,7 +461,7 @@
       }
     }
     objs
-  }.value
+  }
 
   /**
    * Here we establish an invariant which is that every annotatable schema component has, definitely, has an
@@ -476,7 +481,7 @@
 
   protected def isMyFormatAnnotation(a: DFDLAnnotation): Boolean
 
-  final lazy val formatAnnotation = LV('formatAnnotation) {
+  final lazy val formatAnnotation = {
     val format = annotationObjs.collect { case fa: DFDLFormatAnnotation if isMyFormatAnnotation(fa) => fa }
     val res = format match {
       case Seq() => emptyFormatFactory // does make things with the right namespace scopes attached!
@@ -484,6 +489,6 @@
       case _ => schemaDefinitionError("Only one format annotation is allowed at each annotation point.")
     }
     res
-  }.value
+  }
 
 }
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ChoiceGroup.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ChoiceGroup.scala
index 18fc376..ab9ee32 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ChoiceGroup.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ChoiceGroup.scala
@@ -20,7 +20,6 @@
 import org.apache.daffodil.dsom.walker.ChoiceView
 
 import scala.xml.Node
-import scala.xml._
 import org.apache.daffodil.schema.annotation.props.gen.Choice_AnnotationMixin
 import org.apache.daffodil.schema.annotation.props.gen.ChoiceAGMixin
 import org.apache.daffodil.grammar.ChoiceGrammarMixin
@@ -103,7 +102,6 @@
   requiredEvaluationsIfActivated(noBranchesFound)
   requiredEvaluationsIfActivated(branchesAreNonOptional)
   requiredEvaluationsIfActivated(branchesAreNotIVCElements)
-  requiredEvaluationsIfActivated(modelGroupRuntimeData.preSerialization)
 
   final protected lazy val optionChoiceDispatchKeyRaw = findPropertyOption("choiceDispatchKey", expressionAllowed  = true)
   final protected lazy val choiceDispatchKeyRaw = requireProperty(optionChoiceDispatchKeyRaw)
@@ -229,17 +227,21 @@
    * This latter need to be allowed, because while they do not have known required syntax they do
    * have to be executed for side-effect.
    */
-  final def branchesAreNonOptional = LV('branchesAreNonOptional) {
+  final lazy val branchesAreNonOptional = LV('branchesAreNonOptional) {
     val branchesOk = groupMembers map { branch =>
-      if (branch.isOptional) {
-        schemaDefinitionErrorButContinue("Branch of choice %s must be non-optional.".format(branch.path))
+      val realBranch = branch match {
+        case impliedSeq: ChoiceBranchImpliedSequence => impliedSeq.groupMembers(0)
+        case regular => regular
+      }
+      if (realBranch.isOptional) {
+        schemaDefinitionErrorButContinue("Branch of choice %s must be non-optional.".format(realBranch.path))
         false
       } else true
     }
     assuming(branchesOk.forall { x => x })
   }.value
 
-  final def branchesAreNotIVCElements = LV('branchesAreNotIVCElements) {
+  final lazy val branchesAreNotIVCElements = LV('branchesAreNotIVCElements) {
     val branchesOk = groupMembers map { branch =>
       if (!branch.isRepresented) {
         schemaDefinitionErrorButContinue("Branch of choice %s cannot have the dfdl:inputValueCalc property.".format(branch.path))
@@ -250,11 +252,40 @@
   }.value
 }
 
-final class Choice(xmlArg: Node, lexicalParent: SchemaComponent, position: Int)
+object Choice {
+  def apply(xmlArg: Node, lexicalParent: SchemaComponent, position: Int) = {
+    val c = new Choice(xmlArg, lexicalParent, position)
+    c.initialize()
+    c
+  }
+}
+final class Choice private (xmlArg: Node, lexicalParent: SchemaComponent, position: Int)
   extends ChoiceTermBase(xmlArg, Option(lexicalParent), position)
   with ChoiceDefMixin
   with ChoiceView {
 
   override lazy val optReferredToComponent = None
 
+  override protected def computeGroupMembers(): Seq[Term] = {
+    val firstCut = super.computeGroupMembers()
+    val withImpliedSequences =
+      firstCut.map { term =>
+        val finalTerm =
+          if (term.isScalar) term
+          else {
+            /**
+             * If this choice branch is a non-scalar, then we need to encapsulate
+             * it with a ChoiceBranchImpliedSequence, which is a kind of Sequence
+             * base. When compiling this this choice branch, Daffodil can then
+             * depend on the invariant that every recurring element is contained
+             * inside a sequence, and that sequence describes everything about how
+             * that elements occurrences are separated.
+             */
+            ChoiceBranchImpliedSequence(term)
+          }
+        finalTerm
+      }
+    withImpliedSequences
+  }
+
 }
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 d57e883..ab6aeba 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
@@ -60,6 +60,9 @@
     host: BasicComponent,
     compileInfo: DPathCompileInfo): CompiledExpression[T] = {
 
+    compileInfo.initialize
+    compileInfoWhereExpressionWasLocated.initialize
+
     val res =
       if (DPathUtil.isExpression(exprOrLiteral)) {
         compileRealExpression(
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ComplexTypes.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ComplexTypes.scala
index c5b9b9a..b7ee18b 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ComplexTypes.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ComplexTypes.scala
@@ -35,14 +35,12 @@
   final override def optUnion = None
   final override def typeNode = NodeInfo.Complex
 
-  requiredEvaluationsIfActivated(modelGroup)
-
   override final def group = modelGroup
 
   /**
    * Convenience methods for unit testing. Just makes tests a bit more compact and clearer.
    */
-  final def sequence = group.asInstanceOf[Sequence]
+  final def sequence = group.asInstanceOf[LocalSequence]
   final def choice = group.asInstanceOf[Choice]
 
   private lazy val <complexType>{ xmlChildren @ _* }</complexType> = xml
@@ -86,7 +84,15 @@
   }
 }
 
-final class GlobalComplexTypeDef(
+object GlobalComplexTypeDef {
+  def apply(xmlArg: Node, schemaDocumentArg: SchemaDocument) = {
+    val gctd = new GlobalComplexTypeDef(xmlArg, schemaDocumentArg)
+    gctd.initialize()
+    gctd
+  }
+}
+
+final class GlobalComplexTypeDef private (
   xmlArg: Node,
   schemaDocumentArg: SchemaDocument)
   extends ComplexTypeBase(xmlArg, schemaDocumentArg)
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLAnnotation.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLAnnotation.scala
index 97dd586..57a1d67 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLAnnotation.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLAnnotation.scala
@@ -47,7 +47,7 @@
 
   override def toString = diagnosticDebugName
 
-  override lazy val diagnosticDebugName: String = {
+  override protected lazy val diagnosticDebugNameImpl: String = {
     val cn = Misc.getNameFromClass(this)
     val n =
       if (cn.startsWith("DFDL")) {
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLDefineFormat.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLDefineFormat.scala
index e048bf1..4fe772a 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLDefineFormat.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLDefineFormat.scala
@@ -21,20 +21,22 @@
 import scala.xml.Utility
 import org.apache.daffodil.xml.XMLUtils
 
+object DFDLDefineFormat {
+  def apply(node: Node, sd: SchemaDocument) = {
+    val df = new DFDLDefineFormat(node, sd)
+    df.initialize()
+    df
+  }
+}
+
 final class DFDLDefineFormat(node: Node, sd: SchemaDocument)
   extends DFDLDefiningAnnotation(node, sd) // Note: DefineFormat is not a format annotation
   {
 
-  requiredEvaluationsAlways(formatAnnotation)
-
-  // baseFormat was removed from the DFDL spec. Just use a ref from the
-  // dfdl:format inside.
-  // lazy val baseFormat = getAttributeOption("baseFormat") // nor baseFormat
-
   lazy val formatAnnotation = LV('formatAnnotation) {
     XMLUtils.removeComments(Utility.trim(node)) match {
       case <defineFormat>{ f @ <format>{ _* }</format> }</defineFormat> =>
-        new DFDLFormat(f, sd)
+        DFDLFormat(f, sd)
       case _ =>
         schemaDefinitionError("dfdl:defineFormat does not contain a dfdl:format element.")
     }
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 ab8f9eb..eaf1e93 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
@@ -20,20 +20,39 @@
 import scala.xml.Node
 import scala.xml.NodeSeq.seqToNodeSeq
 import org.apache.daffodil.grammar.EmptyGram
-import org.apache.daffodil.processors._
 import org.apache.daffodil.xml.XMLUtils
-import org.apache.daffodil.xml.GlobalQName
 import org.apache.daffodil.xml.QName
 import org.apache.daffodil.dpath.NodeInfo.PrimType
-import org.apache.daffodil.util.Maybe
-import org.apache.daffodil.grammar.primitives.{ SetVariable, NewVariableInstanceStart, NewVariableInstanceEnd }
-import org.apache.daffodil.schema.annotation.props.Found
+import org.apache.daffodil.grammar.primitives.NewVariableInstanceEnd
+import org.apache.daffodil.grammar.primitives.NewVariableInstanceStart
+import org.apache.daffodil.grammar.primitives.SetVariable
+import org.apache.daffodil.runtime1.DFDLDefineVariableRuntime1Mixin
+import org.apache.daffodil.runtime1.DFDLNewVariableInstanceRuntime1Mixin
+import org.apache.daffodil.runtime1.DFDLSetVariableRuntime1Mixin
+import org.apache.daffodil.runtime1.VariableReferenceRuntime1Mixin
 import org.apache.daffodil.schema.annotation.props.gen.VariableDirection
+import org.apache.daffodil.xml.NS
 
-class DFDLDefineVariable(node: Node, doc: SchemaDocument)
-  extends DFDLDefiningAnnotation(node, doc) {
+object DFDLDefineVariable {
+  def apply(node: Node, doc: SchemaDocument) = {
+    val dv = new DFDLDefineVariable(node, doc)
+    dv.initialize()
+    dv
+  }
 
-  requiredEvaluationsAlways(variableRuntimeData.preSerialization)
+  def apply(node: Node, doc: SchemaDocument, nsURI: String) = {
+    val dv = new DFDLDefineVariable(node, doc) {
+      override lazy val namespace = NS(nsURI)
+      override lazy val targetNamespace = NS(nsURI)
+    }
+    dv.initialize()
+    dv
+  }
+}
+
+class DFDLDefineVariable private (node: Node, doc: SchemaDocument)
+  extends DFDLDefiningAnnotation(node, doc)
+  with DFDLDefineVariableRuntime1Mixin{
 
   final lazy val gram = EmptyGram // has to have because statements have parsers layed in by the grammar.
 
@@ -69,56 +88,34 @@
     this.SDE("Variables must have primitive type. Type was '%s'.", typeQName.toPrettyString))
 
   final def createVariableInstance = variableRuntimeData.createVariableInstance
-
-  final override lazy val runtimeData = variableRuntimeData
-
-  lazy val maybeDefaultValueExpr = {
-    val compilationTargetType = primType
-    val qn = this.qNameForProperty("defaultValue", XMLUtils.dafintURI)
-    val defaultValExpr = defaultValue.map { e =>
-      ExpressionCompilers.AnyRef.compileProperty(qn, compilationTargetType, Found(e, this.dpathCompileInfo, "defaultValue", false), this, dpathCompileInfo)
-    }
-
-    Maybe.toMaybe(defaultValExpr)
-  }
-
-  final lazy val variableRuntimeData = {
-    val vrd = new VariableRuntimeData(
-      this.schemaFileLocation,
-      this.diagnosticDebugName,
-      this.path,
-      this.namespaces,
-      this.external,
-      this.direction,
-      maybeDefaultValueExpr,
-      this.typeQName,
-      this.namedQName.asInstanceOf[GlobalQName],
-      this.primType,
-      this.tunable.unqualifiedPathStepPolicy)
-    vrd
-  }
 }
 
-abstract class VariableReference(node: Node, decl: AnnotatedSchemaComponent)
-  extends DFDLStatement(node, decl) {
+sealed abstract class VariableReference(node: Node, decl: AnnotatedSchemaComponent)
+  extends DFDLStatement(node, decl)
+  with VariableReferenceRuntime1Mixin {
+
+  requiredEvaluationsIfActivated(varQName)
 
   final lazy val ref = getAttributeRequired("ref")
   final lazy val varQName = resolveQName(ref)
 
-  def variableRuntimeData = defv.runtimeData
-
   final lazy val defv = decl.schemaSet.getDefineVariable(varQName).getOrElse(
     this.schemaDefinitionError("Variable definition not found: %s", ref))
 }
 
 final class DFDLNewVariableInstance(node: Node, decl: AnnotatedSchemaComponent)
-  extends VariableReference(node, decl) // with NewVariableInstance_AnnotationMixin
-  {
-  // newVariableInstance only allowed within group ref, sequence, or choice
-  decl match {
-    case gr: GroupRef =>
-    case grl: GroupDefLike =>
-    case _ => decl.SDE("newVariableInstance may only be used on group reference, sequence or choice")
+  extends VariableReference(node, decl)
+    with DFDLNewVariableInstanceRuntime1Mixin  {
+
+  requiredEvaluationsIfActivated(checks)
+
+  private lazy val checks = {
+    // newVariableInstance only allowed within group ref, sequence, or choice
+    decl match {
+      case gr: GroupRef =>
+      case grl: GroupDefLike =>
+      case _ => decl.SDE("newVariableInstance may only be used on group reference, sequence or choice")
+    }
   }
 
   private lazy val attrValue = getAttributeOption("value")
@@ -144,37 +141,6 @@
     case (None, "") => decl.SDE("Must have either a value attribute or an element value: %s", node)
   }
 
-  lazy val maybeDefaultValueExpr = {
-    val compilationTargetType = defv.primType
-    val qn = this.qNameForProperty("defaultValue", XMLUtils.dafintURI)
-    val defaultValExpr = defaultValue.map { e =>
-      ExpressionCompilers.AnyRef.compileProperty(qn, compilationTargetType, Found(e, this.dpathCompileInfo, "defaultValue", false), this, dpathCompileInfo)
-    }
-
-    Maybe.toMaybe(defaultValExpr)
-  }
-
-  /* Need to override variableRuntimeData so that defaultValues
-   * are read from newVariableInstance instead of the original
-   * variable definition. Also allows diagnostic messages to
-   * point to this location instead of the original definition
-   */
-  final override lazy val variableRuntimeData = {
-    val vrd = new VariableRuntimeData(
-      this.schemaFileLocation,
-      this.diagnosticDebugName,
-      this.path,
-      this.namespaces,
-      defv.external,
-      defv.direction,
-      maybeDefaultValueExpr,
-      defv.typeQName,
-      defv.namedQName.asInstanceOf[GlobalQName],
-      defv.primType,
-      this.tunable.unqualifiedPathStepPolicy)
-    vrd
-  }
-
   final def gram(term: Term) = LV('gram) {
     NewVariableInstanceStart(decl, this)
   }.value
@@ -185,8 +151,8 @@
 }
 
 final class DFDLSetVariable(node: Node, decl: AnnotatedSchemaComponent)
-  extends VariableReference(node, decl) // with SetVariable_AnnotationMixin
-  {
+  extends VariableReference(node, decl)
+  with DFDLSetVariableRuntime1Mixin {
   private lazy val attrValue = getAttributeOption("value")
   private lazy val <dfdl:setVariable>{ eltChildren @ _* }</dfdl:setVariable> = node
   private lazy val eltValue = eltChildren.text.trim
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 84eef74..7208321 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
@@ -78,7 +78,7 @@
   override def verifyPropValue(key: String, value: String): Boolean =
     super.verifyPropValue(key, value)
 
-  final def escapeCharacterEv = LV('escapeCharacterEv) {
+  final lazy val escapeCharacterEv = LV('escapeCharacterEv) {
     val qn = this.qNameForProperty("escapeCharacter")
     val expr = ExpressionCompilers.String.compileProperty(qn, NodeInfo.NonEmptyString, escapeCharacterRaw, this,
       defES.pointOfUse.dpathCompileInfo)
@@ -87,7 +87,7 @@
     ev
   }.value
 
-  final def optionEscapeEscapeCharacterEv = LV('optionEscapeEscapeCharacterEv) {
+  final lazy val optionEscapeEscapeCharacterEv = LV('optionEscapeEscapeCharacterEv) {
     val qn = this.qNameForProperty("escapeEscapeCharacter")
     escapeEscapeCharacterRaw match {
       case Found("", loc, _, _) => Nope
@@ -103,7 +103,7 @@
     }
   }.value
 
-  final def optionExtraEscapedCharacters = LV('optionExtraEscapedCharacters) {
+  final lazy val optionExtraEscapedCharacters = LV('optionExtraEscapedCharacters) {
     extraEscapedCharactersRaw match {
       case Found("", _, _, _) => Nope
       case Found(v, _, _, _) => One(v)
@@ -130,11 +130,26 @@
 
 }
 
-final class DFDLDefineEscapeSchemeFactory(node: Node, decl: SchemaDocument)
-  extends DFDLDefiningAnnotation(node, decl) {
-  def forComponent(pointOfUse: SchemaComponent) = new DFDLDefineEscapeScheme(node, decl, pointOfUse)
+object DFDLDefineEscapeSchemeFactory {
+  def apply(node: Node, decl: SchemaDocument) = {
+    val desf = new DFDLDefineEscapeSchemeFactory(node, decl)
+    desf.initialize()
+    desf
+  }
 }
 
+final class DFDLDefineEscapeSchemeFactory private (node: Node, decl: SchemaDocument)
+  extends DFDLDefiningAnnotation(node, decl) {
+  def forComponent(pointOfUse: SchemaComponent) = DFDLDefineEscapeScheme(node, decl, pointOfUse)
+}
+
+object DFDLDefineEscapeScheme {
+  def apply(node: Node, sd: SchemaDocument, pointOfUse: SchemaComponent) = {
+    val des = new DFDLDefineEscapeScheme(node, sd, pointOfUse)
+    des.initialize()
+    des
+  }
+}
 /**
  * Escape scheme definitions
  *
@@ -146,12 +161,13 @@
  * has its own expression compilation for these properties, as it would for any regular expression-valued
  * property like byteOrder or encoding or a delimiter.
  */
-final class DFDLDefineEscapeScheme(node: Node, decl: SchemaDocument,
+final class DFDLDefineEscapeScheme private (node: Node, decl: SchemaDocument,
   val pointOfUse: SchemaComponent)
-  extends DFDLDefiningAnnotation(node, decl) // Note: defineEscapeScheme isn't a format annotation itself.
-  {
+  extends DFDLDefiningAnnotation(node, decl) { // Note: defineEscapeScheme isn't a format annotation itself.
 
-  /*
+  requiredEvaluationsAlways(escapeScheme)
+
+  /**
    * For diagnostic messages, we need the decl - because that's where the
    * escapescheme definition is written.
    *
@@ -159,8 +175,6 @@
    * nearest enclosing element. That will be made to happen by way of
    * the ExpressionCompiler - every schema component potentially has one.
    */
-  requiredEvaluationsAlways(escapeScheme)
-
   lazy val referringComponent: Option[SchemaComponent] = Some(pointOfUse)
 
   lazy val escapeScheme = {
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLFormat.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLFormat.scala
index 43a166a..4c6c2bf 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLFormat.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLFormat.scala
@@ -19,7 +19,15 @@
 
 import scala.xml.Node
 
-final class DFDLFormat(node: Node, sd: SchemaDocument)
+object DFDLFormat {
+  def apply(node: Node, sd: SchemaDocument) = {
+    val df = new DFDLFormat(node, sd)
+    df.initialize()
+    df
+  }
+}
+
+final class DFDLFormat private (node: Node, sd: SchemaDocument)
   extends DFDLFormatAnnotation(node, sd)
 // leave the below comments here for a while. (In case we have to reproduce
 // this list of mixins on a schema component somewhere)
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLFormatAnnotation.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLFormatAnnotation.scala
index 7d3ec51..3b5f349 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLFormatAnnotation.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLFormatAnnotation.scala
@@ -73,8 +73,6 @@
   extends DFDLAnnotation(nodeArg, annotatedSCArg)
   with LeafPropProvider {
 
-  requiredEvaluationsAlways(hasConflictingPropertyError)
-
   //
   // prefix of a QName as the value of this ref, must be referring
   // to a namespace binding that is in force right here on this object
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLSchemaFile.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLSchemaFile.scala
index e8fe991..134173e 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLSchemaFile.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLSchemaFile.scala
@@ -23,11 +23,78 @@
 import org.apache.daffodil.api._
 import org.apache.daffodil.dsom.IIUtils._
 import org.apache.daffodil.api.Diagnostic
-import org.apache.daffodil.oolag.OOLAG
+import org.apache.daffodil.exceptions.Assert
+import org.apache.daffodil.exceptions.SchemaFileLocation
 import org.apache.daffodil.util.LogLevel
 import org.apache.daffodil.util.Misc
 import org.apache.daffodil.xml.XMLUtils
 
+class DFDLSchemaFileLoadErrorHandler(schemaFileLocation: SchemaFileLocation)
+extends org.xml.sax.ErrorHandler {
+
+  private var loaderErrors_ : Seq[SAXParseException] = Nil
+  private var loaderWarnings_ : Seq[SAXParseException] = Nil
+
+  private def reset(): Unit = {
+    loaderErrors_ = Nil
+    loaderWarnings_ = Nil
+  }
+
+  private def loaderErrors = loaderErrors_
+  private def loaderWarnings = loaderWarnings_
+
+  private def loaderSDEs: Seq[Diagnostic] = loaderErrors.map {
+    new SchemaDefinitionError(schemaFileLocation, "Error loading schema due to %s", _)
+  }
+
+  private def loaderSDWs: Seq[Diagnostic] = loaderWarnings.map{
+    new SchemaDefinitionWarning(schemaFileLocation, "Warning loading schema due to %s", _)
+  }
+
+  def loadingDiagnostics = loaderSDEs ++ loaderSDWs
+
+  /**
+   * Converts the accumulated SAXParseErrors into SDEs and SDWs
+   * and escalates a file validation error to a thrown SDE
+   * so that the enclosing LV gets a failure due to these errors.
+   *
+   * Note: A common pattern for these error handlers is to implement
+   * the trait/interface for the error handler in the object itself,
+   * that is without a separate error handler object. This causes
+   * trouble because the validator caches this object, so if this object
+   * is connected to a large data structure, that will cause heavy
+   * memory usage/leaking.
+   *
+   * Similarly, this object does not store the context object to avoid
+   * holding onto it and all the compilation-time data structures
+   * reachable from it.
+   *
+   * @param context The DFDLSchemaFile object where we're loading
+   */
+  def handleLoadErrors(context: DFDLSchemaFile): Unit = {
+    loaderSDEs.foreach { context.error(_) }
+    loaderSDWs.foreach { context.warn(_)  }
+    val optErr = loaderSDEs.headOption
+    reset()
+    optErr.foreach{
+      context.toss(_) // escalate to a thrown SDE.
+    }
+  }
+
+  def warning(exception: SAXParseException) = {
+    loaderWarnings_ :+= exception
+  }
+
+  def error(exception: SAXParseException) = {
+    loaderErrors_ :+= exception
+  }
+
+  /**
+   * Called on a fatal exception. The parser/validator throws the exception after
+   * this call returns.
+   */
+  def fatalError(exception: SAXParseException) = error(exception) // same as non-fatal exception.
+}
 /**
  * represents one schema document file
  *
@@ -39,9 +106,7 @@
   val iiParent: IIBase,
   seenBeforeArg: IIMap)
   extends SchemaComponentImpl(<file/>, sset)
-  with org.xml.sax.ErrorHandler {
-
-  requiredEvaluationsAlways(isValid)
+  {
 
   private lazy val seenBefore = seenBeforeArg
 
@@ -51,133 +116,92 @@
    * This is the schema document we are contained in, not the one
    * we are referring to.
    */
-  override lazy val schemaDocument = {
+  override lazy val optSchemaDocument = {
     // the one containing the reference to the file
     // Not the schema document in this file (that one is iiSchemaDocument).
-    val res = iiParent.schemaDocument
+    val res = iiParent.optSchemaDocument
     // the schemaDocument in this file is called iiSchemaDocument,
     // but you may only be interested in its XML characteristics (namespace
     // for example), in which case you want iiXMLSchemaDocument
     res
   }
 
-  override lazy val xmlSchemaDocument = iiParent.xmlSchemaDocument
+  override lazy val optXMLSchemaDocument = iiParent.optXMLSchemaDocument
 
   override lazy val uriString = schemaSource.uriForLoading.toString
 
-  override lazy val diagnosticDebugName = schemaSource.uriForLoading.toString
+  override protected lazy val diagnosticDebugNameImpl = schemaSource.uriForLoading.toString
 
   lazy val diagnosticChildren = Nil // no recursive descent. We just want the loader's validation errors.
 
   lazy val schemaSource = schemaSourceArg
 
-  private var validationDiagnostics_ : Seq[Diagnostic] = Nil
-
-  def validationDiagnostics = validationDiagnostics_
-
-  def isValid: Boolean = {
-    node // demanding this forces the load to happen
-    val ld = validationDiagnostics
-    // warnings won't stop things.
-    // TODO: options to control when validation warnings
-    // should be escalated to errors.
-    val res = !ld.exists { d =>
-      {
-        val isE = d.isError
-        isE
-      }
-    }
-    res
-  }
-
-  def warning(exception: SAXParseException) = {
-    val sdw = new SchemaDefinitionWarning(this.schemaFileLocation, "Warning loading schema due to %s", exception)
-    warn(sdw)
-    validationDiagnostics_ :+= sdw
-  }
-
-  def error(exception: SAXParseException) = {
-    val sde = new SchemaDefinitionError(this.schemaFileLocation, "Error loading schema due to %s", exception)
-    error(sde)
-    validationDiagnostics_ :+= sde
-  }
-
-  /**
-   * Called on a fatal exception. The parser/validator throws the exception after
-   * this call returns.
-   */
-  def fatalError(exception: SAXParseException) = error(exception) // same as non-fatal exception.
-
-  private def loadedNode = LV('loadedNode) {
-    def die(e: Throwable) = {
-      SDE("Error loading schema due to %s.", Misc.getSomeMessage(e).getOrElse("an unknown error."))
-    }
-    val node = try {
+  lazy val (node, validationDiagnostics, isValid) = {
+    val res = try {
       log(LogLevel.Resolver, "Loading %s.", diagnosticDebugName)
       //
       // We do not want to validate here ever, because we have to examine the
       // root xs:schema element of a schema to decide if it is a  DFDL schema
       // at all that we're even supposed to compile.
       //
-      val loader = new DaffodilXMLLoader(this)
       // need line numbers for diagnostics
-      val node = loader.load(schemaSource, None, addPositionAttributes = true)
-      schemaDefinitionUnless(node != null, "Unable to load XML from %s.", diagnosticDebugName)
-      node
+      val node = try {
+        loader.load(schemaSource, None, addPositionAttributes = true)
+      } catch {
+        case e: SAXParseException => {
+          // the loader can throw these due to e.g., doctype disallowed which is fatal.
+          // It would be redundant to record it again.
+          // So we simply ignore it.
+          errHandler.error(e)
+          null // node is null in this case.
+        }
+      }
+      errHandler.handleLoadErrors(this)
+      Assert.invariant(node != null)
+      (node, errHandler.loadingDiagnostics, true)
     } catch {
-      case e: java.io.IOException => die(e)
+      case e: java.io.IOException =>
+        SDE("Error loading schema due to %s.",
+          Misc.getSomeMessage(e).getOrElse("an unknown error."))
     }
-    node
-  }.value
-
-  lazy val node = loadedNode
+    res
+  }
 
   lazy val isDFDLSchemaFile = iiXMLSchemaDocument.isDFDLSchema
 
-  private lazy val loader = new DaffodilXMLLoader(this)
+  private lazy val errHandler = new DFDLSchemaFileLoadErrorHandler(schemaFileLocation)
+  private lazy val loader = new DaffodilXMLLoader(errHandler)
 
   lazy val iiXMLSchemaDocument = LV('iiXMLSchemaDocument) {
-    val res = loadXMLSchemaDocument(seenBefore, Some(this))
-    if (res.isDFDLSchema && sset.validateDFDLSchemas) {
+    val res = makeXMLSchemaDocument(seenBefore, Some(this))
+    if (res.isDFDLSchema && sset.shouldValidateDFDLSchemas) {
       //
       // We validate DFDL schemas, only if validation is requested.
       // Some things, tests generally, want to turn this validation off.
       //
-      try loader.validateAsDFDLSchema(schemaSource) // validate as XSD (catches UPA errors for example)
-      catch {
-        // ok to absorb SAX Parse Exception as we've captured those errors in error handling
-        // elsewhere.
-        case _: org.xml.sax.SAXParseException => // ok
-
-        //
-        // Leaving this commented code in, to document that it
-        // is a BAD IDEA to catch Exception. A more specific exception may be ok.
-        // if you catch Exception, this will mask errors like Null Pointer Exceptions.
-        //
-        // This catch of Exception had been put here due to problems with circular definitions
-        // occurring during issuing of an SDE. If the computation of the error object
-        // such as the file name, proper schema object to blame, etc. if those can
-        // themselves cause an SDE, then we end up in a circular definition.
-        //
-        // However, masking all Exceptions is NOT the right way to fix this.
-        // Use of OOLAG LV's toOption method is a better way.
-        //
-        // case e: Exception =>
-        //   Assert.invariantFailed("Unexpected exception type " + e)
+      try {
+        loader.validateAsDFDLSchema(schemaSource)
+      } catch {
+        // validateAsDFDLSchema doesn't always capture all exceptions in the
+        // loader's error handler. Even for fatal errors it sometimes
+        // just throws them.
+        case e: org.xml.sax.SAXParseException =>
+          errHandler.error(e) // accumulate with error handler.
       }
+      errHandler.handleLoadErrors(this)
     }
     res
   }.value
 
-  def iiSchemaDocument = LV('iiSchemaDocument) {
-    val res = new SchemaDocument(iiXMLSchemaDocument)
+  lazy val iiSchemaDocument = {
+    val res = SchemaDocument(iiXMLSchemaDocument)
     res
-  }.value
+  }
 
-  private def loadXMLSchemaDocument(before: IIMap, sf: Option[DFDLSchemaFile]): XMLSchemaDocument = {
+  private def makeXMLSchemaDocument(before: IIMap, sf: Option[DFDLSchemaFile]): XMLSchemaDocument = {
     val sd = node match {
       case <schema>{ _* }</schema> if (NS(node.namespace) == XMLUtils.xsdURI) => {
-        val sd = new XMLSchemaDocument(node, sset, Some(iiParent), sf, before, false)
+        val sd = XMLSchemaDocument(node, sset, Some(iiParent), sf, before, false)
         sd
       }
       case _ => {
@@ -188,11 +212,8 @@
     sd
   }
 
-  lazy val seenAfter: IIMap = LV('seenAfter) {
-    val res = OOLAG.keepGoing(seenBefore) {
+  lazy val seenAfter: IIMap = {
       val aft = iiXMLSchemaDocument.seenAfter
       aft
-    }
-    res
-  }.value
+  }
 }
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLStatementMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLStatementMixin.scala
index 7393a83..f3d2d4e 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLStatementMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/DFDLStatementMixin.scala
@@ -27,7 +27,7 @@
   extends ThrowsSDE
   with ProvidesDFDLStatementMixin { self: Term =>
 
-  requiredEvaluationsAlways(statements)
+  requiredEvaluationsIfActivated(statements)
 
   final lazy val statements: Seq[DFDLStatement] =
     optReferencedStatementSource.toSeq.flatMap { _.resolvedStatements } ++
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementBase.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementBase.scala
index 341ba72..fa675e1 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementBase.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementBase.scala
@@ -68,6 +68,10 @@
   with OverlapCheckMixin
   with ElementBaseView {
 
+  protected override def initialize() = {
+    super.initialize()
+  }
+
   override final def eBase = this
 
   lazy val init: Unit = {
@@ -89,12 +93,13 @@
   requiredEvaluationsIfActivated(if (hasFractionDigits) fractionDigits)
   requiredEvaluationsIfActivated(checkForAlignmentAmbiguity)
   requiredEvaluationsIfActivated(checkFloating)
+  requiredEvaluationsIfActivated(minimizedScope)
 
   override def name: String
 
   final lazy val inputValueCalcOption = findPropertyOption("inputValueCalc", expressionAllowed = true)
 
-  final lazy val outputValueCalcOption = {
+  final lazy val outputValueCalcOption: PropertyLookupResult = {
     val optOVC = findPropertyOption("outputValueCalc", expressionAllowed = true)
     schemaDefinitionWhen(optOVC.isDefined && isOptional, "dfdl:outputValueCalc cannot be defined on optional elements.")
     schemaDefinitionWhen(optOVC.isDefined && isArray, "dfdl:outputValueCalc cannot be defined on array elements.")
@@ -286,16 +291,21 @@
     }
   }
 
-  private lazy val parentMinimizedScope = {
+  private lazy val parentMinimizedScope = LV('parentMinimizedScope) {
     val ee = enclosingElements.headOption // FIXME: bug DAFFODIL-2282 doesn't work unless all are same.
-    ee.map { _.minimizedScope }.getOrElse(scala.xml.TopScope)
-  }
+    val res =
+      if (ee.isEmpty)
+        scala.xml.TopScope
+      else
+        ee.get.minimizedScope
+    res
+  }.value
 
   /**
    * To be properly constructed, scala's xml Elems must share the scope (namespace bindings) of the enclosing
    * parent element, except when it adds more of its own bindings, in which case the tail is supposed to be shared.
    */
-  final protected lazy val minimizedScope: NamespaceBinding = LV('minimizedScope) {
+  protected lazy val minimizedScope: NamespaceBinding = LV('minimizedScope) {
     val uniquePairs =
       if (this.isInstanceOf[Root]) {
         // If this is the root element and it contains xmlns="", then remove
@@ -409,7 +419,7 @@
     unparserInfosetElementDefaultingBehavior !=:= MustExist
   }
 
-  lazy val isQuasiElement: Boolean = false //overriden by RepTypeQuasiElementDecl
+  def isQuasiElement: Boolean = false //overriden by RepTypeQuasiElementDecl
 
   final protected lazy val optTruncateSpecifiedLengthString =
     Option(truncateSpecifiedLengthString =:= YesNo.Yes)
@@ -1156,4 +1166,17 @@
     case (_, _) => this.subset((floating eq YesNo.No), "Property value floating='yes' is not supported.")
   }
 
+  final lazy val quasiElementChildren: Seq[QuasiElementDeclBase] = {
+    val res =
+      if (!isQuasiElement)
+        if (this.lengthKind == LengthKind.Prefixed)
+          Seq(prefixedLengthElementDecl)
+        else if (this.isSimpleType)
+          this.simpleType.optRepTypeElement.toSeq
+        else
+          Nil
+      else
+        Nil
+    res
+  }
 }
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 99da373..dc49cb5 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
@@ -22,6 +22,7 @@
 import org.apache.daffodil.dpath.NodeInfo.PrimType
 import org.apache.daffodil.dsom.walker.ElementDeclView
 import org.apache.daffodil.equality._
+
 import scala.xml.Node
 
 trait ElementLikeMixin
@@ -93,7 +94,7 @@
   final lazy val optComplexType =
     optNamedComplexType.orElse(optImmediateComplexType.collect { case ct: ComplexTypeBase => ct })
 
-  final lazy val namedType: Option[TypeBase] = LV('namedTypeDef) {
+  final lazy val namedType: Option[TypeBase] = {
     val res = optNamedSimpleType.orElse(optNamedComplexType).orElse {
       namedTypeQName.map { qn => SDE("No type definition found for '%s'.", qn.toPrettyString) }
     }
@@ -101,11 +102,11 @@
       optNamedComplexType.isDefined)
       SDE("Both a simple type and a complex type definition found for %s.", namedTypeQName.get.toPrettyString)
     res
-  }.value
+  }
 
   final lazy val immediateType = optImmediateSimpleType.orElse(optImmediateComplexType)
 
-  final lazy val typeDef: TypeBase = LV('typeDef) {
+  final lazy val typeDef: TypeBase = LV('TypeBase){
     (immediateType, namedType) match {
       case (Some(ty), None) => ty
       case (None, Some(ty)) => ty
@@ -116,21 +117,17 @@
     }
   }.value
 
-  final lazy val optImmediateSimpleType: Option[SimpleTypeBase] = LV('optImmediateSimpleType) {
+  final lazy val optImmediateSimpleType: Option[LocalSimpleTypeDef] = LV('optImmediateSimpleType) {
     val st = xml \ "simpleType"
     if (st.length == 1) {
-      val lstd = new LocalSimpleTypeDef(st(0), this)
+      val lstd = LocalSimpleTypeDef(st(0), this)
       Some(lstd)
     } else None
   }.value
 
   final lazy val typeName = getAttributeOption("type")
 
-  final lazy val namedTypeQName: Option[RefQName] = {
-    typeName.map { tname =>
-      QName.resolveRef(tname, namespaces, tunable.unqualifiedPathStepPolicy).get
-    }
-  }
+  final lazy val namedTypeQName: Option[RefQName] = typeName.map { resolveQName(_) }
 
   final lazy val optNamedSimpleType: Option[SimpleTypeBase] = {
     namedTypeQName.flatMap { qn =>
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementRef.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementRef.scala
index d709869..985c7ad 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementRef.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementRef.scala
@@ -21,11 +21,18 @@
 import org.apache.daffodil.xml._
 import org.apache.daffodil.dpath.NodeInfo
 
+object ElementRef {
+  def apply(xmlArg: Node, lexicalParent: GroupDefLike, position: Int) = {
+    val er = new ElementRef(xmlArg, lexicalParent, position)
+    er.initialize()
+    er
+  }
+}
 /**
  * There are 3 first-class concrete children of ElementBase.
  * Root, LocalElementDecl, and ElementRef
  */
-final class ElementRef(xmlArg: Node, lexicalParent: GroupDefLike, position: Int)
+final class ElementRef private (xmlArg: Node, lexicalParent: GroupDefLike, position: Int)
   extends AbstractElementRef(xmlArg, lexicalParent, position)
 
 abstract class AbstractElementRef(
@@ -62,7 +69,7 @@
    * invokes namedQName because it's a named thing, must be overridden
    * and use refQName instead.
    */
-  override def namedQName: NamedQName = LV('namedQName) {
+  override lazy val namedQName: NamedQName = LV('namedQName) {
     referencedElement.namedQName
   }.value
 
@@ -93,7 +100,7 @@
 
   override lazy val namespace = refQName.namespace
 
-  override lazy val diagnosticDebugName = "element reference " + refQName
+  override protected lazy val diagnosticDebugNameImpl = "element reference " + refQName
 
   override def typeDef = referencedElement.typeDef
 
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Facets.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Facets.scala
index 77e9c2e..473f26c 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Facets.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Facets.scala
@@ -26,17 +26,6 @@
 trait Facets { self: Restriction =>
   import org.apache.daffodil.dsom.FacetTypes._
 
-  requiredEvaluationsAlways(if (hasPattern) patternValues)
-  requiredEvaluationsAlways(if (hasEnumeration) enumerationValues)
-  requiredEvaluationsAlways(if (hasMinLength) minLengthValue)
-  requiredEvaluationsAlways(if (hasMaxLength) maxLengthValue)
-  requiredEvaluationsAlways(if (hasMinInclusive) minInclusiveValue)
-  requiredEvaluationsAlways(if (hasMaxInclusive) maxInclusiveValue)
-  requiredEvaluationsAlways(if (hasMinExclusive) minExclusiveValue)
-  requiredEvaluationsAlways(if (hasMaxExclusive) maxExclusiveValue)
-  requiredEvaluationsAlways(if (hasTotalDigits) totalDigitsValue)
-  requiredEvaluationsAlways(if (hasFractionDigits) fractionDigitsValue)
-
   private def retrieveFacetValueFromRestrictionBase(xml: Node, facetName: Facet.Type): String = {
     val res = xml \\ "restriction" \ facetName.toString() \ "@value"
     if (res.length > 0) res.head.text else ""
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GlobalElementDecl.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GlobalElementDecl.scala
index 55542fd..a978fa4 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GlobalElementDecl.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GlobalElementDecl.scala
@@ -19,7 +19,15 @@
 
 import scala.xml.Node
 
-final class GlobalElementDecl(
+object GlobalElementDecl {
+  def apply(xmlArg: Node, schemaDocument: SchemaDocument) = {
+    val ged = new GlobalElementDecl(xmlArg, schemaDocument)
+    ged.initialize()
+    ged
+  }
+}
+
+final class GlobalElementDecl private (
   xmlArg: Node,
   schemaDocument: SchemaDocument)
   extends AnnotatedSchemaComponentImpl(xmlArg, schemaDocument)
@@ -30,7 +38,7 @@
   // NOT on global element decls such as dfdl:choiceBranchKey
   with ResolvesLocalProperties {
 
-  lazy val asRoot = new Root(xml, schemaDocument, namedQName, this)
+  lazy val asRoot = Root(xml, schemaDocument, namedQName, this)
 
   requiredEvaluationsIfActivated(validateChoiceBranchKey)
 
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GroupDef.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GroupDef.scala
index 28f38a7..b4ea4b1 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GroupDef.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GroupDef.scala
@@ -30,9 +30,9 @@
       case <group>{ contents @ _* }</group> => {
         val list = contents.collect {
           case groupXML @ <sequence>{ _* }</sequence> =>
-            new GlobalSequenceGroupDef(defXML, groupXML, schemaDocument)
+            GlobalSequenceGroupDef(defXML, groupXML, schemaDocument)
           case groupXML @ <choice>{ _* }</choice> =>
-            new GlobalChoiceGroupDef(defXML, groupXML, schemaDocument)
+            GlobalChoiceGroupDef(defXML, groupXML, schemaDocument)
         }
         val res = list(0)
         res
@@ -67,6 +67,11 @@
 
   /** Returns the group members that are elements or model groups. */
   protected lazy val groupMembersDef: Seq[Term] = LV('groupMembers) {
+    computeGroupMembers()
+  }.value
+
+  // override in Choice
+  protected def computeGroupMembers(): Seq[Term] = {
     val positions = List.range(1, goodXmlChildren.length + 1) // range is exclusive on 2nd arg. So +1.
     val pairs = goodXmlChildren zip positions
     val members = pairs.map {
@@ -75,7 +80,7 @@
         t
     }
     members
-  }.value
+  }
 
   /**
    * XML is full of uninteresting text nodes. We just want the element children, not all children.
@@ -126,24 +131,40 @@
   final override lazy val name = defXML.attribute("name").map { _.text }.getOrElse(
     Assert.invariantFailed("Global group def without name attribute."))
 
-  final override protected def optReferredToComponent = None
+  override def optReferredToComponent = None
 }
 
-final class GlobalSequenceGroupDef(
+object GlobalSequenceGroupDef {
+  def apply(defXMLArg: Node, seqXML: Node, schemaDocument: SchemaDocument) = {
+    val gsgd = new GlobalSequenceGroupDef(defXMLArg, seqXML, schemaDocument)
+    gsgd.initialize()
+    gsgd
+  }
+}
+
+final class GlobalSequenceGroupDef private (
   defXMLArg: Node, seqXML: Node, schemaDocument: SchemaDocument)
   extends GlobalGroupDef(defXMLArg, seqXML, schemaDocument)
   with SequenceDefMixin {
 
   requiredEvaluationsIfActivated(checkGroupDefIsNotHiddenSequence)
 
-  private def checkGroupDefIsNotHiddenSequence: Unit = {
+  private lazy val checkGroupDefIsNotHiddenSequence: Unit = {
     if (hiddenGroupRefOption.isDefined) {
       SDE("the model group of a group definition cannot be a sequence with dfdl:hiddenGroupRef")
     }
   }
 }
 
-final class GlobalChoiceGroupDef(
+
+object GlobalChoiceGroupDef {
+  def apply(defXMLArg: Node, xml: Node, schemaDocument: SchemaDocument) = {
+    val gsgd = new GlobalChoiceGroupDef(defXMLArg, xml, schemaDocument)
+    gsgd.initialize()
+    gsgd
+  }
+}
+final class GlobalChoiceGroupDef private (
   defXMLArg: Node, choiceXML: Node, schemaDocument: SchemaDocument)
   extends GlobalGroupDef(defXMLArg, choiceXML, schemaDocument)
   with ChoiceDefMixin
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GroupRef.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GroupRef.scala
index 70341eb..e80659b 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GroupRef.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GroupRef.scala
@@ -18,7 +18,6 @@
 package org.apache.daffodil.dsom
 
 import scala.xml.Node
-import scala.xml._
 import org.apache.daffodil.dsom.walker.GroupRefView
 import org.apache.daffodil.xml.HasRefMixin
 import org.apache.daffodil.schema.annotation.props.NotFound
@@ -95,15 +94,28 @@
       SDE("Referenced group definition not found: %s", this.ref)
     }
     val gref = gdef match {
-      case gd: GlobalSequenceGroupDef => new SequenceGroupRef(gd, refXML, refLexicalParent, position, isHidden)
-      case gd: GlobalChoiceGroupDef => new ChoiceGroupRef(gd, refXML, refLexicalParent, position, isHidden)
+      case gd: GlobalSequenceGroupDef => SequenceGroupRef(gd, refXML, refLexicalParent, position, isHidden)
+      case gd: GlobalChoiceGroupDef => ChoiceGroupRef(gd, refXML, refLexicalParent, position, isHidden)
     }
     gref
   }
 }
 
-final class SequenceGroupRef(
-  globalGroupDefArg: => GlobalSequenceGroupDef,
+object SequenceGroupRef {
+  def apply(
+    globalGroupDefArg: GlobalSequenceGroupDef,
+    refXML: Node,
+    refLexicalParent: SchemaComponent,
+    positionArg: Int,
+    isHidden: Boolean) = {
+    val sgr = new SequenceGroupRef(globalGroupDefArg, refXML, refLexicalParent, positionArg, isHidden)
+    sgr.initialize()
+    sgr
+  }
+}
+
+final class SequenceGroupRef private (
+  globalGroupDefArg: GlobalSequenceGroupDef,
   refXML: Node,
   refLexicalParent: SchemaComponent,
   positionArg: Int,
@@ -127,7 +139,20 @@
 
 }
 
-final class ChoiceGroupRef(
+object ChoiceGroupRef {
+  def apply(
+    globalGroupDefArg: GlobalChoiceGroupDef,
+    refXML: Node,
+    refLexicalParent: SchemaComponent,
+    positionArg: Int,
+    isHidden: Boolean) = {
+    val cgr = new ChoiceGroupRef(globalGroupDefArg, refXML, refLexicalParent, positionArg, isHidden)
+    cgr.initialize()
+    cgr
+  }
+}
+
+final class ChoiceGroupRef private (
   globalGroupDefArg: GlobalChoiceGroupDef,
   refXML: Node,
   refLexicalParent: SchemaComponent,
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/IIBase.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/IIBase.scala
index d936608..9462ec1 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/IIBase.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/IIBase.scala
@@ -18,18 +18,20 @@
 package org.apache.daffodil.dsom
 
 import org.apache.daffodil.util.Misc
+
 import scala.xml.Node
 import scala.collection.immutable.ListMap
 import org.apache.daffodil.xml.NS
-import org.apache.daffodil.util._
-import IIUtils._
+import org.apache.daffodil.dsom.IIUtils._
+
 import java.io.File
 import java.net.URI
-import org.apache.daffodil.xml._
 import org.apache.daffodil.util.Delay
+
 import java.net.URLEncoder
 import org.apache.daffodil.api.DaffodilSchemaSource
 import org.apache.daffodil.api.URISchemaSource
+
 import java.net.URISyntaxException
 import org.apache.daffodil.api.WarnID
 
@@ -118,6 +120,8 @@
  */
 object IIUtils {
   type IIMap = Delay[ListMap[(NS, DaffodilSchemaSource), IIBase]]
+  private val empty = new ListMap[(NS, DaffodilSchemaSource), IIBase]()
+  val emptyIIMap = Delay('IIMapEmpty, this, empty).force
 }
 
 /**
@@ -140,10 +144,8 @@
    * already been seen and result in duplicate effort and slower schema
    * compilation.
    */
-  requiredEvaluationsAlways(iiSchemaFileMaybe)
-  requiredEvaluationsAlways(iiSchemaFileMaybe.map(_.iiXMLSchemaDocument))
 
-  protected final def notSeenThisBefore = LV('notSeenThisBefore) {
+  protected final lazy val notSeenThisBefore = LV('notSeenThisBefore) {
     val mp = mapPair
     val res = seenBefore.value.get(mp) match {
       case Some(_) => false
@@ -159,16 +161,16 @@
    * so that if our own includes/imports cycle back to us
    * we will detect it.
    */
-  protected final def seenBeforeThisFile: IIMap = LV('seenBeforeThisFile) {
-    val res = Delay {
-      val v = if (notSeenThisBefore) Delay(seenBefore.value + mapTuple)
-      else seenBefore
-      v.value
-    }
+  protected final lazy val seenBeforeThisFile: IIMap = LV('seenBeforeThisFile) {
+    val res = Delay('seenBeforeThisFile, this, {
+      val v = if (notSeenThisBefore) seenBefore.value + mapTuple
+      else seenBefore.value
+      v
+    })
     res
   }.value
 
-  final def seenAfter: IIMap = LV('seenAfter) {
+  final lazy val seenAfter: IIMap = LV('seenAfter) {
     val res = iiSchemaFileMaybe.map { _.seenAfter }.getOrElse(seenBefore)
     res
   }.value
@@ -235,7 +237,7 @@
 
   protected def mapPair: (NS, DaffodilSchemaSource)
 
-  protected final def mapTuple = LV('mapTuple) {
+  protected final lazy val mapTuple = LV('mapTuple) {
     val tuple = (mapPair, this)
     tuple
   }.value
@@ -260,7 +262,7 @@
    * point its namespace is not acceptable given the import
    * statement.
    */
-  final def iiSchemaFileMaybe: Option[DFDLSchemaFile] = LV('iiSchemaFileMaybe) {
+  final lazy val iiSchemaFileMaybe: Option[DFDLSchemaFile] = LV('iiSchemaFileMaybe) {
     val res = if (notSeenThisBefore) {
       Some(iiSchemaFile)
     } else None
@@ -270,7 +272,7 @@
   /**
    * Unconditionally, get the schema file object.
    */
-  final def iiSchemaFile: DFDLSchemaFile = LV('iiSchemaFile) {
+  final lazy val iiSchemaFile: DFDLSchemaFile = LV('iiSchemaFile) {
     val res = new DFDLSchemaFile(schemaSet, resolvedLocation, this, seenBeforeThisFile)
     res.node // force access to the data of the file.
     res
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Import.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Import.scala
index 037bc28..8b7bb20 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Import.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Import.scala
@@ -40,7 +40,7 @@
 final class Import(importNode: Node, xsd: XMLSchemaDocument, seenArg: IIMap)
   extends IIBase(importNode, xsd, seenArg) {
 
-  final def mapPair = LV('mapPair) {
+  final lazy val mapPair = LV('mapPair) {
     val mpOpt = importElementNS.map { ieNS => (ieNS, resolvedLocation) }
     val mp = mpOpt.getOrElse {
       //
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Include.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Include.scala
index 89cb109..3544f83 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Include.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Include.scala
@@ -35,7 +35,7 @@
 final class Include(xml: Node, xsd: XMLSchemaDocument, seenArg: IIMap)
   extends IIBase(xml, xsd, seenArg) {
 
-  protected final def mapPair = LV('mapPair) {
+  protected final lazy val mapPair = LV('mapPair) {
     // for an include, the targetNamespace of the schema document that contained us is right.
     val mp = (targetNamespace, resolvedLocation)
     mp
@@ -49,6 +49,10 @@
   lazy val resolvedLocation = LV('resolvedLocation) {
     resolvedSchemaLocation match {
       case Some(rsl) => {
+        //
+        // We use keepGoing here so we can capture diagnostics, but then
+        // issue a final summary diagnostic about the target namespace.
+        //
         val ns = OOLAG.keepGoing(
           schemaDefinitionError("Unable to determine target namespace.")) {
             xsd.targetNamespace
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/LocalElementDecl.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/LocalElementDecl.scala
index f49d2d6..14c68e7 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/LocalElementDecl.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/LocalElementDecl.scala
@@ -17,7 +17,10 @@
 
 package org.apache.daffodil.dsom
 
+import org.apache.daffodil.runtime1.LocalElementDeclBaseRuntime1Mixin
+
 import scala.xml.Node
+import scala.xml.TopScope
 
 sealed abstract class LocalElementDeclBase(
   final override val xml: Node,
@@ -26,13 +29,21 @@
   extends ElementBase
   with LocalElementComponentMixin
   with ElementDeclMixin
-  with NestingLexicalMixin {
+  with NestingLexicalMixin
+  with LocalElementDeclBaseRuntime1Mixin {
 
   requiredEvaluationsIfActivated(minOccurs)
   requiredEvaluationsIfActivated(maxOccurs)
 }
 
-class LocalElementDecl(
+object LocalElementDecl {
+  def apply(xml: Node, lexicalParent: SchemaComponent, position: Int) = {
+    val led = new LocalElementDecl(xml, lexicalParent, position)
+    led.initialize()
+    led
+  }
+}
+class LocalElementDecl private (
   xml: Node,
   lexicalParent: SchemaComponent,
   position: Int)
@@ -52,16 +63,34 @@
   lexicalParent: SchemaComponent)
   extends LocalElementDeclBase(xml, Option(lexicalParent), -1) {
 
-  override lazy val isQuasiElement = true
+  override lazy val minimizedScope = TopScope
+
+  override def isQuasiElement = true
 }
 
-class PrefixLengthQuasiElementDecl(
+object PrefixLengthQuasiElementDecl {
+  def apply(xml: Node, lexicalParent: SchemaComponent) = {
+    val pl = new PrefixLengthQuasiElementDecl(xml, lexicalParent)
+    pl.initialize()
+    pl
+  }
+}
+
+class PrefixLengthQuasiElementDecl private (
   xml: Node,
   lexicalParent: SchemaComponent)
   extends QuasiElementDeclBase(xml, lexicalParent) {
 }
 
-class RepTypeQuasiElementDecl(
+object RepTypeQuasiElementDecl {
+  def apply(xml:Node, lexicalParent: SchemaComponent) = {
+    val rt = new RepTypeQuasiElementDecl(xml, lexicalParent)
+    rt.initialize()
+    rt
+  }
+}
+
+class RepTypeQuasiElementDecl private (
   xml: Node,
   lexicalParent: SchemaComponent)
   extends QuasiElementDeclBase(xml, lexicalParent) {
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ModelGroup.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ModelGroup.scala
index 0f11c62..d4e63f5 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ModelGroup.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ModelGroup.scala
@@ -19,11 +19,10 @@
 
 import scala.xml.Node
 import scala.xml.NodeSeq.seqToNodeSeq
-import scala.xml._
 import org.apache.daffodil.exceptions.Assert
 import org.apache.daffodil.grammar.ModelGroupGrammarMixin
-import java.lang.{ Integer => JInt }
 
+import java.lang.{ Integer => JInt }
 import org.apache.daffodil.dsom.walker.ModelGroupView
 import org.apache.daffodil.schema.annotation.props.AlignmentType
 import org.apache.daffodil.schema.annotation.props.gen.AlignmentUnits
@@ -62,7 +61,9 @@
     nodesAlreadyTrying: Set[Node]): ModelGroup = {
     val childModelGroup: ModelGroup = child match {
       case <sequence>{ _* }</sequence> => {
-        val seq = new Sequence(child, lexicalParent, position) // throwaway just so we can grab local properties to check for hidden
+        // throwaway just so we can grab local properties to check for hidden, without
+        // special-case code
+        val seq = LocalSequence(child, lexicalParent, position)
         if (seq.hiddenGroupRefOption.isDefined) {
           // explicit check here, because we're about to discard this, and construct
           // a SequenceGroupRef or ChoiceGroupRef, with isHidden = true. So this
@@ -73,12 +74,12 @@
           // but set flag so it will be hidden.
           //
           val hgrXML = seq.hiddenGroupRefXML
-          ModelGroupFactory(hgrXML, lexicalParent, position, true, nodesAlreadyTrying)
+          ModelGroupFactory(hgrXML, lexicalParent, position, isHidden = true, nodesAlreadyTrying)
         } else {
-          seq
+          LocalSequence(child, lexicalParent, position)
         }
       }
-      case <choice>{ _* }</choice> => new Choice(child, lexicalParent, position)
+      case <choice>{ _* }</choice> => Choice(child, lexicalParent, position)
       case <group>{ _* }</group> => {
         val pos: Int = lexicalParent match {
           case ct: ComplexTypeBase => 1
@@ -115,10 +116,10 @@
         // be tripped up by dfdl:ref="fmt:fooey" which is a format reference.
         refProp match {
           case None => {
-            val eDecl = new LocalElementDecl(child, lexicalParent, position)
+            val eDecl = LocalElementDecl(child, lexicalParent, position)
             eDecl
           }
-          case Some(_) => new ElementRef(child, lexicalParent, position)
+          case Some(_) => ElementRef(child, lexicalParent, position)
         }
       }
       case _ => ModelGroupFactory(child, lexicalParent, position, false, nodesAlreadyTrying)
@@ -133,14 +134,18 @@
  * There are ultimately 4 concrete classes that implement this:
  * Sequence, Choice, SequenceGroupRef, and ChoiceGroupRef
  */
-abstract class ModelGroup(index: Int)
+abstract class ModelGroup protected (index: Int)
   extends Term
   with ModelGroupGrammarMixin
   with OverlapCheckMixin
   with NestingLexicalMixin
   with ModelGroupView {
 
-  requiredEvaluationsIfActivated(groupMembers)
+  protected override def initialize(): Unit = {
+    super.initialize()
+    xmlChildren
+  }
+
   requiredEvaluationsIfActivated(initiatedContentCheck)
 
   /**
@@ -203,7 +208,7 @@
 
   private def prettyIndex = "[" + index + "]" // 1-based indexing in XML/XSD
 
-  override lazy val diagnosticDebugName = prettyBaseName + prettyIndex
+  override protected lazy val diagnosticDebugNameImpl = prettyBaseName + prettyIndex
 
   override lazy val alignmentValueInBits: JInt = {
     this.alignment match {
@@ -331,7 +336,7 @@
    * any unparse events. This is used to determine next children/sibling
    * elements used during unparsing.
    */
-  final def mustHaveRequiredElement: Boolean = LV('mustHaveRequiredElement) {
+  final lazy val mustHaveRequiredElement: Boolean = LV('mustHaveRequiredElement) {
     this match {
       case gr: GroupRef if gr.isHidden => false
       case s: SequenceTermBase if s.isOrdered =>
@@ -349,13 +354,15 @@
 
   lazy val initiatedContentCheck: Unit = {
     if (initiatedContent eq YesNo.Yes) {
-      groupMembers.foreach {
-        term => {
-          term.schemaDefinitionUnless(term.hasInitiator,
-            "Enclosing group has initiatedContent='yes', but initiator is not defined.")
-          term.schemaDefinitionUnless(term.hasNonZeroLengthInitiator,
-            "Enclosing group has initiatedContent='yes', but initiator can match zero-length data.")
+      groupMembers.foreach { memberTerm =>
+        val term = memberTerm match {
+          case impliedSequence: ChoiceBranchImpliedSequence => impliedSequence.groupMembers(0)
+          case regular => regular
         }
+        term.schemaDefinitionUnless(term.hasInitiator,
+          "Enclosing group has initiatedContent='yes', but initiator is not defined.")
+        term.schemaDefinitionUnless(term.hasNonZeroLengthInitiator,
+          "Enclosing group has initiatedContent='yes', but initiator can match zero-length data.")
       }
     }
   }
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/NamedMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/NamedMixin.scala
index deaab37..ef5d77b 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/NamedMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/NamedMixin.scala
@@ -42,7 +42,7 @@
 
   def namedQName: NamedQName
 
-  override lazy val diagnosticDebugName = namedQName.diagnosticDebugName
+  override protected lazy val diagnosticDebugNameImpl = namedQName.diagnosticDebugName
 
 }
 
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Nesting.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Nesting.scala
index f30ce51..25e93d5 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Nesting.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Nesting.scala
@@ -45,7 +45,7 @@
    * The enclosing components are identified by the object, and the position of this
    * object within that enclosing component by index.
    */
-  final protected lazy val enclosingComponents: Seq[EnclosingComponentDef] = {
+  final lazy val enclosingComponents: Seq[EnclosingComponentDef] = { // Public for tests
     //
     // enclosing components is not defined for some top-level schema component objects
     //
@@ -137,6 +137,6 @@
             } // end match
           components
       }
-    result
+    result.distinct
   }
 }
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ParticleMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ParticleMixin.scala
index c75dad7..fec1f88 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ParticleMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ParticleMixin.scala
@@ -214,7 +214,7 @@
    *
    * This excludes elements that have no representation e.g., elements with dfdl:inputValueCalc.
    */
-  final def hasStaticallyRequiredOccurrencesInDataRepresentation = LV('hasStaticallyRequiredOccurrencesInDataRepresentation) {
+  final lazy val hasStaticallyRequiredOccurrencesInDataRepresentation = LV('hasStaticallyRequiredOccurrencesInDataRepresentation) {
     val res =
       if (!isRepresented) false // if there's no rep, then it's not statically required.
       else if (isScalar) true
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/PropProviders.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/PropProviders.scala
index 6757e19..0559d98 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/PropProviders.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/PropProviders.scala
@@ -130,8 +130,6 @@
 
   final lazy val leafProviders = leafProvidersArg
 
-  final lazy val diagnosticDebugName: String = "ChainPropProvider(" + forAnnotation + ")"
-
   final def chainFindProperty(pname: String): PropertyLookupResult = {
     lookupPropertyInSources(leafProviders, pname)
   }
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ReptypeMixins.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ReptypeMixins.scala
index 3d4cba3..b2526ae 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ReptypeMixins.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ReptypeMixins.scala
@@ -32,7 +32,7 @@
   override lazy val optRepTypeElement: Option[RepTypeQuasiElementDecl] =
     optRepTypeDef.map(repType => {
       val xmlElem = Elem(null, "QuasiElementForTypeCalc", new UnprefixedAttribute("type", repType.namedQName.toAttributeNameString, Null), namespaces, true)
-      new RepTypeQuasiElementDecl(xmlElem, this)
+      RepTypeQuasiElementDecl(xmlElem, this)
     })
 
 }
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 68317f7..ee68368 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
@@ -17,19 +17,21 @@
 
 package org.apache.daffodil.dsom
 
-import java.math.{ BigInteger => JBigInt, BigDecimal => JBigDecimal }
+import java.math.{ BigInteger => JBigInt }
+import java.math.{ BigDecimal => JBigDecimal }
 import org.apache.daffodil.exceptions.ThrowsSDE
 import org.apache.daffodil.exceptions.UnsuppressableException
+
 import scala.xml.Node
 import org.apache.daffodil.xml.QName
 import org.apache.daffodil.dpath.NodeInfo
 import com.ibm.icu.text.SimpleDateFormat
+
 import scala.collection.mutable.Queue
 import org.apache.daffodil.exceptions.Assert
 import com.ibm.icu.util.GregorianCalendar
 import com.ibm.icu.util.TimeZone
 import org.apache.daffodil.dpath.NodeInfo.PrimType
-import org.apache.daffodil.processors.RepValueSet
 import org.apache.daffodil.processors.RepValueSetCompiler
 import org.apache.daffodil.dsom.FacetTypes.ElemFacets
 import org.apache.daffodil.dsom.FacetTypes.FacetValue
@@ -37,31 +39,44 @@
 import org.apache.daffodil.processors.RangeBound
 import org.apache.daffodil.infoset.DataValue
 import org.apache.daffodil.infoset.DataValue.DataValueBigInt
+import org.apache.daffodil.xml.RefQName
 
+object Restriction {
+  def apply(xmlArg: Node, simpleTypeDef: SimpleTypeDefBase) = {
+    val r = new Restriction(xmlArg, simpleTypeDef)
+    r.initialize()
+    r
+  }
+}
 /**
  * A schema component for simple type restrictions
  */
-final class Restriction(xmlArg: Node, val simpleTypeDef: SimpleTypeDefBase)
+final class Restriction private (xmlArg: Node, val simpleTypeDef: SimpleTypeDefBase)
   extends SchemaComponentImpl(xmlArg, simpleTypeDef)
   with Facets
   with NestingLexicalMixin
   with TypeChecks {
 
+  protected override def initialize() = {
+    super.initialize()
+    optUnion
+  }
+
   Assert.invariant(xmlArg.asInstanceOf[scala.xml.Elem].label == "restriction")
 
-  final lazy val primType: PrimType = {
-    optDirectPrimType.getOrElse(optBaseType.get.primType)
+  lazy val primType: PrimType = {
+    optDirectPrimType.getOrElse(optBaseTypeDef.get.primType)
   }
 
   /**
    * Defined if the restriction is derived from a union
    */
-  final lazy val optUnion: Option[Union] = {
-    optBaseType.flatMap { _.optUnion }.orElse(
-      optBaseType.flatMap { _.optRestriction.flatMap { _.optUnion } })
+  lazy val optUnion: Option[Union] = {
+    optBaseTypeDef.flatMap { _.optUnion }.orElse(
+      optBaseTypeDef.flatMap { _.optRestriction.flatMap { _.optUnion } })
   }
 
-  final lazy val derivationBaseRestrictions: Seq[Restriction] = {
+  lazy val derivationBaseRestrictions: Seq[Restriction] = {
     val obt = optBaseTypeDef.toSeq
     val res = obt.flatMap {
       bt =>
@@ -71,9 +86,12 @@
     res
   }
 
-  lazy val baseQName = {
+  lazy val baseQNameString: String = {
     val baseQNameNodeSeq = xml \ "@base"
-    val baseQNameString = baseQNameNodeSeq.text
+    baseQNameNodeSeq.text
+  }
+
+  lazy val baseQName: RefQName = {
     val tryBaseQName = QName.resolveRef(baseQNameString, xml.scope,
       tunable.unqualifiedPathStepPolicy)
     schemaDefinitionUnless(tryBaseQName.isSuccess,
@@ -81,9 +99,6 @@
     tryBaseQName.get
   }
 
-  def optBaseType = optBaseTypeDef
-  def optBaseDef = optBaseTypeDef
-
   /**
    * Exclusive - restriction either has a baseType or a direct primType.
    */
@@ -100,7 +115,7 @@
     res
   }
 
-  final lazy val localBaseFacets: ElemFacets = {
+  lazy val localBaseFacets: ElemFacets = {
     val myFacets: Queue[FacetValue] = Queue.empty // val not var - it's a mutable collection
     if (localPatternValue.length > 0) { myFacets.enqueue((Facet.pattern, localPatternValue)) }
     if (localMinLengthValue.length > 0) { myFacets.enqueue((Facet.minLength, localMinLengthValue)) }
@@ -165,8 +180,8 @@
     combined.toSeq
   }
 
-  final def remoteBaseFacets = LV('remoteBaseFacets) {
-    optBaseType match {
+  final lazy val remoteBaseFacets = LV('remoteBaseFacets) {
+    optBaseTypeDef match {
       case Some(gstd) => gstd.optRestriction.toSeq.flatMap { _.combinedBaseFacets }
       case None => Nil
     }
@@ -239,14 +254,27 @@
   lazy val optLogicalValueSet: Option[RepValueSet] = if (logicalValueSet.isEmpty) None else Some(logicalValueSet)
 }
 
+object Union {
+  def apply(xmlArg: Node, simpleTypeDef: SimpleTypeDefBase) = {
+    val u = new Union(xmlArg, simpleTypeDef)
+    u.initialize()
+    u
+  }
+}
+
 /**
  * A schema component for simple type unions
  */
-final class Union(val xmlArg: Node, simpleTypeDef: SimpleTypeDefBase)
+final class Union private (val xmlArg: Node, simpleTypeDef: SimpleTypeDefBase)
   extends SchemaComponentImpl(xmlArg, simpleTypeDef)
   with NestingLexicalMixin {
   Assert.invariant(xmlArg.asInstanceOf[scala.xml.Elem].label == "union")
 
+  protected override def initialize() = {
+    super.initialize()
+    unionMemberTypes
+  }
+
   lazy val primType: NodeInfo.PrimType = {
     if (unionMemberTypes.length == 1) {
       // degenerate case of union of 1 thing IS ALLOWED by XSD
@@ -269,7 +297,7 @@
   private lazy val immediateTypeXMLs = xml \ "simpleType"
   private lazy val immediateTypes: Seq[SimpleTypeDefBase] = immediateTypeXMLs.map { node =>
     {
-      new LocalSimpleTypeDef(node, schemaDocument)
+      LocalSimpleTypeDef(node, schemaDocument)
     }
   }
 
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Root.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Root.scala
index 23de673..a4ade94 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Root.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Root.scala
@@ -17,34 +17,35 @@
 
 package org.apache.daffodil.dsom
 
-import scala.collection.mutable
 import scala.xml.Node
 import scala.xml.UnprefixedAttribute
-
 import org.apache.daffodil.dsom.walker.RootView
 import org.apache.daffodil.grammar.RootGrammarMixin
 import org.apache.daffodil.xml.NamedQName
 import org.apache.daffodil.xml.XMLUtils
 
+object Root {
+  def apply(defXML: Node,
+    parentArg: SchemaDocument,
+    namedQNameArg: NamedQName,
+    globalElementDecl: GlobalElementDecl) = {
+    val r = new Root(defXML, parentArg, namedQNameArg, globalElementDecl)
+    r.initialize()
+    r
+  }
+}
 /**
  * Root is a special kind of ElementRef that has no enclosing group.
  *
  * This is the entity that is compiled by the schema compiler.
  */
-final class Root(defXML: Node, parentArg: SchemaDocument,
+final class Root private (defXML: Node, parentArg: SchemaDocument,
   namedQNameArg: NamedQName,
   globalElementDecl: GlobalElementDecl)
   extends AbstractElementRef(null, parentArg, 1)
   with RootGrammarMixin
   with RootView {
 
-  requiredEvaluationsAlways({
-    val ac = allComponents
-    ac.foreach {
-      _.setRequiredEvaluationsActive()
-    }
-  })
-
   final override lazy val xml = {
     val elem = XMLUtils.getXSDElement(defXML.scope)
     val res = elem % new UnprefixedAttribute("ref", refQName.toQNameString, scala.xml.Null)
@@ -98,60 +99,17 @@
     }.toMap
   }
 
-  private lazy val allComponentsSet = new mutable.HashSet[SchemaComponent]
-
-  private def allSchemaComponents(component: SchemaComponent, optIndex: Option[Int]): Unit = {
-    if (allComponentsSet.contains(component)) {
-      // ok
-    } else {
-      allComponentsSet.add(component)
-      component match {
-        case aer: AbstractElementRef => {
-          val edecl = aer.referencedElement
-          allSchemaComponents(edecl, None)
-          if (!aer.isRepresented) {
-            // ok // could be inputValueCalc with typeCalc expression referring to a type.
-            // TODO: We're not finding those relationships. But typeCalc is in flux. Not sure we want to fix it.
-          }
-          if (aer.outputValueCalcOption.isDefined) {
-            // ok // could be outputValueCalc option with typeCalc expression referring to a type.
-            // TODO: We're not finding those relationships. But typeCalc is in flux. Not sure we want to fix it.
-          }
-        }
-        case edecl: ElementDeclMixin => edecl.typeDef match {
-          case std: SimpleTypeDefBase => {
-            allSchemaComponents(std, None)
-            std.bases.foreach { allSchemaComponents(_, None) }
-            std.optRepTypeDef.foreach { allSchemaComponents(_, None) }
-          }
-          case ctd: ComplexTypeBase => allSchemaComponents(ctd, None)
-          case pt: PrimitiveType => {
-            // An element decl with primitive type can still reference a simple type by way
-            // of dfdl:inputValueCalc that calls dfdlx:inputTypeCalc('QNameOfType', ....)
-            //
-            // TBD: ok for now, but needs addressing.
-          }
-        }
-        case gr: GroupRef => allSchemaComponents(gr.groupDef, None)
-        case ct: ComplexTypeBase => allSchemaComponents(ct.modelGroup, None)
-        case mg: ModelGroup => mg.groupMembers.foreach { gm =>
-          allSchemaComponents(gm, Some(gm.position))
-        }
-        case gstd: GlobalSimpleTypeDef => gstd.bases.foreach { allSchemaComponents(_, None) }
-        case gd: GlobalGroupDef => gd.groupMembers.foreach { gm =>
-          allSchemaComponents(gm, Some(gm.position))
-        }
-        case std: SimpleTypeDefBase => {
-          std.bases.foreach { allSchemaComponents(_, None) }
-        }
-      }
-    }
-  }
-
-  final lazy val allComponents = {
-    allSchemaComponents(this, None)
-    allComponentsSet.toSeq
-  }
+  /*
+   * Important: the back-pointers allowing a shared object to know what is
+   * referencing it, those are constructed from this allComponents list.
+   * This implies that no reference to those things can occur in any
+   * computation needed to construct the allComponents list.
+   *
+   * So anything using the back-pointers (eg., enclosingComponents member)
+   * or anything derived from that, is effectively in a second pass that has to
+   * happen AFTER allComponents is computed.
+   */
+  def allComponents = schemaSet.allSchemaComponents
 
   final lazy val numComponents =
     allComponents.length
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 a43e666..a142eb7 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
@@ -21,16 +21,15 @@
 import org.apache.daffodil.exceptions.Assert
 import org.apache.daffodil.xml.NS
 import org.apache.daffodil.xml.XMLUtils
-import org.apache.daffodil.processors.RuntimeData
 import org.apache.daffodil.processors.VariableMap
-import org.apache.daffodil.processors.NonTermRuntimeData
 import org.apache.daffodil.xml.ResolvesQNames
-import org.apache.daffodil.schema.annotation.props.LookupLocation
 import org.apache.daffodil.api.DaffodilTunables
 import org.apache.daffodil.xml.GetAttributesMixin
 import org.apache.daffodil.schema.annotation.props.PropTypes
 import org.apache.daffodil.util.Misc
 import org.apache.daffodil.BasicComponent
+import org.apache.daffodil.runtime1.SchemaComponentRuntime1Mixin
+import org.apache.daffodil.util.Delay
 
 abstract class SchemaComponentImpl(
   final override val xml: Node,
@@ -53,29 +52,35 @@
   with SchemaComponentIncludesAndImportsMixin
   with ResolvesQNames
   with SchemaFileLocatableImpl
-  with PropTypes {
+  with PropTypes
+  with SchemaComponentRuntime1Mixin {
+
+  override protected def initialize(): Unit = {
+    super.initialize()
+    xml
+    namespaces
+    diagnosticDebugName
+    optLexicalParent
+  }
 
   def xml: Node
 
   override def oolagContextViaArgs = optLexicalParent
 
-  requiredEvaluationsIfActivated(runtimeData)
-  requiredEvaluationsIfActivated(runtimeData.preSerializationOnlyOnce)
-
   override lazy val tunable: DaffodilTunables = optLexicalParent.get.tunable
   final override lazy val unqualifiedPathStepPolicy = tunable.unqualifiedPathStepPolicy
 
+  // FIXME: I think this should be abstract. We never need this actual object.
   lazy val dpathCompileInfo: DPathCompileInfo = {
     lazy val parents = enclosingTerms.map { _.dpathCompileInfo }
     new DPathCompileInfo(
-      parents,
+      Delay('nonElementParents, this, parents),
       variableMap,
       namespaces,
       path,
       schemaFileLocation,
       tunable.unqualifiedPathStepPolicy,
-      schemaSet.typeCalcMap,
-      runtimeData)
+      schemaSet.typeCalcMap)
   }
 
   /**
@@ -83,36 +88,10 @@
    */
   final def ci = dpathCompileInfo
 
-  /**
-   * All non-terms get runtimeData from this definition. All Terms
-   * which are elements and model-groups) override this.
-   *
-   * The Term class has a generic termRuntimeData => TermRuntimeData
-   * function (useful since all Terms share things like having charset encoding)
-   * The Element classes all inherit an elementRuntimeData => ElementRuntimeData
-   * and the model groups all have modelGroupRuntimeData => ModelGroupRuntimeData.
-   *
-   * There is also VariableRuntimeData and SchemaSetRuntimeData.
-   */
-  lazy val runtimeData: RuntimeData = nonTermRuntimeData // overrides in ModelGroup, ElementBase, SimpleTypes
-
-  final def nonTermRuntimeData = LV('nonTermRuntimeData) {
-    new NonTermRuntimeData(
-      variableMap,
-      schemaFileLocation,
-      diagnosticDebugName,
-      path,
-      namespaces,
-      tunable.unqualifiedPathStepPolicy)
-  }.value
-
-  def variableMap: VariableMap = LV('variableMap) {
+  lazy val variableMap: VariableMap = LV('variableMap) {
     schemaSet.variableMap
   }.value
 
-
-  lazy val schemaComponent: LookupLocation = this
-
   /**
    * Elements that enclose this.
    *
@@ -121,26 +100,12 @@
    */
   final lazy val enclosingElements: Seq[ElementBase] = LV('enclosingElements) {
     val ets = enclosingTerms
-    if (ets.isEmpty) {
-      // a root element (in test situations there can be several) has no enclosing term
-      val r = this.schemaSet.root
-      if (this eq r) Nil
-      else {
-        // A simpleType that is used by way of an expression like:
-        // ```dfdl:inputValueCalc="{ dfdlx:inputTypeCalc('tns:simpleTypeName', ...) }" ```
-        // Also has no enclosing terms. (Currently)
-        this match {
-          case st: GlobalSimpleTypeDef if st.optRepType.isDefined => Nil // no enclosingElements
-          case _ => {
-            // This does happen for some tests in daffodil-core
-            // That use the file example-of-most-dfdl-constructs.dfdl.xml.
-            // This may not be valid.
-            Seq(r)
-          }
-        }
-      }
+    val res = if (ets.isEmpty) {
+      // There are no enclosing terms.
+      Nil
     } else {
-      val res = ets.flatMap { et =>
+      // There ARE enclosing terms
+      val etsRes = ets.flatMap { et =>
         val ee = et match {
           case eb: ElementBase => Seq(eb)
           case sc: SchemaComponent => {
@@ -150,8 +115,9 @@
         }
         ee
       }
-      res
+      etsRes
     }
+    res.distinct
   }.value
 
   /**
@@ -172,7 +138,7 @@
         }
       }
     }
-    res
+    res.distinct
   }
 
   /**
@@ -214,7 +180,7 @@
         case sgr: SequenceGroupRef => "sgr" + (if (sgr.isHidden) "h" else "") + (if (sgr.position > 1) sgr.position else "") + "=" + sgr.groupDef.namedQName.toQNameString
         case sgd: GlobalSequenceGroupDef => "sgd=" + sgd.namedQName.toQNameString
         case cg: Choice => "c" + (if (cg.position > 1) cg.position else "")
-        case sg: Sequence => "s" + (if (sg.position > 1) sg.position else "")
+        case sg: LocalSequence => "s" + (if (sg.position > 1) sg.position else "")
         case unknown => "unk=" + Misc.getNameFromClass(unknown)
       }
     }
@@ -272,6 +238,14 @@
   }
 }
 
+object Schema {
+  def apply(namespace: NS, schemaDocs: Seq[SchemaDocument], schemaSetArg: SchemaSet) = {
+    val s = new Schema(namespace, schemaDocs, schemaSetArg)
+    s.initialize()
+    s
+  }
+}
+
 /**
  * A schema is all the schema documents sharing a single target namespace.
  *
@@ -279,15 +253,11 @@
  * same target namespace, and in that case all those schema documents make up
  * the 'schema'.
  */
-final class Schema(val namespace: NS, schemaDocs: Seq[SchemaDocument], schemaSetArg: SchemaSet)
+final class Schema private (val namespace: NS, schemaDocs: Seq[SchemaDocument], schemaSetArg: SchemaSet)
   extends SchemaComponentImpl(<fake/>, Option(schemaSetArg)) {
 
-  requiredEvaluationsAlways(schemaDocuments)
-
   override def targetNamespace: NS = namespace
 
-  override lazy val schemaDocument: SchemaDocument = Assert.usageError("schemaDocument should not be called on Schema")
-
   override lazy val schemaSet = schemaSetArg
 
   lazy val schemaDocuments = schemaDocs
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaComponentFactory.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaComponentFactory.scala
index 0e8e7f5..8738e1c 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaComponentFactory.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaComponentFactory.scala
@@ -62,9 +62,10 @@
 
   lazy val schemaFile: Option[DFDLSchemaFile] = optLexicalParent.flatMap { _.schemaFile }
   lazy val schemaSet: SchemaSet = optLexicalParent.get.schemaSet
-  def schemaDocument: SchemaDocument = optLexicalParent.get.schemaDocument
-  lazy val xmlSchemaDocument: XMLSchemaDocument = optLexicalParent.get.xmlSchemaDocument
-  lazy val schema: Schema = optLexicalParent.get.schema
+  lazy val optSchemaDocument: Option[SchemaDocument] = optLexicalParent.flatMap{ _.optSchemaDocument }
+  final def schemaDocument: SchemaDocument = optSchemaDocument.get
+  lazy val optXMLSchemaDocument: Option[XMLSchemaDocument] = optLexicalParent.flatMap{ _.optXMLSchemaDocument }
+  final def xmlSchemaDocument: XMLSchemaDocument = optXMLSchemaDocument.get
   def uriString: String = optLexicalParent.get.uriString
 
   def xml: scala.xml.Node
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaComponentIncludesAndImportsMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaComponentIncludesAndImportsMixin.scala
index 56d8130..d26aa9e 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaComponentIncludesAndImportsMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaComponentIncludesAndImportsMixin.scala
@@ -30,9 +30,9 @@
    * Used in diagnostic messages; hence, valueOrElse to avoid
    * problems when this can't get a value due to an error.
    */
-  override def uriString: String = uriString_.toOption.getOrElse(orElseURL)
-  private def uriString_ = LV('fileName) {
+  override def uriString: String = uriString_
+  private lazy val uriString_ = LV('fileName) {
     xmlSchemaDocument.uriString
-  }
+  }.toOption.getOrElse(orElseURL)
 
 }
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaDocIncludesAndImportsMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaDocIncludesAndImportsMixin.scala
index b4889fe..c117163 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaDocIncludesAndImportsMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaDocIncludesAndImportsMixin.scala
@@ -59,7 +59,7 @@
    * namespace (if found) on the xs:schema of this schema document must match
    * that of the import statement. If a namespace is specified there.
    */
-  override def targetNamespace: NS = LV('targetNamespace) {
+  override lazy val targetNamespace: NS = LV('targetNamespace) {
     val checkedNS =
       ii.map {
         _ match {
@@ -117,7 +117,7 @@
     this.uriStringFromAttribute.getOrElse("file:unknown")
   }
 
-  def seenBefore: IIMap
+  protected def seenBefore: IIMap
 
   // val iiXML: Node = xml // override in SchemaSet
 
@@ -154,14 +154,14 @@
 
   def importStatementsMap = ismli_._1
   def localImports = ismli_._2
-  private def ismli_ = LV('importStatementsMap_localImports) {
+  private lazy val ismli_ = LV('importStatementsMap_localImports) {
     val res = getImportsOrIncludes(seenBefore, impNodes, new Import(_, _, _))
     res
   }.value
 
   def seenAfter = sali_._1
   def localIncludes = sali_._2
-  private def sali_ = LV('seenAfter_localIncludes) {
+  private lazy val sali_ = LV('seenAfter_localIncludes) {
     val res = getImportsOrIncludes(importStatementsMap, incNodes, new Include(_, _, _))
     res
   }.value
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaDocument.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaDocument.scala
index 3ee2a2b..b45147f 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaDocument.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaDocument.scala
@@ -44,12 +44,25 @@
  * a schema component was defined within.
  */
 
+object XMLSchemaDocument {
+  def apply(xmlArg: Node,
+    schemaSetArg: SchemaSet,
+    ii: Option[IIBase],
+    sfArg: Option[DFDLSchemaFile],
+    seenBeforeArg: IIMap,
+    isBootStrapSD: Boolean) = {
+    val xsd = new XMLSchemaDocument(xmlArg, schemaSetArg, ii, sfArg, seenBeforeArg, isBootStrapSD)
+    xsd.initialize()
+    xsd
+  }
+}
+
 /**
  * Handles everything about schema documents that has nothing to
  * do with DFDL. Things like namespace, include, import, elementFormDefault
  * etc.
  */
-final class XMLSchemaDocument(
+final class XMLSchemaDocument private (
   xmlArg: Node,
   schemaSetArg: SchemaSet,
 
@@ -70,10 +83,10 @@
 
   requiredEvaluationsAlways(checkUnsupportedAttributes)
 
-  final lazy val seenBefore = seenBeforeArg
+  final protected lazy val seenBefore = seenBeforeArg
 
   final override lazy val schemaFile = sfArg
-  final override lazy val xmlSchemaDocument = this
+  final override lazy val optXMLSchemaDocument = Some(this)
 
   /**
    * Error checks on the xs:schema element itself.
@@ -102,7 +115,7 @@
     else qualOrUnqual(afdAttr, "attribute")
   }
 
-  final def checkUnsupportedAttributes = LV('checkUnsupportedAttributes) {
+  final lazy val checkUnsupportedAttributes = LV('checkUnsupportedAttributes) {
     val hasSchemaLocation = (xml \ "@schemaLocation").text != ""
     val hasBlockDefault = (xml \ "@blockDefault").text != ""
     val hasFinalDefault = (xml \ "@finalDefault").text != ""
@@ -156,45 +169,43 @@
   lazy val isDFDLSchema = hasDFDLNamespaceDefinition
 }
 
+object SchemaDocument {
+  def apply (xmlSDoc: XMLSchemaDocument) = {
+    val sd = new SchemaDocument(xmlSDoc)
+    sd.initialize()
+    sd
+  }
+}
 /**
  * Handles only things specific to DFDL about schema documents.
  *
  * I.e., default format properties, named format properties, etc.
  */
-final class SchemaDocument(xmlSDoc: XMLSchemaDocument)
+final class SchemaDocument private (xmlSDoc: XMLSchemaDocument)
   extends AnnotatedSchemaComponent {
 
+  protected override def initialize() = {
+    super.initialize()
+  }
+
   final override val xml = xmlSDoc.xml
-  final override def optLexicalParent = Option(xmlSDoc)
-  final override lazy val xmlSchemaDocument = xmlSDoc
+  final override lazy val optLexicalParent = Some(xmlSDoc)
+  final override lazy val optXMLSchemaDocument = Some(xmlSDoc)
 
   override lazy val optReferredToComponent = None
 
-  /**
-   * Implements the selectivity so that if you specify a root element
-   * to the compiler, then only that root element (and things reached from it)
-   * is compiled. Otherwise all top level elements are compiled.
-   */
-  requiredEvaluationsAlways(defaultFormat)
-  if (schemaSet.checkAllTopLevel) {
-    requiredEvaluationsAlways(globalElementDecls.foreach{ _.setRequiredEvaluationsActive() })
-    requiredEvaluationsAlways(defineEscapeSchemes)
-    requiredEvaluationsAlways(defineFormats)
-    requiredEvaluationsAlways(defineVariables)
-  }
+  override lazy val optSchemaDocument = Some(this)
 
-  override lazy val schemaDocument = this
-
-  override lazy val schema = schemaSet.getSchema(targetNamespace).getOrElse {
+  lazy val schema = schemaSet.getSchema(targetNamespace).getOrElse {
     Assert.invariantFailed("schema not found for schema document's namespace.")
   }
 
   protected def annotationFactory(node: Node): Option[DFDLAnnotation] = {
     val res = node match {
-      case <dfdl:format>{ content @ _* }</dfdl:format> => new DFDLFormat(node, this)
-      case <dfdl:defineFormat>{ content @ _* }</dfdl:defineFormat> => new DFDLDefineFormat(node, this)
-      case <dfdl:defineEscapeScheme>{ content @ _* }</dfdl:defineEscapeScheme> => new DFDLDefineEscapeSchemeFactory(node, this)
-      case <dfdl:defineVariable>{ content @ _* }</dfdl:defineVariable> => new DFDLDefineVariable(node, this)
+      case <dfdl:format>{ content @ _* }</dfdl:format> => DFDLFormat(node, this)
+      case <dfdl:defineFormat>{ content @ _* }</dfdl:defineFormat> => DFDLDefineFormat(node, this)
+      case <dfdl:defineEscapeScheme>{ content @ _* }</dfdl:defineEscapeScheme> => DFDLDefineEscapeSchemeFactory(node, this)
+      case <dfdl:defineVariable>{ content @ _* }</dfdl:defineVariable> => DFDLDefineVariable(node, this)
       case _ => {
         val prefix =
           if (node.prefix == null || node.prefix == "") ""
@@ -205,16 +216,16 @@
     Some(res)
   }
 
-  protected lazy val emptyFormatFactory = new DFDLFormat(newDFDLAnnotationXML("format"), this)
+  protected lazy val emptyFormatFactory = DFDLFormat(newDFDLAnnotationXML("format"), this)
   protected def isMyFormatAnnotation(a: DFDLAnnotation) = a.isInstanceOf[DFDLFormat]
 
   lazy val globalElementDecls = {
     val xmlelts = (xml \ "element")
-    val decls = xmlelts.map { new GlobalElementDecl(_, this) }
+    val decls = xmlelts.map { GlobalElementDecl(_, this) }
     decls
   }
-  lazy val globalSimpleTypeDefs = (xml \ "simpleType").map { new GlobalSimpleTypeDef(_, this) }
-  lazy val globalComplexTypeDefs = (xml \ "complexType").map { new GlobalComplexTypeDef(_, this) }
+  lazy val globalSimpleTypeDefs = (xml \ "simpleType").map { GlobalSimpleTypeDef(_, this) }
+  lazy val globalComplexTypeDefs = (xml \ "complexType").map { GlobalComplexTypeDef(_, this) }
   lazy val globalGroupDefs = (xml \ "group").map { GlobalGroupDef(_, this) }
 
   lazy val defaultFormat = formatAnnotation.asInstanceOf[DFDLFormat]
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaSet.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaSet.scala
index a3345fb..f4224a5 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaSet.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaSet.scala
@@ -27,8 +27,8 @@
 import org.apache.daffodil.oolag.OOLAG
 import org.apache.daffodil.exceptions.ThrowsSDE
 import org.apache.daffodil.dpath.NodeInfo
-import java.io.File
 
+import java.io.File
 import org.apache.daffodil.xml.DFDLCatalogResolver
 import org.apache.daffodil.api.DaffodilSchemaSource
 import org.apache.daffodil.api.UnitTestSchemaSource
@@ -38,9 +38,38 @@
 import org.apache.daffodil.processors.TypeCalculatorCompiler.TypeCalcMap
 import org.apache.daffodil.grammar.Gram
 import org.apache.daffodil.grammar.SchemaSetGrammarMixin
+import org.apache.daffodil.util.TransitiveClosure
 
 import scala.collection.immutable.Queue
 
+object SchemaSet {
+  def apply(
+    optPFRootSpec: Option[RootSpec],
+  schemaSource: DaffodilSchemaSource,
+  shouldValidateDFDLSchemas: Boolean,
+  checkAllTopLevel: Boolean,
+  tunables: DaffodilTunables,
+  compilerExternalVarSettings: Queue[Binding]) = {
+    val ss = new SchemaSet(optPFRootSpec,
+      schemaSource,
+      shouldValidateDFDLSchemas,
+      checkAllTopLevel,
+      tunables,
+      compilerExternalVarSettings)
+    ss.initialize()
+    ss
+  }
+
+  def apply(sch: Node,
+    rootNamespace: String = null,
+    root: String = null,
+    optTmpDir: Option[File] = None,
+    tunableOpt: Option[DaffodilTunables] = None) = {
+    val ss = new SchemaSet(sch, rootNamespace, root, optTmpDir, tunableOpt)
+    ss.initialize()
+    ss
+  }
+}
 /**
  * A schema set is exactly that, a set of schemas. Each schema has
  * a target namespace (or 'no namespace'), so a schema set is
@@ -62,10 +91,10 @@
  * schema components obviously it does not live within a schema document.
  */
 
-final class SchemaSet(
+final class SchemaSet private (
   optPFRootSpec: Option[RootSpec],
   val schemaSource: DaffodilSchemaSource,
-  val validateDFDLSchemas: Boolean,
+  val shouldValidateDFDLSchemas: Boolean,
   val checkAllTopLevel: Boolean,
   val tunables: DaffodilTunables,
   protected val compilerExternalVarSettings: Queue[Binding])
@@ -73,6 +102,10 @@
   with SchemaSetIncludesAndImportsMixin
   with SchemaSetGrammarMixin {
 
+  override protected def initialize(): Unit = {
+    // no normal schema component initialization for SchemaSet
+  }
+
   /**
    * Used to count instances of element base objects created by
    * compiler - to be sure we're not duplicating them unnecessarily.
@@ -87,22 +120,16 @@
 
   override lazy val tunable = tunables
 
-  requiredEvaluationsAlways(isValid)
   requiredEvaluationsAlways(typeCalcMap)
   requiredEvaluationsAlways(root)
-
-  if (checkAllTopLevel) {
-    requiredEvaluationsAlways(checkForDuplicateTopLevels())
-    requiredEvaluationsAlways(this.allTopLevels)
-  }
-
+  requiredEvaluationsAlways(checkForDuplicateTopLevels())
 
   lazy val resolver = DFDLCatalogResolver.get
 
   override lazy val schemaSet = this
 
-  override lazy val schemaDocument = Assert.usageError("schemaDocument should not be called on SchemaSet")
-  override lazy val xmlSchemaDocument = Assert.usageError("xmlSchemaDocument should not be called on SchemaSet")
+  override lazy val optSchemaDocument = None
+  override lazy val optXMLSchemaDocument = None
 
   override lazy val lineAttribute: Option[String] = None
 
@@ -115,12 +142,13 @@
   override lazy val uriString: String = schemaSource.uriForLoading.toString
 
   override def warn(th: Diagnostic) = oolagWarn(th)
+
   override def error(th: Diagnostic) = oolagError(th)
 
   /**
    * This constructor for unit testing only
    */
-  def this(sch: Node, rootNamespace: String = null, root: String = null, optTmpDir: Option[File] = None, tunableOpt: Option[DaffodilTunables] = None) =
+  private def this(sch: Node, rootNamespace: String = null, root: String = null, optTmpDir: Option[File] = None, tunableOpt: Option[DaffodilTunables] = None) =
     this(
       {
         if (root == null) None else {
@@ -136,11 +164,19 @@
 
   lazy val schemaFileList = schemas.map(s => s.uriString)
 
-  lazy val isValid = {
+  private lazy val isValid: Boolean = {
+    //
+    // We use keepGoing here, because we want to gather a validation error,
+    // suppress further propagation of it, and return false.
+    //
     val isV = OOLAG.keepGoing(false) {
       val files = allSchemaFiles
-      val fileValids = files.map { _.isValid }
-      val res = fileValids.length > 0 && fileValids.fold(true) { _ && _ }
+      val fileValids = files.map {
+        _.isValid
+      }
+      val res = fileValids.length > 0 && fileValids.fold(true) {
+        _ && _
+      }
       res
     }
     isV
@@ -148,11 +184,13 @@
 
   lazy val validationDiagnostics = {
     val files = allSchemaFiles
-    val res = files.flatMap { _.validationDiagnostics }
+    val res = files.flatMap {
+      _.validationDiagnostics
+    }
     res
   }
 
-  lazy val schemas: Seq[Schema] = LV('schemas) {
+  lazy val schemas: Seq[Schema] = {
     val schemaPairs = allSchemaDocuments.map { sd => (sd.targetNamespace, sd) }
     //
     // groupBy is deterministic if the hashCode of the key element is deterministic.
@@ -160,37 +198,29 @@
     //
     // Alas, being deterministic doesn't mean it is in an order we expect.
     // but at least it is deterministic.
-    val schemaGroups = schemaPairs.groupBy { _._1 } // group by the namespace identifier
+    val schemaGroups = schemaPairs.groupBy {
+      _._1
+    } // group by the namespace identifier
     val schemas = schemaGroups.map {
       case (ns, pairs) => {
         val sds = pairs.map { case (ns, s) => s }
-        val sch = new Schema(ns, sds.toSeq, this)
+        val sch = Schema(ns, sds.toSeq, this)
         sch
       }
     }
     schemas.toSeq
-  }.value
+  }
 
   lazy val globalSimpleTypeDefs: Seq[GlobalSimpleTypeDef] = schemas.flatMap(_.globalSimpleTypeDefs)
 
   /**
-   * The global simple type definitions that are reachable from the root element.
-   */
-  lazy val inUseGlobalSimpleTypeDefs: Seq[GlobalSimpleTypeDef] =
-    // TODO: This isn't going to work for elements that reference a repType via
-    // a calculation such as dfdl:inputValueCalc expression that references a type name.
-    // Expressions need to be analyzed for these type names so that the reference can be
-    // added to the allComponents list, and the reverse mapping from shared types to uses of them
-    // also needs to be maintained.
-    // However.... since typeCalc is in flux, not clear we want to fix this.
-    root.allComponents.collect { case gstd: GlobalSimpleTypeDef => gstd }
-
-  /**
-   * For the in-use simple types defs, get those that particpate
+   * For simple types defs, get those that particpate
    * in type calculation.
    */
   lazy val typeCalcMap: TypeCalcMap = {
-    val factories = globalSimpleTypeDefs // inUseGlobalSimpleTypeDefs // FIXME: Hack to just take all global simple type defs for now. Not just "in use".
+    // Just take all global simple type defs for now. Not just "in use".
+    // filter them by whether they have a typeCalculator
+    val factories = globalSimpleTypeDefs
     val withCalc = factories.filter(_.optTypeCalculator.isDefined)
     val mappings = withCalc.map(st => (st.globalQName, st.optTypeCalculator.get))
     mappings.toMap
@@ -202,68 +232,66 @@
 
   private type UC = (NS, String, Symbol, GlobalComponent)
 
-  private def allTopLevels: Seq[UC] = LV('allTopLevels) {
-    val res = schemas.flatMap { schema =>
-      {
-        val ns = schema.namespace
-        val geds = schema.globalElementDecls.map { g =>
-          {
-            (ns, g.name, 'Element, g)
-          }
-        }
-        val stds = schema.globalSimpleTypeDefs.map { g =>
-          {
-            (ns, g.name, 'SimpleType, g)
-          }
-        }
-        val ctds = schema.globalComplexTypeDefs.map { g =>
-          {
-            (ns, g.name, 'ComplexType, g)
-          }
-        }
-        val gds = schema.globalGroupDefs.map { g =>
-          {
-            (ns, g.name, 'Group, g)
-          }
-        }
-        val dfs = schema.defineFormats.map { g =>
-          {
-            (ns, g.name, 'DefineFormat, g)
-          }
-        }
-        val dess = schema.defineEscapeSchemes.map { g =>
-          {
-            (ns, g.name, 'DefineEscapeScheme, g)
-          }
-        }
-        val dvs = schema.defineVariables.map { g =>
-          {
-            (ns, g.name, 'DefineVariable, g)
-          }
-        }
-        val all = geds ++ stds ++ ctds ++ gds ++ dfs ++ dess ++ dvs
-        all
+  private lazy val allTopLevels: Seq[UC] = LV('allTopLevels) {
+    val res = schemas.flatMap { schema => {
+      val ns = schema.namespace
+      val geds = schema.globalElementDecls.map { g => {
+        (ns, g.name, 'Element, g)
       }
+      }
+      val stds = schema.globalSimpleTypeDefs.map { g => {
+        (ns, g.name, 'SimpleType, g)
+      }
+      }
+      val ctds = schema.globalComplexTypeDefs.map { g => {
+        (ns, g.name, 'ComplexType, g)
+      }
+      }
+      val gds = schema.globalGroupDefs.map { g => {
+        (ns, g.name, 'Group, g)
+      }
+      }
+      val dfs = schema.defineFormats.map { g => {
+        (ns, g.name, 'DefineFormat, g)
+      }
+      }
+      val dess = schema.defineEscapeSchemes.map { g => {
+        (ns, g.name, 'DefineEscapeScheme, g)
+      }
+      }
+      val dvs = schema.defineVariables.map { g => {
+        (ns, g.name, 'DefineVariable, g)
+      }
+      }
+      val all = geds ++ stds ++ ctds ++ gds ++ dfs ++ dess ++ dvs
+      all
+    }
     }
     res.asInstanceOf[Seq[UC]]
   }.value
 
-  private def groupedTopLevels = LV('groupedTopLevels) {
+  private lazy val groupedTopLevels = LV('groupedTopLevels) {
     val grouped = allTopLevels.groupBy {
       case (ns, name, kind, obj) => {
         (kind, ns, name)
       }
     }
     val grouped2 = grouped.map {
-      case (idFields, seq) => {
-        val onlyObj = seq.map { case (ns, name, kind, obj) => obj }
-        if (onlyObj.length > 1) {
-          val (ns, name, kind) = idFields
-          val locations = onlyObj.asInstanceOf[Seq[LookupLocation]] // don't like this downcast
-          SDEButContinue("multiple definitions for %s  {%s}%s.\n%s", kind.toString, ns, name,
-            locations.map { _.locationDescription }.mkString("\n"))
+      case (idFields @ (kind, ns, name), seq) => {
+        val locations = seq.map {
+          case (_, _, _, obj: LookupLocation) => obj
+          case _ => Assert.invariantFailed("not (ns, name, kind, lookuplocation)")
         }
-        (idFields, onlyObj)
+        if (locations.length > 1) {
+          SDEButContinue("multiple definitions for %s %s%s.\n%s",
+            kind.name.toString,
+            (if (ns eq NoNamespace) "" else "{" + ns.toString + "}"),
+            name,
+            locations.map {
+              _.locationDescription
+            }.mkString("\n"))
+        }
+        (idFields, locations)
       }
     }
     val res = grouped2.flatMap { case (_, topLevelThing) => topLevelThing }.toSeq
@@ -283,15 +311,16 @@
    * unambiguous, it is used as the root.
    */
   private def findRootElement(name: String) = {
-    val candidates = schemas.flatMap { _.getGlobalElementDecl(name) }
+    val candidates = schemas.flatMap {
+      _.getGlobalElementDecl(name)
+    }
     schemaDefinitionUnless(candidates.length != 0, "No root element found for %s in any available namespace", name)
     schemaDefinitionUnless(candidates.length <= 1, "Root element %s is ambiguous. Candidates are %s.", name,
-      candidates.map { gef =>
-        {
-          val tns = gef.schemaDocument.targetNamespace
-          Assert.invariant(!tns.isUnspecified)
-          gef.name + " " + tns.explainForMsg
-        }
+      candidates.map { gef => {
+        val tns = gef.schemaDocument.targetNamespace
+        Assert.invariant(!tns.isUnspecified)
+        gef.name + " " + tns.explainForMsg
+      }
       })
     Assert.invariant(candidates.length == 1)
     val ge = candidates(0)
@@ -307,7 +336,9 @@
       case RootSpec(Some(rootNamespaceName), rootElementName) => {
         val qn = RefQName(None, rootElementName, rootNamespaceName)
         val optGE = getGlobalElementDecl(qn)
-        val ge = optGE.getOrElse { schemaDefinitionError("No global element found for %s", rootSpec) }
+        val ge = optGE.getOrElse {
+          schemaDefinitionError("No global element found for %s", rootSpec)
+        }
         ge
       }
       case RootSpec(None, rootElementName) => {
@@ -368,31 +399,45 @@
    */
   def getGlobalElementDecl(refQName: RefQName) = {
     val s = getSchema(refQName.namespace)
-    val res = s.flatMap { s =>
-      {
-        val ged = s.getGlobalElementDecl(refQName.local)
-        ged
-      }
+    val res = s.flatMap { s => {
+      val ged = s.getGlobalElementDecl(refQName.local)
+      ged
+    }
     }
     res
   }
-  def getGlobalSimpleTypeDef(refQName: RefQName) = getSchema(refQName.namespace).flatMap { _.getGlobalSimpleTypeDef(refQName.local) }
-  def getGlobalComplexTypeDef(refQName: RefQName) = getSchema(refQName.namespace).flatMap { _.getGlobalComplexTypeDef(refQName.local) }
-  def getGlobalGroupDef(refQName: RefQName) = getSchema(refQName.namespace).flatMap { _.getGlobalGroupDef(refQName.local) }
+
+  def getGlobalSimpleTypeDef(refQName: RefQName) = getSchema(refQName.namespace).flatMap {
+    _.getGlobalSimpleTypeDef(refQName.local)
+  }
+
+  def getGlobalComplexTypeDef(refQName: RefQName) = getSchema(refQName.namespace).flatMap {
+    _.getGlobalComplexTypeDef(refQName.local)
+  }
+
+  def getGlobalGroupDef(refQName: RefQName) = getSchema(refQName.namespace).flatMap {
+    _.getGlobalGroupDef(refQName.local)
+  }
 
   /**
    * DFDL Schema top-level global objects
    */
   def getDefineFormat(refQName: RefQName) = {
     val s = getSchema(refQName.namespace)
-    s.flatMap { _.getDefineFormat(refQName.local) }
+    s.flatMap {
+      _.getDefineFormat(refQName.local)
+    }
   }
+
   def getDefineFormats(namespace: NS, context: ThrowsSDE) = getSchema(namespace) match {
     case None => context.schemaDefinitionError("Failed to find a schema for namespace:  " + namespace)
     case Some(sch) => sch.getDefineFormats()
   }
+
   def getDefineVariable(refQName: RefQName) = {
-    val res = getSchema(refQName.namespace).flatMap { _.getDefineVariable(refQName.local) }
+    val res = getSchema(refQName.namespace).flatMap {
+      _.getDefineVariable(refQName.local)
+    }
     val finalResult = res match {
       case None => {
         val optRes = this.predefinedVars.find(dfv => {
@@ -404,14 +449,19 @@
     }
     finalResult
   }
-  def getDefineEscapeScheme(refQName: RefQName) = getSchema(refQName.namespace).flatMap { _.getDefineEscapeScheme(refQName.local) }
+
+  def getDefineEscapeScheme(refQName: RefQName) = getSchema(refQName.namespace).flatMap {
+    _.getDefineEscapeScheme(refQName.local)
+  }
 
   def getPrimitiveType(refQName: RefQName) = {
     if (refQName.namespace != XMLUtils.XSD_NAMESPACE) // must check namespace
       None
     else {
       val optPrimNode = NodeInfo.PrimType.fromNameString(refQName.local)
-      optPrimNode.map { PrimitiveType(_) }
+      optPrimNode.map {
+        PrimitiveType(_)
+      }
     }
   }
 
@@ -420,16 +470,16 @@
    *
    * @param theName The variable name.
    * @param theType The type of the variable. ex. xs:string
-   * @param nsURI The namespace URI of the variable.
-   *
+   * @param nsURI   The namespace URI of the variable.
    * @return A Seq[DFDLDefineVariable]
    */
   private def generateDefineVariable(theName: String, theType: String, theDefaultValue: String, nsURI: String, sdoc: SchemaDocument) = {
-    val dfv = new DFDLDefineVariable(
-      <dfdl:defineVariable name={ theName } type={ theType } defaultValue={ theDefaultValue } external="true" xmlns:xs={ XMLUtils.XSD_NAMESPACE.toString }/>, sdoc) {
-      override lazy val namespace = NS(nsURI)
-      override lazy val targetNamespace = NS(nsURI)
-    }
+    val dfv = DFDLDefineVariable(
+        <dfdl:defineVariable name={theName}
+                             type={theType}
+                             defaultValue={theDefaultValue}
+                             external="true"
+                             xmlns:xs={XMLUtils.XSD_NAMESPACE.toString}/>, sdoc, nsURI)
     dfv
   }
 
@@ -463,46 +513,177 @@
     Seq(encDFV, boDFV, binDFV, outDFV)
   }
 
-  lazy val allDefinedVariables = schemas.flatMap{ _.defineVariables }
-  lazy val allExternalVariables = allDefinedVariables.filter{ _.external }
+  lazy val allDefinedVariables = schemas.flatMap {
+    _.defineVariables
+  }
+  lazy val allExternalVariables = allDefinedVariables.filter {
+    _.external
+  }
 
   private lazy val checkUnusedProperties = LV('hasUnusedProperties) {
     root.checkUnusedProperties
   }.value
 
-  override def isError = {
+  /**
+   * Asking if there are errors drives compilation. First the schema is validated, then
+   * the abstract syntax tree is constructed (which could be a source of errors)
+   * and finally the AST objects are checked for errors, which recursively
+   * demands that all other aspects of compilation occur.
+   */
+  override def isError: Boolean = {
+    if (!isValid) true
+    else if (
+    // use keepGoing so we can capture errors and
+    // return true (indicating there is an error)
+    //
       OOLAG.keepGoing(true) {
-        val valid = isValid
-        if (valid) {
-          // no point in going forward with more
-          // checks if the schema isn't valid
-          // The code base is written assuming valid
-          // schema input. It's just going to hit
-          // assertion failures and such if we
-          // try to compile invalid schemas.
-          val hasErrors = super.isError
-          if (!hasErrors) {
-            // only check for unused properties if there are no errors
-            checkUnusedProperties
-          }
-          hasErrors
-        } else true
+        !areComponentsConstructed
+      }) true
+    else {
+      val hasErrors = super.isError
+      if (!hasErrors) {
+        // must be last, after all compilation is done.
+        // only check this if there are no errors.
+        checkUnusedProperties
       }
+      hasErrors
+    }
+  }
+
+  /**
+   * Creation of the DSOM tree of components
+   *
+   * Assumes schema files exist and are valid.
+   *
+   * As DSOM objects are constructed, the factory pattern assures
+   * that initialize() is called. This demands the basic fields that
+   * are needed for diagnostic messages describing error contexts.
+   *
+   * Then we start from the root set of schema components, and construct
+   * all children reachable from them. We "activate" these so that the
+   * OOLAG requiredEvaluationsIfActive will execute for these components
+   * as a part of SchemaSet.isError (but that execution of those required
+   * evaluations happens later).
+   *
+   * Then we construct the refMap. This is the core data structure allowing
+   * shared objects to access all the contexts where they are used.
+   *
+   * Some LVs like enclosingComponents depend on the refMap, so those cannot
+   * be evaluated until this point.
+   *
+   * Once the refMap is constructed, we are done "construcing" the components.
+   *
+   * An important characteristic here is that everything we invoke here is
+   * downward looking. None of it involves looking upward at enclosing components
+   * with the exception of the unique lexical parent.
+   *
+   * A challenge is that often quite sophisticated analysis is required in order
+   * to determine the child components. E.g., one must analyze length-kind to
+   * know if a prefix-length quasi-element component is needed. The lengthKind
+   * property can be scoped, hence, all the machinery associated with scoped
+   * lookup of properties is part of establishing the tree/graph of components.
+   * That said, it is a goal to do minimal other work here. Just create all the
+   * components.
+   *
+   * Inability to resolve a QName reference is a fatal error, and no attempt to continue
+   * processing accumulating more errors is required in that situation.
+   *
+   * @return true if the components are all constructed with their interconnections.
+   *         false with diagnostics accumulated otherwise.
+   */
+  private lazy val areComponentsConstructed: Boolean = LV('areComponentsConstructed) {
+    allSchemaFiles
+    allSchemaDocuments
+    schemas
+    allSchemaComponents // recursively constructs all the objects.
+    allSchemaComponents.foreach{ _.setRequiredEvaluationsActive() }
+    root.refMap
+    true
+  }.value
+
+
+  private lazy val startingGlobalComponents: Seq[SchemaComponent] = {
+    root +: {
+      // always need the simple type defs so we can ask for their
+      // repTypeElements as part of constructing the complete object graph.
+      // The inputTypeCalc/outputTypeCalc functions take
+      // The QName of a simple type. By just always obtaining all the simple types defs
+      // we insure the quasi-elements used by them are always constructed, and names
+      // are resolvable.
+      allSchemaDocuments.flatMap { sd: SchemaDocument =>
+        sd.globalSimpleTypeDefs
+      } ++ {
+        if (this.checkAllTopLevel)
+          allSchemaDocuments.flatMap { sd: SchemaDocument =>
+            sd.defaultFormat // just demand this since it should be possible to create it.
+              sd.globalElementDecls ++
+              sd.globalComplexTypeDefs ++
+              sd.globalGroupDefs
+          }
+        else
+          Nil
+      }
+    }
+  }
+
+  private lazy val allSchemaComponentsSet = TransitiveClosureSchemaComponents(startingGlobalComponents)
+
+  lazy val allSchemaComponents = allSchemaComponentsSet.toIndexedSeq
+}
+
+object TransitiveClosureSchemaComponents {
+  def apply(ssc: Seq[SchemaComponent]) =
+    (new TransitiveClosureSchemaComponents())(ssc)
+}
+
+class TransitiveClosureSchemaComponents private() extends TransitiveClosure[SchemaComponent] {
+
+  type SSC = Seq[SchemaComponent]
+
+  override protected def func(sc: SchemaComponent) = {
+    val referents: SSC = sc match {
+      case asc: AnnotatedSchemaComponent => asc.optReferredToComponent.toSeq
+      case _ => Nil
+    }
+    val children: SSC = sc match {
+      case er: AbstractElementRef => Nil // already have referents above.
+      case e: ElementDeclMixin => e.typeDef match {
+        case std: SimpleTypeDefBase => Seq(std)
+        case ctd: ComplexTypeBase => Seq(ctd)
+        case pt: PrimitiveType => {
+          // An element decl with primitive type can still reference a simple type by way
+          // of dfdl:inputValueCalc that calls dfdlx:inputTypeCalc('QNameOfType', ....)
+          //
+          // This is covered because the QNameOfType must be a GlobalSimpleTypeDef and
+          // those will always be part of all components and their type calcs will be
+          // checked.
+          Nil
+        }
+      }
+      case m: ModelGroup => m.groupMembers
+      case st: SimpleTypeDefBase =>
+        st.bases ++
+          st.optRestriction ++
+          st.optUnion ++
+          st.optRepTypeDef ++
+          st.optRepTypeElement
+      case r: Restriction => r.optUnion.toSeq
+      case u: Union => u.unionMemberTypes
+      case c: ComplexTypeBase => Seq(c.modelGroup)
+      case gd: GlobalGroupDef => gd.groupMembers
+      case stmt: DFDLStatement => Nil
+    }
+    val statements: SSC = sc match {
+      case t: Term => t.statements
+      case _ => Nil
+    }
+    val misc: SSC = sc match {
+      case eb: ElementBase => eb.optPrefixLengthElementDecl.toSeq
+      case ch: ChoiceTermBase => ch.optRepTypeElement.toSeq
+      case _ => Seq()
+    }
+
+    referents ++ children ++ statements ++ misc
   }
 }
 
-
-class ValidateSchemasErrorHandler(sset: SchemaSet) extends org.xml.sax.ErrorHandler {
-
-  def warning(exception: org.xml.sax.SAXParseException) = {
-    val sdw = new SchemaDefinitionWarning(sset.schemaFileLocation, "Warning loading schema due to %s", exception)
-    sset.warn(sdw)
-  }
-
-  def error(exception: org.xml.sax.SAXParseException) = {
-    val sde = new SchemaDefinitionError(sset.schemaFileLocation, "Error loading schema due to %s", exception)
-    sset.error(sde)
-  }
-
-  def fatalError(exception: org.xml.sax.SAXParseException) = this.error(exception)
-}
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaSetIncludesAndImportsMixins.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaSetIncludesAndImportsMixins.scala
index 249c9a8..6d8e8b6 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaSetIncludesAndImportsMixins.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaSetIncludesAndImportsMixins.scala
@@ -17,11 +17,8 @@
 
 package org.apache.daffodil.dsom
 
-import scala.collection.immutable.ListMap
-import org.apache.daffodil.util._
-import IIUtils._
+import org.apache.daffodil.dsom.IIUtils._
 import org.apache.daffodil.xml.XMLUtils
-import org.apache.daffodil.util.Delay
 import org.apache.daffodil.api.WarnID
 
 /**
@@ -47,17 +44,17 @@
     val fakeSchemaDocXML =
       <xs:schema xmlns:xs={ xsd }>{ fakeImportStatementsXML }</xs:schema>
 
-    val initialEmptyIIMap: IIMap = Delay(ListMap.empty)
+    val initialEmptyIIMap: IIMap = IIUtils.emptyIIMap
 
-    val fakeSD = new XMLSchemaDocument(fakeSchemaDocXML, self, None, None, initialEmptyIIMap, isBootStrapSD = true)
+    val fakeSD = XMLSchemaDocument(fakeSchemaDocXML, self, None, None, initialEmptyIIMap, isBootStrapSD = true)
     fakeSD
   }
 
-  def allSchemaDocuments = LV('allSchemaDocuments) {
+  lazy val allSchemaDocuments = {
     allSchemaFiles.map { _.iiSchemaDocument }
-  }.value
+  }
 
-  def allSchemaFiles = LV('allSchemaFiles) {
+  lazy val allSchemaFiles = {
     val fd = fakeXMLSchemaDocument //bootstrap
     val sa = fd.seenAfter
     val sfl = sa.value.flatMap {
@@ -75,6 +72,6 @@
       }
     }.toList
     sfl
-  }.value
+  }
 
 }
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 b1d5e61..a44fad8 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
@@ -19,13 +19,11 @@
 
 import scala.xml.Elem
 import scala.xml.Node
-import scala.xml._
 import org.apache.daffodil.schema.annotation.props.gen.Sequence_AnnotationMixin
 import org.apache.daffodil.schema.annotation.props.SeparatorSuppressionPolicyMixin
 import org.apache.daffodil.xml.XMLUtils
 import org.apache.daffodil.schema.annotation.props.gen.OccursCountKind
 import org.apache.daffodil.schema.annotation.props.gen.SequenceKind
-import org.apache.daffodil.Implicits.ns2String
 import org.apache.daffodil.api.WarnID
 import org.apache.daffodil.dsom.walker.SequenceView
 import org.apache.daffodil.grammar.SequenceGrammarMixin
@@ -91,9 +89,7 @@
   with SeparatorSuppressionPolicyMixin
   with LayeringRuntimeValuedPropertiesMixin {
 
-
   requiredEvaluationsIfActivated(checkIfValidUnorderedSequence)
-
   requiredEvaluationsIfActivated(checkIfNonEmptyAndDiscrimsOrAsserts)
 
   protected def apparentXMLChildren: Seq[Node]
@@ -278,7 +274,7 @@
     }
   }
 
-  protected final def emptyFormatFactory = new DFDLSequence(newDFDLAnnotationXML("sequence"), this)
+  protected def emptyFormatFactory = new DFDLSequence(newDFDLAnnotationXML("sequence"), this)
 
   final lazy val <sequence>{ apparentXMLChildren @ _* }</sequence> = (xml \\ "sequence")(0)
 
@@ -292,17 +288,6 @@
     findPropertyOption("hiddenGroupRef")
   }.value
 
-}
-
-/**
- * Represents a local sequence definition.
- */
-final class Sequence(xmlArg: Node, lexicalParent: SchemaComponent, position: Int)
-  extends SequenceGroupTermBase(xmlArg, lexicalParent, position)
-  with SequenceDefMixin
-  with SequenceView {
-
-  requiredEvaluationsIfActivated(checkHiddenGroupRefHasNoChildren)
 
   override lazy val optReferredToComponent = None
 
@@ -323,8 +308,31 @@
     }
     hgr
   }.value
+
 }
 
+object LocalSequence {
+  def apply(xmlArg: Node, lexicalParent: SchemaComponent, position: Int) = {
+    val ls = new LocalSequence(xmlArg, lexicalParent, position)
+    ls.initialize()
+    ls
+  }
+}
+/**
+ * Represents a local sequence definition.
+ */
+final class LocalSequence private (xmlArg: Node, lexicalParent: SchemaComponent, position: Int)
+  extends SequenceGroupTermBase(xmlArg, lexicalParent, position)
+  with SequenceDefMixin
+  with SequenceView
+
+object ChoiceBranchImpliedSequence {
+  def apply(rawGM: Term) = {
+    val cbis = new ChoiceBranchImpliedSequence(rawGM)
+    cbis.initialize()
+    cbis
+  }
+}
 /**
  * For the case when a choice branch happens to be a local element decl or element ref
  * with varying or multiple occurrences. In that case we encapsulate them
@@ -335,7 +343,7 @@
  * sequence machinery. In effect this is specifying the properties needed to ensure it is
  * handled as a degenerate sequence having only one element decl within it.
  */
-final class ChoiceBranchImpliedSequence(rawGM: Term)
+final class ChoiceBranchImpliedSequence private (rawGM: Term)
   extends SequenceTermBase(rawGM.xml, rawGM.optLexicalParent, rawGM.position)
   with SequenceDefMixin
   with ChoiceBranchImpliedSequenceRuntime1Mixin {
@@ -372,9 +380,6 @@
    */
   override lazy val nonDefaultPropertySources: Seq[ChainPropProvider] = Seq()
 
-  // Members declared in AnnotatedSchemaComponent
-  protected def optReferredToComponent: Option[AnnotatedSchemaComponent] = None
-
   final override def xmlChildren: Seq[scala.xml.Node] = Seq(xml)
 
   // Members declared in Term
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 d122c5a..e43ca70 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
@@ -18,7 +18,6 @@
 package org.apache.daffodil.dsom
 
 import java.math.{ BigInteger => JBigInt }
-
 import scala.xml.Node
 import org.apache.daffodil.cookers.IntRangeCooker
 import org.apache.daffodil.cookers.RepValueCooker
@@ -30,7 +29,6 @@
 import org.apache.daffodil.processors.IdentifyTypeCalculator
 import org.apache.daffodil.processors.RepValueSet
 import org.apache.daffodil.processors.RepValueSetCompiler
-import org.apache.daffodil.processors.SimpleTypeRuntimeData
 import org.apache.daffodil.processors.TypeCalculator
 import org.apache.daffodil.processors.TypeCalculatorCompiler
 import org.apache.daffodil.schema.annotation.props.Found
@@ -43,7 +41,9 @@
 import org.apache.daffodil.infoset.DataValue
 import org.apache.daffodil.infoset.DataValue.DataValueBigInt
 import org.apache.daffodil.infoset.DataValue.DataValuePrimitive
+import org.apache.daffodil.runtime1.SimpleTypeRuntime1Mixin
 import org.apache.daffodil.schema.annotation.props.gen.ParseUnparsePolicy
+import org.apache.daffodil.xml.RefQName
 
 trait TypeBase {
   def optRestriction: Option[Restriction] = None
@@ -205,15 +205,16 @@
   with OverlapCheckMixin
   with HasOptRepTypeMixinImpl
   with NamedMixin
-  with HasRepValueAttributes {
+  with HasRepValueAttributes
+  with SimpleTypeRuntime1Mixin {
+
+  requiredEvaluationsIfActivated(validateRepType)
 
   override def typeNode = primType
 
-  def toOpt[R <: AnyRef](b: Boolean, v: => R) = Misc.boolToOpt(b, v)
+  def toOpt[R <: AnyRef](b: Boolean, v: => R): Option[R] = Misc.boolToOpt(b, v)
 
-  //Perfoming this validation on construction causes infinite loops
-  //So we defer it to later
-  private lazy val validate: Unit = {
+  private lazy val validateRepType: Unit = {
     if (optRepType.isDefined && optRepType.get.isInstanceOf[PrimitiveType]) {
       val ees = enclosingElements
       //
@@ -235,38 +236,8 @@
     }
   }
 
-  lazy val simpleTypeRuntimeData: SimpleTypeRuntimeData = {
-    validate
-    val strd =
-      new SimpleTypeRuntimeData(
-        variableMap,
-        schemaFileLocation,
-        diagnosticDebugName,
-        path,
-        namespaces,
-        primType,
-        noFacetChecks,
-        optRestriction.toSeq.flatMap { r => if (r.hasPattern) r.patternValues else Nil },
-        optRestriction.flatMap { r => toOpt(r.hasEnumeration, r.enumerationValues.get) },
-        optRestriction.flatMap { r => toOpt(r.hasMinLength, r.minLengthValue) },
-        optRestriction.flatMap { r => toOpt(r.hasMaxLength, r.maxLengthValue) },
-        optRestriction.flatMap { r => toOpt(r.hasMinInclusive, r.minInclusiveValue) },
-        optRestriction.flatMap { r => toOpt(r.hasMaxInclusive, r.maxInclusiveValue) },
-        optRestriction.flatMap { r => toOpt(r.hasMinExclusive, r.minExclusiveValue) },
-        optRestriction.flatMap { r => toOpt(r.hasMaxExclusive, r.maxExclusiveValue) },
-        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.unqualifiedPathStepPolicy,
-        optRepTypeDef.map(_.simpleTypeRuntimeData),
-        optRepValueSet,
-        optTypeCalculator,
-        optRepType.map(_.primType))
-    strd
-  }
-  override lazy val runtimeData = simpleTypeRuntimeData
 
-  private lazy val noFacetChecks =
+  lazy val noFacetChecks =
     optRestriction.map { r =>
       if (r.hasPattern || r.hasEnumeration || r.hasMinLength || r.hasMaxLength ||
         r.hasMinInclusive || r.hasMaxInclusive || r.hasMinExclusive || r.hasMaxExclusive ||
@@ -276,7 +247,7 @@
 
   // override def name = diagnosticDebugName // don't do this. names are used by diagnosticDebugName
 
-  override final lazy val optReferredToComponent = optRestriction.flatMap { _.optBaseDef }
+  override final lazy val optReferredToComponent = optRestriction.flatMap { _.optBaseTypeDef }
   override final lazy val emptyFormatFactory = new DFDLSimpleType(newDFDLAnnotationXML("simpleType"), this)
 
   override final def isMyFormatAnnotation(a: DFDLAnnotation) = a.isInstanceOf[DFDLSimpleType]
@@ -315,9 +286,9 @@
     if (restrictionNodeSeq.isEmpty) {
       val unionNodeSeq = xml \ "union"
       Assert.invariant(unionNodeSeq.length == 1)
-      (None, Some(new Union(unionNodeSeq(0), this)))
+      (None, Some(Union(unionNodeSeq(0), this)))
     } else {
-      (Some(new Restriction(restrictionNodeSeq(0), this)), None)
+      (Some( Restriction(restrictionNodeSeq(0), this)), None)
     }
   }
 
@@ -385,11 +356,14 @@
         })
         val supportsParse = optInputTypeCalc.isDefined
         val supportsUnparse = optOutputTypeCalc.isDefined
-        if (supportsParse || supportsUnparse) {
-          Some(TypeCalculatorCompiler.compileTypeCalculatorFromExpression(optInputCompiled, optOutputCompiled, srcType, dstType))
-        } else {
-          None
+        val res = {
+          if (supportsParse || supportsUnparse) {
+            Some(TypeCalculatorCompiler.compileTypeCalculatorFromExpression(optInputCompiled, optOutputCompiled, srcType, dstType))
+          } else {
+            None
+          }
         }
+        res
       }
 
       val ans = (fromRestriction, fromUnion, fromExpression) match {
@@ -429,32 +403,34 @@
     })
   }.value
 
-  /*
-   * We don't really need the NamedMixin. It is only used for detecting duplicates
-   * However, since only named types can be a repType, there is no problem
-   * in requiring them to be named
-   */
-  override lazy val optRepType: Option[SimpleTypeBase with NamedMixin] = LV('optRepType) {
-    lazy val fromSelf: Option[SimpleTypeBase with NamedMixin] = {
-      val qName = findPropertyOption("repType").toOption
-        .map(qn => {
-          QName.resolveRef(qn, namespaces, tunable.unqualifiedPathStepPolicy).toOption match {
-            case Some(x) => x
-            case None => SDE(s"Cannot resolve type ${qn}")
-          }
-        })
-      val optRepTypeDef = qName.flatMap(schemaSet.getGlobalSimpleTypeDef(_))
-      val optRepPrimType = qName.flatMap(schemaSet.getPrimitiveType(_))
-      Assert.invariant(!(optRepPrimType.isDefined && optRepTypeDef.isDefined))
-      if (qName.isDefined) {
-        schemaDefinitionUnless(optRepTypeDef.isDefined || optRepPrimType.isDefined, s"Cannot find reptype ${qName.get}")
-      }
-      optRepTypeDef.orElse(optRepPrimType)
+  private lazy val optRepTypeQNameString = findPropertyOption("repType").toOption
+
+  private lazy val optRepTypeQName: Option[RefQName] = LV('optRepTypeQName) {
+    optRepTypeQNameString
+      .map(qn => {
+        QName.resolveRef(qn, namespaces, tunable.unqualifiedPathStepPolicy).toOption match {
+          case Some(x) => x
+          case None => SDE(s"Cannot resolve type ${qn}")
+        }
+      })
+  }.value
+
+  private lazy val optRepTypeFromSelf: Option[SimpleTypeBase with NamedMixin] = LV('optRepTypeFromSelf){
+    val optRepTypeDef = optRepTypeQName.flatMap(schemaSet.getGlobalSimpleTypeDef(_))
+    val optRepPrimType = optRepTypeQName.flatMap(schemaSet.getPrimitiveType(_))
+    Assert.invariant(!(optRepPrimType.isDefined && optRepTypeDef.isDefined))
+    if (optRepTypeQName.isDefined) {
+      schemaDefinitionUnless(optRepTypeDef.isDefined || optRepPrimType.isDefined,
+        s"Cannot find reptype ${optRepTypeQNameString.get}")
     }
-    lazy val fromUnion: Option[SimpleTypeBase with NamedMixin] = optUnion.flatMap(union => {
-      val repTypes = union.unionMemberTypes.map(_.optRepTypeDef)
+    optRepTypeDef.orElse(optRepPrimType)
+  }.value
+
+  private lazy val optRepTypeFromUnion: Option[SimpleTypeBase with NamedMixin] = LV('optRepTypeFromUnion) {
+    optUnion.flatMap(union => {
+      val repTypes = union.unionMemberTypes.map(_.optRepType)
       //check that all repTypes are the same
-      //Because of how we inline types, we do not expect to see structual equality,
+      //Because of how we inline types, we do not expect to see structural equality,
       //so we rely on the xml qname instead
       val numRepTypes = repTypes.map(_.map(_.namedQName)).toSet.size
       if (numRepTypes > 1) {
@@ -466,6 +442,14 @@
         repTypes.head
       }
     })
+  }.value
+
+  /*
+   * We don't really need the NamedMixin. It is only used for detecting duplicates
+   * However, since only named types can be a repType, there is no problem
+   * in requiring them to be named
+   */
+  override lazy val optRepType: Option[SimpleTypeBase with NamedMixin] = LV('optRepType) {
     /*
      * Note that there is no fromRestriction option here
      * In theory, we could consider every restriction type without an explicit repType to be
@@ -474,7 +458,7 @@
      * Instead, when a user needs a restriction transform, they must simply provide the reptype explitly,
      * which is arguably a good design decision from a readability standpoint of the schema as well.
      */
-    fromSelf.orElse(fromUnion)
+    optRepTypeFromSelf.orElse(optRepTypeFromUnion)
   }.toOption.flatten
 
   override lazy val optRepValueSet: Option[RepValueSet] = optRepTypeDef.flatMap(repType => {
@@ -512,35 +496,44 @@
 
 }
 
-final class LocalSimpleTypeDef(
+object LocalSimpleTypeDef {
+  def apply(xmlArg: Node, lexicalParent: SchemaComponent) = {
+    val lstd = new LocalSimpleTypeDef(xmlArg, lexicalParent)
+    lstd.initialize()
+    lstd
+  }
+}
+
+final class LocalSimpleTypeDef private (
   xmlArg: Node, lexicalParent: SchemaComponent)
   extends SimpleTypeDefBase(xmlArg, lexicalParent)
   with LocalNonElementComponentMixin
   with NestingLexicalMixin {
 
+  requiredEvaluationsIfActivated(primType)
+
   /**
    * For anonymous simple type def, uses the base name, or primitive type name
    */
-
-  override lazy val diagnosticDebugName: String = {
-    //
-    // TODO: implement a daf:name property to give an alternate name. If present, use that.
-    //
-    val baseName = optRestriction.flatMap { r =>
-      r.optBaseDef.map { _.namedQName }.orElse(Some(r.primType.globalQName))
-    }.getOrElse(this.optUnion.map { u => u.primType.globalQName }.getOrElse(
-      //Note that this.toString=diagnosticDebugName, so SDE cannot be used here
-      Assert.invariantFailed("Anonymous Simple type is neither a union nor a restriction. Enclosing element is " + this.lexicalParent)))
-    // furthermore, we can't call things that throw SDEs either.
-    val repName = optRepTypeDef.map(_.name)
-    repName match {
-      case None => baseName.diagnosticDebugName
-      case Some(n) => s"${n} -> ${baseName.diagnosticDebugName}"
+  override protected lazy val diagnosticDebugNameImpl: String = {
+    if (optRestriction.isDefined)
+      optRestriction.get.baseQNameString // unresolved string
+    else {
+      Assert.invariant(optUnion.isDefined)
+      optUnion.get.primType.globalQName.toQNameString
     }
   }
 }
 
-final class GlobalSimpleTypeDef(xmlArg: Node, schemaDocumentArg: SchemaDocument)
+object GlobalSimpleTypeDef {
+  def apply(xmlArg: Node, schemaDocumentArg: SchemaDocument) = {
+    val gstd = new GlobalSimpleTypeDef(xmlArg, schemaDocumentArg)
+    gstd.initialize()
+    gstd
+  }
+}
+
+final class GlobalSimpleTypeDef private (xmlArg: Node, schemaDocumentArg: SchemaDocument)
   extends SimpleTypeDefBase(xmlArg, schemaDocumentArg)
   with GlobalNonElementComponentMixin
   with NestingLexicalMixin
@@ -590,7 +583,7 @@
     ans
   }
 
-  override protected val optReferredToComponent = None
+  override val optReferredToComponent = None
 
   protected def annotationFactory(node: Node): Option[DFDLAnnotation] = Assert.invariantFailed("Should not be called")
   protected lazy val emptyFormatFactory: DFDLFormatAnnotation = new DFDLEnumerationFactory(newDFDLAnnotationXML("enumeration"), this)
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Term.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Term.scala
index a500c08..436b7be 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Term.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Term.scala
@@ -73,9 +73,9 @@
 /**
  * Term, and what is and isn't a Term, is a key concept in DSOM.
  *
- * From elements, ElementRef and LocalElementDecl are Term. A GlobalElementDecl is *not* a Term.
- * From sequences, Sequence and SequenceGroupRef are Term. GlobalSequenceGroupDef is *not* a Term.
- * From choices, Choice and ChoiceGroupRef are Term. GlobalChoiceGroupDef is *not* a Term.
+ * From the kinds of elements, ElementRef and LocalElementDecl are Term. A GlobalElementDecl is *not* a Term.
+ * From the kinds of sequences, LocalSequence and SequenceGroupRef are Term. GlobalSequenceGroupDef is *not* a Term.
+ * From the kinds of choices, Choice and ChoiceGroupRef are Term. GlobalChoiceGroupDef is *not* a Term.
  *
  * Terms are the things we actually generate parsers/unparsers for. Non-Terms just
  * contribute information used by Terms.
@@ -277,7 +277,7 @@
         // to the actual choice
         //
         case c: ChoiceBranchImpliedSequence => c.immediatelyEnclosingGroupDef
-        case s: Sequence => Some(s)
+        case s: LocalSequence => Some(s)
         case d: SchemaDocument => {
           // we must be the Root elementRef or a quasi node
           Assert.invariant(this.isInstanceOf[Root] || this.isInstanceOf[QuasiElementDeclBase])
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/TermEncodingMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/TermEncodingMixin.scala
index 388d4ba..d51f145 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/TermEncodingMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/TermEncodingMixin.scala
@@ -23,6 +23,7 @@
 import org.apache.daffodil.processors.KnownEncodingMixin
 import org.apache.daffodil.api.WarnID
 import org.apache.daffodil.schema.annotation.props.gen.YesNo
+import org.apache.daffodil.util.Maybe
 
 /**
  * Captures concepts around dfdl:encoding property and Terms.
@@ -31,7 +32,7 @@
  */
 trait TermEncodingMixin extends KnownEncodingMixin { self: Term =>
 
-  requiredEvaluationsAlways(checkTextBidi)
+  requiredEvaluationsIfActivated(checkTextBidi)
 
   private lazy val optionTextBidi = findPropertyOption("textBidi")
 
@@ -47,12 +48,15 @@
         encodingErrorPolicy
       } else {
         if (!optionEncodingErrorPolicy.isDefined)
-          SDW(WarnID.EncodingErrorPolicyError, "Property 'dfdl:encodingErrorPolicy' is required but not defined, using 'replace' by default.")
+          SDW(
+            WarnID.EncodingErrorPolicyError,
+            "Property 'dfdl:encodingErrorPolicy' is required but not defined, using 'replace' by default.")
         optionEncodingErrorPolicy.getOrElse(EncodingErrorPolicy.Replace)
       }
     if (policy == EncodingErrorPolicy.Error) {
       // DFDL-935 to enable
-      SDW(WarnID.EncodingErrorPolicyError, "dfdl:encodingErrorPolicy=\"error\" is not yet implemented. The 'replace' value will be used.")
+      SDW(WarnID.EncodingErrorPolicyError,
+        "dfdl:encodingErrorPolicy=\"error\" is not yet implemented. The 'replace' value will be used.")
       EncodingErrorPolicy.Replace
     }
     policy
@@ -83,7 +87,9 @@
    */
   override final lazy val knownEncodingAlignmentInBits = {
     if (isKnownEncoding) {
-      schemaDefinitionWarningWhen(WarnID.DeprecatedEncodingNameUSASCII7BitPacked, knownEncodingName == "US-ASCII-7-BIT-PACKED",
+      schemaDefinitionWarningWhen(
+        WarnID.DeprecatedEncodingNameUSASCII7BitPacked,
+        knownEncodingName == "US-ASCII-7-BIT-PACKED",
         "Character set encoding name US-ASCII-7-BIT-PACKED is deprecated." +
           "Please update your DFDL schema to use the name X-DFDL-US-ASCII-7-BIT-PACKED.")
       val cs = charsetEv.optConstant.get
@@ -92,8 +98,15 @@
   }
 
   lazy val encodingInfo =
-    new EncodingRuntimeData(charsetEv, schemaFileLocation, optionUTF16Width, defaultEncodingErrorPolicy,
-      summaryEncoding, isKnownEncoding, isScannable, knownEncodingAlignmentInBits, hasTextAlignment)
+    new EncodingRuntimeData(
+      charsetEv,
+      schemaFileLocation,
+      Maybe.toMaybe(optionUTF16Width),
+      defaultEncodingErrorPolicy,
+      isKnownEncoding,
+      isScannable,
+      knownEncodingAlignmentInBits,
+      hasTextAlignment)
 
 
 
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/package.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/package.scala
index cca94d9..ef10cb8 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/package.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/package.scala
@@ -66,10 +66,10 @@
  * graph has been created, in order to compile it into the runtime data structures.
  *
  * There are a few exceptions to the above. The dfdl:hiddenGroupRef attribute is one such. It
- * must be local to the [[Sequence]] object, and has implications for the parsing
+ * must be local to the [[LocalSequence]] object, and has implications for the parsing
  * of the XML as it implies there should be no children of that xs:sequence.
  * Since it is not scoped, the DSOM graph is not needed in order to access it.
- * Only the local [[Sequence]] object and it's [[DFDLSequence]] annotation object.
+ * Only the local [[LocalSequence]] object and it's [[DFDLSequence]] annotation object.
  * The [[AnnotatedSchemaComponent]] trait provides methods for this local-only
  * property lookup.
  *
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ChoiceGrammarMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ChoiceGrammarMixin.scala
index 383fcef..c46667e 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ChoiceGrammarMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ChoiceGrammarMixin.scala
@@ -17,7 +17,6 @@
 
 package org.apache.daffodil.grammar
 
-import org.apache.daffodil.dsom.ChoiceBranchImpliedSequence
 import org.apache.daffodil.dsom.ChoiceTermBase
 import org.apache.daffodil.grammar.primitives.ChoiceCombinator
 import org.apache.daffodil.runtime1.ChoiceTermRuntime1Mixin
@@ -30,27 +29,7 @@
     ChoiceCombinator(this, alternatives)
   }
 
-  /**
-   * Establish the invariant is that if a direct child member is an array element,
-   * the child will have been encapsulated as a sequence, so that arrays always
-   * live within sequences.
-   */
-  final protected lazy val alternatives: Seq[Gram] = {
-    groupMembers.map { t =>
-      if (!t.isScalar) {
-        /**
-         * If this choice branch is a non-scalar, then we need to encapsulate
-         * it with a ChoiceBranchImpliedSequence, which is a kind of Sequence
-         * base. When compiling this this choice branch, Daffodil can then
-         * depend on the invariant that every recurring element is contained
-         * inside a sequence, and that sequence describes everything about how
-         * that elements occurrences are separated.
-         */
-        val cbis = new ChoiceBranchImpliedSequence(t)
-        cbis.termContentBody
-      } else {
-        t.termContentBody
-      }
-    }
-  }
+  final protected lazy val alternatives: Seq[Gram] =
+    groupMembers.map{ _.termContentBody }
+
 }
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ElementBaseGrammarMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ElementBaseGrammarMixin.scala
index 61da856..9ead55b 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ElementBaseGrammarMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ElementBaseGrammarMixin.scala
@@ -52,6 +52,8 @@
   with PaddingInfoMixin
   with ElementBaseRuntime1Mixin { self: ElementBase =>
 
+  requiredEvaluationsIfActivated(checkPrefixedLengthElementDecl)
+
   private val context = this
 
   private lazy val (leftPadding, rightPadding) = {
@@ -88,91 +90,106 @@
       minLen > 0)
   }
 
-  final lazy val prefixedLengthElementDecl: PrefixLengthQuasiElementDecl = {
-    Assert.invariant(lengthKind == LengthKind.Prefixed)
 
+  private lazy val prefixLengthTypeGSTD = LV('prefixLengthTypeGSTD){
     // We need to resolve the global simple type of the prefix length type
     // because we need to create a detached element with the same schema
     // document/parent of the GSTD.
-    val prefixLengthTypeGSTD = schemaSet.getGlobalSimpleTypeDef(prefixLengthType).getOrElse(
+    schemaSet.getGlobalSimpleTypeDef(prefixLengthType).getOrElse(
       schemaDefinitionError(
         "Failed to resolve dfdl:prefixLengthType=\"%s\" to a simpleType",
         prefixLengthType.toQNameString))
+  }.value
 
+  lazy val prefixedLengthElementDecl: PrefixLengthQuasiElementDecl = LV('prefixedLengthElementDecl){
+    Assert.invariant(lengthKind == LengthKind.Prefixed)
     val detachedNode =
-      <element name={ name + " (prefixLength)" } type={ prefixLengthType.toQNameString }/>
+        <element name={name + " (prefixLength)"} type={prefixLengthType.toQNameString}/>
         .copy(scope = prefixLengthTypeGSTD.xml.scope)
-    val detachedElementDecl =
-      new PrefixLengthQuasiElementDecl(detachedNode, prefixLengthTypeGSTD)
-
-    val prefixedLengthKind = detachedElementDecl.lengthKind
-    prefixedLengthKind match {
-      case LengthKind.Delimited | LengthKind.EndOfParent | LengthKind.Pattern =>
-        schemaDefinitionError(
-          "%s is specified as a dfdl:prefixLengthType, but has a dfdl:lengthKind of %s",
-          prefixLengthType,
-          prefixedLengthKind)
-      case LengthKind.Explicit if detachedElementDecl.optLengthConstant.isEmpty =>
-        schemaDefinitionError(
-          "%s is specified as a dfdl:prefixLengthType, but has an expression for dfdl:length",
-          prefixLengthType)
-      case LengthKind.Implicit | LengthKind.Explicit if prefixIncludesPrefixLength == YesNo.Yes &&
-        lengthUnits != detachedElementDecl.lengthUnits =>
-        schemaDefinitionError(
-          "%s is specified as a dfdl:prefixLengthType where dfdl:prefixIncludesPrefixLength=\"yes\" " +
-            "with dfdl:lengthKind %s, but has different dfdl:lengthUnits than the element",
-          prefixLengthType,
-          prefixedLengthKind)
-      case _ =>
+    val detachedElementDecl = {
+      PrefixLengthQuasiElementDecl(detachedNode, prefixLengthTypeGSTD)
     }
-
-    schemaDefinitionUnless(
-      detachedElementDecl.primType.isSubtypeOf(NodeInfo.Integer),
-      "%s is specified as a dfdl:prefixLengthType, but its type xs:%s is not a subtype of xs:integer",
-      prefixLengthType,
-      detachedElementDecl.primType.toString.toLowerCase)
-
-    schemaDefinitionWhen(
-      detachedElementDecl.isOutputValueCalc,
-      "%s is specified as a dfdl:prefixLengthType, but specifies dfdl:outputValueCalc",
-      prefixLengthType)
-    schemaDefinitionWhen(
-      detachedElementDecl.hasInitiator,
-      "%s is specified as a dfdl:prefixLengthType, but specifies a dfdl:initiator",
-      prefixLengthType)
-    schemaDefinitionWhen(
-      detachedElementDecl.hasTerminator,
-      "%s is specified as a dfdl:prefixLengthType, but specifies a dfdl:terminator",
-      prefixLengthType)
-    schemaDefinitionWhen(
-      detachedElementDecl.alignment != 1,
-      "%s is specified as a dfdl:prefixLengthType, but specifies a dfdl:alignment other than 1",
-      prefixLengthType)
-    schemaDefinitionWhen(
-      detachedElementDecl.leadingSkip != 0,
-      "%s is specified as a dfdl:prefixLengthType, but specifies a dfdl:leadingSkip other than 0",
-      prefixLengthType)
-    schemaDefinitionWhen(
-      detachedElementDecl.trailingSkip != 0,
-      "%s is specified as a dfdl:prefixLengthType, but specifies a dfdl:trailingSkip other than 0",
-      prefixLengthType)
-
-    if (detachedElementDecl.lengthKind == LengthKind.Prefixed &&
-      detachedElementDecl.prefixedLengthElementDecl.lengthKind == LengthKind.Prefixed) {
-      schemaDefinitionError(
-        "Nesting level for dfdl:prefixLengthType exceeds 1: %s > %s > %s > %s",
-        name,
-        prefixLengthType,
-        detachedElementDecl.prefixLengthType,
-        detachedElementDecl.prefixedLengthElementDecl.prefixLengthType)
-    }
-
-    subset(
-      detachedElementDecl.lengthKind != LengthKind.Prefixed,
-      "Nested dfdl:lengthKind=\"prefixed\" is not supported.")
-
     detachedElementDecl
+  }.value
+
+  final lazy val optPrefixLengthElementDecl: Option[PrefixLengthQuasiElementDecl] =
+    if (lengthKind == LengthKind.Prefixed)
+      Some(prefixedLengthElementDecl)
+    else
+      None
+
+  final lazy val checkPrefixedLengthElementDecl: Unit = {
+    if (lengthKind != LengthKind.Prefixed) ()
+    else {
+      val detachedElementDecl = prefixedLengthElementDecl
+      val prefixedLengthKind = detachedElementDecl.lengthKind
+      prefixedLengthKind match {
+        case LengthKind.Delimited | LengthKind.EndOfParent | LengthKind.Pattern =>
+          schemaDefinitionError(
+            "%s is specified as a dfdl:prefixLengthType, but has a dfdl:lengthKind of %s",
+            prefixLengthType,
+            prefixedLengthKind)
+        case LengthKind.Explicit if detachedElementDecl.optLengthConstant.isEmpty =>
+          schemaDefinitionError(
+            "%s is specified as a dfdl:prefixLengthType, but has an expression for dfdl:length",
+            prefixLengthType)
+        case LengthKind.Implicit | LengthKind.Explicit if prefixIncludesPrefixLength == YesNo.Yes &&
+          lengthUnits != detachedElementDecl.lengthUnits =>
+          schemaDefinitionError(
+            "%s is specified as a dfdl:prefixLengthType where dfdl:prefixIncludesPrefixLength=\"yes\" " +
+              "with dfdl:lengthKind %s, but has different dfdl:lengthUnits than the element",
+            prefixLengthType,
+            prefixedLengthKind)
+        case _ => // ok
+      }
+
+      schemaDefinitionUnless(
+        detachedElementDecl.primType.isSubtypeOf(NodeInfo.Integer),
+        "%s is specified as a dfdl:prefixLengthType, but its type xs:%s is not a subtype of xs:integer",
+        prefixLengthType,
+        detachedElementDecl.primType.toString.toLowerCase)
+
+      schemaDefinitionWhen(
+        detachedElementDecl.isOutputValueCalc,
+        "%s is specified as a dfdl:prefixLengthType, but specifies dfdl:outputValueCalc",
+        prefixLengthType)
+      schemaDefinitionWhen(
+        detachedElementDecl.hasInitiator,
+        "%s is specified as a dfdl:prefixLengthType, but specifies a dfdl:initiator",
+        prefixLengthType)
+      schemaDefinitionWhen(
+        detachedElementDecl.hasTerminator,
+        "%s is specified as a dfdl:prefixLengthType, but specifies a dfdl:terminator",
+        prefixLengthType)
+      schemaDefinitionWhen(
+        detachedElementDecl.alignment != 1,
+        "%s is specified as a dfdl:prefixLengthType, but specifies a dfdl:alignment other than 1",
+        prefixLengthType)
+      schemaDefinitionWhen(
+        detachedElementDecl.leadingSkip != 0,
+        "%s is specified as a dfdl:prefixLengthType, but specifies a dfdl:leadingSkip other than 0",
+        prefixLengthType)
+      schemaDefinitionWhen(
+        detachedElementDecl.trailingSkip != 0,
+        "%s is specified as a dfdl:prefixLengthType, but specifies a dfdl:trailingSkip other than 0",
+        prefixLengthType)
+
+      if (detachedElementDecl.lengthKind == LengthKind.Prefixed &&
+        detachedElementDecl.prefixedLengthElementDecl.lengthKind == LengthKind.Prefixed) {
+        schemaDefinitionError(
+          "Nesting level for dfdl:prefixLengthType exceeds 1: %s > %s > %s > %s",
+          name,
+          prefixLengthType,
+          detachedElementDecl.prefixLengthType,
+          detachedElementDecl.prefixedLengthElementDecl.prefixLengthType)
+      }
+
+      subset(
+        detachedElementDecl.lengthKind != LengthKind.Prefixed,
+        "Nested dfdl:lengthKind=\"prefixed\" is not supported.")
+    }
   }
+
   final lazy val prefixedLengthAdjustmentInUnits: Long = prefixIncludesPrefixLength match {
     case YesNo.Yes => {
       // get the known length of the prefix element in lengthUnits
@@ -447,11 +464,13 @@
    * It is critical that the 2nd argument to getShared is passed by name, so not
    * evaluated a second time when sharing opportunities are discovered (same shareKey).
    */
-  lazy val sharedSimpleParsedValue =
+  lazy val sharedSimpleParsedValue = {
+    lazy val retry = retrySimpleType(value) // once only
     schemaSet.sharedSimpleValueFactory.getShared(
       shareKey,
-      captureLengthRegions(leftPadding, retrySimpleType(value), rightPadding ~ rightFill) ~
+      captureLengthRegions(leftPadding, retry, rightPadding ~ rightFill) ~
         terminatorRegion)
+  }
 
   /**
    * Wrapped around the simple value unparsers where the simple type value is
@@ -466,7 +485,7 @@
    * do setups of ustate/data-output-streams when unparsing the result of an OVC.
    */
   private def retrySimpleType(allowedValueArg: => Gram) = {
-    lazy val allowedValue = allowedValueArg
+    lazy val allowedValue = allowedValueArg // once only
     if (this.isOutputValueCalc)
       SimpleTypeRetry(this, allowedValue)
     else if (this.isInstanceOf[PrefixLengthQuasiElementDecl]) {
@@ -1125,7 +1144,11 @@
 
   lazy val hasRepType = (isSimpleType && simpleType.optRepType.isDefined)
   lazy val optRepType = if (hasRepType) Some(simpleType.optRepType.get) else None
-  lazy val optRepTypeElement = if (isSimpleType && simpleType.optRepTypeElement.isDefined) Some(simpleType.optRepTypeElement.get) else None
+  lazy val optRepTypeElement =
+    if (isSimpleType && simpleType.optRepTypeElement.isDefined)
+      Some(simpleType.optRepTypeElement.get)
+    else
+      None
 
   /**
    * the element left framing does not include the initiator nor the element right framing the terminator
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/Grammar.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/Grammar.scala
index 9b75e5f..c5d58f8 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/Grammar.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/Grammar.scala
@@ -35,8 +35,6 @@
  */
 abstract class BinaryGram(context: SchemaComponent, childrenArg: Seq[Gram]) extends Gram(context) {
 
-  requiredEvaluationsAlways(children)
-
   protected def op: String
   protected def open: String
   protected def close: String
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/Production.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/Production.scala
index d10ef4e..0731f14 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/Production.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/Production.scala
@@ -48,18 +48,19 @@
                  override val forWhat: ParserOrUnparser)
   extends NamedGram(sc) {
 
-  final override def deref = gram
+  final override lazy val deref = gram
 
-  final override def name = nameArg
+  final override lazy val name = nameArg
 
   override def toString() = "<" + name + ">" + gram.toString + "</" + name + ">"
 
   final override lazy val path = sc.path + "@@Prod(" + diagnosticDebugName + ")"
 
+  private lazy val g = gramArg // once only
+
   final override lazy val gram: Gram = {
     guard match {
       case true => {
-        val g = gramArg // exactly once.
         g match {
           case p: Prod => {
             p.gram // recursively force this
@@ -75,7 +76,7 @@
     }
   }
 
-  final override def isEmpty = if (!guard) true else gram.isEmpty
+  final override lazy val isEmpty = if (!guard) true else gram.isEmpty
 
   final override lazy val parser = {
     (forWhat, gram.forWhat) match {
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/ElementCombinator.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/ElementCombinator.scala
index 77b2c90..e6e641b 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/ElementCombinator.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/ElementCombinator.scala
@@ -349,9 +349,6 @@
   // - test discriminators (must be attempted even if the parsing of element or setVariable statements fail)
   // - test asserts
 
-  // requiredEvaluationsAlways(patDiscrim, patAssert, eGram, setVar, testDiscrim, testAssert)
-  // Note: above not needed as these are ALWAYS evaluated below.
-
   lazy val patDiscrim = {
     val pd = context.discriminatorStatements.filter(_.testKind == TestKind.Pattern)
     Assert.invariant(pd.size <= 1)
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesBinaryNumber.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesBinaryNumber.scala
index c930f2f..bf0ddb4 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesBinaryNumber.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesBinaryNumber.scala
@@ -60,14 +60,18 @@
 
 class BinaryIntegerPrefixedLength(val e: ElementBase, signed: Boolean) extends Terminal(e, true) {
 
+  private lazy val erd = e.elementRuntimeData
+  private lazy val plerd = e.prefixedLengthElementDecl.elementRuntimeData
+  private lazy val pladj = e.prefixedLengthAdjustmentInUnits
+
   override lazy val parser =
     new BinaryIntegerPrefixedLengthParser(
-      e.elementRuntimeData,
+      erd,
       e.prefixedLengthBody.parser,
-      e.prefixedLengthElementDecl.elementRuntimeData,
+      plerd,
       signed,
       e.lengthUnits,
-      e.prefixedLengthAdjustmentInUnits)
+      pladj)
 
   override lazy val unparser: Unparser = {
     val maybeNBits = e.primType match {
@@ -79,13 +83,13 @@
       case _ => Assert.invariantFailed("Only integer base types should be used for this primitive")
     }
     new BinaryIntegerPrefixedLengthUnparser(
-      e.elementRuntimeData,
+      erd,
       e.prefixedLengthBody.unparser,
-      e.prefixedLengthElementDecl.elementRuntimeData,
+      plerd,
       maybeNBits,
       signed,
       e.lengthUnits,
-      e.prefixedLengthAdjustmentInUnits)
+      pladj)
   }
 }
 
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 0c62112..8645237 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
@@ -17,8 +17,6 @@
 
 package org.apache.daffodil.grammar.primitives
 
-import scala.Boolean
-
 import org.apache.daffodil.dsom.ElementBase
 import org.apache.daffodil.grammar.Terminal
 import org.apache.daffodil.processors.FieldDFAParseEv
@@ -40,7 +38,7 @@
 import org.apache.daffodil.processors.parsers.PackedIntegerDelimitedParser
 import org.apache.daffodil.processors.parsers.StringDelimitedParser
 import org.apache.daffodil.processors.parsers.StringOfSpecifiedLengthParser
-import org.apache.daffodil.processors.parsers.{ Parser => DaffodilParser }
+import org.apache.daffodil.processors.parsers.{Parser => DaffodilParser}
 import org.apache.daffodil.processors.unparsers.BCDDecimalDelimitedUnparser
 import org.apache.daffodil.processors.unparsers.BCDIntegerDelimitedUnparser
 import org.apache.daffodil.processors.unparsers.BlobSpecifiedLengthUnparser
@@ -56,7 +54,7 @@
 import org.apache.daffodil.processors.unparsers.StringMaybeTruncateBitsUnparser
 import org.apache.daffodil.processors.unparsers.StringMaybeTruncateCharactersUnparser
 import org.apache.daffodil.processors.unparsers.StringNoTruncateUnparser
-import org.apache.daffodil.processors.unparsers.{ Unparser => DaffodilUnparser }
+import org.apache.daffodil.processors.unparsers.{Unparser => DaffodilUnparser}
 import org.apache.daffodil.schema.annotation.props.gen.EscapeKind
 import org.apache.daffodil.schema.annotation.props.gen.LengthUnits
 import org.apache.daffodil.util.Maybe.Nope
@@ -103,11 +101,6 @@
   extends StringDelimBase(e, true)
   with Padded {
 
-  // TODO: DFDL-451 - Has been placed on the backburner until we can figure out the appropriate behavior
-  //
-  //  requiredEvaluations(gram.checkDelimiterDistinctness(esObj.escapeSchemeKind, optPadChar, optEscChar,
-  //    optEscEscChar, optEscBlkStart, optEscBlkEnd, staticDelimsCooked, elemBase))
-
   def isDelimRequired: Boolean
 
   lazy val es = e.optionEscapeScheme
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/SpecifiedLength.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/SpecifiedLength.scala
index f1934d2..c603c4f 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/SpecifiedLength.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/SpecifiedLength.scala
@@ -151,21 +151,25 @@
 
   lazy val kind = "Prefixed_" + e.lengthUnits.toString
 
+  private lazy val erd = e.elementRuntimeData
+  private lazy val plerd = e.prefixedLengthElementDecl.elementRuntimeData
+  private lazy val pladj = e.prefixedLengthAdjustmentInUnits
+
   lazy val parser: Parser = new SpecifiedLengthPrefixedParser(
     eParser,
-    e.elementRuntimeData,
+    erd,
     e.prefixedLengthBody.parser,
-    e.prefixedLengthElementDecl.elementRuntimeData,
+    plerd,
     e.lengthUnits,
-    e.prefixedLengthAdjustmentInUnits)
+    pladj)
 
   lazy val unparser: Unparser = new SpecifiedLengthPrefixedUnparser(
     eUnparser,
-    e.elementRuntimeData,
+    erd,
     e.prefixedLengthBody.unparser,
-    e.prefixedLengthElementDecl.elementRuntimeData,
+    plerd,
     e.lengthUnits,
-    e.prefixedLengthAdjustmentInUnits)
+    pladj)
 }
 
 class SpecifiedLengthExplicitCharacters(e: ElementBase, eGram: => Gram)
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 846f9e9..a4a38b1 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
@@ -17,7 +17,10 @@
 
 package org.apache.daffodil.runtime1
 
-import org.apache.daffodil.dsom.{ChoiceTermBase, ExpressionCompilers, SequenceTermBase, Term}
+import org.apache.daffodil.dsom.ChoiceTermBase
+import org.apache.daffodil.dsom.ExpressionCompilers
+import org.apache.daffodil.dsom.SequenceTermBase
+import org.apache.daffodil.dsom.Term
 import org.apache.daffodil.infoset.ChoiceBranchStartEvent
 import org.apache.daffodil.processors.ChoiceRuntimeData
 import org.apache.daffodil.infoset.ChoiceBranchEvent
@@ -26,12 +29,14 @@
 import org.apache.daffodil.api.WarnID
 import org.apache.daffodil.processors.ChoiceDispatchKeyEv
 import org.apache.daffodil.dpath.NodeInfo
-import org.apache.daffodil.grammar.Gram
 import org.apache.daffodil.processors.ElementRuntimeData
 import org.apache.daffodil.grammar.Gram
+import org.apache.daffodil.util.Delay
 
 trait ChoiceTermRuntime1Mixin { self: ChoiceTermBase =>
 
+  requiredEvaluationsIfActivated(optRepTypeElement.map{ _.elementRuntimeData.initialize })
+
   /**
    * The members of the choice group with special treatment given to some kinds of members.
    *
@@ -175,10 +180,13 @@
 
   final lazy val modelGroupRuntimeData = choiceRuntimeData
 
+
+
+
   final lazy val choiceRuntimeData = {
     new ChoiceRuntimeData(
       position,
-      partialNextElementResolver,
+      Delay('ChoicePartialNextElementResolver, this, partialNextElementResolver),
       schemaSet.variableMap,
       encodingInfo,
       // elementChildren.map { _.elementRuntimeData.dpathElementCompileInfo },
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 e53c081..f815ec8 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
@@ -25,6 +25,7 @@
 import org.apache.daffodil.processors.RuntimeData
 import org.apache.daffodil.processors.TermRuntimeData
 import org.apache.daffodil.processors.ElementRuntimeData
+import org.apache.daffodil.util.Delay
 import org.apache.daffodil.util.Maybe
 import org.apache.daffodil.dsom.SimpleTypeDefBase
 import org.apache.daffodil.dsom.ComplexTypeBase
@@ -32,6 +33,16 @@
 
 trait ElementBaseRuntime1Mixin { self: ElementBase =>
 
+  // initialize cyclic structure
+  requiredEvaluationsIfActivated(
+    dpathElementCompileInfo.initialize
+  )
+
+  // initialize cyclic structure
+  requiredEvaluationsIfActivated(
+    elementRuntimeData.initialize
+  )
+
   /**
    * Tells us if, for this element, we need to capture its content length
    *  at unparse runtime, or we can ignore that.
@@ -122,14 +133,14 @@
    * This is the compile info for this element term.
    */
   lazy val dpathElementCompileInfo: DPathElementCompileInfo = {
-    val ee = enclosingElements
+    lazy val ee = enclosingElements
     lazy val parents = ee.map {
       _.dpathElementCompileInfo
     }
     val eci = new DPathElementCompileInfo(
-      parents,
+      Delay('elementParents, this, parents),
       variableMap,
-      elementChildrenCompileInfo,
+      Delay('elementChildrenCompileInfo, this, elementChildrenCompileInfo),
       namespaces,
       slashPath,
       name,
@@ -139,7 +150,6 @@
       schemaFileLocation,
       tunable.unqualifiedPathStepPolicy,
       schemaSet.typeCalcMap,
-      runtimeData,
       shortSchemaComponentDesignator,
       isOutputValueCalc)
     eci
@@ -150,20 +160,18 @@
 
   final def erd = elementRuntimeData // just an abbreviation
 
-  final lazy val elementRuntimeData: ElementRuntimeData = LV('elementRuntimeData) {
-    computeElementRuntimeData
+  private lazy val childrenERDs: Seq[ElementRuntimeData] = LV('childrenERDs) {
+    elementChildren.map {
+      _.elementRuntimeData
+    }
   }.value
 
-  protected def computeElementRuntimeData(): ElementRuntimeData = {
-
-    lazy val childrenERDs: Seq[ElementRuntimeData] =
-      elementChildren.map { _.elementRuntimeData }
-
+  final lazy val elementRuntimeData: ElementRuntimeData = LV('elementRuntimeData) {
     val newERD: ElementRuntimeData = new ElementRuntimeData(
       position,
       childrenERDs,
       schemaSet.variableMap,
-      partialNextElementResolver,
+      Delay('ElementPartialNextElementResolver, this, partialNextElementResolver),
       encodingInfo,
       dpathElementCompileInfo,
       schemaFileLocation,
@@ -204,7 +212,7 @@
       maybeCheckBitOrderAndCharsetEv,
       isQuasiElement)
     newERD
-  }
+  }.value
 
   private lazy val (optSimpleTypeRuntimeData,
     optComplexTypeModelGroupRuntimeData) =
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/LocalElementDeclBaseRuntime1Mixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/LocalElementDeclBaseRuntime1Mixin.scala
new file mode 100644
index 0000000..03e8be5
--- /dev/null
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/LocalElementDeclBaseRuntime1Mixin.scala
@@ -0,0 +1,25 @@
+/*
+ * 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.runtime1
+
+import org.apache.daffodil.dsom.LocalElementDeclBase
+
+trait LocalElementDeclBaseRuntime1Mixin { self: LocalElementDeclBase =>
+
+  requiredEvaluationsIfActivated(elementRuntimeData.initialize)
+}
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ModelGroupRuntime1Mixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ModelGroupRuntime1Mixin.scala
index e9d9b0f..4794402 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ModelGroupRuntime1Mixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ModelGroupRuntime1Mixin.scala
@@ -26,6 +26,8 @@
 
 trait ModelGroupRuntime1Mixin { self: ModelGroup =>
 
+  requiredEvaluationsIfActivated(modelGroupRuntimeData.initialize)
+
   final override lazy val runtimeData: RuntimeData = modelGroupRuntimeData
 
   final override lazy val termRuntimeData: TermRuntimeData = modelGroupRuntimeData
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/SchemaComponentRuntime1Mixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/SchemaComponentRuntime1Mixin.scala
new file mode 100644
index 0000000..63f3413
--- /dev/null
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/SchemaComponentRuntime1Mixin.scala
@@ -0,0 +1,48 @@
+/*
+ * 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.runtime1
+
+import org.apache.daffodil.dsom.SchemaComponent
+import org.apache.daffodil.processors.NonTermRuntimeData
+import org.apache.daffodil.processors.RuntimeData
+
+trait SchemaComponentRuntime1Mixin { self: SchemaComponent =>
+
+  /**
+   * All non-terms get runtimeData from this definition. All Terms
+   * which are elements and model-groups) override this.
+   *
+   * The Term class has a generic termRuntimeData => TermRuntimeData
+   * function (useful since all Terms share things like having charset encoding)
+   * The Element classes all inherit an elementRuntimeData => ElementRuntimeData
+   * and the model groups all have modelGroupRuntimeData => ModelGroupRuntimeData.
+   *
+   * There is also VariableRuntimeData and SchemaSetRuntimeData.
+   */
+  lazy val runtimeData: RuntimeData = nonTermRuntimeData // overrides in ModelGroup, ElementBase, SimpleTypes
+
+  final lazy val nonTermRuntimeData = LV('nonTermRuntimeData) {
+    new NonTermRuntimeData(
+      variableMap,
+      schemaFileLocation,
+      diagnosticDebugName,
+      path,
+      namespaces,
+      tunable.unqualifiedPathStepPolicy)
+  }.value
+
+}
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/SchemaSetRuntime1Mixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/SchemaSetRuntime1Mixin.scala
index 5970d79..103e6b5 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/SchemaSetRuntime1Mixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/SchemaSetRuntime1Mixin.scala
@@ -31,15 +31,27 @@
 import org.apache.daffodil.processors.unparsers.NotUnparsableUnparser
 import org.apache.daffodil.util.LogLevel
 
-import java.io.ObjectOutputStream
-
-trait SchemaSetRuntime1Mixin { self : SchemaSet =>
+trait SchemaSetRuntime1Mixin {
+  self: SchemaSet =>
 
   requiredEvaluationsAlways(parser)
   requiredEvaluationsAlways(unparser)
+  requiredEvaluationsAlways(root.elementRuntimeData.initialize)
 
-  override def variableMap: VariableMap = LV('variableMap) {
-    val dvs = allSchemaDocuments.flatMap { _.defineVariables }
+  /**
+   * This initialization is required for simpleTypeDefs used only
+   * for type calculations where those simpleTypeDefs do not have
+   * a corresponding element of that type.
+   */
+  requiredEvaluationsAlways(typeCalcMap.foreach {
+    case (_, typeCalculator) =>
+      typeCalculator.initialize()
+  })
+
+  override lazy val variableMap: VariableMap = LV('variableMap) {
+    val dvs = allSchemaDocuments.flatMap {
+      _.defineVariables
+    }
     val alldvs = dvs.union(predefinedVars)
     val vmap = VariableMapFactory.create(alldvs)
     //
@@ -74,61 +86,32 @@
   }.value
 
   def onPath(xpath: String): DFDL.DataProcessor = {
-    Assert.usage(!isError)
-    if (xpath != "/") root.notYetImplemented("""Path must be "/". Other path support is not yet implemented.""")
-    val rootERD = root.elementRuntimeData
-    root.schemaDefinitionUnless(
-      rootERD.outputValueCalcExpr.isEmpty,
-      "The root element cannot have the dfdl:outputValueCalc property.")
-    val validationMode = ValidationMode.Off
-    val p = if (!root.isError) parser else null
-    val u = if (!root.isError) unparser else null
-    val ssrd = new SchemaSetRuntimeData(
-      p,
-      u,
-      this.diagnostics,
-      rootERD,
-      variableMap,
-      typeCalcMap)
-    if (root.numComponents > root.numUniqueComponents)
-      log(LogLevel.Info, "Compiler: component counts: unique %s, actual %s.",
-        root.numUniqueComponents, root.numComponents)
-    val dataProc = new DataProcessor(ssrd, tunable, self.compilerExternalVarSettings)
-    //
-    // now we fake serialize to a dev/null-type output stream which forces
-    // any lazy evaluation that hasn't completed to complete.
-    // Those things could signal errors, so we do this before we check for errors.
-    //
-    // Note that calling preSerialization is not sufficient, since that's only mixed into
-    // objects with lazy evaluation. A SSRD is just a tuple-like object, does not mixin
-    // preSerialization, and shouldn't need to. We need to
-    // serialize all its substructure to insure all preSerializations, that force
-    // all lazy evaluations, are done.
-    //
-    // Overhead-wise, this is costly, if the caller is about to save the processor themselves
-    // But as there have been cases of Runtime1 processors which end up doing lazy evaluation
-    // that ends up happening late, this eliminates a source of bugs, albeit, by masking them
-    // so they are not detectable.
-    //
-    // Best to address this for real when we refactor Runtime1 to fully separate it from
-    // the schema compiler. At that point we can draw a firmer line about the compiler's output
-    // being fully realized before runtime objects are constructed.
-    //
-    // We don't call save() here, because that does a few other things than just serialize.
-    val oos = new ObjectOutputStream(org.apache.commons.io.output.NullOutputStream.NULL_OUTPUT_STREAM)
-    oos.writeObject(dataProc)
-
-    if (dataProc.isError) {
-      // NO longer printing anything here. Callers must do this.
-      //        val diags = dataProc.getDiagnostics
-      //        log(LogLevel.Error,"Compilation (DataProcessor) reports %s compile errors/warnings.", diags.length)
-      //        diags.foreach { diag => log(LogLevel.Error, diag.toString()) }
-    } else {
-      log(LogLevel.Compile, "Parser = %s.", ssrd.parser.toString)
-      log(LogLevel.Compile, "Unparser = %s.", ssrd.unparser.toString)
-      log(LogLevel.Compile, "Compilation (DataProcesor) completed with no errors.")
+      Assert.usage(!isError)
+      if (xpath != "/") root.notYetImplemented("""Path must be "/". Other path support is not yet implemented.""")
+      val rootERD = root.elementRuntimeData
+      root.schemaDefinitionUnless(
+        rootERD.outputValueCalcExpr.isEmpty,
+        "The root element cannot have the dfdl:outputValueCalc property.")
+      val validationMode = ValidationMode.Off
+      val p = if (!root.isError) parser else null
+      val u = if (!root.isError) unparser else null
+      val ssrd = new SchemaSetRuntimeData(
+        p,
+        u,
+        this.diagnostics,
+        rootERD,
+        variableMap,
+        typeCalcMap)
+      if (root.numComponents > root.numUniqueComponents)
+        log(LogLevel.Compile, "Compiler: component counts: unique %s, actual %s.",
+          root.numUniqueComponents, root.numComponents)
+      val dataProc = new DataProcessor(ssrd, tunable, self.compilerExternalVarSettings)
+      if (dataProc.isError) {
+      } else {
+        log(LogLevel.Compile, "Parser = %s.", ssrd.parser.toString)
+        log(LogLevel.Compile, "Unparser = %s.", ssrd.unparser.toString)
+        log(LogLevel.Compile, "Compilation (DataProcesor) completed with no errors.")
+      }
+      dataProc
     }
-    dataProc
-  }
-
 }
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/SequenceTermRuntime1Mixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/SequenceTermRuntime1Mixin.scala
index 276b229..549a717 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/SequenceTermRuntime1Mixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/SequenceTermRuntime1Mixin.scala
@@ -22,6 +22,7 @@
 import org.apache.daffodil.processors.SequenceRuntimeData
 import org.apache.daffodil.util.Maybe
 import org.apache.daffodil.processors.FillByteUseNotAllowedEv
+import org.apache.daffodil.util.Delay
 
 trait SequenceTermRuntime1Mixin { self: SequenceTermBase =>
 
@@ -30,7 +31,7 @@
   lazy val sequenceRuntimeData = {
     new SequenceRuntimeData(
       position,
-      partialNextElementResolver,
+      Delay('SequencePartialNextElementResolver, this ,partialNextElementResolver),
       schemaSet.variableMap,
       encodingInfo,
       // elementChildren.map { _.elementRuntimeData.dpathElementCompileInfo },
@@ -54,10 +55,12 @@
 
 trait ChoiceBranchImpliedSequenceRuntime1Mixin { self: ChoiceBranchImpliedSequence =>
 
+  requiredEvaluationsIfActivated(sequenceRuntimeData.initialize)
+
   override lazy val sequenceRuntimeData: SequenceRuntimeData = {
     new SequenceRuntimeData(
       position,
-      partialNextElementResolver,
+      Delay('ChoiceBranchImpliedSequencePartialNextElementResolver, this, partialNextElementResolver),
       schemaSet.variableMap,
       encodingInfo,
       schemaFileLocation,
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/SimpleTypeRuntime1Mixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/SimpleTypeRuntime1Mixin.scala
new file mode 100644
index 0000000..e150832
--- /dev/null
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/SimpleTypeRuntime1Mixin.scala
@@ -0,0 +1,62 @@
+/*
+ * 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.runtime1
+
+import org.apache.daffodil.dsom.SimpleTypeDefBase
+import org.apache.daffodil.processors.SimpleTypeRuntimeData
+
+trait SimpleTypeRuntime1Mixin { self: SimpleTypeDefBase =>
+
+  /**
+   * Initialize cyclic structure
+   */
+  requiredEvaluationsIfActivated(
+    simpleTypeRuntimeData.typeCalculator.map{ tc =>
+      tc.initialize
+    })
+
+  lazy val simpleTypeRuntimeData: SimpleTypeRuntimeData = {
+    val strd =
+      new SimpleTypeRuntimeData(
+        variableMap,
+        schemaFileLocation,
+        diagnosticDebugName,
+        path,
+        namespaces,
+        primType,
+        noFacetChecks,
+        optRestriction.toSeq.flatMap { r => if (r.hasPattern) r.patternValues else Nil },
+        optRestriction.flatMap { r => toOpt(r.hasEnumeration, r.enumerationValues.get) },
+        optRestriction.flatMap { r => toOpt(r.hasMinLength, r.minLengthValue) },
+        optRestriction.flatMap { r => toOpt(r.hasMaxLength, r.maxLengthValue) },
+        optRestriction.flatMap { r => toOpt(r.hasMinInclusive, r.minInclusiveValue) },
+        optRestriction.flatMap { r => toOpt(r.hasMaxInclusive, r.maxInclusiveValue) },
+        optRestriction.flatMap { r => toOpt(r.hasMinExclusive, r.minExclusiveValue) },
+        optRestriction.flatMap { r => toOpt(r.hasMaxExclusive, r.maxExclusiveValue) },
+        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.unqualifiedPathStepPolicy,
+        optRepTypeDef.map(_.simpleTypeRuntimeData),
+        optRepValueSet,
+        optTypeCalculator,
+        optRepType.map(_.primType))
+    strd
+  }
+  override lazy val runtimeData = simpleTypeRuntimeData
+}
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/TermRuntime1Mixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/TermRuntime1Mixin.scala
index 3ed3012..1ad23c0 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/TermRuntime1Mixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/TermRuntime1Mixin.scala
@@ -20,10 +20,18 @@
 import org.apache.daffodil.xml.QNameBase
 import org.apache.daffodil.api.WarnID
 import org.apache.daffodil.dsom._
-import org.apache.daffodil.processors.{ByteOrderEv, ElementRuntimeData, CheckBitOrderAndCharsetEv, CheckByteAndBitOrderEv, TermRuntimeData}
+import org.apache.daffodil.processors.ByteOrderEv
+import org.apache.daffodil.processors.CheckBitOrderAndCharsetEv
+import org.apache.daffodil.processors.CheckByteAndBitOrderEv
+import org.apache.daffodil.processors.ElementRuntimeData
+import org.apache.daffodil.processors.TermRuntimeData
 import org.apache.daffodil.schema.annotation.props.gen.NilKind
 import org.apache.daffodil.exceptions.Assert
-import org.apache.daffodil.infoset.{PartialNextElementResolver, SeveralPossibilitiesForNextElement, NoNextElement, OnlyOnePossibilityForNextElement, DoNotUseThisResolver}
+import org.apache.daffodil.infoset.DoNotUseThisResolver
+import org.apache.daffodil.infoset.NoNextElement
+import org.apache.daffodil.infoset.OnlyOnePossibilityForNextElement
+import org.apache.daffodil.infoset.PartialNextElementResolver
+import org.apache.daffodil.infoset.SeveralPossibilitiesForNextElement
 import org.apache.daffodil.util.Maybe
 
 /**
@@ -197,8 +205,10 @@
    * Within the lexically enclosing model group, if that group is a sequence, then
    * this computation involves subsequent siblings, children of those siblings.
    */
-  lazy val possibleNextLexicalSiblingStreamingUnparserElements: PossibleNextElements = {
-    val res = this match {
+  lazy val (hasNamesDifferingOnlyByNS: Boolean,
+    possibleNextLexicalSiblingStreamingUnparserElements: PossibleNextElements) = {
+    var hasNamesDifferingOnlyByNS = false
+    val possibles = this match {
       // Quasi elements are used for type-value calc, and for prefixed lengths
       // we never consider them for streaming unparsing. They are never present as events.
       // Nor should they ever be used as the source of next-event information.
@@ -221,7 +231,32 @@
       case _ =>
         possibleSelfPlusNextLexicalSiblingStreamingUnparserElements
     }
-    res
+    //
+    // Check for ambiguity except for namespaces
+    // Since some Infoset representations (e.g., JSON) can't support that
+    //
+    val sibs = possibles match {
+      case PossibleNextElements.Closed(sibs) => sibs
+      case PossibleNextElements.Open(sibs) => sibs
+      case PossibleNextElements.DoNotUse => Nil
+    }
+    if (sibs.size > 1) {
+      val groupedByName = possibles.pnes.groupBy(_.e.namedQName.local)
+      groupedByName.foreach {
+        case (_, sameNamesEB) =>
+          if (sameNamesEB.length > 1) {
+            SDW(
+              WarnID.NamespaceDifferencesOnly,
+              "Neighboring QNames differ only by namespaces. " +
+                "Infoset representations that do not support namespaces " +
+                "cannot differentiate between these elements and " +
+                "may fail to unparse. QNames are: %s",
+              sameNamesEB.map(_.e.namedQName.toExtendedSyntax).mkString(", "))
+            hasNamesDifferingOnlyByNS = true
+          }
+      }
+    }
+    (hasNamesDifferingOnlyByNS, possibles)
   }
 
   final protected lazy val possibleSelfPlusNextLexicalSiblingStreamingUnparserElements: PossibleNextElements =
@@ -381,7 +416,6 @@
   final lazy val partialNextElementResolver: PartialNextElementResolver = {
     val context = self
     val possibles = possibleNextLexicalSiblingStreamingUnparserElements
-
     self match {
       case _: QuasiElementDeclBase => {
         Assert.invariant(possibles eq PossibleNextElements.DoNotUse)
@@ -410,21 +444,6 @@
             sibs.head.e.erd,
             isRequiredStreamingUnparserEvent)
           case _ => {
-            val groupedByName = possibles.pnes.groupBy(_.e.namedQName.local)
-            var hasNamesDifferingOnlyByNS = false
-            groupedByName.foreach {
-              case (_, sameNamesEB) =>
-                if (sameNamesEB.length > 1) {
-                  context.SDW(
-                    WarnID.NamespaceDifferencesOnly,
-                    "Neighboring QNames differ only by namespaces. " +
-                      "Infoset representations that do not support namespaces " +
-                      "cannot differentiate between these elements and " +
-                      "may fail to unparse. QNames are: %s",
-                    sameNamesEB.map(_.e.namedQName.toExtendedSyntax).mkString(", "))
-                  hasNamesDifferingOnlyByNS = true
-                }
-            }
             new SeveralPossibilitiesForNextElement(
               trd,
               eltMap,
@@ -575,7 +594,7 @@
   }
 
   lazy val maybeCheckBitOrderAndCharsetEv: Maybe[CheckBitOrderAndCharsetEv] = {
-    val se = summaryEncoding
+    lazy val se = summaryEncoding
     if (!isRepresented || se == NoText || se == Binary)
       Maybe.Nope
     else {
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/VariableRuntime1Mixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/VariableRuntime1Mixin.scala
new file mode 100644
index 0000000..b8142c7
--- /dev/null
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/VariableRuntime1Mixin.scala
@@ -0,0 +1,110 @@
+/*
+ * 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.runtime1
+
+import org.apache.daffodil.dsom.DFDLDefineVariable
+import org.apache.daffodil.dsom.DFDLNewVariableInstance
+import org.apache.daffodil.dsom.DFDLSetVariable
+import org.apache.daffodil.dsom.ExpressionCompilers
+import org.apache.daffodil.dsom.VariableReference
+import org.apache.daffodil.processors.VariableRuntimeData
+import org.apache.daffodil.schema.annotation.props.Found
+import org.apache.daffodil.util.Delay
+import org.apache.daffodil.util.Maybe
+import org.apache.daffodil.xml.GlobalQName
+import org.apache.daffodil.xml.XMLUtils
+
+trait DFDLDefineVariableRuntime1Mixin { self: DFDLDefineVariable =>
+
+  requiredEvaluationsAlways(variableRuntimeData.initialize)
+
+  final lazy val variableRuntimeData = {
+    val vrd = new VariableRuntimeData(
+      this.schemaFileLocation,
+      this.diagnosticDebugName,
+      this.path,
+      this.namespaces,
+      this.external,
+      this.direction,
+      Delay('maybeDefaultValueExpr, this, maybeDefaultValueExpr),
+      this.typeQName,
+      this.namedQName.asInstanceOf[GlobalQName],
+      this.primType,
+      this.tunable.unqualifiedPathStepPolicy)
+    vrd
+  }
+
+  final override lazy val runtimeData = variableRuntimeData
+
+  lazy val maybeDefaultValueExpr = {
+    val compilationTargetType = primType
+    val qn = this.qNameForProperty("defaultValue", XMLUtils.dafintURI)
+    val defaultValExpr = defaultValue.map { e =>
+      ExpressionCompilers.AnyRef.compileProperty(qn, compilationTargetType, Found(e, this.dpathCompileInfo, "defaultValue", false), this, dpathCompileInfo)
+    }
+
+    Maybe.toMaybe(defaultValExpr)
+  }
+}
+
+trait VariableReferenceRuntime1Mixin { self: VariableReference =>
+
+  def variableRuntimeData: VariableRuntimeData
+
+}
+
+trait DFDLNewVariableInstanceRuntime1Mixin { self: DFDLNewVariableInstance =>
+
+  requiredEvaluationsIfActivated(variableRuntimeData.initialize)
+
+  /* Need to override variableRuntimeData so that defaultValues
+  * are read from newVariableInstance instead of the original
+  * variable definition. Also allows diagnostic messages to
+  * point to this location instead of the original definition
+  */
+  final override lazy val variableRuntimeData = {
+    val vrd = new VariableRuntimeData(
+      this.schemaFileLocation,
+      this.diagnosticDebugName,
+      this.path,
+      this.namespaces,
+      defv.external,
+      defv.direction,
+      Delay('maybeDefaultValueExpr2, this, maybeDefaultValueExpr),
+      defv.typeQName,
+      defv.namedQName.asInstanceOf[GlobalQName],
+      defv.primType,
+      this.tunable.unqualifiedPathStepPolicy)
+    vrd
+  }
+
+  lazy val maybeDefaultValueExpr = {
+    val compilationTargetType = defv.primType
+    val qn = this.qNameForProperty("defaultValue", XMLUtils.dafintURI)
+    val defaultValExpr = defaultValue.map { e =>
+      ExpressionCompilers.AnyRef.compileProperty(qn, compilationTargetType, Found(e, this.dpathCompileInfo, "defaultValue", false), this, dpathCompileInfo)
+    }
+
+    Maybe.toMaybe(defaultValExpr)
+  }
+}
+
+trait DFDLSetVariableRuntime1Mixin { self: DFDLSetVariable =>
+
+  final override def variableRuntimeData = defv.variableRuntimeData
+}
\ No newline at end of file
diff --git a/daffodil-core/src/test/scala/org/apache/daffodil/api/TestForHeapDump.scala b/daffodil-core/src/test/scala/org/apache/daffodil/api/TestForHeapDump.scala
new file mode 100644
index 0000000..75ed6e6
--- /dev/null
+++ b/daffodil-core/src/test/scala/org/apache/daffodil/api/TestForHeapDump.scala
@@ -0,0 +1,188 @@
+/*
+ * 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.api;
+
+
+import org.apache.daffodil.util.TestUtils.compileSchema
+import org.apache.daffodil.util._
+import org.junit.Assert.fail
+// import org.junit.Test
+
+import scala.xml.NodeSeq
+
+/**
+ * Test rig that allows capture of heap dumps using jvisualVM, for subsequent
+ * analysis.
+ *
+ * The tests at one time created a jvisualVM heap dump showing
+ * retention of large numbers of DFDL schema compiler data structures.
+ * These are no longer being detected, but the test rig is here for future needs.
+ *
+ * Note that the @Test keywords are commented out.
+ */
+class TestForHeapDump {
+
+  val rootElem =
+    <xs:element name="r" dfdl:lengthKind="implicit">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="e1" type="xs:int" dfdl:length="1"/>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+  /**
+   * Gets a data processor, allowing (in theory) all the other compiler data structures
+   * to be reclaimed by the GC.
+   *
+   * This variant uses a standard include of the DFDLGeneralFormat.
+   */
+  def getDataProcWithInclude() = {
+    val sch = SchemaUtils.dfdlTestSchema(
+        <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
+        <dfdl:format ref="tns:GeneralFormat" lengthKind="explicit"/>,
+      rootElem,
+      elementFormDefault = "unqualified",
+      useDefaultNamespace = false)
+    val p = compileSchema(sch).withValidationMode(ValidationMode.Off)
+    p
+  }
+
+  /**
+   * Gets a data processor, allowing (in theory) all the other compiler data structures
+   * to be reclaimed by the GC.
+   *
+   * This variant is fully self-contained. There are no import/includes.
+   */
+  def getDataProcNoInclude() = {
+    val sch = SchemaUtils.dfdlTestSchema(
+      NodeSeq.Empty,
+        <dfdl:format
+        alignment="1"
+        alignmentUnits="bytes"
+        binaryFloatRep="ieee"
+        binaryNumberCheckPolicy="lax"
+        binaryNumberRep="binary"
+        binaryCalendarEpoch="1970-01-01T00:00:00"
+        bitOrder="mostSignificantBitFirst"
+        byteOrder="bigEndian"
+        calendarCenturyStart="53"
+        calendarCheckPolicy="strict"
+        calendarDaysInFirstWeek="4"
+        calendarFirstDayOfWeek="Sunday"
+        calendarLanguage="en"
+        calendarObserveDST="yes"
+        calendarPatternKind="implicit"
+        calendarTimeZone=""
+        choiceLengthKind="implicit"
+        decimalSigned="yes"
+        documentFinalTerminatorCanBeMissing="no"
+        emptyValueDelimiterPolicy="both"
+        encodingErrorPolicy="replace"
+        encoding="US-ASCII"
+        escapeSchemeRef=""
+        fillByte="%#r20;"
+        floating="no"
+        ignoreCase="no"
+        initiatedContent="no"
+        initiator=""
+        leadingSkip="0"
+        lengthKind="explicit"
+        lengthUnits="bytes"
+        occursCountKind="implicit"
+        outputNewLine="%LF;"
+        representation="text"
+        separator=""
+        separatorPosition="infix"
+        separatorSuppressionPolicy="anyEmpty"
+        sequenceKind="ordered"
+        terminator=""
+        textBidi="no"
+        textBooleanPadCharacter="%SP;"
+        textCalendarJustification="left"
+        textCalendarPadCharacter="%SP;"
+        textNumberCheckPolicy="lax"
+        textNumberJustification="right"
+        textNumberPadCharacter="%SP;"
+        textNumberPattern="#,##0.###;-#,##0.###"
+        textNumberRep="standard"
+        textNumberRounding="explicit"
+        textNumberRoundingIncrement="0"
+        textNumberRoundingMode="roundHalfEven"
+        textOutputMinLength="0"
+        textPadKind="none"
+        textStandardBase="10"
+        textStandardDecimalSeparator="."
+        textStandardExponentRep="E"
+        textStandardGroupingSeparator=","
+        textStandardInfinityRep="Inf"
+        textStandardNaNRep="NaN"
+        textStandardZeroRep="0"
+        textStringJustification="left"
+        textStringPadCharacter="%SP;"
+        textTrimKind="none"
+        trailingSkip="0"
+        truncateSpecifiedLengthString="no"
+        utf16Width="fixed"
+        />,
+      rootElem,
+      elementFormDefault = "unqualified",
+      useDefaultNamespace = false)
+    val p = compileSchema(sch).withValidationMode(ValidationMode.Off)
+    p
+  }
+
+  def gcAndAllowHeapDump(): Unit = {
+    System.gc()
+    System.runFinalization()
+    System.gc()
+    System.out.println("Take a Heap Dump Now! (You have 10 seconds)")
+    Thread.sleep(10000)
+    System.out.println("Too late")
+  }
+
+  /**
+   * Use to get a heap dump for this simple DFDL schema showing that
+   * it does NOT contain any DSOM objects E.g., there are zero
+   * retained instances of the SchemaSet class, or the LocalElementDecl class, and so on.
+   *
+   * Numerous "Lambda" objects - code that is output from the Scala compiler - are
+   * created but these are small, and in general there is exactly one of each.
+   */
+  // @Test
+  def testMemoryObjects_ForUseWithHeapDump_NoInclude(): Unit = {
+    val p = getDataProcNoInclude()
+    gcAndAllowHeapDump()
+    if (p eq null) fail("no processor")
+  }
+
+  /**
+   * Use to get a heap dump for this simple DFDL schema
+   *
+   * The heap dump can be analyzed to show any
+   * schema-compiler data structures that are retained, allowing them to be
+   * visualized for debugging/etc. This includes
+   * DSOM objects, grammar Prod objects, etc.
+   */
+  // @Test
+  def testMemoryObjects_ForUseWithHeapDump_WithInclude(): Unit = {
+    val p = getDataProcWithInclude()
+    gcAndAllowHeapDump()
+    if (p eq null) fail("no processor")
+  }
+}
diff --git a/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestDsomCompiler.scala b/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestDsomCompiler.scala
index b393480..2dc93b0 100644
--- a/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestDsomCompiler.scala
+++ b/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestDsomCompiler.scala
@@ -17,14 +17,25 @@
 
 package org.apache.daffodil.dsom
 
-import scala.xml.{ XML, Utility, Node }
-import org.junit.Test
+import scala.xml.Node
+import scala.xml.Utility
+import scala.xml.XML
 import org.apache.daffodil.compiler._
 import org.apache.daffodil.Implicits._; object INoWarnDSOM1 { ImplicitsSuppressUnusedImportWarning() }
-import org.apache.daffodil.schema.annotation.props.gen.{ YesNo, TextNumberRep, SeparatorPosition, Representation, OccursCountKind, NilKind, LengthKind, ChoiceLengthKind, ByteOrder, BinaryNumberRep, AlignmentUnits }
-
+import org.apache.daffodil.schema.annotation.props.gen.AlignmentUnits
+import org.apache.daffodil.schema.annotation.props.gen.BinaryNumberRep
+import org.apache.daffodil.schema.annotation.props.gen.ByteOrder
+import org.apache.daffodil.schema.annotation.props.gen.ChoiceLengthKind
+import org.apache.daffodil.schema.annotation.props.gen.LengthKind
+import org.apache.daffodil.schema.annotation.props.gen.NilKind
+import org.apache.daffodil.schema.annotation.props.gen.OccursCountKind
+import org.apache.daffodil.schema.annotation.props.gen.Representation
+import org.apache.daffodil.schema.annotation.props.gen.SeparatorPosition
+import org.apache.daffodil.schema.annotation.props.gen.TextNumberRep
+import org.apache.daffodil.schema.annotation.props.gen.YesNo
 import org.apache.daffodil.schema.annotation.props.AlignmentType
-import org.apache.daffodil.util.{ Misc, Logging }
+import org.apache.daffodil.util.Logging
+import org.apache.daffodil.util.Misc
 import org.apache.daffodil.xml.XMLUtils
 import org.junit.Assert._
 import org.apache.daffodil.api.Diagnostic
@@ -199,8 +210,8 @@
     val Seq(ct) = schemaDoc.globalComplexTypeDefs
     assertEquals("example1", ct.name)
 
-    val mg = ct.modelGroup.asInstanceOf[Sequence]
-    assertTrue(mg.isInstanceOf[Sequence])
+    val mg = ct.modelGroup.asInstanceOf[LocalSequence]
+    assertTrue(mg.isInstanceOf[LocalSequence])
 
     val Seq(elem) = mg.groupMembers
     assertTrue(elem.isInstanceOf[LocalElementDecl])
@@ -209,7 +220,7 @@
   @Test def test3: Unit = {
     val testSchema = XML.load(Misc.getRequiredResource("/test/example-of-most-dfdl-constructs.dfdl.xml").toURL)
 
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val Seq(sd, _) = sch.schemaDocuments
 
@@ -229,7 +240,7 @@
     assertTrue(a2.isInstanceOf[DFDLAssert]) // second annotation is newVariableInstance
     assertEquals(OccursCountKind.Implicit.toString, e3.getProperty("occursCountKind"))
     // Explore local complex type def
-    val seq = e1.complexType.modelGroup.asInstanceOf[Sequence] //... which is a sequence
+    val seq = e1.complexType.modelGroup.asInstanceOf[LocalSequence] //... which is a sequence
     seq.formatAnnotation.asInstanceOf[DFDLSequence] //...annotated with...
     assertEquals(YesNo.No, seq.initiatedContent) // initiatedContent="no"
 
@@ -291,7 +302,7 @@
   @Test def test4: Unit = {
     val testSchema = XML.load(Misc.getRequiredResource("/test/example-of-most-dfdl-constructs.dfdl.xml").toURL)
 
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val Seq(sd, _) = sch.schemaDocuments
 
@@ -321,7 +332,7 @@
         Misc.getRequiredResource(
           "/test/example-of-named-format-chaining-and-element-simpleType-property-combining.dfdl.xml").toURL)
 
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val Seq(sd) = sch.schemaDocuments
 
@@ -339,7 +350,7 @@
         Misc.getRequiredResource(
           "/test/example-of-named-format-chaining-and-element-simpleType-property-combining.dfdl.xml").toURL)
 
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val Seq(sd) = sch.schemaDocuments
 
@@ -354,7 +365,7 @@
         Misc.getRequiredResource(
           "/test/example-of-named-format-chaining-and-element-simpleType-property-combining.dfdl.xml").toURL)
 
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val Seq(sd) = sch.schemaDocuments
 
@@ -383,7 +394,7 @@
   @Test def test_simpleType_base_combining: Unit = {
     val testSchema = XML.load(Misc.getRequiredResource("/test/example-of-most-dfdl-constructs.dfdl.xml").toURL)
 
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val root = sset.root
     val Seq(sd, _) = sch.schemaDocuments
@@ -430,7 +441,7 @@
   @Test def test_group_references: Unit = {
     val testSchema = XML.load(Misc.getRequiredResource("/test/example-of-most-dfdl-constructs.dfdl.xml").toURL)
 
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val Seq(sd, _) = sch.schemaDocuments
 
@@ -483,7 +494,7 @@
   @Test def test_ibm_7132: Unit = {
     val ibm7132Schema = XML.load(Misc.getRequiredResource("/test/TestRefChainingIBM7132.dfdl.xml").toURL)
     // val ibm7132Schema = "test/TestRefChainingIBM7132.dfdl.xml"
-    val sset = new SchemaSet(ibm7132Schema)
+    val sset = SchemaSet(ibm7132Schema)
     // val Seq(sch) = sset.schemas
     val Seq(sd) = sset.allSchemaDocuments
 
@@ -514,7 +525,7 @@
       <dfdl:defineFormat name="ref1"> <dfdl:format initiator=":"/> </dfdl:defineFormat>,
       <xs:element name="e1" dfdl:lengthKind="implicit" dfdl:ref="tns:ref1" type="xs:string">
       </xs:element>)
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val Seq(sd, _) = sch.schemaDocuments
 
@@ -532,7 +543,7 @@
       </dfdl:defineFormat>,
       <xs:element name="e1" dfdl:lengthKind="implicit" dfdl:ref="tns:ref1" type="xs:string">
       </xs:element>)
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val Seq(sd, _) = sch.schemaDocuments
 
@@ -559,7 +570,7 @@
   @Test def test_escapeSchemeOverride = {
     val testSchema = SchemaUtils.dfdlTestSchema(
       <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
-      <dfdl:format separator="" initiator="" terminator="" emptyValueDelimiterPolicy="none" textNumberRep="standard" representation="text" occursStopValue="-1" occursCountKind="expression" escapeSchemeRef="pound"/>
+      <dfdl:format ref="tns:GeneralFormat" separator="" initiator="" terminator="" emptyValueDelimiterPolicy="none" textNumberRep="standard" representation="text" occursStopValue="-1" occursCountKind="expression" escapeSchemeRef="pound"/>
       <dfdl:defineEscapeScheme name="pound">
         <dfdl:escapeScheme escapeCharacter='#' escapeKind="escapeCharacter"/>
       </dfdl:defineEscapeScheme>
@@ -574,7 +585,7 @@
           </xs:sequence>
         </xs:complexType>
       </xs:element>)
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val Seq(sd, _) = sch.schemaDocuments
 
@@ -602,7 +613,7 @@
   @Test def test_element_references: Unit = {
     val testSchema = XML.load(Misc.getRequiredResource("/test/example-of-most-dfdl-constructs.dfdl.xml").toURL)
 
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val Seq(sd, _) = sch.schemaDocuments
 
@@ -637,7 +648,7 @@
           </xs:sequence>
         </xs:sequence>
       </xs:complexType>)
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val Seq(sd, _) = sch.schemaDocuments
 
@@ -647,7 +658,7 @@
     val seq = ge1.sequence
 
     val Seq(_, _, s3) = seq.groupMembers
-    val s3s = s3.asInstanceOf[Sequence]
+    val s3s = s3.asInstanceOf[LocalSequence]
     val Seq(es) = s3s.groupMembers
     val ese = es.asInstanceOf[LocalElementDecl]
     assertTrue(ese.path.contains("sequence[3]"))
diff --git a/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestExternalVariables.scala b/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestExternalVariables.scala
index e6d0a5d..8dbf0d0 100644
--- a/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestExternalVariables.scala
+++ b/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestExternalVariables.scala
@@ -68,7 +68,7 @@
           <xs:sequence/>
         </xs:choice>
       </xs:group>)
-    lazy val xsd_sset = new SchemaSet(sch, "http://example.com", "fake")
+    lazy val xsd_sset = SchemaSet(sch, "http://example.com", "fake")
     lazy val xsd_schema = xsd_sset.getSchema(NS("http://example.com")).get
     lazy val fakeSD = xsd_schema.schemaDocuments(0)
     (fakeSD, xsd_sset)
diff --git a/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestMiddleEndAttributes.scala b/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestMiddleEndAttributes.scala
index f315e7e..2bb1d56 100644
--- a/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestMiddleEndAttributes.scala
+++ b/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestMiddleEndAttributes.scala
@@ -41,7 +41,7 @@
         </xs:complexType>
       </xs:element>)
 
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val Seq(sd, _) = sch.schemaDocuments
 
@@ -67,7 +67,7 @@
         </xs:complexType>
       </xs:element>)
 
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val Seq(sd, _) = sch.schemaDocuments
 
@@ -96,7 +96,7 @@
         </xs:complexType>
       </xs:element>)
 
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val Seq(sd, _) = sch.schemaDocuments
 
@@ -128,7 +128,7 @@
         </xs:complexType>
       </xs:element>)
 
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val Seq(sd, _) = sch.schemaDocuments
 
@@ -139,11 +139,11 @@
     val Seq(seqMem) = seq.groupMembers
     val cho = seqMem.asInstanceOf[Choice]
     val Seq(s1, s2) = cho.groupMembers
-    val es = s1.optLexicalParent.get.optLexicalParent.get.asInstanceOf[Sequence]
+    val es = s1.optLexicalParent.get.optLexicalParent.get.asInstanceOf[LocalSequence]
     assertTrue(es.hasInfixSep)
     assertEquals(1, s1.position)
     assertTrue(s1.isScalar)
-    val es2 = s2.optLexicalParent.get.optLexicalParent.get.asInstanceOf[Sequence]
+    val es2 = s2.optLexicalParent.get.optLexicalParent.get.asInstanceOf[LocalSequence]
     assertEquals(es, es2)
     assertEquals(2, s2.position)
     assertTrue(s2.isScalar)
@@ -164,7 +164,7 @@
         </xs:complexType>
       </xs:element>)
 
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val Seq(sd, _) = sch.schemaDocuments
 
@@ -175,7 +175,7 @@
     val mems = seq.groupMembers
     val Seq(t1: Term) = mems
     val e1ref = t1.asInstanceOf[ElementRef]
-    val Some(nes: Sequence) = e1ref.optLexicalParent
+    val Some(nes: LocalSequence) = e1ref.optLexicalParent
     assertEquals(seq, nes)
   }
 
@@ -205,7 +205,7 @@
         </xs:complexType>
       </xs:element>)
 
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val Seq(sd, _) = sch.schemaDocuments
 
diff --git a/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestMiddleEndAttributes2.scala b/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestMiddleEndAttributes2.scala
index c55ba40..920b813 100644
--- a/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestMiddleEndAttributes2.scala
+++ b/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestMiddleEndAttributes2.scala
@@ -40,7 +40,7 @@
         </xs:complexType>
       </xs:element>)
 
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val Seq(sd, _) = sch.schemaDocuments
 
@@ -50,7 +50,7 @@
     val seq1 = e1ct.sequence
     val mems = seq1.groupMembers
     val Seq(t1: Term) = mems
-    t1.asInstanceOf[Sequence]
+    t1.asInstanceOf[LocalSequence]
     val (_, actual) = TestUtils.testString(testSchema, "/5")
     val expected = <e1><x>5</x></e1>
     TestUtils.assertEqualsXMLElements(expected, actual)
diff --git a/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestMiddleEndAttributes3.scala b/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestMiddleEndAttributes3.scala
index c60b966..ea63868 100644
--- a/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestMiddleEndAttributes3.scala
+++ b/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestMiddleEndAttributes3.scala
@@ -50,7 +50,7 @@
         </xs:complexType>
       </xs:element>)
 
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val Seq(sd, _) = sch.schemaDocuments
 
@@ -100,7 +100,7 @@
         </xs:complexType>
       </xs:element>)
 
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     val Seq(sch) = sset.schemas
     val Seq(sd, _) = sch.schemaDocuments
 
diff --git a/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestRefMap.scala b/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestRefMap.scala
index 905602a..2811a32 100644
--- a/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestRefMap.scala
+++ b/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestRefMap.scala
@@ -17,8 +17,7 @@
 
 package org.apache.daffodil.dsom
 
-import org.junit.Test
-import org.apache.daffodil.compiler._;
+import org.apache.daffodil.compiler._
 import org.apache.daffodil.util.Logging
 import org.apache.daffodil.xml.XMLUtils
 import org.junit.Assert._
@@ -34,9 +33,9 @@
 
   @Test def testRefMapEmpty(): Unit = {
     val testSchema = SchemaUtils.dfdlTestSchema(
-      <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
-      <dfdl:format ref="tns:GeneralFormat"/>,
-      <xs:element name="r" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>)
+        <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
+        <dfdl:format ref="tns:GeneralFormat"/>,
+        <xs:element name="r" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>)
     val compiler = Compiler()
     val sset = compiler.compileNode(testSchema).sset
     val root = sset.root
@@ -51,14 +50,14 @@
 
   @Test def testRefMapComplex1(): Unit = {
     val testSchema = SchemaUtils.dfdlTestSchema(
-      <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
-      <dfdl:format ref="tns:GeneralFormat"/>,
-      <xs:element name="r" type="ex:ct"/>
-      <xs:complexType name="ct">
-        <xs:sequence>
-          <xs:element name="e" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
-        </xs:sequence>
-      </xs:complexType>)
+        <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
+        <dfdl:format ref="tns:GeneralFormat"/>,
+        <xs:element name="r" type="ex:ct"/>
+        <xs:complexType name="ct">
+          <xs:sequence>
+            <xs:element name="e" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+          </xs:sequence>
+        </xs:complexType>)
     val compiler = Compiler()
     val sset = compiler.compileNode(testSchema).sset
     val root = sset.root
@@ -76,17 +75,17 @@
 
   @Test def testRefMapGroupRefSeq1(): Unit = {
     val testSchema = SchemaUtils.dfdlTestSchema(
-      <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
-      <dfdl:format ref="tns:GeneralFormat"/>,
-      <xs:element name="r" type="ex:ct"/>
-      <xs:complexType name="ct">
-        <xs:group ref="ex:g"/>
-      </xs:complexType>
-      <xs:group name="g">
-        <xs:sequence>
-          <xs:element name="e" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
-        </xs:sequence>
-      </xs:group>)
+        <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
+        <dfdl:format ref="tns:GeneralFormat"/>,
+        <xs:element name="r" type="ex:ct"/>
+        <xs:complexType name="ct">
+          <xs:group ref="ex:g"/>
+        </xs:complexType>
+        <xs:group name="g">
+          <xs:sequence>
+            <xs:element name="e" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+          </xs:sequence>
+        </xs:group>)
     val compiler = Compiler()
     val sset = compiler.compileNode(testSchema).sset
     val root = sset.root
@@ -110,18 +109,18 @@
 
   @Test def testRefMapGroupRefChoice1(): Unit = {
     val testSchema = SchemaUtils.dfdlTestSchema(
-      <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
-      <dfdl:format ref="tns:GeneralFormat"/>,
-      <xs:element name="r" type="ex:ct"/>
-      <xs:complexType name="ct">
-        <xs:group ref="ex:g"/>
-      </xs:complexType>
-      <xs:group name="g">
-        <xs:choice>
-          <xs:element name="e" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
-          <xs:element name="f" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
-        </xs:choice>
-      </xs:group>)
+        <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
+        <dfdl:format ref="tns:GeneralFormat"/>,
+        <xs:element name="r" type="ex:ct"/>
+        <xs:complexType name="ct">
+          <xs:group ref="ex:g"/>
+        </xs:complexType>
+        <xs:group name="g">
+          <xs:choice>
+            <xs:element name="e" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+            <xs:element name="f" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+          </xs:choice>
+        </xs:group>)
     val compiler = Compiler()
     val sset = compiler.compileNode(testSchema).sset
     val root = sset.root
@@ -145,29 +144,29 @@
 
   @Test def testRefMapGroupRefNest1(): Unit = {
     val testSchema = SchemaUtils.dfdlTestSchema(
-      <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
-      <dfdl:format ref="tns:GeneralFormat"/>,
-      <xs:element name="r" type="ex:ct"/>
-      <xs:complexType name="ct">
-        <xs:group ref="ex:g"/>
-      </xs:complexType>
-      <xs:group name="g">
-        <xs:choice>
-          <xs:element name="e" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
-          <xs:element name="f" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
-          <xs:element ref="ex:r1"/>
-        </xs:choice>
-      </xs:group>
-      <xs:element name="r1" type="ex:ct1"/>
-      <xs:complexType name="ct1">
-        <xs:sequence dfdl:hiddenGroupRef="ex:g1"/>
-      </xs:complexType>
-      <xs:group name="g1">
-        <xs:choice>
-          <xs:element name="e1" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit" dfdl:outputValueCalc="{ 0 }"/>
-          <xs:element name="f1" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
-        </xs:choice>
-      </xs:group>)
+        <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
+        <dfdl:format ref="tns:GeneralFormat"/>,
+        <xs:element name="r" type="ex:ct"/>
+        <xs:complexType name="ct">
+          <xs:group ref="ex:g"/>
+        </xs:complexType>
+        <xs:group name="g">
+          <xs:choice>
+            <xs:element name="e" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+            <xs:element name="f" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+            <xs:element ref="ex:r1"/>
+          </xs:choice>
+        </xs:group>
+          <xs:element name="r1" type="ex:ct1"/>
+        <xs:complexType name="ct1">
+          <xs:sequence dfdl:hiddenGroupRef="ex:g1"/>
+        </xs:complexType>
+        <xs:group name="g1">
+          <xs:choice>
+            <xs:element name="e1" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit" dfdl:outputValueCalc="{ 0 }"/>
+            <xs:element name="f1" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+          </xs:choice>
+        </xs:group>)
     val compiler = Compiler()
     val sset = compiler.compileNode(testSchema).sset
     val root = sset.root
@@ -191,29 +190,30 @@
 
   @Test def testRefMapNonExplosion1(): Unit = {
     val testSchema = SchemaUtils.dfdlTestSchema(
-      <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
-      <dfdl:format ref="tns:GeneralFormat"/>,
-      <xs:element name="r" type="ex:ct"/>
-      <xs:complexType name="ct">
-        <xs:sequence>
-          <xs:group ref="ex:g"/>
-          <xs:group ref="ex:g"/>
-        </xs:sequence>
-      </xs:complexType>
-      <xs:group name="g">
-        <xs:choice>
-          <xs:element ref="ex:r1"/>
-          <xs:element ref="ex:r1"/>
-        </xs:choice>
-      </xs:group>
-      <xs:element name="r1">
-        <xs:complexType>
+        <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
+        <dfdl:format ref="tns:GeneralFormat"/>,
+        <xs:element name="r" type="ex:ct"/>
+        <xs:complexType name="ct">
           <xs:sequence>
-            <xs:element name="e1" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
-            <xs:element name="f1" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+            <xs:group ref="ex:g"/>
+            <xs:group ref="ex:g"/>
           </xs:sequence>
         </xs:complexType>
-      </xs:element>)
+        <xs:group name="g">
+          <xs:sequence>
+            <!-- a choice here would be UPA ambiguous -->
+            <xs:element ref="ex:r1"/>
+            <xs:element ref="ex:r1"/>
+          </xs:sequence>
+        </xs:group>
+        <xs:element name="r1">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element name="e1" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+              <xs:element name="f1" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>)
     val compiler = Compiler()
     val sset = compiler.compileNode(testSchema).sset
     val root = sset.root
@@ -223,7 +223,9 @@
     val numEntries = refMap.size
     assertEquals(4, numEntries)
     val refPairsMap = root.refPairsMap.toSeq
-    val numRefPairs = refPairsMap.map { _._2.length }.sum
+    val numRefPairs = refPairsMap.map {
+      _._2.length
+    }.sum
     assertEquals(6, numRefPairs) // good proxy for schema size
     val allGRefs = root.allGRefs
     assertEquals(2, allGRefs.size)
@@ -237,37 +239,38 @@
 
   @Test def testRefMapExplosion2(): Unit = {
     val testSchema = SchemaUtils.dfdlTestSchema(
-      <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
-      <dfdl:format ref="tns:GeneralFormat"/>,
-      <xs:element name="r" type="ex:ct"/>
-      <xs:complexType name="ct">
-        <xs:sequence>
-          <xs:group ref="ex:g"/>
-          <xs:group ref="ex:g"/>
-        </xs:sequence>
-      </xs:complexType>
-      <xs:group name="g">
-        <xs:choice>
-          <xs:element ref="ex:r1"/>
-          <xs:element ref="ex:r1"/>
-        </xs:choice>
-      </xs:group>
-      <xs:element name="r1">
-        <xs:complexType>
+        <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
+        <dfdl:format ref="tns:GeneralFormat"/>,
+        <xs:element name="r" type="ex:ct"/>
+        <xs:complexType name="ct">
           <xs:sequence>
-            <xs:element ref="ex:r2"/>
-            <xs:element ref="ex:r2"/>
+            <xs:group ref="ex:g"/>
+            <xs:group ref="ex:g"/>
           </xs:sequence>
         </xs:complexType>
-      </xs:element>
-      <xs:element name="r2">
-        <xs:complexType>
+        <xs:group name="g">
           <xs:sequence>
-            <xs:element name="e1" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
-            <xs:element name="f1" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+            <!-- a choice here would be UPA ambiguous -->
+            <xs:element ref="ex:r1"/>
+            <xs:element ref="ex:r1"/>
           </xs:sequence>
-        </xs:complexType>
-      </xs:element>)
+        </xs:group>
+        <xs:element name="r1">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:r2"/>
+              <xs:element ref="ex:r2"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="r2">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element name="e1" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+              <xs:element name="f1" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>)
     val compiler = Compiler()
     val sset = compiler.compileNode(testSchema).sset
     val root = sset.root
@@ -277,7 +280,9 @@
     val numEntries = refMap.size
     assertEquals(5, numEntries)
     val refPairsMap = root.refPairsMap.toSeq
-    val numRefPairs = refPairsMap.map { _._2.length }.sum
+    val numRefPairs = refPairsMap.map {
+      _._2.length
+    }.sum
     assertEquals(8, numRefPairs)
     assertEquals(19, root.numComponents)
     assertEquals(19, root.numUniqueComponents)
@@ -285,8 +290,8 @@
 
   @Test def testRefMapExplosion3(): Unit = {
     val testSchema = SchemaUtils.dfdlTestSchema(
-      <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
-      <dfdl:format ref="tns:GeneralFormat"/>,
+        <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
+        <dfdl:format ref="tns:GeneralFormat"/>,
       <xs:element name="r">
         <xs:complexType>
           <xs:sequence>
@@ -295,30 +300,30 @@
           </xs:sequence>
         </xs:complexType>
       </xs:element>
-      <xs:element name="r1">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element ref="ex:r2"/>
-            <xs:element ref="ex:r2"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>
-      <xs:element name="r2">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element ref="ex:r3"/>
-            <xs:element ref="ex:r3"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>
-      <xs:element name="r3">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element name="e1" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
-            <xs:element name="f1" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>)
+        <xs:element name="r1">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:r2"/>
+              <xs:element ref="ex:r2"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="r2">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:r3"/>
+              <xs:element ref="ex:r3"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="r3">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element name="e1" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+              <xs:element name="f1" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>)
     val compiler = Compiler()
     val sset = compiler.compileNode(testSchema).sset
     val root = sset.root
@@ -328,7 +333,9 @@
     val numEntries = refMap.size
     assertEquals(4, numEntries)
     val refPairsMap = root.refPairsMap.toSeq
-    val numRefPairs = refPairsMap.map { _._2.length }.sum
+    val numRefPairs = refPairsMap.map {
+      _._2.length
+    }.sum
     assertEquals(7, numRefPairs)
     assertEquals(21, root.numComponents)
     assertEquals(21, root.numUniqueComponents)
@@ -336,8 +343,8 @@
 
   @Test def testRefMapExplosion4(): Unit = {
     val testSchema = SchemaUtils.dfdlTestSchema(
-      <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
-      <dfdl:format ref="tns:GeneralFormat"/>,
+        <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
+        <dfdl:format ref="tns:GeneralFormat"/>,
       <xs:element name="e5">
         <xs:complexType>
           <xs:sequence>
@@ -346,38 +353,38 @@
           </xs:sequence>
         </xs:complexType>
       </xs:element>
-      <xs:element name="e4">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element ref="ex:e3"/>
-            <xs:element ref="ex:e3"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>
-      <xs:element name="e3">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element ref="ex:e2"/>
-            <xs:element ref="ex:e2"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>
-      <xs:element name="e2">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element ref="ex:e1"/>
-            <xs:element ref="ex:e1"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>
-      <xs:element name="e1">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element name="e0" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
-            <xs:element name="f0" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>)
+        <xs:element name="e4">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:e3"/>
+              <xs:element ref="ex:e3"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="e3">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:e2"/>
+              <xs:element ref="ex:e2"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="e2">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:e1"/>
+              <xs:element ref="ex:e1"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="e1">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element name="e0" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+              <xs:element name="f0" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>)
     val compiler = Compiler()
     val sset = compiler.compileNode(testSchema).sset
     val root = sset.root
@@ -387,7 +394,9 @@
     val numEntries = refMap.size
     assertEquals(5, numEntries)
     val refPairsMap = root.refPairsMap.toSeq
-    val numRefPairs = refPairsMap.map { _._2.length }.sum
+    val numRefPairs = refPairsMap.map {
+      _._2.length
+    }.sum
     assertEquals(9, numRefPairs)
     assertEquals(26, root.numComponents)
     assertEquals(26, root.numUniqueComponents)
@@ -395,8 +404,8 @@
 
   @Test def testRefMapExplosion5(): Unit = {
     val testSchema = SchemaUtils.dfdlTestSchema(
-      <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
-      <dfdl:format ref="tns:GeneralFormat"/>,
+        <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
+        <dfdl:format ref="tns:GeneralFormat"/>,
       <xs:element name="e6">
         <xs:complexType>
           <xs:sequence>
@@ -405,46 +414,46 @@
           </xs:sequence>
         </xs:complexType>
       </xs:element>
-      <xs:element name="e5">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element ref="ex:e4"/>
-            <xs:element ref="ex:e4"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>
-      <xs:element name="e4">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element ref="ex:e3"/>
-            <xs:element ref="ex:e3"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>
-      <xs:element name="e3">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element ref="ex:e2"/>
-            <xs:element ref="ex:e2"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>
-      <xs:element name="e2">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element ref="ex:e1"/>
-            <xs:element ref="ex:e1"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>
-      <xs:element name="e1">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element name="e0" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
-            <xs:element name="f0" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>)
+        <xs:element name="e5">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:e4"/>
+              <xs:element ref="ex:e4"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="e4">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:e3"/>
+              <xs:element ref="ex:e3"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="e3">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:e2"/>
+              <xs:element ref="ex:e2"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="e2">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:e1"/>
+              <xs:element ref="ex:e1"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="e1">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element name="e0" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+              <xs:element name="f0" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>)
     val compiler = Compiler()
     val sset = compiler.compileNode(testSchema).sset
     val root = sset.root
@@ -454,7 +463,9 @@
     val numEntries = refMap.size
     assertEquals(6, numEntries)
     val refPairsMap = root.refPairsMap.toSeq
-    val numRefPairs = refPairsMap.map { _._2.length }.sum
+    val numRefPairs = refPairsMap.map {
+      _._2.length
+    }.sum
     assertEquals(11, numRefPairs)
     assertEquals(31, root.numComponents)
     assertEquals(31, root.numUniqueComponents)
@@ -462,8 +473,8 @@
 
   @Test def testRefMapExplosion6(): Unit = {
     val testSchema = SchemaUtils.dfdlTestSchema(
-      <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
-      <dfdl:format ref="tns:GeneralFormat"/>,
+        <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
+        <dfdl:format ref="tns:GeneralFormat"/>,
       <xs:element name="e7">
         <xs:complexType>
           <xs:sequence>
@@ -472,54 +483,54 @@
           </xs:sequence>
         </xs:complexType>
       </xs:element>
-      <xs:element name="e6">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element ref="ex:e5"/>
-            <xs:element ref="ex:e5"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>
-      <xs:element name="e5">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element ref="ex:e4"/>
-            <xs:element ref="ex:e4"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>
-      <xs:element name="e4">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element ref="ex:e3"/>
-            <xs:element ref="ex:e3"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>
-      <xs:element name="e3">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element ref="ex:e2"/>
-            <xs:element ref="ex:e2"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>
-      <xs:element name="e2">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element ref="ex:e1"/>
-            <xs:element ref="ex:e1"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>
-      <xs:element name="e1">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element name="e0" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
-            <xs:element name="f0" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>)
+        <xs:element name="e6">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:e5"/>
+              <xs:element ref="ex:e5"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="e5">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:e4"/>
+              <xs:element ref="ex:e4"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="e4">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:e3"/>
+              <xs:element ref="ex:e3"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="e3">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:e2"/>
+              <xs:element ref="ex:e2"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="e2">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:e1"/>
+              <xs:element ref="ex:e1"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="e1">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element name="e0" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+              <xs:element name="f0" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>)
     val compiler = Compiler()
     val sset = compiler.compileNode(testSchema).sset
     val root = sset.root
@@ -529,7 +540,9 @@
     val numEntries = refMap.size
     assertEquals(7, numEntries)
     val refPairsMap = root.refPairsMap.toSeq
-    val numRefPairs = refPairsMap.map { _._2.length }.sum
+    val numRefPairs = refPairsMap.map {
+      _._2.length
+    }.sum
     assertEquals(13, numRefPairs)
     assertEquals(36, root.numComponents)
     assertEquals(36, root.numUniqueComponents)
@@ -537,8 +550,8 @@
 
   @Test def testRefMapExplosion7(): Unit = {
     val testSchema = SchemaUtils.dfdlTestSchema(
-      <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
-      <dfdl:format ref="tns:GeneralFormat"/>,
+        <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
+        <dfdl:format ref="tns:GeneralFormat"/>,
       <xs:element name="e8">
         <xs:complexType>
           <xs:sequence>
@@ -547,62 +560,62 @@
           </xs:sequence>
         </xs:complexType>
       </xs:element>
-      <xs:element name="e7">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element ref="ex:e6"/>
-            <xs:element ref="ex:e6"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>
-      <xs:element name="e6">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element ref="ex:e5"/>
-            <xs:element ref="ex:e5"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>
-      <xs:element name="e5">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element ref="ex:e4"/>
-            <xs:element ref="ex:e4"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>
-      <xs:element name="e4">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element ref="ex:e3"/>
-            <xs:element ref="ex:e3"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>
-      <xs:element name="e3">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element ref="ex:e2"/>
-            <xs:element ref="ex:e2"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>
-      <xs:element name="e2">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element ref="ex:e1"/>
-            <xs:element ref="ex:e1"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>
-      <xs:element name="e1">
-        <xs:complexType>
-          <xs:sequence>
-            <xs:element name="e0" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
-            <xs:element name="f0" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
-          </xs:sequence>
-        </xs:complexType>
-      </xs:element>)
+        <xs:element name="e7">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:e6"/>
+              <xs:element ref="ex:e6"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="e6">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:e5"/>
+              <xs:element ref="ex:e5"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="e5">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:e4"/>
+              <xs:element ref="ex:e4"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="e4">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:e3"/>
+              <xs:element ref="ex:e3"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="e3">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:e2"/>
+              <xs:element ref="ex:e2"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="e2">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element ref="ex:e1"/>
+              <xs:element ref="ex:e1"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+        <xs:element name="e1">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element name="e0" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+              <xs:element name="f0" type="xs:int" dfdl:length="1" dfdl:lengthKind="explicit"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>)
     val compiler = Compiler()
     val sset = compiler.compileNode(testSchema).sset
     val root = sset.root
@@ -612,9 +625,260 @@
     val numEntries = refMap.size
     assertEquals(8, numEntries)
     val refPairsMap = root.refPairsMap.toSeq
-    val numRefPairs = refPairsMap.map { _._2.length }.sum
+    val numRefPairs = refPairsMap.map {
+      _._2.length
+    }.sum
     assertEquals(15, numRefPairs)
     assertEquals(41, root.numComponents)
     assertEquals(41, root.numUniqueComponents)
   }
-}
+
+  /**
+   * This test reproduces a situation observed in the VMF DFDL Schema.
+   *
+   * The situation is an element uses a complex type that references a global group g.
+   * Another global group h, also references g.
+   * But nothing uses h.
+   *
+   * This *was* failing because Daffodil was incorrectly giving the group definition
+   * for h an enclosingElement of the root. It really should have no enclosing element.
+   */
+  @Test def testUnusedGroup1(): Unit = {
+    val testSchema = SchemaUtils.dfdlTestSchema(
+        <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
+        <dfdl:format ref="tns:GeneralFormat" lengthKind="delimited"/>,
+        <xs:element name="r" type="ex:ct"/>
+        <xs:complexType name="ct">
+          <xs:group ref="ex:g"/>
+        </xs:complexType>
+        <xs:group name="h"><!-- unused group shares referenced child group -->
+          <xs:sequence>
+            <xs:group ref="ex:g"/>
+          </xs:sequence>
+        </xs:group>
+        <xs:group name="g">
+          <xs:sequence>
+            <!-- computed element expressions are not meaningful for the unused global group 'h' -->
+            <xs:element name="e" type="xs:int" dfdl:outputValueCalc='{ ../f }'/>
+            <xs:element name="f" type="xs:int" dfdl:inputValueCalc='{ ../e }' />
+          </xs:sequence>
+        </xs:group>,
+      useDefaultNamespace = false,
+      elementFormDefault = "unqualified"
+    )
+    val compiler = Compiler()
+    val sset = compiler.compileNode(testSchema).sset
+    val root = sset.root
+    val comps = root.allComponents
+    val refMap = root.refMap
+    val numEntries = refMap.size
+    val numRefPairs = root.refPairsMap.size
+    val rootDecl = root.referencedElement
+    val ctDef = root.complexType.asInstanceOf[GlobalComplexTypeDef]
+    val Some(Seq((edecl, ctRefSpecs))) = refMap.get(ctDef)
+    val gref = rootDecl.complexType.modelGroup.asInstanceOf[SequenceGroupRef]
+    val g_gDef = gref.groupDef
+    val eDecl = g_gDef.groupMembers(0)
+    val fDecl = g_gDef.groupMembers(1)
+    val e_enclComps = eDecl.enclosingComponents
+    assertEquals(1, e_enclComps.length)
+    val gDef = e_enclComps(0).encloser.asInstanceOf[GlobalSequenceGroupDef]
+    val e_enclTerms = eDecl.enclosingTerms
+    assertEquals(2, e_enclTerms.length)
+    // The second of the above enclosingTerms should NOT have any enclosing element.
+    val e_enclElems = eDecl.enclosingElements
+    assertEquals(1, e_enclElems.length)
+  }
+
+
+  lazy val testRootPathsSchema1 = SchemaUtils.dfdlTestSchema(
+        <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
+        <dfdl:format ref="tns:GeneralFormat" lengthKind="delimited"/>,
+    //
+    // note that the first element below will be the root element.
+    // it doesn't use any of the rest of the schema
+    //
+    // The notRoot element uses type ct, which contains element rr
+    // which makes the expressions inside group g's elements meaningful.
+    // But... notRoot isn't the root.
+    //
+    // The h element also uses group g. But there is no element rr. The
+    // relative paths inside group g aren't meaningful in the context of
+    // element h. Since h is not the root, we will only check, and detect this
+    // if compileAllTopLevels is true.
+    //
+        <xs:element name="r" type="xs:int"/>
+        <xs:element name="notRoot" type="tns:ct"/>
+          ++
+          restOfXML,
+    useDefaultNamespace = false,
+    elementFormDefault = "unqualified"
+  )
+
+  lazy val restOfXML = (
+      <xs:element name="h"><!-- uses the substructure, but expressions are past root-->
+          <xs:complexType>
+            <xs:sequence>
+              <!-- The group g contains elements with paths that are past the root for
+              this usage inside element h -->
+              <xs:group ref="ex:g"/>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+          ++
+        restOfXML2)
+
+  lazy val restOfXML2 =
+        <xs:complexType name="ct">
+          <xs:sequence>
+            <xs:element name="rr">
+              <xs:complexType>
+                <xs:sequence>
+                  <xs:group ref="ex:g"/>
+                </xs:sequence>
+              </xs:complexType>
+            </xs:element>
+          </xs:sequence>
+        </xs:complexType>
+        <xs:group name="g">
+          <xs:sequence>
+            <!--
+            computed element expressions are not meaningful for the unused global element 'h'
+            The paths go up two levels of elements, so these upward paths are reaching
+            outside of the element h, which is not inside element rr.
+
+            These paths are only meaningful when this group g is used inside the context
+            of element rr
+            -->
+            <xs:element name="e" type="xs:int" dfdl:outputValueCalc='{ ../../rr/f }'/>
+            <xs:element name="f" type="xs:int" dfdl:inputValueCalc='{ ../../rr/e }' />
+          </xs:sequence>
+        </xs:group>
+
+  /**
+   * The root element doesn't have any substructure that eventually uses the
+   * group h, so we get the error that indicates h can't be a root (relative path upward)
+   * because we're checking all top level.
+   */
+  @Test def testPathPastRootFromGlobalDef1(): Unit = {
+    val compiler = Compiler().withCheckAllTopLevel(true)
+    val pf = compiler.compileNode(testRootPathsSchema1)
+    val isError = pf.isError
+    val msgs = pf.getDiagnostics.map(_.getMessage()).mkString("\n")
+    // println(msgs)
+    assertTrue(isError)
+    assertTrue(msgs.toLowerCase.contains("Relative path '../../rr/f' past root element".toLowerCase))
+  }
+
+  @Test def testPathPastRootFromGlobalDef2(): Unit = {
+    val compiler = Compiler().withCheckAllTopLevel(false)
+    val pf = compiler.compileNode(testRootPathsSchema1)
+    val isError = pf.isError
+    assertFalse(isError)
+  }
+
+  lazy val testRootPathsSchema2 = SchemaUtils.dfdlTestSchema(
+        <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
+        <dfdl:format ref="tns:GeneralFormat" lengthKind="delimited"/>,
+    //
+    // note that the first element below will be the root element.
+    //
+    // The h element also uses group g. But there is no element rr. The
+    // relative paths inside group g aren't meaningful in the context of
+    // element h.
+    //
+    // However, h is not the root, so even with checkAllTopLevel true
+    // we don't report errors about these meaningless paths, as we only
+    // generate code for the root.
+    //
+      <xs:element name="r" type="tns:ct"/>
+          ++
+      restOfXML,
+      useDefaultNamespace = false,
+      elementFormDefault = "unqualified"
+  )
+
+  /**
+   * Shows that so long as the root reaches the expressions
+   * and they are meaningful in that context, even checkAllTopLevels
+   * doesn't detect that element h can't be correct (as a root)
+   *
+   * Note that if element h were used as part of the substructure of
+   * root, then if it has proper placement so the expressions are
+   * meaningful, then that is correct. It's usage as a root is incorrect
+   * but isn't entertained as a consideration by the schema compiler.
+   */
+  @Test def testPathPastRootFromGlobalDef3(): Unit = {
+    val compiler = Compiler().withCheckAllTopLevel(true)
+    val pf = compiler.compileNode(testRootPathsSchema2)
+    val isError = pf.isError
+    assertFalse(isError)
+  }
+
+  lazy val testRootPathsSchema3 = SchemaUtils.dfdlTestSchema(
+        <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>,
+        <dfdl:format ref="tns:GeneralFormat" lengthKind="delimited"/>,
+    //
+    // note that the first element below will be the root element.
+    //
+    // The h element also uses group g. But there is no element rr. The
+    // relative paths inside group g aren't meaningful in the context of
+    // element h.
+    //
+    // However, h is not the root, so even with checkAllTopLevel true
+    // we don't report errors about these meaningless paths, as we only
+    // generate code for the root.
+    //
+    // But, h is checked. The meaningless part of it is detected.
+    //
+      <xs:element name="r" type="tns:ct"/>
+          ++
+      <xs:element name="h"><!-- uses the substructure, but expressions are past root-->
+          <xs:complexType>
+            <xs:sequence>
+              <!-- The group g contains elements with paths that are past the root for
+              this usage inside element h -->
+              <xs:group ref="ex:g"/>
+              <xs:sequence dfdl:hiddenGroupRef="tns:noSuchGroup"/>
+            </xs:sequence>
+          </xs:complexType>
+      </xs:element>
+        ++
+      restOfXML2,
+      useDefaultNamespace = false,
+      elementFormDefault = "unqualified"
+  )
+
+  /**
+   * This test shows that if checkAllTopLevel is false,
+   * then the error inside global element h, (hiddenGroupRef to non-existing group)
+   * is NOT detected, since it's not part of the schema reachable
+   * from the root.
+   *
+   * Note that checkAllTopLevels false will NOT prevent
+   * schema validation checks. But hiddenGroupRef isn't
+   * a validity check. It's an explicit check done by Daffodil.
+   */
+  @Test def testCheckAllTopLevelWorksToIgnore(): Unit = {
+    val compiler = Compiler().withCheckAllTopLevel(false)
+    val pf = compiler.compileNode(testRootPathsSchema3)
+    val isError = pf.isError
+    assertFalse(isError)
+  }
+
+  /**
+   * Test shows that even though it is not the root,
+   * element h is checked by Daffodil, and the
+   * erroneous hiddenGroupRef is detected.
+   */
+  @Test def testCheckAllTopLevelWorksToCheck(): Unit = {
+    val compiler = Compiler().withCheckAllTopLevel(true)
+    val pf = compiler.compileNode(testRootPathsSchema3)
+    val isError = pf.isError
+    val msgs = pf.getDiagnostics.map(_.getMessage()).mkString("\n")
+    println(msgs)
+    assertTrue(isError)
+    assertTrue(msgs.toLowerCase.contains("not found".toLowerCase))
+    assertTrue(msgs.toLowerCase.contains("noSuchGroup".toLowerCase))
+  }
+}
\ No newline at end of file
diff --git a/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestSimpleTypeUnions.scala b/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestSimpleTypeUnions.scala
index 35c8c14..689eb77 100644
--- a/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestSimpleTypeUnions.scala
+++ b/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestSimpleTypeUnions.scala
@@ -66,7 +66,7 @@
 
   @Test def testUnion01: Unit = {
 
-    val sset = new SchemaSet(testSchema1)
+    val sset = SchemaSet(testSchema1)
     val Seq(sch) = sset.schemas
     val Seq(sd, _) = sch.schemaDocuments
 
@@ -252,7 +252,7 @@
     val (result, actual) = TestUtils.testString(testSchema2, "-1")
     val i = result.resultState.asInstanceOf[PState].infoset.asInstanceOf[DIDocument].contents(0).asInstanceOf[DISimple]
     val umstrd = i.unionMemberRuntimeData.get
-    assertEquals("negIntType", umstrd.diagnosticDebugName) // anonymous simple type gets this name from base.
+    assertEquals("ex:negIntType", umstrd.diagnosticDebugName) // anonymous simple type gets this name from base.
     assertTrue(i.valid.get)
     val expected = <e1>-1</e1>
     TestUtils.assertEqualsXMLElements(expected, actual)
@@ -309,7 +309,7 @@
     val (result, actual) = TestUtils.testString(testSchema3, "foo3bar")
     val i = result.resultState.asInstanceOf[PState].infoset.asInstanceOf[DIDocument].contents(0).asInstanceOf[DISimple]
     val umstrd = i.unionMemberRuntimeData.get
-    assertEquals("foo3or4bar", umstrd.diagnosticDebugName)
+    assertEquals("ex:foo3or4bar", umstrd.diagnosticDebugName)
     assertTrue(i.valid.get)
     val expected = <e1>foo3bar</e1>
     TestUtils.assertEqualsXMLElements(expected, actual)
diff --git a/daffodil-core/src/test/scala/org/apache/daffodil/grammar/TestGrammar.scala b/daffodil-core/src/test/scala/org/apache/daffodil/grammar/TestGrammar.scala
index 7edde61..5f93f45 100644
--- a/daffodil-core/src/test/scala/org/apache/daffodil/grammar/TestGrammar.scala
+++ b/daffodil-core/src/test/scala/org/apache/daffodil/grammar/TestGrammar.scala
@@ -28,7 +28,10 @@
 
 class TestGrammar extends GrammarMixin {
 
-  val fakeDecl = new GlobalElementDecl(<element name="foo" type="xs:int"/>, Fakes.fakeSD)
+  val fakeDecl =
+    GlobalElementDecl(
+      <xs:element name="foo" type="xs:int" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>,
+      Fakes.fakeSD)
   val fakeTerm = fakeDecl.asRoot
 
   final override protected def grammarContext = fakeTerm
diff --git a/daffodil-core/src/test/scala/org/apache/daffodil/outputValueCalc/TestOutputValueCalcAndAlignment.scala b/daffodil-core/src/test/scala/org/apache/daffodil/outputValueCalc/TestOutputValueCalcAndAlignment.scala
index 87643a8..ebdfc8d 100644
--- a/daffodil-core/src/test/scala/org/apache/daffodil/outputValueCalc/TestOutputValueCalcAndAlignment.scala
+++ b/daffodil-core/src/test/scala/org/apache/daffodil/outputValueCalc/TestOutputValueCalcAndAlignment.scala
@@ -20,9 +20,6 @@
 import org.junit.Assert.assertTrue
 import org.junit.Assert.fail
 import org.junit.Test
-
-import org.apache.daffodil.Implicits.ns2String
-import org.apache.daffodil.dsom.RuntimeSchemaDefinitionError
 import org.apache.daffodil.util.Misc
 import org.apache.daffodil.util.SchemaUtils
 import org.apache.daffodil.util.TestUtils
@@ -135,17 +132,15 @@
     try {
       TestUtils.testUnparsing(sch, infoset, "ignored", areTracing)
     } catch {
-      case e: RuntimeSchemaDefinitionError => {
+          // Some test utilities, given multiple diagnostics from a run, will just
+          // concatenate their messages, and throw a vanilla Exception object.
+      case e: Exception => {
         val msg = Misc.getSomeMessage(e).get.toLowerCase
         if (!msg.contains("Schema Definition Error".toLowerCase))
           fail(msg + " did not contain Schema Definition Error")
 
         assertTrue(msg.contains("Deadlock".toLowerCase))
       }
-      case x: Throwable => {
-        val y = x.toString
-        System.err.println(y)
-      }
     }
   }
 
diff --git a/daffodil-core/src/test/scala/org/apache/daffodil/runtime1/TestStreamingUnparserCompilerAttributes.scala b/daffodil-core/src/test/scala/org/apache/daffodil/runtime1/TestStreamingUnparserCompilerAttributes.scala
index 24444d1..89886fc 100644
--- a/daffodil-core/src/test/scala/org/apache/daffodil/runtime1/TestStreamingUnparserCompilerAttributes.scala
+++ b/daffodil-core/src/test/scala/org/apache/daffodil/runtime1/TestStreamingUnparserCompilerAttributes.scala
@@ -21,7 +21,7 @@
 import org.apache.daffodil.dsom.ChoiceGroupRef
 import org.apache.daffodil.dsom.ElementRef
 import org.apache.daffodil.dsom.LocalElementDecl
-import org.apache.daffodil.dsom.Sequence
+import org.apache.daffodil.dsom.LocalSequence
 import org.apache.daffodil.dsom.SequenceGroupRef
 import org.apache.daffodil.dsom.Term
 import org.junit.Test
@@ -35,7 +35,7 @@
   type LE = LocalElementDecl
   type SGR = SequenceGroupRef
   type CGR = ChoiceGroupRef
-  type S = Sequence
+  type S = LocalSequence
   type C = Choice
   type ER = ElementRef
 
diff --git a/daffodil-core/src/test/scala/org/apache/daffodil/util/TestUtils.scala b/daffodil-core/src/test/scala/org/apache/daffodil/util/TestUtils.scala
index ca53fe0..c4f5343 100644
--- a/daffodil-core/src/test/scala/org/apache/daffodil/util/TestUtils.scala
+++ b/daffodil-core/src/test/scala/org/apache/daffodil/util/TestUtils.scala
@@ -121,8 +121,7 @@
     val inputter = new ScalaXMLInfosetInputter(infosetXML)
     val actual = u.unparse(inputter, out)
     if (actual.isProcessingError) {
-      val msgs = actual.getDiagnostics.map(_.getMessage()).mkString("\n")
-      throw new Exception(msgs)
+      throwDiagnostics(actual.getDiagnostics)
     }
     val unparsed = outputStream.toString
     //    System.err.println("parsed: " + infoset)
@@ -247,7 +246,7 @@
       topLevels,
       contentElements,
       elementFormDefault = elementFormDefault)
-    val sset = new SchemaSet(testSchema)
+    val sset = SchemaSet(testSchema)
     sset.root
   }
 
@@ -320,7 +319,7 @@
     </xs:group>)
   val DummyPrimitiveFactory = null
   val tunables = DaffodilTunables()
-  lazy val xsd_sset: SchemaSet = new SchemaSet(sch, "http://example.com", "fake")
+  lazy val xsd_sset: SchemaSet = SchemaSet(sch, "http://example.com", "fake")
   lazy val xsd_schema = xsd_sset.getSchema(NS("http://example.com")).get
   lazy val fakeSD = xsd_schema.schemaDocuments(0)
   lazy val fakeElem = fakeSD.getGlobalElementDecl("fake").get
diff --git a/daffodil-lib/src/main/scala/org/apache/daffodil/exceptions/SchemaFileLocatable.scala b/daffodil-lib/src/main/scala/org/apache/daffodil/exceptions/SchemaFileLocatable.scala
index 069fc7f..4974236 100644
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/exceptions/SchemaFileLocatable.scala
+++ b/daffodil-lib/src/main/scala/org/apache/daffodil/exceptions/SchemaFileLocatable.scala
@@ -20,7 +20,6 @@
 import java.net.URLDecoder
 import org.apache.daffodil.api.LocationInSchemaFile
 import org.apache.daffodil.schema.annotation.props.LookupLocation
-import org.apache.daffodil.util.TransientParam
 
 trait HasSchemaFileLocation extends LookupLocation {
   override def schemaFileLocation: SchemaFileLocation
@@ -33,11 +32,24 @@
   override def locationDescription: String = schemaFileLocation.locationDescription
 }
 
-class SchemaFileLocation(@TransientParam context: SchemaFileLocatable) extends LocationInSchemaFile with Serializable {
+object SchemaFileLocation {
+  def apply(context:SchemaFileLocatable) =
+    new SchemaFileLocation(
+      context.lineNumber,
+      context.columnNumber,
+      context.uriString,
+      context.toString,
+      context.diagnosticDebugName)
+}
 
-  val lineNumber = context.lineNumber
-  val columnNumber = context.columnNumber
-  val uriString: String = context.uriString
+class SchemaFileLocation private (
+  val lineNumber: Option[String],
+  val columnNumber: Option[String],
+  val uriString: String,
+  contextToString: String,
+  val diagnosticDebugName: String)
+  extends LocationInSchemaFile
+    with Serializable {
 
   override def lineDescription = lineNumber match {
     case Some(num) => " line " + num
@@ -49,9 +61,7 @@
     case None => ""
   }
 
-  override val toString = context.toString
-
-  val diagnosticDebugName: String = context.diagnosticDebugName
+  override val toString = contextToString
 
   override def fileDescription = " in " + URLDecoder.decode(uriString, "UTF-8")
 
@@ -128,6 +138,6 @@
 
   }
 
-  override lazy val schemaFileLocation = new SchemaFileLocation(this)
+  override lazy val schemaFileLocation = SchemaFileLocation(this)
 }
 
diff --git a/daffodil-lib/src/main/scala/org/apache/daffodil/oolag/OOLAG.scala b/daffodil-lib/src/main/scala/org/apache/daffodil/oolag/OOLAG.scala
index 8bea1cf..a85a668 100644
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/oolag/OOLAG.scala
+++ b/daffodil-lib/src/main/scala/org/apache/daffodil/oolag/OOLAG.scala
@@ -27,6 +27,8 @@
 import org.apache.daffodil.exceptions.ThinException
 import org.apache.daffodil.util.Maybe._
 
+import scala.collection.mutable
+
 /**
  * OOLAG = Object-oriented Lazy Attribute Grammars
  *
@@ -54,6 +56,9 @@
    *
    * If body fails with an OOLAG exception of the right kind, then
    * alt is evaluated and returned instead.
+   *
+   * Anyplace that calls keepGoing should have a comment saying why it
+   * is using it. There should be very few places that use it.
    */
   def keepGoing[T](alt: => T)(body: => T) = {
     try {
@@ -98,12 +103,7 @@
    *
    * The way these are generally used now is like this
    * {{{
-   *  def foo = LV('foo) {...calculation...}.value
-   * }}}
-   * or, if you would like a slot to show up in the debugger so you
-   * can more easily see the value of the LV then you can
-   * {{{
-   * lazy val foo = LV('foo){...calculation...}.value
+   *  lazy val foo = LV('foo) {...calculation...}.value
    * }}}
    * Why scala needs 'real' Lisp-style macros: Well wouldn't it be
    * nicer if I could write:
@@ -238,40 +238,26 @@
 
     final var currentOVList: Seq[OOLAGValueBase] = Nil
 
-    private val lvCache = new scala.collection.mutable.LinkedHashMap[Symbol, OOLAGValueBase]
-
     /**
      * The factory for OOLAGValues is LV.
      */
     protected final def LV[T](sym: Symbol)(body: => T): OOLAGValue[T] = {
-      //
-      // TODO: This is very fragile. A simple cut/paste error where two LVs have the same symbol
-      // causes no scala compilation error, but results in the second definition to be evaluated
-      // getting the value of the first to be evaluated. This can be very hard to debug.
-      //
-      // Really we want the thunk itself's identity to be the key for lookup, not this
-      // hand maintained symbol.
-      //
-      // Once again this is why scala needs real lisp-style macros, not these quasi function things
-      // where a macro can only do what a function could have done.
-      //
-      // Fixing this problem likely requires one to go back to the older oolag design
-      // which didn't have this lvCache at all, just used actual lazy val for each LV.
-      // That would mean changing all def foo = LV('foo) {...} to be lazy val. But that would
-      // be much safer, because then the sym is only used for debugging info, and could even be optional.
-      //
-      lvCache.get(sym).getOrElse {
-        val lv = new OOLAGValue[T](this, sym.name, body)
-        lvCache.put(sym, lv)
-        lv
-      }.asInstanceOf[OOLAGValue[T]]
+      val lv = new OOLAGValue[T](this, sym.name, body)
+      lv
     }
 
     /*
      * requiredEvaluations feature
      *
      * An object either uses requiredEvaluationsAlways, or requiredEvaluationsIfActivated.
-     * Some objects use both.
+     *
+     * requiredEvaluationsIfActivated is for objects in the abstract syntax tree (AST) where
+     * the mere construction of them is not sufficient to know if the required evaluations
+     * should occur. The objects may or may not ultimately be needed.
+     *
+     * requiredEvaluationsAlways is for top level things like the OOLAG Root object,
+     * and objects where their construction is enough to know that they should have
+     * these required evaluations occur.
      *
      * They are maintained as two separate lists of eval functions aka thunks to be run.
      *
@@ -297,11 +283,16 @@
     private var requiredEvalIfActivatedFunctions: List[OOLAGValueBase] = Nil // for evaluation only if activated.
 
     /**
-     * Unconditionally, evaluate the expression arg in order to insure all checks for this
-     * object are performed.
+     * Used to force evaluation for error checking unconditionally.
+     *
+     * Creating the object will queue up the expression for evaluation later
+     * when checkErrors is called.
+     *
+     * This is for root-of-the-AST objects, where we don't conditionally construct them.
+     * Rather, upon construction we know we positively ARE adding them to the AST.
      */
     protected final def requiredEvaluationsAlways(arg: => Any): Unit = {
-      requiredEvaluationsAlways(thunk(arg))
+        requiredEvaluationsAlways(thunk(arg))
     }
 
     /**
@@ -328,6 +319,11 @@
       lv
     }
 
+    /**
+     * When it is possible to centralize (on the OOLAG Root object) all the
+     * locally enqueued required evaluation thunks, do so. The root needs to be established first,
+     * and the object activated if the requiredEvaluationsIfActive method is used.
+     */
     private def centralizeEvalFunctionsWhenReady(): Unit = {
       if (optOolagContext.isDefined) {
         //
@@ -355,9 +351,21 @@
     /**
      * Saves the arg expression, and insures it is evaluated later only
      * if setRequiredEvaluationActive() is called for this object.
+     *
+     * This is for use when constructing a abstract syntax tree (AST)
+     * such as the DSOM tree (really a directed graph) when
+     * the object creation itself is not enough to know if the object will or
+     * will not be attached to the tree.
+     *
+     * The code constructing the AST must traverse the final tree and activate
+     * the nodes that ultimately want all these things evaluated on them.
+     *
+     * If using this, you should know that the object is either discarded
+     * (in which case these will never get evaluated), or somehow activated
+     * in which case they will be evaluated later when checkErrors is called.
      */
     protected final def requiredEvaluationsIfActivated(arg: => Any): Unit = {
-      requiredEvaluationsIfActivated(thunk(arg))
+        requiredEvaluationsIfActivated(thunk(arg))
     }
 
     /**
@@ -396,8 +404,13 @@
      * required evaluations, as well as those for any objects that
      * become activated during evaluation of required evaluations of
      * any object recursively.
+     *
+     * This is called only on the OOLAGRoot object. It depends on
+     * all other object's required evaluations having been moved up
+     * onto the root, which happens automatically via the calls to
+     * centralizeEvalFunctionsWhenReady().
      */
-    final def checkErrors: Unit = {
+    private def checkErrors: Unit = {
       Assert.usage(this.isOOLAGRoot || requiredEvalFunctions == Nil)
       while (oolagRoot.requiredEvalFunctions != Nil) { // while there is an accumulated crop of eval functions
         // grab the current crop of eval functions
@@ -421,13 +434,13 @@
      * Accumulate diagnostics on the root of the hierarchy.
      * (Likely the SchemaSet object.)
      */
-    private var errors_ : Seq[Diagnostic] = Nil
-    private var warnings_ : Seq[Diagnostic] = Nil
+    private val errors_ = new mutable.LinkedHashSet[Diagnostic]()
+    private val warnings_ = new mutable.LinkedHashSet[Diagnostic]()
 
-    final def errors = oolagRoot.errors_
-    final def warnings = oolagRoot.warnings_
+    final def errors: Seq[Diagnostic] = oolagRoot.errors_.toSeq
+    final def warnings: Seq[Diagnostic] = oolagRoot.warnings_.toSeq
 
-    def getDiagnostics = diagnostics
+    def getDiagnostics: Seq[Diagnostic] = diagnostics
 
     def warn(th: Diagnostic): Unit = {
       oolagRoot.oolagWarn(th)
@@ -449,12 +462,12 @@
 
     protected def oolagWarn(th: Diagnostic): Unit = {
       if (!warnings_.contains(th))
-        warnings_ :+= th
+        warnings_ += th
     }
 
     protected def oolagError(th: Diagnostic): Unit = {
       if (!errors_.contains(th))
-        errors_ :+= th
+        errors_ += th
     }
 
     /**
@@ -467,13 +480,13 @@
      * that have been created and activated at the time this is called.
      */
 
-    def isError = {
+    def isError: Boolean = {
       oolagRoot.checkErrors
-      val errorCount = oolagRoot.errors.length
+      val errorCount = oolagRoot.errors.size
       errorCount > 0
     }
 
-    def diagnostics = errors ++ warnings
+    def diagnostics: Seq[Diagnostic] = (errors ++ warnings).toSeq
   }
 
   /**
diff --git a/daffodil-lib/src/main/scala/org/apache/daffodil/util/Delay.scala b/daffodil-lib/src/main/scala/org/apache/daffodil/util/Delay.scala
index ac75979..02c43a2 100644
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/util/Delay.scala
+++ b/daffodil-lib/src/main/scala/org/apache/daffodil/util/Delay.scala
@@ -17,6 +17,8 @@
 
 package org.apache.daffodil.util
 
+import org.apache.daffodil.exceptions.Assert
+
 /**
  * Delay[T]
  *
@@ -27,18 +29,121 @@
  * ones we might have wanted to supply later, we instead supply them, but
  * as Delay objects.
  *
- * For more info, this is used in the IncludeImport stuff in DSOM.
+ * For more info, this is used in the IncludeImport stuff in DSOM, and
+ * in numerous other places where we construct, functionally, cyclic graphs.
+ *
+ * The idiom is to pass a Delay object to a constructor, and have the object
+ * constructed have a public initialize method (lazy val really) which
+ * forces the delays.
+ *
+ * Suppose we wanted a tuple-like pair to point at itself. It's a silly example,
+ * but illustrates what this is achieving.
+ * {{{
+ *
+ *   /** Like a Lisp "Cons Cell" with Car and "Cudder" values. */
+ *   class Cons(carDelay: Delay[Cons], cdrDelay: Delay[Cons]) extends Serializable {
+ *     lazy val car = carDelay.value
+ *     lazy val cdr = cdrDelay.value
+ *
+ *     lazy val initialize: Unit = {
+ *       car
+ *       cdr
+ *     }
+ *   }
+ *
+ *   // in Lisp, Nil behaves like a Cons where car and cdr are both Nil also.
+ *   lazy val LispNil = new Cons(Delay('car, this, LispNil), Delay('cdr, this, LispNil))
+ *
+ *
+ *   // elsewhere, these must be initialized before serialization or
+ *   // serialization will fail because Delay objects cause errors when
+ *   // serializing unless their values have been previously forced.
+ *
+ *   requiredEvaluation(LispNil.initialize)
+ *
+ *   objectOutputStream.writeObject(LispNil)
+ *
+ * }}}
  */
-
-class Delay[T] private (v: => T) {
-  lazy val value = v
-  private val hasValue: Boolean = false
-  override def toString = {
-    val bodyString = if (hasValue) value.toString else "..."
-    "Delay(" + bodyString + ")"
+final class Delay[T] private (private var box: Delay.Box[T], sym: Symbol)
+  extends PreSerialization {
+  //
+  // This trick of taking another object on a var, and
+  // then clobbering the var after we demand the value
+  // eliminates holding onto a bunch of objects due
+  // to closures for the pass-by-name arguments.
+  //
+  // The idea is no matter what the Scala implementation is doing in its implementation of
+  // by-name args, that's on the constructor of the box object,
+  // and we're going to explicitly null-out the reference to the box object
+  // which guarantees we're not holding onto things we don't expect
+  // once the Delay object has been evaluated.
+  //
+  lazy val value: T = {
+    Assert.invariant(box ne null)
+    val v = box.value
+    box = null // throws away box, which allows GC of all closures, etc.
+    v
   }
+
+  def hasValue = box eq null
+
+  /**
+   * For creating a delay object purely to satisfy a type requirement
+   * when you know the argument does not actually need to be delayed.
+   */
+  def force : Delay[T] = { value; this }
+
+  /**
+   * Create a string representation. Does not force the value to be computed.
+   */
+  override def toString = {
+    val bodyString = if (hasValue) ", " + value.toString else ""
+    val objString = if (hasValue) "" else {
+      box
+    }
+    "Delay(" + sym + ", " + objString + bodyString + ")"
+  }
+
+  override def preSerialization = {
+    if (!hasValue) {
+      Assert.invariant(box ne null)
+      val msg = s"No value for delay. Containing object not initialized? ID Symbol:$sym " +
+      s"object ${box}"
+      Assert.invariantFailed(msg)
+    }
+    super.preSerialization
+  }
+
+  @throws(classOf[java.io.IOException])
+  final private def writeObject(out: java.io.ObjectOutputStream): Unit = serializeObject(out)
 }
 
 object Delay {
-  def apply[T](v: => T) = new Delay(v)
+  /**
+   * Create a delayed expression object.
+   *
+   * @param delayedExpression an argument expression which will not be evaluated until required
+   * @tparam T type of the argument. (Usually inferred by Scala.)
+   * @return the Delay object
+   */
+  def apply[T](sym: Symbol, obj: AnyRef, delayedExpression: => T) = {
+    new Delay(new Box(sym, obj, delayedExpression), sym)
+  }
+
+  /**
+   * Specifically, this is NOT serializable.
+   * Serialization must force all Delay objects.
+   */
+  private class Box[T](val sym: Symbol, val obj: AnyRef, delayedExpression: => T) {
+    lazy val value = delayedExpression
+
+    override def toString() = {
+      val desc = obj match {
+        case d: NamedMixinBase => "(" + d.diagnosticDebugName + ")"
+        case _ => ""
+      }
+      "box(" + obj.hashCode() + desc + ")"
+    }
+  }
 }
diff --git a/daffodil-lib/src/main/scala/org/apache/daffodil/util/Named.scala b/daffodil-lib/src/main/scala/org/apache/daffodil/util/Named.scala
index 0b330b0..d7bd522 100644
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/util/Named.scala
+++ b/daffodil-lib/src/main/scala/org/apache/daffodil/util/Named.scala
@@ -17,6 +17,8 @@
 
 package org.apache.daffodil.util
 
+import org.apache.daffodil.exceptions.Assert
+
 /**
  * Things that are named need some common methods.
  *
@@ -27,7 +29,36 @@
 trait NamedMixinBase {
 
   /**
-   * For diagnostics/trace/debug purposes
+   * Flag used to prevent re-entry of diagnosticDebugName
    */
-  lazy val diagnosticDebugName: String = Misc.getNameFromClass(this)
-}
+  private var isAlreadyComputing: Boolean = false
+
+  /**
+   * For diagnostics/trace/debug purposes
+   *
+   * We cannot call diagnosticDebugName inside another call to diagnosticDebugName
+   * of the same object. This catches stack overflow situations.
+   */
+  final lazy val diagnosticDebugName: String = {
+    if (isAlreadyComputing == true) {
+      Assert.invariantFailed("Reentry of computation")
+    } else {
+      try {
+        isAlreadyComputing = true
+        diagnosticDebugNameImpl
+      } finally {
+        isAlreadyComputing = false
+      }
+    }
+  }
+
+  /**
+   * Override this to implement a diagnostic debug name.
+   *
+   * Note that this cannot throw exceptions because it is used to create
+   * diagnostic messages.
+   */
+  protected def diagnosticDebugNameImpl = className
+
+  private lazy val className = Misc.getNameFromClass(this)
+}
\ No newline at end of file
diff --git a/daffodil-lib/src/main/scala/org/apache/daffodil/util/TransitiveClosure.scala b/daffodil-lib/src/main/scala/org/apache/daffodil/util/TransitiveClosure.scala
new file mode 100644
index 0000000..9bc5b5d
--- /dev/null
+++ b/daffodil-lib/src/main/scala/org/apache/daffodil/util/TransitiveClosure.scala
@@ -0,0 +1,51 @@
+/*
+ * 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.util
+
+import scala.collection.mutable
+
+abstract class TransitiveClosure[T] {
+
+  protected def func(sc: T): Seq[T]
+
+  // LinkedHashSet so we get deterministic behavior.
+  private val processed = new mutable.LinkedHashSet[T]
+  private val items = new mutable.Queue[T]
+
+  def apply(start: Seq[T]): mutable.LinkedHashSet[T] = {
+    start.foreach{ items.enqueue(_) }
+    tclose()
+  }
+
+  /**
+   * Breadth first traversal.
+   */
+  private def tclose() = {
+    while(!items.isEmpty) {
+      val hd = items.dequeue
+      if (!processed.contains(hd)) {
+        processed += hd
+        val newOnes = func(hd).filterNot(processed.contains(_)).distinct
+        newOnes.foreach {
+          items.enqueue(_)
+        }
+      }
+    }
+    processed
+  }
+}
diff --git a/daffodil-lib/src/main/scala/org/apache/daffodil/xml/DaffodilConstructingLoader.scala b/daffodil-lib/src/main/scala/org/apache/daffodil/xml/DaffodilConstructingLoader.scala
index ac55be0..eadb27f 100644
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/xml/DaffodilConstructingLoader.scala
+++ b/daffodil-lib/src/main/scala/org/apache/daffodil/xml/DaffodilConstructingLoader.scala
@@ -444,7 +444,7 @@
       } catch {
         case e: Exception => {
           val exc = makeSAXParseException(curInput.pos, e.toString)
-          errorHandler.fatalError(exc)
+          errorHandler.fatalError(exc) // good place for a breakpoint
           null
         }
       }
diff --git a/daffodil-lib/src/main/scala/org/apache/daffodil/xml/DaffodilXMLLoader.scala b/daffodil-lib/src/main/scala/org/apache/daffodil/xml/DaffodilXMLLoader.scala
index f9b6caf..942e239 100644
--- a/daffodil-lib/src/main/scala/org/apache/daffodil/xml/DaffodilXMLLoader.scala
+++ b/daffodil-lib/src/main/scala/org/apache/daffodil/xml/DaffodilXMLLoader.scala
@@ -428,6 +428,14 @@
   private lazy val schemaFactory = {
     val sf = new org.apache.xerces.jaxp.validation.XMLSchemaFactory()
     sf.setResourceResolver(resolver)
+    //
+    // despite setting the errorHandler here, the validator
+    // sometimes still throws exceptions, so we cannot depend
+    // exclusively on the errorHandler picking off all errors.
+    //
+    // In particular, fatal errors when a node cannot be returned
+    // from the parse, always cause a throw.
+    //
     sf.setErrorHandler(errorHandler)
     sf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true)
     sf.setFeature(XMLUtils.XML_DISALLOW_DOCTYPE_FEATURE, true)
@@ -461,21 +469,40 @@
   def validateAsDFDLSchema(source: DaffodilSchemaSource): Unit = {
     // first we load it, with validation explicitly against the
     // schema for DFDL Schemas.
-    load(source, Some(XMLUtils.schemaForDFDLSchemas), addPositionAttributes = true)
-    //
-    // Then we validate explicitly so Xerces can check things
-    // such as for UPA violations
-    //
-    val inputSource = source.newInputSource()
-    val saxSource = new SAXSource(inputSource)
-    //
-    // We would like this saxSource to be created from an XMLReader
-    // so that we can call XMLUtils.setSecureDefaults on it.
-    // but we get strange errors if I do that, where every symbol
-    // in the schema has an unrecognized namespace prefix.
-    //
-    schemaFactory.newSchema(saxSource)
-    inputSource.getByteStream().close()
+    try {
+      load(source, Some(XMLUtils.schemaForDFDLSchemas), addPositionAttributes = true)
+      //
+      // Then we validate explicitly so Xerces can check things
+      // such as for UPA violations
+      //
+      val inputSource = source.newInputSource()
+      val saxSource = new SAXSource(inputSource)
+      //
+      // We would like this saxSource to be created from an XMLReader
+      // so that we can call XMLUtils.setSecureDefaults on it.
+      // but we get strange errors if I do that, where every symbol
+      // in the schema has an unrecognized namespace prefix.
+      //
+      try {
+        schemaFactory.newSchema(saxSource)
+      } finally {
+        inputSource.getByteStream().close()
+      }
+    } catch {
+      // fatal errors are thrown.
+      // validation errors are never fatal.
+      case e: SAXParseException => {
+        // Capturing this would be redundant.
+        // It will already have been passed to the errorHandler.fatalError
+        // method.
+        // So it is explicitly ok to just rethrow this exception.
+        // we don't want to record it again, but we do want to stop with a
+        // fatal error because the schema was invalid. Daffodil assumes the
+        // schema is valid all over its code base.
+        throw e
+      }
+    }
+
   }
 
   // $COVERAGE-OFF$
@@ -611,8 +638,14 @@
     val constructingLoader =
       new DaffodilConstructingLoader(source.uriForLoading,
         errorHandler, addPositionAttributes, normalizeCRLFtoLF)
-    val res = constructingLoader.load() // construct the XML objects for us.
-    constructingLoader.input.close()
+    val res = try {
+      constructingLoader.load() // construct the XML objects for us.
+    } catch {
+      case e: SAXParseException => // fatal. We can't successfully load.
+        throw e // good place for a breakpoint
+    } finally {
+      constructingLoader.input.close()
+    }
     res
   }
 }
diff --git a/daffodil-lib/src/test/scala/org/apache/daffodil/HowToUseJUnit.scala b/daffodil-lib/src/test/scala/org/apache/daffodil/HowToUseJUnit.scala
index 3d37874..065ca2e 100644
--- a/daffodil-lib/src/test/scala/org/apache/daffodil/HowToUseJUnit.scala
+++ b/daffodil-lib/src/test/scala/org/apache/daffodil/HowToUseJUnit.scala
@@ -84,7 +84,7 @@
   //        // println("not going to throw")
   //      }
   //    } catch {
-  //      case e: JUnitTestFailedError => // we're good // FIXME: wrong exception to catch
+  //      case e: JUnitTestFailedError => // we're good // is this the wrong exception to catch
   //      case e => throw e
   //    }
   //  }
diff --git a/daffodil-lib/src/test/scala/org/apache/daffodil/oolag/TestOOLAG.scala b/daffodil-lib/src/test/scala/org/apache/daffodil/oolag/TestOOLAG.scala
index 89cdc7a..ce58b7d 100644
--- a/daffodil-lib/src/test/scala/org/apache/daffodil/oolag/TestOOLAG.scala
+++ b/daffodil-lib/src/test/scala/org/apache/daffodil/oolag/TestOOLAG.scala
@@ -37,14 +37,14 @@
   extends OOLAGHostImpl(parentArg) {
 
   def a1 = a1_.value
-  def a1_ = LV('a1) {
+  lazy val a1_ = LV('a1) {
 
     // println("evaluating a1")
     "a1 value"
   }
 
   def a2 = a2_.value
-  def a2_ = LV('a2) {
+  lazy val a2_ = LV('a2) {
 
     // println("evaluating a2")
     val msg = "a2 failed with an exception"
@@ -75,46 +75,46 @@
   }
 
   def a3 = a3_.value
-  def a3_ = LV('a3) {
+  lazy val a3_ = LV('a3) {
     // println("My LV name is " + LV.name)
     "a3 value"
   }
 
   def a4 = a4_.value
-  def a4_ = LV('a4) {
+  lazy val a4_ = LV('a4) {
     // println("My LV name is " + LV.name)
     a3
   }
 
   def circ1: Int = circ1_.value
-  private def circ1_ = LV('circ1) {
+  private lazy val circ1_ = LV('circ1) {
     circ2
   }
 
   def circ2: Int = circ2_.value
-  private def circ2_ = LV('circ2) {
+  private lazy val circ2_ = LV('circ2) {
     circ1
   }
 
   def abortInside = abortInside_.value
-  private def abortInside_ = LV('abortInside) {
+  private lazy val abortInside_ = LV('abortInside) {
     abend
   }
 
   def abend = abend_.value
-  private def abend_ = LV('err) {
+  private lazy val abend_ = LV('err) {
     Assert.abort("supposed to abort here")
   }
 
   var x = 0
 
   def divZero = divZero_.value
-  def divZero_ = LV('divZero) {
+  lazy val divZero_ = LV('divZero) {
     5 / x
   }
 
   def warnTest = warnTest_.value
-  def warnTest_ = LV('warnTest) {
+  lazy val warnTest_ = LV('warnTest) {
     if (x < 1) {
       val diag = new MyException("warnTest")
       warn(diag)
@@ -214,7 +214,6 @@
       }
     }
     val msg = e.getMessage()
-    println(e)
     assertTrue(msg.toLowerCase().contains("circ1"))
   }
 
diff --git a/daffodil-lib/src/test/scala/org/apache/daffodil/util/TestNamed.scala b/daffodil-lib/src/test/scala/org/apache/daffodil/util/TestNamed.scala
new file mode 100644
index 0000000..a991446
--- /dev/null
+++ b/daffodil-lib/src/test/scala/org/apache/daffodil/util/TestNamed.scala
@@ -0,0 +1,41 @@
+/*
+ * 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.util
+
+import org.apache.daffodil.Implicits.intercept
+import org.apache.daffodil.exceptions.Abort
+import org.junit.Assert.assertTrue
+import org.junit.Test
+
+class TestNamed {
+
+  object namedThing extends NamedMixinBase {
+    override protected lazy val diagnosticDebugNameImpl = {
+      diagnosticDebugName // glaring example of reentry for the same object.
+    }
+  }
+
+  @Test def testDiagnosticDebugNameCatchesReentry(): Unit = {
+    val e = intercept[Abort] {
+      namedThing.diagnosticDebugName
+    }
+    val msg = e.getMessage()
+    assertTrue(msg.toLowerCase.contains("reentry"))
+  }
+
+}
diff --git a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ChoiceAndOtherVariousUnparsers.scala b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ChoiceAndOtherVariousUnparsers.scala
index b2ec9f5..1f7fb90 100644
--- a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ChoiceAndOtherVariousUnparsers.scala
+++ b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ChoiceAndOtherVariousUnparsers.scala
@@ -20,16 +20,14 @@
 import org.apache.daffodil.processors._
 import org.apache.daffodil.infoset._
 import org.apache.daffodil.processors.RuntimeData
-import org.apache.daffodil.util.Maybe._
 import org.apache.daffodil.util.Maybe
 import org.apache.daffodil.util.MaybeInt
 import org.apache.daffodil.util.Maybe._
-import org.apache.daffodil.util.PreSerialization
 
 case class ChoiceBranchMap(
   lookupTable: Map[ChoiceBranchEvent, Unparser],
   unmappedDefault: Option[Unparser])
-  extends PreSerialization {
+  extends Serializable {
 
   def get(cbe: ChoiceBranchEvent): Maybe[Unparser] = {
     val fromTable = lookupTable.get(cbe)
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/BasicComponent.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/BasicComponent.scala
index 40e155c..bb55dba 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/BasicComponent.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/BasicComponent.scala
@@ -36,4 +36,20 @@
   with ResolvesQNames
   with ImplementsThrowsOrSavesSDE {
 
+  /**
+   * Components have an initialize protocol.
+   *
+   * Use object factories (private constructor on the class) to
+   * enforce calling of initialize() after construction.
+   *
+   * The overrides of initialize should always call super.initialize()
+   *
+   * They should evaluate any lazy vals that MUST be evaluatable upon
+   * object construction - typically this is things that may be needed
+   * in order to issue diagnostic messages.
+   */
+  protected def initialize(): Unit = {
+    // do nothing.
+  }
+
 }
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/ConverterOps.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/ConverterOps.scala
index 5114d94..b811599 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/ConverterOps.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/ConverterOps.scala
@@ -275,8 +275,8 @@
       case l: JLong => if (l == 0) false else true
       case bi: JBigInt => if (bi.compareTo(JBigInt.ZERO) == 0) false else true
       // TODO: Once sequences are supported, fill in these case statements
-      //case s: Sequence if s.length == 0 => false
-      //case s: Sequence if s(0) == Node => true
+      //case s: LocalSequence if s.length == 0 => false
+      //case s: LocalSequence if s(0) == Node => true
       case _ => throw new NumberFormatException("Invalid argument type.")
     }
     res
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLXTypeCalcFunctions.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLXTypeCalcFunctions.scala
index d181cea..c07ae16 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLXTypeCalcFunctions.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLXTypeCalcFunctions.scala
@@ -19,7 +19,6 @@
 
 import org.apache.daffodil.infoset.DataValue.DataValuePrimitive
 import org.apache.daffodil.processors.TypeCalculator
-import org.apache.daffodil.exceptions.Assert
 
 case class DFDLXInputTypeCalc(typedRecipes: List[(CompiledDPath, NodeInfo.Kind)], calc: TypeCalculator)
   extends FNTwoArgs(typedRecipes.map(_._1)) {
@@ -44,67 +43,3 @@
   }
 }
 
-case class DFDLXOutputTypeCalcNextSibling(a: CompiledDPath, b: NodeInfo.Kind) extends RecipeOp {
-
-  def run(dstate: DState): Unit = {
-    if (dstate.isCompile) {
-      //CompileDPath.runExpressionForConstant (in DPathRuntime.scala) determines
-      //that an expression is not constant by seeing if evalutating it throws an exception
-      throw new IllegalStateException()
-    }
-
-    val nextSibling = dstate.nextSibling.asSimple
-    val typeCalculator = nextSibling.erd.optSimpleTypeRuntimeData.get.typeCalculator.get
-    /*
-     * The compiler knows about all the potential typeCalculators we can see here
-     * so any validation of typeCalculator should go in Expression.scala as part of compilation
-     */
-
-    val primType = nextSibling.erd.optPrimType.get
-
-    val x = nextSibling.dataValue
-    Assert.invariant(x.isDefined)
-    typeCalculator.outputTypeCalcRun(dstate, x.getNonNullable, primType)
-  }
-}
-
-case class DFDLXRepTypeValue(a: CompiledDPath, b: NodeInfo.Kind)
-  extends RecipeOp {
-
-  override def run(dstate: DState): Unit = {
-    if (dstate.isCompile){
-      throw new IllegalStateException()
-    }
-    
-    if (!dstate.repValue.isDefined) {
-      /*
-     * In theory, we should be able to detect this error at compile time. In practice
-     * the compiler does not provide sufficient details to the expression compiler for it
-     * to notice.
-     */
-      dstate.SDE("dfdlx:repTypeValue() may only be called from within dfdlx:inputTypeCalc")
-    }
-    dstate.setCurrentValue(dstate.repValue)
-  }
-}
-
-case class DFDLXLogicalTypeValue(a: CompiledDPath, b: NodeInfo.Kind)
-  extends RecipeOp {
-
-  override def run(dstate: DState): Unit = {
-    
-    if (dstate.isCompile){
-      throw new IllegalStateException()
-    }
-    
-    if (!dstate.logicalValue.isDefined) {
-      /*
-     * In theory, we should be able to detect this error at compile time. In practice
-     * the compiler does not provide sufficient details to the expression compiler for it
-     * to notice.
-     */
-      dstate.SDE("dfdlx:logicalTypeValue() may only be called from within dfdlx:outputTypeCalc")
-    }
-    dstate.setCurrentValue(dstate.logicalValue)
-  }
-}
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/NodeInfo.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/NodeInfo.scala
index 1b7cfef..2702428 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/NodeInfo.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/NodeInfo.scala
@@ -17,11 +17,16 @@
 
 package org.apache.daffodil.dpath
 
-import java.lang.{Byte => JByte, Double => JDouble, Float => JFloat, Integer => JInt, Long => JLong, Short => JShort}
-import java.math.{BigDecimal => JBigDecimal, BigInteger => JBigInt}
+import java.lang.{ Integer => JInt }
+import java.lang.{ Byte => JByte }
+import java.lang.{ Double => JDouble }
+import java.lang.{ Short => JShort }
+import java.lang.{ Long => JLong }
+import java.lang.{ Float => JFloat }
+import java.math.{ BigInteger => JBigInt }
+import java.math.{ BigDecimal => JBigDecimal }
 import java.net.URI
 import java.net.URISyntaxException
-
 import org.apache.daffodil.calendar.DFDLCalendar
 import org.apache.daffodil.calendar.DFDLDateConversion
 import org.apache.daffodil.calendar.DFDLDateTimeConversion
@@ -44,7 +49,10 @@
 import org.apache.daffodil.infoset.DataValue.DataValueShort
 import org.apache.daffodil.infoset.DataValue.DataValueTime
 import org.apache.daffodil.infoset.DataValue.DataValueURI
-import org.apache.daffodil.util.{Enum, MaybeInt, Misc}
+import org.apache.daffodil.util.Delay
+import org.apache.daffodil.util.Enum
+import org.apache.daffodil.util.MaybeInt
+import org.apache.daffodil.util.Misc
 import org.apache.daffodil.util.Numbers.asBigInt
 import org.apache.daffodil.util.Numbers.asBigDecimal
 import org.apache.daffodil.xml.GlobalQName
@@ -53,6 +61,7 @@
 import org.apache.daffodil.xml.RefQName
 import org.apache.daffodil.xml.XMLUtils
 
+object TypeNode
 /**
  * We need to have a data structure that lets us represent a type, and
  * its relationship (conversion, subtyping) to other types.
@@ -60,17 +69,42 @@
  * This is what TypeNodes are for. They are linked into a graph that
  * can answer questions about how two types are related. It can find the
  * least general supertype, or most general subtype of two types.
+ *
+ * We construct this highly-cyclic graph functionally, using lazy evaluation/Delay
+ * tricks to allow us to allocate an object that will eventually point at something
+ * that points back at this.
  */
-sealed abstract class TypeNode(parentsArg: => Seq[NodeInfo.Kind], childrenArg: => Seq[NodeInfo.Kind])
+sealed abstract class TypeNode private (
+  parentsDelay:  Delay[Seq[NodeInfo.Kind]],
+  childrenDelay: Delay[Seq[NodeInfo.Kind]])
   extends Serializable
   with NodeInfo.Kind {
 
-  def this(parentArg: NodeInfo.Kind, childrenArg: => Seq[NodeInfo.Kind]) = this(Seq(parentArg), childrenArg)
-  def this(parentArg: NodeInfo.Kind) = this(Seq(parentArg), Seq(NodeInfo.Nothing))
+  def this(sym: Symbol, parents: => Seq[NodeInfo.Kind], children: => Seq[NodeInfo.Kind]) =
+    this(Delay(sym, TypeNode , parents), Delay(sym, TypeNode, children))
 
-  // Eliminated a var here. Doing functional graph construction now below.
-  final override lazy val parents = parentsArg
-  final override lazy val children = childrenArg
+  def this(sym: Symbol, parentArg: NodeInfo.Kind, childrenArg: => Seq[NodeInfo.Kind]) =
+    this(Delay(sym, TypeNode, Seq(parentArg)), Delay(sym, TypeNode, childrenArg))
+
+  def this(sym: Symbol, parentArg: => NodeInfo.Kind) =
+    this(Delay(sym, TypeNode, Seq(parentArg)), Delay(sym, TypeNode, Seq[NodeInfo.Kind](NodeInfo.Nothing)))
+
+  /**
+   * Cyclic structures require an initialization
+   */
+  lazy val initialize: Unit = {
+    parents
+    children // demand their value
+    parents.foreach{ p =>
+      // if this fails, it is because cyclic graph construction of the types
+      // has failed. For some reason, this doesn't cause a stack overflow, but
+      // you just get null as the value of one of the case object type nodes.
+      Assert.invariant(p ne null)
+    }
+  }
+
+  final override lazy val parents = parentsDelay.value
+  final override lazy val children = childrenDelay.value
 }
 
 /*
@@ -78,10 +112,10 @@
  * deal with just the primitive types exclusive of all the abstract
  * types (like AnyAtomic, or AnyDateTimeType) that surround them.
  */
-sealed abstract class PrimTypeNode(parent: NodeInfo.Kind, childrenArg: => Seq[NodeInfo.Kind])
-  extends TypeNode(parent, childrenArg) with NodeInfo.PrimType {
+sealed abstract class PrimTypeNode(sym: Symbol, parent: NodeInfo.Kind, childrenArg: => Seq[NodeInfo.Kind])
+  extends TypeNode(sym, parent, childrenArg) with NodeInfo.PrimType {
 
-  def this(parent: NodeInfo.Kind) = this(parent, Seq(NodeInfo.Nothing))
+  def this(sym: Symbol, parent: NodeInfo.Kind) = this(sym, parent, Seq(NodeInfo.Nothing))
 }
 
 class InvalidPrimitiveDataException(msg: String, cause: Throwable = null) extends Exception(msg, cause)
@@ -124,6 +158,15 @@
  */
 object NodeInfo extends Enum {
 
+  /**
+   * Cyclic structures require initialization
+   */
+  lazy val initialize: Boolean = {
+    allTypes.foreach{
+      _.initialize }
+    true
+  }
+
   // Primitives are not "global" because they don't appear in any schema document
   sealed trait PrimType
     extends AnyAtomic.Kind {
@@ -166,6 +209,7 @@
   }
 
   sealed trait Kind extends EnumValueType with PrimTypeView {
+
     def name: String = Misc.getNameFromClass(this)
 
     def parents: Seq[Kind]
@@ -265,7 +309,7 @@
    * the indexing operation.
    */
   protected sealed trait ArrayKind extends NodeInfo.Kind
-  case object Array extends TypeNode(Nil, Nil) with ArrayKind {
+  case object Array extends TypeNode('Array, Nil, Nil) with ArrayKind {
     sealed trait Kind extends ArrayKind
   }
 
@@ -274,7 +318,7 @@
    * types except some special singleton types like ArrayType.
    */
   protected sealed trait AnyTypeKind extends NodeInfo.Kind
-  case object AnyType extends TypeNode(Nil, Seq(AnySimpleType, Complex, Exists)) with AnyTypeKind {
+  case object AnyType extends TypeNode('AnyType, Nil, Seq(AnySimpleType, Complex, Exists)) with AnyTypeKind {
     sealed trait Kind extends AnyTypeKind
   }
 
@@ -284,17 +328,24 @@
    * It is the return type of the dfdlx:error() function. It's a subtype of
    * every type (except some special singletons like ArrayType).
    */
-  case object Nothing
-    extends TypeNode(
-      List(
-        Boolean,
-        Complex, Array, ArrayIndex,
-        Double, Float,
-        Date, Time, DateTime,
-        UnsignedByte, Byte,
-        HexBinary,
-        AnyURI,
-        String, NonEmptyString), Nil)
+  lazy val Nothing = new TypeNode('Nothing,
+    Seq(
+      Boolean,
+      Complex,
+      Array,
+      ArrayIndex,
+      Double,
+      Float,
+      Date,
+      Time,
+      DateTime,
+      UnsignedByte,
+      Byte,
+      HexBinary,
+      AnyURI,
+      String,
+      NonEmptyString),
+    Nil)
     with Boolean.Kind
     with Complex.Kind
     with Array.Kind
@@ -314,7 +365,7 @@
    * All complex types are represented by this one type object.
    */
   protected sealed trait ComplexKind extends AnyType.Kind
-  case object Complex extends TypeNode(AnyType) with ComplexKind {
+  case object Complex extends TypeNode('Complex, AnyType) with ComplexKind {
     type Kind = ComplexKind
   }
 
@@ -322,7 +373,7 @@
    * For things like fn:exists, fn:empty, dfdl:contenLength
    */
   protected sealed trait ExistsKind extends AnyType.Kind
-  case object Exists extends TypeNode(AnyType) with AnyTypeKind {
+  case object Exists extends TypeNode('Exists, AnyType) with AnyTypeKind {
     type Kind = ExistsKind
   }
 
@@ -337,32 +388,32 @@
    * where AnyAtomic does not?
    */
   protected sealed trait AnySimpleTypeKind extends AnyType.Kind
-  case object AnySimpleType extends TypeNode(AnyType, Seq(AnyAtomic)) with AnySimpleTypeKind {
+  case object AnySimpleType extends TypeNode('AnySimpleType, AnyType, Seq(AnyAtomic)) with AnySimpleTypeKind {
     type Kind = AnySimpleTypeKind
   }
 
   protected sealed trait AnyAtomicKind extends AnySimpleType.Kind
-  case object AnyAtomic extends TypeNode(AnySimpleType, Seq(String, Numeric, Boolean, Opaque, AnyDateTime, AnyURI)) with AnyAtomicKind {
+  case object AnyAtomic extends TypeNode('AnyAtomic, AnySimpleType, Seq(String, Numeric, Boolean, Opaque, AnyDateTime, AnyURI)) with AnyAtomicKind {
     type Kind = AnyAtomicKind
   }
 
   protected sealed trait NumericKind extends AnyAtomic.Kind
-  case object Numeric extends TypeNode(AnyAtomic, Seq(SignedNumeric, UnsignedNumeric)) with NumericKind {
+  case object Numeric extends TypeNode('Numeric, AnyAtomic, Seq(SignedNumeric, UnsignedNumeric)) with NumericKind {
     type Kind = NumericKind
   }
 
   protected sealed trait SignedNumericKind extends Numeric.Kind
-  case object SignedNumeric extends TypeNode(Numeric, Seq(Float, Double, Decimal)) with SignedNumericKind {
+  case object SignedNumeric extends TypeNode('SignedNumeric, Numeric, Seq(Float, Double, Decimal)) with SignedNumericKind {
     type Kind = SignedNumericKind
   }
 
   protected sealed trait UnsignedNumericKind extends Numeric.Kind
-  case object UnsignedNumeric extends TypeNode(Numeric, Seq(NonNegativeInteger)) with UnsignedNumericKind {
+  case object UnsignedNumeric extends TypeNode('UnsignedNumeric, Numeric, Seq(NonNegativeInteger)) with UnsignedNumericKind {
     type Kind = UnsignedNumericKind
   }
 
   protected sealed trait OpaqueKind extends AnyAtomic.Kind
-  case object Opaque extends TypeNode(AnyAtomic, Seq(HexBinary)) with OpaqueKind {
+  case object Opaque extends TypeNode('Opaque, AnyAtomic, Seq(HexBinary)) with OpaqueKind {
     type Kind = OpaqueKind
   }
 
@@ -373,16 +424,16 @@
    * arent allowed to be empty strings (e.g. padChar).
    */
   protected sealed trait NonEmptyStringKind extends String.Kind
-  case object NonEmptyString extends TypeNode(String) with NonEmptyStringKind {
+  case object NonEmptyString extends TypeNode('NonEmptyString, String) with NonEmptyStringKind {
     type Kind = NonEmptyStringKind
   }
   protected sealed trait ArrayIndexKind extends UnsignedInt.Kind
-  case object ArrayIndex extends TypeNode(UnsignedInt) with ArrayIndexKind {
+  case object ArrayIndex extends TypeNode('ArrayIndex, UnsignedInt) with ArrayIndexKind {
     type Kind = ArrayIndexKind
   }
 
   protected sealed trait AnyDateTimeKind extends AnyAtomicKind
-  case object AnyDateTime extends TypeNode(AnyAtomic, Seq(Date, Time, DateTime)) with AnyDateTimeKind {
+  case object AnyDateTime extends TypeNode('AnyDateTime, AnyAtomic, Seq(Date, Time, DateTime)) with AnyDateTimeKind {
     type Kind = AnyDateTimeKind
   }
 
@@ -547,7 +598,7 @@
     }
 
     protected sealed trait FloatKind extends SignedNumeric.Kind
-    case object Float extends PrimTypeNode(SignedNumeric) with FloatKind with PrimNumericFloat with FloatView {
+    case object Float extends PrimTypeNode('Float, SignedNumeric) with FloatKind with PrimNumericFloat with FloatView {
       type Kind = FloatKind
       protected override def fromString(s: String) = {
         val f: JFloat = s match {
@@ -565,7 +616,7 @@
     }
 
     protected sealed trait DoubleKind extends SignedNumeric.Kind
-    case object Double extends PrimTypeNode(SignedNumeric) with DoubleKind with PrimNumericFloat with DoubleView {
+    case object Double extends PrimTypeNode('Double, SignedNumeric) with DoubleKind with PrimNumericFloat with DoubleView {
       type Kind = DoubleKind
       protected override def fromString(s: String): DataValueDouble = {
         val d: JDouble = s match {
@@ -583,7 +634,7 @@
     }
 
     protected sealed trait DecimalKind extends SignedNumeric.Kind
-    case object Decimal extends PrimTypeNode(SignedNumeric, List(Integer)) with DecimalKind with PrimNumeric with DecimalView {
+    case object Decimal extends PrimTypeNode('Decimal, SignedNumeric, List(Integer)) with DecimalKind with PrimNumeric with DecimalView {
       type Kind = DecimalKind
       protected override def fromString(s: String): DataValueBigDecimal = new JBigDecimal(s)
       protected override def fromNumberNoCheck(n: Number): DataValueBigDecimal = asBigDecimal(n)
@@ -593,7 +644,7 @@
     }
 
     protected sealed trait IntegerKind extends Decimal.Kind
-    case object Integer extends PrimTypeNode(Decimal, List(Long, NonNegativeInteger)) with IntegerKind with PrimNumeric
+    case object Integer extends PrimTypeNode('Integer, Decimal, List(Long, NonNegativeInteger)) with IntegerKind with PrimNumeric
         with IntegerView {
       type Kind = IntegerKind
       protected override def fromString(s: String): DataValueBigInt = new JBigInt(s)
@@ -604,7 +655,7 @@
     }
 
     protected sealed trait LongKind extends Integer.Kind
-    case object Long extends PrimTypeNode(Integer, List(Int)) with LongKind with PrimNumericInteger with LongView {
+    case object Long extends PrimTypeNode('Long, Integer, List(Int)) with LongKind with PrimNumericInteger with LongView {
       type Kind = LongKind
       protected override def fromString(s: String): DataValueLong = s.toLong
       protected override def fromNumberNoCheck(n: Number): DataValueLong = n.longValue
@@ -614,7 +665,7 @@
     }
 
     protected sealed trait IntKind extends Long.Kind
-    case object Int extends PrimTypeNode(Long, List(Short)) with IntKind with PrimNumericInteger with IntView {
+    case object Int extends PrimTypeNode('Int, Long, List(Short)) with IntKind with PrimNumericInteger with IntView {
       type Kind = IntKind
       protected override def fromString(s: String): DataValueInt = s.toInt
       protected override def fromNumberNoCheck(n: Number): DataValueInt = n.intValue
@@ -624,7 +675,7 @@
     }
 
     protected sealed trait ShortKind extends Int.Kind
-    case object Short extends PrimTypeNode(Int, List(Byte)) with ShortKind with PrimNumericInteger with ShortView {
+    case object Short extends PrimTypeNode('Short, Int, List(Byte)) with ShortKind with PrimNumericInteger with ShortView {
       type Kind = ShortKind
       protected override def fromString(s: String): DataValueShort = s.toShort
       protected override def fromNumberNoCheck(n: Number): DataValueShort = n.shortValue
@@ -634,7 +685,7 @@
     }
 
     protected sealed trait ByteKind extends Short.Kind
-    case object Byte extends PrimTypeNode(Short) with ByteKind with PrimNumericInteger with ByteView {
+    case object Byte extends PrimTypeNode('Byte, Short) with ByteKind with PrimNumericInteger with ByteView {
       type Kind = ByteKind
       protected override def fromString(s: String): DataValueByte = s.toByte
       protected override def fromNumberNoCheck(n: Number): DataValueByte = n.byteValue
@@ -644,7 +695,7 @@
     }
 
     protected sealed trait NonNegativeIntegerKind extends Integer.Kind
-    case object NonNegativeInteger extends PrimTypeNode(Integer, List(UnsignedLong)) with NonNegativeIntegerKind with PrimNumeric
+    case object NonNegativeInteger extends PrimTypeNode('NonNegativeInteger, Integer, List(UnsignedLong)) with NonNegativeIntegerKind with PrimNumeric
         with NonNegativeIntegerView {
       type Kind = NonNegativeIntegerKind
       protected override def fromString(s: String): DataValueBigInt = new JBigInt(s)
@@ -658,7 +709,7 @@
     }
 
     protected sealed trait UnsignedLongKind extends NonNegativeInteger.Kind
-    case object UnsignedLong extends PrimTypeNode(NonNegativeInteger, List(UnsignedInt)) with UnsignedLongKind with PrimNumeric
+    case object UnsignedLong extends PrimTypeNode('UnsignedLong, NonNegativeInteger, List(UnsignedInt)) with UnsignedLongKind with PrimNumeric
         with UnsignedLongView {
       type Kind = UnsignedLongKind
       protected override def fromString(s: String): DataValueBigInt = new JBigInt(s)
@@ -674,7 +725,7 @@
     }
 
     protected sealed trait UnsignedIntKind extends UnsignedLong.Kind
-    case object UnsignedInt extends PrimTypeNode(UnsignedLong, List(UnsignedShort, ArrayIndex)) with UnsignedIntKind with PrimNumericInteger
+    case object UnsignedInt extends PrimTypeNode('UnsignedInt, UnsignedLong, List(UnsignedShort, ArrayIndex)) with UnsignedIntKind with PrimNumericInteger
         with UnsignedIntView {
       type Kind = UnsignedIntKind
       protected override def fromString(s: String): DataValueLong = s.toLong
@@ -685,7 +736,7 @@
     }
 
     protected sealed trait UnsignedShortKind extends UnsignedInt.Kind
-    case object UnsignedShort extends PrimTypeNode(UnsignedInt, List(UnsignedByte)) with UnsignedShortKind with PrimNumericInteger
+    case object UnsignedShort extends PrimTypeNode('UnsignedShort, UnsignedInt, List(UnsignedByte)) with UnsignedShortKind with PrimNumericInteger
         with UnsignedShortView {
       type Kind = UnsignedShortKind
       protected override def fromString(s: String): DataValueInt = s.toInt
@@ -696,7 +747,7 @@
     }
 
     protected sealed trait UnsignedByteKind extends UnsignedShort.Kind
-    case object UnsignedByte extends PrimTypeNode(UnsignedShort) with UnsignedByteKind with PrimNumericInteger
+    case object UnsignedByte extends PrimTypeNode('UnsignedByte, UnsignedShort) with UnsignedByteKind with PrimNumericInteger
         with UnsignedByteView {
       type Kind = UnsignedByteKind
       protected override def fromString(s: String): DataValueShort = s.toShort
@@ -707,13 +758,13 @@
     }
 
     protected sealed trait StringKind extends AnyAtomic.Kind
-    case object String extends PrimTypeNode(AnyAtomic, List(NonEmptyString)) with StringKind with StringView {
+    case object String extends PrimTypeNode('String, AnyAtomic, List(NonEmptyString)) with StringKind with StringView {
       type Kind = StringKind
       override def fromXMLString(s: String) = s
     }
 
     protected sealed trait BooleanKind extends AnySimpleType.Kind
-    case object Boolean extends PrimTypeNode(AnyAtomic) with BooleanKind with PrimNonNumeric with BooleanView {
+    case object Boolean extends PrimTypeNode('Boolean, AnyAtomic) with BooleanKind with PrimNonNumeric with BooleanView {
       type Kind = BooleanKind
       protected override def fromString(s: String): DataValueBool = {
         s match {
@@ -725,19 +776,19 @@
     }
 
     protected sealed trait AnyURIKind extends AnySimpleType.Kind
-    case object AnyURI extends PrimTypeNode(AnyAtomic) with AnyURIKind with PrimNonNumeric with AnyURIView {
+    case object AnyURI extends PrimTypeNode('AnyURI, AnyAtomic) with AnyURIKind with PrimNonNumeric with AnyURIView {
       type Kind = AnyURIKind
       protected override def fromString(s: String): DataValueURI = new URI(s)
     }
 
     protected sealed trait HexBinaryKind extends Opaque.Kind
-    case object HexBinary extends PrimTypeNode(Opaque) with HexBinaryKind with PrimNonNumeric with HexBinaryView {
+    case object HexBinary extends PrimTypeNode('HexBinary, Opaque) with HexBinaryKind with PrimNonNumeric with HexBinaryView {
       type Kind = HexBinaryKind
       protected override def fromString(s: String): DataValueByteArray = Misc.hex2Bytes(s)
     }
 
     protected sealed trait DateKind extends AnyDateTimeKind
-    case object Date extends PrimTypeNode(AnyDateTime) with DateKind with PrimNonNumeric with DateView {
+    case object Date extends PrimTypeNode('Date, AnyDateTime) with DateKind with PrimNonNumeric with DateView {
       type Kind = DateKind
       protected override def fromString(s: String): DataValueDate = {
         DFDLDateConversion.fromXMLString(s)
@@ -745,7 +796,7 @@
     }
 
     protected sealed trait DateTimeKind extends AnyDateTimeKind
-    case object DateTime extends PrimTypeNode(AnyDateTime) with DateTimeKind with PrimNonNumeric with DateTimeView {
+    case object DateTime extends PrimTypeNode('DateTime, AnyDateTime) with DateTimeKind with PrimNonNumeric with DateTimeView {
       type Kind = DateTimeKind
       protected override def fromString(s: String): DataValueDateTime = {
         DFDLDateTimeConversion.fromXMLString(s)
@@ -753,7 +804,7 @@
     }
 
     protected sealed trait TimeKind extends AnyDateTimeKind
-    case object Time extends PrimTypeNode(AnyDateTime) with TimeKind with PrimNonNumeric with TimeView {
+    case object Time extends PrimTypeNode('Time, AnyDateTime) with TimeKind with PrimNonNumeric with TimeView {
       type Kind = TimeKind
       protected override def fromString(s: String): DataValueTime = {
         DFDLTimeConversion.fromXMLString(s)
@@ -766,11 +817,11 @@
   // list and the definition of these type objects above.
   //
   private lazy val allAbstractTypes = List(
-    AnyType, AnySimpleType, AnyAtomic, Exists,
+    AnyType, AnySimpleType, AnyAtomic, AnyDateTime, AnyURI, Exists,
     Numeric, SignedNumeric, UnsignedNumeric,
     // There is no UnsignedInteger because the concrete type
     // NonNegativeInteger plays that role.
-    Opaque, AnyDateTime, Nothing)
+    Opaque, AnyDateTime)
   private lazy val allDFDLTypes = List(
     Float, Double, Decimal, Integer, Long, Int, Short, Byte,
     NonNegativeInteger, UnsignedLong, UnsignedInt, UnsignedShort, UnsignedByte,
@@ -778,6 +829,7 @@
     Date, Time, DateTime)
 
   lazy val allTypes =
-    allDFDLTypes ++ List(Complex, ArrayIndex, NonEmptyString) ++ allAbstractTypes
+    allDFDLTypes ++ List(Complex, Array, ArrayIndex, NonEmptyString, Nothing) ++ allAbstractTypes
 
+  initialize // initialize self - creates all cyclic structures
 }
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 8fcd43d..3eefc1c 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
@@ -18,7 +18,6 @@
 package org.apache.daffodil.dsom
 
 import scala.runtime.ScalaRunTime.stringOf
-
 import org.apache.daffodil.api.UnqualifiedPathStepPolicy
 import org.apache.daffodil.api.WarnID
 import org.apache.daffodil.dpath.DState
@@ -28,14 +27,13 @@
 import org.apache.daffodil.exceptions.SchemaFileLocation
 import org.apache.daffodil.infoset.DataValue
 import org.apache.daffodil.processors.ParseOrUnparseState
-import org.apache.daffodil.processors.RuntimeData
 import org.apache.daffodil.processors.Suspension
 import org.apache.daffodil.processors.TypeCalculatorCompiler.TypeCalcMap
 import org.apache.daffodil.processors.VariableMap
+import org.apache.daffodil.util.Delay
 import org.apache.daffodil.util.Maybe
 import org.apache.daffodil.util.MaybeULong
 import org.apache.daffodil.util.PreSerialization
-import org.apache.daffodil.util.TransientParam
 import org.apache.daffodil.xml.NS
 import org.apache.daffodil.xml.NamedQName
 import org.apache.daffodil.xml.NoNamespace
@@ -44,8 +42,10 @@
 trait ContentValueReferencedElementInfoMixin {
 
   def contentReferencedElementInfos: Set[DPathElementCompileInfo]
+
   def valueReferencedElementInfos: Set[DPathElementCompileInfo]
 }
+
 /**
  * For the DFDL path/expression language, this provides the place to
  * type check the expression (SDE if not properly typed)
@@ -104,10 +104,13 @@
    */
   @deprecated("Code should just call evaluate(...) on an Evaluatable object.", "2016-02-18")
   def constant: T
+
   def isConstant: Boolean
 
   def evaluate(state: ParseOrUnparseState): T
+
   def run(dstate: DState): Unit
+
   /**
    * The target type of the expression. This is the type that we want the expression to create.
    */
@@ -151,6 +154,7 @@
     dstate.setCurrentValue(DataValue.unsafeFromAnyRef(value))
     value
   }
+
   override def run(dstate: DState) = dstate.setCurrentValue(DataValue.unsafeFromAnyRef(value))
 
   final def evaluateForwardReferencing(state: ParseOrUnparseState, whereBlockedLocation: Suspension): Maybe[T] = {
@@ -162,9 +166,11 @@
   def expressionEvaluationBlockLocation = MaybeULong.Nope
 
   def constant: T = value
+
   def isConstant = true
 
   override def contentReferencedElementInfos = ReferencedElementInfos.None
+
   override def valueReferencedElementInfos = ReferencedElementInfos.None
 }
 
@@ -201,29 +207,21 @@
  * into "passes".
  */
 class DPathCompileInfo(
-  @TransientParam parentsArg: Seq[DPathCompileInfo],
-  @TransientParam variableMapArg: => VariableMap,
+
+  parentsDelay: Delay[Seq[DPathCompileInfo]],
+  val variableMap: VariableMap,
   val namespaces: scala.xml.NamespaceBinding,
   val path: String,
   override val schemaFileLocation: SchemaFileLocation,
   val unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy,
-  typeCalcMapArg: TypeCalcMap,
-  //
-  // lexicalContextRuntimeData is used to get the partialNextElementResolver which is used
-  // to get the next sibling info to support the outputTypeCalcNextSibling function.
-  //
-  // TODO: DAFFODIL-2326 do not pass runtime data as argment to DPathCompileInfo. The point
-  // is for DPathCompileInfo to NOT have all of the runtime data for the term, but just what
-  // is needed to compile DPath. If functions need info about next sibling, then we should
-  // compute what it needs and pass that here (e.g, sequence of possible next sibling DPathCompileInfos,
-  // or if this applies only to elements, then it should be on that object.
-  //
-  // We should not hook in the whole runtime data object here. This should be runtime independent code.
-  //
-  val lexicalContextRuntimeData: RuntimeData)
-  extends ImplementsThrowsSDE with PreSerialization
-  with HasSchemaFileLocation {
+  typeCalcMapArg: TypeCalcMap)
+  extends ImplementsThrowsSDE
+    with PreSerialization
+    with HasSchemaFileLocation {
 
+  def initialize: Unit = {
+    parents
+  }
 
   /**
    * This "parents" val is a backpointer to all DPathCompileInfo's that
@@ -241,8 +239,7 @@
    * Sequence objects and the stack depth is again relative to the schema
    * depth.
    */
-  @transient
-  val parents = parentsArg
+  lazy val parents = parentsDelay.value
 
   def serializeParents(oos: java.io.ObjectOutputStream): Unit = {
     oos.writeObject(parents)
@@ -264,19 +261,11 @@
     parentsField.setAccessible(false)
   }
 
-
-  lazy val variableMap =
-    variableMapArg
-
   /*
    * This map(identity) pattern appears to work around an unidentified bug with serialization.
    */
   lazy val typeCalcMap: TypeCalcMap = typeCalcMapArg.map(identity)
 
-  override def preSerialization: Any = {
-    variableMap
-  }
-
   def diagnosticDebugName = path
 
   @throws(classOf[java.io.IOException])
@@ -298,8 +287,12 @@
    * and the SerializationProxy object.
    */
   final lazy val enclosingElementCompileInfos: Seq[DPathElementCompileInfo] = {
-    val eci = elementCompileInfos.flatMap { _.parents }
-    val res = eci.flatMap { _.elementCompileInfos }
+    val eci = elementCompileInfos.flatMap {
+      _.parents
+    }
+    val res = eci.flatMap {
+      _.elementCompileInfos
+    }
     res
   }.map(identity)
 
@@ -340,10 +333,21 @@
  * (first), and kept on this object, and then subsequently ERD data
  * structures are created which reference these.
  */
-class DPathElementCompileInfo(
-  @TransientParam parentsArg: Seq[DPathElementCompileInfo],
+class DPathElementCompileInfo
+(
+  parentsDelay: Delay[Seq[DPathElementCompileInfo]],
+  // parentsArg is a transient due to serialization order issues,
+  // there is no delay/lazy/by-name involvement here.
+
   variableMap: VariableMap,
-  @TransientParam elementChildrenCompileInfoArg: => Seq[DPathElementCompileInfo],
+  // This next arg must be a Delay as we're creating a circular
+  // structure here. Element's compile info points down to their children. Children
+  // point back to their parents, which may be multiple parents if they are shared.
+  //
+  // We choose a Delay object not call-by-name because it has features to enable
+  // the GC to collect the closure objects that are created from the calling context
+  // to realize the by-name arg expression.
+  elementChildrenCompileInfoDelay: Delay[Seq[DPathElementCompileInfo]],
   namespaces: scala.xml.NamespaceBinding,
   path: String,
   val name: String,
@@ -353,12 +357,21 @@
   sfl: SchemaFileLocation,
   override val unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy,
   typeCalcMap: TypeCalcMap,
-  lexicalContextRuntimeData: RuntimeData,
   val sscd: String,
   val isOutputValueCalc: Boolean)
-  extends DPathCompileInfo(parentsArg, variableMap, namespaces, path, sfl,
+  extends DPathCompileInfo(
+    parentsDelay.asInstanceOf[Delay[Seq[DPathCompileInfo]]],
+    variableMap, namespaces, path, sfl,
     unqualifiedPathStepPolicy,
-    typeCalcMap, lexicalContextRuntimeData) {
+    typeCalcMap) {
+
+  /**
+   * Cyclic objects require initialization
+   */
+  override lazy val initialize: Unit = {
+    parents
+    elementChildrenCompileInfo
+  }
 
   override def serializeParents(oos: java.io.ObjectOutputStream): Unit = {
     super.serializeParents(oos)
@@ -370,8 +383,7 @@
     elementChildrenCompileInfo.foreach { _.deserializeParents(ois) }
   }
 
-
-  lazy val elementChildrenCompileInfo = elementChildrenCompileInfoArg
+  lazy val elementChildrenCompileInfo = elementChildrenCompileInfoDelay.value
 
   override def preSerialization: Any = {
     super.preSerialization
@@ -423,6 +435,7 @@
       info.isReferencedByExpressions = true
     }
   }
+
   /**
    * Finds a child ERD that matches a StepQName. This is for matching up
    * path steps (for example) to their corresponding ERD.
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 1c5341f..3004164 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
@@ -343,7 +343,7 @@
 
   def withTunables(tunablesArg: Map[String, String]): DataProcessor = copy(tunables = tunables.setTunables(tunablesArg))
 
-  override def isError = false // really there is no compiling at all currently, so there can be no errors.
+  override def isError = false
 
   override def getDiagnostics = ssrd.diagnostics
 
@@ -717,8 +717,6 @@
 
   private def encodingInfo = if (maybeEncodingInfo.isDefined) maybeEncodingInfo.get else dp.ssrd.elementRuntimeData.encodingInfo
 
-  def summaryEncoding = encodingInfo.summaryEncoding
-
   override def isScannable = encodingInfo.isScannable
   override def encodingName = {
     Assert.invariant(encodingInfo.isKnownEncoding)
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/EncodingRuntimeData.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/EncodingRuntimeData.scala
index 0447d97..b2bc424 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/EncodingRuntimeData.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/EncodingRuntimeData.scala
@@ -17,7 +17,6 @@
 
 package org.apache.daffodil.processors
 
-import org.apache.daffodil.dsom.EncodingLattice
 import org.apache.daffodil.dsom.ImplementsThrowsSDE
 import org.apache.daffodil.exceptions.Assert
 import org.apache.daffodil.exceptions.SchemaFileLocation
@@ -26,10 +25,8 @@
 import org.apache.daffodil.processors.charset.StandardBitsCharsets
 import org.apache.daffodil.schema.annotation.props.gen.EncodingErrorPolicy
 import org.apache.daffodil.schema.annotation.props.gen.UTF16Width
-import org.apache.daffodil.util.Maybe
-import org.apache.daffodil.util.PreSerialization
-import org.apache.daffodil.util.TransientParam
 import org.apache.daffodil.processors.charset.CharsetUtils
+import org.apache.daffodil.util.Maybe
 
 /**
  * To eliminate circularities between RuntimeData objects and the
@@ -110,33 +107,16 @@
 
 }
 
-/**
- * This is the object we serialize.
- *
- * At compile time we will create an encodingInfo
- * for ourselves supplying as context a schema component.
- *
- * At runtime we will create an encodingInfo supplying as context
- * a TermRuntimeData object.
- */
-
 final class EncodingRuntimeData(
-  @TransientParam charsetEvArg: => CharsetEv,
+  val charsetEv: CharsetEv,
   override val schemaFileLocation: SchemaFileLocation,
-  optionUTF16WidthArg: Option[UTF16Width],
+  val maybeUTF16Width: Maybe[UTF16Width],
   val defaultEncodingErrorPolicy: EncodingErrorPolicy,
-  val summaryEncoding: EncodingLattice,
   val isKnownEncoding: Boolean,
   val isScannable: Boolean,
   override val knownEncodingAlignmentInBits: Int,
   val hasTextAlignment: Boolean)
-  extends KnownEncodingMixin with ImplementsThrowsSDE with PreSerialization {
-
-  private val maybeUTF16Width_ = Maybe.toMaybe[UTF16Width](optionUTF16WidthArg)
-
-  def maybeUTF16Width = maybeUTF16Width_
-
-  lazy val charsetEv = charsetEvArg
+  extends KnownEncodingMixin with ImplementsThrowsSDE with Serializable {
 
   lazy val runtimeDependencies = Vector(charsetEv)
 
@@ -162,12 +142,4 @@
     cs
   }
 
-  override def preSerialization: Any = {
-    super.preSerialization
-    charsetEv
-  }
-
-  @throws(classOf[java.io.IOException])
-  private def writeObject(out: java.io.ObjectOutputStream): Unit = serializeObject(out)
-
 }
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 58ffc8c..480ed82 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
@@ -181,6 +181,7 @@
   @inline final def isCompiled = isCompiled_
 
   @inline final def ensureCompiled: Unit = {
+    ci.initialize
     if (!isCompiled)
       Assert.invariantFailed("not compiled Ev: " + this.qName)
   }
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 6e93846..bdb882c 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
@@ -35,10 +35,9 @@
 import org.apache.daffodil.schema.annotation.props.gen.Representation
 import org.apache.daffodil.schema.annotation.props.gen.YesNo
 import org.apache.daffodil.schema.annotation.props.gen.VariableDirection
+import org.apache.daffodil.util.Delay
 import org.apache.daffodil.util.Maybe
 import org.apache.daffodil.util.Maybe.Nope
-import org.apache.daffodil.util.PreSerialization
-import org.apache.daffodil.util.TransientParam
 import org.apache.daffodil.xml.GlobalQName
 import org.apache.daffodil.xml.LocalDeclQName
 import org.apache.daffodil.xml.NS
@@ -50,7 +49,6 @@
 
 import scala.util.matching.Regex; object NoWarn { ImplicitsSuppressUnusedImportWarning() }
 import java.util.regex.Matcher
-
 import org.apache.daffodil.api.UnqualifiedPathStepPolicy
 import org.apache.daffodil.infoset.DISimple
 import org.apache.daffodil.infoset.DataValue
@@ -75,7 +73,7 @@
 sealed trait RuntimeData
   extends ImplementsThrowsSDE
   with HasSchemaFileLocation
-  with PreSerialization {
+  with Serializable {
   def schemaFileLocation: SchemaFileLocation
   def diagnosticDebugName: String
   def path: String
@@ -85,6 +83,7 @@
 
   def unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy
 
+  def namespaces: NamespaceBinding
 }
 
 object TermRuntimeData {
@@ -99,31 +98,58 @@
 
 }
 
+/**
+ * Base runtime data structure for all terms
+ *
+ * These Delay-type args are part of how we
+ * create a structure here which contains some objects that
+ * somewhere within themselves, refer back to this structure.
+ *
+ * A Delay object is part of a functional programming idiom for creating
+ * a cyclic structure without using side-effects and therefore ordering-dependency.
+ * It is pretty similar to just passing an argument by-name (lazily) but
+ * has some additional sophistication to avoid dragging Scala closures
+ * around and ending up with objects being not garbage collectable.
+ *
+ * The relationhip between RuntimeData and PartialNextElementResolver is
+ * indeed cyclic. Simplest to think of it in terms of elements.
+ * An ERD has a partialNextElementResolver which exists to figure out
+ * the ERD of the next element, which could be this same ERD again, or
+ * could be some other ERD which can then be followed by an element with
+ * this same ERD again. So the cycle can be immediate or flow through
+ * many ERDs and partialNextElementResolvers. Turns out other kinds of
+ * terms can affect the next element resolver process (there's a stack
+ * of them) so partialNextElementResolver ends up on the TermRuntimeData
+ * to share the definition of the slot for this polymorphically.
+ */
 sealed abstract class TermRuntimeData(
-  /**
-   * These transient by-name args are part of how we
-   * create a structure here which contains some objects that
-   * somewhere within themselves, refer back to this structure.
-   *
-   * These are passed by-name, and ultimately what is serialized is not
-   * these, but lazy vals that refer to them which are forced to have
-   * values at the time of object serialization.
-   */
   val position: Int,
-  @TransientParam partialNextElementResolverArg: => PartialNextElementResolver,
-  @TransientParam encodingInfoArg: => EncodingRuntimeData, // depends on CharsetEv
-  @TransientParam dpathCompileInfoArg: => DPathCompileInfo,
-  val isRepresented:  Boolean,
-  @TransientParam couldHaveTextArg: => Boolean,
-  @TransientParam alignmentValueInBitsArg: => Int, // depends ultimately on EncodingEv.isConstant
+  partialNextElementResolverDelay: Delay[PartialNextElementResolver],
+  val encodingInfo: EncodingRuntimeData,
+  val dpathCompileInfo: DPathCompileInfo,
+  val isRepresented: Boolean,
+  val couldHaveText: Boolean,
+  val alignmentValueInBits: Int, // depends ultimately on EncodingEv.isConstant
   val hasNoSkipRegions: Boolean,
-  val defaultBitOrder:  BitOrder,
+  val defaultBitOrder: BitOrder,
   val optIgnoreCase: Option[YesNo],
-  @TransientParam fillByteEvArg: => FillByteEv,
-  @TransientParam maybeCheckByteAndBitOrderEvArg: => Maybe[CheckByteAndBitOrderEv],
-  @TransientParam maybeCheckBitOrderAndCharsetEvArg: => Maybe[CheckBitOrderAndCharsetEv])
+  val fillByteEv: FillByteEv,
+  val maybeCheckByteAndBitOrderEv: Maybe[CheckByteAndBitOrderEv],
+  val maybeCheckBitOrderAndCharsetEv: Maybe[CheckBitOrderAndCharsetEv])
   extends RuntimeData {
 
+  /**
+   * Cyclic structures require initialization
+   */
+  lazy val initialize: Unit = initializeFunction
+
+  protected def initializeFunction: Unit = {
+    partialNextElementResolver
+    dpathCompileInfo.initialize
+  }
+
+  final def namespaces = dpathCompileInfo.namespaces
+
   private val termID = TermRuntimeData.generateTermID
 
   final override def hashCode(): Int = termID
@@ -151,29 +177,8 @@
    */
   def unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy = dpathCompileInfo.unqualifiedPathStepPolicy
 
-  lazy val partialNextElementResolver = partialNextElementResolverArg
-  lazy val encodingInfo = encodingInfoArg
-  lazy val dpathCompileInfo = dpathCompileInfoArg
-  lazy val couldHaveText = couldHaveTextArg
-  lazy val alignmentValueInBits = alignmentValueInBitsArg
-  lazy val fillByteEv = fillByteEvArg
-  lazy val maybeCheckByteAndBitOrderEv = maybeCheckByteAndBitOrderEvArg
-  lazy val maybeCheckBitOrderAndCharsetEv = maybeCheckBitOrderAndCharsetEvArg
-
-  override def preSerialization: Unit = {
-    super.preSerialization
-    partialNextElementResolver
-    encodingInfo
-    dpathCompileInfo
-    couldHaveText
-    alignmentValueInBits
-    fillByteEv
-    maybeCheckByteAndBitOrderEv
-    maybeCheckBitOrderAndCharsetEv
-  }
-  @throws(classOf[java.io.IOException])
-  final private def writeObject(out: java.io.ObjectOutputStream): Unit = serializeObject(out)
-
+  lazy val partialNextElementResolver =
+    partialNextElementResolverDelay.value
 }
 
 sealed class NonTermRuntimeData(
@@ -181,14 +186,9 @@
   val schemaFileLocation:  SchemaFileLocation,
   val diagnosticDebugName:  String,
   val path: String,
-  val namespaces: NamespaceBinding,
+  override val namespaces: NamespaceBinding,
   val unqualifiedPathStepPolicy: UnqualifiedPathStepPolicy)
-  extends RuntimeData {
-
-  @throws(classOf[java.io.IOException])
-  final private def writeObject(out: java.io.ObjectOutputStream): Unit = serializeObject(out)
-
-}
+  extends RuntimeData
 
 /**
  * Singleton. If found as the default value, means to use nil as
@@ -225,9 +225,6 @@
 
   import org.apache.daffodil.util.OKOrError._
 
-  @throws(classOf[java.io.IOException])
-  final private def writeObject(out: java.io.ObjectOutputStream): Unit = serializeObject(out)
-
   /**
    * These are creators of regex pattern matcher objects. we want to avoid
    * allocating Matchers, so this is thread-safe in terms of allocating and returning the
@@ -527,53 +524,50 @@
 
 }
 
-/*
- * These objects have become too big. Most processors don't need most of this stuff.
- *
- * The objective should be to take things OUT of this structure and pass directly to the
- * constructor of the parser/unparser.
+/** Primary Runtime data structure for Elements
  *
  * These objects are for things that are generally heavily used everywhere like information for
  * providing diagnostics.
+ *
+ * These Delay-type args are part of how we
+ * create a structure here which contains some objects that
+ * somewhere within themselves, refer back to this structure.
+ *
+ * These structures are inherently cyclic, particularly for ElementRuntimeData (ERD)
+ * the PartialNextElementResolver,
+ * which is about figuring out the next ERD given incoming name+namespace
+ * and context. Hence it by its very nature contains and returns ERDs and
+ * so involves cycles with the ERD structure.
+ *
+ * To construct this cyclic data structure but still be using functional
+ * programming, we use these Delay/lazy evaluation tricks.
  */
-
 sealed class ElementRuntimeData(
-  /**
-   * These transient by-name args are part of how we
-   * create a structure here which contains some objects that
-   * somewhere within themselves, refer back to this structure.
-   *
-   * These are passed by-name, and ultimately what is serialized is not
-   * these, but lazy vals that refer to them which are forced to have
-   * values at the time of object serialization.
-   *
-   * Note that all transient elements must be added to the preSerialization method below
-   * to allow parser serialization/deserialization to work.
-   */
   positionArg: Int,
-  @TransientParam childrenArg: => Seq[ElementRuntimeData],
-  @TransientParam variableMapArg: => VariableMap,
-  @TransientParam partialNextElementResolverArg: => PartialNextElementResolver,
-  @TransientParam encInfoArg: => EncodingRuntimeData,
-  @TransientParam dpathElementCompileInfoArg: => DPathElementCompileInfo,
+  children: Seq[ElementRuntimeData],
+  val variableMap: VariableMap,
+  partialNextElementResolverDelay: Delay[PartialNextElementResolver],
+  val encInfo: EncodingRuntimeData,
+  val dpathElementCompileInfo: DPathElementCompileInfo,
   val schemaFileLocation: SchemaFileLocation,
   val diagnosticDebugName: String,
   val path: String,
-  @TransientParam minimizedScopeArg: => NamespaceBinding,
+  val minimizedScope: NamespaceBinding,
   defaultBitOrderArg: BitOrder,
-  @TransientParam optPrimTypeArg: => Option[PrimType],
-  @TransientParam targetNamespaceArg: => NS,
-  @TransientParam optSimpleTypeRuntimeDataArg: => Option[SimpleTypeRuntimeData],
-  @TransientParam optComplexTypeModelGroupRuntimeDataArg: => Option[ModelGroupRuntimeData],
-  @TransientParam minOccursArg: => Long,
-  @TransientParam maxOccursArg: => Long,
-  @TransientParam maybeOccursCountKindArg: => Maybe[OccursCountKind],
-  @TransientParam nameArg: => String,
-  @TransientParam targetNamespacePrefixArg: => String,
-  @TransientParam isNillableArg: => Boolean,
-  @TransientParam isArrayArg: => Boolean, // can have more than 1 occurrence
-  @TransientParam isOptionalArg: => Boolean, // can have only 0 or 1 occurrence
-  @TransientParam isRequiredInUnparseInfosetArg: => Boolean, // must have at least 1 occurrence
+  val optPrimType: Option[PrimType],
+  val targetNamespace: NS,
+  val optSimpleTypeRuntimeData: Option[SimpleTypeRuntimeData],
+  val optComplexTypeModelGroupRuntimeData: Option[ModelGroupRuntimeData],
+  val minOccurs: Long,
+  val maxOccurs: Long,
+  val maybeOccursCountKind: Maybe[OccursCountKind],
+  val name: String,
+  val targetNamespacePrefix: String,
+  val isNillable: Boolean,
+  val isArray: Boolean, // can have more than 1 occurrence
+  val isOptional: Boolean, // can have only 0 or 1 occurrence
+  val isRequiredInUnparseInfoset: Boolean, // must have at least 1 occurrence
+
   /**
    * This is the properly qualified name for recognizing this
    * element.
@@ -582,99 +576,38 @@
    * If 'qualified' then there will be a namespace component.
    * If 'unqualified' the the namespace component will be No_Namespace.
    */
-  @TransientParam namedQNameArg: => NamedQName,
+  val namedQName: NamedQName,
   isRepresentedArg: Boolean,
-  @TransientParam couldHaveTextArg: => Boolean,
-  @TransientParam alignmentValueInBitsArg: => Int,
+  couldHaveTextArg: Boolean,
+  alignmentValueInBitsArg: Int,
   hasNoSkipRegionsArg: Boolean,
-  @TransientParam impliedRepresentationArg: => Representation,
+  val impliedRepresentation: Representation,
   optIgnoreCaseArg: Option[YesNo],
-  @TransientParam optDefaultValueArg: => DataValuePrimitiveOrUseNilForDefaultOrNull,
+  val optDefaultValue: DataValuePrimitiveOrUseNilForDefaultOrNull,
   //
   // Unparser-specific arguments
   //
-  @TransientParam optTruncateSpecifiedLengthStringArg: => Option[Boolean],
-  @TransientParam outputValueCalcExprArg: => Option[CompiledExpression[AnyRef]],
-  @TransientParam maybeBinaryFloatRepEvArg: => Maybe[BinaryFloatRepEv],
-  @TransientParam maybeByteOrderEvArg: => Maybe[ByteOrderEv],
-  @TransientParam fillByteEvArg: => FillByteEv,
-  @TransientParam maybeCheckByteAndBitOrderEvArg: => Maybe[CheckByteAndBitOrderEv],
-  @TransientParam maybeCheckBitOrderAndCharsetEvArg: => Maybe[CheckBitOrderAndCharsetEv],
-  @TransientParam isQuasiElementArg: => Boolean)
-  extends TermRuntimeData(positionArg, partialNextElementResolverArg,
-    encInfoArg, dpathElementCompileInfoArg, isRepresentedArg, couldHaveTextArg, alignmentValueInBitsArg, hasNoSkipRegionsArg,
+  val optTruncateSpecifiedLengthString: Option[Boolean],
+  val outputValueCalcExpr: Option[CompiledExpression[AnyRef]],
+  val maybeBinaryFloatRepEv: Maybe[BinaryFloatRepEv],
+  val maybeByteOrderEv: Maybe[ByteOrderEv],
+  fillByteEvArg: FillByteEv,
+  maybeCheckByteAndBitOrderEvArg: Maybe[CheckByteAndBitOrderEv],
+  maybeCheckBitOrderAndCharsetEvArg: Maybe[CheckBitOrderAndCharsetEv],
+  val isQuasiElement: Boolean)
+  extends TermRuntimeData(positionArg, partialNextElementResolverDelay,
+    encInfo, dpathElementCompileInfo, isRepresentedArg, couldHaveTextArg, alignmentValueInBitsArg, hasNoSkipRegionsArg,
     defaultBitOrderArg, optIgnoreCaseArg, fillByteEvArg,
     maybeCheckByteAndBitOrderEvArg,
     maybeCheckBitOrderAndCharsetEvArg) {
 
   override def isRequiredScalar = !isArray && isRequiredInUnparseInfoset
-  override def namespaces: NamespaceBinding = dpathElementCompileInfo.namespaces
-
-  lazy val children = childrenArg
-  lazy val variableMap = variableMapArg
-  lazy val encInfo = encInfoArg
-  lazy val dpathElementCompileInfo = dpathElementCompileInfoArg
-  lazy val minimizedScope = minimizedScopeArg
-  lazy val optPrimType = optPrimTypeArg
-  lazy val targetNamespace = targetNamespaceArg
-  lazy val optSimpleTypeRuntimeData = optSimpleTypeRuntimeDataArg
-  lazy val optComplexTypeModelGroupRuntimeData = optComplexTypeModelGroupRuntimeDataArg
-  lazy val minOccurs = minOccursArg
-  lazy val maxOccurs = maxOccursArg
-  lazy val maybeOccursCountKind = maybeOccursCountKindArg
-  lazy val name = nameArg
-  lazy val targetNamespacePrefix = targetNamespacePrefixArg
-  lazy val isNillable = isNillableArg
-  override lazy val isArray = isArrayArg
-  lazy val isOptional = isOptionalArg
-  lazy val isRequiredInUnparseInfoset = isRequiredInUnparseInfosetArg // if true, no uncertainty about number of occurrences.
-  lazy val namedQName = namedQNameArg
-  lazy val impliedRepresentation = impliedRepresentationArg
-  lazy val optDefaultValue = optDefaultValueArg
-  lazy val optTruncateSpecifiedLengthString = optTruncateSpecifiedLengthStringArg
-  lazy val outputValueCalcExpr = outputValueCalcExprArg
-  lazy val maybeBinaryFloatRepEv = maybeBinaryFloatRepEvArg
-  lazy val maybeByteOrderEv = maybeByteOrderEvArg
-  lazy val isQuasiElement = isQuasiElementArg
-
-  override def preSerialization: Unit = {
-    super.preSerialization
-    children
-    variableMap
-    encInfo
-    dpathElementCompileInfo
-    minimizedScope
-    optPrimType
-    targetNamespace
-    optSimpleTypeRuntimeData
-    optComplexTypeModelGroupRuntimeData
-    minOccurs
-    maxOccurs
-    maybeOccursCountKind
-    name
-    targetNamespacePrefix
-    isNillable
-    isArray
-    isOptional
-    isRequiredInUnparseInfoset
-    namedQName
-    impliedRepresentation
-    optDefaultValue
-    optTruncateSpecifiedLengthString
-    outputValueCalcExpr
-    maybeBinaryFloatRepEv
-    maybeByteOrderEv
-    isQuasiElement
-  }
-
-  @throws(classOf[java.io.IOException])
-  private def writeObject(out: java.io.ObjectOutputStream): Unit = serializeObject(out)
 
   final def childERDs = children
 
   def isSimpleType = optPrimType.isDefined
 
-  lazy val schemaURIStringsForFullValidation = schemaURIStringsForFullValidation1.distinct
+  lazy val schemaURIStringsForFullValidation: Seq[String] = schemaURIStringsForFullValidation1.distinct
   private def schemaURIStringsForFullValidation1: Seq[String] = (schemaFileLocation.uriString +:
     childERDs.flatMap { _.schemaURIStringsForFullValidation1 })
 
@@ -689,7 +622,6 @@
       name
     }
   }
-
 }
 
 /**
@@ -720,9 +652,9 @@
     null, // PartialNextElementResolver
     null, // EncodingRuntimeData
     new DPathElementCompileInfo(
-      Nil, // parentsArg: => Seq[DPathElementCompileInfo],
+      Delay('ErrorERDParents, getClass().getName, Seq[DPathElementCompileInfo]()).force, // parentsArg: => Seq[DPathElementCompileInfo],
       null, // variableMap: => VariableMap,
-      Nil, // elementChildrenCompileInfoArg: => Seq[DPathElementCompileInfo],
+      Delay('ErrorERD, getClass().getName, Seq[DPathElementCompileInfo]()).force, // elementChildrenCompileInfoDelay: Delay[Seq[DPathElementCompileInfo]],
       null, // namespaces: scala.xml.NamespaceBinding,
       local, // path: String,
       local, // val name: String,
@@ -732,7 +664,6 @@
       null, // sfl: SchemaFileLocation,
       null, // override val unqualifiedPathStepPolicy : UnqualifiedPathStepPolicy,
       null, // typeCalcMap: TypeCalcMap,
-      null, // lexicalContextRuntimeData: RuntimeData,
       null, // val sscd: String),
       false), // val hasOutputValueCalc: Boolean
     null, // SchemaFileLocation
@@ -773,9 +704,6 @@
 
   override def toString() = Misc.getNameFromClass(this) + "(" + this.namedQName.toExtendedSyntax + ")"
 
-  @throws(classOf[java.io.IOException])
-  private def writeObject(out: java.io.ObjectOutputStream): Unit =
-    Assert.usageError("Not for serialization")
 }
 
 /**
@@ -823,160 +751,133 @@
   }
 }
 
+/**
+ * Base class for model group runtime data
+ *
+ * These Delay-type args are part of how we
+ * create a structure here which contains some objects that
+ * somewhere within themselves, refer back to this structure.
+ */
 sealed abstract class ModelGroupRuntimeData(
-  /**
-   * These transient by-name args are part of how we
-   * create a structure here which contains some objects that
-   * somewhere within themselves, refer back to this structure.
-   *
-   * These are passed by-name, and ultimately what is serialized is not
-   * these, but lazy vals that refer to them which are forced to have
-   * values at the time of object serialization.
-   */
   positionArg: Int,
-  @TransientParam partialNextElementResolverArg: => PartialNextElementResolver,
-  @TransientParam variableMapArg: => VariableMap,
-  @TransientParam encInfoArg: => EncodingRuntimeData,
-  val schemaFileLocation:  SchemaFileLocation,
-  @TransientParam ciArg: => DPathCompileInfo,
-  val diagnosticDebugName:  String,
-  val path:  String,
+  partialNextElementResolverDelay: Delay[PartialNextElementResolver],
+  val variableMap: VariableMap,
+  val encInfo: EncodingRuntimeData,
+  val schemaFileLocation: SchemaFileLocation,
+  ci: DPathCompileInfo,
+  val diagnosticDebugName: String,
+  val path: String,
   defaultBitOrderArg: BitOrder,
-  @TransientParam groupMembersArg: => Seq[TermRuntimeData],
+  val groupMembers: Seq[TermRuntimeData],
   isRepresentedArg: Boolean,
-  @TransientParam couldHaveTextArg: => Boolean,
-  alignmentValueInBitsArg:  Int,
-  hasNoSkipRegionsArg:  Boolean,
+  couldHaveText: Boolean,
+  alignmentValueInBitsArg: Int,
+  hasNoSkipRegionsArg: Boolean,
   optIgnoreCaseArg: Option[YesNo],
-  @TransientParam fillByteEvArg: => FillByteEv,
-  @TransientParam maybeCheckByteAndBitOrderEvArg: => Maybe[CheckByteAndBitOrderEv],
-  @TransientParam maybeCheckBitOrderAndCharsetEvArg: => Maybe[CheckBitOrderAndCharsetEv])
+  fillByteEvArg: FillByteEv,
+  maybeCheckByteAndBitOrderEvArg: Maybe[CheckByteAndBitOrderEv],
+  maybeCheckBitOrderAndCharsetEvArg: Maybe[CheckBitOrderAndCharsetEv])
   extends TermRuntimeData(
-    positionArg, partialNextElementResolverArg,
-    encInfoArg, ciArg, isRepresentedArg, couldHaveTextArg, alignmentValueInBitsArg, hasNoSkipRegionsArg,
+    positionArg, partialNextElementResolverDelay,
+    encInfo, ci, isRepresentedArg, couldHaveText, alignmentValueInBitsArg, hasNoSkipRegionsArg,
     defaultBitOrderArg, optIgnoreCaseArg, fillByteEvArg,
     maybeCheckByteAndBitOrderEvArg,
     maybeCheckBitOrderAndCharsetEvArg) {
 
   final override def isRequiredScalar = true
   final override def isArray = false
-  override def namespaces: NamespaceBinding = ci.namespaces
-
-  lazy val variableMap = variableMapArg
-  lazy val encInfo = encInfoArg
-  lazy val ci = ciArg
-  lazy val groupMembers = groupMembersArg
-
-  override def preSerialization: Unit = {
-    super.preSerialization
-    variableMap
-    encInfo
-    ci
-    groupMembers
-  }
-  @throws(classOf[java.io.IOException])
-  final private def writeObject(out: java.io.ObjectOutputStream): Unit = serializeObject(out)
 }
 
+/**
+ * These Delay-type args are part of how we
+ * create a structure here which contains some objects that
+ * somewhere within themselves, refer back to this structure.
+ */
 final class SequenceRuntimeData(
-  /**
-   * These transient by-name args are part of how we
-   * create a structure here which contains some objects that
-   * somewhere within themselves, refer back to this structure.
-   *
-   * These are passed by-name, and ultimately what is serialized is not
-   * these, but lazy vals that refer to them which are forced to have
-   * values at the time of object serialization.
-   */
   positionArg: Int,
-  @TransientParam partialNextElementResolverArg: => PartialNextElementResolver,
-  @TransientParam variableMapArg: => VariableMap,
-  @TransientParam encInfoArg: => EncodingRuntimeData,
+  partialNextElementResolverDelay: Delay[PartialNextElementResolver],
+  variableMapArg: VariableMap,
+  encInfo: EncodingRuntimeData,
   schemaFileLocationArg: SchemaFileLocation,
-  @TransientParam ciArg: => DPathCompileInfo,
+  ci: DPathCompileInfo,
   diagnosticDebugNameArg: String,
-  pathArg:  String,
+  pathArg: String,
   defaultBitOrderArg: BitOrder,
-  @TransientParam groupMembersArg: => Seq[TermRuntimeData],
+  groupMembersArg: Seq[TermRuntimeData],
   isRepresentedArg: Boolean,
-  @TransientParam couldHaveTextArg: => Boolean,
+  couldHaveText: Boolean,
   alignmentValueInBitsArg: Int,
   hasNoSkipRegionsArg: Boolean,
   optIgnoreCaseArg: Option[YesNo],
-  @TransientParam fillByteEvArg: => FillByteEv,
-  @TransientParam maybeCheckByteAndBitOrderEvArg: => Maybe[CheckByteAndBitOrderEv],
-  @TransientParam maybeCheckBitOrderAndCharsetEvArg: => Maybe[CheckBitOrderAndCharsetEv])
-  extends ModelGroupRuntimeData(positionArg, partialNextElementResolverArg,
-    variableMapArg, encInfoArg, schemaFileLocationArg, ciArg, diagnosticDebugNameArg, pathArg, defaultBitOrderArg, groupMembersArg,
-    isRepresentedArg, couldHaveTextArg, alignmentValueInBitsArg, hasNoSkipRegionsArg, optIgnoreCaseArg,
+  fillByteEvArg: FillByteEv,
+  maybeCheckByteAndBitOrderEvArg: Maybe[CheckByteAndBitOrderEv],
+  maybeCheckBitOrderAndCharsetEvArg: Maybe[CheckBitOrderAndCharsetEv])
+  extends ModelGroupRuntimeData(positionArg, partialNextElementResolverDelay,
+    variableMapArg, encInfo, schemaFileLocationArg, ci, diagnosticDebugNameArg, pathArg, defaultBitOrderArg, groupMembersArg,
+    isRepresentedArg, couldHaveText, alignmentValueInBitsArg, hasNoSkipRegionsArg, optIgnoreCaseArg,
     fillByteEvArg,
     maybeCheckByteAndBitOrderEvArg,
     maybeCheckBitOrderAndCharsetEvArg)
 
+/*
+ * These Delay-type args are part of how we
+ * create a structure here which contains some objects that
+ * somewhere within themselves, refer back to this structure.
+ */
 final class ChoiceRuntimeData(
-  /**
-   * These transient by-name args are part of how we
-   * create a structure here which contains some objects that
-   * somewhere within themselves, refer back to this structure.
-   *
-   * These are passed by-name, and ultimately what is serialized is not
-   * these, but lazy vals that refer to them which are forced to have
-   * values at the time of object serialization.
-   */
   positionArg: Int,
-  @TransientParam partialNextElementResolverArg: => PartialNextElementResolver,
-  @TransientParam variableMapArg: => VariableMap,
-  @TransientParam encInfoArg: => EncodingRuntimeData,
+  partialNextElementResolverDelay: Delay[PartialNextElementResolver],
+  variableMapArg: VariableMap,
+  encInfo: EncodingRuntimeData,
   schemaFileLocationArg: SchemaFileLocation,
-  @TransientParam ciArg: => DPathCompileInfo,
+  ci: DPathCompileInfo,
   diagnosticDebugNameArg: String,
   pathArg: String,
   defaultBitOrderArg: BitOrder,
-  @TransientParam groupMembersArg: => Seq[TermRuntimeData],
+  groupMembersArg: Seq[TermRuntimeData],
   isRepresentedArg: Boolean,
-  @TransientParam couldHaveTextArg: => Boolean,
+  couldHaveText: Boolean,
   alignmentValueInBitsArg: Int,
   hasNoSkipRegionsArg: Boolean,
   optIgnoreCaseArg: Option[YesNo],
-  @TransientParam fillByteEvArg: => FillByteEv,
-  @TransientParam maybeCheckByteAndBitOrderEvArg: => Maybe[CheckByteAndBitOrderEv],
-  @TransientParam maybeCheckBitOrderAndCharsetEvArg: => Maybe[CheckBitOrderAndCharsetEv])
-  extends ModelGroupRuntimeData(positionArg, partialNextElementResolverArg,
-    variableMapArg, encInfoArg, schemaFileLocationArg, ciArg, diagnosticDebugNameArg, pathArg, defaultBitOrderArg, groupMembersArg,
-    isRepresentedArg, couldHaveTextArg, alignmentValueInBitsArg, hasNoSkipRegionsArg, optIgnoreCaseArg, fillByteEvArg,
+  fillByteEvArg: FillByteEv,
+  maybeCheckByteAndBitOrderEvArg: Maybe[CheckByteAndBitOrderEv],
+  maybeCheckBitOrderAndCharsetEvArg: Maybe[CheckBitOrderAndCharsetEv])
+  extends ModelGroupRuntimeData(positionArg, partialNextElementResolverDelay,
+    variableMapArg, encInfo, schemaFileLocationArg, ci, diagnosticDebugNameArg, pathArg, defaultBitOrderArg, groupMembersArg,
+    isRepresentedArg, couldHaveText, alignmentValueInBitsArg, hasNoSkipRegionsArg, optIgnoreCaseArg, fillByteEvArg,
     maybeCheckByteAndBitOrderEvArg,
     maybeCheckBitOrderAndCharsetEvArg)
 
 final class VariableRuntimeData(
-  schemaFileLocationArg:  SchemaFileLocation,
-  diagnosticDebugNameArg:  String,
+  schemaFileLocationArg: SchemaFileLocation,
+  diagnosticDebugNameArg: String,
   pathArg: String,
   namespacesArg: NamespaceBinding,
   val external: Boolean,
   val direction: VariableDirection,
-  @TransientParam maybeDefaultValueExprArg: => Maybe[CompiledExpression[AnyRef]],
-  val typeRef:  RefQName,
+  maybeDefaultValueExprDelay: Delay[Maybe[CompiledExpression[AnyRef]]],
+  val typeRef: RefQName,
   val globalQName: GlobalQName,
-  val primType:  NodeInfo.PrimType,
-  unqualifiedPathStepPolicyArg:  UnqualifiedPathStepPolicy)
+  val primType: NodeInfo.PrimType,
+  unqualifiedPathStepPolicyArg: UnqualifiedPathStepPolicy)
   extends NonTermRuntimeData(
     null, // no variable map
     schemaFileLocationArg,
     diagnosticDebugNameArg,
     pathArg,
     namespacesArg,
-    unqualifiedPathStepPolicyArg)
-  with Serializable {
+    unqualifiedPathStepPolicyArg) {
 
-  lazy val maybeDefaultValueExpr = maybeDefaultValueExprArg
-
-  override def preSerialization: Unit = {
-    super.preSerialization
-    maybeDefaultValueExpr
+  /**
+   * Cyclic structures require initialization
+   */
+  lazy val initialize: Unit = {
+    maybeDefaultValueExpr // demand this
   }
 
-  @throws(classOf[java.io.IOException])
-  final private def writeObject(out: java.io.ObjectOutputStream): Unit = serializeObject(out)
+  lazy val maybeDefaultValueExpr: Maybe[CompiledExpression[AnyRef]] = maybeDefaultValueExprDelay.value
+
 
   def createVariableInstance(): VariableInstance = VariableInstance(rd=this)
 
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/TypeCalculator.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/TypeCalculator.scala
index dcb719e..a0e5f7c 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/TypeCalculator.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/TypeCalculator.scala
@@ -19,7 +19,6 @@
 
 import scala.collection.immutable.HashMap
 import scala.collection.immutable.HashSet
-
 import org.apache.daffodil.dpath.DState
 import org.apache.daffodil.dpath.NodeInfo
 import org.apache.daffodil.dsom.CompiledExpression
@@ -30,19 +29,18 @@
 import org.apache.daffodil.processors.parsers.PState
 import org.apache.daffodil.processors.parsers.ParseError
 import org.apache.daffodil.processors.unparsers.UState
+import org.apache.daffodil.util.Delay
 import org.apache.daffodil.util.Maybe
 import org.apache.daffodil.util.Maybe.One
 import org.apache.daffodil.util.Numbers
-import org.apache.daffodil.util.PreSerialization
-import org.apache.daffodil.util.TransientParam
 import org.apache.daffodil.xml.QNameBase
 
 abstract class TypeCalculator(val srcType: NodeInfo.Kind, val dstType: NodeInfo.Kind)
-  extends PreSerialization {
+  extends Serializable {
   type Error = String
 
-  override def preSerialization: Any = {
-    super.preSerialization
+  def initialize(): Unit = {
+    // base method does nothing
   }
 
   /*
@@ -121,9 +119,6 @@
   def supportsParse: Boolean = true
   def supportsUnparse: Boolean = true
 
-  @throws(classOf[java.io.IOException])
-  final private def writeObject(out: java.io.ObjectOutputStream): Unit = serializeObject(out)
-
   /*
    * In theory, this normalizeArg method should not be nessasary. We know at compile time what
    * types a given calculator is defined in terms of, so the compiler should insert any conversion
@@ -198,13 +193,25 @@
 }
 
 class ExpressionTypeCalculator(
-  @TransientParam maybeInputTypeCalcArg: => Maybe[CompiledExpression[AnyRef]],
-  @TransientParam maybeOutputTypeCalcArg: => Maybe[CompiledExpression[AnyRef]],
-  srcType: NodeInfo.Kind, dstType: NodeInfo.Kind)
+  private val maybeInputTypeCalcDelay: Delay[Maybe[CompiledExpression[AnyRef]]],
+  private val maybeOutputTypeCalcDelay: Delay[Maybe[CompiledExpression[AnyRef]]],
+  srcType: NodeInfo.Kind,
+  dstType: NodeInfo.Kind)
   extends TypeCalculator(srcType, dstType) {
 
-  override def supportsParse = maybeInputTypeCalcArg.isDefined
-  override def supportsUnparse = maybeOutputTypeCalcArg.isDefined
+  /*
+   * objects with Delay arguments for functional programming construction of
+   * cyclic graphs, need a way to force the delays, resulting in an ordinary
+   * (though cyclic) data structure.
+   */
+  final override def initialize(): Unit = {
+    super.initialize()
+    maybeInputTypeCalc
+    maybeOutputTypeCalc
+  }
+
+  override def supportsParse = maybeInputTypeCalc.isDefined
+  override def supportsUnparse = maybeOutputTypeCalc.isDefined
 
   /*
    * Compiling DPath expressions may need to evaluate typeCalculators in order to lookup their srcType and dstType.
@@ -212,15 +219,8 @@
    *
    * Since these fields must be lazy, we cannot use them to determine supportsParse or supportUnparse
    */
-
-  lazy val maybeInputTypeCalc = maybeInputTypeCalcArg
-  lazy val maybeOutputTypeCalc = maybeOutputTypeCalcArg
-
-  override def preSerialization: Any = {
-    super.preSerialization
-    maybeInputTypeCalc
-    maybeOutputTypeCalc
-  }
+  lazy val maybeInputTypeCalc = maybeInputTypeCalcDelay.value
+  lazy val maybeOutputTypeCalc = maybeOutputTypeCalcDelay.value
 
   //The class TypeValueCalc will verify that supports(Un)Parse is true when nessasary
   //Therefore, if we ever call the below functions, we know that the relevent Maybe object is defined.
@@ -413,7 +413,13 @@
     srcType: NodeInfo.Kind, dstType: NodeInfo.Kind): ExpressionTypeCalculator = {
     lazy val maybeInputType: Maybe[CompiledExpression[AnyRef]] = optInputTypeCalc.map(Maybe(_)).getOrElse(Maybe.Nope)
     lazy val maybeOutputType: Maybe[CompiledExpression[AnyRef]] = optOutputTypeCalc.map(Maybe(_)).getOrElse(Maybe.Nope)
-    new ExpressionTypeCalculator(maybeInputType, maybeOutputType, srcType, dstType)
+    val tc =
+      new ExpressionTypeCalculator(
+        Delay('maybeInputType, this, maybeInputType),
+        Delay('maybeOutputType, this, maybeOutputType),
+        srcType,
+        dstType)
+    tc
   }
   def compileIdentity(srcType: NodeInfo.Kind): TypeCalculator = new IdentifyTypeCalculator(srcType)
 
diff --git a/daffodil-runtime1/src/test/scala/org/apache/daffodil/dpath/TestNodeInfo.scala b/daffodil-runtime1/src/test/scala/org/apache/daffodil/dpath/TestNodeInfo.scala
new file mode 100644
index 0000000..72fc73a
--- /dev/null
+++ b/daffodil-runtime1/src/test/scala/org/apache/daffodil/dpath/TestNodeInfo.scala
@@ -0,0 +1,30 @@
+/*
+ * 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.dpath
+
+import org.junit.Assert.assertTrue
+import org.junit.Test
+
+
+class TestNodeInfo {
+
+  @Test def test_nodeInfoCanBeConstructed(): Unit = {
+    assertTrue(NodeInfo.isXDerivedFromY("Byte", "Long"))
+  }
+
+}
diff --git a/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/AV.dfdl.xsd b/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/AV.dfdl.xsd
index b9d518e..d5fc706 100644
--- a/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/AV.dfdl.xsd
+++ b/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/AV.dfdl.xsd
@@ -44,7 +44,7 @@
         calendarCheckPolicy='strict'
         calendarLanguage='en' 
         escapeSchemeRef=''
-        encodingErrorPolicy="error"
+        encodingErrorPolicy="replace"
         dfdlx:parseUnparsePolicy="parseOnly" />
     </appinfo>
   </annotation>
diff --git a/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/multiple-diagnostics.tdml b/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/multiple-diagnostics.tdml
index 68c020e..0747797 100644
--- a/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/multiple-diagnostics.tdml
+++ b/daffodil-test-ibm1/src/test/resources/test-suite/tresys-contributed/multiple-diagnostics.tdml
@@ -115,17 +115,18 @@
          the properties as it has given up processing those constructs. -->
       <!-- <tdml:error>representation</tdml:error> -->
       
-      <!-- Don't get this type-related error anymore
       <tdml:error>immediate type</tdml:error>
       <tdml:error>named type</tdml:error>
       <tdml:error>not both</tdml:error>
-      -->
+
       <!-- Dont get invalidity error anymore. 
       <tdml:error>invalid</tdml:error>
       <tdml:error>dfdl:format</tdml:error>
       -->
+      <!-- Don't get this anymore - stops once the schema is invalid
       <tdml:error>ex:err2</tdml:error>
       <tdml:error>referenced</tdml:error>
+      -->
     </tdml:errors>
 
   </tdml:parserTestCase>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/inputTypeCalc_malformed.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/inputTypeCalc_malformed.tdml
deleted file mode 100644
index 4f7f801..0000000
--- a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/inputTypeCalc_malformed.tdml
+++ /dev/null
@@ -1,114 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  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.
--->
-
-<tdml:testSuite xmlns:ex="http://example.com" xmlns="http://example.com"
-  xmlns:tdml="http://www.ibm.com/xmlns/dfdl/testData" 
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/" 
-  xmlns:dfdlx="http://www.ogf.org/dfdl/dfdl-1.0/extensions"
-  xmlns:tns="http://example.com"
-  xmlns:xs="http://www.w3.org/2001/XMLSchema">
-
-  <tdml:defineSchema name="inputTypeCalc-Embedded.dfdl.xsd">
-
-    <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
-    <dfdl:format ref="ex:GeneralFormat" lengthKind="delimited"
-      lengthUnits="bytes" encoding="UTF-8" separator="" initiator=""
-      terminator="" occursCountKind="parsed" ignoreCase="no"
-      textNumberRep="standard" representation="text" />
-
-    <xs:element name="keysetValue_00" type="tns:keysetValue_01" />
-
-    <xs:element name="keysetValue_01">
-      <xs:complexType>
-        <xs:sequence>
-          <xs:element name="byte" type="tns:keysetValue_01" maxOccurs="1" dfdl:occursCountKind="parsed"/>
-        </xs:sequence>
-      </xs:complexType>
-    </xs:element>
-
-    <xs:simpleType name="keysetValue_01_repType" dfdl:lengthKind="explicit" dfdl:length="1">
-      <xs:restriction base="xs:unsignedInt" />
-    </xs:simpleType>
-
-    <xs:simpleType name="keysetValue_01" dfdlx:repType="tns:keysetValue_01_repType">
-      <xs:restriction base="xs:string">
-        <xs:enumeration value="zero" dfdlx:repValues="0" />
-        <xs:enumeration value="one" dfdlx:repValues="1" />
-        <xs:enumeration value="2-100" dfdlx:repValueRanges="2 100" />
-        <xs:enumeration value="101 103-110 115 120-125" dfdlx:repValues="101 115" dfdlx:repValueRanges="103 110 120 125"/>
-      </xs:restriction>
-    </xs:simpleType>
-
-  </tdml:defineSchema>
-
-  <tdml:parserTestCase name="InputTypeCalc_keysetValue_00"
-    root="keysetValue_00" model="inputTypeCalc-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc keysetValue transform">
-
-    <tdml:document>
-    <tdml:documentPart type="byte">
-    00
-    </tdml:documentPart>
-    </tdml:document>
-    <tdml:infoset>
-      <tdml:dfdlInfoset xmlns:xs="http://www.w3.org/2001/XMLSchema"
-        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-        <keysetValue_01>
-          <byte>zero</byte>
-        </keysetValue_01>
-      </tdml:dfdlInfoset>
-    </tdml:infoset>
-  </tdml:parserTestCase>
-
-<!--
-
-  <tdml:parserTestCase name="InputTypeCalc_keysetValue_01"
-    root="keysetValue_01" model="inputTypeCalc-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc keysetValue transform">
-
-    <tdml:document>
-    <tdml:documentPart type="byte">
-    00
-    01 
-    02 20 64 
-    65 67 68 6E 73 78 7A 7D 
-    </tdml:documentPart>
-    </tdml:document>
-    <tdml:infoset>
-      <tdml:dfdlInfoset xmlns:xs="http://www.w3.org/2001/XMLSchema"
-        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-        <keysetValue_01>
-          <byte>zero</byte>
-          <byte>one</byte>
-          <byte>2-100</byte>
-          <byte>2-100</byte>
-          <byte>2-100</byte>
-          <byte>101 103-110 115 120-125</byte>
-          <byte>101 103-110 115 120-125</byte>
-          <byte>101 103-110 115 120-125</byte>
-          <byte>101 103-110 115 120-125</byte>
-          <byte>101 103-110 115 120-125</byte>
-          <byte>101 103-110 115 120-125</byte>
-          <byte>101 103-110 115 120-125</byte>
-          <byte>101 103-110 115 120-125</byte>
-        </keysetValue_01>
-      </tdml:dfdlInfoset>
-    </tdml:infoset>
-  </tdml:parserTestCase>
-  -->
-
-</tdml:testSuite>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/typeCalcFunctionErrors.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/typeCalcFunctionErrors.tdml
index d292bde..bfebb7f 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/typeCalcFunctionErrors.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/typeCalcFunctionErrors.tdml
@@ -53,61 +53,6 @@
     <xs:element name="typeCalcDispatch_typeError_01" type="xs:int" dfdl:inputValueCalc="{ dfdlx:inputTypeCalc('tns:intToString', 0) }" />
     <xs:element name="typeCalcDispatch_typeError_02" type="xs:int" dfdl:inputValueCalc="{ dfdlx:outputTypeCalc('tns:stringToInt', 0) }" />
 
-    <xs:element name="typeCalcDispatch_typeError_03" dfdlx:parseUnparsePolicy="unparseOnly">
-      <xs:complexType>
-        <xs:sequence>
-          <xs:element name="raw" dfdl:outputValueCalc="{ dfdlx:outputTypeCalcNextSibling() }" type="tns:uint8" dfdlx:parseUnparsePolicy="unparseOnly"/>
-          <xs:element name="stringToInt" type="stringToInt" dfdlx:parseUnparsePolicy="unparseOnly" dfdl:inputValueCalc="{ 0 }"/>
-        </xs:sequence>
-      </xs:complexType>
-    </xs:element>
-
-    <xs:element name="typeCalcDispatch_typeError_04" dfdlx:parseUnparsePolicy="unparseOnly">
-      <xs:complexType>
-        <xs:sequence>
-          <xs:element name="raw" dfdl:outputValueCalc="{ dfdlx:outputTypeCalcNextSibling() }" type="tns:uint8" dfdlx:parseUnparsePolicy="unparseOnly"/>
-          <xs:element name="stringToInt" type="stringToInt" dfdlx:parseUnparsePolicy="unparseOnly" dfdl:inputValueCalc="{ 0 }"/>
-        </xs:sequence>
-      </xs:complexType>
-    </xs:element>
-
-    <xs:element name="typeCalcDispatch_typeError_05">
-      <xs:simpleType dfdlx:repType="tns:string8" dfdlx:inputTypeCalc="{ dfdlx:repTypeValue() }">
-        <xs:restriction base="xs:int"/>
-      </xs:simpleType>
-    </xs:element>
-
-    <xs:element name="typeCalcDispatch_typeError_06">
-      <xs:simpleType dfdlx:repType="tns:string8" dfdlx:inputTypeCalc="{ dfdlx:repTypeValue() }">
-        <xs:restriction base="xs:int"/>
-      </xs:simpleType>
-    </xs:element>
-
-    <xs:element name="typeCalcDispatch_typeError_07" dfdlx:parseUnparsePolicy="unparseOnly" >
-      <xs:simpleType dfdlx:repType="tns:uint8" dfdlx:outputTypeCalc="{ dfdlx:logicalTypeValue() }">
-        <xs:restriction base="xs:string"/>
-      </xs:simpleType>
-    </xs:element>
-
-    <xs:element name="typeCalcDispatch_typeError_08" dfdlx:parseUnparsePolicy="unparseOnly">
-      <xs:simpleType dfdlx:repType="tns:uint8" dfdlx:outputTypeCalc="{ dfdlx:logicalTypeValue() }">
-        <xs:restriction base="xs:string"/>
-      </xs:simpleType>
-    </xs:element>
-
-    <xs:element name="repTypeValue_bad_context_01" type="xs:string" dfdl:inputValueCalc="{ dfdlx:repTypeValue() }"/>
-    <xs:element name="repTypeValue_bad_context_02" dfdlx:parseUnparsePolicy="unparseOnly">
-      <xs:simpleType dfdlx:repType="tns:uint8" dfdlx:outputTypeCalc="{ dfdlx:repTypeValue() }" dfdlx:inputTypeCalc="{ 0 }">
-        <xs:restriction base="xs:int"/>
-      </xs:simpleType>
-    </xs:element>
-    <xs:element name="logicalTypeValue_bad_context_01" type="xs:string" dfdl:inputValueCalc="{ dfdlx:logicalTypeValue() }"/>
-    <xs:element name="logicalTypeValue_bad_context_02">
-      <xs:simpleType dfdlx:repType="tns:uint8" dfdlx:inputTypeCalc="{ dfdlx:logicalTypeValue() }" dfdlx:outputTypeCalc="{ 0 }">
-        <xs:restriction base="xs:int"/>
-      </xs:simpleType>
-    </xs:element>
-
     <xs:element name="nonexistant_reptype_01">
       <xs:simpleType dfdlx:repType="tns:nonExistant" dfdlx:inputTypeCalc="{ 0 }">
         <xs:restriction base="xs:int"/>
@@ -126,229 +71,8 @@
 
     <xs:element name="nonexistantInputTypeCalc_01" type="xs:int" dfdl:inputValueCalc="{dfdlx:inputTypeCalc('tns:outputConversionOnly', 7)}"/>
 
-    <xs:element name="nextSibling_01" dfdlx:parseUnparsePolicy="unparseOnly" >
-      <xs:complexType>
-        <xs:sequence>
-          <xs:element name="raw" type="xs:int" dfdl:outputValueCalc="{ dfdlx:outputTypeCalcNextSibling() }" dfdlx:parseUnparsePolicy="unparseOnly" />
-          <xs:choice>
-            <xs:element name="a" type="tns:intToString" dfdlx:parseUnparsePolicy="unparseOnly" />
-            <xs:element name="b" type="tns:stringToInt" dfdlx:parseUnparsePolicy="unparseOnly" />
-          </xs:choice>
-        </xs:sequence>
-      </xs:complexType>
-    </xs:element>
-
-    <xs:element name="nextSibling_02" dfdlx:parseUnparsePolicy="unparseOnly" >
-      <xs:complexType>
-        <xs:sequence>
-          <xs:element name="raw" type="xs:int" dfdl:outputValueCalc="{ dfdlx:outputTypeCalcNextSibling() }" dfdlx:parseUnparsePolicy="unparseOnly" />
-          <xs:choice>
-            <xs:element name="a" type="tns:intToString" dfdlx:parseUnparsePolicy="unparseOnly" />
-            <xs:element name="b" type="tns:uint8" dfdlx:parseUnparsePolicy="unparseOnly" />
-          </xs:choice>
-        </xs:sequence>
-      </xs:complexType>
-    </xs:element>
-
-    <xs:element name="nextSibling_03" dfdlx:parseUnparsePolicy="unparseOnly" >
-      <xs:complexType>
-        <xs:sequence>
-          <xs:element name="raw" type="xs:int" dfdl:outputValueCalc="{ dfdlx:outputTypeCalcNextSibling() }" dfdlx:parseUnparsePolicy="unparseOnly" />
-          <xs:element name="b" type="tns:uint8" dfdlx:parseUnparsePolicy="unparseOnly" />
-        </xs:sequence>
-      </xs:complexType>
-    </xs:element>
-
-    <xs:element name="nextSibling_04" dfdlx:parseUnparsePolicy="unparseOnly" >
-      <xs:complexType>
-        <xs:sequence>
-          <xs:element name="raw" type="xs:int" dfdl:outputValueCalc="{ dfdlx:outputTypeCalcNextSibling() }" dfdlx:parseUnparsePolicy="unparseOnly" />
-        </xs:sequence>
-      </xs:complexType>
-    </xs:element>
-
   </tdml:defineSchema>
 
-  <tdml:parserTestCase name="typeCalcDispatch_typeError_01"
-    root="typeCalcDispatch_typeError_01" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
-    <tdml:document>
-    <tdml:documentPart type="byte">
-    </tdml:documentPart>
-    </tdml:document>
-    <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>Cannot convert 'a' from String type to Long</tdml:error>
-    </tdml:errors>
-    <tdml:warnings>
-      <tdml:warning>Schema Definition Warning</tdml:warning>
-      <tdml:warning>result type (String) should be manually cast to the expected type (Int)</tdml:warning>
-    </tdml:warnings>
-  </tdml:parserTestCase>
-
-  <tdml:parserTestCase name="typeCalcDispatch_typeError_02"
-    root="typeCalcDispatch_typeError_02" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
-    <tdml:document>
-    <tdml:documentPart type="byte">
-    </tdml:documentPart>
-    </tdml:document>
-    <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>Cannot convert 'a' from String type to Long</tdml:error>
-    </tdml:errors>
-    <tdml:warnings>
-      <tdml:warning>Schema Definition Warning</tdml:warning>
-      <tdml:warning>result type (String) should be manually cast to the expected type (Int)</tdml:warning>
-    </tdml:warnings>
-  </tdml:parserTestCase>
-
-  <tdml:unparserTestCase name="typeCalcDispatch_typeError_03"
-    root="typeCalcDispatch_typeError_03" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
-    <tdml:infoset>
-      <tdml:dfdlInfoset>
-        <typeCalcDispatch_typeError_03>
-          <stringToInt>0</stringToInt>
-        </typeCalcDispatch_typeError_03>
-      </tdml:dfdlInfoset>
-    </tdml:infoset>
-    <tdml:errors>
-      <tdml:error>Unparse Error</tdml:error>
-      <tdml:error>Cannot convert</tdml:error>
-      <tdml:error>from String type to Long</tdml:error>
-    </tdml:errors>
-    <tdml:warnings>
-      <tdml:warning>Schema Definition Warning</tdml:warning>
-      <tdml:warning>result type (String)</tdml:warning>
-      <tdml:warning>expected type (Int)</tdml:warning>
-    </tdml:warnings>
-  </tdml:unparserTestCase>
-
-  <tdml:unparserTestCase name="typeCalcDispatch_typeError_04"
-    root="typeCalcDispatch_typeError_04" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
-    <tdml:infoset>
-      <tdml:dfdlInfoset>
-        <typeCalcDispatch_typeError_04>
-          <stringToInt>0</stringToInt>
-        </typeCalcDispatch_typeError_04>
-      </tdml:dfdlInfoset>
-    </tdml:infoset>
-    <tdml:errors>
-      <tdml:error>Unparse Error</tdml:error>
-    </tdml:errors>
-    <tdml:warnings>
-      <tdml:warning>Schema Definition Warning</tdml:warning>
-      <tdml:warning>result type (String) should be manually cast to the expected type (Int)</tdml:warning>
-    </tdml:warnings>
-  </tdml:unparserTestCase>
-
-  <tdml:parserTestCase name="typeCalcDispatch_typeError_05"
-    root="typeCalcDispatch_typeError_05" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
-    <tdml:document>
-    <tdml:documentPart type="text">a</tdml:documentPart>
-    </tdml:document>
-    <tdml:errors>
-      <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Cannot convert</tdml:error>
-      <tdml:error>from String type to Long</tdml:error>
-    </tdml:errors>
-  </tdml:parserTestCase>
-
-  <tdml:parserTestCase name="typeCalcDispatch_typeError_06"
-    root="typeCalcDispatch_typeError_06" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
-    <tdml:document>
-    <tdml:documentPart type="text">a</tdml:documentPart>
-    </tdml:document>
-    <tdml:errors>
-      <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Cannot convert</tdml:error>
-      <tdml:error>From String type to Long</tdml:error>
-    </tdml:errors>
-    <tdml:warnings>
-      <tdml:warning>Schema Definition Warning</tdml:warning>
-      <tdml:warning>result type (String)</tdml:warning>
-      <tdml:warning>manually cast</tdml:warning>
-      <tdml:warning>Expected type (Int)</tdml:warning>
-    </tdml:warnings>
-  </tdml:parserTestCase>
-
-  <tdml:unparserTestCase name="typeCalcDispatch_typeError_07"
-    root="typeCalcDispatch_typeError_07" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
-    <tdml:infoset>
-      <tdml:dfdlInfoset>
-        <typeCalcDispatch_typeError_07>a</typeCalcDispatch_typeError_07>
-      </tdml:dfdlInfoset>
-    </tdml:infoset>
-    <tdml:errors>
-      <tdml:error>Unparse Error</tdml:error>
-      <tdml:error>Cannot convert</tdml:error>
-      <tdml:error>From String type to Long</tdml:error>
-    </tdml:errors>
-    <tdml:warnings>
-      <tdml:warning>Schema Definition Warning</tdml:warning>
-      <tdml:warning>result type (String)</tdml:warning>
-      <tdml:warning>manually cast</tdml:warning>
-      <tdml:warning>Expected type (Int)</tdml:warning>
-    </tdml:warnings>
-  </tdml:unparserTestCase>
-
-  <tdml:unparserTestCase name="typeCalcDispatch_typeError_08"
-    root="typeCalcDispatch_typeError_08" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
-    <tdml:infoset>
-      <tdml:dfdlInfoset>
-        <typeCalcDispatch_typeError_08>a</typeCalcDispatch_typeError_08>
-      </tdml:dfdlInfoset>
-    </tdml:infoset>
-    <tdml:errors>
-      <tdml:error>Unparse Error</tdml:error>
-      <tdml:error>Cannot convert 'a' from String type to Long</tdml:error>
-    </tdml:errors>
-  </tdml:unparserTestCase>
-
-  <tdml:parserTestCase name="repTypeValue_bad_context_01"
-    root="repTypeValue_bad_context_01" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
-    <tdml:document>
-    <tdml:documentPart type="byte"></tdml:documentPart>
-    </tdml:document>
-    <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>dfdlx:repTypeValue() can only be defined on a simple type</tdml:error>
-    </tdml:errors>
-  </tdml:parserTestCase>
-
-  <tdml:unparserTestCase name="repTypeValue_bad_context_02"
-    root="repTypeValue_bad_context_02" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
-    <tdml:infoset>
-      <tdml:dfdlInfoset>
-        <repTypeValue_bad_context_02>0</repTypeValue_bad_context_02>
-      </tdml:dfdlInfoset>
-    </tdml:infoset>
-    <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>dfdlx:repTypeValue() may only be called from within dfdlx:inputTypeCalc</tdml:error>
-    </tdml:errors>
-  </tdml:unparserTestCase>
-
-  <tdml:parserTestCase name="logicalTypeValue_bad_context_01"
-    root="logicalTypeValue_bad_context_01" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
-    <tdml:document>
-    <tdml:documentPart type="byte"></tdml:documentPart>
-    </tdml:document>
-    <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>dfdlx:logicalTypeValue() can only be defined on a simple type</tdml:error>
-    </tdml:errors>
-  </tdml:parserTestCase>
-
-  <tdml:parserTestCase name="logicalTypeValue_bad_context_02"
-    root="logicalTypeValue_bad_context_02" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
-    <tdml:document>
-    <tdml:documentPart type="byte">00</tdml:documentPart>
-    </tdml:document>
-    <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>dfdlx:logicalTypeValue() may only be called from within dfdlx:outputTypeCalc</tdml:error>
-    </tdml:errors>
-  </tdml:parserTestCase>
-
   <tdml:parserTestCase name="nonexistant_reptype_01"
     root="nonexistant_reptype_01" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
     <tdml:document>
@@ -435,76 +159,4 @@
     </tdml:errors>
   </tdml:parserTestCase>
 
-  <tdml:unparserTestCase name="nextSibling_01"
-    root="nextSibling_01" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
-    <tdml:infoset>
-      <tdml:dfdlInfoset>
-        <nextSibling_01>
-          <raw>0</raw>
-          <a>a</a>
-        </nextSibling_01>
-      </tdml:dfdlInfoset>
-    </tdml:infoset>
-    <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>dfdlx:outputTypeCalcNextSibling</tdml:error>
-      <tdml:error>all the possible next siblings have the same repType</tdml:error>
-      <tdml:error>potential next siblings ex:a and ex:b</tdml:error>
-      <tdml:error>have repTypes Int and String</tdml:error>
-    </tdml:errors>
-  </tdml:unparserTestCase>
-
-  <tdml:unparserTestCase name="nextSibling_02"
-    root="nextSibling_02" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
-    <tdml:infoset>
-      <tdml:dfdlInfoset>
-        <nextSibling_02>
-          <raw>0</raw>
-          <a>a</a>
-        </nextSibling_02>
-      </tdml:dfdlInfoset>
-    </tdml:infoset>
-    <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>dfdlx:outputTypeCalcNextSibling</tdml:error>
-      <tdml:error>potential next sibling</tdml:error>
-      <tdml:error>ex:b</tdml:error>
-      <tdml:error>does not define a type calculator</tdml:error>
-    </tdml:errors>
-  </tdml:unparserTestCase>
-
-  <tdml:unparserTestCase name="nextSibling_03"
-    root="nextSibling_03" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
-    <tdml:infoset>
-      <tdml:dfdlInfoset>
-        <nextSibling_03>
-          <raw>0</raw>
-          <b>0</b>
-        </nextSibling_03>
-      </tdml:dfdlInfoset>
-    </tdml:infoset>
-    <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>dfdlx:outputTypeCalcNextSibling</tdml:error>
-      <tdml:error>potential next sibling</tdml:error>
-      <tdml:error>ex:b</tdml:error>
-      <tdml:error>does not define a type calculator</tdml:error>
-    </tdml:errors>
-  </tdml:unparserTestCase>
-
-  <tdml:unparserTestCase name="nextSibling_04"
-    root="nextSibling_04" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
-    <tdml:infoset>
-      <tdml:dfdlInfoset>
-        <nextSibling_04>
-          <raw>0</raw>
-        </nextSibling_04>
-      </tdml:dfdlInfoset>
-    </tdml:infoset>
-    <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>dfdlx:outputTypeCalcNextSibling() called where no suitable next sibling exists</tdml:error>
-    </tdml:errors>
-  </tdml:unparserTestCase>
-
 </tdml:testSuite>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/typeCalcFunctions.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/typeCalcFunctions.tdml
index 849ea73..9fca633 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/typeCalcFunctions.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/type_calc/typeCalcFunctions.tdml
@@ -51,22 +51,6 @@
     <xs:restriction base="xs:int"/>
   </xs:simpleType>
 
-  <xs:simpleType name="AbstractIntToMulitiply2" dfdlx:repType="xs:int" dfdlx:inputTypeCalc="{ dfdlx:repTypeValue() * 2 }">
-    <xs:restriction base="xs:int"/>
-  </xs:simpleType>
-
-  <xs:simpleType name="AbstractStringToPrefixedString" dfdlx:repType="xs:string" dfdlx:inputTypeCalc="{ fn:concat('x',dfdlx:repTypeValue()) }">
-    <xs:restriction base="xs:string"/>
-  </xs:simpleType>
-
-  <xs:simpleType name="AbstractMulitiply2FromInt" dfdlx:repType="xs:int" dfdlx:outputTypeCalc="{ dfdlx:logicalTypeValue() * 2 }">
-    <xs:restriction base="xs:int"/>
-  </xs:simpleType>
-
-  <xs:simpleType name="AbstractPrefixedStringFromInt" dfdlx:repType="xs:string" dfdlx:outputTypeCalc="{ fn:concat('x',xs:string(dfdlx:logicalTypeValue())) }">
-    <xs:restriction base="xs:int"/>
-  </xs:simpleType>
-
   <xs:simpleType name="AbstractIntToStringByKeyset" dfdlx:repType="xs:int">
     <xs:restriction base="xs:string">
       <xs:enumeration value="one" dfdlx:repValues="1"/>
@@ -85,28 +69,6 @@
     </xs:complexType>
   </xs:element>
   <xs:element name="outputTypeCalcString_01" type="xs:string" dfdl:inputValueCalc="{ dfdlx:outputTypeCalc('tns:AbstractXYZFromInt', 7) }" />
-  <xs:element name="repTypeValueInt_01" type="xs:int" dfdl:inputValueCalc="{ dfdlx:inputTypeCalc('tns:AbstractIntToMulitiply2', 7) }" />
-  <xs:element name="repTypeValueString_01" type="xs:string" dfdl:inputValueCalc="{ dfdlx:inputTypeCalc('tns:AbstractStringToPrefixedString', 'y') }" />
-  <xs:element name="logicalTypeValueInt_01" dfdlx:parseUnparsePolicy="parseOnly" type="xs:int" 
-    dfdl:inputValueCalc="{ dfdlx:outputTypeCalc('tns:AbstractMulitiply2FromInt', 7) }" />
-  <xs:element name="logicalTypeValueString_01" dfdlx:parseUnparsePolicy="parseOnly" type="xs:string" 
-    dfdl:inputValueCalc="{ dfdlx:outputTypeCalc('tns:AbstractPrefixedStringFromInt', 7) }" />
-  <xs:element name="outputTypeCalcNextSiblingInt_01">
-    <xs:complexType>
-      <xs:sequence>
-        <xs:element name="raw" type="tns:uint8" dfdl:outputValueCalc="{ dfdlx:outputTypeCalcNextSibling() }"/>
-        <xs:element name="logic" type="tns:AbstractMulitiply2FromInt" dfdl:inputValueCalc="{ 0 }"/>
-      </xs:sequence>
-    </xs:complexType>
-  </xs:element>
-  <xs:element name="outputTypeCalcNextSiblingString_01">
-    <xs:complexType>
-      <xs:sequence>
-        <xs:element name="raw" type="xs:string" dfdl:outputValueCalc="{ dfdlx:outputTypeCalcNextSibling() }"/>
-        <xs:element name="logic" type="tns:AbstractXYZFromInt" dfdl:inputValueCalc="{ 0 }"/>
-      </xs:sequence>
-    </xs:complexType>
-  </xs:element>
 
   <xs:element name="abstractIntToStringByKeyset_01" type="xs:string" dfdl:inputValueCalc="{dfdlx:inputTypeCalc('AbstractIntToStringByKeyset',0)}"/>
 
@@ -205,100 +167,6 @@
     </tdml:infoset>
   </tdml:parserTestCase>
 
-  <tdml:parserTestCase name="repTypeValueInt_01"
-    root="repTypeValueInt_01" model="inputTypeCalc-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc keysetValue transform">
-
-    <tdml:document>
-    <tdml:documentPart type="byte">
-    </tdml:documentPart>
-    </tdml:document>
-    <tdml:infoset>
-      <tdml:dfdlInfoset xmlns:xs="http://www.w3.org/2001/XMLSchema"
-        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-        <repTypeValueInt_01>14</repTypeValueInt_01>
-      </tdml:dfdlInfoset>
-    </tdml:infoset>
-  </tdml:parserTestCase>
-
-  <tdml:parserTestCase name="repTypeValueString_01"
-    root="repTypeValueString_01" model="inputTypeCalc-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc keysetValue transform">
-
-    <tdml:document>
-    <tdml:documentPart type="byte">
-    </tdml:documentPart>
-    </tdml:document>
-    <tdml:infoset>
-      <tdml:dfdlInfoset xmlns:xs="http://www.w3.org/2001/XMLSchema"
-        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-        <repTypeValueString_01>xy</repTypeValueString_01>
-      </tdml:dfdlInfoset>
-    </tdml:infoset>
-  </tdml:parserTestCase>
-
-  <tdml:parserTestCase name="logicalTypeValueInt_01"
-    root="logicalTypeValueInt_01" model="inputTypeCalc-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc keysetValue transform">
-
-    <tdml:document>
-    <tdml:documentPart type="byte">
-    </tdml:documentPart>
-    </tdml:document>
-    <tdml:infoset>
-      <tdml:dfdlInfoset xmlns:xs="http://www.w3.org/2001/XMLSchema"
-        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-        <logicalTypeValueInt_01>14</logicalTypeValueInt_01>
-      </tdml:dfdlInfoset>
-    </tdml:infoset>
-  </tdml:parserTestCase>
-
-  <tdml:parserTestCase name="logicalTypeValueString_01"
-    root="logicalTypeValueString_01" model="inputTypeCalc-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc keysetValue transform">
-
-    <tdml:document>
-    <tdml:documentPart type="byte">
-    </tdml:documentPart>
-    </tdml:document>
-    <tdml:infoset>
-      <tdml:dfdlInfoset xmlns:xs="http://www.w3.org/2001/XMLSchema"
-        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-        <logicalTypeValueString_01>x7</logicalTypeValueString_01>
-      </tdml:dfdlInfoset>
-    </tdml:infoset>
-  </tdml:parserTestCase>
-
-  <tdml:unparserTestCase name="outputTypeCalcNextSiblingInt_01"
-    root="outputTypeCalcNextSiblingInt_01" model="inputTypeCalc-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc keysetValue transform">
-
-    <tdml:document>
-    <tdml:documentPart type="byte">
-    0E
-    </tdml:documentPart>
-    </tdml:document>
-    <tdml:infoset>
-      <tdml:dfdlInfoset xmlns:xs="http://www.w3.org/2001/XMLSchema"
-        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-        <outputTypeCalcNextSiblingInt_01>
-          <logic>7</logic>
-        </outputTypeCalcNextSiblingInt_01>
-      </tdml:dfdlInfoset>
-    </tdml:infoset>
-  </tdml:unparserTestCase>
-
-  <tdml:unparserTestCase name="outputTypeCalcNextSiblingString_01"
-    root="outputTypeCalcNextSiblingString_01" model="inputTypeCalc-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc keysetValue transform">
-
-    <tdml:document>
-      <tdml:documentPart type="text">xyz</tdml:documentPart>
-    </tdml:document>
-    <tdml:infoset>
-      <tdml:dfdlInfoset xmlns:xs="http://www.w3.org/2001/XMLSchema"
-        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-        <outputTypeCalcNextSiblingString_01>
-          <logic>7</logic>
-        </outputTypeCalcNextSiblingString_01>
-      </tdml:dfdlInfoset>
-    </tdml:infoset>
-  </tdml:unparserTestCase>
-
   <tdml:parserTestCase name="abstractIntToStringByKeyset_01"
     root="abstractIntToStringByKeyset_01" model="inputTypeCalc-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc keysetValue transform">
 
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/hasDocType-import.dfdl.xsd b/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/hasDocType-import.dfdl.xsd
index 71f6521..474a2e1 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/hasDocType-import.dfdl.xsd
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/hasDocType-import.dfdl.xsd
@@ -25,7 +25,8 @@
   ]>
 <xs:schema
   xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/"
-  xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  xmlns:xs="http://www.w3.org/2001/XMLSchema"
+  targetNamespace="http://example.com">
     
   <xs:element name="imported" type="xs:string"/>
 </xs:schema>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/hasDocType-via-import.dfdl.xsd b/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/hasDocType-via-import.dfdl.xsd
index 1e69a80..02d0f3b 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/hasDocType-via-import.dfdl.xsd
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section00/general/hasDocType-via-import.dfdl.xsd
@@ -20,7 +20,8 @@
   -->
 <xs:schema
   xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/"
-  xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  xmlns:xs="http://www.w3.org/2001/XMLSchema"
+  targetNamespace="http://example.com">
 
   <xs:import schemaLocation="hasDocType-import.dfdl.xsd"/>
     
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/multi_A_05_nons.dfdl.xsd b/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/multi_A_05_nons.dfdl.xsd
index c9f3815..a9b056e 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/multi_A_05_nons.dfdl.xsd
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/multi_A_05_nons.dfdl.xsd
@@ -28,5 +28,8 @@
       </dfdl:defineFormat>
     </xs:appinfo>
   </xs:annotation>
- 
+
+  <xs:element name="vagueElem" type="xs:int"/>
+
+
 </xs:schema>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/multi_C_05_nons.dfdl.xsd b/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/multi_C_05_nons.dfdl.xsd
index 257228c..d11d005 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/multi_C_05_nons.dfdl.xsd
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/multi_C_05_nons.dfdl.xsd
@@ -43,8 +43,6 @@
         <xs:pattern value="[0-5]{3}" />
       </xs:restriction>
     </xs:simpleType>
-  </xs:element> 
- 
-  <xs:element name="vagueElem" type="xs:int"/>
-  
+  </xs:element>
+
 </xs:schema>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/multi_base_05_nons.dfdl.xsd b/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/multi_base_05_nons.dfdl.xsd
index cc5ee02..709f74a 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/multi_base_05_nons.dfdl.xsd
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/multi_base_05_nons.dfdl.xsd
@@ -29,7 +29,6 @@
     </xs:appinfo>
   </xs:annotation>
    
-  <xs:include schemaLocation="org/apache/daffodil/section06/namespaces/multi_A_05_nons.dfdl.xsd"/>
   <xs:include schemaLocation="org/apache/daffodil/section06/namespaces/multi_B_05_nons.dfdl.xsd"/>
   
   <xs:element name="baseSeq">
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/multi_base_05_nons_with_A.dfdl.xsd b/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/multi_base_05_nons_with_A.dfdl.xsd
new file mode 100644
index 0000000..d378962
--- /dev/null
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/multi_base_05_nons_with_A.dfdl.xsd
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/">
+   
+  <xs:include schemaLocation="org/apache/daffodil/section06/namespaces/multi_A_05_nons.dfdl.xsd"/>
+  <xs:include schemaLocation="org/apache/daffodil/section06/namespaces/multi_base_05_nons.dfdl.xsd"/>
+
+</xs:schema>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/multi_temp.dfdl.xsd b/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/multi_temp.dfdl.xsd
index 52702ae..71fc545 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/multi_temp.dfdl.xsd
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/multi_temp.dfdl.xsd
@@ -30,7 +30,7 @@
   <xs:element name="baseSeq2">
     <xs:complexType>
       <xs:sequence dfdl:separator=".">
-        <xs:element dfdl:ref="pipes" maxOccurs="10" type="xs:int"/>
+        <xs:element dfdl:ref="pipes" name="foo" maxOccurs="10" type="xs:int"/>
       </xs:sequence>
     </xs:complexType>
   </xs:element>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/namespaceRules2.dfdl.xsd b/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/namespaceRules2.dfdl.xsd
index 25689cd..1239d73 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/namespaceRules2.dfdl.xsd
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/namespaceRules2.dfdl.xsd
@@ -16,13 +16,16 @@
   limitations under the License.
 -->
 
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/" xmlns:xmlns="http://example.com" targetNamespace="http://example.com">
-      
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+           xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/"
+           xmlns:xmlns="http://foo.com"
+           xmlns:tns="http://example.com"
+           targetNamespace="http://example.com">
+
+  <xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
   <xs:annotation>
     <xs:appinfo source="http://www.ogf.org/dfdl/">
-      <dfdl:format separator="" alignment="1" alignmentUnits="bits" lengthUnits="bytes"
-        trailingSkip="0" initiator="" terminator="" leadingSkip='0' textTrimKind="none" initiatedContent="no"
-        ignoreCase="no" representation="text" textNumberRep="standard" encoding="ASCII"/>
+      <dfdl:format ref="tns:GeneralFormat"/>
     </xs:appinfo>
   </xs:annotation>
   
@@ -30,6 +33,6 @@
       <xs:restriction base="xs:int"/>
     </xs:simpleType>
 
-    <xs:element name="one" type="xmlns:simTyp"/>
+    <xs:element name="one" type="tns:simTyp"/>
   
 </xs:schema>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/namespaces.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/namespaces.tdml
index 8cf64e4..b65ed3a 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/namespaces.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section06/namespaces/namespaces.tdml
@@ -905,7 +905,7 @@
   -->
 
   <tdml:parserTestCase name="no_namespace_02" root="vagueBase"
-    model="multi_base_05_nons.dfdl.xsd" description="import a schema - DFDL-6-007R">
+    model="multi_base_05_nons_with_A.dfdl.xsd" description="import a schema - DFDL-6-007R">
     <tdml:document><![CDATA[333]]></tdml:document>
     <tdml:errors>
       <tdml:error>Schema Definition Error</tdml:error>
@@ -923,11 +923,12 @@
   -->
 
   <tdml:parserTestCase name="no_namespace_03" root="baseSeq2"
-    model="multi_base_05_nons.dfdl.xsd" description="import a schema - DFDL-6-007R">
+    model="multi_base_05_nons_with_A.dfdl.xsd" description="import a schema - DFDL-6-007R">
     <tdml:document><![CDATA[||333|||.||343|||]]></tdml:document>
     <tdml:errors>
       <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>More than one definition for name: pipes</tdml:error>
+      <tdml:error>More than one definition for</tdml:error>
+      <tdml:error>pipes</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -1738,7 +1739,11 @@
     <tdml:document><![CDATA[f:....53....(e)|f:..41..(e)]]></tdml:document>
     <tdml:errors>
       <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>Attribute 'textStringJustification' is not allowed to appear in element 'xs:element'.</tdml:error>
+      <tdml:error>Attribute 'textStringJustification'</tdml:error>
+      <!-- some changes in messages happen when the specific validator changes -->
+      <!-- Calling the Xerces schema validator, XSD parser, and just parsing
+          XML with validation on, create similar, but slightly different messages -->
+      <tdml:error>appear in element</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/HiddenSequences.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/HiddenSequences.tdml
index 6d801b9..30e41df 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/HiddenSequences.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/HiddenSequences.tdml
@@ -264,7 +264,7 @@
   </tdml:unparserTestCase>
 
   <tdml:unparserTestCase name="invalidGroupDefWithHiddenSequenceModelGroup" root="e9"
-    model="SequencesWithHiddenRefs.dfdl.xsd"
+    model="SequencesWithHiddenRefsInvalid.dfdl.xsd"
     description="a group definition is used where the model group is a hidden group ref">
     <tdml:infoset>
       <tdml:dfdlInfoset>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequencesWithHiddenRefs.dfdl.xsd b/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequencesWithHiddenRefs.dfdl.xsd
index 3b43fd3..b9f4ff5 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequencesWithHiddenRefs.dfdl.xsd
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequencesWithHiddenRefs.dfdl.xsd
@@ -124,9 +124,6 @@
       <xs:sequence dfdl:hiddenGroupRef="ex:s4" />
     </xs:sequence>
   </xs:group>
-  <xs:group name="s6">
-    <xs:sequence dfdl:hiddenGroupRef="ex:s4" />
-  </xs:group>
   <xs:element name="e7" dfdl:lengthKind="delimited">
     <xs:complexType>
       <xs:sequence dfdl:separator=",">
@@ -142,12 +139,5 @@
       </xs:sequence>
     </xs:complexType>
   </xs:element>
-  <xs:element name="e9" dfdl:lengthKind="delimited">
-    <xs:complexType>
-      <xs:sequence dfdl:separator=",">
-        <xs:sequence dfdl:hiddenGroupRef="ex:s6" />
-        <xs:element name="g" type="xs:int"/>
-      </xs:sequence>
-    </xs:complexType>
-  </xs:element>
+
 </xs:schema>
\ No newline at end of file
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequencesWithHiddenRefsInvalid.dfdl.xsd b/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequencesWithHiddenRefsInvalid.dfdl.xsd
new file mode 100644
index 0000000..01673f3
--- /dev/null
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequencesWithHiddenRefsInvalid.dfdl.xsd
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+  xmlns:fn="http://www.w3.org/2005/xpath-functions"
+  xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/" xmlns:ex="http://example.com"
+  targetNamespace="http://example.com" elementFormDefault="unqualified">
+  <xs:include
+    schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd" />
+
+  <xs:annotation>
+    <xs:appinfo source="http://www.ogf.org/dfdl/">
+      <dfdl:format ref="ex:GeneralFormat" lengthKind="delimited" />
+    </xs:appinfo>
+  </xs:annotation>
+
+  <xs:group name="s4">
+    <xs:sequence>
+      <xs:element name="f" type="xs:int" dfdl:outputValueCalc="{ 42 }"/>
+    </xs:sequence>
+  </xs:group>
+
+  <xs:group name="s6">
+    <!-- invalid. Must nest within another sequence -->
+    <xs:sequence dfdl:hiddenGroupRef="ex:s4" />
+  </xs:group>
+
+  <xs:element name="e9" dfdl:lengthKind="delimited">
+    <xs:complexType>
+      <xs:sequence dfdl:separator=",">
+        <xs:sequence dfdl:hiddenGroupRef="ex:s6" />
+        <xs:element name="g" type="xs:int"/>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+</xs:schema>
\ No newline at end of file
diff --git a/daffodil-test/src/test/scala/org/apache/daffodil/extensions/TestInputTypeValueCalc.scala b/daffodil-test/src/test/scala/org/apache/daffodil/extensions/TestInputTypeValueCalc.scala
index 85ffc6c..b9d5991 100644
--- a/daffodil-test/src/test/scala/org/apache/daffodil/extensions/TestInputTypeValueCalc.scala
+++ b/daffodil-test/src/test/scala/org/apache/daffodil/extensions/TestInputTypeValueCalc.scala
@@ -72,31 +72,10 @@
   @Test def test_inputTypeCalcString_01(): Unit = { fnRunner.runOneTest("inputTypeCalcString_01") }
   @Test def test_outputTypeCalcInt_01(): Unit = { fnRunner.runOneTest("outputTypeCalcInt_01") }
   @Test def test_outputTypeCalcString_01(): Unit = { fnRunner.runOneTest("outputTypeCalcString_01") }
-  @Test def test_repTypeValueInt_01(): Unit = { fnRunner.runOneTest("repTypeValueInt_01") }
-  @Test def test_logicalTypeValueInt_01(): Unit = { fnRunner.runOneTest("logicalTypeValueInt_01") }
-  @Test def test_repTypeValueString_01(): Unit = { fnRunner.runOneTest("repTypeValueString_01") }
-  @Test def test_logicalTypeValueString_01(): Unit = { fnRunner.runOneTest("logicalTypeValueString_01") }
-  @Test def test_outputTypeCalcNextSiblingInt_01(): Unit = { fnRunner.runOneTest("outputTypeCalcNextSiblingInt_01") }
-  @Test def test_outputTypeCalcNextSiblingString_01(): Unit = { fnRunner.runOneTest("outputTypeCalcNextSiblingString_01") }
+
   @Test def test_abstractIntToStringByKeyset_01(): Unit = { fnRunner.runOneTest("abstractIntToStringByKeyset_01") }
   @Test def test_sparse_enum_01(): Unit = { fnRunner.runOneTest("sparse_enum_01") }
 
-  @Test def test_typeCalcDispatch_typeError_01(): Unit = { fnErrRunner.runOneTest("typeCalcDispatch_typeError_01") }
-  @Test def test_typeCalcDispatch_typeError_02(): Unit = { fnErrRunner.runOneTest("typeCalcDispatch_typeError_02") }
-  @Test def test_typeCalcDispatch_typeError_03(): Unit = { fnErrRunner.runOneTest("typeCalcDispatch_typeError_03") }
-  @Test def test_typeCalcDispatch_typeError_04(): Unit = { fnErrRunner.runOneTest("typeCalcDispatch_typeError_04") }
-  @Test def test_typeCalcDispatch_typeError_05(): Unit = { fnErrRunner.runOneTest("typeCalcDispatch_typeError_05") }
-  @Test def test_typeCalcDispatch_typeError_06(): Unit = { fnErrRunner.runOneTest("typeCalcDispatch_typeError_06") }
-  @Test def test_typeCalcDispatch_typeError_07(): Unit = { fnErrRunner.runOneTest("typeCalcDispatch_typeError_07") }
-  @Test def test_typeCalcDispatch_typeError_08(): Unit = { fnErrRunner.runOneTest("typeCalcDispatch_typeError_08") }
-  @Test def test_repTypeValue_bad_context_01(): Unit = { fnErrRunner.runOneTest("repTypeValue_bad_context_01") }
-  @Test def test_repTypeValue_bad_context_02(): Unit = { fnErrRunner.runOneTest("repTypeValue_bad_context_02") }
-  @Test def test_logicalTypeValue_bad_context_01(): Unit = { fnErrRunner.runOneTest("logicalTypeValue_bad_context_01") }
-  @Test def test_logicalTypeValue_bad_context_02(): Unit = { fnErrRunner.runOneTest("logicalTypeValue_bad_context_02") }
-  @Test def test_nextSibling_01(): Unit = { fnErrRunner.runOneTest("nextSibling_01") }
-  @Test def test_nextSibling_02(): Unit = { fnErrRunner.runOneTest("nextSibling_02") }
-  @Test def test_nextSibling_03(): Unit = { fnErrRunner.runOneTest("nextSibling_03") }
-  @Test def test_nextSibling_04(): Unit = { fnErrRunner.runOneTest("nextSibling_04") }
   @Test def test_nonexistant_reptype_01(): Unit = { fnErrRunner.runOneTest("nonexistant_reptype_01") }
   @Test def test_nonexistantOutputTypeCalc_01(): Unit = { fnErrRunner.runOneTest("nonexistantOutputTypeCalc_01") }
   @Test def test_nonexistantInputTypeCalc_01(): Unit = { fnErrRunner.runOneTest("nonexistantInputTypeCalc_01") }
diff --git a/daffodil-test/src/test/scala/org/apache/daffodil/section14/sequence_groups/TestHiddenSequences.scala b/daffodil-test/src/test/scala/org/apache/daffodil/section14/sequence_groups/TestHiddenSequences.scala
index 817bee4..20ad1d9 100644
--- a/daffodil-test/src/test/scala/org/apache/daffodil/section14/sequence_groups/TestHiddenSequences.scala
+++ b/daffodil-test/src/test/scala/org/apache/daffodil/section14/sequence_groups/TestHiddenSequences.scala
@@ -25,7 +25,10 @@
 
   val testDir = "/org/apache/daffodil/section14/sequence_groups/"
 
-  val runner = Runner(testDir, "HiddenSequences.tdml", validateTDMLFile = true)
+  val runner = Runner(testDir, "HiddenSequences.tdml")
+  val runnerNoValidate = Runner(testDir, "HiddenSequences.tdml",
+    validateDFDLSchemas = false,
+    )
 
   @AfterClass def shutDown: Unit = {
     runner.reset
@@ -54,5 +57,5 @@
   @Test def test_noOVCinHiddenContext(): Unit = { runner.runOneTest("noOVCinHiddenContext") }
   @Test def test_nestedNoOVCinHiddenContext(): Unit = { runner.runOneTest("nestedNoOVCinHiddenContext") }
 
-  @Test def test_invalidGroupDefWithHiddenSequenceModelGroup(): Unit = { runner.runOneTest("invalidGroupDefWithHiddenSequenceModelGroup") }
+  @Test def test_invalidGroupDefWithHiddenSequenceModelGroup(): Unit = { runnerNoValidate.runOneTest("invalidGroupDefWithHiddenSequenceModelGroup") }
 }
diff --git a/project/Dependencies.scala b/project/Dependencies.scala
index 9728321..564b97d 100644
--- a/project/Dependencies.scala
+++ b/project/Dependencies.scala
@@ -38,7 +38,7 @@
     "com.fasterxml.jackson.core" % "jackson-core" % "2.12.4"
   )
 
-  lazy val cli = Seq( 
+  lazy val cli = Seq(
     "org.fusesource.jansi" % "jansi" % "2.3.4",
     "org.jline" % "jline" % "3.20.0",
     "org.rogach" %% "scallop" % "4.0.4",