<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~~~~~~licensing~~~~~~
  route-producing
  ==========
  Copyright (C) 2020 - 2024 EmDev LLC
  ==========
  You may not use this file except in accordance with the License Terms of the Copyright
  Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
  rights to the Software and any copies are the property of the Copyright Holder. Unless
  it is explicitly allowed the Copyright Holder, the User is prohibited from using the
  Software for commercial purposes to provide services to third parties.
  
  The Copyright Holder hereby declares that the Software is provided on an "AS IS".
  Under no circumstances does the Copyright Holder guarantee or promise that the
  Software provided by him will be suitable or not suitable for the specific purposes
  of the User, that the Software will meet all commercial and personal subjective
  expectations of the User, that the Software will work properly, without technical
  errors, quickly and uninterruptedly.
  
  Under no circumstances shall the Copyright Holder or its Affiliates is not liable
  to the User for any direct or indirect losses of the User, his expenses or actual
  damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
  or damage to data, property, etc.
  ~~~~~~/licensing~~~~~~
  -->

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"
                xmlns:entaxy="http://www.entaxy.ru/schemas/1.0"
                xmlns:m="http://www.entaxy.ru/schemas/entaxy-mediators/1.0"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xmlns:blueprint="http://www.osgi.org/xmlns/blueprint/v1.0.0"
                xmlns:camel="http://camel.apache.org/schema/blueprint"
                xmlns="http://camel.apache.org/schema/blueprint">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:param name="context.type" select="'entaxy.runtime.profile'"/>
    <xsl:param name="context.fieldName" select="'in-flow-pre-route'"/>
    <xsl:param name="context.objectId" select="'sys-13'"/>

    <!-- only for inner routes -->
    <xsl:param name="context.properties.__routeOwner" select="'unknown:'"/>
    <!-- aliases -->
    <xsl:param name="routeOwnerId" select="substring-before($context.properties.__routeOwner,':')"/>

    <!--
        BEGIN components
    -->

    <!-- standard-router -->
    <xsl:template match="//m:standard-router">
        <xsl:text>&#10;</xsl:text>
        <xsl:comment>BEGIN standard-router</xsl:comment>
        <choice>
            <when>
                <simple>${headers.ENTAXY_Destination} == null</simple>
                <log>
                    <xsl:attribute name="message">${header.NTX_loggingKey} Destination isn't set</xsl:attribute>
                    <xsl:attribute name="loggingLevel">ERROR</xsl:attribute>
                </log>
                <throwException exceptionType="java.lang.IllegalArgumentException"
                                message="Destination isn't set"/>
            </when>
            <when>
                <simple>${headers.ENTAXY_DestinationType} == 'system.name'</simple>
                <toD>
                    <xsl:attribute name="uri">system:${headers.ENTAXY_Destination}</xsl:attribute>
                </toD>
            </when>
            <when>
                <simple>${headers.ENTAXY_DestinationType} == 'system-group.name'</simple>
                <toD>
                    <xsl:attribute name="uri">system-group:${headers.ENTAXY_Destination}</xsl:attribute>
                </toD>
            </when>
            <when>
                <simple>${headers.ENTAXY_DestinationType} == 'queue.name'</simple>
                <toD>
                    <xsl:attribute name="uri">entaxy-broker:queue:${headers.ENTAXY_Destination}</xsl:attribute>
                </toD>
            </when>
            <when>
                <simple>${headers.ENTAXY_DestinationType} == 'topic.name'</simple>
                <toD>
                    <xsl:attribute name="uri">entaxy-broker:topic:${headers.ENTAXY_Destination}</xsl:attribute>
                </toD>
            </when>
            <otherwise>
                <toD>
                    <xsl:attribute name="uri">system:${headers.ENTAXY_Destination}</xsl:attribute>
                </toD>
            </otherwise>
        </choice>
        <xsl:text>&#10;</xsl:text>
        <xsl:comment>END standard-router</xsl:comment>

    </xsl:template>

    <!-- set-destination -->
    <xsl:template match="//m:set-destination" exclude-result-prefixes="xsl fn xs camel">
        <xsl:variable name="full" select="./text()"/>
        <xsl:variable name="name">
            <xsl:choose>
                <xsl:when test="contains($full, ':')">
                    <xsl:value-of select="substring-before($full, ':')"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$full"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:variable name="type" select="substring-after($full, ':')"/>
        <xsl:comment>generated from 'set-destination'</xsl:comment>
        <setHeader name="ENTAXY_Destination">
            <constant>
                <xsl:value-of select="$name"/>
            </constant>
        </setHeader>
        <xsl:choose>
            <xsl:when test="string-length($type) > 0">
                <setHeader name="ENTAXY_DestinationType">
                    <constant>
                        <xsl:value-of select="$type"/>
                    </constant>
                </setHeader>
            </xsl:when>
            <xsl:otherwise>
                <removeHeader headerName="ENTAXY_DestinationType"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <!-- default-destination -->
    <xsl:template match="//m:default-destination" exclude-result-prefixes="xsl fn xs camel">
        <xsl:variable name="full" select="./text()"/>
        <xsl:variable name="name">
            <xsl:choose>
                <xsl:when test="contains($full, ':')">
                    <xsl:value-of select="substring-before($full, ':')"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$full"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:variable name="type" select="substring-after($full, ':')"/>
        <xsl:comment>generated from 'default-destination'</xsl:comment>
        <choice>
            <when>
                <simple>${headers.ENTAXY_Destination} == null || ${headers.ENTAXY_Destination} == ''</simple>
                <removeHeader headerName="ENTAXY_DestinationType"/>
                <setHeader name="ENTAXY_Destination">
                    <constant>
                        <xsl:value-of select="$name"/>
                    </constant>
                </setHeader>
                <xsl:if test="string-length($type) > 0">
                    <setHeader name="ENTAXY_DestinationType">
                        <constant>
                            <xsl:value-of select="$type"/>
                        </constant>
                    </setHeader>
                </xsl:if>
            </when>
        </choice>
    </xsl:template>

    <!-- prefer-connector -->
    <!--	
		USAGE:
			<prefer-connector>
				<protocol>file</protocol>
				<classifier></classifier>
				<type></type>
			</prefer-connector>
	-->
    <xsl:template match="//m:prefer-connector" exclude-result-prefixes="xsl fn xs camel">
        <xsl:variable name="nodes" select="child::element()"/>
        <setHeader name="NTX_preferred_connector">
            <constant>
                <xsl:text>{</xsl:text>
                <xsl:for-each select="$nodes">
                    <xsl:text>"</xsl:text><xsl:value-of select="local-name(.)"/><xsl:text>": "</xsl:text><xsl:value-of
                        select="."/><xsl:text>"</xsl:text>
                    <xsl:variable name="i" select="position()"/>
                    <xsl:choose>
                        <xsl:when test="$nodes[$i + 1]!=''">
                            <xsl:text>,</xsl:text>
                        </xsl:when>
                    </xsl:choose>
                </xsl:for-each>
                <xsl:text>}</xsl:text>
            </constant>
        </setHeader>
    </xsl:template>


    <!-- log -->
    <xsl:template match="//m:log" exclude-result-prefixes="xsl fn xs camel">
        <xsl:variable name="nodes" select="child::element()"/>
        <log>
            <xsl:variable name="message">
                <xsl:value-of select="@message"/>
            </xsl:variable>
            <xsl:if test="string-length($message) > 0">
                <xsl:attribute name="message"
                               select="concat('${headers.NTX_loggingKey} ', $message)"/>
            </xsl:if>
            <xsl:variable name="loggingLevel">
                <xsl:value-of select="@loggingLevel"/>
            </xsl:variable>
            <xsl:if test="string-length($loggingLevel) > 0">
                <xsl:attribute name="loggingLevel" select="$loggingLevel"/>
            </xsl:if>
            <xsl:variable name="logName">
                <xsl:value-of select="@logName"/>
            </xsl:variable>
            <xsl:if test="string-length($logName) > 0">
                <xsl:attribute name="logName" select="$logName"/>
            </xsl:if>
            <xsl:variable name="marker">
                <xsl:value-of select="@marker"/>
            </xsl:variable>
            <xsl:if test="string-length($marker) > 0">
                <xsl:attribute name="marker" select="$marker"/>
            </xsl:if>
            <xsl:variable name="loggerRef">
                <xsl:value-of select="@loggerRef"/>
            </xsl:variable>
            <xsl:if test="string-length($loggerRef) > 0">
                <xsl:attribute name="loggerRef" select="$loggerRef"/>
            </xsl:if>
        </log>
    </xsl:template>

    <xsl:template match="//m:set-log-key" exclude-result-prefixes="xsl fn xs camel">
        <xsl:for-each select="./*">
            <xsl:choose>
                <xsl:when test="local-name() = 'custom'">
                    <setProperty>
                        <xsl:attribute name="name" select="@name"/>
                        <xsl:copy-of select="node()"/>
                    </setProperty>
                </xsl:when>
                <xsl:otherwise>
                    <setProperty>
                        <xsl:attribute name="name" select="local-name()"/>
                        <xsl:copy-of select="node()"/>
                    </setProperty>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
        <to uri="direct-vm:fill-logging-key"/>
    </xsl:template>

    <!-- next-route -->
    <xsl:template match="//m:next-route" exclude-result-prefixes="xsl fn xs camel">
        <xsl:variable name="local">
            <xsl:choose>
                <xsl:when test="./@local">
                    <xsl:value-of select="./@local"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:text>false</xsl:text>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>

        <xsl:variable name="async">
            <xsl:choose>
                <xsl:when test="./@async">
                    <xsl:value-of select="./@async"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:text>false</xsl:text>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>

        <xsl:variable name="component">
            <xsl:choose>
                <xsl:when test="$async = 'false'">
                    <xsl:text>direct</xsl:text>
                    <xsl:if test="$local = 'false'">
                        <xsl:text>-vm</xsl:text>
                    </xsl:if>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:choose>
                        <xsl:when test="$local = 'true'">
                            <xsl:text>seda</xsl:text>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:text>vm</xsl:text>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>

        <xsl:variable name="name">
            <xsl:value-of select="./text()"/>
        </xsl:variable>
        <xsl:comment>generated from 'next-route'</xsl:comment>
        <setHeader name="NTX_NextPoint">
            <constant>
                <xsl:value-of select="$component"/><xsl:text>:</xsl:text><xsl:value-of select="$name"/>
            </constant>
        </setHeader>
    </xsl:template>

    <!-- xslt-xalan with resources -->
    <xsl:template match="//m:xslt-xalan" exclude-result-prefixes="xsl fn xs camel">
        <blueprint:reference id="xslUrlResolver" interface="javax.xml.transform.URIResolver" filter="(type=xslt)"/>
        <to>
            <xsl:variable name="resource">
                <xsl:value-of select="@resource"/>
            </xsl:variable>
            <xsl:variable name="params">
                <xsl:value-of select="@params"/>
            </xsl:variable>
            <xsl:variable name="resultResource">
                <xsl:choose>
                    <xsl:when test="contains($resource, ':')">
                        <xsl:value-of select="translate($resource,':','/')"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="$resource"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:variable>
            <xsl:variable name="resultParams">
                <xsl:choose>
                    <xsl:when test="string-length($params) > 0">
                        <xsl:value-of select="concat('&amp;', $params)"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:text/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:variable>
            <xsl:attribute name="uri"
                           select="concat('xslt:entaxy-resource://', $resultResource, '?uriResolver=#xslUrlResolver', $resultParams)"/>
        </to>
    </xsl:template>

    <!-- xslt with resources -->
    <xsl:template match="//m:xslt" exclude-result-prefixes="xsl fn xs camel">
        <blueprint:reference id="xslUrlResolver" interface="javax.xml.transform.URIResolver" filter="(type=xslt)"/>
        <to>
            <xsl:variable name="resource">
                <xsl:value-of select="@resource"/>
            </xsl:variable>
            <xsl:variable name="params">
                <xsl:value-of select="@params"/>
            </xsl:variable>
            <xsl:variable name="resultResource">
                <xsl:choose>
                    <xsl:when test="contains($resource, ':')">
                        <xsl:value-of select="translate($resource,':','/')"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="$resource"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:variable>
            <xsl:variable name="resultParams">
                <xsl:choose>
                    <xsl:when test="string-length($params) > 0">
                        <xsl:value-of select="concat('&amp;', $params)"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:text/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:variable>
            <xsl:attribute name="uri"
                           select="concat('xslt-saxon:entaxy-resource://', $resultResource, '?uriResolver=#xslUrlResolver', $resultParams)"/>
        </to>
    </xsl:template>

    <!-- atlasmap with resources -->
    <xsl:template match="//m:atlasmap" exclude-result-prefixes="xsl fn xs camel">
        <to>
            <xsl:variable name="resource">
                <xsl:value-of select="@resource"/>
            </xsl:variable>
            <xsl:variable name="params">
                <xsl:value-of select="@params"/>
            </xsl:variable>
            <xsl:variable name="resultParams">
                <xsl:choose>
                    <xsl:when test="string-length($params) > 0">
                        <xsl:value-of select="concat( '?', $params)"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:text/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:variable>
            <xsl:attribute name="uri" select="concat('atlas:', $resource, $resultParams)"/>
        </to>
    </xsl:template>

    <!-- read-secret -->
    <xsl:template match="//m:read-secret" exclude-result-prefixes="xsl fn xs camel">
        <xsl:choose>
            <xsl:when test="@vault">
                <xsl:variable name="vault">
                    <xsl:value-of select="@vault"/>
                </xsl:variable>
                <xsl:variable name="property">
                    <xsl:choose>
                        <xsl:when test="@property">
                            <xsl:value-of select="@property"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:text>__SECRET__</xsl:text>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:variable>
                <xsl:variable name="secretName">
                    <xsl:choose>
                        <xsl:when test="@alias">
                            <xsl:value-of select="@alias"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:text>secret</xsl:text>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:variable>
                <xsl:variable name="dollar">
                    <xsl:text>$</xsl:text>
                </xsl:variable>
                <reference interface="ru.entaxy.security.vault.runtime.EntaxyVault"
                           xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
                    <xsl:attribute name="id" select="concat('vault-ref-',$vault)"/>
                    <xsl:attribute name="filter" select="concat('(name=', $vault, ')')"/>
                </reference>
                <bean class="ru.entaxy.security.vault.runtime.camel.EntaxyVaultHelperBean" activation="eager"
                      xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
                    <xsl:attribute name="id" select="concat('vault-wrapper-',$vault)"/>
                    <property name="entaxyVault">
                        <xsl:attribute name="ref" select="concat('vault-ref-',$vault)"/>
                    </property>
                </bean>
                <to>
                    <xsl:attribute name="uri"
                                   select="concat('bean:vault-wrapper-',$vault,'?method=getValue(', $dollar, '{exchange}, ''', $secretName, ''',''', $property, ''')' )"/>
                </to>
            </xsl:when>
        </xsl:choose>
    </xsl:template>

    <!-- respond -->
    <xsl:template match="//m:respond" exclude-result-prefixes="xsl fn xs camel">
        <xsl:variable name="respondNow">
            <xsl:choose>
                <xsl:when test="@now">
                    <xsl:value-of select="@now"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:text>true</xsl:text>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:variable name="respondContinue">
            <xsl:choose>
                <xsl:when test="@continue">
                    <xsl:value-of select="@continue"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:text>true</xsl:text>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:variable name="respondContinueAsync">
            <xsl:choose>
                <xsl:when test="@continueAsync">
                    <xsl:value-of select="@continueAsync"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:text>true</xsl:text>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <setHeader name="NTX_RESPOND_exec">
            <constant>true</constant>
        </setHeader>
        <setHeader name="NTX_RESPOND_now">
            <constant>
                <xsl:value-of select="$respondNow"/>
            </constant>
        </setHeader>
        <setHeader name="NTX_RESPOND_continue">
            <constant>
                <xsl:value-of select="$respondContinue"/>
            </constant>
        </setHeader>
        <setHeader name="NTX_RESPOND_continueAsync">
            <constant>
                <xsl:value-of select="$respondContinueAsync"/>
            </constant>
        </setHeader>
    </xsl:template>

    <!-- to-connection -->
    <xsl:template match="//m:to-connection" exclude-result-prefixes="xsl fn xs camel">
        <reference interface="org.apache.camel.Component" xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
            <xsl:attribute name="id" select="@name"/>
            <xsl:attribute name="filter" select="concat('(connection.name=', @name, ')')"/>
        </reference>
        <xsl:variable name="dir">
            <xsl:choose>
                <xsl:when test="@path">
                    <xsl:value-of select="@path"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:text></xsl:text>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>

        <xsl:choose>
            <xsl:when test="@dynamic = 'true'">
                <toD>
                    <xsl:variable name="queryString">
                        <xsl:for-each select="./element()">
                            <xsl:call-template name="convert-to-query"/>
                        </xsl:for-each>
                    </xsl:variable>
                    <xsl:variable name="resultQS">
                        <xsl:choose>
                            <xsl:when test="string-length($queryString) > 0">
                                <xsl:value-of select="concat('?', $queryString)"/>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:text/>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:variable>
                    <xsl:attribute name="uri" select="concat(@name,':' ,$dir , $resultQS)"/>
                </toD>
            </xsl:when>
            <xsl:otherwise>
                <to>
                    <xsl:variable name="queryString">
                        <xsl:for-each select="./element()">
                            <xsl:call-template name="convert-to-query"/>
                        </xsl:for-each>
                    </xsl:variable>
                    <xsl:variable name="resultQS">
                        <xsl:choose>
                            <xsl:when test="string-length($queryString) > 0">
                                <xsl:value-of select="concat('?', $queryString)"/>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:text/>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:variable>
                    <xsl:attribute name="uri" select="concat(@name,':' ,$dir , $resultQS)"/>
                </to>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <!-- call-route -->
    <xsl:template match="//m:call-route" exclude-result-prefixes="xsl fn xs camel">

        <xsl:variable name="finalRouteId" select="@name"/>
        <xsl:variable name="finalOwner">
            <xsl:choose>
                <xsl:when test="$routeOwnerId != 'unknown'">
                    <xsl:value-of select="$routeOwnerId"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$context.objectId"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:variable name="finalLocal">
            <xsl:choose>
                <xsl:when test="@library and not(@library = '')">
                    <xsl:value-of select="'false'"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="'true'"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:variable name="finalLibrary">
            <xsl:choose>
                <xsl:when test="@library and not(@library = '')">
                    <xsl:value-of select="@library"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$finalOwner"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:variable name="finalAsync">
            <xsl:choose>
                <xsl:when test="@async">
                    <xsl:value-of select="@async"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="'false'"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>

        <xsl:variable name="finalSchema">
            <xsl:choose>
                <xsl:when test="$finalLocal = 'true'">
                    <xsl:choose>
                        <xsl:when test="$finalAsync = 'true'">
                            <xsl:value-of select="'seda'"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="'direct'"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:choose>
                        <xsl:when test="$finalAsync = 'true'">
                            <xsl:value-of select="'vm'"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="'direct-vm'"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>

        <xsl:variable name="finalUri">
            <xsl:value-of select="concat($finalSchema, ':', $finalLibrary, '__', $finalRouteId)"/>
        </xsl:variable>

        <xsl:variable name="finalDynamic">
            <xsl:choose>
                <!--
                @TODO investigate why 'matches' doesn't work corectly in Saxon
                <xsl:when test="matches($finalUri, '.*(\$\{.+\}).*')">
                -->
                <!--
                @TODO investigate why we have to get '${' via concatenation rather than setting it directly
                seems to be Saxon-related issue
                -->
                <xsl:when test="contains($finalUri, concat('$','{'))">
                    <xsl:value-of select="'true'"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="'false'"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:variable name="finalTo">
            <xsl:choose>
                <xsl:when test="$finalDynamic = 'true'">
                    <toD>
                        <xsl:attribute name="uri" select="$finalUri"/>
                    </toD>
                </xsl:when>
                <xsl:otherwise>
                    <to>
                        <xsl:attribute name="uri" select="$finalUri"/>
                    </to>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>

        <xsl:text>&#10;</xsl:text>
        <xsl:comment>
            <xsl:text> Generated from 'call-route': name=</xsl:text><xsl:value-of select="@name"/><xsl:text>; library=</xsl:text><xsl:value-of
                select="@library"/><xsl:text>; async=</xsl:text><xsl:value-of select="@async"/><xsl:text> </xsl:text>
        </xsl:comment>
        <xsl:text>&#10;</xsl:text>
        <xsl:choose>
            <xsl:when test="$finalAsync = 'true'">
                <multicast shareUnitOfWork="true">
                    <xsl:copy-of select="$finalTo"/>
                </multicast>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy-of select="$finalTo"/>
            </xsl:otherwise>
        </xsl:choose>

    </xsl:template>

    <!-- entaxy-trace -->
    <!--
        USAGE:
        <m:entaxy-trace reset="true">
            <simple>${headers.HEADER_TO_TRACE}</simple>
        </m:entaxy-trace>
    -->
    <xsl:template match="//m:entaxy-trace" exclude-result-prefixes="xsl fn xs camel">
        <xsl:choose>
            <xsl:when test="@reset = true()">
                <setHeader name="ENTAXY_TRACE">
                    <constant></constant>
                </setHeader>
            </xsl:when>
        </xsl:choose>
        <xsl:choose>
            <xsl:when test="child::element()[1]">
                <choice>
                    <when>
                        <simple>${headers.ENTAXY_TRACE} != null</simple>
                        <setHeader name="ENTAXY_TRACE">
                            <simple>${headers.ENTAXY_TRACE} -&gt;</simple>
                        </setHeader>
                    </when>
                </choice>
                <setHeader name="NTX_TRACE_RECORD">
                    <xsl:apply-templates select="child::element()[1]"/>
                </setHeader>
                <choice>
                    <when>
                        <simple>${headers.ENTAXY_TRACE} == null</simple>
                        <setHeader name="ENTAXY_TRACE">
                            <simple>[${headers.NTX_TRACE_RECORD}]</simple>
                        </setHeader>
                    </when>
                    <otherwise>
                        <setHeader name="ENTAXY_TRACE">
                            <simple>${headers.ENTAXY_TRACE}[${headers.NTX_TRACE_RECORD}]</simple>
                        </setHeader>
                    </otherwise>
                </choice>
                <removeHeader headerName="NTX_TRACE_RECORD"/>
            </xsl:when>
        </xsl:choose>
    </xsl:template>


    <!--
        END components
    -->

    <xsl:template match="/">
        <xsl:apply-templates select="child::node()"/>
    </xsl:template>

    <xsl:template name="default-copy" match="node()|@*" exclude-result-prefixes="fn xs xsi">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template name="convert-to-query" exclude-result-prefixes="xsl fn xs camel">
        <xsl:value-of select="concat(node-name(.), '=', text())"/>
        <xsl:if test="./following-sibling::element()">
            <xsl:text>&amp;</xsl:text>
        </xsl:if>
    </xsl:template>

</xsl:stylesheet>
