<NME> wizard.xbl
<BEF> <!--
  Copyright (C) 2012 Orbeon, Inc.

  This program is free software; you can redistribute it and/or modify it under the terms of the
  GNU Lesser General Public License as published by the Free Software Foundation; either version
  2.1 of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the GNU Lesser General Public License for more details.

  The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
  -->
<xbl:xbl
    xmlns:xh="http://www.w3.org/1999/xhtml"
    xmlns:xf="http://www.w3.org/2002/xforms"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xxf="http://orbeon.org/oxf/xml/xforms"
    xmlns:fr="http://orbeon.org/oxf/xml/form-runner"
    xmlns:xbl="http://www.w3.org/ns/xbl"
    xmlns:xxbl="http://orbeon.org/oxf/xml/xbl"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:oxf="http://www.orbeon.com/oxf/processors"
    xmlns:frf="java:org.orbeon.oxf.fr.FormRunner"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:p="http://www.orbeon.com/oxf/pipeline"
    xmlns:Wizard="java:org.orbeon.xbl.Wizard">

    <xbl:binding
        id="fr-wizard"
        element="fr|wizard"
        xxf:external-events="fr-wizard-focus">

        <xbl:resources>
            <xbl:style src="/xbl/orbeon/wizard/wizard.css"/>
        </xbl:resources>
        <xbl:handlers>

            <xbl:handler event="xxforms-refresh-done" observer="#document" xxbl:scope="outer">
                <!--
                    - `fr:error-summary` listens to events during the capture phase so that it is up to
                       date once the wizard processes them.
                -->
                <xf:dispatch name="fr-update-section-status" targetid="fr-wizard-outer-group"/>
            </xbl:handler>

            <xbl:handler event="fr-prev" phase="target">
                <!-- NOTE: The target shouldn't be in the outer scope ideally. -->
                <xf:dispatch
                    name="fr-prev-internal"
                    targetid="fr-wizard-outer-group"
                    xxbl:scope="outer"/>
            </xbl:handler>
            <xbl:handler event="fr-next" phase="target">
                <!-- NOTE: The target shouldn't be in the outer scope ideally. -->
                <xf:dispatch
                    name="fr-next-internal"
                    targetid="fr-wizard-outer-group"
                    xxbl:scope="outer"/>
            </xbl:handler>
            <xbl:handler event="fr-show-toc" phase="target">
                <xf:action if="$local/separate-toc/data(.)">
                    <xf:setvalue
                        ref="$local/show-toc"
                        value="true()"/>
                    <xf:setvalue
                        ref="$local/show-body"
                        value="false()"/>
                </xf:action>
            </xbl:handler>
            <xbl:handler event="fr-update-validity" phase="target">
                <!-- NOTE: The target shouldn't be in the outer scope ideally. -->
                <xf:dispatch
                    name="fr-wizard-update-validity"
                    targetid="fr-wizard-update-validity"
                    xxbl:scope="outer"/>
            </xbl:handler>
            <xbl:handler event="fr-visit-all fr-show-relevant-errors" phase="target">
                <!-- See https://github.com/orbeon/orbeon-forms/issues/3178 -->
                <xf:var
                    xxbl:scope="outer"
                    name="target-name"
                    value="
                        if (xxf:instance('local')/validate/data(.) = 'free') then
                            'fr-wizard-visit-all'
                        else
                            'fr-wizard-visit-all-available'
                "/>

                <!-- NOTE: The target shouldn't be in the outer scope ideally. -->
                <xf:dispatch
                    name="{$target-name}"
                    targetid="{$target-name}"
                    xxbl:scope="outer"/>

                <!-- So if the captcha is invalid, its error shows in the error summary. This is needed in addition -->
                <!-- to the event we dispatch above as the captcha isn't inside the switch, as we don't want to have -->
                <!-- one instance of the captcha per top-level section. -->
                <xxf:setvisited
                    control="fr-captcha"
                    visited="true"
                    recurse="true"/>

            </xbl:handler>
            <xbl:handler event="fr-verify" phase="target">
                <xf:dispatch name="fr-verify" targetid="fr-captcha"/>
            </xbl:handler>
            <!-- For client-side API -->
            <xbl:handler event="fr-wizard-focus" phase="target">

                <!-- TODO: Support `lax` and `strict` modes. -->
                <xf:action if="xxf:instance('local')/validate/data(.) = 'free'">

                    <xf:setfocus
                        control="{event('fr-control-name')}-control"
                        xxf:repeat-indexes="{event('fr-repeat-indexes')}"
                        xxbl:scope="outer"/>

                </xf:action>

            </xbl:handler>
            <!-- When a page/section is shown, create the associated `fr:section-status` attribute if needed -->
            <!-- NOTE: 2018-08-07: This is done only for *top-level* pages. -->
            <xbl:handler event="fr-section-shown" phase="target">

                <xf:var
                    name="section-binding"
                    value="event('section-binding')"/>

                <xf:insert
                    if="not(exists($section-binding/@fr:section-status))"
                    xxf:structural-dependencies="false"
                    context="$section-binding"
                    origin="xf:attribute('fr:section-status', '')"/>

                <!-- NOTE: No need to update the section status here, as the `xf:insert` will cause a subsequent refresh. -->

            </xbl:handler>
        </xbl:handlers>
        <xbl:implementation>
            <xf:model>
                <xf:instance id="local" xxf:expose-xpath-types="true" xxf:exclude-result-prefixes="#all">
                    <_>
                        <current-case-id/>
                        <current-top-level-case-id/>
                        <current-index/>
                        <show-toc/>
                        <show-body/>
                        <readwrite/>

                        <validate/>
                        <separate-toc/>
                        <section-status/>
                    </_>
                </xf:instance>

                <xf:var name="local" value="instance('local')"/>

                <xf:bind ref="validate"                         xxf:default="Wizard:normalizeWizardMode(fr:component-param-value('validate'))"/>
                <xf:bind ref="separate-toc"   type="xs:boolean" xxf:default="(fr:component-param-value('separate-toc'),   'false')[1]"/>
                <xf:bind ref="section-status" type="xs:boolean" xxf:default="../separate-toc/data(.) or fr:component-param-value('section-status') = 'true'"/>

                <xf:bind ref="current-index"  type="xs:integer" xxf:default="1"/>
                <xf:bind ref="show-toc"       type="xs:boolean" xxf:default="true()"/>
                <xf:bind ref="show-body"      type="xs:boolean" xxf:default="not(../separate-toc/data(.))"/>

                <xf:instance id="available-top-level-sections" xxf:expose-xpath-types="true" xxf:exclude-result-prefixes="#all">
                    <_/>
                </xf:instance>

            </xf:model>
        </xbl:implementation>
        <xbl:template xxbl:transform="oxf:unsafe-xslt">
            <xsl:transform version="2.0">
                <xsl:import href="oxf:/oxf/xslt/utils/copy-modes.xsl"/>

                <!-- `app` and `form` must be passed as attributes (see view.xsl) -->
                <xsl:variable name="static-app"             select="/*/@app/string()"/>
                <xsl:variable name="static-form"            select="/*/@form/string()"/>
                <xsl:variable name="static-validate"        select="/*/@validate/string()"/>        <!-- This is the `free|lax|strict` Form Runner validation mode. -->
                <xsl:variable name="static-validation-mode" select="/*/@validation-mode/string()"/> <!-- This is the `incremental|explicit` Form Runner validation mode. -->

                <xsl:variable
                    xmlns:p="http://www.orbeon.com/oxf/pipeline"
                    name="static-subsections-nav"
                    select="
                        (
                            for $a in /*/@subsections-nav return $a = 'true', (: takes precedence if present :)
                            p:property(string-join(('oxf.xforms.xbl.fr.wizard.subsections-nav', $static-app, $static-form), '.')) = true(),
                            false()
                        )[1]
                    "
                    as="xs:boolean"/>

                <!-- `all | active | none` -->
                <xsl:variable
                    xmlns:p="http://www.orbeon.com/oxf/pipeline"
                    name="static-subsections-toc"
                    select="
                        (
                            /*/@subsections-toc, (: takes precedence if present :)
                            p:property(string-join(('oxf.xforms.xbl.fr.wizard.subsections-toc', $static-app, $static-form), '.'))[. = ('all', 'none')],
                            'active'
                        )[1]"
                    as="xs:string"/>

                <xsl:variable
                    name="static-nav-sections-or-grids"
                    select="
                        if ($static-subsections-nav) then
                            /*//(
                                fr:section[
                                    (
                                        (: Top-level section :)
                                        count(ancestor::fr:section) = 0 and (
                                            empty(fr:section)          or
                                            @subsections-nav = 'false' or
                                            frf:isRepeat(.)
                                        )
                                    ) or (
                                        (: First-level subsection :)
                                        count(ancestor::fr:section) = 1    and
                                        not(../@subsections-nav = 'false') and
                                        not(frf:isRepeat(..))
                                    )
                                ],
                                (: Grid within a top-level section which also contains subsections
                                   and top-level section doesn't have Subsection navigation explicitly
                                   disabled and is not repeated :)
                                fr:grid[
                                    count(ancestor::fr:section) = 1    and
                                    not(../@subsections-nav = 'false') and
                                    not(frf:isRepeat(..))              and
                                    exists((preceding-sibling::fr:section | following-sibling::fr:section))
                                ]
                            )
                        else
                            (: Top-level sections :)
                            /*/fr:section
                "/>

                <!-- Make sure that duplicates are kept, see https://github.com/orbeon/orbeon-forms/issues/3516 -->
                <xsl:variable
                    name="static-matching-top-level-section-ids"
                    select="
                        for $s in $static-nav-sections-or-grids
                        return $s/ancestor-or-self::fr:section[last()]/@id/string()
                "/>

                <xsl:variable
                    name="static-nav-section-or-grid-ids"
                    select="$static-nav-sections-or-grids/((@id/string(), concat(generate-id(), '-wizard-grid'))[1])"/>

                <xsl:variable
                    name="static-top-level-section-ids"
                    select="/*/fr:section/@id/string()"/>

                <xsl:variable
                    name="static-sections-with-paging-section-ids"
                    select="/*//fr:section[@page-size = '1']/@id/string()"/>

                <xsl:variable
                    name="static-sections-with-paging-case-ids"
                    select="for $id in $static-sections-with-paging-section-ids return concat($id, '-case')"/>

                <xsl:variable
                    name="static-lazy-section-relevance"
                    select="
                        (: limited to `free` mode :)
                        $static-validate = 'free' and
                        (: enabled by property :)
                        p:property(
                            string-join(
                                ('oxf.xforms.xbl.fr.wizard.lazy-section-relevance', $static-app, $static-form),
                                '.'
                            )
                        ) = true()"/>

                <xsl:template match="/*">
                    <xf:group appearance="xxf:internal">
                        <xf:group
                            class="fr-wizard-toc{{
                                ' xforms-hidden'         [not($local/show-toc/data(.))],
                                ' fr-wizard-separate-toc'[$local/separate-toc/data(.)]
                            }}">

                            <!-- Dispatch fr-toc-shown event as needed -->
                            <xf:group appearance="xxf:internal" ref=".[$local/show-toc/data(.)]">
                                <xf:action
                                    event="xforms-enabled"
                                    target="#observer">

                                    <xf:dispatch
                                        name="fr-toc-shown"
                                        targetid="fr-wizard">
                                        <xf:property name="validate"     value="$local/validate/data(.)"/>
                                        <xf:property name="separate-toc" value="$local/separate-toc/data(.)"/>
                                    </xf:dispatch>
                                </xf:action>
                            </xf:group>

                            <xf:group
                                xxbl:scope="outer"
                                id="fr-wizard-outer-group"
                                class="fr-wizard-toc-inner"
                                xxf:element="div">

                                <!-- Statically-known section and grid ids -->
                                <xf:var
                                    name="nav-section-or-grid-ids"
                                    value="({
                                        string-join(
                                            for $id in $static-nav-section-or-grid-ids
                                                return concat('''', $id, ''''),
                                            ','
                                        )
                                    })"/>

                                <xf:var
                                    name="nav-matching-top-level-section-ids"
                                    value="({
                                        string-join(
                                            for $id in $static-matching-top-level-section-ids
                                                return concat('''', $id, ''''),
                                            ','
                                        )
                                    })"/>

                                <xf:var
                                    name="top-level-section-ids"
                                    value="({
                                        string-join(
                                            for $id in $static-top-level-section-ids
                                                return concat('''', $id, ''''),
                                            ','
                                        )
                                    })"/>

                                <xf:var
                                    name="sections-with-paging-section-ids"
                                    value="({
                                        string-join(
                                            for $id in $static-sections-with-paging-section-ids
                                                return concat('''', $id, ''''),
                                            ','
                                        )
                                    })"/>

                                <xf:var
                                    name="sections-with-paging-case-ids"
                                    value="({
                                        string-join(
                                            for $id in $static-sections-with-paging-case-ids
                                                return concat('''', $id, ''''),
                                            ','
                                        )
                                    })"/>

                                <xf:var
                                    name="validated-mode"
                                    value="xxf:instance('local')/validate/data(.) != 'free'"/>

                                <xf:var
                                    name="separate-toc-mode"
                                    value="xxf:instance('local')/separate-toc/data(.)"/>

                                <xf:var
                                    name="relevant-nav-section-or-grid-ids"
                                    value="
                                        $nav-section-or-grid-ids[
                                            for $section-or-grid-bind in bind(frf:bindId(frf:controlNameFromId(.)))
                                            return
                                                xxf:relevant($section-or-grid-bind) and (
                                                    not(
                                                        . = $sections-with-paging-section-ids and
                                                        empty($section-or-grid-bind/*)
                                                    )
                                                )
                                        ]"/>

                                <xf:var
                                    name="relevant-top-level-section-ids"
                                    value="
                                        $top-level-section-ids[
                                            for $top-level-section-bind in bind(frf:bindId(frf:controlNameFromId(.)))
                                            return
                                                xxf:relevant($top-level-section-bind)
                                        ]"/>

                                <xf:var
                                    name="relevant-nav-case-ids"
                                    value="
                                        for $section-id in $relevant-nav-section-or-grid-ids
                                        return concat($section-id, '-case')"/>

                                <xf:var
                                    name="relevant-top-level-case-ids"
                                    value="
                                        for $section-id in $relevant-top-level-section-ids
                                        return concat($section-id, '-case')"/>

                                <!-- HACK: Dependency bug, using `xf:random()` to force recalculation -->
                                <xf:var
                                    name="current-top-level-case-id"
                                    value="(xxf:instance('local')/current-top-level-case-id/string(), xf:random())[1]"/>

                                <!-- NOTE: Initially, current-case-id might be empty, so default to the first relevant case id. -->
                                <xf:var
                                    name="current-nav-case-id"
                                    value="
                                        (
                                            xxf:instance('local')/current-case-id[xxf:non-blank()]/string(),
                                            $relevant-nav-case-ids
                                        )[1]"/>

                                <xf:var
                                    name="nav-case-index"
                                    value="index-of($relevant-nav-case-ids, $current-nav-case-id)"/>

                                <xf:var
                                    name="top-level-case-index"
                                    value="index-of($relevant-top-level-case-ids, $current-top-level-case-id)"/>

                                <xf:var
                                    name="prev-nav-case-ids"
                                    value="$relevant-nav-case-ids[position() lt $nav-case-index]"/>

                                <xf:var
                                    name="next-nav-case-ids"
                                    value="$relevant-nav-case-ids[position() gt $nav-case-index]"/>

                                <xf:var
                                    name="next-top-level-case-ids"
                                    value="$relevant-top-level-case-ids[position() gt $top-level-case-index]"/>

                                <xf:var
                                    name="current-section-uses-paging"
                                    value="$current-nav-case-id = $sections-with-paging-case-ids"/>

                                <xf:var
                                    name="current-repeat-id-and-index-opt"
                                    value="
                                        if ($current-section-uses-paging) then
                                            let $section-id    := Wizard:sectionIdFromCaseIdOpt($current-nav-case-id),
                                                $repeat-id     := concat($section-id, '-repeater-repeat'),
                                                $current-index := xxf:instance('local')/current-index/data(.)
                                            return
                                                ($repeat-id, $current-index)
                                        else
                                            ()
                                    "/>

                                <xf:var
                                    name="prev-repeat-id-and-index-opt"
                                    value="
                                        if ($current-section-uses-paging) then
                                            let $section-id    := Wizard:sectionIdFromCaseIdOpt($current-nav-case-id),
                                                $repeat-id     := concat($section-id, '-repeater-repeat'),
                                                $current-index := xxf:instance('local')/current-index/data(.)
                                            return
                                                if ($current-index gt 1) then
                                                    ($repeat-id, $current-index - 1)
                                                else
                                                    ()
                                        else
                                            ()
                                    "/>

                                <xf:var
                                    name="next-repeat-id-and-index-opt"
                                    value="
                                        if ($current-section-uses-paging) then
                                            let $section-id    := Wizard:sectionIdFromCaseIdOpt($current-nav-case-id),
                                                $repeat-id     := concat($section-id, '-repeater-repeat'),
                                                $current-index := xxf:instance('local')/current-index/data(.),
                                                $section-bind  := bind(frf:bindId(frf:controlNameFromId($section-id))),
                                                $last-index    := count($section-bind/*)
                                            return
                                                if ($current-index lt $last-index) then
                                                    ($repeat-id, $current-index + 1)
                                                else
                                                    ()
                                        else
                                            ()
                                    "/>

                                <xf:var
                                    name="next-nested-case-id-opt"
                                    value="
                                        let $next-nav-case-id := $next-nav-case-ids[1]
                                        return
                                            $next-nav-case-id[
                                                Wizard:sectionIdFromCaseIdOpt($current-top-level-case-id) =
                                                    $nav-matching-top-level-section-ids[
                                                        index-of(
                                                            $nav-section-or-grid-ids,
                                                            Wizard:sectionIdFromCaseIdOpt($next-nav-case-id)
                                                        )
                                                    ]
                                            ]
                                    "/>

                                <xf:var
                                    name="next-top-level-case-id-opt"
                                    value="
                                        let $next-top-level-case-id := $next-top-level-case-ids[1]
                                        return
                                            (: Exists and is available :)
                                            $next-top-level-case-id[
                                                exists(
                                                    index-of(
                                                        xxf:split(xxf:instance('available-top-level-sections')),
                                                        frf:controlNameFromIdOpt(Wizard:sectionIdFromCaseIdOpt($next-top-level-case-id))
                                                    )
                                                )
                                            ]
                                    "/>

                                <xf:var
                                    id="fr-wizard-allow-prev"
                                    name="allow-prev"
                                    value="
                                        exists($prev-repeat-id-and-index-opt) or
                                        exists($prev-nav-case-ids)
                                    "/>

                                <xf:var
                                    id="fr-wizard-allow-next"
                                    name="allow-next"
                                    value="
                                        (: We can go to the next top-level section :)
                                        exists($next-top-level-case-id-opt) or
                                        (: We can go to the next repeated section iteration :)
                                        exists($next-repeat-id-and-index-opt) or
                                        (: Next is in the same top-level section :)
                                        exists($next-nested-case-id-opt)
                                    "/>

                                <!-- Wizard.scala uses this via the variable `id` -->
                                <xf:var
                                    id="fr-wizard-is-first-nav"
                                    name="is-first-nav"
                                    value="empty($prev-nav-case-ids)"/>

                                <!-- Wizard.scala uses this via the variable `id` -->
                                <xf:var
                                    id="fr-wizard-is-last-nav"
                                    name="is-last-nav"
                                    value="empty($next-nav-case-ids)"/>

                                <xf:var name="prev-button-ref" value="if (not($is-first-nav)) then xxf:instance('local')/readwrite else ''"/>
                                <xf:var name="next-button-ref" value="if (not($is-last-nav))  then xxf:instance('local')/readwrite else ''"/>

                                <xf:action event="fr-prev-internal">
                                    <xf:action if="$allow-prev">
                                        <xf:action if="exists($prev-repeat-id-and-index-opt)">
                                            <xf:var name="new-index" value="$prev-repeat-id-and-index-opt[2]"/>
                                            <xf:setvalue
                                                ref="xxf:instance('local')/current-index"
                                                value="$new-index"/>
                                            <xf:setindex
                                                repeat="{{$prev-repeat-id-and-index-opt[1]}}"
                                                index="$new-index"/>
                                        </xf:action>
                                        <xf:action if="empty($prev-repeat-id-and-index-opt)">
                                            <xf:var name="prev-case-id" value="$prev-nav-case-ids[last()]"/>
                                            <xf:toggle
                                                case="{{$prev-case-id}}"/>
                                            <xf:action if="$prev-case-id = $sections-with-paging-case-ids">
                                                <xf:var name="section-id" value="Wizard:sectionIdFromCaseIdOpt($prev-case-id)"/>
                                                <xf:var name="new-index" value="count(xxf:binding($section-id)/*)"/>
                                                <xf:setvalue
                                                    ref="xxf:instance('local')/current-index"
                                                    value="$new-index"/>
                                                <xf:setindex
                                                    repeat="{{concat($section-id, '-repeater-repeat')}}"
                                                    index="$new-index"/>
                                            </xf:action>
                                            <xsl:if test="p:property(string-join(('oxf.fr.detail.initial-focus', $static-app, $static-form), '.'))">
                                                <xf:setfocus
                                                    control="{{$prev-case-id}}"
                                                    includes="{{frf:xpathFormRunnerStringProperty('oxf.fr.detail.focus.includes')}}"
                                                    excludes="{{frf:xpathFormRunnerStringProperty('oxf.fr.detail.focus.excludes')}}"/>
                                            </xsl:if>
                                        </xf:action>
                                    </xf:action>
                                </xf:action>

                                <xf:action event="fr-next-internal">
                                    <xf:dispatch
                                        name="fr-wizard-update-validity"
                                        targetid="fr-wizard-update-validity"/>
                                    <xf:dispatch
                                        name="fr-wizard-visit-all-to-current"
                                        targetid="fr-wizard-visit-all-to-current"/>
                                    <xf:action if="$allow-next">
                                        <xf:action if="exists($next-repeat-id-and-index-opt)">
                                            <xf:var name="new-index" value="$next-repeat-id-and-index-opt[2]"/>
                                            <xf:setvalue
                                                ref="xxf:instance('local')/current-index"
                                                value="$new-index"/>
                                            <xf:setindex
                                                repeat="{{$next-repeat-id-and-index-opt[1]}}"
                                                index="$new-index"/>
                                        </xf:action>
                                        <xf:action if="empty($next-repeat-id-and-index-opt)">
                                            <xf:var name="next-case-id" value="$next-nav-case-ids[1]"/>
                                            <xf:toggle
                                                case="{{$next-case-id}}"/>
                                            <xf:action if="$next-case-id = $sections-with-paging-case-ids">
                                                <xf:var name="section-id" value="Wizard:sectionIdFromCaseIdOpt($next-case-id)"/>
                                                <xf:var name="new-index" value="1"/>
                                                <xf:setvalue
                                                    ref="xxf:instance('local')/current-index"
                                                    value="$new-index"/>
                                                <xf:setindex
                                                    repeat="{{concat($section-id, '-repeater-repeat')}}"
                                                    index="$new-index"/>
                                            </xf:action>
                                            <xsl:if test="p:property(string-join(('oxf.fr.detail.initial-focus', $static-app, $static-form), '.'))">
                                                <xf:setfocus
                                                    control="{{$next-case-id}}"
                                                    includes="{{frf:xpathFormRunnerStringProperty('oxf.fr.detail.focus.includes')}}"
                                                    excludes="{{frf:xpathFormRunnerStringProperty('oxf.fr.detail.focus.excludes')}}"/>
                                            </xsl:if>
                                        </xf:action>
                                    </xf:action>
                                    <xf:action if="not($allow-next)">
                                        <xsl:if test="p:property(string-join(('oxf.fr.detail.initial-focus', $static-app, $static-form), '.'))">
                                            <xf:setfocus
                                                control="{{$current-nav-case-id}}"
                                                includes="{{frf:xpathFormRunnerStringProperty('oxf.fr.detail.focus.includes')}}"
                                                excludes="{{frf:xpathFormRunnerStringProperty('oxf.fr.detail.focus.excludes')}}"/>
                                        </xsl:if>
                                    </xf:action>
                                </xf:action>

                                <!-- We put this here because we need `$relevant-top-level-section-ids` -->
                                <xf:action event="fr-update-section-status">

                                    <xf:var
                                        name="maps"
                                        value="Wizard:gatherTopLevelSectionStatusJava($relevant-top-level-section-ids)"/>

                                    <!-- Update available sections instance -->
                                    <!-- We do this because we don't want to run `Wizard:gatherSectionStatusJava` at each refresh, and we want to
                                         depend on instance values, although in practice it might not make much of a difference. -->
                                    <xf:setvalue
                                        ref="xxf:instance('available-top-level-sections')"
                                        value="
                                            string-join(
                                                for $m in $maps
                                                return
                                                    if (map:get($m, 'is-available')) then map:get($m, 'name') else (),
                                                ' '
                                            )"/>

                                    <!-- Update section statuses for all relevant sections -->
                                    <xf:action iterate="$relevant-top-level-section-ids">

                                        <xf:var
                                            name="section-binding"
                                            value="xxf:binding(.)"/>

                                        <xf:action if="exists($section-binding/@fr:section-status)">

                                            <xf:var
                                                name="map"
                                                value="
                                                    for $m in $maps
                                                    return
                                                        if (map:get($m, 'name') = name($section-binding)) then $m else ()"/>

                                            <xf:var
                                                name="existing-tokens"
                                                value="
                                                    distinct-values(
                                                        xxf:split($section-binding/@fr:section-status)
                                                    )"/>

                                            <xf:var
                                                name="new-tokens"
                                                value="
                                                    distinct-values(
                                                        (
                                                            $existing-tokens[
                                                                not(. = (
                                                                    'incomplete',
                                                                    'invalid',
                                                                    'visible-incomplete',
                                                                    'visible-invalid'
                                                                    )
                                                                )
                                                            ], (: these toggle so remove them first :)
                                                            'incomplete'        [exists($map) and map:get($map, 'has-incomplete-fields')],
                                                            'invalid'           [exists($map) and map:get($map, 'has-error-fields')],
                                                            'visible-incomplete'[exists($map) and map:get($map, 'has-visible-incomplete-fields')],
                                                            'visible-invalid'   [exists($map) and map:get($map, 'has-visible-error-fields')]
                                                        )
                                                    )"/>

                                            <xf:setvalue
                                                if="not(count($existing-tokens) = count($new-tokens) and empty($existing-tokens[not(. = $new-tokens)]))"
                                                ref="$section-binding/@fr:section-status"
                                                value="string-join($new-tokens, ' ')"/>

                                        </xf:action>
                                    </xf:action>
                                </xf:action>

                                <!-- This id is used to expose visibility to buttons outside the wizard -->
                                <xf:group
                                    id="fr-wizard-submit-hide"
                                    ref="xxf:instance('local')/readwrite[not($validated-mode) or empty($next-top-level-case-ids)]"/>

                                <xh:div role="navigation">
                                    <xh:ul class="nav nav-list">
                                        <xsl:apply-templates mode="toc-sections"/>
                                    </xh:ul>
                                </xh:div>

                                <xh:div class="fr-wizard-navigation{{if (xxf:instance('local')/separate-toc/data(.)) then ' xforms-hidden' else ''}}">

                                    <xf:action event="xforms-enabled" target="#observer">

                                        <!-- Make sure the first relevant case is shown initially -->
                                        <!-- NOTE: Ideally, we should also handle the case where the fr:section in the
                                             currently-selected case becomes non-relevant. However, this should not happen
                                             in a well-designed form (that would be very user unfriendly). If xf:case supported
                                             relevance, we might be able to let this behavior be handled by the XForms engine.
                                         -->
                                        <!-- Find the last available AND visited section -->
                                        <xf:var
                                            name="last-available-and-visited-top-level-section-id"
                                            value="
                                                (
                                                    (: First relevant section by default :)
                                                    $relevant-top-level-section-ids[1],
                                                    (: But also check subsequent sections for availability and visited :)
                                                    (
                                                        for $id in $relevant-top-level-section-ids[position() gt 1]
                                                        return
                                                            if (
                                                                exists(
                                                                    index-of(
                                                                        xxf:split(xxf:instance('available-top-level-sections')),
                                                                        frf:controlNameFromIdOpt($id)
                                                                    )
                                                                ) and
                                                                    exists(xxf:binding($id)/@fr:section-status)
                                                            ) then
                                                                $id
                                                            else
                                                                ()
                                                    )
                                                )[last()]"/>

                                        <!-- Set initial current section -->
                                        <xf:action if="exists($last-available-and-visited-top-level-section-id)">

                                            <xf:var
                                                name="last-available-and-visited-top-level-case-id"
                                                value="concat($last-available-and-visited-top-level-section-id, '-case')"/>

                                            <xf:var
                                                name="initial-case-id"
                                                value="
                                                    (
                                                        Wizard:caseIdsForTopLevelSection($last-available-and-visited-top-level-section-id)[1],
                                                        $last-available-and-visited-top-level-case-id
                                                    )[1]"/>

                                            <xf:setvalue
                                                ref="xxf:instance('local')/current-case-id"
                                                value="$initial-case-id"/>

                                            <xf:setvalue
                                                ref="xxf:instance('local')/current-top-level-case-id"
                                                value="case('switch')"/>

                                            <!-- See https://github.com/orbeon/orbeon-forms/issues/3433 -->
                                            <xf:toggle
                                                case="{{$initial-case-id}}"/>

                                            <!-- Dispatch `fr-section-shown` the first time the body is shown if needed -->
                                            <xf:action if="xxf:instance('local')/show-body/data(.)">
                                                <xf:dispatch name="fr-section-shown" targetid="fr-wizard" xxbl:scope="inner">
                                                    <xf:property name="section-binding" value="xxf:binding($last-available-and-visited-top-level-section-id)"              xxbl:scope="outer"/>
                                                    <xf:property name="section-name"    value="frf:controlNameFromIdOpt($last-available-and-visited-top-level-section-id)" xxbl:scope="outer"/>
                                                    <xf:property name="validate"        value="xxf:instance('local')/validate/data(.)"/>
                                                    <xf:property name="separate-toc"    value="xxf:instance('local')/separate-toc/data(.)"/>
                                                </xf:dispatch>
                                            </xf:action>

                                        </xf:action>

                                    </xf:action>

                                    <xh:div class="pagination pagination-centered">
                                        <xh:ul>
                                            <xh:li class="{{if ($prev-button-ref instance of xs:string) then 'disabled' else ''}}">
                                                <xf:trigger id="fr-wizard-prev"  ref="$prev-button-ref" appearance="minimal" class="fr-wizard-prev">
                                                    <xf:label><xh:i class="fa fa-fw fa-chevron-left"/></xf:label>
                                                    <xf:action event="DOMActivate" type="xpath">
                                                        fr:run-process-by-name('oxf.fr.detail.process', 'wizard-prev')
                                                    </xf:action>
                                                </xf:trigger>
                                            </xh:li>
                                            <xh:li>
                                                <xh:span class="fr-page-number">
                                                    <xf:output value="
                                                        sum(
                                                            (
                                                                if (exists($prev-repeat-id-and-index-opt)) then
                                                                    $prev-repeat-id-and-index-opt[2] + 1
                                                                else
                                                                    1,
                                                                for $case-id in $prev-nav-case-ids
                                                                return
                                                                    if (
                                                                        $case-id = $sections-with-paging-case-ids
                                                                    ) then
                                                                        count(xxf:binding(Wizard:sectionIdFromCaseIdOpt($case-id))/*)
                                                                    else
                                                                        1
                                                            )
                                                        )"/>

                                                    <xf:output value="concat(' ', $fr-resources/summary/paging/of, ' ')"/>
                                                    <xf:output value="
                                                        sum(
                                                            (
                                                                count(
                                                                    $relevant-nav-case-ids[
                                                                        not(. = $sections-with-paging-case-ids)
                                                                    ]
                                                                ),
                                                                for $section-id in $sections-with-paging-section-ids
                                                                return
                                                                    count(xxf:binding($section-id)/*)
                                                            )
                                                        )"/>
                                                </xh:span>
                                            </xh:li>
                                            <xh:li class="{{if ($next-button-ref instance of xs:string) then 'disabled' else ''}}">
                                                <xf:trigger id="fr-wizard-next" ref="$next-button-ref" appearance="minimal" class="fr-wizard-next">
                                                    <xf:label><xh:i class="fa fa-fw fa-chevron-right"/></xf:label>
                                                    <xf:action event="DOMActivate" type="xpath">
                                                        fr:run-process-by-name('oxf.fr.detail.process', 'wizard-next')
                                                    </xf:action>
                                                </xf:trigger>
                                            </xh:li>
                                        </xh:ul>

                                        <!-- NOTE: This shouldn't be in the outer scope ideally. -->
                                        <xf:group id="fr-wizard-update-validity" appearance="xxf:internal">
                                            <xf:action event="fr-wizard-update-validity">
                                                <xsl:choose>
                                                    <xsl:when test="$static-validation-mode = 'explicit'">
                                                        <!-- Update validity, refresh, then try again -->
                                                        <xxf:update-validity
                                                            control="{{string-join(($prev-nav-case-ids, $current-nav-case-id), ' ')}}"
                                                            recurse="true"/>
                                                        <!-- This ensures that when `fr-do-next` runs, UI variables have been updated -->
                                                        <xf:refresh/>
                                                    </xsl:when>
                                                    <xsl:otherwise>
                                                        <!-- Do action immediately -->
                                                    </xsl:otherwise>
                                                </xsl:choose>
                                            </xf:action>
                                        </xf:group>
                                        <xf:group id="fr-wizard-visit-all" appearance="xxf:internal">
                                            <xf:action event="fr-wizard-visit-all">
                                                <xf:dispatch
                                                    iterate="$top-level-section-ids"
                                                    name="fr-expand"
                                                    targetid="{{.}}"/>

                                                <!-- Create `fr:section-status` for all top-level sections so that the TOC status updates  -->
                                                <xf:action iterate="$relevant-top-level-section-ids">
                                                    <xf:var name="section-binding" value="xxf:binding(.)"/>
                                                    <xf:insert
                                                        if="not(exists($section-binding/@fr:section-status))"
                                                        context="$section-binding"
                                                        origin="xf:attribute('fr:section-status', '')"/>
                                                </xf:action>

                                                <!-- Avoid extra refreshes at this point: xxf:deferred-updates="false" -->
                                                <xxf:setvisited
                                                    xxf:deferred-updates="false"
                                                    control="switch"
                                                    visited="true"
                                                    recurse="true"/>
                                            </xf:action>
                                        </xf:group>
                                        <xf:group id="fr-wizard-visit-all-to-current" appearance="xxf:internal">
                                            <!-- NOTE: We visit the current page upon xforms-deselect too. -->
                                            <xf:action event="fr-wizard-visit-all-to-current">
                                                <!-- This is called upon "next". -->
                                                <!-- The current section, since it is current, is obviously already
                                                     expanded. So we make sure we expand anything before it. -->
                                                <xf:dispatch
                                                    iterate="
                                                        distinct-values(
                                                            for $prev-nav-case-id in $prev-nav-case-ids
                                                            return
                                                                $nav-matching-top-level-section-ids[
                                                                    index-of(
                                                                        $nav-section-or-grid-ids,
                                                                        Wizard:sectionIdFromCaseIdOpt($prev-nav-case-id)
                                                                    )
                                                                ]
                                                        )"
                                                    name="fr-expand"
                                                    targetid="{{.}}"/>

                                                <xxf:setvisited
                                                    iterate="$prev-nav-case-ids, if ($current-section-uses-paging) then () else $current-nav-case-id"
                                                    control="{{.}}"
                                                    visited="true"
                                                    recurse="true"/>
                                                <xxf:setvisited
                                                    if="$current-section-uses-paging"
                                                    iterate="1 to $current-repeat-id-and-index-opt[2]"
                                                    control="{{$current-repeat-id-and-index-opt[1]}}~iteration"
                                                    xxf:repeat-indexes="{{.}}"
                                                    visited="true"
                                                    recurse="true"/>
                                            </xf:action>
                                        </xf:group>
                                        <xf:group id="fr-wizard-visit-all-available" appearance="xxf:internal">
                                            <xf:action event="fr-wizard-visit-all-available">
                                                <!-- Expand all as we want the errors recorded because this is called during `save` and
                                                     the save must be blocked if there are any errors in the entire form. -->
                                                <xf:dispatch
                                                    iterate="$top-level-section-ids"
                                                    name="fr-expand"
                                                    targetid="{{.}}"/>

                                                <xf:var
                                                    name="available-top-level-sections-ids"
                                                    value="
                                                        for $section-name in xxf:split(xxf:instance('available-top-level-sections'))
                                                        return
                                                            (: See https://github.com/orbeon/orbeon-forms/issues/4022 :)
                                                            $nav-section-or-grid-ids[frf:controlNameFromId(.) = $section-name]"/>

                                                <!-- Create `fr:section-status` for all top-level sections so that the TOC status updates -->
                                                <xf:action iterate="$available-top-level-sections-ids">
                                                    <xf:var name="section-binding" value="xxf:binding(.)"/>
                                                    <xf:insert
                                                        if="not(exists($section-binding/@fr:section-status))"
                                                        context="$section-binding"
                                                        origin="xf:attribute('fr:section-status', '')"/>
                                                </xf:action>

                                                <xxf:setvisited
                                                    iterate="
                                                        for $section-id in $available-top-level-sections-ids
                                                        return concat($section-id, '-case')"
                                                    control="{{.}}"
                                                    visited="true"
                                                    recurse="true"/>
                                            </xf:action>
                                        </xf:group>
                                        <xf:group id="fr-wizard-unvisit-following" appearance="xxf:internal">
                                            <xxf:setvisited
                                                event="fr-wizard-unvisit-following"

                                                iterate="$next-nav-case-ids"
                                                control="{{.}}"
                                                visited="false"
                                                recurse="true"/>
                                            <!-- Q: Should we remove `fr:section-status`? -->
                                            <!-- NOTE: We *could* collapse the corresponding top-level sections. -->
                                        </xf:group>
                                        <xf:group id="fr-wizard-section-deselected" appearance="xxf:internal">
                                            <xf:action event="fr-wizard-section-deselected">
                                                <!-- Avoid extra refreshes at this point: xxf:deferred-updates="false" -->
                                                <xxf:setvisited
                                                    if="not($current-section-uses-paging)"

                                                    xxf:deferred-updates="false"
                                                    control="{{event('control')}}"
                                                    visited="true"
                                                    recurse="true"/>

                                                <xxf:setvisited
                                                    if="$current-section-uses-paging"
                                                    iterate="1 to $current-repeat-id-and-index-opt[2]"

                                                    xxf:deferred-updates="false"
                                                    control="{{$current-repeat-id-and-index-opt[1]}}~iteration"
                                                    xxf:repeat-indexes="{{.}}"
                                                    visited="true"
                                                    recurse="true"/>
                                            </xf:action>
                                            <!-- NOTE: We *could* collapse the corresponding top-level sections. Should we? -->
                                        </xf:group>
                                    </xh:div>
                                </xh:div>

                                <!--
                                <xf:group>
                                    <xf:label>Wizard Debugger</xf:label>
                                    <xh:ul>
                                        <xh:li>
                                            available-top-level-sections:
                                            <xh:ul>
                                                <xf:repeat ref="xxf:split(xxf:instance('available-top-level-sections'))">
                                                    <xh:li><xf:output value="."/></xh:li>
                                                </xf:repeat>
                                            </xh:ul>
                                        </xh:li>
                                        <xh:li>
                                            nav-section-or-grid-ids (<xf:output value="count($nav-section-or-grid-ids)"/>):
                                            <xh:ul>
                                                <xf:repeat ref="$nav-section-or-grid-ids">
                                                    <xh:li><xf:output value="."/></xh:li>
                                                </xf:repeat>
                                            </xh:ul>
                                        </xh:li>
                                        <xh:li>
                                            nav-matching-top-level-section-ids (<xf:output value="count($nav-matching-top-level-section-ids)"/>):
                                            <xh:ul>
                                                <xf:repeat ref="$nav-matching-top-level-section-ids">
                                                    <xh:li><xf:output value="."/></xh:li>
                                                </xf:repeat>
                                            </xh:ul>
                                        </xh:li>
                                        <xh:li>
                                            top-level-section-ids (<xf:output value="count($top-level-section-ids)"/>):
                                            <xh:ul>
                                                <xf:repeat ref="$top-level-section-ids">
                                                    <xh:li><xf:output value="."/></xh:li>
                                                </xf:repeat>
                                            </xh:ul>
                                        </xh:li>
                                        <xh:li>
                                            sections-with-paging-section-ids (<xf:output value="count($sections-with-paging-section-ids)"/>):
                                            <xh:ul>
                                                <xf:repeat ref="$sections-with-paging-section-ids">
                                                    <xh:li><xf:output value="."/></xh:li>
                                                </xf:repeat>
                                            </xh:ul>
                                        </xh:li>
                                        </xf:group>
                                    </xh:div>
                                </xh:div>
                            </xf:group>
                        </xf:group>
                        <!-- In case the view contains elements other than sections (like dialogs) -->
                                        </xf:dispatch>

                                        <!-- Check that incoming `xforms-focus` is allowed -->
                                        <!-- TODO: See https://github.com/orbeon/orbeon-forms/issues/3323. -->

                                        <!-- Un-visit all subsequent sections upon error in current section in `strict` mode -->
                                        <!-- Use `delay="0"`, so we dispatch all the `fr-wizard-unvisit-following` after all the
                                             `xforms-invalid`, avoiding a `StackOverflowError` on large forms -->
                                        <xf:dispatch
                                            event="xforms-invalid"
                                            if="xxf:instance('local')/validate/data(.) = 'strict'"

                                            name="fr-wizard-unvisit-following"
                                            targetid="fr-wizard-unvisit-following"
                                            delay="0"/>

                                        <!-- Subsection nav enabled AND the top-level section is not part of the nav, which
                                             means we navigate it's subsections/grids. -->
                                        <xsl:variable
                                            name="has-subsections-nav"
                                            select="$static-subsections-nav and not($static-nav-section-or-grid-ids = @id)"/>

                                        <xf:action event="xforms-select" target="#observer">

                                            <!--
                                                Keep `current-case-id` and `current-top-level-case-id` up to date.

                                                NOTE: The `xforms-select` event is dispatched at the end of the `xf:toggle` but
                                                before focus has been adjusted.
                                            -->
                                            <xsl:if test="not($has-subsections-nav)">
                                                <!-- `current-case-id` is the same as `current-top-level-case-id` -->
                                                <xf:setvalue
                                                    ref="xxf:instance('local')/current-case-id"
                                                    value="event('xxf:targetid')"/>
                                            </xsl:if>
                                            <xsl:if test="$has-subsections-nav">
                                                <!-- Either the top-level case doesn't change, and then the nexted
                                                     switch's event handler sets this value; or the top-level case
                                                     changed, and there is a chance that the nested switch didn't
                                                     change its case, in which case we make sure we set it here. If
                                                     the nested switch changed its case, it already set the value,
                                                     but that's ok. -->
                                                <xf:setvalue
                                                    ref="xxf:instance('local')/current-case-id"
                                                    value="case('{$static-section-id}-switch')"/>
                                            </xsl:if>

                                            <xf:setvalue
                                                ref="xxf:instance('local')/current-top-level-case-id"
                                                value="event('xxf:targetid')"/>

                                            <xf:dispatch name="fr-section-scroll" targetid="switch"/>

                                            <xf:var
                                                name="section-id"
                                                value="Wizard:sectionIdFromCaseIdOpt(event('xxf:targetid'))"
                                                xxbl:scope="inner"/>

                                            <xf:dispatch targetid="{{Wizard:sectionIdFromCaseIdOpt(event('xxf:targetid'))}}" name="fr-expand"/>

                                            <!-- NOTE: 2020-01-23: This is dispatched only for *top-level* pages. -->
                                            <xf:dispatch name="fr-section-shown" targetid="fr-wizard" xxbl:scope="inner">
                                                <xf:property name="section-binding" value="xxf:binding(Wizard:sectionIdFromCaseIdOpt(event('xxf:targetid')))" xxbl:scope="outer"/>
                                                <xf:property name="section-name"    value="frf:controlNameFromIdOpt($section-id)"/>
                                                <xf:property name="validate"        value="$local/validate/data(.)"/>
                                                <xf:property name="separate-toc"    value="$local/separate-toc/data(.)"/>
                                            </xf:dispatch>

                                        </xf:action>

                                        <xf:group appearance="xxf:internal"><!-- Q: Why this group? -->
                                            <!-- This is where the original section's attribute are being copied, including `id` and `bind` -->
                                            <xsl:copy><!-- `<fr:section>` -->
                                                <xsl:attribute name="view-appearance">wizard</xsl:attribute>
                                                <xsl:attribute name="collapsible">false</xsl:attribute>
                                                <xsl:apply-templates select="@* except (@collapse | @collapsible | @open)"/>
                                                <!-- Tell the section whether it needs to be initially open or not (optimization).
                                                     We can't enable this yet in `lax|strict` mode, see:
                                                     https://github.com/orbeon/orbeon-forms/issues/4790#issuecomment-791652516 -->
                                                <xsl:attribute
                                                    name="content-nonrelevant-if-collapsed"
                                                    select="$static-lazy-section-relevance"/>
                                                <xsl:attribute
                                                    name="open"
                                                    select="concat('{case(''switch'') = ''', $static-section-id, '-case''}')"/>

                                                <!-- Update the `changed` token -->
                                                <xf:action event="xforms-value-changed">
                                                    <xf:setvalue
                                                        ref="@fr:section-status"
                                                        value="
                                                            let $tokens := distinct-values(xxf:split(.))
                                                            return
                                                                if (empty(index-of($tokens, 'changed'))) then
                                                                    string-join(($tokens, 'changed'), ' ')
                                                                else
                                                                    ."/>
                                                </xf:action>

                                                <xsl:choose>
                                                    <xsl:when test="$has-subsections-nav">

                                                        <!-- Don't forget the enclosing section lHHA -->
                                                        <xsl:apply-templates select="xf:label | xf:help | xf:hint | xf:alert"/>

                                                        <!-- Subsections -->
                                                        <xf:switch id="{$static-section-id}-switch" xxf:element="div" xxf:update="full">
                                                            <xsl:for-each select="fr:section | fr:grid">
                                                                <!-- fr:grid might not have an id, and we need one to toggle -->
                                                                <xsl:variable name="section-or-grid-id" select="(@id, concat(generate-id(), '-wizard-grid'))[1]"/>
                                                                <xf:case id="{$section-or-grid-id}-case">
                                                                    <xxf:setvisited
                                                                        event="xforms-deselect"
                                                                        target="#observer"
                                                                        control="{{event('xxf:targetid')}}"
                                                                        visited="true"
                                                                        recurse="true"/>
                                                                    <xf:action event="xforms-select" target="#observer">
                                                                        <!-- Keep `current-case-id` up to date in case switch happened via toggling. -->
                                                                        <xf:setvalue
                                                                            ref="xxf:instance('local')/current-case-id"
                                                                            value="event('xxf:targetid')"/>

                                                                        <xf:dispatch name="fr-section-scroll" targetid="switch"/>

                                                                    </xf:action>
                                                                    <xf:group appearance="xxf:internal">
                                                                        <xsl:copy>
                                                                            <xsl:if test="self::fr:section">
                                                                                <xsl:attribute name="view-appearance">wizard</xsl:attribute>
                                                                                <xsl:attribute name="collapsible">false</xsl:attribute>
                                                                            </xsl:if>
                                                                            <xsl:if test="not(@id)">
                                                                                <xsl:attribute name="id" select="$section-or-grid-id"/>
                                                                            </xsl:if>
                                                                            <xsl:apply-templates select="(@* except (@collapse | @collapsible | @open)) | node()"/>
                                                                        </xsl:copy>
                                                                    </xf:group>
                                                                </xf:case>
                                                            </xsl:for-each>
                                                        </xf:switch>
                                                    </xsl:when>
                                                    <xsl:otherwise>
                                                        <!-- No subsection nav -->
                                                        <xsl:apply-templates select="node()"/>
                                                    </xsl:otherwise>
                                                </xsl:choose>
                                            </xsl:copy>
                                        </xf:group>
                                    </xf:case>
                                </xsl:for-each>
                            </xf:switch>
                            <xsl:if test="p:property(string-join(('oxf.fr.detail.captcha.location', $static-app, $static-form), '.')) = 'inside-wizard'">
                                <xf:var name="fr-resources"><xxf:value xxbl:scope="outer" value="$fr-resources"/></xf:var>
                                <fr:captcha id="fr-captcha" namespace-name="{frf:captchaComponent($static-app, $static-form)}"/>
                            </xsl:if>
                        </xh:div>
                        <!-- In case the view contains elements other than sections (like dialogs) -->
                        <xh:div class="fr-wizard-other">
                            <xh:div class="fr-wizard-cell-placeholder"/>
                            <xf:group appearance="xxf:internal" xxbl:scope="outer">
                                <xsl:apply-templates select="* except fr:section"/>
                            </xf:group>
                        </xh:div>
                    </xf:group>
                </xsl:template>

                <!-- TOC: Swallow non-relevant nodes -->
                <xsl:template match="text()" mode="toc-sections"/>
                <xsl:template match="*" mode="toc-sections">
                    <xsl:apply-templates mode="toc-sections"/>
                </xsl:template>

                <!-- TOC: handle section -->
                <xsl:template match="fr:section" mode="toc-sections">

                    <xsl:variable
                        name="static-current-section"
                        select="."/>
                    <xsl:variable
                        name="static-section-id"
                        select="$static-current-section/@id"/>
                    <xsl:variable
                        name="static-is-top-level-section"
                        select="empty($static-current-section/ancestor::fr:section)"/>
                    <xsl:variable
                        name="static-section-has-html-label"
                        select="$static-current-section/xf:label/@mediatype = 'text/html'"/>
                    <xsl:variable
                        name="static-top-level-section-id"
                        select="($static-current-section/ancestor-or-self::fr:section/@id)[1]"/>
                    <xsl:variable
                        name="static-top-level-section-case-id"
                        select="concat($static-top-level-section-id, '-case')"/>
                    <xsl:variable
                        name="use-paging"
                        select="$static-current-section/@page-size = '1'"/>

                    <!-- Propagate binding so that entry for section disappears if the section is non-relevant -->
                    <xsl:element name="xf:{if ($use-paging) then 'repeat' else 'group'}">

                        <xsl:choose>
                            <xsl:when test="$use-paging">
                                <xsl:variable
                                    name="repeat-expression"
                                    as="xs:string?"
                                    select="
                                        (
                                            $static-current-section/@ref,
                                            $static-current-section/@nodeset,
                                            for $b in $static-current-section/@bind
                                                return
                                                    concat(
                                                        'bind(''',
                                                        $b,
                                                        ''')'
                                                    )
                                        )[1]"/>

                                <xsl:attribute
                                    name="ref"
                                    select="concat($repeat-expression, '/*')"/>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:copy-of select="@model | @context | @bind | @ref"/>
                            </xsl:otherwise>
                        </xsl:choose>

                        <xf:var name="top-level-section-available">
                            <xxf:value
                                value="
                                    exists(
                                        index-of(
                                            xxf:split(xxf:instance('available-top-level-sections')),
                                            '{frf:controlNameFromIdOpt($static-top-level-section-id)}'
                                        )
                                    )"
                                xxbl:scope="inner"/>
                        </xf:var>

                        <!-- FIXME: `exists(@fr:section-status)` no longer works, while `exists(@*:section-status)` and
                              `exists(@fr:section-status/string())` work! -->
                        <xf:var
                            name="top-level-section-visited"
                            value="exists(@fr:section-status/string())"/>

                        <xf:var
                            name="top-level-section-tokens"
                            value="xxf:split(@fr:section-status)"/>

                        <xsl:choose>
                            <xsl:when test="$use-paging">
                                <xf:var
                                    name="top-level-section-active"
                                    value="
                                        not($separate-toc-mode) and
                                        $current-top-level-case-id = '{$static-section-id}-case' and
                                        xxf:repeat-position() = xxf:instance('local')/current-index/data(.)"/>
                                <xf:var
                                    name="section-active"
                                    value="
                                        not($separate-toc-mode) and
                                        $current-nav-case-id = '{$static-section-id}-case' and
                                        xxf:repeat-position() = xxf:instance('local')/current-index/data(.)"/>
                            </xsl:when>
                            <xsl:otherwise>
                                <xf:var
                                    name="top-level-section-active"
                                    value="
                                        not($separate-toc-mode) and
                                        $current-top-level-case-id = '{$static-section-id}-case'"/>
                                <xf:var
                                    name="section-active"
                                    value="
                                        not($separate-toc-mode) and
                                        $current-nav-case-id = '{$static-section-id}-case'"/>
                            </xsl:otherwise>
                        </xsl:choose>

                        <xsl:variable name="section-label-expr" as="xs:string">
                            <xsl:choose>
                                <xsl:when test="$use-paging">
                                    <xsl:choose>
                                        <xsl:when test="exists(fr:iteration-label)">
                                            <xsl:value-of select="
                                                concat(
                                                    'xxf:value(''',
                                                    $static-section-id,
                                                    '-repeater-iteration-label'', false())[xxf:repeat-position()]'
                                                )"/>
                                        </xsl:when>
                                        <xsl:otherwise>
                                            <xsl:value-of select="
                                                concat(
                                                    'concat(xxf:label(''',
                                                    $static-section-id,
                                                    '''), '' '', xxf:repeat-position())'
                                                )"/>
                                        </xsl:otherwise>
                                    </xsl:choose>
                                </xsl:when>
                                <xsl:otherwise>
                                    <xsl:value-of select="
                                        concat(
                                            'xxf:label(''',
                                            $static-section-id,
                                            ''')'
                                        )"/>
                                </xsl:otherwise>
                            </xsl:choose>
                        </xsl:variable>

                        <xh:li class="{{
                            'disabled'           [not($top-level-section-available)],
                            'active'             [$section-active or $top-level-section-active],
                            'started'            [$top-level-section-visited],
                            $top-level-section-tokens,

                            'first-page'         [$relevant-top-level-case-ids[1]      = '{concat($static-section-id, '-case')}'],
                            'last-top-level-page'[$relevant-top-level-case-ids[last()] = '{concat($static-section-id, '-case')}'],
                            'last-page'          [$relevant-nav-case-ids[last()]       = '{concat($static-section-id, '-case')}']
                        }}" aria-current="{{
                            if ($section-active) then 'page' else 'false'
                        }}" aria-disabled="{{
                            if (not($top-level-section-available)) then 'true' else 'false'
                        }}">

                            <xf:trigger appearance="minimal">
                                <xf:label>
                                    <xh:span class="fr-toc-title">
                                        <xf:output value="{$section-label-expr}">
                                            <xsl:if test="$static-section-has-html-label"><xsl:attribute name="mediatype">text/html</xsl:attribute></xsl:if>
                                        </xf:output>
                                    </xh:span>
                                    <xh:span class="fr-toc-edit {{'xforms-hidden'[not(xxf:instance('local')/section-status/data(.))]}}"><xf:output value="xxf:r('components.wizard.edit', '|fr-fr-resources|')"/></xh:span>
                                    <xsl:if test="$static-is-top-level-section">
                                        <!-- NOTE: Hide labels when not in `separate-toc` mode as they take a lot of space -->
                                        <xh:span class="fr-toc-status {{'xforms-hidden'[not(xxf:instance('local')/section-status/data(.))]}} label{{
                                            if ($top-level-section-tokens = 'invalid') then
                                                ' label-important'
                                            else if ($top-level-section-tokens = 'incomplete') then
                                                ' label-warning'
                                            else if ($top-level-section-visited) then
                                                ' label-success'
                                            else
                                                ''
                                        }}"><xf:output value="
                                                xxf:r(
                                                    if ($top-level-section-tokens = 'invalid') then
                                                        'components.wizard.errors'
                                                    else if ($top-level-section-tokens = 'incomplete') then
                                                        'components.wizard.incomplete'
                                                    else if ($top-level-section-visited) then
                                                        'components.wizard.complete'
                                                    else
                                                        'components.wizard.not-started',
                                                    '|fr-fr-resources|'
                                                )"/></xh:span>
                                    </xsl:if>
                                </xf:label>
                                <xf:hint value="{$section-label-expr}">
                                    <xsl:if test="$static-section-has-html-label"><xsl:attribute name="mediatype">text/html</xsl:attribute></xsl:if>
                                </xf:hint>
                                <!-- DOMActivate handler which depends on `$static-validation-mode` -->
                                <xf:action event="DOMActivate">
                                    <xf:dispatch
                                        name="fr-wizard-update-validity"
                                        targetid="fr-wizard-update-validity"/>
                                    <xf:action if="$top-level-section-available">

                                        <!-- Figure out the nav section id based on whether we support subsection navigation AND where in the hierarchy
                                             the clicked TOC section is. -->
                                        <xsl:variable
                                            name="static-nav-section-id"
                                            select="
                                                if ($static-subsections-nav) then
                                                    (
                                                        if ($static-is-top-level-section) then
                                                            (: Current section is a top-level section. Try first subsection or grid if any,
                                                               otherwise the top-level section itself, which means that there are no subsections
                                                               or grids. Unfortunately, there is some logic duplication between here and the
                                                               computation of `$static-nav-sections-or-grids` above. :)
                                                            (
                                                                $static-current-section[
                                                                    not(@subsections-nav = 'false') and
                                                                    not(frf:isRepeat(.))            and
                                                                    exists(fr:section)
                                                                ]/(fr:section | fr:grid)[1],
                                                                $static-current-section
                                                            )[1]
                                                        else
                                                            (: Current section is a subsection. Take first subsection from the top, as only two levels of
                                                               section navigation are supported. :)
                                                            ($static-current-section/ancestor-or-self::fr:section)[2]
                                                    )/(
                                                        @id,
                                                        concat(generate-id(), '-wizard-grid')
                                                    )[1]
                                                else
                                                    $static-top-level-section-id
                                        "/>

                                        <!-- Remember where we are toggling to, toggle... -->
                                        <xf:toggle
                                            case="{$static-nav-section-id}-case"/>

                                        <xsl:if test="$use-paging">
                                            <xf:var name="new-index" value="xxf:repeat-position()"/>
                                            <xf:setvalue
                                                ref="xxf:instance('local')/current-index"
                                                value="$new-index"/>
                                            <xf:setindex
                                                repeat="{$static-section-id}-repeater-repeat"
                                                index="$new-index"/>
                                        </xsl:if>

                                        <!-- ...and focus on specific sub-section -->
                                        <xsl:if test="p:property(string-join(('oxf.fr.detail.initial-focus', $static-app, $static-form), '.'))">
                                            <xf:setfocus
                                                control="{$static-section-id}"
                                                includes="{{frf:xpathFormRunnerStringProperty('oxf.fr.detail.focus.includes')}}"
                                                excludes="{{frf:xpathFormRunnerStringProperty('oxf.fr.detail.focus.excludes')}}"/>
                                        </xsl:if>

                                        <!-- Show body if needed -->
                                        <xf:var name="local" value="xxf:instance('local')"/>
                                        <xf:action if="$local/separate-toc/data(.)">
                                            <xf:setvalue
                                                ref="$local/show-toc"
                                                value="false()"/>

                                            <!-- See https://github.com/orbeon/orbeon-forms/issues/3668 -->
                                            <xf:action if="not($local/show-body/data(.))">

                                                <xf:var
                                                    name="current-top-level-section-id"
                                                    value="Wizard:sectionIdFromCaseIdOpt($current-top-level-case-id)"/>

                                                <xf:dispatch name="fr-section-shown" targetid="fr-wizard" xxbl:scope="inner">
                                                    <xf:property name="section-binding" value="xxf:binding($current-top-level-section-id)"              xxbl:scope="outer"/>
                                                    <xf:property name="section-name"    value="frf:controlNameFromIdOpt($current-top-level-section-id)" xxbl:scope="outer"/>
                                                    <xf:property name="validate"        value="xxf:instance('local')/validate/data(.)"/>
                                                    <xf:property name="separate-toc"    value="xxf:instance('local')/separate-toc/data(.)"/>
                                                </xf:dispatch>

                                                <xf:setvalue
                                                    ref="$local/show-body"
                                                    value="true()"/>
                                            </xf:action>

                                        </xf:action>
                                    </xf:action>
                                </xf:action>
                            </xf:trigger>

                            <xsl:choose>
                                <xsl:when test="$static-subsections-toc = 'all' and exists(.//fr:section)">
                                    <xh:div role="navigation">
                                        <xh:ul class="nav nav-list">
                                            <xsl:apply-templates mode="toc-sections"/>
                                        </xh:ul>
                                    </xh:div>
                                </xsl:when>
                                <xsl:when test="$static-subsections-toc = 'active' and exists(.//fr:section)">
                                    <xh:div role="navigation">
                                        <xh:ul class="nav nav-list{{' xforms-hidden'[not($top-level-section-active)]}}">
                                            <xsl:apply-templates mode="toc-sections"/>
                                        </xh:ul>
                                    </xh:div>
                                </xsl:when>
                                <xsl:otherwise>
                                    <!-- No content -->
                                </xsl:otherwise>
                            </xsl:choose>
                        </xh:li>
                    </xsl:element>
                </xsl:template>

            </xsl:transform>
        </xbl:template>
    </xbl:binding>

</xbl:xbl>
<MSG> Following #4211: add "wizard debugger"

<DFF> @@ -1048,6 +1048,125 @@
                                         </xf:group>
                                     </xh:div>
                                 </xh:div>
+
+                                <!--
+                                <xf:group>
+                                    <xf:label>Wizard Debugger</xf:label>
+                                    <xh:ul>
+                                        <xh:li>
+                                            nav-section-or-grid-ids (<xf:output value="count($nav-section-or-grid-ids)"/>):
+                                            <xh:ul>
+                                                <xf:repeat ref="$nav-section-or-grid-ids">
+                                                    <xh:li><xf:output value="."/></xh:li>
+                                                </xf:repeat>
+                                            </xh:ul>
+                                        </xh:li>
+                                        <xh:li>
+                                            nav-matching-top-level-section-ids (<xf:output value="count($nav-matching-top-level-section-ids)"/>):
+                                            <xh:ul>
+                                                <xf:repeat ref="$nav-matching-top-level-section-ids">
+                                                    <xh:li><xf:output value="."/></xh:li>
+                                                </xf:repeat>
+                                            </xh:ul>
+                                        </xh:li>
+                                        <xh:li>
+                                            top-level-section-ids (<xf:output value="count($top-level-section-ids)"/>):
+                                            <xh:ul>
+                                                <xf:repeat ref="$top-level-section-ids">
+                                                    <xh:li><xf:output value="."/></xh:li>
+                                                </xf:repeat>
+                                            </xh:ul>
+                                        </xh:li>
+                                        <xh:li>
+                                            sections-with-paging-section-ids (<xf:output value="count($sections-with-paging-section-ids)"/>):
+                                            <xh:ul>
+                                                <xf:repeat ref="$sections-with-paging-section-ids">
+                                                    <xh:li><xf:output value="."/></xh:li>
+                                                </xf:repeat>
+                                            </xh:ul>
+                                        </xh:li>
+                                        <xh:li>
+                                            sections-with-paging-case-ids (<xf:output value="count($sections-with-paging-case-ids)"/>):
+                                            <xh:ul>
+                                                <xf:repeat ref="$sections-with-paging-case-ids">
+                                                    <xh:li><xf:output value="."/></xh:li>
+                                                </xf:repeat>
+                                            </xh:ul>
+                                        </xh:li>
+                                        <xh:li>validated-mode: <xf:output value="$validated-mode"/></xh:li>
+                                        <xh:li>separate-toc-mode: <xf:output value="$separate-toc-mode"/></xh:li>
+                                        <xh:li>
+                                            relevant-nav-section-or-grid-ids (<xf:output value="count($relevant-nav-section-or-grid-ids)"/>):
+                                            <xh:ul>
+                                                <xf:repeat ref="$relevant-nav-section-or-grid-ids">
+                                                    <xh:li><xf:output value="."/></xh:li>
+                                                </xf:repeat>
+                                            </xh:ul>
+                                        </xh:li>
+                                        <xh:li>
+                                            relevant-top-level-section-ids (<xf:output value="count($relevant-top-level-section-ids)"/>):
+                                            <xh:ul>
+                                                <xf:repeat ref="$relevant-top-level-section-ids">
+                                                    <xh:li><xf:output value="."/></xh:li>
+                                                </xf:repeat>
+                                            </xh:ul>
+                                        </xh:li>
+                                        <xh:li>
+                                            relevant-nav-case-ids (<xf:output value="count($relevant-nav-case-ids)"/>):
+                                            <xh:ul>
+                                                <xf:repeat ref="$relevant-nav-case-ids">
+                                                    <xh:li><xf:output value="."/></xh:li>
+                                                </xf:repeat>
+                                            </xh:ul>
+                                        </xh:li>
+                                        <xh:li>
+                                            relevant-top-level-case-ids (<xf:output value="count($relevant-top-level-case-ids)"/>):
+                                            <xh:ul>
+                                                <xf:repeat ref="$relevant-top-level-case-ids">
+                                                    <xh:li><xf:output value="."/></xh:li>
+                                                </xf:repeat>
+                                            </xh:ul>
+                                        </xh:li>
+                                        <xh:li>current-top-level-case-id: <xf:output value="$current-top-level-case-id"/></xh:li>
+                                        <xh:li>current-nav-case-id: <xf:output value="$current-nav-case-id"/></xh:li>
+                                        <xh:li>nav-case-index: <xf:output value="$nav-case-index"/></xh:li>
+                                        <xh:li>top-level-case-index: <xf:output value="top-level-case-index"/></xh:li>
+                                        <xh:li>
+                                            prev-nav-case-ids (<xf:output value="count($prev-nav-case-ids)"/>):
+                                            <xh:ul>
+                                                <xf:repeat ref="$prev-nav-case-ids">
+                                                    <xh:li><xf:output value="."/></xh:li>
+                                                </xf:repeat>
+                                            </xh:ul>
+                                        </xh:li>
+                                        <xh:li>
+                                            next-nav-case-ids (<xf:output value="count($next-nav-case-ids)"/>):
+                                            <xh:ul>
+                                                <xf:repeat ref="$next-nav-case-ids">
+                                                    <xh:li><xf:output value="."/></xh:li>
+                                                </xf:repeat>
+                                            </xh:ul>
+                                        </xh:li>
+                                        <xh:li>
+                                            next-top-level-case-ids (<xf:output value="count($next-top-level-case-ids)"/>):
+                                            <xh:ul>
+                                                <xf:repeat ref="$next-top-level-case-ids">
+                                                    <xh:li><xf:output value="."/></xh:li>
+                                                </xf:repeat>
+                                            </xh:ul>
+                                        </xh:li>
+                                        <xh:li>current-section-uses-paging: <xf:output value="$current-section-uses-paging"/></xh:li>
+                                        <xh:li>prev-repeat-id-and-index-opt: <xf:output value="$prev-repeat-id-and-index-opt"/></xh:li>
+                                        <xh:li>next-repeat-id-and-index-opt: <xf:output value="$next-repeat-id-and-index-opt"/></xh:li>
+                                        <xh:li>next-nested-case-id-opt: <xf:output value="$next-nested-case-id-opt"/></xh:li>
+                                        <xh:li>next-top-level-case-id-opt: <xf:output value="$next-top-level-case-id-opt"/></xh:li>
+                                        <xh:li>allow-prev: <xf:output value="$allow-prev"/></xh:li>
+                                        <xh:li>allow-next: <xf:output value="$allow-next"/></xh:li>
+                                        <xh:li>is-first-nav: <xf:output value="$is-first-nav"/></xh:li>
+                                        <xh:li>is-last-nav: <xf:output value="$is-last-nav"/></xh:li>
+                                    </xh:ul>
+                                </xf:group>
+                                -->
                             </xf:group>
                         </xf:group>
                         <!-- In case the view contains elements other than sections (like dialogs) -->

{'commit': 'diff --git a/form-runner/jvm/src/main/resources/xbl/orbeon/wizard/wizard.xbl b/form-runner/jvm/src/main/resources/xbl/orbeon/wizard/wizard.xbl\nindex a911992bc4..37bbcda0a8 100644\n--- a/form-runner/jvm/src/main/resources/xbl/orbeon/wizard/wizard.xbl\n+++ b/form-runner/jvm/src/main/resources/xbl/orbeon/wizard/wizard.xbl\n@@ -1048,6 +1048,125 @@\n                                         </xf:group>\n                                     </xh:div>\n                                 </xh:div>\n+\n+                                <!--\n+                                <xf:group>\n+                                    <xf:label>Wizard Debugger</xf:label>\n+                                    <xh:ul>\n+                                        <xh:li>\n+                                            nav-section-or-grid-ids (<xf:output value="count($nav-section-or-grid-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$nav-section-or-grid-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>\n+                                            nav-matching-top-level-section-ids (<xf:output value="count($nav-matching-top-level-section-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$nav-matching-top-level-section-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>\n+                                            top-level-section-ids (<xf:output value="count($top-level-section-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$top-level-section-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>\n+                                            sections-with-paging-section-ids (<xf:output value="count($sections-with-paging-section-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$sections-with-paging-section-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>\n+                                            sections-with-paging-case-ids (<xf:output value="count($sections-with-paging-case-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$sections-with-paging-case-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>validated-mode: <xf:output value="$validated-mode"/></xh:li>\n+                                        <xh:li>separate-toc-mode: <xf:output value="$separate-toc-mode"/></xh:li>\n+                                        <xh:li>\n+                                            relevant-nav-section-or-grid-ids (<xf:output value="count($relevant-nav-section-or-grid-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$relevant-nav-section-or-grid-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>\n+                                            relevant-top-level-section-ids (<xf:output value="count($relevant-top-level-section-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$relevant-top-level-section-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>\n+                                            relevant-nav-case-ids (<xf:output value="count($relevant-nav-case-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$relevant-nav-case-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>\n+                                            relevant-top-level-case-ids (<xf:output value="count($relevant-top-level-case-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$relevant-top-level-case-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>current-top-level-case-id: <xf:output value="$current-top-level-case-id"/></xh:li>\n+                                        <xh:li>current-nav-case-id: <xf:output value="$current-nav-case-id"/></xh:li>\n+                                        <xh:li>nav-case-index: <xf:output value="$nav-case-index"/></xh:li>\n+                                        <xh:li>top-level-case-index: <xf:output value="top-level-case-index"/></xh:li>\n+                                        <xh:li>\n+                                            prev-nav-case-ids (<xf:output value="count($prev-nav-case-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$prev-nav-case-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>\n+                                            next-nav-case-ids (<xf:output value="count($next-nav-case-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$next-nav-case-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>\n+                                            next-top-level-case-ids (<xf:output value="count($next-top-level-case-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$next-top-level-case-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>current-section-uses-paging: <xf:output value="$current-section-uses-paging"/></xh:li>\n+                                        <xh:li>prev-repeat-id-and-index-opt: <xf:output value="$prev-repeat-id-and-index-opt"/></xh:li>\n+                                        <xh:li>next-repeat-id-and-index-opt: <xf:output value="$next-repeat-id-and-index-opt"/></xh:li>\n+                                        <xh:li>next-nested-case-id-opt: <xf:output value="$next-nested-case-id-opt"/></xh:li>\n+                                        <xh:li>next-top-level-case-id-opt: <xf:output value="$next-top-level-case-id-opt"/></xh:li>\n+                                        <xh:li>allow-prev: <xf:output value="$allow-prev"/></xh:li>\n+                                        <xh:li>allow-next: <xf:output value="$allow-next"/></xh:li>\n+                                        <xh:li>is-first-nav: <xf:output value="$is-first-nav"/></xh:li>\n+                                        <xh:li>is-last-nav: <xf:output value="$is-last-nav"/></xh:li>\n+                                    </xh:ul>\n+                                </xf:group>\n+                                -->\n                             </xf:group>\n                         </xf:group>\n                         <!-- In case the view contains elements other than sections (like dialogs) -->\n', 'commit_subject': 'Following #4211: add "wizard debugger"', 'repo_name': 'orbeon/orbeon-forms', 'committer': {'name': 'ebruchez', 'email': '67aad48d6511806a4af5612b9998de6a8f7fe611@orbeon.com', 'time_sec': '1579823515', 'tz_offset': '-480', 'date': {'seconds': '1579823515'}}, 'commit_tree': '008d06c3fb10fe603e8fc4d3e0ceac8f83765d32', 'commit_message': 'Following #4211: add "wizard debugger"\n', 'language_name': 'Java', 'license': 'lgpl-2.1', 'hunks': '@@ -1048,6 +1048,125 @@\n                                         </xf:group>\n                                     </xh:div>\n                                 </xh:div>\n+\n+                                <!--\n+                                <xf:group>\n+                                    <xf:label>Wizard Debugger</xf:label>\n+                                    <xh:ul>\n+                                        <xh:li>\n+                                            nav-section-or-grid-ids (<xf:output value="count($nav-section-or-grid-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$nav-section-or-grid-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>\n+                                            nav-matching-top-level-section-ids (<xf:output value="count($nav-matching-top-level-section-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$nav-matching-top-level-section-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>\n+                                            top-level-section-ids (<xf:output value="count($top-level-section-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$top-level-section-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>\n+                                            sections-with-paging-section-ids (<xf:output value="count($sections-with-paging-section-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$sections-with-paging-section-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>\n+                                            sections-with-paging-case-ids (<xf:output value="count($sections-with-paging-case-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$sections-with-paging-case-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>validated-mode: <xf:output value="$validated-mode"/></xh:li>\n+                                        <xh:li>separate-toc-mode: <xf:output value="$separate-toc-mode"/></xh:li>\n+                                        <xh:li>\n+                                            relevant-nav-section-or-grid-ids (<xf:output value="count($relevant-nav-section-or-grid-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$relevant-nav-section-or-grid-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>\n+                                            relevant-top-level-section-ids (<xf:output value="count($relevant-top-level-section-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$relevant-top-level-section-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>\n+                                            relevant-nav-case-ids (<xf:output value="count($relevant-nav-case-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$relevant-nav-case-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>\n+                                            relevant-top-level-case-ids (<xf:output value="count($relevant-top-level-case-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$relevant-top-level-case-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>current-top-level-case-id: <xf:output value="$current-top-level-case-id"/></xh:li>\n+                                        <xh:li>current-nav-case-id: <xf:output value="$current-nav-case-id"/></xh:li>\n+                                        <xh:li>nav-case-index: <xf:output value="$nav-case-index"/></xh:li>\n+                                        <xh:li>top-level-case-index: <xf:output value="top-level-case-index"/></xh:li>\n+                                        <xh:li>\n+                                            prev-nav-case-ids (<xf:output value="count($prev-nav-case-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$prev-nav-case-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>\n+                                            next-nav-case-ids (<xf:output value="count($next-nav-case-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$next-nav-case-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>\n+                                            next-top-level-case-ids (<xf:output value="count($next-top-level-case-ids)"/>):\n+                                            <xh:ul>\n+                                                <xf:repeat ref="$next-top-level-case-ids">\n+                                                    <xh:li><xf:output value="."/></xh:li>\n+                                                </xf:repeat>\n+                                            </xh:ul>\n+                                        </xh:li>\n+                                        <xh:li>current-section-uses-paging: <xf:output value="$current-section-uses-paging"/></xh:li>\n+                                        <xh:li>prev-repeat-id-and-index-opt: <xf:output value="$prev-repeat-id-and-index-opt"/></xh:li>\n+                                        <xh:li>next-repeat-id-and-index-opt: <xf:output value="$next-repeat-id-and-index-opt"/></xh:li>\n+                                        <xh:li>next-nested-case-id-opt: <xf:output value="$next-nested-case-id-opt"/></xh:li>\n+                                        <xh:li>next-top-level-case-id-opt: <xf:output value="$next-top-level-case-id-opt"/></xh:li>\n+                                        <xh:li>allow-prev: <xf:output value="$allow-prev"/></xh:li>\n+                                        <xh:li>allow-next: <xf:output value="$allow-next"/></xh:li>\n+                                        <xh:li>is-first-nav: <xf:output value="$is-first-nav"/></xh:li>\n+                                        <xh:li>is-last-nav: <xf:output value="$is-last-nav"/></xh:li>\n+                                    </xh:ul>\n+                                </xf:group>\n+                                -->\n                             </xf:group>\n                         </xf:group>\n                         <!-- In case the view contains elements other than sections (like dialogs) -->\n', 'addition_count': 119, 'deletion_count': 0, 'src_file': 'a/form-runner/jvm/src/main/resources/xbl/orbeon/wizard/wizard.xbl', 'tgt_file': 'b/form-runner/jvm/src/main/resources/xbl/orbeon/wizard/wizard.xbl', 'file_extension': '.xbl', 'before_file': '<!--\n  Copyright (C) 2012 Orbeon, Inc.\n\n  This program is free software; you can redistribute it and/or modify it under the terms of the\n  GNU Lesser General Public License as published by the Free Software Foundation; either version\n  2.1 of the License, or (at your option) any later version.\n\n  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n  See the GNU Lesser General Public License for more details.\n\n  The full text of the license is available at http://www.gnu.org/copyleft/lesser.html\n  -->\n<xbl:xbl\n    xmlns:xh="http://www.w3.org/1999/xhtml"\n    xmlns:xf="http://www.w3.org/2002/xforms"\n    xmlns:xs="http://www.w3.org/2001/XMLSchema"\n    xmlns:xxf="http://orbeon.org/oxf/xml/xforms"\n    xmlns:fr="http://orbeon.org/oxf/xml/form-runner"\n    xmlns:xbl="http://www.w3.org/ns/xbl"\n    xmlns:xxbl="http://orbeon.org/oxf/xml/xbl"\n    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"\n    xmlns:oxf="http://www.orbeon.com/oxf/processors"\n    xmlns:frf="java:org.orbeon.oxf.fr.FormRunner"\n    xmlns:map="http://www.w3.org/2005/xpath-functions/map"\n    xmlns:p="http://www.orbeon.com/oxf/pipeline"\n    xmlns:Wizard="java:org.orbeon.xbl.Wizard">\n\n    <xbl:binding\n        id="fr-wizard"\n        element="fr|wizard"\n        xxf:external-events="fr-wizard-focus">\n\n        <xbl:resources>\n            <xbl:style src="/xbl/orbeon/wizard/wizard.css"/>\n        </xbl:resources>\n        <xbl:handlers>\n\n            <xbl:handler event="xxforms-refresh-done" observer="#document" xxbl:scope="outer">\n                <!--\n                    - `fr:error-summary` listens to events during the capture phase so that it is up to\n                       date once the wizard processes them.\n                -->\n                <xf:dispatch name="fr-update-section-status" targetid="fr-wizard-outer-group"/>\n            </xbl:handler>\n\n            <xbl:handler event="fr-prev" phase="target">\n                <!-- NOTE: The target shouldn\'t be in the outer scope ideally. -->\n                <xf:dispatch\n                    name="fr-prev-internal"\n                    targetid="fr-wizard-outer-group"\n                    xxbl:scope="outer"/>\n            </xbl:handler>\n            <xbl:handler event="fr-next" phase="target">\n                <!-- NOTE: The target shouldn\'t be in the outer scope ideally. -->\n                <xf:dispatch\n                    name="fr-next-internal"\n                    targetid="fr-wizard-outer-group"\n                    xxbl:scope="outer"/>\n            </xbl:handler>\n            <xbl:handler event="fr-show-toc" phase="target">\n                <xf:action if="$local/separate-toc/data(.)">\n                    <xf:setvalue\n                        ref="$local/show-toc"\n                        value="true()"/>\n                    <xf:setvalue\n                        ref="$local/show-body"\n                        value="false()"/>\n                </xf:action>\n            </xbl:handler>\n            <xbl:handler event="fr-update-validity" phase="target">\n                <!-- NOTE: The target shouldn\'t be in the outer scope ideally. -->\n                <xf:dispatch\n                    name="fr-wizard-update-validity"\n                    targetid="fr-wizard-update-validity"\n                    xxbl:scope="outer"/>\n            </xbl:handler>\n            <xbl:handler event="fr-visit-all fr-show-relevant-errors" phase="target">\n                <!-- See https://github.com/orbeon/orbeon-forms/issues/3178 -->\n                <xf:var\n                    xxbl:scope="outer"\n                    name="target-name"\n                    value="\n                        if (xxf:instance(\'local\')/validate/data(.) = \'free\') then\n                            \'fr-wizard-visit-all\'\n                        else\n                            \'fr-wizard-visit-all-available\'\n                "/>\n\n                <!-- NOTE: The target shouldn\'t be in the outer scope ideally. -->\n                <xf:dispatch\n                    name="{$target-name}"\n                    targetid="{$target-name}"\n                    xxbl:scope="outer"/>\n\n                <!-- So if the captcha is invalid, its error shows in the error summary. This is needed in addition -->\n                <!-- to the event we dispatch above as the captcha isn\'t inside the switch, as we don\'t want to have -->\n                <!-- one instance of the captcha per top-level section. -->\n                <xxf:setvisited\n                    control="fr-captcha"\n                    visited="true"\n                    recurse="true"/>\n\n            </xbl:handler>\n            <xbl:handler event="fr-verify" phase="target">\n                <xf:dispatch name="fr-verify" targetid="fr-captcha"/>\n            </xbl:handler>\n            <!-- For client-side API -->\n            <xbl:handler event="fr-wizard-focus" phase="target">\n\n                <!-- TODO: Support `lax` and `strict` modes. -->\n                <xf:action if="xxf:instance(\'local\')/validate/data(.) = \'free\'">\n\n                    <xf:setfocus\n                        control="{event(\'fr-control-name\')}-control"\n                        xxf:repeat-indexes="{event(\'fr-repeat-indexes\')}"\n                        xxbl:scope="outer"/>\n\n                </xf:action>\n\n            </xbl:handler>\n            <!-- When a page/section is shown, create the associated `fr:section-status` attribute if needed -->\n            <!-- NOTE: 2018-08-07: This is done only for *top-level* pages. -->\n            <xbl:handler event="fr-section-shown" phase="target">\n\n                <xf:var\n                    name="section-binding"\n                    value="event(\'section-binding\')"/>\n\n                <xf:insert\n                    if="not(exists($section-binding/@fr:section-status))"\n                    xxf:structural-dependencies="false"\n                    context="$section-binding"\n                    origin="xf:attribute(\'fr:section-status\', \'\')"/>\n\n                <!-- NOTE: No need to update the section status here, as the `xf:insert` will cause a subsequent refresh. -->\n\n            </xbl:handler>\n        </xbl:handlers>\n        <xbl:implementation>\n            <xf:model>\n                <xf:instance id="local" xxf:expose-xpath-types="true" xxf:exclude-result-prefixes="#all">\n                    <_>\n                        <current-case-id/>\n                        <current-top-level-case-id/>\n                        <current-index/>\n                        <show-toc/>\n                        <show-body/>\n                        <readwrite/>\n\n                        <validate/>\n                        <separate-toc/>\n                        <section-status/>\n                    </_>\n                </xf:instance>\n\n                <xf:var name="local" value="instance(\'local\')"/>\n\n                <xf:bind ref="validate"                         xxf:default="Wizard:normalizeWizardMode(fr:component-param-value(\'validate\'))"/>\n                <xf:bind ref="separate-toc"   type="xs:boolean" xxf:default="(fr:component-param-value(\'separate-toc\'),   \'false\')[1]"/>\n                <xf:bind ref="section-status" type="xs:boolean" xxf:default="../separate-toc/data(.) or fr:component-param-value(\'section-status\') = \'true\'"/>\n\n                <xf:bind ref="current-index"  type="xs:integer" xxf:default="1"/>\n                <xf:bind ref="show-toc"       type="xs:boolean" xxf:default="true()"/>\n                <xf:bind ref="show-body"      type="xs:boolean" xxf:default="not(../separate-toc/data(.))"/>\n\n                <xf:instance id="available-top-level-sections" xxf:expose-xpath-types="true" xxf:exclude-result-prefixes="#all">\n                    <_/>\n                </xf:instance>\n\n            </xf:model>\n        </xbl:implementation>\n        <xbl:template xxbl:transform="oxf:unsafe-xslt">\n            <xsl:transform version="2.0">\n                <xsl:import href="oxf:/oxf/xslt/utils/copy-modes.xsl"/>\n\n                <!-- `app` and `form` must be passed as attributes (see view.xsl) -->\n                <xsl:variable name="static-app"             select="/*/@app/string()"/>\n                <xsl:variable name="static-form"            select="/*/@form/string()"/>\n                <xsl:variable name="static-validate"        select="/*/@validate/string()"/>        <!-- This is the `free|lax|strict` Form Runner validation mode. -->\n                <xsl:variable name="static-validation-mode" select="/*/@validation-mode/string()"/> <!-- This is the `incremental|explicit` Form Runner validation mode. -->\n\n                <xsl:variable\n                    xmlns:p="http://www.orbeon.com/oxf/pipeline"\n                    name="static-subsections-nav"\n                    select="\n                        (\n                            for $a in /*/@subsections-nav return $a = \'true\', (: takes precedence if present :)\n                            p:property(string-join((\'oxf.xforms.xbl.fr.wizard.subsections-nav\', $static-app, $static-form), \'.\')) = true(),\n                            false()\n                        )[1]\n                    "\n                    as="xs:boolean"/>\n\n                <!-- `all | active | none` -->\n                <xsl:variable\n                    xmlns:p="http://www.orbeon.com/oxf/pipeline"\n                    name="static-subsections-toc"\n                    select="\n                        (\n                            /*/@subsections-toc, (: takes precedence if present :)\n                            p:property(string-join((\'oxf.xforms.xbl.fr.wizard.subsections-toc\', $static-app, $static-form), \'.\'))[. = (\'all\', \'none\')],\n                            \'active\'\n                        )[1]"\n                    as="xs:string"/>\n\n                <xsl:variable\n                    name="static-nav-sections-or-grids"\n                    select="\n                        if ($static-subsections-nav) then\n                            /*//(\n                                fr:section[\n                                    (\n                                        (: Top-level section :)\n                                        count(ancestor::fr:section) = 0 and (\n                                            empty(fr:section)          or\n                                            @subsections-nav = \'false\' or\n                                            frf:isRepeat(.)\n                                        )\n                                    ) or (\n                                        (: First-level subsection :)\n                                        count(ancestor::fr:section) = 1    and\n                                        not(../@subsections-nav = \'false\') and\n                                        not(frf:isRepeat(..))\n                                    )\n                                ],\n                                (: Grid within a top-level section which also contains subsections\n                                   and top-level section doesn\'t have Subsection navigation explicitly\n                                   disabled and is not repeated :)\n                                fr:grid[\n                                    count(ancestor::fr:section) = 1    and\n                                    not(../@subsections-nav = \'false\') and\n                                    not(frf:isRepeat(..))              and\n                                    exists((preceding-sibling::fr:section | following-sibling::fr:section))\n                                ]\n                            )\n                        else\n                            (: Top-level sections :)\n                            /*/fr:section\n                "/>\n\n                <!-- Make sure that duplicates are kept, see https://github.com/orbeon/orbeon-forms/issues/3516 -->\n                <xsl:variable\n                    name="static-matching-top-level-section-ids"\n                    select="\n                        for $s in $static-nav-sections-or-grids\n                        return $s/ancestor-or-self::fr:section[last()]/@id/string()\n                "/>\n\n                <xsl:variable\n                    name="static-nav-section-or-grid-ids"\n                    select="$static-nav-sections-or-grids/((@id/string(), concat(generate-id(), \'-wizard-grid\'))[1])"/>\n\n                <xsl:variable\n                    name="static-top-level-section-ids"\n                    select="/*/fr:section/@id/string()"/>\n\n                <xsl:variable\n                    name="static-sections-with-paging-section-ids"\n                    select="/*//fr:section[@page-size = \'1\']/@id/string()"/>\n\n                <xsl:variable\n                    name="static-sections-with-paging-case-ids"\n                    select="for $id in $static-sections-with-paging-section-ids return concat($id, \'-case\')"/>\n\n                <xsl:variable\n                    name="static-lazy-section-relevance"\n                    select="\n                        (: limited to `free` mode :)\n                        $static-validate = \'free\' and\n                        (: enabled by property :)\n                        p:property(\n                            string-join(\n                                (\'oxf.xforms.xbl.fr.wizard.lazy-section-relevance\', $static-app, $static-form),\n                                \'.\'\n                            )\n                        ) = true()"/>\n\n                <xsl:template match="/*">\n                    <xf:group appearance="xxf:internal">\n                        <xf:group\n                            class="fr-wizard-toc{{\n                                \' xforms-hidden\'         [not($local/show-toc/data(.))],\n                                \' fr-wizard-separate-toc\'[$local/separate-toc/data(.)]\n                            }}">\n\n                            <!-- Dispatch fr-toc-shown event as needed -->\n                            <xf:group appearance="xxf:internal" ref=".[$local/show-toc/data(.)]">\n                                <xf:action\n                                    event="xforms-enabled"\n                                    target="#observer">\n\n                                    <xf:dispatch\n                                        name="fr-toc-shown"\n                                        targetid="fr-wizard">\n                                        <xf:property name="validate"     value="$local/validate/data(.)"/>\n                                        <xf:property name="separate-toc" value="$local/separate-toc/data(.)"/>\n                                    </xf:dispatch>\n                                </xf:action>\n                            </xf:group>\n\n                            <xf:group\n                                xxbl:scope="outer"\n                                id="fr-wizard-outer-group"\n                                class="fr-wizard-toc-inner"\n                                xxf:element="div">\n\n                                <!-- Statically-known section and grid ids -->\n                                <xf:var\n                                    name="nav-section-or-grid-ids"\n                                    value="({\n                                        string-join(\n                                            for $id in $static-nav-section-or-grid-ids\n                                                return concat(\'\'\'\', $id, \'\'\'\'),\n                                            \',\'\n                                        )\n                                    })"/>\n\n                                <xf:var\n                                    name="nav-matching-top-level-section-ids"\n                                    value="({\n                                        string-join(\n                                            for $id in $static-matching-top-level-section-ids\n                                                return concat(\'\'\'\', $id, \'\'\'\'),\n                                            \',\'\n                                        )\n                                    })"/>\n\n                                <xf:var\n                                    name="top-level-section-ids"\n                                    value="({\n                                        string-join(\n                                            for $id in $static-top-level-section-ids\n                                                return concat(\'\'\'\', $id, \'\'\'\'),\n                                            \',\'\n                                        )\n                                    })"/>\n\n                                <xf:var\n                                    name="sections-with-paging-section-ids"\n                                    value="({\n                                        string-join(\n                                            for $id in $static-sections-with-paging-section-ids\n                                                return concat(\'\'\'\', $id, \'\'\'\'),\n                                            \',\'\n                                        )\n                                    })"/>\n\n                                <xf:var\n                                    name="sections-with-paging-case-ids"\n                                    value="({\n                                        string-join(\n                                            for $id in $static-sections-with-paging-case-ids\n                                                return concat(\'\'\'\', $id, \'\'\'\'),\n                                            \',\'\n                                        )\n                                    })"/>\n\n                                <xf:var\n                                    name="validated-mode"\n                                    value="xxf:instance(\'local\')/validate/data(.) != \'free\'"/>\n\n                                <xf:var\n                                    name="separate-toc-mode"\n                                    value="xxf:instance(\'local\')/separate-toc/data(.)"/>\n\n                                <xf:var\n                                    name="relevant-nav-section-or-grid-ids"\n                                    value="\n                                        $nav-section-or-grid-ids[\n                                            for $section-or-grid-bind in bind(frf:bindId(frf:controlNameFromId(.)))\n                                            return\n                                                xxf:relevant($section-or-grid-bind) and (\n                                                    not(\n                                                        . = $sections-with-paging-section-ids and\n                                                        empty($section-or-grid-bind/*)\n                                                    )\n                                                )\n                                        ]"/>\n\n                                <xf:var\n                                    name="relevant-top-level-section-ids"\n                                    value="\n                                        $top-level-section-ids[\n                                            for $top-level-section-bind in bind(frf:bindId(frf:controlNameFromId(.)))\n                                            return\n                                                xxf:relevant($top-level-section-bind)\n                                        ]"/>\n\n                                <xf:var\n                                    name="relevant-nav-case-ids"\n                                    value="\n                                        for $section-id in $relevant-nav-section-or-grid-ids\n                                        return concat($section-id, \'-case\')"/>\n\n                                <xf:var\n                                    name="relevant-top-level-case-ids"\n                                    value="\n                                        for $section-id in $relevant-top-level-section-ids\n                                        return concat($section-id, \'-case\')"/>\n\n                                <!-- HACK: Dependency bug, using `xf:random()` to force recalculation -->\n                                <xf:var\n                                    name="current-top-level-case-id"\n                                    value="(xxf:instance(\'local\')/current-top-level-case-id/string(), xf:random())[1]"/>\n\n                                <!-- NOTE: Initially, current-case-id might be empty, so default to the first relevant case id. -->\n                                <xf:var\n                                    name="current-nav-case-id"\n                                    value="\n                                        (\n                                            xxf:instance(\'local\')/current-case-id[xxf:non-blank()]/string(),\n                                            $relevant-nav-case-ids\n                                        )[1]"/>\n\n                                <xf:var\n                                    name="nav-case-index"\n                                    value="index-of($relevant-nav-case-ids, $current-nav-case-id)"/>\n\n                                <xf:var\n                                    name="top-level-case-index"\n                                    value="index-of($relevant-top-level-case-ids, $current-top-level-case-id)"/>\n\n                                <xf:var\n                                    name="prev-nav-case-ids"\n                                    value="$relevant-nav-case-ids[position() lt $nav-case-index]"/>\n\n                                <xf:var\n                                    name="next-nav-case-ids"\n                                    value="$relevant-nav-case-ids[position() gt $nav-case-index]"/>\n\n                                <xf:var\n                                    name="next-top-level-case-ids"\n                                    value="$relevant-top-level-case-ids[position() gt $top-level-case-index]"/>\n\n                                <xf:var\n                                    name="current-section-uses-paging"\n                                    value="$current-nav-case-id = $sections-with-paging-case-ids"/>\n\n                                <xf:var\n                                    name="current-repeat-id-and-index-opt"\n                                    value="\n                                        if ($current-section-uses-paging) then\n                                            let $section-id    := Wizard:sectionIdFromCaseIdOpt($current-nav-case-id),\n                                                $repeat-id     := concat($section-id, \'-repeater-repeat\'),\n                                                $current-index := xxf:instance(\'local\')/current-index/data(.)\n                                            return\n                                                ($repeat-id, $current-index)\n                                        else\n                                            ()\n                                    "/>\n\n                                <xf:var\n                                    name="prev-repeat-id-and-index-opt"\n                                    value="\n                                        if ($current-section-uses-paging) then\n                                            let $section-id    := Wizard:sectionIdFromCaseIdOpt($current-nav-case-id),\n                                                $repeat-id     := concat($section-id, \'-repeater-repeat\'),\n                                                $current-index := xxf:instance(\'local\')/current-index/data(.)\n                                            return\n                                                if ($current-index gt 1) then\n                                                    ($repeat-id, $current-index - 1)\n                                                else\n                                                    ()\n                                        else\n                                            ()\n                                    "/>\n\n                                <xf:var\n                                    name="next-repeat-id-and-index-opt"\n                                    value="\n                                        if ($current-section-uses-paging) then\n                                            let $section-id    := Wizard:sectionIdFromCaseIdOpt($current-nav-case-id),\n                                                $repeat-id     := concat($section-id, \'-repeater-repeat\'),\n                                                $current-index := xxf:instance(\'local\')/current-index/data(.),\n                                                $section-bind  := bind(frf:bindId(frf:controlNameFromId($section-id))),\n                                                $last-index    := count($section-bind/*)\n                                            return\n                                                if ($current-index lt $last-index) then\n                                                    ($repeat-id, $current-index + 1)\n                                                else\n                                                    ()\n                                        else\n                                            ()\n                                    "/>\n\n                                <xf:var\n                                    name="next-nested-case-id-opt"\n                                    value="\n                                        let $next-nav-case-id := $next-nav-case-ids[1]\n                                        return\n                                            $next-nav-case-id[\n                                                Wizard:sectionIdFromCaseIdOpt($current-top-level-case-id) =\n                                                    $nav-matching-top-level-section-ids[\n                                                        index-of(\n                                                            $nav-section-or-grid-ids,\n                                                            Wizard:sectionIdFromCaseIdOpt($next-nav-case-id)\n                                                        )\n                                                    ]\n                                            ]\n                                    "/>\n\n                                <xf:var\n                                    name="next-top-level-case-id-opt"\n                                    value="\n                                        let $next-top-level-case-id := $next-top-level-case-ids[1]\n                                        return\n                                            (: Exists and is available :)\n                                            $next-top-level-case-id[\n                                                exists(\n                                                    index-of(\n                                                        xxf:split(xxf:instance(\'available-top-level-sections\')),\n                                                        frf:controlNameFromIdOpt(Wizard:sectionIdFromCaseIdOpt($next-top-level-case-id))\n                                                    )\n                                                )\n                                            ]\n                                    "/>\n\n                                <xf:var\n                                    id="fr-wizard-allow-prev"\n                                    name="allow-prev"\n                                    value="\n                                        exists($prev-repeat-id-and-index-opt) or\n                                        exists($prev-nav-case-ids)\n                                    "/>\n\n                                <xf:var\n                                    id="fr-wizard-allow-next"\n                                    name="allow-next"\n                                    value="\n                                        (: We can go to the next top-level section :)\n                                        exists($next-top-level-case-id-opt) or\n                                        (: We can go to the next repeated section iteration :)\n                                        exists($next-repeat-id-and-index-opt) or\n                                        (: Next is in the same top-level section :)\n                                        exists($next-nested-case-id-opt)\n                                    "/>\n\n                                <!-- Wizard.scala uses this via the variable `id` -->\n                                <xf:var\n                                    id="fr-wizard-is-first-nav"\n                                    name="is-first-nav"\n                                    value="empty($prev-nav-case-ids)"/>\n\n                                <!-- Wizard.scala uses this via the variable `id` -->\n                                <xf:var\n                                    id="fr-wizard-is-last-nav"\n                                    name="is-last-nav"\n                                    value="empty($next-nav-case-ids)"/>\n\n                                <xf:var name="prev-button-ref" value="if (not($is-first-nav)) then xxf:instance(\'local\')/readwrite else \'\'"/>\n                                <xf:var name="next-button-ref" value="if (not($is-last-nav))  then xxf:instance(\'local\')/readwrite else \'\'"/>\n\n                                <xf:action event="fr-prev-internal">\n                                    <xf:action if="$allow-prev">\n                                        <xf:action if="exists($prev-repeat-id-and-index-opt)">\n                                            <xf:var name="new-index" value="$prev-repeat-id-and-index-opt[2]"/>\n                                            <xf:setvalue\n                                                ref="xxf:instance(\'local\')/current-index"\n                                                value="$new-index"/>\n                                            <xf:setindex\n                                                repeat="{{$prev-repeat-id-and-index-opt[1]}}"\n                                                index="$new-index"/>\n                                        </xf:action>\n                                        <xf:action if="empty($prev-repeat-id-and-index-opt)">\n                                            <xf:var name="prev-case-id" value="$prev-nav-case-ids[last()]"/>\n                                            <xf:toggle\n                                                case="{{$prev-case-id}}"/>\n                                            <xf:action if="$prev-case-id = $sections-with-paging-case-ids">\n                                                <xf:var name="section-id" value="Wizard:sectionIdFromCaseIdOpt($prev-case-id)"/>\n                                                <xf:var name="new-index" value="count(xxf:binding($section-id)/*)"/>\n                                                <xf:setvalue\n                                                    ref="xxf:instance(\'local\')/current-index"\n                                                    value="$new-index"/>\n                                                <xf:setindex\n                                                    repeat="{{concat($section-id, \'-repeater-repeat\')}}"\n                                                    index="$new-index"/>\n                                            </xf:action>\n                                            <xsl:if test="p:property(string-join((\'oxf.fr.detail.initial-focus\', $static-app, $static-form), \'.\'))">\n                                                <xf:setfocus\n                                                    control="{{$prev-case-id}}"\n                                                    includes="{{frf:xpathFormRunnerStringProperty(\'oxf.fr.detail.focus.includes\')}}"\n                                                    excludes="{{frf:xpathFormRunnerStringProperty(\'oxf.fr.detail.focus.excludes\')}}"/>\n                                            </xsl:if>\n                                        </xf:action>\n                                    </xf:action>\n                                </xf:action>\n\n                                <xf:action event="fr-next-internal">\n                                    <xf:dispatch\n                                        name="fr-wizard-update-validity"\n                                        targetid="fr-wizard-update-validity"/>\n                                    <xf:dispatch\n                                        name="fr-wizard-visit-all-to-current"\n                                        targetid="fr-wizard-visit-all-to-current"/>\n                                    <xf:action if="$allow-next">\n                                        <xf:action if="exists($next-repeat-id-and-index-opt)">\n                                            <xf:var name="new-index" value="$next-repeat-id-and-index-opt[2]"/>\n                                            <xf:setvalue\n                                                ref="xxf:instance(\'local\')/current-index"\n                                                value="$new-index"/>\n                                            <xf:setindex\n                                                repeat="{{$next-repeat-id-and-index-opt[1]}}"\n                                                index="$new-index"/>\n                                        </xf:action>\n                                        <xf:action if="empty($next-repeat-id-and-index-opt)">\n                                            <xf:var name="next-case-id" value="$next-nav-case-ids[1]"/>\n                                            <xf:toggle\n                                                case="{{$next-case-id}}"/>\n                                            <xf:action if="$next-case-id = $sections-with-paging-case-ids">\n                                                <xf:var name="section-id" value="Wizard:sectionIdFromCaseIdOpt($next-case-id)"/>\n                                                <xf:var name="new-index" value="1"/>\n                                                <xf:setvalue\n                                                    ref="xxf:instance(\'local\')/current-index"\n                                                    value="$new-index"/>\n                                                <xf:setindex\n                                                    repeat="{{concat($section-id, \'-repeater-repeat\')}}"\n                                                    index="$new-index"/>\n                                            </xf:action>\n                                            <xsl:if test="p:property(string-join((\'oxf.fr.detail.initial-focus\', $static-app, $static-form), \'.\'))">\n                                                <xf:setfocus\n                                                    control="{{$next-case-id}}"\n                                                    includes="{{frf:xpathFormRunnerStringProperty(\'oxf.fr.detail.focus.includes\')}}"\n                                                    excludes="{{frf:xpathFormRunnerStringProperty(\'oxf.fr.detail.focus.excludes\')}}"/>\n                                            </xsl:if>\n                                        </xf:action>\n                                    </xf:action>\n                                    <xf:action if="not($allow-next)">\n                                        <xsl:if test="p:property(string-join((\'oxf.fr.detail.initial-focus\', $static-app, $static-form), \'.\'))">\n                                            <xf:setfocus\n                                                control="{{$current-nav-case-id}}"\n                                                includes="{{frf:xpathFormRunnerStringProperty(\'oxf.fr.detail.focus.includes\')}}"\n                                                excludes="{{frf:xpathFormRunnerStringProperty(\'oxf.fr.detail.focus.excludes\')}}"/>\n                                        </xsl:if>\n                                    </xf:action>\n                                </xf:action>\n\n                                <!-- We put this here because we need `$relevant-top-level-section-ids` -->\n                                <xf:action event="fr-update-section-status">\n\n                                    <xf:var\n                                        name="maps"\n                                        value="Wizard:gatherTopLevelSectionStatusJava($relevant-top-level-section-ids)"/>\n\n                                    <!-- Update available sections instance -->\n                                    <!-- We do this because we don\'t want to run `Wizard:gatherSectionStatusJava` at each refresh, and we want to\n                                         depend on instance values, although in practice it might not make much of a difference. -->\n                                    <xf:setvalue\n                                        ref="xxf:instance(\'available-top-level-sections\')"\n                                        value="\n                                            string-join(\n                                                for $m in $maps\n                                                return\n                                                    if (map:get($m, \'is-available\')) then map:get($m, \'name\') else (),\n                                                \' \'\n                                            )"/>\n\n                                    <!-- Update section statuses for all relevant sections -->\n                                    <xf:action iterate="$relevant-top-level-section-ids">\n\n                                        <xf:var\n                                            name="section-binding"\n                                            value="xxf:binding(.)"/>\n\n                                        <xf:action if="exists($section-binding/@fr:section-status)">\n\n                                            <xf:var\n                                                name="map"\n                                                value="\n                                                    for $m in $maps\n                                                    return\n                                                        if (map:get($m, \'name\') = name($section-binding)) then $m else ()"/>\n\n                                            <xf:var\n                                                name="existing-tokens"\n                                                value="\n                                                    distinct-values(\n                                                        xxf:split($section-binding/@fr:section-status)\n                                                    )"/>\n\n                                            <xf:var\n                                                name="new-tokens"\n                                                value="\n                                                    distinct-values(\n                                                        (\n                                                            $existing-tokens[\n                                                                not(. = (\n                                                                    \'incomplete\',\n                                                                    \'invalid\',\n                                                                    \'visible-incomplete\',\n                                                                    \'visible-invalid\'\n                                                                    )\n                                                                )\n                                                            ], (: these toggle so remove them first :)\n                                                            \'incomplete\'        [exists($map) and map:get($map, \'has-incomplete-fields\')],\n                                                            \'invalid\'           [exists($map) and map:get($map, \'has-error-fields\')],\n                                                            \'visible-incomplete\'[exists($map) and map:get($map, \'has-visible-incomplete-fields\')],\n                                                            \'visible-invalid\'   [exists($map) and map:get($map, \'has-visible-error-fields\')]\n                                                        )\n                                                    )"/>\n\n                                            <xf:setvalue\n                                                if="not(count($existing-tokens) = count($new-tokens) and empty($existing-tokens[not(. = $new-tokens)]))"\n                                                ref="$section-binding/@fr:section-status"\n                                                value="string-join($new-tokens, \' \')"/>\n\n                                        </xf:action>\n                                    </xf:action>\n                                </xf:action>\n\n                                <!-- This id is used to expose visibility to buttons outside the wizard -->\n                                <xf:group\n                                    id="fr-wizard-submit-hide"\n                                    ref="xxf:instance(\'local\')/readwrite[not($validated-mode) or empty($next-top-level-case-ids)]"/>\n\n                                <xh:div role="navigation">\n                                    <xh:ul class="nav nav-list">\n                                        <xsl:apply-templates mode="toc-sections"/>\n                                    </xh:ul>\n                                </xh:div>\n\n                                <xh:div class="fr-wizard-navigation{{if (xxf:instance(\'local\')/separate-toc/data(.)) then \' xforms-hidden\' else \'\'}}">\n\n                                    <xf:action event="xforms-enabled" target="#observer">\n\n                                        <!-- Make sure the first relevant case is shown initially -->\n                                        <!-- NOTE: Ideally, we should also handle the case where the fr:section in the\n                                             currently-selected case becomes non-relevant. However, this should not happen\n                                             in a well-designed form (that would be very user unfriendly). If xf:case supported\n                                             relevance, we might be able to let this behavior be handled by the XForms engine.\n                                         -->\n                                        <!-- Find the last available AND visited section -->\n                                        <xf:var\n                                            name="last-available-and-visited-top-level-section-id"\n                                            value="\n                                                (\n                                                    (: First relevant section by default :)\n                                                    $relevant-top-level-section-ids[1],\n                                                    (: But also check subsequent sections for availability and visited :)\n                                                    (\n                                                        for $id in $relevant-top-level-section-ids[position() gt 1]\n                                                        return\n                                                            if (\n                                                                exists(\n                                                                    index-of(\n                                                                        xxf:split(xxf:instance(\'available-top-level-sections\')),\n                                                                        frf:controlNameFromIdOpt($id)\n                                                                    )\n                                                                ) and\n                                                                    exists(xxf:binding($id)/@fr:section-status)\n                                                            ) then\n                                                                $id\n                                                            else\n                                                                ()\n                                                    )\n                                                )[last()]"/>\n\n                                        <!-- Set initial current section -->\n                                        <xf:action if="exists($last-available-and-visited-top-level-section-id)">\n\n                                            <xf:var\n                                                name="last-available-and-visited-top-level-case-id"\n                                                value="concat($last-available-and-visited-top-level-section-id, \'-case\')"/>\n\n                                            <xf:var\n                                                name="initial-case-id"\n                                                value="\n                                                    (\n                                                        Wizard:caseIdsForTopLevelSection($last-available-and-visited-top-level-section-id)[1],\n                                                        $last-available-and-visited-top-level-case-id\n                                                    )[1]"/>\n\n                                            <xf:setvalue\n                                                ref="xxf:instance(\'local\')/current-case-id"\n                                                value="$initial-case-id"/>\n\n                                            <xf:setvalue\n                                                ref="xxf:instance(\'local\')/current-top-level-case-id"\n                                                value="case(\'switch\')"/>\n\n                                            <!-- See https://github.com/orbeon/orbeon-forms/issues/3433 -->\n                                            <xf:toggle\n                                                case="{{$initial-case-id}}"/>\n\n                                            <!-- Dispatch `fr-section-shown` the first time the body is shown if needed -->\n                                            <xf:action if="xxf:instance(\'local\')/show-body/data(.)">\n                                                <xf:dispatch name="fr-section-shown" targetid="fr-wizard" xxbl:scope="inner">\n                                                    <xf:property name="section-binding" value="xxf:binding($last-available-and-visited-top-level-section-id)"              xxbl:scope="outer"/>\n                                                    <xf:property name="section-name"    value="frf:controlNameFromIdOpt($last-available-and-visited-top-level-section-id)" xxbl:scope="outer"/>\n                                                    <xf:property name="validate"        value="xxf:instance(\'local\')/validate/data(.)"/>\n                                                    <xf:property name="separate-toc"    value="xxf:instance(\'local\')/separate-toc/data(.)"/>\n                                                </xf:dispatch>\n                                            </xf:action>\n\n                                        </xf:action>\n\n                                    </xf:action>\n\n                                    <xh:div class="pagination pagination-centered">\n                                        <xh:ul>\n                                            <xh:li class="{{if ($prev-button-ref instance of xs:string) then \'disabled\' else \'\'}}">\n                                                <xf:trigger id="fr-wizard-prev"  ref="$prev-button-ref" appearance="minimal" class="fr-wizard-prev">\n                                                    <xf:label><xh:i class="fa fa-fw fa-chevron-left"/></xf:label>\n                                                    <xf:action event="DOMActivate" type="xpath">\n                                                        fr:run-process-by-name(\'oxf.fr.detail.process\', \'wizard-prev\')\n                                                    </xf:action>\n                                                </xf:trigger>\n                                            </xh:li>\n                                            <xh:li>\n                                                <xh:span class="fr-page-number">\n                                                    <xf:output value="\n                                                        sum(\n                                                            (\n                                                                if (exists($prev-repeat-id-and-index-opt)) then\n                                                                    $prev-repeat-id-and-index-opt[2] + 1\n                                                                else\n                                                                    1,\n                                                                for $case-id in $prev-nav-case-ids\n                                                                return\n                                                                    if (\n                                                                        $case-id = $sections-with-paging-case-ids\n                                                                    ) then\n                                                                        count(xxf:binding(Wizard:sectionIdFromCaseIdOpt($case-id))/*)\n                                                                    else\n                                                                        1\n                                                            )\n                                                        )"/>\n\n                                                    <xf:output value="concat(\' \', $fr-resources/summary/paging/of, \' \')"/>\n                                                    <xf:output value="\n                                                        sum(\n                                                            (\n                                                                count(\n                                                                    $relevant-nav-case-ids[\n                                                                        not(. = $sections-with-paging-case-ids)\n                                                                    ]\n                                                                ),\n                                                                for $section-id in $sections-with-paging-section-ids\n                                                                return\n                                                                    count(xxf:binding($section-id)/*)\n                                                            )\n                                                        )"/>\n                                                </xh:span>\n                                            </xh:li>\n                                            <xh:li class="{{if ($next-button-ref instance of xs:string) then \'disabled\' else \'\'}}">\n                                                <xf:trigger id="fr-wizard-next" ref="$next-button-ref" appearance="minimal" class="fr-wizard-next">\n                                                    <xf:label><xh:i class="fa fa-fw fa-chevron-right"/></xf:label>\n                                                    <xf:action event="DOMActivate" type="xpath">\n                                                        fr:run-process-by-name(\'oxf.fr.detail.process\', \'wizard-next\')\n                                                    </xf:action>\n                                                </xf:trigger>\n                                            </xh:li>\n                                        </xh:ul>\n\n                                        <!-- NOTE: This shouldn\'t be in the outer scope ideally. -->\n                                        <xf:group id="fr-wizard-update-validity" appearance="xxf:internal">\n                                            <xf:action event="fr-wizard-update-validity">\n                                                <xsl:choose>\n                                                    <xsl:when test="$static-validation-mode = \'explicit\'">\n                                                        <!-- Update validity, refresh, then try again -->\n                                                        <xxf:update-validity\n                                                            control="{{string-join(($prev-nav-case-ids, $current-nav-case-id), \' \')}}"\n                                                            recurse="true"/>\n                                                        <!-- This ensures that when `fr-do-next` runs, UI variables have been updated -->\n                                                        <xf:refresh/>\n                                                    </xsl:when>\n                                                    <xsl:otherwise>\n                                                        <!-- Do action immediately -->\n                                                    </xsl:otherwise>\n                                                </xsl:choose>\n                                            </xf:action>\n                                        </xf:group>\n                                        <xf:group id="fr-wizard-visit-all" appearance="xxf:internal">\n                                            <xf:action event="fr-wizard-visit-all">\n                                                <xf:dispatch\n                                                    iterate="$top-level-section-ids"\n                                                    name="fr-expand"\n                                                    targetid="{{.}}"/>\n\n                                                <!-- Create `fr:section-status` for all top-level sections so that the TOC status updates  -->\n                                                <xf:action iterate="$relevant-top-level-section-ids">\n                                                    <xf:var name="section-binding" value="xxf:binding(.)"/>\n                                                    <xf:insert\n                                                        if="not(exists($section-binding/@fr:section-status))"\n                                                        context="$section-binding"\n                                                        origin="xf:attribute(\'fr:section-status\', \'\')"/>\n                                                </xf:action>\n\n                                                <!-- Avoid extra refreshes at this point: xxf:deferred-updates="false" -->\n                                                <xxf:setvisited\n                                                    xxf:deferred-updates="false"\n                                                    control="switch"\n                                                    visited="true"\n                                                    recurse="true"/>\n                                            </xf:action>\n                                        </xf:group>\n                                        <xf:group id="fr-wizard-visit-all-to-current" appearance="xxf:internal">\n                                            <!-- NOTE: We visit the current page upon xforms-deselect too. -->\n                                            <xf:action event="fr-wizard-visit-all-to-current">\n                                                <!-- This is called upon "next". -->\n                                                <!-- The current section, since it is current, is obviously already\n                                                     expanded. So we make sure we expand anything before it. -->\n                                                <xf:dispatch\n                                                    iterate="\n                                                        distinct-values(\n                                                            for $prev-nav-case-id in $prev-nav-case-ids\n                                                            return\n                                                                $nav-matching-top-level-section-ids[\n                                                                    index-of(\n                                                                        $nav-section-or-grid-ids,\n                                                                        Wizard:sectionIdFromCaseIdOpt($prev-nav-case-id)\n                                                                    )\n                                                                ]\n                                                        )"\n                                                    name="fr-expand"\n                                                    targetid="{{.}}"/>\n\n                                                <xxf:setvisited\n                                                    iterate="$prev-nav-case-ids, if ($current-section-uses-paging) then () else $current-nav-case-id"\n                                                    control="{{.}}"\n                                                    visited="true"\n                                                    recurse="true"/>\n                                                <xxf:setvisited\n                                                    if="$current-section-uses-paging"\n                                                    iterate="1 to $current-repeat-id-and-index-opt[2]"\n                                                    control="{{$current-repeat-id-and-index-opt[1]}}~iteration"\n                                                    xxf:repeat-indexes="{{.}}"\n                                                    visited="true"\n                                                    recurse="true"/>\n                                            </xf:action>\n                                        </xf:group>\n                                        <xf:group id="fr-wizard-visit-all-available" appearance="xxf:internal">\n                                            <xf:action event="fr-wizard-visit-all-available">\n                                                <!-- Expand all as we want the errors recorded because this is called during `save` and\n                                                     the save must be blocked if there are any errors in the entire form. -->\n                                                <xf:dispatch\n                                                    iterate="$top-level-section-ids"\n                                                    name="fr-expand"\n                                                    targetid="{{.}}"/>\n\n                                                <xf:var\n                                                    name="available-top-level-sections-ids"\n                                                    value="\n                                                        for $section-name in xxf:split(xxf:instance(\'available-top-level-sections\'))\n                                                        return\n                                                            (: See https://github.com/orbeon/orbeon-forms/issues/4022 :)\n                                                            $nav-section-or-grid-ids[frf:controlNameFromId(.) = $section-name]"/>\n\n                                                <!-- Create `fr:section-status` for all top-level sections so that the TOC status updates -->\n                                                <xf:action iterate="$available-top-level-sections-ids">\n                                                    <xf:var name="section-binding" value="xxf:binding(.)"/>\n                                                    <xf:insert\n                                                        if="not(exists($section-binding/@fr:section-status))"\n                                                        context="$section-binding"\n                                                        origin="xf:attribute(\'fr:section-status\', \'\')"/>\n                                                </xf:action>\n\n                                                <xxf:setvisited\n                                                    iterate="\n                                                        for $section-id in $available-top-level-sections-ids\n                                                        return concat($section-id, \'-case\')"\n                                                    control="{{.}}"\n                                                    visited="true"\n                                                    recurse="true"/>\n                                            </xf:action>\n                                        </xf:group>\n                                        <xf:group id="fr-wizard-unvisit-following" appearance="xxf:internal">\n                                            <xxf:setvisited\n                                                event="fr-wizard-unvisit-following"\n\n                                                iterate="$next-nav-case-ids"\n                                                control="{{.}}"\n                                                visited="false"\n                                                recurse="true"/>\n                                            <!-- Q: Should we remove `fr:section-status`? -->\n                                            <!-- NOTE: We *could* collapse the corresponding top-level sections. -->\n                                        </xf:group>\n                                        <xf:group id="fr-wizard-section-deselected" appearance="xxf:internal">\n                                            <xf:action event="fr-wizard-section-deselected">\n                                                <!-- Avoid extra refreshes at this point: xxf:deferred-updates="false" -->\n                                                <xxf:setvisited\n                                                    if="not($current-section-uses-paging)"\n\n                                                    xxf:deferred-updates="false"\n                                                    control="{{event(\'control\')}}"\n                                                    visited="true"\n                                                    recurse="true"/>\n\n                                                <xxf:setvisited\n                                                    if="$current-section-uses-paging"\n                                                    iterate="1 to $current-repeat-id-and-index-opt[2]"\n\n                                                    xxf:deferred-updates="false"\n                                                    control="{{$current-repeat-id-and-index-opt[1]}}~iteration"\n                                                    xxf:repeat-indexes="{{.}}"\n                                                    visited="true"\n                                                    recurse="true"/>\n                                            </xf:action>\n                                            <!-- NOTE: We *could* collapse the corresponding top-level sections. Should we? -->\n                                        </xf:group>\n                                    </xh:div>\n                                </xh:div>\n\n                                <!--\n                                <xf:group>\n                                    <xf:label>Wizard Debugger</xf:label>\n                                    <xh:ul>\n                                        <xh:li>\n                                            available-top-level-sections:\n                                            <xh:ul>\n                                                <xf:repeat ref="xxf:split(xxf:instance(\'available-top-level-sections\'))">\n                                                    <xh:li><xf:output value="."/></xh:li>\n                                                </xf:repeat>\n                                            </xh:ul>\n                                        </xh:li>\n                                        <xh:li>\n                                            nav-section-or-grid-ids (<xf:output value="count($nav-section-or-grid-ids)"/>):\n                                            <xh:ul>\n                                                <xf:repeat ref="$nav-section-or-grid-ids">\n                                                    <xh:li><xf:output value="."/></xh:li>\n                                                </xf:repeat>\n                                            </xh:ul>\n                                        </xh:li>\n                                        <xh:li>\n                                            nav-matching-top-level-section-ids (<xf:output value="count($nav-matching-top-level-section-ids)"/>):\n                                            <xh:ul>\n                                                <xf:repeat ref="$nav-matching-top-level-section-ids">\n                                                    <xh:li><xf:output value="."/></xh:li>\n                                                </xf:repeat>\n                                            </xh:ul>\n                                        </xh:li>\n                                        <xh:li>\n                                            top-level-section-ids (<xf:output value="count($top-level-section-ids)"/>):\n                                            <xh:ul>\n                                                <xf:repeat ref="$top-level-section-ids">\n                                                    <xh:li><xf:output value="."/></xh:li>\n                                                </xf:repeat>\n                                            </xh:ul>\n                                        </xh:li>\n                                        <xh:li>\n                                            sections-with-paging-section-ids (<xf:output value="count($sections-with-paging-section-ids)"/>):\n                                            <xh:ul>\n                                                <xf:repeat ref="$sections-with-paging-section-ids">\n                                                    <xh:li><xf:output value="."/></xh:li>\n                                                </xf:repeat>\n                                            </xh:ul>\n                                        </xh:li>\n                                        </xf:group>\n                                    </xh:div>\n                                </xh:div>\n                            </xf:group>\n                        </xf:group>\n                        <!-- In case the view contains elements other than sections (like dialogs) -->\n                                        </xf:dispatch>\n\n                                        <!-- Check that incoming `xforms-focus` is allowed -->\n                                        <!-- TODO: See https://github.com/orbeon/orbeon-forms/issues/3323. -->\n\n                                        <!-- Un-visit all subsequent sections upon error in current section in `strict` mode -->\n                                        <!-- Use `delay="0"`, so we dispatch all the `fr-wizard-unvisit-following` after all the\n                                             `xforms-invalid`, avoiding a `StackOverflowError` on large forms -->\n                                        <xf:dispatch\n                                            event="xforms-invalid"\n                                            if="xxf:instance(\'local\')/validate/data(.) = \'strict\'"\n\n                                            name="fr-wizard-unvisit-following"\n                                            targetid="fr-wizard-unvisit-following"\n                                            delay="0"/>\n\n                                        <!-- Subsection nav enabled AND the top-level section is not part of the nav, which\n                                             means we navigate it\'s subsections/grids. -->\n                                        <xsl:variable\n                                            name="has-subsections-nav"\n                                            select="$static-subsections-nav and not($static-nav-section-or-grid-ids = @id)"/>\n\n                                        <xf:action event="xforms-select" target="#observer">\n\n                                            <!--\n                                                Keep `current-case-id` and `current-top-level-case-id` up to date.\n\n                                                NOTE: The `xforms-select` event is dispatched at the end of the `xf:toggle` but\n                                                before focus has been adjusted.\n                                            -->\n                                            <xsl:if test="not($has-subsections-nav)">\n                                                <!-- `current-case-id` is the same as `current-top-level-case-id` -->\n                                                <xf:setvalue\n                                                    ref="xxf:instance(\'local\')/current-case-id"\n                                                    value="event(\'xxf:targetid\')"/>\n                                            </xsl:if>\n                                            <xsl:if test="$has-subsections-nav">\n                                                <!-- Either the top-level case doesn\'t change, and then the nexted\n                                                     switch\'s event handler sets this value; or the top-level case\n                                                     changed, and there is a chance that the nested switch didn\'t\n                                                     change its case, in which case we make sure we set it here. If\n                                                     the nested switch changed its case, it already set the value,\n                                                     but that\'s ok. -->\n                                                <xf:setvalue\n                                                    ref="xxf:instance(\'local\')/current-case-id"\n                                                    value="case(\'{$static-section-id}-switch\')"/>\n                                            </xsl:if>\n\n                                            <xf:setvalue\n                                                ref="xxf:instance(\'local\')/current-top-level-case-id"\n                                                value="event(\'xxf:targetid\')"/>\n\n                                            <xf:dispatch name="fr-section-scroll" targetid="switch"/>\n\n                                            <xf:var\n                                                name="section-id"\n                                                value="Wizard:sectionIdFromCaseIdOpt(event(\'xxf:targetid\'))"\n                                                xxbl:scope="inner"/>\n\n                                            <xf:dispatch targetid="{{Wizard:sectionIdFromCaseIdOpt(event(\'xxf:targetid\'))}}" name="fr-expand"/>\n\n                                            <!-- NOTE: 2020-01-23: This is dispatched only for *top-level* pages. -->\n                                            <xf:dispatch name="fr-section-shown" targetid="fr-wizard" xxbl:scope="inner">\n                                                <xf:property name="section-binding" value="xxf:binding(Wizard:sectionIdFromCaseIdOpt(event(\'xxf:targetid\')))" xxbl:scope="outer"/>\n                                                <xf:property name="section-name"    value="frf:controlNameFromIdOpt($section-id)"/>\n                                                <xf:property name="validate"        value="$local/validate/data(.)"/>\n                                                <xf:property name="separate-toc"    value="$local/separate-toc/data(.)"/>\n                                            </xf:dispatch>\n\n                                        </xf:action>\n\n                                        <xf:group appearance="xxf:internal"><!-- Q: Why this group? -->\n                                            <!-- This is where the original section\'s attribute are being copied, including `id` and `bind` -->\n                                            <xsl:copy><!-- `<fr:section>` -->\n                                                <xsl:attribute name="view-appearance">wizard</xsl:attribute>\n                                                <xsl:attribute name="collapsible">false</xsl:attribute>\n                                                <xsl:apply-templates select="@* except (@collapse | @collapsible | @open)"/>\n                                                <!-- Tell the section whether it needs to be initially open or not (optimization).\n                                                     We can\'t enable this yet in `lax|strict` mode, see:\n                                                     https://github.com/orbeon/orbeon-forms/issues/4790#issuecomment-791652516 -->\n                                                <xsl:attribute\n                                                    name="content-nonrelevant-if-collapsed"\n                                                    select="$static-lazy-section-relevance"/>\n                                                <xsl:attribute\n                                                    name="open"\n                                                    select="concat(\'{case(\'\'switch\'\') = \'\'\', $static-section-id, \'-case\'\'}\')"/>\n\n                                                <!-- Update the `changed` token -->\n                                                <xf:action event="xforms-value-changed">\n                                                    <xf:setvalue\n                                                        ref="@fr:section-status"\n                                                        value="\n                                                            let $tokens := distinct-values(xxf:split(.))\n                                                            return\n                                                                if (empty(index-of($tokens, \'changed\'))) then\n                                                                    string-join(($tokens, \'changed\'), \' \')\n                                                                else\n                                                                    ."/>\n                                                </xf:action>\n\n                                                <xsl:choose>\n                                                    <xsl:when test="$has-subsections-nav">\n\n                                                        <!-- Don\'t forget the enclosing section lHHA -->\n                                                        <xsl:apply-templates select="xf:label | xf:help | xf:hint | xf:alert"/>\n\n                                                        <!-- Subsections -->\n                                                        <xf:switch id="{$static-section-id}-switch" xxf:element="div" xxf:update="full">\n                                                            <xsl:for-each select="fr:section | fr:grid">\n                                                                <!-- fr:grid might not have an id, and we need one to toggle -->\n                                                                <xsl:variable name="section-or-grid-id" select="(@id, concat(generate-id(), \'-wizard-grid\'))[1]"/>\n                                                                <xf:case id="{$section-or-grid-id}-case">\n                                                                    <xxf:setvisited\n                                                                        event="xforms-deselect"\n                                                                        target="#observer"\n                                                                        control="{{event(\'xxf:targetid\')}}"\n                                                                        visited="true"\n                                                                        recurse="true"/>\n                                                                    <xf:action event="xforms-select" target="#observer">\n                                                                        <!-- Keep `current-case-id` up to date in case switch happened via toggling. -->\n                                                                        <xf:setvalue\n                                                                            ref="xxf:instance(\'local\')/current-case-id"\n                                                                            value="event(\'xxf:targetid\')"/>\n\n                                                                        <xf:dispatch name="fr-section-scroll" targetid="switch"/>\n\n                                                                    </xf:action>\n                                                                    <xf:group appearance="xxf:internal">\n                                                                        <xsl:copy>\n                                                                            <xsl:if test="self::fr:section">\n                                                                                <xsl:attribute name="view-appearance">wizard</xsl:attribute>\n                                                                                <xsl:attribute name="collapsible">false</xsl:attribute>\n                                                                            </xsl:if>\n                                                                            <xsl:if test="not(@id)">\n                                                                                <xsl:attribute name="id" select="$section-or-grid-id"/>\n                                                                            </xsl:if>\n                                                                            <xsl:apply-templates select="(@* except (@collapse | @collapsible | @open)) | node()"/>\n                                                                        </xsl:copy>\n                                                                    </xf:group>\n                                                                </xf:case>\n                                                            </xsl:for-each>\n                                                        </xf:switch>\n                                                    </xsl:when>\n                                                    <xsl:otherwise>\n                                                        <!-- No subsection nav -->\n                                                        <xsl:apply-templates select="node()"/>\n                                                    </xsl:otherwise>\n                                                </xsl:choose>\n                                            </xsl:copy>\n                                        </xf:group>\n                                    </xf:case>\n                                </xsl:for-each>\n                            </xf:switch>\n                            <xsl:if test="p:property(string-join((\'oxf.fr.detail.captcha.location\', $static-app, $static-form), \'.\')) = \'inside-wizard\'">\n                                <xf:var name="fr-resources"><xxf:value xxbl:scope="outer" value="$fr-resources"/></xf:var>\n                                <fr:captcha id="fr-captcha" namespace-name="{frf:captchaComponent($static-app, $static-form)}"/>\n                            </xsl:if>\n                        </xh:div>\n                        <!-- In case the view contains elements other than sections (like dialogs) -->\n                        <xh:div class="fr-wizard-other">\n                            <xh:div class="fr-wizard-cell-placeholder"/>\n                            <xf:group appearance="xxf:internal" xxbl:scope="outer">\n                                <xsl:apply-templates select="* except fr:section"/>\n                            </xf:group>\n                        </xh:div>\n                    </xf:group>\n                </xsl:template>\n\n                <!-- TOC: Swallow non-relevant nodes -->\n                <xsl:template match="text()" mode="toc-sections"/>\n                <xsl:template match="*" mode="toc-sections">\n                    <xsl:apply-templates mode="toc-sections"/>\n                </xsl:template>\n\n                <!-- TOC: handle section -->\n                <xsl:template match="fr:section" mode="toc-sections">\n\n                    <xsl:variable\n                        name="static-current-section"\n                        select="."/>\n                    <xsl:variable\n                        name="static-section-id"\n                        select="$static-current-section/@id"/>\n                    <xsl:variable\n                        name="static-is-top-level-section"\n                        select="empty($static-current-section/ancestor::fr:section)"/>\n                    <xsl:variable\n                        name="static-section-has-html-label"\n                        select="$static-current-section/xf:label/@mediatype = \'text/html\'"/>\n                    <xsl:variable\n                        name="static-top-level-section-id"\n                        select="($static-current-section/ancestor-or-self::fr:section/@id)[1]"/>\n                    <xsl:variable\n                        name="static-top-level-section-case-id"\n                        select="concat($static-top-level-section-id, \'-case\')"/>\n                    <xsl:variable\n                        name="use-paging"\n                        select="$static-current-section/@page-size = \'1\'"/>\n\n                    <!-- Propagate binding so that entry for section disappears if the section is non-relevant -->\n                    <xsl:element name="xf:{if ($use-paging) then \'repeat\' else \'group\'}">\n\n                        <xsl:choose>\n                            <xsl:when test="$use-paging">\n                                <xsl:variable\n                                    name="repeat-expression"\n                                    as="xs:string?"\n                                    select="\n                                        (\n                                            $static-current-section/@ref,\n                                            $static-current-section/@nodeset,\n                                            for $b in $static-current-section/@bind\n                                                return\n                                                    concat(\n                                                        \'bind(\'\'\',\n                                                        $b,\n                                                        \'\'\')\'\n                                                    )\n                                        )[1]"/>\n\n                                <xsl:attribute\n                                    name="ref"\n                                    select="concat($repeat-expression, \'/*\')"/>\n                            </xsl:when>\n                            <xsl:otherwise>\n                                <xsl:copy-of select="@model | @context | @bind | @ref"/>\n                            </xsl:otherwise>\n                        </xsl:choose>\n\n                        <xf:var name="top-level-section-available">\n                            <xxf:value\n                                value="\n                                    exists(\n                                        index-of(\n                                            xxf:split(xxf:instance(\'available-top-level-sections\')),\n                                            \'{frf:controlNameFromIdOpt($static-top-level-section-id)}\'\n                                        )\n                                    )"\n                                xxbl:scope="inner"/>\n                        </xf:var>\n\n                        <!-- FIXME: `exists(@fr:section-status)` no longer works, while `exists(@*:section-status)` and\n                              `exists(@fr:section-status/string())` work! -->\n                        <xf:var\n                            name="top-level-section-visited"\n                            value="exists(@fr:section-status/string())"/>\n\n                        <xf:var\n                            name="top-level-section-tokens"\n                            value="xxf:split(@fr:section-status)"/>\n\n                        <xsl:choose>\n                            <xsl:when test="$use-paging">\n                                <xf:var\n                                    name="top-level-section-active"\n                                    value="\n                                        not($separate-toc-mode) and\n                                        $current-top-level-case-id = \'{$static-section-id}-case\' and\n                                        xxf:repeat-position() = xxf:instance(\'local\')/current-index/data(.)"/>\n                                <xf:var\n                                    name="section-active"\n                                    value="\n                                        not($separate-toc-mode) and\n                                        $current-nav-case-id = \'{$static-section-id}-case\' and\n                                        xxf:repeat-position() = xxf:instance(\'local\')/current-index/data(.)"/>\n                            </xsl:when>\n                            <xsl:otherwise>\n                                <xf:var\n                                    name="top-level-section-active"\n                                    value="\n                                        not($separate-toc-mode) and\n                                        $current-top-level-case-id = \'{$static-section-id}-case\'"/>\n                                <xf:var\n                                    name="section-active"\n                                    value="\n                                        not($separate-toc-mode) and\n                                        $current-nav-case-id = \'{$static-section-id}-case\'"/>\n                            </xsl:otherwise>\n                        </xsl:choose>\n\n                        <xsl:variable name="section-label-expr" as="xs:string">\n                            <xsl:choose>\n                                <xsl:when test="$use-paging">\n                                    <xsl:choose>\n                                        <xsl:when test="exists(fr:iteration-label)">\n                                            <xsl:value-of select="\n                                                concat(\n                                                    \'xxf:value(\'\'\',\n                                                    $static-section-id,\n                                                    \'-repeater-iteration-label\'\', false())[xxf:repeat-position()]\'\n                                                )"/>\n                                        </xsl:when>\n                                        <xsl:otherwise>\n                                            <xsl:value-of select="\n                                                concat(\n                                                    \'concat(xxf:label(\'\'\',\n                                                    $static-section-id,\n                                                    \'\'\'), \'\' \'\', xxf:repeat-position())\'\n                                                )"/>\n                                        </xsl:otherwise>\n                                    </xsl:choose>\n                                </xsl:when>\n                                <xsl:otherwise>\n                                    <xsl:value-of select="\n                                        concat(\n                                            \'xxf:label(\'\'\',\n                                            $static-section-id,\n                                            \'\'\')\'\n                                        )"/>\n                                </xsl:otherwise>\n                            </xsl:choose>\n                        </xsl:variable>\n\n                        <xh:li class="{{\n                            \'disabled\'           [not($top-level-section-available)],\n                            \'active\'             [$section-active or $top-level-section-active],\n                            \'started\'            [$top-level-section-visited],\n                            $top-level-section-tokens,\n\n                            \'first-page\'         [$relevant-top-level-case-ids[1]      = \'{concat($static-section-id, \'-case\')}\'],\n                            \'last-top-level-page\'[$relevant-top-level-case-ids[last()] = \'{concat($static-section-id, \'-case\')}\'],\n                            \'last-page\'          [$relevant-nav-case-ids[last()]       = \'{concat($static-section-id, \'-case\')}\']\n                        }}" aria-current="{{\n                            if ($section-active) then \'page\' else \'false\'\n                        }}" aria-disabled="{{\n                            if (not($top-level-section-available)) then \'true\' else \'false\'\n                        }}">\n\n                            <xf:trigger appearance="minimal">\n                                <xf:label>\n                                    <xh:span class="fr-toc-title">\n                                        <xf:output value="{$section-label-expr}">\n                                            <xsl:if test="$static-section-has-html-label"><xsl:attribute name="mediatype">text/html</xsl:attribute></xsl:if>\n                                        </xf:output>\n                                    </xh:span>\n                                    <xh:span class="fr-toc-edit {{\'xforms-hidden\'[not(xxf:instance(\'local\')/section-status/data(.))]}}"><xf:output value="xxf:r(\'components.wizard.edit\', \'|fr-fr-resources|\')"/></xh:span>\n                                    <xsl:if test="$static-is-top-level-section">\n                                        <!-- NOTE: Hide labels when not in `separate-toc` mode as they take a lot of space -->\n                                        <xh:span class="fr-toc-status {{\'xforms-hidden\'[not(xxf:instance(\'local\')/section-status/data(.))]}} label{{\n                                            if ($top-level-section-tokens = \'invalid\') then\n                                                \' label-important\'\n                                            else if ($top-level-section-tokens = \'incomplete\') then\n                                                \' label-warning\'\n                                            else if ($top-level-section-visited) then\n                                                \' label-success\'\n                                            else\n                                                \'\'\n                                        }}"><xf:output value="\n                                                xxf:r(\n                                                    if ($top-level-section-tokens = \'invalid\') then\n                                                        \'components.wizard.errors\'\n                                                    else if ($top-level-section-tokens = \'incomplete\') then\n                                                        \'components.wizard.incomplete\'\n                                                    else if ($top-level-section-visited) then\n                                                        \'components.wizard.complete\'\n                                                    else\n                                                        \'components.wizard.not-started\',\n                                                    \'|fr-fr-resources|\'\n                                                )"/></xh:span>\n                                    </xsl:if>\n                                </xf:label>\n                                <xf:hint value="{$section-label-expr}">\n                                    <xsl:if test="$static-section-has-html-label"><xsl:attribute name="mediatype">text/html</xsl:attribute></xsl:if>\n                                </xf:hint>\n                                <!-- DOMActivate handler which depends on `$static-validation-mode` -->\n                                <xf:action event="DOMActivate">\n                                    <xf:dispatch\n                                        name="fr-wizard-update-validity"\n                                        targetid="fr-wizard-update-validity"/>\n                                    <xf:action if="$top-level-section-available">\n\n                                        <!-- Figure out the nav section id based on whether we support subsection navigation AND where in the hierarchy\n                                             the clicked TOC section is. -->\n                                        <xsl:variable\n                                            name="static-nav-section-id"\n                                            select="\n                                                if ($static-subsections-nav) then\n                                                    (\n                                                        if ($static-is-top-level-section) then\n                                                            (: Current section is a top-level section. Try first subsection or grid if any,\n                                                               otherwise the top-level section itself, which means that there are no subsections\n                                                               or grids. Unfortunately, there is some logic duplication between here and the\n                                                               computation of `$static-nav-sections-or-grids` above. :)\n                                                            (\n                                                                $static-current-section[\n                                                                    not(@subsections-nav = \'false\') and\n                                                                    not(frf:isRepeat(.))            and\n                                                                    exists(fr:section)\n                                                                ]/(fr:section | fr:grid)[1],\n                                                                $static-current-section\n                                                            )[1]\n                                                        else\n                                                            (: Current section is a subsection. Take first subsection from the top, as only two levels of\n                                                               section navigation are supported. :)\n                                                            ($static-current-section/ancestor-or-self::fr:section)[2]\n                                                    )/(\n                                                        @id,\n                                                        concat(generate-id(), \'-wizard-grid\')\n                                                    )[1]\n                                                else\n                                                    $static-top-level-section-id\n                                        "/>\n\n                                        <!-- Remember where we are toggling to, toggle... -->\n                                        <xf:toggle\n                                            case="{$static-nav-section-id}-case"/>\n\n                                        <xsl:if test="$use-paging">\n                                            <xf:var name="new-index" value="xxf:repeat-position()"/>\n                                            <xf:setvalue\n                                                ref="xxf:instance(\'local\')/current-index"\n                                                value="$new-index"/>\n                                            <xf:setindex\n                                                repeat="{$static-section-id}-repeater-repeat"\n                                                index="$new-index"/>\n                                        </xsl:if>\n\n                                        <!-- ...and focus on specific sub-section -->\n                                        <xsl:if test="p:property(string-join((\'oxf.fr.detail.initial-focus\', $static-app, $static-form), \'.\'))">\n                                            <xf:setfocus\n                                                control="{$static-section-id}"\n                                                includes="{{frf:xpathFormRunnerStringProperty(\'oxf.fr.detail.focus.includes\')}}"\n                                                excludes="{{frf:xpathFormRunnerStringProperty(\'oxf.fr.detail.focus.excludes\')}}"/>\n                                        </xsl:if>\n\n                                        <!-- Show body if needed -->\n                                        <xf:var name="local" value="xxf:instance(\'local\')"/>\n                                        <xf:action if="$local/separate-toc/data(.)">\n                                            <xf:setvalue\n                                                ref="$local/show-toc"\n                                                value="false()"/>\n\n                                            <!-- See https://github.com/orbeon/orbeon-forms/issues/3668 -->\n                                            <xf:action if="not($local/show-body/data(.))">\n\n                                                <xf:var\n                                                    name="current-top-level-section-id"\n                                                    value="Wizard:sectionIdFromCaseIdOpt($current-top-level-case-id)"/>\n\n                                                <xf:dispatch name="fr-section-shown" targetid="fr-wizard" xxbl:scope="inner">\n                                                    <xf:property name="section-binding" value="xxf:binding($current-top-level-section-id)"              xxbl:scope="outer"/>\n                                                    <xf:property name="section-name"    value="frf:controlNameFromIdOpt($current-top-level-section-id)" xxbl:scope="outer"/>\n                                                    <xf:property name="validate"        value="xxf:instance(\'local\')/validate/data(.)"/>\n                                                    <xf:property name="separate-toc"    value="xxf:instance(\'local\')/separate-toc/data(.)"/>\n                                                </xf:dispatch>\n\n                                                <xf:setvalue\n                                                    ref="$local/show-body"\n                                                    value="true()"/>\n                                            </xf:action>\n\n                                        </xf:action>\n                                    </xf:action>\n                                </xf:action>\n                            </xf:trigger>\n\n                            <xsl:choose>\n                                <xsl:when test="$static-subsections-toc = \'all\' and exists(.//fr:section)">\n                                    <xh:div role="navigation">\n                                        <xh:ul class="nav nav-list">\n                                            <xsl:apply-templates mode="toc-sections"/>\n                                        </xh:ul>\n                                    </xh:div>\n                                </xsl:when>\n                                <xsl:when test="$static-subsections-toc = \'active\' and exists(.//fr:section)">\n                                    <xh:div role="navigation">\n                                        <xh:ul class="nav nav-list{{\' xforms-hidden\'[not($top-level-section-active)]}}">\n                                            <xsl:apply-templates mode="toc-sections"/>\n                                        </xh:ul>\n                                    </xh:div>\n                                </xsl:when>\n                                <xsl:otherwise>\n                                    <!-- No content -->\n                                </xsl:otherwise>\n                            </xsl:choose>\n                        </xh:li>\n                    </xsl:element>\n                </xsl:template>\n\n            </xsl:transform>\n        </xbl:template>\n    </xbl:binding>\n\n</xbl:xbl>', 'message': 'Following #4211: add "wizard debugger"\n', 'author_name': 'ebruchez', 'lang': 'xbl'}