Despecialized typeCalc functions

Instead of having a seperate function for each return type,
typeCalc functions now look at the schema to determine what
their return type is.

This also remove the arbitrary restrictions of types that
they can return.

DAFFODIL-2165
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 c9ce721..69600e4 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
@@ -30,6 +30,9 @@
 import java.math.{ BigDecimal => JBigDecimal, BigInteger => JBigInt }
 import org.apache.daffodil.util.Numbers
 import org.apache.daffodil.api.WarnID
+import org.apache.daffodil.infoset.NoNextElement
+import org.apache.daffodil.infoset.OnlyOnePossibilityForNextElement
+import org.apache.daffodil.infoset.SeveralPossibilitiesForNextElement
 
 /**
  * Root class of the type hierarchy for the AST nodes used when we
@@ -1553,46 +1556,91 @@
       //Begin DFDLX functions
 
       //Begin TypeValueCalc related functions
-      case (RefQName(_, "inputTypeCalcInt", DFDLX), args) =>
+      case (RefQName(_, "inputTypeCalc", DFDLX), args) => {
+        val typeCalc = lookupTypeCalculator(args(0), true, false)
         FNTwoArgsExprInferedArgType(functionQNameString, functionQName, args,
-          NodeInfo.Int, NodeInfo.String, args(1).inherentType, DFDLXInputTypeCalcInt(_))
-
-      case (RefQName(_, "inputTypeCalcString", DFDLX), args) => {
-        FNTwoArgsExprInferedArgType(functionQNameString, functionQName, args,
-          NodeInfo.String, NodeInfo.String, args(1).inherentType, DFDLXInputTypeCalcString(_))
+          typeCalc.dstType, NodeInfo.String, typeCalc.srcType, DFDLXInputTypeCalc(_, typeCalc))
       }
 
-      case (RefQName(_, "outputTypeCalcInt", DFDLX), args) =>
+      case (RefQName(_, "outputTypeCalc", DFDLX), args) => {
+        val typeCalc = lookupTypeCalculator(args(0), false, true)
         FNTwoArgsExprInferedArgType(functionQNameString, functionQName, args,
-          NodeInfo.Int, NodeInfo.String, args(1).inherentType, DFDLXOutputTypeCalcInt(_))
+          typeCalc.srcType, NodeInfo.String, typeCalc.dstType, DFDLXOutputTypeCalc(_, typeCalc))
+      }
 
-      case (RefQName(_, "outputTypeCalcString", DFDLX), args) =>
-        FNTwoArgsExprInferedArgType(functionQNameString, functionQName, args,
-          NodeInfo.String, NodeInfo.String, args(1).inherentType, DFDLXOutputTypeCalcString(_))
-
-      case (RefQName(_, "outputTypeCalcNextSiblingInt", DFDLX), args) =>
+      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.nextElementResolver
+        //we keep the ERD to be able to produce better error messages
+        val dstTypes: Seq[(NodeInfo.Kind, ElementRuntimeData)] = resolver.allPossibleNextElements.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 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
+          }
+        }
         FNZeroArgExpr(functionQNameString, functionQName,
-          NodeInfo.Int, NodeInfo.AnyAtomic, DFDLXOutputTypeCalcNextSiblingInt(_, _))
+          dstType, NodeInfo.AnyAtomic, DFDLXOutputTypeCalcNextSibling(_, _))
+      }
 
-      case (RefQName(_, "outputTypeCalcNextSiblingString", DFDLX), args) =>
+      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,
-          NodeInfo.String, NodeInfo.AnyAtomic, DFDLXOutputTypeCalcNextSiblingString(_, _))
+          repPrimType, NodeInfo.AnyAtomic, DFDLXRepTypeValue(_, _))
+      }
 
-      case (RefQName(_, "repTypeValueInt", DFDLX), args) =>
+      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,
-          NodeInfo.Integer, NodeInfo.AnyAtomic, DFDLXRepTypeValueInt(_, _))
-
-      case (RefQName(_, "repTypeValueString", DFDLX), args) =>
-        FNZeroArgExpr(functionQNameString, functionQName,
-          NodeInfo.String, NodeInfo.AnyAtomic, DFDLXRepTypeValueString(_, _))
-
-      case (RefQName(_, "logicalTypeValueInt", DFDLX), args) =>
-        FNZeroArgExpr(functionQNameString, functionQName,
-          NodeInfo.Integer, NodeInfo.AnyAtomic, DFDLXLogicalTypeValueInt(_, _))
-
-      case (RefQName(_, "logicalTypeValueString", DFDLX), args) =>
-        FNZeroArgExpr(functionQNameString, functionQName,
-          NodeInfo.String, NodeInfo.AnyAtomic, DFDLXLogicalTypeValueString(_, _))
+          logicalType, NodeInfo.AnyAtomic, DFDLXLogicalTypeValue(_, _))
+      }
 
       //End typeValueCalc related functions
 
@@ -1706,6 +1754,43 @@
     funcObj.setOOLAGContext(this)
     funcObj
   }
+
+  def lookupTypeCalculator(typeCalcExpr: Expression, requiresParse: Boolean, requiresUnparse: Boolean): TypeCalculator[AnyRef, AnyRef] = {
+    /*
+     * Every function that currently uses this defines the type calculator
+     * as their first arguement.
+     * We still take the calculators name as an arguement to avoid relying on this
+     * fact.
+     */
+    Assert.invariant(typeCalcExpr == expressions(0))
+    /*
+     * This lookup needs to occur before the main type-checker runs, because it is
+     * used to determine the type of this expression.
+     * As a result, we must do some type checking manually
+     * Also, we insist that typeCalcExpr is a constant, which is not even
+     * a concept that the type checker has
+     */
+    if (typeCalcExpr.inherentType != NodeInfo.String) {
+      SDE("The type calculuator name arguement must be a constant string")
+    }
+    val qname = typeCalcExpr match {
+      case typeCalcName: LiteralExpression => typeCalcName.v.asInstanceOf[String]
+      case _ => SDE("The type calculuator name arguement must be a constant string")
+    }
+    val refType = QName.resolveRef(qname, compileInfo.namespaces, compileInfo.tunable).get.toGlobalQName
+    val typeCalculator = compileInfo.typeCalcMap.get(refType) match {
+      case None => SDE("Simple type %s does not exist or does not have a repType", refType)
+      case Some(x) => x
+    }
+    if (requiresParse && !typeCalculator.supportsParse) {
+      SDE("The type calculator defined by %s does not define an inputValueCalc.", qname)
+    }
+    if (requiresUnparse && !typeCalculator.supportsUnparse) {
+      SDE("The type calculator defined by %s does not define an outputValueCalc.", qname)
+    }
+    typeCalculator
+  }
+
 }
 
 abstract class FunctionCallBase(
@@ -1749,6 +1834,7 @@
   final def argCountTooManyErr(n: Int) = {
     SDE("The %s function requires no more than %s argument(s).", functionQName.toPrettyString, n)
   }
+
 }
 
 /**
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 787020d..bca3e4e 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
@@ -301,7 +301,8 @@
       optPrimType,
       schemaFileLocation,
       tunable,
-      schemaSet.typeCalcMap)
+      schemaSet.typeCalcMap,
+      runtimeData)
     eci
   }
 
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 1d454b4..5dba150 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
@@ -33,6 +33,7 @@
 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.Maybe
 
 abstract class SchemaComponentImpl(
   final override val xml: Node,
@@ -71,11 +72,10 @@
       path,
       schemaFileLocation,
       tunable,
-      schemaSet.typeCalcMap)
+      schemaSet.typeCalcMap,
+      runtimeData)
 
   /**
-   * 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)
@@ -84,7 +84,7 @@
    *
    * There is also VariableRuntimeData and SchemaSetRuntimeData.
    */
