You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@daffodil.apache.org by ja...@apache.org on 2019/10/02 20:14:16 UTC

[incubator-daffodil] branch master updated: Implemented unordered sequences

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

jadams 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 e23ed92  Implemented unordered sequences
e23ed92 is described below

commit e23ed924e1aab5a378c6b6686064577befceb82c
Author: Josh Adams <ja...@tresys.com>
AuthorDate: Thu Jul 11 09:52:34 2019 -0400

    Implemented unordered sequences
    
    Unordered sequences are now ipmlemented using a choice of the sequence
    member parsers. This choice is then looped over until we either consume
    all the data or hit a failure. The parsed infoset is then sorted into
    schema definition order, and unparsing is identical to ordered
    sequences.
    
    DAFFODIL-1159
---
 .../org/apache/daffodil/dsom/ElementBase.scala     |   1 +
 .../org/apache/daffodil/dsom/SequenceGroup.scala   |   1 -
 .../main/scala/org/apache/daffodil/dsom/Term.scala |  10 +-
 .../org/apache/daffodil/grammar/AlignedMixin.scala |  30 +-
 .../daffodil/grammar/SequenceGrammarMixin.scala    |  18 +-
 .../grammar/primitives/ElementCombinator.scala     |  33 +-
 .../grammar/primitives/SequenceChild.scala         |   4 +-
 .../grammar/primitives/SequenceCombinator.scala    |  79 +++
 .../apache/daffodil/dsom/TestDsomCompiler.scala    |   2 +-
 .../daffodil/dsom/TestMiddleEndAttributes.scala    |  14 +-
 .../org/apache/daffodil/infoset/InfosetImpl.scala  |  62 ++-
 .../apache/daffodil/processors/RuntimeData.scala   |   3 +
 .../processors/parsers/ElementCombinator1.scala    |  56 --
 .../SeparatedSequenceChildParseResultHelper.scala  |  20 +-
 .../parsers/SeparatedSequenceParsers.scala         |  32 +-
 .../processors/parsers/SequenceChildBases.scala    |   9 +
 .../processors/parsers/SequenceParserBases.scala   |  32 +-
 .../parsers/UnorderedSequenceParser.scala          | 168 ------
 .../parsers/UnseparatedSequenceParsers.scala       |  14 +-
 .../unordered_sequences/UnorderedSequences.tdml    | 610 ++++++++++-----------
 .../TestUnorderedSequencesNew.scala                |  57 +-
 21 files changed, 617 insertions(+), 638 deletions(-)

diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementBase.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementBase.scala
index 09d98a7..e2c635a 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementBase.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ElementBase.scala
@@ -541,6 +541,7 @@ trait ElementBase
       elementChildren.map { _.elementRuntimeData }
 
     val newERD: ElementRuntimeData = new ElementRuntimeData(
+      position,
       childrenERDs,
       schemaSet.variableMap,
       nextElementResolver,
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SequenceGroup.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SequenceGroup.scala
index 9ed2d58..76a9196 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SequenceGroup.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SequenceGroup.scala
@@ -275,7 +275,6 @@ abstract class SequenceGroupTermBase(
   }
 
   final def isLayered = maybeLayerTransformerEv.isDefined
-
 }
 
 /**
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Term.scala b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Term.scala
index 8b73566..cf2cd41 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Term.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/Term.scala
@@ -282,6 +282,8 @@ trait Term
     case Some(_) => enclosingTerm.get.nearestEnclosingUnorderedSequence
   }
 
+  final lazy val isInUnorderedSequence: Boolean = !nearestEnclosingUnorderedSequence.isEmpty
+
   final lazy val nearestEnclosingUnorderedSequenceBeforeSequence: Option[SequenceTermBase] = enclosingTerm match {
     case None => None
     case Some(s: SequenceTermBase) if !s.isOrdered => Some(s)
@@ -564,13 +566,15 @@ trait Term
    * terms that could appear before this. The second item in the tuple is a
    * One(enclosingParent) if all prior siblings are optional or this element has no prior siblings
    */
