You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by sl...@apache.org on 2020/01/13 14:14:08 UTC

[incubator-daffodil] branch master updated: Refactor text numbers and related primitives/parsers

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 265fc9d  Refactor text numbers and related primitives/parsers
265fc9d is described below

commit 265fc9d1c3a43f8ee270cbd6c6035dfbcc0071cc
Author: Steve Lawrence <sl...@apache.org>
AuthorDate: Wed Dec 18 13:59:21 2019 -0500

    Refactor text numbers and related primitives/parsers
    
    For each text number parser, we allocated a helper which did things like
    check if a number was in a valid range, or convert a parsed number to
    the correct type. Many of the actions were actually static and aren't
    really specific to text numbers, but are more specific to the actual
    data type (e.g. int, float). This moves all that static information out
    of helpers and into NodeInfo Primitives.
    
    The information in the helper that isn't static is really just specific
    to the single text number parser, and so is just passed in directly to
    the parser. This also gets rid of the NumberFormatFactory and
    CacheDynamic stuff and replaces it with the more modern Evaluatable.
    
    This allows for complete removal of the helpers and even all the
    different text number primitives with type parameter, removing a lot of
    unnecessary duplication.
    
    This also led to the refactoring of other parts of code that do range
    checking, particularly DPath conversions. That removed a lot of
    duplicate range checking logic and instead uses the new range checker in
    NodeInfo. This also uncovered a handful of cases where we were too lax
    or incorrect in the DataValues that were being used (e.g. a dpath
    function should return xs:unsignedByte but returned a JLong instead of
    JShort). These changes make conversion much more strict about which
    numeric types are expected to enforce correctness. This also avoids
    unnecessary conversions since we now know exactly which types things
    should be.
    
    Additionally, it was discovered that binary numbers do not enforce range
    checking, so that is now checked and a PE created if a binary number is
    too large for the type. That is the only functional change here.
    
    DAFFODIL-942
---
 .../daffodil/grammar/ElementBaseGrammarMixin.scala | 356 ++---------
 .../grammar/primitives/PrimitivesTextNumber.scala  | 179 ++----
 .../grammar/primitives/PrimitivesZoned.scala       | 103 +---
 .../unparsers/ConvertTextNumberUnparser.scala      |  21 +-
 .../unparsers/ConvertZonedNumberUnparser.scala     |   9 +-
 .../org/apache/daffodil/infoset/DataValue.scala    |   5 +-
 .../org/apache/daffodil/infoset/DataValue.scala    |   3 +
 .../org/apache/daffodil/dpath/ConverterOps.scala   | 192 +++---
 .../org/apache/daffodil/dpath/ConverterOps3.scala  |  31 +-
 .../apache/daffodil/dpath/DFDLConstructors.scala   |  31 +-
 .../org/apache/daffodil/dpath/DFDLFunctions.scala  |   4 +-
 .../org/apache/daffodil/dpath/DFDLXFunctions.scala |   5 +-
 .../org/apache/daffodil/dpath/FNFunctions.scala    |  24 +-
 .../scala/org/apache/daffodil/dpath/NodeInfo.scala | 150 ++++-
 .../org/apache/daffodil/processors/Dynamic.scala   | 176 ------
 .../apache/daffodil/processors/EvTextNumber.scala  | 172 ++++++
 .../processors/parsers/BinaryBooleanParsers.scala  |   4 +-
 .../processors/parsers/BinaryNumberParsers.scala   |  15 +-
 .../processors/parsers/PrimitivesDateTime1.scala   |   4 +-
 .../processors/parsers/PrimitivesTextNumber1.scala | 679 ++-------------------
 .../processors/parsers/TextBooleanParser.scala     |   2 +-
 .../processors/parsers/ZonedTextParsers.scala      |  60 +-
 .../daffodil/extensions/lookAhead/lookAhead.tdml   |   8 +-
 .../section02/validation_errors/Validation.tdml    |  12 +-
 .../apache/daffodil/section05/facets/Facets.tdml   |   4 +-
 .../daffodil/section05/simple_types/Boolean.tdml   |   6 +-
 .../section05/simple_types/SimpleTypes.tdml        | 199 ++++--
 .../daffodil/section06/namespaces/namespaces.tdml  |  10 +-
 .../section12/aligned_data/Aligned_Data.tdml       |  27 +-
 .../length_properties/LengthProperties.tdml        |   8 +-
 .../text_number_props/TextNumberProps.tdml         |  42 +-
 .../org/apache/daffodil/section13/zoned/zoned.tdml |  14 +-
 .../section14/sequence_groups/SequenceGroup.tdml   |   5 +-
 .../sequence_groups/SequenceGroupDelimiters.tdml   |   6 +-
 .../choice_groups/ChoiceGroupInitiatedContent.tdml |   4 +-
 .../daffodil/section15/choice_groups/choice.tdml   |  12 +-
 .../section23/dfdl_functions/Functions.tdml        | 170 ++++--
 37 files changed, 1029 insertions(+), 1723 deletions(-)

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 3e129d4..1483659 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
@@ -597,338 +597,85 @@ trait ElementBaseGrammarMixin
     notYetImplemented("objectKind='chars'")
   }
 
-  private lazy val textInt = prod("textInt", impliedRepresentation == Representation.Text) {
-    standardTextInt || zonedTextInt
-  }
-
-  private lazy val textByte = prod("textByte", impliedRepresentation == Representation.Text) {
-    standardTextByte || zonedTextByte
-  }
-
-  private lazy val textShort = prod("textShort", impliedRepresentation == Representation.Text) {
-    standardTextShort || zonedTextShort
-  }
 
-  private lazy val textLong = prod("textLong", impliedRepresentation == Representation.Text) {
-    standardTextLong || zonedTextLong
-  }
+  private lazy val textNumber = textStandardNumber || textZonedNumber
 