-  lazy val runtimeData: RuntimeData = nonTermRuntimeData // overrides in ModelGroup, ElementBase
+  lazy val runtimeData: RuntimeData = nonTermRuntimeData // overrides in ModelGroup, ElementBase, SimpleTypes
 
   final def nonTermRuntimeData = LV('nonTermRuntimeData) {
     new NonTermRuntimeData(
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 9d11e17..59e52d9 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
@@ -209,6 +209,7 @@
   with HasRepValueAttributes {
 
   requiredEvaluations(simpleTypeRuntimeData.preSerialization)
+  requiredEvaluations(optTypeCalculator.map(_.preSerialization))
 
   override def typeNode = primType
 
@@ -249,8 +250,10 @@
       tunable,
       optRepTypeDef.map(_.simpleTypeRuntimeData),
       optRepValueSet,
-      optTypeCalculator)
+      optTypeCalculator,
+      optRepType.map(_.primType))
   }
+  override lazy val runtimeData = simpleTypeRuntimeData
 
   private lazy val noFacetChecks =
     optRestriction.map { r =>
@@ -310,7 +313,7 @@
   lazy val optInputTypeCalc = findPropertyOption("inputTypeCalc")
   lazy val optOutputTypeCalc = findPropertyOption("outputTypeCalc")
 
-  lazy val optTypeCalculator: Option[TypeCalculator[AnyRef, AnyRef]] = {
+  lazy val optTypeCalculator: Option[TypeCalculator[AnyRef, AnyRef]] = LV('optTypeCalculator) {
     optRepType.flatMap(repType => {
       val srcType = repType.primType
       val dstType = primType
@@ -369,7 +372,7 @@
         val supportsParse = optInputTypeCalc.isDefined
         val supportsUnparse = optOutputTypeCalc.isDefined
         if (supportsParse || supportsUnparse) {
-          Some(TypeCalculatorCompiler.compileTypeCalculatorFromExpression(optInputCompiled, optOutputCompiled, srcType, dstType, supportsParse, supportsUnparse))
+          Some(TypeCalculatorCompiler.compileTypeCalculatorFromExpression(optInputCompiled, optOutputCompiled, srcType, dstType))
         } else {
           None
         }
@@ -410,7 +413,7 @@
       ans
 
     })
-  }
+  }.value
 
   /*
    * We don't really need the NamedMixin. It is only used for detecting duplicates
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesExpressions.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesExpressions.scala
index b7d4e38..1a284fe 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesExpressions.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesExpressions.scala
@@ -258,11 +258,7 @@
   extends Terminal(e, e.hasRepType) {
 
   private lazy val simpleTypeDefBase = e.simpleType.asInstanceOf[SimpleTypeDefBase]
-  private lazy val typeCalculator = {
-    val a = simpleTypeDefBase
-    val b = simpleTypeDefBase.optTypeCalculator
-    simpleTypeDefBase.optTypeCalculator.get
-  }
+  private lazy val typeCalculator = simpleTypeDefBase.optTypeCalculator.get
   private lazy val repTypeRuntimeData = simpleTypeDefBase.optRepTypeElement.get.elementRuntimeData
   private lazy val repTypeParser = simpleTypeDefBase.optRepTypeElement.get.enclosedElement.parser
   private lazy val repTypeUnparser = simpleTypeDefBase.optRepTypeElement.get.enclosedElement.unparser
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 0e85725..a026362 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
@@ -25,105 +25,32 @@
 import org.apache.daffodil.dpath.NodeInfo.PrimType.IntegerKind
 import org.apache.daffodil.dpath.NodeInfo.PrimType.String
 import org.apache.daffodil.dpath.NodeInfo.PrimType.Integer
+import org.apache.daffodil.processors.TypeCalculator
 
-trait TypeCalculatorNamedDispatch { self: FNTwoArgs =>
-  val srcType: NodeInfo.Kind
-  val dstType: NodeInfo.Kind
+case class DFDLXInputTypeCalc(typedRecipes: List[(CompiledDPath, NodeInfo.Kind)], calc: TypeCalculator[AnyRef, AnyRef])
+  extends FNTwoArgs(typedRecipes.map(_._1)) {
 
-  /*
-   * Note the the src/dst type of the calculator are not nessasarily expected to match the src/dst type of the expression.
-   * In particular, there are 2 things to be aware of:
-   *
-   * 1) The src/dst type of the calculator refer to the type of the inputTypeCalc function
-   *       they will be swapped for the outputTypeCalc function
-   *
-   *    For clarity, "inputType" and "outputType" refer to the domain and codomain of calculator function that the caller plans on using.
-   *
-   * 2) It is possible for the srcType of the expression to be a subtype of inputType
-   *    it is possible for the dstType of the expression to be a subtype of outputType
-   */
-  def getCalculator(arg1: AnyRef, dstate: DState, expectedInputType: NodeInfo.Kind, expectedOutputType: NodeInfo.Kind, requireInputCalc: Boolean = false, requireOutputCalc: Boolean = false): TypeCalculator[AnyRef, AnyRef] = {
-    val qn = arg1.asInstanceOf[String]
-    val refType = QName.resolveRef(qn, dstate.compileInfo.namespaces, dstate.compileInfo.tunable).get.toGlobalQName
-    val maybeCalc = dstate.typeCalculators.get(refType)
-    if (!maybeCalc.isDefined) {
-      dstate.SDE("Simple type %s does not exist or does not have a repType", refType)
-    }
-    val calc = maybeCalc.get
-    if (!expectedInputType.isSubtypeOf(calc.srcType)) {
-      dstate.SDE(s"The type calculator defined by ${qn} has a source type of ${calc.srcType}, but its usage requires ${expectedInputType}")
-    }
-    if (!calc.dstType.isSubtypeOf(expectedOutputType)) {
-      dstate.SDE(s"The type calculator defined by ${qn} has a destination type of ${calc.dstType}, but its usage requires ${expectedOutputType}")
-    }
-
-    Assert.invariant(requireInputCalc || requireOutputCalc)
-    
-    if (requireInputCalc && !calc.supportsParse) {
-      dstate.SDE(s"${qn} does not define an inputValueCalc")
-    }
-    if (requireOutputCalc && !calc.supportsUnparse) {
-      dstate.SDE(s"${qn} does not define an outputValueCalc")
-    }
-    calc
-  }
-}
-
-case class DFDLXInputTypeCalcInt(typedRecipes: List[(CompiledDPath, NodeInfo.Kind)])
-  extends FNTwoArgs(typedRecipes.map(_._1))
-  with TypeCalculatorNamedDispatch {
-  
-  override val dstType = NodeInfo.Int
-  override val srcType = typedRecipes(1)._2
+  val srcType = typedRecipes(1)._2
 
   override def computeValue(arg1: AnyRef, arg2: AnyRef, dstate: DState): AnyRef = {
-    val calc = getCalculator(arg1, dstate, srcType, dstType, requireInputCalc=true)
     calc.inputTypeCalcRun(dstate, arg2, srcType)
     dstate.currentValue
   }
 
 }
 