-  lazy val potentialPriorTerms: (Seq[Term], Option[Term]) = {
+  lazy val potentialPriorTerms: (Seq[Term], Option[Term]) = LV('potentialPriorTerms) {
     val et = enclosingTerm
     val (potentialPrior, optEnclosingParent) = et match {
       case None => (Seq(), None)
       case Some(eb: ElementBase) => (Seq(), Some(eb))
       case Some(ch: ChoiceTermBase) => (Seq(), Some(ch))
-      case Some(sq: SequenceTermBase) if !sq.isOrdered => (sq.groupMembers, Some(sq))
+      case Some(sq: SequenceTermBase) if !sq.isOrdered => {
+        (sq.groupMembers, Some(sq))
+      }
       case Some(sq: SequenceTermBase) if sq.isOrdered => {
         val previousTerms = sq.groupMembers.takeWhile { _ != this }
         if (previousTerms.isEmpty) {
@@ -600,7 +604,7 @@ trait Term
       }
     }
     (potentialPriorRepresented, optEnclosingParent)
-  }
+  }.value
 
   /*
    * This function returns at list of simple elements that are descendents of
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/AlignedMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/AlignedMixin.scala
index 92d1ebe..d3d1244 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/AlignedMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/AlignedMixin.scala
@@ -52,7 +52,7 @@ trait AlignedMixin extends GrammarMixin { self: Term =>
    * will be properly aligned by where the prior thing left us positioned.
    * Hence we are guaranteed to be properly aligned.
    */
-  final def isKnownToBeAligned: Boolean = LV('isKnownToBeAligned) {
+  final lazy val isKnownToBeAligned: Boolean = LV('isKnownToBeAligned) {
     if (!isRepresented) {
       true
     } else {
@@ -71,7 +71,7 @@ trait AlignedMixin extends GrammarMixin { self: Term =>
    * This goes further TermEncodingMixin.hasTextAlignment because it
    * considers the surrounding context meeting the alignment needs.
    */
-  final lazy val isKnownToBeTextAligned: Boolean = {
+  final lazy val isKnownToBeTextAligned: Boolean = LV('isKnownToBeTextAligned) {
     if (self.encodingInfo.isKnownEncoding) {
       if (self.encodingInfo.knownEncodingAlignmentInBits == 1)
         true
@@ -83,7 +83,7 @@ trait AlignedMixin extends GrammarMixin { self: Term =>
       true
     else
       false
-  }
+  }.value
 
   final lazy val isDelimiterKnownToBeTextAligned: Boolean = {
     if (self.encodingInfo.isKnownEncoding) {
@@ -123,13 +123,13 @@ trait AlignedMixin extends GrammarMixin { self: Term =>
     }
   }
 
-  private lazy val trailingSkipApprox: LengthApprox = {
+  protected lazy val trailingSkipApprox: LengthApprox = {
     LengthExact(trailingSkipInBits)
   }
 
   private lazy val unaligned = AlignmentMultipleOf(1)
 
-  private lazy val priorAlignmentApprox: AlignmentMultipleOf = {
+  private lazy val priorAlignmentApprox: AlignmentMultipleOf = LV('priorAlignmentApprox) {
     if (this.isInstanceOf[Root] || this.isInstanceOf[QuasiElementDeclBase]) {
       AlignmentMultipleOf(0) // root and quasi elements are aligned with anything
     } else {
@@ -172,10 +172,21 @@ trait AlignedMixin extends GrammarMixin { self: Term =>
           Seq()
         }
 
+      val unorderedSequenceSelfAlignment =
+        if (isInUnorderedSequence) {
+          Seq(alignmentApprox + (elementSpecifiedLengthApprox + trailingSkipApprox))
+        } else {
+          Seq()
+        }
+
       val priorSibsAlignmentsApprox = priorSibs.map { ps =>
-        val eaa = ps.endingAlignmentApprox
+        val eaa = if (isInUnorderedSequence) {
+          alignmentApprox + (ps.elementSpecifiedLengthApprox + ps.trailingSkipApprox)
+        } else {
+          ps.endingAlignmentApprox
+        }
         eaa
-      }
+      }.toSeq
       val parentAlignmentApprox = optEnclosingParent.map { p =>
         val csa = p.contentStartAlignment
         csa
@@ -186,7 +197,7 @@ trait AlignedMixin extends GrammarMixin { self: Term =>
       else
         priorAlignmentsApprox.reduce(_ * _)
     }
-  }
+  }.value
 
   private lazy val priorAlignmentWithLeadingSkipApprox: AlignmentMultipleOf = {
     priorAlignmentApprox + leadingSkipApprox
@@ -233,7 +244,7 @@ trait AlignedMixin extends GrammarMixin { self: Term =>
     }
   }
 
-  private lazy val elementSpecifiedLengthApprox: LengthApprox = {
+  protected lazy val elementSpecifiedLengthApprox: LengthApprox = {
     this match {
       case eb: ElementBase => {
         eb.lengthKind match {
@@ -265,6 +276,7 @@ trait AlignedMixin extends GrammarMixin { self: Term =>
           case LengthKind.Prefixed => LengthMultipleOf(1) // NYI
         }
       }
+      case mg: ModelGroup => Assert.usageError("Only for elements")
     }
   }
 
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/SequenceGrammarMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/SequenceGrammarMixin.scala
index 9901baf..2717e7a 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/SequenceGrammarMixin.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/SequenceGrammarMixin.scala
@@ -22,6 +22,7 @@ import org.apache.daffodil.dsom._
 import org.apache.daffodil.exceptions.Assert
 import org.apache.daffodil.grammar.primitives._
 import org.apache.daffodil.grammar.primitives.OrderedSequence
+import org.apache.daffodil.grammar.primitives.UnorderedSequence
 
 trait SequenceGrammarMixin extends GrammarMixin { self: SequenceTermBase =>
 
@@ -34,7 +35,7 @@ trait SequenceGrammarMixin extends GrammarMixin { self: SequenceTermBase =>
     import columnConstants._
     self.sequenceKind match {
       case Ordered__ => orderedSequence
-      case Unordered => subsetError("Unordered sequences are not supported.") // unorderedSequenceContent
+      case Unordered => unorderedSequence
     }
   }
 
@@ -58,6 +59,12 @@ trait SequenceGrammarMixin extends GrammarMixin { self: SequenceTermBase =>
     res
   }
 
+  private lazy val unorderedSequence = {
+    val alternatives = groupMembers.map { _.termContentBody }
+    val res = new UnorderedSequence(this, seqChildren, alternatives)
+    res
+  }
+
   /**
    * Constants to make the lookup tables below more readable without using fragile whitespace
    */
@@ -117,9 +124,8 @@ trait SequenceGrammarMixin extends GrammarMixin { self: SequenceTermBase =>
         separatorSuppressionPolicy
 
     val res = (child, sequenceKind, ssp, ock, min, max) match {
-      case (e: EB, Ordered__, ___________, _________, ONE, ONE) => new ScalarOrderedSequenceChild(this, e, groupIndex)
+      case (e: EB, Ordered__, ___________, __________, ONE, ONE) => new ScalarOrderedSequenceChild(this, e, groupIndex)
       case (e: EB, _________, ___________, StopValue_, ___, __2) => e.subsetError("dfdl:occursCountKind 'stopValue' is not supported.")
-      case (_____, Unordered, ___________, __________, ___, __2) => this.subsetError("Unordered sequences are not supported.")
       case (e: EB, Ordered__, ___________, Parsed____, ___, __2) => new RepOrderedWithMinMaxSequenceChild(this, e, groupIndex)
       case (e: EB, Ordered__, ___________, Fixed_____, ___, UNB) => e.SDE("occursCountKind='fixed' not allowed with unbounded maxOccurs")
       case (e: EB, Ordered__, Never______, Implicit__, ___, UNB) if !e.isLastDeclaredRepresentedInSequence => unboundedPositionalError(e)
@@ -135,7 +141,11 @@ trait SequenceGrammarMixin extends GrammarMixin { self: SequenceTermBase =>
       case (e: EB, Ordered__, TrailingStr, Implicit__, ___, UNB) => new RepOrderedWithMinMaxSequenceChild(this, e, groupIndex)
       case (e: EB, Ordered__, TrailingStr, Implicit__, ___, max) => new RepOrderedWithMinMaxSequenceChild(this, e, groupIndex)
       case (e: EB, Ordered__, Always_____, Implicit__, ___, max) => new RepOrderedWithMinMaxSequenceChild(this, e, groupIndex)
-      case (m: MG, Ordered__, ___________, __________, ___, __2) => new ScalarOrderedSequenceChild(this, m, groupIndex)
+      case (e: EB, Unordered, ___________, __________, ___, ONE) => new ScalarOrderedSequenceChild(this, e, groupIndex)
+      case (e: EB, Unordered, ___________, Parsed____, ___, max) => new RepOrderedWithMinMaxSequenceChild(this, e, groupIndex)
+      case (e: EB, Unordered, ___________, __________, ___, __2) => e.SDE("When sequenceKind='unordered', occursCountKind must be 'parsed'")
+      case (m: MG, Unordered, ___________, __________, ___, __2) => child.SDE("All memebers of an unordered sequence must be Element or ElemenntRef")
+      case (m: MG, _________, ___________, __________, ___, __2) => new ScalarOrderedSequenceChild(this, m, groupIndex)
       case (_____, _________, policy /**/ , ock /**/ , ___, __2) => child.SDE("separatorSuppressionPolicy='" + policy + "' not allowed with occursCountKind='" + ock + "'.")
     }
     res
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/ElementCombinator.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/ElementCombinator.scala
index 0bafdf9..91254b2 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/ElementCombinator.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/ElementCombinator.scala
@@ -23,7 +23,6 @@ import org.apache.daffodil.exceptions.Assert
 import org.apache.daffodil.grammar.Gram
 import org.apache.daffodil.grammar.NamedGram
 import org.apache.daffodil.grammar.Terminal
-import org.apache.daffodil.processors.parsers.ChoiceElementParser
 import org.apache.daffodil.processors.parsers.ElementParser
 import org.apache.daffodil.processors.parsers.ElementParserNoRep
 import org.apache.daffodil.processors.parsers.Parser
@@ -79,17 +78,10 @@ class ElementCombinator(
   extends NamedGram(context)
   with Padded {
 
-  override def toString = subComb.toString() // parse centric view of the world. Unparser doesn't use subComb at all.
+  override def toString = subComb.toString()
 
-  private lazy val subComb = {
-    if (context.isParentUnorderedSequence) {
-      new ChoiceElementCombinator(context, eBeforeContent,
-        eValue, eAfterValue)
-    } else {
-      new ElementParseAndUnspecifiedLength(context, eBeforeContent,
-        eValue, eAfterValue, repTypeElementGram)
-    }
-  }
+  private lazy val subComb = new ElementParseAndUnspecifiedLength(context, eBeforeContent,
+    eValue, eAfterValue, repTypeElementGram)
 
   override lazy val parser: Parser = {
     //
@@ -340,25 +332,6 @@ class ElementParseAndUnspecifiedLength(context: ElementBase, eBeforeGram: Gram,
   }
 }
 
-class ChoiceElementCombinator(context: ElementBase, eGramBefore: Gram, eGram: Gram, eAfterGram: Gram)
-  extends ElementCombinatorBase(context, eGramBefore, eGram, eAfterGram,  EmptyGram) {
-
-  lazy val parser: Parser = new ChoiceElementParser(
-    context.erd,
-    context.name,
-    patDiscrim,
-    patAssert,
-    pSetVar,
-    testDiscrim,
-    testAssert,
-    eBeforeParser,
-    eParser,
-    eAfterParser)
-
-  lazy val unparser = hasNoUnparser
-
-}
-
 abstract class ElementCombinatorBase(context: ElementBase, eGramBefore: Gram, eGram: Gram, eGramAfter: Gram, repTypeElementGram:Gram)
   extends NamedGram(context) {
 
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/SequenceChild.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/SequenceChild.scala
index d62c56f..abbb239 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/SequenceChild.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/SequenceChild.scala
@@ -407,7 +407,7 @@ class ScalarOrderedSequenceChild(sq: SequenceTermBase, term: Term, groupIndex: I
     }
     res
   }
-  lazy val sequenceChildUnparser: SequenceChildUnparser = {
+  override lazy val sequenceChildUnparser: SequenceChildUnparser = {
     val res =
       if (sq.hasSeparator) {
         new ScalarOrderedSeparatedSequenceChildUnparser(
@@ -487,7 +487,7 @@ sealed abstract class RepElementSequenceChild(
 
   Assert.usage(!e.isScalar)
 
-  lazy val sequenceChildUnparser: SequenceChildUnparser =
+  override lazy val sequenceChildUnparser: SequenceChildUnparser =
     sq.hasSeparator match {
       case true => {
         new RepOrderedSeparatedSequenceChildUnparser(
diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/SequenceCombinator.scala b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/SequenceCombinator.scala
index 7d33820..0b84621 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/SequenceCombinator.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/SequenceCombinator.scala
@@ -18,8 +18,10 @@
 package org.apache.daffodil.grammar.primitives
 
 import org.apache.daffodil.grammar.Terminal
+import org.apache.daffodil.grammar.Gram
 import org.apache.daffodil.dsom._
 import org.apache.daffodil.processors.parsers._
+import org.apache.daffodil.schema.annotation.props.SeparatorSuppressionPolicy
 import org.apache.daffodil.processors.unparsers._
 import org.apache.daffodil.util.Misc
 
@@ -76,3 +78,80 @@ class OrderedSequence(sq: SequenceTermBase, sequenceChildrenArg: Seq[SequenceChi
     }
   }
 }
+
+class UnorderedSequence(sq: SequenceTermBase, sequenceChildrenArg: Seq[SequenceChild], alternatives: Seq[Gram])
+  extends SequenceCombinator(sq, sequenceChildrenArg) {
+
+  import SeparatedSequenceChildBehavior._
+
+  private lazy val sepGram = sq.sequenceSeparator
+  private lazy val sepParser = sepGram.parser
+  private lazy val sepUnparser = sepGram.unparser
+
+  private lazy val sequenceChildren = sequenceChildrenArg.toVector
+
+
+  private lazy val parsers = alternatives.map(_.parser)
+
+
+  override lazy val parser: Parser = {
+
+    lazy val choiceParser = new ChoiceParser(srd, parsers.toVector)
+
+    sq.hasSeparator match {
+      case true => {
+        lazy val groupHelper = new NonPositionalGroupSeparatedSequenceChildParseResultHelper(
+          srd,
+          NonPositional,
+          true,  // Due to the nature of UOSeqs, could potentially be empty
+          false) // and does not have required syntax
+
+        lazy val groupParser = new GroupSeparatedUnorderedSequenceChildParser(
+          choiceParser,
+          srd,
+          srd, // Won't actually be used
+          sepParser,
+          sq.separatorPosition,
+          groupHelper)
+
+        new UnorderedSeparatedSequenceParser(
+          srd, sq.separatorPosition, sepParser,
+          Vector(groupParser))
+      }
+      case false => {
+        lazy val groupHelper = new GroupUnseparatedSequenceChildParseResultHelper(
+          srd,
+          true,  // Due to the nature of UOSeqs, could potentially be empty
+          false) // and does not have required syntax
+
+        lazy val groupParser = new ScalarUnorderedUnseparatedSequenceChildParser(
+          choiceParser,
+          srd,
+          srd, // Won't actually be used
+          groupHelper)
+
+        new UnorderedUnseparatedSequenceParser(
+          srd,
+          Vector(groupParser))
+      }
+    }
+  }
+
+  override lazy val unparser: Unparser = {
+    sq.checkHiddenSequenceIsDefaultableOrOVC
+    val childUnparsers = sequenceChildren.flatMap { _.optSequenceChildUnparser }
+    if (childUnparsers.isEmpty) new NadaUnparser(null)
+    else {
+      sq.hasSeparator match {
+        case true => new OrderedSeparatedSequenceUnparser(
+          srd,
+          SeparatorSuppressionPolicy.AnyEmpty, sq.separatorPosition, sepUnparser,
+          childUnparsers)
+        case false =>
+          new OrderedUnseparatedSequenceUnparser(
+            srd,
+            childUnparsers)
+      }
+    }
+  }
+}
diff --git a/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestDsomCompiler.scala b/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestDsomCompiler.scala
index b717009..ee0df4e 100644
--- a/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestDsomCompiler.scala
+++ b/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestDsomCompiler.scala
@@ -588,7 +588,7 @@ class TestDsomCompiler extends Logging {
       </dfdl:defineEscapeScheme>,
       <xs:element name="list">
         <xs:complexType>
-          <xs:sequence>
+          <xs:sequence dfdl:sequenceKind="ordered">
             <xs:element name="character" type="xsd:string" maxOccurs="unbounded" dfdl:representation="text" dfdl:separator="," dfdl:terminator="%NL;"/>
             <xs:element name="block" type="xsd:string" maxOccurs="unbounded" dfdl:representation="text" dfdl:separator="," dfdl:terminator="%NL;" dfdl:escapeSchemeRef="cStyleComment"/>
           </xs:sequence>
diff --git a/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestMiddleEndAttributes.scala b/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestMiddleEndAttributes.scala
index a26e7c4..b65f8ce 100644
--- a/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestMiddleEndAttributes.scala
+++ b/daffodil-core/src/test/scala/org/apache/daffodil/dsom/TestMiddleEndAttributes.scala
@@ -35,7 +35,7 @@ class TestMiddleEndAttributes {
       <dfdl:format representation="text" lengthUnits="bytes" encoding="US-ASCII" initiator="" terminator="" separator="" ignoreCase="no"/>,
       <xs:element name="e1" dfdl:lengthKind="implicit">
         <xs:complexType>
-          <xs:sequence>
+          <xs:sequence dfdl:sequenceKind="ordered">
             <xs:element name="s1" type="xs:string" dfdl:lengthKind="explicit" dfdl:length="{ 1 }"/>
             <xs:element name="s2" type="xs:string" dfdl:lengthKind="explicit" dfdl:length="{ 1 }"/>
           </xs:sequence>
@@ -65,7 +65,7 @@ class TestMiddleEndAttributes {
       <dfdl:format representation="text" occursCountKind="parsed" lengthUnits="bytes" encoding="US-ASCII" initiator="" terminator="" separator="" ignoreCase="no"/>,
       <xs:element name="e1" dfdl:lengthKind="implicit">
         <xs:complexType>
-          <xs:sequence>
+          <xs:sequence dfdl:sequenceKind="ordered">
             <xs:element name="s1" type="xs:string" minOccurs="0" dfdl:lengthKind="explicit" dfdl:length="{ 1 }"/>
             <xs:element name="s2" type="xs:string" minOccurs="0" dfdl:lengthKind="explicit" dfdl:length="{ 1 }"/>
           </xs:sequence>
@@ -95,7 +95,7 @@ class TestMiddleEndAttributes {
       <dfdl:format representation="text" occursCountKind="parsed" lengthUnits="bytes" encoding="US-ASCII" initiator="" terminator="" separator="" ignoreCase="no"/>,
       <xs:element name="e1" dfdl:lengthKind="implicit">
         <xs:complexType>
-          <xs:sequence>
+          <xs:sequence dfdl:sequenceKind="ordered">
             <xs:element name="s1" type="xs:string" minOccurs="0" dfdl:lengthKind="explicit" dfdl:length="{ 1 }"/>
             <xs:element name="s2" type="xs:string" dfdl:lengthKind="explicit" dfdl:length="{ 1 }"/>
             <xs:element name="s3" type="xs:string" minOccurs="0" dfdl:lengthKind="explicit" dfdl:length="{ 1 }"/>
@@ -138,7 +138,7 @@ class TestMiddleEndAttributes {
       <dfdl:format representation="text" occursCountKind="parsed" lengthUnits="bytes" encoding="US-ASCII" initiator="" terminator="" separator="" ignoreCase="no"/>,
       <xs:element name="e1" dfdl:lengthKind="implicit">
         <xs:complexType>
-          <xs:sequence dfdl:separator="," dfdl:separatorPosition="infix">
+          <xs:sequence dfdl:sequenceKind="ordered" dfdl:separator="," dfdl:separatorPosition="infix">
             <xs:choice>
               <xs:element name="s1" type="xs:int" dfdl:lengthKind="explicit" dfdl:length="{ 1 }"/>
               <xs:element name="s2" type="xs:string" dfdl:lengthKind="explicit" dfdl:length="{ 1 }"/>
@@ -180,7 +180,7 @@ class TestMiddleEndAttributes {
       <xs:element name="e1" dfdl:lengthKind="explicit" dfdl:length="{ 1 }"/>
       <xs:element name="e2" dfdl:lengthKind="implicit">
         <xs:complexType>
-          <xs:sequence dfdl:separator="," dfdl:separatorPosition="infix">
+          <xs:sequence dfdl:sequenceKind="ordered" dfdl:separator="," dfdl:separatorPosition="infix">
             <xs:element ref="e1"/>
           </xs:sequence>
         </xs:complexType>
@@ -214,7 +214,7 @@ class TestMiddleEndAttributes {
 
       <xs:element name="doc">
         <xs:complexType>
-          <xs:sequence>
+          <xs:sequence dfdl:sequenceKind="ordered">
             <xs:element name="msg" type="ex:msgType" maxOccurs="unbounded"/>
           </xs:sequence>
         </xs:complexType>
@@ -227,7 +227,7 @@ class TestMiddleEndAttributes {
       </xs:complexType>
       <xs:element name="fWithInitiator" dfdl:initiator="$">
         <xs:complexType>
-          <xs:sequence>
+          <xs:sequence dfdl:sequenceKind="ordered">
             <xs:element name="f" type="xs:string"/>
           </xs:sequence>
         </xs:complexType>
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetImpl.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetImpl.scala
index 4b2b6e1..eacbe2b 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetImpl.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetImpl.scala
@@ -207,6 +207,9 @@ case class InfosetContentLengthUnknownException(lengthState: LengthState, overri
 case class InfosetValueLengthUnknownException(lengthState: LengthState, override val diElement: DIElement, override val erd: ElementRuntimeData)
   extends InfosetLengthUnknownException(lengthState, "Value", diElement, erd)
 
+case class InfosetMultipleScalarError(val erd: ElementRuntimeData)
+  extends ProcessingError("Scalar Element", Nope, Nope, "Multiple instances detected for scalar element %s", erd.namedQName)
+
 /**
  * Used to determine if expressions can be evaluated without any nodes.
  * They all save/restore the current node, so this is the placeholder
@@ -886,7 +889,6 @@ sealed trait DIElement
   private var _array: Maybe[InfosetArray] = Nope
   override def array = _array
   override def setArray(a: InfosetArray) = {
-    Assert.invariant(_array == Nope)
     _array = One(a)
   }
 
@@ -1004,6 +1006,14 @@ final class DIArray(
     ie.setArray(this)
   }
 
+  def concat(array: DIArray) = {
+    val newContents = array.contents
+    newContents.foreach( ie => {
+      ie.asInstanceOf[InfosetElement].setArray(this)
+      append(ie.asInstanceOf[InfosetElement])
+    })
+  }
+
   final def length: Long = _contents.length
 
   final def maybeMostRecentlyAddedChild(): Maybe[DIElement] = {
@@ -1431,6 +1441,56 @@ sealed class DIComplex(override val erd: ElementRuntimeData, val tunable: Daffod
     }
   }
 
+  /*
+   * When parsing unordered sequences it is possible to have non-contiguous arrays.
+   * When parsed, these arrays show up as separate DIArrays in the infoset. We need
+   * to combine these separate arrays and sort the child nodes into schema definition
+   * order.
+   * */
+  final def flattenAndValidateChildNodes(pstate: ParseOrUnparseState, start: Int): Unit = {
+    val (ordered, unordered) = childNodes.splitAt(start)
+    childNodes.clear()
+    childNodes ++= ordered
+    val groups = unordered.groupBy(_.erd)
+    unordered.clear()
+    groups foreach {
+      case (erd, nodes) => {
+        // Check min/maxOccurs validity while iterating over childNodes
+        val min = erd.minOccurs
+        val max = erd.maxOccurs
+        val isUnbounded = max == -1
+
+        // Flatten multiple DIArrays into the first one
+        if (erd.isArray) {
+          val a = nodes(0).asInstanceOf[DIArray]
+          nodes.tail.foreach( b => a.concat(b.asInstanceOf[DIArray]))
+          nodes.reduceToSize(1)
+
+          // Need to also remove duplicates from fastLookup
+          val fastSeq = nameToChildNodeLookup.get(a.namedQName)
+          if (fastSeq != null)
+            fastSeq.reduceToSize(1)
+
+          // Validate min/maxOccurs for array
+          val occurrence = nodes(0).contents.length
+          if (isUnbounded && occurrence < min)
+            pstate.validationError("Element %s failed check of minOccurs='%s' and maxOccurs='unbounded', actual number of occurrences: %s", erd.namedQName, min, occurrence)
+          else if (!isUnbounded && (occurrence < min || occurrence > max))
+            pstate.validationError("Element %s failed check of minOccurs='%s' and maxOccurs='%s', actual number of occurrences: %s", erd.namedQName, min, max, occurrence)
+
+        } else {
+          if (nodes.length > 1) {
+            val diag = new InfosetMultipleScalarError(erd)
+            pstate.setFailed(diag)
+          }
+        }
+
+        unordered ++= nodes
+      }
+    }
+    childNodes ++= unordered.sortBy(_.erd.position)
+  }
+
   override def addChild(e: InfosetElement): Unit = {
     if (!e.isHidden && !hasVisibleChildren) hasVisibleChildren = true
     if (e.runtimeData.isArray) {
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/RuntimeData.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/RuntimeData.scala
index 080681f..90cb6b5 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/RuntimeData.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/RuntimeData.scala
@@ -603,6 +603,7 @@ final class ElementRuntimeData(
    * all transient elements must be added to the preSerialization method below
    * to allow parser serialization/deserialization to work.
    */
+  @TransientParam positionArg: => Int,
   @TransientParam childrenArg: => Seq[ElementRuntimeData],
   @TransientParam variableMapArg: => VariableMap,
   @TransientParam nextElementResolverArg: => NextElementResolver,
@@ -664,6 +665,7 @@ final class ElementRuntimeData(
 
   override def isRequiredScalar = !isArray && isRequiredOrOptional
 
+  lazy val position = positionArg
   lazy val children = childrenArg
   lazy val variableMap = variableMapArg
   lazy val nextElementResolver = nextElementResolverArg
@@ -701,6 +703,7 @@ final class ElementRuntimeData(
 
   override def preSerialization: Unit = {
     super.preSerialization
+    position
     children
     variableMap
     nextElementResolver
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/ElementCombinator1.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/ElementCombinator1.scala
index af0e39c..4eba42d 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/ElementCombinator1.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/ElementCombinator1.scala
@@ -323,59 +323,3 @@ class ElementParserNoRep(
     state.mpstate.moveOverOneElementChildOnly
   }
 }
-
-class ChoiceElementParser(
-  erd: ElementRuntimeData,
-  name: String,
-  patDiscrim: Maybe[Parser],
-  patAssert: Array[Parser],
-  setVar: Array[Parser],
-  testDiscrim: Maybe[Parser],
-  testAssert: Array[Parser],
-  eBeforeParser: Maybe[Parser],
-  eParser: Maybe[Parser],
-  eAfterParser: Maybe[Parser])
-  extends ElementParserBase(
-    erd,
-    name,
-    patDiscrim,
-    patAssert,
-    setVar,
-    testDiscrim,
-    testAssert,
-    eBeforeParser,
-    eParser,
-    eAfterParser,
-    Maybe.Nope  
-  ) {
-
-  def move(state: PState) = {}
-
-  /**
-   * ElementBegin just adds the element we are constructing to the infoset and changes
-   * the state to be referring to this new element as what we're parsing data into.
-   */
-  def parseBegin(pstate: PState): Unit = {
-    val currentElement = Infoset.newElement(erd, pstate.tunable)
-    log(LogLevel.Debug, "currentElement = %s", currentElement)
-  }
-
-  // We don't want to modify the state here except
-  // for validation.
-  def parseEnd(pstate: PState): Unit = {
-    val currentElement = pstate.thisElement
-
-    val shouldValidate =
-      (pstate.dataProc.isDefined) && pstate.dataProc.value.getValidationMode != ValidationMode.Off
-    if (shouldValidate && erd.isSimpleType) {
-      // Execute checkConstraints
-      validate(pstate)
-    }
-
-    val priorElement = currentElement.parent
-    // Note: interaction of unboxed Maybe[T] with pass by name args of log method
-    // require us to call toScalaOption here.
-    log(LogLevel.Debug, "priorElement = %s", Maybe.WithNulls.toScalaOption(priorElement))
-    move(pstate)
-  }
-}
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SeparatedSequenceChildParseResultHelper.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SeparatedSequenceChildParseResultHelper.scala
index 3e7a0ac..b1fc8ff 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SeparatedSequenceChildParseResultHelper.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SeparatedSequenceChildParseResultHelper.scala
@@ -312,10 +312,22 @@ class NonPositionalGroupSeparatedSequenceChildParseResultHelper(
     isZL: Boolean,
     mgrd: ModelGroupRuntimeData,
     requiredOptional: RequiredOptionalStatus): ParseAttemptStatus = {
-    if (isZL)
-      ParseAttemptStatus.MissingItem // it is an error if ZL in NonPositional
-    else
-      ParseAttemptStatus.NormalRep
+    if (pstate.isSuccess) {
+      val maybeElem = pstate.infoset.asComplex.maybeMostRecentlyAddedChild()
+      Assert.invariant(maybeElem.isDefined)
+      val elem = maybeElem.get
+      val maybeIsNilled = elem.maybeIsNilled // can't just call isNilled because that throws exceptions on not defined
+      if (maybeIsNilled.isDefined && maybeIsNilled.get) {
+        ParseAttemptStatus.NilRep
+      } else {
+        ParseAttemptStatus.NormalRep
+      }
+    } else {
+      if (isZL)
+        ParseAttemptStatus.MissingItem // it is an error if ZL in NonPositional
+      else
+        ParseAttemptStatus.NormalRep
+    }
   }
 
 }
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SeparatedSequenceParsers.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SeparatedSequenceParsers.scala
index 288dc07..8b5c575 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SeparatedSequenceParsers.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SeparatedSequenceParsers.scala
@@ -65,6 +65,17 @@ sealed abstract class ScalarOrderedSeparatedSequenceChildParser(
   with Separated
   with NonRepeatingSequenceChildParser
 
+sealed abstract class ScalarUnorderedSeparatedSequenceChildParser(
+  childParser: Parser,
+  srd: SequenceRuntimeData,
+  trd: TermRuntimeData,
+  override val sep: Parser,
+  override val spos: SeparatorPosition,
+  override val parseResultHelper: SeparatedSequenceChildParseResultHelper)
+  extends SequenceChildParser(childParser, srd, trd)
+  with Separated
+  with NonRepeatingUnorderedSequenceChildParser
+
 final class ScalarOrderedElementSeparatedSequenceChildParser(
   childParser: Parser,
   srd: SequenceRuntimeData,
@@ -83,6 +94,15 @@ final class GroupSeparatedSequenceChildParser(
   prh: SeparatedSequenceChildParseResultHelper)
   extends ScalarOrderedSeparatedSequenceChildParser(childParser, srd, mrd, sep, spos, prh)
 
+final class GroupSeparatedUnorderedSequenceChildParser(
+  childParser: Parser,
+  srd: SequenceRuntimeData,
+  val mrd: ModelGroupRuntimeData,
+  sep: Parser,
+  spos: SeparatorPosition,
+  prh: SeparatedSequenceChildParseResultHelper)
+  extends ScalarUnorderedSeparatedSequenceChildParser(childParser, srd, mrd, sep, spos, prh)
+
 final class RepOrderedExactlyNSeparatedSequenceChildParser(
   childParser: Parser,
   srd: SequenceRuntimeData,
@@ -119,7 +139,17 @@ final class OrderedSeparatedSequenceParser(
   spos: SeparatorPosition,
   sep: Parser,
   childrenArg: Vector[SequenceChildParser])
-  extends OrderedSequenceParserBase(rd, childrenArg) {
+  extends SequenceParserBase(rd, childrenArg) {
 
   override lazy val childProcessors = (sep +: childrenArg.asInstanceOf[Seq[Parser]]).toVector
 }
+
+final class UnorderedSeparatedSequenceParser(
+  rd: SequenceRuntimeData,
+  spos: SeparatorPosition,
+  sep: Parser,
+  choiceParser: Vector[SequenceChildParser])
+  extends SequenceParserBase(rd, choiceParser, false) {
+
+  override lazy val childProcessors = sep +: choiceParser
+}
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceChildBases.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceChildBases.scala
index 610f0c1..bea2c67 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceChildBases.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceChildBases.scala
@@ -223,6 +223,15 @@ trait NonRepeatingSequenceChildParser { self: SequenceChildParser =>
 
 }
 
+trait NonRepeatingUnorderedSequenceChildParser { self: SequenceChildParser =>
+
+  def pouStatus: PoUStatus = PoUStatus.HasPoU
+
+  def maybeStaticRequiredOptionalStatus: Maybe[RequiredOptionalStatus] =
+    Maybe(RequiredOptionalStatus.Optional)
+
+}
+
 /**
  * For computed elements, and for groups (which commonly will be sequences)
  * which contain only other non-represented entities, or executable
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceParserBases.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceParserBases.scala
index 2b360f5..7cb6d92 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceParserBases.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/SequenceParserBases.scala
@@ -16,12 +16,18 @@
  */
 package org.apache.daffodil.processors.parsers
 
+import scala.collection.mutable.ArrayBuffer
+
 import org.apache.daffodil.processors.Evaluatable
-import java.io.PrintWriter
 import org.apache.daffodil.exceptions.UnsuppressableException
+import java.io.PrintWriter
 import java.io.StringWriter
+import java.util.Comparator
+import java.util.Arrays
 import org.apache.daffodil.dsom.SchemaDefinitionDiagnosticBase
 import org.apache.daffodil.dsom.TunableLimitExceededError
+import org.apache.daffodil.infoset.DIComplex
+import org.apache.daffodil.infoset.DIArray
 import org.apache.daffodil.exceptions.Assert
 import org.apache.daffodil.processors.Success
 import org.apache.daffodil.processors.SequenceRuntimeData
@@ -36,18 +42,13 @@ import org.apache.daffodil.processors.ModelGroupRuntimeData
  */
 abstract class SequenceParserBase(
   srd: SequenceRuntimeData,
-  protected val childParsers: Vector[Parser])
+  childParsers: Vector[Parser],
+  isOrdered: Boolean = true)
   extends CombinatorParser(srd) {
   override def nom = "Sequence"
 
   override lazy val runtimeDependencies: Vector[Evaluatable[AnyRef]] = Vector()
   override lazy val childProcessors = childParsers
-}
-
-abstract class OrderedSequenceParserBase(
-  srd: SequenceRuntimeData,
-  childParsersArg: Vector[Parser])
-  extends SequenceParserBase(srd, childParsersArg) {
 
   import ParseAttemptStatus._
   import ArrayIndexStatus._
@@ -86,6 +87,8 @@ abstract class OrderedSequenceParserBase(
 
     var resultOfTry: ParseAttemptStatus = ParseAttemptStatus.Uninitialized
 
+    val infosetIndexStart = pstate.infoset.asInstanceOf[DIComplex].childNodes.size
+
     /**
      * On exit from the sequence loop, if the last thing was Missing, we
      * want to look back one prior to see if that followed a EmptyRep or AbsentRep,
@@ -224,12 +227,23 @@ abstract class OrderedSequenceParserBase(
               pstate.setSuccess()
               isDone = true
             }
+            case (MissingItem | MissingSeparator | FailureUnspecified) if (!isOrdered) => {
+              // We have hit the end of an unordered sequence, mask the failure and exit
+              // the sequence succesfully.
+              pstate.setSuccess()
+              isDone = true
+            }
             case _ => // ok.
           }
           pstate.mpstate.moveOverOneGroupIndexOnly()
         } // end case scalarParser
       } // end match case parser
-      scpIndex += 1
+      if (isOrdered)
+        scpIndex += 1
+      else if (isDone) {
+        val infoset = pstate.infoset.asInstanceOf[DIComplex]
+        infoset.flattenAndValidateChildNodes(pstate, infosetIndexStart)
+      }
     } // end while for each sequence child parser
 
     if (child ne null) child.finalChecks(pstate, resultOfTry, priorResultOfTry)
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/UnorderedSequenceParser.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/UnorderedSequenceParser.scala
deleted file mode 100644
index 0a666a6..0000000
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/UnorderedSequenceParser.scala
+++ /dev/null
@@ -1,168 +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.parsers
-
-import org.apache.daffodil.processors.ModelGroupRuntimeData
-
-class UnorderedSequenceParser(
-  override val context: ModelGroupRuntimeData,
-  sortOrder: Seq[(String, org.jdom2.Namespace)],
-  scalarMembers: Seq[(String, String, org.jdom2.Namespace)],
-  uoSeqParser: Parser)
-  extends CombinatorParser(context) {
-
-  override lazy val runtimeDependencies = Vector()
-
-  override def nom = "UnorderedSequence"
-  override lazy val childProcessors = Vector(uoSeqParser)
-
-  //  def sort(elt: org.jdom2.Element, pstate: PState): Unit = {
-  //    val childrenDetached = elt.removeContent().toList.asInstanceOf[List[org.jdom2.Element]]
-  //
-  //        println("Children Detached: " + childrenDetached)
-  //
-  //    println("Sort Order: " + sortOrder)
-  //    sortOrder.foreach {
-  //      case (name, ns) => {
-  //
-  //        val newContent = childrenDetached.filter(child => {
-  //          val infoSetElem = Infoset.newElement(child)
-  //          val rd = infoSetElem.schemaComponent
-  //          val isMatch = rd.name == name && rd.targetNamespace == ns
-  //          isMatch
-  //        })
-  //
-  //        println("New Content: " + newContent)
-  //        if (newContent.size > 0)
-  //          elt.addContent(newContent)
-  //      }
-  //    }
-  //  }
-  //
-  //  def checkScalarsOccurExactlyOnce(elt: org.jdom2.Element, pstate: PState): Unit = {
-  //    // Always occurs, does not depend on validation
-  //    val children = elt.getChildren().toList.asInstanceOf[List[org.jdom2.Element]]
-  //    scalarMembers.foreach {
-  //      case (name, path, ns) => {
-  //        val scalarChildren = children.filter(e => {
-  //          e.getName() == name && e.getNamespace() == ns
-  //        })
-  //        val numScalarChildren = scalarChildren.length
-  //        if (numScalarChildren > 1 || numScalarChildren == 0)
-  //          pstate.SDE("%s is scalar but occurred %s times.\nPath: %s\nOffending children: %s",
-  //            name, scalarChildren.length, path, scalarChildren.mkString(", "))
-  //      }
-  //    }
-  //  }
-  //
-  //  /**
-  //   * We want to check that we met he expected occurrence values
-  //   * but we don't want to SDE, instead we issue a PE (ProcessingError).
-  //   */
-  //  def checkOccurrence(elt: org.jdom2.Element): Unit = {
-  //    val childrenList = elt.getContent().toList.asInstanceOf[List[org.jdom2.Element]]
-  //
-  //    val erds =
-  //      context.groupMembers.collect { case erd: ElementRuntimeData => erd }
-  //    erds.foreach(erd => {
-  //      val minOccurs = erd.minOccurs
-  //      val maxOccurs = erd.maxOccurs
-  //      val ns = erd.targetNamespace
-  //      val name = erd.name
-  //
-  //      val children = childrenList.filter(c => {
-  //        val childName = c.getName()
-  //        val childNS = c.getNamespace()
-  //        name == childName && ns == childNS
-  //      })
-  //
-  //      val numChildren = children.length
-  //
-  //      minOccurs.foreach { minOccurs =>
-  //        if (numChildren < minOccurs) {
-  //          PE("UnorderedSequence.checkOccurrence - %s failed minOccurs check. Expected at least %s but found %s.",
-  //            erd, minOccurs, numChildren)
-  //        }
-  //      }
-  //      maxOccurs.foreach { maxOccurs =>
-  //        if (numChildren > maxOccurs) {
-  //          PE("UnorderedSequence.checkOccurrence - %s failed maxOccurs check. Expected at most %s but found %s.",
-  //            erd, maxOccurs, numChildren)
-  //        }
-  //      }
-  //    })
-  //  }
-  //
-  //  def dropDefaulted(elt: org.jdom2.Element, pstate: PState): Unit = {
-  //    // Always occurs, does not depend on validation
-  //
-  //    // RequiredElement, index in its array <= minOccurs
-  //    // If empty rep, a required element that has a default value will be defaulted.
-  //
-  //    // Drop anything after the minOccurs that was defaulted.
-  //
-  //    // So we need the original minOccurs for each element.
-  //    val childrenDetached = elt.removeContent().toList.asInstanceOf[List[org.jdom2.Element]]
-  //    val erds = childrenDetached.map(c => {
-  //      val infoSetElem = Infoset.newElement(c)
-  //      val rd = infoSetElem.schemaComponent
-  //      rd
-  //    }).distinct
-  //
-  //    erds.foreach(erd => {
-  //      val minOccurs = erd.minOccurs.get
-  //      val ns = erd.targetNamespace
-  //      val name = erd.name
-  //
-  //      val children = childrenDetached.filter(c => {
-  //        val childName = c.getName()
-  //        val childNS = c.getNamespace()
-  //        name == childName && ns == childNS
-  //      })
-  //
-  //      val numChildren = children.length
-  //
-  //      if (numChildren >= minOccurs) {
-  //        val firstChild = children.head
-  //        val restOfChildren = children.tail
-  //        val restOfNonDefaultedChildren = restOfChildren.filterNot(c => c.getAttribute("defaulted", XMLUtils.INT_NS_OBJECT).getBooleanValue())
-  //        val newContent = firstChild :: restOfNonDefaultedChildren
-  //        if (newContent.length > 0)
-  //          elt.addContent(newContent)
-  //      } else {
-  //        // Nothing to do here, reattach children.
-  //        elt.addContent(childrenDetached)
-  //      }
-  //    })
-  //  }
-
-  override def parse(start: PState): Unit = {
-    ???
-    //    val end = uoSeqParser.parse1(start)
-    //    val currentElemAfter = end.parentElement.jdomElt.get
-
-    //    checkScalarsOccurExactlyOnce(currentElemAfter, end)
-    //    dropDefaulted(currentElemAfter, end)
-    //    checkOccurrence(currentElemAfter)
-    //
-    //    // Sort so that the contents are in the expected order.
-    //    sort(currentElemAfter, end)
-
-    //    end
-  }
-}
diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/UnseparatedSequenceParsers.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/UnseparatedSequenceParsers.scala
index f4f8102..9a5f153 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/UnseparatedSequenceParsers.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/UnseparatedSequenceParsers.scala
@@ -45,6 +45,15 @@ class ScalarOrderedUnseparatedSequenceChildParser(
   with Unseparated
   with NonRepeatingSequenceChildParser
 
+class ScalarUnorderedUnseparatedSequenceChildParser(
+  override val childParser: Parser,
+  override val srd: SequenceRuntimeData,
+  override val trd: TermRuntimeData,
+  override val parseResultHelper: UnseparatedSequenceChildParseResultHelper)
+  extends SequenceChildParser(childParser, srd, trd)
+  with Unseparated
+  with NonRepeatingUnorderedSequenceChildParser
+
 class RepOrderedExactlyNUnseparatedSequenceChildParser(
   childParser: Parser,
   srd: SequenceRuntimeData,
@@ -72,4 +81,7 @@ class RepOrderedWithMinMaxUnseparatedSequenceChildParser(
   with Unseparated
 
 class OrderedUnseparatedSequenceParser(rd: SequenceRuntimeData, childParsersArg: Vector[SequenceChildParser])
-  extends OrderedSequenceParserBase(rd, childParsersArg)
+  extends SequenceParserBase(rd, childParsersArg)
+
+class UnorderedUnseparatedSequenceParser(rd: SequenceRuntimeData, choiceParser: Vector[SequenceChildParser])
+  extends SequenceParserBase(rd, choiceParser, false)
diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section14/unordered_sequences/UnorderedSequences.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section14/unordered_sequences/UnorderedSequences.tdml
index d78931a..cdd6c65 100644
--- a/daffodil-test/src/test/resources/org/apache/daffodil/section14/unordered_sequences/UnorderedSequences.tdml
+++ b/daffodil-test/src/test/resources/org/apache/daffodil/section14/unordered_sequences/UnorderedSequences.tdml
@@ -18,12 +18,13 @@
 
 <tdml:testSuite xmlns:tdml="http://www.ibm.com/xmlns/dfdl/testData"
 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/"
-	xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ex="http://example.com">
+  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ex="http://example.com"
+  xmlns:fn="http://www.w3.org/2005/xpath-functions">
 
 	<tdml:defineSchema name="simple">
 		<xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
     <dfdl:format ref="ex:GeneralFormat" lengthUnits="characters"
-			lengthKind="implicit" />
+			lengthKind="implicit" occursCountKind="parsed" />
 		<xs:element name="USG_01">
 			<xs:complexType>
 				<xs:sequence dfdl:sequenceKind="unordered">
@@ -71,7 +72,6 @@
 	</tdml:defineSchema>
 
 	<tdml:parserTestCase name="test_simple" model="simple"
-		description="Section 14 Sequence group with left over data - DFDL-14-001R"
 		root="USG_01">
 		<tdml:document><![CDATA[veba00]]></tdml:document>
 		<tdml:infoset>
@@ -86,26 +86,25 @@
 	</tdml:parserTestCase>
 
 	<tdml:parserTestCase name="test_simple_fail_scalar"
-		model="simple" description="Section 14 Sequence group with left over data - DFDL-14-001R"
-		root="USG_01">
+		model="simple" root="USG_01" validation="limited">
 		<tdml:document><![CDATA[verybadf00d222]]></tdml:document>
-		<tdml:errors>
-			<tdml:error>e1</tdml:error>
-			<tdml:error>is scalar but occurred 2 times</tdml:error>
-		</tdml:errors>
+    <tdml:errors>
+      <tdml:error>Scalar Element Error</tdml:error>
+      <tdml:error>Multiple instances detected for scalar element</tdml:error>
+    </tdml:errors>
 	</tdml:parserTestCase>
 
 	<tdml:defineSchema name="simple_min_max_occurs">
 		<xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
     <dfdl:format ref="ex:GeneralFormat" lengthUnits="characters"
-			lengthKind="implicit" />
+			lengthKind="implicit" occursCountKind="parsed" />
 		<xs:element name="USG_01">
 			<xs:complexType>
 				<xs:sequence dfdl:sequenceKind="unordered">
 
 					<xs:element name="e1" type="ex:stNumStr"
 						dfdl:lengthKind="explicit" dfdl:length="2" minOccurs="1"
-						maxOccurs="2" dfdl:occursCountKind="parsed">
+						maxOccurs="2">
 						<xs:annotation>
 							<xs:appinfo source="http://www.ogf.org/dfdl/">
 								<dfdl:assert test="{ dfdl:checkConstraints(.) }"
@@ -147,8 +146,7 @@
 	</tdml:defineSchema>
 
 	<tdml:parserTestCase name="test_simple_min_max_occurs"
-		model="simple_min_max_occurs" description="Section 14 Sequence group with left over data - DFDL-14-001R"
-		root="USG_01" validation="on">
+		model="simple_min_max_occurs" root="USG_01" validation="on">
 		<tdml:document><![CDATA[veba0022]]></tdml:document>
 		<tdml:infoset>
 			<tdml:dfdlInfoset>
@@ -163,18 +161,106 @@
 	</tdml:parserTestCase>
 
 	<tdml:parserTestCase name="test_simple_min_max_occurs_fail"
-		model="simple_min_max_occurs" description="Section 14 Sequence group with left over data - DFDL-14-001R"
-		root="USG_01" validation="on">
-		<tdml:document><![CDATA[verybadf00d222]]></tdml:document>
-		<tdml:errors>
-			<tdml:error>e2 is scalar but occurred 3 times</tdml:error>
-		</tdml:errors>
+		model="simple_min_max_occurs" root="USG_01" validation="limited" roundTrip="false">
+		<tdml:document><![CDATA[ve00ba2233]]></tdml:document>
+		<tdml:infoset>
+			<tdml:dfdlInfoset>
+				<USG_01>
+					<e1>00</e1>
+					<e1>22</e1>
+					<e1>33</e1>
+					<e2>ba</e2>
+					<e3>ve</e3>
+				</USG_01>
+			</tdml:dfdlInfoset>
+		</tdml:infoset>
+    <tdml:validationErrors>
+			<tdml:error>Element ex:e1 failed check</tdml:error>
+    </tdml:validationErrors>
+  </tdml:parserTestCase>
+
+	<tdml:defineSchema name="array_reference">
+		<xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" lengthUnits="characters"
+			lengthKind="implicit" occursCountKind="parsed" />
+		<xs:element name="USG_01">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="uoseq">
+            <xs:complexType>
+              <xs:sequence dfdl:sequenceKind="unordered">
+
+                <xs:element name="e1" type="ex:stNumStr"
+                  dfdl:lengthKind="explicit" dfdl:length="2" minOccurs="1"
+                  maxOccurs="2">
+                  <xs:annotation>
+                    <xs:appinfo source="http://www.ogf.org/dfdl/">
+                      <dfdl:assert test="{ dfdl:checkConstraints(.) }"
+                        message="Assertion failed for dfdl:checkConstraints(.)" />
+                    </xs:appinfo>
+                  </xs:annotation>
+                </xs:element>
+                <xs:element name="e2" type="ex:stHexStr"
+                  dfdl:lengthKind="explicit" dfdl:length="2">
+                  <xs:annotation>
+                    <xs:appinfo source="http://www.ogf.org/dfdl/">
+                      <dfdl:assert test="{ dfdl:checkConstraints(.) }"
+                        message="Assertion failed for dfdl:checkConstraints(.)" />
+                    </xs:appinfo>
+                  </xs:annotation>
+                </xs:element>
+                <xs:element name="e3" type="xs:string" dfdl:lengthKind="explicit"
+                  dfdl:length="2">
+                  <xs:annotation>
+                    <xs:appinfo source="http://www.ogf.org/dfdl/">
+                      <dfdl:assert test="{ dfdl:checkConstraints(.) }"
+                        message="Assertion failed for dfdl:checkConstraints(.)" />
+                    </xs:appinfo>
+                  </xs:annotation>
+                </xs:element>
+              </xs:sequence>
+            </xs:complexType>
+          </xs:element>
+          <xs:element name="testRef" type="ex:stNumStr"
+            dfdl:lengthKind="explicit" dfdl:length="2"
+            dfdl:inputValueCalc="{ ../ex:uoseq/ex:e1[2] }" />
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+		<xs:simpleType name="stHexStr">
+			<xs:restriction base="xs:string">
+				<xs:pattern value="[a-fA-F0-9]+"></xs:pattern>
+			</xs:restriction>
+		</xs:simpleType>
+		<xs:simpleType name="stNumStr">
+			<xs:restriction base="xs:string">
+				<xs:pattern value="[0-9]+"></xs:pattern>
+			</xs:restriction>
+		</xs:simpleType>
+	</tdml:defineSchema>
+
+	<tdml:parserTestCase name="test_array_reference"
+		model="array_reference" root="USG_01" validation="on">
+		<tdml:document><![CDATA[ve00ba22]]></tdml:document>
+		<tdml:infoset>
+			<tdml:dfdlInfoset>
+        <USG_01>
+          <uoseq>
+            <e1>00</e1>
+            <e1>22</e1>
+            <e2>ba</e2>
+            <e3>ve</e3>
+          </uoseq>
+          <testRef>22</testRef>
+        </USG_01>
+			</tdml:dfdlInfoset>
+		</tdml:infoset>
 	</tdml:parserTestCase>
 
 	<tdml:defineSchema name="simple_delimited">
 		<xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
     <dfdl:format ref="ex:GeneralFormat" lengthUnits="characters"
-			lengthKind="delimited" />
+			lengthKind="delimited" occursCountKind="parsed" />
 		<xs:element name="USG_01">
 			<xs:complexType>
 				<xs:sequence dfdl:sequenceKind="unordered"
@@ -198,8 +284,7 @@
 	</tdml:defineSchema>
 
 	<tdml:parserTestCase name="test_simple_delimited"
-		model="simple_delimited" description="Section 14 Sequence group with left over data - DFDL-14-001R"
-		root="USG_01">
+		model="simple_delimited" root="USG_01">
 		<tdml:document><![CDATA[b2,a1,c3]]></tdml:document>
 		<tdml:infoset>
 			<tdml:dfdlInfoset>
@@ -215,7 +300,7 @@
 	<tdml:defineSchema name="simple_nil">
 		<xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
     <dfdl:format ref="ex:GeneralFormat" lengthUnits="characters"
-			lengthKind="implicit" nilValueDelimiterPolicy="none"/>
+			lengthKind="implicit" nilValueDelimiterPolicy="none" occursCountKind="parsed"/>
 		<xs:element name="USG_01">
 			<xs:complexType>
 				<xs:sequence dfdl:sequenceKind="unordered"
@@ -239,8 +324,7 @@
 	</tdml:defineSchema>
 
 	<tdml:parserTestCase name="test_simple_nil"
-		model="simple_nil" description="Section 14 Sequence group with left over data - DFDL-14-001R"
-		root="USG_01">
+		model="simple_nil" root="USG_01">
 		<tdml:document><![CDATA[b2,,c3]]></tdml:document>
 		<tdml:infoset>
 			<tdml:dfdlInfoset>
@@ -251,13 +335,54 @@
 				</USG_01>
 			</tdml:dfdlInfoset>
 		</tdml:infoset>
+  </tdml:parserTestCase>
+
+
+	<tdml:defineSchema name="simple_optional">
+		<xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" lengthUnits="characters"
+			lengthKind="implicit" nilValueDelimiterPolicy="none" occursCountKind="parsed"/>
+		<xs:element name="USG_01">
+			<xs:complexType>
+				<xs:sequence dfdl:sequenceKind="unordered"
+					dfdl:separator=",">
+
+					<xs:element name="e1" type="xs:int" dfdl:lengthKind="delimited"
+						dfdl:initiator="a" minOccurs="0">
+					</xs:element>
+
+					<xs:element name="e2" type="xs:int" dfdl:lengthKind="delimited"
+						dfdl:initiator="b">
+					</xs:element>
+
+					<xs:element name="e3" type="xs:int" dfdl:lengthKind="delimited"
+						dfdl:initiator="c">
+					</xs:element>
+
+				</xs:sequence>
+			</xs:complexType>
+		</xs:element>
+	</tdml:defineSchema>
+
+	<tdml:parserTestCase name="test_simple_optional_elem"
+		model="simple_optional" description="Verify that optional elements are handled correctly in unordered sequences"
+		root="USG_01">
+		<tdml:document><![CDATA[b2,c3]]></tdml:document>
+		<tdml:infoset>
+			<tdml:dfdlInfoset>
+				<USG_01>
+					<e2>2</e2>
+					<e3>3</e3>
+				</USG_01>
+			</tdml:dfdlInfoset>
+		</tdml:infoset>
 	</tdml:parserTestCase>
 
 
 	<tdml:defineSchema name="simple_invalid_path_to_branch">
 		<xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
     <dfdl:format ref="ex:GeneralFormat" lengthUnits="characters"
-			lengthKind="delimited" />
+			lengthKind="delimited" occursCountKind="parsed" />
 		<xs:element name="USG_01">
 			<xs:complexType>
 				<xs:sequence dfdl:sequenceKind="unordered"
@@ -315,10 +440,7 @@
 		<tdml:document><![CDATA[b2,a1,a4,c3,ruh-oh!]]></tdml:document>
 		<tdml:errors>
 			<tdml:error>Schema Definition Error</tdml:error>
-			<tdml:error>Expression</tdml:error>
-			<tdml:error>../e3</tdml:error>
-			<tdml:error>navigates to another branch</tdml:error>
-			<tdml:error>e3</tdml:error>
+			<tdml:error>No element corresponding</tdml:error>
 		</tdml:errors>
 	</tdml:parserTestCase>
 
@@ -337,7 +459,7 @@
 	<tdml:defineSchema name="nested_paths">
 		<xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
     <dfdl:format ref="ex:GeneralFormat" lengthUnits="characters"
-			lengthKind="delimited" />
+			lengthKind="delimited" occursCountKind="parsed" />
 		<xs:element name="USG_01">
 			<xs:complexType>
 				<xs:sequence dfdl:sequenceKind="ordered" dfdl:separator=",">
@@ -345,99 +467,21 @@
 					<xs:element name="e1" type="xs:int" dfdl:lengthKind="delimited"
 						dfdl:initiator="a" />
 
-					<xs:element name="uoSeq" dfdl:lengthKind="implicit"
-						dfdl:initiator="b">
-						<xs:complexType>
-							<xs:sequence dfdl:sequenceKind="unordered"
-								dfdl:separator=":">
-								<xs:element name="uoMember1" type="xs:int"
-									dfdl:lengthKind="delimited" dfdl:initiator="x" />
-								<xs:element name="uoMember2" type="xs:int"
-									dfdl:lengthKind="delimited" dfdl:initiator="y" />
-								<xs:element name="uoMember3" type="xs:int"
-									dfdl:lengthKind="delimited" dfdl:initiator="z">
-									<xs:annotation>
-										<xs:appinfo source="http://www.ogf.org/dfdl/">
-											<dfdl:assert test="{ ../../e1 }" message="Assertion failed for ../../e1" />
-										</xs:appinfo>
-									</xs:annotation>
-								</xs:element>
-							</xs:sequence>
-						</xs:complexType>
-					</xs:element>
-
-					<xs:element name="e2" type="xs:int" dfdl:lengthKind="delimited"
-						dfdl:initiator="c" />
-
-				</xs:sequence>
-			</xs:complexType>
-		</xs:element>
-
-		<xs:element name="USG_02">
-			<xs:complexType>
-				<xs:sequence dfdl:sequenceKind="ordered" dfdl:separator=",">
-
-					<xs:element name="e1" type="xs:int" dfdl:lengthKind="delimited"
-						dfdl:initiator="a" />
-
-					<xs:element name="uoSeq" dfdl:lengthKind="implicit"
-						dfdl:initiator="b">
-						<xs:complexType>
-							<xs:sequence dfdl:sequenceKind="unordered"
-								dfdl:separator=":">
-								<xs:element name="uoMember1" type="xs:int"
-									dfdl:lengthKind="delimited" dfdl:initiator="x" />
-								<xs:element name="uoMember2" type="xs:int"
-									dfdl:lengthKind="delimited" dfdl:initiator="y" />
-								<xs:element name="uoMember3" type="xs:int"
-									dfdl:lengthKind="delimited" dfdl:initiator="z">
-									<xs:annotation>
-										<xs:appinfo source="http://www.ogf.org/dfdl/">
-											<dfdl:assert test="{ ../uoMember1 }"
-												message="Assertion failed for ../uoMember1" />
-										</xs:appinfo>
-									</xs:annotation>
-								</xs:element>
-							</xs:sequence>
-						</xs:complexType>
-					</xs:element>
-
-					<xs:element name="e2" type="xs:int" dfdl:lengthKind="delimited"
-						dfdl:initiator="c" />
-
-				</xs:sequence>
-			</xs:complexType>
-		</xs:element>
-
-		<xs:element name="USG_03">
-			<xs:complexType>
-				<xs:sequence dfdl:sequenceKind="unordered"
-					dfdl:separator=",">
-
-					<xs:element name="e1" type="xs:int" dfdl:lengthKind="delimited"
-						dfdl:initiator="a" />
-
-					<xs:element name="uoSeq" dfdl:lengthKind="implicit"
-						dfdl:initiator="b">
-						<xs:complexType>
-							<xs:sequence dfdl:sequenceKind="unordered"
-								dfdl:separator=":">
-								<xs:element name="uoMember1" type="xs:int"
-									dfdl:lengthKind="delimited" dfdl:initiator="x" />
-								<xs:element name="uoMember2" type="xs:int"
-									dfdl:lengthKind="delimited" dfdl:initiator="y" />
-								<xs:element name="uoMember3" type="xs:int"
-									dfdl:lengthKind="delimited" dfdl:initiator="z">
-									<xs:annotation>
-										<xs:appinfo source="http://www.ogf.org/dfdl/">
-											<dfdl:assert test="{ ../../e1 eq 1 }"
-												message="Assertion failed for xs:int(../../e1) eq 1" />
-										</xs:appinfo>
-									</xs:annotation>
-								</xs:element>
-							</xs:sequence>
-						</xs:complexType>
-					</xs:element>
+            <xs:sequence dfdl:sequenceKind="unordered"
+              dfdl:separator=":">
+              <xs:element name="uoMember1" type="xs:int"
+                dfdl:lengthKind="delimited" dfdl:initiator="x" />
+              <xs:element name="uoMember2" type="xs:int"
+                dfdl:lengthKind="delimited" dfdl:initiator="y" />
+              <xs:element name="uoMember3" type="xs:int"
+                dfdl:lengthKind="delimited" dfdl:initiator="z">
+                <xs:annotation>
+                  <xs:appinfo source="http://www.ogf.org/dfdl/">
+                    <dfdl:assert test="{ ../ex:e1 }" message="Assertion failed for ../ex:e1" />
+                  </xs:appinfo>
+                </xs:annotation>
+              </xs:element>
+            </xs:sequence>
 
 					<xs:element name="e2" type="xs:int" dfdl:lengthKind="delimited"
 						dfdl:initiator="c" />
@@ -446,49 +490,6 @@
 			</xs:complexType>
 		</xs:element>
 
-		<xs:element name="USG_04">
-			<xs:complexType>
-				<xs:sequence dfdl:sequenceKind="ordered" dfdl:separator=",">
-
-					<xs:element name="choice" dfdl:lengthKind="implicit"
-						minOccurs="1" maxOccurs="unbounded">
-						<xs:complexType>
-							<xs:choice dfdl:choiceLengthKind="implicit">
-								<xs:element name="e1" type="xs:int" dfdl:lengthKind="delimited"
-									dfdl:initiator="a" />
-
-								<xs:element name="uoSeq" dfdl:lengthKind="implicit"
-									dfdl:initiator="b">
-									<xs:complexType>
-										<xs:sequence dfdl:sequenceKind="unordered"
-											dfdl:separator=":">
-											<xs:element name="uoMember1" type="xs:int"
-												dfdl:lengthKind="delimited" dfdl:initiator="x" />
-											<xs:element name="uoMember2" type="xs:int"
-												dfdl:lengthKind="delimited" dfdl:initiator="y" />
-											<xs:element name="uoMember3" type="xs:int"
-												dfdl:lengthKind="delimited" dfdl:initiator="z">
-												<xs:annotation>
-													<xs:appinfo source="http://www.ogf.org/dfdl/">
-														<dfdl:assert test="{ ../../../choice[1]/e1 eq 1 }"
-															message="Assertion failed for xs:int(../../../choice[1]/e1) eq 1" />
-													</xs:appinfo>
-												</xs:annotation>
-											</xs:element>
-										</xs:sequence>
-									</xs:complexType>
-								</xs:element>
-
-								<xs:element name="e2" type="xs:int" dfdl:lengthKind="delimited"
-									dfdl:initiator="c" />
-							</xs:choice>
-						</xs:complexType>
-					</xs:element>
-
-				</xs:sequence>
-			</xs:complexType>
-		</xs:element>
-
 		<!-- Test multiple valid paths in single expression -->
 		<xs:element name="USG_05">
 			<xs:complexType>
@@ -513,8 +514,8 @@
 									dfdl:lengthKind="delimited" dfdl:initiator="z">
 									<xs:annotation>
 										<xs:appinfo source="http://www.ogf.org/dfdl/">
-											<dfdl:assert test="{ (../../e1 * ../../e2) eq 2 }"
-												message="Assertion failed for ../../e1" />
+											<dfdl:assert test="{ (../../ex:e1 * ../../ex:e2) eq 2 }"
+												message="Assertion failed for ../../ex:e1" />
 										</xs:appinfo>
 									</xs:annotation>
 								</xs:element>
@@ -550,58 +551,8 @@
 									dfdl:lengthKind="delimited" dfdl:initiator="z">
 									<xs:annotation>
 										<xs:appinfo source="http://www.ogf.org/dfdl/">
-											<dfdl:assert test="{ (../uoMember1[1] * ../uoMember2[1]) eq 2 }"
-												message="Assertion failed for (../uoMember1 * ../uoMember2) eq 2" />
-										</xs:appinfo>
-									</xs:annotation>
-								</xs:element>
-							</xs:sequence>
-						</xs:complexType>
-					</xs:element>
-
-				</xs:sequence>
-			</xs:complexType>
-		</xs:element>
-
-		<!-- Testing that the wildcard character in DFDLExpression works and that 
-			we can successfully retrieve and test the nodeset to see if it navigates 
-			to an invalid location -->
-		<xs:element name="USG_07">
-			<xs:complexType>
-				<xs:sequence dfdl:sequenceKind="ordered" dfdl:separator=",">
-
-					<xs:element name="e1" dfdl:lengthKind="implicit"
-						dfdl:initiator="a">
-						<xs:complexType>
-							<xs:sequence>
-								<xs:element name="c1" type="xs:int" dfdl:lengthKind="explicit"
-									dfdl:lengthUnits="characters" dfdl:length="1" />
-								<xs:element name="c2" type="xs:int" dfdl:lengthKind="explicit"
-									dfdl:lengthUnits="characters" dfdl:length="1" />
-								<xs:element name="c3" type="xs:int" dfdl:lengthKind="explicit"
-									dfdl:lengthUnits="characters" dfdl:length="1" />
-							</xs:sequence>
-						</xs:complexType>
-					</xs:element>
-
-					<xs:element name="e2" type="xs:int" dfdl:lengthKind="delimited"
-						dfdl:initiator="b" />
-
-					<xs:element name="uoSeq" dfdl:lengthKind="implicit"
-						dfdl:initiator="c">
-						<xs:complexType>
-							<xs:sequence dfdl:sequenceKind="unordered"
-								dfdl:separator=":">
-								<xs:element name="uoMember1" type="xs:int"
-									dfdl:lengthKind="delimited" dfdl:initiator="x" />
-								<xs:element name="uoMember2" type="xs:int"
-									dfdl:lengthKind="delimited" dfdl:initiator="y" />
-								<xs:element name="uoMember3" type="xs:int"
-									dfdl:lengthKind="delimited" dfdl:initiator="z">
-									<xs:annotation>
-										<xs:appinfo source="http://www.ogf.org/dfdl/">
-											<dfdl:assert test="{ fn:count( ../../e1 ) eq 3 }"
-												message="Assertion failed for fn:count( ../../e1 ) eq 3" />
+											<dfdl:assert test="{ (../ex:uoMember1[1] * ../ex:uoMember2[1]) eq 2 }"
+												message="Assertion failed for (../ex:uoMember1 * ../ex:uoMember2) eq 2" />
 										</xs:appinfo>
 									</xs:annotation>
 								</xs:element>
@@ -619,16 +570,14 @@
 		model="nested_paths"
 		description="navigate from unordered branch to an element of an enclosing ordered sequence"
 		root="USG_01">
-		<tdml:document><![CDATA[a1,bz10:x20:y99,c55]]></tdml:document>
+		<tdml:document><![CDATA[a1,z10:y77:x20,c55]]></tdml:document>
 		<tdml:infoset>
 			<tdml:dfdlInfoset>
 				<USG_01>
 					<e1>1</e1>
-					<uoSeq>
 						<uoMember1>20</uoMember1>
-						<uoMember2>99</uoMember2>
+						<uoMember2>77</uoMember2>
 						<uoMember3>10</uoMember3>
-					</uoSeq>
 					<e2>55</e2>
 				</USG_01>
 			</tdml:dfdlInfoset>
@@ -664,96 +613,15 @@
 		root="USG_06">
 		<tdml:document><![CDATA[a1,b2,cy99:x20:z10]]></tdml:document>
 		<tdml:errors>
-			<tdml:error>Expression</tdml:error>
-			<tdml:error>(../uoMember1[1] * ../uoMember2[1]) eq 2</tdml:error>
-			<tdml:error>contains a path</tdml:error>
-			<tdml:error>../uoMember1[1]</tdml:error>
-			<tdml:error>navigates to another branch</tdml:error>
-			<tdml:error>of the same choice</tdml:error>
-		</tdml:errors>
-	</tdml:parserTestCase>
-
-	<tdml:parserTestCase name="test_nested_path_evaluates_to_nodelist"
-		model="nested_paths"
-		description="navigate from unordered branch to element of an enclosing 
-		ordered sequence using function that expects nodeset"
-		root="USG_07">
-		<tdml:document><![CDATA[a123,b2,cz10:x20:y99]]></tdml:document>
-		<tdml:infoset>
-			<tdml:dfdlInfoset>
-				<USG_07>
-					<e1>
-						<c1>1</c1>
-						<c2>2</c2>
-						<c3>3</c3>
-					</e1>
-					<e2>2</e2>
-					<uoSeq>
-						<uoMember1>20</uoMember1>
-						<uoMember2>99</uoMember2>
-						<uoMember3>10</uoMember3>
-					</uoSeq>
-				</USG_07>
-			</tdml:dfdlInfoset>
-		</tdml:infoset>
-	</tdml:parserTestCase>
-
-	<tdml:parserTestCase name="test_nested_invalid_path_to_branch"
-		model="nested_paths"
-		description="navigate from unordered sequence to another branch of same unordered sequence"
-		root="USG_02">
-		<tdml:document><![CDATA[a1,bx20:y99:z10,c55]]></tdml:document>
-		<tdml:errors>
-			<tdml:error>../uoMember1</tdml:error>
-			<tdml:error>navigates</tdml:error>
-			<tdml:error>to</tdml:error>
-			<tdml:error>another</tdml:error>
-			<tdml:error>branch</tdml:error>
-			<tdml:error>uoMember1</tdml:error>
-			<tdml:error>of</tdml:error>
-			<tdml:error>same</tdml:error>
-			<tdml:error>choice</tdml:error>
-		</tdml:errors>
-	</tdml:parserTestCase>
-
-	<tdml:parserTestCase name="test_nested_invalid_path_to_branch_2"
-		model="nested_paths"
-		description="navigate from unordered sequence to enclosing unordered sequence"
-		root="USG_03">
-		<tdml:document><![CDATA[a1,bx20:y99:z10,c55]]></tdml:document>
-		<tdml:errors>
-			<tdml:error>Expression</tdml:error>
-			<tdml:error>../../e1 eq 1</tdml:error>
-			<tdml:error>navigates</tdml:error>
-			<tdml:error>to</tdml:error>
-			<tdml:error>branch</tdml:error>
-			<tdml:error>another</tdml:error>
-			<tdml:error>choice</tdml:error>
-			<tdml:error>USG_03::LocalComplexTypeDef::sequence::element.choiceElement::LocalComplexTypeDef::choice</tdml:error>
-		</tdml:errors>
-	</tdml:parserTestCase>
-
-	<tdml:parserTestCase name="test_nested_invalid_path_to_branch_3"
-		model="nested_paths"
-		description="navigate from unordered sequence to choice branch of enclosing ordered sequence"
-		root="USG_04">
-		<tdml:document><![CDATA[a1,bx20:y99:z10,c55]]></tdml:document>
-		<tdml:errors>
-			<tdml:error>Expression</tdml:error>
-			<tdml:error>../../../choice[1]/e1 eq 1</tdml:error>
-			<tdml:error>navigates</tdml:error>
-			<tdml:error>to</tdml:error>
-			<tdml:error>branch</tdml:error>
-			<tdml:error>another</tdml:error>
-			<tdml:error>choice</tdml:error>
-			<tdml:error>USG_04::LocalComplexTypeDef::sequence::element.choice::LocalComplexTypeDef::choice</tdml:error>
+			<tdml:error>Schema Definition Error</tdml:error>
+			<tdml:error>Subset Indexing is only allowed on arrays</tdml:error>
 		</tdml:errors>
 	</tdml:parserTestCase>
 
 	<tdml:defineSchema name="simple_sdes_1">
 		<xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
     <dfdl:format ref="ex:GeneralFormat" lengthUnits="characters"
-			lengthKind="delimited" />
+			lengthKind="delimited" occursCountKind="parsed" />
 
 		<!-- Immediate children of unordered sequence must be Element or ElementRef -->
 		<xs:element name="SDE_01">
@@ -845,9 +713,8 @@
 		root="SDE_01">
 		<tdml:document><![CDATA[a1,bx20:y99:z,c55]]></tdml:document>
 		<tdml:errors>
-			<tdml:error>Members of an unordered sequence (element.SDE_01::LocalComplexTypeDef::sequence)</tdml:error>
-			<tdml:error>must be Element or ElementRef.</tdml:error>
-			<tdml:error>The offending members: choice.</tdml:error>
+			<tdml:error>Members of an unordered sequence</tdml:error>
+			<tdml:error>must be Element or ElementRef</tdml:error>
 		</tdml:errors>
 	</tdml:parserTestCase>
 
@@ -857,9 +724,8 @@
 		root="SDE_02">
 		<tdml:document><![CDATA[a1,bx20:y99:z,c55]]></tdml:document>
 		<tdml:errors>
-			<tdml:error>Members of an unordered sequence (element.SDE_02::LocalComplexTypeDef::sequence)</tdml:error>
+			<tdml:error>Members of an unordered sequence</tdml:error>
 			<tdml:error>that are optional or array elements must have dfdl:occursCountKind='parsed'.</tdml:error>
-			<tdml:error>The offending members: ruh-oh.</tdml:error>
 		</tdml:errors>
 	</tdml:parserTestCase>
 
@@ -869,10 +735,120 @@
 		root="SDE_03">
 		<tdml:document><![CDATA[a1,bx20:y99:z,c55]]></tdml:document>
 		<tdml:errors>
-			<tdml:error>Two or more members of the unordered sequence (element.SDE_03::LocalComplexTypeDef::sequence)</tdml:error>
+			<tdml:error>Two or more members of the unordered sequence</tdml:error>
 			<tdml:error>have the same name and the same namespace.</tdml:error>
-			<tdml:error>[Namespace: prefix "" is mapped to URI "http://example.com"]	Name: e2.</tdml:error>
 		</tdml:errors>
-	</tdml:parserTestCase>
+  </tdml:parserTestCase>
+
+	<tdml:defineSchema name="separated">
+		<xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+    <dfdl:format ref="ex:GeneralFormat" lengthUnits="characters"
+			lengthKind="delimited" occursCountKind="parsed" />
+		<xs:element name="infix">
+			<xs:complexType>
+				<xs:sequence dfdl:sequenceKind="unordered"
+					dfdl:separator="," dfdl:separatorPosition="infix">
+
+					<xs:element name="e1" type="xs:int" dfdl:lengthKind="delimited"
+						dfdl:initiator="a">
+					</xs:element>
+
+					<xs:element name="e2" type="xs:int" dfdl:lengthKind="delimited"
+						dfdl:initiator="b">
+					</xs:element>
+
+					<xs:element name="e3" type="xs:int" dfdl:lengthKind="delimited"
+						dfdl:initiator="c">
+					</xs:element>
+
+				</xs:sequence>
+			</xs:complexType>
+    </xs:element>
+
+    <xs:element name="prefix">
+			<xs:complexType>
+				<xs:sequence dfdl:sequenceKind="unordered"
+					dfdl:separator="," dfdl:separatorPosition="prefix">
+
+					<xs:element name="e1" type="xs:int" dfdl:lengthKind="delimited"
+						dfdl:initiator="a">
+					</xs:element>
+
+					<xs:element name="e2" type="xs:int" dfdl:lengthKind="delimited"
+						dfdl:initiator="b">
+					</xs:element>
+
+					<xs:element name="e3" type="xs:int" dfdl:lengthKind="delimited"
+						dfdl:initiator="c">
+					</xs:element>
+
+				</xs:sequence>
+			</xs:complexType>
+		</xs:element>
+
+    <xs:element name="postfix">
+			<xs:complexType>
+				<xs:sequence dfdl:sequenceKind="unordered"
+					dfdl:separator="," dfdl:separatorPosition="postfix">
+
+					<xs:element name="e1" type="xs:int" dfdl:lengthKind="delimited"
+						dfdl:initiator="a">
+					</xs:element>
+
+					<xs:element name="e2" type="xs:int" dfdl:lengthKind="delimited"
+						dfdl:initiator="b">
+					</xs:element>
+
+					<xs:element name="e3" type="xs:int" dfdl:lengthKind="delimited"
+						dfdl:initiator="c">
+					</xs:element>
+
+				</xs:sequence>
+			</xs:complexType>
+		</xs:element>
+
+	</tdml:defineSchema>
+
+	<tdml:parserTestCase name="test_separated_infix"
+		model="separated" root="infix">
+		<tdml:document><![CDATA[b2,a1,c3]]></tdml:document>
+		<tdml:infoset>
+			<tdml:dfdlInfoset>
+				<infix>
+					<e1>1</e1>
+					<e2>2</e2>
+					<e3>3</e3>
+				</infix>
+			</tdml:dfdlInfoset>
+		</tdml:infoset>
+  </tdml:parserTestCase>
+
+	<tdml:parserTestCase name="test_separated_prefix"
+		model="separated" root="prefix">
+		<tdml:document><![CDATA[,b2,a1,c3]]></tdml:document>
+		<tdml:infoset>
+			<tdml:dfdlInfoset>
+				<prefix>
+					<e1>1</e1>
+					<e2>2</e2>
+					<e3>3</e3>
+				</prefix>
+			</tdml:dfdlInfoset>
+		</tdml:infoset>
+  </tdml:parserTestCase>
+
+	<tdml:parserTestCase name="test_separated_postfix"
+		model="separated" root="postfix">
+		<tdml:document><![CDATA[b2,a1,c3,]]></tdml:document>
+		<tdml:infoset>
+			<tdml:dfdlInfoset>
+				<postfix>
+					<e1>1</e1>
+					<e2>2</e2>
+					<e3>3</e3>
+				</postfix>
+			</tdml:dfdlInfoset>
+		</tdml:infoset>
+  </tdml:parserTestCase>
 
 </tdml:testSuite>
diff --git a/daffodil-test/src/test/scala/org/apache/daffodil/section14/unordered_sequences/TestUnorderedSequencesNew.scala b/daffodil-test/src/test/scala/org/apache/daffodil/section14/unordered_sequences/TestUnorderedSequencesNew.scala
index 8c7818c..363aac3 100644
--- a/daffodil-test/src/test/scala/org/apache/daffodil/section14/unordered_sequences/TestUnorderedSequencesNew.scala
+++ b/daffodil-test/src/test/scala/org/apache/daffodil/section14/unordered_sequences/TestUnorderedSequencesNew.scala
@@ -17,33 +17,42 @@
 
 package org.apache.daffodil.section14.unordered_sequences
 
-import org.apache.daffodil.util.Misc
-import org.apache.daffodil.tdml.DFDLTestSuite
+import org.junit.Test
+import org.junit.AfterClass
+import org.apache.daffodil.tdml.Runner
 
-class TestUnorderedSequencesNew {
+object TestUnorderedSequencesNew {
   val testDir = "/org/apache/daffodil/section14/unordered_sequences/"
-  val uos = testDir + "UnorderedSequences.tdml"
-  val res = Misc.getRequiredResource(uos)
-  lazy val runner = new DFDLTestSuite(res)
+  val runner = Runner(testDir, "UnorderedSequences.tdml")
+
+  @AfterClass def shutDown {
+    runner.reset
+  }
+}
+
+class TestUnorderedSequencesNew {
+
+  import TestUnorderedSequencesNew._
 
   //DFDL-1010
-  //@Test def test_simple = { runner.runOneTest("test_simple") }
-  //@Test def test_simple_fail_scalar = { runner.runOneTest("test_simple_fail_scalar") }
-  //@Test def test_simple_min_max_occurs = { runner.runOneTest("test_simple_min_max_occurs") }
-  //@Test def test_simple_min_max_occurs_fail = { runner.runOneTest("test_simple_min_max_occurs_fail") }
-  //@Test def test_simple_delimited = { runner.runOneTest("test_simple_delimited") }
-  //@Test def test_simple_nil = { runner.runOneTest("test_simple_nil") }
-  //@Test def test_simple_invalid_path_to_branch = { runner.runOneTest("test_simple_invalid_path_to_branch") }
-  //@Test def test_simple_invalid_path_to_branch_does_not_exist = { runner.runOneTest("test_simple_invalid_path_to_branch_does_not_exist") }
-  //@Test def test_nested_valid_path_to_branch = { runner.runOneTest("test_nested_valid_path_to_branch") }
-  //@Test def test_nested_multiple_valid_paths_to_branch = { runner.runOneTest("test_nested_multiple_valid_paths_to_branch") }
-  //@Test def test_nested_multiple_invalid_paths_to_branch = { runner.runOneTest("test_nested_multiple_invalid_paths_to_branch") }
-  //@Test def test_nested_path_evaluates_to_nodelist = { runner.runOneTest("test_nested_path_evaluates_to_nodelist") }
-  //@Test def test_nested_invalid_path_to_branch = { runner.runOneTest("test_nested_invalid_path_to_branch") }
-  //@Test def test_nested_invalid_path_to_branch_2 = { runner.runOneTest("test_nested_invalid_path_to_branch_2") }
-  //@Test def test_nested_invalid_path_to_branch_3 = { runner.runOneTest("test_nested_invalid_path_to_branch_3") }
-  //@Test def test_sde_element_element_ref = { runner.runOneTest("test_sde_element_element_ref") }
-  //@Test def test_sde_optional_array_ock_parsed = { runner.runOneTest("test_sde_optional_array_ock_parsed") }
-  //@Test def test_sde_unique_names_in_ns = { runner.runOneTest("test_sde_unique_names_in_ns") }
+  @Test def test_simple = { runner.runOneTest("test_simple") }
+  @Test def test_simple_fail_scalar = { runner.runOneTest("test_simple_fail_scalar") }
+  @Test def test_simple_min_max_occurs = { runner.runOneTest("test_simple_min_max_occurs") }
+  @Test def test_simple_min_max_occurs_fail = { runner.runOneTest("test_simple_min_max_occurs_fail") }
+  @Test def test_array_reference = { runner.runOneTest("test_array_reference") }
+  @Test def test_simple_delimited = { runner.runOneTest("test_simple_delimited") }
+  @Test def test_separated_infix = { runner.runOneTest("test_separated_infix") }
+  @Test def test_separated_prefix = { runner.runOneTest("test_separated_prefix") }
+  @Test def test_separated_postfix = { runner.runOneTest("test_separated_postfix") }
+  @Test def test_simple_nil = { runner.runOneTest("test_simple_nil") }
+  @Test def test_simple_optional_elem = { runner.runOneTest("test_simple_optional_elem") }
+  @Test def test_simple_invalid_path_to_branch = { runner.runOneTest("test_simple_invalid_path_to_branch") }
+  @Test def test_simple_invalid_path_to_branch_does_not_exist = { runner.runOneTest("test_simple_invalid_path_to_branch_does_not_exist") }
+  @Test def test_nested_valid_path_to_branch = { runner.runOneTest("test_nested_valid_path_to_branch") }
+  @Test def test_nested_multiple_valid_paths_to_branch = { runner.runOneTest("test_nested_multiple_valid_paths_to_branch") }
+  @Test def test_nested_multiple_invalid_paths_to_branch = { runner.runOneTest("test_nested_multiple_invalid_paths_to_branch") }
+  @Test def test_sde_element_element_ref = { runner.runOneTest("test_sde_element_element_ref") }
+  @Test def test_sde_optional_array_ock_parsed = { runner.runOneTest("test_sde_optional_array_ock_parsed") }
+  @Test def test_sde_unique_names_in_ns = { runner.runOneTest("test_sde_unique_names_in_ns") }
 
 }