def validateElementSequence(modelXbrl, compositor, children, ixFacts, iNextChild=0):
    particles = compositor.dereference().particles        
    iStartingChild = iNextChild
    errDesc = None
    if isinstance(compositor, ModelAll):
        allParticles = set() # elements required
        iNextAfterAll = iStartingChild
    elif isinstance(compositor, ModelChoice):
        anyChoiceHasMinOccurs0 = False
    moreParticlesPasses = True
    while moreParticlesPasses:
        moreParticlesPasses = False
        for particle in particles:
            occurrences = 0
            if isinstance(particle, (ModelConcept, ModelAny)):
                elementDeclaration = particle.dereference()
                while iNextChild < len(children):
                    elt = children[iNextChild]
                    # children now only contains ModelObjects, no comments or other lxml elements
                    vQname = elt.vQname(modelXbrl) # takes care of elements inside inline or other instances
                    # for any, check namespace overlap
                    if ((isinstance(particle, ModelAny) and 
                         particle.allowsNamespace(vQname.namespaceURI)) or 
                        (isinstance(particle, ModelConcept) and
                         elementDeclaration is not None and 
                         (vQname == elementDeclaration.qname or
                          (vQname in modelXbrl.qnameConcepts and  
                           modelXbrl.qnameConcepts[vQname].substitutesForQname(elementDeclaration.qname))))):
                        occurrences += 1
                        validate(modelXbrl, elt, ixFacts=ixFacts)
                        iNextChild += 1
                        if occurrences == particle.maxOccurs:
                            break
                    elif not isinstance(particle, ModelAll):
                        break # done with this element
            else:  # group definition or compositor
                while occurrences < particle.maxOccurs:
                    iPrevChild = iNextChild
                    iNextChild, occurred, errDesc, errArgs = validateElementSequence(modelXbrl, particle, children, ixFacts, iNextChild)
                    if occurred:
                        # test if occurrence was because of minOccurs zero but no match occurred (HF 2012-09-07)
                        if occurred and iNextChild == iPrevChild and particle.minOccurs == 0: # nothing really occurred
                            break
                        occurrences += 1
                        if occurrences == particle.maxOccurs or iNextChild >= len(children):
                            break
                    else:
                        break
            if isinstance(compositor, ModelChoice):
                if occurrences > 0 and particle.minOccurs <= occurrences <= particle.maxOccurs:
                    return (iNextChild, True, None, None)  # choice has been selected
                else: # otherwise start again on next choice
                    if particle.minOccurs == 0:
                        anyChoiceHasMinOccurs0 = True
                    iNextChild = iStartingChild
            elif isinstance(compositor, ModelAll):
                if particle.minOccurs <= occurrences <= particle.maxOccurs:
                    allParticles.add(particle)  # particle found
                    moreParticlesPasses = True
                    break # advance to next all particle
            elif particle.minOccurs > 0 and errDesc:
                return (iNextChild, False, errDesc, errArgs)
            elif not particle.minOccurs <= occurrences <= particle.maxOccurs:
                return (iNextChild, False,
                        ("xmlSchema:elementOccurrencesError", 
                         _("%(compositor)s(%(particles)s) %(element)s occurred %(occurrences)s times, minOccurs=%(minOccurs)s, maxOccurs=%(maxOccurs)s, within %(parentElement)s")
                        if occurrences > 0 else
                         _("%(compositor)s(%(particles)s) content occurred %(occurrences)s times, minOccurs=%(minOccurs)s, maxOccurs=%(maxOccurs)s, within %(parentElement)s")
                         ),
                        dict(compositor=compositor, particles=particles, occurrences=occurrences, minOccurs=particle.minOccursStr, maxOccurs=particle.maxOccursStr))
    if isinstance(compositor, ModelAll):
        missingParticles = set(particles) - allParticles
        if missingParticles:
            return (iNextChild, False,
                    ("xmlSchema:missingParticlesError",
                     _("All(%(particles)s) missing at %(element)s, within %(parentElement)s")),
                    dict(particles=particles))
        occurred = True
    elif isinstance(compositor, ModelChoice):
        occurred = anyChoiceHasMinOccurs0 # deemed to have occurred if any choice had minoccurs=0
    else:
        occurred = True
    if isinstance(compositor, ModelType) and iNextChild < len(children):
        #if any(True for child in children[iNextChild:] if isinstance(child, ModelObject)): # any unexpected content elements
        if len(children) > iNextChild: # any unexpected content elements
            return (iNextChild, False,
                    ("xmlSchema:elementUnexpected",
                     _("%(compositor)s(%(particles)s) %(element)s unexpected, within %(parentElement)s")),
                    dict(compositor=compositor, particles=particles))
    return (iNextChild, occurred, None, None)
dataset/ETHPy150Open Arelle/Arelle/arelle/XmlValidateParticles.py/validateElementSequence/original