-case class DFDLXInputTypeCalcString(typedRecipes: List[(CompiledDPath, NodeInfo.Kind)])
-  extends FNTwoArgs(typedRecipes.map(_._1))
-  with TypeCalculatorNamedDispatch {
-  
-  override val dstType = NodeInfo.String
-  override val srcType = typedRecipes(1)._2
-  
+case class DFDLXOutputTypeCalc(typedRecipes: List[(CompiledDPath, NodeInfo.Kind)], calc: TypeCalculator[AnyRef, AnyRef])
+  extends FNTwoArgs(typedRecipes.map(_._1)) {
+
+  val srcType = typedRecipes(1)._2
+
   def computeValue(arg1: AnyRef, arg2: AnyRef, dstate: DState): AnyRef = {
-    getCalculator(arg1, dstate, srcType, dstType, requireInputCalc=true).inputTypeCalcRun(dstate, arg2, srcType)
+    calc.outputTypeCalcRun(dstate, arg2, srcType)
     dstate.currentValue
   }
 }
 
-case class DFDLXOutputTypeCalcInt(typedRecipes: List[(CompiledDPath, NodeInfo.Kind)])
-  extends FNTwoArgs(typedRecipes.map(_._1))
-  with TypeCalculatorNamedDispatch {
-  
-  override val dstType = NodeInfo.Int
-  override val srcType = typedRecipes(1)._2
-  
-  def computeValue(arg1: AnyRef, arg2: AnyRef, dstate: DState): AnyRef = {
-    getCalculator(arg1, dstate, dstType, srcType, requireOutputCalc=true).outputTypeCalcRun(dstate, arg2, srcType)
-    dstate.currentValue
-  }
-}
-
-case class DFDLXOutputTypeCalcString(typedRecipes: List[(CompiledDPath, NodeInfo.Kind)])
-  extends FNTwoArgs(typedRecipes.map(_._1))
-  with TypeCalculatorNamedDispatch {
-  override val dstType = NodeInfo.String
-  override val srcType = typedRecipes(1)._2
-  
-  def computeValue(arg1: AnyRef, arg2: AnyRef, dstate: DState): AnyRef = {
-    getCalculator(arg1, dstate, dstType, srcType, requireOutputCalc=true).outputTypeCalcRun(dstate, arg2, srcType)
-    dstate.currentValue
-  }
-}
-
-trait DFDLXOutputTypeCalcNextSibling {
-  def dstType: NodeInfo.Kind
+case class DFDLXOutputTypeCalcNextSibling(a: CompiledDPath, b: NodeInfo.Kind) extends RecipeOp {
 
   def run(dstate: DState): Unit = {
     if (dstate.isCompile) {
@@ -134,110 +61,55 @@
 
     val nextSibling = dstate.nextSibling.asSimple
     val typeCalculator = nextSibling.erd.optSimpleTypeRuntimeData.get.typeCalculator.get
-    if(!typeCalculator.supportsUnparse){
-      dstate.SDE(s"The type calculator defined by ${nextSibling.erd.diagnosticDebugName} does not define an outputCalc")
-    }
-    if (!typeCalculator.srcType.isSubtypeOf(dstType)) {
-      dstate.SDE(s"The type calculator defined by ${nextSibling.erd.diagnosticDebugName} has a source type of ${typeCalculator.srcType}, but its usage requires ${dstType}")
-    }
+    /*
+     * 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
-    if (!primType.isSubtypeOf(typeCalculator.dstType)) {
-      dstate.SDE(s"The type calculator defined by ${nextSibling.erd.diagnosticDebugName} has a destination type of ${typeCalculator.dstType}, but its usage requires ${primType}")
-    }
+
     val x = nextSibling.dataValue
     typeCalculator.outputTypeCalcRun(dstate, x, primType)
   }
 }
 
-case class DFDLXOutputTypeCalcNextSiblingInt(a: CompiledDPath, b: NodeInfo.Kind) extends RecipeOp
-  with DFDLXOutputTypeCalcNextSibling {
-  override def dstType = NodeInfo.Int
-}
+case class DFDLXRepTypeValue(a: CompiledDPath, b: NodeInfo.Kind)
+  extends RecipeOp {
 
-case class DFDLXOutputTypeCalcNextSiblingString(a: CompiledDPath, b: NodeInfo.Kind) extends RecipeOp
-  with DFDLXOutputTypeCalcNextSibling {
-  override def dstType = NodeInfo.String
-}
-
-trait DFDLXWithExtractTypedValue { self: RecipeOp =>
-  def returnType: NodeInfo.Kind
-
-  //Below strings are to provide better diagnostic messages
-  def functionName: String
-  def legalContext: String
-  def repOrLogicalType: String
-
-  def extractVal(typedVal: Maybe[(AnyRef, NodeInfo.Kind)], dstate: DState): AnyRef = {
-    if (dstate.isCompile) {
-      //CompileDPath.runExpressionForConstant (in DPathRuntime.scala) determines
-      //that an expression is not constant by seeing if evalutating it throws an exception
+  override def run(dstate: DState): Unit = {
+    if (dstate.isCompile){
       throw new IllegalStateException()
     }
-    if (typedVal.isEmpty) {
-      dstate.SDE(s"${functionName} may only be called from within a ${legalContext} annotation")
+    
+    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")
     }
-    val (x, xKind) = typedVal.get
-    if (!xKind.isSubtypeOf(returnType)) {
-      xKind.isSubtypeOf(returnType)
-      dstate.SDE(s"${repOrLogicalType} is a(n) ${xKind} type, where ${returnType} is expected")
+    dstate.setCurrentValue(dstate.repValue.get)
+  }
+}
+
+case class DFDLXLogicalTypeValue(a: CompiledDPath, b: NodeInfo.Kind)
+  extends RecipeOp {
+
+  override def run(dstate: DState): Unit = {
+    
+    if (dstate.isCompile){
+      throw new IllegalStateException()
     }
-    x
-  }
-}
-
-case class DFDLXRepTypeValueInt(a: CompiledDPath, b: NodeInfo.Kind)
-  extends RecipeOp
-  with DFDLXWithExtractTypedValue {
-  override val returnType = Integer
-  override val functionName = "dfdlx:repTypeValueInt()"
-  override val legalContext = "dfdlx:inputTypeCalc"
-  override val repOrLogicalType = "repType"
-
-  override def run(dstate: DState): Unit = {
-    val repValue = extractVal(dstate.repValue, dstate)
-    dstate.setCurrentValue(repValue)
-  }
-}
-
-case class DFDLXRepTypeValueString(a: CompiledDPath, b: NodeInfo.Kind)
-  extends RecipeOp
-  with DFDLXWithExtractTypedValue {
-
-  override val returnType = String
-  override val functionName = "dfdlx:repTypeValueString()"
-  override val legalContext = "dfdlx:inputTypeCalc"
-  override val repOrLogicalType = "repType"
-
-  override def run(dstate: DState): Unit = {
-    val repValue = extractVal(dstate.repValue, dstate)
-    dstate.setCurrentValue(repValue)
-  }
-}
-
-case class DFDLXLogicalTypeValueInt(a: CompiledDPath, b: NodeInfo.Kind)
-  extends RecipeOp
-  with DFDLXWithExtractTypedValue {
-
-  override val returnType = Integer
-  override val functionName = "dfdlx:logicalTypeValueInt()"
-  override val legalContext = "dfdlx:outputTypeCalc"
-  override val repOrLogicalType = "logical type"
-
-  override def run(dstate: DState): Unit = {
-    val repValue = extractVal(dstate.logicalValue, dstate)
-    dstate.setCurrentValue(repValue)
-  }
-}
-case class DFDLXLogicalTypeValueString(a: CompiledDPath, b: NodeInfo.Kind)
-  extends RecipeOp
-  with DFDLXWithExtractTypedValue {
-  override val returnType = String
-  override val functionName = "dfdlx:logicalTypeValueString()"
-  override val legalContext = "dfdlx:outputTypeCalc"
-  override val repOrLogicalType = "logical type"
-
-  override def run(dstate: DState): Unit = {
-    val repValue = extractVal(dstate.logicalValue, dstate)
-    dstate.setCurrentValue(repValue)
+    
+    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.get)
   }
 }
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DState.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DState.scala
index 73290de..9e10ec1 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DState.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DState.scala
@@ -113,9 +113,9 @@
    * (eg. to the runtime stack), and replaces the below fields.
    * At the end of the computation, it should restore the below fields.
    */
-  var logicalValue: Maybe[(AnyRef, NodeInfo.Kind)] = Maybe.Nope
+  var logicalValue: Maybe[AnyRef] = Maybe.Nope
 
-  var repValue: Maybe[(AnyRef, NodeInfo.Kind)] = Maybe.Nope
+  var repValue: Maybe[AnyRef] = Maybe.Nope
 
   /**
    * The currentValue is used when we have a value that is not
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 0b3d065..a76d8d5 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
@@ -17,7 +17,7 @@
 
 package org.apache.daffodil.dsom
 
-import scala.runtime.ScalaRunTime.stringOf
+import scala.runtime.ScalaRunTime.stringOf // for printing arrays properly.
 
 import org.apache.daffodil.api.DaffodilTunables
 import org.apache.daffodil.api.UnqualifiedPathStepPolicy
@@ -29,6 +29,7 @@
 import org.apache.daffodil.exceptions.HasSchemaFileLocation
 import org.apache.daffodil.exceptions.SchemaFileLocation
 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
@@ -205,7 +206,8 @@
   val path: String,
   override val schemaFileLocation: SchemaFileLocation,
   val tunable: DaffodilTunables,
-  @TransientParam typeCalcMapArg: => TypeCalcMap)
+  @TransientParam typeCalcMapArg: => TypeCalcMap,
+  val lexicalContextRuntimeData: RuntimeData)
   extends ImplementsThrowsSDE with PreSerialization
   with HasSchemaFileLocation {
 
@@ -316,8 +318,9 @@
   val optPrimType: Option[PrimType],
   sfl: SchemaFileLocation,
   override val tunable: DaffodilTunables,
-  typeCalcMap: TypeCalcMap)
-  extends DPathCompileInfo(parentArg, variableMap, namespaces, path, sfl, tunable, typeCalcMap)
+  typeCalcMap: TypeCalcMap,
+  lexicalContextRuntimeData: RuntimeData)
+  extends DPathCompileInfo(parentArg, variableMap, namespaces, path, sfl, tunable, typeCalcMap, lexicalContextRuntimeData)
   with HasSchemaFileLocation {
 
   lazy val elementChildrenCompileInfo = elementChildrenCompileInfoArg
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/NextElementResolver.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/NextElementResolver.scala
index 8c0d9e8..e79ae93 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/NextElementResolver.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/NextElementResolver.scala
@@ -51,6 +51,8 @@
   //
   def nextElement(nqn: NamedQName, hasNamespace: Boolean): ElementRuntimeData =
     nextElement(nqn.local, if (hasNamespace) nqn.namespace.toStringOrNullIfNoNS else null, hasNamespace)
+    
+  def allPossibleNextElements: Seq[ElementRuntimeData]
 }
 
 sealed abstract class ResolverType(val name: String) extends Serializable
@@ -66,10 +68,12 @@
   }
 
   override def toString() = "NoNextElement"
+  
+  override val allPossibleNextElements = Seq()
 
 }
 
-class OnlyOnePossibilityForNextElement(schemaFileLocation: SchemaFileLocation, nextERD: ElementRuntimeData, resolverType: ResolverType)
+class OnlyOnePossibilityForNextElement(schemaFileLocation: SchemaFileLocation, val nextERD: ElementRuntimeData, resolverType: ResolverType)
   extends NextElementResolver {
 
   override def nextElement(local: String, namespace: String, hasNamespace: Boolean): ElementRuntimeData = {
@@ -95,6 +99,8 @@
   }
 
   override def toString() = "OnlyOne(" + nextERD.namedQName + ")"
+  
+  override lazy val allPossibleNextElements = Seq(nextERD)
 }
 
 /**
@@ -163,4 +169,6 @@
   }
 
   override def toString() = "Several(" + nextERDMap.keySet.mkString(", ") + ")"
+  
+  override lazy val allPossibleNextElements = nextERDMap.values.toSeq
 }
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 9785700..080681f 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
@@ -240,7 +240,8 @@
   @TransientParam tunableArg: => DaffodilTunables,
   @TransientParam repTypeRuntimeDataArg: => Option[SimpleTypeRuntimeData],
   @TransientParam repValueSetArg: => Option[RepValueSet[AnyRef]],
-  @TransientParam typeCalculatorArg: => Option[TypeCalculator[AnyRef,AnyRef]]
+  @TransientParam typeCalculatorArg: => Option[TypeCalculator[AnyRef,AnyRef]],
+  @TransientParam optRepPrimTypeArg: => Option[PrimType]
 ) extends NonTermRuntimeData(variableMapArg, schemaFileLocationArg, diagnosticDebugNameArg,
   pathArg, namespacesArg, tunableArg) {
 
@@ -262,6 +263,7 @@
   lazy val repTypeRuntimeData = repTypeRuntimeDataArg
   lazy val repValueSet = repValueSetArg
   lazy val typeCalculator = typeCalculatorArg
+  lazy val optRepPrimType = optRepPrimTypeArg
 
   override def preSerialization: Unit = {
     super.preSerialization
@@ -281,6 +283,7 @@
     repTypeRuntimeData
     repValueSet
     typeCalculator
+    optRepPrimType
   }
 
   @throws(classOf[java.io.IOException])
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 332da69..970a4e3 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
@@ -32,12 +32,16 @@
 import org.apache.daffodil.util.PreSerialization
 import org.apache.daffodil.util.RangeBound
 import org.apache.daffodil.util.TransientParam
-import org.apache.daffodil.xml.GlobalQName
+import org.apache.daffodil.xml.QNameBase
 
 abstract class TypeCalculator[A <: AnyRef, B <: AnyRef](val srcType: NodeInfo.Kind, val dstType: NodeInfo.Kind)
   extends PreSerialization {
   type Error = String
 
+  override def preSerialization: Any = {
+    super.preSerialization
+  }
+
   /*
    * We can be used from both a parser directly, and as part of a DPath expression.
    * There are 2 main differences that require handling these cases seperatly
@@ -172,12 +176,14 @@
 }
 
 class ExpressionTypeCalculator[A <: AnyRef, B <: AnyRef](
-  @TransientParam maybeInputTypeCalcArg: => Maybe[CompiledExpression[B]],
+  @TransientParam maybeInputTypeCalcArg: => Maybe[ CompiledExpression[B]],
   @TransientParam maybeOutputTypeCalcArg: => Maybe[CompiledExpression[A]],
-  srcType: NodeInfo.Kind, dstType: NodeInfo.Kind,
-  override val supportsParse: Boolean, override val supportsUnparse: Boolean)
+  srcType: NodeInfo.Kind, dstType: NodeInfo.Kind)
   extends TypeCalculator[A, B](srcType, dstType) {
 
+  override def supportsParse = maybeInputTypeCalcArg.isDefined
+  override def supportsUnparse = maybeOutputTypeCalcArg.isDefined
+
   /*
    * Compiling DPath expressions may need to evaluate typeCalculators in order to lookup their srcType and dstType.
    * To prevent circular dependencies, this means that the underlying expressions must be lazy.
@@ -188,7 +194,7 @@
   lazy val maybeInputTypeCalc = maybeInputTypeCalcArg
   lazy val maybeOutputTypeCalc = maybeOutputTypeCalcArg
 
-  override protected def preSerialization: Any = {
+  override def preSerialization: Any = {
     super.preSerialization
     maybeInputTypeCalc
     maybeOutputTypeCalc
@@ -208,7 +214,7 @@
     val dstate = state.dState
     val oldRepValue = dstate.repValue
     val oldLogicalValue = dstate.logicalValue
-    dstate.repValue = One((x, xType))
+    dstate.repValue = One(x)
     dstate.logicalValue = Maybe.Nope
 
     val ans = Maybe(maybeInputTypeCalc.get.evaluate(state))
@@ -222,7 +228,7 @@
     val oldRepValue = dstate.repValue
     val oldLogicalValue = dstate.logicalValue
     dstate.repValue = Maybe.Nope
-    dstate.logicalValue = One((x, xType))
+    dstate.logicalValue = One(x)
 
     val ans = Maybe(maybeOutputTypeCalc.get.evaluate(state))
 
@@ -234,7 +240,7 @@
   override def inputTypeCalcRun(dstate: DState, x: A, xType: NodeInfo.Kind): Unit = {
     val oldRepValue = dstate.repValue
     val oldLogicalValue = dstate.logicalValue
-    dstate.repValue = One((x, xType))
+    dstate.repValue = One(x)
     dstate.logicalValue = Maybe.Nope
 
     maybeInputTypeCalc.get.run(dstate)
@@ -247,7 +253,7 @@
     val oldRepValue = dstate.repValue
     val oldLogicalValue = dstate.logicalValue
     dstate.repValue = Maybe.Nope
-    dstate.logicalValue = One((x, xType))
+    dstate.logicalValue = One(x)
 
     maybeOutputTypeCalc.get.run(dstate)
 
@@ -330,7 +336,7 @@
 
 object TypeCalculatorCompiler {
 
-  type TypeCalcMap = Map[GlobalQName, TypeCalculator[AnyRef, AnyRef]]
+  type TypeCalcMap = Map[QNameBase, TypeCalculator[AnyRef, AnyRef]]
 
   // mappings: [(keySet, canonicalKey, value)]
   def compileKeysetValue[A <: AnyRef, B <: AnyRef](mappings: Seq[(RepValueSet[A], A, B)], srcType: NodeInfo.Kind, dstType: NodeInfo.Kind): TypeCalculator[A, B] = {
@@ -374,11 +380,10 @@
   def compileTypeCalculatorFromExpression[A <: AnyRef, B <: AnyRef](
     optInputTypeCalc: => Option[CompiledExpression[B]],
     optOutputTypeCalc: => Option[CompiledExpression[A]],
-    srcType: NodeInfo.Kind, dstType: NodeInfo.Kind,
-    supportsParse: Boolean, supportsUnparse: Boolean): ExpressionTypeCalculator[A, B] = {
+    srcType: NodeInfo.Kind, dstType: NodeInfo.Kind): ExpressionTypeCalculator[A, B] = {
     lazy val maybeInputType: Maybe[CompiledExpression[B]] = optInputTypeCalc.map(Maybe(_)).getOrElse(Maybe.Nope)
     lazy val maybeOutputType: Maybe[CompiledExpression[A]] = optOutputTypeCalc.map(Maybe(_)).getOrElse(Maybe.Nope)
-    new ExpressionTypeCalculator(maybeInputType, maybeOutputType, srcType, dstType, supportsParse, supportsUnparse)
+    new ExpressionTypeCalculator(maybeInputType, maybeOutputType, srcType, dstType)
   }
   def compileIdentity[A <: AnyRef](srcType: NodeInfo.Kind): TypeCalculator[A, A] = new IdentifyTypeCalculator(srcType)
 
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
index 824e076..5162064 100644
--- 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
@@ -18,7 +18,8 @@
 
 <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:xs="http://www.w3.org/2001/XMLSchema">
+  xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/" xmlns:xs="http://www.w3.org/2001/XMLSchema"
+  xmlns:dfdlx="http://www.ogf.org/dfdl/dfdl-1.0/extensions" >
 
   <tdml:defineSchema name="inputTypeCalc-Embedded.dfdl.xsd">
 
@@ -28,7 +29,7 @@
       terminator="" occursCountKind="parsed" ignoreCase="no"
       textNumberRep="standard" representation="text" />
 
-    <xs:element name="keysetValue_00" type="tns:keysetValue_01">
+    <xs:element name="keysetValue_00" type="tns:keysetValue_01" />
 
     <xs:element name="keysetValue_01">
       <xs:complexType>
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 5aa2a7e..033540e 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
@@ -49,65 +49,63 @@
       <xs:restriction base="xs:string"/>
     </xs:simpleType>
 
-    <!--
-    <xs:element name="typeCalcDispatch_typeError_baseline" type="xs:string" dfdl:inputValueCalc="{ dfdlx:inputTypeCalcString('tns:intToString', 0) }" />
-    -->
-    <xs:element name="typeCalcDispatch_typeError_01" type="xs:int" dfdl:inputValueCalc="{ dfdlx:inputTypeCalcString('tns:intToString', 0) }" />
-    <xs:element name="typeCalcDispatch_typeError_02" type="xs:int" dfdl:inputValueCalc="{ dfdlx:inputTypeCalcInt('tns:intToString', 0) }" />
-    <xs:element name="typeCalcDispatch_typeError_03" type="xs:int" dfdl:inputValueCalc="{ dfdlx:inputTypeCalcInt('tns:stringToInt', 0) }" />
-    <!--
-    <xs:element name="typeCalcDispatch_typeError_baseline" type="xs:string" dfdl:outputValueCalc="{ dfdlx:outputTypeCalcString('tns:stringToInt', 0) }" />
-    -->
-    <xs:element name="typeCalcDispatch_typeError_04" type="xs:int" dfdl:inputValueCalc="{ dfdlx:outputTypeCalcString('tns:stringToInt', 0) }" />
-    <xs:element name="typeCalcDispatch_typeError_05" type="xs:int" dfdl:inputValueCalc="{ dfdlx:outputTypeCalcInt('tns:stringToInt', 0) }" />
-    <xs:element name="typeCalcDispatch_typeError_06" type="xs:int" dfdl:inputValueCalc="{ dfdlx:outputTypeCalcInt('tns:intToString', 0) }" />
+    <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_07" dfdlx:parseUnparsePolicy="unparseOnly">
+    <xs:element name="typeCalcDispatch_typeError_03" dfdlx:parseUnparsePolicy="unparseOnly">
       <xs:complexType>
         <xs:sequence>
-          <xs:element name="raw" dfdl:outputValueCalc="{ dfdlx:outputTypeCalcNextSiblingInt() }" type="tns:uint8" dfdlx:parseUnparsePolicy="unparseOnly"/>
+          <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:complexType>
-        <xs:sequence>
-          <xs:element name="raw" dfdl:outputValueCalc="{ dfdlx:outputTypeCalcNextSiblingString() }" 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_09">
-      <xs:simpleType dfdlx:repType="tns:string8" dfdlx:inputTypeCalc="{ dfdlx:repTypeValueString() }">
-        <xs:restriction base="xs:int"/>
-      </xs:simpleType>
-    </xs:element>
-
-    <xs:element name="typeCalcDispatch_typeError_10">
-      <xs:simpleType dfdlx:repType="tns:string8" dfdlx:inputTypeCalc="{ dfdlx:repTypeValueInt() }">
-        <xs:restriction base="xs:int"/>
-      </xs:simpleType>
-    </xs:element>
-
-    <xs:element name="typeCalcDispatch_typeError_11" dfdlx:parseUnparsePolicy="unparseOnly" >
-      <xs:simpleType dfdlx:repType="tns:uint8" dfdlx:outputTypeCalc="{ dfdlx:logicalTypeValueInt() }">
+      <xs:simpleType dfdlx:repType="tns:uint8" dfdlx:outputTypeCalc="{ dfdlx:logicalTypeValue() }">
         <xs:restriction base="xs:string"/>
       </xs:simpleType>
     </xs:element>
 
-    <xs:element name="typeCalcDispatch_typeError_12" dfdlx:parseUnparsePolicy="unparseOnly">
-      <xs:simpleType dfdlx:repType="tns:uint8" dfdlx:outputTypeCalc="{ dfdlx:logicalTypeValueString() }">
-        <xs:restriction base="xs:string"/>
+    <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="repTypeValue_bad_context_01" type="xs:string" dfdl:inputValueCalc="{ dfdlx:repTypeValueString() }"/>
-    <xs:element name="repTypeValue_bad_context_02" type="xs:int" dfdl:inputValueCalc="{ dfdlx:repTypeValueInt() }"/>
-    <xs:element name="logicalTypeValue_bad_context_01" type="xs:string" dfdl:inputValueCalc="{ dfdlx:logicalTypeValueString() }"/>
-    <xs:element name="logicalTypeValue_bad_context_02" type="xs:int" dfdl:inputValueCalc="{ dfdlx:logicalTypeValueInt() }"/>
+    <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 }">
@@ -119,13 +117,54 @@
       <xs:restriction base="xs:int"/>
     </xs:simpleType>
 
-    <xs:element name="nonexistantOutputTypeCalc_01" type="xs:int" dfdl:inputValueCalc="{dfdlx:outputTypeCalcInt('tns:inputConversionOnly', 7)}"/>
+    <xs:element name="nonexistantOutputTypeCalc_01" type="xs:int" dfdl:inputValueCalc="{dfdlx:outputTypeCalc('tns:inputConversionOnly', 7)}"/>
 
     <xs:simpleType name="outputConversionOnly" dfdlx:repType="tns:uint8" dfdlx:outputTypeCalc="{ 1 }">
       <xs:restriction base="xs:int"/>
     </xs:simpleType>
 
-    <xs:element name="nonexistantInputTypeCalc_01" type="xs:int" dfdl:inputValueCalc="{dfdlx:inputTypeCalcInt('tns:outputConversionOnly', 7)}"/>
+    <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>
 
@@ -153,30 +192,6 @@
     </tdml:document>
     <tdml:errors>
       <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>tns:intToString has a destination type of String, but its usage requires Int</tdml:error>
-    </tdml:errors>
-  </tdml:parserTestCase>
-
-  <tdml:parserTestCase name="typeCalcDispatch_typeError_03"
-    root="typeCalcDispatch_typeError_03" 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>tns:stringToInt has a source type of String, but its usage requires Int</tdml:error>
-    </tdml:errors>
-  </tdml:parserTestCase>
-
-  <tdml:parserTestCase name="typeCalcDispatch_typeError_04"
-    root="typeCalcDispatch_typeError_04" 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>
@@ -185,52 +200,34 @@
     </tdml:warnings>
   </tdml:parserTestCase>
 
-  <tdml:parserTestCase name="typeCalcDispatch_typeError_05"
-    root="typeCalcDispatch_typeError_05" 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>tns:stringToInt has a source type of String, but its usage requires Int</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="byte">
-    </tdml:documentPart>
-    </tdml:document>
-    <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>tns:intToString has a destination type of String, but its usage requires Int</tdml:error>
-    </tdml:errors>
-  </tdml:parserTestCase>
-
-  <tdml:unparserTestCase name="typeCalcDispatch_typeError_07"
-    root="typeCalcDispatch_typeError_07" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
+  <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_07>
+        <typeCalcDispatch_typeError_03>
           <stringToInt>0</stringToInt>
-        </typeCalcDispatch_typeError_07>
+        </typeCalcDispatch_typeError_03>
       </tdml:dfdlInfoset>
     </tdml:infoset>
     <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>The type calculator defined by stringToInt has a source type of String, but its usage requires Int</tdml:error>
+      <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>Expression result type (String)</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:unparserTestCase name="typeCalcDispatch_typeError_04"
+    root="typeCalcDispatch_typeError_04" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
     <tdml:infoset>
       <tdml:dfdlInfoset>
-        <typeCalcDispatch_typeError_08>
+        <typeCalcDispatch_typeError_04>
           <stringToInt>0</stringToInt>
-        </typeCalcDispatch_typeError_08>
+        </typeCalcDispatch_typeError_04>
       </tdml:dfdlInfoset>
     </tdml:infoset>
     <tdml:errors>
@@ -242,8 +239,8 @@
     </tdml:warnings>
   </tdml:unparserTestCase>
 
-  <tdml:parserTestCase name="typeCalcDispatch_typeError_09"
-    root="typeCalcDispatch_typeError_09" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
+  <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>
@@ -254,35 +251,49 @@
     </tdml:errors>
   </tdml:parserTestCase>
 
-  <tdml:parserTestCase name="typeCalcDispatch_typeError_10"
-    root="typeCalcDispatch_typeError_10" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
+  <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>Schema Definition Error</tdml:error>
-      <tdml:error>Reptype is a(n) String type, where Integer is expected</tdml:error>
+      <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>Expression 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_11"
-    root="typeCalcDispatch_typeError_11" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
+  <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_11>a</typeCalcDispatch_typeError_11>
+        <typeCalcDispatch_typeError_07>a</typeCalcDispatch_typeError_07>
       </tdml:dfdlInfoset>
     </tdml:infoset>
     <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>logical type is a(n) String type, where Integer is expected</tdml:error>
+      <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>Expression 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_12"
-    root="typeCalcDispatch_typeError_12" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
+  <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_12>a</typeCalcDispatch_typeError_12>
+        <typeCalcDispatch_typeError_08>a</typeCalcDispatch_typeError_08>
       </tdml:dfdlInfoset>
     </tdml:infoset>
     <tdml:errors>
@@ -298,20 +309,22 @@
     </tdml:document>
     <tdml:errors>
       <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>dfdlx:repTypeValueString() may only be called from within a dfdlx:inputTypeCalc annotation</tdml:error>
+      <tdml:error>dfdlx:repTypeValue() can only be defined on a simple type</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
-  <tdml:parserTestCase name="repTypeValue_bad_context_02"
+  <tdml:unparserTestCase name="repTypeValue_bad_context_02"
     root="repTypeValue_bad_context_02" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
-    <tdml:document>
-    <tdml:documentPart type="byte"></tdml:documentPart>
-    </tdml:document>
+    <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:repTypeValueInt() may only be called from within a dfdlx:inputTypeCalc annotation</tdml:error>
+      <tdml:error>dfdlx:repTypeValue() may only be called from within dfdlx:inputTypeCalc</tdml:error>
     </tdml:errors>
-  </tdml:parserTestCase>
+  </tdml:unparserTestCase>
 
   <tdml:parserTestCase name="logicalTypeValue_bad_context_01"
     root="logicalTypeValue_bad_context_01" model="inputTypeCalcFunctionErrors-Embedded.dfdl.xsd" description="Extensions - inputTypeCalc errors">
@@ -320,18 +333,18 @@
     </tdml:document>
     <tdml:errors>
       <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>dfdlx:logicalTypeValueString() may only be called from within a dfdlx:outputTypeCalc annotation</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"></tdml:documentPart>
+    <tdml:documentPart type="byte">00</tdml:documentPart>
     </tdml:document>
     <tdml:errors>
       <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>dfdlx:logicalTypeValueInt() may only be called from within a dfdlx:outputTypeCalc annotation</tdml:error>
+      <tdml:error>dfdlx:logicalTypeValue() may only be called from within dfdlx:outputTypeCalc</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -377,7 +390,7 @@
       dfdlx:parseUnparsePolicy="parseOnly"
       />
 
-     <xs:element name="root" type="xs:int" dfdl:inputValueCalc="{ dfdlx:inputTypeCalcInt('tns:nonExistant', 0) }"/>
+     <xs:element name="root" type="xs:int" dfdl:inputValueCalc="{ dfdlx:inputTypeCalc('tns:nonExistant', 0) }"/>
 
   </tdml:defineSchema>
 
@@ -405,7 +418,7 @@
      <xs:simpleType name="nonExistantTypeCalc">
        <xs:restriction base="xs:int"/>
      </xs:simpleType>
-     <xs:element name="root" type="xs:int" dfdl:inputValueCalc="{ dfdlx:inputTypeCalcInt('tns:nonExistantTypeCalc', 0) }"/>
+     <xs:element name="root" type="xs:int" dfdl:inputValueCalc="{ dfdlx:inputTypeCalc('tns:nonExistantTypeCalc', 0) }"/>
 
   </tdml:defineSchema>
 
@@ -421,4 +434,76 @@
     </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 a and 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>{http://example.com}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>{http://example.com}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 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 5dc3cf2..8a4d856 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
@@ -50,19 +50,19 @@
     <xs:restriction base="xs:int"/>
   </xs:simpleType>
 
-  <xs:simpleType name="AbstractIntToMulitiply2" dfdlx:repType="xs:int" dfdlx:inputTypeCalc="{ dfdlx:repTypeValueInt() * 2 }">
+  <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:repTypeValueString()) }">
+  <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:logicalTypeValueInt() * 2 }">
+  <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:logicalTypeValueInt())) }">
+  <xs:simpleType name="AbstractPrefixedStringFromInt" dfdlx:repType="xs:string" dfdlx:outputTypeCalc="{ fn:concat('x',xs:string(dfdlx:logicalTypeValue())) }">
     <xs:restriction base="xs:int"/>
   </xs:simpleType>
 
@@ -73,27 +73,27 @@
     </xs:restriction>
   </xs:simpleType>
 
-  <xs:element name="inputTypeCalcInt_01" type="xs:int" dfdl:inputValueCalc="{ dfdlx:inputTypeCalcInt('tns:AbstractIntTo1', 7) }" />
-  <xs:element name="inputTypeCalcString_01" type="xs:string" dfdl:inputValueCalc="{ dfdlx:inputTypeCalcString('tns:AbstractIntToXYZ', 7) }" />
+  <xs:element name="inputTypeCalcInt_01" type="xs:int" dfdl:inputValueCalc="{ dfdlx:inputTypeCalc('tns:AbstractIntTo1', 7) }" />
+  <xs:element name="inputTypeCalcString_01" type="xs:string" dfdl:inputValueCalc="{ dfdlx:inputTypeCalc('tns:AbstractIntToXYZ', 7) }" />
 
   <xs:element name="outputTypeCalcInt_01">
     <xs:complexType>
       <xs:sequence>
-        <xs:element name="inner" type="tns:uint8" dfdl:outputValueCalc="{ dfdlx:outputTypeCalcInt('tns:Abstract1FromInt', 7) }" />
+        <xs:element name="inner" type="tns:uint8" dfdl:outputValueCalc="{ dfdlx:outputTypeCalc('tns:Abstract1FromInt', 7) }" />
       </xs:sequence>
     </xs:complexType>
   </xs:element>
-  <xs:element name="outputTypeCalcString_01" type="xs:string" dfdl:inputValueCalc="{ dfdlx:outputTypeCalcString('tns:AbstractXYZFromInt', 7) }" />
-  <xs:element name="repTypeValueInt_01" type="xs:int" dfdl:inputValueCalc="{ dfdlx:inputTypeCalcInt('tns:AbstractIntToMulitiply2', 7) }" />
-  <xs:element name="repTypeValueString_01" type="xs:string" dfdl:inputValueCalc="{ dfdlx:inputTypeCalcString('tns:AbstractStringToPrefixedString', 'y') }" />
+  <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:outputTypeCalcInt('tns:AbstractMulitiply2FromInt', 7) }" />
+    dfdl:inputValueCalc="{ dfdlx:outputTypeCalc('tns:AbstractMulitiply2FromInt', 7) }" />
   <xs:element name="logicalTypeValueString_01" dfdlx:parseUnparsePolicy="parseOnly" type="xs:string" 
-    dfdl:inputValueCalc="{ dfdlx:outputTypeCalcString('tns:AbstractPrefixedStringFromInt', 7) }" />
+    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:outputTypeCalcNextSiblingInt() }"/>
+        <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>
@@ -101,13 +101,13 @@
   <xs:element name="outputTypeCalcNextSiblingString_01">
     <xs:complexType>
       <xs:sequence>
-        <xs:element name="raw" type="xs:string" dfdl:outputValueCalc="{ dfdlx:outputTypeCalcNextSiblingString() }"/>
+        <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:inputTypeCalcString('AbstractIntToStringByKeyset',0)}"/>
+  <xs:element name="abstractIntToStringByKeyset_01" type="xs:string" dfdl:inputValueCalc="{dfdlx:inputTypeCalc('AbstractIntToStringByKeyset',0)}"/>
 
   </tdml:defineSchema>
 
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 11b1e60..30c66a7 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
@@ -85,14 +85,14 @@
   @Test def test_typeCalcDispatch_typeError_06() { fnErrRunner.runOneTest("typeCalcDispatch_typeError_06") }
   @Test def test_typeCalcDispatch_typeError_07() { fnErrRunner.runOneTest("typeCalcDispatch_typeError_07") }
   @Test def test_typeCalcDispatch_typeError_08() { fnErrRunner.runOneTest("typeCalcDispatch_typeError_08") }
-  @Test def test_typeCalcDispatch_typeError_09() { fnErrRunner.runOneTest("typeCalcDispatch_typeError_09") }
-  @Test def test_typeCalcDispatch_typeError_10() { fnErrRunner.runOneTest("typeCalcDispatch_typeError_10") }
-  @Test def test_typeCalcDispatch_typeError_11() { fnErrRunner.runOneTest("typeCalcDispatch_typeError_11") }
-  @Test def test_typeCalcDispatch_typeError_12() { fnErrRunner.runOneTest("typeCalcDispatch_typeError_12") }
   @Test def test_repTypeValue_bad_context_01() { fnErrRunner.runOneTest("repTypeValue_bad_context_01") }
   @Test def test_repTypeValue_bad_context_02() { fnErrRunner.runOneTest("repTypeValue_bad_context_02") }
   @Test def test_logicalTypeValue_bad_context_01() { fnErrRunner.runOneTest("logicalTypeValue_bad_context_01") }
   @Test def test_logicalTypeValue_bad_context_02() { fnErrRunner.runOneTest("logicalTypeValue_bad_context_02") }
+  @Test def test_nextSibling_01() { fnErrRunner.runOneTest("nextSibling_01") }
+  @Test def test_nextSibling_02() { fnErrRunner.runOneTest("nextSibling_02") }
+  @Test def test_nextSibling_03() { fnErrRunner.runOneTest("nextSibling_03") }
+  @Test def test_nextSibling_04() { fnErrRunner.runOneTest("nextSibling_04") }
   @Test def test_nonexistant_reptype_01() { fnErrRunner.runOneTest("nonexistant_reptype_01") }
   @Test def test_nonexistantOutputTypeCalc_01() { fnErrRunner.runOneTest("nonexistantOutputTypeCalc_01") }
   @Test def test_nonexistantInputTypeCalc_01() { fnErrRunner.runOneTest("nonexistantInputTypeCalc_01") }