-  private lazy val textInteger = prod("textInteger", impliedRepresentation == Representation.Text) {
-    standardTextInteger || zonedTextInteger
+  private lazy val textNonNumber = {
+    ConvertTextCombinator(this, stringValue, textConverter)
   }
 
-  private lazy val textDecimal = prod("textDecimal", impliedRepresentation == Representation.Text) {
-    standardTextDecimal || zonedTextDecimal
+  private lazy val textStandardNumber = prod("textStandardNumber", textNumberRep == TextNumberRep.Standard) {
+    ConvertTextCombinator(this, stringValue, textConverter)
   }
 
-  private lazy val textNonNegativeInteger = prod("textNonNegativeInteger", impliedRepresentation == Representation.Text) {
-    standardTextNonNegativeInteger || zonedTextNonNegativeInteger
+  private lazy val textZonedNumber = prod("textZonedNumber", textNumberRep == TextNumberRep.Zoned) {
+    ConvertZonedCombinator(this, stringValue, textZonedConverter)
   }
 
-  private lazy val textUnsignedInt = prod("textUnsignedInt", impliedRepresentation == Representation.Text) {
-    standardTextUnsignedInt || zonedTextUnsignedInt
-  }
+  private lazy val textConverter = {
+    primType match {
+      case _: NodeInfo.Numeric.Kind => ConvertTextNumberPrim(this)
+      case PrimType.Boolean => ConvertTextBooleanPrim(this)
+      case PrimType.Date => ConvertTextDatePrim(this)
+      case PrimType.Time => ConvertTextTimePrim(this)
+      case PrimType.DateTime => ConvertTextDateTimePrim(this)
 
-  private lazy val textUnsignedByte = prod("textUnsignedByte", impliedRepresentation == Representation.Text) {
-    standardTextUnsignedByte || zonedTextUnsignedByte
-  }
-
-  private lazy val textUnsignedShort = prod("textUnsignedShort", impliedRepresentation == Representation.Text) {
-    standardTextUnsignedShort || zonedTextUnsignedShort
+      case PrimType.HexBinary | PrimType.String | PrimType.AnyURI =>
+        Assert.invariantFailed("textConverter not to be used for binary or string types")
+    }
   }
 
-  private lazy val textUnsignedLong = prod("textUnsignedLong", impliedRepresentation == Representation.Text) {
-    standardTextUnsignedLong || zonedTextUnsignedLong
+  private lazy val textZonedConverter = {
+    primType match {
+      case PrimType.Double | PrimType.Float =>
+        SDE("dfdl:textNumberRep=\"zoned\" is not allowed for %s", primType.globalQName)
+      case _: NodeInfo.Numeric.Kind => ConvertZonedNumberPrim(this)
+      case PrimType.HexBinary | PrimType.Boolean | PrimType.Date | PrimType.Time | PrimType.DateTime | PrimType.AnyURI | PrimType.String =>
+        Assert.invariantFailed("textZonedConverter only to be used for numeric types")
+    }
   }
 
-  //
-  // We could now break it down by lengthKind, and have specialized primitives
-  // depending on the length kind.
-  //
-  private lazy val standardTextInteger = prod(
-    "standardTextInteger",
-    textNumberRep == TextNumberRep.Standard) { ConvertTextCombinator(this, stringValue, ConvertTextIntegerPrim(this)) }
-  private lazy val standardTextDecimal = prod(
-    "standardTextDecimal",
-    textNumberRep == TextNumberRep.Standard) { ConvertTextCombinator(this, stringValue, ConvertTextDecimalPrim(this)) }
-  private lazy val standardTextNonNegativeInteger = prod(
-    "standardTextNonNegativeInteger",
-    textNumberRep == TextNumberRep.Standard) { ConvertTextCombinator(this, stringValue, ConvertTextNonNegativeIntegerPrim(this)) }
-  private lazy val standardTextLong = prod(
-    "standardTextLong",
-    textNumberRep == TextNumberRep.Standard) { ConvertTextCombinator(this, stringValue, ConvertTextLongPrim(this)) }
-  private lazy val standardTextInt = prod(
-    "standardTextInt",
-    textNumberRep == TextNumberRep.Standard) { ConvertTextCombinator(this, stringValue, ConvertTextIntPrim(this)) }
-  private lazy val standardTextShort = prod(
-    "standardTextShort",
-    textNumberRep == TextNumberRep.Standard) { ConvertTextCombinator(this, stringValue, ConvertTextShortPrim(this)) }
-  private lazy val standardTextByte = prod(
-    "standardTextByte",
-    textNumberRep == TextNumberRep.Standard) { ConvertTextCombinator(this, stringValue, ConvertTextBytePrim(this)) }
-  private lazy val standardTextUnsignedLong = prod(
-    "standardTextUnsignedLong",
-    textNumberRep == TextNumberRep.Standard) { ConvertTextCombinator(this, stringValue, ConvertTextUnsignedLongPrim(this)) }
-  private lazy val standardTextUnsignedInt = prod(
-    "standardTextUnsignedInt",
-    textNumberRep == TextNumberRep.Standard) { ConvertTextCombinator(this, stringValue, ConvertTextUnsignedIntPrim(this)) }
-  private lazy val standardTextUnsignedShort = prod(
-    "standardTextUnsignedShort",
-    textNumberRep == TextNumberRep.Standard) { ConvertTextCombinator(this, stringValue, ConvertTextUnsignedShortPrim(this)) }
-  private lazy val standardTextUnsignedByte = prod(
-    "standardTextUnsignedByte",
-    textNumberRep == TextNumberRep.Standard) { ConvertTextCombinator(this, stringValue, ConvertTextUnsignedBytePrim(this)) }
-
-  private lazy val zonedTextInteger = prod(
-    "zonedTextInteger",
-    textNumberRep == TextNumberRep.Zoned) { ConvertZonedCombinator(this, stringValue, ConvertZonedIntegerPrim(this)) }
-  private lazy val zonedTextDecimal = prod(
-    "zonedTextDecimal",
-    textNumberRep == TextNumberRep.Zoned) { ConvertZonedCombinator(this, stringValue, ConvertZonedDecimalPrim(this)) }
-  private lazy val zonedTextNonNegativeInteger = prod(
-    "zonedTextNonNegativeInteger",
-    textNumberRep == TextNumberRep.Zoned) { ConvertZonedCombinator(this, stringValue, ConvertZonedNonNegativeIntegerPrim(this)) }
-  private lazy val zonedTextLong = prod(
-    "zonedTextLong",
-    textNumberRep == TextNumberRep.Zoned) { ConvertZonedCombinator(this, stringValue, ConvertZonedLongPrim(this)) }
-  private lazy val zonedTextInt = prod(
-    "zonedTextInt",
-    textNumberRep == TextNumberRep.Zoned) { ConvertZonedCombinator(this, stringValue, ConvertZonedIntPrim(this)) }
-  private lazy val zonedTextShort = prod(
-    "zonedTextShort",
-    textNumberRep == TextNumberRep.Zoned) { ConvertZonedCombinator(this, stringValue, ConvertZonedShortPrim(this)) }
-  private lazy val zonedTextByte = prod(
-    "zonedTextByte",
-    textNumberRep == TextNumberRep.Zoned) { ConvertZonedCombinator(this, stringValue, ConvertZonedBytePrim(this)) }
-  private lazy val zonedTextUnsignedLong = prod(
-    "zonedTextUnsignedLong",
-    textNumberRep == TextNumberRep.Zoned) { ConvertZonedCombinator(this, stringValue, ConvertZonedUnsignedLongPrim(this)) }
-  private lazy val zonedTextUnsignedInt = prod(
-    "zonedTextUnsignedInt",
-    textNumberRep == TextNumberRep.Zoned) { ConvertZonedCombinator(this, stringValue, ConvertZonedUnsignedIntPrim(this)) }
-  private lazy val zonedTextUnsignedShort = prod(
-    "zonedTextUnsignedShort",
-    textNumberRep == TextNumberRep.Zoned) { ConvertZonedCombinator(this, stringValue, ConvertZonedUnsignedShortPrim(this)) }
-  private lazy val zonedTextUnsignedByte = prod(
-    "zonedTextUnsignedByte",
-    textNumberRep == TextNumberRep.Zoned) { ConvertZonedCombinator(this, stringValue, ConvertZonedUnsignedBytePrim(this)) }
-
   private lazy val bcdKnownLengthCalendar = prod("bcdKnownLengthCalendar", binaryCalendarRep == BinaryCalendarRep.Bcd) {
-    bcdDateKnownLength || bcdTimeKnownLength || bcdDateTimeKnownLength
+    ConvertZonedCombinator(this, new BCDIntegerKnownLength(this, binaryNumberKnownLengthInBits), textConverter)
   }
   private lazy val bcdRuntimeLengthCalendar = prod("bcdRuntimeLengthCalendar", binaryCalendarRep == BinaryCalendarRep.Bcd) {
-    bcdDateRuntimeLength || bcdTimeRuntimeLength || bcdDateTimeRuntimeLength
+    ConvertZonedCombinator(this, new BCDIntegerRuntimeLength(this), textConverter)
   }
   private lazy val bcdDelimitedLengthCalendar = prod("bcdDelimitedLengthCalendar", binaryCalendarRep == BinaryCalendarRep.Bcd) {
-    bcdDateDelimitedLength || bcdTimeDelimitedLength || bcdDateTimeDelimitedLength
+    ConvertZonedCombinator(this, new BCDIntegerDelimitedEndOfData(this), textConverter)
   }
   private lazy val bcdPrefixedLengthCalendar = prod("bcdPrefixedLengthCalendar", binaryCalendarRep == BinaryCalendarRep.Bcd) {
-    bcdDatePrefixedLength || bcdTimePrefixedLength || bcdDateTimePrefixedLength
+    ConvertZonedCombinator(this, new BCDIntegerPrefixedLength(this), textConverter)
   }
 
-  // BCD calendar with known length
-  private lazy val bcdDateKnownLength = prod("bcdDateKnownLength", primType == PrimType.Date) {
-    ConvertZonedCombinator(this, new BCDIntegerKnownLength(this, binaryNumberKnownLengthInBits), ConvertTextDatePrim(this))
-  }
-  private lazy val bcdDateTimeKnownLength = prod("bcdDateTimeKnownLength", primType == PrimType.DateTime) {
-    ConvertZonedCombinator(this, new BCDIntegerKnownLength(this, binaryNumberKnownLengthInBits), ConvertTextDateTimePrim(this))
-  }
-  private lazy val bcdTimeKnownLength = prod("bcdTimeKnownLength", primType == PrimType.Time) {
-    ConvertZonedCombinator(this, new BCDIntegerKnownLength(this, binaryNumberKnownLengthInBits), ConvertTextTimePrim(this))
-  }
-
-  // BCD calendar with runtime length
-  private lazy val bcdDateRuntimeLength = prod("bcdDateRuntimeLength", primType == PrimType.Date) {
-    ConvertZonedCombinator(this, new BCDIntegerRuntimeLength(this), ConvertTextDatePrim(this))
-  }
-  private lazy val bcdDateTimeRuntimeLength = prod("bcdDateTimeRuntimeLength", primType == PrimType.DateTime) {
-    ConvertZonedCombinator(this, new BCDIntegerRuntimeLength(this), ConvertTextDateTimePrim(this))
-  }
-  private lazy val bcdTimeRuntimeLength = prod("bcdTimeRuntimeLength", primType == PrimType.Time) {
-    ConvertZonedCombinator(this, new BCDIntegerRuntimeLength(this), ConvertTextTimePrim(this))
-  }
-
-  // BCD calendar with delimited length
-  private lazy val bcdDateDelimitedLength = prod("bcdDateDelimitedLength", primType == PrimType.Date) {
-    ConvertZonedCombinator(this, new BCDIntegerDelimitedEndOfData(this), ConvertTextDatePrim(this))
-  }
-  private lazy val bcdDateTimeDelimitedLength = prod("bcdDateTimeDelimitedLength", primType == PrimType.DateTime) {
-    ConvertZonedCombinator(this, new BCDIntegerDelimitedEndOfData(this), ConvertTextDateTimePrim(this))
-  }
-  private lazy val bcdTimeDelimitedLength = prod("bcdTimeDelimitedLength", primType == PrimType.Time) {
-    ConvertZonedCombinator(this, new BCDIntegerDelimitedEndOfData(this), ConvertTextTimePrim(this))
-  }
-
-  // BCD calendar with prefixed length
-  private lazy val bcdDatePrefixedLength = prod("bcdDatePrefixedLength", primType == PrimType.Date) {
-    ConvertZonedCombinator(this, new BCDIntegerPrefixedLength(this), ConvertTextDatePrim(this))
-  }
-  private lazy val bcdDateTimePrefixedLength = prod("bcdDateTimePrefixedLength", primType == PrimType.DateTime) {
-    ConvertZonedCombinator(this, new BCDIntegerPrefixedLength(this), ConvertTextDateTimePrim(this))
-  }
-  private lazy val bcdTimePrefixedLength = prod("bcdTimePrefixedLength", primType == PrimType.Time) {
-    ConvertZonedCombinator(this, new BCDIntegerPrefixedLength(this), ConvertTextTimePrim(this))
-  }
 
   private lazy val ibm4690PackedKnownLengthCalendar = prod("ibm4690PackedKnownLengthCalendar", binaryCalendarRep == BinaryCalendarRep.Ibm4690Packed) {
-    ibm4690PackedDateKnownLength || ibm4690PackedTimeKnownLength || ibm4690PackedDateTimeKnownLength
+    ConvertZonedCombinator(this, new IBM4690PackedIntegerKnownLength(this, false, binaryNumberKnownLengthInBits), textConverter)
   }
   private lazy val ibm4690PackedRuntimeLengthCalendar = prod("ibm4690PackedRuntimeLengthCalendar", binaryCalendarRep == BinaryCalendarRep.Ibm4690Packed) {
-    ibm4690PackedDateRuntimeLength || ibm4690PackedTimeRuntimeLength || ibm4690PackedDateTimeRuntimeLength
+    ConvertZonedCombinator(this, new IBM4690PackedIntegerRuntimeLength(this, false), textConverter)
   }
   private lazy val ibm4690PackedDelimitedLengthCalendar = prod("ibm4690PackedDelimitedLengthCalendar", binaryCalendarRep == BinaryCalendarRep.Ibm4690Packed) {
-    ibm4690PackedDateDelimitedLength || ibm4690PackedTimeDelimitedLength || ibm4690PackedDateTimeDelimitedLength
+    ConvertZonedCombinator(this, new IBM4690PackedIntegerDelimitedEndOfData(this, false), textConverter)
   }
   private lazy val ibm4690PackedPrefixedLengthCalendar = prod("ibm4690PackedPrefixedLengthCalendar", binaryCalendarRep == BinaryCalendarRep.Ibm4690Packed) {
-    ibm4690PackedDatePrefixedLength || ibm4690PackedTimePrefixedLength || ibm4690PackedDateTimePrefixedLength
+    ConvertZonedCombinator(this, new IBM4690PackedIntegerPrefixedLength(this, false), textConverter)
   }
 
-  // ibm4690Packed calendar with known length
-  private lazy val ibm4690PackedDateKnownLength = prod("ibm4690PackedDateKnownLength", primType == PrimType.Date) {
-    ConvertZonedCombinator(this, new IBM4690PackedIntegerKnownLength(this, false, binaryNumberKnownLengthInBits), ConvertTextDatePrim(this))
-  }
-  private lazy val ibm4690PackedDateTimeKnownLength = prod("ibm4690PackedDateTimeKnownLength", primType == PrimType.DateTime) {
-    ConvertZonedCombinator(this, new IBM4690PackedIntegerKnownLength(this, false, binaryNumberKnownLengthInBits), ConvertTextDateTimePrim(this))
-  }
-  private lazy val ibm4690PackedTimeKnownLength = prod("ibm4690PackedTimeKnownLength", primType == PrimType.Time) {
-    ConvertZonedCombinator(this, new IBM4690PackedIntegerKnownLength(this, false, binaryNumberKnownLengthInBits), ConvertTextTimePrim(this))
-  }
-
-  // ibm4690Packed calendar with runtime length
-  private lazy val ibm4690PackedDateRuntimeLength = prod("ibm4690PackedDateRuntimeLength", primType == PrimType.Date) {
-    ConvertZonedCombinator(this, new IBM4690PackedIntegerRuntimeLength(this, false), ConvertTextDatePrim(this))
-  }
-  private lazy val ibm4690PackedDateTimeRuntimeLength = prod("ibm4690PackedDateTimeRuntimeLength", primType == PrimType.DateTime) {
-    ConvertZonedCombinator(this, new IBM4690PackedIntegerRuntimeLength(this, false), ConvertTextDateTimePrim(this))
-  }
-  private lazy val ibm4690PackedTimeRuntimeLength = prod("ibm4690PackedTimeRuntimeLength", primType == PrimType.Time) {
-    ConvertZonedCombinator(this, new IBM4690PackedIntegerRuntimeLength(this, false), ConvertTextTimePrim(this))
-  }
-
-  // ibm4690Packed calendar with delimited length
-  private lazy val ibm4690PackedDateDelimitedLength = prod("ibm4690PackedDateDelimitedLength", primType == PrimType.Date) {
-    ConvertZonedCombinator(this, new IBM4690PackedIntegerDelimitedEndOfData(this, false), ConvertTextDatePrim(this))
-  }
-  private lazy val ibm4690PackedDateTimeDelimitedLength = prod("ibm4690PackedDateTimeDelimitedLength", primType == PrimType.DateTime) {
-    ConvertZonedCombinator(this, new IBM4690PackedIntegerDelimitedEndOfData(this, false), ConvertTextDateTimePrim(this))
-  }
-  private lazy val ibm4690PackedTimeDelimitedLength = prod("ibm4690PackedTimeDelimitedLength", primType == PrimType.Time) {
-    ConvertZonedCombinator(this, new IBM4690PackedIntegerDelimitedEndOfData(this, false), ConvertTextTimePrim(this))
-  }
-
-  // ibm4690Packed calendar with prefixed length
-  private lazy val ibm4690PackedDatePrefixedLength = prod("ibm4690PackedDatePrefixedLength", primType == PrimType.Date) {
-    ConvertZonedCombinator(this, new IBM4690PackedIntegerPrefixedLength(this, false), ConvertTextDatePrim(this))
-  }
-  private lazy val ibm4690PackedDateTimePrefixedLength = prod("ibm4690PackedDateTimePrefixedLength", primType == PrimType.DateTime) {
-    ConvertZonedCombinator(this, new IBM4690PackedIntegerPrefixedLength(this, false), ConvertTextDateTimePrim(this))
-  }
-  private lazy val ibm4690PackedTimePrefixedLength = prod("ibm4690PackedTimePrefixedLength", primType == PrimType.Time) {
-    ConvertZonedCombinator(this, new IBM4690PackedIntegerPrefixedLength(this, false), ConvertTextTimePrim(this))
-  }
 
   private lazy val packedKnownLengthCalendar = prod("packedKnownLengthCalendar", binaryCalendarRep == BinaryCalendarRep.Packed) {
-    packedDateKnownLength || packedTimeKnownLength || packedDateTimeKnownLength
+    ConvertZonedCombinator(this, new PackedIntegerKnownLength(this, false, packedSignCodes, binaryNumberKnownLengthInBits), textConverter)
   }
   private lazy val packedRuntimeLengthCalendar = prod("packedRuntimeLengthCalendar", binaryCalendarRep == BinaryCalendarRep.Packed) {
-    packedDateRuntimeLength || packedTimeRuntimeLength || packedDateTimeRuntimeLength
+    ConvertZonedCombinator(this, new PackedIntegerRuntimeLength(this, false, packedSignCodes), textConverter)
   }
   private lazy val packedDelimitedLengthCalendar = prod("packedDelimitedLengthCalendar", binaryCalendarRep == BinaryCalendarRep.Packed) {
-    packedDateDelimitedLength || packedTimeDelimitedLength || packedDateTimeDelimitedLength
+    ConvertZonedCombinator(this, new PackedIntegerDelimitedEndOfData(this, false, packedSignCodes), textConverter)
   }
   private lazy val packedPrefixedLengthCalendar = prod("packedPrefixedLengthCalendar", binaryCalendarRep == BinaryCalendarRep.Packed) {
-    packedDatePrefixedLength || packedTimePrefixedLength || packedDateTimePrefixedLength
-  }
-
-  // Packed calendar with known length
-  private lazy val packedDateKnownLength = prod("packedDateKnownLength", primType == PrimType.Date) {
-    ConvertZonedCombinator(this, new PackedIntegerKnownLength(this, false, packedSignCodes, binaryNumberKnownLengthInBits), ConvertTextDatePrim(this))
-  }
-  private lazy val packedDateTimeKnownLength = prod("packedDateTimeKnownLength", primType == PrimType.DateTime) {
-    ConvertZonedCombinator(this, new PackedIntegerKnownLength(this, false, packedSignCodes, binaryNumberKnownLengthInBits), ConvertTextDateTimePrim(this))
-  }
-  private lazy val packedTimeKnownLength = prod("packedTimeKnownLength", primType == PrimType.Time) {
-    ConvertZonedCombinator(this, new PackedIntegerKnownLength(this, false, packedSignCodes, binaryNumberKnownLengthInBits), ConvertTextTimePrim(this))
-  }
-
-  // Packed calendar with runtime length
-  private lazy val packedDateRuntimeLength = prod("packedDateRuntimeLength", primType == PrimType.Date) {
-    ConvertZonedCombinator(this, new PackedIntegerRuntimeLength(this, false, packedSignCodes), ConvertTextDatePrim(this))
-  }
-  private lazy val packedDateTimeRuntimeLength = prod("packedDateTimeRuntimeLength", primType == PrimType.DateTime) {
-    ConvertZonedCombinator(this, new PackedIntegerRuntimeLength(this, false, packedSignCodes), ConvertTextDateTimePrim(this))
-  }
-  private lazy val packedTimeRuntimeLength = prod("packedTimeRuntimeLength", primType == PrimType.Time) {
-    ConvertZonedCombinator(this, new PackedIntegerRuntimeLength(this, false, packedSignCodes), ConvertTextTimePrim(this))
-  }
-
-  // Packed calendar with delimited length
-  private lazy val packedDateDelimitedLength = prod("packedDateDelimitedLength", primType == PrimType.Date) {
-    ConvertZonedCombinator(this, new PackedIntegerDelimitedEndOfData(this, false, packedSignCodes), ConvertTextDatePrim(this))
-  }
-  private lazy val packedDateTimeDelimitedLength = prod("packedDateTimeDelimitedLength", primType == PrimType.DateTime) {
-    ConvertZonedCombinator(this, new PackedIntegerDelimitedEndOfData(this, false, packedSignCodes), ConvertTextDateTimePrim(this))
-  }
-  private lazy val packedTimeDelimitedLength = prod("packedTimeDelimitedLength", primType == PrimType.Time) {
-    ConvertZonedCombinator(this, new PackedIntegerDelimitedEndOfData(this, false, packedSignCodes), ConvertTextTimePrim(this))
-  }
-
-  // Packed calendar with prefixed length
-  private lazy val packedDatePrefixedLength = prod("packedDatePrefixedLength", primType == PrimType.Date) {
-    ConvertZonedCombinator(this, new PackedIntegerPrefixedLength(this, false, packedSignCodes), ConvertTextDatePrim(this))
+    ConvertZonedCombinator(this, new PackedIntegerPrefixedLength(this, false, packedSignCodes), textConverter)
   }
-  private lazy val packedDateTimePrefixedLength = prod("packedDateTimePrefixedLength", primType == PrimType.DateTime) {
-    ConvertZonedCombinator(this, new PackedIntegerPrefixedLength(this, false, packedSignCodes), ConvertTextDateTimePrim(this))
-  }
-  private lazy val packedTimePrefixedLength = prod("packedTimePrefixedLength", primType == PrimType.Time) {
-    ConvertZonedCombinator(this, new PackedIntegerPrefixedLength(this, false, packedSignCodes), ConvertTextTimePrim(this))
-  }
-
-  private lazy val textDouble = prod("textDouble", impliedRepresentation == Representation.Text) {
-    standardTextDouble || zonedTextDouble
-  }
-
-  //  private lazy val ibm390HexBinaryRepDouble = prod("ibm390HexBinaryRepDouble",
-  //    binaryFloatRep.isConstant &&
-  //      binaryFloatRep.constant == BinaryFloatRep.Ibm390Hex.toString) {
-  //      subsetError("ibm390Hex not supported")
-  //    }
-
-  private lazy val standardTextDouble = prod(
-    "standardTextDouble",
-    textNumberRep == TextNumberRep.Standard) { ConvertTextCombinator(this, stringValue, ConvertTextDoublePrim(this)) }
-
-  private lazy val zonedTextDouble = prod(
-    "zonedTextDouble",
-    textNumberRep == TextNumberRep.Zoned) { SDE("Zoned not supported for float and double") }
-
-  private lazy val textFloat = prod("textFloat", impliedRepresentation == Representation.Text) {
-    standardTextFloat || zonedTextFloat
-  }
-
-  private lazy val standardTextFloat = prod(
-    "standardTextFloat",
-    textNumberRep == TextNumberRep.Standard) { ConvertTextCombinator(this, stringValue, ConvertTextFloatPrim(this)) }
 
-  private lazy val zonedTextFloat = prod(
-    "zonedTextFloat",
-    textNumberRep == TextNumberRep.Zoned) { SDE("Zoned not supported for float and double") }
-
-  private lazy val textDate = prod("textDate", impliedRepresentation == Representation.Text) {
-    ConvertTextCombinator(this, stringValue, ConvertTextDatePrim(this))
-  }
-
-  private lazy val textTime = prod("textTime", impliedRepresentation == Representation.Text) {
-    ConvertTextCombinator(this, stringValue, ConvertTextTimePrim(this))
-  }
-
-  private lazy val textDateTime = prod("textDateTime", impliedRepresentation == Representation.Text) {
-    ConvertTextCombinator(this, stringValue, ConvertTextDateTimePrim(this))
-  }
-
-  private lazy val textBoolean = prod("textBoolean", impliedRepresentation == Representation.Text) {
-    ConvertTextCombinator(this, stringValue, ConvertTextBooleanPrim(this))
-  }
 
   def primType: PrimType
 
@@ -1133,31 +880,22 @@ trait ElementBaseGrammarMixin
     val pt = primType
     Assert.invariant(pt != PrimType.String)
     Assert.invariant(pt != PrimType.HexBinary)
+    Assert.invariant(pt != PrimType.AnyURI)
     Assert.invariant(impliedRepresentation == Representation.Text)
     schemaDefinitionWhen(
       lengthKind == LengthKind.Implicit,
       "Type %s cannot have lengthKind='implicit' when representation='text'",
       pt.name)
+
     val res = primType match {
-      case PrimType.Int => textInt
-      case PrimType.Byte => textByte
-      case PrimType.Short => textShort
-      case PrimType.Long => textLong
-      case PrimType.Integer => textInteger
-      case PrimType.Decimal => textDecimal
-      case PrimType.UnsignedInt => textUnsignedInt
-      case PrimType.UnsignedByte => textUnsignedByte
-      case PrimType.UnsignedShort => textUnsignedShort
-      case PrimType.UnsignedLong => textUnsignedLong
-      case PrimType.NonNegativeInteger => textNonNegativeInteger // Should be treated as unsigned xs:integer
-      case PrimType.Double => textDouble
-      case PrimType.Float => textFloat
-      case PrimType.HexBinary => Assert.invariantFailed("Primitive hexBinary must be representation='binary'.")
-      case PrimType.Boolean => textBoolean
-      case PrimType.Date => textDate
-      case PrimType.Time => textTime
-      case PrimType.DateTime => textDateTime
-      case _ => schemaDefinitionError("Unrecognized primitive type: " + primType.name)
+      case _: NodeInfo.Numeric.Kind => textNumber
+      case PrimType.Boolean => textNonNumber
+      case PrimType.Date => textNonNumber
+      case PrimType.Time => textNonNumber
+      case PrimType.DateTime => textNonNumber
+
+      case PrimType.HexBinary | PrimType.AnyURI | PrimType.String =>
+        Assert.invariantFailed("types handled in 'value' grammer element")
     }
     res
   }
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesTextNumber.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesTextNumber.scala
index 484082f..160e640 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesTextNumber.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesTextNumber.scala
@@ -17,41 +17,30 @@
 
 package org.apache.daffodil.grammar.primitives
 
+import com.ibm.icu.text.DecimalFormat
+
+import java.math.{ BigDecimal => JBigDecimal }
+import java.math.{ BigDecimal => JBigDecimal, BigInteger => JBigInt }
+import java.math.{ BigInteger => JBigInt }
+
+import org.apache.daffodil.cookers.EntityReplacer
+import org.apache.daffodil.dpath.NodeInfo.PrimType
 import org.apache.daffodil.dsom._
 import org.apache.daffodil.grammar.Gram
 import org.apache.daffodil.grammar.Terminal
+import org.apache.daffodil.processors.Delimiter
+import org.apache.daffodil.processors.Evaluatable
+import org.apache.daffodil.processors.parsers.ConvertTextCombinatorParser
+import org.apache.daffodil.processors.parsers.ConvertTextNumberParser
+import org.apache.daffodil.processors.parsers.Parser
+import org.apache.daffodil.processors.TextNumberFormatEv
+import org.apache.daffodil.processors.unparsers.ConvertTextCombinatorUnparser
+import org.apache.daffodil.processors.unparsers.ConvertTextNumberUnparser
+import org.apache.daffodil.processors.unparsers.Unparser
 import org.apache.daffodil.schema.annotation.props.gen.TextNumberRounding
 import org.apache.daffodil.util.Maybe
 import org.apache.daffodil.util.Maybe._
-import com.ibm.icu.text.DecimalFormat
-import org.apache.daffodil.processors.unparsers.Unparser
-import org.apache.daffodil.processors.unparsers.ConvertTextNumberUnparser
-import org.apache.daffodil.processors.unparsers.ConvertTextCombinatorUnparser
 import org.apache.daffodil.util.MaybeDouble
-import java.math.{ BigDecimal => JBigDecimal, BigInteger => JBigInt }
-import org.apache.daffodil.processors.parsers.ConvertTextByteParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextCombinatorParser
-import org.apache.daffodil.processors.parsers.ConvertTextDecimalParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextDoubleParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextFloatParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextIntParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextIntegerParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextLongParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextNonNegativeIntegerParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextNumberParser
-import org.apache.daffodil.processors.parsers.ConvertTextNumberParserUnparserHelperBase
-import org.apache.daffodil.processors.parsers.ConvertTextShortParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextUnsignedByteParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextUnsignedLongParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextUnsignedShortParserUnparserHelper
-import org.apache.daffodil.processors.Evaluatable
-import org.apache.daffodil.processors.parsers.NumberFormatFactoryBase
-import org.apache.daffodil.processors.parsers.NumberFormatFactoryDynamic
-import org.apache.daffodil.processors.parsers.NumberFormatFactoryStatic
-import java.math.{ BigDecimal => JBigDecimal }
-import java.math.{ BigInteger => JBigInt }
-import org.apache.daffodil.processors.parsers.ConvertTextUnsignedIntParserUnparserHelper
-import org.apache.daffodil.processors.parsers.Parser
 
 case class ConvertTextCombinator(e: ElementBase, value: Gram, converter: Gram)
   extends Terminal(e, !(value.isEmpty || converter.isEmpty)) {
@@ -61,14 +50,24 @@ case class ConvertTextCombinator(e: ElementBase, value: Gram, converter: Gram)
   override lazy val unparser = new ConvertTextCombinatorUnparser(e.termRuntimeData, value.unparser, converter.unparser)
 }
 
-abstract class ConvertTextNumberPrim[S](e: ElementBase)
+case class ConvertTextNumberPrim(e: ElementBase)
   extends Terminal(e, true) {
 
-  def helper: ConvertTextNumberParserUnparserHelperBase[S]
-
-  def numFormatFactory: NumberFormatFactoryBase[S] = {
-    val h = helper
+  val zeroRepsRaw = e.textStandardZeroRep.filter { _ != "" }
+  val zeroRepsRegex = zeroRepsRaw.map { zr =>
+    val d = new Delimiter()
+    d.compileDelimiter(zr, e.ignoreCaseBool)
+    // add '^' and '$' to require the regular expression to match the entire
+    // string as a zero rep instead of just part of it
+    val ignoreCaseStr = if (e.ignoreCaseBool) "(?i)" else ""
+    val regex = (ignoreCaseStr + "^" + d.delimRegExParseDelim + "$").r
+    regex
+  }
+  val zeroRepUnparse: Maybe[String] = zeroRepsRaw.headOption.map { zr =>
+    EntityReplacer { _.replaceForUnparse(zr) }
+  }
 
+  val textNumberFormatEv: TextNumberFormatEv = {
     val (pattern, patternStripped) = {
       val p = e.textNumberPattern
 
@@ -105,12 +104,10 @@ abstract class ConvertTextNumberPrim[S](e: ElementBase)
         case TextNumberRounding.Pattern => (MaybeDouble.Nope, Nope)
       }
 
-    val (infRep, nanRep) =
-      if (h.allowInfNaN) {
-        (One(e.textStandardInfinityRep), One(e.textStandardNaNRep))
-      } else {
-        (Nope, Nope)
-      }
+    val (infRep, nanRep) = e.primType match {
+      case PrimType.Double | PrimType.Float => (One(e.textStandardInfinityRep), One(e.textStandardNaNRep))
+      case _ => (Nope, Nope)
+    }
 
     // If the pattern contains any of these characters, we need to set both
     // group and decimal separators, even if the pattern doesn't contain the
@@ -122,7 +119,7 @@ abstract class ConvertTextNumberPrim[S](e: ElementBase)
       patternStripped.contains(",") || patternStripped.contains(".") ||
       patternStripped.contains("E") || patternStripped.contains("@")
 
-    val decSep: Maybe[Evaluatable[List[String]]] =
+    val decSep =
       if (requireDecGroupSeps) {
         One(e.textStandardDecimalSeparatorEv)
       } else {
@@ -136,91 +133,25 @@ abstract class ConvertTextNumberPrim[S](e: ElementBase)
         Nope
       }
 
-    val isConstant = ((decSep.isEmpty || decSep.get.isConstant) &&
-      (groupSep.isEmpty || groupSep.get.isConstant) &&
-      e.textStandardExponentRepEv.isConstant)
-
-    val nff = if (isConstant) {
-      new NumberFormatFactoryStatic[S](e.termRuntimeData, h,
-        decSep,
-        groupSep,
-        One(e.textStandardExponentRepEv),
-        infRep,
-        nanRep,
-        e.textNumberCheckPolicy,
-        pattern,
-        e.textNumberRounding,
-        roundingMode,
-        roundingIncrement)
-    } else {
-      new NumberFormatFactoryDynamic[S](e.termRuntimeData, h,
-        decSep,
-        groupSep,
-        One(e.textStandardExponentRepEv),
-        infRep,
-        nanRep,
-        e.textNumberCheckPolicy,
-        pattern,
-        e.textNumberRounding,
-        roundingMode,
-        roundingIncrement)
-    }
-    nff
+    val ev = new TextNumberFormatEv(
+      e.tci,
+      decSep,
+      groupSep,
+      One(e.textStandardExponentRepEv),
+      infRep,
+      nanRep,
+      e.textNumberCheckPolicy,
+      pattern,
+      e.textNumberRounding,
+      roundingMode,
+      roundingIncrement,
+      zeroRepsRaw,
+      e.primType)
+    ev.compile(tunable)
+    ev
   }
 
-  lazy val parser: Parser = new ConvertTextNumberParser[S](helper, numFormatFactory, e.elementRuntimeData)
-
-  override lazy val unparser: Unparser = new ConvertTextNumberUnparser[S](helper, numFormatFactory, e.elementRuntimeData)
-}
-
-case class ConvertTextIntegerPrim(e: ElementBase) extends ConvertTextNumberPrim[JBigInt](e) {
-  val helper = new ConvertTextIntegerParserUnparserHelper[JBigInt](e.textStandardZeroRep, e.ignoreCaseBool)
-}
-
-case class ConvertTextDecimalPrim(e: ElementBase) extends ConvertTextNumberPrim[JBigDecimal](e) {
-  val helper = new ConvertTextDecimalParserUnparserHelper[JBigDecimal](e.textStandardZeroRep, e.ignoreCaseBool)
-}
-
-case class ConvertTextNonNegativeIntegerPrim(e: ElementBase) extends ConvertTextNumberPrim[JBigInt](e) {
-  val helper = new ConvertTextNonNegativeIntegerParserUnparserHelper[JBigDecimal](e.textStandardZeroRep, e.ignoreCaseBool)
-}
-
-case class ConvertTextLongPrim(e: ElementBase) extends ConvertTextNumberPrim[Long](e) {
-  val helper = new ConvertTextLongParserUnparserHelper[Long](e.textStandardZeroRep, e.ignoreCaseBool)
-}
-
-case class ConvertTextIntPrim(e: ElementBase) extends ConvertTextNumberPrim[Int](e) {
-  val helper = new ConvertTextIntParserUnparserHelper[Int](e.textStandardZeroRep, e.ignoreCaseBool)
-}
-
-case class ConvertTextShortPrim(e: ElementBase) extends ConvertTextNumberPrim[Short](e) {
-  val helper = new ConvertTextShortParserUnparserHelper[Short](e.textStandardZeroRep, e.ignoreCaseBool)
-}
-
-case class ConvertTextBytePrim(e: ElementBase) extends ConvertTextNumberPrim[Byte](e) {
-  val helper = new ConvertTextByteParserUnparserHelper[Byte](e.textStandardZeroRep, e.ignoreCaseBool)
-}
-
-case class ConvertTextUnsignedLongPrim(e: ElementBase) extends ConvertTextNumberPrim[JBigInt](e) {
-  val helper = new ConvertTextUnsignedLongParserUnparserHelper[JBigInt](e.textStandardZeroRep, e.ignoreCaseBool)
-}
-
-case class ConvertTextUnsignedIntPrim(e: ElementBase) extends ConvertTextNumberPrim[Long](e) {
-  val helper = ConvertTextUnsignedIntParserUnparserHelper[Long](e.textStandardZeroRep, e.ignoreCaseBool)
-}
-
-case class ConvertTextUnsignedShortPrim(e: ElementBase) extends ConvertTextNumberPrim[Int](e) {
-  val helper = new ConvertTextUnsignedShortParserUnparserHelper[Int](e.textStandardZeroRep, e.ignoreCaseBool)
-}
-
-case class ConvertTextUnsignedBytePrim(e: ElementBase) extends ConvertTextNumberPrim[Short](e) {
-  val helper = new ConvertTextUnsignedByteParserUnparserHelper[Short](e.textStandardZeroRep, e.ignoreCaseBool)
-}
-
-case class ConvertTextDoublePrim(e: ElementBase) extends ConvertTextNumberPrim[Double](e) {
-  val helper = new ConvertTextDoubleParserUnparserHelper[Double](e.textStandardZeroRep, e.ignoreCaseBool)
-}
+  lazy val parser: Parser = new ConvertTextNumberParser(textNumberFormatEv, zeroRepsRegex, e.elementRuntimeData)
 
-case class ConvertTextFloatPrim(e: ElementBase) extends ConvertTextNumberPrim[Float](e) {
-  val helper = new ConvertTextFloatParserUnparserHelper[Float](e.textStandardZeroRep, e.ignoreCaseBool)
+  override lazy val unparser: Unparser = new ConvertTextNumberUnparser(textNumberFormatEv, zeroRepUnparse, e.elementRuntimeData)
 }
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesZoned.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesZoned.scala
index 6a8e684..e2e2e52 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesZoned.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/PrimitivesZoned.scala
@@ -17,40 +17,26 @@
 
 package org.apache.daffodil.grammar.primitives
 
-import org.apache.daffodil.dsom._
+
+import com.ibm.icu.text.DecimalFormat
+
 import org.apache.daffodil.dpath.NodeInfo.PrimType
+import org.apache.daffodil.dsom._
 import org.apache.daffodil.grammar.Gram
 import org.apache.daffodil.grammar.Terminal
-import com.ibm.icu.text.DecimalFormat
-import org.apache.daffodil.processors.unparsers.Unparser
-import org.apache.daffodil.processors.unparsers.ConvertZonedNumberUnparser
-import org.apache.daffodil.processors.unparsers.ConvertZonedCombinatorUnparser
-import org.apache.daffodil.processors.parsers.Parser
-import org.apache.daffodil.processors.parsers.ConvertZonedNumberParser
+import org.apache.daffodil.processors.TextNumberFormatEv
 import org.apache.daffodil.processors.parsers.ConvertZonedCombinatorParser
-import org.apache.daffodil.processors.parsers.ConvertTextByteParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextDecimalParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextIntParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextIntegerParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextLongParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextNonNegativeIntegerParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextNumberParserUnparserHelperBase
-import org.apache.daffodil.processors.parsers.ConvertTextShortParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextUnsignedByteParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextUnsignedLongParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextUnsignedShortParserUnparserHelper
-import org.apache.daffodil.processors.parsers.ConvertTextUnsignedIntParserUnparserHelper
-import org.apache.daffodil.processors.parsers.NumberFormatFactoryBase
-import org.apache.daffodil.processors.parsers.NumberFormatFactoryStatic
+import org.apache.daffodil.processors.parsers.ConvertZonedNumberParser
+import org.apache.daffodil.processors.parsers.Parser
+import org.apache.daffodil.processors.unparsers.ConvertZonedCombinatorUnparser
+import org.apache.daffodil.processors.unparsers.ConvertZonedNumberUnparser
+import org.apache.daffodil.processors.unparsers.Unparser
 import org.apache.daffodil.schema.annotation.props.gen.TextNumberCheckPolicy
 import org.apache.daffodil.schema.annotation.props.gen.TextNumberRounding
+import org.apache.daffodil.util.DecimalUtils.OverpunchLocation
 import org.apache.daffodil.util.Maybe
 import org.apache.daffodil.util.Maybe._
 import org.apache.daffodil.util.MaybeDouble
-import org.apache.daffodil.util.DecimalUtils.OverpunchLocation
-
-import java.math.{ BigDecimal => JBigDecimal }
-import java.math.{ BigInteger => JBigInt }
 
 case class ConvertZonedCombinator(e: ElementBase, value: Gram, converter: Gram)
   extends Terminal(e, !(value.isEmpty || converter.isEmpty)) {
@@ -60,14 +46,10 @@ case class ConvertZonedCombinator(e: ElementBase, value: Gram, converter: Gram)
   override lazy val unparser = new ConvertZonedCombinatorUnparser(e.termRuntimeData, value.unparser, converter.unparser)
 }
 
-abstract class ConvertZonedNumberPrim[S](e: ElementBase)
+case class ConvertZonedNumberPrim(e: ElementBase)
   extends Terminal(e, true) {
 
-  def helper: ConvertTextNumberParserUnparserHelperBase[S]
-
-  def numFormatFactory: NumberFormatFactoryBase[S] = {
-    val h = helper
-
+  val textNumberFormatEv: TextNumberFormatEv = {
     val pattern = {
       val p = e.textNumberPattern
 
@@ -137,8 +119,8 @@ abstract class ConvertZonedNumberPrim[S](e: ElementBase)
         case TextNumberRounding.Pattern => (MaybeDouble.Nope, Nope)
       }
 
-    val nff = new NumberFormatFactoryStatic[S](
-      e.termRuntimeData, h,
+    val ev = new TextNumberFormatEv(
+      e.tci,
       Maybe.Nope,
       Maybe.Nope,
       Maybe.Nope,
@@ -148,8 +130,11 @@ abstract class ConvertZonedNumberPrim[S](e: ElementBase)
       zonedPattern,
       e.textNumberRounding,
       roundingMode,
-      roundingIncrement)
-    nff
+      roundingIncrement,
+      Nil,
+      e.primType)
+    ev.compile(tunable)
+    ev
   }
 
   val opindex = e.textNumberPattern.indexOf('+')
@@ -162,51 +147,7 @@ abstract class ConvertZonedNumberPrim[S](e: ElementBase)
       OverpunchLocation.None
   }
 
-  lazy val parser: Parser = new ConvertZonedNumberParser[S](helper, opl, numFormatFactory, e.textZonedSignStyle, e.elementRuntimeData)
-
-  override lazy val unparser: Unparser = new ConvertZonedNumberUnparser[S](helper, opl, e.textZonedSignStyle, e.elementRuntimeData)
-}
-
-case class ConvertZonedIntegerPrim(e: ElementBase) extends ConvertZonedNumberPrim[JBigInt](e) {
-  val helper = new ConvertTextIntegerParserUnparserHelper[JBigInt](List(), false)
-}
-
-case class ConvertZonedDecimalPrim(e: ElementBase) extends ConvertZonedNumberPrim[JBigDecimal](e) {
-  val helper = new ConvertTextDecimalParserUnparserHelper[JBigDecimal](List(), false)
-}
-
-case class ConvertZonedNonNegativeIntegerPrim(e: ElementBase) extends ConvertZonedNumberPrim[JBigInt](e) {
-  val helper = new ConvertTextNonNegativeIntegerParserUnparserHelper[JBigDecimal](List(), false)
-}
-
-case class ConvertZonedLongPrim(e: ElementBase) extends ConvertZonedNumberPrim[Long](e) {
-  val helper = new ConvertTextLongParserUnparserHelper[Long](List(), false)
-}
-
-case class ConvertZonedIntPrim(e: ElementBase) extends ConvertZonedNumberPrim[Int](e) {
-  val helper = new ConvertTextIntParserUnparserHelper[Int](List(), false)
-}
-
-case class ConvertZonedShortPrim(e: ElementBase) extends ConvertZonedNumberPrim[Short](e) {
-  val helper = new ConvertTextShortParserUnparserHelper[Short](List(), false)
-}
-
-case class ConvertZonedBytePrim(e: ElementBase) extends ConvertZonedNumberPrim[Byte](e) {
-  val helper = new ConvertTextByteParserUnparserHelper[Byte](List(), false)
-}
-
-case class ConvertZonedUnsignedLongPrim(e: ElementBase) extends ConvertZonedNumberPrim[JBigInt](e) {
-  val helper = new ConvertTextUnsignedLongParserUnparserHelper[JBigInt](List(), false)
-}
-
-case class ConvertZonedUnsignedIntPrim(e: ElementBase) extends ConvertZonedNumberPrim[Long](e) {
-  val helper = ConvertTextUnsignedIntParserUnparserHelper[Long](List(), false)
-}
-
-case class ConvertZonedUnsignedShortPrim(e: ElementBase) extends ConvertZonedNumberPrim[Int](e) {
-  val helper = new ConvertTextUnsignedShortParserUnparserHelper[Int](List(), false)
-}
+  lazy val parser: Parser = new ConvertZonedNumberParser(opl, textNumberFormatEv, e.textZonedSignStyle, e.elementRuntimeData)
 
-case class ConvertZonedUnsignedBytePrim(e: ElementBase) extends ConvertZonedNumberPrim[Short](e) {
-  val helper = new ConvertTextUnsignedByteParserUnparserHelper[Short](List(), false)
+  override lazy val unparser: Unparser = new ConvertZonedNumberUnparser(opl, e.textZonedSignStyle, e.elementRuntimeData)
 }
diff --git a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ConvertTextNumberUnparser.scala b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ConvertTextNumberUnparser.scala
index 5a47ccf..d5edf7e 100644
--- a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ConvertTextNumberUnparser.scala
+++ b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ConvertTextNumberUnparser.scala
@@ -23,10 +23,8 @@ import java.lang.{ Float => JFloat }
 import org.apache.daffodil.processors._
 import org.apache.daffodil.util.Maybe
 import org.apache.daffodil.util.Maybe._
-import org.apache.daffodil.cookers.EntityReplacer
 import org.apache.daffodil.exceptions.Assert
-import org.apache.daffodil.processors.parsers.NumberFormatFactoryBase
-import org.apache.daffodil.processors.parsers.ConvertTextNumberParserUnparserHelperBase
+import org.apache.daffodil.processors.TextNumberFormatEv
 
 case class ConvertTextCombinatorUnparser(
   rd: TermRuntimeData,
@@ -47,21 +45,14 @@ case class ConvertTextCombinatorUnparser(
   }
 }
 
-case class ConvertTextNumberUnparser[S](
-  helper: ConvertTextNumberParserUnparserHelperBase[S],
-  nff: NumberFormatFactoryBase[S],
+case class ConvertTextNumberUnparser(
+  textNumberFormatEv: TextNumberFormatEv,
+  zeroRep: Maybe[String],
   override val context: ElementRuntimeData)
   extends PrimUnparser
   with ToBriefXMLImpl {
 
-  override lazy val runtimeDependencies = Vector()
-
-  override def toString = "to(xs:" + helper.xsdType + ")"
-  override lazy val childProcessors = Vector()
-
-  lazy val zeroRep: Maybe[String] = helper.zeroRepListRaw.headOption.map { zr =>
-    EntityReplacer { _.replaceForUnparse(zr) }
-  }
+  override lazy val runtimeDependencies = Vector(textNumberFormatEv)
 
   override def unparse(state: UState): Unit = {
 
@@ -73,7 +64,7 @@ case class ConvertTextNumberUnparser[S](
     // if we find this is not the case. Want something akin to:
     // Assert.invariant(value.isInstanceOf[S])
         
-    val df = nff.getNumFormat(state).get
+    val df = textNumberFormatEv.evaluate(state).get
     val dfs = df.getDecimalFormatSymbols
 
     val strRep = value.getAnyRef match {
diff --git a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ConvertZonedNumberUnparser.scala b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ConvertZonedNumberUnparser.scala
index 6bb5e3a..6745021 100644
--- a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ConvertZonedNumberUnparser.scala
+++ b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ConvertZonedNumberUnparser.scala
@@ -17,11 +17,10 @@
 
 package org.apache.daffodil.processors.unparsers
 
-import org.apache.daffodil.schema.annotation.props.gen.TextZonedSignStyle
 import org.apache.daffodil.processors._
+import org.apache.daffodil.schema.annotation.props.gen.TextZonedSignStyle
 import org.apache.daffodil.util.DecimalUtils
 import org.apache.daffodil.util.DecimalUtils.OverpunchLocation
-import org.apache.daffodil.processors.parsers.ConvertTextNumberParserUnparserHelperBase
 
 case class ConvertZonedCombinatorUnparser(
   rd: TermRuntimeData,
@@ -42,8 +41,7 @@ case class ConvertZonedCombinatorUnparser(
   }
 }
 
-case class ConvertZonedNumberUnparser[S](
-  helper: ConvertTextNumberParserUnparserHelperBase[S],
+case class ConvertZonedNumberUnparser(
   opl: OverpunchLocation.Value,
   zonedSignStyle: TextZonedSignStyle,
   override val context: ElementRuntimeData)
@@ -52,9 +50,6 @@ case class ConvertZonedNumberUnparser[S](
 
   override lazy val runtimeDependencies = Vector()
 
-  override def toString = "to(xs:" + helper.xsdType + ")"
-  override lazy val childProcessors = Vector()
-
   override def unparse(state: UState): Unit = {
 
     val node = state.currentInfosetNode.asSimple
diff --git a/daffodil-runtime1/src/main/scala-2.11/org/apache/daffodil/infoset/DataValue.scala b/daffodil-runtime1/src/main/scala-2.11/org/apache/daffodil/infoset/DataValue.scala
index 9ebeb7c..a311aef 100644
--- a/daffodil-runtime1/src/main/scala-2.11/org/apache/daffodil/infoset/DataValue.scala
+++ b/daffodil-runtime1/src/main/scala-2.11/org/apache/daffodil/infoset/DataValue.scala
@@ -92,9 +92,12 @@ final class DataValue[+T <: AnyRef, +X <: AnyRef] private (val v: T) extends Any
   @inline def getByteArray = v.asInstanceOf[BoxedByteArray].v
   @inline def getBoolean = v.asInstanceOf[JBoolean]
   @inline def getNumber = v.asInstanceOf[JNumber]
+  @inline def getByte = v.asInstanceOf[JByte]
+  @inline def getShort = v.asInstanceOf[JShort]
   @inline def getInt = v.asInstanceOf[JInt]
   @inline def getLong = v.asInstanceOf[JLong]
   @inline def getDouble = v.asInstanceOf[JDouble]
+  @inline def getFloat = v.asInstanceOf[JFloat]
   @inline def getBigInt = v.asInstanceOf[JBigInt]
   @inline def getString = v.asInstanceOf[JString]
   @inline def getURI = v.asInstanceOf[URI]
@@ -250,4 +253,4 @@ object DataValue {
 
 class BoxedByteArray(val v: Array[Byte]) extends Serializable {
 
-}
\ No newline at end of file
+}
diff --git a/daffodil-runtime1/src/main/scala-2.12/org/apache/daffodil/infoset/DataValue.scala b/daffodil-runtime1/src/main/scala-2.12/org/apache/daffodil/infoset/DataValue.scala
index f33d8d9..ef83ced 100644
--- a/daffodil-runtime1/src/main/scala-2.12/org/apache/daffodil/infoset/DataValue.scala
+++ b/daffodil-runtime1/src/main/scala-2.12/org/apache/daffodil/infoset/DataValue.scala
@@ -82,9 +82,12 @@ final class DataValue[+T <: AnyRef, +X <: AnyRef] private (val v: T) extends Any
   @inline def getByteArray = v.asInstanceOf[Array[Byte]]
   @inline def getBoolean = v.asInstanceOf[JBoolean]
   @inline def getNumber = v.asInstanceOf[JNumber]
+  @inline def getByte = v.asInstanceOf[JByte]
+  @inline def getShort = v.asInstanceOf[JShort]
   @inline def getInt = v.asInstanceOf[JInt]
   @inline def getLong = v.asInstanceOf[JLong]
   @inline def getDouble = v.asInstanceOf[JDouble]
+  @inline def getFloat = v.asInstanceOf[JFloat]
   @inline def getBigInt = v.asInstanceOf[JBigInt]
   @inline def getString = v.asInstanceOf[JString]
   @inline def getURI = v.asInstanceOf[URI]
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 a64a784..feea216 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
@@ -29,6 +29,8 @@ import java.math.{ BigInteger => JBigInt }
 
 import org.apache.daffodil.calendar.DFDLDate
 import org.apache.daffodil.calendar.DFDLDateTime
+import org.apache.daffodil.dpath.NodeInfo.PrimType
+import org.apache.daffodil.dpath.NodeInfo.PrimType.PrimNumeric
 import org.apache.daffodil.infoset.DataValue.DataValueBigDecimal
 import org.apache.daffodil.infoset.DataValue.DataValueBigInt
 import org.apache.daffodil.infoset.DataValue.DataValueBool
@@ -54,6 +56,16 @@ import org.apache.daffodil.util.Numbers.asLong
 import org.apache.daffodil.util.Numbers.asShort
 import org.apache.daffodil.xml.XMLUtils
 
+trait NumericRangeCheck {
+  protected val rangePrim: PrimNumeric
+  final protected def checkRange(num: Number) = {
+    if (!rangePrim.isValidRange(num)) {
+      val msg = "Value is out of range for %s type: %s".format(rangePrim.asInstanceOf[PrimType].globalQName, num)
+      throw new NumberFormatException(msg)
+    }
+  }
+}
+
 case object BooleanToLong extends Converter {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong = JLong.valueOf(if (asBoolean(a.getAnyRef) == true) 1L else 0L)
 }
@@ -87,40 +99,42 @@ case object DateToDateTime extends Converter {
   }
 }
 case object DecimalToInteger extends Converter {
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigInt = asBigDecimal(a.getAnyRef).toBigInteger()
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigInt = asBigInt(a.getBigDecimal)
 }
-case object DecimalToLong extends Converter {
-  val MAX_VALUE = JBigDecimal.valueOf(Long.MaxValue)
-  val MIN_VALUE = JBigDecimal.valueOf(Long.MinValue)
-
+case object DecimalToLong extends Converter with NumericRangeCheck {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong = {
-    val res = asBigDecimal(a.getAnyRef)
-    if (res.compareTo(MIN_VALUE) == -1 || res.compareTo(MAX_VALUE) == 1) throw new NumberFormatException("Value %s out of range for Long type.".format(res))
+    val res = a.getBigDecimal
+    checkRange(res)
     asLong(res)
   }
+  override protected val rangePrim = PrimType.Long
 }
 case object DecimalToDouble extends Converter {
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueDouble = asDouble(a.getAnyRef)
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueDouble = {
+    val res = a.getBigDecimal
+    // TODO: why no range check here?
+    asDouble(res)
+  }
 }
-case object DecimalToNonNegativeInteger extends Converter {
+case object DecimalToNonNegativeInteger extends Converter with NumericRangeCheck {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigInt = {
-    val res = asBigDecimal(a.getAnyRef)
-    if (res.compareTo(JBigDecimal.ZERO) == -1) throw new NumberFormatException("Negative value %s cannot be converted to a non-negative integer.".format(res))
-    res.toBigInteger()
+    val res = a.getBigDecimal
+    checkRange(res)
+    asBigInt(res)
   }
+  override protected val rangePrim = PrimType.NonNegativeInteger
 }
-case object DecimalToUnsignedLong extends Converter {
+case object DecimalToUnsignedLong extends Converter with NumericRangeCheck {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigInt = {
-    val res = asBigDecimal(a.getAnyRef).toBigInteger()
-    if (res.compareTo(JBigInt.ZERO) == -1) throw new NumberFormatException("Negative value %s cannot be converted to a non-negative integer.".format(res))
-
-    if (res.compareTo(NodeInfo.UnsignedLong.Max) == 1) throw new NumberFormatException("Value %s out of range for UnsignedLong type.".format(res))
-    else res
+    val res = a.getBigDecimal
+    checkRange(res)
+    asBigInt(res)
   }
+  override protected val rangePrim = PrimType.UnsignedLong
 }
 case object DecimalToBoolean extends Converter {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBool = {
-    val d = asBigDecimal(a.getAnyRef)
+    val d = a.getBigDecimal
     val comp = d.compareTo(JBigDecimal.ZERO)
     val b =
       if (comp == 0) false
@@ -129,34 +143,34 @@ case object DecimalToBoolean extends Converter {
   }
 }
 case object DoubleToDecimal extends Converter {
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigDecimal = JBigDecimal.valueOf(asDouble(a.getAnyRef))
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigDecimal = JBigDecimal.valueOf(a.getDouble)
 }
 case object DoubleToFloat extends Converter {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueFloat = {
-    val f = asFloat(a.getAnyRef)
-    f
+    val res = a.getDouble
+    // TODO: why no range check here?
+    asFloat(res)
   }
 }
-case object DoubleToLong extends Converter {
-  val MAX_VALUE = JBigDecimal.valueOf(Long.MaxValue)
-  val MIN_VALUE = JBigDecimal.valueOf(Long.MinValue)
+case object DoubleToLong extends Converter with NumericRangeCheck {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong = {
-    val res = asBigDecimal(a.getAnyRef)
-    if (res.compareTo(MIN_VALUE) == -1 || res.compareTo(MAX_VALUE) == 1) throw new NumberFormatException("Value %s out of range for Long type.".format(res))
-    asLong(a.getAnyRef)
+    val res = a.getDouble
+    checkRange(res)
+    asLong(res)
   }
+  override protected val rangePrim = PrimType.Long
 }
-case object DoubleToUnsignedLong extends Converter {
+case object DoubleToUnsignedLong extends Converter with NumericRangeCheck {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigInt = {
-    val res = asBigInt(a.getAnyRef)
-    if (res.compareTo(JBigInt.ZERO) == -1) throw new NumberFormatException("Negative value %s cannot be converted to an unsigned long.".format(res))
-    if (res.compareTo(NodeInfo.UnsignedLong.Max) == 1) throw new NumberFormatException("Value %s out of range for UnsignedLong type.".format(res))
-    else res
+    val res = a.getDouble
+    checkRange(res)
+    asBigInt(res)
   }
+  override protected val rangePrim = PrimType.UnsignedLong
 }
 case object DoubleToBoolean extends Converter {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBool = {
-    val d = asDouble(a.getAnyRef).doubleValue()
+    val d = a.getDouble
     val b =
       if (d == 0.0) false
       else if (d.isNaN()) false
@@ -165,104 +179,108 @@ case object DoubleToBoolean extends Converter {
   }
 }
 case object FloatToDouble extends Converter {
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueDouble = asDouble(a.getAnyRef)
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueDouble = asDouble(a.getFloat)
 }
 case object IntegerToDecimal extends Converter {
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigDecimal = new JBigDecimal(asBigInt(a.getAnyRef))
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigDecimal = new JBigDecimal(a.getBigInt)
 }
-case object IntegerToUnsignedLong extends Converter {
+case object IntegerToUnsignedLong extends Converter with NumericRangeCheck {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigInt = {
-    val res = asBigInt(a.getAnyRef)
-    if (res.compareTo(JBigInt.ZERO) == -1) throw new NumberFormatException("Negative value %s cannot be converted to an unsigned long.".format(res))
-    if (res.compareTo(NodeInfo.UnsignedLong.Max) == 1) throw new NumberFormatException("Value %s out of range for UnsignedLong type.".format(res))
-    else res
+    val res = a.getBigInt
+    checkRange(res)
+    asBigInt(res)
   }
+  override protected val rangePrim = PrimType.UnsignedLong
 }
 case object LongToBoolean extends Converter {
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBool = asBoolean(if (asLong(a.getAnyRef) == 0) false else true)
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBool = asBoolean(if (a.getLong == 0) false else true)
 }
-case object LongToByte extends Converter {
+case object LongToByte extends Converter with NumericRangeCheck {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueByte = {
-    val l = a.getLong
-    if (l > Byte.MaxValue || l < Byte.MinValue) throw new NumberFormatException("Value %s out of range for Byte type.".format(l))
-    asByte(l)
+    val res = a.getLong
+    checkRange(res)
+    asByte(res)
   }
+  override protected val rangePrim = PrimType.Byte
 }
 case object LongToDecimal extends Converter {
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigDecimal = JBigDecimal.valueOf(asLong(a.getAnyRef))
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigDecimal = asBigDecimal(a.getLong)
 }
 case object LongToDouble extends Converter {
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueDouble = asDouble(a.getAnyRef)
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueDouble = asDouble(a.getLong)
 }
 case object LongToFloat extends Converter {
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueFloat = asFloat(a.getAnyRef)
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueFloat = asFloat(a.getLong)
 }
-case object LongToInt extends Converter {
+case object LongToInt extends Converter with NumericRangeCheck {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueInt = {
-    val l = asLong(a.getAnyRef).longValue()
-    if (l > Int.MaxValue || l < Int.MinValue) throw new NumberFormatException("Value %s out of range for Int type.".format(l))
-    asInt(a.getAnyRef)
+    val res = a.getLong
+    checkRange(res)
+    asInt(res)
   }
+  override protected val rangePrim = PrimType.Int
 }
 
 case object LongToInteger extends Converter {
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigInt = JBigInt.valueOf(asLong(a.getAnyRef))
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigInt = asBigInt(a.getLong)
 }
 
-case object LongToShort extends Converter {
+case object LongToShort extends Converter with NumericRangeCheck {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueShort = {
-    val l = asLong(a.getAnyRef).longValue()
-    if (l > Short.MaxValue || l < Short.MinValue) throw new NumberFormatException("Value %s out of range for Short type.".format(l))
-    asShort(a.getAnyRef)
+    val res = a.getLong
+    checkRange(res)
+    asShort(res)
   }
+  override protected val rangePrim = PrimType.Short
 }
 
 case object LongToArrayIndex extends Converter {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong = {
-    val res = asLong(a.getAnyRef)
+    val res = a.getLong
     res
   }
 }
-case object LongToUnsignedByte extends Converter {
+case object LongToUnsignedByte extends Converter with NumericRangeCheck {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueShort = {
-    val res = asLong(a.getAnyRef).longValue()
-    if (res < 0) throw new NumberFormatException("Negative value %s cannot be converted to an unsigned byte.".format(res))
-    if (res > 255) throw new NumberFormatException("Value %s out of range for unsigned byte.".format(res))
-    asShort(a.getAnyRef)
+    val res = a.getLong
+    checkRange(res)
+    asShort(res)
   }
+  override protected val rangePrim = PrimType.UnsignedByte
 }
-case object LongToUnsignedInt extends Converter {
+case object LongToUnsignedInt extends Converter with NumericRangeCheck {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong = {
-    val r = asLong(a.getAnyRef)
-    val res = r.longValue()
-    if (res < 0) throw new NumberFormatException("Negative value %s cannot be converted to an unsigned int.".format(res))
-    if (res > 0xFFFFFFFFL) throw new NumberFormatException("Value %s out of range for unsigned int.".format(res))
-    r
+    val res = a.getLong
+    checkRange(res)
+    res
   }
+  override protected val rangePrim = PrimType.UnsignedInt
 }
-case object LongToUnsignedShort extends Converter {
+case object LongToUnsignedShort extends Converter with NumericRangeCheck {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueInt = {
-    val res = asLong(a.getAnyRef).longValue()
-    if (res < 0) throw new NumberFormatException("Negative value %s cannot be converted to an unsigned short.".format(res))
-    if (res > 65535) throw new NumberFormatException("Value %s out of range for unsigned short.".format(res))
-    asInt(a.getAnyRef)
+    val res = a.getLong
+    checkRange(res)
+    asInt(res)
   }
+  override protected val rangePrim = PrimType.UnsignedShort
 }
 
-case object LongToNonNegativeInteger extends Converter {
+case object LongToNonNegativeInteger extends Converter with NumericRangeCheck {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigInt = {
-    val res = JBigInt.valueOf(asLong(a.getAnyRef))
-    if (res.compareTo(JBigInt.ZERO) == -1) throw new NumberFormatException("Negative value %s cannot be converted to a non-negative integer.".format(res))
-    res
+    val res = a.getLong
+    checkRange(res)
+    asBigInt(res)
   }
+  override protected val rangePrim = PrimType.NonNegativeInteger
 }
 
-case object LongToUnsignedLong extends Converter {
+case object LongToUnsignedLong extends Converter with NumericRangeCheck {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigInt = {
-    val res = JBigInt.valueOf(asLong(a.getAnyRef))
-    if (res.compareTo(JBigInt.ZERO) == -1) throw new NumberFormatException("Negative value %s cannot be converted to a non-negative integer.".format(res))
-    else res
+    val res = a.getLong
+    checkRange(res)
+    asBigInt(res)
   }
+  override protected val rangePrim = PrimType.UnsignedLong
 }
 
 case object NumericToDouble extends Converter {
@@ -307,13 +325,13 @@ case object StringToLong extends Converter {
     res
   }
 }
-case object StringToUnsignedLong extends Converter {
+case object StringToUnsignedLong extends Converter with NumericRangeCheck {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigInt = {
     val res = new JBigInt(a.getString)
-    if (res.compareTo(JBigInt.ZERO) == -1) throw new NumberFormatException("Negative value %s cannot be converted to an unsigned long.".format(res))
-    if (res.compareTo(NodeInfo.UnsignedLong.Max) == 1) throw new NumberFormatException("Value %s out of range for UnsignedLong type.".format(res))
-    else res
+    checkRange(res)
+    res
   }
+  override protected val rangePrim = PrimType.UnsignedLong
 }
 
 /**
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/ConverterOps3.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/ConverterOps3.scala
index a680334..8969245 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/ConverterOps3.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/ConverterOps3.scala
@@ -19,6 +19,7 @@ package org.apache.daffodil.dpath
 
 import java.math.{ BigInteger => JBigInt }
 
+import org.apache.daffodil.dpath.NodeInfo.PrimType
 import org.apache.daffodil.infoset.DataValue.DataValueBigInt
 import org.apache.daffodil.infoset.DataValue.DataValueLong
 import org.apache.daffodil.infoset.DataValue.DataValuePrimitive
@@ -66,30 +67,28 @@ case object HexStringToUnsignedLong extends Converter {
     res
   }
 }
-case object BigIntToLong extends Converter {
-  val MAX_VALUE = JBigInt.valueOf(Long.MaxValue)
-  val MIN_VALUE = JBigInt.valueOf(Long.MinValue)
+case object IntegerToLong extends Converter with NumericRangeCheck {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong = {
-    val res = asBigInt(a.getAnyRef)
-    if (res.compareTo(MIN_VALUE) == -1 || res.compareTo(MAX_VALUE) == 1) throw new NumberFormatException("Value %s out of range for Long type.".format(res))
+    val res = a.getBigInt
+    checkRange(res)
     asLong(res)
   }
+  override protected val rangePrim = PrimType.Long
 }
 case object IntToLong extends Converter {
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong = asLong(a.getAnyRef)
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong = asLong(a.getInt)
 }
-case object UnsignedLongToLong extends Converter {
-  val MAX_VALUE = JBigInt.valueOf(Long.MaxValue)
-  val MIN_VALUE = JBigInt.valueOf(Long.MinValue)
+case object UnsignedLongToLong extends Converter with NumericRangeCheck {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong = {
-    val res = asBigInt(a.getAnyRef)
-    if (res.compareTo(MIN_VALUE) == -1 || res.compareTo(MAX_VALUE) == 1) throw new NumberFormatException("Value %s out of range for Long type.".format(res))
+    val res = a.getBigInt
+    checkRange(res)
     asLong(res)
   }
+  override protected val rangePrim = PrimType.Long
 }
 case object UnsignedIntToLong extends Converter {
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong = {
-    asLong(a.getAnyRef)
+    a.getLong
   }
 }
 case object ArrayIndexToLong extends Converter {
@@ -98,14 +97,14 @@ case object ArrayIndexToLong extends Converter {
   }
 }
 case object ShortToLong extends Converter {
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong = asLong(a.getAnyRef)
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong = asLong(a.getShort)
 }
 case object UnsignedShortToLong extends Converter {
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong = asLong(a.getAnyRef)
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong = asLong(a.getInt)
 }
 case object ByteToLong extends Converter {
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong = asLong(a.getAnyRef)
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong = asLong(a.getByte)
 }
 case object UnsignedByteToLong extends Converter {
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong = asLong(a.getAnyRef)
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong = asLong(a.getShort)
 }
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLConstructors.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLConstructors.scala
index 611b6cb..49a0cff 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLConstructors.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLConstructors.scala
@@ -45,17 +45,19 @@ abstract class DFDLConstructorFunction(recipe: CompiledDPath, argType: NodeInfo.
   protected def convert(longValue: DataValueLong, dstate: DState): DataValuePrimitive
 
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValuePrimitive = {
-    val long:DataValueLong = a.getAnyRef match {
-      case _: JByte | _: JShort | _: JInt => IntToLong.computeValue(a, dstate)
+    val long: DataValueLong = a.getAnyRef match {
+      case _: JByte => ByteToLong.computeValue(a, dstate)
+      case _: JShort => ShortToLong.computeValue(a, dstate)
+      case _: JInt => IntToLong.computeValue(a, dstate)
       case l: JLong => l
       case s: String if s.startsWith("x") => {
         val hexStr = s.substring(1)
         if (hexStr.length > maxHexDigits) throw new NumberFormatException(hexMsg.format(hexStr.length))
         HexStringToLong.computeValue(hexStr, dstate)
       }
-      case s: String => StringToLong.computeValue(s, dstate)
-      case bi: JBigInt => BigIntToLong.computeValue(bi, dstate)
-      case bd: JBigDecimal if (bd.remainder(JBigDecimal.ONE) == JBigDecimal.ZERO) => BigIntToLong.computeValue(bd.toBigInteger(), dstate)
+      case _: String => StringToLong.computeValue(a, dstate)
+      case _: JBigInt => IntegerToLong.computeValue(a, dstate)
+      case _: JBigDecimal => DecimalToLong.computeValue(a, dstate)
       case hb: Array[Byte] => {
         val str = "0x" + HexBinaryToString.computeValue(hb, dstate).getString
         throw new NumberFormatException(nfeMsg.format(str))
@@ -198,15 +200,26 @@ case class DFDLUnsignedLong(recipe: CompiledDPath, argType: NodeInfo.Kind)
 
   override def computeValue(a: DataValuePrimitive, dstate: DState): DataValuePrimitive = {
     val ulong: DataValuePrimitive = a.getAnyRef match {
-      case _: JByte | _: JShort | _: JInt => IntegerToUnsignedLong.computeValue(a, dstate)
+      case _: JByte => {
+        val l = ByteToLong.computeValue(a, dstate)
+        LongToUnsignedLong.computeValue(l, dstate)
+      }
+      case _: JShort => {
+        val l = ShortToLong.computeValue(a, dstate)
+        LongToUnsignedLong.computeValue(l, dstate)
+      }
+      case _: JInt => {
+        val l = IntToLong.computeValue(a, dstate)
+        LongToUnsignedLong.computeValue(l, dstate)
+      }
       case s: String if s.startsWith("x") => {
         val hexStr = s.substring(1)
         if (hexStr.length > maxHexDigits) throw new NumberFormatException(hexMsg.format(hexStr.length))
         HexStringToUnsignedLong.computeValue(hexStr, dstate)
       }
-      case s: String => StringToUnsignedLong.computeValue(s, dstate)
-      case bi: JBigInt => IntegerToUnsignedLong.computeValue(bi, dstate)
-      case bd: JBigDecimal => IntegerToUnsignedLong.computeValue(bd, dstate)
+      case _: String => StringToUnsignedLong.computeValue(a, dstate)
+      case _: JBigInt => IntegerToUnsignedLong.computeValue(a, dstate)
+      case _: JBigDecimal => DecimalToUnsignedLong.computeValue(a, dstate)
       case x =>
         throw new NumberFormatException(nfeMsg.format(x))
     }
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLFunctions.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLFunctions.scala
index 0ed5484..f324d4f 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLFunctions.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLFunctions.scala
@@ -24,6 +24,7 @@ import org.apache.daffodil.exceptions.Assert
 import org.apache.daffodil.infoset.DataValue.DataValueBool
 import org.apache.daffodil.infoset.DataValue.DataValuePrimitive
 import org.apache.daffodil.infoset.DataValue.DataValueString
+import org.apache.daffodil.infoset.DataValue.DataValueShort
 
 case class DFDLCheckConstraints(recipe: CompiledDPath) extends RecipeOpWithSubRecipes(recipe) {
   override def run(dstate: DState) {
@@ -172,7 +173,8 @@ case class DFDLSetBits(bitRecipes: List[CompiledDPath]) extends RecipeOpWithSubR
       i += 1
       bitR = bitR.tail
     }
-    dstate.setCurrentValue(byteVal)
+    val res: DataValueShort = byteVal.toShort
+    dstate.setCurrentValue(res)
   }
 
   private def processValue(i: Int): Boolean = {
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLXFunctions.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLXFunctions.scala
index 3576e20..bb574c5 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLXFunctions.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DFDLXFunctions.scala
@@ -18,6 +18,7 @@
 package org.apache.daffodil.dpath
 
 import java.lang.{ Long => JLong }
+import java.math.{ BigInteger => JBigInt }
 
 import org.apache.daffodil.exceptions.Assert
 import org.apache.daffodil.infoset.DISimple
@@ -128,9 +129,9 @@ case class DFDLXLookAhead(recipes: List[CompiledDPath])
       val ans: DataValuePrimitive = if (bitSize > 63) {
         dis.getUnsignedBigInt(bitSize, pstate)
       } else if (bitSize == 0) {
-        JLong.valueOf(0)
+        JBigInt.ZERO
       } else {
-        JLong.valueOf(dis.getUnsignedLong(bitSize, pstate).longValue)
+        JBigInt.valueOf(dis.getUnsignedLong(bitSize, pstate).longValue)
       }
       dis.resetPos(mark)
       ans
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/FNFunctions.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/FNFunctions.scala
index dde6321..e8a03d4 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/FNFunctions.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/FNFunctions.scala
@@ -771,9 +771,9 @@ trait FNFromDateTimeKind {
 abstract class FNFromDateTime(recipe: CompiledDPath, argType: NodeInfo.Kind)
   extends FNOneArg(recipe, argType)
   with FNFromDateTimeKind {
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValuePrimitive = {
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueNumber = {
     a.getAnyRef match {
-      case dt: DFDLDateTime => dt.calendar.get(field)
+      case dt: DFDLDateTime => JLong.valueOf(dt.calendar.get(field))
       case _ => throw new NumberFormatException("fn:" + fieldName + "-from-dateTime only accepts xs:dateTime.")
     }
   }
@@ -782,9 +782,9 @@ abstract class FNFromDateTime(recipe: CompiledDPath, argType: NodeInfo.Kind)
 abstract class FNFromDate(recipe: CompiledDPath, argType: NodeInfo.Kind)
   extends FNOneArg(recipe, argType)
   with FNFromDateTimeKind {
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueInt = {
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueNumber = {
     a.getAnyRef match {
-      case d: DFDLDate => d.calendar.get(field)
+      case d: DFDLDate => JLong.valueOf(d.calendar.get(field))
       case _ => throw new NumberFormatException("fn:" + fieldName + "-from-date only accepts xs:date.")
     }
   }
@@ -793,9 +793,9 @@ abstract class FNFromDate(recipe: CompiledDPath, argType: NodeInfo.Kind)
 abstract class FNFromTime(recipe: CompiledDPath, argType: NodeInfo.Kind)
   extends FNOneArg(recipe, argType)
   with FNFromDateTimeKind {
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValuePrimitive = {
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueNumber = {
     a.getAnyRef match {
-      case t: DFDLTime => t.calendar.get(field)
+      case t: DFDLTime => JLong.valueOf(t.calendar.get(field))
       case _ => throw new NumberFormatException("fn:" + fieldName + "-from-time only accepts xs:time.")
     }
   }
@@ -810,7 +810,7 @@ case class FNMonthFromDateTime(recipe: CompiledDPath, argType: NodeInfo.Kind)
   extends FNFromDateTime(recipe, argType) {
   val fieldName = "month"
   val field = Calendar.MONTH
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueInt = asInt(super.computeValue(a, dstate).getAnyRef).intValue() + 1 // JAN 0
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong = super.computeValue(a, dstate).getLong + 1 // JAN 0
 }
 case class FNDayFromDateTime(recipe: CompiledDPath, argType: NodeInfo.Kind)
   extends FNFromDateTime(recipe, argType) {
@@ -832,7 +832,7 @@ case class FNSecondsFromDateTime(recipe: CompiledDPath, argType: NodeInfo.Kind)
   val fieldName = "seconds"
   val field = Calendar.SECOND
 
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueNumber = {
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigDecimal = {
     //
     // It matters that val res is declared to be type JNumber.
     //
@@ -861,7 +861,7 @@ case class FNSecondsFromDateTime(recipe: CompiledDPath, argType: NodeInfo.Kind)
       }
       case _ => throw new NumberFormatException("fn:" + fieldName + "-from-dateTime only accepts xs:dateTime.")
     }
-    res
+    asBigDecimal(res)
   }
 }
 
@@ -874,7 +874,7 @@ case class FNMonthFromDate(recipe: CompiledDPath, argType: NodeInfo.Kind)
   extends FNFromDate(recipe, argType) {
   val fieldName = "month"
   val field = Calendar.MONTH
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueInt = asInt(super.computeValue(a, dstate).getAnyRef).intValue() + 1 // JAN 0
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueLong = super.computeValue(a, dstate).getLong + 1 // JAN 0
 }
 case class FNDayFromDate(recipe: CompiledDPath, argType: NodeInfo.Kind)
   extends FNFromDate(recipe, argType) {
@@ -895,7 +895,7 @@ case class FNSecondsFromTime(recipe: CompiledDPath, argType: NodeInfo.Kind)
   extends FNFromTime(recipe, argType) {
   val fieldName = "seconds"
   val field = Calendar.SECOND
-  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueNumber = {
+  override def computeValue(a: DataValuePrimitive, dstate: DState): DataValueBigDecimal = {
     //
     // Please see the block comment in FNSecondsFromDateTime.computeValue
     //
@@ -913,7 +913,7 @@ case class FNSecondsFromTime(recipe: CompiledDPath, argType: NodeInfo.Kind)
       }
       case _ => throw new NumberFormatException("fn:" + fieldName + "-from-dateTime only accepts xs:dateTime.")
     }
-    res
+    asBigDecimal(res)
   }
 }
 
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 66f136b..a6e4880 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
@@ -26,13 +26,18 @@ import org.apache.daffodil.calendar.DFDLDateConversion
 import org.apache.daffodil.calendar.DFDLDateTimeConversion
 import org.apache.daffodil.calendar.DFDLTimeConversion
 import org.apache.daffodil.exceptions.Assert
+import org.apache.daffodil.infoset.DataValue.DataValueBigDecimal
+import org.apache.daffodil.infoset.DataValue.DataValueBigInt
 import org.apache.daffodil.infoset.DataValue.DataValueBool
 import org.apache.daffodil.infoset.DataValue.DataValueByte
 import org.apache.daffodil.infoset.DataValue.DataValueByteArray
 import org.apache.daffodil.infoset.DataValue.DataValueDate
 import org.apache.daffodil.infoset.DataValue.DataValueDateTime
+import org.apache.daffodil.infoset.DataValue.DataValueDouble
+import org.apache.daffodil.infoset.DataValue.DataValueFloat
 import org.apache.daffodil.infoset.DataValue.DataValueInt
 import org.apache.daffodil.infoset.DataValue.DataValueLong
+import org.apache.daffodil.infoset.DataValue.DataValueNumber
 import org.apache.daffodil.infoset.DataValue.DataValuePrimitive
 import org.apache.daffodil.infoset.DataValue.DataValueShort
 import org.apache.daffodil.infoset.DataValue.DataValueTime
@@ -123,8 +128,8 @@ object NodeInfo extends Enum {
     /**
      * When class name is isomorphic to the type name, compute automatically.
      */
-    protected lazy val pname = {
-      val cname = Misc.getNameFromClass(this)
+    override def name = {
+      val cname = super.name
       val first = cname(0).toLower
       val rest = cname.substring(1)
       first + rest
@@ -187,7 +192,7 @@ object NodeInfo extends Enum {
     // prefix the user defines for the XSD namespace.
     //
     lazy val globalQName: GlobalQName = this match {
-      case pt: PrimTypeNode => QName.createGlobal(name.toLowerCase(), XMLUtils.XSD_NAMESPACE, xsScope)
+      case pt: PrimTypeNode => QName.createGlobal(name, XMLUtils.XSD_NAMESPACE, xsScope)
       case _ => QName.createGlobal(name, NoNamespace, scala.xml.TopScope)
     }
 
@@ -430,7 +435,7 @@ object NodeInfo extends Enum {
     }
 
     def fromNameString(name: String): Option[PrimType] = {
-      allPrims.find { _.pname.toLowerCase == name.toLowerCase }
+      allPrims.find { _.name.toLowerCase == name.toLowerCase }
     }
 
     def fromNodeInfo(nodeInfo: NodeInfo.Kind): Option[PrimType] = {
@@ -439,8 +444,61 @@ object NodeInfo extends Enum {
       }
     }
 
+    trait PrimNumeric { self: Numeric.Kind =>
+      def isValidRange(n: Number): Boolean
+      def fromNumber(n: Number): DataValueNumber
+    }
+
+    // this should only be used for integer primitives that can fit inside a
+    // long (e.g. long, unsignedInt). Primitives larger than that should
+    // implement a custom isValidRange
+    trait PrimNumericInteger extends PrimNumeric { self: Numeric.Kind =>
+      val min: Long
+      val max: Long
+      private lazy val minBD = new JBigDecimal(min)
+      private lazy val maxBD = new JBigDecimal(max)
+
+      override def isValidRange(n: Number): Boolean = n match {
+        case bd: JBigDecimal => {
+          bd.compareTo(minBD) >= 0 && bd.compareTo(maxBD) <= 0
+        }
+        case bi: JBigInt => {
+          if (bi.bitLength > 63) {
+            // check against 63 since bitLength() doesn't count the sign bit
+            false
+          } else {
+            // bit length 63 or less means it can convert to a long without any
+            // truncation
+            val l = bi.longValue
+            l >= min && l <= max
+          }
+        }
+        case _ => {
+          val l = n.longValue
+          l >= min && l <= max
+        }
+      }
+    }
+
+    trait PrimNumericFloat extends PrimNumeric { self: Numeric.Kind =>
+      def min: Double
+      def max: Double
+      private lazy val minBD = new JBigDecimal(min)
+      private lazy val maxBD = new JBigDecimal(max)
+
+      def isValidRange(n: java.lang.Number): Boolean = n match {
+        case bd: JBigDecimal => {
+          bd.compareTo(minBD) >= 0 && bd.compareTo(maxBD) <= 0          
+        }
+        case _ => {
+          val d = n.doubleValue
+          !d.isNaN && d >= min && d <= max
+        }
+      }
+    }
+
     protected sealed trait FloatKind extends SignedNumeric.Kind
-    case object Float extends PrimTypeNode(SignedNumeric) with FloatKind {
+    case object Float extends PrimTypeNode(SignedNumeric) with FloatKind with PrimNumericFloat {
       type Kind = FloatKind
       override def fromXMLString(s: String) = {
         val f: JFloat = s match {
@@ -451,12 +509,15 @@ object NodeInfo extends Enum {
         }
         f
       }
+      override def fromNumber(n: Number): DataValueFloat = n.floatValue
+      override val min = -JFloat.MAX_VALUE.doubleValue
+      override val max = JFloat.MAX_VALUE.doubleValue
     }
 
     protected sealed trait DoubleKind extends SignedNumeric.Kind
-    case object Double extends PrimTypeNode(SignedNumeric) with DoubleKind {
+    case object Double extends PrimTypeNode(SignedNumeric) with DoubleKind with PrimNumericFloat {
       type Kind = DoubleKind
-      override def fromXMLString(s: String) = {
+      override def fromXMLString(s: String): DataValueDouble = {
         val d: JDouble = s match {
           case XMLUtils.PositiveInfinityString => scala.Double.PositiveInfinity
           case XMLUtils.NegativeInfinityString => scala.Double.NegativeInfinity
@@ -465,76 +526,113 @@ object NodeInfo extends Enum {
         }
         d
       }
+      override def fromNumber(n: Number): DataValueDouble = n.doubleValue
+      override val min = -JDouble.MAX_VALUE
+      override val max = JDouble.MAX_VALUE
     }
 
     protected sealed trait DecimalKind extends SignedNumeric.Kind
-    case object Decimal extends PrimTypeNode(SignedNumeric, List(Integer)) with DecimalKind {
+    case object Decimal extends PrimTypeNode(SignedNumeric, List(Integer)) with DecimalKind with PrimNumeric {
       type Kind = DecimalKind
-      override def fromXMLString(s: String) = new JBigDecimal(s)
+      override def fromXMLString(s: String): DataValueBigDecimal = new JBigDecimal(s)
+      override def fromNumber(n: Number): DataValueBigDecimal = new JBigDecimal(n.toString)
+      override def isValidRange(n: Number): Boolean = true
     }
 
     protected sealed trait IntegerKind extends Decimal.Kind
-    case object Integer extends PrimTypeNode(Decimal, List(Long, NonNegativeInteger)) with IntegerKind {
+    case object Integer extends PrimTypeNode(Decimal, List(Long, NonNegativeInteger)) with IntegerKind with PrimNumeric {
       type Kind = IntegerKind
-      override def fromXMLString(s: String) = new JBigInt(s)
+      override def fromXMLString(s: String): DataValueBigInt = new JBigInt(s)
+      override def fromNumber(n: Number): DataValueBigInt = new JBigInt(n.toString)
+      override def isValidRange(n: Number): Boolean = true
     }
 
     protected sealed trait LongKind extends Integer.Kind
-    case object Long extends PrimTypeNode(Integer, List(Int)) with LongKind {
+    case object Long extends PrimTypeNode(Integer, List(Int)) with LongKind with PrimNumericInteger {
       type Kind = LongKind
       override def fromXMLString(s: String): DataValueLong = s.toLong
+      override def fromNumber(n: Number): DataValueLong = n.longValue
+      override val min = JLong.MIN_VALUE
+      override val max = JLong.MAX_VALUE
     }
 
     protected sealed trait IntKind extends Long.Kind
-    case object Int extends PrimTypeNode(Long, List(Short)) with IntKind {
+    case object Int extends PrimTypeNode(Long, List(Short)) with IntKind with PrimNumericInteger {
       type Kind = IntKind
       override def fromXMLString(s: String): DataValueInt = s.toInt
+      override def fromNumber(n: Number): DataValueInt = n.intValue
+      override val min = JInt.MIN_VALUE.toLong
+      override val max = JInt.MAX_VALUE.toLong
     }
 
     protected sealed trait ShortKind extends Int.Kind
-    case object Short extends PrimTypeNode(Int, List(Byte)) with ShortKind {
+    case object Short extends PrimTypeNode(Int, List(Byte)) with ShortKind with PrimNumericInteger {
       type Kind = ShortKind
       override def fromXMLString(s: String): DataValueShort = s.toShort
+      override def fromNumber(n: Number): DataValueShort = n.shortValue
+      override val min = JShort.MIN_VALUE.toLong
+      override val max = JShort.MAX_VALUE.toLong
     }
 
     protected sealed trait ByteKind extends Short.Kind
-    case object Byte extends PrimTypeNode(Short) with ByteKind {
+    case object Byte extends PrimTypeNode(Short) with ByteKind with PrimNumericInteger {
       type Kind = ByteKind
       override def fromXMLString(s: String): DataValueByte = s.toByte
+      override def fromNumber(n: Number): DataValueByte = n.byteValue
+      override val min = JByte.MIN_VALUE.toLong
+      override val max = JByte.MAX_VALUE.toLong
     }
 
     protected sealed trait NonNegativeIntegerKind extends Integer.Kind
-    case object NonNegativeInteger extends PrimTypeNode(Integer, List(UnsignedLong)) with NonNegativeIntegerKind {
+    case object NonNegativeInteger extends PrimTypeNode(Integer, List(UnsignedLong)) with NonNegativeIntegerKind with PrimNumeric {
       type Kind = NonNegativeIntegerKind
-      override def fromXMLString(s: String) = new JBigInt(s)
+      override def fromXMLString(s: String): DataValueBigInt = new JBigInt(s)
+      override def fromNumber(n: Number): DataValueBigInt = new JBigInt(n.toString)
+      def isValidRange(n: Number): Boolean = n match {
+        case bi: JBigInt => bi.signum >= 0
+        case _ => n.longValue >= 0
+      }
     }
 
     protected sealed trait UnsignedLongKind extends NonNegativeInteger.Kind
-    case object UnsignedLong extends PrimTypeNode(NonNegativeInteger, List(UnsignedInt)) with UnsignedLongKind {
+    case object UnsignedLong extends PrimTypeNode(NonNegativeInteger, List(UnsignedInt)) with UnsignedLongKind with PrimNumeric {
       type Kind = UnsignedLongKind
-      val Max = new JBigInt("18446744073709551615")
-      override def fromXMLString(s: String) = new JBigInt(s)
+      override def fromXMLString(s: String): DataValueBigInt = new JBigInt(s)
+      override def fromNumber(n: Number): DataValueBigInt = new JBigInt(n.toString)
+      def isValidRange(n: Number): Boolean = n match {
+        case bd: JBigDecimal => bd.signum >= 0 && bd.compareTo(maxBD) <= 0
+        case bi: JBigInt => bi.signum >= 0 && bi.compareTo(max) <= 0
+        case _ => n.longValue >= 0
+      }
+      val max = new JBigInt(1, scala.Array.fill(8)(0xFF.toByte))
+      val maxBD = new JBigDecimal(max)
     }
 
     protected sealed trait UnsignedIntKind extends UnsignedLong.Kind
-    case object UnsignedInt extends PrimTypeNode(UnsignedLong, List(UnsignedShort, ArrayIndex)) with UnsignedIntKind {
+    case object UnsignedInt extends PrimTypeNode(UnsignedLong, List(UnsignedShort, ArrayIndex)) with UnsignedIntKind with PrimNumericInteger {
       type Kind = UnsignedIntKind
-      val Max = 4294967295L
       override def fromXMLString(s: String): DataValueLong = s.toLong
+      override def fromNumber(n: Number): DataValueLong = n.longValue
+      override val min = 0L
+      override val max = 0xFFFFFFFFL
     }
 
     protected sealed trait UnsignedShortKind extends UnsignedInt.Kind
-    case object UnsignedShort extends PrimTypeNode(UnsignedInt, List(UnsignedByte)) with UnsignedShortKind {
+    case object UnsignedShort extends PrimTypeNode(UnsignedInt, List(UnsignedByte)) with UnsignedShortKind with PrimNumericInteger {
       type Kind = UnsignedShortKind
-      val Max = 65535
       override def fromXMLString(s: String): DataValueInt = s.toInt
+      override def fromNumber(n: Number): DataValueInt = n.intValue
+      override val min = 0L
+      override val max = 0xFFFFL
     }
 
     protected sealed trait UnsignedByteKind extends UnsignedShort.Kind
-    case object UnsignedByte extends PrimTypeNode(UnsignedShort) with UnsignedByteKind {
+    case object UnsignedByte extends PrimTypeNode(UnsignedShort) with UnsignedByteKind with PrimNumericInteger {
       type Kind = UnsignedByteKind
-      val Max = 255
       override def fromXMLString(s: String): DataValueShort = s.toShort
+      override def fromNumber(n: Number): DataValueShort = n.shortValue
+      override val min = 0L
+      override val max = 0xFFL
     }
 
     protected sealed trait StringKind extends AnyAtomic.Kind
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/Dynamic.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/Dynamic.scala
deleted file mode 100644
index ce89da4..0000000
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/Dynamic.scala
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * 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.processors
-
-import org.apache.daffodil.util.Maybe
-import org.apache.daffodil.util.Maybe._
-
-/**
- * Takes a compiled expression and a conversion, and if the expression is a constant,
- * runs the conversion once saving the converted result. This saves work if this
- * happens at compilation time, not runtime.
- *
- * If the expression is dynamic, then
- * it runs the expression then the conversion once, and saves the result.
- *
- * Note that the "only once" aspect of this isn't terribly important, as one would not
- * expect parse/unparse operations to go back and ask for these expressions repeatedly. They
- * should be keeping it in a local val.
- */
-trait Dynamic {
-
-  // TODO: Performance - is this cache necessary? Seems to only be used in text number format
-  // situations. Why would any of these be referenced more than once in parse or unparse of a simple
-  // text number type element?  (Can't these just be lazy val on the infoset element then?)
-
-  // TODO: Performance - we should consider avoiding using an Either object here since they are
-  // allocated every time this is called. Getting allocation down to where meaningful and necessary
-  // objects are allocated is important, and little tuples and Some(..) and Right/Left objects
-  // are not created makes a great deal of performance difference, albeit at the cost of making the
-  // code slighly more clumsy.
-
-  // We can use an AnyRef, and use either a value or a compiled expression, and methods that embed
-  // the cast, answer isExpression or isValue, etc.
-  // i.e, Create a value class named EitherOr that plays the same tricks as Maybe. Probably has to be
-  // special for CompiledExpression because we have to have a non-generic thing we can test for
-  // isInstanceOf that isn't erased. (Should build this right into compiled expression - i.e.,
-  // have evaluate method and getCache() method which returns object which has evaluate() also, but caches))
-  //
-  // However, we still have the box/unbox problem if the values of these are numbers. May not matter
-  // as these caches are not hit a lot.
-  //
-
-  //
-  // TODO: Complexity - seems excessively complex
-  //
-  // Dynamic is a mixin. It's used only in two places - escape schemes (because escChar and escescChar)
-  // and text number formats.
-  //
-  // The type A appears only as String, List[Char], Character. Generic [A] type may be overkill. Or
-  // generic should just call a common thing that is wired for String, List[Char] or Character, and has the
-  // converter built into it. So no function object needs to be passed, etc.
-  //
-  // There shouldn't be a need for NumFormat static and dynamic variants. That's a redundant distinction
-  // that is being hidden at this level in theory. Yet there is the static/dynamic distinction being made
-  // at that level also.
-  //
-
-  // We can use an AnyRef, and use either a value or a compiled expression, and methods that embed
-  // the cast, answer isExpression or isValue, etc.
-  // i.e, Create a value class named EitherOr that plays the same tricks as Maybe. Probably has to be
-  // special for CompiledExpression because we have to have a non-generic thing we can test for
-  // isInstanceOf that isn't erased. (Should build this right into compiled expression - i.e.,
-  // have evaluate method and getCache() method which returns object which has evaluate() also, but caches))
-  //
-  // However, we still have the box/unbox problem if the values of these are numbers. May not matter
-  // as these caches are not hit a lot.
-  //
-  // Dynamic is a mixin. It's used only in two places - escape schemes (because escChar and escescChar)
-  // and text number formats.
-  //
-  // The type A appears only as String, List[Char], Character. Generic [A] type may be overkill. Or
-  // generic should just call a common thing that is wired for String, List[Char] or Character, and has the
-  // converter built into it.
-  //
-  // There shouldn't be a need for NumFormat static and dynamic variants. That's a redundant distinction
-  // that is being hidden at this level in theory.
-  //
-  type CachedDynamic[A <: AnyRef, B <: AnyRef] = Either[Evaluatable[A], B]
-
-  // Returns an Either, with Right being the value of the constant, and the
-  // Left being the a non-constant compiled expression. The conv variable is
-  // used to convert the constant value to a more usable form, and perform and
-  // SDE checks. This should be called during initialization/compile time. Not
-  // during runtime.
-  def cacheConstantExpression[A <: AnyRef, B <: AnyRef](e: Evaluatable[A])(conv: (A) => B): CachedDynamic[A, B] = {
-    if (e.isConstant) {
-      val v: A = e.maybeConstant.get
-      Right(conv(v))
-    } else {
-      Left(e)
-    }
-  }
-
-  // Note: These method names used to be just overloads without the "Maybe" suffix.
-  // We don't really need them to be overloads, and some permutation of the Maybe[T] class
-  // with lots of inlining resulted in errors here because a Maybe[T] is an AnyVal aka
-  // value class. At compile time Maybe[Foo] and just Foo aren't distinguishable to resolve
-  // the overloading. So keep it simple, and just don't overload the names.
-  def cacheConstantExpressionMaybe[A <: AnyRef, B <: AnyRef](oe: Maybe[Evaluatable[A]])(conv: (A) => B): Maybe[CachedDynamic[A, B]] = {
-    //oe.map { e => cacheConstantExpression[A](e)(conv) }
-    if (oe.isDefined) One(cacheConstantExpression[A, B](oe.get)(conv))
-    else Nope
-  }
-
-  def cacheConstantExpression[A <: AnyRef, B <: AnyRef](listOfE: List[Evaluatable[A]])(conv: (A) => B): List[CachedDynamic[A, B]] = {
-    listOfE.map { e => cacheConstantExpression[A, B](e)(conv) }
-  }
-
-  // For any expression that couldn't be evaluated in cacheConstantExpression,
-  // this evaluates that. This is used to evaluate only runtime expressions.
-  // This also carries along PState that is modified during expression
-  // evaluation.
-  def evalWithConversion[A <: AnyRef, B <: AnyRef](s: ParseOrUnparseState, e: CachedDynamic[A, B])(conv: (ParseOrUnparseState, A) => B): B = {
-    e match {
-      case Right(r) => r
-      case Left(l) => {
-        val a: A = l.evaluate(s)
-        if (s.processorStatus ne Success) {
-          // evaluation failed
-          // we can't continue this code path
-          // have to throw out of here
-          throw s.processorStatus.asInstanceOf[Failure].cause
-        }
-        val b: B = conv(s, a)
-        b
-      }
-    }
-  }
-
-  def evalWithConversionMaybe[A <: AnyRef, B <: AnyRef](s: ParseOrUnparseState, oe: Maybe[CachedDynamic[A, B]])(conv: (ParseOrUnparseState, A) => B): Maybe[B] = {
-    if (oe.isDefined) {
-      val b: B = evalWithConversion[A, B](s, oe.get)(conv)
-      One(b)
-    } else Nope
-  }
-
-  def evalWithConversion[A <: AnyRef, B <: AnyRef](s: ParseOrUnparseState, oe: List[CachedDynamic[A, B]])(conv: (ParseOrUnparseState, A) => B): List[B] = {
-    val state = s
-    val listE = oe.map(e => {
-      val exp: B = evalWithConversion[A, B](state, e)(conv)
-      exp
-    })
-    listE
-  }
-
-  // With an property that can potentially be compiled, this returns an Option,
-  // which is either Some(s) if the value of the property is static, or None
-  // otherwise
-
-  def getStatic[A <: AnyRef, B <: AnyRef](e: CachedDynamic[A, B]): Maybe[B] = {
-    e match {
-      case Left(l) => Nope
-      case Right(r) => One(r)
-    }
-  }
-
-  def getStaticMaybe[A <: AnyRef, B <: AnyRef](oe: Maybe[CachedDynamic[A, B]]): Maybe[B] = {
-    if (oe.isDefined) getStatic(oe.get)
-    else Nope
-  }
-}
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/EvTextNumber.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/EvTextNumber.scala
index 63c1651..88e0bc1 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/EvTextNumber.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/EvTextNumber.scala
@@ -17,12 +17,27 @@
 
 package org.apache.daffodil.processors
 
+import java.math.RoundingMode
+   
+import scala.collection.mutable
+
+import com.ibm.icu.text.DecimalFormat
+import com.ibm.icu.text.DecimalFormatSymbols
+
 import org.apache.daffodil.dsom._
 import org.apache.daffodil.cookers.TextStandardGroupingSeparatorCooker
 import org.apache.daffodil.cookers.TextBooleanFalseRepCooker
 import org.apache.daffodil.cookers.TextStandardExponentRepCooker
 import org.apache.daffodil.cookers.TextBooleanTrueRepCooker
 import org.apache.daffodil.cookers.TextStandardDecimalSeparatorCooker
+import org.apache.daffodil.util.Maybe
+import org.apache.daffodil.util.Maybe._
+import org.apache.daffodil.util.MaybeChar
+import org.apache.daffodil.util.MaybeDouble
+import org.apache.daffodil.schema.annotation.props.gen.TextNumberCheckPolicy
+import org.apache.daffodil.schema.annotation.props.gen.TextNumberRounding
+import org.apache.daffodil.schema.annotation.props.gen.TextNumberRoundingMode
+import org.apache.daffodil.dpath.NodeInfo.PrimType
 
 class TextStandardDecimalSeparatorEv(expr: CompiledExpression[String], tci: DPathCompileInfo)
   extends EvaluatableConvertedExpression[String, List[String]](
@@ -51,6 +66,163 @@ class TextStandardExponentRepEv(expr: CompiledExpression[String], tci: DPathComp
   override lazy val runtimeDependencies = Vector()
 }
 
+class TextNumberFormatEv(
+  tci: DPathCompileInfo,
+  decimalSepEv: Maybe[TextStandardDecimalSeparatorEv],
+  groupingSepEv: Maybe[TextStandardGroupingSeparatorEv],
+  exponentRepEv: Maybe[TextStandardExponentRepEv],
+  infRep: Maybe[String],
+  nanRep: Maybe[String],
+  checkPolicy: TextNumberCheckPolicy,
+  textNumberPattern: String,
+  rounding: TextNumberRounding,
+  roundingMode: Maybe[TextNumberRoundingMode],
+  roundingIncrement: MaybeDouble,
+  zeroRepsRaw: List[String],
+  primType: PrimType)
+  extends Evaluatable[ThreadLocal[DecimalFormat]](tci)
+  with InfosetCachedEvaluatable[ThreadLocal[DecimalFormat]] {
+
+  override lazy val runtimeDependencies = (decimalSepEv.toList ++ groupingSepEv.toList ++ exponentRepEv.toList).toVector
+
+  private val isInt = primType match {
+    case PrimType.Double | PrimType.Float | PrimType.Decimal => false
+    case _ => true
+  }
+
+  private def checkUnique(
+    decimalSep: MaybeChar,
+    groupingSep: MaybeChar,
+    exponentRep: Maybe[String]): Unit = {
+
+    val mm = new mutable.HashMap[String, mutable.Set[String]] with mutable.MultiMap[String, String]
+    if (decimalSep.isDefined) mm.addBinding(decimalSep.get.toString, "textStandardDecimalSeparator")
+    if (groupingSep.isDefined) mm.addBinding(groupingSep.get.toString, "textStandardGroupingSeparator")
+    if (exponentRep.isDefined) mm.addBinding(exponentRep.get, "textStandardExponentRep")
+    if (infRep.isDefined) mm.addBinding(infRep.get, "textStandardInfinityRep")
+    if (nanRep.isDefined) mm.addBinding(nanRep.get, "textStandardNaNRep")
+    zeroRepsRaw.foreach { zr => mm.addBinding(zr, "textStandardZeroRep") }
+
+    val dupes = mm.filter { case (k, s) => s.size > 1 }
+    val dupeStrings = dupes.map {
+      case (k, s) =>
+        "Non-distinct property '%s' found in: %s".format(k, s.mkString(", "))
+    }
+    tci.schemaDefinitionUnless(dupeStrings.size == 0, dupeStrings.mkString("\n"))
+  }
+
+  private def generateNumFormat(
+    decimalSep: MaybeChar,
+    groupingSep: MaybeChar,
+    exponentRep: Maybe[String]): DecimalFormat = {
+
+    val dfs = new DecimalFormatSymbols()
+
+    if (decimalSep.isDefined) {
+      dfs.setDecimalSeparator(decimalSep.get)
+    }
+
+    if (groupingSep.isDefined) {
+      dfs.setGroupingSeparator(groupingSep.get)
+    }
+
+    // TODO: this is allowed to be case insenstive, ICU doesn't support that
+    if (exponentRep.isDefined) {
+      dfs.setExponentSeparator(exponentRep.get)
+    }
+
+    if (infRep.isDefined) {
+      // TODO: this is allowed to be case insensitive, ICU doesn't support that
+      dfs.setInfinity(infRep.get)
+    }
+
+    if (nanRep.isDefined) {
+      // TODO: this is allowed to be case insensitive, ICU doesn't support that
+      dfs.setNaN(nanRep.get)
+    }
+
+    val df = new DecimalFormat(textNumberPattern, dfs)
+
+    val cp = checkPolicy match {
+      case TextNumberCheckPolicy.Strict => true
+      case TextNumberCheckPolicy.Lax => false
+    }
+    df.setParseStrict(cp)
+
+    rounding match {
+      case TextNumberRounding.Pattern => {
+        df.setRoundingMode(RoundingMode.HALF_EVEN.ordinal())
+      }
+      case TextNumberRounding.Explicit => {
+        val rm = roundingMode.get match {
+          case TextNumberRoundingMode.RoundCeiling => RoundingMode.CEILING
+          case TextNumberRoundingMode.RoundFloor => RoundingMode.FLOOR
+          case TextNumberRoundingMode.RoundDown => RoundingMode.DOWN
+          case TextNumberRoundingMode.RoundUp => RoundingMode.UP
+          case TextNumberRoundingMode.RoundHalfEven => RoundingMode.HALF_EVEN
+          case TextNumberRoundingMode.RoundHalfDown => RoundingMode.HALF_DOWN
+          case TextNumberRoundingMode.RoundHalfUp => RoundingMode.HALF_UP
+          case TextNumberRoundingMode.RoundUnnecessary => RoundingMode.UNNECESSARY
+        }
+        df.setRoundingMode(rm.ordinal())
+        df.setRoundingIncrement(roundingIncrement.get)
+      }
+    }
+
+    if (isInt) {
+      df.setMaximumFractionDigits(0)
+      df.setDecimalSeparatorAlwaysShown(false)
+      df.setParseIntegerOnly(true)
+    }
+
+    df
+  }
+
+  override protected def compute(state: ParseOrUnparseState): ThreadLocal[DecimalFormat] = {
+
+    val decimalSepList = if (decimalSepEv.isDefined) {
+      val seps = decimalSepEv.get.evaluate(state)
+      if (seps.length > 1) {
+        // TODO: ICU only supports a single decimal separator
+        tci.notYetImplemented("More than one textStandardDecimalSeparator")
+      }
+      MaybeChar(seps.head(0))
+    } else {
+      MaybeChar.Nope
+    }
+
+    val groupingSep = if (groupingSepEv.isDefined) {
+      MaybeChar(groupingSepEv.get.evaluate(state)(0))
+    } else {
+      MaybeChar.Nope
+    }
+
+    val exponentRep = if (exponentRepEv.isDefined) {
+      One(exponentRepEv.get.evaluate(state))
+    } else {
+      Nope
+    }
+
+    checkUnique(
+      decimalSepList,
+      groupingSep,
+      exponentRep)
+
+    val numFormat = new ThreadLocal[DecimalFormat] with Serializable {
+      override def initialValue() = {
+        generateNumFormat(
+          decimalSepList,
+          groupingSep,
+          exponentRep)
+      }
+    }
+
+    numFormat
+  }
+  
+}
+
+
 class TextBooleanTrueRepEv(exprT: CompiledExpression[String], falseRepEv: TextBooleanFalseRepEv, mustBeSameLength: Boolean, tci: DPathCompileInfo)
   extends EvaluatableConvertedExpression[String, List[String]](
     exprT,
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/BinaryBooleanParsers.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/BinaryBooleanParsers.scala
index 01c486f..964b378 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/BinaryBooleanParsers.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/BinaryBooleanParsers.scala
@@ -48,7 +48,7 @@ abstract class BinaryBooleanParserBase(
   override def parse(start: PState): Unit = {
     val nBits = getBitLength(start)
     if (nBits < 1 || nBits > 32) {
-      PE(start, "Number of bits %d out of range, must be between 1 and 32 bits.", nBits)
+      PE(start, "Number of bits %d out of range for xs:boolean, must be between 1 and 32 bits.", nBits)
       return
     }
 
@@ -72,7 +72,7 @@ abstract class BinaryBooleanParserBase(
         if (binaryBooleanTrueRep.getULong == sl) true
         else if (binaryBooleanFalseRep == sl) false
         else {
-          PE(start, "Convert to xs:boolean: Cannot parse boolean from '%s'", sl)
+          PE(start, "Unable to parse xs:boolean from binary: %s", sl)
           return
         }
       }
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/BinaryNumberParsers.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/BinaryNumberParsers.scala
index f6eeb1c..38a80a0 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/BinaryNumberParsers.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/BinaryNumberParsers.scala
@@ -20,6 +20,7 @@ package org.apache.daffodil.processors.parsers
 import java.lang.{ Long => JLong, Number => JNumber, Double => JDouble, Float => JFloat }
 import java.math.{BigInteger => JBigInt, BigDecimal => JBigDecimal}
 
+import org.apache.daffodil.dpath.NodeInfo
 import org.apache.daffodil.processors.ElementRuntimeData
 import org.apache.daffodil.processors.Evaluatable
 import org.apache.daffodil.processors.ParseOrUnparseState
@@ -147,6 +148,8 @@ abstract class BinaryIntegerBaseParser(override val context: ElementRuntimeData,
 
   protected def getBitLength(s: ParseOrUnparseState): Int
 
+  private val primNumeric = context.optPrimType.get.asInstanceOf[NodeInfo.PrimType.PrimNumeric]
+
   def parse(start: PState): Unit = {
     val nBits = getBitLength(start)
     if (nBits == 0) return // zero length is used for outputValueCalc often.
@@ -156,7 +159,7 @@ abstract class BinaryIntegerBaseParser(override val context: ElementRuntimeData,
       return
     }
 
-    val int: JNumber =
+    val num: JNumber =
       if (signed) {
         if (nBits > 64) { dis.getSignedBigInt(nBits, start) }
         else { dis.getSignedLong(nBits, start) }
@@ -165,6 +168,14 @@ abstract class BinaryIntegerBaseParser(override val context: ElementRuntimeData,
         else { dis.getUnsignedLong(nBits, start).toLong }
       }
 
-    start.simpleElement.overwriteDataValue(int)
+    if (!primNumeric.isValidRange(num)) {
+      PE(start, "Parsed %s is out of range for type: %s",
+        context.optPrimType.get.globalQName, num)
+      return
+    }
+
+    val res = primNumeric.fromNumber(num)
+
+    start.simpleElement.overwriteDataValue(res)
   }
 }
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PrimitivesDateTime1.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PrimitivesDateTime1.scala
index 0031dc1..76c01db 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PrimitivesDateTime1.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PrimitivesDateTime1.scala
@@ -144,7 +144,7 @@ case class ConvertTextCalendarParser(
     // Use pos to verify all characters consumed & check for errors
     if (pos.getIndex != str.length || pos.getErrorIndex >= 0) {
       val errIndex = if (pos.getErrorIndex >= 0) pos.getErrorIndex else pos.getIndex
-      PE(start, "Convert to %s (for xs:%s): Failed to parse '%s' at character %d.", prettyType, xsdType, str, errIndex + 1)
+      PE(start, "Unable to parse xs:%s from text: %s", xsdType, str)
       return
     }
 
@@ -160,7 +160,7 @@ case class ConvertTextCalendarParser(
           calendar.get(Calendar.YEAR), start.tunable.minValidYear, start.tunable.maxValidYear)
     } catch {
       case e: IllegalArgumentException => {
-        PE(start, "Convert to %s (for xs:%s): Failed to parse '%s': %s.", prettyType, xsdType, str, e.getMessage())
+        PE(start, "Unable to parse xs:%s from text: %s. %s", xsdType, str, e.getMessage())
         return
       }
     }
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PrimitivesTextNumber1.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PrimitivesTextNumber1.scala
index 125dfee..6b0945c 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PrimitivesTextNumber1.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PrimitivesTextNumber1.scala
@@ -17,36 +17,29 @@
 
 package org.apache.daffodil.processors.parsers
 
+
 import com.ibm.icu.math.{ BigDecimal => ICUBigDecimal }
+import com.ibm.icu.text.DecimalFormat
+
+import java.text.ParsePosition
+
+import scala.util.matching.Regex
 
+import org.apache.daffodil.dpath.NodeInfo
+import org.apache.daffodil.exceptions.Assert
+import org.apache.daffodil.infoset.DISimple
+import org.apache.daffodil.infoset.DataValue.DataValueNumber
+import org.apache.daffodil.processors.ElementRuntimeData
+import org.apache.daffodil.processors.Success
+import org.apache.daffodil.processors.TermRuntimeData
+import org.apache.daffodil.processors.TextNumberFormatEv
 import org.apache.daffodil.schema.annotation.props.gen.TextNumberCheckPolicy
 import org.apache.daffodil.schema.annotation.props.gen.TextNumberRounding
 import org.apache.daffodil.schema.annotation.props.gen.TextNumberRoundingMode
-import org.apache.daffodil.xml.XMLUtils
-import org.apache.daffodil.exceptions.ThrowsSDE
-import org.apache.daffodil.exceptions.Assert
-import org.apache.daffodil.exceptions.UnsuppressableException
 import org.apache.daffodil.util.Maybe
 import org.apache.daffodil.util.Maybe._
-import java.text.ParsePosition
-import com.ibm.icu.text.DecimalFormat
-import com.ibm.icu.text.DecimalFormatSymbols
-import org.apache.daffodil.util.MaybeDouble
 import org.apache.daffodil.util.MaybeDouble
-import java.lang.{ Number => JNumber }
-import java.math.{ BigDecimal => JBigDecimal, BigInteger => JBigInt }
-import java.math.RoundingMode
-import org.apache.daffodil.infoset.DISimple
-import org.apache.daffodil.processors.Delimiter
-import org.apache.daffodil.processors.Dynamic
-import org.apache.daffodil.processors.ElementRuntimeData
-import org.apache.daffodil.processors.Evaluatable
-import org.apache.daffodil.processors.ParseOrUnparseState
-import org.apache.daffodil.processors.Success
-import java.lang.{ Number => JNumber }
-import java.math.{ BigDecimal => JBigDecimal }
-import java.math.{ BigInteger => JBigInt }
-import org.apache.daffodil.processors.TermRuntimeData
+import org.apache.daffodil.xml.XMLUtils
 
 case class ConvertTextCombinatorParser(
   rd: TermRuntimeData,
@@ -67,13 +60,15 @@ case class ConvertTextCombinatorParser(
   }
 }
 
-case class ConvertTextNumberParser[S](
-  helper: ConvertTextNumberParserUnparserHelperBase[S],
-  nff: NumberFormatFactoryBase[S],
-  override val context: ElementRuntimeData) extends TextPrimParser {
-  override lazy val runtimeDependencies = Vector()
+case class ConvertTextNumberParser(
+  textNumberFormatEv: TextNumberFormatEv,
+  zeroRepsRegex: List[Regex],
+  override val context: ElementRuntimeData)
+  extends TextPrimParser {
 
-  override def toString = "to(xs:" + helper.xsdType + ")"
+  override lazy val runtimeDependencies = Vector(textNumberFormatEv)
+
+  private val primNumeric = context.optPrimType.get.asInstanceOf[NodeInfo.PrimType.PrimNumeric]
 
   def parse(start: PState): Unit = {
     val node: DISimple = start.simpleElement
@@ -81,7 +76,7 @@ case class ConvertTextNumberParser[S](
 
     Assert.invariant(str != null) // worst case it should be empty string. But not null.
     if (str == "") {
-      PE(start, "Convert to %s (for xs:%s): Cannot parse number from empty string", helper.prettyType, helper.xsdType)
+      PE(start, "Unable to parse %s from empty string", context.optPrimType.get.globalQName)
       return
     }
 
@@ -89,29 +84,30 @@ case class ConvertTextNumberParser[S](
     // will match either all or none of 'str', never part of it. Thus,
     // findFirstIn() either matches and it's a zero rep, or it doesn't and it's
     // not a zero
-    val numValue = helper.zeroRepList.find { _.findFirstIn(str).isDefined } match {
-      case Some(_) => helper.getNum(0)
+    val numValue = zeroRepsRegex.find { _.findFirstIn(str).isDefined } match {
+      case Some(_) => primNumeric.fromNumber(0)
       case None => {
-        val df = nff.getNumFormat(start).get
+        val df = textNumberFormatEv.evaluate(start).get
         val strCheckPolicy = if (df.isParseStrict) str else str.trim
         val pos = new ParsePosition(0)
-        val num = try {
-          df.parse(strCheckPolicy, pos)
-        } catch {
-          case s: scala.util.control.ControlThrowable => throw s
-          case u: UnsuppressableException => throw u
-          case e: Exception => {
-            PE(start, "Convert to %s (for xs:%s): Parse of '%s' threw exception %s",
-              helper.prettyType, helper.xsdType, str, e)
-            return
+        val icuNum = df.parse(strCheckPolicy, pos)
+
+        // sometimes ICU will return their own custom BigDecimal, even if the
+        // value could be represented as a BigInteger. We only want Java types,
+        // so detect this and convert it to the appropriate type
+        val num = icuNum match {
+          case bd: ICUBigDecimal => {
+            if (bd.scale == 0) bd.unscaledValue
+            else bd.toBigDecimal
           }
+          case _ => icuNum
         }
 
         // Verify that what was parsed was what was passed exactly in byte count.
         // Use pos to verify all characters consumed & check for errors!
         if (num == null) {
-          PE(start, "Convert to %s (for xs:%s): Unable to parse '%s' (using up all characters).",
-            helper.prettyType, helper.xsdType, str)
+          PE(start, "Unable to parse %s from text: %s",
+            context.optPrimType.get.globalQName, str)
           return
         }
         if (pos.getIndex != strCheckPolicy.length) {
@@ -131,13 +127,13 @@ case class ConvertTextNumberParser[S](
               false
             }
           if (!isValid) {
-            PE(start, "Convert to %s (for xs:%s): Unable to parse '%s' (using up all characters).",
-              helper.prettyType, helper.xsdType, str)
+            PE(start, "Unable to parse %s from text: %s",
+              context.optPrimType.get.globalQName, str)
             return
           }
         }
 
-        val numValue = num match {
+        val numValue: DataValueNumber = num match {
           // if num is infRep, -infRep, or nanRep, then parse() returns
           // Double.{POSINF, NEGINF, NAN}. otherwise, it returns some kind
           // of boxed number that can hold the full contents of the number,
@@ -146,602 +142,21 @@ case class ConvertTextNumberParser[S](
           case d: java.lang.Double if (d.isInfinite && d < 0) => XMLUtils.NegativeInfinity
           case d: java.lang.Double if (d.isNaN) => XMLUtils.NaN
           case _ => {
-            if (helper.isInvalidRange(num)) {
-              PE(start, "Convert to %s (for xs:%s): Out of Range: '%s' converted to %s, is not in range for the type.",
-                helper.prettyType, helper.xsdType, str, num)
+            if (!primNumeric.isValidRange(num)) {
+              PE(start, "Parsed %s is out of range for type: %s",
+                context.optPrimType.get.globalQName, num)
               return
             }
 
             // convert to proper type
-            val asNumber = helper.getNum(num)
-            Assert.invariant(!asNumber.isInstanceOf[String])
-
-            // The following change was made because of the issues with the float
-            // adding a position of precision to the Number object.  At some point we
-            // will want to revert this back to the actual type but this is a quick fix
-            // for the issues we were having with the 0.003 vs 0.0030 error in test_DelimProp_05
-            //
-            //helper.getStringFormat(asNumber)
-            //
-            // Above was changed back into the actual number object.
-            asNumber
+            primNumeric.fromNumber(num)
           }
         }
         numValue
       }
     }
 
-    Assert.invariant(!numValue.isInstanceOf[String])
-    node.overwriteDataValue(numValue.asInstanceOf[JNumber])
-
-  }
-}
-
-abstract class ConvertTextNumberParserUnparserHelperBase[S](zeroRep: List[String], ignoreCase: Boolean) extends Serializable {
-  val xsdType: String
-  val prettyType: String
-
-  def getNum(s: Number): S
-  def isInt: Boolean
-  def isInvalidRange(n: java.lang.Number): Boolean
-  def getStringFormat(n: S): String
-  def allowInfNaN: Boolean = false
-
-  val zeroRepListRaw = zeroRep.filter { _ != "" }
-  val zeroRepList = zeroRepListRaw.map { zr =>
-    val d = new Delimiter()
-    d.compileDelimiter(zr, ignoreCase)
-    // add '^' and '$' to require the regular expression to match the entire
-    // string as a zero rep instead of just part of it
-    val ignoreCaseStr = if (ignoreCase) "(?i)" else ""
-    val regex = (ignoreCaseStr + "^" + d.delimRegExParseDelim + "$").r
-    regex
-  }
-}
-
-abstract class ConvertTextIntegerNumberParserUnparserHelper[S](zeroRep: List[String], ignoreCase: Boolean)
-  extends ConvertTextNumberParserUnparserHelperBase[S](zeroRep, ignoreCase) {
-  override def isInt = true
-
-  override def getStringFormat(n: S): String = n.toString()
-
-  def isInvalidRange(n: java.lang.Number): Boolean = {
-    //
-    // Note: Scala has no class analogous to java.lang.Number. There's no common
-    // base class above its number types (as there isn't above the Java *primitive* number types.)
-    //
-    // We're being handed here a java 'boxed' number type, and those have common parent Number.
-    //
-    // println("number's actual type is: " + n.getClass.getName)
-    //
-    // This method only for things that fit in range of a Long. (i.e., not unbounded size Integer, and not unsignedLong
-    // Nevertheless, if invalid data much too long for the real numeric type is what is found in the data
-    // then a java BigInteger (or maybe even BigDecimal might get passed here.
-    //
-    // The only thing we can check is whether there is conversion to a long available.
-    // e.g., like this: Assert.invariant(n.isInstanceOf[{ def longValue : Long}])
-    // But that's eliminated by erasure, so we'll just do without.
-    //
-    val l = n.longValue
-
-    // check for overflow/underflow.
-    val orig = new JBigDecimal(n.toString)
-    val newl = new JBigDecimal(l)
-    if (orig.compareTo(newl) != 0) {
-      true
-    } else {
-      l < min || l > max
-    }
-  }
-  def min: Long
-  def max: Long
-}
-
-abstract class ConvertTextFloatingPointNumberParserUnparserHelper[S](zeroRep: List[String], ignoreCase: Boolean)
-  extends ConvertTextNumberParserUnparserHelperBase[S](zeroRep, ignoreCase) {
-  override def isInt = false
-  override def getStringFormat(n: S): String = {
-
-    //val trailingZeroes = """0*(?!<[1-9])$"""
-    val trailingZeroes = """(?<=[1-9])(0*)$""".r
-    val trailingZeroesBeforeExponent = """(?<=[1-9])(0*?)(?=E.*)""".r
-
-    val nAsStr = n.toString()
-
-    if (nAsStr.contains("E") || nAsStr.contains("e")) {
-      // Exponent
-      trailingZeroesBeforeExponent.replaceAllIn(nAsStr, "")
-    } else {
-      trailingZeroes.replaceAllIn(nAsStr, "")
-    }
-
-    nAsStr
-  }
-
-}
-
-case class ConvertTextIntegerParserUnparserHelper[S](zeroRep: List[String], ignoreCase: Boolean)
-  extends ConvertTextIntegerNumberParserUnparserHelper[JBigInt](zeroRep, ignoreCase) {
-
-  override def getNum(num: Number) = new JBigInt(num.toString)
-  override val xsdType = "integer"
-  override val prettyType = "Unlimited Size Integer"
-  override def isInvalidRange(n: java.lang.Number): Boolean = false
-  def min = -1 // ignored
-  def max = -1 // ignored
-}
-
-case class ConvertTextNonNegativeIntegerParserUnparserHelper[S](zeroRep: List[String], ignoreCase: Boolean)
-  extends ConvertTextIntegerNumberParserUnparserHelper[JBigInt](zeroRep, ignoreCase) {
-
-  override def getNum(num: Number) = new JBigInt(num.toString)
-  override val xsdType = "nonNegativeInteger"
-  override val prettyType = "Unlimited Size Non Negative Integer"
-  override def isInvalidRange(n: java.lang.Number): Boolean = {
-    val value = new JBigDecimal(n.toString())
-    val isNegative = value.signum == -1
-    if (isNegative) return true
-    false
-  }
-  def min = -1 // ignored
-  def max = -1 // ignored
-}
-
-case class ConvertTextLongParserUnparserHelper[S](zeroRep: List[String], ignoreCase: Boolean)
-  extends ConvertTextIntegerNumberParserUnparserHelper[Long](zeroRep, ignoreCase) {
-
-  override def getNum(num: Number) = num.longValue
-  override val xsdType = "long"
-  override val prettyType = "Long Integer"
-  val min = Long.MinValue
-  val max = Long.MaxValue
-}
-
-case class ConvertTextIntParserUnparserHelper[S](zeroRep: List[String], ignoreCase: Boolean)
-  extends ConvertTextIntegerNumberParserUnparserHelper[Int](zeroRep, ignoreCase) {
-
-  override def getNum(num: Number) = num.intValue
-  override val xsdType = "int"
-  override val prettyType = "Integer"
-  val min = Int.MinValue.toLong
-  val max = Int.MaxValue.toLong
-}
-
-case class ConvertTextShortParserUnparserHelper[S](zeroRep: List[String], ignoreCase: Boolean)
-  extends ConvertTextIntegerNumberParserUnparserHelper[Short](zeroRep, ignoreCase) {
-
-  override def getNum(num: Number) = num.shortValue
-  override val xsdType = "short"
-  override val prettyType = "Short Integer"
-  val min = Short.MinValue.toLong
-  val max = Short.MaxValue.toLong
-}
-
-case class ConvertTextByteParserUnparserHelper[S](zeroRep: List[String], ignoreCase: Boolean)
-  extends ConvertTextIntegerNumberParserUnparserHelper[Byte](zeroRep, ignoreCase) {
-
-  override def getNum(num: Number) = num.byteValue
-  override val xsdType = "byte"
-  override val prettyType = "Byte"
-  val min = Byte.MinValue.toLong
-  val max = Byte.MaxValue.toLong
-}
-
-case class ConvertTextUnsignedLongParserUnparserHelper[S](zeroRep: List[String], ignoreCase: Boolean)
-  extends ConvertTextIntegerNumberParserUnparserHelper[JBigInt](zeroRep, ignoreCase) {
-
-  override def getNum(num: Number) = new JBigInt(num.toString)
-  override val xsdType = "unsignedLong"
-  override val prettyType = "Unsigned Long"
-  override def isInvalidRange(jn: java.lang.Number) = {
-    jn match {
-      case n: ICUBigDecimal => {
-        n.compareTo(ICUBigDecimal.ZERO) < 0 || n.compareTo(maxBD) >= 0
-      }
-      case _ => {
-        val n = jn.longValue()
-        n < 0 // note: the other side of the check is inherently ok since a Long must be smaller than an unsignedLong.
-      }
-    }
-  }
-  val min = 0.toLong
-  val max = -1.toLong // unused.
-  val maxBD = new ICUBigDecimal(JBigInt.ONE.shiftLeft(64))
-}
-
-case class ConvertTextUnsignedIntParserUnparserHelper[S](zeroRep: List[String], ignoreCase: Boolean)
-  extends ConvertTextIntegerNumberParserUnparserHelper[Long](zeroRep, ignoreCase) {
-
-  override def getNum(num: Number) = num.longValue
-  override val xsdType = "unsignedInt"
-  override val prettyType = "Unsigned Integer"
-  val min = 0L
-  val max = (1L << 32) - 1L
-}
-
-case class ConvertTextUnsignedShortParserUnparserHelper[S](zeroRep: List[String], ignoreCase: Boolean)
-  extends ConvertTextIntegerNumberParserUnparserHelper[Int](zeroRep, ignoreCase) {
-
-  override def getNum(num: Number) = num.intValue
-  override val xsdType = "unsignedShort"
-  override val prettyType = "Unsigned Short"
-  val min = 0L
-  val max = (1L << 16) - 1L
-}
-
-case class ConvertTextUnsignedByteParserUnparserHelper[S](zeroRep: List[String], ignoreCase: Boolean)
-  extends ConvertTextIntegerNumberParserUnparserHelper[Short](zeroRep, ignoreCase) {
-
-  override def getNum(num: Number) = num.shortValue
-  override val xsdType = "unsignedByte"
-  override val prettyType = "Unsigned Byte"
-  val min = 0L
-  val max = (1L << 8) - 1L
-}
-
-case class ConvertTextDecimalParserUnparserHelper[S](zeroRep: List[String], ignoreCase: Boolean)
-  extends ConvertTextFloatingPointNumberParserUnparserHelper[JBigDecimal](zeroRep, ignoreCase) {
-
-  override def getNum(num: Number) = new JBigDecimal(num.toString)
-  override val xsdType = "decimal"
-  override val prettyType = "Unlimited Size Decimal"
-  override def isInvalidRange(n: java.lang.Number): Boolean = false
-
-  override def getStringFormat(n: JBigDecimal): String = {
-    n.toPlainString()
-  }
-}
-
-case class ConvertTextDoubleParserUnparserHelper[S](zeroRep: List[String], ignoreCase: Boolean)
-  extends ConvertTextFloatingPointNumberParserUnparserHelper[Double](zeroRep, ignoreCase) {
-
-  val MAX_VALUE = new JBigDecimal(Double.MaxValue)
-  val MIN_VALUE = new JBigDecimal(Double.MinValue)
-
-  override def getNum(num: Number) = num.doubleValue
-  override val xsdType = "double"
-  override val prettyType = "Double"
-  override def allowInfNaN = true
-  def isInvalidRange(n: java.lang.Number): Boolean = {
-    val d = n.doubleValue() // This can truncate the number and void range checking
-    val bd = new JBigDecimal(n.toString)
-    (d.isNaN || bd.compareTo(MIN_VALUE) < 0 || bd.compareTo(MAX_VALUE) > 0)
-  }
-}
-
-case class ConvertTextFloatParserUnparserHelper[S](zeroRep: List[String], ignoreCase: Boolean)
-  extends ConvertTextFloatingPointNumberParserUnparserHelper[Float](zeroRep, ignoreCase) {
-
-  val MAX_VALUE = new JBigDecimal(Float.MaxValue)
-  val MIN_VALUE = new JBigDecimal(Float.MinValue)
-
-  override def getNum(num: Number) = num.floatValue
-  override val xsdType = "float"
-  override val prettyType = "Float"
-  override def allowInfNaN = true
-  def isInvalidRange(n: java.lang.Number): Boolean = {
-    val f = n.floatValue() // This can truncated the number and void range checking
-    val bd = new JBigDecimal(n.toString)
-    (f.isNaN || bd.compareTo(MIN_VALUE) < 0 || bd.compareTo(MAX_VALUE) > 0)
-  }
-}
-
-abstract class NumberFormatFactoryBase[S](parserHelper: ConvertTextNumberParserUnparserHelperBase[S]) extends Serializable {
-
-  protected def checkUnique(
-    decimalSepList: Maybe[List[Character]],
-    groupingSep: Maybe[Character],
-    exponentRep: Maybe[String],
-    infRep: Maybe[String],
-    nanRep: Maybe[String],
-    zeroRep: List[String],
-    context: ThrowsSDE) = {
-
-    import scala.collection.mutable.{ HashMap, MultiMap, Set }
-
-    val mm = new HashMap[String, Set[String]] with MultiMap[String, String]
-    if (decimalSepList.isDefined) {
-      val dsl = decimalSepList.value
-      dsl.foreach { ds => mm.addBinding(ds.toString, "textStandardDecimalSeparator") }
-    }
-    if (groupingSep.isDefined) mm.addBinding(groupingSep.get.toString, "textStandardGroupingSeparator")
-    if (exponentRep.isDefined) {
-      val er = exponentRep.value
-      er.foreach { c => mm.addBinding(c.toString, "textStandardExponentRep") }
-    }
-    if (infRep.isDefined) {
-      val ir = infRep.value
-      mm.addBinding(ir, "textStandardInfinityRep")
-    }
-    if (nanRep.isDefined) {
-      val nr = nanRep.value
-      mm.addBinding(nr, "textStandardNaNRep")
-    }
-    zeroRep.foreach { zr => mm.addBinding(zr, "textStandardZeroRep") }
-
-    val dupes = mm.filter { case (k, s) => s.size > 1 }
-    val dupeStrings = dupes.map {
-      case (k, s) =>
-        "Non-distinct property '%s' found in: %s".format(k, s.mkString(", "))
-    }
-    context.schemaDefinitionUnless(dupeStrings.size == 0, dupeStrings.mkString("\n"))
-  }
-
-  protected def generateNumFormat(
-    decimalSepList: Maybe[List[Character]],
-    groupingSep: Maybe[Character],
-    exponentRep: Maybe[String],
-    infRep: Maybe[String],
-    nanRep: Maybe[String],
-    checkPolicy: TextNumberCheckPolicy,
-    pattern: String,
-    rounding: TextNumberRounding,
-    roundingMode: Maybe[TextNumberRoundingMode],
-    roundingIncrement: MaybeDouble) = {
-
-    val dfs = new DecimalFormatSymbols()
-
-    if (decimalSepList.isDefined) {
-      // TODO: ICU only supports a single decimal separator
-      dfs.setDecimalSeparator((decimalSepList.get)(0))
-    }
-
-    if (groupingSep.isDefined) {
-      dfs.setGroupingSeparator(groupingSep.get)
-    }
-
-    // TODO: this is allowed to be case insenstive, ICU doesn't support that
-    if (exponentRep.isDefined) {
-      dfs.setExponentSeparator(exponentRep.get)
-    }
-
-    if (infRep.isDefined) {
-      // TODO: this is allowed to be case insensitive, ICU doesn't support that
-      dfs.setInfinity(infRep.get)
-    }
-
-    if (nanRep.isDefined) {
-      // TODO: this is allowed to be case insensitive, ICU doesn't support that
-      dfs.setNaN(nanRep.get)
-    }
-
-    val df = new DecimalFormat(pattern, dfs)
-
-    val cp = checkPolicy match {
-      case TextNumberCheckPolicy.Strict => true
-      case TextNumberCheckPolicy.Lax => false
-    }
-    df.setParseStrict(cp)
-
-    rounding match {
-      case TextNumberRounding.Pattern => {
-        df.setRoundingMode(RoundingMode.HALF_EVEN.ordinal())
-      }
-      case TextNumberRounding.Explicit => {
-        val rm = roundingMode.get match {
-          case TextNumberRoundingMode.RoundCeiling => RoundingMode.CEILING
-          case TextNumberRoundingMode.RoundFloor => RoundingMode.FLOOR
-          case TextNumberRoundingMode.RoundDown => RoundingMode.DOWN
-          case TextNumberRoundingMode.RoundUp => RoundingMode.UP
-          case TextNumberRoundingMode.RoundHalfEven => RoundingMode.HALF_EVEN
-          case TextNumberRoundingMode.RoundHalfDown => RoundingMode.HALF_DOWN
-          case TextNumberRoundingMode.RoundHalfUp => RoundingMode.HALF_UP
-          case TextNumberRoundingMode.RoundUnnecessary => RoundingMode.UNNECESSARY
-        }
-        df.setRoundingMode(rm.ordinal())
-        df.setRoundingIncrement(roundingIncrement.get)
-      }
-    }
-
-    if (parserHelper.isInt) {
-      df.setMaximumFractionDigits(0)
-      df.setDecimalSeparatorAlwaysShown(false)
-      df.setParseIntegerOnly(true)
-    }
-
-    df
-  }
-
-  protected def getDecimalSepList(decimalSeps: List[String], context: ThrowsSDE): List[Character] = {
-
-    // TODO: ICU only supports a single separator
-    Assert.notYetImplemented(decimalSeps.length != 1, "lists of textStandardDecimalSeparator")
-    List(decimalSeps.head(0))
-  }
-
-  /**
-   * Returns java.lang.Character on purpose since that is an AnyRef and this gets used
-   * polymorphically in the CacheDynamic/Maybe frameworks which require AnyRef
-   */
-  protected def getGroupingSep(groupingSep: String, context: ThrowsSDE): Character = {
-
-    //    val gs = TextStandardGroupingSeparatorCooker.convertConstant(groupingSepRaw, context, forUnparse = false)
-    //    gs(0)
-    groupingSep(0)
-  }
-
-  protected def getExponentRep(exponentRep: String, context: ThrowsSDE): String = {
-
-    //    val er = TextStandardExponentRepCooker.convertConstant(exponentRepRaw, context, forUnparse = false)
-    //    er
-    exponentRep
-  }
-
-  protected def getRoundingIncrement(roundingInc: Double, context: ThrowsSDE): Double = {
-    context.schemaDefinitionUnless(roundingInc >= 0, "textNumberRoundingIncrement cannot be negative")
-    roundingInc
-  }
-
-  // as per ICU4J documentation, "DecimalFormat objects are not
-  // synchronized. Multiple threads should not access one formatter
-  // concurrently."
-  def getNumFormat(state: ParseOrUnparseState): ThreadLocal[DecimalFormat]
-
-}
-
-//
-// TODO: Complexity - why do we need both Static and Dynamic variants of this?
-// CachedDynamic hides this distinction (or should), as does CompiledExpression underneath that.
-
-class NumberFormatFactoryStatic[S](
-  context: ThrowsSDE,
-  parserHelper: ConvertTextNumberParserUnparserHelperBase[S],
-  decimalSepExpEv: Maybe[Evaluatable[List[String]]],
-  groupingSepExpEv: Maybe[Evaluatable[String]],
-  exponentRepExpEv: Maybe[Evaluatable[String]],
-  infRep: Maybe[String],
-  nanRep: Maybe[String],
-  checkPolicy: TextNumberCheckPolicy,
-  pattern: String,
-  rounding: TextNumberRounding,
-  roundingMode: Maybe[TextNumberRoundingMode],
-  roundingIncrement: MaybeDouble)
-  extends NumberFormatFactoryBase[S](parserHelper) {
-
-  val decSep =
-    if (decimalSepExpEv.isEmpty) Nope else One {
-      val dse = decimalSepExpEv.get.maybeConstant.get
-      getDecimalSepList(dse, context)
-    }
-
-  val groupSep =
-    if (groupingSepExpEv.isEmpty) Nope else One {
-      val gse = groupingSepExpEv.get.maybeConstant.get
-      getGroupingSep(gse, context)
-    }
-
-  val expRep =
-    if (exponentRepExpEv.isEmpty) Nope else One {
-      Assert.invariant(exponentRepExpEv.get.isConstant)
-      getExponentRep(exponentRepExpEv.get.maybeConstant.get, context)
-    }
-
-  val roundingInc: MaybeDouble = if (roundingIncrement.isEmpty) MaybeDouble.Nope else MaybeDouble { getRoundingIncrement(roundingIncrement.value, context) }
-
-  checkUnique(
-    decSep,
-    groupSep,
-    expRep,
-    infRep,
-    nanRep,
-    parserHelper.zeroRepListRaw,
-    context)
-
-  @transient lazy val numFormat = new ThreadLocal[DecimalFormat] {
-    override def initialValue() = {
-      generateNumFormat(
-        decSep,
-        groupSep,
-        expRep,
-        infRep,
-        nanRep,
-        checkPolicy,
-        pattern,
-        rounding,
-        roundingMode,
-        roundingInc)
-    }
-  }
+    node.overwriteDataValue(numValue)
 
-  def getNumFormat(state: ParseOrUnparseState): ThreadLocal[DecimalFormat] = {
-    numFormat
   }
 }
-
-class NumberFormatFactoryDynamic[S](
-  staticContext: ThrowsSDE,
-  parserHelper: ConvertTextNumberParserUnparserHelperBase[S],
-  decimalSepExpEv: Maybe[Evaluatable[List[String]]],
-  groupingSepExpEv: Maybe[Evaluatable[String]],
-  exponentRepExpEv: Maybe[Evaluatable[String]],
-  infRep: Maybe[String],
-  nanRep: Maybe[String],
-  checkPolicy: TextNumberCheckPolicy,
-  pattern: String,
-  rounding: TextNumberRounding,
-  roundingMode: Maybe[TextNumberRoundingMode],
-  roundingIncrement: MaybeDouble)
-  extends NumberFormatFactoryBase[S](parserHelper)
-  with Dynamic {
-
-  val decimalSepListCached: Maybe[CachedDynamic[List[String], List[Character]]] =
-    cacheConstantExpressionMaybe(decimalSepExpEv) {
-      (a: List[String]) => getDecimalSepList(a, staticContext)
-    }
-
-  val groupingSepCached: Maybe[CachedDynamic[String, Character]] =
-    cacheConstantExpressionMaybe(groupingSepExpEv) {
-      (a: String) => getGroupingSep(a, staticContext)
-    }
-
-  val exponentRepCached: Maybe[CachedDynamic[String, String]] =
-    cacheConstantExpressionMaybe(exponentRepExpEv) {
-      (a: String) => getExponentRep(a, staticContext)
-    }
-
-  checkUnique(
-    getStaticMaybe(decimalSepListCached),
-    getStaticMaybe(groupingSepCached),
-    getStaticMaybe(exponentRepCached),
-    infRep,
-    nanRep,
-    parserHelper.zeroRepListRaw,
-    staticContext)
-
-  val roundingInc = if (roundingIncrement.isEmpty) MaybeDouble.Nope else MaybeDouble { getRoundingIncrement(roundingIncrement.value, staticContext) }
-
-  def getNumFormat(state: ParseOrUnparseState): ThreadLocal[DecimalFormat] = {
-
-    val decimalSepList = evalWithConversionMaybe(state, decimalSepListCached) {
-      (s: ParseOrUnparseState, c: List[String]) =>
-        {
-          getDecimalSepList(c, s)
-        }
-    }
-
-    val groupingSep = evalWithConversionMaybe(state, groupingSepCached) {
-      (s: ParseOrUnparseState, c: String) =>
-        {
-          getGroupingSep(c, s)
-        }
-    }
-
-    val exponentRep = evalWithConversionMaybe(state, exponentRepCached) {
-      (s: ParseOrUnparseState, c: String) =>
-        {
-          getExponentRep(c, s)
-        }
-    }
-
-    checkUnique(
-      decimalSepList,
-      groupingSep,
-      exponentRep,
-      infRep,
-      nanRep,
-      parserHelper.zeroRepListRaw,
-      state)
-
-    val generatedNumFormat =
-      generateNumFormat(
-        decimalSepList,
-        groupingSep,
-        exponentRep,
-        infRep,
-        nanRep,
-        checkPolicy,
-        pattern,
-        rounding,
-        roundingMode,
-        roundingInc)
-
-    val numFormat = new ThreadLocal[DecimalFormat] {
-      override def initialValue() = {
-        generatedNumFormat
-      }
-    }
-
-    numFormat
-  }
-
-}
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/TextBooleanParser.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/TextBooleanParser.scala
index 8e88d57..4a9b512 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/TextBooleanParser.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/TextBooleanParser.scala
@@ -52,7 +52,7 @@ case class ConvertTextBooleanParser(
       if (textBooleanTrueReps.find(matches(_, str)).isDefined) true
       else if (textBooleanFalseReps.find(matches(_, str)).isDefined) false
       else {
-        PE(start, "Convert to xs:boolean: Cannot parse boolean from '%s'", str)
+        PE(start, "Unable to parse xs:boolean from text: %s", str)
         return
       }
 
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/ZonedTextParsers.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/ZonedTextParsers.scala
index 1f6a2d5..fd606b2 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/ZonedTextParsers.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/ZonedTextParsers.scala
@@ -17,17 +17,18 @@
 
 package org.apache.daffodil.processors.parsers
 
-import org.apache.daffodil.schema.annotation.props.gen.TextZonedSignStyle
+import java.text.ParsePosition
+import org.apache.daffodil.dpath.NodeInfo
 import org.apache.daffodil.exceptions.Assert
 import org.apache.daffodil.exceptions.UnsuppressableException
-import org.apache.daffodil.util.DecimalUtils
-import org.apache.daffodil.util.DecimalUtils.OverpunchLocation
-import java.text.ParsePosition
-import java.lang.{ Number => JNumber }
 import org.apache.daffodil.infoset.DISimple
 import org.apache.daffodil.processors.ElementRuntimeData
 import org.apache.daffodil.processors.Success
 import org.apache.daffodil.processors.TermRuntimeData
+import org.apache.daffodil.processors.TextNumberFormatEv
+import org.apache.daffodil.schema.annotation.props.gen.TextZonedSignStyle
+import org.apache.daffodil.util.DecimalUtils
+import org.apache.daffodil.util.DecimalUtils.OverpunchLocation
 
 case class ConvertZonedCombinatorParser(
   rd: TermRuntimeData,
@@ -47,15 +48,15 @@ case class ConvertZonedCombinatorParser(
   }
 }
 
-case class ConvertZonedNumberParser[S](
-  helper: ConvertTextNumberParserUnparserHelperBase[S],
+case class ConvertZonedNumberParser(
   opl: OverpunchLocation.Value,
-  nff: NumberFormatFactoryBase[S],
+  textNumberFormatEv: TextNumberFormatEv,
   zonedSignStyle: TextZonedSignStyle,
   override val context: ElementRuntimeData) extends TextPrimParser {
-  override lazy val runtimeDependencies = Vector()
 
-  override def toString = "to(xs:" + helper.xsdType + ")"
+  override lazy val runtimeDependencies = Vector(textNumberFormatEv)
+
+  private val primNumeric = context.optPrimType.get.asInstanceOf[NodeInfo.PrimType.PrimNumeric]
 
   def parse(start: PState): Unit = {
     val node: DISimple = start.simpleElement
@@ -63,54 +64,53 @@ case class ConvertZonedNumberParser[S](
 
     Assert.invariant(str != null) // worst case it should be empty string. But not null.
     if (str == "") {
-      PE(start, "Convert to %s (for xs:%s): Cannot parse number from empty string", helper.prettyType, helper.xsdType)
+      PE(start, "Unable to parse zoned %s from empty string", context.optPrimType.get.globalQName)
       return
     }
 
     var checkLength = str.length
     val numValue = {
-      val df = nff.getNumFormat(start)
+      val df = textNumberFormatEv.evaluate(start)
       val pos = new ParsePosition(0)
-      val num = try {
-        val decodedNum = DecimalUtils.zonedToNumber(str, zonedSignStyle, opl)
-        if (decodedNum(0) == '-')
-          checkLength = checkLength + 1
-        df.get.parse(decodedNum, pos)
+
+      val decodedNum = try {
+        DecimalUtils.zonedToNumber(str, zonedSignStyle, opl)
       } catch {
-        case s: scala.util.control.ControlThrowable => throw s
-        case u: UnsuppressableException => throw u
-        case e: Exception => {
-          PE(start, "Convert to %s (for xs:%s): Parse of '%s' threw exception %s",
-            helper.prettyType, helper.xsdType, str, e)
+        case e: NumberFormatException => {
+          PE(start, "Unable to parse zoned %s from text: %s. %s",
+            context.optPrimType.get.globalQName, str, e.getMessage)
           return
         }
       }
+      if (decodedNum(0) == '-')
+        checkLength = checkLength + 1
+
+      val num = df.get.parse(decodedNum, pos)
 
       // Verify that what was parsed was what was passed exactly in byte count.
       // Use pos to verify all characters consumed & check for errors!
       if (num == null || pos.getIndex != checkLength) {
-        PE(start, "Convert to %s (for xs:%s): Unable to parse '%s' (using up all characters).",
-          helper.prettyType, helper.xsdType, str)
+        PE(start, "Unable to parse zoned %s from text: %s.",
+          context.optPrimType.get.globalQName, str)
         return
       }
 
       val numValue = {
-        if (helper.isInvalidRange(num)) {
-          PE(start, "Convert to %s (for xs:%s): Out of Range: '%s' converted to %s, is not in range for the type.",
-            helper.prettyType, helper.xsdType, str, num)
+        if (!primNumeric.isValidRange(num)) {
+          PE(start, "Parsed %s is out of range for type: %s",
+            context.optPrimType.get.globalQName, str, num)
           return
         }
 
         // convert to proper type
-        val asNumber = helper.getNum(num)
-        Assert.invariant(!asNumber.isInstanceOf[String])
+        val asNumber = primNumeric.fromNumber(num)
 
         asNumber
       }
       numValue
     }
 
-    node.overwriteDataValue(numValue.asInstanceOf[JNumber])
+    node.overwriteDataValue(numValue)
 
   }
 }
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/lookAhead/lookAhead.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/lookAhead/lookAhead.tdml
index c0e92dd..b7dec45 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/extensions/lookAhead/lookAhead.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/extensions/lookAhead/lookAhead.tdml
@@ -350,7 +350,9 @@
     </tdml:document>
     <tdml:errors>
       <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>Negative value -1 cannot be converted to an unsigned int</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>xs:unsignedInt</tdml:error>
+      <tdml:error>-1</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -364,7 +366,9 @@
     </tdml:document>
     <tdml:errors>
       <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>Negative value -1 cannot be converted to an unsigned int</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>xs:unsignedInt</tdml:error>
+      <tdml:error>-1</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section02/validation_errors/Validation.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section02/validation_errors/Validation.tdml
index 0b57505..292a96a 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section02/validation_errors/Validation.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section02/validation_errors/Validation.tdml
@@ -1691,7 +1691,9 @@
       
       <!-- Failure for branch1:e2  -->
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Cannot parse number from empty string</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>xs:nonNegativeInteger</tdml:error>
+      <tdml:error>empty string</tdml:error>
 
       <!-- Failure for branch2  -->
       <tdml:error>Parse Error</tdml:error>
@@ -1750,7 +1752,9 @@
       
       <!-- Failure for branch1:e2  -->
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Cannot parse number from empty string</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>xs:nonNegativeInteger</tdml:error>
+      <tdml:error>empty string</tdml:error>
 
       <!-- Failure for branch2  -->
       <tdml:error>Parse Error</tdml:error>
@@ -1778,7 +1782,9 @@
       
       <!-- Failure for branch1:e2  -->
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Unlimited Size Non Negative Integer (for xs:nonNegativeInteger): Cannot parse number from empty string</tdml:error>
+      <tdml:error>xs:nonNegativeInteger</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>empty string</tdml:error>
 
       <!-- Failure for branch2  -->
       <tdml:error>Parse Error</tdml:error>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section05/facets/Facets.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section05/facets/Facets.tdml
index d0cf90d..84aceae 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section05/facets/Facets.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section05/facets/Facets.tdml
@@ -6252,7 +6252,9 @@
     <tdml:document>.75</tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Integer (for xs:int): Unable to parse '.75'</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>xs:int</tdml:error>
+      <tdml:error>.75</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section05/simple_types/Boolean.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section05/simple_types/Boolean.tdml
index 0bc5d22..4bcefa0 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section05/simple_types/Boolean.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section05/simple_types/Boolean.tdml
@@ -334,7 +334,8 @@
     </tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to xs:boolean: Cannot parse boolean from </tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>xs:boolean</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -569,7 +570,8 @@
     <tdml:document><![CDATA[yes,non;]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to xs:boolean: Cannot parse boolean from </tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>xs:boolean</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 </tdml:testSuite>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section05/simple_types/SimpleTypes.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section05/simple_types/SimpleTypes.tdml
index d1779a2..5704205 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section05/simple_types/SimpleTypes.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section05/simple_types/SimpleTypes.tdml
@@ -480,7 +480,7 @@
     <tdml:document><![CDATA[1.23]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Unlimited Size Integer (for xs:integer)</tdml:error>
+      <tdml:error>xs:integer</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -511,8 +511,10 @@
 
     <tdml:document><![CDATA[-2147483649]]></tdml:document>
     <tdml:errors>
-      <tdml:error>Parse Error: Convert to Integer</tdml:error>
-      <tdml:error>Out of Range: '-2147483649' converted to -2147483649, is not in range for the type.</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>xs:int</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>-2147483649</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -521,8 +523,10 @@
 
     <tdml:document><![CDATA[2147483648]]></tdml:document>
     <tdml:errors>
-      <tdml:error>Parse Error: Convert to Integer</tdml:error>
-      <tdml:error>Out of Range: '2147483648' converted to 2147483648, is not in range for the type.</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>xs:int</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>2147483648</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -576,8 +580,10 @@
 
     <tdml:document><![CDATA[-1]]></tdml:document>
     <tdml:errors>
-      <tdml:error>Parse Error: Convert to Unsigned Long</tdml:error>
-      <tdml:error>Out of Range: '-1' converted to -1, is not in range for the type.</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>xs:unsignedLong</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>-1</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -586,8 +592,9 @@
 
     <tdml:document>a</tdml:document>
     <tdml:errors>
-      <tdml:error>Parse Error: Convert to Unsigned Long</tdml:error>
-      <tdml:error>Unable to parse 'a' (using up all characters).</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>xs:unsignedLong</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -625,8 +632,10 @@
 
     <tdml:document><![CDATA[5.01]]></tdml:document>
     <tdml:errors>
-      <tdml:error>Parse Error: Convert to Integer</tdml:error>
-      <tdml:error>Unable to parse '5.01' (using up all characters).</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>xs:int</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>5.01</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -635,8 +644,10 @@
 
     <tdml:document><![CDATA[70000]]></tdml:document>
     <tdml:errors>
-      <tdml:error>Parse Error: Convert to Short Integer</tdml:error>
-      <tdml:error>Out of Range: '70000' converted to 70000, is not in range for the type.</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>xs:short</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>70000</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -654,8 +665,10 @@
 
     <tdml:document><![CDATA[7018631476]]></tdml:document>
     <tdml:errors>
-      <tdml:error>Parse Error: Convert to Unsigned Integer</tdml:error>
-      <tdml:error>Out of Range: '7018631476' converted to 7018631476, is not in range for the type.</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>xs:unsignedInt</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>7018631476</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -679,8 +692,10 @@
     description="Section 05 - Simple Types - unsignedInt - DFDL-5-018R">
     <tdml:document><![CDATA[-999]]></tdml:document>
     <tdml:errors>
-      <tdml:error>Parse Error: Convert to Unsigned Integer</tdml:error>
-      <tdml:error>Out of Range: '-999' converted to -999, is not in range for the type.</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>xs:unsignedInt</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>-999</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -690,7 +705,9 @@
     <tdml:document><![CDATA[9a99]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Unsigned Integer (for xs:unsignedInt): Unable to parse '9a99'</tdml:error>
+      <tdml:error>xs:unsignedInt</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>9a99</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -718,7 +735,8 @@
     <tdml:document><![CDATA[99 99]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Unable to parse '99 9' (using up all characters).</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>99 9</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -781,7 +799,9 @@
     <tdml:document><![CDATA[9a99]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Integer (for xs:int): Unable to parse '9a99'</tdml:error>
+      <tdml:error>xs:int</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>9a99</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -809,7 +829,8 @@
     <tdml:document><![CDATA[99 99]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Unable to parse '99 9' (using up all characters).</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>99 9</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -872,7 +893,9 @@
     <tdml:document><![CDATA[9a99]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Unlimited Size Integer (for xs:integer): Unable to parse '9a99'</tdml:error>
+      <tdml:error>xs:integer</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>9a99</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -900,7 +923,8 @@
     <tdml:document><![CDATA[99 99]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Unable to parse '99 9' (using up all characters).</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>99 9</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -964,7 +988,9 @@
     <tdml:document><![CDATA[9a99]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Long Integer (for xs:long): Unable to parse '9a99'</tdml:error>
+      <tdml:error>xs:long</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>9a99</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -992,7 +1018,8 @@
     <tdml:document><![CDATA[99 99]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Unable to parse '99 9' (using up all characters).</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>99 9</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -1055,7 +1082,9 @@
     <tdml:document><![CDATA[9a991]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Short Integer (for xs:short): Unable to parse '9a991'</tdml:error>
+      <tdml:error>xs:short</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>9a991</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -1136,7 +1165,8 @@
     <tdml:document><![CDATA[99 99]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Unable to parse '99 9' (using up all characters).</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>99 9</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -1147,7 +1177,9 @@
     <tdml:document><![CDATA[1a27]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Byte (for xs:byte): Unable to parse '1a27'</tdml:error>
+      <tdml:error>xs:byte</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>1a27</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -1175,7 +1207,8 @@
     <tdml:document><![CDATA[00 12]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Unable to parse '00 1' (using up all characters).</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>00 1</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -1243,8 +1276,10 @@
     description="Section 5 - Simple Types - unsignedLong - DFDL-5-017R">
     <tdml:document><![CDATA[-123]]></tdml:document>
     <tdml:errors>
-      <tdml:error>Parse Error: Convert to Unsigned Long</tdml:error>
-      <tdml:error>Out of Range: '-123' converted to -123, is not in range for the type.</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>xs:unsignedLong</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>-123</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -1254,7 +1289,9 @@
     <tdml:document><![CDATA[9a99]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Unsigned Long (for xs:unsignedLong): Unable to parse '9a99'</tdml:error>
+      <tdml:error>xs:unsignedLong</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>9a99</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -1282,7 +1319,8 @@
     <tdml:document><![CDATA[99 99]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Unable to parse '99 9' (using up all characters).</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>99 9</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -1350,8 +1388,10 @@
     description="Section 5 - Simple Types - unsignedShort - DFDL-5-019R">
     <tdml:document><![CDATA[-999]]></tdml:document>
     <tdml:errors>
-      <tdml:error>Parse Error: Convert to Unsigned Short</tdml:error>
-      <tdml:error>Out of Range: '-999' converted to -999, is not in range for the type.</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>xs:unsignedShort</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>-999</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -1361,7 +1401,9 @@
     <tdml:document><![CDATA[9a99]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Unsigned Short (for xs:unsignedShort): Unable to parse '9a99'</tdml:error>
+      <tdml:error>xs:unsignedShort</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>9a99</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -1389,7 +1431,8 @@
     <tdml:document><![CDATA[99 99]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Unable to parse '99 9' (using up all characters).</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>99 9</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -1457,8 +1500,10 @@
     description="Section 5 - Simple Types - unsignedByte - DFDL-5-020R">
     <tdml:document><![CDATA[-99]]></tdml:document>
     <tdml:errors>
-      <tdml:error>Parse Error: Convert to Unsigned Byte</tdml:error>
-      <tdml:error>Out of Range: '-99' converted to -99, is not in range for the type.</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>xs:unsignedByte</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>-99</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -1468,7 +1513,9 @@
     <tdml:document><![CDATA[9a9]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Unsigned Byte (for xs:unsignedByte): Unable to parse '9a9'</tdml:error>
+      <tdml:error>xs:unsignedByte</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>9a9</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -1496,7 +1543,8 @@
     <tdml:document><![CDATA[1 27]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Unable to parse '1 2' (using up all characters).</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>1 2</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -1557,8 +1605,10 @@
 
     <tdml:document><![CDATA[-1]]></tdml:document>
     <tdml:errors>
-      <tdml:error>Parse Error: Convert to Unsigned Short</tdml:error>
-      <tdml:error>Out of Range: '-1' converted to -1, is not in range for the type.</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>xs:unsignedShort</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>-1</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -1847,7 +1897,8 @@
     <tdml:document><![CDATA[1.5]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Unlimited Size Non Negative Integer</tdml:error>
+      <tdml:error>xs:nonNegativeInteger</tdml:error>
+      <tdml:error>1.5</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -2096,8 +2147,10 @@
 
     <tdml:document><![CDATA[9a9]]></tdml:document>
     <tdml:errors>
-      <tdml:error>Parse Error: Convert to Unlimited Size Decimal (for xs:decimal)</tdml:error>
-      <tdml:error>Unable to parse '9a9'</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>xs:decimal</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>9a9</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -3411,8 +3464,10 @@
 
     <tdml:document><![CDATA[9a99]]></tdml:document>
     <tdml:errors>
-      <tdml:error>Parse Error: Convert to Double (for xs:double)</tdml:error>
-      <tdml:error>Unable to parse '9a99'</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>xs:double</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>9a99</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -3467,8 +3522,10 @@
 
     <tdml:document><![CDATA[9a99]]></tdml:document>
     <tdml:errors>
-      <tdml:error>Parse Error: Convert to Float (for xs:float)</tdml:error>
-      <tdml:error>Unable to parse '9a99'</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>xs:float</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>9a99</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -4863,8 +4920,9 @@
     <tdml:document><![CDATA[1998-3-Mar]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error:</tdml:error>
-      <tdml:error>Convert to Date (for xs:date)</tdml:error>
-      <tdml:error>Failed to parse '1998-3-Mar'</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>xs:date</tdml:error>
+      <tdml:error>1998-3-Mar</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -4901,9 +4959,10 @@
 
     <tdml:document><![CDATA[12:43.45 PM]]></tdml:document>
     <tdml:errors>
-      <tdml:error>Parse Error:</tdml:error>
-      <tdml:error>Convert to Time (for xs:time)</tdml:error>
-      <tdml:error>Failed to parse '12:43.45 PM'</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>xs:time</tdml:error>
+      <tdml:error>12:43.45 PM</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -4941,8 +5000,9 @@
     <tdml:document><![CDATA[2013.03.24 03:45:30]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error:</tdml:error>
-      <tdml:error>Convert to DateTime (for xs:dateTime)</tdml:error>
-      <tdml:error>Failed to parse '2013.03.24 03:45:30'</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>xs:dateTime</tdml:error>
+      <tdml:error>2013.03.24 03:45:30</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -4960,7 +5020,8 @@
     <tdml:document><![CDATA[2013-03-24T03:45:30-00:00]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error:</tdml:error>
-      <tdml:error>Convert to DateTime (for xs:dateTime)</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>xs:dateTime</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -4978,7 +5039,8 @@
     <tdml:document><![CDATA[2013-03-24T03:45:30 Pacific Standard Time]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error:</tdml:error>
-      <tdml:error>Convert to DateTime (for xs:dateTime)</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>xs:dateTime</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -4996,7 +5058,8 @@
     <tdml:document><![CDATA[2013-03-24T03:45:30GMT]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error:</tdml:error>
-      <tdml:error>Convert to DateTime (for xs:dateTime)</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>xs:dateTime</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -6073,7 +6136,9 @@
 
     <tdml:document><![CDATA[12:30AM]]></tdml:document>
     <tdml:errors>
-      <tdml:error>Parse Error: Convert to Time</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>xs:time</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -6090,7 +6155,9 @@
 
     <tdml:document><![CDATA[00:30AM]]></tdml:document>
     <tdml:errors>
-      <tdml:error>Parse Error: Convert to Time</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>xs:time</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -7714,10 +7781,10 @@
 ]]></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-      <tdml:error>Convert to Unlimited Size Non Negative Integer</tdml:error>
-      <tdml:error>Out of Range</tdml:error>
-      <tdml:error>converted to -2</tdml:error>
-      <tdml:error>not in range for the type</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>xs:nonNegativeInteger</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>-2</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
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 983f1bf..fab1fa4 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
@@ -1651,8 +1651,9 @@
     <tdml:document>thisIsNotAnInteger</tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Integer (for xs:int)</tdml:error>
-      <tdml:error>Unable to parse 'thisIsNotAnInteger'</tdml:error>
+      <tdml:error>xs:int</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>thisIsNotAnInteger</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -1671,8 +1672,9 @@
     <tdml:document>thisIsNotAnInteger</tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Integer (for xs:int)</tdml:error>
-      <tdml:error>Unable to parse 'thisIsNotAnInteger'</tdml:error>
+      <tdml:error>xs:int</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>thisIsNotAnInteger</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section12/aligned_data/Aligned_Data.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section12/aligned_data/Aligned_Data.tdml
index f14a157..610dbfd 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section12/aligned_data/Aligned_Data.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section12/aligned_data/Aligned_Data.tdml
@@ -1187,9 +1187,9 @@
     </tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Unsigned Integer (for xs:unsignedInt)</tdml:error>
-      <tdml:error>Unable to parse '㐀</tdml:error>
-      <tdml:error>(using up all characters).</tdml:error>
+      <tdml:error>xs:unsignedInt</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>㐀</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -1515,9 +1515,9 @@
 
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Unsigned Byte</tdml:error>
-      <tdml:error>Out of Range: '-1' converted to -1</tdml:error>
-      <tdml:error>not in range for the type</tdml:error>
+      <tdml:error>xs:unsignedByte</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>-1</tdml:error>
     </tdml:errors>
 
   </tdml:parserTestCase>
@@ -1710,9 +1710,8 @@
 
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Float (for xs:float)</tdml:error>
+      <tdml:error>xs:float</tdml:error>
       <tdml:error>Unable to parse</tdml:error>
-      <tdml:error>(using up all characters).</tdml:error>
     </tdml:errors>
 
   </tdml:parserTestCase>
@@ -1882,9 +1881,8 @@
 
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Double (for xs:double)</tdml:error>
+      <tdml:error>xs:double</tdml:error>
       <tdml:error>Unable to parse</tdml:error>
-      <tdml:error>(using up all characters).</tdml:error>
     </tdml:errors>
 
   </tdml:parserTestCase>
@@ -2736,9 +2734,8 @@
 
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Unlimited Size Non Negative Integer (for xs:nonNegativeInteger)</tdml:error>
+      <tdml:error>xs:nonNegativeInteger</tdml:error>
       <tdml:error>Unable to parse</tdml:error>
-      <tdml:error>(using up all characters).</tdml:error>
     </tdml:errors>
 
   </tdml:parserTestCase>
@@ -2809,9 +2806,8 @@
 
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Unlimited Size Integer (for xs:integer)</tdml:error>
+      <tdml:error>xs:integer</tdml:error>
       <tdml:error>Unable to parse</tdml:error>
-      <tdml:error>(using up all characters).</tdml:error>
     </tdml:errors>
 
   </tdml:parserTestCase>
@@ -2882,9 +2878,8 @@
 
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Unlimited Size Decimal (for xs:decimal)</tdml:error>
+      <tdml:error>xs:decimal</tdml:error>
       <tdml:error>Unable to parse</tdml:error>
-      <tdml:error>(using up all characters).</tdml:error>
     </tdml:errors>
 
   </tdml:parserTestCase>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section12/length_properties/LengthProperties.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section12/length_properties/LengthProperties.tdml
index b9536e0..c413231 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section12/length_properties/LengthProperties.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section12/length_properties/LengthProperties.tdml
@@ -854,9 +854,9 @@
       dfdl:lengthKind="explicit" dfdl:length="16" dfdl:byteOrder="littleEndian" />
     <xs:element name="bit5" type="xs:unsignedInt"
       dfdl:lengthKind="explicit" dfdl:length="16" dfdl:byteOrder="bigEndian" />
-    <xs:element name="bit6" type="xs:unsignedShort"
+    <xs:element name="bit6" type="xs:unsignedInt"
       dfdl:lengthKind="explicit" dfdl:length="24" dfdl:alignment="1" dfdl:byteOrder="bigEndian" />
-    <xs:element name="bit7" type="xs:unsignedShort"
+    <xs:element name="bit7" type="xs:unsignedInt"
       dfdl:lengthKind="explicit" dfdl:length="24" dfdl:alignment="1" dfdl:byteOrder="littleEndian" />
     <xs:element name="bit8" type="xs:unsignedShort"
       dfdl:lengthKind="explicit" dfdl:length="9" dfdl:alignment="1" dfdl:byteOrder="bigEndian" />
@@ -866,8 +866,8 @@
     <xs:element name="s1">
       <xs:complexType>
         <xs:sequence dfdl:separator="">
-          <xs:element name="bit10" type="xs:unsignedByte" dfdl:lengthKind="explicit" dfdl:length="9" dfdl:byteOrder="bigEndian" />
-          <xs:element name="bit11" type="xs:unsignedByte" dfdl:lengthKind="explicit" dfdl:length="10" dfdl:byteOrder="littleEndian"/>
+          <xs:element name="bit10" type="xs:unsignedShort" dfdl:lengthKind="explicit" dfdl:length="9" dfdl:byteOrder="bigEndian" />
+          <xs:element name="bit11" type="xs:unsignedShort" dfdl:lengthKind="explicit" dfdl:length="10" dfdl:byteOrder="littleEndian"/>
         </xs:sequence>
       </xs:complexType>
     </xs:element>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section13/text_number_props/TextNumberProps.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section13/text_number_props/TextNumberProps.tdml
index f74d23f..7415d84 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section13/text_number_props/TextNumberProps.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section13/text_number_props/TextNumberProps.tdml
@@ -419,7 +419,9 @@
     </tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Unable to parse '(4,3,0.00)</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>xs:float</tdml:error>
+      <tdml:error>(4,3,0.00)</tdml:error>
     </tdml:errors>
 
   </tdml:parserTestCase>
@@ -2273,7 +2275,7 @@
     </tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Integer (for xs:int)</tdml:error>
+      <tdml:error>xs:int</tdml:error>
       <tdml:error>Unable to parse</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
@@ -2293,7 +2295,7 @@
     </tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Integer (for xs:int)</tdml:error>
+      <tdml:error>xs:int</tdml:error>
       <tdml:error>Unable to parse</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
@@ -3239,7 +3241,7 @@
     </tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Integer</tdml:error>
+      <tdml:error>xs:int</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -3258,8 +3260,9 @@
     </tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Integer (for xs:int)</tdml:error>
-      <tdml:error>Unable to parse '123'</tdml:error>
+      <tdml:error>xs:int</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>123</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -3278,8 +3281,9 @@
     </tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Integer (for xs:int)</tdml:error>
-      <tdml:error>Unable to parse '*****'</tdml:error>
+      <tdml:error>xs:int</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>*****</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -3300,8 +3304,9 @@
     </tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Unsigned Integer (for xs:unsignedInt)</tdml:error>
-      <tdml:error>Out of Range: '(123)' converted to -123, is not in range for the type</tdml:error>
+      <tdml:error>xs:unsignedInt</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>-123</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
@@ -3322,8 +3327,9 @@
     </tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Unsigned Short (for xs:unsignedShort)</tdml:error>
-      <tdml:error>Out of Range: '-123' converted to -123, is not in range for the type</tdml:error>
+      <tdml:error>xs:unsignedShort</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>-123</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -3759,7 +3765,9 @@
 
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Double (for xs:double): Unable to parse '1234567.89AbC2'</tdml:error>
+      <tdml:error>xs:double</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>1234567.89AbC2</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -4039,7 +4047,9 @@
 
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Unable to parse 'NOTANUMBER'</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>xs:long</tdml:error>
+      <tdml:error>NOTANUMBER</tdml:error>
     </tdml:errors>
 
   </tdml:parserTestCase>
@@ -4059,7 +4069,9 @@
 
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Unable to parse 'INFINITY'</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>xs:long</tdml:error>
+      <tdml:error>INFINITY</tdml:error>
     </tdml:errors>
 
   </tdml:parserTestCase>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section13/zoned/zoned.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section13/zoned/zoned.tdml
index c0be5d5..6d82475 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section13/zoned/zoned.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section13/zoned/zoned.tdml
@@ -137,7 +137,8 @@
       <tdml:documentPart type="text">1988</tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-      <tdml:error>Zoned not supported for float and double</tdml:error>
+      <tdml:error>textNumberRep="zoned"</tdml:error>
+      <tdml:error>xs:float</tdml:error>
     </tdml:errors>
 
   </tdml:parserTestCase>
@@ -149,7 +150,8 @@
       <tdml:documentPart type="text">1988</tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-      <tdml:error>Zoned not supported for float and double</tdml:error>
+      <tdml:error>textNumberRep="zoned"</tdml:error>
+      <tdml:error>xs:double</tdml:error>
     </tdml:errors>
 
   </tdml:parserTestCase>
@@ -189,7 +191,7 @@
       <tdml:documentPart type="text">z234567890</tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-      <tdml:error>NumberFormatException: Invalid zoned digit</tdml:error>
+      <tdml:error>Invalid zoned digit</tdml:error>
     </tdml:errors>
 
   </tdml:parserTestCase>
@@ -257,7 +259,7 @@
       <tdml:documentPart type="text">z234567890</tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-      <tdml:error>NumberFormatException: Invalid zoned digit</tdml:error>
+      <tdml:error>Invalid zoned digit</tdml:error>
     </tdml:errors>
 
   </tdml:parserTestCase>
@@ -325,7 +327,7 @@
       <tdml:documentPart type="text">z234567890</tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-      <tdml:error>NumberFormatException: Invalid zoned digit</tdml:error>
+      <tdml:error>Invalid zoned digit</tdml:error>
     </tdml:errors>
 
   </tdml:parserTestCase>
@@ -393,7 +395,7 @@
       <tdml:documentPart type="text">z234567890</tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-      <tdml:error>NumberFormatException: Invalid zoned digit</tdml:error>
+      <tdml:error>Invalid zoned digit</tdml:error>
     </tdml:errors>
 
   </tdml:parserTestCase>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequenceGroup.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequenceGroup.tdml
index b598a34..c506124 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequenceGroup.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequenceGroup.tdml
@@ -874,8 +874,9 @@
       <tdml:documentPart type="text"><![CDATA[1:2,3]]></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-      <tdml:error>Parse Error: Convert to Integer</tdml:error>
-      <tdml:error>Unable to parse ':'</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>xs:int</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequenceGroupDelimiters.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequenceGroupDelimiters.tdml
index 7e71430..c45ad1d 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequenceGroupDelimiters.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequenceGroupDelimiters.tdml
@@ -468,9 +468,9 @@
     <tdml:document><![CDATA[450Item: Shirts]]></tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-      <tdml:error>Convert to Integer (for xs:int)</tdml:error>
-      <tdml:error>Unable to parse '450Item: Shirts'</tdml:error>
-      <tdml:error>(using up all characters)</tdml:error>
+      <tdml:error>xs:int</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>450Item: Shirts</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/ChoiceGroupInitiatedContent.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/ChoiceGroupInitiatedContent.tdml
index c02b16b..53d9a33 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/ChoiceGroupInitiatedContent.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/ChoiceGroupInitiatedContent.tdml
@@ -269,8 +269,8 @@
     <tdml:errors>
       <tdml:error>noi</tdml:error>
       <tdml:error>noi</tdml:error>
-      <tdml:error>convert</tdml:error>
-      <tdml:error>unable to parse</tdml:error>
+      <tdml:error>xs:int</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/choice.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/choice.tdml
index e08bc78..0273105 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/choice.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/choice.tdml
@@ -300,9 +300,11 @@
     <tdml:document><![CDATA[AAA]]></tdml:document>
 
     <tdml:errors>
-      <tdml:error>Convert</tdml:error>
-      <tdml:error>float</tdml:error>
-      <tdml:error>int</tdml:error>
+      <tdml:error>Parse Error</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>xs:int</tdml:error>
+      <tdml:error>xs:float</tdml:error>
+      <tdml:error>AAA</tdml:error>
       <tdml:error>Alternative failed</tdml:error>
       <tdml:error>All choice alternatives failed</tdml:error>
 
@@ -1789,8 +1791,8 @@ it sure is/
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
       <tdml:error>Choice dispatch branch failed</tdml:error>
-      <tdml:error>Convert</tdml:error>
-      <tdml:error>integer</tdml:error>
+      <tdml:error>Unable to parse</tdml:error>
+      <tdml:error>xs:int</tdml:error>
       <tdml:error>fail</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/Functions.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/Functions.tdml
index 1ecd306..150aec9 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/Functions.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/Functions.tdml
@@ -9055,7 +9055,7 @@
     </tdml:document>
     <tdml:errors>
       <tdml:error>Parse Error</tdml:error>
-    <tdml:error>out of range</tdml:error>
+      <tdml:error>out of range</tdml:error>
       <tdml:error>unsignedInt</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
@@ -11691,8 +11691,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 208 out of range for Byte type</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>byte</tdml:error>
+      <tdml:error>208</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -11732,8 +11734,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 208 out of range for Byte type</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>byte</tdml:error>
+      <tdml:error>208</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -11773,8 +11777,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 208 out of range for Byte type</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>byte</tdml:error>
+      <tdml:error>208</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -11834,8 +11840,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 208 out of range for Byte type</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>byte</tdml:error>
+      <tdml:error>208</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -11895,8 +11903,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 256 out of range for unsigned byte</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>unsignedByte</tdml:error>
+      <tdml:error>256</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -11936,8 +11946,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 256 out of range for unsigned byte</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>unsignedByte</tdml:error>
+      <tdml:error>256</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -12018,8 +12030,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 256 out of range for unsigned byte</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>unsignedByte</tdml:error>
+      <tdml:error>256</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -12099,8 +12113,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 32768 out of range for Short type</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>short</tdml:error>
+      <tdml:error>32768</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -12140,8 +12156,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 32768 out of range for Short type</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>short</tdml:error>
+      <tdml:error>32768</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -12181,8 +12199,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 32768 out of range for Short type</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>short</tdml:error>
+      <tdml:error>32768</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -12222,8 +12242,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 32768 out of range for Short type</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>short</tdml:error>
+      <tdml:error>32768</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -12303,8 +12325,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 65536 out of range for unsigned short</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>unsignedShort</tdml:error>
+      <tdml:error>65536</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -12344,8 +12368,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 65536 out of range for unsigned short</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>unsignedShort</tdml:error>
+      <tdml:error>65536</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -12426,8 +12452,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 65536 out of range for unsigned short</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>unsignedShort</tdml:error>
+      <tdml:error>65536</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -12506,8 +12534,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 2147483648 out of range for Int type</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>int</tdml:error>
+      <tdml:error>2147483648</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -12547,8 +12577,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 2147483648 out of range for Int type</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>int</tdml:error>
+      <tdml:error>2147483648</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -12588,8 +12620,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 2147483648 out of range for Int type</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>int</tdml:error>
+      <tdml:error>2147483648</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -12629,8 +12663,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 2147483648 out of range for Int type</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>int</tdml:error>
+      <tdml:error>2147483648</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -12772,8 +12808,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 4294967296 out of range for unsigned int</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>unsignedInt</tdml:error>
+      <tdml:error>4294967296</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -12813,8 +12851,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 4294967296 out of range for unsigned int</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>unsignedInt</tdml:error>
+      <tdml:error>4294967296</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -12896,8 +12936,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 4294967296 out of range for unsigned int</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>unsignedInt</tdml:error>
+      <tdml:error>4294967296</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -12956,8 +12998,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Negative value -1 cannot be converted to an unsigned int</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>unsignedInt</tdml:error>
+      <tdml:error>-1</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -12998,8 +13042,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 9223372036854775808 out of range for Long type</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>long</tdml:error>
+      <tdml:error>9223372036854775808</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -13121,8 +13167,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 9223372036854775808 out of range for Long type</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>long</tdml:error>
+      <tdml:error>9223372036854775808</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -13224,8 +13272,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 18446744073709551616 out of range for UnsignedLong type</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>unsignedLong</tdml:error>
+      <tdml:error>18446744073709551616</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -13265,8 +13315,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 18446744073709551616 out of range for UnsignedLong type</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>unsignedLong</tdml:error>
+      <tdml:error>18446744073709551616</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -13347,8 +13399,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Value 18446744073709551616 out of range for UnsignedLong type</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>unsignedLong</tdml:error>
+      <tdml:error>18446744073709551616</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
   
@@ -13407,8 +13461,10 @@
       <tdml:documentPart type="text"></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-    	<tdml:error>Schema Definition Error</tdml:error>
-    	<tdml:error>Negative value -1 cannot be converted to an unsigned long</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>out of range</tdml:error>
+      <tdml:error>unsignedLong</tdml:error>
+      <tdml:error>-1</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>