<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>

<!-- Start -->
<xsl:template match="/">
   <xsl:apply-templates select="*"/>
</xsl:template>


<xsl:template match="subcommand">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
      <xsl:apply-templates select="*"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="flagset">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:for-each select="flag[not(@name = preceding-sibling::flag/@name)]">
      <xsl:apply-templates select="."/>
    </xsl:for-each>
  </xsl:copy>
</xsl:template>

<xsl:template match="contents">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:for-each select="*">
      <xsl:call-template name="Groupings">
        <xsl:with-param name="root" select="."/>
      </xsl:call-template>
    </xsl:for-each>
  </xsl:copy>
</xsl:template>


<xsl:template match="flag|brace|commands|word|ellipses|or">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
      <xsl:apply-templates select="*"/>
  </xsl:copy>
</xsl:template>

<xsl:template name="showPath">
    <xsl:param name="node"/>

    <xsl:choose>
      <xsl:when test="count($node/ancestor::*) &gt; 0">
        <xsl:call-template name="showPath">
          <xsl:with-param name="node" select="$node/ancestor::*[1]"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise/>
    </xsl:choose>
    <xsl:text>/</xsl:text><xsl:value-of select="name($node)"/>
</xsl:template>

<xsl:template name="Groupings">
  <xsl:param name="root"/>

  <xsl:for-each select="$root">
   <xsl:choose>
     <!-- const | brace | ellipses | flag | group | word  -->
      <xsl:when test="name()='flag'">
        <xsl:copy>
          <xsl:copy-of select="@*"/>
          <xsl:variable name="end_position">
            <xsl:call-template name="flag_end">
              <xsl:with-param name="root" select="."/>
            </xsl:call-template>
          </xsl:variable>
          <xsl:for-each select="following-sibling::*">
            <xsl:if test="position() &lt; $end_position">
              <xsl:choose>
                <!--
                     Check to see if we have a set of words. Which looks like
                     { word | word | word }
                -->
                <xsl:when test="name()='brace' and ./group/or and count(group/or/*) = count(group/or/word)">
                  <flag_set>
                    <xsl:for-each select="group/or/word">
                      <xsl:call-template name="RenameElements">
                        <xsl:with-param name="root" select="."/>
                        <xsl:with-param name="prefix" select="'flag_'"/>
                      </xsl:call-template>
                    </xsl:for-each>
                  </flag_set>
                </xsl:when>
                <xsl:when test="true()">
                  <xsl:call-template name="RenameElements">
                    <xsl:with-param name="root" select="."/>
                    <xsl:with-param name="prefix" select="'flag_'"/>
                  </xsl:call-template>
                </xsl:when>
              </xsl:choose>
            </xsl:if>
          </xsl:for-each>
        </xsl:copy>
      </xsl:when>
      <xsl:when test="name()='word' or name()='brace' or name()='group' or name()='ellipses'">
        <xsl:choose>
          <xsl:when test="not(preceding-sibling::flag)">
            <xsl:copy>
              <xsl:copy-of select="@*"/>
              <xsl:for-each select="*">
                <xsl:call-template name="Groupings">
                  <xsl:with-param name="root" select="."/>
                </xsl:call-template>
              </xsl:for-each>
            </xsl:copy>
          </xsl:when>
          <xsl:otherwise>
          <!-- We have a preceding flag -->
            <xsl:variable name="here" select="."/>
            <xsl:variable name="my_flag" select="preceding-sibling::flag[1]"/>
            <xsl:variable name="end_position">
              <xsl:call-template name="flag_end">
                <xsl:with-param name="root" select="$my_flag"/>
              </xsl:call-template>
            </xsl:variable>

            <!-- Copy this element only if it is not part of flag.... -->
            <!-- If it is part of flag, it has already been copied -->
            <xsl:for-each select="$my_flag/following-sibling::*">
              <xsl:if test="position() &gt;= $end_position and generate-id($here) = generate-id(.)">
                <xsl:copy>
                  <xsl:copy-of select="@*"/>
                  <xsl:for-each select="*">
                    <xsl:call-template name="Groupings">
                      <xsl:with-param name="root" select="."/>
                    </xsl:call-template>
                  </xsl:for-each>
                </xsl:copy>
              </xsl:if>
            </xsl:for-each>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:when>
      <xsl:when test="name()='ellipses'">
      </xsl:when>
      <xsl:when test="name()='const'">
      </xsl:when>
      <xsl:when test="name()='or' or name()='brace' or name()='group'">
        <xsl:copy>
          <xsl:copy-of select="@*"/>
          <xsl:for-each select="*">
            <xsl:call-template name="Groupings">
              <xsl:with-param name="root" select="."/>
            </xsl:call-template>
          </xsl:for-each>
        </xsl:copy>
      </xsl:when>
      <xsl:otherwise>
      <xsl:message>
        Error with contents template, got an unexpected element
        <xsl:value-of select="name()"/>
      </xsl:message>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each>
</xsl:template>

<xsl:template name="flag_end">
  <xsl:param name="root"/>

  <xsl:variable name="flag_ends">
    <xsl:for-each select="$root/following-sibling::*">
       <xsl:choose>
         <xsl:when test="name()='ellipses' or name()='word' or  name()='const'">
           <!-- Do nothing, these could be part of flag -->
           </xsl:when>
           <xsl:when test="name()='flag'">
             <xsl:value-of select="position()"/>
             <xsl:text>,</xsl:text>
           </xsl:when>
           <xsl:when test="name()='brace' or name()='group'">
             <xsl:if test=".//flag">
               <xsl:value-of select="position()"/>
               <xsl:text>,</xsl:text>
             </xsl:if>
           </xsl:when>
           <xsl:otherwise>
             <xsl:message>
               Error with contents template, got an unexpected element
               <xsl:value-of select="name()"/>
             </xsl:message>
           </xsl:otherwise>
         </xsl:choose>
         <xsl:if test="position()=last()">
           <xsl:text>l</xsl:text>
           <xsl:value-of select="position()+1"/>
         </xsl:if>

      </xsl:for-each>
    </xsl:variable>

   <xsl:variable name="end_position">
     <xsl:choose>
       <xsl:when test="contains($flag_ends,',')">
         <xsl:value-of select="substring-before($flag_ends,',')"/>
       </xsl:when>
       <xsl:otherwise>
         <xsl:value-of select="substring-after($flag_ends,'l')"/>
       </xsl:otherwise>
     </xsl:choose>
   </xsl:variable>
   <xsl:value-of select="$end_position"/>
</xsl:template>

<xsl:template name="RenameElements">
  <xsl:param name="root" />
  <xsl:param name="prefix" />

  <xsl:variable name="newname">
    <xsl:value-of select="$prefix"/><xsl:value-of select="name($root)"/>
  </xsl:variable>

  <xsl:element name="{$newname}">
    <xsl:copy-of select="$root/@*"/>
    <xsl:for-each select="$root/*">
      <xsl:call-template name="RenameElements">
        <xsl:with-param name="root" select="."/>
        <xsl:with-param name="prefix" select="$prefix"/>
      </xsl:call-template>
    </xsl:for-each>
  </xsl:element>
</xsl:template>


</xsl:stylesheet>