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

olabusayo 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 c43887d  Refactor isHidden
c43887d is described below

commit c43887d3976e628e0eb75ba1846dce0676d0ceec
Author: olabusayoT <[email protected]>
AuthorDate: Wed Mar 4 15:32:15 2020 -0500

    Refactor isHidden
    
    - Removes isHidden from ElementRuntimeData
    - Adds isHidden flag to GroupRef
    - Adds private hiddenDepth counter (and associated functions)
    - Adds increment/decrement logic (HiddenGroupCombinators) for PState/UState
    - overrides increment/decrement functions in UStateForSuspension to
    fail on UsageError as these have no place in that context
    - Adds check to verify  we are out of hidden state at the end of
    parsing/unparsing
    - Adds isHidden/setHidden logic to InfosetElement/DIElement
    - adds "info hidden" to debugger and associated tests
    - Reorders info subcommands and objects to maintain alphabetic ordering
    - refactors childrenThatAreRecursivelyNotDefaultableOrOVC to 
canUnparseIfHidden
    - Adds hiddenness to UState/PState toString
    - add toNameQString for SGR
    - updated SDE for no choices and seqs with no defaultable branches
    - refactored sequence unparsers to match choice unparsers when checking
    for children that can't be unparsed
    - Adds tests for group defs used in both hidden/non-hidden sequence &
    choice contexts
    - Adds tests for multiply nested hiddenGroupRefs
    - add tests to check unparseable children for sequences
    - Added test for DAFFODIL-2304
    
    DAFFODIL-2281
---
 .../it/scala/org/apache/daffodil/CLI/Util.scala    |  14 +
 .../apache/daffodil/debugger/TestCLIDebugger.scala | 201 +++++++++++++++
 .../scala/org/apache/daffodil/dsom/GroupRef.scala  |  17 +-
 .../org/apache/daffodil/dsom/ModelGroup.scala      |   8 +-
 .../org/apache/daffodil/dsom/SchemaComponent.scala |  19 +-
 .../org/apache/daffodil/dsom/SequenceGroup.scala   |  14 -
 .../main/scala/org/apache/daffodil/dsom/Term.scala |  52 ++--
 .../org/apache/daffodil/grammar/GrammarTerm.scala  |   5 +-
 .../daffodil/grammar/ModelGroupGrammarMixin.scala  |  21 +-
 .../grammar/primitives/ChoiceCombinator.scala      |  98 +++----
 .../grammar/primitives/HiddenGroupCombinator.scala |  37 +++
 .../grammar/primitives/SequenceCombinator.scala    |  32 ++-
 .../runtime1/ChoiceTermRuntime1Mixin.scala         |  16 +-
 .../runtime1/ElementBaseRuntime1Mixin.scala        |   1 -
 .../daffodil/runtime1/TermRuntime1Mixin.scala      |   9 +-
 .../unparsers/ChoiceAndOtherVariousUnparsers.scala | 100 ++++----
 .../processors/unparsers/ElementUnparser.scala     |  14 +-
 .../unparsers/ExpressionEvaluatingUnparsers.scala  |   3 +
 .../unparsers/HiddenGroupCombinatorUnparser.scala  |  45 ++++
 .../daffodil/debugger/InteractiveDebugger.scala    |  83 ++++--
 .../org/apache/daffodil/infoset/Infoset.scala      |   2 +
 .../org/apache/daffodil/infoset/InfosetImpl.scala  |  20 +-
 .../infoset/PartialNextElementResolver.scala       |   8 +-
 .../apache/daffodil/processors/DataProcessor.scala |   1 +
 .../daffodil/processors/ProcessorStateBases.scala  |  11 +
 .../apache/daffodil/processors/RuntimeData.scala   |   4 -
 .../processors/parsers/ElementCombinator1.scala    |   3 +
 .../parsers/HiddenGroupCombinatorParser.scala      |  45 ++++
 .../daffodil/processors/parsers/PState.scala       |   4 +-
 .../daffodil/processors/parsers/Parser.scala       |   1 +
 .../daffodil/processors/unparsers/UState.scala     |  10 +
 .../section14/sequence_groups/HiddenSequences.tdml | 285 +++++++++++++++++++++
 .../section14/sequence_groups/SequenceGroup.tdml   |   7 +-
 .../SequencesWithHiddenRefs.dfdl.xsd               | 153 +++++++++++
 .../choice_groups/ChoicesInHiddenContexts.dfdl.xsd | 198 ++++++++++++++
 .../section15/choice_groups/HiddenChoices.tdml     | 232 +++++++++++++++++
 .../sequence_groups/TestHiddenSequences.scala      |  63 +++++
 .../choice_groups/TestHiddenChoices.scala          |  56 ++++
 38 files changed, 1626 insertions(+), 266 deletions(-)

diff --git a/daffodil-cli/src/it/scala/org/apache/daffodil/CLI/Util.scala 
b/daffodil-cli/src/it/scala/org/apache/daffodil/CLI/Util.scala
index 3521b93..fc350eb 100644
--- a/daffodil-cli/src/it/scala/org/apache/daffodil/CLI/Util.scala
+++ b/daffodil-cli/src/it/scala/org/apache/daffodil/CLI/Util.scala
@@ -22,8 +22,10 @@ import net.sf.expectit.ExpectBuilder
 import net.sf.expectit.Expect
 import net.sf.expectit.filter.Filters.replaceInString
 import java.nio.file.Paths
+import java.io.{File, PrintWriter}
 import scala.collection.JavaConverters._
 import java.util.concurrent.TimeUnit
+
 import org.apache.daffodil.xml.XMLUtils
 
 object Util {
@@ -178,4 +180,16 @@ object Util {
       "cat " + str
     }
   }
+
+  def newTempFile(filePrefix: String, fileSuffix: String, optFileContents: 
Option[String] = None): File = {
+    val inputFile = File.createTempFile(filePrefix, fileSuffix)
+    inputFile.deleteOnExit
+    if( optFileContents.nonEmpty) {
+      val contents = optFileContents.get
+      val pw = new PrintWriter(inputFile)
+      pw.write(contents)
+      pw.close
+    }
+    inputFile
+  }
 }
diff --git 
a/daffodil-cli/src/it/scala/org/apache/daffodil/debugger/TestCLIDebugger.scala 
b/daffodil-cli/src/it/scala/org/apache/daffodil/debugger/TestCLIDebugger.scala
index 2c991cd..1412ab3 100644
--- 
a/daffodil-cli/src/it/scala/org/apache/daffodil/debugger/TestCLIDebugger.scala
+++ 
b/daffodil-cli/src/it/scala/org/apache/daffodil/debugger/TestCLIDebugger.scala
@@ -899,6 +899,207 @@ class TestCLIdebugger {
     }
   }
 
