<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:axsl="http://www.w3.org/1999/XSL/Transform/alias"
                xmlns:saxon="http://saxon.sf.net/"
                extension-element-prefixes="saxon"
                version="1.0">

    <!-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
    <!--                                            -->
    <!-- This stylesheet is capable of rewriting    -->
    <!-- itself at run-time!  That is, this program -->
    <!-- programs itself at run-time!               -->
    <!-- by Roger L. Costello                       -->
    <!--                                            -->
    <!-- Many thanks to Mike Kuras, Didier Martin,  -->
    <!-- Tom Passin, and Len Bullard for their keen -->
    <!-- insights and suggestions.                  -->
    <!--                                            -->
    <!-- This stylesheet contains code for          -->
    <!-- computing f(x, y).  It is initially        -->
    <!-- coded to compute f(x, y) = 2 * x + 2 * y   -->
    <!-- where x,y are input values.  However, the  -->
    <!-- input can instruct the stylesheet to       -->
    <!-- rewrite itself, to compute a new function! -->
    <!-- The stylesheet outputs a new stylesheet    -->
    <!-- which is a modified version of itself,     -->
    <!-- where it now computes the new function.    -->
    <!-- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -->
 
    <xsl:output method="xml"/>

    <xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
 
    <xsl:template match="f">
        <xsl:choose>
            <xsl:when test="not(modify-y)">
               <xsl:message>
                    f(x,y) = <xsl:value-of select="(2 * x) + (2 * y)"/>
               </xsl:message>
               <!-- Output yourself, unmodified -->
               <xsl:variable name="self" select="document('')"/>
               <xsl:copy-of select="$self"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:message>
                    <xsl:variable name="expression" select="concat('(2 * x) + (', modify-y, ')')"/>
                    f(x,y) = <xsl:value-of select="saxon:evaluate($expression)"/>
                </xsl:message>
                <!-- Ouput yourself, modified to compute the new function. -->
                <xsl:value-of disable-output-escaping="yes" select="'&lt;xsl:stylesheet xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot; 
                              xmlns:axsl=&quot;http://www.w3.org/1999/XSL/Transform/alias&quot;
                              xmlns:saxon=&quot;http://saxon.sf.net/&quot;
                              extension-element-prefixes=&quot;saxon&quot;
                              version=&quot;1.0&quot;>'"/>
         
                    <axsl:output method="xml"/>

                    <axsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
 
                    <axsl:template match="f">
                        <axsl:choose>
                            <axsl:when test="not(modify-y)">
                                <axsl:message>
                                    f(x,y) = <axsl:value-of>
                                                 <xsl:attribute name="select">(2 * x) + (<xsl:value-of select="modify-y"/>)</xsl:attribute>
                                             </axsl:value-of>
                                </axsl:message>
                               <axsl:variable name="self" select="document('')"/>
                               <axsl:copy-of select="$self"/>
                            </axsl:when>
                            <axsl:otherwise>      
                                <xsl:variable name="self" select="document('')"/>
                                <xsl:copy-of select="$self//xsl:template[@match='f']/xsl:choose/xsl:otherwise/*"/>
                            </axsl:otherwise>
                        </axsl:choose>
                    </axsl:template>
                <xsl:value-of disable-output-escaping="yes"  select="'&lt;/xsl:stylesheet>'"/> 
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>


</xsl:stylesheet>