+  @Test def test_CLI_Debugger_InfoHidden_1() {
+    val schemaFile = Util.daffodilPath(
+      
"daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequencesWithHiddenRefs.dfdl.xsd")
+    val inputFile = Util.newTempFile("testInput_", ".tmp", optFileContents = 
Some("2~3"))
+    val (testSchemaFile, testInputFile) = if (Util.isWindows) {
+      (Util.cmdConvert(schemaFile), Util.cmdConvert(inputFile.getAbsolutePath))
+    } else {
+      (schemaFile, inputFile)
+    }
+
+    val shell = if (Util.isWindows) Util.start("", envp = DAFFODIL_JAVA_OPTS) 
else Util.start("")
+
+    try {
+      val cmd = String.format("%s -d parse -s %s -r e5 %s", Util.binPath, 
testSchemaFile, testInputFile)
+      shell.sendLine(cmd)
+      shell.expect(contains("(debug)"))
+
+      shell.sendLine("break f")
+      shell.sendLine("display info hidden")
+
+      shell.sendLine("continue")
+      shell.expect(contains("hidden: false"))
+
+      shell.sendLine("continue")
+      shell.expect(contains("hidden: false"))
+
+      shell.sendLine("continue")
+      shell.expect(contains("hidden: true"))
+
+      shell.sendLine("continue")
+      shell.expect(contains("hidden: true"))
+
+      shell.sendLine("continue")
+      shell.expect(contains("<f>2</f>"))
+      shell.sendLine("quit")
+    } finally {
+      shell.close()
+    }
+  }
+
+  @Test def test_CLI_Debugger_InfoHidden_2() {
+    val schemaFile = Util.daffodilPath(
+      
"daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequencesWithHiddenRefs.dfdl.xsd")
+    val inputFile = Util.newTempFile("testInput_", ".tmp", optFileContents = 
Some("2~3"))
+    val (testSchemaFile, testInputFile) = if (Util.isWindows) {
+      (Util.cmdConvert(schemaFile), Util.cmdConvert(inputFile.getAbsolutePath))
+    } else {
+      (schemaFile, inputFile)
+    }
+
+    val shell = if (Util.isWindows) Util.start("", envp = DAFFODIL_JAVA_OPTS) 
else Util.start("")
+
+    try {
+      val cmd = String.format("%s -d parse -s %s -r e4 %s", Util.binPath, 
testSchemaFile, testInputFile)
+      shell.sendLine(cmd)
+      shell.expect(contains("(debug)"))
+
+      shell.sendLine("break f")
+      shell.sendLine("display info hidden")
+
+      shell.sendLine("continue")
+      shell.expect(contains("hidden: true"))
+
+      shell.sendLine("continue")
+      shell.expect(contains("hidden: true"))
+
+      shell.sendLine("continue")
+      shell.expect(contains("hidden: false"))
+
+      shell.sendLine("continue")
+      shell.expect(contains("hidden: false"))
+
+      shell.sendLine("continue")
+      shell.expect(contains("<f>3</f>"))
+      shell.sendLine("quit")
+    } finally {
+      shell.close()
+    }
+  }
+
+  @Test def test_CLI_Debugger_InfoHidden_3() {
+    val schemaFile = Util.daffodilPath(
+      
"daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/ChoicesInHiddenContexts.dfdl.xsd")
+    val inputFile = Util.newTempFile("testInput_", ".tmp", optFileContents = 
Some("2,3"))
+    val (testSchemaFile, testInputFile) = if (Util.isWindows) {
+      (Util.cmdConvert(schemaFile), Util.cmdConvert(inputFile.getAbsolutePath))
+    } else {
+      (schemaFile, inputFile)
+    }
+
+    val shell = if (Util.isWindows) Util.start("", envp = DAFFODIL_JAVA_OPTS) 
else Util.start("")
+
+    try {
+      val cmd = String.format("%s -d parse -s %s -r e8 %s", Util.binPath, 
testSchemaFile, testInputFile)
+      shell.sendLine(cmd)
+      shell.expect(contains("(debug)"))
+
+      shell.sendLine("break a")
+      shell.sendLine("break h")
+      shell.sendLine("break g")
+      shell.sendLine("break e")
+      shell.sendLine("break f")
+      shell.sendLine("display info hidden")
+
+      shell.sendLine("continue")
+      shell.expect(contains("hidden: false"))
+
+      shell.sendLine("continue")
+      shell.expect(contains("hidden: false"))
+
+      shell.sendLine("continue")
+      shell.expect(contains("hidden: false"))
+
+      shell.sendLine("continue")
+      shell.expect(contains("hidden: true"))
+
+      shell.sendLine("continue")
+      shell.expect(contains("hidden: true"))
+
+      shell.sendLine("continue")
+      shell.expect(contains("<a>2</a>"))
+      shell.expect(contains("<g />"))
+    } finally {
+      shell.close()
+    }
+  }
+
+  @Test def test_CLI_Debugger_InfoHidden_4() {
+    val schemaFile = Util.daffodilPath(
+      
"daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/ChoicesInHiddenContexts.dfdl.xsd")
+    val inputFile = Util.newTempFile("testInput_", ".tmp", optFileContents = 
Some("[6~]9"))
+    val (testSchemaFile, testInputFile) = if (Util.isWindows) {
+      (Util.cmdConvert(schemaFile), Util.cmdConvert(inputFile.getAbsolutePath))
+    } else {
+      (schemaFile, inputFile)
+    }
+
+    val shell = if (Util.isWindows) Util.start("", envp = DAFFODIL_JAVA_OPTS) 
else Util.start("")
+
+    try {
+      val cmd = String.format("%s -d parse -s %s -r e9 %s", Util.binPath, 
testSchemaFile, testInputFile)
+      shell.sendLine(cmd)
+      shell.expect(contains("(debug)"))
+
+      shell.sendLine("break e")
+      shell.sendLine("break f")
+      shell.sendLine("break g")
+      shell.sendLine("break h")
+      shell.sendLine("break i")
+      shell.sendLine("display info path hidden")
+
+      shell.sendLine("continue")
+      shell.expect(contains(":f"))
+      shell.expect(contains("hidden: true"))
+
+      shell.sendLine("continue")
+      shell.expect(contains(":i"))
+      shell.expect(contains("hidden: true"))
+
+      shell.sendLine("continue")
+      shell.expect(contains(":h"))
+      shell.expect(contains("hidden: true"))
+
+      shell.sendLine("continue")
+      shell.expect(contains(":e"))
+      shell.expect(contains("hidden: true"))
+
+      shell.sendLine("continue")
+      shell.expect(contains(":f"))
+      shell.expect(contains("hidden: true"))
+
+      shell.sendLine("continue")
+      shell.expect(contains(":f"))
+      shell.expect(contains("hidden: false"))
+
+      shell.sendLine("continue")
+      shell.expect(contains(":g"))
+      shell.expect(contains("hidden: false"))
+
+      shell.sendLine("continue")
+      shell.expect(contains(":i"))
+      shell.expect(contains("hidden: false"))
+
+      shell.sendLine("continue")
+      shell.expect(contains(":h"))
+      shell.expect(contains("hidden: false"))
+
+      shell.sendLine("continue")
+      shell.expect(contains(":e"))
+      shell.expect(contains("hidden: true"))
+
+      shell.sendLine("continue")
+      shell.expect(contains(":f"))
+      shell.expect(contains("hidden: true"))
+
+      shell.sendLine("continue")
+      shell.expect(contains("<h />"))
+    } finally {
+      shell.close()
+    }
+  }
   /* See DFDL-1264
   @Test def test_3585_CLI_Debugger_simpleDebugger_unparse() {
     val schemaFile = 
Util.daffodilPath("daffodil-test/src/test/resources/org/apache/daffodil/section00/general/generalSchema.dfdl.xsd")
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GroupRef.scala 
b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GroupRef.scala
index e9887b9..02e7896 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GroupRef.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/GroupRef.scala
@@ -30,6 +30,11 @@ trait GroupRef { self: ModelGroup =>
 
   final def referredToComponent = groupDef
 
+  /**
+   * Override in sequenceGroupRef and choiceGroupRef for hidden groups
+   */
+  def isHidden: Boolean
+
   final override lazy val optReferredToComponent = Some(referredToComponent)
 
   final override protected lazy val groupMembersDef = LV('groupMembers) {
@@ -101,15 +106,12 @@ final class SequenceGroupRef(
   refXML: Node,
   refLexicalParent: SchemaComponent,
   positionArg: Int,
-  isHiddenArg: Boolean)
+  override val isHidden: Boolean)
   extends SequenceGroupTermBase(refXML, refLexicalParent, positionArg)
   with GroupRef {
 
   private lazy val globalGroupDef = globalGroupDefArg // once only
 
-  override def isHidden = isHiddenArg
-  override def isHiddenGroupRef = isHiddenArg
-
   private lazy val sgd = groupDef.asInstanceOf[GlobalSequenceGroupDef]
 
   override def xmlChildren = sgd.xmlChildren
@@ -129,7 +131,7 @@ final class ChoiceGroupRef(
   refXML: Node,
   refLexicalParent: SchemaComponent,
   positionArg: Int,
-  isHiddenArg: Boolean)
+  override val isHidden: Boolean)
   extends ChoiceTermBase(refXML, Option(refLexicalParent), positionArg)
   with GroupRef {
 
@@ -137,10 +139,7 @@ final class ChoiceGroupRef(
 
   private lazy val globalGroupDef = globalGroupDefArg // once only
 
-  override def isHidden = isHiddenArg
-  override def isHiddenGroupRef = isHiddenArg
-
-  override lazy val groupDef = globalGroupDef
+  override lazy val groupDef = LV('cgrGroupDef){ globalGroupDef }.value
 
   private lazy val cgd = groupDef.asInstanceOf[GlobalChoiceGroupDef]
 
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ModelGroup.scala 
b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ModelGroup.scala
index c582031..d18c248 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ModelGroup.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/ModelGroup.scala
@@ -71,7 +71,7 @@ object ModelGroupFactory {
         val seq = new Sequence(child, lexicalParent, position) // throwaway 
just so we can grab local properties to check for hidden
         if (seq.hiddenGroupRefOption.isDefined) {
           // explicit check here, because we're about to discard this, and 
construct
-          // a SequenceGroupRef or ChoiceGroupRef, with isHiddenGroupRef = 
true. So this
+          // a SequenceGroupRef or ChoiceGroupRef, with isHidden = true. So 
this
           // temporary sequence will be discarded after this.
           seq.checkHiddenGroupRefHasNoChildren
           //
@@ -148,8 +148,6 @@ abstract class ModelGroup(index: Int)
   requiredEvaluationsIfActivated(groupMembers)
   requiredEvaluationsIfActivated(initiatedContentCheck)
 
-  def isHiddenGroupRef: Boolean = false
-
   /**
    * FIXME: DAFFODIL-2132. This tells us if framing is expressed on the schema.
    * It does NOT tell us if that framing occupies bits in the data stream or 
not.
@@ -349,7 +347,7 @@ abstract class ModelGroup(index: Int)
             // follow it
             Seq(e) ++ e.possibleNextSiblingTerms
           }
-          case Some(s: SequenceTermBase) if s.isHiddenGroupRef => 
s.possibleNextSiblingTerms
+          case Some(gr: GroupRef) if gr.isHidden => gr.possibleNextSiblingTerms
           case Some(mg: ModelGroup) if !mg.mustHaveRequiredElement => Seq(mg) 
++ mg.possibleNextSiblingTerms
           case Some(e: ElementBase) => Seq(e)
           case Some(mg: ModelGroup) => Seq(mg)
@@ -370,7 +368,7 @@ abstract class ModelGroup(index: Int)
    */
   final def mustHaveRequiredElement: Boolean = LV('mustHaveRequiredElement) {
     this match {
-      case s: SequenceTermBase if s.isHiddenGroupRef => false
+      case gr: GroupRef if gr.isHidden => false
       case s: SequenceTermBase if s.isOrdered =>
         groupMembers.exists {
           case e: ElementBase => !e.canBeAbsentFromUnparseInfoset
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaComponent.scala 
b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaComponent.scala
index 0dd20b6..211bac8 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaComponent.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/SchemaComponent.scala
@@ -115,21 +115,6 @@ trait SchemaComponent
     schemaSet.variableMap
   }.value
 
-  /**
-   * Whether the component is hidden.
-   *
-   * Override this in the components that can hide - SequenceGroupRef
-   * and ChoiceGroupRef
-   */
-  def isHidden: Boolean = isHiddenLV
-
-  private lazy val isHiddenLV = {
-    val optEC = enclosingTerms.headOption // FIXME: broken if there are hidden 
and non-hidden uses
-    optEC match {
-      case None => false
-      case Some(ec) => ec.isHidden
-    }
-  }
 
   lazy val schemaComponent: LookupLocation = this
 
@@ -229,9 +214,9 @@ trait SchemaComponent
         case ct: ComplexTypeBase => "ct"
         case st: SimpleTypeDefBase => "st=" + st.namedQName.toQNameString
         case st: SimpleTypeBase => "st=" + 
st.primType.globalQName.toQNameString
-        case cgr: ChoiceGroupRef => "cgr" + (if (cgr.position > 1) 
cgr.position else "") + "=" + cgr.groupDef.namedQName.toQNameString
+        case cgr: ChoiceGroupRef => "cgr" + (if (cgr.isHidden) "h" else "") + 
(if (cgr.position > 1) cgr.position else "") + "=" + 
cgr.groupDef.namedQName.toQNameString
         case cgd: GlobalChoiceGroupDef => "cgd=" + cgd.namedQName.toQNameString
-        case sgr: SequenceGroupRef => "sgr" + (if (sgr.isHiddenGroupRef) "h" 
else "") + (if (sgr.position > 1) sgr.position else "") + "=" + 
sgr.groupDef.namedQName
+        case sgr: SequenceGroupRef => "sgr" + (if (sgr.isHidden) "h" else "") 
+ (if (sgr.position > 1) sgr.position else "") + "=" + 
sgr.groupDef.namedQName.toQNameString
         case sgd: GlobalSequenceGroupDef => "sgd=" + 
sgd.namedQName.toQNameString
         case cg: Choice => "c" + (if (cg.position > 1) cg.position else "")
         case sg: Sequence => "s" + (if (sg.position > 1) sg.position else "")
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 d412c1a..65f4564 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
@@ -73,8 +73,6 @@ abstract class SequenceTermBase(
 
   def maybeLayerTransformerEv: Maybe[LayerTransformerEv]
 
-  def checkHiddenSequenceIsDefaultableOrOVC: Unit
-
 }
 
 /**
@@ -211,16 +209,6 @@ abstract class SequenceGroupTermBase(
     }
   }
 
-  lazy val checkHiddenSequenceIsDefaultableOrOVC: Unit = {
-    if (this.isHidden) {
-      val nonDefaultableOrOVC =
-        this.childrenInHiddenGroupNotDefaultableOrOVC
-      if (nonDefaultableOrOVC.length > 0) {
-        this.SDE("Element(s) of hidden group must define 
dfdl:outputValueCalc:\n%s", nonDefaultableOrOVC.mkString("\n"))
-      }
-    }
-  }
-
   final lazy val isOrdered: Boolean = this.sequenceKind match {
     case SequenceKind.Ordered => true
     case SequenceKind.Unordered => false
@@ -361,8 +349,6 @@ final class ChoiceBranchImpliedSequence(rawGM: Term)
 
   override def maybeLayerTransformerEv: Maybe[LayerTransformerEv] = Maybe.Nope
 
-  override def checkHiddenSequenceIsDefaultableOrOVC: Unit = ()
-
   override def findPropertyOption(pname: String): PropertyLookupResult = 
rawGM.findPropertyOption(pname)
 
   /**
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 e842ea9..8531c27 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
@@ -496,7 +496,6 @@ trait Term
         case sq: SequenceTermBase if !sq.isOrdered =>
           sq.groupMembers.filter { _.isRepresented }
         case sq: SequenceDefMixin => {
-          // ??? Didin' check for ordered/unordered here.
           val psibs = priorSiblings
           val representedPriorSiblings = psibs.filter { _.isRepresented }
           val (optionalPotentialPriorReversed, requiredPotentialPriorReversed) 
=
@@ -512,52 +511,38 @@ trait Term
           val firstNonOptional = requiredPotentialPriorReversed.headOption
           optionalPotentialPrior ++ firstNonOptional
         }
-        case _ => Nil // ?? potentially wrong
+        case _ => Nil
       }
     }
   }
 
   /*
-   * This function returns at list of simple elements that are descendents of
-   * this term that are not defaultable or OVC. This is a requirement for terms
-   * inside a hidden group. Note that there is an exception for choices, in
-   * which only a single branch be all defaultable or OVC. If any elements in a
-   * hidden group are not defaultable or OVC, then it is an SDE. This function
-   * assumes it is only called on elements inside of a hidden group.
+   * This function returns a boolean if the values of the term can be figured
+   * out during unparsing or if they don't need to appear in the infoset at 
all.
    *
-   * Note that this currently only requires OVC since default's aren't
-   * implemented. This function may need to change when we support defaults.
+   * Usually this means the term/its descendants have a default value (i.e 
defaultable),
+   * have defined dfdl:outputValueCalc, or are optional (minOccurs=0)
+   *
+   * Note that this currently only requires OVC and Optionality since defaults
+   * aren't fully implemented everywhere. This function may need to change when
+   * defaults are fully implemented.
    */
-  lazy val childrenInHiddenGroupNotDefaultableOrOVC: Seq[ElementBase] = {
-    // this should only be called on hidden elements
-    val isH = isHidden
-    Assert.invariant(isH)
-
+  lazy val canUnparseIfHidden: Boolean = {
     val res = this match {
       case s: SequenceTermBase => {
-        s.groupMembers.flatMap { member =>
-          val res = member.childrenInHiddenGroupNotDefaultableOrOVC
+        s.groupMembers.forall { member =>
+          val res = member.canUnparseIfHidden
           res
         }
       }
       case c: ChoiceTermBase => {
-        val branches = c.groupMembers.map { 
_.childrenInHiddenGroupNotDefaultableOrOVC }
-        val countFullyDefaultableOrOVCBranches = branches.count { _.length == 
0 }
-        if (countFullyDefaultableOrOVCBranches == 0) {
-          c.SDE("xs:choice inside a hidden group must contain a branch with 
all children having the dfdl:outputValueCalc property set.")
-          // TODO: Diagnostics to display which branches contained 
non-defaultable elements, and what those elements were
-        }
-        Nil
+        c.groupMembers.exists { _.canUnparseIfHidden }
       }
       case e: ElementBase if e.isComplexType => {
-        e.complexType.group.childrenInHiddenGroupNotDefaultableOrOVC
+        e.complexType.group.canUnparseIfHidden
       }
       case e: ElementBase => {
-        if (!e.canBeAbsentFromUnparseInfoset) {
-          Seq(e)
-        } else {
-          Nil
-        }
+        e.canBeAbsentFromUnparseInfoset
       }
     }
     res
@@ -578,14 +563,13 @@ trait Term
   protected def possibleFirstChildTerms: Seq[Term]
 
   /*
-     * Returns list of Elements that could be the first child in the infoset 
of this model group or element.
-     */
+   * Returns list of Elements that could be the first child in the infoset of 
this model group or element.
+   */
   final lazy val possibleFirstChildElementsInInfoset: Seq[ElementBase] = 
LV('possibleFirstChildElementsInInfoset) {
     val pfct = possibleFirstChildTerms
     val firstChildren = pfct.flatMap {
-      case e: ElementBase if e.isHidden => Nil
       case e: ElementBase => Seq(e)
-      case s: SequenceTermBase if s.isHidden => Nil
+      case gr: GroupRef if gr.isHidden => Nil
       case mg: ModelGroup => mg.possibleFirstChildElementsInInfoset
     }
     firstChildren.distinct
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/GrammarTerm.scala 
b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/GrammarTerm.scala
index 59145a3..46b6291 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/GrammarTerm.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/GrammarTerm.scala
@@ -102,8 +102,9 @@ abstract class Gram(contextArg: SchemaComponent)
         if (q.isEmpty)
           EmptyGram
         else q
-      } else if (q.isEmpty) self
-      else {
+      } else if (q.isEmpty) {
+        self
+      } else {
         Assert.invariant(!self.isEmpty)
         Assert.invariant(!q.isEmpty)
         SeqComp(context, self, q)
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ModelGroupGrammarMixin.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ModelGroupGrammarMixin.scala
index a5fdf10..5ad9835 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ModelGroupGrammarMixin.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/ModelGroupGrammarMixin.scala
@@ -18,20 +18,15 @@
 package org.apache.daffodil.grammar
 
 import org.apache.daffodil.schema.annotation.props.gen._
-import org.apache.daffodil.dsom.InitiatedTerminatedMixin
-import org.apache.daffodil.dsom.ModelGroup
 import org.apache.daffodil.dsom.SharedFactory
+import org.apache.daffodil.dsom.{ChoiceTermBase, GroupRef, 
InitiatedTerminatedMixin, ModelGroup, SequenceTermBase, SchemaSet}
 import org.apache.daffodil.grammar.primitives.TrailingSkipRegion
 import org.apache.daffodil.grammar.primitives.LeadingSkipRegion
 import org.apache.daffodil.grammar.primitives.AlignmentFill
 import org.apache.daffodil.grammar.primitives.DelimiterStackCombinatorSequence
 import org.apache.daffodil.grammar.primitives.DelimiterStackCombinatorChoice
-import org.apache.daffodil.dsom.SequenceTermBase
-import org.apache.daffodil.dsom.ChoiceTermBase
-import org.apache.daffodil.grammar.primitives.DelimiterStackCombinatorChoice
 import org.apache.daffodil.runtime1.ModelGroupRuntime1Mixin
-import org.apache.daffodil.grammar.primitives.LeadingSkipRegion
-import org.apache.daffodil.dsom.SchemaSet
+import org.apache.daffodil.grammar.primitives.HiddenGroupCombinator
 
 trait ModelGroupGrammarMixin
   extends InitiatedTerminatedMixin
@@ -51,7 +46,7 @@ trait ModelGroupGrammarMixin
   }
 
   private lazy val groupContentWithInitiatorTerminator = 
prod("groupContentWithInitiatorTerminator") {
-    val finalContent =
+    val finalContent = {
       if (hasDelimiters ||
         immediatelyEnclosingModelGroup.map(_.hasDelimiters).getOrElse(false) //
         // The above reference to the delimiters of the enclosing term,
@@ -68,9 +63,15 @@ trait ModelGroupGrammarMixin
           case c: ChoiceTermBase => DelimiterStackCombinatorChoice(c, content)
           case s: SequenceTermBase => DelimiterStackCombinatorSequence(s, 
content)
         }
-      } else { groupContentDef }
+      } else {
+        groupContent
+      }
+    }
 
-    finalContent
+    this match {
+      case gr: GroupRef if gr.isHidden => new HiddenGroupCombinator(self, 
finalContent)
+      case _ => finalContent
+    }
   }
 
   /**
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/ChoiceCombinator.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/ChoiceCombinator.scala
index 8fd8cb5..abab995 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/ChoiceCombinator.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/ChoiceCombinator.scala
@@ -242,58 +242,66 @@ case class ChoiceCombinator(ch: ChoiceTermBase, 
alternatives: Seq[Gram])
   }
 
   override lazy val unparser: Unparser = {
-    if (!ch.isHiddenGroupRef) {
-      val (eventRDMap, optDefaultBranch) = ch.choiceBranchMap
-      val optDefaultUnparser: Option[Unparser] = optDefaultBranch.map { 
defaultBranch =>
-        val defaultBranchGram = defaultBranch.termContentBody
-        val defaultBranchUnparser = defaultBranchGram.unparser
-        if (defaultBranchUnparser.isEmpty) {
-          // This is a NadaUnparser, likely caused by a default choice branch
-          // that is just an empty sequence. NadaUnparsers throw an assertion
-          // when unparsed, but the ChoiceCombinatorUnparser still expects to
-          // have a something to unparse, so we have an unparser that just does
-          // nothing for this special case
-          new ChoiceBranchEmptyUnparser(defaultBranch.runtimeData)
-        } else {
-          defaultBranchUnparser
-        }
+    val (eventRDMap, optDefaultBranch) = ch.choiceBranchMap
+    /*
+     * Since it's impossible to know the hiddenness for terms at this level 
(unless
+     * they're a hiddenGroupRef), we always attempt to find a defaultable 
unparser.
+     * If we find one, and at runtime, we're in a hidden state, we can use 
that. If we
+     * are not in a hidden state, it doesn't get used. If we don't find a 
defaultable branch
+     * for a hidden group ref, we SDE because required elements must have a 
default value
+     * or dfdl:outputValueCalc defined during unparsing,
+     */
+    val optDefaultUnparser: Option[Unparser] = optDefaultBranch.map { 
defaultBranch =>
+      val defaultBranchGram = defaultBranch.termContentBody
+      val defaultBranchUnparser = defaultBranchGram.unparser
+      if (defaultBranchUnparser.isEmpty) {
+        // This is a NadaUnparser, likely caused by a default choice branch
+        // that is just an empty sequence. NadaUnparsers throw an assertion
+        // when unparsed, but the ChoiceCombinatorUnparser still expects to
+        // have a something to unparse, so we have an unparser that just does
+        // nothing for this special case
+        new ChoiceBranchEmptyUnparser(defaultBranch.runtimeData)
+      } else {
+        defaultBranchUnparser
       }
+    }
 
-      val eventUnparserMap = eventRDMap.map {
-        case (cbe, branchTerm) => (cbe, branchTerm.termContentBody.unparser)
-      }
-      val mapValues = eventUnparserMap.map { case (k, v) => v 
}.toSeq.filterNot(_.isEmpty)
-      if (mapValues.isEmpty)
-        if (optDefaultBranch.isEmpty)
-          new NadaUnparser(null)
-        else {
-          // just a default branch.
-          Assert.invariant(optDefaultUnparser.isDefined)
-          optDefaultUnparser.get
+    val branchForUnparse = if (optDefaultUnparser.isEmpty) {
+      ch match {
+        case cgr: ChoiceGroupRef if cgr.isHidden => {
+          /*
+           * This is a requirement for at least one term inside a hidden 
choice, we
+           * SDE if there is no descendant that is fully defaultable, optional 
or OVC.
+           */
+          cgr.SDE(
+            "At least one branch of hidden choice must be fully defaultable or 
define dfdl:outputValueCalc:\n%s",
+            ch.groupMembers.mkString("\n"))
         }
-      else {
-        val cbm = ChoiceBranchMap(eventUnparserMap, optDefaultUnparser)
-        new ChoiceCombinatorUnparser(ch.modelGroupRuntimeData, cbm, 
choiceLengthInBits)
+        /*
+         * empty unparser is fine as we have no expectations of hiddenness 
during
+         * compile time if it's not a hiddenGroupRef
+         */
+        case _ => optDefaultUnparser
       }
     } else {
-      // Choices inside a hidden group ref are slightly different because we
-      // will never see events for any of the branches. Instead, we will just
-      // always pick the branch in which every thing is defaultble or OVC. It
-      // is a warning if more than one of those branches exist. It is an SDE if
-      // such a branch does not exist, which is detected elsewhere
+      optDefaultUnparser
+    }
 
-      // this call is necessary since it will throw an SDE if no choice branch
-      // was defaultable
-      ch.childrenInHiddenGroupNotDefaultableOrOVC
-      val defaultableBranches = ch.groupMembers.filter { 
_.childrenInHiddenGroupNotDefaultableOrOVC.length == 0 }
-      Assert.invariant(defaultableBranches.length > 0)
-      if (defaultableBranches.length > 1) {
-        SDW(WarnID.ChoiceInsideHiddenGroup, "xs:choice inside a hidden group 
has unparse ambiguity: multiple branches exist with all children either 
defaulable or have the dfdl:outputValueCalc property set. The first branch will 
be chosen during unparse. Defaultable branches are:\n%s",
-          defaultableBranches.mkString("\n"))
+    val eventUnparserMap = eventRDMap.map {
+      case (cbe, branchTerm) => (cbe, branchTerm.termContentBody.unparser)
+    }
+    val mapValues = eventUnparserMap.map { case (k, v) => v 
}.toSeq.filterNot(_.isEmpty)
+    if (mapValues.isEmpty) {
+      if (branchForUnparse.isEmpty) {
+        new NadaUnparser(null)
+      } else {
+        // just a default branch.
+        Assert.invariant(branchForUnparse.isDefined)
+        branchForUnparse.get
       }
-      val defaultableBranchRD = defaultableBranches(0).runtimeData
-      val defaultableBranchUnparser = alternatives.find(_.context.runtimeData 
=:= defaultableBranchRD).get.unparser
-      new HiddenChoiceCombinatorUnparser(ch.modelGroupRuntimeData, 
defaultableBranchUnparser)
+    } else {
+      val cbm = ChoiceBranchMap(eventUnparserMap, branchForUnparse)
+      new ChoiceCombinatorUnparser(ch.modelGroupRuntimeData, cbm, 
choiceLengthInBits)
     }
   }
 }
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/HiddenGroupCombinator.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/HiddenGroupCombinator.scala
new file mode 100644
index 0000000..d5b7f49
--- /dev/null
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/grammar/primitives/HiddenGroupCombinator.scala
@@ -0,0 +1,37 @@
+/*
+ * 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.grammar.primitives
+
+import org.apache.daffodil.dsom.ModelGroup
+import org.apache.daffodil.grammar.Gram
+import org.apache.daffodil.grammar.Terminal
+import org.apache.daffodil.processors.parsers.Parser
+import org.apache.daffodil.processors.unparsers.Unparser
+import org.apache.daffodil.processors.parsers.HiddenGroupCombinatorParser
+import org.apache.daffodil.processors.unparsers.HiddenGroupCombinatorUnparser
+
+final class HiddenGroupCombinator(
+  ctxt: ModelGroup,
+  body: Gram)
+  extends Terminal(ctxt, !body.isEmpty) {
+
+  lazy val parser: Parser = new 
HiddenGroupCombinatorParser(ctxt.modelGroupRuntimeData, body.parser)
+
+  override lazy val unparser: Unparser = new 
HiddenGroupCombinatorUnparser(ctxt.modelGroupRuntimeData, body.unparser)
+
+}
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 73801fd..59f23ed 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
@@ -61,7 +61,21 @@ class OrderedSequence(sq: SequenceTermBase, 
sequenceChildrenArg: Seq[SequenceChi
         sequenceChildren.flatMap { _.optSequenceChildParser })
   }
   override lazy val unparser: Unparser = {
-    sq.checkHiddenSequenceIsDefaultableOrOVC
+    sq match {
+      case sgr: SequenceGroupRef if sgr.isHidden =>
+        /*
+         * This is a requirement for all descendants of a hidden sequence, so 
we
+         * SDE if all descendants are not fully defaultable, optional or OVC.
+         */
+        val nonUnparseableIfHidden = 
sq.groupMembers.filter(!_.canUnparseIfHidden)
+        if (nonUnparseableIfHidden.nonEmpty) {
+          SDE("Element(s) of hidden group must define dfdl:outputValueCalc, be 
defaultable or be optional:\n%s",
+            nonUnparseableIfHidden.mkString("\n"))
+        }
+      case _ => {
+        //do nothing as only GroupRefs have the concept of hiddenness at 
compile time
+      }
+    }
     val childUnparsers = sequenceChildren.flatMap { _.optSequenceChildUnparser 
}
     if (childUnparsers.isEmpty) new NadaUnparser(null)
     else {
@@ -138,7 +152,21 @@ class UnorderedSequence(sq: SequenceTermBase, 
sequenceChildrenArg: Seq[SequenceC
   }
 
   override lazy val unparser: Unparser = {
-    sq.checkHiddenSequenceIsDefaultableOrOVC
+    sq match {
+      case sgr: SequenceGroupRef if sgr.isHidden =>
+        /*
+         * This is a requirement for all descendants of a hidden sequence, so 
we
+         * SDE if all descendants are not fully defaultable, optional or OVC.
+         */
+        val nonUnparseableIfHidden  = sq.groupMembers.filter( 
!_.canUnparseIfHidden)
+        if (nonUnparseableIfHidden.nonEmpty) {
+          SDE("Element(s) of hidden group must define dfdl:outputValueCalc, be 
defaultable or be optional:\n%s",
+            nonUnparseableIfHidden.mkString("\n"))
+        }
+      case _ => {
+        //do nothing as only GroupRefs have the concept of hiddenness at 
compile state
+      }
+    }
     val childUnparsers = sequenceChildren.flatMap { _.optSequenceChildUnparser 
}
     if (childUnparsers.isEmpty) new NadaUnparser(null)
     else {
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ChoiceTermRuntime1Mixin.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ChoiceTermRuntime1Mixin.scala
index 5fe80b0..4c59342 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ChoiceTermRuntime1Mixin.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ChoiceTermRuntime1Mixin.scala
@@ -17,26 +17,21 @@
 
 package org.apache.daffodil.runtime1
 
-import org.apache.daffodil.dsom.ChoiceTermBase
-import org.apache.daffodil.dsom.ModelGroup
+import org.apache.daffodil.dsom.{ChoiceGroupRef, ChoiceTermBase, ElementBase, 
ExpressionCompilers, ModelGroup, SequenceTermBase, Term}
 import org.apache.daffodil.infoset.ChoiceBranchStartEvent
 import org.apache.daffodil.processors.RuntimeData
 import org.apache.daffodil.processors.ChoiceRuntimeData
-import org.apache.daffodil.dsom.ElementBase
 import org.apache.daffodil.infoset.ChoiceBranchEvent
 import org.apache.daffodil.exceptions.Assert
 import org.apache.daffodil.infoset.ChoiceBranchEndEvent
-import org.apache.daffodil.dsom.SequenceTermBase
 import org.apache.daffodil.api.WarnID
 import org.apache.daffodil.processors.ChoiceDispatchKeyEv
-import org.apache.daffodil.dsom.ExpressionCompilers
 import org.apache.daffodil.dpath.NodeInfo
 import org.apache.daffodil.grammar.Gram
 import org.apache.daffodil.processors.TermRuntimeData
 import org.apache.daffodil.processors.SequenceRuntimeData
 import org.apache.daffodil.processors.ElementRuntimeData
 import org.apache.daffodil.processors.unparsers.ChoiceBranchMap
-import org.apache.daffodil.dsom.Term
 import org.apache.daffodil.grammar.Gram
 
 trait ChoiceTermRuntime1Mixin { self: ChoiceTermBase =>
@@ -97,19 +92,22 @@ trait ChoiceTermRuntime1Mixin { self: ChoiceTermBase =>
       // in the arriving infoset for unparse.
       //
       val optDefaultBranch = {
-
         val optEmpty: Option[Term] =
           groupMembers.find { gm =>
             val ies = gm.identifyingEventsForChoiceBranch
             ies.pnes.isEmpty // empty event list makes it the default, not 
simply isOpen
-        }
-        val optDefault: Option[Term] =
+          }
+        val optOpen: Option[Term] =
           optEmpty.orElse {
             groupMembers.find { gm =>
               val ies = gm.identifyingEventsForChoiceBranch
               ies.isOpen // first open one is used if there is no branch that 
has empty event list. (test ptg_1u)
             }
           }
+        val optDefault: Option[Term] =
+          optOpen.orElse {
+            groupMembers.find { _.canUnparseIfHidden } //optional, defaultable 
or OVC
+          }
         optDefault
       }
 
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ElementBaseRuntime1Mixin.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ElementBaseRuntime1Mixin.scala
index a66bc97..4a38540 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ElementBaseRuntime1Mixin.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/ElementBaseRuntime1Mixin.scala
@@ -189,7 +189,6 @@ trait ElementBaseRuntime1Mixin { self: ElementBase =>
       name,
       targetNamespacePrefix,
       thisElementsNamespacePrefix,
-      isHidden,
       isNillable,
       isArray, // can have more than 1 occurrence
       isOptional, // can have exactly 0 or 1 occurrence
diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/TermRuntime1Mixin.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/TermRuntime1Mixin.scala
index 4a1f0d1..3ed3012 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/TermRuntime1Mixin.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/TermRuntime1Mixin.scala
@@ -122,9 +122,9 @@ trait TermRuntime1Mixin { self: Term =>
         Closed(Seq(PNE(eb, true)))
       case eb: ElementBase =>
         Open(Seq(PNE(eb, false)))
-      case stb: SequenceTermBase if stb.isHiddenGroupRef =>
+      case sgr: SequenceGroupRef if sgr.isHidden =>
         Open(Nil)
-      case ctb: ChoiceTermBase if ctb.isHiddenGroupRef =>
+      case cgr: ChoiceGroupRef if cgr.isHidden =>
         Open(Nil)
       case ctb: ChoiceTermBase => {
         val gms = ctb.groupMembers
@@ -276,7 +276,8 @@ trait TermRuntime1Mixin { self: Term =>
             }
           res
         }
-        case stb: SequenceTermBase if !stb.isHidden => {
+        case gr: GroupRef if gr.isHidden => Open(Nil)
+        case stb: SequenceTermBase => {
           //
           // This case only applies to when we are analyzing a sequence, but 
it is
           // being considered as contributing possible elements that are after 
the
@@ -289,8 +290,6 @@ trait TermRuntime1Mixin { self: Term =>
             subTerms.headOption.map { 
_.possibleSelfPlusNextLexicalSiblingStreamingUnparserElements }
           res.getOrElse(Open(Nil))
         }
-        case stb: SequenceTermBase if stb.isHidden =>
-          Open(Nil)
       }
       val res = thisItself match {
         //
diff --git 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ChoiceAndOtherVariousUnparsers.scala
 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ChoiceAndOtherVariousUnparsers.scala
index 160eea8..47cd220 100644
--- 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ChoiceAndOtherVariousUnparsers.scala
+++ 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ChoiceAndOtherVariousUnparsers.scala
@@ -59,6 +59,8 @@ case class ChoiceBranchMap(
     res
   }
 
+  def defaultUnparser = unmappedDefault
+
   def childProcessors = lookupTable.values.toSeq ++ unmappedDefault
 
   def keys = lookupTable.keys
@@ -82,7 +84,7 @@ class ChoiceBranchEmptyUnparser(val context: RuntimeData)
 
 class ChoiceCombinatorUnparser(
   mgrd: ModelGroupRuntimeData,
-  eventUnparserMap: ChoiceBranchMap,
+  choiceBranchMap: ChoiceBranchMap,
   choiceLengthInBits: MaybeInt)
   extends CombinatorUnparser(mgrd)
   with ToBriefXMLImpl {
@@ -90,64 +92,52 @@ class ChoiceCombinatorUnparser(
 
   override val runtimeDependencies = Vector()
 
-  override val childProcessors = eventUnparserMap.childProcessors.toVector
+  override val childProcessors = choiceBranchMap.childProcessors.toVector
 
   def unparse(state: UState): Unit = {
-    state.pushTRD(mgrd)
-    val event: InfosetAccessor = state.inspectOrError
-    val key: ChoiceBranchEvent = event match {
-      //
-      // The ChoiceBranchStartEvent(...) is not a case class constructor. It 
is a
-      // hash-table lookup for a cached value. This avoids constructing these
-      // objects over and over again.
-      //
-      case e if e.isStart && e.isElement => 
ChoiceBranchStartEvent(e.erd.namedQName)
-      case e if e.isEnd && e.isElement => 
ChoiceBranchEndEvent(e.erd.namedQName)
-      case e if e.isStart && e.isArray => 
ChoiceBranchStartEvent(e.erd.namedQName)
-      case e if e.isEnd && e.isArray => ChoiceBranchEndEvent(e.erd.namedQName)
-    }
-
-    val maybeChildUnparser = eventUnparserMap.get(key)
-    if (maybeChildUnparser.isEmpty) {
-      UnparseError(One(mgrd.schemaFileLocation), One(state.currentLocation),
-        "Found next element %s, but expected one of %s.",
-        key.qname.toExtendedSyntax,
-        eventUnparserMap.keys.map { _.qname.toExtendedSyntax }.mkString(", "))
-    }
-    val childUnparser = maybeChildUnparser.get
-    state.popTRD(mgrd)
-    state.pushTRD(childUnparser.context.asInstanceOf[TermRuntimeData])
-    if (choiceLengthInBits.isDefined) {
-      val suspendableOp = new ChoiceUnusedUnparserSuspendableOperation(mgrd, 
choiceLengthInBits.get)
-      val choiceUnusedUnparser = new ChoiceUnusedUnparser(mgrd, 
choiceLengthInBits.get, suspendableOp)
-
-      suspendableOp.captureDOSStartForChoiceUnused(state)
-      childUnparser.unparse1(state)
-      suspendableOp.captureDOSEndForChoiceUnused(state)
-      choiceUnusedUnparser.unparse(state)
+    if (state.withinHiddenNest) {
+      val branchForUnparseIfHidden = choiceBranchMap.defaultUnparser
+      branchForUnparseIfHidden.get.unparse1(state)
     } else {
-      childUnparser.unparse1(state)
-    }
-    state.popTRD(childUnparser.context.asInstanceOf[TermRuntimeData])
-  }
-}
-
-// Choices inside a hidden group ref (i.e. Hidden Choices) are slightly
-// different because we will never see events for any of the branches. Instead,
-// we will just always pick the branch in which every thing is defaultble or
-// OVC, so we can calculated exactly which branch to take in a hidden choice
-// statically at compile time. That logic is in ChoiceCombinator, and the
-// branch to take is passed into this HiddenChoiceCombinatorUnparser.
-class HiddenChoiceCombinatorUnparser(mgrd: ModelGroupRuntimeData, 
branchUnparser: Unparser)
-  extends CombinatorUnparser(mgrd)
-  with ToBriefXMLImpl {
-  override def nom = "HiddenChoice"
-  override lazy val runtimeDependencies = Vector()
-
-  override lazy val childProcessors = Vector(branchUnparser)
+      state.pushTRD(mgrd)
+      val event: InfosetAccessor = state.inspectOrError
+      val key: ChoiceBranchEvent = event match {
+        //
+        // The ChoiceBranchStartEvent(...) is not a case class constructor. It 
is a
+        // hash-table lookup for a cached value. This avoids constructing these
+        // objects over and over again.
+        //
+        case e if e.isStart && e.isElement => 
ChoiceBranchStartEvent(e.erd.namedQName)
+        case e if e.isEnd && e.isElement => 
ChoiceBranchEndEvent(e.erd.namedQName)
+        case e if e.isStart && e.isArray => 
ChoiceBranchStartEvent(e.erd.namedQName)
+        case e if e.isEnd && e.isArray => 
ChoiceBranchEndEvent(e.erd.namedQName)
+      }
 
-  def unparse(state: UState): Unit = {
-    branchUnparser.unparse1(state)
+      val maybeChildUnparser = choiceBranchMap.get(key)
+      if (maybeChildUnparser.isEmpty) {
+        UnparseError(One(mgrd.schemaFileLocation), One(state.currentLocation),
+          "Found next element %s, but expected one of %s.",
+          key.qname.toExtendedSyntax,
+          choiceBranchMap.keys.map {
+            _.qname.toExtendedSyntax
+          }.mkString(", "))
+      }
+      val childUnparser = maybeChildUnparser.get
+      state.popTRD(mgrd)
+      state.pushTRD(childUnparser.context.asInstanceOf[TermRuntimeData])
+      if (choiceLengthInBits.isDefined) {
+        val suspendableOp = new ChoiceUnusedUnparserSuspendableOperation(mgrd, 
choiceLengthInBits.get)
+        val choiceUnusedUnparser = new ChoiceUnusedUnparser(mgrd, 
choiceLengthInBits.get, suspendableOp)
+
+        suspendableOp.captureDOSStartForChoiceUnused(state)
+        childUnparser.unparse1(state)
+        suspendableOp.captureDOSEndForChoiceUnused(state)
+        choiceUnusedUnparser.unparse(state)
+      } else {
+        childUnparser.unparse1(state)
+      }
+      state.popTRD(childUnparser.context.asInstanceOf[TermRuntimeData])
+    }
   }
 }
 
diff --git 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ElementUnparser.scala
 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ElementUnparser.scala
index 2bd7785..06072c8 100644
--- 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ElementUnparser.scala
+++ 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ElementUnparser.scala
@@ -408,8 +408,8 @@ sealed trait RegularElementUnparserStartEndStrategy
       ()
     } else {
       val elem =
-        if (!erd.isHidden) {
-          // Hidden elements are not in the infoset, so we will never get an 
event
+        if (!state.withinHiddenNest) {
+          // Elements in a hidden context are not in the infoset, so we will 
never get an event
           // for them. Only try to consume start events for non-hidden elements
           val event = state.advanceOrError
           if (!event.isStart || event.erd != erd) {
@@ -437,10 +437,11 @@ sealed trait RegularElementUnparserStartEndStrategy
           }
           res
         } else {
-          Assert.invariant(erd.isHidden)
-          // Since we never get events for hidden elements, their infoset 
elements
+          Assert.invariant(state.withinHiddenNest)
+          // Since we never get events for elements in hidden contexts, their 
infoset elements
           // will have never been created. This means we need to manually 
create them
           val e = if (erd.isComplexType) new DIComplex(erd) else new 
DISimple(erd)
+          e.setHidden()
           state.currentInfosetNode.asComplex.addChild(e, state.tunable)
           e
         }
@@ -464,7 +465,7 @@ sealed trait RegularElementUnparserStartEndStrategy
       Assert.invariant(state.currentInfosetNode.asSimple.erd eq erd)
       ()
     } else {
-      if (!erd.isHidden) {
+      if (!state.withinHiddenNest) {
         // Hidden elements are not in the infoset, so we will never get an 
event
         // for them. Only try to consume end events for non-hidden elements
         val event = state.advanceOrError
@@ -496,7 +497,7 @@ trait OVCStartEndStrategy
    */
   protected final override def unparseBegin(state: UState) {
     val elem =
-      if (!erd.isHidden) {
+      if (!state.withinHiddenNest) {
         // outputValueCalc elements are optional in the infoset. If the next 
event
         // is for this OVC element, then consume the start/end events.
         // Otherwise, the next event is for a following element, and we do not 
want
@@ -525,6 +526,7 @@ trait OVCStartEndStrategy
       } else {
         // Event was hidden and will never exist, create a new InfosetElement 
and add it
         val e = new DISimple(erd)
+        e.setHidden()
         state.currentInfosetNode.asComplex.addChild(e, state.tunable)
         e
       }
diff --git 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ExpressionEvaluatingUnparsers.scala
 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ExpressionEvaluatingUnparsers.scala
index 62cb5b4..7906e77 100644
--- 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ExpressionEvaluatingUnparsers.scala
+++ 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/ExpressionEvaluatingUnparsers.scala
@@ -135,6 +135,9 @@ class TypeValueCalcUnparser(typeCalculator: TypeCalculator, 
repTypeUnparser: Unp
 
     val origInfosetElement = ustate.currentInfosetNode
     val tmpInfosetElement = 
Infoset.newElement(repTypeRuntimeData).asInstanceOf[DISimple]
+    if (ustate.withinHiddenNest)
+      tmpInfosetElement.setHidden()
+
 
     if (ustate.processorStatus == Success) {
 
diff --git 
a/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/HiddenGroupCombinatorUnparser.scala
 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/HiddenGroupCombinatorUnparser.scala
new file mode 100644
index 0000000..5ba81bf
--- /dev/null
+++ 
b/daffodil-runtime1-unparser/src/main/scala/org/apache/daffodil/processors/unparsers/HiddenGroupCombinatorUnparser.scala
@@ -0,0 +1,45 @@
+/*
+ * 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.unparsers
+
+import org.apache.daffodil.processors.ModelGroupRuntimeData
+
+/**
+ * The purpose of this combinator is to increment/decrement the depth counter
+ * for hidden groups, and call the group's unparser. As we get deeper into the
+ * hiddenGroupRefs, we'll increment the counter, call the group's unparser, 
and as
+ * we unwind from the refs, we'll decrement.
+ */
+class HiddenGroupCombinatorUnparser(
+  ctxt: ModelGroupRuntimeData, bodyUnparser: Unparser)
+  extends CombinatorUnparser(ctxt) {
+
+  override lazy val childProcessors = Vector(bodyUnparser)
+
+  override lazy val runtimeDependencies = Vector()
+
+  def unparse(start: UState): Unit = {
+    try {
+      start.incrementHiddenDef
+      // unparse
+      bodyUnparser.unparse1(start)
+    } finally {
+      start.decrementHiddenDef
+    }
+  }
+}
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/debugger/InteractiveDebugger.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/debugger/InteractiveDebugger.scala
index 84380d7..0d9cba0 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/debugger/InteractiveDebugger.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/debugger/InteractiveDebugger.scala
@@ -1191,7 +1191,25 @@ class InteractiveDebugger(runner: 
InteractiveDebuggerRunner, eCompilers: Express
                         |multiple times to display multiple pieces of 
information.
                         |
                         |Example: info data infoset""".stripMargin
-      override val subcommands = Seq(InfoBitLimit, InfoBitPosition, 
InfoBreakpoints, InfoChildIndex, InfoData, InfoDelimiterStack, InfoDiff, 
InfoDiscriminator, InfoDisplays, InfoFoundDelimiter, InfoGroupIndex, 
InfoInfoset, InfoOccursIndex, InfoParser, InfoUnparser, InfoPath)
+      override val subcommands =
+        Seq(
+          InfoBitLimit,
+          InfoBitPosition,
+          InfoBreakpoints,
+          InfoChildIndex,
+          InfoData,
+          InfoDelimiterStack,
+          InfoDiff,
+          InfoDiscriminator,
+          InfoDisplays,
+          InfoFoundDelimiter,
+          InfoGroupIndex,
+          InfoHidden,
+          InfoInfoset,
+          InfoOccursIndex,
+          InfoPath,
+          InfoParser,
+          InfoUnparser)
 
       override def validate(args: Seq[String]) {
         if (args.size == 0) {
@@ -1231,21 +1249,6 @@ class InteractiveDebugger(runner: 
InteractiveDebuggerRunner, eCompilers: Express
         }
       }
 
-      object InfoOccursIndex extends DebugCommand with 
DebugCommandValidateZeroArgs {
-        val name = "occursIndex"
-        override lazy val short = "oi"
-        val desc = "display the current array limit"
-        val longDesc = desc
-        def act(args: Seq[String], prestate: StateForDebugger, state: 
ParseOrUnparseState, processor: Processor): DebugState.Type = {
-          if (state.arrayPos != -1) {
-            debugPrintln("%s: %d".format(name, state.arrayPos))
-          } else {
-            debugPrintln("%s: not in an array".format(name))
-          }
-          DebugState.Pause
-        }
-      }
-
       object InfoBitLimit extends DebugCommand with 
DebugCommandValidateZeroArgs {
         val name = "bitLimit"
         override lazy val short = "bl"
@@ -1497,6 +1500,17 @@ class InteractiveDebugger(runner: 
InteractiveDebuggerRunner, eCompilers: Express
         }
       }
 
+      object InfoHidden extends DebugCommand with DebugCommandValidateZeroArgs 
{
+        val name = "hidden"
+        override lazy val short = "h"
+        val desc = "display whether or not we're within the nesting context of 
a hidden group"
+        val longDesc = desc
+        def act(args: Seq[String], prestate: StateForDebugger, state: 
ParseOrUnparseState, processor: Processor): DebugState.Type = {
+          debugPrintln("%s: %b".format(name, state.withinHiddenNest))
+          DebugState.Pause
+        }
+      }
+
       object InfoInfoset extends DebugCommand with 
DebugCommandValidateZeroArgs {
         val name = "infoset"
         val desc = "display the current infoset"
@@ -1545,23 +1559,21 @@ class InteractiveDebugger(runner: 
InteractiveDebuggerRunner, eCompilers: Express
         }
       }
 
-      abstract class InfoProcessorBase extends DebugCommand with 
DebugCommandValidateZeroArgs {
-        val desc = "display the current Daffodil " + name
+      object InfoOccursIndex extends DebugCommand with 
DebugCommandValidateZeroArgs {
+        val name = "occursIndex"
+        override lazy val short = "oi"
+        val desc = "display the current array limit"
         val longDesc = desc
         def act(args: Seq[String], prestate: StateForDebugger, state: 
ParseOrUnparseState, processor: Processor): DebugState.Type = {
-          debugPrintln("%s: %s".format(name, processor.toBriefXML(2))) // only 
2 levels of output, please!
+          if (state.arrayPos != -1) {
+            debugPrintln("%s: %d".format(name, state.arrayPos))
+          } else {
+            debugPrintln("%s: not in an array".format(name))
+          }
           DebugState.Pause
         }
       }
 
-      object InfoParser extends {
-        override val name = "parser" // scala -xcheckinit reported this was 
uninitialized
-      } with InfoProcessorBase
-
-      object InfoUnparser extends {
-        override val name = "unparser"
-      } with InfoProcessorBase
-
       object InfoPath extends DebugCommand with DebugCommandValidateZeroArgs {
         val name = "path"
         override lazy val short = "path"
@@ -1572,6 +1584,23 @@ class InteractiveDebugger(runner: 
InteractiveDebuggerRunner, eCompilers: Express
           DebugState.Pause
         }
       }
+
+      abstract class InfoProcessorBase extends DebugCommand with 
DebugCommandValidateZeroArgs {
+        val desc = "display the current Daffodil " + name
+        val longDesc = desc
+        def act(args: Seq[String], prestate: StateForDebugger, state: 
ParseOrUnparseState, processor: Processor): DebugState.Type = {
+          debugPrintln("%s: %s".format(name, processor.toBriefXML(2))) // only 
2 levels of output, please!
+          DebugState.Pause
+        }
+      }
+
+      object InfoParser extends {
+        override val name = "parser" // scala -xcheckinit reported this was 
uninitialized
+      } with InfoProcessorBase
+
+      object InfoUnparser extends {
+        override val name = "unparser"
+      } with InfoProcessorBase
     }
 
     object Quit extends DebugCommand with DebugCommandValidateZeroArgs {
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/Infoset.scala 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/Infoset.scala
index 17b31d9..e07aba7 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/Infoset.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/Infoset.scala
@@ -62,6 +62,8 @@ trait InfosetElement extends InfosetItem {
   def namespace: NS
   def name: String
   def isHidden: Boolean
+  def setHidden(): Unit
+
 }
 
 trait InfosetComplexElement extends InfosetElement {
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 b314faa..d335481 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
@@ -863,18 +863,16 @@ sealed trait DIElement
   }
 
   /**
-   * Note: there is no infoset data member for isHidden. A hidden group is
-   * a DFDL schema characteristic for a model group. Elements inside it will
-   * have (their element base) isHidden statically on the schema. So there is
-   * no notion of creating an infoset element then making it hidden by marking
-   * it in some way. Rather, the corresponding elementRuntimeData tells you 
whether
-   * it is hidden or not.
-   *
-   * When we convert to XML, then if we want to preserve information about
-   * things being hidden (for inspection by looking at the XML) then we
-   * need to add an attribute. But for the infoset itself, we don't need it.
+   * If we are in a hidden context, isHidden should be true for the infoset
+   * data member. Therefore, when a new element is created in a hidden context
+   * we set isHidden to true.
    */
-  final def isHidden: Boolean = erd.isHidden
+  protected final var _isHidden = false
+  final def isHidden: Boolean = _isHidden
+
+  override def setHidden: Unit = {
+    _isHidden = true
+  }
 
   final def runtimeData = erd
   protected final var _parent: InfosetComplexElement = null
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/PartialNextElementResolver.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/PartialNextElementResolver.scala
index f7c51ce..c7962ac 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/PartialNextElementResolver.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/PartialNextElementResolver.scala
@@ -76,12 +76,8 @@ trait NextElementResolver { self: InfosetInputter =>
         // set of possible elements.
         //
         maybeERD = resolver.maybeNextElement(name, nameSpace, hasNamespace)
-        //
-        // If the ERD is marked hidden, then we never expect any events 
corresponding
-        // to its elements.
-        //
-        if (maybeERD.isDefined && maybeERD.get.isHidden)
-          maybeERD = Nope // clobber it back to Nope
+        // The cases where ERD is in a hidden context are addressed where the 
elements
+        // are assigned their value i.e ElementUnparser
       }
     } // end while
     //
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/DataProcessor.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/DataProcessor.scala
index 5aeabbb..3adc8ac 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/DataProcessor.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/DataProcessor.scala
@@ -437,6 +437,7 @@ class DataProcessor(
     Assert.invariant(state.currentInfosetNodeMaybe.isEmpty)
     Assert.invariant(state.escapeSchemeEVCache.isEmpty)
     Assert.invariant(state.maybeTopTRD().isEmpty) // dynamic TRD stack is empty
+    Assert.invariant(!state.withinHiddenNest) //ensure we are not in hidden 
nest
 
     //
     // All the DOS that precede the last one
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/ProcessorStateBases.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/ProcessorStateBases.scala
index c7e737e..2e226e4 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/ProcessorStateBases.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/ProcessorStateBases.scala
@@ -480,6 +480,17 @@ abstract class ParseOrUnparseState protected (
     res
   }
 
+  private var _hiddenDepth = 0
+
+  def incrementHiddenDef = {
+    _hiddenDepth += 1
+  }
+  def decrementHiddenDef = {
+    _hiddenDepth -= 1
+  }
+
+  def withinHiddenNest: Boolean = _hiddenDepth > 0
+
   /**
    * The User API sets the debugger and debug on/off flag on the DataProcessor 
object.
    * When a PState or UState is created by the DataProcessor, the DataProcessor
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 ed0c6b7..1387a90 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
@@ -631,7 +631,6 @@ sealed class ElementRuntimeData(
   @TransientParam nameArg: => String,
   @TransientParam targetNamespacePrefixArg: => String,
   @TransientParam thisElementsNamespacePrefixArg: => String,
-  @TransientParam isHiddenArg: => Boolean,
   @TransientParam isNillableArg: => Boolean,
   @TransientParam isArrayArg: => Boolean, // can have more than 1 occurrence
   @TransientParam isOptionalArg: => Boolean, // can have only 0 or 1 occurrence
@@ -691,7 +690,6 @@ sealed class ElementRuntimeData(
   lazy val name = nameArg
   lazy val targetNamespacePrefix = targetNamespacePrefixArg
   lazy val thisElementsNamespacePrefix = thisElementsNamespacePrefixArg
-  lazy val isHidden = isHiddenArg
   lazy val isNillable = isNillableArg
   override lazy val isArray = isArrayArg
   lazy val isOptional = isOptionalArg
@@ -727,7 +725,6 @@ sealed class ElementRuntimeData(
     name
     targetNamespacePrefix
     thisElementsNamespacePrefix
-    isHidden
     isNillable
     isArray
     isOptional
@@ -825,7 +822,6 @@ sealed abstract class ErrorERD(local: String, namespaceURI: 
String)
     local, // nameArg: => String,
     null, // targetNamespacePrefixArg: => String,
     null, // thisElementsNamespacePrefixArg: => String,
-    false, // isHiddenArg: => Boolean,
     false, // isNillableArg: => Boolean,
     false, // isArrayArg: => Boolean, // can have more than 1 occurrence
     false, // isOptionalArg: => Boolean, // can have only 0 or 1 occurrence
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 f63e466..646ccae 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
@@ -29,6 +29,7 @@ import org.apache.daffodil.processors.ElementRuntimeData
 import org.apache.daffodil.processors.Processor
 import org.apache.daffodil.processors.Success
 import org.apache.daffodil.processors.TermRuntimeData
+import org.apache.daffodil.processors.ModelGroupRuntimeData
 
 abstract class ElementParserBase(
   rd: TermRuntimeData,
@@ -244,6 +245,8 @@ class ElementParser(
 
   def parseBegin(pstate: PState): Unit = {
     val currentElement = Infoset.newElement(erd).asInstanceOf[DIElement]
+    if (pstate.withinHiddenNest)
+      currentElement.setHidden()
 
     log(LogLevel.Debug, "currentElement = %s", currentElement)
     val priorElement = pstate.infoset
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/HiddenGroupCombinatorParser.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/HiddenGroupCombinatorParser.scala
new file mode 100644
index 0000000..5566531
--- /dev/null
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/HiddenGroupCombinatorParser.scala
@@ -0,0 +1,45 @@
+/*
+ * 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
+
+/**
+ * The purpose of this combinator is to increment/decrement the depth counter
+ * for hidden groups, call the group's parser. As we get deeper into the
+ * hiddenGroupRefs, we'll increment the counter, call the group's parser, and 
as
+ * we unwind from the refs, we'll decrement.
+ */
+class HiddenGroupCombinatorParser(
+  ctxt: ModelGroupRuntimeData, bodyParser: Parser)
+  extends CombinatorParser(ctxt) {
+
+  override lazy val childProcessors = Vector(bodyParser)
+
+  override lazy val runtimeDependencies = Vector()
+
+  def parse(start: PState): Unit = {
+    try {
+      start.incrementHiddenDef
+      // parse
+      bodyParser.parse1(start)
+    } finally {
+      start.decrementHiddenDef
+    }
+  }
+}
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PState.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PState.scala
index 1e8f6b6..463b8d2 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PState.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/PState.scala
@@ -215,7 +215,8 @@ final class PState private (
 
   override def toString() = {
     // threadCheck()
-    "PState( bitPos=%s status=%s )".format(bitPos0b, processorStatus)
+    val hidden = if (withinHiddenNest) "hidden " else ""
+    "PState( bitPos=%s status=%s %s)".format(bitPos0b, processorStatus, hidden)
   }
 
   def currentLocation: DataLocation = {
@@ -360,6 +361,7 @@ final class PState private (
     try {
       if (optThrown.isEmpty) {
         Assert.invariant(this.discriminatorStack.length == 1)
+        Assert.invariant(!this.withinHiddenNest) //ensure we are not in hidden 
nest
         mpstate.verifyFinalState()
       }
       // These we check regardless of throw or not.
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/Parser.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/Parser.scala
index 5f5d86a..978015b 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/Parser.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/parsers/Parser.scala
@@ -42,6 +42,7 @@ import org.apache.daffodil.processors.CombinatorProcessor
 import org.apache.daffodil.processors.PrimProcessor
 import org.apache.daffodil.processors.TextProcessor
 import org.apache.daffodil.processors.PrimProcessorNoData
+import org.apache.daffodil.processors.ModelGroupRuntimeData
 
 /**
  * Encapsulates lower-level parsing with a uniform interface
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/unparsers/UState.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/unparsers/UState.scala
index adf52e3..d45e08b 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/unparsers/UState.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/processors/unparsers/UState.scala
@@ -423,6 +423,10 @@ final class UStateForSuspension(
 
   override def documentElement = mainUState.documentElement
 
+  override def incrementHiddenDef = Assert.usageError("Unparser suspended 
UStates need not be aware of hidden contexts")
+  override def decrementHiddenDef = Assert.usageError("Unparser suspended 
UStates need not be aware of hidden contexts")
+  override def withinHiddenNest = Assert.usageError("Unparser suspended 
UStates need not be aware of hidden contexts")
+
 }
 
 final class UStateMain private (
@@ -649,6 +653,12 @@ final class UStateMain private (
   }
 
   final override def documentElement = inputter.documentElement
+
+  override def toString = {
+    val elt = if (this.currentInfosetNodeMaybe.isDefined) "node=" + 
this.currentInfosetNode.toString else ""
+    val hidden = if (withinHiddenNest) " hidden" else ""
+    "UState(" + elt +  hidden + " DOS=" + dataOutputStream.toString() + ")"
+  }
 }
 
 class SuspensionDeadlockException(suspExprs: Seq[Suspension])
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/HiddenSequences.tdml
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/HiddenSequences.tdml
new file mode 100644
index 0000000..ae2d344
--- /dev/null
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/HiddenSequences.tdml
@@ -0,0 +1,285 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<tdml:testSuite xmlns: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:daf="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:ext"
+  xmlns:fn="http://www.w3.org/2005/xpath-functions"; defaultRoundTrip="none">
+
+  <tdml:parserTestCase name="parseHiddenGroupRef" root="e1"
+    model="SequencesWithHiddenRefs.dfdl.xsd"
+    description="hidden group ref">
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[2,3]]></tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <e1>
+          <g>3</g>
+        </e1>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="parseRegularGroupRef" root="e2"
+    model="SequencesWithHiddenRefs.dfdl.xsd"
+    description="hidden group ref">
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[2,3]]></tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <e2>
+          <f>2</f>
+          <g>3</g>
+        </e2>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="parseSeqOfHiddenAndRegularRef" root="e3"
+    model="SequencesWithHiddenRefs.dfdl.xsd"
+    description="hidden group ref">
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[2,3]]></tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <e3>
+          <g>
+            <f>3</f>
+          </g>
+        </e3>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="parseNestedHiddenAndRegularRef" root="e4"
+    model="SequencesWithHiddenRefs.dfdl.xsd"
+    description="hidden group ref">
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[6~9]]></tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <e4>
+          <f>
+            <h>
+              <f>9</f>
+            </h>
+          </f>
+        </e4>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="parseNestedRegularAndHiddenRef" root="e5"
+    model="SequencesWithHiddenRefs.dfdl.xsd"
+    description="hidden group ref">
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[6~9]]></tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <e5>
+          <f>
+            <h>
+              <f>6</f>
+            </h>
+          </f>
+        </e5>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="parseNestedHiddenGroupRefs" root="e6"
+    model="SequencesWithHiddenRefs.dfdl.xsd"
+    description="hidden group ref">
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[6~9]]></tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <e6>
+          <q>
+            <h />
+          </q>
+        </e6>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:unparserTestCase name="unparseHiddenGroupRef" root="e1"
+    model="SequencesWithHiddenRefs.dfdl.xsd"
+    description="hidden group ref">
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:e1>
+          <g>7</g>
+        </ex:e1>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[1,7]]></tdml:documentPart>
+    </tdml:document>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="unparseRegularGroupRef" root="e2"
+    model="SequencesWithHiddenRefs.dfdl.xsd"
+    description="hidden group ref">
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:e2>
+          <f>17</f>
+          <g>12</g>
+        </ex:e2>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[1,12]]></tdml:documentPart>
+    </tdml:document>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="unparseSeqOfHiddenAndRegularRef" root="e3"
+    model="SequencesWithHiddenRefs.dfdl.xsd"
+    description="hidden group ref">
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:e3>
+          <g>
+            <f>3</f>
+          </g>
+        </ex:e3>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[1,1]]></tdml:documentPart>
+    </tdml:document>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="unparseNestedHiddenAndRegularRef" root="e4"
+    model="SequencesWithHiddenRefs.dfdl.xsd"
+    description="hidden group ref">
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:e4>
+          <f>
+            <h>
+              <f>9</f>
+            </h>
+          </f>
+        </ex:e4>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[1~1]]></tdml:documentPart>
+    </tdml:document>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="unparseNestedRegularAndHiddenRef" root="e5"
+    model="SequencesWithHiddenRefs.dfdl.xsd"
+    description="hidden group ref">
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:e5>
+          <f>
+            <h>
+              <f>9</f>
+            </h>
+          </f>
+        </ex:e5>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[1~1]]></tdml:documentPart>
+    </tdml:document>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="unparseNestedHiddenGroupRefs" root="e6"
+    model="SequencesWithHiddenRefs.dfdl.xsd"
+    description="hidden group ref">
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:e6>
+          <q>
+            <h />
+          </q>
+        </ex:e6>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[1~1]]></tdml:documentPart>
+    </tdml:document>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="noOVCinHiddenContext" root="e7"
+    model="SequencesWithHiddenRefs.dfdl.xsd" description="hidden group ref">
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:e7 />
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:errors>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>hidden group</tdml:error>
+      <tdml:error>defaultable</tdml:error>
+      <tdml:error>dfdl:outputValueCalc</tdml:error>
+      <tdml:error>optional</tdml:error>
+    </tdml:errors>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="nestedNoOVCinHiddenContext" root="e8"
+    model="SequencesWithHiddenRefs.dfdl.xsd" description="hidden group ref">
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:e8>
+          <g>7</g>
+        </ex:e8>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:errors>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>hidden group</tdml:error>
+      <tdml:error>defaultable</tdml:error>
+      <tdml:error>dfdl:outputValueCalc</tdml:error>
+      <tdml:error>optional</tdml:error>
+    </tdml:errors>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="ignoredHiddenGroupRefWithNoSequenceParent" 
root="e9"
+    model="SequencesWithHiddenRefs.dfdl.xsd"
+    description="the hiddenGroupRef is not wrapped in a sequence and is 
ignored by daffodil">
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:e9>
+          <g>7</g>
+        </ex:e9>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:warnings>
+      <tdml:warning>Schema Definition Warning</tdml:warning>
+      <tdml:warning>DFDL property was ignored: hiddenGroupRef</tdml:warning>
+    </tdml:warnings>
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[7]]></tdml:documentPart>
+    </tdml:document>
+  </tdml:unparserTestCase>
+
+</tdml:testSuite>
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 05805ba..3e6b4e7 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
@@ -1406,9 +1406,10 @@
       <tdml:documentPart type="text"><![CDATA[145,2]]></tdml:documentPart>
     </tdml:document>
     <tdml:errors>
-      <tdml:error>choice</tdml:error>
-      <tdml:error>hidden group</tdml:error>
-      <tdml:error>outputValueCalc</tdml:error>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>hidden choice</tdml:error>
+      <tdml:error>defaultable</tdml:error>
+      <tdml:error>dfdl:outputValueCalc</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequencesWithHiddenRefs.dfdl.xsd
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequencesWithHiddenRefs.dfdl.xsd
new file mode 100644
index 0000000..3b43fd3
--- /dev/null
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section14/sequence_groups/SequencesWithHiddenRefs.dfdl.xsd
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema";
+  xmlns:fn="http://www.w3.org/2005/xpath-functions";
+  xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/"; xmlns:ex="http://example.com";
+  targetNamespace="http://example.com"; elementFormDefault="unqualified">
+  <xs:include
+    schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd" />
+  <xs:annotation>
+    <xs:appinfo source="http://www.ogf.org/dfdl/";>
+      <dfdl:format ref="ex:GeneralFormat" lengthKind="delimited" />
+    </xs:appinfo>
+  </xs:annotation>
+  <xs:group name="s1">
+    <xs:sequence>
+      <xs:element name="f" type="xs:int" dfdl:outputValueCalc="{ 1 }" />
+    </xs:sequence>
+  </xs:group>
+  <xs:element name="e1" dfdl:lengthKind="delimited">
+    <xs:complexType>
+      <xs:sequence dfdl:separator=",">
+        <xs:sequence dfdl:hiddenGroupRef="ex:s1" />
+        <xs:element name="g" type="xs:int" />
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="e2" dfdl:lengthKind="delimited">
+    <xs:complexType>
+      <xs:sequence dfdl:separator=",">
+        <xs:group ref="ex:s1" />
+        <xs:element name="g" type="xs:int" />
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="e3" dfdl:lengthKind="delimited">
+    <xs:complexType>
+      <xs:sequence dfdl:separator=",">
+        <xs:sequence dfdl:hiddenGroupRef="ex:s1" />
+        <xs:element name="g">
+          <xs:complexType>
+            <xs:group ref="ex:s1" />
+          </xs:complexType>
+        </xs:element>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:group name="s2">
+    <xs:sequence>
+      <xs:element name="f">
+        <xs:complexType>
+          <xs:sequence>
+            <xs:element name="h">
+              <xs:complexType>
+                <xs:group ref="ex:s1" />
+              </xs:complexType>
+            </xs:element>
+          </xs:sequence>
+        </xs:complexType>
+      </xs:element>
+    </xs:sequence>
+  </xs:group>
+  <xs:group name="s3">
+    <xs:sequence>
+      <xs:element name="q">
+        <xs:complexType>
+          <xs:sequence>
+            <xs:element name="h">
+              <xs:complexType>
+                <xs:sequence dfdl:hiddenGroupRef="ex:s1" />
+              </xs:complexType>
+            </xs:element>
+          </xs:sequence>
+        </xs:complexType>
+      </xs:element>
+    </xs:sequence>
+  </xs:group>
+  <xs:element name="e4" dfdl:lengthKind="delimited">
+    <xs:complexType>
+      <xs:sequence dfdl:separator="~">
+        <xs:sequence dfdl:hiddenGroupRef="ex:s2" />
+        <xs:group ref="ex:s2" />
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="e5" dfdl:lengthKind="delimited">
+    <xs:complexType>
+      <xs:sequence dfdl:separator="~">
+        <xs:group ref="ex:s2" />
+        <xs:sequence dfdl:hiddenGroupRef="ex:s2" />
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="e6" dfdl:lengthKind="delimited">
+    <xs:complexType>
+      <xs:sequence dfdl:separator="~">
+        <xs:group ref="ex:s3" />
+        <xs:sequence dfdl:hiddenGroupRef="ex:s3" />
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:group name="s4">
+    <xs:sequence>
+      <xs:element name="f" type="xs:int" />
+    </xs:sequence>
+  </xs:group>
+  <xs:group name="s5">
+    <xs:sequence>
+      <xs:sequence dfdl:hiddenGroupRef="ex:s4" />
+    </xs:sequence>
+  </xs:group>
+  <xs:group name="s6">
+    <xs:sequence dfdl:hiddenGroupRef="ex:s4" />
+  </xs:group>
+  <xs:element name="e7" dfdl:lengthKind="delimited">
+    <xs:complexType>
+      <xs:sequence dfdl:separator=",">
+        <xs:sequence dfdl:hiddenGroupRef="ex:s4" />
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="e8" dfdl:lengthKind="delimited">
+    <xs:complexType>
+      <xs:sequence dfdl:separator=",">
+        <xs:sequence dfdl:hiddenGroupRef="ex:s5" />
+        <xs:element name="g" type="xs:int"/>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="e9" dfdl:lengthKind="delimited">
+    <xs:complexType>
+      <xs:sequence dfdl:separator=",">
+        <xs:sequence dfdl:hiddenGroupRef="ex:s6" />
+        <xs:element name="g" type="xs:int"/>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+</xs:schema>
\ No newline at end of file
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/ChoicesInHiddenContexts.dfdl.xsd
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/ChoicesInHiddenContexts.dfdl.xsd
new file mode 100644
index 0000000..1fe0c0f
--- /dev/null
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/ChoicesInHiddenContexts.dfdl.xsd
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema";
+  xmlns:fn="http://www.w3.org/2005/xpath-functions";
+  xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/"; xmlns:ex="http://example.com";
+  targetNamespace="http://example.com"; elementFormDefault="unqualified">
+  <xs:include
+    schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd" />
+  <xs:annotation>
+    <xs:appinfo source="http://www.ogf.org/dfdl/";>
+      <dfdl:format ref="ex:GeneralFormat" lengthKind="delimited" />
+    </xs:appinfo>
+  </xs:annotation>
+  <xs:group name="c1">
+    <xs:choice>
+      <xs:element name="e" type="xs:string" dfdl:initiator="["
+        dfdl:outputValueCalc="{ 'hello' }" />
+      <xs:element name="f" type="xs:int" dfdl:outputValueCalc="{ 1 }" />
+    </xs:choice>
+  </xs:group>
+  <xs:group name="c3">
+    <xs:choice>
+      <xs:element name="e" type="xs:string" dfdl:initiator="[" />
+      <xs:element name="f" type="xs:int" />
+    </xs:choice>
+  </xs:group>
+  <xs:element name="e1" dfdl:lengthKind="delimited">
+    <xs:complexType>
+      <xs:sequence dfdl:separator=",">
+        <xs:sequence dfdl:hiddenGroupRef="ex:c1" />
+        <xs:element name="g" type="xs:int" />
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="e2" dfdl:lengthKind="delimited">
+    <xs:complexType>
+      <xs:sequence dfdl:separator=",">
+        <xs:group ref="ex:c1" />
+        <xs:element name="g" type="xs:int" />
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="e3" dfdl:lengthKind="delimited">
+    <xs:complexType>
+      <xs:sequence dfdl:separator=",">
+        <xs:sequence dfdl:hiddenGroupRef="ex:c1" />
+        <xs:element name="g">
+          <xs:complexType>
+            <xs:group ref="ex:c1" />
+          </xs:complexType>
+        </xs:element>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:group name="c2">
+    <xs:choice>
+      <xs:element name="f" dfdl:initiator="[">
+        <xs:complexType>
+          <xs:choice>
+            <xs:element name="i" type="xs:int" dfdl:initiator="["
+              dfdl:outputValueCalc="{ 1 }" />
+            <xs:element name="h">
+              <xs:complexType>
+                <xs:group ref="ex:c1" />
+              </xs:complexType>
+            </xs:element>
+          </xs:choice>
+        </xs:complexType>
+      </xs:element>
+      <xs:element name="g" dfdl:initiator="]">
+        <xs:complexType>
+          <xs:choice>
+            <xs:element name="i" dfdl:initiator="]" type="xs:string"
+              dfdl:outputValueCalc="{ 'hello' }" />
+            <xs:element name="h">
+              <xs:complexType>
+                <xs:group ref="ex:c1" />
+              </xs:complexType>
+            </xs:element>
+          </xs:choice>
+        </xs:complexType>
+      </xs:element>
+    </xs:choice>
+  </xs:group>
+  <xs:group name="c4">
+    <xs:choice>
+      <xs:element name="f" dfdl:initiator="[">
+        <xs:complexType>
+          <xs:choice>
+            <xs:element name="i" type="xs:int" dfdl:initiator="["
+              dfdl:outputValueCalc="{ 1 }" />
+            <xs:element name="h">
+              <xs:complexType>
+                <xs:sequence dfdl:hiddenGroupRef="ex:c1" />
+              </xs:complexType>
+            </xs:element>
+          </xs:choice>
+        </xs:complexType>
+      </xs:element>
+      <xs:element name="g" dfdl:initiator="]">
+        <xs:complexType>
+          <xs:choice>
+            <xs:element name="i" dfdl:initiator="]" type="xs:string"
+              dfdl:outputValueCalc="{ 'hello' }" />
+            <xs:element name="h">
+              <xs:complexType>
+                <xs:sequence dfdl:hiddenGroupRef="ex:c1" />
+              </xs:complexType>
+            </xs:element>
+          </xs:choice>
+        </xs:complexType>
+      </xs:element>
+    </xs:choice>
+  </xs:group>
+  <xs:element name="e4" dfdl:lengthKind="delimited">
+    <xs:complexType>
+      <xs:sequence dfdl:separator="~">
+        <xs:sequence dfdl:hiddenGroupRef="ex:c2" />
+        <xs:group ref="ex:c2" />
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="e5" dfdl:lengthKind="delimited">
+    <xs:complexType>
+      <xs:sequence dfdl:separator="~">
+        <xs:group ref="ex:c2" />
+        <xs:sequence dfdl:hiddenGroupRef="ex:c2" />
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="e6" dfdl:lengthKind="delimited">
+    <xs:complexType>
+      <xs:sequence dfdl:separator=",">
+        <xs:sequence dfdl:hiddenGroupRef="ex:c3" />
+        <xs:element name="g" type="xs:int" />
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="e7" dfdl:lengthKind="delimited">
+    <xs:complexType>
+      <xs:sequence dfdl:separator=",">
+        <xs:element name="a" type="xs:int" />
+        <xs:element name="h">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element name="g">
+                <xs:complexType>
+                  <xs:sequence dfdl:hiddenGroupRef="ex:c3" />
+                </xs:complexType>
+              </xs:element>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="e8" dfdl:lengthKind="delimited">
+    <xs:complexType>
+      <xs:sequence dfdl:separator=",">
+        <xs:element name="a" type="xs:int" />
+        <xs:element name="h">
+          <xs:complexType>
+            <xs:sequence>
+              <xs:element name="g">
+                <xs:complexType>
+                  <xs:sequence dfdl:hiddenGroupRef="ex:c1" />
+                </xs:complexType>
+              </xs:element>
+            </xs:sequence>
+          </xs:complexType>
+        </xs:element>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="e9" dfdl:lengthKind="delimited">
+    <xs:complexType>
+      <xs:sequence dfdl:separator="~">
+        <xs:sequence dfdl:hiddenGroupRef="ex:c4" />
+        <xs:group ref="ex:c4" />
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+</xs:schema>
\ No newline at end of file
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/HiddenChoices.tdml
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/HiddenChoices.tdml
new file mode 100644
index 0000000..e4094ac
--- /dev/null
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section15/choice_groups/HiddenChoices.tdml
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<tdml:testSuite xmlns: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:daf="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:ext"
+  xmlns:fn="http://www.w3.org/2005/xpath-functions"; defaultRoundTrip="none">
+
+  <tdml:parserTestCase name="parseHiddenGroupRef" root="e1"
+    model="ChoicesInHiddenContexts.dfdl.xsd" description="hidden group ref">
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[[string,3]]></tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <e1>
+          <g>3</g>
+        </e1>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="parseRegularGroupRef" root="e2"
+    model="ChoicesInHiddenContexts.dfdl.xsd" description="hidden group ref">
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[[string,3]]></tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <e2>
+          <e>string</e>
+          <g>3</g>
+        </e2>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="parseSeqOfHiddenAndRegularRef" root="e3"
+    model="ChoicesInHiddenContexts.dfdl.xsd" description="hidden group ref">
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[2,3]]></tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <e3>
+          <g>
+            <f>3</f>
+          </g>
+        </e3>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="parseNestedHiddenAndRegularRef" root="e4"
+    model="ChoicesInHiddenContexts.dfdl.xsd" description="hidden group ref">
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[[6~]9]]></tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <e4>
+          <g>
+            <h>
+              <f>9</f>
+            </h>
+          </g>
+        </e4>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:parserTestCase name="parseNestedHiddenGroupRefs" root="e9"
+    model="ChoicesInHiddenContexts.dfdl.xsd" description="hidden group ref">
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[[6~]9]]></tdml:documentPart>
+    </tdml:document>
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <e9>
+          <g>
+            <h />
+          </g>
+        </e9>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+  </tdml:parserTestCase>
+
+  <tdml:unparserTestCase name="unparseHiddenGroupRef" root="e1"
+    model="ChoicesInHiddenContexts.dfdl.xsd" description="hidden group ref">
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:e1>
+          <g>3</g>
+        </ex:e1>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[[hello,3]]></tdml:documentPart>
+    </tdml:document>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="unparseRegularGroupRef" root="e2"
+    model="ChoicesInHiddenContexts.dfdl.xsd" description="hidden group ref">
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:e2>
+          <f>4</f>
+          <g>3</g>
+        </ex:e2>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[1,3]]></tdml:documentPart>
+    </tdml:document>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="unparseSeqOfHiddenAndRegularRef" root="e3"
+    model="ChoicesInHiddenContexts.dfdl.xsd" description="hidden group ref">
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:e3>
+          <g>
+            <e>testing</e>
+          </g>
+        </ex:e3>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:document>
+      <tdml:documentPart 
type="text"><![CDATA[[hello,[hello]]></tdml:documentPart>
+    </tdml:document>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="unparseNestedHiddenAndRegularRef" root="e4"
+    model="ChoicesInHiddenContexts.dfdl.xsd" description="hidden group ref">
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:e4>
+          <g>
+            <h>
+              <f>3</f>
+            </h>
+          </g>
+        </ex:e4>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[[[1~]1]]></tdml:documentPart>
+    </tdml:document>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="unparseNestedRegularAndHiddenRef"
+    model="ChoicesInHiddenContexts.dfdl.xsd" description="hidden group ref">
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:e5>
+          <g>
+            <h>
+              <f>3</f>
+            </h>
+          </g>
+        </ex:e5>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:document>
+      <tdml:documentPart type="text"><![CDATA[]1~[[1]]></tdml:documentPart>
+    </tdml:document>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="unparseNestedHiddenGroupRefs"
+    model="ChoicesInHiddenContexts.dfdl.xsd" description="hidden group ref">
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:e9>
+          <g>
+            <h />
+          </g>
+        </ex:e9>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:document>
+      <tdml:documentPart 
type="text"><![CDATA[[[1~][hello]]></tdml:documentPart>
+    </tdml:document>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="noOVCinHiddenContext" root="e6"
+    model="ChoicesInHiddenContexts.dfdl.xsd" description="hidden group ref">
+    <tdml:infoset>
+      <tdml:dfdlInfoset>
+        <ex:e6/>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:errors>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>hidden choice</tdml:error>
+      <tdml:error>defaultable</tdml:error>
+      <tdml:error>dfdl:outputValueCalc</tdml:error>
+    </tdml:errors>
+  </tdml:unparserTestCase>
+
+  <tdml:unparserTestCase name="nestedNoOVCinHiddenContext" root="e7"
+    model="ChoicesInHiddenContexts.dfdl.xsd" description="hidden group ref">
+    <tdml:infoset>
+      <tdml:dfdlInfoset>)
+        <ex:e7/>
+      </tdml:dfdlInfoset>
+    </tdml:infoset>
+    <tdml:errors>
+      <tdml:error>Schema Definition Error</tdml:error>
+      <tdml:error>hidden choice</tdml:error>
+      <tdml:error>defaultable</tdml:error>
+      <tdml:error>dfdl:outputValueCalc</tdml:error>
+    </tdml:errors>
+  </tdml:unparserTestCase>
+
+</tdml:testSuite>
diff --git 
a/daffodil-test/src/test/scala/org/apache/daffodil/section14/sequence_groups/TestHiddenSequences.scala
 
b/daffodil-test/src/test/scala/org/apache/daffodil/section14/sequence_groups/TestHiddenSequences.scala
new file mode 100644
index 0000000..9903dcf
--- /dev/null
+++ 
b/daffodil-test/src/test/scala/org/apache/daffodil/section14/sequence_groups/TestHiddenSequences.scala
@@ -0,0 +1,63 @@
+/*
+ * 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.section14.sequence_groups
+
+import org.junit.Test
+import org.apache.daffodil.tdml.Runner
+import org.junit.AfterClass
+
+object TestHiddenSequences {
+
+  val testDir = "/org/apache/daffodil/section14/sequence_groups/"
+
+  val runner = Runner(testDir, "HiddenSequences.tdml", validateTDMLFile = true)
+
+  @AfterClass def shutDown {
+    runner.reset
+  }
+
+}
+
+class TestHiddenSequences {
+
+  import TestHiddenSequences._
+
+
+  @Test def test_parseHiddenGroupRef() { 
runner.runOneTest("parseHiddenGroupRef") }
+  @Test def test_parseRegularGroupRef() { 
runner.runOneTest("parseRegularGroupRef") }
+  @Test def test_parseSeqOfHiddenAndRegularRef() { 
runner.runOneTest("parseSeqOfHiddenAndRegularRef") }
+  @Test def test_parseNestedHiddenAndRegularRef() { 
runner.runOneTest("parseNestedHiddenAndRegularRef") }
+  @Test def test_parseNestedRegularAndHiddenRef() { 
runner.runOneTest("parseNestedRegularAndHiddenRef") }
+  @Test def test_parseNestedHiddenGroupRefs() { 
runner.runOneTest("parseNestedHiddenGroupRefs") }
+
+  @Test def test_unparseHiddenGroupRef() { 
runner.runOneTest("unparseHiddenGroupRef") }
+  @Test def test_unparseRegularGroupRef() { 
runner.runOneTest("unparseRegularGroupRef") }
+  @Test def test_unparseSeqOfHiddenAndRegularRef() { 
runner.runOneTest("unparseSeqOfHiddenAndRegularRef") }
+  @Test def test_unparseNestedHiddenAndRegularRef() { 
runner.runOneTest("unparseNestedHiddenAndRegularRef") }
+  @Test def test_unparseNestedRegularAndHiddenRef() { 
runner.runOneTest("unparseNestedRegularAndHiddenRef") }
+  @Test def test_unparseNestedHiddenGroupRefs() { 
runner.runOneTest("unparseNestedHiddenGroupRefs") }
+  @Test def test_noOVCinHiddenContext() { 
runner.runOneTest("noOVCinHiddenContext") }
+  @Test def test_nestedNoOVCinHiddenContext() { 
runner.runOneTest("nestedNoOVCinHiddenContext") }
+
+  /*
+   * FIXME DAFFODIL-2304; Dropped hiddenGroupRef
+   * This will fail once fixed, as no warrning will be generated and the 
output data will changed
+   */
+  @Test def test_ignoredHiddenGroupRefWithNoSequenceParent() { 
runner.runOneTest("ignoredHiddenGroupRefWithNoSequenceParent") }
+
+}
diff --git 
a/daffodil-test/src/test/scala/org/apache/daffodil/section15/choice_groups/TestHiddenChoices.scala
 
b/daffodil-test/src/test/scala/org/apache/daffodil/section15/choice_groups/TestHiddenChoices.scala
new file mode 100644
index 0000000..51c0e69
--- /dev/null
+++ 
b/daffodil-test/src/test/scala/org/apache/daffodil/section15/choice_groups/TestHiddenChoices.scala
@@ -0,0 +1,56 @@
+/*
+ * 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.section15.choice_groups
+
+import org.junit.Test
+import org.apache.daffodil.tdml.Runner
+import org.junit.AfterClass
+
+object TestHiddenChoices {
+
+  val testDir = "/org/apache/daffodil/section15/choice_groups/"
+
+  val runner = Runner(testDir, "HiddenChoices.tdml", validateTDMLFile = true)
+
+  @AfterClass def shutDown {
+    runner.reset
+  }
+
+}
+
+class TestHiddenChoices {
+
+  import TestHiddenChoices._
+
+
+  @Test def test_parseHiddenGroupRef() { 
runner.runOneTest("parseHiddenGroupRef") }
+  @Test def test_parseRegularGroupRef() { 
runner.runOneTest("parseRegularGroupRef") }
+  @Test def test_parseSeqOfHiddenAndRegularRef() { 
runner.runOneTest("parseSeqOfHiddenAndRegularRef") }
+  @Test def test_parseNestedHiddenAndRegularRef() { 
runner.runOneTest("parseNestedHiddenAndRegularRef") }
+  @Test def test_parseNestedHiddenGroupRefs() { 
runner.runOneTest("parseNestedHiddenGroupRefs") }
+
+  @Test def test_unparseHiddenGroupRef() { 
runner.runOneTest("unparseHiddenGroupRef") }
+  @Test def test_unparseRegularGroupRef() { 
runner.runOneTest("unparseRegularGroupRef") }
+  @Test def test_unparseSeqOfHiddenAndRegularRef() { 
runner.runOneTest("unparseSeqOfHiddenAndRegularRef") }
+  @Test def test_unparseNestedHiddenAndRegularRef() { 
runner.runOneTest("unparseNestedHiddenAndRegularRef") }
+  @Test def test_unparseNestedRegularAndHiddenRef() { 
runner.runOneTest("unparseNestedRegularAndHiddenRef") }
+  @Test def test_unparseNestedHiddenGroupRefs() { 
runner.runOneTest("unparseNestedHiddenGroupRefs") }
+  @Test def test_noOVCinHiddenContext() { 
runner.runOneTest("noOVCinHiddenContext") }
+  @Test def test_nestedNoOVCinHiddenContext() { 
runner.runOneTest("nestedNoOVCinHiddenContext") }
+
+}

Reply via email to